start making wellformedness argument

This commit is contained in:
Alex Vlasov 2019-02-21 20:26:45 -05:00
parent 37f57a99a6
commit 0089b98439
5 changed files with 225 additions and 1 deletions

@ -0,0 +1,3 @@
/// One must prove that for commitments to two polynomials of degree n products of the coefficients
/// in those two polynomials are equal (part of the permutation argument)

@ -4,3 +4,4 @@
/// s1 part requires grand product and permutation arguments, that are also implemented
pub mod s2_proof;
mod wellformed_argument;

@ -0,0 +1,159 @@
/// Wellformedness argument allows to verify that some committment was to multivariate polynomial of degree n,
/// with no constant term and negative powers
use ff::{Field, PrimeField, PrimeFieldRepr};
use pairing::{Engine, CurveProjective, CurveAffine};
use std::marker::PhantomData;
use crate::sonic::srs::SRS;
use crate::sonic::util::*;
#[derive(Clone)]
pub struct WellformednessArgument<E: Engine> {
polynomials: Vec<Vec<E::Fr>>
}
#[derive(Clone)]
pub struct WellformednessProof<E: Engine> {
commitments: Vec<E::G1Affine>,
challenges: Vec<E::Fr>,
l: E::G1Affine,
r: E::G1Affine
}
impl<E: Engine> WellformednessArgument<E> {
pub fn new(polynomials: Vec<Vec<E::Fr>>) -> Self {
assert!(polynomials.len() > 0);
let length = polynomials[0].len();
for p in polynomials.iter() {
assert!(p.len() == length);
}
WellformednessArgument {
polynomials: polynomials
}
}
// Make a commitment to polynomial in a form \sum_{i=1}^{N} a_{i} X^{i} Y^{i}
pub fn commit(&self, srs: &SRS<E>) -> Vec<E::G1Affine> {
let mut results = vec![];
let n = self.polynomials[0].len();
for p in self.polynomials.iter() {
let c = multiexp(
srs.g_positive_x_alpha[0..n].iter(),
p.iter()
).into_affine();
results.push(c);
}
results
}
pub fn make_argument(self, challenges: Vec<E::Fr>, srs: &SRS<E>) -> WellformednessProof<E> {
let commitments = self.commit(&srs);
assert_eq!(commitments.len(), challenges.len());
let mut polynomials = self.polynomials;
let mut challenges = challenges;
let mut p0 = polynomials.pop().unwrap();
let r0 = challenges.pop().unwrap();
let n = p0.len();
mul_polynomial_by_scalar(&mut p0[..], r0);
let m = polynomials.len();
for _ in 0..m {
let p = polynomials.pop().unwrap();
let r = challenges.pop().unwrap();
mul_add_polynomials(&mut p0[..], & p[..], r);
}
let d = srs.d;
// here the multiplier is x^-d, so largest negative power is -d + 1
let l = polynomial_commitment::<E, _>(
n,
d - 1,
0,
&srs,
p0.iter());
// here the multiplier is x^d-n, so largest positive power is d
let r = polynomial_commitment::<E, _>(
n,
0,
d,
&srs,
p0.iter());
WellformednessProof {
commitments: commitments,
challenges: challenges,
l: l,
r: r
}
}
// pub fn verify(challenges: Vec<E::Fr>, proof: &WellformednessProof<E>, srs: &SRS<E>) -> bool {
// // e(C,hαx)e(Cyz,hα) = e(O,h)e(gc,hα)
// let alpha_x_precomp = srs.h_positive_x_alpha[1].prepare();
// let 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 mut c_minus_xy = proof.c_value;
// let mut xy = x;
// xy.mul_assign(&y);
// c_minus_xy.sub_assign(&xy);
// let mut c_in_c_minus_xy = proof.c_opening.mul(c_minus_xy.into_repr()).into_affine();
// let valid = E::final_exponentiation(&E::miller_loop(&[
// (&proof.c_opening.prepare(), &alpha_x_precomp),
// (&c_in_c_minus_xy.prepare(), &alpha_precomp),
// (&proof.o.prepare(), &h_prep),
// ])).unwrap() == E::Fqk::one();
// if !valid {
// return false;
// }
// // e(D,hαx)e(Dy1z,hα) = e(O,h)e(gd,hα)
// let mut d_minus_x_y_inv = proof.d_value;
// let mut x_y_inv = x;
// x_y_inv.mul_assign(&y.inverse().unwrap());
// d_minus_x_y_inv.sub_assign(&x_y_inv);
// let mut d_in_d_minus_x_y_inv = proof.d_opening.mul(d_minus_x_y_inv.into_repr()).into_affine();
// let valid = E::final_exponentiation(&E::miller_loop(&[
// (&proof.d_opening.prepare(), &alpha_x_precomp),
// (&d_in_d_minus_x_y_inv.prepare(), &alpha_precomp),
// (&proof.o.prepare(), &h_prep),
// ])).unwrap() == E::Fqk::one();
// if !valid {
// return false;
// }
// true
// }
}

@ -573,6 +573,67 @@ pub fn multiply_polynomials_serial<E: Engine>(mut a: Vec<E::Fr>, mut b: Vec<E::F
a
}
pub fn add_polynomials<F: Field>(a: &mut [F], b: &[F]) {
use crate::multicore::Worker;
use crate::domain::{EvaluationDomain, Scalar};
let worker = Worker::new();
assert_eq!(a.len(), b.len());
worker.scope(a.len(), |scope, chunk| {
for (a, b) in a.chunks_mut(chunk).zip(b.chunks(chunk))
{
scope.spawn(move |_| {
for (a, b) in a.iter_mut().zip(b.iter()) {
a.add_assign(b);
}
});
}
});
}
pub fn mul_polynomial_by_scalar<F: Field>(a: &mut [F], b: F) {
use crate::multicore::Worker;
use crate::domain::{EvaluationDomain, Scalar};
let worker = Worker::new();
worker.scope(a.len(), |scope, chunk| {
for a in a.chunks_mut(chunk)
{
scope.spawn(move |_| {
for a in a.iter_mut() {
a.mul_assign(&b);
}
});
}
});
}
pub fn mul_add_polynomials<F: Field>(a: &mut [F], b: &[F], c: F) {
use crate::multicore::Worker;
use crate::domain::{EvaluationDomain, Scalar};
let worker = Worker::new();
assert_eq!(a.len(), b.len());
worker.scope(a.len(), |scope, chunk| {
for (a, b) in a.chunks_mut(chunk).zip(b.chunks(chunk))
{
scope.spawn(move |_| {
for (a, b) in a.iter_mut().zip(b.iter()) {
let mut r = *b;
r.mul_assign(&c);
a.add_assign(&r);
}
});
}
});
}
fn serial_fft<E: Engine>(a: &mut [E::Fr], omega: &E::Fr, log_n: u32) {
fn bitreverse(mut n: u32, l: u32) -> u32 {
let mut r = 0;