mirror of
https://github.com/saymrwulf/pasta_curves-source.git
synced 2026-09-03 19:53:40 +00:00
Allow commitments to generic advice wire polynomials
This commit is contained in:
parent
c16141be9a
commit
7edffe0197
5 changed files with 191 additions and 17 deletions
74
src/plonk.rs
74
src/plonk.rs
|
|
@ -42,15 +42,21 @@ pub struct SRS<C: CurveAffine> {
|
|||
sd_commitment: C,
|
||||
sm_commitment: C,
|
||||
domain: EvaluationDomain<C::Scalar>,
|
||||
|
||||
fixed_commitments: Vec<C>,
|
||||
fixed_polys: Vec<(Vec<C::Scalar>, Vec<C::Scalar>)>,
|
||||
meta: MetaCircuit,
|
||||
}
|
||||
|
||||
/// This is an object which represents a (Turbo)PLONK proof.
|
||||
// This structure must never allow points at infinity.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Proof<C: CurveAffine> {
|
||||
a_commitment: C,
|
||||
b_commitment: C,
|
||||
c_commitment: C,
|
||||
d_commitment: C,
|
||||
advice_commitments: Vec<C>,
|
||||
h_commitments: Vec<C>,
|
||||
a_eval_x: C::Scalar,
|
||||
b_eval_x: C::Scalar,
|
||||
|
|
@ -77,6 +83,8 @@ pub enum Error {
|
|||
IncompatibleParams,
|
||||
/// The constraint system is not satisfied.
|
||||
ConstraintSystemFailure,
|
||||
/// Out of bounds index passed to a backend
|
||||
BoundsFailure,
|
||||
}
|
||||
|
||||
fn hash_point<C: CurveAffine, H: Hasher<C::Base>>(
|
||||
|
|
@ -103,7 +111,16 @@ fn test_proving() {
|
|||
// Initialize the polynomial commitment parameters
|
||||
let params: Params<EqAffine> = Params::new::<DummyHash<Fq>>(K);
|
||||
|
||||
struct MyConfig {}
|
||||
struct MyConfig {
|
||||
a: Wire,
|
||||
b: Wire,
|
||||
c: Wire,
|
||||
|
||||
sa: Wire,
|
||||
sb: Wire,
|
||||
sc: Wire,
|
||||
sm: Wire,
|
||||
}
|
||||
struct MyCircuit<F: Field> {
|
||||
a: Option<F>,
|
||||
}
|
||||
|
|
@ -112,7 +129,24 @@ fn test_proving() {
|
|||
type Config = MyConfig;
|
||||
|
||||
fn configure(meta: &mut MetaCircuit) -> MyConfig {
|
||||
MyConfig {}
|
||||
let a = meta.advice_wire();
|
||||
let b = meta.advice_wire();
|
||||
let c = meta.advice_wire();
|
||||
|
||||
let sa = meta.fixed_wire();
|
||||
let sb = meta.fixed_wire();
|
||||
let sc = meta.fixed_wire();
|
||||
let sm = meta.fixed_wire();
|
||||
|
||||
MyConfig {
|
||||
a,
|
||||
b,
|
||||
c,
|
||||
sa,
|
||||
sb,
|
||||
sc,
|
||||
sm,
|
||||
}
|
||||
}
|
||||
|
||||
fn synthesize(
|
||||
|
|
@ -137,6 +171,42 @@ fn test_proving() {
|
|||
//cs.copy(c, e);
|
||||
}
|
||||
|
||||
// Similar to the above...
|
||||
let mut row = 0;
|
||||
for _ in 0..10 {
|
||||
cs.assign(Variable(config.a, row), || {
|
||||
self.a.ok_or(Error::SynthesisError)
|
||||
})?;
|
||||
cs.assign(Variable(config.b, row), || {
|
||||
self.a.ok_or(Error::SynthesisError)
|
||||
})?;
|
||||
let a_squared = self.a.map(|a| a.square());
|
||||
cs.assign(Variable(config.c, row), || {
|
||||
self.a.ok_or(Error::SynthesisError)
|
||||
})?;
|
||||
// Multiplication gate
|
||||
cs.assign(Variable(config.sa, row), || Ok(Field::zero()))?;
|
||||
cs.assign(Variable(config.sb, row), || Ok(Field::zero()))?;
|
||||
cs.assign(Variable(config.sc, row), || Ok(Field::one()))?;
|
||||
cs.assign(Variable(config.sm, row), || Ok(Field::one()))?;
|
||||
row += 1;
|
||||
|
||||
cs.assign(Variable(config.a, row), || {
|
||||
self.a.ok_or(Error::SynthesisError)
|
||||
})?;
|
||||
cs.assign(Variable(config.b, row), || {
|
||||
a_squared.ok_or(Error::SynthesisError)
|
||||
})?;
|
||||
let fin = a_squared.and_then(|a_squared| self.a.map(|a| a + a_squared));
|
||||
cs.assign(Variable(config.c, row), || fin.ok_or(Error::SynthesisError))?;
|
||||
// Addition gate
|
||||
cs.assign(Variable(config.sa, row), || Ok(Field::one()))?;
|
||||
cs.assign(Variable(config.sb, row), || Ok(Field::one()))?;
|
||||
cs.assign(Variable(config.sc, row), || Ok(Field::one()))?;
|
||||
cs.assign(Variable(config.sm, row), || Ok(Field::zero()))?;
|
||||
row += 1;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use crate::arithmetic::Field;
|
|||
|
||||
/// This represents a PLONK wire, which could be a fixed (selector) wire or an
|
||||
/// advice wire.
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum Wire {
|
||||
/// A wires
|
||||
A,
|
||||
|
|
@ -16,15 +16,23 @@ pub enum Wire {
|
|||
C,
|
||||
/// D wires
|
||||
D,
|
||||
/// Fixed wires
|
||||
Fixed(usize),
|
||||
/// Advice wires
|
||||
Advice(usize),
|
||||
}
|
||||
|
||||
/// Represents a pointer to a value in the constraint system.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Variable(pub(crate) Wire, pub(crate) usize);
|
||||
pub struct Variable(pub Wire, pub usize);
|
||||
|
||||
/// This trait allows a [`Circuit`] to direct some backend to assign a witness
|
||||
/// for a constraint system.
|
||||
pub trait ConstraintSystem<F: Field> {
|
||||
/// Assign a wire value
|
||||
fn assign(&mut self, var: Variable, to: impl FnOnce() -> Result<F, Error>)
|
||||
-> Result<(), Error>;
|
||||
|
||||
/// Creates a gate.
|
||||
fn create_gate(
|
||||
&mut self,
|
||||
|
|
@ -131,8 +139,8 @@ impl<F> Mul<F> for Polynomial<F> {
|
|||
/// permutation arrangements.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MetaCircuit {
|
||||
// num_fixed_wires: usize,
|
||||
// num_advice_wires: usize,
|
||||
pub(crate) num_fixed_wires: usize,
|
||||
pub(crate) num_advice_wires: usize,
|
||||
// permutations: Vec<Vec<Wire>>,
|
||||
// gates: Vec<Polynomial>,
|
||||
// queries: HashSet<(Wire, usize)>,
|
||||
|
|
@ -141,6 +149,24 @@ pub struct MetaCircuit {
|
|||
|
||||
impl Default for MetaCircuit {
|
||||
fn default() -> MetaCircuit {
|
||||
MetaCircuit {}
|
||||
MetaCircuit {
|
||||
num_fixed_wires: 0,
|
||||
num_advice_wires: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MetaCircuit {
|
||||
/// Allocate a new fixed wire
|
||||
pub fn fixed_wire(&mut self) -> Wire {
|
||||
let tmp = Wire::Fixed(self.num_fixed_wires);
|
||||
self.num_fixed_wires += 1;
|
||||
tmp
|
||||
}
|
||||
/// Allocate a new advice wire
|
||||
pub fn advice_wire(&mut self) -> Wire {
|
||||
let tmp = Wire::Advice(self.num_advice_wires);
|
||||
self.num_advice_wires += 1;
|
||||
tmp
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use super::{
|
||||
circuit::{Circuit, ConstraintSystem, MetaCircuit, Wire, Variable},
|
||||
circuit::{Circuit, ConstraintSystem, MetaCircuit, Variable, Wire},
|
||||
hash_point, Error, Proof, SRS,
|
||||
};
|
||||
use crate::arithmetic::{
|
||||
|
|
@ -31,9 +31,29 @@ impl<C: CurveAffine> Proof<C> {
|
|||
sc: Vec<F>,
|
||||
sd: Vec<F>,
|
||||
sm: Vec<F>,
|
||||
advice: Vec<Vec<F>>,
|
||||
}
|
||||
|
||||
impl<F: Field> ConstraintSystem<F> for WitnessCollection<F> {
|
||||
fn assign(
|
||||
&mut self,
|
||||
var: Variable,
|
||||
to: impl FnOnce() -> Result<F, Error>,
|
||||
) -> Result<(), Error> {
|
||||
// We only care about advice wires here.
|
||||
match var.0 {
|
||||
Wire::Advice(index) => {
|
||||
*self
|
||||
.advice
|
||||
.get_mut(index)
|
||||
.and_then(|v| v.get_mut(var.1))
|
||||
.ok_or(Error::BoundsFailure)? = to()?;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn create_gate(
|
||||
&mut self,
|
||||
sa: F,
|
||||
|
|
@ -66,6 +86,9 @@ impl<C: CurveAffine> Proof<C> {
|
|||
// }
|
||||
}
|
||||
|
||||
let mut meta = MetaCircuit::default();
|
||||
let config = ConcreteCircuit::configure(&mut meta);
|
||||
|
||||
let mut witness = WitnessCollection {
|
||||
a: vec![],
|
||||
b: vec![],
|
||||
|
|
@ -76,12 +99,9 @@ impl<C: CurveAffine> Proof<C> {
|
|||
sc: vec![],
|
||||
sd: vec![],
|
||||
sm: vec![],
|
||||
advice: vec![vec![C::Scalar::zero(); params.n as usize]; meta.num_advice_wires],
|
||||
};
|
||||
|
||||
let mut meta = MetaCircuit::default();
|
||||
|
||||
let config = ConcreteCircuit::configure(&mut meta);
|
||||
|
||||
// Synthesize the circuit to obtain the witness and other information.
|
||||
circuit.synthesize(&mut witness, config)?;
|
||||
|
||||
|
|
@ -115,10 +135,21 @@ impl<C: CurveAffine> Proof<C> {
|
|||
let c_commitment = params.commit_lagrange(&witness.c, c_blind).to_affine();
|
||||
let d_commitment = params.commit_lagrange(&witness.d, d_blind).to_affine();
|
||||
|
||||
let advice_blinds = vec![C::Scalar::one(); witness.advice.len()]; // TODO: not random
|
||||
let advice_commitments = witness
|
||||
.advice
|
||||
.iter()
|
||||
.zip(advice_blinds.iter())
|
||||
.map(|(poly, blind)| params.commit_lagrange(poly, *blind).to_affine())
|
||||
.collect();
|
||||
|
||||
hash_point(&mut transcript, &a_commitment)?;
|
||||
hash_point(&mut transcript, &b_commitment)?;
|
||||
hash_point(&mut transcript, &c_commitment)?;
|
||||
hash_point(&mut transcript, &d_commitment)?;
|
||||
for commitment in &advice_commitments {
|
||||
hash_point(&mut transcript, commitment)?;
|
||||
}
|
||||
|
||||
let domain = &srs.domain;
|
||||
|
||||
|
|
@ -127,6 +158,12 @@ impl<C: CurveAffine> Proof<C> {
|
|||
let (c_coset, c_poly) = domain.obtain_coset(witness.c);
|
||||
let (d_coset, d_poly) = domain.obtain_coset(witness.d);
|
||||
|
||||
let advice_polys: Vec<_> = witness
|
||||
.advice
|
||||
.into_iter()
|
||||
.map(|poly| domain.obtain_coset(poly))
|
||||
.collect();
|
||||
|
||||
// (a * sa) + (b * sb) + (a * sm * b) + (d * sd) - (c * sc)
|
||||
let mut h_poly = Vec::with_capacity(a_coset.len());
|
||||
for ((((((((a, b), c), d), sa), sb), sc), sd), sm) in a_coset
|
||||
|
|
@ -253,6 +290,7 @@ impl<C: CurveAffine> Proof<C> {
|
|||
b_commitment,
|
||||
c_commitment,
|
||||
d_commitment,
|
||||
advice_commitments,
|
||||
h_commitments,
|
||||
a_eval_x,
|
||||
b_eval_x,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use super::{
|
||||
circuit::{Circuit, ConstraintSystem, MetaCircuit, Wire, Variable},
|
||||
circuit::{Circuit, ConstraintSystem, MetaCircuit, Variable, Wire},
|
||||
domain::EvaluationDomain,
|
||||
Error, GATE_DEGREE, SRS,
|
||||
};
|
||||
|
|
@ -19,9 +19,28 @@ impl<C: CurveAffine> SRS<C> {
|
|||
sc: Vec<F>,
|
||||
sd: Vec<F>,
|
||||
sm: Vec<F>,
|
||||
fixed: Vec<Vec<F>>,
|
||||
}
|
||||
|
||||
impl<F: Field> ConstraintSystem<F> for Assembly<F> {
|
||||
fn assign(
|
||||
&mut self,
|
||||
var: Variable,
|
||||
to: impl FnOnce() -> Result<F, Error>,
|
||||
) -> Result<(), Error> {
|
||||
// We only care about fixed wires here.
|
||||
match var.0 {
|
||||
Wire::Fixed(index) => {
|
||||
*self
|
||||
.fixed
|
||||
.get_mut(index)
|
||||
.and_then(|v| v.get_mut(var.1))
|
||||
.ok_or(Error::BoundsFailure)? = to()?;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
fn create_gate(
|
||||
&mut self,
|
||||
sa: F,
|
||||
|
|
@ -46,18 +65,18 @@ impl<C: CurveAffine> SRS<C> {
|
|||
}
|
||||
}
|
||||
|
||||
let mut meta = MetaCircuit::default();
|
||||
let config = ConcreteCircuit::configure(&mut meta);
|
||||
|
||||
let mut assembly: Assembly<C::Scalar> = Assembly {
|
||||
sa: vec![],
|
||||
sb: vec![],
|
||||
sc: vec![],
|
||||
sd: vec![],
|
||||
sm: vec![],
|
||||
fixed: vec![vec![C::Scalar::zero(); params.n as usize]; meta.num_fixed_wires],
|
||||
};
|
||||
|
||||
let mut meta = MetaCircuit::default();
|
||||
|
||||
let config = ConcreteCircuit::configure(&mut meta);
|
||||
|
||||
// Synthesize the circuit to obtain SRS
|
||||
circuit.synthesize(&mut assembly, config)?;
|
||||
|
||||
|
|
@ -84,6 +103,12 @@ impl<C: CurveAffine> SRS<C> {
|
|||
.commit_lagrange(&assembly.sm, C::Scalar::one())
|
||||
.to_affine();
|
||||
|
||||
let fixed_commitments = assembly
|
||||
.fixed
|
||||
.iter()
|
||||
.map(|poly| params.commit_lagrange(poly, C::Scalar::one()).to_affine())
|
||||
.collect();
|
||||
|
||||
let domain = EvaluationDomain::new(GATE_DEGREE, params.k);
|
||||
|
||||
let sa = domain.obtain_coset(assembly.sa);
|
||||
|
|
@ -92,6 +117,12 @@ impl<C: CurveAffine> SRS<C> {
|
|||
let sd = domain.obtain_coset(assembly.sd);
|
||||
let sm = domain.obtain_coset(assembly.sm);
|
||||
|
||||
let fixed_polys = assembly
|
||||
.fixed
|
||||
.into_iter()
|
||||
.map(|poly| domain.obtain_coset(poly))
|
||||
.collect();
|
||||
|
||||
Ok(SRS {
|
||||
sa,
|
||||
sb,
|
||||
|
|
@ -104,6 +135,10 @@ impl<C: CurveAffine> SRS<C> {
|
|||
sd_commitment,
|
||||
sm_commitment,
|
||||
domain,
|
||||
|
||||
fixed_commitments,
|
||||
fixed_polys,
|
||||
meta,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,11 @@ impl<C: CurveAffine> Proof<C> {
|
|||
hash_point(&mut transcript, &self.d_commitment)
|
||||
.expect("proof cannot contain points at infinity");
|
||||
|
||||
for commitment in &self.advice_commitments {
|
||||
hash_point(&mut transcript, commitment)
|
||||
.expect("proof cannot contain points at infinity");
|
||||
}
|
||||
|
||||
for c in &self.h_commitments {
|
||||
hash_point(&mut transcript, c).expect("proof cannot contain points at infinity");
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue