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

View File

@ -17,7 +17,6 @@ use std::{
convert::{From, Into, TryFrom},
fmt,
io::{self, Write},
ops::Deref,
str::FromStr,
};
@ -253,24 +252,29 @@ impl SpendingKey {
/// _Spend Description_, proving ownership of notes.
///
/// [ps]: https://zips.z.cash/protocol/protocol.pdf#saplingkeycomponents
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct SpendAuthorizingKey(pub Scalar);
impl Deref for SpendAuthorizingKey {
type Target = Scalar;
fn deref(&self) -> &Scalar {
&self.0
}
}
impl fmt::Debug for SpendAuthorizingKey {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_tuple("SpendAuthorizingKey")
.field(&hex::encode(self.to_bytes()))
.field(&hex::encode(<[u8; 32]>::from(*self)))
.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 {
/// Invokes Blake2b-512 as _PRF^expand_, t=0, to derive a
/// 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
/// §4.2.2][ps].
///
/// Used in the _Spend Statement_ to prove nullifier integrity.
///
/// [ps]: https://zips.z.cash/protocol/protocol.pdf#saplingkeycomponents
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct ProofAuthorizingKey(pub Scalar);
impl Deref for ProofAuthorizingKey {
type Target = Scalar;
fn deref(&self) -> &Scalar {
&self.0
}
}
impl fmt::Debug for ProofAuthorizingKey {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_tuple("ProofAuthorizingKey")
.field(&hex::encode(&self.to_bytes()))
.field(&hex::encode(<[u8; 32]>::from(*self)))
.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 {
/// 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
/// §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
/// §4.2.2][ps].
///
@ -387,6 +402,8 @@ impl PartialEq<OutgoingViewingKey> for [u8; 32] {
#[derive(Copy, Clone, Debug)]
pub struct AuthorizingKey(pub redjubjub::PublicKey<SpendAuth>);
impl Eq for AuthorizingKey {}
impl From<[u8; 32]> for AuthorizingKey {
fn from(bytes: [u8; 32]) -> Self {
Self(redjubjub::PublicKey::try_from(bytes).unwrap())
@ -401,20 +418,20 @@ impl From<AuthorizingKey> for [u8; 32] {
impl From<SpendAuthorizingKey> for AuthorizingKey {
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))
}
}
impl PartialEq for AuthorizingKey {
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 {
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)]
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 {
fn from(bytes: [u8; 32]) -> Self {
Self(jubjub::AffinePoint::from_bytes(bytes).unwrap())
}
}
impl Eq for NullifierDerivingKey {}
impl From<NullifierDerivingKey> for [u8; 32] {
fn from(nk: NullifierDerivingKey) -> [u8; 32] {
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 {
/// Requires JubJub's _FindGroupHash^J("Zcash_H_", "")_, then uses
/// 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
/// Sapling IncomingViewingKeys are associated with when
/// encoded/decoded with bech32.
@ -552,7 +569,7 @@ impl From<(AuthorizingKey, NullifierDerivingKey)> for IncomingViewingKey {
//
// [ps]: https://zips.z.cash/protocol/protocol.pdf#saplingkeycomponents
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)
}
@ -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 {
/// Derives a [_default diversifier_][4.2.2] from a SpendingKey.
///
@ -678,44 +707,50 @@ impl Diversifier {
#[derive(Copy, Clone, PartialEq)]
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 {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("TransmissionKey")
.field("u", &hex::encode(self.get_u().to_bytes()))
.field("v", &hex::encode(self.get_v().to_bytes()))
.field("u", &hex::encode(self.0.get_u().to_bytes()))
.field("v", &hex::encode(self.0.get_v().to_bytes()))
.finish()
}
}
impl Eq for TransmissionKey {}
impl 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,
))
}
impl From<[u8; 32]> for TransmissionKey {
/// Attempts to interpret a byte representation of an
/// affine point, failing if the element is not on
/// the curve or non-canonical.
///
/// https://github.com/zkcrypto/jubjub/blob/master/src/lib.rs#L411
pub fn from_bytes(b: [u8; 32]) -> Self {
Self(jubjub::AffinePoint::from_bytes(b).unwrap())
fn from(bytes: [u8; 32]) -> Self {
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”.
///
/// https://zips.z.cash/protocol/protocol.pdf#saplingfullviewingkeyencoding
#[derive(Copy, Clone, PartialEq)]
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct FullViewingKey {
network: Network,
authorizing_key: AuthorizingKey,
@ -762,9 +797,9 @@ impl fmt::Display for FullViewingKey {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut bytes = io::Cursor::new(Vec::new());
let _ = bytes.write_all(&Into::<[u8; 32]>::into(self.authorizing_key));
let _ = bytes.write_all(&Into::<[u8; 32]>::into(self.nullifier_deriving_key));
let _ = bytes.write_all(&Into::<[u8; 32]>::into(self.outgoing_viewing_key));
let _ = bytes.write_all(&<[u8; 32]>::from(self.authorizing_key));
let _ = bytes.write_all(&<[u8; 32]>::from(self.nullifier_deriving_key));
let _ = bytes.write_all(&<[u8; 32]>::from(self.outgoing_viewing_key));
let hrp = match self.network {
Network::Mainnet => fvk_hrp::MAINNET,

View File

@ -21,7 +21,7 @@ impl Arbitrary for TransmissionKey {
let diversifier = Diversifier::from(spending_key);
return Self::from(incoming_viewing_key, diversifier);
return Self::from((incoming_viewing_key, diversifier));
})
.boxed()
}
@ -32,53 +32,24 @@ impl Arbitrary for TransmissionKey {
#[cfg(test)]
mod tests {
use rand_core::OsRng;
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]
fn derive_for_each_test_vector() {
for test_vector in test_vectors::TEST_VECTORS.iter() {
let spending_key = SpendingKey::from(test_vector.sk);
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);
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);
assert_eq!(outgoing_viewing_key, test_vector.ovk);
let authorizing_key = AuthorizingKey::from(spend_authorizing_key);
assert_eq!(authorizing_key, test_vector.ak);
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 =
IncomingViewingKey::from((authorizing_key, nullifier_deriving_key));
assert_eq!(incoming_viewing_key, test_vector.ivk);
@ -86,8 +57,8 @@ mod tests {
let diversifier = Diversifier::from(spending_key);
assert_eq!(diversifier, test_vector.default_d);
let transmission_key = TransmissionKey::from(incoming_viewing_key, diversifier);
assert_eq!(transmission_key.to_bytes(), test_vector.default_pk_d);
let transmission_key = TransmissionKey::from((incoming_viewing_key, diversifier));
assert_eq!(transmission_key, test_vector.default_pk_d);
let _full_viewing_key = FullViewingKey {
network: Network::default(),