hashes: Use associated cost for pre-tagging

Instead of requiring users of the `Tag` trait to implement the `engine`
method we can have an associated const and provide an `engine` method
with a default implementation.

Use an associated const for the pre-tagged hash engine. Fro now keep the
`engine` trait method but have a default impl that returns the const. We
will remove it as a separate patch to assist review.
This commit is contained in:
Tobin C. Harding 2025-02-07 07:05:30 +11:00
parent 613fddc82b
commit ba6425947f
No known key found for this signature in database
GPG Key ID: 40BF9E4C269D6607
3 changed files with 9 additions and 15 deletions

View File

@ -33,11 +33,7 @@ macro_rules! sha256t_tag {
$crate::sha256t_tag_struct!($tag_vis, $tag, stringify!($hash_name), $(#[$($tag_attr)*])*); $crate::sha256t_tag_struct!($tag_vis, $tag, stringify!($hash_name), $(#[$($tag_attr)*])*);
impl $crate::sha256t::Tag for $tag { impl $crate::sha256t::Tag for $tag {
#[inline] const MIDSTATE: $crate::sha256::Midstate = $crate::sha256t_tag_constructor!($constructor, $($tag_value)+);
fn engine() -> $crate::sha256::HashEngine {
const MIDSTATE: $crate::sha256::Midstate = $crate::sha256t_tag_constructor!($constructor, $($tag_value)+);
$crate::sha256::HashEngine::from_midstate(MIDSTATE)
}
} }
} }
} }

View File

@ -11,8 +11,13 @@ type HashEngine = sha256::HashEngine;
/// Trait representing a tag that can be used as a context for SHA256t hashes. /// Trait representing a tag that can be used as a context for SHA256t hashes.
pub trait Tag { pub trait Tag {
/// The [`Midstate`] after pre-tagging the hash engine.
const MIDSTATE: sha256::Midstate;
/// Returns a hash engine that is pre-tagged and is ready to be used for the data. /// Returns a hash engine that is pre-tagged and is ready to be used for the data.
fn engine() -> sha256::HashEngine; fn engine() -> sha256::HashEngine {
sha256::HashEngine::from_midstate(Self::MIDSTATE)
}
} }
/// Output of the SHA256t hash function. /// Output of the SHA256t hash function.
@ -190,11 +195,7 @@ mod tests {
pub struct TestHashTag; pub struct TestHashTag;
impl sha256t::Tag for TestHashTag { impl sha256t::Tag for TestHashTag {
fn engine() -> sha256::HashEngine { const MIDSTATE: sha256::Midstate = sha256::Midstate::new(TEST_MIDSTATE, 64);
// The TapRoot TapLeaf midstate.
let midstate = sha256::Midstate::new(TEST_MIDSTATE, 64);
sha256::HashEngine::from_midstate(midstate)
}
} }
// We support manually implementing `Tag` and creating a tagged hash from it. // We support manually implementing `Tag` and creating a tagged hash from it.

View File

@ -40,10 +40,7 @@ impl_regression_test! {
pub struct RegHashTag; pub struct RegHashTag;
impl sha256t::Tag for RegHashTag { impl sha256t::Tag for RegHashTag {
fn engine() -> sha256::HashEngine { const MIDSTATE: sha256::Midstate = sha256::Midstate::new([0xab; 32], 64);
let midstate = sha256::Midstate::new([0xab; 32], 64);
sha256::HashEngine::from_midstate(midstate)
}
} }
type RegHash = sha256t::Hash<RegHashTag>; type RegHash = sha256t::Hash<RegHashTag>;