pirate-librustzcash/src/rustzcash.rs

112 lines
2.7 KiB
Rust
Raw Normal View History

2017-03-17 11:07:23 -06:00
extern crate libc;
2018-04-09 18:28:42 -06:00
extern crate sapling_crypto;
extern crate pairing;
2018-04-09 18:28:42 -06:00
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};
pub struct SaplingParams {
pub jubjub_params: JubjubBls12
}
#[no_mangle]
pub extern "system" fn librustzcash_init_params() -> *mut SaplingParams {
Box::into_raw(Box::new(SaplingParams{
jubjub_params: JubjubBls12::new()
}))
}
#[no_mangle]
pub extern "system" fn librustzcash_free_params(
params: *mut SaplingParams
)
{
let tmp = unsafe { Box::from_raw(params) };
drop(tmp);
}
#[no_mangle]
pub extern "system" fn librustzcash_merkle_hash(
params: *const SaplingParams,
depth: size_t,
a: *const [c_uchar; 32],
b: *const [c_uchar; 32],
result: *mut [c_uchar; 32],
)
{
// Should be okay, because caller is responsible for ensuring
// params points to valid parameters.
let params = unsafe { &*params };
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),
lhs.iter().map(|&x| x)
.take(Fr::NUM_BITS as usize)
.chain(rhs.iter().map(|&x| x).take(Fr::NUM_BITS as usize)),
&params.jubjub_params
).into_xy().0.into_repr();
// Should be okay, caller is responsible for ensuring the pointer
2018-04-12 15:01:48 -06:00
// is a valid pointer to 32 bytes that can be mutated.
let result = unsafe { &mut *result };
tmp.write_be(&mut result[..]).unwrap();
}
2017-03-17 11:07:23 -06:00
/// XOR two uint64_t values and return the result, used
/// as a temporary mechanism for introducing Rust into
/// Zcash.
#[no_mangle]
pub extern "system" fn librustzcash_xor(a: uint64_t, b: uint64_t) -> uint64_t
{
a ^ b
}
#[test]
fn test_xor() {
2017-03-17 11:36:32 -06:00
assert_eq!(librustzcash_xor(0x0f0f0f0f0f0f0f0f, 0x1111111111111111), 0x1e1e1e1e1e1e1e1e);
2017-03-17 11:07:23 -06:00
}