Wrap AuthorizingKey around redjubjub::PublicKey<SpendAuth>

And derive From's and Into's for it, halfway through full key derivation via a test case.
This commit is contained in:
Deirdre Connolly 2020-04-03 04:45:23 -04:00 committed by Deirdre Connolly
parent 8388b13ac9
commit 7e2ae70d66
1 changed files with 68 additions and 29 deletions

View File

@ -7,12 +7,13 @@
//! //!
//! [ps]: https://zips.z.cash/protocol/protocol.pdf#saplingkeycomponents //! [ps]: https://zips.z.cash/protocol/protocol.pdf#saplingkeycomponents
use std::{fmt, ops::Deref}; use std::{convert::TryFrom, fmt, ops::Deref};
use blake2b_simd; use blake2b_simd;
use blake2s_simd; use blake2s_simd;
use jubjub; use jubjub;
use rand_core::{CryptoRng, RngCore}; use rand_core::{CryptoRng, RngCore};
use redjubjub::{self, SpendAuth};
#[cfg(test)] #[cfg(test)]
use proptest::{arbitrary::Arbitrary, array, prelude::*}; use proptest::{arbitrary::Arbitrary, array, prelude::*};
@ -81,7 +82,7 @@ impl From<[u8; 32]> for SpendingKey {
} }
/// Derived from a _SpendingKey_. /// Derived from a _SpendingKey_.
pub struct SpendAuthorizingKey(Scalar); pub struct SpendAuthorizingKey(pub Scalar);
impl Deref for SpendAuthorizingKey { impl Deref for SpendAuthorizingKey {
type Target = Scalar; type Target = Scalar;
@ -164,29 +165,40 @@ impl From<SpendingKey> for OutgoingViewingKey {
let hash_bytes = prf_expand(spending_key.0, 2); let hash_bytes = prf_expand(spending_key.0, 2);
let mut bytes = [0u8; 32]; let mut bytes = [0u8; 32];
bytes[..].copy_from_slice(&hash_bytes); bytes[..].copy_from_slice(&hash_bytes[0..32]);
Self(bytes) Self(bytes)
} }
} }
/// ///
pub struct AuthorizingKey(pub jubjub::AffinePoint); pub struct AuthorizingKey(pub redjubjub::PublicKey<SpendAuth>);
impl Deref for AuthorizingKey { impl Deref for AuthorizingKey {
type Target = jubjub::AffinePoint; type Target = redjubjub::PublicKey<SpendAuth>;
fn deref(&self) -> &jubjub::AffinePoint { fn deref(&self) -> &redjubjub::PublicKey<SpendAuth> {
&self.0 &self.0
} }
} }
impl fmt::Debug for AuthorizingKey { impl From<[u8; 32]> for AuthorizingKey {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn from(bytes: [u8; 32]) -> Self {
f.debug_struct("AuthorizingKey") let sk = redjubjub::SecretKey::<SpendAuth>::try_from(bytes).unwrap();
.field("u", &hex::encode(self.get_u().to_bytes())) Self(redjubjub::PublicKey::from(&sk))
.field("v", &hex::encode(self.get_v().to_bytes())) }
.finish() }
impl From<AuthorizingKey> for [u8; 32] {
fn from(ak: AuthorizingKey) -> [u8; 32] {
ak.into()
}
}
impl From<SpendAuthorizingKey> for AuthorizingKey {
fn from(ask: SpendAuthorizingKey) -> Self {
let sk = redjubjub::SecretKey::<SpendAuth>::try_from(ask.to_bytes()).unwrap();
Self(redjubjub::PublicKey::from(&sk))
} }
} }
@ -210,6 +222,16 @@ impl fmt::Debug for NullifierDerivingKey {
} }
} }
impl From<ProofAuthorizingKey> for NullifierDerivingKey {
/// Requires jubjub's FindGroupHash^J("Zcash_H_", "")
///
/// https://zips.z.cash/protocol/protocol.pdf#saplingkeycomponents
/// https://zips.z.cash/protocol/protocol.pdf#concretegrouphashjubjub
fn from(nsk: ProofAuthorizingKey) -> Self {
unimplemented!()
}
}
/// ///
pub struct IncomingViewingKey(pub Scalar); pub struct IncomingViewingKey(pub Scalar);
@ -235,14 +257,11 @@ impl IncomingViewingKey {
/// https://zips.z.cash/protocol/protocol.pdf#saplingkeycomponents /// https://zips.z.cash/protocol/protocol.pdf#saplingkeycomponents
/// https://zips.z.cash/protocol/protocol.pdf#concreteprfs /// https://zips.z.cash/protocol/protocol.pdf#concreteprfs
/// https://zips.z.cash/protocol/protocol.pdf#jubjub /// https://zips.z.cash/protocol/protocol.pdf#jubjub
fn new( pub fn from(
authorizing_key: AuthorizingKey, authorizing_key: AuthorizingKey,
nullifier_deriving_key: NullifierDerivingKey, nullifier_deriving_key: NullifierDerivingKey,
) -> IncomingViewingKey { ) -> IncomingViewingKey {
let hash_bytes = crh_ivk( let hash_bytes = crh_ivk(authorizing_key.into(), nullifier_deriving_key.to_bytes());
authorizing_key.to_bytes(),
nullifier_deriving_key.to_bytes(),
);
Self(Scalar::from_bytes(&hash_bytes).unwrap()) Self(Scalar::from_bytes(&hash_bytes).unwrap())
} }
@ -303,20 +322,21 @@ impl TransmissionKey {
} }
} }
// #[cfg(test)] // TODO: fix
// impl Arbitrary for TransmissionKey { #[cfg(test)]
// type Parameters = (); impl Arbitrary for TransmissionKey {
type Parameters = ();
// fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy { fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
// (array::uniform32(any::<u8>())) (array::uniform32(any::<u8>()))
// .prop_map(|transmission_key_bytes| { .prop_map(|transmission_key_bytes| {
// return Self::from_bytes(transmission_key_bytes).unwrap(); return Self::from_bytes(transmission_key_bytes);
// }) })
// .boxed() .boxed()
// } }
// type Strategy = BoxedStrategy<Self>; type Strategy = BoxedStrategy<Self>;
// } }
/// Full Viewing Keys /// Full Viewing Keys
/// ///
@ -337,6 +357,8 @@ pub struct FullViewingKey {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use rand_core::OsRng;
use super::*; use super::*;
#[test] #[test]
@ -345,6 +367,23 @@ mod tests {
ivk.to_bytes(); ivk.to_bytes();
} }
// TODO: finish
#[test]
fn derive() {
let spending_key = SpendingKey::new(&mut OsRng);
println!("{:?}", spending_key);
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);
// let incoming_viewing_key =
// IncomingViewingKey::from(authorizing_key, nullifier_deriving_key);
}
} }
#[cfg(test)] #[cfg(test)]