From bc99cd26348ab00810bee1e8568171b68e30b4bd Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Tue, 10 Jan 2023 13:25:11 +0000 Subject: [PATCH] Move prepared key types into `sapling::keys` We re-export them under `sapling::note_encryption` for now to make the API changes smaller. --- zcash_primitives/CHANGELOG.md | 2 + zcash_primitives/src/sapling/keys.rs | 40 ++++++++++++++--- .../src/sapling/note_encryption.rs | 44 ++----------------- 3 files changed, 40 insertions(+), 46 deletions(-) diff --git a/zcash_primitives/CHANGELOG.md b/zcash_primitives/CHANGELOG.md index 747cfb03e..f62e0763c 100644 --- a/zcash_primitives/CHANGELOG.md +++ b/zcash_primitives/CHANGELOG.md @@ -10,6 +10,8 @@ and this library adheres to Rust's notion of - `zcash_primitives::sapling`: - `keys::DiversifiedTransmissionKey` - `keys::{EphemeralSecretKey, EphemeralPublicKey, SharedSecret}` + - `keys::{PreparedIncomingViewingKey, PreparedEphemeralPublicKey}` + (re-exported from `note_encryption`). - `note`, a module containing types related to Sapling notes. The existing `Note` and `Rseed` types are re-exported here, and new types are added. - `Node::from_cmu` diff --git a/zcash_primitives/src/sapling/keys.rs b/zcash_primitives/src/sapling/keys.rs index 0d20ebf2e..d0422e6e4 100644 --- a/zcash_primitives/src/sapling/keys.rs +++ b/zcash_primitives/src/sapling/keys.rs @@ -8,12 +8,11 @@ use std::io::{self, Read, Write}; use super::{ address::PaymentAddress, - note_encryption::{ - PreparedEphemeralPublicKey, PreparedIncomingViewingKey, KDF_SAPLING_PERSONALIZATION, - }, + note_encryption::KDF_SAPLING_PERSONALIZATION, spec::{ crh_ivk, diversify_hash, ka_sapling_agree, ka_sapling_agree_prepared, - ka_sapling_derive_public, ka_sapling_derive_public_subgroup_prepared, PreparedBaseSubgroup, + ka_sapling_derive_public, ka_sapling_derive_public_subgroup_prepared, PreparedBase, + PreparedBaseSubgroup, PreparedScalar, }, }; use crate::{ @@ -251,6 +250,27 @@ impl SaplingIvk { } } +/// A Sapling incoming viewing key that has been precomputed for trial decryption. +#[derive(Clone, Debug)] +pub struct PreparedIncomingViewingKey(PreparedScalar); + +impl memuse::DynamicUsage for PreparedIncomingViewingKey { + fn dynamic_usage(&self) -> usize { + self.0.dynamic_usage() + } + + fn dynamic_usage_bounds(&self) -> (usize, Option) { + self.0.dynamic_usage_bounds() + } +} + +impl PreparedIncomingViewingKey { + /// Performs the necessary precomputations to use a `SaplingIvk` for note decryption. + pub fn new(ivk: &SaplingIvk) -> Self { + Self(PreparedScalar::new(&ivk.0)) + } +} + #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct Diversifier(pub [u8; 11]); @@ -280,7 +300,7 @@ impl DiversifiedTransmissionKey { pub(crate) fn derive(ivk: &PreparedIncomingViewingKey, d: &Diversifier) -> Option { d.g_d() .map(PreparedBaseSubgroup::new) - .map(|g_d| ka_sapling_derive_public_subgroup_prepared(ivk.inner(), &g_d)) + .map(|g_d| ka_sapling_derive_public_subgroup_prepared(&ivk.0, &g_d)) .map(DiversifiedTransmissionKey) } @@ -382,9 +402,17 @@ impl EphemeralPublicKey { } } +/// A Sapling ephemeral public key that has been precomputed for trial decryption. +#[derive(Clone, Debug)] +pub struct PreparedEphemeralPublicKey(PreparedBase); + impl PreparedEphemeralPublicKey { + pub(crate) fn new(epk: jubjub::ExtendedPoint) -> Self { + PreparedEphemeralPublicKey(PreparedBase::new(epk)) + } + pub(crate) fn agree(&self, ivk: &PreparedIncomingViewingKey) -> SharedSecret { - SharedSecret(ka_sapling_agree_prepared(ivk.inner(), self.inner())) + SharedSecret(ka_sapling_agree_prepared(&ivk.0, &self.0)) } } diff --git a/zcash_primitives/src/sapling/note_encryption.rs b/zcash_primitives/src/sapling/note_encryption.rs index 8d0f4a6e7..7be0c8d83 100644 --- a/zcash_primitives/src/sapling/note_encryption.rs +++ b/zcash_primitives/src/sapling/note_encryption.rs @@ -23,9 +23,8 @@ use crate::{ DiversifiedTransmissionKey, EphemeralPublicKey, EphemeralSecretKey, OutgoingViewingKey, SharedSecret, }, - spec::{PreparedBase, PreparedScalar}, value::ValueCommitment, - Diversifier, Note, PaymentAddress, Rseed, SaplingIvk, + Diversifier, Note, PaymentAddress, Rseed, }, transaction::components::{ amount::Amount, @@ -35,46 +34,11 @@ use crate::{ use super::note::ExtractedNoteCommitment; +pub use crate::sapling::keys::{PreparedEphemeralPublicKey, PreparedIncomingViewingKey}; + pub const KDF_SAPLING_PERSONALIZATION: &[u8; 16] = b"Zcash_SaplingKDF"; pub const PRF_OCK_PERSONALIZATION: &[u8; 16] = b"Zcash_Derive_ock"; -/// A Sapling incoming viewing key that has been precomputed for trial decryption. -#[derive(Clone, Debug)] -pub struct PreparedIncomingViewingKey(PreparedScalar); - -impl DynamicUsage for PreparedIncomingViewingKey { - fn dynamic_usage(&self) -> usize { - self.0.dynamic_usage() - } - - fn dynamic_usage_bounds(&self) -> (usize, Option) { - self.0.dynamic_usage_bounds() - } -} - -impl PreparedIncomingViewingKey { - /// Performs the necessary precomputations to use a `SaplingIvk` for note decryption. - pub fn new(ivk: &SaplingIvk) -> Self { - Self(PreparedScalar::new(&ivk.0)) - } - - /// TODO: Remove after type changes. - pub(crate) fn inner(&self) -> &PreparedScalar { - &self.0 - } -} - -/// A Sapling ephemeral public key that has been precomputed for trial decryption. -#[derive(Clone, Debug)] -pub struct PreparedEphemeralPublicKey(PreparedBase); - -impl PreparedEphemeralPublicKey { - /// TODO: Remove after type changes. - pub(crate) fn inner(&self) -> &PreparedBase { - &self.0 - } -} - /// Sapling PRF^ock. /// /// Implemented per section 5.4.2 of the Zcash Protocol Specification. @@ -188,7 +152,7 @@ impl Domain for SaplingDomain

{ } fn prepare_epk(epk: Self::EphemeralPublicKey) -> Self::PreparedEphemeralPublicKey { - PreparedEphemeralPublicKey(PreparedBase::new(epk)) + PreparedEphemeralPublicKey::new(epk) } fn ka_derive_public(