address comment

This commit is contained in:
Marvin Jones 2026-06-17 14:19:51 -04:00
parent acd4beb50f
commit 72b2bc3b65
4 changed files with 13 additions and 11 deletions

View File

@ -150,7 +150,7 @@ impl GroupKeyHolder {
///
/// Uses ML-KEM-768 encapsulation to derive a shared secret, then AES-256-GCM to encrypt
/// the payload. The returned bytes are
/// `kem_ciphertext (1088) || nonce (12) || ciphertext+tag (48)` = 1148 bytes.
/// `kem_ciphertext (ML_KEM_768_CIPHERTEXT_LEN) || nonce (12) || ciphertext+tag (48)`.
///
/// Each call generates a fresh KEM encapsulation, so two seals of the same holder produce
/// different ciphertexts.
@ -186,7 +186,7 @@ impl GroupKeyHolder {
/// Returns `Err` if the ciphertext is too short or the AES-GCM authentication tag
/// doesn't verify (wrong key or tampered data).
pub fn unseal(sealed: &[u8], own_key: &SealingSecretKey) -> Result<Self, SealError> {
// kem_ciphertext (1088) + nonce (12) = header, then AES-GCM tag (16) minimum.
// kem_ciphertext (ML_KEM_768_CIPHERTEXT_LEN) + nonce (12) = header, then AES-GCM tag (16) minimum.
const HEADER_LEN: usize = ML_KEM_768_CIPHERTEXT_LEN + 12;
const MIN_LEN: usize = HEADER_LEN + 16;

View File

@ -150,6 +150,7 @@ mod tests {
],
);
// Length matches MlKem768EncapsulationKey::LEN.
let expected_vpk: [u8; 1184] = [
127, 229, 162, 212, 104, 117, 4, 150, 192, 103, 122, 195, 14, 35, 12, 60, 52, 23, 220,
150, 100, 203, 34, 34, 127, 232, 156, 43, 218, 109, 6, 160, 67, 35, 210, 194, 25, 181,
@ -257,6 +258,7 @@ mod tests {
],
);
// Length matches MlKem768EncapsulationKey::LEN.
let expected_vpk: [u8; 1184] = [
215, 229, 207, 120, 148, 177, 148, 197, 72, 222, 134, 3, 231, 146, 123, 226, 36, 84,
232, 179, 205, 16, 241, 142, 9, 81, 58, 54, 12, 115, 148, 182, 19, 245, 22, 203, 57,

View File

@ -153,7 +153,7 @@ impl From<&ViewingSecretKey> for ViewingPublicKey {
seed_bytes[32..].copy_from_slice(&sk.z);
let dk = <MlKem768 as Kem>::DecapsulationKey::from_seed(Seed::from(seed_bytes));
Self::from_bytes(dk.encapsulation_key().to_bytes().to_vec())
.expect("key_protocol::secret_holders::From<&ViewingSecretKey>: ML-KEM-768 encapsulation key is always 1184 bytes")
.expect("key_protocol::secret_holders::From<&ViewingSecretKey>: ML-KEM-768 encapsulation key is always ViewingPublicKey::LEN bytes")
}
}

View File

@ -64,7 +64,7 @@ impl SharedSecretKey {
let ek_bytes: ml_kem::kem::Key<ml_kem::EncapsulationKey768> =
ek.0.as_slice()
.try_into()
.expect("MlKem768EncapsulationKey must be 1184 bytes");
.expect("MlKem768EncapsulationKey must be MlKem768EncapsulationKey::LEN bytes");
let ek_obj = ml_kem::EncapsulationKey768::new(&ek_bytes).expect(
"MlKem768EncapsulationKey bytes must encode a valid ML-KEM-768 encapsulation key",
);
@ -104,7 +104,7 @@ impl SharedSecretKey {
let ek_bytes: ml_kem::kem::Key<ml_kem::EncapsulationKey768> =
ek.0.as_slice()
.try_into()
.expect("MlKem768EncapsulationKey must be 1184 bytes");
.expect("MlKem768EncapsulationKey must be MlKem768EncapsulationKey::LEN bytes");
let ek_obj = ml_kem::EncapsulationKey768::new(&ek_bytes).expect(
"MlKem768EncapsulationKey bytes must encode a valid ML-KEM-768 encapsulation key",
);
@ -118,7 +118,7 @@ impl SharedSecretKey {
/// Receiver: decapsulate the shared secret from a KEM ciphertext.
///
/// Returns `None` if the `EphemeralPublicKey` is not exactly 1088 bytes — callers on
/// Returns `None` if the `EphemeralPublicKey` is not exactly [`ML_KEM_768_CIPHERTEXT_LEN`] bytes — callers on
/// the wallet scan path should skip the output rather than panic on malformed chain data.
///
/// `d` and `z` are the two 32-byte halves of the FIPS 203 `ViewingSecretKey` seed.
@ -168,12 +168,12 @@ mod tests {
assert_eq!(
epk.0.len(),
ML_KEM_768_CIPHERTEXT_LEN,
"ML-KEM-768 ciphertext is 1088 bytes"
"ML-KEM-768 ciphertext length"
);
assert_eq!(
ek.0.len(),
1184,
"ML-KEM-768 encapsulation key is 1184 bytes"
MlKem768EncapsulationKey::LEN,
"ML-KEM-768 encapsulation key length"
);
}
@ -182,14 +182,14 @@ mod tests {
let d = [1_u8; 32];
let z = [2_u8; 32];
// Too short — 100 bytes instead of 1088.
// Too short — 100 bytes instead of ML_KEM_768_CIPHERTEXT_LEN.
let short_epk = EphemeralPublicKey(vec![42_u8; 100]);
assert!(
SharedSecretKey::decapsulate(&short_epk, &d, &z).is_none(),
"short EphemeralPublicKey must return None"
);
// Too long — 1089 bytes instead of 1088.
// Too long — ML_KEM_768_CIPHERTEXT_LEN + 1.
let long_epk = EphemeralPublicKey(vec![42_u8; ML_KEM_768_CIPHERTEXT_LEN + 1]);
assert!(
SharedSecretKey::decapsulate(&long_epk, &d, &z).is_none(),