From 4697232a4bca2e43d7ad697d1cd278ae18db92e7 Mon Sep 17 00:00:00 2001 From: Murisi Tarusenga Date: Sat, 27 Jan 2024 21:20:28 +0200 Subject: [PATCH 1/5] Modified the transaction generator to use mock prover when in testing mode. --- crates/sdk/src/masp.rs | 636 ++++++++++++++++++----------------------- wasm/checksums.json | 48 ++-- 2 files changed, 295 insertions(+), 389 deletions(-) diff --git a/crates/sdk/src/masp.rs b/crates/sdk/src/masp.rs index c3cf8d1bf3..2ebc23977d 100644 --- a/crates/sdk/src/masp.rs +++ b/crates/sdk/src/masp.rs @@ -4,9 +4,13 @@ use std::cmp::Ordering; use std::collections::{btree_map, BTreeMap, BTreeSet, HashMap, HashSet}; use std::env; use std::fmt::Debug; +#[cfg(any(test, feature = "testing"))] +use std::ops::AddAssign; use std::ops::Deref; use std::path::PathBuf; use std::str::FromStr; +#[cfg(any(test, feature = "testing"))] +use std::sync::Mutex; // use async_std::io::prelude::WriteExt; // use async_std::io::{self}; @@ -19,7 +23,11 @@ use masp_primitives::asset_type::AssetType; use masp_primitives::consensus::MainNetwork; #[cfg(not(feature = "mainnet"))] use masp_primitives::consensus::TestNetwork; +#[cfg(any(test, feature = "testing"))] +use masp_primitives::constants::SPENDING_KEY_GENERATOR; use masp_primitives::convert::AllowedConversion; +#[cfg(any(test, feature = "testing"))] +use masp_primitives::ff::Field; use masp_primitives::ff::PrimeField; use masp_primitives::group::GroupEncoding; use masp_primitives::memo::MemoBytes; @@ -28,13 +36,21 @@ use masp_primitives::merkle_tree::{ }; use masp_primitives::sapling::keys::FullViewingKey; use masp_primitives::sapling::note_encryption::*; +#[cfg(any(test, feature = "testing"))] +use masp_primitives::sapling::prover::TxProver; use masp_primitives::sapling::redjubjub::PublicKey; +#[cfg(any(test, feature = "testing"))] +use masp_primitives::sapling::redjubjub::Signature; use masp_primitives::sapling::{ Diversifier, Node, Note, Nullifier, ViewingKey, }; +#[cfg(any(test, feature = "testing"))] +use masp_primitives::sapling::{ProofGenerationKey, Rseed}; use masp_primitives::transaction::builder::{self, *}; use masp_primitives::transaction::components::sapling::builder::SaplingMetadata; use masp_primitives::transaction::components::transparent::builder::TransparentBuilder; +#[cfg(any(test, feature = "testing"))] +use masp_primitives::transaction::components::GROTH_PROOF_SIZE; use masp_primitives::transaction::components::{ ConvertDescription, I128Sum, OutputDescription, SpendDescription, TxOut, U64Sum, ValueSum, @@ -71,10 +87,12 @@ use thiserror::Error; use token::storage_key::is_any_shielded_action_balance_key; use token::Amount; -#[cfg(feature = "testing")] -use crate::error::EncodingError; use crate::error::{Error, PinnedBalanceError, QueryError}; use crate::io::Io; +#[cfg(any(test, feature = "testing"))] +use crate::masp_primitives::constants::VALUE_COMMITMENT_RANDOMNESS_GENERATOR; +#[cfg(any(test, feature = "testing"))] +use crate::masp_primitives::sapling::redjubjub::PrivateKey; use crate::queries::Client; use crate::rpc::{ query_block, query_conversion, query_denom, query_epoch_at_height, @@ -137,14 +155,6 @@ pub struct MaspTokenRewardData { pub locked_amount_target: Uint, } -#[cfg(feature = "testing")] -#[derive(Clone, Copy, Debug)] -enum LoadOrSaveProofs { - Load, - Save, - Neither, -} - /// A return type for gen_shielded_transfer #[derive(Error, Debug)] pub enum TransferErr { @@ -213,6 +223,241 @@ fn load_pvks() -> &'static PVKs { &VERIFIYING_KEYS } +// This function computes `value` in the exponent of the value commitment +// base +#[cfg(any(test, feature = "testing"))] +fn masp_compute_value_balance( + asset_type: AssetType, + value: i128, +) -> Option { + // Compute the absolute value (failing if -i128::MAX is + // the value) + let abs = match value.checked_abs() { + Some(a) => a as u128, + None => return None, + }; + + // Is it negative? We'll have to negate later if so. + let is_negative = value.is_negative(); + + // Compute it in the exponent + let mut abs_bytes = [0u8; 32]; + abs_bytes[0..16].copy_from_slice(&abs.to_le_bytes()); + let mut value_balance = asset_type.value_commitment_generator() + * jubjub::Fr::from_bytes(&abs_bytes).unwrap(); + + // Negate if necessary + if is_negative { + value_balance = -value_balance; + } + + // Convert to unknown order point + Some(value_balance.into()) +} + +// A context object for creating the Sapling components of a Zcash +// transaction. +pub struct SaplingProvingContext { + bsk: jubjub::Fr, + // (sum of the Spend value commitments) - (sum of the Output value + // commitments) + cv_sum: jubjub::ExtendedPoint, +} + +// An implementation of TxProver that does everything except generating +// valid zero-knowledge proofs. Uses the supplied source of randomness to +// carry out its operations. +#[cfg(any(test, feature = "testing"))] +pub struct MockTxProver(Mutex); + +#[cfg(any(test, feature = "testing"))] +impl TxProver for MockTxProver { + type SaplingProvingContext = SaplingProvingContext; + + fn new_sapling_proving_context(&self) -> Self::SaplingProvingContext { + SaplingProvingContext { + bsk: jubjub::Fr::zero(), + cv_sum: jubjub::ExtendedPoint::identity(), + } + } + + fn spend_proof( + &self, + ctx: &mut Self::SaplingProvingContext, + proof_generation_key: ProofGenerationKey, + _diversifier: Diversifier, + _rseed: Rseed, + ar: jubjub::Fr, + asset_type: AssetType, + value: u64, + _anchor: bls12_381::Scalar, + _merkle_path: MerklePath, + ) -> Result<([u8; GROTH_PROOF_SIZE], jubjub::ExtendedPoint, PublicKey), ()> + { + // Initialize secure RNG + let mut rng = self.0.lock().unwrap(); + + // We create the randomness of the value commitment + let rcv = jubjub::Fr::random(&mut *rng); + + // Accumulate the value commitment randomness in the context + { + let mut tmp = rcv; + tmp.add_assign(&ctx.bsk); + + // Update the context + ctx.bsk = tmp; + } + + // Construct the value commitment + let value_commitment = asset_type.value_commitment(value, rcv); + + // This is the result of the re-randomization, we compute it for the + // caller + let rk = PublicKey(proof_generation_key.ak.into()) + .randomize(ar, SPENDING_KEY_GENERATOR); + + // Compute value commitment + let value_commitment: jubjub::ExtendedPoint = + value_commitment.commitment().into(); + + // Accumulate the value commitment in the context + ctx.cv_sum += value_commitment; + + Ok(([0u8; GROTH_PROOF_SIZE], value_commitment, rk)) + } + + fn output_proof( + &self, + ctx: &mut Self::SaplingProvingContext, + _esk: jubjub::Fr, + _payment_address: masp_primitives::sapling::PaymentAddress, + _rcm: jubjub::Fr, + asset_type: AssetType, + value: u64, + ) -> ([u8; GROTH_PROOF_SIZE], jubjub::ExtendedPoint) { + // Initialize secure RNG + let mut rng = self.0.lock().unwrap(); + + // We construct ephemeral randomness for the value commitment. This + // randomness is not given back to the caller, but the synthetic + // blinding factor `bsk` is accumulated in the context. + let rcv = jubjub::Fr::random(&mut *rng); + + // Accumulate the value commitment randomness in the context + { + let mut tmp = rcv.neg(); // Outputs subtract from the total. + tmp.add_assign(&ctx.bsk); + + // Update the context + ctx.bsk = tmp; + } + + // Construct the value commitment for the proof instance + let value_commitment = asset_type.value_commitment(value, rcv); + + // Compute the actual value commitment + let value_commitment_point: jubjub::ExtendedPoint = + value_commitment.commitment().into(); + + // Accumulate the value commitment in the context. We do this to + // check internal consistency. + ctx.cv_sum -= value_commitment_point; // Outputs subtract from the total. + + ([0u8; GROTH_PROOF_SIZE], value_commitment_point) + } + + fn convert_proof( + &self, + ctx: &mut Self::SaplingProvingContext, + allowed_conversion: AllowedConversion, + value: u64, + _anchor: bls12_381::Scalar, + _merkle_path: MerklePath, + ) -> Result<([u8; GROTH_PROOF_SIZE], jubjub::ExtendedPoint), ()> { + // Initialize secure RNG + let mut rng = self.0.lock().unwrap(); + + // We create the randomness of the value commitment + let rcv = jubjub::Fr::random(&mut *rng); + + // Accumulate the value commitment randomness in the context + { + let mut tmp = rcv; + tmp.add_assign(&ctx.bsk); + + // Update the context + ctx.bsk = tmp; + } + + // Construct the value commitment + let value_commitment = allowed_conversion.value_commitment(value, rcv); + + // Compute value commitment + let value_commitment: jubjub::ExtendedPoint = + value_commitment.commitment().into(); + + // Accumulate the value commitment in the context + ctx.cv_sum += value_commitment; + + Ok(([0u8; GROTH_PROOF_SIZE], value_commitment)) + } + + fn binding_sig( + &self, + ctx: &mut Self::SaplingProvingContext, + assets_and_values: &I128Sum, + sighash: &[u8; 32], + ) -> Result { + // Initialize secure RNG + let mut rng = self.0.lock().unwrap(); + + // Grab the current `bsk` from the context + let bsk = PrivateKey(ctx.bsk); + + // Grab the `bvk` using DerivePublic. + let bvk = PublicKey::from_private( + &bsk, + VALUE_COMMITMENT_RANDOMNESS_GENERATOR, + ); + + // In order to check internal consistency, let's use the accumulated + // value commitments (as the verifier would) and apply + // value_balance to compare against our derived bvk. + { + let final_bvk = assets_and_values + .components() + .map(|(asset_type, value_balance)| { + // Compute value balance for each asset + // Error for bad value balances (-INT128_MAX value) + masp_compute_value_balance(*asset_type, *value_balance) + }) + .try_fold(ctx.cv_sum, |tmp, value_balance| { + // Compute cv_sum minus sum of all value balances + Result::<_, ()>::Ok(tmp - value_balance.ok_or(())?) + })?; + + // The result should be the same, unless the provided + // valueBalance is wrong. + if bvk.0 != final_bvk { + return Err(()); + } + } + + // Construct signature message + let mut data_to_be_signed = [0u8; 64]; + data_to_be_signed[0..32].copy_from_slice(&bvk.0.to_bytes()); + data_to_be_signed[32..64].copy_from_slice(&sighash[..]); + + // Sign + Ok(bsk.sign( + &data_to_be_signed, + &mut *rng, + VALUE_COMMITMENT_RANDOMNESS_GENERATOR, + )) + } +} + /// check_spend wrapper pub fn check_spend( spend: &SpendDescription<::SaplingAuth>, @@ -226,6 +471,7 @@ pub fn check_spend( Ok(zkproof) => zkproof, _ => return false, }; + ctx.check_spend( spend.cv, spend.anchor, @@ -256,6 +502,7 @@ pub fn check_output( Some(p) => p, None => return false, }; + ctx.check_output(output.cv, output.cmu, epk, zkproof, parameters) } @@ -271,6 +518,7 @@ pub fn check_convert( Ok(zkproof) => zkproof, _ => return false, }; + ctx.check_convert(convert.cv, convert.anchor, zkproof, parameters) } @@ -2209,114 +2457,20 @@ impl ShieldedContext { } } - // To speed up integration tests, we can save and load proofs - #[cfg(feature = "testing")] - let load_or_save = if let Ok(masp_proofs) = - env::var(ENV_VAR_MASP_TEST_PROOFS) - { - let parsed = match masp_proofs.to_ascii_lowercase().as_str() { - "load" => LoadOrSaveProofs::Load, - "save" => LoadOrSaveProofs::Save, - env_var => Err(Error::Other(format!( - "Unexpected value for {ENV_VAR_MASP_TEST_PROOFS} env var. \ - Expecting \"save\" or \"load\", but got \"{env_var}\"." - )))?, - }; - if env::var(ENV_VAR_MASP_TEST_SEED).is_err() { - Err(Error::Other(format!( - "Ensure to set a seed with {ENV_VAR_MASP_TEST_SEED} env \ - var when using {ENV_VAR_MASP_TEST_PROOFS} for \ - deterministic proofs." - )))?; - } - parsed - } else { - LoadOrSaveProofs::Neither - }; - let builder_clone = builder.clone().map_builder(WalletMap); - #[cfg(feature = "testing")] - let builder_bytes = borsh::to_vec(&builder_clone).map_err(|e| { - Error::from(EncodingError::Conversion(e.to_string())) - })?; - - let build_transfer = |prover: LocalTxProver| -> Result< - ShieldedTransfer, - builder::Error, - > { - let (masp_tx, metadata) = builder - .build(&prover, &FeeRule::non_standard(U64Sum::zero()))?; - Ok(ShieldedTransfer { - builder: builder_clone, - masp_tx, - metadata, - epoch, - }) - }; - - #[cfg(feature = "testing")] - { - let builder_hash = - namada_core::types::hash::Hash::sha256(&builder_bytes); - - let saved_filepath = env::current_dir() - .map_err(|e| Error::Other(e.to_string()))? - // Two up from "tests" dir to the root dir - .parent() - .and_then(std::path::Path::parent) - .ok_or_else(|| { - Error::Other("Can not get root dir".to_string()) - })? - .join(MASP_TEST_PROOFS_DIR) - .join(format!("{builder_hash}.bin")); - - if let LoadOrSaveProofs::Load = load_or_save { - let recommendation = format!( - "Re-run the tests with {ENV_VAR_MASP_TEST_PROOFS}=save to \ - re-generate proofs." - ); - let exp_str = format!( - "Read saved MASP proofs from {}. {recommendation}", - saved_filepath.to_string_lossy() - ); - let loaded_bytes = tokio::fs::read(&saved_filepath) - .await - .map_err(|_e| Error::Other(exp_str))?; - - let exp_str = format!( - "Valid `ShieldedTransfer` bytes in {}. {recommendation}", - saved_filepath.to_string_lossy() - ); - let loaded: ShieldedTransfer = - BorshDeserialize::try_from_slice(&loaded_bytes) - .map_err(|_e| Error::Other(exp_str))?; - - Ok(Some(loaded)) - } else { - // Build and return the constructed transaction - let built = build_transfer( - context.shielded().await.utils.local_tx_prover(), - )?; - if let LoadOrSaveProofs::Save = load_or_save { - let built_bytes = borsh::to_vec(&built).map_err(|e| { - Error::from(EncodingError::Conversion(e.to_string())) - })?; - tokio::fs::write(&saved_filepath, built_bytes) - .await - .map_err(|e| Error::Other(e.to_string()))?; - } - Ok(Some(built)) - } - } - + // Build and return the constructed transaction #[cfg(not(feature = "testing"))] - { - // Build and return the constructed transaction - let built = build_transfer( - context.shielded().await.utils.local_tx_prover(), - )?; - Ok(Some(built)) - } + let prover = context.shielded().await.utils.local_tx_prover(); + #[cfg(feature = "testing")] + let prover = MockTxProver(Mutex::new(OsRng)); + let (masp_tx, metadata) = + builder.build(&prover, &FeeRule::non_standard(U64Sum::zero()))?; + Ok(Some(ShieldedTransfer { + builder: builder_clone, + masp_tx, + metadata, + epoch, + })) } /// Obtain the known effects of all accepted shielded and transparent @@ -2793,21 +2947,11 @@ mod tests { #[cfg(any(test, feature = "testing"))] /// Tests and strategies for transactions pub mod testing { - use std::ops::AddAssign; use std::sync::Mutex; use masp_primitives::asset_type::AssetType; use masp_primitives::consensus::testing::arb_height; - use masp_primitives::constants::SPENDING_KEY_GENERATOR; - use masp_primitives::convert::AllowedConversion; - use masp_primitives::ff::Field; - use masp_primitives::merkle_tree::MerklePath; - use masp_primitives::sapling::prover::TxProver; - use masp_primitives::sapling::redjubjub::{PublicKey, Signature}; - use masp_primitives::sapling::{ - Diversifier, Node, PaymentAddress, ProofGenerationKey, Rseed, - }; - use masp_primitives::transaction::components::{I128Sum, GROTH_PROOF_SIZE}; + use masp_primitives::sapling::{Diversifier, Node}; use proptest::collection::SizeRange; use proptest::prelude::*; use proptest::test_runner::TestRng; @@ -2815,10 +2959,8 @@ pub mod testing { use super::*; use crate::masp_primitives::consensus::BranchId; - use crate::masp_primitives::constants::VALUE_COMMITMENT_RANDOMNESS_GENERATOR; use crate::masp_primitives::merkle_tree::FrozenCommitmentTree; use crate::masp_primitives::sapling::keys::OutgoingViewingKey; - use crate::masp_primitives::sapling::redjubjub::PrivateKey; use crate::masp_primitives::transaction::components::transparent::testing::arb_transparent_address; use crate::token::testing::arb_denomination; use crate::types::address::testing::arb_address; @@ -2851,242 +2993,6 @@ pub mod testing { } } - // This function computes `value` in the exponent of the value commitment - // base - fn masp_compute_value_balance( - asset_type: AssetType, - value: i128, - ) -> Option { - // Compute the absolute value (failing if -i128::MAX is - // the value) - let abs = match value.checked_abs() { - Some(a) => a as u128, - None => return None, - }; - - // Is it negative? We'll have to negate later if so. - let is_negative = value.is_negative(); - - // Compute it in the exponent - let mut abs_bytes = [0u8; 32]; - abs_bytes[0..16].copy_from_slice(&abs.to_le_bytes()); - let mut value_balance = asset_type.value_commitment_generator() - * jubjub::Fr::from_bytes(&abs_bytes).unwrap(); - - // Negate if necessary - if is_negative { - value_balance = -value_balance; - } - - // Convert to unknown order point - Some(value_balance.into()) - } - - // A context object for creating the Sapling components of a Zcash - // transaction. - pub struct SaplingProvingContext { - bsk: jubjub::Fr, - // (sum of the Spend value commitments) - (sum of the Output value - // commitments) - cv_sum: jubjub::ExtendedPoint, - } - - // An implementation of TxProver that does everything except generating - // valid zero-knowledge proofs. Uses the supplied source of randomness to - // carry out its operations. - pub struct MockTxProver(Mutex); - - impl TxProver for MockTxProver { - type SaplingProvingContext = SaplingProvingContext; - - fn new_sapling_proving_context(&self) -> Self::SaplingProvingContext { - SaplingProvingContext { - bsk: jubjub::Fr::zero(), - cv_sum: jubjub::ExtendedPoint::identity(), - } - } - - fn spend_proof( - &self, - ctx: &mut Self::SaplingProvingContext, - proof_generation_key: ProofGenerationKey, - _diversifier: Diversifier, - _rseed: Rseed, - ar: jubjub::Fr, - asset_type: AssetType, - value: u64, - _anchor: bls12_381::Scalar, - _merkle_path: MerklePath, - ) -> Result< - ([u8; GROTH_PROOF_SIZE], jubjub::ExtendedPoint, PublicKey), - (), - > { - // Initialize secure RNG - let mut rng = self.0.lock().unwrap(); - - // We create the randomness of the value commitment - let rcv = jubjub::Fr::random(&mut *rng); - - // Accumulate the value commitment randomness in the context - { - let mut tmp = rcv; - tmp.add_assign(&ctx.bsk); - - // Update the context - ctx.bsk = tmp; - } - - // Construct the value commitment - let value_commitment = asset_type.value_commitment(value, rcv); - - // This is the result of the re-randomization, we compute it for the - // caller - let rk = PublicKey(proof_generation_key.ak.into()) - .randomize(ar, SPENDING_KEY_GENERATOR); - - // Compute value commitment - let value_commitment: jubjub::ExtendedPoint = - value_commitment.commitment().into(); - - // Accumulate the value commitment in the context - ctx.cv_sum += value_commitment; - - Ok(([0u8; GROTH_PROOF_SIZE], value_commitment, rk)) - } - - fn output_proof( - &self, - ctx: &mut Self::SaplingProvingContext, - _esk: jubjub::Fr, - _payment_address: PaymentAddress, - _rcm: jubjub::Fr, - asset_type: AssetType, - value: u64, - ) -> ([u8; GROTH_PROOF_SIZE], jubjub::ExtendedPoint) { - // Initialize secure RNG - let mut rng = self.0.lock().unwrap(); - - // We construct ephemeral randomness for the value commitment. This - // randomness is not given back to the caller, but the synthetic - // blinding factor `bsk` is accumulated in the context. - let rcv = jubjub::Fr::random(&mut *rng); - - // Accumulate the value commitment randomness in the context - { - let mut tmp = rcv.neg(); // Outputs subtract from the total. - tmp.add_assign(&ctx.bsk); - - // Update the context - ctx.bsk = tmp; - } - - // Construct the value commitment for the proof instance - let value_commitment = asset_type.value_commitment(value, rcv); - - // Compute the actual value commitment - let value_commitment_point: jubjub::ExtendedPoint = - value_commitment.commitment().into(); - - // Accumulate the value commitment in the context. We do this to - // check internal consistency. - ctx.cv_sum -= value_commitment_point; // Outputs subtract from the total. - - ([0u8; GROTH_PROOF_SIZE], value_commitment_point) - } - - fn convert_proof( - &self, - ctx: &mut Self::SaplingProvingContext, - allowed_conversion: AllowedConversion, - value: u64, - _anchor: bls12_381::Scalar, - _merkle_path: MerklePath, - ) -> Result<([u8; GROTH_PROOF_SIZE], jubjub::ExtendedPoint), ()> - { - // Initialize secure RNG - let mut rng = self.0.lock().unwrap(); - - // We create the randomness of the value commitment - let rcv = jubjub::Fr::random(&mut *rng); - - // Accumulate the value commitment randomness in the context - { - let mut tmp = rcv; - tmp.add_assign(&ctx.bsk); - - // Update the context - ctx.bsk = tmp; - } - - // Construct the value commitment - let value_commitment = - allowed_conversion.value_commitment(value, rcv); - - // Compute value commitment - let value_commitment: jubjub::ExtendedPoint = - value_commitment.commitment().into(); - - // Accumulate the value commitment in the context - ctx.cv_sum += value_commitment; - - Ok(([0u8; GROTH_PROOF_SIZE], value_commitment)) - } - - fn binding_sig( - &self, - ctx: &mut Self::SaplingProvingContext, - assets_and_values: &I128Sum, - sighash: &[u8; 32], - ) -> Result { - // Initialize secure RNG - let mut rng = self.0.lock().unwrap(); - - // Grab the current `bsk` from the context - let bsk = PrivateKey(ctx.bsk); - - // Grab the `bvk` using DerivePublic. - let bvk = PublicKey::from_private( - &bsk, - VALUE_COMMITMENT_RANDOMNESS_GENERATOR, - ); - - // In order to check internal consistency, let's use the accumulated - // value commitments (as the verifier would) and apply - // value_balance to compare against our derived bvk. - { - let final_bvk = assets_and_values - .components() - .map(|(asset_type, value_balance)| { - // Compute value balance for each asset - // Error for bad value balances (-INT128_MAX value) - masp_compute_value_balance(*asset_type, *value_balance) - }) - .try_fold(ctx.cv_sum, |tmp, value_balance| { - // Compute cv_sum minus sum of all value balances - Result::<_, ()>::Ok(tmp - value_balance.ok_or(())?) - })?; - - // The result should be the same, unless the provided - // valueBalance is wrong. - if bvk.0 != final_bvk { - return Err(()); - } - } - - // Construct signature message - let mut data_to_be_signed = [0u8; 64]; - data_to_be_signed[0..32].copy_from_slice(&bvk.0.to_bytes()); - data_to_be_signed[32..64].copy_from_slice(&sighash[..]); - - // Sign - Ok(bsk.sign( - &data_to_be_signed, - &mut *rng, - VALUE_COMMITMENT_RANDOMNESS_GENERATOR, - )) - } - } - prop_compose! { // Expose a random number generator pub fn arb_rng()(rng in Just(()).prop_perturb(|(), rng| rng)) -> TestRng { diff --git a/wasm/checksums.json b/wasm/checksums.json index d0115fe642..9825650b0b 100644 --- a/wasm/checksums.json +++ b/wasm/checksums.json @@ -1,26 +1,26 @@ { - "tx_become_validator.wasm": "tx_become_validator.c6e8c6965cedb3b34f7caf5f50733a111637f4b9bad60751c38dd338171cd834.wasm", - "tx_bond.wasm": "tx_bond.f4525312dd6ed4558c28d8626e543e75c86ff69994d02493c0301aa387d35f2c.wasm", - "tx_bridge_pool.wasm": "tx_bridge_pool.555a94f7484a5906d02dd5789e229bf4ce52a236639fe8c31397450fe886671b.wasm", - "tx_change_consensus_key.wasm": "tx_change_consensus_key.a0ad35a50885ec061259d1dc488acd068fe5b4f9bb2350f4c3afe9eae3409899.wasm", - "tx_change_validator_commission.wasm": "tx_change_validator_commission.4fb7035ddda07ba98e98ae51095a466962c342a5f3b317356dd3bb49bb2f8d67.wasm", - "tx_change_validator_metadata.wasm": "tx_change_validator_metadata.04e986fa8ff1f852da414f798fbcede0be8845428408764c616228b2b7647114.wasm", - "tx_claim_rewards.wasm": "tx_claim_rewards.78822fcf8379224e99fd3f1408953ee498c7c6a45caad271b253bc131f4caae0.wasm", - "tx_deactivate_validator.wasm": "tx_deactivate_validator.887fb7174ecb31ab4216bac6280a011a3916760fc46a28a63faae8b5e6ac17d9.wasm", - "tx_ibc.wasm": "tx_ibc.33c98a73d9c724d7aa16a97f66295eb07b6ee4098416e736aaf956946ba37f58.wasm", - "tx_init_account.wasm": "tx_init_account.27dce52838621bf4be33d28cf2adc941af8a03d762da92ac8d9e2fc084ba4e12.wasm", - "tx_init_proposal.wasm": "tx_init_proposal.90cb78f977b78d3ec5237a4d528b4cb44893b763a1af5ba6f316b03eabc37961.wasm", - "tx_reactivate_validator.wasm": "tx_reactivate_validator.57772585eab55f15de0b0f59482398a788b0b9ebc1b13fde56e7e207b77c2c07.wasm", - "tx_redelegate.wasm": "tx_redelegate.770720386415806de18279e3c9d645329bbc8340809fb9e1c814b1ef9923b233.wasm", - "tx_resign_steward.wasm": "tx_resign_steward.ef5785006f6a2a8c90dc0cb59d17663d47a26652b47320663fb38d7ceda746f6.wasm", - "tx_reveal_pk.wasm": "tx_reveal_pk.9d0747dc82dff7b3196e6aa64d43b42e0861aca03221a7c4675e715d862c19d1.wasm", - "tx_transfer.wasm": "tx_transfer.3e0be903d24e9c72fd434fd30ecf734a2b0b8c7e3b29f5db1ded2a660d3fcdb0.wasm", - "tx_unbond.wasm": "tx_unbond.95a2e5082ccc5a4beed7960fedbbd592eca565494bfd57bf0f5a2bf4320dec49.wasm", - "tx_unjail_validator.wasm": "tx_unjail_validator.546da623777465ced2f3f5afed7ed5d1cfdf9cca7beb993bbf985266b3bbc93d.wasm", - "tx_update_account.wasm": "tx_update_account.fef4e62f363537da22f6afc4b2f1173afd40a19f18c1d9b35389cc6d7a8e8de9.wasm", - "tx_update_steward_commission.wasm": "tx_update_steward_commission.eaef9db6bb8783b3e85aa4198179eb8dd09ec7824aa7c85ef0c720f703c6e20e.wasm", - "tx_vote_proposal.wasm": "tx_vote_proposal.3b55549f56fc73bca6d168e20475badda7e9e8d0647307ca1cea439eb345907c.wasm", - "tx_withdraw.wasm": "tx_withdraw.580b8abb6e6f88f825b50e37264c122443007684d34011bed1a57cbd0aba0d02.wasm", - "vp_implicit.wasm": "vp_implicit.5ccdd3c94e2f2dcc89005e35d76d09e28e48c8b308a61cde5ed99df6c98ca0aa.wasm", - "vp_user.wasm": "vp_user.b89e2c0688e7141cc2bc2024bb6222f2141741bfb8a8d73578314c31f345b844.wasm" + "tx_become_validator.wasm": "tx_become_validator.8151595cbc63dd98da8e9242fe5c74ad197615139bde86deb76f5a82eaf5cbe4.wasm", + "tx_bond.wasm": "tx_bond.f5f51dbd9210a11a9af10895b3b1778937c2338d0b05321e628971c357845786.wasm", + "tx_bridge_pool.wasm": "tx_bridge_pool.d570eae9213c283c5d2ea161674dfde0f3a6dc1d1c7eed27c3c765c0a0ec9ed2.wasm", + "tx_change_consensus_key.wasm": "tx_change_consensus_key.62c1429e513fa0fa4e8c235b26fef4d3f0b4921fc98cec10e5e1ffcc516ca851.wasm", + "tx_change_validator_commission.wasm": "tx_change_validator_commission.b841e3db62d0982d929dee5ed382105952dc658b5120da3d6b74e3610594272b.wasm", + "tx_change_validator_metadata.wasm": "tx_change_validator_metadata.6c40ef29b37de7fe0d6cf51c51ac0f29d5a5cc767466acdda8e4793f421e2932.wasm", + "tx_claim_rewards.wasm": "tx_claim_rewards.d01907535a68bafa2a8962dce033ee34998eddf5fc091bff888022df58cb184b.wasm", + "tx_deactivate_validator.wasm": "tx_deactivate_validator.8c56c3e6a59f6e663db4aa38a8c4a9d64d98d57c061db62b8f3330562cc487b1.wasm", + "tx_ibc.wasm": "tx_ibc.5050d1f0cf8ee45ddef5b13fc59fb7215d03fe8001724416fc46e307475a2d2d.wasm", + "tx_init_account.wasm": "tx_init_account.4de8ce9ca014f3d73074062776b17b4db906eefacc0e8507d7860beb0f8561b2.wasm", + "tx_init_proposal.wasm": "tx_init_proposal.7ea60ada35b2e323e1835d07ad86be591b999257dd9b8d9f4a3361cb6f735780.wasm", + "tx_reactivate_validator.wasm": "tx_reactivate_validator.c5b959fa1a32ef16d2bc2fe8c8b046300a5b2b007f313f5e42873f98072e7840.wasm", + "tx_redelegate.wasm": "tx_redelegate.f27a966d2c9b8f10d24516396bf1504f1137d6f3fc56f2da8231a50618dfbafa.wasm", + "tx_resign_steward.wasm": "tx_resign_steward.c2cc8f8597720c6d4e2c0dc3688870f681c416819b5e923e79f8daf08918aa9d.wasm", + "tx_reveal_pk.wasm": "tx_reveal_pk.8f36c126b97e0bdceaab2eeff1b7232528b6a04bc7b994e19490fe55b27f2879.wasm", + "tx_transfer.wasm": "tx_transfer.a0e53e0968896e05abe5b82bf3d75984b5761fe297ec6a850a7a59e98e6711bc.wasm", + "tx_unbond.wasm": "tx_unbond.ad0f542be4f7dd54f90b575dba89a1dcf7e6140e18a8750a379213a6a2b24dee.wasm", + "tx_unjail_validator.wasm": "tx_unjail_validator.a4ec69c7debeaa5bfda466750490f11da07555de87cf79819cdbf1e19e896789.wasm", + "tx_update_account.wasm": "tx_update_account.7aedd91e8b4423ae41d203322deae7b4a9edb453d0eb0e3e35b3b5d057b12a5a.wasm", + "tx_update_steward_commission.wasm": "tx_update_steward_commission.6fa736ac072bf27b5ea8e1ad1270b71b33b9cbfe06b19ca5f5dd0dcbe88606c2.wasm", + "tx_vote_proposal.wasm": "tx_vote_proposal.c66250b350d07701d08c903ed219f649a4794067efd76c6af8a872d0a5cdec7e.wasm", + "tx_withdraw.wasm": "tx_withdraw.0c359816f375aaedf85cca4ae4c33e9e40e6c5c20713a2b7a223a3fb1dab59af.wasm", + "vp_implicit.wasm": "vp_implicit.6279e39412240f27d68df76364d1fabe10c11a2995d1a9baea6e9d39daa6e90e.wasm", + "vp_user.wasm": "vp_user.15c520832cbe6e48c4284017d6f4c48c4b7fa63e5ebd7f94846df2692b248af6.wasm" } \ No newline at end of file From 4af94d50acf935d6a124e07bd52cdc7e5802603a Mon Sep 17 00:00:00 2001 From: Murisi Tarusenga Date: Thu, 22 Feb 2024 14:17:11 +0200 Subject: [PATCH 2/5] Implemented a MockSaplingVerificationContext and enable it for testing flag. --- Cargo.lock | 6 +- Cargo.toml | 4 +- Makefile | 22 +-- crates/sdk/src/masp.rs | 180 ++++++++++++++++-- ...582DAD9FBD3ACA2E0F8314642810FC958594E7.bin | Bin 10105 -> 0 bytes ...D4D70154B89179E7DA6F14C700AAE1EC531E80.bin | Bin 2045 -> 0 bytes ...FD0A13DAD049EAA1ECA95234C8AB02601FC0F0.bin | Bin 2045 -> 0 bytes ...11DFBCF2AAA7876CE5FACD48AD18CB552E7349.bin | Bin 2045 -> 0 bytes ...DB8CE4F984EEA5DE6991947DC46912C5EEEC72.bin | Bin 8392 -> 0 bytes ...F2741B2A24802E41AF7F56081564BF2A160464.bin | Bin 2045 -> 0 bytes ...753FB3BE606A5729D43A6EA8F79007D34F6C60.bin | Bin 2045 -> 0 bytes ...0F3AD4FA4AB61D0B965BB9ED02971491A2B7FC.bin | Bin 2045 -> 0 bytes ...0DF6893C1C09CF3101C402BFE1465005639F14.bin | Bin 14387 -> 0 bytes ...83E61BED82F25C4452CA41B769C3BABEB62D2B.bin | Bin 2045 -> 0 bytes ...DC5356710DE7B6F6FA2B23C19412005669DC2B.bin | Bin 10105 -> 0 bytes ...9384EF0421F46F7732EE62196DEB73ECB4C225.bin | Bin 8608 -> 0 bytes ...1E2DCE33145F68A217FD50B065966646F59116.bin | Bin 2045 -> 0 bytes ...9AFB3B6AE2AA3ADCACF75E6520A66B2F7D184C.bin | Bin 7875 -> 0 bytes ...A81A7DF315190329C7C2F708876D51F60D2D60.bin | Bin 4895 -> 0 bytes ...9BC3BBACE79DF98801EB8154EA1904597854A1.bin | Bin 4679 -> 0 bytes ...EF52D368B771AD525817E722EA3E12B0A96971.bin | Bin 7650 -> 0 bytes ...F7858007C4DA521F8E3BF250A46E9342178EEB.bin | Bin 5660 -> 0 bytes ...3356453E412F862D949ABE9671C24A3903909E.bin | Bin 2045 -> 0 bytes ...861C7F98EA4325D94989648024831E350D8F98.bin | Bin 2045 -> 0 bytes test_fixtures/masp_proofs/README.md | 11 -- wasm/Cargo.lock | 6 +- wasm_for_tests/wasm_source/Cargo.lock | 6 +- 27 files changed, 180 insertions(+), 55 deletions(-) delete mode 100644 test_fixtures/masp_proofs/11BBC6FA2A8493A11DD5E488B2582DAD9FBD3ACA2E0F8314642810FC958594E7.bin delete mode 100644 test_fixtures/masp_proofs/2B6C3CEF478B4971AF997B08C8D4D70154B89179E7DA6F14C700AAE1EC531E80.bin delete mode 100644 test_fixtures/masp_proofs/3E93E8F4FC3498BA19EF4D4D70FD0A13DAD049EAA1ECA95234C8AB02601FC0F0.bin delete mode 100644 test_fixtures/masp_proofs/3FDD781F73CEEE5426EF9EF03811DFBCF2AAA7876CE5FACD48AD18CB552E7349.bin delete mode 100644 test_fixtures/masp_proofs/5355FAACD2BC8B1D4E226738EADB8CE4F984EEA5DE6991947DC46912C5EEEC72.bin delete mode 100644 test_fixtures/masp_proofs/55CC69CC552A02161C1C9EED1AF2741B2A24802E41AF7F56081564BF2A160464.bin delete mode 100644 test_fixtures/masp_proofs/59CC89A38C2D211F8765F502B6753FB3BE606A5729D43A6EA8F79007D34F6C60.bin delete mode 100644 test_fixtures/masp_proofs/6A12E11EEAA83A0D00BF7470DD0F3AD4FA4AB61D0B965BB9ED02971491A2B7FC.bin delete mode 100644 test_fixtures/masp_proofs/AF6B3A470013460A05E8A522EC0DF6893C1C09CF3101C402BFE1465005639F14.bin delete mode 100644 test_fixtures/masp_proofs/B0876E15DE7B2C742912E048F583E61BED82F25C4452CA41B769C3BABEB62D2B.bin delete mode 100644 test_fixtures/masp_proofs/BE09EB8FF98C0CAF7BA8278C4ADC5356710DE7B6F6FA2B23C19412005669DC2B.bin delete mode 100644 test_fixtures/masp_proofs/BEDD60F57C8F73C0266B1DFF869384EF0421F46F7732EE62196DEB73ECB4C225.bin delete mode 100644 test_fixtures/masp_proofs/C614F20521BADE7CE91F2399B81E2DCE33145F68A217FD50B065966646F59116.bin delete mode 100644 test_fixtures/masp_proofs/CCDB111327E4189EC4C6FE2D429AFB3B6AE2AA3ADCACF75E6520A66B2F7D184C.bin delete mode 100644 test_fixtures/masp_proofs/D1DF6FEDD8C02C1506E1DCA61CA81A7DF315190329C7C2F708876D51F60D2D60.bin delete mode 100644 test_fixtures/masp_proofs/E1D883F9C9E7FD5C51D39AE1809BC3BBACE79DF98801EB8154EA1904597854A1.bin delete mode 100644 test_fixtures/masp_proofs/EA7A88B1429EFFF0AE7167F6FBEF52D368B771AD525817E722EA3E12B0A96971.bin delete mode 100644 test_fixtures/masp_proofs/EF7D15FBFB9CC557CC8F9D4D18F7858007C4DA521F8E3BF250A46E9342178EEB.bin delete mode 100644 test_fixtures/masp_proofs/F4F0D829373DDA78336CF39EBA3356453E412F862D949ABE9671C24A3903909E.bin delete mode 100644 test_fixtures/masp_proofs/F7D91D1E43AA598631284A69E9861C7F98EA4325D94989648024831E350D8F98.bin delete mode 100644 test_fixtures/masp_proofs/README.md diff --git a/Cargo.lock b/Cargo.lock index 9ae92171d8..2bd3185408 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3897,7 +3897,7 @@ dependencies = [ [[package]] name = "masp_note_encryption" version = "1.0.0" -source = "git+https://github.com/anoma/masp?tag=v1.1.0#f24691c0eb76909e3c15ae03aef294dccebd2df3" +source = "git+https://github.com/anoma/masp?rev=30492323d98b0531fd18b6285cd94afcaa4066d2#30492323d98b0531fd18b6285cd94afcaa4066d2" dependencies = [ "borsh", "chacha20", @@ -3910,7 +3910,7 @@ dependencies = [ [[package]] name = "masp_primitives" version = "1.0.0" -source = "git+https://github.com/anoma/masp?tag=v1.1.0#f24691c0eb76909e3c15ae03aef294dccebd2df3" +source = "git+https://github.com/anoma/masp?rev=30492323d98b0531fd18b6285cd94afcaa4066d2#30492323d98b0531fd18b6285cd94afcaa4066d2" dependencies = [ "aes", "bip0039", @@ -3942,7 +3942,7 @@ dependencies = [ [[package]] name = "masp_proofs" version = "1.0.0" -source = "git+https://github.com/anoma/masp?tag=v1.1.0#f24691c0eb76909e3c15ae03aef294dccebd2df3" +source = "git+https://github.com/anoma/masp?rev=30492323d98b0531fd18b6285cd94afcaa4066d2#30492323d98b0531fd18b6285cd94afcaa4066d2" dependencies = [ "bellman", "blake2b_simd", diff --git a/Cargo.toml b/Cargo.toml index d05dfb4b39..ec924de282 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -114,8 +114,8 @@ ledger-transport-hid = "0.10.0" libc = "0.2.97" libloading = "0.7.2" # branch = "murisi/namada-integration" -masp_primitives = { git = "https://github.com/anoma/masp", tag = "v1.1.0" } -masp_proofs = { git = "https://github.com/anoma/masp", tag = "v1.1.0", default-features = false, features = ["local-prover"] } +masp_primitives = { git = "https://github.com/anoma/masp", rev = "30492323d98b0531fd18b6285cd94afcaa4066d2" } +masp_proofs = { git = "https://github.com/anoma/masp", rev = "30492323d98b0531fd18b6285cd94afcaa4066d2", default-features = false, features = ["local-prover"] } num256 = "0.3.5" num_cpus = "1.13.0" num-derive = "0.3.3" diff --git a/Makefile b/Makefile index d8b389b5a8..042d5529b6 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,6 @@ package = namada NAMADA_E2E_USE_PREBUILT_BINARIES ?= true NAMADA_E2E_DEBUG ?= true RUST_BACKTRACE ?= 1 -NAMADA_MASP_TEST_SEED ?= 0 PROPTEST_CASES ?= 100 # Disable shrinking in `make test-pos-sm` for CI runs. If the test fail in CI, # we only want to get the seed. @@ -148,14 +147,12 @@ test: test-unit test-e2e test-wasm test-benches test-coverage: # Run integration tests separately because they require `integration` - # feature (and without coverage) and run them with pre-built MASP proofs + # feature (and without coverage) $(cargo) +$(nightly) llvm-cov --output-path lcov.info \ --features namada/testing \ --lcov \ -- --skip e2e --skip pos_state_machine_test --skip integration \ -Z unstable-options --report-time && \ - NAMADA_MASP_TEST_SEED=$(NAMADA_MASP_TEST_SEED) \ - NAMADA_MASP_TEST_PROOFS=load \ $(cargo) +$(nightly) test integration:: \ --features integration \ -- -Z unstable-options --report-time @@ -175,23 +172,8 @@ test-e2e: --nocapture \ -Z unstable-options --report-time -# Run integration tests with pre-built MASP proofs +# Run integration tests test-integration: - NAMADA_MASP_TEST_SEED=$(NAMADA_MASP_TEST_SEED) \ - NAMADA_MASP_TEST_PROOFS=load \ - make test-integration-slow - -# Clear pre-built proofs, run integration tests and save the new proofs -test-integration-save-proofs: - # Clear old proofs first - rm -f test_fixtures/masp_proofs/*.bin || true - NAMADA_MASP_TEST_SEED=$(NAMADA_MASP_TEST_SEED) \ - NAMADA_MASP_TEST_PROOFS=save \ - TEST_FILTER=masp \ - make test-integration-slow - -# Run integration tests without specifying any pre-built MASP proofs option -test-integration-slow: RUST_BACKTRACE=$(RUST_BACKTRACE) \ $(cargo) +$(nightly) test integration::$(TEST_FILTER) --features integration \ -Z unstable-options \ diff --git a/crates/sdk/src/masp.rs b/crates/sdk/src/masp.rs index 2ebc23977d..fba7829179 100644 --- a/crates/sdk/src/masp.rs +++ b/crates/sdk/src/masp.rs @@ -12,6 +12,8 @@ use std::str::FromStr; #[cfg(any(test, feature = "testing"))] use std::sync::Mutex; +#[cfg(any(test, feature = "testing"))] +use bls12_381::{G1Affine, G2Affine}; // use async_std::io::prelude::WriteExt; // use async_std::io::{self}; use borsh::{BorshDeserialize, BorshSerialize}; @@ -64,8 +66,11 @@ use masp_primitives::transaction::{ }; use masp_primitives::zip32::{ExtendedFullViewingKey, ExtendedSpendingKey}; use masp_proofs::bellman::groth16::PreparedVerifyingKey; +#[cfg(any(test, feature = "testing"))] +use masp_proofs::bellman::groth16::Proof; use masp_proofs::bls12_381::Bls12; use masp_proofs::prover::LocalTxProver; +#[cfg(not(feature = "testing"))] use masp_proofs::sapling::SaplingVerificationContext; use namada_core::types::address::{Address, MASP}; use namada_core::types::dec::Dec; @@ -93,6 +98,8 @@ use crate::io::Io; use crate::masp_primitives::constants::VALUE_COMMITMENT_RANDOMNESS_GENERATOR; #[cfg(any(test, feature = "testing"))] use crate::masp_primitives::sapling::redjubjub::PrivateKey; +#[cfg(any(test, feature = "testing"))] +use crate::masp_proofs::sapling::SaplingVerificationContextInner; use crate::queries::Client; use crate::rpc::{ query_block, query_conversion, query_denom, query_epoch_at_height, @@ -106,17 +113,10 @@ use crate::{display_line, edisplay_line, rpc, MaybeSend, MaybeSync, Namada}; /// the default OS specific path is used. pub const ENV_VAR_MASP_PARAMS_DIR: &str = "NAMADA_MASP_PARAMS_DIR"; -/// Env var to either "save" proofs into files or to "load" them from -/// files. -pub const ENV_VAR_MASP_TEST_PROOFS: &str = "NAMADA_MASP_TEST_PROOFS"; - /// Randomness seed for MASP integration tests to build proofs with /// deterministic rng. pub const ENV_VAR_MASP_TEST_SEED: &str = "NAMADA_MASP_TEST_SEED"; -/// A directory to save serialized proofs for tests. -pub const MASP_TEST_PROOFS_DIR: &str = "test_fixtures/masp_proofs"; - /// The network to use for MASP #[cfg(feature = "mainnet")] const NETWORK: MainNetwork = MainNetwork; @@ -223,6 +223,124 @@ fn load_pvks() -> &'static PVKs { &VERIFIYING_KEYS } +/// A context object for verifying the Sapling components of a single Zcash +/// transaction. Same as SaplingVerificationContext, but always assumes the +/// proofs to be valid. +#[cfg(any(test, feature = "testing"))] +pub struct MockSaplingVerificationContext { + inner: SaplingVerificationContextInner, + zip216_enabled: bool, +} + +#[cfg(any(test, feature = "testing"))] +impl MockSaplingVerificationContext { + /// Construct a new context to be used with a single transaction. + pub fn new(zip216_enabled: bool) -> Self { + MockSaplingVerificationContext { + inner: SaplingVerificationContextInner::new(), + zip216_enabled, + } + } + + /// Perform consensus checks on a Sapling SpendDescription, while + /// accumulating its value commitment inside the context for later use. + #[allow(clippy::too_many_arguments)] + pub fn check_spend( + &mut self, + cv: jubjub::ExtendedPoint, + anchor: bls12_381::Scalar, + nullifier: &[u8; 32], + rk: PublicKey, + sighash_value: &[u8; 32], + spend_auth_sig: Signature, + zkproof: Proof, + _verifying_key: &PreparedVerifyingKey, + ) -> bool { + let zip216_enabled = true; + self.inner.check_spend( + cv, + anchor, + nullifier, + rk, + sighash_value, + spend_auth_sig, + zkproof, + &mut (), + |_, rk, msg, spend_auth_sig| { + rk.verify_with_zip216( + &msg, + &spend_auth_sig, + SPENDING_KEY_GENERATOR, + zip216_enabled, + ) + }, + |_, _proof, _public_inputs| true, + ) + } + + /// Perform consensus checks on a Sapling SpendDescription, while + /// accumulating its value commitment inside the context for later use. + #[allow(clippy::too_many_arguments)] + pub fn check_convert( + &mut self, + cv: jubjub::ExtendedPoint, + anchor: bls12_381::Scalar, + zkproof: Proof, + _verifying_key: &PreparedVerifyingKey, + ) -> bool { + self.inner.check_convert( + cv, + anchor, + zkproof, + &mut (), + |_, _proof, _public_inputs| true, + ) + } + + /// Perform consensus checks on a Sapling OutputDescription, while + /// accumulating its value commitment inside the context for later use. + pub fn check_output( + &mut self, + cv: jubjub::ExtendedPoint, + cmu: bls12_381::Scalar, + epk: jubjub::ExtendedPoint, + zkproof: Proof, + _verifying_key: &PreparedVerifyingKey, + ) -> bool { + self.inner.check_output( + cv, + cmu, + epk, + zkproof, + |_proof, _public_inputs| true, + ) + } + + /// Perform consensus checks on the valueBalance and bindingSig parts of a + /// Sapling transaction. All SpendDescriptions and OutputDescriptions must + /// have been checked before calling this function. + pub fn final_check( + &self, + value_balance: I128Sum, + sighash_value: &[u8; 32], + binding_sig: Signature, + ) -> bool { + self.inner.final_check( + value_balance, + sighash_value, + binding_sig, + |bvk, msg, binding_sig| { + bvk.verify_with_zip216( + &msg, + &binding_sig, + VALUE_COMMITMENT_RANDOMNESS_GENERATOR, + self.zip216_enabled, + ) + }, + ) + } +} + // This function computes `value` in the exponent of the value commitment // base #[cfg(any(test, feature = "testing"))] @@ -257,6 +375,7 @@ fn masp_compute_value_balance( // A context object for creating the Sapling components of a Zcash // transaction. +#[cfg(any(test, feature = "testing"))] pub struct SaplingProvingContext { bsk: jubjub::Fr, // (sum of the Spend value commitments) - (sum of the Output value @@ -324,7 +443,16 @@ impl TxProver for MockTxProver { // Accumulate the value commitment in the context ctx.cv_sum += value_commitment; - Ok(([0u8; GROTH_PROOF_SIZE], value_commitment, rk)) + let mut zkproof = [0u8; GROTH_PROOF_SIZE]; + let proof = Proof:: { + a: G1Affine::generator(), + b: G2Affine::generator(), + c: G1Affine::generator(), + }; + proof + .write(&mut zkproof[..]) + .expect("should be able to serialize a proof"); + Ok((zkproof, value_commitment, rk)) } fn output_proof( @@ -364,7 +492,17 @@ impl TxProver for MockTxProver { // check internal consistency. ctx.cv_sum -= value_commitment_point; // Outputs subtract from the total. - ([0u8; GROTH_PROOF_SIZE], value_commitment_point) + let mut zkproof = [0u8; GROTH_PROOF_SIZE]; + let proof = Proof:: { + a: G1Affine::generator(), + b: G2Affine::generator(), + c: G1Affine::generator(), + }; + proof + .write(&mut zkproof[..]) + .expect("should be able to serialize a proof"); + + (zkproof, value_commitment_point) } fn convert_proof( @@ -400,7 +538,17 @@ impl TxProver for MockTxProver { // Accumulate the value commitment in the context ctx.cv_sum += value_commitment; - Ok(([0u8; GROTH_PROOF_SIZE], value_commitment)) + let mut zkproof = [0u8; GROTH_PROOF_SIZE]; + let proof = Proof:: { + a: G1Affine::generator(), + b: G2Affine::generator(), + c: G1Affine::generator(), + }; + proof + .write(&mut zkproof[..]) + .expect("should be able to serialize a proof"); + + Ok((zkproof, value_commitment)) } fn binding_sig( @@ -462,7 +610,8 @@ impl TxProver for MockTxProver { pub fn check_spend( spend: &SpendDescription<::SaplingAuth>, sighash: &[u8; 32], - ctx: &mut SaplingVerificationContext, + #[cfg(not(feature = "testing"))] ctx: &mut SaplingVerificationContext, + #[cfg(feature = "testing")] ctx: &mut MockSaplingVerificationContext, parameters: &PreparedVerifyingKey, ) -> bool { let zkproof = @@ -487,7 +636,8 @@ pub fn check_spend( /// check_output wrapper pub fn check_output( output: &OutputDescription<<::SaplingAuth as masp_primitives::transaction::components::sapling::Authorization>::Proof>, - ctx: &mut SaplingVerificationContext, + #[cfg(not(feature = "testing"))] ctx: &mut SaplingVerificationContext, + #[cfg(feature = "testing")] ctx: &mut MockSaplingVerificationContext, parameters: &PreparedVerifyingKey, ) -> bool { let zkproof = @@ -509,7 +659,8 @@ pub fn check_output( /// check convert wrapper pub fn check_convert( convert: &ConvertDescription<<::SaplingAuth as masp_primitives::transaction::components::sapling::Authorization>::Proof>, - ctx: &mut SaplingVerificationContext, + #[cfg(not(feature = "testing"))] ctx: &mut SaplingVerificationContext, + #[cfg(feature = "testing")] ctx: &mut MockSaplingVerificationContext, parameters: &PreparedVerifyingKey, ) -> bool { let zkproof = @@ -596,7 +747,10 @@ pub fn verify_shielded_tx(transaction: &Transaction) -> bool { output_vk, } = load_pvks(); + #[cfg(not(feature = "testing"))] let mut ctx = SaplingVerificationContext::new(true); + #[cfg(feature = "testing")] + let mut ctx = MockSaplingVerificationContext::new(true); let spends_valid = sapling_bundle .shielded_spends .iter() diff --git a/test_fixtures/masp_proofs/11BBC6FA2A8493A11DD5E488B2582DAD9FBD3ACA2E0F8314642810FC958594E7.bin b/test_fixtures/masp_proofs/11BBC6FA2A8493A11DD5E488B2582DAD9FBD3ACA2E0F8314642810FC958594E7.bin deleted file mode 100644 index d8d0752e4d74fc2a475d90ee3fcf3eb99f40c073..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10105 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 O_N%-8C5V41sQ&^n#u%Ca diff --git a/test_fixtures/masp_proofs/2B6C3CEF478B4971AF997B08C8D4D70154B89179E7DA6F14C700AAE1EC531E80.bin b/test_fixtures/masp_proofs/2B6C3CEF478B4971AF997B08C8D4D70154B89179E7DA6F14C700AAE1EC531E80.bin deleted file mode 100644 index 896302b0a08d269fd8a34f058423f58b29ea1a40..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2045 zcmaF;9|9N|7#JF^G8ZVUS6P1idwTMUd*`j52&K;c`)g|Vm&j%3=8AMKW|(4H4phbv zdv&X*n!+=a*(|4}-0ZD4_py8UfW#SI1I;4Jpqx`3PUNCOFW0HKi+>WQ= zqEq3A=a-oFisdyPO<8mO+L8OVgzRCe&(}G-$zE%Bb*6gXlp4lkVqAvjnGVinyYTJl zYT2^xsoy{j9|a>e1ekz6=Tcv;wygC3OHd$yk~Jf-sS`(jV!SB!a)q+JcDQX)zJ1%9 zHqVY<&UXWTeSL2mvHktEOsfOs%j*hT_>&@@%;}%`J$A-Mi>Ma|eJA)T>zsEo3SGX? z=%?kWwhgBDZpM{gFIBuRR>aQMx{)iBJN*2M9ziayy;)A5Gc9X;%`L5sZj!D|AU@D)m+oUnv;)s0P^WPli4z7<6ZA)8|GJWok z8yjYAc;}feZ2I%>q3_zeL=%`2)^JT(v%Kx#rO4f#4u7Sd&N#8w^>7qxN3XH2$+W-C zVzSxaN+WMe%YW1jlris_J^y;y`X{LP&HbiIO5vDU0E`0uLIuiuhU76>Cu*OIh)maspxTdZBdc*6`O_q zN2(*HTC6^N@Y6935k>uz&%F{@FRr(e$~gRA>~hEv*By~ z9bwq9kNv!((!{r0z6C%3%Rf=!X}}sugZJ!qfhz42gzx%&5O7$rV8!q6Q(6r-MdizJ zT&h&XwLd&ewFzT&i{W|^SsS+Ze}q5 z?F5G(&-2b-NZEGpfAqRUf9FJ=D;4)od_B;&TkU>D&pNSRKbL%&@rAF9**E5f>C8JZ zt7m%|g!7-8*dy?(KJwb5z>hD~_{2W_+qCfV-+D1l#?T%8j#Eu9{cJ9^dCGI!*Zo5M z-Jn1vgfnQNtv$>1*F@ zZFKlcvf+!fow+Mjubg~X!@Iw_NS@PXtCPB3b3ISn-G6xA7#EAFD=R0 z+g*K$@v3t9lKW5WJbI7%-^$t?R_NB2-7Htbl_FkTx6b?6fiAI>><>>E^LdjkCbPhb OWN_6A<$y{n5C8yK_Uz>V diff --git a/test_fixtures/masp_proofs/3E93E8F4FC3498BA19EF4D4D70FD0A13DAD049EAA1ECA95234C8AB02601FC0F0.bin b/test_fixtures/masp_proofs/3E93E8F4FC3498BA19EF4D4D70FD0A13DAD049EAA1ECA95234C8AB02601FC0F0.bin deleted file mode 100644 index 5747b31c0179afb8170fa41f07c7b6564eea08e1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2045 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 MA{kt@LOC!t06k{UtN;K2 diff --git a/test_fixtures/masp_proofs/5355FAACD2BC8B1D4E226738EADB8CE4F984EEA5DE6991947DC46912C5EEEC72.bin b/test_fixtures/masp_proofs/5355FAACD2BC8B1D4E226738EADB8CE4F984EEA5DE6991947DC46912C5EEEC72.bin deleted file mode 100644 index c3af4cfd0cd7e2a1bae0ad839683d383c1ef9364..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8392 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

