diff --git a/starknet-crypto/src/lib.rs b/starknet-crypto/src/lib.rs index ce10c1f3..f35271e6 100644 --- a/starknet-crypto/src/lib.rs +++ b/starknet-crypto/src/lib.rs @@ -33,7 +33,7 @@ mod test_utils; pub use starknet_types_core::felt::Felt; -pub use pedersen_hash::pedersen_hash; +pub use pedersen_hash::{pedersen_hash, PedersenHasher}; pub use poseidon_hash::{ poseidon_hash, poseidon_hash_many, poseidon_hash_single, poseidon_permute_comp, PoseidonHasher, diff --git a/starknet-crypto/src/pedersen_hash/mod.rs b/starknet-crypto/src/pedersen_hash/mod.rs index c6d01a59..37d4548b 100644 --- a/starknet-crypto/src/pedersen_hash/mod.rs +++ b/starknet-crypto/src/pedersen_hash/mod.rs @@ -1,3 +1,5 @@ +use starknet_types_core::felt::Felt; + #[cfg(not(feature = "pedersen_no_lookup"))] mod default; #[cfg(not(feature = "pedersen_no_lookup"))] @@ -8,6 +10,31 @@ mod no_lookup; #[cfg(feature = "pedersen_no_lookup")] pub use no_lookup::pedersen_hash; +/// A stateful hasher for Starknet Pedersen hash. +#[derive(Debug, Default)] +pub struct PedersenHasher { + hash: Felt, + len: usize, +} + +impl PedersenHasher { + /// Creates a new [`PedersenHasher`]. + pub fn new() -> Self { + Self::default() + } + + /// Absorbs message into the hash. + pub fn update(&mut self, msg: Felt) { + self.hash = pedersen_hash(&self.hash, &msg); + self.len += 1; + } + + /// Finishes and returns hash. + pub fn finalize(&self) -> Felt { + pedersen_hash(&self.hash, &self.len.into()) + } +} + #[cfg(test)] mod tests { use super::*;