mirror of
https://github.com/exfinen/zk-toolkit.git
synced 2026-01-10 04:28:02 -05:00
migrate to protocol 2 with zk
This commit is contained in:
@@ -150,7 +150,6 @@ impl<'a> Mul<&'a PrivateKey> for &G1Point {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
type AffinePoint = G1Point;
|
||||
impl_affine_add!(G1Point);
|
||||
impl_scalar_mul_point!(Fq1, G1Point);
|
||||
|
||||
@@ -2,40 +2,36 @@ use crate::{
|
||||
building_block::{
|
||||
curves::bls12_381::g1_point::G1Point,
|
||||
curves::bls12_381::g2_point::G2Point,
|
||||
field::{
|
||||
prime_field::PrimeField,
|
||||
prime_field_elem::PrimeFieldElem,
|
||||
},
|
||||
field::prime_field::PrimeField,
|
||||
},
|
||||
zk::w_trusted_setup::pinocchio::pinocchio_prover::PinocchioProver,
|
||||
};
|
||||
|
||||
pub struct EvaluationKeys {
|
||||
pub si: Vec<G1Point>,
|
||||
pub alpha_si: Vec<G1Point>,
|
||||
pub vi_mid: Vec<G1Point>,
|
||||
pub wi_mid: Vec<G1Point>,
|
||||
pub yi_mid: Vec<G1Point>,
|
||||
pub beta_vi_mid: Vec<G1Point>,
|
||||
pub beta_wi_mid: Vec<G1Point>,
|
||||
pub beta_yi_mid: Vec<G1Point>,
|
||||
pub g_v_v_k_mid: Vec<G1Point>,
|
||||
pub g1_w_w_k_mid: Vec<G1Point>,
|
||||
pub g2_w_w_k_mid: Vec<G2Point>,
|
||||
pub g_y_y_k_mid: Vec<G1Point>,
|
||||
pub g_v_alpha_v_k_mid: Vec<G1Point>,
|
||||
pub g_w_alpha_w_k_mid: Vec<G1Point>,
|
||||
pub g_y_alpha_y_k_mid: Vec<G1Point>,
|
||||
pub g1_si: Vec<G1Point>,
|
||||
pub g2_si: Vec<G2Point>,
|
||||
pub g_vwy_beta_vwy_k_mid: Vec<G1Point>,
|
||||
}
|
||||
|
||||
pub struct VerificationKeys {
|
||||
pub one_e1: G1Point,
|
||||
pub one_e2: G2Point,
|
||||
pub e_alpha: G2Point,
|
||||
pub e_gamma: G2Point,
|
||||
pub beta_v_gamma: G2Point,
|
||||
pub beta_w_gamma: G2Point,
|
||||
pub beta_y_gamma: G2Point,
|
||||
pub t_e1: G1Point,
|
||||
pub t_e2: G2Point,
|
||||
pub vi_io: Vec<G1Point>,
|
||||
pub wi_io: Vec<G2Point>,
|
||||
pub wi_io_e1: Vec<G1Point>,
|
||||
pub yi_io: Vec<G1Point>,
|
||||
pub wi_mid: Vec<G2Point>,
|
||||
pub one_g1: G1Point,
|
||||
pub one_g2: G2Point,
|
||||
pub g_alpha_v: G2Point,
|
||||
pub g2_alpha_w: G2Point,
|
||||
pub g2_alpha_y: G2Point,
|
||||
pub g_gamma: G2Point,
|
||||
pub g_beta_gamma: G2Point,
|
||||
pub g_y_t: G1Point,
|
||||
pub g_v_v_k_io: Vec<G1Point>,
|
||||
pub g_w_w_k_io: Vec<G2Point>,
|
||||
pub g_y_y_k_io: Vec<G1Point>,
|
||||
}
|
||||
|
||||
pub struct CRS {
|
||||
@@ -48,93 +44,104 @@ impl CRS {
|
||||
pub fn new(
|
||||
f: &PrimeField,
|
||||
p: &PinocchioProver,
|
||||
s: &PrimeFieldElem,
|
||||
) -> Self {
|
||||
println!("--> Building CRS...");
|
||||
let g1 = &G1Point::g();
|
||||
let g2 = &G2Point::g();
|
||||
let E1 = |n: &PrimeFieldElem| -> G1Point { g1 * n };
|
||||
let E2 = |n: &PrimeFieldElem| -> G2Point { g2 * n };
|
||||
|
||||
let alpha = &f.rand_elem(true);
|
||||
let beta_v = &f.rand_elem(true);
|
||||
let beta_w = &f.rand_elem(true);
|
||||
let beta_y = &f.rand_elem(true);
|
||||
// generate random values
|
||||
let r_v = &f.rand_elem(true);
|
||||
let r_w = &f.rand_elem(true);
|
||||
let alpha_v = &f.rand_elem(true);
|
||||
let alpha_w = &f.rand_elem(true);
|
||||
let alpha_y = &f.rand_elem(true);
|
||||
let beta = &f.rand_elem(true);
|
||||
let gamma = &f.rand_elem(true);
|
||||
|
||||
let s_pows = &s.pow_seq(&p.max_degree);
|
||||
let mid_beg: usize = (&p.witness.mid_beg.e).try_into().unwrap();
|
||||
// derive values from random values
|
||||
let r_y = &(r_v * r_w);
|
||||
let g1_v = &(g1 * r_v);
|
||||
let g2_v = &(g2 * r_v);
|
||||
let g1_w = &(g1 * r_w);
|
||||
let g2_w = &(g2 * r_w);
|
||||
let g_y = &(g1 * r_y);
|
||||
|
||||
let mid: Vec<usize> = {
|
||||
let end: usize = (&p.witness.end.e).try_into().unwrap();
|
||||
(mid_beg..=end).collect()
|
||||
// build indices
|
||||
let (mid, io) = {
|
||||
let mid_beg: usize = (&p.witness.mid_beg.e).try_into().unwrap();
|
||||
let mid: Vec<usize> = {
|
||||
let end: usize = (&p.witness.end.e).try_into().unwrap();
|
||||
(mid_beg..=end).collect()
|
||||
};
|
||||
let io = (0..mid_beg).collect::<Vec<usize>>();
|
||||
(mid, io)
|
||||
};
|
||||
let io: &Vec<usize> = &(0usize..mid_beg).collect();
|
||||
let s = &f.elem(&42u8); // &f.rand_elem(true);
|
||||
|
||||
// Evaluation keys
|
||||
// compute evaluation keys
|
||||
println!("----> Computing evaluation keys...");
|
||||
let g_v_v_k_mid: Vec<G1Point> = mid.iter().map(|i| { g1_v * &p.vi[*i].eval_at(s) }).collect();
|
||||
let g1_w_w_k_mid: Vec<G1Point> = mid.iter().map(|i| { g1_w * &p.wi[*i].eval_at(s) }).collect();
|
||||
let g2_w_w_k_mid: Vec<G2Point> = mid.iter().map(|i| { g2_w * &p.wi[*i].eval_at(s) }).collect();
|
||||
let g_y_y_k_mid: Vec<G1Point> = mid.iter().map(|i| { g_y * &p.yi[*i].eval_at(s) }).collect();
|
||||
|
||||
// E(s^i), E(alpha * s^i)
|
||||
let si: Vec<G1Point> = s_pows.iter().map(|pow| { E1(pow) }).collect();
|
||||
let alpha_si: Vec<G1Point> = s_pows.iter().map(|pow| {
|
||||
E1(pow) * alpha
|
||||
}).collect();
|
||||
let g_v_alpha_v_k_mid: Vec<G1Point> = mid.iter().map(|i| { g1_v * alpha_v * &p.vi[*i].eval_at(s) }).collect();
|
||||
let g_w_alpha_w_k_mid: Vec<G1Point> = mid.iter().map(|i| { g1_w * alpha_w * &p.wi[*i].eval_at(s) }).collect();
|
||||
let g_y_alpha_y_k_mid: Vec<G1Point> = mid.iter().map(|i| { g_y * alpha_y * &p.yi[*i].eval_at(s) }).collect();
|
||||
|
||||
// mid contains witness 1 as well
|
||||
let vi_mid: Vec<G1Point> = mid.iter().map(|i| { E1(&p.vi[*i].eval_at(s)) }).collect();
|
||||
let wi_mid_e1: Vec<G1Point> = mid.iter().map(|i| { E1(&p.wi[*i].eval_at(s)) }).collect();
|
||||
let wi_mid_e2: Vec<G2Point> = mid.iter().map(|i| { E2(&p.wi[*i].eval_at(s)) }).collect();
|
||||
let yi_mid: Vec<G1Point> = mid.iter().map(|i| { E1(&p.yi[*i].eval_at(s)) }).collect();
|
||||
let s_pows = &s.pow_seq(&p.max_degree);
|
||||
let g1_si: Vec<G1Point> = s_pows.iter().map(|pow| { g1 * pow }).collect();
|
||||
let g2_si: Vec<G2Point> = s_pows.iter().map(|pow| { g2 * pow }).collect();
|
||||
|
||||
let beta_vi_mid: Vec<G1Point> = mid.iter().map(|i| { E1(&p.vi[*i].eval_at(s)) * beta_v }).collect();
|
||||
let beta_wi_mid: Vec<G1Point> = mid.iter().map(|i| { E1(&p.wi[*i].eval_at(s)) * beta_w }).collect();
|
||||
let beta_yi_mid: Vec<G1Point> = mid.iter().map(|i| { E1(&p.yi[*i].eval_at(s)) * beta_y }).collect();
|
||||
let g_vwy_beta_vwy_k_mid: Vec<G1Point> = {
|
||||
mid.iter().map(|i| {
|
||||
g1_v * beta * &p.vi[*i].eval_at(s)
|
||||
+ g1_w * beta * &p.wi[*i].eval_at(s)
|
||||
+ g_y * beta * &p.yi[*i].eval_at(s)
|
||||
}).collect()
|
||||
};
|
||||
|
||||
// Verification keys
|
||||
// compute verification keys
|
||||
println!("----> Computing verification keys...");
|
||||
let one_g1 = g1 * f.elem(&1u8);
|
||||
let one_g2 = g2 * f.elem(&1u8);
|
||||
let g_alpha_v = g2 * alpha_v;
|
||||
let g2_alpha_w = g2 * alpha_w;
|
||||
let g2_alpha_y = g2 * alpha_y;
|
||||
let g_gamma = g2 * gamma;
|
||||
let g_beta_gamma = g2 * beta * gamma;
|
||||
|
||||
let one_e1 = E1(&f.elem(&1u8));
|
||||
let one_e2 = E2(&f.elem(&1u8));
|
||||
let e_alpha = E2(alpha);
|
||||
let e_gamma = E2(gamma);
|
||||
let beta_v_gamma = E2(gamma) * beta_v;
|
||||
let beta_w_gamma = E2(gamma) * beta_w;
|
||||
let beta_y_gamma = E2(gamma) * beta_y;
|
||||
let g_y_t = g_y * p.t.eval_at(s);
|
||||
|
||||
let t_e1 = E1(&p.t.eval_at(s));
|
||||
let t_e2 = E2(&p.t.eval_at(s));
|
||||
|
||||
let vi_io: Vec<G1Point> = io.iter().map(|i| { E1(&p.vi[*i].eval_at(s)) }).collect();
|
||||
let wi_io: Vec<G2Point> = io.iter().map(|i| { E2(&p.wi[*i].eval_at(s)) }).collect();
|
||||
let wi_io_e1: Vec<G1Point> = io.iter().map(|i| { E1(&p.wi[*i].eval_at(s)) }).collect();
|
||||
let yi_io: Vec<G1Point> = io.iter().map(|i| { E1(&p.yi[*i].eval_at(s)) }).collect();
|
||||
let g_v_v_k_io: Vec<G1Point> = io.iter().map(|i| { g1_v * &p.vi[*i].eval_at(s) }).collect();
|
||||
let g_w_w_k_io: Vec<G2Point> = io.iter().map(|i| { g2_w * &p.wi[*i].eval_at(s) }).collect();
|
||||
let g_y_y_k_io: Vec<G1Point> = io.iter().map(|i| { g_y * &p.yi[*i].eval_at(s) }).collect();
|
||||
|
||||
let ek = EvaluationKeys {
|
||||
si,
|
||||
alpha_si,
|
||||
vi_mid,
|
||||
wi_mid: wi_mid_e1,
|
||||
yi_mid,
|
||||
beta_vi_mid,
|
||||
beta_wi_mid,
|
||||
beta_yi_mid,
|
||||
g_v_v_k_mid,
|
||||
g1_w_w_k_mid,
|
||||
g2_w_w_k_mid,
|
||||
g_y_y_k_mid,
|
||||
g_v_alpha_v_k_mid,
|
||||
g_w_alpha_w_k_mid,
|
||||
g_y_alpha_y_k_mid,
|
||||
g1_si,
|
||||
g2_si,
|
||||
g_vwy_beta_vwy_k_mid,
|
||||
};
|
||||
|
||||
let vk = VerificationKeys {
|
||||
one_e1,
|
||||
one_e2,
|
||||
e_alpha,
|
||||
e_gamma,
|
||||
beta_v_gamma,
|
||||
beta_w_gamma,
|
||||
beta_y_gamma,
|
||||
t_e1,
|
||||
t_e2,
|
||||
vi_io,
|
||||
wi_io,
|
||||
wi_io_e1,
|
||||
yi_io,
|
||||
wi_mid: wi_mid_e2,
|
||||
one_g1,
|
||||
one_g2,
|
||||
g_alpha_v,
|
||||
g2_alpha_w,
|
||||
g2_alpha_y,
|
||||
g_gamma,
|
||||
g_beta_gamma,
|
||||
g_y_t,
|
||||
g_v_v_k_io,
|
||||
g_w_w_k_io,
|
||||
g_y_y_k_io,
|
||||
};
|
||||
|
||||
CRS {
|
||||
|
||||
@@ -4,17 +4,17 @@ use crate::building_block::curves::bls12_381::{
|
||||
};
|
||||
|
||||
pub struct PinocchioProof {
|
||||
pub v_mid: G1Point,
|
||||
pub v_mid_zk: G1Point,
|
||||
pub w_mid_e1: G1Point,
|
||||
pub w_mid_e2: G2Point,
|
||||
pub y_mid: G1Point,
|
||||
pub y_mid_zk: G1Point,
|
||||
pub beta_v_mid: G1Point,
|
||||
pub beta_w_mid_e1: G1Point,
|
||||
pub beta_y_mid: G1Point,
|
||||
pub h: G1Point,
|
||||
pub adj_h: G1Point,
|
||||
pub alpha_h: G1Point,
|
||||
pub g_v_v_mid_s: G1Point,
|
||||
pub g1_w_w_mid_s: G1Point,
|
||||
pub g2_w_w_mid_s: G2Point,
|
||||
pub g_y_y_mid_s: G1Point,
|
||||
|
||||
pub g_h_s: G2Point,
|
||||
|
||||
pub g_v_alpha_v_mid_s: G1Point,
|
||||
pub g_w_alpha_w_mid_s: G1Point,
|
||||
pub g_y_alpha_y_mid_s: G1Point,
|
||||
|
||||
pub g_beta_vwy_mid_s: G1Point,
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,10 @@ use crate::{
|
||||
equation_parser::EquationParser,
|
||||
gate::Gate,
|
||||
qap::QAP,
|
||||
polynomial::{Polynomial, DivResult},
|
||||
polynomial::{
|
||||
DivResult,
|
||||
Polynomial,
|
||||
},
|
||||
pinocchio_proof::PinocchioProof,
|
||||
r1cs::R1CS,
|
||||
r1cs_tmpl::R1CSTmpl,
|
||||
@@ -38,42 +41,10 @@ pub struct PinocchioProver {
|
||||
}
|
||||
|
||||
impl PinocchioProver {
|
||||
fn print_debug_info(
|
||||
f: &PrimeField,
|
||||
gates: &Vec<Gate>,
|
||||
r1cs: &R1CS,
|
||||
qap: &QAP,
|
||||
s: &PrimeFieldElem,
|
||||
) {
|
||||
println!("s = {:?}\n", s);
|
||||
println!("witness {:?}\n", &r1cs.witness);
|
||||
|
||||
for (i, gate) in gates.iter().enumerate() {
|
||||
println!("{}: {:?}", i+1 , gate);
|
||||
}
|
||||
println!("");
|
||||
|
||||
let mut v = f.elem(&0u8);
|
||||
let mut w = f.elem(&0u8);
|
||||
let mut y = f.elem(&0u8);
|
||||
|
||||
for i in 0..r1cs.witness.size_in_usize() {
|
||||
let vi = &qap.vi[i].eval_at(s);
|
||||
let wi = &qap.wi[i].eval_at(s);
|
||||
let yi = &qap.yi[i].eval_at(s);
|
||||
|
||||
v = &v + vi * &r1cs.witness[&i];
|
||||
w = &w + wi * &r1cs.witness[&i];
|
||||
y = &y + yi * &r1cs.witness[&i];
|
||||
}
|
||||
println!("{:?} * {:?} = {:?}\n", v, w, y);
|
||||
}
|
||||
|
||||
pub fn new(
|
||||
f: &PrimeField,
|
||||
expr: &str,
|
||||
witness_map: &HashMap<Term, PrimeFieldElem>,
|
||||
s: &PrimeFieldElem,
|
||||
) -> Self {
|
||||
let eq = EquationParser::parse(f, expr).unwrap();
|
||||
|
||||
@@ -89,15 +60,20 @@ impl PinocchioProver {
|
||||
let p = qap.build_p(&r1cs.witness);
|
||||
|
||||
let max_degree: usize = {
|
||||
let xs = vec![&qap.vi[..], &qap.wi[..], &qap.yi[..]].concat();
|
||||
xs.iter().map(|x| x.degree()).max().unwrap()
|
||||
}.e.try_into().unwrap();
|
||||
let xs = vec![
|
||||
&qap.vi[..],
|
||||
&qap.wi[..],
|
||||
&qap.yi[..],
|
||||
&vec![p.clone(), t.clone()],
|
||||
].concat();
|
||||
let n: PrimeFieldElem = xs.iter().map(|x| x.degree()).max().unwrap();
|
||||
let n: usize = n.e.try_into().unwrap();
|
||||
n + 1
|
||||
};
|
||||
|
||||
let witness = Witness::new(&r1cs.witness.clone(), &tmpl.mid_beg);
|
||||
let num_constraints = tmpl.constraints.len();
|
||||
|
||||
Self::print_debug_info(f, gates, &r1cs, &qap, s);
|
||||
|
||||
PinocchioProver {
|
||||
f: f.clone(),
|
||||
max_degree,
|
||||
@@ -114,87 +90,51 @@ impl PinocchioProver {
|
||||
pub fn prove(&self, crs: &CRS) -> PinocchioProof {
|
||||
println!("--> Generating proof...");
|
||||
let witness_mid = &self.witness.mid();
|
||||
let witness_io = &self.witness.io();
|
||||
|
||||
macro_rules! calc {
|
||||
($point_type:ty, $points:ident) => {{
|
||||
let mut sum = <$point_type>::zero();
|
||||
for i in 0..$points.len() {
|
||||
sum = sum + &$points[i] * &witness_mid[&i];
|
||||
}
|
||||
sum
|
||||
}};
|
||||
let ek = &crs.ek;
|
||||
|
||||
let mut g_v_v_mid_s = G1Point::zero();
|
||||
let mut g1_w_w_mid_s = G1Point::zero();
|
||||
let mut g2_w_w_mid_s = G2Point::zero();
|
||||
let mut g_y_y_mid_s = G1Point::zero();
|
||||
let mut g_v_alpha_v_mid_s = G1Point::zero();
|
||||
let mut g_w_alpha_w_mid_s = G1Point::zero();
|
||||
let mut g_y_alpha_y_mid_s = G1Point::zero();
|
||||
let mut g_beta_vwy_mid_s = G1Point::zero();
|
||||
|
||||
for i in 0..witness_mid.size_in_usize() {
|
||||
let w = &witness_mid[&i];
|
||||
|
||||
g_v_v_mid_s = &g_v_v_mid_s + &ek.g_v_v_k_mid[i] * w;
|
||||
g1_w_w_mid_s = &g1_w_w_mid_s + &ek.g1_w_w_k_mid[i] * w;
|
||||
g2_w_w_mid_s = &g2_w_w_mid_s + &ek.g2_w_w_k_mid[i] * w;
|
||||
g_y_y_mid_s = &g_y_y_mid_s + &ek.g_y_y_k_mid[i] * w;
|
||||
|
||||
g_v_alpha_v_mid_s = &g_v_alpha_v_mid_s + &ek.g_v_alpha_v_k_mid[i] * w;
|
||||
g_w_alpha_w_mid_s = &g_w_alpha_w_mid_s + &ek.g_w_alpha_w_k_mid[i] * w;
|
||||
g_y_alpha_y_mid_s = &g_y_alpha_y_mid_s + &ek.g_y_alpha_y_k_mid[i] * w;
|
||||
|
||||
g_beta_vwy_mid_s = &g_beta_vwy_mid_s + &ek.g_vwy_beta_vwy_k_mid[i] * w;
|
||||
}
|
||||
let calc_e1 = |points: &Vec<G1Point>| calc!(G1Point, points);
|
||||
let calc_e2 = |points: &Vec<G2Point>| calc!(G2Point, points);
|
||||
|
||||
// making only v and y zero-knowledge, excluding w.
|
||||
// the reason is that including w results in having t(s)^2 in the
|
||||
// adjusted h, and that seems to make adj_h * t != v * w - y
|
||||
//
|
||||
// without using delta factors, adj_h(s) * t(s) is:
|
||||
//
|
||||
// adj_h * t(s)
|
||||
// = (v(s) + t(s)) * (w(s) + t(s)) - (y(s) + t(s))
|
||||
// = v(s) * w(s) + v(s) * t(s) + w(s) * t(s) + t(s)^2 - y(s) - t(s)
|
||||
// = v(s) * w(s) - y(s) + v(s) * t(s) + w(s) * t(s) + t(s)^2 - t(s)
|
||||
// = h(s) * t(s) + v(s) * t(s) + w(s) * t(s) + t(s)^2 - t(s)
|
||||
// = t(s) * (h(s) + v(s) + w(s) + t(s) - 1)
|
||||
//
|
||||
// so, adjusted h is h(s) + v(s) + w(s) + t(s) - 1.
|
||||
// but the existence t(s) here seems to make the calculation fail.
|
||||
//
|
||||
// TODO fix this problem and make w zero-knowledge as well
|
||||
|
||||
let (ek, vk, f) = (&crs.ek, &crs.vk, &self.f);
|
||||
let delta_v = &f.rand_elem(true);
|
||||
let delta_y = &f.rand_elem(true);
|
||||
|
||||
let v_mid = calc_e1(&ek.vi_mid);
|
||||
let v_mid_zk = calc_e1(&ek.vi_mid) + &vk.t_e1 * delta_v;
|
||||
let beta_v_mid = calc_e1(&ek.beta_vi_mid);
|
||||
|
||||
let w_mid_e1 = calc_e1(&ek.wi_mid);
|
||||
let beta_w_mid_e1 = calc_e1(&ek.beta_wi_mid);
|
||||
|
||||
let w_mid_e2 = calc_e2(&vk.wi_mid);
|
||||
|
||||
let y_mid = calc_e1(&ek.yi_mid);
|
||||
let y_mid_zk = calc_e1(&ek.yi_mid) + &vk.t_e1 * delta_y;
|
||||
let beta_y_mid = calc_e1(&ek.beta_yi_mid);
|
||||
|
||||
let h = match self.p.divide_by(&self.t) {
|
||||
DivResult::Quotient(h) => h,
|
||||
DivResult::QuotientRemainder(_) => panic!("p must be divisible by t"),
|
||||
let g_h_s = {
|
||||
let h = match self.p.divide_by(&self.t) {
|
||||
DivResult::Quotient(q) => q,
|
||||
_ => panic!("p should be divisible by t"),
|
||||
};
|
||||
h.eval_with_g2_hidings(&ek.g2_si)
|
||||
};
|
||||
|
||||
let h_hiding = h.eval_with_g1_hidings(&ek.si);
|
||||
|
||||
let adj_h = {
|
||||
let mut w_e_e1 = w_mid_e1.clone();
|
||||
for i in 0..vk.wi_io.len() {
|
||||
let w = &witness_io[&i];
|
||||
let p = &vk.wi_io_e1[i];
|
||||
w_e_e1 = w_e_e1 + p * w;
|
||||
}
|
||||
&h_hiding + &w_e_e1 * delta_v + -&vk.one_e1 * delta_y
|
||||
};
|
||||
|
||||
let alpha_h = h.eval_with_g1_hidings(&crs.ek.alpha_si);
|
||||
|
||||
PinocchioProof {
|
||||
v_mid,
|
||||
v_mid_zk,
|
||||
w_mid_e1,
|
||||
w_mid_e2,
|
||||
y_mid,
|
||||
y_mid_zk,
|
||||
beta_v_mid,
|
||||
beta_w_mid_e1,
|
||||
beta_y_mid,
|
||||
h: h_hiding,
|
||||
adj_h,
|
||||
alpha_h,
|
||||
g_v_v_mid_s,
|
||||
g1_w_w_mid_s,
|
||||
g2_w_w_mid_s,
|
||||
g_y_y_mid_s,
|
||||
g_h_s,
|
||||
g_v_alpha_v_mid_s,
|
||||
g_w_alpha_w_mid_s,
|
||||
g_y_alpha_y_mid_s,
|
||||
g_beta_vwy_mid_s,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -224,10 +164,9 @@ mod tests {
|
||||
(Out, eq.rhs),
|
||||
])
|
||||
};
|
||||
let s = &f.rand_elem(true);
|
||||
let prover = &PinocchioProver::new(f, expr, &witness_map, s);
|
||||
let prover = &PinocchioProver::new(f, expr, &witness_map);
|
||||
let verifier = &PinocchioVerifier::new();
|
||||
let crs = CRS::new(f, prover, s);
|
||||
let crs = CRS::new(f, prover);
|
||||
|
||||
let proof = prover.prove(&crs);
|
||||
let result = verifier.verify(
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
use crate::{
|
||||
building_block::curves::bls12_381::pairing::Pairing,
|
||||
building_block::{
|
||||
curves::bls12_381::{
|
||||
g1_point::G1Point,
|
||||
g2_point::G2Point,
|
||||
pairing::Pairing,
|
||||
},
|
||||
zero::Zero,
|
||||
},
|
||||
zk::w_trusted_setup::pinocchio::{
|
||||
crs::CRS,
|
||||
pinocchio_proof::PinocchioProof,
|
||||
@@ -29,39 +36,51 @@ impl PinocchioVerifier {
|
||||
println!("--> Verifying Pinnochio proof...");
|
||||
let e = |a, b| self.pairing.tate(a, b);
|
||||
|
||||
macro_rules! fail_if_ne { ($a:expr, $b:expr) => { if ($a != $b) { return false; } }}
|
||||
let (p, vk) = (&proof, &crs.vk);
|
||||
|
||||
println!("----> Checking if e(E(αh(s)),E(1)) =? e(E(h(s)),E(α))...");
|
||||
fail_if_ne!(e(&p.alpha_h, &vk.one_e2), e(&p.h, &vk.e_alpha));
|
||||
|
||||
println!("----> Checking if e(E(βv v_mid(s), E(γ)) =? e(v_mid(s),E(βvγ))...");
|
||||
fail_if_ne!(e(&p.beta_v_mid, &vk.e_gamma), e(&p.v_mid, &vk.beta_v_gamma));
|
||||
|
||||
println!("----> Checking if e(E(βw w_mid(s)), E(γ)) =? e(w_mid(s),E(βwγ))...");
|
||||
fail_if_ne!(e(&p.beta_w_mid_e1, &vk.e_gamma), e(&p.w_mid_e1, &vk.beta_w_gamma));
|
||||
|
||||
println!("----> Checking if e(E(βy y_mid(s)), E(γ)) =? e(y_mid(s),E(βyγ))...");
|
||||
fail_if_ne!(e(&p.beta_y_mid, &vk.e_gamma), e(&p.y_mid, &vk.beta_y_gamma));
|
||||
|
||||
macro_rules! add_io_x_wit_to_mid {
|
||||
($io_polys:expr, $mid_zk:expr) => {{
|
||||
let mut sum = $mid_zk.clone();
|
||||
for i in 0..$io_polys.len() {
|
||||
let w = &witness_io[&i];
|
||||
let p = &$io_polys[i];
|
||||
sum = sum + p * w;
|
||||
}
|
||||
sum
|
||||
}};
|
||||
// KC of v * w * y
|
||||
let g_vwd_mid_s = &p.g_v_v_mid_s + &p.g1_w_w_mid_s + &p.g_y_y_mid_s;
|
||||
{
|
||||
let lhs = e(&p.g_beta_vwy_mid_s, &vk.g_gamma);
|
||||
let rhs = e(&g_vwd_mid_s, &vk.g_beta_gamma);
|
||||
if lhs != rhs { return false; }
|
||||
}
|
||||
let v_e = add_io_x_wit_to_mid!(vk.vi_io, p.v_mid_zk);
|
||||
let w_e = add_io_x_wit_to_mid!(vk.wi_io, p.w_mid_e2);
|
||||
let y_e = add_io_x_wit_to_mid!(vk.yi_io, p.y_mid_zk);
|
||||
|
||||
println!("----> Checking if e(v_e, w_e)/e(y_e, E(1)) ?= e(E(h(s)), E(t(s)))...");
|
||||
let lhs = e(&v_e, &w_e) * e(&y_e, &vk.one_e2).inv();
|
||||
let rhs = e(&p.adj_h, &vk.t_e2);
|
||||
// KC of v, w and y
|
||||
{
|
||||
let lhs = e(&p.g_v_alpha_v_mid_s, &vk.one_g2);
|
||||
let rhs = e(&p.g_v_v_mid_s, &vk.g_alpha_v);
|
||||
if lhs != rhs { return false; }
|
||||
}
|
||||
{
|
||||
let lhs = e(&p.g_w_alpha_w_mid_s, &vk.one_g2);
|
||||
let rhs = e(&p.g1_w_w_mid_s, &vk.g2_alpha_w);
|
||||
if lhs != rhs { return false; }
|
||||
}
|
||||
{
|
||||
let lhs = e(&p.g_y_alpha_y_mid_s, &vk.one_g2);
|
||||
let rhs = e(&p.g_y_y_mid_s, &vk.g2_alpha_y);
|
||||
if lhs != rhs { return false; }
|
||||
}
|
||||
|
||||
// QAP divisibility check
|
||||
let mut v_io: G1Point = G1Point::zero();
|
||||
let mut w_io: G2Point = G2Point::zero();
|
||||
let mut y_io: G1Point = G1Point::zero();
|
||||
|
||||
for i in 0..witness_io.size_in_usize() {
|
||||
let w = &witness_io[&i];
|
||||
v_io = v_io + &vk.g_v_v_k_io[i] * w;
|
||||
w_io = w_io + &vk.g_w_w_k_io[i] * w;
|
||||
y_io = y_io + &vk.g_y_y_k_io[i] * w;
|
||||
}
|
||||
|
||||
let v_s = &v_io + &p.g_v_v_mid_s;
|
||||
let w_s = &w_io + &p.g2_w_w_mid_s;
|
||||
let y_s = &y_io + &p.g_y_y_mid_s;
|
||||
|
||||
let lhs = e(&v_s, &w_s) ;
|
||||
let rhs = e(&vk.g_y_t, &p.g_h_s) * e(&y_s, &vk.one_g2);
|
||||
|
||||
lhs == rhs
|
||||
}
|
||||
|
||||
@@ -3,7 +3,10 @@ use crate::building_block::{
|
||||
prime_field::PrimeField,
|
||||
prime_field_elem::PrimeFieldElem,
|
||||
},
|
||||
curves::bls12_381::g1_point::G1Point,
|
||||
curves::bls12_381::{
|
||||
g1_point::G1Point,
|
||||
g2_point::G2Point,
|
||||
},
|
||||
to_biguint::ToBigUint, zero::Zero,
|
||||
};
|
||||
use num_bigint::BigUint;
|
||||
@@ -267,11 +270,23 @@ impl Polynomial {
|
||||
#[allow(non_snake_case)]
|
||||
pub fn eval_with_g1_hidings(
|
||||
&self,
|
||||
g1_powers: &[G1Point],
|
||||
powers: &[G1Point],
|
||||
) -> G1Point {
|
||||
let mut sum = G1Point::zero();
|
||||
for i in 0..self.coeffs.len() {
|
||||
sum = sum + (&g1_powers[i] * &self.coeffs[i]);
|
||||
sum = sum + (&powers[i] * &self.coeffs[i]);
|
||||
}
|
||||
sum
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn eval_with_g2_hidings(
|
||||
&self,
|
||||
powers: &[G2Point],
|
||||
) -> G2Point {
|
||||
let mut sum = G2Point::zero();
|
||||
for i in 0..self.coeffs.len() {
|
||||
sum = sum + (&powers[i] * &self.coeffs[i]);
|
||||
}
|
||||
sum
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user