diff --git a/crates/starknet-types-core/src/hash/pedersen.rs b/crates/starknet-types-core/src/hash/pedersen.rs index 2102d797..129b6e07 100644 --- a/crates/starknet-types-core/src/hash/pedersen.rs +++ b/crates/starknet-types-core/src/hash/pedersen.rs @@ -17,6 +17,9 @@ impl StarkHash for Pedersen { /// Computes the Pedersen hash of an array of Felts, as defined /// in + /// + /// Warning: there is room for collision as: + /// Pedersen::hash_array([value]) and Pedersen::hash(Pedersen::hash(0, value), 1) will return the same values fn hash_array(felts: &[Felt]) -> Felt { let data_len = Felt::from(felts.len()); let current_hash: FieldElement = felts @@ -26,12 +29,43 @@ impl StarkHash for Pedersen { }); Felt(PedersenStarkCurve::hash(¤t_hash, &data_len.0)) } + + /// Computes the Pedersen hash of a single Felt + /// + /// Warning: there is room for collision as: + /// Pedersen::hash_single(value) and Pedersen::hash(value, 0) will return the same values + fn hash_single(felt: &Felt) -> Felt { + Felt(PedersenStarkCurve::hash(&felt.0, &Felt::from(0).0)) + } } #[cfg(test)] mod tests { use super::*; + #[test] + fn test_pedersen_hash_single() { + let x = + Felt::from_hex("0x03d937c035c878245caf64531a5756109c53068da139362728feb561405371cb") + .unwrap(); + assert_eq!( + Pedersen::hash_single(&x), + Felt::from_hex("0x460ded9dacd215bcfc43f1b30b2a02690378e00f82a2283617d47d948c7b7f1") + .unwrap() + ) + } + + #[test] + fn test_pedersen_hash_collision() { + let x = + Felt::from_hex("0x03d937c035c878245caf64531a5756109c53068da139362728feb561405371cb") + .unwrap(); + assert_eq!( + Pedersen::hash_single(&x), + Pedersen::hash(&x, &Felt::from(0)) + ) + } + #[test] fn test_pedersen_hash() { let x = diff --git a/crates/starknet-types-core/src/hash/poseidon.rs b/crates/starknet-types-core/src/hash/poseidon.rs index ec6fc68d..f445b93d 100644 --- a/crates/starknet-types-core/src/hash/poseidon.rs +++ b/crates/starknet-types-core/src/hash/poseidon.rs @@ -28,6 +28,10 @@ impl StarkHash for Poseidon { ) })) } + + fn hash_single(felt: &Felt) -> Felt { + Felt(PoseidonCairoStark252::hash_single(&felt.0)) + } } impl Poseidon { @@ -46,6 +50,17 @@ impl Poseidon { mod tests { use super::*; + #[test] + fn test_poseidon_single() { + let x = Felt::from_hex("0x9").unwrap(); + + assert_eq!( + Poseidon::hash_single(&x), + Felt::from_hex("0x3bb3b91c714cb47003947f36dadc98326176963c434cd0a10320b8146c948b3") + .unwrap() + ); + } + #[test] fn test_poseidon_hash() { let x = diff --git a/crates/starknet-types-core/src/hash/traits.rs b/crates/starknet-types-core/src/hash/traits.rs index 72036ab4..00fbe8fd 100644 --- a/crates/starknet-types-core/src/hash/traits.rs +++ b/crates/starknet-types-core/src/hash/traits.rs @@ -7,4 +7,6 @@ pub trait StarkHash { /// Computes the hash of an array of Felts, /// as defined in fn hash_array(felts: &[Felt]) -> Felt; + + fn hash_single(felt: &Felt) -> Felt; }