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.

234 lines
5.1 KiB

  1. // Code generated by goff DO NOT EDIT
  2. package ff
  3. import (
  4. "crypto/rand"
  5. "math/big"
  6. mrand "math/rand"
  7. "testing"
  8. )
  9. func TestELEMENTCorrectnessAgainstBigInt(t *testing.T) {
  10. modulus, _ := new(big.Int).SetString("21888242871839275222246405745257275088548364400416034343698204186575808495617", 10)
  11. cmpEandB := func(e *Element, b *big.Int, name string) {
  12. var _e big.Int
  13. if e.FromMont().ToBigInt(&_e).Cmp(b) != 0 {
  14. t.Fatal(name, "failed")
  15. }
  16. }
  17. var modulusMinusOne, one big.Int
  18. one.SetUint64(1)
  19. modulusMinusOne.Sub(modulus, &one)
  20. for i := 0; i < 1000; i++ {
  21. // sample 2 random big int
  22. b1, _ := rand.Int(rand.Reader, modulus)
  23. b2, _ := rand.Int(rand.Reader, modulus)
  24. rExp := mrand.Uint64()
  25. // adding edge cases
  26. // TODO need more edge cases
  27. switch i {
  28. case 0:
  29. rExp = 0
  30. b1.SetUint64(0)
  31. case 1:
  32. b2.SetUint64(0)
  33. case 2:
  34. b1.SetUint64(0)
  35. b2.SetUint64(0)
  36. case 3:
  37. rExp = 0
  38. case 4:
  39. rExp = 1
  40. case 5:
  41. rExp = ^uint64(0) // max uint
  42. case 6:
  43. rExp = 2
  44. b1.Set(&modulusMinusOne)
  45. case 7:
  46. b2.Set(&modulusMinusOne)
  47. case 8:
  48. b1.Set(&modulusMinusOne)
  49. b2.Set(&modulusMinusOne)
  50. }
  51. rbExp := new(big.Int).SetUint64(rExp)
  52. var bMul, bAdd, bSub, bDiv, bNeg, bLsh, bInv, bExp, bSquare big.Int
  53. // e1 = mont(b1), e2 = mont(b2)
  54. var e1, e2, eMul, eAdd, eSub, eDiv, eNeg, eLsh, eInv, eExp, eSquare, eMulAssign, eSubAssign, eAddAssign Element
  55. e1.SetBigInt(b1)
  56. e2.SetBigInt(b2)
  57. // (e1*e2).FromMont() === b1*b2 mod q ... etc
  58. eSquare.Square(&e1)
  59. eMul.Mul(&e1, &e2)
  60. eMulAssign.Set(&e1)
  61. eMulAssign.MulAssign(&e2)
  62. eAdd.Add(&e1, &e2)
  63. eAddAssign.Set(&e1)
  64. eAddAssign.AddAssign(&e2)
  65. eSub.Sub(&e1, &e2)
  66. eSubAssign.Set(&e1)
  67. eSubAssign.SubAssign(&e2)
  68. eDiv.Div(&e1, &e2)
  69. eNeg.Neg(&e1)
  70. eInv.Inverse(&e1)
  71. eExp.Exp(e1, rExp)
  72. eLsh.Double(&e1)
  73. // same operations with big int
  74. bAdd.Add(b1, b2).Mod(&bAdd, modulus)
  75. bMul.Mul(b1, b2).Mod(&bMul, modulus)
  76. bSquare.Mul(b1, b1).Mod(&bSquare, modulus)
  77. bSub.Sub(b1, b2).Mod(&bSub, modulus)
  78. bDiv.ModInverse(b2, modulus)
  79. bDiv.Mul(&bDiv, b1).
  80. Mod(&bDiv, modulus)
  81. bNeg.Neg(b1).Mod(&bNeg, modulus)
  82. bInv.ModInverse(b1, modulus)
  83. bExp.Exp(b1, rbExp, modulus)
  84. bLsh.Lsh(b1, 1).Mod(&bLsh, modulus)
  85. cmpEandB(&eSquare, &bSquare, "Square")
  86. cmpEandB(&eMul, &bMul, "Mul")
  87. cmpEandB(&eMulAssign, &bMul, "MulAssign")
  88. cmpEandB(&eAdd, &bAdd, "Add")
  89. cmpEandB(&eAddAssign, &bAdd, "AddAssign")
  90. cmpEandB(&eSub, &bSub, "Sub")
  91. cmpEandB(&eSubAssign, &bSub, "SubAssign")
  92. cmpEandB(&eDiv, &bDiv, "Div")
  93. cmpEandB(&eNeg, &bNeg, "Neg")
  94. cmpEandB(&eInv, &bInv, "Inv")
  95. cmpEandB(&eExp, &bExp, "Exp")
  96. cmpEandB(&eLsh, &bLsh, "Lsh")
  97. }
  98. }
  99. func TestELEMENTIsRandom(t *testing.T) {
  100. for i := 0; i < 1000; i++ {
  101. var x, y Element
  102. x.SetRandom()
  103. y.SetRandom()
  104. if x.Equal(&y) {
  105. t.Fatal("2 random numbers are unlikely to be equal")
  106. }
  107. }
  108. }
  109. // -------------------------------------------------------------------------------------------------
  110. // benchmarks
  111. // most benchmarks are rudimentary and should sample a large number of random inputs
  112. // or be run multiple times to ensure it didn't measure the fastest path of the function
  113. // TODO: clean up and push benchmarking branch
  114. var benchResElement Element
  115. func BenchmarkInverseELEMENT(b *testing.B) {
  116. var x Element
  117. x.SetRandom()
  118. benchResElement.SetRandom()
  119. b.ResetTimer()
  120. for i := 0; i < b.N; i++ {
  121. benchResElement.Inverse(&x)
  122. }
  123. }
  124. func BenchmarkExpELEMENT(b *testing.B) {
  125. var x Element
  126. x.SetRandom()
  127. benchResElement.SetRandom()
  128. b.ResetTimer()
  129. for i := 0; i < b.N; i++ {
  130. benchResElement.Exp(x, mrand.Uint64())
  131. }
  132. }
  133. func BenchmarkDoubleELEMENT(b *testing.B) {
  134. benchResElement.SetRandom()
  135. b.ResetTimer()
  136. for i := 0; i < b.N; i++ {
  137. benchResElement.Double(&benchResElement)
  138. }
  139. }
  140. func BenchmarkAddELEMENT(b *testing.B) {
  141. var x Element
  142. x.SetRandom()
  143. benchResElement.SetRandom()
  144. b.ResetTimer()
  145. for i := 0; i < b.N; i++ {
  146. benchResElement.Add(&x, &benchResElement)
  147. }
  148. }
  149. func BenchmarkSubELEMENT(b *testing.B) {
  150. var x Element
  151. x.SetRandom()
  152. benchResElement.SetRandom()
  153. b.ResetTimer()
  154. for i := 0; i < b.N; i++ {
  155. benchResElement.Sub(&x, &benchResElement)
  156. }
  157. }
  158. func BenchmarkNegELEMENT(b *testing.B) {
  159. benchResElement.SetRandom()
  160. b.ResetTimer()
  161. for i := 0; i < b.N; i++ {
  162. benchResElement.Neg(&benchResElement)
  163. }
  164. }
  165. func BenchmarkDivELEMENT(b *testing.B) {
  166. var x Element
  167. x.SetRandom()
  168. benchResElement.SetRandom()
  169. b.ResetTimer()
  170. for i := 0; i < b.N; i++ {
  171. benchResElement.Div(&x, &benchResElement)
  172. }
  173. }
  174. func BenchmarkFromMontELEMENT(b *testing.B) {
  175. benchResElement.SetRandom()
  176. b.ResetTimer()
  177. for i := 0; i < b.N; i++ {
  178. benchResElement.FromMont()
  179. }
  180. }
  181. func BenchmarkToMontELEMENT(b *testing.B) {
  182. benchResElement.SetRandom()
  183. b.ResetTimer()
  184. for i := 0; i < b.N; i++ {
  185. benchResElement.ToMont()
  186. }
  187. }
  188. func BenchmarkSquareELEMENT(b *testing.B) {
  189. benchResElement.SetRandom()
  190. b.ResetTimer()
  191. for i := 0; i < b.N; i++ {
  192. benchResElement.Square(&benchResElement)
  193. }
  194. }
  195. func BenchmarkMulAssignELEMENT(b *testing.B) {
  196. x := Element{
  197. 1997599621687373223,
  198. 6052339484930628067,
  199. 10108755138030829701,
  200. 150537098327114917,
  201. }
  202. benchResElement.SetOne()
  203. b.ResetTimer()
  204. for i := 0; i < b.N; i++ {
  205. benchResElement.MulAssign(&x)
  206. }
  207. }