diff --git a/plonky2/src/fri/prover.rs b/plonky2/src/fri/prover.rs index 43674ad1..d2731600 100644 --- a/plonky2/src/fri/prover.rs +++ b/plonky2/src/fri/prover.rs @@ -1,3 +1,4 @@ +use itertools::Itertools; use plonky2_field::extension_field::{flatten, unflatten, Extendable}; use plonky2_field::polynomial::{PolynomialCoeffs, PolynomialValues}; use plonky2_util::reverse_index_bits_in_place; @@ -116,12 +117,12 @@ fn fri_proof_of_work, C: GenericConfig, c .into_par_iter() .find_any(|&i| { C::InnerHasher::hash( - current_hash + ¤t_hash .elements .iter() .copied() .chain(Some(F::from_canonical_u64(i))) - .collect(), + .collect_vec(), false, ) .elements[0] diff --git a/plonky2/src/hash/gmimc.rs b/plonky2/src/hash/gmimc.rs index 3492e08f..050bdeec 100644 --- a/plonky2/src/hash/gmimc.rs +++ b/plonky2/src/hash/gmimc.rs @@ -107,7 +107,7 @@ impl Hasher for GMiMCHash { type Hash = HashOut; type Permutation = GMiMCPermutation; - fn hash(input: Vec, pad: bool) -> Self::Hash { + fn hash(input: &[F], pad: bool) -> Self::Hash { hash_n_to_hash::(input, pad) } diff --git a/plonky2/src/hash/hashing.rs b/plonky2/src/hash/hashing.rs index 2f6a725c..0867eaa8 100644 --- a/plonky2/src/hash/hashing.rs +++ b/plonky2/src/hash/hashing.rs @@ -18,7 +18,7 @@ pub fn hash_or_noop>(inputs: Vec) -> Ha if inputs.len() <= 4 { HashOut::from_partial(inputs) } else { - hash_n_to_hash::(inputs, false) + hash_n_to_hash::(&inputs, false) } } @@ -101,16 +101,18 @@ pub trait PlonkyPermutation { /// for the hash to be secure, but it can safely be disabled in certain cases, like if the input /// length is fixed. pub fn hash_n_to_m>( - mut inputs: Vec, + inputs: &[F], num_outputs: usize, pad: bool, ) -> Vec { if pad { - inputs.push(F::ZERO); - while (inputs.len() + 1) % SPONGE_WIDTH != 0 { - inputs.push(F::ONE); + let mut padded_inputs = inputs.to_vec(); + padded_inputs.push(F::ZERO); + while (padded_inputs.len() + 1) % SPONGE_WIDTH != 0 { + padded_inputs.push(F::ONE); } - inputs.push(F::ZERO); + padded_inputs.push(F::ZERO); + return hash_n_to_m::(&padded_inputs, num_outputs, false); } let mut state = [F::ZERO; SPONGE_WIDTH]; @@ -135,7 +137,7 @@ pub fn hash_n_to_m>( } pub fn hash_n_to_hash>( - inputs: Vec, + inputs: &[F], pad: bool, ) -> HashOut { HashOut::from_vec(hash_n_to_m::(inputs, 4, pad)) diff --git a/plonky2/src/hash/keccak.rs b/plonky2/src/hash/keccak.rs index 78cf5dc3..a537f5e3 100644 --- a/plonky2/src/hash/keccak.rs +++ b/plonky2/src/hash/keccak.rs @@ -56,9 +56,9 @@ impl Hasher for KeccakHash { type Hash = BytesHash; type Permutation = KeccakPermutation; - fn hash(input: Vec, _pad: bool) -> Self::Hash { + fn hash(input: &[F], _pad: bool) -> Self::Hash { let mut buffer = Buffer::new(Vec::new()); - buffer.write_field_vec(&input).unwrap(); + buffer.write_field_vec(input).unwrap(); let mut arr = [0; N]; let hash_bytes = keccak(buffer.bytes()).0; arr.copy_from_slice(&hash_bytes[..N]); diff --git a/plonky2/src/hash/merkle_proofs.rs b/plonky2/src/hash/merkle_proofs.rs index 543c06fd..60fe236a 100644 --- a/plonky2/src/hash/merkle_proofs.rs +++ b/plonky2/src/hash/merkle_proofs.rs @@ -32,7 +32,7 @@ pub(crate) fn verify_merkle_proof>( proof: &MerkleProof, ) -> Result<()> { let mut index = leaf_index; - let mut current_digest = H::hash(leaf_data, false); + let mut current_digest = H::hash(&leaf_data, false); for &sibling_digest in proof.siblings.iter() { let bit = index & 1; index >>= 1; diff --git a/plonky2/src/hash/merkle_tree.rs b/plonky2/src/hash/merkle_tree.rs index 88c1ebdc..8f191366 100644 --- a/plonky2/src/hash/merkle_tree.rs +++ b/plonky2/src/hash/merkle_tree.rs @@ -36,21 +36,24 @@ pub struct MerkleTree> { impl> MerkleTree { pub fn new(leaves: Vec>, cap_height: usize) -> Self { - let mut layers = vec![leaves + let mut current_layer = leaves .par_iter() - .map(|l| H::hash(l.clone(), false)) - .collect::>()]; - while let Some(l) = layers.last() { - if l.len() == 1 << cap_height { - break; + .map(|l| H::hash(l, false)) + .collect::>(); + + let mut layers = vec![]; + let cap = loop { + if current_layer.len() == 1 << cap_height { + break current_layer; } - let next_layer = l + let next_layer = current_layer .par_chunks(2) .map(|chunk| H::two_to_one(chunk[0], chunk[1])) .collect::>(); - layers.push(next_layer); - } - let cap = layers.pop().unwrap(); + layers.push(current_layer); + current_layer = next_layer; + }; + Self { leaves, layers, diff --git a/plonky2/src/hash/path_compression.rs b/plonky2/src/hash/path_compression.rs index 75c63331..c5c3f36e 100644 --- a/plonky2/src/hash/path_compression.rs +++ b/plonky2/src/hash/path_compression.rs @@ -66,7 +66,7 @@ pub(crate) fn decompress_merkle_proofs>( for (&i, v) in leaves_indices.iter().zip(leaves_data) { // Observe the leaves. - seen.insert(i + num_leaves, H::hash(v.to_vec(), false)); + seen.insert(i + num_leaves, H::hash(v, false)); } // Iterators over the siblings. diff --git a/plonky2/src/hash/poseidon.rs b/plonky2/src/hash/poseidon.rs index 606dfd13..81fc3937 100644 --- a/plonky2/src/hash/poseidon.rs +++ b/plonky2/src/hash/poseidon.rs @@ -633,7 +633,7 @@ impl Hasher for PoseidonHash { type Hash = HashOut; type Permutation = PoseidonPermutation; - fn hash(input: Vec, pad: bool) -> Self::Hash { + fn hash(input: &[F], pad: bool) -> Self::Hash { hash_n_to_hash::(input, pad) } diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index d5a2192b..33b44054 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -725,7 +725,7 @@ impl, const D: usize> CircuitBuilder { constants_sigmas_cap.flatten(), vec![/* Add other circuit data here */], ]; - let circuit_digest = C::Hasher::hash(circuit_digest_parts.concat(), false); + let circuit_digest = C::Hasher::hash(&circuit_digest_parts.concat(), false); let common = CommonCircuitData { config: self.config, diff --git a/plonky2/src/plonk/config.rs b/plonky2/src/plonk/config.rs index 461a9573..72d5487e 100644 --- a/plonky2/src/plonk/config.rs +++ b/plonky2/src/plonk/config.rs @@ -32,7 +32,7 @@ pub trait Hasher: Sized + Clone + Debug + Eq + PartialEq { /// Permutation used in the sponge construction. type Permutation: PlonkyPermutation; - fn hash(input: Vec, pad: bool) -> Self::Hash; + fn hash(input: &[F], pad: bool) -> Self::Hash; fn two_to_one(left: Self::Hash, right: Self::Hash) -> Self::Hash; } diff --git a/plonky2/src/plonk/get_challenges.rs b/plonky2/src/plonk/get_challenges.rs index c340cef9..d28f29da 100644 --- a/plonky2/src/plonk/get_challenges.rs +++ b/plonky2/src/plonk/get_challenges.rs @@ -1,5 +1,6 @@ use std::collections::HashSet; +use itertools::Itertools; use plonky2_field::extension_field::Extendable; use plonky2_field::polynomial::PolynomialCoeffs; @@ -65,13 +66,13 @@ fn get_challenges, C: GenericConfig, cons challenger.observe_extension_elements(&final_poly.coeffs); let fri_pow_response = C::InnerHasher::hash( - challenger + &challenger .get_hash() .elements .iter() .copied() .chain(Some(pow_witness)) - .collect(), + .collect_vec(), false, ) .elements[0]; diff --git a/plonky2/src/plonk/proof.rs b/plonky2/src/plonk/proof.rs index cd49de89..07ca7c9e 100644 --- a/plonky2/src/plonk/proof.rs +++ b/plonky2/src/plonk/proof.rs @@ -90,7 +90,7 @@ impl, C: GenericConfig, const D: usize> pub(crate) fn get_public_inputs_hash( &self, ) -> <>::InnerHasher as Hasher>::Hash { - C::InnerHasher::hash(self.public_inputs.clone(), true) + C::InnerHasher::hash(&self.public_inputs, true) } pub fn to_bytes(&self) -> anyhow::Result> { @@ -206,7 +206,7 @@ impl, C: GenericConfig, const D: usize> pub(crate) fn get_public_inputs_hash( &self, ) -> <>::InnerHasher as Hasher>::Hash { - C::InnerHasher::hash(self.public_inputs.clone(), true) + C::InnerHasher::hash(&self.public_inputs, true) } pub fn to_bytes(&self) -> anyhow::Result> { diff --git a/plonky2/src/plonk/prover.rs b/plonky2/src/plonk/prover.rs index 64730ea3..0dd2aba2 100644 --- a/plonky2/src/plonk/prover.rs +++ b/plonky2/src/plonk/prover.rs @@ -43,7 +43,7 @@ pub(crate) fn prove, C: GenericConfig, co ); let public_inputs = partition_witness.get_targets(&prover_data.public_inputs); - let public_inputs_hash = C::InnerHasher::hash(public_inputs.clone(), true); + let public_inputs_hash = C::InnerHasher::hash(&public_inputs, true); if cfg!(debug_assertions) { // Display the marked targets for debugging purposes.