-
Notifications
You must be signed in to change notification settings - Fork 251
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ZIP 32 APIs #29
ZIP 32 APIs #29
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm wondering how this will be designed to work without repeating addresses. E.g. if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Correct; you are given back the "index" of the address being returned, and should store it so that you know to try There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wondering if the following interface is better: You give as input the index j of a valid diversifier - the method return an error if j is not a valid index; and if it is, returns the next valid diversifier There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might be; we can explore that in a follow-up PR when we have more users of the API. |
||
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_ |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,23 +5,28 @@ extern crate libc; | |
extern crate pairing; | ||
extern crate rand; | ||
extern crate sapling_crypto; | ||
extern crate zip32; | ||
|
||
mod hashreader; | ||
|
||
#[macro_use] | ||
extern crate lazy_static; | ||
|
||
use pairing::{ | ||
bls12_381::{Bls12, Fr, FrRepr}, BitIterator, Field, PrimeField, PrimeFieldRepr, | ||
bls12_381::{Bls12, Fr, FrRepr}, | ||
BitIterator, Field, PrimeField, PrimeFieldRepr, | ||
}; | ||
|
||
use sapling_crypto::{ | ||
circuit::multipack, constants::CRH_IVK_PERSONALIZATION, | ||
circuit::multipack, | ||
constants::CRH_IVK_PERSONALIZATION, | ||
jubjub::{ | ||
edwards, fs::{Fs, FsRepr}, FixedGenerators, JubjubBls12, JubjubEngine, JubjubParams, | ||
PrimeOrder, ToUniform, Unknown, | ||
edwards, | ||
fs::{Fs, FsRepr}, | ||
FixedGenerators, JubjubBls12, JubjubEngine, JubjubParams, PrimeOrder, ToUniform, Unknown, | ||
}, | ||
pedersen_hash::{pedersen_hash, Personalization}, redjubjub::{self, Signature}, | ||
pedersen_hash::{pedersen_hash, Personalization}, | ||
redjubjub::{self, Signature}, | ||
}; | ||
|
||
use sapling_crypto::circuit::sprout::{self, TREE_DEPTH as SPROUT_TREE_DEPTH}; | ||
|
@@ -1563,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) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add somewhere descriptive error message for hardened child index? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That should happen in the librustzcash repo now, where we should have a better overall error story instead of arbitrary strings. As for here, we don't get to easily send error states across the FFI :( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Where should that happen exactly? Isn't this librustzcash? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, I meant in the refactor work happening in the master branch. This PR is merging into a 2.0.1-specific branch, which will later be merged into master. |
||
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], | ||
daira marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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 | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use
extsk
,extfvk
, etc.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Huh? I thought we decided on
xsk
andxfvk
for the ZIP 32 constructs (as used in ZIP 32 itself), andexpsk
/fvk
for the corresponding Sapling key structs?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ZIP 32 uses
Ext*
.