Update examples to use AssignedCell.

This commit is contained in:
therealyingtong 2021-11-27 10:08:01 -05:00
parent 36183bd01a
commit 61c431edc7
5 changed files with 74 additions and 138 deletions

View File

@ -110,7 +110,7 @@ fn bench_with_k(name: &str, k: u32, c: &mut Criterion) {
region.assign_fixed(|| "b", self.config.sb, 0, || Ok(FF::zero()))?;
region.assign_fixed(|| "c", self.config.sc, 0, || Ok(FF::one()))?;
region.assign_fixed(|| "a * b", self.config.sm, 0, || Ok(FF::one()))?;
Ok((lhs, rhs, out))
Ok((lhs.cell(), rhs.cell(), out.cell()))
},
)
}
@ -152,7 +152,7 @@ fn bench_with_k(name: &str, k: u32, c: &mut Criterion) {
region.assign_fixed(|| "b", self.config.sb, 0, || Ok(FF::one()))?;
region.assign_fixed(|| "c", self.config.sc, 0, || Ok(FF::one()))?;
region.assign_fixed(|| "a * b", self.config.sm, 0, || Ok(FF::zero()))?;
Ok((lhs, rhs, out))
Ok((lhs.cell(), rhs.cell(), out.cell()))
},
)
}

View File

