mirror of
https://github.com/Qortal/pirate-librustzcash.git
synced 2025-07-30 20:11:23 +00:00
Add ffi and computation for Sapling note commitment.
This commit is contained in:
@@ -102,6 +102,27 @@ extern "C" {
|
||||
/// `librustzcash_sapling_verification_ctx_init`.
|
||||
void librustzcash_sapling_verification_ctx_free(void *);
|
||||
|
||||
/// Compute a Sapling commitment.
|
||||
///
|
||||
/// The `diversifier` parameter must be 11 bytes in length.
|
||||
/// The `pk_d` and `r` parameters must be of length 32.
|
||||
/// The result is also of length 32 and placed in `result`.
|
||||
/// Returns false if the diversifier or pk_d is not valid
|
||||
bool librustzcash_sapling_compute_cm(
|
||||
const unsigned char *diversifier,
|
||||
const unsigned char *pk_d,
|
||||
const uint64_t value,
|
||||
const unsigned char *r,
|
||||
unsigned char *result
|
||||
);
|
||||
|
||||
/// Generate uniform Sapling commitment randomness `r`.
|
||||
/// The result is of length 32.
|
||||
/// Returns false if there was an error.
|
||||
bool librustzcash_sapling_generate_commitment_randomness(
|
||||
unsigned char *result
|
||||
);
|
||||
|
||||
/// Sprout JoinSplit proof generation.
|
||||
void librustzcash_sprout_prove(
|
||||
unsigned char *proof_out,
|
||||
|
@@ -13,7 +13,7 @@ use pairing::{BitIterator, Field, PrimeField, PrimeFieldRepr, bls12_381::{Bls12,
|
||||
|
||||
use sapling_crypto::{circuit::multipack, constants::CRH_IVK_PERSONALIZATION,
|
||||
jubjub::{edwards, FixedGenerators, JubjubBls12, JubjubEngine, JubjubParams,
|
||||
PrimeOrder, ToUniform, Unknown, fs::FsRepr},
|
||||
PrimeOrder, ToUniform, Unknown, fs::{Fs, FsRepr}},
|
||||
pedersen_hash::{pedersen_hash, Personalization}, redjubjub::{self, Signature}};
|
||||
|
||||
use sapling_crypto::circuit::sprout::{self, TREE_DEPTH as SPROUT_TREE_DEPTH};
|
||||
@@ -25,7 +25,7 @@ use blake2_rfc::blake2s::Blake2s;
|
||||
|
||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||
|
||||
use rand::OsRng;
|
||||
use rand::{OsRng, Rng};
|
||||
use std::io::BufReader;
|
||||
|
||||
use libc::{c_char, c_uchar, size_t, int64_t, uint32_t, uint64_t};
|
||||
@@ -301,6 +301,78 @@ pub extern "system" fn librustzcash_ivk_to_pkd(
|
||||
}
|
||||
}
|
||||
|
||||
/// Return 32 byte randomness, uniform, to be used for a Sapling commitment.
|
||||
#[no_mangle]
|
||||
pub extern "system" fn librustzcash_sapling_generate_commitment_randomness(
|
||||
result: *mut [c_uchar; 32],
|
||||
) -> bool {
|
||||
// create random 64 byte buffer
|
||||
let mut rng = OsRng::new().expect("should be able to construct RNG");
|
||||
let mut buffer = [0u8; 64];
|
||||
for i in 0..buffer.len() {
|
||||
buffer[i] = rng.gen();
|
||||
}
|
||||
|
||||
// TODO: Remove this debug statement
|
||||
println!("buffer of random bytes: {:?}", &buffer[..]);
|
||||
|
||||
// reduce to uniform value
|
||||
let r = <Bls12 as JubjubEngine>::Fs::to_uniform(&buffer[..]);
|
||||
let result = unsafe { &mut *result };
|
||||
r.into_repr()
|
||||
.write_le(&mut result[..])
|
||||
.expect("result must be 32 bytes");
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
/// Compute Sapling note commitment.
|
||||
#[no_mangle]
|
||||
pub extern "system" fn librustzcash_sapling_compute_cm(
|
||||
diversifier: *const [c_uchar; 11],
|
||||
pk_d: *const [c_uchar; 32],
|
||||
value: uint64_t,
|
||||
r: *const [c_uchar; 32],
|
||||
result: *mut [c_uchar; 32],
|
||||
) -> bool {
|
||||
let diversifier = sapling_crypto::primitives::Diversifier(unsafe { *diversifier });
|
||||
let g_d = match diversifier.g_d::<Bls12>(&JUBJUB) {
|
||||
Some(g_d) => g_d,
|
||||
None => return false,
|
||||
};
|
||||
|
||||
let pk_d = match edwards::Point::<Bls12, Unknown>::read(&(unsafe { &*pk_d })[..], &JUBJUB) {
|
||||
Ok(p) => p,
|
||||
Err(_) => return false,
|
||||
};
|
||||
|
||||
let pk_d = match pk_d.as_prime_order(&JUBJUB) {
|
||||
Some(pk_d) => pk_d,
|
||||
None => return false,
|
||||
};
|
||||
|
||||
// Deserialize randomness
|
||||
let r = unsafe { *r };
|
||||
let mut repr = FsRepr::default();
|
||||
repr.read_le(&r[..]).expect("length is not 32 bytes");
|
||||
let r = match Fs::from_repr(repr) {
|
||||
Ok(p) => p,
|
||||
Err(_) => return false,
|
||||
};
|
||||
|
||||
let note = sapling_crypto::primitives::Note {
|
||||
value,
|
||||
g_d,
|
||||
pk_d,
|
||||
r,
|
||||
};
|
||||
|
||||
let result = unsafe { &mut *result };
|
||||
write_le(note.cm(&JUBJUB).into_repr(), &mut result[..]);
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
/// XOR two uint64_t values and return the result, used
|
||||
/// as a temporary mechanism for introducing Rust into
|
||||
/// Zcash.
|
||||
|
Reference in New Issue
Block a user