mirror of https://github.com/zcash/orchard.git
Merge pull request #373 from nuttycom/update_incrementalmerkletree
Update to development versions of incrementalmerkletree/bridgetree
This commit is contained in:
commit
3619b86d1c
|
@ -2,3 +2,4 @@
|
||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
Cargo.lock
|
Cargo.lock
|
||||||
.vscode
|
.vscode
|
||||||
|
action-circuit-layout.png
|
||||||
|
|
|
@ -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" }
|
||||||
|
|
|
@ -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(¬e.commitment().into());
|
let leaf = MerkleHashOrchard::from_cmx(¬e.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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
42
src/tree.rs
42
src/tree.rs
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(),
|
||||||
|
|
Loading…
Reference in New Issue