mirror of https://github.com/zcash/halo2.git
Update examples to use AssignedCell.
This commit is contained in:
parent
36183bd01a
commit
61c431edc7
|
@ -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()))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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())
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue