arnaucube
arnaucube/go-snarkPublic Self-hosted repository
go-snark/snark.go
snark.goRaw
  1package snark
  2
  3import (
  4	"crypto/rand"
  5	"math/big"
  6
  7	"github.com/arnaucube/go-snark/bn128"
  8	"github.com/arnaucube/go-snark/fields"
  9)
 10
 11type Setup struct {
 12	Toxic struct {
 13		T      *big.Int // trusted setup secret
 14		Ka     *big.Int // prover
 15		Kb     *big.Int // prover
 16		Kc     *big.Int // prover
 17		Kbeta  *big.Int
 18		Kgamma *big.Int
 19		RhoA   *big.Int
 20		RhoB   *big.Int
 21		RhoC   *big.Int
 22	}
 23
 24	// public
 25	G1T   [][3]*big.Int    // t encrypted in G1 curve
 26	G2T   [][3][2]*big.Int // t encrypted in G2 curve
 27	G1Kbg [3]*big.Int      // g1 * Kbeta * Kgamma
 28	G2Kbg [3][2]*big.Int   // g2 * Kbeta * Kgamma
 29	G2Kg  [3][2]*big.Int   // g2 * Kgamma
 30}
 31
 32type Proof struct {
 33	PiA  [3]*big.Int
 34	PiAp [3]*big.Int
 35	PiB  [3][2]*big.Int
 36	PiBp [3]*big.Int
 37	PiC  [3]*big.Int
 38	PiCp [3]*big.Int
 39	PiH  [3]*big.Int
 40	PiK  [3]*big.Int
 41	Va   [3][2]*big.Int
 42	Vb   [3]*big.Int
 43	Vc   [3][2]*big.Int
 44	Vz   [3][2]*big.Int
 45}
 46
 47const bits = 512
 48
 49func GenerateTrustedSetup(bn bn128.Bn128, polLength int) (Setup, error) {
 50	var setup Setup
 51	var err error
 52	// generate random t value
 53	setup.Toxic.T, err = rand.Prime(rand.Reader, bits)
 54	if err != nil {
 55		return Setup{}, err
 56	}
 57
 58	// k for calculating pi' and Vk
 59	setup.Toxic.Ka, err = rand.Prime(rand.Reader, bits)
 60	if err != nil {
 61		return Setup{}, err
 62	}
 63	setup.Toxic.Kb, err = rand.Prime(rand.Reader, bits)
 64	if err != nil {
 65		return Setup{}, err
 66	}
 67	setup.Toxic.Kc, err = rand.Prime(rand.Reader, bits)
 68	if err != nil {
 69		return Setup{}, err
 70	}
 71
 72	// generate Kβ (Kbeta) and Kγ (Kgamma)
 73	setup.Toxic.Kbeta, err = rand.Prime(rand.Reader, bits)
 74	if err != nil {
 75		return Setup{}, err
 76	}
 77	setup.Toxic.Kgamma, err = rand.Prime(rand.Reader, bits)
 78	if err != nil {
 79		return Setup{}, err
 80	}
 81
 82	// generate ρ (Rho): ρA, ρB, ρC
 83	setup.Toxic.RhoA, err = rand.Prime(rand.Reader, bits)
 84	if err != nil {
 85		return Setup{}, err
 86	}
 87	setup.Toxic.RhoB, err = rand.Prime(rand.Reader, bits)
 88	if err != nil {
 89		return Setup{}, err
 90	}
 91	setup.Toxic.RhoC = bn.Fq1.Mul(setup.Toxic.RhoA, setup.Toxic.RhoB)
 92
 93	// encrypt t values with curve generators
 94	var gt1 [][3]*big.Int
 95	var gt2 [][3][2]*big.Int
 96	for i := 0; i < polLength; i++ {
 97		tPow := bn.Fq1.Exp(setup.Toxic.T, big.NewInt(int64(i)))
 98		tEncr1 := bn.G1.MulScalar(bn.G1.G, tPow)
 99		gt1 = append(gt1, tEncr1)
100		tEncr2 := bn.G2.MulScalar(bn.G2.G, tPow)
101		gt2 = append(gt2, tEncr2)
102	}
103	// gt1: g1, g1*t, g1*t^2, g1*t^3, ...
104	// gt2: g2, g2*t, g2*t^2, ...
105	setup.G1T = gt1
106	setup.G2T = gt2
107
108	/*
109		Verification keys:
110		- Vk_betagamma1: setup.G1Kbg = g1 * Kbeta*Kgamma
111		- Vk_betagamma2: setup.G2Kbg = g2 * Kbeta*Kgamma
112		- Vk_gamma: setup.G2Kg = g2 * Kgamma
113	*/
114	kbg := bn.Fq1.Mul(setup.Toxic.Kbeta, setup.Toxic.Kgamma)
115	setup.G1Kbg = bn.G1.MulScalar(bn.G1.G, kbg)
116	setup.G2Kbg = bn.G2.MulScalar(bn.G2.G, kbg)
117	setup.G2Kg = bn.G2.MulScalar(bn.G2.G, setup.Toxic.Kgamma)
118
119	return setup, nil
120}
121
122func GenerateProofs(bn bn128.Bn128, f fields.Fq, setup Setup, w, ax, bx, cx, hx, zx []*big.Int) (Proof, error) {
123	var proof Proof
124
125	// g1*A(t)
126	proof.PiA = [3]*big.Int{bn.G1.F.Zero(), bn.G1.F.Zero(), bn.G1.F.Zero()}
127	for i := 0; i < len(ax); i++ {
128		m := bn.G1.MulScalar(setup.G1T[i], ax[i])
129		proof.PiA = bn.G1.Add(proof.PiA, m)
130	}
131	proof.PiAp = bn.G1.MulScalar(proof.PiA, setup.Toxic.Ka) // move this in the setup step
132
133	// g2*B(t)
134	proof.PiB = bn.Fq6.Zero()
135	// g1*B(t)
136	pib1 := [3]*big.Int{bn.G1.F.Zero(), bn.G1.F.Zero(), bn.G1.F.Zero()}
137	for i := 0; i < len(bx); i++ {
138		m := bn.G2.MulScalar(setup.G2T[i], bx[i])
139		proof.PiB = bn.G2.Add(proof.PiB, m)
140		m1 := bn.G1.MulScalar(setup.G1T[i], bx[i])
141		pib1 = bn.G1.Add(pib1, m1)
142	}
143	proof.PiBp = bn.G1.MulScalar(pib1, setup.Toxic.Kb) // this in the setup step
144
145	// g1*C(t)
146	proof.PiC = [3]*big.Int{bn.G1.F.Zero(), bn.G1.F.Zero(), bn.G1.F.Zero()}
147	for i := 0; i < len(cx); i++ {
148		m := bn.G1.MulScalar(setup.G1T[i], cx[i])
149		proof.PiC = bn.G1.Add(proof.PiC, m)
150	}
151	proof.PiCp = bn.G1.MulScalar(proof.PiC, setup.Toxic.Kc) // this in the setup step
152
153	// g1*H(t)
154	proof.PiH = [3]*big.Int{bn.G1.F.Zero(), bn.G1.F.Zero(), bn.G1.F.Zero()}
155	for i := 0; i < len(hx); i++ {
156		m := bn.G1.MulScalar(setup.G1T[i], hx[i])
157		proof.PiH = bn.G1.Add(proof.PiH, m)
158	}
159
160	proof.Vz = bn.Fq6.Zero()
161	for i := 0; i < len(bx); i++ {
162		m := bn.G2.MulScalar(setup.G2T[i], zx[i])
163		proof.Vz = bn.G2.Add(proof.Vz, m)
164	}
165	// proof.Vz = g2Zt
166	proof.Va = bn.G2.MulScalar(bn.G2.G, setup.Toxic.Ka) // this in the setup step
167
168	proof.Vb = bn.G1.MulScalar(bn.G1.G, setup.Toxic.Kb) // this in the setup step
169
170	proof.Vc = bn.G2.MulScalar(bn.G2.G, setup.Toxic.Kc) // this in the setup step
171
172	return proof, nil
173}
174
175func VerifyProof(bn bn128.Bn128, setup Setup, proof Proof) bool {
176
177	// e(piA, Va) == e(piA', g2)
178	pairingPiaVa, err := bn.Pairing(proof.PiA, proof.Va)
179	if err != nil {
180		return false
181	}
182	pairingPiapG2, err := bn.Pairing(proof.PiAp, bn.G2.G)
183	if err != nil {
184		return false
185	}
186	if !bn.Fq12.Equal(pairingPiaVa, pairingPiapG2) {
187		return false
188	}
189
190	// e(Vb, piB) == e(piB', g2)
191	pairingVbPib, err := bn.Pairing(proof.Vb, proof.PiB)
192	if err != nil {
193		return false
194	}
195	pairingPibpG2, err := bn.Pairing(proof.PiBp, bn.G2.G)
196	if err != nil {
197		return false
198	}
199	if !bn.Fq12.Equal(pairingVbPib, pairingPibpG2) {
200		return false
201	}
202
203	// e(piC, Vc) == e(piC', g2)
204	pairingPicVc, err := bn.Pairing(proof.PiC, proof.Vc)
205	if err != nil {
206		return false
207	}
208	pairingPicpG2, err := bn.Pairing(proof.PiCp, bn.G2.G)
209	if err != nil {
210		return false
211	}
212	if !bn.Fq12.Equal(pairingPicVc, pairingPicpG2) {
213		return false
214	}
215
216	// e(piA+piC, g2KbetaKgamma) * e(g1KbetaKgamma, piB)
217	// == e(piK, g2Kgamma)
218	// piApiC := bn.G1.Add(proof.PiA, proof.PiC)
219	// pairingPiACG2Kbg, err := bn.Pairing(piApiC, setup.G2Kbg)
220	// if err != nil {
221	//         return false
222	// }
223	// pairingG1KbgPiB, err := bn.Pairing(setup.G1Kbg, proof.PiB)
224	// if err != nil {
225	//         return false
226	// }
227	// pairing1 := bn.Fq12.Mul(pairingPiACG2Kbg, pairingG1KbgPiB)
228
229	//
230
231	// e(piA, piB) == e(piH, Vz) * e(piC, g2)
232	// pairingPiaPib, err := bn.Pairing(proof.PiA, proof.PiB)
233	// if err != nil {
234	// 	return false
235	// }
236	// pairingPihVz, err := bn.Pairing(proof.PiH, proof.Vz)
237	// if err != nil {
238	// 	return false
239	// }
240	// pairingPicG2, err := bn.Pairing(proof.PiC, bn.G2.G)
241	// if err != nil {
242	// 	return false
243	// }
244	// if !bn.Fq12.Equal(pairingPiaPib, bn.Fq12.Mul(pairingPihVz, pairingPicG2)) {
245	// 	return false
246	// }
247
248	return true
249}