chain: extract sapling code to sapling module

This commit is contained in:
Henry de Valence 2020-08-15 18:02:07 -07:00
parent c5a8cb0c91
commit e06f59ee21
27 changed files with 104 additions and 85 deletions

View File

@ -1,5 +1,4 @@
//! Address types. //! Address types.
pub mod sapling;
pub mod sprout; pub mod sprout;
pub mod transparent; pub mod transparent;

View File

@ -1,7 +1,7 @@
//! The LightClientRootHash enum, used for the corresponding block header field. //! The LightClientRootHash enum, used for the corresponding block header field.
use crate::parameters::{Network, NetworkUpgrade, NetworkUpgrade::*}; use crate::parameters::{Network, NetworkUpgrade, NetworkUpgrade::*};
use crate::treestate::note_commitment_tree::SaplingNoteTreeRootHash; use crate::sapling::tree::SaplingNoteTreeRootHash;
use super::BlockHeight; use super::BlockHeight;

View File

@ -1,4 +1,3 @@
//! Note and value commitments and associated types. //! Note and value commitments and associated types.
pub mod sapling;
pub mod sprout; pub mod sprout;

View File

@ -1,5 +1,4 @@
//! Key types. //! Key types.
pub mod sapling;
pub mod sprout; pub mod sprout;
pub mod transparent; pub mod transparent;

View File

@ -5,7 +5,7 @@
#![doc(html_favicon_url = "https://www.zfnd.org/images/zebra-favicon-128.png")] #![doc(html_favicon_url = "https://www.zfnd.org/images/zebra-favicon-128.png")]
#![doc(html_logo_url = "https://www.zfnd.org/images/zebra-icon.png")] #![doc(html_logo_url = "https://www.zfnd.org/images/zebra-icon.png")]
#![doc(html_root_url = "https://doc.zebra.zfnd.org/zebra_chain")] #![doc(html_root_url = "https://doc.zebra.zfnd.org/zebra_chain")]
#![deny(missing_docs)] //#![deny(missing_docs)]
#![allow(clippy::try_err)] #![allow(clippy::try_err)]
#[macro_use] #[macro_use]
@ -14,15 +14,19 @@ extern crate serde;
mod merkle_tree; mod merkle_tree;
pub mod addresses; pub mod addresses;
pub mod amount;
pub mod block;
pub mod commitments; pub mod commitments;
pub mod keys; pub mod keys;
pub mod notes; pub mod notes;
pub mod parameters;
pub mod primitives;
pub mod serialization;
pub mod transaction;
pub mod treestate; pub mod treestate;
pub mod types; pub mod types;
pub mod amount;
pub mod block;
pub mod parameters;
pub mod primitives;
pub mod sapling;
pub mod serialization;
pub mod sprout;
pub mod transaction;
pub mod transparent;
pub mod work; pub mod work;

View File

@ -2,7 +2,6 @@
#[cfg(test)] #[cfg(test)]
mod arbitrary; mod arbitrary;
mod memo; pub mod memo;
pub mod sapling;
pub mod sprout; pub mod sprout;

View File

@ -0,0 +1,7 @@
//! Sapling-related functionality.
pub mod address;
pub mod commitment;
pub mod keys;
pub mod note;
pub mod tree;

View File

