Sapling incremental witnesses
This commit is contained in:
parent
bf74915053
commit
667d6101c9
|
@ -3,6 +3,7 @@ use ff::{PrimeField, PrimeFieldRepr};
|
|||
use pairing::bls12_381::{Bls12, Fr, FrRepr};
|
||||
use sapling_crypto::{circuit::sapling::TREE_DEPTH, primitives::Note};
|
||||
use std::collections::VecDeque;
|
||||
use std::iter;
|
||||
|
||||
use sapling::merkle_hash;
|
||||
|
||||
|
@ -16,7 +17,7 @@ trait Hashable: Clone + Copy {
|
|||
fn blank() -> Self;
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub struct Node {
|
||||
repr: FrRepr,
|
||||
}
|
||||
|
@ -75,6 +76,7 @@ impl PathFiller {
|
|||
}
|
||||
|
||||
/// A Merkle tree of Sapling note commitments.
|
||||
#[derive(Clone)]
|
||||
pub struct CommitmentTree {
|
||||
left: Option<Node>,
|
||||
right: Option<Node>,
|
||||
|
@ -192,25 +194,203 @@ impl CommitmentTree {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct IncrementalWitness {
|
||||
tree: CommitmentTree,
|
||||
filled: Vec<Node>,
|
||||
cursor_depth: usize,
|
||||
cursor: Option<CommitmentTree>,
|
||||
}
|
||||
|
||||
impl IncrementalWitness {
|
||||
pub fn from_tree(tree: &CommitmentTree) -> IncrementalWitness {
|
||||
IncrementalWitness {
|
||||
tree: tree.clone(),
|
||||
filled: vec![],
|
||||
cursor_depth: 0,
|
||||
cursor: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the position of the witnessed note in the commitment tree.
|
||||
pub fn position(&self) -> usize {
|
||||
self.tree.size() - 1
|
||||
}
|
||||
|
||||
fn filler(&self) -> PathFiller {
|
||||
let cursor_root = self
|
||||
.cursor
|
||||
.as_ref()
|
||||
.map(|c| c.root_inner(self.cursor_depth, PathFiller::empty()));
|
||||
|
||||
let queue = if let Some(node) = cursor_root {
|
||||
self.filled
|
||||
.iter()
|
||||
.cloned()
|
||||
.chain(iter::once(node))
|
||||
.collect()
|
||||
} else {
|
||||
self.filled.iter().cloned().collect()
|
||||
};
|
||||
|
||||
PathFiller { queue }
|
||||
}
|
||||
|
||||
/// Finds the next "depth" of an unfilled subtree.
|
||||
fn next_depth(&self) -> usize {
|
||||
let mut skip = self.filled.len();
|
||||
|
||||
if self.tree.left.is_none() {
|
||||
if skip > 0 {
|
||||
skip -= 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if self.tree.right.is_none() {
|
||||
if skip > 0 {
|
||||
skip -= 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
let mut d = 1;
|
||||
for p in &self.tree.parents {
|
||||
if p.is_none() {
|
||||
if skip > 0 {
|
||||
skip -= 1;
|
||||
} else {
|
||||
return d;
|
||||
}
|
||||
}
|
||||
d += 1;
|
||||
}
|
||||
|
||||
d + skip
|
||||
}
|
||||
|
||||
/// Tracks a note that has been added to the underlying tree. Returns an
|
||||
/// error if the tree is full.
|
||||
pub fn append(&mut self, node: Node) -> Result<(), ()> {
|
||||
self.append_inner(node, SAPLING_COMMITMENT_TREE_DEPTH)
|
||||
}
|
||||
|
||||
fn append_inner(&mut self, node: Node, depth: usize) -> Result<(), ()> {
|
||||
if let Some(mut cursor) = self.cursor.take() {
|
||||
cursor
|
||||
.append_inner(node, depth)
|
||||
.expect("cursor should not be full");
|
||||
if cursor.is_complete(self.cursor_depth) {
|
||||
self.filled
|
||||
.push(cursor.root_inner(self.cursor_depth, PathFiller::empty()));
|
||||
} else {
|
||||
self.cursor = Some(cursor);
|
||||
}
|
||||
} else {
|
||||
self.cursor_depth = self.next_depth();
|
||||
if self.cursor_depth >= depth {
|
||||
// Tree is full
|
||||
return Err(());
|
||||
}
|
||||
|
||||
if self.cursor_depth == 0 {
|
||||
self.filled.push(node);
|
||||
} else {
|
||||
let mut cursor = CommitmentTree::new();
|
||||
cursor
|
||||
.append_inner(node, depth)
|
||||
.expect("cursor should not be full");
|
||||
self.cursor = Some(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns the current root of the tree corresponding to the witness.
|
||||
pub fn root(&self) -> Node {
|
||||
self.root_inner(SAPLING_COMMITMENT_TREE_DEPTH)
|
||||
}
|
||||
|
||||
fn root_inner(&self, depth: usize) -> Node {
|
||||
self.tree.root_inner(depth, self.filler())
|
||||
}
|
||||
|
||||
/// Returns the current witness, or None if the tree is empty.
|
||||
pub fn path(&self) -> Option<CommitmentTreeWitness> {
|
||||
self.path_inner(SAPLING_COMMITMENT_TREE_DEPTH)
|
||||
}
|
||||
|
||||
fn path_inner(&self, depth: usize) -> Option<CommitmentTreeWitness> {
|
||||
let mut filler = self.filler();
|
||||
let mut auth_path = Vec::new();
|
||||
|
||||
if let Some(node) = self.tree.left {
|
||||
if self.tree.right.is_some() {
|
||||
auth_path.push(Some((node, true)));
|
||||
} else {
|
||||
auth_path.push(Some((filler.next(0), false)));
|
||||
}
|
||||
} else {
|
||||
// Can't create an authentication path for the beginning of the tree
|
||||
return None;
|
||||
}
|
||||
|
||||
for (i, p) in self.tree.parents.iter().enumerate() {
|
||||
auth_path.push(match p {
|
||||
Some(node) => Some((*node, true)),
|
||||
None => Some((filler.next(i + 1), false)),
|
||||
});
|
||||
}
|
||||
|
||||
for i in self.tree.parents.len()..(depth - 1) {
|
||||
auth_path.push(Some((filler.next(i + 1), false)));
|
||||
}
|
||||
assert_eq!(auth_path.len(), depth);
|
||||
|
||||
Some(CommitmentTreeWitness::from_path(
|
||||
auth_path
|
||||
.iter()
|
||||
.map(|n| n.map(|(node, b)| (node.into(), b)))
|
||||
.collect(),
|
||||
self.position() as u64,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
/// A witness to a path from a position in a particular Sapling commitment tree
|
||||
/// to the root of that tree.
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct CommitmentTreeWitness {
|
||||
pub auth_path: Vec<Option<(Fr, bool)>>,
|
||||
pub position: u64,
|
||||
}
|
||||
|
||||
impl CommitmentTreeWitness {
|
||||
pub fn from_slice(mut witness: &[u8]) -> Result<Self, ()> {
|
||||
pub fn from_path(auth_path: Vec<Option<(Fr, bool)>>, position: u64) -> Self {
|
||||
CommitmentTreeWitness {
|
||||
auth_path,
|
||||
position,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_slice(witness: &[u8]) -> Result<Self, ()> {
|
||||
Self::from_slice_with_depth(witness, TREE_DEPTH)
|
||||
}
|
||||
|
||||
pub fn from_slice_with_depth(mut witness: &[u8], depth: usize) -> 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);
|
||||
assert_eq!(witness[0], depth as u8);
|
||||
witness = &witness[1..];
|
||||
|
||||
// Begin to construct the authentication path
|
||||
let mut auth_path = vec![None; TREE_DEPTH];
|
||||
let mut auth_path = vec![None; depth];
|
||||
|
||||
// The vector works in reverse
|
||||
for i in (0..TREE_DEPTH).rev() {
|
||||
for i in (0..depth).rev() {
|
||||
// skip length of inner vector
|
||||
assert_eq!(witness[0], 32); // the length of a pedersen hash
|
||||
witness = &witness[1..];
|
||||
|
@ -244,7 +424,7 @@ impl CommitmentTreeWitness {
|
|||
// Given the position, let's finish constructing the authentication
|
||||
// path
|
||||
let mut tmp = position;
|
||||
for i in 0..TREE_DEPTH {
|
||||
for i in 0..depth {
|
||||
auth_path[i].as_mut().map(|p| p.1 = (tmp & 1) == 1);
|
||||
|
||||
tmp >>= 1;
|
||||
|
@ -264,7 +444,10 @@ impl CommitmentTreeWitness {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{CommitmentTree, Hashable, Node, PathFiller, EMPTY_ROOTS};
|
||||
use super::{
|
||||
CommitmentTree, CommitmentTreeWitness, Hashable, IncrementalWitness, Node, PathFiller,
|
||||
EMPTY_ROOTS,
|
||||
};
|
||||
|
||||
use ff::PrimeFieldRepr;
|
||||
use hex;
|
||||
|
@ -328,6 +511,26 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
struct TestIncrementalWitness(IncrementalWitness);
|
||||
|
||||
impl TestIncrementalWitness {
|
||||
fn from_tree(tree: &TestCommitmentTree) -> Self {
|
||||
TestIncrementalWitness(IncrementalWitness::from_tree(&tree.0))
|
||||
}
|
||||
|
||||
fn append(&mut self, node: Node) -> Result<(), ()> {
|
||||
self.0.append_inner(node, TESTING_DEPTH)
|
||||
}
|
||||
|
||||
fn root(&self) -> Node {
|
||||
self.0.root_inner(TESTING_DEPTH)
|
||||
}
|
||||
|
||||
fn path(&self) -> Option<CommitmentTreeWitness> {
|
||||
self.0.path_inner(TESTING_DEPTH)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_root_test_vectors() {
|
||||
let mut tmp = [0u8; 32];
|
||||
|
@ -410,6 +613,130 @@ mod tests {
|
|||
"5c0bea7e17bde5bee4eb795c2eec3d389a68da587b36dd687b134826ecc09308",
|
||||
];
|
||||
|
||||
// From https://github.com/zcash/zcash/blob/master/src/test/data/merkle_path_sapling.json
|
||||
let paths = [
|
||||
"0420d8283386ef2ef07ebdbb4383c12a739a953a4d6e0d6fb1139a4036d693bfbb6c20ffe9fc03f18b176c998806439ff0bb8ad193afdb27b2ccbc88856916dd804e3420817de36ab2d57feb077634bca77819c8e0bd298c04f6fed0e6a83cc1356ca15520225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114580000000000000000",
|
||||
"0420d8283386ef2ef07ebdbb4383c12a739a953a4d6e0d6fb1139a4036d693bfbb6c20ffe9fc03f18b176c998806439ff0bb8ad193afdb27b2ccbc88856916dd804e342037b3a0921a4047e617bde62b8958f86c010e6af6cc650959b9f50af8c7e8392620225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114580000000000000000",
|
||||
"0420d8283386ef2ef07ebdbb4383c12a739a953a4d6e0d6fb1139a4036d693bfbb6c20ffe9fc03f18b176c998806439ff0bb8ad193afdb27b2ccbc88856916dd804e342037b3a0921a4047e617bde62b8958f86c010e6af6cc650959b9f50af8c7e8392620b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f550100000000000000",
|
||||
"0420d8283386ef2ef07ebdbb4383c12a739a953a4d6e0d6fb1139a4036d693bfbb6c20ffe9fc03f18b176c998806439ff0bb8ad193afdb27b2ccbc88856916dd804e3420f2c6ff34520c4ed63159b5ad4e99712fe64e3b4add73c66218e9797ac15a826420225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114580000000000000000",
|
||||
"0420d8283386ef2ef07ebdbb4383c12a739a953a4d6e0d6fb1139a4036d693bfbb6c20ffe9fc03f18b176c998806439ff0bb8ad193afdb27b2ccbc88856916dd804e3420f2c6ff34520c4ed63159b5ad4e99712fe64e3b4add73c66218e9797ac15a826420b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f550100000000000000",
|
||||
"0420d8283386ef2ef07ebdbb4383c12a739a953a4d6e0d6fb1139a4036d693bfbb6c20ffe9fc03f18b176c998806439ff0bb8ad193afdb27b2ccbc88856916dd804e342062324ff2c329e99193a74d28a585a3c167a93bf41a255135529c913bd9b1e6662050421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0300200000000000000",
|
||||
"0420d8283386ef2ef07ebdbb4383c12a739a953a4d6e0d6fb1139a4036d693bfbb6c2031d39685384e4ea322594d99a15aa8bdd8cc5cd6724410fa385b8d5447f1740220f2c6ff34520c4ed63159b5ad4e99712fe64e3b4add73c66218e9797ac15a826420225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114580000000000000000",
|
||||
"0420d8283386ef2ef07ebdbb4383c12a739a953a4d6e0d6fb1139a4036d693bfbb6c2031d39685384e4ea322594d99a15aa8bdd8cc5cd6724410fa385b8d5447f1740220f2c6ff34520c4ed63159b5ad4e99712fe64e3b4add73c66218e9797ac15a826420b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f550100000000000000",
|
||||
"0420d8283386ef2ef07ebdbb4383c12a739a953a4d6e0d6fb1139a4036d693bfbb6c2031d39685384e4ea322594d99a15aa8bdd8cc5cd6724410fa385b8d5447f174022062324ff2c329e99193a74d28a585a3c167a93bf41a255135529c913bd9b1e6662050421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0300200000000000000",
|
||||
"0420d8283386ef2ef07ebdbb4383c12a739a953a4d6e0d6fb1139a4036d693bfbb6c2031d39685384e4ea322594d99a15aa8bdd8cc5cd6724410fa385b8d5447f174022062324ff2c329e99193a74d28a585a3c167a93bf41a255135529c913bd9b1e666207c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e036c0300000000000000",
|
||||
"0420d8283386ef2ef07ebdbb4383c12a739a953a4d6e0d6fb1139a4036d693bfbb6c20f0321eea8e13c2f3a567f894c9738759d9d01e64ec259caf2cecca61374c157320f2c6ff34520c4ed63159b5ad4e99712fe64e3b4add73c66218e9797ac15a826420225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114580000000000000000",
|
||||
"0420d8283386ef2ef07ebdbb4383c12a739a953a4d6e0d6fb1139a4036d693bfbb6c20f0321eea8e13c2f3a567f894c9738759d9d01e64ec259caf2cecca61374c157320f2c6ff34520c4ed63159b5ad4e99712fe64e3b4add73c66218e9797ac15a826420b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f550100000000000000",
|
||||
"0420d8283386ef2ef07ebdbb4383c12a739a953a4d6e0d6fb1139a4036d693bfbb6c20f0321eea8e13c2f3a567f894c9738759d9d01e64ec259caf2cecca61374c15732062324ff2c329e99193a74d28a585a3c167a93bf41a255135529c913bd9b1e6662050421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0300200000000000000",
|
||||
"0420d8283386ef2ef07ebdbb4383c12a739a953a4d6e0d6fb1139a4036d693bfbb6c20f0321eea8e13c2f3a567f894c9738759d9d01e64ec259caf2cecca61374c15732062324ff2c329e99193a74d28a585a3c167a93bf41a255135529c913bd9b1e666207c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e036c0300000000000000",
|
||||
"0420d8283386ef2ef07ebdbb4383c12a739a953a4d6e0d6fb1139a4036d693bfbb6c201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f65518656420817de36ab2d57feb077634bca77819c8e0bd298c04f6fed0e6a83cc1356ca15520f76748d40d5ee5f9a608512e7954dd515f86e8f6d009141c89163de1cf351a020400000000000000",
|
||||
"0420d8283386ef2ef07ebdbb4383c12a739a953a4d6e0d6fb1139a4036d693bfbb6c2082c424de0185a63f6ce0aa65d3d55890748af44bb4bb5822a9a21df34546d32220f2c6ff34520c4ed63159b5ad4e99712fe64e3b4add73c66218e9797ac15a826420225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114580000000000000000",
|
||||
"0420d8283386ef2ef07ebdbb4383c12a739a953a4d6e0d6fb1139a4036d693bfbb6c2082c424de0185a63f6ce0aa65d3d55890748af44bb4bb5822a9a21df34546d32220f2c6ff34520c4ed63159b5ad4e99712fe64e3b4add73c66218e9797ac15a826420b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f550100000000000000",
|
||||
"0420d8283386ef2ef07ebdbb4383c12a739a953a4d6e0d6fb1139a4036d693bfbb6c2082c424de0185a63f6ce0aa65d3d55890748af44bb4bb5822a9a21df34546d3222062324ff2c329e99193a74d28a585a3c167a93bf41a255135529c913bd9b1e6662050421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0300200000000000000",
|
||||
"0420d8283386ef2ef07ebdbb4383c12a739a953a4d6e0d6fb1139a4036d693bfbb6c2082c424de0185a63f6ce0aa65d3d55890748af44bb4bb5822a9a21df34546d3222062324ff2c329e99193a74d28a585a3c167a93bf41a255135529c913bd9b1e666207c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e036c0300000000000000",
|
||||
"0420d8283386ef2ef07ebdbb4383c12a739a953a4d6e0d6fb1139a4036d693bfbb6c201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f655186564206ab2e08286c36f6fe4374baebdc28b97e2f1f4ea3544fafd8a6489f42824bf0e20f76748d40d5ee5f9a608512e7954dd515f86e8f6d009141c89163de1cf351a020400000000000000",
|
||||
"0420d8283386ef2ef07ebdbb4383c12a739a953a4d6e0d6fb1139a4036d693bfbb6c201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f655186564206ab2e08286c36f6fe4374baebdc28b97e2f1f4ea3544fafd8a6489f42824bf0e20aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc120500000000000000",
|
||||
"0420d8283386ef2ef07ebdbb4383c12a739a953a4d6e0d6fb1139a4036d693bfbb6c20130adab3afe0931c42f058efb1381c2dce6cc768ad7964330146bf88b2b34f2420f2c6ff34520c4ed63159b5ad4e99712fe64e3b4add73c66218e9797ac15a826420225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114580000000000000000",
|
||||
"0420d8283386ef2ef07ebdbb4383c12a739a953a4d6e0d6fb1139a4036d693bfbb6c20130adab3afe0931c42f058efb1381c2dce6cc768ad7964330146bf88b2b34f2420f2c6ff34520c4ed63159b5ad4e99712fe64e3b4add73c66218e9797ac15a826420b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f550100000000000000",
|
||||
"0420d8283386ef2ef07ebdbb4383c12a739a953a4d6e0d6fb1139a4036d693bfbb6c20130adab3afe0931c42f058efb1381c2dce6cc768ad7964330146bf88b2b34f242062324ff2c329e99193a74d28a585a3c167a93bf41a255135529c913bd9b1e6662050421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0300200000000000000",
|
||||
"0420d8283386ef2ef07ebdbb4383c12a739a953a4d6e0d6fb1139a4036d693bfbb6c20130adab3afe0931c42f058efb1381c2dce6cc768ad7964330146bf88b2b34f242062324ff2c329e99193a74d28a585a3c167a93bf41a255135529c913bd9b1e666207c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e036c0300000000000000",
|
||||
"0420d8283386ef2ef07ebdbb4383c12a739a953a4d6e0d6fb1139a4036d693bfbb6c201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f65518656420d0c26e22b78df58552b4fd61e8883a70f9011556b2e14b80ff23c591db7dbc4c20f76748d40d5ee5f9a608512e7954dd515f86e8f6d009141c89163de1cf351a020400000000000000",
|
||||
"0420d8283386ef2ef07ebdbb4383c12a739a953a4d6e0d6fb1139a4036d693bfbb6c201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f65518656420d0c26e22b78df58552b4fd61e8883a70f9011556b2e14b80ff23c591db7dbc4c20aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc120500000000000000",
|
||||
"0420d8283386ef2ef07ebdbb4383c12a739a953a4d6e0d6fb1139a4036d693bfbb6c201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f65518656420eb97b35d826f55a65e23ea7febf38fadea8517312ca79346c129a277260fd72420da1adda2ccde9381e11151686c121e7f52d19a990439161c7eb5a9f94be5a5110600000000000000",
|
||||
"0420109713c6c346ab0b17904ae18d101d92a98a612116a3f787043c802b55d5573120130adab3afe0931c42f058efb1381c2dce6cc768ad7964330146bf88b2b34f2420f2c6ff34520c4ed63159b5ad4e99712fe64e3b4add73c66218e9797ac15a826420225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114580000000000000000",
|
||||
"0420109713c6c346ab0b17904ae18d101d92a98a612116a3f787043c802b55d5573120130adab3afe0931c42f058efb1381c2dce6cc768ad7964330146bf88b2b34f2420f2c6ff34520c4ed63159b5ad4e99712fe64e3b4add73c66218e9797ac15a826420b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f550100000000000000",
|
||||
"0420109713c6c346ab0b17904ae18d101d92a98a612116a3f787043c802b55d5573120130adab3afe0931c42f058efb1381c2dce6cc768ad7964330146bf88b2b34f242062324ff2c329e99193a74d28a585a3c167a93bf41a255135529c913bd9b1e6662050421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0300200000000000000",
|
||||
"0420109713c6c346ab0b17904ae18d101d92a98a612116a3f787043c802b55d5573120130adab3afe0931c42f058efb1381c2dce6cc768ad7964330146bf88b2b34f242062324ff2c329e99193a74d28a585a3c167a93bf41a255135529c913bd9b1e666207c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e036c0300000000000000",
|
||||
"0420109713c6c346ab0b17904ae18d101d92a98a612116a3f787043c802b55d55731201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f65518656420d0c26e22b78df58552b4fd61e8883a70f9011556b2e14b80ff23c591db7dbc4c20f76748d40d5ee5f9a608512e7954dd515f86e8f6d009141c89163de1cf351a020400000000000000",
|
||||
"0420109713c6c346ab0b17904ae18d101d92a98a612116a3f787043c802b55d55731201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f65518656420d0c26e22b78df58552b4fd61e8883a70f9011556b2e14b80ff23c591db7dbc4c20aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc120500000000000000",
|
||||
"0420109713c6c346ab0b17904ae18d101d92a98a612116a3f787043c802b55d55731201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f65518656420eb97b35d826f55a65e23ea7febf38fadea8517312ca79346c129a277260fd72420da1adda2ccde9381e11151686c121e7f52d19a990439161c7eb5a9f94be5a5110600000000000000",
|
||||
"0420109713c6c346ab0b17904ae18d101d92a98a612116a3f787043c802b55d55731201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f65518656420eb97b35d826f55a65e23ea7febf38fadea8517312ca79346c129a277260fd72420bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0b2e0700000000000000",
|
||||
"0420bced38e720c8eab9b3b8b2959e5a8b8dda2b2537f6ea71c8e2aea8834a9af54220130adab3afe0931c42f058efb1381c2dce6cc768ad7964330146bf88b2b34f2420f2c6ff34520c4ed63159b5ad4e99712fe64e3b4add73c66218e9797ac15a826420225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114580000000000000000",
|
||||
"0420bced38e720c8eab9b3b8b2959e5a8b8dda2b2537f6ea71c8e2aea8834a9af54220130adab3afe0931c42f058efb1381c2dce6cc768ad7964330146bf88b2b34f2420f2c6ff34520c4ed63159b5ad4e99712fe64e3b4add73c66218e9797ac15a826420b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f550100000000000000",
|
||||
"0420bced38e720c8eab9b3b8b2959e5a8b8dda2b2537f6ea71c8e2aea8834a9af54220130adab3afe0931c42f058efb1381c2dce6cc768ad7964330146bf88b2b34f242062324ff2c329e99193a74d28a585a3c167a93bf41a255135529c913bd9b1e6662050421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0300200000000000000",
|
||||
"0420bced38e720c8eab9b3b8b2959e5a8b8dda2b2537f6ea71c8e2aea8834a9af54220130adab3afe0931c42f058efb1381c2dce6cc768ad7964330146bf88b2b34f242062324ff2c329e99193a74d28a585a3c167a93bf41a255135529c913bd9b1e666207c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e036c0300000000000000",
|
||||
"0420bced38e720c8eab9b3b8b2959e5a8b8dda2b2537f6ea71c8e2aea8834a9af542201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f65518656420d0c26e22b78df58552b4fd61e8883a70f9011556b2e14b80ff23c591db7dbc4c20f76748d40d5ee5f9a608512e7954dd515f86e8f6d009141c89163de1cf351a020400000000000000",
|
||||
"0420bced38e720c8eab9b3b8b2959e5a8b8dda2b2537f6ea71c8e2aea8834a9af542201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f65518656420d0c26e22b78df58552b4fd61e8883a70f9011556b2e14b80ff23c591db7dbc4c20aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc120500000000000000",
|
||||
"0420bced38e720c8eab9b3b8b2959e5a8b8dda2b2537f6ea71c8e2aea8834a9af542201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f65518656420eb97b35d826f55a65e23ea7febf38fadea8517312ca79346c129a277260fd72420da1adda2ccde9381e11151686c121e7f52d19a990439161c7eb5a9f94be5a5110600000000000000",
|
||||
"0420bced38e720c8eab9b3b8b2959e5a8b8dda2b2537f6ea71c8e2aea8834a9af542201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f65518656420eb97b35d826f55a65e23ea7febf38fadea8517312ca79346c129a277260fd72420bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0b2e0700000000000000",
|
||||
"04200d6b42350c11df4fcc17987c13d8492ba4e8b3f31eb9baff9be5d8890cfa512d20ffe9fc03f18b176c998806439ff0bb8ad193afdb27b2ccbc88856916dd804e3420817de36ab2d57feb077634bca77819c8e0bd298c04f6fed0e6a83cc1356ca15520c7ca8f7df8fd997931d33985d935ee2d696856cc09cc516d419ea6365f1630080800000000000000",
|
||||
"042094d3061a43d999e95bab82684aeb53d0a381b40e33a80abfc5c05e25b0a91d0f20130adab3afe0931c42f058efb1381c2dce6cc768ad7964330146bf88b2b34f2420f2c6ff34520c4ed63159b5ad4e99712fe64e3b4add73c66218e9797ac15a826420225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114580000000000000000",
|
||||
"042094d3061a43d999e95bab82684aeb53d0a381b40e33a80abfc5c05e25b0a91d0f20130adab3afe0931c42f058efb1381c2dce6cc768ad7964330146bf88b2b34f2420f2c6ff34520c4ed63159b5ad4e99712fe64e3b4add73c66218e9797ac15a826420b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f550100000000000000",
|
||||
"042094d3061a43d999e95bab82684aeb53d0a381b40e33a80abfc5c05e25b0a91d0f20130adab3afe0931c42f058efb1381c2dce6cc768ad7964330146bf88b2b34f242062324ff2c329e99193a74d28a585a3c167a93bf41a255135529c913bd9b1e6662050421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0300200000000000000",
|
||||
"042094d3061a43d999e95bab82684aeb53d0a381b40e33a80abfc5c05e25b0a91d0f20130adab3afe0931c42f058efb1381c2dce6cc768ad7964330146bf88b2b34f242062324ff2c329e99193a74d28a585a3c167a93bf41a255135529c913bd9b1e666207c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e036c0300000000000000",
|
||||
"042094d3061a43d999e95bab82684aeb53d0a381b40e33a80abfc5c05e25b0a91d0f201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f65518656420d0c26e22b78df58552b4fd61e8883a70f9011556b2e14b80ff23c591db7dbc4c20f76748d40d5ee5f9a608512e7954dd515f86e8f6d009141c89163de1cf351a020400000000000000",
|
||||
"042094d3061a43d999e95bab82684aeb53d0a381b40e33a80abfc5c05e25b0a91d0f201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f65518656420d0c26e22b78df58552b4fd61e8883a70f9011556b2e14b80ff23c591db7dbc4c20aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc120500000000000000",
|
||||
"042094d3061a43d999e95bab82684aeb53d0a381b40e33a80abfc5c05e25b0a91d0f201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f65518656420eb97b35d826f55a65e23ea7febf38fadea8517312ca79346c129a277260fd72420da1adda2ccde9381e11151686c121e7f52d19a990439161c7eb5a9f94be5a5110600000000000000",
|
||||
"042094d3061a43d999e95bab82684aeb53d0a381b40e33a80abfc5c05e25b0a91d0f201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f65518656420eb97b35d826f55a65e23ea7febf38fadea8517312ca79346c129a277260fd72420bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0b2e0700000000000000",
|
||||
"04200d6b42350c11df4fcc17987c13d8492ba4e8b3f31eb9baff9be5d8890cfa512d20ffe9fc03f18b176c998806439ff0bb8ad193afdb27b2ccbc88856916dd804e342076bd791f7708c0b6f5a348d574032e07ce3b1929daae19530346f5de955d543c20c7ca8f7df8fd997931d33985d935ee2d696856cc09cc516d419ea6365f1630080800000000000000",
|
||||
"04200d6b42350c11df4fcc17987c13d8492ba4e8b3f31eb9baff9be5d8890cfa512d20ffe9fc03f18b176c998806439ff0bb8ad193afdb27b2ccbc88856916dd804e342076bd791f7708c0b6f5a348d574032e07ce3b1929daae19530346f5de955d543c203a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774460900000000000000",
|
||||
"042061ae87cb694e8237accda801c8271a8a9d4ffc2581aebf923f5227f24c6bb92a20130adab3afe0931c42f058efb1381c2dce6cc768ad7964330146bf88b2b34f2420f2c6ff34520c4ed63159b5ad4e99712fe64e3b4add73c66218e9797ac15a826420225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114580000000000000000",
|
||||
"042061ae87cb694e8237accda801c8271a8a9d4ffc2581aebf923f5227f24c6bb92a20130adab3afe0931c42f058efb1381c2dce6cc768ad7964330146bf88b2b34f2420f2c6ff34520c4ed63159b5ad4e99712fe64e3b4add73c66218e9797ac15a826420b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f550100000000000000",
|
||||
"042061ae87cb694e8237accda801c8271a8a9d4ffc2581aebf923f5227f24c6bb92a20130adab3afe0931c42f058efb1381c2dce6cc768ad7964330146bf88b2b34f242062324ff2c329e99193a74d28a585a3c167a93bf41a255135529c913bd9b1e6662050421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0300200000000000000",
|
||||
"042061ae87cb694e8237accda801c8271a8a9d4ffc2581aebf923f5227f24c6bb92a20130adab3afe0931c42f058efb1381c2dce6cc768ad7964330146bf88b2b34f242062324ff2c329e99193a74d28a585a3c167a93bf41a255135529c913bd9b1e666207c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e036c0300000000000000",
|
||||
"042061ae87cb694e8237accda801c8271a8a9d4ffc2581aebf923f5227f24c6bb92a201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f65518656420d0c26e22b78df58552b4fd61e8883a70f9011556b2e14b80ff23c591db7dbc4c20f76748d40d5ee5f9a608512e7954dd515f86e8f6d009141c89163de1cf351a020400000000000000",
|
||||
"042061ae87cb694e8237accda801c8271a8a9d4ffc2581aebf923f5227f24c6bb92a201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f65518656420d0c26e22b78df58552b4fd61e8883a70f9011556b2e14b80ff23c591db7dbc4c20aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc120500000000000000",
|
||||
"042061ae87cb694e8237accda801c8271a8a9d4ffc2581aebf923f5227f24c6bb92a201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f65518656420eb97b35d826f55a65e23ea7febf38fadea8517312ca79346c129a277260fd72420da1adda2ccde9381e11151686c121e7f52d19a990439161c7eb5a9f94be5a5110600000000000000",
|
||||
"042061ae87cb694e8237accda801c8271a8a9d4ffc2581aebf923f5227f24c6bb92a201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f65518656420eb97b35d826f55a65e23ea7febf38fadea8517312ca79346c129a277260fd72420bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0b2e0700000000000000",
|
||||
"04200d6b42350c11df4fcc17987c13d8492ba4e8b3f31eb9baff9be5d8890cfa512d20ffe9fc03f18b176c998806439ff0bb8ad193afdb27b2ccbc88856916dd804e3420635c0b1b8035705127dc3f672191b4958ad331f9134117e3ba7d721f712b614420c7ca8f7df8fd997931d33985d935ee2d696856cc09cc516d419ea6365f1630080800000000000000",
|
||||
"04200d6b42350c11df4fcc17987c13d8492ba4e8b3f31eb9baff9be5d8890cfa512d20ffe9fc03f18b176c998806439ff0bb8ad193afdb27b2ccbc88856916dd804e3420635c0b1b8035705127dc3f672191b4958ad331f9134117e3ba7d721f712b6144203a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774460900000000000000",
|
||||
"04200d6b42350c11df4fcc17987c13d8492ba4e8b3f31eb9baff9be5d8890cfa512d20ffe9fc03f18b176c998806439ff0bb8ad193afdb27b2ccbc88856916dd804e3420cca46d2249e0d79669b8ad2e8c3fc5e67a8501112aa4e572fe03a1868ef3173220e6d4d7685894d01b32f7e081ab188930be6c2b9f76d6847b7f382e3dddd7c6080a00000000000000",
|
||||
"04208850438b439403c52a62aa6c81280ce5ea92bc5ff899ada6933c6afddc882e1820130adab3afe0931c42f058efb1381c2dce6cc768ad7964330146bf88b2b34f2420f2c6ff34520c4ed63159b5ad4e99712fe64e3b4add73c66218e9797ac15a826420225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114580000000000000000",
|
||||
"04208850438b439403c52a62aa6c81280ce5ea92bc5ff899ada6933c6afddc882e1820130adab3afe0931c42f058efb1381c2dce6cc768ad7964330146bf88b2b34f2420f2c6ff34520c4ed63159b5ad4e99712fe64e3b4add73c66218e9797ac15a826420b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f550100000000000000",
|
||||
"04208850438b439403c52a62aa6c81280ce5ea92bc5ff899ada6933c6afddc882e1820130adab3afe0931c42f058efb1381c2dce6cc768ad7964330146bf88b2b34f242062324ff2c329e99193a74d28a585a3c167a93bf41a255135529c913bd9b1e6662050421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0300200000000000000",
|
||||
"04208850438b439403c52a62aa6c81280ce5ea92bc5ff899ada6933c6afddc882e1820130adab3afe0931c42f058efb1381c2dce6cc768ad7964330146bf88b2b34f242062324ff2c329e99193a74d28a585a3c167a93bf41a255135529c913bd9b1e666207c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e036c0300000000000000",
|
||||
"04208850438b439403c52a62aa6c81280ce5ea92bc5ff899ada6933c6afddc882e18201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f65518656420d0c26e22b78df58552b4fd61e8883a70f9011556b2e14b80ff23c591db7dbc4c20f76748d40d5ee5f9a608512e7954dd515f86e8f6d009141c89163de1cf351a020400000000000000",
|
||||
"04208850438b439403c52a62aa6c81280ce5ea92bc5ff899ada6933c6afddc882e18201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f65518656420d0c26e22b78df58552b4fd61e8883a70f9011556b2e14b80ff23c591db7dbc4c20aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc120500000000000000",
|
||||
"04208850438b439403c52a62aa6c81280ce5ea92bc5ff899ada6933c6afddc882e18201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f65518656420eb97b35d826f55a65e23ea7febf38fadea8517312ca79346c129a277260fd72420da1adda2ccde9381e11151686c121e7f52d19a990439161c7eb5a9f94be5a5110600000000000000",
|
||||
"04208850438b439403c52a62aa6c81280ce5ea92bc5ff899ada6933c6afddc882e18201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f65518656420eb97b35d826f55a65e23ea7febf38fadea8517312ca79346c129a277260fd72420bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0b2e0700000000000000",
|
||||
"04200d6b42350c11df4fcc17987c13d8492ba4e8b3f31eb9baff9be5d8890cfa512d20130266c8ace013b416e56be57600a9da16e136df92231a964613e2885cce756620635c0b1b8035705127dc3f672191b4958ad331f9134117e3ba7d721f712b614420c7ca8f7df8fd997931d33985d935ee2d696856cc09cc516d419ea6365f1630080800000000000000",
|
||||
"04200d6b42350c11df4fcc17987c13d8492ba4e8b3f31eb9baff9be5d8890cfa512d20130266c8ace013b416e56be57600a9da16e136df92231a964613e2885cce756620635c0b1b8035705127dc3f672191b4958ad331f9134117e3ba7d721f712b6144203a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774460900000000000000",
|
||||
"04200d6b42350c11df4fcc17987c13d8492ba4e8b3f31eb9baff9be5d8890cfa512d20130266c8ace013b416e56be57600a9da16e136df92231a964613e2885cce756620cca46d2249e0d79669b8ad2e8c3fc5e67a8501112aa4e572fe03a1868ef3173220e6d4d7685894d01b32f7e081ab188930be6c2b9f76d6847b7f382e3dddd7c6080a00000000000000",
|
||||
"04200d6b42350c11df4fcc17987c13d8492ba4e8b3f31eb9baff9be5d8890cfa512d20130266c8ace013b416e56be57600a9da16e136df92231a964613e2885cce756620cca46d2249e0d79669b8ad2e8c3fc5e67a8501112aa4e572fe03a1868ef3173220f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c37020b00000000000000",
|
||||
"0420c9cd5269cd697706cb0745d57f66e5ba4a5051fb910127318d283f751910ac7120130adab3afe0931c42f058efb1381c2dce6cc768ad7964330146bf88b2b34f2420f2c6ff34520c4ed63159b5ad4e99712fe64e3b4add73c66218e9797ac15a826420225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114580000000000000000",
|
||||
"0420c9cd5269cd697706cb0745d57f66e5ba4a5051fb910127318d283f751910ac7120130adab3afe0931c42f058efb1381c2dce6cc768ad7964330146bf88b2b34f2420f2c6ff34520c4ed63159b5ad4e99712fe64e3b4add73c66218e9797ac15a826420b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f550100000000000000",
|
||||
"0420c9cd5269cd697706cb0745d57f66e5ba4a5051fb910127318d283f751910ac7120130adab3afe0931c42f058efb1381c2dce6cc768ad7964330146bf88b2b34f242062324ff2c329e99193a74d28a585a3c167a93bf41a255135529c913bd9b1e6662050421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0300200000000000000",
|
||||
"0420c9cd5269cd697706cb0745d57f66e5ba4a5051fb910127318d283f751910ac7120130adab3afe0931c42f058efb1381c2dce6cc768ad7964330146bf88b2b34f242062324ff2c329e99193a74d28a585a3c167a93bf41a255135529c913bd9b1e666207c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e036c0300000000000000",
|
||||
"0420c9cd5269cd697706cb0745d57f66e5ba4a5051fb910127318d283f751910ac71201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f65518656420d0c26e22b78df58552b4fd61e8883a70f9011556b2e14b80ff23c591db7dbc4c20f76748d40d5ee5f9a608512e7954dd515f86e8f6d009141c89163de1cf351a020400000000000000",
|
||||
"0420c9cd5269cd697706cb0745d57f66e5ba4a5051fb910127318d283f751910ac71201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f65518656420d0c26e22b78df58552b4fd61e8883a70f9011556b2e14b80ff23c591db7dbc4c20aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc120500000000000000",
|
||||
"0420c9cd5269cd697706cb0745d57f66e5ba4a5051fb910127318d283f751910ac71201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f65518656420eb97b35d826f55a65e23ea7febf38fadea8517312ca79346c129a277260fd72420da1adda2ccde9381e11151686c121e7f52d19a990439161c7eb5a9f94be5a5110600000000000000",
|
||||
"0420c9cd5269cd697706cb0745d57f66e5ba4a5051fb910127318d283f751910ac71201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f65518656420eb97b35d826f55a65e23ea7febf38fadea8517312ca79346c129a277260fd72420bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0b2e0700000000000000",
|
||||
"04200d6b42350c11df4fcc17987c13d8492ba4e8b3f31eb9baff9be5d8890cfa512d20c2b786e4ab72ae4f01c7241bc056817b19d42bc85107f42c3fd3a9b9e98f156420635c0b1b8035705127dc3f672191b4958ad331f9134117e3ba7d721f712b614420c7ca8f7df8fd997931d33985d935ee2d696856cc09cc516d419ea6365f1630080800000000000000",
|
||||
"04200d6b42350c11df4fcc17987c13d8492ba4e8b3f31eb9baff9be5d8890cfa512d20c2b786e4ab72ae4f01c7241bc056817b19d42bc85107f42c3fd3a9b9e98f156420635c0b1b8035705127dc3f672191b4958ad331f9134117e3ba7d721f712b6144203a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774460900000000000000",
|
||||
"04200d6b42350c11df4fcc17987c13d8492ba4e8b3f31eb9baff9be5d8890cfa512d20c2b786e4ab72ae4f01c7241bc056817b19d42bc85107f42c3fd3a9b9e98f156420cca46d2249e0d79669b8ad2e8c3fc5e67a8501112aa4e572fe03a1868ef3173220e6d4d7685894d01b32f7e081ab188930be6c2b9f76d6847b7f382e3dddd7c6080a00000000000000",
|
||||
"04200d6b42350c11df4fcc17987c13d8492ba4e8b3f31eb9baff9be5d8890cfa512d20c2b786e4ab72ae4f01c7241bc056817b19d42bc85107f42c3fd3a9b9e98f156420cca46d2249e0d79669b8ad2e8c3fc5e67a8501112aa4e572fe03a1868ef3173220f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c37020b00000000000000",
|
||||
"04200d6b42350c11df4fcc17987c13d8492ba4e8b3f31eb9baff9be5d8890cfa512d20002df68503da9247dfde6585cb8c9fa94897cf21735f8fc1b32116ef474de05c20817de36ab2d57feb077634bca77819c8e0bd298c04f6fed0e6a83cc1356ca1552022fab8bcdb88154dbf5877ad1e2d7f1b541bc8a5ec1b52266095381339c27c030c00000000000000",
|
||||
"04203cf9ea50bea2cebf829213d91c098813d11dbe5c6696cdaefab3249dbf892f5e20130adab3afe0931c42f058efb1381c2dce6cc768ad7964330146bf88b2b34f2420f2c6ff34520c4ed63159b5ad4e99712fe64e3b4add73c66218e9797ac15a826420225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114580000000000000000",
|
||||
"04203cf9ea50bea2cebf829213d91c098813d11dbe5c6696cdaefab3249dbf892f5e20130adab3afe0931c42f058efb1381c2dce6cc768ad7964330146bf88b2b34f2420f2c6ff34520c4ed63159b5ad4e99712fe64e3b4add73c66218e9797ac15a826420b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f550100000000000000",
|
||||
"04203cf9ea50bea2cebf829213d91c098813d11dbe5c6696cdaefab3249dbf892f5e20130adab3afe0931c42f058efb1381c2dce6cc768ad7964330146bf88b2b34f242062324ff2c329e99193a74d28a585a3c167a93bf41a255135529c913bd9b1e6662050421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0300200000000000000",
|
||||
"04203cf9ea50bea2cebf829213d91c098813d11dbe5c6696cdaefab3249dbf892f5e20130adab3afe0931c42f058efb1381c2dce6cc768ad7964330146bf88b2b34f242062324ff2c329e99193a74d28a585a3c167a93bf41a255135529c913bd9b1e666207c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e036c0300000000000000",
|
||||
"04203cf9ea50bea2cebf829213d91c098813d11dbe5c6696cdaefab3249dbf892f5e201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f65518656420d0c26e22b78df58552b4fd61e8883a70f9011556b2e14b80ff23c591db7dbc4c20f76748d40d5ee5f9a608512e7954dd515f86e8f6d009141c89163de1cf351a020400000000000000",
|
||||
"04203cf9ea50bea2cebf829213d91c098813d11dbe5c6696cdaefab3249dbf892f5e201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f65518656420d0c26e22b78df58552b4fd61e8883a70f9011556b2e14b80ff23c591db7dbc4c20aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc120500000000000000",
|
||||
"04203cf9ea50bea2cebf829213d91c098813d11dbe5c6696cdaefab3249dbf892f5e201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f65518656420eb97b35d826f55a65e23ea7febf38fadea8517312ca79346c129a277260fd72420da1adda2ccde9381e11151686c121e7f52d19a990439161c7eb5a9f94be5a5110600000000000000",
|
||||
"04203cf9ea50bea2cebf829213d91c098813d11dbe5c6696cdaefab3249dbf892f5e201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f65518656420eb97b35d826f55a65e23ea7febf38fadea8517312ca79346c129a277260fd72420bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0b2e0700000000000000",
|
||||
"04200d6b42350c11df4fcc17987c13d8492ba4e8b3f31eb9baff9be5d8890cfa512d20cd6db4bcd77d6ca695b9579f9ec5791d106f83b69118bb3a2a2a99f63779e06720635c0b1b8035705127dc3f672191b4958ad331f9134117e3ba7d721f712b614420c7ca8f7df8fd997931d33985d935ee2d696856cc09cc516d419ea6365f1630080800000000000000",
|
||||
"04200d6b42350c11df4fcc17987c13d8492ba4e8b3f31eb9baff9be5d8890cfa512d20cd6db4bcd77d6ca695b9579f9ec5791d106f83b69118bb3a2a2a99f63779e06720635c0b1b8035705127dc3f672191b4958ad331f9134117e3ba7d721f712b6144203a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774460900000000000000",
|
||||
"04200d6b42350c11df4fcc17987c13d8492ba4e8b3f31eb9baff9be5d8890cfa512d20cd6db4bcd77d6ca695b9579f9ec5791d106f83b69118bb3a2a2a99f63779e06720cca46d2249e0d79669b8ad2e8c3fc5e67a8501112aa4e572fe03a1868ef3173220e6d4d7685894d01b32f7e081ab188930be6c2b9f76d6847b7f382e3dddd7c6080a00000000000000",
|
||||
"04200d6b42350c11df4fcc17987c13d8492ba4e8b3f31eb9baff9be5d8890cfa512d20cd6db4bcd77d6ca695b9579f9ec5791d106f83b69118bb3a2a2a99f63779e06720cca46d2249e0d79669b8ad2e8c3fc5e67a8501112aa4e572fe03a1868ef3173220f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c37020b00000000000000",
|
||||
"04200d6b42350c11df4fcc17987c13d8492ba4e8b3f31eb9baff9be5d8890cfa512d20002df68503da9247dfde6585cb8c9fa94897cf21735f8fc1b32116ef474de05c2045d573e80606a552974215e13b5d3e7b4dd8675c77b8d612d293475ee139b9472022fab8bcdb88154dbf5877ad1e2d7f1b541bc8a5ec1b52266095381339c27c030c00000000000000",
|
||||
"04200d6b42350c11df4fcc17987c13d8492ba4e8b3f31eb9baff9be5d8890cfa512d20002df68503da9247dfde6585cb8c9fa94897cf21735f8fc1b32116ef474de05c2045d573e80606a552974215e13b5d3e7b4dd8675c77b8d612d293475ee139b947208cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8260d00000000000000",
|
||||
"04201d73ff8e39cff60ff0d6402cc752a3351f1b434dccfa1941da3b1e422b73a33c20130adab3afe0931c42f058efb1381c2dce6cc768ad7964330146bf88b2b34f2420f2c6ff34520c4ed63159b5ad4e99712fe64e3b4add73c66218e9797ac15a826420225747f3b5d5dab4e5a424f81f85c904ff43286e0f3fd07ef0b8c6a627b114580000000000000000",
|
||||
"04201d73ff8e39cff60ff0d6402cc752a3351f1b434dccfa1941da3b1e422b73a33c20130adab3afe0931c42f058efb1381c2dce6cc768ad7964330146bf88b2b34f2420f2c6ff34520c4ed63159b5ad4e99712fe64e3b4add73c66218e9797ac15a826420b02310f2e087e55bfd07ef5e242e3b87ee5d00c9ab52f61e6bd42542f93a6f550100000000000000",
|
||||
"04201d73ff8e39cff60ff0d6402cc752a3351f1b434dccfa1941da3b1e422b73a33c20130adab3afe0931c42f058efb1381c2dce6cc768ad7964330146bf88b2b34f242062324ff2c329e99193a74d28a585a3c167a93bf41a255135529c913bd9b1e6662050421d6c2c94571dfaaa135a4ff15bf916681ebd62c0e43e69e3b90684d0a0300200000000000000",
|
||||
"04201d73ff8e39cff60ff0d6402cc752a3351f1b434dccfa1941da3b1e422b73a33c20130adab3afe0931c42f058efb1381c2dce6cc768ad7964330146bf88b2b34f242062324ff2c329e99193a74d28a585a3c167a93bf41a255135529c913bd9b1e666207c3ea01a6e3a3d90cf59cd789e467044b5cd78eb2c84cc6816f960746d0e036c0300000000000000",
|
||||
"04201d73ff8e39cff60ff0d6402cc752a3351f1b434dccfa1941da3b1e422b73a33c201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f65518656420d0c26e22b78df58552b4fd61e8883a70f9011556b2e14b80ff23c591db7dbc4c20f76748d40d5ee5f9a608512e7954dd515f86e8f6d009141c89163de1cf351a020400000000000000",
|
||||
"04201d73ff8e39cff60ff0d6402cc752a3351f1b434dccfa1941da3b1e422b73a33c201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f65518656420d0c26e22b78df58552b4fd61e8883a70f9011556b2e14b80ff23c591db7dbc4c20aaec63863aaa0b2e3b8009429bdddd455e59be6f40ccab887a32eb98723efc120500000000000000",
|
||||
"04201d73ff8e39cff60ff0d6402cc752a3351f1b434dccfa1941da3b1e422b73a33c201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f65518656420eb97b35d826f55a65e23ea7febf38fadea8517312ca79346c129a277260fd72420da1adda2ccde9381e11151686c121e7f52d19a990439161c7eb5a9f94be5a5110600000000000000",
|
||||
"04201d73ff8e39cff60ff0d6402cc752a3351f1b434dccfa1941da3b1e422b73a33c201fb189b02ad2f7c6b0d09bd5691c4896c28269da3d4ba768b1b446f65518656420eb97b35d826f55a65e23ea7febf38fadea8517312ca79346c129a277260fd72420bc8a5ec71647415c380203b681f7717366f3501661512225b6dc3e121efc0b2e0700000000000000",
|
||||
"04200d6b42350c11df4fcc17987c13d8492ba4e8b3f31eb9baff9be5d8890cfa512d20076795f3651049c8895a7d127eb9bb4a17698da400430b33fdd06b1d8160394020635c0b1b8035705127dc3f672191b4958ad331f9134117e3ba7d721f712b614420c7ca8f7df8fd997931d33985d935ee2d696856cc09cc516d419ea6365f1630080800000000000000",
|
||||
"04200d6b42350c11df4fcc17987c13d8492ba4e8b3f31eb9baff9be5d8890cfa512d20076795f3651049c8895a7d127eb9bb4a17698da400430b33fdd06b1d8160394020635c0b1b8035705127dc3f672191b4958ad331f9134117e3ba7d721f712b6144203a27fed5dbbc475d3880360e38638c882fd9b273b618fc433106896083f774460900000000000000",
|
||||
"04200d6b42350c11df4fcc17987c13d8492ba4e8b3f31eb9baff9be5d8890cfa512d20076795f3651049c8895a7d127eb9bb4a17698da400430b33fdd06b1d8160394020cca46d2249e0d79669b8ad2e8c3fc5e67a8501112aa4e572fe03a1868ef3173220e6d4d7685894d01b32f7e081ab188930be6c2b9f76d6847b7f382e3dddd7c6080a00000000000000",
|
||||
"04200d6b42350c11df4fcc17987c13d8492ba4e8b3f31eb9baff9be5d8890cfa512d20076795f3651049c8895a7d127eb9bb4a17698da400430b33fdd06b1d8160394020cca46d2249e0d79669b8ad2e8c3fc5e67a8501112aa4e572fe03a1868ef3173220f0fa37e8063b139d342246142fc48e7c0c50d0a62c97768589e06466742c37020b00000000000000",
|
||||
"04200d6b42350c11df4fcc17987c13d8492ba4e8b3f31eb9baff9be5d8890cfa512d20002df68503da9247dfde6585cb8c9fa94897cf21735f8fc1b32116ef474de05c20afa80a9a1bb8b6aad144cfb53e0bab004dd541c8b72025ae694bb60d6050a5322022fab8bcdb88154dbf5877ad1e2d7f1b541bc8a5ec1b52266095381339c27c030c00000000000000",
|
||||
"04200d6b42350c11df4fcc17987c13d8492ba4e8b3f31eb9baff9be5d8890cfa512d20002df68503da9247dfde6585cb8c9fa94897cf21735f8fc1b32116ef474de05c20afa80a9a1bb8b6aad144cfb53e0bab004dd541c8b72025ae694bb60d6050a532208cebb73be883466d18d3b0c06990520e80b936440a2c9fd184d92a1f06c4e8260d00000000000000",
|
||||
"04200d6b42350c11df4fcc17987c13d8492ba4e8b3f31eb9baff9be5d8890cfa512d20002df68503da9247dfde6585cb8c9fa94897cf21735f8fc1b32116ef474de05c205991131c5c25911b35fcea2a8343e2dfd7a4d5b45493390e0cb184394d91c349203a3661bc12b72646c94bc6c92796e81953985ee62d80a9ec3645a9a95740ac150e00000000000000",
|
||||
];
|
||||
|
||||
fn assert_root_eq(root: Node, expected: &str) {
|
||||
let mut tmp = [0u8; 32];
|
||||
root.repr
|
||||
|
@ -421,6 +748,8 @@ mod tests {
|
|||
let mut tree = TestCommitmentTree::new();
|
||||
assert_eq!(tree.size(), 0);
|
||||
|
||||
let mut witnesses = vec![];
|
||||
let mut paths_i = 0;
|
||||
for i in 0..16 {
|
||||
let mut cm = FrRepr::default();
|
||||
cm.read_le(&hex::decode(commitments[i]).unwrap()[..])
|
||||
|
@ -428,7 +757,10 @@ mod tests {
|
|||
|
||||
let cm = Node::new(cm);
|
||||
|
||||
// Append a commitment to the tree
|
||||
// Witness here
|
||||
witnesses.push(TestIncrementalWitness::from_tree(&tree));
|
||||
|
||||
// Now append a commitment to the tree
|
||||
assert!(tree.append(cm).is_ok());
|
||||
|
||||
// Size incremented by one.
|
||||
|
@ -436,10 +768,36 @@ mod tests {
|
|||
|
||||
// Check tree root consistency
|
||||
assert_root_eq(tree.root(), roots[i]);
|
||||
|
||||
let mut first = true; // The first witness can never form a path
|
||||
for witness in witnesses.as_mut_slice() {
|
||||
// Append the same commitment to all the witnesses
|
||||
assert!(witness.append(cm).is_ok());
|
||||
|
||||
if first {
|
||||
assert!(witness.path().is_none());
|
||||
} else {
|
||||
let path = witness.path().expect("should be able to create a path");
|
||||
let expected = CommitmentTreeWitness::from_slice_with_depth(
|
||||
&mut hex::decode(paths[paths_i]).unwrap(),
|
||||
TESTING_DEPTH,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(path, expected);
|
||||
paths_i += 1;
|
||||
}
|
||||
|
||||
assert_eq!(witness.root(), tree.root());
|
||||
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Tree should be full now
|
||||
let node = Node::blank();
|
||||
assert!(tree.append(node).is_err());
|
||||
for witness in witnesses.as_mut_slice() {
|
||||
assert!(witness.append(node).is_err());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue