diff --git a/src/address.rs b/src/address.rs index 69543d12..eb1bea02 100644 --- a/src/address.rs +++ b/src/address.rs @@ -1,8 +1,6 @@ -use pasta_curves::pallas; - use crate::{ keys::{DiversifiedTransmissionKey, Diversifier}, - spec::diversify_hash, + spec::{diversify_hash, NonIdentityPallasPoint}, }; /// A shielded payment address. @@ -30,7 +28,7 @@ impl Address { Address { d, pk_d } } - pub(crate) fn g_d(&self) -> pallas::Point { + pub(crate) fn g_d(&self) -> NonIdentityPallasPoint { diversify_hash(self.d.as_array()) } diff --git a/src/keys.rs b/src/keys.rs index de538318..695ba23f 100644 --- a/src/keys.rs +++ b/src/keys.rs @@ -16,7 +16,7 @@ use crate::{ primitives::redpallas::{self, SpendAuth}, spec::{ commit_ivk, diversify_hash, extract_p, ka_orchard, prf_expand, prf_expand_vec, prf_nf, - to_base, to_scalar, NonZeroPallasBase, NonZeroPallasScalar, + to_base, to_scalar, NonIdentityPallasPoint, NonZeroPallasBase, NonZeroPallasScalar, }, }; @@ -363,7 +363,7 @@ impl From<&FullViewingKey> for OutgoingViewingKey { /// /// [orchardkeycomponents]: https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents #[derive(Debug, Clone)] -pub(crate) struct DiversifiedTransmissionKey(pallas::Point); +pub(crate) struct DiversifiedTransmissionKey(NonIdentityPallasPoint); impl DiversifiedTransmissionKey { /// Defined in [Zcash Protocol Spec § 4.2.3: Orchard Key Components][orchardkeycomponents]. diff --git a/src/spec.rs b/src/spec.rs index d6911adb..32be743c 100644 --- a/src/spec.rs +++ b/src/spec.rs @@ -17,6 +17,18 @@ use crate::{ const PRF_EXPAND_PERSONALIZATION: &[u8; 16] = b"Zcash_ExpandSeed"; +/// A Pallas point that is guaranteed to not be the identity. +#[derive(Clone, Debug)] +pub(crate) struct NonIdentityPallasPoint(pallas::Point); + +impl Deref for NonIdentityPallasPoint { + type Target = pallas::Point; + + fn deref(&self) -> &pallas::Point { + &self.0 + } +} + /// An integer in [1..q_P]. pub(crate) struct NonZeroPallasBase(pallas::Base); @@ -118,15 +130,11 @@ 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]) -> pallas::Point { +pub(crate) fn diversify_hash(d: &[u8; 11]) -> NonIdentityPallasPoint { let hasher = pallas::Point::hash_to_curve("z.cash:Orchard-gd"); let pk_d = hasher(d); - if pk_d.is_identity().into() { - // If the identity occurs, we replace it with a different fixed point. - hasher(&[]) - } else { - pk_d - } + // If the identity occurs, we replace it with a different fixed point. + NonIdentityPallasPoint(CtOption::new(pk_d, !pk_d.is_identity()).unwrap_or_else(|| hasher(&[]))) } /// $PRF^\mathsf{expand}(sk, t) := BLAKE2b-512("Zcash_ExpandSeed", sk || t)$ @@ -162,8 +170,11 @@ pub(crate) fn prf_nf(nk: pallas::Base, rho: pallas::Base) -> pallas::Base { /// 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(sk: &pallas::Scalar, b: &pallas::Point) -> pallas::Point { - b * sk +pub(crate) fn ka_orchard( + sk: &NonZeroPallasScalar, + b: &NonIdentityPallasPoint, +) -> NonIdentityPallasPoint { + NonIdentityPallasPoint(b.deref() * sk.deref()) } /// Coordinate extractor for Pallas.