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
3.2 KiB

  1. package prover
  2. import (
  3. "bytes"
  4. "math/big"
  5. "github.com/iden3/go-circom-prover-verifier/types"
  6. "github.com/iden3/go-iden3-crypto/ff"
  7. )
  8. func arrayOfZeroes(n int) []*big.Int {
  9. var r []*big.Int
  10. for i := 0; i < n; i++ {
  11. r = append(r, new(big.Int).SetInt64(0))
  12. }
  13. return r
  14. }
  15. func arrayOfZeroesE(n int) []*ff.Element {
  16. var r []*ff.Element
  17. for i := 0; i < n; i++ {
  18. r = append(r, ff.NewElement())
  19. }
  20. return r
  21. }
  22. func fAdd(a, b *big.Int) *big.Int {
  23. ab := new(big.Int).Add(a, b)
  24. return new(big.Int).Mod(ab, types.R)
  25. }
  26. func fSub(a, b *big.Int) *big.Int {
  27. ab := new(big.Int).Sub(a, b)
  28. return new(big.Int).Mod(ab, types.R)
  29. }
  30. func fMul(a, b *big.Int) *big.Int {
  31. ab := new(big.Int).Mul(a, b)
  32. return new(big.Int).Mod(ab, types.R)
  33. }
  34. func fDiv(a, b *big.Int) *big.Int {
  35. ab := new(big.Int).Mul(a, new(big.Int).ModInverse(b, types.R))
  36. return new(big.Int).Mod(ab, types.R)
  37. }
  38. func fNeg(a *big.Int) *big.Int {
  39. return new(big.Int).Mod(new(big.Int).Neg(a), types.R)
  40. }
  41. func fInv(a *big.Int) *big.Int {
  42. return new(big.Int).ModInverse(a, types.R)
  43. }
  44. func fExp(base *big.Int, e *big.Int) *big.Int {
  45. res := big.NewInt(1)
  46. rem := new(big.Int).Set(e)
  47. exp := base
  48. for !bytes.Equal(rem.Bytes(), big.NewInt(int64(0)).Bytes()) {
  49. // if BigIsOdd(rem) {
  50. if rem.Bit(0) == 1 { // .Bit(0) returns 1 when is odd
  51. res = fMul(res, exp)
  52. }
  53. exp = fMul(exp, exp)
  54. rem = new(big.Int).Rsh(rem, 1)
  55. }
  56. return res
  57. }
  58. func max(a, b int) int {
  59. if a > b {
  60. return a
  61. }
  62. return b
  63. }
  64. func polynomialSub(a, b []*big.Int) []*big.Int {
  65. r := arrayOfZeroes(max(len(a), len(b)))
  66. for i := 0; i < len(a); i++ {
  67. r[i] = fAdd(r[i], a[i])
  68. }
  69. for i := 0; i < len(b); i++ {
  70. r[i] = fSub(r[i], b[i])
  71. }
  72. return r
  73. }
  74. func polynomialSubE(a, b []*ff.Element) []*ff.Element {
  75. r := arrayOfZeroesE(max(len(a), len(b)))
  76. for i := 0; i < len(a); i++ {
  77. r[i].Add(r[i], a[i])
  78. }
  79. for i := 0; i < len(b); i++ {
  80. r[i].Sub(r[i], b[i])
  81. }
  82. return r
  83. }
  84. func polynomialMul(a, b []*big.Int) []*big.Int {
  85. r := arrayOfZeroes(len(a) + len(b) - 1)
  86. for i := 0; i < len(a); i++ {
  87. for j := 0; j < len(b); j++ {
  88. r[i+j] = fAdd(r[i+j], fMul(a[i], b[j]))
  89. }
  90. }
  91. return r
  92. }
  93. func polynomialMulE(a, b []*ff.Element) []*ff.Element {
  94. r := arrayOfZeroesE(len(a) + len(b) - 1)
  95. for i := 0; i < len(a); i++ {
  96. for j := 0; j < len(b); j++ {
  97. r[i+j].Add(r[i+j], ff.NewElement().Mul(a[i], b[j]))
  98. }
  99. }
  100. return r
  101. }
  102. func polynomialDiv(a, b []*big.Int) ([]*big.Int, []*big.Int) {
  103. // https://en.wikipedia.org/wiki/Division_algorithm
  104. r := arrayOfZeroes(len(a) - len(b) + 1)
  105. rem := a
  106. for len(rem) >= len(b) {
  107. l := fDiv(rem[len(rem)-1], b[len(b)-1])
  108. pos := len(rem) - len(b)
  109. r[pos] = l
  110. aux := arrayOfZeroes(pos)
  111. aux1 := append(aux, l)
  112. aux2 := polynomialSub(rem, polynomialMul(b, aux1))
  113. rem = aux2[:len(aux2)-1]
  114. }
  115. return r, rem
  116. }
  117. func polynomialDivE(a, b []*ff.Element) ([]*ff.Element, []*ff.Element) {
  118. // https://en.wikipedia.org/wiki/Division_algorithm
  119. r := arrayOfZeroesE(len(a) - len(b) + 1)
  120. rem := a
  121. for len(rem) >= len(b) {
  122. l := ff.NewElement().Div(rem[len(rem)-1], b[len(b)-1])
  123. pos := len(rem) - len(b)
  124. r[pos] = l
  125. aux := arrayOfZeroesE(pos)
  126. aux1 := append(aux, l)
  127. aux2 := polynomialSubE(rem, polynomialMulE(b, aux1))
  128. rem = aux2[:len(aux2)-1]
  129. }
  130. return r, rem
  131. }