public void AuditTest() { // Build a tree, and given the root node and a leaf hash, verify that the we can reconstruct the root hash. MerkleTree tree = new MerkleTree(); MerkleHash l1 = new MerkleHash("abc"); MerkleHash l2 = new MerkleHash("def"); MerkleHash l3 = new MerkleHash("123"); MerkleHash l4 = new MerkleHash("456"); tree.Append(new MerkleHash[] { l1, l2, l3, l4 }); MerkleHash rootHash = tree.BuildTree(); List <MerkleProofHash> auditTrail = tree.AuditProof(l1); MerkleTree.VerifyAudit(rootHash, l1, auditTrail).Should().BeTrue(); auditTrail = tree.AuditProof(l2); MerkleTree.VerifyAudit(rootHash, l2, auditTrail).Should().BeTrue(); auditTrail = tree.AuditProof(l3); MerkleTree.VerifyAudit(rootHash, l3, auditTrail).Should().BeTrue(); auditTrail = tree.AuditProof(l4); MerkleTree.VerifyAudit(rootHash, l4, auditTrail).Should().BeTrue(); }
protected void DrawAuditProof(string text, MerkleTree tree) { // We use First because a tree with an odd number of leaves will duplicate the last leaf // when computing the hash. var node = tree.RootNode.Cast <DemoMerkleNode>().First(t => t.Text == text); Highlight(node, "Orange"); List <MerkleProofHash> proof = tree.AuditProof(node.Hash); bool ret = MerkleTree.VerifyAudit(tree.RootNode.Hash, node.Hash, proof); lblAuditPassFail.Text = ret ? "Pass" : "Fail"; lblAuditPassFail.ForeColor = ret ? Color.Green : Color.Red; tbAuditTrail.Clear(); foreach (var auditHash in proof) { // We use First because a tree with an odd number of leaves will duplicate the last leaf // when computing the hash. var n = tree.RootNode.Cast <DemoMerkleNode>().First(t => t.Hash == auditHash.Hash); // tbAuditTrail.AppendText(n.Text + CRLF); Highlight(n); } var auditPairs = MerkleTree.AuditHashPairs(node.Hash, proof); foreach (var pair in auditPairs) { DemoMerkleNode left = tree.RootNode.Cast <DemoMerkleNode>().First(t => t.Hash == pair.Item1); DemoMerkleNode right = tree.RootNode.Cast <DemoMerkleNode>().First(t => t.Hash == pair.Item2); tbAuditTrail.AppendText(left.Text + " + " + right.Text + " = " + left.Text + right.Text + CRLF); } }