Remove the Deref's and make the From's consistent for all key types

This commit is contained in:
Deirdre Connolly 2020-04-18 03:21:41 -04:00 committed by Deirdre Connolly
parent 37337c9e44
commit d445799626
3 changed files with 120 additions and 114 deletions

View File

@ -49,8 +49,8 @@ impl fmt::Display for SaplingShieldedAddress {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut bytes = io::Cursor::new(Vec::new()); let mut bytes = io::Cursor::new(Vec::new());
let _ = bytes.write_all(&self.diversifier.0[..]); let _ = bytes.write_all(&<[u8; 11]>::from(self.diversifier));
let _ = bytes.write_all(&self.transmission_key.to_bytes()); let _ = bytes.write_all(&<[u8; 32]>::from(self.transmission_key));
let hrp = match self.network { let hrp = match self.network {
Network::Mainnet => human_readable_parts::MAINNET, Network::Mainnet => human_readable_parts::MAINNET,
@ -79,8 +79,8 @@ impl std::str::FromStr for SaplingShieldedAddress {
human_readable_parts::MAINNET => Network::Mainnet, human_readable_parts::MAINNET => Network::Mainnet,
_ => Network::Testnet, _ => Network::Testnet,
}, },
diversifier: sapling::Diversifier(diversifier_bytes), diversifier: sapling::Diversifier::from(diversifier_bytes),
transmission_key: sapling::TransmissionKey::from_bytes(transmission_key_bytes), transmission_key: sapling::TransmissionKey::from(transmission_key_bytes),
}) })
} }
Err(_) => Err(SerializationError::Parse("bech32 decoding error")), Err(_) => Err(SerializationError::Parse("bech32 decoding error")),
@ -147,7 +147,7 @@ mod tests {
sapling::IncomingViewingKey::from((authorizing_key, nullifier_deriving_key)); sapling::IncomingViewingKey::from((authorizing_key, nullifier_deriving_key));
let diversifier = sapling::Diversifier::new(&mut OsRng); let diversifier = sapling::Diversifier::new(&mut OsRng);
let transmission_key = sapling::TransmissionKey::from(incoming_viewing_key, diversifier); let transmission_key = sapling::TransmissionKey::from((incoming_viewing_key, diversifier));
let _sapling_shielded_address = SaplingShieldedAddress { let _sapling_shielded_address = SaplingShieldedAddress {
network: Network::Mainnet, network: Network::Mainnet,

View File

@ -17,7 +17,6 @@ use std::{
convert::{From, Into, TryFrom}, convert::{From, Into, TryFrom},
fmt, fmt,
io::{self, Write}, io::{self, Write},
ops::Deref,
str::FromStr, str::FromStr,
}; };
@ -253,24 +252,29 @@ impl SpendingKey {
/// _Spend Description_, proving ownership of notes. /// _Spend Description_, proving ownership of notes.
/// ///
/// [ps]: https://zips.z.cash/protocol/protocol.pdf#saplingkeycomponents /// [ps]: https://zips.z.cash/protocol/protocol.pdf#saplingkeycomponents
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct SpendAuthorizingKey(pub Scalar); pub struct SpendAuthorizingKey(pub Scalar);
impl Deref for SpendAuthorizingKey {
type Target = Scalar;
fn deref(&self) -> &Scalar {
&self.0
}
}
impl fmt::Debug for SpendAuthorizingKey { impl fmt::Debug for SpendAuthorizingKey {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_tuple("SpendAuthorizingKey") f.debug_tuple("SpendAuthorizingKey")
.field(&hex::encode(self.to_bytes())) .field(&hex::encode(<[u8; 32]>::from(*self)))
.finish() .finish()
} }
} }
impl From<[u8; 32]> for SpendAuthorizingKey {
fn from(bytes: [u8; 32]) -> Self {
Self(Scalar::from_bytes(&bytes).unwrap())
}
}
impl From<SpendAuthorizingKey> for [u8; 32] {
fn from(sk: SpendAuthorizingKey) -> Self {
sk.0.to_bytes()
}
}
impl From<SpendingKey> for SpendAuthorizingKey { impl From<SpendingKey> for SpendAuthorizingKey {
/// Invokes Blake2b-512 as _PRF^expand_, t=0, to derive a /// Invokes Blake2b-512 as _PRF^expand_, t=0, to derive a
/// SpendAuthorizingKey from a SpendingKey. /// SpendAuthorizingKey from a SpendingKey.
@ -284,30 +288,41 @@ impl From<SpendingKey> for SpendAuthorizingKey {
} }
} }
impl PartialEq<[u8; 32]> for SpendAuthorizingKey {
fn eq(&self, other: &[u8; 32]) -> bool {
<[u8; 32]>::from(*self) == *other
}
}
/// A _Proof Authorizing Key_, as described in [protocol specification /// A _Proof Authorizing Key_, as described in [protocol specification
/// §4.2.2][ps]. /// §4.2.2][ps].
/// ///
/// Used in the _Spend Statement_ to prove nullifier integrity. /// Used in the _Spend Statement_ to prove nullifier integrity.
/// ///
/// [ps]: https://zips.z.cash/protocol/protocol.pdf#saplingkeycomponents /// [ps]: https://zips.z.cash/protocol/protocol.pdf#saplingkeycomponents
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct ProofAuthorizingKey(pub Scalar); pub struct ProofAuthorizingKey(pub Scalar);
impl Deref for ProofAuthorizingKey {
type Target = Scalar;
fn deref(&self) -> &Scalar {
&self.0
}
}
impl fmt::Debug for ProofAuthorizingKey { impl fmt::Debug for ProofAuthorizingKey {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_tuple("ProofAuthorizingKey") f.debug_tuple("ProofAuthorizingKey")
.field(&hex::encode(&self.to_bytes())) .field(&hex::encode(<[u8; 32]>::from(*self)))
.finish() .finish()
} }
} }
impl From<[u8; 32]> for ProofAuthorizingKey {
fn from(bytes: [u8; 32]) -> Self {
Self(Scalar::from_bytes(&bytes).unwrap())
}
}
impl From<ProofAuthorizingKey> for [u8; 32] {
fn from(sk: ProofAuthorizingKey) -> Self {
sk.0.to_bytes()
}
}
impl From<SpendingKey> for ProofAuthorizingKey { impl From<SpendingKey> for ProofAuthorizingKey {
/// For this invocation of Blake2b-512 as _PRF^expand_, t=1. /// For this invocation of Blake2b-512 as _PRF^expand_, t=1.
/// ///
@ -320,6 +335,12 @@ impl From<SpendingKey> for ProofAuthorizingKey {
} }
} }
impl PartialEq<[u8; 32]> for ProofAuthorizingKey {
fn eq(&self, other: &[u8; 32]) -> bool {
<[u8; 32]>::from(*self) == *other
}
}
/// An _Outgoing Viewing Key_, as described in [protocol specification /// An _Outgoing Viewing Key_, as described in [protocol specification
/// §4.2.2][ps]. /// §4.2.2][ps].
/// ///
@ -371,12 +392,6 @@ impl PartialEq<[u8; 32]> for OutgoingViewingKey {
} }
} }
impl PartialEq<OutgoingViewingKey> for [u8; 32] {
fn eq(&self, other: &OutgoingViewingKey) -> bool {
*self == other.0
}
}
/// An _Authorizing Key_, as described in [protocol specification /// An _Authorizing Key_, as described in [protocol specification
/// §4.2.2][ps]. /// §4.2.2][ps].
/// ///
@ -387,6 +402,8 @@ impl PartialEq<OutgoingViewingKey> for [u8; 32] {
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct AuthorizingKey(pub redjubjub::PublicKey<SpendAuth>); pub struct AuthorizingKey(pub redjubjub::PublicKey<SpendAuth>);
impl Eq for AuthorizingKey {}
impl From<[u8; 32]> for AuthorizingKey { impl From<[u8; 32]> for AuthorizingKey {
fn from(bytes: [u8; 32]) -> Self { fn from(bytes: [u8; 32]) -> Self {
Self(redjubjub::PublicKey::try_from(bytes).unwrap()) Self(redjubjub::PublicKey::try_from(bytes).unwrap())
@ -401,20 +418,20 @@ impl From<AuthorizingKey> for [u8; 32] {
impl From<SpendAuthorizingKey> for AuthorizingKey { impl From<SpendAuthorizingKey> for AuthorizingKey {
fn from(ask: SpendAuthorizingKey) -> Self { fn from(ask: SpendAuthorizingKey) -> Self {
let sk = redjubjub::SecretKey::<SpendAuth>::try_from(ask.to_bytes()).unwrap(); let sk = redjubjub::SecretKey::<SpendAuth>::try_from(<[u8; 32]>::from(ask)).unwrap();
Self(redjubjub::PublicKey::from(&sk)) Self(redjubjub::PublicKey::from(&sk))
} }
} }
impl PartialEq for AuthorizingKey { impl PartialEq for AuthorizingKey {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
Into::<[u8; 32]>::into(self.0) == Into::<[u8; 32]>::into(other.0) <[u8; 32]>::from(self.0) == <[u8; 32]>::from(other.0)
} }
} }
impl PartialEq<[u8; 32]> for AuthorizingKey { impl PartialEq<[u8; 32]> for AuthorizingKey {
fn eq(&self, other: &[u8; 32]) -> bool { fn eq(&self, other: &[u8; 32]) -> bool {
Into::<[u8; 32]>::into(self.0) == *other <[u8; 32]>::from(self.0) == *other
} }
} }
@ -427,35 +444,29 @@ impl PartialEq<[u8; 32]> for AuthorizingKey {
#[derive(Copy, Clone, PartialEq)] #[derive(Copy, Clone, PartialEq)]
pub struct NullifierDerivingKey(pub jubjub::AffinePoint); pub struct NullifierDerivingKey(pub jubjub::AffinePoint);
impl fmt::Debug for NullifierDerivingKey {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("NullifierDerivingKey")
.field("u", &hex::encode(self.0.get_u().to_bytes()))
.field("v", &hex::encode(self.0.get_v().to_bytes()))
.finish()
}
}
impl From<[u8; 32]> for NullifierDerivingKey { impl From<[u8; 32]> for NullifierDerivingKey {
fn from(bytes: [u8; 32]) -> Self { fn from(bytes: [u8; 32]) -> Self {
Self(jubjub::AffinePoint::from_bytes(bytes).unwrap()) Self(jubjub::AffinePoint::from_bytes(bytes).unwrap())
} }
} }
impl Eq for NullifierDerivingKey {}
impl From<NullifierDerivingKey> for [u8; 32] { impl From<NullifierDerivingKey> for [u8; 32] {
fn from(nk: NullifierDerivingKey) -> [u8; 32] { fn from(nk: NullifierDerivingKey) -> [u8; 32] {
nk.0.to_bytes() nk.0.to_bytes()
} }
} }
impl Deref for NullifierDerivingKey {
type Target = jubjub::AffinePoint;
fn deref(&self) -> &jubjub::AffinePoint {
&self.0
}
}
impl fmt::Debug for NullifierDerivingKey {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("NullifierDerivingKey")
.field("u", &hex::encode(self.get_u().to_bytes()))
.field("v", &hex::encode(self.get_v().to_bytes()))
.finish()
}
}
impl From<ProofAuthorizingKey> for NullifierDerivingKey { impl From<ProofAuthorizingKey> for NullifierDerivingKey {
/// Requires JubJub's _FindGroupHash^J("Zcash_H_", "")_, then uses /// Requires JubJub's _FindGroupHash^J("Zcash_H_", "")_, then uses
/// the resulting generator point to scalar multiply the /// the resulting generator point to scalar multiply the
@ -477,6 +488,12 @@ impl From<ProofAuthorizingKey> for NullifierDerivingKey {
} }
} }
impl PartialEq<[u8; 32]> for NullifierDerivingKey {
fn eq(&self, other: &[u8; 32]) -> bool {
<[u8; 32]>::from(*self) == *other
}
}
/// Magic human-readable strings used to identify what networks /// Magic human-readable strings used to identify what networks
/// Sapling IncomingViewingKeys are associated with when /// Sapling IncomingViewingKeys are associated with when
/// encoded/decoded with bech32. /// encoded/decoded with bech32.
@ -552,7 +569,7 @@ impl From<(AuthorizingKey, NullifierDerivingKey)> for IncomingViewingKey {
// //
// [ps]: https://zips.z.cash/protocol/protocol.pdf#saplingkeycomponents // [ps]: https://zips.z.cash/protocol/protocol.pdf#saplingkeycomponents
fn from((ask, nk): (AuthorizingKey, NullifierDerivingKey)) -> Self { fn from((ask, nk): (AuthorizingKey, NullifierDerivingKey)) -> Self {
let hash_bytes = crh_ivk(ask.into(), nk.to_bytes()); let hash_bytes = crh_ivk(ask.into(), nk.into());
IncomingViewingKey::from(hash_bytes) IncomingViewingKey::from(hash_bytes)
} }
@ -606,6 +623,18 @@ impl fmt::Debug for Diversifier {
} }
} }
impl From<[u8; 11]> for Diversifier {
fn from(bytes: [u8; 11]) -> Self {
Self(bytes)
}
}
impl From<Diversifier> for [u8; 11] {
fn from(d: Diversifier) -> [u8; 11] {
d.0
}
}
impl From<SpendingKey> for Diversifier { impl From<SpendingKey> for Diversifier {
/// Derives a [_default diversifier_][4.2.2] from a SpendingKey. /// Derives a [_default diversifier_][4.2.2] from a SpendingKey.
/// ///
@ -678,44 +707,50 @@ impl Diversifier {
#[derive(Copy, Clone, PartialEq)] #[derive(Copy, Clone, PartialEq)]
pub struct TransmissionKey(pub jubjub::AffinePoint); pub struct TransmissionKey(pub jubjub::AffinePoint);
impl Deref for TransmissionKey {
type Target = jubjub::AffinePoint;
fn deref(&self) -> &jubjub::AffinePoint {
&self.0
}
}
impl fmt::Debug for TransmissionKey { impl fmt::Debug for TransmissionKey {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("TransmissionKey") f.debug_struct("TransmissionKey")
.field("u", &hex::encode(self.get_u().to_bytes())) .field("u", &hex::encode(self.0.get_u().to_bytes()))
.field("v", &hex::encode(self.get_v().to_bytes())) .field("v", &hex::encode(self.0.get_v().to_bytes()))
.finish() .finish()
} }
} }
impl Eq for TransmissionKey {} impl Eq for TransmissionKey {}
impl TransmissionKey { impl From<[u8; 32]> for TransmissionKey {
/// This includes _KA^Sapling.DerivePublic(ivk, G_d)_, which is just a
/// scalar mult _[ivk]G_d_.
///
/// https://zips.z.cash/protocol/protocol.pdf#saplingkeycomponents
/// https://zips.z.cash/protocol/protocol.pdf#concretesaplingkeyagreement
pub fn from(ivk: IncomingViewingKey, d: Diversifier) -> Self {
Self(jubjub::AffinePoint::from(
diversify_hash(d.0).unwrap() * ivk.scalar,
))
}
/// Attempts to interpret a byte representation of an /// Attempts to interpret a byte representation of an
/// affine point, failing if the element is not on /// affine point, failing if the element is not on
/// the curve or non-canonical. /// the curve or non-canonical.
/// ///
/// https://github.com/zkcrypto/jubjub/blob/master/src/lib.rs#L411 /// https://github.com/zkcrypto/jubjub/blob/master/src/lib.rs#L411
pub fn from_bytes(b: [u8; 32]) -> Self { fn from(bytes: [u8; 32]) -> Self {
Self(jubjub::AffinePoint::from_bytes(b).unwrap()) Self(jubjub::AffinePoint::from_bytes(bytes).unwrap())
}
}
impl From<TransmissionKey> for [u8; 32] {
fn from(pk_d: TransmissionKey) -> [u8; 32] {
pk_d.0.to_bytes()
}
}
impl From<(IncomingViewingKey, Diversifier)> for TransmissionKey {
/// This includes _KA^Sapling.DerivePublic(ivk, G_d)_, which is just a
/// scalar mult _[ivk]G_d_.
///
/// https://zips.z.cash/protocol/protocol.pdf#saplingkeycomponents
/// https://zips.z.cash/protocol/protocol.pdf#concretesaplingkeyagreement
fn from((ivk, d): (IncomingViewingKey, Diversifier)) -> Self {
Self(jubjub::AffinePoint::from(
diversify_hash(d.0).unwrap() * ivk.scalar,
))
}
}
impl PartialEq<[u8; 32]> for TransmissionKey {
fn eq(&self, other: &[u8; 32]) -> bool {
<[u8; 32]>::from(*self) == *other
} }
} }
@ -737,7 +772,7 @@ mod fvk_hrp {
/// test network, the Human-Readable Part is “zviewtestsapling”. /// test network, the Human-Readable Part is “zviewtestsapling”.
/// ///
/// https://zips.z.cash/protocol/protocol.pdf#saplingfullviewingkeyencoding /// https://zips.z.cash/protocol/protocol.pdf#saplingfullviewingkeyencoding
#[derive(Copy, Clone, PartialEq)] #[derive(Copy, Clone, Eq, PartialEq)]
pub struct FullViewingKey { pub struct FullViewingKey {
network: Network, network: Network,
authorizing_key: AuthorizingKey, authorizing_key: AuthorizingKey,
@ -762,9 +797,9 @@ impl fmt::Display for FullViewingKey {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut bytes = io::Cursor::new(Vec::new()); let mut bytes = io::Cursor::new(Vec::new());
let _ = bytes.write_all(&Into::<[u8; 32]>::into(self.authorizing_key)); let _ = bytes.write_all(&<[u8; 32]>::from(self.authorizing_key));
let _ = bytes.write_all(&Into::<[u8; 32]>::into(self.nullifier_deriving_key)); let _ = bytes.write_all(&<[u8; 32]>::from(self.nullifier_deriving_key));
let _ = bytes.write_all(&Into::<[u8; 32]>::into(self.outgoing_viewing_key)); let _ = bytes.write_all(&<[u8; 32]>::from(self.outgoing_viewing_key));
let hrp = match self.network { let hrp = match self.network {
Network::Mainnet => fvk_hrp::MAINNET, Network::Mainnet => fvk_hrp::MAINNET,

View File

@ -21,7 +21,7 @@ impl Arbitrary for TransmissionKey {
let diversifier = Diversifier::from(spending_key); let diversifier = Diversifier::from(spending_key);
return Self::from(incoming_viewing_key, diversifier); return Self::from((incoming_viewing_key, diversifier));
}) })
.boxed() .boxed()
} }
@ -32,53 +32,24 @@ impl Arbitrary for TransmissionKey {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use rand_core::OsRng;
use super::*; use super::*;
#[test]
fn derive() {
let spending_key = SpendingKey::new(&mut OsRng);
let spend_authorizing_key = SpendAuthorizingKey::from(spending_key);
let proof_authorizing_key = ProofAuthorizingKey::from(spending_key);
let outgoing_viewing_key = OutgoingViewingKey::from(spending_key);
let authorizing_key = AuthorizingKey::from(spend_authorizing_key);
let nullifier_deriving_key = NullifierDerivingKey::from(proof_authorizing_key);
// "If ivk = 0, discard this key and start over with a new
// [spending key]."
// https://zips.z.cash/protocol/protocol.pdf#saplingkeycomponents
let incoming_viewing_key =
IncomingViewingKey::from((authorizing_key, nullifier_deriving_key));
let diversifier = Diversifier::new(&mut OsRng);
let _transmission_key = TransmissionKey::from(incoming_viewing_key, diversifier);
let _full_viewing_key = FullViewingKey {
network: Network::default(),
authorizing_key,
nullifier_deriving_key,
outgoing_viewing_key,
};
}
#[test] #[test]
fn derive_for_each_test_vector() { fn derive_for_each_test_vector() {
for test_vector in test_vectors::TEST_VECTORS.iter() { for test_vector in test_vectors::TEST_VECTORS.iter() {
let spending_key = SpendingKey::from(test_vector.sk); let spending_key = SpendingKey::from(test_vector.sk);
let spend_authorizing_key = SpendAuthorizingKey::from(spending_key); let spend_authorizing_key = SpendAuthorizingKey::from(spending_key);
assert_eq!(spend_authorizing_key.to_bytes(), test_vector.ask); assert_eq!(spend_authorizing_key, test_vector.ask);
let proof_authorizing_key = ProofAuthorizingKey::from(spending_key); let proof_authorizing_key = ProofAuthorizingKey::from(spending_key);
assert_eq!(proof_authorizing_key.to_bytes(), test_vector.nsk); assert_eq!(proof_authorizing_key, test_vector.nsk);
let outgoing_viewing_key = OutgoingViewingKey::from(spending_key); let outgoing_viewing_key = OutgoingViewingKey::from(spending_key);
assert_eq!(outgoing_viewing_key, test_vector.ovk); assert_eq!(outgoing_viewing_key, test_vector.ovk);
let authorizing_key = AuthorizingKey::from(spend_authorizing_key); let authorizing_key = AuthorizingKey::from(spend_authorizing_key);
assert_eq!(authorizing_key, test_vector.ak); assert_eq!(authorizing_key, test_vector.ak);
let nullifier_deriving_key = NullifierDerivingKey::from(proof_authorizing_key); let nullifier_deriving_key = NullifierDerivingKey::from(proof_authorizing_key);
assert_eq!(nullifier_deriving_key.to_bytes(), test_vector.nk); assert_eq!(nullifier_deriving_key, test_vector.nk);
let incoming_viewing_key = let incoming_viewing_key =
IncomingViewingKey::from((authorizing_key, nullifier_deriving_key)); IncomingViewingKey::from((authorizing_key, nullifier_deriving_key));
assert_eq!(incoming_viewing_key, test_vector.ivk); assert_eq!(incoming_viewing_key, test_vector.ivk);
@ -86,8 +57,8 @@ mod tests {
let diversifier = Diversifier::from(spending_key); let diversifier = Diversifier::from(spending_key);
assert_eq!(diversifier, test_vector.default_d); assert_eq!(diversifier, test_vector.default_d);
let transmission_key = TransmissionKey::from(incoming_viewing_key, diversifier); let transmission_key = TransmissionKey::from((incoming_viewing_key, diversifier));
assert_eq!(transmission_key.to_bytes(), test_vector.default_pk_d); assert_eq!(transmission_key, test_vector.default_pk_d);
let _full_viewing_key = FullViewingKey { let _full_viewing_key = FullViewingKey {
network: Network::default(), network: Network::default(),