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.

152 lines
3.8 KiB

  1. package snark
  2. import (
  3. "fmt"
  4. "math/big"
  5. "strings"
  6. "testing"
  7. "time"
  8. "github.com/arnaucube/go-snark/circuitcompiler"
  9. "github.com/arnaucube/go-snark/r1csqap"
  10. "github.com/stretchr/testify/assert"
  11. )
  12. func TestZkFromFlatCircuitCode(t *testing.T) {
  13. // compile circuit and get the R1CS
  14. flatCode := `
  15. func test(x):
  16. aux = x*x
  17. y = aux*x
  18. z = x + y
  19. out = z + 5
  20. `
  21. fmt.Print("\nflat code of the circuit:")
  22. fmt.Println(flatCode)
  23. // parse the code
  24. parser := circuitcompiler.NewParser(strings.NewReader(flatCode))
  25. circuit, err := parser.Parse()
  26. assert.Nil(t, err)
  27. fmt.Println("\ncircuit data:", circuit)
  28. b3 := big.NewInt(int64(3))
  29. inputs := []*big.Int{b3}
  30. // wittness
  31. w := circuit.CalculateWitness(inputs)
  32. fmt.Println("\nwitness", w)
  33. // flat code to R1CS
  34. fmt.Println("\ngenerating R1CS from flat code")
  35. a, b, c := circuit.GenerateR1CS()
  36. fmt.Println("\nR1CS:")
  37. fmt.Println("a:", a)
  38. fmt.Println("b:", b)
  39. fmt.Println("c:", c)
  40. // R1CS to QAP
  41. alphas, betas, gammas, zx := Utils.PF.R1CSToQAP(a, b, c)
  42. fmt.Println("qap")
  43. fmt.Println(alphas)
  44. fmt.Println(betas)
  45. fmt.Println(gammas)
  46. ax, bx, cx, px := Utils.PF.CombinePolynomials(w, alphas, betas, gammas)
  47. hx := Utils.PF.DivisorPolynomial(px, zx)
  48. // hx==px/zx so px==hx*zx
  49. assert.Equal(t, px, Utils.PF.Mul(hx, zx))
  50. // p(x) = a(x) * b(x) - c(x) == h(x) * z(x)
  51. abc := Utils.PF.Sub(Utils.PF.Mul(ax, bx), cx)
  52. assert.Equal(t, abc, px)
  53. hz := Utils.PF.Mul(hx, zx)
  54. assert.Equal(t, abc, hz)
  55. div, rem := Utils.PF.Div(px, zx)
  56. assert.Equal(t, hx, div)
  57. assert.Equal(t, rem, r1csqap.ArrayOfBigZeros(4))
  58. // calculate trusted setup
  59. setup, err := GenerateTrustedSetup(len(w), *circuit, alphas, betas, gammas, zx)
  60. assert.Nil(t, err)
  61. fmt.Println("\nt:", setup.Toxic.T)
  62. // piA = g1 * A(t), piB = g2 * B(t), piC = g1 * C(t), piH = g1 * H(t)
  63. proof, err := GenerateProofs(*circuit, setup, hx, w)
  64. assert.Nil(t, err)
  65. fmt.Println("\n proofs:")
  66. fmt.Println(proof)
  67. before := time.Now()
  68. assert.True(t, VerifyProof(*circuit, setup, proof))
  69. fmt.Println("verify proof time elapsed:", time.Since(before))
  70. }
  71. func TestZkFromHardcodedR1CS(t *testing.T) {
  72. b0 := big.NewInt(int64(0))
  73. b1 := big.NewInt(int64(1))
  74. b3 := big.NewInt(int64(3))
  75. b5 := big.NewInt(int64(5))
  76. b9 := big.NewInt(int64(9))
  77. b27 := big.NewInt(int64(27))
  78. b30 := big.NewInt(int64(30))
  79. b35 := big.NewInt(int64(35))
  80. a := [][]*big.Int{
  81. []*big.Int{b0, b1, b0, b0, b0, b0},
  82. []*big.Int{b0, b0, b0, b1, b0, b0},
  83. []*big.Int{b0, b1, b0, b0, b1, b0},
  84. []*big.Int{b5, b0, b0, b0, b0, b1},
  85. }
  86. b := [][]*big.Int{
  87. []*big.Int{b0, b1, b0, b0, b0, b0},
  88. []*big.Int{b0, b1, b0, b0, b0, b0},
  89. []*big.Int{b1, b0, b0, b0, b0, b0},
  90. []*big.Int{b1, b0, b0, b0, b0, b0},
  91. }
  92. c := [][]*big.Int{
  93. []*big.Int{b0, b0, b0, b1, b0, b0},
  94. []*big.Int{b0, b0, b0, b0, b1, b0},
  95. []*big.Int{b0, b0, b0, b0, b0, b1},
  96. []*big.Int{b0, b0, b1, b0, b0, b0},
  97. }
  98. alphas, betas, gammas, zx := Utils.PF.R1CSToQAP(a, b, c)
  99. // wittness = 1, 3, 35, 9, 27, 30
  100. w := []*big.Int{b1, b3, b35, b9, b27, b30}
  101. circuit := circuitcompiler.Circuit{
  102. NVars: 6,
  103. NPublic: 0,
  104. NSignals: len(w),
  105. }
  106. ax, bx, cx, px := Utils.PF.CombinePolynomials(w, alphas, betas, gammas)
  107. hx := Utils.PF.DivisorPolynomial(px, zx)
  108. // hx==px/zx so px==hx*zx
  109. assert.Equal(t, px, Utils.PF.Mul(hx, zx))
  110. // p(x) = a(x) * b(x) - c(x) == h(x) * z(x)
  111. abc := Utils.PF.Sub(Utils.PF.Mul(ax, bx), cx)
  112. assert.Equal(t, abc, px)
  113. hz := Utils.PF.Mul(hx, zx)
  114. assert.Equal(t, abc, hz)
  115. div, rem := Utils.PF.Div(px, zx)
  116. assert.Equal(t, hx, div)
  117. assert.Equal(t, rem, r1csqap.ArrayOfBigZeros(4))
  118. // calculate trusted setup
  119. setup, err := GenerateTrustedSetup(len(w), circuit, alphas, betas, gammas, zx)
  120. assert.Nil(t, err)
  121. fmt.Println("t", setup.Toxic.T)
  122. // piA = g1 * A(t), piB = g2 * B(t), piC = g1 * C(t), piH = g1 * H(t)
  123. proof, err := GenerateProofs(circuit, setup, hx, w)
  124. assert.Nil(t, err)
  125. assert.True(t, VerifyProof(circuit, setup, proof))
  126. }