From b4d133473edc4afb4161e433d912a1fe76dda96c Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Wed, 18 Dec 2024 13:55:39 -0800 Subject: [PATCH] digest internals: Refactor `format_output`. Avoid calling `format_output` through pointers. It turns out it's more efficient to just do things the straightforward way, as we don't save anything (code size, in particular) with the function pointer approach, as we would with the `block_data_order`. This further clarifies the static analysis of the panic-freeness of `BlockContext::try_finish` as we remove these two unreachable `unreachable!()` calls. --- src/digest.rs | 9 +-------- src/digest/dynstate.rs | 31 +++++++++++-------------------- 2 files changed, 12 insertions(+), 28 deletions(-) diff --git a/src/digest.rs b/src/digest.rs index 9919871b1e..208954e06c 100644 --- a/src/digest.rs +++ b/src/digest.rs @@ -127,7 +127,7 @@ impl BlockContext { Ok(Digest { algorithm: self.algorithm, - value: (self.algorithm.format_output)(self.state), + value: self.state.format_output(), }) } @@ -348,8 +348,6 @@ pub struct Algorithm { cpu_features: cpu::Features, ) -> (usize, &'d [u8]), - format_output: fn(input: DynState) -> Output, - initial_state: DynState, id: AlgorithmID, @@ -405,7 +403,6 @@ pub static SHA1_FOR_LEGACY_USE_ONLY: Algorithm = Algorithm { chaining_len: sha1::CHAINING_LEN, block_len: sha1::BLOCK_LEN, block_data_order: dynstate::sha1_block_data_order, - format_output: dynstate::sha256_format_output, initial_state: DynState::new32([ Wrapping(0x67452301u32), Wrapping(0xefcdab89u32), @@ -427,7 +424,6 @@ pub static SHA256: Algorithm = Algorithm { chaining_len: SHA256_OUTPUT_LEN, block_len: SHA256_BLOCK_LEN, block_data_order: dynstate::sha256_block_data_order, - format_output: dynstate::sha256_format_output, initial_state: DynState::new32([ Wrapping(0x6a09e667u32), Wrapping(0xbb67ae85u32), @@ -449,7 +445,6 @@ pub static SHA384: Algorithm = Algorithm { chaining_len: SHA512_OUTPUT_LEN, block_len: SHA512_BLOCK_LEN, block_data_order: dynstate::sha512_block_data_order, - format_output: dynstate::sha512_format_output, initial_state: DynState::new64([ Wrapping(0xcbbb9d5dc1059ed8), Wrapping(0x629a292a367cd507), @@ -471,7 +466,6 @@ pub static SHA512: Algorithm = Algorithm { chaining_len: SHA512_OUTPUT_LEN, block_len: SHA512_BLOCK_LEN, block_data_order: dynstate::sha512_block_data_order, - format_output: dynstate::sha512_format_output, initial_state: DynState::new64([ Wrapping(0x6a09e667f3bcc908), Wrapping(0xbb67ae8584caa73b), @@ -497,7 +491,6 @@ pub static SHA512_256: Algorithm = Algorithm { chaining_len: SHA512_OUTPUT_LEN, block_len: SHA512_BLOCK_LEN, block_data_order: dynstate::sha512_block_data_order, - format_output: dynstate::sha512_format_output, initial_state: DynState::new64([ Wrapping(0x22312194fc2bf72c), Wrapping(0x9f555fa3c84c64c2), diff --git a/src/digest/dynstate.rs b/src/digest/dynstate.rs index a121a0a8bd..0615213a69 100644 --- a/src/digest/dynstate.rs +++ b/src/digest/dynstate.rs @@ -33,6 +33,17 @@ impl DynState { pub const fn new64(initial_state: sha2::State64) -> Self { Self::As64(initial_state) } + + pub fn format_output(self) -> Output { + match self { + Self::As64(state) => { + format_output::<_, _, { size_of::() }>(state, u64::to_be_bytes) + } + Self::As32(state) => { + format_output::<_, _, { size_of::() }>(state, u32::to_be_bytes) + } + } + } } pub(super) fn sha1_block_data_order<'d>( @@ -85,23 +96,3 @@ pub(super) fn sha512_block_data_order<'d>( sha2::block_data_order_64(state, full_blocks, cpu_features); (full_blocks.len() * sha2::SHA512_BLOCK_LEN.into(), leftover) } - -pub(super) fn sha256_format_output(state: DynState) -> Output { - let state = match state { - DynState::As32(state) => state, - _ => { - unreachable!(); - } - }; - format_output::<_, _, { size_of::() }>(state, u32::to_be_bytes) -} - -pub(super) fn sha512_format_output(state: DynState) -> Output { - let state = match state { - DynState::As64(state) => state, - _ => { - unreachable!(); - } - }; - format_output::<_, _, { size_of::() }>(state, u64::to_be_bytes) -}