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.

218 lines
6.2 KiB

  1. // implementation of https://eprint.iacr.org/2016/260.pdf
  2. package groth16
  3. import (
  4. "math/big"
  5. "github.com/arnaucube/go-snark/bn128"
  6. "github.com/arnaucube/go-snark/circuitcompiler"
  7. "github.com/arnaucube/go-snark/fields"
  8. "github.com/arnaucube/go-snark/r1csqap"
  9. )
  10. // Setup is the data structure holding the Trusted Setup data. The Setup.Toxic sub struct must be destroyed after the GenerateTrustedSetup function is completed
  11. type Setup struct {
  12. Toxic struct {
  13. T *big.Int // trusted setup secret
  14. Kalpha *big.Int
  15. Kbeta *big.Int
  16. Kgamma *big.Int
  17. Kdelta *big.Int
  18. }
  19. // public
  20. Pk struct { // Proving Key
  21. BACDelta [][3]*big.Int // {( βui(x)+αvi(x)+wi(x) ) / γ } from 0 to l
  22. Z []*big.Int
  23. G1 struct {
  24. Alpha [3]*big.Int
  25. Beta [3]*big.Int
  26. Delta [3]*big.Int
  27. At [][3]*big.Int // {a(τ)} from 0 to m
  28. BACGamma [][3]*big.Int // {( βui(x)+αvi(x)+wi(x) ) / δ } from l+1 to m
  29. }
  30. G2 struct {
  31. Beta [3][2]*big.Int
  32. Gamma [3][2]*big.Int
  33. Delta [3][2]*big.Int
  34. BACGamma [][3][2]*big.Int // {( βui(x)+αvi(x)+wi(x) ) / δ } from l+1 to m
  35. }
  36. PowersTauDelta [][3]*big.Int // powers of τ encrypted in G1 curve, divided by δ
  37. }
  38. Vk struct {
  39. IC [][3]*big.Int
  40. G1 struct {
  41. Alpha [3]*big.Int
  42. }
  43. G2 struct {
  44. Beta [3][2]*big.Int
  45. Gamma [3][2]*big.Int
  46. Delta [3][2]*big.Int
  47. }
  48. }
  49. }
  50. // ProofGroth contains the parameters to proof the zkSNARK
  51. type ProofGroth struct {
  52. PiA [3]*big.Int
  53. PiB [3][2]*big.Int
  54. PiC [3]*big.Int
  55. }
  56. type utils struct {
  57. Bn bn128.Bn128
  58. FqR fields.Fq
  59. PF r1csqap.PolynomialField
  60. }
  61. // Utils is the data structure holding the BN128, FqR Finite Field over R, PolynomialField, that will be used inside the snarks operations
  62. var Utils = prepareUtils()
  63. func prepareUtils() utils {
  64. bn, err := bn128.NewBn128()
  65. if err != nil {
  66. panic(err)
  67. }
  68. // new Finite Field
  69. fqR := fields.NewFq(bn.R)
  70. // new Polynomial Field
  71. pf := r1csqap.NewPolynomialField(fqR)
  72. return utils{
  73. Bn: bn,
  74. FqR: fqR,
  75. PF: pf,
  76. }
  77. }
  78. // GenerateTrustedSetup generates the Trusted Setup from a compiled Circuit. The Setup.Toxic sub data structure must be destroyed
  79. func GenerateTrustedSetup(witnessLength int, circuit circuitcompiler.Circuit, alphas, betas, gammas [][]*big.Int) (Setup, error) {
  80. var setup Setup
  81. var err error
  82. // generate random t value
  83. setup.Toxic.T, err = Utils.FqR.Rand()
  84. if err != nil {
  85. return Setup{}, err
  86. }
  87. setup.Toxic.Kalpha, err = Utils.FqR.Rand()
  88. if err != nil {
  89. return Setup{}, err
  90. }
  91. setup.Toxic.Kbeta, err = Utils.FqR.Rand()
  92. if err != nil {
  93. return Setup{}, err
  94. }
  95. setup.Toxic.Kgamma, err = Utils.FqR.Rand()
  96. if err != nil {
  97. return Setup{}, err
  98. }
  99. setup.Toxic.Kdelta, err = Utils.FqR.Rand()
  100. if err != nil {
  101. return Setup{}, err
  102. }
  103. // z pol
  104. zpol := []*big.Int{big.NewInt(int64(1))}
  105. for i := 1; i < len(alphas)-1; i++ {
  106. zpol = Utils.PF.Mul(
  107. zpol,
  108. []*big.Int{
  109. Utils.FqR.Neg(
  110. big.NewInt(int64(i))),
  111. big.NewInt(int64(1)),
  112. })
  113. }
  114. setup.Pk.Z = zpol
  115. zt := Utils.PF.Eval(zpol, setup.Toxic.T)
  116. invDelta := Utils.FqR.Inverse(setup.Toxic.Kdelta)
  117. ztinvDelta := Utils.FqR.Mul(invDelta, zt)
  118. // encrypt t values with curve generators
  119. // powers of tau divided by delta
  120. var ptd [][3]*big.Int
  121. ini := Utils.Bn.G1.MulScalar(Utils.Bn.G1.G, ztinvDelta)
  122. ptd = append(ptd, ini)
  123. tEncr := setup.Toxic.T
  124. for i := 1; i < len(zpol); i++ {
  125. ptd = append(ptd, Utils.Bn.G1.MulScalar(Utils.Bn.G1.G, Utils.FqR.Mul(tEncr, ztinvDelta)))
  126. tEncr = Utils.FqR.Mul(tEncr, setup.Toxic.T)
  127. }
  128. // powers of τ encrypted in G1 curve, divided by δ
  129. // (G1 * τ) / δ
  130. setup.Pk.PowersTauDelta = ptd
  131. setup.Pk.G1.Alpha = Utils.Bn.G1.MulScalar(Utils.Bn.G1.G, setup.Toxic.Kalpha)
  132. setup.Pk.G1.Beta = Utils.Bn.G1.MulScalar(Utils.Bn.G1.G, setup.Toxic.Kbeta)
  133. setup.Pk.G1.Delta = Utils.Bn.G1.MulScalar(Utils.Bn.G1.G, setup.Toxic.Kdelta)
  134. setup.Pk.G2.Beta = Utils.Bn.G2.MulScalar(Utils.Bn.G2.G, setup.Toxic.Kbeta)
  135. setup.Pk.G2.Delta = Utils.Bn.G2.MulScalar(Utils.Bn.G2.G, setup.Toxic.Kdelta)
  136. setup.Vk.G1.Alpha = Utils.Bn.G1.MulScalar(Utils.Bn.G1.G, setup.Toxic.Kalpha)
  137. setup.Vk.G2.Beta = Utils.Bn.G2.MulScalar(Utils.Bn.G2.G, setup.Toxic.Kbeta)
  138. setup.Vk.G2.Gamma = Utils.Bn.G2.MulScalar(Utils.Bn.G2.G, setup.Toxic.Kgamma)
  139. setup.Vk.G2.Delta = Utils.Bn.G2.MulScalar(Utils.Bn.G2.G, setup.Toxic.Kdelta)
  140. for i := 0; i < len(circuit.Signals); i++ {
  141. // Pk.G1.At: {a(τ)} from 0 to m
  142. at := Utils.PF.Eval(alphas[i], setup.Toxic.T)
  143. a := Utils.Bn.G1.MulScalar(Utils.Bn.G1.G, at)
  144. setup.Pk.G1.At = append(setup.Pk.G1.At, a)
  145. bt := Utils.PF.Eval(betas[i], setup.Toxic.T)
  146. g1bt := Utils.Bn.G1.MulScalar(Utils.Bn.G1.G, bt)
  147. g2bt := Utils.Bn.G2.MulScalar(Utils.Bn.G2.G, bt)
  148. // G1.BACGamma: {( βui(x)+αvi(x)+wi(x) ) / δ } from l+1 to m in G1
  149. setup.Pk.G1.BACGamma = append(setup.Pk.G1.BACGamma, g1bt)
  150. // G2.BACGamma: {( βui(x)+αvi(x)+wi(x) ) / δ } from l+1 to m in G2
  151. setup.Pk.G2.BACGamma = append(setup.Pk.G2.BACGamma, g2bt)
  152. }
  153. zero3 := [3]*big.Int{Utils.Bn.G1.F.Zero(), Utils.Bn.G1.F.Zero(), Utils.Bn.G1.F.Zero()}
  154. for i := 0; i < circuit.NPublic+1; i++ {
  155. setup.Pk.BACDelta = append(setup.Pk.BACDelta, zero3)
  156. }
  157. for i := circuit.NPublic + 1; i < circuit.NVars; i++ {
  158. // TODO calculate all at, bt, ct outside, to avoid repeating calculations
  159. at := Utils.PF.Eval(alphas[i], setup.Toxic.T)
  160. bt := Utils.PF.Eval(betas[i], setup.Toxic.T)
  161. ct := Utils.PF.Eval(gammas[i], setup.Toxic.T)
  162. c := Utils.FqR.Mul(
  163. invDelta,
  164. Utils.FqR.Add(
  165. Utils.FqR.Add(
  166. Utils.FqR.Mul(at, setup.Toxic.Kbeta),
  167. Utils.FqR.Mul(bt, setup.Toxic.Kalpha),
  168. ),
  169. ct,
  170. ),
  171. )
  172. g1c := Utils.Bn.G1.MulScalar(Utils.Bn.G1.G, c)
  173. // Pk.BACDelta: {( βui(x)+αvi(x)+wi(x) ) / γ } from 0 to l
  174. setup.Pk.BACDelta = append(setup.Pk.BACDelta, g1c)
  175. }
  176. for i := 0; i <= circuit.NPublic; i++ {
  177. at := Utils.PF.Eval(alphas[i], setup.Toxic.T)
  178. bt := Utils.PF.Eval(betas[i], setup.Toxic.T)
  179. ct := Utils.PF.Eval(gammas[i], setup.Toxic.T)
  180. ic := Utils.FqR.Mul(
  181. Utils.FqR.Inverse(setup.Toxic.Kgamma),
  182. Utils.FqR.Add(
  183. Utils.FqR.Add(
  184. Utils.FqR.Mul(at, setup.Toxic.Kbeta),
  185. Utils.FqR.Mul(bt, setup.Toxic.Kalpha),
  186. ),
  187. ct,
  188. ),
  189. )
  190. g1ic := Utils.Bn.G1.MulScalar(Utils.Bn.G1.G, ic)
  191. // used in verifier
  192. setup.Vk.IC = append(setup.Vk.IC, g1ic)
  193. }
  194. return setup, nil
  195. }