go-snark/zk/zk.go
zk/zk.goRaw
1package zk
2
3import (
4 "crypto/rand"
5 "fmt"
6 "math/big"
7
8 "github.com/arnaucube/go-snark/bn128"
9)
10
11type Setup struct {
12 T *big.Int // trusted setup secret
13 Ka *big.Int // trusted setup
14 Kb *big.Int // trusted setup
15 Kc *big.Int // trusted setup
16
17 // public
18 G1T [][3]*big.Int // t encrypted in G1 curve
19 G2T [][3][2]*big.Int // t encrypted in G2 curve
20}
21type Proof struct {
22 PiA [3]*big.Int
23 PiAp [3]*big.Int
24 PiB [3][2]*big.Int
25 PiBp [3][2]*big.Int
26 PiC [3]*big.Int
27 PiCp [3]*big.Int
28 PiH [3]*big.Int
29 Va [3][2]*big.Int
30 Vb [3][2]*big.Int
31 Vc [3][2]*big.Int
32 Vz [3][2]*big.Int
33}
34
35const bits = 512
36
37func GenerateTrustedSetup(bn bn128.Bn128, pollength int) (Setup, error) {
38 var setup Setup
39 var err error
40 // generate random t value
41 setup.T, err = rand.Prime(rand.Reader, bits)
42 if err != nil {
43 return Setup{}, err
44 }
45 fmt.Print("trusted t: ")
46 fmt.Println(setup.T)
47
48 // encrypt t values with curve generators
49 var gt1 [][3]*big.Int
50 var gt2 [][3][2]*big.Int
51 for i := 0; i < pollength; i++ {
52 tPow := bn.Fq1.Exp(setup.T, big.NewInt(int64(i)))
53 tEncr1 := bn.G1.MulScalar(bn.G1.G, tPow)
54 gt1 = append(gt1, tEncr1)
55 tEncr2 := bn.G2.MulScalar(bn.G2.G, tPow)
56 gt2 = append(gt2, tEncr2)
57 }
58 // gt1: g1, g1*t, g1*t^2, g1*t^3, ...
59 // gt2: g2, g2*t, g2*t^2, ...
60 setup.G1T = gt1
61 setup.G2T = gt2
62
63 // k for pi'
64 setup.Ka, err = rand.Prime(rand.Reader, bits)
65 if err != nil {
66 return Setup{}, err
67 }
68 setup.Kb, err = rand.Prime(rand.Reader, bits)
69 if err != nil {
70 return Setup{}, err
71 }
72 setup.Kc, err = rand.Prime(rand.Reader, bits)
73 if err != nil {
74 return Setup{}, err
75 }
76
77 return setup, nil
78}
79
80func GenerateProofs(bn bn128.Bn128, setup Setup, ax, bx, cx, hx, zx []*big.Int) Proof {
81 var proof Proof
82
83 // g1*A(x)
84 proof.PiA = [3]*big.Int{bn.G1.F.Zero(), bn.G1.F.Zero(), bn.G1.F.Zero()}
85 for i := 0; i < len(ax); i++ {
86 m := bn.G1.MulScalar(setup.G1T[i], ax[i])
87 proof.PiA = bn.G1.Add(proof.PiA, m)
88 }
89 proof.PiAp = bn.G1.MulScalar(proof.PiA, setup.Ka)
90
91 // g1*B(x)
92 proof.PiB = bn.Fq6.Zero()
93 for i := 0; i < len(bx); i++ {
94 m := bn.G2.MulScalar(setup.G2T[i], bx[i])
95 proof.PiB = bn.G2.Add(proof.PiB, m)
96 }
97 proof.PiBp = bn.G2.MulScalar(proof.PiB, setup.Kb)
98
99 // g1*C(x)
100 proof.PiC = [3]*big.Int{bn.G1.F.Zero(), bn.G1.F.Zero(), bn.G1.F.Zero()}
101 for i := 0; i < len(cx); i++ {
102 m := bn.G1.MulScalar(setup.G1T[i], cx[i])
103 proof.PiC = bn.G1.Add(proof.PiC, m)
104 }
105 proof.PiCp = bn.G1.MulScalar(proof.PiC, setup.Kc)
106
107 g1Ht := [3]*big.Int{bn.G1.F.Zero(), bn.G1.F.Zero(), bn.G1.F.Zero()}
108 for i := 0; i < len(hx); i++ {
109 m := bn.G1.MulScalar(setup.G1T[i], hx[i])
110 g1Ht = bn.G1.Add(g1Ht, m)
111 }
112 g2Zt := bn.Fq6.Zero()
113 for i := 0; i < len(bx); i++ {
114 m := bn.G2.MulScalar(setup.G2T[i], zx[i])
115 g2Zt = bn.G2.Add(g2Zt, m)
116 }
117 proof.PiH = g1Ht
118 proof.Vz = g2Zt
119 proof.Va = bn.G2.MulScalar(bn.G2.G, setup.Ka)
120 proof.Vb = bn.G2.MulScalar(bn.G2.G, setup.Kb)
121 proof.Vc = bn.G2.MulScalar(bn.G2.G, setup.Kc)
122
123 return proof
124}
125
126func VerifyProof(bn bn128.Bn128, setup Setup, proof Proof) bool {
127
128 // e(piA, Va) == e(piA', g2)
129 pairingPiaVa, err := bn.Pairing(proof.PiA, proof.Va)
130 if err != nil {
131 return false
132 }
133 pairingPiapG2, err := bn.Pairing(proof.PiAp, bn.G2.G)
134 if err != nil {
135 return false
136 }
137 if !bn.Fq12.Equal(pairingPiaVa, pairingPiapG2) {
138 return false
139 }
140
141 // e(piB, Vb) == e(piB', g2)
142
143 // e(piC, Vc) == e(piC', g2)
144 pairingPicVc, err := bn.Pairing(proof.PiC, proof.Vc)
145 if err != nil {
146 return false
147 }
148 pairingPicpG2, err := bn.Pairing(proof.PiCp, bn.G2.G)
149 if err != nil {
150 return false
151 }
152 if !bn.Fq12.Equal(pairingPicVc, pairingPicpG2) {
153 return false
154 }
155
156 //
157
158 return true
159}