Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion benches/note_decryption.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
Expand Down
34 changes: 17 additions & 17 deletions src/action.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use memuse::DynamicUsage;

use crate::{
domain::OrchardDomainCommon,
note::{ExtractedNoteCommitment, Nullifier, Rho, TransmittedNoteCiphertext},
primitives::redpallas::{self, SpendAuth},
primitives::OrchardPrimitives,
value::ValueCommitment,
};

Expand All @@ -12,28 +12,28 @@ 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<A, D: OrchardDomainCommon> {
pub struct Action<A, P: OrchardPrimitives> {
/// The nullifier of the note being spent.
nf: Nullifier,
/// The randomized verification key for the note being spent.
rk: redpallas::VerificationKey<SpendAuth>,
/// A commitment to the new note being created.
cmx: ExtractedNoteCommitment,
/// The transmitted note ciphertext.
encrypted_note: TransmittedNoteCiphertext<D>,
encrypted_note: TransmittedNoteCiphertext<P>,
/// A commitment to the net value created or consumed by this action.
cv_net: ValueCommitment,
/// The authorization for this action.
authorization: A,
}

impl<A, D: OrchardDomainCommon> Action<A, D> {
impl<A, P: OrchardPrimitives> Action<A, P> {
/// Constructs an `Action` from its constituent parts.
pub fn from_parts(
nf: Nullifier,
rk: redpallas::VerificationKey<SpendAuth>,
cmx: ExtractedNoteCommitment,
encrypted_note: TransmittedNoteCiphertext<D>,
encrypted_note: TransmittedNoteCiphertext<P>,
cv_net: ValueCommitment,
authorization: A,
) -> Self {
Expand Down Expand Up @@ -63,7 +63,7 @@ impl<A, D: OrchardDomainCommon> Action<A, D> {
}

/// Returns the encrypted note ciphertext.
pub fn encrypted_note(&self) -> &TransmittedNoteCiphertext<D> {
pub fn encrypted_note(&self) -> &TransmittedNoteCiphertext<P> {
&self.encrypted_note
}

Expand All @@ -83,7 +83,7 @@ impl<A, D: OrchardDomainCommon> Action<A, D> {
}

/// Transitions this action from one authorization state to another.
pub fn map<U>(self, step: impl FnOnce(A) -> U) -> Action<U, D> {
pub fn map<U>(self, step: impl FnOnce(A) -> U) -> Action<U, P> {
Action {
nf: self.nf,
rk: self.rk,
Expand All @@ -95,7 +95,7 @@ impl<A, D: OrchardDomainCommon> Action<A, D> {
}

/// Transitions this action from one authorization state to another.
pub fn try_map<U, E>(self, step: impl FnOnce(A) -> Result<U, E>) -> Result<Action<U, D>, E> {
pub fn try_map<U, E>(self, step: impl FnOnce(A) -> Result<U, E>) -> Result<Action<U, P>, E> {
Ok(Action {
nf: self.nf,
rk: self.rk,
Expand All @@ -107,7 +107,7 @@ impl<A, D: OrchardDomainCommon> Action<A, D> {
}
}

impl<D: OrchardDomainCommon> DynamicUsage for Action<redpallas::Signature<SpendAuth>, D> {
impl<P: OrchardPrimitives> DynamicUsage for Action<redpallas::Signature<SpendAuth>, P> {
#[inline(always)]
fn dynamic_usage(&self) -> usize {
0
Expand All @@ -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,
Expand All @@ -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},
};

Expand All @@ -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<D: OrchardDomainCommon> {
phantom: core::marker::PhantomData<D>,
pub struct ActionArb<P: OrchardPrimitives> {
phantom: core::marker::PhantomData<P>,
}

impl<D: OrchardDomainCommon> ActionArb<D> {
impl<P: OrchardPrimitives> ActionArb<P> {
fn encrypt_note<R: RngCore>(
note: Note,
memo: Vec<u8>,
cmx: &ExtractedNoteCommitment,
cv_net: &ValueCommitment,
rng: &mut R,
) -> TransmittedNoteCiphertext<D> {
) -> TransmittedNoteCiphertext<P> {
let encryptor =
NoteEncryption::<OrchardDomain<D>>::new(None, note, memo.try_into().unwrap());
NoteEncryption::<OrchardDomain<P>>::new(None, note, memo.try_into().unwrap());

TransmittedNoteCiphertext {
epk_bytes: encryptor.epk().to_bytes().0,
Expand All @@ -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,
Expand Down Expand Up @@ -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<redpallas::Signature<SpendAuth>, D> {
) -> Action<redpallas::Signature<SpendAuth>, P> {
let cmx = ExtractedNoteCommitment::from(note.commitment());
let cv_net = ValueCommitment::derive(
spend_value - output_value,
Expand Down
44 changes: 23 additions & 21 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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<D: OrchardDomainCommon>(
fn build<P: OrchardPrimitives>(
&self,
cv_net: &ValueCommitment,
nf_old: Nullifier,
mut rng: impl RngCore,
) -> (Note, ExtractedNoteCommitment, TransmittedNoteCiphertext<D>) {
) -> (Note, ExtractedNoteCommitment, TransmittedNoteCiphertext<P>) {
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::<OrchardDomain<D>>::new(self.ovk.clone(), note, self.memo);
let encryptor = NoteEncryption::<OrchardDomain<P>>::new(self.ovk.clone(), note, self.memo);

let encrypted_note = TransmittedNoteCiphertext {
epk_bytes: encryptor.epk().to_bytes().0,
Expand All @@ -437,13 +437,13 @@ impl OutputInfo {
(note, cmx, encrypted_note)
}

fn into_pczt<D: OrchardDomainCommon>(
fn into_pczt<P: OrchardPrimitives>(
self,
cv_net: &ValueCommitment,
nf_old: Nullifier,
rng: impl RngCore,
) -> crate::pczt::Output {
let (note, cmx, encrypted_note) = self.build::<D>(cv_net, nf_old, rng);
let (note, cmx, encrypted_note) = self.build::<P>(cv_net, nf_old, rng);

crate::pczt::Output {
cmx,
Expand Down Expand Up @@ -532,7 +532,7 @@ impl ActionInfo {
)
}

fn build_for_pczt<D: OrchardDomainCommon>(self, mut rng: impl RngCore) -> crate::pczt::Action {
fn build_for_pczt<P: OrchardPrimitives>(self, mut rng: impl RngCore) -> crate::pczt::Action {
assert_eq!(
self.spend.note.asset(),
self.output.asset,
Expand All @@ -544,7 +544,7 @@ impl ActionInfo {
let spend = self.spend.into_pczt(&mut rng);
let output = self
.output
.into_pczt::<D>(&cv_net, spend.nullifier, &mut rng);
.into_pczt::<P>(&cv_net, spend.nullifier, &mut rng);

crate::pczt::Action {
cv_net,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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<D: OrchardDomainCommon>(
pub fn build_for_pczt<P: OrchardPrimitives>(
self,
rng: impl RngCore,
) -> Result<(crate::pczt::Bundle, BundleMetadata), BuildError> {
Expand All @@ -789,7 +789,7 @@ impl Builder {
// Create the actions.
let actions = pre_actions
.into_iter()
.map(|a| a.build_for_pczt::<D>(&mut rng))
.map(|a| a.build_for_pczt::<P>(&mut rng))
.collect::<Vec<_>>();

Ok((
Expand Down Expand Up @@ -1267,15 +1267,15 @@ impl MaybeSigned {
}
}

impl<P: fmt::Debug, V, D: OrchardDomainCommon> Bundle<InProgress<P, Unauthorized>, V, D> {
impl<Proof: fmt::Debug, V, P: OrchardPrimitives> Bundle<InProgress<Proof, Unauthorized>, V, P> {
/// Loads the sighash into this bundle, preparing it for signing.
///
/// This API ensures that all signatures are created over the same sighash.
pub fn prepare<R: RngCore + CryptoRng>(
self,
mut rng: R,
sighash: [u8; 32],
) -> Bundle<InProgress<P, PartiallyAuthorized>, V, D> {
) -> Bundle<InProgress<Proof, PartiallyAuthorized>, V, P> {
self.map_authorization(
&mut rng,
|rng, _, SigningMetadata { dummy_ask, parts }| {
Expand All @@ -1296,7 +1296,7 @@ impl<P: fmt::Debug, V, D: OrchardDomainCommon> Bundle<InProgress<P, Unauthorized
}
}

impl<V, D: OrchardDomainCommon> Bundle<InProgress<Proof, Unauthorized>, V, D> {
impl<V, P: OrchardPrimitives> Bundle<InProgress<Proof, Unauthorized>, V, P> {
/// Applies signatures to this bundle, in order to authorize it.
///
/// This is a helper method that wraps [`Bundle::prepare`], [`Bundle::sign`], and
Expand All @@ -1306,7 +1306,7 @@ impl<V, D: OrchardDomainCommon> Bundle<InProgress<Proof, Unauthorized>, V, D> {
mut rng: R,
sighash: [u8; 32],
signing_keys: &[SpendAuthorizingKey],
) -> Result<Bundle<Authorized, V, D>, BuildError> {
) -> Result<Bundle<Authorized, V, P>, BuildError> {
signing_keys
.iter()
.fold(self.prepare(&mut rng, sighash), |partial, ask| {
Expand All @@ -1316,7 +1316,9 @@ impl<V, D: OrchardDomainCommon> Bundle<InProgress<Proof, Unauthorized>, V, D> {
}
}

impl<P: fmt::Debug, V, D: OrchardDomainCommon> Bundle<InProgress<P, PartiallyAuthorized>, V, D> {
impl<Proof: fmt::Debug, V, P: OrchardPrimitives>
Bundle<InProgress<Proof, PartiallyAuthorized>, V, P>
{
/// Signs this bundle with the given [`SpendAuthorizingKey`].
///
/// This will apply signatures for all notes controlled by this spending key.
Expand Down Expand Up @@ -1379,11 +1381,11 @@ impl<P: fmt::Debug, V, D: OrchardDomainCommon> Bundle<InProgress<P, PartiallyAut
}
}

impl<V, D: OrchardDomainCommon> Bundle<InProgress<Proof, PartiallyAuthorized>, V, D> {
impl<V, P: OrchardPrimitives> Bundle<InProgress<Proof, PartiallyAuthorized>, 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<Bundle<Authorized, V, D>, BuildError> {
pub fn finalize(self) -> Result<Bundle<Authorized, V, P>, BuildError> {
self.try_map_authorization(
&mut (),
|_, _, maybe| maybe.finalize(),
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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<D: OrchardDomainCommon> {
phantom: core::marker::PhantomData<D>,
pub struct BuilderArb<P: OrchardPrimitives> {
phantom: core::marker::PhantomData<P>,
}

impl<FL: OrchardFlavor> BuilderArb<FL> {
Expand Down
Loading
Loading