From 5db6a203c550630fc516543786c42cc8f6a0a987 Mon Sep 17 00:00:00 2001 From: Quant-TheodoreFelix <53819958+Quant-TheodoreFelix@users.noreply.github.com> Date: Wed, 10 Jun 2026 20:22:24 +0900 Subject: [PATCH 1/5] Remove Vec returns from Hash and MAC traits, add const generic HashFixedOutput and MACFixedOutput --- crypto/core/src/traits.rs | 116 +++++++++++++++++++++++++++----------- 1 file changed, 83 insertions(+), 33 deletions(-) diff --git a/crypto/core/src/traits.rs b/crypto/core/src/traits.rs index 3713fcb..d82971a 100644 --- a/crypto/core/src/traits.rs +++ b/crypto/core/src/traits.rs @@ -24,10 +24,6 @@ pub trait Hash : Default { /// The size of the output in bytes. fn output_len(&self) -> usize; - /// A static one-shot API that hashes the provided data. - /// `data` can be of any length, including zero bytes. - fn hash(self, data: &[u8]) -> Vec; - /// A static one-shot API that hashes the provided data into the provided output slice. /// `data` can be of any length, including zero bytes. /// The entire output buffer is zeroized before the hash output is written. @@ -40,11 +36,6 @@ pub trait Hash : Default { // fn do_update(&mut self, data: &[u8]) -> Result<(), HashError>; fn do_update(&mut self, data: &[u8]); - /// Finish absorbing input and produce the hashes output. - /// Consumes self, so this must be the final call to this object. - // fn do_final(self) -> Result, HashError>; - fn do_final(self) -> Vec; - /// Finish absorbing input and produce the hashes output. /// Consumes self, so this must be the final call to this object. /// @@ -57,14 +48,6 @@ pub trait Hash : Default { /// The return value is the number of bytes written. fn do_final_out(self, output: &mut [u8]) -> usize; - /// The same as [Hash::do_final], but allows for supplying a partial byte as the last input. - /// Assumes that the input is in the least significant bits (big endian). - fn do_final_partial_bits( - self, - partial_byte: u8, - num_partial_bits: usize, - ) -> Result, HashError>; - /// The same as [Hash::do_final_out], but allows for supplying a partial byte as the last input. /// Assumes that the input is in the least significant bits (big endian). /// will be placed in the first [Hash::output_len] bytes. @@ -81,6 +64,49 @@ pub trait Hash : Default { fn max_security_strength(&self) -> SecurityStrength; } +/// An extension to [Hash] for algorithms whose output length is known at compile time. +/// +/// `OUTPUT_LEN` is the output length of the hash in bytes and must equal [Hash::output_len]; +/// implementors are expected to declare it via the matching [HashAlgParams::OUTPUT_LEN] constant, +/// for example `impl HashFixedOutput<{ SHA256Params::OUTPUT_LEN }> for SHA256 {}`. +/// +/// The provided methods return fixed-size arrays instead of heap allocations, so they are +/// usable in `no_std` environments and keep all intermediate state on the stack. +/// Runtime-dispatching wrappers (such as factory enums) whose output length varies by variant +/// cannot implement this trait and offer only the `*_out` functions of [Hash]. +pub trait HashFixedOutput: Hash { + /// A static one-shot API that hashes the provided data. + /// `data` can be of any length, including zero bytes. + fn hash(self, data: &[u8]) -> [u8; OUTPUT_LEN] { + let mut output = [0u8; OUTPUT_LEN]; + let written = self.hash_out(data, &mut output); + debug_assert_eq!(written, OUTPUT_LEN); + output + } + + /// Finish absorbing input and produce the hashes output. + /// Consumes self, so this must be the final call to this object. + fn do_final(self) -> [u8; OUTPUT_LEN] { + let mut output = [0u8; OUTPUT_LEN]; + let written = self.do_final_out(&mut output); + debug_assert_eq!(written, OUTPUT_LEN); + output + } + + /// The same as [HashFixedOutput::do_final], but allows for supplying a partial byte as the last input. + /// Assumes that the input is in the least significant bits (big endian). + fn do_final_partial_bits( + self, + partial_byte: u8, + num_partial_bits: usize, + ) -> Result<[u8; OUTPUT_LEN], HashError> { + let mut output = [0u8; OUTPUT_LEN]; + let written = self.do_final_partial_bits_out(partial_byte, num_partial_bits, &mut output)?; + debug_assert_eq!(written, OUTPUT_LEN); + Ok(output) + } +} + pub trait HashAlgParams: Algorithm { const OUTPUT_LEN: usize; const BLOCK_LEN: usize; @@ -234,13 +260,14 @@ pub trait KEMPrivateKey : PartialEq + Eq + Clone + Secret + /// A MAC algorithm takes in a key and some data, and produces a MAC (message authentication code) that /// can be used to verify the integrity of data. /// -/// This trait provides one-shot functions [MAC::mac], [MAC::mac_out], and [MAC::verify]. -/// It also provides streaming functions [MAC::do_update], [MAC::do_final], [MAC::do_final_out], +/// This trait provides one-shot functions [MAC::mac_out] and [MAC::verify]. +/// It also provides streaming functions [MAC::do_update], [MAC::do_final_out], /// and [MAC::do_verify_final]. +/// Fixed-size variants that return the MAC value as an array are provided by [MACFixedOutput]. /// The workflow is that a MAC object is initialized with a key with [MAC::new] -- or [MAC::new_allow_weak_key] if you /// need to disable the library's safety mechanism to prevent the use of weak keys -- then data is /// processed into one or more calls to [MAC::do_update], -/// after that the object can either create a MAC with [MAC::do_final] or [MAC::do_final_out] (which are final functions, and so consume the object), +/// after that the object can either create a MAC with [MACFixedOutput::do_final] or [MAC::do_final_out] (which are final functions, and so consume the object), /// or the object can be used to verify a MAC. /// /// For varifying an existing MAC, it is functionally equivalent to use the provided [MAC::verify] and [MAC::do_verify_final] @@ -282,17 +309,6 @@ pub trait MAC: Sized { /// The size of the output in bytes. fn output_len(&self) -> usize; - /// One-shot API that computes a MAC for the provided data. - /// `data` can be of any length, including zero bytes. - /// - /// Note about the security strength of the provided key: - /// If the provided key is tagged at a lower [SecurityStrength] than the instantiated MAC algorithm, - /// this will fail with an error: - /// ```text - /// MACError::KeyMaterialError(KeyMaterialError::SecurityStrength("HMAC::init(): provided key has a lower security strength than the instantiated HMAC") - /// ``` - fn mac(self, data: &[u8]) -> Vec; - /// One-shot API that computes a MAC for the provided data and writes it into the provided output slice. /// `data` can be of any length, including zero bytes. /// @@ -321,8 +337,6 @@ pub trait MAC: Sized { /// do_update() is intended to be used as part of a streaming interface, and so may by called multiple times. fn do_update(&mut self, data: &[u8]); - fn do_final(self) -> Vec; - /// Depending on the underlying MAC implementation, NIST may require that the library enforce /// a minimum length on the mac output value. See documentation for the underlying implementation /// to see conditions under which it throws [MACError::InvalidLength]. @@ -344,6 +358,42 @@ pub trait MAC: Sized { fn max_security_strength(&self) -> SecurityStrength; } +/// An extension to [MAC] for algorithms whose output length is known at compile time. +/// +/// `OUTPUT_LEN` is the full (untruncated) MAC output length in bytes and must equal [MAC::output_len]. +/// +/// The provided methods return fixed-size arrays instead of heap allocations, so they are +/// usable in `no_std` environments and keep all intermediate state on the stack. +/// Runtime-dispatching wrappers (such as factory enums) whose output length varies by variant +/// cannot implement this trait and offer only the `*_out` functions of [MAC]. +pub trait MACFixedOutput: MAC { + /// One-shot API that computes a MAC for the provided data. + /// `data` can be of any length, including zero bytes. + fn mac(self, data: &[u8]) -> [u8; OUTPUT_LEN] { + let mut output = [0u8; OUTPUT_LEN]; + // Infallible: OUTPUT_LEN is the full MAC output length, so the minimum-length + // check on truncated MAC values in mac_out() cannot fail. + let written = self + .mac_out(data, &mut output) + .expect("MACFixedOutput::mac(): full-length output buffer was rejected"); + debug_assert_eq!(written, OUTPUT_LEN); + output + } + + /// Finish absorbing input and produce the MAC value. + /// Consumes self, so this must be the final call to this object. + fn do_final(self) -> [u8; OUTPUT_LEN] { + let mut output = [0u8; OUTPUT_LEN]; + // Infallible: OUTPUT_LEN is the full MAC output length, so the minimum-length + // check on truncated MAC values in do_final_out() cannot fail. + let written = self + .do_final_out(&mut output) + .expect("MACFixedOutput::do_final(): full-length output buffer was rejected"); + debug_assert_eq!(written, OUTPUT_LEN); + output + } +} + #[derive(Eq, PartialEq, PartialOrd, Clone, Debug)] pub enum SecurityStrength { None, From 346d8a1e5f54bf501d9fd55c224a9d4a8b1b3bf5 Mon Sep 17 00:00:00 2001 From: Quant-TheodoreFelix <53819958+Quant-TheodoreFelix@users.noreply.github.com> Date: Wed, 10 Jun 2026 20:22:24 +0900 Subject: [PATCH 2/5] Implement the fixed output traits in SHA2, SHA3 and HMAC - replace hmac internal vec allocations with zeroized stack buffers --- crypto/hmac/src/lib.rs | 47 ++++++++++++++++++--------------------- crypto/sha2/src/lib.rs | 20 +++++++++++------ crypto/sha2/src/sha256.rs | 24 -------------------- crypto/sha2/src/sha512.rs | 24 -------------------- crypto/sha3/src/lib.rs | 25 ++++++++++++--------- crypto/sha3/src/sha3.rs | 29 ------------------------ 6 files changed, 50 insertions(+), 119 deletions(-) diff --git a/crypto/hmac/src/lib.rs b/crypto/hmac/src/lib.rs index c63c249..064eb1b 100644 --- a/crypto/hmac/src/lib.rs +++ b/crypto/hmac/src/lib.rs @@ -53,12 +53,12 @@ //! ``` //! //! ## Computing a MAC -//! MAC functionality is accessed via the [MAC] trait. +//! MAC functionality is accessed via the [MAC] and [MACFixedOutput] traits. //! //! The simplest usage is via the one-shot functions. //! ``` //! use bouncycastle_hmac::HMAC_SHA256; -//! use bouncycastle_core::traits::MAC; +//! use bouncycastle_core::traits::{MAC, MACFixedOutput}; //! use bouncycastle_core::key_material::{KeyMaterial256, KeyType}; //! //! let key = KeyMaterial256::from_bytes_as_type( @@ -67,7 +67,7 @@ //! //! let data: &[u8] = b"Hello, world!"; //! let hmac = HMAC_SHA256::new(&key).expect("Should succeed because key is long enough and tagged KeyType::MACKey"); -//! let output: Vec = hmac.mac(data); +//! let output: [u8; 32] = hmac.mac(data); //! ``` //! //! More advanced usage will require creating an HMAC object to hold state between successive calls, @@ -75,7 +75,7 @@ //! //! ``` //! use bouncycastle_core::key_material::{KeyMaterial256, KeyType}; -//! use bouncycastle_core::traits::MAC; +//! use bouncycastle_core::traits::{MAC, MACFixedOutput}; //! use bouncycastle_hmac::HMAC_SHA256; //! //! let key = KeyMaterial256::from_bytes_as_type( @@ -84,7 +84,7 @@ //! let mut hmac = HMAC_SHA256::new(&key).expect("Should succeed because key is long enough and tagged KeyType::MACKey"); //! hmac.do_update(b"Hello,"); //! hmac.do_update(b" world!"); -//! let output: Vec = hmac.do_final(); +//! let output: [u8; 32] = hmac.do_final(); //! ``` //! //! ## Verifying a MAC @@ -115,7 +115,7 @@ //! ``` //! //! Similarly, a streaming version is available, which is identical to the streaming interface for -//! computing a mac value, but calls [MAC::do_verify_final] instead of [MAC::do_final]. +//! computing a mac value, but calls [MAC::do_verify_final] instead of [MACFixedOutput::do_final]. //! //! ``` //! use bouncycastle_core::key_material::{KeyMaterial256, KeyType}; @@ -159,7 +159,7 @@ use bouncycastle_core::errors::{KeyMaterialError, MACError}; use bouncycastle_core::key_material::{KeyMaterialTrait, KeyType}; -use bouncycastle_core::traits::{Algorithm, Hash, MAC, SecurityStrength}; +use bouncycastle_core::traits::{Algorithm, Hash, HashFixedOutput, MAC, MACFixedOutput, SecurityStrength}; use bouncycastle_sha2::{SHA224, SHA256, SHA384, SHA512}; use bouncycastle_sha3::{SHA3_224, SHA3_256, SHA3_384, SHA3_512}; use bouncycastle_utils::ct; @@ -337,14 +337,15 @@ impl HMAC { // scratch pad here: if we're truncating the output but not // truncating the underlying hashes, we'd lose bytes and compute an // invalid outer hashes. - // TODO: rework this to be no_std friendly (ie no vec!) - let mut ihash = vec![0u8; self.hasher.output_len()]; - self.hasher.do_final_out(&mut ihash); + let mut ihash = [0u8; LARGEST_HASHER_OUTPUT_LEN]; + let ihash_len = self.hasher.output_len(); + self.hasher.do_final_out(&mut ihash[..ihash_len]); // ohash self.hasher = HASH::default(); self.pad_key_into_hasher(OPAD_BYTE); - self.hasher.do_update(&ihash); + self.hasher.do_update(&ihash[..ihash_len]); + ihash.fill(0); Ok(self.hasher.do_final_out(out)) } } @@ -373,12 +374,6 @@ impl MAC for HMAC { self.hasher.output_len() } - fn mac(self, data: &[u8]) -> Vec { - let mut out = vec![0_u8; self.hasher.output_len()]; - let bytes_written = self.mac_out(data, &mut out).expect("HMAC::mac(): should not have failed because we gave it a sufficiently large output buffer to meet FIPS rules."); - out[..bytes_written].to_vec() - } - fn mac_out(mut self, data: &[u8], mut out: &mut [u8]) -> Result { out.fill(0); @@ -395,12 +390,6 @@ impl MAC for HMAC { self.hasher.do_update(data) } - fn do_final(self) -> Vec { - let mut out = vec![0_u8; self.hasher.output_len()]; - self.do_final_internal_out(&mut out).expect("HMAC::do_final(): should not have failed because we gave it a sufficiently large output buffer to meet FIPS rules."); - out - } - fn do_final_out(self, mut out: &mut [u8]) -> Result { out.fill(0); @@ -408,15 +397,23 @@ impl MAC for HMAC { } fn do_verify_final(self, mac: &[u8]) -> bool { - let mut out = vec![0_u8; HASH::default().output_len()]; + let mut out = [0_u8; LARGEST_HASHER_OUTPUT_LEN]; let output_len = self.do_final_internal_out(&mut out).expect("HMAC::do_final(): should not have failed because we gave it a sufficiently large output buffer to meet FIPS rules."); if mac.len() != output_len { + out.fill(0); return false; } - ct::ct_eq_bytes(mac, &out[..output_len]) + let matches = ct::ct_eq_bytes(mac, &out[..output_len]); + out.fill(0); + matches } fn max_security_strength(&self) -> SecurityStrength { HASH::default().max_security_strength() } } + +impl + Default, const OUTPUT_LEN: usize> MACFixedOutput + for HMAC +{ +} diff --git a/crypto/sha2/src/lib.rs b/crypto/sha2/src/lib.rs index b3582fc..4224622 100644 --- a/crypto/sha2/src/lib.rs +++ b/crypto/sha2/src/lib.rs @@ -2,23 +2,24 @@ //! //! # Examples //! ## Hash -//! Hash functionality is accessed via the [bouncycastle_core::traits::Hash] trait, -//! which is implemented by [SHA224], [SHA256], [SHA384] and [SHA512]. +//! Hash functionality is accessed via the [bouncycastle_core::traits::Hash] and +//! [bouncycastle_core::traits::HashFixedOutput] traits, +//! which are implemented by [SHA224], [SHA256], [SHA384] and [SHA512]. //! //! The simplest usage is via the static functions. //! ``` -//! use bouncycastle_core::traits::Hash; +//! use bouncycastle_core::traits::HashFixedOutput; //! use bouncycastle_sha2 as sha2; //! //! let data: &[u8] = b"Hello, world!"; -//! let output: Vec = sha2::SHA256::new().hash(data); +//! let output: [u8; 32] = sha2::SHA256::new().hash(data); //! ``` //! //! More advanced usage will require creating a SHA3 or SHAKE object to hold state between successive calls, //! for example if input is received in chunks and not all available at the same time: //! //! ``` -//! use bouncycastle_core::traits::Hash; +//! use bouncycastle_core::traits::{Hash, HashFixedOutput}; //! use bouncycastle_sha2 as sha2; //! //! let data: &[u8] = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F @@ -31,7 +32,7 @@ //! sha2.do_update(chunk); //! } //! -//! let output: Vec = sha2.do_final(); +//! let output: [u8; 32] = sha2.do_final(); //! ``` #![forbid(unsafe_code)] @@ -42,7 +43,7 @@ mod sha512; pub use self::sha256::SHA256Internal; pub use self::sha512::Sha512Internal; -use bouncycastle_core::traits::{Algorithm, HashAlgParams, SecurityStrength}; +use bouncycastle_core::traits::{Algorithm, HashAlgParams, HashFixedOutput, SecurityStrength}; /*** String constants ***/ pub const SHA224_NAME: &str = "SHA224"; @@ -135,3 +136,8 @@ impl HashAlgParams for SHA512Params { const BLOCK_LEN: usize = 128; } impl SHA2Params for SHA512Params {} + +impl HashFixedOutput<{ SHA224Params::OUTPUT_LEN }> for SHA224 {} +impl HashFixedOutput<{ SHA256Params::OUTPUT_LEN }> for SHA256 {} +impl HashFixedOutput<{ SHA384Params::OUTPUT_LEN }> for SHA384 {} +impl HashFixedOutput<{ SHA512Params::OUTPUT_LEN }> for SHA512 {} diff --git a/crypto/sha2/src/sha256.rs b/crypto/sha2/src/sha256.rs index 7073c59..8ae480a 100644 --- a/crypto/sha2/src/sha256.rs +++ b/crypto/sha2/src/sha256.rs @@ -190,12 +190,6 @@ impl Hash for SHA256Internal { PARAMS::OUTPUT_LEN } - fn hash(self, data: &[u8]) -> Vec { - let mut output = vec![0u8; PARAMS::OUTPUT_LEN]; - self.hash_out(data, &mut output); - output - } - fn hash_out(mut self, data: &[u8], output: &mut [u8]) -> usize { output.fill(0); @@ -236,12 +230,6 @@ impl Hash for SHA256Internal { self.x_buf_off = remaining; } - fn do_final(self) -> Vec { - let mut output = vec![0u8; PARAMS::OUTPUT_LEN]; - self.do_final_out(&mut output); - output - } - fn do_final_out(mut self, output: &mut [u8]) -> usize { output.fill(0); @@ -276,18 +264,6 @@ impl Hash for SHA256Internal { n } - /// TODO: This is defined in FIPS 180-4 s. 5.1.2 - /// TODO: - /// TODO: Could implement if there is demand. - #[allow(unused)] - fn do_final_partial_bits( - self, - partial_byte: u8, - num_partial_bits: usize, - ) -> Result, HashError> { - unimplemented!() - } - /// TODO: This is defined in FIPS 180-4 s. 5.1.2 /// TODO: /// TODO: Could implement if there is demand. diff --git a/crypto/sha2/src/sha512.rs b/crypto/sha2/src/sha512.rs index c404fc6..5e3c8b2 100644 --- a/crypto/sha2/src/sha512.rs +++ b/crypto/sha2/src/sha512.rs @@ -202,12 +202,6 @@ impl Hash for Sha512Internal { PARAMS::OUTPUT_LEN } - fn hash(self, data: &[u8]) -> Vec { - let mut output = vec![0u8; self.output_len()]; - self.hash_out(data, &mut output); - output - } - fn hash_out(mut self, data: &[u8], output: &mut [u8]) -> usize { output.fill(0); @@ -247,12 +241,6 @@ impl Hash for Sha512Internal { self.x_buf_off = remaining; } - fn do_final(self) -> Vec { - let mut output = vec![0u8; PARAMS::OUTPUT_LEN]; - self.do_final_out(&mut output); - output - } - fn do_final_out(mut self, output: &mut [u8]) -> usize { output.fill(0); @@ -288,18 +276,6 @@ impl Hash for Sha512Internal { n } - /// TODO: This is defined in FIPS 180-4 s. 5.1.2 - /// TODO: - /// TODO: Could implement if there is demand. - #[allow(unused)] - fn do_final_partial_bits( - self, - partial_byte: u8, - num_partial_bits: usize, - ) -> Result, HashError> { - unimplemented!() - } - /// TODO: This is defined in FIPS 180-4 s. 5.1.2 /// TODO: /// TODO: Could implement if there is demand. diff --git a/crypto/sha3/src/lib.rs b/crypto/sha3/src/lib.rs index 42ecac4..24bbf92 100644 --- a/crypto/sha3/src/lib.rs +++ b/crypto/sha3/src/lib.rs @@ -2,23 +2,23 @@ //! //! # Examples //! ## Hash -//! Hash functionality is accessed via the [Hash] trait, -//! which is implemented by [SHA3_224], [SHA3_256], [SHA3_384] and [SHA3_512]. +//! Hash functionality is accessed via the [Hash] and [HashFixedOutput] traits, +//! which are implemented by [SHA3_224], [SHA3_256], [SHA3_384] and [SHA3_512]. //! //! The simplest usage is via the one-shot functions. //! ``` -//! use bouncycastle_core::traits::Hash; +//! use bouncycastle_core::traits::HashFixedOutput; //! use bouncycastle_sha3 as sha3; //! //! let data: &[u8] = b"Hello, world!"; -//! let output: Vec = sha3::SHA3_256::new().hash(data); +//! let output: [u8; 32] = sha3::SHA3_256::new().hash(data); //! ``` //! //! More advanced usage will require creating a SHA3 or SHAKE object to hold state between successive calls, //! for example if input is received in chunks and not all available at the same time: //! //! ``` -//! use bouncycastle_core::traits::Hash; +//! use bouncycastle_core::traits::{Hash, HashFixedOutput}; //! use bouncycastle_sha3 as sha3; //! //! let data: &[u8] = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F @@ -31,20 +31,20 @@ //! sha3.do_update(chunk); //! } //! -//! let output: Vec = sha3.do_final(); +//! let output: [u8; 32] = sha3.do_final(); //! ``` //! //! It is also possible to provide input where the final byte contains less than 8 bits of data (ie is a partial byte); //! for example, the following code uses only 3 bits of the final byte: //! ``` -//! use bouncycastle_core::traits::Hash; +//! use bouncycastle_core::traits::{Hash, HashFixedOutput}; //! use bouncycastle_sha3 as sha3; //! //! let data: &[u8] = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"; //! let mut sha3 = sha3::SHA3_256::new(); //! sha3.do_update(&data[..data.len()-1]); //! let final_byte = data[data.len()-1]; -//! let output: Vec = sha3.do_final_partial_bits(final_byte, 3).expect("Failed to finalize hash state."); +//! let output: [u8; 32] = sha3.do_final_partial_bits(final_byte, 3).expect("Failed to finalize hash state."); //! ``` //! //! ## XOF @@ -63,7 +63,7 @@ //! ``` //! //! As with [Hash] above, the [XOF] trait has streaming APIs in the form of [XOF::absorb] and [XOF::squeeze]. -//! Unlike [Hash::do_final], [XOF::squeeze] can be called multiple times. +//! Unlike [HashFixedOutput::do_final], [XOF::squeeze] can be called multiple times. //! The following code produces the same output as the previous example: //!``` //! use bouncycastle_core::traits::XOF; @@ -108,7 +108,7 @@ #![allow(private_bounds)] use crate::keccak::KeccakSize; -use bouncycastle_core::traits::{Algorithm, HashAlgParams, SecurityStrength}; +use bouncycastle_core::traits::{Algorithm, HashAlgParams, HashFixedOutput, SecurityStrength}; // imports needed for docs #[allow(unused_imports)] @@ -239,6 +239,11 @@ impl SHA3Params for SHA3_512Params { const SIZE: KeccakSize = KeccakSize::_512; } +impl HashFixedOutput<{ SHA3_224Params::OUTPUT_LEN }> for SHA3_224 {} +impl HashFixedOutput<{ SHA3_256Params::OUTPUT_LEN }> for SHA3_256 {} +impl HashFixedOutput<{ SHA3_384Params::OUTPUT_LEN }> for SHA3_384 {} +impl HashFixedOutput<{ SHA3_512Params::OUTPUT_LEN }> for SHA3_512 {} + trait SHAKEParams: Algorithm { const SIZE: KeccakSize; } diff --git a/crypto/sha3/src/sha3.rs b/crypto/sha3/src/sha3.rs index ed5656c..8c40e8d 100644 --- a/crypto/sha3/src/sha3.rs +++ b/crypto/sha3/src/sha3.rs @@ -116,12 +116,6 @@ impl Hash for SHA3 { PARAMS::OUTPUT_LEN } - fn hash(self, data: &[u8]) -> Vec { - let mut output: Vec = vec![0u8; PARAMS::OUTPUT_LEN]; - _ = self.hash_internal(data, &mut output[..]); - output - } - fn hash_out(self, data: &[u8], mut output: &mut [u8]) -> usize { output.fill(0); @@ -132,15 +126,6 @@ impl Hash for SHA3 { self.keccak.absorb(data) } - fn do_final(self) -> Vec { - let dbg_rslt_len = self.output_len(); - let mut output: Vec = vec![0u8; self.output_len()]; - let bytes_written = self.do_final_out(output.as_mut_slice()); - debug_assert_eq!(bytes_written, dbg_rslt_len); - - output - } - // todo -- why doesn't this take a &mut [u8; HASH_LEN] ? // That's probably more user-friendly than this auto-truncating that I have here. fn do_final_out(mut self, output: &mut [u8]) -> usize { @@ -158,20 +143,6 @@ impl Hash for SHA3 { bytes_written } - fn do_final_partial_bits( - self, - partial_byte: u8, - num_partial_bits: usize, - ) -> Result, HashError> { - let dbg_rslt_len = self.output_len(); - let mut output: Vec = vec![0u8; self.output_len()]; - let bytes_written = - self.do_final_partial_bits_out(partial_byte, num_partial_bits, output.as_mut_slice())?; - debug_assert_eq!(bytes_written, dbg_rslt_len); - - Ok(output) - } - fn do_final_partial_bits_out( mut self, partial_byte: u8, From 80db9c12c5cbac25bcedf25b239c75ff4d180c5b Mon Sep 17 00:00:00 2001 From: Quant-TheodoreFelix <53819958+Quant-TheodoreFelix@users.noreply.github.com> Date: Wed, 10 Jun 2026 20:22:24 +0900 Subject: [PATCH 3/5] Drop the removed Vec functions from factory dispatch, switch factory docs to the _out functions --- crypto/factory/src/hash_factory.rs | 51 ++++-------------------------- crypto/factory/src/lib.rs | 4 ++- crypto/factory/src/mac_factory.rs | 32 +++---------------- crypto/factory/src/rng_factory.rs | 8 +++-- 4 files changed, 19 insertions(+), 76 deletions(-) diff --git a/crypto/factory/src/hash_factory.rs b/crypto/factory/src/hash_factory.rs index 9d12117..8d602e5 100644 --- a/crypto/factory/src/hash_factory.rs +++ b/crypto/factory/src/hash_factory.rs @@ -12,7 +12,9 @@ //! let data: &[u8] = b"Hello, world!"; //! //! let h = bouncycastle_factory::hash_factory::HashFactory::new(sha3::SHA3_256_NAME).unwrap(); -//! let output: Vec = h.hash(data); +//! let mut output = [0u8; 64]; +//! let written = h.hash_out(data, &mut output); +//! let digest = &output[..written]; //! ``` //! You can equivalently invoke this by string instead of using the constant: //! @@ -23,7 +25,9 @@ //! let data: &[u8] = b"Hello, world!"; //! //! let h = bouncycastle_factory::hash_factory::HashFactory::new("SHA3-256").unwrap(); -//! let output: Vec = h.hash(data); +//! let mut output = [0u8; 64]; +//! let written = h.hash_out(data, &mut output); +//! let digest = &output[..written]; //! ``` use crate::{AlgorithmFactory, FactoryError}; @@ -115,19 +119,6 @@ impl Hash for HashFactory { } } - fn hash(self, data: &[u8]) -> Vec { - match self { - Self::SHA224(h) => h.hash(data), - Self::SHA256(h) => h.hash(data), - Self::SHA384(h) => h.hash(data), - Self::SHA512(h) => h.hash(data), - Self::SHA3_224(h) => h.hash(data), - Self::SHA3_256(h) => h.hash(data), - Self::SHA3_384(h) => h.hash(data), - Self::SHA3_512(h) => h.hash(data), - } - } - fn hash_out(self, data: &[u8], output: &mut [u8]) -> usize { output.fill(0); @@ -156,19 +147,6 @@ impl Hash for HashFactory { } } - fn do_final(self) -> Vec { - match self { - Self::SHA224(h) => h.do_final(), - Self::SHA256(h) => h.do_final(), - Self::SHA384(h) => h.do_final(), - Self::SHA512(h) => h.do_final(), - Self::SHA3_224(h) => h.do_final(), - Self::SHA3_256(h) => h.do_final(), - Self::SHA3_384(h) => h.do_final(), - Self::SHA3_512(h) => h.do_final(), - } - } - fn do_final_out(self, output: &mut [u8]) -> usize { output.fill(0); @@ -184,23 +162,6 @@ impl Hash for HashFactory { } } - fn do_final_partial_bits( - self, - partial_byte: u8, - num_partial_bits: usize, - ) -> Result, HashError> { - match self { - Self::SHA224(h) => h.do_final_partial_bits(partial_byte, num_partial_bits), - Self::SHA256(h) => h.do_final_partial_bits(partial_byte, num_partial_bits), - Self::SHA384(h) => h.do_final_partial_bits(partial_byte, num_partial_bits), - Self::SHA512(h) => h.do_final_partial_bits(partial_byte, num_partial_bits), - Self::SHA3_224(h) => h.do_final_partial_bits(partial_byte, num_partial_bits), - Self::SHA3_256(h) => h.do_final_partial_bits(partial_byte, num_partial_bits), - Self::SHA3_384(h) => h.do_final_partial_bits(partial_byte, num_partial_bits), - Self::SHA3_512(h) => h.do_final_partial_bits(partial_byte, num_partial_bits), - } - } - fn do_final_partial_bits_out( self, partial_byte: u8, diff --git a/crypto/factory/src/lib.rs b/crypto/factory/src/lib.rs index 3f6d974..870cd60 100644 --- a/crypto/factory/src/lib.rs +++ b/crypto/factory/src/lib.rs @@ -15,7 +15,9 @@ //! let data: &[u8] = b"Hello, world!"; //! //! let h = HashFactory::new("SHA3-256").unwrap(); -//! let output: Vec = h.hash(data); +//! let mut output = [0u8; 64]; +//! let written = h.hash_out(data, &mut output); +//! let digest = &output[..written]; //! ``` //! //! All other factory types similarly implement their underlying trait and thus behave the same way. diff --git a/crypto/factory/src/mac_factory.rs b/crypto/factory/src/mac_factory.rs index 141c59f..0adb3f0 100644 --- a/crypto/factory/src/mac_factory.rs +++ b/crypto/factory/src/mac_factory.rs @@ -23,11 +23,13 @@ //! let hmac = MACFactory::new(bouncycastle_hmac::HMAC_SHA3_256_NAME, &key).unwrap(); //! //! // Generate the MAC value -//! let mac_value: Vec = hmac.mac(data); +//! let mut mac_buf = [0u8; 64]; +//! let written = hmac.mac_out(data, &mut mac_buf).unwrap(); +//! let mac_value = &mac_buf[..written]; //! //! // Verify the MAC value //! let hmac = MACFactory::new(bouncycastle_hmac::HMAC_SHA3_256_NAME, &key).unwrap(); -//! if hmac.verify(data, &mac_value,) { +//! if hmac.verify(data, mac_value,) { //! println!("MAC verified successfully!") //! } else { //! println!("MAC verification failed") @@ -161,19 +163,6 @@ impl MAC for MACFactory { } } - fn mac(self, data: &[u8]) -> Vec { - match self { - Self::HMAC_SHA224(h) => h.mac(data), - Self::HMAC_SHA256(h) => h.mac(data), - Self::HMAC_SHA384(h) => h.mac(data), - Self::HMAC_SHA512(h) => h.mac(data), - Self::HMAC_SHA3_224(h) => h.mac(data), - Self::HMAC_SHA3_256(h) => h.mac(data), - Self::HMAC_SHA3_384(h) => h.mac(data), - Self::HMAC_SHA3_512(h) => h.mac(data), - } - } - fn mac_out(self, data: &[u8], out: &mut [u8]) -> Result { out.fill(0); @@ -215,19 +204,6 @@ impl MAC for MACFactory { } } - fn do_final(self) -> Vec { - match self { - Self::HMAC_SHA224(h) => h.do_final(), - Self::HMAC_SHA256(h) => h.do_final(), - Self::HMAC_SHA384(h) => h.do_final(), - Self::HMAC_SHA512(h) => h.do_final(), - Self::HMAC_SHA3_224(h) => h.do_final(), - Self::HMAC_SHA3_256(h) => h.do_final(), - Self::HMAC_SHA3_384(h) => h.do_final(), - Self::HMAC_SHA3_512(h) => h.do_final(), - } - } - fn do_final_out(self, mut out: &mut [u8]) -> Result { out.fill(0); diff --git a/crypto/factory/src/rng_factory.rs b/crypto/factory/src/rng_factory.rs index f1792d1..a90bca0 100644 --- a/crypto/factory/src/rng_factory.rs +++ b/crypto/factory/src/rng_factory.rs @@ -27,7 +27,9 @@ //! let data: &[u8] = b"Hello, world!"; //! //! let h = bouncycastle_factory::hash_factory::HashFactory::new(sha3::SHA3_256_NAME).unwrap(); -//! let output: Vec = h.hash(data); +//! let mut output = [0u8; 64]; +//! let written = h.hash_out(data, &mut output); +//! let digest = &output[..written]; //! ``` //! You can equivalently invoke this by string instead of using the constant: //! @@ -38,7 +40,9 @@ //! let data: &[u8] = b"Hello, world!"; //! //! let h = bouncycastle_factory::hash_factory::HashFactory::new("SHA3-256").unwrap(); -//! let output: Vec = h.hash(data); +//! let mut output = [0u8; 64]; +//! let written = h.hash_out(data, &mut output); +//! let digest = &output[..written]; //! ``` use bouncycastle_core::errors::RNGError; From e0df0e6a12a7787d78ba090dfa322772cd4188d4 Mon Sep 17 00:00:00 2001 From: Quant-TheodoreFelix <53819958+Quant-TheodoreFelix@users.noreply.github.com> Date: Wed, 10 Jun 2026 20:22:24 +0900 Subject: [PATCH 4/5] Replace do_final try_into unwrap with direct array output in hash mldsa, adjust mlkem imports --- crypto/mldsa/src/hash_mldsa.rs | 12 ++++++++---- crypto/mldsa_lowmemory/src/hash_mldsa.rs | 12 ++++++++---- crypto/mlkem/src/mlkem_keys.rs | 2 +- crypto/mlkem_lowmemory/src/mlkem_keys.rs | 2 +- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/crypto/mldsa/src/hash_mldsa.rs b/crypto/mldsa/src/hash_mldsa.rs index 52fbdc8..6f5d751 100644 --- a/crypto/mldsa/src/hash_mldsa.rs +++ b/crypto/mldsa/src/hash_mldsa.rs @@ -29,14 +29,14 @@ //! ```rust //! use bouncycastle_core::errors::SignatureError; //! use bouncycastle_mldsa::{HashMLDSA65_with_SHA512, MLDSATrait, HashMLDSA44_with_SHA512}; -//! use bouncycastle_core::traits::{Signature, PHSignature, Hash}; +//! use bouncycastle_core::traits::{Signature, PHSignature, HashFixedOutput}; //! use bouncycastle_sha2::SHA512; //! //! let msg = b"The quick brown fox jumped over the lazy dog"; //! //! // Here, and in contrast to External Mu mode of ML-DSA, we can pre-hash the message before //! // even generating the signing key. -//! let ph: [u8; 64] = SHA512::default().hash(msg).as_slice().try_into().unwrap(); +//! let ph: [u8; 64] = SHA512::default().hash(msg); //! //! //! let (pk, sk) = HashMLDSA65_with_SHA512::keygen().unwrap(); @@ -898,7 +898,9 @@ impl< } fn sign_final_out(self, output: &mut [u8; SIG_LEN]) -> Result { - let ph: [u8; PH_LEN] = self.hash.do_final().try_into().unwrap(); + let mut ph = [0u8; PH_LEN]; + let written = self.hash.do_final_out(&mut ph); + debug_assert_eq!(written, PH_LEN); if self.sk.is_none() && self.seed.is_none() { return Err(SignatureError::GenericError( @@ -975,7 +977,9 @@ impl< self.pk.is_some(), "Somehow you managed to construct a streaming verifier without a public key, impressive!" ); - let ph: [u8; PH_LEN] = self.hash.do_final().try_into().unwrap(); + let mut ph = [0u8; PH_LEN]; + let written = self.hash.do_final_out(&mut ph); + debug_assert_eq!(written, PH_LEN); Self::verify_ph(&self.pk.unwrap(), &ph, Some(&self.ctx[..self.ctx_len]), sig) } } diff --git a/crypto/mldsa_lowmemory/src/hash_mldsa.rs b/crypto/mldsa_lowmemory/src/hash_mldsa.rs index 99140fa..a678273 100644 --- a/crypto/mldsa_lowmemory/src/hash_mldsa.rs +++ b/crypto/mldsa_lowmemory/src/hash_mldsa.rs @@ -28,7 +28,7 @@ //! //! ```rust //! use bouncycastle_core::errors::SignatureError; -//! use bouncycastle_core::traits::{Signature, PHSignature, Hash}; +//! use bouncycastle_core::traits::{Signature, PHSignature, HashFixedOutput}; //! use bouncycastle_sha2::SHA512; //! use bouncycastle_mldsa_lowmemory::{MLDSATrait, HashMLDSA65_with_SHA512, HashMLDSA44_with_SHA512}; //! @@ -36,7 +36,7 @@ //! //! // Here, and in contrast to External Mu mode of ML-DSA, we can pre-hash the message before //! // even generating the signing key. -//! let ph: [u8; 64] = SHA512::default().hash(msg).as_slice().try_into().unwrap(); +//! let ph: [u8; 64] = SHA512::default().hash(msg); //! //! //! let (pk, sk) = HashMLDSA65_with_SHA512::keygen().unwrap(); @@ -843,7 +843,9 @@ impl< } fn sign_final_out(self, output: &mut [u8; SIG_LEN]) -> Result { - let ph: [u8; PH_LEN] = self.hash.do_final().try_into().unwrap(); + let mut ph = [0u8; PH_LEN]; + let written = self.hash.do_final_out(&mut ph); + debug_assert_eq!(written, PH_LEN); if self.sk.is_none() && self.seed.is_none() { return Err(SignatureError::GenericError( @@ -923,7 +925,9 @@ impl< self.pk.is_some(), "Somehow you managed to construct a streaming verifier without a public key, impressive!" ); - let ph: [u8; PH_LEN] = self.hash.do_final().try_into().unwrap(); + let mut ph = [0u8; PH_LEN]; + let written = self.hash.do_final_out(&mut ph); + debug_assert_eq!(written, PH_LEN); Self::verify_ph(&self.pk.unwrap(), &ph, Some(&self.ctx[..self.ctx_len]), &sig[..SIG_LEN]) } } diff --git a/crypto/mlkem/src/mlkem_keys.rs b/crypto/mlkem/src/mlkem_keys.rs index a93934d..7661123 100644 --- a/crypto/mlkem/src/mlkem_keys.rs +++ b/crypto/mlkem/src/mlkem_keys.rs @@ -9,7 +9,7 @@ use crate::mlkem::{MLKEM1024_PK_LEN, MLKEM1024_SK_LEN, MLKEM1024_k}; use crate::{ML_KEM_512_NAME, ML_KEM_768_NAME, ML_KEM_1024_NAME}; use bouncycastle_core::errors::KEMError; use bouncycastle_core::key_material::{KeyMaterial, KeyMaterialTrait, KeyType}; -use bouncycastle_core::traits::{Hash, KEMPrivateKey, KEMPublicKey, Secret, SecurityStrength}; +use bouncycastle_core::traits::{Hash, HashFixedOutput, KEMPrivateKey, KEMPublicKey, Secret, SecurityStrength}; use bouncycastle_sha3::SHA3_256; diff --git a/crypto/mlkem_lowmemory/src/mlkem_keys.rs b/crypto/mlkem_lowmemory/src/mlkem_keys.rs index b9e58f3..5de6791 100644 --- a/crypto/mlkem_lowmemory/src/mlkem_keys.rs +++ b/crypto/mlkem_lowmemory/src/mlkem_keys.rs @@ -19,7 +19,7 @@ use crate::polynomial::Polynomial; use crate::{ML_KEM_512_NAME, ML_KEM_768_NAME, ML_KEM_1024_NAME}; use bouncycastle_core::errors::KEMError; use bouncycastle_core::key_material::{KeyMaterial, KeyMaterialTrait, KeyType}; -use bouncycastle_core::traits::{Hash, KEMPrivateKey, KEMPublicKey, Secret, SecurityStrength}; +use bouncycastle_core::traits::{Hash, HashFixedOutput, KEMPrivateKey, KEMPublicKey, Secret, SecurityStrength}; use bouncycastle_sha3::SHA3_256; use core::fmt; use core::fmt::{Debug, Display, Formatter}; From 1f43b9bdebbc7a5cc031a2aabbb69a4d4442196c Mon Sep 17 00:00:00 2001 From: Quant-TheodoreFelix <53819958+Quant-TheodoreFelix@users.noreply.github.com> Date: Wed, 10 Jun 2026 20:22:24 +0900 Subject: [PATCH 5/5] Adapt test framework, tests and CLI to the trait split, update release notes --- alpha_0.1.2_release_notes.md | 14 +++- cli/src/mac_cmd.rs | 7 +- cli/src/sha2_cmd.rs | 6 +- cli/src/sha3_cmd.rs | 6 +- crypto/core-test-framework/src/hash.rs | 17 ++--- crypto/core-test-framework/src/mac.rs | 8 +-- crypto/core-test-framework/src/signature.rs | 6 +- crypto/factory/tests/hash_factory_tests.rs | 58 ++++++++------- crypto/hmac/tests/hmac_tests.rs | 71 ++++++++++--------- crypto/mldsa/tests/bc_test_data.rs | 17 ++--- crypto/mldsa/tests/hash_mldsa_tests.rs | 24 +++---- crypto/mldsa_lowmemory/tests/bc_test_data.rs | 17 ++--- .../mldsa_lowmemory/tests/hash_mldsa_tests.rs | 10 +-- crypto/sha2/tests/sha2_tests.rs | 42 +++++------ crypto/sha3/tests/sha3_tests.rs | 37 +++++----- 15 files changed, 176 insertions(+), 164 deletions(-) diff --git a/alpha_0.1.2_release_notes.md b/alpha_0.1.2_release_notes.md index d6609db..61befa8 100644 --- a/alpha_0.1.2_release_notes.md +++ b/alpha_0.1.2_release_notes.md @@ -17,8 +17,9 @@ * Ensure that all crates have `#![forbid(missing_docs)]` * Apply Secret trait consistently across the library --> study the `Zeroize` trait in RustCrypto * Change all "[u8;0]" to "[]" throughout the code and docs ... or better yet, change the APIs to take an Option<> -* Change all `-> Vec` to `-> [u8; CONST_LEN]`, and the `output: &mut [u8]` to `output: &mut [u8; CONST_LEN]` where - appropriate. +* Change the `output: &mut [u8]` to `output: &mut [u8; CONST_LEN]` where appropriate. (The `-> Vec` half of this + item is done, see changelog. The `*_out` slice parameters were deliberately left as `&mut [u8]` because the + documented truncation / oversized-buffer semantics depend on them; revisit per-API.) * Probably it makes sense to leave Hex and Base64 as requiring std; ... or maybe add a no_std version that uses fixed-sized blocks? * Create a cargo feature #[cfg(feature='rng')] and put it around things like keygen that takes an rng so that the build @@ -52,6 +53,15 @@ * ML-DSA * Low-Memory ML-DSA -- runs in about 1/10th of the usual memory (~ 30 kb of stack) with only minor performance impact. +* (Breaking, progress on #14) Removed all heap-allocating `-> Vec` functions from the `Hash` and `MAC` traits + (`hash`, `do_final`, `do_final_partial_bits`, `mac`). They are replaced by the new `HashFixedOutput` + and `MACFixedOutput` traits which return `[u8; OUTPUT_LEN]` stack arrays, following the same + const-generic pattern as the `KEM` and `Signature` traits. All concrete algorithms (SHA2, SHA3, HMAC) implement the + new traits; the factory enums keep only the `*_out` functions because their output length is a runtime property. + The XOF functions (`hash_xof`, `squeeze`) keep returning `Vec` because their output length is inherently a + runtime parameter. +* HMAC no longer heap-allocates its intermediate inner digest (was an internal `vec!`, now a fixed stack buffer), + and the inner digest buffer is zeroized after use. * All public `*_out(.., out: &mut [u8])` functions now begin by zeroizing the entire output buffer with `.fill(0)`, preventing exposure of stale data in oversized output buffers or on early error returns. * Github issues resolved: diff --git a/cli/src/mac_cmd.rs b/cli/src/mac_cmd.rs index 3a4e98d..8a6e8b6 100644 --- a/cli/src/mac_cmd.rs +++ b/cli/src/mac_cmd.rs @@ -63,14 +63,17 @@ fn do_mac(mut mac: impl MAC, verify_val: &Option, output_hex: bool) { if verify_val.is_none() { // compute a MAC value - let out = mac.do_final(); + let mut out = [0u8; 64]; + let bytes_written = + mac.do_final_out(&mut out).expect("Failed to compute the MAC value"); + let out = &out[..bytes_written]; if output_hex { for b in out.iter() { print!("{b:02x}"); } } else { - io::stdout().write(&out).unwrap(); + io::stdout().write(out).unwrap(); } println!(); } else { diff --git a/cli/src/sha2_cmd.rs b/cli/src/sha2_cmd.rs index 4007a13..45f6627 100644 --- a/cli/src/sha2_cmd.rs +++ b/cli/src/sha2_cmd.rs @@ -24,12 +24,14 @@ fn do_sha2(mut sha2: impl Hash, output_hex: bool) { bytes_read = io::stdin().read(&mut buf).expect("Failed to read from stdin"); } - let out = sha2.do_final(); + let mut out = [0u8; 64]; + let bytes_written = sha2.do_final_out(&mut out); + let out = &out[..bytes_written]; if output_hex { for b in out.iter() { print!("{b:02x}"); } - } else { io::stdout().write(&out).unwrap(); } + } else { io::stdout().write(out).unwrap(); } println!(); } \ No newline at end of file diff --git a/cli/src/sha3_cmd.rs b/cli/src/sha3_cmd.rs index 3efa6a7..3905343 100644 --- a/cli/src/sha3_cmd.rs +++ b/cli/src/sha3_cmd.rs @@ -25,13 +25,15 @@ fn do_sha3(mut sha3: impl Hash, output_hex: bool) { bytes_read = io::stdin().read(&mut buf).expect("Failed to read from stdin"); } - let out = sha3.do_final(); + let mut out = [0u8; 64]; + let bytes_written = sha3.do_final_out(&mut out); + let out = &out[..bytes_written]; if output_hex { for b in out.iter() { print!("{b:02x}"); } - } else { io::stdout().write(&out).unwrap(); } + } else { io::stdout().write(out).unwrap(); } println!(); } diff --git a/crypto/core-test-framework/src/hash.rs b/crypto/core-test-framework/src/hash.rs index 8bcc000..a901ed5 100644 --- a/crypto/core-test-framework/src/hash.rs +++ b/crypto/core-test-framework/src/hash.rs @@ -1,4 +1,4 @@ -use bouncycastle_core::traits::{Hash, HashAlgParams}; +use bouncycastle_core::traits::{HashAlgParams, HashFixedOutput}; pub struct TestFrameworkHash { pub enable_partial_final_input_tests: bool, @@ -13,17 +13,18 @@ impl TestFrameworkHash { /// This gives good baseline test coverage, but is not exhaustive; for example it does not test /// do_final_partial_bits() or do_final_partial_bits_out() /// because those require different input-output pairs. - pub fn test_hash( + pub fn test_hash + HashAlgParams + Default, const N: usize>( &self, input: &[u8], expected_output: &[u8], ) { /*** fn result_len() -> usize ***/ assert_eq!(H::default().output_len(), H::OUTPUT_LEN); + assert_eq!(N, H::OUTPUT_LEN); - /*** fn hash(self, data: &[u8]) -> Vec **/ - let output_vec = H::default().hash(input); - assert_eq!(output_vec, expected_output); + /*** fn hash(self, data: &[u8]) -> [u8; N] **/ + let output_arr = H::default().hash(input); + assert_eq!(&output_arr[..], expected_output); /*** fn hash_out(self, data: &[u8], output: &mut [u8]) -> Result ***/ let mut output_buf = vec![0_u8; H::OUTPUT_LEN]; @@ -31,12 +32,12 @@ impl TestFrameworkHash { assert_eq!(output_buf, expected_output); /*** fn do_update(&mut self, data: &[u8]) -> Result<(), HashError> ***/ - /*** fn do_final(self) -> Result, HashError> **/ + /*** fn do_final(self) -> [u8; N] **/ let mut message_digest = H::default(); message_digest.do_update(input); let output_buf = message_digest.do_final(); - assert_eq!(expected_output, output_buf, "Incorrect output for input (update_bytes)"); + assert_eq!(expected_output, &output_buf[..], "Incorrect output for input (update_bytes)"); for length in 1..output_buf.len() { let mut truncated = vec![0_u8; length]; @@ -58,7 +59,7 @@ impl TestFrameworkHash { message_digest.do_update(chunk); } let output_buf = message_digest.do_final(); - assert_eq!(expected_output, output_buf, "Incorrect output for input (update_bytes)"); + assert_eq!(expected_output, &output_buf[..], "Incorrect output for input (update_bytes)"); /*** fn do_update(&mut self, data: &[u8]) -> Result<(), HashError> ***/ /*** fn do_final_out(self, output: &mut [u8]) -> Result ***/ diff --git a/crypto/core-test-framework/src/mac.rs b/crypto/core-test-framework/src/mac.rs index 728e35c..babc5eb 100644 --- a/crypto/core-test-framework/src/mac.rs +++ b/crypto/core-test-framework/src/mac.rs @@ -1,7 +1,7 @@ use crate::DUMMY_SEED_512; use bouncycastle_core::errors::{KeyMaterialError, MACError}; use bouncycastle_core::key_material::{KeyMaterial512, KeyType, KeyMaterialTrait}; -use bouncycastle_core::traits::MAC; +use bouncycastle_core::traits::MACFixedOutput; use bouncycastle_core::traits::{SecurityStrength}; pub struct TestFrameworkMAC { @@ -15,7 +15,7 @@ impl TestFrameworkMAC { /// Test all the members of trait Hash against the given input-output pair. /// This gives good baseline test coverage, but is not exhaustive. - pub fn test_mac( + pub fn test_mac, const N: usize>( &self, key: &impl KeyMaterialTrait, input: &[u8], @@ -23,7 +23,7 @@ impl TestFrameworkMAC { ) { // Test ::mac() let out = M::new_allow_weak_key(key).unwrap().mac(input); - assert_eq!(out, expected_output); + assert_eq!(&out[..], expected_output); // Test ::mac_out let mut out = vec![0u8; expected_output.len()]; @@ -53,7 +53,7 @@ impl TestFrameworkMAC { let output_len = mac.output_len(); mac.do_update(input); let out = mac.do_final(); - assert_eq!(out, expected_output); + assert_eq!(&out[..], expected_output); // Test .output_len() assert_eq!(output_len, out.len()); diff --git a/crypto/core-test-framework/src/signature.rs b/crypto/core-test-framework/src/signature.rs index d97dc0c..9dc5b7b 100644 --- a/crypto/core-test-framework/src/signature.rs +++ b/crypto/core-test-framework/src/signature.rs @@ -254,14 +254,16 @@ impl TestFrameworkSignature { // sign_ph let (pk, sk) = SigAlg::keygen().unwrap(); - let ph: [u8; PH_LEN] = HASH::default().hash(msg)[..PH_LEN].try_into().unwrap(); + let mut ph = [0u8; PH_LEN]; + HASH::default().hash_out(msg, &mut ph); let sig_val = SigAlg::sign_ph(&sk, &ph, None).unwrap(); SigAlg::verify(&pk, msg, None, &sig_val).unwrap(); SigAlg::verify_ph(&pk, &ph, None, &sig_val).unwrap(); // sign_ph_out let (pk, sk) = SigAlg::keygen().unwrap(); - let ph: [u8; PH_LEN] = HASH::default().hash(msg)[..PH_LEN].try_into().unwrap(); + let mut ph = [0u8; PH_LEN]; + HASH::default().hash_out(msg, &mut ph); let mut sig_val = [0u8; SIG_LEN]; let bytes_written = SigAlg::sign_ph_out(&sk, &ph, None, &mut sig_val).unwrap(); assert_eq!(bytes_written, SIG_LEN); diff --git a/crypto/factory/tests/hash_factory_tests.rs b/crypto/factory/tests/hash_factory_tests.rs index 55221ee..daa5751 100644 --- a/crypto/factory/tests/hash_factory_tests.rs +++ b/crypto/factory/tests/hash_factory_tests.rs @@ -3,7 +3,13 @@ mod hash_factory_tests { use bouncycastle_factory::AlgorithmFactory; use bouncycastle_factory::hash_factory::{HashFactory}; use bouncycastle_factory::xof_factory::{XOFFactory}; - use bouncycastle_core::traits::{Hash, XOF}; + use bouncycastle_core::traits::{Hash, HashFixedOutput, XOF}; + + fn factory_hash(h: HashFactory, data: &[u8]) -> Vec { + let mut out = vec![0u8; h.output_len()]; + h.hash_out(data, &mut out); + out + } use bouncycastle_core_test_framework::DUMMY_SEED_512; mod sha3_tests { @@ -23,39 +29,39 @@ mod hash_factory_tests { let sha2 = HashFactory::new("SHA224").unwrap(); assert_eq!(sha2.output_len(), 28); - assert_eq!(sha2.hash(DUMMY_SEED_512), b"\xb8\x06\x0c\xcc\x82\xd4\x0c\x57\x61\x56\xf7\xca\x03\x33\xe4\x38\x9e\x41\x0d\xf0\x27\xd2\xfb\x8f\x76\x4f\xa6\x03"); + assert_eq!(factory_hash(sha2, DUMMY_SEED_512), b"\xb8\x06\x0c\xcc\x82\xd4\x0c\x57\x61\x56\xf7\xca\x03\x33\xe4\x38\x9e\x41\x0d\xf0\x27\xd2\xfb\x8f\x76\x4f\xa6\x03"); let sha2 = HashFactory::new(sha2::SHA224_NAME).unwrap(); assert_eq!(sha2.output_len(), 28); - assert_eq!(sha2.hash(DUMMY_SEED_512), b"\xb8\x06\x0c\xcc\x82\xd4\x0c\x57\x61\x56\xf7\xca\x03\x33\xe4\x38\x9e\x41\x0d\xf0\x27\xd2\xfb\x8f\x76\x4f\xa6\x03"); + assert_eq!(factory_hash(sha2, DUMMY_SEED_512), b"\xb8\x06\x0c\xcc\x82\xd4\x0c\x57\x61\x56\xf7\xca\x03\x33\xe4\x38\x9e\x41\x0d\xf0\x27\xd2\xfb\x8f\x76\x4f\xa6\x03"); // SHA256 let sha2 = HashFactory::new("SHA256").unwrap(); assert_eq!(sha2.output_len(), 32); - assert_eq!(sha2.hash(DUMMY_SEED_512), b"\x11\x00\x09\xdc\xee\x21\x62\x0b\x16\x6f\x3a\xbf\xec\xb5\xef\xf7\xa8\x73\xbe\x72\x9d\x1c\x2d\x53\x82\x2e\x7a\xcc\x5f\x34\xeb\x9b"); + assert_eq!(factory_hash(sha2, DUMMY_SEED_512), b"\x11\x00\x09\xdc\xee\x21\x62\x0b\x16\x6f\x3a\xbf\xec\xb5\xef\xf7\xa8\x73\xbe\x72\x9d\x1c\x2d\x53\x82\x2e\x7a\xcc\x5f\x34\xeb\x9b"); let sha2 = HashFactory::new(sha2::SHA256_NAME).unwrap(); assert_eq!(sha2.output_len(), 32); - assert_eq!(sha2.hash(DUMMY_SEED_512), b"\x11\x00\x09\xdc\xee\x21\x62\x0b\x16\x6f\x3a\xbf\xec\xb5\xef\xf7\xa8\x73\xbe\x72\x9d\x1c\x2d\x53\x82\x2e\x7a\xcc\x5f\x34\xeb\x9b"); + assert_eq!(factory_hash(sha2, DUMMY_SEED_512), b"\x11\x00\x09\xdc\xee\x21\x62\x0b\x16\x6f\x3a\xbf\xec\xb5\xef\xf7\xa8\x73\xbe\x72\x9d\x1c\x2d\x53\x82\x2e\x7a\xcc\x5f\x34\xeb\x9b"); // SHA384 let sha2 = HashFactory::new("SHA384").unwrap(); assert_eq!(sha2.output_len(), 48); - assert_eq!(sha2.hash(DUMMY_SEED_512), b"\x45\x82\xfc\x82\x43\x0e\x52\x68\x86\xa1\x85\x34\x11\xe6\x06\x45\xfe\xf7\xe8\xea\x0c\x85\x46\xb7\xc9\xba\x0c\x84\x16\xd9\xa9\x8f\xb5\x2e\xbd\x0c\x60\x5f\xbb\x70\x74\x9c\x4e\x3e\x5d\xa3\xdb\xac"); + assert_eq!(factory_hash(sha2, DUMMY_SEED_512), b"\x45\x82\xfc\x82\x43\x0e\x52\x68\x86\xa1\x85\x34\x11\xe6\x06\x45\xfe\xf7\xe8\xea\x0c\x85\x46\xb7\xc9\xba\x0c\x84\x16\xd9\xa9\x8f\xb5\x2e\xbd\x0c\x60\x5f\xbb\x70\x74\x9c\x4e\x3e\x5d\xa3\xdb\xac"); let sha2 = HashFactory::new(sha2::SHA384_NAME).unwrap(); assert_eq!(sha2.output_len(), 48); - assert_eq!(sha2.hash(DUMMY_SEED_512), b"\x45\x82\xfc\x82\x43\x0e\x52\x68\x86\xa1\x85\x34\x11\xe6\x06\x45\xfe\xf7\xe8\xea\x0c\x85\x46\xb7\xc9\xba\x0c\x84\x16\xd9\xa9\x8f\xb5\x2e\xbd\x0c\x60\x5f\xbb\x70\x74\x9c\x4e\x3e\x5d\xa3\xdb\xac"); + assert_eq!(factory_hash(sha2, DUMMY_SEED_512), b"\x45\x82\xfc\x82\x43\x0e\x52\x68\x86\xa1\x85\x34\x11\xe6\x06\x45\xfe\xf7\xe8\xea\x0c\x85\x46\xb7\xc9\xba\x0c\x84\x16\xd9\xa9\x8f\xb5\x2e\xbd\x0c\x60\x5f\xbb\x70\x74\x9c\x4e\x3e\x5d\xa3\xdb\xac"); // SHA512 let sha2 = HashFactory::new("SHA512").unwrap(); assert_eq!(sha2.output_len(), 64); - assert_eq!(sha2.hash(DUMMY_SEED_512), b"\xed\xb9\xbe\xd7\x21\xaa\x6a\x5f\x6f\xbc\x66\x19\xd3\xa3\xc2\xbe\x3d\x04\x30\x43\xf0\x5a\x9a\xeb\xc7\xb1\x19\x7a\x2a\xa9\xc4\x9a\x57\xd5\xdd\xd4\x67\x4c\x17\x85\x78\x50\x88\xd9\xf1\xff\x42\xc7\x97\xa0\x2a\xdc\x9b\x81\x7a\x13\x9a\x50\x97\x0d\xa6\xc9\x95\x24"); + assert_eq!(factory_hash(sha2, DUMMY_SEED_512), b"\xed\xb9\xbe\xd7\x21\xaa\x6a\x5f\x6f\xbc\x66\x19\xd3\xa3\xc2\xbe\x3d\x04\x30\x43\xf0\x5a\x9a\xeb\xc7\xb1\x19\x7a\x2a\xa9\xc4\x9a\x57\xd5\xdd\xd4\x67\x4c\x17\x85\x78\x50\x88\xd9\xf1\xff\x42\xc7\x97\xa0\x2a\xdc\x9b\x81\x7a\x13\x9a\x50\x97\x0d\xa6\xc9\x95\x24"); let sha2 = HashFactory::new(sha2::SHA512_NAME).unwrap(); assert_eq!(sha2.output_len(), 64); - assert_eq!(sha2.hash(DUMMY_SEED_512), b"\xed\xb9\xbe\xd7\x21\xaa\x6a\x5f\x6f\xbc\x66\x19\xd3\xa3\xc2\xbe\x3d\x04\x30\x43\xf0\x5a\x9a\xeb\xc7\xb1\x19\x7a\x2a\xa9\xc4\x9a\x57\xd5\xdd\xd4\x67\x4c\x17\x85\x78\x50\x88\xd9\xf1\xff\x42\xc7\x97\xa0\x2a\xdc\x9b\x81\x7a\x13\x9a\x50\x97\x0d\xa6\xc9\x95\x24"); + assert_eq!(factory_hash(sha2, DUMMY_SEED_512), b"\xed\xb9\xbe\xd7\x21\xaa\x6a\x5f\x6f\xbc\x66\x19\xd3\xa3\xc2\xbe\x3d\x04\x30\x43\xf0\x5a\x9a\xeb\xc7\xb1\x19\x7a\x2a\xa9\xc4\x9a\x57\xd5\xdd\xd4\x67\x4c\x17\x85\x78\x50\x88\xd9\xf1\xff\x42\xc7\x97\xa0\x2a\xdc\x9b\x81\x7a\x13\x9a\x50\x97\x0d\xa6\xc9\x95\x24"); } #[test] @@ -63,39 +69,39 @@ mod hash_factory_tests { // SHA3-224 let sha3 = HashFactory::new("SHA3-224").unwrap(); assert_eq!(sha3.output_len(), 28); - assert_eq!(sha3.hash(DUMMY_SEED_512), b"\xFE\x51\xC5\xD7\x62\x48\xE1\xE9\xD3\x01\x29\x6A\xE8\xAB\x94\x69\xD2\x86\x34\xB4\xAD\x3E\x9E\x78\xC8\xB0\x9D\x47"); + assert_eq!(factory_hash(sha3, DUMMY_SEED_512), b"\xFE\x51\xC5\xD7\x62\x48\xE1\xE9\xD3\x01\x29\x6A\xE8\xAB\x94\x69\xD2\x86\x34\xB4\xAD\x3E\x9E\x78\xC8\xB0\x9D\x47"); let sha3 = HashFactory::new(sha3::SHA3_224_NAME).unwrap(); assert_eq!(sha3.output_len(), 28); - assert_eq!(sha3.hash(DUMMY_SEED_512), b"\xFE\x51\xC5\xD7\x62\x48\xE1\xE9\xD3\x01\x29\x6A\xE8\xAB\x94\x69\xD2\x86\x34\xB4\xAD\x3E\x9E\x78\xC8\xB0\x9D\x47"); + assert_eq!(factory_hash(sha3, DUMMY_SEED_512), b"\xFE\x51\xC5\xD7\x62\x48\xE1\xE9\xD3\x01\x29\x6A\xE8\xAB\x94\x69\xD2\x86\x34\xB4\xAD\x3E\x9E\x78\xC8\xB0\x9D\x47"); // SHA3-256 let sha3 = HashFactory::new("SHA3-256").unwrap(); assert_eq!(sha3.output_len(), 32); - assert_eq!(sha3.hash(DUMMY_SEED_512), b"\xD4\x72\x8E\xA5\xE9\xF3\x81\x9F\x2B\x47\x60\x15\x1A\x8F\x80\x2D\xBE\x9F\x94\x1F\xD6\xFB\x59\xB3\x71\x58\x92\x43\x65\x55\x77\x2A"); + assert_eq!(factory_hash(sha3, DUMMY_SEED_512), b"\xD4\x72\x8E\xA5\xE9\xF3\x81\x9F\x2B\x47\x60\x15\x1A\x8F\x80\x2D\xBE\x9F\x94\x1F\xD6\xFB\x59\xB3\x71\x58\x92\x43\x65\x55\x77\x2A"); let sha3 = HashFactory::new(sha3::SHA3_256_NAME).unwrap(); assert_eq!(sha3.output_len(), 32); - assert_eq!(sha3.hash(DUMMY_SEED_512), b"\xD4\x72\x8E\xA5\xE9\xF3\x81\x9F\x2B\x47\x60\x15\x1A\x8F\x80\x2D\xBE\x9F\x94\x1F\xD6\xFB\x59\xB3\x71\x58\x92\x43\x65\x55\x77\x2A"); + assert_eq!(factory_hash(sha3, DUMMY_SEED_512), b"\xD4\x72\x8E\xA5\xE9\xF3\x81\x9F\x2B\x47\x60\x15\x1A\x8F\x80\x2D\xBE\x9F\x94\x1F\xD6\xFB\x59\xB3\x71\x58\x92\x43\x65\x55\x77\x2A"); // SHA3-384 let sha3 = HashFactory::new("SHA3-384").unwrap(); assert_eq!(sha3.output_len(), 48); - assert_eq!(sha3.hash(DUMMY_SEED_512), b"\xd5\x3b\x51\x68\x53\xf5\xac\xb4\xaa\xfd\xa5\x9d\x6f\x74\x0f\x69\x99\xc9\xe5\x21\x1c\x51\x03\x9c\x6d\x64\x5b\xf9\x83\xd7\xba\x0b\xdf\x12\x31\xb5\x50\x90\xb5\x5e\x35\x99\xee\x7a\xaa\x62\xd3\xbf"); + assert_eq!(factory_hash(sha3, DUMMY_SEED_512), b"\xd5\x3b\x51\x68\x53\xf5\xac\xb4\xaa\xfd\xa5\x9d\x6f\x74\x0f\x69\x99\xc9\xe5\x21\x1c\x51\x03\x9c\x6d\x64\x5b\xf9\x83\xd7\xba\x0b\xdf\x12\x31\xb5\x50\x90\xb5\x5e\x35\x99\xee\x7a\xaa\x62\xd3\xbf"); let sha3 = HashFactory::new(sha3::SHA3_384_NAME).unwrap(); assert_eq!(sha3.output_len(), 48); - assert_eq!(sha3.hash(DUMMY_SEED_512), b"\xd5\x3b\x51\x68\x53\xf5\xac\xb4\xaa\xfd\xa5\x9d\x6f\x74\x0f\x69\x99\xc9\xe5\x21\x1c\x51\x03\x9c\x6d\x64\x5b\xf9\x83\xd7\xba\x0b\xdf\x12\x31\xb5\x50\x90\xb5\x5e\x35\x99\xee\x7a\xaa\x62\xd3\xbf"); + assert_eq!(factory_hash(sha3, DUMMY_SEED_512), b"\xd5\x3b\x51\x68\x53\xf5\xac\xb4\xaa\xfd\xa5\x9d\x6f\x74\x0f\x69\x99\xc9\xe5\x21\x1c\x51\x03\x9c\x6d\x64\x5b\xf9\x83\xd7\xba\x0b\xdf\x12\x31\xb5\x50\x90\xb5\x5e\x35\x99\xee\x7a\xaa\x62\xd3\xbf"); // SHA3-512 let sha3 = HashFactory::new("SHA3-512").unwrap(); assert_eq!(sha3.output_len(), 64); - assert_eq!(sha3.hash(DUMMY_SEED_512), b"\x58\x4c\xc7\x02\xc2\x22\x9a\x0a\xbc\x78\x9b\xfa\x64\xb4\x27\x1f\xb8\xf0\xbb\x78\x67\x15\x88\xb9\xef\x1d\x09\x3e\xa3\xd4\x72\x58\x4c\x6d\x43\xb5\x68\x33\x59\x47\x2f\x44\x1b\x33\x85\x6f\x68\x28\x59\xf0\xc3\x95\x4b\x56\x80\x8f\xd1\xfb\xa0\xb5\x9c\x9d\x19\x54"); + assert_eq!(factory_hash(sha3, DUMMY_SEED_512), b"\x58\x4c\xc7\x02\xc2\x22\x9a\x0a\xbc\x78\x9b\xfa\x64\xb4\x27\x1f\xb8\xf0\xbb\x78\x67\x15\x88\xb9\xef\x1d\x09\x3e\xa3\xd4\x72\x58\x4c\x6d\x43\xb5\x68\x33\x59\x47\x2f\x44\x1b\x33\x85\x6f\x68\x28\x59\xf0\xc3\x95\x4b\x56\x80\x8f\xd1\xfb\xa0\xb5\x9c\x9d\x19\x54"); let sha3 = HashFactory::new(sha3::SHA3_512_NAME).unwrap(); assert_eq!(sha3.output_len(), 64); - assert_eq!(sha3.hash(DUMMY_SEED_512), b"\x58\x4c\xc7\x02\xc2\x22\x9a\x0a\xbc\x78\x9b\xfa\x64\xb4\x27\x1f\xb8\xf0\xbb\x78\x67\x15\x88\xb9\xef\x1d\x09\x3e\xa3\xd4\x72\x58\x4c\x6d\x43\xb5\x68\x33\x59\x47\x2f\x44\x1b\x33\x85\x6f\x68\x28\x59\xf0\xc3\x95\x4b\x56\x80\x8f\xd1\xfb\xa0\xb5\x9c\x9d\x19\x54"); + assert_eq!(factory_hash(sha3, DUMMY_SEED_512), b"\x58\x4c\xc7\x02\xc2\x22\x9a\x0a\xbc\x78\x9b\xfa\x64\xb4\x27\x1f\xb8\xf0\xbb\x78\x67\x15\x88\xb9\xef\x1d\x09\x3e\xa3\xd4\x72\x58\x4c\x6d\x43\xb5\x68\x33\x59\x47\x2f\x44\x1b\x33\x85\x6f\x68\x28\x59\xf0\xc3\x95\x4b\x56\x80\x8f\xd1\xfb\xa0\xb5\x9c\x9d\x19\x54"); } #[test] @@ -109,41 +115,41 @@ mod hash_factory_tests { fn test_defaults() { // All the ways to get "default" let hash = HashFactory::default(); - let out = hash.hash(DUMMY_SEED_512); + let out = factory_hash(hash, DUMMY_SEED_512); assert_ne!(out, vec![0u8; out.len()]); let hash = HashFactory::new("Default").unwrap(); - let out = hash.hash(DUMMY_SEED_512); + let out = factory_hash(hash, DUMMY_SEED_512); assert_ne!(out, vec![0u8; out.len()]); let hash = HashFactory::new(factory::DEFAULT).unwrap(); - let out = hash.hash(DUMMY_SEED_512); + let out = factory_hash(hash, DUMMY_SEED_512); assert_ne!(out, vec![0u8; out.len()]); // All the ways to get "default_128_bit" let hash = HashFactory::default_128_bit(); - let out = hash.hash(DUMMY_SEED_512); + let out = factory_hash(hash, DUMMY_SEED_512); assert_ne!(out, vec![0u8; out.len()]); let hash = HashFactory::new("Default128Bit").unwrap(); - let out = hash.hash(DUMMY_SEED_512); + let out = factory_hash(hash, DUMMY_SEED_512); assert_ne!(out, vec![0u8; out.len()]); let hash = HashFactory::new(factory::DEFAULT_128_BIT).unwrap(); - let out = hash.hash(DUMMY_SEED_512); + let out = factory_hash(hash, DUMMY_SEED_512); assert_ne!(out, vec![0u8; out.len()]); // All the ways to get "default_256_bit" let hash = HashFactory::default_256_bit(); - let out = hash.hash(DUMMY_SEED_512); + let out = factory_hash(hash, DUMMY_SEED_512); assert_ne!(out, vec![0u8; out.len()]); let hash = HashFactory::new("Default256Bit").unwrap(); - let out = hash.hash(DUMMY_SEED_512); + let out = factory_hash(hash, DUMMY_SEED_512); assert_ne!(out, vec![0u8; out.len()]); let hash = HashFactory::new(factory::DEFAULT_256_BIT).unwrap(); - let out = hash.hash(DUMMY_SEED_512); + let out = factory_hash(hash, DUMMY_SEED_512); assert_ne!(out, vec![0u8; out.len()]); } } diff --git a/crypto/hmac/tests/hmac_tests.rs b/crypto/hmac/tests/hmac_tests.rs index 87dd118..cd1c4e0 100644 --- a/crypto/hmac/tests/hmac_tests.rs +++ b/crypto/hmac/tests/hmac_tests.rs @@ -1,7 +1,7 @@ #[cfg(test)] mod hmac_tests { use bouncycastle_core::key_material::{KeyMaterial256, KeyMaterial512, KeyMaterial, KeyType, KeyMaterialTrait}; - use bouncycastle_core::traits::{Algorithm, Hash, SecurityStrength, MAC}; + use bouncycastle_core::traits::{Algorithm, Hash, MACFixedOutput, SecurityStrength, MAC}; use bouncycastle_core_test_framework::mac::TestFrameworkMAC; use bouncycastle_hex as hex; use bouncycastle_core::errors::{KeyMaterialError, MACError}; @@ -22,7 +22,7 @@ mod hmac_tests { let mut mac = HMAC::::new_allow_weak_key(&zero_length_key).unwrap(); mac.do_update("Hi There".as_bytes()); let output = mac.do_final(); - assert_eq!(output, b"\xe4\x84\x11\x26\x27\x15\xc8\x37\x0c\xd5\xe7\xbf\x8e\x82\xbe\xf5\x3b\xd5\x37\x12\xd0\x07\xf3\x42\x93\x51\x84\x3b\x77\xc7\xbb\x9b"); + assert_eq!(output, *b"\xe4\x84\x11\x26\x27\x15\xc8\x37\x0c\xd5\xe7\xbf\x8e\x82\xbe\xf5\x3b\xd5\x37\x12\xd0\x07\xf3\x42\x93\x51\x84\x3b\x77\xc7\xbb\x9b"); // RFC4231 Test Case 1 for SHA224 let key = KeyMaterial256::from_bytes_as_type( @@ -32,7 +32,7 @@ mod hmac_tests { let mut mac = HMAC::::new(&key).unwrap(); mac.do_update(b"Hi There"); let output = mac.do_final(); - assert_eq!(output, b"\x89\x6f\xb1\x12\x8a\xbb\xdf\x19\x68\x32\x10\x7c\xd4\x9d\xf3\x3f\x47\xb4\xb1\x16\x99\x12\xba\x4f\x53\x68\x4b\x22"); + assert_eq!(output, *b"\x89\x6f\xb1\x12\x8a\xbb\xdf\x19\x68\x32\x10\x7c\xd4\x9d\xf3\x3f\x47\xb4\xb1\x16\x99\x12\xba\x4f\x53\x68\x4b\x22"); // success case: do_final without do_update (ie empty content) let key = KeyMaterial256::from_bytes_as_type( @@ -42,7 +42,7 @@ mod hmac_tests { let mac = HMAC::::new(&key).unwrap(); // mac.do_update(b"").unwrap(); let output = mac.do_final(); - assert_eq!(&output, &hex::decode("999a901219f032cd497cadb5e6051e97b6a29ab297bd6ae722bd6062a2f59542").unwrap()); + assert_eq!(&output[..], &hex::decode("999a901219f032cd497cadb5e6051e97b6a29ab297bd6ae722bd6062a2f59542").unwrap()[..]); } #[test] @@ -196,7 +196,7 @@ mod hmac_tests { // fail case: mac value is correct but truncated let mac = HMAC_SHA3_224::new(&key).unwrap(); - let mut mac_val = mac.mac(b"Polly want a cracker?"); + let mac_val = mac.mac(b"Polly want a cracker?"); let verifier = HMAC_SHA3_224::new(&key).unwrap(); assert!(verifier.verify(b"Polly want a cracker?", &mac_val)); @@ -206,8 +206,9 @@ mod hmac_tests { // .. as is some extra bytes at the end let verifier = HMAC_SHA3_224::new(&key).unwrap(); - mac_val.extend_from_slice(&[0u8; 4]); - assert!(! verifier.verify(b"Polly want a cracker?", &mac_val) ); + let mut extended_mac_val = mac_val.to_vec(); + extended_mac_val.extend_from_slice(&[0u8; 4]); + assert!(! verifier.verify(b"Polly want a cracker?", &extended_mac_val) ); } #[test] @@ -237,7 +238,7 @@ mod hmac_tests { assert_eq!(zero_length_key.key_len(), 0); assert_eq!(zero_length_key.key_type(), KeyType::MACKey); - test_framework.test_mac::>( + test_framework.test_mac::, 28>( &zero_length_key, b"Hello, world", &hex::decode("57454372e6a8780b11150274d7056c6fbcffef902f9c23f24fbbfee9").unwrap(), @@ -245,7 +246,7 @@ mod hmac_tests { // RFC4231 Test Case 1 let test_framework = TestFrameworkMAC::new(); - test_framework.test_mac::>( + test_framework.test_mac::, 28>( &KeyMaterial256::from_bytes_as_type( &hex::decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b").unwrap(), KeyType::MACKey, @@ -256,7 +257,7 @@ mod hmac_tests { ); // RFC4231 Test Case 2 -- Test with a key shorter than the length of the HMAC output. - test_framework.test_mac::>( + test_framework.test_mac::, 28>( &KeyMaterial256::from_bytes_as_type(b"Jefe", KeyType::MACKey).unwrap(), b"what do ya want for nothing?", &hex::decode("a30e01098bc6dbbf45690f3a7e9e6d0f8bbea2a39e6148008fd05e44").unwrap(), @@ -264,14 +265,14 @@ mod hmac_tests { // RFC4231 Test Case 3 -- Test with a combined length of key and data that is larger than 64 // bytes (= block-size of SHA-224 and SHA-256). - test_framework.test_mac::>(&KeyMaterial256::from_bytes_as_type(&hex::decode("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").unwrap(), KeyType::MACKey).unwrap(), + test_framework.test_mac::, 28>(&KeyMaterial256::from_bytes_as_type(&hex::decode("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").unwrap(), KeyType::MACKey).unwrap(), &hex::decode("dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd").unwrap(), &hex::decode("7fb3cb3588c6c1f6ffa9694d7d6ad2649365b0c1f65d69d1ec8333ea").unwrap() ); // RFC4231 Test Case 4 -- Test with a combined length of key and data that is larger than 64 // bytes (= block-size of SHA-224 and SHA-256). - test_framework.test_mac::>(&KeyMaterial256::from_bytes_as_type(&hex::decode("0102030405060708090a0b0c0d0e0f10111213141516171819").unwrap(), KeyType::MACKey).unwrap(), + test_framework.test_mac::, 28>(&KeyMaterial256::from_bytes_as_type(&hex::decode("0102030405060708090a0b0c0d0e0f10111213141516171819").unwrap(), KeyType::MACKey).unwrap(), &hex::decode("cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd").unwrap(), &hex::decode("6c11506874013cac6a2abc1bb382627cec6a90d86efc012de7afec5a").unwrap() ); @@ -289,14 +290,14 @@ mod hmac_tests { // RFC4231 Test Case 6 -- Test with a combined length of key and data that is larger than 64 // bytes (= block-size of SHA-224 and SHA-256). let key = KeyMaterial::<131>::from_bytes_as_type(&hex::decode("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").unwrap(), KeyType::MACKey).unwrap(); - test_framework.test_mac::>(&key, + test_framework.test_mac::, 28>(&key, b"Test Using Larger Than Block-Size Key - Hash Key First", &hex::decode("95e9a0db962095adaebe9b2d6f0dbce2d499f112f2d2b7273fa6870e").unwrap() ); // RFC4231 Test Case 7 -- Test with a key and data that is larger than 128 bytes (= block-size // of SHA-384 and SHA-512) - test_framework.test_mac::>(&KeyMaterial::<131>::from_bytes_as_type(&hex::decode("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").unwrap(), KeyType::MACKey).unwrap(), + test_framework.test_mac::, 28>(&KeyMaterial::<131>::from_bytes_as_type(&hex::decode("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").unwrap(), KeyType::MACKey).unwrap(), b"This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.", &hex::decode("3a854166ac5d9f023f54d517d0b39dbd946770db9c2b95c9f6f565d1").unwrap() ); @@ -312,7 +313,7 @@ mod hmac_tests { assert_eq!(zero_length_key.key_len(), 0); assert_eq!(zero_length_key.key_type(), KeyType::MACKey); - test_framework.test_mac::>( + test_framework.test_mac::, 32>( &zero_length_key, b"Hello, world", &hex::decode("c0fa4c55880318c31c1020e7a2cf830c2c695716387795c7a0eb918ba84e4bf0").unwrap(), @@ -320,7 +321,7 @@ mod hmac_tests { // RFC4231 Test Case 1 let test_framework = TestFrameworkMAC::new(); - test_framework.test_mac::>( + test_framework.test_mac::, 32>( &KeyMaterial256::from_bytes_as_type( &hex::decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b").unwrap(), KeyType::MACKey, @@ -331,7 +332,7 @@ mod hmac_tests { ); // RFC4231 Test Case 2 -- Test with a key shorter than the length of the HMAC output. - test_framework.test_mac::>( + test_framework.test_mac::, 32>( &KeyMaterial256::from_bytes_as_type(b"Jefe", KeyType::MACKey).unwrap(), b"what do ya want for nothing?", &hex::decode("5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843").unwrap(), @@ -339,14 +340,14 @@ mod hmac_tests { // RFC4231 Test Case 3 -- Test with a combined length of key and data that is larger than 64 // bytes (= block-size of SHA-224 and SHA-256). - test_framework.test_mac::>(&KeyMaterial256::from_bytes_as_type(&hex::decode("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").unwrap(), KeyType::MACKey).unwrap(), + test_framework.test_mac::, 32>(&KeyMaterial256::from_bytes_as_type(&hex::decode("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").unwrap(), KeyType::MACKey).unwrap(), &hex::decode("dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd").unwrap(), &hex::decode("773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe").unwrap() ); // RFC4231 Test Case 4 -- Test with a combined length of key and data that is larger than 64 // bytes (= block-size of SHA-224 and SHA-256). - test_framework.test_mac::>(&KeyMaterial256::from_bytes_as_type(&hex::decode("0102030405060708090a0b0c0d0e0f10111213141516171819").unwrap(), KeyType::MACKey).unwrap(), + test_framework.test_mac::, 32>(&KeyMaterial256::from_bytes_as_type(&hex::decode("0102030405060708090a0b0c0d0e0f10111213141516171819").unwrap(), KeyType::MACKey).unwrap(), &hex::decode("cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd").unwrap(), &hex::decode("82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b").unwrap() ); @@ -363,14 +364,14 @@ mod hmac_tests { // RFC4231 Test Case 6 -- Test with a combined length of key and data that is larger than 64 // bytes (= block-size of SHA-224 and SHA-256). - test_framework.test_mac::>(&KeyMaterial::<131>::from_bytes_as_type(&hex::decode("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").unwrap(), KeyType::MACKey).unwrap(), + test_framework.test_mac::, 32>(&KeyMaterial::<131>::from_bytes_as_type(&hex::decode("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").unwrap(), KeyType::MACKey).unwrap(), b"Test Using Larger Than Block-Size Key - Hash Key First", &hex::decode("60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54").unwrap() ); // RFC4231 Test Case 7 -- Test with a key and data that is larger than 128 bytes (= block-size // of SHA-384 and SHA-512) - test_framework.test_mac::>(&KeyMaterial::<131>::from_bytes_as_type(&hex::decode("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").unwrap(), KeyType::MACKey).unwrap(), + test_framework.test_mac::, 32>(&KeyMaterial::<131>::from_bytes_as_type(&hex::decode("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").unwrap(), KeyType::MACKey).unwrap(), b"This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.", &hex::decode("9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2").unwrap() ); @@ -386,7 +387,7 @@ mod hmac_tests { assert_eq!(zero_length_key.key_len(), 0); assert_eq!(zero_length_key.key_type(), KeyType::MACKey); - test_framework.test_mac::>( + test_framework.test_mac::, 48>( &zero_length_key, b"Hello, world", &hex::decode("fbd41442f749049355175277afbaff610539e5bfa874c9cf86ef867a43a30b09a5eac6578d5c0cb1ceddc95f97598af7").unwrap(), @@ -394,7 +395,7 @@ mod hmac_tests { // RFC4231 Test Case 1 let test_framework = TestFrameworkMAC::new(); - test_framework.test_mac::>( + test_framework.test_mac::, 48>( &KeyMaterial256::from_bytes_as_type( &hex::decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b").unwrap(), KeyType::MACKey, @@ -404,7 +405,7 @@ mod hmac_tests { ); // RFC4231 Test Case 2 -- Test with a key shorter than the length of the HMAC output. - test_framework.test_mac::>( + test_framework.test_mac::, 48>( &KeyMaterial256::from_bytes_as_type(b"Jefe", KeyType::MACKey).unwrap(), b"what do ya want for nothing?", &hex::decode("af45d2e376484031617f78d2b58a6b1b9c7ef464f5a01b47e42ec3736322445e8e2240ca5e69e2c78b3239ecfab21649").unwrap(), @@ -412,14 +413,14 @@ mod hmac_tests { // RFC4231 Test Case 3 -- Test with a combined length of key and data that is larger than 64 // bytes (= block-size of SHA-224 and SHA-256). - test_framework.test_mac::>(&KeyMaterial256::from_bytes_as_type(&hex::decode("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").unwrap(), KeyType::MACKey).unwrap(), + test_framework.test_mac::, 48>(&KeyMaterial256::from_bytes_as_type(&hex::decode("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").unwrap(), KeyType::MACKey).unwrap(), &hex::decode("dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd").unwrap(), &hex::decode("88062608d3e6ad8a0aa2ace014c8a86f0aa635d947ac9febe83ef4e55966144b2a5ab39dc13814b94e3ab6e101a34f27").unwrap() ); // RFC4231 Test Case 4 -- Test with a combined length of key and data that is larger than 64 // bytes (= block-size of SHA-224 and SHA-256). - test_framework.test_mac::>(&KeyMaterial256::from_bytes_as_type(&hex::decode("0102030405060708090a0b0c0d0e0f10111213141516171819").unwrap(), KeyType::MACKey).unwrap(), + test_framework.test_mac::, 48>(&KeyMaterial256::from_bytes_as_type(&hex::decode("0102030405060708090a0b0c0d0e0f10111213141516171819").unwrap(), KeyType::MACKey).unwrap(), &hex::decode("cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd").unwrap(), &hex::decode("3e8a69b7783c25851933ab6290af6ca77a9981480850009cc5577c6e1f573b4e6801dd23c4a7d679ccf8a386c674cffb").unwrap() ); @@ -438,14 +439,14 @@ mod hmac_tests { // RFC4231 Test Case 6 -- Test with a combined length of key and data that is larger than 64 // bytes (= block-size of SHA-224 and SHA-256). - test_framework.test_mac::>(&KeyMaterial::<131>::from_bytes_as_type(&hex::decode("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").unwrap(), KeyType::MACKey).unwrap(), + test_framework.test_mac::, 48>(&KeyMaterial::<131>::from_bytes_as_type(&hex::decode("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").unwrap(), KeyType::MACKey).unwrap(), b"Test Using Larger Than Block-Size Key - Hash Key First", &hex::decode("4ece084485813e9088d2c63a041bc5b44f9ef1012a2b588f3cd11f05033ac4c60c2ef6ab4030fe8296248df163f44952").unwrap() ); // RFC4231 Test Case 7 -- Test with a key and data that is larger than 128 bytes (= block-size // of SHA-384 and SHA-512) - test_framework.test_mac::>(&KeyMaterial::<131>::from_bytes_as_type(&hex::decode("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").unwrap(), KeyType::MACKey).unwrap(), + test_framework.test_mac::, 48>(&KeyMaterial::<131>::from_bytes_as_type(&hex::decode("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").unwrap(), KeyType::MACKey).unwrap(), b"This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.", &hex::decode("6617178e941f020d351e2f254e8fd32c602420feb0b8fb9adccebb82461e99c5a678cc31e799176d3860e6110c46523e").unwrap() ); @@ -461,7 +462,7 @@ mod hmac_tests { assert_eq!(zero_length_key.key_len(), 0); assert_eq!(zero_length_key.key_type(), KeyType::MACKey); - test_framework.test_mac::>( + test_framework.test_mac::, 64>( &zero_length_key, b"Hello, world", &hex::decode("e8f7176e01bf9bb883f71f42c143681e86cfafe0b61f3bc0d824e2cde13b5f80199e82d865aebb725461c86a54086aeacac37a86a9f1cf07db567ba5a10f1cc1").unwrap(), @@ -469,7 +470,7 @@ mod hmac_tests { // RFC4231 Test Case 1 let test_framework = TestFrameworkMAC::new(); - test_framework.test_mac::>( + test_framework.test_mac::, 64>( &KeyMaterial256::from_bytes_as_type( &hex::decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b").unwrap(), KeyType::MACKey, @@ -480,7 +481,7 @@ mod hmac_tests { ); // RFC4231 Test Case 2 -- Test with a key shorter than the length of the HMAC output. - test_framework.test_mac::>( + test_framework.test_mac::, 64>( &KeyMaterial256::from_bytes_as_type(b"Jefe", KeyType::MACKey).unwrap(), b"what do ya want for nothing?", &hex::decode("164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737").unwrap(), @@ -488,14 +489,14 @@ mod hmac_tests { // RFC4231 Test Case 3 -- Test with a combined length of key and data that is larger than 64 // bytes (= block-size of SHA-224 and SHA-256). - test_framework.test_mac::>(&KeyMaterial256::from_bytes_as_type(&hex::decode("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").unwrap(), KeyType::MACKey).unwrap(), + test_framework.test_mac::, 64>(&KeyMaterial256::from_bytes_as_type(&hex::decode("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").unwrap(), KeyType::MACKey).unwrap(), &hex::decode("dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd").unwrap(), &hex::decode("fa73b0089d56a284efb0f0756c890be9b1b5dbdd8ee81a3655f83e33b2279d39bf3e848279a722c806b485a47e67c807b946a337bee8942674278859e13292fb").unwrap() ); // RFC4231 Test Case 4 -- Test with a combined length of key and data that is larger than 64 // bytes (= block-size of SHA-224 and SHA-256). - test_framework.test_mac::>(&KeyMaterial256::from_bytes_as_type(&hex::decode("0102030405060708090a0b0c0d0e0f10111213141516171819").unwrap(), KeyType::MACKey).unwrap(), + test_framework.test_mac::, 64>(&KeyMaterial256::from_bytes_as_type(&hex::decode("0102030405060708090a0b0c0d0e0f10111213141516171819").unwrap(), KeyType::MACKey).unwrap(), &hex::decode("cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd").unwrap(), &hex::decode("b0ba465637458c6990e5a8c5f61d4af7e576d97ff94b872de76f8050361ee3dba91ca5c11aa25eb4d679275cc5788063a5f19741120c4f2de2adebeb10a298dd").unwrap() ); @@ -514,14 +515,14 @@ mod hmac_tests { // RFC4231 Test Case 6 -- Test with a combined length of key and data that is larger than 64 // bytes (= block-size of SHA-224 and SHA-256). - test_framework.test_mac::>(&KeyMaterial::<131>::from_bytes_as_type(&hex::decode("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").unwrap(), KeyType::MACKey).unwrap(), + test_framework.test_mac::, 64>(&KeyMaterial::<131>::from_bytes_as_type(&hex::decode("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").unwrap(), KeyType::MACKey).unwrap(), b"Test Using Larger Than Block-Size Key - Hash Key First", &hex::decode("80b24263c7c1a3ebb71493c1dd7be8b49b46d1f41b4aeec1121b013783f8f3526b56d037e05f2598bd0fd2215d6a1e5295e64f73f63f0aec8b915a985d786598").unwrap() ); // RFC4231 Test Case 7 -- Test with a key and data that is larger than 128 bytes (= block-size // of SHA-384 and SHA-512) - test_framework.test_mac::>(&KeyMaterial::<131>::from_bytes_as_type(&hex::decode("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").unwrap(), KeyType::MACKey).unwrap(), + test_framework.test_mac::, 64>(&KeyMaterial::<131>::from_bytes_as_type(&hex::decode("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").unwrap(), KeyType::MACKey).unwrap(), b"This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.", &hex::decode("e37b6a775dc87dbaa4dfa9f96e5e3ffddebd71f8867289865df5a32d20cdc944b6022cac3c4982b10d5eeb55c3e4de15134676fb6de0446065c97440fa8c6a58").unwrap() ); diff --git a/crypto/mldsa/tests/bc_test_data.rs b/crypto/mldsa/tests/bc_test_data.rs index 77ae858..ed947ae 100644 --- a/crypto/mldsa/tests/bc_test_data.rs +++ b/crypto/mldsa/tests/bc_test_data.rs @@ -14,7 +14,7 @@ mod bc_test_data { use bouncycastle_core::errors::SignatureError; use bouncycastle_core::key_material::{KeyMaterial256, KeyMaterialTrait, KeyType}; use bouncycastle_core::traits::{ - Hash, SecurityStrength, Signature, SignaturePrivateKey, SignaturePublicKey, + HashFixedOutput, SecurityStrength, Signature, SignaturePrivateKey, SignaturePublicKey, }; use bouncycastle_hex as hex; use bouncycastle_mldsa::{ @@ -722,10 +722,7 @@ mod bc_test_data { if IS_HASH_MLDSA { // we're only testing SHA512 let ph: [u8; 64] = SHA512::new() - .hash(&hex::decode(&self.msg).unwrap()) - .as_slice() - .try_into() - .unwrap(); + .hash(&hex::decode(&self.msg).unwrap()); assert_eq!(ph, &*hex::decode(&self.message_hash).unwrap()); let sig = HashMLDSA44_with_SHA512::sign_ph_deterministic( @@ -800,10 +797,7 @@ mod bc_test_data { if IS_HASH_MLDSA { // we're only testing SHA512 let ph: [u8; 64] = SHA512::new() - .hash(&hex::decode(&self.msg).unwrap()) - .as_slice() - .try_into() - .unwrap(); + .hash(&hex::decode(&self.msg).unwrap()); assert_eq!(ph, &*hex::decode(&self.message_hash).unwrap()); let sig = HashMLDSA65_with_SHA512::sign_ph_deterministic( @@ -872,10 +866,7 @@ mod bc_test_data { if IS_HASH_MLDSA { // we're only testing SHA512 let ph: [u8; 64] = SHA512::new() - .hash(&hex::decode(&self.msg).unwrap()) - .as_slice() - .try_into() - .unwrap(); + .hash(&hex::decode(&self.msg).unwrap()); assert_eq!(ph, &*hex::decode(&self.message_hash).unwrap()); let sig = HashMLDSA87_with_SHA512::sign_ph_deterministic( diff --git a/crypto/mldsa/tests/hash_mldsa_tests.rs b/crypto/mldsa/tests/hash_mldsa_tests.rs index 4301d7b..d8eba3f 100644 --- a/crypto/mldsa/tests/hash_mldsa_tests.rs +++ b/crypto/mldsa/tests/hash_mldsa_tests.rs @@ -2,7 +2,7 @@ mod hash_mldsa_tests { use bouncycastle_core::errors::SignatureError; use bouncycastle_core::key_material::{KeyMaterial256, KeyType}; - use bouncycastle_core::traits::{Hash, PHSignature, Signature}; + use bouncycastle_core::traits::{HashFixedOutput, PHSignature, Signature}; use bouncycastle_core_test_framework::signature::TestFrameworkSignature; use bouncycastle_hex as hex; use bouncycastle_mldsa::{ @@ -134,14 +134,14 @@ mod hash_mldsa_tests { let msg = b"The quick brown fox jumped over the lazy dog"; let (pk, sk) = HashMLDSA44_with_SHA256::keygen().unwrap(); - let ph: [u8; 32] = SHA256::default().hash(msg)[..32].try_into().unwrap(); + let ph: [u8; 32] = SHA256::default().hash(msg); let sig_val = HashMLDSA44_with_SHA256::sign_ph(&sk, &ph, None).unwrap(); HashMLDSA44_with_SHA256::verify_ph(&pk, &ph, None, &sig_val).unwrap(); HashMLDSA44_with_SHA256::verify(&pk, msg, None, &sig_val).unwrap(); // sign_ph_out let (pk, sk) = HashMLDSA44_with_SHA256::keygen().unwrap(); - let ph: [u8; 32] = SHA256::default().hash(msg)[..32].try_into().unwrap(); + let ph: [u8; 32] = SHA256::default().hash(msg); let mut sig_val = [0u8; MLDSA44_SIG_LEN]; let bytes_written = HashMLDSA44_with_SHA256::sign_ph_out(&sk, &ph, None, &mut sig_val).unwrap(); @@ -175,7 +175,7 @@ mod hash_mldsa_tests { // since I'm not exposing a sign_deterministic() that does the ph computation internally and takes an rnd, // we have to compute the ph manually here - let ph: [u8; 64] = SHA512::new().hash(msg)[..64].try_into().unwrap(); + let ph: [u8; 64] = SHA512::new().hash(msg); let sig = HashMLDSA44_with_SHA512::sign_ph_deterministic(&sk, None, None, &ph, rnd).unwrap(); assert_eq!(&sig, expected_sig.as_slice()); @@ -187,7 +187,7 @@ mod hash_mldsa_tests { // since I'm not exposing a sign_deterministic() that does the ph computation internally and takes an rnd, // we have to compute the ph manually here - let ph: [u8; 64] = SHA512::new().hash(msg)[..64].try_into().unwrap(); + let ph: [u8; 64] = SHA512::new().hash(msg); let sig = HashMLDSA65_with_SHA512::sign_ph_deterministic(&sk, None, None, &ph, rnd).unwrap(); assert_eq!(&sig, expected_sig.as_slice()); @@ -199,7 +199,7 @@ mod hash_mldsa_tests { // since I'm not exposing a sign_deterministic() that does the ph computation internally and takes an rnd, // we have to compute the ph manually here - let ph: [u8; 64] = SHA512::new().hash(msg)[..64].try_into().unwrap(); + let ph: [u8; 64] = SHA512::new().hash(msg); let sig = HashMLDSA87_with_SHA512::sign_ph_deterministic(&sk, None, None, &ph, rnd).unwrap(); @@ -213,7 +213,7 @@ mod hash_mldsa_tests { // since I'm not exposing a sign_deterministic() that does the ph computation internally and takes an rnd, // we have to compute the ph manually here - let ph: [u8; 64] = SHA512::new().hash(msg)[..64].try_into().unwrap(); + let ph: [u8; 64] = SHA512::new().hash(msg); let sig = HashMLDSA44_with_SHA512::sign_ph_deterministic(&sk, None, Some(ctx), &ph, rnd).unwrap(); @@ -241,7 +241,7 @@ mod hash_mldsa_tests { // BEGIN expected values let (expected_pk, expected_sk) = HashMLDSA44_with_SHA512::keygen_from_seed(&seed).unwrap(); - let expected_ph: [u8; 64] = SHA512::new().hash(msg).try_into().unwrap(); + let expected_ph: [u8; 64] = SHA512::new().hash(msg); let mut expected_sig = [0u8; MLDSA44_SIG_LEN]; let bytes_written = HashMLDSA44_with_SHA512::sign_ph_deterministic_out( &expected_sk, None, ctx, &expected_ph, rnd, &mut expected_sig, @@ -301,13 +301,13 @@ mod hash_mldsa_tests { // since I'm not exposing a sign_deterministic() that does the ph computation internally and takes an rnd, // we have to compute the ph manually here - let ph: [u8; 64] = SHA512::new().hash(msg)[..64].try_into().unwrap(); + let ph: [u8; 64] = SHA512::new().hash(msg); let sig = HashMLDSA44_with_SHA512::sign_ph_with_expanded_key(&sk_expanded, &ph, None).unwrap(); HashMLDSA44_with_SHA512::verify_with_expanded_key(&pk_expanded, msg, None, &sig).unwrap(); // and sign_ph_with_expanded_key_out - let ph: [u8; 64] = SHA512::new().hash(msg)[..64].try_into().unwrap(); + let ph: [u8; 64] = SHA512::new().hash(msg); let mut sig = [0u8; MLDSA44_SIG_LEN]; let bytes_written = HashMLDSA44_with_SHA512::sign_ph_with_expanded_key_out( &sk_expanded, &ph, None, &mut sig, @@ -328,7 +328,7 @@ mod hash_mldsa_tests { // since I'm not exposing a sign_deterministic() that does the ph computation internally and takes an rnd, // we have to compute the ph manually here - let ph: [u8; 64] = SHA512::new().hash(msg)[..64].try_into().unwrap(); + let ph: [u8; 64] = SHA512::new().hash(msg); let sig = HashMLDSA65_with_SHA512::sign_ph_with_expanded_key(&sk_expanded, &ph, None).unwrap(); HashMLDSA65_with_SHA512::verify_with_expanded_key(&pk_expanded, msg, None, &sig).unwrap(); @@ -345,7 +345,7 @@ mod hash_mldsa_tests { // since I'm not exposing a sign_deterministic() that does the ph computation internally and takes an rnd, // we have to compute the ph manually here - let ph: [u8; 64] = SHA512::new().hash(msg)[..64].try_into().unwrap(); + let ph: [u8; 64] = SHA512::new().hash(msg); let sig = HashMLDSA87_with_SHA512::sign_ph_with_expanded_key(&sk_expanded, &ph, None).unwrap(); HashMLDSA87_with_SHA512::verify_with_expanded_key(&pk_expanded, msg, None, &sig).unwrap(); diff --git a/crypto/mldsa_lowmemory/tests/bc_test_data.rs b/crypto/mldsa_lowmemory/tests/bc_test_data.rs index 706c82a..52fde56 100644 --- a/crypto/mldsa_lowmemory/tests/bc_test_data.rs +++ b/crypto/mldsa_lowmemory/tests/bc_test_data.rs @@ -18,7 +18,7 @@ mod bc_test_data { use bouncycastle_core::errors::SignatureError; use bouncycastle_core::key_material::{KeyMaterial256, KeyMaterialTrait, KeyType}; use bouncycastle_core::traits::{ - Hash, SecurityStrength, Signature, SignaturePrivateKey, SignaturePublicKey, + HashFixedOutput, SecurityStrength, Signature, SignaturePrivateKey, SignaturePublicKey, }; use bouncycastle_hex as hex; use bouncycastle_mldsa_lowmemory::{ @@ -716,10 +716,7 @@ mod bc_test_data { if IS_HASH_MLDSA { // we're only testing SHA512 let ph: [u8; 64] = SHA512::new() - .hash(&hex::decode(&self.msg).unwrap()) - .as_slice() - .try_into() - .unwrap(); + .hash(&hex::decode(&self.msg).unwrap()); assert_eq!(ph, &*hex::decode(&self.message_hash).unwrap()); let sig = HashMLDSA44_with_SHA512::sign_ph_deterministic( @@ -792,10 +789,7 @@ mod bc_test_data { if IS_HASH_MLDSA { // we're only testing SHA512 let ph: [u8; 64] = SHA512::new() - .hash(&hex::decode(&self.msg).unwrap()) - .as_slice() - .try_into() - .unwrap(); + .hash(&hex::decode(&self.msg).unwrap()); assert_eq!(ph, &*hex::decode(&self.message_hash).unwrap()); let sig = HashMLDSA65_with_SHA512::sign_ph_deterministic( @@ -862,10 +856,7 @@ mod bc_test_data { if IS_HASH_MLDSA { // we're only testing SHA512 let ph: [u8; 64] = SHA512::new() - .hash(&hex::decode(&self.msg).unwrap()) - .as_slice() - .try_into() - .unwrap(); + .hash(&hex::decode(&self.msg).unwrap()); assert_eq!(ph, &*hex::decode(&self.message_hash).unwrap()); let sig = HashMLDSA87_with_SHA512::sign_ph_deterministic( diff --git a/crypto/mldsa_lowmemory/tests/hash_mldsa_tests.rs b/crypto/mldsa_lowmemory/tests/hash_mldsa_tests.rs index 1380296..373a897 100644 --- a/crypto/mldsa_lowmemory/tests/hash_mldsa_tests.rs +++ b/crypto/mldsa_lowmemory/tests/hash_mldsa_tests.rs @@ -6,7 +6,7 @@ mod hash_mldsa_tests { use super::*; use bouncycastle_core::errors::SignatureError; use bouncycastle_core::key_material::{KeyMaterial256, KeyType}; - use bouncycastle_core::traits::{Hash, PHSignature}; + use bouncycastle_core::traits::{HashFixedOutput, PHSignature}; use bouncycastle_core_test_framework::signature::TestFrameworkSignature; use bouncycastle_mldsa_lowmemory::{ HashMLDSA44_with_SHA256, HashMLDSA44_with_SHA512, HashMLDSA65_with_SHA256, @@ -64,7 +64,7 @@ mod hash_mldsa_tests { // since I'm not exposing a sign_deterministic() that does the ph computation internally and takes an rnd, // we have to compute the ph manually here - let ph: [u8; 64] = SHA512::new().hash(msg)[..64].try_into().unwrap(); + let ph: [u8; 64] = SHA512::new().hash(msg); let sig = HashMLDSA44_with_SHA512::sign_ph_deterministic(&sk, None, &ph, rnd).unwrap(); assert_eq!(&sig, expected_sig.as_slice()); @@ -75,7 +75,7 @@ mod hash_mldsa_tests { // since I'm not exposing a sign_deterministic() that does the ph computation internally and takes an rnd, // we have to compute the ph manually here - let ph: [u8; 64] = SHA512::new().hash(msg)[..64].try_into().unwrap(); + let ph: [u8; 64] = SHA512::new().hash(msg); let sig = HashMLDSA65_with_SHA512::sign_ph_deterministic(&sk, None, &ph, rnd).unwrap(); assert_eq!(&sig, expected_sig.as_slice()); @@ -86,7 +86,7 @@ mod hash_mldsa_tests { // since I'm not exposing a sign_deterministic() that does the ph computation internally and takes an rnd, // we have to compute the ph manually here - let ph: [u8; 64] = SHA512::new().hash(msg)[..64].try_into().unwrap(); + let ph: [u8; 64] = SHA512::new().hash(msg); let sig = HashMLDSA87_with_SHA512::sign_ph_deterministic(&sk, None, &ph, rnd).unwrap(); assert_eq!(&sig, expected_sig.as_slice()); } @@ -112,7 +112,7 @@ mod hash_mldsa_tests { // BEGIN expected values let (expected_pk, expected_sk) = HashMLDSA44_with_SHA512::keygen_from_seed(&seed).unwrap(); - let expected_ph: [u8; 64] = SHA512::new().hash(msg).try_into().unwrap(); + let expected_ph: [u8; 64] = SHA512::new().hash(msg); let mut expected_sig = [0u8; MLDSA44_SIG_LEN]; let bytes_written = HashMLDSA44_with_SHA512::sign_ph_deterministic_out( &expected_sk, ctx, &expected_ph, rnd, &mut expected_sig, diff --git a/crypto/sha2/tests/sha2_tests.rs b/crypto/sha2/tests/sha2_tests.rs index 7d3e239..3a010ca 100644 --- a/crypto/sha2/tests/sha2_tests.rs +++ b/crypto/sha2/tests/sha2_tests.rs @@ -14,45 +14,45 @@ mod sha2_tests { fn sha224() { let mut test_framework = TestFrameworkHash::new(); test_framework.enable_partial_final_input_tests = false; - test_framework.test_hash::(b"", b"\xd1\x4a\x02\x8c\x2a\x3a\x2b\xc9\x47\x61\x02\xbb\x28\x82\x34\xc4\x15\xa2\xb0\x1f\x82\x8e\xa6\x2a\xc5\xb3\xe4\x2f"); - test_framework.test_hash::(b"a", b"\xab\xd3\x75\x34\xc7\xd9\xa2\xef\xb9\x46\x5d\xe9\x31\xcd\x70\x55\xff\xdb\x88\x79\x56\x3a\xe9\x80\x78\xd6\xd6\xd5"); - test_framework.test_hash::(b"abc", b"\x23\x09\x7d\x22\x34\x05\xd8\x22\x86\x42\xa4\x77\xbd\xa2\x55\xb3\x2a\xad\xbc\xe4\xbd\xa0\xb3\xf7\xe3\x6c\x9d\xa7"); - test_framework.test_hash::(b"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", b"\x75\x38\x8b\x16\x51\x27\x76\xcc\x5d\xba\x5d\xa1\xfd\x89\x01\x50\xb0\xc6\x45\x5c\xb4\xf5\x8b\x19\x52\x52\x25\x25"); - test_framework.test_hash::(DUMMY_SEED_512, b"\xb8\x06\x0c\xcc\x82\xd4\x0c\x57\x61\x56\xf7\xca\x03\x33\xe4\x38\x9e\x41\x0d\xf0\x27\xd2\xfb\x8f\x76\x4f\xa6\x03"); - test_framework.test_hash::(DUMMY_SEED_1024, b"\x62\x90\x81\x7f\x60\x01\x43\x2c\xd4\x41\x05\x8d\x2b\xb8\x2d\x88\xb3\xf3\x24\x25\xad\xe4\xc9\x3d\x56\x20\x78\x38"); + test_framework.test_hash::(b"", b"\xd1\x4a\x02\x8c\x2a\x3a\x2b\xc9\x47\x61\x02\xbb\x28\x82\x34\xc4\x15\xa2\xb0\x1f\x82\x8e\xa6\x2a\xc5\xb3\xe4\x2f"); + test_framework.test_hash::(b"a", b"\xab\xd3\x75\x34\xc7\xd9\xa2\xef\xb9\x46\x5d\xe9\x31\xcd\x70\x55\xff\xdb\x88\x79\x56\x3a\xe9\x80\x78\xd6\xd6\xd5"); + test_framework.test_hash::(b"abc", b"\x23\x09\x7d\x22\x34\x05\xd8\x22\x86\x42\xa4\x77\xbd\xa2\x55\xb3\x2a\xad\xbc\xe4\xbd\xa0\xb3\xf7\xe3\x6c\x9d\xa7"); + test_framework.test_hash::(b"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", b"\x75\x38\x8b\x16\x51\x27\x76\xcc\x5d\xba\x5d\xa1\xfd\x89\x01\x50\xb0\xc6\x45\x5c\xb4\xf5\x8b\x19\x52\x52\x25\x25"); + test_framework.test_hash::(DUMMY_SEED_512, b"\xb8\x06\x0c\xcc\x82\xd4\x0c\x57\x61\x56\xf7\xca\x03\x33\xe4\x38\x9e\x41\x0d\xf0\x27\xd2\xfb\x8f\x76\x4f\xa6\x03"); + test_framework.test_hash::(DUMMY_SEED_1024, b"\x62\x90\x81\x7f\x60\x01\x43\x2c\xd4\x41\x05\x8d\x2b\xb8\x2d\x88\xb3\xf3\x24\x25\xad\xe4\xc9\x3d\x56\x20\x78\x38"); } #[test] fn sha256() { let mut test_framework = TestFrameworkHash::new(); test_framework.enable_partial_final_input_tests = false; - test_framework.test_hash::(b"", b"\xe3\xb0\xc4\x42\x98\xfc\x1c\x14\x9a\xfb\xf4\xc8\x99\x6f\xb9\x24\x27\xae\x41\xe4\x64\x9b\x93\x4c\xa4\x95\x99\x1b\x78\x52\xb8\x55"); - test_framework.test_hash::(b"a", b"\xca\x97\x81\x12\xca\x1b\xbd\xca\xfa\xc2\x31\xb3\x9a\x23\xdc\x4d\xa7\x86\xef\xf8\x14\x7c\x4e\x72\xb9\x80\x77\x85\xaf\xee\x48\xbb"); - test_framework.test_hash::(b"abc", b"\xba\x78\x16\xbf\x8f\x01\xcf\xea\x41\x41\x40\xde\x5d\xae\x22\x23\xb0\x03\x61\xa3\x96\x17\x7a\x9c\xb4\x10\xff\x61\xf2\x00\x15\xad"); - test_framework.test_hash::(b"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", b"\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1"); - test_framework.test_hash::(DUMMY_SEED_512, b"\x11\x00\x09\xdc\xee\x21\x62\x0b\x16\x6f\x3a\xbf\xec\xb5\xef\xf7\xa8\x73\xbe\x72\x9d\x1c\x2d\x53\x82\x2e\x7a\xcc\x5f\x34\xeb\x9b"); + test_framework.test_hash::(b"", b"\xe3\xb0\xc4\x42\x98\xfc\x1c\x14\x9a\xfb\xf4\xc8\x99\x6f\xb9\x24\x27\xae\x41\xe4\x64\x9b\x93\x4c\xa4\x95\x99\x1b\x78\x52\xb8\x55"); + test_framework.test_hash::(b"a", b"\xca\x97\x81\x12\xca\x1b\xbd\xca\xfa\xc2\x31\xb3\x9a\x23\xdc\x4d\xa7\x86\xef\xf8\x14\x7c\x4e\x72\xb9\x80\x77\x85\xaf\xee\x48\xbb"); + test_framework.test_hash::(b"abc", b"\xba\x78\x16\xbf\x8f\x01\xcf\xea\x41\x41\x40\xde\x5d\xae\x22\x23\xb0\x03\x61\xa3\x96\x17\x7a\x9c\xb4\x10\xff\x61\xf2\x00\x15\xad"); + test_framework.test_hash::(b"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", b"\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1"); + test_framework.test_hash::(DUMMY_SEED_512, b"\x11\x00\x09\xdc\xee\x21\x62\x0b\x16\x6f\x3a\xbf\xec\xb5\xef\xf7\xa8\x73\xbe\x72\x9d\x1c\x2d\x53\x82\x2e\x7a\xcc\x5f\x34\xeb\x9b"); } #[test] fn sha384() { let mut test_framework = TestFrameworkHash::new(); test_framework.enable_partial_final_input_tests = false; - test_framework.test_hash::(b"", b"\x38\xb0\x60\xa7\x51\xac\x96\x38\x4c\xd9\x32\x7e\xb1\xb1\xe3\x6a\x21\xfd\xb7\x11\x14\xbe\x07\x43\x4c\x0c\xc7\xbf\x63\xf6\xe1\xda\x27\x4e\xde\xbf\xe7\x6f\x65\xfb\xd5\x1a\xd2\xf1\x48\x98\xb9\x5b"); - test_framework.test_hash::(b"a", b"\x54\xa5\x9b\x9f\x22\xb0\xb8\x08\x80\xd8\x42\x7e\x54\x8b\x7c\x23\xab\xd8\x73\x48\x6e\x1f\x03\x5d\xce\x9c\xd6\x97\xe8\x51\x75\x03\x3c\xaa\x88\xe6\xd5\x7b\xc3\x5e\xfa\xe0\xb5\xaf\xd3\x14\x5f\x31"); - test_framework.test_hash::(b"abc", b"\xcb\x00\x75\x3f\x45\xa3\x5e\x8b\xb5\xa0\x3d\x69\x9a\xc6\x50\x07\x27\x2c\x32\xab\x0e\xde\xd1\x63\x1a\x8b\x60\x5a\x43\xff\x5b\xed\x80\x86\x07\x2b\xa1\xe7\xcc\x23\x58\xba\xec\xa1\x34\xc8\x25\xa7"); - test_framework.test_hash::(b"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", b"\x09\x33\x0c\x33\xf7\x11\x47\xe8\x3d\x19\x2f\xc7\x82\xcd\x1b\x47\x53\x11\x1b\x17\x3b\x3b\x05\xd2\x2f\xa0\x80\x86\xe3\xb0\xf7\x12\xfc\xc7\xc7\x1a\x55\x7e\x2d\xb9\x66\xc3\xe9\xfa\x91\x74\x60\x39"); - test_framework.test_hash::(DUMMY_SEED_512, b"\x45\x82\xfc\x82\x43\x0e\x52\x68\x86\xa1\x85\x34\x11\xe6\x06\x45\xfe\xf7\xe8\xea\x0c\x85\x46\xb7\xc9\xba\x0c\x84\x16\xd9\xa9\x8f\xb5\x2e\xbd\x0c\x60\x5f\xbb\x70\x74\x9c\x4e\x3e\x5d\xa3\xdb\xac"); + test_framework.test_hash::(b"", b"\x38\xb0\x60\xa7\x51\xac\x96\x38\x4c\xd9\x32\x7e\xb1\xb1\xe3\x6a\x21\xfd\xb7\x11\x14\xbe\x07\x43\x4c\x0c\xc7\xbf\x63\xf6\xe1\xda\x27\x4e\xde\xbf\xe7\x6f\x65\xfb\xd5\x1a\xd2\xf1\x48\x98\xb9\x5b"); + test_framework.test_hash::(b"a", b"\x54\xa5\x9b\x9f\x22\xb0\xb8\x08\x80\xd8\x42\x7e\x54\x8b\x7c\x23\xab\xd8\x73\x48\x6e\x1f\x03\x5d\xce\x9c\xd6\x97\xe8\x51\x75\x03\x3c\xaa\x88\xe6\xd5\x7b\xc3\x5e\xfa\xe0\xb5\xaf\xd3\x14\x5f\x31"); + test_framework.test_hash::(b"abc", b"\xcb\x00\x75\x3f\x45\xa3\x5e\x8b\xb5\xa0\x3d\x69\x9a\xc6\x50\x07\x27\x2c\x32\xab\x0e\xde\xd1\x63\x1a\x8b\x60\x5a\x43\xff\x5b\xed\x80\x86\x07\x2b\xa1\xe7\xcc\x23\x58\xba\xec\xa1\x34\xc8\x25\xa7"); + test_framework.test_hash::(b"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", b"\x09\x33\x0c\x33\xf7\x11\x47\xe8\x3d\x19\x2f\xc7\x82\xcd\x1b\x47\x53\x11\x1b\x17\x3b\x3b\x05\xd2\x2f\xa0\x80\x86\xe3\xb0\xf7\x12\xfc\xc7\xc7\x1a\x55\x7e\x2d\xb9\x66\xc3\xe9\xfa\x91\x74\x60\x39"); + test_framework.test_hash::(DUMMY_SEED_512, b"\x45\x82\xfc\x82\x43\x0e\x52\x68\x86\xa1\x85\x34\x11\xe6\x06\x45\xfe\xf7\xe8\xea\x0c\x85\x46\xb7\xc9\xba\x0c\x84\x16\xd9\xa9\x8f\xb5\x2e\xbd\x0c\x60\x5f\xbb\x70\x74\x9c\x4e\x3e\x5d\xa3\xdb\xac"); } #[test] fn sha512() { let mut test_framework = TestFrameworkHash::new(); test_framework.enable_partial_final_input_tests = false; - test_framework.test_hash::(b"", b"\xcf\x83\xe1\x35\x7e\xef\xb8\xbd\xf1\x54\x28\x50\xd6\x6d\x80\x07\xd6\x20\xe4\x05\x0b\x57\x15\xdc\x83\xf4\xa9\x21\xd3\x6c\xe9\xce\x47\xd0\xd1\x3c\x5d\x85\xf2\xb0\xff\x83\x18\xd2\x87\x7e\xec\x2f\x63\xb9\x31\xbd\x47\x41\x7a\x81\xa5\x38\x32\x7a\xf9\x27\xda\x3e"); - test_framework.test_hash::(b"a", b"\x1f\x40\xfc\x92\xda\x24\x16\x94\x75\x09\x79\xee\x6c\xf5\x82\xf2\xd5\xd7\xd2\x8e\x18\x33\x5d\xe0\x5a\xbc\x54\xd0\x56\x0e\x0f\x53\x02\x86\x0c\x65\x2b\xf0\x8d\x56\x02\x52\xaa\x5e\x74\x21\x05\x46\xf3\x69\xfb\xbb\xce\x8c\x12\xcf\xc7\x95\x7b\x26\x52\xfe\x9a\x75"); - test_framework.test_hash::(b"abc", b"\xdd\xaf\x35\xa1\x93\x61\x7a\xba\xcc\x41\x73\x49\xae\x20\x41\x31\x12\xe6\xfa\x4e\x89\xa9\x7e\xa2\x0a\x9e\xee\xe6\x4b\x55\xd3\x9a\x21\x92\x99\x2a\x27\x4f\xc1\xa8\x36\xba\x3c\x23\xa3\xfe\xeb\xbd\x45\x4d\x44\x23\x64\x3c\xe8\x0e\x2a\x9a\xc9\x4f\xa5\x4c\xa4\x9f"); - test_framework.test_hash::(b"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", b"\x8e\x95\x9b\x75\xda\xe3\x13\xda\x8c\xf4\xf7\x28\x14\xfc\x14\x3f\x8f\x77\x79\xc6\xeb\x9f\x7f\xa1\x72\x99\xae\xad\xb6\x88\x90\x18\x50\x1d\x28\x9e\x49\x00\xf7\xe4\x33\x1b\x99\xde\xc4\xb5\x43\x3a\xc7\xd3\x29\xee\xb6\xdd\x26\x54\x5e\x96\xe5\x5b\x87\x4b\xe9\x09"); - test_framework.test_hash::(DUMMY_SEED_512, b"\xed\xb9\xbe\xd7\x21\xaa\x6a\x5f\x6f\xbc\x66\x19\xd3\xa3\xc2\xbe\x3d\x04\x30\x43\xf0\x5a\x9a\xeb\xc7\xb1\x19\x7a\x2a\xa9\xc4\x9a\x57\xd5\xdd\xd4\x67\x4c\x17\x85\x78\x50\x88\xd9\xf1\xff\x42\xc7\x97\xa0\x2a\xdc\x9b\x81\x7a\x13\x9a\x50\x97\x0d\xa6\xc9\x95\x24"); + test_framework.test_hash::(b"", b"\xcf\x83\xe1\x35\x7e\xef\xb8\xbd\xf1\x54\x28\x50\xd6\x6d\x80\x07\xd6\x20\xe4\x05\x0b\x57\x15\xdc\x83\xf4\xa9\x21\xd3\x6c\xe9\xce\x47\xd0\xd1\x3c\x5d\x85\xf2\xb0\xff\x83\x18\xd2\x87\x7e\xec\x2f\x63\xb9\x31\xbd\x47\x41\x7a\x81\xa5\x38\x32\x7a\xf9\x27\xda\x3e"); + test_framework.test_hash::(b"a", b"\x1f\x40\xfc\x92\xda\x24\x16\x94\x75\x09\x79\xee\x6c\xf5\x82\xf2\xd5\xd7\xd2\x8e\x18\x33\x5d\xe0\x5a\xbc\x54\xd0\x56\x0e\x0f\x53\x02\x86\x0c\x65\x2b\xf0\x8d\x56\x02\x52\xaa\x5e\x74\x21\x05\x46\xf3\x69\xfb\xbb\xce\x8c\x12\xcf\xc7\x95\x7b\x26\x52\xfe\x9a\x75"); + test_framework.test_hash::(b"abc", b"\xdd\xaf\x35\xa1\x93\x61\x7a\xba\xcc\x41\x73\x49\xae\x20\x41\x31\x12\xe6\xfa\x4e\x89\xa9\x7e\xa2\x0a\x9e\xee\xe6\x4b\x55\xd3\x9a\x21\x92\x99\x2a\x27\x4f\xc1\xa8\x36\xba\x3c\x23\xa3\xfe\xeb\xbd\x45\x4d\x44\x23\x64\x3c\xe8\x0e\x2a\x9a\xc9\x4f\xa5\x4c\xa4\x9f"); + test_framework.test_hash::(b"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", b"\x8e\x95\x9b\x75\xda\xe3\x13\xda\x8c\xf4\xf7\x28\x14\xfc\x14\x3f\x8f\x77\x79\xc6\xeb\x9f\x7f\xa1\x72\x99\xae\xad\xb6\x88\x90\x18\x50\x1d\x28\x9e\x49\x00\xf7\xe4\x33\x1b\x99\xde\xc4\xb5\x43\x3a\xc7\xd3\x29\xee\xb6\xdd\x26\x54\x5e\x96\xe5\x5b\x87\x4b\xe9\x09"); + test_framework.test_hash::(DUMMY_SEED_512, b"\xed\xb9\xbe\xd7\x21\xaa\x6a\x5f\x6f\xbc\x66\x19\xd3\xa3\xc2\xbe\x3d\x04\x30\x43\xf0\x5a\x9a\xeb\xc7\xb1\x19\x7a\x2a\xa9\xc4\x9a\x57\xd5\xdd\xd4\x67\x4c\x17\x85\x78\x50\x88\xd9\xf1\xff\x42\xc7\x97\xa0\x2a\xdc\x9b\x81\x7a\x13\x9a\x50\x97\x0d\xa6\xc9\x95\x24"); } } diff --git a/crypto/sha3/tests/sha3_tests.rs b/crypto/sha3/tests/sha3_tests.rs index 68fd94b..cdaa2a5 100644 --- a/crypto/sha3/tests/sha3_tests.rs +++ b/crypto/sha3/tests/sha3_tests.rs @@ -2,7 +2,7 @@ mod sha3_tests { use super::sha3_test_helpers::*; use bouncycastle_core::key_material::{KeyMaterial256, KeyMaterial512, KeyMaterial, KeyType, KeyMaterialTrait,}; - use bouncycastle_core::traits::{Hash, HashAlgParams, KDF, SecurityStrength}; + use bouncycastle_core::traits::{Hash, HashAlgParams, HashFixedOutput, KDF, SecurityStrength}; use bouncycastle_core_test_framework::DUMMY_SEED_512; use bouncycastle_core_test_framework::hash::TestFrameworkHash; use bouncycastle_core_test_framework::kdf::TestFrameworkKDF; @@ -29,19 +29,19 @@ mod sha3_tests { #[test] fn test_framework_hash() { let test_framework = TestFrameworkHash::new(); - test_framework.test_hash::(DUMMY_SEED_512, b"\xFE\x51\xC5\xD7\x62\x48\xE1\xE9\xD3\x01\x29\x6A\xE8\xAB\x94\x69\xD2\x86\x34\xB4\xAD\x3E\x9E\x78\xC8\xB0\x9D\x47"); - test_framework.test_hash::(DUMMY_SEED_512, b"\xD4\x72\x8E\xA5\xE9\xF3\x81\x9F\x2B\x47\x60\x15\x1A\x8F\x80\x2D\xBE\x9F\x94\x1F\xD6\xFB\x59\xB3\x71\x58\x92\x43\x65\x55\x77\x2A"); - test_framework.test_hash::(DUMMY_SEED_512, b"\xd5\x3b\x51\x68\x53\xf5\xac\xb4\xaa\xfd\xa5\x9d\x6f\x74\x0f\x69\x99\xc9\xe5\x21\x1c\x51\x03\x9c\x6d\x64\x5b\xf9\x83\xd7\xba\x0b\xdf\x12\x31\xb5\x50\x90\xb5\x5e\x35\x99\xee\x7a\xaa\x62\xd3\xbf"); - test_framework.test_hash::(DUMMY_SEED_512, b"\x58\x4c\xc7\x02\xc2\x22\x9a\x0a\xbc\x78\x9b\xfa\x64\xb4\x27\x1f\xb8\xf0\xbb\x78\x67\x15\x88\xb9\xef\x1d\x09\x3e\xa3\xd4\x72\x58\x4c\x6d\x43\xb5\x68\x33\x59\x47\x2f\x44\x1b\x33\x85\x6f\x68\x28\x59\xf0\xc3\x95\x4b\x56\x80\x8f\xd1\xfb\xa0\xb5\x9c\x9d\x19\x54"); + test_framework.test_hash::(DUMMY_SEED_512, b"\xFE\x51\xC5\xD7\x62\x48\xE1\xE9\xD3\x01\x29\x6A\xE8\xAB\x94\x69\xD2\x86\x34\xB4\xAD\x3E\x9E\x78\xC8\xB0\x9D\x47"); + test_framework.test_hash::(DUMMY_SEED_512, b"\xD4\x72\x8E\xA5\xE9\xF3\x81\x9F\x2B\x47\x60\x15\x1A\x8F\x80\x2D\xBE\x9F\x94\x1F\xD6\xFB\x59\xB3\x71\x58\x92\x43\x65\x55\x77\x2A"); + test_framework.test_hash::(DUMMY_SEED_512, b"\xd5\x3b\x51\x68\x53\xf5\xac\xb4\xaa\xfd\xa5\x9d\x6f\x74\x0f\x69\x99\xc9\xe5\x21\x1c\x51\x03\x9c\x6d\x64\x5b\xf9\x83\xd7\xba\x0b\xdf\x12\x31\xb5\x50\x90\xb5\x5e\x35\x99\xee\x7a\xaa\x62\xd3\xbf"); + test_framework.test_hash::(DUMMY_SEED_512, b"\x58\x4c\xc7\x02\xc2\x22\x9a\x0a\xbc\x78\x9b\xfa\x64\xb4\x27\x1f\xb8\xf0\xbb\x78\x67\x15\x88\xb9\xef\x1d\x09\x3e\xa3\xd4\x72\x58\x4c\x6d\x43\xb5\x68\x33\x59\x47\x2f\x44\x1b\x33\x85\x6f\x68\x28\x59\xf0\xc3\x95\x4b\x56\x80\x8f\xd1\xfb\xa0\xb5\x9c\x9d\x19\x54"); } #[test] fn test_static_hash() { // success case -- return vec version - assert_eq!(SHA3_224::new().hash(DUMMY_SEED_512), b"\xFE\x51\xC5\xD7\x62\x48\xE1\xE9\xD3\x01\x29\x6A\xE8\xAB\x94\x69\xD2\x86\x34\xB4\xAD\x3E\x9E\x78\xC8\xB0\x9D\x47"); - assert_eq!(SHA3_256::new().hash(DUMMY_SEED_512), b"\xD4\x72\x8E\xA5\xE9\xF3\x81\x9F\x2B\x47\x60\x15\x1A\x8F\x80\x2D\xBE\x9F\x94\x1F\xD6\xFB\x59\xB3\x71\x58\x92\x43\x65\x55\x77\x2A"); - assert_eq!(SHA3_384::new().hash(DUMMY_SEED_512), b"\xd5\x3b\x51\x68\x53\xf5\xac\xb4\xaa\xfd\xa5\x9d\x6f\x74\x0f\x69\x99\xc9\xe5\x21\x1c\x51\x03\x9c\x6d\x64\x5b\xf9\x83\xd7\xba\x0b\xdf\x12\x31\xb5\x50\x90\xb5\x5e\x35\x99\xee\x7a\xaa\x62\xd3\xbf"); - assert_eq!(SHA3_512::new().hash(DUMMY_SEED_512), b"\x58\x4c\xc7\x02\xc2\x22\x9a\x0a\xbc\x78\x9b\xfa\x64\xb4\x27\x1f\xb8\xf0\xbb\x78\x67\x15\x88\xb9\xef\x1d\x09\x3e\xa3\xd4\x72\x58\x4c\x6d\x43\xb5\x68\x33\x59\x47\x2f\x44\x1b\x33\x85\x6f\x68\x28\x59\xf0\xc3\x95\x4b\x56\x80\x8f\xd1\xfb\xa0\xb5\x9c\x9d\x19\x54"); + assert_eq!(SHA3_224::new().hash(DUMMY_SEED_512), *b"\xFE\x51\xC5\xD7\x62\x48\xE1\xE9\xD3\x01\x29\x6A\xE8\xAB\x94\x69\xD2\x86\x34\xB4\xAD\x3E\x9E\x78\xC8\xB0\x9D\x47"); + assert_eq!(SHA3_256::new().hash(DUMMY_SEED_512), *b"\xD4\x72\x8E\xA5\xE9\xF3\x81\x9F\x2B\x47\x60\x15\x1A\x8F\x80\x2D\xBE\x9F\x94\x1F\xD6\xFB\x59\xB3\x71\x58\x92\x43\x65\x55\x77\x2A"); + assert_eq!(SHA3_384::new().hash(DUMMY_SEED_512), *b"\xd5\x3b\x51\x68\x53\xf5\xac\xb4\xaa\xfd\xa5\x9d\x6f\x74\x0f\x69\x99\xc9\xe5\x21\x1c\x51\x03\x9c\x6d\x64\x5b\xf9\x83\xd7\xba\x0b\xdf\x12\x31\xb5\x50\x90\xb5\x5e\x35\x99\xee\x7a\xaa\x62\xd3\xbf"); + assert_eq!(SHA3_512::new().hash(DUMMY_SEED_512), *b"\x58\x4c\xc7\x02\xc2\x22\x9a\x0a\xbc\x78\x9b\xfa\x64\xb4\x27\x1f\xb8\xf0\xbb\x78\x67\x15\x88\xb9\xef\x1d\x09\x3e\xa3\xd4\x72\x58\x4c\x6d\x43\xb5\x68\x33\x59\x47\x2f\x44\x1b\x33\x85\x6f\x68\x28\x59\xf0\xc3\x95\x4b\x56\x80\x8f\xd1\xfb\xa0\xb5\x9c\x9d\x19\x54"); // success case -- output slice version // We're just gonna hand an output slice that's too big and the result had better get written to the beginning of it. @@ -105,19 +105,19 @@ mod sha3_tests { let output = SHA3_224::new() .do_final_partial_bits(input_byte, 1) .expect("Failed to finalize partial input"); - assert_eq!(output, b"\x6f\x2f\xc5\x4a\x6b\x11\xa6\xda\x61\x1e\xd7\x34\x50\x5b\x9c\xab\x89\xee\xcc\x1d\xc7\xdd\x2d\xeb\xd2\x7b\xd1\xc9"); + assert_eq!(output, *b"\x6f\x2f\xc5\x4a\x6b\x11\xa6\xda\x61\x1e\xd7\x34\x50\x5b\x9c\xab\x89\xee\xcc\x1d\xc7\xdd\x2d\xeb\xd2\x7b\xd1\xc9"); let output = SHA3_224::new() .do_final_partial_bits(input_byte, 2) .expect("Failed to finalize partial input"); - assert_eq!(output, b"\xdf\xeb\x54\xcd\x8a\x7a\x54\x90\x89\xae\x37\x09\x30\x79\x23\xb4\x91\x16\xdb\xa1\xad\x3c\xbc\x3f\xe4\x03\xb6\xe8"); + assert_eq!(output, *b"\xdf\xeb\x54\xcd\x8a\x7a\x54\x90\x89\xae\x37\x09\x30\x79\x23\xb4\x91\x16\xdb\xa1\xad\x3c\xbc\x3f\xe4\x03\xb6\xe8"); // .. let output = SHA3_224::new() .do_final_partial_bits(input_byte, 7) .expect("Failed to finalize partial input"); - assert_eq!(output, b"\x81\x67\x07\x1f\xfc\x12\xaf\x71\x65\x06\x01\x4e\x99\x49\xe9\xa8\x9d\x11\x26\x04\x93\xf9\x88\x09\x8c\xbb\x7f\x35"); + assert_eq!(output, *b"\x81\x67\x07\x1f\xfc\x12\xaf\x71\x65\x06\x01\x4e\x99\x49\xe9\xa8\x9d\x11\x26\x04\x93\xf9\x88\x09\x8c\xbb\x7f\x35"); // println!("{:2x?}", output); // success case -- output slice version @@ -125,7 +125,7 @@ mod sha3_tests { SHA3_224::new() .do_final_partial_bits_out(input_byte, 7, &mut *output) .expect("Failed to finalize partial input"); - assert_eq!(output, b"\x81\x67\x07\x1f\xfc\x12\xaf\x71\x65\x06\x01\x4e\x99\x49\xe9\xa8\x9d\x11\x26\x04\x93\xf9\x88\x09\x8c\xbb\x7f\x35"); + assert_eq!(output, *b"\x81\x67\x07\x1f\xfc\x12\xaf\x71\x65\x06\x01\x4e\x99\x49\xe9\xa8\x9d\x11\x26\x04\x93\xf9\x88\x09\x8c\xbb\x7f\x35"); //output slice too small -- should just truncate let mut expected_output = vec![0u8; SHA3_224::new().output_len()]; @@ -406,17 +406,20 @@ mod sha3_tests { fn run_test_case(tc: TestCase, mut sha3: impl Hash) { let partial_bits = tc.bits % 8; - let output: Vec; + let mut output = [0u8; 64]; + let bytes_written; if partial_bits == 0 { sha3.do_update(tc.msg.as_slice()); - output = sha3.do_final(); + bytes_written = sha3.do_final_out(&mut output); } else { sha3.do_update(&tc.msg[..(tc.msg.len() - 1)]); - output = sha3.do_final_partial_bits(tc.msg[tc.msg.len() - 1], partial_bits).unwrap(); + bytes_written = sha3 + .do_final_partial_bits_out(tc.msg[tc.msg.len() - 1], partial_bits, &mut output) + .unwrap(); } - assert_eq!(tc.hash, output); + assert_eq!(tc.hash, &output[..bytes_written]); } }