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);
|
|
|
|
}
|
|
|
|
}
|