tools.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. package curve
  2. import (
  3. "context"
  4. "errors"
  5. "math/big"
  6. "math/rand"
  7. "time"
  8. )
  9. var (
  10. rnd = rand.New(rand.NewSource(time.Now().UnixNano())) // Генератор случайных чисел
  11. intZero = big.NewInt(0)
  12. intMax, _ = new(big.Int).SetString("9223372036854775807", 10)
  13. )
  14. func intCopy(val *big.Int) (res *big.Int) {
  15. if val != nil {
  16. res = new(big.Int).Set(val)
  17. }
  18. return
  19. }
  20. // Возвращает число или 0 при пустом указателе
  21. func mustBigInt(val *big.Int) (res *big.Int) {
  22. res = val
  23. if res == nil {
  24. res = big.NewInt(0)
  25. }
  26. return res
  27. }
  28. func IsPrime(val *big.Int) bool {
  29. return val.ProbablyPrime(100)
  30. }
  31. func SearchP(min *big.Int, ctx context.Context) (p *big.Int, g *big.Int, err error) {
  32. ch := make(chan struct{})
  33. go func() {
  34. defer func() {
  35. close(ch)
  36. }()
  37. p = intCopy(min)
  38. var check bool
  39. for {
  40. select {
  41. case <-ctx.Done():
  42. err = errors.New("Поиск поля и первообразного корня - время вышло")
  43. return
  44. default:
  45. if g, check = CheckP(p); check {
  46. ch <- struct{}{}
  47. return
  48. }
  49. p = Add64(p, 1)
  50. }
  51. }
  52. }()
  53. <-ch
  54. return
  55. }
  56. func CheckP(val *big.Int) (res *big.Int, check bool) {
  57. if IsPrime(val) {
  58. //log.Println("PRIME", val, Div64(Sub64(val, 1), 2))
  59. res = Div64(Sub64(val, 1), 2)
  60. check = IsPrime(res)
  61. }
  62. return
  63. }
  64. func SearchPrime(val *big.Int) *big.Int {
  65. rVal := new(big.Int).Set(val)
  66. //log.Println(rVal)
  67. for {
  68. if rVal.ProbablyPrime(100) {
  69. break
  70. }
  71. rVal.Add(rVal, big.NewInt(1))
  72. //log.Println(rVal)
  73. }
  74. return rVal
  75. }
  76. func Random(min, max *big.Int) *big.Int {
  77. if min == nil {
  78. min = intZero
  79. }
  80. if max == nil {
  81. max = intMax
  82. }
  83. res := new(big.Int).Rand(rnd, max)
  84. for res.Cmp(min) == -1 {
  85. res = new(big.Int).Rand(rnd, max)
  86. }
  87. return res
  88. }