forked from zksecurity/zkBank
-
Notifications
You must be signed in to change notification settings - Fork 0
/
gkr_adder.go
119 lines (94 loc) · 2.32 KB
/
gkr_adder.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
package zksec_gkr
import (
"hash"
"math/big"
"github.com/consensys/gnark-crypto/ecc/bn254/fr"
hashMimc "github.com/consensys/gnark-crypto/hash"
bn254r1cs "github.com/consensys/gnark/constraint/bn254"
"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/std/gkr"
stdHash "github.com/consensys/gnark/std/hash"
hashMimcCircuit "github.com/consensys/gnark/std/hash/mimc"
)
func init() {
InitializeBalanceGKR()
}
// This computes X + Y = Z using GKR
type BalanceGKR struct {
X []frontend.Variable
Y []frontend.Variable
Z []frontend.Variable
counter int
api frontend.API
}
func NewBalanceGKR(api frontend.API, bN int) *BalanceGKR {
return &BalanceGKR{
X: make([]frontend.Variable, 1<<bN),
Y: make([]frontend.Variable, 1<<bN),
Z: make([]frontend.Variable, 1<<bN),
counter: 0,
api: api,
}
}
func (m *BalanceGKR) VerifyGKR(challenges ...frontend.Variable) error {
if m.counter == 0 {
panic("are you even using the app bro?")
}
for i := m.counter; i < len(m.X); i++ {
m.X[i] = 0
m.Y[i] = 0
m.Z[i] = 0
}
_gkr := gkr.NewApi()
x, err := _gkr.Import(m.X)
if err != nil {
return err
}
y, err := _gkr.Import(m.Y)
if err != nil {
return err
}
z := _gkr.Add(x, y)
solution, err := _gkr.Solve(m.api)
if err != nil {
return err
}
Z_gkr := solution.Export(z)
err = solution.Verify("mimc", challenges...)
if err != nil {
return err
}
for i := 0; i < m.counter; i++ {
m.api.AssertIsEqual(m.Z[i], Z_gkr[i])
}
return nil
}
func (m *BalanceGKR) AddCircuit(il, ir frontend.Variable) frontend.Variable {
m.X[m.counter] = il
m.Y[m.counter] = ir
results, err := m.api.Compiler().NewHint(TransferHint, 1, il, ir)
if err != nil {
panic("failed to run hint, err: " + err.Error())
}
m.Z[m.counter] = results[0]
m.counter++
return results[0]
}
func TransferHint(q *big.Int, inputs []*big.Int, results []*big.Int) error {
lhs := new(fr.Element).SetBigInt(inputs[0])
rhs := new(fr.Element).SetBigInt(inputs[1])
var res fr.Element
res.Add(rhs, lhs)
bytes := res.Bytes()
results[0].SetBytes(bytes[:])
return nil
}
func InitializeBalanceGKR() {
bn254r1cs.RegisterHashBuilder("mimc", func() hash.Hash {
return hashMimc.MIMC_BN254.New()
})
stdHash.Register("mimc", func(api frontend.API) (stdHash.FieldHasher, error) {
m, err := hashMimcCircuit.NewMiMC(api)
return &m, err
})
}