예제 #1
0
        /// <summary>
        ///     For demo / debugging purposes, we return the pairs of hashes used to verify the audit proof.
        /// </summary>
        public static List <Tuple <MerkleHash, MerkleHash> > AuditHashPairs(MerkleHash leafHash,
                                                                            List <MerkleProofHash> auditTrail)
        {
            Contract(() => auditTrail.Count > 0, "Audit trail cannot be empty.");
            var auditPairs = new List <Tuple <MerkleHash, MerkleHash> >();
            var testHash   = leafHash;

            // TODO: Inefficient - compute hashes directly.
            foreach (var auditHash in auditTrail)
            {
                switch (auditHash.Direction)
                {
                case MerkleProofHash.Branch.Left:
                    auditPairs.Add(new Tuple <MerkleHash, MerkleHash>(testHash, auditHash.Hash));
                    testHash = MerkleHash.Create(testHash.Value.Concat(auditHash.Hash.Value).ToArray());
                    break;

                case MerkleProofHash.Branch.Right:
                    auditPairs.Add(new Tuple <MerkleHash, MerkleHash>(auditHash.Hash, testHash));
                    testHash = MerkleHash.Create(auditHash.Hash.Value.Concat(testHash.Value).ToArray());
                    break;
                }
            }

            return(auditPairs);
        }
예제 #2
0
        /// <summary>
        ///     Verify that if we walk up the tree from a particular leaf, we encounter the expected root hash.
        /// </summary>
        public static bool VerifyAudit(MerkleHash rootHash, MerkleHash leafHash, List <MerkleProofHash> auditTrail)
        {
            Contract(() => auditTrail.Count > 0, "Audit trail cannot be empty.");
            var testHash = leafHash;

            // TODO: Inefficient - compute hashes directly.
            foreach (var auditHash in auditTrail)
            {
                testHash = auditHash.Direction == MerkleProofHash.Branch.Left
                    ? MerkleHash.Create(testHash.Value.Concat(auditHash.Hash.Value).ToArray())
                    : MerkleHash.Create(auditHash.Hash.Value.Concat(testHash.Value).ToArray());
            }

            return(rootHash == testHash);
        }
예제 #3
0
        protected void ComputeHash()
        {
            // Repeat the left node if the right node doesn't exist.
            // This process breaks the case of doing a consistency check on 3 leaves when there are only 3 leaves in the tree.
            //MerkleHash rightHash = RightNode == null ? LeftNode.Hash : RightNode.Hash;
            //Hash = MerkleHash.Create(LeftNode.Hash.Value.Concat(rightHash.Value).ToArray());

            // Alternativately, do not repeat the left node, but carry the left node's hash up.
            // This process does not break the edge case described above.
            // We're implementing this version because the consistency check unit tests pass when we don't simulate
            // a right-hand node.
            Hash = RightNode == null
                ? LeftNode.Hash
                :                  //MerkleHash.Create(LeftNode.Hash.Value.Concat(LeftNode.Hash.Value).ToArray()) :
                   MerkleHash.Create(LeftNode.Hash.Value.Concat(RightNode.Hash.Value).ToArray());
            Parent?.ComputeHash(); // Recurse, because out hash has changed.
        }
예제 #4
0
        /// <summary>
        ///     Verifies the hash for this node against the computed hash for our child nodes.
        ///     If we don't have any children, the return is always true because we have nothing to verify against.
        /// </summary>
        public bool VerifyHash()
        {
            if (LeftNode == null && RightNode == null)
            {
                return(true);
            }

            if (RightNode == null)
            {
                return(Hash.Equals(LeftNode.Hash));
            }

            MerkleTree.Contract(() => LeftNode != null, "Left branch must be a node if right branch is a node.");
            var leftRightHash = MerkleHash.Create(LeftNode.Hash, RightNode.Hash);

            return(Hash.Equals(leftRightHash));
        }
예제 #5
0
        public MerkleHash ComputeHash(byte[] buffer)
        {
            Hash = MerkleHash.Create(buffer);

            return(Hash);
        }
예제 #6
0
 public static MerkleHash ComputeHash(MerkleHash left, MerkleHash right)
 {
     return(MerkleHash.Create(left.Value.Concat(right.Value).ToArray()));
 }