Skip to content

Commit

Permalink
Merge pull request #2 from poloniex/init
Browse files Browse the repository at this point in the history
init
  • Loading branch information
Pzzzzzack authored Aug 20, 2024
2 parents 02d87bd + 572aa67 commit dea3448
Show file tree
Hide file tree
Showing 41 changed files with 4,234 additions and 1 deletion.
27 changes: 27 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
.PHONY: build-local



merkle_verify:
go build -o build/MerkleVerify-macos-x64 main/main.go

merkle_verify_linux:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o build/MerkleVerify-linux-x64 main/main.go

merkle_verify_windows:
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -o build/MerkleVerify-win-x64.exe main/main.go

keygen:
go build -o build/MerkleVerify merkle_groth16/src/keygen/main.go

prover:
go build -o build/MerkleVerify merkle_groth16/src/prover/main.go

userproof:
go build -o build/MerkleVerify merkle_groth16/src/userproof/main.go

verifier:
go build -o build/MerkleVerify merkle_groth16/src/verifier/main.go

witness:
go build -o build/MerkleVerify merkle_groth16/src/witness/main.go
124 changes: 123 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,123 @@
# template-repo
# Poloniex Merkle Verify Tool

## Background

Poloniex launches [Proof of Reserves (PoR)]() to improve the security and transparency of user's assets. These tools will allow
you to verify the validity of your assets in the merkle sum tree by verify merkle proof file, in order to confirm your assets in Poloniex.

## Introduction

### Building the source

Download the [latest build](https://github.com/poloniex/tools-go-merkle-verify/releases) for your operating system and architecture. Also, you can build the source by yourself.

Building this open source tool requires Go (version >= 1.16).

Install dependencies
```shell
go mod vendor
```

build
```shell
make merkle_verify
```

run
```shell
./build/MerkleVerify --file ./merkle_sum_proof.json
```

# Poloniex Merkle Verify Tool V2

#### 1. Prover service
By using the r1cs circuit and pk and vk files generated by the keygen program, the required proof files are generated and stored in the database, allowing users to verify. The service is performed on the server side, and its built-in already includes verify, so after the prover runs, the verify will succeed as long as it runs according to the correct steps.

Operation method: Make sure that the current working directory is under zkmerkleverify, that is, under the upper directory of src. The config file is merkle_groth16/src/prover/config/config.json

MysqlDataSource is the dsn of you save your proofs
Redis is the source you save your treeroot
DbSuffix is the proof table suffix
ZkKeyName is corresponding to the batchsize

(1) When only one host is used to enable the prover service, use the following command to use the prover service:
```shell
go run merkle_groth16/src/prover/main.go
```
When prover is run correctly, it will output:
"there is no published status witness in db, so quit"
"prover run finish..."


(2) When multiple hosts are used to enable the prover service, all hosts are guaranteed to be in the above-mentioned working directory, and then use the same command:
```shell
go run merkle_groth16/src/prover/main.go
```
When the command of all hosts ends, the following output will be

"there is no published status witness in db, so quit"
"prover run finish..."

Use the following command:
```shell
go run merkle_groth16/src/prover/main.go -rerun
```
To check whether there is a prover program that has not been run, if there is, run it to completion, when the program runs normally, the final output shows:

"there is no received status witness in db, so quit"
"prover rerun finish..."

#### 2. Verifier service
Uses the verifier service to provide users with self-verification por verification services and userproof verification services. The customer uses the proof form and vk generated by the prover service to perform por verification and userproof verification. Among them, por verification is our zero-knowledge asset proof verification, and userproof is our zero-knowledge Merkle tree verification. Operation methods:Make sure that the current working directory is under zkmerkleverify, which is the upper directory of src.

Before using this service, you need to use the following command to download the proof0.csv required by the user:
The config file of it is
merkle_groth16/load_proof_from_database/config/config.json

MysqlDataSource is the dsn that you save your proofs
```shell
go run merkle_groth16/test/main/main.go
```

Use the following command to download the config.json required by the user:
The config file is merkle_groth16/src/dbtool/config/config.json

MysqlDataSource is the dsn of you save your proofs
TreeDB is the source you save your treeroot
DbSuffix is the proof table suffix

```shell
go run merkle_groth16/src/dbtool/main.go
```

Use the following command to verify por:
The config file is merkle_groth16/src/verifier/config/config.json

```shell
go run merkle_groth16/src/verifier/main.go
```

If the verification is passed, it will output

"All proofs verify passed!!!"

otherwise output

"proof verify failed:"
Use the following command to perform userproof verification
The config file is merkle_groth16/src/verifier/config/user_config.json

```shell
go run merkle_groth16/src/verifier/main.go -user
```

If the verification is passed, the output will be:

"verify pass!!!"

Otherwise output:

"verify failed..."



76 changes: 76 additions & 0 deletions main/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package main

import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"os"

"github.com/spf13/cobra"

"merkleverifytool/merkle"
)

