From 8db848139b5fdfb8f216cae71bb38511b7f5afbb Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 11 Jul 2018 01:26:07 +0100 Subject: [PATCH] Basic conversions --- Cargo.toml | 1 + src/lib.rs | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index f97aee5..0872467 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ homepage = "https://github.com/zcash-hackworks/zip32" repository = "https://github.com/zcash-hackworks/zip32" [dependencies] +lazy_static = "1.0" pairing = "0.14.2" [dependencies.sapling-crypto] diff --git a/src/lib.rs b/src/lib.rs index e696dd3..60429eb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,12 +1,21 @@ +#[macro_use] +extern crate lazy_static; extern crate pairing; extern crate sapling_crypto; use pairing::bls12_381::Bls12; -use sapling_crypto::{jubjub::JubjubEngine, primitives::ViewingKey}; +use sapling_crypto::{ + jubjub::{FixedGenerators, JubjubBls12, JubjubEngine, JubjubParams}, primitives::ViewingKey, +}; + +lazy_static! { + static ref JUBJUB: JubjubBls12 = { JubjubBls12::new() }; +} // Sapling key components /// An outgoing viewing key +#[derive(Clone, Copy)] struct OutgoingViewingKey([u8; 32]); /// A Sapling expanded spending key @@ -22,24 +31,67 @@ struct FullViewingKey { ovk: OutgoingViewingKey, } +impl FullViewingKey { + fn from_expanded_spending_key(xsk: &ExpandedSpendingKey, params: &E::Params) -> Self { + FullViewingKey { + vk: ViewingKey { + ak: params + .generator(FixedGenerators::SpendingKeyGenerator) + .mul(xsk.ask, params), + nk: params + .generator(FixedGenerators::ProofGenerationKey) + .mul(xsk.nsk, params), + }, + ovk: xsk.ovk, + } + } +} + // ZIP 32 structures /// A Sapling full viewing key fingerprint struct FVKFingerprint([u8; 32]); /// A Sapling full viewing key tag +#[derive(Clone, Copy)] struct FVKTag([u8; 4]); +impl<'a> From<&'a FVKFingerprint> for FVKTag { + fn from(fingerprint: &FVKFingerprint) -> Self { + let mut tag = [0u8; 4]; + tag.copy_from_slice(&fingerprint.0[..4]); + FVKTag(tag) + } +} + +impl From for FVKTag { + fn from(fingerprint: FVKFingerprint) -> Self { + (&fingerprint).into() + } +} + /// A child index for a derived key +#[derive(Clone, Copy)] pub enum ChildIndex { NonHardened(u32), Hardened(u32), // Hardened(n) == n + (1 << 31) == n' in path notation } +impl ChildIndex { + pub fn from_index(i: u32) -> Self { + match i { + n if n >= (1 << 31) => ChildIndex::Hardened(n - (1 << 31)), + n => ChildIndex::NonHardened(n), + } + } +} + /// A chain code +#[derive(Clone, Copy)] struct ChainCode([u8; 32]); /// A key used to derive diversifiers for a particular child key +#[derive(Clone, Copy)] struct DiversifierKey([u8; 32]); /// A Sapling extended spending key @@ -62,6 +114,19 @@ pub struct ExtendedFullViewingKey { dk: DiversifierKey, } +impl<'a> From<&'a ExtendedSpendingKey> for ExtendedFullViewingKey { + fn from(xsk: &ExtendedSpendingKey) -> Self { + ExtendedFullViewingKey { + depth: xsk.depth, + parent_fvk_tag: xsk.parent_fvk_tag, + child_index: xsk.child_index, + chain_code: xsk.chain_code, + fvk: FullViewingKey::from_expanded_spending_key(&xsk.xsk, &JUBJUB), + dk: xsk.dk, + } + } +} + #[cfg(test)] mod tests { #[test]