From c44d70299ba9a2b3116e733ecc10fc805ff4e9da Mon Sep 17 00:00:00 2001 From: Jay Graber Date: Mon, 14 May 2018 20:40:35 -0700 Subject: [PATCH] Add ask_to_ak and nsk_to_nk --- include/librustzcash.h | 4 ++++ src/rustzcash.rs | 41 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/include/librustzcash.h b/include/librustzcash.h index 6aa388a..794662b 100644 --- a/include/librustzcash.h +++ b/include/librustzcash.h @@ -8,6 +8,10 @@ extern "C" { void librustzcash_to_scalar(const unsigned char *input, unsigned char *result); + void librustzcash_ask_to_ak(const unsigned char *ask, unsigned char *result); + + void librustzcash_nsk_to_nk(const unsigned char *nsk, unsigned char *result); + /// Loads the zk-SNARK parameters into memory and saves /// paths as necessary. Only called once. void librustzcash_init_zksnark_params( diff --git a/src/rustzcash.rs b/src/rustzcash.rs index 74fc115..b9f7b6b 100644 --- a/src/rustzcash.rs +++ b/src/rustzcash.rs @@ -13,7 +13,7 @@ use pairing::{BitIterator, Field, PrimeField, PrimeFieldRepr, bls12_381::{Bls12, use sapling_crypto::{circuit::multipack, jubjub::{edwards, FixedGenerators, JubjubBls12, JubjubEngine, JubjubParams, - ToUniform, Unknown, fs::FsRepr}, + PrimeOrder, ToUniform, Unknown, fs::FsRepr}, pedersen_hash::{pedersen_hash, Personalization}, redjubjub::{self, Signature}}; use sapling_crypto::circuit::sprout::{self, TREE_DEPTH as SPROUT_TREE_DEPTH}; @@ -71,6 +71,19 @@ fn read_le(from: &[u8]) -> FrRepr { f } +/// Reads an FsRepr from [u8] of length 32 +/// and multiplies it by the given base. +/// This will panic (abort) if length provided is +/// not correct +fn fixed_scalar_mult(from: &[u8], p_g: FixedGenerators) -> edwards::Point { + assert_eq!(from.len(), 32); + + let mut f = <::Fs as PrimeField>::Repr::default(); + f.read_le(from).expect("length is 32 bytes"); + + JUBJUB.generator(p_g).mul(f, &JUBJUB) +} + #[no_mangle] pub extern "system" fn librustzcash_init_zksnark_params( spend_path: *const c_char, @@ -202,6 +215,32 @@ pub extern "system" fn librustzcash_to_scalar( .expect("length is 32 bytes"); } +#[no_mangle] +pub extern "system" fn librustzcash_ask_to_ak( + ask: *const [c_uchar; 32], + result: *mut [c_uchar; 32], +) { + let ask = unsafe { &*ask }; + let ak = fixed_scalar_mult(ask, FixedGenerators::SpendingKeyGenerator); + + let result = unsafe { &mut *result }; + + ak.write(&mut result[..]).expect("length is 32 bytes"); +} + +#[no_mangle] +pub extern "system" fn librustzcash_nsk_to_nk( + nsk: *const [c_uchar; 32], + result: *mut [c_uchar; 32], +) { + let nsk = unsafe { &*nsk }; + let nk = fixed_scalar_mult(nsk, FixedGenerators::ProofGenerationKey); + + let result = unsafe { &mut *result }; + + nk.write(&mut result[..]).expect("length is 32 bytes"); +} + /// XOR two uint64_t values and return the result, used /// as a temporary mechanism for introducing Rust into /// Zcash.