Update to development versions of incrementalmerkletree/bridgetree

This modifies the tests where required to use bridgetree checkpoint
identifiers.
This commit is contained in:
Kris Nuttycombe 2023-02-15 21:20:26 -07:00
parent 7d4aa67eaa
commit 8bc53ecbde
5 changed files with 39 additions and 35 deletions

1
.gitignore vendored
View File

@ -2,3 +2,4 @@
**/*.rs.bk **/*.rs.bk
Cargo.lock Cargo.lock
.vscode .vscode
action-circuit-layout.png

View File

@ -26,6 +26,7 @@ rustdoc-args = ["--cfg", "docsrs", "--html-in-header", "katex-header.html"]
aes = "0.8" aes = "0.8"
bitvec = "1" bitvec = "1"
blake2b_simd = "1" blake2b_simd = "1"
bridgetree = { version = "0.2", optional = true }
ff = "0.13" ff = "0.13"
fpe = "0.6" fpe = "0.6"
group = { version = "0.13", features = ["wnaf-memuse"] } group = { version = "0.13", features = ["wnaf-memuse"] }
@ -52,11 +53,13 @@ image = { version = ">= 0.24, < 0.24.5", optional = true } # 0.24.5 has MSRV 1.6
plotters = { version = "0.3.0", optional = true } plotters = { version = "0.3.0", optional = true }
[dev-dependencies] [dev-dependencies]
bridgetree = "0.2"
criterion = "0.3" criterion = "0.3"
halo2_gadgets = { version = "0.3", features = ["test-dependencies"] } halo2_gadgets = { version = "0.3", features = ["test-dependencies"] }
hex = "0.4" hex = "0.4"
proptest = "1.0.0" proptest = "1.0.0"
zcash_note_encryption = { version = "0.3", features = ["pre-zip-212"] } zcash_note_encryption = { version = "0.3", features = ["pre-zip-212"] }
incrementalmerkletree = { version = "0.3", features = ["test-dependencies"] }
[target.'cfg(unix)'.dev-dependencies] [target.'cfg(unix)'.dev-dependencies]
inferno = ">= 0.11, < 0.11.15" inferno = ">= 0.11, < 0.11.15"
@ -69,7 +72,7 @@ bench = false
default = ["multicore"] default = ["multicore"]
multicore = ["halo2_proofs/multicore"] multicore = ["halo2_proofs/multicore"]
dev-graph = ["halo2_proofs/dev-graph", "image", "plotters"] dev-graph = ["halo2_proofs/dev-graph", "image", "plotters"]
test-dependencies = ["proptest"] test-dependencies = ["bridgetree", "proptest"]
[[bench]] [[bench]]
name = "note_decryption" name = "note_decryption"
@ -88,3 +91,7 @@ debug = true
[profile.bench] [profile.bench]
debug = true debug = true
[patch.crates-io]
bridgetree = { git = "https://github.com/zcash/incrementalmerkletree.git", rev = "ea1686e8f8f6c1e41aa97251a7eb4fadfd33df47" }
incrementalmerkletree = { git = "https://github.com/zcash/incrementalmerkletree.git", rev = "ea1686e8f8f6c1e41aa97251a7eb4fadfd33df47" }

View File

