Commit 0fcd58d8 authored by Danny Willems's avatar Danny Willems Committed by Pierre Boutillier
Browse files

Remove rust directory

parent 8b65efc0
......@@ -2,7 +2,6 @@
This repository contains different artefacts used in [Tezos](https://gitlab.com/tezos/tezos)
- *rust* contains the Rust dependencies, grouped in a Cargo workspace.
- *packages* contains specific OPAM packages.
- *zcash-params* contains the Sapling parameters.
- *scripts* contains miscellaneous scripts.
......
This diff is collapsed.
[workspace]
members = [
# repository: https://github.com/zcash/zcash
# revision: c7b2fc101dacfb89f30f911852af7dfb1bf952f2
# plus small tweaks to Cargo.toml
"librustzcash",
"rustc-bls12-381",
]
[package]
name = "librustzcash"
description = "Rust FFI used by the zcashd binary. Not an official API."
version = "0.2.0"
authors = [
"Sean Bowe <ewillbefull@gmail.com>",
"Jack Grigg <jack@z.cash>",
"Jay Graber <jay@z.cash>",
"Simon Liu <simon@z.cash>"
]
homepage = "https://github.com/zcash/zcash"
repository = "https://github.com/zcash/zcash"
readme = "README.md"
license = "MIT OR Apache-2.0"
edition = "2018"
[lib]
name = "rustzcash"
path = "src/rustzcash.rs"
crate-type = ["staticlib"]
[dependencies]
bellman = "0.6"
blake2b_simd = "0.5"
blake2s_simd = "0.5"
ff = "0.6"
libc = "0.2"
pairing = "0.16"
lazy_static = "1"
rand_core = "0.5.1"
zcash_history = "0.2"
zcash_primitives = "0.2"
zcash_proofs = "0.2"
# librustzcash
`librustzcash` is an FFI library crate that exposes the Zcash Rust components to
the `zcashd` full node.
The FFI API does not have any stability guarantees, and will change as required
by `zcashd`.
## License
Licensed under either of
* Apache License, Version 2.0, ([LICENSE-APACHE](../LICENSE-APACHE) or
http://www.apache.org/licenses/LICENSE-2.0)
* MIT license ([LICENSE-MIT](../LICENSE-MIT) or http://opensource.org/licenses/MIT)
at your option.
### Contribution
Unless you explicitly state otherwise, any contribution intentionally
submitted for inclusion in the work by you, as defined in the Apache-2.0
license, shall be dual licensed as above, without any additional terms or
conditions.
#ifndef LIBRUSTZCASH_INCLUDE_H_
#define LIBRUSTZCASH_INCLUDE_H_
#include <stdint.h>
#ifndef __cplusplus
#include <assert.h>
#include <stdalign.h>
#endif
#define ENTRY_SERIALIZED_LENGTH 180
typedef struct HistoryEntry {
unsigned char bytes[ENTRY_SERIALIZED_LENGTH];
} HistoryEntry;
static_assert(
sizeof(HistoryEntry) == ENTRY_SERIALIZED_LENGTH,
"HistoryEntry struct is not the same size as the underlying byte array");
static_assert(alignof(HistoryEntry) == 1, "HistoryEntry struct alignment is not 1");
#ifdef __cplusplus
extern "C" {
#endif
#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);
void librustzcash_nsk_to_nk(const unsigned char *nsk, unsigned char *result);
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(
const codeunit* spend_path,
size_t spend_path_len,
const char* spend_hash,
const codeunit* output_path,
size_t output_path_len,
const char* output_hash,
const codeunit* sprout_path,
size_t sprout_path_len,
const char* sprout_hash
);
/// Validates the provided Equihash solution against
/// the given parameters, input and nonce.
bool librustzcash_eh_isvalid(
uint32_t n,
uint32_t k,
const unsigned char* input,
size_t input_len,
const unsigned char* nonce,
size_t nonce_len,
const unsigned char* soln,
size_t soln_len
);
/// Writes the "uncommitted" note value for empty leaves
/// of the merkle tree. `result` must be a valid pointer
/// to 32 bytes which will be written.
void librustzcash_tree_uncommitted(
unsigned char *result
);
/// Computes a merkle tree hash for a given depth.
/// The `depth` parameter should not be larger than
/// 62.
///
/// `a` and `b` each must be of length 32, and must each
/// be scalars of BLS12-381.
///
/// The result of the merkle tree hash is placed in
/// `result`, which must also be of length 32.
void librustzcash_merkle_hash(
size_t depth,
const unsigned char *a,
const unsigned char *b,
unsigned char *result
);
/// Computes the signature for each Spend description, given the key
/// `ask`, the re-randomization `ar`, the 32-byte sighash `sighash`,
/// and an output `result` buffer of 64-bytes for the signature.
///
/// This function will fail if the provided `ask` or `ar` are invalid.
bool librustzcash_sapling_spend_sig(
const unsigned char *ask,
const unsigned char *ar,
const unsigned char *sighash,
unsigned char *result
);
/// Creates a Sapling proving context. Please free this when you're done.
void * librustzcash_sapling_proving_ctx_init();
/// This function (using the proving context) constructs a Spend proof
/// given the necessary witness information. It outputs `cv` (the value
/// commitment) and `rk` (so that you don't have to compute it) along
/// with the proof.
bool librustzcash_sapling_spend_proof(
void *ctx,
const unsigned char *ak,
const unsigned char *nsk,
const unsigned char *diversifier,
const unsigned char *rcm,
const unsigned char *ar,
const uint64_t value,
const unsigned char *anchor,
const unsigned char *witness,
unsigned char *cv,
unsigned char *rk,
unsigned char *zkproof
);
/// This function (using the proving context) constructs an Output
/// proof given the necessary witness information. It outputs `cv`
/// and the `zkproof`.
bool librustzcash_sapling_output_proof(
void *ctx,
const unsigned char *esk,
const unsigned char *payment_address,
const unsigned char *rcm,
const uint64_t value,
unsigned char *cv,
unsigned char *zkproof
);
/// This function (using the proving context) constructs a binding
/// signature. You must provide the intended valueBalance so that
/// we can internally check consistency.
bool librustzcash_sapling_binding_sig(
const void *ctx,
int64_t valueBalance,
const unsigned char *sighash,
unsigned char *result
);
/// Frees a Sapling proving context returned from
/// `librustzcash_sapling_proving_ctx_init`.
void librustzcash_sapling_proving_ctx_free(void *);
/// Creates a Sapling verification context. Please free this
/// when you're done.
void * librustzcash_sapling_verification_ctx_init();
/// Check the validity of a Sapling Spend description,
/// accumulating the value commitment into the context.
bool librustzcash_sapling_check_spend(
void *ctx,
const unsigned char *cv,
const unsigned char *anchor,
const unsigned char *nullifier,
const unsigned char *rk,
const unsigned char *zkproof,
const unsigned char *spendAuthSig,
const unsigned char *sighashValue
);
/// Check the validity of a Sapling Output description,
/// accumulating the value commitment into the context.
bool librustzcash_sapling_check_output(
void *ctx,
const unsigned char *cv,
const unsigned char *cm,
const unsigned char *ephemeralKey,
const unsigned char *zkproof
);
/// Finally checks the validity of the entire Sapling
/// transaction given valueBalance and the binding signature.
bool librustzcash_sapling_final_check(
void *ctx,
int64_t valueBalance,
const unsigned char *bindingSig,
const unsigned char *sighashValue
);
/// Frees a Sapling verification context returned from
/// `librustzcash_sapling_verification_ctx_init`.
void librustzcash_sapling_verification_ctx_free(void *);
/// Compute a Sapling nullifier.
///
/// The `diversifier` parameter must be 11 bytes in length.
/// The `pk_d`, `r`, `ak` and `nk` 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_nf(
const unsigned char *diversifier,
const unsigned char *pk_d,
const uint64_t value,
const unsigned char *r,
const unsigned char *ak,
const unsigned char *nk,
const uint64_t position,
unsigned char *result
);
/// 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
);
/// Compute [sk] [8] P for some 32-byte
/// point P, and 32-byte Fs. If P or sk
/// are invalid, returns false. Otherwise,
/// the result is written to the 32-byte
/// `result` buffer.
bool librustzcash_sapling_ka_agree(
const unsigned char *p,
const unsigned char *sk,
unsigned char *result
);
/// Compute g_d = GH(diversifier) and returns
/// false if the diversifier is invalid.
/// Computes [esk] g_d and writes the result
/// to the 32-byte `result` buffer. Returns
/// false if `esk` is not a valid scalar.
bool librustzcash_sapling_ka_derivepublic(
const unsigned char *diversifier,
const unsigned char *esk,
unsigned char *result
);
/// Generate uniformly random scalar in Jubjub.
/// The result is of length 32.
void librustzcash_sapling_generate_r(
unsigned char *result
);
/// Sprout JoinSplit proof generation.
void librustzcash_sprout_prove(
unsigned char *proof_out,
const unsigned char *phi,
const unsigned char *rt,
const unsigned char *h_sig,
const unsigned char *in_sk1,
uint64_t in_value1,
const unsigned char *in_rho1,
const unsigned char *in_r1,
const unsigned char *in_auth1,
const unsigned char *in_sk2,
uint64_t in_value2,
const unsigned char *in_rho2,
const unsigned char *in_r2,
const unsigned char *in_auth2,
const unsigned char *out_pk1,
uint64_t out_value1,
const unsigned char *out_r1,
const unsigned char *out_pk2,
uint64_t out_value2,
const unsigned char *out_r2,
uint64_t vpub_old,
uint64_t vpub_new
);
/// Sprout JoinSplit proof verification.
bool librustzcash_sprout_verify(
const unsigned char *proof,
const unsigned char *rt,
const unsigned char *h_sig,
const unsigned char *mac1,
const unsigned char *mac2,
const unsigned char *nf1,
const unsigned char *nf2,
const unsigned char *cm1,
const unsigned char *cm2,
uint64_t vpub_old,
uint64_t vpub_new
);
/// Derive the master ExtendedSpendingKey from a seed.
void librustzcash_zip32_xsk_master(
const unsigned char *seed,
size_t seedlen,
unsigned char *xsk_master
);
/// Derive a child ExtendedSpendingKey from a parent.
void librustzcash_zip32_xsk_derive(
const unsigned char *xsk_parent,
uint32_t i,
unsigned char *xsk_i
);
/// Derive a child ExtendedFullViewingKey from a parent.
bool librustzcash_zip32_xfvk_derive(
const unsigned char *xfvk_parent,
uint32_t i,
unsigned char *xfvk_i
);
/// Derive a PaymentAddress from an ExtendedFullViewingKey.
bool librustzcash_zip32_xfvk_address(
const unsigned char *xfvk,
const unsigned char *j,
unsigned char *j_ret,
unsigned char *addr_ret
);
uint32_t librustzcash_mmr_append(
uint32_t cbranch,
uint32_t t_len,
const uint32_t *ni_ptr,
const HistoryEntry *n_ptr,
size_t p_len,
const unsigned char *nn_ptr,
unsigned char *rt_ret,
unsigned char *buf_ret
);
uint32_t librustzcash_mmr_delete(
uint32_t cbranch,
uint32_t t_len,
const uint32_t *ni_ptr,
const HistoryEntry *n_ptr,
size_t p_len,
size_t e_len,
unsigned char *rt_ret
);
uint32_t librustzcash_mmr_hash_node(
uint32_t cbranch,
const unsigned char *n_ptr,
unsigned char *h_ret
);
#ifdef __cplusplus
}
#endif
#endif // LIBRUSTZCASH_INCLUDE_H_
This diff is collapsed.
use ff::{PrimeField, PrimeFieldRepr};
use pairing::bls12_381::Bls12;
use rand_core::{OsRng, RngCore};
use zcash_primitives::jubjub::{edwards, JubjubBls12};
use zcash_primitives::primitives::{Diversifier, ViewingKey};
use crate::{
librustzcash_sapling_generate_r, librustzcash_sapling_ka_agree,
librustzcash_sapling_ka_derivepublic,
};
#[test]
fn test_key_agreement() {
let params = JubjubBls12::new();
let mut rng = OsRng;
// Create random viewing key
let vk = ViewingKey::<Bls12> {
ak: edwards::Point::rand(&mut rng, &params).mul_by_cofactor(&params),
nk: edwards::Point::rand(&mut rng, &params).mul_by_cofactor(&params),
};
// Create a random address with the viewing key
let addr = loop {
let mut d = [0; 11];
rng.fill_bytes(&mut d);
match vk.to_payment_address(Diversifier(d), &params) {
Some(a) => break a,
None => {}
}
};
// Grab ivk from our viewing key in serialized form
let ivk = vk.ivk();
let mut ivk_serialized = [0u8; 32];
ivk.into_repr().write_le(&mut ivk_serialized[..]).unwrap();
// Create random esk
let mut esk = [0u8; 32];
librustzcash_sapling_generate_r(&mut esk);
// The sender will create a shared secret with the recipient
// by multiplying the pk_d from their address with the esk
// we randomly generated
let mut shared_secret_sender = [0u8; 32];
// Serialize pk_d for the call to librustzcash_sapling_ka_agree
let mut addr_pk_d = [0u8; 32];
addr.pk_d().write(&mut addr_pk_d[..]).unwrap();
assert!(librustzcash_sapling_ka_agree(
&addr_pk_d,
&esk,
&mut shared_secret_sender
));
// Create epk for the recipient, placed in the transaction. Computed
// using the diversifier and esk.
let mut epk = [0u8; 32];
assert!(librustzcash_sapling_ka_derivepublic(
&addr.diversifier().0,
&esk,
&mut epk
));
// Create sharedSecret with ephemeral key
let mut shared_secret_recipient = [0u8; 32];
assert!(librustzcash_sapling_ka_agree(
&epk,
&ivk_serialized,
&mut shared_secret_recipient
));
assert!(!shared_secret_sender.iter().all(|&v| v == 0));
assert_eq!(shared_secret_sender, shared_secret_recipient);
}
This diff is collapsed.
use zcash_history::{Entry, EntryLink, NodeData};
use crate::{librustzcash_mmr_append, librustzcash_mmr_delete};
const NODE_DATA_16L: &[u8] = include_bytes!("./res/tree16.dat");
const NODE_DATA_1023L: &[u8] = include_bytes!("./res/tree1023.dat");
struct TreeView {
peaks: Vec<(u32, Entry)>,
extra: Vec<(u32, Entry)>,
}
fn draft(into: &mut Vec<(u32, Entry)>, nodes: &[NodeData], peak_pos: usize, h: u32) {
let node_data = nodes[peak_pos - 1].clone();
let peak: Entry = match h {
0 => node_data.into(),
_ => Entry::new(
node_data,
EntryLink::Stored((peak_pos - (1 << h) - 1) as u32),
EntryLink::Stored((peak_pos - 2) as u32),
),
};
into.push(((peak_pos - 1) as u32, peak));
}
fn prepare_tree(nodes: &[NodeData]) -> TreeView {
assert!(!nodes.is_empty());
// integer log2 of (nodes.len()+1), -1
let mut h = (32 - ((nodes.len() + 1) as u32).leading_zeros() - 1) - 1;
let mut peak_pos = (1 << (h + 1)) - 1;
let mut peaks = Vec::new();
// used later
let mut last_peak_pos = 0;
let mut last_peak_h = 0;
loop {
if peak_pos > nodes.len() {
// left child, -2^h
peak_pos -= 1 << h;
h -= 1;
}
if peak_pos <= nodes.len() {
draft(&mut peaks, nodes, peak_pos, h);
// save to be used in next loop
last_peak_pos = peak_pos;
last_peak_h = h;
// right sibling
peak_pos += (1 << (h + 1)) - 1;
}
if h == 0 {
break;
}
}
// for deletion, everything on the right slope of the last peak should be pre-loaded
let mut extra = Vec::new();
let mut h = last_peak_h;
let mut peak_pos = last_peak_pos;
while h > 0 {
let left_pos = peak_pos - (1 << h);
let right_pos = peak_pos - 1;
h -= 1;
// drafting left child
draft(&mut extra, nodes, left_pos, h);
// drafting right child
draft(&mut extra, nodes, right_pos, h);
// continuing on right slope
peak_pos = right_pos;
}
TreeView { peaks, extra }
}
fn preload_tree_append(nodes: &[NodeData]) -> (Vec<u32>, Vec<[u8; zcash_history::MAX_ENTRY_SIZE]>) {
assert!(!nodes.is_empty());