From ea142afb4087413b6888b4bea3af2438fd3b06f7 Mon Sep 17 00:00:00 2001 From: soralit Date: Tue, 5 Nov 2024 18:12:52 +0800 Subject: [PATCH] fix: adjust transaction signing code --- rust/Cargo.lock | 1 + rust/apps/zcash/Cargo.toml | 1 + rust/apps/zcash/src/pczt.rs | 120 +++++++++++++++++- rust/keystore/src/algorithms/zcash/mod.rs | 1 + rust/zcash_vendor/src/orchard/address.rs | 6 +- rust/zcash_vendor/src/orchard/constants.rs | 2 +- rust/zcash_vendor/src/orchard/keys.rs | 62 ++++----- rust/zcash_vendor/src/orchard/mod.rs | 2 +- rust/zcash_vendor/src/orchard/redpallas.rs | 2 +- rust/zcash_vendor/src/orchard/spec.rs | 44 +++---- rust/zcash_vendor/src/orchard/zip32.rs | 2 +- rust/zcash_vendor/src/pczt/common.rs | 18 +-- rust/zcash_vendor/src/pczt/mod.rs | 18 +-- rust/zcash_vendor/src/pczt/orchard.rs | 80 ++++++------ rust/zcash_vendor/src/pczt/pczt_ext.rs | 18 ++- rust/zcash_vendor/src/pczt/sapling.rs | 76 +++++------ rust/zcash_vendor/src/pczt/transparent.rs | 40 +++--- rust/zcash_vendor/src/sinsemilla/mod.rs | 4 +- .../src/zcash_address/unified/address.rs | 2 +- .../src/zcash_address/unified/fvk.rs | 2 +- .../src/zcash_address/unified/ivk.rs | 2 +- .../src/zcash_address/unified/mod.rs | 8 +- .../src/zcash_primitives/legacy.rs | 2 +- .../src/zcash_primitives/legacy/keys.rs | 2 +- 24 files changed, 320 insertions(+), 195 deletions(-) diff --git a/rust/Cargo.lock b/rust/Cargo.lock index d82c4a483..8e2304011 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -356,6 +356,7 @@ version = "0.1.0" dependencies = [ "app_utils", "bitcoin", + "hex", "keystore", "rust_tools", "thiserror-core", diff --git a/rust/apps/zcash/Cargo.toml b/rust/apps/zcash/Cargo.toml index 8b1bb0e0f..d224d9369 100644 --- a/rust/apps/zcash/Cargo.toml +++ b/rust/apps/zcash/Cargo.toml @@ -12,6 +12,7 @@ app_utils = { workspace = true } bitcoin = { workspace = true } thiserror = { workspace = true } zcash_vendor = { workspace = true } +hex = { workspace = true } [dev-dependencies] keystore = { path = "../../keystore" } diff --git a/rust/apps/zcash/src/pczt.rs b/rust/apps/zcash/src/pczt.rs index a6a39121b..e696b0aa0 100644 --- a/rust/apps/zcash/src/pczt.rs +++ b/rust/apps/zcash/src/pczt.rs @@ -7,7 +7,7 @@ use zcash_vendor::pczt::pczt_ext::{PcztSigner, ZcashSignature}; use crate::errors::ZcashError; struct SeedSigner { - seed: [u8; 32], + seed: [u8; 64], } impl PcztSigner for SeedSigner { @@ -42,3 +42,121 @@ impl PcztSigner for SeedSigner { .map_err(|e| ZcashError::SigningError(e.to_string())) } } + +#[cfg(test)] +mod tests { + use alloc::{collections::btree_map::BTreeMap, vec}; + use zcash_vendor::pczt::{ + common::Global, + orchard::{self, Action}, + sapling, transparent, Pczt, Version, V5_TX_VERSION, V5_VERSION_GROUP_ID, + }; + + use super::*; + + extern crate std; + use std::println; + + #[test] + fn test_pczt_sign() { + let seed = hex::decode("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap(); + let signer = SeedSigner { + seed: seed.try_into().unwrap(), + }; + + let pczt = Pczt { + version: Version::V0, + transparent: transparent::Bundle { + inputs: vec![], + outputs: vec![], + }, + sapling: sapling::Bundle { + anchor: None, + spends: vec![], + outputs: vec![], + value_balance: 0, + bsk: None, + }, + orchard: orchard::Bundle { + anchor: Some(hex::decode("a6c1ad5befd98da596ebe78491d76f76402f3400bf921f73a3b176bd70ab5000").unwrap().try_into().unwrap()), + actions: vec![ + Action { + cv: hex::decode("4ac2480c13624d2b8aabf82ee808b4e4965d6c26efd9cfc9070f69e1a9a69609").unwrap().try_into().unwrap(), + spend: orchard::Spend { + value: None, + witness: None, + alpha: Some(hex::decode("105dd4f80b149ee6a8d5f11b2d0f7d0caa7cece6d0dce3ce494ce14977def354").unwrap().try_into().unwrap()), + fvk: None, + proprietary: BTreeMap::new(), + recipient: None, + rho: None, + rseed: None, + nullifier: hex::decode("ef870733c09572b274782e32e28809c201a90c1e179ad78e88eb1477c7bd9631").unwrap().try_into().unwrap(), + rk: hex::decode("7fe9364e043a92f893100dc09fc70f1a4faad022687767f8c3495a83a57e6726").unwrap().try_into().unwrap(), + spend_auth_sig: None, + }, + output: orchard::Output { + cmx: hex::decode("dbc7cc05319a4c70a6792ec195e99f1f3028194338953ee28f2f9426e06e1039").unwrap().try_into().unwrap(), + ephemeral_key: hex::decode("c7a4a801f5a0cf4380263eed1acc4952ecc61805a6bc4c17ce0fe783aa8f582e").unwrap().try_into().unwrap(), + enc_ciphertext: hex::decode("212c8799c5cc99400f3c1685820fd7d6b86a155f43b35d803aab357ef65f95430c922192e3a5c9d0e23d34a39d4257d2361c6f7ffbe386e4573ace688854f1c45ff08644d1ec4de6ad877104f9172cffbbcaf97993eac6a54b426c492697dcfe15461a661a0dd770696f1e6a59b3d280034b38f96cecfb8bb8c3ee642640887e021cc06406c1dc94a1d0c1e71bdb864bd97e1ca6beb25bcdb5bb756ca209da24aea0cfe45f65e159ad395e78133bd56c227da05778df4368fbb5247bb33cddafc7fefd67a8cb26d7b8841896f3e7ca57e218273335851e980ee470a7995e7ff179eb4a566ca8a7aca67cee124b8d8fd32072804d288f9db115edabb90b2cb3121dcb6069f8cb0809e1d53e1b71182f6a903436fe6685706d0e089e2cef276b27e7cd0a32230e1da7f5ded3edd136dc263f4913b1fd519eefd7f4a23dbfa8c530807e2c352b1b2e4d69cce2ffc506e85bba1dbf0daf212bc5ec204964aa26329071ae19cfc2614b7e6f2b5f0b831b1dafaa91e1b2e0e46f7d6b7e6870209cf10fc13908b88d079802f3e2fa2a62a3a88dd7fba600655948ff716ee6e7ee76f2deeb32a2cac8726168dcedad7584c9b42a4938b617b605f3e7acde18f8f5b5495ecd5ccbb7c9d86888b8f6a236cb79eced16eb41dbe884382d78dd26768d7110843aa3e3804c0757768458d4556f69e8887d1cbbd3f3ab0c9eb0b66319052a6089a94fb769ecf80930ae87cf04d282eb4fcaa24e5959c3b535ff99ba2ecb0f71931035f37f9875c944bdbd741adb95d5fed3ddbb78585c21f58c3d74a6cc18418e8537e1b8").unwrap().try_into().unwrap(), + out_ciphertext: hex::decode("6295187eb1d8dc74a065d46ae2bc235a47e5914b4320419e1312157ca16f153269e44278ad6f999a3899dfa6d004ce685cd7759a33112b26e5359dc7fe7ec3d81429854b4bbf767857120d14019353e5").unwrap().try_into().unwrap(), + ock: None, + proprietary: BTreeMap::new(), + recipient: None, + rseed: None, + shared_secret: None, + value: None, + }, + rcv: None, + }, + Action { + cv: hex::decode("6c78ee94ced314a28898218fb3d9594ff97b96d7d92c71f9e1866731eddd3ca8").unwrap().try_into().unwrap(), + spend: orchard::Spend { + value: None, + witness: None, + alpha: Some(hex::decode("15716c9c0c9af80201b63a1b0a329fd9579824cfae4cd9f086848d729dd37cff").unwrap().try_into().unwrap()), + fvk: None, + proprietary: BTreeMap::new(), + recipient: None, + rho: None, + rseed: None, + nullifier: hex::decode("0e65a80237a3d3e1dcede4fe7632eec67254e0e1af721cd20fa8b9800263f508").unwrap().try_into().unwrap(), + rk: hex::decode("afa2899a1fc1f5d16639e162979b29bedbf84aeb0987a2d8143d10134a47f722").unwrap().try_into().unwrap(), + spend_auth_sig: None, + }, + output: orchard::Output { + cmx: hex::decode("c7e391d7deb77891735e12be5f63e8821a79636a774578706bf495bef678072b").unwrap().try_into().unwrap(), + ephemeral_key: hex::decode("b306bb760dc8b8018db27ee58072969d1665b98095b41034615d4ff62410800f").unwrap().try_into().unwrap(), + enc_ciphertext: hex::decode("572b855e2c2b872eb6d9e375831a34b486833a015d0d42876c8b8b47409aa67d238903a931539466b12645d0e7f18ad6637fc81152b145585511245a48b9e4a20069dcf3d10aef699388f6a1855567c5312d66a94724db45c10ae0bc4a6af7fa508b4184859a1bfc38dbed7258b39406a64af9a401ab9d921f74fd8fb2f44893458d9a0fd67c773a8d65ecffe2f0868755b8e359ab3b7bf6ebce2553745b96d31bdcea662188691f9fc12fd652b8528e6339924c66f12e39e4b1b3041fde91cef49b7c9f4c0201e22f712ecc599219acdc4d5c77b795ebe3c80a701e22780274c2f88298fa40af2bcba9b78b258e80bebf5bf962c82e020e7444aafa3c857f8fefe5c2c79627873e334af336defc71c772c472840228cd6a7a870ff16efc2204d232b1f4da4b17ca5c9dee367c7aecd0f1deb9ec65f6c03f26ec95c6e9f03f5da0419260be47703ac2a56467883a272858625cb64bd3c0e388a15197665493377984c78aee751bab65971ea0b511879b6339856d724780250843a34af9462c765ac5200b22b6a35341c73ef4da9fc82087f3fa9dfb6ce6434a1e60b6c15beedfa3a8ca2feeeb249fb73154d541c4ced12936fe5ab6b0ac989eee5d045a36659d31d7352f77db6c32b8a827a456ce93bcd8f69e9b3b17ba2f44016107a886392af6c413e54d3707008573d2b393693616dae726e2e1ae52e437a0a5bab14ffe5ea26df3be381770fa9fce263a0adfbf4bf5182826c573da06d83011e85dbb16866099de5dc79465f46b29552565eede84f36ae0b443ea05e46a97362be8796bb635549108").unwrap().try_into().unwrap(), + out_ciphertext: hex::decode("f60df073061724815f4ae663a99a6781fc5ca797390541172c5cf8b4fece3d45a07d97636853bdaec1758fa8ba339b935462ff4bc23ced395990a6551fcee705d092bcd33a0a68c41f2cd15d59128060").unwrap().try_into().unwrap(), + ock: None, + proprietary: BTreeMap::new(), + recipient: None, + rseed: None, + shared_secret: None, + value: None, + }, + rcv: None, + } + ], + flags: 3, + value_balance: 10000, + zkproof: None, + bsk: None, + }, + global: Global { + tx_version: V5_TX_VERSION, + version_group_id: V5_VERSION_GROUP_ID, + consensus_branch_id: 0xc2d6_d0b4, + lock_time: 0, + expiry_height: 2705733, + proprietary: BTreeMap::new(), + }, + }; + + let signed = pczt.sign(&signer).unwrap(); + + assert_eq!("274d411da4e2cdeab282ac5b61b6b2acb0d6edfe9b9fc6282c200ed621a581a1234b44710fedee313667cc315d896ec69bb0e233b9897bf3fea2820f84757419", hex::encode(signed.orchard.actions[0].spend.spend_auth_sig.unwrap())); + assert_eq!("cc49f7b09c5d2bb2ed55390da728e7a37639d461b040183a8ac87020d8236f1db920b3b162c41bfeba278c170702716e81db09320e4ce69fda4095c53091052f", hex::encode(signed.orchard.actions[1].spend.spend_auth_sig.unwrap())); + } +} diff --git a/rust/keystore/src/algorithms/zcash/mod.rs b/rust/keystore/src/algorithms/zcash/mod.rs index 11f84ec69..a915dca27 100644 --- a/rust/keystore/src/algorithms/zcash/mod.rs +++ b/rust/keystore/src/algorithms/zcash/mod.rs @@ -57,6 +57,7 @@ pub fn sign_message_orchard( let rng_seed = alpha.clone(); let rng = ChaCha8Rng::from_seed(rng_seed); let osk = SpendingKey::from_zip32_seed(seed, coin_type, account_id).unwrap(); + let osak = SpendAuthorizingKey::from(&osk); let randm = Fq::from_repr(alpha) .into_option() diff --git a/rust/zcash_vendor/src/orchard/address.rs b/rust/zcash_vendor/src/orchard/address.rs index 2fd37f253..93f2031cf 100644 --- a/rust/zcash_vendor/src/orchard/address.rs +++ b/rust/zcash_vendor/src/orchard/address.rs @@ -19,7 +19,7 @@ pub struct Address { } impl Address { - pub(crate) fn from_parts(d: Diversifier, pk_d: DiversifiedTransmissionKey) -> Self { + pub fn from_parts(d: Diversifier, pk_d: DiversifiedTransmissionKey) -> Self { // We assume here that pk_d is correctly-derived from d. We ensure this for // internal APIs. For parsing from raw byte encodings, we assume that users aren't // modifying internals of encoded address formats. If they do, that can result in @@ -32,11 +32,11 @@ impl Address { self.d } - pub(crate) fn g_d(&self) -> NonIdentityPallasPoint { + pub fn g_d(&self) -> NonIdentityPallasPoint { diversify_hash(self.d.as_array()) } - pub(crate) fn pk_d(&self) -> &DiversifiedTransmissionKey { + pub fn pk_d(&self) -> &DiversifiedTransmissionKey { &self.pk_d } diff --git a/rust/zcash_vendor/src/orchard/constants.rs b/rust/zcash_vendor/src/orchard/constants.rs index 5fac7e1cc..5aa3450dd 100644 --- a/rust/zcash_vendor/src/orchard/constants.rs +++ b/rust/zcash_vendor/src/orchard/constants.rs @@ -1,7 +1,7 @@ pub const COMMIT_IVK_PERSONALIZATION: &str = "z.cash:Orchard-CommitIvk"; /// $\ell^\mathsf{Orchard}_\mathsf{base}$ -pub(crate) const L_ORCHARD_BASE: usize = 255; +pub const L_ORCHARD_BASE: usize = 255; /// SWU hash-to-curve personalization for the group hash for key diversification pub const KEY_DIVERSIFICATION_PERSONALIZATION: &str = "z.cash:Orchard-gd"; \ No newline at end of file diff --git a/rust/zcash_vendor/src/orchard/keys.rs b/rust/zcash_vendor/src/orchard/keys.rs index be4d714cc..4c14d07f3 100644 --- a/rust/zcash_vendor/src/orchard/keys.rs +++ b/rust/zcash_vendor/src/orchard/keys.rs @@ -74,7 +74,7 @@ impl SpendingKey { /// derived according to [ZIP 32]. /// /// [ZIP 32]: https://zips.z.cash/zip-0032 - pub(crate) fn random(rng: &mut impl RngCore) -> Self { + pub fn random(rng: &mut impl RngCore) -> Self { loop { let mut bytes = [0; 32]; rng.fill_bytes(&mut bytes); @@ -208,7 +208,7 @@ impl SpendValidatingKey { /// 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] { + pub fn to_bytes(&self) -> [u8; 32] { // This is correct because the wrapped point must have ỹ = 0, and // so the point repr is the same as I2LEOSP of its x-coordinate. let b = <[u8; 32]>::from(&self.0); @@ -220,7 +220,7 @@ impl SpendValidatingKey { /// /// Returns `None` if the given slice does not contain a valid spend validating key. #[cfg_attr(feature = "unstable-frost", visibility::make(pub))] - pub(crate) fn from_bytes(bytes: &[u8]) -> Option { + pub fn from_bytes(bytes: &[u8]) -> Option { <[u8; 32]>::try_from(bytes) .ok() .and_then(|b| { @@ -246,10 +246,10 @@ impl SpendValidatingKey { /// [`Note`]: crate::note::Note /// [orchardkeycomponents]: https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents #[derive(Copy, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] -pub(crate) struct NullifierDerivingKey(pallas::Base); +pub struct NullifierDerivingKey(pallas::Base); impl NullifierDerivingKey { - pub(crate) fn inner(&self) -> pallas::Base { + pub fn inner(&self) -> pallas::Base { self.0 } } @@ -262,11 +262,11 @@ impl From<&SpendingKey> for NullifierDerivingKey { impl NullifierDerivingKey { /// Converts this nullifier deriving key to its serialized form. - pub(crate) fn to_bytes(self) -> [u8; 32] { + pub fn to_bytes(self) -> [u8; 32] { <[u8; 32]>::from(self.0) } - pub(crate) fn from_bytes(bytes: &[u8]) -> Option { + pub fn from_bytes(bytes: &[u8]) -> Option { let nk_bytes = <[u8; 32]>::try_from(bytes).ok()?; let nk = pallas::Base::from_repr(nk_bytes).map(NullifierDerivingKey); if nk.is_some().into() { @@ -283,7 +283,7 @@ impl NullifierDerivingKey { /// /// [orchardkeycomponents]: https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents #[derive(Copy, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] -pub(crate) struct CommitIvkRandomness(pallas::Scalar); +pub struct CommitIvkRandomness(pallas::Scalar); impl From<&SpendingKey> for CommitIvkRandomness { fn from(sk: &SpendingKey) -> Self { @@ -292,16 +292,16 @@ impl From<&SpendingKey> for CommitIvkRandomness { } impl CommitIvkRandomness { - pub(crate) fn inner(&self) -> pallas::Scalar { + pub fn inner(&self) -> pallas::Scalar { self.0 } /// Converts this nullifier deriving key to its serialized form. - pub(crate) fn to_bytes(self) -> [u8; 32] { + pub fn to_bytes(self) -> [u8; 32] { <[u8; 32]>::from(self.0) } - pub(crate) fn from_bytes(bytes: &[u8]) -> Option { + pub fn from_bytes(bytes: &[u8]) -> Option { let rivk_bytes = <[u8; 32]>::try_from(bytes).ok()?; let rivk = pallas::Scalar::from_repr(rivk_bytes).map(CommitIvkRandomness); if rivk.is_some().into() { @@ -350,12 +350,12 @@ impl From for SpendValidatingKey { } impl FullViewingKey { - pub(crate) fn nk(&self) -> &NullifierDerivingKey { + pub fn nk(&self) -> &NullifierDerivingKey { &self.nk } /// Returns either `rivk` or `rivk_internal` based on `scope`. - pub(crate) fn rivk(&self, scope: Scope) -> CommitIvkRandomness { + pub fn rivk(&self, scope: Scope) -> CommitIvkRandomness { match scope { Scope::External => self.rivk, Scope::Internal => { @@ -469,7 +469,7 @@ impl FullViewingKey { /// /// [orchardkeycomponents]: https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] -pub(crate) struct DiversifierKey([u8; 32]); +pub struct DiversifierKey([u8; 32]); impl DiversifierKey { /// Returns the diversifier at the given index. @@ -728,7 +728,7 @@ impl AsRef<[u8; 32]> for OutgoingViewingKey { pub struct DiversifiedTransmissionKey(NonIdentityPallasPoint); impl DiversifiedTransmissionKey { - pub(crate) fn inner(&self) -> NonIdentityPallasPoint { + pub fn inner(&self) -> NonIdentityPallasPoint { self.0 } } @@ -737,18 +737,18 @@ impl DiversifiedTransmissionKey { /// Defined in [Zcash Protocol Spec § 4.2.3: Orchard Key Components][orchardkeycomponents]. /// /// [orchardkeycomponents]: https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents - pub(crate) fn derive(ivk: &PreparedIncomingViewingKey, d: &Diversifier) -> Self { + pub fn derive(ivk: &PreparedIncomingViewingKey, d: &Diversifier) -> Self { let g_d = PreparedNonIdentityBase::new(diversify_hash(d.as_array())); DiversifiedTransmissionKey(ka_orchard_prepared(&ivk.0, &g_d)) } /// $abst_P(bytes)$ - pub(crate) fn from_bytes(bytes: &[u8; 32]) -> CtOption { + pub fn from_bytes(bytes: &[u8; 32]) -> CtOption { NonIdentityPallasPoint::from_bytes(bytes).map(DiversifiedTransmissionKey) } /// $repr_P(self)$ - pub(crate) fn to_bytes(self) -> [u8; 32] { + pub fn to_bytes(self) -> [u8; 32] { self.0.to_bytes() } } @@ -772,7 +772,7 @@ impl ConditionallySelectable for DiversifiedTransmissionKey { /// /// [concreteorchardkeyagreement]: https://zips.z.cash/protocol/nu5.pdf#concreteorchardkeyagreement #[derive(Debug)] -pub struct EphemeralSecretKey(pub(crate) NonZeroPallasScalar); +pub struct EphemeralSecretKey(pub NonZeroPallasScalar); impl ConstantTimeEq for EphemeralSecretKey { fn ct_eq(&self, other: &Self) -> subtle::Choice { @@ -781,15 +781,15 @@ impl ConstantTimeEq for EphemeralSecretKey { } impl EphemeralSecretKey { - pub(crate) fn from_bytes(bytes: &[u8; 32]) -> CtOption { + pub fn from_bytes(bytes: &[u8; 32]) -> CtOption { NonZeroPallasScalar::from_bytes(bytes).map(EphemeralSecretKey) } - pub(crate) fn derive_public(&self, g_d: NonIdentityPallasPoint) -> EphemeralPublicKey { + pub fn derive_public(&self, g_d: NonIdentityPallasPoint) -> EphemeralPublicKey { EphemeralPublicKey(ka_orchard(&self.0, &g_d)) } - pub(crate) fn agree(&self, pk_d: &DiversifiedTransmissionKey) -> SharedSecret { + pub fn agree(&self, pk_d: &DiversifiedTransmissionKey) -> SharedSecret { SharedSecret(ka_orchard(&self.0, &pk_d.0)) } } @@ -808,15 +808,15 @@ impl EphemeralSecretKey { pub struct EphemeralPublicKey(NonIdentityPallasPoint); impl EphemeralPublicKey { - pub(crate) fn from_bytes(bytes: &[u8; 32]) -> CtOption { + pub fn from_bytes(bytes: &[u8; 32]) -> CtOption { NonIdentityPallasPoint::from_bytes(bytes).map(EphemeralPublicKey) } - pub(crate) fn to_bytes(&self) -> EphemeralKeyBytes { + pub fn to_bytes(&self) -> EphemeralKeyBytes { EphemeralKeyBytes(self.0.to_bytes()) } - pub(crate) fn agree(&self, ivk: &IncomingViewingKey) -> SharedSecret { + pub fn agree(&self, ivk: &IncomingViewingKey) -> SharedSecret { SharedSecret(ka_orchard(&ivk.ivk.0, &self.0)) } } @@ -826,11 +826,11 @@ impl EphemeralPublicKey { pub struct PreparedEphemeralPublicKey(PreparedNonIdentityBase); impl PreparedEphemeralPublicKey { - pub(crate) fn new(epk: EphemeralPublicKey) -> Self { + pub fn new(epk: EphemeralPublicKey) -> Self { PreparedEphemeralPublicKey(PreparedNonIdentityBase::new(epk.0)) } - pub(crate) fn agree(&self, ivk: &PreparedIncomingViewingKey) -> SharedSecret { + pub fn agree(&self, ivk: &PreparedIncomingViewingKey) -> SharedSecret { SharedSecret(ka_orchard_prepared(&ivk.0, &self.0)) } } @@ -846,12 +846,12 @@ pub struct SharedSecret(NonIdentityPallasPoint); impl SharedSecret { /// For checking test vectors only. #[cfg(test)] - pub(crate) fn to_bytes(&self) -> [u8; 32] { + pub fn to_bytes(&self) -> [u8; 32] { self.0.to_bytes() } /// Only for use in batched note encryption. - pub(crate) fn batch_to_affine( + pub fn batch_to_affine( shared_secrets: Vec>, ) -> impl Iterator> { // Filter out the positions for which ephemeral_key was not a valid encoding. @@ -874,12 +874,12 @@ impl SharedSecret { /// Defined in [Zcash Protocol Spec § 5.4.5.6: Orchard Key Agreement][concreteorchardkdf]. /// /// [concreteorchardkdf]: https://zips.z.cash/protocol/nu5.pdf#concreteorchardkdf - pub(crate) fn kdf_orchard(self, ephemeral_key: &EphemeralKeyBytes) -> Blake2bHash { + pub fn kdf_orchard(self, ephemeral_key: &EphemeralKeyBytes) -> Blake2bHash { Self::kdf_orchard_inner(self.0.to_affine(), ephemeral_key) } /// Only for direct use in batched note encryption. - pub(crate) fn kdf_orchard_inner( + pub fn kdf_orchard_inner( secret: pallas::Affine, ephemeral_key: &EphemeralKeyBytes, ) -> Blake2bHash { diff --git a/rust/zcash_vendor/src/orchard/mod.rs b/rust/zcash_vendor/src/orchard/mod.rs index 019e164f8..538394171 100644 --- a/rust/zcash_vendor/src/orchard/mod.rs +++ b/rust/zcash_vendor/src/orchard/mod.rs @@ -4,6 +4,6 @@ pub mod keys; pub mod prf_expand; pub mod redpallas; pub mod spec; -pub(crate) mod zip32; +pub mod zip32; pub use address::Address; diff --git a/rust/zcash_vendor/src/orchard/redpallas.rs b/rust/zcash_vendor/src/orchard/redpallas.rs index 1d8809b3a..a00c8de1b 100644 --- a/rust/zcash_vendor/src/orchard/redpallas.rs +++ b/rust/zcash_vendor/src/orchard/redpallas.rs @@ -161,7 +161,7 @@ impl From<&Signature> for [u8; 64] { } } -pub(crate) mod private { +pub mod private { use super::{Binding, SpendAuth}; pub trait Sealed {} diff --git a/rust/zcash_vendor/src/orchard/spec.rs b/rust/zcash_vendor/src/orchard/spec.rs index 80f7be27d..fae356196 100644 --- a/rust/zcash_vendor/src/orchard/spec.rs +++ b/rust/zcash_vendor/src/orchard/spec.rs @@ -11,7 +11,7 @@ use subtle::{ConditionallySelectable, CtOption}; /// A Pallas point that is guaranteed to not be the identity. #[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub(crate) struct NonIdentityPallasPoint(pallas::Point); +pub struct NonIdentityPallasPoint(pallas::Point); impl Default for NonIdentityPallasPoint { fn default() -> Self { @@ -26,7 +26,7 @@ impl ConditionallySelectable for NonIdentityPallasPoint { } impl NonIdentityPallasPoint { - pub(crate) fn from_bytes(bytes: &[u8; 32]) -> CtOption { + pub fn from_bytes(bytes: &[u8; 32]) -> CtOption { pallas::Point::from_bytes(bytes) .and_then(|p| CtOption::new(NonIdentityPallasPoint(p), !p.is_identity())) } @@ -42,7 +42,7 @@ impl Deref for NonIdentityPallasPoint { /// An integer in [1..q_P]. #[derive(Clone, Copy, Debug)] -pub(crate) struct NonZeroPallasBase(pallas::Base); +pub struct NonZeroPallasBase(pallas::Base); impl Default for NonZeroPallasBase { fn default() -> Self { @@ -57,15 +57,15 @@ impl ConditionallySelectable for NonZeroPallasBase { } impl NonZeroPallasBase { - pub(crate) fn from_bytes(bytes: &[u8; 32]) -> CtOption { + pub fn from_bytes(bytes: &[u8; 32]) -> CtOption { pallas::Base::from_repr(*bytes).and_then(NonZeroPallasBase::from_base) } - pub(crate) fn to_bytes(self) -> [u8; 32] { + pub fn to_bytes(self) -> [u8; 32] { self.0.to_repr() } - pub(crate) fn from_base(b: pallas::Base) -> CtOption { + pub fn from_base(b: pallas::Base) -> CtOption { CtOption::new(NonZeroPallasBase(b), !b.is_zero()) } @@ -82,7 +82,7 @@ impl NonZeroPallasBase { /// An integer in [1..r_P]. #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] -pub(crate) struct NonZeroPallasScalar(pallas::Scalar); +pub struct NonZeroPallasScalar(pallas::Scalar); impl Default for NonZeroPallasScalar { fn default() -> Self { @@ -103,11 +103,11 @@ impl ConditionallySelectable for NonZeroPallasScalar { } impl NonZeroPallasScalar { - pub(crate) fn from_bytes(bytes: &[u8; 32]) -> CtOption { + pub fn from_bytes(bytes: &[u8; 32]) -> CtOption { pallas::Scalar::from_repr(*bytes).and_then(NonZeroPallasScalar::from_scalar) } - pub(crate) fn from_scalar(s: pallas::Scalar) -> CtOption { + pub fn from_scalar(s: pallas::Scalar) -> CtOption { CtOption::new(NonZeroPallasScalar(s), !s.is_zero()) } @@ -133,19 +133,19 @@ impl Deref for NonZeroPallasScalar { const PREPARED_WINDOW_SIZE: usize = 4; #[derive(Clone, Debug)] -pub(crate) struct PreparedNonIdentityBase(WnafBase); +pub struct PreparedNonIdentityBase(WnafBase); impl PreparedNonIdentityBase { - pub(crate) fn new(base: NonIdentityPallasPoint) -> Self { + pub fn new(base: NonIdentityPallasPoint) -> Self { PreparedNonIdentityBase(WnafBase::new(base.0)) } } #[derive(Clone, Debug)] -pub(crate) struct PreparedNonZeroScalar(WnafScalar); +pub struct PreparedNonZeroScalar(WnafScalar); impl PreparedNonZeroScalar { - pub(crate) fn new(scalar: &NonZeroPallasScalar) -> Self { + pub fn new(scalar: &NonZeroPallasScalar) -> Self { PreparedNonZeroScalar(WnafScalar::new(scalar)) } } @@ -155,7 +155,7 @@ impl PreparedNonZeroScalar { /// Defined in [Zcash Protocol Spec § 4.2.3: Orchard Key Components][orchardkeycomponents]. /// /// [orchardkeycomponents]: https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents -pub(crate) fn to_base(x: [u8; 64]) -> pallas::Base { +pub fn to_base(x: [u8; 64]) -> pallas::Base { pallas::Base::from_uniform_bytes(&x) } @@ -164,7 +164,7 @@ pub(crate) fn to_base(x: [u8; 64]) -> pallas::Base { /// Defined in [Zcash Protocol Spec § 4.2.3: Orchard Key Components][orchardkeycomponents]. /// /// [orchardkeycomponents]: https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents -pub(crate) fn to_scalar(x: [u8; 64]) -> pallas::Scalar { +pub fn to_scalar(x: [u8; 64]) -> pallas::Scalar { pallas::Scalar::from_uniform_bytes(&x) } @@ -172,14 +172,14 @@ pub(crate) fn to_scalar(x: [u8; 64]) -> pallas::Scalar { /// /// This requires no modular reduction because Pallas' base field is smaller than its /// scalar field. -pub(crate) fn mod_r_p(x: pallas::Base) -> pallas::Scalar { +pub fn mod_r_p(x: pallas::Base) -> pallas::Scalar { pallas::Scalar::from_repr(x.to_repr()).unwrap() } /// Defined in [Zcash Protocol Spec § 5.4.8.4: Sinsemilla commitments][concretesinsemillacommit]. /// /// [concretesinsemillacommit]: https://zips.z.cash/protocol/protocol.pdf#concretesinsemillacommit -pub(crate) fn commit_ivk( +pub fn commit_ivk( ak: &pallas::Base, nk: &pallas::Base, rivk: &pallas::Scalar, @@ -198,7 +198,7 @@ pub(crate) fn commit_ivk( /// Defined in [Zcash Protocol Spec § 5.4.1.6: DiversifyHash^Sapling and DiversifyHash^Orchard Hash Functions][concretediversifyhash]. /// /// [concretediversifyhash]: https://zips.z.cash/protocol/nu5.pdf#concretediversifyhash -pub(crate) fn diversify_hash(d: &[u8; 11]) -> NonIdentityPallasPoint { +pub fn diversify_hash(d: &[u8; 11]) -> NonIdentityPallasPoint { let hasher = pallas::Point::hash_to_curve(KEY_DIVERSIFICATION_PERSONALIZATION); let g_d = hasher(d); // If the identity occurs, we replace it with a different fixed point. @@ -209,7 +209,7 @@ pub(crate) fn diversify_hash(d: &[u8; 11]) -> NonIdentityPallasPoint { /// Defined in [Zcash Protocol Spec § 5.4.5.5: Orchard Key Agreement][concreteorchardkeyagreement]. /// /// [concreteorchardkeyagreement]: https://zips.z.cash/protocol/nu5.pdf#concreteorchardkeyagreement -pub(crate) fn ka_orchard( +pub fn ka_orchard( sk: &NonZeroPallasScalar, b: &NonIdentityPallasPoint, ) -> NonIdentityPallasPoint { @@ -222,7 +222,7 @@ pub(crate) fn ka_orchard( /// Defined in [Zcash Protocol Spec § 5.4.5.5: Orchard Key Agreement][concreteorchardkeyagreement]. /// /// [concreteorchardkeyagreement]: https://zips.z.cash/protocol/nu5.pdf#concreteorchardkeyagreement -pub(crate) fn ka_orchard_prepared( +pub fn ka_orchard_prepared( sk: &PreparedNonZeroScalar, b: &PreparedNonIdentityBase, ) -> NonIdentityPallasPoint { @@ -234,7 +234,7 @@ pub(crate) fn ka_orchard_prepared( /// Defined in [Zcash Protocol Spec § 5.4.9.7: Coordinate Extractor for Pallas][concreteextractorpallas]. /// /// [concreteextractorpallas]: https://zips.z.cash/protocol/nu5.pdf#concreteextractorpallas -pub(crate) fn extract_p(point: &pallas::Point) -> pallas::Base { +pub fn extract_p(point: &pallas::Point) -> pallas::Base { point .to_affine() .coordinates() @@ -247,6 +247,6 @@ pub(crate) fn extract_p(point: &pallas::Point) -> pallas::Base { /// Defined in [Zcash Protocol Spec § 5.4.9.7: Coordinate Extractor for Pallas][concreteextractorpallas]. /// /// [concreteextractorpallas]: https://zips.z.cash/protocol/nu5.pdf#concreteextractorpallas -pub(crate) fn extract_p_bottom(point: CtOption) -> CtOption { +pub fn extract_p_bottom(point: CtOption) -> CtOption { point.map(|p| extract_p(&p)) } \ No newline at end of file diff --git a/rust/zcash_vendor/src/orchard/zip32.rs b/rust/zcash_vendor/src/orchard/zip32.rs index 99f675dee..da8e03346 100644 --- a/rust/zcash_vendor/src/orchard/zip32.rs +++ b/rust/zcash_vendor/src/orchard/zip32.rs @@ -105,7 +105,7 @@ impl KeyIndex { /// /// [orchardextendedkeys]: https://zips.z.cash/zip-0032#orchard-extended-keys #[derive(Debug, Clone)] -pub(crate) struct ExtendedSpendingKey { +pub struct ExtendedSpendingKey { depth: u8, parent_fvk_tag: FvkTag, child_index: KeyIndex, diff --git a/rust/zcash_vendor/src/pczt/common.rs b/rust/zcash_vendor/src/pczt/common.rs index 4890d19c2..96b53f1f0 100644 --- a/rust/zcash_vendor/src/pczt/common.rs +++ b/rust/zcash_vendor/src/pczt/common.rs @@ -1,31 +1,31 @@ use alloc::{collections::BTreeMap, string::String, vec::Vec}; /// Global fields that are relevant to the transaction as a whole. -#[derive(Clone)] -pub(crate) struct Global { +#[derive(Clone, Debug)] +pub struct Global { // // Transaction effecting data. // // These are required fields that are part of the final transaction, and are filled in // by the Creator when initializing the PCZT. // - pub(crate) tx_version: u32, - pub(crate) version_group_id: u32, + pub tx_version: u32, + pub version_group_id: u32, /// The consensus branch ID for the chain in which this transaction will be mined. /// /// Non-optional because this commits to the set of consensus rules that will apply to /// the transaction; differences therein can affect every role. - pub(crate) consensus_branch_id: u32, + pub consensus_branch_id: u32, /// TODO: In PSBT this is `fallback_lock_time`; decide whether this should have the /// same semantics. - pub(crate) lock_time: u32, - pub(crate) expiry_height: u32, + pub lock_time: u32, + pub expiry_height: u32, - pub(crate) proprietary: BTreeMap>, + pub proprietary: BTreeMap>, } impl Global { - pub(crate) fn merge(self, other: Self) -> Option { + pub fn merge(self, other: Self) -> Option { let Self { tx_version, version_group_id, diff --git a/rust/zcash_vendor/src/pczt/mod.rs b/rust/zcash_vendor/src/pczt/mod.rs index 92c1c5541..08a4d8fdf 100644 --- a/rust/zcash_vendor/src/pczt/mod.rs +++ b/rust/zcash_vendor/src/pczt/mod.rs @@ -89,18 +89,18 @@ //! - Creates bindingSig and extracts the final transaction. -mod common; -mod orchard; -mod sapling; -mod transparent; +pub mod common; +pub mod orchard; +pub mod sapling; +pub mod transparent; pub mod pczt_ext; -const V5_TX_VERSION: u32 = 5; -const V5_VERSION_GROUP_ID: u32 = 0x26A7270A; +pub const V5_TX_VERSION: u32 = 5; +pub const V5_VERSION_GROUP_ID: u32 = 0x26A7270A; /// A partially-created Zcash transaction. -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct Pczt { /// The version of this PCZT format, for storage. pub version: Version, @@ -128,8 +128,8 @@ pub struct Pczt { /// TODO: We might just define the version as a prefix byte included within the encoding, /// and then permit the entire rest of the format to change arbitrarily in new versions /// (though it would likely instead be altered via predictable diffs). -#[derive(Clone, PartialEq, Eq)] -enum Version { +#[derive(Clone, PartialEq, Eq, Debug)] +pub enum Version { V0, } diff --git a/rust/zcash_vendor/src/pczt/orchard.rs b/rust/zcash_vendor/src/pczt/orchard.rs index ebf51a244..51f83f9c1 100644 --- a/rust/zcash_vendor/src/pczt/orchard.rs +++ b/rust/zcash_vendor/src/pczt/orchard.rs @@ -3,13 +3,13 @@ use alloc::{collections::BTreeMap, string::String, vec::Vec}; use super::merge_optional; /// PCZT fields that are specific to producing the transaction's Orchard bundle (if any). -#[derive(Clone)] -pub(crate) struct Bundle { +#[derive(Clone, Debug)] +pub struct Bundle { /// The Orchard actions in this bundle. /// /// Entries are added by the Constructor, and modified by an Updater, IO Finalizer, /// Signer, Combiner, or Spend Finalizer. - pub(crate) actions: Vec, + pub actions: Vec, /// The flags for the Orchard bundle. /// @@ -20,45 +20,45 @@ pub(crate) struct Bundle { /// /// This is set by the Creator. The Constructor MUST only add spends and outputs that /// are consistent with these flags (i.e. are dummies as appropriate). - pub(crate) flags: u8, + pub flags: u8, /// The net value of Orchard spends minus outputs. /// /// This is initialized by the Creator, and updated by the Constructor as spends or /// outputs are added to the PCZT. It enables per-spend and per-output values to be /// redacted from the PCZT after they are no longer necessary. - pub(crate) value_balance: i64, + pub value_balance: i64, /// The Orchard anchor for this transaction. /// /// TODO: Should this be non-optional and set by the Creator (which would be simpler)? /// Or do we need a separate role that picks the anchor, which runs before the /// Constructor adds spends? - pub(crate) anchor: Option<[u8; 32]>, + pub anchor: Option<[u8; 32]>, /// The Orchard bundle proof. /// /// This is `None` until it is set by the Prover. - pub(crate) zkproof: Option>, + pub zkproof: Option>, /// The Orchard binding signature signing key. /// /// - This is `None` until it is set by the IO Finalizer. /// - The Transaction Extractor uses this to produce the binding signature. - pub(crate) bsk: Option<[u8; 32]>, + pub bsk: Option<[u8; 32]>, } -#[derive(Clone)] -pub(crate) struct Action { +#[derive(Clone, Debug)] +pub struct Action { // // Action effecting data. // // These are required fields that are part of the final transaction, and are filled in // by the Constructor when adding an output. // - pub(crate) cv: [u8; 32], - pub(crate) spend: Spend, - pub(crate) output: Output, + pub cv: [u8; 32], + pub spend: Spend, + pub output: Output, /// The value commitment randomness. /// @@ -69,31 +69,31 @@ pub(crate) struct Action { /// /// This opens `cv` for all participants. For Signers who don't need this information, /// or after proofs / signatures have been applied, this can be redacted. - pub(crate) rcv: Option<[u8; 32]>, + pub rcv: Option<[u8; 32]>, } /// Information about a Sapling spend within a transaction. -#[derive(Clone)] -pub(crate) struct Spend { +#[derive(Clone, Debug)] +pub struct Spend { // // Spend-specific Action effecting data. // // These are required fields that are part of the final transaction, and are filled in // by the Constructor when adding an output. // - pub(crate) nullifier: [u8; 32], - pub(crate) rk: [u8; 32], + pub nullifier: [u8; 32], + pub rk: [u8; 32], /// The spend authorization signature. /// /// This is set by the Signer. - pub(crate) spend_auth_sig: Option<[u8; 64]>, + pub spend_auth_sig: Option<[u8; 64]>, /// The address that received the note being spent. /// /// - This is set by the Constructor (or Updater?). /// - This is required by the Prover. - pub(crate) recipient: Option<[u8; 43]>, + pub recipient: Option<[u8; 43]>, /// The value of the input being spent. /// @@ -103,7 +103,7 @@ pub(crate) struct Spend { /// /// This exposes the input value to all participants. For Signers who don't need this /// information, or after signatures have been applied, this can be redacted. - pub(crate) value: Option, + pub value: Option, /// The rho value for the note being spent. /// @@ -112,25 +112,25 @@ pub(crate) struct Spend { /// /// TODO: This could be merged with `rseed` into a tuple. `recipient` and `value` are /// separate because they might need to be independently redacted. (For which role?) - pub(crate) rho: Option<[u8; 32]>, + pub rho: Option<[u8; 32]>, /// The seed randomness for the note being spent. /// /// - This is set by the Constructor. /// - This is required by the Prover. - pub(crate) rseed: Option<[u8; 32]>, + pub rseed: Option<[u8; 32]>, /// The full viewing key that received the note being spent. /// /// - This is set by the Updater. /// - This is required by the Prover. - pub(crate) fvk: Option<[u8; 96]>, + pub fvk: Option<[u8; 96]>, /// A witness from the note to the bundle's anchor. /// /// - This is set by the Updater. /// - This is required by the Prover. - pub(crate) witness: Option<(u32, [[u8; 32]; 32])>, + pub witness: Option<(u32, [[u8; 32]; 32])>, /// The spend authorization randomizer. /// @@ -138,35 +138,35 @@ pub(crate) struct Spend { /// - This is required by the Signer for creating `spend_auth_sig`, and may be used to /// validate `rk`. /// - After`zkproof` / `spend_auth_sig` has been set, this can be redacted. - pub(crate) alpha: Option<[u8; 32]>, + pub alpha: Option<[u8; 32]>, // TODO derivation path // TODO FROST - pub(crate) proprietary: BTreeMap>, + pub proprietary: BTreeMap>, } /// Information about an Orchard output within a transaction. -#[derive(Clone)] -pub(crate) struct Output { +#[derive(Clone, Debug)] +pub struct Output { // // Output-specific Action effecting data. // // These are required fields that are part of the final transaction, and are filled in // by the Constructor when adding an output. // - pub(crate) cmx: [u8; 32], - pub(crate) ephemeral_key: [u8; 32], + pub cmx: [u8; 32], + pub ephemeral_key: [u8; 32], /// TODO: Should it be possible to choose the memo _value_ after defining an Output? - pub(crate) enc_ciphertext: [u8; 580], - pub(crate) out_ciphertext: [u8; 80], + pub enc_ciphertext: [u8; 580], + pub out_ciphertext: [u8; 80], /// The address that will receive the output. /// /// - This is set by the Constructor. /// - This is required by the Prover. - pub(crate) recipient: Option<[u8; 43]>, + pub recipient: Option<[u8; 43]>, /// The value of the output. /// @@ -175,7 +175,7 @@ pub(crate) struct Output { /// /// This exposes the value to all participants. For Signers who don't need this /// information, we can drop the values and compress the rcvs into the bsk global. - pub(crate) value: Option, + pub value: Option, /// The seed randomness for the output. /// @@ -185,14 +185,14 @@ pub(crate) struct Output { /// TODO: This could instead be decrypted from `enc_ciphertext` if `shared_secret` /// were required by the Prover. Likewise for `recipient` and `value`; is there ever a /// need for these to be independently redacted though? - pub(crate) rseed: Option<[u8; 32]>, + pub rseed: Option<[u8; 32]>, /// The symmetric shared secret used to encrypt `enc_ciphertext`. /// /// This enables Signers to verify that `enc_ciphertext` is correctly encrypted (and /// contains a note plaintext matching the public commitments), and to confirm the /// value of the memo. - pub(crate) shared_secret: Option<[u8; 32]>, + pub shared_secret: Option<[u8; 32]>, /// The `ock` value used to encrypt `out_ciphertext`. /// @@ -200,18 +200,18 @@ pub(crate) struct Output { /// /// This may be `None` if the Constructor added the output using an OVK policy of /// "None", to make the output unrecoverable from the chain by the sender. - pub(crate) ock: Option<[u8; 32]>, + pub ock: Option<[u8; 32]>, // TODO derivation path - pub(crate) proprietary: BTreeMap>, + pub proprietary: BTreeMap>, } impl Bundle { /// Merges this bundle with another. /// /// Returns `None` if the bundles have conflicting data. - pub(crate) fn merge(mut self, other: Self) -> Option { + pub fn merge(mut self, other: Self) -> Option { // Destructure `other` to ensure we handle everything. let Self { mut actions, diff --git a/rust/zcash_vendor/src/pczt/pczt_ext.rs b/rust/zcash_vendor/src/pczt/pczt_ext.rs index 28118bccd..b5d88a485 100644 --- a/rust/zcash_vendor/src/pczt/pczt_ext.rs +++ b/rust/zcash_vendor/src/pczt/pczt_ext.rs @@ -13,7 +13,7 @@ const ZCASH_TX_PERSONALIZATION_PREFIX: &[u8; 12] = b"ZcashTxHash_"; // TxId level 1 node personalization const ZCASH_HEADERS_HASH_PERSONALIZATION: &[u8; 16] = b"ZTxIdHeadersHash"; -pub(crate) const ZCASH_TRANSPARENT_HASH_PERSONALIZATION: &[u8; 16] = b"ZTxIdTranspaHash"; +pub const ZCASH_TRANSPARENT_HASH_PERSONALIZATION: &[u8; 16] = b"ZTxIdTranspaHash"; const ZCASH_SAPLING_HASH_PERSONALIZATION: &[u8; 16] = b"ZTxIdSaplingHash"; #[cfg(zcash_unstable = "zfuture")] const ZCASH_TZE_HASH_PERSONALIZATION: &[u8; 16] = b"ZTxIdTZE____Hash"; @@ -191,7 +191,7 @@ impl Pczt { h.update(mh.finalize().as_bytes()); h.update(nh.finalize().as_bytes()); h.update(&[self.orchard.flags]); - h.update(&self.orchard.value_balance.to_le_bytes()); + h.update(&self.orchard.value_balance.to_le_bytes()); h.update(&self.orchard.anchor.unwrap()); h.finalize() } @@ -373,8 +373,8 @@ impl Pczt { pczt.orchard.actions.iter_mut().try_for_each(|action| { let signature = signer.sign_orchard( self.sheilded_sig_commitment().as_bytes(), - pczt.orchard.anchor.unwrap(), - "".to_string(), + action.spend.alpha.unwrap(), + "m/44'/133'/0'".to_string(), )?; action.spend.spend_auth_sig = Some(signature); Ok(()) @@ -386,9 +386,10 @@ impl Pczt { #[cfg(test)] mod tests { extern crate std; - use std::println; - use alloc::{collections::btree_map::BTreeMap, vec::{Vec}}; use alloc::vec; + use alloc::{collections::btree_map::BTreeMap, vec::Vec}; + use secp256k1::Message; + use std::println; use crate::pczt::{ self, @@ -492,6 +493,9 @@ mod tests { }; let hash = pczt.sheilded_sig_commitment(); - assert_eq!("3840e39aef20acc050a509658397bbaa9500370967e37fe30d18e5fba05aba81", hex::encode(hash.as_bytes())); + assert_eq!( + "3840e39aef20acc050a509658397bbaa9500370967e37fe30d18e5fba05aba81", + hex::encode(hash.as_bytes()) + ); } } diff --git a/rust/zcash_vendor/src/pczt/sapling.rs b/rust/zcash_vendor/src/pczt/sapling.rs index 3a9c32d4f..28f27dd72 100644 --- a/rust/zcash_vendor/src/pczt/sapling.rs +++ b/rust/zcash_vendor/src/pczt/sapling.rs @@ -5,60 +5,60 @@ use super::merge_optional; const GROTH_PROOF_SIZE: usize = 48 + 96 + 48; /// PCZT fields that are specific to producing the transaction's Sapling bundle (if any). -#[derive(Clone)] -pub(crate) struct Bundle { - pub(crate) spends: Vec, - pub(crate) outputs: Vec, +#[derive(Clone, Debug)] +pub struct Bundle { + pub spends: Vec, + pub outputs: Vec, /// The net value of Sapling spends minus outputs. /// /// This is initialized by the Creator, and updated by the Constructor as spends or /// outputs are added to the PCZT. It enables per-spend and per-output values to be /// redacted from the PCZT after they are no longer necessary. - pub(crate) value_balance: u64, + pub value_balance: u64, /// The Sapling anchor for this transaction. /// /// TODO: Should this be non-optional and set by the Creator (which would be simpler)? /// Or do we need a separate role that picks the anchor, which runs before the /// Constructor adds spends? - pub(crate) anchor: Option<[u8; 32]>, + pub anchor: Option<[u8; 32]>, /// The Sapling binding signature signing key. /// /// - This is `None` until it is set by the IO Finalizer. /// - The Transaction Extractor uses this to produce the binding signature. - pub(crate) bsk: Option<[u8; 32]>, + pub bsk: Option<[u8; 32]>, } /// Information about a Sapling spend within a transaction. -#[derive(Clone)] -pub(crate) struct Spend { +#[derive(Clone, Debug)] +pub struct Spend { // // SpendDescription effecting data. // // These are required fields that are part of the final transaction, and are filled in // by the Constructor when adding an output. // - pub(crate) cv: [u8; 32], - pub(crate) nullifier: [u8; 32], - pub(crate) rk: [u8; 32], + pub cv: [u8; 32], + pub nullifier: [u8; 32], + pub rk: [u8; 32], /// The Spend proof. /// /// This is set by the Prover. - pub(crate) zkproof: Option<[u8; GROTH_PROOF_SIZE]>, + pub zkproof: Option<[u8; GROTH_PROOF_SIZE]>, /// The spend authorization signature. /// /// This is set by the Signer. - pub(crate) spend_auth_sig: Option<[u8; 64]>, + pub spend_auth_sig: Option<[u8; 64]>, /// The address that received the note being spent. /// /// - This is set by the Constructor (or Updater?). /// - This is required by the Prover. - pub(crate) recipient: Option<[u8; 43]>, + pub recipient: Option<[u8; 43]>, /// The value of the input being spent. /// @@ -67,13 +67,13 @@ pub(crate) struct Spend { /// /// This exposes the input value to all participants. For Signers who don't need this /// information, or after signatures have been applied, this can be redacted. - pub(crate) value: Option, + pub value: Option, /// The seed randomness for the note being spent. /// /// - This is set by the Constructor. /// - This is required by the Prover. - pub(crate) rseed: Option<[u8; 32]>, + pub rseed: Option<[u8; 32]>, /// The value commitment randomness. /// @@ -84,20 +84,20 @@ pub(crate) struct Spend { /// /// This opens `cv` for all participants. For Signers who don't need this information, /// or after proofs / signatures have been applied, this can be redacted. - pub(crate) rcv: Option<[u8; 32]>, + pub rcv: Option<[u8; 32]>, /// The proof generation key `(ak, nsk)` corresponding to the recipient that received /// the note being spent. /// /// - This is set by the Updater. /// - This is required by the Prover. - pub(crate) proof_generation_key: Option<([u8; 32], [u8; 32])>, + pub proof_generation_key: Option<([u8; 32], [u8; 32])>, /// A witness from the note to the bundle's anchor. /// /// - This is set by the Updater. /// - This is required by the Prover. - pub(crate) witness: Option<(u32, [[u8; 32]; 32])>, + pub witness: Option<(u32, [[u8; 32]; 32])>, /// The spend authorization randomizer. /// @@ -105,41 +105,41 @@ pub(crate) struct Spend { /// - This is required by the Signer for creating `spend_auth_sig`, and may be used to /// validate `rk`. /// - After`zkproof` / `spend_auth_sig` has been set, this can be redacted. - pub(crate) alpha: Option<[u8; 32]>, + pub alpha: Option<[u8; 32]>, // TODO derivation path // TODO FROST - pub(crate) proprietary: BTreeMap>, + pub proprietary: BTreeMap>, } /// Information about a Sapling output within a transaction. -#[derive(Clone)] -pub(crate) struct Output { +#[derive(Clone, Debug)] +pub struct Output { // // OutputDescription effecting data. // // These are required fields that are part of the final transaction, and are filled in // by the Constructor when adding an output. // - pub(crate) cv: [u8; 32], - pub(crate) cmu: [u8; 32], - pub(crate) ephemeral_key: [u8; 32], + pub cv: [u8; 32], + pub cmu: [u8; 32], + pub ephemeral_key: [u8; 32], /// TODO: Should it be possible to choose the memo _value_ after defining an Output? - pub(crate) enc_ciphertext: [u8; 580], - pub(crate) out_ciphertext: [u8; 80], + pub enc_ciphertext: [u8; 580], + pub out_ciphertext: [u8; 80], /// The Output proof. /// /// This is set by the Prover. - pub(crate) zkproof: Option<[u8; GROTH_PROOF_SIZE]>, + pub zkproof: Option<[u8; GROTH_PROOF_SIZE]>, /// The address that will receive the output. /// /// - This is set by the Constructor. /// - This is required by the Prover. - pub(crate) recipient: Option<[u8; 43]>, + pub recipient: Option<[u8; 43]>, /// The value of the output. /// @@ -148,7 +148,7 @@ pub(crate) struct Output { /// /// This exposes the output value to all participants. For Signers who don't need this /// information, or after signatures have been applied, this can be redacted. - pub(crate) value: Option, + pub value: Option, /// The seed randomness for the output. /// @@ -158,7 +158,7 @@ pub(crate) struct Output { /// TODO: This could instead be decrypted from `enc_ciphertext` if `shared_secret` /// were required by the Prover. Likewise for `recipient` and `value`; is there ever a /// need for these to be independently redacted though? - pub(crate) rseed: Option<[u8; 32]>, + pub rseed: Option<[u8; 32]>, /// The value commitment randomness. /// @@ -169,14 +169,14 @@ pub(crate) struct Output { /// /// This opens `cv` for all participants. For Signers who don't need this information, /// or after proofs / signatures have been applied, this can be redacted. - pub(crate) rcv: Option<[u8; 32]>, + pub rcv: Option<[u8; 32]>, /// The symmetric shared secret used to encrypt `enc_ciphertext`. /// /// This enables Signers to verify that `enc_ciphertext` is correctly encrypted (and /// contains a note plaintext matching the public commitments), and to confirm the /// value of the memo. - pub(crate) shared_secret: Option<[u8; 32]>, + pub shared_secret: Option<[u8; 32]>, /// The `ock` value used to encrypt `out_ciphertext`. /// @@ -184,18 +184,18 @@ pub(crate) struct Output { /// /// This may be `None` if the Constructor added the output using an OVK policy of /// "None", to make the output unrecoverable from the chain by the sender. - pub(crate) ock: Option<[u8; 32]>, + pub ock: Option<[u8; 32]>, // TODO derivation path - pub(crate) proprietary: BTreeMap>, + pub proprietary: BTreeMap>, } impl Bundle { /// Merges this bundle with another. /// /// Returns `None` if the bundles have conflicting data. - pub(crate) fn merge(mut self, other: Self) -> Option { + pub fn merge(mut self, other: Self) -> Option { // Destructure `other` to ensure we handle everything. let Self { mut spends, diff --git a/rust/zcash_vendor/src/pczt/transparent.rs b/rust/zcash_vendor/src/pczt/transparent.rs index 90a7413ec..7a63011c7 100644 --- a/rust/zcash_vendor/src/pczt/transparent.rs +++ b/rust/zcash_vendor/src/pczt/transparent.rs @@ -4,34 +4,34 @@ use super::merge_optional; /// PCZT fields that are specific to producing the transaction's transparent bundle (if /// any). -#[derive(Clone)] -pub(crate) struct Bundle { - pub(crate) inputs: Vec, - pub(crate) outputs: Vec, +#[derive(Clone, Debug)] +pub struct Bundle { + pub inputs: Vec, + pub outputs: Vec, } -#[derive(Clone)] -pub(crate) struct Input { +#[derive(Clone, Debug)] +pub struct Input { // // Transparent effecting data. // // These are required fields that are part of the final transaction, and are filled in // by the Constructor when adding an output. // - pub(crate) prevout_txid: [u8; 32], - pub(crate) prevout_index: u32, + pub prevout_txid: [u8; 32], + pub prevout_index: u32, /// TODO: which role should set this? - pub(crate) sequence: u32, + pub sequence: u32, /// A satisfying witness for the `script_pubkey` of the input being spent. /// /// This is set by the Spend Finalizer. - pub(crate) script_sig: Option>, + pub script_sig: Option>, // These are required by the Transaction Extractor, to derive the shielded sighash // needed for computing the binding signatures. - pub(crate) value: u64, - pub(crate) script_pubkey: Vec, + pub value: u64, + pub script_pubkey: Vec, /// A map from a pubkey to a signature created by it. /// @@ -39,34 +39,34 @@ pub(crate) struct Input { /// - These are required by the Spend Finalizer to assemble `script_sig`. /// /// TODO: Decide on map key type. - pub(crate) signatures: BTreeMap, Vec>, + pub signatures: BTreeMap, Vec>, // TODO derivation path - pub(crate) proprietary: BTreeMap>, + pub proprietary: BTreeMap>, } -#[derive(Clone)] -pub(crate) struct Output { +#[derive(Clone, Debug)] +pub struct Output { // // Transparent effecting data. // // These are required fields that are part of the final transaction, and are filled in // by the Constructor when adding an output. // - pub(crate) value: u64, - pub(crate) script_pubkey: Vec, + pub value: u64, + pub script_pubkey: Vec, // TODO derivation path - pub(crate) proprietary: BTreeMap>, + pub proprietary: BTreeMap>, } impl Bundle { /// Merges this bundle with another. /// /// Returns `None` if the bundles have conflicting data. - pub(crate) fn merge(mut self, other: Self) -> Option { + pub fn merge(mut self, other: Self) -> Option { // Destructure `other` to ensure we handle everything. let Self { mut inputs, diff --git a/rust/zcash_vendor/src/sinsemilla/mod.rs b/rust/zcash_vendor/src/sinsemilla/mod.rs index 27861ad6b..e486ab063 100644 --- a/rust/zcash_vendor/src/sinsemilla/mod.rs +++ b/rust/zcash_vendor/src/sinsemilla/mod.rs @@ -33,7 +33,7 @@ pub const Q_PERSONALIZATION: &str = "z.cash:SinsemillaQ"; /// SWU hash-to-curve personalization for Sinsemilla $S$ generators. pub const S_PERSONALIZATION: &str = "z.cash:SinsemillaS"; -pub(crate) fn lebs2ip_k(bits: &[bool]) -> u32 { +pub fn lebs2ip_k(bits: &[bool]) -> u32 { assert!(bits.len() == K); bits.iter() .enumerate() @@ -166,7 +166,7 @@ impl HashDomain { /// This is only for testing use. #[cfg(test)] #[allow(non_snake_case)] - pub(crate) fn from_Q(Q: pallas::Point) -> Self { + pub fn from_Q(Q: pallas::Point) -> Self { HashDomain { Q } } diff --git a/rust/zcash_vendor/src/zcash_address/unified/address.rs b/rust/zcash_vendor/src/zcash_address/unified/address.rs index f8329c163..33ac721f1 100644 --- a/rust/zcash_vendor/src/zcash_address/unified/address.rs +++ b/rust/zcash_vendor/src/zcash_address/unified/address.rs @@ -61,7 +61,7 @@ impl SealedItem for Receiver { } #[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct Address(pub(crate) Vec); +pub struct Address(pub Vec); impl Address { // Returns whether this address has the ability to receive transfers of the given pool type. diff --git a/rust/zcash_vendor/src/zcash_address/unified/fvk.rs b/rust/zcash_vendor/src/zcash_address/unified/fvk.rs index f0ed995df..26079a233 100644 --- a/rust/zcash_vendor/src/zcash_address/unified/fvk.rs +++ b/rust/zcash_vendor/src/zcash_address/unified/fvk.rs @@ -105,7 +105,7 @@ impl SealedItem for Fvk { /// # } /// ``` #[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct Ufvk(pub(crate) Vec); +pub struct Ufvk(pub Vec); impl Container for Ufvk { type Item = Fvk; diff --git a/rust/zcash_vendor/src/zcash_address/unified/ivk.rs b/rust/zcash_vendor/src/zcash_address/unified/ivk.rs index e591542ab..4d4fc0d14 100644 --- a/rust/zcash_vendor/src/zcash_address/unified/ivk.rs +++ b/rust/zcash_vendor/src/zcash_address/unified/ivk.rs @@ -110,7 +110,7 @@ impl SealedItem for Ivk { /// # } /// ``` #[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct Uivk(pub(crate) Vec); +pub struct Uivk(pub Vec); impl Container for Uivk { type Item = Ivk; diff --git a/rust/zcash_vendor/src/zcash_address/unified/mod.rs b/rust/zcash_vendor/src/zcash_address/unified/mod.rs index 0c8deafff..8e452a5d4 100644 --- a/rust/zcash_vendor/src/zcash_address/unified/mod.rs +++ b/rust/zcash_vendor/src/zcash_address/unified/mod.rs @@ -11,9 +11,9 @@ use bech32::{self, Bech32m}; use super::super::zcash_protocol::consensus::NetworkType as Network; -pub(crate) mod address; -pub(crate) mod fvk; -pub(crate) mod ivk; +pub mod address; +pub mod fvk; +pub mod ivk; pub use address::{Address, Receiver}; pub use fvk::{Fvk, Ufvk}; @@ -159,7 +159,7 @@ impl fmt::Display for ParseError { impl Error for ParseError {} -pub(crate) mod private { +pub mod private { use crate::zcash_encoding; use alloc::vec; diff --git a/rust/zcash_vendor/src/zcash_primitives/legacy.rs b/rust/zcash_vendor/src/zcash_primitives/legacy.rs index 687974195..6b74b1a43 100644 --- a/rust/zcash_vendor/src/zcash_primitives/legacy.rs +++ b/rust/zcash_vendor/src/zcash_primitives/legacy.rs @@ -332,7 +332,7 @@ impl Script { } /// Returns the address that this Script contains, if any. - pub(crate) fn address(&self) -> Option { + pub fn address(&self) -> Option { if self.0.len() == 25 && self.0[0..3] == [OpCode::Dup as u8, OpCode::Hash160 as u8, 0x14] && self.0[23..25] == [OpCode::EqualVerify as u8, OpCode::CheckSig as u8] diff --git a/rust/zcash_vendor/src/zcash_primitives/legacy/keys.rs b/rust/zcash_vendor/src/zcash_primitives/legacy/keys.rs index b64661000..55aa8b237 100644 --- a/rust/zcash_vendor/src/zcash_primitives/legacy/keys.rs +++ b/rust/zcash_vendor/src/zcash_primitives/legacy/keys.rs @@ -304,7 +304,7 @@ pub fn pubkey_to_address(pubkey: &secp256k1::PublicKey) -> TransparentAddress { ) } -pub(crate) mod private { +pub mod private { use super::TransparentKeyScope; use bip32::ExtendedPublicKey; use secp256k1::PublicKey;