/
withdraw.go
132 lines (115 loc) · 4.2 KB
/
withdraw.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package types
import (
"github.com/consensys/gnark-crypto/ecc"
"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/std/hash/mimc"
)
type WithdrawCircuit struct {
//public
TreeRootHash frontend.Variable `gnark:",public"`
AuthorizeSpendHash frontend.Variable `gnark:",public"`
NullifierHash frontend.Variable `gnark:",public"`
Amount frontend.Variable `gnark:",public"`
//secret
ReceiverPubKey frontend.Variable
ReturnPubKey frontend.Variable
AuthorizePubKey frontend.Variable
NoteRandom frontend.Variable
SpendPriKey frontend.Variable
SpendFlag frontend.Variable
AuthorizeFlag frontend.Variable
//tree path info
NoteHash frontend.Variable
Path0 frontend.Variable
Path1 frontend.Variable
Path2 frontend.Variable
Path3 frontend.Variable
Path4 frontend.Variable
Path5 frontend.Variable
Path6 frontend.Variable
Path7 frontend.Variable
Path8 frontend.Variable
Path9 frontend.Variable
Helper0 frontend.Variable
Helper1 frontend.Variable
Helper2 frontend.Variable
Helper3 frontend.Variable
Helper4 frontend.Variable
Helper5 frontend.Variable
Helper6 frontend.Variable
Helper7 frontend.Variable
Helper8 frontend.Variable
Helper9 frontend.Variable
Valid0 frontend.Variable
Valid1 frontend.Variable
Valid2 frontend.Variable
Valid3 frontend.Variable
Valid4 frontend.Variable
Valid5 frontend.Variable
Valid6 frontend.Variable
Valid7 frontend.Variable
Valid8 frontend.Variable
Valid9 frontend.Variable
}
// Define declares the circuit's constraints
func (circuit *WithdrawCircuit) Define(curveID ecc.ID, cs frontend.API) error {
cs.AssertIsBoolean(circuit.SpendFlag)
cs.AssertIsBoolean(circuit.AuthorizeFlag)
// hash function
h, _ := mimc.NewMiMC(MimcHashSeed, curveID, cs)
mimc := &h
mimc.Write(circuit.SpendPriKey)
targetSpendKey := cs.Select(circuit.SpendFlag, circuit.ReceiverPubKey, circuit.ReturnPubKey)
cs.AssertIsEqual(targetSpendKey, mimc.Sum())
nullValue := cs.Constant(0)
mimc.Reset()
mimc.Write(targetSpendKey, circuit.Amount, circuit.NoteRandom)
calcAuthHash := mimc.Sum()
targetAuthHash := cs.Select(circuit.AuthorizeFlag, calcAuthHash, nullValue)
cs.AssertIsEqual(circuit.AuthorizeSpendHash, targetAuthHash)
mimc.Reset()
mimc.Write(circuit.NoteRandom)
cs.AssertIsEqual(circuit.NullifierHash, mimc.Sum())
calcReturnPubkey := cs.Select(circuit.AuthorizeFlag, circuit.ReturnPubKey, nullValue)
calcAuthPubkey := cs.Select(circuit.AuthorizeFlag, circuit.AuthorizePubKey, nullValue)
mimc.Reset()
mimc.Write(circuit.ReceiverPubKey, calcReturnPubkey, calcAuthPubkey, circuit.Amount, circuit.NoteRandom)
cs.AssertIsEqual(circuit.NoteHash, mimc.Sum())
var proofSet, helper, valid []frontend.Variable
proofSet = append(proofSet, circuit.NoteHash)
proofSet = append(proofSet, circuit.Path0)
proofSet = append(proofSet, circuit.Path1)
proofSet = append(proofSet, circuit.Path2)
proofSet = append(proofSet, circuit.Path3)
proofSet = append(proofSet, circuit.Path4)
proofSet = append(proofSet, circuit.Path5)
proofSet = append(proofSet, circuit.Path6)
proofSet = append(proofSet, circuit.Path7)
proofSet = append(proofSet, circuit.Path8)
proofSet = append(proofSet, circuit.Path9)
//helper[0],valid[0]占位, 方便接口只设置有效值
helper = append(helper, cs.Constant("1"))
helper = append(helper, circuit.Helper0)
helper = append(helper, circuit.Helper1)
helper = append(helper, circuit.Helper2)
helper = append(helper, circuit.Helper3)
helper = append(helper, circuit.Helper4)
helper = append(helper, circuit.Helper5)
helper = append(helper, circuit.Helper6)
helper = append(helper, circuit.Helper7)
helper = append(helper, circuit.Helper8)
helper = append(helper, circuit.Helper9)
valid = append(valid, cs.Constant("1"))
valid = append(valid, circuit.Valid0)
valid = append(valid, circuit.Valid1)
valid = append(valid, circuit.Valid2)
valid = append(valid, circuit.Valid3)
valid = append(valid, circuit.Valid4)
valid = append(valid, circuit.Valid5)
valid = append(valid, circuit.Valid6)
valid = append(valid, circuit.Valid7)
valid = append(valid, circuit.Valid8)
valid = append(valid, circuit.Valid9)
VerifyMerkleProof(cs, mimc, circuit.TreeRootHash, proofSet, helper, valid)
return nil
}