@ -759,8 +759,8 @@ impl OutputView for RecipientInfo {
#[cfg(any(test, feature = "test-dependencies"))] #[cfg(any(test, feature = "test-dependencies"))]
#[cfg_attr(docsrs, doc(cfg(feature = "test-dependencies")))] #[cfg_attr(docsrs, doc(cfg(feature = "test-dependencies")))]
pub mod testing { pub mod testing {
use bridgetree::BridgeTree;
use core::fmt::Debug; use core::fmt::Debug;
use incrementalmerkletree::{bridgetree::BridgeTree, Tree};
use rand::{rngs::StdRng, CryptoRng, SeedableRng}; use rand::{rngs::StdRng, CryptoRng, SeedableRng};
use proptest::collection::vec; use proptest::collection::vec;
@ -853,16 +853,15 @@ pub mod testing {
rng_seed in prop::array::uniform32(prop::num::u8::ANY) rng_seed in prop::array::uniform32(prop::num::u8::ANY)
) -> ArbitraryBundleInputs<StdRng> { ) -> ArbitraryBundleInputs<StdRng> {
const MERKLE_DEPTH_ORCHARD: u8 = crate::constants::MERKLE_DEPTH_ORCHARD as u8; const MERKLE_DEPTH_ORCHARD: u8 = crate::constants::MERKLE_DEPTH_ORCHARD as u8;
let mut tree = BridgeTree::<MerkleHashOrchard, MERKLE_DEPTH_ORCHARD>::new(100); let mut tree = BridgeTree::<MerkleHashOrchard, u32, MERKLE_DEPTH_ORCHARD>::new(100, 0);
let mut notes_and_auth_paths: Vec<(Note, MerklePath)> = Vec::new(); let mut notes_and_auth_paths: Vec<(Note, MerklePath)> = Vec::new();
for note in notes.iter() { for note in notes.iter() {
let leaf = MerkleHashOrchard::from_cmx(&note.commitment().into()); let leaf = MerkleHashOrchard::from_cmx(&note.commitment().into());
tree.append(&leaf); tree.append(leaf);
let position = tree.witness().expect("tree is not empty"); let position = tree.mark().expect("tree is not empty");
let root = tree.root(0).unwrap(); let path = MerklePath::from((position, tree.witness(position, 0).expect("we just witnessed the path")));
let path = MerklePath::from((position, tree.authentication_path(position, &root).expect("we just witnessed the path")));
notes_and_auth_paths.push((*note, path)); notes_and_auth_paths.push((*note, path));
} }

View File

@ -11,7 +11,7 @@ use crate::{
}; };
use halo2_gadgets::sinsemilla::primitives::HashDomain; use halo2_gadgets::sinsemilla::primitives::HashDomain;
use incrementalmerkletree::{Altitude, Hashable}; use incrementalmerkletree::{Hashable, Level};
use pasta_curves::pallas; use pasta_curves::pallas;
use ff::{Field, PrimeField, PrimeFieldBits}; use ff::{Field, PrimeField, PrimeFieldBits};
@ -205,7 +205,7 @@ impl Hashable for MerkleHashOrchard {
/// - when hashing two leaves, we produce a node on the layer above the leaves, i.e. /// - when hashing two leaves, we produce a node on the layer above the leaves, i.e.
/// layer = 31, l = 0 /// layer = 31, l = 0
/// - when hashing to the final root, we produce the anchor with layer = 0, l = 31. /// - when hashing to the final root, we produce the anchor with layer = 0, l = 31.
fn combine(altitude: Altitude, left: &Self, right: &Self) -> Self { fn combine(level: Level, left: &Self, right: &Self) -> Self {
// MerkleCRH Sinsemilla hash domain. // MerkleCRH Sinsemilla hash domain.
let domain = HashDomain::new(MERKLE_CRH_PERSONALIZATION); let domain = HashDomain::new(MERKLE_CRH_PERSONALIZATION);
@ -213,7 +213,7 @@ impl Hashable for MerkleHashOrchard {
domain domain
.hash( .hash(
iter::empty() iter::empty()
.chain(i2lebsp_k(altitude.into()).iter().copied()) .chain(i2lebsp_k(level.into()).iter().copied())
.chain(left.0.to_le_bits().iter().by_vals().take(L_ORCHARD_MERKLE)) .chain(left.0.to_le_bits().iter().by_vals().take(L_ORCHARD_MERKLE))
.chain(right.0.to_le_bits().iter().by_vals().take(L_ORCHARD_MERKLE)), .chain(right.0.to_le_bits().iter().by_vals().take(L_ORCHARD_MERKLE)),
) )
@ -221,8 +221,8 @@ impl Hashable for MerkleHashOrchard {
) )
} }
fn empty_root(altitude: Altitude) -> Self { fn empty_root(level: Level) -> Self {
EMPTY_ROOTS[<usize>::from(altitude)] EMPTY_ROOTS[<usize>::from(level)]
} }
} }
@ -248,18 +248,14 @@ impl<'de> Deserialize<'de> for MerkleHashOrchard {
#[cfg_attr(docsrs, doc(cfg(feature = "test-dependencies")))] #[cfg_attr(docsrs, doc(cfg(feature = "test-dependencies")))]
pub mod testing { pub mod testing {
#[cfg(test)] #[cfg(test)]
use incrementalmerkletree::{ use {
crate::tree::{MerkleHashOrchard, EMPTY_ROOTS},
bridgetree::{BridgeTree, Frontier as BridgeFrontier}, bridgetree::{BridgeTree, Frontier as BridgeFrontier},
Altitude, Frontier, Tree, group::ff::PrimeField,
incrementalmerkletree::Level,
pasta_curves::pallas,
}; };
#[cfg(test)]
use crate::tree::{MerkleHashOrchard, EMPTY_ROOTS};
#[cfg(test)]
use group::ff::PrimeField;
#[cfg(test)]
use pasta_curves::pallas;
#[test] #[test]
fn test_vectors() { fn test_vectors() {
let tv_empty_roots = crate::test_vectors::commitment_tree::test_vectors().empty_roots; let tv_empty_roots = crate::test_vectors::commitment_tree::test_vectors().empty_roots;
@ -268,14 +264,14 @@ pub mod testing {
assert_eq!(tv_empty_roots[height], root.to_bytes()); assert_eq!(tv_empty_roots[height], root.to_bytes());
} }
let mut tree = BridgeTree::<MerkleHashOrchard, 4>::new(100); let mut tree = BridgeTree::<MerkleHashOrchard, u32, 4>::new(100, 0);
for (i, tv) in crate::test_vectors::merkle_path::test_vectors() for (i, tv) in crate::test_vectors::merkle_path::test_vectors()
.into_iter() .into_iter()
.enumerate() .enumerate()
{ {
let cmx = MerkleHashOrchard::from_bytes(&tv.leaves[i]).unwrap(); let cmx = MerkleHashOrchard::from_bytes(&tv.leaves[i]).unwrap();
tree.append(&cmx); tree.append(cmx);
let position = tree.witness().expect("tree is not empty"); let position = tree.mark().expect("tree is not empty");
assert_eq!(position, i.into()); assert_eq!(position, i.into());
let root = tree.root(0).unwrap(); let root = tree.root(0).unwrap();
@ -286,7 +282,7 @@ pub mod testing {
// but BridgeTree doesn't encode these. // but BridgeTree doesn't encode these.
for j in 0..=i { for j in 0..=i {
assert_eq!( assert_eq!(
tree.authentication_path(j.try_into().unwrap(), &root), tree.witness(j.try_into().unwrap(), 0).ok(),
Some( Some(
tv.paths[j] tv.paths[j]
.iter() .iter()
@ -304,14 +300,14 @@ pub mod testing {
let tv_empty_roots = crate::test_vectors::commitment_tree::test_vectors().empty_roots; let tv_empty_roots = crate::test_vectors::commitment_tree::test_vectors().empty_roots;
for (altitude, tv_root) in tv_empty_roots.iter().enumerate() { for (level, tv_root) in tv_empty_roots.iter().enumerate() {
assert_eq!( assert_eq!(
MerkleHashOrchard::empty_root(Altitude::from(altitude as u8)) MerkleHashOrchard::empty_root(Level::from(level as u8))
.0 .0
.to_repr(), .to_repr(),
*tv_root, *tv_root,
"Empty root mismatch at altitude {}", "Empty root mismatch at level {}",
altitude level
); );
} }
} }
@ -360,7 +356,7 @@ pub mod testing {
let mut frontier = BridgeFrontier::<MerkleHashOrchard, 32>::empty(); let mut frontier = BridgeFrontier::<MerkleHashOrchard, 32>::empty();
for commitment in commitments.iter() { for commitment in commitments.iter() {
let cmx = MerkleHashOrchard(pallas::Base::from_repr(*commitment).unwrap()); let cmx = MerkleHashOrchard(pallas::Base::from_repr(*commitment).unwrap());
frontier.append(&cmx); frontier.append(cmx);
} }
assert_eq!(frontier.root().0, pallas::Base::from_repr(anchor).unwrap()); assert_eq!(frontier.root().0, pallas::Base::from_repr(anchor).unwrap());
} }

View File

@ -1,4 +1,5 @@
use incrementalmerkletree::{bridgetree::BridgeTree, Hashable, Tree}; use bridgetree::BridgeTree;
use incrementalmerkletree::Hashable;
use orchard::{ use orchard::{
builder::Builder, builder::Builder,
bundle::{Authorized, Flags}, bundle::{Authorized, Flags},
@ -70,11 +71,11 @@ fn bundle_chain() {
// Use the tree with a single leaf. // Use the tree with a single leaf.
let cmx: ExtractedNoteCommitment = note.commitment().into(); let cmx: ExtractedNoteCommitment = note.commitment().into();
let leaf = MerkleHashOrchard::from_cmx(&cmx); let leaf = MerkleHashOrchard::from_cmx(&cmx);
let mut tree = BridgeTree::<MerkleHashOrchard, 32>::new(0); let mut tree = BridgeTree::<MerkleHashOrchard, u32, 32>::new(100, 0);
tree.append(&leaf); tree.append(leaf);
let position = tree.witness().unwrap(); let position = tree.mark().unwrap();
let root = tree.root(0).unwrap(); let root = tree.root(0).unwrap();
let auth_path = tree.authentication_path(position, &root).unwrap(); let auth_path = tree.witness(position, 0).unwrap();
let merkle_path = MerklePath::from_parts( let merkle_path = MerklePath::from_parts(
u64::from(position).try_into().unwrap(), u64::from(position).try_into().unwrap(),
auth_path[..].try_into().unwrap(), auth_path[..].try_into().unwrap(),