Skip to content

Commit

Permalink
feat: make hasher accept iterators rather than arrays (#594)
Browse files Browse the repository at this point in the history
* feat: poseidon_hash_may takes an iterator

* feat: compute_hash_on_elements takes ExactSizeIterator

* fix bug
  • Loading branch information
tdelabro authored Jun 17, 2024
1 parent 33581e3 commit bdb2663
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 14 deletions.
13 changes: 9 additions & 4 deletions starknet-core/src/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Item = &'a Felt>,
II: IntoIterator<IntoIter = ESI>,
{
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(&current_hash, item);
for elem in data_iter {
current_hash = pedersen_hash(&current_hash, elem);
}

let data_len = Felt::from(data.len());
pedersen_hash(&current_hash, &data_len)
}

Expand Down
29 changes: 19 additions & 10 deletions starknet-crypto/src/poseidon_hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Item = &'a Felt>>(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]
Expand Down

0 comments on commit bdb2663

Please sign in to comment.