/// <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> >(); MerkleHash testHash = leafHash; foreach (MerkleProofHash 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); }
public static MerkleHash Create(MerkleHash left, MerkleHash right) { return(Create(left.Value.Concat(right.Value).ToArray())); }
// Override in derived class to extend the behavior. // Alternatively, we could implement a factory pattern. protected virtual MerkleNode CreateNode(MerkleHash hash) { return(new MerkleNode(hash)); }
/// <summary> /// Constructor for a base node (leaf), representing the lowest level of the tree. /// </summary> public MerkleNode(MerkleHash hash) { Hash = hash; }
public MerkleHash ComputeHash(byte[] buffer) { Hash = MerkleHash.Create(buffer); return(Hash); }