mirror of
https://github.com/Qortal/pirate-librustzcash.git
synced 2025-02-15 03:05:48 +00:00
Personalize GH for each generator independently.
This commit is contained in:
parent
b831942501
commit
f155c01cf5
@ -517,7 +517,7 @@ fn test_input_circuit_with_bls12_381() {
|
|||||||
|
|
||||||
assert!(cs.is_satisfied());
|
assert!(cs.is_satisfied());
|
||||||
assert_eq!(cs.num_constraints(), 97395);
|
assert_eq!(cs.num_constraints(), 97395);
|
||||||
assert_eq!(cs.hash(), "9f730803965612392772c3c1fbb110c1539656e1bab40d5a9a124b06e927ef40");
|
assert_eq!(cs.hash(), "9abc0559abf54a41da789313b1692dc744d940646bb7dd3e6c01ceb54d0cc261");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -555,6 +555,6 @@ fn test_output_circuit_with_bls12_381() {
|
|||||||
|
|
||||||
assert!(cs.is_satisfied());
|
assert!(cs.is_satisfied());
|
||||||
assert_eq!(cs.num_constraints(), 7827);
|
assert_eq!(cs.num_constraints(), 7827);
|
||||||
assert_eq!(cs.hash(), "f4219872738a81ef3ea66199ea5019d87f53ec369ee7f64d0b7c63ade6014114");
|
assert_eq!(cs.hash(), "2896f259ad7a50c83604976ee9362358396d547b70f2feaf91d82d287e4ffc1d");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -201,17 +201,65 @@ impl JubjubBls12 {
|
|||||||
|
|
||||||
// Create the bases for other parts of the protocol
|
// Create the bases for other parts of the protocol
|
||||||
{
|
{
|
||||||
let mut cur = 0;
|
let mut fixed_base_generators = vec![edwards::Point::zero(); FixedGenerators::Max as usize];
|
||||||
let mut fixed_base_generators = vec![];
|
|
||||||
|
|
||||||
while fixed_base_generators.len() < (FixedGenerators::Max as usize) {
|
{
|
||||||
let gh = group_hash(&[cur], ::OTHER_PERSONALIZATION, &tmp);
|
// Each generator is found by invoking the group hash
|
||||||
// We don't want to overflow and start reusing generators
|
// on tag 0x00, 0x01, ... until we find a valid result.
|
||||||
assert!(cur != u8::max_value());
|
let find_first_gh = |personalization| {
|
||||||
cur += 1;
|
let mut cur = 0;
|
||||||
|
|
||||||
if let Some(gh) = gh {
|
loop {
|
||||||
fixed_base_generators.push(gh);
|
let gh = group_hash::<Bls12>(&[cur], personalization, &tmp);
|
||||||
|
// We don't want to overflow.
|
||||||
|
assert!(cur != u8::max_value());
|
||||||
|
cur += 1;
|
||||||
|
|
||||||
|
if let Some(gh) = gh {
|
||||||
|
break gh;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Written this way for exhaustion (double entendre). There's no
|
||||||
|
// way to iterate over the variants of an enum, so it's hideous.
|
||||||
|
for c in 0..(FixedGenerators::Max as usize) {
|
||||||
|
let p = match c {
|
||||||
|
c if c == (FixedGenerators::ProvingPublicKey as usize) => {
|
||||||
|
::PROVING_KEY_BASE_GENERATOR_PERSONALIZATION
|
||||||
|
},
|
||||||
|
c if c == (FixedGenerators::NoteCommitmentRandomness as usize) => {
|
||||||
|
::NOTE_COMMITMENT_RANDOMNESS_GENERATOR_PERSONALIZATION
|
||||||
|
},
|
||||||
|
c if c == (FixedGenerators::NullifierPosition as usize) => {
|
||||||
|
::NULLIFIER_POSITION_IN_TREE_GENERATOR_PERSONALIZATION
|
||||||
|
},
|
||||||
|
c if c == (FixedGenerators::ValueCommitmentValue as usize) => {
|
||||||
|
::VALUE_COMMITMENT_VALUE_GENERATOR_PERSONALIZATION
|
||||||
|
},
|
||||||
|
c if c == (FixedGenerators::ValueCommitmentRandomness as usize) => {
|
||||||
|
::VALUE_COMMITMENT_RANDOMNESS_GENERATOR_PERSONALIZATION
|
||||||
|
},
|
||||||
|
c if c == (FixedGenerators::SpendingKeyGenerator as usize) => {
|
||||||
|
::SPENDING_KEY_GENERATOR_PERSONALIZATION
|
||||||
|
},
|
||||||
|
_ => unreachable!()
|
||||||
|
};
|
||||||
|
|
||||||
|
fixed_base_generators[c] = find_first_gh(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for duplicates, far worse than spec inconsistencies!
|
||||||
|
for (i, p1) in fixed_base_generators.iter().enumerate() {
|
||||||
|
if p1 == &edwards::Point::zero() {
|
||||||
|
panic!("Neutral element!");
|
||||||
|
}
|
||||||
|
|
||||||
|
for p2 in fixed_base_generators.iter().skip(i+1) {
|
||||||
|
if p1 == p2 {
|
||||||
|
panic!("Duplicate generator!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,18 +271,23 @@ impl JubjubBls12 {
|
|||||||
{
|
{
|
||||||
let mut pedersen_circuit_generators = vec![];
|
let mut pedersen_circuit_generators = vec![];
|
||||||
|
|
||||||
|
// Process each segment
|
||||||
for mut gen in tmp.pedersen_hash_generators.iter().cloned() {
|
for mut gen in tmp.pedersen_hash_generators.iter().cloned() {
|
||||||
let mut gen = montgomery::Point::from_edwards(&gen, &tmp);
|
let mut gen = montgomery::Point::from_edwards(&gen, &tmp);
|
||||||
let mut windows = vec![];
|
let mut windows = vec![];
|
||||||
for _ in 0..tmp.pedersen_hash_chunks_per_generator() {
|
for _ in 0..tmp.pedersen_hash_chunks_per_generator() {
|
||||||
|
// Create (x, y) coeffs for this chunk
|
||||||
let mut coeffs = vec![];
|
let mut coeffs = vec![];
|
||||||
let mut g = gen.clone();
|
let mut g = gen.clone();
|
||||||
|
|
||||||
|
// coeffs = g, g*2, g*3, g*4
|
||||||
for _ in 0..4 {
|
for _ in 0..4 {
|
||||||
coeffs.push(g.into_xy().expect("cannot produce O"));
|
coeffs.push(g.into_xy().expect("cannot produce O"));
|
||||||
g = g.add(&gen, &tmp);
|
g = g.add(&gen, &tmp);
|
||||||
}
|
}
|
||||||
windows.push(coeffs);
|
windows.push(coeffs);
|
||||||
|
|
||||||
|
// Our chunks are separated by 2 bits to prevent overlap.
|
||||||
for _ in 0..4 {
|
for _ in 0..4 {
|
||||||
gen = gen.double(&tmp);
|
gen = gen.double(&tmp);
|
||||||
}
|
}
|
||||||
@ -261,6 +314,7 @@ impl JubjubBls12 {
|
|||||||
}
|
}
|
||||||
windows.push(coeffs);
|
windows.push(coeffs);
|
||||||
|
|
||||||
|
// gen = gen * 8
|
||||||
gen = g;
|
gen = g;
|
||||||
}
|
}
|
||||||
fixed_base_circuit_generators.push(windows);
|
fixed_base_circuit_generators.push(windows);
|
||||||
|
26
src/lib.rs
26
src/lib.rs
@ -16,10 +16,24 @@ pub mod group_hash;
|
|||||||
pub mod pedersen_hash;
|
pub mod pedersen_hash;
|
||||||
pub mod primitives;
|
pub mod primitives;
|
||||||
|
|
||||||
// BLAKE2s personalizations
|
// BLAKE2s invocation personalizations
|
||||||
pub const CRH_IVK_PERSONALIZATION: &'static [u8; 8] = b"Zcashivk";
|
/// BLAKE2s Personalization for CRH^ivk = BLAKE2s(ak | rk)
|
||||||
pub const PRF_NR_PERSONALIZATION: &'static [u8; 8] = b"WhatTheH";
|
const CRH_IVK_PERSONALIZATION: &'static [u8; 8] = b"Zcashivk";
|
||||||
pub const PEDERSEN_HASH_GENERATORS_PERSONALIZATION: &'static [u8; 8] = b"PEDERSEN";
|
/// BLAKE2s Personalization for PRF^nr = BLAKE2s(rk | cm + position)
|
||||||
|
const PRF_NR_PERSONALIZATION: &'static [u8; 8] = b"WhatTheH";
|
||||||
|
|
||||||
// TODO: Expand the personalizations to the specific generators
|
// Group hash personalizations
|
||||||
pub const OTHER_PERSONALIZATION: &'static [u8; 8] = b"GOTOFAIL";
|
/// BLAKE2s Personalization for Pedersen hash generators.
|
||||||
|
const PEDERSEN_HASH_GENERATORS_PERSONALIZATION: &'static [u8; 8] = b"PEDERSEN";
|
||||||
|
/// BLAKE2s Personalization for the proof generation key base point
|
||||||
|
const PROVING_KEY_BASE_GENERATOR_PERSONALIZATION: &'static [u8; 8] = b"12345678";
|
||||||
|
/// BLAKE2s Personalization for the note commitment randomness generator
|
||||||
|
const NOTE_COMMITMENT_RANDOMNESS_GENERATOR_PERSONALIZATION: &'static [u8; 8] = b"abcdefgh";
|
||||||
|
/// BLAKE2s Personalization for the nullifier position generator (for PRF^nr)
|
||||||
|
const NULLIFIER_POSITION_IN_TREE_GENERATOR_PERSONALIZATION: &'static [u8; 8] = b"nfnfnfnf";
|
||||||
|
/// BLAKE2s Personalization for the value commitment generator for the value
|
||||||
|
const VALUE_COMMITMENT_VALUE_GENERATOR_PERSONALIZATION: &'static [u8; 8] = b"45u8gh45";
|
||||||
|
/// BLAKE2s Personalization for the value commitment randomness generator
|
||||||
|
const VALUE_COMMITMENT_RANDOMNESS_GENERATOR_PERSONALIZATION: &'static [u8; 8] = b"11111111";
|
||||||
|
/// BLAKE2s Personalization for the spending key base point
|
||||||
|
const SPENDING_KEY_GENERATOR_PERSONALIZATION: &'static [u8; 8] = b"sksksksk";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user