Merge pull request #178 from zcash/simple-example-comments

Reflow simple-example.rs comments
This commit is contained in:
str4d 2021-02-13 05:09:15 +13:00 committed by GitHub
commit 13ac4e7573
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 39 additions and 37 deletions

View File

@ -34,21 +34,22 @@ trait NumericInstructions: Chip {
// ANCHOR_END: instructions
// ANCHOR: chip
/// The chip that will implement our instructions! Chips do not store any persistent state
/// themselves, and usually only contain type markers if necessary.
/// The chip that will implement our instructions! Chips do not store any persistent
/// state themselves, and usually only contain type markers if necessary.
struct FieldChip<F: FieldExt> {
_marker: PhantomData<F>,
}
// ANCHOR_END: chip
// ANCHOR: chip-config
/// Chip state is stored in a separate config struct. This is generated by the chip during
/// configuration, and then handed to the `Layouter`, which makes it available to the chip
/// when it needs to implement its instructions.
/// Chip state is stored in a separate config struct. This is generated by the chip
/// during configuration, and then handed to the `Layouter`, which makes it available
/// to the chip when it needs to implement its instructions.
#[derive(Clone, Debug)]
struct FieldConfig {
/// For this chip, we will use two advice columns to implement our instructions. These
/// are also the columns through which we communicate with other parts of the circuit.
/// For this chip, we will use two advice columns to implement our instructions.
/// These are also the columns through which we communicate with other parts of
/// the circuit.
advice: [Column<Advice>; 2],
// We need to create a permutation between our advice columns. This allows us to
@ -86,18 +87,18 @@ impl<F: FieldExt> FieldChip<F> {
// | lhs | rhs | s_mul |
// | out | | |
//
// Gates may refer to any relative offsets we want, but each distinct offset
// adds a cost to the proof. The most common offsets are 0 (the current row),
// 1 (the next row), and -1 (the previous row), for which `Rotation` has
// specific constructors.
// Gates may refer to any relative offsets we want, but each distinct
// offset adds a cost to the proof. The most common offsets are 0 (the
// current row), 1 (the next row), and -1 (the previous row), for which
// `Rotation` has specific constructors.
let lhs = meta.query_advice(advice[0], Rotation::cur());
let rhs = meta.query_advice(advice[1], Rotation::cur());
let out = meta.query_advice(advice[0], Rotation::next());
let s_mul = meta.query_fixed(s_mul, Rotation::cur());
// The polynomial expression returned from `create_gate` will be constrained
// by the proving system to equal zero. Our expression has the following
// properties:
// The polynomial expression returned from `create_gate` will be
// constrained by the proving system to equal zero. Our expression
// has the following properties:
// - When s_mul = 0, any value is allowed in lhs, rhs, and out.
// - When s_mul != 0, this constrains lhs * rhs = out.
s_mul * (lhs * rhs + out * -F::one())
@ -105,14 +106,14 @@ impl<F: FieldExt> FieldChip<F> {
// Define our public-input gate!
meta.create_gate("public input", |meta| {
// We choose somewhat-arbitrarily that we will use the second advice column
// for exposing numbers as public inputs.
// We choose somewhat-arbitrarily that we will use the second advice
// column for exposing numbers as public inputs.
let a = meta.query_advice(advice[1], Rotation::cur());
let p = meta.query_aux(aux, Rotation::cur());
let s = meta.query_fixed(s_pub, Rotation::cur());
// We simply constrain the advice cell to be equal to the aux cell, when the
// selector is enabled.
// We simply constrain the advice cell to be equal to the aux cell,
// when the selector is enabled.
s * (p + a * -F::one())
});
@ -132,8 +133,8 @@ impl<F: FieldExt> Chip for FieldChip<F> {
type Field = F;
fn load(_layouter: &mut impl Layouter<Self>) -> Result<(), halo2::plonk::Error> {
// None of the instructions implemented by this chip have any fixed state. But if
// we required e.g. a lookup table, this is where we would load it.
// None of the instructions implemented by this chip have any fixed state.
// But if we required e.g. a lookup table, this is where we would load it.
Ok(())
}
}
@ -182,15 +183,15 @@ impl<F: FieldExt> NumericInstructions for FieldChip<F> {
layouter.assign_region(
|| "mul",
|mut region| {
// We only want to use a single multiplication gate in this region, so we
// enable it at region offset 0; this means it will constrain cells at
// offsets 0 and 1.
// We only want to use a single multiplication gate in this region,
// so we enable it at region offset 0; this means it will constrain
// cells at offsets 0 and 1.
region.assign_fixed(|| "example mul", config.s_mul, 0, || Ok(F::one()))?;
// The inputs we've been given could be located anywhere in the circuit,
// 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.
// 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],
@ -215,8 +216,8 @@ impl<F: FieldExt> NumericInstructions for FieldChip<F> {
|| value.ok_or(Error::SynthesisError),
)?;
// Finally, we return a variable representing the output, to be used in
// another part of the circuit.
// Finally, we return a variable representing the output,
// to be used in another part of the circuit.
out = Some(Number { cell, value });
Ok(())
},
@ -242,8 +243,8 @@ impl<F: FieldExt> NumericInstructions for FieldChip<F> {
)?;
region.constrain_equal(&config.perm, num.cell, out)?;
// We don't assign to the auxiliary column inside the circuit; the mapping
// of public inputs to cells is provided to the prover.
// We don't assign to the auxiliary column inside the circuit;
// the mapping of public inputs to cells is provided to the prover.
Ok(())
},
)
@ -254,9 +255,9 @@ impl<F: FieldExt> NumericInstructions for FieldChip<F> {
// ANCHOR: circuit
/// The full circuit implementation.
///
/// In this struct we store the private input variables. We use `Option<F>` because they
/// won't have any value during key generation. During proving, if any of these were
/// `None` we would get an error.
/// In this struct we store the private input variables. We use `Option<F>` because
/// they won't have any value during key generation. During proving, if any of these
/// were `None` we would get an error.
struct MyCircuit<F: FieldExt> {
a: Option<F>,
b: Option<F>,
@ -283,7 +284,8 @@ impl<F: FieldExt> Circuit<F> for MyCircuit<F> {
let a = FieldChip::load_private(&mut layouter, self.a)?;
let b = FieldChip::load_private(&mut layouter, self.b)?;
// We only have access to plain multiplication. We could implement our circuit as:
// We only have access to plain multiplication.
// We could implement our circuit as:
// asq = a*a
// bsq = b*b
// c = asq*bsq
@ -304,8 +306,8 @@ fn main() {
use halo2::{dev::MockProver, pasta::Fp};
// ANCHOR: test-circuit
// The number of rows in our circuit cannot exceed 2^k. Since our example circuit is
// very small, we can pick a very small value here.
// The number of rows in our circuit cannot exceed 2^k. Since our example
// circuit is very small, we can pick a very small value here.
let k = 3;
// Prepare the private and public inputs to the circuit!
@ -319,8 +321,8 @@ fn main() {
b: Some(b),
};
// Arrange the public input. We expose the multiplication result in row 4 of the aux
// column, so we position it there in our public inputs.
// Arrange the public input. We expose the multiplication result in row 6
// of the aux column, so we position it there in our public inputs.
let mut public_inputs = vec![Fp::zero(); 1 << k];
public_inputs[6] = c;