mirror of
https://github.com/Qortal/pirate-librustzcash.git
synced 2025-07-30 20:11:23 +00:00
adds test for linear relation between pedersen hash generators
This commit is contained in:
@@ -216,28 +216,6 @@ impl JubjubBls12 {
|
|||||||
fixed_base_circuit_generators: vec![],
|
fixed_base_circuit_generators: vec![],
|
||||||
};
|
};
|
||||||
|
|
||||||
fn find_group_hash<E: JubjubEngine>(
|
|
||||||
m: &[u8],
|
|
||||||
personalization: &[u8; 8],
|
|
||||||
params: &E::Params,
|
|
||||||
) -> edwards::Point<E, PrimeOrder> {
|
|
||||||
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
|
// Create the bases for the Pedersen hashes
|
||||||
{
|
{
|
||||||
let mut pedersen_hash_generators = vec![];
|
let mut pedersen_hash_generators = vec![];
|
||||||
@@ -250,26 +228,17 @@ impl JubjubBls12 {
|
|||||||
.write_u32::<LittleEndian>(m)
|
.write_u32::<LittleEndian>(m)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
pedersen_hash_generators.push(find_group_hash(
|
pedersen_hash_generators.push(JubjubBls12::find_group_hash(
|
||||||
&segment_number,
|
&segment_number,
|
||||||
constants::PEDERSEN_HASH_GENERATORS_PERSONALIZATION,
|
constants::PEDERSEN_HASH_GENERATORS_PERSONALIZATION,
|
||||||
&tmp_params,
|
&tmp_params,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for duplicates, far worse than spec inconsistencies!
|
JubjubBls12::check_consistency_of_pedersen_hash_generators(
|
||||||
for (i, p1) in pedersen_hash_generators.iter().enumerate() {
|
&tmp_params,
|
||||||
if p1 == &edwards::Point::zero() {
|
&pedersen_hash_generators,
|
||||||
panic!("Neutral element!");
|
);
|
||||||
}
|
|
||||||
|
|
||||||
for p2 in pedersen_hash_generators.iter().skip(i + 1) {
|
|
||||||
if p1 == p2 {
|
|
||||||
panic!("Duplicate generator!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp_params.pedersen_hash_generators = pedersen_hash_generators;
|
tmp_params.pedersen_hash_generators = pedersen_hash_generators;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -314,43 +283,47 @@ impl JubjubBls12 {
|
|||||||
let mut fixed_base_generators =
|
let mut fixed_base_generators =
|
||||||
vec![edwards::Point::zero(); FixedGenerators::Max as usize];
|
vec![edwards::Point::zero(); FixedGenerators::Max as usize];
|
||||||
|
|
||||||
fixed_base_generators[FixedGenerators::ProofGenerationKey as usize] = find_group_hash(
|
fixed_base_generators[FixedGenerators::ProofGenerationKey as usize] =
|
||||||
&[],
|
JubjubBls12::find_group_hash(
|
||||||
constants::PROOF_GENERATION_KEY_BASE_GENERATOR_PERSONALIZATION,
|
&[],
|
||||||
&tmp_params,
|
constants::PROOF_GENERATION_KEY_BASE_GENERATOR_PERSONALIZATION,
|
||||||
);
|
&tmp_params,
|
||||||
|
);
|
||||||
|
|
||||||
fixed_base_generators[FixedGenerators::NoteCommitmentRandomness as usize] =
|
fixed_base_generators[FixedGenerators::NoteCommitmentRandomness as usize] =
|
||||||
find_group_hash(
|
JubjubBls12::find_group_hash(
|
||||||
b"r",
|
b"r",
|
||||||
constants::PEDERSEN_HASH_GENERATORS_PERSONALIZATION,
|
constants::PEDERSEN_HASH_GENERATORS_PERSONALIZATION,
|
||||||
&tmp_params,
|
&tmp_params,
|
||||||
);
|
);
|
||||||
|
|
||||||
fixed_base_generators[FixedGenerators::NullifierPosition as usize] = find_group_hash(
|
fixed_base_generators[FixedGenerators::NullifierPosition as usize] =
|
||||||
&[],
|
JubjubBls12::find_group_hash(
|
||||||
constants::NULLIFIER_POSITION_IN_TREE_GENERATOR_PERSONALIZATION,
|
&[],
|
||||||
&tmp_params,
|
constants::NULLIFIER_POSITION_IN_TREE_GENERATOR_PERSONALIZATION,
|
||||||
);
|
&tmp_params,
|
||||||
|
);
|
||||||
|
|
||||||
fixed_base_generators[FixedGenerators::ValueCommitmentValue as usize] = find_group_hash(
|
fixed_base_generators[FixedGenerators::ValueCommitmentValue as usize] =
|
||||||
b"v",
|
JubjubBls12::find_group_hash(
|
||||||
constants::VALUE_COMMITMENT_GENERATOR_PERSONALIZATION,
|
b"v",
|
||||||
&tmp_params,
|
constants::VALUE_COMMITMENT_GENERATOR_PERSONALIZATION,
|
||||||
);
|
&tmp_params,
|
||||||
|
);
|
||||||
|
|
||||||
fixed_base_generators[FixedGenerators::ValueCommitmentRandomness as usize] =
|
fixed_base_generators[FixedGenerators::ValueCommitmentRandomness as usize] =
|
||||||
find_group_hash(
|
JubjubBls12::find_group_hash(
|
||||||
b"r",
|
b"r",
|
||||||
constants::VALUE_COMMITMENT_GENERATOR_PERSONALIZATION,
|
constants::VALUE_COMMITMENT_GENERATOR_PERSONALIZATION,
|
||||||
&tmp_params,
|
&tmp_params,
|
||||||
);
|
);
|
||||||
|
|
||||||
fixed_base_generators[FixedGenerators::SpendingKeyGenerator as usize] = find_group_hash(
|
fixed_base_generators[FixedGenerators::SpendingKeyGenerator as usize] =
|
||||||
&[],
|
JubjubBls12::find_group_hash(
|
||||||
constants::SPENDING_KEY_GENERATOR_PERSONALIZATION,
|
&[],
|
||||||
&tmp_params,
|
constants::SPENDING_KEY_GENERATOR_PERSONALIZATION,
|
||||||
);
|
&tmp_params,
|
||||||
|
);
|
||||||
|
|
||||||
// Check for duplicates, far worse than spec inconsistencies!
|
// Check for duplicates, far worse than spec inconsistencies!
|
||||||
for (i, p1) in fixed_base_generators.iter().enumerate() {
|
for (i, p1) in fixed_base_generators.iter().enumerate() {
|
||||||
@@ -427,6 +400,55 @@ impl JubjubBls12 {
|
|||||||
|
|
||||||
tmp_params
|
tmp_params
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn find_group_hash<E: JubjubEngine>(
|
||||||
|
m: &[u8],
|
||||||
|
personalization: &[u8; 8],
|
||||||
|
params: &E::Params,
|
||||||
|
) -> edwards::Point<E, PrimeOrder> {
|
||||||
|
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<E: JubjubEngine>(
|
||||||
|
tmp_params: &E::Params,
|
||||||
|
pedersen_hash_generators: &[edwards::Point<E, PrimeOrder>],
|
||||||
|
) {
|
||||||
|
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]
|
#[test]
|
||||||
@@ -464,3 +486,35 @@ fn test_jubjub_bls12() {
|
|||||||
|
|
||||||
assert!(p == q);
|
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<edwards::Point<Bls12, PrimeOrder>> = vec![];
|
||||||
|
|
||||||
|
use byteorder::{LittleEndian, WriteBytesExt};
|
||||||
|
|
||||||
|
for m in 0..5 {
|
||||||
|
let mut segment_number = [0u8; 4];
|
||||||
|
(&mut segment_number[0..4])
|
||||||
|
.write_u32::<LittleEndian>(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);
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user