From bae589650825037a83a36a2277d9a3d01eb0f7b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Wed, 19 Mar 2025 16:50:34 +0300 Subject: [PATCH 01/31] digest: add `newtype!` macro --- digest/src/lib.rs | 1 + digest/src/newtype.rs | 281 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 282 insertions(+) create mode 100644 digest/src/newtype.rs diff --git a/digest/src/lib.rs b/digest/src/lib.rs index bd9f3c035..183a88ac7 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -55,6 +55,7 @@ pub mod core_api; mod digest; #[cfg(feature = "mac")] mod mac; +mod newtype; #[cfg(feature = "core-api")] pub use block_buffer; diff --git a/digest/src/newtype.rs b/digest/src/newtype.rs new file mode 100644 index 000000000..2e9df1e5c --- /dev/null +++ b/digest/src/newtype.rs @@ -0,0 +1,281 @@ +/// Creates a newtype wrapper around another type and +/// delegates implementation of `digest` traits to it. +#[macro_export] +macro_rules! newtype { + ( + $(#[$attr:meta])* + $name:ident($wrapped_ty:ty); + delegate: $($trait_name:ident)* + ) => { + $(#[$attr])* + pub struct $name($wrapped_ty); + + $( + newtype!(delegate_impl: $name($wrapped_ty) $trait_name); + )* + + // Clone, Default, BlockSizeUser, CoreProxy, ExtendableOutput, FixedOutput, KeyInit, + // OutputSizeUser, Update, HashMarker, MacMarker + + // Write + }; + + (delegate_impl: $name:ident($wrapped_ty:ty) Debug) => { + impl core::fmt::Debug for $name { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str(concat!(stringify!($name), " { ... }")) + } + } + }; + + (delegate_impl: $name:ident($wrapped_ty:ty) AlgorithmName) => { + impl $crate::crypto_common::AlgorithmName for $name { + fn write_alg_name(f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { + f.write_str(stringify!($name)) + } + } + }; + + (delegate_impl: $name:ident($wrapped_ty:ty) Clone) => { + impl Clone for $name { + #[inline] + fn clone(&self) -> Self { + Self(self.0.clone()) + } + } + }; + + (delegate_impl: $name:ident($wrapped_ty:ty) Default) => { + impl Default for $name { + #[inline] + fn default() -> Self { + Self(Default::default()) + } + } + }; + + (delegate_impl: $name:ident($wrapped_ty:ty) InnerInit) => { + impl $crate::InnerInit for $name { + #[inline] + fn new(inner: Self::Inner) -> Self { + self.0.new(inner) + } + } + }; + + (delegate_impl: $name:ident($wrapped_ty:ty) KeyInit) => { + impl $crate::KeyInit for $name { + #[inline] + fn new(key: &$crate::Key) -> Self { + self.0.new(key) + } + } + }; + + (delegate_impl: $name:ident($wrapped_ty:ty) CustomizedInit) => { + impl $crate::CustomizedInit for $name { + #[inline] + fn new_customized(customization: &[u8]) -> Self { + $wrapped_ty::new_customized(customization) + } + } + }; + + (delegate_impl: $name:ident($wrapped_ty:ty) Reset) => { + impl Reset for $name { + #[inline] + fn reset(&mut self) { + self.0.reset() + } + } + }; + + (delegate_impl: $name:ident($wrapped_ty:ty) BlockSizeUser) => { + impl $crate::core_api::BlockSizeUser for $name { + type BlockSize = <$wrapped_ty as $crate::crypto_common::BlockSizeUser>::BlockSize; + } + }; + + (delegate_impl: $name:ident($wrapped_ty:ty) OutputSizeUser) => { + impl $crate::OutputSizeUser for $name { + type OutputSize = <$wrapped_ty as $crate::core_api::OutputSizeUser>::OutputSize; + } + }; + + (delegate_impl: $name:ident($wrapped_ty:ty) KeySizeUser) => { + impl $crate::crypto_common::KeySizeUser for $name { + type KeySize = <$wrapped_ty as $crate::crypto_common::KeySizeUser>::KeySize; + } + }; + + (delegate_impl: $name:ident($wrapped_ty:ty) HashMarker) => { + impl $crate::HashMarker for $name {} + + // TODO: assert that `$wrapped_ty` impls `HashMarker`? + }; + + (delegate_impl: $name:ident($wrapped_ty:ty) MacMarker) => { + impl $crate::MacMarker for $name {} + + // TODO: assert that `$wrapped_ty` impls `MacMarker`? + }; + + (delegate_impl: $name:ident($wrapped_ty:ty) Update) => { + impl $crate::Update for $name { + #[inline] + fn update(&mut self, data: &[u8]) { + self.0.update(data) + } + } + + #[cfg(feature = "std")] + impl std::io::Write for $name { + #[inline] + fn write(&mut self, data: &[u8]) -> std::io::Result { + $crate::Update::update(&mut self.0, data); + Ok(data.len()) + } + + #[inline] + fn flush(&mut self) -> std::io::Result<()> { + Ok(()) + } + } + }; + + (delegate_impl: $name:ident($wrapped_ty:ty) CoreProxy) => { + impl $crate::core_api::CoreProxy for $name { + type Core = <$wrapped_ty as $crate::core_api::CoreProxy>::Core; + } + }; + + (delegate_impl: $name:ident($wrapped_ty:ty) FixedOutput) => { + impl $crate::FixedOutput for $name { + #[inline] + fn finalize_into(self, out: &mut $crate::Output) { + self.0.finalize_into(out); + } + } + }; + + (delegate_impl: $name:ident($wrapped_ty:ty) FixedOutputReset) => { + impl $crate::FixedOutputReset for $name { + #[inline] + fn finalize_into_reset(&mut self, out: &mut Output) { + self.0.finalize_into_reset(out); + } + } + }; + + (delegate_impl: $name:ident($wrapped_ty:ty) VariableOutput) => { + impl $crate::VariableOutput for $name { + const MAX_OUTPUT_SIZE: usize = <$wrapped_ty as $crate::VariableOutput>::MAX_OUTPUT_SIZE; + + #[inline] + fn new(output_size: usize) -> Result { + $wrapped_ty::new(output_size) + } + + #[inline] + fn output_size(&self) -> usize { + self.0.output_size() + } + + #[inline] + fn finalize_variable(self, out: &mut [u8]) -> Result<(), $crate::InvalidBufferSize> { + self.0.finalize_variable(out) + } + } + }; + + (delegate_impl: $name:ident($wrapped_ty:ty) VariableOutputReset) => { + impl $crate::VariableOutputReset for $name { + #[inline] + fn finalize_variable_reset( + &mut self, + out: &mut [u8], + ) -> Result<(), $crate::InvalidBufferSize> { + self.0.finalize_variable_reset(out) + } + } + }; + + (delegate_impl: $name:ident($wrapped_ty:ty) ExtendableOutput) => { + impl $crate::ExtendableOutput for $name { + // TODO: use a newtype wrapper? + type Reader = <$wrapped_ty as $crate::ExtendableOutput>::Reader; + + fn finalize_xof(self) -> Self::Reader { + self.0.finalize_xof() + } + } + }; + + (delegate_impl: $name:ident($wrapped_ty:ty) ExtendableOutputReset) => { + impl $crate::ExtendableOutputReset for $name { + fn finalize_xof_reset(&mut self) -> Self::Reader { + self.0.finalize_xof_reset() + } + } + }; +} + +#[cfg(test)] +mod tests { + use crate::HashMarker; + use crate::consts::U8; + use crate::core_api::{Buffer, BufferKindUser, CoreWrapper, FixedOutputCore, UpdateCore}; + use crypto_common::{Block, Output, OutputSizeUser, Reset}; + + /// Core of primitive XOR hasher for testing purposes + #[derive(Clone, Default, Debug)] + pub struct FixedHashCore { + state: u64, + } + + impl crate::core_api::BlockSizeUser for FixedHashCore { + type BlockSize = U8; + } + + impl BufferKindUser for FixedHashCore { + type BufferKind = block_buffer::Eager; + } + + impl Reset for FixedHashCore { + fn reset(&mut self) { + self.state = 0; + } + } + + impl UpdateCore for FixedHashCore { + fn update_blocks(&mut self, blocks: &[Block]) { + for block in blocks { + self.state ^= u64::from_le_bytes(block.0) + } + } + } + + impl HashMarker for FixedHashCore {} + + impl OutputSizeUser for FixedHashCore { + type OutputSize = U8; + } + + impl FixedOutputCore for FixedHashCore { + fn finalize_fixed_core(&mut self, buffer: &mut Buffer, out: &mut Output) { + let block = buffer.pad_with_zeros(); + self.state ^= u64::from_le_bytes(block.0); + out.copy_from_slice(&self.state.to_le_bytes()); + } + } + + newtype!( + /// Primitive XOR hasher for testing purposes + FixedHash(CoreWrapper); + delegate: + Debug AlgorithmName + Clone Default Reset + BlockSizeUser OutputSizeUser HashMarker + Update FixedOutput FixedOutputReset + ); +} From f86022aaedfb981784c6ed289fb1aaa1231149c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Wed, 19 Mar 2025 16:52:14 +0300 Subject: [PATCH 02/31] Gate tests --- digest/src/newtype.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/digest/src/newtype.rs b/digest/src/newtype.rs index 2e9df1e5c..3ac7326d6 100644 --- a/digest/src/newtype.rs +++ b/digest/src/newtype.rs @@ -221,6 +221,7 @@ macro_rules! newtype { } #[cfg(test)] +#[cfg(feature = "core-api")] mod tests { use crate::HashMarker; use crate::consts::U8; From 740b5fa39e44ddd81500d4e09fb80704beacafdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Mon, 7 Apr 2025 15:23:58 +0300 Subject: [PATCH 03/31] Remove outdated docs --- digest/README.md | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/digest/README.md b/digest/README.md index 5038829ad..e17da08b0 100644 --- a/digest/README.md +++ b/digest/README.md @@ -64,25 +64,6 @@ let hash = Sha256::digest(b"my message"); println!("Result: {:x}", hash); ``` -### Hashing `Read`-able objects - -If you want to hash data from [`Read`][3] trait (e.g. from file) you can rely on -implementation of [`Write`][4] trait (requires enabled-by-default `std` feature): - -```rust -use sha2::{Sha256, Digest}; -use std::{fs, io}; - -let mut file = fs::File::open(&path)?; -let mut hasher = Sha256::new(); -let n = io::copy(&mut file, &mut hasher)?; -let hash = hasher.finalize(); - -println!("Path: {}", path); -println!("Bytes processed: {}", n); -println!("Hash value: {:x}", hash); -``` - ### Generic code You can write generic code over `Digest` (or other traits from `digest` crate) From 1261c02a126e35317c845d69a95cb36d692db246 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Mon, 7 Apr 2025 15:24:29 +0300 Subject: [PATCH 04/31] Remove `io::Write` impl --- digest/src/newtype.rs | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/digest/src/newtype.rs b/digest/src/newtype.rs index 3ac7326d6..d4797f814 100644 --- a/digest/src/newtype.rs +++ b/digest/src/newtype.rs @@ -127,20 +127,6 @@ macro_rules! newtype { self.0.update(data) } } - - #[cfg(feature = "std")] - impl std::io::Write for $name { - #[inline] - fn write(&mut self, data: &[u8]) -> std::io::Result { - $crate::Update::update(&mut self.0, data); - Ok(data.len()) - } - - #[inline] - fn flush(&mut self) -> std::io::Result<()> { - Ok(()) - } - } }; (delegate_impl: $name:ident($wrapped_ty:ty) CoreProxy) => { From 6b9c5a9acc8229454a2f2e3f8fb9534d51cd42f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Mon, 7 Apr 2025 16:29:09 +0300 Subject: [PATCH 05/31] Move dummy hash to the tests folder --- digest/src/newtype.rs | 63 +------------------------------------------ digest/tests/dummy.rs | 60 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 62 deletions(-) create mode 100644 digest/tests/dummy.rs diff --git a/digest/src/newtype.rs b/digest/src/newtype.rs index d4797f814..281736a60 100644 --- a/digest/src/newtype.rs +++ b/digest/src/newtype.rs @@ -11,7 +11,7 @@ macro_rules! newtype { pub struct $name($wrapped_ty); $( - newtype!(delegate_impl: $name($wrapped_ty) $trait_name); + $crate::newtype!(delegate_impl: $name($wrapped_ty) $trait_name); )* // Clone, Default, BlockSizeUser, CoreProxy, ExtendableOutput, FixedOutput, KeyInit, @@ -205,64 +205,3 @@ macro_rules! newtype { } }; } - -#[cfg(test)] -#[cfg(feature = "core-api")] -mod tests { - use crate::HashMarker; - use crate::consts::U8; - use crate::core_api::{Buffer, BufferKindUser, CoreWrapper, FixedOutputCore, UpdateCore}; - use crypto_common::{Block, Output, OutputSizeUser, Reset}; - - /// Core of primitive XOR hasher for testing purposes - #[derive(Clone, Default, Debug)] - pub struct FixedHashCore { - state: u64, - } - - impl crate::core_api::BlockSizeUser for FixedHashCore { - type BlockSize = U8; - } - - impl BufferKindUser for FixedHashCore { - type BufferKind = block_buffer::Eager; - } - - impl Reset for FixedHashCore { - fn reset(&mut self) { - self.state = 0; - } - } - - impl UpdateCore for FixedHashCore { - fn update_blocks(&mut self, blocks: &[Block]) { - for block in blocks { - self.state ^= u64::from_le_bytes(block.0) - } - } - } - - impl HashMarker for FixedHashCore {} - - impl OutputSizeUser for FixedHashCore { - type OutputSize = U8; - } - - impl FixedOutputCore for FixedHashCore { - fn finalize_fixed_core(&mut self, buffer: &mut Buffer, out: &mut Output) { - let block = buffer.pad_with_zeros(); - self.state ^= u64::from_le_bytes(block.0); - out.copy_from_slice(&self.state.to_le_bytes()); - } - } - - newtype!( - /// Primitive XOR hasher for testing purposes - FixedHash(CoreWrapper); - delegate: - Debug AlgorithmName - Clone Default Reset - BlockSizeUser OutputSizeUser HashMarker - Update FixedOutput FixedOutputReset - ); -} diff --git a/digest/tests/dummy.rs b/digest/tests/dummy.rs new file mode 100644 index 000000000..555d3cd16 --- /dev/null +++ b/digest/tests/dummy.rs @@ -0,0 +1,60 @@ +#![cfg(feature = "core-api")] + +use digest::{ + HashMarker, + consts::U8, + core_api::{Buffer, BufferKindUser, CoreWrapper, FixedOutputCore, UpdateCore}, + crypto_common::{Block, BlockSizeUser, Output, OutputSizeUser, Reset}, +}; + +/// Core of primitive XOR hasher for testing purposes +#[derive(Clone, Default, Debug)] +pub struct FixedHashCore { + state: u64, +} + +impl BlockSizeUser for FixedHashCore { + type BlockSize = U8; +} + +impl BufferKindUser for FixedHashCore { + type BufferKind = block_buffer::Eager; +} + +impl Reset for FixedHashCore { + fn reset(&mut self) { + self.state = 0; + } +} + +impl UpdateCore for FixedHashCore { + fn update_blocks(&mut self, blocks: &[Block]) { + for block in blocks { + self.state ^= u64::from_le_bytes(block.0) + } + } +} + +impl HashMarker for FixedHashCore {} + +impl OutputSizeUser for FixedHashCore { + type OutputSize = U8; +} + +impl FixedOutputCore for FixedHashCore { + fn finalize_fixed_core(&mut self, buffer: &mut Buffer, out: &mut Output) { + let block = buffer.pad_with_zeros(); + self.state ^= u64::from_le_bytes(block.0); + out.copy_from_slice(&self.state.to_le_bytes()); + } +} + +digest::newtype!( + /// Primitive XOR hasher for testing purposes + FixedHash(CoreWrapper); + delegate: + Debug AlgorithmName + Clone Default Reset + BlockSizeUser OutputSizeUser HashMarker + Update FixedOutput FixedOutputReset +); From f4d75591d6012599be895cf122db6410dbf593c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Mon, 7 Apr 2025 16:33:51 +0300 Subject: [PATCH 06/31] rename dummy to dummy fixed --- digest/tests/{dummy.rs => dummy_fixed.rs} | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) rename digest/tests/{dummy.rs => dummy_fixed.rs} (88%) diff --git a/digest/tests/dummy.rs b/digest/tests/dummy_fixed.rs similarity index 88% rename from digest/tests/dummy.rs rename to digest/tests/dummy_fixed.rs index 555d3cd16..d25450fd8 100644 --- a/digest/tests/dummy.rs +++ b/digest/tests/dummy_fixed.rs @@ -1,10 +1,11 @@ #![cfg(feature = "core-api")] use digest::{ - HashMarker, + HashMarker, Output, OutputSizeUser, Reset, consts::U8, - core_api::{Buffer, BufferKindUser, CoreWrapper, FixedOutputCore, UpdateCore}, - crypto_common::{Block, BlockSizeUser, Output, OutputSizeUser, Reset}, + core_api::{ + Block, BlockSizeUser, Buffer, BufferKindUser, CoreWrapper, FixedOutputCore, UpdateCore, + }, }; /// Core of primitive XOR hasher for testing purposes From eb0f2583c9ff7d00e8d5a2e290180dbef4ed50c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Tue, 8 Apr 2025 00:09:38 +0300 Subject: [PATCH 07/31] Add delegate template, improve macro robustness --- digest/src/core_api/wrapper.rs | 7 +++ digest/src/newtype.rs | 89 ++++++++++++++++++++++++---------- digest/tests/dummy_fixed.rs | 35 ++++++++++--- 3 files changed, 99 insertions(+), 32 deletions(-) diff --git a/digest/src/core_api/wrapper.rs b/digest/src/core_api/wrapper.rs index 6cd006fab..24d619ac1 100644 --- a/digest/src/core_api/wrapper.rs +++ b/digest/src/core_api/wrapper.rs @@ -145,6 +145,13 @@ impl ExtendableOutputReset for CoreWrapper { } } +impl AlgorithmName for CoreWrapper { + #[inline] + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + T::write_alg_name(f) + } +} + impl Drop for CoreWrapper { #[inline] fn drop(&mut self) { diff --git a/digest/src/newtype.rs b/digest/src/newtype.rs index 281736a60..4984a8a01 100644 --- a/digest/src/newtype.rs +++ b/digest/src/newtype.rs @@ -4,24 +4,42 @@ macro_rules! newtype { ( $(#[$attr:meta])* - $name:ident($wrapped_ty:ty); - delegate: $($trait_name:ident)* + $v:vis struct $name:ident($wrapped_ty:ty); + $(delegate_template: $template_name:ident)? + $(delegate: $($trait_name:ident)*)? ) => { $(#[$attr])* - pub struct $name($wrapped_ty); + $v struct $name($wrapped_ty); $( - $crate::newtype!(delegate_impl: $name($wrapped_ty) $trait_name); - )* + $crate::newtype!(template_impl: $template_name $name($wrapped_ty)); + )? - // Clone, Default, BlockSizeUser, CoreProxy, ExtendableOutput, FixedOutput, KeyInit, - // OutputSizeUser, Update, HashMarker, MacMarker + $( + $crate::newtype!(delegate_impls: $name($wrapped_ty) $($trait_name)*); + )? + }; - // Write + (template_impl: FixedOutputHash $name:ident($wrapped_ty:ty)) => { + $crate::newtype!( + delegate_impls: $name($wrapped_ty) + Debug Clone Default + AlgorithmName SerializableState + BlockSizeUser OutputSizeUser + HashMarker Reset Update + FixedOutput FixedOutputReset + ); + }; + + (delegate_impls: $name:ident($wrapped_ty:ty) $($trait_name:ident)*) => { + $( + $crate::newtype!(delegate_impl: $name($wrapped_ty) $trait_name); + )* }; (delegate_impl: $name:ident($wrapped_ty:ty) Debug) => { impl core::fmt::Debug for $name { + #[inline] fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.write_str(concat!(stringify!($name), " { ... }")) } @@ -30,8 +48,9 @@ macro_rules! newtype { (delegate_impl: $name:ident($wrapped_ty:ty) AlgorithmName) => { impl $crate::crypto_common::AlgorithmName for $name { + #[inline] fn write_alg_name(f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { - f.write_str(stringify!($name)) + <$wrapped_ty as $crate::crypto_common::AlgorithmName>::write_alg_name(f) } } }; @@ -40,7 +59,7 @@ macro_rules! newtype { impl Clone for $name { #[inline] fn clone(&self) -> Self { - Self(self.0.clone()) + Self(<$wrapped_ty as Clone>::clone(&self.0)) } } }; @@ -49,7 +68,7 @@ macro_rules! newtype { impl Default for $name { #[inline] fn default() -> Self { - Self(Default::default()) + Self(<$wrapped_ty as Default>::default()) } } }; @@ -58,7 +77,7 @@ macro_rules! newtype { impl $crate::InnerInit for $name { #[inline] fn new(inner: Self::Inner) -> Self { - self.0.new(inner) + Self(<$wrapped_ty as $crate::InnerInit>::new(inner)) } } }; @@ -67,7 +86,7 @@ macro_rules! newtype { impl $crate::KeyInit for $name { #[inline] fn new(key: &$crate::Key) -> Self { - self.0.new(key) + Self(<$wrapped_ty as $crate::KeyInit>::new(key)) } } }; @@ -76,16 +95,16 @@ macro_rules! newtype { impl $crate::CustomizedInit for $name { #[inline] fn new_customized(customization: &[u8]) -> Self { - $wrapped_ty::new_customized(customization) + <$wrapped_ty as $crate::CustomizedInit>::new_customized(customization) } } }; (delegate_impl: $name:ident($wrapped_ty:ty) Reset) => { - impl Reset for $name { + impl $crate::Reset for $name { #[inline] fn reset(&mut self) { - self.0.reset() + <$wrapped_ty as $crate::Reset>::reset(&mut self.0); } } }; @@ -124,7 +143,7 @@ macro_rules! newtype { impl $crate::Update for $name { #[inline] fn update(&mut self, data: &[u8]) { - self.0.update(data) + <$wrapped_ty as $crate::Update>::update(&mut self.0, data) } } }; @@ -139,7 +158,7 @@ macro_rules! newtype { impl $crate::FixedOutput for $name { #[inline] fn finalize_into(self, out: &mut $crate::Output) { - self.0.finalize_into(out); + <$wrapped_ty as $crate::FixedOutput>::finalize_into(self.0, out) } } }; @@ -148,7 +167,7 @@ macro_rules! newtype { impl $crate::FixedOutputReset for $name { #[inline] fn finalize_into_reset(&mut self, out: &mut Output) { - self.0.finalize_into_reset(out); + <$wrapped_ty as $crate::FixedOutputReset>::finalize_into_reset(&mut self.0, out); } } }; @@ -159,17 +178,17 @@ macro_rules! newtype { #[inline] fn new(output_size: usize) -> Result { - $wrapped_ty::new(output_size) + <$wrapped_ty as $crate::VariableOutput>::new(output_size) } #[inline] fn output_size(&self) -> usize { - self.0.output_size() + <$wrapped_ty as $crate::VariableOutput>::output_size(&self.0) } #[inline] fn finalize_variable(self, out: &mut [u8]) -> Result<(), $crate::InvalidBufferSize> { - self.0.finalize_variable(out) + <$wrapped_ty as $crate::VariableOutput>::finalize_variable(self.0, out) } } }; @@ -181,7 +200,7 @@ macro_rules! newtype { &mut self, out: &mut [u8], ) -> Result<(), $crate::InvalidBufferSize> { - self.0.finalize_variable_reset(out) + <$wrapped_ty as $crate::VariableOutputReset>::finalize_variable_reset(&mut self.0, out) } } }; @@ -191,16 +210,36 @@ macro_rules! newtype { // TODO: use a newtype wrapper? type Reader = <$wrapped_ty as $crate::ExtendableOutput>::Reader; + #[inline] fn finalize_xof(self) -> Self::Reader { - self.0.finalize_xof() + <$wrapped_ty as $crate::ExtendanbleOutput>::finalize_xof(self.0) } } }; (delegate_impl: $name:ident($wrapped_ty:ty) ExtendableOutputReset) => { impl $crate::ExtendableOutputReset for $name { + #[inline] fn finalize_xof_reset(&mut self) -> Self::Reader { - self.0.finalize_xof_reset() + <$wrapped_ty as $crate::ExtendableOutputReset>::finalize_xof_reset(&mut self.0) + } + } + }; + + (delegate_impl: $name:ident($wrapped_ty:ty) SerializableState) => { + impl $crate::crypto_common::hazmat::SerializableState for $name { + type SerializedStateSize = <$wrapped_ty as $crate::crypto_common::hazmat::SerializableState>::SerializedStateSize; + + #[inline] + fn serialize(&self) -> $crate::crypto_common::hazmat::SerializedState { + <$wrapped_ty as $crate::crypto_common::hazmat::SerializableState>::serialize(&self.0) + } + + #[inline] + fn deserialize( + serialized_state: &$crate::crypto_common::hazmat::SerializedState, + ) -> Result { + <$wrapped_ty as $crate::crypto_common::hazmat::SerializableState>::deserialize(serialized_state).map(Self) } } }; diff --git a/digest/tests/dummy_fixed.rs b/digest/tests/dummy_fixed.rs index d25450fd8..0b28dfde9 100644 --- a/digest/tests/dummy_fixed.rs +++ b/digest/tests/dummy_fixed.rs @@ -1,11 +1,14 @@ #![cfg(feature = "core-api")] +use core::fmt; use digest::{ HashMarker, Output, OutputSizeUser, Reset, consts::U8, core_api::{ - Block, BlockSizeUser, Buffer, BufferKindUser, CoreWrapper, FixedOutputCore, UpdateCore, + AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, CoreWrapper, FixedOutputCore, + UpdateCore, }, + crypto_common::hazmat::{DeserializeStateError, SerializableState, SerializedState}, }; /// Core of primitive XOR hasher for testing purposes @@ -14,6 +17,12 @@ pub struct FixedHashCore { state: u64, } +impl AlgorithmName for FixedHashCore { + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + f.write_str("FixedHash") + } +} + impl BlockSizeUser for FixedHashCore { type BlockSize = U8; } @@ -50,12 +59,24 @@ impl FixedOutputCore for FixedHashCore { } } +impl SerializableState for FixedHashCore { + type SerializedStateSize = U8; + + fn serialize(&self) -> SerializedState { + self.state.to_le_bytes().into() + } + + fn deserialize( + serialized_state: &SerializedState, + ) -> Result { + Ok(Self { + state: u64::from_le_bytes(serialized_state.0), + }) + } +} + digest::newtype!( /// Primitive XOR hasher for testing purposes - FixedHash(CoreWrapper); - delegate: - Debug AlgorithmName - Clone Default Reset - BlockSizeUser OutputSizeUser HashMarker - Update FixedOutput FixedOutputReset + pub struct FixedHash(CoreWrapper); + delegate_template: FixedOutputHash ); From 4f68309089a0b3e003ed75536e1946b13d4dbd80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Tue, 8 Apr 2025 02:24:38 +0300 Subject: [PATCH 08/31] Add OID helper --- digest/src/newtype.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/digest/src/newtype.rs b/digest/src/newtype.rs index 4984a8a01..483d3716a 100644 --- a/digest/src/newtype.rs +++ b/digest/src/newtype.rs @@ -7,6 +7,7 @@ macro_rules! newtype { $v:vis struct $name:ident($wrapped_ty:ty); $(delegate_template: $template_name:ident)? $(delegate: $($trait_name:ident)*)? + $(oid: $oid:literal)? ) => { $(#[$attr])* $v struct $name($wrapped_ty); @@ -18,6 +19,14 @@ macro_rules! newtype { $( $crate::newtype!(delegate_impls: $name($wrapped_ty) $($trait_name)*); )? + + $( + #[cfg(feature = "oid")] + impl $crate::const_oid::AssociatedOid for $name { + const OID: $crate::const_oid::ObjectIdentifier = + $crate::const_oid::ObjectIdentifier::new_unwrap($oid); + } + )? }; (template_impl: FixedOutputHash $name:ident($wrapped_ty:ty)) => { @@ -166,7 +175,7 @@ macro_rules! newtype { (delegate_impl: $name:ident($wrapped_ty:ty) FixedOutputReset) => { impl $crate::FixedOutputReset for $name { #[inline] - fn finalize_into_reset(&mut self, out: &mut Output) { + fn finalize_into_reset(&mut self, out: &mut $crate::Output) { <$wrapped_ty as $crate::FixedOutputReset>::finalize_into_reset(&mut self.0, out); } } From 3e5921287da7cec7e3bea3a4112720a6515562cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Thu, 10 Apr 2025 03:36:02 +0300 Subject: [PATCH 09/31] add ExtendableOutputHash template --- digest/src/newtype.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/digest/src/newtype.rs b/digest/src/newtype.rs index 483d3716a..03d0afc1e 100644 --- a/digest/src/newtype.rs +++ b/digest/src/newtype.rs @@ -40,6 +40,17 @@ macro_rules! newtype { ); }; + (template_impl: ExtendableOutputHash $name:ident($wrapped_ty:ty)) => { + $crate::newtype!( + delegate_impls: $name($wrapped_ty) + Debug Clone Default + AlgorithmName SerializableState + BlockSizeUser OutputSizeUser + HashMarker Reset Update + ExtendableOutput ExtendableOutputReset + ); + }; + (delegate_impls: $name:ident($wrapped_ty:ty) $($trait_name:ident)*) => { $( $crate::newtype!(delegate_impl: $name($wrapped_ty) $trait_name); @@ -221,7 +232,7 @@ macro_rules! newtype { #[inline] fn finalize_xof(self) -> Self::Reader { - <$wrapped_ty as $crate::ExtendanbleOutput>::finalize_xof(self.0) + <$wrapped_ty as $crate::ExtendableOutput>::finalize_xof(self.0) } } }; From dbcd0bd6f8995e0380f3e44113d76916e4861b3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Thu, 10 Apr 2025 06:42:32 +0300 Subject: [PATCH 10/31] fix CustomizedInit delegation --- digest/src/newtype.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/digest/src/newtype.rs b/digest/src/newtype.rs index 03d0afc1e..b50642628 100644 --- a/digest/src/newtype.rs +++ b/digest/src/newtype.rs @@ -45,7 +45,7 @@ macro_rules! newtype { delegate_impls: $name($wrapped_ty) Debug Clone Default AlgorithmName SerializableState - BlockSizeUser OutputSizeUser + BlockSizeUser HashMarker Reset Update ExtendableOutput ExtendableOutputReset ); @@ -115,7 +115,7 @@ macro_rules! newtype { impl $crate::CustomizedInit for $name { #[inline] fn new_customized(customization: &[u8]) -> Self { - <$wrapped_ty as $crate::CustomizedInit>::new_customized(customization) + Self(<$wrapped_ty as $crate::CustomizedInit>::new_customized(customization)) } } }; From c0725f1d6e250285fa5754b113753f891defafa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Sun, 4 May 2025 15:53:43 +0300 Subject: [PATCH 11/31] Introduce separate newtype macros --- digest/src/core_api/wrapper.rs | 12 +- digest/src/newtype.rs | 328 ++++++++++++++++++--------------- digest/tests/dummy_fixed.rs | 3 +- 3 files changed, 180 insertions(+), 163 deletions(-) diff --git a/digest/src/core_api/wrapper.rs b/digest/src/core_api/wrapper.rs index 24d619ac1..644fe1d27 100644 --- a/digest/src/core_api/wrapper.rs +++ b/digest/src/core_api/wrapper.rs @@ -217,20 +217,12 @@ where } } -/// A proxy trait to a core type implemented by [`CoreWrapper`] -// TODO: replace with an inherent associated type on stabilization: -// https://github.com/rust-lang/rust/issues/8995 -pub trait CoreProxy: sealed::Sealed { +/// A proxy trait to a core type. +pub trait CoreProxy { /// Type wrapped by [`CoreWrapper`]. type Core; } -mod sealed { - pub trait Sealed {} -} - -impl sealed::Sealed for CoreWrapper {} - impl CoreProxy for CoreWrapper { type Core = T; } diff --git a/digest/src/newtype.rs b/digest/src/newtype.rs index b50642628..737ef71a4 100644 --- a/digest/src/newtype.rs +++ b/digest/src/newtype.rs @@ -1,265 +1,291 @@ /// Creates a newtype wrapper around another type and /// delegates implementation of `digest` traits to it. #[macro_export] -macro_rules! newtype { +macro_rules! newtype_fixed_hash { ( $(#[$attr:meta])* $v:vis struct $name:ident($wrapped_ty:ty); - $(delegate_template: $template_name:ident)? - $(delegate: $($trait_name:ident)*)? $(oid: $oid:literal)? ) => { $(#[$attr])* - $v struct $name($wrapped_ty); - - $( - $crate::newtype!(template_impl: $template_name $name($wrapped_ty)); - )? - - $( - $crate::newtype!(delegate_impls: $name($wrapped_ty) $($trait_name)*); - )? - - $( - #[cfg(feature = "oid")] - impl $crate::const_oid::AssociatedOid for $name { - const OID: $crate::const_oid::ObjectIdentifier = - $crate::const_oid::ObjectIdentifier::new_unwrap($oid); - } - )? - }; - - (template_impl: FixedOutputHash $name:ident($wrapped_ty:ty)) => { - $crate::newtype!( - delegate_impls: $name($wrapped_ty) - Debug Clone Default - AlgorithmName SerializableState - BlockSizeUser OutputSizeUser - HashMarker Reset Update - FixedOutput FixedOutputReset - ); - }; - - (template_impl: ExtendableOutputHash $name:ident($wrapped_ty:ty)) => { - $crate::newtype!( - delegate_impls: $name($wrapped_ty) - Debug Clone Default - AlgorithmName SerializableState - BlockSizeUser - HashMarker Reset Update - ExtendableOutput ExtendableOutputReset - ); - }; - - (delegate_impls: $name:ident($wrapped_ty:ty) $($trait_name:ident)*) => { - $( - $crate::newtype!(delegate_impl: $name($wrapped_ty) $trait_name); - )* - }; + $v struct $name { + inner: $wrapped_ty + } - (delegate_impl: $name:ident($wrapped_ty:ty) Debug) => { impl core::fmt::Debug for $name { #[inline] fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.write_str(concat!(stringify!($name), " { ... }")) } } - }; - (delegate_impl: $name:ident($wrapped_ty:ty) AlgorithmName) => { impl $crate::crypto_common::AlgorithmName for $name { #[inline] fn write_alg_name(f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { <$wrapped_ty as $crate::crypto_common::AlgorithmName>::write_alg_name(f) } } - }; - (delegate_impl: $name:ident($wrapped_ty:ty) Clone) => { impl Clone for $name { #[inline] fn clone(&self) -> Self { - Self(<$wrapped_ty as Clone>::clone(&self.0)) + Self { + inner: <$wrapped_ty as Clone>::clone(&self.inner), + } } } - }; - (delegate_impl: $name:ident($wrapped_ty:ty) Default) => { impl Default for $name { #[inline] fn default() -> Self { - Self(<$wrapped_ty as Default>::default()) - } - } - }; - - (delegate_impl: $name:ident($wrapped_ty:ty) InnerInit) => { - impl $crate::InnerInit for $name { - #[inline] - fn new(inner: Self::Inner) -> Self { - Self(<$wrapped_ty as $crate::InnerInit>::new(inner)) - } - } - }; - - (delegate_impl: $name:ident($wrapped_ty:ty) KeyInit) => { - impl $crate::KeyInit for $name { - #[inline] - fn new(key: &$crate::Key) -> Self { - Self(<$wrapped_ty as $crate::KeyInit>::new(key)) + Self { + inner: <$wrapped_ty as Default>::default(), + } } } - }; - (delegate_impl: $name:ident($wrapped_ty:ty) CustomizedInit) => { - impl $crate::CustomizedInit for $name { - #[inline] - fn new_customized(customization: &[u8]) -> Self { - Self(<$wrapped_ty as $crate::CustomizedInit>::new_customized(customization)) - } - } - }; - - (delegate_impl: $name:ident($wrapped_ty:ty) Reset) => { impl $crate::Reset for $name { #[inline] fn reset(&mut self) { - <$wrapped_ty as $crate::Reset>::reset(&mut self.0); + <$wrapped_ty as $crate::Reset>::reset(&mut self.inner); } } - }; - (delegate_impl: $name:ident($wrapped_ty:ty) BlockSizeUser) => { impl $crate::core_api::BlockSizeUser for $name { type BlockSize = <$wrapped_ty as $crate::crypto_common::BlockSizeUser>::BlockSize; } - }; - (delegate_impl: $name:ident($wrapped_ty:ty) OutputSizeUser) => { impl $crate::OutputSizeUser for $name { type OutputSize = <$wrapped_ty as $crate::core_api::OutputSizeUser>::OutputSize; } - }; - - (delegate_impl: $name:ident($wrapped_ty:ty) KeySizeUser) => { - impl $crate::crypto_common::KeySizeUser for $name { - type KeySize = <$wrapped_ty as $crate::crypto_common::KeySizeUser>::KeySize; - } - }; - (delegate_impl: $name:ident($wrapped_ty:ty) HashMarker) => { impl $crate::HashMarker for $name {} - // TODO: assert that `$wrapped_ty` impls `HashMarker`? - }; - - (delegate_impl: $name:ident($wrapped_ty:ty) MacMarker) => { - impl $crate::MacMarker for $name {} - - // TODO: assert that `$wrapped_ty` impls `MacMarker`? - }; + impl $crate::core_api::CoreProxy for $name { + type Core = <$wrapped_ty as $crate::core_api::CoreProxy>::Core; + } - (delegate_impl: $name:ident($wrapped_ty:ty) Update) => { impl $crate::Update for $name { #[inline] fn update(&mut self, data: &[u8]) { - <$wrapped_ty as $crate::Update>::update(&mut self.0, data) + <$wrapped_ty as $crate::Update>::update(&mut self.inner, data) } } - }; - (delegate_impl: $name:ident($wrapped_ty:ty) CoreProxy) => { - impl $crate::core_api::CoreProxy for $name { - type Core = <$wrapped_ty as $crate::core_api::CoreProxy>::Core; - } - }; - - (delegate_impl: $name:ident($wrapped_ty:ty) FixedOutput) => { impl $crate::FixedOutput for $name { #[inline] fn finalize_into(self, out: &mut $crate::Output) { - <$wrapped_ty as $crate::FixedOutput>::finalize_into(self.0, out) + <$wrapped_ty as $crate::FixedOutput>::finalize_into(self.inner, out) } } - }; - (delegate_impl: $name:ident($wrapped_ty:ty) FixedOutputReset) => { impl $crate::FixedOutputReset for $name { #[inline] fn finalize_into_reset(&mut self, out: &mut $crate::Output) { - <$wrapped_ty as $crate::FixedOutputReset>::finalize_into_reset(&mut self.0, out); + <$wrapped_ty as $crate::FixedOutputReset>::finalize_into_reset(&mut self.inner, out); } } + + impl $crate::crypto_common::hazmat::SerializableState for $name { + type SerializedStateSize = <$wrapped_ty as $crate::crypto_common::hazmat::SerializableState>::SerializedStateSize; + + #[inline] + fn serialize(&self) -> $crate::crypto_common::hazmat::SerializedState { + <$wrapped_ty as $crate::crypto_common::hazmat::SerializableState>::serialize(&self.inner) + } + + #[inline] + fn deserialize( + serialized_state: &$crate::crypto_common::hazmat::SerializedState, + ) -> Result { + let inner = <$wrapped_ty as $crate::crypto_common::hazmat::SerializableState>::deserialize(serialized_state)?; + Ok(Self { inner }) + } + } + + $( + #[cfg(feature = "oid")] + impl $crate::const_oid::AssociatedOid for $name { + const OID: $crate::const_oid::ObjectIdentifier = + $crate::const_oid::ObjectIdentifier::new_unwrap($oid); + } + )? }; - (delegate_impl: $name:ident($wrapped_ty:ty) VariableOutput) => { - impl $crate::VariableOutput for $name { - const MAX_OUTPUT_SIZE: usize = <$wrapped_ty as $crate::VariableOutput>::MAX_OUTPUT_SIZE; + // (delegate_impl: $name:ident($wrapped_ty:ty) VariableOutput) => { + // impl $crate::VariableOutput for $name { + // const MAX_OUTPUT_SIZE: usize = <$wrapped_ty as $crate::VariableOutput>::MAX_OUTPUT_SIZE; + + // #[inline] + // fn new(output_size: usize) -> Result { + // <$wrapped_ty as $crate::VariableOutput>::new(output_size) + // } + + // #[inline] + // fn output_size(&self) -> usize { + // <$wrapped_ty as $crate::VariableOutput>::output_size(&self.0) + // } + + // #[inline] + // fn finalize_variable(self, out: &mut [u8]) -> Result<(), $crate::InvalidBufferSize> { + // <$wrapped_ty as $crate::VariableOutput>::finalize_variable(self.0, out) + // } + // } + // }; + + // (delegate_impl: $name:ident($wrapped_ty:ty) VariableOutputReset) => { + // impl $crate::VariableOutputReset for $name { + // #[inline] + // fn finalize_variable_reset( + // &mut self, + // out: &mut [u8], + // ) -> Result<(), $crate::InvalidBufferSize> { + // <$wrapped_ty as $crate::VariableOutputReset>::finalize_variable_reset(&mut self.0, out) + // } + // } + // }; +} + +/// Creates a newtype wrapper around another type and +/// delegates implementation of `digest` traits to it. +#[macro_export] +macro_rules! newtype_xof_hash { + ( + $(#[$attr:meta])* + $v:vis struct $name:ident($wrapped_ty:ty); + $(#[$reader_attr:meta])* + $reader_v:vis struct $reader_name:ident($wrapped_reader_ty:ty); + $(oid: $oid:literal)? + ) => { + $(#[$attr])* + $v struct $name { + inner: $wrapped_ty + } + + impl core::fmt::Debug for $name { + #[inline] + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str(concat!(stringify!($name), " { ... }")) + } + } + impl $crate::crypto_common::AlgorithmName for $name { #[inline] - fn new(output_size: usize) -> Result { - <$wrapped_ty as $crate::VariableOutput>::new(output_size) + fn write_alg_name(f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { + <$wrapped_ty as $crate::crypto_common::AlgorithmName>::write_alg_name(f) } + } + impl Clone for $name { #[inline] - fn output_size(&self) -> usize { - <$wrapped_ty as $crate::VariableOutput>::output_size(&self.0) + fn clone(&self) -> Self { + Self { + inner: <$wrapped_ty as Clone>::clone(&self.inner), + } } + } + impl Default for $name { #[inline] - fn finalize_variable(self, out: &mut [u8]) -> Result<(), $crate::InvalidBufferSize> { - <$wrapped_ty as $crate::VariableOutput>::finalize_variable(self.0, out) + fn default() -> Self { + Self { + inner: <$wrapped_ty as Default>::default(), + } } } - }; - (delegate_impl: $name:ident($wrapped_ty:ty) VariableOutputReset) => { - impl $crate::VariableOutputReset for $name { + impl $crate::Reset for $name { #[inline] - fn finalize_variable_reset( - &mut self, - out: &mut [u8], - ) -> Result<(), $crate::InvalidBufferSize> { - <$wrapped_ty as $crate::VariableOutputReset>::finalize_variable_reset(&mut self.0, out) + fn reset(&mut self) { + $crate::Reset::reset(&mut self.inner); + } + } + + impl $crate::core_api::BlockSizeUser for $name { + type BlockSize = <$wrapped_ty as $crate::crypto_common::BlockSizeUser>::BlockSize; + } + + impl $crate::HashMarker for $name {} + + impl $crate::core_api::CoreProxy for $name { + type Core = <$wrapped_ty as $crate::core_api::CoreProxy>::Core; + } + + impl $crate::Update for $name { + #[inline] + fn update(&mut self, data: &[u8]) { + <$wrapped_ty as $crate::Update>::update(&mut self.inner, data) } } - }; - (delegate_impl: $name:ident($wrapped_ty:ty) ExtendableOutput) => { impl $crate::ExtendableOutput for $name { - // TODO: use a newtype wrapper? - type Reader = <$wrapped_ty as $crate::ExtendableOutput>::Reader; + type Reader = $reader_name; #[inline] fn finalize_xof(self) -> Self::Reader { - <$wrapped_ty as $crate::ExtendableOutput>::finalize_xof(self.0) + let inner: $wrapped_reader_ty = <$wrapped_ty as $crate::ExtendableOutput>::finalize_xof(self.inner); + $reader_name { inner } } } - }; - (delegate_impl: $name:ident($wrapped_ty:ty) ExtendableOutputReset) => { impl $crate::ExtendableOutputReset for $name { #[inline] fn finalize_xof_reset(&mut self) -> Self::Reader { - <$wrapped_ty as $crate::ExtendableOutputReset>::finalize_xof_reset(&mut self.0) + let inner = <$wrapped_ty as $crate::ExtendableOutputReset>::finalize_xof_reset(&mut self.inner); + $reader_name { inner } } } - }; - (delegate_impl: $name:ident($wrapped_ty:ty) SerializableState) => { impl $crate::crypto_common::hazmat::SerializableState for $name { type SerializedStateSize = <$wrapped_ty as $crate::crypto_common::hazmat::SerializableState>::SerializedStateSize; #[inline] fn serialize(&self) -> $crate::crypto_common::hazmat::SerializedState { - <$wrapped_ty as $crate::crypto_common::hazmat::SerializableState>::serialize(&self.0) + $crate::crypto_common::hazmat::SerializableState::serialize(&self.inner) } #[inline] fn deserialize( serialized_state: &$crate::crypto_common::hazmat::SerializedState, ) -> Result { - <$wrapped_ty as $crate::crypto_common::hazmat::SerializableState>::deserialize(serialized_state).map(Self) + let inner = $crate::crypto_common::hazmat::SerializableState::deserialize(serialized_state)?; + Ok(Self { inner }) + } + } + + $( + #[cfg(feature = "oid")] + impl $crate::const_oid::AssociatedOid for $name { + const OID: $crate::const_oid::ObjectIdentifier = + $crate::const_oid::ObjectIdentifier::new_unwrap($oid); + } + )? + + $(#[$reader_attr])* + $reader_v struct $reader_name { + inner: $wrapped_reader_ty + } + + impl core::fmt::Debug for $reader_name { + #[inline] + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str(concat!(stringify!($reader_name), " { ... }")) + } + } + + impl Clone for $reader_name { + #[inline] + fn clone(&self) -> Self { + Self { + inner: Clone::clone(&self.inner), + } + } + } + + impl $crate::XofReader for $reader_name { + #[inline] + fn read(&mut self, buf: &mut [u8]) { + $crate::XofReader::read(&mut self.inner, buf) } } }; diff --git a/digest/tests/dummy_fixed.rs b/digest/tests/dummy_fixed.rs index 0b28dfde9..df327f5aa 100644 --- a/digest/tests/dummy_fixed.rs +++ b/digest/tests/dummy_fixed.rs @@ -75,8 +75,7 @@ impl SerializableState for FixedHashCore { } } -digest::newtype!( +digest::newtype_fixed_hash!( /// Primitive XOR hasher for testing purposes pub struct FixedHash(CoreWrapper); - delegate_template: FixedOutputHash ); From 24d0f6a9b1db824121902d3eef4f998ef2d63fc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Sun, 4 May 2025 18:32:59 +0300 Subject: [PATCH 12/31] add variable newtype and support generics in fixed newtype --- digest/src/newtype.rs | 295 +-------------------------------- digest/src/newtype/fixed.rs | 155 +++++++++++++++++ digest/src/newtype/variable.rs | 129 ++++++++++++++ digest/src/newtype/xof.rs | 144 ++++++++++++++++ 4 files changed, 431 insertions(+), 292 deletions(-) create mode 100644 digest/src/newtype/fixed.rs create mode 100644 digest/src/newtype/variable.rs create mode 100644 digest/src/newtype/xof.rs diff --git a/digest/src/newtype.rs b/digest/src/newtype.rs index 737ef71a4..b0412f4fe 100644 --- a/digest/src/newtype.rs +++ b/digest/src/newtype.rs @@ -1,292 +1,3 @@ -/// Creates a newtype wrapper around another type and -/// delegates implementation of `digest` traits to it. -#[macro_export] -macro_rules! newtype_fixed_hash { - ( - $(#[$attr:meta])* - $v:vis struct $name:ident($wrapped_ty:ty); - $(oid: $oid:literal)? - ) => { - $(#[$attr])* - $v struct $name { - inner: $wrapped_ty - } - - impl core::fmt::Debug for $name { - #[inline] - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.write_str(concat!(stringify!($name), " { ... }")) - } - } - - impl $crate::crypto_common::AlgorithmName for $name { - #[inline] - fn write_alg_name(f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { - <$wrapped_ty as $crate::crypto_common::AlgorithmName>::write_alg_name(f) - } - } - - impl Clone for $name { - #[inline] - fn clone(&self) -> Self { - Self { - inner: <$wrapped_ty as Clone>::clone(&self.inner), - } - } - } - - impl Default for $name { - #[inline] - fn default() -> Self { - Self { - inner: <$wrapped_ty as Default>::default(), - } - } - } - - impl $crate::Reset for $name { - #[inline] - fn reset(&mut self) { - <$wrapped_ty as $crate::Reset>::reset(&mut self.inner); - } - } - - impl $crate::core_api::BlockSizeUser for $name { - type BlockSize = <$wrapped_ty as $crate::crypto_common::BlockSizeUser>::BlockSize; - } - - impl $crate::OutputSizeUser for $name { - type OutputSize = <$wrapped_ty as $crate::core_api::OutputSizeUser>::OutputSize; - } - - impl $crate::HashMarker for $name {} - - impl $crate::core_api::CoreProxy for $name { - type Core = <$wrapped_ty as $crate::core_api::CoreProxy>::Core; - } - - impl $crate::Update for $name { - #[inline] - fn update(&mut self, data: &[u8]) { - <$wrapped_ty as $crate::Update>::update(&mut self.inner, data) - } - } - - impl $crate::FixedOutput for $name { - #[inline] - fn finalize_into(self, out: &mut $crate::Output) { - <$wrapped_ty as $crate::FixedOutput>::finalize_into(self.inner, out) - } - } - - impl $crate::FixedOutputReset for $name { - #[inline] - fn finalize_into_reset(&mut self, out: &mut $crate::Output) { - <$wrapped_ty as $crate::FixedOutputReset>::finalize_into_reset(&mut self.inner, out); - } - } - - impl $crate::crypto_common::hazmat::SerializableState for $name { - type SerializedStateSize = <$wrapped_ty as $crate::crypto_common::hazmat::SerializableState>::SerializedStateSize; - - #[inline] - fn serialize(&self) -> $crate::crypto_common::hazmat::SerializedState { - <$wrapped_ty as $crate::crypto_common::hazmat::SerializableState>::serialize(&self.inner) - } - - #[inline] - fn deserialize( - serialized_state: &$crate::crypto_common::hazmat::SerializedState, - ) -> Result { - let inner = <$wrapped_ty as $crate::crypto_common::hazmat::SerializableState>::deserialize(serialized_state)?; - Ok(Self { inner }) - } - } - - $( - #[cfg(feature = "oid")] - impl $crate::const_oid::AssociatedOid for $name { - const OID: $crate::const_oid::ObjectIdentifier = - $crate::const_oid::ObjectIdentifier::new_unwrap($oid); - } - )? - }; - - // (delegate_impl: $name:ident($wrapped_ty:ty) VariableOutput) => { - // impl $crate::VariableOutput for $name { - // const MAX_OUTPUT_SIZE: usize = <$wrapped_ty as $crate::VariableOutput>::MAX_OUTPUT_SIZE; - - // #[inline] - // fn new(output_size: usize) -> Result { - // <$wrapped_ty as $crate::VariableOutput>::new(output_size) - // } - - // #[inline] - // fn output_size(&self) -> usize { - // <$wrapped_ty as $crate::VariableOutput>::output_size(&self.0) - // } - - // #[inline] - // fn finalize_variable(self, out: &mut [u8]) -> Result<(), $crate::InvalidBufferSize> { - // <$wrapped_ty as $crate::VariableOutput>::finalize_variable(self.0, out) - // } - // } - // }; - - // (delegate_impl: $name:ident($wrapped_ty:ty) VariableOutputReset) => { - // impl $crate::VariableOutputReset for $name { - // #[inline] - // fn finalize_variable_reset( - // &mut self, - // out: &mut [u8], - // ) -> Result<(), $crate::InvalidBufferSize> { - // <$wrapped_ty as $crate::VariableOutputReset>::finalize_variable_reset(&mut self.0, out) - // } - // } - // }; -} - -/// Creates a newtype wrapper around another type and -/// delegates implementation of `digest` traits to it. -#[macro_export] -macro_rules! newtype_xof_hash { - ( - $(#[$attr:meta])* - $v:vis struct $name:ident($wrapped_ty:ty); - $(#[$reader_attr:meta])* - $reader_v:vis struct $reader_name:ident($wrapped_reader_ty:ty); - $(oid: $oid:literal)? - ) => { - $(#[$attr])* - $v struct $name { - inner: $wrapped_ty - } - - impl core::fmt::Debug for $name { - #[inline] - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.write_str(concat!(stringify!($name), " { ... }")) - } - } - - impl $crate::crypto_common::AlgorithmName for $name { - #[inline] - fn write_alg_name(f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { - <$wrapped_ty as $crate::crypto_common::AlgorithmName>::write_alg_name(f) - } - } - - impl Clone for $name { - #[inline] - fn clone(&self) -> Self { - Self { - inner: <$wrapped_ty as Clone>::clone(&self.inner), - } - } - } - - impl Default for $name { - #[inline] - fn default() -> Self { - Self { - inner: <$wrapped_ty as Default>::default(), - } - } - } - - impl $crate::Reset for $name { - #[inline] - fn reset(&mut self) { - $crate::Reset::reset(&mut self.inner); - } - } - - impl $crate::core_api::BlockSizeUser for $name { - type BlockSize = <$wrapped_ty as $crate::crypto_common::BlockSizeUser>::BlockSize; - } - - impl $crate::HashMarker for $name {} - - impl $crate::core_api::CoreProxy for $name { - type Core = <$wrapped_ty as $crate::core_api::CoreProxy>::Core; - } - - impl $crate::Update for $name { - #[inline] - fn update(&mut self, data: &[u8]) { - <$wrapped_ty as $crate::Update>::update(&mut self.inner, data) - } - } - - impl $crate::ExtendableOutput for $name { - type Reader = $reader_name; - - #[inline] - fn finalize_xof(self) -> Self::Reader { - let inner: $wrapped_reader_ty = <$wrapped_ty as $crate::ExtendableOutput>::finalize_xof(self.inner); - $reader_name { inner } - } - } - - impl $crate::ExtendableOutputReset for $name { - #[inline] - fn finalize_xof_reset(&mut self) -> Self::Reader { - let inner = <$wrapped_ty as $crate::ExtendableOutputReset>::finalize_xof_reset(&mut self.inner); - $reader_name { inner } - } - } - - impl $crate::crypto_common::hazmat::SerializableState for $name { - type SerializedStateSize = <$wrapped_ty as $crate::crypto_common::hazmat::SerializableState>::SerializedStateSize; - - #[inline] - fn serialize(&self) -> $crate::crypto_common::hazmat::SerializedState { - $crate::crypto_common::hazmat::SerializableState::serialize(&self.inner) - } - - #[inline] - fn deserialize( - serialized_state: &$crate::crypto_common::hazmat::SerializedState, - ) -> Result { - let inner = $crate::crypto_common::hazmat::SerializableState::deserialize(serialized_state)?; - Ok(Self { inner }) - } - } - - $( - #[cfg(feature = "oid")] - impl $crate::const_oid::AssociatedOid for $name { - const OID: $crate::const_oid::ObjectIdentifier = - $crate::const_oid::ObjectIdentifier::new_unwrap($oid); - } - )? - - $(#[$reader_attr])* - $reader_v struct $reader_name { - inner: $wrapped_reader_ty - } - - impl core::fmt::Debug for $reader_name { - #[inline] - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.write_str(concat!(stringify!($reader_name), " { ... }")) - } - } - - impl Clone for $reader_name { - #[inline] - fn clone(&self) -> Self { - Self { - inner: Clone::clone(&self.inner), - } - } - } - - impl $crate::XofReader for $reader_name { - #[inline] - fn read(&mut self, buf: &mut [u8]) { - $crate::XofReader::read(&mut self.inner, buf) - } - } - }; -} +mod fixed; +mod variable; +mod xof; diff --git a/digest/src/newtype/fixed.rs b/digest/src/newtype/fixed.rs new file mode 100644 index 000000000..0f1b13d64 --- /dev/null +++ b/digest/src/newtype/fixed.rs @@ -0,0 +1,155 @@ +/// Creates a newtype wrapper around another type and +/// delegates implementation of `digest` traits to it. +#[macro_export] +macro_rules! newtype_fixed_hash { + ( + $(#[$attr:meta])* + $v:vis struct $name:ident$(<$gp:ident: $bound:ident>)?($wrapped_ty:ty); + ) => { + $(#[$attr])* + $v struct $name$(<$gp: $bound>)? { + inner: $wrapped_ty + } + + impl$(<$gp: $bound>)? core::fmt::Debug for $name$(<$gp>)? { + #[inline] + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str(concat!(stringify!($name), " { ... }")) + } + } + + impl$(<$gp: $bound>)? $crate::crypto_common::AlgorithmName for $name$(<$gp>)? { + #[inline] + fn write_alg_name(f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { + <$wrapped_ty as $crate::crypto_common::AlgorithmName>::write_alg_name(f) + } + } + + impl$(<$gp: $bound>)? Clone for $name$(<$gp>)? { + #[inline] + fn clone(&self) -> Self { + Self { + inner: <$wrapped_ty as Clone>::clone(&self.inner), + } + } + } + + impl$(<$gp: $bound>)? Default for $name$(<$gp>)? { + #[inline] + fn default() -> Self { + Self { + inner: <$wrapped_ty as Default>::default(), + } + } + } + + impl$(<$gp: $bound>)? $crate::Reset for $name$(<$gp>)? { + #[inline] + fn reset(&mut self) { + <$wrapped_ty as $crate::Reset>::reset(&mut self.inner); + } + } + + impl$(<$gp: $bound>)? $crate::core_api::BlockSizeUser for $name$(<$gp>)? { + type BlockSize = <$wrapped_ty as $crate::crypto_common::BlockSizeUser>::BlockSize; + } + + impl$(<$gp: $bound>)? $crate::OutputSizeUser for $name$(<$gp>)? { + type OutputSize = <$wrapped_ty as $crate::core_api::OutputSizeUser>::OutputSize; + } + + impl$(<$gp: $bound>)? $crate::HashMarker for $name$(<$gp>)? {} + + impl$(<$gp: $bound>)? $crate::core_api::CoreProxy for $name$(<$gp>)? { + type Core = <$wrapped_ty as $crate::core_api::CoreProxy>::Core; + } + + impl$(<$gp: $bound>)? $crate::Update for $name$(<$gp>)? { + #[inline] + fn update(&mut self, data: &[u8]) { + <$wrapped_ty as $crate::Update>::update(&mut self.inner, data) + } + } + + impl$(<$gp: $bound>)? $crate::FixedOutput for $name$(<$gp>)? { + #[inline] + fn finalize_into(self, out: &mut $crate::Output) { + <$wrapped_ty as $crate::FixedOutput>::finalize_into(self.inner, out) + } + } + + impl$(<$gp: $bound>)? $crate::FixedOutputReset for $name$(<$gp>)? { + #[inline] + fn finalize_into_reset(&mut self, out: &mut $crate::Output) { + <$wrapped_ty as $crate::FixedOutputReset>::finalize_into_reset(&mut self.inner, out); + } + } + + impl$(<$gp: $bound>)? $crate::crypto_common::hazmat::SerializableState for $name$(<$gp>)? { + type SerializedStateSize = <$wrapped_ty as $crate::crypto_common::hazmat::SerializableState>::SerializedStateSize; + + #[inline] + fn serialize(&self) -> $crate::crypto_common::hazmat::SerializedState { + <$wrapped_ty as $crate::crypto_common::hazmat::SerializableState>::serialize(&self.inner) + } + + #[inline] + fn deserialize( + serialized_state: &$crate::crypto_common::hazmat::SerializedState, + ) -> Result { + let inner = <$wrapped_ty as $crate::crypto_common::hazmat::SerializableState>::deserialize(serialized_state)?; + Ok(Self { inner }) + } + } + }; + + ( + $(#[$attr:meta])* + $v:vis struct $name:ident$(<$gp:ident: $bound:ident>)?($wrapped_ty:ty); + oid: $oid:literal + ) => { + $crate::newtype_fixed_hash!( + $(#[$attr])* + $v struct $name$(<$gp: $bound>)?($wrapped_ty); + ); + + #[cfg(feature = "oid")] + impl$(<$gp: $bound>)? $crate::const_oid::AssociatedOid for $name$(<$gp>)? { + const OID: $crate::const_oid::ObjectIdentifier = + $crate::const_oid::ObjectIdentifier::new_unwrap($oid); + } + }; + + // (delegate_impl: $name:ident($wrapped_ty:ty) VariableOutput) => { + // impl $crate::VariableOutput for $name { + // const MAX_OUTPUT_SIZE: usize = <$wrapped_ty as $crate::VariableOutput>::MAX_OUTPUT_SIZE; + + // #[inline] + // fn new(output_size: usize) -> Result { + // <$wrapped_ty as $crate::VariableOutput>::new(output_size) + // } + + // #[inline] + // fn output_size(&self) -> usize { + // <$wrapped_ty as $crate::VariableOutput>::output_size(&self.0) + // } + + // #[inline] + // fn finalize_variable(self, out: &mut [u8]) -> Result<(), $crate::InvalidBufferSize> { + // <$wrapped_ty as $crate::VariableOutput>::finalize_variable(self.0, out) + // } + // } + // }; + + // (delegate_impl: $name:ident($wrapped_ty:ty) VariableOutputReset) => { + // impl $crate::VariableOutputReset for $name { + // #[inline] + // fn finalize_variable_reset( + // &mut self, + // out: &mut [u8], + // ) -> Result<(), $crate::InvalidBufferSize> { + // <$wrapped_ty as $crate::VariableOutputReset>::finalize_variable_reset(&mut self.0, out) + // } + // } + // }; +} diff --git a/digest/src/newtype/variable.rs b/digest/src/newtype/variable.rs new file mode 100644 index 000000000..463f3aa8f --- /dev/null +++ b/digest/src/newtype/variable.rs @@ -0,0 +1,129 @@ +/// Creates a newtype wrapper around another type and +/// delegates implementation of `digest` traits to it. +#[macro_export] +macro_rules! newtype_variable_hash { + ( + $(#[$attr:meta])* + $v:vis struct $name:ident($wrapped_ty:ty); + $(oid: $oid:literal)? + ) => { + $(#[$attr])* + $v struct $name { + inner: $wrapped_ty + } + + impl core::fmt::Debug for $name { + #[inline] + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str(concat!(stringify!($name), " { ... }")) + } + } + + impl $crate::crypto_common::AlgorithmName for $name { + #[inline] + fn write_alg_name(f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { + <$wrapped_ty as $crate::crypto_common::AlgorithmName>::write_alg_name(f) + } + } + + impl Clone for $name { + #[inline] + fn clone(&self) -> Self { + Self { + inner: <$wrapped_ty as Clone>::clone(&self.inner), + } + } + } + + impl Default for $name { + #[inline] + fn default() -> Self { + Self { + inner: <$wrapped_ty as Default>::default(), + } + } + } + + impl $crate::Reset for $name { + #[inline] + fn reset(&mut self) { + <$wrapped_ty as $crate::Reset>::reset(&mut self.inner); + } + } + + impl $crate::core_api::BlockSizeUser for $name { + type BlockSize = <$wrapped_ty as $crate::crypto_common::BlockSizeUser>::BlockSize; + } + + impl $crate::OutputSizeUser for $name { + type OutputSize = <$wrapped_ty as $crate::core_api::OutputSizeUser>::OutputSize; + } + + impl $crate::HashMarker for $name {} + + impl $crate::core_api::CoreProxy for $name { + type Core = <$wrapped_ty as $crate::core_api::CoreProxy>::Core; + } + + impl $crate::Update for $name { + #[inline] + fn update(&mut self, data: &[u8]) { + <$wrapped_ty as $crate::Update>::update(&mut self.inner, data) + } + } + + impl $crate::VariableOutput for $name { + const MAX_OUTPUT_SIZE: usize = <$wrapped_ty as $crate::VariableOutput>::MAX_OUTPUT_SIZE; + + #[inline] + fn new(output_size: usize) -> Result { + <$wrapped_ty as $crate::VariableOutput>::new(output_size) + } + + #[inline] + fn output_size(&self) -> usize { + <$wrapped_ty as $crate::VariableOutput>::output_size(&self.0) + } + + #[inline] + fn finalize_variable(self, out: &mut [u8]) -> Result<(), $crate::InvalidBufferSize> { + <$wrapped_ty as $crate::VariableOutput>::finalize_variable(self.0, out) + } + } + + impl $crate::VariableOutputReset for $name { + #[inline] + fn finalize_variable_reset( + &mut self, + out: &mut [u8], + ) -> Result<(), $crate::InvalidBufferSize> { + <$wrapped_ty as $crate::VariableOutputReset>::finalize_variable_reset(&mut self.0, out) + } + } + + impl $crate::crypto_common::hazmat::SerializableState for $name { + type SerializedStateSize = <$wrapped_ty as $crate::crypto_common::hazmat::SerializableState>::SerializedStateSize; + + #[inline] + fn serialize(&self) -> $crate::crypto_common::hazmat::SerializedState { + <$wrapped_ty as $crate::crypto_common::hazmat::SerializableState>::serialize(&self.inner) + } + + #[inline] + fn deserialize( + serialized_state: &$crate::crypto_common::hazmat::SerializedState, + ) -> Result { + let inner = <$wrapped_ty as $crate::crypto_common::hazmat::SerializableState>::deserialize(serialized_state)?; + Ok(Self { inner }) + } + } + + $( + #[cfg(feature = "oid")] + impl $crate::const_oid::AssociatedOid for $name { + const OID: $crate::const_oid::ObjectIdentifier = + $crate::const_oid::ObjectIdentifier::new_unwrap($oid); + } + )? + }; +} diff --git a/digest/src/newtype/xof.rs b/digest/src/newtype/xof.rs new file mode 100644 index 000000000..1c42a9c93 --- /dev/null +++ b/digest/src/newtype/xof.rs @@ -0,0 +1,144 @@ +/// Creates a newtype wrapper around another type and +/// delegates implementation of `digest` traits to it. +#[macro_export] +macro_rules! newtype_xof_hash { + ( + $(#[$attr:meta])* + $v:vis struct $name:ident($wrapped_ty:ty); + $(#[$reader_attr:meta])* + $reader_v:vis struct $reader_name:ident($wrapped_reader_ty:ty); + $(oid: $oid:literal)? + ) => { + $(#[$attr])* + $v struct $name { + inner: $wrapped_ty + } + + impl core::fmt::Debug for $name { + #[inline] + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str(concat!(stringify!($name), " { ... }")) + } + } + + impl $crate::crypto_common::AlgorithmName for $name { + #[inline] + fn write_alg_name(f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { + <$wrapped_ty as $crate::crypto_common::AlgorithmName>::write_alg_name(f) + } + } + + impl Clone for $name { + #[inline] + fn clone(&self) -> Self { + Self { + inner: <$wrapped_ty as Clone>::clone(&self.inner), + } + } + } + + impl Default for $name { + #[inline] + fn default() -> Self { + Self { + inner: <$wrapped_ty as Default>::default(), + } + } + } + + impl $crate::Reset for $name { + #[inline] + fn reset(&mut self) { + $crate::Reset::reset(&mut self.inner); + } + } + + impl $crate::core_api::BlockSizeUser for $name { + type BlockSize = <$wrapped_ty as $crate::crypto_common::BlockSizeUser>::BlockSize; + } + + impl $crate::HashMarker for $name {} + + impl $crate::core_api::CoreProxy for $name { + type Core = <$wrapped_ty as $crate::core_api::CoreProxy>::Core; + } + + impl $crate::Update for $name { + #[inline] + fn update(&mut self, data: &[u8]) { + <$wrapped_ty as $crate::Update>::update(&mut self.inner, data) + } + } + + impl $crate::ExtendableOutput for $name { + type Reader = $reader_name; + + #[inline] + fn finalize_xof(self) -> Self::Reader { + let inner: $wrapped_reader_ty = <$wrapped_ty as $crate::ExtendableOutput>::finalize_xof(self.inner); + $reader_name { inner } + } + } + + impl $crate::ExtendableOutputReset for $name { + #[inline] + fn finalize_xof_reset(&mut self) -> Self::Reader { + let inner = <$wrapped_ty as $crate::ExtendableOutputReset>::finalize_xof_reset(&mut self.inner); + $reader_name { inner } + } + } + + impl $crate::crypto_common::hazmat::SerializableState for $name { + type SerializedStateSize = <$wrapped_ty as $crate::crypto_common::hazmat::SerializableState>::SerializedStateSize; + + #[inline] + fn serialize(&self) -> $crate::crypto_common::hazmat::SerializedState { + $crate::crypto_common::hazmat::SerializableState::serialize(&self.inner) + } + + #[inline] + fn deserialize( + serialized_state: &$crate::crypto_common::hazmat::SerializedState, + ) -> Result { + let inner = $crate::crypto_common::hazmat::SerializableState::deserialize(serialized_state)?; + Ok(Self { inner }) + } + } + + $( + #[cfg(feature = "oid")] + impl $crate::const_oid::AssociatedOid for $name { + const OID: $crate::const_oid::ObjectIdentifier = + $crate::const_oid::ObjectIdentifier::new_unwrap($oid); + } + )? + + $(#[$reader_attr])* + $reader_v struct $reader_name { + inner: $wrapped_reader_ty + } + + impl core::fmt::Debug for $reader_name { + #[inline] + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str(concat!(stringify!($reader_name), " { ... }")) + } + } + + impl Clone for $reader_name { + #[inline] + fn clone(&self) -> Self { + Self { + inner: Clone::clone(&self.inner), + } + } + } + + impl $crate::XofReader for $reader_name { + #[inline] + fn read(&mut self, buf: &mut [u8]) { + $crate::XofReader::read(&mut self.inner, buf) + } + } + }; +} From 185b4755157ae2cc2264999443748c5c04da17c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Sun, 4 May 2025 18:36:00 +0300 Subject: [PATCH 13/31] remove old code --- digest/src/newtype/fixed.rs | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/digest/src/newtype/fixed.rs b/digest/src/newtype/fixed.rs index 0f1b13d64..a603bf7ea 100644 --- a/digest/src/newtype/fixed.rs +++ b/digest/src/newtype/fixed.rs @@ -119,37 +119,4 @@ macro_rules! newtype_fixed_hash { $crate::const_oid::ObjectIdentifier::new_unwrap($oid); } }; - - // (delegate_impl: $name:ident($wrapped_ty:ty) VariableOutput) => { - // impl $crate::VariableOutput for $name { - // const MAX_OUTPUT_SIZE: usize = <$wrapped_ty as $crate::VariableOutput>::MAX_OUTPUT_SIZE; - - // #[inline] - // fn new(output_size: usize) -> Result { - // <$wrapped_ty as $crate::VariableOutput>::new(output_size) - // } - - // #[inline] - // fn output_size(&self) -> usize { - // <$wrapped_ty as $crate::VariableOutput>::output_size(&self.0) - // } - - // #[inline] - // fn finalize_variable(self, out: &mut [u8]) -> Result<(), $crate::InvalidBufferSize> { - // <$wrapped_ty as $crate::VariableOutput>::finalize_variable(self.0, out) - // } - // } - // }; - - // (delegate_impl: $name:ident($wrapped_ty:ty) VariableOutputReset) => { - // impl $crate::VariableOutputReset for $name { - // #[inline] - // fn finalize_variable_reset( - // &mut self, - // out: &mut [u8], - // ) -> Result<(), $crate::InvalidBufferSize> { - // <$wrapped_ty as $crate::VariableOutputReset>::finalize_variable_reset(&mut self.0, out) - // } - // } - // }; } From 19b2e43c90339658c6c8b66b9bc2b3fe188d104a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Sun, 4 May 2025 20:22:46 +0300 Subject: [PATCH 14/31] update newtype_variable_hash --- digest/src/core_api/rt_variable.rs | 15 +- digest/src/newtype/variable.rs | 241 ++++++++++++++++++++++------- 2 files changed, 197 insertions(+), 59 deletions(-) diff --git a/digest/src/core_api/rt_variable.rs b/digest/src/core_api/rt_variable.rs index 6b69f09d9..c880ccaa0 100644 --- a/digest/src/core_api/rt_variable.rs +++ b/digest/src/core_api/rt_variable.rs @@ -18,8 +18,7 @@ use crypto_common::{ #[cfg(feature = "zeroize")] use zeroize::ZeroizeOnDrop; -/// Wrapper around [`VariableOutputCore`] which selects output size -/// at run time. +/// Wrapper around [`VariableOutputCore`] which selects output size at run time. #[derive(Clone)] pub struct RtVariableCoreWrapper { core: T, @@ -64,11 +63,19 @@ impl BlockSizeUser for RtVariableCoreWrapper { type BlockSize = T::BlockSize; } -impl Reset for RtVariableCoreWrapper { +// TODO: remove because the hasher may be customized? +impl Reset for RtVariableCoreWrapper { #[inline] fn reset(&mut self) { self.buffer.reset(); - self.core.reset(); + self.core = T::new(self.output_size as usize).unwrap(); + } +} + +impl AlgorithmName for RtVariableCoreWrapper { + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { + T::write_alg_name(f)?; + f.write_str("Var") } } diff --git a/digest/src/newtype/variable.rs b/digest/src/newtype/variable.rs index 463f3aa8f..5d720a119 100644 --- a/digest/src/newtype/variable.rs +++ b/digest/src/newtype/variable.rs @@ -3,127 +3,258 @@ #[macro_export] macro_rules! newtype_variable_hash { ( - $(#[$attr:meta])* - $v:vis struct $name:ident($wrapped_ty:ty); - $(oid: $oid:literal)? + $(#[$ct_attr:meta])* + $ct_vis:vis struct $ct_name:ident<$out_size:ident>($wrapped_ct:ty); + $(#[$rt_attr:meta])* + $rt_vis:vis struct $rt_name:ident($wrapped_rt:ty); + // Ideally, we would use `$core_ty::OutputSize`, but unfortunately the compiler + // does not accept such code. The likely reason is this issue: + // https://github.com/rust-lang/rust/issues/79629 + max_size: $max_size:ty; ) => { - $(#[$attr])* - $v struct $name { - inner: $wrapped_ty + $(#[$ct_attr])* + $ct_vis struct $ct_name<$out_size> + where + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, + $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, + { + inner: $wrapped_ct, } - impl core::fmt::Debug for $name { + impl<$out_size> core::fmt::Debug for $ct_name<$out_size> + where + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, + $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, + { #[inline] fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.write_str(concat!(stringify!($name), " { ... }")) + f.write_str(concat!(stringify!($ct_name), " { ... }")) } } - impl $crate::crypto_common::AlgorithmName for $name { + impl<$out_size> $crate::crypto_common::AlgorithmName for $ct_name<$out_size> + where + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, + $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, + { #[inline] fn write_alg_name(f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { - <$wrapped_ty as $crate::crypto_common::AlgorithmName>::write_alg_name(f) + <$wrapped_ct as $crate::crypto_common::AlgorithmName>::write_alg_name(f) } } - impl Clone for $name { + impl<$out_size> Clone for $ct_name<$out_size> + where + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, + $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, + { #[inline] fn clone(&self) -> Self { - Self { - inner: <$wrapped_ty as Clone>::clone(&self.inner), - } + let inner = <$wrapped_ct as Clone>::clone(&self.inner); + Self { inner } } } - impl Default for $name { + impl<$out_size> Default for $ct_name<$out_size> + where + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, + $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, + { #[inline] fn default() -> Self { - Self { - inner: <$wrapped_ty as Default>::default(), - } + let inner = <$wrapped_ct as Default>::default(); + Self { inner } } } - impl $crate::Reset for $name { + impl<$out_size> $crate::Reset for $ct_name<$out_size> + where + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, + $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, + { #[inline] fn reset(&mut self) { - <$wrapped_ty as $crate::Reset>::reset(&mut self.inner); + <$wrapped_ct as $crate::Reset>::reset(&mut self.inner); } } - impl $crate::core_api::BlockSizeUser for $name { - type BlockSize = <$wrapped_ty as $crate::crypto_common::BlockSizeUser>::BlockSize; + impl<$out_size> $crate::core_api::BlockSizeUser for $ct_name<$out_size> + where + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, + $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, + { + type BlockSize = <$wrapped_ct as $crate::crypto_common::BlockSizeUser>::BlockSize; } - impl $crate::OutputSizeUser for $name { - type OutputSize = <$wrapped_ty as $crate::core_api::OutputSizeUser>::OutputSize; + impl<$out_size> $crate::OutputSizeUser for $ct_name<$out_size> + where + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, + $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, + { + type OutputSize = <$wrapped_ct as $crate::crypto_common::OutputSizeUser>::OutputSize; } - impl $crate::HashMarker for $name {} + impl<$out_size> $crate::HashMarker for $ct_name<$out_size> + where + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, + $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, + {} - impl $crate::core_api::CoreProxy for $name { - type Core = <$wrapped_ty as $crate::core_api::CoreProxy>::Core; + impl<$out_size> $crate::core_api::CoreProxy for $ct_name<$out_size> + where + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, + $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, + { + type Core = <$wrapped_ct as $crate::core_api::CoreProxy>::Core; } - impl $crate::Update for $name { + impl<$out_size> $crate::Update for $ct_name<$out_size> + where + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, + $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, + { #[inline] fn update(&mut self, data: &[u8]) { - <$wrapped_ty as $crate::Update>::update(&mut self.inner, data) + <$wrapped_ct as $crate::Update>::update(&mut self.inner, data) } } - impl $crate::VariableOutput for $name { - const MAX_OUTPUT_SIZE: usize = <$wrapped_ty as $crate::VariableOutput>::MAX_OUTPUT_SIZE; + impl<$out_size> $crate::FixedOutput for $ct_name<$out_size> + where + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, + $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, + { + #[inline] + fn finalize_into(self, out: &mut $crate::Output) { + <$wrapped_ct as $crate::FixedOutput>::finalize_into(self.inner, out) + } + } + impl<$out_size> $crate::FixedOutputReset for $ct_name<$out_size> + where + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, + $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, + { #[inline] - fn new(output_size: usize) -> Result { - <$wrapped_ty as $crate::VariableOutput>::new(output_size) + fn finalize_into_reset(&mut self, out: &mut $crate::Output) { + <$wrapped_ct as $crate::FixedOutputReset>::finalize_into_reset(&mut self.inner, out); } + } + + impl<$out_size> $crate::crypto_common::hazmat::SerializableState for $ct_name<$out_size> + where + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, + $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, + { + type SerializedStateSize = <$wrapped_ct as $crate::crypto_common::hazmat::SerializableState>::SerializedStateSize; #[inline] - fn output_size(&self) -> usize { - <$wrapped_ty as $crate::VariableOutput>::output_size(&self.0) + fn serialize(&self) -> $crate::crypto_common::hazmat::SerializedState { + <$wrapped_ct as $crate::crypto_common::hazmat::SerializableState>::serialize(&self.inner) } #[inline] - fn finalize_variable(self, out: &mut [u8]) -> Result<(), $crate::InvalidBufferSize> { - <$wrapped_ty as $crate::VariableOutput>::finalize_variable(self.0, out) + fn deserialize( + serialized_state: &$crate::crypto_common::hazmat::SerializedState, + ) -> Result { + let inner = <$wrapped_ct as $crate::crypto_common::hazmat::SerializableState>::deserialize(serialized_state)?; + Ok(Self { inner }) + } + } + + $(#[$rt_attr])* + $rt_vis struct $rt_name { + inner: $wrapped_rt, + } + + impl core::fmt::Debug for $rt_name { + #[inline] + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str(concat!(stringify!($rt_name), " { ... }")) } } - impl $crate::VariableOutputReset for $name { + impl $crate::crypto_common::AlgorithmName for $rt_name { #[inline] - fn finalize_variable_reset( - &mut self, - out: &mut [u8], - ) -> Result<(), $crate::InvalidBufferSize> { - <$wrapped_ty as $crate::VariableOutputReset>::finalize_variable_reset(&mut self.0, out) + fn write_alg_name(f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { + <$wrapped_rt as $crate::crypto_common::AlgorithmName>::write_alg_name(f) } } - impl $crate::crypto_common::hazmat::SerializableState for $name { - type SerializedStateSize = <$wrapped_ty as $crate::crypto_common::hazmat::SerializableState>::SerializedStateSize; + impl Clone for $rt_name { + #[inline] + fn clone(&self) -> Self { + Self { + inner: <$wrapped_rt as Clone>::clone(&self.inner), + } + } + } + + impl $crate::Reset for $rt_name { + #[inline] + fn reset(&mut self) { + <$wrapped_rt as $crate::Reset>::reset(&mut self.inner); + } + } + + impl $crate::core_api::BlockSizeUser for $rt_name { + type BlockSize = <$wrapped_rt as $crate::crypto_common::BlockSizeUser>::BlockSize; + } + + impl $crate::HashMarker for $rt_name {} + + impl $crate::Update for $rt_name { + #[inline] + fn update(&mut self, data: &[u8]) { + <$wrapped_rt as $crate::Update>::update(&mut self.inner, data) + } + } + + impl $crate::VariableOutput for $rt_name { + const MAX_OUTPUT_SIZE: usize = <$wrapped_rt as $crate::VariableOutput>::MAX_OUTPUT_SIZE; + + #[inline] + fn new(output_size: usize) -> Result { + let inner = <$wrapped_rt as $crate::VariableOutput>::new(output_size)?; + Ok(Self { inner }) + } + + #[inline] + fn output_size(&self) -> usize { + <$wrapped_rt as $crate::VariableOutput>::output_size(&self.inner) + } + + #[inline] + fn finalize_variable(self, out: &mut [u8]) -> Result<(), $crate::InvalidBufferSize> { + <$wrapped_rt as $crate::VariableOutput>::finalize_variable(self.inner, out) + } + } + + // impl $crate::VariableOutputReset for $rt_name { + // #[inline] + // fn finalize_variable_reset( + // &mut self, + // out: &mut [u8], + // ) -> Result<(), $crate::InvalidBufferSize> { + // <$wrapped_rt as $crate::VariableOutputReset>::finalize_variable_reset(&mut self.inner, out) + // } + // } + + impl $crate::crypto_common::hazmat::SerializableState for $rt_name { + type SerializedStateSize = <$wrapped_rt as $crate::crypto_common::hazmat::SerializableState>::SerializedStateSize; #[inline] fn serialize(&self) -> $crate::crypto_common::hazmat::SerializedState { - <$wrapped_ty as $crate::crypto_common::hazmat::SerializableState>::serialize(&self.inner) + <$wrapped_rt as $crate::crypto_common::hazmat::SerializableState>::serialize(&self.inner) } #[inline] fn deserialize( serialized_state: &$crate::crypto_common::hazmat::SerializedState, ) -> Result { - let inner = <$wrapped_ty as $crate::crypto_common::hazmat::SerializableState>::deserialize(serialized_state)?; + let inner = <$wrapped_rt as $crate::crypto_common::hazmat::SerializableState>::deserialize(serialized_state)?; Ok(Self { inner }) } } - - $( - #[cfg(feature = "oid")] - impl $crate::const_oid::AssociatedOid for $name { - const OID: $crate::const_oid::ObjectIdentifier = - $crate::const_oid::ObjectIdentifier::new_unwrap($oid); - } - )? }; } From 75445cc29fa2722e0d4a67b9159edea126c8b1d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Sun, 4 May 2025 20:38:29 +0300 Subject: [PATCH 15/31] Add HashMarker checks --- digest/src/newtype/fixed.rs | 7 +++++++ digest/src/newtype/variable.rs | 18 ++++++++++++++++++ digest/src/newtype/xof.rs | 7 +++++++ 3 files changed, 32 insertions(+) diff --git a/digest/src/newtype/fixed.rs b/digest/src/newtype/fixed.rs index a603bf7ea..bae3f8260 100644 --- a/digest/src/newtype/fixed.rs +++ b/digest/src/newtype/fixed.rs @@ -60,6 +60,13 @@ macro_rules! newtype_fixed_hash { impl$(<$gp: $bound>)? $crate::HashMarker for $name$(<$gp>)? {} + // Verify that `$wrapped_ty` implements `HashMarker` + const _: () = { + fn check$(<$gp: $bound>)?(v: &$wrapped_ty) { + v as &dyn $crate::HashMarker; + } + }; + impl$(<$gp: $bound>)? $crate::core_api::CoreProxy for $name$(<$gp>)? { type Core = <$wrapped_ty as $crate::core_api::CoreProxy>::Core; } diff --git a/digest/src/newtype/variable.rs b/digest/src/newtype/variable.rs index 5d720a119..b30f95603 100644 --- a/digest/src/newtype/variable.rs +++ b/digest/src/newtype/variable.rs @@ -100,6 +100,17 @@ macro_rules! newtype_variable_hash { $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, {} + // Verify that `$wrapped_ty` implements `HashMarker` + const _: () = { + fn check<$out_size>(v: &$wrapped_ct) + where + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, + $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, + { + v as &dyn $crate::HashMarker; + } + }; + impl<$out_size> $crate::core_api::CoreProxy for $ct_name<$out_size> where $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, @@ -203,6 +214,13 @@ macro_rules! newtype_variable_hash { impl $crate::HashMarker for $rt_name {} + // Verify that `$wrapped_ty` implements `HashMarker` + const _: () = { + fn check(v: &$wrapped_rt) { + v as &dyn $crate::HashMarker; + } + }; + impl $crate::Update for $rt_name { #[inline] fn update(&mut self, data: &[u8]) { diff --git a/digest/src/newtype/xof.rs b/digest/src/newtype/xof.rs index 1c42a9c93..b216ff624 100644 --- a/digest/src/newtype/xof.rs +++ b/digest/src/newtype/xof.rs @@ -59,6 +59,13 @@ macro_rules! newtype_xof_hash { impl $crate::HashMarker for $name {} + // Verify that `$wrapped_ty` implements `HashMarker` + const _: () = { + fn check(v: &$wrapped_ty) { + v as &dyn $crate::HashMarker; + } + }; + impl $crate::core_api::CoreProxy for $name { type Core = <$wrapped_ty as $crate::core_api::CoreProxy>::Core; } From de0daef9446e64ab9a599653d9c804d27a32b969 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Mon, 5 May 2025 17:03:19 +0300 Subject: [PATCH 16/31] Implement fixed traits directly instead of delegating --- digest/src/newtype/fixed.rs | 88 +++++++++++++++++++++------- digest/tests/dummy_fixed.rs | 114 ++++++++++++++++++------------------ 2 files changed, 125 insertions(+), 77 deletions(-) diff --git a/digest/src/newtype/fixed.rs b/digest/src/newtype/fixed.rs index bae3f8260..dc33214ff 100644 --- a/digest/src/newtype/fixed.rs +++ b/digest/src/newtype/fixed.rs @@ -4,11 +4,15 @@ macro_rules! newtype_fixed_hash { ( $(#[$attr:meta])* - $v:vis struct $name:ident$(<$gp:ident: $bound:ident>)?($wrapped_ty:ty); + $v:vis struct $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); ) => { $(#[$attr])* $v struct $name$(<$gp: $bound>)? { - inner: $wrapped_ty + core: $core_ty, + buffer: $crate::block_buffer::BlockBuffer< + <$core_ty as $crate::core_api::BlockSizeUser>::BlockSize, + <$core_ty as $crate::core_api::BufferKindUser>::BufferKind, + > } impl$(<$gp: $bound>)? core::fmt::Debug for $name$(<$gp>)? { @@ -21,7 +25,7 @@ macro_rules! newtype_fixed_hash { impl$(<$gp: $bound>)? $crate::crypto_common::AlgorithmName for $name$(<$gp>)? { #[inline] fn write_alg_name(f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { - <$wrapped_ty as $crate::crypto_common::AlgorithmName>::write_alg_name(f) + <$core_ty as $crate::crypto_common::AlgorithmName>::write_alg_name(f) } } @@ -29,7 +33,8 @@ macro_rules! newtype_fixed_hash { #[inline] fn clone(&self) -> Self { Self { - inner: <$wrapped_ty as Clone>::clone(&self.inner), + core: self.core.clone(), + buffer: self.buffer.clone(), } } } @@ -38,7 +43,8 @@ macro_rules! newtype_fixed_hash { #[inline] fn default() -> Self { Self { - inner: <$wrapped_ty as Default>::default(), + core: Default::default(), + buffer: Default::default(), } } } @@ -46,78 +52,118 @@ macro_rules! newtype_fixed_hash { impl$(<$gp: $bound>)? $crate::Reset for $name$(<$gp>)? { #[inline] fn reset(&mut self) { - <$wrapped_ty as $crate::Reset>::reset(&mut self.inner); + self.core.reset(); + self.buffer.reset(); } } impl$(<$gp: $bound>)? $crate::core_api::BlockSizeUser for $name$(<$gp>)? { - type BlockSize = <$wrapped_ty as $crate::crypto_common::BlockSizeUser>::BlockSize; + type BlockSize = <$core_ty as $crate::crypto_common::BlockSizeUser>::BlockSize; } impl$(<$gp: $bound>)? $crate::OutputSizeUser for $name$(<$gp>)? { - type OutputSize = <$wrapped_ty as $crate::core_api::OutputSizeUser>::OutputSize; + type OutputSize = <$core_ty as $crate::core_api::OutputSizeUser>::OutputSize; } impl$(<$gp: $bound>)? $crate::HashMarker for $name$(<$gp>)? {} - // Verify that `$wrapped_ty` implements `HashMarker` + // Verify that `$core_ty` implements `HashMarker` const _: () = { - fn check$(<$gp: $bound>)?(v: &$wrapped_ty) { + fn check$(<$gp: $bound>)?(v: &$core_ty) { v as &dyn $crate::HashMarker; } }; impl$(<$gp: $bound>)? $crate::core_api::CoreProxy for $name$(<$gp>)? { - type Core = <$wrapped_ty as $crate::core_api::CoreProxy>::Core; + type Core = $core_ty; } impl$(<$gp: $bound>)? $crate::Update for $name$(<$gp>)? { #[inline] fn update(&mut self, data: &[u8]) { - <$wrapped_ty as $crate::Update>::update(&mut self.inner, data) + let Self { core, buffer } = self; + buffer.digest_blocks(data, |blocks| { + $crate::core_api::UpdateCore::update_blocks(core, blocks) + }); } } impl$(<$gp: $bound>)? $crate::FixedOutput for $name$(<$gp>)? { #[inline] - fn finalize_into(self, out: &mut $crate::Output) { - <$wrapped_ty as $crate::FixedOutput>::finalize_into(self.inner, out) + fn finalize_into(mut self, out: &mut $crate::Output) { + let Self { core, buffer } = &mut self; + $crate::core_api::FixedOutputCore::finalize_fixed_core(core, buffer, out); } } impl$(<$gp: $bound>)? $crate::FixedOutputReset for $name$(<$gp>)? { #[inline] fn finalize_into_reset(&mut self, out: &mut $crate::Output) { - <$wrapped_ty as $crate::FixedOutputReset>::finalize_into_reset(&mut self.inner, out); + let Self { core, buffer } = self; + $crate::core_api::FixedOutputCore::finalize_fixed_core(core, buffer, out); + $crate::Reset::reset(core); + buffer.reset(); } } impl$(<$gp: $bound>)? $crate::crypto_common::hazmat::SerializableState for $name$(<$gp>)? { - type SerializedStateSize = <$wrapped_ty as $crate::crypto_common::hazmat::SerializableState>::SerializedStateSize; + type SerializedStateSize = $crate::typenum::Sum< + <$core_ty as $crate::crypto_common::hazmat::SerializableState>::SerializedStateSize, + $crate::typenum::Add1< + <$core_ty as $crate::core_api::BlockSizeUser>::BlockSize + > + >; #[inline] fn serialize(&self) -> $crate::crypto_common::hazmat::SerializedState { - <$wrapped_ty as $crate::crypto_common::hazmat::SerializableState>::serialize(&self.inner) + use $crate::{ + array::Array, + consts::U1, + block_buffer::BlockBuffer, + crypto_common::hazmat::SerializableState, + }; + + let serialized_core = self.core.serialize(); + let pos = u8::try_from(self.buffer.get_pos()).unwrap(); + let serialized_pos: Array = Array([pos]); + let serialized_data = self.buffer.clone().pad_with_zeros(); + + serialized_core + .concat(serialized_pos) + .concat(serialized_data) } #[inline] fn deserialize( serialized_state: &$crate::crypto_common::hazmat::SerializedState, ) -> Result { - let inner = <$wrapped_ty as $crate::crypto_common::hazmat::SerializableState>::deserialize(serialized_state)?; - Ok(Self { inner }) + use $crate::{ + block_buffer::BlockBuffer, + consts::U1, + crypto_common::hazmat::{SerializableState, DeserializeStateError}, + }; + + let (serialized_core, remaining_buffer) = serialized_state + .split_ref::<<$core_ty as SerializableState>::SerializedStateSize>(); + let (serialized_pos, serialized_data) = remaining_buffer.split_ref::(); + + Ok(Self { + core: <$core_ty as SerializableState>::deserialize(serialized_core)?, + buffer: BlockBuffer::try_new(&serialized_data[..serialized_pos[0].into()]) + .map_err(|_| DeserializeStateError)?, + }) } } }; ( $(#[$attr:meta])* - $v:vis struct $name:ident$(<$gp:ident: $bound:ident>)?($wrapped_ty:ty); + $v:vis struct $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); oid: $oid:literal ) => { $crate::newtype_fixed_hash!( $(#[$attr])* - $v struct $name$(<$gp: $bound>)?($wrapped_ty); + $v struct $name$(<$gp: $bound>)?($core_ty); ); #[cfg(feature = "oid")] diff --git a/digest/tests/dummy_fixed.rs b/digest/tests/dummy_fixed.rs index df327f5aa..169bb50ab 100644 --- a/digest/tests/dummy_fixed.rs +++ b/digest/tests/dummy_fixed.rs @@ -1,81 +1,83 @@ #![cfg(feature = "core-api")] -use core::fmt; -use digest::{ - HashMarker, Output, OutputSizeUser, Reset, - consts::U8, - core_api::{ - AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, CoreWrapper, FixedOutputCore, - UpdateCore, - }, - crypto_common::hazmat::{DeserializeStateError, SerializableState, SerializedState}, -}; +mod block_api { + use core::fmt; + use digest::{ + HashMarker, Output, OutputSizeUser, Reset, + consts::U8, + core_api::{ + AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, FixedOutputCore, + UpdateCore, + }, + crypto_common::hazmat::{DeserializeStateError, SerializableState, SerializedState}, + }; -/// Core of primitive XOR hasher for testing purposes -#[derive(Clone, Default, Debug)] -pub struct FixedHashCore { - state: u64, -} + /// Core of primitive XOR hasher for testing purposes + #[derive(Clone, Default, Debug)] + pub struct FixedHashCore { + state: u64, + } -impl AlgorithmName for FixedHashCore { - fn write_alg_name(f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - f.write_str("FixedHash") + impl AlgorithmName for FixedHashCore { + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + f.write_str("FixedHash") + } } -} -impl BlockSizeUser for FixedHashCore { - type BlockSize = U8; -} + impl BlockSizeUser for FixedHashCore { + type BlockSize = U8; + } -impl BufferKindUser for FixedHashCore { - type BufferKind = block_buffer::Eager; -} + impl BufferKindUser for FixedHashCore { + type BufferKind = block_buffer::Eager; + } -impl Reset for FixedHashCore { - fn reset(&mut self) { - self.state = 0; + impl Reset for FixedHashCore { + fn reset(&mut self) { + self.state = 0; + } } -} -impl UpdateCore for FixedHashCore { - fn update_blocks(&mut self, blocks: &[Block]) { - for block in blocks { - self.state ^= u64::from_le_bytes(block.0) + impl UpdateCore for FixedHashCore { + fn update_blocks(&mut self, blocks: &[Block]) { + for block in blocks { + self.state ^= u64::from_le_bytes(block.0) + } } } -} -impl HashMarker for FixedHashCore {} + impl HashMarker for FixedHashCore {} -impl OutputSizeUser for FixedHashCore { - type OutputSize = U8; -} + impl OutputSizeUser for FixedHashCore { + type OutputSize = U8; + } -impl FixedOutputCore for FixedHashCore { - fn finalize_fixed_core(&mut self, buffer: &mut Buffer, out: &mut Output) { - let block = buffer.pad_with_zeros(); - self.state ^= u64::from_le_bytes(block.0); - out.copy_from_slice(&self.state.to_le_bytes()); + impl FixedOutputCore for FixedHashCore { + fn finalize_fixed_core(&mut self, buffer: &mut Buffer, out: &mut Output) { + let block = buffer.pad_with_zeros(); + self.state ^= u64::from_le_bytes(block.0); + out.copy_from_slice(&self.state.to_le_bytes()); + } } -} -impl SerializableState for FixedHashCore { - type SerializedStateSize = U8; + impl SerializableState for FixedHashCore { + type SerializedStateSize = U8; - fn serialize(&self) -> SerializedState { - self.state.to_le_bytes().into() - } + fn serialize(&self) -> SerializedState { + self.state.to_le_bytes().into() + } - fn deserialize( - serialized_state: &SerializedState, - ) -> Result { - Ok(Self { - state: u64::from_le_bytes(serialized_state.0), - }) + fn deserialize( + serialized_state: &SerializedState, + ) -> Result { + Ok(Self { + state: u64::from_le_bytes(serialized_state.0), + }) + } } } digest::newtype_fixed_hash!( /// Primitive XOR hasher for testing purposes - pub struct FixedHash(CoreWrapper); + pub struct FixedHash(block_api::FixedHashCore); ); From 727f9f51be5e17481234e4c969addaa914b5ddd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Tue, 6 May 2025 19:36:53 +0300 Subject: [PATCH 17/31] tweak newtype_xof --- digest/src/core_api.rs | 1 + digest/src/newtype/fixed.rs | 9 ++- digest/src/newtype/xof.rs | 133 +++++++++++++++++++++++++----------- 3 files changed, 98 insertions(+), 45 deletions(-) diff --git a/digest/src/core_api.rs b/digest/src/core_api.rs index 6e8b8def7..d7fe308ce 100644 --- a/digest/src/core_api.rs +++ b/digest/src/core_api.rs @@ -5,6 +5,7 @@ //! higher-level traits. use crate::InvalidOutputSize; +pub use block_buffer::{Eager, Lazy}; pub use crypto_common::{AlgorithmName, Block, BlockSizeUser, OutputSizeUser, Reset}; use block_buffer::{BlockBuffer, BufferKind}; diff --git a/digest/src/newtype/fixed.rs b/digest/src/newtype/fixed.rs index dc33214ff..3102d83b4 100644 --- a/digest/src/newtype/fixed.rs +++ b/digest/src/newtype/fixed.rs @@ -33,8 +33,8 @@ macro_rules! newtype_fixed_hash { #[inline] fn clone(&self) -> Self { Self { - core: self.core.clone(), - buffer: self.buffer.clone(), + core: Clone::clone(&self.core), + buffer: Clone::clone(&self.buffer), } } } @@ -52,7 +52,7 @@ macro_rules! newtype_fixed_hash { impl$(<$gp: $bound>)? $crate::Reset for $name$(<$gp>)? { #[inline] fn reset(&mut self) { - self.core.reset(); + $crate::Reset::reset(&mut self.core); self.buffer.reset(); } } @@ -101,8 +101,7 @@ macro_rules! newtype_fixed_hash { fn finalize_into_reset(&mut self, out: &mut $crate::Output) { let Self { core, buffer } = self; $crate::core_api::FixedOutputCore::finalize_fixed_core(core, buffer, out); - $crate::Reset::reset(core); - buffer.reset(); + $crate::Reset::reset(self); } } diff --git a/digest/src/newtype/xof.rs b/digest/src/newtype/xof.rs index b216ff624..257811c0b 100644 --- a/digest/src/newtype/xof.rs +++ b/digest/src/newtype/xof.rs @@ -4,125 +4,174 @@ macro_rules! newtype_xof_hash { ( $(#[$attr:meta])* - $v:vis struct $name:ident($wrapped_ty:ty); + $hasher_vis:vis struct $hasher_name:ident($hasher_core:ty); $(#[$reader_attr:meta])* - $reader_v:vis struct $reader_name:ident($wrapped_reader_ty:ty); + $reader_vis:vis struct $reader_name:ident($reader_core:ty); $(oid: $oid:literal)? ) => { $(#[$attr])* - $v struct $name { - inner: $wrapped_ty + $hasher_vis struct $hasher_name { + core: $hasher_core, + buffer: $crate::block_buffer::BlockBuffer< + <$hasher_core as $crate::core_api::BlockSizeUser>::BlockSize, + <$hasher_core as $crate::core_api::BufferKindUser>::BufferKind, + > } - impl core::fmt::Debug for $name { + impl core::fmt::Debug for $hasher_name { #[inline] fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.write_str(concat!(stringify!($name), " { ... }")) + f.write_str(concat!(stringify!($hasher_name), " { ... }")) } } - impl $crate::crypto_common::AlgorithmName for $name { + impl $crate::crypto_common::AlgorithmName for $hasher_name { #[inline] fn write_alg_name(f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { - <$wrapped_ty as $crate::crypto_common::AlgorithmName>::write_alg_name(f) + <$hasher_core as $crate::crypto_common::AlgorithmName>::write_alg_name(f) } } - impl Clone for $name { + impl Clone for $hasher_name { #[inline] fn clone(&self) -> Self { Self { - inner: <$wrapped_ty as Clone>::clone(&self.inner), + core: Clone::clone(&self.core), + buffer: Clone::clone(&self.buffer), } } } - impl Default for $name { + impl Default for $hasher_name { #[inline] fn default() -> Self { Self { - inner: <$wrapped_ty as Default>::default(), + core: Default::default(), + buffer: Default::default(), } } } - impl $crate::Reset for $name { + impl $crate::Reset for $hasher_name { #[inline] fn reset(&mut self) { - $crate::Reset::reset(&mut self.inner); + $crate::Reset::reset(&mut self.core); + self.buffer.reset(); } } - impl $crate::core_api::BlockSizeUser for $name { - type BlockSize = <$wrapped_ty as $crate::crypto_common::BlockSizeUser>::BlockSize; + impl $crate::core_api::BlockSizeUser for $hasher_name { + type BlockSize = <$hasher_core as $crate::crypto_common::BlockSizeUser>::BlockSize; } - impl $crate::HashMarker for $name {} + impl $crate::HashMarker for $hasher_name {} - // Verify that `$wrapped_ty` implements `HashMarker` + // Verify that `$hasher_core` implements `HashMarker` const _: () = { - fn check(v: &$wrapped_ty) { + fn check(v: &$hasher_core) { v as &dyn $crate::HashMarker; } }; - impl $crate::core_api::CoreProxy for $name { - type Core = <$wrapped_ty as $crate::core_api::CoreProxy>::Core; + impl $crate::core_api::CoreProxy for $hasher_name { + type Core = $hasher_core; } - impl $crate::Update for $name { + impl $crate::Update for $hasher_name { #[inline] fn update(&mut self, data: &[u8]) { - <$wrapped_ty as $crate::Update>::update(&mut self.inner, data) + let Self { core, buffer } = self; + buffer.digest_blocks(data, |blocks| { + $crate::core_api::UpdateCore::update_blocks(core, blocks) + }); } } - impl $crate::ExtendableOutput for $name { + impl $crate::ExtendableOutput for $hasher_name { type Reader = $reader_name; #[inline] - fn finalize_xof(self) -> Self::Reader { - let inner: $wrapped_reader_ty = <$wrapped_ty as $crate::ExtendableOutput>::finalize_xof(self.inner); - $reader_name { inner } + fn finalize_xof(mut self) -> Self::Reader { + let Self { core, buffer } = &mut self; + let core = <$hasher_core as $crate::core_api::ExtendableOutputCore>::finalize_xof_core(core, buffer); + let buffer = Default::default(); + Self::Reader { core, buffer } } } - impl $crate::ExtendableOutputReset for $name { + impl $crate::ExtendableOutputReset for $hasher_name { #[inline] fn finalize_xof_reset(&mut self) -> Self::Reader { - let inner = <$wrapped_ty as $crate::ExtendableOutputReset>::finalize_xof_reset(&mut self.inner); - $reader_name { inner } + let Self { core, buffer } = self; + let core = <$hasher_core as $crate::core_api::ExtendableOutputCore>::finalize_xof_core(core, buffer); + $crate::Reset::reset(self); + let buffer = Default::default(); + Self::Reader { core, buffer } } } - impl $crate::crypto_common::hazmat::SerializableState for $name { - type SerializedStateSize = <$wrapped_ty as $crate::crypto_common::hazmat::SerializableState>::SerializedStateSize; + + impl $crate::crypto_common::hazmat::SerializableState for $hasher_name { + type SerializedStateSize = $crate::typenum::Sum< + <$hasher_core as $crate::crypto_common::hazmat::SerializableState>::SerializedStateSize, + $crate::typenum::Add1< + <$hasher_core as $crate::core_api::BlockSizeUser>::BlockSize + > + >; #[inline] fn serialize(&self) -> $crate::crypto_common::hazmat::SerializedState { - $crate::crypto_common::hazmat::SerializableState::serialize(&self.inner) + use $crate::{ + array::Array, + consts::U1, + block_buffer::BlockBuffer, + crypto_common::hazmat::SerializableState, + }; + + let serialized_core = self.core.serialize(); + let pos = u8::try_from(self.buffer.get_pos()).unwrap(); + let serialized_pos: Array = Array([pos]); + let serialized_data = self.buffer.clone().pad_with_zeros(); + + serialized_core + .concat(serialized_pos) + .concat(serialized_data) } #[inline] fn deserialize( serialized_state: &$crate::crypto_common::hazmat::SerializedState, ) -> Result { - let inner = $crate::crypto_common::hazmat::SerializableState::deserialize(serialized_state)?; - Ok(Self { inner }) + use $crate::{ + block_buffer::BlockBuffer, + consts::U1, + crypto_common::hazmat::{SerializableState, DeserializeStateError}, + }; + + let (serialized_core, remaining_buffer) = serialized_state + .split_ref::<<$hasher_core as SerializableState>::SerializedStateSize>(); + let (serialized_pos, serialized_data) = remaining_buffer.split_ref::(); + + Ok(Self { + core: <$hasher_core as SerializableState>::deserialize(serialized_core)?, + buffer: BlockBuffer::try_new(&serialized_data[..serialized_pos[0].into()]) + .map_err(|_| DeserializeStateError)?, + }) } } $( #[cfg(feature = "oid")] - impl $crate::const_oid::AssociatedOid for $name { + impl $crate::const_oid::AssociatedOid for $hasher_name { const OID: $crate::const_oid::ObjectIdentifier = $crate::const_oid::ObjectIdentifier::new_unwrap($oid); } )? $(#[$reader_attr])* - $reader_v struct $reader_name { - inner: $wrapped_reader_ty + $reader_vis struct $reader_name { + core: $reader_core, + buffer: $crate::block_buffer::ReadBuffer<<$reader_core as $crate::core_api::BlockSizeUser>::BlockSize>, } impl core::fmt::Debug for $reader_name { @@ -136,7 +185,8 @@ macro_rules! newtype_xof_hash { #[inline] fn clone(&self) -> Self { Self { - inner: Clone::clone(&self.inner), + core: Clone::clone(&self.core), + buffer: Clone::clone(&self.buffer), } } } @@ -144,7 +194,10 @@ macro_rules! newtype_xof_hash { impl $crate::XofReader for $reader_name { #[inline] fn read(&mut self, buf: &mut [u8]) { - $crate::XofReader::read(&mut self.inner, buf) + let Self { core, buffer } = self; + buffer.read(buf, |block| { + *block = $crate::core_api::XofReaderCore::read_block(core); + }); } } }; From 01f3055c82ce740d94d3dcb19a24684c23df5c01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Wed, 7 May 2025 17:14:21 +0300 Subject: [PATCH 18/31] introduce separate `newtype_rt_variable_hash` macro --- digest/src/newtype.rs | 3 +- digest/src/newtype/fixed.rs | 5 +- .../newtype/{variable.rs => variable_ct.rs} | 106 +---------- digest/src/newtype/variable_rt.rs | 175 ++++++++++++++++++ digest/src/newtype/xof.rs | 5 +- 5 files changed, 180 insertions(+), 114 deletions(-) rename digest/src/newtype/{variable.rs => variable_ct.rs} (65%) create mode 100644 digest/src/newtype/variable_rt.rs diff --git a/digest/src/newtype.rs b/digest/src/newtype.rs index b0412f4fe..f03fec8d8 100644 --- a/digest/src/newtype.rs +++ b/digest/src/newtype.rs @@ -1,3 +1,4 @@ mod fixed; -mod variable; +mod variable_ct; +mod variable_rt; mod xof; diff --git a/digest/src/newtype/fixed.rs b/digest/src/newtype/fixed.rs index 3102d83b4..5bef611f8 100644 --- a/digest/src/newtype/fixed.rs +++ b/digest/src/newtype/fixed.rs @@ -9,10 +9,7 @@ macro_rules! newtype_fixed_hash { $(#[$attr])* $v struct $name$(<$gp: $bound>)? { core: $core_ty, - buffer: $crate::block_buffer::BlockBuffer< - <$core_ty as $crate::core_api::BlockSizeUser>::BlockSize, - <$core_ty as $crate::core_api::BufferKindUser>::BufferKind, - > + buffer: $crate::core_api::Buffer<$core_ty>, } impl$(<$gp: $bound>)? core::fmt::Debug for $name$(<$gp>)? { diff --git a/digest/src/newtype/variable.rs b/digest/src/newtype/variable_ct.rs similarity index 65% rename from digest/src/newtype/variable.rs rename to digest/src/newtype/variable_ct.rs index b30f95603..df7f2f527 100644 --- a/digest/src/newtype/variable.rs +++ b/digest/src/newtype/variable_ct.rs @@ -1,12 +1,10 @@ /// Creates a newtype wrapper around another type and /// delegates implementation of `digest` traits to it. #[macro_export] -macro_rules! newtype_variable_hash { +macro_rules! newtype_ct_variable_hash { ( $(#[$ct_attr:meta])* $ct_vis:vis struct $ct_name:ident<$out_size:ident>($wrapped_ct:ty); - $(#[$rt_attr:meta])* - $rt_vis:vis struct $rt_name:ident($wrapped_rt:ty); // Ideally, we would use `$core_ty::OutputSize`, but unfortunately the compiler // does not accept such code. The likely reason is this issue: // https://github.com/rust-lang/rust/issues/79629 @@ -172,107 +170,5 @@ macro_rules! newtype_variable_hash { Ok(Self { inner }) } } - - $(#[$rt_attr])* - $rt_vis struct $rt_name { - inner: $wrapped_rt, - } - - impl core::fmt::Debug for $rt_name { - #[inline] - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.write_str(concat!(stringify!($rt_name), " { ... }")) - } - } - - impl $crate::crypto_common::AlgorithmName for $rt_name { - #[inline] - fn write_alg_name(f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { - <$wrapped_rt as $crate::crypto_common::AlgorithmName>::write_alg_name(f) - } - } - - impl Clone for $rt_name { - #[inline] - fn clone(&self) -> Self { - Self { - inner: <$wrapped_rt as Clone>::clone(&self.inner), - } - } - } - - impl $crate::Reset for $rt_name { - #[inline] - fn reset(&mut self) { - <$wrapped_rt as $crate::Reset>::reset(&mut self.inner); - } - } - - impl $crate::core_api::BlockSizeUser for $rt_name { - type BlockSize = <$wrapped_rt as $crate::crypto_common::BlockSizeUser>::BlockSize; - } - - impl $crate::HashMarker for $rt_name {} - - // Verify that `$wrapped_ty` implements `HashMarker` - const _: () = { - fn check(v: &$wrapped_rt) { - v as &dyn $crate::HashMarker; - } - }; - - impl $crate::Update for $rt_name { - #[inline] - fn update(&mut self, data: &[u8]) { - <$wrapped_rt as $crate::Update>::update(&mut self.inner, data) - } - } - - impl $crate::VariableOutput for $rt_name { - const MAX_OUTPUT_SIZE: usize = <$wrapped_rt as $crate::VariableOutput>::MAX_OUTPUT_SIZE; - - #[inline] - fn new(output_size: usize) -> Result { - let inner = <$wrapped_rt as $crate::VariableOutput>::new(output_size)?; - Ok(Self { inner }) - } - - #[inline] - fn output_size(&self) -> usize { - <$wrapped_rt as $crate::VariableOutput>::output_size(&self.inner) - } - - #[inline] - fn finalize_variable(self, out: &mut [u8]) -> Result<(), $crate::InvalidBufferSize> { - <$wrapped_rt as $crate::VariableOutput>::finalize_variable(self.inner, out) - } - } - - // impl $crate::VariableOutputReset for $rt_name { - // #[inline] - // fn finalize_variable_reset( - // &mut self, - // out: &mut [u8], - // ) -> Result<(), $crate::InvalidBufferSize> { - // <$wrapped_rt as $crate::VariableOutputReset>::finalize_variable_reset(&mut self.inner, out) - // } - // } - - impl $crate::crypto_common::hazmat::SerializableState for $rt_name { - type SerializedStateSize = <$wrapped_rt as $crate::crypto_common::hazmat::SerializableState>::SerializedStateSize; - - #[inline] - fn serialize(&self) -> $crate::crypto_common::hazmat::SerializedState { - <$wrapped_rt as $crate::crypto_common::hazmat::SerializableState>::serialize(&self.inner) - } - - #[inline] - fn deserialize( - serialized_state: &$crate::crypto_common::hazmat::SerializedState, - ) -> Result { - let inner = <$wrapped_rt as $crate::crypto_common::hazmat::SerializableState>::deserialize(serialized_state)?; - Ok(Self { inner }) - } - } }; } diff --git a/digest/src/newtype/variable_rt.rs b/digest/src/newtype/variable_rt.rs new file mode 100644 index 000000000..34542b260 --- /dev/null +++ b/digest/src/newtype/variable_rt.rs @@ -0,0 +1,175 @@ +/// Wrap +#[macro_export] +macro_rules! newtype_rt_variable_hash { + ( + $(#[$rt_attr:meta])* + $rt_vis:vis struct $name:ident($core_ty:ty); + ) => { + $(#[$rt_attr])* + $rt_vis struct $name { + core: $core_ty, + buffer: $crate::core_api::Buffer<$core_ty>, + output_size: u8, + } + + impl core::fmt::Debug for $name { + #[inline] + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str(concat!(stringify!($name), " { ... }")) + } + } + + impl $crate::crypto_common::AlgorithmName for $name { + #[inline] + fn write_alg_name(f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { + <$core_ty as $crate::crypto_common::AlgorithmName>::write_alg_name(f) + } + } + + impl Clone for $name { + #[inline] + fn clone(&self) -> Self { + Self { + core: Clone::clone(&self.core), + buffer: Clone::clone(&self.buffer), + output_size: self.output_size, + } + } + } + + impl $crate::Reset for $name { + #[inline] + fn reset(&mut self) { + let size = self.output_size.into(); + self.core = <$core_ty as $crate::core_api::VariableOutputCore>::new(size).unwrap(); + self.buffer.reset(); + } + } + + impl $crate::core_api::BlockSizeUser for $name { + type BlockSize = <$core_ty as $crate::crypto_common::BlockSizeUser>::BlockSize; + } + + impl $crate::HashMarker for $name {} + + // Verify that `$wrapped_ty` implements `HashMarker` + const _: () = { + fn check(v: &$core_ty) { + v as &dyn $crate::HashMarker; + } + }; + + impl $crate::Update for $name { + #[inline] + fn update(&mut self, data: &[u8]) { + let Self { core, buffer, .. } = self; + buffer.digest_blocks(data, |blocks| { + $crate::core_api::UpdateCore::update_blocks(core, blocks); + }); + } + } + + impl $name { + #[inline] + fn finalize_dirty(&mut self, out: &mut [u8]) -> Result<(), $crate::InvalidBufferSize> { + let Self { + core, + buffer, + output_size, + } = self; + let size_u8 = u8::try_from(out.len()).map_err(|_| $crate::InvalidBufferSize)?; + + let max_size = ::MAX_OUTPUT_SIZE; + if out.len() > max_size || size_u8 != *output_size { + return Err($crate::InvalidBufferSize); + } + let mut full_res = Default::default(); + $crate::core_api::VariableOutputCore::finalize_variable_core(core, buffer, &mut full_res); + let n = out.len(); + let m = full_res.len() - n; + use $crate::core_api::TruncSide::{Left, Right}; + let side = <$core_ty as $crate::core_api::VariableOutputCore>::TRUNC_SIDE; + match side { + Left => out.copy_from_slice(&full_res[..n]), + Right => out.copy_from_slice(&full_res[m..]), + } + Ok(()) + } + } + + impl $crate::VariableOutput for $name { + const MAX_OUTPUT_SIZE: usize = < + <$core_ty as $crate::core_api::OutputSizeUser>::OutputSize + as $crate::typenum::Unsigned + >::USIZE; + + #[inline] + fn new(output_size: usize) -> Result { + let output_size = u8::try_from(output_size).map_err(|_| $crate::InvalidOutputSize)?; + let buffer = Default::default(); + let core = <$core_ty as $crate::core_api::VariableOutputCore>::new(output_size.into())?; + Ok(Self { + core, + buffer, + output_size, + }) + } + + #[inline] + fn output_size(&self) -> usize { + self.output_size.into() + } + + #[inline] + fn finalize_variable(mut self, out: &mut [u8]) -> Result<(), $crate::InvalidBufferSize> { + self.finalize_dirty(out) + } + } + + impl $crate::VariableOutputReset for $name { + #[inline] + fn finalize_variable_reset( + &mut self, + out: &mut [u8], + ) -> Result<(), $crate::InvalidBufferSize> { + self.finalize_dirty(out)?; + $crate::Reset::reset(self); + Ok(()) + } + } + + impl Drop for $name { + #[inline] + fn drop(&mut self) { + #[cfg(feature = "zeroize")] + { + use $crate::zeroize::Zeroize; + self.buffer.zeroize(); + self.output_size.zeroize(); + } + } + } + + #[cfg(feature = "zeroize")] + impl $crate::zeroize::ZeroizeOnDrop for $name {} + + impl $crate::crypto_common::hazmat::SerializableState for $name { + type SerializedStateSize = $crate::typenum::Add1<$crate::typenum::Sum< + <$core_ty as $crate::crypto_common::hazmat::SerializableState>::SerializedStateSize, + <$core_ty as $crate::core_api::BlockSizeUser>::BlockSize, + >>; + + #[inline] + fn serialize(&self) -> $crate::crypto_common::hazmat::SerializedState { + todo!() + } + + #[inline] + fn deserialize( + serialized_state: &$crate::crypto_common::hazmat::SerializedState, + ) -> Result { + todo!() + } + } + }; +} diff --git a/digest/src/newtype/xof.rs b/digest/src/newtype/xof.rs index 257811c0b..427a3371a 100644 --- a/digest/src/newtype/xof.rs +++ b/digest/src/newtype/xof.rs @@ -12,10 +12,7 @@ macro_rules! newtype_xof_hash { $(#[$attr])* $hasher_vis struct $hasher_name { core: $hasher_core, - buffer: $crate::block_buffer::BlockBuffer< - <$hasher_core as $crate::core_api::BlockSizeUser>::BlockSize, - <$hasher_core as $crate::core_api::BufferKindUser>::BufferKind, - > + buffer: $crate::core_api::Buffer<$hasher_core>, } impl core::fmt::Debug for $hasher_name { From 2aced1d84f450f788f68586b519a828ce4d54600 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Wed, 7 May 2025 18:44:12 +0300 Subject: [PATCH 19/31] change `newtype_ct_variable_hash!` --- digest/src/core_api/ct_variable.rs | 1 + digest/src/newtype/variable_ct.rs | 120 ++++++++++++++++++++--------- 2 files changed, 86 insertions(+), 35 deletions(-) diff --git a/digest/src/core_api/ct_variable.rs b/digest/src/core_api/ct_variable.rs index d8ad3e8ca..1aba4d90a 100644 --- a/digest/src/core_api/ct_variable.rs +++ b/digest/src/core_api/ct_variable.rs @@ -16,6 +16,7 @@ use crypto_common::{ hazmat::{DeserializeStateError, SerializableState, SerializedState, SubSerializedStateSize}, typenum::{IsLess, IsLessOrEqual, Le, LeEq, NonZero, Sum, U1, U256}, }; + /// Wrapper around [`VariableOutputCore`] which selects output size /// at compile time. #[derive(Clone)] diff --git a/digest/src/newtype/variable_ct.rs b/digest/src/newtype/variable_ct.rs index df7f2f527..86216f456 100644 --- a/digest/src/newtype/variable_ct.rs +++ b/digest/src/newtype/variable_ct.rs @@ -4,95 +4,101 @@ macro_rules! newtype_ct_variable_hash { ( $(#[$ct_attr:meta])* - $ct_vis:vis struct $ct_name:ident<$out_size:ident>($wrapped_ct:ty); + $vis:vis struct $name:ident<$out_size:ident>($core_ty:ty); // Ideally, we would use `$core_ty::OutputSize`, but unfortunately the compiler // does not accept such code. The likely reason is this issue: // https://github.com/rust-lang/rust/issues/79629 max_size: $max_size:ty; ) => { $(#[$ct_attr])* - $ct_vis struct $ct_name<$out_size> + $vis struct $name<$out_size> where $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, { - inner: $wrapped_ct, + core: $crate::core_api::CtVariableCoreWrapper<$core_ty, $out_size>, + buffer: $crate::core_api::Buffer<$core_ty>, } - impl<$out_size> core::fmt::Debug for $ct_name<$out_size> + impl<$out_size> core::fmt::Debug for $name<$out_size> where $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, { #[inline] fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.write_str(concat!(stringify!($ct_name), " { ... }")) + f.write_str(concat!(stringify!($name), " { ... }")) } } - impl<$out_size> $crate::crypto_common::AlgorithmName for $ct_name<$out_size> + impl<$out_size> $crate::crypto_common::AlgorithmName for $name<$out_size> where $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, { #[inline] fn write_alg_name(f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { - <$wrapped_ct as $crate::crypto_common::AlgorithmName>::write_alg_name(f) + <$core_ty as $crate::crypto_common::AlgorithmName>::write_alg_name(f) } } - impl<$out_size> Clone for $ct_name<$out_size> + impl<$out_size> Clone for $name<$out_size> where $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, { #[inline] fn clone(&self) -> Self { - let inner = <$wrapped_ct as Clone>::clone(&self.inner); - Self { inner } + Self { + core: Clone::clone(&self.core), + buffer: Clone::clone(&self.buffer), + } } } - impl<$out_size> Default for $ct_name<$out_size> + impl<$out_size> Default for $name<$out_size> where $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, { #[inline] fn default() -> Self { - let inner = <$wrapped_ct as Default>::default(); - Self { inner } + Self { + core: Default::default(), + buffer: Default::default(), + } } } - impl<$out_size> $crate::Reset for $ct_name<$out_size> + impl<$out_size> $crate::Reset for $name<$out_size> where $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, { #[inline] fn reset(&mut self) { - <$wrapped_ct as $crate::Reset>::reset(&mut self.inner); + $crate::Reset::reset(&mut self.core); + self.buffer.reset(); } } - impl<$out_size> $crate::core_api::BlockSizeUser for $ct_name<$out_size> + impl<$out_size> $crate::core_api::BlockSizeUser for $name<$out_size> where $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, { - type BlockSize = <$wrapped_ct as $crate::crypto_common::BlockSizeUser>::BlockSize; + type BlockSize = <$core_ty as $crate::crypto_common::BlockSizeUser>::BlockSize; } - impl<$out_size> $crate::OutputSizeUser for $ct_name<$out_size> + impl<$out_size> $crate::OutputSizeUser for $name<$out_size> where $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, { - type OutputSize = <$wrapped_ct as $crate::crypto_common::OutputSizeUser>::OutputSize; + type OutputSize = $out_size; } - impl<$out_size> $crate::HashMarker for $ct_name<$out_size> + impl<$out_size> $crate::HashMarker for $name<$out_size> where $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, @@ -100,7 +106,7 @@ macro_rules! newtype_ct_variable_hash { // Verify that `$wrapped_ty` implements `HashMarker` const _: () = { - fn check<$out_size>(v: &$wrapped_ct) + fn check<$out_size>(v: &$core_ty) where $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, @@ -109,65 +115,109 @@ macro_rules! newtype_ct_variable_hash { } }; - impl<$out_size> $crate::core_api::CoreProxy for $ct_name<$out_size> + impl<$out_size> $crate::core_api::CoreProxy for $name<$out_size> where $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, { - type Core = <$wrapped_ct as $crate::core_api::CoreProxy>::Core; + type Core = $crate::core_api::CtVariableCoreWrapper<$core_ty, $out_size>; } - impl<$out_size> $crate::Update for $ct_name<$out_size> + impl<$out_size> $crate::Update for $name<$out_size> where $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, { #[inline] fn update(&mut self, data: &[u8]) { - <$wrapped_ct as $crate::Update>::update(&mut self.inner, data) + let Self { core, buffer } = self; + buffer.digest_blocks(data, |blocks| { + $crate::core_api::UpdateCore::update_blocks(core, blocks) + }); } } - impl<$out_size> $crate::FixedOutput for $ct_name<$out_size> + impl<$out_size> $crate::FixedOutput for $name<$out_size> where $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, { #[inline] - fn finalize_into(self, out: &mut $crate::Output) { - <$wrapped_ct as $crate::FixedOutput>::finalize_into(self.inner, out) + fn finalize_into(mut self, out: &mut $crate::Output) { + let Self { core, buffer } = &mut self; + $crate::core_api::FixedOutputCore::finalize_fixed_core(core, buffer, out); } } - impl<$out_size> $crate::FixedOutputReset for $ct_name<$out_size> + impl<$out_size> $crate::FixedOutputReset for $name<$out_size> where $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, { #[inline] fn finalize_into_reset(&mut self, out: &mut $crate::Output) { - <$wrapped_ct as $crate::FixedOutputReset>::finalize_into_reset(&mut self.inner, out); + let Self { core, buffer } = self; + $crate::core_api::FixedOutputCore::finalize_fixed_core(core, buffer, out); + $crate::Reset::reset(self); } } - impl<$out_size> $crate::crypto_common::hazmat::SerializableState for $ct_name<$out_size> + impl<$out_size> $crate::crypto_common::hazmat::SerializableState for $name<$out_size> where $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, { - type SerializedStateSize = <$wrapped_ct as $crate::crypto_common::hazmat::SerializableState>::SerializedStateSize; + type SerializedStateSize = $crate::typenum::Add1<$crate::typenum::Sum< + < + $crate::core_api::CtVariableCoreWrapper<$core_ty, $out_size> + as $crate::crypto_common::hazmat::SerializableState + >::SerializedStateSize, + <$core_ty as $crate::core_api::BlockSizeUser>::BlockSize, + >>; #[inline] fn serialize(&self) -> $crate::crypto_common::hazmat::SerializedState { - <$wrapped_ct as $crate::crypto_common::hazmat::SerializableState>::serialize(&self.inner) + use $crate::{ + array::Array, + consts::U1, + block_buffer::BlockBuffer, + crypto_common::hazmat::SerializableState, + }; + + let serialized_core = self.core.serialize(); + let pos = u8::try_from(self.buffer.get_pos()).unwrap(); + let serialized_pos: Array = Array([pos]); + let serialized_data = self.buffer.clone().pad_with_zeros(); + + serialized_core + .concat(serialized_pos) + .concat(serialized_data) } #[inline] fn deserialize( serialized_state: &$crate::crypto_common::hazmat::SerializedState, ) -> Result { - let inner = <$wrapped_ct as $crate::crypto_common::hazmat::SerializableState>::deserialize(serialized_state)?; - Ok(Self { inner }) + use $crate::{ + block_buffer::BlockBuffer, + consts::U1, + core_api::CtVariableCoreWrapper, + crypto_common::hazmat::{SerializableState, DeserializeStateError}, + }; + + let (serialized_core, remaining_buffer) = serialized_state + .split_ref::<< + CtVariableCoreWrapper<$core_ty, $out_size> + as SerializableState + >::SerializedStateSize>(); + let (serialized_pos, serialized_data) = remaining_buffer.split_ref::(); + + let core = SerializableState::deserialize(serialized_core)?; + let pos = usize::from(serialized_pos[0]); + let buffer = BlockBuffer::try_new(&serialized_data[..pos]) + .map_err(|_| DeserializeStateError)?; + + Ok(Self { core, buffer }) } } }; From e3794b02f00da68c43e1b266300676f336edc12e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Fri, 16 May 2025 06:40:38 +0300 Subject: [PATCH 20/31] Rename CtVariableCoreWrapper to CtOutWrapper --- digest/src/core_api.rs | 2 +- digest/src/core_api/ct_variable.rs | 35 +++++++++++++++--------------- digest/src/newtype/variable_ct.rs | 10 ++++----- 3 files changed, 23 insertions(+), 24 deletions(-) diff --git a/digest/src/core_api.rs b/digest/src/core_api.rs index d7fe308ce..b9f281dff 100644 --- a/digest/src/core_api.rs +++ b/digest/src/core_api.rs @@ -16,7 +16,7 @@ mod rt_variable; mod wrapper; mod xof_reader; -pub use ct_variable::CtVariableCoreWrapper; +pub use ct_variable::CtOutWrapper; pub use rt_variable::RtVariableCoreWrapper; pub use wrapper::{CoreProxy, CoreWrapper}; pub use xof_reader::XofReaderCoreWrapper; diff --git a/digest/src/core_api/ct_variable.rs b/digest/src/core_api/ct_variable.rs index 1aba4d90a..bd687fce1 100644 --- a/digest/src/core_api/ct_variable.rs +++ b/digest/src/core_api/ct_variable.rs @@ -17,10 +17,9 @@ use crypto_common::{ typenum::{IsLess, IsLessOrEqual, Le, LeEq, NonZero, Sum, U1, U256}, }; -/// Wrapper around [`VariableOutputCore`] which selects output size -/// at compile time. +/// Wrapper around [`VariableOutputCore`] which selects output size at compile time. #[derive(Clone)] -pub struct CtVariableCoreWrapper +pub struct CtOutWrapper where T: VariableOutputCore, OutSize: ArraySize + IsLessOrEqual, @@ -30,7 +29,7 @@ where _out: PhantomData, } -impl HashMarker for CtVariableCoreWrapper +impl HashMarker for CtOutWrapper where T: VariableOutputCore + HashMarker, OutSize: ArraySize + IsLessOrEqual, @@ -39,7 +38,7 @@ where } #[cfg(feature = "mac")] -impl MacMarker for CtVariableCoreWrapper +impl MacMarker for CtOutWrapper where T: VariableOutputCore + MacMarker, OutSize: ArraySize + IsLessOrEqual, @@ -47,7 +46,7 @@ where { } -impl CollisionResistance for CtVariableCoreWrapper +impl CollisionResistance for CtOutWrapper where T: VariableOutputCore + CollisionResistance, OutSize: ArraySize + IsLessOrEqual, @@ -56,7 +55,7 @@ where type CollisionResistance = T::CollisionResistance; } -impl BlockSizeUser for CtVariableCoreWrapper +impl BlockSizeUser for CtOutWrapper where T: VariableOutputCore, OutSize: ArraySize + IsLessOrEqual, @@ -65,7 +64,7 @@ where type BlockSize = T::BlockSize; } -impl UpdateCore for CtVariableCoreWrapper +impl UpdateCore for CtOutWrapper where T: VariableOutputCore, OutSize: ArraySize + IsLessOrEqual, @@ -77,7 +76,7 @@ where } } -impl OutputSizeUser for CtVariableCoreWrapper +impl OutputSizeUser for CtOutWrapper where T: VariableOutputCore, OutSize: ArraySize + IsLessOrEqual, @@ -86,7 +85,7 @@ where type OutputSize = OutSize; } -impl BufferKindUser for CtVariableCoreWrapper +impl BufferKindUser for CtOutWrapper where T: VariableOutputCore, OutSize: ArraySize + IsLessOrEqual, @@ -95,7 +94,7 @@ where type BufferKind = T::BufferKind; } -impl FixedOutputCore for CtVariableCoreWrapper +impl FixedOutputCore for CtOutWrapper where T: VariableOutputCore, OutSize: ArraySize + IsLessOrEqual, @@ -118,7 +117,7 @@ where } } -impl Default for CtVariableCoreWrapper +impl Default for CtOutWrapper where T: VariableOutputCore, OutSize: ArraySize + IsLessOrEqual, @@ -133,7 +132,7 @@ where } } -impl CustomizedInit for CtVariableCoreWrapper +impl CustomizedInit for CtOutWrapper where T: VariableOutputCore + VarOutputCustomized, OutSize: ArraySize + IsLessOrEqual, @@ -148,7 +147,7 @@ where } } -impl Reset for CtVariableCoreWrapper +impl Reset for CtOutWrapper where T: VariableOutputCore, OutSize: ArraySize + IsLessOrEqual, @@ -160,7 +159,7 @@ where } } -impl AlgorithmName for CtVariableCoreWrapper +impl AlgorithmName for CtOutWrapper where T: VariableOutputCore + AlgorithmName, OutSize: ArraySize + IsLessOrEqual, @@ -174,7 +173,7 @@ where } #[cfg(feature = "zeroize")] -impl zeroize::ZeroizeOnDrop for CtVariableCoreWrapper +impl zeroize::ZeroizeOnDrop for CtOutWrapper where T: VariableOutputCore + zeroize::ZeroizeOnDrop, OutSize: ArraySize + IsLessOrEqual, @@ -182,7 +181,7 @@ where { } -impl fmt::Debug for CtVariableCoreWrapper +impl fmt::Debug for CtOutWrapper where T: VariableOutputCore + AlgorithmName, OutSize: ArraySize + IsLessOrEqual, @@ -196,7 +195,7 @@ where type CtVariableCoreWrapperSerializedStateSize = Sum<::SerializedStateSize, U1>; -impl SerializableState for CtVariableCoreWrapper +impl SerializableState for CtOutWrapper where T: VariableOutputCore + SerializableState, OutSize: ArraySize + IsLessOrEqual, diff --git a/digest/src/newtype/variable_ct.rs b/digest/src/newtype/variable_ct.rs index 86216f456..af16529f8 100644 --- a/digest/src/newtype/variable_ct.rs +++ b/digest/src/newtype/variable_ct.rs @@ -16,7 +16,7 @@ macro_rules! newtype_ct_variable_hash { $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, { - core: $crate::core_api::CtVariableCoreWrapper<$core_ty, $out_size>, + core: $crate::core_api::CtOutWrapper<$core_ty, $out_size>, buffer: $crate::core_api::Buffer<$core_ty>, } @@ -120,7 +120,7 @@ macro_rules! newtype_ct_variable_hash { $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, { - type Core = $crate::core_api::CtVariableCoreWrapper<$core_ty, $out_size>; + type Core = $crate::core_api::CtOutWrapper<$core_ty, $out_size>; } impl<$out_size> $crate::Update for $name<$out_size> @@ -169,7 +169,7 @@ macro_rules! newtype_ct_variable_hash { { type SerializedStateSize = $crate::typenum::Add1<$crate::typenum::Sum< < - $crate::core_api::CtVariableCoreWrapper<$core_ty, $out_size> + $crate::core_api::CtOutWrapper<$core_ty, $out_size> as $crate::crypto_common::hazmat::SerializableState >::SerializedStateSize, <$core_ty as $crate::core_api::BlockSizeUser>::BlockSize, @@ -201,13 +201,13 @@ macro_rules! newtype_ct_variable_hash { use $crate::{ block_buffer::BlockBuffer, consts::U1, - core_api::CtVariableCoreWrapper, + core_api::CtOutWrapper, crypto_common::hazmat::{SerializableState, DeserializeStateError}, }; let (serialized_core, remaining_buffer) = serialized_state .split_ref::<< - CtVariableCoreWrapper<$core_ty, $out_size> + CtOutWrapper<$core_ty, $out_size> as SerializableState >::SerializedStateSize>(); let (serialized_pos, serialized_data) = remaining_buffer.split_ref::(); From 58d65d961fc5c091ee43750a4037a3994c202edd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Mon, 19 May 2025 13:05:41 +0300 Subject: [PATCH 21/31] Update macros --- digest/src/core_api/ct_variable.rs | 50 ++---- digest/src/newtype/fixed.rs | 247 +++++++++++++++++++++++------ digest/src/newtype/variable_ct.rs | 62 ++++---- digest/src/newtype/variable_rt.rs | 20 ++- digest/src/newtype/xof.rs | 2 +- digest/tests/dummy_fixed.rs | 18 +++ 6 files changed, 281 insertions(+), 118 deletions(-) diff --git a/digest/src/core_api/ct_variable.rs b/digest/src/core_api/ct_variable.rs index bd687fce1..775dd3c34 100644 --- a/digest/src/core_api/ct_variable.rs +++ b/digest/src/core_api/ct_variable.rs @@ -14,7 +14,7 @@ use crypto_common::{ Block, BlockSizeUser, OutputSizeUser, array::{Array, ArraySize}, hazmat::{DeserializeStateError, SerializableState, SerializedState, SubSerializedStateSize}, - typenum::{IsLess, IsLessOrEqual, Le, LeEq, NonZero, Sum, U1, U256}, + typenum::{IsLess, IsLessOrEqual, Le, NonZero, Sum, True, U1, U256}, }; /// Wrapper around [`VariableOutputCore`] which selects output size at compile time. @@ -22,8 +22,7 @@ use crypto_common::{ pub struct CtOutWrapper where T: VariableOutputCore, - OutSize: ArraySize + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArraySize + IsLessOrEqual, { inner: T, _out: PhantomData, @@ -32,8 +31,7 @@ where impl HashMarker for CtOutWrapper where T: VariableOutputCore + HashMarker, - OutSize: ArraySize + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArraySize + IsLessOrEqual, { } @@ -41,16 +39,14 @@ where impl MacMarker for CtOutWrapper where T: VariableOutputCore + MacMarker, - OutSize: ArraySize + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArraySize + IsLessOrEqual, { } impl CollisionResistance for CtOutWrapper where T: VariableOutputCore + CollisionResistance, - OutSize: ArraySize + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArraySize + IsLessOrEqual, { type CollisionResistance = T::CollisionResistance; } @@ -58,8 +54,7 @@ where impl BlockSizeUser for CtOutWrapper where T: VariableOutputCore, - OutSize: ArraySize + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArraySize + IsLessOrEqual, { type BlockSize = T::BlockSize; } @@ -67,8 +62,7 @@ where impl UpdateCore for CtOutWrapper where T: VariableOutputCore, - OutSize: ArraySize + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArraySize + IsLessOrEqual, { #[inline] fn update_blocks(&mut self, blocks: &[Block]) { @@ -79,8 +73,7 @@ where impl OutputSizeUser for CtOutWrapper where T: VariableOutputCore, - OutSize: ArraySize + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArraySize + IsLessOrEqual, { type OutputSize = OutSize; } @@ -88,8 +81,7 @@ where impl BufferKindUser for CtOutWrapper where T: VariableOutputCore, - OutSize: ArraySize + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArraySize + IsLessOrEqual, { type BufferKind = T::BufferKind; } @@ -97,8 +89,7 @@ where impl FixedOutputCore for CtOutWrapper where T: VariableOutputCore, - OutSize: ArraySize + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArraySize + IsLessOrEqual, { #[inline] fn finalize_fixed_core( @@ -120,8 +111,7 @@ where impl Default for CtOutWrapper where T: VariableOutputCore, - OutSize: ArraySize + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArraySize + IsLessOrEqual, { #[inline] fn default() -> Self { @@ -135,8 +125,7 @@ where impl CustomizedInit for CtOutWrapper where T: VariableOutputCore + VarOutputCustomized, - OutSize: ArraySize + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArraySize + IsLessOrEqual, { #[inline] fn new_customized(customization: &[u8]) -> Self { @@ -150,8 +139,7 @@ where impl Reset for CtOutWrapper where T: VariableOutputCore, - OutSize: ArraySize + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArraySize + IsLessOrEqual, { #[inline] fn reset(&mut self) { @@ -162,8 +150,7 @@ where impl AlgorithmName for CtOutWrapper where T: VariableOutputCore + AlgorithmName, - OutSize: ArraySize + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArraySize + IsLessOrEqual, { fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { T::write_alg_name(f)?; @@ -176,16 +163,14 @@ where impl zeroize::ZeroizeOnDrop for CtOutWrapper where T: VariableOutputCore + zeroize::ZeroizeOnDrop, - OutSize: ArraySize + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArraySize + IsLessOrEqual, { } impl fmt::Debug for CtOutWrapper where T: VariableOutputCore + AlgorithmName, - OutSize: ArraySize + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArraySize + IsLessOrEqual, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { Self::write_alg_name(f) @@ -198,8 +183,7 @@ type CtVariableCoreWrapperSerializedStateSize = impl SerializableState for CtOutWrapper where T: VariableOutputCore + SerializableState, - OutSize: ArraySize + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArraySize + IsLessOrEqual, T::BlockSize: IsLess, Le: NonZero, T::SerializedStateSize: Add, diff --git a/digest/src/newtype/fixed.rs b/digest/src/newtype/fixed.rs index 5bef611f8..071860a38 100644 --- a/digest/src/newtype/fixed.rs +++ b/digest/src/newtype/fixed.rs @@ -5,6 +5,7 @@ macro_rules! newtype_fixed_hash { ( $(#[$attr:meta])* $v:vis struct $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); + impl: $($trait_name:ident)*; ) => { $(#[$attr])* $v struct $name$(<$gp: $bound>)? { @@ -12,6 +13,71 @@ macro_rules! newtype_fixed_hash { buffer: $crate::core_api::Buffer<$core_ty>, } + $crate::newtype_fixed_hash!( + impl_inner: $name$(<$gp: $bound>)?($core_ty); + $($trait_name)*; + ); + }; + + ( + $(#[$attr:meta])* + $v:vis struct $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); + oid: $oid:literal; + impl: $($trait_name:ident)*; + ) => { + $(#[$attr])* + $v struct $name$(<$gp: $bound>)? { + core: $core_ty, + buffer: $crate::core_api::Buffer<$core_ty>, + } + + #[cfg(feature = "oid")] + impl$(<$gp: $bound>)? $crate::const_oid::AssociatedOid for $name$(<$gp>)? { + const OID: $crate::const_oid::ObjectIdentifier = + $crate::const_oid::ObjectIdentifier::new_unwrap($oid); + } + + $crate::newtype_fixed_hash!( + impl_inner: $name$(<$gp: $bound>)?($core_ty); + $($trait_name)*; + ); + }; + + // Terminates `impl_inner` sequences. + ( + impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); ; + ) => {}; + + // Implements the set of traits common for fixed output hashes: + // `Default`, `Clone`, `HashMarker`, `Reset`, `FixedOutputReset`, `SerializableState` + ( + impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); + FixedHashTraits $($trait_name:ident)*; + ) => { + $crate::newtype_fixed_hash!( + impl_inner: $name$(<$gp: $bound>)?($core_ty); + BaseFixedTraits Default Clone HashMarker Reset FixedOutputReset SerializableState $($trait_name)*; + ); + }; + + // Implements basic fixed traits: + // `Debug`, `AlgorithmName`, `BlockSizeUser`, `OutputSizeUser`, + // `CoreProxy`, `Update`, and `FixedOutput`. + ( + impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); + BaseFixedTraits $($trait_name:ident)*; + ) => { + $crate::newtype_fixed_hash!( + impl_inner: $name$(<$gp: $bound>)?($core_ty); + Debug AlgorithmName BlockSizeUser OutputSizeUser CoreProxy Update FixedOutput $($trait_name)*; + ); + }; + + // Implements `Debug` + ( + impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); + Debug $($trait_name:ident)*; + ) => { impl$(<$gp: $bound>)? core::fmt::Debug for $name$(<$gp>)? { #[inline] fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { @@ -19,6 +85,14 @@ macro_rules! newtype_fixed_hash { } } + $crate::newtype_fixed_hash!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + }; + + // Implements `AlgorithmName` + ( + impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); + AlgorithmName $($trait_name:ident)*; + ) => { impl$(<$gp: $bound>)? $crate::crypto_common::AlgorithmName for $name$(<$gp>)? { #[inline] fn write_alg_name(f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { @@ -26,16 +100,84 @@ macro_rules! newtype_fixed_hash { } } - impl$(<$gp: $bound>)? Clone for $name$(<$gp>)? { + $crate::newtype_fixed_hash!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + }; + + // Implements `BlockSizeUser` + ( + impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); + BlockSizeUser $($trait_name:ident)*; + ) => { + impl$(<$gp: $bound>)? $crate::core_api::BlockSizeUser for $name$(<$gp>)? { + type BlockSize = <$core_ty as $crate::crypto_common::BlockSizeUser>::BlockSize; + } + + $crate::newtype_fixed_hash!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + }; + + // Implements `OutputSizeUser` + ( + impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); + OutputSizeUser $($trait_name:ident)*; + ) => { + impl$(<$gp: $bound>)? $crate::OutputSizeUser for $name$(<$gp>)? { + type OutputSize = <$core_ty as $crate::core_api::OutputSizeUser>::OutputSize; + } + + $crate::newtype_fixed_hash!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + }; + + // Implements `CoreProxy` + ( + impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); + CoreProxy $($trait_name:ident)*; + ) => { + impl$(<$gp: $bound>)? $crate::core_api::CoreProxy for $name$(<$gp>)? { + type Core = $core_ty; + } + + $crate::newtype_fixed_hash!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + }; + + // Implements `Update` + ( + impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); + Update $($trait_name:ident)*; + ) => { + impl$(<$gp: $bound>)? $crate::Update for $name$(<$gp>)? { #[inline] - fn clone(&self) -> Self { - Self { - core: Clone::clone(&self.core), - buffer: Clone::clone(&self.buffer), - } + fn update(&mut self, data: &[u8]) { + let Self { core, buffer } = self; + buffer.digest_blocks(data, |blocks| { + $crate::core_api::UpdateCore::update_blocks(core, blocks) + }); } } + $crate::newtype_fixed_hash!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + }; + + // Implements `FixedOutput` + ( + impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); + FixedOutput $($trait_name:ident)*; + ) => { + impl$(<$gp: $bound>)? $crate::FixedOutput for $name$(<$gp>)? { + #[inline] + fn finalize_into(mut self, out: &mut $crate::Output) { + let Self { core, buffer } = &mut self; + $crate::core_api::FixedOutputCore::finalize_fixed_core(core, buffer, out); + } + } + + $crate::newtype_fixed_hash!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + }; + + // Implements `Default` + ( + impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); + Default $($trait_name:ident)*; + ) => { impl$(<$gp: $bound>)? Default for $name$(<$gp>)? { #[inline] fn default() -> Self { @@ -46,22 +188,32 @@ macro_rules! newtype_fixed_hash { } } - impl$(<$gp: $bound>)? $crate::Reset for $name$(<$gp>)? { + $crate::newtype_fixed_hash!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + }; + + // Implements `Clone` + ( + impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); + Clone $($trait_name:ident)*; + ) => { + impl$(<$gp: $bound>)? Clone for $name$(<$gp>)? { #[inline] - fn reset(&mut self) { - $crate::Reset::reset(&mut self.core); - self.buffer.reset(); + fn clone(&self) -> Self { + Self { + core: Clone::clone(&self.core), + buffer: Clone::clone(&self.buffer), + } } } - impl$(<$gp: $bound>)? $crate::core_api::BlockSizeUser for $name$(<$gp>)? { - type BlockSize = <$core_ty as $crate::crypto_common::BlockSizeUser>::BlockSize; - } - - impl$(<$gp: $bound>)? $crate::OutputSizeUser for $name$(<$gp>)? { - type OutputSize = <$core_ty as $crate::core_api::OutputSizeUser>::OutputSize; - } + $crate::newtype_fixed_hash!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + }; + // Implements `HashMarker` and asserts that `$core_ty` implements it + ( + impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); + HashMarker $($trait_name:ident)*; + ) => { impl$(<$gp: $bound>)? $crate::HashMarker for $name$(<$gp>)? {} // Verify that `$core_ty` implements `HashMarker` @@ -71,28 +223,30 @@ macro_rules! newtype_fixed_hash { } }; - impl$(<$gp: $bound>)? $crate::core_api::CoreProxy for $name$(<$gp>)? { - type Core = $core_ty; - } + $crate::newtype_fixed_hash!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + }; - impl$(<$gp: $bound>)? $crate::Update for $name$(<$gp>)? { + // Implements `Reset` + ( + impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); + Reset $($trait_name:ident)*; + ) => { + impl$(<$gp: $bound>)? $crate::Reset for $name$(<$gp>)? { #[inline] - fn update(&mut self, data: &[u8]) { - let Self { core, buffer } = self; - buffer.digest_blocks(data, |blocks| { - $crate::core_api::UpdateCore::update_blocks(core, blocks) - }); + fn reset(&mut self) { + $crate::Reset::reset(&mut self.core); + self.buffer.reset(); } } - impl$(<$gp: $bound>)? $crate::FixedOutput for $name$(<$gp>)? { - #[inline] - fn finalize_into(mut self, out: &mut $crate::Output) { - let Self { core, buffer } = &mut self; - $crate::core_api::FixedOutputCore::finalize_fixed_core(core, buffer, out); - } - } + $crate::newtype_fixed_hash!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + }; + // Implements `FixedOutputReset` + ( + impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); + FixedOutputReset $($trait_name:ident)*; + ) => { impl$(<$gp: $bound>)? $crate::FixedOutputReset for $name$(<$gp>)? { #[inline] fn finalize_into_reset(&mut self, out: &mut $crate::Output) { @@ -102,6 +256,14 @@ macro_rules! newtype_fixed_hash { } } + $crate::newtype_fixed_hash!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + }; + + // Implements `SerializableState` + ( + impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); + SerializableState $($trait_name:ident)*; + ) => { impl$(<$gp: $bound>)? $crate::crypto_common::hazmat::SerializableState for $name$(<$gp>)? { type SerializedStateSize = $crate::typenum::Sum< <$core_ty as $crate::crypto_common::hazmat::SerializableState>::SerializedStateSize, @@ -150,22 +312,7 @@ macro_rules! newtype_fixed_hash { }) } } - }; - ( - $(#[$attr:meta])* - $v:vis struct $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); - oid: $oid:literal - ) => { - $crate::newtype_fixed_hash!( - $(#[$attr])* - $v struct $name$(<$gp: $bound>)?($core_ty); - ); - - #[cfg(feature = "oid")] - impl$(<$gp: $bound>)? $crate::const_oid::AssociatedOid for $name$(<$gp>)? { - const OID: $crate::const_oid::ObjectIdentifier = - $crate::const_oid::ObjectIdentifier::new_unwrap($oid); - } - }; + $crate::newtype_fixed_hash!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + } } diff --git a/digest/src/newtype/variable_ct.rs b/digest/src/newtype/variable_ct.rs index af16529f8..2bf0e1833 100644 --- a/digest/src/newtype/variable_ct.rs +++ b/digest/src/newtype/variable_ct.rs @@ -3,18 +3,18 @@ #[macro_export] macro_rules! newtype_ct_variable_hash { ( - $(#[$ct_attr:meta])* + $(#[$attr:meta])* $vis:vis struct $name:ident<$out_size:ident>($core_ty:ty); + exclude: SerializableState; // Ideally, we would use `$core_ty::OutputSize`, but unfortunately the compiler // does not accept such code. The likely reason is this issue: // https://github.com/rust-lang/rust/issues/79629 max_size: $max_size:ty; ) => { - $(#[$ct_attr])* + $(#[$attr])* $vis struct $name<$out_size> where - $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, - $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size, Output = $crate::typenum::True>, { core: $crate::core_api::CtOutWrapper<$core_ty, $out_size>, buffer: $crate::core_api::Buffer<$core_ty>, @@ -22,8 +22,7 @@ macro_rules! newtype_ct_variable_hash { impl<$out_size> core::fmt::Debug for $name<$out_size> where - $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, - $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size, Output = $crate::typenum::True>, { #[inline] fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { @@ -33,8 +32,7 @@ macro_rules! newtype_ct_variable_hash { impl<$out_size> $crate::crypto_common::AlgorithmName for $name<$out_size> where - $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, - $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size, Output = $crate::typenum::True>, { #[inline] fn write_alg_name(f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { @@ -44,8 +42,7 @@ macro_rules! newtype_ct_variable_hash { impl<$out_size> Clone for $name<$out_size> where - $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, - $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size, Output = $crate::typenum::True>, { #[inline] fn clone(&self) -> Self { @@ -58,8 +55,7 @@ macro_rules! newtype_ct_variable_hash { impl<$out_size> Default for $name<$out_size> where - $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, - $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size, Output = $crate::typenum::True>, { #[inline] fn default() -> Self { @@ -72,8 +68,7 @@ macro_rules! newtype_ct_variable_hash { impl<$out_size> $crate::Reset for $name<$out_size> where - $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, - $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size, Output = $crate::typenum::True>, { #[inline] fn reset(&mut self) { @@ -84,24 +79,21 @@ macro_rules! newtype_ct_variable_hash { impl<$out_size> $crate::core_api::BlockSizeUser for $name<$out_size> where - $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, - $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size, Output = $crate::typenum::True>, { type BlockSize = <$core_ty as $crate::crypto_common::BlockSizeUser>::BlockSize; } impl<$out_size> $crate::OutputSizeUser for $name<$out_size> where - $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, - $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size, Output = $crate::typenum::True>, { type OutputSize = $out_size; } impl<$out_size> $crate::HashMarker for $name<$out_size> where - $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, - $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size, Output = $crate::typenum::True>, {} // Verify that `$wrapped_ty` implements `HashMarker` @@ -117,16 +109,14 @@ macro_rules! newtype_ct_variable_hash { impl<$out_size> $crate::core_api::CoreProxy for $name<$out_size> where - $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, - $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size, Output = $crate::typenum::True>, { type Core = $crate::core_api::CtOutWrapper<$core_ty, $out_size>; } impl<$out_size> $crate::Update for $name<$out_size> where - $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, - $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size, Output = $crate::typenum::True>, { #[inline] fn update(&mut self, data: &[u8]) { @@ -139,8 +129,7 @@ macro_rules! newtype_ct_variable_hash { impl<$out_size> $crate::FixedOutput for $name<$out_size> where - $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, - $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size, Output = $crate::typenum::True>, { #[inline] fn finalize_into(mut self, out: &mut $crate::Output) { @@ -151,8 +140,7 @@ macro_rules! newtype_ct_variable_hash { impl<$out_size> $crate::FixedOutputReset for $name<$out_size> where - $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, - $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size, Output = $crate::typenum::True>, { #[inline] fn finalize_into_reset(&mut self, out: &mut $crate::Output) { @@ -161,11 +149,25 @@ macro_rules! newtype_ct_variable_hash { $crate::Reset::reset(self); } } + }; + ( + $(#[$attr:meta])* + $vis:vis struct $name:ident<$out_size:ident>($core_ty:ty); + // Ideally, we would use `$core_ty::OutputSize`, but unfortunately the compiler + // does not accept such code. The likely reason is this issue: + // https://github.com/rust-lang/rust/issues/79629 + max_size: $max_size:ty; + ) => { + $crate::newtype_ct_variable_hash!( + $(#[$attr])* + $vis struct $name<$out_size>($core_ty); + exclude: SerializableState; + max_size: $max_size; + ); impl<$out_size> $crate::crypto_common::hazmat::SerializableState for $name<$out_size> where - $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, - $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size, Output = $crate::typenum::True>, { type SerializedStateSize = $crate::typenum::Add1<$crate::typenum::Sum< < diff --git a/digest/src/newtype/variable_rt.rs b/digest/src/newtype/variable_rt.rs index 34542b260..8fff60951 100644 --- a/digest/src/newtype/variable_rt.rs +++ b/digest/src/newtype/variable_rt.rs @@ -2,11 +2,12 @@ #[macro_export] macro_rules! newtype_rt_variable_hash { ( - $(#[$rt_attr:meta])* - $rt_vis:vis struct $name:ident($core_ty:ty); + $(#[$attr:meta])* + $vis:vis struct $name:ident($core_ty:ty); + exclude: SerializableState; ) => { - $(#[$rt_attr])* - $rt_vis struct $name { + $(#[$attr])* + $vis struct $name { core: $core_ty, buffer: $crate::core_api::Buffer<$core_ty>, output_size: u8, @@ -152,6 +153,17 @@ macro_rules! newtype_rt_variable_hash { #[cfg(feature = "zeroize")] impl $crate::zeroize::ZeroizeOnDrop for $name {} + }; + + ( + $(#[$attr:meta])* + $vis:vis struct $name:ident($core_ty:ty); + ) => { + $crate::newtype_rt_variable_hash!( + $(#[$attr])* + $vis struct $name($core_ty); + exclude: SerializableState; + ); impl $crate::crypto_common::hazmat::SerializableState for $name { type SerializedStateSize = $crate::typenum::Add1<$crate::typenum::Sum< diff --git a/digest/src/newtype/xof.rs b/digest/src/newtype/xof.rs index 427a3371a..ab12e7779 100644 --- a/digest/src/newtype/xof.rs +++ b/digest/src/newtype/xof.rs @@ -7,7 +7,7 @@ macro_rules! newtype_xof_hash { $hasher_vis:vis struct $hasher_name:ident($hasher_core:ty); $(#[$reader_attr:meta])* $reader_vis:vis struct $reader_name:ident($reader_core:ty); - $(oid: $oid:literal)? + $(oid: $oid:literal;)? ) => { $(#[$attr])* $hasher_vis struct $hasher_name { diff --git a/digest/tests/dummy_fixed.rs b/digest/tests/dummy_fixed.rs index 169bb50ab..f6f72399a 100644 --- a/digest/tests/dummy_fixed.rs +++ b/digest/tests/dummy_fixed.rs @@ -80,4 +80,22 @@ mod block_api { digest::newtype_fixed_hash!( /// Primitive XOR hasher for testing purposes pub struct FixedHash(block_api::FixedHashCore); + impl: BaseFixedTraits Default Clone HashMarker Reset FixedOutputReset; +); +digest::newtype_fixed_hash!( + /// Primitive XOR hasher for testing purposes + pub struct FixedHashWithSer(block_api::FixedHashCore); + impl: FixedHashTraits; +); +digest::newtype_fixed_hash!( + /// Primitive XOR hasher for testing purposes + pub struct FixedHashWithOid(block_api::FixedHashCore); + oid: "0.1.2.3.4.5"; + impl: BaseFixedTraits Default Clone HashMarker Reset FixedOutputReset; +); +digest::newtype_fixed_hash!( + /// Primitive XOR hasher for testing purposes + pub struct FixedHashWithOidSer(block_api::FixedHashCore); + oid: "0.1.2.3.4.5"; + impl: FixedHashTraits; ); From 0bd68a446c10e0d9678f428aa8df557312c2845d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Mon, 19 May 2025 14:23:32 +0300 Subject: [PATCH 22/31] tweak cof macro --- digest/src/newtype/fixed.rs | 33 ++-- digest/src/newtype/xof.rs | 290 ++++++++++++++++++++++++++---------- 2 files changed, 232 insertions(+), 91 deletions(-) diff --git a/digest/src/newtype/fixed.rs b/digest/src/newtype/fixed.rs index 071860a38..1de3c80b0 100644 --- a/digest/src/newtype/fixed.rs +++ b/digest/src/newtype/fixed.rs @@ -25,22 +25,17 @@ macro_rules! newtype_fixed_hash { oid: $oid:literal; impl: $($trait_name:ident)*; ) => { - $(#[$attr])* - $v struct $name$(<$gp: $bound>)? { - core: $core_ty, - buffer: $crate::core_api::Buffer<$core_ty>, - } + $crate::newtype_fixed_hash!( + $(#[$attr])* + $v struct $name$(<$gp: $bound>)?($core_ty); + impl: $($trait_name)*; + ); #[cfg(feature = "oid")] impl$(<$gp: $bound>)? $crate::const_oid::AssociatedOid for $name$(<$gp>)? { const OID: $crate::const_oid::ObjectIdentifier = $crate::const_oid::ObjectIdentifier::new_unwrap($oid); } - - $crate::newtype_fixed_hash!( - impl_inner: $name$(<$gp: $bound>)?($core_ty); - $($trait_name)*; - ); }; // Terminates `impl_inner` sequences. @@ -191,6 +186,24 @@ macro_rules! newtype_fixed_hash { $crate::newtype_fixed_hash!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); }; + // Implements `CustomizedInit` + ( + impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); + CustomizedInit $($trait_name:ident)*; + ) => { + impl$(<$gp: $bound>)? $crate::CustomizedInit for $name$(<$gp>)? { + #[inline] + fn new_customized(customization: &[u8]) -> Self { + Self { + core: $crate::CustomizedInit::new_customized(customization), + buffer: Default::default(), + } + } + } + + $crate::newtype_fixed_hash!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + }; + // Implements `Clone` ( impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); diff --git a/digest/src/newtype/xof.rs b/digest/src/newtype/xof.rs index ab12e7779..3597c21c4 100644 --- a/digest/src/newtype/xof.rs +++ b/digest/src/newtype/xof.rs @@ -3,78 +3,226 @@ #[macro_export] macro_rules! newtype_xof_hash { ( - $(#[$attr:meta])* + $(#[$hasher_attr:meta])* $hasher_vis:vis struct $hasher_name:ident($hasher_core:ty); + $(oid: $oid:literal;)? + impl: $($hasher_trait_name:ident)*; + $(#[$reader_attr:meta])* $reader_vis:vis struct $reader_name:ident($reader_core:ty); - $(oid: $oid:literal;)? + impl: $($reader_trait_name:ident)*; ) => { - $(#[$attr])* + $(#[$hasher_attr])* $hasher_vis struct $hasher_name { core: $hasher_core, buffer: $crate::core_api::Buffer<$hasher_core>, } - impl core::fmt::Debug for $hasher_name { + impl $crate::ExtendableOutput for $hasher_name { + type Reader = $reader_name; + + #[inline] + fn finalize_xof(mut self) -> Self::Reader { + let Self { core, buffer } = &mut self; + let core = <$hasher_core as $crate::core_api::ExtendableOutputCore>::finalize_xof_core(core, buffer); + let buffer = Default::default(); + Self::Reader { core, buffer } + } + } + + $( + #[cfg(feature = "oid")] + impl $crate::const_oid::AssociatedOid for $hasher_name { + const OID: $crate::const_oid::ObjectIdentifier = + $crate::const_oid::ObjectIdentifier::new_unwrap($oid); + } + )? + + $crate::newtype_xof_hash!( + impl_inner: $hasher_name($hasher_core); + $($hasher_trait_name)*; + ); + + $(#[$reader_attr])* + $reader_vis struct $reader_name { + core: $reader_core, + buffer: $crate::block_buffer::ReadBuffer<<$reader_core as $crate::core_api::BlockSizeUser>::BlockSize>, + } + + impl $crate::XofReader for $reader_name { + #[inline] + fn read(&mut self, buf: &mut [u8]) { + let Self { core, buffer } = self; + buffer.read(buf, |block| { + *block = $crate::core_api::XofReaderCore::read_block(core); + }); + } + } + + $crate::newtype_xof_hash!( + impl_inner: $reader_name($reader_core); + $($reader_trait_name)*; + ); + }; + + // Terminates `impl_inner` sequences. + ( + impl_inner: $name:ident($core_ty:ty); ; + ) => {}; + + // Implements the set of traits common for XOF hashers + ( + impl_inner: $name:ident($core_ty:ty); + XofHasherTraits $($trait_name:ident)*; + ) => { + $crate::newtype_xof_hash!( + impl_inner: $name($core_ty); + Debug AlgorithmName Clone Default BlockSizeUser CoreProxy HashMarker Update SerializableState Reset ExtendableOutputReset $($trait_name)* ; + ); + }; + + // Implements the set of traits common for XOF readers + ( + impl_inner: $name:ident($core_ty:ty); + XofReaderTraits $($trait_name:ident)*; + ) => { + $crate::newtype_xof_hash!( + impl_inner: $name($core_ty); + Debug Clone BlockSizeUser CoreProxy + $($trait_name)*;); + }; + + // Implements `Debug` + ( + impl_inner: $name:ident($core_ty:ty); + Debug $($trait_name:ident)*; + ) => { + impl core::fmt::Debug for $name { #[inline] fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.write_str(concat!(stringify!($hasher_name), " { ... }")) + f.write_str(concat!(stringify!($name), " { ... }")) } } - impl $crate::crypto_common::AlgorithmName for $hasher_name { + $crate::newtype_xof_hash!(impl_inner: $name($core_ty); $($trait_name)*;); + }; + + // Implements `AlgorithmName` + ( + impl_inner: $name:ident($core_ty:ty); + AlgorithmName $($trait_name:ident)*; + ) => { + impl $crate::crypto_common::AlgorithmName for $name { #[inline] fn write_alg_name(f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { - <$hasher_core as $crate::crypto_common::AlgorithmName>::write_alg_name(f) + <$core_ty as $crate::crypto_common::AlgorithmName>::write_alg_name(f) } } - impl Clone for $hasher_name { + $crate::newtype_xof_hash!(impl_inner: $name($core_ty); $($trait_name)*;); + }; + + // Implements `Default` + ( + impl_inner: $name:ident($core_ty:ty); + Default $($trait_name:ident)*; + ) => { + impl Default for $name { #[inline] - fn clone(&self) -> Self { + fn default() -> Self { Self { - core: Clone::clone(&self.core), - buffer: Clone::clone(&self.buffer), + core: Default::default(), + buffer: Default::default(), } } } - impl Default for $hasher_name { + $crate::newtype_xof_hash!(impl_inner: $name($core_ty); $($trait_name)*;); + }; + + // Implements `CustomizedInit` + ( + impl_inner: $name:ident($core_ty:ty); + CustomizedInit $($trait_name:ident)*; + ) => { + impl $crate::CustomizedInit for $name { #[inline] - fn default() -> Self { + fn new_customized(customization: &[u8]) -> Self { Self { - core: Default::default(), + core: $crate::CustomizedInit::new_customized(customization), buffer: Default::default(), } } } - impl $crate::Reset for $hasher_name { + $crate::newtype_xof_hash!(impl_inner: $name($core_ty); $($trait_name)*;); + }; + + // Implements `Clone` + ( + impl_inner: $name:ident($core_ty:ty); + Clone $($trait_name:ident)*; + ) => { + impl Clone for $name { #[inline] - fn reset(&mut self) { - $crate::Reset::reset(&mut self.core); - self.buffer.reset(); + fn clone(&self) -> Self { + Self { + core: Clone::clone(&self.core), + buffer: Clone::clone(&self.buffer), + } } } - impl $crate::core_api::BlockSizeUser for $hasher_name { - type BlockSize = <$hasher_core as $crate::crypto_common::BlockSizeUser>::BlockSize; + $crate::newtype_xof_hash!(impl_inner: $name($core_ty); $($trait_name)*;); + }; + + // Implements `BlockSizeUser` + ( + impl_inner: $name:ident($core_ty:ty); + BlockSizeUser $($trait_name:ident)*; + ) => { + impl $crate::core_api::BlockSizeUser for $name { + type BlockSize = <$core_ty as $crate::crypto_common::BlockSizeUser>::BlockSize; } - impl $crate::HashMarker for $hasher_name {} + $crate::newtype_xof_hash!(impl_inner: $name($core_ty); $($trait_name)*;); + }; - // Verify that `$hasher_core` implements `HashMarker` + // Implements `CoreProxy` + ( + impl_inner: $name:ident($core_ty:ty); + CoreProxy $($trait_name:ident)*; + ) => { + impl $crate::core_api::CoreProxy for $name { + type Core = $core_ty; + } + + $crate::newtype_xof_hash!(impl_inner: $name($core_ty); $($trait_name)*;); + }; + + // Implements `HashMarker` + ( + impl_inner: $name:ident($core_ty:ty); + HashMarker $($trait_name:ident)*; + ) => { + impl $crate::HashMarker for $name {} + + // Verify that `$core_ty` implements `HashMarker` const _: () = { - fn check(v: &$hasher_core) { + fn check(v: &$core_ty) { v as &dyn $crate::HashMarker; } }; - impl $crate::core_api::CoreProxy for $hasher_name { - type Core = $hasher_core; - } + $crate::newtype_xof_hash!(impl_inner: $name($core_ty); $($trait_name)*;); + }; - impl $crate::Update for $hasher_name { + // Implements `Update` + ( + impl_inner: $name:ident($core_ty:ty); + Update $($trait_name:ident)*; + ) => { + impl $crate::Update for $name { #[inline] fn update(&mut self, data: &[u8]) { let Self { core, buffer } = self; @@ -84,35 +232,54 @@ macro_rules! newtype_xof_hash { } } - impl $crate::ExtendableOutput for $hasher_name { - type Reader = $reader_name; + $crate::newtype_xof_hash!(impl_inner: $name($core_ty); $($trait_name)*;); + }; + // Implements `Reset` + ( + impl_inner: $name:ident($core_ty:ty); + Reset $($trait_name:ident)*; + ) => { + impl $crate::Reset for $name { #[inline] - fn finalize_xof(mut self) -> Self::Reader { - let Self { core, buffer } = &mut self; - let core = <$hasher_core as $crate::core_api::ExtendableOutputCore>::finalize_xof_core(core, buffer); - let buffer = Default::default(); - Self::Reader { core, buffer } + fn reset(&mut self) { + $crate::Reset::reset(&mut self.core); + self.buffer.reset(); } } - impl $crate::ExtendableOutputReset for $hasher_name { + $crate::newtype_xof_hash!(impl_inner: $name($core_ty); $($trait_name)*;); + }; + + // Implements `ExtendableOutputReset` + ( + impl_inner: $name:ident($core_ty:ty); + ExtendableOutputReset $($trait_name:ident)*; + ) => { + impl $crate::ExtendableOutputReset for $name { #[inline] fn finalize_xof_reset(&mut self) -> Self::Reader { let Self { core, buffer } = self; - let core = <$hasher_core as $crate::core_api::ExtendableOutputCore>::finalize_xof_core(core, buffer); + let core = <$core_ty as $crate::core_api::ExtendableOutputCore>::finalize_xof_core(core, buffer); $crate::Reset::reset(self); let buffer = Default::default(); Self::Reader { core, buffer } } } + $crate::newtype_xof_hash!(impl_inner: $name($core_ty); $($trait_name)*;); + }; - impl $crate::crypto_common::hazmat::SerializableState for $hasher_name { + // Implements `SerializableState` + ( + impl_inner: $name:ident($core_ty:ty); + SerializableState $($trait_name:ident)*; + ) => { + impl $crate::crypto_common::hazmat::SerializableState for $name { type SerializedStateSize = $crate::typenum::Sum< - <$hasher_core as $crate::crypto_common::hazmat::SerializableState>::SerializedStateSize, + <$core_ty as $crate::crypto_common::hazmat::SerializableState>::SerializedStateSize, $crate::typenum::Add1< - <$hasher_core as $crate::core_api::BlockSizeUser>::BlockSize + <$core_ty as $crate::core_api::BlockSizeUser>::BlockSize > >; @@ -146,56 +313,17 @@ macro_rules! newtype_xof_hash { }; let (serialized_core, remaining_buffer) = serialized_state - .split_ref::<<$hasher_core as SerializableState>::SerializedStateSize>(); + .split_ref::<<$core_ty as SerializableState>::SerializedStateSize>(); let (serialized_pos, serialized_data) = remaining_buffer.split_ref::(); Ok(Self { - core: <$hasher_core as SerializableState>::deserialize(serialized_core)?, + core: <$core_ty as SerializableState>::deserialize(serialized_core)?, buffer: BlockBuffer::try_new(&serialized_data[..serialized_pos[0].into()]) .map_err(|_| DeserializeStateError)?, }) } } - $( - #[cfg(feature = "oid")] - impl $crate::const_oid::AssociatedOid for $hasher_name { - const OID: $crate::const_oid::ObjectIdentifier = - $crate::const_oid::ObjectIdentifier::new_unwrap($oid); - } - )? - - $(#[$reader_attr])* - $reader_vis struct $reader_name { - core: $reader_core, - buffer: $crate::block_buffer::ReadBuffer<<$reader_core as $crate::core_api::BlockSizeUser>::BlockSize>, - } - - impl core::fmt::Debug for $reader_name { - #[inline] - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.write_str(concat!(stringify!($reader_name), " { ... }")) - } - } - - impl Clone for $reader_name { - #[inline] - fn clone(&self) -> Self { - Self { - core: Clone::clone(&self.core), - buffer: Clone::clone(&self.buffer), - } - } - } - - impl $crate::XofReader for $reader_name { - #[inline] - fn read(&mut self, buf: &mut [u8]) { - let Self { core, buffer } = self; - buffer.read(buf, |block| { - *block = $crate::core_api::XofReaderCore::read_block(core); - }); - } - } + $crate::newtype_xof_hash!(impl_inner: $name($core_ty); $($trait_name)*;); }; } From f3d7a4fd41036494ee89bb3f282a6d01dfcf072a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Mon, 19 May 2025 14:58:37 +0300 Subject: [PATCH 23/31] rename macros --- digest/src/{newtype.rs => buffer_macros.rs} | 0 .../src/{newtype => buffer_macros}/fixed.rs | 41 +++++++++---------- .../{newtype => buffer_macros}/variable_ct.rs | 8 ++-- .../{newtype => buffer_macros}/variable_rt.rs | 7 ++-- digest/src/{newtype => buffer_macros}/xof.rs | 37 ++++++++--------- digest/src/lib.rs | 2 +- digest/tests/dummy_fixed.rs | 8 ++-- 7 files changed, 51 insertions(+), 52 deletions(-) rename digest/src/{newtype.rs => buffer_macros.rs} (100%) rename digest/src/{newtype => buffer_macros}/fixed.rs (85%) rename digest/src/{newtype => buffer_macros}/variable_ct.rs (97%) rename digest/src/{newtype => buffer_macros}/variable_rt.rs (96%) rename digest/src/{newtype => buffer_macros}/xof.rs (88%) diff --git a/digest/src/newtype.rs b/digest/src/buffer_macros.rs similarity index 100% rename from digest/src/newtype.rs rename to digest/src/buffer_macros.rs diff --git a/digest/src/newtype/fixed.rs b/digest/src/buffer_macros/fixed.rs similarity index 85% rename from digest/src/newtype/fixed.rs rename to digest/src/buffer_macros/fixed.rs index 1de3c80b0..e86ef23b4 100644 --- a/digest/src/newtype/fixed.rs +++ b/digest/src/buffer_macros/fixed.rs @@ -1,7 +1,6 @@ -/// Creates a newtype wrapper around another type and -/// delegates implementation of `digest` traits to it. +/// Creates a buffered wrapper around block-level "core" type which implements fixed output size traits. #[macro_export] -macro_rules! newtype_fixed_hash { +macro_rules! buffer_fixed { ( $(#[$attr:meta])* $v:vis struct $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); @@ -13,7 +12,7 @@ macro_rules! newtype_fixed_hash { buffer: $crate::core_api::Buffer<$core_ty>, } - $crate::newtype_fixed_hash!( + $crate::buffer_fixed!( impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*; ); @@ -25,7 +24,7 @@ macro_rules! newtype_fixed_hash { oid: $oid:literal; impl: $($trait_name:ident)*; ) => { - $crate::newtype_fixed_hash!( + $crate::buffer_fixed!( $(#[$attr])* $v struct $name$(<$gp: $bound>)?($core_ty); impl: $($trait_name)*; @@ -49,7 +48,7 @@ macro_rules! newtype_fixed_hash { impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); FixedHashTraits $($trait_name:ident)*; ) => { - $crate::newtype_fixed_hash!( + $crate::buffer_fixed!( impl_inner: $name$(<$gp: $bound>)?($core_ty); BaseFixedTraits Default Clone HashMarker Reset FixedOutputReset SerializableState $($trait_name)*; ); @@ -62,7 +61,7 @@ macro_rules! newtype_fixed_hash { impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); BaseFixedTraits $($trait_name:ident)*; ) => { - $crate::newtype_fixed_hash!( + $crate::buffer_fixed!( impl_inner: $name$(<$gp: $bound>)?($core_ty); Debug AlgorithmName BlockSizeUser OutputSizeUser CoreProxy Update FixedOutput $($trait_name)*; ); @@ -80,7 +79,7 @@ macro_rules! newtype_fixed_hash { } } - $crate::newtype_fixed_hash!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + $crate::buffer_fixed!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); }; // Implements `AlgorithmName` @@ -95,7 +94,7 @@ macro_rules! newtype_fixed_hash { } } - $crate::newtype_fixed_hash!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + $crate::buffer_fixed!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); }; // Implements `BlockSizeUser` @@ -107,7 +106,7 @@ macro_rules! newtype_fixed_hash { type BlockSize = <$core_ty as $crate::crypto_common::BlockSizeUser>::BlockSize; } - $crate::newtype_fixed_hash!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + $crate::buffer_fixed!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); }; // Implements `OutputSizeUser` @@ -119,7 +118,7 @@ macro_rules! newtype_fixed_hash { type OutputSize = <$core_ty as $crate::core_api::OutputSizeUser>::OutputSize; } - $crate::newtype_fixed_hash!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + $crate::buffer_fixed!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); }; // Implements `CoreProxy` @@ -131,7 +130,7 @@ macro_rules! newtype_fixed_hash { type Core = $core_ty; } - $crate::newtype_fixed_hash!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + $crate::buffer_fixed!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); }; // Implements `Update` @@ -149,7 +148,7 @@ macro_rules! newtype_fixed_hash { } } - $crate::newtype_fixed_hash!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + $crate::buffer_fixed!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); }; // Implements `FixedOutput` @@ -165,7 +164,7 @@ macro_rules! newtype_fixed_hash { } } - $crate::newtype_fixed_hash!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + $crate::buffer_fixed!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); }; // Implements `Default` @@ -183,7 +182,7 @@ macro_rules! newtype_fixed_hash { } } - $crate::newtype_fixed_hash!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + $crate::buffer_fixed!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); }; // Implements `CustomizedInit` @@ -201,7 +200,7 @@ macro_rules! newtype_fixed_hash { } } - $crate::newtype_fixed_hash!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + $crate::buffer_fixed!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); }; // Implements `Clone` @@ -219,7 +218,7 @@ macro_rules! newtype_fixed_hash { } } - $crate::newtype_fixed_hash!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + $crate::buffer_fixed!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); }; // Implements `HashMarker` and asserts that `$core_ty` implements it @@ -236,7 +235,7 @@ macro_rules! newtype_fixed_hash { } }; - $crate::newtype_fixed_hash!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + $crate::buffer_fixed!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); }; // Implements `Reset` @@ -252,7 +251,7 @@ macro_rules! newtype_fixed_hash { } } - $crate::newtype_fixed_hash!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + $crate::buffer_fixed!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); }; // Implements `FixedOutputReset` @@ -269,7 +268,7 @@ macro_rules! newtype_fixed_hash { } } - $crate::newtype_fixed_hash!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + $crate::buffer_fixed!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); }; // Implements `SerializableState` @@ -326,6 +325,6 @@ macro_rules! newtype_fixed_hash { } } - $crate::newtype_fixed_hash!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + $crate::buffer_fixed!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); } } diff --git a/digest/src/newtype/variable_ct.rs b/digest/src/buffer_macros/variable_ct.rs similarity index 97% rename from digest/src/newtype/variable_ct.rs rename to digest/src/buffer_macros/variable_ct.rs index 2bf0e1833..da5f6abc8 100644 --- a/digest/src/newtype/variable_ct.rs +++ b/digest/src/buffer_macros/variable_ct.rs @@ -1,7 +1,7 @@ -/// Creates a newtype wrapper around another type and -/// delegates implementation of `digest` traits to it. +/// Creates a buffered wrapper around block-level "core" type which implements variable output size traits +/// with output size selected at compile time. #[macro_export] -macro_rules! newtype_ct_variable_hash { +macro_rules! buffer_ct_variable { ( $(#[$attr:meta])* $vis:vis struct $name:ident<$out_size:ident>($core_ty:ty); @@ -158,7 +158,7 @@ macro_rules! newtype_ct_variable_hash { // https://github.com/rust-lang/rust/issues/79629 max_size: $max_size:ty; ) => { - $crate::newtype_ct_variable_hash!( + $crate::buffer_ct_variable!( $(#[$attr])* $vis struct $name<$out_size>($core_ty); exclude: SerializableState; diff --git a/digest/src/newtype/variable_rt.rs b/digest/src/buffer_macros/variable_rt.rs similarity index 96% rename from digest/src/newtype/variable_rt.rs rename to digest/src/buffer_macros/variable_rt.rs index 8fff60951..14bab748e 100644 --- a/digest/src/newtype/variable_rt.rs +++ b/digest/src/buffer_macros/variable_rt.rs @@ -1,6 +1,7 @@ -/// Wrap +/// Creates a buffered wrapper around block-level "core" type which implements variable output size traits +/// with output size selected at run time. #[macro_export] -macro_rules! newtype_rt_variable_hash { +macro_rules! buffer_rt_variable { ( $(#[$attr:meta])* $vis:vis struct $name:ident($core_ty:ty); @@ -159,7 +160,7 @@ macro_rules! newtype_rt_variable_hash { $(#[$attr:meta])* $vis:vis struct $name:ident($core_ty:ty); ) => { - $crate::newtype_rt_variable_hash!( + $crate::buffer_rt_variable!( $(#[$attr])* $vis struct $name($core_ty); exclude: SerializableState; diff --git a/digest/src/newtype/xof.rs b/digest/src/buffer_macros/xof.rs similarity index 88% rename from digest/src/newtype/xof.rs rename to digest/src/buffer_macros/xof.rs index 3597c21c4..c17d8b7cc 100644 --- a/digest/src/newtype/xof.rs +++ b/digest/src/buffer_macros/xof.rs @@ -1,7 +1,6 @@ -/// Creates a newtype wrapper around another type and -/// delegates implementation of `digest` traits to it. +/// Creates a buffered wrapper around block-level "core" type which implements extendable output size traits. #[macro_export] -macro_rules! newtype_xof_hash { +macro_rules! buffer_xof { ( $(#[$hasher_attr:meta])* $hasher_vis:vis struct $hasher_name:ident($hasher_core:ty); @@ -38,7 +37,7 @@ macro_rules! newtype_xof_hash { } )? - $crate::newtype_xof_hash!( + $crate::buffer_xof!( impl_inner: $hasher_name($hasher_core); $($hasher_trait_name)*; ); @@ -59,7 +58,7 @@ macro_rules! newtype_xof_hash { } } - $crate::newtype_xof_hash!( + $crate::buffer_xof!( impl_inner: $reader_name($reader_core); $($reader_trait_name)*; ); @@ -75,7 +74,7 @@ macro_rules! newtype_xof_hash { impl_inner: $name:ident($core_ty:ty); XofHasherTraits $($trait_name:ident)*; ) => { - $crate::newtype_xof_hash!( + $crate::buffer_xof!( impl_inner: $name($core_ty); Debug AlgorithmName Clone Default BlockSizeUser CoreProxy HashMarker Update SerializableState Reset ExtendableOutputReset $($trait_name)* ; ); @@ -86,7 +85,7 @@ macro_rules! newtype_xof_hash { impl_inner: $name:ident($core_ty:ty); XofReaderTraits $($trait_name:ident)*; ) => { - $crate::newtype_xof_hash!( + $crate::buffer_xof!( impl_inner: $name($core_ty); Debug Clone BlockSizeUser CoreProxy $($trait_name)*;); @@ -104,7 +103,7 @@ macro_rules! newtype_xof_hash { } } - $crate::newtype_xof_hash!(impl_inner: $name($core_ty); $($trait_name)*;); + $crate::buffer_xof!(impl_inner: $name($core_ty); $($trait_name)*;); }; // Implements `AlgorithmName` @@ -119,7 +118,7 @@ macro_rules! newtype_xof_hash { } } - $crate::newtype_xof_hash!(impl_inner: $name($core_ty); $($trait_name)*;); + $crate::buffer_xof!(impl_inner: $name($core_ty); $($trait_name)*;); }; // Implements `Default` @@ -137,7 +136,7 @@ macro_rules! newtype_xof_hash { } } - $crate::newtype_xof_hash!(impl_inner: $name($core_ty); $($trait_name)*;); + $crate::buffer_xof!(impl_inner: $name($core_ty); $($trait_name)*;); }; // Implements `CustomizedInit` @@ -155,7 +154,7 @@ macro_rules! newtype_xof_hash { } } - $crate::newtype_xof_hash!(impl_inner: $name($core_ty); $($trait_name)*;); + $crate::buffer_xof!(impl_inner: $name($core_ty); $($trait_name)*;); }; // Implements `Clone` @@ -173,7 +172,7 @@ macro_rules! newtype_xof_hash { } } - $crate::newtype_xof_hash!(impl_inner: $name($core_ty); $($trait_name)*;); + $crate::buffer_xof!(impl_inner: $name($core_ty); $($trait_name)*;); }; // Implements `BlockSizeUser` @@ -185,7 +184,7 @@ macro_rules! newtype_xof_hash { type BlockSize = <$core_ty as $crate::crypto_common::BlockSizeUser>::BlockSize; } - $crate::newtype_xof_hash!(impl_inner: $name($core_ty); $($trait_name)*;); + $crate::buffer_xof!(impl_inner: $name($core_ty); $($trait_name)*;); }; // Implements `CoreProxy` @@ -197,7 +196,7 @@ macro_rules! newtype_xof_hash { type Core = $core_ty; } - $crate::newtype_xof_hash!(impl_inner: $name($core_ty); $($trait_name)*;); + $crate::buffer_xof!(impl_inner: $name($core_ty); $($trait_name)*;); }; // Implements `HashMarker` @@ -214,7 +213,7 @@ macro_rules! newtype_xof_hash { } }; - $crate::newtype_xof_hash!(impl_inner: $name($core_ty); $($trait_name)*;); + $crate::buffer_xof!(impl_inner: $name($core_ty); $($trait_name)*;); }; // Implements `Update` @@ -232,7 +231,7 @@ macro_rules! newtype_xof_hash { } } - $crate::newtype_xof_hash!(impl_inner: $name($core_ty); $($trait_name)*;); + $crate::buffer_xof!(impl_inner: $name($core_ty); $($trait_name)*;); }; // Implements `Reset` @@ -248,7 +247,7 @@ macro_rules! newtype_xof_hash { } } - $crate::newtype_xof_hash!(impl_inner: $name($core_ty); $($trait_name)*;); + $crate::buffer_xof!(impl_inner: $name($core_ty); $($trait_name)*;); }; // Implements `ExtendableOutputReset` @@ -267,7 +266,7 @@ macro_rules! newtype_xof_hash { } } - $crate::newtype_xof_hash!(impl_inner: $name($core_ty); $($trait_name)*;); + $crate::buffer_xof!(impl_inner: $name($core_ty); $($trait_name)*;); }; // Implements `SerializableState` @@ -324,6 +323,6 @@ macro_rules! newtype_xof_hash { } } - $crate::newtype_xof_hash!(impl_inner: $name($core_ty); $($trait_name)*;); + $crate::buffer_xof!(impl_inner: $name($core_ty); $($trait_name)*;); }; } diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 9ec84531d..2e64ff946 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -50,12 +50,12 @@ use alloc::boxed::Box; #[cfg(feature = "dev")] pub mod dev; +mod buffer_macros; #[cfg(feature = "core-api")] pub mod core_api; mod digest; #[cfg(feature = "mac")] mod mac; -mod newtype; mod xof_fixed; #[cfg(feature = "core-api")] diff --git a/digest/tests/dummy_fixed.rs b/digest/tests/dummy_fixed.rs index f6f72399a..da81213bf 100644 --- a/digest/tests/dummy_fixed.rs +++ b/digest/tests/dummy_fixed.rs @@ -77,23 +77,23 @@ mod block_api { } } -digest::newtype_fixed_hash!( +digest::buffer_fixed!( /// Primitive XOR hasher for testing purposes pub struct FixedHash(block_api::FixedHashCore); impl: BaseFixedTraits Default Clone HashMarker Reset FixedOutputReset; ); -digest::newtype_fixed_hash!( +digest::buffer_fixed!( /// Primitive XOR hasher for testing purposes pub struct FixedHashWithSer(block_api::FixedHashCore); impl: FixedHashTraits; ); -digest::newtype_fixed_hash!( +digest::buffer_fixed!( /// Primitive XOR hasher for testing purposes pub struct FixedHashWithOid(block_api::FixedHashCore); oid: "0.1.2.3.4.5"; impl: BaseFixedTraits Default Clone HashMarker Reset FixedOutputReset; ); -digest::newtype_fixed_hash!( +digest::buffer_fixed!( /// Primitive XOR hasher for testing purposes pub struct FixedHashWithOidSer(block_api::FixedHashCore); oid: "0.1.2.3.4.5"; From 844f04357ae1dfaa6b06c253bff441df40402d07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Sun, 25 May 2025 11:10:08 +0300 Subject: [PATCH 24/31] Add MAC support to `buffer_fixed` --- digest/src/buffer_macros/fixed.rs | 250 +++++++++++++++++++++++------- 1 file changed, 196 insertions(+), 54 deletions(-) diff --git a/digest/src/buffer_macros/fixed.rs b/digest/src/buffer_macros/fixed.rs index e86ef23b4..2bc01a97d 100644 --- a/digest/src/buffer_macros/fixed.rs +++ b/digest/src/buffer_macros/fixed.rs @@ -3,35 +3,39 @@ macro_rules! buffer_fixed { ( $(#[$attr:meta])* - $v:vis struct $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); + $v:vis struct $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); impl: $($trait_name:ident)*; ) => { $(#[$attr])* - $v struct $name$(<$gp: $bound>)? { + $v struct $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? { core: $core_ty, buffer: $crate::core_api::Buffer<$core_ty>, } $crate::buffer_fixed!( - impl_inner: $name$(<$gp: $bound>)?($core_ty); + impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*; ); }; ( $(#[$attr:meta])* - $v:vis struct $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); + $v:vis struct $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); oid: $oid:literal; impl: $($trait_name:ident)*; ) => { $crate::buffer_fixed!( $(#[$attr])* - $v struct $name$(<$gp: $bound>)?($core_ty); + $v struct $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); impl: $($trait_name)*; ); #[cfg(feature = "oid")] - impl$(<$gp: $bound>)? $crate::const_oid::AssociatedOid for $name$(<$gp>)? { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::const_oid::AssociatedOid for $name$(< $( $lt ),+ >)? { const OID: $crate::const_oid::ObjectIdentifier = $crate::const_oid::ObjectIdentifier::new_unwrap($oid); } @@ -39,106 +43,154 @@ macro_rules! buffer_fixed { // Terminates `impl_inner` sequences. ( - impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); ; + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); + ; ) => {}; // Implements the set of traits common for fixed output hashes: // `Default`, `Clone`, `HashMarker`, `Reset`, `FixedOutputReset`, `SerializableState` ( - impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); FixedHashTraits $($trait_name:ident)*; ) => { $crate::buffer_fixed!( - impl_inner: $name$(<$gp: $bound>)?($core_ty); + impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); BaseFixedTraits Default Clone HashMarker Reset FixedOutputReset SerializableState $($trait_name)*; ); }; + // Implements the set of traits common for MAC functions: + // `Debug`, `OutputSizeUser`, `CoreProxy`, `Update`, `FixedOutput`, `Clone`, `MacMarker`. + ( + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); + MacTraits $($trait_name:ident)*; + ) => { + $crate::buffer_fixed!( + impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); + Debug OutputSizeUser CoreProxy Update FixedOutput Clone MacMarker $($trait_name)*; + ); + }; + + // Implements the set of traits common for resettable MAC functions: + // `Debug`, `OutputSizeUser`, `CoreProxy`, `Update`, `FixedOutput`, `Clone`, `MacMarker`, + // `Reset`, `FixedOutputReset`. + ( + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); + ResetMacTraits $($trait_name:ident)*; + ) => { + $crate::buffer_fixed!( + impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); + MacTraits Reset FixedOutputReset $($trait_name)*; + ); + }; + // Implements basic fixed traits: // `Debug`, `AlgorithmName`, `BlockSizeUser`, `OutputSizeUser`, // `CoreProxy`, `Update`, and `FixedOutput`. ( - impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); BaseFixedTraits $($trait_name:ident)*; ) => { $crate::buffer_fixed!( - impl_inner: $name$(<$gp: $bound>)?($core_ty); + impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); Debug AlgorithmName BlockSizeUser OutputSizeUser CoreProxy Update FixedOutput $($trait_name)*; ); }; // Implements `Debug` ( - impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); Debug $($trait_name:ident)*; ) => { - impl$(<$gp: $bound>)? core::fmt::Debug for $name$(<$gp>)? { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? core::fmt::Debug for $name$(< $( $lt ),+ >)? { #[inline] fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.write_str(concat!(stringify!($name), " { ... }")) } } - $crate::buffer_fixed!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); }; // Implements `AlgorithmName` ( - impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); AlgorithmName $($trait_name:ident)*; ) => { - impl$(<$gp: $bound>)? $crate::crypto_common::AlgorithmName for $name$(<$gp>)? { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::crypto_common::AlgorithmName for $name$(< $( $lt ),+ >)? { #[inline] fn write_alg_name(f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { <$core_ty as $crate::crypto_common::AlgorithmName>::write_alg_name(f) } } - $crate::buffer_fixed!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); }; // Implements `BlockSizeUser` ( - impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); BlockSizeUser $($trait_name:ident)*; ) => { - impl$(<$gp: $bound>)? $crate::core_api::BlockSizeUser for $name$(<$gp>)? { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::core_api::BlockSizeUser for $name$(< $( $lt ),+ >)? { type BlockSize = <$core_ty as $crate::crypto_common::BlockSizeUser>::BlockSize; } - $crate::buffer_fixed!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); }; // Implements `OutputSizeUser` ( - impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); OutputSizeUser $($trait_name:ident)*; ) => { - impl$(<$gp: $bound>)? $crate::OutputSizeUser for $name$(<$gp>)? { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::OutputSizeUser for $name$(< $( $lt ),+ >)? { type OutputSize = <$core_ty as $crate::core_api::OutputSizeUser>::OutputSize; } - $crate::buffer_fixed!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); }; // Implements `CoreProxy` ( - impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); CoreProxy $($trait_name:ident)*; ) => { - impl$(<$gp: $bound>)? $crate::core_api::CoreProxy for $name$(<$gp>)? { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::core_api::CoreProxy for $name$(< $( $lt ),+ >)? { type Core = $core_ty; } - $crate::buffer_fixed!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); }; // Implements `Update` ( - impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); Update $($trait_name:ident)*; ) => { - impl$(<$gp: $bound>)? $crate::Update for $name$(<$gp>)? { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::Update for $name$(< $( $lt ),+ >)? { #[inline] fn update(&mut self, data: &[u8]) { let Self { core, buffer } = self; @@ -148,15 +200,17 @@ macro_rules! buffer_fixed { } } - $crate::buffer_fixed!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); }; // Implements `FixedOutput` ( - impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); FixedOutput $($trait_name:ident)*; ) => { - impl$(<$gp: $bound>)? $crate::FixedOutput for $name$(<$gp>)? { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::FixedOutput for $name$(< $( $lt ),+ >)? { #[inline] fn finalize_into(mut self, out: &mut $crate::Output) { let Self { core, buffer } = &mut self; @@ -164,15 +218,17 @@ macro_rules! buffer_fixed { } } - $crate::buffer_fixed!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); }; // Implements `Default` ( - impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); Default $($trait_name:ident)*; ) => { - impl$(<$gp: $bound>)? Default for $name$(<$gp>)? { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? Default for $name$(< $( $lt ),+ >)? { #[inline] fn default() -> Self { Self { @@ -182,15 +238,17 @@ macro_rules! buffer_fixed { } } - $crate::buffer_fixed!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); }; // Implements `CustomizedInit` ( - impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); CustomizedInit $($trait_name:ident)*; ) => { - impl$(<$gp: $bound>)? $crate::CustomizedInit for $name$(<$gp>)? { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::CustomizedInit for $name$(< $( $lt ),+ >)? { #[inline] fn new_customized(customization: &[u8]) -> Self { Self { @@ -200,15 +258,17 @@ macro_rules! buffer_fixed { } } - $crate::buffer_fixed!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); }; // Implements `Clone` ( - impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); Clone $($trait_name:ident)*; ) => { - impl$(<$gp: $bound>)? Clone for $name$(<$gp>)? { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? Clone for $name$(< $( $lt ),+ >)? { #[inline] fn clone(&self) -> Self { Self { @@ -218,32 +278,110 @@ macro_rules! buffer_fixed { } } - $crate::buffer_fixed!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); }; // Implements `HashMarker` and asserts that `$core_ty` implements it ( - impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); HashMarker $($trait_name:ident)*; ) => { - impl$(<$gp: $bound>)? $crate::HashMarker for $name$(<$gp>)? {} + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::HashMarker for $name$(< $( $lt ),+ >)? {} // Verify that `$core_ty` implements `HashMarker` const _: () = { - fn check$(<$gp: $bound>)?(v: &$core_ty) { + fn check$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?(v: &$core_ty) { v as &dyn $crate::HashMarker; } }; - $crate::buffer_fixed!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); + }; + + // Implements `MacMarker` and asserts that `$core_ty` implements it + ( + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); + MacMarker $($trait_name:ident)*; + ) => { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::MacMarker for $name$(< $( $lt ),+ >)? {} + + // Verify that `$core_ty` implements `MacMarker` + const _: () = { + fn check$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?(v: &$core_ty) { + v as &dyn $crate::MacMarker; + } + }; + + $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); + }; + + // Implements `InnerUser` and `InnerInit` + ( + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); + InnerInit $($trait_name:ident)*; + ) => { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::crypto_common::InnerUser for $name$(< $( $lt ),+ >)? { + type Inner = <$core_ty as $crate::crypto_common::InnerUser>::Inner; + } + + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::crypto_common::InnerInit for $name$(< $( $lt ),+ >)? { + #[inline] + fn inner_init(inner: Self::Inner) -> Self { + Self { + core: <$core_ty as $crate::crypto_common::InnerInit>::inner_init(inner), + buffer: Default::default(), + } + } + } + + $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); + }; + + // Implements `KeySizeUser` and `KeyInit` + ( + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); + KeyInit $($trait_name:ident)*; + ) => { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::crypto_common::KeySizeUser for $name$(< $( $lt ),+ >)? { + type KeySize = <$core_ty as $crate::crypto_common::KeySizeUser>::KeySize; + } + + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::KeyInit for $name$(< $( $lt ),+ >)? { + #[inline] + fn new(key: &$crate::Key) -> Self { + Self { + core: <$core_ty as $crate::KeyInit>::new(key), + buffer: Default::default(), + } + } + + #[inline] + fn new_from_slice(key: &[u8]) -> Result { + <$core_ty as $crate::KeyInit>::new_from_slice(key).map(|core| + Self { core, buffer: Default::default() } + ) + } + } + + $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); }; // Implements `Reset` ( - impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); Reset $($trait_name:ident)*; ) => { - impl$(<$gp: $bound>)? $crate::Reset for $name$(<$gp>)? { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::Reset for $name$(< $( $lt ),+ >)? { #[inline] fn reset(&mut self) { $crate::Reset::reset(&mut self.core); @@ -251,15 +389,17 @@ macro_rules! buffer_fixed { } } - $crate::buffer_fixed!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); }; // Implements `FixedOutputReset` ( - impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); FixedOutputReset $($trait_name:ident)*; ) => { - impl$(<$gp: $bound>)? $crate::FixedOutputReset for $name$(<$gp>)? { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::FixedOutputReset for $name$(< $( $lt ),+ >)? { #[inline] fn finalize_into_reset(&mut self, out: &mut $crate::Output) { let Self { core, buffer } = self; @@ -268,15 +408,17 @@ macro_rules! buffer_fixed { } } - $crate::buffer_fixed!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); }; // Implements `SerializableState` ( - impl_inner: $name:ident$(<$gp:ident: $bound:ident>)?($core_ty:ty); + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); SerializableState $($trait_name:ident)*; ) => { - impl$(<$gp: $bound>)? $crate::crypto_common::hazmat::SerializableState for $name$(<$gp>)? { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::crypto_common::hazmat::SerializableState for $name$(< $( $lt ),+ >)? { type SerializedStateSize = $crate::typenum::Sum< <$core_ty as $crate::crypto_common::hazmat::SerializableState>::SerializedStateSize, $crate::typenum::Add1< @@ -325,6 +467,6 @@ macro_rules! buffer_fixed { } } - $crate::buffer_fixed!(impl_inner: $name$(<$gp: $bound>)?($core_ty); $($trait_name)*;); + $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); } } From b3cd57bf98814dd4861a8080818a4e7877fe3d7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Sun, 25 May 2025 11:42:57 +0300 Subject: [PATCH 25/31] remove wrappers --- digest/src/core_api.rs | 13 +- digest/src/core_api/rt_variable.rs | 197 ------------------------ digest/src/core_api/wrapper.rs | 232 ----------------------------- digest/src/core_api/xof_reader.rs | 51 ------- 4 files changed, 6 insertions(+), 487 deletions(-) delete mode 100644 digest/src/core_api/rt_variable.rs delete mode 100644 digest/src/core_api/wrapper.rs delete mode 100644 digest/src/core_api/xof_reader.rs diff --git a/digest/src/core_api.rs b/digest/src/core_api.rs index b9f281dff..882576a02 100644 --- a/digest/src/core_api.rs +++ b/digest/src/core_api.rs @@ -12,14 +12,7 @@ use block_buffer::{BlockBuffer, BufferKind}; use crypto_common::Output; mod ct_variable; -mod rt_variable; -mod wrapper; -mod xof_reader; - pub use ct_variable::CtOutWrapper; -pub use rt_variable::RtVariableCoreWrapper; -pub use wrapper::{CoreProxy, CoreWrapper}; -pub use xof_reader::XofReaderCoreWrapper; /// Buffer type used by type which implements [`BufferKindUser`]. pub type Buffer = @@ -103,3 +96,9 @@ pub enum TruncSide { /// Truncate right side, i.e. `&out[m..]`. Right, } + +/// A proxy trait to a core type. +pub trait CoreProxy { + /// Type wrapped by [`CoreWrapper`]. + type Core; +} diff --git a/digest/src/core_api/rt_variable.rs b/digest/src/core_api/rt_variable.rs deleted file mode 100644 index c880ccaa0..000000000 --- a/digest/src/core_api/rt_variable.rs +++ /dev/null @@ -1,197 +0,0 @@ -use super::{AlgorithmName, BlockSizeUser, TruncSide, VariableOutputCore}; -#[cfg(feature = "mac")] -use crate::MacMarker; -use crate::{CollisionResistance, HashMarker, InvalidBufferSize}; -use crate::{InvalidOutputSize, Reset, Update, VariableOutput, VariableOutputReset}; -use block_buffer::BlockBuffer; -use core::{ - convert::TryInto, - fmt, - ops::{Add, Sub}, -}; -use crypto_common::{ - AddBlockSize, SubBlockSize, - array::{Array, ArraySize}, - hazmat::{DeserializeStateError, SerializableState, SerializedState, SubSerializedStateSize}, - typenum::{Diff, IsLess, Le, NonZero, Sum, U1, U256, Unsigned}, -}; -#[cfg(feature = "zeroize")] -use zeroize::ZeroizeOnDrop; - -/// Wrapper around [`VariableOutputCore`] which selects output size at run time. -#[derive(Clone)] -pub struct RtVariableCoreWrapper { - core: T, - buffer: BlockBuffer, - output_size: u8, -} - -impl RtVariableCoreWrapper { - #[inline] - fn finalize_dirty(&mut self, out: &mut [u8]) -> Result<(), InvalidBufferSize> { - let Self { - core, - buffer, - output_size, - } = self; - let size_u8 = u8::try_from(out.len()).map_err(|_| InvalidBufferSize)?; - if out.len() > Self::MAX_OUTPUT_SIZE || size_u8 != *output_size { - return Err(InvalidBufferSize); - } - let mut full_res = Default::default(); - core.finalize_variable_core(buffer, &mut full_res); - let n = out.len(); - let m = full_res.len() - n; - match T::TRUNC_SIDE { - TruncSide::Left => out.copy_from_slice(&full_res[..n]), - TruncSide::Right => out.copy_from_slice(&full_res[m..]), - } - Ok(()) - } -} - -impl HashMarker for RtVariableCoreWrapper {} - -#[cfg(feature = "mac")] -impl MacMarker for RtVariableCoreWrapper {} - -impl CollisionResistance for RtVariableCoreWrapper { - type CollisionResistance = T::CollisionResistance; -} - -impl BlockSizeUser for RtVariableCoreWrapper { - type BlockSize = T::BlockSize; -} - -// TODO: remove because the hasher may be customized? -impl Reset for RtVariableCoreWrapper { - #[inline] - fn reset(&mut self) { - self.buffer.reset(); - self.core = T::new(self.output_size as usize).unwrap(); - } -} - -impl AlgorithmName for RtVariableCoreWrapper { - fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { - T::write_alg_name(f)?; - f.write_str("Var") - } -} - -impl Update for RtVariableCoreWrapper { - #[inline] - fn update(&mut self, input: &[u8]) { - let Self { core, buffer, .. } = self; - buffer.digest_blocks(input, |blocks| core.update_blocks(blocks)); - } -} - -impl VariableOutput for RtVariableCoreWrapper { - const MAX_OUTPUT_SIZE: usize = T::OutputSize::USIZE; - - #[inline] - fn new(output_size: usize) -> Result { - let output_size = u8::try_from(output_size).map_err(|_| InvalidOutputSize)?; - let buffer = Default::default(); - T::new(output_size.into()).map(|core| Self { - core, - buffer, - output_size, - }) - } - - #[inline] - fn output_size(&self) -> usize { - self.output_size.into() - } - - #[inline] - fn finalize_variable(mut self, out: &mut [u8]) -> Result<(), InvalidBufferSize> { - self.finalize_dirty(out) - } -} - -impl VariableOutputReset for RtVariableCoreWrapper { - #[inline] - fn finalize_variable_reset(&mut self, out: &mut [u8]) -> Result<(), InvalidBufferSize> { - self.finalize_dirty(out)?; - self.core.reset(); - self.buffer.reset(); - Ok(()) - } -} - -impl Drop for RtVariableCoreWrapper { - #[inline] - fn drop(&mut self) { - #[cfg(feature = "zeroize")] - { - use zeroize::Zeroize; - self.buffer.zeroize(); - self.output_size.zeroize(); - } - } -} - -#[cfg(feature = "zeroize")] -impl ZeroizeOnDrop for RtVariableCoreWrapper {} - -impl fmt::Debug for RtVariableCoreWrapper { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - T::write_alg_name(f)?; - f.write_str(" { .. }") - } -} - -type RtVariableCoreWrapperSerializedStateSize = - Sum::SerializedStateSize, U1>, T>, U1>; - -impl SerializableState for RtVariableCoreWrapper -where - T: VariableOutputCore + SerializableState, - T::BlockSize: IsLess, - Le: NonZero, - T::SerializedStateSize: Add, - Sum: Add + ArraySize, - AddBlockSize, T>: Add + ArraySize, - RtVariableCoreWrapperSerializedStateSize: Sub + ArraySize, - SubSerializedStateSize, T>: Sub + ArraySize, - Diff, T>, U1>: - Sub + ArraySize, - SubBlockSize< - Diff, T>, U1>, - T, - >: ArraySize, -{ - type SerializedStateSize = RtVariableCoreWrapperSerializedStateSize; - - fn serialize(&self) -> SerializedState { - let serialized_core = self.core.serialize(); - let serialized_pos = Array([self.buffer.get_pos().try_into().unwrap()]); - let serialized_data = self.buffer.clone().pad_with_zeros(); - let serialized_output_size = Array([self.output_size]); - - serialized_core - .concat(serialized_pos) - .concat(serialized_data) - .concat(serialized_output_size) - } - - fn deserialize( - serialized_state: &SerializedState, - ) -> Result { - let (serialized_core, remaining_buffer) = - serialized_state.split_ref::(); - let (serialized_pos, remaining_buffer) = remaining_buffer.split_ref::(); - let (serialized_data, serialized_output_size) = - remaining_buffer.split_ref::(); - - Ok(Self { - core: T::deserialize(serialized_core)?, - buffer: BlockBuffer::try_new(&serialized_data[..serialized_pos[0].into()]) - .map_err(|_| DeserializeStateError)?, - output_size: serialized_output_size[0], - }) - } -} diff --git a/digest/src/core_api/wrapper.rs b/digest/src/core_api/wrapper.rs deleted file mode 100644 index 5c91034ce..000000000 --- a/digest/src/core_api/wrapper.rs +++ /dev/null @@ -1,232 +0,0 @@ -use super::{ - AlgorithmName, BufferKindUser, ExtendableOutputCore, FixedOutputCore, OutputSizeUser, Reset, - UpdateCore, XofReaderCoreWrapper, -}; -use crate::{ - CollisionResistance, CustomizedInit, ExtendableOutput, ExtendableOutputReset, FixedOutput, - FixedOutputReset, HashMarker, Update, -}; -use block_buffer::BlockBuffer; -use core::{ - convert::TryInto, - fmt, - ops::{Add, Sub}, -}; -use crypto_common::{ - BlockSizeUser, InvalidLength, Key, KeyInit, KeySizeUser, Output, - array::{Array, ArraySize}, - hazmat::{DeserializeStateError, SerializableState, SerializedState, SubSerializedStateSize}, - typenum::{Diff, IsLess, Le, NonZero, Sum, U1, U256}, -}; - -#[cfg(feature = "mac")] -use crate::MacMarker; - -/// Wrapper around [`BufferKindUser`]. -/// -/// It handles data buffering and implements the slice-based traits. -#[derive(Clone, Default)] -pub struct CoreWrapper { - core: T, - buffer: BlockBuffer, -} - -impl HashMarker for CoreWrapper {} - -#[cfg(feature = "mac")] -impl MacMarker for CoreWrapper {} - -impl CollisionResistance for CoreWrapper { - type CollisionResistance = T::CollisionResistance; -} - -// this blanket impl is needed for HMAC -impl BlockSizeUser for CoreWrapper { - type BlockSize = T::BlockSize; -} - -impl CoreWrapper { - /// Create new wrapper from `core`. - #[inline] - pub fn from_core(core: T) -> Self { - let buffer = Default::default(); - Self { core, buffer } - } -} - -impl KeySizeUser for CoreWrapper { - type KeySize = T::KeySize; -} - -impl KeyInit for CoreWrapper { - #[inline] - fn new(key: &Key) -> Self { - Self { - core: T::new(key), - buffer: Default::default(), - } - } - - #[inline] - fn new_from_slice(key: &[u8]) -> Result { - Ok(Self { - core: T::new_from_slice(key)?, - buffer: Default::default(), - }) - } -} - -impl fmt::Debug for CoreWrapper { - #[inline] - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - T::write_alg_name(f)?; - f.write_str(" { .. }") - } -} - -impl Reset for CoreWrapper { - #[inline] - fn reset(&mut self) { - self.core.reset(); - self.buffer.reset(); - } -} - -impl Update for CoreWrapper { - #[inline] - fn update(&mut self, input: &[u8]) { - let Self { core, buffer } = self; - buffer.digest_blocks(input, |blocks| core.update_blocks(blocks)); - } -} - -impl OutputSizeUser for CoreWrapper { - type OutputSize = T::OutputSize; -} - -impl FixedOutput for CoreWrapper { - #[inline] - fn finalize_into(mut self, out: &mut Output) { - let Self { core, buffer } = &mut self; - core.finalize_fixed_core(buffer, out); - } -} - -impl FixedOutputReset for CoreWrapper { - #[inline] - fn finalize_into_reset(&mut self, out: &mut Output) { - let Self { core, buffer } = self; - core.finalize_fixed_core(buffer, out); - core.reset(); - buffer.reset(); - } -} - -impl ExtendableOutput for CoreWrapper { - type Reader = XofReaderCoreWrapper; - - #[inline] - fn finalize_xof(mut self) -> Self::Reader { - Self::Reader { - core: self.core.finalize_xof_core(&mut self.buffer), - buffer: Default::default(), - } - } -} - -impl ExtendableOutputReset for CoreWrapper { - #[inline] - fn finalize_xof_reset(&mut self) -> Self::Reader { - let Self { core, buffer } = self; - let reader_core = core.finalize_xof_core(buffer); - core.reset(); - buffer.reset(); - let buffer = Default::default(); - Self::Reader { - core: reader_core, - buffer, - } - } -} - -impl AlgorithmName for CoreWrapper { - #[inline] - fn write_alg_name(f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - T::write_alg_name(f) - } -} - -impl Drop for CoreWrapper { - #[inline] - fn drop(&mut self) { - #[cfg(feature = "zeroize")] - { - use zeroize::Zeroize; - self.buffer.zeroize(); - } - } -} - -#[cfg(feature = "zeroize")] -impl zeroize::ZeroizeOnDrop for CoreWrapper {} - -impl CustomizedInit for CoreWrapper -where - T: BufferKindUser + CustomizedInit, -{ - #[inline] - fn new_customized(customization: &[u8]) -> Self { - Self::from_core(T::new_customized(customization)) - } -} - -type CoreWrapperSerializedStateSize = - Sum::SerializedStateSize, U1>, ::BlockSize>; - -impl SerializableState for CoreWrapper -where - T: BufferKindUser + SerializableState, - T::BlockSize: IsLess, - Le: NonZero, - T::SerializedStateSize: Add, - Sum: Add + ArraySize, - CoreWrapperSerializedStateSize: Sub + ArraySize, - SubSerializedStateSize, T>: Sub + ArraySize, - Diff, T>, U1>: ArraySize, -{ - type SerializedStateSize = CoreWrapperSerializedStateSize; - - fn serialize(&self) -> SerializedState { - let serialized_core = self.core.serialize(); - let serialized_pos = Array([self.buffer.get_pos().try_into().unwrap()]); - let serialized_data = self.buffer.clone().pad_with_zeros(); - - serialized_core - .concat(serialized_pos) - .concat(serialized_data) - } - - fn deserialize( - serialized_state: &SerializedState, - ) -> Result { - let (serialized_core, remaining_buffer) = - serialized_state.split_ref::(); - let (serialized_pos, serialized_data) = remaining_buffer.split_ref::(); - - Ok(Self { - core: T::deserialize(serialized_core)?, - buffer: BlockBuffer::try_new(&serialized_data[..serialized_pos[0].into()]) - .map_err(|_| DeserializeStateError)?, - }) - } -} - -/// A proxy trait to a core type. -pub trait CoreProxy { - /// Type wrapped by [`CoreWrapper`]. - type Core; -} - -impl CoreProxy for CoreWrapper { - type Core = T; -} diff --git a/digest/src/core_api/xof_reader.rs b/digest/src/core_api/xof_reader.rs deleted file mode 100644 index 0bb63933c..000000000 --- a/digest/src/core_api/xof_reader.rs +++ /dev/null @@ -1,51 +0,0 @@ -use super::{AlgorithmName, XofReaderCore}; -use crate::XofReader; -use block_buffer::ReadBuffer; -use core::fmt; - -/// Wrapper around [`XofReaderCore`] implementations. -/// -/// It handles data buffering and implements the mid-level traits. -#[derive(Clone, Default)] -pub struct XofReaderCoreWrapper -where - T: XofReaderCore, -{ - pub(super) core: T, - pub(super) buffer: ReadBuffer, -} - -impl fmt::Debug for XofReaderCoreWrapper -where - T: XofReaderCore + AlgorithmName, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - T::write_alg_name(f)?; - f.write_str(" { .. }") - } -} - -impl XofReader for XofReaderCoreWrapper -where - T: XofReaderCore, -{ - #[inline] - fn read(&mut self, buffer: &mut [u8]) { - let Self { core, buffer: buf } = self; - buf.read(buffer, |block| *block = core.read_block()); - } -} - -impl Drop for XofReaderCoreWrapper { - #[inline] - fn drop(&mut self) { - #[cfg(feature = "zeroize")] - { - use zeroize::Zeroize; - self.buffer.zeroize(); - } - } -} - -#[cfg(feature = "zeroize")] -impl zeroize::ZeroizeOnDrop for XofReaderCoreWrapper {} From b5bac4352fd6200fd91795f63e1060ba02cb7920 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Sun, 25 May 2025 11:46:23 +0300 Subject: [PATCH 26/31] fix docs --- digest/src/core_api.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/digest/src/core_api.rs b/digest/src/core_api.rs index 882576a02..bdc70ab6c 100644 --- a/digest/src/core_api.rs +++ b/digest/src/core_api.rs @@ -99,6 +99,6 @@ pub enum TruncSide { /// A proxy trait to a core type. pub trait CoreProxy { - /// Type wrapped by [`CoreWrapper`]. + /// Wrapped block-level type. type Core; } From 954e8ff1197d25b5b4dbb6baa042573c78b8dbf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Sun, 25 May 2025 11:49:52 +0300 Subject: [PATCH 27/31] rename `core_api` to `block_api` --- digest/Cargo.toml | 4 ++-- digest/src/{core_api.rs => block_api.rs} | 0 .../{core_api => block_api}/ct_variable.rs | 0 digest/src/buffer_macros/fixed.rs | 16 +++++++------- digest/src/buffer_macros/variable_ct.rs | 22 +++++++++---------- digest/src/buffer_macros/variable_rt.rs | 20 ++++++++--------- digest/src/buffer_macros/xof.rs | 18 +++++++-------- digest/src/lib.rs | 6 ++--- digest/tests/dummy_fixed.rs | 6 ++--- 9 files changed, 46 insertions(+), 46 deletions(-) rename digest/src/{core_api.rs => block_api.rs} (100%) rename digest/src/{core_api => block_api}/ct_variable.rs (100%) diff --git a/digest/Cargo.toml b/digest/Cargo.toml index db79a487d..895d1efe9 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -23,8 +23,8 @@ const-oid = { version = "0.10", optional = true } zeroize = { version = "1.7", optional = true, default-features = false } [features] -default = ["core-api"] -core-api = ["block-buffer"] # Enable Core API traits +default = ["block-api"] +block-api = ["block-buffer"] # Enable block API traits mac = ["subtle"] # Enable MAC traits rand_core = ["crypto-common/rand_core"] # Enable random key generation methods os_rng = ["crypto-common/rand_core", "rand_core"] diff --git a/digest/src/core_api.rs b/digest/src/block_api.rs similarity index 100% rename from digest/src/core_api.rs rename to digest/src/block_api.rs diff --git a/digest/src/core_api/ct_variable.rs b/digest/src/block_api/ct_variable.rs similarity index 100% rename from digest/src/core_api/ct_variable.rs rename to digest/src/block_api/ct_variable.rs diff --git a/digest/src/buffer_macros/fixed.rs b/digest/src/buffer_macros/fixed.rs index 2bc01a97d..0c4add274 100644 --- a/digest/src/buffer_macros/fixed.rs +++ b/digest/src/buffer_macros/fixed.rs @@ -11,7 +11,7 @@ macro_rules! buffer_fixed { $(#[$attr])* $v struct $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? { core: $core_ty, - buffer: $crate::core_api::Buffer<$core_ty>, + buffer: $crate::block_api::Buffer<$core_ty>, } $crate::buffer_fixed!( @@ -148,7 +148,7 @@ macro_rules! buffer_fixed { ($core_ty:ty); BlockSizeUser $($trait_name:ident)*; ) => { - impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::core_api::BlockSizeUser for $name$(< $( $lt ),+ >)? { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::block_api::BlockSizeUser for $name$(< $( $lt ),+ >)? { type BlockSize = <$core_ty as $crate::crypto_common::BlockSizeUser>::BlockSize; } @@ -163,7 +163,7 @@ macro_rules! buffer_fixed { OutputSizeUser $($trait_name:ident)*; ) => { impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::OutputSizeUser for $name$(< $( $lt ),+ >)? { - type OutputSize = <$core_ty as $crate::core_api::OutputSizeUser>::OutputSize; + type OutputSize = <$core_ty as $crate::block_api::OutputSizeUser>::OutputSize; } $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); @@ -176,7 +176,7 @@ macro_rules! buffer_fixed { ($core_ty:ty); CoreProxy $($trait_name:ident)*; ) => { - impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::core_api::CoreProxy for $name$(< $( $lt ),+ >)? { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::block_api::CoreProxy for $name$(< $( $lt ),+ >)? { type Core = $core_ty; } @@ -195,7 +195,7 @@ macro_rules! buffer_fixed { fn update(&mut self, data: &[u8]) { let Self { core, buffer } = self; buffer.digest_blocks(data, |blocks| { - $crate::core_api::UpdateCore::update_blocks(core, blocks) + $crate::block_api::UpdateCore::update_blocks(core, blocks) }); } } @@ -214,7 +214,7 @@ macro_rules! buffer_fixed { #[inline] fn finalize_into(mut self, out: &mut $crate::Output) { let Self { core, buffer } = &mut self; - $crate::core_api::FixedOutputCore::finalize_fixed_core(core, buffer, out); + $crate::block_api::FixedOutputCore::finalize_fixed_core(core, buffer, out); } } @@ -403,7 +403,7 @@ macro_rules! buffer_fixed { #[inline] fn finalize_into_reset(&mut self, out: &mut $crate::Output) { let Self { core, buffer } = self; - $crate::core_api::FixedOutputCore::finalize_fixed_core(core, buffer, out); + $crate::block_api::FixedOutputCore::finalize_fixed_core(core, buffer, out); $crate::Reset::reset(self); } } @@ -422,7 +422,7 @@ macro_rules! buffer_fixed { type SerializedStateSize = $crate::typenum::Sum< <$core_ty as $crate::crypto_common::hazmat::SerializableState>::SerializedStateSize, $crate::typenum::Add1< - <$core_ty as $crate::core_api::BlockSizeUser>::BlockSize + <$core_ty as $crate::block_api::BlockSizeUser>::BlockSize > >; diff --git a/digest/src/buffer_macros/variable_ct.rs b/digest/src/buffer_macros/variable_ct.rs index da5f6abc8..1399ec084 100644 --- a/digest/src/buffer_macros/variable_ct.rs +++ b/digest/src/buffer_macros/variable_ct.rs @@ -16,8 +16,8 @@ macro_rules! buffer_ct_variable { where $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size, Output = $crate::typenum::True>, { - core: $crate::core_api::CtOutWrapper<$core_ty, $out_size>, - buffer: $crate::core_api::Buffer<$core_ty>, + core: $crate::block_api::CtOutWrapper<$core_ty, $out_size>, + buffer: $crate::block_api::Buffer<$core_ty>, } impl<$out_size> core::fmt::Debug for $name<$out_size> @@ -77,7 +77,7 @@ macro_rules! buffer_ct_variable { } } - impl<$out_size> $crate::core_api::BlockSizeUser for $name<$out_size> + impl<$out_size> $crate::block_api::BlockSizeUser for $name<$out_size> where $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size, Output = $crate::typenum::True>, { @@ -107,11 +107,11 @@ macro_rules! buffer_ct_variable { } }; - impl<$out_size> $crate::core_api::CoreProxy for $name<$out_size> + impl<$out_size> $crate::block_api::CoreProxy for $name<$out_size> where $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size, Output = $crate::typenum::True>, { - type Core = $crate::core_api::CtOutWrapper<$core_ty, $out_size>; + type Core = $crate::block_api::CtOutWrapper<$core_ty, $out_size>; } impl<$out_size> $crate::Update for $name<$out_size> @@ -122,7 +122,7 @@ macro_rules! buffer_ct_variable { fn update(&mut self, data: &[u8]) { let Self { core, buffer } = self; buffer.digest_blocks(data, |blocks| { - $crate::core_api::UpdateCore::update_blocks(core, blocks) + $crate::block_api::UpdateCore::update_blocks(core, blocks) }); } } @@ -134,7 +134,7 @@ macro_rules! buffer_ct_variable { #[inline] fn finalize_into(mut self, out: &mut $crate::Output) { let Self { core, buffer } = &mut self; - $crate::core_api::FixedOutputCore::finalize_fixed_core(core, buffer, out); + $crate::block_api::FixedOutputCore::finalize_fixed_core(core, buffer, out); } } @@ -145,7 +145,7 @@ macro_rules! buffer_ct_variable { #[inline] fn finalize_into_reset(&mut self, out: &mut $crate::Output) { let Self { core, buffer } = self; - $crate::core_api::FixedOutputCore::finalize_fixed_core(core, buffer, out); + $crate::block_api::FixedOutputCore::finalize_fixed_core(core, buffer, out); $crate::Reset::reset(self); } } @@ -171,10 +171,10 @@ macro_rules! buffer_ct_variable { { type SerializedStateSize = $crate::typenum::Add1<$crate::typenum::Sum< < - $crate::core_api::CtOutWrapper<$core_ty, $out_size> + $crate::block_api::CtOutWrapper<$core_ty, $out_size> as $crate::crypto_common::hazmat::SerializableState >::SerializedStateSize, - <$core_ty as $crate::core_api::BlockSizeUser>::BlockSize, + <$core_ty as $crate::block_api::BlockSizeUser>::BlockSize, >>; #[inline] @@ -203,7 +203,7 @@ macro_rules! buffer_ct_variable { use $crate::{ block_buffer::BlockBuffer, consts::U1, - core_api::CtOutWrapper, + block_api::CtOutWrapper, crypto_common::hazmat::{SerializableState, DeserializeStateError}, }; diff --git a/digest/src/buffer_macros/variable_rt.rs b/digest/src/buffer_macros/variable_rt.rs index 14bab748e..e39ff5adb 100644 --- a/digest/src/buffer_macros/variable_rt.rs +++ b/digest/src/buffer_macros/variable_rt.rs @@ -10,7 +10,7 @@ macro_rules! buffer_rt_variable { $(#[$attr])* $vis struct $name { core: $core_ty, - buffer: $crate::core_api::Buffer<$core_ty>, + buffer: $crate::block_api::Buffer<$core_ty>, output_size: u8, } @@ -43,12 +43,12 @@ macro_rules! buffer_rt_variable { #[inline] fn reset(&mut self) { let size = self.output_size.into(); - self.core = <$core_ty as $crate::core_api::VariableOutputCore>::new(size).unwrap(); + self.core = <$core_ty as $crate::block_api::VariableOutputCore>::new(size).unwrap(); self.buffer.reset(); } } - impl $crate::core_api::BlockSizeUser for $name { + impl $crate::block_api::BlockSizeUser for $name { type BlockSize = <$core_ty as $crate::crypto_common::BlockSizeUser>::BlockSize; } @@ -66,7 +66,7 @@ macro_rules! buffer_rt_variable { fn update(&mut self, data: &[u8]) { let Self { core, buffer, .. } = self; buffer.digest_blocks(data, |blocks| { - $crate::core_api::UpdateCore::update_blocks(core, blocks); + $crate::block_api::UpdateCore::update_blocks(core, blocks); }); } } @@ -86,11 +86,11 @@ macro_rules! buffer_rt_variable { return Err($crate::InvalidBufferSize); } let mut full_res = Default::default(); - $crate::core_api::VariableOutputCore::finalize_variable_core(core, buffer, &mut full_res); + $crate::block_api::VariableOutputCore::finalize_variable_core(core, buffer, &mut full_res); let n = out.len(); let m = full_res.len() - n; - use $crate::core_api::TruncSide::{Left, Right}; - let side = <$core_ty as $crate::core_api::VariableOutputCore>::TRUNC_SIDE; + use $crate::block_api::TruncSide::{Left, Right}; + let side = <$core_ty as $crate::block_api::VariableOutputCore>::TRUNC_SIDE; match side { Left => out.copy_from_slice(&full_res[..n]), Right => out.copy_from_slice(&full_res[m..]), @@ -101,7 +101,7 @@ macro_rules! buffer_rt_variable { impl $crate::VariableOutput for $name { const MAX_OUTPUT_SIZE: usize = < - <$core_ty as $crate::core_api::OutputSizeUser>::OutputSize + <$core_ty as $crate::block_api::OutputSizeUser>::OutputSize as $crate::typenum::Unsigned >::USIZE; @@ -109,7 +109,7 @@ macro_rules! buffer_rt_variable { fn new(output_size: usize) -> Result { let output_size = u8::try_from(output_size).map_err(|_| $crate::InvalidOutputSize)?; let buffer = Default::default(); - let core = <$core_ty as $crate::core_api::VariableOutputCore>::new(output_size.into())?; + let core = <$core_ty as $crate::block_api::VariableOutputCore>::new(output_size.into())?; Ok(Self { core, buffer, @@ -169,7 +169,7 @@ macro_rules! buffer_rt_variable { impl $crate::crypto_common::hazmat::SerializableState for $name { type SerializedStateSize = $crate::typenum::Add1<$crate::typenum::Sum< <$core_ty as $crate::crypto_common::hazmat::SerializableState>::SerializedStateSize, - <$core_ty as $crate::core_api::BlockSizeUser>::BlockSize, + <$core_ty as $crate::block_api::BlockSizeUser>::BlockSize, >>; #[inline] diff --git a/digest/src/buffer_macros/xof.rs b/digest/src/buffer_macros/xof.rs index c17d8b7cc..dd635332c 100644 --- a/digest/src/buffer_macros/xof.rs +++ b/digest/src/buffer_macros/xof.rs @@ -14,7 +14,7 @@ macro_rules! buffer_xof { $(#[$hasher_attr])* $hasher_vis struct $hasher_name { core: $hasher_core, - buffer: $crate::core_api::Buffer<$hasher_core>, + buffer: $crate::block_api::Buffer<$hasher_core>, } impl $crate::ExtendableOutput for $hasher_name { @@ -23,7 +23,7 @@ macro_rules! buffer_xof { #[inline] fn finalize_xof(mut self) -> Self::Reader { let Self { core, buffer } = &mut self; - let core = <$hasher_core as $crate::core_api::ExtendableOutputCore>::finalize_xof_core(core, buffer); + let core = <$hasher_core as $crate::block_api::ExtendableOutputCore>::finalize_xof_core(core, buffer); let buffer = Default::default(); Self::Reader { core, buffer } } @@ -45,7 +45,7 @@ macro_rules! buffer_xof { $(#[$reader_attr])* $reader_vis struct $reader_name { core: $reader_core, - buffer: $crate::block_buffer::ReadBuffer<<$reader_core as $crate::core_api::BlockSizeUser>::BlockSize>, + buffer: $crate::block_buffer::ReadBuffer<<$reader_core as $crate::block_api::BlockSizeUser>::BlockSize>, } impl $crate::XofReader for $reader_name { @@ -53,7 +53,7 @@ macro_rules! buffer_xof { fn read(&mut self, buf: &mut [u8]) { let Self { core, buffer } = self; buffer.read(buf, |block| { - *block = $crate::core_api::XofReaderCore::read_block(core); + *block = $crate::block_api::XofReaderCore::read_block(core); }); } } @@ -180,7 +180,7 @@ macro_rules! buffer_xof { impl_inner: $name:ident($core_ty:ty); BlockSizeUser $($trait_name:ident)*; ) => { - impl $crate::core_api::BlockSizeUser for $name { + impl $crate::block_api::BlockSizeUser for $name { type BlockSize = <$core_ty as $crate::crypto_common::BlockSizeUser>::BlockSize; } @@ -192,7 +192,7 @@ macro_rules! buffer_xof { impl_inner: $name:ident($core_ty:ty); CoreProxy $($trait_name:ident)*; ) => { - impl $crate::core_api::CoreProxy for $name { + impl $crate::block_api::CoreProxy for $name { type Core = $core_ty; } @@ -226,7 +226,7 @@ macro_rules! buffer_xof { fn update(&mut self, data: &[u8]) { let Self { core, buffer } = self; buffer.digest_blocks(data, |blocks| { - $crate::core_api::UpdateCore::update_blocks(core, blocks) + $crate::block_api::UpdateCore::update_blocks(core, blocks) }); } } @@ -259,7 +259,7 @@ macro_rules! buffer_xof { #[inline] fn finalize_xof_reset(&mut self) -> Self::Reader { let Self { core, buffer } = self; - let core = <$core_ty as $crate::core_api::ExtendableOutputCore>::finalize_xof_core(core, buffer); + let core = <$core_ty as $crate::block_api::ExtendableOutputCore>::finalize_xof_core(core, buffer); $crate::Reset::reset(self); let buffer = Default::default(); Self::Reader { core, buffer } @@ -278,7 +278,7 @@ macro_rules! buffer_xof { type SerializedStateSize = $crate::typenum::Sum< <$core_ty as $crate::crypto_common::hazmat::SerializableState>::SerializedStateSize, $crate::typenum::Add1< - <$core_ty as $crate::core_api::BlockSizeUser>::BlockSize + <$core_ty as $crate::block_api::BlockSizeUser>::BlockSize > >; diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 2e64ff946..894990d7f 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -50,15 +50,15 @@ use alloc::boxed::Box; #[cfg(feature = "dev")] pub mod dev; +#[cfg(feature = "block-api")] +pub mod block_api; mod buffer_macros; -#[cfg(feature = "core-api")] -pub mod core_api; mod digest; #[cfg(feature = "mac")] mod mac; mod xof_fixed; -#[cfg(feature = "core-api")] +#[cfg(feature = "block-api")] pub use block_buffer; #[cfg(feature = "oid")] pub use const_oid; diff --git a/digest/tests/dummy_fixed.rs b/digest/tests/dummy_fixed.rs index da81213bf..cbec6aced 100644 --- a/digest/tests/dummy_fixed.rs +++ b/digest/tests/dummy_fixed.rs @@ -1,14 +1,14 @@ -#![cfg(feature = "core-api")] +#![cfg(feature = "block-api")] mod block_api { use core::fmt; use digest::{ HashMarker, Output, OutputSizeUser, Reset, - consts::U8, - core_api::{ + block_api::{ AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, FixedOutputCore, UpdateCore, }, + consts::U8, crypto_common::hazmat::{DeserializeStateError, SerializableState, SerializedState}, }; From 774c061e99e959289cdca4f29d5c97e507a2209b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Sun, 25 May 2025 12:08:39 +0300 Subject: [PATCH 28/31] fix docs --- digest/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 894990d7f..600658e2e 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -12,7 +12,7 @@ //! traits atomically describe available functionality of an algorithm. //! - **Marker traits**: [`HashMarker`], [`MacMarker`]. Used to distinguish //! different algorithm classes. -//! - **Low-level traits** defined in the [`core_api`] module. These traits +//! - **Low-level traits** defined in the [`block_api`] module. These traits //! operate at a block-level and do not contain any built-in buffering. //! They are intended to be implemented by low-level algorithm providers only. //! Usually they should not be used in application-level code. From 99be71bb13992d97f66dedf0efd889adc71a5237 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Mon, 26 May 2025 03:58:48 +0300 Subject: [PATCH 29/31] Update changelog --- digest/CHANGELOG.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/digest/CHANGELOG.md b/digest/CHANGELOG.md index 431816c5e..bafe3827f 100644 --- a/digest/CHANGELOG.md +++ b/digest/CHANGELOG.md @@ -7,20 +7,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## 0.11.0 (UNRELEASED) ### Added -- `CustomizedInit` trait ([#1334]). +- `CustomizedInit` trait ([#1334]) +- `buffer_fixed`, `buffer_ct_variable`, `buffer_rt_variable`, and `buffer_xof` macros ([#1799]) ### Changed - `crypto-common` dependency bumped to v0.2 ([#1173]) - Edition changed to 2024 and MSRV bumped to 1.85 ([#1759]) +- `CtVariableCoreWrapper` renamed to `CtOutWrapper` ([#1799]) +- Removed the OID type parameter from `CtOutWrapper` ([#1799]) ### Removed - `Mac::new`, `Mac::new_from_slice`, and `Mac::generate_key` methods ([#1173]) +- `CoreWrapper`, `RtVariableCoreWrapper`, and `XofReaderCoreWrapper` types ([#1799]) - `HashReader` and `HashWriter` are moved to the `digest-io` crate ([#1809]) - `io::Write/Read` implementations in favor of the `digest_io::IoWrapper` type ([#1809]) [#1173]: https://github.com/RustCrypto/traits/pull/1173 [#1334]: https://github.com/RustCrypto/traits/pull/1334 [#1759]: https://github.com/RustCrypto/traits/pull/1759 +[#1799]: https://github.com/RustCrypto/traits/pull/1799 [#1809]: https://github.com/RustCrypto/traits/pull/1809 ## 0.10.7 (2023-05-19) From 161c42b9f6c8f1f4831e3d5cf10947978eb03209 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Mon, 26 May 2025 04:01:05 +0300 Subject: [PATCH 30/31] Add changelog entry for #1820 --- digest/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/digest/CHANGELOG.md b/digest/CHANGELOG.md index bafe3827f..a4fe6b64a 100644 --- a/digest/CHANGELOG.md +++ b/digest/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - `CustomizedInit` trait ([#1334]) - `buffer_fixed`, `buffer_ct_variable`, `buffer_rt_variable`, and `buffer_xof` macros ([#1799]) +- `CollisionResistance` trait ([#1820]) ### Changed - `crypto-common` dependency bumped to v0.2 ([#1173]) @@ -27,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [#1759]: https://github.com/RustCrypto/traits/pull/1759 [#1799]: https://github.com/RustCrypto/traits/pull/1799 [#1809]: https://github.com/RustCrypto/traits/pull/1809 +[#1820]: https://github.com/RustCrypto/traits/pull/1820 ## 0.10.7 (2023-05-19) ### Changed From c61b646f14b87c0bb04709ea300c778920d5c56b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Mon, 26 May 2025 05:03:11 +0300 Subject: [PATCH 31/31] Tweak `buffer_fixed` --- digest/src/buffer_macros/fixed.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/digest/src/buffer_macros/fixed.rs b/digest/src/buffer_macros/fixed.rs index 0c4add274..7d27d8906 100644 --- a/digest/src/buffer_macros/fixed.rs +++ b/digest/src/buffer_macros/fixed.rs @@ -59,12 +59,14 @@ macro_rules! buffer_fixed { ) => { $crate::buffer_fixed!( impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); - BaseFixedTraits Default Clone HashMarker Reset FixedOutputReset SerializableState $($trait_name)*; + BaseFixedTraits AlgorithmName Default Clone HashMarker + Reset FixedOutputReset SerializableState $($trait_name)*; ); }; // Implements the set of traits common for MAC functions: - // `Debug`, `OutputSizeUser`, `CoreProxy`, `Update`, `FixedOutput`, `Clone`, `MacMarker`. + // `Debug`, `BlockSizeUser`, `OutputSizeUser`, `CoreProxy`, `Update`, `FixedOutput`, + // `Clone`, `MacMarker`. ( impl_inner: $name:ident $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? @@ -73,13 +75,13 @@ macro_rules! buffer_fixed { ) => { $crate::buffer_fixed!( impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); - Debug OutputSizeUser CoreProxy Update FixedOutput Clone MacMarker $($trait_name)*; + BaseFixedTraits Clone MacMarker $($trait_name)*; ); }; // Implements the set of traits common for resettable MAC functions: - // `Debug`, `OutputSizeUser`, `CoreProxy`, `Update`, `FixedOutput`, `Clone`, `MacMarker`, - // `Reset`, `FixedOutputReset`. + // `Debug`, `BlockSizeUser`, `OutputSizeUser`, `CoreProxy`, `Update`, `FixedOutput`, + // `Clone`, `MacMarker`, `Reset`, `FixedOutputReset`. ( impl_inner: $name:ident $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? @@ -93,8 +95,7 @@ macro_rules! buffer_fixed { }; // Implements basic fixed traits: - // `Debug`, `AlgorithmName`, `BlockSizeUser`, `OutputSizeUser`, - // `CoreProxy`, `Update`, and `FixedOutput`. + // `Debug`, `BlockSizeUser`, `OutputSizeUser`, `CoreProxy`, `Update`, and `FixedOutput`. ( impl_inner: $name:ident $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? @@ -103,7 +104,7 @@ macro_rules! buffer_fixed { ) => { $crate::buffer_fixed!( impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); - Debug AlgorithmName BlockSizeUser OutputSizeUser CoreProxy Update FixedOutput $($trait_name)*; + Debug BlockSizeUser OutputSizeUser CoreProxy Update FixedOutput $($trait_name)*; ); };