From 20db596e573e7f9d78af6010b5b2518c9a978b02 Mon Sep 17 00:00:00 2001 From: Robin Salen Date: Fri, 5 Jan 2024 09:45:45 +0100 Subject: [PATCH 1/7] Add some more explicit doc on plonky2 crate --- plonky2/src/gadgets/mod.rs | 3 + plonky2/src/gates/gate.rs | 49 +++++++++++- plonky2/src/iop/ext_target.rs | 4 + plonky2/src/iop/target.rs | 16 +++- plonky2/src/plonk/circuit_builder.rs | 114 ++++++++++++++++++++++++--- plonky2/src/plonk/circuit_data.rs | 12 +++ 6 files changed, 185 insertions(+), 13 deletions(-) diff --git a/plonky2/src/gadgets/mod.rs b/plonky2/src/gadgets/mod.rs index 9016211f..ba19e667 100644 --- a/plonky2/src/gadgets/mod.rs +++ b/plonky2/src/gadgets/mod.rs @@ -1,3 +1,6 @@ +//! Gadgets provide additional methods to [`CircuitBuilder`] +//! to ease circuit creation. + pub mod arithmetic; pub mod arithmetic_extension; pub mod hash; diff --git a/plonky2/src/gates/gate.rs b/plonky2/src/gates/gate.rs index 2f8f7df1..baf26f8c 100644 --- a/plonky2/src/gates/gate.rs +++ b/plonky2/src/gates/gate.rs @@ -26,15 +26,45 @@ use crate::plonk::vars::{ use crate::util::serialization::{Buffer, IoResult}; /// A custom gate. +/// +/// Vanilla Plonk arithmetization only supports basic fan-in 2 / fan-out 1 arithmetic gates, +/// each of the form +/// +/// $$ a.b.q_M + a.q_L + b.q_R + c.q_O + q_C = 0 $$ +/// +/// where: +/// - q_M, q_L, q_R and q_O are boolean selectors, +/// - a, b and c are values used as inputs and output respectively, +/// - q_C is a constant (possibly 0). +/// +/// This allows expressing simple operations like multiplication, addition, etc. For +/// instance, to define a multiplication, one can set q_M=1, q_L=q_R=0, q_O = -1 and q_C = 0. +/// Hence, the gate equation simplifies to a.b - c = 0, or a.b = c. +/// +/// However, such gate is fairly limited for more complex computations. Hence, when a computation may +/// require too many of these "vanilla" gates, or when a computation arises often within the same circuit, +/// one may want to construct a tailored custom gate. These custom gates can use more selectors and are +/// not necessarily limited to 2 inputs + 1 output = 3 wires. +/// For instance, plonky2 supports natively a custom Poseidon hash gate that uses 135 wires. +/// +/// Note however that extending the number of wires necessary for a custom gate comes at a price, and may +/// impact the overall performances when generating proofs for a circuit containing them. pub trait Gate, const D: usize>: 'static + Send + Sync { + /// Defines a unique identifier for this custom gate. + /// + /// This is used as differentiating tag in gate serializers. fn id(&self) -> String; + /// Serializes this custom gate to the targeted byte buffer, with the provided [`CommonCircuitData`]. fn serialize(&self, dst: &mut Vec, common_data: &CommonCircuitData) -> IoResult<()>; + /// Deserializes the bytes in the provided buffer into this custom gate, given some [`CommonCircuitData`]. fn deserialize(src: &mut Buffer, common_data: &CommonCircuitData) -> IoResult where Self: Sized; + /// Defines the constraints that enforce the statement represented by this gate. + /// Constraints must be defined in the extension of this custom gate base field. fn eval_unfiltered(&self, vars: EvaluationVars) -> Vec; /// Like `eval_unfiltered`, but specialized for points in the base field. @@ -88,6 +118,12 @@ pub trait Gate, const D: usize>: 'static + Send + S res } + /// Defines the recursive constraints that enforce the statement represented by this custom gate. + /// This is necessary to recursively verify proofs generated from a circuit containing such gates. + /// + /// **Note**: The order of the recursive constraints output by this method should match exactly the order + /// of the constraints obtained by the non-recursive [`Gate::eval_unfiltered`] method, otherwise the + /// prover won't be able to generate proofs. fn eval_unfiltered_circuit( &self, builder: &mut CircuitBuilder, @@ -175,10 +211,20 @@ pub trait Gate, const D: usize>: 'static + Send + S } /// The generators used to populate the witness. - /// Note: This should return exactly 1 generator per operation in the gate. + /// + /// **Note**: This should return exactly 1 generator per operation in the gate. fn generators(&self, row: usize, local_constants: &[F]) -> Vec>; /// The number of wires used by this gate. + /// + /// While vanilla Plonk can only evaluate one addition/multiplication at a time, a wider + /// configuration may be able to accomodate several identical gates at once. This is + /// particularly helpful for tiny custom gates that are being used extensively in circuits. + /// + /// For instance, the [crate::gates::multiplication_extension::MulExtensionGate] takes `3*D` + /// wires per multiplication (where `D`` is the degree of the extension), hence for a usual + /// configuration of 80 routed wires with D=2, one can evaluate 13 multiplications within a + /// single gate. fn num_wires(&self) -> usize; /// The number of constants used by this gate. @@ -187,6 +233,7 @@ pub trait Gate, const D: usize>: 'static + Send + S /// The maximum degree among this gate's constraint polynomials. fn degree(&self) -> usize; + /// The number of constraints defined by this sole custom gate. fn num_constraints(&self) -> usize; /// Number of operations performed by the gate. diff --git a/plonky2/src/iop/ext_target.rs b/plonky2/src/iop/ext_target.rs index 68d81fef..c64d96e8 100644 --- a/plonky2/src/iop/ext_target.rs +++ b/plonky2/src/iop/ext_target.rs @@ -9,6 +9,10 @@ use crate::iop::target::Target; use crate::plonk::circuit_builder::CircuitBuilder; /// `Target`s representing an element of an extension field. +/// +/// This is typically used in recursion settings, where the outer circuit must verify +/// a proof satisfying an inner circuit's statement, which is verified using arithmetic +/// in an extension of the base field. #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct ExtensionTarget(pub [Target; D]); diff --git a/plonky2/src/iop/target.rs b/plonky2/src/iop/target.rs index c0a1e286..f1225714 100644 --- a/plonky2/src/iop/target.rs +++ b/plonky2/src/iop/target.rs @@ -8,15 +8,25 @@ use crate::iop::wire::Wire; use crate::plonk::circuit_data::CircuitConfig; /// A location in the witness. +/// +/// Targets can either be placed at a specific location, or be "floating" around, +/// serving as intermediary value holders, and copied to other locations whenever needed. +/// +/// When generating a proof for a given circuit, the prover will "set" the values of some +/// (or all) targets, so that they satisfy the circuit constraints. This is done through +/// the [`PartialWitness`] interface. +/// +/// There are different "variants" of the `Target` type, namely [`ExtensionTarget`], +/// [`ExtensionAlgebraTarget`], but the `Target` type is the default one for most circuits +/// verifying some simple statement. #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Serialize, Deserialize)] pub enum Target { + /// A target that has a fixed location in the witness (seen as a `degree x num_wires` grid). Wire(Wire), /// A target that doesn't have any inherent location in the witness (but it can be copied to /// another target that does). This is useful for representing intermediate values in witness /// generation. - VirtualTarget { - index: usize, - }, + VirtualTarget { index: usize }, } impl Default for Target { diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index 3bc34099..38281d51 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -83,7 +83,56 @@ pub struct LookupWire { /// Index of the first lookup table row (i.e. the last `LookupTableGate`). pub first_lut_gate: usize, } + +/// Structure used to construct a plonky2 circuit. It provides all the necessary toolkit that, +/// from an initial circuit configuration, will enable one to design a circuit and its associated +/// prover/verifier data. +/// +/// # Usage +/// +/// ```rust +/// use plonky2::plonk::circuit_data::CircuitConfig; +/// use plonky2::plonk::circuit_builder::CircuitBuilder; +/// use plonky2::plonk::config::PoseidonGoldilocksConfig; +/// +/// // Define parameters for this circuit +/// const D: usize = 2; +/// type C = PoseidonGoldilocksConfig; +/// type F = >::F; +/// +/// let config = CircuitConfig::standard_recursion_config(); +/// let mut builder = CircuitBuilder::::new(config); +/// +/// // Build a circuit for the statement: "I know the 100th term +/// // of the Fibonacci sequence, starting from 0 and 1". +/// let initial_a = builder.constant(F::ZERO); +/// let initial_b = builder.constant(F::ONE); +/// let mut prev_target = initial_a; +/// let mut cur_target = initial_b; +/// for _ in 0..99 { +/// let temp = builder.add(prev_target, cur_target); +/// prev_target = cur_target; +/// cur_target = temp; +/// } +/// +/// // The only public input is the result (which is generated). +/// builder.register_public_input(cur_target); +/// +/// // Build the circuit +/// let circuit_data = builder.build::(); +/// +/// // Now compute the witness and generate a proof +/// let mut pw = PartialWitness::new(); +/// +/// // There are no public inputs to register, as the only one +/// // will be generated while proving the statement. +/// let proof = data.prove(pw).unwrap(); +/// +/// // Verify the proof +/// assert!(data.verify(proof).is_ok()); +/// ``` pub struct CircuitBuilder, const D: usize> { + /// Circuit configuration to be used by this `CircuitBuilder`. pub config: CircuitConfig, /// A domain separator, which is included in the initial Fiat-Shamir seed. This is generally not @@ -146,6 +195,10 @@ pub struct CircuitBuilder, const D: usize> { } impl, const D: usize> CircuitBuilder { + /// Given a [`CircuitConfig`], generate a new [`CircuitBuilder`] instance. + /// It will also check that the configuration provided is consistent, i.e. + /// that the different parameters provided can achieve the targeted security + /// level. pub fn new(config: CircuitConfig) -> Self { let builder = CircuitBuilder { config, @@ -173,6 +226,8 @@ impl, const D: usize> CircuitBuilder { builder } + /// Assert that the configuration used to create this `CircuitBuilder` is consistent, + /// i.e. that the different parameters meet the targeted security level. fn check_config(&self) { let &CircuitConfig { security_bits, @@ -201,6 +256,7 @@ impl, const D: usize> CircuitBuilder { self.domain_separator = Some(separator); } + /// Outputs the number of gates in this circuit. pub fn num_gates(&self) -> usize { self.gate_instances.len() } @@ -215,6 +271,7 @@ impl, const D: usize> CircuitBuilder { targets.iter().for_each(|&t| self.register_public_input(t)); } + /// Outputs the number of public inputs in this circuit. pub fn num_public_inputs(&self) -> usize { self.public_inputs.len() } @@ -244,10 +301,13 @@ impl, const D: usize> CircuitBuilder { self.lut_to_lookups[lut_index].push((looking_in, looking_out)); } + /// Outputs the number of lookup tables in this circuit. pub fn num_luts(&self) -> usize { self.lut_to_lookups.len() } + /// Given an index, outputs the corresponding looking table in the set of tables + /// used in this circuit, as a sequence of target tuples `(input, output)`. pub fn get_lut_lookups(&self, lut_index: usize) -> &[(Target, Target)] { &self.lut_to_lookups[lut_index] } @@ -262,22 +322,28 @@ impl, const D: usize> CircuitBuilder { Target::VirtualTarget { index } } + /// Adds `n` new "virtual" targets. pub fn add_virtual_targets(&mut self, n: usize) -> Vec { (0..n).map(|_i| self.add_virtual_target()).collect() } + /// Adds `N` new "virtual" targets, arranged as an array. pub fn add_virtual_target_arr(&mut self) -> [Target; N] { [0; N].map(|_| self.add_virtual_target()) } + /// Adds a new `HashOutTarget`. `NUM_HASH_OUT_ELTS` being hardcoded to 4, it internally + /// adds 4 virtual targets in a vector fashion. pub fn add_virtual_hash(&mut self) -> HashOutTarget { HashOutTarget::from_vec(self.add_virtual_targets(4)) } + /// Adds a new `MerkleCapTarget`, consisting in `1 << cap_height` `HashOutTarget`. pub fn add_virtual_cap(&mut self, cap_height: usize) -> MerkleCapTarget { MerkleCapTarget(self.add_virtual_hashes(1 << cap_height)) } + /// Adds `n` new `HashOutTarget` in a vector fashion. pub fn add_virtual_hashes(&mut self, n: usize) -> Vec { (0..n).map(|_i| self.add_virtual_hash()).collect() } @@ -337,7 +403,9 @@ impl, const D: usize> CircuitBuilder { } /// Add a virtual verifier data, register it as a public input and set it to `self.verifier_data_public_input`. - /// WARNING: Do not register any public input after calling this! TODO: relax this + /// + /// **WARNING**: Do not register any public input after calling this! + // TODO: relax this pub fn add_verifier_data_public_inputs(&mut self) -> VerifierCircuitTarget { assert!( self.verifier_data_public_input.is_none(), @@ -410,16 +478,12 @@ impl, const D: usize> CircuitBuilder { ); } + /// Adds a gate type to the set of gates to be used in this circuit. This can be useful + /// in conditional recursion to uniformize the gates set of the different circuits. pub fn add_gate_to_gate_set(&mut self, gate: GateRef) { self.gates.insert(gate); } - pub fn connect_extension(&mut self, src: ExtensionTarget, dst: ExtensionTarget) { - for i in 0..D { - self.connect(src.0[i], dst.0[i]); - } - } - /// Adds a generator which will copy `src` to `dst`. pub fn generate_copy(&mut self, src: Target, dst: Target) { self.add_simple_generator(CopyGenerator { src, dst }); @@ -427,6 +491,8 @@ impl, const D: usize> CircuitBuilder { /// Uses Plonk's permutation argument to require that two elements be equal. /// Both elements must be routable, otherwise this method will panic. + /// + /// For an example of usage, see [`CircuitBuilder::assert_one()`]. pub fn connect(&mut self, x: Target, y: Target) { assert!( x.is_routable(&self.config), @@ -440,17 +506,40 @@ impl, const D: usize> CircuitBuilder { .push(CopyConstraint::new((x, y), self.context_log.open_stack())); } + /// Enforces that two [`ExtensionTarget`] underlying values are equal. + pub fn connect_extension(&mut self, src: ExtensionTarget, dst: ExtensionTarget) { + for i in 0..D { + self.connect(src.0[i], dst.0[i]); + } + } + + /// Enforces that a routable `Target` value is 0, using Plonk's permutation argument. pub fn assert_zero(&mut self, x: Target) { let zero = self.zero(); self.connect(x, zero); } + /// Enforces that a routable `Target` value is 1, using Plonk's permutation argument. + /// + /// # Example + /// + /// Let say the circuit contains a target `a`, and a target `b` as public input so that the + /// prover can non-deterministically compute the multiplicative inverse of `a` when generating + /// a proof. + /// + /// One can then add the following constraint in the circuit to enforce that the value provided + /// by the prover is correct: + /// + /// ```ignore + /// let c = builder.mul(a, b); + /// builder.assert_one(c); + /// ``` pub fn assert_one(&mut self, x: Target) { let one = self.one(); self.connect(x, one); } - pub fn add_generators(&mut self, generators: Vec>) { + fn add_generators(&mut self, generators: Vec>) { self.generators.extend(generators); } @@ -479,10 +568,12 @@ impl, const D: usize> CircuitBuilder { self.constant(F::NEG_ONE) } + /// Returns a rootable boolean target set to false. pub fn _false(&mut self) -> BoolTarget { BoolTarget::new_unsafe(self.zero()) } + /// Returns a rootable boolean target set to true. pub fn _true(&mut self) -> BoolTarget { BoolTarget::new_unsafe(self.one()) } @@ -501,10 +592,12 @@ impl, const D: usize> CircuitBuilder { target } + /// Returns a vector of routable targets with the given constant values. pub fn constants(&mut self, constants: &[F]) -> Vec { constants.iter().map(|&c| self.constant(c)).collect() } + /// Returns a routable target with the given constant boolean value. pub fn constant_bool(&mut self, b: bool) -> BoolTarget { if b { self._true() @@ -513,12 +606,14 @@ impl, const D: usize> CircuitBuilder { } } + /// Returns a routable [`HashOutTarget`]. pub fn constant_hash(&mut self, h: HashOut) -> HashOutTarget { HashOutTarget { elements: h.elements.map(|x| self.constant(x)), } } + /// Returns a routable [`MerkleCapTarget`]. pub fn constant_merkle_cap>>( &mut self, cap: &MerkleCap, @@ -545,7 +640,7 @@ impl, const D: usize> CircuitBuilder { self.targets_to_constants.get(&target).cloned() } - /// If the given `ExtensionTarget` is a constant (i.e. it was created by the + /// If the given [`ExtensionTarget`] is a constant (i.e. it was created by the /// `constant_extension(F)` method), returns its constant value. Otherwise, returns `None`. pub fn target_as_constant_ext(&self, target: ExtensionTarget) -> Option { // Get a Vec of any coefficients that are constant. If we end up with exactly D of them, @@ -1178,6 +1273,7 @@ impl, const D: usize> CircuitBuilder { ) } + /// Builds a "full circuit", with both prover and verifier data. pub fn build>(self) -> CircuitData { self.build_with_options(true) } diff --git a/plonky2/src/plonk/circuit_data.rs b/plonky2/src/plonk/circuit_data.rs index 1b07a8b2..c0c60220 100644 --- a/plonky2/src/plonk/circuit_data.rs +++ b/plonky2/src/plonk/circuit_data.rs @@ -38,9 +38,19 @@ use crate::util::serialization::{ }; use crate::util::timing::TimingTree; +/// Configuration to be used when building a circuit. This defines the shape of the circuit +/// as well as its targeted security level and sub-protocol (e.g. FRI) parameters. +/// +/// It supports a [`Default`] implementation tailored for recursion with Poseidon hash (of width 12) +/// as internal hash function and FRI rate of 1/8. #[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct CircuitConfig { + /// The number of wires available at each row. This corresponds to the "width" of the circuit, + /// and consists in the sum of routed wires and advice wires. pub num_wires: usize, + /// The number of routed wires, i.e. wires that will be involved in Plonk's permutation argument. + /// This allows copy constraints, i.e. enforcing that two distant values in a circuit are equal. + /// Non-routed wires are called advice wires. pub num_routed_wires: usize, pub num_constants: usize, /// Whether to use a dedicated gate for base field arithmetic, rather than using a single gate @@ -50,6 +60,8 @@ pub struct CircuitConfig { /// The number of challenge points to generate, for IOPs that have soundness errors of (roughly) /// `degree / |F|`. pub num_challenges: usize, + /// A boolean to activate the zero-knowledge property. When this is set to `false`, proofs *may* + /// leak additional information. pub zero_knowledge: bool, /// A cap on the quotient polynomial's degree factor. The actual degree factor is derived /// systematically, but will never exceed this value. From 3c8b150f0f6528c933b4e9fa4ae186bb5b28e8de Mon Sep 17 00:00:00 2001 From: Robin Salen Date: Mon, 8 Jan 2024 09:37:42 +0100 Subject: [PATCH 2/7] Rustdoc --- plonky2/src/plonk/circuit_builder.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index 38281d51..fba33434 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -92,8 +92,10 @@ pub struct LookupWire { /// /// ```rust /// use plonky2::plonk::circuit_data::CircuitConfig; +/// use plonky2::iop::witness::PartialWitness; /// use plonky2::plonk::circuit_builder::CircuitBuilder; -/// use plonky2::plonk::config::PoseidonGoldilocksConfig; +/// use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; +/// use plonky2::field::types::Field; /// /// // Define parameters for this circuit /// const D: usize = 2; @@ -126,10 +128,10 @@ pub struct LookupWire { /// /// // There are no public inputs to register, as the only one /// // will be generated while proving the statement. -/// let proof = data.prove(pw).unwrap(); +/// let proof = circuit_data.prove(pw).unwrap(); /// /// // Verify the proof -/// assert!(data.verify(proof).is_ok()); +/// assert!(circuit_data.verify(proof).is_ok()); /// ``` pub struct CircuitBuilder, const D: usize> { /// Circuit configuration to be used by this `CircuitBuilder`. From ed2e1bc780f749748b20f83edd2a899dd4c5bb53 Mon Sep 17 00:00:00 2001 From: Robin Salen Date: Mon, 8 Jan 2024 09:38:55 +0100 Subject: [PATCH 3/7] Add comment --- plonky2/src/plonk/circuit_builder.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index fba33434..c0e0d870 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -112,7 +112,9 @@ pub struct LookupWire { /// let mut prev_target = initial_a; /// let mut cur_target = initial_b; /// for _ in 0..99 { +/// // Encode an addition of the two previous terms /// let temp = builder.add(prev_target, cur_target); +/// // Shift the two previous terms with the new value /// prev_target = cur_target; /// cur_target = temp; /// } From 82804e4201f675fda91119414c706d07e4ecd4fe Mon Sep 17 00:00:00 2001 From: Robin Salen Date: Mon, 8 Jan 2024 15:14:26 +0100 Subject: [PATCH 4/7] Add some more + module doc --- plonky2/src/fri/mod.rs | 3 +++ plonky2/src/gadgets/mod.rs | 3 ++- plonky2/src/gates/mod.rs | 22 +++++++++++++++++++ plonky2/src/hash/mod.rs | 3 +++ plonky2/src/lib.rs | 1 + plonky2/src/plonk/circuit_builder.rs | 4 ++-- plonky2/src/plonk/mod.rs | 5 +++++ plonky2/src/recursion/mod.rs | 6 +++++ plonky2/src/util/mod.rs | 2 ++ .../util/serialization/gate_serialization.rs | 2 +- .../serialization/generator_serialization.rs | 2 +- 11 files changed, 48 insertions(+), 5 deletions(-) diff --git a/plonky2/src/fri/mod.rs b/plonky2/src/fri/mod.rs index 100ae851..11d469f4 100644 --- a/plonky2/src/fri/mod.rs +++ b/plonky2/src/fri/mod.rs @@ -1,3 +1,6 @@ +//! Fast Reed-Solomon IOP (FRI) protocol and its circuit version +//! of the FRI verifier for recursive proof composition. + use alloc::vec::Vec; use serde::Serialize; diff --git a/plonky2/src/gadgets/mod.rs b/plonky2/src/gadgets/mod.rs index ba19e667..cc14a835 100644 --- a/plonky2/src/gadgets/mod.rs +++ b/plonky2/src/gadgets/mod.rs @@ -1,4 +1,5 @@ -//! Gadgets provide additional methods to [`CircuitBuilder`] +//! Helper gadgets providing additional methods to +//! [CircuitBuilder](crate::plonk::circuit_builder::CircuitBuilder), //! to ease circuit creation. pub mod arithmetic; diff --git a/plonky2/src/gates/mod.rs b/plonky2/src/gates/mod.rs index 432f0264..446f1aed 100644 --- a/plonky2/src/gates/mod.rs +++ b/plonky2/src/gates/mod.rs @@ -1,3 +1,25 @@ +//! plonky2 custom gates. +//! +//! Vanilla Plonk arithmetization only supports basic fan-in 2 / fan-out 1 arithmetic gates, +//! each of the form +//! +//! $$ a.b.q_M + a.q_L + b.q_R + c.q_O + q_C = 0 $$ +//! +//! where: +//! - q_M, q_L, q_R and q_O are boolean selectors, +//! - a, b and c are values used as inputs and output respectively, +//! - q_C is a constant (possibly 0). +//! +//! This allows expressing simple operations like multiplication, addition, etc. For +//! instance, to define a multiplication, one can set q_M=1, q_L=q_R=0, q_O = -1 and q_C = 0. +//! Hence, the gate equation simplifies to a.b - c = 0, or a.b = c. +//! +//! However, such gate is fairly limited for more complex computations. Hence, when a computation may +//! require too many of these "vanilla" gates, or when a computation arises often within the same circuit, +//! one may want to construct a tailored custom gate. These custom gates can use more selectors and are +//! not necessarily limited to 2 inputs + 1 output = 3 wires. +//! For instance, plonky2 supports natively a custom Poseidon hash gate that uses 135 wires. + // Gates have `new` methods that return `GateRef`s. pub mod arithmetic_base; diff --git a/plonky2/src/hash/mod.rs b/plonky2/src/hash/mod.rs index b8293920..c98c5706 100644 --- a/plonky2/src/hash/mod.rs +++ b/plonky2/src/hash/mod.rs @@ -1,3 +1,6 @@ +//! plonky2 hashing logic for in-circuit hashing and Merkle proof verification +//! as well as specific hash functions implementation. + mod arch; pub mod hash_types; pub mod hashing; diff --git a/plonky2/src/lib.rs b/plonky2/src/lib.rs index b02fc21b..44bc2cf6 100644 --- a/plonky2/src/lib.rs +++ b/plonky2/src/lib.rs @@ -4,6 +4,7 @@ pub extern crate alloc; +/// Re-export of `plonky2_field`. #[doc(inline)] pub use plonky2_field as field; diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index c0e0d870..4a1eee90 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -136,7 +136,7 @@ pub struct LookupWire { /// assert!(circuit_data.verify(proof).is_ok()); /// ``` pub struct CircuitBuilder, const D: usize> { - /// Circuit configuration to be used by this `CircuitBuilder`. + /// Circuit configuration to be used by this [`CircuitBuilder`]. pub config: CircuitConfig, /// A domain separator, which is included in the initial Fiat-Shamir seed. This is generally not @@ -179,7 +179,7 @@ pub struct CircuitBuilder, const D: usize> { /// List of constant generators used to fill the constant wires. constant_generators: Vec>, - /// Rows for each LUT: LookupWire contains: first `LookupGate`, first `LookupTableGate`, last `LookupTableGate`. + /// Rows for each LUT: LookupWire contains: first `LookupGate`, first [`LookupTableGate`], last `LookupTableGate`. lookup_rows: Vec, /// For each LUT index, vector of `(looking_in, looking_out)` pairs. diff --git a/plonky2/src/plonk/mod.rs b/plonky2/src/plonk/mod.rs index 604c1f79..565b1c57 100644 --- a/plonky2/src/plonk/mod.rs +++ b/plonky2/src/plonk/mod.rs @@ -1,3 +1,8 @@ +//! plonky2 proving system. +//! +//! This module also defines the [CircuitBuilder](circuit_builder::CircuitBuilder) +//! structure, used to build custom plonky2 circuits satisfying arbitrary statements. + pub mod circuit_builder; pub mod circuit_data; pub mod config; diff --git a/plonky2/src/recursion/mod.rs b/plonky2/src/recursion/mod.rs index 0e9cd2cc..438f6007 100644 --- a/plonky2/src/recursion/mod.rs +++ b/plonky2/src/recursion/mod.rs @@ -1,3 +1,9 @@ +//! Recursion logic for verifying recursively plonky2 circuits. +//! +//! This module also provides ways to perform conditional recursive verification +//! (between two different circuits, depending on a condition), and cyclic +//! recursion where a circuit implements its own verification logic. + pub mod conditional_recursive_verifier; pub mod cyclic_recursion; pub mod dummy_circuit; diff --git a/plonky2/src/util/mod.rs b/plonky2/src/util/mod.rs index fc2c4f09..e0f71f12 100644 --- a/plonky2/src/util/mod.rs +++ b/plonky2/src/util/mod.rs @@ -1,3 +1,5 @@ +//! Utility module for helper methods and plonky2 serialization logic. + use alloc::vec::Vec; use plonky2_maybe_rayon::*; diff --git a/plonky2/src/util/serialization/gate_serialization.rs b/plonky2/src/util/serialization/gate_serialization.rs index d858a057..c5763fb0 100644 --- a/plonky2/src/util/serialization/gate_serialization.rs +++ b/plonky2/src/util/serialization/gate_serialization.rs @@ -59,7 +59,7 @@ macro_rules! get_gate_tag_impl { } #[macro_export] -/// Macro implementing the `GateSerializer` trait. +/// Macro implementing the [`GateSerializer`] trait. /// To serialize a list of gates used for a circuit, /// this macro should be called with a struct on which to implement /// this as first argument, followed by all the targeted gates. diff --git a/plonky2/src/util/serialization/generator_serialization.rs b/plonky2/src/util/serialization/generator_serialization.rs index 19a22a77..bad24ceb 100644 --- a/plonky2/src/util/serialization/generator_serialization.rs +++ b/plonky2/src/util/serialization/generator_serialization.rs @@ -63,7 +63,7 @@ macro_rules! get_generator_tag_impl { } #[macro_export] -/// Macro implementing the `WitnessGeneratorSerializer` trait. +/// Macro implementing the [`WitnessGeneratorSerializer`] trait. /// To serialize a list of generators used for a circuit, /// this macro should be called with a struct on which to implement /// this as first argument, followed by all the targeted generators. From f4be34dc6d2bb7c336ed237304728dad067ec6c8 Mon Sep 17 00:00:00 2001 From: Robin Salen Date: Tue, 9 Jan 2024 10:59:00 +0100 Subject: [PATCH 5/7] Some more --- plonky2/src/gadgets/arithmetic.rs | 16 ++++++++++------ plonky2/src/plonk/circuit_builder.rs | 2 ++ plonky2/src/plonk/circuit_data.rs | 14 ++++++++++++++ plonky2/src/plonk/config.rs | 8 ++++++++ plonky2/src/plonk/plonk_common.rs | 2 ++ plonky2/src/plonk/proof.rs | 6 ++++++ plonky2/src/plonk/prover.rs | 2 ++ plonky2/src/plonk/vars.rs | 2 ++ plonky2/src/plonk/verifier.rs | 2 ++ 9 files changed, 48 insertions(+), 6 deletions(-) diff --git a/plonky2/src/gadgets/arithmetic.rs b/plonky2/src/gadgets/arithmetic.rs index e3af60e9..9982628e 100644 --- a/plonky2/src/gadgets/arithmetic.rs +++ b/plonky2/src/gadgets/arithmetic.rs @@ -191,7 +191,7 @@ impl, const D: usize> CircuitBuilder { self.arithmetic(F::ONE, F::ONE, x, one, y) } - /// Add `n` `Target`s. + /// Adds `n` `Target`s. pub fn add_many(&mut self, terms: impl IntoIterator) -> Target where T: Borrow, @@ -224,7 +224,7 @@ impl, const D: usize> CircuitBuilder { .fold(self.one(), |acc, t| self.mul(acc, *t.borrow())) } - /// Exponentiate `base` to the power of `2^power_log`. + /// Exponentiates `base` to the power of `2^power_log`. pub fn exp_power_of_2(&mut self, base: Target, power_log: usize) -> Target { if power_log > self.num_base_arithmetic_ops_per_gate() { // Cheaper to just use `ExponentiateGate`. @@ -239,7 +239,7 @@ impl, const D: usize> CircuitBuilder { } // TODO: Test - /// Exponentiate `base` to the power of `exponent`, given by its little-endian bits. + /// Exponentiates `base` to the power of `exponent`, given by its little-endian bits. pub fn exp_from_bits( &mut self, base: Target, @@ -264,7 +264,7 @@ impl, const D: usize> CircuitBuilder { } // TODO: Test - /// Exponentiate `base` to the power of `exponent`, where `exponent < 2^num_bits`. + /// Exponentiates `base` to the power of `exponent`, where `exponent < 2^num_bits`. pub fn exp(&mut self, base: Target, exponent: Target, num_bits: usize) -> Target { let exponent_bits = self.split_le(exponent, num_bits); @@ -303,7 +303,7 @@ impl, const D: usize> CircuitBuilder { product } - /// Exponentiate `base` to the power of a known `exponent`. + /// Exponentiates `base` to the power of a known `exponent`. // TODO: Test pub fn exp_u64(&mut self, base: Target, mut exponent: u64) -> Target { let mut exp_bits = Vec::new(); @@ -330,28 +330,32 @@ impl, const D: usize> CircuitBuilder { self.inverse_extension(x_ext).0[0] } + /// Computes the logical NOT of the provided [`BoolTarget`]. pub fn not(&mut self, b: BoolTarget) -> BoolTarget { let one = self.one(); let res = self.sub(one, b.target); BoolTarget::new_unsafe(res) } + /// Computes the logical AND of the provided [`BoolTarget`]s. pub fn and(&mut self, b1: BoolTarget, b2: BoolTarget) -> BoolTarget { BoolTarget::new_unsafe(self.mul(b1.target, b2.target)) } - /// computes the arithmetic extension of logical "or": `b1 + b2 - b1 * b2` + /// Computes the logical OR through the arithmetic expression: `b1 + b2 - b1 * b2`. pub fn or(&mut self, b1: BoolTarget, b2: BoolTarget) -> BoolTarget { let res_minus_b2 = self.arithmetic(-F::ONE, F::ONE, b1.target, b2.target, b1.target); BoolTarget::new_unsafe(self.add(res_minus_b2, b2.target)) } + /// Outputs `x` if `b` is true, and else `y`, through the formula: `b*x + (1-b)*y`. pub fn _if(&mut self, b: BoolTarget, x: Target, y: Target) -> Target { let not_b = self.not(b); let maybe_x = self.mul(b.target, x); self.mul_add(not_b.target, y, maybe_x) } + /// Checks whether `x` and `y` are equal and outputs the boolean result. pub fn is_equal(&mut self, x: Target, y: Target) -> BoolTarget { let zero = self.zero(); diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index 4a1eee90..be905cc2 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -1,3 +1,5 @@ +//! Logic for building plonky2 circuits. + use alloc::collections::BTreeMap; use alloc::sync::Arc; use alloc::vec; diff --git a/plonky2/src/plonk/circuit_data.rs b/plonky2/src/plonk/circuit_data.rs index c0c60220..4a2efe06 100644 --- a/plonky2/src/plonk/circuit_data.rs +++ b/plonky2/src/plonk/circuit_data.rs @@ -1,3 +1,17 @@ +//! Circuit data specific to the prover and the verifier. +//! +//! This module also defines a [`CircuitConfig`] to be customized +//! when building circuits for arbitrary statements. +//! +//! After building a circuit, one obtains an instance of [`CircuitData`]. +//! This contains both prover and verifier data, allowing to generate +//! proofs for the given circuit and verify them. +//! +//! Most of the [`CircuitData`] is actually prover-specific, and can be +//! extracted by calling [`CircuitData::prover_data`] method. +//! The verifier data can similarly be extracted by calling [`CircuitData::verifier_data`]. +//! This is useful to allow even small devices to verify plonky2 proofs. + use alloc::collections::BTreeMap; use alloc::vec; use alloc::vec::Vec; diff --git a/plonky2/src/plonk/config.rs b/plonky2/src/plonk/config.rs index 2391ef6c..c4e73356 100644 --- a/plonky2/src/plonk/config.rs +++ b/plonky2/src/plonk/config.rs @@ -1,3 +1,11 @@ +//! Hashing configuration to be used when building a circuit. +//! +//! This module defines a [`Hasher`] trait as well as its recursive +//! counterpart [`AlgebraicHasher`] for in-circuit hashing. It also +//! provides concrete configurations, one fully recursive leveraging +//! Poseidon hash function both internally and natively, and one mixing +//! Poseidon internally and truncated Keccak externally. + use alloc::vec; use alloc::vec::Vec; use core::fmt::Debug; diff --git a/plonky2/src/plonk/plonk_common.rs b/plonky2/src/plonk/plonk_common.rs index f064cbac..ca8ea919 100644 --- a/plonky2/src/plonk/plonk_common.rs +++ b/plonky2/src/plonk/plonk_common.rs @@ -1,3 +1,5 @@ +//! Utility methods and constants for Plonk. + use alloc::vec; use alloc::vec::Vec; diff --git a/plonky2/src/plonk/proof.rs b/plonky2/src/plonk/proof.rs index bd935233..c010414e 100644 --- a/plonky2/src/plonk/proof.rs +++ b/plonky2/src/plonk/proof.rs @@ -1,3 +1,9 @@ +//! plonky2 proof definition. +//! +//! Proofs can be later compressed to reduce their size, into either +//! [`CompressedProof`] or [`CompressedProofWithPublicInputs`] formats. +//! The latter can be directly passed to a verifier to assert its correctness. + use alloc::vec; use alloc::vec::Vec; diff --git a/plonky2/src/plonk/prover.rs b/plonky2/src/plonk/prover.rs index 41aebdb1..e0c8d727 100644 --- a/plonky2/src/plonk/prover.rs +++ b/plonky2/src/plonk/prover.rs @@ -1,3 +1,5 @@ +//! plonky2 prover implementation. + use alloc::vec::Vec; use alloc::{format, vec}; use core::cmp::min; diff --git a/plonky2/src/plonk/vars.rs b/plonky2/src/plonk/vars.rs index 727f7651..b9d6d790 100644 --- a/plonky2/src/plonk/vars.rs +++ b/plonky2/src/plonk/vars.rs @@ -1,3 +1,5 @@ +//! Logic for evaluating constraints. + use core::ops::Range; use crate::field::extension::algebra::ExtensionAlgebra; diff --git a/plonky2/src/plonk/verifier.rs b/plonky2/src/plonk/verifier.rs index b160fddc..fa1bc14b 100644 --- a/plonky2/src/plonk/verifier.rs +++ b/plonky2/src/plonk/verifier.rs @@ -1,3 +1,5 @@ +//! plonky2 verifier implementation. + use anyhow::{ensure, Result}; use crate::field::extension::Extendable; From 85524cfacc4f7dcebd8f765108af643f24e5a7ff Mon Sep 17 00:00:00 2001 From: Robin Salen Date: Wed, 10 Jan 2024 09:06:34 +0100 Subject: [PATCH 6/7] Intra doc link --- evm/src/curve_pairings.rs | 4 ++-- evm/src/lookup.rs | 2 +- plonky2/src/gates/arithmetic_base.rs | 2 +- plonky2/src/gates/arithmetic_extension.rs | 2 +- plonky2/src/gates/multiplication_extension.rs | 2 +- plonky2/src/iop/target.rs | 6 +++--- plonky2/src/plonk/circuit_builder.rs | 5 +++-- plonky2/src/plonk/prover.rs | 2 +- plonky2/src/plonk/vanishing_poly.rs | 4 ++-- 9 files changed, 15 insertions(+), 14 deletions(-) diff --git a/evm/src/curve_pairings.rs b/evm/src/curve_pairings.rs index 1380c96e..71188a21 100644 --- a/evm/src/curve_pairings.rs +++ b/evm/src/curve_pairings.rs @@ -63,7 +63,7 @@ where } /// Standard addition formula for elliptic curves, restricted to the cases -/// https://en.wikipedia.org/wiki/Elliptic_curve#Algebraic_interpretation +/// impl Add for Curve { type Output = Self; @@ -201,7 +201,7 @@ pub(crate) fn bn_tate(p: Curve, q: Curve>) -> Fp12 { } /// Standard code for miller loop, can be found on page 99 at this url: -/// https://static1.squarespace.com/static/5fdbb09f31d71c1227082339/t/5ff394720493bd28278889c6/1609798774687/PairingsForBeginners.pdf#page=107 +/// /// where BN_EXP is a hardcoding of the array of Booleans that the loop traverses pub(crate) fn bn_miller_loop(p: Curve, q: Curve>) -> Fp12 { let mut r = p; diff --git a/evm/src/lookup.rs b/evm/src/lookup.rs index 8bf0c8f6..5d5d1a7b 100644 --- a/evm/src/lookup.rs +++ b/evm/src/lookup.rs @@ -40,7 +40,7 @@ impl Lookup { } } -/// logUp protocol from https://ia.cr/2022/1530 +/// logUp protocol from /// Compute the helper columns for the lookup argument. /// Given columns `f0,...,fk` and a column `t`, such that `∪fi ⊆ t`, and challenges `x`, /// this computes the helper columns `h_i = 1/(x+f_2i) + 1/(x+f_2i+1)`, `g = 1/(x+t)`, diff --git a/plonky2/src/gates/arithmetic_base.rs b/plonky2/src/gates/arithmetic_base.rs index f47bd18f..e06c58af 100644 --- a/plonky2/src/gates/arithmetic_base.rs +++ b/plonky2/src/gates/arithmetic_base.rs @@ -20,7 +20,7 @@ use crate::plonk::vars::{ }; use crate::util::serialization::{Buffer, IoResult, Read, Write}; -/// A gate which can perform a weighted multiply-add, i.e. `result = c0 x y + c1 z`. If the config +/// A gate which can perform a weighted multiply-add, i.e. `result = c0.x.y + c1.z`. If the config /// supports enough routed wires, it can support several such operations in one gate. #[derive(Debug, Clone)] pub struct ArithmeticGate { diff --git a/plonky2/src/gates/arithmetic_extension.rs b/plonky2/src/gates/arithmetic_extension.rs index 084a14d6..37482a5d 100644 --- a/plonky2/src/gates/arithmetic_extension.rs +++ b/plonky2/src/gates/arithmetic_extension.rs @@ -16,7 +16,7 @@ use crate::plonk::circuit_data::{CircuitConfig, CommonCircuitData}; use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; use crate::util::serialization::{Buffer, IoResult, Read, Write}; -/// A gate which can perform a weighted multiply-add, i.e. `result = c0 x y + c1 z`. If the config +/// A gate which can perform a weighted multiply-add, i.e. `result = c0.x.y + c1.z`. If the config /// supports enough routed wires, it can support several such operations in one gate. #[derive(Debug, Clone)] pub struct ArithmeticExtensionGate { diff --git a/plonky2/src/gates/multiplication_extension.rs b/plonky2/src/gates/multiplication_extension.rs index 11fd88eb..1d85817a 100644 --- a/plonky2/src/gates/multiplication_extension.rs +++ b/plonky2/src/gates/multiplication_extension.rs @@ -16,7 +16,7 @@ use crate::plonk::circuit_data::{CircuitConfig, CommonCircuitData}; use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; use crate::util::serialization::{Buffer, IoResult, Read, Write}; -/// A gate which can perform a weighted multiplication, i.e. `result = c0 x y`. If the config +/// A gate which can perform a weighted multiplication, i.e. `result = c0.x.y`. If the config /// supports enough routed wires, it can support several such operations in one gate. #[derive(Debug, Clone)] pub struct MulExtensionGate { diff --git a/plonky2/src/iop/target.rs b/plonky2/src/iop/target.rs index f1225714..b1fe9bf9 100644 --- a/plonky2/src/iop/target.rs +++ b/plonky2/src/iop/target.rs @@ -14,11 +14,11 @@ use crate::plonk::circuit_data::CircuitConfig; /// /// When generating a proof for a given circuit, the prover will "set" the values of some /// (or all) targets, so that they satisfy the circuit constraints. This is done through -/// the [`PartialWitness`] interface. +/// the [PartialWitness](crate::iop::witness::PartialWitness) interface. /// /// There are different "variants" of the `Target` type, namely [`ExtensionTarget`], -/// [`ExtensionAlgebraTarget`], but the `Target` type is the default one for most circuits -/// verifying some simple statement. +/// [ExtensionAlgebraTarget](crate::iop::ext_target::ExtensionAlgebraTarget), but the `Target` +/// type is the default one for most circuits verifying some simple statement. #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Serialize, Deserialize)] pub enum Target { /// A target that has a fixed location in the witness (seen as a `degree x num_wires` grid). diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index be905cc2..227af85b 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -181,7 +181,8 @@ pub struct CircuitBuilder, const D: usize> { /// List of constant generators used to fill the constant wires. constant_generators: Vec>, - /// Rows for each LUT: LookupWire contains: first `LookupGate`, first [`LookupTableGate`], last `LookupTableGate`. + /// Rows for each LUT: [`LookupWire`] contains: first [`LookupGate`], first and last + /// [LookupTableGate](crate::gates::lookup_table::LookupTableGate). lookup_rows: Vec, /// For each LUT index, vector of `(looking_in, looking_out)` pairs. @@ -1007,7 +1008,7 @@ impl, const D: usize> CircuitBuilder { /// In PLONK's permutation argument, there's a slight chance of division by zero. We can /// mitigate this by randomizing some unused witness elements, so if proving fails with /// division by zero, the next attempt will have an (almost) independent chance of success. - /// See https://github.com/0xPolygonZero/plonky2/issues/456 + /// See . fn randomize_unused_pi_wires(&mut self, pi_gate: usize) { for wire in PublicInputGate::wires_public_inputs_hash().end..self.config.num_wires { self.add_simple_generator(RandomValueGenerator { diff --git a/plonky2/src/plonk/prover.rs b/plonky2/src/plonk/prover.rs index e0c8d727..153610dc 100644 --- a/plonky2/src/plonk/prover.rs +++ b/plonky2/src/plonk/prover.rs @@ -443,7 +443,7 @@ fn wires_permutation_partial_products_and_zs< } /// Computes lookup polynomials for a given challenge. -/// The polynomials hold the value of RE, Sum and Ldc of the Tip5 paper (https://eprint.iacr.org/2023/107.pdf). To reduce their +/// The polynomials hold the value of RE, Sum and Ldc of the Tip5 paper (). To reduce their /// numbers, we batch multiple slots in a single polynomial. Since RE only involves degree one constraints, we can batch /// all the slots of a row. For Sum and Ldc, batching increases the constraint degree, so we bound the number of /// partial polynomials according to `max_quotient_degree_factor`. diff --git a/plonky2/src/plonk/vanishing_poly.rs b/plonky2/src/plonk/vanishing_poly.rs index 2c53efcf..e3ddcf5b 100644 --- a/plonky2/src/plonk/vanishing_poly.rs +++ b/plonky2/src/plonk/vanishing_poly.rs @@ -323,8 +323,8 @@ pub(crate) fn eval_vanishing_poly_base_batch, const res_batch } -/// Evaluates all lookup constraints, based on the logarithmic derivatives paper (https://eprint.iacr.org/2022/1530.pdf), -/// following the Tip5 paper's implementation (https://eprint.iacr.org/2023/107.pdf). +/// Evaluates all lookup constraints, based on the logarithmic derivatives paper (), +/// following the Tip5 paper's implementation (). /// /// There are three polynomials to check: /// - RE ensures the well formation of lookup tables; From cda30847a9c33f23aae1eb659646f6e5023a942e Mon Sep 17 00:00:00 2001 From: Robin Salen Date: Thu, 11 Jan 2024 15:43:51 +0100 Subject: [PATCH 7/7] Apply review --- plonky2/src/fri/mod.rs | 4 +++- plonky2/src/gates/arithmetic_base.rs | 2 +- plonky2/src/gates/arithmetic_extension.rs | 2 +- plonky2/src/gates/gate.rs | 4 ++-- plonky2/src/gates/mod.rs | 2 +- plonky2/src/gates/multiplication_extension.rs | 4 ++-- plonky2/src/iop/target.rs | 4 ++-- plonky2/src/plonk/circuit_builder.rs | 6 +++--- plonky2/src/plonk/circuit_data.rs | 2 ++ plonky2/src/plonk/config.rs | 4 ++-- 10 files changed, 19 insertions(+), 15 deletions(-) diff --git a/plonky2/src/fri/mod.rs b/plonky2/src/fri/mod.rs index ce104ada..207a2ea8 100644 --- a/plonky2/src/fri/mod.rs +++ b/plonky2/src/fri/mod.rs @@ -1,4 +1,6 @@ -//! Fast Reed-Solomon IOP (FRI) protocol and its circuit version +//! Fast Reed-Solomon IOP (FRI) protocol. +//! +//! It provides both a native implementation and an in-circuit version //! of the FRI verifier for recursive proof composition. use alloc::vec::Vec; diff --git a/plonky2/src/gates/arithmetic_base.rs b/plonky2/src/gates/arithmetic_base.rs index e06c58af..dfdd87e8 100644 --- a/plonky2/src/gates/arithmetic_base.rs +++ b/plonky2/src/gates/arithmetic_base.rs @@ -21,7 +21,7 @@ use crate::plonk::vars::{ use crate::util::serialization::{Buffer, IoResult, Read, Write}; /// A gate which can perform a weighted multiply-add, i.e. `result = c0.x.y + c1.z`. If the config -/// supports enough routed wires, it can support several such operations in one gate. +/// has enough routed wires, it can support several such operations in one gate. #[derive(Debug, Clone)] pub struct ArithmeticGate { /// Number of arithmetic operations performed by an arithmetic gate. diff --git a/plonky2/src/gates/arithmetic_extension.rs b/plonky2/src/gates/arithmetic_extension.rs index 37482a5d..a19c6b4a 100644 --- a/plonky2/src/gates/arithmetic_extension.rs +++ b/plonky2/src/gates/arithmetic_extension.rs @@ -17,7 +17,7 @@ use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; use crate::util::serialization::{Buffer, IoResult, Read, Write}; /// A gate which can perform a weighted multiply-add, i.e. `result = c0.x.y + c1.z`. If the config -/// supports enough routed wires, it can support several such operations in one gate. +/// has enough routed wires, it can support several such operations in one gate. #[derive(Debug, Clone)] pub struct ArithmeticExtensionGate { /// Number of arithmetic operations performed by an arithmetic gate. diff --git a/plonky2/src/gates/gate.rs b/plonky2/src/gates/gate.rs index baf26f8c..3087b74c 100644 --- a/plonky2/src/gates/gate.rs +++ b/plonky2/src/gates/gate.rs @@ -41,7 +41,7 @@ use crate::util::serialization::{Buffer, IoResult}; /// instance, to define a multiplication, one can set q_M=1, q_L=q_R=0, q_O = -1 and q_C = 0. /// Hence, the gate equation simplifies to a.b - c = 0, or a.b = c. /// -/// However, such gate is fairly limited for more complex computations. Hence, when a computation may +/// However, such a gate is fairly limited for more complex computations. Hence, when a computation may /// require too many of these "vanilla" gates, or when a computation arises often within the same circuit, /// one may want to construct a tailored custom gate. These custom gates can use more selectors and are /// not necessarily limited to 2 inputs + 1 output = 3 wires. @@ -63,7 +63,7 @@ pub trait Gate, const D: usize>: 'static + Send + S where Self: Sized; - /// Defines the constraints that enforce the statement represented by this gate. + /// Defines and evaluates the constraints that enforce the statement represented by this gate. /// Constraints must be defined in the extension of this custom gate base field. fn eval_unfiltered(&self, vars: EvaluationVars) -> Vec; diff --git a/plonky2/src/gates/mod.rs b/plonky2/src/gates/mod.rs index 446f1aed..b490e12e 100644 --- a/plonky2/src/gates/mod.rs +++ b/plonky2/src/gates/mod.rs @@ -14,7 +14,7 @@ //! instance, to define a multiplication, one can set q_M=1, q_L=q_R=0, q_O = -1 and q_C = 0. //! Hence, the gate equation simplifies to a.b - c = 0, or a.b = c. //! -//! However, such gate is fairly limited for more complex computations. Hence, when a computation may +//! However, such a gate is fairly limited for more complex computations. Hence, when a computation may //! require too many of these "vanilla" gates, or when a computation arises often within the same circuit, //! one may want to construct a tailored custom gate. These custom gates can use more selectors and are //! not necessarily limited to 2 inputs + 1 output = 3 wires. diff --git a/plonky2/src/gates/multiplication_extension.rs b/plonky2/src/gates/multiplication_extension.rs index 1d85817a..3f9fd8fe 100644 --- a/plonky2/src/gates/multiplication_extension.rs +++ b/plonky2/src/gates/multiplication_extension.rs @@ -16,8 +16,8 @@ use crate::plonk::circuit_data::{CircuitConfig, CommonCircuitData}; use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; use crate::util::serialization::{Buffer, IoResult, Read, Write}; -/// A gate which can perform a weighted multiplication, i.e. `result = c0.x.y`. If the config -/// supports enough routed wires, it can support several such operations in one gate. +/// A gate which can perform a weighted multiplication, i.e. `result = c0.x.y` on [`ExtensionTarget`]. +/// If the config has enough routed wires, it can support several such operations in one gate. #[derive(Debug, Clone)] pub struct MulExtensionGate { /// Number of multiplications performed by the gate. diff --git a/plonky2/src/iop/target.rs b/plonky2/src/iop/target.rs index b1fe9bf9..705941e0 100644 --- a/plonky2/src/iop/target.rs +++ b/plonky2/src/iop/target.rs @@ -17,8 +17,8 @@ use crate::plonk::circuit_data::CircuitConfig; /// the [PartialWitness](crate::iop::witness::PartialWitness) interface. /// /// There are different "variants" of the `Target` type, namely [`ExtensionTarget`], -/// [ExtensionAlgebraTarget](crate::iop::ext_target::ExtensionAlgebraTarget), but the `Target` -/// type is the default one for most circuits verifying some simple statement. +/// [ExtensionAlgebraTarget](crate::iop::ext_target::ExtensionAlgebraTarget). +/// The `Target` type is the default one for most circuits verifying some simple statement. #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Serialize, Deserialize)] pub enum Target { /// A target that has a fixed location in the witness (seen as a `degree x num_wires` grid). diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index 227af85b..2e0904e4 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -486,7 +486,7 @@ impl, const D: usize> CircuitBuilder { } /// Adds a gate type to the set of gates to be used in this circuit. This can be useful - /// in conditional recursion to uniformize the gates set of the different circuits. + /// in conditional recursion to uniformize the set of gates of the different circuits. pub fn add_gate_to_gate_set(&mut self, gate: GateRef) { self.gates.insert(gate); } @@ -575,12 +575,12 @@ impl, const D: usize> CircuitBuilder { self.constant(F::NEG_ONE) } - /// Returns a rootable boolean target set to false. + /// Returns a routable boolean target set to false. pub fn _false(&mut self) -> BoolTarget { BoolTarget::new_unsafe(self.zero()) } - /// Returns a rootable boolean target set to true. + /// Returns a routable boolean target set to true. pub fn _true(&mut self) -> BoolTarget { BoolTarget::new_unsafe(self.one()) } diff --git a/plonky2/src/plonk/circuit_data.rs b/plonky2/src/plonk/circuit_data.rs index 4a2efe06..d9847f4b 100644 --- a/plonky2/src/plonk/circuit_data.rs +++ b/plonky2/src/plonk/circuit_data.rs @@ -66,6 +66,8 @@ pub struct CircuitConfig { /// This allows copy constraints, i.e. enforcing that two distant values in a circuit are equal. /// Non-routed wires are called advice wires. pub num_routed_wires: usize, + /// The number of constants that can be used per gate. If a gate requires more constants than the config + /// allows, the [`CircuitBuilder`] will complain when trying to add this gate to its set of gates. pub num_constants: usize, /// Whether to use a dedicated gate for base field arithmetic, rather than using a single gate /// for both base field and extension field arithmetic. diff --git a/plonky2/src/plonk/config.rs b/plonky2/src/plonk/config.rs index c4e73356..1ed40c40 100644 --- a/plonky2/src/plonk/config.rs +++ b/plonky2/src/plonk/config.rs @@ -3,8 +3,8 @@ //! This module defines a [`Hasher`] trait as well as its recursive //! counterpart [`AlgebraicHasher`] for in-circuit hashing. It also //! provides concrete configurations, one fully recursive leveraging -//! Poseidon hash function both internally and natively, and one mixing -//! Poseidon internally and truncated Keccak externally. +//! the Poseidon hash function both internally and natively, and one +//! mixing Poseidon internally and truncated Keccak externally. use alloc::vec; use alloc::vec::Vec;