pub const MANIFEST_PATH: &str = "/.well-known/memstead-publishing.json";
pub const ALG: &str = "ed25519";
pub const SIGNING_DOMAIN: &str = "memstead-domain-publish-v1";
pub const HEADER_KEY: &str = "x-memstead-domain-key";
pub const HEADER_SIGNATURE: &str = "x-memstead-domain-signature";
pub const HEADER_TIMESTAMP: &str = "x-memstead-domain-timestamp";
pub fn signing_payload(
content_sha256: &str,
scope: &str,
name: &str,
version: &str,
timestamp: i64,
) -> Vec<u8> {
format!("{SIGNING_DOMAIN}\n{content_sha256}\n{scope}\n{name}\n{version}\n{timestamp}")
.into_bytes()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn payload_is_deterministic_and_binds_every_field() {
let base = signing_payload("deadbeef", "acme.com:pay", "mem", "1.0.0", 1000);
assert_eq!(
base,
signing_payload("deadbeef", "acme.com:pay", "mem", "1.0.0", 1000)
);
assert_ne!(
base,
signing_payload("feedface", "acme.com:pay", "mem", "1.0.0", 1000)
);
assert_ne!(
base,
signing_payload("deadbeef", "other.com:pay", "mem", "1.0.0", 1000)
);
assert_ne!(
base,
signing_payload("deadbeef", "acme.com:pay", "other", "1.0.0", 1000)
);
assert_ne!(
base,
signing_payload("deadbeef", "acme.com:pay", "mem", "2.0.0", 1000)
);
assert_ne!(
base,
signing_payload("deadbeef", "acme.com:pay", "mem", "1.0.0", 1001)
);
}
#[test]
fn payload_exact_bytes_are_pinned() {
let p = signing_payload("abc123", "acme.com:pay", "demo", "1.2.3", 1700000000);
assert_eq!(
p,
b"memstead-domain-publish-v1\nabc123\nacme.com:pay\ndemo\n1.2.3\n1700000000".to_vec()
);
}
}