zcash_primitives: Add Sapling verification key newtypes

This commit is contained in:
Jack Grigg 2023-11-03 07:10:32 +00:00
parent 1b9f26c984
commit 82535112c2
7 changed files with 75 additions and 30 deletions

View File

@ -13,6 +13,8 @@ and this library adheres to Rust's notion of
- `SaplingVerificationContext` (moved from `zcash_proofs::sapling`). - `SaplingVerificationContext` (moved from `zcash_proofs::sapling`).
- `circuit` module (moved from `zcash_proofs::circuit::sapling`). - `circuit` module (moved from `zcash_proofs::circuit::sapling`).
- `circuit::{SpendParameters, OutputParameters}` - `circuit::{SpendParameters, OutputParameters}`
- `circuit::{SpendVerifyingKey, PreparedSpendVerifyingKey}`
- `circuit::{OutputVerifyingKey, PreparedOutputVerifyingKey}`
- `constants` module. - `constants` module.
- `prover::{SpendProver, OutputProver}` - `prover::{SpendProver, OutputProver}`
- `value`: - `value`:
@ -61,6 +63,11 @@ and this library adheres to Rust's notion of
### Changed ### Changed
- `zcash_primitives::sapling`: - `zcash_primitives::sapling`:
- `BatchValidator::validate` now takes the `SpendVerifyingKey` and
`OutputVerifyingKey` newtypes.
- `SaplingVerificationContext::{check_spend, check_output}` now take
the `PreparedSpendVerifyingKey` and `PreparedOutputVerifyingKey`
newtypes.
- `address::PaymentAddress::create_note` now takes its `value` argument as a - `address::PaymentAddress::create_note` now takes its `value` argument as a
`NoteValue` instead of as a bare `u64`. `NoteValue` instead of as a bare `u64`.
- `circuit::ValueCommitmentOpening::value` is now represented as a `NoteValue` - `circuit::ValueCommitmentOpening::value` is now represented as a `NoteValue`

View File

