set.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. package tools
  2. import (
  3. "context"
  4. "errors"
  5. "math/big"
  6. "git.ali33.ru/fcg-xvii/go-tools/json"
  7. )
  8. func NewCrypt(conf json.Map, ctx context.Context) (res *Crypt, err error) {
  9. var p *big.Int
  10. var check bool
  11. if conf.KeyExists("p") {
  12. p, check = big.NewInt(0).SetString(conf.String("p", ""), 10)
  13. if !check {
  14. return nil, errors.New(`ожидается строка числового значения p > 0 в поле [ p ], например "1234"`)
  15. }
  16. if p.Cmp(intZero) <= 0 {
  17. return nil, errors.New(`ожидается строка числового значения p > 0 в поле [ p ], например "1234"`)
  18. }
  19. }
  20. res = new(Crypt)
  21. err = res.Init(p, ctx)
  22. return
  23. }
  24. type Crypt struct {
  25. p *big.Int
  26. g *big.Int
  27. }
  28. func (s *Crypt) IsValid() bool {
  29. return s.p != nil
  30. }
  31. func (s *Crypt) Init(p *big.Int, ctx context.Context) (err error) {
  32. if s.p != nil {
  33. return errors.New("параметры криптографии инициированы были инициализированы ранее")
  34. }
  35. if p == nil {
  36. //p = Random(valMin, max)
  37. p = Random(valMin, maxTest)
  38. }
  39. s.p, s.g, err = SearchP(p, ctx)
  40. return
  41. }
  42. func (s *Crypt) Keys(key *big.Int, ctx context.Context) *KeyPair {
  43. if !s.IsValid() {
  44. s.Init(nil, ctx)
  45. }
  46. priv := &KeyPrivate{
  47. key: key,
  48. c: s,
  49. }
  50. pub := &KeyPublic{
  51. key: Exp(s.g, priv.key, s.p),
  52. c: s,
  53. }
  54. res := &KeyPair{
  55. priv: priv,
  56. pub: pub,
  57. }
  58. return res
  59. }
  60. func (s *Crypt) KeysGenerate(ctx context.Context) *KeyPair {
  61. return s.Keys(Random(big.NewInt(1), Sub64(s.p, 1)), ctx)
  62. }
  63. func (s *Crypt) BrutforceKey(pub *KeyPublic, threads int, ctx context.Context) (res *KeyPair, err error) {
  64. if threads < 0 {
  65. threads = 1
  66. } else if threads > 5 {
  67. threads = 5
  68. }
  69. ch := make(chan *KeyPair)
  70. cctx, cancel := context.WithCancel(ctx)
  71. parts := Split(s.p, threads, big.NewInt(1), big.NewInt(1))
  72. for i := 0; i < threads; i++ {
  73. go func(part []*big.Int) {
  74. cur, finish := intCopy(part[0]), part[1]
  75. for {
  76. select {
  77. case <-cctx.Done():
  78. return
  79. case <-ctx.Done():
  80. return
  81. default:
  82. if cur.Cmp(finish) <= 0 {
  83. pair := s.Keys(cur, ctx)
  84. if pair.pub.IsEqual(pub) {
  85. ch <- pair
  86. return
  87. }
  88. cur = Add64(cur, 1)
  89. } else {
  90. return
  91. }
  92. }
  93. }
  94. }(parts[i])
  95. }
  96. defer cancel()
  97. select {
  98. case res = <-ch:
  99. case <-ctx.Done():
  100. err = errors.New("Атака грубой силы не удалась - время вышло")
  101. }
  102. return
  103. }
  104. //////////////////////////////
  105. type KeyPair struct {
  106. priv *KeyPrivate
  107. pub *KeyPublic
  108. }
  109. type KeyPrivate struct {
  110. key *big.Int
  111. c *Crypt
  112. }
  113. func (s *KeyPrivate) MessageDecode(mes *Message) ([]byte, error) {
  114. sl := Exp(mes.a, s.key, s.c.p)
  115. if sl.ModInverse(sl, s.c.p) == nil {
  116. return nil, errors.New("Ощиюбка расшифровки сообщения: некорректный приватный ключ")
  117. }
  118. data := make([]byte, len(mes.encrypted))
  119. for i, e := range mes.encrypted {
  120. part := Mul(sl, e)
  121. data[i] = Mod(part, s.c.p).Bytes()[0]
  122. }
  123. return data, nil
  124. }
  125. type KeyPublic struct {
  126. key *big.Int
  127. c *Crypt
  128. }
  129. func (s *KeyPublic) IsEqual(c *KeyPublic) bool {
  130. return s.key.Cmp(c.key) == 0
  131. }
  132. func (s *KeyPublic) MessageEncode(data []byte) (res *Message) {
  133. k := Random(big.NewInt(1), Sub64(s.c.p, 20))
  134. k = SearchPrime(k)
  135. //k := big.NewInt(2)
  136. res = &Message{
  137. a: Exp(s.c.g, k, s.c.p),
  138. encrypted: make([]*big.Int, len(data)),
  139. }
  140. sl := Exp(s.key, k, s.c.p)
  141. for i, b := range data {
  142. part := Mul(sl, big.NewInt(int64(b)))
  143. res.encrypted[i] = Mod(part, s.c.p)
  144. }
  145. return
  146. }
  147. //////////////////////////////
  148. type Message struct {
  149. a *big.Int
  150. encrypted []*big.Int
  151. }