Merge pull request #1001 from zcash/752-separate-sapling-provers
Separate Sapling provers
This commit is contained in:
commit
ad01585d34
|
@ -11,6 +11,7 @@ and this library adheres to Rust's notion of
|
||||||
- `zcash_primitives::sapling`:
|
- `zcash_primitives::sapling`:
|
||||||
- `circuit` module (moved from `zcash_proofs::circuit::sapling`).
|
- `circuit` module (moved from `zcash_proofs::circuit::sapling`).
|
||||||
- `constants` module.
|
- `constants` module.
|
||||||
|
- `prover::{SpendProver, OutputProver}`
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
- `zcash_primitives::constants`:
|
- `zcash_primitives::constants`:
|
||||||
|
|
|
@ -1,16 +1,75 @@
|
||||||
//! Abstractions over the proving system and parameters.
|
//! Abstractions over the proving system and parameters.
|
||||||
|
|
||||||
|
use rand_core::RngCore;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
sapling::{
|
sapling::{
|
||||||
self,
|
self,
|
||||||
redjubjub::{PublicKey, Signature},
|
redjubjub::{PublicKey, Signature},
|
||||||
value::ValueCommitment,
|
value::{NoteValue, ValueCommitTrapdoor, ValueCommitment},
|
||||||
|
MerklePath,
|
||||||
},
|
},
|
||||||
transaction::components::{Amount, GROTH_PROOF_SIZE},
|
transaction::components::{Amount, GROTH_PROOF_SIZE},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{Diversifier, PaymentAddress, ProofGenerationKey, Rseed};
|
use super::{Diversifier, PaymentAddress, ProofGenerationKey, Rseed};
|
||||||
|
|
||||||
|
/// Interface for creating Sapling Spend proofs.
|
||||||
|
pub trait SpendProver {
|
||||||
|
/// The proof type created by this prover.
|
||||||
|
type Proof;
|
||||||
|
|
||||||
|
/// Prepares an instance of the Sapling Spend circuit for the given inputs.
|
||||||
|
///
|
||||||
|
/// Returns `None` if `diversifier` is not a valid Sapling diversifier.
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
fn prepare_circuit(
|
||||||
|
proof_generation_key: ProofGenerationKey,
|
||||||
|
diversifier: Diversifier,
|
||||||
|
rseed: Rseed,
|
||||||
|
value: NoteValue,
|
||||||
|
alpha: jubjub::Fr,
|
||||||
|
rcv: ValueCommitTrapdoor,
|
||||||
|
anchor: bls12_381::Scalar,
|
||||||
|
merkle_path: MerklePath,
|
||||||
|
) -> Option<sapling::circuit::Spend>;
|
||||||
|
|
||||||
|
/// Create the proof for a Sapling [`SpendDescription`].
|
||||||
|
///
|
||||||
|
/// [`SpendDescription`]: crate::transaction::components::SpendDescription
|
||||||
|
fn create_proof<R: RngCore>(
|
||||||
|
&self,
|
||||||
|
circuit: sapling::circuit::Spend,
|
||||||
|
rng: &mut R,
|
||||||
|
) -> Self::Proof;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Interface for creating Sapling Output proofs.
|
||||||
|
pub trait OutputProver {
|
||||||
|
/// The proof type created by this prover.
|
||||||
|
type Proof;
|
||||||
|
|
||||||
|
/// Prepares an instance of the Sapling Output circuit for the given inputs.
|
||||||
|
///
|
||||||
|
/// Returns `None` if `diversifier` is not a valid Sapling diversifier.
|
||||||
|
fn prepare_circuit(
|
||||||
|
esk: jubjub::Fr,
|
||||||
|
payment_address: PaymentAddress,
|
||||||
|
rcm: jubjub::Fr,
|
||||||
|
value: NoteValue,
|
||||||
|
rcv: ValueCommitTrapdoor,
|
||||||
|
) -> sapling::circuit::Output;
|
||||||
|
|
||||||
|
/// Create the proof for a Sapling [`OutputDescription`].
|
||||||
|
///
|
||||||
|
/// [`OutputDescription`]: crate::transaction::components::OutputDescription
|
||||||
|
fn create_proof<R: RngCore>(
|
||||||
|
&self,
|
||||||
|
circuit: sapling::circuit::Output,
|
||||||
|
rng: &mut R,
|
||||||
|
) -> Self::Proof;
|
||||||
|
}
|
||||||
|
|
||||||
/// Interface for creating zero-knowledge proofs for shielded transactions.
|
/// Interface for creating zero-knowledge proofs for shielded transactions.
|
||||||
pub trait TxProver {
|
pub trait TxProver {
|
||||||
/// Type for persisting any necessary context across multiple Sapling proofs.
|
/// Type for persisting any necessary context across multiple Sapling proofs.
|
||||||
|
|
|
@ -6,6 +6,21 @@ and this library adheres to Rust's notion of
|
||||||
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
### Added
|
||||||
|
- `zcash_proofs::{SpendParameters, OutputParameters}`
|
||||||
|
|
||||||
|
### 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.
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
- `zcash_proofs::circuit::sapling` (moved to `zcash_primitives::sapling::circuit`).
|
- `zcash_proofs::circuit::sapling` (moved to `zcash_primitives::sapling::circuit`).
|
||||||
- `zcash_proofs::circuit::{ecc, pedersen_hash}`
|
- `zcash_proofs::circuit::{ecc, pedersen_hash}`
|
||||||
|
|
|
@ -283,11 +283,17 @@ fn stream_params_downloads_to_disk(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The parameters for the Sapling Spend circuit.
|
||||||
|
pub struct SpendParameters(Parameters<Bls12>);
|
||||||
|
|
||||||
|
/// The parameters for the Sapling Output circuit.
|
||||||
|
pub struct OutputParameters(Parameters<Bls12>);
|
||||||
|
|
||||||
/// Zcash Sprout and Sapling groth16 circuit parameters.
|
/// Zcash Sprout and Sapling groth16 circuit parameters.
|
||||||
pub struct ZcashParameters {
|
pub struct ZcashParameters {
|
||||||
pub spend_params: Parameters<Bls12>,
|
pub spend_params: SpendParameters,
|
||||||
pub spend_vk: PreparedVerifyingKey<Bls12>,
|
pub spend_vk: PreparedVerifyingKey<Bls12>,
|
||||||
pub output_params: Parameters<Bls12>,
|
pub output_params: OutputParameters,
|
||||||
pub output_vk: PreparedVerifyingKey<Bls12>,
|
pub output_vk: PreparedVerifyingKey<Bls12>,
|
||||||
pub sprout_vk: Option<PreparedVerifyingKey<Bls12>>,
|
pub sprout_vk: Option<PreparedVerifyingKey<Bls12>>,
|
||||||
}
|
}
|
||||||
|
@ -429,9 +435,9 @@ pub fn parse_parameters<R: io::Read>(
|
||||||
let sprout_vk = sprout_vk.map(|vk| prepare_verifying_key(&vk));
|
let sprout_vk = sprout_vk.map(|vk| prepare_verifying_key(&vk));
|
||||||
|
|
||||||
ZcashParameters {
|
ZcashParameters {
|
||||||
spend_params,
|
spend_params: SpendParameters(spend_params),
|
||||||
spend_vk,
|
spend_vk,
|
||||||
output_params,
|
output_params: OutputParameters(output_params),
|
||||||
output_vk,
|
output_vk,
|
||||||
sprout_vk,
|
sprout_vk,
|
||||||
}
|
}
|
||||||
|
|
|
@ -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::{Parameters, PreparedVerifyingKey};
|
use bellman::groth16::PreparedVerifyingKey;
|
||||||
use bls12_381::Bls12;
|
use bls12_381::Bls12;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use zcash_primitives::{
|
use zcash_primitives::{
|
||||||
|
@ -13,7 +13,10 @@ use zcash_primitives::{
|
||||||
transaction::components::{Amount, GROTH_PROOF_SIZE},
|
transaction::components::{Amount, GROTH_PROOF_SIZE},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{load_parameters, parse_parameters, sapling::SaplingProvingContext};
|
use crate::{
|
||||||
|
load_parameters, parse_parameters, sapling::SaplingProvingContext, OutputParameters,
|
||||||
|
SpendParameters,
|
||||||
|
};
|
||||||
|
|
||||||
#[cfg(feature = "local-prover")]
|
#[cfg(feature = "local-prover")]
|
||||||
use crate::{default_params_folder, SAPLING_OUTPUT_NAME, SAPLING_SPEND_NAME};
|
use crate::{default_params_folder, SAPLING_OUTPUT_NAME, SAPLING_SPEND_NAME};
|
||||||
|
@ -21,9 +24,12 @@ use crate::{default_params_folder, SAPLING_OUTPUT_NAME, SAPLING_SPEND_NAME};
|
||||||
/// An implementation of [`TxProver`] using Sapling Spend and Output parameters from
|
/// An implementation of [`TxProver`] using Sapling Spend and Output parameters from
|
||||||
/// locally-accessible paths.
|
/// locally-accessible paths.
|
||||||
pub struct LocalTxProver {
|
pub struct LocalTxProver {
|
||||||
spend_params: Parameters<Bls12>,
|
spend_params: SpendParameters,
|
||||||
|
// TODO: Either re-introduce verification-after-proving (once the verifier is
|
||||||
|
// refactored), or remove this.
|
||||||
|
#[allow(unused)]
|
||||||
spend_vk: PreparedVerifyingKey<Bls12>,
|
spend_vk: PreparedVerifyingKey<Bls12>,
|
||||||
output_params: Parameters<Bls12>,
|
output_params: OutputParameters,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LocalTxProver {
|
impl LocalTxProver {
|
||||||
|
@ -164,7 +170,6 @@ impl TxProver for LocalTxProver {
|
||||||
anchor,
|
anchor,
|
||||||
merkle_path,
|
merkle_path,
|
||||||
&self.spend_params,
|
&self.spend_params,
|
||||||
&self.spend_vk,
|
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let mut zkproof = [0u8; GROTH_PROOF_SIZE];
|
let mut zkproof = [0u8; GROTH_PROOF_SIZE];
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
use bellman::{
|
use bellman::groth16::{create_random_proof, Proof};
|
||||||
gadgets::multipack,
|
|
||||||
groth16::{create_random_proof, verify_proof, Parameters, PreparedVerifyingKey, Proof},
|
|
||||||
};
|
|
||||||
use bls12_381::Bls12;
|
use bls12_381::Bls12;
|
||||||
use group::{Curve, GroupEncoding};
|
use group::GroupEncoding;
|
||||||
use rand_core::OsRng;
|
use rand_core::{OsRng, RngCore};
|
||||||
use zcash_primitives::{
|
use zcash_primitives::{
|
||||||
sapling::{
|
sapling::{
|
||||||
circuit::{Output, Spend, ValueCommitmentOpening},
|
circuit::{Output, Spend, ValueCommitmentOpening},
|
||||||
constants::{SPENDING_KEY_GENERATOR, VALUE_COMMITMENT_RANDOMNESS_GENERATOR},
|
constants::{SPENDING_KEY_GENERATOR, VALUE_COMMITMENT_RANDOMNESS_GENERATOR},
|
||||||
|
prover::{OutputProver, SpendProver},
|
||||||
redjubjub::{PublicKey, Signature},
|
redjubjub::{PublicKey, Signature},
|
||||||
value::{CommitmentSum, NoteValue, TrapdoorSum, ValueCommitTrapdoor, ValueCommitment},
|
value::{CommitmentSum, NoteValue, TrapdoorSum, ValueCommitTrapdoor, ValueCommitment},
|
||||||
Diversifier, MerklePath, Note, PaymentAddress, ProofGenerationKey, Rseed,
|
Diversifier, MerklePath, Note, PaymentAddress, ProofGenerationKey, Rseed,
|
||||||
|
@ -16,6 +14,88 @@ use zcash_primitives::{
|
||||||
transaction::components::Amount,
|
transaction::components::Amount,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::{OutputParameters, SpendParameters};
|
||||||
|
|
||||||
|
impl SpendProver for SpendParameters {
|
||||||
|
type Proof = Proof<Bls12>;
|
||||||
|
|
||||||
|
fn prepare_circuit(
|
||||||
|
proof_generation_key: ProofGenerationKey,
|
||||||
|
diversifier: Diversifier,
|
||||||
|
rseed: Rseed,
|
||||||
|
value: NoteValue,
|
||||||
|
alpha: jubjub::Fr,
|
||||||
|
rcv: ValueCommitTrapdoor,
|
||||||
|
anchor: bls12_381::Scalar,
|
||||||
|
merkle_path: MerklePath,
|
||||||
|
) -> Option<Spend> {
|
||||||
|
// Construct the value commitment
|
||||||
|
let value_commitment_opening = ValueCommitmentOpening {
|
||||||
|
value: value.inner(),
|
||||||
|
randomness: rcv.inner(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Construct the viewing key
|
||||||
|
let viewing_key = proof_generation_key.to_viewing_key();
|
||||||
|
|
||||||
|
// Construct the payment address with the viewing key / diversifier
|
||||||
|
let payment_address = viewing_key.to_payment_address(diversifier)?;
|
||||||
|
|
||||||
|
let note = Note::from_parts(payment_address, value, rseed);
|
||||||
|
|
||||||
|
// We now have the full witness for our circuit
|
||||||
|
let pos: u64 = merkle_path.position().into();
|
||||||
|
Some(Spend {
|
||||||
|
value_commitment_opening: Some(value_commitment_opening),
|
||||||
|
proof_generation_key: Some(proof_generation_key),
|
||||||
|
payment_address: Some(payment_address),
|
||||||
|
commitment_randomness: Some(note.rcm()),
|
||||||
|
ar: Some(alpha),
|
||||||
|
auth_path: merkle_path
|
||||||
|
.path_elems()
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, node)| Some(((*node).into(), pos >> i & 0x1 == 1)))
|
||||||
|
.collect(),
|
||||||
|
anchor: Some(anchor),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_proof<R: RngCore>(&self, circuit: Spend, rng: &mut R) -> Self::Proof {
|
||||||
|
create_random_proof(circuit, &self.0, rng).expect("proving should not fail")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OutputProver for OutputParameters {
|
||||||
|
type Proof = Proof<Bls12>;
|
||||||
|
|
||||||
|
fn prepare_circuit(
|
||||||
|
esk: jubjub::Fr,
|
||||||
|
payment_address: PaymentAddress,
|
||||||
|
rcm: jubjub::Fr,
|
||||||
|
value: NoteValue,
|
||||||
|
rcv: ValueCommitTrapdoor,
|
||||||
|
) -> Output {
|
||||||
|
// Construct the value commitment for the proof instance
|
||||||
|
let value_commitment_opening = ValueCommitmentOpening {
|
||||||
|
value: value.inner(),
|
||||||
|
randomness: rcv.inner(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// We now have a full witness for the output proof.
|
||||||
|
Output {
|
||||||
|
value_commitment_opening: Some(value_commitment_opening),
|
||||||
|
payment_address: Some(payment_address),
|
||||||
|
commitment_randomness: Some(rcm),
|
||||||
|
esk: Some(esk),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_proof<R: RngCore>(&self, circuit: Output, rng: &mut R) -> Self::Proof {
|
||||||
|
create_random_proof(circuit, &self.0, rng).expect("proving should not fail")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A context object for creating the Sapling components of a Zcash transaction.
|
/// A context object for creating the Sapling components of a Zcash transaction.
|
||||||
pub struct SaplingProvingContext {
|
pub struct SaplingProvingContext {
|
||||||
bsk: TrapdoorSum,
|
bsk: TrapdoorSum,
|
||||||
|
@ -51,8 +131,7 @@ impl SaplingProvingContext {
|
||||||
value: u64,
|
value: u64,
|
||||||
anchor: bls12_381::Scalar,
|
anchor: bls12_381::Scalar,
|
||||||
merkle_path: MerklePath,
|
merkle_path: MerklePath,
|
||||||
proving_key: &Parameters<Bls12>,
|
proving_key: &SpendParameters,
|
||||||
verifying_key: &PreparedVerifyingKey<Bls12>,
|
|
||||||
) -> Result<(Proof<Bls12>, ValueCommitment, PublicKey), ()> {
|
) -> Result<(Proof<Bls12>, ValueCommitment, PublicKey), ()> {
|
||||||
// Initialize secure RNG
|
// Initialize secure RNG
|
||||||
let mut rng = OsRng;
|
let mut rng = OsRng;
|
||||||
|
@ -64,81 +143,26 @@ impl SaplingProvingContext {
|
||||||
self.bsk += &rcv;
|
self.bsk += &rcv;
|
||||||
|
|
||||||
// Construct the value commitment
|
// Construct the value commitment
|
||||||
let value_commitment_opening = ValueCommitmentOpening {
|
let value = NoteValue::from_raw(value);
|
||||||
value,
|
let value_commitment = ValueCommitment::derive(value, rcv.clone());
|
||||||
randomness: rcv.inner(),
|
|
||||||
};
|
|
||||||
let value_commitment = ValueCommitment::derive(NoteValue::from_raw(value), rcv);
|
|
||||||
|
|
||||||
// Construct the viewing key
|
|
||||||
let viewing_key = proof_generation_key.to_viewing_key();
|
|
||||||
|
|
||||||
// Construct the payment address with the viewing key / diversifier
|
|
||||||
let payment_address = viewing_key.to_payment_address(diversifier).ok_or(())?;
|
|
||||||
|
|
||||||
// This is the result of the re-randomization, we compute it for the caller
|
// 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 rk = PublicKey(proof_generation_key.ak.into()).randomize(ar, SPENDING_KEY_GENERATOR);
|
||||||
|
|
||||||
// Let's compute the nullifier while we have the position
|
let instance = SpendParameters::prepare_circuit(
|
||||||
let note = Note::from_parts(payment_address, NoteValue::from_raw(value), rseed);
|
proof_generation_key,
|
||||||
|
diversifier,
|
||||||
let nullifier = note.nf(
|
rseed,
|
||||||
&viewing_key.nk,
|
value,
|
||||||
u64::try_from(merkle_path.position())
|
ar,
|
||||||
.expect("Sapling note commitment tree position must fit into a u64"),
|
rcv,
|
||||||
);
|
anchor,
|
||||||
|
merkle_path,
|
||||||
// We now have the full witness for our circuit
|
)
|
||||||
let pos: u64 = merkle_path.position().into();
|
.ok_or(())?;
|
||||||
let instance = Spend {
|
|
||||||
value_commitment_opening: Some(value_commitment_opening),
|
|
||||||
proof_generation_key: Some(proof_generation_key),
|
|
||||||
payment_address: Some(payment_address),
|
|
||||||
commitment_randomness: Some(note.rcm()),
|
|
||||||
ar: Some(ar),
|
|
||||||
auth_path: merkle_path
|
|
||||||
.path_elems()
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(i, node)| Some(((*node).into(), pos >> i & 0x1 == 1)))
|
|
||||||
.collect(),
|
|
||||||
anchor: Some(anchor),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Create proof
|
// Create proof
|
||||||
let proof =
|
let proof = proving_key.create_proof(instance, &mut rng);
|
||||||
create_random_proof(instance, proving_key, &mut rng).expect("proving should not fail");
|
|
||||||
|
|
||||||
// Try to verify the proof:
|
|
||||||
// Construct public input for circuit
|
|
||||||
let mut public_input = [bls12_381::Scalar::zero(); 7];
|
|
||||||
{
|
|
||||||
let affine = rk.0.to_affine();
|
|
||||||
let (u, v) = (affine.get_u(), affine.get_v());
|
|
||||||
public_input[0] = u;
|
|
||||||
public_input[1] = v;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
let affine = value_commitment.as_inner().to_affine();
|
|
||||||
let (u, v) = (affine.get_u(), affine.get_v());
|
|
||||||
public_input[2] = u;
|
|
||||||
public_input[3] = v;
|
|
||||||
}
|
|
||||||
public_input[4] = anchor;
|
|
||||||
|
|
||||||
// Add the nullifier through multiscalar packing
|
|
||||||
{
|
|
||||||
let nullifier = multipack::bytes_to_bits_le(&nullifier.0);
|
|
||||||
let nullifier = multipack::compute_multipacking(&nullifier);
|
|
||||||
|
|
||||||
assert_eq!(nullifier.len(), 2);
|
|
||||||
|
|
||||||
public_input[5] = nullifier[0];
|
|
||||||
public_input[6] = nullifier[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify the proof
|
|
||||||
verify_proof(verifying_key, &proof, &public_input[..]).map_err(|_| ())?;
|
|
||||||
|
|
||||||
// Accumulate the value commitment in the context
|
// Accumulate the value commitment in the context
|
||||||
self.cv_sum += &value_commitment;
|
self.cv_sum += &value_commitment;
|
||||||
|
@ -155,7 +179,7 @@ impl SaplingProvingContext {
|
||||||
payment_address: PaymentAddress,
|
payment_address: PaymentAddress,
|
||||||
rcm: jubjub::Fr,
|
rcm: jubjub::Fr,
|
||||||
value: u64,
|
value: u64,
|
||||||
proving_key: &Parameters<Bls12>,
|
proving_key: &OutputParameters,
|
||||||
) -> (Proof<Bls12>, ValueCommitment) {
|
) -> (Proof<Bls12>, ValueCommitment) {
|
||||||
// Initialize secure RNG
|
// Initialize secure RNG
|
||||||
let mut rng = OsRng;
|
let mut rng = OsRng;
|
||||||
|
@ -169,23 +193,14 @@ impl SaplingProvingContext {
|
||||||
self.bsk -= &rcv; // Outputs subtract from the total.
|
self.bsk -= &rcv; // Outputs subtract from the total.
|
||||||
|
|
||||||
// Construct the value commitment for the proof instance
|
// Construct the value commitment for the proof instance
|
||||||
let value_commitment_opening = ValueCommitmentOpening {
|
let value = NoteValue::from_raw(value);
|
||||||
value,
|
let value_commitment = ValueCommitment::derive(value, rcv.clone());
|
||||||
randomness: rcv.inner(),
|
|
||||||
};
|
|
||||||
let value_commitment = ValueCommitment::derive(NoteValue::from_raw(value), rcv);
|
|
||||||
|
|
||||||
// We now have a full witness for the output proof.
|
// We now have a full witness for the output proof.
|
||||||
let instance = Output {
|
let instance = OutputParameters::prepare_circuit(esk, payment_address, rcm, value, rcv);
|
||||||
value_commitment_opening: Some(value_commitment_opening),
|
|
||||||
payment_address: Some(payment_address),
|
|
||||||
commitment_randomness: Some(rcm),
|
|
||||||
esk: Some(esk),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Create proof
|
// Create proof
|
||||||
let proof =
|
let proof = proving_key.create_proof(instance, &mut rng);
|
||||||
create_random_proof(instance, proving_key, &mut rng).expect("proving should not fail");
|
|
||||||
|
|
||||||
// Accumulate the value commitment in the context. We do this to check internal consistency.
|
// Accumulate the value commitment in the context. We do this to check internal consistency.
|
||||||
self.cv_sum -= &value_commitment; // Outputs subtract from the total.
|
self.cv_sum -= &value_commitment; // Outputs subtract from the total.
|
||||||
|
|
Loading…
Reference in New Issue