Make several types wrap jubjub types and impl Deref

This commit is contained in:
Deirdre Connolly 2020-03-29 05:17:56 -04:00 committed by Deirdre Connolly
parent 145afb7bda
commit 743330fd0b
1 changed files with 97 additions and 38 deletions

View File

@ -7,9 +7,10 @@
//! //!
//! [ps]: https://zips.z.cash/protocol/protocol.pdf#saplingkeycomponents //! [ps]: https://zips.z.cash/protocol/protocol.pdf#saplingkeycomponents
use std::fmt; use std::{fmt, ops::Deref};
use blake2b_simd; use blake2b_simd;
use blake2s_simd;
use jubjub; use jubjub;
use rand_core::{CryptoRng, RngCore}; use rand_core::{CryptoRng, RngCore};
@ -44,13 +45,21 @@ impl SpendingKey {
impl From<[u8; 32]> for SpendingKey { impl From<[u8; 32]> for SpendingKey {
/// Generate a _SpendingKey_ from existing bytes. /// Generate a _SpendingKey_ from existing bytes.
fn from(mut bytes: [u8; 32]) -> SpendingKey { fn from(bytes: [u8; 32]) -> SpendingKey {
SpendingKey(bytes) SpendingKey(bytes)
} }
} }
/// Derived from a _SpendingKey_. /// Derived from a _SpendingKey_.
pub type SpendAuthorizationKey = Scalar; pub struct SpendAuthorizationKey(Scalar);
impl Deref for SpendAuthorizationKey {
type Target = Scalar;
fn deref(&self) -> &Scalar {
&self.0
}
}
impl From<SpendingKey> for SpendAuthorizationKey { impl From<SpendingKey> for SpendAuthorizationKey {
/// Invokes Blake2b-512 as PRF^expand, t=0, to derive a /// Invokes Blake2b-512 as PRF^expand, t=0, to derive a
@ -63,25 +72,33 @@ impl From<SpendingKey> for SpendAuthorizationKey {
.hash_length(64) // Blake2b-512 .hash_length(64) // Blake2b-512
.personal(b"Zcash_ExpandSeed") .personal(b"Zcash_ExpandSeed")
.to_state() .to_state()
.update(spending_key.0[..]) .update(&spending_key.0[..])
.update([0]) // t=0 .update(&[0]) // t=0
.finalize(); .finalize();
Self::from(hash) Self(Scalar::from_bytes_wide(hash.as_array()))
} }
} }
/// Derived from a _SpendingKey_. /// Derived from a _SpendingKey_.
pub type ProofAuthorizingKey = Scalar; pub struct ProofAuthorizingKey(pub Scalar);
impl fmt::Debug for ProofAuthorizingKey { impl Deref for ProofAuthorizingKey {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { type Target = Scalar;
f.debug_tuple("ProofAuthorizingKey")
.field(&hex::encode(&self.0)) fn deref(&self) -> &Scalar {
.finish() &self.0
} }
} }
// impl fmt::Debug for ProofAuthorizingKey {
// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// f.debug_tuple("ProofAuthorizingKey")
// .field(&hex::encode(&self.0))
// .finish()
// }
// }
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.
/// ///
@ -92,11 +109,11 @@ impl From<SpendingKey> for ProofAuthorizingKey {
.hash_length(64) .hash_length(64)
.personal(b"Zcash_ExpandSeed") .personal(b"Zcash_ExpandSeed")
.to_state() .to_state()
.update(spending_key.0[..]) .update(&spending_key.0[..])
.update([1]) .update(&[1])
.finalize(); .finalize();
Self::from(hash) Self(Scalar::from_bytes_wide(hash.as_array()))
} }
} }
@ -122,33 +139,75 @@ impl From<SpendingKey> for OutgoingViewingKey {
.hash_length(64) .hash_length(64)
.personal(b"Zcash_ExpandSeed") .personal(b"Zcash_ExpandSeed")
.to_state() .to_state()
.update(spending_key.0[..]) .update(&spending_key.0[..])
.update([2]) .update(&[2])
.finalize(); .finalize();
Self::from(hash[0..32]) let mut bytes = [0u8; 32];
bytes[..].copy_from_slice(hash.as_bytes());
Self(bytes)
} }
} }
/// ///
pub type AuthorizingKey = redjubjub::PublicKeyBytes<redjubjub::SpendAuth>; pub type AuthorizingKey = jubjub::AffinePoint;
impl fmt::Debug for AuthorizingKey { // impl fmt::Debug for AuthorizingKey {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { // fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_tuple("AuthorizingKey") // f.debug_struct("AuthorizingKey")
.field(&hex::encode(&self.0)) // .field("u", &hex::encode(&self.u))
.finish() // .field("v", &hex::encode(&self.v))
// .finish()
// }
// }
///
pub type NullifierDerivingKey = jubjub::AffinePoint;
///
pub struct IncomingViewingKey(pub Scalar);
impl Deref for IncomingViewingKey {
type Target = Scalar;
fn deref(&self) -> &Scalar {
&self.0
}
}
// impl fmt::Debug for IncomingViewingKey {
// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// f.debug_tuple("IncomingViewingKey")
// .field(&hex::encode(&self.0))
// .finish()
// }
// }
impl IncomingViewingKey {
/// For this invocation of Blake2s-256 as CRH^ivk.
///
/// https://zips.z.cash/protocol/protocol.pdf#saplingkeycomponents
/// https://zips.z.cash/protocol/protocol.pdf#concreteprfs
/// https://zips.z.cash/protocol/protocol.pdf#jubjub
fn new(
authorizing_key: AuthorizingKey,
nullifier_deriving_key: NullifierDerivingKey,
) -> IncomingViewingKey {
let hash = blake2s_simd::Params::new()
.hash_length(32)
.personal(b"Zcashivk")
.to_state()
// TODO: double-check that `to_bytes()` == repr_J
.update(&authorizing_key.to_bytes()[..])
.update(&nullifier_deriving_key.to_bytes()[..])
.finalize();
Self(Scalar::from_bytes(hash.as_array()).unwrap())
} }
} }
/// ///
pub type NullifierDerivingKey = redjubjub::PublicKeyBytes; #[derive(Copy, Clone, Eq, PartialEq)]
///
pub type IncomingViewingKey = Scalar;
///
#[derive(Copy, Clone, Display, Eq, PartialEq)]
pub struct Diversifier(pub [u8; 11]); pub struct Diversifier(pub [u8; 11]);
impl fmt::Debug for Diversifier { impl fmt::Debug for Diversifier {
@ -171,7 +230,7 @@ impl fmt::Debug for Diversifier {
/// _Diversifier_ by the _IncomingViewingKey_ scalar. /// _Diversifier_ by the _IncomingViewingKey_ scalar.
/// ///
/// [ps]: https://zips.z.cash/protocol/protocol.pdf#concretediversifyhash /// [ps]: https://zips.z.cash/protocol/protocol.pdf#concretediversifyhash
pub type TransmissionKey = redjubjub::PublicKeyBytes; pub type TransmissionKey = jubjub::AffinePoint;
/// Full Viewing Keys /// Full Viewing Keys
/// ///
@ -192,14 +251,14 @@ pub struct FullViewingKey {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use rand_core::OsRng;
use super::*; use super::*;
// #[test] #[test]
// TODO: test vectors, not just random data fn check_deref() {
// fn derive_keys() { let ivk = IncomingViewingKey(jubjub::Fr::zero());
// }
ivk.to_bytes();
}
} }
#[cfg(test)] #[cfg(test)]