Add a new() and impl From<[u8; 32]> for SpendingKey
Currently fills/receives 32 random bytes and forces the top 4 bits to zero, ala clamping. If there is a nicer way to csprng'ly fill 252 bits without clamping, that would be nicer, less bias.
This commit is contained in:
parent
5f7f851481
commit
2e063998fb
|
|
@ -1,6 +1,6 @@
|
||||||
//! Sprout Shielded Payment Address types.
|
//! Sprout Shielded Payment Address types.
|
||||||
|
|
||||||
use std::{fmt, io, str::FromStr};
|
use std::{fmt, io};
|
||||||
|
|
||||||
use bs58;
|
use bs58;
|
||||||
|
|
||||||
|
|
@ -154,6 +154,8 @@ impl Arbitrary for SproutShieldedAddress {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use byteorder::{ByteOrder, LittleEndian};
|
use byteorder::{ByteOrder, LittleEndian};
|
||||||
|
use rand_core::{CryptoRng, RngCore};
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use proptest::prelude::*;
|
use proptest::prelude::*;
|
||||||
|
|
@ -24,11 +25,34 @@ use sha2;
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||||
pub struct SpendingKey(pub [u8; 32]);
|
pub struct SpendingKey(pub [u8; 32]);
|
||||||
|
|
||||||
|
impl SpendingKey {
|
||||||
|
/// Generate a new _SpendingKey_ with the highest 4 bits set to
|
||||||
|
/// zero (ie, 256 random bits, clamped to 252).
|
||||||
|
pub fn new<T>(csprng: &mut T) -> Self
|
||||||
|
where
|
||||||
|
T: RngCore + CryptoRng,
|
||||||
|
{
|
||||||
|
let mut bytes = [0u8; 32];
|
||||||
|
csprng.fill_bytes(&mut bytes);
|
||||||
|
|
||||||
|
Self::from(bytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<[u8; 32]> for SpendingKey {
|
||||||
|
/// Generate a _SpendingKey_ from existing bytes, with the highest
|
||||||
|
/// 4 bits set to zero (ie, 256 bits clamped to 252).
|
||||||
|
fn from(mut bytes: [u8; 32]) -> SpendingKey {
|
||||||
|
bytes[0] &= 0b0000_1111; // Force the 4 high-order bits to zero.
|
||||||
|
SpendingKey(bytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Derived from a _SpendingKey_.
|
/// Derived from a _SpendingKey_.
|
||||||
pub type ReceivingKey = x25519_dalek::StaticSecret;
|
pub type ReceivingKey = x25519_dalek::StaticSecret;
|
||||||
|
|
||||||
impl From<SpendingKey> for ReceivingKey {
|
impl From<SpendingKey> for ReceivingKey {
|
||||||
/// For this invocation of SHA256Compress as the PRF, t=0, which
|
/// For this invocation of SHA256Compress as PRF^addr, t=0, which
|
||||||
/// is populated by default in an empty block of all zeros to
|
/// is populated by default in an empty block of all zeros to
|
||||||
/// start.
|
/// start.
|
||||||
///
|
///
|
||||||
|
|
@ -63,7 +87,7 @@ impl fmt::Debug for PayingKey {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<SpendingKey> for PayingKey {
|
impl From<SpendingKey> for PayingKey {
|
||||||
/// For this invocation of SHA256Compress as the PRF, t=1.
|
/// For this invocation of SHA256Compress as PRF^addr, t=1.
|
||||||
///
|
///
|
||||||
/// https://zips.z.cash/protocol/protocol.pdf#sproutkeycomponents
|
/// https://zips.z.cash/protocol/protocol.pdf#sproutkeycomponents
|
||||||
/// https://zips.z.cash/protocol/protocol.pdf#concreteprfs
|
/// https://zips.z.cash/protocol/protocol.pdf#concreteprfs
|
||||||
|
|
@ -98,17 +122,14 @@ pub struct IncomingViewingKey {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
use rand_core::{OsRng, RngCore};
|
use rand_core::OsRng;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
// TODO: test vectors, not just random data
|
// TODO: test vectors, not just random data
|
||||||
fn derive_keys() {
|
fn derive_keys() {
|
||||||
let mut bytes = [0u8; 32];
|
let spending_key = SpendingKey::new(&mut OsRng);
|
||||||
OsRng.fill_bytes(&mut bytes);
|
|
||||||
|
|
||||||
let spending_key = SpendingKey(bytes);
|
|
||||||
|
|
||||||
println!("{:?}", spending_key);
|
println!("{:?}", spending_key);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue