mirror of https://github.com/zcash/zip32.git
ExtendedSpendingKey::master()
This commit is contained in:
parent
8db848139b
commit
2fdfa4b671
|
@ -15,6 +15,10 @@ repository = "https://github.com/zcash-hackworks/zip32"
|
|||
lazy_static = "1.0"
|
||||
pairing = "0.14.2"
|
||||
|
||||
[dependencies.blake2-rfc]
|
||||
git = "https://github.com/gtank/blake2-rfc"
|
||||
rev = "7a5b5fc99ae483a0043db7547fb79a6fa44b88a9"
|
||||
|
||||
[dependencies.sapling-crypto]
|
||||
git = "https://github.com/zcash-hackworks/sapling-crypto"
|
||||
rev = "21084bde2019c04bd34208e63c3560fe2c02fb0e"
|
||||
|
|
66
src/lib.rs
66
src/lib.rs
|
@ -1,19 +1,33 @@
|
|||
extern crate blake2_rfc;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
extern crate pairing;
|
||||
extern crate sapling_crypto;
|
||||
|
||||
use blake2_rfc::blake2b::{Blake2b, Blake2bResult};
|
||||
use pairing::bls12_381::Bls12;
|
||||
use sapling_crypto::{
|
||||
jubjub::{FixedGenerators, JubjubBls12, JubjubEngine, JubjubParams}, primitives::ViewingKey,
|
||||
jubjub::{FixedGenerators, JubjubBls12, JubjubEngine, JubjubParams, ToUniform},
|
||||
primitives::ViewingKey,
|
||||
};
|
||||
|
||||
lazy_static! {
|
||||
static ref JUBJUB: JubjubBls12 = { JubjubBls12::new() };
|
||||
}
|
||||
|
||||
pub const PRF_EXPAND_PERSONALIZATION: &'static [u8; 16] = b"Zcash_ExpandSeed";
|
||||
pub const ZIP32_SAPLING_MASTER_PERSONALIZATION: &'static [u8; 16] = b"ZcashIP32Sapling";
|
||||
|
||||
// Sapling key components
|
||||
|
||||
/// PRF^expand(sk, t) := BLAKE2b-512("Zcash_ExpandSeed", sk || t)
|
||||
fn prf_expand(sk: &[u8], t: &[u8]) -> Blake2bResult {
|
||||
let mut h = Blake2b::with_params(64, &[], &[], PRF_EXPAND_PERSONALIZATION);
|
||||
h.update(sk);
|
||||
h.update(t);
|
||||
h.finalize()
|
||||
}
|
||||
|
||||
/// An outgoing viewing key
|
||||
#[derive(Clone, Copy)]
|
||||
struct OutgoingViewingKey([u8; 32]);
|
||||
|
@ -31,6 +45,17 @@ struct FullViewingKey<E: JubjubEngine> {
|
|||
ovk: OutgoingViewingKey,
|
||||
}
|
||||
|
||||
impl<E: JubjubEngine> ExpandedSpendingKey<E> {
|
||||
fn from_spending_key(sk: &[u8]) -> Self {
|
||||
let ask = E::Fs::to_uniform(prf_expand(sk, &[0x00]).as_bytes());
|
||||
let nsk = E::Fs::to_uniform(prf_expand(sk, &[0x01]).as_bytes());
|
||||
let mut ovk = OutgoingViewingKey([0u8; 32]);
|
||||
ovk.0
|
||||
.copy_from_slice(&prf_expand(sk, &[0x02]).as_bytes()[..32]);
|
||||
ExpandedSpendingKey { ask, nsk, ovk }
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: JubjubEngine> FullViewingKey<E> {
|
||||
fn from_expanded_spending_key(xsk: &ExpandedSpendingKey<E>, params: &E::Params) -> Self {
|
||||
FullViewingKey {
|
||||
|
@ -70,6 +95,12 @@ impl From<FVKFingerprint> for FVKTag {
|
|||
}
|
||||
}
|
||||
|
||||
impl FVKTag {
|
||||
fn master() -> Self {
|
||||
FVKTag([0u8; 4])
|
||||
}
|
||||
}
|
||||
|
||||
/// A child index for a derived key
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum ChildIndex {
|
||||
|
@ -84,6 +115,10 @@ impl ChildIndex {
|
|||
n => ChildIndex::NonHardened(n),
|
||||
}
|
||||
}
|
||||
|
||||
fn master() -> Self {
|
||||
ChildIndex::from_index(0)
|
||||
}
|
||||
}
|
||||
|
||||
/// A chain code
|
||||
|
@ -94,6 +129,14 @@ struct ChainCode([u8; 32]);
|
|||
#[derive(Clone, Copy)]
|
||||
struct DiversifierKey([u8; 32]);
|
||||
|
||||
impl DiversifierKey {
|
||||
fn master(sk_m: &[u8]) -> Self {
|
||||
let mut dk_m = [0u8; 32];
|
||||
dk_m.copy_from_slice(&prf_expand(sk_m, &[0x10]).as_bytes()[..32]);
|
||||
DiversifierKey(dk_m)
|
||||
}
|
||||
}
|
||||
|
||||
/// A Sapling extended spending key
|
||||
pub struct ExtendedSpendingKey {
|
||||
depth: u8,
|
||||
|
@ -114,6 +157,27 @@ pub struct ExtendedFullViewingKey {
|
|||
dk: DiversifierKey,
|
||||
}
|
||||
|
||||
impl ExtendedSpendingKey {
|
||||
pub fn master(seed: &[u8]) -> Self {
|
||||
let mut h = Blake2b::with_params(64, &[], &[], ZIP32_SAPLING_MASTER_PERSONALIZATION);
|
||||
h.update(seed);
|
||||
let i = h.finalize();
|
||||
|
||||
let sk_m = &i.as_bytes()[..32];
|
||||
let mut c_m = [0u8; 32];
|
||||
c_m.copy_from_slice(&i.as_bytes()[32..]);
|
||||
|
||||
ExtendedSpendingKey {
|
||||
depth: 0,
|
||||
parent_fvk_tag: FVKTag::master(),
|
||||
child_index: ChildIndex::master(),
|
||||
chain_code: ChainCode(c_m),
|
||||
xsk: ExpandedSpendingKey::from_spending_key(sk_m),
|
||||
dk: DiversifierKey::master(sk_m),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a ExtendedSpendingKey> for ExtendedFullViewingKey {
|
||||
fn from(xsk: &ExtendedSpendingKey) -> Self {
|
||||
ExtendedFullViewingKey {
|
||||
|
|
Loading…
Reference in New Issue