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.

111 lines
2.6 KiB

  1. package kzg
  2. import (
  3. "bytes"
  4. "crypto/rand"
  5. "math/big"
  6. "testing"
  7. cryptoConstants "github.com/iden3/go-iden3-crypto/constants"
  8. "github.com/stretchr/testify/assert"
  9. )
  10. func randBI() *big.Int {
  11. maxbits := 256
  12. b := make([]byte, (maxbits/8)-1)
  13. _, err := rand.Read(b)
  14. if err != nil {
  15. panic(err)
  16. }
  17. r := new(big.Int).SetBytes(b)
  18. return new(big.Int).Mod(r, cryptoConstants.Q)
  19. }
  20. func neg(a *big.Int) *big.Int {
  21. return new(big.Int).Neg(a)
  22. }
  23. func TestPolynomial(t *testing.T) {
  24. b0 := big.NewInt(int64(0))
  25. b1 := big.NewInt(int64(1))
  26. b2 := big.NewInt(int64(2))
  27. b3 := big.NewInt(int64(3))
  28. b4 := big.NewInt(int64(4))
  29. b5 := big.NewInt(int64(5))
  30. b6 := big.NewInt(int64(6))
  31. b16 := big.NewInt(int64(16))
  32. a := []*big.Int{b1, b0, b5}
  33. b := []*big.Int{b3, b0, b1}
  34. // new Finite Field
  35. r, ok := new(big.Int).SetString("21888242871839275222246405745257275088548364400416034343698204186575808495617", 10) //nolint:lll
  36. assert.True(nil, ok)
  37. // polynomial multiplication
  38. o := polynomialMul(a, b)
  39. assert.Equal(t, o, []*big.Int{b3, b0, b16, b0, b5})
  40. // polynomial division
  41. quo, rem := polynomialDiv(a, b)
  42. assert.Equal(t, quo[0].Int64(), int64(5))
  43. // check the rem result without modulo
  44. assert.Equal(t, new(big.Int).Sub(rem[0], r).Int64(), int64(-14))
  45. c := []*big.Int{neg(b4), b0, neg(b2), b1}
  46. d := []*big.Int{neg(b3), b1}
  47. quo2, rem2 := polynomialDiv(c, d)
  48. assert.Equal(t, quo2, []*big.Int{b3, b1, b1})
  49. assert.Equal(t, rem2[0].Int64(), int64(5))
  50. // polynomial addition
  51. o = polynomialAdd(a, b)
  52. assert.Equal(t, o, []*big.Int{b4, b0, b6})
  53. // polynomial subtraction
  54. o1 := polynomialSub(a, b)
  55. o2 := polynomialSub(b, a)
  56. o = polynomialAdd(o1, o2)
  57. assert.True(t, bytes.Equal(b0.Bytes(), o[0].Bytes()))
  58. assert.True(t, bytes.Equal(b0.Bytes(), o[1].Bytes()))
  59. assert.True(t, bytes.Equal(b0.Bytes(), o[2].Bytes()))
  60. c = []*big.Int{b5, b6, b1}
  61. d = []*big.Int{b1, b3}
  62. o = polynomialSub(c, d)
  63. assert.Equal(t, o, []*big.Int{b4, b3, b1})
  64. // NewPolZeroAt
  65. o = newPolZeroAt(3, 4, b4)
  66. assert.Equal(t, polynomialEval(o, big.NewInt(3)), b4)
  67. o = newPolZeroAt(2, 4, b3)
  68. assert.Equal(t, polynomialEval(o, big.NewInt(2)), b3)
  69. }
  70. func BenchmarkArithmetic(b *testing.B) {
  71. // generate arrays with bigint
  72. var p, q []*big.Int
  73. for i := 0; i < 1000; i++ {
  74. pi := randBI()
  75. p = append(p, pi)
  76. }
  77. for i := 1000 - 1; i >= 0; i-- {
  78. q = append(q, p[i])
  79. }
  80. b.Run("polynomialSub", func(b *testing.B) {
  81. for i := 0; i < b.N; i++ {
  82. polynomialSub(p, q)
  83. }
  84. })
  85. b.Run("polynomialMul", func(b *testing.B) {
  86. for i := 0; i < b.N; i++ {
  87. polynomialMul(p, q)
  88. }
  89. })
  90. b.Run("polynomialDiv", func(b *testing.B) {
  91. for i := 0; i < b.N; i++ {
  92. polynomialDiv(p, q)
  93. }
  94. })
  95. }