Remove the Deref's and make the From's consistent for all key types
This commit is contained in:
parent
37337c9e44
commit
d445799626
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
Loading…
Reference in New Issue