From ee32de2b8652209774f90a7c84723ab757da3be1 Mon Sep 17 00:00:00 2001 From: Deirdre Connolly Date: Tue, 24 Mar 2020 04:49:27 -0400 Subject: [PATCH] Derive Sprout ReceivingKey's from SpendingKey's via SHA256Compress Test is incomplete, also the type aliases block us from impl'ing Debug or Display. --- Cargo.lock | 1 + zebra-chain/Cargo.toml | 1 + zebra-chain/src/keys/sprout.rs | 40 ++++++++++++++++++++++++++++++++-- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 429b1bca..9fea087b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2077,6 +2077,7 @@ dependencies = [ "lazy_static", "proptest", "proptest-derive", + "rand_core 0.5.1", "redjubjub", "ripemd160", "secp256k1", diff --git a/zebra-chain/Cargo.toml b/zebra-chain/Cargo.toml index fef5908d..b66ddf62 100644 --- a/zebra-chain/Cargo.toml +++ b/zebra-chain/Cargo.toml @@ -14,6 +14,7 @@ chrono = "0.4" futures = "0.3" hex = "0.4" lazy_static = "1.4.0" +rand_core = "0.5.1" ripemd160 = "0.8.0" secp256k1 = { version = "0.17.2", features = ["serde"] } serde = { version = "1", features = ["serde_derive"] } diff --git a/zebra-chain/src/keys/sprout.rs b/zebra-chain/src/keys/sprout.rs index 15139c76..e1ac305c 100644 --- a/zebra-chain/src/keys/sprout.rs +++ b/zebra-chain/src/keys/sprout.rs @@ -11,6 +11,8 @@ use std::{ io::{self}, }; +use byteorder::{ByteOrder, LittleEndian}; + #[cfg(test)] use proptest::{array, collection::vec, prelude::*}; #[cfg(test)] @@ -24,6 +26,7 @@ use crate::serialization::{SerializationError, ZcashDeserialize, ZcashSerialize} /// /// All other Sprout key types derive from the SpendingKey value. /// Actually 252 bits. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] pub struct SpendingKey(pub [u8; 32]); /// Derived from a _SpendingKey_. @@ -31,12 +34,23 @@ pub type ReceivingKey = x25519_dalek::StaticSecret; impl From for ReceivingKey { fn from(spending_key: SpendingKey) -> ReceivingKey { - ReceivingKey::from(spending_key.0) + let mut state = [0u32; 8]; + let mut block = [0u8; 64]; + + block[0..32].copy_from_slice(&spending_key.0[..]); + block[0] |= 0b11000000; + + compress256(&mut state, &block); + + let mut derived_bytes = [0u8; 32]; + LittleEndian::write_u32_into(&state, &mut derived_bytes); + + ReceivingKey::from(derived_bytes) } } /// Derived from a _SpendingKey_. -#[derive(Copy, Clone, Eq, PartialEq)] +#[derive(Copy, Clone, Debug, Eq, PartialEq)] pub struct PayingKey(pub [u8; 32]); /// Derived from a _ReceivingKey_. @@ -48,6 +62,28 @@ pub struct IncomingViewingKey { receiving_key: ReceivingKey, } +#[cfg(test)] +mod tests { + + use rand_core::{OsRng, RngCore}; + + use super::*; + + #[test] + fn derive_receiving_key() { + let mut bytes = [0u8; 32]; + OsRng.fill_bytes(&mut bytes); + + let spending_key = SpendingKey(bytes); + + println!("{:?}", spending_key); + + let receiving_key = ReceivingKey::from(spending_key); + + // println!("{}", receiving_key); + } +} + #[cfg(test)] proptest! {