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.

149 lines
4.0 KiB

  1. package prover
  2. import (
  3. "crypto/rand"
  4. "math"
  5. "math/big"
  6. bn256 "github.com/ethereum/go-ethereum/crypto/bn256/cloudflare"
  7. "github.com/iden3/go-circom-prover-verifier/types"
  8. "github.com/iden3/go-iden3-crypto/ff"
  9. "github.com/iden3/go-iden3-crypto/utils"
  10. )
  11. // Proof is the data structure of the Groth16 zkSNARK proof
  12. type Proof struct {
  13. A *bn256.G1
  14. B *bn256.G2
  15. C *bn256.G1
  16. }
  17. // Pk holds the data structure of the ProvingKey
  18. type Pk struct {
  19. A []*bn256.G1
  20. B2 []*bn256.G2
  21. B1 []*bn256.G1
  22. C []*bn256.G1
  23. NVars int
  24. NPublic int
  25. VkAlpha1 *bn256.G1
  26. VkDelta1 *bn256.G1
  27. VkBeta1 *bn256.G1
  28. VkBeta2 *bn256.G2
  29. VkDelta2 *bn256.G2
  30. HExps []*bn256.G1
  31. DomainSize int
  32. PolsA []map[int]*big.Int
  33. PolsB []map[int]*big.Int
  34. PolsC []map[int]*big.Int
  35. }
  36. // Witness contains the witness
  37. type Witness []*big.Int
  38. func randBigInt() (*big.Int, error) {
  39. maxbits := types.R.BitLen()
  40. b := make([]byte, (maxbits/8)-1)
  41. _, err := rand.Read(b)
  42. if err != nil {
  43. return nil, err
  44. }
  45. r := new(big.Int).SetBytes(b)
  46. rq := new(big.Int).Mod(r, types.R)
  47. return rq, nil
  48. }
  49. // GenerateProof generates the Groth16 zkSNARK proof
  50. func GenerateProof(pk *types.Pk, w types.Witness) (*types.Proof, []*big.Int, error) {
  51. var proof types.Proof
  52. r, err := randBigInt()
  53. if err != nil {
  54. return nil, nil, err
  55. }
  56. s, err := randBigInt()
  57. if err != nil {
  58. return nil, nil, err
  59. }
  60. proof.A = new(bn256.G1).ScalarBaseMult(big.NewInt(0))
  61. proof.B = new(bn256.G2).ScalarBaseMult(big.NewInt(0))
  62. proof.C = new(bn256.G1).ScalarBaseMult(big.NewInt(0))
  63. proofBG1 := new(bn256.G1).ScalarBaseMult(big.NewInt(0))
  64. for i := 0; i < pk.NVars; i++ {
  65. proof.A = new(bn256.G1).Add(proof.A, new(bn256.G1).ScalarMult(pk.A[i], w[i]))
  66. proof.B = new(bn256.G2).Add(proof.B, new(bn256.G2).ScalarMult(pk.B2[i], w[i]))
  67. proofBG1 = new(bn256.G1).Add(proofBG1, new(bn256.G1).ScalarMult(pk.B1[i], w[i]))
  68. }
  69. for i := pk.NPublic + 1; i < pk.NVars; i++ {
  70. proof.C = new(bn256.G1).Add(proof.C, new(bn256.G1).ScalarMult(pk.C[i], w[i]))
  71. }
  72. proof.A = new(bn256.G1).Add(proof.A, pk.VkAlpha1)
  73. proof.A = new(bn256.G1).Add(proof.A, new(bn256.G1).ScalarMult(pk.VkDelta1, r))
  74. proof.B = new(bn256.G2).Add(proof.B, pk.VkBeta2)
  75. proof.B = new(bn256.G2).Add(proof.B, new(bn256.G2).ScalarMult(pk.VkDelta2, s))
  76. proofBG1 = new(bn256.G1).Add(proofBG1, pk.VkBeta1)
  77. proofBG1 = new(bn256.G1).Add(proofBG1, new(bn256.G1).ScalarMult(pk.VkDelta1, s))
  78. h := calculateH(pk, w)
  79. for i := 0; i < len(h); i++ {
  80. proof.C = new(bn256.G1).Add(proof.C, new(bn256.G1).ScalarMult(pk.HExps[i], h[i]))
  81. }
  82. proof.C = new(bn256.G1).Add(proof.C, new(bn256.G1).ScalarMult(proof.A, s))
  83. proof.C = new(bn256.G1).Add(proof.C, new(bn256.G1).ScalarMult(proofBG1, r))
  84. rsneg := new(big.Int).Mod(new(big.Int).Neg(new(big.Int).Mul(r, s)), types.R) // fAdd & fMul
  85. proof.C = new(bn256.G1).Add(proof.C, new(bn256.G1).ScalarMult(pk.VkDelta1, rsneg))
  86. pubSignals := w[1 : pk.NPublic+1]
  87. return &proof, pubSignals, nil
  88. }
  89. func calculateH(pk *types.Pk, w types.Witness) []*big.Int {
  90. m := pk.DomainSize
  91. polAT := arrayOfZeroes(m)
  92. polBT := arrayOfZeroes(m)
  93. for i := 0; i < pk.NVars; i++ {
  94. for j := range pk.PolsA[i] {
  95. polAT[j] = fAdd(polAT[j], fMul(w[i], pk.PolsA[i][j]))
  96. }
  97. for j := range pk.PolsB[i] {
  98. polBT[j] = fAdd(polBT[j], fMul(w[i], pk.PolsB[i][j]))
  99. }
  100. }
  101. polATe := utils.BigIntArrayToElementArray(polAT)
  102. polBTe := utils.BigIntArrayToElementArray(polBT)
  103. polASe := ifft(polATe)
  104. polBSe := ifft(polBTe)
  105. r := int(math.Log2(float64(m))) + 1
  106. roots := newRootsT()
  107. roots.setRoots(r)
  108. for i := 0; i < len(polASe); i++ {
  109. polASe[i] = ff.NewElement().Mul(polASe[i], roots.roots[r][i])
  110. polBSe[i] = ff.NewElement().Mul(polBSe[i], roots.roots[r][i])
  111. }
  112. polATodd := fft(polASe)
  113. polBTodd := fft(polBSe)
  114. polABT := arrayOfZeroesE(len(polASe) * 2)
  115. for i := 0; i < len(polASe); i++ {
  116. polABT[2*i] = ff.NewElement().Mul(polATe[i], polBTe[i])
  117. polABT[2*i+1] = ff.NewElement().Mul(polATodd[i], polBTodd[i])
  118. }
  119. hSeFull := ifft(polABT)
  120. hSe := hSeFull[m:]
  121. return utils.ElementArrayToBigIntArray(hSe)
  122. }