From 15b4c37ab01530f7e13a4987baf46e02f49d0015 Mon Sep 17 00:00:00 2001 From: Kobi Gurkan Date: Wed, 1 Aug 2018 09:26:30 +0300 Subject: [PATCH] adds test for linear relation between pedersen hash generators --- zcash_primitives/src/jubjub/mod.rs | 170 +++++++++++++++++++---------- 1 file changed, 112 insertions(+), 58 deletions(-) diff --git a/zcash_primitives/src/jubjub/mod.rs b/zcash_primitives/src/jubjub/mod.rs index 40938f3..65e04a0 100644 --- a/zcash_primitives/src/jubjub/mod.rs +++ b/zcash_primitives/src/jubjub/mod.rs @@ -216,28 +216,6 @@ impl JubjubBls12 { fixed_base_circuit_generators: vec![], }; - fn find_group_hash( - m: &[u8], - personalization: &[u8; 8], - params: &E::Params, - ) -> edwards::Point { - let mut tag = m.to_vec(); - let i = tag.len(); - tag.push(0u8); - - loop { - let gh = group_hash(&tag, personalization, params); - - // We don't want to overflow and start reusing generators - assert!(tag[i] != u8::max_value()); - tag[i] += 1; - - if let Some(gh) = gh { - break gh; - } - } - } - // Create the bases for the Pedersen hashes { let mut pedersen_hash_generators = vec![]; @@ -250,26 +228,17 @@ impl JubjubBls12 { .write_u32::(m) .unwrap(); - pedersen_hash_generators.push(find_group_hash( + pedersen_hash_generators.push(JubjubBls12::find_group_hash( &segment_number, constants::PEDERSEN_HASH_GENERATORS_PERSONALIZATION, &tmp_params, )); } - // Check for duplicates, far worse than spec inconsistencies! - for (i, p1) in pedersen_hash_generators.iter().enumerate() { - if p1 == &edwards::Point::zero() { - panic!("Neutral element!"); - } - - for p2 in pedersen_hash_generators.iter().skip(i + 1) { - if p1 == p2 { - panic!("Duplicate generator!"); - } - } - } - + JubjubBls12::check_consistency_of_pedersen_hash_generators( + &tmp_params, + &pedersen_hash_generators, + ); tmp_params.pedersen_hash_generators = pedersen_hash_generators; } @@ -314,43 +283,47 @@ impl JubjubBls12 { let mut fixed_base_generators = vec![edwards::Point::zero(); FixedGenerators::Max as usize]; - fixed_base_generators[FixedGenerators::ProofGenerationKey as usize] = find_group_hash( - &[], - constants::PROOF_GENERATION_KEY_BASE_GENERATOR_PERSONALIZATION, - &tmp_params, - ); + fixed_base_generators[FixedGenerators::ProofGenerationKey as usize] = + JubjubBls12::find_group_hash( + &[], + constants::PROOF_GENERATION_KEY_BASE_GENERATOR_PERSONALIZATION, + &tmp_params, + ); fixed_base_generators[FixedGenerators::NoteCommitmentRandomness as usize] = - find_group_hash( + JubjubBls12::find_group_hash( b"r", constants::PEDERSEN_HASH_GENERATORS_PERSONALIZATION, &tmp_params, ); - fixed_base_generators[FixedGenerators::NullifierPosition as usize] = find_group_hash( - &[], - constants::NULLIFIER_POSITION_IN_TREE_GENERATOR_PERSONALIZATION, - &tmp_params, - ); + fixed_base_generators[FixedGenerators::NullifierPosition as usize] = + JubjubBls12::find_group_hash( + &[], + constants::NULLIFIER_POSITION_IN_TREE_GENERATOR_PERSONALIZATION, + &tmp_params, + ); - fixed_base_generators[FixedGenerators::ValueCommitmentValue as usize] = find_group_hash( - b"v", - constants::VALUE_COMMITMENT_GENERATOR_PERSONALIZATION, - &tmp_params, - ); + fixed_base_generators[FixedGenerators::ValueCommitmentValue as usize] = + JubjubBls12::find_group_hash( + b"v", + constants::VALUE_COMMITMENT_GENERATOR_PERSONALIZATION, + &tmp_params, + ); fixed_base_generators[FixedGenerators::ValueCommitmentRandomness as usize] = - find_group_hash( + JubjubBls12::find_group_hash( b"r", constants::VALUE_COMMITMENT_GENERATOR_PERSONALIZATION, &tmp_params, ); - fixed_base_generators[FixedGenerators::SpendingKeyGenerator as usize] = find_group_hash( - &[], - constants::SPENDING_KEY_GENERATOR_PERSONALIZATION, - &tmp_params, - ); + fixed_base_generators[FixedGenerators::SpendingKeyGenerator as usize] = + JubjubBls12::find_group_hash( + &[], + constants::SPENDING_KEY_GENERATOR_PERSONALIZATION, + &tmp_params, + ); // Check for duplicates, far worse than spec inconsistencies! for (i, p1) in fixed_base_generators.iter().enumerate() { @@ -427,6 +400,55 @@ impl JubjubBls12 { tmp_params } + + fn find_group_hash( + m: &[u8], + personalization: &[u8; 8], + params: &E::Params, + ) -> edwards::Point { + let mut tag = m.to_vec(); + let i = tag.len(); + tag.push(0u8); + + loop { + let gh = group_hash(&tag, personalization, params); + + // We don't want to overflow and start reusing generators + assert!(tag[i] != u8::max_value()); + tag[i] += 1; + + if let Some(gh) = gh { + break gh; + } + } + } + + /// Check for simple relations between the generators, that make finding collisions easy; + /// far worse than spec inconsistencies! + fn check_consistency_of_pedersen_hash_generators( + tmp_params: &E::Params, + pedersen_hash_generators: &[edwards::Point], + ) { + let sum = &edwards::Point::zero(); + for (i, p1) in pedersen_hash_generators.iter().enumerate() { + if p1 == &edwards::Point::zero() { + panic!("Neutral element!"); + } + // Used for checking no generator is a sum of previous ones. + let sum = &sum.add(&p1, &tmp_params); + for p2 in pedersen_hash_generators.iter().skip(i + 1) { + if p1 == p2 { + panic!("Duplicate generator!"); + } + if p1 == &p2.negate() { + panic!("Inverse generator!"); + } + if sum == p2 { + panic!("Linear relation between generators!"); + } + } + } + } } #[test] @@ -464,3 +486,35 @@ fn test_jubjub_bls12() { assert!(p == q); } + +#[test] +#[should_panic(expected = "Linear relation between generators!")] +fn test_jubjub_bls12_pedersen_hash_generators_consistency_check_linear_relation() { + let params = JubjubBls12::new(); + + let mut pedersen_hash_generators: Vec> = vec![]; + + use byteorder::{LittleEndian, WriteBytesExt}; + + for m in 0..5 { + let mut segment_number = [0u8; 4]; + (&mut segment_number[0..4]) + .write_u32::(m) + .unwrap(); + + let p = JubjubBls12::find_group_hash( + &segment_number, + constants::PEDERSEN_HASH_GENERATORS_PERSONALIZATION, + ¶ms, + ); + pedersen_hash_generators.push(p); + } + + let p1 = pedersen_hash_generators[0].clone(); + let p2 = pedersen_hash_generators[1].clone(); + + //test for linear relation + pedersen_hash_generators.push(p1.add(&p2, ¶ms)); + + JubjubBls12::check_consistency_of_pedersen_hash_generators(¶ms, &pedersen_hash_generators); +}