diff --git a/zcash_proofs/CHANGELOG.md b/zcash_proofs/CHANGELOG.md index 1971f9359..d95bcf422 100644 --- a/zcash_proofs/CHANGELOG.md +++ b/zcash_proofs/CHANGELOG.md @@ -12,21 +12,14 @@ and this library adheres to Rust's notion of `zcash_proofs::prover::LocalTxProver` ### Changed -- The new `SpendParameters` and `OutputParameters` types are used in the - following places: - - `zcash_proofs::ZcashParameters::{spend_params, output_params}` fields. - - `zcash_proofs::sapling::prover`: - - `SaplingProvingContext::{spend_proof, output_proof}` (the `proving_key` - arguments). -- `zcash_proofs::sapling::prover`: - - The `verifying_key` argument `SaplingProvingContext::spend_proof` has been - removed. Callers should instead use `SaplingVerifyingContext` to verify - proofs after they have been created. +- The `zcash_proofs::ZcashParameters::{spend_params, output_params}` fields + now have types `SpendParameters` and `OutputParameters` respectively. ### Removed - `zcash_proofs::circuit::sapling` (moved to `zcash_primitives::sapling::circuit`). - `zcash_proofs::circuit::{ecc, pedersen_hash}` - `zcash_proofs::constants` +- `zcash_proofs::sapling::SaplingProvingContext` ## [0.13.0] - 2023-09-25 ### Changed diff --git a/zcash_proofs/src/sapling/mod.rs b/zcash_proofs/src/sapling/mod.rs index 3aae724be..1faf0ab09 100644 --- a/zcash_proofs/src/sapling/mod.rs +++ b/zcash_proofs/src/sapling/mod.rs @@ -3,5 +3,4 @@ mod prover; mod verifier; -pub use self::prover::SaplingProvingContext; pub use self::verifier::{BatchValidator, SaplingVerificationContext}; diff --git a/zcash_proofs/src/sapling/prover.rs b/zcash_proofs/src/sapling/prover.rs index b028e3e96..f7c1d59dd 100644 --- a/zcash_proofs/src/sapling/prover.rs +++ b/zcash_proofs/src/sapling/prover.rs @@ -1,17 +1,14 @@ use bellman::groth16::{create_random_proof, Proof}; use bls12_381::Bls12; -use group::GroupEncoding; -use rand_core::{OsRng, RngCore}; +use rand_core::RngCore; use zcash_primitives::{ sapling::{ circuit::{Output, Spend, ValueCommitmentOpening}, - constants::{SPENDING_KEY_GENERATOR, VALUE_COMMITMENT_RANDOMNESS_GENERATOR}, prover::{OutputProver, SpendProver}, - redjubjub::{PublicKey, Signature}, - value::{CommitmentSum, NoteValue, TrapdoorSum, ValueCommitTrapdoor, ValueCommitment}, + value::{NoteValue, ValueCommitTrapdoor}, Diversifier, MerklePath, Note, PaymentAddress, ProofGenerationKey, Rseed, }, - transaction::components::{sapling::GrothProofBytes, Amount, GROTH_PROOF_SIZE}, + transaction::components::{sapling::GrothProofBytes, GROTH_PROOF_SIZE}, }; use crate::{OutputParameters, SpendParameters}; @@ -111,154 +108,3 @@ impl OutputProver for OutputParameters { zkproof } } - -/// A context object for creating the Sapling components of a Zcash transaction. -pub struct SaplingProvingContext { - bsk: TrapdoorSum, - // (sum of the Spend value commitments) - (sum of the Output value commitments) - cv_sum: CommitmentSum, -} - -impl Default for SaplingProvingContext { - fn default() -> Self { - SaplingProvingContext::new() - } -} - -impl SaplingProvingContext { - /// Construct a new context to be used with a single transaction. - pub fn new() -> Self { - SaplingProvingContext { - bsk: TrapdoorSum::zero(), - cv_sum: CommitmentSum::zero(), - } - } - - /// Create the value commitment, re-randomized key, and proof for a Sapling - /// SpendDescription, while accumulating its value commitment randomness - /// inside the context for later use. - #[allow(clippy::too_many_arguments)] - pub fn spend_proof( - &mut self, - proof_generation_key: ProofGenerationKey, - diversifier: Diversifier, - rseed: Rseed, - ar: jubjub::Fr, - value: u64, - anchor: bls12_381::Scalar, - merkle_path: MerklePath, - proving_key: &SpendParameters, - ) -> Result<(Proof, ValueCommitment, PublicKey), ()> { - // Initialize secure RNG - let mut rng = OsRng; - - // We create the randomness of the value commitment - let rcv = ValueCommitTrapdoor::random(&mut rng); - - // Accumulate the value commitment randomness in the context - self.bsk += &rcv; - - // Construct the value commitment - let value = NoteValue::from_raw(value); - let value_commitment = ValueCommitment::derive(value, rcv.clone()); - - // 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); - - let instance = SpendParameters::prepare_circuit( - proof_generation_key, - diversifier, - rseed, - value, - ar, - rcv, - anchor, - merkle_path, - ) - .ok_or(())?; - - // Create proof - let proof = proving_key.create_proof(instance, &mut rng); - - // Accumulate the value commitment in the context - self.cv_sum += &value_commitment; - - Ok((proof, value_commitment, rk)) - } - - /// Create the value commitment and proof for a Sapling OutputDescription, - /// while accumulating its value commitment randomness inside the context - /// for later use. - pub fn output_proof( - &mut self, - esk: jubjub::Fr, - payment_address: PaymentAddress, - rcm: jubjub::Fr, - value: u64, - proving_key: &OutputParameters, - ) -> (Proof, ValueCommitment) { - // Initialize secure RNG - let mut rng = OsRng; - - // 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 = ValueCommitTrapdoor::random(&mut rng); - - // Accumulate the value commitment randomness in the context - self.bsk -= &rcv; // Outputs subtract from the total. - - // Construct the value commitment for the proof instance - let value = NoteValue::from_raw(value); - let value_commitment = ValueCommitment::derive(value, rcv.clone()); - - // We now have a full witness for the output proof. - let instance = OutputParameters::prepare_circuit(esk, payment_address, rcm, value, rcv); - - // Create proof - let proof = proving_key.create_proof(instance, &mut rng); - - // Accumulate the value commitment in the context. We do this to check internal consistency. - self.cv_sum -= &value_commitment; // Outputs subtract from the total. - - (proof, value_commitment) - } - - /// Create the bindingSig for a Sapling transaction. All calls to spend_proof() - /// and output_proof() must be completed before calling this function. - pub fn binding_sig(&self, value_balance: Amount, sighash: &[u8; 32]) -> Result { - // Initialize secure RNG - let mut rng = OsRng; - - // Grab the current `bsk` from the context - let bsk = self.bsk.into_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. - { - // Compute the final bvk. - let final_bvk = self.cv_sum.into_bvk(value_balance); - - // The result should be the same, unless the provided valueBalance is wrong. - if bvk.0 != final_bvk.0 { - 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, - )) - } -}