From 2d49523f04b4c3e17b64ffd4222d12925af7e790 Mon Sep 17 00:00:00 2001 From: ashWhiteHat Date: Tue, 24 Oct 2023 12:54:31 +0900 Subject: [PATCH] modify relaxed r1cs --- src/constraint_system.rs | 30 +++++++++++++++--------------- src/nifs.rs | 8 ++++---- src/proof.rs | 11 ++++------- src/prover.rs | 16 ++++++++-------- src/r1cs.rs | 24 ++++++++++++------------ src/r1cs/blueprint.rs | 33 ++++++++++++++++++--------------- src/r1cs/witness.rs | 35 ++++++++++++++++++----------------- src/relaxed_r1cs.rs | 34 +++++++++++++++++++++------------- src/relaxed_r1cs/instance.rs | 26 ++++++++++++++++++++------ src/relaxed_r1cs/witness.rs | 28 ++++++++++++---------------- src/tests.rs | 8 +++++--- 11 files changed, 137 insertions(+), 116 deletions(-) diff --git a/src/constraint_system.rs b/src/constraint_system.rs index 9ca74a9..782267b 100644 --- a/src/constraint_system.rs +++ b/src/constraint_system.rs @@ -2,14 +2,14 @@ use crate::matrix::Element; use crate::r1cs::R1csInstance; use crate::wire::Wire; -use zkstd::common::PrimeField; +use zkstd::common::{Ring, TwistedEdwardsAffine}; #[derive(Debug)] -pub struct ConstraintSystem { - r1cs: R1csInstance, +pub struct ConstraintSystem { + r1cs: R1csInstance, } -impl ConstraintSystem { +impl ConstraintSystem { /// init constraint system with first instance one pub fn new() -> Self { Self { @@ -18,14 +18,14 @@ impl ConstraintSystem { } /// assign instance value to constraint system - pub fn public_wire(&mut self, instance: F) -> Wire { + pub fn public_wire(&mut self, instance: C::Scalar) -> Wire { let index = self.r1cs.witness.public_len(); self.r1cs.witness.append_instance(instance); Wire::instance(index) } /// assign witness value to constraint system - pub fn private_wire(&mut self, witness: F) -> Wire { + pub fn private_wire(&mut self, witness: C::Scalar) -> Wire { let index = self.r1cs.witness.private_len(); self.r1cs.witness.append_witness(witness); Wire::witness(index) @@ -34,7 +34,7 @@ impl ConstraintSystem { /// constrain a + b == c pub fn add_constraint(&mut self, a: Wire, b: Wire, c: Wire) { self.r1cs.r1cs.append_a(a); - self.enable_constraint(b, F::one(), c) + self.enable_constraint(b, C::Scalar::one(), c) } /// constrain a * b == c @@ -44,15 +44,15 @@ impl ConstraintSystem { /// constrain a == b pub fn equal_constraint(&mut self, a: Wire, b: Wire) { - self.enable_constraint(a, F::one(), b) + self.enable_constraint(a, C::Scalar::one(), b) } /// add constraint internally fn enable_constraint( &mut self, - a: impl Into>, - b: impl Into>, - c: impl Into>, + a: impl Into>, + b: impl Into>, + c: impl Into>, ) { self.r1cs.r1cs.append(a, b, c); self.r1cs.r1cs.increment() @@ -68,14 +68,14 @@ impl ConstraintSystem { mod tests { use super::ConstraintSystem; - use jub_jub::Fr as Scalar; + use jub_jub::{Fr as Scalar, JubjubAffine as Curve}; use zkstd::common::PrimeField; #[test] fn equal_constraint_test() { let x = Scalar::one().double(); - let mut cs = ConstraintSystem::::new(); + let mut cs = ConstraintSystem::::new(); let (a, b) = (cs.public_wire(x), cs.public_wire(x)); cs.equal_constraint(a, b); @@ -88,7 +88,7 @@ mod tests { let y = Scalar::one().double().double(); let z = x * y; - let mut cs = ConstraintSystem::::new(); + let mut cs = ConstraintSystem::::new(); let (a, b, c) = (cs.public_wire(x), cs.public_wire(y), cs.public_wire(z)); cs.mul_constraint(a, b, c); @@ -106,7 +106,7 @@ mod tests { let five = Scalar::from(5); let output = Scalar::from(35); - let mut cs = ConstraintSystem::::new(); + let mut cs = ConstraintSystem::::new(); let (a, b, e, f) = ( cs.public_wire(x), cs.public_wire(y), diff --git a/src/nifs.rs b/src/nifs.rs index 48c8206..5887f61 100644 --- a/src/nifs.rs +++ b/src/nifs.rs @@ -2,20 +2,20 @@ use crate::prover::Prover; use crate::public_param::PedersenCommitment; use crate::r1cs::R1csStructure; -use zkstd::common::{CurveAffine, PrimeField, RngCore}; +use zkstd::common::{PrimeField, RngCore, TwistedEdwardsAffine}; -struct Nifs { +struct Nifs { pp: PedersenCommitment, } -impl Nifs { +impl Nifs { pub(crate) fn g(λ: u64, r: impl RngCore) -> PedersenCommitment { PedersenCommitment::new(λ, r) } pub(crate) fn k( pp: PedersenCommitment, - r1cs: R1csStructure, + r1cs: R1csStructure, ) -> (Prover, VerificationKey) { let digest = pp.digest(); (Prover { pp, f: r1cs, i: 0 }, VerificationKey { digest }) diff --git a/src/proof.rs b/src/proof.rs index f5c8470..e5a43fc 100644 --- a/src/proof.rs +++ b/src/proof.rs @@ -1,12 +1,9 @@ use crate::r1cs::{Instance as R1csInstance, Witness as R1csWitness}; use crate::relaxed_r1cs::{Instance as RelaxedR1csInstance, Witness as RelaxedR1csWitness}; -use zkstd::common::CurveAffine; +use zkstd::common::TwistedEdwardsAffine; -pub(crate) struct IvcProof { - pub(crate) upper_pair: ( - RelaxedR1csInstance, - RelaxedR1csWitness, - ), - pub(crate) lower_pair: (R1csInstance, R1csWitness), +pub(crate) struct IvcProof { + pub(crate) upper_pair: (RelaxedR1csInstance, RelaxedR1csWitness), + pub(crate) lower_pair: (R1csInstance, R1csWitness), } diff --git a/src/prover.rs b/src/prover.rs index da20b9b..fd0e177 100644 --- a/src/prover.rs +++ b/src/prover.rs @@ -2,16 +2,16 @@ use crate::proof::IvcProof; use crate::public_param::PedersenCommitment; use crate::r1cs::R1csStructure; -use zkstd::common::CurveAffine; +use zkstd::common::TwistedEdwardsAffine; -pub(crate) struct Prover { +pub(crate) struct Prover { pub(crate) pp: PedersenCommitment, - pub(crate) f: R1csStructure, + pub(crate) f: R1csStructure, pub(crate) i: usize, } -impl Prover { - pub(crate) fn new(pp: PedersenCommitment, f: R1csStructure) -> Self { +impl Prover { + pub(crate) fn new(pp: PedersenCommitment, f: R1csStructure) -> Self { Self { pp, f, i: 0 } } @@ -28,14 +28,14 @@ impl Prover { #[cfg(test)] mod tests { - use crate::relaxed_r1cs::{Instance as RelaxedR1csInstance, Witness as RelaxedR1csWitness}; + use crate::relaxed_r1cs::Witness as RelaxedR1csWitness; use crate::tests::example_r1cs; - use jub_jub::Fr as Scalar; + use jub_jub::JubjubAffine as Curve; #[test] fn folding_test() { - let r1cs = example_r1cs::(); + let r1cs = example_r1cs::(); let w0 = RelaxedR1csWitness::init(r1cs); } } diff --git a/src/r1cs.rs b/src/r1cs.rs index 5f61161..e7bb24e 100644 --- a/src/r1cs.rs +++ b/src/r1cs.rs @@ -10,17 +10,17 @@ use crate::matrix::Element; use crate::relaxed_r1cs::RelaxedR1csInstance; use crate::wire::Wire; -use zkstd::common::PrimeField; +use zkstd::common::{Group, TwistedEdwardsAffine}; #[derive(Debug, Default)] -pub struct R1csInstance { - pub(crate) r1cs: R1csStructure, - pub(crate) instance: Instance, - pub(crate) witness: Witness, +pub struct R1csInstance { + pub(crate) r1cs: R1csStructure, + pub(crate) instance: Instance, + pub(crate) witness: Witness, } -impl R1csInstance { - pub(crate) fn new(r1cs: &R1csStructure, witness: &Vec) -> Self { +impl R1csInstance { + pub(crate) fn new(r1cs: &R1csStructure, witness: &Vec) -> Self { let (instance, witness) = r1cs.instance_and_witness(witness); let r1cs = r1cs.clone(); Self { @@ -30,7 +30,7 @@ impl R1csInstance { } } - pub(crate) fn relax(&self) -> RelaxedR1csInstance { + pub(crate) fn relax(&self) -> RelaxedR1csInstance { let relaxed_r1cs = self.r1cs.relax(); let (witness, instance) = self.witness.relax(self.r1cs.m); RelaxedR1csInstance { @@ -52,8 +52,8 @@ impl R1csInstance { } // dot product for each gate - fn dot_product(&self, elements: &Vec>) -> F { - elements.iter().fold(F::zero(), |sum, element| { + fn dot_product(&self, elements: &Vec>) -> C::Scalar { + elements.iter().fold(C::Scalar::zero(), |sum, element| { let (wire, value) = (element.0, element.1); let coeff = match wire { Wire::Witness(index) => self.witness.w[index], @@ -70,11 +70,11 @@ mod tests { use super::{R1csInstance, R1csStructure}; use crate::tests::{example_r1cs, example_r1cs_witness}; - use jub_jub::Fr as Scalar; + use jub_jub::JubjubAffine as Curve; #[test] fn r1cs_instance_test() { - let r1cs: R1csStructure = example_r1cs(); + let r1cs: R1csStructure = example_r1cs(); for i in 0..100 { let z = example_r1cs_witness(i); let r1cs_instance = R1csInstance::new(&r1cs, &z); diff --git a/src/r1cs/blueprint.rs b/src/r1cs/blueprint.rs index 3893474..f6fb091 100644 --- a/src/r1cs/blueprint.rs +++ b/src/r1cs/blueprint.rs @@ -1,7 +1,7 @@ use crate::matrix::{DenseVectors, Element, SparseMatrix}; use crate::relaxed_r1cs::RelaxedR1csStructure; -use zkstd::common::PrimeField; +use zkstd::common::{Ring, TwistedEdwardsAffine}; pub(crate) use super::instance::Instance; pub(crate) use super::witness::Witness; @@ -11,17 +11,17 @@ use super::R1csInstance; /// 4.1 Definition 10 R1CS /// (A · Z) ◦ (B · Z) = C · Z #[derive(Clone, Debug)] -pub struct R1csStructure { +pub struct R1csStructure { /// matrix length pub(crate) m: usize, /// instance length pub(crate) l: usize, - pub(crate) a: SparseMatrix, - pub(crate) b: SparseMatrix, - pub(crate) c: SparseMatrix, + pub(crate) a: SparseMatrix, + pub(crate) b: SparseMatrix, + pub(crate) c: SparseMatrix, } -impl Default for R1csStructure { +impl Default for R1csStructure { fn default() -> Self { Self { m: 0, @@ -33,19 +33,19 @@ impl Default for R1csStructure { } } -impl R1csStructure { +impl R1csStructure { pub(crate) fn append( &mut self, - a: impl Into>, - b: impl Into>, - c: impl Into>, + a: impl Into>, + b: impl Into>, + c: impl Into>, ) { self.a[self.m].push(a.into()); self.b[self.m].push(b.into()); self.c[self.m].push(c.into()); } - pub(crate) fn append_a(&mut self, a: impl Into>) { + pub(crate) fn append_a(&mut self, a: impl Into>) { self.a[self.m].push(a.into()) } @@ -56,7 +56,7 @@ impl R1csStructure { self.m += 1 } - pub(crate) fn instantiate(&self, z: &Vec) -> R1csInstance { + pub(crate) fn instantiate(&self, z: &Vec) -> R1csInstance { let (instance, witness) = self.instance_and_witness(z); R1csInstance { r1cs: self.clone(), @@ -65,14 +65,17 @@ impl R1csStructure { } } - pub(crate) fn instance_and_witness(&self, witnesses: &Vec) -> (Instance, Witness) { + pub(crate) fn instance_and_witness( + &self, + witnesses: &Vec, + ) -> (Instance, Witness) { let w = DenseVectors(witnesses[self.l..].to_vec()); let x = DenseVectors(witnesses[..self.l].to_vec()); - let one = F::one(); + let one = C::Scalar::one(); (Instance { x: x.clone() }, Witness { w, x, one }) } - pub(crate) fn relax(&self) -> RelaxedR1csStructure { + pub(crate) fn relax(&self) -> RelaxedR1csStructure { let Self { m, l, a, b, c } = self.clone(); RelaxedR1csStructure { m, l, a, b, c } } diff --git a/src/r1cs/witness.rs b/src/r1cs/witness.rs index 22d6e6f..ddd6d6c 100644 --- a/src/r1cs/witness.rs +++ b/src/r1cs/witness.rs @@ -1,31 +1,31 @@ use crate::matrix::DenseVectors; use crate::relaxed_r1cs::{Instance as RelaxedR1csInstance, Witness as RelaxedR1csWitness}; -use zkstd::common::PrimeField; +use zkstd::common::{Group, Ring, TwistedEdwardsAffine}; /// witness for r1cs (W, x, 1) #[derive(Clone, Debug)] -pub struct Witness { +pub struct Witness { /// intermediate value and private inputs - pub(crate) w: DenseVectors, + pub(crate) w: DenseVectors, /// public inputs and outputs - pub(crate) x: DenseVectors, + pub(crate) x: DenseVectors, /// first public input element one - pub(crate) one: F, + pub(crate) one: C::Scalar, } -impl Default for Witness { +impl Default for Witness { fn default() -> Self { Self { w: DenseVectors(vec![]), x: DenseVectors(vec![]), - one: F::one(), + one: C::Scalar::one(), } } } -impl Witness { - pub(crate) fn get(&self) -> (DenseVectors, DenseVectors) { +impl Witness { + pub(crate) fn get(&self) -> (DenseVectors, DenseVectors) { (self.x.clone(), self.w.clone()) } @@ -37,26 +37,27 @@ impl Witness { self.w.0.len() } - pub(crate) fn append_instance(&mut self, instance: F) { + pub(crate) fn append_instance(&mut self, instance: C::Scalar) { self.x.0.push(instance) } - pub(crate) fn append_witness(&mut self, witness: F) { + pub(crate) fn append_witness(&mut self, witness: C::Scalar) { self.w.0.push(witness) } - pub(crate) fn relax(&self, m: usize) -> (RelaxedR1csWitness, RelaxedR1csInstance) { + pub(crate) fn relax(&self, m: usize) -> (RelaxedR1csWitness, RelaxedR1csInstance) { let Self { w, x, one: _ } = self; - let e = DenseVectors(vec![F::zero(); m]); - let u = F::one(); - let x = x.clone(); ( RelaxedR1csWitness { w: w.clone(), + e: DenseVectors(vec![C::Scalar::zero(); m]), + }, + RelaxedR1csInstance { + commit_w: C::ADDITIVE_IDENTITY, + commit_e: C::ADDITIVE_IDENTITY, + u: C::Scalar::one(), x: x.clone(), - u, }, - RelaxedR1csInstance { e, u, x }, ) } } diff --git a/src/relaxed_r1cs.rs b/src/relaxed_r1cs.rs index 8bdb144..1f1423e 100644 --- a/src/relaxed_r1cs.rs +++ b/src/relaxed_r1cs.rs @@ -6,12 +6,12 @@ pub(crate) use blueprint::RelaxedR1csStructure; pub(crate) use instance::Instance; pub(crate) use witness::Witness; -use zkstd::common::PrimeField; +use zkstd::common::TwistedEdwardsAffine; -pub(crate) struct RelaxedR1csInstance { - pub(crate) relaxed_r1cs: RelaxedR1csStructure, - pub(crate) instance: Instance, - pub(crate) witness: Witness, +pub(crate) struct RelaxedR1csInstance { + pub(crate) relaxed_r1cs: RelaxedR1csStructure, + pub(crate) instance: Instance, + pub(crate) witness: Witness, } #[cfg(test)] @@ -19,11 +19,19 @@ use crate::matrix::Element; #[cfg(test)] use crate::wire::Wire; #[cfg(test)] -impl RelaxedR1csInstance { +use zkstd::common::Group; +#[cfg(test)] +impl RelaxedR1csInstance { /// check (A · Z) ◦ (B · Z) = u · (C · Z) + E pub(crate) fn is_sat(&self) -> bool { let RelaxedR1csStructure { m, l: _, a, b, c } = self.relaxed_r1cs.clone(); - let Instance { e, u, x: _ } = self.instance.clone(); + let Witness { w: _, e } = self.witness.clone(); + let Instance { + commit_e: _, + commit_w: _, + u, + x: _, + } = self.instance.clone(); (0..m).all(|i| { let a_prod = self.dot_product(&a[i]); let b_prod = self.dot_product(&b[i]); @@ -35,13 +43,13 @@ impl RelaxedR1csInstance { } // dot product for each gate - fn dot_product(&self, elements: &Vec>) -> F { - elements.iter().fold(F::zero(), |sum, element| { + fn dot_product(&self, elements: &Vec>) -> C::Scalar { + elements.iter().fold(C::Scalar::zero(), |sum, element| { let (wire, value) = element.get(); let coeff = match wire { Wire::Witness(index) => self.witness.w[index], - Wire::Instance(index) => self.witness.x[index], - Wire::One => self.witness.u, + Wire::Instance(index) => self.instance.x[index], + Wire::One => self.instance.u, }; sum + coeff * value }) @@ -52,12 +60,12 @@ impl RelaxedR1csInstance { mod tests { use crate::tests::example_relaxed_r1cs_instance; - use jub_jub::Fr as Scalar; + use jub_jub::JubjubAffine as Curve; #[test] fn relaxed_r1cs_instance_test() { for i in 0..100 { - let relaxed_r1cs_instance = example_relaxed_r1cs_instance::(i); + let relaxed_r1cs_instance = example_relaxed_r1cs_instance::(i); assert!(relaxed_r1cs_instance.is_sat()) } } diff --git a/src/relaxed_r1cs/instance.rs b/src/relaxed_r1cs/instance.rs index 6ce35f0..d9edcd6 100644 --- a/src/relaxed_r1cs/instance.rs +++ b/src/relaxed_r1cs/instance.rs @@ -1,14 +1,28 @@ use crate::matrix::DenseVectors; +use crate::r1cs::R1csStructure; -use zkstd::common::PrimeField; +use zkstd::common::{Group, Ring, TwistedEdwardsAffine}; /// instance for relaxed r1cs (E, u, x) #[derive(Clone, Debug)] -pub struct Instance { - /// error vectors - pub(crate) e: DenseVectors, +pub struct Instance { + /// commitment for witness vectors + pub(crate) commit_w: C, + /// commitment for error vectors + pub(crate) commit_e: C, /// scalar - pub(crate) u: F, + pub(crate) u: C::Scalar, /// public inputs and outputs - pub(crate) x: DenseVectors, + pub(crate) x: DenseVectors, +} + +impl Instance { + pub(crate) fn init(r1cs: R1csStructure) -> Self { + Self { + commit_w: C::ADDITIVE_IDENTITY, + commit_e: C::ADDITIVE_IDENTITY, + u: C::Scalar::one(), + x: DenseVectors(vec![C::Scalar::zero(); r1cs.l]), + } + } } diff --git a/src/relaxed_r1cs/witness.rs b/src/relaxed_r1cs/witness.rs index 9b394ba..ea40d2d 100644 --- a/src/relaxed_r1cs/witness.rs +++ b/src/relaxed_r1cs/witness.rs @@ -1,29 +1,25 @@ use crate::matrix::DenseVectors; use crate::r1cs::R1csStructure; -use zkstd::common::PrimeField; +use zkstd::common::{Group, TwistedEdwardsAffine}; -/// witness for relaxed r1cs Z = (W, x, u) #[derive(Clone, Debug)] -pub struct Witness { - /// intermediate value and private inputs - pub(crate) w: DenseVectors, - /// public inputs and outputs - pub(crate) x: DenseVectors, - /// scalar - pub(crate) u: F, +pub struct Witness { + /// witness + pub(crate) w: DenseVectors, + /// error vectors + pub(crate) e: DenseVectors, } -impl Witness { - pub(crate) fn get(&self) -> (DenseVectors, DenseVectors) { - (self.x.clone(), self.w.clone()) +impl Witness { + pub(crate) fn get(&self) -> (DenseVectors, DenseVectors) { + (self.e.clone(), self.w.clone()) } - pub(crate) fn init(r1cs: R1csStructure) -> Self { + pub(crate) fn init(r1cs: R1csStructure) -> Self { Self { - w: DenseVectors(vec![F::zero(); r1cs.m - r1cs.l]), - x: DenseVectors(vec![F::zero(); r1cs.l]), - u: F::one(), + w: DenseVectors(vec![C::Scalar::zero(); r1cs.m - r1cs.l]), + e: DenseVectors(vec![C::Scalar::zero(); r1cs.l]), } } } diff --git a/src/tests.rs b/src/tests.rs index ef1014b..741d0c0 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -3,7 +3,7 @@ use crate::r1cs::{R1csInstance, R1csStructure}; use crate::relaxed_r1cs::RelaxedR1csInstance; use crate::wire::Wire; -use zkstd::common::PrimeField; +use zkstd::common::{PrimeField, TwistedEdwardsAffine}; pub(crate) fn array_to_witnessess(witnesses: Vec) -> Vec { witnesses @@ -40,7 +40,7 @@ pub(crate) fn dense_to_sparse(value: Vec>, l: usize) -> /// R1CS for: x^3 + x + 5 = y /// https://www.vitalik.ca/general/2016/12/10/qap.html -pub(crate) fn example_r1cs() -> R1csStructure { +pub(crate) fn example_r1cs() -> R1csStructure { let m = 4; let l = 1; let a = dense_to_sparse( @@ -84,7 +84,9 @@ pub(crate) fn example_r1cs_witness(input: u64) -> Vec { ]) } -pub(crate) fn example_relaxed_r1cs_instance(input: u64) -> RelaxedR1csInstance { +pub(crate) fn example_relaxed_r1cs_instance( + input: u64, +) -> RelaxedR1csInstance { let r1cs = example_r1cs(); let z = example_r1cs_witness(input); let r1cs_instance = R1csInstance::new(&r1cs, &z);