zip32/src/lib.rs

137 lines
3.3 KiB
Rust
Raw Normal View History

2018-07-10 17:26:07 -07:00
#[macro_use]
extern crate lazy_static;
2018-07-10 15:58:06 -07:00
extern crate pairing;
extern crate sapling_crypto;
use pairing::bls12_381::Bls12;
2018-07-10 17:26:07 -07:00
use sapling_crypto::{
jubjub::{FixedGenerators, JubjubBls12, JubjubEngine, JubjubParams}, primitives::ViewingKey,
};
lazy_static! {
static ref JUBJUB: JubjubBls12 = { JubjubBls12::new() };
}
2018-07-10 15:58:06 -07:00
// Sapling key components
/// An outgoing viewing key
2018-07-10 17:26:07 -07:00
#[derive(Clone, Copy)]
2018-07-10 15:58:06 -07:00
struct OutgoingViewingKey([u8; 32]);
/// A Sapling expanded spending key
struct ExpandedSpendingKey<E: JubjubEngine> {
ask: E::Fs,
nsk: E::Fs,
ovk: OutgoingViewingKey,
}
/// A Sapling full viewing key
struct FullViewingKey<E: JubjubEngine> {
vk: ViewingKey<E>,
ovk: OutgoingViewingKey,
}
2018-07-10 17:26:07 -07:00
impl<E: JubjubEngine> FullViewingKey<E> {
fn from_expanded_spending_key(xsk: &ExpandedSpendingKey<E>, 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,
}
}
}
2018-07-10 15:58:06 -07:00
// ZIP 32 structures
/// A Sapling full viewing key fingerprint
struct FVKFingerprint([u8; 32]);
/// A Sapling full viewing key tag
2018-07-10 17:26:07 -07:00
#[derive(Clone, Copy)]
2018-07-10 15:58:06 -07:00
struct FVKTag([u8; 4]);
2018-07-10 17:26:07 -07:00
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<FVKFingerprint> for FVKTag {
fn from(fingerprint: FVKFingerprint) -> Self {
(&fingerprint).into()
}
}
2018-07-10 15:58:06 -07:00
/// A child index for a derived key
2018-07-10 17:26:07 -07:00
#[derive(Clone, Copy)]
2018-07-10 15:58:06 -07:00
pub enum ChildIndex {
NonHardened(u32),
Hardened(u32), // Hardened(n) == n + (1 << 31) == n' in path notation
}
2018-07-10 17:26:07 -07:00
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),
}
}
}
2018-07-10 15:58:06 -07:00
/// A chain code
2018-07-10 17:26:07 -07:00
#[derive(Clone, Copy)]
2018-07-10 15:58:06 -07:00
struct ChainCode([u8; 32]);
/// A key used to derive diversifiers for a particular child key
2018-07-10 17:26:07 -07:00
#[derive(Clone, Copy)]
2018-07-10 15:58:06 -07:00
struct DiversifierKey([u8; 32]);
/// A Sapling extended spending key
pub struct ExtendedSpendingKey {
depth: u8,
parent_fvk_tag: FVKTag,
child_index: ChildIndex,
chain_code: ChainCode,
xsk: ExpandedSpendingKey<Bls12>,
dk: DiversifierKey,
}
// A Sapling extended full viewing key
pub struct ExtendedFullViewingKey {
depth: u8,
parent_fvk_tag: FVKTag,
child_index: ChildIndex,
chain_code: ChainCode,
fvk: FullViewingKey<Bls12>,
dk: DiversifierKey,
}
2018-07-10 17:26:07 -07:00
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,
}
}
}
2018-07-10 15:23:02 -07:00
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}