mtree

package module
v0.3.5 Latest Latest
Warning

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

Go to latest
Published: May 2, 2020 License: MIT Imports: 6 Imported by: 0

README

mtree

GoDoc Go Report Card

Merkle Tree implementation in golang

A hash tree or Merkle tree is a tree in which every leaf node is labelled with the cryptographic hash of a data block, and every non-leaf node is labelled with the cryptographic hash in the labels of its child nodes. Hash trees allow efficient and secure verification of the contents of large data structures. Hash trees are a generalization of hash lists and hash chains. More details

An example of a binary hash tree. By Azaghal - Own work, CC0, Link Merkle Tree

Project Status
  • Variable branching factor
  • Binary Serialization
  • Update leaf-nodes partially
  • Append leaf-nodes
  • Support custom store (you can provide your own store either on-memory or persistent)
  • Find different leaf-nodes between two trees (useful for data synchronization)
Documentation

See the docs here.

Install
go get github.com/aungmawjj/mtree
Example Usage
package main

import (
	"crypto"
	"fmt"

	_ "crypto/sha256"

	"github.com/aungmawjj/mtree"
)

func main() {

	nbranch := 2 // branching factor of merkle tree

	hashFunc := crypto.SHA256
	hasher := hashFunc.New()

	data := []string{"Foo", "Bar", "Apple", "Orange", "Tree", "Box", "Big", "Cow"}

	// compute leaf-nodes for the merkle tree
	lnodes := make([][]byte, len(data))
	for i, d := range data {
		hasher.Write([]byte(d))
		lnodes[i] = hasher.Sum(nil)
		hasher.Reset()
	}

	m, _ := mtree.New(hashFunc, nbranch)
	m.Compute(lnodes)

	height, _ := m.Height()
	fmt.Println("Tree Height:", height)
	// Tree Height 4

	hasher.Reset()
	hasher.Write([]byte(data[1]))
	res, _ := m.Verify(1, hasher.Sum(nil))

	fmt.Println("Data block at index 1 verify result:", res)
	// Data block at index 1 verify result: true
	hasher.Reset()

	data[1] = "MODIFIED"

	hasher.Reset()
	hasher.Write([]byte(data[1]))
	res, _ = m.Verify(1, hasher.Sum(nil))

	fmt.Println("Data block at index 1 verify result:", res)
	// Data block at index 1 verify result: false
	hasher.Reset()
}

License

This project is licensed under the MIT License.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrorInvalidBF = errors.New("Branching factor must be at least 2")

	ErrorInvalidHashFunc = errors.New("Invalid hash function")

	ErrorInvalidBinaryLength = errors.New("Binary length is not valid")
)

Errors

Functions

This section is empty.

Types

type MerkleTree

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

MerkleTree type

func New

func New(hashFunc crypto.Hash, nbranch int) (*MerkleTree, error)

New creates a new MerkleTree instance

func NewWithStore added in v0.3.0

func NewWithStore(
	hashFunc crypto.Hash, nbranch int, store Store,
) (*MerkleTree, error)

NewWithStore creates a new MerkleTree instance with a given store

func (*MerkleTree) CommitUpdates added in v0.3.3

func (m *MerkleTree) CommitUpdates(bundle *UpdateBundle) error

CommitUpdates calls the store's CommitUpdates method

func (*MerkleTree) Compute

func (m *MerkleTree) Compute(lnodes [][]byte) error

Compute builds the merkle tree from given leaf-nodes It commits the results to the store during the process

func (*MerkleTree) Height

func (m *MerkleTree) Height() (int, error)

Height returns the merkle tree height

func (*MerkleTree) MarshalBinary

func (m *MerkleTree) MarshalBinary() ([]byte, error)

MarshalBinary encodes the merkle tree It directly calls the store's MarshalBinary method

func (*MerkleTree) Root

func (m *MerkleTree) Root() ([]byte, error)

Root returns the merkle root hash

func (*MerkleTree) UnmarshalBinary

func (m *MerkleTree) UnmarshalBinary(b []byte) error

UnmarshalBinary decoded the merkle tree It directly calls the store's UnmarshalBinary method

func (*MerkleTree) Update

func (m *MerkleTree) Update(
	lnodes map[int][]byte,
) (*UpdateBundle, error)

Update computes the sum of affected nodes for the modified leaf nodes. It doesn't commit the changes. Instead, it returns UpdateBundle, to be used for CommitUpdates() to commit the changes.

func (*MerkleTree) Verify

func (m *MerkleTree) Verify(idx int, value []byte) (bool, error)

Verify verifies the leaf-node at the specified index

type Position added in v0.3.0

type Position struct {
	Level   int
	NodeIdx int
}

Position of a node in the tree

type Store added in v0.3.0

type Store interface {

	// SetLeafCount sets the new leaf count
	SetLeafCount(nleaf int) error

	// GetLeafCount gives the current leaf count
	GetLeafCount() (int, error)

	// GetTreeHeight gives the current tree height
	GetTreeHeight() (int, error)

	// CommitUpdates commits updated nodes
	CommitUpdates(bundle *UpdateBundle) error

	// WriteNode insert the node to the specified position
	WriteNode(p Position, value []byte) error

	// ReadNode gives the node at the specified position
	ReadNode(p Position) ([]byte, error)

	// MarshalBinary encodes the tree to a []byte slice
	MarshalBinary() ([]byte, error)

	// UnmarshalBinary decodes the tree from a []byte slice
	UnmarshalBinary(b []byte) error
}

Store interface for merkle tree

type UpdateBundle added in v0.3.2

type UpdateBundle struct {
	NLeaf  int
	Height int
	Nodes  map[Position][]byte
}

UpdateBundle contains the information to commit updates

func (*UpdateBundle) Root added in v0.3.3

func (b *UpdateBundle) Root() []byte

Root returns the updated root value

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

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