From dfc677b130ec6179090314fef478b47ff2870f05 Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Tue, 19 Oct 2021 18:41:15 -0700 Subject: [PATCH] crypto: use new `poseidon377` API https://github.com/penumbra-zone/poseidon377/pull/4 reworked the `poseidon377` API to allow direct access to the permutation state, allowing the hash_n functions to be moved into that crate. --- crypto/src/asset.rs | 7 +-- crypto/src/keys/diversifier.rs | 6 +-- crypto/src/lib.rs | 2 - crypto/src/merkle.rs | 3 +- crypto/src/note.rs | 4 +- crypto/src/poseidon_hash.rs | 90 ---------------------------------- 6 files changed, 9 insertions(+), 103 deletions(-) delete mode 100644 crypto/src/poseidon_hash.rs diff --git a/crypto/src/asset.rs b/crypto/src/asset.rs index 1fff953c9a..b06e35926a 100644 --- a/crypto/src/asset.rs +++ b/crypto/src/asset.rs @@ -57,9 +57,10 @@ static VALUE_GENERATOR_DOMAIN_SEP: Lazy = Lazy::new(|| { impl Id { /// Compute the value commitment generator for this asset. pub fn value_generator(&self) -> decaf377::Element { - use crate::poseidon_hash::hash_1; - let hash = hash_1(&VALUE_GENERATOR_DOMAIN_SEP, self.0); - decaf377::Element::map_to_group_cdh(&hash) + decaf377::Element::map_to_group_cdh(&poseidon377::hash_1( + &VALUE_GENERATOR_DOMAIN_SEP, + self.0, + )) } } diff --git a/crypto/src/keys/diversifier.rs b/crypto/src/keys/diversifier.rs index e781bb4a6f..a21964938b 100644 --- a/crypto/src/keys/diversifier.rs +++ b/crypto/src/keys/diversifier.rs @@ -26,11 +26,9 @@ impl Diversifier { /// Generate the diversified basepoint. pub fn diversified_generator(&self) -> decaf377::Element { - use crate::poseidon_hash::hash_1; - let hash = hash_1( + decaf377::Element::map_to_group_cdh(&poseidon377::hash_1( &DIVERSIFY_GENERATOR_DOMAIN_SEP, Fq::from_le_bytes_mod_order(&self.0[..]), - ); - decaf377::Element::map_to_group_cdh(&hash) + )) } } diff --git a/crypto/src/lib.rs b/crypto/src/lib.rs index e85e735fe1..a78fc166a5 100644 --- a/crypto/src/lib.rs +++ b/crypto/src/lib.rs @@ -16,8 +16,6 @@ pub mod proofs; pub mod transaction; pub mod value; -mod poseidon_hash; - pub use action::output::Output; pub use action::spend::Spend; pub use note::Note; diff --git a/crypto/src/merkle.rs b/crypto/src/merkle.rs index 6008e7158a..461aecd742 100644 --- a/crypto/src/merkle.rs +++ b/crypto/src/merkle.rs @@ -5,7 +5,6 @@ use incrementalmerkletree; use once_cell::sync::Lazy; use crate::note; -use crate::poseidon_hash::hash_2; pub use incrementalmerkletree::{ bridgetree::{self, AuthFragment, BridgeTree}, @@ -46,6 +45,6 @@ impl Hashable for note::Commitment { // extend to build domain sep let level_fq: Fq = u8::from(level).into(); let level_domain_sep: Fq = *MERKLE_DOMAIN_SEP + level_fq; - note::Commitment(hash_2(&level_domain_sep, (a.0, b.0))) + note::Commitment(poseidon377::hash_2(&level_domain_sep, (a.0, b.0))) } } diff --git a/crypto/src/note.rs b/crypto/src/note.rs index 1b13886579..e917a7e1ac 100644 --- a/crypto/src/note.rs +++ b/crypto/src/note.rs @@ -1,7 +1,7 @@ use ark_ff::PrimeField; use once_cell::sync::Lazy; -use crate::{addresses::PaymentAddress, keys, poseidon_hash::hash_5, Fq, Value}; +use crate::{addresses::PaymentAddress, keys, Fq, Value}; // TODO: Should have a `leadByte` as in Sapling and Orchard note plaintexts? // Do we need that in addition to the tx version? @@ -38,7 +38,7 @@ impl Note { } pub fn commit(&self) -> Commitment { - let commit = hash_5( + let commit = poseidon377::hash_5( &NOTECOMMIT_DOMAIN_SEP, ( self.note_blinding, diff --git a/crypto/src/poseidon_hash.rs b/crypto/src/poseidon_hash.rs deleted file mode 100644 index 6ce32a76d1..0000000000 --- a/crypto/src/poseidon_hash.rs +++ /dev/null @@ -1,90 +0,0 @@ -// XXX move into poseidon377 crate? - -// allow unused since this module is garbage stub code -#![allow(unused)] - -use crate::Fq; - -use poseidon377::ark_sponge::{ - poseidon::PoseidonSponge, CryptographicSponge, FieldBasedCryptographicSponge, -}; - -pub fn hash_1(domain_separator: &Fq, value: Fq) -> Fq { - // we want to set the capacity to domain_separator and the rate to value, - // then run the sponge and extract the rate. it's a bit hard to do this - // using the ark-sponge api, which is trying to do a higher-level duplex - // construction and doesn't allow access to the underlying sponge - - let mut sponge = PoseidonSponge::new(&poseidon377::params::rate_1()); - - // arkworks sponge api doesn't let us call permute - // - // best we can do now is to look in the source to see how the rate and - // capacity are arranged and try to plumb the functionality we want through - // the higher-level API - // - // arkworks uses (rate || capacity) instead of (capacity || rate) - // - // this also gives incompatible outputs, but let's deal with that later - - // set the capacity - assert_eq!(sponge.state.len(), 2); - sponge.state[1] = *domain_separator; - - // now use absorb to set the rate (hopefully) - sponge.absorb(&value); - // and squeeze an element - let out_vec = sponge.squeeze_native_field_elements(1); - - out_vec.into_iter().next().unwrap() -} - -pub fn hash_2(domain_separator: &Fq, value: (Fq, Fq)) -> Fq { - let mut sponge = PoseidonSponge::new(&poseidon377::params::rate_2()); - assert_eq!(sponge.state.len(), 3); - sponge.state[2] = *domain_separator; - - // now use absorb to set the rate (hopefully) - sponge.absorb(&value.0); - sponge.absorb(&value.1); - - // and squeeze an element - let out_vec = sponge.squeeze_native_field_elements(1); - - out_vec.into_iter().next().unwrap() -} - -pub fn hash_4(domain_separator: &Fq, value: (Fq, Fq, Fq, Fq)) -> Fq { - let mut sponge = PoseidonSponge::new(&poseidon377::params::rate_4()); - assert_eq!(sponge.state.len(), 5); - sponge.state[4] = *domain_separator; - - // now use absorb to set the rate (hopefully) - sponge.absorb(&value.0); - sponge.absorb(&value.1); - sponge.absorb(&value.2); - sponge.absorb(&value.3); - - // and squeeze an element - let out_vec = sponge.squeeze_native_field_elements(1); - - out_vec.into_iter().next().unwrap() -} - -pub fn hash_5(domain_separator: &Fq, value: (Fq, Fq, Fq, Fq, Fq)) -> Fq { - let mut sponge = PoseidonSponge::new(&poseidon377::params::rate_5()); - assert_eq!(sponge.state.len(), 6); - sponge.state[5] = *domain_separator; - - // now use absorb to set the rate (hopefully) - sponge.absorb(&value.0); - sponge.absorb(&value.1); - sponge.absorb(&value.2); - sponge.absorb(&value.3); - sponge.absorb(&value.4); - - // and squeeze an element - let out_vec = sponge.squeeze_native_field_elements(1); - - out_vec.into_iter().next().unwrap() -}