@ -104,7 +104,7 @@ impl<FF: FieldExt> StandardCs<FF> for StandardPlonk<FF> {
region.assign_fixed(|| "b", self.config.sb, 0, || Ok(FF::zero()))?;
region.assign_fixed(|| "c", self.config.sc, 0, || Ok(FF::one()))?;
region.assign_fixed(|| "a * b", self.config.sm, 0, || Ok(FF::one()))?;
Ok((lhs, rhs, out))
Ok((lhs.cell(), rhs.cell(), out.cell()))
}
fn raw_add<F>(&self, region: &mut Region<FF>, mut f: F) -> Result<(Cell, Cell, Cell), Error>
where
@ -149,7 +149,7 @@ impl<FF: FieldExt> StandardCs<FF> for StandardPlonk<FF> {
region.assign_fixed(|| "b", self.config.sb, 0, || Ok(FF::one()))?;
region.assign_fixed(|| "c", self.config.sc, 0, || Ok(FF::one()))?;
region.assign_fixed(|| "a * b", self.config.sm, 0, || Ok(FF::zero()))?;
Ok((lhs, rhs, out))
Ok((lhs.cell(), rhs.cell(), out.cell()))
}
fn copy(&self, region: &mut Region<FF>, left: Cell, right: Cell) -> Result<(), Error> {
region.constrain_equal(left, right)

View File

@ -4,7 +4,7 @@ use std::marker::PhantomData;
use halo2::{
arithmetic::FieldExt,
circuit::{Cell, Chip, Layouter, Region, SimpleFloorPlanner},
circuit::{AssignedCell, Chip, Layouter, Region, SimpleFloorPlanner},
plonk::{Advice, Circuit, Column, ConstraintSystem, Error, Fixed, Instance, Selector},
poly::Rotation,
};
@ -149,10 +149,7 @@ impl<F: FieldExt> Chip<F> for FieldChip<F> {
// ANCHOR: instructions-impl
/// A variable representing a number.
#[derive(Clone)]
struct Number<F: FieldExt> {
cell: Cell,
value: Option<F>,
}
struct Number<F: FieldExt>(AssignedCell<F, F>);
impl<F: FieldExt> NumericInstructions<F> for FieldChip<F> {
type Num = Number<F>;
@ -164,21 +161,19 @@ impl<F: FieldExt> NumericInstructions<F> for FieldChip<F> {
) -> Result<Self::Num, Error> {
let config = self.config();
let mut num = None;
layouter.assign_region(
|| "load private",
|mut region| {
let cell = region.assign_advice(
|| "private input",
config.advice[0],
0,
|| value.ok_or(Error::Synthesis),
)?;
num = Some(Number { cell, value });
Ok(())
region
.assign_advice(
|| "private input",
config.advice[0],
0,
|| value.ok_or(Error::Synthesis),
)
.map(Number)
},
)?;
Ok(num.unwrap())
)
}
fn load_constant(
@ -188,24 +183,14 @@ impl<F: FieldExt> NumericInstructions<F> for FieldChip<F> {
) -> Result<Self::Num, Error> {
let config = self.config();
let mut num = None;
layouter.assign_region(
|| "load constant",
|mut region| {
let cell = region.assign_advice_from_constant(
|| "constant value",
config.advice[0],
0,
constant,
)?;
num = Some(Number {
cell,
value: Some(constant),
});
Ok(())
region
.assign_advice_from_constant(|| "constant value", config.advice[0], 0, constant)
.map(Number)
},
)?;
Ok(num.unwrap())
)
}
fn mul(
@ -216,7 +201,6 @@ impl<F: FieldExt> NumericInstructions<F> for FieldChip<F> {
) -> Result<Self::Num, Error> {
let config = self.config();
let mut out = None;
layouter.assign_region(
|| "mul",
|mut region: Region<'_, F>| {
@ -229,38 +213,24 @@ impl<F: FieldExt> NumericInstructions<F> for FieldChip<F> {
// but we can only rely on relative offsets inside this region. So we
// assign new cells inside the region and constrain them to have the
// same values as the inputs.
let lhs = region.assign_advice(
|| "lhs",
config.advice[0],
0,
|| a.value.ok_or(Error::Synthesis),
)?;
let rhs = region.assign_advice(
|| "rhs",
config.advice[1],
0,
|| b.value.ok_or(Error::Synthesis),
)?;
region.constrain_equal(a.cell, lhs)?;
region.constrain_equal(b.cell, rhs)?;
a.0.copy_advice(|| "lhs", &mut region, config.advice[0], 0)?;
b.0.copy_advice(|| "rhs", &mut region, config.advice[1], 0)?;
// Now we can assign the multiplication result into the output position.
let value = a.value.and_then(|a| b.value.map(|b| a * b));
let cell = region.assign_advice(
|| "lhs * rhs",
config.advice[0],
1,
|| value.ok_or(Error::Synthesis),
)?;
let value = a.0.value().and_then(|a| b.0.value().map(|b| a * b));
// Finally, we return a variable representing the output,
// to be used in another part of the circuit.
out = Some(Number { cell, value });
Ok(())
region
.assign_advice(
|| "lhs * rhs",
config.advice[0],
1,
|| value.ok_or(Error::Synthesis),
)
.map(Number)
},
)?;
Ok(out.unwrap())
)
}
fn expose_public(
@ -271,7 +241,7 @@ impl<F: FieldExt> NumericInstructions<F> for FieldChip<F> {
) -> Result<(), Error> {
let config = self.config();
layouter.constrain_instance(num.cell, config.instance, row)
layouter.constrain_instance(num.0.cell(), config.instance, row)
}
}
// ANCHOR_END: instructions-impl

View File

@ -4,7 +4,7 @@ use std::marker::PhantomData;
use halo2::{
arithmetic::FieldExt,
circuit::{Cell, Chip, Layouter, Region, SimpleFloorPlanner},
circuit::{AssignedCell, Chip, Layouter, Region, SimpleFloorPlanner},
plonk::{Advice, Circuit, Column, ConstraintSystem, Error, Instance, Selector},
poly::Rotation,
};
@ -12,10 +12,7 @@ use halo2::{
// ANCHOR: field-instructions
/// A variable representing a number.
#[derive(Clone)]
struct Number<F: FieldExt> {
cell: Cell,
value: Option<F>,
}
struct Number<F: FieldExt>(AssignedCell<F, F>);
trait FieldInstructions<F: FieldExt>: AddInstructions<F> + MulInstructions<F> {
/// Variable representing a number.
@ -205,11 +202,10 @@ impl<F: FieldExt> AddInstructions<F> for AddChip<F> {
) -> Result<Self::Num, Error> {
let config = self.config();
let mut out = None;
layouter.assign_region(
|| "add",
|mut region: Region<'_, F>| {
// We only want to use a single multiplication gate in this region,
// We only want to use a single addition gate in this region,
// so we enable it at region offset 0; this means it will constrain
// cells at offsets 0 and 1.
config.s_add.enable(&mut region, 0)?;
@ -218,38 +214,24 @@ impl<F: FieldExt> AddInstructions<F> for AddChip<F> {
// but we can only rely on relative offsets inside this region. So we
// assign new cells inside the region and constrain them to have the
// same values as the inputs.
let lhs = region.assign_advice(
|| "lhs",
config.advice[0],
0,
|| a.value.ok_or(Error::Synthesis),
)?;
let rhs = region.assign_advice(
|| "rhs",
config.advice[1],
0,
|| b.value.ok_or(Error::Synthesis),
)?;
region.constrain_equal(a.cell, lhs)?;
region.constrain_equal(b.cell, rhs)?;
a.0.copy_advice(|| "lhs", &mut region, config.advice[0], 0)?;
b.0.copy_advice(|| "rhs", &mut region, config.advice[1], 0)?;
// Now we can assign the multiplication result into the output position.
let value = a.value.and_then(|a| b.value.map(|b| a + b));
let cell = region.assign_advice(
|| "lhs * rhs",
config.advice[0],
1,
|| value.ok_or(Error::Synthesis),
)?;
// Now we can assign the addition result into the output position.
let value = a.0.value().and_then(|a| b.0.value().map(|b| a + b));
// Finally, we return a variable representing the output,
// to be used in another part of the circuit.
out = Some(Number { cell, value });
Ok(())
region
.assign_advice(
|| "lhs + rhs",
config.advice[0],
1,
|| value.ok_or(Error::Synthesis),
)
.map(Number)
},
)?;
Ok(out.unwrap())
)
}
}
// ANCHOR END: add-instructions-impl
@ -345,7 +327,6 @@ impl<F: FieldExt> MulInstructions<F> for MulChip<F> {
) -> Result<Self::Num, Error> {
let config = self.config();
let mut out = None;
layouter.assign_region(
|| "mul",
|mut region: Region<'_, F>| {
@ -358,38 +339,24 @@ impl<F: FieldExt> MulInstructions<F> for MulChip<F> {
// but we can only rely on relative offsets inside this region. So we
// assign new cells inside the region and constrain them to have the
// same values as the inputs.
let lhs = region.assign_advice(
|| "lhs",
config.advice[0],
0,
|| a.value.ok_or(Error::Synthesis),
)?;
let rhs = region.assign_advice(
|| "rhs",
config.advice[1],
0,
|| b.value.ok_or(Error::Synthesis),
)?;
region.constrain_equal(a.cell, lhs)?;
region.constrain_equal(b.cell, rhs)?;
a.0.copy_advice(|| "lhs", &mut region, config.advice[0], 0)?;
b.0.copy_advice(|| "rhs", &mut region, config.advice[1], 0)?;
// Now we can assign the multiplication result into the output position.
let value = a.value.and_then(|a| b.value.map(|b| a * b));
let cell = region.assign_advice(
|| "lhs * rhs",
config.advice[0],
1,
|| value.ok_or(Error::Synthesis),
)?;
let value = a.0.value().and_then(|a| b.0.value().map(|b| a * b));
// Finally, we return a variable representing the output,
// to be used in another part of the circuit.
out = Some(Number { cell, value });
Ok(())
region
.assign_advice(
|| "lhs * rhs",
config.advice[0],
1,
|| value.ok_or(Error::Synthesis),
)
.map(Number)
},
)?;
Ok(out.unwrap())
)
}
}
// ANCHOR END: mul-instructions-impl
@ -449,21 +416,19 @@ impl<F: FieldExt> FieldInstructions<F> for FieldChip<F> {
) -> Result<<Self as FieldInstructions<F>>::Num, Error> {
let config = self.config();
let mut num = None;
layouter.assign_region(
|| "load private",
|mut region| {
let cell = region.assign_advice(
|| "private input",
config.advice[0],
0,
|| value.ok_or(Error::Synthesis),
)?;
num = Some(Number { cell, value });
Ok(())
region
.assign_advice(
|| "private input",
config.advice[0],
0,
|| value.ok_or(Error::Synthesis),
)
.map(Number)
},
)?;
Ok(num.unwrap())
)
}
/// Returns `d = (a + b) * c`.
@ -486,7 +451,7 @@ impl<F: FieldExt> FieldInstructions<F> for FieldChip<F> {
) -> Result<(), Error> {
let config = self.config();
layouter.constrain_instance(num.cell, config.instance, row)
layouter.constrain_instance(num.0.cell(), config.instance, row)
}
}
// ANCHOR_END: field-instructions-impl

