You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

376 lines
12 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
5 years ago
6 years ago
5 years ago
6 years ago
6 years ago
5 years ago
6 years ago
5 years ago
6 years ago
5 years ago
6 years ago
  1. package snark
  2. import (
  3. "fmt"
  4. "github.com/arnaucube/go-snark/circuitcompiler"
  5. "math/big"
  6. "os"
  7. "github.com/arnaucube/go-snark/bn128"
  8. "github.com/arnaucube/go-snark/fields"
  9. "github.com/arnaucube/go-snark/r1csqap"
  10. )
  11. // Setup is the data structure holding the Trusted Setup data. The Setup.Toxic sub struct must be destroyed after the GenerateTrustedSetup function is completed
  12. type 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. Kbeta *big.Int
  19. Kgamma *big.Int
  20. RhoA *big.Int
  21. RhoB *big.Int
  22. RhoC *big.Int
  23. }
  24. // public
  25. G1T [][3]*big.Int // t encrypted in G1 curve, G1T == Pk.H
  26. G2T [][3][2]*big.Int // t encrypted in G2 curve
  27. Pk struct {
  28. // Proving Key pk:=(pkA, pkB, pkC, pkH)
  29. A [][3]*big.Int
  30. B [][3][2]*big.Int
  31. C [][3]*big.Int
  32. Kp [][3]*big.Int
  33. Ap [][3]*big.Int
  34. Bp [][3]*big.Int
  35. Cp [][3]*big.Int
  36. Z []*big.Int
  37. }
  38. Vk struct {
  39. Vka [3][2]*big.Int
  40. Vkb [3]*big.Int
  41. Vkc [3][2]*big.Int
  42. IC [][3]*big.Int
  43. G1Kbg [3]*big.Int // g1 * Kbeta * Kgamma
  44. G2Kbg [3][2]*big.Int // g2 * Kbeta * Kgamma
  45. G2Kg [3][2]*big.Int // g2 * Kgamma
  46. Vkz [3][2]*big.Int
  47. }
  48. }
  49. // Proof contains the parameters to proof the zkSNARK
  50. type Proof struct {
  51. PiA [3]*big.Int
  52. PiAp [3]*big.Int
  53. PiB [3][2]*big.Int
  54. PiBp [3]*big.Int
  55. PiC [3]*big.Int
  56. PiCp [3]*big.Int
  57. PiH [3]*big.Int
  58. PiKp [3]*big.Int
  59. // PublicSignals []*big.Int
  60. }
  61. type utils struct {
  62. Bn bn128.Bn128
  63. FqR fields.Fq
  64. PF r1csqap.PolynomialField
  65. }
  66. // Utils is the data structure holding the BN128, FqR Finite Field over R, PolynomialField, that will be used inside the snarks operations
  67. var Utils = prepareUtils()
  68. func prepareUtils() utils {
  69. bn, err := bn128.NewBn128()
  70. if err != nil {
  71. panic(err)
  72. }
  73. // new Finite Field
  74. fqR := fields.NewFq(bn.R)
  75. // new Polynomial Field
  76. pf := r1csqap.NewPolynomialField(fqR)
  77. return utils{
  78. Bn: bn,
  79. FqR: fqR,
  80. PF: pf,
  81. }
  82. }
  83. // GenerateTrustedSetup generates the Trusted Setup from a compiled Circuit. The Setup.Toxic sub data structure must be destroyed
  84. func GenerateTrustedSetup(witnessLength int, alphas, betas, gammas [][]*big.Int) (Setup, error) {
  85. var setup Setup
  86. var err error
  87. // input soundness
  88. // for i := 0; i < len(alphas); i++ {
  89. // for j := 0; j < len(alphas[i]); j++ {
  90. // if j <= circuit.NPublic {
  91. // if bytes.Equal(alphas[i][j].Bytes(), Utils.FqR.Zero().Bytes()) {
  92. // alphas[i][j] = Utils.FqR.One()
  93. // }
  94. // }
  95. // }
  96. // }
  97. // generate random t value
  98. setup.Toxic.T, err = Utils.FqR.Rand()
  99. if err != nil {
  100. return Setup{}, err
  101. }
  102. // k for calculating pi' and Vk
  103. setup.Toxic.Ka, err = Utils.FqR.Rand()
  104. if err != nil {
  105. return Setup{}, err
  106. }
  107. setup.Toxic.Kb, err = Utils.FqR.Rand()
  108. if err != nil {
  109. return Setup{}, err
  110. }
  111. setup.Toxic.Kc, err = Utils.FqR.Rand()
  112. if err != nil {
  113. return Setup{}, err
  114. }
  115. // generate Kβ (Kbeta) and Kγ (Kgamma)
  116. setup.Toxic.Kbeta, err = Utils.FqR.Rand()
  117. if err != nil {
  118. return Setup{}, err
  119. }
  120. setup.Toxic.Kgamma, err = Utils.FqR.Rand()
  121. if err != nil {
  122. return Setup{}, err
  123. }
  124. // generate ρ (Rho): ρA, ρB, ρC
  125. setup.Toxic.RhoA, err = Utils.FqR.Rand()
  126. if err != nil {
  127. return Setup{}, err
  128. }
  129. setup.Toxic.RhoB, err = Utils.FqR.Rand()
  130. if err != nil {
  131. return Setup{}, err
  132. }
  133. setup.Toxic.RhoC = Utils.FqR.Mul(setup.Toxic.RhoA, setup.Toxic.RhoB)
  134. // calculated more down
  135. // for i := 0; i < witnessLength; i++ {
  136. // tPow := Utils.FqR.Exp(setup.Toxic.T, big.NewInt(int64(i)))
  137. // tEncr1 := Utils.Bn.G1.MulScalar(Utils.Bn.G1.G, tPow)
  138. // gt1 = append(gt1, tEncr1)
  139. // tEncr2 := Utils.Bn.G2.MulScalar(Utils.Bn.G2.G, tPow)
  140. // gt2 = append(gt2, tEncr2)
  141. // }
  142. // gt1: g1, g1*t, g1*t^2, g1*t^3, ...
  143. // gt2: g2, g2*t, g2*t^2, ...
  144. setup.Vk.Vka = Utils.Bn.G2.MulScalar(Utils.Bn.G2.G, setup.Toxic.Ka)
  145. setup.Vk.Vkb = Utils.Bn.G1.MulScalar(Utils.Bn.G1.G, setup.Toxic.Kb)
  146. setup.Vk.Vkc = Utils.Bn.G2.MulScalar(Utils.Bn.G2.G, setup.Toxic.Kc)
  147. /*
  148. Verification keys:
  149. - Vk_betagamma1: setup.G1Kbg = g1 * Kbeta*Kgamma
  150. - Vk_betagamma2: setup.G2Kbg = g2 * Kbeta*Kgamma
  151. - Vk_gamma: setup.G2Kg = g2 * Kgamma
  152. */
  153. kbg := Utils.FqR.Mul(setup.Toxic.Kbeta, setup.Toxic.Kgamma)
  154. setup.Vk.G1Kbg = Utils.Bn.G1.MulScalar(Utils.Bn.G1.G, kbg)
  155. setup.Vk.G2Kbg = Utils.Bn.G2.MulScalar(Utils.Bn.G2.G, kbg)
  156. setup.Vk.G2Kg = Utils.Bn.G2.MulScalar(Utils.Bn.G2.G, setup.Toxic.Kgamma)
  157. // for i := 0; i < circuit.NVars; i++ {
  158. for i := 0; i < witnessLength; i++ {
  159. at := Utils.PF.Eval(alphas[i], setup.Toxic.T)
  160. // rhoAat := Utils.Bn.Fq1.Mul(setup.Toxic.RhoA, at)
  161. rhoAat := Utils.FqR.Mul(setup.Toxic.RhoA, at)
  162. a := Utils.Bn.G1.MulScalar(Utils.Bn.G1.G, rhoAat)
  163. setup.Pk.A = append(setup.Pk.A, a)
  164. if i <= 4 {
  165. setup.Vk.IC = append(setup.Vk.IC, a)
  166. }
  167. bt := Utils.PF.Eval(betas[i], setup.Toxic.T)
  168. // rhoBbt := Utils.Bn.Fq1.Mul(setup.Toxic.RhoB, bt)
  169. rhoBbt := Utils.FqR.Mul(setup.Toxic.RhoB, bt)
  170. bg1 := Utils.Bn.G1.MulScalar(Utils.Bn.G1.G, rhoBbt)
  171. bg2 := Utils.Bn.G2.MulScalar(Utils.Bn.G2.G, rhoBbt)
  172. setup.Pk.B = append(setup.Pk.B, bg2)
  173. ct := Utils.PF.Eval(gammas[i], setup.Toxic.T)
  174. // rhoCct := Utils.Bn.Fq1.Mul(setup.Toxic.RhoC, ct)
  175. rhoCct := Utils.FqR.Mul(setup.Toxic.RhoC, ct)
  176. c := Utils.Bn.G1.MulScalar(Utils.Bn.G1.G, rhoCct)
  177. setup.Pk.C = append(setup.Pk.C, c)
  178. kt := Utils.FqR.Add(Utils.FqR.Add(rhoAat, rhoBbt), rhoCct)
  179. k := Utils.Bn.G1.Affine(Utils.Bn.G1.MulScalar(Utils.Bn.G1.G, kt))
  180. ktest := Utils.Bn.G1.Affine(Utils.Bn.G1.Add(Utils.Bn.G1.Add(a, bg1), c))
  181. if !Utils.Bn.Fq2.Equal(k, ktest) {
  182. os.Exit(1)
  183. return setup, err
  184. }
  185. setup.Pk.Ap = append(setup.Pk.Ap, Utils.Bn.G1.MulScalar(a, setup.Toxic.Ka))
  186. setup.Pk.Bp = append(setup.Pk.Bp, Utils.Bn.G1.MulScalar(bg1, setup.Toxic.Kb))
  187. setup.Pk.Cp = append(setup.Pk.Cp, Utils.Bn.G1.MulScalar(c, setup.Toxic.Kc))
  188. k_ := Utils.Bn.G1.MulScalar(Utils.Bn.G1.G, kt)
  189. setup.Pk.Kp = append(setup.Pk.Kp, Utils.Bn.G1.MulScalar(k_, setup.Toxic.Kbeta))
  190. }
  191. // z pol
  192. zpol := []*big.Int{big.NewInt(int64(1))}
  193. // for i := 0; i < len(circuit.Constraints); i++ {
  194. for i := 1; i < len(alphas)-1; i++ {
  195. zpol = Utils.PF.Mul(
  196. zpol,
  197. []*big.Int{
  198. Utils.FqR.Neg( // neg over R
  199. big.NewInt(int64(i))),
  200. big.NewInt(int64(1)),
  201. })
  202. }
  203. setup.Pk.Z = zpol
  204. zt := Utils.PF.Eval(zpol, setup.Toxic.T)
  205. // rhoCzt := Utils.Bn.Fq1.Mul(setup.Toxic.RhoC, zt)
  206. rhoCzt := Utils.FqR.Mul(setup.Toxic.RhoC, zt)
  207. setup.Vk.Vkz = Utils.Bn.G2.MulScalar(Utils.Bn.G2.G, rhoCzt)
  208. // encrypt t values with curve generators
  209. var gt1 [][3]*big.Int
  210. gt1 = append(gt1, Utils.Bn.G1.G) // the first is t**0 * G1 = 1 * G1 = G1
  211. tEncr := setup.Toxic.T
  212. for i := 1; i < len(zpol); i++ { //should be G1T = pkH = (tau**i * G1) from i=0 to d, where d is degree of pol Z(x)
  213. gt1 = append(gt1, Utils.Bn.G1.MulScalar(Utils.Bn.G1.G, tEncr))
  214. // tEncr = Utils.Bn.Fq1.Mul(tEncr, setup.Toxic.T)
  215. tEncr = Utils.FqR.Mul(tEncr, setup.Toxic.T)
  216. }
  217. setup.G1T = gt1
  218. return setup, nil
  219. }
  220. // GenerateProofs generates all the parameters to proof the zkSNARK from the Circuit, Setup and the Witness
  221. func GenerateProofs(setup Setup, nInputs int, w []*big.Int, px []*big.Int) (Proof, error) {
  222. var proof Proof
  223. proof.PiA = [3]*big.Int{Utils.Bn.G1.F.Zero(), Utils.Bn.G1.F.Zero(), Utils.Bn.G1.F.Zero()}
  224. proof.PiAp = [3]*big.Int{Utils.Bn.G1.F.Zero(), Utils.Bn.G1.F.Zero(), Utils.Bn.G1.F.Zero()}
  225. proof.PiB = Utils.Bn.Fq6.Zero()
  226. proof.PiBp = [3]*big.Int{Utils.Bn.G1.F.Zero(), Utils.Bn.G1.F.Zero(), Utils.Bn.G1.F.Zero()}
  227. proof.PiC = [3]*big.Int{Utils.Bn.G1.F.Zero(), Utils.Bn.G1.F.Zero(), Utils.Bn.G1.F.Zero()}
  228. proof.PiCp = [3]*big.Int{Utils.Bn.G1.F.Zero(), Utils.Bn.G1.F.Zero(), Utils.Bn.G1.F.Zero()}
  229. proof.PiH = [3]*big.Int{Utils.Bn.G1.F.Zero(), Utils.Bn.G1.F.Zero(), Utils.Bn.G1.F.Zero()}
  230. proof.PiKp = [3]*big.Int{Utils.Bn.G1.F.Zero(), Utils.Bn.G1.F.Zero(), Utils.Bn.G1.F.Zero()}
  231. for i := nInputs; i < len(w)-1; i++ {
  232. proof.PiA = Utils.Bn.G1.Add(proof.PiA, Utils.Bn.G1.MulScalar(setup.Pk.A[i], w[i]))
  233. proof.PiAp = Utils.Bn.G1.Add(proof.PiAp, Utils.Bn.G1.MulScalar(setup.Pk.Ap[i], w[i]))
  234. }
  235. for i := 0; i < len(w); i++ {
  236. proof.PiB = Utils.Bn.G2.Add(proof.PiB, Utils.Bn.G2.MulScalar(setup.Pk.B[i], w[i]))
  237. proof.PiBp = Utils.Bn.G1.Add(proof.PiBp, Utils.Bn.G1.MulScalar(setup.Pk.Bp[i], w[i]))
  238. proof.PiC = Utils.Bn.G1.Add(proof.PiC, Utils.Bn.G1.MulScalar(setup.Pk.C[i], w[i]))
  239. proof.PiCp = Utils.Bn.G1.Add(proof.PiCp, Utils.Bn.G1.MulScalar(setup.Pk.Cp[i], w[i]))
  240. proof.PiKp = Utils.Bn.G1.Add(proof.PiKp, Utils.Bn.G1.MulScalar(setup.Pk.Kp[i], w[i]))
  241. }
  242. hx := Utils.PF.DivisorPolynomial(px, setup.Pk.Z) // maybe move this calculation to a previous step
  243. // piH = pkH,0 + sum ( hi * pk H,i ), where pkH = G1T, hi=hx
  244. // proof.PiH = Utils.Bn.G1.Add(proof.PiH, setup.G1T[0])
  245. for i := 0; i < len(hx); i++ {
  246. proof.PiH = Utils.Bn.G1.Add(proof.PiH, Utils.Bn.G1.MulScalar(setup.G1T[i], hx[i]))
  247. }
  248. return proof, nil
  249. }
  250. // VerifyProof verifies over the BN128 the Pairings of the Proof
  251. func VerifyProof(setup Setup, proof Proof, publicSignals []*big.Int, debug bool) bool {
  252. // e(piA, Va) == e(piA', g2)
  253. pairingPiaVa := Utils.Bn.Pairing(proof.PiA, setup.Vk.Vka)
  254. pairingPiapG2 := Utils.Bn.Pairing(proof.PiAp, Utils.Bn.G2.G)
  255. if !Utils.Bn.Fq12.Equal(pairingPiaVa, pairingPiapG2) {
  256. fmt.Println("❌ e(piA, Va) == e(piA', g2), valid knowledge commitment for A")
  257. return false
  258. }
  259. if debug {
  260. fmt.Println("✓ e(piA, Va) == e(piA', g2), valid knowledge commitment for A")
  261. }
  262. // e(Vb, piB) == e(piB', g2)
  263. pairingVbPib := Utils.Bn.Pairing(setup.Vk.Vkb, proof.PiB)
  264. pairingPibpG2 := Utils.Bn.Pairing(proof.PiBp, Utils.Bn.G2.G)
  265. if !Utils.Bn.Fq12.Equal(pairingVbPib, pairingPibpG2) {
  266. fmt.Println("❌ e(Vb, piB) == e(piB', g2), valid knowledge commitment for B")
  267. return false
  268. }
  269. if debug {
  270. fmt.Println("✓ e(Vb, piB) == e(piB', g2), valid knowledge commitment for B")
  271. }
  272. // e(piC, Vc) == e(piC', g2)
  273. pairingPicVc := Utils.Bn.Pairing(proof.PiC, setup.Vk.Vkc)
  274. pairingPicpG2 := Utils.Bn.Pairing(proof.PiCp, Utils.Bn.G2.G)
  275. if !Utils.Bn.Fq12.Equal(pairingPicVc, pairingPicpG2) {
  276. fmt.Println("❌ e(piC, Vc) == e(piC', g2), valid knowledge commitment for C")
  277. return false
  278. }
  279. if debug {
  280. fmt.Println("✓ e(piC, Vc) == e(piC', g2), valid knowledge commitment for C")
  281. }
  282. // Vkx, to then calculate Vkx+piA
  283. vkxpia := setup.Vk.IC[0]
  284. for i := 0; i < len(publicSignals); i++ {
  285. vkxpia = Utils.Bn.G1.Add(vkxpia, Utils.Bn.G1.MulScalar(setup.Vk.IC[i+1], publicSignals[i]))
  286. }
  287. // e(Vkx+piA, piB) == e(piH, Vkz) * e(piC, g2)
  288. if !Utils.Bn.Fq12.Equal(
  289. Utils.Bn.Pairing(Utils.Bn.G1.Add(vkxpia, proof.PiA), proof.PiB), // TODO Add(vkxpia, proof.PiA) can go outside in order to save computation, as is reused later
  290. Utils.Bn.Fq12.Mul(
  291. Utils.Bn.Pairing(proof.PiH, setup.Vk.Vkz),
  292. Utils.Bn.Pairing(proof.PiC, Utils.Bn.G2.G))) {
  293. fmt.Println("❌ e(Vkx+piA, piB) == e(piH, Vkz) * e(piC, g2), QAP disibility checked")
  294. return false
  295. }
  296. if debug {
  297. fmt.Println("✓ e(Vkx+piA, piB) == e(piH, Vkz) * e(piC, g2), QAP disibility checked")
  298. }
  299. // e(Vkx+piA+piC, g2KbetaKgamma) * e(g1KbetaKgamma, piB)
  300. // == e(piK, g2Kgamma)
  301. piApiC := Utils.Bn.G1.Add(Utils.Bn.G1.Add(vkxpia, proof.PiA), proof.PiC)
  302. pairingPiACG2Kbg := Utils.Bn.Pairing(piApiC, setup.Vk.G2Kbg)
  303. pairingG1KbgPiB := Utils.Bn.Pairing(setup.Vk.G1Kbg, proof.PiB)
  304. pairingL := Utils.Bn.Fq12.Mul(pairingPiACG2Kbg, pairingG1KbgPiB)
  305. pairingR := Utils.Bn.Pairing(proof.PiKp, setup.Vk.G2Kg)
  306. if !Utils.Bn.Fq12.Equal(pairingL, pairingR) {
  307. fmt.Println("❌ e(Vkx+piA+piC, g2KbetaKgamma) * e(g1KbetaKgamma, piB) == e(piK, g2Kgamma)")
  308. return false
  309. }
  310. if debug {
  311. fmt.Println("✓ e(Vkx+piA+piC, g2KbetaKgamma) * e(g1KbetaKgamma, piB) == e(piK, g2Kgamma)")
  312. }
  313. return true
  314. }
  315. //TODO this is just a workaround to place the output after the input signals. Will be removed once the handling of private variables is already considered in the lexer
  316. func RelocateOutput(numberOfInputs int, r1cs circuitcompiler.R1CS, witness []*big.Int) (r circuitcompiler.R1CS, w []*big.Int) {
  317. tmpA, tmpB, tmpC := [][]*big.Int{}, [][]*big.Int{}, [][]*big.Int{}
  318. tmpA = append(tmpA, r1cs.A[len(r1cs.A)-1])
  319. tmpA = append(tmpA, r1cs.A[:len(r1cs.A)-1]...)
  320. tmpB = append(tmpB, r1cs.B[len(r1cs.B)-1])
  321. tmpB = append(tmpB, r1cs.B[:len(r1cs.B)-1]...)
  322. tmpC = append(tmpC, r1cs.C[len(r1cs.C)-1])
  323. tmpC = append(tmpC, r1cs.C[:len(r1cs.C)-1]...)
  324. wtmp := append(witness[:numberOfInputs], witness[len(witness)-1])
  325. wtmp = append(wtmp, witness[numberOfInputs:len(witness)-2]...)
  326. return circuitcompiler.R1CS{A: tmpA, B: tmpB, C: tmpC}, wtmp
  327. }