starknet_crypto/pedersen_hash/
mod.rs

1use starknet_types_core::felt::Felt;
2
3#[cfg(not(feature = "pedersen_no_lookup"))]
4mod default;
5#[cfg(not(feature = "pedersen_no_lookup"))]
6pub use default::pedersen_hash;
7
8#[cfg(feature = "pedersen_no_lookup")]
9mod no_lookup;
10#[cfg(feature = "pedersen_no_lookup")]
11pub use no_lookup::pedersen_hash;
12
13/// A stateful hasher for Starknet Pedersen hash.
14#[derive(Debug, Default)]
15pub struct PedersenHasher {
16    hash: Felt,
17    len: usize,
18}
19
20impl PedersenHasher {
21    /// Creates a new [`PedersenHasher`].
22    pub fn new() -> Self {
23        Self::default()
24    }
25
26    /// Absorbs message into the hash.
27    pub fn update(&mut self, msg: Felt) {
28        self.hash = pedersen_hash(&self.hash, &msg);
29        self.len += 1;
30    }
31
32    /// Finishes and returns hash.
33    pub fn finalize(&self) -> Felt {
34        pedersen_hash(&self.hash, &self.len.into())
35    }
36}
37
38#[cfg(test)]
39mod tests {
40    use super::*;
41    use crate::test_utils::field_element_from_be_hex;
42
43    // Test case ported from:
44    //   https://github.com/starkware-libs/starkex-for-spot-trading/blob/607f0b4ce507e1d95cd018d206a2797f6ba4aab4/src/starkware/crypto/starkware/crypto/signature/test/config/signature_test_data.json
45
46    #[test]
47    #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
48    fn test_pedersen_hash() {
49        let test_data = [
50            (
51                "03d937c035c878245caf64531a5756109c53068da139362728feb561405371cb",
52                "0208a0a10250e382e1e4bbe2880906c2791bf6275695e02fbbc6aeff9cd8b31a",
53                "030e480bed5fe53fa909cc0f8c4d99b8f9f2c016be4c41e13a4848797979c662",
54            ),
55            (
56                "058f580910a6ca59b28927c08fe6c43e2e303ca384badc365795fc645d479d45",
57                "078734f65a067be9bdb39de18434d71e79f7b6466a4b66bbd979ab9e7515fe0b",
58                "068cc0b76cddd1dd4ed2301ada9b7c872b23875d5ff837b3a87993e0d9996b87",
59            ),
60        ];
61
62        for (in1, in2, expected_hash) in test_data {
63            let in1 = field_element_from_be_hex(in1);
64            let in2 = field_element_from_be_hex(in2);
65            let expected_hash = field_element_from_be_hex(expected_hash);
66
67            assert_eq!(pedersen_hash(&in1, &in2), expected_hash);
68        }
69    }
70}