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); } }
protected void DrawConsistencyProof(MerkleTree tree, DemoMerkleNode oldTreeRoot, int m, MerkleHash newRootHash) { tree.RootNode.Leaves().Cast <DemoMerkleNode>().Take(m).ForEach(n => Highlight(n, "Orange")); List <MerkleProofHash> proofToOldRoot = tree.ConsistencyProof(m); bool ret = MerkleTree.VerifyConsistency(oldTreeRoot.Hash, proofToOldRoot); lblConsistencyPassFail.Text = ret ? "Pass" : "Fail"; lblConsistencyPassFail.ForeColor = ret ? Color.Green : Color.Red; tbConsistencyTrail.Clear(); proofToOldRoot.ForEach(hash => { var node = tree.RootNode.Cast <DemoMerkleNode>().First(t => t.Hash == hash.Hash); Highlight(node); tbConsistencyTrail.AppendText(node.Text + CRLF); }); tbConsistencyTrail.AppendText(oldTreeRoot.Text + " = old root" + CRLF); if (!ckOnlyToOldRoot.Checked) { // The remainder: consistency audit proof. var lastNode = proofToOldRoot.Last(); List <MerkleProofHash> proofToNewRoot = tree.ConsistencyAuditProof(lastNode.Hash); foreach (var auditHash in proofToNewRoot) { // 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); if (!proofToOldRoot.Any(ph => ph.Hash == n.Hash)) { Highlight(n, "Purple"); } } var auditPairs = MerkleTree.AuditHashPairs(lastNode.Hash, proofToNewRoot); string lastHash = ""; foreach (var pair in auditPairs) { var left = tree.RootNode.Cast <DemoMerkleNode>().First(t => t.Hash == pair.Item1); var right = tree.RootNode.Cast <DemoMerkleNode>().First(t => t.Hash == pair.Item2); lastHash = left.Text + right.Text; tbConsistencyTrail.AppendText(left.Text + " + " + right.Text + " = " + lastHash + CRLF); } tbConsistencyTrail.AppendText(lastHash + " = new root" + CRLF); } }