From 8461c2153e88ac24c75a501b56521346b75cccc6 Mon Sep 17 00:00:00 2001 From: Deirdre Connolly Date: Wed, 17 Mar 2021 18:12:11 -0400 Subject: [PATCH] Update diversify_hash and its use to match spec updates --- zebra-chain/src/orchard/keys.rs | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/zebra-chain/src/orchard/keys.rs b/zebra-chain/src/orchard/keys.rs index c6616a154..9063423a4 100644 --- a/zebra-chain/src/orchard/keys.rs +++ b/zebra-chain/src/orchard/keys.rs @@ -18,7 +18,7 @@ use aes::Aes256; use bech32::{self, FromBase32, ToBase32, Variant}; use bitvec::prelude::*; use fpe::ff1::{BinaryNumeralString, FF1}; -use group::GroupEncoding; +use group::{Group, GroupEncoding}; use halo2::{ arithmetic::{CurveAffine, FieldExt}, pasta::pallas, @@ -103,11 +103,20 @@ fn prf_ock(ovk: [u8; 32], cv: [u8; 32], cm_x: [u8; 32], ephemeral_key: [u8; 32]) /// Used to derive a diversified base point from a diversifier value. /// -/// DiversifyHash^Orchard(d) := GroupHash^P("z.cash:Orchard-gd", LEBS2OSP_l_d(d)) +/// DiversifyHash^Orchard(d) := {︃ GroupHash^P("z.cash:Orchard-gd",""), if P = 0_P +/// P, otherwise +/// +/// where P = GroupHash^P(("z.cash:Orchard-gd", LEBS2OSP_l_d(d))) /// /// https://zips.z.cash/protocol/protocol.pdf#concretediversifyhash fn diversify_hash(d: &[u8]) -> pallas::Point { - pallas_group_hash(b"z.cash:Orchard-gd", &d) + let p = pallas_group_hash(b"z.cash:Orchard-gd", &d); + + if ::from(p.is_identity()) { + pallas_group_hash(b"z.cash:Orchard-gd", b"") + } else { + p + } } /// Magic human-readable strings used to identify what networks Orchard spending @@ -790,6 +799,8 @@ impl From for [u8; 11] { } impl From for pallas::Point { + /// Derive a _diversified base_ point. + /// /// g_d := DiversifyHash^Orchard(d) /// /// [orchardkeycomponents]: https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents @@ -888,7 +899,9 @@ impl From<(IncomingViewingKey, Diversifier)> for TransmissionKey { /// https://zips.z.cash/protocol/protocol.pdf#orchardkeycomponents /// https://zips.z.cash/protocol/protocol.pdf#concreteorchardkeyagreement fn from((ivk, d): (IncomingViewingKey, Diversifier)) -> Self { - Self(pallas::Affine::from(pallas::Point::from(d) * ivk.scalar)) + let g_d = pallas::Point::from(d); + + Self(pallas::Affine::from(g_d * ivk.scalar)) } }