From 953c1d7ec8ff3e4c21c9b52412c2b90c40b21e37 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 9919871b1..208954e06 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 a121a0a8b..0615213a6 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) -}