cleanup succinct arguments for batched verification
This commit is contained in:
parent
da501f4572
commit
d4dd7d27fa
@ -31,7 +31,7 @@ use crate::{
|
||||
SynthesisError
|
||||
};
|
||||
|
||||
const MIMC_ROUNDS: usize = 2;
|
||||
const MIMC_ROUNDS: usize = 322;
|
||||
|
||||
fn mimc<E: Engine>(
|
||||
mut xl: E::Fr,
|
||||
@ -544,8 +544,8 @@ fn test_succinct_sonic_mimc() {
|
||||
let s1_srs = perm_structure.create_permutation_special_reference(&srs);
|
||||
let s2_srs = perm_structure.calculate_s2_commitment_value(&srs);
|
||||
|
||||
// let info = get_circuit_parameters_for_succinct_sonic::<Bls12, _>(circuit.clone()).expect("Must get circuit info");
|
||||
// println!("{:?}", info);
|
||||
let info = get_circuit_parameters_for_succinct_sonic::<Bls12, _>(circuit.clone()).expect("Must get circuit info");
|
||||
println!("{:?}", info);
|
||||
|
||||
println!("creating proof");
|
||||
let start = Instant::now();
|
||||
@ -609,36 +609,38 @@ fn test_succinct_sonic_mimc() {
|
||||
{
|
||||
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);
|
||||
|
||||
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!("Permutation argument done in {:?}", start.elapsed());
|
||||
|
||||
println!("S_1 naive = {}", s1_naive);
|
||||
// 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]);
|
||||
|
||||
let mut s_1 = s1_naive;
|
||||
s_1.mul_assign(&z_inv_n_plus_1);
|
||||
s_1.mul_assign(&y_n);
|
||||
// println!("S_1 naive = {}", s1_naive);
|
||||
|
||||
println!("S_1 multiplied = {}", s_1);
|
||||
// let mut s_1 = s1_naive;
|
||||
// s_1.mul_assign(&z_inv_n_plus_1);
|
||||
// s_1.mul_assign(&y_n);
|
||||
|
||||
let mut s_2 = s2_proof.c_value;
|
||||
s_2.add_assign(&s2_proof.d_value);
|
||||
s_2.mul_assign(&z_n);
|
||||
// println!("S_1 multiplied = {}", s_1);
|
||||
|
||||
s_1.sub_assign(&s_2);
|
||||
println!("S naive = {}", 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 mut verifier = SuccinctMultiVerifier::<Bls12, _, Permutation3, _>::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap();
|
||||
println!("verifying 100 proofs with advice");
|
||||
println!("verifying 100 proofs with succinct advice");
|
||||
let start = Instant::now();
|
||||
{
|
||||
for (ref proof, ref advice) in &proofs {
|
||||
|
@ -8,6 +8,8 @@ use std::marker::PhantomData;
|
||||
|
||||
use crate::sonic::srs::SRS;
|
||||
use crate::sonic::util::*;
|
||||
use crate::sonic::transcript::{Transcript, TranscriptProtocol};
|
||||
use super::wellformed_argument::{WellformednessSignature, WellformednessArgument};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct GrandProductArgument<E: Engine> {
|
||||
@ -27,7 +29,82 @@ pub struct GrandProductProof<E: Engine> {
|
||||
f_opening: E::G1Affine,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct GrandProductSignature<E: Engine> {
|
||||
pub a_commitments: Vec<E::G1Affine>,
|
||||
pub b_commitments: Vec<E::G1Affine>,
|
||||
pub c_commitments: Vec<(E::G1Affine, E::Fr)>,
|
||||
pub t_commitment: E::G1Affine,
|
||||
pub grand_product_openings: Vec<(E::Fr, E::G1Affine)>,
|
||||
// pub a_zy: Vec<E::Fr>,
|
||||
pub proof: GrandProductProof<E>,
|
||||
pub wellformedness_signature: WellformednessSignature<E>,
|
||||
}
|
||||
|
||||
impl<E: Engine> GrandProductArgument<E> {
|
||||
pub fn create_signature(
|
||||
grand_products: Vec<(Vec<E::Fr>, Vec<E::Fr>)>,
|
||||
y: E::Fr,
|
||||
z: E::Fr,
|
||||
srs: &SRS<E>,
|
||||
) -> GrandProductSignature<E> {
|
||||
let mut a_commitments = vec![];
|
||||
let mut b_commitments = vec![];
|
||||
|
||||
let mut transcript = Transcript::new(&[]);
|
||||
let mut grand_product_challenges = vec![];
|
||||
|
||||
for (a, b) in grand_products.iter() {
|
||||
let (c_a, c_b) = GrandProductArgument::commit_for_individual_products(& a[..], & b[..], &srs);
|
||||
{
|
||||
let mut transcript = Transcript::new(&[]);
|
||||
transcript.commit_point(&c_a);
|
||||
let challenge = transcript.get_challenge_scalar();
|
||||
grand_product_challenges.push(challenge);
|
||||
transcript.commit_point(&c_b);
|
||||
let challenge = transcript.get_challenge_scalar();
|
||||
grand_product_challenges.push(challenge);
|
||||
}
|
||||
a_commitments.push(c_a);
|
||||
b_commitments.push(c_b);
|
||||
transcript.commit_point(&c_a);
|
||||
transcript.commit_point(&c_b);
|
||||
}
|
||||
|
||||
let mut all_polys = vec![];
|
||||
for p in grand_products.iter() {
|
||||
let (a, b) = p;
|
||||
all_polys.push(a.clone());
|
||||
all_polys.push(b.clone());
|
||||
}
|
||||
|
||||
let wellformedness_signature = WellformednessArgument::create_signature(
|
||||
all_polys,
|
||||
&srs
|
||||
);
|
||||
|
||||
|
||||
let mut grand_product_argument = GrandProductArgument::new(grand_products);
|
||||
let c_commitments = grand_product_argument.commit_to_individual_c_polynomials(&srs);
|
||||
let t_commitment = grand_product_argument.commit_to_t_polynomial(&grand_product_challenges, y, &srs);
|
||||
let grand_product_openings = grand_product_argument.open_commitments_for_grand_product(y, z, &srs);
|
||||
let a_zy: Vec<E::Fr> = grand_product_openings.iter().map(|el| el.0.clone()).collect();
|
||||
let proof = grand_product_argument.make_argument(&a_zy, &grand_product_challenges, y, z, &srs);
|
||||
|
||||
GrandProductSignature {
|
||||
a_commitments,
|
||||
b_commitments,
|
||||
c_commitments,
|
||||
t_commitment,
|
||||
grand_product_openings,
|
||||
// a_zy,
|
||||
proof,
|
||||
wellformedness_signature
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
pub fn new(polynomials: Vec<(Vec<E::Fr>, Vec<E::Fr>)>) -> Self {
|
||||
assert!(polynomials.len() > 0);
|
||||
|
||||
|
@ -9,7 +9,9 @@ use std::marker::PhantomData;
|
||||
use crate::sonic::srs::SRS;
|
||||
use crate::sonic::util::*;
|
||||
use super::wellformed_argument::{WellformednessArgument, WellformednessProof};
|
||||
use super::grand_product_argument::{GrandProductArgument, GrandProductProof};
|
||||
use super::grand_product_argument::{GrandProductArgument, GrandProductSignature};
|
||||
|
||||
use crate::sonic::transcript::{Transcript, TranscriptProtocol};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct SpecializedSRS<E: Engine> {
|
||||
@ -43,6 +45,15 @@ pub struct PermutationArgumentProof<E: Engine> {
|
||||
pub s_zy: E::Fr
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct SignatureOfCorrectComputation<E: Engine> {
|
||||
pub s_commitments: Vec<E::G1Affine>,
|
||||
pub s_prime_commitments: Vec<E::G1Affine>,
|
||||
pub perm_argument_proof: PermutationArgumentProof<E>,
|
||||
pub perm_proof: PermutationProof<E>,
|
||||
pub grand_product_signature: GrandProductSignature<E>
|
||||
}
|
||||
|
||||
fn permute<F: Field>(coeffs: &[F], permutation: & [usize]) -> Vec<F>{
|
||||
assert_eq!(coeffs.len(), permutation.len());
|
||||
let mut result: Vec<F> = vec![F::zero(); coeffs.len()];
|
||||
@ -158,7 +169,6 @@ impl<E: Engine> PermutationArgument<E> {
|
||||
let mut permuted_coefficients = vec![];
|
||||
let mut permuted_at_y_coefficients = vec![];
|
||||
|
||||
|
||||
// naive algorithms
|
||||
// for every permutation poly
|
||||
// -- go throught all variable_idx
|
||||
@ -311,8 +321,6 @@ impl<E: Engine> PermutationArgument<E> {
|
||||
let s_polynomial = s_polynomial.unwrap();
|
||||
// evaluate at z
|
||||
let s_zy = evaluate_at_consequitive_powers(& s_polynomial[..], z, z);
|
||||
println!("In permutation argument S1_(z, y) = {}", s_zy);
|
||||
|
||||
|
||||
let mut s_zy_neg = s_zy;
|
||||
s_zy_neg.negate();
|
||||
@ -449,82 +457,6 @@ impl<E: Engine> PermutationArgument<E> {
|
||||
assert_eq!(randomness.len(), 2);
|
||||
assert_eq!(challenges.len(), commitments.len());
|
||||
|
||||
// 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_prep = srs.h_positive_x[0];
|
||||
// h_prep.negate();
|
||||
// let h_prep = h_prep.prepare();
|
||||
|
||||
// let value = proof.v_zy;
|
||||
// let g_v = g.mul(value.into_repr());
|
||||
|
||||
// {
|
||||
|
||||
// let mut minus_z_prime = z_prime;
|
||||
// minus_z_prime.negate();
|
||||
|
||||
// let e_z = proof.e_opening.mul(minus_z_prime.into_repr());
|
||||
|
||||
// let mut h_alpha_term = e_z;
|
||||
|
||||
// h_alpha_term.add_assign(&g_v);
|
||||
|
||||
// let h_alpha_x_term = proof.e_opening;
|
||||
|
||||
// let s_r = multiexp(
|
||||
// commitments.iter(),
|
||||
// challenges.iter()
|
||||
// ).into_affine();
|
||||
|
||||
// let h_term = s_r;
|
||||
|
||||
// let valid = E::final_exponentiation(&E::miller_loop(&[
|
||||
// (&h_alpha_x_term.prepare(), &h_alpha_x_precomp),
|
||||
// (&h_alpha_term.into_affine().prepare(), &h_alpha_precomp),
|
||||
// (&h_term.prepare(), &h_prep),
|
||||
// ])).unwrap() == E::Fqk::one();
|
||||
|
||||
// if !valid {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// {
|
||||
// let mut minus_yz = z_prime;
|
||||
// minus_yz.mul_assign(&y);
|
||||
// minus_yz.negate();
|
||||
|
||||
// let f_yz = proof.f_opening.mul(minus_yz.into_repr());
|
||||
|
||||
// let p2_r = multiexp(
|
||||
// specialized_srs.p_2.iter(),
|
||||
// challenges.iter()
|
||||
// ).into_affine();
|
||||
|
||||
// let mut h_alpha_term = f_yz;
|
||||
|
||||
// h_alpha_term.add_assign(&g_v);
|
||||
|
||||
// let h_alpha_x_term = proof.f_opening;
|
||||
|
||||
// let h_term = p2_r;
|
||||
|
||||
// let valid = E::final_exponentiation(&E::miller_loop(&[
|
||||
// (&h_alpha_x_term.prepare(), &h_alpha_x_precomp),
|
||||
// (&h_alpha_term.into_affine().prepare(), &h_alpha_precomp),
|
||||
// (&h_term.prepare(), &h_prep),
|
||||
// ])).unwrap() == E::Fqk::one();
|
||||
|
||||
// if !valid {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
|
||||
// true
|
||||
|
||||
// e(E,hαx)e(E−z′,hα) = e(Mj=1Sj′rj,h)e(g−v,hα)
|
||||
// e(F,hαx)e(F−yz′,hα) = e(Mj=1P2jrj,h)e(g−v,hα)
|
||||
|
||||
@ -635,6 +567,162 @@ impl<E: Engine> PermutationArgument<E> {
|
||||
(&h_term.prepare(), &h_prep),
|
||||
])).unwrap() == E::Fqk::one()
|
||||
}
|
||||
|
||||
pub fn make_signature(
|
||||
coefficients: Vec<Vec<E::Fr>>,
|
||||
permutations: Vec<Vec<usize>>,
|
||||
y: E::Fr,
|
||||
z: E::Fr,
|
||||
srs: &SRS<E>
|
||||
) -> SignatureOfCorrectComputation<E> {
|
||||
let mut argument = PermutationArgument::new(coefficients, permutations);
|
||||
let commitments = argument.commit(y, &srs);
|
||||
let mut transcript = Transcript::new(&[]);
|
||||
|
||||
let mut s_commitments = vec![];
|
||||
let mut s_prime_commitments = vec![];
|
||||
let mut challenges = vec![];
|
||||
for (s, s_prime) in commitments.into_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);
|
||||
s_commitments.push(s);
|
||||
s_prime_commitments.push(s_prime);
|
||||
}
|
||||
|
||||
let z_prime = transcript.get_challenge_scalar();
|
||||
// TODO: create better way to get few distinct challenges from the transcript
|
||||
let mut transcript = Transcript::new(&[]);
|
||||
transcript.commit_scalar(&z_prime);
|
||||
let beta: E::Fr = transcript.get_challenge_scalar();
|
||||
let mut transcript = Transcript::new(&[]);
|
||||
transcript.commit_scalar(&beta);
|
||||
let gamma: E::Fr = transcript.get_challenge_scalar();
|
||||
|
||||
let s_prime_commitments_opening = argument.open_commitments_to_s_prime(&challenges, y, z_prime, &srs);
|
||||
|
||||
let (proof, grand_product_signature) = argument.make_argument_with_transcript(
|
||||
beta,
|
||||
gamma,
|
||||
y,
|
||||
z,
|
||||
&srs
|
||||
);
|
||||
|
||||
SignatureOfCorrectComputation {
|
||||
s_commitments,
|
||||
s_prime_commitments,
|
||||
perm_argument_proof: proof,
|
||||
perm_proof: s_prime_commitments_opening,
|
||||
grand_product_signature
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Argument a permutation argument. Current implementation consumes, cause extra arguments are required
|
||||
pub fn make_argument_with_transcript(self,
|
||||
beta: E::Fr,
|
||||
gamma: E::Fr,
|
||||
y: E::Fr,
|
||||
z: E::Fr,
|
||||
srs: &SRS<E>
|
||||
) -> (PermutationArgumentProof<E>, GrandProductSignature<E>) {
|
||||
// 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
|
||||
|
||||
let n = self.n;
|
||||
let j = self.non_permuted_coefficients.len();
|
||||
|
||||
let mut s_polynomial: Option<Vec<E::Fr>> = None;
|
||||
|
||||
for c in self.permuted_at_y_coefficients.iter()
|
||||
{
|
||||
if s_polynomial.is_some() {
|
||||
if let Some(poly) = s_polynomial.as_mut() {
|
||||
add_polynomials(&mut poly[..], & c[..]);
|
||||
}
|
||||
} else {
|
||||
s_polynomial = Some(c.clone());
|
||||
}
|
||||
}
|
||||
let s_polynomial = s_polynomial.unwrap();
|
||||
// evaluate at z
|
||||
let s_zy = evaluate_at_consequitive_powers(& s_polynomial[..], z, z);
|
||||
|
||||
let mut s_zy_neg = s_zy;
|
||||
s_zy_neg.negate();
|
||||
|
||||
let s_zy_opening = polynomial_commitment_opening(
|
||||
0,
|
||||
n,
|
||||
Some(s_zy_neg).iter().chain_ext(s_polynomial.iter()),
|
||||
z,
|
||||
&srs
|
||||
);
|
||||
|
||||
// Sj(P4j)^β (P1j)^γ is equal to the product of the coefficients of Sj′(P3j)^β (P1j)^γ
|
||||
|
||||
let p_1_values = vec![E::Fr::one(); n];
|
||||
let p_3_values: Vec<E::Fr> = (1..=n).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();
|
||||
|
||||
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()
|
||||
|
||||
{
|
||||
// \prod si+βσi+γ = \prod s'i + β*i + γ
|
||||
let mut s_j_combination = non_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();
|
||||
|
||||
fe
|
||||
}).collect();
|
||||
mul_add_polynomials(&mut s_j_combination[..], & p_4_values[..], beta);
|
||||
mul_add_polynomials(&mut s_j_combination[..], & p_1_values[..], gamma);
|
||||
}
|
||||
|
||||
let mut s_prime_j_combination = 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);
|
||||
}
|
||||
|
||||
grand_products.push((s_j_combination, s_prime_j_combination));
|
||||
}
|
||||
|
||||
let grand_product_signature = GrandProductArgument::create_signature(
|
||||
grand_products,
|
||||
y,
|
||||
z,
|
||||
&srs
|
||||
);
|
||||
|
||||
let proof = PermutationArgumentProof {
|
||||
j: j,
|
||||
s_opening: s_zy_opening,
|
||||
s_zy: s_zy
|
||||
};
|
||||
|
||||
(proof, grand_product_signature)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -56,7 +56,7 @@ pub fn create_permutation_structure<E: Engine, C: Circuit<E>>(
|
||||
let n = backend.n;
|
||||
let q = backend.q;
|
||||
|
||||
println!("Will have {} gates and {} linear constraints", n, q);
|
||||
// println!("Will have {} gates and {} linear constraints", n, q);
|
||||
|
||||
PermutationStructure::<E> {
|
||||
n: n,
|
||||
@ -369,8 +369,6 @@ impl<E: Engine> PermutationStructure<E> {
|
||||
}
|
||||
}
|
||||
|
||||
println!("naive s eval = {}", s_contrib);
|
||||
|
||||
let mut argument = PermutationArgument::new(non_permuted_coeffs, permutations);
|
||||
let challenges = (0..m).map(|_| E::Fr::rand(rng)).collect::<Vec<_>>();
|
||||
|
||||
|
@ -7,6 +7,7 @@ use std::marker::PhantomData;
|
||||
|
||||
use crate::sonic::srs::SRS;
|
||||
use crate::sonic::util::*;
|
||||
use crate::sonic::transcript::{Transcript, TranscriptProtocol};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct WellformednessArgument<E: Engine> {
|
||||
@ -15,11 +16,44 @@ pub struct WellformednessArgument<E: Engine> {
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct WellformednessProof<E: Engine> {
|
||||
l: E::G1Affine,
|
||||
r: E::G1Affine
|
||||
pub l: E::G1Affine,
|
||||
pub r: E::G1Affine
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct WellformednessSignature<E: Engine> {
|
||||
pub commitments: Vec<E::G1Affine>,
|
||||
pub proof: WellformednessProof<E>
|
||||
}
|
||||
|
||||
impl<E: Engine> WellformednessArgument<E> {
|
||||
|
||||
pub fn create_signature(
|
||||
all_polys: Vec<Vec<E::Fr>>,
|
||||
srs: &SRS<E>
|
||||
) -> WellformednessSignature<E> {
|
||||
let j = all_polys.len();
|
||||
let mut transcript = Transcript::new(&[]);
|
||||
let wellformed_argument = WellformednessArgument::new(all_polys);
|
||||
let commitments = wellformed_argument.commit(&srs);
|
||||
let mut wellformed_challenges = vec![];
|
||||
for c in commitments.iter() {
|
||||
transcript.commit_point(c);
|
||||
}
|
||||
|
||||
for _ in 0..j {
|
||||
let challenge = transcript.get_challenge_scalar();
|
||||
wellformed_challenges.push(challenge);
|
||||
}
|
||||
|
||||
let proof = wellformed_argument.make_argument(wellformed_challenges, &srs);
|
||||
|
||||
WellformednessSignature {
|
||||
commitments,
|
||||
proof
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(polynomials: Vec<Vec<E::Fr>>) -> Self {
|
||||
assert!(polynomials.len() > 0);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user