Skip to content

Commit

Permalink
ZIP 32 APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
str4d committed Aug 29, 2018
1 parent 5c16673 commit 77ee1d6
Show file tree
Hide file tree
Showing 4 changed files with 234 additions and 0 deletions.
117 changes: 117 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ rev = "7a5b5fc99ae483a0043db7547fb79a6fa44b88a9"
git = "https://github.com/zcash-hackworks/sapling-crypto"
rev = "21084bde2019c04bd34208e63c3560fe2c02fb0e"

[dependencies.zip32]
git = "https://github.com/zcash-hackworks/zip32"
rev = "176470ef41583b5bd0bd749bd1b61d417aa8ec79"

[profile.release]
lto = true
panic = 'abort'
Expand Down
29 changes: 29 additions & 0 deletions include/librustzcash.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,35 @@ extern "C" {
uint64_t vpub_old,
uint64_t vpub_new
);

/// Derive the master ExtendedSpendingKey from a seed.
void librustzcash_zip32_xsk_master(
const unsigned char *seed,
size_t seedlen,
unsigned char *xsk_master
);

/// Derive a child ExtendedSpendingKey from a parent.
void librustzcash_zip32_xsk_derive(
const unsigned char *xsk_parent,
uint32_t i,
unsigned char *xsk_i
);

/// Derive a child ExtendedFullViewingKey from a parent.
bool librustzcash_zip32_xfvk_derive(
const unsigned char *xfvk_parent,
uint32_t i,
unsigned char *xfvk_i
);

/// Derive a PaymentAddress from an ExtendedFullViewingKey.
bool librustzcash_zip32_xfvk_address(
const unsigned char *xfvk,
const unsigned char *j,
unsigned char *j_ret,
unsigned char *addr_ret
);
}

#endif // LIBRUSTZCASH_INCLUDE_H_
84 changes: 84 additions & 0 deletions src/rustzcash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ extern crate libc;
extern crate pairing;
extern crate rand;
extern crate sapling_crypto;
extern crate zip32;

mod hashreader;

Expand Down Expand Up @@ -1567,3 +1568,86 @@ pub extern "system" fn librustzcash_sapling_proving_ctx_init() -> *mut SaplingPr
pub extern "system" fn librustzcash_sapling_proving_ctx_free(ctx: *mut SaplingProvingContext) {
drop(unsafe { Box::from_raw(ctx) });
}

#[no_mangle]
pub extern "system" fn librustzcash_zip32_xsk_master(
seed: *const c_uchar,
seedlen: size_t,
xsk_master: *mut [c_uchar; 169],
) {
let seed = unsafe { std::slice::from_raw_parts(seed, seedlen) };

let xsk = zip32::ExtendedSpendingKey::master(seed);

xsk.write(&mut (unsafe { &mut *xsk_master })[..])
.expect("should be able to serialize an ExtendedSpendingKey");
}

#[no_mangle]
pub extern "system" fn librustzcash_zip32_xsk_derive(
xsk_parent: *const [c_uchar; 169],
i: uint32_t,
xsk_i: *mut [c_uchar; 169],
) {
let xsk_parent = zip32::ExtendedSpendingKey::read(&unsafe { *xsk_parent }[..])
.expect("valid ExtendedSpendingKey");
let i = zip32::ChildIndex::from_index(i);

let xsk = xsk_parent.derive_child(i);

xsk.write(&mut (unsafe { &mut *xsk_i })[..])
.expect("should be able to serialize an ExtendedSpendingKey");
}

#[no_mangle]
pub extern "system" fn librustzcash_zip32_xfvk_derive(
xfvk_parent: *const [c_uchar; 169],
i: uint32_t,
xfvk_i: *mut [c_uchar; 169],
) -> bool {
let xfvk_parent = zip32::ExtendedFullViewingKey::read(&unsafe { *xfvk_parent }[..])
.expect("valid ExtendedFullViewingKey");
let i = zip32::ChildIndex::from_index(i);

let xfvk = match xfvk_parent.derive_child(i) {
Ok(xfvk) => xfvk,
Err(_) => return false,
};

xfvk.write(&mut (unsafe { &mut *xfvk_i })[..])
.expect("should be able to serialize an ExtendedFullViewingKey");

true
}

#[no_mangle]
pub extern "system" fn librustzcash_zip32_xfvk_address(
xfvk: *const [c_uchar; 169],
j: *const [c_uchar; 11],
j_ret: *mut [c_uchar; 11],
addr_ret: *mut [c_uchar; 43],
) -> bool {
let xfvk = zip32::ExtendedFullViewingKey::read(&unsafe { *xfvk }[..])
.expect("valid ExtendedFullViewingKey");
let j = zip32::DiversifierIndex(unsafe { *j });

let addr = match xfvk.address(j) {
Ok(addr) => addr,
Err(_) => return false,
};

let j_ret = unsafe { &mut *j_ret };
let addr_ret = unsafe { &mut *addr_ret };

j_ret.copy_from_slice(&(addr.0).0);
addr_ret
.get_mut(..11)
.unwrap()
.copy_from_slice(&addr.1.diversifier.0);
addr.1
.pk_d
.write(addr_ret.get_mut(11..).unwrap())
.expect("should be able to serialize a PaymentAddress");

true
}

0 comments on commit 77ee1d6

Please sign in to comment.