Merge pull request #204 from str4d/proving-api-ux-refactors

UX refactors for proving-related APIs
This commit is contained in:
str4d 2020-02-16 18:56:46 +00:00 committed by GitHub
commit d4bae99cb7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 114 additions and 106 deletions

View File

@ -50,7 +50,7 @@ use zcash_primitives::{
fs::{Fs, FsRepr}, fs::{Fs, FsRepr},
FixedGenerators, JubjubEngine, JubjubParams, PrimeOrder, ToUniform, Unknown, FixedGenerators, JubjubEngine, JubjubParams, PrimeOrder, ToUniform, Unknown,
}, },
merkle_tree::CommitmentTreeWitness, merkle_tree::MerklePath,
note_encryption::sapling_ka_agree, note_encryption::sapling_ka_agree,
primitives::{Diversifier, Note, PaymentAddress, ProofGenerationKey, ViewingKey}, primitives::{Diversifier, Note, PaymentAddress, ProofGenerationKey, ViewingKey},
redjubjub::{self, Signature}, redjubjub::{self, Signature},
@ -980,7 +980,7 @@ pub extern "C" fn librustzcash_sapling_spend_proof(
ar: *const [c_uchar; 32], ar: *const [c_uchar; 32],
value: u64, value: u64,
anchor: *const [c_uchar; 32], anchor: *const [c_uchar; 32],
witness: *const [c_uchar; 1 + 33 * SAPLING_TREE_DEPTH + 8], merkle_path: *const [c_uchar; 1 + 33 * SAPLING_TREE_DEPTH + 8],
cv: *mut [c_uchar; 32], cv: *mut [c_uchar; 32],
rk_out: *mut [c_uchar; 32], rk_out: *mut [c_uchar; 32],
zkproof: *mut [c_uchar; GROTH_PROOF_SIZE], zkproof: *mut [c_uchar; GROTH_PROOF_SIZE],
@ -1030,9 +1030,8 @@ pub extern "C" fn librustzcash_sapling_spend_proof(
Err(_) => return false, Err(_) => return false,
}; };
// The witness contains the incremental tree witness information, in a // Parse the Merkle path from the caller
// weird serialized format. let merkle_path = match MerklePath::from_slice(unsafe { &(&*merkle_path)[..] }) {
let witness = match CommitmentTreeWitness::from_slice(unsafe { &(&*witness)[..] }) {
Ok(w) => w, Ok(w) => w,
Err(_) => return false, Err(_) => return false,
}; };
@ -1046,7 +1045,7 @@ pub extern "C" fn librustzcash_sapling_spend_proof(
ar, ar,
value, value,
anchor, anchor,
witness, merkle_path,
unsafe { SAPLING_SPEND_PARAMS.as_ref() }.unwrap(), unsafe { SAPLING_SPEND_PARAMS.as_ref() }.unwrap(),
unsafe { SAPLING_SPEND_VK.as_ref() }.unwrap(), unsafe { SAPLING_SPEND_VK.as_ref() }.unwrap(),
&JUBJUB, &JUBJUB,

View File

@ -375,19 +375,19 @@ impl<Node: Hashable> IncrementalWitness<Node> {
} }
/// Returns the current witness, or None if the tree is empty. /// Returns the current witness, or None if the tree is empty.
pub fn path(&self) -> Option<CommitmentTreeWitness<Node>> { pub fn path(&self) -> Option<MerklePath<Node>> {
self.path_inner(SAPLING_COMMITMENT_TREE_DEPTH) self.path_inner(SAPLING_COMMITMENT_TREE_DEPTH)
} }
fn path_inner(&self, depth: usize) -> Option<CommitmentTreeWitness<Node>> { fn path_inner(&self, depth: usize) -> Option<MerklePath<Node>> {
let mut filler = self.filler(); let mut filler = self.filler();
let mut auth_path = Vec::new(); let mut auth_path = Vec::new();
if let Some(node) = self.tree.left { if let Some(node) = self.tree.left {
if self.tree.right.is_some() { if self.tree.right.is_some() {
auth_path.push(Some((node, true))); auth_path.push((node, true));
} else { } else {
auth_path.push(Some((filler.next(0), false))); auth_path.push((filler.next(0), false));
} }
} else { } else {
// Can't create an authentication path for the beginning of the tree // Can't create an authentication path for the beginning of the tree
@ -396,41 +396,37 @@ impl<Node: Hashable> IncrementalWitness<Node> {
for (i, p) in self.tree.parents.iter().enumerate() { for (i, p) in self.tree.parents.iter().enumerate() {
auth_path.push(match p { auth_path.push(match p {
Some(node) => Some((*node, true)), Some(node) => (*node, true),
None => Some((filler.next(i + 1), false)), None => (filler.next(i + 1), false),
}); });
} }
for i in self.tree.parents.len()..(depth - 1) { for i in self.tree.parents.len()..(depth - 1) {
auth_path.push(Some((filler.next(i + 1), false))); auth_path.push((filler.next(i + 1), false));
} }
assert_eq!(auth_path.len(), depth); assert_eq!(auth_path.len(), depth);
Some(CommitmentTreeWitness::from_path( Some(MerklePath::from_path(auth_path, self.position() as u64))
auth_path,
self.position() as u64,
))
} }
} }
/// A witness to a path from a position in a particular commitment tree to the root of /// A path from a position in a particular commitment tree to the root of that tree.
/// that tree.
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub struct CommitmentTreeWitness<Node: Hashable> { pub struct MerklePath<Node: Hashable> {
pub auth_path: Vec<Option<(Node, bool)>>, pub auth_path: Vec<(Node, bool)>,
pub position: u64, pub position: u64,
} }
impl<Node: Hashable> CommitmentTreeWitness<Node> { impl<Node: Hashable> MerklePath<Node> {
/// Constructs a witness directly from its path and position. /// Constructs a Merkle path directly from a path and position.
pub fn from_path(auth_path: Vec<Option<(Node, bool)>>, position: u64) -> Self { pub fn from_path(auth_path: Vec<(Node, bool)>, position: u64) -> Self {
CommitmentTreeWitness { MerklePath {
auth_path, auth_path,
position, position,
} }
} }
/// Reads a witness from its serialized form. /// Reads a Merkle path from its serialized form.
pub fn from_slice(witness: &[u8]) -> Result<Self, ()> { pub fn from_slice(witness: &[u8]) -> Result<Self, ()> {
Self::from_slice_with_depth(witness, SAPLING_COMMITMENT_TREE_DEPTH) Self::from_slice_with_depth(witness, SAPLING_COMMITMENT_TREE_DEPTH)
} }
@ -444,48 +440,41 @@ impl<Node: Hashable> CommitmentTreeWitness<Node> {
witness = &witness[1..]; witness = &witness[1..];
// Begin to construct the authentication path // Begin to construct the authentication path
let mut auth_path = vec![None; depth]; let iter = witness.chunks_exact(33);
witness = iter.remainder();
// The vector works in reverse // The vector works in reverse
for i in (0..depth).rev() { let mut auth_path = iter
// skip length of inner vector .rev()
if witness[0] != 32 { .map(|bytes| {
// the length of a pedersen hash // Length of inner vector should be the length of a Pedersen hash
return Err(()); if bytes[0] == 32 {
} // Sibling node should be an element of Fr
witness = &witness[1..]; Node::read(&bytes[1..])
.map(|sibling| {
// Grab the sibling node at this depth in the tree // Set the value in the auth path; we put false here
let mut sibling = [0u8; 32]; // for now (signifying the position bit) which we'll
sibling.copy_from_slice(&witness[0..32]); // fill in later.
witness = &witness[32..]; (sibling, false)
})
// Sibling node should be an element of Fr .map_err(|_| ())
let sibling = match Node::read(&sibling[..]) { } else {
Ok(p) => p, Err(())
Err(_) => return Err(()), }
}; })
.collect::<Result<Vec<_>, _>>()?;
// Set the value in the auth path; we put false here if auth_path.len() != depth {
// for now (signifying the position bit) which we'll return Err(());
// fill in later.
auth_path[i] = Some((sibling, false));
} }
// Read the position from the witness // Read the position from the witness
let position = match witness.read_u64::<LittleEndian>() { let position = witness.read_u64::<LittleEndian>().map_err(|_| ())?;
Ok(pos) => pos,
Err(_) => return Err(()),
};
// Given the position, let's finish constructing the authentication // Given the position, let's finish constructing the authentication
// path // path
let mut tmp = position; let mut tmp = position;
for entry in auth_path.iter_mut() { for entry in auth_path.iter_mut() {
if let Some(p) = entry { entry.1 = (tmp & 1) == 1;
p.1 = (tmp & 1) == 1;
}
tmp >>= 1; tmp >>= 1;
} }
@ -493,7 +482,7 @@ impl<Node: Hashable> CommitmentTreeWitness<Node> {
// have provided more information than they should have, indicating // have provided more information than they should have, indicating
// a bug downstream // a bug downstream
if witness.is_empty() { if witness.is_empty() {
Ok(CommitmentTreeWitness { Ok(MerklePath {
auth_path, auth_path,
position, position,
}) })
@ -501,11 +490,25 @@ impl<Node: Hashable> CommitmentTreeWitness<Node> {
Err(()) Err(())
} }
} }
/// Returns the root of the tree corresponding to this path applied to `leaf`.
pub fn root(&self, leaf: Node) -> Node {
self.auth_path
.iter()
.enumerate()
.fold(
leaf,
|root, (i, (p, leaf_is_on_right))| match leaf_is_on_right {
false => Node::combine(i, &root, p),
true => Node::combine(i, p, &root),
},
)
}
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::{CommitmentTree, CommitmentTreeWitness, Hashable, IncrementalWitness, PathFiller}; use super::{CommitmentTree, Hashable, IncrementalWitness, MerklePath, PathFiller};
use crate::sapling::Node; use crate::sapling::Node;
use ff::PrimeFieldRepr; use ff::PrimeFieldRepr;
@ -604,7 +607,7 @@ mod tests {
self.0.root_inner(TESTING_DEPTH) self.0.root_inner(TESTING_DEPTH)
} }
fn path(&self) -> Option<CommitmentTreeWitness<Node>> { fn path(&self) -> Option<MerklePath<Node>> {
self.0.path_inner(TESTING_DEPTH) self.0.path_inner(TESTING_DEPTH)
} }
} }
@ -1009,6 +1012,7 @@ mod tests {
assert_eq!(tree.size(), 0); assert_eq!(tree.size(), 0);
let mut witnesses = vec![]; let mut witnesses = vec![];
let mut last_cm = None;
let mut paths_i = 0; let mut paths_i = 0;
let mut witness_ser_i = 0; let mut witness_ser_i = 0;
for i in 0..16 { for i in 0..16 {
@ -1019,7 +1023,7 @@ mod tests {
let cm = Node::new(cm); let cm = Node::new(cm);
// Witness here // Witness here
witnesses.push(TestIncrementalWitness::from_tree(&tree)); witnesses.push((TestIncrementalWitness::from_tree(&tree), last_cm));
// Now append a commitment to the tree // Now append a commitment to the tree
assert!(tree.append(cm).is_ok()); assert!(tree.append(cm).is_ok());
@ -1033,22 +1037,23 @@ mod tests {
// Check serialization of tree // Check serialization of tree
assert_tree_ser_eq(&tree, tree_ser[i]); assert_tree_ser_eq(&tree, tree_ser[i]);
let mut first = true; // The first witness can never form a path for (witness, leaf) in witnesses.as_mut_slice() {
for witness in witnesses.as_mut_slice() {
// Append the same commitment to all the witnesses // Append the same commitment to all the witnesses
assert!(witness.append(cm).is_ok()); assert!(witness.append(cm).is_ok());
if first { if let Some(leaf) = leaf {
assert!(witness.path().is_none());
} else {
let path = witness.path().expect("should be able to create a path"); let path = witness.path().expect("should be able to create a path");
let expected = CommitmentTreeWitness::from_slice_with_depth( let expected = MerklePath::from_slice_with_depth(
&mut hex::decode(paths[paths_i]).unwrap(), &mut hex::decode(paths[paths_i]).unwrap(),
TESTING_DEPTH, TESTING_DEPTH,
) )
.unwrap(); .unwrap();
assert_eq!(path, expected); assert_eq!(path, expected);
assert_eq!(path.root(*leaf), witness.root());
paths_i += 1; paths_i += 1;
} else {
// The first witness can never form a path
assert!(witness.path().is_none());
} }
// Check witness serialization // Check witness serialization
@ -1056,15 +1061,15 @@ mod tests {
witness_ser_i += 1; witness_ser_i += 1;
assert_eq!(witness.root(), tree.root()); assert_eq!(witness.root(), tree.root());
first = false;
} }
last_cm = Some(cm);
} }
// Tree should be full now // Tree should be full now
let node = Node::blank(); let node = Node::blank();
assert!(tree.append(node).is_err()); assert!(tree.append(node).is_err());
for witness in witnesses.as_mut_slice() { for (witness, _) in witnesses.as_mut_slice() {
assert!(witness.append(node).is_err()); assert!(witness.append(node).is_err());
} }
} }

View File

@ -7,7 +7,7 @@ use crate::{
use pairing::bls12_381::{Bls12, Fr}; use pairing::bls12_381::{Bls12, Fr};
use crate::{ use crate::{
merkle_tree::CommitmentTreeWitness, merkle_tree::MerklePath,
redjubjub::{PublicKey, Signature}, redjubjub::{PublicKey, Signature},
sapling::Node, sapling::Node,
transaction::components::{Amount, GROTH_PROOF_SIZE}, transaction::components::{Amount, GROTH_PROOF_SIZE},
@ -35,7 +35,7 @@ pub trait TxProver {
ar: Fs, ar: Fs,
value: u64, value: u64,
anchor: Fr, anchor: Fr,
witness: CommitmentTreeWitness<Node>, merkle_path: MerklePath<Node>,
) -> Result< ) -> Result<
( (
[u8; GROTH_PROOF_SIZE], [u8; GROTH_PROOF_SIZE],
@ -82,7 +82,7 @@ pub(crate) mod mock {
}; };
use crate::{ use crate::{
merkle_tree::CommitmentTreeWitness, merkle_tree::MerklePath,
redjubjub::{PublicKey, Signature}, redjubjub::{PublicKey, Signature},
sapling::Node, sapling::Node,
transaction::components::{Amount, GROTH_PROOF_SIZE}, transaction::components::{Amount, GROTH_PROOF_SIZE},
@ -108,7 +108,7 @@ pub(crate) mod mock {
ar: Fs, ar: Fs,
value: u64, value: u64,
_anchor: Fr, _anchor: Fr,
_witness: CommitmentTreeWitness<Node>, _merkle_path: MerklePath<Node>,
) -> Result< ) -> Result<
( (
[u8; GROTH_PROOF_SIZE], [u8; GROTH_PROOF_SIZE],

View File

@ -13,7 +13,7 @@ use crate::{
consensus, consensus,
keys::OutgoingViewingKey, keys::OutgoingViewingKey,
legacy::TransparentAddress, legacy::TransparentAddress,
merkle_tree::{CommitmentTreeWitness, IncrementalWitness}, merkle_tree::MerklePath,
note_encryption::{generate_esk, Memo, SaplingNoteEncryption}, note_encryption::{generate_esk, Memo, SaplingNoteEncryption},
prover::TxProver, prover::TxProver,
redjubjub::PrivateKey, redjubjub::PrivateKey,
@ -44,7 +44,6 @@ pub enum Error {
ChangeIsNegative(Amount), ChangeIsNegative(Amount),
InvalidAddress, InvalidAddress,
InvalidAmount, InvalidAmount,
InvalidWitness,
NoChangeAddress, NoChangeAddress,
SpendProof, SpendProof,
} }
@ -54,7 +53,7 @@ struct SpendDescriptionInfo {
diversifier: Diversifier, diversifier: Diversifier,
note: Note<Bls12>, note: Note<Bls12>,
alpha: Fs, alpha: Fs,
witness: CommitmentTreeWitness<Node>, merkle_path: MerklePath<Node>,
} }
pub struct SaplingOutput { pub struct SaplingOutput {
@ -335,25 +334,25 @@ impl<R: RngCore + CryptoRng> Builder<R> {
/// Adds a Sapling note to be spent in this transaction. /// Adds a Sapling note to be spent in this transaction.
/// ///
/// Returns an error if the given witness does not have the same anchor as previous /// Returns an error if the given Merkle path does not have the same anchor as the
/// witnesses, or has no path. /// paths for previous Sapling notes.
pub fn add_sapling_spend( pub fn add_sapling_spend(
&mut self, &mut self,
extsk: ExtendedSpendingKey, extsk: ExtendedSpendingKey,
diversifier: Diversifier, diversifier: Diversifier,
note: Note<Bls12>, note: Note<Bls12>,
witness: IncrementalWitness<Node>, merkle_path: MerklePath<Node>,
) -> Result<(), Error> { ) -> Result<(), Error> {
// Consistency check: all anchors must equal the first one // Consistency check: all anchors must equal the first one
let cm = Node::new(note.cm(&JUBJUB).into());
if let Some(anchor) = self.anchor { if let Some(anchor) = self.anchor {
let witness_root: Fr = witness.root().into(); let path_root: Fr = merkle_path.root(cm).into();
if witness_root != anchor { if path_root != anchor {
return Err(Error::AnchorMismatch); return Err(Error::AnchorMismatch);
} }
} else { } else {
self.anchor = Some(witness.root().into()) self.anchor = Some(merkle_path.root(cm).into())
} }
let witness = witness.path().ok_or(Error::InvalidWitness)?;
let alpha = Fs::random(&mut self.rng); let alpha = Fs::random(&mut self.rng);
@ -364,7 +363,7 @@ impl<R: RngCore + CryptoRng> Builder<R> {
diversifier, diversifier,
note, note,
alpha, alpha,
witness, merkle_path,
}); });
Ok(()) Ok(())
@ -436,7 +435,7 @@ impl<R: RngCore + CryptoRng> Builder<R> {
pub fn build( pub fn build(
mut self, mut self,
consensus_branch_id: consensus::BranchId, consensus_branch_id: consensus::BranchId,
prover: impl TxProver, prover: &impl TxProver,
) -> Result<(Transaction, TransactionMetadata), Error> { ) -> Result<(Transaction, TransactionMetadata), Error> {
let mut tx_metadata = TransactionMetadata::new(); let mut tx_metadata = TransactionMetadata::new();
@ -522,7 +521,7 @@ impl<R: RngCore + CryptoRng> Builder<R> {
let mut nullifier = [0u8; 32]; let mut nullifier = [0u8; 32];
nullifier.copy_from_slice(&spend.note.nf( nullifier.copy_from_slice(&spend.note.nf(
&proof_generation_key.to_viewing_key(&JUBJUB), &proof_generation_key.to_viewing_key(&JUBJUB),
spend.witness.position, spend.merkle_path.position,
&JUBJUB, &JUBJUB,
)); ));
@ -535,7 +534,7 @@ impl<R: RngCore + CryptoRng> Builder<R> {
spend.alpha, spend.alpha,
spend.note.value, spend.note.value,
anchor, anchor,
spend.witness.clone(), spend.merkle_path.clone(),
) )
.map_err(|()| Error::SpendProof)?; .map_err(|()| Error::SpendProof)?;
@ -559,7 +558,7 @@ impl<R: RngCore + CryptoRng> Builder<R> {
// Record the post-randomized output location // Record the post-randomized output location
tx_metadata.output_indices[pos] = i; tx_metadata.output_indices[pos] = i;
output.build(&prover, &mut ctx, &mut self.rng) output.build(prover, &mut ctx, &mut self.rng)
} else { } else {
// This is a dummy output // This is a dummy output
let (dummy_to, dummy_note) = { let (dummy_to, dummy_note) = {
@ -719,7 +718,7 @@ mod tests {
{ {
let builder = Builder::new(0); let builder = Builder::new(0);
assert_eq!( assert_eq!(
builder.build(consensus::BranchId::Sapling, MockTxProver), builder.build(consensus::BranchId::Sapling, &MockTxProver),
Err(Error::ChangeIsNegative(Amount::from_i64(-10000).unwrap())) Err(Error::ChangeIsNegative(Amount::from_i64(-10000).unwrap()))
); );
} }
@ -741,7 +740,7 @@ mod tests {
) )
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
builder.build(consensus::BranchId::Sapling, MockTxProver), builder.build(consensus::BranchId::Sapling, &MockTxProver),
Err(Error::ChangeIsNegative(Amount::from_i64(-60000).unwrap())) Err(Error::ChangeIsNegative(Amount::from_i64(-60000).unwrap()))
); );
} }
@ -757,7 +756,7 @@ mod tests {
) )
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
builder.build(consensus::BranchId::Sapling, MockTxProver), builder.build(consensus::BranchId::Sapling, &MockTxProver),
Err(Error::ChangeIsNegative(Amount::from_i64(-60000).unwrap())) Err(Error::ChangeIsNegative(Amount::from_i64(-60000).unwrap()))
); );
} }
@ -779,7 +778,7 @@ mod tests {
extsk.clone(), extsk.clone(),
*to.diversifier(), *to.diversifier(),
note1.clone(), note1.clone(),
witness1.clone(), witness1.path().unwrap(),
) )
.unwrap(); .unwrap();
builder builder
@ -797,7 +796,7 @@ mod tests {
) )
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
builder.build(consensus::BranchId::Sapling, MockTxProver), builder.build(consensus::BranchId::Sapling, &MockTxProver),
Err(Error::ChangeIsNegative(Amount::from_i64(-1).unwrap())) Err(Error::ChangeIsNegative(Amount::from_i64(-1).unwrap()))
); );
} }
@ -816,10 +815,15 @@ mod tests {
{ {
let mut builder = Builder::new(0); let mut builder = Builder::new(0);
builder builder
.add_sapling_spend(extsk.clone(), *to.diversifier(), note1, witness1) .add_sapling_spend(
extsk.clone(),
*to.diversifier(),
note1,
witness1.path().unwrap(),
)
.unwrap(); .unwrap();
builder builder
.add_sapling_spend(extsk, *to.diversifier(), note2, witness2) .add_sapling_spend(extsk, *to.diversifier(), note2, witness2.path().unwrap())
.unwrap(); .unwrap();
builder builder
.add_sapling_output(ovk, to, Amount::from_u64(30000).unwrap(), None) .add_sapling_output(ovk, to, Amount::from_u64(30000).unwrap(), None)
@ -831,7 +835,7 @@ mod tests {
) )
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
builder.build(consensus::BranchId::Sapling, MockTxProver), builder.build(consensus::BranchId::Sapling, &MockTxProver),
Err(Error::BindingSig) Err(Error::BindingSig)
) )
} }