View File

@ -41,6 +41,7 @@ fn plonk_api() {
sl: TableColumn,
}
#[allow(clippy::type_complexity)]
trait StandardCs<FF: FieldExt> {
fn raw_multiply<F>(
&self,
@ -138,7 +139,7 @@ fn plonk_api() {
region.assign_fixed(|| "b", self.config.sb, 0, || Ok(FF::zero()))?;
region.assign_fixed(|| "c", self.config.sc, 0, || Ok(FF::one()))?;
region.assign_fixed(|| "a * b", self.config.sm, 0, || Ok(FF::one()))?;
Ok((lhs, rhs, out))
Ok((lhs.cell(), rhs.cell(), out.cell()))
},
)
}
@ -192,7 +193,7 @@ fn plonk_api() {
region.assign_fixed(|| "b", self.config.sb, 0, || Ok(FF::one()))?;
region.assign_fixed(|| "c", self.config.sc, 0, || Ok(FF::one()))?;
region.assign_fixed(|| "a * b", self.config.sm, 0, || Ok(FF::zero()))?;
Ok((lhs, rhs, out))
Ok((lhs.cell(), rhs.cell(), out.cell()))
},
)
}
@ -220,7 +221,7 @@ fn plonk_api() {
let value = region.assign_advice(|| "value", self.config.a, 0, || f())?;
region.assign_fixed(|| "public", self.config.sp, 0, || Ok(FF::one()))?;
Ok(value)
Ok(value.cell())
},
)
}