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.

219 lines
5.0 KiB

  1. package prover
  2. import (
  3. "crypto/rand"
  4. "math"
  5. "math/big"
  6. "runtime"
  7. "sync"
  8. bn256 "github.com/ethereum/go-ethereum/crypto/bn256/cloudflare"
  9. "github.com/iden3/go-circom-prover-verifier/types"
  10. "github.com/iden3/go-iden3-crypto/utils"
  11. //"fmt"
  12. )
  13. // Group Size
  14. const (
  15. GSIZE = 6
  16. )
  17. func randBigInt() (*big.Int, error) {
  18. maxbits := types.R.BitLen()
  19. b := make([]byte, (maxbits/8)-1)
  20. _, err := rand.Read(b)
  21. if err != nil {
  22. return nil, err
  23. }
  24. r := new(big.Int).SetBytes(b)
  25. rq := new(big.Int).Mod(r, types.R)
  26. return rq, nil
  27. }
  28. // GenerateProof generates the Groth16 zkSNARK proof
  29. func GenerateProof(pk *types.Pk, w types.Witness) (*types.Proof, []*big.Int, error) {
  30. var proof types.Proof
  31. r, err := randBigInt()
  32. if err != nil {
  33. return nil, nil, err
  34. }
  35. s, err := randBigInt()
  36. if err != nil {
  37. return nil, nil, err
  38. }
  39. // BEGIN PAR
  40. numcpu := runtime.NumCPU()
  41. proofA := arrayOfZeroesG1(numcpu)
  42. proofB := arrayOfZeroesG2(numcpu)
  43. proofC := arrayOfZeroesG1(numcpu)
  44. proofBG1 := arrayOfZeroesG1(numcpu)
  45. gsize := GSIZE
  46. var wg1 sync.WaitGroup
  47. wg1.Add(numcpu)
  48. for _cpu, _ranges := range ranges(pk.NVars, numcpu) {
  49. // split 1
  50. go func(cpu int, ranges [2]int) {
  51. proofA[cpu] = scalarMultNoDoubleG1(pk.A[ranges[0]:ranges[1]],
  52. w[ranges[0]:ranges[1]],
  53. proofA[cpu],
  54. gsize)
  55. proofB[cpu] = scalarMultNoDoubleG2(pk.B2[ranges[0]:ranges[1]],
  56. w[ranges[0]:ranges[1]],
  57. proofB[cpu],
  58. gsize)
  59. proofBG1[cpu] = scalarMultNoDoubleG1(pk.B1[ranges[0]:ranges[1]],
  60. w[ranges[0]:ranges[1]],
  61. proofBG1[cpu],
  62. gsize)
  63. minLim := pk.NPublic + 1
  64. if ranges[0] > pk.NPublic+1 {
  65. minLim = ranges[0]
  66. }
  67. if ranges[1] > pk.NPublic+1 {
  68. proofC[cpu] = scalarMultNoDoubleG1(pk.C[minLim:ranges[1]],
  69. w[minLim:ranges[1]],
  70. proofC[cpu],
  71. gsize)
  72. }
  73. wg1.Done()
  74. }(_cpu, _ranges)
  75. }
  76. wg1.Wait()
  77. // join 1
  78. for cpu := 1; cpu < numcpu; cpu++ {
  79. proofA[0].Add(proofA[0], proofA[cpu])
  80. proofB[0].Add(proofB[0], proofB[cpu])
  81. proofC[0].Add(proofC[0], proofC[cpu])
  82. proofBG1[0].Add(proofBG1[0], proofBG1[cpu])
  83. }
  84. proof.A = proofA[0]
  85. proof.B = proofB[0]
  86. proof.C = proofC[0]
  87. // END PAR
  88. h := calculateH(pk, w)
  89. proof.A.Add(proof.A, pk.VkAlpha1)
  90. proof.A.Add(proof.A, new(bn256.G1).ScalarMult(pk.VkDelta1, r))
  91. proof.B.Add(proof.B, pk.VkBeta2)
  92. proof.B.Add(proof.B, new(bn256.G2).ScalarMult(pk.VkDelta2, s))
  93. proofBG1[0].Add(proofBG1[0], pk.VkBeta1)
  94. proofBG1[0].Add(proofBG1[0], new(bn256.G1).ScalarMult(pk.VkDelta1, s))
  95. proofC = arrayOfZeroesG1(numcpu)
  96. var wg2 sync.WaitGroup
  97. wg2.Add(numcpu)
  98. for _cpu, _ranges := range ranges(len(h), numcpu) {
  99. // split 2
  100. go func(cpu int, ranges [2]int) {
  101. proofC[cpu] = scalarMultNoDoubleG1(pk.HExps[ranges[0]:ranges[1]],
  102. h[ranges[0]:ranges[1]],
  103. proofC[cpu],
  104. gsize)
  105. wg2.Done()
  106. }(_cpu, _ranges)
  107. }
  108. wg2.Wait()
  109. // join 2
  110. for cpu := 1; cpu < numcpu; cpu++ {
  111. proofC[0].Add(proofC[0], proofC[cpu])
  112. }
  113. proof.C.Add(proof.C, proofC[0])
  114. proof.C.Add(proof.C, new(bn256.G1).ScalarMult(proof.A, s))
  115. proof.C.Add(proof.C, new(bn256.G1).ScalarMult(proofBG1[0], r))
  116. rsneg := new(big.Int).Mod(new(big.Int).Neg(new(big.Int).Mul(r, s)), types.R)
  117. proof.C.Add(proof.C, new(bn256.G1).ScalarMult(pk.VkDelta1, rsneg))
  118. pubSignals := w[1 : pk.NPublic+1]
  119. return &proof, pubSignals, nil
  120. }
  121. func calculateH(pk *types.Pk, w types.Witness) []*big.Int {
  122. m := pk.DomainSize
  123. polAT := arrayOfZeroes(m)
  124. polBT := arrayOfZeroes(m)
  125. numcpu := runtime.NumCPU()
  126. var wg1 sync.WaitGroup
  127. wg1.Add(2)
  128. go func() {
  129. for i := 0; i < pk.NVars; i++ {
  130. for j := range pk.PolsA[i] {
  131. polAT[j] = fAdd(polAT[j], fMul(w[i], pk.PolsA[i][j]))
  132. }
  133. }
  134. wg1.Done()
  135. }()
  136. go func() {
  137. for i := 0; i < pk.NVars; i++ {
  138. for j := range pk.PolsB[i] {
  139. polBT[j] = fAdd(polBT[j], fMul(w[i], pk.PolsB[i][j]))
  140. }
  141. }
  142. wg1.Done()
  143. }()
  144. wg1.Wait()
  145. polATe := utils.BigIntArrayToElementArray(polAT)
  146. polBTe := utils.BigIntArrayToElementArray(polBT)
  147. polASe := ifft(polATe)
  148. polBSe := ifft(polBTe)
  149. r := int(math.Log2(float64(m))) + 1
  150. roots := newRootsT()
  151. roots.setRoots(r)
  152. var wg2 sync.WaitGroup
  153. wg2.Add(numcpu)
  154. for _cpu, _ranges := range ranges(len(polASe), numcpu) {
  155. go func(cpu int, ranges [2]int) {
  156. for i := ranges[0]; i < ranges[1]; i++ {
  157. polASe[i].Mul(polASe[i], roots.roots[r][i])
  158. polBSe[i].Mul(polBSe[i], roots.roots[r][i])
  159. }
  160. wg2.Done()
  161. }(_cpu, _ranges)
  162. }
  163. wg2.Wait()
  164. polATodd := fft(polASe)
  165. polBTodd := fft(polBSe)
  166. polABT := arrayOfZeroesE(len(polASe) * 2)
  167. var wg3 sync.WaitGroup
  168. wg3.Add(numcpu)
  169. for _cpu, _ranges := range ranges(len(polASe), numcpu) {
  170. go func(cpu int, ranges [2]int) {
  171. for i := ranges[0]; i < ranges[1]; i++ {
  172. polABT[2*i].Mul(polATe[i], polBTe[i])
  173. polABT[2*i+1].Mul(polATodd[i], polBTodd[i])
  174. }
  175. wg3.Done()
  176. }(_cpu, _ranges)
  177. }
  178. wg3.Wait()
  179. hSeFull := ifft(polABT)
  180. hSe := hSeFull[m:]
  181. return utils.ElementArrayToBigIntArray(hSe)
  182. }
  183. func ranges(n, parts int) [][2]int {
  184. s := make([][2]int, parts)
  185. p := float64(n) / float64(parts)
  186. for i := 0; i < parts; i++ {
  187. a, b := int(float64(i)*p), int(float64(i+1)*p)
  188. s[i] = [2]int{a, b}
  189. }
  190. return s
  191. }