func main() {
Execute()
}

var proofJsonFile string
var failStr = "Merkle proof verify failed! "

var rootCmd = &cobra.Command{
Use: "MerkleValidator",
Short: "merkle tree path validation",
Long: ``,
Run: MerkleVerify,
}

func Execute() {
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}

func init() {
cobra.OnInitialize(initConfig)
rootCmd.PersistentFlags().StringVar(&proofJsonFile, "file", "", "")
}

func initConfig() {}

func MerkleVerify(cmd *cobra.Command, args []string) {
log.Println("Merkle verify start")
if proofJsonFile == "" {
log.Println(failStr, "Invalid merkle proof file")
return
}
buf, err := ioutil.ReadFile(proofJsonFile)
if err != nil {
log.Println(failStr, "Invalid merkle proof file", err)
return
}
if len(buf) == 0 {
log.Println(failStr, "Empty merkle proof file")
return
}
pf := new(merkle.JsonProofPath)
if err := json.Unmarshal(buf, &pf); err != nil {
log.Println(fmt.Sprintf(failStr+"error:%s", err))
return
}

verified, err := merkle.VerifyProofFile(pf)

if verified {
log.Println("Merkle proof verify passed.")
return
} else {
if err != nil {
log.Println(failStr + err.Error())
return
}
log.Println(failStr)
}
}
68 changes: 68 additions & 0 deletions merkle/proof.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package merkle

import (
"errors"
"fmt"
"hash"
)

func hash256(hash string, hashStrategy func() hash.Hash) ([]byte, error) {
h := hashStrategy()
if _, err := h.Write([]byte(hash)); err != nil {
return nil, err
}

return h.Sum(nil), nil
}

func VerifyProof(m *PathNodes) (bool, error) {
if len(m.Path) < 3 {
return false, errors.New("invalid path")
}
self := m.Path[len(m.Path)-1]
var lNode, rNode *PathNode
if self.R == 1 {
lNode, rNode = m.Path[1], self
} else {
lNode, rNode = self, m.Path[1]
}

node, err := NewPath(lNode, rNode)
if err != nil {
return false, err
}

for i := 2; i < len(m.Path)-1; i++ {
if m.Path[i].R == 1 {
lNode, rNode = node, m.Path[i]
} else {
lNode, rNode = m.Path[i], node
}
node, err = NewPath(lNode, rNode)
if err != nil {
return false, err
}
}

root := m.Path[0]

for i := 0; i < Length; i++ {
fmt.Printf("Rebuild root %s balance : %s, root %s balance in proof file : %s \n", CoinList[i], node.Ub.Coins[CoinList[i]], CoinList[i], root.Ub.Coins[CoinList[i]])
}

fmt.Printf("Rebuild root hash: %s, root hash in proof file: %s \n", node.Hash, root.Hash)

if node.Hash != root.Hash || !node.Ub.Equal(root.Ub) {
return false, err
}
return true, nil
}

func VerifyProofFile(pf *JsonProofPath) (bool, error) {
verified, err := VerifyProof(pf.JsonProofPathToPathNodes())
if verified {
return true, nil
}

return false, err
}
Loading

0 comments on commit dea3448

Please sign in to comment.