Move CommitmentTreeWitness into zcash_primitives
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -553,6 +553,7 @@ dependencies = [
|
|||||||
"pairing 0.14.2",
|
"pairing 0.14.2",
|
||||||
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"sapling-crypto 0.0.1",
|
"sapling-crypto 0.0.1",
|
||||||
|
"zcash_primitives 0.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
|||||||
@@ -57,13 +57,14 @@ use std::os::windows::ffi::OsStringExt;
|
|||||||
|
|
||||||
use sapling_crypto::primitives::{ProofGenerationKey, ViewingKey};
|
use sapling_crypto::primitives::{ProofGenerationKey, ViewingKey};
|
||||||
use zcash_primitives::{
|
use zcash_primitives::{
|
||||||
|
merkle_tree::CommitmentTreeWitness,
|
||||||
note_encryption::sapling_ka_agree,
|
note_encryption::sapling_ka_agree,
|
||||||
sapling::{merkle_hash, spend_sig},
|
sapling::{merkle_hash, spend_sig},
|
||||||
zip32, JUBJUB,
|
zip32, JUBJUB,
|
||||||
};
|
};
|
||||||
use zcash_proofs::{
|
use zcash_proofs::{
|
||||||
load_parameters,
|
load_parameters,
|
||||||
sapling::{CommitmentTreeWitness, SaplingProvingContext, SaplingVerificationContext},
|
sapling::{SaplingProvingContext, SaplingVerificationContext},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod equihash;
|
pub mod equihash;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use ff::PrimeField;
|
use byteorder::{LittleEndian, ReadBytesExt};
|
||||||
|
use ff::{PrimeField, PrimeFieldRepr};
|
||||||
use pairing::bls12_381::{Bls12, Fr, FrRepr};
|
use pairing::bls12_381::{Bls12, Fr, FrRepr};
|
||||||
use sapling_crypto::primitives::Note;
|
use sapling_crypto::{circuit::sapling::TREE_DEPTH, primitives::Note};
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
use sapling::merkle_hash;
|
use sapling::merkle_hash;
|
||||||
@@ -191,6 +192,76 @@ impl CommitmentTree {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A witness to a path from a position in a particular Sapling commitment tree
|
||||||
|
/// to the root of that tree.
|
||||||
|
pub struct CommitmentTreeWitness {
|
||||||
|
pub auth_path: Vec<Option<(Fr, bool)>>,
|
||||||
|
pub position: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CommitmentTreeWitness {
|
||||||
|
pub fn from_slice(mut witness: &[u8]) -> Result<Self, ()> {
|
||||||
|
// Skip the first byte, which should be "32" to signify the length of
|
||||||
|
// the following vector of Pedersen hashes.
|
||||||
|
assert_eq!(witness[0], TREE_DEPTH as u8);
|
||||||
|
witness = &witness[1..];
|
||||||
|
|
||||||
|
// Begin to construct the authentication path
|
||||||
|
let mut auth_path = vec![None; TREE_DEPTH];
|
||||||
|
|
||||||
|
// The vector works in reverse
|
||||||
|
for i in (0..TREE_DEPTH).rev() {
|
||||||
|
// skip length of inner vector
|
||||||
|
assert_eq!(witness[0], 32); // the length of a pedersen hash
|
||||||
|
witness = &witness[1..];
|
||||||
|
|
||||||
|
// Grab the sibling node at this depth in the tree
|
||||||
|
let mut sibling = [0u8; 32];
|
||||||
|
sibling.copy_from_slice(&witness[0..32]);
|
||||||
|
witness = &witness[32..];
|
||||||
|
|
||||||
|
// Sibling node should be an element of Fr
|
||||||
|
let sibling = match {
|
||||||
|
let mut repr = FrRepr::default();
|
||||||
|
repr.read_le(&sibling[..]).expect("length is 32 bytes");
|
||||||
|
Fr::from_repr(repr)
|
||||||
|
} {
|
||||||
|
Ok(p) => p,
|
||||||
|
Err(_) => return Err(()),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set the value in the auth path; we put false here
|
||||||
|
// for now (signifying the position bit) which we'll
|
||||||
|
// fill in later.
|
||||||
|
auth_path[i] = Some((sibling, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the position from the witness
|
||||||
|
let position = witness
|
||||||
|
.read_u64::<LittleEndian>()
|
||||||
|
.expect("should have had index at the end");
|
||||||
|
|
||||||
|
// Given the position, let's finish constructing the authentication
|
||||||
|
// path
|
||||||
|
let mut tmp = position;
|
||||||
|
for i in 0..TREE_DEPTH {
|
||||||
|
auth_path[i].as_mut().map(|p| p.1 = (tmp & 1) == 1);
|
||||||
|
|
||||||
|
tmp >>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The witness should be empty now; if it wasn't, the caller would
|
||||||
|
// have provided more information than they should have, indicating
|
||||||
|
// a bug downstream
|
||||||
|
assert_eq!(witness.len(), 0);
|
||||||
|
|
||||||
|
Ok(CommitmentTreeWitness {
|
||||||
|
auth_path,
|
||||||
|
position,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{CommitmentTree, Hashable, Node, PathFiller, EMPTY_ROOTS};
|
use super::{CommitmentTree, Hashable, Node, PathFiller, EMPTY_ROOTS};
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ ff = { path = "../ff" }
|
|||||||
pairing = { path = "../pairing" }
|
pairing = { path = "../pairing" }
|
||||||
rand = "0.4"
|
rand = "0.4"
|
||||||
sapling-crypto = { path = "../sapling-crypto" }
|
sapling-crypto = { path = "../sapling-crypto" }
|
||||||
|
zcash_primitives = { path = "../zcash_primitives" }
|
||||||
|
|
||||||
[dependencies.blake2-rfc]
|
[dependencies.blake2-rfc]
|
||||||
git = "https://github.com/gtank/blake2-rfc"
|
git = "https://github.com/gtank/blake2-rfc"
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ extern crate ff;
|
|||||||
extern crate pairing;
|
extern crate pairing;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
extern crate sapling_crypto;
|
extern crate sapling_crypto;
|
||||||
|
extern crate zcash_primitives;
|
||||||
|
|
||||||
use bellman::groth16::{prepare_verifying_key, Parameters, PreparedVerifyingKey, VerifyingKey};
|
use bellman::groth16::{prepare_verifying_key, Parameters, PreparedVerifyingKey, VerifyingKey};
|
||||||
use pairing::bls12_381::Bls12;
|
use pairing::bls12_381::Bls12;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use sapling_crypto::jubjub::{
|
|||||||
mod prover;
|
mod prover;
|
||||||
mod verifier;
|
mod verifier;
|
||||||
|
|
||||||
pub use self::prover::{CommitmentTreeWitness, SaplingProvingContext};
|
pub use self::prover::SaplingProvingContext;
|
||||||
pub use self::verifier::SaplingVerificationContext;
|
pub use self::verifier::SaplingVerificationContext;
|
||||||
|
|
||||||
// This function computes `value` in the exponent of the value commitment base
|
// This function computes `value` in the exponent of the value commitment base
|
||||||
|
|||||||
@@ -1,92 +1,22 @@
|
|||||||
use bellman::groth16::{
|
use bellman::groth16::{
|
||||||
create_random_proof, verify_proof, Parameters, PreparedVerifyingKey, Proof,
|
create_random_proof, verify_proof, Parameters, PreparedVerifyingKey, Proof,
|
||||||
};
|
};
|
||||||
use byteorder::{LittleEndian, ReadBytesExt};
|
use ff::Field;
|
||||||
use ff::{Field, PrimeField, PrimeFieldRepr};
|
use pairing::bls12_381::{Bls12, Fr};
|
||||||
use pairing::bls12_381::{Bls12, Fr, FrRepr};
|
|
||||||
use rand::{OsRng, Rand};
|
use rand::{OsRng, Rand};
|
||||||
use sapling_crypto::{
|
use sapling_crypto::{
|
||||||
circuit::{
|
circuit::{
|
||||||
multipack,
|
multipack,
|
||||||
sapling::{Output, Spend, TREE_DEPTH},
|
sapling::{Output, Spend},
|
||||||
},
|
},
|
||||||
jubjub::{edwards, fs::Fs, FixedGenerators, JubjubBls12, Unknown},
|
jubjub::{edwards, fs::Fs, FixedGenerators, JubjubBls12, Unknown},
|
||||||
primitives::{Diversifier, Note, PaymentAddress, ProofGenerationKey, ValueCommitment},
|
primitives::{Diversifier, Note, PaymentAddress, ProofGenerationKey, ValueCommitment},
|
||||||
redjubjub::{PrivateKey, PublicKey, Signature},
|
redjubjub::{PrivateKey, PublicKey, Signature},
|
||||||
};
|
};
|
||||||
|
use zcash_primitives::merkle_tree::CommitmentTreeWitness;
|
||||||
|
|
||||||
use super::compute_value_balance;
|
use super::compute_value_balance;
|
||||||
|
|
||||||
/// A witness to a path from a postion in a particular Sapling commitment tree
|
|
||||||
/// to the root of that tree.
|
|
||||||
pub struct CommitmentTreeWitness {
|
|
||||||
auth_path: Vec<Option<(Fr, bool)>>,
|
|
||||||
position: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CommitmentTreeWitness {
|
|
||||||
pub fn from_slice(mut witness: &[u8]) -> Result<Self, ()> {
|
|
||||||
// Skip the first byte, which should be "32" to signify the length of
|
|
||||||
// the following vector of Pedersen hashes.
|
|
||||||
assert_eq!(witness[0], TREE_DEPTH as u8);
|
|
||||||
witness = &witness[1..];
|
|
||||||
|
|
||||||
// Begin to construct the authentication path
|
|
||||||
let mut auth_path = vec![None; TREE_DEPTH];
|
|
||||||
|
|
||||||
// The vector works in reverse
|
|
||||||
for i in (0..TREE_DEPTH).rev() {
|
|
||||||
// skip length of inner vector
|
|
||||||
assert_eq!(witness[0], 32); // the length of a pedersen hash
|
|
||||||
witness = &witness[1..];
|
|
||||||
|
|
||||||
// Grab the sibling node at this depth in the tree
|
|
||||||
let mut sibling = [0u8; 32];
|
|
||||||
sibling.copy_from_slice(&witness[0..32]);
|
|
||||||
witness = &witness[32..];
|
|
||||||
|
|
||||||
// Sibling node should be an element of Fr
|
|
||||||
let sibling = match {
|
|
||||||
let mut repr = FrRepr::default();
|
|
||||||
repr.read_le(&sibling[..]).expect("length is 32 bytes");
|
|
||||||
Fr::from_repr(repr)
|
|
||||||
} {
|
|
||||||
Ok(p) => p,
|
|
||||||
Err(_) => return Err(()),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Set the value in the auth path; we put false here
|
|
||||||
// for now (signifying the position bit) which we'll
|
|
||||||
// fill in later.
|
|
||||||
auth_path[i] = Some((sibling, false));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read the position from the witness
|
|
||||||
let position = witness
|
|
||||||
.read_u64::<LittleEndian>()
|
|
||||||
.expect("should have had index at the end");
|
|
||||||
|
|
||||||
// Given the position, let's finish constructing the authentication
|
|
||||||
// path
|
|
||||||
let mut tmp = position;
|
|
||||||
for i in 0..TREE_DEPTH {
|
|
||||||
auth_path[i].as_mut().map(|p| p.1 = (tmp & 1) == 1);
|
|
||||||
|
|
||||||
tmp >>= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The witness should be empty now; if it wasn't, the caller would
|
|
||||||
// have provided more information than they should have, indicating
|
|
||||||
// a bug downstream
|
|
||||||
assert_eq!(witness.len(), 0);
|
|
||||||
|
|
||||||
Ok(CommitmentTreeWitness {
|
|
||||||
auth_path,
|
|
||||||
position,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A context object for creating the Sapling components of a Zcash transaction.
|
/// A context object for creating the Sapling components of a Zcash transaction.
|
||||||
pub struct SaplingProvingContext {
|
pub struct SaplingProvingContext {
|
||||||
bsk: Fs,
|
bsk: Fs,
|
||||||
|
|||||||
Reference in New Issue
Block a user