diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f172ad334..30c6f0639 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,10 +1,6 @@ name: CI checks -#on: [push, pull_request] -on: - push: - branches: [ main ] # Only runs on push to main - pull_request: # Runs on any PR to any branch +on: [push, pull_request] jobs: test: @@ -12,16 +8,11 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ ubuntu-latest, windows-latest ] - # os: [ubuntu-latest, windows-latest, macOS-latest] - + os: [ubuntu-latest, windows-latest, macOS-latest] steps: - uses: actions/checkout@v4 - name: Run tests - env: - # Disable LTO in CI to avoid very slow/hanging release test builds on macOS (rustc/LLVM). - CARGO_PROFILE_RELEASE_LTO: "off" - run: cargo test --verbose --release + run: cargo test --verbose - name: Verify working directory is clean run: git diff --exit-code @@ -120,7 +111,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Generate coverage report - run: timeout --preserve-status 300s cargo tarpaulin --engine llvm --timeout 600 --out xml --skip-clean || true + run: cargo tarpaulin --engine llvm --all-features --release --timeout 600 --out xml - name: Upload coverage to Codecov uses: codecov/codecov-action@v3.1.4 diff --git a/Cargo.toml b/Cargo.toml index 92a1b64eb..69c3510dc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ authors = [ "Kris Nuttycombe ", ] edition = "2021" -rust-version = "1.71" +rust-version = "1.70" description = "The Orchard shielded transaction protocol" license = "MIT OR Apache-2.0" repository = "https://github.com/zcash/orchard" diff --git a/README.md b/README.md index 004ba10b1..8fdcd2730 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@ -# orchard [![Crates.io](https://img.shields.io/crates/v/orchard.svg)](https://crates.io/crates/orchard) [![CI checks](https://github.com/QED-it/orchard/actions/workflows/ci.yml/badge.svg?branch=zsa1)](https://github.com/QED-it/orchard/actions/workflows/ci.yml) -# +# orchard [![Crates.io](https://img.shields.io/crates/v/orchard.svg)](https://crates.io/crates/orchard) # -Requires Rust 1.71+. +Requires Rust 1.70+. ## Documentation diff --git a/benches/circuit.rs b/benches/circuit.rs index 6e3708f94..045288dab 100644 --- a/benches/circuit.rs +++ b/benches/circuit.rs @@ -7,11 +7,11 @@ use criterion::{BenchmarkId, Criterion}; use pprof::criterion::{Output, PProfProfiler}; use orchard::{ - builder::{Builder, BundleType}, + builder::Builder, circuit::{ProvingKey, VerifyingKey}, + flavor::{OrchardVanilla, OrchardZSA}, keys::{FullViewingKey, Scope, SpendingKey}, note::AssetBase, - orchard_flavor::{OrchardVanilla, OrchardZSA}, value::NoteValue, Anchor, Bundle, }; @@ -31,7 +31,10 @@ fn criterion_benchmark(c: &mut Criterion) { let pk = ProvingKey::build::(); let create_bundle = |num_recipients| { - let mut builder = Builder::new(BundleType::DEFAULT, Anchor::from_bytes([0; 32]).unwrap()); + let mut builder = Builder::new( + FL::DEFAULT_BUNDLE_TYPE, + Anchor::from_bytes([0; 32]).unwrap(), + ); for _ in 0..num_recipients { builder .add_output( diff --git a/benches/note_decryption.rs b/benches/note_decryption.rs index f6247afca..0bcaa9aeb 100644 --- a/benches/note_decryption.rs +++ b/benches/note_decryption.rs @@ -1,10 +1,10 @@ use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput}; use orchard::{ - builder::{Builder, BundleType}, + builder::Builder, circuit::ProvingKey, + flavor::{OrchardVanilla, OrchardZSA}, keys::{FullViewingKey, PreparedIncomingViewingKey, Scope, SpendingKey}, note::AssetBase, - orchard_flavor::{OrchardVanilla, OrchardZSA}, primitives::{CompactAction, OrchardDomain}, value::NoteValue, Anchor, Bundle, @@ -50,7 +50,10 @@ fn bench_note_decryption(c: &mut Criterion) { .collect(); let bundle = { - let mut builder = Builder::new(BundleType::DEFAULT, Anchor::from_bytes([0; 32]).unwrap()); + let mut builder = Builder::new( + FL::DEFAULT_BUNDLE_TYPE, + Anchor::from_bytes([0; 32]).unwrap(), + ); // The builder pads to two actions, and shuffles their order. Add two recipients // so the first action is always decryptable. builder diff --git a/benches/utils.rs b/benches/utils.rs index d5f639278..caa4f87be 100644 --- a/benches/utils.rs +++ b/benches/utils.rs @@ -1,8 +1,13 @@ use criterion::{measurement::Measurement, BenchmarkGroup, Criterion}; -use orchard::orchard_flavor::{OrchardFlavor, OrchardVanilla, OrchardZSA}; +use orchard::{ + builder::BundleType, + flavor::{OrchardFlavor, OrchardVanilla, OrchardZSA}, +}; pub(crate) trait OrchardFlavorBench: OrchardFlavor { + const DEFAULT_BUNDLE_TYPE: BundleType; + fn benchmark_group<'a, M: Measurement>( c: &'a mut Criterion, group_name: &str, @@ -10,6 +15,8 @@ pub(crate) trait OrchardFlavorBench: OrchardFlavor { } impl OrchardFlavorBench for OrchardVanilla { + const DEFAULT_BUNDLE_TYPE: BundleType = BundleType::DEFAULT; + fn benchmark_group<'a, M: Measurement>( c: &'a mut Criterion, group_name: &str, @@ -19,6 +26,8 @@ impl OrchardFlavorBench for OrchardVanilla { } impl OrchardFlavorBench for OrchardZSA { + const DEFAULT_BUNDLE_TYPE: BundleType = BundleType::DEFAULT_ZSA; + fn benchmark_group<'a, M: Measurement>( c: &'a mut Criterion, group_name: &str, diff --git a/book/src/design/actions.md b/book/src/design/actions.md index 73c81a1af..cec9684fa 100644 --- a/book/src/design/actions.md +++ b/book/src/design/actions.md @@ -21,7 +21,6 @@ balance the transaction without doubling its size. ## Dummy notes for Orchard For Orchard, a transaction is a bundle of actions. Each action is composed of one spend and one output. -This means we have the same amount of "spends" and "outputs" in one transaction. If we would like to create a transaction with a different number of spends and outputs, we need to add "dummy" spends or outputs to balance their count. A dummy spend or output is a note with a value of zero and a random recipient address. @@ -53,4 +52,3 @@ Each Orchard action has a memo field for its corresponding output, as with Sprou Sapling. We did at one point consider having a single Orchard memo field per transaction, and/or having a mechanism for enabling multiple recipients to decrypt the same memo, but these were decided against in order to keep the overall design simpler. - diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 6ea608282..cad9254a9 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] -channel = "1.71.0" +channel = "1.70.0" components = [ "clippy", "rustfmt" ] diff --git a/src/action.rs b/src/action.rs index db23490d3..1b56afb95 100644 --- a/src/action.rs +++ b/src/action.rs @@ -2,9 +2,9 @@ use memuse::DynamicUsage; use crate::{ note::{ExtractedNoteCommitment, Nullifier, Rho, TransmittedNoteCiphertext}, - orchard_sighash_versioning::VerSpendAuthSig, primitives::redpallas::{self, SpendAuth}, primitives::OrchardPrimitives, + sighash_versioning::VerSpendAuthSig, value::ValueCommitment, }; @@ -136,12 +136,12 @@ pub(crate) mod testing { commitment::ExtractedNoteCommitment, nullifier::testing::arb_nullifier, testing::arb_note, AssetBase, Note, TransmittedNoteCiphertext, }, - orchard_sighash_versioning::VerSpendAuthSig, primitives::redpallas::{ self, testing::{arb_spendauth_signing_key, arb_spendauth_verification_key}, }, primitives::{OrchardDomain, OrchardPrimitives}, + sighash_versioning::VerSpendAuthSig, value::{NoteValue, ValueCommitTrapdoor, ValueCommitment}, }; diff --git a/src/builder.rs b/src/builder.rs index 6f2ca22b2..126a2b96c 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -15,15 +15,15 @@ use crate::{ address::Address, builder::BuildError::{BurnNative, BurnZero}, bundle::{Authorization, Authorized, Bundle, Flags}, + flavor::OrchardVanilla, keys::{ FullViewingKey, OutgoingViewingKey, Scope, SpendAuthorizingKey, SpendValidatingKey, SpendingKey, }, note::{AssetBase, ExtractedNoteCommitment, Note, Nullifier, Rho, TransmittedNoteCiphertext}, - orchard_flavor::OrchardVanilla, - orchard_sighash_versioning::{VerBindingSig, VerSpendAuthSig}, primitives::redpallas::{self, Binding, SpendAuth}, primitives::{OrchardDomain, OrchardPrimitives}, + sighash_versioning::{VerBindingSig, VerSpendAuthSig}, tree::{Anchor, MerklePath}, value::{self, NoteValue, OverflowError, ValueCommitTrapdoor, ValueCommitment, ValueSum}, Proof, @@ -35,7 +35,7 @@ use { action::Action, bundle::derive_bvk, circuit::{Circuit, Instance, OrchardCircuit, ProvingKey, Witnesses}, - orchard_flavor::OrchardFlavor, + flavor::OrchardFlavor, }, nonempty::NonEmpty, }; @@ -517,7 +517,7 @@ impl ActionInfo { mut rng: impl RngCore, ) -> (Action, Witnesses) { let v_net = self.value_sum(); - let cv_net = ValueCommitment::derive(v_net, self.rcv, self.output.asset); + let cv_net = ValueCommitment::derive(v_net, self.rcv.clone(), self.output.asset); let (nf_old, ak, alpha, rk) = self.spend.build(&mut rng); let (note, cmx, encrypted_note) = self.output.build(&cv_net, nf_old, &mut rng); @@ -540,7 +540,7 @@ impl ActionInfo { fn build_for_pczt(self, mut rng: impl RngCore) -> crate::pczt::Action { let v_net = self.value_sum(); - let cv_net = ValueCommitment::derive(v_net, self.rcv, self.spend.note.asset()); + let cv_net = ValueCommitment::derive(v_net, self.rcv.clone(), self.spend.note.asset()); let spend = self.spend.into_pczt(&mut rng); let output = self.output.into_pczt(&cv_net, spend.nullifier, &mut rng); @@ -1398,9 +1398,9 @@ pub mod testing { address::testing::arb_address, bundle::{Authorized, Bundle}, circuit::ProvingKey, + flavor::OrchardFlavor, keys::{testing::arb_spending_key, FullViewingKey, SpendAuthorizingKey, SpendingKey}, note::{testing::arb_note, AssetBase}, - orchard_flavor::OrchardFlavor, primitives::OrchardPrimitives, tree::{Anchor, MerkleHashOrchard, MerklePath}, value::{testing::arb_positive_note_value, NoteValue, MAX_NOTE_VALUE}, @@ -1546,9 +1546,9 @@ mod tests { bundle::{Authorized, Bundle}, circuit::ProvingKey, constants::MERKLE_DEPTH_ORCHARD, + flavor::{OrchardFlavor, OrchardVanilla, OrchardZSA}, keys::{FullViewingKey, Scope, SpendingKey}, note::AssetBase, - orchard_flavor::{OrchardFlavor, OrchardVanilla, OrchardZSA}, tree::EMPTY_ROOTS, value::NoteValue, }; diff --git a/src/bundle.rs b/src/bundle.rs index 1163a8d51..fbded5407 100644 --- a/src/bundle.rs +++ b/src/bundle.rs @@ -26,9 +26,9 @@ use crate::{ bundle::commitments::{hash_bundle_auth_data, hash_bundle_txid_data}, keys::{IncomingViewingKey, OutgoingViewingKey, PreparedIncomingViewingKey}, note::{AssetBase, Note}, - orchard_sighash_versioning::{OrchardSighashVersion, VerBindingSig, VerSpendAuthSig}, primitives::redpallas::{self, Binding}, primitives::{OrchardDomain, OrchardPrimitives}, + sighash_versioning::{OrchardSighashVersion, VerBindingSig, VerSpendAuthSig}, tree::Anchor, value::{NoteValue, ValueCommitTrapdoor, ValueCommitment, ValueSum}, Proof, @@ -639,8 +639,8 @@ pub mod testing { asset_base::testing::{arb_asset_base, arb_zsa_asset_base}, AssetBase, }, - orchard_sighash_versioning::{VerBindingSig, VerSpendAuthSig}, primitives::{redpallas::testing::arb_binding_signing_key, OrchardPrimitives}, + sighash_versioning::{VerBindingSig, VerSpendAuthSig}, value::{ testing::{arb_note_value, arb_note_value_bounded}, NoteValue, ValueSum, MAX_NOTE_VALUE, diff --git a/src/bundle/burn_validation.rs b/src/bundle/burn_validation.rs index 0d94c761e..8c42b37a3 100644 --- a/src/bundle/burn_validation.rs +++ b/src/bundle/burn_validation.rs @@ -66,7 +66,10 @@ impl fmt::Display for BurnError { #[cfg(test)] mod tests { use super::*; - use crate::{issuance::compute_asset_desc_hash, issuance_auth::ZSASchnorr, value::NoteValue}; + use crate::{ + issuance::{auth::ZSASchnorr, compute_asset_desc_hash}, + value::NoteValue, + }; use nonempty::NonEmpty; /// Creates an item of bundle burn list for a given asset description hash and value. @@ -84,7 +87,7 @@ mod tests { /// A tuple `(AssetBase, Amount)` representing the burn list item. /// fn get_burn_tuple(asset_desc_hash: &[u8; 32], value: u64) -> (AssetBase, NoteValue) { - use crate::issuance_auth::{IssueAuthKey, IssueValidatingKey}; + use crate::issuance::auth::{IssueAuthKey, IssueValidatingKey}; let isk = IssueAuthKey::::from_bytes(&[1u8; 32]).unwrap(); diff --git a/src/bundle/commitments.rs b/src/bundle/commitments.rs index 2497c493a..20ae5e91c 100644 --- a/src/bundle/commitments.rs +++ b/src/bundle/commitments.rs @@ -5,10 +5,12 @@ use blake2b_simd::{Hash as Blake2bHash, Params, State}; use crate::{ bundle::{Authorization, Authorized, Bundle}, - issuance::{IssueAuth, IssueBundle, Signed}, - issuance_sighash_versioning::IssueSighashVersion, - orchard_sighash_versioning::OrchardSighashVersion, + issuance::{ + sighash_versioning::IssueSighashVersion, + {IssueAuth, IssueBundle, Signed}, + }, primitives::OrchardPrimitives, + sighash_versioning::OrchardSighashVersion, }; pub(crate) const ZCASH_ORCHARD_HASH_PERSONALIZATION: &[u8; 16] = b"ZTxIdOrchardHash"; @@ -192,13 +194,15 @@ mod tests { Authorized, Bundle, }, circuit::ProvingKey, - issuance::{compute_asset_desc_hash, AwaitingSighash, IssueBundle, IssueInfo}, - issuance_auth::{IssueAuthKey, IssueValidatingKey, ZSASchnorr}, - issuance_sighash_versioning::IssueSighashVersion, + flavor::{OrchardFlavor, OrchardVanilla, OrchardZSA}, + issuance::{ + auth::{IssueAuthKey, IssueValidatingKey, ZSASchnorr}, + sighash_versioning::IssueSighashVersion, + {compute_asset_desc_hash, AwaitingSighash, IssueBundle, IssueInfo}, + }, keys::{FullViewingKey, Scope, SpendingKey}, note::{AssetBase, Nullifier}, - orchard_flavor::{OrchardFlavor, OrchardVanilla, OrchardZSA}, - orchard_sighash_versioning::OrchardSighashVersion, + sighash_versioning::OrchardSighashVersion, value::NoteValue, Anchor, }; @@ -328,7 +332,7 @@ mod tests { compute_asset_desc_hash(&NonEmpty::from_slice(b"second asset").unwrap()); let (mut bundle, asset) = IssueBundle::new( - ik.clone(), + ik, asset_desc_hash_1, Some(IssueInfo { recipient, diff --git a/src/circuit.rs b/src/circuit.rs index f5e0a6677..5c0db1d4d 100644 --- a/src/circuit.rs +++ b/src/circuit.rs @@ -267,6 +267,8 @@ impl Witnesses { } /// The verifying key for the Orchard Action circuit. +/// +/// In practice, this is constructed for either `OrchardVanilla` or `OrchardZSA`. #[derive(Debug, Clone)] pub struct VerifyingKey { pub(crate) params: halo2_proofs::poly::commitment::Params, @@ -286,6 +288,8 @@ impl VerifyingKey { } /// The proving key for the Orchard Action circuit. +/// +/// In practice, this is constructed for either `OrchardVanilla` or `OrchardZSA`. #[derive(Debug, Clone)] pub struct ProvingKey { params: halo2_proofs::poly::commitment::Params, diff --git a/src/circuit/circuit_vanilla.rs b/src/circuit/circuit_vanilla.rs index 767e6d6a2..74f2383d1 100644 --- a/src/circuit/circuit_vanilla.rs +++ b/src/circuit/circuit_vanilla.rs @@ -36,8 +36,8 @@ use crate::{ ENABLE_OUTPUT, ENABLE_SPEND, NF_OLD, RK_X, RK_Y, }, constants::{OrchardFixedBases, OrchardFixedBasesFull, OrchardHashDomains}, + flavor::OrchardVanilla, note::AssetBase, - orchard_flavor::OrchardVanilla, }; impl OrchardCircuit for OrchardVanilla { @@ -641,9 +641,9 @@ mod tests { use crate::{ bundle::Flags, circuit::{Circuit, Instance, Proof, ProvingKey, VerifyingKey, Witnesses, K}, + flavor::OrchardVanilla, keys::SpendValidatingKey, note::{AssetBase, Note, Rho}, - orchard_flavor::OrchardVanilla, tree::MerklePath, value::{ValueCommitTrapdoor, ValueCommitment}, }; @@ -665,7 +665,7 @@ mod tests { let value = spent_note.value() - output_note.value(); let rcv = ValueCommitTrapdoor::random(&mut rng); - let cv_net = ValueCommitment::derive(value, rcv, AssetBase::native()); + let cv_net = ValueCommitment::derive(value, rcv.clone(), AssetBase::native()); let path = MerklePath::dummy(&mut rng); let anchor = path.root(spent_note.commitment().into()); diff --git a/src/circuit/circuit_zsa.rs b/src/circuit/circuit_zsa.rs index 41e796d6b..19ec190ea 100644 --- a/src/circuit/circuit_zsa.rs +++ b/src/circuit/circuit_zsa.rs @@ -41,8 +41,8 @@ use crate::{ ENABLE_OUTPUT, ENABLE_SPEND, ENABLE_ZSA, NF_OLD, RK_X, RK_Y, }, constants::{OrchardFixedBases, OrchardFixedBasesFull, OrchardHashDomains}, + flavor::OrchardZSA, note::AssetBase, - orchard_flavor::OrchardZSA, }; impl OrchardCircuit for OrchardZSA { @@ -883,9 +883,9 @@ mod tests { AdditionalZsaWitnesses, Circuit, Instance, Proof, ProvingKey, VerifyingKey, Witnesses, K, }, + flavor::OrchardZSA, keys::{FullViewingKey, Scope, SpendValidatingKey, SpendingKey}, note::{commitment::NoteCommitTrapdoor, AssetBase, Note, NoteCommitment, Nullifier, Rho}, - orchard_flavor::OrchardZSA, primitives::redpallas::VerificationKey, tree::MerklePath, value::{NoteValue, ValueCommitTrapdoor, ValueCommitment}, @@ -908,7 +908,7 @@ mod tests { let value = spent_note.value() - output_note.value(); let rcv = ValueCommitTrapdoor::random(&mut rng); - let cv_net = ValueCommitment::derive(value, rcv, AssetBase::native()); + let cv_net = ValueCommitment::derive(value, rcv.clone(), AssetBase::native()); let path = MerklePath::dummy(&mut rng); let anchor = path.root(spent_note.commitment().into()); @@ -1224,7 +1224,7 @@ mod tests { let cmx = output_note.commitment().into(); let rcv = ValueCommitTrapdoor::random(&mut rng); - let cv_net = ValueCommitment::derive(v_net, rcv, asset_base); + let cv_net = ValueCommitment::derive(v_net, rcv.clone(), asset_base); let path = MerklePath::dummy(&mut rng); let anchor = path.root(spent_note.commitment().into()); @@ -1337,7 +1337,7 @@ mod tests { v_new: circuit.witnesses.v_new, psi_new: circuit.witnesses.psi_new, rcm_new: circuit.witnesses.rcm_new.clone(), - rcv: circuit.witnesses.rcv, + rcv: circuit.witnesses.rcv.clone(), additional_zsa_witnesses: circuit .witnesses @@ -1399,7 +1399,7 @@ mod tests { v_new: circuit.witnesses.v_new, psi_new: circuit.witnesses.psi_new, rcm_new: circuit.witnesses.rcm_new.clone(), - rcv: circuit.witnesses.rcv, + rcv: circuit.witnesses.rcv.clone(), additional_zsa_witnesses: circuit .witnesses diff --git a/src/circuit/gadget/add_chip.rs b/src/circuit/gadget/add_chip.rs index 41b90b1f1..03d57a0e9 100644 --- a/src/circuit/gadget/add_chip.rs +++ b/src/circuit/gadget/add_chip.rs @@ -1,4 +1,4 @@ -//! `Add` chip implemetation. +//! `Add` chip implementation. use halo2_proofs::{ circuit::{AssignedCell, Chip, Layouter}, diff --git a/src/circuit/value_commit_orchard.rs b/src/circuit/value_commit_orchard.rs index 8ad2793a1..05dd3732c 100644 --- a/src/circuit/value_commit_orchard.rs +++ b/src/circuit/value_commit_orchard.rs @@ -369,7 +369,7 @@ mod tests { circuits.push(MyCircuit { v_old: Value::known(v_old), v_new: Value::known(v_new), - rcv: Value::known(rcv), + rcv: Value::known(rcv.clone()), asset: Value::known(asset), split_flag: Value::known(split_flag), }); diff --git a/src/constants/reference_keys.rs b/src/constants/reference_keys.rs index 535528000..3b97dfea2 100644 --- a/src/constants/reference_keys.rs +++ b/src/constants/reference_keys.rs @@ -41,12 +41,11 @@ impl ReferenceKeys { #[cfg(test)] mod tests { use super::*; - use crate::keys::{FullViewingKey, Scope}; + use crate::keys::Scope; #[test] fn recipient() { - let sk = SpendingKey::from_bytes([0; 32]).unwrap(); - let fvk = FullViewingKey::from(&sk); + let fvk = ReferenceKeys::fvk(); let recipient = fvk.address_at(0u32, Scope::External); assert_eq!(recipient, ReferenceKeys::recipient()); diff --git a/src/constants/sinsemilla.rs b/src/constants/sinsemilla.rs index 5df103344..36e7f3875 100644 --- a/src/constants/sinsemilla.rs +++ b/src/constants/sinsemilla.rs @@ -224,7 +224,10 @@ mod tests { #[test] fn q_note_zsa_commitment_m() { - let domain = CommitDomain::new(NOTE_ZSA_COMMITMENT_PERSONALIZATION); + let domain = CommitDomain::new_with_separate_domains( + NOTE_ZSA_COMMITMENT_PERSONALIZATION, + NOTE_COMMITMENT_PERSONALIZATION, + ); let point = domain.Q(); let coords = point.to_affine().coordinates().unwrap(); diff --git a/src/orchard_flavor.rs b/src/flavor.rs similarity index 100% rename from src/orchard_flavor.rs rename to src/flavor.rs diff --git a/src/issuance.rs b/src/issuance.rs index 7567f39b7..ca403cbac 100644 --- a/src/issuance.rs +++ b/src/issuance.rs @@ -23,8 +23,6 @@ use rand::RngCore; use crate::{ bundle::commitments::{hash_issue_bundle_auth_data, hash_issue_bundle_txid_data}, constants::reference_keys::ReferenceKeys, - issuance_auth::{IssueAuthKey, IssueValidatingKey, ZSASchnorr}, - issuance_sighash_versioning::{IssueSighashVersion, VerBIP340IssueAuthSig}, note::{rho_for_issuance_note, AssetBase, Nullifier, Rho}, value::NoteValue, Address, Note, @@ -38,6 +36,12 @@ use Error::{ MissingReferenceNoteOnFirstIssuance, ValueOverflow, }; +pub mod auth; +pub mod sighash_versioning; + +use auth::{IssueAuthKey, IssueValidatingKey, ZSASchnorr}; +use sighash_versioning::{IssueSighashVersion, VerBIP340IssueAuthSig}; + /// Checks if a given note is a reference note. /// /// A reference note satisfies the following conditions: @@ -884,19 +888,20 @@ mod tests { use crate::{ builder::{Builder, BundleType}, circuit::ProvingKey, + flavor::OrchardZSA, issuance::Error::{ IncorrectRhoDerivation, InvalidIssueBundleSig, IssueActionNotFound, IssueActionPreviouslyFinalizedAssetBase, IssueBundleIkMismatchAssetBase, }, issuance::{ - compute_asset_desc_hash, is_reference_note, verify_issue_bundle, AssetRecord, - IssuanceFlags, IssueAction, IssueBundle, IssueInfo, Signed, + auth::{IssueAuthKey, IssueValidatingKey, ZSASchnorr}, + compute_asset_desc_hash, is_reference_note, + sighash_versioning::{IssueSighashVersion, VerBIP340IssueAuthSig}, + verify_issue_bundle, AssetRecord, IssuanceFlags, IssueAction, IssueBundle, IssueInfo, + Signed, }, - issuance_auth::{IssueAuthKey, IssueValidatingKey, ZSASchnorr}, - issuance_sighash_versioning::{IssueSighashVersion, VerBIP340IssueAuthSig}, keys::{FullViewingKey, Scope, SpendAuthorizingKey, SpendingKey}, note::{rho_for_issuance_note, AssetBase, ExtractedNoteCommitment, Nullifier, Rho}, - orchard_flavor::OrchardZSA, tree::{MerkleHashOrchard, MerklePath}, value::NoteValue, Address, Anchor, Bundle, Note, @@ -1554,7 +1559,7 @@ mod tests { compute_asset_desc_hash(&NonEmpty::from_slice(b"asset desc").unwrap()); let (bundle, _) = IssueBundle::new( - ik.clone(), + ik, asset_desc_hash, Some(IssueInfo { recipient, @@ -2038,14 +2043,14 @@ mod tests { pub mod testing { use crate::{ issuance::{ + auth::{ + testing::arb_issuance_validating_key, IssueAuthSig, IssueAuthSigScheme, + IssueValidatingKey, ZSASchnorr, + }, + sighash_versioning::IssueSighashVersion, AwaitingNullifier, IssuanceFlags, IssueAction, IssueBundle, Prepared, Signed, VerBIP340IssueAuthSig, }, - issuance_auth::{ - testing::arb_issuance_validating_key, IssueAuthSig, IssueAuthSigScheme, - IssueValidatingKey, ZSASchnorr, - }, - issuance_sighash_versioning::IssueSighashVersion, note::testing::arb_zsa_note, }; use nonempty::NonEmpty; diff --git a/src/issuance_auth.rs b/src/issuance/auth.rs similarity index 99% rename from src/issuance_auth.rs rename to src/issuance/auth.rs index b4be0fdef..77794ef72 100644 --- a/src/issuance_auth.rs +++ b/src/issuance/auth.rs @@ -6,7 +6,7 @@ //! # Example //! ``` //! use rand::rngs::OsRng; -//! use orchard::issuance_auth::{IssueAuthKey, IssueValidatingKey, ZSASchnorr}; +//! use orchard::issuance::auth::{IssueAuthKey, IssueValidatingKey, ZSASchnorr}; //! //! let mut rng = OsRng; //! let isk = IssueAuthKey::::random(&mut rng); diff --git a/src/issuance_sighash_versioning.rs b/src/issuance/sighash_versioning.rs similarity index 93% rename from src/issuance_sighash_versioning.rs rename to src/issuance/sighash_versioning.rs index effeabe9d..760022ee4 100644 --- a/src/issuance_sighash_versioning.rs +++ b/src/issuance/sighash_versioning.rs @@ -1,6 +1,6 @@ //! This module defines the versioning for issuance authorization signatures. -use crate::issuance_auth::{IssueAuthSig, IssueAuthSigScheme, ZSASchnorr}; +use crate::issuance::auth::{IssueAuthSig, IssueAuthSigScheme, ZSASchnorr}; /// The Issuance Sighash version. #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] diff --git a/src/keys.rs b/src/keys.rs index 0513e66e1..1ba8529f2 100644 --- a/src/keys.rs +++ b/src/keys.rs @@ -4,6 +4,7 @@ use alloc::vec::Vec; use core::fmt::Debug; use core2::io::{self, Read, Write}; +use ::zip32::{hardened_only, ChildIndex}; use aes::Aes256; use blake2b_simd::{Hash as Blake2bHash, Params}; use fpe::ff1::{BinaryNumeralString, FF1}; @@ -28,9 +29,7 @@ use crate::{ zip32::{self, ExtendedSpendingKey}, }; -// Preserve '::' which specifies the EXTERNAL 'zip32' crate -#[rustfmt::skip] -pub use ::zip32::{AccountId, ChildIndex, DiversifierIndex, Scope, hardened_only}; +pub use ::zip32::{AccountId, DiversifierIndex, Scope}; const KDF_ORCHARD_PERSONALIZATION: &[u8; 16] = b"Zcash_OrchardKDF"; const ZIP32_PURPOSE: u32 = 32; @@ -187,7 +186,7 @@ impl SpendValidatingKey { self.0.randomize(randomizer) } - /// Converts this spend key to its serialized form, + /// Converts this spend validating key to its serialized form, /// I2LEOSP_256(ak). #[cfg_attr(feature = "unstable-frost", visibility::make(pub))] pub(crate) fn to_bytes(&self) -> [u8; 32] { @@ -977,7 +976,7 @@ mod tests { *, }; use crate::{ - issuance_auth::{IssueAuthKey, IssueValidatingKey, ZSASchnorr}, + issuance::auth::{IssueAuthKey, IssueValidatingKey, ZSASchnorr}, note::{AssetBase, ExtractedNoteCommitment, RandomSeed, Rho}, value::NoteValue, Note, diff --git a/src/lib.rs b/src/lib.rs index 4c9deded7..f4da3456f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -32,15 +32,13 @@ pub mod bundle; #[cfg(feature = "circuit")] pub mod circuit; mod constants; +pub mod flavor; pub mod issuance; -pub mod issuance_auth; -pub mod issuance_sighash_versioning; pub mod keys; pub mod note; -pub mod orchard_flavor; -pub mod orchard_sighash_versioning; pub mod pczt; pub mod primitives; +pub mod sighash_versioning; mod spec; pub mod tree; pub mod value; @@ -52,12 +50,8 @@ mod test_vectors; pub use action::Action; pub use address::Address; pub use bundle::Bundle; -pub use constants::reference_keys::ReferenceKeys; pub use constants::MERKLE_DEPTH_ORCHARD as NOTE_COMMITMENT_TREE_DEPTH; -pub use note::{ - commitment::{ExtractedNoteCommitment, NoteCommitment}, - Note, -}; +pub use note::Note; pub use tree::Anchor; /// A proof of the validity of an Orchard [`Bundle`]. diff --git a/src/note.rs b/src/note.rs index 8f4e144d9..07b1dd9a6 100644 --- a/src/note.rs +++ b/src/note.rs @@ -18,6 +18,9 @@ use crate::{ Address, }; +pub(crate) mod asset_base; +pub use self::asset_base::AssetBase; + pub(crate) mod commitment; pub use self::commitment::{ExtractedNoteCommitment, NoteCommitment}; @@ -70,9 +73,6 @@ impl Rho { } } -pub(crate) mod asset_base; -pub use self::asset_base::AssetBase; - /// The ZIP 212 seed randomness for a note. #[derive(Copy, Clone, Debug)] pub struct RandomSeed([u8; 32]); @@ -203,6 +203,37 @@ impl Note { asset: AssetBase, rho: Rho, rseed: RandomSeed, + ) -> CtOption { + Self::from_parts_internal( + recipient, + value, + asset, + rho, + rseed, + CtOption::new(rseed, 0u8.into()), + ) + } + + /// Creates a `Note` from its component parts. + /// + /// This additionally permits constructing a [Split Input note], which is necessary + /// for constructing certain patterns of bundles containing ZSA outputs. It is used by + /// the PCZT code, which is the only place where these notes are serialized. + /// + /// Returns `None` if a valid [`NoteCommitment`] cannot be derived from the note. + /// + /// # Caveats + /// + /// See [`Self::from_parts`]. + /// + /// [Split Input note]: https://zips.z.cash/zip-0226#split-notes + pub(crate) fn from_parts_internal( + recipient: Address, + value: NoteValue, + asset: AssetBase, + rho: Rho, + rseed: RandomSeed, + rseed_split_note: CtOption, ) -> CtOption { let note = Note { recipient, @@ -210,7 +241,7 @@ impl Note { asset, rho, rseed, - rseed_split_note: CtOption::new(rseed, 0u8.into()), + rseed_split_note, }; CtOption::new(note, note.commitment_inner().is_some()) } @@ -287,14 +318,10 @@ impl Note { } /// Returns the rseed_split_note value of this note. - pub fn rseed_split_note(&self) -> CtOption { + pub(crate) fn rseed_split_note(&self) -> CtOption { self.rseed_split_note } - pub(crate) fn set_rseed_split_note(&mut self, rseed_split_note: RandomSeed) { - self.rseed_split_note = CtOption::new(rseed_split_note, 1u8.into()); - } - /// Derives the ephemeral secret key for this note. pub(crate) fn esk(&self) -> EphemeralSecretKey { EphemeralSecretKey(self.rseed.esk(&self.rho)) @@ -351,8 +378,14 @@ impl Note { ) } - /// Create a split note which has the same values than the input note except for - /// `rseed_split_note` which is equal to a random seed. + /// Creates a [Split Input note] from a Custom Asset note, for use on the Spend side + /// of an Output-only Action. + /// + /// # Panics + /// + /// Panics if `self.asset().is_native()`. + /// + /// [Split Input note]: https://zips.z.cash/zip-0226#split-notes pub fn create_split_note(self, rng: &mut impl RngCore) -> Self { Note { rseed_split_note: CtOption::new(RandomSeed::random(rng, &self.rho), 1u8.into()), @@ -429,7 +462,7 @@ pub mod testing { use crate::{ address::testing::arb_address, - issuance_auth::{IssueValidatingKey, ZSASchnorr}, + issuance::auth::{IssueValidatingKey, ZSASchnorr}, note::{asset_base::testing::arb_asset_base, nullifier::testing::arb_nullifier, AssetBase}, value::{testing::arb_note_value, NoteValue}, }; diff --git a/src/note/asset_base.rs b/src/note/asset_base.rs index 8283378bc..98e6e3b79 100644 --- a/src/note/asset_base.rs +++ b/src/note/asset_base.rs @@ -2,9 +2,8 @@ use alloc::vec::Vec; use blake2b_simd::{Hash as Blake2bHash, Params}; use core::cmp::Ordering; use core::hash::{Hash, Hasher}; -use group::{Curve, Group, GroupEncoding}; +use group::{Group, GroupEncoding}; use nonempty::NonEmpty; -use pasta_curves::arithmetic::CurveAffine; use pasta_curves::{arithmetic::CurveExt, pallas}; use rand_core::CryptoRngCore; use subtle::{Choice, ConstantTimeEq, CtOption}; @@ -13,8 +12,10 @@ use crate::{ constants::fixed_bases::{ NATIVE_ASSET_BASE_V_BYTES, VALUE_COMMITMENT_PERSONALIZATION, ZSA_ASSET_BASE_PERSONALIZATION, }, - issuance::compute_asset_desc_hash, - issuance_auth::{IssueAuthKey, IssueValidatingKey, ZSASchnorr}, + issuance::{ + auth::{IssueAuthKey, IssueValidatingKey, ZSASchnorr}, + compute_asset_desc_hash, + }, }; /// Note type identifier. @@ -30,23 +31,18 @@ impl PartialOrd for AssetBase { impl Ord for AssetBase { fn cmp(&self, other: &Self) -> Ordering { - let self_coord = self.0.to_affine().coordinates().unwrap(); - let other_coord = other.0.to_affine().coordinates().unwrap(); - self_coord - .x() - .cmp(other_coord.x()) - .then_with(|| self_coord.y().cmp(other_coord.y())) + self.0.to_bytes().cmp(&other.0.to_bytes()) } } /// Personalization for the ZSA asset digest generator pub const ZSA_ASSET_DIGEST_PERSONALIZATION: &[u8; 16] = b"ZSA-Asset-Digest"; -/// AssetDigest for the ZSA asset +/// Derives the Asset Digest for the given ZSA asset. /// -/// Defined in [ZIP-227: Issuance of Zcash Shielded Assets][assetdigest]. +/// Defined in [ZIP-227: Issuance of Zcash Shielded Assets][assetdigest]. /// -/// [assetdigest]: https://zips.z.cash/zip-0227.html#specification-asset-identifier-asset-digest-and-asset-base +/// [assetdigest]: https://zips.z.cash/zip-0227#asset-digests pub fn asset_digest(encode_asset_id: &[u8]) -> Blake2bHash { Params::new() .hash_length(64) @@ -64,10 +60,10 @@ pub fn encode_asset_id( ik: &IssueValidatingKey, asset_desc_hash: &[u8; 32], ) -> Vec { - let ik_encoding = ik.encode(); - let mut asset_id = Vec::with_capacity(1 + ik_encoding.len() + asset_desc_hash.len()); + let issuer = ik.encode(); + let mut asset_id = Vec::with_capacity(1 + issuer.len() + asset_desc_hash.len()); asset_id.push(version); - asset_id.extend(ik_encoding); + asset_id.extend(issuer); asset_id.extend_from_slice(&asset_desc_hash[..]); asset_id } @@ -85,9 +81,9 @@ impl AssetBase { /// Note type derivation. /// - /// Defined in [ZIP-226: Transfer and Burn of Zcash Shielded Assets][assetbase]. + /// Defined in [ZIP 227: Issuance of Zcash Shielded Assets][assetbase]. /// - /// [assetbase]: https://zips.z.cash/zip-0226.html#asset-identifiers + /// [assetbase]: https://zips.z.cash/zip-0227#asset-bases /// /// # Panics /// @@ -117,7 +113,7 @@ impl AssetBase { pub fn native() -> Self { AssetBase(pallas::Point::hash_to_curve( VALUE_COMMITMENT_PERSONALIZATION, - )(&NATIVE_ASSET_BASE_V_BYTES[..])) + )(&NATIVE_ASSET_BASE_V_BYTES)) } /// The base point used in value commitments. @@ -164,7 +160,7 @@ pub mod testing { use proptest::prelude::*; - use crate::issuance_auth::{ + use crate::issuance::auth::{ testing::arb_issuance_authorizing_key, IssueValidatingKey, ZSASchnorr, }; @@ -204,7 +200,7 @@ pub mod testing { #[cfg(test)] mod tests { use crate::{ - issuance_auth::{IssueValidatingKey, ZSASchnorr}, + issuance::auth::{IssueValidatingKey, ZSASchnorr}, note::AssetBase, }; diff --git a/src/note/commitment.rs b/src/note/commitment.rs index 6bc04f5ed..de7606bee 100644 --- a/src/note/commitment.rs +++ b/src/note/commitment.rs @@ -40,7 +40,7 @@ impl NoteCommitment { /// /// Defined in [ZIP-226: Transfer and Burn of Zcash Shielded Assets][notecommit]. /// - /// [notecommit]: https://zips.z.cash/zip-0226#note-structure-commitment + /// [notecommit]: https://zips.z.cash/zip-0226#note-structure-and-commitment pub(crate) fn derive( g_d: [u8; 32], pk_d: [u8; 32], diff --git a/src/pczt.rs b/src/pczt.rs index 2f2b0a5bb..a41558efc 100644 --- a/src/pczt.rs +++ b/src/pczt.rs @@ -12,9 +12,9 @@ use zip32::ChildIndex; use crate::{ bundle::Flags, + flavor::OrchardVanilla, keys::{FullViewingKey, SpendingKey}, note::{ExtractedNoteCommitment, Nullifier, RandomSeed, Rho, TransmittedNoteCiphertext}, - orchard_flavor::OrchardVanilla, primitives::redpallas::{self, Binding, SpendAuth}, tree::MerklePath, value::{NoteValue, ValueCommitTrapdoor, ValueCommitment, ValueSum}, @@ -343,9 +343,9 @@ mod tests { builder::{Builder, BundleType}, circuit::ProvingKey, constants::MERKLE_DEPTH_ORCHARD, + flavor::OrchardVanilla, keys::{FullViewingKey, Scope, SpendAuthorizingKey, SpendingKey}, note::{AssetBase, ExtractedNoteCommitment, RandomSeed, Rho}, - orchard_flavor::OrchardVanilla, pczt::Zip32Derivation, tree::{MerkleHashOrchard, EMPTY_ROOTS}, value::NoteValue, diff --git a/src/pczt/parse.rs b/src/pczt/parse.rs index 76414d908..fa98c98cf 100644 --- a/src/pczt/parse.rs +++ b/src/pczt/parse.rs @@ -11,9 +11,9 @@ use zip32::ChildIndex; use super::{Action, Bundle, Output, Spend, Zip32Derivation}; use crate::{ bundle::Flags, + flavor::OrchardVanilla, keys::{FullViewingKey, SpendingKey}, note::{ExtractedNoteCommitment, Nullifier, RandomSeed, Rho, TransmittedNoteCiphertext}, - orchard_flavor::OrchardVanilla, primitives::{ redpallas::{self, SpendAuth}, OrchardPrimitives, diff --git a/src/pczt/prover.rs b/src/pczt/prover.rs index 5a103f9bd..6b5b98f93 100644 --- a/src/pczt/prover.rs +++ b/src/pczt/prover.rs @@ -6,8 +6,8 @@ use rand::{CryptoRng, RngCore}; use crate::{ builder::SpendInfo, circuit::{Circuit, Instance, ProvingKey, Witnesses}, + flavor::OrchardVanilla, note::{AssetBase, Rho}, - orchard_flavor::OrchardVanilla, Note, Proof, }; @@ -74,7 +74,10 @@ impl super::Bundle { .spend .alpha .ok_or(ProverError::MissingSpendAuthRandomizer)?; - let rcv = action.rcv.ok_or(ProverError::MissingValueCommitTrapdoor)?; + let rcv = action + .rcv + .clone() + .ok_or(ProverError::MissingValueCommitTrapdoor)?; Witnesses::from_action_context::(spend, output_note, alpha, rcv) .ok_or(ProverError::RhoMismatch) diff --git a/src/pczt/tx_extractor.rs b/src/pczt/tx_extractor.rs index 057dc2831..10cfe9f0b 100644 --- a/src/pczt/tx_extractor.rs +++ b/src/pczt/tx_extractor.rs @@ -4,9 +4,9 @@ use rand::{CryptoRng, RngCore}; use super::Action; use crate::{ bundle::{Authorization, Authorized, EffectsOnly}, - orchard_flavor::OrchardVanilla, - orchard_sighash_versioning::{OrchardSighashVersion, VerBindingSig, VerSpendAuthSig}, + flavor::OrchardVanilla, primitives::redpallas::{self, Binding, SpendAuth}, + sighash_versioning::{OrchardSighashVersion, VerBindingSig, VerSpendAuthSig}, Proof, }; @@ -46,6 +46,7 @@ impl super::Bundle { .ok_or(TxExtractorError::MissingProof)?, bsk: bundle .bsk + .clone() .ok_or(TxExtractorError::MissingBindingSignatureSigningKey)?, }) }, diff --git a/src/pczt/verify.rs b/src/pczt/verify.rs index c6a22b9e0..e58576fbe 100644 --- a/src/pczt/verify.rs +++ b/src/pczt/verify.rs @@ -15,7 +15,10 @@ impl super::Action { pub fn verify_cv_net(&self) -> Result<(), VerifyError> { let spend_value = self.spend().value.ok_or(VerifyError::MissingValue)?; let output_value = self.output().value.ok_or(VerifyError::MissingValue)?; - let rcv = self.rcv.ok_or(VerifyError::MissingValueCommitTrapdoor)?; + let rcv = self + .rcv + .clone() + .ok_or(VerifyError::MissingValueCommitTrapdoor)?; let cv_net = ValueCommitment::derive(spend_value - output_value, rcv, AssetBase::native()); if cv_net.to_bytes() == self.cv_net.to_bytes() { diff --git a/src/primitives/compact_action.rs b/src/primitives/compact_action.rs index dcedb048b..54b809da6 100644 --- a/src/primitives/compact_action.rs +++ b/src/primitives/compact_action.rs @@ -6,8 +6,8 @@ use zcash_note_encryption::{note_bytes::NoteBytes, EphemeralKeyBytes, ShieldedOu use crate::{ action::Action, + flavor::OrchardVanilla, note::{ExtractedNoteCommitment, Nullifier, Rho}, - orchard_flavor::OrchardVanilla, }; use super::{orchard_domain::OrchardDomain, orchard_primitives::OrchardPrimitives}; diff --git a/src/primitives/orchard_primitives.rs b/src/primitives/orchard_primitives.rs index 96ef64a6c..d6f83b77b 100644 --- a/src/primitives/orchard_primitives.rs +++ b/src/primitives/orchard_primitives.rs @@ -10,8 +10,8 @@ use zcash_note_encryption::{note_bytes::NoteBytes, AEAD_TAG_SIZE}; use crate::{ bundle::{Authorization, Authorized}, note::AssetBase, - orchard_sighash_versioning::OrchardSighashVersion, primitives::zcash_note_encryption_domain::{Memo, MEMO_SIZE}, + sighash_versioning::OrchardSighashVersion, Bundle, Note, }; diff --git a/src/primitives/orchard_primitives_vanilla.rs b/src/primitives/orchard_primitives_vanilla.rs index 3d5ff74b4..3c35b6f25 100644 --- a/src/primitives/orchard_primitives_vanilla.rs +++ b/src/primitives/orchard_primitives_vanilla.rs @@ -15,9 +15,8 @@ use crate::{ }, Authorization, Authorized, }, + flavor::OrchardVanilla, note::{AssetBase, Note}, - orchard_flavor::OrchardVanilla, - orchard_sighash_versioning::OrchardSighashVersion, primitives::{ orchard_primitives::OrchardPrimitives, zcash_note_encryption_domain::{ @@ -25,6 +24,7 @@ use crate::{ NOTE_VERSION_BYTE_V2, }, }, + sighash_versioning::OrchardSighashVersion, Bundle, }; @@ -129,6 +129,7 @@ mod tests { use crate::{ action::Action, address::Address, + flavor::OrchardVanilla, keys::{ DiversifiedTransmissionKey, Diversifier, EphemeralSecretKey, IncomingViewingKey, OutgoingViewingKey, PreparedIncomingViewingKey, @@ -137,7 +138,6 @@ mod tests { testing::arb_native_note, AssetBase, ExtractedNoteCommitment, Note, Nullifier, RandomSeed, Rho, TransmittedNoteCiphertext, }, - orchard_flavor::OrchardVanilla, primitives::{ compact_action::CompactAction, orchard_domain::OrchardDomain, diff --git a/src/primitives/orchard_primitives_zsa.rs b/src/primitives/orchard_primitives_zsa.rs index 537d1315d..29a366953 100644 --- a/src/primitives/orchard_primitives_zsa.rs +++ b/src/primitives/orchard_primitives_zsa.rs @@ -19,9 +19,8 @@ use crate::{ }, Authorization, Authorized, }, + flavor::OrchardZSA, note::{AssetBase, Note}, - orchard_flavor::OrchardZSA, - orchard_sighash_versioning::OrchardSighashVersion, primitives::{ orchard_primitives::OrchardPrimitives, zcash_note_encryption_domain::{ @@ -29,6 +28,7 @@ use crate::{ COMPACT_NOTE_SIZE_ZSA, MEMO_SIZE, NOTE_VERSION_BYTE_V3, }, }, + sighash_versioning::OrchardSighashVersion, Bundle, }; @@ -176,6 +176,7 @@ mod tests { use crate::{ action::Action, address::Address, + flavor::OrchardZSA, keys::{ DiversifiedTransmissionKey, Diversifier, EphemeralSecretKey, IncomingViewingKey, OutgoingViewingKey, PreparedIncomingViewingKey, @@ -184,7 +185,6 @@ mod tests { testing::arb_note, AssetBase, ExtractedNoteCommitment, Note, Nullifier, RandomSeed, Rho, TransmittedNoteCiphertext, }, - orchard_flavor::OrchardZSA, primitives::{ compact_action::CompactAction, orchard_domain::OrchardDomain, diff --git a/src/primitives/redpallas.rs b/src/primitives/redpallas.rs index 70155cfbf..f14c17061 100644 --- a/src/primitives/redpallas.rs +++ b/src/primitives/redpallas.rs @@ -23,7 +23,7 @@ pub type Binding = reddsa::orchard::Binding; impl SigType for Binding {} /// A RedPallas signing key. -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Debug)] pub struct SigningKey(reddsa::SigningKey); impl From> for [u8; 32] { diff --git a/src/orchard_sighash_versioning.rs b/src/sighash_versioning.rs similarity index 100% rename from src/orchard_sighash_versioning.rs rename to src/sighash_versioning.rs diff --git a/src/value.rs b/src/value.rs index 54c377af0..2f221c6f3 100644 --- a/src/value.rs +++ b/src/value.rs @@ -218,7 +218,7 @@ impl ValueSum { ) } - pub(crate) fn into>(self) -> Result { + pub(crate) fn into_value_balance>(self) -> Result { i64::try_from(self) .map_err(BuildError::ValueSum) .and_then(|i| V::try_from(i).map_err(|_| BuildError::ValueSum(OverflowError))) @@ -285,7 +285,7 @@ impl From for ValueSum { } /// The blinding factor for a [`ValueCommitment`]. -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Debug)] pub struct ValueCommitTrapdoor(pallas::Scalar); impl ValueCommitTrapdoor { @@ -396,6 +396,7 @@ impl ValueCommitment { #[allow(non_snake_case)] pub fn derive(value: ValueSum, rcv: ValueCommitTrapdoor, asset: AssetBase) -> Self { let hasher = pallas::Point::hash_to_curve(VALUE_COMMITMENT_PERSONALIZATION); + let V = asset.cv_base(); let R = hasher(&VALUE_COMMITMENT_R_BYTES); let abs_value = u64::try_from(value.0.abs()).expect("value must be in valid range"); @@ -405,9 +406,7 @@ impl ValueCommitment { pallas::Scalar::from(abs_value) }; - let V_zsa = asset.cv_base(); - - ValueCommitment(V_zsa * value + R * rcv.0) + ValueCommitment(V * value + R * rcv.0) } pub(crate) fn into_bvk(self) -> redpallas::VerificationKey { diff --git a/tests/builder.rs b/tests/builder.rs index c9e2f853e..0848dc550 100644 --- a/tests/builder.rs +++ b/tests/builder.rs @@ -3,9 +3,9 @@ use orchard::{ builder::{Builder, BundleType}, bundle::{Authorized, Flags}, circuit::{ProvingKey, VerifyingKey}, + flavor::{OrchardFlavor, OrchardVanilla, OrchardZSA}, keys::{FullViewingKey, PreparedIncomingViewingKey, Scope, SpendAuthorizingKey, SpendingKey}, note::{AssetBase, ExtractedNoteCommitment}, - orchard_flavor::{OrchardFlavor, OrchardVanilla, OrchardZSA}, primitives::{OrchardDomain, OrchardPrimitives}, tree::{MerkleHashOrchard, MerklePath}, value::NoteValue, diff --git a/tests/issuance_global_state.rs b/tests/issuance_global_state.rs index 6d7d688c7..750529d7c 100644 --- a/tests/issuance_global_state.rs +++ b/tests/issuance_global_state.rs @@ -6,6 +6,7 @@ use rand::{rngs::OsRng, RngCore}; use orchard::{ issuance::{ + auth::{IssueAuthKey, IssueValidatingKey, ZSASchnorr}, compute_asset_desc_hash, verify_issue_bundle, AssetRecord, Error::{ IssueActionPreviouslyFinalizedAssetBase, MissingReferenceNoteOnFirstIssuance, @@ -13,7 +14,6 @@ use orchard::{ }, IssueBundle, IssueInfo, Signed, }, - issuance_auth::{IssueAuthKey, IssueValidatingKey, ZSASchnorr}, keys::{FullViewingKey, Scope, SpendingKey}, note::{AssetBase, Nullifier}, value::NoteValue, diff --git a/tests/zsa.rs b/tests/zsa.rs index 66017e4b9..0f769ea1a 100644 --- a/tests/zsa.rs +++ b/tests/zsa.rs @@ -7,14 +7,14 @@ use orchard::{ builder::{Builder, BundleType}, bundle::Authorized, circuit::{ProvingKey, VerifyingKey}, + flavor::OrchardZSA, issuance::{ + auth::{IssueAuthKey, IssueValidatingKey, ZSASchnorr}, compute_asset_desc_hash, verify_issue_bundle, AwaitingNullifier, IssueBundle, IssueInfo, Signed, }, - issuance_auth::{IssueAuthKey, IssueValidatingKey, ZSASchnorr}, keys::{FullViewingKey, PreparedIncomingViewingKey, Scope, SpendAuthorizingKey, SpendingKey}, note::{AssetBase, ExtractedNoteCommitment, Nullifier}, - orchard_flavor::OrchardZSA, primitives::OrchardDomain, tree::{MerkleHashOrchard, MerklePath}, value::NoteValue,