From 1dd1a82ab4e785cf33b38abe8d9a8f16cf80852d Mon Sep 17 00:00:00 2001 From: Dmitry Demin Date: Mon, 24 Jun 2024 09:40:00 +0200 Subject: [PATCH] Rename OrchardDomain to OrchardNoteEnc, OrchardDomainBase to OrchardDomain, intruduce and use OrchardFlavor --- benches/circuit.rs | 8 ++-- benches/note_decryption.rs | 15 ++++---- src/action.rs | 20 +++++----- src/builder.rs | 34 ++++++++--------- src/bundle.rs | 38 +++++++++---------- src/bundle/batch.rs | 4 +- src/bundle/commitments.rs | 8 ++-- src/circuit.rs | 20 +++++----- src/note.rs | 6 +-- src/note_encryption.rs | 7 ++-- src/note_encryption/compact_action.rs | 24 ++++++------ src/note_encryption/domain.rs | 6 +-- src/note_encryption/orchard_domain.rs | 6 +-- src/note_encryption/orchard_domain_vanilla.rs | 10 ++--- src/note_encryption/orchard_domain_zsa.rs | 10 ++--- src/orchard_flavors.rs | 9 +++++ tests/builder.rs | 14 +++---- tests/zsa.rs | 4 +- 18 files changed, 125 insertions(+), 118 deletions(-) diff --git a/benches/circuit.rs b/benches/circuit.rs index 62c662463..d043dbba3 100644 --- a/benches/circuit.rs +++ b/benches/circuit.rs @@ -8,18 +8,16 @@ use pprof::criterion::{Output, PProfProfiler}; use orchard::{ builder::{Builder, BundleType}, - bundle::OrchardHash, - circuit::{OrchardCircuit, ProvingKey, VerifyingKey}, + circuit::{ProvingKey, VerifyingKey}, keys::{FullViewingKey, Scope, SpendingKey}, note::AssetBase, - note_encryption::OrchardDomain, - orchard_flavors::{OrchardVanilla, OrchardZSA}, + orchard_flavors::{OrchardFlavor, OrchardVanilla, OrchardZSA}, value::NoteValue, Anchor, Bundle, }; use rand::rngs::OsRng; -fn criterion_benchmark(c: &mut Criterion) { +fn criterion_benchmark(c: &mut Criterion) { let rng = OsRng; let sk = SpendingKey::from_bytes([7; 32]).unwrap(); diff --git a/benches/note_decryption.rs b/benches/note_decryption.rs index 12bec6d7c..9eddc6585 100644 --- a/benches/note_decryption.rs +++ b/benches/note_decryption.rs @@ -1,12 +1,11 @@ use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput}; use orchard::{ builder::{Builder, BundleType}, - bundle::OrchardHash, - circuit::{OrchardCircuit, ProvingKey}, + circuit::ProvingKey, keys::{FullViewingKey, PreparedIncomingViewingKey, Scope, SpendingKey}, note::AssetBase, - note_encryption::{CompactAction, OrchardDomain, OrchardDomainBase}, - orchard_flavors::{OrchardVanilla, OrchardZSA}, + note_encryption::{CompactAction, OrchardDomain}, + orchard_flavors::{OrchardFlavor, OrchardVanilla, OrchardZSA}, value::NoteValue, Anchor, Bundle, }; @@ -16,7 +15,7 @@ use zcash_note_encryption_zsa::{batch, try_compact_note_decryption, try_note_dec #[cfg(unix)] use pprof::criterion::{Output, PProfProfiler}; -fn bench_note_decryption(c: &mut Criterion) { +fn bench_note_decryption(c: &mut Criterion) { let rng = OsRng; let pk = ProvingKey::build::(); @@ -80,7 +79,7 @@ fn bench_note_decryption(c: &mu }; let action = bundle.actions().first(); - let domain = OrchardDomainBase::for_action(action); + let domain = OrchardDomain::for_action(action); let compact = { let mut group = c.benchmark_group("note-decryption"); @@ -121,12 +120,12 @@ fn bench_note_decryption(c: &mu let ivks = 2; let valid_ivks = vec![valid_ivk; ivks]; let actions: Vec<_> = (0..100) - .map(|_| (OrchardDomainBase::for_action(action), action.clone())) + .map(|_| (OrchardDomain::for_action(action), action.clone())) .collect(); let compact: Vec<_> = (0..100) .map(|_| { ( - OrchardDomainBase::for_action(action), + OrchardDomain::for_action(action), CompactAction::from(action), ) }) diff --git a/src/action.rs b/src/action.rs index 67ac6d841..8faadbe50 100644 --- a/src/action.rs +++ b/src/action.rs @@ -2,7 +2,7 @@ use memuse::DynamicUsage; use crate::{ note::{ExtractedNoteCommitment, Nullifier, Rho, TransmittedNoteCiphertext}, - note_encryption::OrchardDomain, + note_encryption::OrchardNoteEnc, primitives::redpallas::{self, SpendAuth}, 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. @@ -27,7 +27,7 @@ pub struct Action { authorization: A, } -impl Action { +impl Action { /// Constructs an `Action` from its constituent parts. pub fn from_parts( nf: Nullifier, @@ -107,7 +107,7 @@ impl Action { } } -impl DynamicUsage for Action, D> { +impl DynamicUsage for Action, D> { #[inline(always)] fn dynamic_usage(&self) -> usize { 0 @@ -135,7 +135,7 @@ pub(crate) mod testing { asset_base::testing::arb_asset_base, commitment::ExtractedNoteCommitment, nullifier::testing::arb_nullifier, testing::arb_note, TransmittedNoteCiphertext, }, - note_encryption::{OrchardDomain, OrchardDomainBase}, + note_encryption::{OrchardDomain, OrchardNoteEnc}, primitives::redpallas::{ self, testing::{arb_spendauth_signing_key, arb_spendauth_verification_key}, @@ -148,13 +148,13 @@ pub(crate) mod testing { /// `ActionArb` adapts `arb_...` functions for both Vanilla and ZSA Orchard protocol variations /// in property-based testing, addressing proptest crate limitations. #[derive(Debug)] - pub struct ActionArb { + pub struct ActionArb { phantom: std::marker::PhantomData, } - impl ActionArb { + impl ActionArb { fn encrypt_note( - encryptor: NoteEncryption>, + encryptor: NoteEncryption>, cmx: &ExtractedNoteCommitment, cv_net: &ValueCommitment, rng: &mut R, @@ -184,7 +184,7 @@ pub(crate) mod testing { ); let mut rng = StdRng::from_seed(rng_seed); - let encryptor = NoteEncryption::>::new(None, note, memo.try_into().unwrap()); + let encryptor = NoteEncryption::>::new(None, note, memo.try_into().unwrap()); let encrypted_note = Self::encrypt_note(encryptor, &cmx, &cv_net, &mut rng); Action { @@ -218,7 +218,7 @@ pub(crate) mod testing { let mut rng = StdRng::from_seed(rng_seed); - let encryptor = NoteEncryption::>::new(None, note, memo.try_into().unwrap()); + let encryptor = NoteEncryption::>::new(None, note, memo.try_into().unwrap()); let encrypted_note = Self::encrypt_note(encryptor, &cmx, &cv_net, &mut rng); Action { diff --git a/src/builder.rs b/src/builder.rs index ced03dd2a..4f03842b8 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -23,7 +23,7 @@ use crate::{ SpendingKey, }, note::{AssetBase, Note, Rho, TransmittedNoteCiphertext}, - note_encryption::{OrchardDomain, OrchardDomainBase}, + note_encryption::{OrchardDomain, OrchardNoteEnc}, primitives::redpallas::{self, Binding, SpendAuth}, tree::{Anchor, MerklePath}, value::{self, NoteValue, OverflowError, ValueCommitTrapdoor, ValueCommitment, ValueSum}, @@ -387,7 +387,7 @@ impl ActionInfo { /// # Panics /// /// Panics if the asset types of the spent and output notes do not match. - fn build( + fn build( self, mut rng: impl RngCore, ) -> (Action, Circuit) { @@ -418,7 +418,7 @@ impl ActionInfo { let cmx = cm_new.into(); let encryptor = - NoteEncryption::>::new(self.output.ovk, note, self.output.memo); + NoteEncryption::>::new(self.output.ovk, note, self.output.memo); let encrypted_note = TransmittedNoteCiphertext { epk_bytes: encryptor.epk().to_bytes().0, @@ -635,7 +635,7 @@ impl Builder { /// [`Bundle::create_proof`] and [`Bundle::apply_signatures`] respectively. // FIXME: Consider factoring parts of the return type into `type` definitions #[allow(clippy::type_complexity)] - pub fn build, D: OrchardDomain + OrchardCircuit + OrchardHash>( + pub fn build, D: OrchardNoteEnc + OrchardCircuit + OrchardHash>( self, rng: impl RngCore, ) -> Result, BundleMetadata)>, BuildError> { @@ -716,7 +716,7 @@ fn pad_spend(spend: Option<&SpendInfo>, asset: AssetBase, mut rng: impl RngCore) /// The returned bundle will have no proof or signatures; these can be applied with /// [`Bundle::create_proof`] and [`Bundle::apply_signatures`] respectively. #[allow(clippy::type_complexity)] -pub fn bundle, D: OrchardDomain + OrchardCircuit + OrchardHash>( +pub fn bundle, D: OrchardNoteEnc + OrchardCircuit + OrchardHash>( mut rng: impl RngCore, anchor: Anchor, bundle_type: BundleType, @@ -907,11 +907,11 @@ impl Authorization for InProgress /// /// This struct contains the private data needed to create a [`Proof`] for a [`Bundle`]. #[derive(Clone, Debug)] -pub struct Unproven { - circuits: Vec>, +pub struct Unproven { + circuits: Vec>, } -impl InProgress, S> { +impl InProgress, S> { /// Creates the proof for this bundle. pub fn create_proof( &self, @@ -923,7 +923,7 @@ impl InProgress, S> { } } -impl +impl Bundle, S>, V, D> { /// Creates the proof for this bundle. @@ -1014,7 +1014,7 @@ impl MaybeSigned { } } -impl Bundle, V, D> { +impl Bundle, V, D> { /// Loads the sighash into this bundle, preparing it for signing. /// /// This API ensures that all signatures are created over the same sighash. @@ -1043,7 +1043,7 @@ impl Bundle, V, } } -impl Bundle, V, D> { +impl Bundle, V, D> { /// Applies signatures to this bundle, in order to authorize it. /// /// This is a helper method that wraps [`Bundle::prepare`], [`Bundle::sign`], and @@ -1063,7 +1063,7 @@ impl Bundle, V, D> { } } -impl Bundle, V, D> { +impl Bundle, V, D> { /// Signs this bundle with the given [`SpendAuthorizingKey`]. /// /// This will apply signatures for all notes controlled by this spending key. @@ -1126,7 +1126,7 @@ impl Bundle Bundle, V, D> { +impl Bundle, V, D> { /// Finalizes this bundle, enabling it to be included in a transaction. /// /// Returns an error if any signatures are missing. @@ -1195,7 +1195,7 @@ pub mod testing { circuit::{OrchardCircuit, ProvingKey}, keys::{testing::arb_spending_key, FullViewingKey, SpendAuthorizingKey, SpendingKey}, note::testing::arb_note, - note_encryption::OrchardDomain, + note_encryption::OrchardNoteEnc, tree::{Anchor, MerkleHashOrchard, MerklePath}, value::{testing::arb_positive_note_value, NoteValue, MAX_NOTE_VALUE}, Address, Note, @@ -1224,7 +1224,7 @@ pub mod testing { /// Create a bundle from the set of arbitrary bundle inputs. fn into_bundle< V: TryFrom + Copy + Into, - D: OrchardDomain + OrchardCircuit + OrchardHash, + D: OrchardNoteEnc + OrchardCircuit + OrchardHash, >( mut self, ) -> Bundle { @@ -1262,11 +1262,11 @@ 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 { + pub struct BuilderArb { phantom: std::marker::PhantomData, } - impl BuilderArb { + impl BuilderArb { prop_compose! { /// Produce a random valid Orchard bundle. fn arb_bundle_inputs(sk: SpendingKey) diff --git a/src/bundle.rs b/src/bundle.rs index 4cffc19b7..c001934e9 100644 --- a/src/bundle.rs +++ b/src/bundle.rs @@ -20,15 +20,15 @@ use crate::{ circuit::{Instance, Proof, VerifyingKey}, keys::{IncomingViewingKey, OutgoingViewingKey, PreparedIncomingViewingKey}, note::{AssetBase, Note}, - note_encryption::{OrchardDomain, OrchardDomainBase}, + note_encryption::{OrchardDomain, OrchardNoteEnc}, primitives::redpallas::{self, Binding, SpendAuth}, tree::Anchor, value::{ValueCommitTrapdoor, ValueCommitment, ValueSum}, }; -pub use commitments::OrchardHash; +pub(crate) use commitments::OrchardHash; -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 { @@ -186,7 +186,7 @@ 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>, /// Orchard-specific transaction-level flags for this bundle. @@ -204,11 +204,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: OrchardDomain>(&'a NonEmpty>); - impl<'a, A: fmt::Debug, D: OrchardDomain> fmt::Debug for Actions<'a, A, D> { + struct Actions<'a, A, D: OrchardNoteEnc>(&'a NonEmpty>); + impl<'a, A: fmt::Debug, D: OrchardNoteEnc> fmt::Debug for Actions<'a, A, D> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self.0.iter()).finish() } @@ -224,7 +224,7 @@ impl fmt::Debug for Bundle Bundle { +impl Bundle { /// Constructs a `Bundle` from its constituent parts. pub fn from_parts( actions: NonEmpty>, @@ -365,7 +365,7 @@ impl Bundle { .iter() .enumerate() .filter_map(|(idx, action)| { - let domain = OrchardDomainBase::for_action(action); + let domain = OrchardDomain::for_action(action); prepared_keys.iter().find_map(|(ivk, prepared_ivk)| { try_note_decryption(&domain, prepared_ivk, action) .map(|(n, a, m)| (idx, (*ivk).clone(), n, a, m)) @@ -384,7 +384,7 @@ impl Bundle { ) -> Option<(Note, Address, [u8; 512])> { let prepared_ivk = PreparedIncomingViewingKey::new(key); self.actions.get(action_idx).and_then(move |action| { - let domain = OrchardDomainBase::for_action(action); + let domain = OrchardDomain::for_action(action); try_note_decryption(&domain, &prepared_ivk, action) }) } @@ -401,7 +401,7 @@ impl Bundle { .iter() .enumerate() .filter_map(|(idx, action)| { - let domain = OrchardDomainBase::for_action(action); + let domain = OrchardDomain::for_action(action); keys.iter().find_map(move |key| { try_output_recovery_with_ovk( &domain, @@ -425,7 +425,7 @@ impl Bundle { key: &OutgoingViewingKey, ) -> Option<(Note, Address, [u8; 512])> { self.actions.get(action_idx).and_then(move |action| { - let domain = OrchardDomainBase::for_action(action); + let domain = OrchardDomain::for_action(action); try_output_recovery_with_ovk( &domain, key, @@ -437,7 +437,7 @@ impl Bundle { } } -pub(crate) fn derive_bvk<'a, A: 'a, V: Clone + Into, D: 'a + OrchardDomain + OrchardHash>( +pub(crate) fn derive_bvk<'a, A: 'a, V: Clone + Into, D: 'a + OrchardNoteEnc + OrchardHash>( actions: impl IntoIterator>, value_balance: V, burn: impl Iterator, @@ -464,7 +464,7 @@ pub(crate) fn derive_bvk<'a, A: 'a, V: Clone + Into, D: 'a + OrchardDomain .into_bvk() } -impl, D: OrchardDomain + OrchardHash> Bundle { +impl, D: OrchardNoteEnc + OrchardHash> Bundle { /// Computes a commitment to the effects of this bundle, suitable for inclusion within /// a transaction ID. pub fn commitment(&self) -> BundleCommitment { @@ -511,7 +511,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. @@ -527,7 +527,7 @@ impl Bundle { } } -impl DynamicUsage for Bundle { +impl DynamicUsage for Bundle { fn dynamic_usage(&self) -> usize { self.actions.dynamic_usage() + self.value_balance.dynamic_usage() @@ -595,7 +595,7 @@ pub mod testing { pub use crate::action::testing::ActionArb; use crate::note::asset_base::testing::arb_zsa_asset_base; use crate::note::AssetBase; - use crate::note_encryption::OrchardDomain; + use crate::note_encryption::OrchardNoteEnc; use crate::value::testing::arb_value_sum; /// Marker for an unauthorized bundle with no proofs or signatures. @@ -609,11 +609,11 @@ 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 { + 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, diff --git a/src/bundle/batch.rs b/src/bundle/batch.rs index 253e08b62..070e7a8aa 100644 --- a/src/bundle/batch.rs +++ b/src/bundle/batch.rs @@ -8,7 +8,7 @@ use super::{Authorized, Bundle}; use crate::{ bundle::OrchardHash, circuit::VerifyingKey, - note_encryption::OrchardDomain, + note_encryption::OrchardNoteEnc, primitives::redpallas::{self, Binding, SpendAuth}, }; @@ -38,7 +38,7 @@ impl BatchValidator { } /// Adds the proof and RedPallas signatures from the given bundle to the validator. - pub fn add_bundle, D: OrchardDomain + OrchardHash>( + pub fn add_bundle, D: OrchardNoteEnc + OrchardHash>( &mut self, bundle: &Bundle, sighash: [u8; 32], diff --git a/src/bundle/commitments.rs b/src/bundle/commitments.rs index 3190584a6..039dd1a3e 100644 --- a/src/bundle/commitments.rs +++ b/src/bundle/commitments.rs @@ -1,5 +1,7 @@ //! Utility functions for computing bundle commitments +// FIXME: rename this to hash.rs? + use blake2b_simd::{Hash as Blake2bHash, Params, State}; use zcash_note_encryption_zsa::MEMO_SIZE; @@ -8,7 +10,7 @@ use crate::{ bundle::{Authorization, Authorized, Bundle}, issuance::{IssueAuth, IssueBundle, Signed}, note::AssetBase, - note_encryption::OrchardDomain, + note_encryption::OrchardNoteEnc, orchard_flavors::{OrchardVanilla, OrchardZSA}, }; @@ -80,7 +82,7 @@ impl OrchardHash for OrchardZSA { pub(crate) fn hash_bundle_txid_data< A: Authorization, V: Copy + Into, - D: OrchardDomain + OrchardHash, + D: OrchardNoteEnc + OrchardHash, >( bundle: &Bundle, ) -> Blake2bHash { @@ -134,7 +136,7 @@ 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( +pub(crate) fn hash_bundle_auth_data( bundle: &Bundle, ) -> Blake2bHash { let mut h = hasher(ZCASH_ORCHARD_SIGS_HASH_PERSONALIZATION); diff --git a/src/circuit.rs b/src/circuit.rs index d2a77e11d..0af6f8c4f 100644 --- a/src/circuit.rs +++ b/src/circuit.rs @@ -73,8 +73,8 @@ pub trait OrchardCircuit: Sized + Default { ) -> Result<(), plonk::Error>; } -impl plonk::Circuit for Circuit { - type Config = D::Config; +impl plonk::Circuit for Circuit { + type Config = C::Config; type FloorPlanner = floor_planner::V1; fn without_witnesses(&self) -> Self { @@ -82,7 +82,7 @@ impl plonk::Circuit for Circuit { } fn configure(meta: &mut plonk::ConstraintSystem) -> Self::Config { - D::configure(meta) + C::configure(meta) } fn synthesize( @@ -90,7 +90,7 @@ impl plonk::Circuit for Circuit { config: Self::Config, layouter: impl Layouter, ) -> Result<(), plonk::Error> { - D::synthesize(self, config, layouter) + C::synthesize(self, config, layouter) } } @@ -203,9 +203,9 @@ pub struct VerifyingKey { impl VerifyingKey { /// Builds the verifying key. - pub fn build() -> Self { + pub fn build() -> Self { let params = halo2_proofs::poly::commitment::Params::new(K); - let circuit: Circuit = Default::default(); + let circuit: Circuit = Default::default(); let vk = plonk::keygen_vk(¶ms, &circuit).unwrap(); @@ -222,9 +222,9 @@ pub struct ProvingKey { impl ProvingKey { /// Builds the proving key. - pub fn build() -> Self { + pub fn build() -> Self { let params = halo2_proofs::poly::commitment::Params::new(K); - let circuit: Circuit = Default::default(); + let circuit: Circuit = Default::default(); let vk = plonk::keygen_vk(¶ms, &circuit).unwrap(); let pk = plonk::keygen_pk(¶ms, vk, &circuit).unwrap(); @@ -338,9 +338,9 @@ impl DynamicUsage for Proof { impl Proof { /// Creates a proof for the given circuits and instances. - pub fn create( + pub fn create( pk: &ProvingKey, - circuits: &[Circuit], + circuits: &[Circuit], instances: &[Instance], mut rng: impl RngCore, ) -> Result { diff --git a/src/note.rs b/src/note.rs index 4019cd21b..52971309b 100644 --- a/src/note.rs +++ b/src/note.rs @@ -10,7 +10,7 @@ use subtle::{Choice, ConditionallySelectable, CtOption}; use crate::{ keys::{EphemeralSecretKey, FullViewingKey, Scope, SpendingKey}, - note_encryption::OrchardDomain, + note_encryption::OrchardNoteEnc, spec::{to_base, to_scalar, NonZeroPallasScalar, PrfExpand}, value::NoteValue, Address, @@ -349,7 +349,7 @@ impl 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 @@ -359,7 +359,7 @@ pub struct TransmittedNoteCiphertext { 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/note_encryption.rs b/src/note_encryption.rs index 14f30b628..096b7e8e1 100644 --- a/src/note_encryption.rs +++ b/src/note_encryption.rs @@ -11,7 +11,6 @@ mod orchard_domain; mod orchard_domain_vanilla; mod orchard_domain_zsa; -pub use { - compact_action::CompactAction, - orchard_domain::{OrchardDomain, OrchardDomainBase}, -}; +pub(crate) use orchard_domain::OrchardNoteEnc; + +pub use {compact_action::CompactAction, orchard_domain::OrchardDomain}; diff --git a/src/note_encryption/compact_action.rs b/src/note_encryption/compact_action.rs index e93f0eba8..4c2dfc3ad 100644 --- a/src/note_encryption/compact_action.rs +++ b/src/note_encryption/compact_action.rs @@ -11,9 +11,9 @@ use crate::{ note::{ExtractedNoteCommitment, Nullifier, Rho}, }; -use super::orchard_domain::{OrchardDomain, OrchardDomainBase}; +use super::orchard_domain::{OrchardNoteEnc, OrchardDomain}; -impl ShieldedOutput> for Action { +impl ShieldedOutput> for Action { fn ephemeral_key(&self) -> EphemeralKeyBytes { EphemeralKeyBytes(self.encrypted_note().epk_bytes) } @@ -32,22 +32,22 @@ impl ShieldedOutput> for Action } /// A compact Action for light clients. -pub struct CompactAction { +pub struct CompactAction { nullifier: Nullifier, cmx: ExtractedNoteCommitment, ephemeral_key: EphemeralKeyBytes, enc_ciphertext: D::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 { CompactAction { @@ -59,7 +59,7 @@ where } } -impl ShieldedOutput> for CompactAction { +impl ShieldedOutput> for CompactAction { fn ephemeral_key(&self) -> EphemeralKeyBytes { EphemeralKeyBytes(self.ephemeral_key.0) } @@ -77,7 +77,7 @@ impl ShieldedOutput> for CompactAction } } -impl CompactAction { +impl CompactAction { /// Create a CompactAction from its constituent parts pub fn from_parts( nullifier: Nullifier, @@ -123,12 +123,12 @@ pub mod testing { value::NoteValue, }; - use super::{CompactAction, OrchardDomain, OrchardDomainBase}; + use super::{CompactAction, OrchardNoteEnc, OrchardDomain}; /// 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, @@ -147,9 +147,9 @@ pub mod testing { } }; let note = Note::from_parts(recipient, value, AssetBase::native(), rho, rseed).unwrap(); - let encryptor = NoteEncryption::>::new(ovk, note, [0u8; 512]); + let encryptor = NoteEncryption::>::new(ovk, note, [0u8; 512]); let cmx = ExtractedNoteCommitment::from(note.commitment()); - let ephemeral_key = OrchardDomainBase::::epk_bytes(encryptor.epk()); + let ephemeral_key = OrchardDomain::::epk_bytes(encryptor.epk()); let enc_ciphertext = encryptor.encrypt_note_plaintext(); ( diff --git a/src/note_encryption/domain.rs b/src/note_encryption/domain.rs index df4a8f0b9..85205d37e 100644 --- a/src/note_encryption/domain.rs +++ b/src/note_encryption/domain.rs @@ -21,7 +21,7 @@ use crate::{ value::{NoteValue, ValueCommitment}, }; -use super::orchard_domain::{OrchardDomain, OrchardDomainBase}; +use super::orchard_domain::{OrchardDomain, OrchardNoteEnc}; // FIXME: fix it to be "git mv" from the origina tone_encryption.rs and reorder elements // to reduce git diff @@ -161,7 +161,7 @@ pub(super) fn build_base_note_plaintext_bytes( np } -impl Domain for OrchardDomainBase { +impl Domain for OrchardDomain { type EphemeralSecretKey = EphemeralSecretKey; type EphemeralPublicKey = EphemeralPublicKey; type PreparedEphemeralPublicKey = PreparedEphemeralPublicKey; @@ -293,7 +293,7 @@ impl Domain for OrchardDomainBase { } } -impl BatchDomain for OrchardDomainBase { +impl BatchDomain for OrchardDomain { fn batch_kdf<'a>( items: impl Iterator, &'a EphemeralKeyBytes)>, ) -> Vec> { diff --git a/src/note_encryption/orchard_domain.rs b/src/note_encryption/orchard_domain.rs index f2334736e..654b90257 100644 --- a/src/note_encryption/orchard_domain.rs +++ b/src/note_encryption/orchard_domain.rs @@ -53,7 +53,7 @@ pub trait NoteBytes: impl NoteBytes for NoteBytesData {} /// Represents the Orchard protocol domain specifics required for note encryption and decryption. -pub trait OrchardDomain: fmt::Debug + Clone { +pub trait OrchardNoteEnc: fmt::Debug + Clone { /// The size of a compact note, specific to the Orchard protocol. const COMPACT_NOTE_SIZE: usize; @@ -78,13 +78,13 @@ pub trait OrchardDomain: fmt::Debug + Clone { /// Orchard-specific note encryption logic. #[derive(Debug, Clone)] -pub struct OrchardDomainBase { +pub struct OrchardDomain { /// A parameter needed to generate the nullifier. pub rho: Rho, phantom: std::marker::PhantomData, } -impl OrchardDomainBase { +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 { diff --git a/src/note_encryption/orchard_domain_vanilla.rs b/src/note_encryption/orchard_domain_vanilla.rs index 5df90af0c..569f9fb7a 100644 --- a/src/note_encryption/orchard_domain_vanilla.rs +++ b/src/note_encryption/orchard_domain_vanilla.rs @@ -6,10 +6,10 @@ use super::{ domain::{ build_base_note_plaintext_bytes, Memo, COMPACT_NOTE_SIZE_VANILLA, NOTE_VERSION_BYTE_VANILLA, }, - orchard_domain::{NoteBytesData, OrchardDomain}, + orchard_domain::{NoteBytesData, OrchardNoteEnc}, }; -impl OrchardDomain for OrchardVanilla { +impl OrchardNoteEnc for OrchardVanilla { const COMPACT_NOTE_SIZE: usize = COMPACT_NOTE_SIZE_VANILLA; type NotePlaintextBytes = NoteBytesData<{ Self::NOTE_PLAINTEXT_SIZE }>; @@ -59,10 +59,10 @@ mod tests { parse_note_plaintext_without_memo, parse_note_version, prf_ock_orchard, NOTE_VERSION_BYTE_VANILLA, }, - orchard_domain::{NoteBytesData, OrchardDomainBase}, + orchard_domain::{NoteBytesData, OrchardDomain}, }; - type OrchardDomainVanilla = OrchardDomainBase; + type OrchardDomainVanilla = OrchardDomain; /// Implementation of in-band secret distribution for Orchard bundles. pub type OrchardNoteEncryptionVanilla = @@ -169,7 +169,7 @@ mod tests { // (Tested first because it only requires immutable references.) // - let domain = OrchardDomainBase::for_rho(rho); + let domain = OrchardDomain::for_rho(rho); match try_note_decryption(&domain, &ivk, &action) { Some((decrypted_note, decrypted_to, decrypted_memo)) => { diff --git a/src/note_encryption/orchard_domain_zsa.rs b/src/note_encryption/orchard_domain_zsa.rs index 9edb44b68..09b79bd65 100644 --- a/src/note_encryption/orchard_domain_zsa.rs +++ b/src/note_encryption/orchard_domain_zsa.rs @@ -7,10 +7,10 @@ use super::{ build_base_note_plaintext_bytes, Memo, COMPACT_NOTE_SIZE_VANILLA, COMPACT_NOTE_SIZE_ZSA, NOTE_VERSION_BYTE_ZSA, }, - orchard_domain::{NoteBytesData, OrchardDomain}, + orchard_domain::{NoteBytesData, OrchardNoteEnc}, }; -impl OrchardDomain for OrchardZSA { +impl OrchardNoteEnc for OrchardZSA { const COMPACT_NOTE_SIZE: usize = COMPACT_NOTE_SIZE_ZSA; type NotePlaintextBytes = NoteBytesData<{ Self::NOTE_PLAINTEXT_SIZE }>; @@ -62,10 +62,10 @@ mod tests { parse_note_plaintext_without_memo, parse_note_version, prf_ock_orchard, NOTE_VERSION_BYTE_ZSA, }, - orchard_domain::{NoteBytesData, OrchardDomainBase}, + orchard_domain::{NoteBytesData, OrchardDomain}, }; - type OrchardDomainZSA = OrchardDomainBase; + type OrchardDomainZSA = OrchardDomain; /// Implementation of in-band secret distribution for Orchard bundles. pub type OrchardNoteEncryptionZSA = zcash_note_encryption_zsa::NoteEncryption; @@ -171,7 +171,7 @@ mod tests { // (Tested first because it only requires immutable references.) // - let domain = OrchardDomainBase::for_rho(rho); + let domain = OrchardDomain::for_rho(rho); match try_note_decryption(&domain, &ivk, &action) { Some((decrypted_note, decrypted_to, decrypted_memo)) => { diff --git a/src/orchard_flavors.rs b/src/orchard_flavors.rs index 80c0c30de..ca2424809 100644 --- a/src/orchard_flavors.rs +++ b/src/orchard_flavors.rs @@ -1,5 +1,7 @@ //! Defines types and traits for the variations ("flavors") of the Orchard protocol (Vanilla and ZSA). +use crate::{bundle::OrchardHash, circuit::OrchardCircuit, note_encryption::OrchardNoteEnc}; + /// Represents the standard ("Vanilla") variation ("flavor") of the Orchard protocol. #[derive(Debug, Clone, Default)] pub struct OrchardVanilla; @@ -7,3 +9,10 @@ pub struct OrchardVanilla; /// Represents a ZSA variation ("flavor") of the Orchard protocol. #[derive(Debug, Clone, Default)] pub struct OrchardZSA; + +/// A trait binding the common functionality between different Orchard protocol variations +/// ("flavors"). +pub trait OrchardFlavor: OrchardNoteEnc + OrchardCircuit + OrchardHash {} + +impl OrchardFlavor for OrchardVanilla {} +impl OrchardFlavor for OrchardZSA {} diff --git a/tests/builder.rs b/tests/builder.rs index 5dcafc679..31c28fd92 100644 --- a/tests/builder.rs +++ b/tests/builder.rs @@ -2,12 +2,12 @@ use bridgetree::BridgeTree; use incrementalmerkletree::Hashable; use orchard::{ builder::{Builder, BundleType}, - bundle::{Authorized, Flags, OrchardHash}, - circuit::{OrchardCircuit, ProvingKey, VerifyingKey}, + bundle::{Authorized, Flags}, + circuit::{ProvingKey, VerifyingKey}, keys::{FullViewingKey, PreparedIncomingViewingKey, Scope, SpendAuthorizingKey, SpendingKey}, note::{AssetBase, ExtractedNoteCommitment}, - note_encryption::{OrchardDomain, OrchardDomainBase}, - orchard_flavors::{OrchardVanilla, OrchardZSA}, + note_encryption::OrchardDomain, + orchard_flavors::{OrchardFlavor, OrchardVanilla, OrchardZSA}, tree::{MerkleHashOrchard, MerklePath}, value::NoteValue, Anchor, Bundle, Note, @@ -15,7 +15,7 @@ use orchard::{ use rand::rngs::OsRng; use zcash_note_encryption_zsa::try_note_decryption; -pub fn verify_bundle( +pub fn verify_bundle( bundle: &Bundle, vk: &VerifyingKey, verify_proof: bool, @@ -52,7 +52,7 @@ pub fn build_merkle_path(note: &Note) -> (MerklePath, Anchor) { (merkle_path, anchor) } -fn bundle_chain() { +fn bundle_chain() { let mut rng = OsRng; let pk = ProvingKey::build::(); let vk = VerifyingKey::build::(); @@ -107,7 +107,7 @@ fn bundle_chain() { .actions() .iter() .find_map(|action| { - let domain = OrchardDomainBase::for_action(action); + let domain = OrchardDomain::for_action(action); try_note_decryption(&domain, &ivk, action) }) .unwrap(); diff --git a/tests/zsa.rs b/tests/zsa.rs index ef9bb8881..ebca22785 100644 --- a/tests/zsa.rs +++ b/tests/zsa.rs @@ -13,7 +13,7 @@ use orchard::{ builder::{Builder, BundleType}, circuit::{ProvingKey, VerifyingKey}, keys::{FullViewingKey, PreparedIncomingViewingKey, Scope, SpendAuthorizingKey, SpendingKey}, - note_encryption::OrchardDomainBase, + note_encryption::OrchardDomain, orchard_flavors::OrchardZSA, value::NoteValue, Address, Anchor, Bundle, Note, @@ -207,7 +207,7 @@ fn create_native_note(keys: &Keychain) -> Note { .actions() .iter() .find_map(|action| { - let domain = OrchardDomainBase::for_action(action); + let domain = OrchardDomain::for_action(action); try_note_decryption(&domain, &PreparedIncomingViewingKey::new(&ivk), action) }) .unwrap();