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.

281 lines
8.8 KiB

  1. // implementation of https://eprint.iacr.org/2016/260.pdf
  2. package proof
  3. import (
  4. "fmt"
  5. "math/big"
  6. "github.com/arnaucube/go-snark/circuit"
  7. )
  8. // Groth16Setup is the data structure holding the Trusted Groth16Setup data.
  9. type Groth16Setup struct {
  10. Toxic struct {
  11. T *big.Int // trusted setup secret
  12. Kalpha *big.Int
  13. Kbeta *big.Int
  14. Kgamma *big.Int
  15. Kdelta *big.Int
  16. }
  17. // public
  18. Pk struct { // Proving Key
  19. BACDelta [][3]*big.Int // {( βui(x)+αvi(x)+wi(x) ) / γ } from 0 to l
  20. Z []*big.Int
  21. G1 struct {
  22. Alpha [3]*big.Int
  23. Beta [3]*big.Int
  24. Delta [3]*big.Int
  25. At [][3]*big.Int // {a(τ)} from 0 to m
  26. BACGamma [][3]*big.Int // {( βui(x)+αvi(x)+wi(x) ) / δ } from l+1 to m
  27. }
  28. G2 struct {
  29. Beta [3][2]*big.Int
  30. Gamma [3][2]*big.Int
  31. Delta [3][2]*big.Int
  32. BACGamma [][3][2]*big.Int // {( βui(x)+αvi(x)+wi(x) ) / δ } from l+1 to m
  33. }
  34. PowersTauDelta [][3]*big.Int // powers of τ encrypted in G1 curve, divided by δ
  35. }
  36. Vk struct {
  37. IC [][3]*big.Int
  38. G1 struct {
  39. Alpha [3]*big.Int
  40. }
  41. G2 struct {
  42. Beta [3][2]*big.Int
  43. Gamma [3][2]*big.Int
  44. Delta [3][2]*big.Int
  45. }
  46. }
  47. }
  48. // Groth16Proof contains the parameters to proof the zkSNARK
  49. type Groth16Proof struct {
  50. PiA [3]*big.Int
  51. PiB [3][2]*big.Int
  52. PiC [3]*big.Int
  53. }
  54. // Z is ...
  55. func (setup *Groth16Setup) Z() []*big.Int {
  56. return setup.Pk.Z
  57. }
  58. // Init generates the Trusted Setup from a compiled Circuit. The Setup.Toxic sub data structure must be destroyed
  59. func (setup *Groth16Setup) Init(witnessLength int, circuit circuit.Circuit, alphas, betas, gammas [][]*big.Int) error {
  60. var err error
  61. // generate random t value
  62. setup.Toxic.T, err = Utils.FqR.Rand()
  63. if err != nil {
  64. return err
  65. }
  66. setup.Toxic.Kalpha, err = Utils.FqR.Rand()
  67. if err != nil {
  68. return err
  69. }
  70. setup.Toxic.Kbeta, err = Utils.FqR.Rand()
  71. if err != nil {
  72. return err
  73. }
  74. setup.Toxic.Kgamma, err = Utils.FqR.Rand()
  75. if err != nil {
  76. return err
  77. }
  78. setup.Toxic.Kdelta, err = Utils.FqR.Rand()
  79. if err != nil {
  80. return err
  81. }
  82. // z pol
  83. zpol := []*big.Int{big.NewInt(int64(1))}
  84. for i := 1; i < len(alphas)-1; i++ {
  85. zpol = Utils.PF.Mul(
  86. zpol,
  87. []*big.Int{
  88. Utils.FqR.Neg(
  89. big.NewInt(int64(i))),
  90. big.NewInt(int64(1)),
  91. })
  92. }
  93. setup.Pk.Z = zpol
  94. zt := Utils.PF.Eval(zpol, setup.Toxic.T)
  95. invDelta := Utils.FqR.Inverse(setup.Toxic.Kdelta)
  96. ztinvDelta := Utils.FqR.Mul(invDelta, zt)
  97. // encrypt t values with curve generators
  98. // powers of tau divided by delta
  99. var ptd [][3]*big.Int
  100. ini := Utils.Bn.G1.MulScalar(Utils.Bn.G1.G, ztinvDelta)
  101. ptd = append(ptd, ini)
  102. tEncr := setup.Toxic.T
  103. for i := 1; i < len(zpol); i++ {
  104. ptd = append(ptd, Utils.Bn.G1.MulScalar(Utils.Bn.G1.G, Utils.FqR.Mul(tEncr, ztinvDelta)))
  105. tEncr = Utils.FqR.Mul(tEncr, setup.Toxic.T)
  106. }
  107. // powers of τ encrypted in G1 curve, divided by δ
  108. // (G1 * τ) / δ
  109. setup.Pk.PowersTauDelta = ptd
  110. setup.Pk.G1.Alpha = Utils.Bn.G1.MulScalar(Utils.Bn.G1.G, setup.Toxic.Kalpha)
  111. setup.Pk.G1.Beta = Utils.Bn.G1.MulScalar(Utils.Bn.G1.G, setup.Toxic.Kbeta)
  112. setup.Pk.G1.Delta = Utils.Bn.G1.MulScalar(Utils.Bn.G1.G, setup.Toxic.Kdelta)
  113. setup.Pk.G2.Beta = Utils.Bn.G2.MulScalar(Utils.Bn.G2.G, setup.Toxic.Kbeta)
  114. setup.Pk.G2.Delta = Utils.Bn.G2.MulScalar(Utils.Bn.G2.G, setup.Toxic.Kdelta)
  115. setup.Vk.G1.Alpha = Utils.Bn.G1.MulScalar(Utils.Bn.G1.G, setup.Toxic.Kalpha)
  116. setup.Vk.G2.Beta = Utils.Bn.G2.MulScalar(Utils.Bn.G2.G, setup.Toxic.Kbeta)
  117. setup.Vk.G2.Gamma = Utils.Bn.G2.MulScalar(Utils.Bn.G2.G, setup.Toxic.Kgamma)
  118. setup.Vk.G2.Delta = Utils.Bn.G2.MulScalar(Utils.Bn.G2.G, setup.Toxic.Kdelta)
  119. for i := 0; i < len(circuit.Signals); i++ {
  120. // Pk.G1.At: {a(τ)} from 0 to m
  121. at := Utils.PF.Eval(alphas[i], setup.Toxic.T)
  122. a := Utils.Bn.G1.MulScalar(Utils.Bn.G1.G, at)
  123. setup.Pk.G1.At = append(setup.Pk.G1.At, a)
  124. bt := Utils.PF.Eval(betas[i], setup.Toxic.T)
  125. g1bt := Utils.Bn.G1.MulScalar(Utils.Bn.G1.G, bt)
  126. g2bt := Utils.Bn.G2.MulScalar(Utils.Bn.G2.G, bt)
  127. // G1.BACGamma: {( βui(x)+αvi(x)+wi(x) ) / δ } from l+1 to m in G1
  128. setup.Pk.G1.BACGamma = append(setup.Pk.G1.BACGamma, g1bt)
  129. // G2.BACGamma: {( βui(x)+αvi(x)+wi(x) ) / δ } from l+1 to m in G2
  130. setup.Pk.G2.BACGamma = append(setup.Pk.G2.BACGamma, g2bt)
  131. }
  132. zero3 := [3]*big.Int{Utils.Bn.G1.F.Zero(), Utils.Bn.G1.F.Zero(), Utils.Bn.G1.F.Zero()}
  133. for i := 0; i < circuit.NPublic+1; i++ {
  134. setup.Pk.BACDelta = append(setup.Pk.BACDelta, zero3)
  135. }
  136. for i := circuit.NPublic + 1; i < circuit.NVars; i++ {
  137. // TODO calculate all at, bt, ct outside, to avoid repeating calculations
  138. at := Utils.PF.Eval(alphas[i], setup.Toxic.T)
  139. bt := Utils.PF.Eval(betas[i], setup.Toxic.T)
  140. ct := Utils.PF.Eval(gammas[i], setup.Toxic.T)
  141. c := Utils.FqR.Mul(
  142. invDelta,
  143. Utils.FqR.Add(
  144. Utils.FqR.Add(
  145. Utils.FqR.Mul(at, setup.Toxic.Kbeta),
  146. Utils.FqR.Mul(bt, setup.Toxic.Kalpha),
  147. ),
  148. ct,
  149. ),
  150. )
  151. g1c := Utils.Bn.G1.MulScalar(Utils.Bn.G1.G, c)
  152. // Pk.BACDelta: {( βui(x)+αvi(x)+wi(x) ) / γ } from 0 to l
  153. setup.Pk.BACDelta = append(setup.Pk.BACDelta, g1c)
  154. }
  155. for i := 0; i <= circuit.NPublic; i++ {
  156. at := Utils.PF.Eval(alphas[i], setup.Toxic.T)
  157. bt := Utils.PF.Eval(betas[i], setup.Toxic.T)
  158. ct := Utils.PF.Eval(gammas[i], setup.Toxic.T)
  159. ic := Utils.FqR.Mul(
  160. Utils.FqR.Inverse(setup.Toxic.Kgamma),
  161. Utils.FqR.Add(
  162. Utils.FqR.Add(
  163. Utils.FqR.Mul(at, setup.Toxic.Kbeta),
  164. Utils.FqR.Mul(bt, setup.Toxic.Kalpha),
  165. ),
  166. ct,
  167. ),
  168. )
  169. g1ic := Utils.Bn.G1.MulScalar(Utils.Bn.G1.G, ic)
  170. // used in verifier
  171. setup.Vk.IC = append(setup.Vk.IC, g1ic)
  172. }
  173. return nil
  174. }
  175. // Generate generates all the parameters to proof the zkSNARK from the Circuit, Setup and the Witness
  176. func (setup Groth16Setup) Generate(circuit circuit.Circuit, w []*big.Int, px []*big.Int) (Proof, error) {
  177. proof := &Groth16Proof{}
  178. proof.PiA = [3]*big.Int{Utils.Bn.G1.F.Zero(), Utils.Bn.G1.F.Zero(), Utils.Bn.G1.F.Zero()}
  179. proof.PiB = Utils.Bn.Fq6.Zero()
  180. proof.PiC = [3]*big.Int{Utils.Bn.G1.F.Zero(), Utils.Bn.G1.F.Zero(), Utils.Bn.G1.F.Zero()}
  181. r, err := Utils.FqR.Rand()
  182. if err != nil {
  183. return &Groth16Proof{}, err
  184. }
  185. s, err := Utils.FqR.Rand()
  186. if err != nil {
  187. return &Groth16Proof{}, err
  188. }
  189. // piBG1 will hold all the same than proof.PiB but in G1 curve
  190. piBG1 := [3]*big.Int{Utils.Bn.G1.F.Zero(), Utils.Bn.G1.F.Zero(), Utils.Bn.G1.F.Zero()}
  191. for i := 0; i < circuit.NVars; i++ {
  192. proof.PiA = Utils.Bn.G1.Add(proof.PiA, Utils.Bn.G1.MulScalar(setup.Pk.G1.At[i], w[i]))
  193. piBG1 = Utils.Bn.G1.Add(piBG1, Utils.Bn.G1.MulScalar(setup.Pk.G1.BACGamma[i], w[i]))
  194. proof.PiB = Utils.Bn.G2.Add(proof.PiB, Utils.Bn.G2.MulScalar(setup.Pk.G2.BACGamma[i], w[i]))
  195. }
  196. for i := circuit.NPublic + 1; i < circuit.NVars; i++ {
  197. proof.PiC = Utils.Bn.G1.Add(proof.PiC, Utils.Bn.G1.MulScalar(setup.Pk.BACDelta[i], w[i]))
  198. }
  199. // piA = (Σ from 0 to m (pk.A * w[i])) + pk.Alpha1 + r * δ
  200. proof.PiA = Utils.Bn.G1.Add(proof.PiA, setup.Pk.G1.Alpha)
  201. deltaR := Utils.Bn.G1.MulScalar(setup.Pk.G1.Delta, r)
  202. proof.PiA = Utils.Bn.G1.Add(proof.PiA, deltaR)
  203. // piBG1 = (Σ from 0 to m (pk.B1 * w[i])) + pk.g1.Beta + s * δ
  204. // piB = piB2 = (Σ from 0 to m (pk.B2 * w[i])) + pk.g2.Beta + s * δ
  205. piBG1 = Utils.Bn.G1.Add(piBG1, setup.Pk.G1.Beta)
  206. proof.PiB = Utils.Bn.G2.Add(proof.PiB, setup.Pk.G2.Beta)
  207. deltaSG1 := Utils.Bn.G1.MulScalar(setup.Pk.G1.Delta, s)
  208. piBG1 = Utils.Bn.G1.Add(piBG1, deltaSG1)
  209. deltaSG2 := Utils.Bn.G2.MulScalar(setup.Pk.G2.Delta, s)
  210. proof.PiB = Utils.Bn.G2.Add(proof.PiB, deltaSG2)
  211. hx := Utils.PF.DivisorPolynomial(px, setup.Pk.Z) // maybe move this calculation to a previous step
  212. // piC = (Σ from l+1 to m (w[i] * (pk.g1.Beta + pk.g1.Alpha + pk.C)) + h(tau)) / δ) + piA*s + r*piB - r*s*δ
  213. for i := 0; i < len(hx); i++ {
  214. proof.PiC = Utils.Bn.G1.Add(proof.PiC, Utils.Bn.G1.MulScalar(setup.Pk.PowersTauDelta[i], hx[i]))
  215. }
  216. proof.PiC = Utils.Bn.G1.Add(proof.PiC, Utils.Bn.G1.MulScalar(proof.PiA, s))
  217. proof.PiC = Utils.Bn.G1.Add(proof.PiC, Utils.Bn.G1.MulScalar(piBG1, r))
  218. negRS := Utils.FqR.Neg(Utils.FqR.Mul(r, s))
  219. proof.PiC = Utils.Bn.G1.Add(proof.PiC, Utils.Bn.G1.MulScalar(setup.Pk.G1.Delta, negRS))
  220. return proof, nil
  221. }
  222. // Verify verifies over the BN128 the Pairings of the Proof
  223. func (setup Groth16Setup) Verify(circuit circuit.Circuit, proof Proof, publicSignals []*big.Int, debug bool) bool {
  224. pproof, ok := proof.(*Groth16Proof)
  225. if !ok {
  226. panic("bad proof")
  227. }
  228. icPubl := setup.Vk.IC[0]
  229. for i := 0; i < len(publicSignals); i++ {
  230. icPubl = Utils.Bn.G1.Add(icPubl, Utils.Bn.G1.MulScalar(setup.Vk.IC[i+1], publicSignals[i]))
  231. }
  232. if !Utils.Bn.Fq12.Equal(
  233. Utils.Bn.Pairing(pproof.PiA, pproof.PiB),
  234. Utils.Bn.Fq12.Mul(
  235. Utils.Bn.Pairing(setup.Vk.G1.Alpha, setup.Vk.G2.Beta),
  236. Utils.Bn.Fq12.Mul(
  237. Utils.Bn.Pairing(icPubl, setup.Vk.G2.Gamma),
  238. Utils.Bn.Pairing(pproof.PiC, setup.Vk.G2.Delta)))) {
  239. if debug {
  240. fmt.Println("❌ groth16 verification not passed")
  241. }
  242. return false
  243. }
  244. if debug {
  245. fmt.Println("✓ groth16 verification passed")
  246. }
  247. return true
  248. }