Force personalization of Pedersen hashes.

This commit is contained in:
Sean Bowe 2018-02-20 13:16:41 -07:00
parent 39175a0c2a
commit d779f31ccd
No known key found for this signature in database
GPG Key ID: 95684257D8F8B031
2 changed files with 46 additions and 6 deletions

View File

@ -10,18 +10,42 @@ use bellman::{
};
use super::lookup::*;
pub enum Personalization {
NoteCommitment,
AnotherPersonalization
}
impl Personalization {
fn get_constant_bools(&self) -> Vec<Boolean> {
self.get_bits()
.into_iter()
.map(|e| Boolean::constant(e))
.collect()
}
pub fn get_bits(&self) -> Vec<bool> {
match *self {
Personalization::NoteCommitment =>
vec![false, false, false, false, false, false],
Personalization::AnotherPersonalization =>
vec![false, false, false, false, false, true],
}
}
}
pub fn pedersen_hash<E: JubjubEngine, CS>(
mut cs: CS,
personalization: Personalization,
bits: &[Boolean],
params: &E::Params
) -> Result<EdwardsPoint<E>, SynthesisError>
where CS: ConstraintSystem<E>
{
// 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::<Bls12, _>(
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::<Bls12, _>(
Personalization::AnotherPersonalization,
input.into_iter(),
params
).into_xy();
assert!(res.x.get_value().unwrap() != unexpected.0);
assert!(res.y.get_value().unwrap() != unexpected.1);
}
}
}

View File

@ -1,14 +1,17 @@
use jubjub::*;
use pairing::*;
use circuit::pedersen_hash::Personalization;
pub fn pedersen_hash<E, I>(
personalization: Personalization,
bits: I,
params: &E::Params
) -> edwards::Point<E, PrimeOrder>
where I: IntoIterator<Item=bool>,
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();