mirror of https://github.com/zcash/orchard.git
Replace `UtilitiesInstructions` usage with a dedicated helper
The new helper enables returning typed `AssignedCell`s, rather than only `AssignedCell<F, F>`.
This commit is contained in:
parent
314728aada
commit
0bad10d3eb
|
@ -4,7 +4,7 @@ use core::fmt;
|
||||||
|
|
||||||
use group::{Curve, GroupEncoding};
|
use group::{Curve, GroupEncoding};
|
||||||
use halo2_proofs::{
|
use halo2_proofs::{
|
||||||
circuit::{floor_planner, AssignedCell, Layouter},
|
circuit::{floor_planner, Layouter},
|
||||||
plonk::{
|
plonk::{
|
||||||
self, Advice, Column, Constraints, Expression, Instance as InstanceColumn, Selector,
|
self, Advice, Column, Constraints, Expression, Instance as InstanceColumn, Selector,
|
||||||
SingleVerifier,
|
SingleVerifier,
|
||||||
|
@ -18,7 +18,10 @@ use rand::RngCore;
|
||||||
|
|
||||||
use self::{
|
use self::{
|
||||||
commit_ivk::{CommitIvkChip, CommitIvkConfig},
|
commit_ivk::{CommitIvkChip, CommitIvkConfig},
|
||||||
gadget::add_chip::{AddChip, AddConfig},
|
gadget::{
|
||||||
|
add_chip::{AddChip, AddConfig},
|
||||||
|
assign_free_advice,
|
||||||
|
},
|
||||||
note_commit::NoteCommitConfig,
|
note_commit::NoteCommitConfig,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -53,7 +56,7 @@ use halo2_gadgets::{
|
||||||
MerklePath,
|
MerklePath,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
utilities::{lookup_range_check::LookupRangeCheckConfig, UtilitiesInstructions},
|
utilities::lookup_range_check::LookupRangeCheckConfig,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod commit_ivk;
|
mod commit_ivk;
|
||||||
|
@ -118,10 +121,6 @@ pub struct Circuit {
|
||||||
pub(crate) rcv: Option<ValueCommitTrapdoor>,
|
pub(crate) rcv: Option<ValueCommitTrapdoor>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UtilitiesInstructions<pallas::Base> for Circuit {
|
|
||||||
type Var = AssignedCell<pallas::Base, pallas::Base>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl plonk::Circuit<pallas::Base> for Circuit {
|
impl plonk::Circuit<pallas::Base> for Circuit {
|
||||||
type Config = Config;
|
type Config = Config;
|
||||||
type FloorPlanner = floor_planner::V1;
|
type FloorPlanner = floor_planner::V1;
|
||||||
|
@ -332,14 +331,14 @@ impl plonk::Circuit<pallas::Base> for Circuit {
|
||||||
// Witness private inputs that are used across multiple checks.
|
// 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) = {
|
let (psi_old, rho_old, cm_old, g_d_old, ak_P, nk, v_old, v_new) = {
|
||||||
// Witness psi_old
|
// Witness psi_old
|
||||||
let psi_old = self.load_private(
|
let psi_old = assign_free_advice(
|
||||||
layouter.namespace(|| "witness psi_old"),
|
layouter.namespace(|| "witness psi_old"),
|
||||||
config.advices[0],
|
config.advices[0],
|
||||||
self.psi_old,
|
self.psi_old,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Witness rho_old
|
// Witness rho_old
|
||||||
let rho_old = self.load_private(
|
let rho_old = assign_free_advice(
|
||||||
layouter.namespace(|| "witness rho_old"),
|
layouter.namespace(|| "witness rho_old"),
|
||||||
config.advices[0],
|
config.advices[0],
|
||||||
self.rho_old.map(|rho| rho.0),
|
self.rho_old.map(|rho| rho.0),
|
||||||
|
@ -368,21 +367,21 @@ impl plonk::Circuit<pallas::Base> for Circuit {
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Witness nk.
|
// Witness nk.
|
||||||
let nk = self.load_private(
|
let nk = assign_free_advice(
|
||||||
layouter.namespace(|| "witness nk"),
|
layouter.namespace(|| "witness nk"),
|
||||||
config.advices[0],
|
config.advices[0],
|
||||||
self.nk.map(|nk| nk.inner()),
|
self.nk.map(|nk| nk.inner()),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Witness v_old.
|
// Witness v_old.
|
||||||
let v_old = self.load_private(
|
let v_old = assign_free_advice(
|
||||||
layouter.namespace(|| "witness v_old"),
|
layouter.namespace(|| "witness v_old"),
|
||||||
config.advices[0],
|
config.advices[0],
|
||||||
self.v_old.map(|v_old| pallas::Base::from(v_old.inner())),
|
self.v_old.map(|v_old| pallas::Base::from(v_old.inner())),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Witness v_new.
|
// Witness v_new.
|
||||||
let v_new = self.load_private(
|
let v_new = assign_free_advice(
|
||||||
layouter.namespace(|| "witness v_new"),
|
layouter.namespace(|| "witness v_new"),
|
||||||
config.advices[0],
|
config.advices[0],
|
||||||
self.v_new.map(|v_new| pallas::Base::from(v_new.inner())),
|
self.v_new.map(|v_new| pallas::Base::from(v_new.inner())),
|
||||||
|
@ -426,12 +425,12 @@ impl plonk::Circuit<pallas::Base> for Circuit {
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
let magnitude = self.load_private(
|
let magnitude = assign_free_advice(
|
||||||
layouter.namespace(|| "v_net magnitude"),
|
layouter.namespace(|| "v_net magnitude"),
|
||||||
config.advices[9],
|
config.advices[9],
|
||||||
magnitude_sign.map(|m_s| m_s.0),
|
magnitude_sign.map(|m_s| m_s.0),
|
||||||
)?;
|
)?;
|
||||||
let sign = self.load_private(
|
let sign = assign_free_advice(
|
||||||
layouter.namespace(|| "v_net sign"),
|
layouter.namespace(|| "v_net sign"),
|
||||||
config.advices[9],
|
config.advices[9],
|
||||||
magnitude_sign.map(|m_s| m_s.1),
|
magnitude_sign.map(|m_s| m_s.1),
|
||||||
|
@ -582,7 +581,7 @@ impl plonk::Circuit<pallas::Base> for Circuit {
|
||||||
let rho_new = nf_old.inner().clone();
|
let rho_new = nf_old.inner().clone();
|
||||||
|
|
||||||
// Witness psi_new
|
// Witness psi_new
|
||||||
let psi_new = self.load_private(
|
let psi_new = assign_free_advice(
|
||||||
layouter.namespace(|| "witness psi_new"),
|
layouter.namespace(|| "witness psi_new"),
|
||||||
config.advices[0],
|
config.advices[0],
|
||||||
self.psi_new,
|
self.psi_new,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
//! Gadgets used in the Orchard circuit.
|
//! Gadgets used in the Orchard circuit.
|
||||||
|
|
||||||
|
use ff::Field;
|
||||||
use pasta_curves::pallas;
|
use pasta_curves::pallas;
|
||||||
|
|
||||||
use super::commit_ivk::CommitIvkChip;
|
use super::commit_ivk::CommitIvkChip;
|
||||||
|
@ -18,7 +19,7 @@ use halo2_gadgets::{
|
||||||
use halo2_proofs::{
|
use halo2_proofs::{
|
||||||
arithmetic::FieldExt,
|
arithmetic::FieldExt,
|
||||||
circuit::{AssignedCell, Chip, Layouter},
|
circuit::{AssignedCell, Chip, Layouter},
|
||||||
plonk,
|
plonk::{self, Advice, Assigned, Column},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(in crate::circuit) mod add_chip;
|
pub(in crate::circuit) mod add_chip;
|
||||||
|
@ -76,6 +77,32 @@ pub(in crate::circuit) trait AddInstruction<F: FieldExt>: Chip<F> {
|
||||||
) -> Result<AssignedCell<F, F>, plonk::Error>;
|
) -> Result<AssignedCell<F, F>, 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<F: Field, V: Copy>(
|
||||||
|
mut layouter: impl Layouter<F>,
|
||||||
|
column: Column<Advice>,
|
||||||
|
value: Option<V>,
|
||||||
|
) -> Result<AssignedCell<V, F>, plonk::Error>
|
||||||
|
where
|
||||||
|
for<'v> Assigned<F>: 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)].
|
/// `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
|
/// [Section 5.4.8.3 Homomorphic Pedersen commitments (Sapling and Orchard)]: https://zips.z.cash/protocol/protocol.pdf#concretehomomorphiccommit
|
||||||
|
|
|
@ -1488,9 +1488,12 @@ mod tests {
|
||||||
use core::iter;
|
use core::iter;
|
||||||
|
|
||||||
use super::NoteCommitConfig;
|
use super::NoteCommitConfig;
|
||||||
use crate::constants::{
|
use crate::{
|
||||||
fixed_bases::NOTE_COMMITMENT_PERSONALIZATION, OrchardCommitDomains, OrchardFixedBases,
|
circuit::gadget::assign_free_advice,
|
||||||
OrchardHashDomains, L_ORCHARD_BASE, L_VALUE, T_Q,
|
constants::{
|
||||||
|
fixed_bases::NOTE_COMMITMENT_PERSONALIZATION, OrchardCommitDomains, OrchardFixedBases,
|
||||||
|
OrchardHashDomains, L_ORCHARD_BASE, L_VALUE, T_Q,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use halo2_gadgets::{
|
use halo2_gadgets::{
|
||||||
ecc::{
|
ecc::{
|
||||||
|
@ -1499,13 +1502,13 @@ mod tests {
|
||||||
},
|
},
|
||||||
primitives::sinsemilla::CommitDomain,
|
primitives::sinsemilla::CommitDomain,
|
||||||
sinsemilla::chip::SinsemillaChip,
|
sinsemilla::chip::SinsemillaChip,
|
||||||
utilities::{lookup_range_check::LookupRangeCheckConfig, UtilitiesInstructions},
|
utilities::lookup_range_check::LookupRangeCheckConfig,
|
||||||
};
|
};
|
||||||
|
|
||||||
use ff::{Field, PrimeField, PrimeFieldBits};
|
use ff::{Field, PrimeField, PrimeFieldBits};
|
||||||
use group::Curve;
|
use group::Curve;
|
||||||
use halo2_proofs::{
|
use halo2_proofs::{
|
||||||
circuit::{AssignedCell, Layouter, SimpleFloorPlanner},
|
circuit::{Layouter, SimpleFloorPlanner},
|
||||||
dev::MockProver,
|
dev::MockProver,
|
||||||
plonk::{Circuit, ConstraintSystem, Error},
|
plonk::{Circuit, ConstraintSystem, Error},
|
||||||
};
|
};
|
||||||
|
@ -1528,10 +1531,6 @@ mod tests {
|
||||||
psi: Option<pallas::Base>,
|
psi: Option<pallas::Base>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UtilitiesInstructions<pallas::Base> for MyCircuit {
|
|
||||||
type Var = AssignedCell<pallas::Base, pallas::Base>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Circuit<pallas::Base> for MyCircuit {
|
impl Circuit<pallas::Base> for MyCircuit {
|
||||||
type Config = (NoteCommitConfig, EccConfig<OrchardFixedBases>);
|
type Config = (NoteCommitConfig, EccConfig<OrchardFixedBases>);
|
||||||
type FloorPlanner = SimpleFloorPlanner;
|
type FloorPlanner = SimpleFloorPlanner;
|
||||||
|
@ -1669,7 +1668,7 @@ mod tests {
|
||||||
pallas::Base::from(rng.next_u64())
|
pallas::Base::from(rng.next_u64())
|
||||||
};
|
};
|
||||||
let value_var = {
|
let value_var = {
|
||||||
self.load_private(
|
assign_free_advice(
|
||||||
layouter.namespace(|| "witness value"),
|
layouter.namespace(|| "witness value"),
|
||||||
note_commit_config.advices[0],
|
note_commit_config.advices[0],
|
||||||
Some(value),
|
Some(value),
|
||||||
|
@ -1677,14 +1676,14 @@ mod tests {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Witness rho
|
// Witness rho
|
||||||
let rho = self.load_private(
|
let rho = assign_free_advice(
|
||||||
layouter.namespace(|| "witness rho"),
|
layouter.namespace(|| "witness rho"),
|
||||||
note_commit_config.advices[0],
|
note_commit_config.advices[0],
|
||||||
self.rho,
|
self.rho,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Witness psi
|
// Witness psi
|
||||||
let psi = self.load_private(
|
let psi = assign_free_advice(
|
||||||
layouter.namespace(|| "witness psi"),
|
layouter.namespace(|| "witness psi"),
|
||||||
note_commit_config.advices[0],
|
note_commit_config.advices[0],
|
||||||
self.psi,
|
self.psi,
|
||||||
|
|
Loading…
Reference in New Issue