Example #1
0
        public MerkleTree(MerkleProof proof)
        {
            if (proof == null)
            {
                throw new ArgumentNullException(nameof(proof));
            }

            Root = CreateTree(proof, DepthNeeded(proof.LeafCount));

            CheckForLeftovers(proof.ProofHashes, nameof(proof.ProofHashes));
            CheckForLeftovers(proof.IncludedHashes, nameof(proof.IncludedHashes));
            CheckForLeftovers(proof.Flags, nameof(proof.Flags));
        }
Example #2
0
        MerkleNode CreateTree(MerkleProof proof, int depth)
        {
            if (proof.Flags.Dequeue())
            {
                return(new(proof.ProofHashes.Dequeue()));
            }

            if (depth == 1)
            {
                return(new(proof.IncludedHashes.Dequeue()));
            }

            var left  = CreateTree(proof, depth - 1);
            var right = proof.Flags.Any() ? CreateTree(proof, depth - 1) : null;

            return(new(GetParentHash(left, right), left, right));
        }
Example #3
0
 void AddToProof(MerkleNode?node, MerkleProof proof, HashSet <string> includedSet)
 {
     if (node != null)
     {
         if (ContainsAny(node, includedSet))
         {
             proof.Flags.Enqueue(false);
             if (node.IsLeaf)
             {
                 proof.IncludedHashes.Enqueue(node.Hash);
             }
             AddToProof(node.Left, proof, includedSet);
             AddToProof(node.Right, proof, includedSet);
         }
         else
         {
             proof.Flags.Enqueue(true);
             proof.ProofHashes.Enqueue(node.Hash);
         }
     }
 }
Example #4
0
        public MerkleProof CreateProof(IEnumerable <byte[]> includedHashes)
        {
            if (includedHashes == null)
            {
                throw new ArgumentNullException(nameof(includedHashes));
            }
            var includedSet = new HashSet <string>(includedHashes.Select(b => b.ToHex()));

            if (!includedSet.Any())
            {
                throw new ArgumentException("Included hashes must not be empty", nameof(includedHashes));
            }

            var proof = new MerkleProof(LeafCount);

            AddToProof(Root, proof, includedSet);

            if (proof.IncludedHashes.Count != includedSet.Count)
            {
                throw new InvalidOperationException("Not all included hashes were found in the tree");
            }

            return(proof);
        }