Move `zcash_primitives::sapling` module into `sapling-crypto`

This commit is contained in:
Jack Grigg 2023-12-06 18:46:06 +00:00
parent e7f71c3f1f
commit 6acc64e61c
39 changed files with 244 additions and 278 deletions

43
Cargo.lock generated
View File

@ -2089,17 +2089,32 @@ dependencies = [
name = "sapling-crypto"
version = "0.0.1"
dependencies = [
"bellman 0.1.0",
"blake2b_simd 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
"blake2s_simd 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"ff 0.4.0",
"hex-literal 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"pairing 0.14.2",
"rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_xorshift 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"aes",
"bellman",
"bitvec",
"blake2b_simd",
"blake2s_simd",
"bls12_381",
"byteorder",
"chacha20poly1305",
"ff",
"fpe",
"group",
"hex",
"incrementalmerkletree",
"jubjub",
"lazy_static",
"memuse",
"proptest",
"rand",
"rand_core",
"rand_xorshift",
"redjubjub",
"subtle",
"tracing",
"zcash_note_encryption",
"zcash_spec",
"zip32",
]
[[package]]
@ -3096,12 +3111,8 @@ version = "0.13.0"
dependencies = [
"aes",
"assert_matches",
"bellman",
"bip0039",
"bitvec",
"blake2b_simd",
"blake2s_simd",
"bls12_381",
"byteorder",
"chacha20poly1305",
"criterion",
@ -3113,7 +3124,6 @@ dependencies = [
"hex",
"incrementalmerkletree",
"jubjub",
"lazy_static",
"memuse",
"nonempty",
"orchard",
@ -3124,6 +3134,7 @@ dependencies = [
"rand_xorshift",
"redjubjub",
"ripemd",
"sapling-crypto",
"secp256k1",
"sha2",
"subtle",

View File

@ -28,6 +28,7 @@ categories = ["cryptography::cryptocurrencies"]
[workspace.dependencies]
# Intra-workspace dependencies
equihash = { version = "0.2", path = "components/equihash" }
sapling = { package = "sapling-crypto", version = "0.0", path = "sapling-crypto" }
zcash_address = { version = "0.3", path = "components/zcash_address" }
zcash_client_backend = { version = "0.10", path = "zcash_client_backend" }
zcash_encoding = { version = "0.2", path = "components/zcash_encoding" }

View File

@ -1,27 +1,72 @@
[package]
authors = ["Sean Bowe <sean@z.cash>"]
description = "Cryptographic library for Zcash Sapling"
documentation = "https://github.com/zcash-hackworks/sapling"
homepage = "https://github.com/zcash-hackworks/sapling"
license = "MIT/Apache-2.0"
name = "sapling-crypto"
repository = "https://github.com/zcash-hackworks/sapling"
version = "0.0.1"
[dependencies.pairing]
path = "../pairing"
features = ["expose-arith"]
authors = [
"Sean Bowe <sean@electriccoin.co>",
"Jack Grigg <jack@electriccoin.co>",
"Kris Nuttycombe <kris@electriccoin.co>",
]
edition = "2021"
rust-version = "1.65"
description = "Cryptographic library for Zcash Sapling"
homepage = "https://github.com/zcash/sapling-crypto"
repository = "https://github.com/zcash/sapling-crypto"
license = "MIT OR Apache-2.0"
[dependencies]
bellman = { path = "../bellman" }
blake2b_simd = "0.5"
blake2s_simd = "0.5"
ff = { path = "../ff" }
rand_core = "0.5"
digest = "0.8"
ff = "0.13"
group = "0.13"
bls12_381 = "0.8"
jubjub = "0.10"
redjubjub = "0.7"
zcash_spec = "0.1"
# Circuits
bellman = { version = "0.14", default-features = false, features = ["groth16"] }
# CSPRNG
rand = "0.8"
rand_core = "0.6"
# Digests
blake2b_simd = "1"
blake2s_simd = "1"
# Encodings
byteorder = "1"
hex = "0.4"
# Logging and metrics
memuse = "0.2.1"
tracing = "0.1"
# Note Commitment Trees
bitvec = "1"
incrementalmerkletree = "0.5"
# Note encryption
zcash_note_encryption = "0.4"
# Secret management
subtle = "2.2.3"
# Static constants
lazy_static = "1"
# Test dependencies
proptest = { version = "1", optional = true }
# ZIP 32
aes = "0.8"
fpe = "0.6"
zip32 = "0.1"
[dev-dependencies]
hex-literal = "0.1"
rand_xorshift = "0.2"
sha2 = "0.8"
chacha20poly1305 = "0.10"
proptest = "1"
rand_xorshift = "0.3"
[features]
multicore = ["bellman/multicore"]
test-dependencies = ["proptest"]

View File

@ -8,12 +8,12 @@ use rand::{seq::SliceRandom, RngCore};
use rand_core::CryptoRng;
use redjubjub::{Binding, SpendAuth};
use crate::sapling::{
self,
use crate::{
bundle::{
Authorization, Authorized, Bundle, GrothProofBytes, MapAuth, OutputDescription,
SpendDescription,
},
circuit,
keys::{OutgoingViewingKey, SpendAuthorizingKey, SpendValidatingKey},
note_encryption::{sapling_note_encryption, Zip212Enforcement},
prover::{OutputProver, SpendProver},
@ -195,7 +195,7 @@ impl SaplingOutputInfo {
fn build<Pr: OutputProver, R: RngCore>(
self,
rng: &mut R,
) -> OutputDescription<sapling::circuit::Output> {
) -> OutputDescription<circuit::Output> {
let encryptor = sapling_note_encryption::<R>(
self.ovk,
self.note.clone(),
@ -318,7 +318,7 @@ impl SaplingBuilder {
///
/// This may be larger than the number of outputs that have been added to the builder,
/// depending on whether padding is going to be applied.
pub(crate) fn bundle_output_count(&self) -> usize {
pub fn bundle_output_count(&self) -> usize {
// This matches the padding behaviour in `Self::build`.
match self.spends.len() {
0 => self.outputs.len(),
@ -493,24 +493,16 @@ impl SaplingBuilder {
};
assert_eq!(redjubjub::VerificationKey::from(&bsk), bvk);
let bundle = if shielded_spends.is_empty() && shielded_outputs.is_empty() {
None
} else {
Some((
Bundle::from_parts(
shielded_spends,
shielded_outputs,
value_balance,
InProgress {
sigs: Unsigned { bsk },
_proof_state: PhantomData::default(),
},
),
tx_metadata,
))
};
Ok(bundle)
Ok(Bundle::from_parts(
shielded_spends,
shielded_outputs,
value_balance,
InProgress {
sigs: Unsigned { bsk },
_proof_state: PhantomData::default(),
},
)
.map(|b| (b, tx_metadata)))
}
}
@ -555,8 +547,8 @@ impl<P: InProgressProofs, S: InProgressSignatures> Authorization for InProgress<
pub struct Unproven;
impl InProgressProofs for Unproven {
type SpendProof = sapling::circuit::Spend;
type OutputProof = sapling::circuit::Output;
type SpendProof = circuit::Spend;
type OutputProof = circuit::Output;
}
/// Marker for a [`Bundle`] with proofs.
@ -639,13 +631,13 @@ impl<
U: ProverProgress,
> MapAuth<InProgress<Unproven, S>, InProgress<Proven, S>> for CreateProofs<'a, SP, OP, R, U>
{
fn map_spend_proof(&mut self, spend: sapling::circuit::Spend) -> GrothProofBytes {
fn map_spend_proof(&mut self, spend: circuit::Spend) -> GrothProofBytes {
let proof = self.spend_prover.create_proof(spend, &mut self.rng);
self.update_progress();
SP::encode_proof(proof)
}
fn map_output_proof(&mut self, output: sapling::circuit::Output) -> GrothProofBytes {
fn map_output_proof(&mut self, output: circuit::Output) -> GrothProofBytes {
let proof = self.output_prover.create_proof(output, &mut self.rng);
self.update_progress();
OP::encode_proof(proof)
@ -872,7 +864,7 @@ pub mod testing {
use proptest::prelude::*;
use rand::{rngs::StdRng, SeedableRng};
use crate::sapling::{
use crate::{
bundle::{Authorized, Bundle},
note_encryption::Zip212Enforcement,
prover::mock::{MockOutputProver, MockSpendProver},

View File

@ -7,7 +7,7 @@ use zcash_note_encryption::{
EphemeralKeyBytes, ShieldedOutput, COMPACT_NOTE_SIZE, ENC_CIPHERTEXT_SIZE, OUT_CIPHERTEXT_SIZE,
};
use crate::sapling::{
use crate::{
circuit::GROTH_PROOF_SIZE,
note::ExtractedNoteCommitment,
note_encryption::{CompactOutputDescription, SaplingDomain},
@ -158,33 +158,21 @@ pub struct Bundle<A: Authorization, V> {
impl<A: Authorization, V> Bundle<A, V> {
/// Constructs a `Bundle` from its constituent parts.
#[cfg(feature = "temporary-zcashd")]
pub fn temporary_zcashd_from_parts(
pub fn from_parts(
shielded_spends: Vec<SpendDescription<A>>,
shielded_outputs: Vec<OutputDescription<A::OutputProof>>,
value_balance: V,
authorization: A,
) -> Self {
Self::from_parts(
shielded_spends,
shielded_outputs,
value_balance,
authorization,
)
}
/// Constructs a `Bundle` from its constituent parts.
pub(crate) fn from_parts(
shielded_spends: Vec<SpendDescription<A>>,
shielded_outputs: Vec<OutputDescription<A::OutputProof>>,
value_balance: V,
authorization: A,
) -> Self {
Bundle {
shielded_spends,
shielded_outputs,
value_balance,
authorization,
) -> Option<Self> {
if shielded_spends.is_empty() && shielded_outputs.is_empty() {
None
} else {
Some(Bundle {
shielded_spends,
shielded_outputs,
value_balance,
authorization,
})
}
}
@ -331,19 +319,8 @@ impl<A: Authorization> std::fmt::Debug for SpendDescription<A> {
}
impl<A: Authorization> SpendDescription<A> {
#[cfg(feature = "temporary-zcashd")]
pub fn temporary_zcashd_from_parts(
cv: ValueCommitment,
anchor: bls12_381::Scalar,
nullifier: Nullifier,
rk: redjubjub::VerificationKey<SpendAuth>,
zkproof: A::SpendProof,
spend_auth_sig: A::AuthSig,
) -> Self {
Self::from_parts(cv, anchor, nullifier, rk, zkproof, spend_auth_sig)
}
pub(crate) fn from_parts(
/// Constructs a v4 `SpendDescription` from its constituent parts.
pub fn from_parts(
cv: ValueCommitment,
anchor: bls12_381::Scalar,
nullifier: Nullifier,
@ -410,7 +387,8 @@ pub struct SpendDescriptionV5 {
}
impl SpendDescriptionV5 {
pub(crate) fn from_parts(
/// Constructs a v5 `SpendDescription` from its constituent parts.
pub fn from_parts(
cv: ValueCommitment,
nullifier: Nullifier,
rk: redjubjub::VerificationKey<SpendAuth>,
@ -475,26 +453,8 @@ impl<Proof> OutputDescription<Proof> {
&self.zkproof
}
#[cfg(feature = "temporary-zcashd")]
pub fn temporary_zcashd_from_parts(
cv: ValueCommitment,
cmu: ExtractedNoteCommitment,
ephemeral_key: EphemeralKeyBytes,
enc_ciphertext: [u8; ENC_CIPHERTEXT_SIZE],
out_ciphertext: [u8; OUT_CIPHERTEXT_SIZE],
zkproof: Proof,
) -> Self {
Self::from_parts(
cv,
cmu,
ephemeral_key,
enc_ciphertext,
out_ciphertext,
zkproof,
)
}
pub(crate) fn from_parts(
/// Constructs a v4 `OutputDescription` from its constituent parts.
pub fn from_parts(
cv: ValueCommitment,
cmu: ExtractedNoteCommitment,
ephemeral_key: EphemeralKeyBytes,
@ -578,7 +538,8 @@ pub struct OutputDescriptionV5 {
memuse::impl_no_dynamic_usage!(OutputDescriptionV5);
impl OutputDescriptionV5 {
pub(crate) fn from_parts(
/// Constructs a v5 `OutputDescription` from its constituent parts.
pub fn from_parts(
cv: ValueCommitment,
cmu: ExtractedNoteCommitment,
ephemeral_key: EphemeralKeyBytes,
@ -630,15 +591,13 @@ pub mod testing {
use rand::{rngs::StdRng, SeedableRng};
use crate::{
sapling::{
note::testing::arb_cmu,
value::{
testing::{arb_note_value_bounded, arb_trapdoor},
ValueCommitment, MAX_NOTE_VALUE,
},
Nullifier,
circuit::GROTH_PROOF_SIZE,
note::testing::arb_cmu,
value::{
testing::{arb_note_value_bounded, arb_trapdoor},
ValueCommitment, MAX_NOTE_VALUE,
},
transaction::components::GROTH_PROOF_SIZE,
Nullifier,
};
use super::{

View File

@ -634,7 +634,7 @@ pub struct PreparedOutputVerifyingKey(pub(crate) groth16::PreparedVerifyingKey<B
#[test]
fn test_input_circuit_with_bls12_381() {
use crate::sapling::{
use crate::{
keys::SpendValidatingKey, pedersen_hash, Diversifier, Note, ProofGenerationKey, Rseed,
};
@ -783,7 +783,7 @@ fn test_input_circuit_with_bls12_381() {
#[test]
fn test_input_circuit_with_bls12_381_external_test_vectors() {
use crate::sapling::{
use crate::{
keys::SpendValidatingKey, pedersen_hash, Diversifier, Note, ProofGenerationKey, Rseed,
};
@ -966,7 +966,7 @@ fn test_input_circuit_with_bls12_381_external_test_vectors() {
#[test]
fn test_output_circuit_with_bls12_381() {
use crate::sapling::{keys::SpendValidatingKey, Diversifier, ProofGenerationKey, Rseed};
use crate::{keys::SpendValidatingKey, Diversifier, ProofGenerationKey, Rseed};
use bellman::gadgets::test::*;
use group::ff::Field;

View File

@ -1,6 +1,7 @@
//! Various constants used for the Zcash proofs.
use crate::sapling::constants::{PEDERSEN_HASH_CHUNKS_PER_GENERATOR, PEDERSEN_HASH_GENERATORS};
use crate::constants::{PEDERSEN_HASH_CHUNKS_PER_GENERATOR, PEDERSEN_HASH_GENERATORS};
use bls12_381::Scalar;
use group::{ff::Field, Curve, Group};
use jubjub::ExtendedPoint;
@ -42,22 +43,22 @@ pub type FixedGeneratorOwned = Vec<Vec<(Scalar, Scalar)>>;
lazy_static! {
pub static ref PROOF_GENERATION_KEY_GENERATOR: FixedGeneratorOwned =
generate_circuit_generator(crate::sapling::constants::PROOF_GENERATION_KEY_GENERATOR);
generate_circuit_generator(crate::constants::PROOF_GENERATION_KEY_GENERATOR);
pub static ref NOTE_COMMITMENT_RANDOMNESS_GENERATOR: FixedGeneratorOwned =
generate_circuit_generator(crate::sapling::constants::NOTE_COMMITMENT_RANDOMNESS_GENERATOR);
generate_circuit_generator(crate::constants::NOTE_COMMITMENT_RANDOMNESS_GENERATOR);
pub static ref NULLIFIER_POSITION_GENERATOR: FixedGeneratorOwned =
generate_circuit_generator(crate::sapling::constants::NULLIFIER_POSITION_GENERATOR);
generate_circuit_generator(crate::constants::NULLIFIER_POSITION_GENERATOR);
pub static ref VALUE_COMMITMENT_VALUE_GENERATOR: FixedGeneratorOwned =
generate_circuit_generator(crate::sapling::constants::VALUE_COMMITMENT_VALUE_GENERATOR);
generate_circuit_generator(crate::constants::VALUE_COMMITMENT_VALUE_GENERATOR);
pub static ref VALUE_COMMITMENT_RANDOMNESS_GENERATOR: FixedGeneratorOwned =
generate_circuit_generator(crate::sapling::constants::VALUE_COMMITMENT_RANDOMNESS_GENERATOR);
generate_circuit_generator(crate::constants::VALUE_COMMITMENT_RANDOMNESS_GENERATOR);
pub static ref SPENDING_KEY_GENERATOR: FixedGeneratorOwned =
generate_circuit_generator(crate::sapling::constants::SPENDING_KEY_GENERATOR);
generate_circuit_generator(crate::constants::SPENDING_KEY_GENERATOR);
/// The pre-computed window tables `[-4, 3, 2, 1, 1, 2, 3, 4]` of different magnitudes
/// of the Pedersen hash segment generators.

View File

@ -631,9 +631,7 @@ mod test {
use bellman::gadgets::test::*;
use super::{fixed_base_multiplication, AllocatedNum, EdwardsPoint, MontgomeryPoint};
use crate::sapling::circuit::constants::{
to_montgomery_coords, NOTE_COMMITMENT_RANDOMNESS_GENERATOR,
};
use crate::circuit::constants::{to_montgomery_coords, NOTE_COMMITMENT_RANDOMNESS_GENERATOR};
use bellman::gadgets::boolean::{AllocatedBit, Boolean};
#[test]
@ -735,7 +733,7 @@ mod test {
for _ in 0..100 {
let mut cs = TestConstraintSystem::<bls12_381::Scalar>::new();
let p = crate::sapling::constants::NOTE_COMMITMENT_RANDOMNESS_GENERATOR;
let p = crate::constants::NOTE_COMMITMENT_RANDOMNESS_GENERATOR;
let s = jubjub::Fr::random(&mut rng);
let q = jubjub::ExtendedPoint::from(p * s).to_affine();
let (u1, v1) = (q.get_u(), q.get_v());

View File

@ -1,7 +1,8 @@
//! Gadget for Zcash's Pedersen hash.
use super::ecc::{EdwardsPoint, MontgomeryPoint};
pub use crate::sapling::pedersen_hash::Personalization;
pub use crate::pedersen_hash::Personalization;
use bellman::gadgets::boolean::Boolean;
use bellman::gadgets::lookup::*;
use bellman::{ConstraintSystem, SynthesisError};
@ -105,7 +106,8 @@ where
#[cfg(test)]
mod test {
use super::*;
use crate::sapling::pedersen_hash;
use crate::pedersen_hash;
use bellman::gadgets::boolean::{AllocatedBit, Boolean};
use bellman::gadgets::test::*;
use group::{ff::PrimeField, Curve};

View File

@ -276,7 +276,7 @@ mod tests {
use jubjub::SubgroupPoint;
use super::*;
use crate::sapling::group_hash::group_hash;
use crate::group_hash::group_hash;
fn find_group_hash(m: &[u8], personalization: &[u8; 8]) -> SubgroupPoint {
let mut tag = m.to_vec();

View File

@ -692,7 +692,7 @@ mod tests {
use group::{Group, GroupEncoding};
use super::{FullViewingKey, SpendAuthorizingKey, SpendValidatingKey};
use crate::sapling::{constants::SPENDING_KEY_GENERATOR, test_vectors};
use crate::{constants::SPENDING_KEY_GENERATOR, test_vectors};
#[test]
fn ak_must_be_prime_order() {

View File

@ -1,18 +1,39 @@
extern crate pairing;
extern crate bellman;
extern crate blake2b_simd;
extern crate blake2s_simd;
extern crate digest;
extern crate ff;
extern crate rand_core;
extern crate byteorder;
//! Structs and constants specific to the Sapling shielded pool.
mod address;
pub mod builder;
pub mod bundle;
pub mod circuit;
pub mod constants;
pub mod group_hash;
pub mod keys;
pub mod note;
pub mod note_encryption;
pub mod pedersen_hash;
pub mod prover;
mod spec;
mod tree;
pub mod util;
pub mod value;
mod verifier;
pub mod zip32;
pub use address::PaymentAddress;
pub use bundle::Bundle;
pub use keys::{Diversifier, NullifierDerivingKey, ProofGenerationKey, SaplingIvk, ViewingKey};
pub use note::{nullifier::Nullifier, Note, Rseed};
pub use tree::{
merkle_hash, CommitmentTree, IncrementalWitness, MerklePath, Node, NOTE_COMMITMENT_TREE_DEPTH,
};
pub use verifier::{BatchValidator, SaplingVerificationContext};
#[cfg(any(test, feature = "test-dependencies"))]
pub mod testing {
pub use super::{
address::testing::arb_payment_address, keys::testing::arb_incoming_viewing_key,
note::testing::arb_note, tree::testing::arb_node,
};
}
#[cfg(test)]
#[macro_use]
extern crate hex_literal;
#[cfg(test)]
extern crate rand_xorshift;
#[cfg(test)]
extern crate sha2;
mod test_vectors;

View File

@ -4,7 +4,7 @@ use bitvec::{array::BitArray, order::Lsb0};
use group::ff::PrimeField;
use subtle::{ConstantTimeEq, CtOption};
use crate::sapling::{
use crate::{
pedersen_hash::Personalization,
spec::{extract_p, windowed_pedersen_commit},
value::NoteValue,

View File

@ -4,7 +4,7 @@ use std::fmt;
use subtle::{Choice, ConstantTimeEq};
use super::NoteCommitment;
use crate::sapling::{
use crate::{
keys::NullifierDerivingKey,
spec::{mixing_pedersen_hash, prf_nf},
};

View File

@ -15,7 +15,7 @@ use zcash_note_encryption::{
ENC_CIPHERTEXT_SIZE, NOTE_PLAINTEXT_SIZE, OUT_PLAINTEXT_SIZE,
};
use crate::sapling::{
use crate::{
bundle::{GrothProofBytes, OutputDescription},
keys::{
DiversifiedTransmissionKey, EphemeralPublicKey, EphemeralSecretKey, OutgoingViewingKey,
@ -27,7 +27,7 @@ use crate::sapling::{
use super::note::ExtractedNoteCommitment;
pub use crate::sapling::keys::{PreparedEphemeralPublicKey, PreparedIncomingViewingKey};
pub use crate::keys::{PreparedEphemeralPublicKey, PreparedIncomingViewingKey};
pub const KDF_SAPLING_PERSONALIZATION: &[u8; 16] = b"Zcash_SaplingKDF";
pub const PRF_OCK_PERSONALIZATION: &[u8; 16] = b"Zcash_Derive_ock";
@ -357,15 +357,12 @@ impl ShieldedOutput<SaplingDomain, COMPACT_NOTE_SIZE> for CompactOutputDescripti
/// ```
/// use ff::Field;
/// use rand_core::OsRng;
/// use zcash_primitives::{
/// consensus::{TEST_NETWORK, NetworkUpgrade, Parameters},
/// sapling::{
/// keys::OutgoingViewingKey,
/// note_encryption::{sapling_note_encryption, Zip212Enforcement},
/// util::generate_random_rseed,
/// value::{NoteValue, ValueCommitTrapdoor, ValueCommitment},
/// Diversifier, PaymentAddress, Rseed, SaplingIvk,
/// },
/// use sapling_crypto::{
/// keys::OutgoingViewingKey,
/// note_encryption::{sapling_note_encryption, Zip212Enforcement},
/// util::generate_random_rseed,
/// value::{NoteValue, ValueCommitTrapdoor, ValueCommitment},
/// Diversifier, PaymentAddress, Rseed, SaplingIvk,
/// };
///
/// let mut rng = OsRng;
@ -378,7 +375,6 @@ impl ShieldedOutput<SaplingDomain, COMPACT_NOTE_SIZE> for CompactOutputDescripti
/// let value = NoteValue::from_raw(1000);
/// let rcv = ValueCommitTrapdoor::random(&mut rng);
/// let cv = ValueCommitment::derive(value, rcv);
/// let height = TEST_NETWORK.activation_height(NetworkUpgrade::Canopy).unwrap();
/// let rseed = generate_random_rseed(
/// Zip212Enforcement::GracePeriod,
/// &mut rng,
@ -488,7 +484,7 @@ mod tests {
Zip212Enforcement,
};
use crate::sapling::{
use crate::{
bundle::{GrothProofBytes, OutputDescription},
circuit::GROTH_PROOF_SIZE,
keys::{DiversifiedTransmissionKey, EphemeralSecretKey, OutgoingViewingKey},

View File

@ -4,10 +4,9 @@ use bellman::groth16::{create_random_proof, Proof};
use bls12_381::Bls12;
use rand_core::RngCore;
use crate::sapling::{
self,
use crate::{
bundle::GrothProofBytes,
circuit::GROTH_PROOF_SIZE,
circuit::{self, GROTH_PROOF_SIZE},
value::{NoteValue, ValueCommitTrapdoor},
MerklePath,
};
@ -35,16 +34,12 @@ pub trait SpendProver {
rcv: ValueCommitTrapdoor,
anchor: bls12_381::Scalar,
merkle_path: MerklePath,
) -> Option<sapling::circuit::Spend>;
) -> Option<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;
fn create_proof<R: RngCore>(&self, circuit: circuit::Spend, rng: &mut R) -> Self::Proof;
/// Encodes the given Sapling [`SpendDescription`] proof, erasing its type.
///
@ -66,16 +61,12 @@ pub trait OutputProver {
rcm: jubjub::Fr,
value: NoteValue,
rcv: ValueCommitTrapdoor,
) -> sapling::circuit::Output;
) -> 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;
fn create_proof<R: RngCore>(&self, circuit: circuit::Output, rng: &mut R) -> Self::Proof;
/// Encodes the given Sapling [`OutputDescription`] proof, erasing its type.
///
@ -185,14 +176,10 @@ pub mod mock {
use super::{OutputProver, SpendProver};
use crate::{
sapling::{
self,
bundle::GrothProofBytes,
circuit::ValueCommitmentOpening,
value::{NoteValue, ValueCommitTrapdoor},
Diversifier, PaymentAddress, ProofGenerationKey, Rseed,
},
transaction::components::GROTH_PROOF_SIZE,
bundle::GrothProofBytes,
circuit::{self, ValueCommitmentOpening, GROTH_PROOF_SIZE},
value::{NoteValue, ValueCommitTrapdoor},
Diversifier, MerklePath, PaymentAddress, ProofGenerationKey, Rseed,
};
pub struct MockSpendProver;
@ -208,13 +195,13 @@ pub mod mock {
alpha: jubjub::Fr,
rcv: ValueCommitTrapdoor,
anchor: bls12_381::Scalar,
_merkle_path: sapling::MerklePath,
) -> Option<sapling::circuit::Spend> {
_merkle_path: MerklePath,
) -> Option<circuit::Spend> {
let payment_address = proof_generation_key
.to_viewing_key()
.ivk()
.to_payment_address(diversifier);
Some(sapling::circuit::Spend {
Some(circuit::Spend {
value_commitment_opening: Some(ValueCommitmentOpening {
value,
randomness: rcv.inner(),
@ -230,7 +217,7 @@ pub mod mock {
fn create_proof<R: rand_core::RngCore>(
&self,
_circuit: sapling::circuit::Spend,
_circuit: circuit::Spend,
_rng: &mut R,
) -> Self::Proof {
[0u8; GROTH_PROOF_SIZE]
@ -252,8 +239,8 @@ pub mod mock {
rcm: jubjub::Fr,
value: NoteValue,
rcv: ValueCommitTrapdoor,
) -> sapling::circuit::Output {
sapling::circuit::Output {
) -> circuit::Output {
circuit::Output {
value_commitment_opening: Some(ValueCommitmentOpening {
value,
randomness: rcv.inner(),
@ -266,7 +253,7 @@ pub mod mock {
fn create_proof<R: rand_core::RngCore>(
&self,
_circuit: sapling::circuit::Output,
_circuit: circuit::Output,
_rng: &mut R,
) -> Self::Proof {
[0u8; GROTH_PROOF_SIZE]

View File

@ -1 +1,2 @@
pub(crate) mod note_encryption;
pub(crate) mod signatures;

View File

@ -132,7 +132,7 @@ pub(super) mod testing {
use proptest::prelude::*;
use super::Node;
use crate::sapling::note::testing::arb_cmu;
use crate::note::testing::arb_cmu;
prop_compose! {
pub fn arb_node()(cmu in arb_cmu()) -> Node {

View File

@ -6,7 +6,7 @@ use group::GroupEncoding;
use redjubjub::Binding;
use super::{NoteValue, ValueCommitTrapdoor, ValueCommitment};
use crate::sapling::constants::VALUE_COMMITMENT_VALUE_GENERATOR;
use crate::constants::VALUE_COMMITMENT_VALUE_GENERATOR;
/// A value operation overflowed.
#[derive(Debug)]

View File

@ -3,7 +3,7 @@ use bls12_381::Bls12;
use group::{ff::PrimeField, Curve};
use redjubjub::{Binding, SpendAuth};
use crate::sapling::{
use crate::{
note::ExtractedNoteCommitment,
value::{CommitmentSum, ValueCommitment},
};

View File

@ -4,7 +4,7 @@ use group::GroupEncoding;
use rand_core::{CryptoRng, RngCore};
use super::SaplingVerificationContextInner;
use crate::sapling::{
use crate::{
bundle::{Authorized, Bundle},
circuit::{OutputVerifyingKey, SpendVerifyingKey},
};

View File

@ -3,7 +3,7 @@ use bls12_381::Bls12;
use redjubjub::{Binding, SpendAuth};
use super::SaplingVerificationContextInner;
use crate::sapling::{
use crate::{
circuit::{PreparedOutputVerifyingKey, PreparedSpendVerifyingKey},
note::ExtractedNoteCommitment,
value::ValueCommitment,

View File

@ -9,21 +9,18 @@ use blake2b_simd::Params as Blake2bParams;
use byteorder::{ByteOrder, LittleEndian, ReadBytesExt, WriteBytesExt};
use fpe::ff1::{BinaryNumeralString, FF1};
use zcash_spec::PrfExpand;
use zip32::{ChainCode, ChildIndex, DiversifierIndex, Scope};
use std::io::{self, Read, Write};
use std::ops::AddAssign;
use super::{Diversifier, NullifierDerivingKey, PaymentAddress, ViewingKey};
use crate::{
sapling::{
constants::PROOF_GENERATION_KEY_GENERATOR,
keys::{
DecodingError, ExpandedSpendingKey, FullViewingKey, OutgoingViewingKey,
SpendAuthorizingKey,
},
SaplingIvk,
constants::PROOF_GENERATION_KEY_GENERATOR,
keys::{
DecodingError, ExpandedSpendingKey, FullViewingKey, OutgoingViewingKey, SpendAuthorizingKey,
},
zip32::{ChainCode, ChildIndex, DiversifierIndex, Scope},
SaplingIvk,
};
pub const ZIP32_SAPLING_MASTER_PERSONALIZATION: &[u8; 16] = b"ZcashIP32Sapling";

View File

@ -41,21 +41,17 @@ tracing.workspace = true
subtle.workspace = true
# - Shielded protocols
bellman = { version = "0.14", default-features = false, features = ["groth16"] }
bls12_381.workspace = true
ff.workspace = true
group = { workspace = true, features = ["wnaf-memuse"] }
jubjub.workspace = true
nonempty.workspace = true
orchard.workspace = true
sapling.workspace = true
zcash_spec.workspace = true
# - Note Commitment Trees
incrementalmerkletree = { workspace = true, features = ["legacy-api"] }
# - Static constants
lazy_static.workspace = true
# - Test dependencies
proptest = { workspace = true, optional = true }
@ -75,8 +71,6 @@ byteorder.workspace = true
hex.workspace = true
# - Shielded protocols
bitvec.workspace = true
blake2s_simd.workspace = true
redjubjub = "0.7"
# - Transparent inputs
@ -104,10 +98,14 @@ pprof = { version = "0.11", features = ["criterion", "flamegraph"] } # MSRV 1.56
[features]
default = ["multicore"]
multicore = ["bellman/multicore", "orchard/multicore"]
multicore = ["orchard/multicore", "sapling/multicore"]
transparent-inputs = ["hdwallet", "ripemd", "secp256k1"]
temporary-zcashd = []
test-dependencies = ["proptest", "orchard/test-dependencies"]
test-dependencies = [
"proptest",
"orchard/test-dependencies",
"sapling/test-dependencies",
]
unstable-nu6 = []
zfuture = []

View File

@ -16,13 +16,10 @@ pub mod keys;
pub mod legacy;
pub mod memo;
pub mod merkle_tree;
pub mod sapling;
pub use sapling;
pub mod transaction;
pub use zip32;
pub mod zip339;
#[cfg(feature = "zfuture")]
pub mod extensions;
#[cfg(test)]
mod test_vectors;

View File

@ -1,39 +0,0 @@
//! Structs and constants specific to the Sapling shielded pool.
mod address;
pub mod builder;
pub mod bundle;
pub mod circuit;
pub mod constants;
pub mod group_hash;
pub mod keys;
pub mod note;
pub mod note_encryption;
pub mod pedersen_hash;
pub mod prover;
mod spec;
mod tree;
pub mod util;
pub mod value;
mod verifier;
pub mod zip32;
pub use address::PaymentAddress;
pub use bundle::Bundle;
pub use keys::{Diversifier, NullifierDerivingKey, ProofGenerationKey, SaplingIvk, ViewingKey};
pub use note::{nullifier::Nullifier, Note, Rseed};
pub use tree::{
merkle_hash, CommitmentTree, IncrementalWitness, MerklePath, Node, NOTE_COMMITMENT_TREE_DEPTH,
};
pub use verifier::{BatchValidator, SaplingVerificationContext};
#[cfg(any(test, feature = "test-dependencies"))]
pub mod testing {
pub use super::{
address::testing::arb_payment_address, keys::testing::arb_incoming_viewing_key,
note::testing::arb_note, tree::testing::arb_node,
};
}
#[cfg(test)]
mod test_vectors;

View File

@ -1 +0,0 @@
pub(crate) mod signatures;

View File

@ -47,10 +47,10 @@ fn read_cmu<R: Read>(mut reader: R) -> io::Result<ExtractedNoteCommitment> {
/// Consensus rules (§7.3) & (§7.4):
/// - Canonical encoding is enforced here
pub fn read_base<R: Read>(mut reader: R, field: &str) -> io::Result<bls12_381::Scalar> {
pub fn read_base<R: Read>(mut reader: R, field: &str) -> io::Result<jubjub::Base> {
let mut f = [0u8; 32];
reader.read_exact(&mut f)?;
Option::from(bls12_381::Scalar::from_repr(f)).ok_or_else(|| {
Option::from(jubjub::Base::from_repr(f)).ok_or_else(|| {
io::Error::new(
io::ErrorKind::InvalidInput,
format!("{} not in field", field),
@ -379,7 +379,7 @@ pub(crate) fn read_v5_bundle<R: Read>(
.map(|(od_5, zkproof)| od_5.into_output_description(zkproof))
.collect();
Ok(binding_sig.map(|binding_sig| {
Ok(binding_sig.and_then(|binding_sig| {
Bundle::from_parts(
shielded_spends,
shielded_outputs,

View File

@ -646,7 +646,7 @@ impl Transaction {
expiry_height,
transparent_bundle,
sprout_bundle,
sapling_bundle: binding_sig.map(|binding_sig| {
sapling_bundle: binding_sig.and_then(|binding_sig| {
sapling::Bundle::from_parts(
shielded_spends,
shielded_outputs,