diff --git a/Cargo.lock b/Cargo.lock index a754c35..3870758 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -230,6 +230,7 @@ dependencies = [ "pairing 0.14.2", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "sapling-crypto 0.0.1", + "zcash_primitives 0.0.0", "zcash_proofs 0.0.0", "zip32 0.0.0", ] diff --git a/librustzcash/Cargo.toml b/librustzcash/Cargo.toml index c2ab7ff..e633152 100644 --- a/librustzcash/Cargo.toml +++ b/librustzcash/Cargo.toml @@ -22,6 +22,7 @@ lazy_static = "1" byteorder = "1" rand = "0.4" sapling-crypto = { path = "../sapling-crypto" } +zcash_primitives = { path = "../zcash_primitives" } zcash_proofs = { path = "../zcash_proofs" } zip32 = { path = "../zip32" } diff --git a/librustzcash/src/rustzcash.rs b/librustzcash/src/rustzcash.rs index f264690..29df19f 100644 --- a/librustzcash/src/rustzcash.rs +++ b/librustzcash/src/rustzcash.rs @@ -6,6 +6,7 @@ extern crate libc; extern crate pairing; extern crate rand; extern crate sapling_crypto; +extern crate zcash_primitives; extern crate zcash_proofs; extern crate zip32; @@ -61,6 +62,7 @@ use std::ffi::OsString; use std::os::windows::ffi::OsStringExt; use sapling_crypto::primitives::{ProofGenerationKey, ViewingKey}; +use zcash_primitives::sapling::spend_sig; use zcash_proofs::sapling::{ CommitmentTreeWitness, SaplingProvingContext, SaplingVerificationContext, }; @@ -1069,27 +1071,8 @@ pub extern "system" fn librustzcash_sapling_spend_sig( Err(_) => return false, }; - // We compute `rsk`... - let rsk = ask.randomize(ar); - - // We compute `rk` from there (needed for key prefixing) - let rk = - redjubjub::PublicKey::from_private(&rsk, FixedGenerators::SpendingKeyGenerator, &JUBJUB); - - // Compute the signature's message for rk/spend_auth_sig - let mut data_to_be_signed = [0u8; 64]; - rk.0.write(&mut data_to_be_signed[0..32]) - .expect("message buffer should be 32 bytes"); - (&mut data_to_be_signed[32..64]).copy_from_slice(&(unsafe { &*sighash })[..]); - // Do the signing - let mut rng = OsRng::new().expect("should be able to construct RNG"); - let sig = rsk.sign( - &data_to_be_signed, - &mut rng, - FixedGenerators::SpendingKeyGenerator, - &JUBJUB, - ); + let sig = spend_sig(ask, ar, unsafe { &*sighash }, &JUBJUB); // Write out the signature sig.write(&mut (unsafe { &mut *result })[..]) diff --git a/zcash_primitives/src/lib.rs b/zcash_primitives/src/lib.rs index 6a84cc3..e053e50 100644 --- a/zcash_primitives/src/lib.rs +++ b/zcash_primitives/src/lib.rs @@ -10,6 +10,7 @@ extern crate sapling_crypto; use sapling_crypto::jubjub::JubjubBls12; +pub mod sapling; mod serialize; pub mod transaction; diff --git a/zcash_primitives/src/sapling.rs b/zcash_primitives/src/sapling.rs new file mode 100644 index 0000000..b59dc2b --- /dev/null +++ b/zcash_primitives/src/sapling.rs @@ -0,0 +1,37 @@ +use pairing::bls12_381::Bls12; +use rand::OsRng; +use sapling_crypto::{ + jubjub::{fs::Fs, FixedGenerators, JubjubBls12}, + redjubjub::{PrivateKey, PublicKey, Signature}, +}; + +/// Create the spendAuthSig for a Sapling SpendDescription. +pub fn spend_sig( + ask: PrivateKey, + ar: Fs, + sighash: &[u8; 32], + params: &JubjubBls12, +) -> Signature { + // Initialize secure RNG + let mut rng = OsRng::new().expect("should be able to construct RNG"); + + // We compute `rsk`... + let rsk = ask.randomize(ar); + + // We compute `rk` from there (needed for key prefixing) + let rk = PublicKey::from_private(&rsk, FixedGenerators::SpendingKeyGenerator, params); + + // Compute the signature's message for rk/spend_auth_sig + let mut data_to_be_signed = [0u8; 64]; + rk.0.write(&mut data_to_be_signed[0..32]) + .expect("message buffer should be 32 bytes"); + (&mut data_to_be_signed[32..64]).copy_from_slice(&sighash[..]); + + // Do the signing + rsk.sign( + &data_to_be_signed, + &mut rng, + FixedGenerators::SpendingKeyGenerator, + params, + ) +}