View File

@ -9,7 +9,7 @@ use zcash_primitives::{
primitives::{Diversifier, PaymentAddress, ProofGenerationKey}, primitives::{Diversifier, PaymentAddress, ProofGenerationKey},
}; };
use zcash_primitives::{ use zcash_primitives::{
merkle_tree::CommitmentTreeWitness, merkle_tree::MerklePath,
prover::TxProver, prover::TxProver,
redjubjub::{PublicKey, Signature}, redjubjub::{PublicKey, Signature},
sapling::Node, sapling::Node,
@ -127,7 +127,7 @@ impl TxProver for LocalTxProver {
ar: Fs, ar: Fs,
value: u64, value: u64,
anchor: Fr, anchor: Fr,
witness: CommitmentTreeWitness<Node>, merkle_path: MerklePath<Node>,
) -> Result< ) -> Result<
( (
[u8; GROTH_PROOF_SIZE], [u8; GROTH_PROOF_SIZE],
@ -143,7 +143,7 @@ impl TxProver for LocalTxProver {
ar, ar,
value, value,
anchor, anchor,
witness, merkle_path,
&self.spend_params, &self.spend_params,
&self.spend_vk, &self.spend_vk,
&JUBJUB, &JUBJUB,

View File

@ -10,7 +10,7 @@ use zcash_primitives::{
primitives::{Diversifier, Note, PaymentAddress, ProofGenerationKey, ValueCommitment}, primitives::{Diversifier, Note, PaymentAddress, ProofGenerationKey, ValueCommitment},
}; };
use zcash_primitives::{ use zcash_primitives::{
merkle_tree::CommitmentTreeWitness, merkle_tree::MerklePath,
redjubjub::{PrivateKey, PublicKey, Signature}, redjubjub::{PrivateKey, PublicKey, Signature},
sapling::Node, sapling::Node,
transaction::components::Amount, transaction::components::Amount,
@ -46,7 +46,7 @@ impl SaplingProvingContext {
ar: Fs, ar: Fs,
value: u64, value: u64,
anchor: Fr, anchor: Fr,
witness: CommitmentTreeWitness<Node>, merkle_path: MerklePath<Node>,
proving_key: &Parameters<Bls12>, proving_key: &Parameters<Bls12>,
verifying_key: &PreparedVerifyingKey<Bls12>, verifying_key: &PreparedVerifyingKey<Bls12>,
params: &JubjubBls12, params: &JubjubBls12,
@ -104,7 +104,7 @@ impl SaplingProvingContext {
r: rcm, r: rcm,
}; };
let nullifier = note.nf(&viewing_key, witness.position, params); let nullifier = note.nf(&viewing_key, merkle_path.position, params);
// We now have the full witness for our circuit // We now have the full witness for our circuit
let instance = Spend { let instance = Spend {
@ -114,10 +114,10 @@ impl SaplingProvingContext {
payment_address: Some(payment_address), payment_address: Some(payment_address),
commitment_randomness: Some(rcm), commitment_randomness: Some(rcm),
ar: Some(ar), ar: Some(ar),
auth_path: witness auth_path: merkle_path
.auth_path .auth_path
.iter() .iter()
.map(|n| n.map(|(node, b)| (node.into(), b))) .map(|(node, b)| Some(((*node).into(), *b)))
.collect(), .collect(),
anchor: Some(anchor), anchor: Some(anchor),
}; };