Skip to content

Commit

Permalink
Merge pull request #12 from levs57/feat/protostar-witness
Browse files Browse the repository at this point in the history
witness generation from circuit run instance
  • Loading branch information
rebenkoy authored Nov 23, 2023
2 parents a607a9e + 7babaad commit 8c856fa
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 7 deletions.
32 changes: 31 additions & 1 deletion src/circuit.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use std::{rc::{Rc, Weak}, marker::PhantomData, iter::repeat_with, cell::RefCell};
use elsa::map::FrozenMap;
use ff::PrimeField;
use itertools::Itertools;

use crate::{witness::CSWtns, gate::{Gatebb, Gate}, constraint_system::{Variable, ConstraintSystem, CommitKind, Visibility, CS, Constraint}, utils::poly_utils::check_poly, circuit::circuit_operations::{AttachedAdvice, AttachedPolynomialAdvice, AttachedAdvicePub}, external_interface::{RunIndex, RunAllocator} };
use crate::{witness::{CSWtns, ProtostarWtns, ProtostarLhsWtns}, gate::{Gatebb, Gate}, constraint_system::{Variable, ConstraintSystem, CommitKind, Visibility, CS, Constraint}, utils::poly_utils::check_poly, circuit::circuit_operations::{AttachedAdvice, AttachedPolynomialAdvice, AttachedAdvicePub}, external_interface::{RunIndex, RunAllocator} };

use self::circuit_operations::CircuitOperation;

Expand Down Expand Up @@ -367,6 +368,35 @@ where
}
}

pub fn end(&self, mut beta: F) -> ProtostarWtns<'constructed, 'circuit, F, G> {
let m = self.constructed.circuit.cs.constr_spec().num_nonlinear_constraints;
let mut p = 1;
let mut protostar_challenges = vec![];
while p <= m {
protostar_challenges.push(beta);
beta = beta * beta;
p = p * 2;
}

let mut pubs = vec![];
let mut round_wtns = vec![];

for round in &self.cs.wtns {
round_wtns.push(round.privs.iter().map(|x| x.unwrap()).collect_vec());
pubs.push(round.pubs.iter().map(|x| x.unwrap()).collect_vec());
}

ProtostarWtns {
lhs: ProtostarLhsWtns {
round_wtns,
pubs,
protostar_challenges,
circuit: self.constructed,
},
error: F::ZERO,
}
}

pub fn set_ext(&mut self, ext: ExternalValue<F>, value: F) -> () {
self.cs.setext(ext, value);
}
Expand Down
10 changes: 6 additions & 4 deletions src/folding/shape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
use ff::PrimeField;
use halo2::halo2curves::CurveAffine;
use itertools::Itertools;
use crate::{utils::arith_helper::{log2_ceil, ev}, constraint_system::{WitnessSpec, ConstraintSystem, CS, ConstrSpec}, gate::Gate};
use crate::{utils::arith_helper::{log2_ceil, ev}, constraint_system::{WitnessSpec, ConstraintSystem, CS, ConstrSpec}, gate::Gate, witness::Module};

/// Encode value as field elements.
pub trait FEncoding <F: PrimeField> {
Expand Down Expand Up @@ -44,20 +44,22 @@ impl<F: PrimeField, C: CurveAffine<ScalarExt = F>> ProtostarLhs<F, C> {

assert_eq!(self.protostar_challenges.len(), log2_ceil(shape.cspec.num_nonlinear_constraints));
}
}

