def create_summary(self): """ This step computes a Merkle tree over the checksums for each format and writes a file containing the head of the tree and inclusion proofs for each file. """ for fmt in self.config["formats"]: hash_fn = self._get_hash_function(fmt) files = [fn for fn in sorted(self.checksums)] data = [self.checksums[fn]["hashes"][fmt] for fn in files] tree = MerkleTree(hash_fn, data) head = binascii.hexlify(tree.head()) proofs = [ binascii.hexlify(tree.inclusion_proof(i).to_rfc6962_bis()) for i in range(len(files)) ] summary = self._get_summary_filename(fmt) self.info("Creating summary file: {}".format(summary)) content = "{} TREE_HEAD\n".format(head.decode('ascii')) for i in range(len(files)): content += "{} {}\n".format(proofs[i].decode('ascii'), files[i]) self.write_to_file(summary, content)
def testPreComputed(self): tree = MerkleTree(hash_fn, data) head = tree.head() self.assertEqual(head, nodeF) for i in range(len(data)): proof = tree.inclusion_proof(i) self.assertTrue(proof.verify(hash_fn, data[i], i, len(data), head)) self.assertEqual(proof.leaf_index, i) self.assertEqual(proof.tree_size, tree.n) self.assertEqual(proof.path_elements, proofs[i])
def testPreComputed(self): tree = MerkleTree(hash_fn, data) head = tree.head() self.assertEquals(head, nodeF) for i in range(len(data)): proof = tree.inclusion_proof(i) self.assertTrue(proof.verify(hash_fn, data[i], i, len(data), head)) self.assertEquals(proof.leaf_index, i) self.assertEquals(proof.tree_size, tree.n) self.assertEquals(proof.path_elements, proofs[i])
def testLargeTree(self): TEST_SIZE = 5000 ELEM_SIZE_BYTES = 16 data = [bytearray(random.getrandbits(8) for _ in xrange(ELEM_SIZE_BYTES)) for _ in xrange(TEST_SIZE)] tree = MerkleTree(hash_fn, data) head = tree.head() for i in range(len(data)): proof = tree.inclusion_proof(i) self.assertTrue(proof.verify(hash_fn, data[i], i, len(data), head)) self.assertEquals(proof.leaf_index, i) self.assertEquals(proof.tree_size, tree.n)
def testInclusionProofEncodeDecode(self): tree = MerkleTree(hash_fn, data) # Inclusion proof encode/decode round trip test proof5 = tree.inclusion_proof(5) serialized5 = proof5.to_rfc6962_bis() deserialized5 = InclusionProof.from_rfc6962_bis(serialized5) reserialized5 = deserialized5.to_rfc6962_bis() self.assertEquals(serialized5, reserialized5) # Inclusion proof encode known answer test serialized5 = proof5.to_rfc6962_bis() self.assertEquals(serialized5, known_proof5) # Inclusion proof decode known answer test known_deserialized5 = InclusionProof.from_rfc6962_bis(known_proof5) self.assertEquals(proof5.leaf_index, known_deserialized5.leaf_index) self.assertEquals(proof5.tree_size, known_deserialized5.tree_size) self.assertEquals(proof5.path_elements, known_deserialized5.path_elements)
def create_summary(self): """ This step computes a Merkle tree over the checksums for each format and writes a file containing the head of the tree and inclusion proofs for each file. """ for fmt in self.config["formats"]: hash_fn = self._get_hash_function(fmt) files = [fn for fn in sorted(self.checksums)] data = [self.checksums[fn]["hashes"][fmt] for fn in files] tree = MerkleTree(hash_fn, data) head = tree.head().encode("hex") proofs = [tree.inclusion_proof(i).to_rfc6962_bis().encode("hex") for i in range(len(files))] summary = self._get_summary_filename(fmt) self.info("Creating summary file: {}".format(summary)) content = "{} TREE_HEAD\n".format(head) for i in range(len(files)): content += "{} {}\n".format(proofs[i], files[i]) self.write_to_file(summary, content)