def test_tree_get_root_hash_invalid_size(self): """Test handling of bad inputs to get root hash. Test that an assertion is raised for invalid tree size passed into get_root_hash. """ tree = leveldb_merkle_tree.LeveldbMerkleTree(leaves=TEST_VECTOR_DATA, db=self.db) self.assertRaises(ValueError, tree.get_root_hash, tree.tree_size + 3) tree.close()
def test_tree_consistency_proof_precomputed(self): """Test consistency proof generation. Test Consistency proof generation correctness test for known-good proofs. """ tree = leveldb_merkle_tree.LeveldbMerkleTree(leaves=TEST_VECTOR_DATA, db=self.db) for v in PRECOMPUTED_PROOF_TEST_VECTORS: consistency_proof = tree.get_consistency_proof( v.snapshot_1, v.snapshot_2) self.assertEqual(consistency_proof, v.proof) tree.close()
def test_tree_snapshot_root_hash(self): """Test root hash calculation. Test that root hash is calculated correctly when all leaves are added at once. """ tree = leveldb_merkle_tree.LeveldbMerkleTree(leaves=TEST_VECTOR_DATA, db=self.db) hasher = merkle.TreeHasher() for i in range(len(TEST_VECTOR_DATA)): self.assertEqual( tree.get_root_hash(i), hasher.hash_full_tree(TEST_VECTOR_DATA[0:i])) tree.close()
def test_tree_incremental_root_hash(self): """Test root hash calculation. Test that root hash is calculated correctly when leaves are added incrementally. """ tree = leveldb_merkle_tree.LeveldbMerkleTree(leaves=[], db=self.db) hasher = merkle.TreeHasher() for i in range(len(TEST_VECTOR_DATA)): tree.add_leaf(TEST_VECTOR_DATA[i]) self.assertEqual( tree.get_root_hash(), hasher.hash_full_tree(TEST_VECTOR_DATA[0:i+1])) tree.close()
def test_tree_consistency_proof_bad_indices(self): """Test handling of bad inputs into get consistency proof. Test that an assertion is raised for invalid tree sizes passed into get_consistency_proof. """ tree = leveldb_merkle_tree.LeveldbMerkleTree(leaves=TEST_VECTOR_DATA, db=self.db) n = tree.tree_size # 2nd tree size too large self.assertRaises(ValueError, tree.get_consistency_proof, 1, n + 3) # 1st tree size > 2nd tree size self.assertRaises(ValueError, tree.get_consistency_proof, n - 1, n - 3) tree.close()
def test_tree_inclusion_proof_bad_indices(self): """Test handling of bad inputs into get inclusion proof. Test that an assertion is raised for invalid tree sizes or invalid leaf indices are passed into get_inclusion_proof. """ tree = leveldb_merkle_tree.LeveldbMerkleTree(leaves=TEST_VECTOR_DATA, db=self.db) n = tree.tree_size # Tree size too large self.assertRaises(ValueError, tree.get_inclusion_proof, 0, n + 3) # Leaf index too large self.assertRaises(ValueError, tree.get_inclusion_proof, n + 3, n - 1) tree.close()
def test_tree_consistency_proof_generated(self): """Test consistency proof generation. Consistency proof generation correctness test for generated proofs. """ leaves = [] for i in range(128): leaves.append(chr(i) * 32) tree = leveldb_merkle_tree.LeveldbMerkleTree(leaves=leaves, db=self.db) verifier = merkle.MerkleVerifier() for i in range(1, tree.tree_size): for j in range(i): consistency_proof = tree.get_consistency_proof(j, i) self.assertTrue(verifier.verify_tree_consistency( j, i, tree.get_root_hash(j), tree.get_root_hash(i), consistency_proof)) tree.close()
def test_tree_inclusion_proof_generated(self): """Test inclusion proof generation. Test inclusion proof generation correctness for generated proofs. """ leaves = [] leaf_hashes = [] hasher = merkle.TreeHasher() for i in range(128): leaves.append(chr(i) * 32) leaf_hashes.append(hasher.hash_leaf(leaves[-1])) tree = leveldb_merkle_tree.LeveldbMerkleTree(leaves=leaves, db=self.db) verifier = merkle.MerkleVerifier() for i in range(1, tree.tree_size): for j in range(i): audit_path = tree.get_inclusion_proof(j, i) dummy_sth = DummySTH(i, tree.get_root_hash(i)) verifier.verify_leaf_hash_inclusion( leaf_hashes[j], j, audit_path, dummy_sth) tree.close()
def test_tree_inclusion_proof_precomputed(self): """Test inclusion proof generation. Test inclusion proof generation correctness test for known-good proofs. """ tree = leveldb_merkle_tree.LeveldbMerkleTree(leaves=TEST_VECTOR_DATA, db=self.db) verifier = merkle.MerkleVerifier() for v in PRECOMPUTED_PATH_TEST_VECTORS: audit_path = tree.get_inclusion_proof(v.leaf, v.tree_size_snapshot) self.assertEqual(len(audit_path), v.path_length) self.assertEqual(audit_path, v.path) leaf_data = TEST_VECTOR_DATA[v.leaf] leaf_hash = merkle.TreeHasher().hash_leaf(leaf_data) dummy_sth = DummySTH(v.tree_size_snapshot, tree.get_root_hash(v.tree_size_snapshot)) if v.tree_size_snapshot > 0: verifier.verify_leaf_hash_inclusion( leaf_hash, v.leaf, audit_path, dummy_sth) tree.close()
LEAF_SIZE = 2048 NUM_LEAVES = 65536 TEST_LEAF = random.randint(0, NUM_LEAVES) def encode_byte_list(l): return [h.encode('hex') for h in l] LEAVES = [os.urandom(LEAF_SIZE) for i in xrange(NUM_LEAVES)] IMT = in_memory_merkle_tree.InMemoryMerkleTree(leaves=LEAVES) print "Root hash in InMemoryMerkleTree: " + IMT.get_root_hash().encode('hex') shutil.rmtree("./merkle_db", ignore_errors=True) LMT = leveldb_merkle_tree.LeveldbMerkleTree(leaves=LEAVES) # LMT.extend(LEAVES) print "Root hash in LeveldbMerkleTree: " + LMT.get_root_hash().encode('hex') # check that root hashes are identical print "Are the two root hashes identical? %s: " % (IMT.get_root_hash() == LMT.get_root_hash()) # check that consistency proof is working and identical MV = merkle.MerkleVerifier() const_proof = LMT.get_consistency_proof(TEST_LEAF) print "Consistency proof for subtree at leaf %s:\n%s" % ( TEST_LEAF, encode_byte_list(const_proof)) print "Is consistency proof correct?: %s" % MV.verify_tree_consistency( TEST_LEAF, NUM_LEAVES, IMT.get_root_hash(TEST_LEAF), LMT.get_root_hash(),