Merge pull request #30 from zcash/blinded-accumulator

Faux blinded accumulator
This commit is contained in:
ebfull 2020-09-28 08:30:51 -06:00 committed by GitHub
commit 865160ca88
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 85 additions and 79 deletions

View File

@ -375,7 +375,7 @@ fn test_proving() {
pubinputs[0] = Fp::one();
pubinputs[0] += Fp::one();
let pubinput = params
.commit_lagrange(&pubinputs, Blind(Field::zero()))
.commit_lagrange(&pubinputs, Blind::default())
.to_affine();
for _ in 0..100 {

View File

@ -96,7 +96,7 @@ impl<C: CurveAffine> Proof<C> {
// Compute commitments to aux wire polynomials
let aux_commitments_projective: Vec<_> = aux
.iter()
.map(|poly| params.commit_lagrange(poly, Blind(C::Scalar::zero()))) // TODO: bad blind?
.map(|poly| params.commit_lagrange(poly, Blind::default()))
.collect();
let mut aux_commitments = vec![C::zero(); aux_commitments_projective.len()];
C::Projective::batch_to_affine(&aux_commitments_projective, &mut aux_commitments);
@ -501,7 +501,7 @@ impl<C: CurveAffine> Proof<C> {
accumulate(
point_index,
&aux_polys[wire.0],
Blind(C::Scalar::zero()),
Blind::default(),
aux_evals[query_index],
);
}

View File

@ -4,15 +4,15 @@
//! [halo]: https://eprint.iacr.org/2019/1021
use super::{Coeff, LagrangeCoeff, Polynomial};
use crate::arithmetic::{
best_fft, best_multiexp, parallelize, Challenge, Curve, CurveAffine, Field,
};
use crate::arithmetic::{best_fft, best_multiexp, parallelize, Curve, CurveAffine, Field};
use crate::transcript::Hasher;
use std::ops::{Add, AddAssign, Mul, MulAssign};
mod prover;
mod verifier;
pub use verifier::{Accumulator, Guard};
/// This is a proof object for the polynomial commitment scheme opening.
#[derive(Debug, Clone)]
pub struct Proof<C: CurveAffine> {
@ -22,17 +22,6 @@ pub struct Proof<C: CurveAffine> {
z2: C::Scalar,
}
/// An accumulator instance consisting of an evaluation claim and a proof.
#[derive(Debug, Clone)]
pub struct Accumulator<C: CurveAffine> {
/// The claimed output of the linear-time polycommit opening protocol
pub g: C,
/// A vector of 128-bit challenges sampled by the verifier, to be used in
/// computing g.
pub challenges_sq_packed: Vec<Challenge>,
}
/// A multiscalar multiplication in the polynomial commitment scheme
#[derive(Debug, Clone)]
pub struct MSM<'a, C: CurveAffine> {
@ -281,46 +270,6 @@ impl<C: CurveAffine> Params<C> {
}
}
/// A guard returned by the verifier
#[derive(Debug, Clone)]
pub struct Guard<'a, C: CurveAffine> {
msm: MSM<'a, C>,
neg_z1: C::Scalar,
allinv: C::Scalar,
challenges_sq: Vec<C::Scalar>,
challenges_sq_packed: Vec<Challenge>,
}
impl<'a, C: CurveAffine> Guard<'a, C> {
/// Lets caller supply the challenges and obtain an MSM with updated
/// scalars and points.
pub fn use_challenges(mut self) -> MSM<'a, C> {
let s = compute_s(&self.challenges_sq, self.allinv * &self.neg_z1);
self.msm.add_to_g(&s);
self.msm
}
/// Lets caller supply the purported G point and simply appends it to
/// return an updated MSM.
pub fn use_g(mut self, g: C) -> (MSM<'a, C>, Accumulator<C>) {
self.msm.add_term(self.neg_z1, g);
let accumulator = Accumulator {
g,
challenges_sq_packed: self.challenges_sq_packed,
};
(self.msm, accumulator)
}
/// Computes the g value when given a potential scalar as input.
pub fn compute_g(&self) -> C {
let s = compute_s(&self.challenges_sq, self.allinv);
best_multiexp(&s, &self.msm.params.g).to_affine()
}
}
/// Wrapper type around a blinding factor.
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub struct Blind<F>(pub F);
@ -494,20 +443,3 @@ fn test_opening_proof() {
}
}
}
// TODO: parallelize
fn compute_s<F: Field>(challenges_sq: &[F], allinv: F) -> Vec<F> {
let lg_n = challenges_sq.len();
let n = 1 << lg_n;
let mut s = Vec::with_capacity(n);
s.push(allinv);
for i in 1..n {
let lg_i = (32 - 1 - (i as u32).leading_zeros()) as usize;
let k = 1 << lg_i;
let u_lg_i_sq = challenges_sq[(lg_n - 1) - lg_i];
s.push(s[i - k] * u_lg_i_sq);
}
s
}

View File

@ -1,8 +1,65 @@
use super::super::Error;
use super::{Guard, Params, Proof, MSM};
use super::{Params, Proof, MSM};
use crate::transcript::Hasher;
use crate::arithmetic::{get_challenge_scalar, Challenge, CurveAffine, Field};
use crate::arithmetic::{
best_multiexp, get_challenge_scalar, Challenge, Curve, CurveAffine, Field,
};
/// A guard returned by the verifier
#[derive(Debug, Clone)]
pub struct Guard<'a, C: CurveAffine> {
msm: MSM<'a, C>,
neg_z1: C::Scalar,
allinv: C::Scalar,
challenges_sq: Vec<C::Scalar>,
challenges_sq_packed: Vec<Challenge>,
}
/// An accumulator instance consisting of an evaluation claim and a proof.
#[derive(Debug, Clone)]
pub struct Accumulator<C: CurveAffine> {
/// The claimed output of the linear-time polycommit opening protocol
pub g: C,
/// A vector of 128-bit challenges sampled by the verifier, to be used in
/// computing g.
pub challenges_sq_packed: Vec<Challenge>,
}
impl<'a, C: CurveAffine> Guard<'a, C> {
/// Lets caller supply the challenges and obtain an MSM with updated
/// scalars and points.
pub fn use_challenges(mut self) -> MSM<'a, C> {
let s = compute_s(&self.challenges_sq, self.allinv * &self.neg_z1);
self.msm.add_to_g(&s);
self.msm.add_to_h(self.neg_z1);
self.msm
}
/// Lets caller supply the purported G point and simply appends it to
/// return an updated MSM.
pub fn use_g(mut self, g: C) -> (MSM<'a, C>, Accumulator<C>) {
self.msm.add_term(self.neg_z1, g);
let accumulator = Accumulator {
g,
challenges_sq_packed: self.challenges_sq_packed,
};
(self.msm, accumulator)
}
/// Computes the g value when given a potential scalar as input.
pub fn compute_g(&self) -> C {
let s = compute_s(&self.challenges_sq, self.allinv);
let mut tmp = best_multiexp(&s, &self.msm.params.g);
tmp += self.msm.params.h;
tmp.to_affine()
}
}
impl<C: CurveAffine> Proof<C> {
/// Checks to see if an [`Proof`] is valid given the current `transcript`,
@ -106,7 +163,7 @@ impl<C: CurveAffine> Proof<C> {
let c: C::Scalar = get_challenge_scalar(Challenge(c_packed));
// Check
// [c] P + [c * v] U + [c] sum(L_i * u_i^2) + [c] sum(R_i * u_i^-2) + delta - [z1] G - [z1 * b] U - [z2] H
// [c] P + [c * v] U + [c] sum(L_i * u_i^2) + [c] sum(R_i * u_i^-2) + delta - [z1] G - [z1 * b] U - [z1 - z2] H
// = 0
let b = compute_b(x, &challenges, &challenges_inv);
@ -131,8 +188,8 @@ impl<C: CurveAffine> Proof<C> {
// delta
msm.add_term(Field::one(), self.delta);
// - [z2] H
msm.add_to_h(-self.z2);
// - [z1 - z2] H
msm.add_to_h(self.z1 - &self.z2);
let guard = Guard {
msm,
@ -160,3 +217,20 @@ fn compute_b<F: Field>(x: F, challenges: &[F], challenges_inv: &[F]) -> F {
)
}
}
// TODO: parallelize
fn compute_s<F: Field>(challenges_sq: &[F], allinv: F) -> Vec<F> {
let lg_n = challenges_sq.len();
let n = 1 << lg_n;
let mut s = Vec::with_capacity(n);
s.push(allinv);
for i in 1..n {
let lg_i = (32 - 1 - (i as u32).leading_zeros()) as usize;
let k = 1 << lg_i;
let u_lg_i_sq = challenges_sq[(lg_n - 1) - lg_i];
s.push(s[i - k] * u_lg_i_sq);
}
s
}