diff --git a/starknet-core/src/crypto.rs b/starknet-core/src/crypto.rs index 634faab9..1977f4da 100644 --- a/starknet-core/src/crypto.rs +++ b/starknet-core/src/crypto.rs @@ -46,14 +46,19 @@ mod errors { } pub use errors::{EcdsaSignError, EcdsaVerifyError}; -pub fn compute_hash_on_elements(data: &[Felt]) -> Felt { +pub fn compute_hash_on_elements<'a, ESI, II>(data: II) -> Felt +where + ESI: ExactSizeIterator, + II: IntoIterator, +{ let mut current_hash = Felt::ZERO; + let data_iter = data.into_iter(); + let data_len = Felt::from(data_iter.len()); - for item in data.iter() { - current_hash = pedersen_hash(¤t_hash, item); + for elem in data_iter { + current_hash = pedersen_hash(¤t_hash, elem); } - let data_len = Felt::from(data.len()); pedersen_hash(¤t_hash, &data_len) } diff --git a/starknet-crypto/src/poseidon_hash.rs b/starknet-crypto/src/poseidon_hash.rs index c8b15bd9..4f3db345 100644 --- a/starknet-crypto/src/poseidon_hash.rs +++ b/starknet-crypto/src/poseidon_hash.rs @@ -72,20 +72,29 @@ pub fn poseidon_hash_single(x: Felt) -> Felt { /// Computes the Starknet Poseidon hash of an arbitrary number of [Felt]s. /// /// Using this function is the same as using [PoseidonHasher]. -pub fn poseidon_hash_many(msgs: &[Felt]) -> Felt { +pub fn poseidon_hash_many<'a, I: IntoIterator>(msgs: I) -> Felt { let mut state = [Felt::ZERO, Felt::ZERO, Felt::ZERO]; - let mut iter = msgs.chunks_exact(2); + let mut iter = msgs.into_iter(); + + loop { + match iter.next() { + Some(v) => state[0] += *v, + None => { + state[0] += Felt::ONE; + break; + } + } + + match iter.next() { + Some(v) => state[1] += *v, + None => { + state[1] += Felt::ONE; + break; + } + } - for msg in iter.by_ref() { - state[0] += msg[0]; - state[1] += msg[1]; poseidon_permute_comp(&mut state); } - let r = iter.remainder(); - if r.len() == 1 { - state[0] += r[0]; - } - state[r.len()] += Felt::ONE; poseidon_permute_comp(&mut state); state[0]