merkletree

package
v0.0.6 Latest Latest
Warning

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

Go to latest
Published: Jul 9, 2019 License: GPL-3.0 Imports: 11 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// ElemBytesLen is the length in bytes of each element used for storing
	// data and hashing.
	ElemBytesLen = 32
	// IndexLen indicates how many elements are used for the index.
	IndexLen = 2
	// DataLen indicates how many elements are used for the data.
	DataLen = 4
)

Variables

View Source
var (
	// ErrNodeKeyAlreadyExists is used when a node key already exists.
	ErrNodeKeyAlreadyExists = errors.New("node already exists")
	// ErrEntryIndexNotFound is used when no entry is found for an index.
	ErrEntryIndexNotFound = errors.New("node index not found in the DB")
	// ErrNodeDataBadSize is used when the data of a node has an incorrect
	// size and can't be parsed.
	ErrNodeDataBadSize = errors.New("node data has incorrect size in the DB")
	// ErrReachedMaxLevel is used when a traversal of the MT reaches the
	// maximum level.
	ErrReachedMaxLevel = errors.New("reached maximum level of the merkle tree")
	// ErrInvalidNodeFound is used when an invalid node is found and can't
	// be parsed.
	ErrInvalidNodeFound = errors.New("found an invalid node in the DB")
	// ErrInvalidProofBytes is used when a serialized proof is invalid.
	ErrInvalidProofBytes = errors.New("the serialized proof is invalid")
	// ErrInvalidDBValue is used when a value in the key value DB is
	// invalid (for example, it doen't contain a byte header and a []byte
	// body of at least len=1.
	ErrInvalidDBValue = errors.New("the value in the DB is invalid")
	// ErrEntryIndexAlreadyExists is used when the entry index already
	// exists in the tree.
	ErrEntryIndexAlreadyExists = errors.New("the entry index already exists in the tree")
	// ErrNotWritable is used when the MerkleTree is not writable and a write function is called
	ErrNotWritable = errors.New("Merkle Tree not writable")
	// HashZero is a hash value of zeros, and is the key of an empty node.
	HashZero = Hash{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
	// ElemBytesOne is a constant element used as a prefix to compute leaf node keys.
	ElemBytesOne = ElemBytes{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}
)

Functions

func ElemBytesToRElem added in v0.0.6

func ElemBytesToRElem(elem ElemBytes) (mimc7.RElem, error)

ElemBytesToRElem converts an ElemBytes to a mimc7.RElem. This function returns an error if the ElemBytes is invalid (it's bigger than the RElement field).

func ElemsBytesToBytes

func ElemsBytesToBytes(es []ElemBytes) []byte

ElemsBytesToBytes serializes an array of ElemBytes to []byte.

func ElemsBytesToRElems

func ElemsBytesToRElems(elems ...ElemBytes) ([]mimc7.RElem, error)

ElemsBytesToRElems converts an array of ElemBytes to an array of mimc7.RElem. This function returns an error if any ElemBytes are invalid (they are bigger than the RElement field).

func ElemsBytesToRElemsPanic

func ElemsBytesToRElemsPanic(elems ...ElemBytes) []mimc7.RElem

ElemsBytesToRElemsPanic converts an array of ElemBytes to an array of mimc7.RElem. This function assumes that ElemBytes are properly constructed, and will panic if they are not.

func VerifyProof

func VerifyProof(rootKey *Hash, proof *Proof, hIndex, hValue *Hash) bool

VerifyProof verifies the Merkle Proof for the entry and root.

Types

type Data

type Data [DataLen]ElemBytes

Data is the type used to represent the data stored in an entry of the MT. It consists of 4 elements: e0, e1, e2, e3; where v = [e0,e1], index = [e2,e3].

func NewDataFromBytes added in v0.0.3

func NewDataFromBytes(b [ElemBytesLen * DataLen]byte) *Data

func (*Data) Bytes

func (d *Data) Bytes() (b [ElemBytesLen * DataLen]byte)

func (*Data) Equal added in v0.0.6

func (d1 *Data) Equal(d2 *Data) bool

func (*Data) MarshalJSON

func (d *Data) MarshalJSON() ([]byte, error)

func (*Data) String

func (d *Data) String() string

func (*Data) UnmarshalJSON added in v0.0.3

func (d *Data) UnmarshalJSON(bs []byte) error

type ElemBytes

type ElemBytes [ElemBytesLen]byte

ElemBytes is the basic type used to store data in the MT. ElemBytes corresponds to the serialization of an element from mimc7.

func (*ElemBytes) String

func (e *ElemBytes) String() string

String returns the last 4 bytes of ElemBytes in hex.

type Entrier

type Entrier interface {
	Entry() *Entry
}

type Entry

type Entry struct {
	Data Data
	// contains filtered or unexported fields
}

Entry is the generic type that is stored in the MT. The entry should not be modified after creating because the cached hIndex and hValue won't be updated.

func (*Entry) Bytes

func (e *Entry) Bytes() []byte

func (*Entry) HIndex

func (e *Entry) HIndex() *Hash

HIndex calculates the hash of the Index of the entry, used to find the path from the root to the leaf in the MT.

func (*Entry) HValue

func (e *Entry) HValue() *Hash

func (*Entry) MarshalJSON added in v0.0.3

func (e *Entry) MarshalJSON() ([]byte, error)

type Hash

type Hash ElemBytes

Hash is the type used to represent a hash used in the MT.

func HashElems

func HashElems(elems ...ElemBytes) *Hash

HashElems performs a mimc7 hash over the array of ElemBytes.

func HashElemsKey added in v0.0.5

func HashElemsKey(key *big.Int, elems ...ElemBytes) *Hash

HashElemsKey performs a mimc7 hash over the array of ElemBytes.

func LeafKey

func LeafKey(hIndex, hValue *Hash) *Hash

LeafKey computes the key of a leaf node given the hIndex and hValue of the entry of the leaf.

func RElemToHash

func RElemToHash(relem mimc7.RElem) (h Hash)

RElemToHash converts a mimc7.RElem to a Hash.

func (Hash) Bytes

func (h Hash) Bytes() []byte

Bytes returns a byte array from a Hash.

func (Hash) Hex

func (h Hash) Hex() string

Hex returns a hex string from the Hash type.

func (*Hash) MarshalJSON

func (h *Hash) MarshalJSON() ([]byte, error)

func (*Hash) String

func (h *Hash) String() string

String returns the last 4 bytes of Hash in hex.

func (*Hash) UnmarshalJSON added in v0.0.3

func (h *Hash) UnmarshalJSON(bs []byte) error

type Index

type Index [IndexLen]ElemBytes

Index is the type used to represent the index of an entry in the MT, used to find the path from the root to the leaf that contains such entry.

type MerkleTree

type MerkleTree struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

MerkleTree is the struct with the main elements of the Merkle Tree

func NewMerkleTree

func NewMerkleTree(storage db.Storage, maxLevels int) (*MerkleTree, error)

NewMerkleTree generates a new Merkle Tree

func (*MerkleTree) Add

func (mt *MerkleTree) Add(e *Entry) error

Add adds the Entry to the MerkleTree

func (*MerkleTree) DumpClaims

func (mt *MerkleTree) DumpClaims(w io.Writer, rootKey *Hash) error

DumpClaims uses Walk function to get all the Claims of the tree and write them to w

func (*MerkleTree) GenerateProof

func (mt *MerkleTree) GenerateProof(hIndex *Hash, rootKey *Hash) (*Proof, error)

GenerateProof generates the proof of existence (or non-existence) of an Entry's hash Index for a Merkle Tree given the root. If the rootKey is nil, the current merkletree root is used

func (*MerkleTree) GetDataByIndex

func (mt *MerkleTree) GetDataByIndex(hIndex *Hash) (*Data, error)

GetDataByIndex returns the data from the MT in the position of the hash of the index (hIndex)

func (*MerkleTree) GetNode

func (mt *MerkleTree) GetNode(key *Hash) (*Node, error)

GetNode gets a node by key from the MT. Empty nodes are not stored in the tree; they are all the same and assumed to always exist.

func (*MerkleTree) GraphViz

func (mt *MerkleTree) GraphViz(w io.Writer, rootKey *Hash) error

GraphViz uses Walk function to generate a string GraphViz representation of the tree and writes it to w

func (*MerkleTree) MaxLevels

func (mt *MerkleTree) MaxLevels() int

MaxLevels returns the MT maximum level

func (*MerkleTree) RootKey

func (mt *MerkleTree) RootKey() *Hash

RootKey returns the MT root node key

func (*MerkleTree) Snapshot

func (mt *MerkleTree) Snapshot(rootKey *Hash) (*MerkleTree, error)

func (*MerkleTree) Storage

func (mt *MerkleTree) Storage() db.Storage

Storage returns the MT storage

func (*MerkleTree) Walk

func (mt *MerkleTree) Walk(rootKey *Hash, f func(*Node)) error

Walk iterates over all the branches of a MerkleTree with the given rootKey if rootKey is nil, it will get the current RootKey of the current state of the MerkleTree. For each node, it calls the f function given in the parameters. See some examples of the Walk function usage in the merkletree_test.go test functions: TestMTWalk, TestMTWalkGraphViz, TestMTWalkDumpClaims

type Node

type Node struct {
	// Type is the type of node in the tree.
	Type NodeType
	// ChildL is the left child of a middle node.
	ChildL *Hash
	// ChildR is the right child of a middle node.
	ChildR *Hash
	// Entry is the data stored in a leaf node.
	Entry *Entry
	// contains filtered or unexported fields
}

Node is the struct that represents a node in the MT. The node should not be modified after creation because the cached key won't be updated.

func NewNodeEmpty

func NewNodeEmpty() *Node

NewNodeEmpty creates a new empty node.

func NewNodeFromBytes

func NewNodeFromBytes(b []byte) (*Node, error)

NewNodeFromBytes creates a new node by parsing the input []byte.

func NewNodeLeaf

func NewNodeLeaf(entry *Entry) *Node

NewNodeLeaf creates a new leaf node.

func NewNodeMiddle

func NewNodeMiddle(childL *Hash, childR *Hash) *Node

NewNodeMiddle creates a new middle node.

func (*Node) Key

func (n *Node) Key() *Hash

Key computes the key of the node by hashing the content in a specific way for each type of node. This key is used as the hash of the merklee tree for each node.

func (*Node) String

func (n *Node) String() string

String outputs a string representation of a node (different for each type).

func (*Node) Value

func (n *Node) Value() []byte

Value returns the value of the node. This is the content that is stored in the backend database.

type NodeType

type NodeType byte

NodeType defines the type of node in the MT.

const (
	// NodeTypeMiddle indicates the type of middle Node that has children.
	NodeTypeMiddle NodeType = 0
	// NodeTypeLeaf indicates the type of a leaf Node that contains a claim.
	NodeTypeLeaf NodeType = 1
	// NodeTypeEmpty indicates the type of an empty Node.
	NodeTypeEmpty NodeType = 2

	// DBEntryTypeRoot indicates the type of a DB entry that indicates the current Root of a MerkleTree
	DBEntryTypeRoot NodeType = 3
)

type Proof

type Proof struct {
	// existence indicates wether this is a proof of existence or non-existence.
	Existence bool

	// Siblings is a list of non-empty sibling keys.
	Siblings []*Hash
	// contains filtered or unexported fields
}

Proof defines the required elements for a MT proof of existence or non-existence.

func NewProofFromBytes

func NewProofFromBytes(bs []byte) (*Proof, error)

NewProofFromBytes parses a byte array into a Proof.

func (*Proof) Bytes

func (p *Proof) Bytes() []byte

Bytes serializes a Proof into a byte array.

func (*Proof) MarshalJSON

func (p *Proof) MarshalJSON() ([]byte, error)

func (*Proof) String

func (p *Proof) String() string

String outputs a multiline string representation of the Proof.

func (*Proof) UnmarshalJSON added in v0.0.3

func (p *Proof) UnmarshalJSON(bs []byte) error

Jump to

Keyboard shortcuts

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