diff --git a/benches/note_decryption.rs b/benches/note_decryption.rs index 603f3419d..8f2ce8373 100644 --- a/benches/note_decryption.rs +++ b/benches/note_decryption.rs @@ -2,10 +2,10 @@ use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Through use orchard::{ builder::{Builder, BundleType}, circuit::ProvingKey, - domain::{CompactAction, OrchardDomain}, keys::{FullViewingKey, PreparedIncomingViewingKey, Scope, SpendingKey}, note::AssetBase, orchard_flavor::{OrchardVanilla, OrchardZSA}, + primitives::{CompactAction, OrchardDomain}, value::NoteValue, Anchor, Bundle, }; diff --git a/src/action.rs b/src/action.rs index df4110e41..9d39c2b6b 100644 --- a/src/action.rs +++ b/src/action.rs @@ -1,9 +1,9 @@ use memuse::DynamicUsage; use crate::{ - domain::OrchardDomainCommon, note::{ExtractedNoteCommitment, Nullifier, Rho, TransmittedNoteCiphertext}, primitives::redpallas::{self, SpendAuth}, + primitives::OrchardPrimitives, value::ValueCommitment, }; @@ -12,7 +12,7 @@ use crate::{ /// This both creates a note (adding a commitment to the global ledger), and consumes /// some note created prior to this action (adding a nullifier to the global ledger). #[derive(Debug, Clone)] -pub struct Action { +pub struct Action { /// The nullifier of the note being spent. nf: Nullifier, /// The randomized verification key for the note being spent. @@ -20,20 +20,20 @@ pub struct Action { /// A commitment to the new note being created. cmx: ExtractedNoteCommitment, /// The transmitted note ciphertext. - encrypted_note: TransmittedNoteCiphertext, + encrypted_note: TransmittedNoteCiphertext

, /// A commitment to the net value created or consumed by this action. cv_net: ValueCommitment, /// The authorization for this action. authorization: A, } -impl Action { +impl Action { /// Constructs an `Action` from its constituent parts. pub fn from_parts( nf: Nullifier, rk: redpallas::VerificationKey, cmx: ExtractedNoteCommitment, - encrypted_note: TransmittedNoteCiphertext, + encrypted_note: TransmittedNoteCiphertext

, cv_net: ValueCommitment, authorization: A, ) -> Self { @@ -63,7 +63,7 @@ impl Action { } /// Returns the encrypted note ciphertext. - pub fn encrypted_note(&self) -> &TransmittedNoteCiphertext { + pub fn encrypted_note(&self) -> &TransmittedNoteCiphertext

{ &self.encrypted_note } @@ -83,7 +83,7 @@ impl Action { } /// Transitions this action from one authorization state to another. - pub fn map(self, step: impl FnOnce(A) -> U) -> Action { + pub fn map(self, step: impl FnOnce(A) -> U) -> Action { Action { nf: self.nf, rk: self.rk, @@ -95,7 +95,7 @@ impl Action { } /// Transitions this action from one authorization state to another. - pub fn try_map(self, step: impl FnOnce(A) -> Result) -> Result, E> { + pub fn try_map(self, step: impl FnOnce(A) -> Result) -> Result, E> { Ok(Action { nf: self.nf, rk: self.rk, @@ -107,7 +107,7 @@ impl Action { } } -impl DynamicUsage for Action, D> { +impl DynamicUsage for Action, P> { #[inline(always)] fn dynamic_usage(&self) -> usize { 0 @@ -132,7 +132,6 @@ pub(crate) mod testing { use zcash_note_encryption::NoteEncryption; use crate::{ - domain::{OrchardDomain, OrchardDomainCommon}, note::{ asset_base::testing::arb_asset_base, commitment::ExtractedNoteCommitment, nullifier::testing::arb_nullifier, testing::arb_note, Note, TransmittedNoteCiphertext, @@ -141,6 +140,7 @@ pub(crate) mod testing { self, testing::{arb_spendauth_signing_key, arb_spendauth_verification_key}, }, + primitives::{OrchardDomain, OrchardPrimitives}, value::{NoteValue, ValueCommitTrapdoor, ValueCommitment}, }; @@ -149,20 +149,20 @@ pub(crate) mod testing { /// `ActionArb` adapts `arb_...` functions for both Vanilla and ZSA Orchard protocol flavors /// in property-based testing, addressing proptest crate limitations. #[derive(Debug)] - pub struct ActionArb { - phantom: core::marker::PhantomData, + pub struct ActionArb { + phantom: core::marker::PhantomData

, } - impl ActionArb { + impl ActionArb

{ fn encrypt_note( note: Note, memo: Vec, cmx: &ExtractedNoteCommitment, cv_net: &ValueCommitment, rng: &mut R, - ) -> TransmittedNoteCiphertext { + ) -> TransmittedNoteCiphertext

{ let encryptor = - NoteEncryption::>::new(None, note, memo.try_into().unwrap()); + NoteEncryption::>::new(None, note, memo.try_into().unwrap()); TransmittedNoteCiphertext { epk_bytes: encryptor.epk().to_bytes().0, @@ -180,7 +180,7 @@ pub(crate) mod testing { asset in arb_asset_base(), rng_seed in prop::array::uniform32(prop::num::u8::ANY), memo in prop::collection::vec(prop::num::u8::ANY, 512), - ) -> Action<(), D> { + ) -> Action<(), P> { let cmx = ExtractedNoteCommitment::from(note.commitment()); let cv_net = ValueCommitment::derive( spend_value - output_value, @@ -212,7 +212,7 @@ pub(crate) mod testing { fake_sighash in prop::array::uniform32(prop::num::u8::ANY), asset in arb_asset_base(), memo in prop::collection::vec(prop::num::u8::ANY, 512), - ) -> Action, D> { + ) -> Action, P> { let cmx = ExtractedNoteCommitment::from(note.commitment()); let cv_net = ValueCommitment::derive( spend_value - output_value, diff --git a/src/builder.rs b/src/builder.rs index 61cc2aa0e..67fb00920 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -15,13 +15,13 @@ use crate::{ address::Address, builder::BuildError::{BurnNative, BurnZero}, bundle::{Authorization, Authorized, Bundle, Flags}, - domain::{OrchardDomain, OrchardDomainCommon}, keys::{ FullViewingKey, OutgoingViewingKey, Scope, SpendAuthorizingKey, SpendValidatingKey, SpendingKey, }, note::{AssetBase, ExtractedNoteCommitment, Note, Nullifier, Rho, TransmittedNoteCiphertext}, primitives::redpallas::{self, Binding, SpendAuth}, + primitives::{OrchardDomain, OrchardPrimitives}, tree::{Anchor, MerklePath}, value::{self, NoteValue, OverflowError, ValueCommitTrapdoor, ValueCommitment, ValueSum}, Proof, @@ -415,18 +415,18 @@ impl OutputInfo { /// Defined in [Zcash Protocol Spec ยง 4.7.3: Sending Notes (Orchard)][orchardsend]. /// /// [orchardsend]: https://zips.z.cash/protocol/nu5.pdf#orchardsend - fn build( + fn build( &self, cv_net: &ValueCommitment, nf_old: Nullifier, mut rng: impl RngCore, - ) -> (Note, ExtractedNoteCommitment, TransmittedNoteCiphertext) { + ) -> (Note, ExtractedNoteCommitment, TransmittedNoteCiphertext

) { let rho = Rho::from_nf_old(nf_old); let note = Note::new(self.recipient, self.value, self.asset, rho, &mut rng); let cm_new = note.commitment(); let cmx = cm_new.into(); - let encryptor = NoteEncryption::>::new(self.ovk.clone(), note, self.memo); + let encryptor = NoteEncryption::>::new(self.ovk.clone(), note, self.memo); let encrypted_note = TransmittedNoteCiphertext { epk_bytes: encryptor.epk().to_bytes().0, @@ -437,13 +437,13 @@ impl OutputInfo { (note, cmx, encrypted_note) } - fn into_pczt( + fn into_pczt( self, cv_net: &ValueCommitment, nf_old: Nullifier, rng: impl RngCore, ) -> crate::pczt::Output { - let (note, cmx, encrypted_note) = self.build::(cv_net, nf_old, rng); + let (note, cmx, encrypted_note) = self.build::

(cv_net, nf_old, rng); crate::pczt::Output { cmx, @@ -532,7 +532,7 @@ impl ActionInfo { ) } - fn build_for_pczt(self, mut rng: impl RngCore) -> crate::pczt::Action { + fn build_for_pczt(self, mut rng: impl RngCore) -> crate::pczt::Action { assert_eq!( self.spend.note.asset(), self.output.asset, @@ -544,7 +544,7 @@ impl ActionInfo { let spend = self.spend.into_pczt(&mut rng); let output = self .output - .into_pczt::(&cv_net, spend.nullifier, &mut rng); + .into_pczt::

(&cv_net, spend.nullifier, &mut rng); crate::pczt::Action { cv_net, @@ -648,7 +648,7 @@ impl Builder { /// Returns an error if the given Merkle path does not have the required anchor for /// the given note. /// - /// [`OrchardDomain`]: crate::domain::OrchardDomain + /// [`OrchardDomain`]: crate::primitives::OrchardDomain /// [`MerkleHashOrchard`]: crate::tree::MerkleHashOrchard pub fn add_spend( &mut self, @@ -774,7 +774,7 @@ impl Builder { /// Builds a bundle containing the given spent notes and outputs along with their /// metadata, for inclusion in a PCZT. - pub fn build_for_pczt( + pub fn build_for_pczt( self, rng: impl RngCore, ) -> Result<(crate::pczt::Bundle, BundleMetadata), BuildError> { @@ -789,7 +789,7 @@ impl Builder { // Create the actions. let actions = pre_actions .into_iter() - .map(|a| a.build_for_pczt::(&mut rng)) + .map(|a| a.build_for_pczt::

(&mut rng)) .collect::>(); Ok(( @@ -1267,7 +1267,7 @@ impl MaybeSigned { } } -impl Bundle, V, D> { +impl Bundle, V, P> { /// Loads the sighash into this bundle, preparing it for signing. /// /// This API ensures that all signatures are created over the same sighash. @@ -1275,7 +1275,7 @@ impl Bundle Bundle, V, D> { + ) -> Bundle, V, P> { self.map_authorization( &mut rng, |rng, _, SigningMetadata { dummy_ask, parts }| { @@ -1296,7 +1296,7 @@ impl Bundle Bundle, V, D> { +impl Bundle, V, P> { /// Applies signatures to this bundle, in order to authorize it. /// /// This is a helper method that wraps [`Bundle::prepare`], [`Bundle::sign`], and @@ -1306,7 +1306,7 @@ impl Bundle, V, D> { mut rng: R, sighash: [u8; 32], signing_keys: &[SpendAuthorizingKey], - ) -> Result, BuildError> { + ) -> Result, BuildError> { signing_keys .iter() .fold(self.prepare(&mut rng, sighash), |partial, ask| { @@ -1316,7 +1316,9 @@ impl Bundle, V, D> { } } -impl Bundle, V, D> { +impl + Bundle, V, P> +{ /// Signs this bundle with the given [`SpendAuthorizingKey`]. /// /// This will apply signatures for all notes controlled by this spending key. @@ -1379,11 +1381,11 @@ impl Bundle Bundle, V, D> { +impl Bundle, V, P> { /// Finalizes this bundle, enabling it to be included in a transaction. /// /// Returns an error if any signatures are missing. - pub fn finalize(self) -> Result, BuildError> { + pub fn finalize(self) -> Result, BuildError> { self.try_map_authorization( &mut (), |_, _, maybe| maybe.finalize(), @@ -1448,10 +1450,10 @@ pub mod testing { address::testing::arb_address, bundle::{Authorized, Bundle}, circuit::ProvingKey, - domain::OrchardDomainCommon, keys::{testing::arb_spending_key, FullViewingKey, SpendAuthorizingKey, SpendingKey}, note::testing::arb_note, orchard_flavor::OrchardFlavor, + primitives::OrchardPrimitives, tree::{Anchor, MerkleHashOrchard, MerklePath}, value::{testing::arb_positive_note_value, NoteValue, MAX_NOTE_VALUE}, Address, Note, @@ -1514,8 +1516,8 @@ pub mod testing { /// `BuilderArb` adapts `arb_...` functions for both Vanilla and ZSA Orchard protocol variations /// in property-based testing, addressing proptest crate limitations. #[derive(Debug)] - pub struct BuilderArb { - phantom: core::marker::PhantomData, + pub struct BuilderArb { + phantom: core::marker::PhantomData

, } impl BuilderArb { diff --git a/src/bundle.rs b/src/bundle.rs index af2762a66..165bad6d1 100644 --- a/src/bundle.rs +++ b/src/bundle.rs @@ -23,10 +23,10 @@ use crate::{ action::Action, address::Address, bundle::commitments::{hash_bundle_auth_data, hash_bundle_txid_data}, - domain::{OrchardDomain, OrchardDomainCommon}, keys::{IncomingViewingKey, OutgoingViewingKey, PreparedIncomingViewingKey}, note::{AssetBase, Note}, primitives::redpallas::{self, Binding, SpendAuth}, + primitives::{OrchardDomain, OrchardPrimitives}, tree::Anchor, value::{NoteValue, ValueCommitTrapdoor, ValueCommitment, ValueSum}, Proof, @@ -36,7 +36,7 @@ use crate::{ use crate::circuit::{Instance, VerifyingKey}; #[cfg(feature = "circuit")] -impl Action { +impl Action { /// Prepares the public instance for this action, for creating and verifying the /// bundle proof. pub fn to_instance(&self, flags: Flags, anchor: Anchor) -> Instance { @@ -201,9 +201,9 @@ pub trait Authorization: fmt::Debug { /// A bundle of actions to be applied to the ledger. #[derive(Clone)] -pub struct Bundle { +pub struct Bundle { /// The list of actions that make up this bundle. - actions: NonEmpty>, + actions: NonEmpty>, /// Orchard-specific transaction-level flags for this bundle. flags: Flags, /// The net value moved out of the Orchard shielded pool. @@ -223,11 +223,11 @@ pub struct Bundle { authorization: A, } -impl fmt::Debug for Bundle { +impl fmt::Debug for Bundle { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { /// Helper struct for debug-printing actions without exposing `NonEmpty`. - struct Actions<'a, A, D: OrchardDomainCommon>(&'a NonEmpty>); - impl fmt::Debug for Actions<'_, A, D> { + struct Actions<'a, A, P: OrchardPrimitives>(&'a NonEmpty>); + impl fmt::Debug for Actions<'_, A, P> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self.0.iter()).finish() } @@ -243,10 +243,10 @@ impl fmt::Debug for Bun } } -impl Bundle { +impl Bundle { /// Constructs a `Bundle` from its constituent parts. pub fn from_parts( - actions: NonEmpty>, + actions: NonEmpty>, flags: Flags, value_balance: V, burn: Vec<(AssetBase, NoteValue)>, @@ -265,7 +265,7 @@ impl Bundle { } /// Returns the list of actions that make up this bundle. - pub fn actions(&self) -> &NonEmpty> { + pub fn actions(&self) -> &NonEmpty> { &self.actions } @@ -308,7 +308,7 @@ impl Bundle { pub fn try_map_value_balance Result>( self, f: F, - ) -> Result, E> { + ) -> Result, E> { Ok(Bundle { actions: self.actions, flags: self.flags, @@ -326,7 +326,7 @@ impl Bundle { context: &mut R, mut spend_auth: impl FnMut(&mut R, &A, A::SpendAuth) -> U::SpendAuth, step: impl FnOnce(&mut R, A) -> U, - ) -> Bundle { + ) -> Bundle { let authorization = self.authorization; Bundle { actions: self @@ -347,7 +347,7 @@ impl Bundle { context: &mut R, mut spend_auth: impl FnMut(&mut R, &A, A::SpendAuth) -> Result, step: impl FnOnce(&mut R, A) -> Result, - ) -> Result, E> { + ) -> Result, E> { let authorization = self.authorization; let new_actions = self .actions @@ -462,8 +462,8 @@ impl Bundle { } } -pub(crate) fn derive_bvk, D: OrchardDomainCommon>( - actions: &NonEmpty>, +pub(crate) fn derive_bvk, P: OrchardPrimitives>( + actions: &NonEmpty>, value_balance: V, burn: &[(AssetBase, NoteValue)], ) -> redpallas::VerificationKey { @@ -491,7 +491,7 @@ pub(crate) fn derive_bvk_raw( .into_bvk() } -impl, D: OrchardDomainCommon> Bundle { +impl, P: OrchardPrimitives> Bundle { /// Computes a commitment to the effects of this bundle, suitable for inclusion within /// a transaction ID. pub fn commitment(&self) -> BundleCommitment { @@ -546,7 +546,7 @@ impl Authorized { } } -impl Bundle { +impl Bundle { /// Computes a commitment to the authorizing data within for this bundle. /// /// This together with `Bundle::commitment` bind the entire bundle. @@ -564,7 +564,7 @@ impl Bundle { } #[cfg(feature = "std")] -impl DynamicUsage for Bundle { +impl DynamicUsage for Bundle { fn dynamic_usage(&self) -> usize { self.actions.tail.dynamic_usage() + self.value_balance.dynamic_usage() @@ -631,9 +631,9 @@ pub mod testing { use super::{Action, Authorized, Bundle, Flags}; pub use crate::action::testing::ActionArb; - use crate::domain::OrchardDomainCommon; use crate::note::asset_base::testing::arb_zsa_asset_base; use crate::note::AssetBase; + use crate::primitives::OrchardPrimitives; use crate::value::testing::arb_note_value; /// Marker type for a bundle that contains no authorizing data. @@ -642,16 +642,16 @@ pub mod testing { /// `BundleArb` adapts `arb_...` functions for both Vanilla and ZSA Orchard protocol variations /// in property-based testing, addressing proptest crate limitations. #[derive(Debug)] - pub struct BundleArb { - phantom: std::marker::PhantomData, + pub struct BundleArb { + phantom: std::marker::PhantomData

, } - impl BundleArb { + impl BundleArb

{ /// Generate an unauthorized action having spend and output values less than MAX_NOTE_VALUE / n_actions. pub fn arb_unauthorized_action_n( n_actions: usize, flags: Flags, - ) -> impl Strategy)> { + ) -> impl Strategy)> { let spend_value_gen = if flags.spends_enabled { Strategy::boxed(arb_note_value_bounded(MAX_NOTE_VALUE / n_actions as u64)) } else { @@ -676,7 +676,7 @@ pub mod testing { pub fn arb_action_n( n_actions: usize, flags: Flags, - ) -> impl Strategy, D>)> { + ) -> impl Strategy, P>)> { let spend_value_gen = if flags.spends_enabled { Strategy::boxed(arb_note_value_bounded(MAX_NOTE_VALUE / n_actions as u64)) } else { @@ -737,7 +737,7 @@ pub mod testing { anchor in Self::arb_base().prop_map(Anchor::from), flags in Just(flags), burn in vec(Self::arb_asset_to_burn(), 1usize..10) - ) -> Bundle { + ) -> Bundle { let (balances, actions): (Vec, Vec>) = acts.into_iter().unzip(); Bundle::from_parts( @@ -768,7 +768,7 @@ pub mod testing { fake_sighash in prop::array::uniform32(prop::num::u8::ANY), flags in Just(flags), burn in vec(Self::arb_asset_to_burn(), 1usize..10) - ) -> Bundle { + ) -> Bundle { let (balances, actions): (Vec, Vec, >) = acts.into_iter().unzip(); let rng = StdRng::from_seed(rng_seed); diff --git a/src/bundle/batch.rs b/src/bundle/batch.rs index 90bbfeb30..94b0306d9 100644 --- a/src/bundle/batch.rs +++ b/src/bundle/batch.rs @@ -9,8 +9,8 @@ use super::{Authorized, Bundle}; use crate::{ circuit::VerifyingKey, - orchard_flavor::OrchardFlavor, primitives::redpallas::{self, Binding, SpendAuth}, + primitives::OrchardPrimitives, }; /// A signature within an authorized Orchard bundle. @@ -39,9 +39,9 @@ impl BatchValidator { } /// Adds the proof and RedPallas signatures from the given bundle to the validator. - pub fn add_bundle, FL: OrchardFlavor>( + pub fn add_bundle, P: OrchardPrimitives>( &mut self, - bundle: &Bundle, + bundle: &Bundle, sighash: [u8; 32], ) { for action in bundle.actions().iter() { diff --git a/src/bundle/commitments.rs b/src/bundle/commitments.rs index c7ac76d38..a060cab88 100644 --- a/src/bundle/commitments.rs +++ b/src/bundle/commitments.rs @@ -4,8 +4,8 @@ use blake2b_simd::{Hash as Blake2bHash, Params, State}; use crate::{ bundle::{Authorization, Authorized, Bundle}, - domain::OrchardDomainCommon, issuance::{IssueAuth, IssueBundle, Signed}, + primitives::OrchardPrimitives, }; pub(crate) const ZCASH_ORCHARD_HASH_PERSONALIZATION: &[u8; 16] = b"ZTxIdOrchardHash"; @@ -37,14 +37,10 @@ pub(crate) fn hasher(personal: &[u8; 16]) -> State { /// /// [zip244]: https://zips.z.cash/zip-0244 /// [zip226]: https://zips.z.cash/zip-0226 -pub(crate) fn hash_bundle_txid_data< - A: Authorization, - V: Copy + Into, - D: OrchardDomainCommon, ->( - bundle: &Bundle, +pub(crate) fn hash_bundle_txid_data, P: OrchardPrimitives>( + bundle: &Bundle, ) -> Blake2bHash { - D::hash_bundle_txid_data(bundle) + P::hash_bundle_txid_data(bundle) } /// Construct the commitment for the absent bundle as defined in @@ -60,10 +56,10 @@ pub fn hash_bundle_txid_empty() -> Blake2bHash { /// Identifier Non-Malleability][zip244] /// /// [zip244]: https://zips.z.cash/zip-0244 -pub(crate) fn hash_bundle_auth_data( - bundle: &Bundle, +pub(crate) fn hash_bundle_auth_data( + bundle: &Bundle, ) -> Blake2bHash { - D::hash_bundle_auth_data(bundle) + P::hash_bundle_auth_data(bundle) } /// Construct the commitment for an absent bundle as defined in diff --git a/src/domain.rs b/src/domain.rs deleted file mode 100644 index c946d6772..000000000 --- a/src/domain.rs +++ /dev/null @@ -1,20 +0,0 @@ -//! In-band secret distribution for Orchard bundles. -//! -//! This module handles the encryption and decryption of notes within the Orchard protocol, -//! It includes functionality for handling both the standard "Vanilla" variantion and the ZSA -//! variantion, with different implementations for each. The different implementations are -//! organized into separate submodules. - -mod compact_action; -mod orchard_domain; -mod orchard_domain_vanilla; -mod orchard_domain_zsa; -mod zcash_note_encryption_domain; - -pub use { - compact_action::CompactAction, - orchard_domain::{OrchardDomain, OrchardDomainCommon}, -}; - -#[cfg(feature = "test-dependencies")] -pub use compact_action::testing::fake_compact_action; diff --git a/src/lib.rs b/src/lib.rs index 1a15de563..f6d8dff1c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -33,7 +33,6 @@ pub mod bundle; #[cfg(feature = "circuit")] pub mod circuit; mod constants; -pub mod domain; pub mod issuance; pub mod keys; pub mod note; diff --git a/src/note.rs b/src/note.rs index 5f070d393..14f02a7d5 100644 --- a/src/note.rs +++ b/src/note.rs @@ -11,8 +11,8 @@ use rand::RngCore; use subtle::{Choice, ConditionallySelectable, CtOption}; use crate::{ - domain::OrchardDomainCommon, keys::{EphemeralSecretKey, FullViewingKey, Scope, SpendingKey}, + primitives::OrchardPrimitives, spec::{to_base, to_scalar, NonZeroPallasScalar, PrfExpand}, value::NoteValue, Address, @@ -41,7 +41,7 @@ impl Rho { /// value otherwise. /// /// [`Action::rho`]: crate::action::Action::rho - /// [`CompactAction::rho`]: crate::domain::CompactAction::rho + /// [`CompactAction::rho`]: crate::primitives::CompactAction::rho pub fn from_bytes(bytes: &[u8; 32]) -> CtOption { pallas::Base::from_repr(*bytes).map(Rho) } @@ -397,17 +397,17 @@ pub(crate) fn rho_for_issuance_note( /// An encrypted note. #[derive(Clone)] -pub struct TransmittedNoteCiphertext { +pub struct TransmittedNoteCiphertext { /// The serialization of the ephemeral public key pub epk_bytes: [u8; 32], /// The encrypted note ciphertext - pub enc_ciphertext: D::NoteCiphertextBytes, + pub enc_ciphertext: P::NoteCiphertextBytes, /// An encrypted value that allows the holder of the outgoing cipher /// key for the note to recover the note plaintext. pub out_ciphertext: [u8; 80], } -impl fmt::Debug for TransmittedNoteCiphertext { +impl fmt::Debug for TransmittedNoteCiphertext

{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("TransmittedNoteCiphertext") .field("epk_bytes", &self.epk_bytes) diff --git a/src/orchard_flavor.rs b/src/orchard_flavor.rs index f0459abf0..0cc898690 100644 --- a/src/orchard_flavor.rs +++ b/src/orchard_flavor.rs @@ -1,7 +1,7 @@ //! Defines types and traits for the variations ("flavors") of the Orchard protocol (Vanilla and ZSA). #[cfg(feature = "circuit")] -use crate::{circuit::OrchardCircuit, domain::OrchardDomainCommon}; +use crate::{circuit::OrchardCircuit, primitives::OrchardPrimitives}; /// Represents the "Vanilla" variation ("flavor") of the Orchard protocol. #[derive(Debug, Clone, Default, PartialEq, Eq)] @@ -13,7 +13,7 @@ pub struct OrchardZSA; /// A trait binding the common functionality between different Orchard protocol flavors. #[cfg(feature = "circuit")] -pub trait OrchardFlavor: OrchardDomainCommon + OrchardCircuit {} +pub trait OrchardFlavor: OrchardPrimitives + OrchardCircuit {} #[cfg(feature = "circuit")] impl OrchardFlavor for OrchardVanilla {} diff --git a/src/pczt.rs b/src/pczt.rs index 20d654925..ed635bb80 100644 --- a/src/pczt.rs +++ b/src/pczt.rs @@ -12,12 +12,12 @@ use zip32::ChildIndex; use crate::{ bundle::Flags, - domain::OrchardDomainCommon, keys::{FullViewingKey, SpendingKey}, note::{ AssetBase, ExtractedNoteCommitment, Nullifier, RandomSeed, Rho, TransmittedNoteCiphertext, }, primitives::redpallas::{self, Binding, SpendAuth}, + primitives::OrchardPrimitives, tree::MerklePath, value::{NoteValue, ValueCommitTrapdoor, ValueCommitment, ValueSum}, Address, Anchor, Proof, @@ -376,8 +376,8 @@ pub struct PcztTransmittedNoteCiphertext { pub out_ciphertext: [u8; 80], } -impl From> for PcztTransmittedNoteCiphertext { - fn from(transmitted: TransmittedNoteCiphertext) -> Self { +impl From> for PcztTransmittedNoteCiphertext { + fn from(transmitted: TransmittedNoteCiphertext

) -> Self { PcztTransmittedNoteCiphertext { epk_bytes: transmitted.epk_bytes, enc_ciphertext: transmitted.enc_ciphertext.as_ref().to_vec(), @@ -386,11 +386,11 @@ impl From> for PcztTransmit } } -impl From for TransmittedNoteCiphertext { +impl From for TransmittedNoteCiphertext

{ fn from(ciphertext: PcztTransmittedNoteCiphertext) -> Self { TransmittedNoteCiphertext { epk_bytes: ciphertext.epk_bytes, - enc_ciphertext: D::NoteCiphertextBytes::from_slice(&ciphertext.enc_ciphertext) + enc_ciphertext: P::NoteCiphertextBytes::from_slice(&ciphertext.enc_ciphertext) .expect("Failed to parse enc_ciphertext: data may be corrupt or incorrect size"), out_ciphertext: ciphertext.out_ciphertext, } diff --git a/src/pczt/prover.rs b/src/pczt/prover.rs index a11f7b035..0977acc5c 100644 --- a/src/pczt/prover.rs +++ b/src/pczt/prover.rs @@ -5,15 +5,14 @@ use rand::{CryptoRng, RngCore}; use crate::{ builder::SpendInfo, - circuit::{Circuit, Instance, ProvingKey, Witnesses}, + circuit::{Circuit, Instance, OrchardCircuit, ProvingKey, Witnesses}, note::Rho, - orchard_flavor::OrchardFlavor, Note, Proof, }; impl super::Bundle { /// Adds a proof to this PCZT bundle. - pub fn create_proof( + pub fn create_proof( &mut self, pk: &ProvingKey, rng: R, @@ -86,9 +85,9 @@ impl super::Bundle { .ok_or(ProverError::MissingSpendAuthRandomizer)?; let rcv = action.rcv.ok_or(ProverError::MissingValueCommitTrapdoor)?; - Witnesses::from_action_context::(spend, output_note, alpha, rcv) + Witnesses::from_action_context::(spend, output_note, alpha, rcv) .ok_or(ProverError::RhoMismatch) - .map(|witnesses| Circuit:: { + .map(|witnesses| Circuit:: { witnesses, phantom: core::marker::PhantomData, }) diff --git a/src/pczt/tx_extractor.rs b/src/pczt/tx_extractor.rs index f71a05d3e..483348f17 100644 --- a/src/pczt/tx_extractor.rs +++ b/src/pczt/tx_extractor.rs @@ -4,8 +4,8 @@ use rand::{CryptoRng, RngCore}; use super::Action; use crate::{ bundle::{Authorization, Authorized, EffectsOnly}, - domain::OrchardDomainCommon, primitives::redpallas::{self, Binding, SpendAuth}, + primitives::OrchardPrimitives, Proof, }; @@ -15,9 +15,9 @@ impl super::Bundle { /// This is used by the Signer role to produce the transaction sighash. /// /// [regular `Bundle`]: crate::Bundle - pub fn extract_effects, D: OrchardDomainCommon>( + pub fn extract_effects, P: OrchardPrimitives>( &self, - ) -> Result>, TxExtractorError> { + ) -> Result>, TxExtractorError> { self.to_tx_data(|_| Ok(()), |_| Ok(EffectsOnly)) } @@ -26,9 +26,9 @@ impl super::Bundle { /// This is used by the Transaction Extractor role to produce the final transaction. /// /// [regular `Bundle`]: crate::Bundle - pub fn extract, D: OrchardDomainCommon>( + pub fn extract, P: OrchardPrimitives>( self, - ) -> Result>, TxExtractorError> { + ) -> Result>, TxExtractorError> { self.to_tx_data( |action| { action @@ -52,18 +52,18 @@ impl super::Bundle { } /// Converts this PCZT bundle into a regular bundle with the given authorizations. - fn to_tx_data( + fn to_tx_data( &self, action_auth: F, bundle_auth: G, - ) -> Result>, E> + ) -> Result>, E> where A: Authorization, E: From, F: Fn(&Action) -> Result<::SpendAuth, E>, G: FnOnce(&Self) -> Result, V: TryFrom, - D: OrchardDomainCommon, + P: OrchardPrimitives, { let actions = self .actions @@ -128,7 +128,7 @@ impl Authorization for Unbound { type SpendAuth = redpallas::Signature; } -impl crate::Bundle { +impl crate::Bundle { /// Verifies the given sighash with every `spend_auth_sig`, and then binds the bundle. /// /// Returns `None` if the given sighash does not validate against every `spend_auth_sig`. @@ -136,7 +136,7 @@ impl crate::Bundle { self, sighash: [u8; 32], rng: R, - ) -> Option> { + ) -> Option> { if self .actions() .iter() diff --git a/src/primitives.rs b/src/primitives.rs index 42a01fe48..c55e8ec3b 100644 --- a/src/primitives.rs +++ b/src/primitives.rs @@ -1,7 +1,25 @@ //! Primitives used in the Orchard protocol. -// TODO: -// - DH stuff -// - EphemeralPublicKey -// - EphemeralSecretKey +//! +//! This module handles +//! - the encryption and decryption of notes, +//! - the commitments, +//! - the redpallas signatures. +//! It includes functionality for handling both the standard "Vanilla" variation and the ZSA +//! variation, with different implementations for each. The different implementations are +//! organized into separate submodules. +mod compact_action; +mod orchard_domain; +mod orchard_primitives; +mod orchard_primitives_vanilla; +mod orchard_primitives_zsa; pub mod redpallas; +mod zcash_note_encryption_domain; + +pub use { + compact_action::CompactAction, orchard_domain::OrchardDomain, + orchard_primitives::OrchardPrimitives, +}; + +#[cfg(feature = "test-dependencies")] +pub use compact_action::testing::fake_compact_action; diff --git a/src/domain/compact_action.rs b/src/primitives/compact_action.rs similarity index 69% rename from src/domain/compact_action.rs rename to src/primitives/compact_action.rs index 985b3075b..12ed9d2ae 100644 --- a/src/domain/compact_action.rs +++ b/src/primitives/compact_action.rs @@ -9,9 +9,9 @@ use crate::{ note::{ExtractedNoteCommitment, Nullifier, Rho}, }; -use super::orchard_domain::{OrchardDomain, OrchardDomainCommon}; +use super::{orchard_domain::OrchardDomain, orchard_primitives::OrchardPrimitives}; -impl ShieldedOutput> for Action { +impl ShieldedOutput> for Action { fn ephemeral_key(&self) -> EphemeralKeyBytes { EphemeralKeyBytes(self.encrypted_note().epk_bytes) } @@ -20,13 +20,13 @@ impl ShieldedOutput> for Action Option<&D::NoteCiphertextBytes> { + fn enc_ciphertext(&self) -> Option<&P::NoteCiphertextBytes> { Some(&self.encrypted_note().enc_ciphertext) } - fn enc_ciphertext_compact(&self) -> D::CompactNoteCiphertextBytes { - D::CompactNoteCiphertextBytes::from_slice( - &self.encrypted_note().enc_ciphertext.as_ref()[..D::COMPACT_NOTE_SIZE], + fn enc_ciphertext_compact(&self) -> P::CompactNoteCiphertextBytes { + P::CompactNoteCiphertextBytes::from_slice( + &self.encrypted_note().enc_ciphertext.as_ref()[..P::COMPACT_NOTE_SIZE], ) .unwrap() } @@ -34,24 +34,24 @@ impl ShieldedOutput> for Action { +pub struct CompactAction { nullifier: Nullifier, cmx: ExtractedNoteCommitment, ephemeral_key: EphemeralKeyBytes, - enc_ciphertext: D::CompactNoteCiphertextBytes, + enc_ciphertext: P::CompactNoteCiphertextBytes, } -impl fmt::Debug for CompactAction { +impl fmt::Debug for CompactAction

{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "CompactAction") } } -impl From<&Action> for CompactAction +impl From<&Action> for CompactAction

where - Action: ShieldedOutput>, + Action: ShieldedOutput>, { - fn from(action: &Action) -> Self { + fn from(action: &Action) -> Self { CompactAction { nullifier: *action.nullifier(), cmx: *action.cmx(), @@ -61,7 +61,7 @@ where } } -impl ShieldedOutput> for CompactAction { +impl ShieldedOutput> for CompactAction

{ fn ephemeral_key(&self) -> EphemeralKeyBytes { EphemeralKeyBytes(self.ephemeral_key.0) } @@ -70,22 +70,22 @@ impl ShieldedOutput> for CompactAction< self.cmx.to_bytes() } - fn enc_ciphertext(&self) -> Option<&D::NoteCiphertextBytes> { + fn enc_ciphertext(&self) -> Option<&P::NoteCiphertextBytes> { None } - fn enc_ciphertext_compact(&self) -> D::CompactNoteCiphertextBytes { - D::CompactNoteCiphertextBytes::from_slice(self.enc_ciphertext.as_ref()).unwrap() + fn enc_ciphertext_compact(&self) -> P::CompactNoteCiphertextBytes { + P::CompactNoteCiphertextBytes::from_slice(self.enc_ciphertext.as_ref()).unwrap() } } -impl CompactAction { +impl CompactAction

{ /// Create a CompactAction from its constituent parts pub fn from_parts( nullifier: Nullifier, cmx: ExtractedNoteCommitment, ephemeral_key: EphemeralKeyBytes, - enc_ciphertext: D::CompactNoteCiphertextBytes, + enc_ciphertext: P::CompactNoteCiphertextBytes, ) -> Self { Self { nullifier, @@ -120,24 +120,24 @@ pub mod testing { use crate::{ address::Address, - domain::zcash_note_encryption_domain::MEMO_SIZE, keys::OutgoingViewingKey, note::{AssetBase, ExtractedNoteCommitment, Note, Nullifier, RandomSeed, Rho}, + primitives::zcash_note_encryption_domain::MEMO_SIZE, value::NoteValue, }; - use super::{CompactAction, OrchardDomain, OrchardDomainCommon}; + use super::{CompactAction, OrchardDomain, OrchardPrimitives}; /// Creates a fake `CompactAction` paying the given recipient the specified value. /// /// Returns the `CompactAction` and the new note. - pub fn fake_compact_action( + pub fn fake_compact_action( rng: &mut R, nf_old: Nullifier, recipient: Address, value: NoteValue, ovk: Option, - ) -> (CompactAction, Note) { + ) -> (CompactAction

, Note) { let rho = Rho::from_nf_old(nf_old); let rseed = { loop { @@ -150,9 +150,9 @@ pub mod testing { } }; let note = Note::from_parts(recipient, value, AssetBase::native(), rho, rseed).unwrap(); - let encryptor = NoteEncryption::>::new(ovk, note, [0u8; MEMO_SIZE]); + let encryptor = NoteEncryption::>::new(ovk, note, [0u8; MEMO_SIZE]); let cmx = ExtractedNoteCommitment::from(note.commitment()); - let ephemeral_key = OrchardDomain::::epk_bytes(encryptor.epk()); + let ephemeral_key = OrchardDomain::

::epk_bytes(encryptor.epk()); let enc_ciphertext = encryptor.encrypt_note_plaintext(); ( @@ -160,8 +160,8 @@ pub mod testing { nullifier: nf_old, cmx, ephemeral_key, - enc_ciphertext: D::CompactNoteCiphertextBytes::from_slice( - &enc_ciphertext.as_ref()[..D::COMPACT_NOTE_SIZE], + enc_ciphertext: P::CompactNoteCiphertextBytes::from_slice( + &enc_ciphertext.as_ref()[..P::COMPACT_NOTE_SIZE], ) .unwrap(), }, diff --git a/src/primitives/orchard_domain.rs b/src/primitives/orchard_domain.rs new file mode 100644 index 000000000..2f03e9074 --- /dev/null +++ b/src/primitives/orchard_domain.rs @@ -0,0 +1,41 @@ +//! Orchard-specific note encryption domain. + +use crate::{ + action::Action, note::Rho, primitives::compact_action::CompactAction, + primitives::orchard_primitives::OrchardPrimitives, +}; + +/// Orchard-specific note encryption logic. +#[derive(Debug, Clone)] +pub struct OrchardDomain { + /// A parameter needed to generate the nullifier. + pub rho: Rho, + phantom: core::marker::PhantomData

, +} + +impl OrchardDomain

{ + /// Constructs a domain that can be used to trial-decrypt this action's output note. + pub fn for_action(act: &Action) -> Self { + Self { + rho: act.rho(), + phantom: Default::default(), + } + } + + /// Constructs a domain that can be used to trial-decrypt this action's output note. + pub fn for_compact_action(act: &CompactAction

) -> Self { + Self { + rho: act.rho(), + phantom: Default::default(), + } + } + + /// Constructs a domain from a rho. + #[cfg(test)] + pub fn for_rho(rho: Rho) -> Self { + Self { + rho, + phantom: Default::default(), + } + } +} diff --git a/src/domain/orchard_domain.rs b/src/primitives/orchard_primitives.rs similarity index 78% rename from src/domain/orchard_domain.rs rename to src/primitives/orchard_primitives.rs index 22c3a94d2..1b7af8be6 100644 --- a/src/domain/orchard_domain.rs +++ b/src/primitives/orchard_primitives.rs @@ -1,4 +1,4 @@ -//! The OrchardDomain trait represents the difference between the `OrchardVanilla` and the +//! The OrchardPrimitives trait represents the difference between the `OrchardVanilla` and the //! `OrchardZSA` commitment, encryption and decryption procedures. use core::fmt; @@ -7,7 +7,6 @@ use blake2b_simd::{Hash as Blake2bHash, State}; use zcash_note_encryption::{note_bytes::NoteBytes, AEAD_TAG_SIZE}; use crate::{ - action::Action, bundle::{ commitments::{ hasher, ZCASH_ORCHARD_ACTIONS_COMPACT_HASH_PERSONALIZATION, @@ -16,16 +15,14 @@ use crate::{ }, Authorization, Authorized, }, - domain::{ - compact_action::CompactAction, - zcash_note_encryption_domain::{Memo, MEMO_SIZE}, - }, - note::{AssetBase, Rho}, + note::AssetBase, + primitives::zcash_note_encryption_domain::{Memo, MEMO_SIZE}, Bundle, Note, }; -/// Represents the Orchard protocol domain specifics required for note encryption and decryption. -pub trait OrchardDomainCommon: fmt::Debug + Clone { +/// Represents the Orchard protocol domain specifics required for commitment, note encryption and +/// decryption. +pub trait OrchardPrimitives: fmt::Debug + Clone { /// The size of a compact note, specific to the Orchard protocol. const COMPACT_NOTE_SIZE: usize; @@ -121,38 +118,3 @@ pub trait OrchardDomainCommon: fmt::Debug + Clone { /// [zip226]: https://zips.z.cash/zip-0226 fn hash_bundle_auth_data(bundle: &Bundle) -> Blake2bHash; } - -/// Orchard-specific note encryption logic. -#[derive(Debug, Clone)] -pub struct OrchardDomain { - /// A parameter needed to generate the nullifier. - pub rho: Rho, - phantom: core::marker::PhantomData, -} - -impl OrchardDomain { - /// Constructs a domain that can be used to trial-decrypt this action's output note. - pub fn for_action(act: &Action) -> Self { - Self { - rho: act.rho(), - phantom: Default::default(), - } - } - - /// Constructs a domain that can be used to trial-decrypt this action's output note. - pub fn for_compact_action(act: &CompactAction) -> Self { - Self { - rho: act.rho(), - phantom: Default::default(), - } - } - - /// Constructs a domain from a rho. - #[cfg(test)] - pub fn for_rho(rho: Rho) -> Self { - Self { - rho, - phantom: Default::default(), - } - } -} diff --git a/src/domain/orchard_domain_vanilla.rs b/src/primitives/orchard_primitives_vanilla.rs similarity index 96% rename from src/domain/orchard_domain_vanilla.rs rename to src/primitives/orchard_primitives_vanilla.rs index 7f7579818..a853a9784 100644 --- a/src/domain/orchard_domain_vanilla.rs +++ b/src/primitives/orchard_primitives_vanilla.rs @@ -17,13 +17,13 @@ use crate::{ }; use super::{ - orchard_domain::OrchardDomainCommon, + orchard_primitives::OrchardPrimitives, zcash_note_encryption_domain::{ build_base_note_plaintext_bytes, Memo, COMPACT_NOTE_SIZE_VANILLA, NOTE_VERSION_BYTE_V2, }, }; -impl OrchardDomainCommon for OrchardVanilla { +impl OrchardPrimitives for OrchardVanilla { const COMPACT_NOTE_SIZE: usize = COMPACT_NOTE_SIZE_VANILLA; type NotePlaintextBytes = NoteBytesData<{ Self::NOTE_PLAINTEXT_SIZE }>; @@ -114,10 +114,6 @@ mod tests { type OrchardDomainVanilla = OrchardDomain; - /// Implementation of in-band secret distribution for Orchard bundles. - pub type OrchardDomainCommonryptionVanilla = - zcash_note_encryption::NoteEncryption; - proptest! { #[test] fn encoding_roundtrip( @@ -251,7 +247,12 @@ mod tests { // Test encryption // - let ne = OrchardDomainCommonryptionVanilla::new_with_esk(esk, Some(ovk), note, tv.memo); + let ne = zcash_note_encryption::NoteEncryption::::new_with_esk( + esk, + Some(ovk), + note, + tv.memo, + ); assert_eq!(ne.encrypt_note_plaintext().as_ref(), &tv.c_enc[..]); assert_eq!( diff --git a/src/domain/orchard_domain_zsa.rs b/src/primitives/orchard_primitives_zsa.rs similarity index 96% rename from src/domain/orchard_domain_zsa.rs rename to src/primitives/orchard_primitives_zsa.rs index 859b2e521..98fb6b61c 100644 --- a/src/domain/orchard_domain_zsa.rs +++ b/src/primitives/orchard_primitives_zsa.rs @@ -22,14 +22,14 @@ use crate::{ }; use super::{ - orchard_domain::OrchardDomainCommon, + orchard_primitives::OrchardPrimitives, zcash_note_encryption_domain::{ build_base_note_plaintext_bytes, Memo, COMPACT_NOTE_SIZE_VANILLA, COMPACT_NOTE_SIZE_ZSA, NOTE_VERSION_BYTE_V3, }, }; -impl OrchardDomainCommon for OrchardZSA { +impl OrchardPrimitives for OrchardZSA { const COMPACT_NOTE_SIZE: usize = COMPACT_NOTE_SIZE_ZSA; type NotePlaintextBytes = NoteBytesData<{ Self::NOTE_PLAINTEXT_SIZE }>; @@ -139,10 +139,6 @@ mod tests { type OrchardDomainZSA = OrchardDomain; - /// Implementation of in-band secret distribution for Orchard bundles. - pub type OrchardDomainCommonryptionZSA = - zcash_note_encryption::NoteEncryption; - proptest! { #[test] fn encoding_roundtrip( @@ -276,7 +272,12 @@ mod tests { // Test encryption // - let ne = OrchardDomainCommonryptionZSA::new_with_esk(esk, Some(ovk), note, tv.memo); + let ne = zcash_note_encryption::NoteEncryption::::new_with_esk( + esk, + Some(ovk), + note, + tv.memo, + ); assert_eq!(ne.encrypt_note_plaintext().as_ref(), &tv.c_enc[..]); assert_eq!( diff --git a/src/domain/zcash_note_encryption_domain.rs b/src/primitives/zcash_note_encryption_domain.rs similarity index 90% rename from src/domain/zcash_note_encryption_domain.rs rename to src/primitives/zcash_note_encryption_domain.rs index 0bd347564..965dcff27 100644 --- a/src/domain/zcash_note_encryption_domain.rs +++ b/src/primitives/zcash_note_encryption_domain.rs @@ -10,6 +10,7 @@ use zcash_note_encryption::{ OutgoingCipherKey, OUT_PLAINTEXT_SIZE, }; +use super::{orchard_domain::OrchardDomain, orchard_primitives::OrchardPrimitives}; use crate::{ address::Address, keys::{ @@ -20,8 +21,6 @@ use crate::{ value::{NoteValue, ValueCommitment}, }; -use super::orchard_domain::{OrchardDomain, OrchardDomainCommon}; - const PRF_OCK_ORCHARD_PERSONALIZATION: &[u8; 16] = b"Zcash_Orchardock"; const NOTE_VERSION_SIZE: usize = 1; @@ -92,9 +91,9 @@ pub(super) fn parse_note_version(plaintext: &[u8]) -> Option { /// Parses the note plaintext (excluding the memo) and extracts the note and address if valid. /// Domain-specific requirements: /// - If the note version is 3, the `plaintext` must contain a valid encoding of a ZSA asset type. -pub(super) fn parse_note_plaintext_without_memo( +pub(super) fn parse_note_plaintext_without_memo( rho: Rho, - plaintext: &D::CompactNotePlaintextBytes, + plaintext: &P::CompactNotePlaintextBytes, get_validated_pk_d: F, ) -> Option<(Note, Address)> where @@ -124,7 +123,7 @@ where let pk_d = get_validated_pk_d(&diversifier)?; let recipient = Address::from_parts(diversifier, pk_d); - let asset = D::extract_asset(plaintext)?; + let asset = P::extract_asset(plaintext)?; let note = Option::from(Note::from_parts(recipient, value, asset, rho, rseed))?; Some((note, recipient)) @@ -146,7 +145,7 @@ pub(super) fn build_base_note_plaintext_bytes( np } -impl Domain for OrchardDomain { +impl Domain for OrchardDomain

{ type EphemeralSecretKey = EphemeralSecretKey; type EphemeralPublicKey = EphemeralPublicKey; type PreparedEphemeralPublicKey = PreparedEphemeralPublicKey; @@ -162,10 +161,10 @@ impl Domain for OrchardDomain { type ExtractedCommitmentBytes = [u8; 32]; type Memo = Memo; - type NotePlaintextBytes = D::NotePlaintextBytes; - type NoteCiphertextBytes = D::NoteCiphertextBytes; - type CompactNotePlaintextBytes = D::CompactNotePlaintextBytes; - type CompactNoteCiphertextBytes = D::CompactNoteCiphertextBytes; + type NotePlaintextBytes = P::NotePlaintextBytes; + type NoteCiphertextBytes = P::NoteCiphertextBytes; + type CompactNotePlaintextBytes = P::CompactNotePlaintextBytes; + type CompactNoteCiphertextBytes = P::CompactNoteCiphertextBytes; fn derive_esk(note: &Self::Note) -> Option { Some(note.esk()) @@ -204,8 +203,8 @@ impl Domain for OrchardDomain { secret.kdf_orchard(ephemeral_key) } - fn note_plaintext_bytes(note: &Self::Note, memo: &Self::Memo) -> D::NotePlaintextBytes { - D::build_note_plaintext_bytes(note, memo) + fn note_plaintext_bytes(note: &Self::Note, memo: &Self::Memo) -> P::NotePlaintextBytes { + P::build_note_plaintext_bytes(note, memo) } fn derive_ock( @@ -242,9 +241,9 @@ impl Domain for OrchardDomain { fn parse_note_plaintext_without_memo_ivk( &self, ivk: &Self::IncomingViewingKey, - plaintext: &D::CompactNotePlaintextBytes, + plaintext: &P::CompactNotePlaintextBytes, ) -> Option<(Self::Note, Self::Recipient)> { - parse_note_plaintext_without_memo::(self.rho, plaintext, |diversifier| { + parse_note_plaintext_without_memo::(self.rho, plaintext, |diversifier| { Some(DiversifiedTransmissionKey::derive(ivk, diversifier)) }) } @@ -252,16 +251,16 @@ impl Domain for OrchardDomain { fn parse_note_plaintext_without_memo_ovk( &self, pk_d: &Self::DiversifiedTransmissionKey, - plaintext: &D::CompactNotePlaintextBytes, + plaintext: &P::CompactNotePlaintextBytes, ) -> Option<(Self::Note, Self::Recipient)> { - parse_note_plaintext_without_memo::(self.rho, plaintext, |_| Some(*pk_d)) + parse_note_plaintext_without_memo::(self.rho, plaintext, |_| Some(*pk_d)) } fn split_plaintext_at_memo( &self, - plaintext: &D::NotePlaintextBytes, + plaintext: &P::NotePlaintextBytes, ) -> Option<(Self::CompactNotePlaintextBytes, Self::Memo)> { - let (compact, memo) = plaintext.as_ref().split_at(D::COMPACT_NOTE_SIZE); + let (compact, memo) = plaintext.as_ref().split_at(P::COMPACT_NOTE_SIZE); Some(( Self::CompactNotePlaintextBytes::from_slice(compact)?, memo.try_into().ok()?, @@ -278,7 +277,7 @@ impl Domain for OrchardDomain { } } -impl BatchDomain for OrchardDomain { +impl BatchDomain for OrchardDomain

{ fn batch_kdf<'a>( items: impl Iterator, &'a EphemeralKeyBytes)>, ) -> Vec> { diff --git a/tests/builder.rs b/tests/builder.rs index aebb2a501..e32c71e9d 100644 --- a/tests/builder.rs +++ b/tests/builder.rs @@ -3,10 +3,10 @@ use orchard::{ builder::{Builder, BundleType}, bundle::{Authorized, Flags}, circuit::{ProvingKey, VerifyingKey}, - domain::OrchardDomain, keys::{FullViewingKey, PreparedIncomingViewingKey, Scope, SpendAuthorizingKey, SpendingKey}, note::{AssetBase, ExtractedNoteCommitment}, orchard_flavor::{OrchardFlavor, OrchardVanilla, OrchardZSA}, + primitives::{OrchardDomain, OrchardPrimitives}, tree::{MerkleHashOrchard, MerklePath}, value::NoteValue, Anchor, Bundle, Note, @@ -16,8 +16,8 @@ use rand::SeedableRng; use shardtree::{store::memory::MemoryShardStore, ShardTree}; use zcash_note_encryption::try_note_decryption; -pub fn verify_bundle( - bundle: &Bundle, +pub fn verify_bundle( + bundle: &Bundle, vk: &VerifyingKey, verify_proof: bool, ) { diff --git a/tests/zsa.rs b/tests/zsa.rs index 071498847..a0b19ce87 100644 --- a/tests/zsa.rs +++ b/tests/zsa.rs @@ -14,9 +14,9 @@ use orchard::tree::{MerkleHashOrchard, MerklePath}; use orchard::{ builder::{Builder, BundleType}, circuit::{ProvingKey, VerifyingKey}, - domain::OrchardDomain, keys::{FullViewingKey, PreparedIncomingViewingKey, Scope, SpendAuthorizingKey, SpendingKey}, orchard_flavor::OrchardZSA, + primitives::OrchardDomain, value::NoteValue, Address, Anchor, Bundle, Note, };