@ -566,11 +566,31 @@ impl SpendParameters {
} }
/// Returns the verifying key for the Sapling Spend circuit. /// Returns the verifying key for the Sapling Spend circuit.
pub fn verifying_key(&self) -> &groth16::VerifyingKey<Bls12> { pub fn verifying_key(&self) -> SpendVerifyingKey {
&self.0.vk SpendVerifyingKey(self.0.vk.clone())
}
/// Returns the verifying key for the Sapling Spend circuit, with precomputations
/// optimized for verifying individual proofs.
pub fn prepared_verifying_key(&self) -> PreparedSpendVerifyingKey {
PreparedSpendVerifyingKey(groth16::prepare_verifying_key(&self.0.vk))
} }
} }
/// The verifying key for the Sapling Spend circuit.
pub struct SpendVerifyingKey(pub(crate) groth16::VerifyingKey<Bls12>);
impl SpendVerifyingKey {
/// Performs precomputations optimized for verifying individual proofs.
pub fn prepare(&self) -> PreparedSpendVerifyingKey {
PreparedSpendVerifyingKey(groth16::prepare_verifying_key(&self.0))
}
}
/// The verifying key for the Sapling Spend circuit, with precomputations optimized for
/// verifying individual proofs.
pub struct PreparedSpendVerifyingKey(pub(crate) groth16::PreparedVerifyingKey<Bls12>);
/// The parameters for the Sapling Output circuit. /// The parameters for the Sapling Output circuit.
pub struct OutputParameters(pub(crate) groth16::Parameters<Bls12>); pub struct OutputParameters(pub(crate) groth16::Parameters<Bls12>);
@ -584,11 +604,31 @@ impl OutputParameters {
} }
/// Returns the verifying key for the Sapling Output circuit. /// Returns the verifying key for the Sapling Output circuit.
pub fn verifying_key(&self) -> &groth16::VerifyingKey<Bls12> { pub fn verifying_key(&self) -> OutputVerifyingKey {
&self.0.vk OutputVerifyingKey(self.0.vk.clone())
}
/// Returns the verifying key for the Sapling Output circuit, with precomputations
/// optimized for verifying individual proofs.
pub fn prepared_verifying_key(&self) -> PreparedOutputVerifyingKey {
PreparedOutputVerifyingKey(groth16::prepare_verifying_key(&self.0.vk))
} }
} }
/// The verifying key for the Sapling Output circuit.
pub struct OutputVerifyingKey(pub(crate) groth16::VerifyingKey<Bls12>);
impl OutputVerifyingKey {
/// Performs precomputations optimized for verifying individual proofs.
pub fn prepare(&self) -> PreparedOutputVerifyingKey {
PreparedOutputVerifyingKey(groth16::prepare_verifying_key(&self.0))
}
}
/// The verifying key for the Sapling Output circuit, with precomputations optimized for
/// verifying individual proofs.
pub struct PreparedOutputVerifyingKey(pub(crate) groth16::PreparedVerifyingKey<Bls12>);
#[test] #[test]
fn test_input_circuit_with_bls12_381() { fn test_input_circuit_with_bls12_381() {
use crate::sapling::{pedersen_hash, Diversifier, Note, ProofGenerationKey, Rseed}; use crate::sapling::{pedersen_hash, Diversifier, Note, ProofGenerationKey, Rseed};

View File

@ -4,7 +4,10 @@ use group::GroupEncoding;
use rand_core::{CryptoRng, RngCore}; use rand_core::{CryptoRng, RngCore};
use super::SaplingVerificationContextInner; use super::SaplingVerificationContextInner;
use crate::transaction::components::sapling::{Authorized, Bundle}; use crate::{
sapling::circuit::{OutputVerifyingKey, SpendVerifyingKey},
transaction::components::sapling::{Authorized, Bundle},
};
/// Batch validation context for Sapling. /// Batch validation context for Sapling.
/// ///
@ -145,8 +148,8 @@ impl BatchValidator {
/// is desired, construct separate [`BatchValidator`]s for sub-batches of the bundles. /// is desired, construct separate [`BatchValidator`]s for sub-batches of the bundles.
pub fn validate<R: RngCore + CryptoRng>( pub fn validate<R: RngCore + CryptoRng>(
self, self,
spend_vk: &groth16::VerifyingKey<Bls12>, spend_vk: &SpendVerifyingKey,
output_vk: &groth16::VerifyingKey<Bls12>, output_vk: &OutputVerifyingKey,
mut rng: R, mut rng: R,
) -> bool { ) -> bool {
if !self.bundles_added { if !self.bundles_added {
@ -166,12 +169,12 @@ impl BatchValidator {
let mut verify_proofs = let mut verify_proofs =
|batch: groth16::batch::Verifier<Bls12>, vk| batch.verify(&mut rng, vk); |batch: groth16::batch::Verifier<Bls12>, vk| batch.verify(&mut rng, vk);
if verify_proofs(self.spend_proofs, spend_vk).is_err() { if verify_proofs(self.spend_proofs, &spend_vk.0).is_err() {
tracing::debug!("Spend proof batch validation failed"); tracing::debug!("Spend proof batch validation failed");
return false; return false;
} }
if verify_proofs(self.output_proofs, output_vk).is_err() { if verify_proofs(self.output_proofs, &output_vk.0).is_err() {
tracing::debug!("Output proof batch validation failed"); tracing::debug!("Output proof batch validation failed");
return false; return false;
} }

View File

@ -1,9 +1,10 @@
use bellman::groth16::{verify_proof, PreparedVerifyingKey, Proof}; use bellman::groth16::{verify_proof, Proof};
use bls12_381::Bls12; use bls12_381::Bls12;
use super::SaplingVerificationContextInner; use super::SaplingVerificationContextInner;
use crate::{ use crate::{
sapling::{ sapling::{
circuit::{PreparedOutputVerifyingKey, PreparedSpendVerifyingKey},
constants::{SPENDING_KEY_GENERATOR, VALUE_COMMITMENT_RANDOMNESS_GENERATOR}, constants::{SPENDING_KEY_GENERATOR, VALUE_COMMITMENT_RANDOMNESS_GENERATOR},
note::ExtractedNoteCommitment, note::ExtractedNoteCommitment,
redjubjub::{PublicKey, Signature}, redjubjub::{PublicKey, Signature},
@ -39,7 +40,7 @@ impl SaplingVerificationContext {
sighash_value: &[u8; 32], sighash_value: &[u8; 32],
spend_auth_sig: Signature, spend_auth_sig: Signature,
zkproof: Proof<Bls12>, zkproof: Proof<Bls12>,
verifying_key: &PreparedVerifyingKey<Bls12>, verifying_key: &PreparedSpendVerifyingKey,
) -> bool { ) -> bool {
let zip216_enabled = self.zip216_enabled; let zip216_enabled = self.zip216_enabled;
self.inner.check_spend( self.inner.check_spend(
@ -55,7 +56,7 @@ impl SaplingVerificationContext {
rk.verify_with_zip216(&msg, spend_auth_sig, SPENDING_KEY_GENERATOR, zip216_enabled) rk.verify_with_zip216(&msg, spend_auth_sig, SPENDING_KEY_GENERATOR, zip216_enabled)
}, },
|_, proof, public_inputs| { |_, proof, public_inputs| {
verify_proof(verifying_key, &proof, &public_inputs[..]).is_ok() verify_proof(&verifying_key.0, &proof, &public_inputs[..]).is_ok()
}, },
) )
} }
@ -68,11 +69,11 @@ impl SaplingVerificationContext {
cmu: ExtractedNoteCommitment, cmu: ExtractedNoteCommitment,
epk: jubjub::ExtendedPoint, epk: jubjub::ExtendedPoint,
zkproof: Proof<Bls12>, zkproof: Proof<Bls12>,
verifying_key: &PreparedVerifyingKey<Bls12>, verifying_key: &PreparedOutputVerifyingKey,
) -> bool { ) -> bool {
self.inner self.inner
.check_output(cv, cmu, epk, zkproof, |proof, public_inputs| { .check_output(cv, cmu, epk, zkproof, |proof, public_inputs| {
verify_proof(verifying_key, &proof, &public_inputs[..]).is_ok() verify_proof(&verifying_key.0, &proof, &public_inputs[..]).is_ok()
}) })
} }

View File

@ -11,9 +11,8 @@ and this library adheres to Rust's notion of
`zcash_proofs::prover::LocalTxProver` `zcash_proofs::prover::LocalTxProver`
### Changed ### Changed
- The `zcash_proofs::ZcashParameters::{spend_params, output_params}` fields - The `zcash_proofs::ZcashParameters` Sapling fields now use the parameter and
now have types `zcash_primitives::sapling::circuit::SpendParameters` and viewing key newtypes defined in `zcash_primitives::sapling::circuit`.
`zcash_primitives::sapling::circuit::OutputParameters` respectively.
### Removed ### Removed
- `zcash_proofs::circuit::sapling` (moved to `zcash_primitives::sapling::circuit`). - `zcash_proofs::circuit::sapling` (moved to `zcash_primitives::sapling::circuit`).

View File

@ -11,7 +11,9 @@
use bellman::groth16::{prepare_verifying_key, PreparedVerifyingKey, VerifyingKey}; use bellman::groth16::{prepare_verifying_key, PreparedVerifyingKey, VerifyingKey};
use bls12_381::Bls12; use bls12_381::Bls12;
use zcash_primitives::sapling::circuit::{OutputParameters, SpendParameters}; use zcash_primitives::sapling::circuit::{
OutputParameters, PreparedOutputVerifyingKey, PreparedSpendVerifyingKey, SpendParameters,
};
use std::fs::File; use std::fs::File;
use std::io::{self, BufReader}; use std::io::{self, BufReader};
@ -287,9 +289,9 @@ fn stream_params_downloads_to_disk(
/// Zcash Sprout and Sapling groth16 circuit parameters. /// Zcash Sprout and Sapling groth16 circuit parameters.
pub struct ZcashParameters { pub struct ZcashParameters {
pub spend_params: SpendParameters, pub spend_params: SpendParameters,
pub spend_vk: PreparedVerifyingKey<Bls12>, pub spend_vk: PreparedSpendVerifyingKey,
pub output_params: OutputParameters, pub output_params: OutputParameters,
pub output_vk: PreparedVerifyingKey<Bls12>, pub output_vk: PreparedOutputVerifyingKey,
pub sprout_vk: Option<PreparedVerifyingKey<Bls12>>, pub sprout_vk: Option<PreparedVerifyingKey<Bls12>>,
} }
@ -427,8 +429,8 @@ pub fn parse_parameters<R: io::Read>(
} }
// Prepare verifying keys // Prepare verifying keys
let spend_vk = prepare_verifying_key(spend_params.verifying_key()); let spend_vk = spend_params.prepared_verifying_key();
let output_vk = prepare_verifying_key(output_params.verifying_key()); let output_vk = output_params.prepared_verifying_key();
let sprout_vk = sprout_vk.map(|vk| prepare_verifying_key(&vk)); let sprout_vk = sprout_vk.map(|vk| prepare_verifying_key(&vk));
ZcashParameters { ZcashParameters {

View File

@ -1,6 +1,6 @@
//! Abstractions over the proving system and parameters for ease of use. //! Abstractions over the proving system and parameters for ease of use.
use bellman::groth16::{PreparedVerifyingKey, Proof}; use bellman::groth16::Proof;
use bls12_381::Bls12; use bls12_381::Bls12;
use std::path::Path; use std::path::Path;
use zcash_primitives::{ use zcash_primitives::{
@ -22,10 +22,6 @@ use crate::{default_params_folder, SAPLING_OUTPUT_NAME, SAPLING_SPEND_NAME};
/// locally-accessible paths. /// locally-accessible paths.
pub struct LocalTxProver { pub struct LocalTxProver {
spend_params: SpendParameters, spend_params: SpendParameters,
// TODO: Either re-introduce verification-after-proving (once the verifier is
// refactored), or remove this.
#[allow(unused)]
spend_vk: PreparedVerifyingKey<Bls12>,
output_params: OutputParameters, output_params: OutputParameters,
} }
@ -52,7 +48,6 @@ impl LocalTxProver {
let p = load_parameters(spend_path, output_path, None); let p = load_parameters(spend_path, output_path, None);
LocalTxProver { LocalTxProver {
spend_params: p.spend_params, spend_params: p.spend_params,
spend_vk: p.spend_vk,
output_params: p.output_params, output_params: p.output_params,
} }
} }
@ -77,7 +72,6 @@ impl LocalTxProver {
LocalTxProver { LocalTxProver {
spend_params: p.spend_params, spend_params: p.spend_params,
spend_vk: p.spend_vk,
output_params: p.output_params, output_params: p.output_params,
} }
} }
@ -134,7 +128,6 @@ impl LocalTxProver {
LocalTxProver { LocalTxProver {
spend_params: p.spend_params, spend_params: p.spend_params,
spend_vk: p.spend_vk,
output_params: p.output_params, output_params: p.output_params,
} }
} }