From 3b922f8f486a3ea1f56522eb79b28024448630a8 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Fri, 29 Apr 2022 20:05:00 +0000 Subject: [PATCH] Extract a `ValueCommit^Orchard` gadget from the circuit --- src/circuit.rs | 29 ++++++++------------------ src/circuit/gadget.rs | 47 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 53 insertions(+), 23 deletions(-) diff --git a/src/circuit.rs b/src/circuit.rs index 814ac27a..c9609048 100644 --- a/src/circuit.rs +++ b/src/circuit.rs @@ -24,7 +24,7 @@ use self::{ use crate::{ constants::{ OrchardCommitDomains, OrchardFixedBases, OrchardFixedBasesFull, OrchardHashDomains, - ValueCommitV, MERKLE_DEPTH_ORCHARD, + MERKLE_DEPTH_ORCHARD, }, keys::{ CommitIvkRandomness, DiversifiedTransmissionKey, NullifierDerivingKey, SpendValidatingKey, @@ -42,7 +42,7 @@ use crate::{ use halo2_gadgets::{ ecc::{ chip::{EccChip, EccConfig}, - FixedPoint, FixedPointShort, NonIdentityPoint, Point, + FixedPoint, NonIdentityPoint, Point, }, poseidon::{Pow5Chip as PoseidonChip, Pow5Config as PoseidonConfig}, primitives::poseidon, @@ -436,25 +436,12 @@ impl plonk::Circuit for Circuit { (magnitude, sign) }; - // commitment = [v_net] ValueCommitV - let (commitment, _) = { - let value_commit_v = ValueCommitV; - let value_commit_v = FixedPointShort::from_inner(ecc_chip.clone(), value_commit_v); - value_commit_v.mul(layouter.namespace(|| "[v_net] ValueCommitV"), v_net.clone())? - }; - - // blind = [rcv] ValueCommitR - let (blind, _rcv) = { - let rcv = self.rcv.as_ref().map(|rcv| rcv.inner()); - let value_commit_r = OrchardFixedBasesFull::ValueCommitR; - let value_commit_r = FixedPoint::from_inner(ecc_chip.clone(), value_commit_r); - - // [rcv] ValueCommitR - value_commit_r.mul(layouter.namespace(|| "[rcv] ValueCommitR"), rcv)? - }; - - // [v_net] ValueCommitV + [rcv] ValueCommitR - let cv_net = commitment.add(layouter.namespace(|| "cv_net"), &blind)?; + let cv_net = gadget::value_commit_orchard( + layouter.namespace(|| "cv_net = ValueCommit^Orchard_rcv(v_net)"), + ecc_chip.clone(), + v_net.clone(), + self.rcv.as_ref().map(|rcv| rcv.inner()), + )?; // Constrain cv_net to equal public input layouter.constrain_instance(cv_net.inner().x().cell(), config.primary, CV_NET_X)?; diff --git a/src/circuit/gadget.rs b/src/circuit/gadget.rs index 7cc0fc89..98cde020 100644 --- a/src/circuit/gadget.rs +++ b/src/circuit/gadget.rs @@ -2,9 +2,14 @@ use pasta_curves::pallas; -use crate::constants::{NullifierK, OrchardCommitDomains, OrchardFixedBases, OrchardHashDomains}; +use crate::constants::{ + NullifierK, OrchardCommitDomains, OrchardFixedBases, OrchardFixedBasesFull, OrchardHashDomains, + ValueCommitV, +}; use halo2_gadgets::{ - ecc::{chip::EccChip, EccInstructions, FixedPointBaseField, Point, X}, + ecc::{ + chip::EccChip, EccInstructions, FixedPoint, FixedPointBaseField, FixedPointShort, Point, X, + }, poseidon::{Hash as PoseidonHash, PoseidonSpongeInstructions, Pow5Chip as PoseidonChip}, primitives::poseidon::{self, ConstantLength}, sinsemilla::{chip::SinsemillaChip, merkle::chip::MerkleChip}, @@ -66,6 +71,44 @@ pub(in crate::circuit) trait AddInstruction: Chip { ) -> Result, plonk::Error>; } +/// `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 +pub(in crate::circuit) fn value_commit_orchard< + EccChip: EccInstructions< + pallas::Affine, + FixedPoints = OrchardFixedBases, + Var = AssignedCell, + >, +>( + mut layouter: impl Layouter, + ecc_chip: EccChip, + v: ( + AssignedCell, + AssignedCell, + ), + rcv: Option, +) -> Result, plonk::Error> { + // commitment = [v] ValueCommitV + let (commitment, _) = { + let value_commit_v = ValueCommitV; + let value_commit_v = FixedPointShort::from_inner(ecc_chip.clone(), value_commit_v); + value_commit_v.mul(layouter.namespace(|| "[v] ValueCommitV"), v)? + }; + + // blind = [rcv] ValueCommitR + let (blind, _rcv) = { + let value_commit_r = OrchardFixedBasesFull::ValueCommitR; + let value_commit_r = FixedPoint::from_inner(ecc_chip, value_commit_r); + + // [rcv] ValueCommitR + value_commit_r.mul(layouter.namespace(|| "[rcv] ValueCommitR"), rcv)? + }; + + // [v] ValueCommitV + [rcv] ValueCommitR + commitment.add(layouter.namespace(|| "cv"), &blind) +} + /// `DeriveNullifier` from [Section 4.16: Note Commitments and Nullifiers]. /// /// [Section 4.16: Note Commitments and Nullifiers]: https://zips.z.cash/protocol/protocol.pdf#commitmentsandnullifiers