Documentation ¶
Overview ¶
Package arbo implements a Merkle Tree compatible with the circomlib implementation of the MerkleTree, following the specification from https://docs.iden3.io/publications/pdfs/Merkle-Tree.pdf and https://eprint.iacr.org/2018/955.
Allows to define which hash function to use. So for example, when working with zkSnarks the Poseidon hash function can be used, but when not, it can be used the Blake2b hash function, which has much faster computation time.
Package arbo > vt.go implements the Virtual Tree, which computes a tree without computing any hash. With the idea of once all the leafs are placed in their positions, the hashes can be computed, avoiding computing a node hash more than one time.
Index ¶
- Constants
- Variables
- func BigIntToBytes(blen int, bi *big.Int) []byte
- func BytesToBigInt(b []byte) *big.Int
- func CheckProof(hashFunc HashFunction, k, v, root, packedSiblings []byte) (bool, error)
- func PackSiblings(hashFunc HashFunction, siblings [][]byte) ([]byte, error)
- func ReadIntermediateChilds(b []byte) ([]byte, []byte)
- func ReadLeafValue(b []byte) ([]byte, []byte)
- func SwapEndianness(b []byte) []byte
- func UnpackSiblings(hashFunc HashFunction, b []byte) ([][]byte, error)
- type CircomVerifierProof
- type Config
- type HashBlake2b
- type HashFunction
- type HashPoseidon
- type HashSha256
- type Invalid
- type Tree
- func (t *Tree) Add(k, v []byte) error
- func (t *Tree) AddBatch(keys, values [][]byte) ([]Invalid, error)
- func (t *Tree) AddBatchWithTx(wTx db.WriteTx, keys, values [][]byte) ([]Invalid, error)
- func (t *Tree) AddWithTx(wTx db.WriteTx, k, v []byte) error
- func (t *Tree) Delete(k []byte) error
- func (t *Tree) DeleteWithTx(wTx db.WriteTx, k []byte) error
- func (t *Tree) Dump(fromRoot []byte) ([]byte, error)
- func (t *Tree) DumpWriter(fromRoot []byte, w io.Writer) error
- func (t *Tree) FillMissingEmptySiblings(s [][]byte) [][]byte
- func (t *Tree) GenProof(k []byte) ([]byte, []byte, []byte, bool, error)
- func (t *Tree) GenProofWithTx(rTx db.Reader, k []byte) ([]byte, []byte, []byte, bool, error)
- func (t *Tree) GenerateCircomVerifierProof(k []byte) (*CircomVerifierProof, error)
- func (t *Tree) Get(k []byte) ([]byte, []byte, error)
- func (t *Tree) GetNLeafs() (int, error)
- func (*Tree) GetNLeafsWithTx(rTx db.Reader) (int, error)
- func (t *Tree) GetWithTx(rTx db.Reader, k []byte) ([]byte, []byte, error)
- func (t *Tree) Graphviz(w io.Writer, fromRoot []byte) error
- func (t *Tree) GraphvizFirstNLevels(rTx db.Reader, w io.Writer, fromRoot []byte, untilLvl int) error
- func (t *Tree) HashFunction() HashFunction
- func (t *Tree) ImportDump(b []byte) error
- func (t *Tree) ImportDumpReader(r io.Reader) error
- func (t *Tree) Iterate(fromRoot []byte, f func([]byte, []byte)) error
- func (t *Tree) IterateWithStop(fromRoot []byte, f func(int, []byte, []byte) bool) error
- func (t *Tree) IterateWithStopWithTx(rTx db.Reader, fromRoot []byte, f func(int, []byte, []byte) bool) error
- func (t *Tree) IterateWithTx(rTx db.Reader, fromRoot []byte, f func([]byte, []byte)) error
- func (t *Tree) PrintGraphviz(fromRoot []byte) error
- func (t *Tree) PrintGraphvizFirstNLevels(rTx db.Reader, fromRoot []byte, untilLvl int) error
- func (t *Tree) Root() ([]byte, error)
- func (t *Tree) RootWithTx(rTx db.Reader) ([]byte, error)
- func (t *Tree) RootsFromLevel(level int) ([][]byte, error)
- func (t *Tree) SetRoot(root []byte) error
- func (t *Tree) SetRootWithTx(wTx db.WriteTx, root []byte) error
- func (t *Tree) Snapshot(fromRoot []byte) (*Tree, error)
- func (t *Tree) Update(k, v []byte) error
- func (t *Tree) UpdateWithTx(wTx db.WriteTx, k, v []byte) error
Constants ¶
const ( // PrefixValueLen defines the bytes-prefix length used for the Value // bytes representation stored in the db PrefixValueLen = 2 // PrefixValueEmpty is used for the first byte of a Value to indicate // that is an Empty value PrefixValueEmpty = 0 // PrefixValueLeaf is used for the first byte of a Value to indicate // that is a Leaf value PrefixValueLeaf = 1 // PrefixValueIntermediate is used for the first byte of a Value to // indicate that is a Intermediate value PrefixValueIntermediate = 2 )
Variables ¶
var ( // TypeHashSha256 represents the label for the HashFunction of Sha256 TypeHashSha256 = []byte("sha256") // TypeHashPoseidon represents the label for the HashFunction of // Poseidon TypeHashPoseidon = []byte("poseidon") // TypeHashBlake2b represents the label for the HashFunction of Blake2b TypeHashBlake2b = []byte("blake2b") // HashFunctionSha256 contains the HashSha256 struct which implements // the HashFunction interface HashFunctionSha256 HashSha256 // HashFunctionPoseidon contains the HashPoseidon struct which implements // the HashFunction interface HashFunctionPoseidon HashPoseidon // HashFunctionBlake2b contains the HashBlake2b struct which implements // the HashFunction interface HashFunctionBlake2b HashBlake2b )
var ( // DefaultThresholdNLeafs defines the threshold number of leafs in the // tree that determines if AddBatch will work in memory or in disk. It // is defined when calling NewTree, and if set to 0 it will work always // in disk. DefaultThresholdNLeafs = 65536 // ErrKeyNotFound is used when a key is not found in the db neither in // the current db Batch. ErrKeyNotFound = fmt.Errorf("key not found") // ErrKeyAlreadyExists is used when trying to add a key as leaf to the // tree that already exists. ErrKeyAlreadyExists = fmt.Errorf("key already exists") // ErrInvalidValuePrefix is used when going down into the tree, a value // is read from the db and has an unrecognized prefix. ErrInvalidValuePrefix = fmt.Errorf("invalid value prefix") // ErrDBNoTx is used when trying to use Tree.dbPut but Tree.dbBatch==nil ErrDBNoTx = fmt.Errorf("dbPut error: no db Batch") // ErrMaxLevel indicates when going down into the tree, the max level is // reached ErrMaxLevel = fmt.Errorf("max level reached") // ErrMaxVirtualLevel indicates when going down into the tree, the max // virtual level is reached ErrMaxVirtualLevel = fmt.Errorf("max virtual level reached") // ErrSnapshotNotEditable indicates when the tree is a non writable // snapshot, thus can not be modified ErrSnapshotNotEditable = fmt.Errorf("snapshot tree can not be edited") // ErrTreeNotEmpty indicates when the tree was expected to be empty and // it is not ErrTreeNotEmpty = fmt.Errorf("tree is not empty") )
Functions ¶
func BigIntToBytes ¶
BigIntToBytes converts a *big.Int into a byte array in Little-Endian
func BytesToBigInt ¶
BytesToBigInt converts a byte array in Little-Endian representation into *big.Int
func CheckProof ¶
func CheckProof(hashFunc HashFunction, k, v, root, packedSiblings []byte) (bool, error)
CheckProof verifies the given proof. The proof verification depends on the HashFunction passed as parameter.
func PackSiblings ¶
func PackSiblings(hashFunc HashFunction, siblings [][]byte) ([]byte, error)
PackSiblings packs the siblings into a byte array. [ 2 byte | 2 byte | L bytes | S * N bytes ] [ full length | bitmap length (L) | bitmap | N non-zero siblings ] Where the bitmap indicates if the sibling is 0 or a value from the siblings array. And S is the size of the output of the hash function used for the Tree. The 2 2-byte that define the full length and bitmap length, are encoded in little-endian.
func ReadIntermediateChilds ¶
ReadIntermediateChilds reads from a byte array the two childs keys
func ReadLeafValue ¶
ReadLeafValue reads from a byte array the leaf key & value
func SwapEndianness ¶
SwapEndianness swaps the order of the bytes in the byte slice.
func UnpackSiblings ¶
func UnpackSiblings(hashFunc HashFunction, b []byte) ([][]byte, error)
UnpackSiblings unpacks the siblings from a byte array.
Types ¶
type CircomVerifierProof ¶
type CircomVerifierProof struct { Root []byte `json:"root"` Siblings [][]byte `json:"siblings"` OldKey []byte `json:"oldKey"` OldValue []byte `json:"oldValue"` IsOld0 bool `json:"isOld0"` Key []byte `json:"key"` Value []byte `json:"value"` Fnc int `json:"fnc"` // 0: inclusion, 1: non inclusion }
CircomVerifierProof contains the needed data to check a Circom Verifier Proof inside a circom circuit. CircomVerifierProof allow to verify through a zkSNARK proof the inclusion/exclusion of a leaf in a tree.
func (CircomVerifierProof) MarshalJSON ¶
func (cvp CircomVerifierProof) MarshalJSON() ([]byte, error)
MarshalJSON implements the JSON marshaler
type Config ¶
type Config struct { Database db.Database MaxLevels int ThresholdNLeafs int HashFunction HashFunction }
Config defines the configuration for calling NewTree & NewTreeWithTx methods
type HashBlake2b ¶
type HashBlake2b struct{}
HashBlake2b implements the HashFunction interface for the Blake2b hash
func (HashBlake2b) Hash ¶
func (HashBlake2b) Hash(b ...[]byte) ([]byte, error)
Hash implements the hash method for the HashFunction HashBlake2b
func (HashBlake2b) Type ¶
func (HashBlake2b) Type() []byte
Type returns the type of HashFunction for the HashBlake2b
type HashFunction ¶
HashFunction defines the interface that is expected for a hash function to be used in a generic way in the Tree.
type HashPoseidon ¶
type HashPoseidon struct{}
HashPoseidon implements the HashFunction interface for the Poseidon hash
func (HashPoseidon) Hash ¶
func (f HashPoseidon) Hash(b ...[]byte) ([]byte, error)
Hash implements the hash method for the HashFunction HashPoseidon. It expects the byte arrays to be little-endian representations of big.Int values.
func (HashPoseidon) Type ¶
func (HashPoseidon) Type() []byte
Type returns the type of HashFunction for the HashPoseidon
type HashSha256 ¶
type HashSha256 struct{}
HashSha256 implements the HashFunction interface for the Sha256 hash
func (HashSha256) Hash ¶
func (HashSha256) Hash(b ...[]byte) ([]byte, error)
Hash implements the hash method for the HashFunction HashSha256
func (HashSha256) Type ¶
func (HashSha256) Type() []byte
Type returns the type of HashFunction for the HashSha256
type Invalid ¶
Invalid is used when a key-value can not be added trough AddBatch, and contains the index of the key-value and the error.
type Tree ¶
Tree defines the struct that implements the MerkleTree functionalities
func NewTree ¶
NewTree returns a new Tree, if there is a Tree still in the given database, it will load it.
func NewTreeWithTx ¶
NewTreeWithTx returns a new Tree using the given db.WriteTx, which will not be committed inside this method, if there is a Tree still in the given database, it will load it.
func (*Tree) Add ¶
Add inserts the key-value into the Tree. If the inputs come from a *big.Int, is expected that are represented by a Little-Endian byte array (for circom compatibility).
func (*Tree) AddBatch ¶
AddBatch adds a batch of key-values to the Tree. Returns an array containing the indexes of the keys failed to add. Supports empty values as input parameters, which is equivalent to 0 valued byte array.
func (*Tree) AddBatchWithTx ¶
AddBatchWithTx does the same than the AddBatch method, but allowing to pass the db.WriteTx that is used. The db.WriteTx will not be committed inside this method.
func (*Tree) AddWithTx ¶
AddWithTx does the same than the Add method, but allowing to pass the db.WriteTx that is used. The db.WriteTx will not be committed inside this method.
func (*Tree) DeleteWithTx ¶ added in v1.9.0
DeleteWithTx does the same as the Delete method, but allows passing the db.WriteTx that is used. The db.WriteTx will not be committed inside this method.
func (*Tree) Dump ¶
Dump exports all the Tree leafs in a byte array. The provided root must be a valid existing intermediate node in the tree. Or nil to use the current root.
func (*Tree) DumpWriter ¶
DumpWriter exports all the Tree leafs writing the bytes in the given Writer. The provided root must be a valid existing intermediate node in the tree. Or nil to use the current root.
func (*Tree) FillMissingEmptySiblings ¶
FillMissingEmptySiblings adds the empty values to the array of siblings for the Tree number of max levels
func (*Tree) GenProof ¶
GenProof generates a MerkleTree proof for the given key. The leaf value is returned, together with the packed siblings of the proof, and a boolean parameter that indicates if the proof is of existence (true) or not (false).
func (*Tree) GenProofWithTx ¶
GenProofWithTx does the same than the GenProof method, but allowing to pass the db.ReadTx that is used.
func (*Tree) GenerateCircomVerifierProof ¶
func (t *Tree) GenerateCircomVerifierProof(k []byte) (*CircomVerifierProof, error)
GenerateCircomVerifierProof generates a CircomVerifierProof for a given key in the Tree
func (*Tree) Get ¶
Get returns the value in the Tree for a given key. If the key is not found, will return the error ErrKeyNotFound, and in the leafK & leafV parameters will be placed the data found in the tree in the leaf that was on the path going to the input key.
func (*Tree) GetNLeafsWithTx ¶
GetNLeafsWithTx does the same than the GetNLeafs method, but allowing to pass the db.ReadTx that is used.
func (*Tree) GetWithTx ¶
GetWithTx does the same than the Get method, but allowing to pass the db.ReadTx that is used. If the key is not found, will return the error ErrKeyNotFound, and in the leafK & leafV parameters will be placed the data found in the tree in the leaf that was on the path going to the input key.
func (*Tree) Graphviz ¶
Graphviz iterates across the full tree to generate a string Graphviz representation of the tree and writes it to w
func (*Tree) GraphvizFirstNLevels ¶
func (t *Tree) GraphvizFirstNLevels(rTx db.Reader, w io.Writer, fromRoot []byte, untilLvl int) error
GraphvizFirstNLevels iterates across the first NLevels of the tree to generate a string Graphviz representation of the first NLevels of the tree and writes it to w
func (*Tree) HashFunction ¶
func (t *Tree) HashFunction() HashFunction
HashFunction returns Tree.hashFunction
func (*Tree) ImportDump ¶
ImportDump imports the leafs (that have been exported with the Dump method) in the Tree, reading them from the given byte array.
func (*Tree) ImportDumpReader ¶
ImportDumpReader imports the leafs (that have been exported with the Dump method) in the Tree, reading them from the given reader.
func (*Tree) Iterate ¶
Iterate iterates through the full Tree, executing the given function on each node of the Tree. The iteration starts from the given root. If no root is given, the current root is used. The provided root must be a valid existing intermediate node in the tree.
func (*Tree) IterateWithStop ¶
IterateWithStop does the same than Iterate, but with int for the current level, and a boolean parameter used by the passed function, is to indicate to stop iterating on the branch when the method returns 'true'.
func (*Tree) IterateWithStopWithTx ¶
func (t *Tree) IterateWithStopWithTx(rTx db.Reader, fromRoot []byte, f func(int, []byte, []byte) bool) error
IterateWithStopWithTx does the same than the IterateWithStop method, but allowing to pass the db.ReadTx that is used.
func (*Tree) IterateWithTx ¶
IterateWithTx does the same than the Iterate method, but allowing to pass the db.ReadTx that is used. The iteration starts from the given root. If no root is given, the current root is used. The provided root must be a valid existing intermediate node in the tree.
func (*Tree) PrintGraphviz ¶
PrintGraphviz prints the output of Tree.Graphviz
func (*Tree) PrintGraphvizFirstNLevels ¶
PrintGraphvizFirstNLevels prints the output of Tree.GraphvizFirstNLevels
func (*Tree) RootWithTx ¶
RootWithTx returns the root of the Tree using the given db.ReadTx
func (*Tree) RootsFromLevel ¶ added in v1.9.0
RootsFromLevel retrieves all intermediary nodes at a specified level of the tree. The function traverses the tree from the root down to the given level, collecting all the intermediary nodes along the way. If the specified level exceeds the maximum depth of the tree, an error is returned.
func (*Tree) SetRoot ¶
SetRoot sets the root to the given root. The root hash must be a valid existing intermediate node in the tree. The list of roots for a level can be obtained using tree.RootsFromLevel().
func (*Tree) SetRootWithTx ¶
SetRootWithTx sets the root to the given root using the given db.WriteTx
func (*Tree) Snapshot ¶
Snapshot returns a read-only copy of the Tree from the given root. If no root is given, the current root is used. The provided root must be a valid existing intermediate node in the tree. The list of roots for a level can be obtained using tree.RootsFromLevel().