arnaucube
arnaucube/go-snarkPublic Self-hosted repository
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	"github.com/arnaucube/go-snark/fields"
 10)
 11
 12type Setup struct {
 13	Toxic struct {
 14		T  *big.Int // trusted setup secret
 15		Ka *big.Int // prover
 16		Kb *big.Int // prover
 17		Kc *big.Int // prover
 18	}
 19
 20	// public
 21	G1T [][3]*big.Int    // t encrypted in G1 curve
 22	G2T [][3][2]*big.Int // t encrypted in G2 curve
 23}
 24type Proof struct {
 25	PiA  [3]*big.Int
 26	PiAp [3]*big.Int
 27	PiB  [3][2]*big.Int
 28	PiBp [3]*big.Int
 29	PiC  [3]*big.Int
 30	PiCp [3]*big.Int
 31	PiH  [3]*big.Int
 32	Va   [3][2]*big.Int
 33	Vb   [3]*big.Int
 34	Vc   [3][2]*big.Int
 35	Vz   [3][2]*big.Int
 36}
 37
 38const bits = 512
 39
 40func GenerateTrustedSetup(bn bn128.Bn128, pollength int) (Setup, error) {
 41	var setup Setup
 42	var err error
 43	// generate random t value
 44	setup.Toxic.T, err = rand.Prime(rand.Reader, bits)
 45	if err != nil {
 46		return Setup{}, err
 47	}
 48	fmt.Print("trusted t: ")
 49	fmt.Println(setup.Toxic.T)
 50
 51	// encrypt t values with curve generators
 52	var gt1 [][3]*big.Int
 53	var gt2 [][3][2]*big.Int
 54	for i := 0; i < pollength; i++ {
 55		tPow := bn.Fq1.Exp(setup.Toxic.T, big.NewInt(int64(i)))
 56		tEncr1 := bn.G1.MulScalar(bn.G1.G, tPow)
 57		gt1 = append(gt1, tEncr1)
 58		tEncr2 := bn.G2.MulScalar(bn.G2.G, tPow)
 59		gt2 = append(gt2, tEncr2)
 60	}
 61	// gt1: g1, g1*t, g1*t^2, g1*t^3, ...
 62	// gt2: g2, g2*t, g2*t^2, ...
 63	setup.G1T = gt1
 64	setup.G2T = gt2
 65
 66	return setup, nil
 67}
 68
 69func GenerateProofs(bn bn128.Bn128, f fields.Fq, setup Setup, ax, bx, cx, hx, zx []*big.Int) (Proof, error) {
 70	var proof Proof
 71	var err error
 72
 73	// k for calculating pi' and Vk
 74	setup.Toxic.Ka, err = rand.Prime(rand.Reader, bits)
 75	if err != nil {
 76		return Proof{}, err
 77	}
 78	setup.Toxic.Kb, err = rand.Prime(rand.Reader, bits)
 79	if err != nil {
 80		return Proof{}, err
 81	}
 82	setup.Toxic.Kc, err = rand.Prime(rand.Reader, bits)
 83	if err != nil {
 84		return Proof{}, err
 85	}
 86
 87	// g1*A(t)
 88	proof.PiA = [3]*big.Int{bn.G1.F.Zero(), bn.G1.F.Zero(), bn.G1.F.Zero()}
 89	for i := 0; i < len(ax); i++ {
 90		m := bn.G1.MulScalar(setup.G1T[i], ax[i])
 91		proof.PiA = bn.G1.Add(proof.PiA, m)
 92	}
 93	proof.PiAp = bn.G1.MulScalar(proof.PiA, setup.Toxic.Ka)
 94
 95	// g2*B(t)
 96	proof.PiB = bn.Fq6.Zero()
 97	// g1*B(t)
 98	pib1 := [3]*big.Int{bn.G1.F.Zero(), bn.G1.F.Zero(), bn.G1.F.Zero()}
 99	for i := 0; i < len(bx); i++ {
100		m := bn.G2.MulScalar(setup.G2T[i], bx[i])
101		proof.PiB = bn.G2.Add(proof.PiB, m)
102		m1 := bn.G1.MulScalar(setup.G1T[i], bx[i])
103		pib1 = bn.G1.Add(pib1, m1)
104	}
105	proof.PiBp = bn.G1.MulScalar(pib1, setup.Toxic.Kb)
106
107	// g1*C(t)
108	proof.PiC = [3]*big.Int{bn.G1.F.Zero(), bn.G1.F.Zero(), bn.G1.F.Zero()}
109	for i := 0; i < len(cx); i++ {
110		m := bn.G1.MulScalar(setup.G1T[i], cx[i])
111		proof.PiC = bn.G1.Add(proof.PiC, m)
112	}
113	proof.PiCp = bn.G1.MulScalar(proof.PiC, setup.Toxic.Kc)
114
115	// g1*H(t)
116	proof.PiH = [3]*big.Int{bn.G1.F.Zero(), bn.G1.F.Zero(), bn.G1.F.Zero()}
117	for i := 0; i < len(hx); i++ {
118		m := bn.G1.MulScalar(setup.G1T[i], hx[i])
119		proof.PiH = bn.G1.Add(proof.PiH, m)
120	}
121
122	g2Zt := bn.Fq6.Zero()
123	for i := 0; i < len(bx); i++ {
124		m := bn.G2.MulScalar(setup.G2T[i], zx[i])
125		g2Zt = bn.G2.Add(g2Zt, m)
126	}
127	proof.Vz = g2Zt
128	proof.Va = bn.G2.MulScalar(bn.G2.G, setup.Toxic.Ka)
129	proof.Vb = bn.G1.MulScalar(bn.G1.G, setup.Toxic.Kb)
130	proof.Vc = bn.G2.MulScalar(bn.G2.G, setup.Toxic.Kc)
131
132	return proof, nil
133}
134
135func VerifyProof(bn bn128.Bn128, setup Setup, proof Proof) bool {
136
137	// e(piA, Va) == e(piA', g2)
138	pairingPiaVa, err := bn.Pairing(proof.PiA, proof.Va)
139	if err != nil {
140		return false
141	}
142	pairingPiapG2, err := bn.Pairing(proof.PiAp, bn.G2.G)
143	if err != nil {
144		return false
145	}
146	if !bn.Fq12.Equal(pairingPiaVa, pairingPiapG2) {
147		return false
148	}
149
150	// e(Vb, piB) == e(piB', g2)
151	pairingVbPib, err := bn.Pairing(proof.Vb, proof.PiB)
152	if err != nil {
153		return false
154	}
155	pairingPibpG2, err := bn.Pairing(proof.PiBp, bn.G2.G)
156	if err != nil {
157		return false
158	}
159	if !bn.Fq12.Equal(pairingVbPib, pairingPibpG2) {
160		return false
161	}
162
163	// e(piC, Vc) == e(piC', g2)
164	pairingPicVc, err := bn.Pairing(proof.PiC, proof.Vc)
165	if err != nil {
166		return false
167	}
168	pairingPicpG2, err := bn.Pairing(proof.PiCp, bn.G2.G)
169	if err != nil {
170		return false
171	}
172	if !bn.Fq12.Equal(pairingPicVc, pairingPicpG2) {
173		return false
174	}
175
176	// e(piA, piB) == e(piH, Vz) * e(piC, g2)
177	// pairingPiaPib, err := bn.Pairing(proof.PiA, proof.PiB)
178	// if err != nil {
179	//         return false
180	// }
181	// pairingPihVz, err := bn.Pairing(proof.PiH, proof.Vz)
182	// if err != nil {
183	//         return false
184	// }
185	// pairingPicG2, err := bn.Pairing(proof.PiC, bn.G2.G)
186	// if err != nil {
187	//         return false
188	// }
189	// if !bn.Fq12.Equal(pairingPiaPib, bn.Fq12.Mul(pairingPihVz, pairingPicG2)) {
190	//         return false
191	// }
192
193	return true
194}