public static Hash GetMerkleRoot(this IEnumerable <Hash> nodes) { if (nodes.Count() == 0) { return(null); } if (nodes.Count() == 1) { return(nodes.FirstOrDefault()); } var merkle = new Queue <Hash>(); while (merkle.Count > 1) { // Create a copy of the last entry if we have an odd number of entries if (merkle.Count % 2 == 1) { merkle.Enqueue(new Hash(merkle.Last().Digest)); } // Start creating our next layer var nextMerkle = new Queue <Hash>(); while (merkle.Count > 0) { using (var ms = new MemoryStream()) using (var bw = new BinaryWriter(ms)) { // We can assume merkle was even to start with // => it will keep on being even if we always dequeue 2 at a time bw.Write((byte[])merkle.Dequeue()); bw.Write((byte[])merkle.Dequeue()); nextMerkle.Enqueue(HashUtil.Compute(HashUtil.Compute(ms.ToArray()))); } } merkle = nextMerkle; } return(merkle.Dequeue()); }
public bool Validate(byte[] data) => HashUtil.Compute(HashUtil.Compute(data.SkipLast(4).ToArray())).TakeLast(4).SequenceEqual(data.TakeLast(4));