Skip to content

Commit

Permalink
Use slices of native strings to pass parameter paths into Rust
Browse files Browse the repository at this point in the history
On Windows, the slices are [u16] representing UTF-16. On all other
platforms, the slices are [u8] in the native filesystem encoding.

Closes #44.
  • Loading branch information
str4d committed Oct 27, 2018
1 parent 041671f commit bbec1b8
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 24 deletions.
15 changes: 12 additions & 3 deletions librustzcash/include/librustzcash.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@
#include <stdint.h>

extern "C" {
#ifdef WIN32
typedef uint16_t codeunit;
#else
typedef uint8_t codeunit;
#endif

void librustzcash_to_scalar(const unsigned char *input, unsigned char *result);

void librustzcash_ask_to_ak(const unsigned char *ask, unsigned char *result);
Expand All @@ -19,11 +25,14 @@ extern "C" {
/// Loads the zk-SNARK parameters into memory and saves
/// paths as necessary. Only called once.
void librustzcash_init_zksnark_params(
const char* spend_path,
const codeunit* spend_path,
size_t spend_path_len,
const char* spend_hash,
const char* output_path,
const codeunit* output_path,
size_t output_path_len,
const char* output_hash,
const char* sprout_path,
const codeunit* sprout_path,
size_t sprout_path_len,
const char* sprout_hash
);

Expand Down
100 changes: 79 additions & 21 deletions librustzcash/src/rustzcash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,19 @@ use std::io::{self, BufReader};
use libc::{c_char, c_uchar, int64_t, size_t, uint32_t, uint64_t};
use std::ffi::CStr;
use std::fs::File;
use std::path::{Path, PathBuf};
use std::slice;

#[cfg(not(target_os = "windows"))]
use std::ffi::OsStr;
#[cfg(not(target_os = "windows"))]
use std::os::unix::ffi::OsStrExt;

#[cfg(target_os = "windows")]
use std::ffi::OsString;
#[cfg(target_os = "windows")]
use std::os::windows::ffi::OsStringExt;

use sapling_crypto::primitives::{ProofGenerationKey, ValueCommitment, ViewingKey};

pub mod equihash;
Expand All @@ -67,7 +78,7 @@ static mut SPROUT_GROTH16_VK: Option<PreparedVerifyingKey<Bls12>> = None;

static mut SAPLING_SPEND_PARAMS: Option<Parameters<Bls12>> = None;
static mut SAPLING_OUTPUT_PARAMS: Option<Parameters<Bls12>> = None;
static mut SPROUT_GROTH16_PARAMS_PATH: Option<String> = None;
static mut SPROUT_GROTH16_PARAMS_PATH: Option<PathBuf> = None;

fn is_small_order<Order>(p: &edwards::Point<Bls12, Order>) -> bool {
p.double(&JUBJUB).double(&JUBJUB).double(&JUBJUB) == edwards::Point::zero()
Expand Down Expand Up @@ -114,13 +125,75 @@ fn fixed_scalar_mult(from: &[u8], p_g: FixedGenerators) -> edwards::Point<Bls12,
JUBJUB.generator(p_g).mul(f, &JUBJUB)
}

#[cfg(not(target_os = "windows"))]
#[no_mangle]
pub extern "system" fn librustzcash_init_zksnark_params(
spend_path: *const u8,
spend_path_len: usize,
spend_hash: *const c_char,
output_path: *const u8,
output_path_len: usize,
output_hash: *const c_char,
sprout_path: *const u8,
sprout_path_len: usize,
sprout_hash: *const c_char,
) {
let spend_path = Path::new(OsStr::from_bytes(unsafe {
slice::from_raw_parts(spend_path, spend_path_len)
}));
let output_path = Path::new(OsStr::from_bytes(unsafe {
slice::from_raw_parts(output_path, output_path_len)
}));
let sprout_path = Path::new(OsStr::from_bytes(unsafe {
slice::from_raw_parts(sprout_path, sprout_path_len)
}));

init_zksnark_params(
spend_path,
spend_hash,
output_path,
output_hash,
sprout_path,
sprout_hash,
)
}

#[cfg(target_os = "windows")]
#[no_mangle]
pub extern "system" fn librustzcash_init_zksnark_params(
spend_path: *const c_char,
spend_path: *const u16,
spend_path_len: usize,
spend_hash: *const c_char,
output_path: *const c_char,
output_path: *const u16,
output_path_len: usize,
output_hash: *const c_char,
sprout_path: *const c_char,
sprout_path: *const u16,
sprout_path_len: usize,
sprout_hash: *const c_char,
) {
let spend_path =
OsString::from_wide(unsafe { slice::from_raw_parts(spend_path, spend_path_len) });
let output_path =
OsString::from_wide(unsafe { slice::from_raw_parts(output_path, output_path_len) });
let sprout_path =
OsString::from_wide(unsafe { slice::from_raw_parts(sprout_path, sprout_path_len) });

init_zksnark_params(
Path::new(&spend_path),
spend_hash,
Path::new(&output_path),
output_hash,
Path::new(&sprout_path),
sprout_hash,
)
}

fn init_zksnark_params(
spend_path: &Path,
spend_hash: *const c_char,
output_path: &Path,
output_hash: *const c_char,
sprout_path: &Path,
sprout_hash: *const c_char,
) {
// Initialize jubjub parameters here
Expand All @@ -141,25 +214,10 @@ pub extern "system" fn librustzcash_init_zksnark_params(
.expect("hash should be a valid string")
.to_string();

// These should be valid CStr's, but the decoding may fail on Windows
// so we may need to use OSStr or something.
let spend_path = unsafe { CStr::from_ptr(spend_path) }
.to_str()
.expect("parameter path encoding error")
.to_string();
let output_path = unsafe { CStr::from_ptr(output_path) }
.to_str()
.expect("parameter path encoding error")
.to_string();
let sprout_path = unsafe { CStr::from_ptr(sprout_path) }
.to_str()
.expect("parameter path encoding error")
.to_string();

// Load from each of the paths
let spend_fs = File::open(spend_path).expect("couldn't load Sapling spend parameters file");
let output_fs = File::open(output_path).expect("couldn't load Sapling output parameters file");
let sprout_fs = File::open(&sprout_path).expect("couldn't load Sprout groth16 parameters file");
let sprout_fs = File::open(sprout_path).expect("couldn't load Sprout groth16 parameters file");

let mut spend_fs = hashreader::HashReader::new(BufReader::with_capacity(1024 * 1024, spend_fs));
let mut output_fs =
Expand Down Expand Up @@ -213,7 +271,7 @@ pub extern "system" fn librustzcash_init_zksnark_params(
unsafe {
SAPLING_SPEND_PARAMS = Some(spend_params);
SAPLING_OUTPUT_PARAMS = Some(output_params);
SPROUT_GROTH16_PARAMS_PATH = Some(sprout_path);
SPROUT_GROTH16_PARAMS_PATH = Some(sprout_path.to_owned());

SAPLING_SPEND_VK = Some(spend_vk);
SAPLING_OUTPUT_VK = Some(output_vk);
Expand Down

0 comments on commit bbec1b8

Please sign in to comment.