diff --git a/src/primitives/poseidon.rs b/src/primitives/poseidon.rs index b80ec0b8..e1954545 100644 --- a/src/primitives/poseidon.rs +++ b/src/primitives/poseidon.rs @@ -1,3 +1,4 @@ +use std::array; use std::iter; use std::marker::PhantomData; @@ -250,15 +251,15 @@ pub trait Domain, const T: usize, const RATE: u /// /// Domain specified in section 4.2 of https://eprint.iacr.org/2019/458.pdf #[derive(Clone, Copy, Debug)] -pub struct ConstantLength(pub usize); +pub struct ConstantLength; -impl, const T: usize, const RATE: usize> Domain - for ConstantLength +impl, const T: usize, const RATE: usize, const L: usize> + Domain for ConstantLength { fn initial_capacity_element(&self) -> F { // Capacity value is $length \cdot 2^64 + (o-1)$ where o is the output length. // We hard-code an output length of 1. - F::from_u128((self.0 as u128) << 64) + F::from_u128((L as u128) << 64) } fn pad_and_add(&self) -> Box, &SpongeState)> { @@ -309,21 +310,14 @@ impl< } } -impl, const T: usize, const RATE: usize> - Hash +impl, const T: usize, const RATE: usize, const L: usize> + Hash, T, RATE> { /// Hashes the given input. - /// - /// # Panics - /// - /// Panics if the message length is not the correct length. - pub fn hash(mut self, message: impl Iterator) -> F { - let mut length = 0; - for (i, value) in message.enumerate() { - length = i + 1; + pub fn hash(mut self, message: [F; L]) -> F { + for value in array::IntoIter::new(message) { self.duplex.absorb(value); } - assert_eq!(length, self.domain.0); self.duplex.squeeze() } } @@ -341,8 +335,8 @@ mod tests { let (round_constants, mds, _) = OrchardNullifier.constants(); - let hasher = Hash::init(OrchardNullifier, ConstantLength(2)); - let result = hasher.hash(message.iter().cloned()); + let hasher = Hash::init(OrchardNullifier, ConstantLength); + let result = hasher.hash(message); // The result should be equivalent to just directly applying the permutation and // taking the first state element as the output. diff --git a/src/spec.rs b/src/spec.rs index f7172513..59003b4f 100644 --- a/src/spec.rs +++ b/src/spec.rs @@ -104,8 +104,7 @@ pub(crate) fn prf_expand_vec(sk: &[u8], ts: &[&[u8]]) -> [u8; 64] { /// /// [concreteprfs]: https://zips.z.cash/protocol/nu5.pdf#concreteprfs pub(crate) fn prf_nf(nk: pallas::Base, rho: pallas::Base) -> pallas::Base { - poseidon::Hash::init(poseidon::OrchardNullifier, poseidon::ConstantLength(2)) - .hash(iter::empty().chain(Some(nk)).chain(Some(rho))) + poseidon::Hash::init(poseidon::OrchardNullifier, poseidon::ConstantLength).hash([nk, rho]) } /// Defined in [Zcash Protocol Spec ยง 5.4.5.5: Orchard Key Agreement][concreteorchardkeyagreement].