From 0bad10d3eb671c0438afedb9789df0dfe456c440 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Tue, 3 May 2022 20:02:29 +0000 Subject: [PATCH] Replace `UtilitiesInstructions` usage with a dedicated helper The new helper enables returning typed `AssignedCell`s, rather than only `AssignedCell`. --- src/circuit.rs | 29 ++++++++++++++--------------- src/circuit/gadget.rs | 29 ++++++++++++++++++++++++++++- src/circuit/note_commit.rs | 23 +++++++++++------------ 3 files changed, 53 insertions(+), 28 deletions(-) diff --git a/src/circuit.rs b/src/circuit.rs index 2adb3167..6cf58e11 100644 --- a/src/circuit.rs +++ b/src/circuit.rs @@ -4,7 +4,7 @@ use core::fmt; use group::{Curve, GroupEncoding}; use halo2_proofs::{ - circuit::{floor_planner, AssignedCell, Layouter}, + circuit::{floor_planner, Layouter}, plonk::{ self, Advice, Column, Constraints, Expression, Instance as InstanceColumn, Selector, SingleVerifier, @@ -18,7 +18,10 @@ use rand::RngCore; use self::{ commit_ivk::{CommitIvkChip, CommitIvkConfig}, - gadget::add_chip::{AddChip, AddConfig}, + gadget::{ + add_chip::{AddChip, AddConfig}, + assign_free_advice, + }, note_commit::NoteCommitConfig, }; use crate::{ @@ -53,7 +56,7 @@ use halo2_gadgets::{ MerklePath, }, }, - utilities::{lookup_range_check::LookupRangeCheckConfig, UtilitiesInstructions}, + utilities::lookup_range_check::LookupRangeCheckConfig, }; mod commit_ivk; @@ -118,10 +121,6 @@ pub struct Circuit { pub(crate) rcv: Option, } -impl UtilitiesInstructions for Circuit { - type Var = AssignedCell; -} - impl plonk::Circuit for Circuit { type Config = Config; type FloorPlanner = floor_planner::V1; @@ -332,14 +331,14 @@ impl plonk::Circuit for Circuit { // Witness private inputs that are used across multiple checks. let (psi_old, rho_old, cm_old, g_d_old, ak_P, nk, v_old, v_new) = { // Witness psi_old - let psi_old = self.load_private( + let psi_old = assign_free_advice( layouter.namespace(|| "witness psi_old"), config.advices[0], self.psi_old, )?; // Witness rho_old - let rho_old = self.load_private( + let rho_old = assign_free_advice( layouter.namespace(|| "witness rho_old"), config.advices[0], self.rho_old.map(|rho| rho.0), @@ -368,21 +367,21 @@ impl plonk::Circuit for Circuit { )?; // Witness nk. - let nk = self.load_private( + let nk = assign_free_advice( layouter.namespace(|| "witness nk"), config.advices[0], self.nk.map(|nk| nk.inner()), )?; // Witness v_old. - let v_old = self.load_private( + let v_old = assign_free_advice( layouter.namespace(|| "witness v_old"), config.advices[0], self.v_old.map(|v_old| pallas::Base::from(v_old.inner())), )?; // Witness v_new. - let v_new = self.load_private( + let v_new = assign_free_advice( layouter.namespace(|| "witness v_new"), config.advices[0], self.v_new.map(|v_new| pallas::Base::from(v_new.inner())), @@ -426,12 +425,12 @@ impl plonk::Circuit for Circuit { ) }); - let magnitude = self.load_private( + let magnitude = assign_free_advice( layouter.namespace(|| "v_net magnitude"), config.advices[9], magnitude_sign.map(|m_s| m_s.0), )?; - let sign = self.load_private( + let sign = assign_free_advice( layouter.namespace(|| "v_net sign"), config.advices[9], magnitude_sign.map(|m_s| m_s.1), @@ -582,7 +581,7 @@ impl plonk::Circuit for Circuit { let rho_new = nf_old.inner().clone(); // Witness psi_new - let psi_new = self.load_private( + let psi_new = assign_free_advice( layouter.namespace(|| "witness psi_new"), config.advices[0], self.psi_new, diff --git a/src/circuit/gadget.rs b/src/circuit/gadget.rs index e2b2fc07..fb471a94 100644 --- a/src/circuit/gadget.rs +++ b/src/circuit/gadget.rs @@ -1,5 +1,6 @@ //! Gadgets used in the Orchard circuit. +use ff::Field; use pasta_curves::pallas; use super::commit_ivk::CommitIvkChip; @@ -18,7 +19,7 @@ use halo2_gadgets::{ use halo2_proofs::{ arithmetic::FieldExt, circuit::{AssignedCell, Chip, Layouter}, - plonk, + plonk::{self, Advice, Assigned, Column}, }; pub(in crate::circuit) mod add_chip; @@ -76,6 +77,32 @@ pub(in crate::circuit) trait AddInstruction: Chip { ) -> Result, plonk::Error>; } +/// Witnesses the given value in a standalone region. +/// +/// Usages of this helper are technically superfluous, as the single-cell region is only +/// ever used in equality constraints. We could eliminate them with a write-on-copy +/// abstraction (https://github.com/zcash/halo2/issues/334). +pub(in crate::circuit) fn assign_free_advice( + mut layouter: impl Layouter, + column: Column, + value: Option, +) -> Result, plonk::Error> +where + for<'v> Assigned: From<&'v V>, +{ + layouter.assign_region( + || "load private", + |mut region| { + region.assign_advice( + || "load private", + column, + 0, + || value.ok_or(plonk::Error::Synthesis), + ) + }, + ) +} + /// `ValueCommit^Orchard` from [Section 5.4.8.3 Homomorphic Pedersen commitments (Sapling and Orchard)]. /// /// [Section 5.4.8.3 Homomorphic Pedersen commitments (Sapling and Orchard)]: https://zips.z.cash/protocol/protocol.pdf#concretehomomorphiccommit diff --git a/src/circuit/note_commit.rs b/src/circuit/note_commit.rs index 01a0afbf..d98bf0d6 100644 --- a/src/circuit/note_commit.rs +++ b/src/circuit/note_commit.rs @@ -1488,9 +1488,12 @@ mod tests { use core::iter; use super::NoteCommitConfig; - use crate::constants::{ - fixed_bases::NOTE_COMMITMENT_PERSONALIZATION, OrchardCommitDomains, OrchardFixedBases, - OrchardHashDomains, L_ORCHARD_BASE, L_VALUE, T_Q, + use crate::{ + circuit::gadget::assign_free_advice, + constants::{ + fixed_bases::NOTE_COMMITMENT_PERSONALIZATION, OrchardCommitDomains, OrchardFixedBases, + OrchardHashDomains, L_ORCHARD_BASE, L_VALUE, T_Q, + }, }; use halo2_gadgets::{ ecc::{ @@ -1499,13 +1502,13 @@ mod tests { }, primitives::sinsemilla::CommitDomain, sinsemilla::chip::SinsemillaChip, - utilities::{lookup_range_check::LookupRangeCheckConfig, UtilitiesInstructions}, + utilities::lookup_range_check::LookupRangeCheckConfig, }; use ff::{Field, PrimeField, PrimeFieldBits}; use group::Curve; use halo2_proofs::{ - circuit::{AssignedCell, Layouter, SimpleFloorPlanner}, + circuit::{Layouter, SimpleFloorPlanner}, dev::MockProver, plonk::{Circuit, ConstraintSystem, Error}, }; @@ -1528,10 +1531,6 @@ mod tests { psi: Option, } - impl UtilitiesInstructions for MyCircuit { - type Var = AssignedCell; - } - impl Circuit for MyCircuit { type Config = (NoteCommitConfig, EccConfig); type FloorPlanner = SimpleFloorPlanner; @@ -1669,7 +1668,7 @@ mod tests { pallas::Base::from(rng.next_u64()) }; let value_var = { - self.load_private( + assign_free_advice( layouter.namespace(|| "witness value"), note_commit_config.advices[0], Some(value), @@ -1677,14 +1676,14 @@ mod tests { }; // Witness rho - let rho = self.load_private( + let rho = assign_free_advice( layouter.namespace(|| "witness rho"), note_commit_config.advices[0], self.rho, )?; // Witness psi - let psi = self.load_private( + let psi = assign_free_advice( layouter.namespace(|| "witness psi"), note_commit_config.advices[0], self.psi,