pub fn scale(&mut self, scale: F) {
impl<F: PrimeField, C: CurveAffine<ScalarExt = F>> Module<F> for ProtostarLhs<F, C> {
fn scale(&mut self, scale: F) {
self.round_commitments.iter_mut().map(|x| *x = (*x * scale).into()).count();
self.pubs.iter_mut().map(|rpubs| rpubs.iter_mut().map(|x| *x *= scale).count()).count();
self.protostar_challenges.iter_mut().map(|x| *x *= scale).count();
}

pub fn neg(&mut self) {
fn neg(&mut self) {
self.round_commitments.iter_mut().map(|x| *x = -*x).count();
self.pubs.iter_mut().map(|rpubs| rpubs.iter_mut().map(|x| *x = -*x).count()).count();
self.protostar_challenges.iter_mut().map(|x| *x = -*x).count();
}

pub fn add_assign(&mut self, other: Self) {
fn add_assign(&mut self, other: Self) {
self.round_commitments.iter_mut().zip_eq(other.round_commitments.iter())
.map(|(a, b)| *a = (*a + *b).into()).count();
self.pubs.iter_mut().zip_eq(other.pubs.iter())
Expand Down
97 changes: 95 additions & 2 deletions src/witness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ use std::iter::repeat;
use std::marker::PhantomData;

use ff::PrimeField;
use halo2::halo2curves::CurveAffine;
use halo2::{halo2curves::CurveAffine, arithmetic::best_multiexp};
use itertools::Itertools;

use crate::{gate::Gate, constraint_system::{ConstraintSystem, Variable, CS, Visibility, WitnessSpec}, commitment::{CommitmentKey, CkWtns, CtRound, ErrGroup, CkRelaxed}, circuit::ExternalValue};
use crate::{gate::Gate, constraint_system::{ConstraintSystem, Variable, CS, Visibility, WitnessSpec}, commitment::{CommitmentKey, CkWtns, CtRound, ErrGroup, CkRelaxed}, circuit::{ExternalValue, ConstructedCircuit, PolyOp}, utils::field_precomp::FieldUtils, folding::shape::{ProtostarLhs, ProtostarInstance}};

#[derive(Clone)]
pub struct RoundWtns<F: PrimeField> {
Expand Down Expand Up @@ -138,3 +139,95 @@ impl<'c, F: PrimeField, T: Gate<'c, F>, G:CurveAffine<ScalarExt=F>> CSSystemComm
(ck.0.commit(&self.cs.wtns), ck.1.commit(&self.err))
}
}

pub trait Module<F> {
fn add_assign(&mut self, other: Self) -> ();
fn neg(&mut self) -> ();
fn scale(&mut self, scale: F) -> ();
}

pub struct ProtostarLhsWtns<'constructed, 'circuit, F: PrimeField, G: Gate<'circuit, F> + From<PolyOp<'circuit, F>>> {
pub round_wtns: Vec<Vec<F>>,
pub pubs: Vec<Vec<F>>,
pub protostar_challenges: Vec<F>,
pub circuit: &'constructed ConstructedCircuit<'circuit, F, G>,
}

impl<'constructed, 'circuit, F: PrimeField, G: Gate<'circuit, F> + From<PolyOp<'circuit, F>>> ProtostarLhsWtns<'constructed, 'circuit, F, G> {
pub fn commit<C: CurveAffine<ScalarExt=F>> (&self, commitment_key: Vec<Vec<C>>) -> ProtostarLhs<F, C> {
ProtostarLhs {
round_commitments: self.round_wtns.iter().zip_eq(commitment_key).map(|(wtns, ck)| best_multiexp(&wtns, &ck).into()).collect_vec(),
pubs: self.pubs.clone(),
protostar_challenges: self.protostar_challenges.clone(),
}
}
}

impl<'constructed, 'circuit, F: PrimeField, G: Gate<'circuit, F> + From<PolyOp<'circuit, F>>> Module<F> for ProtostarLhsWtns<'constructed, 'circuit, F, G> {
fn add_assign(&mut self, other: Self) -> () {
self.round_wtns.iter_mut().zip_eq(other.round_wtns.iter()).map(|(s, o)| {
s.iter_mut().zip_eq(o.iter()).map(|(s, o)| *s = *s + o)
}).last();
self.pubs.iter_mut().zip_eq(other.pubs.iter()).map(|(s, o)| {
s.iter_mut().zip_eq(o.iter()).map(|(s, o)| *s = *s + o)
}).last();
self.protostar_challenges.iter_mut().zip_eq(other.protostar_challenges.iter()).map(|(s, o)| {
*s = *s + o
}).last();
}

fn neg(&mut self) -> () {
self.round_wtns.iter_mut().map(|s| {
s.iter_mut().map(|s| *s = -*s)
}).last();
self.pubs.iter_mut().map(|s| {
s.iter_mut().map(|s| *s = -*s)
}).last();
self.protostar_challenges.iter_mut().map(|s| {
*s = -*s
}).last();
}

fn scale(&mut self, scale: F) -> () {
self.round_wtns.iter_mut().map(|s| {
s.iter_mut().map(|s| *s = *s * scale)
}).last();
self.pubs.iter_mut().map(|s| {
s.iter_mut().map(|s| *s = *s * scale)
}).last();
self.protostar_challenges.iter_mut().map(|s| {
*s = *s * scale
}).last();
}
}

pub struct ProtostarWtns<'constructed, 'circuit, F: PrimeField, G: Gate<'circuit, F> + From<PolyOp<'circuit, F>>> {
pub lhs: ProtostarLhsWtns<'constructed, 'circuit, F, G>,
pub error: F
}

impl<'constructed, 'circuit, F: PrimeField, G: Gate<'circuit, F> + From<PolyOp<'circuit, F>>> Module<F> for ProtostarWtns<'constructed, 'circuit, F, G> {
fn add_assign(&mut self, other: Self) -> () {
self.error += other.error;
self.lhs.add_assign(other.lhs);
}

fn neg(&mut self) -> () {
self.error = -self.error;
self.lhs.neg();
}

fn scale(&mut self, scale: F) -> () {
self.error *= scale;
self.lhs.scale(scale);
}
}

impl<'constructed, 'circuit, F: PrimeField, G: Gate<'circuit, F> + From<PolyOp<'circuit, F>>> ProtostarWtns<'constructed, 'circuit, F, G> {
pub fn commit<C: CurveAffine<ScalarExt=F>> (&self, commitment_key: Vec<Vec<C>>) -> ProtostarInstance<F, C> {
ProtostarInstance {
lhs: self.lhs.commit(commitment_key),
error: self.error,
}
}
}

0 comments on commit 8c856fa

Please sign in to comment.