diff --git a/Cargo.lock b/Cargo.lock index d3dc55a0e..66d8bfd34 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1010,7 +1010,7 @@ dependencies = [ [[package]] name = "halo2_gadgets" version = "0.3.0" -source = "git+https://github.com/QED-it/halo2?branch=orchardzsa-backward-compatability#4cc147385e7cf106b9fab6d6951d66a343899e38" +source = "git+https://github.com/QED-it/halo2?branch=improve-backward-compatability-with-zsa#36a9319487008110aa5f49706917377e405c26c2" dependencies = [ "arrayvec", "bitvec", @@ -1034,7 +1034,7 @@ checksum = "47716fe1ae67969c5e0b2ef826f32db8c3be72be325e1aa3c1951d06b5575ec5" [[package]] name = "halo2_proofs" version = "0.3.0" -source = "git+https://github.com/QED-it/halo2?branch=orchardzsa-backward-compatability#4cc147385e7cf106b9fab6d6951d66a343899e38" +source = "git+https://github.com/QED-it/halo2?branch=improve-backward-compatability-with-zsa#36a9319487008110aa5f49706917377e405c26c2" dependencies = [ "blake2b_simd", "ff", diff --git a/Cargo.toml b/Cargo.toml index 11c9ceb1f..67f1d5d17 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,8 +30,8 @@ half = "=2.2.1" # Last version requires Rust 1.70 ff = "0.13" fpe = "0.6" group = { version = "0.13", features = ["wnaf-memuse"] } -halo2_gadgets = { git = "https://github.com/QED-it/halo2", branch = "orchardzsa-backward-compatability" } -halo2_proofs = { git = "https://github.com/QED-it/halo2", branch = "orchardzsa-backward-compatability", default-features = false, features = ["batch", "floor-planner-v1-legacy-pdqsort"] } +halo2_gadgets = { git = "https://github.com/QED-it/halo2", branch = "improve-backward-compatability-with-zsa" } +halo2_proofs = { git = "https://github.com/QED-it/halo2", branch = "improve-backward-compatability-with-zsa", default-features = false, features = ["batch", "floor-planner-v1-legacy-pdqsort"] } hex = "0.4" k256 = { version = "0.13.0", features = ["arithmetic", "schnorr"] } lazy_static = "1" @@ -58,7 +58,7 @@ plotters = { version = "0.3.0", optional = true } [dev-dependencies] bridgetree = "0.4" criterion = "0.4" # 0.5 depends on clap 4 which has MSRV 1.70 -halo2_gadgets = { git = "https://github.com/QED-it/halo2", branch = "orchardzsa-backward-compatability", features = ["test-dependencies"] } +halo2_gadgets = { git = "https://github.com/QED-it/halo2", branch = "improve-backward-compatability-with-zsa", features = ["test-dependencies"] } proptest = "1.0.0" zcash_note_encryption_zsa = { package = "zcash_note_encryption", version = "0.4", git = "https://github.com/QED-it/zcash_note_encryption", branch = "zsa1", features = ["pre-zip-212"] } incrementalmerkletree = { version = "0.5", features = ["test-dependencies"] } diff --git a/src/circuit.rs b/src/circuit.rs index 80b6d7673..d2a77e11d 100644 --- a/src/circuit.rs +++ b/src/circuit.rs @@ -38,6 +38,7 @@ mod circuit_zsa; pub(in crate::circuit) mod commit_ivk; pub(in crate::circuit) mod gadget; +pub(in crate::circuit) mod orchard_sinsemilla_chip; /// Size of the Orchard circuit. const K: u32 = 11; diff --git a/src/circuit/circuit_vanilla.rs b/src/circuit/circuit_vanilla.rs index 5f9f6423d..04c7da725 100644 --- a/src/circuit/circuit_vanilla.rs +++ b/src/circuit/circuit_vanilla.rs @@ -19,7 +19,7 @@ use halo2_gadgets::{ MerklePath, }, }, - utilities::lookup_range_check::LookupRangeCheckConfig, + utilities::lookup_range_check::{LookupRangeCheck, LookupRangeCheckConfig}, }; use halo2_proofs::{ @@ -143,7 +143,6 @@ impl OrchardCircuit for OrchardVanilla { table_idx, meta.lookup_table_column(), meta.lookup_table_column(), - None, ); // Instance column used for public inputs @@ -179,7 +178,7 @@ impl OrchardCircuit for OrchardVanilla { // We have a lot of free space in the right-most advice columns; use one of them // for all of our range checks. - let range_check = LookupRangeCheckConfig::configure(meta, advices[9], table_idx, None); + let range_check = LookupRangeCheckConfig::configure(meta, advices[9], table_idx); // Configuration for curve point operations. // This uses 10 advice columns and spans the whole circuit. diff --git a/src/circuit/circuit_vanilla/note_commit.rs b/src/circuit/circuit_vanilla/note_commit.rs index 391a8e5ab..c79584fba 100644 --- a/src/circuit/circuit_vanilla/note_commit.rs +++ b/src/circuit/circuit_vanilla/note_commit.rs @@ -24,7 +24,9 @@ use halo2_gadgets::{ CommitDomain, Message, MessagePiece, }, utilities::{ - bool_check, lookup_range_check::LookupRangeCheckConfig, FieldValue, RangeConstrained, + bool_check, + lookup_range_check::{LookupRangeCheck, LookupRangeCheckConfig}, + FieldValue, RangeConstrained, }, }; @@ -2036,7 +2038,7 @@ mod tests { }, sinsemilla::chip::SinsemillaChip, sinsemilla::primitives::CommitDomain, - utilities::lookup_range_check::LookupRangeCheckConfig, + utilities::lookup_range_check::{LookupRangeCheck, LookupRangeCheckConfig}, }; use ff::{Field, PrimeField, PrimeFieldBits}; @@ -2097,7 +2099,6 @@ mod tests { table_idx, meta.lookup_table_column(), meta.lookup_table_column(), - None, ); let lagrange_coeffs = [ meta.fixed_column(), @@ -2110,8 +2111,7 @@ mod tests { meta.fixed_column(), ]; - let range_check = - LookupRangeCheckConfig::configure(meta, advices[9], table_idx, None); + let range_check = LookupRangeCheckConfig::configure(meta, advices[9], table_idx); let sinsemilla_config = SinsemillaChip::< OrchardHashDomains, OrchardCommitDomains, diff --git a/src/circuit/circuit_zsa.rs b/src/circuit/circuit_zsa.rs index 94cfcdd01..35f4a3457 100644 --- a/src/circuit/circuit_zsa.rs +++ b/src/circuit/circuit_zsa.rs @@ -15,16 +15,16 @@ use halo2_gadgets::{ }, poseidon::{primitives as poseidon, Pow5Chip as PoseidonChip, Pow5Config as PoseidonConfig}, sinsemilla::{ - chip::{SinsemillaChip, SinsemillaConfig}, + chip::{SinsemillaChipOptimized, SinsemillaConfig}, merkle::{ - chip::{MerkleChip, MerkleConfig}, + chip::{MerkleChipOptimized, MerkleConfig}, MerklePath, }, }, utilities::{ bool_check, cond_swap::{CondSwapChip, CondSwapConfig}, - lookup_range_check::LookupRangeCheckConfig, + lookup_range_check::{LookupRangeCheckConfigOptimized, PallasLookupConfigOptimized}, }, }; @@ -69,14 +69,32 @@ pub struct Config { q_orchard: Selector, advices: [Column; 10], add_config: AddConfig, - ecc_config: EccConfig, + ecc_config: EccConfig, poseidon_config: PoseidonConfig, - merkle_config_1: MerkleConfig, - merkle_config_2: MerkleConfig, - sinsemilla_config_1: - SinsemillaConfig, - sinsemilla_config_2: - SinsemillaConfig, + merkle_config_1: MerkleConfig< + OrchardHashDomains, + OrchardCommitDomains, + OrchardFixedBases, + PallasLookupConfigOptimized, + >, + merkle_config_2: MerkleConfig< + OrchardHashDomains, + OrchardCommitDomains, + OrchardFixedBases, + PallasLookupConfigOptimized, + >, + sinsemilla_config_1: SinsemillaConfig< + OrchardHashDomains, + OrchardCommitDomains, + OrchardFixedBases, + PallasLookupConfigOptimized, + >, + sinsemilla_config_2: SinsemillaConfig< + OrchardHashDomains, + OrchardCommitDomains, + OrchardFixedBases, + PallasLookupConfigOptimized, + >, commit_ivk_config: CommitIvkConfig, old_note_commit_config: NoteCommitConfig, new_note_commit_config: NoteCommitConfig, @@ -224,7 +242,6 @@ impl OrchardCircuit for OrchardZSA { table_idx, meta.lookup_table_column(), meta.lookup_table_column(), - Some(table_range_check_tag), ); // Instance column used for public inputs @@ -260,17 +277,21 @@ impl OrchardCircuit for OrchardZSA { // We have a lot of free space in the right-most advice columns; use one of them // for all of our range checks. - let range_check = LookupRangeCheckConfig::configure( + let range_check = LookupRangeCheckConfigOptimized::configure_with_tag( meta, advices[9], table_idx, - Some(table_range_check_tag), + table_range_check_tag, ); // Configuration for curve point operations. // This uses 10 advice columns and spans the whole circuit. - let ecc_config = - EccChip::::configure(meta, advices, lagrange_coeffs, range_check); + let ecc_config = EccChip::::configure( + meta, + advices, + lagrange_coeffs, + range_check, + ); // Configuration for the Poseidon hash. let poseidon_config = PoseidonChip::configure::( @@ -288,7 +309,7 @@ impl OrchardCircuit for OrchardZSA { // Since the Sinsemilla config uses only 5 advice columns, // we can fit two instances side-by-side. let (sinsemilla_config_1, merkle_config_1) = { - let sinsemilla_config_1 = SinsemillaChip::configure( + let sinsemilla_config_1 = SinsemillaChipOptimized::configure( meta, advices[..5].try_into().unwrap(), advices[6], @@ -296,7 +317,7 @@ impl OrchardCircuit for OrchardZSA { lookup, range_check, ); - let merkle_config_1 = MerkleChip::configure(meta, sinsemilla_config_1.clone()); + let merkle_config_1 = MerkleChipOptimized::configure(meta, sinsemilla_config_1.clone()); (sinsemilla_config_1, merkle_config_1) }; @@ -306,7 +327,7 @@ impl OrchardCircuit for OrchardZSA { // Since the Sinsemilla config uses only 5 advice columns, // we can fit two instances side-by-side. let (sinsemilla_config_2, merkle_config_2) = { - let sinsemilla_config_2 = SinsemillaChip::configure( + let sinsemilla_config_2 = SinsemillaChipOptimized::configure( meta, advices[5..].try_into().unwrap(), advices[7], @@ -314,7 +335,7 @@ impl OrchardCircuit for OrchardZSA { lookup, range_check, ); - let merkle_config_2 = MerkleChip::configure(meta, sinsemilla_config_2.clone()); + let merkle_config_2 = MerkleChipOptimized::configure(meta, sinsemilla_config_2.clone()); (sinsemilla_config_2, merkle_config_2) }; @@ -360,7 +381,7 @@ impl OrchardCircuit for OrchardZSA { mut layouter: impl Layouter, ) -> Result<(), plonk::Error> { // Load the Sinsemilla generator lookup table used by the whole circuit. - SinsemillaChip::load(config.sinsemilla_config_1.clone(), &mut layouter)?; + SinsemillaChipOptimized::load(config.sinsemilla_config_1.clone(), &mut layouter)?; // Construct the ECC chip. let ecc_chip = config.ecc_chip(); diff --git a/src/circuit/circuit_zsa/gadget.rs b/src/circuit/circuit_zsa/gadget.rs index b21128a32..1ce9d4098 100644 --- a/src/circuit/circuit_zsa/gadget.rs +++ b/src/circuit/circuit_zsa/gadget.rs @@ -14,8 +14,8 @@ use halo2_gadgets::{ primitives::{self as poseidon, ConstantLength}, Hash as PoseidonHash, PoseidonSpongeInstructions, Pow5Chip as PoseidonChip, }, - sinsemilla::{chip::SinsemillaChip, merkle::chip::MerkleChip}, - utilities::cond_swap::CondSwapChip, + sinsemilla::{chip::SinsemillaChipOptimized, merkle::chip::MerkleChipOptimized}, + utilities::{cond_swap::CondSwapChip, lookup_range_check::PallasLookupConfigOptimized}, }; use halo2_proofs::{ circuit::{AssignedCell, Layouter, Value}, @@ -31,32 +31,32 @@ impl super::Config { CommitIvkChip::construct(self.commit_ivk_config.clone()) } - pub(super) fn ecc_chip(&self) -> EccChip { + pub(super) fn ecc_chip(&self) -> EccChip { EccChip::construct(self.ecc_config.clone()) } pub(super) fn sinsemilla_chip_1( &self, - ) -> SinsemillaChip { - SinsemillaChip::construct(self.sinsemilla_config_1.clone()) + ) -> SinsemillaChipOptimized { + SinsemillaChipOptimized::construct(self.sinsemilla_config_1.clone()) } pub(super) fn sinsemilla_chip_2( &self, - ) -> SinsemillaChip { - SinsemillaChip::construct(self.sinsemilla_config_2.clone()) + ) -> SinsemillaChipOptimized { + SinsemillaChipOptimized::construct(self.sinsemilla_config_2.clone()) } pub(super) fn merkle_chip_1( &self, - ) -> MerkleChip { - MerkleChip::construct(self.merkle_config_1.clone()) + ) -> MerkleChipOptimized { + MerkleChipOptimized::construct(self.merkle_config_1.clone()) } pub(super) fn merkle_chip_2( &self, - ) -> MerkleChip { - MerkleChip::construct(self.merkle_config_2.clone()) + ) -> MerkleChipOptimized { + MerkleChipOptimized::construct(self.merkle_config_2.clone()) } pub(super) fn poseidon_chip(&self) -> PoseidonChip { diff --git a/src/circuit/circuit_zsa/note_commit.rs b/src/circuit/circuit_zsa/note_commit.rs index 8247178c9..e0d0e668c 100644 --- a/src/circuit/circuit_zsa/note_commit.rs +++ b/src/circuit/circuit_zsa/note_commit.rs @@ -20,18 +20,20 @@ use halo2_gadgets::{ NonIdentityPoint, Point, ScalarFixed, }, sinsemilla::{ - chip::{SinsemillaChip, SinsemillaConfig}, + chip::{SinsemillaChipOptimized, SinsemillaConfig}, CommitDomain, Message, MessagePiece, }, utilities::{ - bool_check, cond_swap::CondSwapChip, lookup_range_check::LookupRangeCheckConfig, + bool_check, + cond_swap::CondSwapChip, + lookup_range_check::{LookupRangeCheck, PallasLookupConfigOptimized}, FieldValue, RangeConstrained, }, }; type NoteCommitPiece = MessagePiece< pallas::Affine, - SinsemillaChip, + SinsemillaChipOptimized, 10, 253, >; @@ -123,8 +125,8 @@ impl DecomposeB { #[allow(clippy::type_complexity)] fn decompose( - lookup_config: &LookupRangeCheckConfig, - chip: SinsemillaChip, + lookup_config: &PallasLookupConfigOptimized, + chip: SinsemillaChipOptimized, layouter: &mut impl Layouter, g_d: &NonIdentityEccPoint, pk_d: &NonIdentityEccPoint, @@ -268,8 +270,8 @@ impl DecomposeD { #[allow(clippy::type_complexity)] fn decompose( - lookup_config: &LookupRangeCheckConfig, - chip: SinsemillaChip, + lookup_config: &PallasLookupConfigOptimized, + chip: SinsemillaChipOptimized, layouter: &mut impl Layouter, pk_d: &NonIdentityEccPoint, value: &AssignedCell, @@ -390,8 +392,8 @@ impl DecomposeE { #[allow(clippy::type_complexity)] fn decompose( - lookup_config: &LookupRangeCheckConfig, - chip: SinsemillaChip, + lookup_config: &PallasLookupConfigOptimized, + chip: SinsemillaChipOptimized, layouter: &mut impl Layouter, value: &AssignedCell, rho: &AssignedCell, @@ -515,8 +517,8 @@ impl DecomposeG { #[allow(clippy::type_complexity)] fn decompose( - lookup_config: &LookupRangeCheckConfig, - chip: SinsemillaChip, + lookup_config: &PallasLookupConfigOptimized, + chip: SinsemillaChipOptimized, layouter: &mut impl Layouter, rho: &AssignedCell, psi: &AssignedCell, @@ -651,8 +653,8 @@ impl DecomposeH { #[allow(clippy::type_complexity)] fn decompose( - lookup_config: &LookupRangeCheckConfig, - chip: SinsemillaChip, + lookup_config: &PallasLookupConfigOptimized, + chip: SinsemillaChipOptimized, layouter: &mut impl Layouter, psi: &AssignedCell, asset: &NonIdentityEccPoint, @@ -800,7 +802,7 @@ impl DecomposeJ { #[allow(clippy::type_complexity)] fn decompose( - chip: SinsemillaChip, + chip: SinsemillaChipOptimized, layouter: &mut impl Layouter, asset: &NonIdentityEccPoint, ) -> Result< @@ -1596,8 +1598,12 @@ pub struct NoteCommitConfig { psi: PsiCanonicity, y_canon: YCanonicity, advices: [Column; 10], - sinsemilla_config: - SinsemillaConfig, + sinsemilla_config: SinsemillaConfig< + OrchardHashDomains, + OrchardCommitDomains, + OrchardFixedBases, + PallasLookupConfigOptimized, + >, } #[derive(Clone, Debug)] @@ -1615,6 +1621,7 @@ impl NoteCommitChip { OrchardHashDomains, OrchardCommitDomains, OrchardFixedBases, + PallasLookupConfigOptimized, >, ) -> NoteCommitConfig { // Useful constants @@ -1744,8 +1751,8 @@ pub(in crate::circuit) mod gadgets { #[allow(clippy::too_many_arguments)] pub(in crate::circuit) fn note_commit( mut layouter: impl Layouter, - chip: SinsemillaChip, - ecc_chip: EccChip, + chip: SinsemillaChipOptimized, + ecc_chip: EccChip, note_commit_chip: NoteCommitChip, cond_swap_chip: CondSwapChip, g_d: &NonIdentityEccPoint, @@ -1754,9 +1761,10 @@ pub(in crate::circuit) mod gadgets { rho: AssignedCell, psi: AssignedCell, asset: &NonIdentityEccPoint, - rcm: ScalarFixed>, + rcm: ScalarFixed>, is_native_asset: AssignedCell, - ) -> Result>, Error> { + ) -> Result>, Error> + { let lookup_config = chip.config().lookup_config(); // `a` = bits 0..=249 of `x(g_d)` @@ -2090,7 +2098,7 @@ pub(in crate::circuit) mod gadgets { /// - [`g_d` canonicity](https://p.z.cash/orchard-0.1:note-commit-canonicity-g_d?partial) /// - [`y` canonicity](https://p.z.cash/orchard-0.1:note-commit-canonicity-y?partial) fn canon_bitshift_130( - lookup_config: &LookupRangeCheckConfig, + lookup_config: &PallasLookupConfigOptimized, mut layouter: impl Layouter, a: AssignedCell, ) -> Result { @@ -2124,7 +2132,7 @@ pub(in crate::circuit) mod gadgets { /// /// [Specification](https://p.z.cash/orchard-0.1:note-commit-canonicity-pk_d?partial). fn pkd_asset_x_canonicity( - lookup_config: &LookupRangeCheckConfig, + lookup_config: &PallasLookupConfigOptimized, mut layouter: impl Layouter, b_3: RangeConstrained>, c: AssignedCell, @@ -2167,7 +2175,7 @@ pub(in crate::circuit) mod gadgets { /// /// [Specification](https://p.z.cash/orchard-0.1:note-commit-canonicity-rho?partial). fn rho_canonicity( - lookup_config: &LookupRangeCheckConfig, + lookup_config: &PallasLookupConfigOptimized, mut layouter: impl Layouter, e_1: RangeConstrained>, f: AssignedCell, @@ -2208,7 +2216,7 @@ pub(in crate::circuit) mod gadgets { /// /// [Specification](https://p.z.cash/orchard-0.1:note-commit-canonicity-psi?partial). fn psi_canonicity( - lookup_config: &LookupRangeCheckConfig, + lookup_config: &PallasLookupConfigOptimized, mut layouter: impl Layouter, g_1: RangeConstrained>, g_2: AssignedCell, @@ -2250,7 +2258,7 @@ pub(in crate::circuit) mod gadgets { /// - [`y` decomposition](https://p.z.cash/orchard-0.1:note-commit-decomposition-y?partial) /// - [`y` canonicity](https://p.z.cash/orchard-0.1:note-commit-canonicity-y?partial) fn y_canonicity( - lookup_config: &LookupRangeCheckConfig, + lookup_config: &PallasLookupConfigOptimized, y_canon: &YCanonicity, mut layouter: impl Layouter, y: AssignedCell, @@ -2340,10 +2348,10 @@ mod tests { chip::{EccChip, EccConfig}, NonIdentityPoint, ScalarFixed, }, - sinsemilla::chip::SinsemillaChip, + sinsemilla::chip::SinsemillaChipOptimized, utilities::{ cond_swap::{CondSwapChip, CondSwapConfig}, - lookup_range_check::LookupRangeCheckConfig, + lookup_range_check::PallasLookupConfigOptimized, }, }; @@ -2372,7 +2380,7 @@ mod tests { impl Circuit for MyCircuit { type Config = ( NoteCommitConfig, - EccConfig, + EccConfig, CondSwapConfig, ); type FloorPlanner = SimpleFloorPlanner; @@ -2409,7 +2417,6 @@ mod tests { table_idx, meta.lookup_table_column(), meta.lookup_table_column(), - Some(table_range_check_tag), ); let lagrange_coeffs = [ meta.fixed_column(), @@ -2422,13 +2429,13 @@ mod tests { meta.fixed_column(), ]; - let range_check = LookupRangeCheckConfig::configure( + let range_check = PallasLookupConfigOptimized::configure_with_tag( meta, advices[9], table_idx, - Some(table_range_check_tag), + table_range_check_tag, ); - let sinsemilla_config = SinsemillaChip::< + let sinsemilla_config = SinsemillaChipOptimized::< OrchardHashDomains, OrchardCommitDomains, OrchardFixedBases, @@ -2443,12 +2450,13 @@ mod tests { let note_commit_config = NoteCommitChip::configure(meta, advices, sinsemilla_config); - let ecc_config = EccChip::::configure( - meta, - advices, - lagrange_coeffs, - range_check, - ); + let ecc_config = + EccChip::::configure( + meta, + advices, + lagrange_coeffs, + range_check, + ); let cond_swap_config = CondSwapChip::configure(meta, advices[0..5].try_into().unwrap()); @@ -2464,15 +2472,18 @@ mod tests { let (note_commit_config, ecc_config, cond_swap_config) = config; // Load the Sinsemilla generator lookup table used by the whole circuit. - SinsemillaChip::< - OrchardHashDomains, - OrchardCommitDomains, - OrchardFixedBases, - >::load(note_commit_config.sinsemilla_config.clone(), &mut layouter)?; + SinsemillaChipOptimized::< + OrchardHashDomains, + OrchardCommitDomains, + OrchardFixedBases, + >::load( + note_commit_config.sinsemilla_config.clone(), &mut layouter + )?; // Construct a Sinsemilla chip - let sinsemilla_chip = - SinsemillaChip::construct(note_commit_config.sinsemilla_config.clone()); + let sinsemilla_chip = SinsemillaChipOptimized::construct( + note_commit_config.sinsemilla_config.clone(), + ); // Construct an ECC chip let ecc_chip = EccChip::construct(ecc_config); diff --git a/src/circuit/circuit_zsa/value_commit_orchard.rs b/src/circuit/circuit_zsa/value_commit_orchard.rs index a183ad77e..676184fa6 100644 --- a/src/circuit/circuit_zsa/value_commit_orchard.rs +++ b/src/circuit/circuit_zsa/value_commit_orchard.rs @@ -8,7 +8,8 @@ pub(in crate::circuit) mod gadgets { }; use halo2_gadgets::{ ecc::{chip::EccChip, FixedPoint, NonIdentityPoint, Point, ScalarFixed, ScalarVar}, - sinsemilla::{self, chip::SinsemillaChip}, + sinsemilla::{self, chip::SinsemillaChipOptimized}, + utilities::lookup_range_check::{LookupRangeCheck, PallasLookupConfigOptimized}, }; use halo2_proofs::{ circuit::{AssignedCell, Chip, Layouter}, @@ -20,19 +21,25 @@ pub(in crate::circuit) mod gadgets { /// [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( mut layouter: impl Layouter, - sinsemilla_chip: SinsemillaChip< + sinsemilla_chip: SinsemillaChipOptimized< OrchardHashDomains, OrchardCommitDomains, OrchardFixedBases, >, - ecc_chip: EccChip, + ecc_chip: EccChip, v_net_magnitude_sign: ( AssignedCell, AssignedCell, ), - rcv: ScalarFixed>, - asset: NonIdentityPoint>, - ) -> Result>, plonk::Error> { + rcv: ScalarFixed>, + asset: NonIdentityPoint< + pallas::Affine, + EccChip, + >, + ) -> Result< + Point>, + plonk::Error, + > { // Check that magnitude is 64 bits. { let lookup_config = sinsemilla_chip.config().lookup_config(); @@ -105,8 +112,10 @@ mod tests { chip::{EccChip, EccConfig}, NonIdentityPoint, ScalarFixed, }, - sinsemilla::chip::{SinsemillaChip, SinsemillaConfig}, - utilities::lookup_range_check::LookupRangeCheckConfig, + sinsemilla::chip::{SinsemillaChipOptimized, SinsemillaConfig}, + utilities::lookup_range_check::{ + LookupRangeCheckConfigOptimized, PallasLookupConfigOptimized, + }, }; use group::Curve; @@ -125,11 +134,15 @@ mod tests { pub struct MyConfig { primary: Column, advices: [Column; 10], - ecc_config: EccConfig, + ecc_config: EccConfig, // Sinsemilla config is only used to initialize the table_idx lookup table in the same // way as in the Orchard circuit - sinsemilla_config: - SinsemillaConfig, + sinsemilla_config: SinsemillaConfig< + OrchardHashDomains, + OrchardCommitDomains, + OrchardFixedBases, + PallasLookupConfigOptimized, + >, } #[derive(Default)] struct MyCircuit { @@ -176,7 +189,6 @@ mod tests { table_idx, meta.lookup_table_column(), meta.lookup_table_column(), - Some(table_range_check_tag), ); let lagrange_coeffs = [ @@ -191,14 +203,14 @@ mod tests { ]; meta.enable_constant(lagrange_coeffs[0]); - let range_check = LookupRangeCheckConfig::configure( + let range_check = LookupRangeCheckConfigOptimized::configure_with_tag( meta, advices[9], table_idx, - Some(table_range_check_tag), + table_range_check_tag, ); - let sinsemilla_config = SinsemillaChip::configure( + let sinsemilla_config = SinsemillaChipOptimized::configure( meta, advices[..5].try_into().unwrap(), advices[6], @@ -210,12 +222,13 @@ mod tests { MyConfig { primary, advices, - ecc_config: EccChip::::configure( - meta, - advices, - lagrange_coeffs, - range_check, - ), + ecc_config: + EccChip::::configure( + meta, + advices, + lagrange_coeffs, + range_check, + ), sinsemilla_config, } } @@ -226,12 +239,13 @@ mod tests { mut layouter: impl Layouter, ) -> Result<(), Error> { // Load the Sinsemilla generator lookup table. - SinsemillaChip::load(config.sinsemilla_config.clone(), &mut layouter)?; + SinsemillaChipOptimized::load(config.sinsemilla_config.clone(), &mut layouter)?; // Construct an ECC chip let ecc_chip = EccChip::construct(config.ecc_config); - let sinsemilla_chip = SinsemillaChip::construct(config.sinsemilla_config.clone()); + let sinsemilla_chip = + SinsemillaChipOptimized::construct(config.sinsemilla_config.clone()); // Witness the magnitude and sign of v_net = v_old - v_new let v_net_magnitude_sign = { diff --git a/src/circuit/commit_ivk.rs b/src/circuit/commit_ivk.rs index 566bd55f9..0c1a793fa 100644 --- a/src/circuit/commit_ivk.rs +++ b/src/circuit/commit_ivk.rs @@ -10,10 +10,10 @@ use halo2_proofs::{ }; use pasta_curves::pallas; -use crate::constants::{OrchardCommitDomains, OrchardFixedBases, OrchardHashDomains, T_P}; +use crate::constants::{OrchardCommitDomains, OrchardFixedBases, T_P}; use halo2_gadgets::{ ecc::{chip::EccChip, ScalarFixed, X}, - sinsemilla::{chip::SinsemillaChip, CommitDomain, Message, MessagePiece}, + sinsemilla::{CommitDomain, Message, MessagePiece}, utilities::{bool_check, RangeConstrained}, }; @@ -230,29 +230,29 @@ impl CommitIvkChip { } pub(in crate::circuit) mod gadgets { - use halo2_gadgets::utilities::{lookup_range_check::LookupRangeCheckConfig, RangeConstrained}; - use halo2_proofs::circuit::Chip; + use halo2_gadgets::utilities::{lookup_range_check::PallasLookupRC, RangeConstrained}; use super::*; + use super::super::orchard_sinsemilla_chip::OrchardSinsemillaChip; + /// `Commit^ivk` from [Section 5.4.8.4 Sinsemilla commitments]. /// /// [Section 5.4.8.4 Sinsemilla commitments]: https://zips.z.cash/protocol/protocol.pdf#concretesinsemillacommit #[allow(non_snake_case)] #[allow(clippy::type_complexity)] - pub(in crate::circuit) fn commit_ivk( - sinsemilla_chip: SinsemillaChip< - OrchardHashDomains, - OrchardCommitDomains, - OrchardFixedBases, - >, - ecc_chip: EccChip, + pub(in crate::circuit) fn commit_ivk< + Lookup: PallasLookupRC, + Chip: OrchardSinsemillaChip, + >( + sinsemilla_chip: Chip, + ecc_chip: EccChip, commit_ivk_chip: CommitIvkChip, mut layouter: impl Layouter, ak: AssignedCell, nk: AssignedCell, - rivk: ScalarFixed>, - ) -> Result>, Error> { + rivk: ScalarFixed>, + ) -> Result>, Error> { let lookup_config = sinsemilla_chip.config().lookup_config(); // We need to hash `ak || nk` where each of `ak`, `nk` is a field element (255 bits). @@ -400,8 +400,8 @@ pub(in crate::circuit) mod gadgets { /// /// [Specification](https://p.z.cash/orchard-0.1:commit-ivk-canonicity-ak?partial). #[allow(clippy::type_complexity)] - fn ak_canonicity( - lookup_config: &LookupRangeCheckConfig, + fn ak_canonicity( + lookup_config: &Lookup, mut layouter: impl Layouter, a: AssignedCell, ) -> Result< @@ -441,8 +441,8 @@ pub(in crate::circuit) mod gadgets { /// /// [Specification](https://p.z.cash/orchard-0.1:commit-ivk-canonicity-nk?partial). #[allow(clippy::type_complexity)] - fn nk_canonicity( - lookup_config: &LookupRangeCheckConfig, + fn nk_canonicity( + lookup_config: &Lookup, mut layouter: impl Layouter, b_2: &RangeConstrained>, c: AssignedCell, @@ -661,6 +661,7 @@ struct GateCells { z14_b2_c_prime: AssignedCell, } +// FIXME: add tests for SinsemillaChip as well (not only for SinsemillaChipOptimized) #[cfg(test)] mod tests { use core::iter; @@ -677,10 +678,13 @@ mod tests { ScalarFixed, }, sinsemilla::{ - chip::{SinsemillaChip, SinsemillaConfig}, + chip::{SinsemillaChipOptimized, SinsemillaConfig}, primitives::CommitDomain, }, - utilities::{lookup_range_check::LookupRangeCheckConfig, UtilitiesInstructions}, + utilities::{ + lookup_range_check::{LookupRangeCheckConfigOptimized, PallasLookupConfigOptimized}, + UtilitiesInstructions, + }, }; use halo2_proofs::{ circuit::{AssignedCell, Layouter, SimpleFloorPlanner, Value}, @@ -704,9 +708,14 @@ mod tests { impl Circuit for MyCircuit { type Config = ( - SinsemillaConfig, + SinsemillaConfig< + OrchardHashDomains, + OrchardCommitDomains, + OrchardFixedBases, + PallasLookupConfigOptimized, + >, CommitIvkConfig, - EccConfig, + EccConfig, ); type FloorPlanner = SimpleFloorPlanner; @@ -741,7 +750,6 @@ mod tests { table_idx, meta.lookup_table_column(), meta.lookup_table_column(), - Some(table_range_check_tag), ); let lagrange_coeffs = [ meta.fixed_column(), @@ -754,13 +762,13 @@ mod tests { meta.fixed_column(), ]; - let range_check = LookupRangeCheckConfig::configure( + let range_check = LookupRangeCheckConfigOptimized::configure_with_tag( meta, advices[9], table_idx, - Some(table_range_check_tag), + table_range_check_tag, ); - let sinsemilla_config = SinsemillaChip::< + let sinsemilla_config = SinsemillaChipOptimized::< OrchardHashDomains, OrchardCommitDomains, OrchardFixedBases, @@ -775,12 +783,13 @@ mod tests { let commit_ivk_config = CommitIvkChip::configure(meta, advices); - let ecc_config = EccChip::::configure( - meta, - advices, - lagrange_coeffs, - range_check, - ); + let ecc_config = + EccChip::::configure( + meta, + advices, + lagrange_coeffs, + range_check, + ); (sinsemilla_config, commit_ivk_config, ecc_config) } @@ -793,10 +802,14 @@ mod tests { let (sinsemilla_config, commit_ivk_config, ecc_config) = config; // Load the Sinsemilla generator lookup table used by the whole circuit. - SinsemillaChip::::load(sinsemilla_config.clone(), &mut layouter)?; + SinsemillaChipOptimized::< + OrchardHashDomains, + OrchardCommitDomains, + OrchardFixedBases, + >::load(sinsemilla_config.clone(), &mut layouter)?; // Construct a Sinsemilla chip - let sinsemilla_chip = SinsemillaChip::construct(sinsemilla_config); + let sinsemilla_chip = SinsemillaChipOptimized::construct(sinsemilla_config); // Construct an ECC chip let ecc_chip = EccChip::construct(ecc_config);