merkle

package module
v2.0.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 8, 2022 License: MIT Imports: 2 Imported by: 0

README

Merkle - Efficient calculation of merkle roots and proofs

Go Reference Go Report Card Tests Coverage Status Mentioned in Awesome Go

This is merkle, a Go package for computing the Merkle root hash of a sequence of byte strings, or of their hashes. It can also produce a compact proof that a given string belongs in a Merkle tree with a given root hash.

This implementation does not require holding all of the input in memory while computing a root hash or a proof. Instead, it is able to operate on a stream of input strings of unbounded length, holding incremental state that is only logarithmic [O(log N)] in the size of the input.

For more about Merkle trees, see the Wikipedia article.

Creating a merkle root hash:

var ch <-chan []byte  // Represents some source of byte strings
tree := merkle.NewTree(sha256.New())
for str := range ch {
  tree.Add(str)
}
fmt.Printf("merkle root hash is %x\n", tree.Root())

Creating a merkle proof that ref belongs in the tree, then verifying the proof:

var (
  ch       <-chan []byte  // Represents some source of byte strings
  rootHash []byte         // Represents a previously computed merkle root hash (held by someone wishing to verify that ref is in the tree)
  ref      []byte         // Represents the string to prove is a member of the tree with the given root hash
)
tree := merkle.NewProofTree(sha256.New(), ref)
for str := range ch {
  tree.Add(str)
}
proof := tree.Proof()  // This is a compact object. For verification purposes, tree can now be discarded.

// Verification:
if bytes.Equal(rootHash, proof.Hash(sha256.New(), ref)) {
  fmt.Println("Verified!")
}

Documentation

Overview

Example (ComputeMerkleRoot)
var ch <-chan []byte // Represents a sequence of byte strings

tree := merkle.NewTree(sha256.New())
for str := range ch {
	tree.Add(str)
}
// The Merkle root hash of the sequence of strings is now tree.Root()
Output:

Example (ProduceMerkleProof)
var (
	ch  <-chan []byte // Represents a sequence of byte strings
	ref []byte        // Represents the string you will later want to prove is a member of the tree we're about to build
)

tree := merkle.NewProofTree(sha256.New(), ref)
for str := range ch {
	tree.Add(str)
}
proof := tree.Proof()
// A verifier with only the Merkle root hash r,
// and this proof,
// can verify ref belongs in the tree by checking:
//   bytes.Equal(r, proof.Hash(sha256.New(), ref))
_ = proof
Output:

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func LeafHash

func LeafHash(h hash.Hash, out, in []byte) []byte

LeafHash produces the hash of a leaf of a Tree.

Types

type HTree

type HTree struct {
	// contains filtered or unexported fields
}

HTree accepts a sequence of leaf hashes via its Add method. A leaf hash is the result of calling LeafHash on a string. After adding all leaf hashes in the sequence, their Merkle root hash may be read via the Root method.

Note that a Tree works by converting its input from a sequence of strings to the corresponding sequence of leaf hashes and feeding those to an HTree.

func NewHTree

func NewHTree(hasher hash.Hash) *HTree

NewHTree produces a new HTree.

func NewProofHTree

func NewProofHTree(hasher hash.Hash, ref []byte) *HTree

NewProofHTree produces a new HTree that can compactly prove a given reference hash is in it. After adding elements to the tree, call Proof to get the proof.

func (*HTree) Add

func (h *HTree) Add(item []byte)

Add adds a leaf hash to the sequence in h. The caller must not reuse the space in item. It is an error to call Add after a call to Root or Proof.

func (*HTree) Proof

func (h *HTree) Proof() Proof

Proof returns the Merkle inclusion proof for the reference hash given to NewProofHTree. It is an error to call Add after a call to Proof.

func (*HTree) Root

func (h *HTree) Root() []byte

Root returns the Merkle root hash for the sequence of leaf hashes that have been added to h with Add. It is an error to call Add after a call to Root.

type Proof

type Proof struct {
	Steps []ProofStep
	// contains filtered or unexported fields
}

Proof is a Merkle proof.

func (Proof) Hash

func (p Proof) Hash(hasher hash.Hash, ref []byte) []byte

Hash computes the hash of a Merkle proof. A valid Merkle proof hash matches the root hash of the Merkle tree it came from.

To prove that x is in a tree, create a tree t with NewProofTree(h, x). Then fill the tree with calls to t.Add. Then get the proof p with t.Proof(). Then check that p.Hash(h, x) is the same as t.Root(). This will be true only if there was a call t.Add(x) in the proper sequence.

type ProofStep

type ProofStep struct {
	H    []byte
	Left bool
}

ProofStep is one step in a Merkle proof.

type Tree

type Tree struct {
	// contains filtered or unexported fields
}

Tree accepts a sequence of strings via its Add method. It builds a Merkle hash tree from them. After adding all strings in the sequence, their Merkle root hash may be read via the Root method.

func NewProofTree

func NewProofTree(hasher hash.Hash, ref []byte) *Tree

NewProofTree produces a new Tree that can compactly prove a given string is in it. After adding elements to the tree, call Proof to get the proof.

func NewTree

func NewTree(hasher hash.Hash) *Tree

NewTree produces a new Tree.

func (*Tree) Add

func (m *Tree) Add(str []byte)

Add adds a string to the sequence in m. The caller may reuse the space in str. It is an error to call Add after a call to Root or Proof.

func (*Tree) Proof

func (m *Tree) Proof() Proof

Proof returns the Merkle inclusion proof for the reference string given to NewProofTree. It is an error to call Add after a call to Proof.

func (*Tree) Root

func (m *Tree) Root() []byte

Root returns the Merkle root hash for the sequence of strings that have been added to m with Add. It is an error to call Add after a call to Root.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL