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);
|
||||
|
||||
println!("Helper s(z, w) = {}", value);
|
||||
|
||||
let opening = {
|
||||
let mut value = value;
|
||||
value.negate();
|
||||
@ -117,20 +119,6 @@ pub fn create_aggregate_on_srs_using_information<E: Engine, C: Circuit<E>, S: Sy
|
||||
w,
|
||||
&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.
|
||||
@ -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(&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
|
||||
}
|
||||
|
||||
@ -180,20 +152,6 @@ pub fn create_aggregate_on_srs_using_information<E: Engine, C: Circuit<E>, S: Sy
|
||||
*y,
|
||||
&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));
|
||||
@ -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_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());
|
||||
@ -254,19 +203,6 @@ pub fn create_aggregate_on_srs_using_information<E: Engine, C: Circuit<E>, S: Sy
|
||||
&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 {
|
||||
|
@ -498,47 +498,13 @@ fn test_succinct_sonic_mimc() {
|
||||
use crate::sonic::sonic::AdaptorCircuit;
|
||||
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::helper::{create_aggregate_on_srs};
|
||||
use crate::sonic::sonic::Permutation3;
|
||||
use crate::sonic::unhelped::permutation_structure::*;
|
||||
use crate::sonic::unhelped::SuccinctMultiVerifier;
|
||||
use crate::sonic::unhelped::{create_aggregate_on_srs};
|
||||
|
||||
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 s1_srs = perm_structure.create_permutation_special_reference(&srs);
|
||||
@ -560,84 +526,49 @@ fn test_succinct_sonic_mimc() {
|
||||
println!("creating aggregate for {} proofs", samples);
|
||||
let start = Instant::now();
|
||||
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());
|
||||
|
||||
{
|
||||
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 rng = thread_rng();
|
||||
let mut verifier = MultiVerifier::<Bls12, _, Permutation3, _>::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap();
|
||||
println!("verifying {} proofs without advice", samples);
|
||||
let start = Instant::now();
|
||||
{
|
||||
for _ in 0..samples {
|
||||
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();
|
||||
// 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 rng = thread_rng();
|
||||
let mut verifier = MultiVerifier::<Bls12, _, Permutation3, _>::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap();
|
||||
println!("verifying 100 proofs with advice non-succinct");
|
||||
let start = Instant::now();
|
||||
{
|
||||
for (ref proof, ref advice) in &proofs {
|
||||
verifier.add_proof_with_advice(proof, &[], advice);
|
||||
}
|
||||
verifier.add_aggregate(&proofs, &aggregate);
|
||||
assert_eq!(verifier.check_all(), true); // TODO
|
||||
}
|
||||
println!("done in {:?}", start.elapsed());
|
||||
}
|
||||
// {
|
||||
// let rng = thread_rng();
|
||||
// let mut verifier = MultiVerifier::<Bls12, _, Permutation3, _>::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap();
|
||||
// println!("verifying {} proofs without advice", samples);
|
||||
// let start = Instant::now();
|
||||
// {
|
||||
// for _ in 0..samples {
|
||||
// verifier.add_proof(&proof, &[], |_, _| None);
|
||||
// }
|
||||
// assert_eq!(verifier.check_all(), true); // TODO
|
||||
// }
|
||||
// println!("done in {:?}", start.elapsed());
|
||||
// }
|
||||
|
||||
{
|
||||
use rand::{XorShiftRng, SeedableRng, Rand, Rng};
|
||||
let mut rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
|
||||
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 n = perm_structure.n;
|
||||
// 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);
|
||||
// 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 s2_proof = perm_structure.calculate_s2_proof(aggregate.z, aggregate.w, &srs);
|
||||
|
||||
// println!("Permutation argument done in {:?}", start.elapsed());
|
||||
|
||||
let mut verifier = SuccinctMultiVerifier::<Bls12, _, Permutation3, _>::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap();
|
||||
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_aggregate(
|
||||
&proofs,
|
||||
&proofs,
|
||||
&aggregate,
|
||||
&perm_arg_proof,
|
||||
&perm_proof,
|
||||
&s2_proof,
|
||||
num_poly,
|
||||
&srs,
|
||||
z_prime,
|
||||
&perm_commitments,
|
||||
s_prime_challenges
|
||||
&s1_srs
|
||||
);
|
||||
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::sonic::CountNandQ;
|
||||
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)]
|
||||
pub struct SuccinctAggregate<E: Engine> {
|
||||
pub permutations: []
|
||||
pub a: Vec<[Option<(Coeff<E>, usize)>; M]>,
|
||||
pub b: Vec<[Option<(Coeff<E>, usize)>; M]>,
|
||||
pub c: Vec<[Option<(Coeff<E>, usize)>; M]>,
|
||||
pub signature: SignatureOfCorrectComputation<E>,
|
||||
pub s2_proof: S2Proof<E>,
|
||||
pub c: E::G1Affine,
|
||||
// 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>(
|
||||
circuit: &C,
|
||||
inputs: &[(Proof<E>, SxyAdvice<E>)],
|
||||
params: &Parameters<E>,
|
||||
) -> SuccinctAggregate<E>
|
||||
{
|
||||
let n = params.vk.n;
|
||||
let q = params.vk.q;
|
||||
// pub fn create_aggregate<E: Engine, C: Circuit<E>, S: SynthesisDriver>(
|
||||
// circuit: &C,
|
||||
// inputs: &[(Proof<E>, SxyAdvice<E>)],
|
||||
// params: &Parameters<E>,
|
||||
// ) -> SuccinctAggregate<E>
|
||||
// {
|
||||
// let n = params.vk.n;
|
||||
// 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>(
|
||||
circuit: &C,
|
||||
inputs: &[(Proof<E>, SxyAdvice<E>)],
|
||||
srs: &SRS<E>,
|
||||
specialized_srs: &SpecializedSRS<E>
|
||||
) -> SuccinctAggregate<E>
|
||||
{
|
||||
// TODO: precompute this?
|
||||
@ -52,17 +67,19 @@ pub fn create_aggregate_on_srs<E: Engine, C: Circuit<E>, S: SynthesisDriver>(
|
||||
(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>(
|
||||
circuit: &C,
|
||||
inputs: &[(Proof<E>, SxyAdvice<E>)],
|
||||
srs: &SRS<E>,
|
||||
specialized_srs: &SpecializedSRS<E>,
|
||||
n: usize,
|
||||
q: usize,
|
||||
) -> 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 y_values: Vec<E::Fr> = Vec::with_capacity(inputs.len());
|
||||
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 t = {
|
||||
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)
|
||||
// Compute s(z, Y) for opening of the previous commitments at the same `z`
|
||||
let (s_poly_negative, s_poly_positive) = {
|
||||
let mut tmp = SyEval::new(z, n, q);
|
||||
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
|
||||
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);
|
||||
|
||||
println!("Aggregate: S(z,w) = {}", value);
|
||||
|
||||
let opening = {
|
||||
let mut value = value;
|
||||
value.negate();
|
||||
@ -126,22 +132,30 @@ pub fn create_aggregate_on_srs_using_information<E: Engine, C: Circuit<E>, S: Sy
|
||||
w,
|
||||
&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.
|
||||
fn compute_value<E: Engine>(y: &E::Fr, poly_positive: &[E::Fr], poly_negative: &[E::Fr]) -> E::Fr {
|
||||
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(&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
|
||||
}
|
||||
|
||||
use std::time::Instant;
|
||||
let start = Instant::now();
|
||||
|
||||
// we still need to re-open previous commitments at the same new z
|
||||
|
||||
let mut c_openings = vec![];
|
||||
for y in &y_values {
|
||||
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,
|
||||
&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));
|
||||
@ -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_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());
|
||||
@ -262,30 +238,17 @@ pub fn create_aggregate_on_srs_using_information<E: Engine, C: Circuit<E>, S: Sy
|
||||
z,
|
||||
&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 {
|
||||
// Commitment to s(z, Y)
|
||||
SuccinctAggregate {
|
||||
signature,
|
||||
s2_proof,
|
||||
c,
|
||||
// We have to open each of the S commitments to a random point `z`
|
||||
s_opening,
|
||||
// We have to open C to each constituent `y`
|
||||
c_openings,
|
||||
// Then we have to finally open C
|
||||
opening,
|
||||
|
||||
z: z,
|
||||
w: w,
|
||||
}
|
||||
}
|
@ -49,6 +49,7 @@ impl<E: Engine> GrandProductArgument<E> {
|
||||
z: E::Fr,
|
||||
srs: &SRS<E>,
|
||||
) -> GrandProductSignature<E> {
|
||||
println!("Making grand product argument for {} grand products", grand_products.len());
|
||||
let mut a_commitments = vec![];
|
||||
let mut b_commitments = vec![];
|
||||
|
||||
@ -68,7 +69,7 @@ impl<E: Engine> GrandProductArgument<E> {
|
||||
|
||||
let mut all_polys = 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();
|
||||
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}]
|
||||
pub fn commit_for_grand_product(a: &[E::Fr], b: &[E::Fr], srs: &SRS<E>) -> E::G1Affine {
|
||||
assert_eq!(a.len(), b.len());
|
||||
// // 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 {
|
||||
// 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) {
|
||||
assert_eq!(a.len(), b.len());
|
||||
|
||||
@ -536,11 +537,10 @@ impl<E: Engine> GrandProductArgument<E> {
|
||||
y: E::Fr,
|
||||
z: E::Fr,
|
||||
srs: &SRS<E>
|
||||
) -> bool {
|
||||
) -> bool {
|
||||
assert_eq!(randomness.len(), a_commitments.len());
|
||||
assert_eq!(openings.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α)
|
||||
|
||||
@ -625,8 +625,6 @@ impl<E: Engine> GrandProductArgument<E> {
|
||||
assert_eq!(a_zy.len(), challenges.len());
|
||||
assert_eq!(commitments.len(), challenges.len());
|
||||
|
||||
let d = srs.d;
|
||||
|
||||
let g = srs.g_positive_x[0];
|
||||
|
||||
let h_alpha_x_precomp = srs.h_positive_x_alpha[1].prepare();
|
||||
|
@ -9,10 +9,9 @@ mod grand_product_argument;
|
||||
mod permutation_argument;
|
||||
mod verifier;
|
||||
pub mod permutation_structure;
|
||||
// mod helper;
|
||||
// mod permutation;
|
||||
// pub mod padding;
|
||||
mod aggregate;
|
||||
|
||||
pub use self::wellformed_argument::{WellformednessArgument, WellformednessProof};
|
||||
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)]
|
||||
pub struct SpecializedSRS<E: Engine> {
|
||||
p_1: E::G1Affine,
|
||||
p_2: Vec<E::G1Affine>,
|
||||
p_3: E::G1Affine,
|
||||
p_4: Vec<E::G1Affine>,
|
||||
pub p_1: E::G1Affine,
|
||||
pub p_2: Vec<E::G1Affine>,
|
||||
pub p_3: E::G1Affine,
|
||||
pub p_4: Vec<E::G1Affine>,
|
||||
n: usize
|
||||
}
|
||||
|
||||
@ -26,8 +26,8 @@ pub struct SpecializedSRS<E: Engine> {
|
||||
pub struct PermutationArgument<E: Engine> {
|
||||
non_permuted_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>>,
|
||||
inverse_permuted_at_y_coefficients: Vec<Vec<E::Fr>>,
|
||||
permutations: Vec<Vec<usize>>,
|
||||
n: usize
|
||||
}
|
||||
@ -97,9 +97,10 @@ impl<E: Engine> PermutationArgument<E> {
|
||||
|
||||
PermutationArgument {
|
||||
non_permuted_coefficients: coefficients,
|
||||
non_permuted_at_y_coefficients: vec![vec![]],
|
||||
permuted_coefficients: vec![vec![]],
|
||||
permuted_at_y_coefficients: vec![vec![]],
|
||||
non_permuted_at_y_coefficients: vec![],
|
||||
// permuted_coefficients: vec![],
|
||||
permuted_at_y_coefficients: vec![],
|
||||
inverse_permuted_at_y_coefficients: vec![],
|
||||
permutations: permutations,
|
||||
n: n
|
||||
}
|
||||
@ -148,7 +149,9 @@ impl<E: Engine> PermutationArgument<E> {
|
||||
|
||||
fe
|
||||
}).collect();
|
||||
|
||||
let p4 = multiexp(srs.g_positive_x_alpha[0..n].iter(), values.iter()).into_affine();
|
||||
|
||||
p_4.push(p4);
|
||||
}
|
||||
}
|
||||
@ -164,71 +167,59 @@ impl<E: Engine> PermutationArgument<E> {
|
||||
|
||||
// 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)> {
|
||||
assert!(self.inverse_permuted_at_y_coefficients.len() == 0);
|
||||
let mut result = vec![];
|
||||
|
||||
let n = self.non_permuted_coefficients[0].len();
|
||||
|
||||
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 inverse_permuted_at_y_coefficients = vec![];
|
||||
|
||||
// naive algorithms
|
||||
// for every permutation poly
|
||||
// -- 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 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()) {
|
||||
// this one will have terms coeff[0] * Y^1
|
||||
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);
|
||||
// and commit to S'
|
||||
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
|
||||
mut_distribute_consequitive_powers(&mut permuted_at_y[..], y, y);
|
||||
// if we pretend that non_permuted_at_y[sigma[i]] = coeffs[sigma[i]] * Y^sigma[i],
|
||||
// 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 permuted_at_y = permute_inverse(&permuted_at_y[..], &p[..]);
|
||||
// let mut t = vec![E::Fr::zero(); inverse_permuted_at_y.len()];
|
||||
// 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
|
||||
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));
|
||||
|
||||
non_permuted_at_y_coefficients.push(non_permuted_at_y);
|
||||
permuted_coefficients.push(permuted);
|
||||
permuted_at_y_coefficients.push(permuted_at_y);
|
||||
// permuted_coefficients.push(permuted);
|
||||
// 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.permuted_coefficients = permuted_coefficients;
|
||||
// self.permuted_coefficients = permuted_coefficients;
|
||||
self.permuted_at_y_coefficients = permuted_at_y_coefficients;
|
||||
self.inverse_permuted_at_y_coefficients = inverse_permuted_at_y_coefficients;
|
||||
|
||||
result
|
||||
}
|
||||
@ -302,6 +293,7 @@ impl<E: Engine> PermutationArgument<E> {
|
||||
_specialized_srs: &SpecializedSRS<E>,
|
||||
srs: &SRS<E>
|
||||
) -> PermutationArgumentProof<E> {
|
||||
panic!("");
|
||||
// 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
|
||||
|
||||
@ -313,6 +305,7 @@ impl<E: Engine> PermutationArgument<E> {
|
||||
let mut s_polynomial: Option<Vec<E::Fr>> = None;
|
||||
|
||||
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 let Some(poly) = s_polynomial.as_mut() {
|
||||
@ -326,6 +319,8 @@ impl<E: Engine> PermutationArgument<E> {
|
||||
// evaluate at z
|
||||
let s_zy = evaluate_at_consequitive_powers(& s_polynomial[..], z, z);
|
||||
|
||||
println!("S_zy = {}", s_zy);
|
||||
|
||||
let mut s_zy_neg = s_zy;
|
||||
s_zy_neg.negate();
|
||||
|
||||
@ -350,32 +345,76 @@ impl<E: Engine> PermutationArgument<E> {
|
||||
|
||||
let mut grand_products = vec![];
|
||||
|
||||
for (i, ((non_permuted, permuted), permutation)) in self.non_permuted_coefficients.into_iter()
|
||||
.zip(self.permuted_coefficients.into_iter())
|
||||
.zip(self.permutations.into_iter()).enumerate()
|
||||
for (((non_permuted, inv_permuted), permutation), permuted) in self.non_permuted_at_y_coefficients.into_iter()
|
||||
.zip(self.inverse_permuted_at_y_coefficients.into_iter())
|
||||
.zip(self.permutations.into_iter())
|
||||
.zip(self.permuted_at_y_coefficients.into_iter())
|
||||
|
||||
{
|
||||
// \prod si+βσi+γ = \prod s'i + β*i + γ
|
||||
let mut s_j_combination = non_permuted;
|
||||
// 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
|
||||
// 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 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();
|
||||
let p_4_values: Vec<E::Fr> = permutation.clone().into_iter().map(|el| {
|
||||
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_j_combination[..], & p_4_values[..], beta);
|
||||
mul_add_polynomials(&mut s_j_combination[..], & p_1_values[..], gamma);
|
||||
fe
|
||||
}).collect();
|
||||
mul_add_polynomials(&mut s_combination[..], & p_4_values[..], beta);
|
||||
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);
|
||||
mul_add_polynomials(&mut s_prime_j_combination[..], & p_1_values[..], gamma);
|
||||
let p_4_values: Vec<E::Fr> = permutation.clone().into_iter().map(|el| {
|
||||
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![];
|
||||
@ -400,7 +439,7 @@ impl<E: Engine> PermutationArgument<E> {
|
||||
let proof = wellformed_argument.make_argument(wellformed_challenges.clone(), &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);
|
||||
@ -416,7 +455,7 @@ impl<E: Engine> PermutationArgument<E> {
|
||||
let randomness = (0..j).map(|_| E::Fr::rand(rng)).collect::<Vec<_>>();
|
||||
|
||||
let valid = GrandProductArgument::verify_ab_commitment(n,
|
||||
&randomness,
|
||||
& randomness,
|
||||
& a_commitments,
|
||||
& b_commitments,
|
||||
&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 (proof, grand_product_signature) = {
|
||||
let (proof, grand_product_signature, beta, gamma) = {
|
||||
// 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,
|
||||
y,
|
||||
z,
|
||||
&srs
|
||||
);
|
||||
|
||||
(proof, grand_product_signature)
|
||||
(proof, grand_product_signature, beta, gamma)
|
||||
};
|
||||
|
||||
// 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()));
|
||||
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);
|
||||
assert!(lhs.into_affine() == *a);
|
||||
|
||||
// // Sj′(P3j)β(P1j)γ
|
||||
// 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()));
|
||||
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);
|
||||
// }
|
||||
assert!(rhs.into_affine() == *b);
|
||||
}
|
||||
|
||||
SignatureOfCorrectComputation {
|
||||
s_commitments,
|
||||
@ -658,9 +697,11 @@ impl<E: Engine> PermutationArgument<E> {
|
||||
y: E::Fr,
|
||||
z: E::Fr,
|
||||
srs: &SRS<E>
|
||||
) -> (PermutationArgumentProof<E>, GrandProductSignature<E>) {
|
||||
) -> (PermutationArgumentProof<E>, GrandProductSignature<E>, E::Fr, E::Fr) {
|
||||
let beta: E::Fr = transcript.get_challenge_scalar();
|
||||
println!("Beta in prover = {}", beta);
|
||||
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)γ
|
||||
// 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;
|
||||
|
||||
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 let Some(poly) = s_polynomial.as_mut() {
|
||||
@ -709,59 +751,54 @@ impl<E: Engine> PermutationArgument<E> {
|
||||
let mut grand_products = vec![];
|
||||
|
||||
// TODO: Check the validity!
|
||||
|
||||
for ((non_permuted, permuted), permutation) in self.non_permuted_coefficients.into_iter()
|
||||
.zip(self.permuted_coefficients.into_iter())
|
||||
.zip(self.permutations.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())
|
||||
for ((non_permuted, inv_permuted), permutation) in self.non_permuted_at_y_coefficients.into_iter()
|
||||
.zip(self.inverse_permuted_at_y_coefficients.into_iter())
|
||||
.zip(self.permutations.into_iter())
|
||||
// .zip(self.permuted_at_y_coefficients.into_iter())
|
||||
|
||||
{
|
||||
// \prod si+βσi+γ = \prod s'i + β*i + γ
|
||||
|
||||
// s combination is coeff[sigma(i)]*Y^{sigma(i)} + beta*sigma(i) + gamma
|
||||
let mut s_j_combination = non_permuted;
|
||||
// let mut s_j_combination = permuted;
|
||||
// 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
|
||||
// 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 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();
|
||||
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_j_combination[..], & p_4_values[..], beta);
|
||||
mul_add_polynomials(&mut s_j_combination[..], & p_1_values[..], gamma);
|
||||
fe
|
||||
}).collect();
|
||||
mul_add_polynomials(&mut s_combination[..], & p_4_values[..], beta);
|
||||
mul_add_polynomials(&mut s_combination[..], & p_1_values[..], gamma);
|
||||
}
|
||||
|
||||
let mut s_prime_j_combination = permuted;
|
||||
// let mut s_prime_j_combination = non_permuted;
|
||||
// s' combination is coeff[i]*Y^{i} + beta*i + gamma
|
||||
|
||||
// combination of coeff[i]*Y^i + beta * i + gamma
|
||||
let mut s_prime_combination = non_permuted.clone();
|
||||
{
|
||||
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
|
||||
let product = s_j_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|
|
||||
let s_prime_product = s_prime_combination.iter().fold(E::Fr::one(), |mut sum, x|
|
||||
{
|
||||
sum.mul_assign(&x);
|
||||
|
||||
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(
|
||||
@ -778,7 +815,7 @@ impl<E: Engine> PermutationArgument<E> {
|
||||
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_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 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)
|
||||
}
|
||||
|
||||
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> {
|
||||
let s2_eval = S2Eval::new(self.n);
|
||||
|
||||
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;
|
||||
let n = self.n;
|
||||
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() {
|
||||
// place it
|
||||
assert!(*place != 0);
|
||||
let x_power = offset - gate_index + 1;
|
||||
let array_position = offset - gate_index; // special for A
|
||||
let place_coeff_into = &mut non_permuted_coeffs[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() {
|
||||
// place it
|
||||
assert!(*place != 0);
|
||||
let x_power = offset + gate_index + 1; // 1 indexed
|
||||
let array_position = offset + gate_index;
|
||||
let place_coeff_into = &mut non_permuted_coeffs[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() {
|
||||
// place it
|
||||
assert!(*place != 0);
|
||||
let x_power = offset + gate_index + 1; // 1 indexed
|
||||
let array_position = offset + gate_index;
|
||||
let place_coeff_into = &mut non_permuted_coeffs[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
|
||||
|
||||
// TODO: fix
|
||||
@ -283,15 +213,6 @@ impl<E: Engine> PermutationStructure<E> {
|
||||
|
||||
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
|
||||
|
||||
for i in 0..m {
|
||||
@ -322,6 +243,198 @@ impl<E: Engine> PermutationStructure<E> {
|
||||
(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>
|
||||
{
|
||||
let (non_permuted_coeffs, permutations) = self.create_permutation_vectors();
|
||||
@ -335,9 +448,33 @@ impl<E: Engine> PermutationStructure<E> {
|
||||
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 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(
|
||||
&non_permuted_coeffs,
|
||||
&permutations,
|
||||
@ -352,6 +489,8 @@ impl<E: Engine> PermutationStructure<E> {
|
||||
&srs,
|
||||
&specialized_srs
|
||||
);
|
||||
|
||||
signature
|
||||
}
|
||||
|
||||
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();
|
||||
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]);
|
||||
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][variable_index];
|
||||
let coeff = non_permuted_coeffs[permutation_index][*sigma_i - 1];
|
||||
|
||||
let mut result = coeff;
|
||||
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 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();
|
||||
println!("making srs");
|
||||
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());
|
||||
|
||||
{
|
||||
@ -506,18 +648,52 @@ fn test_simple_succinct_sonic() {
|
||||
use crate::sonic::sonic::Permutation3;
|
||||
use crate::sonic::unhelped::permutation_structure::*;
|
||||
|
||||
let x: Fr = rng.gen();
|
||||
let y: Fr = rng.gen();
|
||||
// let z: Fr = rng.gen();
|
||||
// let y: Fr = rng.gen();
|
||||
|
||||
let x = Fr::one();
|
||||
let mut y = Fr::one();
|
||||
y.double();
|
||||
let z: Fr = Fr::from_str("2").unwrap();
|
||||
let y: Fr = Fr::one();
|
||||
|
||||
let perm_structure = create_permutation_structure::<Bls12, _>(&MyCircuit);
|
||||
perm_structure.create_permutation_arguments(x, y, rng, &srs);
|
||||
perm_structure.make_signature(x, y, &srs);
|
||||
let (non_permuted_coeffs, permutations) = perm_structure.create_permutation_vectors();
|
||||
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 = s2.evaluate(x, y, &srs);
|
||||
let s2 = s2.evaluate(z, y, &srs);
|
||||
let mut s2_value = s2.c_value;
|
||||
s2_value.add_assign(&s2.d_value);
|
||||
|
||||
@ -525,7 +701,7 @@ fn test_simple_succinct_sonic() {
|
||||
let y_inv = y.inverse().unwrap();
|
||||
let mut p1 = y;
|
||||
p1.add_assign(&y_inv);
|
||||
p1.mul_assign(&x);
|
||||
p1.mul_assign(&z);
|
||||
expected_s2_value.add_assign(&p1);
|
||||
|
||||
let mut t0 = y;
|
||||
@ -536,13 +712,33 @@ fn test_simple_succinct_sonic() {
|
||||
|
||||
let mut p2 = t0;
|
||||
p2.add_assign(&t1);
|
||||
p2.mul_assign(&x);
|
||||
p2.mul_assign(&x);
|
||||
p2.mul_assign(&z);
|
||||
p2.mul_assign(&z);
|
||||
|
||||
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);
|
||||
|
||||
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 super::s2_proof::{S2Proof, S2Eval};
|
||||
use super::aggregate::SuccinctAggregate;
|
||||
use super::permutation_structure::create_permutation_structure;
|
||||
use super::permutation_argument::SpecializedSRS;
|
||||
use super::permutation_argument::{PermutationArgumentProof, PermutationProof, PermutationArgument};
|
||||
use super::permutation_argument::{
|
||||
PermutationArgumentProof,
|
||||
PermutationProof,
|
||||
PermutationArgument,
|
||||
SpecializedSRS
|
||||
};
|
||||
|
||||
pub struct SuccinctMultiVerifier<E: Engine, C: Circuit<E>, S: SynthesisDriver, R: Rng> {
|
||||
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 s1_special_reference = permutation_structure.create_permutation_special_reference(&srs);
|
||||
|
||||
|
||||
Ok(SuccinctMultiVerifier {
|
||||
circuit,
|
||||
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(
|
||||
&mut self,
|
||||
proofs: &[(Proof<E>, SxyAdvice<E>)],
|
||||
aggregate: &Aggregate<E>,
|
||||
permutation_argument_proof: &PermutationArgumentProof<E>,
|
||||
permutation_proof: &PermutationProof<E>,
|
||||
s2_proof: &S2Proof<E>,
|
||||
num_permutation_polynomials: usize,
|
||||
aggregate: &SuccinctAggregate<E>,
|
||||
srs: &SRS<E>,
|
||||
z_prime: E::Fr, // TODO, temporary before incorporation to the transcript
|
||||
permutation_argument_commitments: & Vec<(E::G1Affine, E::G1Affine)>,
|
||||
s_prime_challenges: Vec<E::Fr>
|
||||
specialized_srs: &SpecializedSRS<E>
|
||||
)
|
||||
{
|
||||
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();
|
||||
|
||||
println!("Verifier: Z = {}, W = {}", z, w);
|
||||
|
||||
let szw = {
|
||||
// prover will supply s1 and s2, need to calculate
|
||||
// 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
|
||||
|
||||
// this is s2 contribution itself
|
||||
let s2_proof = &aggregate.s2_proof;
|
||||
let mut s2_part = s2_proof.c_value;
|
||||
s2_part.add_assign(&s2_proof.d_value);
|
||||
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
|
||||
|
||||
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(&y_n);
|
||||
|
||||
// TODO: this one should be from transcipt
|
||||
// let s_prime_challenges = (0..num_permutation_polynomials).map(|_| E::Fr::rand(&mut self.randomness_source)).collect::<Vec<_>>();
|
||||
let mut szw = s1_part;
|
||||
szw.sub_assign(&s2_part);
|
||||
|
||||
// s and s' commitments of permutation argument
|
||||
let mut s_commitments = vec![];
|
||||
let mut s_prime_commitments = vec![];
|
||||
for (s, s_prime) in permutation_argument_commitments.iter() {
|
||||
s_commitments.push(*s);
|
||||
s_prime_commitments.push(*s_prime);
|
||||
// verify commitments for s' and s
|
||||
|
||||
{
|
||||
let mut transcript = Transcript::new(&[]);
|
||||
|
||||
// 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<_>>();
|
||||
|
||||
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
|
||||
szw
|
||||
};
|
||||
|
||||
println!("Verifier: S(z,w) = {}", szw);
|
||||
|
||||
{
|
||||
let random: E::Fr = self.randomness_source.gen();
|
||||
|
||||
|
@ -34,8 +34,9 @@ impl<E: Engine> WellformednessArgument<E> {
|
||||
srs: &SRS<E>
|
||||
) -> WellformednessSignature<E> {
|
||||
let j = all_polys.len();
|
||||
let mut transcript = Transcript::new(&[]);
|
||||
println!("Making wellformedness argument for {} polys", j);
|
||||
let wellformed_argument = WellformednessArgument::new(all_polys);
|
||||
// TODO: remove commitments
|
||||
let commitments = wellformed_argument.commit(&srs);
|
||||
// let mut wellformed_challenges = vec![];
|
||||
// for c in commitments.iter() {
|
||||
|
Loading…
Reference in New Issue
Block a user