diff --git a/Cargo.lock b/Cargo.lock index 8a9ad0f7..24835f2b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1139,8 +1139,7 @@ dependencies = [ [[package]] name = "signature" version = "3.0.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7ae074ff622614874804868b07d9cb786223082c9fe726a6653608f32f37b02" +source = "git+https://github.com/RustCrypto/traits?rev=9e3f5ec97faf6a96c0bad7756402c940db240066#9e3f5ec97faf6a96c0bad7756402c940db240066" dependencies = [ "digest", "rand_core 0.9.2", diff --git a/Cargo.toml b/Cargo.toml index 57f708b7..1e56256b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,3 +25,5 @@ lms-signature = { path = "./lms" } ml-dsa = { path = "./ml-dsa" } rfc6979 = { path = "./rfc6979" } slh-dsa = { path = "./slh-dsa" } + +signature = { git = "https://github.com/RustCrypto/traits", rev = "9e3f5ec97faf6a96c0bad7756402c940db240066" } diff --git a/dsa/src/signing_key.rs b/dsa/src/signing_key.rs index ad63e18d..1b3f0bc8 100644 --- a/dsa/src/signing_key.rs +++ b/dsa/src/signing_key.rs @@ -148,8 +148,9 @@ impl SigningKey { impl ZeroizeOnDrop for SigningKey {} impl Signer for SigningKey { - fn try_sign(&self, msg: &[u8]) -> Result { - let digest = sha2::Sha256::new_with_prefix(msg); + fn try_sign(&self, msg: &[&[u8]]) -> Result { + let mut digest = sha2::Sha256::default(); + msg.iter().for_each(|slice| digest.update(slice)); self.try_sign_digest(digest) } } diff --git a/dsa/src/verifying_key.rs b/dsa/src/verifying_key.rs index fe9d2c38..7ce271e2 100644 --- a/dsa/src/verifying_key.rs +++ b/dsa/src/verifying_key.rs @@ -107,8 +107,10 @@ impl VerifyingKey { } impl Verifier for VerifyingKey { - fn verify(&self, msg: &[u8], signature: &Signature) -> Result<(), signature::Error> { - self.verify_digest(sha2::Sha256::new_with_prefix(msg), signature) + fn verify(&self, msg: &[&[u8]], signature: &Signature) -> Result<(), signature::Error> { + let mut digest = sha2::Sha256::default(); + msg.iter().for_each(|slice| digest.update(slice)); + self.verify_digest(digest, signature) } } diff --git a/dsa/tests/signature.rs b/dsa/tests/signature.rs index 3fa326d6..614b989c 100644 --- a/dsa/tests/signature.rs +++ b/dsa/tests/signature.rs @@ -104,9 +104,9 @@ fn signer_verifier_signature() { // construct signature manually and by `Signer` defaults. Ensure results are identical. let manual_digest = Sha256::new_with_prefix(message).finalize(); let manual_signature = signing_key.sign_prehash(&manual_digest).unwrap(); - let signer_signature = signing_key.sign(message); - verifying_key.verify(message, &manual_signature).unwrap(); - verifying_key.verify(message, &signer_signature).unwrap(); + let signer_signature = signing_key.sign(&[message]); + verifying_key.verify(&[message], &manual_signature).unwrap(); + verifying_key.verify(&[message], &signer_signature).unwrap(); assert_eq!(manual_signature, signer_signature); // verify signature manually and by `Verifier` defaults. Ensure signatures can be applied interchangeably. @@ -116,8 +116,8 @@ fn signer_verifier_signature() { verifying_key .verify_prehash(&manual_digest, &signer_signature) .unwrap(); - verifying_key.verify(message, &manual_signature).unwrap(); - verifying_key.verify(message, &signer_signature).unwrap(); + verifying_key.verify(&[message], &manual_signature).unwrap(); + verifying_key.verify(&[message], &signer_signature).unwrap(); } /// This test forces the r and s of the signature to a bit precision different to what would diff --git a/ecdsa/src/dev.rs b/ecdsa/src/dev.rs index e700a25c..51697e53 100644 --- a/ecdsa/src/dev.rs +++ b/ecdsa/src/dev.rs @@ -200,7 +200,7 @@ macro_rules! new_wycheproof_test { Err(_) => return Some("failed to parse signature ASN.1"), }; - match verifying_key.verify(msg, &sig) { + match verifying_key.verify(&[msg], &sig) { Ok(_) if pass => None, Ok(_) => Some("signature verify unexpectedly succeeded"), Err(_) if !pass => None, diff --git a/ecdsa/src/recovery.rs b/ecdsa/src/recovery.rs index d09073ae..7ef94193 100644 --- a/ecdsa/src/recovery.rs +++ b/ecdsa/src/recovery.rs @@ -96,7 +96,7 @@ impl RecoveryId { /// otherwise. pub fn trial_recovery_from_msg( verifying_key: &VerifyingKey, - msg: &[u8], + msg: &[&[u8]], signature: &Signature, ) -> Result where @@ -105,7 +105,9 @@ impl RecoveryId { FieldBytesSize: sec1::ModulusSize, SignatureSize: ArraySize, { - Self::trial_recovery_from_digest(verifying_key, C::Digest::new_with_prefix(msg), signature) + let mut digest = C::Digest::new(); + msg.iter().for_each(|slice| digest.update(slice)); + Self::trial_recovery_from_digest(verifying_key, digest, signature) } /// Given a public key, message digest, and signature, use trial recovery @@ -220,8 +222,10 @@ where /// Sign the given message, hashing it with the curve's default digest /// function, and returning a signature and recovery ID. - pub fn sign_recoverable(&self, msg: &[u8]) -> Result<(Signature, RecoveryId)> { - self.sign_digest_recoverable(C::Digest::new_with_prefix(msg)) + pub fn sign_recoverable(&self, msg: &[&[u8]]) -> Result<(Signature, RecoveryId)> { + let mut digest = C::Digest::new(); + msg.iter().for_each(|slice| digest.update(slice)); + self.sign_digest_recoverable(digest) } } @@ -290,7 +294,7 @@ where Scalar: Invert>>, SignatureSize: ArraySize, { - fn try_sign(&self, msg: &[u8]) -> Result<(Signature, RecoveryId)> { + fn try_sign(&self, msg: &[&[u8]]) -> Result<(Signature, RecoveryId)> { self.sign_recoverable(msg) } } @@ -308,14 +312,16 @@ where /// /// The message is first hashed using this curve's [`DigestPrimitive`]. pub fn recover_from_msg( - msg: &[u8], + msg: &[&[u8]], signature: &Signature, recovery_id: RecoveryId, ) -> Result where C: DigestPrimitive, { - Self::recover_from_digest(C::Digest::new_with_prefix(msg), signature, recovery_id) + let mut digest = C::Digest::new(); + msg.iter().for_each(|slice| digest.update(slice)); + Self::recover_from_digest(digest, signature, recovery_id) } /// Recover a [`VerifyingKey`] from the given message [`Digest`], diff --git a/ecdsa/src/signing.rs b/ecdsa/src/signing.rs index 5872dff3..5cc49d4b 100644 --- a/ecdsa/src/signing.rs +++ b/ecdsa/src/signing.rs @@ -175,8 +175,10 @@ where Scalar: Invert>>, SignatureSize: ArraySize, { - fn try_sign(&self, msg: &[u8]) -> Result> { - self.try_sign_digest(C::Digest::new_with_prefix(msg)) + fn try_sign(&self, msg: &[&[u8]]) -> Result> { + let mut digest = C::Digest::new(); + msg.iter().for_each(|slice| digest.update(slice)); + self.try_sign_digest(digest) } } @@ -232,9 +234,11 @@ where fn try_sign_with_rng( &self, rng: &mut R, - msg: &[u8], + msg: &[&[u8]], ) -> Result> { - self.try_sign_digest_with_rng(rng, C::Digest::new_with_prefix(msg)) + let mut digest = C::Digest::new(); + msg.iter().for_each(|slice| digest.update(slice)); + self.try_sign_digest_with_rng(rng, digest) } } @@ -259,8 +263,10 @@ where Scalar: Invert>>, SignatureSize: ArraySize, { - fn try_sign(&self, msg: &[u8]) -> Result> { - self.try_sign_digest(C::Digest::new_with_prefix(msg)) + fn try_sign(&self, msg: &[&[u8]]) -> Result> { + let mut digest = C::Digest::new(); + msg.iter().for_each(|slice| digest.update(slice)); + self.try_sign_digest(digest) } } @@ -287,7 +293,7 @@ where der::MaxSize: ArraySize, as Add>::Output: Add + ArraySize, { - fn try_sign(&self, msg: &[u8]) -> Result> { + fn try_sign(&self, msg: &[&[u8]]) -> Result> { Signer::>::try_sign(self, msg).map(Into::into) } } @@ -358,7 +364,7 @@ where fn try_sign_with_rng( &self, rng: &mut R, - msg: &[u8], + msg: &[&[u8]], ) -> Result> { RandomizedSigner::>::try_sign_with_rng(self, rng, msg).map(Into::into) } diff --git a/ecdsa/src/verifying.rs b/ecdsa/src/verifying.rs index 8ea4485c..bbedd370 100644 --- a/ecdsa/src/verifying.rs +++ b/ecdsa/src/verifying.rs @@ -177,8 +177,10 @@ where C: EcdsaCurve + CurveArithmetic + DigestPrimitive, SignatureSize: ArraySize, { - fn verify(&self, msg: &[u8], signature: &Signature) -> Result<()> { - self.verify_digest(C::Digest::new_with_prefix(msg), signature) + fn verify(&self, msg: &[&[u8]], signature: &Signature) -> Result<()> { + let mut digest = C::Digest::new(); + msg.iter().for_each(|slice| digest.update(slice)); + self.verify_digest(digest, signature) } } @@ -188,12 +190,28 @@ where C: EcdsaCurve + CurveArithmetic + DigestPrimitive, SignatureSize: ArraySize, { - fn verify(&self, msg: &[u8], sig: &SignatureWithOid) -> Result<()> { + fn verify(&self, msg: &[&[u8]], sig: &SignatureWithOid) -> Result<()> { match sig.oid() { - ECDSA_SHA224_OID => self.verify_prehash(&Sha224::digest(msg), sig.signature()), - ECDSA_SHA256_OID => self.verify_prehash(&Sha256::digest(msg), sig.signature()), - ECDSA_SHA384_OID => self.verify_prehash(&Sha384::digest(msg), sig.signature()), - ECDSA_SHA512_OID => self.verify_prehash(&Sha512::digest(msg), sig.signature()), + ECDSA_SHA224_OID => { + let mut digest = Sha224::new(); + msg.iter().for_each(|slice| digest.update(slice)); + self.verify_prehash(&digest.finalize(), sig.signature()) + } + ECDSA_SHA256_OID => { + let mut digest = Sha256::new(); + msg.iter().for_each(|slice| digest.update(slice)); + self.verify_prehash(&digest.finalize(), sig.signature()) + } + ECDSA_SHA384_OID => { + let mut digest = Sha384::new(); + msg.iter().for_each(|slice| digest.update(slice)); + self.verify_prehash(&digest.finalize(), sig.signature()) + } + ECDSA_SHA512_OID => { + let mut digest = Sha512::new(); + msg.iter().for_each(|slice| digest.update(slice)); + self.verify_prehash(&digest.finalize(), sig.signature()) + } _ => Err(Error::new()), } } @@ -236,7 +254,7 @@ where der::MaxSize: ArraySize, as Add>::Output: Add + ArraySize, { - fn verify(&self, msg: &[u8], signature: &der::Signature) -> Result<()> { + fn verify(&self, msg: &[&[u8]], signature: &der::Signature) -> Result<()> { let signature = Signature::::try_from(signature.clone())?; Verifier::>::verify(self, msg, &signature) } diff --git a/ed25519/src/lib.rs b/ed25519/src/lib.rs index aeab9bf6..97f2cfd3 100644 --- a/ed25519/src/lib.rs +++ b/ed25519/src/lib.rs @@ -43,7 +43,7 @@ //! // NOTE: use `try_sign` if you'd like to be able to handle //! // errors from external signing services/devices (e.g. HSM/KMS) //! // -//! self.signing_key.sign(format_message(person).as_bytes()) +//! self.signing_key.sign(&[format_message(person).as_bytes()]) //! } //! } //! @@ -60,7 +60,7 @@ //! person: &str, //! signature: &ed25519::Signature //! ) -> Result<(), ed25519::Error> { -//! self.verifying_key.verify(format_message(person).as_bytes(), signature) +//! self.verifying_key.verify(&[format_message(person).as_bytes()], signature) //! } //! } //! diff --git a/ed448/src/lib.rs b/ed448/src/lib.rs index eda69318..f98a2069 100644 --- a/ed448/src/lib.rs +++ b/ed448/src/lib.rs @@ -43,7 +43,7 @@ //! // NOTE: use `try_sign` if you'd like to be able to handle //! // errors from external signing services/devices (e.g. HSM/KMS) //! // -//! self.signing_key.sign(format_message(person).as_bytes()) +//! self.signing_key.sign(&[format_message(person).as_bytes()]) //! } //! } //! @@ -60,7 +60,7 @@ //! person: &str, //! signature: &ed448_signature::Signature //! ) -> Result<(), ed448_signature::Error> { -//! self.verifying_key.verify(format_message(person).as_bytes(), signature) +//! self.verifying_key.verify(&[format_message(person).as_bytes()], signature) //! } //! } //! diff --git a/lms/src/lms/mod.rs b/lms/src/lms/mod.rs index c5de9cdb..3cc6112d 100644 --- a/lms/src/lms/mod.rs +++ b/lms/src/lms/mod.rs @@ -32,11 +32,11 @@ mod tests { let msg = "this is a test message".as_bytes(); // Sign the message - let sig = sk.try_sign_with_rng(&mut rng, msg); + let sig = sk.try_sign_with_rng(&mut rng, &[msg]); let sig = sig.unwrap(); // Verify the signature - assert!(pk.verify(msg, &sig).is_ok()); + assert!(pk.verify(&[msg], &sig).is_ok()); } // TODO: macro-generate these exhaustively diff --git a/lms/src/lms/private.rs b/lms/src/lms/private.rs index ec857ddc..9c178ee8 100644 --- a/lms/src/lms/private.rs +++ b/lms/src/lms/private.rs @@ -108,7 +108,7 @@ impl RandomizedSignerMut> for SigningKey { fn try_sign_with_rng( &mut self, rng: &mut R, - msg: &[u8], + msg: &[&[u8]], ) -> Result, Error> { if self.q >= Mode::LEAVES { return Err(Error::from_source(LmsOutOfPrivateKeys {})); @@ -354,7 +354,7 @@ mod tests { let mut rng = ConstantRng(&c); let sig = lms_priv - .try_sign_with_rng(&mut rng, msg) + .try_sign_with_rng(&mut rng, &[msg]) .unwrap() .to_bytes(); assert_eq!(sig.len(), expected_signature.len()); diff --git a/lms/src/lms/public.rs b/lms/src/lms/public.rs index fdf20f00..ee45bdc5 100644 --- a/lms/src/lms/public.rs +++ b/lms/src/lms/public.rs @@ -56,7 +56,7 @@ impl VerifyingKey { } impl Verifier> for VerifyingKey { - fn verify(&self, msg: &[u8], signature: &Signature) -> Result<(), Error> { + fn verify(&self, msg: &[&[u8]], signature: &Signature) -> Result<(), Error> { // Compute the LMS Public Key Candidate Tc from the signature, // message, identifier, pubtype, and ots_typecode, using // Algorithm 6a. diff --git a/lms/src/lms/signature.rs b/lms/src/lms/signature.rs index f0bcd7e2..2cbfc9ec 100644 --- a/lms/src/lms/signature.rs +++ b/lms/src/lms/signature.rs @@ -254,7 +254,7 @@ mod tests { let pk = VerifyingKey::>::try_from(&pk_bytes[..]).unwrap(); let sig = Signature::>::try_from(&sig_bytes[..]).unwrap(); - assert!(pk.verify(&msg[..], &sig).is_ok()); + assert!(pk.verify(&[&msg[..]], &sig).is_ok()); } fn test_serialize_deserialize_random() @@ -272,10 +272,10 @@ mod tests { let mut sk = SigningKey::::new(&mut rng); let pk = sk.public(); let msg = b"Hello, world!"; - let sig = sk.sign_with_rng(&mut rng, msg); + let sig = sk.sign_with_rng(&mut rng, &[msg]); let sig_bytes: Vec<_> = sig.clone().into(); let sig2 = Signature::::try_from(&sig_bytes[..]).unwrap(); - assert!(pk.verify(msg, &sig2).is_ok()); + assert!(pk.verify(&[msg], &sig2).is_ok()); } #[test] diff --git a/lms/src/ots/mod.rs b/lms/src/ots/mod.rs index e2cdfcbd..ac4ad091 100644 --- a/lms/src/ots/mod.rs +++ b/lms/src/ots/mod.rs @@ -47,13 +47,13 @@ pub mod tests { let msg = "this is a test message".as_bytes(); assert!(sk.is_valid()); - let sig = sk.try_sign_with_rng(&mut rng, msg); + let sig = sk.try_sign_with_rng(&mut rng, &[msg]); assert!(!sk.is_valid()); assert!(sig.is_ok()); let sig = sig.unwrap(); - let result = pk.verify(msg, &sig); + let result = pk.verify(&[msg], &sig); assert!(matches!(result, Ok(()))); } @@ -71,7 +71,7 @@ pub mod tests { let msg = "this is a test message".as_bytes(); assert!(sk.is_valid()); - let sig = sk.try_sign_with_rng(&mut rng, msg); + let sig = sk.try_sign_with_rng(&mut rng, &[msg]); assert!(!sk.is_valid()); assert!(sig.is_ok()); @@ -79,7 +79,7 @@ pub mod tests { let sig = sig.unwrap(); // modify q to get the wrong public key pk.q = 1; - let result = pk.verify(msg, &sig); + let result = pk.verify(&[msg], &sig); assert!(result.is_err()); } @@ -163,7 +163,7 @@ pub mod tests { let c = hex!("0eb1ed54a2460d512388cad533138d240534e97b1e82d33bd927d201dfc24ebb"); let mut rng = ConstantRng(&c); let msg = "The enumeration in the Constitution, of certain rights, shall not be construed to deny or disparage others retained by the people.\n".as_bytes(); - let sig = sk.try_sign_with_rng(&mut rng, msg).unwrap(); + let sig = sk.try_sign_with_rng(&mut rng, &[msg]).unwrap(); assert_eq!(sig.c, Array::from(c)); assert_eq!(sig.y[0], Array::from(y0)); diff --git a/lms/src/ots/private.rs b/lms/src/ots/private.rs index 21beb511..87e2be4b 100644 --- a/lms/src/ots/private.rs +++ b/lms/src/ots/private.rs @@ -99,7 +99,7 @@ impl RandomizedSignerMut> for SigningKey fn try_sign_with_rng( &mut self, rng: &mut R, - msg: &[u8], + msg: &[&[u8]], ) -> Result, Error> { if !self.valid { return Err(Error::from_source(LmsOtsInvalidPrivateKey {})); @@ -110,13 +110,13 @@ impl RandomizedSignerMut> for SigningKey rng.try_fill_bytes(&mut c).map_err(|_| Error::new())?; // Q is the randomized message hash - let q = Mode::Hasher::new() - .chain_update(self.id) - .chain_update(self.q.to_be_bytes()) - .chain_update(D_MESG) - .chain_update(&c) - .chain_update(msg) - .finalize(); + let mut q_hasher = Mode::Hasher::new(); + q_hasher.update(self.id); + q_hasher.update(self.q.to_be_bytes()); + q_hasher.update(D_MESG); + q_hasher.update(&c); + msg.iter().for_each(|slice| q_hasher.update(slice)); + let q = q_hasher.finalize(); // Y is the signature. We iterate over the message hash and checksum expanded into Winternitz coefficients let y = Mode::expand(&q).into_iter().enumerate().map(|(i, a)| { diff --git a/lms/src/ots/public.rs b/lms/src/ots/public.rs index d17ea246..d4bda23d 100644 --- a/lms/src/ots/public.rs +++ b/lms/src/ots/public.rs @@ -47,7 +47,7 @@ where Sum<::OutputSize, U2>: ArraySize, { // this implements algorithm 4a of https://datatracker.ietf.org/doc/html/rfc8554#section-4.6 - fn verify(&self, msg: &[u8], signature: &Signature) -> Result<(), Error> { + fn verify(&self, msg: &[&[u8]], signature: &Signature) -> Result<(), Error> { // If the public key is not at least four bytes long, return INVALID. // We are calling this method on a valid public key so there's no worry here. let kc = signature.recover_pubkey(self.id, self.q, msg); diff --git a/lms/src/ots/signature.rs b/lms/src/ots/signature.rs index 0e014c3c..aaedaecb 100644 --- a/lms/src/ots/signature.rs +++ b/lms/src/ots/signature.rs @@ -105,17 +105,17 @@ impl Signature { /// Returns a public key candidate for this signature as defined by /// algorithm 4b of the LMS RFC. The signature will always be valid for /// the returned public key candidate. - pub fn recover_pubkey(&self, id: Identifier, q: u32, msg: &[u8]) -> VerifyingKey { + pub fn recover_pubkey(&self, id: Identifier, q: u32, msg: &[&[u8]]) -> VerifyingKey { // algorithm 4b // Q = H(I || u32str(q) || u16str(D_MESG) || C || message) - let msg_hash = Mode::Hasher::new() - .chain_update(id) - .chain_update(q.to_be_bytes()) - .chain_update(D_MESG) - .chain_update(&self.c) - .chain_update(msg) - .finalize(); + let mut msg_hasher = Mode::Hasher::new(); + msg_hasher.update(id); + msg_hasher.update(q.to_be_bytes()); + msg_hasher.update(D_MESG); + msg_hasher.update(&self.c); + msg.iter().for_each(|slice| msg_hasher.update(slice)); + let msg_hash = msg_hasher.finalize(); // first part of // Kc = H(I || u32str(q) || u16str(D_PBLC) || z[0] || z[1] || ... || z[p-1]) diff --git a/ml-dsa/benches/ml_dsa.rs b/ml-dsa/benches/ml_dsa.rs index 0d2d1e8b..50894488 100644 --- a/ml-dsa/benches/ml_dsa.rs +++ b/ml-dsa/benches/ml_dsa.rs @@ -18,7 +18,7 @@ fn criterion_benchmark(c: &mut Criterion) { let kp = MlDsa65::key_gen_internal(&xi); let sk = kp.signing_key(); let vk = kp.verifying_key(); - let sig = sk.sign_deterministic(&m, &ctx).unwrap(); + let sig = sk.sign_deterministic(&[&m], &ctx).unwrap(); let sk_bytes = sk.encode(); let vk_bytes = vk.encode(); @@ -37,7 +37,7 @@ fn criterion_benchmark(c: &mut Criterion) { c.bench_function("sign", |b| { b.iter(|| { let sk = SigningKey::::decode(&sk_bytes); - let _sig = sk.sign_deterministic(&m, &ctx); + let _sig = sk.sign_deterministic(&[&m], &ctx); }) }); @@ -46,7 +46,7 @@ fn criterion_benchmark(c: &mut Criterion) { b.iter(|| { let vk = VerifyingKey::::decode(&vk_bytes); let sig = Signature::::decode(&sig_bytes).unwrap(); - let _ver = vk.verify_with_context(&m, &ctx, &sig); + let _ver = vk.verify_with_context(&[&m], &ctx, &sig); }) }); @@ -54,8 +54,8 @@ fn criterion_benchmark(c: &mut Criterion) { c.bench_function("round_trip", |b| { b.iter(|| { let kp = MlDsa65::key_gen_internal(&xi); - let sig = kp.signing_key().sign_deterministic(&m, &ctx).unwrap(); - let _ver = kp.verifying_key().verify_with_context(&m, &ctx, &sig); + let sig = kp.signing_key().sign_deterministic(&[&m], &ctx).unwrap(); + let _ver = kp.verifying_key().verify_with_context(&[&m], &ctx, &sig); }) }); } diff --git a/ml-dsa/src/lib.rs b/ml-dsa/src/lib.rs index a3ec3b7f..1fad9199 100644 --- a/ml-dsa/src/lib.rs +++ b/ml-dsa/src/lib.rs @@ -25,9 +25,9 @@ //! let kp = MlDsa65::key_gen(&mut rng); //! //! let msg = b"Hello world"; -//! let sig = kp.signing_key().sign(msg); +//! let sig = kp.signing_key().sign(&[msg]); //! -//! assert!(kp.verifying_key().verify(msg, &sig).is_ok()); +//! assert!(kp.verifying_key().verify(&[msg], &sig).is_ok()); //! # } //! ``` @@ -168,10 +168,10 @@ where // This method takes a slice of slices so that we can accommodate the varying calculations (direct // for test vectors, 0... for sign/sign_deterministic, 1... for the pre-hashed version) without // having to allocate memory for components. -fn message_representative(tr: &[u8], Mp: &[&[u8]]) -> B64 { +fn message_representative(tr: &[u8], Mp: &[&[&[u8]]]) -> B64 { let mut h = H::default().absorb(tr); - for m in Mp { + for m in Mp.iter().flat_map(|slices| slices.iter()) { h = h.absorb(m); } @@ -244,7 +244,7 @@ where /// The `Signer` implementation for `KeyPair` uses the optional deterministic variant of ML-DSA, and /// only supports signing with an empty context string. impl signature::Signer> for KeyPair

{ - fn try_sign(&self, msg: &[u8]) -> Result, Error> { + fn try_sign(&self, msg: &[&[u8]]) -> Result, Error> { self.signing_key.sign_deterministic(msg, &[]) } } @@ -349,7 +349,7 @@ impl SigningKey

{ /// and it does not separate the context string from the rest of the message. // Algorithm 7 ML-DSA.Sign_internal // TODO(RLB) Only expose based on a feature. Tests need access, but normal code shouldn't. - pub fn sign_internal(&self, Mp: &[&[u8]], rnd: &B32) -> Signature

+ pub fn sign_internal(&self, Mp: &[&[&[u8]]], rnd: &B32) -> Signature

where P: MlDsaParams, { @@ -418,7 +418,7 @@ impl SigningKey

{ #[cfg(feature = "rand_core")] pub fn sign_randomized( &self, - M: &[u8], + M: &[&[u8]], ctx: &[u8], rng: &mut R, ) -> Result, Error> { @@ -429,7 +429,7 @@ impl SigningKey

{ let mut rnd = B32::default(); rng.try_fill_bytes(&mut rnd).map_err(|_| Error::new())?; - let Mp = &[&[0], &[Truncate::truncate(ctx.len())], ctx, M]; + let Mp = &[&[&[0], &[Truncate::truncate(ctx.len())], ctx], M]; Ok(self.sign_internal(Mp, &rnd)) } @@ -439,13 +439,13 @@ impl SigningKey

{ /// /// This method will return an opaque error if the context string is more than 255 bytes long. // Algorithm 2 ML-DSA.Sign (optional deterministic variant) - pub fn sign_deterministic(&self, M: &[u8], ctx: &[u8]) -> Result, Error> { + pub fn sign_deterministic(&self, M: &[&[u8]], ctx: &[u8]) -> Result, Error> { if ctx.len() > 255 { return Err(Error::new()); } let rnd = B32::default(); - let Mp = &[&[0], &[Truncate::truncate(ctx.len())], ctx, M]; + let Mp = &[&[&[0], &[Truncate::truncate(ctx.len())], ctx], M]; Ok(self.sign_internal(Mp, &rnd)) } @@ -491,7 +491,7 @@ impl SigningKey

{ /// only supports signing with an empty context string. If you would like to include a context /// string, use the [`SigningKey::sign_deterministic`] method. impl signature::Signer> for SigningKey

{ - fn try_sign(&self, msg: &[u8]) -> Result, Error> { + fn try_sign(&self, msg: &[&[u8]]) -> Result, Error> { self.sign_deterministic(msg, &[]) } } @@ -504,7 +504,7 @@ impl signature::RandomizedSigner> for SigningKey

fn try_sign_with_rng( &self, rng: &mut R, - msg: &[u8], + msg: &[&[u8]], ) -> Result, Error> { self.sign_randomized(msg, &[], rng) } @@ -575,7 +575,7 @@ impl VerifyingKey

{ /// include the domain separator that distinguishes between the normal and pre-hashed cases, /// and it does not separate the context string from the rest of the message. // Algorithm 8 ML-DSA.Verify_internal - pub fn verify_internal(&self, Mp: &[&[u8]], sigma: &Signature

) -> bool + pub fn verify_internal(&self, Mp: &[&[&[u8]]], sigma: &Signature

) -> bool where P: MlDsaParams, { @@ -604,12 +604,12 @@ impl VerifyingKey

{ /// This algorithm reflect the ML-DSA.Verify algorithm from FIPS 204. // Algorithm 3 ML-DSA.Verify - pub fn verify_with_context(&self, M: &[u8], ctx: &[u8], sigma: &Signature

) -> bool { + pub fn verify_with_context(&self, M: &[&[u8]], ctx: &[u8], sigma: &Signature

) -> bool { if ctx.len() > 255 { return false; } - let Mp = &[&[0], &[Truncate::truncate(ctx.len())], ctx, M]; + let Mp = &[&[&[0], &[Truncate::truncate(ctx.len())], ctx], M]; self.verify_internal(Mp, sigma) } @@ -634,7 +634,7 @@ impl VerifyingKey

{ } impl signature::Verifier> for VerifyingKey

{ - fn verify(&self, msg: &[u8], signature: &Signature

) -> Result<(), Error> { + fn verify(&self, msg: &[&[u8]], signature: &Signature

) -> Result<(), Error> { self.verify_with_context(msg, &[], signature) .then_some(()) .ok_or(Error::new()) @@ -889,7 +889,7 @@ mod test { let M = b"Hello world"; let rnd = Array([0u8; 32]); - let sig = sk.sign_internal(&[M], &rnd); + let sig = sk.sign_internal(&[&[M]], &rnd); let sig_bytes = sig.encode(); let sig2 = Signature::

::decode(&sig_bytes).unwrap(); assert!(sig == sig2); @@ -912,9 +912,9 @@ mod test { let M = b"Hello world"; let rnd = Array([0u8; 32]); - let sig = sk.sign_internal(&[M], &rnd); + let sig = sk.sign_internal(&[&[M]], &rnd); - assert!(vk.verify_internal(&[M], &sig)); + assert!(vk.verify_internal(&[&[M]], &sig)); } #[test] @@ -945,13 +945,13 @@ mod test { let M = b"Hello world"; let rnd = Array([0u8; 32]); - let sig = sk.sign_internal(&[M], &rnd); + let sig = sk.sign_internal(&[&[M]], &rnd); let sig_enc = sig.encode(); let sig_dec = Signature::

::decode(&sig_enc).unwrap(); assert_eq!(sig_dec, sig); - assert!(vk.verify_internal(&[M], &sig_dec)); + assert!(vk.verify_internal(&[&[M]], &sig_dec)); } } diff --git a/ml-dsa/tests/proptests.rs b/ml-dsa/tests/proptests.rs index f513873e..5cb08038 100644 --- a/ml-dsa/tests/proptests.rs +++ b/ml-dsa/tests/proptests.rs @@ -26,10 +26,10 @@ prop_compose! { macro_rules! round_trip_test { ($params:path, $keypair:expr) => { - let sig = $keypair.signing_key().sign(MSG); + let sig = $keypair.signing_key().sign(&[MSG]); // Check signature verification - let verify_result = $keypair.verifying_key().verify(MSG, &sig); + let verify_result = $keypair.verifying_key().verify(&[MSG], &sig); prop_assert!(verify_result.is_ok()); // Check signature encoding round trip diff --git a/ml-dsa/tests/sig-gen.rs b/ml-dsa/tests/sig-gen.rs index 07c52c68..7ebf17e1 100644 --- a/ml-dsa/tests/sig-gen.rs +++ b/ml-dsa/tests/sig-gen.rs @@ -35,7 +35,7 @@ fn verify(tc: &acvp::TestCase, deterministic: bool) { } else { B32::try_from(tc.rnd.as_slice()).unwrap() }; - let sig = sk.sign_internal(&[&tc.message], &rnd); + let sig = sk.sign_internal(&[&[&tc.message]], &rnd); let sig_bytes = sig.encode(); assert_eq!(tc.signature.as_slice(), sig_bytes.as_slice()); diff --git a/ml-dsa/tests/sig-ver.rs b/ml-dsa/tests/sig-ver.rs index 2c783e78..b0653ea9 100644 --- a/ml-dsa/tests/sig-ver.rs +++ b/ml-dsa/tests/sig-ver.rs @@ -35,7 +35,7 @@ fn verify(tg: &acvp::TestGroup, tc: &acvp::TestCase) { // Verify the signature if it successfully decoded let test_passed = sig - .map(|sig| vk.verify_internal(&[&tc.message], &sig)) + .map(|sig| vk.verify_internal(&[&[&tc.message]], &sig)) .unwrap_or_default(); assert_eq!(test_passed, tc.test_passed); } diff --git a/slh-dsa/benches/sign_verify.rs b/slh-dsa/benches/sign_verify.rs index 9f010b18..384d623a 100644 --- a/slh-dsa/benches/sign_verify.rs +++ b/slh-dsa/benches/sign_verify.rs @@ -8,7 +8,7 @@ pub fn sign_benchmark(c: &mut Criterion) { c.bench_function(&format!("sign: {}", P::NAME), |b| { b.iter(|| { let msg = b"Hello, world!"; - let sig = sk.try_sign(msg).unwrap(); + let sig = sk.try_sign(&[msg]).unwrap(); black_box(sig) }) }); @@ -18,11 +18,11 @@ pub fn verify_benchmark(c: &mut Criterion) { let mut rng = rand::rng(); let sk = SigningKey::

::new(&mut rng); let msg = b"Hello, world!"; - let sig = sk.try_sign(msg).unwrap(); + let sig = sk.try_sign(&[msg]).unwrap(); let vk = sk.verifying_key(); c.bench_function(&format!("verify: {}", P::NAME), |b| { b.iter(|| { - let ok = vk.verify(msg, &sig); + let ok = vk.verify(&[msg], &sig); black_box(ok) }) }); diff --git a/slh-dsa/src/hashes.rs b/slh-dsa/src/hashes.rs index 24546a11..7fd00a0a 100644 --- a/slh-dsa/src/hashes.rs +++ b/slh-dsa/src/hashes.rs @@ -23,7 +23,7 @@ pub(crate) trait HashSuite: Sized + Clone + Debug + PartialEq + Eq { fn prf_msg( sk_prf: &SkPrf, opt_rand: &Array, - msg: &[impl AsRef<[u8]>], + msg: &[&[impl AsRef<[u8]>]], ) -> Array; /// Hashes a message using a given randomizer @@ -31,7 +31,7 @@ pub(crate) trait HashSuite: Sized + Clone + Debug + PartialEq + Eq { rand: &Array, pk_seed: &PkSeed, pk_root: &Array, - msg: &[impl AsRef<[u8]>], + msg: &[&[impl AsRef<[u8]>]], ) -> Array; /// PRF that is used to generate the secret values in WOTS+ and FORS private keys. @@ -76,7 +76,7 @@ mod tests { let opt_rand = Array::::from_fn(|_| 1); let msg = [2u8; 32]; - let result = H::prf_msg(&sk_prf, &opt_rand, &[msg]); + let result = H::prf_msg(&sk_prf, &opt_rand, &[&[msg]]); assert_eq!(result.as_slice(), expected); } @@ -87,7 +87,7 @@ mod tests { let pk_root = Array::::from_fn(|_| 2); let msg = [3u8; 32]; - let result = H::h_msg(&rand, &pk_seed, &pk_root, &[msg]); + let result = H::h_msg(&rand, &pk_seed, &pk_root, &[&[msg]]); assert_eq!(result.as_slice(), expected); } diff --git a/slh-dsa/src/hashes/sha2.rs b/slh-dsa/src/hashes/sha2.rs index d9959cde..c5a90365 100644 --- a/slh-dsa/src/hashes/sha2.rs +++ b/slh-dsa/src/hashes/sha2.rs @@ -61,11 +61,12 @@ where fn prf_msg( sk_prf: &SkPrf, opt_rand: &Array, - msg: &[impl AsRef<[u8]>], + msg: &[&[impl AsRef<[u8]>]], ) -> Array { let mut mac = Hmac::::new_from_slice(sk_prf.as_ref()).unwrap(); mac.update(opt_rand.as_slice()); msg.iter() + .flat_map(|slices| slices.iter()) .for_each(|msg_part| mac.update(msg_part.as_ref())); let result = mac.finalize().into_bytes(); Array::clone_from_slice(&result[..Self::N::USIZE]) @@ -75,13 +76,15 @@ where rand: &Array, pk_seed: &PkSeed, pk_root: &Array, - msg: &[impl AsRef<[u8]>], + msg: &[&[impl AsRef<[u8]>]], ) -> Array { let mut h = Sha256::new(); h.update(rand); h.update(pk_seed); h.update(pk_root); - msg.iter().for_each(|msg_part| h.update(msg_part.as_ref())); + msg.iter() + .flat_map(|slices| slices.iter()) + .for_each(|msg_part| h.update(msg_part.as_ref())); let result = Array(h.finalize().into()); let seed = rand.clone().concat(pk_seed.0.clone()).concat(result); mgf1::(&seed) @@ -224,11 +227,12 @@ where fn prf_msg( sk_prf: &SkPrf, opt_rand: &Array, - msg: &[impl AsRef<[u8]>], + msg: &[&[impl AsRef<[u8]>]], ) -> Array { let mut mac = Hmac::::new_from_slice(sk_prf.as_ref()).unwrap(); mac.update(opt_rand.as_slice()); msg.iter() + .flat_map(|slices| slices.iter()) .for_each(|msg_part| mac.update(msg_part.as_ref())); let result = mac.finalize().into_bytes(); Array::clone_from_slice(&result[..Self::N::USIZE]) @@ -238,13 +242,15 @@ where rand: &Array, pk_seed: &PkSeed, pk_root: &Array, - msg: &[impl AsRef<[u8]>], + msg: &[&[impl AsRef<[u8]>]], ) -> Array { let mut h = Sha512::new(); h.update(rand); h.update(pk_seed); h.update(pk_root); - msg.iter().for_each(|msg_part| h.update(msg_part.as_ref())); + msg.iter() + .flat_map(|slices| slices.iter()) + .for_each(|msg_part| h.update(msg_part.as_ref())); let result = Array(h.finalize().into()); let seed = rand.clone().concat(pk_seed.0.clone()).concat(result); mgf1::(&seed) diff --git a/slh-dsa/src/hashes/shake.rs b/slh-dsa/src/hashes/shake.rs index 0bc59657..ca9863cd 100644 --- a/slh-dsa/src/hashes/shake.rs +++ b/slh-dsa/src/hashes/shake.rs @@ -35,12 +35,13 @@ where fn prf_msg( sk_prf: &SkPrf, opt_rand: &Array, - msg: &[impl AsRef<[u8]>], + msg: &[&[impl AsRef<[u8]>]], ) -> Array { let mut hasher = Shake256::default(); hasher.update(sk_prf.as_ref()); hasher.update(opt_rand.as_slice()); msg.iter() + .flat_map(|slices| slices.iter()) .for_each(|msg_part| hasher.update(msg_part.as_ref())); let mut output = Array::::default(); hasher.finalize_xof_into(&mut output); @@ -51,13 +52,14 @@ where rand: &Array, pk_seed: &PkSeed, pk_root: &Array, - msg: &[impl AsRef<[u8]>], + msg: &[&[impl AsRef<[u8]>]], ) -> Array { let mut hasher = Shake256::default(); hasher.update(rand.as_slice()); hasher.update(pk_seed.as_ref()); hasher.update(pk_root.as_ref()); msg.iter() + .flat_map(|slices| slices.iter()) .for_each(|msg_part| hasher.update(msg_part.as_ref())); let mut output = Array::::default(); hasher.finalize_xof_into(&mut output); @@ -276,7 +278,7 @@ mod tests { let expected = hex!("bc5c062307df0a41aeeae19ad655f7b2"); - let result = H::prf_msg(&sk_prf, &opt_rand, &[msg]); + let result = H::prf_msg(&sk_prf, &opt_rand, &[&[msg]]); assert_eq!(result.as_slice(), expected); } diff --git a/slh-dsa/src/lib.rs b/slh-dsa/src/lib.rs index 26b2ffb8..eac9372f 100644 --- a/slh-dsa/src/lib.rs +++ b/slh-dsa/src/lib.rs @@ -37,13 +37,13 @@ //! //! // Sign a message //! let message = b"Hello world"; -//! let sig = sk.sign_with_rng(&mut rng, message); // .sign() can be used for deterministic signatures +//! let sig = sk.sign_with_rng(&mut rng, &[message]); // .sign() can be used for deterministic signatures //! //! // Deserialize a verifying key //! let vk_deserialized = vk_bytes.try_into().unwrap(); //! assert_eq!(vk, vk_deserialized); //! -//! assert!(vk_deserialized.verify(message, &sig).is_ok()) +//! assert!(vk_deserialized.verify(&[message], &sig).is_ok()) //! ``` #[cfg(feature = "alloc")] @@ -93,8 +93,8 @@ mod tests { let sk = SigningKey::

::new(&mut rng); let vk = sk.verifying_key(); let msg = b"Hello, world!"; - let sig = sk.try_sign(msg).unwrap(); - vk.verify(msg, &sig).unwrap(); + let sig = sk.try_sign(&[msg]).unwrap(); + vk.verify(&[msg], &sig).unwrap(); } test_parameter_sets!(test_sign_verify); @@ -106,10 +106,10 @@ mod tests { let msg = b"Hello, world!"; let modified_msg = b"Goodbye, world!"; - let sig = sk.try_sign(msg).unwrap(); + let sig = sk.try_sign(&[msg]).unwrap(); let vk = sk.verifying_key(); - assert!(vk.verify(msg, &sig).is_ok()); - assert!(vk.verify(modified_msg, &sig).is_err()); + assert!(vk.verify(&[msg], &sig).is_ok()); + assert!(vk.verify(&[modified_msg], &sig).is_err()); } #[test] @@ -119,11 +119,11 @@ mod tests { let wrong_sk = SigningKey::::new(&mut rng); // Generate a different signing key let msg = b"Hello, world!"; - let sig = sk.try_sign(msg).unwrap(); + let sig = sk.try_sign(&[msg]).unwrap(); let vk = sk.verifying_key(); let wrong_vk = wrong_sk.verifying_key(); // Get the verifying key of the wrong signing key - assert!(vk.verify(msg, &sig).is_ok()); - assert!(wrong_vk.verify(msg, &sig).is_err()); // This should fail because the verifying key does not match the signing key used + assert!(vk.verify(&[msg], &sig).is_ok()); + assert!(wrong_vk.verify(&[msg], &sig).is_err()); // This should fail because the verifying key does not match the signing key used } #[test] @@ -132,7 +132,7 @@ mod tests { let sk = SigningKey::::new(&mut rng); let msg = b"Hello, world!"; - let mut sig_bytes = sk.try_sign(msg).unwrap().to_bytes(); + let mut sig_bytes = sk.try_sign(&[msg]).unwrap().to_bytes(); // Randomly modify one byte in the signature let sig_len = sig_bytes.len(); let random_byte_index = rng.random_range(0..sig_len); @@ -141,7 +141,7 @@ mod tests { let vk = sk.verifying_key(); assert!( - vk.verify(msg, &sig).is_err(), + vk.verify(&[msg], &sig).is_err(), "Verification should fail with a modified signature" ); } @@ -152,8 +152,8 @@ mod tests { let sk = SigningKey::::new(&mut rng); let msg = b"Hello, world!"; - let sig1 = sk.try_sign_with_rng(&mut rng, msg).unwrap(); - let sig2 = sk.try_sign_with_rng(&mut rng, msg).unwrap(); + let sig1 = sk.try_sign_with_rng(&mut rng, &[msg]).unwrap(); + let sig2 = sk.try_sign_with_rng(&mut rng, &[msg]).unwrap(); assert_ne!( sig1, sig2, @@ -168,8 +168,8 @@ mod tests { let vk = sk.verifying_key(); let msg = b"Hello, world!"; let ctx = b"Test context"; - let sig = sk.try_sign_with_context(msg, ctx, None).unwrap(); - vk.try_verify_with_context(msg, ctx, &sig).unwrap(); + let sig = sk.try_sign_with_context(&[msg], ctx, None).unwrap(); + vk.try_verify_with_context(&[msg], ctx, &sig).unwrap(); } #[test] @@ -180,7 +180,7 @@ mod tests { let msg = b"Hello, world!"; let ctx = b"Test context!"; let wrong_ctx = b"Wrong context"; - let sig = sk.try_sign_with_context(msg, ctx, None).unwrap(); - assert!(vk.try_verify_with_context(msg, wrong_ctx, &sig).is_err()); + let sig = sk.try_sign_with_context(&[msg], ctx, None).unwrap(); + assert!(vk.try_verify_with_context(&[msg], wrong_ctx, &sig).is_err()); } } diff --git a/slh-dsa/src/signature_encoding.rs b/slh-dsa/src/signature_encoding.rs index 24c7d6a0..c06c134f 100644 --- a/slh-dsa/src/signature_encoding.rs +++ b/slh-dsa/src/signature_encoding.rs @@ -190,7 +190,7 @@ mod tests { let mut rng = rand::rng(); let sk = SigningKey::

::new(&mut rng); let msg = b"Hello, world!"; - let sig = sk.try_sign(msg).unwrap(); + let sig = sk.try_sign(&[msg]).unwrap(); let sig_bytes = sig.to_bytes(); assert_eq!( sig.encoded_len(), @@ -208,7 +208,7 @@ mod tests { let mut rng = rand::rng(); let sk = SigningKey::

::new(&mut rng); let msg = b"Hello, world!"; - let sig = sk.try_sign(msg).unwrap(); + let sig = sk.try_sign(&[msg]).unwrap(); let sig_vec: alloc::vec::Vec = (&sig).into(); assert_eq!( sig.encoded_len(), @@ -227,7 +227,7 @@ mod tests { let mut rng = rand::rng(); let sk = SigningKey::::new(&mut rng); let msg = b"Hello, world!"; - let sig = sk.try_sign(msg).unwrap(); + let sig = sk.try_sign(&[msg]).unwrap(); let sig_bytes: Array = sig.into(); // Modify the signature bytes to an incorrect length let incorrect_sig_bytes = &sig_bytes[..sig_bytes.len() - 1]; diff --git a/slh-dsa/src/signing_key.rs b/slh-dsa/src/signing_key.rs index e78a3c8e..a90bbe85 100644 --- a/slh-dsa/src/signing_key.rs +++ b/slh-dsa/src/signing_key.rs @@ -132,7 +132,7 @@ impl SigningKey

{ /// Implements [slh_sign_internal] as defined in FIPS-205. /// Published for KAT validation purposes but not intended for general use. /// opt_rand must be a P::N length slice, panics otherwise. - pub fn slh_sign_internal(&self, msg: &[&[u8]], opt_rand: Option<&[u8]>) -> Signature

{ + pub fn slh_sign_internal(&self, msg: &[&[&[u8]]], opt_rand: Option<&[u8]>) -> Signature

{ let rand = opt_rand .unwrap_or(&self.verifying_key.pk_seed.0) .try_into() @@ -164,14 +164,14 @@ impl SigningKey

{ /// Returns an error if the context string is too long. pub fn try_sign_with_context( &self, - msg: &[u8], + msg: &[&[u8]], ctx: &[u8], opt_rand: Option<&[u8]>, ) -> Result, Error> { let ctx_len = u8::try_from(ctx.len()).map_err(|_| Error::new())?; let ctx_len_bytes = ctx_len.to_be_bytes(); - let ctx_msg = [&[0], &ctx_len_bytes, ctx, msg]; + let ctx_msg = [&[&[0], &ctx_len_bytes, ctx], msg]; Ok(self.slh_sign_internal(&ctx_msg, opt_rand)) } @@ -217,7 +217,7 @@ impl TryFrom<&[u8]> for SigningKey

{ } impl Signer> for SigningKey

{ - fn try_sign(&self, msg: &[u8]) -> Result, Error> { + fn try_sign(&self, msg: &[&[u8]]) -> Result, Error> { self.try_sign_with_context(msg, &[], None) } } @@ -226,7 +226,7 @@ impl RandomizedSigner> for SigningKey

{ fn try_sign_with_rng( &self, rng: &mut R, - msg: &[u8], + msg: &[&[u8]], ) -> Result, signature::Error> { let mut randomizer = Array::::default(); rng.try_fill_bytes(randomizer.as_mut_slice()) diff --git a/slh-dsa/src/verifying_key.rs b/slh-dsa/src/verifying_key.rs index 1c39d5f3..5deb50db 100644 --- a/slh-dsa/src/verifying_key.rs +++ b/slh-dsa/src/verifying_key.rs @@ -57,7 +57,7 @@ impl VerifyingKey

{ /// Published for KAT validation purposes but not intended for general use. pub fn slh_verify_internal( &self, - msg: &[&[u8]], + msg: &[&[&[u8]]], signature: &Signature

, ) -> Result<(), Error> { let pk_seed = &self.pk_seed; @@ -81,14 +81,14 @@ impl VerifyingKey

{ /// Returns an error if the context is too long or if the signature is invalid pub fn try_verify_with_context( &self, - msg: &[u8], + msg: &[&[u8]], ctx: &[u8], signature: &Signature

, ) -> Result<(), Error> { let ctx_len = u8::try_from(ctx.len()).map_err(|_| Error::new())?; let ctx_len_bytes = ctx_len.to_be_bytes(); - let ctx_msg = [&[0], &ctx_len_bytes, ctx, msg]; + let ctx_msg = [&[&[0], &ctx_len_bytes, ctx], msg]; self.slh_verify_internal(&ctx_msg, signature) // TODO - context processing } @@ -150,7 +150,7 @@ impl TryFrom<&[u8]> for VerifyingKey

{ } impl Verifier> for VerifyingKey

{ - fn verify(&self, msg: &[u8], signature: &Signature

) -> Result<(), Error> { + fn verify(&self, msg: &[&[u8]], signature: &Signature

) -> Result<(), Error> { self.try_verify_with_context(msg, &[], signature) // TODO - context processing } } diff --git a/slh-dsa/tests/acvp_sig.rs b/slh-dsa/tests/acvp_sig.rs index a1c93c11..88fd024e 100644 --- a/slh-dsa/tests/acvp_sig.rs +++ b/slh-dsa/tests/acvp_sig.rs @@ -39,7 +39,7 @@ macro_rules! parameter_case { .additionalRandomness .as_ref() .map(|x| x.data.as_slice()); - let sig = sk.slh_sign_internal(&[$test_case.message.data.as_slice()], opt_rand); + let sig = sk.slh_sign_internal(&[&[$test_case.message.data.as_slice()]], opt_rand); assert_eq!(sig.to_vec(), $test_case.signature.data); }}; } diff --git a/slh-dsa/tests/acvp_ver.rs b/slh-dsa/tests/acvp_ver.rs index 4bd82f70..40fe5d3b 100644 --- a/slh-dsa/tests/acvp_ver.rs +++ b/slh-dsa/tests/acvp_ver.rs @@ -36,7 +36,7 @@ macro_rules! parameter_case { ($param:ident, $test_case:expr) => {{ let sk = VerifyingKey::<$param>::try_from($test_case.pk.data.as_slice()).unwrap(); if let Ok(sig) = $test_case.signature.data.as_slice().try_into() { - let success = sk.slh_verify_internal(&[$test_case.message.data.as_slice()], &sig); + let success = sk.slh_verify_internal(&[&[$test_case.message.data.as_slice()]], &sig); assert_eq!($test_case.testPassed, success.is_ok()); } else { assert!(!$test_case.testPassed); diff --git a/slh-dsa/tests/known_answer_tests.rs b/slh-dsa/tests/known_answer_tests.rs index a7bfcb9b..dfd034f7 100644 --- a/slh-dsa/tests/known_answer_tests.rs +++ b/slh-dsa/tests/known_answer_tests.rs @@ -142,7 +142,7 @@ where let mut opt_rand = vec![0; P::VkLen::USIZE / 2]; rng.fill_bytes(opt_rand.as_mut()); - let sig = sk.slh_sign_internal(&[msg], Some(&opt_rand)).to_bytes(); + let sig = sk.slh_sign_internal(&[&[msg]], Some(&opt_rand)).to_bytes(); writeln!(resp, "smlen = {}", sig.as_slice().len() + msg.len()).unwrap(); writeln!( resp,