From be1b3074463a574cdcb2123596a62b32cf93fdbe Mon Sep 17 00:00:00 2001 From: Jay Graber Date: Mon, 14 May 2018 22:34:27 -0700 Subject: [PATCH] Add check_diversifier and ivk_to_pkd --- include/librustzcash.h | 4 ++++ src/rustzcash.rs | 40 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/include/librustzcash.h b/include/librustzcash.h index 8473959e5..b6e11846f 100644 --- a/include/librustzcash.h +++ b/include/librustzcash.h @@ -14,6 +14,10 @@ extern "C" { void librustzcash_crh_ivk(const unsigned char *ak, const unsigned char *nk, unsigned char *result); + bool librustzcash_check_diversifier(const unsigned char *diversifier); + + bool librustzcash_ivk_to_pkd(const unsigned char *ivk, const unsigned char *diversifier, 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 50a482d60..08fe1f3bb 100644 --- a/src/rustzcash.rs +++ b/src/rustzcash.rs @@ -74,15 +74,24 @@ fn read_le(from: &[u8]) -> FrRepr { } /// 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 { +fn read_fs(from: &[u8]) -> FsRepr { assert_eq!(from.len(), 32); let mut f = <::Fs as PrimeField>::Repr::default(); f.read_le(from).expect("length is 32 bytes"); + 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 { + let f = read_fs(from); + JUBJUB.generator(p_g).mul(f, &JUBJUB) } @@ -265,6 +274,33 @@ pub extern "system" fn librustzcash_crh_ivk( result.copy_from_slice(&h); } +#[no_mangle] +pub extern "system" fn librustzcash_check_diversifier(diversifier: *const [c_uchar; 11]) -> bool { + let diversifier = sapling_crypto::primitives::Diversifier(unsafe { *diversifier }); + diversifier.g_d::(&JUBJUB).is_some() +} + +#[no_mangle] +pub extern "system" fn librustzcash_ivk_to_pkd( + ivk: *const [c_uchar; 32], + diversifier: *const [c_uchar; 11], + result: *mut [c_uchar; 32], +) -> bool { + let ivk = read_fs(unsafe { &*ivk }); + let diversifier = sapling_crypto::primitives::Diversifier(unsafe { *diversifier }); + if let Some(g_d) = diversifier.g_d::(&JUBJUB) { + let pk_d = g_d.mul(ivk, &JUBJUB); + + let result = unsafe { &mut *result }; + + pk_d.write(&mut result[..]).expect("length is 32 bytes"); + + true + } else { + false + } +} + /// XOR two uint64_t values and return the result, used /// as a temporary mechanism for introducing Rust into /// Zcash.