diff --git a/src/builder.rs b/src/builder.rs index 70cd3dc77..eb20033b2 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -167,26 +167,20 @@ impl SpendInfo { } } - /// Creates a split spend, which is identical to origin normal spend except that we use a random - /// fvk to generate a different nullifier. In addition, the split_flag is raised. + /// Creates a split spend, which is identical to origin normal spend except that + /// `rseed_split_note` contains a random seed. In addition, the split_flag is raised. /// /// Defined in [Transfer and Burn of Zcash Shielded Assets ZIP-0226 § Split Notes (DRAFT PR)][TransferZSA]. /// /// [TransferZSA]: https://qed-it.github.io/zips/zip-0226.html#split-notes fn create_split_spend(&self, rng: &mut impl RngCore) -> Self { - let note = self.note; - let merkle_path = self.merkle_path.clone(); - - let sk = SpendingKey::random(rng); - let fvk: FullViewingKey = (&sk).into(); - SpendInfo { - dummy_sk: Some(sk), - fvk, + dummy_sk: None, + fvk: self.fvk.clone(), // We use external scope to avoid unnecessary derivations scope: Scope::External, - note, - merkle_path, + note: self.note.create_split_note(rng), + merkle_path: self.merkle_path.clone(), split_flag: true, } } diff --git a/src/bundle.rs b/src/bundle.rs index f6265761d..2e5d5a034 100644 --- a/src/bundle.rs +++ b/src/bundle.rs @@ -141,7 +141,6 @@ pub struct Bundle { /// This is the sum of Orchard spends minus the sum of Orchard outputs. value_balance: V, /// Assets intended for burning - /// TODO We need to add a consensus check to make sure that it is impossible to burn ZEC. burn: Vec<(AssetBase, V)>, /// The root of the Orchard commitment tree that this bundle commits to. anchor: Anchor, diff --git a/src/circuit.rs b/src/circuit.rs index 67833b013..99a35b1d9 100644 --- a/src/circuit.rs +++ b/src/circuit.rs @@ -21,7 +21,7 @@ use self::{ commit_ivk::{CommitIvkChip, CommitIvkConfig}, gadget::{ add_chip::{AddChip, AddConfig}, - assign_free_advice, assign_is_native_asset, + assign_free_advice, assign_is_native_asset, assign_split_flag, }, note_commit::{NoteCommitChip, NoteCommitConfig}, }; @@ -113,6 +113,7 @@ pub struct Circuit { pub(crate) psi_old: Value, pub(crate) rcm_old: Value, pub(crate) cm_old: Value, + pub(crate) psi_nf: Value, pub(crate) alpha: Value, pub(crate) ak: Value, pub(crate) nk: Value, @@ -164,6 +165,9 @@ impl Circuit { let psi_old = spend.note.rseed().psi(&rho_old); let rcm_old = spend.note.rseed().rcm(&rho_old); + let nf_rseed = spend.note.rseed_split_note().unwrap_or(*spend.note.rseed()); + let psi_nf = nf_rseed.psi(&rho_old); + let rho_new = output_note.rho(); let psi_new = output_note.rseed().psi(&rho_new); let rcm_new = output_note.rseed().rcm(&rho_new); @@ -178,6 +182,7 @@ impl Circuit { psi_old: Value::known(psi_old), rcm_old: Value::known(rcm_old), cm_old: Value::known(spend.note.commitment()), + psi_nf: Value::known(psi_nf), alpha: Value::known(alpha), ak: Value::known(spend.fvk.clone().into()), nk: Value::known(*spend.fvk.nk()), @@ -222,10 +227,9 @@ impl plonk::Circuit for Circuit { // Constrain v_old = 0 or calculated root = anchor (https://p.z.cash/ZKS:action-merkle-path-validity?partial). // Constrain v_old = 0 or enable_spends = 1 (https://p.z.cash/ZKS:action-enable-spend). // Constrain v_new = 0 or enable_outputs = 1 (https://p.z.cash/ZKS:action-enable-output). - // Constrain split_flag = 1 or nf_old = nf_old_pub // Constrain is_native_asset to be boolean // Constraint if is_native_asset = 1 then asset = native_asset else asset != native_asset - // Constraint split_flag = 1 or derived_pk_d_old = pk_d_old + // Constraint if split_flag = 0 then psi_old = psi_nf let q_orchard = meta.selector(); meta.create_gate("Orchard circuit checks", |meta| { let q_orchard = meta.query_selector(q_orchard); @@ -242,14 +246,11 @@ impl plonk::Circuit for Circuit { let split_flag = meta.query_advice(advices[8], Rotation::cur()); - let nf_old = meta.query_advice(advices[9], Rotation::cur()); - let nf_old_pub = meta.query_advice(advices[0], Rotation::next()); - - let is_native_asset = meta.query_advice(advices[1], Rotation::next()); - let asset_x = meta.query_advice(advices[2], Rotation::next()); - let asset_y = meta.query_advice(advices[3], Rotation::next()); - let diff_asset_x_inv = meta.query_advice(advices[4], Rotation::next()); - let diff_asset_y_inv = meta.query_advice(advices[5], Rotation::next()); + let is_native_asset = meta.query_advice(advices[9], Rotation::cur()); + let asset_x = meta.query_advice(advices[0], Rotation::next()); + let asset_y = meta.query_advice(advices[1], Rotation::next()); + let diff_asset_x_inv = meta.query_advice(advices[2], Rotation::next()); + let diff_asset_y_inv = meta.query_advice(advices[3], Rotation::next()); let one = Expression::Constant(pallas::Base::one()); @@ -262,10 +263,8 @@ impl plonk::Circuit for Circuit { let diff_asset_x = asset_x - Expression::Constant(*native_asset.x()); let diff_asset_y = asset_y - Expression::Constant(*native_asset.y()); - let pk_d_old_x = meta.query_advice(advices[6], Rotation::next()); - let pk_d_old_y = meta.query_advice(advices[7], Rotation::next()); - let derived_pk_d_old_x = meta.query_advice(advices[8], Rotation::next()); - let derived_pk_d_old_y = meta.query_advice(advices[9], Rotation::next()); + let psi_old = meta.query_advice(advices[4], Rotation::next()); + let psi_nf = meta.query_advice(advices[5], Rotation::next()); Constraints::with_selector( q_orchard, @@ -289,10 +288,6 @@ impl plonk::Circuit for Circuit { "v_new = 0 or enable_outputs = 1", v_new * (one.clone() - enable_outputs), ), - ( - "split_flag = 1 or nf_old = nf_old_pub", - (one.clone() - split_flag.clone()) * (nf_old - nf_old_pub), - ), ( "bool_check is_native_asset", bool_check(is_native_asset.clone()), @@ -316,20 +311,9 @@ impl plonk::Circuit for Circuit { * (diff_asset_x * diff_asset_x_inv - one.clone()) * (diff_asset_y * diff_asset_y_inv - one.clone()), ), - // Constrain derived pk_d_old to equal witnessed pk_d_old - // - // This equality constraint is technically superfluous, because the assigned - // value of `derived_pk_d_old` is an equivalent witness. But it's nice to see - // an explicit connection between circuit-synthesized values, and explicit - // prover witnesses. We could get the best of both worlds with a write-on-copy - // abstraction (https://github.com/zcash/halo2/issues/334). ( - "split_flag = 1 or pk_d_old_x = derived_pk_d_old_x", - (one.clone() - split_flag.clone()) * (pk_d_old_x - derived_pk_d_old_x), - ), - ( - "split_flag = 1 or pk_d_old_y = derived_pk_d_old_y", - (one - split_flag) * (pk_d_old_y - derived_pk_d_old_y), + "(split_flag = 0) => (psi_old = psi_nf)", + (one - split_flag) * (psi_old - psi_nf), ), ], ) @@ -480,7 +464,14 @@ impl plonk::Circuit for Circuit { let ecc_chip = config.ecc_chip(); // 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, asset, nf_old_pub) = { + let (psi_nf, psi_old, rho_old, cm_old, g_d_old, ak_P, nk, v_old, v_new, asset) = { + // Witness psi_nf + let psi_nf = assign_free_advice( + layouter.namespace(|| "witness psi_nf"), + config.advices[0], + self.psi_nf, + )?; + // Witness psi_old let psi_old = assign_free_advice( layouter.namespace(|| "witness psi_old"), @@ -545,25 +536,18 @@ impl plonk::Circuit for Circuit { self.asset.map(|asset| asset.cv_base().to_affine()), )?; - // Witness nf_old_pub - let nf_old_pub = layouter.assign_region( - || "load nf_old pub", - |mut region| { - region.assign_advice_from_instance( - || "load nf_old pub", - config.primary, - NF_OLD, - config.advices[0], - 1, - ) - }, - )?; - ( - psi_old, rho_old, cm_old, g_d_old, ak_P, nk, v_old, v_new, asset, nf_old_pub, + psi_nf, psi_old, rho_old, cm_old, g_d_old, ak_P, nk, v_old, v_new, asset, ) }; + // Witness split_flag + let split_flag = assign_split_flag( + layouter.namespace(|| "witness split_flag"), + config.advices[0], + self.split_flag, + )?; + // Witness is_native_asset which is equal to // 1 if asset is equal to native asset, and // 0 if asset is not equal to native asset. @@ -656,16 +640,21 @@ impl plonk::Circuit for Circuit { // Nullifier integrity (https://p.z.cash/ZKS:action-nullifier-integrity). let nf_old = { let nf_old = gadget::derive_nullifier( - layouter.namespace(|| "nf_old = DeriveNullifier_nk(rho_old, psi_old, cm_old)"), + layouter.namespace(|| "nf_old = DeriveNullifier_nk(rho_old, psi_nf, cm_old)"), config.poseidon_chip(), config.add_chip(), ecc_chip.clone(), + config.mux_chip(), rho_old.clone(), - &psi_old, + &psi_nf, &cm_old, nk.clone(), + split_flag.clone(), )?; + // Constrain nf_old to equal public input + layouter.constrain_instance(nf_old.inner().cell(), config.primary, NF_OLD)?; + nf_old }; @@ -690,7 +679,7 @@ impl plonk::Circuit for Circuit { } // Diversified address integrity (https://p.z.cash/ZKS:action-addr-integrity?partial). - let (derived_pk_d_old, pk_d_old) = { + let pk_d_old = { let ivk = { let ak = ak_P.extract_p().inner().clone(); let rivk = ScalarFixed::new( @@ -717,13 +706,22 @@ impl plonk::Circuit for Circuit { let (derived_pk_d_old, _ivk) = g_d_old.mul(layouter.namespace(|| "[ivk] g_d_old"), ivk)?; + // Constrain derived pk_d_old to equal witnessed pk_d_old + // + // This equality constraint is technically superfluous, because the assigned + // value of `derived_pk_d_old` is an equivalent witness. But it's nice to see + // an explicit connection between circuit-synthesized values, and explicit + // prover witnesses. We could get the best of both worlds with a write-on-copy + // abstraction (https://github.com/zcash/halo2/issues/334). let pk_d_old = NonIdentityPoint::new( ecc_chip.clone(), layouter.namespace(|| "witness pk_d_old"), self.pk_d_old.map(|pk_d_old| pk_d_old.inner().to_affine()), )?; + derived_pk_d_old + .constrain_equal(layouter.namespace(|| "pk_d_old equality"), &pk_d_old)?; - (derived_pk_d_old, pk_d_old) + pk_d_old }; // Old note commitment integrity (https://p.z.cash/ZKS:action-cm-old-integrity?partial). @@ -747,7 +745,7 @@ impl plonk::Circuit for Circuit { pk_d_old.inner(), v_old.clone(), rho_old, - psi_old, + psi_old.clone(), asset.inner(), rcm_old, is_native_asset.clone(), @@ -780,7 +778,7 @@ impl plonk::Circuit for Circuit { }; // ρ^new = nf^old - let rho_new = nf_old_pub.clone(); + let rho_new = nf_old.inner().clone(); // Witness psi_new let psi_new = assign_free_advice( @@ -864,41 +862,28 @@ impl plonk::Circuit for Circuit { 0, )?; - region.assign_advice( - || "split_flag", - config.advices[8], - 0, - || { - self.split_flag - .map(|split_flag| pallas::Base::from(split_flag as u64)) - }, - )?; - - nf_old - .inner() - .copy_advice(|| "nf_old", &mut region, config.advices[9], 0)?; - nf_old_pub.copy_advice(|| "nf_old", &mut region, config.advices[0], 1)?; + split_flag.copy_advice(|| "split_flag", &mut region, config.advices[8], 0)?; is_native_asset.copy_advice( || "is_native_asset", &mut region, - config.advices[1], - 1, + config.advices[9], + 0, )?; asset .inner() .x() - .copy_advice(|| "asset_x", &mut region, config.advices[2], 1)?; + .copy_advice(|| "asset_x", &mut region, config.advices[0], 1)?; asset .inner() .y() - .copy_advice(|| "asset_y", &mut region, config.advices[3], 1)?; + .copy_advice(|| "asset_y", &mut region, config.advices[1], 1)?; // `diff_asset_x_inv` and `diff_asset_y_inv` will be used to prove that // if is_native_asset = 0, then asset != native_asset. region.assign_advice( || "diff_asset_x_inv", - config.advices[4], + config.advices[2], 1, || { self.asset.map(|asset| { @@ -922,7 +907,7 @@ impl plonk::Circuit for Circuit { )?; region.assign_advice( || "diff_asset_y_inv", - config.advices[5], + config.advices[3], 1, || { self.asset.map(|asset| { @@ -945,30 +930,8 @@ impl plonk::Circuit for Circuit { }, )?; - pk_d_old.inner().x().copy_advice( - || "pk_d_old_x", - &mut region, - config.advices[6], - 1, - )?; - pk_d_old.inner().y().copy_advice( - || "pk_d_old_y", - &mut region, - config.advices[7], - 1, - )?; - derived_pk_d_old.inner().x().copy_advice( - || "derived_pk_d_old_x", - &mut region, - config.advices[8], - 1, - )?; - derived_pk_d_old.inner().y().copy_advice( - || "derived_pk_d_old_y", - &mut region, - config.advices[9], - 1, - )?; + psi_old.copy_advice(|| "psi_old", &mut region, config.advices[4], 1)?; + psi_nf.copy_advice(|| "psi_nf", &mut region, config.advices[5], 1)?; config.q_orchard.enable(&mut region, 0) }, @@ -1226,6 +1189,8 @@ mod tests { let path = MerklePath::dummy(&mut rng); let anchor = path.root(spent_note.commitment().into()); + let psi_old = spent_note.rseed().psi(&spent_note.rho()); + ( Circuit { path: Value::known(path.auth_path()), @@ -1234,9 +1199,11 @@ mod tests { pk_d_old: Value::known(*sender_address.pk_d()), v_old: Value::known(spent_note.value()), rho_old: Value::known(spent_note.rho()), - psi_old: Value::known(spent_note.rseed().psi(&spent_note.rho())), + psi_old: Value::known(psi_old), rcm_old: Value::known(spent_note.rseed().rcm(&spent_note.rho())), cm_old: Value::known(spent_note.commitment()), + // For non split note, psi_nf is equal to psi_old + psi_nf: Value::known(psi_old), alpha: Value::known(alpha), ak: Value::known(ak), nk: Value::known(nk), @@ -1426,6 +1393,7 @@ mod tests { psi_old: Value::unknown(), rcm_old: Value::unknown(), cm_old: Value::unknown(), + psi_nf: Value::unknown(), alpha: Value::unknown(), ak: Value::unknown(), nk: Value::unknown(), @@ -1483,42 +1451,41 @@ mod tests { let fvk: FullViewingKey = (&sk).into(); let sender_address = fvk.address_at(0u32, Scope::External); let rho_old = Nullifier::dummy(&mut rng); - let spent_note = Note::new( + let note = Note::new( sender_address, NoteValue::from_raw(40), asset_base, rho_old, &mut rng, ); + let spent_note = if split_flag { + note.create_split_note(&mut rng) + } else { + note + }; (fvk, spent_note) }; let output_value = NoteValue::from_raw(10); - let (dummy_sk, fvk, scope, nf_old, v_net) = if split_flag { - let sk = SpendingKey::random(&mut rng); - let fvk: FullViewingKey = (&sk).into(); + let (scope, v_net) = if split_flag { ( - Some(sk), - fvk.clone(), Scope::External, - spent_note.nullifier(&fvk), // Split notes do not contribute to v_net. // Therefore, if split_flag is true, v_net = - output_value NoteValue::zero() - output_value, ) } else { ( - None, - spent_note_fvk.clone(), spent_note_fvk .scope_for_address(&spent_note.recipient()) .unwrap(), - spent_note.nullifier(&spent_note_fvk), spent_note.value() - output_value, ) }; - let ak: SpendValidatingKey = fvk.clone().into(); + + let nf_old = spent_note.nullifier(&spent_note_fvk); + let ak: SpendValidatingKey = spent_note_fvk.clone().into(); let alpha = pallas::Scalar::random(&mut rng); let rk = ak.randomize(&alpha); @@ -1539,8 +1506,8 @@ mod tests { let anchor = path.root(spent_note.commitment().into()); let spend_info = SpendInfo { - dummy_sk, - fvk, + dummy_sk: None, + fvk: spent_note_fvk, scope, note: spent_note, merkle_path: path, @@ -1623,6 +1590,7 @@ mod tests { psi_old: circuit.psi_old, rcm_old: circuit.rcm_old.clone(), cm_old: Value::known(random_note_commitment(&mut rng)), + psi_nf: circuit.psi_nf, alpha: circuit.alpha, ak: circuit.ak.clone(), nk: circuit.nk, diff --git a/src/circuit/gadget.rs b/src/circuit/gadget.rs index 646bef288..919b2c10b 100644 --- a/src/circuit/gadget.rs +++ b/src/circuit/gadget.rs @@ -1,13 +1,16 @@ //! Gadgets used in the Orchard circuit. use ff::Field; +use group::Curve; +use pasta_curves::arithmetic::CurveExt; use pasta_curves::pallas; use super::{commit_ivk::CommitIvkChip, note_commit::NoteCommitChip}; +use crate::circuit::gadget::mux_chip::{MuxChip, MuxInstructions}; use crate::constants::{NullifierK, OrchardCommitDomains, OrchardFixedBases, OrchardHashDomains}; use crate::note::AssetBase; use halo2_gadgets::{ - ecc::{chip::EccChip, EccInstructions, FixedPointBaseField, Point, X}, + ecc::{chip::EccChip, chip::EccPoint, EccInstructions, FixedPointBaseField, Point, X}, poseidon::{ primitives::{self as poseidon, ConstantLength}, Hash as PoseidonHash, PoseidonSpongeInstructions, Pow5Chip as PoseidonChip, @@ -128,6 +131,28 @@ where ) } +/// Witnesses split_flag. +pub(in crate::circuit) fn assign_split_flag( + layouter: impl Layouter, + column: Column, + split_flag: Value, +) -> Result, plonk::Error> +where + Assigned: for<'v> From<&'v pasta_curves::Fp>, +{ + assign_free_advice( + layouter, + column, + split_flag.map(|split_flag| { + if split_flag { + pallas::Base::one() + } else { + pallas::Base::zero() + } + }), + ) +} + /// `DeriveNullifier` from [Section 4.16: Note Commitments and Nullifiers]. /// /// [Section 4.16: Note Commitments and Nullifiers]: https://zips.z.cash/protocol/protocol.pdf#commitmentsandnullifiers @@ -138,6 +163,7 @@ pub(in crate::circuit) fn derive_nullifier< EccChip: EccInstructions< pallas::Affine, FixedPoints = OrchardFixedBases, + Point = EccPoint, Var = AssignedCell, >, >( @@ -145,10 +171,12 @@ pub(in crate::circuit) fn derive_nullifier< poseidon_chip: PoseidonChip, add_chip: AddChip, ecc_chip: EccChip, + mux_chip: MuxChip, rho: AssignedCell, psi: &AssignedCell, cm: &Point, nk: AssignedCell, + split_flag: AssignedCell, ) -> Result, plonk::Error> { // hash = poseidon_hash(nk, rho) let hash = { @@ -173,17 +201,37 @@ pub(in crate::circuit) fn derive_nullifier< // `product` = [poseidon_hash(nk, rho) + psi] NullifierK. // let product = { - let nullifier_k = FixedPointBaseField::from_inner(ecc_chip, NullifierK); + let nullifier_k = FixedPointBaseField::from_inner(ecc_chip.clone(), NullifierK); nullifier_k.mul( layouter.namespace(|| "[poseidon_output + psi] NullifierK"), scalar, )? }; - // Add cm to multiplied fixed base to get nf - // cm + [poseidon_output + psi] NullifierK - cm.add(layouter.namespace(|| "nf"), &product) - .map(|res| res.extract_p()) + // Add cm to multiplied fixed base + // nf = cm + [poseidon_output + psi] NullifierK + let nf = cm.add(layouter.namespace(|| "nf"), &product)?; + + // Add NullifierL to nf + // split_note_nf = NullifierL + nf + let nullifier_l = Point::new_from_constant( + ecc_chip.clone(), + layouter.namespace(|| "witness NullifierL constant"), + pallas::Point::hash_to_curve("z.cash:Orchard")(b"L").to_affine(), + )?; + let split_note_nf = nullifier_l.add(layouter.namespace(|| "split_note_nf"), &nf)?; + + // Select the desired nullifier according to split_flag + Ok(Point::from_inner( + ecc_chip, + mux_chip.mux( + layouter.namespace(|| "mux on nf"), + &split_flag, + nf.inner(), + split_note_nf.inner(), + )?, + ) + .extract_p()) } pub(in crate::circuit) use crate::circuit::commit_ivk::gadgets::commit_ivk; diff --git a/src/circuit_description b/src/circuit_description index ffb19ab6f..8078e15f1 100644 --- a/src/circuit_description +++ b/src/circuit_description @@ -447,97 +447,6 @@ PinnedVerificationKey { ), ), ), - Product( - Product( - Product( - Product( - Fixed { - query_index: 18, - column_index: 18, - rotation: Rotation( - 0, - ), - }, - Sum( - Constant( - 0x0000000000000000000000000000000000000000000000000000000000000002, - ), - Negated( - Fixed { - query_index: 18, - column_index: 18, - rotation: Rotation( - 0, - ), - }, - ), - ), - ), - Sum( - Constant( - 0x0000000000000000000000000000000000000000000000000000000000000003, - ), - Negated( - Fixed { - query_index: 18, - column_index: 18, - rotation: Rotation( - 0, - ), - }, - ), - ), - ), - Sum( - Constant( - 0x0000000000000000000000000000000000000000000000000000000000000004, - ), - Negated( - Fixed { - query_index: 18, - column_index: 18, - rotation: Rotation( - 0, - ), - }, - ), - ), - ), - Product( - Sum( - Constant( - 0x0000000000000000000000000000000000000000000000000000000000000001, - ), - Negated( - Advice { - query_index: 8, - column_index: 8, - rotation: Rotation( - 0, - ), - }, - ), - ), - Sum( - Advice { - query_index: 9, - column_index: 9, - rotation: Rotation( - 0, - ), - }, - Negated( - Advice { - query_index: 10, - column_index: 0, - rotation: Rotation( - 1, - ), - }, - ), - ), - ), - ), Product( Product( Product( @@ -596,10 +505,10 @@ PinnedVerificationKey { ), Product( Advice { - query_index: 11, - column_index: 1, + query_index: 9, + column_index: 9, rotation: Rotation( - 1, + 0, ), }, Sum( @@ -608,10 +517,10 @@ PinnedVerificationKey { ), Negated( Advice { - query_index: 11, - column_index: 1, + query_index: 9, + column_index: 9, rotation: Rotation( - 1, + 0, ), }, ), @@ -676,16 +585,16 @@ PinnedVerificationKey { ), Product( Advice { - query_index: 11, - column_index: 1, + query_index: 9, + column_index: 9, rotation: Rotation( - 1, + 0, ), }, Sum( Advice { - query_index: 12, - column_index: 2, + query_index: 10, + column_index: 0, rotation: Rotation( 1, ), @@ -756,16 +665,16 @@ PinnedVerificationKey { ), Product( Advice { - query_index: 11, - column_index: 1, + query_index: 9, + column_index: 9, rotation: Rotation( - 1, + 0, ), }, Sum( Advice { - query_index: 13, - column_index: 3, + query_index: 11, + column_index: 1, rotation: Rotation( 1, ), @@ -842,10 +751,10 @@ PinnedVerificationKey { ), Negated( Advice { - query_index: 11, - column_index: 1, + query_index: 9, + column_index: 9, rotation: Rotation( - 1, + 0, ), }, ), @@ -854,8 +763,8 @@ PinnedVerificationKey { Product( Sum( Advice { - query_index: 12, - column_index: 2, + query_index: 10, + column_index: 0, rotation: Rotation( 1, ), @@ -867,8 +776,8 @@ PinnedVerificationKey { ), ), Advice { - query_index: 14, - column_index: 4, + query_index: 12, + column_index: 2, rotation: Rotation( 1, ), @@ -885,8 +794,8 @@ PinnedVerificationKey { Product( Sum( Advice { - query_index: 13, - column_index: 3, + query_index: 11, + column_index: 1, rotation: Rotation( 1, ), @@ -898,8 +807,8 @@ PinnedVerificationKey { ), ), Advice { - query_index: 15, - column_index: 5, + query_index: 13, + column_index: 3, rotation: Rotation( 1, ), @@ -986,107 +895,16 @@ PinnedVerificationKey { ), Sum( Advice { - query_index: 16, - column_index: 6, - rotation: Rotation( - 1, - ), - }, - Negated( - Advice { - query_index: 18, - column_index: 8, - rotation: Rotation( - 1, - ), - }, - ), - ), - ), - ), - Product( - Product( - Product( - Product( - Fixed { - query_index: 18, - column_index: 18, - rotation: Rotation( - 0, - ), - }, - Sum( - Constant( - 0x0000000000000000000000000000000000000000000000000000000000000002, - ), - Negated( - Fixed { - query_index: 18, - column_index: 18, - rotation: Rotation( - 0, - ), - }, - ), - ), - ), - Sum( - Constant( - 0x0000000000000000000000000000000000000000000000000000000000000003, - ), - Negated( - Fixed { - query_index: 18, - column_index: 18, - rotation: Rotation( - 0, - ), - }, - ), - ), - ), - Sum( - Constant( - 0x0000000000000000000000000000000000000000000000000000000000000004, - ), - Negated( - Fixed { - query_index: 18, - column_index: 18, - rotation: Rotation( - 0, - ), - }, - ), - ), - ), - Product( - Sum( - Constant( - 0x0000000000000000000000000000000000000000000000000000000000000001, - ), - Negated( - Advice { - query_index: 8, - column_index: 8, - rotation: Rotation( - 0, - ), - }, - ), - ), - Sum( - Advice { - query_index: 17, - column_index: 7, + query_index: 14, + column_index: 4, rotation: Rotation( 1, ), }, Negated( Advice { - query_index: 19, - column_index: 9, + query_index: 15, + column_index: 5, rotation: Rotation( 1, ), @@ -1239,7 +1057,7 @@ PinnedVerificationKey { Product( Scaled( Advice { - query_index: 20, + query_index: 17, column_index: 9, rotation: Rotation( -1, @@ -1248,7 +1066,7 @@ PinnedVerificationKey { 0x0000000000000000000000000000000000000000000000000000000000000400, ), Advice { - query_index: 19, + query_index: 16, column_index: 9, rotation: Rotation( 1, @@ -1272,20 +1090,20 @@ PinnedVerificationKey { Product( Product( Fixed { - query_index: 18, - column_index: 18, + query_index: 19, + column_index: 19, rotation: Rotation( 0, ), }, Sum( Constant( - 0x0000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000002, ), Negated( Fixed { - query_index: 18, - column_index: 18, + query_index: 19, + column_index: 19, rotation: Rotation( 0, ), @@ -1295,12 +1113,12 @@ PinnedVerificationKey { ), Sum( Constant( - 0x0000000000000000000000000000000000000000000000000000000000000002, + 0x0000000000000000000000000000000000000000000000000000000000000003, ), Negated( Fixed { - query_index: 18, - column_index: 18, + query_index: 19, + column_index: 19, rotation: Rotation( 0, ), @@ -1310,12 +1128,12 @@ PinnedVerificationKey { ), Sum( Constant( - 0x0000000000000000000000000000000000000000000000000000000000000003, + 0x0000000000000000000000000000000000000000000000000000000000000004, ), Negated( Fixed { - query_index: 18, - column_index: 18, + query_index: 19, + column_index: 19, rotation: Rotation( 0, ), @@ -1390,20 +1208,20 @@ PinnedVerificationKey { Product( Product( Fixed { - query_index: 18, - column_index: 18, + query_index: 19, + column_index: 19, rotation: Rotation( 0, ), }, Sum( Constant( - 0x0000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000002, ), Negated( Fixed { - query_index: 18, - column_index: 18, + query_index: 19, + column_index: 19, rotation: Rotation( 0, ), @@ -1413,12 +1231,12 @@ PinnedVerificationKey { ), Sum( Constant( - 0x0000000000000000000000000000000000000000000000000000000000000002, + 0x0000000000000000000000000000000000000000000000000000000000000003, ), Negated( Fixed { - query_index: 18, - column_index: 18, + query_index: 19, + column_index: 19, rotation: Rotation( 0, ), @@ -1428,12 +1246,12 @@ PinnedVerificationKey { ), Sum( Constant( - 0x0000000000000000000000000000000000000000000000000000000000000003, + 0x0000000000000000000000000000000000000000000000000000000000000004, ), Negated( Fixed { - query_index: 18, - column_index: 18, + query_index: 19, + column_index: 19, rotation: Rotation( 0, ), @@ -1515,7 +1333,7 @@ PinnedVerificationKey { }, Sum( Constant( - 0x0000000000000000000000000000000000000000000000000000000000000002, + 0x0000000000000000000000000000000000000000000000000000000000000001, ), Negated( Fixed { @@ -1639,7 +1457,7 @@ PinnedVerificationKey { ), Sum( Constant( - 0x0000000000000000000000000000000000000000000000000000000000000003, + 0x0000000000000000000000000000000000000000000000000000000000000002, ), Negated( Fixed { @@ -1803,7 +1621,7 @@ PinnedVerificationKey { ), Sum( Constant( - 0x0000000000000000000000000000000000000000000000000000000000000003, + 0x0000000000000000000000000000000000000000000000000000000000000002, ), Negated( Fixed { @@ -1953,7 +1771,7 @@ PinnedVerificationKey { ), Sum( Constant( - 0x0000000000000000000000000000000000000000000000000000000000000004, + 0x0000000000000000000000000000000000000000000000000000000000000003, ), Negated( Fixed { @@ -2079,7 +1897,7 @@ PinnedVerificationKey { ), Sum( Constant( - 0x0000000000000000000000000000000000000000000000000000000000000004, + 0x0000000000000000000000000000000000000000000000000000000000000003, ), Negated( Fixed { @@ -2218,7 +2036,7 @@ PinnedVerificationKey { ), Sum( Constant( - 0x0000000000000000000000000000000000000000000000000000000000000004, + 0x0000000000000000000000000000000000000000000000000000000000000003, ), Negated( Fixed { @@ -2362,7 +2180,7 @@ PinnedVerificationKey { ), Sum( Constant( - 0x0000000000000000000000000000000000000000000000000000000000000004, + 0x0000000000000000000000000000000000000000000000000000000000000003, ), Negated( Fixed { @@ -2506,7 +2324,7 @@ PinnedVerificationKey { ), Sum( Constant( - 0x0000000000000000000000000000000000000000000000000000000000000004, + 0x0000000000000000000000000000000000000000000000000000000000000003, ), Negated( Fixed { @@ -2648,7 +2466,7 @@ PinnedVerificationKey { ), Sum( Constant( - 0x0000000000000000000000000000000000000000000000000000000000000004, + 0x0000000000000000000000000000000000000000000000000000000000000003, ), Negated( Fixed { @@ -2790,7 +2608,7 @@ PinnedVerificationKey { ), Sum( Constant( - 0x0000000000000000000000000000000000000000000000000000000000000004, + 0x0000000000000000000000000000000000000000000000000000000000000003, ), Negated( Fixed { @@ -2890,7 +2708,7 @@ PinnedVerificationKey { ), Sum( Constant( - 0x0000000000000000000000000000000000000000000000000000000000000004, + 0x0000000000000000000000000000000000000000000000000000000000000003, ), Negated( Fixed { @@ -2990,7 +2808,7 @@ PinnedVerificationKey { ), Sum( Constant( - 0x0000000000000000000000000000000000000000000000000000000000000004, + 0x0000000000000000000000000000000000000000000000000000000000000003, ), Negated( Fixed { @@ -3090,7 +2908,7 @@ PinnedVerificationKey { ), Sum( Constant( - 0x0000000000000000000000000000000000000000000000000000000000000004, + 0x0000000000000000000000000000000000000000000000000000000000000003, ), Negated( Fixed { @@ -3190,7 +3008,7 @@ PinnedVerificationKey { ), Sum( Constant( - 0x0000000000000000000000000000000000000000000000000000000000000004, + 0x0000000000000000000000000000000000000000000000000000000000000003, ), Negated( Fixed { @@ -3319,7 +3137,7 @@ PinnedVerificationKey { ), Sum( Constant( - 0x0000000000000000000000000000000000000000000000000000000000000004, + 0x0000000000000000000000000000000000000000000000000000000000000003, ), Negated( Fixed { @@ -3410,8 +3228,8 @@ PinnedVerificationKey { Product( Product( Fixed { - query_index: 19, - column_index: 19, + query_index: 18, + column_index: 18, rotation: Rotation( 0, ), @@ -3422,8 +3240,8 @@ PinnedVerificationKey { ), Negated( Fixed { - query_index: 19, - column_index: 19, + query_index: 18, + column_index: 18, rotation: Rotation( 0, ), @@ -3437,8 +3255,8 @@ PinnedVerificationKey { ), Negated( Fixed { - query_index: 19, - column_index: 19, + query_index: 18, + column_index: 18, rotation: Rotation( 0, ), @@ -3452,8 +3270,8 @@ PinnedVerificationKey { ), Negated( Fixed { - query_index: 19, - column_index: 19, + query_index: 18, + column_index: 18, rotation: Rotation( 0, ), @@ -3857,7 +3675,7 @@ PinnedVerificationKey { Negated( Scaled( Advice { - query_index: 20, + query_index: 17, column_index: 9, rotation: Rotation( -1, @@ -3883,7 +3701,7 @@ PinnedVerificationKey { Negated( Scaled( Advice { - query_index: 20, + query_index: 17, column_index: 9, rotation: Rotation( -1, @@ -4101,7 +3919,7 @@ PinnedVerificationKey { Negated( Scaled( Advice { - query_index: 20, + query_index: 17, column_index: 9, rotation: Rotation( -1, @@ -4662,7 +4480,7 @@ PinnedVerificationKey { Negated( Scaled( Advice { - query_index: 20, + query_index: 17, column_index: 9, rotation: Rotation( -1, @@ -4688,7 +4506,7 @@ PinnedVerificationKey { Negated( Scaled( Advice { - query_index: 20, + query_index: 17, column_index: 9, rotation: Rotation( -1, @@ -4906,7 +4724,7 @@ PinnedVerificationKey { Negated( Scaled( Advice { - query_index: 20, + query_index: 17, column_index: 9, rotation: Rotation( -1, @@ -5405,7 +5223,7 @@ PinnedVerificationKey { Product( Sum( Advice { - query_index: 18, + query_index: 19, column_index: 8, rotation: Rotation( 1, @@ -5421,7 +5239,7 @@ PinnedVerificationKey { ), Sum( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -5432,14 +5250,14 @@ PinnedVerificationKey { Sum( Product( Advice { - query_index: 18, + query_index: 19, column_index: 8, rotation: Rotation( 1, ), }, Advice { - query_index: 18, + query_index: 19, column_index: 8, rotation: Rotation( 1, @@ -5448,7 +5266,7 @@ PinnedVerificationKey { ), Negated( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -5740,7 +5558,7 @@ PinnedVerificationKey { Negated( Scaled( Advice { - query_index: 21, + query_index: 20, column_index: 6, rotation: Rotation( -1, @@ -5766,7 +5584,7 @@ PinnedVerificationKey { Negated( Scaled( Advice { - query_index: 21, + query_index: 20, column_index: 6, rotation: Rotation( -1, @@ -5968,7 +5786,7 @@ PinnedVerificationKey { Negated( Scaled( Advice { - query_index: 21, + query_index: 20, column_index: 6, rotation: Rotation( -1, @@ -6089,7 +5907,7 @@ PinnedVerificationKey { ), Negated( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -6241,7 +6059,7 @@ PinnedVerificationKey { }, Negated( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -6328,7 +6146,7 @@ PinnedVerificationKey { Product( Sum( Advice { - query_index: 18, + query_index: 19, column_index: 8, rotation: Rotation( 1, @@ -6344,7 +6162,7 @@ PinnedVerificationKey { ), Sum( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -6355,14 +6173,14 @@ PinnedVerificationKey { Sum( Product( Advice { - query_index: 18, + query_index: 19, column_index: 8, rotation: Rotation( 1, ), }, Advice { - query_index: 18, + query_index: 19, column_index: 8, rotation: Rotation( 1, @@ -6371,7 +6189,7 @@ PinnedVerificationKey { ), Negated( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -6497,7 +6315,7 @@ PinnedVerificationKey { Negated( Scaled( Advice { - query_index: 21, + query_index: 20, column_index: 6, rotation: Rotation( -1, @@ -6523,7 +6341,7 @@ PinnedVerificationKey { Negated( Scaled( Advice { - query_index: 21, + query_index: 20, column_index: 6, rotation: Rotation( -1, @@ -6741,7 +6559,7 @@ PinnedVerificationKey { Negated( Scaled( Advice { - query_index: 21, + query_index: 20, column_index: 6, rotation: Rotation( -1, @@ -6878,7 +6696,7 @@ PinnedVerificationKey { ), Negated( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -7046,7 +6864,7 @@ PinnedVerificationKey { }, Negated( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -7130,7 +6948,7 @@ PinnedVerificationKey { ), Negated( Advice { - query_index: 18, + query_index: 19, column_index: 8, rotation: Rotation( 1, @@ -7230,7 +7048,7 @@ PinnedVerificationKey { Product( Sum( Advice { - query_index: 19, + query_index: 16, column_index: 9, rotation: Rotation( 1, @@ -7242,7 +7060,7 @@ PinnedVerificationKey { 0x0000000000000000000000000000000000000000000000000000000000000002, ), Advice { - query_index: 20, + query_index: 17, column_index: 9, rotation: Rotation( -1, @@ -7258,7 +7076,7 @@ PinnedVerificationKey { Negated( Sum( Advice { - query_index: 19, + query_index: 16, column_index: 9, rotation: Rotation( 1, @@ -7270,7 +7088,7 @@ PinnedVerificationKey { 0x0000000000000000000000000000000000000000000000000000000000000002, ), Advice { - query_index: 20, + query_index: 17, column_index: 9, rotation: Rotation( -1, @@ -7375,7 +7193,7 @@ PinnedVerificationKey { Product( Sum( Advice { - query_index: 19, + query_index: 16, column_index: 9, rotation: Rotation( 1, @@ -7387,7 +7205,7 @@ PinnedVerificationKey { 0x0000000000000000000000000000000000000000000000000000000000000002, ), Advice { - query_index: 20, + query_index: 17, column_index: 9, rotation: Rotation( -1, @@ -7406,7 +7224,7 @@ PinnedVerificationKey { }, Negated( Advice { - query_index: 22, + query_index: 21, column_index: 1, rotation: Rotation( -1, @@ -7423,7 +7241,7 @@ PinnedVerificationKey { Negated( Sum( Advice { - query_index: 19, + query_index: 16, column_index: 9, rotation: Rotation( 1, @@ -7435,7 +7253,7 @@ PinnedVerificationKey { 0x0000000000000000000000000000000000000000000000000000000000000002, ), Advice { - query_index: 20, + query_index: 17, column_index: 9, rotation: Rotation( -1, @@ -7455,7 +7273,7 @@ PinnedVerificationKey { ), }, Advice { - query_index: 22, + query_index: 21, column_index: 1, rotation: Rotation( -1, @@ -7650,7 +7468,7 @@ PinnedVerificationKey { Sum( Sum( Advice { - query_index: 21, + query_index: 20, column_index: 6, rotation: Rotation( -1, @@ -7850,7 +7668,7 @@ PinnedVerificationKey { ), }, Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -7960,7 +7778,7 @@ PinnedVerificationKey { ), }, Advice { - query_index: 16, + query_index: 22, column_index: 6, rotation: Rotation( 1, @@ -7971,7 +7789,7 @@ PinnedVerificationKey { ), ), Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -8070,7 +7888,7 @@ PinnedVerificationKey { Product( Sum( Advice { - query_index: 19, + query_index: 16, column_index: 9, rotation: Rotation( 1, @@ -8096,7 +7914,7 @@ PinnedVerificationKey { Negated( Sum( Advice { - query_index: 19, + query_index: 16, column_index: 9, rotation: Rotation( 1, @@ -8211,7 +8029,7 @@ PinnedVerificationKey { Product( Sum( Advice { - query_index: 19, + query_index: 16, column_index: 9, rotation: Rotation( 1, @@ -8246,7 +8064,7 @@ PinnedVerificationKey { Negated( Sum( Advice { - query_index: 19, + query_index: 16, column_index: 9, rotation: Rotation( 1, @@ -8380,7 +8198,7 @@ PinnedVerificationKey { Product( Sum( Advice { - query_index: 19, + query_index: 16, column_index: 9, rotation: Rotation( 1, @@ -8415,7 +8233,7 @@ PinnedVerificationKey { Negated( Sum( Advice { - query_index: 19, + query_index: 16, column_index: 9, rotation: Rotation( 1, @@ -10777,7 +10595,7 @@ PinnedVerificationKey { }, Sum( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -10883,7 +10701,7 @@ PinnedVerificationKey { Product( Sum( Advice { - query_index: 18, + query_index: 19, column_index: 8, rotation: Rotation( 1, @@ -10892,7 +10710,7 @@ PinnedVerificationKey { Negated( Scaled( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -10909,7 +10727,7 @@ PinnedVerificationKey { Negated( Sum( Advice { - query_index: 18, + query_index: 19, column_index: 8, rotation: Rotation( 1, @@ -10918,7 +10736,7 @@ PinnedVerificationKey { Negated( Scaled( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -11014,7 +10832,7 @@ PinnedVerificationKey { ), }, Advice { - query_index: 16, + query_index: 22, column_index: 6, rotation: Rotation( 1, @@ -11434,7 +11252,7 @@ PinnedVerificationKey { Sum( Sum( Advice { - query_index: 21, + query_index: 20, column_index: 6, rotation: Rotation( -1, @@ -11802,7 +11620,7 @@ PinnedVerificationKey { ), Negated( Advice { - query_index: 16, + query_index: 22, column_index: 6, rotation: Rotation( 1, @@ -12147,7 +11965,7 @@ PinnedVerificationKey { ), Negated( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -12492,7 +12310,7 @@ PinnedVerificationKey { ), Negated( Advice { - query_index: 18, + query_index: 19, column_index: 8, rotation: Rotation( 1, @@ -13032,7 +12850,7 @@ PinnedVerificationKey { Sum( Scaled( Advice { - query_index: 16, + query_index: 22, column_index: 6, rotation: Rotation( 1, @@ -13042,7 +12860,7 @@ PinnedVerificationKey { ), Scaled( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -13053,7 +12871,7 @@ PinnedVerificationKey { ), Scaled( Advice { - query_index: 18, + query_index: 19, column_index: 8, rotation: Rotation( 1, @@ -13188,7 +13006,7 @@ PinnedVerificationKey { Sum( Scaled( Advice { - query_index: 16, + query_index: 22, column_index: 6, rotation: Rotation( 1, @@ -13198,7 +13016,7 @@ PinnedVerificationKey { ), Scaled( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -13209,7 +13027,7 @@ PinnedVerificationKey { ), Scaled( Advice { - query_index: 18, + query_index: 19, column_index: 8, rotation: Rotation( 1, @@ -13344,7 +13162,7 @@ PinnedVerificationKey { Sum( Scaled( Advice { - query_index: 16, + query_index: 22, column_index: 6, rotation: Rotation( 1, @@ -13354,7 +13172,7 @@ PinnedVerificationKey { ), Scaled( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -13365,7 +13183,7 @@ PinnedVerificationKey { ), Scaled( Advice { - query_index: 18, + query_index: 19, column_index: 8, rotation: Rotation( 1, @@ -13452,7 +13270,7 @@ PinnedVerificationKey { Sum( Sum( Advice { - query_index: 21, + query_index: 20, column_index: 6, rotation: Rotation( -1, @@ -13468,7 +13286,7 @@ PinnedVerificationKey { ), Negated( Advice { - query_index: 16, + query_index: 22, column_index: 6, rotation: Rotation( 1, @@ -13568,7 +13386,7 @@ PinnedVerificationKey { ), Negated( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -13659,7 +13477,7 @@ PinnedVerificationKey { }, Negated( Advice { - query_index: 18, + query_index: 19, column_index: 8, rotation: Rotation( 1, @@ -15249,14 +15067,14 @@ PinnedVerificationKey { Product( Sum( Advice { - query_index: 18, + query_index: 19, column_index: 8, rotation: Rotation( 1, ), }, Advice { - query_index: 19, + query_index: 16, column_index: 9, rotation: Rotation( 1, @@ -15276,14 +15094,14 @@ PinnedVerificationKey { Sum( Product( Advice { - query_index: 18, + query_index: 19, column_index: 8, rotation: Rotation( 1, ), }, Advice { - query_index: 18, + query_index: 19, column_index: 8, rotation: Rotation( 1, @@ -15302,7 +15120,7 @@ PinnedVerificationKey { ), Negated( Advice { - query_index: 16, + query_index: 22, column_index: 6, rotation: Rotation( 1, @@ -15343,7 +15161,7 @@ PinnedVerificationKey { 0x0000000000000000000000000000000000000000000000000000000000000002, ), Advice { - query_index: 18, + query_index: 19, column_index: 8, rotation: Rotation( 1, @@ -15860,7 +15678,7 @@ PinnedVerificationKey { ), Negated( Advice { - query_index: 19, + query_index: 16, column_index: 9, rotation: Rotation( 1, @@ -15979,7 +15797,7 @@ PinnedVerificationKey { Negated( Scaled( Advice { - query_index: 16, + query_index: 22, column_index: 6, rotation: Rotation( 1, @@ -15991,7 +15809,7 @@ PinnedVerificationKey { ), Scaled( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -16105,7 +15923,7 @@ PinnedVerificationKey { Sum( Sum( Advice { - query_index: 18, + query_index: 19, column_index: 8, rotation: Rotation( 1, @@ -16223,7 +16041,7 @@ PinnedVerificationKey { ), Sum( Advice { - query_index: 16, + query_index: 22, column_index: 6, rotation: Rotation( 1, @@ -16232,7 +16050,7 @@ PinnedVerificationKey { Negated( Sum( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -16240,7 +16058,7 @@ PinnedVerificationKey { }, Scaled( Advice { - query_index: 18, + query_index: 19, column_index: 8, rotation: Rotation( 1, @@ -17636,7 +17454,7 @@ PinnedVerificationKey { ), }, Advice { - query_index: 16, + query_index: 22, column_index: 6, rotation: Rotation( 1, @@ -17766,7 +17584,7 @@ PinnedVerificationKey { ), Negated( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -17872,7 +17690,7 @@ PinnedVerificationKey { ), }, Advice { - query_index: 18, + query_index: 19, column_index: 8, rotation: Rotation( 1, @@ -18082,7 +17900,7 @@ PinnedVerificationKey { ), Product( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -18094,7 +17912,7 @@ PinnedVerificationKey { ), Negated( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -18224,7 +18042,7 @@ PinnedVerificationKey { ), Scaled( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -18235,7 +18053,7 @@ PinnedVerificationKey { ), Scaled( Advice { - query_index: 18, + query_index: 19, column_index: 8, rotation: Rotation( 1, @@ -18591,7 +18409,7 @@ PinnedVerificationKey { ), Scaled( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -18602,7 +18420,7 @@ PinnedVerificationKey { ), Scaled( Advice { - query_index: 18, + query_index: 19, column_index: 8, rotation: Rotation( 1, @@ -18953,7 +18771,7 @@ PinnedVerificationKey { }, Scaled( Advice { - query_index: 16, + query_index: 22, column_index: 6, rotation: Rotation( 1, @@ -18964,7 +18782,7 @@ PinnedVerificationKey { ), Scaled( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -19297,7 +19115,7 @@ PinnedVerificationKey { ), Sum( Advice { - query_index: 16, + query_index: 22, column_index: 6, rotation: Rotation( 1, @@ -19326,7 +19144,7 @@ PinnedVerificationKey { ), Scaled( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -19792,7 +19610,7 @@ PinnedVerificationKey { ), Scaled( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -19922,7 +19740,7 @@ PinnedVerificationKey { ), Negated( Advice { - query_index: 18, + query_index: 19, column_index: 8, rotation: Rotation( 1, @@ -20021,7 +19839,7 @@ PinnedVerificationKey { ), Product( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -20126,7 +19944,7 @@ PinnedVerificationKey { ), Product( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -20231,14 +20049,14 @@ PinnedVerificationKey { ), Product( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, ), }, Advice { - query_index: 19, + query_index: 16, column_index: 9, rotation: Rotation( 1, @@ -20373,7 +20191,7 @@ PinnedVerificationKey { ), Scaled( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -20531,7 +20349,7 @@ PinnedVerificationKey { ), Negated( Advice { - query_index: 18, + query_index: 19, column_index: 8, rotation: Rotation( 1, @@ -20646,7 +20464,7 @@ PinnedVerificationKey { ), Product( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -20767,14 +20585,14 @@ PinnedVerificationKey { ), Product( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, ), }, Advice { - query_index: 19, + query_index: 16, column_index: 9, rotation: Rotation( 1, @@ -21056,7 +20874,7 @@ PinnedVerificationKey { ), Scaled( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -21214,7 +21032,7 @@ PinnedVerificationKey { ), Negated( Advice { - query_index: 18, + query_index: 19, column_index: 8, rotation: Rotation( 1, @@ -21329,7 +21147,7 @@ PinnedVerificationKey { ), Product( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -21450,14 +21268,14 @@ PinnedVerificationKey { ), Product( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, ), }, Advice { - query_index: 19, + query_index: 16, column_index: 9, rotation: Rotation( 1, @@ -21593,7 +21411,7 @@ PinnedVerificationKey { ), Scaled( Advice { - query_index: 16, + query_index: 22, column_index: 6, rotation: Rotation( 1, @@ -21604,7 +21422,7 @@ PinnedVerificationKey { ), Scaled( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -21762,7 +21580,7 @@ PinnedVerificationKey { ), Negated( Advice { - query_index: 18, + query_index: 19, column_index: 8, rotation: Rotation( 1, @@ -21877,14 +21695,14 @@ PinnedVerificationKey { ), Product( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, ), }, Advice { - query_index: 16, + query_index: 22, column_index: 6, rotation: Rotation( 1, @@ -21998,7 +21816,7 @@ PinnedVerificationKey { ), Product( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -22119,14 +21937,14 @@ PinnedVerificationKey { ), Product( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, ), }, Advice { - query_index: 19, + query_index: 16, column_index: 9, rotation: Rotation( 1, @@ -22397,7 +22215,7 @@ PinnedVerificationKey { ), Scaled( Advice { - query_index: 16, + query_index: 22, column_index: 6, rotation: Rotation( 1, @@ -22682,7 +22500,7 @@ PinnedVerificationKey { ), Negated( Advice { - query_index: 18, + query_index: 19, column_index: 8, rotation: Rotation( 1, @@ -22925,7 +22743,7 @@ PinnedVerificationKey { ), }, Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -23046,7 +22864,7 @@ PinnedVerificationKey { ), }, Advice { - query_index: 19, + query_index: 16, column_index: 9, rotation: Rotation( 1, @@ -23288,7 +23106,7 @@ PinnedVerificationKey { ), Product( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -23300,7 +23118,7 @@ PinnedVerificationKey { ), Negated( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -23446,7 +23264,7 @@ PinnedVerificationKey { ), Scaled( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -23457,7 +23275,7 @@ PinnedVerificationKey { ), Scaled( Advice { - query_index: 18, + query_index: 19, column_index: 8, rotation: Rotation( 1, @@ -23861,7 +23679,7 @@ PinnedVerificationKey { ), Scaled( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -23872,7 +23690,7 @@ PinnedVerificationKey { ), Scaled( Advice { - query_index: 18, + query_index: 19, column_index: 8, rotation: Rotation( 1, @@ -24271,7 +24089,7 @@ PinnedVerificationKey { }, Scaled( Advice { - query_index: 16, + query_index: 22, column_index: 6, rotation: Rotation( 1, @@ -24282,7 +24100,7 @@ PinnedVerificationKey { ), Scaled( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -24663,7 +24481,7 @@ PinnedVerificationKey { ), Sum( Advice { - query_index: 16, + query_index: 22, column_index: 6, rotation: Rotation( 1, @@ -24692,7 +24510,7 @@ PinnedVerificationKey { ), Scaled( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -25222,7 +25040,7 @@ PinnedVerificationKey { ), Scaled( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -25368,7 +25186,7 @@ PinnedVerificationKey { ), Negated( Advice { - query_index: 18, + query_index: 19, column_index: 8, rotation: Rotation( 1, @@ -25483,7 +25301,7 @@ PinnedVerificationKey { ), Product( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -25604,7 +25422,7 @@ PinnedVerificationKey { ), Product( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -25725,14 +25543,14 @@ PinnedVerificationKey { ), Product( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, ), }, Advice { - query_index: 19, + query_index: 16, column_index: 9, rotation: Rotation( 1, @@ -25867,7 +25685,7 @@ PinnedVerificationKey { ), Scaled( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -26025,7 +25843,7 @@ PinnedVerificationKey { ), Negated( Advice { - query_index: 18, + query_index: 19, column_index: 8, rotation: Rotation( 1, @@ -26140,7 +25958,7 @@ PinnedVerificationKey { ), Product( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -26261,14 +26079,14 @@ PinnedVerificationKey { ), Product( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, ), }, Advice { - query_index: 19, + query_index: 16, column_index: 9, rotation: Rotation( 1, @@ -26502,7 +26320,7 @@ PinnedVerificationKey { ), Scaled( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -26612,7 +26430,7 @@ PinnedVerificationKey { ), Negated( Advice { - query_index: 18, + query_index: 19, column_index: 8, rotation: Rotation( 1, @@ -26679,7 +26497,7 @@ PinnedVerificationKey { ), Product( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -26752,14 +26570,14 @@ PinnedVerificationKey { ), Product( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, ), }, Advice { - query_index: 19, + query_index: 16, column_index: 9, rotation: Rotation( 1, @@ -26847,7 +26665,7 @@ PinnedVerificationKey { ), Scaled( Advice { - query_index: 16, + query_index: 22, column_index: 6, rotation: Rotation( 1, @@ -26858,7 +26676,7 @@ PinnedVerificationKey { ), Scaled( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -26968,7 +26786,7 @@ PinnedVerificationKey { ), Negated( Advice { - query_index: 18, + query_index: 19, column_index: 8, rotation: Rotation( 1, @@ -27035,14 +26853,14 @@ PinnedVerificationKey { ), Product( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, ), }, Advice { - query_index: 16, + query_index: 22, column_index: 6, rotation: Rotation( 1, @@ -27108,7 +26926,7 @@ PinnedVerificationKey { ), Product( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -27181,14 +26999,14 @@ PinnedVerificationKey { ), Product( Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, ), }, Advice { - query_index: 19, + query_index: 16, column_index: 9, rotation: Rotation( 1, @@ -27363,7 +27181,7 @@ PinnedVerificationKey { ), Scaled( Advice { - query_index: 16, + query_index: 22, column_index: 6, rotation: Rotation( 1, @@ -27552,7 +27370,7 @@ PinnedVerificationKey { ), Negated( Advice { - query_index: 18, + query_index: 19, column_index: 8, rotation: Rotation( 1, @@ -27699,7 +27517,7 @@ PinnedVerificationKey { ), }, Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -27772,7 +27590,7 @@ PinnedVerificationKey { ), }, Advice { - query_index: 19, + query_index: 16, column_index: 9, rotation: Rotation( 1, @@ -28037,7 +27855,7 @@ PinnedVerificationKey { ), ( Column { - index: 6, + index: 9, column_type: Advice, }, Rotation( @@ -28046,16 +27864,16 @@ PinnedVerificationKey { ), ( Column { - index: 7, + index: 9, column_type: Advice, }, Rotation( - 1, + -1, ), ), ( Column { - index: 8, + index: 7, column_type: Advice, }, Rotation( @@ -28064,7 +27882,7 @@ PinnedVerificationKey { ), ( Column { - index: 9, + index: 8, column_type: Advice, }, Rotation( @@ -28073,7 +27891,7 @@ PinnedVerificationKey { ), ( Column { - index: 9, + index: 6, column_type: Advice, }, Rotation( @@ -28082,7 +27900,7 @@ PinnedVerificationKey { ), ( Column { - index: 6, + index: 1, column_type: Advice, }, Rotation( @@ -28091,11 +27909,11 @@ PinnedVerificationKey { ), ( Column { - index: 1, + index: 6, column_type: Advice, }, Rotation( - -1, + 1, ), ), ( @@ -28495,7 +28313,7 @@ PinnedVerificationKey { Negated( Scaled( Advice { - query_index: 19, + query_index: 16, column_index: 9, rotation: Rotation( 1, @@ -28855,7 +28673,7 @@ PinnedVerificationKey { ), ), Advice { - query_index: 17, + query_index: 18, column_index: 7, rotation: Rotation( 1, @@ -29069,48 +28887,48 @@ PinnedVerificationKey { (0x3a83a8e762ebade712aa5cf3c41c730a79369475085bf1155579f7f7682408e2, 0x25b00d3ee1da9a6bbd36b35ba461da45abd931c767b863ec4a604f8ce094e4eb), (0x1caeb4d7ebb44a717f83ee5afd35446a5e2124f6a4075342ba4eff589523fb57, 0x3a8c431a13632a5b5f035eb4b804d37f2591e84d05d765ba3f70a3d61b907ebb), (0x107d95a6361fc98df9042f32451faa4fd48c1381653be7847d97cf997a55a4ad, 0x31ebf6a2e352108bb180c3278e72d88bb5bab723d3b38aa47c144fc37fb8a962), - (0x23d190a42430492732de147e7560ae1387a0e8c6b0dc405b893c99c34d124152, 0x0f7f1cb9cd7c701f22270a68d9cb484b4fffdc6144c8ce3f4eca5b646f8a939f), - (0x2b0f9d7b69e1f353868a4d542b7a23f24f39335b16c3a46fca1edb12a69bb350, 0x1e4ac9f6f6d4ba4fa4cd21e669b8293e3be8c143c795d2eb31503a9389ad4314), - (0x28f1ed28efc008bcec444c440ddbe60a8e58fe5b9a6047f0bf4d8abf599cc4ed, 0x180eef569a332ec094a76dd55de8f8ef4f087465bb2abc8dd5f7a265e048e84f), - (0x36608273abc0c47131ee4cb410b4e936fe693e9e034c686e188438d5eab134cd, 0x304e3ffef142c51a5a081a977f9c2581fa18a356e080d20cf10a044e46a3c802), - (0x355228aaa5e1134d08305d64d86cca7abac7c4114252a2a71df6a40d6a3633a9, 0x2d492e1c28cf94f9a074b14cb4cfd0cabd46121faa034d887c5f07cb743464e2), - (0x31fe923865ff58a9e59393bf64ebff3f25831371afbd2de5ddf147519ad6160a, 0x30449e9123aee5a61d3ed4c9e5822e2f60184a6c4234cfd61575e9f9572f370e), - (0x0e24cddb59a4615d0595e5439fca547a3f1ed39c4a2b0879d7e8603306d9e4b5, 0x35ab4acd6912b9bc66c19ebc9845886a4828bac17246137e36f924df2f9be175), - (0x3bd9f4407fcbb3e4ec812de2c53e70fb9203381f5a1c0f4c5e5fa52b932f5ac1, 0x06d8356f6b642427ddfad6e3642e40c0b29034baf9adb19c8a3ab251b16f39ef), - (0x21e3606f857180611036daa84bee713ff0b360b6282adc5bbaa40a5f6f7e6bc7, 0x3bff3cd61a5ae314f5eead93e3084c60a31e8b794186061a24ffa5a5dcd7e0f5), + (0x20700a506e3d86a64a39b130676dddce5f1b2bf0334fec71ed2551c204822c67, 0x3b6942d1884ab8af10fad654411308e22b2cd04efc964b92fd921678436c0c98), + (0x01050032408d33b1dfaede46b04fa62672309dd6068c0833589f4c8080e829a2, 0x0e3f605da6ff82b3aa6ad00dcf43b9478f05ff876599522bf6e560d3d014fc34), + (0x3de6d72fbecfa7c79cc390c6a7d5f80f1bcdb6ec66967002c0f003890ca6e1fb, 0x188d7336a6662b8e16e4b3a279958e60dbe1f86bfdbc1dca253db40235430f44), + (0x1581f8e414673d197d0cd5730da9bb65faae27e4a7aa70055f1c92d70fa31f7d, 0x3262ae14b4137e321618661aa7a5f4b817ff8b2846d9362813da34512c6bd965), + (0x21c96b5ae31bc87ecc34afaeb56d6c155b624b22f23f474ea80fc0bc7312735d, 0x123f4ffff944155267ab11f68de7573cb27a78b30d96ad315756086adfc75137), + (0x17a4fffca31db428439c483107a7b92f8b81451bb66892f2e8b2e4a3f2181083, 0x31f214f9e19e6282a502fd0984b81b9f7c761d66236e7600049e45ec7acfe778), + (0x31efd1ed8ab3ef69dd0a927b9c371fc0e9a2dfbd3586c5f596133f2605445850, 0x28da702b4e3f6df487b6530829a48751c10557127d11b0056c7c581091a8e03e), + (0x098c8a506a6d33d2744d0e1810c2b5070d49f597c8b87fcef67ee008da94f56c, 0x3d7dd49111a5e9834dbd5c1fee58ceae6ac758ee167522843fbb50bd95715cab), + (0x17c91b96eabea3a9ff280ae99e74bb96e80e14d770cf5d0a35814500c08159ac, 0x021d68cbd102f26c8c1b849312c3970f06d0e8c4733d325c5247137da3f940eb), (0x3c0f3f0d7b2306490dac7d578d4846c63adcc76988ce322d8691c3b8b5b0f623, 0x12d81ca672a1c18f6e0d9b7eb8fbabdbe450fae6667cf349c1a0e63ca9a0824e), (0x27d13b33003ffddcd36efb731fe94db93d181bd994e0c057e945402bc8501789, 0x0e1dde94ea3b35e0d0a66350163ba2ff9dd5070500912b7d076747816965ffd2), - (0x3049e9c8a3e6c7fe628660121f04915e03546b7a2dcb8a3e59fa99546e4f7f86, 0x2dcebc740917584f788b776f4cf1e3cd96b4a29e9df7224fd8e5f428d4112546), + (0x3fdc611a96e66e8f5c21c211bff2006204c4884b2c6df9b55d92420af8e32d15, 0x0a525125d5a85a579cbc8e4862b88800d7dbaf8a8adc18bd0181bbbab9434b8d), (0x245ebb4ccefa7c4e2d5a9d7b1746b8277abc25f74cd11b2dbb752d49612f248e, 0x145f605111205a7c3e4620ac035b3cccb6375f8d3c3469b7900e427607c401c9), (0x1751912a19fa0009ece61b686342d6b4385415e942159e8db3f174ad24d612b9, 0x0f31114ef566211d46914d0bc2d1a27a0e34eeda04dab53a0af7a37024f057a1), (0x091c6c4854fa5d9ed8a966f2a1c4946b41f6872de6c19fa8b521a0a8eb2bd899, 0x29100b4e15344d750fae4a81c82faca1e8e0573336b1f54b394946e95e7baad0), - (0x1a5bb6ffd1af2165203df63414021a531f0f2bfcec85443a180993cc222b40af, 0x0d6b8b0d2363607d15746434b670008845ed0524406c1d8a221cb6f58ee2d4ed), - (0x0e3ead6853e036099146875357a97c73327ac7aac89df7af91e8e126cf1adb3d, 0x16e19a920aa5d52ec2bb18e595b12cc3f65ae6703af8c088c3741ec59acdde8a), + (0x0f1d83f1dd2f4ba4d92cae2a2f40fc6d5d66fb2b6d1f1a2e981931cfc7c751af, 0x385ae95bb483cc65bb507d8418e447a7ad8346bc52b5114913d1e2c25c0fd11d), + (0x070664e70f0b48311a30b833a6b93cdf4ab06b872f28a723b935c88802275bd0, 0x1a3c22a9ff9d9d5434b8b979d6635d135d909b143927bc90a96cde88c6e93331), (0x34c8b83a2cc924f1b0237978c8f911e6a54375c509ba46456a011fbb74c8698c, 0x260cc681c222535c0030f702172ee8855b681c16d706b1b9a786165e06705de6), - (0x3dcb136a22551e524212c0325331a9dae5ad6ff356175e6b82a54039475be1ef, 0x3bbbd0d20ea0ebb0f36d740910947d1934bcb93ba16325ea42f124ec0cde7a81), + (0x1b7a61e8a9b32fe558433feec9aaf51204e5486aa468d7215087ed35fd6ecbe5, 0x1f36dc6852f92c141ba800f721d079ffc553c7449b85d16e7487e0c3009c7835), (0x3bb657ca32617e6242b6c6a0b166a1db205024d0441d091b8d45fb478cd4782c, 0x3189ce1b97103345fc0eafd287eed80ab186151171f22af2c9befc71a0957529), (0x25578b0a6d546cf38dc84329fad41e59690a2bd94a0db5fddb42e0db8c267827, 0x03448e4552625dda62a96318bcafcc305deafd6a028f8379d8c8d9ffa0f86e64), - (0x30d1828d7463255ad75b39ee4c718de05a762c45c5d717d059496fe05d1575b4, 0x0a8eb70a9b252ee9ee57b29e4dab191cbb29665821830b2ab60fdd5d3414de45), - (0x1bdd262015bc4b15fd90dcb6dea748cb9032fed094df3edfc0ca96c419c6ea9f, 0x28bad5ad4461b66303cb84925b54258e27953e8ef5e67c1057c823091a8562b9), - (0x09e15af05d50016fd1c475fbd3ae0be95289f239f13962f755f8b39732c73feb, 0x03760949d5057f33c30391474cbc3d447858da57e8b72487a98827b339993e60), - (0x0460fc7f74c9808eea035e8df3ac031c2d05ecafd8f0189f2d6ddac3274752fb, 0x2bc99ad7317625f1a1d6bca1781557b87e8b9976cdcaf994c827a0087d1ce182), - (0x31b7012d949d0668d34cb20200d4e159262aa0dd92114d3aa5e8aa84af51a802, 0x2eb9c55ed473e18e62dc273a8606f955690a984551fbc38e80d65199ab8d0c3d), - (0x33dced988c6a1d40aff3da1710a0e36a6b787fd6dae51ebe3dda7835c2dbea15, 0x3b54a967115d43feccf77c385dcfc6e89f30343457bc8921e017c930a381b5b0), + (0x3eab58caf9fc2aa3fee6d649cf087fe9bca284c27f57c08410b0f8a7e09d634c, 0x04b350dc56fe19a25da0882d2acb6622bdad1c4b3e2200d35acf689782c20da7), + (0x37e00880dbfd31f1c3f86201583025a666bf48745428ac39caa1d0a0acaa0bd9, 0x0ff8ef43177aa324665a296a9a444fb4a6666e250930a039a687e53acc43eddc), + (0x0934479f5c328fdb235ac47bf94cb8551784068de4fc26f0dcdca078138cb71d, 0x213f745ff2233ec74c310b142665e4e223643eb72607fc50b98aae5c7149c78f), + (0x1a98842473bddb61c943296a39cc0a8a41cec5aa02696bd0a97569ca9f839186, 0x08291ab77b541973368946a0d14c85c69a142bfda31f9021328c98b69be25e3c), + (0x34a41b2fa64d913ddc6df62a3b881658ee29bd5c69154dc30bee28d64acee443, 0x1d88f6fd73525eeb4e8b0531297edcd107bf3c2303dd615f34732d7fb01a9b16), + (0x0a6e085a051cab2808d58f29990b4ba83ed49fba5f363f67b78c329514ac79e5, 0x20b236e5722f4cff16ee1607ffa3bf60c63e9f866b27d85e85a0b06b0b8c58ec), ], permutation: VerifyingKey { commitments: [ - (0x01b2f977b5e96e2d00052aa77013b4a7522b714ed1265e5b761a90add04a677d, 0x06ae5604d2abf710e3720ab4ca37bc7a75cec4772624973990fe7acb95d2b90e), - (0x3487595fd169aea1e2055c38daf7b83a923600084a12f6beb068e9ef0886884b, 0x2094e9bc4aead08e32eb63939e7b365f7c4dbe7bb9e4fe439fe7855da2a8ef59), - (0x34b7b5583a32b3a2a188214b041b0402948759fbdf47b4b50421905728b78148, 0x10fafdf7f63a938d87eb031cbe61c6dd5915612ecb71865e94a7d7fdcb96f9c8), - (0x38b9b1352ef7da340b69e7d152d86c26abaa7eb8da2b2049c75eb908bc42dae1, 0x2b7880c4c7790b2bd4f603a95561e7e1f4fba95eba4096f6d44b89e4b0a16519), - (0x08b55ac77535aa391210533786aa9a62215fe2cb6950b60dde6563f8c4f47d58, 0x1ca42aafc1ae6e8554a933225daae97222e08a59c866024a936f66e45455c47b), - (0x3b23fca8ae9ee4f186c654428419b16169777a1b5cf7e959f73de3fd21cf1403, 0x3ff330b5247e4a88c38452e3bbaf20c79cff67a4a5b91c5ac3c6614d8cc17119), - (0x39c00327041f3b0a21cc10acacd55a94f968770121fb55e8bee01e146ea024a1, 0x38c3af47f4278d74e808aeecaf9407b17757384e9d50b59500604c7bb86687cd), - (0x0fe245acf5779d18b38c28fd4f6d921bb5487579d1fd257b7ea48f8d6de2db2f, 0x1f8a5b90451fa159c9c517a0b7250787d86c63555659298bb7ca10c537e94e12), - (0x13f4c48990bdcadf99fc60d63b04eb82f26dc2c59b515f265a66c2732abd0205, 0x20dbafa9a43baccfc5ee6947bc408b1e8974af2f5c141f3f704a747e194f04f0), - (0x16d8e8e787a2dfde1ec419ce969aa5a6c23b9d703a7440a6f085cb1fbbb21a57, 0x217624d76f302eb4f3a4f9bd3968fa79f66e4b06b5bc72048b979fb58b1f29d7), - (0x0f74011b79a40415b90f8f22db1a1433b7336307801cfe97b84f60bf7cb15d44, 0x10f2a0765e05ab426d0b183ad84616438187efbfb6122540d768895324d42667), - (0x2139a7b9a8c74648139b556ae77015620edcc81cf0a89cc960a57e16c4346a0b, 0x0295889e3496dac3174b2ba3c5399b78d9ecf042730cede62d37f6f0bfc021b6), + (0x3b61bede3f87e9208caf3626fbe7a645e1b9f9b241a96160c68b708196e86cbb, 0x0932e9c67d6bb593c9b3d6bd9697efe79bb2f81bee35abeaa8a2a0a828d8fcc6), + (0x07800024b352149368405f222a8dfbf373bd4603df89929a5d00f7ac9ffac504, 0x250be8a84de9a8ded91e85860f1b1751f6bd2c0aba96329ee2d6f0e377f4679f), + (0x3384b0dbfa6553ad5adf0b218df2cbe6243c33102a97774b4e023ec1dc2d83e9, 0x2873fe49458cd70b9d72419e0d6a6ceadb8070f4b62a0bb47c58a89269e0b583), + (0x38def0fd8f233ef8651a28ffb7ae6f1e4eaeb0acec19453a3e5a0d70b2058782, 0x0512c67736284a225f0b6617cabd76ac2e4a6805940af4480798ca884e02d277), + (0x26b6d69fd8c13013c6ab5fb74bd3fbe85d01b0abb57e149ff53e77a535c6bf40, 0x05ae4f52e4ab72ff3cf2b64df6d371fda270f4f78ed0bccce8e3138d4e30e4a0), + (0x3f1b6f3ea5a2b24646dbe1c6f7c7dbf797fe6602a344bed59668ba5413519631, 0x0401a6f6ed893aa112f234127f8c30ee6e09b45f75993351aea9974389b261d6), + (0x2f34843015cfc9c9ff59c7ecab3cbb6aea69dcf6f5af79e166f25d90f70353d5, 0x2bcfde5880412d171705b41124b404a323697c4d1008b2e8b2bf9966e5809d3d), + (0x1241f0e0058575ff769809aa569ab0ff12d5b2d7d840eae76912c16433be00ff, 0x33339365e1edbdb387b0a0b7dc5a9212c0313bb0a131c9302bc57db36174f3b0), + (0x240a361e73afa04a2e5cc578680e54bf28e3375dbb35a8918c3cdbc91f1bc25b, 0x161c53e65c1b6500b576d8fa982e2565dbe35954840b0bab8a3d912158b9dbe7), + (0x32f883bbd63b0700f0150ea8d71f6f5d7cdcc4463289983d71e9bc104d4a5c28, 0x33aeb42bec794138b8db28696bd7cef4946a8a89edcbf3f8289655ff9f9129ee), + (0x03f33d3064517ab1a8e538444013bd0d6b011f9923f8cb964763a88d6d7409e0, 0x16f534b6d12d9e011b951e374982f048f0bed808099fd3ed97cd827360f6fb65), + (0x0ee42598f7ed2c349d720bdcbe34f85d6650e1b3f2add5a71ab0bf330fcd4f51, 0x346a2c51d2895839bb3e556eb20e6af8f5248f2d538a1407622c9d69bde1448a), (0x21d210b41675a1eae44cbd0f3fd27d69e30716c71873f6089cee61acacd403ab, 0x2275e97c7e84f68bfaa528a9d8be4e059f7abefd80d03fbfca774e8414a9b7c1), (0x0f9e7de28e0f650d99d99d95c0fcd39c9dac9db5aa1973319f66922d6eb9f7d5, 0x1ba644ecc18ad711ddd33af7f695f6834e9f35c93d47a6a5273dabbe800fc7e6), (0x0aab3ab73afac76277cd94a891de15e42ceb09f3a9865dab5c814bebfbb4453f, 0x27119fec3736d99abeeef1ad7b857db7e754e0c158780ed3dd0cdd4dc2453e10), diff --git a/src/circuit_proof_test_case.bin b/src/circuit_proof_test_case.bin index 9d541d63f..695d163d9 100644 Binary files a/src/circuit_proof_test_case.bin and b/src/circuit_proof_test_case.bin differ diff --git a/src/note.rs b/src/note.rs index 81c3b166f..61a9f9a99 100644 --- a/src/note.rs +++ b/src/note.rs @@ -4,7 +4,7 @@ use core::fmt; use group::GroupEncoding; use pasta_curves::pallas; use rand::RngCore; -use subtle::CtOption; +use subtle::{Choice, ConditionallySelectable, CtOption}; use crate::{ keys::{EphemeralSecretKey, FullViewingKey, Scope, SpendingKey}, @@ -86,6 +86,17 @@ impl RandomSeed { } } +impl ConditionallySelectable for RandomSeed { + fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { + let result: Vec = + a.0.iter() + .zip(b.0.iter()) + .map(|(a_i, b_i)| u8::conditional_select(a_i, b_i, choice)) + .collect(); + RandomSeed(<[u8; 32]>::try_from(result).unwrap()) + } +} + /// A discrete amount of funds received by an address. #[derive(Debug, Copy, Clone)] pub struct Note { @@ -104,6 +115,10 @@ pub struct Note { rho: Nullifier, /// The seed randomness for various note components. rseed: RandomSeed, + /// The seed randomness for split notes. + /// + /// If it is not a split note, this field is `None`. + rseed_split_note: CtOption, } impl PartialEq for Note { @@ -144,6 +159,7 @@ impl Note { asset, rho, rseed, + rseed_split_note: CtOption::new(rseed, 0u8.into()), }; CtOption::new(note, note.commitment_inner().is_some()) } @@ -219,6 +235,11 @@ impl Note { &self.rseed } + /// Returns the rseed_split_note value of this note. + pub fn rseed_split_note(&self) -> CtOption { + self.rseed_split_note + } + /// Derives the ephemeral secret key for this note. pub(crate) fn esk(&self) -> EphemeralSecretKey { EphemeralSecretKey(self.rseed.esk(&self.rho)) @@ -264,13 +285,25 @@ impl Note { /// Derives the nullifier for this note. pub fn nullifier(&self, fvk: &FullViewingKey) -> Nullifier { + let selected_rseed = self.rseed_split_note.unwrap_or(self.rseed); + Nullifier::derive( fvk.nk(), self.rho.0, - self.rseed.psi(&self.rho), + selected_rseed.psi(&self.rho), self.commitment(), + self.rseed_split_note.is_some(), ) } + + /// Create a split note which has the same values than the input note except for + /// `rseed_split_note` which is equal to a random seed. + pub fn create_split_note(self, rng: &mut impl RngCore) -> Self { + Note { + rseed_split_note: CtOption::new(RandomSeed::random(rng, &self.rho), 1u8.into()), + ..self + } + } } /// An encrypted note. @@ -308,6 +341,8 @@ pub mod testing { address::testing::arb_address, note::nullifier::testing::arb_nullifier, value::NoteValue, }; + use subtle::CtOption; + use super::{Note, RandomSeed}; prop_compose! { @@ -331,6 +366,7 @@ pub mod testing { asset, rho, rseed, + rseed_split_note: CtOption::new(rseed, 0u8.into()), } } } @@ -349,6 +385,7 @@ pub mod testing { asset: AssetBase::native(), rho, rseed, + rseed_split_note: CtOption::new(rseed, 0u8.into()) } } } @@ -367,6 +404,7 @@ pub mod testing { asset, rho, rseed, + rseed_split_note: CtOption::new(rseed, 0u8.into()), } } } diff --git a/src/note/nullifier.rs b/src/note/nullifier.rs index a18e77fef..51769fdbf 100644 --- a/src/note/nullifier.rs +++ b/src/note/nullifier.rs @@ -3,7 +3,7 @@ use halo2_proofs::arithmetic::CurveExt; use memuse::DynamicUsage; use pasta_curves::pallas; use rand::RngCore; -use subtle::CtOption; +use subtle::{Choice, ConditionallySelectable, CtOption}; use super::NoteCommitment; use crate::{ @@ -55,10 +55,18 @@ impl Nullifier { rho: pallas::Base, psi: pallas::Base, cm: NoteCommitment, + is_split_note: Choice, ) -> Self { let k = pallas::Point::hash_to_curve("z.cash:Orchard")(b"K"); + let l = pallas::Point::hash_to_curve("z.cash:Orchard")(b"L"); - Nullifier(extract_p(&(k * mod_r_p(nk.prf_nf(rho) + psi) + cm.0))) + let nullifier = k * mod_r_p(nk.prf_nf(rho) + psi) + cm.0; + let split_note_nullifier = nullifier + l; + + let selected_nullifier = + pallas::Point::conditional_select(&nullifier, &split_note_nullifier, is_split_note); + + Nullifier(extract_p(&(selected_nullifier))) } }