dX*f{S8ui4!4)x^5^;NS9$g@3bl6}B$- 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 diff --git a/test_fixtures/masp_proofs/B0876E15DE7B2C742912E048F583E61BED82F25C4452CA41B769C3BABEB62D2B.bin b/test_fixtures/masp_proofs/B0876E15DE7B2C742912E048F583E61BED82F25C4452CA41B769C3BABEB62D2B.bin deleted file mode 100644 index dd3f26ba0b5e09c55eede5979d2697289b2a04d7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2045 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 De%Lu! diff --git a/test_fixtures/masp_proofs/C614F20521BADE7CE91F2399B81E2DCE33145F68A217FD50B065966646F59116.bin b/test_fixtures/masp_proofs/C614F20521BADE7CE91F2399B81E2DCE33145F68A217FD50B065966646F59116.bin deleted file mode 100644 index f30214b8c8e5884234bd94a8dd6b77e3e418c469..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2045 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 VDf|Ea|BF%o*~b12tKU0^{{V@WqJaPa diff --git a/test_fixtures/masp_proofs/D1DF6FEDD8C02C1506E1DCA61CA81A7DF315190329C7C2F708876D51F60D2D60.bin b/test_fixtures/masp_proofs/D1DF6FEDD8C02C1506E1DCA61CA81A7DF315190329C7C2F708876D51F60D2D60.bin deleted file mode 100644 index 8357cbe5ed1cb99b84554487ffc9a07d4392a450..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4895 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 diff --git a/test_fixtures/masp_proofs/E1D883F9C9E7FD5C51D39AE1809BC3BBACE79DF98801EB8154EA1904597854A1.bin b/test_fixtures/masp_proofs/E1D883F9C9E7FD5C51D39AE1809BC3BBACE79DF98801EB8154EA1904597854A1.bin deleted file mode 100644 index a25fa32cf0c24c8d7437caad4c3549b2c087aa26..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4679 zcmeHKRZyG@lf?-P?ixOvzyx==0fKA7po0dO3^2jni2#8?f{5LRV^LqO!jjyvPlFlo0Z821?D2tep z`@b_K-SrVk;d}JEf7k!37W1E$Kk=`pC&n>Y`yKj0E=X-wezhKOrTr!jq0>8y` zThCR(Gt1>gkBdXQ$XU{)SRXOyil*nN;sc8MF_ZWZcT4_&AWu_8 zv<4mtI7qQ|Por!6I~`s95XyeS|8CMV{pxXIXdRD^9bn)m^>hKmSDP&og_W2(BuCca zBwf43J7H`if#Ms&`KI)GOFF_=9``7~s?I)NlS^y9Nk+F%Dnv6^ZrhKnx4p{j4}@bkY8fJa z+vjcGU0_*=fSD2zSOFYg&eG1U3uX`L9)mq2vGTEkox#IZa=eZH_S`Xv0hm2BghHcO z?Vs_+&NoV!y&{u{ELr?&K7n-5L3>K3b|Qxf;(mJ{6=HwODZZ6*;s@aXz_Q}ypxd4) zX20}3{hKd?-Y=_Hdq{>SkCxhxmvSKYBtRMUt@dFXJFqzhavzoB=9~n#^XTXmVRpUAZIyj|XL50HJ)QSKx=Q`jBgotLcS-84^2pc5{PucG zKn8M6F04)tQig{I`WD&C%4{aN<=2Dk@v-onQVyxj08RV`wLuMESvYZP^>c-4ybp`9-eHs<>z1qZur&wXy@MnA6fHI1aldaJ}as) zWCxsPY+KUd^MTGm4Z3u$bMscpFSx#)kgZvWKuZ<&;$HwuB>0hnWi&o`u_fg~jH{GH zyq~a%iC^{|^X>`5_CsZW2vMkMiPeM4s?96U$+d~lU0+`&3okM;4eV66eQ@)FN-ju>7+0H^otEftQ;((+f-pY2@aW}Y87u^OzlAunzxpjIHUjKY zI%>eL-B?@A4SXf{zrT-YOop@LP}1OJnCnU60ru zvhvA#msYNUP3o-yQzI&US*+rCUO2GEA4{)zV~XAQY0cOHg%;40m3$ z|D#lY1o%&m`JYsBdo_-hVLQz?Nq-na^nvR1Dlvt@#<^2$!luXy8(E)&8w#T`EE9sdIq^B=;C}&(-|F8&z|RaP1IoLhix1odV3Z>@6@G{woGT}>!ZnYLk;v5FnQyrF<{(Se> zQ$IktVz*!S3-<@gBuw||=C^go!^tKH>r785oqy`!4e?bqsjwVUI7T;(SFP3CIx%y>#V1>*UPw~|#>c{v{q27E*> z8)8~F@*D|}QRgo1NiOEyxa*ldiUhruzzXd675N> z$jWE2Q+DFVrQg<(qi>lPc&y|y%2MsCwJo-Fy+CutSsit8=~w;lhy^5MY5xzb*T#* zj5_B6WV;`K&~>+jn*R#ThOU6nlKT`J9|Jz5dn>mx2`?K%C z#eowmbn1yjr4tVdGOM$y2Hp=oud*@Q(8xA=JIt5vki*A`xzl{o_uz`5ZYO~jPR+e~ zjcu|KC3Ih?-Ac!_Rlr-z*m4~?pO^#+AYE)274X9Py~NIGDzTFeYxt2FtLu}Lqzz%W zF_E9L{#@T05%brMtuV!?V@@TvzdJ%E69>*$pD^pGNlmkzB}i8L6A}PrZ(IyKd=lj% z4~m%CC+KAXrIH02?R>yaSGZ?maRm${d6Jm;($}{2oT7~ciB`UQ2_3HE4@XQ+M21o7 zk5yhfK=w$F1SPjeE?8;rcoF4> zg2SbdhCI{v?|N$%^Vs`0gn!c(!c!TX7@uP)`9I5MSF2J{eV&&v0#TZrzqXphQyW@- z*AEh}f3_PQd{B*ZGsD?KqRsP&eudPme)H=Lkvtv!2ZO@d_-CZ4e+%dJ)!Q3nr(sPk|lZ)!3! zbWw(H!UOXxBwoDL)wSbjVi};8)PV#tBG?AnDoP_w*H7YG8XfKVm#@#n_tI