diff --git a/src/circuit/pedersen_hash.rs b/src/circuit/pedersen_hash.rs index a405b7a..c540a23 100644 --- a/src/circuit/pedersen_hash.rs +++ b/src/circuit/pedersen_hash.rs @@ -10,18 +10,42 @@ use bellman::{ }; use super::lookup::*; +pub enum Personalization { + NoteCommitment, + AnotherPersonalization +} + +impl Personalization { + fn get_constant_bools(&self) -> Vec { + self.get_bits() + .into_iter() + .map(|e| Boolean::constant(e)) + .collect() + } + + pub fn get_bits(&self) -> Vec { + match *self { + Personalization::NoteCommitment => + vec![false, false, false, false, false, false], + Personalization::AnotherPersonalization => + vec![false, false, false, false, false, true], + } + } +} + pub fn pedersen_hash( mut cs: CS, + personalization: Personalization, bits: &[Boolean], params: &E::Params ) -> Result, SynthesisError> where CS: ConstraintSystem { - // Unnecessary if forced personalization is introduced - assert!(bits.len() > 0); + let personalization = personalization.get_constant_bools(); + assert_eq!(personalization.len(), 6); let mut edwards_result = None; - let mut bits = bits.iter(); + let mut bits = personalization.iter().chain(bits.iter()); let mut segment_generators = params.pedersen_circuit_generators().iter(); let boolean_false = Boolean::constant(false); @@ -124,12 +148,13 @@ mod test { pedersen_hash( cs.namespace(|| "pedersen hash"), + Personalization::NoteCommitment, &input_bools, params ).unwrap(); assert!(cs.is_satisfied()); - assert_eq!(cs.num_constraints(), 1539); + assert_eq!(cs.num_constraints(), 1551); } #[test] @@ -151,6 +176,7 @@ mod test { let res = pedersen_hash( cs.namespace(|| "pedersen hash"), + Personalization::NoteCommitment, &input_bools, params ).unwrap(); @@ -158,12 +184,23 @@ mod test { assert!(cs.is_satisfied()); let expected = ::pedersen_hash::pedersen_hash::( - input.into_iter(), + Personalization::NoteCommitment, + input.clone().into_iter(), params ).into_xy(); assert_eq!(res.x.get_value().unwrap(), expected.0); assert_eq!(res.y.get_value().unwrap(), expected.1); + + // Test against the output of a different personalization + let unexpected = ::pedersen_hash::pedersen_hash::( + Personalization::AnotherPersonalization, + input.into_iter(), + params + ).into_xy(); + + assert!(res.x.get_value().unwrap() != unexpected.0); + assert!(res.y.get_value().unwrap() != unexpected.1); } } } diff --git a/src/pedersen_hash.rs b/src/pedersen_hash.rs index 0bbf7a9..12e5c7d 100644 --- a/src/pedersen_hash.rs +++ b/src/pedersen_hash.rs @@ -1,14 +1,17 @@ use jubjub::*; use pairing::*; +use circuit::pedersen_hash::Personalization; + pub fn pedersen_hash( + personalization: Personalization, bits: I, params: &E::Params ) -> edwards::Point where I: IntoIterator, E: JubjubEngine { - let mut bits = bits.into_iter(); + let mut bits = personalization.get_bits().into_iter().chain(bits.into_iter()); let mut result = edwards::Point::zero(); let mut generators = params.pedersen_hash_generators().iter();