mirror of
https://github.com/saymrwulf/pasta_curves-source.git
synced 2026-09-06 20:20:34 +00:00
Sample of abstraction for writing PLONK circuits
This commit is contained in:
parent
9852913a32
commit
378c56b952
1 changed files with 124 additions and 29 deletions
153
src/plonk.rs
153
src/plonk.rs
|
|
@ -84,12 +84,13 @@ fn test_proving() {
|
||||||
use crate::arithmetic::{EqAffine, Field, Fp, Fq};
|
use crate::arithmetic::{EqAffine, Field, Fp, Fq};
|
||||||
use crate::polycommit::Params;
|
use crate::polycommit::Params;
|
||||||
use crate::transcript::DummyHash;
|
use crate::transcript::DummyHash;
|
||||||
|
use std::marker::PhantomData;
|
||||||
const K: u32 = 5;
|
const K: u32 = 5;
|
||||||
|
|
||||||
// Initialize the polynomial commitment parameters
|
// Initialize the polynomial commitment parameters
|
||||||
let params: Params<EqAffine> = Params::new::<DummyHash<Fq>>(K);
|
let params: Params<EqAffine> = Params::new::<DummyHash<Fq>>(K);
|
||||||
|
|
||||||
struct MyConfig {
|
struct PLONKConfig {
|
||||||
a: AdviceWire,
|
a: AdviceWire,
|
||||||
b: AdviceWire,
|
b: AdviceWire,
|
||||||
c: AdviceWire,
|
c: AdviceWire,
|
||||||
|
|
@ -99,14 +100,112 @@ fn test_proving() {
|
||||||
sc: FixedWire,
|
sc: FixedWire,
|
||||||
sm: FixedWire,
|
sm: FixedWire,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
struct Variable(AdviceWire, usize);
|
||||||
|
|
||||||
|
trait StandardCS<FF: Field> {
|
||||||
|
fn raw_multiply<F>(&mut self, f: F) -> Result<(Variable, Variable, Variable), Error>
|
||||||
|
where
|
||||||
|
F: FnOnce() -> Result<(FF, FF, FF), Error>;
|
||||||
|
fn raw_add<F>(&mut self, f: F) -> Result<(Variable, Variable, Variable), Error>
|
||||||
|
where
|
||||||
|
F: FnOnce() -> Result<(FF, FF, FF), Error>;
|
||||||
|
}
|
||||||
|
|
||||||
struct MyCircuit<F: Field> {
|
struct MyCircuit<F: Field> {
|
||||||
a: Option<F>,
|
a: Option<F>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: Field> Circuit<F> for MyCircuit<F> {
|
struct StandardPLONK<'a, F: Field, CS: ConstraintSystem<F> + 'a> {
|
||||||
type Config = MyConfig;
|
cs: &'a mut CS,
|
||||||
|
config: PLONKConfig,
|
||||||
|
current_gate: usize,
|
||||||
|
_marker: PhantomData<F>,
|
||||||
|
}
|
||||||
|
|
||||||
fn configure(meta: &mut MetaCircuit<F>) -> MyConfig {
|
impl<'a, FF: Field, CS: ConstraintSystem<FF>> StandardPLONK<'a, FF, CS> {
|
||||||
|
fn new(cs: &'a mut CS, config: PLONKConfig) -> Self {
|
||||||
|
StandardPLONK {
|
||||||
|
cs,
|
||||||
|
config,
|
||||||
|
current_gate: 0,
|
||||||
|
_marker: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, FF: Field, CS: ConstraintSystem<FF>> StandardCS<FF> for StandardPLONK<'a, FF, CS> {
|
||||||
|
fn raw_multiply<F>(&mut self, f: F) -> Result<(Variable, Variable, Variable), Error>
|
||||||
|
where
|
||||||
|
F: FnOnce() -> Result<(FF, FF, FF), Error>,
|
||||||
|
{
|
||||||
|
let index = self.current_gate;
|
||||||
|
self.current_gate += 1;
|
||||||
|
let mut value = None;
|
||||||
|
self.cs.assign_advice(self.config.a, index, || {
|
||||||
|
value = Some(f()?);
|
||||||
|
Ok(value.ok_or(Error::SynthesisError)?.0)
|
||||||
|
})?;
|
||||||
|
self.cs.assign_advice(self.config.b, index, || {
|
||||||
|
Ok(value.ok_or(Error::SynthesisError)?.1)
|
||||||
|
})?;
|
||||||
|
self.cs.assign_advice(self.config.c, index, || {
|
||||||
|
Ok(value.ok_or(Error::SynthesisError)?.2)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
self.cs
|
||||||
|
.assign_fixed(self.config.sa, index, || Ok(FF::zero()))?;
|
||||||
|
self.cs
|
||||||
|
.assign_fixed(self.config.sb, index, || Ok(FF::zero()))?;
|
||||||
|
self.cs
|
||||||
|
.assign_fixed(self.config.sc, index, || Ok(FF::one()))?;
|
||||||
|
self.cs
|
||||||
|
.assign_fixed(self.config.sm, index, || Ok(FF::one()))?;
|
||||||
|
Ok((
|
||||||
|
Variable(self.config.a, index),
|
||||||
|
Variable(self.config.b, index),
|
||||||
|
Variable(self.config.c, index),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
fn raw_add<F>(&mut self, f: F) -> Result<(Variable, Variable, Variable), Error>
|
||||||
|
where
|
||||||
|
F: FnOnce() -> Result<(FF, FF, FF), Error>,
|
||||||
|
{
|
||||||
|
let index = self.current_gate;
|
||||||
|
self.current_gate += 1;
|
||||||
|
let mut value = None;
|
||||||
|
self.cs.assign_advice(self.config.a, index, || {
|
||||||
|
value = Some(f()?);
|
||||||
|
Ok(value.ok_or(Error::SynthesisError)?.0)
|
||||||
|
})?;
|
||||||
|
self.cs.assign_advice(self.config.b, index, || {
|
||||||
|
Ok(value.ok_or(Error::SynthesisError)?.1)
|
||||||
|
})?;
|
||||||
|
self.cs.assign_advice(self.config.c, index, || {
|
||||||
|
Ok(value.ok_or(Error::SynthesisError)?.2)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
self.cs
|
||||||
|
.assign_fixed(self.config.sa, index, || Ok(FF::one()))?;
|
||||||
|
self.cs
|
||||||
|
.assign_fixed(self.config.sb, index, || Ok(FF::one()))?;
|
||||||
|
self.cs
|
||||||
|
.assign_fixed(self.config.sc, index, || Ok(FF::one()))?;
|
||||||
|
self.cs
|
||||||
|
.assign_fixed(self.config.sm, index, || Ok(FF::zero()))?;
|
||||||
|
Ok((
|
||||||
|
Variable(self.config.a, index),
|
||||||
|
Variable(self.config.b, index),
|
||||||
|
Variable(self.config.c, index),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F: Field> Circuit<F> for MyCircuit<F> {
|
||||||
|
type Config = PLONKConfig;
|
||||||
|
|
||||||
|
fn configure(meta: &mut MetaCircuit<F>) -> PLONKConfig {
|
||||||
let a = meta.advice_wire();
|
let a = meta.advice_wire();
|
||||||
let b = meta.advice_wire();
|
let b = meta.advice_wire();
|
||||||
let c = meta.advice_wire();
|
let c = meta.advice_wire();
|
||||||
|
|
@ -129,7 +228,7 @@ fn test_proving() {
|
||||||
a.clone() * sa + b.clone() * sb + a * b * sm + (c * sc * (-F::one()))
|
a.clone() * sa + b.clone() * sb + a * b * sm + (c * sc * (-F::one()))
|
||||||
});
|
});
|
||||||
|
|
||||||
MyConfig {
|
PLONKConfig {
|
||||||
a,
|
a,
|
||||||
b,
|
b,
|
||||||
c,
|
c,
|
||||||
|
|
@ -143,32 +242,28 @@ fn test_proving() {
|
||||||
fn synthesize(
|
fn synthesize(
|
||||||
&self,
|
&self,
|
||||||
cs: &mut impl ConstraintSystem<F>,
|
cs: &mut impl ConstraintSystem<F>,
|
||||||
config: MyConfig,
|
config: PLONKConfig,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
// Similar to the above...
|
let mut cs = StandardPLONK::new(cs, config);
|
||||||
let mut row = 0;
|
|
||||||
for _ in 0..10 {
|
|
||||||
cs.assign_advice(config.a, row, || self.a.ok_or(Error::SynthesisError))?;
|
|
||||||
cs.assign_advice(config.b, row, || self.a.ok_or(Error::SynthesisError))?;
|
|
||||||
let a_squared = self.a.map(|a| a.square());
|
|
||||||
cs.assign_advice(config.c, row, || a_squared.ok_or(Error::SynthesisError))?;
|
|
||||||
// Multiplication gate
|
|
||||||
cs.assign_fixed(config.sa, row, || Ok(Field::zero()))?;
|
|
||||||
cs.assign_fixed(config.sb, row, || Ok(Field::zero()))?;
|
|
||||||
cs.assign_fixed(config.sc, row, || Ok(Field::one()))?;
|
|
||||||
cs.assign_fixed(config.sm, row, || Ok(Field::one()))?;
|
|
||||||
row += 1;
|
|
||||||
|
|
||||||
cs.assign_advice(config.a, row, || self.a.ok_or(Error::SynthesisError))?;
|
for _ in 0..10 {
|
||||||
cs.assign_advice(config.b, row, || a_squared.ok_or(Error::SynthesisError))?;
|
let mut a_squared = None;
|
||||||
let fin = a_squared.and_then(|a_squared| self.a.map(|a| a + a_squared));
|
let (_, _, _) = cs.raw_multiply(|| {
|
||||||
cs.assign_advice(config.c, row, || fin.ok_or(Error::SynthesisError))?;
|
a_squared = self.a.map(|a| a.square());
|
||||||
// Addition gate
|
Ok((
|
||||||
cs.assign_fixed(config.sa, row, || Ok(Field::one()))?;
|
self.a.ok_or(Error::SynthesisError)?,
|
||||||
cs.assign_fixed(config.sb, row, || Ok(Field::one()))?;
|
self.a.ok_or(Error::SynthesisError)?,
|
||||||
cs.assign_fixed(config.sc, row, || Ok(Field::one()))?;
|
a_squared.ok_or(Error::SynthesisError)?,
|
||||||
cs.assign_fixed(config.sm, row, || Ok(Field::zero()))?;
|
))
|
||||||
row += 1;
|
})?;
|
||||||
|
let (_, _, _) = cs.raw_add(|| {
|
||||||
|
let fin = a_squared.and_then(|a2| self.a.map(|a| a + a2));
|
||||||
|
Ok((
|
||||||
|
self.a.ok_or(Error::SynthesisError)?,
|
||||||
|
a_squared.ok_or(Error::SynthesisError)?,
|
||||||
|
fin.ok_or(Error::SynthesisError)?,
|
||||||
|
))
|
||||||
|
})?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue