TODO: reformulate permutation argument
This commit is contained in:
parent
eaaff874fc
commit
ae9716a428
@ -106,6 +106,8 @@ pub fn create_aggregate_on_srs_using_information<E: Engine, C: Circuit<E>, S: Sy
|
|||||||
|
|
||||||
let value = compute_value::<E>(&w, &s_poly_positive, &s_poly_negative);
|
let value = compute_value::<E>(&w, &s_poly_positive, &s_poly_negative);
|
||||||
|
|
||||||
|
println!("Helper s(z, w) = {}", value);
|
||||||
|
|
||||||
let opening = {
|
let opening = {
|
||||||
let mut value = value;
|
let mut value = value;
|
||||||
value.negate();
|
value.negate();
|
||||||
@ -117,20 +119,6 @@ pub fn create_aggregate_on_srs_using_information<E: Engine, C: Circuit<E>, S: Sy
|
|||||||
w,
|
w,
|
||||||
&srs
|
&srs
|
||||||
)
|
)
|
||||||
|
|
||||||
// let poly = kate_divison(
|
|
||||||
// s_poly_negative.iter().rev().chain_ext(Some(value).iter()).chain_ext(s_poly_positive.iter()),
|
|
||||||
// w,
|
|
||||||
// );
|
|
||||||
|
|
||||||
// let negative_poly = poly[0..n].iter().rev();
|
|
||||||
// let positive_poly = poly[n..].iter();
|
|
||||||
// multiexp(
|
|
||||||
// srs.g_negative_x[1..(negative_poly.len() + 1)].iter().chain_ext(
|
|
||||||
// srs.g_positive_x[0..positive_poly.len()].iter()
|
|
||||||
// ),
|
|
||||||
// negative_poly.chain_ext(positive_poly)
|
|
||||||
// ).into_affine()
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Let's open up C to every y.
|
// Let's open up C to every y.
|
||||||
@ -143,22 +131,6 @@ pub fn create_aggregate_on_srs_using_information<E: Engine, C: Circuit<E>, S: Sy
|
|||||||
value.add_assign(&positive_powers_contrib);
|
value.add_assign(&positive_powers_contrib);
|
||||||
value.add_assign(&negative_powers_contrib);
|
value.add_assign(&negative_powers_contrib);
|
||||||
|
|
||||||
// let mut tmp = yinv;
|
|
||||||
// for &coeff in poly_negative {
|
|
||||||
// let mut coeff = coeff;
|
|
||||||
// coeff.mul_assign(&tmp);
|
|
||||||
// value.add_assign(&coeff);
|
|
||||||
// tmp.mul_assign(&yinv);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// let mut tmp = *y;
|
|
||||||
// for &coeff in poly_positive {
|
|
||||||
// let mut coeff = coeff;
|
|
||||||
// coeff.mul_assign(&tmp);
|
|
||||||
// value.add_assign(&coeff);
|
|
||||||
// tmp.mul_assign(&y);
|
|
||||||
// }
|
|
||||||
|
|
||||||
value
|
value
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,20 +152,6 @@ pub fn create_aggregate_on_srs_using_information<E: Engine, C: Circuit<E>, S: Sy
|
|||||||
*y,
|
*y,
|
||||||
&srs
|
&srs
|
||||||
)
|
)
|
||||||
|
|
||||||
// let poly = kate_divison(
|
|
||||||
// s_poly_negative.iter().rev().chain_ext(Some(value).iter()).chain_ext(s_poly_positive.iter()),
|
|
||||||
// *y,
|
|
||||||
// );
|
|
||||||
|
|
||||||
// let negative_poly = poly[0..n].iter().rev();
|
|
||||||
// let positive_poly = poly[n..].iter();
|
|
||||||
// multiexp(
|
|
||||||
// srs.g_negative_x[1..(negative_poly.len() + 1)].iter().chain_ext(
|
|
||||||
// srs.g_positive_x[0..positive_poly.len()].iter()
|
|
||||||
// ),
|
|
||||||
// negative_poly.chain_ext(positive_poly)
|
|
||||||
// ).into_affine()
|
|
||||||
};
|
};
|
||||||
|
|
||||||
c_openings.push((opening, value));
|
c_openings.push((opening, value));
|
||||||
@ -229,15 +187,6 @@ pub fn create_aggregate_on_srs_using_information<E: Engine, C: Circuit<E>, S: Sy
|
|||||||
mul_add_polynomials(& mut poly_negative[..], &s_poly_negative[..], r);
|
mul_add_polynomials(& mut poly_negative[..], &s_poly_negative[..], r);
|
||||||
mul_add_polynomials(& mut poly_positive[..], &s_poly_positive[..], r);
|
mul_add_polynomials(& mut poly_positive[..], &s_poly_positive[..], r);
|
||||||
|
|
||||||
// for (mut coeff, target) in s_poly_negative.into_iter().zip(poly_negative.iter_mut()) {
|
|
||||||
// coeff.mul_assign(&r);
|
|
||||||
// target.add_assign(&coeff);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// for (mut coeff, target) in s_poly_positive.into_iter().zip(poly_positive.iter_mut()) {
|
|
||||||
// coeff.mul_assign(&r);
|
|
||||||
// target.add_assign(&coeff);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("Re-evaluation of {} S polynomials taken {:?}", y_values.len(), start.elapsed());
|
println!("Re-evaluation of {} S polynomials taken {:?}", y_values.len(), start.elapsed());
|
||||||
@ -254,19 +203,6 @@ pub fn create_aggregate_on_srs_using_information<E: Engine, C: Circuit<E>, S: Sy
|
|||||||
&srs
|
&srs
|
||||||
)
|
)
|
||||||
|
|
||||||
// let poly = kate_divison(
|
|
||||||
// poly_negative.iter().rev().chain_ext(Some(value).iter()).chain_ext(poly_positive.iter()),
|
|
||||||
// z,
|
|
||||||
// );
|
|
||||||
|
|
||||||
// let negative_poly = poly[0..n].iter().rev();
|
|
||||||
// let positive_poly = poly[n..].iter();
|
|
||||||
// multiexp(
|
|
||||||
// srs.g_negative_x[1..(negative_poly.len() + 1)].iter().chain_ext(
|
|
||||||
// srs.g_positive_x[0..positive_poly.len()].iter()
|
|
||||||
// ),
|
|
||||||
// negative_poly.chain_ext(positive_poly)
|
|
||||||
// ).into_affine()
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Aggregate {
|
Aggregate {
|
||||||
|
@ -498,47 +498,13 @@ fn test_succinct_sonic_mimc() {
|
|||||||
use crate::sonic::sonic::AdaptorCircuit;
|
use crate::sonic::sonic::AdaptorCircuit;
|
||||||
use crate::sonic::helped::prover::{create_advice_on_srs, create_proof_on_srs};
|
use crate::sonic::helped::prover::{create_advice_on_srs, create_proof_on_srs};
|
||||||
use crate::sonic::helped::{get_circuit_parameters_for_succinct_sonic, MultiVerifier};
|
use crate::sonic::helped::{get_circuit_parameters_for_succinct_sonic, MultiVerifier};
|
||||||
use crate::sonic::helped::helper::{create_aggregate_on_srs};
|
|
||||||
use crate::sonic::sonic::Permutation3;
|
use crate::sonic::sonic::Permutation3;
|
||||||
use crate::sonic::unhelped::permutation_structure::*;
|
use crate::sonic::unhelped::permutation_structure::*;
|
||||||
use crate::sonic::unhelped::SuccinctMultiVerifier;
|
use crate::sonic::unhelped::SuccinctMultiVerifier;
|
||||||
|
use crate::sonic::unhelped::{create_aggregate_on_srs};
|
||||||
|
|
||||||
use crate::sonic::cs::{Circuit, ConstraintSystem, LinearCombination, Coeff};
|
use crate::sonic::cs::{Circuit, ConstraintSystem, LinearCombination, Coeff};
|
||||||
|
|
||||||
struct MyCircuit;
|
|
||||||
|
|
||||||
impl<E: Engine> Circuit<E> for MyCircuit {
|
|
||||||
fn synthesize<CS: ConstraintSystem<E>>(&self, cs: &mut CS) -> Result<(), SynthesisError> {
|
|
||||||
let (a, b, c) = cs.multiply(|| {
|
|
||||||
Ok((
|
|
||||||
E::Fr::from_str("10").unwrap(),
|
|
||||||
E::Fr::from_str("20").unwrap(),
|
|
||||||
E::Fr::from_str("200").unwrap(),
|
|
||||||
))
|
|
||||||
})?;
|
|
||||||
|
|
||||||
cs.enforce_zero(LinearCombination::zero() + (Coeff::Full(E::Fr::from_str("2").unwrap()), a) - b);
|
|
||||||
|
|
||||||
let multiplier = cs.alloc_input(|| Ok(E::Fr::from_str("20").unwrap()))?;
|
|
||||||
|
|
||||||
cs.enforce_zero(LinearCombination::from(b) - multiplier);
|
|
||||||
|
|
||||||
let (a1, b1, _) = cs.multiply(|| {
|
|
||||||
Ok((
|
|
||||||
E::Fr::from_str("5").unwrap(),
|
|
||||||
E::Fr::from_str("5").unwrap(),
|
|
||||||
E::Fr::from_str("25").unwrap(),
|
|
||||||
))
|
|
||||||
})?;
|
|
||||||
|
|
||||||
cs.enforce_zero(LinearCombination::zero() + (Coeff::Full(E::Fr::from_str("2").unwrap()), b1) - a);
|
|
||||||
cs.enforce_zero(LinearCombination::zero() + (Coeff::Full(E::Fr::from_str("4").unwrap()), a1) - b);
|
|
||||||
cs.enforce_zero(LinearCombination::zero() + (Coeff::Full(E::Fr::from_str("40").unwrap()), b1) - c);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// let perm_structure = create_permutation_structure::<Bls12, _>(&AdaptorCircuit(circuit.clone()));
|
// let perm_structure = create_permutation_structure::<Bls12, _>(&AdaptorCircuit(circuit.clone()));
|
||||||
let perm_structure = create_permutation_structure::<Bls12, _>(&AdaptorCircuit(circuit.clone()));
|
let perm_structure = create_permutation_structure::<Bls12, _>(&AdaptorCircuit(circuit.clone()));
|
||||||
let s1_srs = perm_structure.create_permutation_special_reference(&srs);
|
let s1_srs = perm_structure.create_permutation_special_reference(&srs);
|
||||||
@ -560,84 +526,49 @@ fn test_succinct_sonic_mimc() {
|
|||||||
println!("creating aggregate for {} proofs", samples);
|
println!("creating aggregate for {} proofs", samples);
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
let proofs: Vec<_> = (0..samples).map(|_| (proof.clone(), advice.clone())).collect();
|
let proofs: Vec<_> = (0..samples).map(|_| (proof.clone(), advice.clone())).collect();
|
||||||
let aggregate = create_aggregate_on_srs::<Bls12, _, Permutation3>(&AdaptorCircuit(circuit.clone()), &proofs, &srs);
|
let aggregate = create_aggregate_on_srs::<Bls12, _, Permutation3>(&AdaptorCircuit(circuit.clone()), &proofs, &srs, &s1_srs);
|
||||||
println!("done in {:?}", start.elapsed());
|
println!("done in {:?}", start.elapsed());
|
||||||
|
|
||||||
{
|
|
||||||
let rng = thread_rng();
|
|
||||||
let mut verifier = MultiVerifier::<Bls12, _, Permutation3, _>::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap();
|
|
||||||
println!("verifying 1 proof without advice");
|
|
||||||
let start = Instant::now();
|
|
||||||
{
|
|
||||||
for _ in 0..1 {
|
|
||||||
verifier.add_proof(&proof, &[], |_, _| None);
|
|
||||||
}
|
|
||||||
assert_eq!(verifier.check_all(), true); // TODO
|
|
||||||
}
|
|
||||||
println!("done in {:?}", start.elapsed());
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
let _ = crate::sonic::helped::helper::create_aggregate_on_srs::<Bls12, _, Permutation3>(&AdaptorCircuit(circuit.clone()), &proofs, &srs);
|
||||||
let rng = thread_rng();
|
// {
|
||||||
let mut verifier = MultiVerifier::<Bls12, _, Permutation3, _>::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap();
|
// let rng = thread_rng();
|
||||||
println!("verifying {} proofs without advice", samples);
|
// let mut verifier = MultiVerifier::<Bls12, _, Permutation3, _>::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap();
|
||||||
let start = Instant::now();
|
// println!("verifying 1 proof without advice");
|
||||||
{
|
// let start = Instant::now();
|
||||||
for _ in 0..samples {
|
// {
|
||||||
verifier.add_proof(&proof, &[], |_, _| None);
|
// for _ in 0..1 {
|
||||||
}
|
// verifier.add_proof(&proof, &[], |_, _| None);
|
||||||
assert_eq!(verifier.check_all(), true); // TODO
|
// }
|
||||||
}
|
// assert_eq!(verifier.check_all(), true); // TODO
|
||||||
println!("done in {:?}", start.elapsed());
|
// }
|
||||||
}
|
// println!("done in {:?}", start.elapsed());
|
||||||
|
// }
|
||||||
|
|
||||||
{
|
// {
|
||||||
let rng = thread_rng();
|
// let rng = thread_rng();
|
||||||
let mut verifier = MultiVerifier::<Bls12, _, Permutation3, _>::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap();
|
// let mut verifier = MultiVerifier::<Bls12, _, Permutation3, _>::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap();
|
||||||
println!("verifying 100 proofs with advice non-succinct");
|
// println!("verifying {} proofs without advice", samples);
|
||||||
let start = Instant::now();
|
// let start = Instant::now();
|
||||||
{
|
// {
|
||||||
for (ref proof, ref advice) in &proofs {
|
// for _ in 0..samples {
|
||||||
verifier.add_proof_with_advice(proof, &[], advice);
|
// verifier.add_proof(&proof, &[], |_, _| None);
|
||||||
}
|
// }
|
||||||
verifier.add_aggregate(&proofs, &aggregate);
|
// assert_eq!(verifier.check_all(), true); // TODO
|
||||||
assert_eq!(verifier.check_all(), true); // TODO
|
// }
|
||||||
}
|
// println!("done in {:?}", start.elapsed());
|
||||||
println!("done in {:?}", start.elapsed());
|
// }
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
use rand::{XorShiftRng, SeedableRng, Rand, Rng};
|
use rand::{XorShiftRng, SeedableRng, Rand, Rng};
|
||||||
let mut rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
let mut rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
let (perm_commitments, s_prime_challenges, perm_proof, perm_arg_proof, z_prime, num_poly, s1_naive) = perm_structure.create_permutation_arguments(aggregate.w, aggregate.z, &mut rng, &srs);
|
|
||||||
let s2_proof = perm_structure.calculate_s2_proof(aggregate.z, aggregate.w, &srs);
|
|
||||||
|
|
||||||
println!("Permutation argument done in {:?}", start.elapsed());
|
// let aggregate =
|
||||||
|
// let (perm_commitments, s_prime_challenges, perm_proof, perm_arg_proof, z_prime, num_poly, s1_naive) = perm_structure.create_permutation_arguments(aggregate.w, aggregate.z, &mut rng, &srs);
|
||||||
// let n = perm_structure.n;
|
// let s2_proof = perm_structure.calculate_s2_proof(aggregate.z, aggregate.w, &srs);
|
||||||
// let z = aggregate.z;
|
|
||||||
// let y = aggregate.w;
|
|
||||||
// let z_inv = z.inverse().unwrap();
|
|
||||||
// let z_inv_n_plus_1 = z_inv.pow([(n+1) as u64]);
|
|
||||||
// let z_n = z.pow([n as u64]);
|
|
||||||
// let y_n = y.pow([n as u64]);
|
|
||||||
|
|
||||||
// println!("S_1 naive = {}", s1_naive);
|
|
||||||
|
|
||||||
// let mut s_1 = s1_naive;
|
|
||||||
// s_1.mul_assign(&z_inv_n_plus_1);
|
|
||||||
// s_1.mul_assign(&y_n);
|
|
||||||
|
|
||||||
// println!("S_1 multiplied = {}", s_1);
|
|
||||||
|
|
||||||
// let mut s_2 = s2_proof.c_value;
|
|
||||||
// s_2.add_assign(&s2_proof.d_value);
|
|
||||||
// s_2.mul_assign(&z_n);
|
|
||||||
|
|
||||||
// s_1.sub_assign(&s_2);
|
|
||||||
// println!("S naive = {}", s_1);
|
|
||||||
|
|
||||||
|
// println!("Permutation argument done in {:?}", start.elapsed());
|
||||||
|
|
||||||
let mut verifier = SuccinctMultiVerifier::<Bls12, _, Permutation3, _>::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap();
|
let mut verifier = SuccinctMultiVerifier::<Bls12, _, Permutation3, _>::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap();
|
||||||
println!("verifying 100 proofs with succinct advice");
|
println!("verifying 100 proofs with succinct advice");
|
||||||
@ -647,16 +578,10 @@ fn test_succinct_sonic_mimc() {
|
|||||||
verifier.add_proof_with_advice(proof, &[], advice);
|
verifier.add_proof_with_advice(proof, &[], advice);
|
||||||
}
|
}
|
||||||
verifier.add_aggregate(
|
verifier.add_aggregate(
|
||||||
&proofs,
|
&proofs,
|
||||||
&aggregate,
|
&aggregate,
|
||||||
&perm_arg_proof,
|
|
||||||
&perm_proof,
|
|
||||||
&s2_proof,
|
|
||||||
num_poly,
|
|
||||||
&srs,
|
&srs,
|
||||||
z_prime,
|
&s1_srs
|
||||||
&perm_commitments,
|
|
||||||
s_prime_challenges
|
|
||||||
);
|
);
|
||||||
assert_eq!(verifier.check_all(), true); // TODO
|
assert_eq!(verifier.check_all(), true); // TODO
|
||||||
}
|
}
|
||||||
|
@ -16,31 +16,46 @@ use crate::sonic::cs::{Circuit, Variable, Coeff};
|
|||||||
use crate::sonic::srs::SRS;
|
use crate::sonic::srs::SRS;
|
||||||
use crate::sonic::sonic::CountNandQ;
|
use crate::sonic::sonic::CountNandQ;
|
||||||
use crate::sonic::sonic::M;
|
use crate::sonic::sonic::M;
|
||||||
|
use super::s2_proof::{S2Eval, S2Proof};
|
||||||
|
use super::permutation_structure::create_permutation_structure;
|
||||||
|
use super::permutation_argument::PermutationArgument;
|
||||||
|
use super::permutation_argument::SignatureOfCorrectComputation;
|
||||||
|
use super::permutation_argument::SpecializedSRS;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct SuccinctAggregate<E: Engine> {
|
pub struct SuccinctAggregate<E: Engine> {
|
||||||
pub permutations: []
|
pub signature: SignatureOfCorrectComputation<E>,
|
||||||
pub a: Vec<[Option<(Coeff<E>, usize)>; M]>,
|
pub s2_proof: S2Proof<E>,
|
||||||
pub b: Vec<[Option<(Coeff<E>, usize)>; M]>,
|
pub c: E::G1Affine,
|
||||||
pub c: Vec<[Option<(Coeff<E>, usize)>; M]>,
|
// We have to open each of the S commitments to a random point `z`
|
||||||
|
pub s_opening: E::G1Affine,
|
||||||
|
// We have to open C to each constituent `y`
|
||||||
|
pub c_openings: Vec<(E::G1Affine, E::Fr)>,
|
||||||
|
// Then we have to finally open C
|
||||||
|
pub opening: E::G1Affine,
|
||||||
|
|
||||||
|
pub z: E::Fr,
|
||||||
|
pub w: E::Fr,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_aggregate<E: Engine, C: Circuit<E>, S: SynthesisDriver>(
|
// pub fn create_aggregate<E: Engine, C: Circuit<E>, S: SynthesisDriver>(
|
||||||
circuit: &C,
|
// circuit: &C,
|
||||||
inputs: &[(Proof<E>, SxyAdvice<E>)],
|
// inputs: &[(Proof<E>, SxyAdvice<E>)],
|
||||||
params: &Parameters<E>,
|
// params: &Parameters<E>,
|
||||||
) -> SuccinctAggregate<E>
|
// ) -> SuccinctAggregate<E>
|
||||||
{
|
// {
|
||||||
let n = params.vk.n;
|
// let n = params.vk.n;
|
||||||
let q = params.vk.q;
|
// let q = params.vk.q;
|
||||||
|
|
||||||
create_aggregate_on_srs_using_information::<E, C, S>(circuit, inputs, ¶ms.srs, n, q)
|
// create_aggregate_on_srs_using_information::<E, C, S>(circuit, inputs, ¶ms.srs, n, q)
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn create_aggregate_on_srs<E: Engine, C: Circuit<E>, S: SynthesisDriver>(
|
pub fn create_aggregate_on_srs<E: Engine, C: Circuit<E>, S: SynthesisDriver>(
|
||||||
circuit: &C,
|
circuit: &C,
|
||||||
inputs: &[(Proof<E>, SxyAdvice<E>)],
|
inputs: &[(Proof<E>, SxyAdvice<E>)],
|
||||||
srs: &SRS<E>,
|
srs: &SRS<E>,
|
||||||
|
specialized_srs: &SpecializedSRS<E>
|
||||||
) -> SuccinctAggregate<E>
|
) -> SuccinctAggregate<E>
|
||||||
{
|
{
|
||||||
// TODO: precompute this?
|
// TODO: precompute this?
|
||||||
@ -52,17 +67,19 @@ pub fn create_aggregate_on_srs<E: Engine, C: Circuit<E>, S: SynthesisDriver>(
|
|||||||
(tmp.n, tmp.q)
|
(tmp.n, tmp.q)
|
||||||
};
|
};
|
||||||
|
|
||||||
create_aggregate_on_srs_using_information::<E, C, S>(circuit, inputs, srs, n, q)
|
create_aggregate_on_srs_using_information::<E, C, S>(circuit, inputs, srs, specialized_srs, n, q)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_aggregate_on_srs_using_information<E: Engine, C: Circuit<E>, S: SynthesisDriver>(
|
pub fn create_aggregate_on_srs_using_information<E: Engine, C: Circuit<E>, S: SynthesisDriver>(
|
||||||
circuit: &C,
|
circuit: &C,
|
||||||
inputs: &[(Proof<E>, SxyAdvice<E>)],
|
inputs: &[(Proof<E>, SxyAdvice<E>)],
|
||||||
srs: &SRS<E>,
|
srs: &SRS<E>,
|
||||||
|
specialized_srs: &SpecializedSRS<E>,
|
||||||
n: usize,
|
n: usize,
|
||||||
q: usize,
|
q: usize,
|
||||||
) -> SuccinctAggregate<E>
|
) -> SuccinctAggregate<E>
|
||||||
{
|
{
|
||||||
|
// take few proofs that are to be evaluated at some y_i and make an aggregate from them
|
||||||
let mut transcript = Transcript::new(&[]);
|
let mut transcript = Transcript::new(&[]);
|
||||||
let mut y_values: Vec<E::Fr> = Vec::with_capacity(inputs.len());
|
let mut y_values: Vec<E::Fr> = Vec::with_capacity(inputs.len());
|
||||||
for &(ref proof, ref sxyadvice) in inputs {
|
for &(ref proof, ref sxyadvice) in inputs {
|
||||||
@ -77,22 +94,7 @@ pub fn create_aggregate_on_srs_using_information<E: Engine, C: Circuit<E>, S: Sy
|
|||||||
|
|
||||||
let z: E::Fr = transcript.get_challenge_scalar();
|
let z: E::Fr = transcript.get_challenge_scalar();
|
||||||
|
|
||||||
let t = {
|
// Compute s(z, Y) for opening of the previous commitments at the same `z`
|
||||||
let mut tmp: PermutationSynthesizer<E, B> = PermutationSynthesizer::new(backend);
|
|
||||||
|
|
||||||
let one = tmp.alloc_input(|| Ok(E::Fr::one())).expect("should have no issues");
|
|
||||||
|
|
||||||
match (one, <PermutationSynthesizer<E, B> as ConstraintSystem<E>>::ONE) {
|
|
||||||
(Variable::A(1), Variable::A(1)) => {},
|
|
||||||
_ => panic!("one variable is incorrect")
|
|
||||||
}
|
|
||||||
|
|
||||||
circuit.synthesize(&mut tmp).expect("should synthesize");
|
|
||||||
|
|
||||||
tmp
|
|
||||||
};
|
|
||||||
|
|
||||||
// Compute s(z, Y)
|
|
||||||
let (s_poly_negative, s_poly_positive) = {
|
let (s_poly_negative, s_poly_positive) = {
|
||||||
let mut tmp = SyEval::new(z, n, q);
|
let mut tmp = SyEval::new(z, n, q);
|
||||||
S::synthesize(&mut tmp, circuit).unwrap(); // TODO
|
S::synthesize(&mut tmp, circuit).unwrap(); // TODO
|
||||||
@ -113,8 +115,12 @@ pub fn create_aggregate_on_srs_using_information<E: Engine, C: Circuit<E>, S: Sy
|
|||||||
// Open C at w
|
// Open C at w
|
||||||
let w: E::Fr = transcript.get_challenge_scalar();
|
let w: E::Fr = transcript.get_challenge_scalar();
|
||||||
|
|
||||||
|
println!("Aggregate: Z = {}, W = {}", z, w);
|
||||||
|
|
||||||
let value = compute_value::<E>(&w, &s_poly_positive, &s_poly_negative);
|
let value = compute_value::<E>(&w, &s_poly_positive, &s_poly_negative);
|
||||||
|
|
||||||
|
println!("Aggregate: S(z,w) = {}", value);
|
||||||
|
|
||||||
let opening = {
|
let opening = {
|
||||||
let mut value = value;
|
let mut value = value;
|
||||||
value.negate();
|
value.negate();
|
||||||
@ -126,22 +132,30 @@ pub fn create_aggregate_on_srs_using_information<E: Engine, C: Circuit<E>, S: Sy
|
|||||||
w,
|
w,
|
||||||
&srs
|
&srs
|
||||||
)
|
)
|
||||||
|
|
||||||
// let poly = kate_divison(
|
|
||||||
// s_poly_negative.iter().rev().chain_ext(Some(value).iter()).chain_ext(s_poly_positive.iter()),
|
|
||||||
// w,
|
|
||||||
// );
|
|
||||||
|
|
||||||
// let negative_poly = poly[0..n].iter().rev();
|
|
||||||
// let positive_poly = poly[n..].iter();
|
|
||||||
// multiexp(
|
|
||||||
// srs.g_negative_x[1..(negative_poly.len() + 1)].iter().chain_ext(
|
|
||||||
// srs.g_positive_x[0..positive_poly.len()].iter()
|
|
||||||
// ),
|
|
||||||
// negative_poly.chain_ext(positive_poly)
|
|
||||||
// ).into_affine()
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// now we need signature of correct computation. For this purpose
|
||||||
|
// verifier already knows specialized SRS, so we can just commit to
|
||||||
|
// s1 and s2 parts of such signature to get `w` and later open at this point!
|
||||||
|
|
||||||
|
// Commit!
|
||||||
|
|
||||||
|
// TODO: Precompute!
|
||||||
|
// this will internally synthesize a circuit and structure of permutations
|
||||||
|
|
||||||
|
let s2_eval = S2Eval::new(n);
|
||||||
|
let s2_proof = s2_eval.evaluate(z, w, &srs);
|
||||||
|
let permutation_structure = create_permutation_structure(circuit);
|
||||||
|
let (non_permuted_coeffs, permutations) = permutation_structure.create_permutation_vectors();
|
||||||
|
let signature = PermutationArgument::make_signature(
|
||||||
|
non_permuted_coeffs,
|
||||||
|
permutations,
|
||||||
|
w,
|
||||||
|
z,
|
||||||
|
&srs,
|
||||||
|
&specialized_srs
|
||||||
|
);
|
||||||
|
|
||||||
// Let's open up C to every y.
|
// Let's open up C to every y.
|
||||||
fn compute_value<E: Engine>(y: &E::Fr, poly_positive: &[E::Fr], poly_negative: &[E::Fr]) -> E::Fr {
|
fn compute_value<E: Engine>(y: &E::Fr, poly_positive: &[E::Fr], poly_negative: &[E::Fr]) -> E::Fr {
|
||||||
let mut value = E::Fr::zero();
|
let mut value = E::Fr::zero();
|
||||||
@ -152,28 +166,14 @@ pub fn create_aggregate_on_srs_using_information<E: Engine, C: Circuit<E>, S: Sy
|
|||||||
value.add_assign(&positive_powers_contrib);
|
value.add_assign(&positive_powers_contrib);
|
||||||
value.add_assign(&negative_powers_contrib);
|
value.add_assign(&negative_powers_contrib);
|
||||||
|
|
||||||
// let mut tmp = yinv;
|
|
||||||
// for &coeff in poly_negative {
|
|
||||||
// let mut coeff = coeff;
|
|
||||||
// coeff.mul_assign(&tmp);
|
|
||||||
// value.add_assign(&coeff);
|
|
||||||
// tmp.mul_assign(&yinv);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// let mut tmp = *y;
|
|
||||||
// for &coeff in poly_positive {
|
|
||||||
// let mut coeff = coeff;
|
|
||||||
// coeff.mul_assign(&tmp);
|
|
||||||
// value.add_assign(&coeff);
|
|
||||||
// tmp.mul_assign(&y);
|
|
||||||
// }
|
|
||||||
|
|
||||||
value
|
value
|
||||||
}
|
}
|
||||||
|
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
|
|
||||||
|
// we still need to re-open previous commitments at the same new z
|
||||||
|
|
||||||
let mut c_openings = vec![];
|
let mut c_openings = vec![];
|
||||||
for y in &y_values {
|
for y in &y_values {
|
||||||
let value = compute_value::<E>(y, &s_poly_positive, &s_poly_negative);
|
let value = compute_value::<E>(y, &s_poly_positive, &s_poly_negative);
|
||||||
@ -189,20 +189,6 @@ pub fn create_aggregate_on_srs_using_information<E: Engine, C: Circuit<E>, S: Sy
|
|||||||
*y,
|
*y,
|
||||||
&srs
|
&srs
|
||||||
)
|
)
|
||||||
|
|
||||||
// let poly = kate_divison(
|
|
||||||
// s_poly_negative.iter().rev().chain_ext(Some(value).iter()).chain_ext(s_poly_positive.iter()),
|
|
||||||
// *y,
|
|
||||||
// );
|
|
||||||
|
|
||||||
// let negative_poly = poly[0..n].iter().rev();
|
|
||||||
// let positive_poly = poly[n..].iter();
|
|
||||||
// multiexp(
|
|
||||||
// srs.g_negative_x[1..(negative_poly.len() + 1)].iter().chain_ext(
|
|
||||||
// srs.g_positive_x[0..positive_poly.len()].iter()
|
|
||||||
// ),
|
|
||||||
// negative_poly.chain_ext(positive_poly)
|
|
||||||
// ).into_affine()
|
|
||||||
};
|
};
|
||||||
|
|
||||||
c_openings.push((opening, value));
|
c_openings.push((opening, value));
|
||||||
@ -237,16 +223,6 @@ pub fn create_aggregate_on_srs_using_information<E: Engine, C: Circuit<E>, S: Sy
|
|||||||
|
|
||||||
mul_add_polynomials(& mut poly_negative[..], &s_poly_negative[..], r);
|
mul_add_polynomials(& mut poly_negative[..], &s_poly_negative[..], r);
|
||||||
mul_add_polynomials(& mut poly_positive[..], &s_poly_positive[..], r);
|
mul_add_polynomials(& mut poly_positive[..], &s_poly_positive[..], r);
|
||||||
|
|
||||||
// for (mut coeff, target) in s_poly_negative.into_iter().zip(poly_negative.iter_mut()) {
|
|
||||||
// coeff.mul_assign(&r);
|
|
||||||
// target.add_assign(&coeff);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// for (mut coeff, target) in s_poly_positive.into_iter().zip(poly_positive.iter_mut()) {
|
|
||||||
// coeff.mul_assign(&r);
|
|
||||||
// target.add_assign(&coeff);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("Re-evaluation of {} S polynomials taken {:?}", y_values.len(), start.elapsed());
|
println!("Re-evaluation of {} S polynomials taken {:?}", y_values.len(), start.elapsed());
|
||||||
@ -262,30 +238,17 @@ pub fn create_aggregate_on_srs_using_information<E: Engine, C: Circuit<E>, S: Sy
|
|||||||
z,
|
z,
|
||||||
&srs
|
&srs
|
||||||
)
|
)
|
||||||
|
|
||||||
// let poly = kate_divison(
|
|
||||||
// poly_negative.iter().rev().chain_ext(Some(value).iter()).chain_ext(poly_positive.iter()),
|
|
||||||
// z,
|
|
||||||
// );
|
|
||||||
|
|
||||||
// let negative_poly = poly[0..n].iter().rev();
|
|
||||||
// let positive_poly = poly[n..].iter();
|
|
||||||
// multiexp(
|
|
||||||
// srs.g_negative_x[1..(negative_poly.len() + 1)].iter().chain_ext(
|
|
||||||
// srs.g_positive_x[0..positive_poly.len()].iter()
|
|
||||||
// ),
|
|
||||||
// negative_poly.chain_ext(positive_poly)
|
|
||||||
// ).into_affine()
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Aggregate {
|
SuccinctAggregate {
|
||||||
// Commitment to s(z, Y)
|
signature,
|
||||||
|
s2_proof,
|
||||||
c,
|
c,
|
||||||
// We have to open each of the S commitments to a random point `z`
|
|
||||||
s_opening,
|
s_opening,
|
||||||
// We have to open C to each constituent `y`
|
|
||||||
c_openings,
|
c_openings,
|
||||||
// Then we have to finally open C
|
|
||||||
opening,
|
opening,
|
||||||
|
|
||||||
|
z: z,
|
||||||
|
w: w,
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -49,6 +49,7 @@ impl<E: Engine> GrandProductArgument<E> {
|
|||||||
z: E::Fr,
|
z: E::Fr,
|
||||||
srs: &SRS<E>,
|
srs: &SRS<E>,
|
||||||
) -> GrandProductSignature<E> {
|
) -> GrandProductSignature<E> {
|
||||||
|
println!("Making grand product argument for {} grand products", grand_products.len());
|
||||||
let mut a_commitments = vec![];
|
let mut a_commitments = vec![];
|
||||||
let mut b_commitments = vec![];
|
let mut b_commitments = vec![];
|
||||||
|
|
||||||
@ -68,7 +69,7 @@ impl<E: Engine> GrandProductArgument<E> {
|
|||||||
|
|
||||||
let mut all_polys = vec![];
|
let mut all_polys = vec![];
|
||||||
let mut wellformed_challenges = vec![];
|
let mut wellformed_challenges = vec![];
|
||||||
for c in 0..(grand_products.len()*2) {
|
for _ in 0..(grand_products.len()*2) {
|
||||||
let c = transcript.get_challenge_scalar();
|
let c = transcript.get_challenge_scalar();
|
||||||
wellformed_challenges.push(c);
|
wellformed_challenges.push(c);
|
||||||
}
|
}
|
||||||
@ -196,21 +197,21 @@ impl<E: Engine> GrandProductArgument<E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make a commitment to a polynomial in a form A*B^{x+1} = [a_1...a_{n}, 0, b_1...b_{n}]
|
// // Make a commitment to a polynomial in a form A*B^{x+1} = [a_1...a_{n}, 0, b_1...b_{n}]
|
||||||
pub fn commit_for_grand_product(a: &[E::Fr], b: &[E::Fr], srs: &SRS<E>) -> E::G1Affine {
|
// pub fn commit_for_grand_product(a: &[E::Fr], b: &[E::Fr], srs: &SRS<E>) -> E::G1Affine {
|
||||||
assert_eq!(a.len(), b.len());
|
// assert_eq!(a.len(), b.len());
|
||||||
|
|
||||||
let n = a.len();
|
// let n = a.len();
|
||||||
|
|
||||||
|
// multiexp(
|
||||||
|
// srs.g_positive_x_alpha[0..(2*n+1)].iter(),
|
||||||
|
// a.iter()
|
||||||
|
// .chain_ext(Some(E::Fr::zero()).iter())
|
||||||
|
// .chain_ext(b.iter())
|
||||||
|
// ).into_affine()
|
||||||
|
// }
|
||||||
|
|
||||||
multiexp(
|
|
||||||
srs.g_positive_x_alpha[0..(2*n+1)].iter(),
|
|
||||||
a.iter()
|
|
||||||
.chain_ext(Some(E::Fr::zero()).iter())
|
|
||||||
.chain_ext(b.iter())
|
|
||||||
).into_affine()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make a commitment to a polynomial in a form A*B^{x+1} = [a_1...a_{n}, 0, b_1...b_{n}]
|
|
||||||
pub fn commit_for_individual_products(a: &[E::Fr], b: &[E::Fr], srs: &SRS<E>) -> (E::G1Affine, E::G1Affine) {
|
pub fn commit_for_individual_products(a: &[E::Fr], b: &[E::Fr], srs: &SRS<E>) -> (E::G1Affine, E::G1Affine) {
|
||||||
assert_eq!(a.len(), b.len());
|
assert_eq!(a.len(), b.len());
|
||||||
|
|
||||||
@ -536,11 +537,10 @@ impl<E: Engine> GrandProductArgument<E> {
|
|||||||
y: E::Fr,
|
y: E::Fr,
|
||||||
z: E::Fr,
|
z: E::Fr,
|
||||||
srs: &SRS<E>
|
srs: &SRS<E>
|
||||||
) -> bool {
|
) -> bool {
|
||||||
assert_eq!(randomness.len(), a_commitments.len());
|
assert_eq!(randomness.len(), a_commitments.len());
|
||||||
assert_eq!(openings.len(), a_commitments.len());
|
assert_eq!(openings.len(), a_commitments.len());
|
||||||
assert_eq!(b_commitments.len(), a_commitments.len());
|
assert_eq!(b_commitments.len(), a_commitments.len());
|
||||||
let d = srs.d;
|
|
||||||
|
|
||||||
// e(Dj,hαx)e(D−yz,hα) = e(Aj,h)e(Bj,hxn+1)e(g−aj ,hα)
|
// e(Dj,hαx)e(D−yz,hα) = e(Aj,h)e(Bj,hxn+1)e(g−aj ,hα)
|
||||||
|
|
||||||
@ -625,8 +625,6 @@ impl<E: Engine> GrandProductArgument<E> {
|
|||||||
assert_eq!(a_zy.len(), challenges.len());
|
assert_eq!(a_zy.len(), challenges.len());
|
||||||
assert_eq!(commitments.len(), challenges.len());
|
assert_eq!(commitments.len(), challenges.len());
|
||||||
|
|
||||||
let d = srs.d;
|
|
||||||
|
|
||||||
let g = srs.g_positive_x[0];
|
let g = srs.g_positive_x[0];
|
||||||
|
|
||||||
let h_alpha_x_precomp = srs.h_positive_x_alpha[1].prepare();
|
let h_alpha_x_precomp = srs.h_positive_x_alpha[1].prepare();
|
||||||
|
@ -9,10 +9,9 @@ mod grand_product_argument;
|
|||||||
mod permutation_argument;
|
mod permutation_argument;
|
||||||
mod verifier;
|
mod verifier;
|
||||||
pub mod permutation_structure;
|
pub mod permutation_structure;
|
||||||
// mod helper;
|
mod aggregate;
|
||||||
// mod permutation;
|
|
||||||
// pub mod padding;
|
|
||||||
|
|
||||||
pub use self::wellformed_argument::{WellformednessArgument, WellformednessProof};
|
pub use self::wellformed_argument::{WellformednessArgument, WellformednessProof};
|
||||||
pub use self::permutation_argument::{PermutationArgument, PermutationProof, PermutationArgumentProof};
|
pub use self::permutation_argument::{PermutationArgument, PermutationProof, PermutationArgumentProof};
|
||||||
pub use self::verifier::SuccinctMultiVerifier;
|
pub use self::verifier::SuccinctMultiVerifier;
|
||||||
|
pub use self::aggregate::*;
|
@ -15,10 +15,10 @@ use crate::sonic::transcript::{Transcript, TranscriptProtocol};
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct SpecializedSRS<E: Engine> {
|
pub struct SpecializedSRS<E: Engine> {
|
||||||
p_1: E::G1Affine,
|
pub p_1: E::G1Affine,
|
||||||
p_2: Vec<E::G1Affine>,
|
pub p_2: Vec<E::G1Affine>,
|
||||||
p_3: E::G1Affine,
|
pub p_3: E::G1Affine,
|
||||||
p_4: Vec<E::G1Affine>,
|
pub p_4: Vec<E::G1Affine>,
|
||||||
n: usize
|
n: usize
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,8 +26,8 @@ pub struct SpecializedSRS<E: Engine> {
|
|||||||
pub struct PermutationArgument<E: Engine> {
|
pub struct PermutationArgument<E: Engine> {
|
||||||
non_permuted_coefficients: Vec<Vec<E::Fr>>,
|
non_permuted_coefficients: Vec<Vec<E::Fr>>,
|
||||||
non_permuted_at_y_coefficients: Vec<Vec<E::Fr>>,
|
non_permuted_at_y_coefficients: Vec<Vec<E::Fr>>,
|
||||||
permuted_coefficients: Vec<Vec<E::Fr>>,
|
|
||||||
permuted_at_y_coefficients: Vec<Vec<E::Fr>>,
|
permuted_at_y_coefficients: Vec<Vec<E::Fr>>,
|
||||||
|
inverse_permuted_at_y_coefficients: Vec<Vec<E::Fr>>,
|
||||||
permutations: Vec<Vec<usize>>,
|
permutations: Vec<Vec<usize>>,
|
||||||
n: usize
|
n: usize
|
||||||
}
|
}
|
||||||
@ -97,9 +97,10 @@ impl<E: Engine> PermutationArgument<E> {
|
|||||||
|
|
||||||
PermutationArgument {
|
PermutationArgument {
|
||||||
non_permuted_coefficients: coefficients,
|
non_permuted_coefficients: coefficients,
|
||||||
non_permuted_at_y_coefficients: vec![vec![]],
|
non_permuted_at_y_coefficients: vec![],
|
||||||
permuted_coefficients: vec![vec![]],
|
// permuted_coefficients: vec![],
|
||||||
permuted_at_y_coefficients: vec![vec![]],
|
permuted_at_y_coefficients: vec![],
|
||||||
|
inverse_permuted_at_y_coefficients: vec![],
|
||||||
permutations: permutations,
|
permutations: permutations,
|
||||||
n: n
|
n: n
|
||||||
}
|
}
|
||||||
@ -148,7 +149,9 @@ impl<E: Engine> PermutationArgument<E> {
|
|||||||
|
|
||||||
fe
|
fe
|
||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
let p4 = multiexp(srs.g_positive_x_alpha[0..n].iter(), values.iter()).into_affine();
|
let p4 = multiexp(srs.g_positive_x_alpha[0..n].iter(), values.iter()).into_affine();
|
||||||
|
|
||||||
p_4.push(p4);
|
p_4.push(p4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -164,71 +167,59 @@ impl<E: Engine> PermutationArgument<E> {
|
|||||||
|
|
||||||
// commit to s and s' at y. Mutates the state
|
// commit to s and s' at y. Mutates the state
|
||||||
pub fn commit(&mut self, y: E::Fr, srs: &SRS<E>) -> Vec<(E::G1Affine, E::G1Affine)> {
|
pub fn commit(&mut self, y: E::Fr, srs: &SRS<E>) -> Vec<(E::G1Affine, E::G1Affine)> {
|
||||||
|
assert!(self.inverse_permuted_at_y_coefficients.len() == 0);
|
||||||
let mut result = vec![];
|
let mut result = vec![];
|
||||||
|
|
||||||
let n = self.non_permuted_coefficients[0].len();
|
let n = self.non_permuted_coefficients[0].len();
|
||||||
|
|
||||||
let mut non_permuted_at_y_coefficients = vec![];
|
let mut non_permuted_at_y_coefficients = vec![];
|
||||||
let mut permuted_coefficients = vec![];
|
// let mut permuted_coefficients = vec![];
|
||||||
let mut permuted_at_y_coefficients = vec![];
|
let mut permuted_at_y_coefficients = vec![];
|
||||||
|
let mut inverse_permuted_at_y_coefficients = vec![];
|
||||||
|
|
||||||
// naive algorithms
|
// naive algorithms
|
||||||
// for every permutation poly
|
// for every permutation poly
|
||||||
// -- go throught all variable_idx
|
// -- go throught all variable_idx
|
||||||
// - take coeff from non-permuted coeffs[veriable_idx]
|
// - take coeff from non-permuted coeffs[permutation[variable_idx]]
|
||||||
// - mul by Y^{permutation[variable_idx]}
|
// - mul by Y^{permutation[variable_idx]}
|
||||||
// - mul by X^{variable_idx + 1}
|
// - mul by X^{variable_idx + 1}
|
||||||
|
|
||||||
// let mut s_contrib = E::Fr::zero();
|
|
||||||
// for permutation_index in 0..m {
|
|
||||||
// for (variable_index, constraint_power) in permutations[permutation_index].iter().enumerate() {
|
|
||||||
// let y_power = y.pow([*constraint_power as u64]);
|
|
||||||
// let x_power = z.pow([(variable_index+1) as u64]);
|
|
||||||
// let coeff = non_permuted_coeffs[permutation_index][variable_index];
|
|
||||||
|
|
||||||
// let mut result = coeff;
|
|
||||||
// result.mul_assign(&x_power);
|
|
||||||
// result.mul_assign(&y_power);
|
|
||||||
// s_contrib.add_assign(&result);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
// this part distributes powers of Y^{constraint} and Y^{variable} for different arguments
|
|
||||||
for (c, p) in self.non_permuted_coefficients.iter().zip(self.permutations.iter()) {
|
for (c, p) in self.non_permuted_coefficients.iter().zip(self.permutations.iter()) {
|
||||||
// this one will have terms coeff[0] * Y^1
|
|
||||||
let mut non_permuted_at_y = c.clone();
|
let mut non_permuted_at_y = c.clone();
|
||||||
|
|
||||||
// permute to later have coeff[i] at spot K for distribution of powers and for argument
|
|
||||||
let permuted = permute(&non_permuted_at_y[..], &p[..]);
|
|
||||||
|
|
||||||
// here will be distributed powers for coeff[i] * Y^K
|
|
||||||
let mut permuted_at_y = permuted.clone();
|
|
||||||
|
|
||||||
// distribute powers of Y to non-permuted coefficients as coeff[0]*Y^1, coeff[0]*Y^2, ...
|
|
||||||
mut_distribute_consequitive_powers(&mut non_permuted_at_y[..], y, y);
|
mut_distribute_consequitive_powers(&mut non_permuted_at_y[..], y, y);
|
||||||
// and commit to S'
|
|
||||||
let s_prime = multiexp(srs.g_positive_x_alpha[0..n].iter(), non_permuted_at_y.iter()).into_affine();
|
let s_prime = multiexp(srs.g_positive_x_alpha[0..n].iter(), non_permuted_at_y.iter()).into_affine();
|
||||||
|
|
||||||
// this construction has already moved coeff[i] to the corresponding constraint k, so term is coeff[i]*Y^{K} for place K
|
// if we pretend that non_permuted_at_y[sigma[i]] = coeffs[sigma[i]] * Y^sigma[i],
|
||||||
mut_distribute_consequitive_powers(&mut permuted_at_y[..], y, y);
|
// then inverse_permuted_at_y[i] = coeffs[sigma[i]] * Y^sigma[i]
|
||||||
|
let inverse_permuted_at_y = permute_inverse(&non_permuted_at_y[..], &p[..]);
|
||||||
|
|
||||||
// now there is a coefficient coeff[i]*Y^{K} for place K at place K, so we need to move it back to i
|
// let mut t = vec![E::Fr::zero(); inverse_permuted_at_y.len()];
|
||||||
let permuted_at_y = permute_inverse(&permuted_at_y[..], &p[..]);
|
// for i in 0..t.len() {
|
||||||
|
// let coeff = c[i];
|
||||||
|
// let sigma_i = p[i];
|
||||||
|
// let y_sigma_i = y.pow([sigma_i as u64]);
|
||||||
|
// t[i] = coeff;
|
||||||
|
// t[i].mul_assign(&y_sigma_i);
|
||||||
|
// }
|
||||||
|
|
||||||
// and commit to S
|
// and commit to S
|
||||||
let s = multiexp(srs.g_positive_x_alpha[0..n].iter(), permuted_at_y.iter()).into_affine();
|
let s = multiexp(srs.g_positive_x_alpha[0..n].iter(), inverse_permuted_at_y.iter()).into_affine();
|
||||||
|
|
||||||
|
// let s = multiexp(srs.g_positive_x_alpha[0..n].iter(), t.iter()).into_affine();
|
||||||
|
|
||||||
result.push((s, s_prime));
|
result.push((s, s_prime));
|
||||||
|
|
||||||
non_permuted_at_y_coefficients.push(non_permuted_at_y);
|
non_permuted_at_y_coefficients.push(non_permuted_at_y);
|
||||||
permuted_coefficients.push(permuted);
|
// permuted_coefficients.push(permuted);
|
||||||
permuted_at_y_coefficients.push(permuted_at_y);
|
// permuted_at_y_coefficients.push(t);
|
||||||
|
// permuted_at_y_coefficients.push(permuted_at_y);
|
||||||
|
inverse_permuted_at_y_coefficients.push(inverse_permuted_at_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.non_permuted_at_y_coefficients = non_permuted_at_y_coefficients;
|
self.non_permuted_at_y_coefficients = non_permuted_at_y_coefficients;
|
||||||
self.permuted_coefficients = permuted_coefficients;
|
// self.permuted_coefficients = permuted_coefficients;
|
||||||
self.permuted_at_y_coefficients = permuted_at_y_coefficients;
|
self.permuted_at_y_coefficients = permuted_at_y_coefficients;
|
||||||
|
self.inverse_permuted_at_y_coefficients = inverse_permuted_at_y_coefficients;
|
||||||
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
@ -302,6 +293,7 @@ impl<E: Engine> PermutationArgument<E> {
|
|||||||
_specialized_srs: &SpecializedSRS<E>,
|
_specialized_srs: &SpecializedSRS<E>,
|
||||||
srs: &SRS<E>
|
srs: &SRS<E>
|
||||||
) -> PermutationArgumentProof<E> {
|
) -> PermutationArgumentProof<E> {
|
||||||
|
panic!("");
|
||||||
// Sj(P4j)β(P1j)γ is equal to the product of the coefficients of Sj′(P3j)β(P1j)γ
|
// Sj(P4j)β(P1j)γ is equal to the product of the coefficients of Sj′(P3j)β(P1j)γ
|
||||||
// also open s = \sum self.permuted_coefficients(X, y) at z
|
// also open s = \sum self.permuted_coefficients(X, y) at z
|
||||||
|
|
||||||
@ -313,6 +305,7 @@ impl<E: Engine> PermutationArgument<E> {
|
|||||||
let mut s_polynomial: Option<Vec<E::Fr>> = None;
|
let mut s_polynomial: Option<Vec<E::Fr>> = None;
|
||||||
|
|
||||||
for c in self.permuted_at_y_coefficients.iter()
|
for c in self.permuted_at_y_coefficients.iter()
|
||||||
|
// for c in self.inverse_permuted_at_y_coefficients.iter()
|
||||||
{
|
{
|
||||||
if s_polynomial.is_some() {
|
if s_polynomial.is_some() {
|
||||||
if let Some(poly) = s_polynomial.as_mut() {
|
if let Some(poly) = s_polynomial.as_mut() {
|
||||||
@ -326,6 +319,8 @@ impl<E: Engine> PermutationArgument<E> {
|
|||||||
// evaluate at z
|
// evaluate at z
|
||||||
let s_zy = evaluate_at_consequitive_powers(& s_polynomial[..], z, z);
|
let s_zy = evaluate_at_consequitive_powers(& s_polynomial[..], z, z);
|
||||||
|
|
||||||
|
println!("S_zy = {}", s_zy);
|
||||||
|
|
||||||
let mut s_zy_neg = s_zy;
|
let mut s_zy_neg = s_zy;
|
||||||
s_zy_neg.negate();
|
s_zy_neg.negate();
|
||||||
|
|
||||||
@ -350,32 +345,76 @@ impl<E: Engine> PermutationArgument<E> {
|
|||||||
|
|
||||||
let mut grand_products = vec![];
|
let mut grand_products = vec![];
|
||||||
|
|
||||||
for (i, ((non_permuted, permuted), permutation)) in self.non_permuted_coefficients.into_iter()
|
for (((non_permuted, inv_permuted), permutation), permuted) in self.non_permuted_at_y_coefficients.into_iter()
|
||||||
.zip(self.permuted_coefficients.into_iter())
|
.zip(self.inverse_permuted_at_y_coefficients.into_iter())
|
||||||
.zip(self.permutations.into_iter()).enumerate()
|
.zip(self.permutations.into_iter())
|
||||||
|
.zip(self.permuted_at_y_coefficients.into_iter())
|
||||||
|
|
||||||
{
|
{
|
||||||
// \prod si+βσi+γ = \prod s'i + β*i + γ
|
// in S combination at the place i there should be term coeff[sigma(i)] * Y^sigma(i), that we can take
|
||||||
let mut s_j_combination = non_permuted;
|
// from non-permuted by inverse_permuting it
|
||||||
|
// let mut s_combination = permute_inverse(&non_permuted[..], &permutation);
|
||||||
|
let mut s_combination = inv_permuted;
|
||||||
{
|
{
|
||||||
let p_4_values: Vec<E::Fr> = permutation.into_iter().map(|el| {
|
let p_4_values: Vec<E::Fr> = permutation.clone().into_iter().map(|el| {
|
||||||
let mut repr = <<E as ScalarEngine>::Fr as PrimeField>::Repr::default();
|
let mut repr = <<E as ScalarEngine>::Fr as PrimeField>::Repr::default();
|
||||||
repr.as_mut()[0] = el as u64;
|
repr.as_mut()[0] = el as u64;
|
||||||
let fe = E::Fr::from_repr(repr).unwrap();
|
let fe = E::Fr::from_repr(repr).unwrap();
|
||||||
|
|
||||||
fe
|
fe
|
||||||
}).collect();
|
}).collect();
|
||||||
mul_add_polynomials(&mut s_j_combination[..], & p_4_values[..], beta);
|
mul_add_polynomials(&mut s_combination[..], & p_4_values[..], beta);
|
||||||
mul_add_polynomials(&mut s_j_combination[..], & p_1_values[..], gamma);
|
mul_add_polynomials(&mut s_combination[..], & p_1_values[..], gamma);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut s_prime_j_combination = permuted;
|
let mut s_combination_may_be = permuted;
|
||||||
{
|
{
|
||||||
mul_add_polynomials(&mut s_prime_j_combination[..], & p_3_values[..], beta);
|
let p_4_values: Vec<E::Fr> = permutation.clone().into_iter().map(|el| {
|
||||||
mul_add_polynomials(&mut s_prime_j_combination[..], & p_1_values[..], gamma);
|
let mut repr = <<E as ScalarEngine>::Fr as PrimeField>::Repr::default();
|
||||||
|
repr.as_mut()[0] = el as u64;
|
||||||
|
let fe = E::Fr::from_repr(repr).unwrap();
|
||||||
|
|
||||||
|
fe
|
||||||
|
}).collect();
|
||||||
|
mul_add_polynomials(&mut s_combination_may_be[..], & p_4_values[..], beta);
|
||||||
|
mul_add_polynomials(&mut s_combination_may_be[..], & p_1_values[..], gamma);
|
||||||
}
|
}
|
||||||
|
|
||||||
grand_products.push((s_j_combination, s_prime_j_combination));
|
// combination of coeff[i]*Y^i + beta * i + gamma
|
||||||
|
let mut s_prime_combination = non_permuted.clone();
|
||||||
|
{
|
||||||
|
|
||||||
|
mul_add_polynomials(&mut s_prime_combination[..], & p_3_values[..], beta);
|
||||||
|
mul_add_polynomials(&mut s_prime_combination[..], & p_1_values[..], gamma);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sanity check
|
||||||
|
let s_prime_product = s_prime_combination.iter().fold(E::Fr::one(), |mut sum, x|
|
||||||
|
{
|
||||||
|
sum.mul_assign(&x);
|
||||||
|
|
||||||
|
sum
|
||||||
|
});
|
||||||
|
|
||||||
|
let s_product = s_combination.iter().fold(E::Fr::one(), |mut sum, x|
|
||||||
|
{
|
||||||
|
sum.mul_assign(&x);
|
||||||
|
|
||||||
|
sum
|
||||||
|
});
|
||||||
|
|
||||||
|
let s_product_may_be = s_combination_may_be.iter().fold(E::Fr::one(), |mut sum, x|
|
||||||
|
{
|
||||||
|
sum.mul_assign(&x);
|
||||||
|
|
||||||
|
sum
|
||||||
|
});
|
||||||
|
|
||||||
|
println!("S = {}, S may be = {}, S' = {}", s_product, s_product_may_be, s_prime_product);
|
||||||
|
|
||||||
|
assert_eq!(s_product, s_prime_product, "product of coefficients must be the same");
|
||||||
|
|
||||||
|
grand_products.push((s_combination, s_prime_combination));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut a_commitments = vec![];
|
let mut a_commitments = vec![];
|
||||||
@ -400,7 +439,7 @@ impl<E: Engine> PermutationArgument<E> {
|
|||||||
let proof = wellformed_argument.make_argument(wellformed_challenges.clone(), &srs);
|
let proof = wellformed_argument.make_argument(wellformed_challenges.clone(), &srs);
|
||||||
let valid = WellformednessArgument::verify(n, &wellformed_challenges, &commitments, &proof, &srs);
|
let valid = WellformednessArgument::verify(n, &wellformed_challenges, &commitments, &proof, &srs);
|
||||||
|
|
||||||
assert!(valid, "wellformedness argument must be valid");
|
// assert!(valid, "wellformedness argument must be valid");
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut grand_product_argument = GrandProductArgument::new(grand_products);
|
let mut grand_product_argument = GrandProductArgument::new(grand_products);
|
||||||
@ -416,7 +455,7 @@ impl<E: Engine> PermutationArgument<E> {
|
|||||||
let randomness = (0..j).map(|_| E::Fr::rand(rng)).collect::<Vec<_>>();
|
let randomness = (0..j).map(|_| E::Fr::rand(rng)).collect::<Vec<_>>();
|
||||||
|
|
||||||
let valid = GrandProductArgument::verify_ab_commitment(n,
|
let valid = GrandProductArgument::verify_ab_commitment(n,
|
||||||
&randomness,
|
& randomness,
|
||||||
& a_commitments,
|
& a_commitments,
|
||||||
& b_commitments,
|
& b_commitments,
|
||||||
&grand_product_openings,
|
&grand_product_openings,
|
||||||
@ -605,42 +644,42 @@ impl<E: Engine> PermutationArgument<E> {
|
|||||||
|
|
||||||
let s_prime_commitments_opening = argument.open_commitments_to_s_prime(&challenges, y, z_prime, &srs);
|
let s_prime_commitments_opening = argument.open_commitments_to_s_prime(&challenges, y, z_prime, &srs);
|
||||||
|
|
||||||
let (proof, grand_product_signature) = {
|
let (proof, grand_product_signature, beta, gamma) = {
|
||||||
// TODO: create better way to get few distinct challenges from the transcript
|
// TODO: create better way to get few distinct challenges from the transcript
|
||||||
|
|
||||||
let (proof, grand_product_signature) = argument.make_argument_with_transcript(
|
let (proof, grand_product_signature, beta, gamma) = argument.make_argument_with_transcript(
|
||||||
&mut transcript,
|
&mut transcript,
|
||||||
y,
|
y,
|
||||||
z,
|
z,
|
||||||
&srs
|
&srs
|
||||||
);
|
);
|
||||||
|
|
||||||
(proof, grand_product_signature)
|
(proof, grand_product_signature, beta, gamma)
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: sanity check for now,
|
// TODO: sanity check for now,
|
||||||
// later eliminate a and b commitments
|
// later eliminate a and b commitments
|
||||||
// for (j, (((a, b), s), s_prime)) in grand_product_signature.a_commitments.iter()
|
for (j, (((a, b), s), s_prime)) in grand_product_signature.a_commitments.iter()
|
||||||
// .zip(grand_product_signature.b_commitments.iter())
|
.zip(grand_product_signature.b_commitments.iter())
|
||||||
// .zip(s_commitments.iter())
|
.zip(s_commitments.iter())
|
||||||
// .zip(s_prime_commitments.iter())
|
.zip(s_prime_commitments.iter())
|
||||||
// .enumerate()
|
.enumerate()
|
||||||
// {
|
{
|
||||||
// // Sj(P4j)β(P1j)γ
|
// Sj(P4j)β(P1j)γ
|
||||||
// let mut lhs = s.into_projective();
|
let mut lhs = s.into_projective();
|
||||||
// lhs.add_assign(&specialized_srs.p_4[j].mul(beta.into_repr()));
|
lhs.add_assign(&specialized_srs.p_4[j].mul(beta.into_repr()));
|
||||||
// lhs.add_assign(&specialized_srs.p_1.mul(gamma.into_repr()));
|
lhs.add_assign(&specialized_srs.p_1.mul(gamma.into_repr()));
|
||||||
|
|
||||||
// assert!(lhs.into_affine() == *a);
|
assert!(lhs.into_affine() == *a);
|
||||||
|
|
||||||
// // Sj′(P3j)β(P1j)γ
|
// Sj′(P3j)β(P1j)γ
|
||||||
|
|
||||||
// let mut rhs = s_prime.into_projective();
|
let mut rhs = s_prime.into_projective();
|
||||||
// rhs.add_assign(&specialized_srs.p_3.mul(beta.into_repr()));
|
rhs.add_assign(&specialized_srs.p_3.mul(beta.into_repr()));
|
||||||
// rhs.add_assign(&specialized_srs.p_1.mul(gamma.into_repr()));
|
rhs.add_assign(&specialized_srs.p_1.mul(gamma.into_repr()));
|
||||||
|
|
||||||
// assert!(rhs.into_affine() == *b);
|
assert!(rhs.into_affine() == *b);
|
||||||
// }
|
}
|
||||||
|
|
||||||
SignatureOfCorrectComputation {
|
SignatureOfCorrectComputation {
|
||||||
s_commitments,
|
s_commitments,
|
||||||
@ -658,9 +697,11 @@ impl<E: Engine> PermutationArgument<E> {
|
|||||||
y: E::Fr,
|
y: E::Fr,
|
||||||
z: E::Fr,
|
z: E::Fr,
|
||||||
srs: &SRS<E>
|
srs: &SRS<E>
|
||||||
) -> (PermutationArgumentProof<E>, GrandProductSignature<E>) {
|
) -> (PermutationArgumentProof<E>, GrandProductSignature<E>, E::Fr, E::Fr) {
|
||||||
let beta: E::Fr = transcript.get_challenge_scalar();
|
let beta: E::Fr = transcript.get_challenge_scalar();
|
||||||
|
println!("Beta in prover = {}", beta);
|
||||||
let gamma: E::Fr = transcript.get_challenge_scalar();
|
let gamma: E::Fr = transcript.get_challenge_scalar();
|
||||||
|
println!("Gamma in prover = {}", gamma);
|
||||||
|
|
||||||
// Sj(P4j)β(P1j)γ is equal to the product of the coefficients of Sj′(P3j)β(P1j)γ
|
// Sj(P4j)β(P1j)γ is equal to the product of the coefficients of Sj′(P3j)β(P1j)γ
|
||||||
// also open s = \sum self.permuted_coefficients(X, y) at z
|
// also open s = \sum self.permuted_coefficients(X, y) at z
|
||||||
@ -670,7 +711,8 @@ impl<E: Engine> PermutationArgument<E> {
|
|||||||
|
|
||||||
let mut s_polynomial: Option<Vec<E::Fr>> = None;
|
let mut s_polynomial: Option<Vec<E::Fr>> = None;
|
||||||
|
|
||||||
for c in self.permuted_at_y_coefficients.iter()
|
// for c in self.permuted_at_y_coefficients.iter()
|
||||||
|
for c in self.inverse_permuted_at_y_coefficients.iter()
|
||||||
{
|
{
|
||||||
if s_polynomial.is_some() {
|
if s_polynomial.is_some() {
|
||||||
if let Some(poly) = s_polynomial.as_mut() {
|
if let Some(poly) = s_polynomial.as_mut() {
|
||||||
@ -709,59 +751,54 @@ impl<E: Engine> PermutationArgument<E> {
|
|||||||
let mut grand_products = vec![];
|
let mut grand_products = vec![];
|
||||||
|
|
||||||
// TODO: Check the validity!
|
// TODO: Check the validity!
|
||||||
|
for ((non_permuted, inv_permuted), permutation) in self.non_permuted_at_y_coefficients.into_iter()
|
||||||
for ((non_permuted, permuted), permutation) in self.non_permuted_coefficients.into_iter()
|
.zip(self.inverse_permuted_at_y_coefficients.into_iter())
|
||||||
.zip(self.permuted_coefficients.into_iter())
|
.zip(self.permutations.into_iter())
|
||||||
.zip(self.permutations.into_iter())
|
// .zip(self.permuted_at_y_coefficients.into_iter())
|
||||||
|
|
||||||
// for ((non_permuted, permuted), permutation) in self.non_permuted_at_y_coefficients.into_iter()
|
|
||||||
// .zip(self.permuted_at_y_coefficients.into_iter())
|
|
||||||
// .zip(self.permutations.into_iter())
|
|
||||||
|
|
||||||
{
|
{
|
||||||
// \prod si+βσi+γ = \prod s'i + β*i + γ
|
// in S combination at the place i there should be term coeff[sigma(i)] * Y^sigma(i), that we can take
|
||||||
|
// from non-permuted by inverse_permuting it
|
||||||
// s combination is coeff[sigma(i)]*Y^{sigma(i)} + beta*sigma(i) + gamma
|
// let mut s_combination = permute_inverse(&non_permuted[..], &permutation);
|
||||||
let mut s_j_combination = non_permuted;
|
let mut s_combination = inv_permuted;
|
||||||
// let mut s_j_combination = permuted;
|
|
||||||
{
|
{
|
||||||
let p_4_values: Vec<E::Fr> = permutation.into_iter().map(|el| {
|
let p_4_values: Vec<E::Fr> = permutation.into_iter().map(|el| {
|
||||||
let mut repr = <<E as ScalarEngine>::Fr as PrimeField>::Repr::default();
|
let mut repr = <<E as ScalarEngine>::Fr as PrimeField>::Repr::default();
|
||||||
repr.as_mut()[0] = el as u64;
|
repr.as_mut()[0] = el as u64;
|
||||||
let fe = E::Fr::from_repr(repr).unwrap();
|
let fe = E::Fr::from_repr(repr).unwrap();
|
||||||
|
|
||||||
fe
|
fe
|
||||||
}).collect();
|
}).collect();
|
||||||
mul_add_polynomials(&mut s_j_combination[..], & p_4_values[..], beta);
|
mul_add_polynomials(&mut s_combination[..], & p_4_values[..], beta);
|
||||||
mul_add_polynomials(&mut s_j_combination[..], & p_1_values[..], gamma);
|
mul_add_polynomials(&mut s_combination[..], & p_1_values[..], gamma);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut s_prime_j_combination = permuted;
|
// combination of coeff[i]*Y^i + beta * i + gamma
|
||||||
// let mut s_prime_j_combination = non_permuted;
|
let mut s_prime_combination = non_permuted.clone();
|
||||||
// s' combination is coeff[i]*Y^{i} + beta*i + gamma
|
|
||||||
|
|
||||||
{
|
{
|
||||||
mul_add_polynomials(&mut s_prime_j_combination[..], & p_3_values[..], beta);
|
|
||||||
mul_add_polynomials(&mut s_prime_j_combination[..], & p_1_values[..], gamma);
|
mul_add_polynomials(&mut s_prime_combination[..], & p_3_values[..], beta);
|
||||||
|
mul_add_polynomials(&mut s_prime_combination[..], & p_1_values[..], gamma);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sanity check
|
// Sanity check
|
||||||
let product = s_j_combination.iter().fold(E::Fr::one(), |mut sum, x|
|
let s_prime_product = s_prime_combination.iter().fold(E::Fr::one(), |mut sum, x|
|
||||||
{
|
|
||||||
sum.mul_assign(&x);
|
|
||||||
|
|
||||||
sum
|
|
||||||
});
|
|
||||||
let product_prime = s_prime_j_combination.iter().fold(E::Fr::one(), |mut sum, x|
|
|
||||||
{
|
{
|
||||||
sum.mul_assign(&x);
|
sum.mul_assign(&x);
|
||||||
|
|
||||||
sum
|
sum
|
||||||
});
|
});
|
||||||
|
|
||||||
assert_eq!(product, product_prime);
|
let s_product = s_combination.iter().fold(E::Fr::one(), |mut sum, x|
|
||||||
|
{
|
||||||
|
sum.mul_assign(&x);
|
||||||
|
|
||||||
grand_products.push((s_j_combination, s_prime_j_combination));
|
sum
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(s_product, s_prime_product, "product of coefficients must be the same");
|
||||||
|
|
||||||
|
grand_products.push((s_combination, s_prime_combination));
|
||||||
}
|
}
|
||||||
|
|
||||||
let grand_product_signature = GrandProductArgument::create_signature(
|
let grand_product_signature = GrandProductArgument::create_signature(
|
||||||
@ -778,7 +815,7 @@ impl<E: Engine> PermutationArgument<E> {
|
|||||||
s_zy: s_zy
|
s_zy: s_zy
|
||||||
};
|
};
|
||||||
|
|
||||||
(proof, grand_product_signature)
|
(proof, grand_product_signature, beta, gamma)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -791,7 +828,8 @@ fn test_permutation_argument() {
|
|||||||
|
|
||||||
let srs_x = Fr::from_str("23923").unwrap();
|
let srs_x = Fr::from_str("23923").unwrap();
|
||||||
let srs_alpha = Fr::from_str("23728792").unwrap();
|
let srs_alpha = Fr::from_str("23728792").unwrap();
|
||||||
let srs = SRS::<Bls12>::dummy(830564, srs_x, srs_alpha);
|
// let srs = SRS::<Bls12>::dummy(830564, srs_x, srs_alpha);
|
||||||
|
let srs = SRS::<Bls12>::new(1024, srs_x, srs_alpha);
|
||||||
|
|
||||||
let n: usize = 1 << 4;
|
let n: usize = 1 << 4;
|
||||||
let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
||||||
|
@ -74,82 +74,13 @@ impl<E: Engine> PermutationStructure<E> {
|
|||||||
S2Eval::calculate_commitment_element(self.n, srs)
|
S2Eval::calculate_commitment_element(self.n, srs)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_constraints(n:usize, q: usize, coeffs: &Vec<Vec<E::Fr>>, permutations: &Vec<Vec<usize>>) {
|
|
||||||
let m = coeffs.len();
|
|
||||||
|
|
||||||
for constraint_idx in 1..=q {
|
|
||||||
println!("Constraint {}", constraint_idx);
|
|
||||||
let mut terms = vec![];
|
|
||||||
for p_idx in 0..m {
|
|
||||||
if let Some(variable_idx) = permutations[p_idx].iter().position(|&s| s == constraint_idx) {
|
|
||||||
let coeff = coeffs[p_idx][variable_idx];
|
|
||||||
terms.push((variable_idx, coeff));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (var_idx, coeff) in terms.into_iter() {
|
|
||||||
if var_idx < n + 1 {
|
|
||||||
print!("{} * A({})", coeff, n - var_idx);
|
|
||||||
} else if var_idx < 2*n + 1 {
|
|
||||||
print!("{} * B({})", coeff, var_idx - n);
|
|
||||||
} else {
|
|
||||||
print!("{} * C({})", coeff, var_idx - 2*n);
|
|
||||||
}
|
|
||||||
print!("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn print_terms_per_variable(n:usize, q: usize, coeffs: &Vec<Vec<E::Fr>>, permutations: &Vec<Vec<usize>>) {
|
|
||||||
let m = coeffs.len();
|
|
||||||
let k = coeffs[0].len();
|
|
||||||
|
|
||||||
for var_idx in 0..k {
|
|
||||||
println!("Terms for X^{}", var_idx + 1);
|
|
||||||
for p_idx in 0..m {
|
|
||||||
println!("In permutation poly {}", p_idx);
|
|
||||||
let constraint_index = permutations[p_idx][var_idx];
|
|
||||||
if constraint_index == 0 {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let coeff = coeffs[p_idx][var_idx];
|
|
||||||
if var_idx < n + 1 {
|
|
||||||
print!("{} * A({}) * Y^{}", coeff, n - var_idx, constraint_index);
|
|
||||||
} else if var_idx < 2*n + 1 {
|
|
||||||
print!("{} * B({}) * Y^{}", coeff, var_idx - n, constraint_index);
|
|
||||||
} else {
|
|
||||||
print!("{} * C({}) * Y^{}", coeff, var_idx - 2*n, constraint_index);
|
|
||||||
}
|
|
||||||
print!("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn print_terms_in_permutations(n:usize, q: usize, coeffs: &Vec<Vec<E::Fr>>, permutations: &Vec<Vec<usize>>) {
|
|
||||||
let m = coeffs.len();
|
|
||||||
|
|
||||||
for p_idx in 0..m {
|
|
||||||
println!("Permutation polynomial {}", p_idx);
|
|
||||||
for (var_idx, constraint_idx) in permutations[p_idx].iter().enumerate() {
|
|
||||||
let coeff = coeffs[p_idx][var_idx];
|
|
||||||
if var_idx < n + 1 {
|
|
||||||
print!("{} * A({})", coeff, n - var_idx);
|
|
||||||
} else if var_idx < 2*n + 1 {
|
|
||||||
print!("{} * B({})", coeff, var_idx - n);
|
|
||||||
} else {
|
|
||||||
print!("{} * C({})", coeff, var_idx - 2*n);
|
|
||||||
}
|
|
||||||
print!("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn calculate_s2_proof(&self, x: E::Fr, y: E::Fr, srs: &SRS<E>) -> S2Proof<E> {
|
pub fn calculate_s2_proof(&self, x: E::Fr, y: E::Fr, srs: &SRS<E>) -> S2Proof<E> {
|
||||||
let s2_eval = S2Eval::new(self.n);
|
let s2_eval = S2Eval::new(self.n);
|
||||||
|
|
||||||
s2_eval.evaluate(x, y, &srs)
|
s2_eval.evaluate(x, y, &srs)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_permutation_vectors(&self) -> (Vec<Vec<E::Fr>>, Vec<Vec<usize>>) {
|
pub fn create_inverse_permutation_vectors(&self) -> (Vec<Vec<E::Fr>>, Vec<Vec<usize>>) {
|
||||||
// we have to form non-permuted coefficients, as well as permutation structures;
|
// we have to form non-permuted coefficients, as well as permutation structures;
|
||||||
let n = self.n;
|
let n = self.n;
|
||||||
let mut non_permuted_coeffs = vec![vec![E::Fr::zero(); 3*n+1]; M];
|
let mut non_permuted_coeffs = vec![vec![E::Fr::zero(); 3*n+1]; M];
|
||||||
@ -168,7 +99,6 @@ impl<E: Engine> PermutationStructure<E> {
|
|||||||
if let Some((coeff, place)) = info[i].as_ref() {
|
if let Some((coeff, place)) = info[i].as_ref() {
|
||||||
// place it
|
// place it
|
||||||
assert!(*place != 0);
|
assert!(*place != 0);
|
||||||
let x_power = offset - gate_index + 1;
|
|
||||||
let array_position = offset - gate_index; // special for A
|
let array_position = offset - gate_index; // special for A
|
||||||
let place_coeff_into = &mut non_permuted_coeffs[i];
|
let place_coeff_into = &mut non_permuted_coeffs[i];
|
||||||
let place_permutation_into = &mut permutations[i];
|
let place_permutation_into = &mut permutations[i];
|
||||||
@ -201,7 +131,6 @@ impl<E: Engine> PermutationStructure<E> {
|
|||||||
if let Some((coeff, place)) = info[i].as_ref() {
|
if let Some((coeff, place)) = info[i].as_ref() {
|
||||||
// place it
|
// place it
|
||||||
assert!(*place != 0);
|
assert!(*place != 0);
|
||||||
let x_power = offset + gate_index + 1; // 1 indexed
|
|
||||||
let array_position = offset + gate_index;
|
let array_position = offset + gate_index;
|
||||||
let place_coeff_into = &mut non_permuted_coeffs[i];
|
let place_coeff_into = &mut non_permuted_coeffs[i];
|
||||||
let place_permutation_into = &mut permutations[i];
|
let place_permutation_into = &mut permutations[i];
|
||||||
@ -235,7 +164,6 @@ impl<E: Engine> PermutationStructure<E> {
|
|||||||
if let Some((coeff, place)) = info[i].as_ref() {
|
if let Some((coeff, place)) = info[i].as_ref() {
|
||||||
// place it
|
// place it
|
||||||
assert!(*place != 0);
|
assert!(*place != 0);
|
||||||
let x_power = offset + gate_index + 1; // 1 indexed
|
|
||||||
let array_position = offset + gate_index;
|
let array_position = offset + gate_index;
|
||||||
let place_coeff_into = &mut non_permuted_coeffs[i];
|
let place_coeff_into = &mut non_permuted_coeffs[i];
|
||||||
let place_permutation_into = &mut permutations[i];
|
let place_permutation_into = &mut permutations[i];
|
||||||
@ -262,6 +190,8 @@ impl<E: Engine> PermutationStructure<E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Self::print_constraints(n, self.q, &non_permuted_coeffs, &permutations);
|
||||||
|
|
||||||
// need to fill arrays with non-zero indexes just to have full permutation, even while it's just zero coefficient
|
// need to fill arrays with non-zero indexes just to have full permutation, even while it's just zero coefficient
|
||||||
|
|
||||||
// TODO: fix
|
// TODO: fix
|
||||||
@ -283,15 +213,6 @@ impl<E: Engine> PermutationStructure<E> {
|
|||||||
|
|
||||||
assert!(m != 0);
|
assert!(m != 0);
|
||||||
|
|
||||||
// Self::print_constraints(n, self.q, &non_permuted_coeffs, &permutations);
|
|
||||||
// Self::print_terms_per_variable(n, self.q, &non_permuted_coeffs, &permutations);
|
|
||||||
// Self::print_terms_in_permutations(n, self.q, &non_permuted_coeffs, &permutations);
|
|
||||||
|
|
||||||
// for i in 0..m {
|
|
||||||
// println!("Coeffs = {:?}", non_permuted_coeffs[i]);
|
|
||||||
// println!("Permutation = {:?}", permutations[i]);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// find something faster, although it's still linear
|
// find something faster, although it's still linear
|
||||||
|
|
||||||
for i in 0..m {
|
for i in 0..m {
|
||||||
@ -322,6 +243,198 @@ impl<E: Engine> PermutationStructure<E> {
|
|||||||
(non_permuted_coeffs, permutations)
|
(non_permuted_coeffs, permutations)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn create_permutation_vectors(&self) -> (Vec<Vec<E::Fr>>, Vec<Vec<usize>>) {
|
||||||
|
// we have to form non-permuted coefficients, as well as permutation structures;
|
||||||
|
let n = self.n;
|
||||||
|
let mut non_permuted_coeffs = vec![vec![E::Fr::zero(); 3*n+1]; M];
|
||||||
|
let mut permutations = vec![vec![0usize; 3*n+1]; M];
|
||||||
|
|
||||||
|
let one = E::Fr::one();
|
||||||
|
let mut minus_one = E::Fr::one();
|
||||||
|
minus_one.negate();
|
||||||
|
|
||||||
|
let mut not_empty = [false; M];
|
||||||
|
// go other the permutations
|
||||||
|
for (gate_index, info) in self.a.iter().enumerate() {
|
||||||
|
let offset = n-1;
|
||||||
|
for i in 0..M {
|
||||||
|
// coefficients of A are placed at the offset = 0 from the beginning of the vector
|
||||||
|
if let Some((coeff, place)) = info[i].as_ref() {
|
||||||
|
// place it
|
||||||
|
assert!(*place != 0);
|
||||||
|
let array_position = offset - gate_index; // special for A
|
||||||
|
let coeff_position = *place - 1;
|
||||||
|
let place_coeff_into = &mut non_permuted_coeffs[i];
|
||||||
|
let place_permutation_into = &mut permutations[i];
|
||||||
|
match coeff {
|
||||||
|
Coeff::Zero => {
|
||||||
|
},
|
||||||
|
Coeff::One => {
|
||||||
|
not_empty[i] = true;
|
||||||
|
place_coeff_into[coeff_position] = one;
|
||||||
|
place_permutation_into[array_position] = *place;
|
||||||
|
},
|
||||||
|
Coeff::NegativeOne => {
|
||||||
|
not_empty[i] = true;
|
||||||
|
place_coeff_into[coeff_position] = minus_one;
|
||||||
|
place_permutation_into[array_position] = *place;
|
||||||
|
},
|
||||||
|
Coeff::Full(value) => {
|
||||||
|
not_empty[i] = true;
|
||||||
|
place_coeff_into[coeff_position] = *value;
|
||||||
|
place_permutation_into[array_position] = *place;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (gate_index, info) in self.b.iter().enumerate() {
|
||||||
|
let offset = n + 1;
|
||||||
|
for i in 0..M {
|
||||||
|
if let Some((coeff, place)) = info[i].as_ref() {
|
||||||
|
// place it
|
||||||
|
assert!(*place != 0);
|
||||||
|
let array_position = offset + gate_index;
|
||||||
|
let coeff_position = *place - 1;
|
||||||
|
let place_coeff_into = &mut non_permuted_coeffs[i];
|
||||||
|
let place_permutation_into = &mut permutations[i];
|
||||||
|
match coeff {
|
||||||
|
Coeff::Zero => {
|
||||||
|
},
|
||||||
|
Coeff::One => {
|
||||||
|
not_empty[i] = true;
|
||||||
|
place_coeff_into[coeff_position] = one;
|
||||||
|
place_permutation_into[array_position] = *place;
|
||||||
|
},
|
||||||
|
Coeff::NegativeOne => {
|
||||||
|
not_empty[i] = true;
|
||||||
|
place_coeff_into[coeff_position] = minus_one;
|
||||||
|
place_permutation_into[array_position] = *place;
|
||||||
|
},
|
||||||
|
Coeff::Full(value) => {
|
||||||
|
not_empty[i] = true;
|
||||||
|
place_coeff_into[coeff_position] = *value;
|
||||||
|
place_permutation_into[array_position] = *place;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (gate_index, info) in self.c.iter().enumerate() {
|
||||||
|
let offset = 2*n + 1;
|
||||||
|
for i in 0..M {
|
||||||
|
// coefficients of A are placed at the offset = 0 from the beginning of the vector
|
||||||
|
if let Some((coeff, place)) = info[i].as_ref() {
|
||||||
|
// place it
|
||||||
|
assert!(*place != 0);
|
||||||
|
let array_position = offset + gate_index;
|
||||||
|
let coeff_position = *place - 1;
|
||||||
|
let place_coeff_into = &mut non_permuted_coeffs[i];
|
||||||
|
let place_permutation_into = &mut permutations[i];
|
||||||
|
match coeff {
|
||||||
|
Coeff::Zero => {
|
||||||
|
},
|
||||||
|
Coeff::One => {
|
||||||
|
not_empty[i] = true;
|
||||||
|
place_coeff_into[coeff_position] = one;
|
||||||
|
place_permutation_into[array_position] = *place;
|
||||||
|
},
|
||||||
|
Coeff::NegativeOne => {
|
||||||
|
not_empty[i] = true;
|
||||||
|
place_coeff_into[coeff_position] = minus_one;
|
||||||
|
place_permutation_into[array_position] = *place;
|
||||||
|
},
|
||||||
|
Coeff::Full(value) => {
|
||||||
|
not_empty[i] = true;
|
||||||
|
place_coeff_into[coeff_position] = *value;
|
||||||
|
place_permutation_into[array_position] = *place;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Self::print_constraints(n, self.q, &non_permuted_coeffs, &permutations);
|
||||||
|
|
||||||
|
// need to fill arrays with non-zero indexes just to have full permutation, even while it's just zero coefficient
|
||||||
|
|
||||||
|
// TODO: fix
|
||||||
|
|
||||||
|
let mut m = M;
|
||||||
|
// for i in (0..M).into_iter().rev() {
|
||||||
|
// // these are no constant terms
|
||||||
|
// assert!(non_permuted_coeffs[i][n].is_zero());
|
||||||
|
// assert!(permutations[i][n] == 0);
|
||||||
|
// }
|
||||||
|
|
||||||
|
for i in (0..M).into_iter().rev() {
|
||||||
|
if !not_empty[i] {
|
||||||
|
non_permuted_coeffs.pop();
|
||||||
|
permutations.pop();
|
||||||
|
m -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert!(m != 0);
|
||||||
|
|
||||||
|
// find something faster, although it's still linear
|
||||||
|
|
||||||
|
for i in 0..m {
|
||||||
|
let mut fillers: Vec<usize> = (1..=(3*n+1)).map(|el| el).collect();
|
||||||
|
for (p, c) in permutations[i].iter_mut().zip(non_permuted_coeffs[i].iter()) {
|
||||||
|
if *p == 0 {
|
||||||
|
continue;
|
||||||
|
// assert!(c.is_zero());
|
||||||
|
} else {
|
||||||
|
fillers[*p - 1] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut fill_from = 0;
|
||||||
|
for p in permutations[i].iter_mut() {
|
||||||
|
if *p == 0 {
|
||||||
|
loop {
|
||||||
|
if fillers[fill_from] != 0 {
|
||||||
|
*p = fillers[fill_from];
|
||||||
|
fill_from += 1;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
fill_from += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(non_permuted_coeffs, permutations)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn print_constraints(n:usize, q: usize, coeffs: &Vec<Vec<E::Fr>>, permutations: &Vec<Vec<usize>>) {
|
||||||
|
let m = coeffs.len();
|
||||||
|
|
||||||
|
for constraint_idx in 1..=q {
|
||||||
|
println!("Constraint {} (term for Y^{})", constraint_idx, constraint_idx);
|
||||||
|
let mut terms = vec![];
|
||||||
|
for p_idx in 0..m {
|
||||||
|
if let Some(variable_idx) = permutations[p_idx].iter().position(|&s| s == constraint_idx) {
|
||||||
|
let coeff = coeffs[p_idx][variable_idx];
|
||||||
|
terms.push((variable_idx, coeff));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (var_idx, coeff) in terms.into_iter() {
|
||||||
|
if var_idx < n + 1 {
|
||||||
|
print!("{} * A({})", coeff, n - var_idx);
|
||||||
|
} else if var_idx < 2*n + 1 {
|
||||||
|
print!("{} * B({})", coeff, var_idx - n);
|
||||||
|
} else {
|
||||||
|
print!("{} * C({})", coeff, var_idx - 2*n);
|
||||||
|
}
|
||||||
|
print!("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn create_permutation_special_reference(&self, srs: &SRS<E>) -> SpecializedSRS<E>
|
pub fn create_permutation_special_reference(&self, srs: &SRS<E>) -> SpecializedSRS<E>
|
||||||
{
|
{
|
||||||
let (non_permuted_coeffs, permutations) = self.create_permutation_vectors();
|
let (non_permuted_coeffs, permutations) = self.create_permutation_vectors();
|
||||||
@ -335,9 +448,33 @@ impl<E: Engine> PermutationStructure<E> {
|
|||||||
specialized_srs
|
specialized_srs
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn make_signature(&self, y: E::Fr, z: E::Fr, srs: &SRS<E>) {
|
pub fn make_signature(&self, y: E::Fr, z: E::Fr, srs: &SRS<E>) -> SignatureOfCorrectComputation<E> {
|
||||||
let (non_permuted_coeffs, permutations) = self.create_permutation_vectors();
|
let (non_permuted_coeffs, permutations) = self.create_permutation_vectors();
|
||||||
|
|
||||||
|
let mut s_contrib = E::Fr::zero();
|
||||||
|
for permutation_index in 0..permutations.len() {
|
||||||
|
for (variable_index, sigma_i) in permutations[permutation_index].iter().enumerate() {
|
||||||
|
let y_power = y.pow([*sigma_i as u64]);
|
||||||
|
let x_power = z.pow([(variable_index+1) as u64]);
|
||||||
|
let coeff = non_permuted_coeffs[permutation_index][*sigma_i - 1];
|
||||||
|
|
||||||
|
let mut result = coeff;
|
||||||
|
result.mul_assign(&x_power);
|
||||||
|
result.mul_assign(&y_power);
|
||||||
|
s_contrib.add_assign(&result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let z_n_plus_1_inv = z.pow([(self.n + 1) as u64]).inverse().unwrap();
|
||||||
|
let y_n = y.pow([self.n as u64]);
|
||||||
|
|
||||||
|
println!("Naive S contribution = {}", s_contrib);
|
||||||
|
|
||||||
|
s_contrib.mul_assign(&z_n_plus_1_inv);
|
||||||
|
s_contrib.mul_assign(&y_n);
|
||||||
|
|
||||||
|
println!("Naive S contribution scaled = {}", s_contrib);
|
||||||
|
|
||||||
let specialized_srs = PermutationArgument::make_specialized_srs(
|
let specialized_srs = PermutationArgument::make_specialized_srs(
|
||||||
&non_permuted_coeffs,
|
&non_permuted_coeffs,
|
||||||
&permutations,
|
&permutations,
|
||||||
@ -352,6 +489,8 @@ impl<E: Engine> PermutationStructure<E> {
|
|||||||
&srs,
|
&srs,
|
||||||
&specialized_srs
|
&specialized_srs
|
||||||
);
|
);
|
||||||
|
|
||||||
|
signature
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_permutation_arguments<R: Rng>(&self, y: E::Fr, z: E::Fr, rng: &mut R, srs: &SRS<E>)
|
pub fn create_permutation_arguments<R: Rng>(&self, y: E::Fr, z: E::Fr, rng: &mut R, srs: &SRS<E>)
|
||||||
@ -376,10 +515,10 @@ impl<E: Engine> PermutationStructure<E> {
|
|||||||
|
|
||||||
let mut s_contrib = E::Fr::zero();
|
let mut s_contrib = E::Fr::zero();
|
||||||
for permutation_index in 0..m {
|
for permutation_index in 0..m {
|
||||||
for (variable_index, constraint_power) in permutations[permutation_index].iter().enumerate() {
|
for (variable_index, sigma_i) in permutations[permutation_index].iter().enumerate() {
|
||||||
let y_power = y.pow([*constraint_power as u64]);
|
let y_power = y.pow([*sigma_i as u64]);
|
||||||
let x_power = z.pow([(variable_index+1) as u64]);
|
let x_power = z.pow([(variable_index+1) as u64]);
|
||||||
let coeff = non_permuted_coeffs[permutation_index][variable_index];
|
let coeff = non_permuted_coeffs[permutation_index][*sigma_i - 1];
|
||||||
|
|
||||||
let mut result = coeff;
|
let mut result = coeff;
|
||||||
result.mul_assign(&x_power);
|
result.mul_assign(&x_power);
|
||||||
@ -388,6 +527,8 @@ impl<E: Engine> PermutationStructure<E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
println!("Naive S contribution = {}", s_contrib);
|
||||||
|
|
||||||
let mut argument = PermutationArgument::new(non_permuted_coeffs, permutations);
|
let mut argument = PermutationArgument::new(non_permuted_coeffs, permutations);
|
||||||
let challenges = (0..m).map(|_| E::Fr::rand(rng)).collect::<Vec<_>>();
|
let challenges = (0..m).map(|_| E::Fr::rand(rng)).collect::<Vec<_>>();
|
||||||
|
|
||||||
@ -491,7 +632,8 @@ fn test_simple_succinct_sonic() {
|
|||||||
let srs_alpha = Fr::from_str("23728792").unwrap();
|
let srs_alpha = Fr::from_str("23728792").unwrap();
|
||||||
println!("making srs");
|
println!("making srs");
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
let srs = SRS::<Bls12>::dummy(830564, srs_x, srs_alpha);
|
// let srs = SRS::<Bls12>::dummy(830564, srs_x, srs_alpha);
|
||||||
|
let srs = SRS::<Bls12>::new(100, srs_x, srs_alpha);
|
||||||
println!("done in {:?}", start.elapsed());
|
println!("done in {:?}", start.elapsed());
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -506,18 +648,52 @@ fn test_simple_succinct_sonic() {
|
|||||||
use crate::sonic::sonic::Permutation3;
|
use crate::sonic::sonic::Permutation3;
|
||||||
use crate::sonic::unhelped::permutation_structure::*;
|
use crate::sonic::unhelped::permutation_structure::*;
|
||||||
|
|
||||||
let x: Fr = rng.gen();
|
// let z: Fr = rng.gen();
|
||||||
let y: Fr = rng.gen();
|
// let y: Fr = rng.gen();
|
||||||
|
|
||||||
let x = Fr::one();
|
let z: Fr = Fr::from_str("2").unwrap();
|
||||||
let mut y = Fr::one();
|
let y: Fr = Fr::one();
|
||||||
y.double();
|
|
||||||
|
|
||||||
let perm_structure = create_permutation_structure::<Bls12, _>(&MyCircuit);
|
let perm_structure = create_permutation_structure::<Bls12, _>(&MyCircuit);
|
||||||
perm_structure.create_permutation_arguments(x, y, rng, &srs);
|
let (non_permuted_coeffs, permutations) = perm_structure.create_permutation_vectors();
|
||||||
perm_structure.make_signature(x, y, &srs);
|
println!("Non-permuted = {:?}", non_permuted_coeffs[0]);
|
||||||
|
println!("Permutation = {:?}", permutations[0]);
|
||||||
|
println!("N = {}, Q = {}", perm_structure.n, perm_structure.q);
|
||||||
|
let n = perm_structure.n;
|
||||||
|
let szy = {
|
||||||
|
let mut tmp = SxEval::<Bls12>::new(y, n);
|
||||||
|
Permutation3::synthesize(&mut tmp, &MyCircuit).unwrap(); // TODO
|
||||||
|
tmp.finalize(z)
|
||||||
|
};
|
||||||
|
|
||||||
|
let naive_s1 = {
|
||||||
|
let mut res = Fr::zero();
|
||||||
|
for j in 0..permutations.len() {
|
||||||
|
for i in 0..non_permuted_coeffs[j].len() {
|
||||||
|
let sigma_i = permutations[j][i];
|
||||||
|
let coeff_i = non_permuted_coeffs[j][i];
|
||||||
|
let coeff_sigma_i = non_permuted_coeffs[j][sigma_i - 1];
|
||||||
|
|
||||||
|
let y_power = y.pow([sigma_i as u64]);
|
||||||
|
let x_power = z.pow([(i+1) as u64]);
|
||||||
|
// let mut result = coeff_sigma_i;
|
||||||
|
let mut result = coeff_i;
|
||||||
|
result.mul_assign(&y_power);
|
||||||
|
result.mul_assign(&x_power);
|
||||||
|
|
||||||
|
res.add_assign(&result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
};
|
||||||
|
|
||||||
|
println!("Naive s1 = {}", naive_s1);
|
||||||
|
|
||||||
|
// perm_structure.create_permutation_arguments(y, z, rng, &srs);
|
||||||
|
let signature = perm_structure.make_signature(y, z, &srs);
|
||||||
let s2 = S2Eval::new(perm_structure.n);
|
let s2 = S2Eval::new(perm_structure.n);
|
||||||
let s2 = s2.evaluate(x, y, &srs);
|
let s2 = s2.evaluate(z, y, &srs);
|
||||||
let mut s2_value = s2.c_value;
|
let mut s2_value = s2.c_value;
|
||||||
s2_value.add_assign(&s2.d_value);
|
s2_value.add_assign(&s2.d_value);
|
||||||
|
|
||||||
@ -525,7 +701,7 @@ fn test_simple_succinct_sonic() {
|
|||||||
let y_inv = y.inverse().unwrap();
|
let y_inv = y.inverse().unwrap();
|
||||||
let mut p1 = y;
|
let mut p1 = y;
|
||||||
p1.add_assign(&y_inv);
|
p1.add_assign(&y_inv);
|
||||||
p1.mul_assign(&x);
|
p1.mul_assign(&z);
|
||||||
expected_s2_value.add_assign(&p1);
|
expected_s2_value.add_assign(&p1);
|
||||||
|
|
||||||
let mut t0 = y;
|
let mut t0 = y;
|
||||||
@ -536,13 +712,33 @@ fn test_simple_succinct_sonic() {
|
|||||||
|
|
||||||
let mut p2 = t0;
|
let mut p2 = t0;
|
||||||
p2.add_assign(&t1);
|
p2.add_assign(&t1);
|
||||||
p2.mul_assign(&x);
|
p2.mul_assign(&z);
|
||||||
p2.mul_assign(&x);
|
p2.mul_assign(&z);
|
||||||
|
|
||||||
expected_s2_value.add_assign(&p2);
|
expected_s2_value.add_assign(&p2);
|
||||||
|
|
||||||
|
let z_n = z.pow([n as u64]);
|
||||||
|
let z_n_plus_1_inv = z.pow([(n + 1) as u64]).inverse().unwrap();
|
||||||
|
let y_n = y.pow([n as u64]);
|
||||||
|
|
||||||
assert!(expected_s2_value == s2_value);
|
assert!(expected_s2_value == s2_value);
|
||||||
|
|
||||||
println!("N = {}, Q = {}", perm_structure.n, perm_structure.q);
|
s2_value.mul_assign(&z_n);
|
||||||
|
|
||||||
|
let mut s1 = signature.perm_argument_proof.s_zy;
|
||||||
|
println!("S1 = {}", s1);
|
||||||
|
s1.mul_assign(&z_n_plus_1_inv);
|
||||||
|
s1.mul_assign(&y_n);
|
||||||
|
|
||||||
|
s1.sub_assign(&s2_value);
|
||||||
|
|
||||||
|
let mut naive_s1 = naive_s1;
|
||||||
|
naive_s1.mul_assign(&z_n_plus_1_inv);
|
||||||
|
naive_s1.mul_assign(&y_n);
|
||||||
|
naive_s1.sub_assign(&s2_value);
|
||||||
|
|
||||||
|
println!("S1(?) = {}", naive_s1);
|
||||||
|
|
||||||
|
assert_eq!(s1, szy);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -19,9 +19,14 @@ use crate::sonic::srs::SRS;
|
|||||||
use crate::sonic::sonic::Preprocess;
|
use crate::sonic::sonic::Preprocess;
|
||||||
|
|
||||||
use super::s2_proof::{S2Proof, S2Eval};
|
use super::s2_proof::{S2Proof, S2Eval};
|
||||||
|
use super::aggregate::SuccinctAggregate;
|
||||||
use super::permutation_structure::create_permutation_structure;
|
use super::permutation_structure::create_permutation_structure;
|
||||||
use super::permutation_argument::SpecializedSRS;
|
use super::permutation_argument::{
|
||||||
use super::permutation_argument::{PermutationArgumentProof, PermutationProof, PermutationArgument};
|
PermutationArgumentProof,
|
||||||
|
PermutationProof,
|
||||||
|
PermutationArgument,
|
||||||
|
SpecializedSRS
|
||||||
|
};
|
||||||
|
|
||||||
pub struct SuccinctMultiVerifier<E: Engine, C: Circuit<E>, S: SynthesisDriver, R: Rng> {
|
pub struct SuccinctMultiVerifier<E: Engine, C: Circuit<E>, S: SynthesisDriver, R: Rng> {
|
||||||
circuit: C,
|
circuit: C,
|
||||||
@ -51,7 +56,6 @@ impl<E: Engine, C: Circuit<E>, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier
|
|||||||
let s2_special_reference = permutation_structure.calculate_s2_commitment_value(&srs);
|
let s2_special_reference = permutation_structure.calculate_s2_commitment_value(&srs);
|
||||||
let s1_special_reference = permutation_structure.create_permutation_special_reference(&srs);
|
let s1_special_reference = permutation_structure.create_permutation_special_reference(&srs);
|
||||||
|
|
||||||
|
|
||||||
Ok(SuccinctMultiVerifier {
|
Ok(SuccinctMultiVerifier {
|
||||||
circuit,
|
circuit,
|
||||||
s1_special_reference,
|
s1_special_reference,
|
||||||
@ -65,91 +69,12 @@ impl<E: Engine, C: Circuit<E>, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn add_non_succinct_aggregate(
|
|
||||||
// &mut self,
|
|
||||||
// proofs: &[(Proof<E>, SxyAdvice<E>)],
|
|
||||||
// aggregate: &Aggregate<E>,
|
|
||||||
// )
|
|
||||||
// {
|
|
||||||
// let mut transcript = Transcript::new(&[]);
|
|
||||||
// let mut y_values: Vec<E::Fr> = Vec::with_capacity(proofs.len());
|
|
||||||
// for &(ref proof, ref sxyadvice) in proofs {
|
|
||||||
// {
|
|
||||||
// let mut transcript = Transcript::new(&[]);
|
|
||||||
// transcript.commit_point(&proof.r);
|
|
||||||
// y_values.push(transcript.get_challenge_scalar());
|
|
||||||
// }
|
|
||||||
|
|
||||||
// transcript.commit_point(&sxyadvice.s);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// let z: E::Fr = transcript.get_challenge_scalar();
|
|
||||||
|
|
||||||
// let z = E::Fr::one();
|
|
||||||
|
|
||||||
// transcript.commit_point(&aggregate.c);
|
|
||||||
|
|
||||||
// let w: E::Fr = transcript.get_challenge_scalar();
|
|
||||||
|
|
||||||
// let szw = {
|
|
||||||
// let mut tmp = SxEval::new(w, self.n);
|
|
||||||
// S::synthesize(&mut tmp, &self.circuit).unwrap(); // TODO
|
|
||||||
|
|
||||||
// tmp.finalize(z)
|
|
||||||
// };
|
|
||||||
|
|
||||||
// println!("Nonsuccinct S(z,w) = {}", szw);
|
|
||||||
|
|
||||||
// // {
|
|
||||||
// // let random: E::Fr = self.randomness_source.gen();
|
|
||||||
|
|
||||||
// // self.batch.add_opening(aggregate.opening, random, w);
|
|
||||||
// // self.batch.add_commitment(aggregate.c, random);
|
|
||||||
// // self.batch.add_opening_value(szw, random);
|
|
||||||
// // }
|
|
||||||
|
|
||||||
// for ((opening, value), &y) in aggregate.c_openings.iter().zip(y_values.iter()) {
|
|
||||||
// let random: E::Fr = self.randomness_source.gen();
|
|
||||||
|
|
||||||
// self.batch.add_opening(*opening, random, y);
|
|
||||||
// self.batch.add_commitment(aggregate.c, random);
|
|
||||||
// self.batch.add_opening_value(*value, random);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// let random: E::Fr = self.randomness_source.gen();
|
|
||||||
|
|
||||||
// let mut expected_value = E::Fr::zero();
|
|
||||||
// for ((_, advice), c_opening) in proofs.iter().zip(aggregate.c_openings.iter()) {
|
|
||||||
// let mut r: E::Fr = transcript.get_challenge_scalar();
|
|
||||||
|
|
||||||
// // expected value of the later opening
|
|
||||||
// {
|
|
||||||
// let mut tmp = c_opening.1;
|
|
||||||
// tmp.mul_assign(&r);
|
|
||||||
// expected_value.add_assign(&tmp);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// r.mul_assign(&random);
|
|
||||||
|
|
||||||
// self.batch.add_commitment(advice.s, r);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// self.batch.add_opening_value(expected_value, random);
|
|
||||||
// self.batch.add_opening(aggregate.s_opening, random, z);
|
|
||||||
// }
|
|
||||||
|
|
||||||
pub fn add_aggregate(
|
pub fn add_aggregate(
|
||||||
&mut self,
|
&mut self,
|
||||||
proofs: &[(Proof<E>, SxyAdvice<E>)],
|
proofs: &[(Proof<E>, SxyAdvice<E>)],
|
||||||
aggregate: &Aggregate<E>,
|
aggregate: &SuccinctAggregate<E>,
|
||||||
permutation_argument_proof: &PermutationArgumentProof<E>,
|
|
||||||
permutation_proof: &PermutationProof<E>,
|
|
||||||
s2_proof: &S2Proof<E>,
|
|
||||||
num_permutation_polynomials: usize,
|
|
||||||
srs: &SRS<E>,
|
srs: &SRS<E>,
|
||||||
z_prime: E::Fr, // TODO, temporary before incorporation to the transcript
|
specialized_srs: &SpecializedSRS<E>
|
||||||
permutation_argument_commitments: & Vec<(E::G1Affine, E::G1Affine)>,
|
|
||||||
s_prime_challenges: Vec<E::Fr>
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
let mut transcript = Transcript::new(&[]);
|
let mut transcript = Transcript::new(&[]);
|
||||||
@ -170,6 +95,8 @@ impl<E: Engine, C: Circuit<E>, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier
|
|||||||
|
|
||||||
let w: E::Fr = transcript.get_challenge_scalar();
|
let w: E::Fr = transcript.get_challenge_scalar();
|
||||||
|
|
||||||
|
println!("Verifier: Z = {}, W = {}", z, w);
|
||||||
|
|
||||||
let szw = {
|
let szw = {
|
||||||
// prover will supply s1 and s2, need to calculate
|
// prover will supply s1 and s2, need to calculate
|
||||||
// s(z, w) = X^-(N+1) * Y^N * s1 - X^N * s2
|
// s(z, w) = X^-(N+1) * Y^N * s1 - X^N * s2
|
||||||
@ -184,6 +111,7 @@ impl<E: Engine, C: Circuit<E>, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier
|
|||||||
// simultaneously add components to the batch verifier
|
// simultaneously add components to the batch verifier
|
||||||
|
|
||||||
// this is s2 contribution itself
|
// this is s2 contribution itself
|
||||||
|
let s2_proof = &aggregate.s2_proof;
|
||||||
let mut s2_part = s2_proof.c_value;
|
let mut s2_part = s2_proof.c_value;
|
||||||
s2_part.add_assign(&s2_proof.d_value);
|
s2_part.add_assign(&s2_proof.d_value);
|
||||||
s2_part.mul_assign(&x_n);
|
s2_part.mul_assign(&x_n);
|
||||||
@ -222,50 +150,244 @@ impl<E: Engine, C: Circuit<E>, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier
|
|||||||
|
|
||||||
// now work with s1 part
|
// now work with s1 part
|
||||||
|
|
||||||
let mut s1_part = permutation_argument_proof.s_zy;
|
let mut s1_part = aggregate.signature.perm_argument_proof.s_zy;
|
||||||
s1_part.mul_assign(&x_n_plus_1_inv);
|
s1_part.mul_assign(&x_n_plus_1_inv);
|
||||||
s1_part.mul_assign(&y_n);
|
s1_part.mul_assign(&y_n);
|
||||||
|
|
||||||
// TODO: this one should be from transcipt
|
let mut szw = s1_part;
|
||||||
// let s_prime_challenges = (0..num_permutation_polynomials).map(|_| E::Fr::rand(&mut self.randomness_source)).collect::<Vec<_>>();
|
szw.sub_assign(&s2_part);
|
||||||
|
|
||||||
// s and s' commitments of permutation argument
|
// verify commitments for s' and s
|
||||||
let mut s_commitments = vec![];
|
|
||||||
let mut s_prime_commitments = vec![];
|
{
|
||||||
for (s, s_prime) in permutation_argument_commitments.iter() {
|
let mut transcript = Transcript::new(&[]);
|
||||||
s_commitments.push(*s);
|
|
||||||
s_prime_commitments.push(*s_prime);
|
// let s_commitments = &aggregate.signature.s_commitments;
|
||||||
|
// let s_prime_commitments = &aggregate.signature.s_prime_commitments;
|
||||||
|
|
||||||
|
let mut challenges = vec![];
|
||||||
|
for (s, s_prime) in aggregate.signature.s_commitments.iter()
|
||||||
|
.zip(aggregate.signature.s_prime_commitments.iter()) {
|
||||||
|
{
|
||||||
|
let mut transcript = Transcript::new(&[]);
|
||||||
|
transcript.commit_point(s);
|
||||||
|
transcript.commit_point(s_prime);
|
||||||
|
let challenge = transcript.get_challenge_scalar();
|
||||||
|
challenges.push(challenge);
|
||||||
|
}
|
||||||
|
transcript.commit_point(s);
|
||||||
|
transcript.commit_point(s_prime);
|
||||||
|
}
|
||||||
|
|
||||||
|
let z_prime: E::Fr = transcript.get_challenge_scalar();
|
||||||
|
|
||||||
|
// we expect M permutation proofs, add them all into verification
|
||||||
|
// using batching with random challenges and extra randomness for pairing equation
|
||||||
|
{
|
||||||
|
// e(E,hαx)e(E−z′,hα) = e(Mj=1Sj′rj,h)e(g−v,hα)
|
||||||
|
let perm_proof = &aggregate.signature.perm_proof;
|
||||||
|
|
||||||
|
let s_r = multiexp(
|
||||||
|
aggregate.signature.s_prime_commitments.iter(),
|
||||||
|
challenges.iter()
|
||||||
|
).into_affine();
|
||||||
|
|
||||||
|
let p2_r = multiexp(
|
||||||
|
self.s1_special_reference.p_2.iter(),
|
||||||
|
challenges.iter()
|
||||||
|
).into_affine();
|
||||||
|
|
||||||
|
|
||||||
|
let value = perm_proof.v_zy;
|
||||||
|
|
||||||
|
let random: E::Fr = self.randomness_source.gen();
|
||||||
|
|
||||||
|
self.batch.add_opening(perm_proof.e_opening, random, z_prime);
|
||||||
|
self.batch.add_opening_value(random, value);
|
||||||
|
self.batch.add_commitment(s_r, random);
|
||||||
|
|
||||||
|
|
||||||
|
// e(F,hαx)e(F−yz′,hα) = e(Mj=1P2jrj,h)e(g−v,hα)
|
||||||
|
|
||||||
|
let mut y_z_prime = z_prime;
|
||||||
|
y_z_prime.mul_assign(&w);
|
||||||
|
|
||||||
|
let random: E::Fr = self.randomness_source.gen();
|
||||||
|
|
||||||
|
self.batch.add_opening(perm_proof.f_opening, random, y_z_prime);
|
||||||
|
self.batch.add_opening_value(random, value);
|
||||||
|
self.batch.add_commitment(p2_r, random);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// now we can actually take an opening of S commitments and
|
||||||
|
|
||||||
|
{
|
||||||
|
// e(I,hαx)e(I−z,hα) = e(Mj=1 Sj,h)e(g−s,hα)
|
||||||
|
|
||||||
|
let value = aggregate.signature.perm_argument_proof.s_zy;
|
||||||
|
let mut s_commitment = E::G1::zero();
|
||||||
|
|
||||||
|
for s in aggregate.signature.s_commitments.iter() {
|
||||||
|
s_commitment.add_assign_mixed(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
let random: E::Fr = self.randomness_source.gen();
|
||||||
|
|
||||||
|
self.batch.add_opening(aggregate.signature.perm_argument_proof.s_opening, random, z);
|
||||||
|
self.batch.add_opening_value(random, value);
|
||||||
|
self.batch.add_commitment(s_commitment.into_affine(), random);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Add grand product argument!
|
||||||
|
|
||||||
|
// for each of the grand product arguments create a corresponding commitment
|
||||||
|
// from already known elements
|
||||||
|
|
||||||
|
let beta: E::Fr = transcript.get_challenge_scalar();
|
||||||
|
println!("Beta in verifier = {}", beta);
|
||||||
|
let gamma: E::Fr = transcript.get_challenge_scalar();
|
||||||
|
println!("Gamma in verifier = {}", gamma);
|
||||||
|
|
||||||
|
let mut a_commitments = vec![];
|
||||||
|
let mut b_commitments = vec![];
|
||||||
|
|
||||||
|
use crate::pairing::CurveAffine;
|
||||||
|
use crate::pairing::ff::PrimeField;
|
||||||
|
|
||||||
|
for (j, (s, s_prime)) in aggregate.signature.s_commitments.iter()
|
||||||
|
.zip(aggregate.signature.s_prime_commitments.iter())
|
||||||
|
.enumerate()
|
||||||
|
|
||||||
|
{
|
||||||
|
// Sj(P4j)β(P1j)γ
|
||||||
|
|
||||||
|
let mut a = s.into_projective();
|
||||||
|
a.add_assign(&self.s1_special_reference.p_4[j].mul(beta.into_repr()));
|
||||||
|
a.add_assign(&self.s1_special_reference.p_1.mul(gamma.into_repr()));
|
||||||
|
let a = a.into_affine();
|
||||||
|
|
||||||
|
// Sj′(P3j)β(P1j)γ
|
||||||
|
|
||||||
|
let mut b = s_prime.into_projective();
|
||||||
|
b.add_assign(&self.s1_special_reference.p_3.mul(beta.into_repr()));
|
||||||
|
b.add_assign(&self.s1_special_reference.p_1.mul(gamma.into_repr()));
|
||||||
|
let b = b.into_affine();
|
||||||
|
|
||||||
|
// let a_original = aggregate.signature.grand_product_signature.a_commitments[j];
|
||||||
|
// let b_original = aggregate.signature.grand_product_signature.b_commitments[j];
|
||||||
|
|
||||||
|
// assert!(a == a_original);
|
||||||
|
// assert!(b == b_original);
|
||||||
|
|
||||||
|
a_commitments.push(a);
|
||||||
|
b_commitments.push(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now perform an actual check
|
||||||
|
{
|
||||||
|
let randomness: Vec<E::Fr> = (0..aggregate.signature.s_commitments.len()).map(|_| self.randomness_source.gen()).collect();
|
||||||
|
// e(Dj,hαx)e(D−yz,hα) = e(Aj,h)e(Bj,hxn+1)e(g−aj ,hα)
|
||||||
|
|
||||||
|
let g = srs.g_positive_x[0];
|
||||||
|
let h_alpha_x_precomp = srs.h_positive_x_alpha[1].prepare();
|
||||||
|
let h_alpha_precomp = srs.h_positive_x_alpha[0].prepare();
|
||||||
|
|
||||||
|
let mut h_x_n_plus_one_precomp = srs.h_positive_x[self.n];
|
||||||
|
h_x_n_plus_one_precomp.negate();
|
||||||
|
let h_x_n_plus_one_precomp = h_x_n_plus_one_precomp.prepare();
|
||||||
|
|
||||||
|
let mut h_prep = srs.h_positive_x[0];
|
||||||
|
h_prep.negate();
|
||||||
|
let h_prep = h_prep.prepare();
|
||||||
|
|
||||||
|
let a = multiexp(
|
||||||
|
a_commitments.iter(),
|
||||||
|
randomness.iter(),
|
||||||
|
).into_affine();
|
||||||
|
|
||||||
|
let a = a.prepare();
|
||||||
|
|
||||||
|
let b = multiexp(
|
||||||
|
b_commitments.iter(),
|
||||||
|
randomness.iter(),
|
||||||
|
).into_affine();
|
||||||
|
|
||||||
|
let b = b.prepare();
|
||||||
|
|
||||||
|
let mut yz_neg = w;
|
||||||
|
yz_neg.mul_assign(&z);
|
||||||
|
yz_neg.negate();
|
||||||
|
|
||||||
|
let mut ops = vec![];
|
||||||
|
let mut value = E::Fr::zero();
|
||||||
|
|
||||||
|
for (el, r) in aggregate.signature.grand_product_signature.grand_product_openings.iter().zip(randomness.iter()) {
|
||||||
|
let (v, o) = el;
|
||||||
|
ops.push(o.clone());
|
||||||
|
let mut val = *v;
|
||||||
|
val.mul_assign(&r);
|
||||||
|
value.add_assign(&val);
|
||||||
|
}
|
||||||
|
|
||||||
|
let value = g.mul(value.into_repr()).into_affine().prepare();
|
||||||
|
|
||||||
|
let openings = multiexp(
|
||||||
|
ops.iter(),
|
||||||
|
randomness.iter(),
|
||||||
|
).into_affine();
|
||||||
|
|
||||||
|
let openings_zy = openings.mul(yz_neg.into_repr()).into_affine().prepare();
|
||||||
|
let openings = openings.prepare();
|
||||||
|
|
||||||
|
// e(Dj,hαx)e(D−yz,hα) = e(Aj,h)e(Bj,hxn+1)e(g−aj ,hα)
|
||||||
|
|
||||||
|
let valid = E::final_exponentiation(&E::miller_loop(&[
|
||||||
|
(&openings, &h_alpha_x_precomp),
|
||||||
|
(&openings_zy, &h_alpha_precomp),
|
||||||
|
(&a, &h_prep),
|
||||||
|
(&b, &h_x_n_plus_one_precomp),
|
||||||
|
(&value, &h_alpha_precomp)
|
||||||
|
])).unwrap() == E::Fqk::one();
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// assert!(valid, "grand product arguments must be valid for individual commitments");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: sanity check for now,
|
||||||
|
// later eliminate a and b commitments
|
||||||
|
// for (j, (((a, b), s), s_prime)) in grand_product_signature.a_commitments.iter()
|
||||||
|
// .zip(grand_product_signature.b_commitments.iter())
|
||||||
|
// .zip(s_commitments.iter())
|
||||||
|
// .zip(s_prime_commitments.iter())
|
||||||
|
// .enumerate()
|
||||||
|
// {
|
||||||
|
// // Sj(P4j)β(P1j)γ
|
||||||
|
// let mut lhs = s.into_projective();
|
||||||
|
// lhs.add_assign(&specialized_srs.p_4[j].mul(beta.into_repr()));
|
||||||
|
// lhs.add_assign(&specialized_srs.p_1.mul(gamma.into_repr()));
|
||||||
|
|
||||||
|
// assert!(lhs.into_affine() == *a);
|
||||||
|
|
||||||
|
// // Sj′(P3j)β(P1j)γ
|
||||||
|
|
||||||
|
// let mut rhs = s_prime.into_projective();
|
||||||
|
// rhs.add_assign(&specialized_srs.p_3.mul(beta.into_repr()));
|
||||||
|
// rhs.add_assign(&specialized_srs.p_1.mul(gamma.into_repr()));
|
||||||
|
|
||||||
|
// assert!(rhs.into_affine() == *b);
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let randomness = (0..2).map(|_| E::Fr::rand(&mut self.randomness_source)).collect::<Vec<_>>();
|
szw
|
||||||
|
|
||||||
let valid = PermutationArgument::verify_s_prime_commitment(self.n,
|
|
||||||
&randomness,
|
|
||||||
&s_prime_challenges,
|
|
||||||
&s_prime_commitments,
|
|
||||||
permutation_proof,
|
|
||||||
w,
|
|
||||||
z_prime,
|
|
||||||
&self.s1_special_reference,
|
|
||||||
&srs);
|
|
||||||
|
|
||||||
assert!(valid);
|
|
||||||
|
|
||||||
// TODO: move all these to the transcripts
|
|
||||||
let beta : E::Fr = self.randomness_source.gen();
|
|
||||||
let gamma : E::Fr = self.randomness_source.gen();
|
|
||||||
|
|
||||||
let valid = PermutationArgument::verify(&s_commitments, &permutation_argument_proof, z, &srs);
|
|
||||||
|
|
||||||
assert!(valid);
|
|
||||||
|
|
||||||
let mut s = s1_part;
|
|
||||||
s.sub_assign(&s2_part);
|
|
||||||
|
|
||||||
s
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
println!("Verifier: S(z,w) = {}", szw);
|
||||||
|
|
||||||
{
|
{
|
||||||
let random: E::Fr = self.randomness_source.gen();
|
let random: E::Fr = self.randomness_source.gen();
|
||||||
|
|
||||||
|
@ -34,8 +34,9 @@ impl<E: Engine> WellformednessArgument<E> {
|
|||||||
srs: &SRS<E>
|
srs: &SRS<E>
|
||||||
) -> WellformednessSignature<E> {
|
) -> WellformednessSignature<E> {
|
||||||
let j = all_polys.len();
|
let j = all_polys.len();
|
||||||
let mut transcript = Transcript::new(&[]);
|
println!("Making wellformedness argument for {} polys", j);
|
||||||
let wellformed_argument = WellformednessArgument::new(all_polys);
|
let wellformed_argument = WellformednessArgument::new(all_polys);
|
||||||
|
// TODO: remove commitments
|
||||||
let commitments = wellformed_argument.commit(&srs);
|
let commitments = wellformed_argument.commit(&srs);
|
||||||
// let mut wellformed_challenges = vec![];
|
// let mut wellformed_challenges = vec![];
|
||||||
// for c in commitments.iter() {
|
// for c in commitments.iter() {
|
||||||
|
Loading…
Reference in New Issue
Block a user