From ef87f61ada41e3096738f278b6f6b670dc6e3eda Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 10 Jan 2024 21:50:10 +0000 Subject: [PATCH] Migrate to `zcash_spec 0.1` --- Cargo.lock | 10 ++++++ Cargo.toml | 1 + src/keys.rs | 10 +++--- src/note.rs | 6 ++-- src/spec.rs | 3 +- src/spec/prf_expand.rs | 75 ------------------------------------------ src/zip32.rs | 5 +-- 7 files changed, 23 insertions(+), 87 deletions(-) delete mode 100644 src/spec/prf_expand.rs diff --git a/Cargo.lock b/Cargo.lock index 0ad8fcc60..1ebe810ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1441,6 +1441,7 @@ dependencies = [ "subtle", "tracing", "zcash_note_encryption", + "zcash_spec", ] [[package]] @@ -2493,6 +2494,15 @@ dependencies = [ "subtle", ] +[[package]] +name = "zcash_spec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7a3bf58b673cb3dacd8ae09ba345998923a197ab0da70d6239d8e8838949e9b" +dependencies = [ + "blake2b_simd", +] + [[package]] name = "zeroize" version = "1.6.0" diff --git a/Cargo.toml b/Cargo.toml index ff1d0e530..f54971a89 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,6 +43,7 @@ serde = { version = "1.0", features = ["derive"] } subtle = "2.3" zcash_note_encryption = "0.4" incrementalmerkletree = "0.5" +zcash_spec = "0.1" # Logging tracing = "0.1" diff --git a/src/keys.rs b/src/keys.rs index a7856f915..e2408dd7b 100644 --- a/src/keys.rs +++ b/src/keys.rs @@ -115,7 +115,7 @@ pub struct SpendAuthorizingKey(redpallas::SigningKey); impl SpendAuthorizingKey { /// Derives ask from sk. Internal use only, does not enforce all constraints. fn derive_inner(sk: &SpendingKey) -> pallas::Scalar { - to_scalar(PrfExpand::OrchardAsk.expand(&sk.0)) + to_scalar(PrfExpand::ORCHARD_ASK.with(&sk.0)) } /// Randomizes this spend authorizing key with the given `randomizer`. @@ -222,7 +222,7 @@ impl NullifierDerivingKey { impl From<&SpendingKey> for NullifierDerivingKey { fn from(sk: &SpendingKey) -> Self { - NullifierDerivingKey(to_base(PrfExpand::OrchardNk.expand(&sk.0))) + NullifierDerivingKey(to_base(PrfExpand::ORCHARD_NK.with(&sk.0))) } } @@ -257,7 +257,7 @@ pub(crate) struct CommitIvkRandomness(pallas::Scalar); impl From<&SpendingKey> for CommitIvkRandomness { fn from(sk: &SpendingKey) -> Self { - CommitIvkRandomness(to_scalar(PrfExpand::OrchardRivk.expand(&sk.0))) + CommitIvkRandomness(to_scalar(PrfExpand::ORCHARD_RIVK.with(&sk.0))) } } @@ -351,7 +351,7 @@ impl FullViewingKey { let ak = self.ak.to_bytes(); let nk = self.nk.to_bytes(); CommitIvkRandomness(to_scalar( - PrfExpand::OrchardRivkInternal.with_ad_slices(&k, &[&ak, &nk]), + PrfExpand::ORCHARD_RIVK_INTERNAL.with(&k, &ak, &nk), )) } } @@ -363,7 +363,7 @@ impl FullViewingKey { fn derive_dk_ovk(&self) -> (DiversifierKey, OutgoingViewingKey) { let k = self.rivk.0.to_repr(); let b = [(&self.ak.0).into(), self.nk.0.to_repr()]; - let r = PrfExpand::OrchardDkOvk.with_ad_slices(&k, &[&b[0][..], &b[1][..]]); + let r = PrfExpand::ORCHARD_DK_OVK.with(&k, &b[0], &b[1]); ( DiversifierKey(r[..32].try_into().unwrap()), OutgoingViewingKey(r[32..].try_into().unwrap()), diff --git a/src/note.rs b/src/note.rs index 522b137f3..e55397884 100644 --- a/src/note.rs +++ b/src/note.rs @@ -53,7 +53,7 @@ impl RandomSeed { /// /// [orchardsend]: https://zips.z.cash/protocol/nu5.pdf#orchardsend pub(crate) fn psi(&self, rho: &Nullifier) -> pallas::Base { - to_base(PrfExpand::Psi.with_ad(&self.0, &rho.to_bytes()[..])) + to_base(PrfExpand::PSI.with(&self.0, &rho.to_bytes())) } /// Defined in [Zcash Protocol Spec § 4.7.3: Sending Notes (Orchard)][orchardsend]. @@ -61,7 +61,7 @@ impl RandomSeed { /// [orchardsend]: https://zips.z.cash/protocol/nu5.pdf#orchardsend fn esk_inner(&self, rho: &Nullifier) -> CtOption { NonZeroPallasScalar::from_scalar(to_scalar( - PrfExpand::Esk.with_ad(&self.0, &rho.to_bytes()[..]), + PrfExpand::ORCHARD_ESK.with(&self.0, &rho.to_bytes()), )) } @@ -78,7 +78,7 @@ impl RandomSeed { /// [orchardsend]: https://zips.z.cash/protocol/nu5.pdf#orchardsend pub(crate) fn rcm(&self, rho: &Nullifier) -> commitment::NoteCommitTrapdoor { commitment::NoteCommitTrapdoor(to_scalar( - PrfExpand::Rcm.with_ad(&self.0, &rho.to_bytes()[..]), + PrfExpand::ORCHARD_RCM.with(&self.0, &rho.to_bytes()), )) } } diff --git a/src/spec.rs b/src/spec.rs index 698b7a394..7f0224bff 100644 --- a/src/spec.rs +++ b/src/spec.rs @@ -16,8 +16,7 @@ use crate::constants::{ KEY_DIVERSIFICATION_PERSONALIZATION, L_ORCHARD_BASE, }; -mod prf_expand; -pub(crate) use prf_expand::PrfExpand; +pub(crate) use zcash_spec::PrfExpand; /// A Pallas point that is guaranteed to not be the identity. #[derive(Clone, Copy, Debug, PartialEq, Eq)] diff --git a/src/spec/prf_expand.rs b/src/spec/prf_expand.rs deleted file mode 100644 index e2f95e7ff..000000000 --- a/src/spec/prf_expand.rs +++ /dev/null @@ -1,75 +0,0 @@ -use blake2b_simd::Params; - -const PRF_EXPAND_PERSONALIZATION: &[u8; 16] = b"Zcash_ExpandSeed"; - -/// The set of domains in which $PRF^\mathsf{expand}$ is defined. -pub(crate) enum PrfExpand { - Esk, - Rcm, - OrchardAsk, - OrchardNk, - OrchardRivk, - Psi, - OrchardZip32Child, - OrchardDkOvk, - OrchardRivkInternal, -} - -impl PrfExpand { - fn domain_separator(&self) -> u8 { - match self { - Self::Esk => 0x04, - Self::Rcm => 0x05, - Self::OrchardAsk => 0x06, - Self::OrchardNk => 0x07, - Self::OrchardRivk => 0x08, - Self::Psi => 0x09, - Self::OrchardZip32Child => 0x81, - Self::OrchardDkOvk => 0x82, - Self::OrchardRivkInternal => 0x83, - } - } - - /// Expands the given secret key in this domain, with no additional data. - /// - /// $PRF^\mathsf{expand}(sk, dst) := BLAKE2b-512("Zcash_ExpandSeed", sk || dst)$ - /// - /// Defined in [Zcash Protocol Spec § 5.4.2: Pseudo Random Functions][concreteprfs]. - /// - /// [concreteprfs]: https://zips.z.cash/protocol/nu5.pdf#concreteprfs - pub(crate) fn expand(self, sk: &[u8]) -> [u8; 64] { - self.with_ad_slices(sk, &[]) - } - - /// Expands the given secret key in this domain, with the given additional data. - /// - /// $PRF^\mathsf{expand}(sk, dst, t) := BLAKE2b-512("Zcash_ExpandSeed", sk || dst || t)$ - /// - /// Defined in [Zcash Protocol Spec § 5.4.2: Pseudo Random Functions][concreteprfs]. - /// - /// [concreteprfs]: https://zips.z.cash/protocol/nu5.pdf#concreteprfs - pub(crate) fn with_ad(self, sk: &[u8], t: &[u8]) -> [u8; 64] { - self.with_ad_slices(sk, &[t]) - } - - /// Expands the given secret key in this domain, with additional data concatenated - /// from the given slices. - /// - /// $PRF^\mathsf{expand}(sk, dst, a, b, ...) := BLAKE2b-512("Zcash_ExpandSeed", sk || dst || a || b || ...)$ - /// - /// Defined in [Zcash Protocol Spec § 5.4.2: Pseudo Random Functions][concreteprfs]. - /// - /// [concreteprfs]: https://zips.z.cash/protocol/nu5.pdf#concreteprfs - pub(crate) fn with_ad_slices(self, sk: &[u8], ts: &[&[u8]]) -> [u8; 64] { - let mut h = Params::new() - .hash_length(64) - .personal(PRF_EXPAND_PERSONALIZATION) - .to_state(); - h.update(sk); - h.update(&[self.domain_separator()]); - for t in ts { - h.update(t); - } - *h.finalize().as_array() - } -} diff --git a/src/zip32.rs b/src/zip32.rs index 3ba8bd571..2e79be505 100644 --- a/src/zip32.rs +++ b/src/zip32.rs @@ -174,9 +174,10 @@ impl ExtendedSpendingKey { /// Discards index if it results in an invalid sk fn derive_child(&self, index: ChildIndex) -> Result { // I := PRF^Expand(c_par, [0x81] || sk_par || I2LEOSP(i)) - let I: [u8; 64] = PrfExpand::OrchardZip32Child.with_ad_slices( + let I: [u8; 64] = PrfExpand::ORCHARD_ZIP32_CHILD.with( &self.chain_code.0, - &[self.sk.to_bytes(), &index.0.to_le_bytes()], + &self.sk.to_bytes(), + &index.0.to_le_bytes(), ); // I_L is used as the child spending key sk_i.