Path derivation

This commit is contained in:
Jack Grigg 2018-07-11 13:15:31 +01:00
parent e87fb329f9
commit f5d6091c93
No known key found for this signature in database
GPG Key ID: 1B8D649257DB0829
1 changed files with 55 additions and 0 deletions

View File

@ -50,6 +50,7 @@ impl OutgoingViewingKey {
}
/// A Sapling expanded spending key
#[derive(Clone)]
struct ExpandedSpendingKey<E: JubjubEngine> {
ask: E::Fs,
nsk: E::Fs,
@ -226,6 +227,7 @@ impl DiversifierKey {
}
/// A Sapling extended spending key
#[derive(Clone)]
pub struct ExtendedSpendingKey {
depth: u8,
parent_fvk_tag: FVKTag,
@ -245,6 +247,29 @@ pub struct ExtendedFullViewingKey {
dk: DiversifierKey,
}
impl std::cmp::PartialEq for ExtendedSpendingKey {
fn eq(&self, rhs: &ExtendedSpendingKey) -> bool {
self.depth == rhs.depth
&& self.parent_fvk_tag == rhs.parent_fvk_tag
&& self.child_index == rhs.child_index
&& self.chain_code == rhs.chain_code
&& self.xsk.ask == rhs.xsk.ask
&& self.xsk.nsk == rhs.xsk.nsk
&& self.xsk.ovk == rhs.xsk.ovk
&& self.dk == rhs.dk
}
}
impl std::fmt::Debug for ExtendedSpendingKey {
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
write!(
f,
"ExtendedSpendingKey(d = {}, tag_p = {:?}, i = {:?})",
self.depth, self.parent_fvk_tag, self.child_index
)
}
}
impl std::cmp::PartialEq for ExtendedFullViewingKey {
fn eq(&self, rhs: &ExtendedFullViewingKey) -> bool {
self.depth == rhs.depth
@ -288,6 +313,15 @@ impl ExtendedSpendingKey {
}
}
/// Returns the child key corresponding to the path derived from the master key
pub fn from_path(master: &ExtendedSpendingKey, path: &[ChildIndex]) -> Self {
let mut xsk = master.clone();
for &i in path.iter() {
xsk = xsk.derive_child(i);
}
xsk
}
pub fn derive_child(&self, i: ChildIndex) -> Self {
let fvk = FullViewingKey::from_expanded_spending_key(&self.xsk, &JUBJUB);
let tmp = match i {
@ -404,4 +438,25 @@ mod tests {
assert!(xfvk_5h_7.is_ok());
assert_eq!(ExtendedFullViewingKey::from(&xsk_5h_7), xfvk_5h_7.unwrap());
}
#[test]
fn path() {
let seed = [0; 32];
let xsk_m = ExtendedSpendingKey::master(&seed);
let xsk_5h = xsk_m.derive_child(ChildIndex::Hardened(5));
assert_eq!(
ExtendedSpendingKey::from_path(&xsk_m, &[ChildIndex::Hardened(5)]),
xsk_5h
);
let xsk_5h_7 = xsk_5h.derive_child(ChildIndex::NonHardened(7));
assert_eq!(
ExtendedSpendingKey::from_path(
&xsk_m,
&[ChildIndex::Hardened(5), ChildIndex::NonHardened(7)]
),
xsk_5h_7
);
}
}