@ -1,4 +1,4 @@
//! Sapling Shielded Payment Address types. //! Shielded addresses.
use std::{ use std::{
fmt, fmt,
@ -11,11 +11,12 @@ use bech32::{self, FromBase32, ToBase32};
use proptest::prelude::*; use proptest::prelude::*;
use crate::{ use crate::{
keys::sapling,
parameters::Network, parameters::Network,
serialization::{ReadZcashExt, SerializationError}, serialization::{ReadZcashExt, SerializationError},
}; };
use super::keys;
/// Human-Readable Parts for input to bech32 encoding. /// Human-Readable Parts for input to bech32 encoding.
mod human_readable_parts { mod human_readable_parts {
pub const MAINNET: &str = "zs"; pub const MAINNET: &str = "zs";
@ -31,8 +32,8 @@ mod human_readable_parts {
#[derive(Clone, Copy, Eq, PartialEq)] #[derive(Clone, Copy, Eq, PartialEq)]
pub struct SaplingShieldedAddress { pub struct SaplingShieldedAddress {
network: Network, network: Network,
diversifier: sapling::Diversifier, diversifier: keys::Diversifier,
transmission_key: sapling::TransmissionKey, transmission_key: keys::TransmissionKey,
} }
impl fmt::Debug for SaplingShieldedAddress { impl fmt::Debug for SaplingShieldedAddress {
@ -79,8 +80,8 @@ impl std::str::FromStr for SaplingShieldedAddress {
human_readable_parts::MAINNET => Network::Mainnet, human_readable_parts::MAINNET => Network::Mainnet,
_ => Network::Testnet, _ => Network::Testnet,
}, },
diversifier: sapling::Diversifier::from(diversifier_bytes), diversifier: keys::Diversifier::from(diversifier_bytes),
transmission_key: sapling::TransmissionKey::from(transmission_key_bytes), transmission_key: keys::TransmissionKey::from(transmission_key_bytes),
}) })
} }
Err(_) => Err(SerializationError::Parse("bech32 decoding error")), Err(_) => Err(SerializationError::Parse("bech32 decoding error")),
@ -95,8 +96,8 @@ impl Arbitrary for SaplingShieldedAddress {
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy { fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
( (
any::<Network>(), any::<Network>(),
any::<sapling::Diversifier>(), any::<keys::Diversifier>(),
any::<sapling::TransmissionKey>(), any::<keys::TransmissionKey>(),
) )
.prop_map(|(network, diversifier, transmission_key)| Self { .prop_map(|(network, diversifier, transmission_key)| Self {
network, network,
@ -131,18 +132,18 @@ mod tests {
#[test] #[test]
fn derive_keys_and_addresses() { fn derive_keys_and_addresses() {
let spending_key = sapling::SpendingKey::new(&mut OsRng); let spending_key = keys::SpendingKey::new(&mut OsRng);
let spend_authorizing_key = sapling::SpendAuthorizingKey::from(spending_key); let spend_authorizing_key = keys::SpendAuthorizingKey::from(spending_key);
let proof_authorizing_key = sapling::ProofAuthorizingKey::from(spending_key); let proof_authorizing_key = keys::ProofAuthorizingKey::from(spending_key);
let authorizing_key = sapling::AuthorizingKey::from(spend_authorizing_key); let authorizing_key = keys::AuthorizingKey::from(spend_authorizing_key);
let nullifier_deriving_key = sapling::NullifierDerivingKey::from(proof_authorizing_key); let nullifier_deriving_key = keys::NullifierDerivingKey::from(proof_authorizing_key);
let incoming_viewing_key = let incoming_viewing_key =
sapling::IncomingViewingKey::from((authorizing_key, nullifier_deriving_key)); keys::IncomingViewingKey::from((authorizing_key, nullifier_deriving_key));
let diversifier = sapling::Diversifier::new(&mut OsRng); let diversifier = keys::Diversifier::new(&mut OsRng);
let transmission_key = sapling::TransmissionKey::from((incoming_viewing_key, diversifier)); let transmission_key = keys::TransmissionKey::from((incoming_viewing_key, diversifier));
let _sapling_shielded_address = SaplingShieldedAddress { let _sapling_shielded_address = SaplingShieldedAddress {
network: Network::Mainnet, network: Network::Mainnet,

View File

@ -1,4 +1,4 @@
//! Sapling note and value commitments and types. //! Note and value commitments.
#[cfg(test)] #[cfg(test)]
mod arbitrary; mod arbitrary;
@ -14,12 +14,13 @@ use rand_core::{CryptoRng, RngCore};
use crate::{ use crate::{
amount::{Amount, NonNegative}, amount::{Amount, NonNegative},
keys::sapling::{find_group_hash, Diversifier, TransmissionKey},
serialization::{ serialization::{
serde_helpers, ReadZcashExt, SerializationError, ZcashDeserialize, ZcashSerialize, serde_helpers, ReadZcashExt, SerializationError, ZcashDeserialize, ZcashSerialize,
}, },
}; };
use super::keys::{find_group_hash, Diversifier, TransmissionKey};
use pedersen_hashes::*; use pedersen_hashes::*;
/// The randomness used in the Pedersen Hash for note commitment. /// The randomness used in the Pedersen Hash for note commitment.
@ -219,13 +220,12 @@ impl ValueCommitment {
mod tests { mod tests {
use super::*; use super::*;
use crate::commitments::sapling::test_vectors::TEST_VECTORS;
#[test] #[test]
fn pedersen_hash_to_point_test_vectors() { fn pedersen_hash_to_point_test_vectors() {
const D: [u8; 8] = *b"Zcash_PH"; const D: [u8; 8] = *b"Zcash_PH";
for test_vector in TEST_VECTORS.iter() { for test_vector in test_vectors::TEST_VECTORS.iter() {
let result = jubjub::AffinePoint::from(pedersen_hash_to_point( let result = jubjub::AffinePoint::from(pedersen_hash_to_point(
D, D,
&test_vector.input_bits.clone(), &test_vector.input_bits.clone(),

View File

@ -2,9 +2,9 @@ use std::convert::TryFrom;
use proptest::{arbitrary::any, array, prelude::*}; use proptest::{arbitrary::any, array, prelude::*};
use crate::commitments::sapling; use super::super::commitment;
impl Arbitrary for sapling::NoteCommitment { impl Arbitrary for commitment::NoteCommitment {
type Parameters = (); type Parameters = ();
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy { fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
@ -16,7 +16,7 @@ impl Arbitrary for sapling::NoteCommitment {
type Strategy = BoxedStrategy<Self>; type Strategy = BoxedStrategy<Self>;
} }
impl Arbitrary for sapling::ValueCommitment { impl Arbitrary for commitment::ValueCommitment {
type Parameters = (); type Parameters = ();
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy { fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {

View File

@ -3,7 +3,7 @@
use bitvec::prelude::*; use bitvec::prelude::*;
use rand_core::{CryptoRng, RngCore}; use rand_core::{CryptoRng, RngCore};
use crate::keys::sapling::find_group_hash; use super::super::keys::find_group_hash;
/// I_i /// I_i
/// ///

View File

@ -1,4 +1,4 @@
//! Sapling key types //! Key types.
//! //!
//! "The spend authorizing key ask, proof authorizing key (ak, nsk), //! "The spend authorizing key ask, proof authorizing key (ak, nsk),
//! full viewing key (ak, nk, ovk), incoming viewing key ivk, and each //! full viewing key (ak, nk, ovk), incoming viewing key ivk, and each

View File

@ -2,9 +2,9 @@ use std::convert::TryFrom;
use proptest::{arbitrary::any, array, prelude::*}; use proptest::{arbitrary::any, array, prelude::*};
use crate::keys::sapling; use super::*;
impl Arbitrary for sapling::EphemeralPublicKey { impl Arbitrary for EphemeralPublicKey {
type Parameters = (); type Parameters = ();
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy { fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {

View File

@ -3,18 +3,22 @@
#![allow(clippy::unit_arg)] #![allow(clippy::unit_arg)]
#![allow(dead_code)] #![allow(dead_code)]
#[cfg(test)]
mod arbitrary;
mod ciphertexts; mod ciphertexts;
mod nullifiers; mod nullifiers;
#[cfg(test)]
mod arbitrary;
use crate::{ use crate::{
amount::{Amount, NonNegative}, amount::{Amount, NonNegative},
commitments::sapling::CommitmentRandomness,
keys::sapling::{Diversifier, TransmissionKey},
notes::memo::Memo, notes::memo::Memo,
}; };
use super::{
commitment::CommitmentRandomness,
keys::{Diversifier, TransmissionKey},
};
pub use ciphertexts::{EncryptedCiphertext, OutCiphertext}; pub use ciphertexts::{EncryptedCiphertext, OutCiphertext};
pub use nullifiers::Nullifier; pub use nullifiers::Nullifier;

View File

@ -1,8 +1,8 @@
use proptest::{arbitrary::any, collection::vec, prelude::*}; use proptest::{arbitrary::any, collection::vec, prelude::*};
use crate::notes::sapling; use super::*;
impl Arbitrary for sapling::EncryptedCiphertext { impl Arbitrary for EncryptedCiphertext {
type Parameters = (); type Parameters = ();
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy { fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
@ -18,7 +18,7 @@ impl Arbitrary for sapling::EncryptedCiphertext {
type Strategy = BoxedStrategy<Self>; type Strategy = BoxedStrategy<Self>;
} }
impl Arbitrary for sapling::OutCiphertext { impl Arbitrary for OutCiphertext {
type Parameters = (); type Parameters = ();
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy { fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {

View File

@ -1,10 +1,10 @@
#![allow(clippy::unit_arg)] #![allow(clippy::unit_arg)]
#![allow(dead_code)] #![allow(dead_code)]
use crate::{ use super::super::{
commitments::sapling::{pedersen_hashes::mixing_pedersen_hash, NoteCommitment}, commitment::{pedersen_hashes::mixing_pedersen_hash, NoteCommitment},
keys::sapling::NullifierDerivingKey, keys::NullifierDerivingKey,
treestate::note_commitment_tree::Position, tree::Position,
}; };
/// Invokes Blake2s-256 as PRF^nfSapling to derive the nullifier for a /// Invokes Blake2s-256 as PRF^nfSapling to derive the nullifier for a

View File

@ -19,10 +19,9 @@ use bitvec::prelude::*;
#[cfg(test)] #[cfg(test)]
use proptest_derive::Arbitrary; use proptest_derive::Arbitrary;
use crate::{ use crate::serialization::{SerializationError, ZcashDeserialize, ZcashSerialize};
commitments::sapling::pedersen_hashes::pedersen_hash,
serialization::{SerializationError, ZcashDeserialize, ZcashSerialize}, use super::commitment::pedersen_hashes::pedersen_hash;
};
/// MerkleCRH^Sapling Hash Function /// MerkleCRH^Sapling Hash Function
/// ///

View File

@ -0,0 +1 @@

View File

@ -9,7 +9,7 @@ use std::{
}; };
use crate::{ use crate::{
commitments, keys, notes, commitments, notes,
primitives::{Script, ZkSnarkProof}, primitives::{Script, ZkSnarkProof},
serialization::{ serialization::{
ReadZcashExt, SerializationError, WriteZcashExt, ZcashDeserialize, ZcashSerialize, ReadZcashExt, SerializationError, WriteZcashExt, ZcashDeserialize, ZcashSerialize,
@ -350,11 +350,13 @@ impl ZcashSerialize for Spend {
impl ZcashDeserialize for Spend { impl ZcashDeserialize for Spend {
fn zcash_deserialize<R: io::Read>(mut reader: R) -> Result<Self, SerializationError> { fn zcash_deserialize<R: io::Read>(mut reader: R) -> Result<Self, SerializationError> {
use crate::treestate::note_commitment_tree::SaplingNoteTreeRootHash; use crate::sapling::{
commitment::ValueCommitment, note::Nullifier, tree::SaplingNoteTreeRootHash,
};
Ok(Spend { Ok(Spend {
cv: commitments::sapling::ValueCommitment::zcash_deserialize(&mut reader)?, cv: ValueCommitment::zcash_deserialize(&mut reader)?,
anchor: SaplingNoteTreeRootHash(reader.read_32_bytes()?), anchor: SaplingNoteTreeRootHash(reader.read_32_bytes()?),
nullifier: notes::sapling::Nullifier::from(reader.read_32_bytes()?), nullifier: Nullifier::from(reader.read_32_bytes()?),
rk: reader.read_32_bytes()?.into(), rk: reader.read_32_bytes()?.into(),
zkproof: Groth16Proof::zcash_deserialize(&mut reader)?, zkproof: Groth16Proof::zcash_deserialize(&mut reader)?,
spend_auth_sig: reader.read_64_bytes()?.into(), spend_auth_sig: reader.read_64_bytes()?.into(),
@ -376,12 +378,16 @@ impl ZcashSerialize for Output {
impl ZcashDeserialize for Output { impl ZcashDeserialize for Output {
fn zcash_deserialize<R: io::Read>(mut reader: R) -> Result<Self, SerializationError> { fn zcash_deserialize<R: io::Read>(mut reader: R) -> Result<Self, SerializationError> {
use crate::sapling::{
commitment::ValueCommitment, keys::EphemeralPublicKey, note::EncryptedCiphertext,
note::OutCiphertext,
};
Ok(Output { Ok(Output {
cv: commitments::sapling::ValueCommitment::zcash_deserialize(&mut reader)?, cv: ValueCommitment::zcash_deserialize(&mut reader)?,
cm_u: jubjub::Fq::zcash_deserialize(&mut reader)?, cm_u: jubjub::Fq::zcash_deserialize(&mut reader)?,
ephemeral_key: keys::sapling::EphemeralPublicKey::zcash_deserialize(&mut reader)?, ephemeral_key: EphemeralPublicKey::zcash_deserialize(&mut reader)?,
enc_ciphertext: notes::sapling::EncryptedCiphertext::zcash_deserialize(&mut reader)?, enc_ciphertext: EncryptedCiphertext::zcash_deserialize(&mut reader)?,
out_ciphertext: notes::sapling::OutCiphertext::zcash_deserialize(&mut reader)?, out_ciphertext: OutCiphertext::zcash_deserialize(&mut reader)?,
zkproof: Groth16Proof::zcash_deserialize(&mut reader)?, zkproof: Groth16Proof::zcash_deserialize(&mut reader)?,
}) })
} }

View File

@ -1,13 +1,13 @@
use futures::future::Either;
use crate::{ use crate::{
commitments, keys, notes,
primitives::{ primitives::{
redjubjub::{self, Binding, SpendAuth}, redjubjub::{self, Binding, SpendAuth},
Groth16Proof, Groth16Proof,
}, },
sapling::{commitment, keys, note, tree},
serialization::serde_helpers, serialization::serde_helpers,
treestate::note_commitment_tree::SaplingNoteTreeRootHash,
}; };
use futures::future::Either;
/// A _Spend Description_, as described in [protocol specification §7.3][ps]. /// A _Spend Description_, as described in [protocol specification §7.3][ps].
/// ///
@ -15,11 +15,11 @@ use futures::future::Either;
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Spend { pub struct Spend {
/// A value commitment to the value of the input note. /// A value commitment to the value of the input note.
pub cv: commitments::sapling::ValueCommitment, pub cv: commitment::ValueCommitment,
/// A root of the Sapling note commitment tree at some block height in the past. /// A root of the Sapling note commitment tree at some block height in the past.
pub anchor: SaplingNoteTreeRootHash, pub anchor: tree::SaplingNoteTreeRootHash,
/// The nullifier of the input note. /// The nullifier of the input note.
pub nullifier: notes::sapling::Nullifier, pub nullifier: note::Nullifier,
/// The randomized public key for `spend_auth_sig`. /// The randomized public key for `spend_auth_sig`.
pub rk: redjubjub::VerificationKeyBytes<SpendAuth>, pub rk: redjubjub::VerificationKeyBytes<SpendAuth>,
/// The ZK spend proof. /// The ZK spend proof.
@ -34,16 +34,16 @@ pub struct Spend {
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Output { pub struct Output {
/// A value commitment to the value of the input note. /// A value commitment to the value of the input note.
pub cv: commitments::sapling::ValueCommitment, pub cv: commitment::ValueCommitment,
/// The u-coordinate of the note commitment for the output note. /// The u-coordinate of the note commitment for the output note.
#[serde(with = "serde_helpers::Fq")] #[serde(with = "serde_helpers::Fq")]
pub cm_u: jubjub::Fq, pub cm_u: jubjub::Fq,
/// An encoding of an ephemeral Jubjub public key. /// An encoding of an ephemeral Jubjub public key.
pub ephemeral_key: keys::sapling::EphemeralPublicKey, pub ephemeral_key: keys::EphemeralPublicKey,
/// A ciphertext component for the encrypted output note. /// A ciphertext component for the encrypted output note.
pub enc_ciphertext: notes::sapling::EncryptedCiphertext, pub enc_ciphertext: note::EncryptedCiphertext,
/// A ciphertext component for the encrypted output note. /// A ciphertext component for the encrypted output note.
pub out_ciphertext: notes::sapling::OutCiphertext, pub out_ciphertext: note::OutCiphertext,
/// The ZK output proof. /// The ZK output proof.
pub zkproof: Groth16Proof, pub zkproof: Groth16Proof,
} }

View File

@ -5,14 +5,15 @@ use proptest::{arbitrary::any, array, collection::vec, option, prelude::*};
use crate::{ use crate::{
amount::{Amount, NonNegative}, amount::{Amount, NonNegative},
block::BlockHeight, block::BlockHeight,
commitments, keys, commitments,
notes::{sapling, sprout}, notes::sprout,
primitives::{Bctv14Proof, Groth16Proof, Script, ZkSnarkProof}, primitives::{Bctv14Proof, Groth16Proof, Script, ZkSnarkProof},
sapling,
transaction::{ transaction::{
CoinbaseData, JoinSplit, JoinSplitData, LockTime, OutPoint, Output, ShieldedData, Spend, CoinbaseData, JoinSplit, JoinSplitData, LockTime, OutPoint, Output, ShieldedData, Spend,
Transaction, TransparentInput, TransparentOutput, Transaction, TransparentInput, TransparentOutput,
}, },
treestate::{self, note_commitment_tree::SaplingNoteTreeRootHash}, treestate,
}; };
impl Transaction { impl Transaction {
@ -197,11 +198,11 @@ impl Arbitrary for Output {
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy { fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
( (
any::<commitments::sapling::ValueCommitment>(), any::<sapling::commitment::ValueCommitment>(),
any::<commitments::sapling::NoteCommitment>(), any::<sapling::commitment::NoteCommitment>(),
any::<keys::sapling::EphemeralPublicKey>(), any::<sapling::keys::EphemeralPublicKey>(),
any::<sapling::EncryptedCiphertext>(), any::<sapling::note::EncryptedCiphertext>(),
any::<sapling::OutCiphertext>(), any::<sapling::note::OutCiphertext>(),
any::<Groth16Proof>(), any::<Groth16Proof>(),
) )
.prop_map( .prop_map(
@ -254,9 +255,9 @@ impl Arbitrary for Spend {
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy { fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
( (
any::<SaplingNoteTreeRootHash>(), any::<sapling::tree::SaplingNoteTreeRootHash>(),
any::<commitments::sapling::ValueCommitment>(), any::<sapling::commitment::ValueCommitment>(),
any::<sapling::Nullifier>(), any::<sapling::note::Nullifier>(),
array::uniform32(any::<u8>()), array::uniform32(any::<u8>()),
any::<Groth16Proof>(), any::<Groth16Proof>(),
vec(any::<u8>(), 64), vec(any::<u8>(), 64),

View File

@ -0,0 +1 @@

View File

@ -1,5 +1,4 @@
//! Treestate representations for Sprout and Sapling //! Treestate representations for Sprout and Sapling
pub mod note_commitment_tree;
// mod nullifier_set; // mod nullifier_set;
pub mod sprout; pub mod sprout;