-
Notifications
You must be signed in to change notification settings - Fork 346
Expose API for merkle hash #3
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
Changes from all commits
f1d3570
96654ee
cb8c9eb
37f20fb
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 |
|---|---|---|
| @@ -1,7 +1,97 @@ | ||
| extern crate libc; | ||
| extern crate sapling_crypto; | ||
| extern crate pairing; | ||
|
|
||
| use libc::uint64_t; | ||
| #[macro_use] | ||
| extern crate lazy_static; | ||
|
|
||
| use pairing::{ | ||
| BitIterator, | ||
| PrimeFieldRepr, | ||
| PrimeField, | ||
| bls12_381::{ | ||
| Bls12, | ||
| Fr, | ||
| FrRepr | ||
| } | ||
| }; | ||
|
|
||
| use sapling_crypto::{ | ||
| jubjub::JubjubBls12, | ||
| pedersen_hash::{ | ||
| pedersen_hash, | ||
| Personalization | ||
| } | ||
| }; | ||
|
|
||
| use libc::{uint64_t, size_t, c_uchar}; | ||
|
|
||
| lazy_static! { | ||
| static ref JUBJUB: JubjubBls12 = { | ||
| JubjubBls12::new() | ||
| }; | ||
| } | ||
|
|
||
| #[no_mangle] | ||
| pub extern "system" fn librustzcash_tree_uncommitted( | ||
| result: *mut [c_uchar; 32] | ||
| ) | ||
| { | ||
| let tmp = sapling_crypto::primitives::Note::<Bls12>::uncommitted().into_repr(); | ||
|
|
||
| // Should be okay, caller is responsible for ensuring the pointer | ||
| // is a valid pointer to 32 bytes that can be mutated. | ||
| let result = unsafe { &mut *result }; | ||
|
|
||
| tmp.write_be(&mut result[..]).unwrap(); | ||
| } | ||
|
|
||
| #[no_mangle] | ||
| pub extern "system" fn librustzcash_merkle_hash( | ||
| depth: size_t, | ||
| a: *const [c_uchar; 32], | ||
| b: *const [c_uchar; 32], | ||
| result: *mut [c_uchar; 32], | ||
| ) | ||
| { | ||
| let mut a_repr = FrRepr::default(); | ||
| let mut b_repr = FrRepr::default(); | ||
|
|
||
| // Should be okay, because caller is responsible for ensuring | ||
| // the pointer is a valid pointer to 32 bytes, and that is the | ||
| // size of the representation | ||
| a_repr.read_be(unsafe { &(&*a)[..] }).unwrap(); | ||
|
|
||
| // Should be okay, because caller is responsible for ensuring | ||
| // the pointer is a valid pointer to 32 bytes, and that is the | ||
| // size of the representation | ||
| b_repr.read_be(unsafe { &(&*b)[..] }).unwrap(); | ||
|
|
||
| let mut lhs = [false; 256]; | ||
| let mut rhs = [false; 256]; | ||
|
|
||
| for (a, b) in lhs.iter_mut().rev().zip(BitIterator::new(a_repr)) { | ||
| *a = b; | ||
| } | ||
|
|
||
| for (a, b) in rhs.iter_mut().rev().zip(BitIterator::new(b_repr)) { | ||
| *a = b; | ||
| } | ||
|
|
||
| let tmp = pedersen_hash::<Bls12, _>( | ||
| Personalization::MerkleTree(depth), | ||
|
Contributor
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. What happens if a depth larger than 62 is passed in? Relatedly, how do panics unroll into the C++ code - as segfaults?
Collaborator
Author
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. If a depth larger than 62 is passed in, undefined behavior. Probably a segfault.
Contributor
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. Could we add a
Collaborator
Author
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. The code this calls will panic if the depth is larger then 62. |
||
| lhs.iter().map(|&x| x) | ||
| .take(Fr::NUM_BITS as usize) | ||
| .chain(rhs.iter().map(|&x| x).take(Fr::NUM_BITS as usize)), | ||
| &JUBJUB | ||
| ).into_xy().0.into_repr(); | ||
|
|
||
| // Should be okay, caller is responsible for ensuring the pointer | ||
| // is a valid pointer to 32 bytes that can be mutated. | ||
| let result = unsafe { &mut *result }; | ||
|
|
||
| tmp.write_be(&mut result[..]).unwrap(); | ||
| } | ||
|
|
||
| /// XOR two uint64_t values and return the result, used | ||
| /// as a temporary mechanism for introducing Rust into | ||
|
|
||
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.
Just to confirm, this is only the Jubjub parameters? The Sapling and Sprout CRSs will be loaded/unloaded via pointers? Or will the Sapling CRS be similarly statically-loaded?
Uh oh!
There was an error while loading. Please reload this page.
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.
@ebfull and I discussed this. The Sapling and Sprout CRSs will be loaded via an API through which zcashd passes the paths to the params. Both verification keys along with the Sapling proving key will be loaded into memory immediately, while the Sprout proving key will be loaded and unloaded on-demand.