Browse Source

Add Usage section to README.md

master
arnaucube 3 years ago
parent
commit
f2d5037862
2 changed files with 82 additions and 15 deletions
  1. +76
    -5
      README.md
  2. +6
    -10
      tree.go

+ 76
- 5
README.md

@ -3,10 +3,81 @@
> *arbo*: tree in Esperanto. > *arbo*: tree in Esperanto.
MerkleTree implementation in Go. Compatible with the circomlib implementation of MerkleTree implementation in Go. Compatible with the circomlib implementation of
the MerkleTree (when using the Poseidon hash function), following the
specification from https://docs.iden3.io/publications/pdfs/Merkle-Tree.pdf and
the MerkleTree, following the specification from
https://docs.iden3.io/publications/pdfs/Merkle-Tree.pdf and
https://eprint.iacr.org/2018/955. 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 Blake3 hash function, which improves the computation time.
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.
## Usage
```go
// create new database
database, err := db.NewBadgerDB(c.TempDir())
// create new Tree with maxLevels=100 and Blake2b hash function
tree, err := arbo.NewTree(database, 100, arbo.HashFunctionBlake2b)
key := []byte("hello")
value := []byte("world")
err = tree.Add(key, value)
// There are cases where multiple key-values (leafs) are going to be added to a
// Tree, for these cases is more effitient to use:
invalids, err := tree.AddBatch(keys, values)
// generate the merkle proof of a leaf by it's key
value, siblings, err := tree.GenProof(key)
// verify the proof
verified, err := arbo.CheckProof(tree.hashFunction, key, value, tree.Root(), siblings)
if !verified {
fmt.Println("proof could not be verified")
}
// get the value of a leaf assigned to a key
gettedKey, gettedValue, err := tree.Get(key)
// update the value of a leaf assigned to a key
err = tree.Update(key, value)
// dump the tree (the leafs)
dump, err := tree.Dump(nil) // instead of nil, a root to start from can be used
// import the dump into a tree
err = tree.ImportDump(dump)
// print graphviz diagram of the tree
err = tree.PrintGraphviz(nil) // instead of nil, a root to start from can be used
```
### Usage with SNARKs compatibility
Arbo is designed to be compatible with [circom merkle
tree](https://github.com/iden3/circomlib/tree/master/circuits/smt)'s
snark-friendly merkletree.
The only change needed is the hash function used for the Tree, for example using
the Poseidon hash function:
```go
tree, err := arbo.NewTree(database, 100, arbo.HashFunctionPoseidon)
```
Be aware of the characteristics of this kind of hashes, such as using values
inside the finite field used by the hash, and also the computation time.
The interface of arbo uses byte arrays, and for the case of these kind of hashes
(that usually work directly with finite field elements), arbo expects those
values to be represented by little-endian byte arrays. There is a helper method
to convert a `*big.Int` to `[]byte` using little-endian:
```go
bLen := tree.HashFunction().Len()
kBigInt := big.NewInt(100)
// convert *big.Int to byte array
kBytes := arbo.BigIntToBytes(bLen, kBigInt)
// convert byte array to *big.Int
kBigInt2 := arbo.BytesToBigInt(kBytes)
```

+ 6
- 10
tree.go

@ -1,13 +1,12 @@
/* /*
Package arbo implements a Merkle Tree compatible with the circomlib Package arbo implements a Merkle Tree compatible with the circomlib
implementation of the MerkleTree (when using the Poseidon hash function),
following the specification from
implementation of the MerkleTree, following the specification from
https://docs.iden3.io/publications/pdfs/Merkle-Tree.pdf and https://docs.iden3.io/publications/pdfs/Merkle-Tree.pdf and
https://eprint.iacr.org/2018/955. https://eprint.iacr.org/2018/955.
Also 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 Blake3 hash function, which improves the computation time.
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 package arbo
@ -966,9 +965,6 @@ func (t *Tree) PrintGraphvizFirstNLevels(rootKey []byte, untilLvl int) error {
return nil return nil
} }
// Purge WIP: unimplemented TODO
func (t *Tree) Purge(keys [][]byte) error {
return nil
}
// TODO circom proofs // TODO circom proofs
// TODO data structure for proofs (including root, key, value, siblings,
// hashFunction) + method to verify that data structure

Loading…
Cancel
Save