elgamal.go 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. package curve
  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. }
  152. /*
  153. // PublicKey represents an ElGamal public key.
  154. type PublicKey struct {
  155. G, P, Y *big.Int
  156. }
  157. // PrivateKey represents an ElGamal private key.
  158. type PrivateKey struct {
  159. PublicKey
  160. X *big.Int
  161. }
  162. // Encrypt encrypts the given message to the given public key. The result is a
  163. // pair of integers. Errors can result from reading random, or because msg is
  164. // too large to be encrypted to the public key.
  165. func Encrypt(random io.Reader, pub *PublicKey, msg []byte) (c1, c2 *big.Int, err error) {
  166. pLen := (pub.P.BitLen() + 7) / 8
  167. log.Println(pLen, len(msg))
  168. if len(msg) > pLen-11 {
  169. err = errors.New("elgamal: message too long")
  170. return
  171. }
  172. // EM = 0x02 || PS || 0x00 || M
  173. em := make([]byte, pLen-1)
  174. em[0] = 2
  175. ps, mm := em[1:len(em)-len(msg)-1], em[len(em)-len(msg):]
  176. err = nonZeroRandomBytes(ps, random)
  177. if err != nil {
  178. return
  179. }
  180. em[len(em)-len(msg)-1] = 0
  181. copy(mm, msg)
  182. m := new(big.Int).SetBytes(em)
  183. k, err := rand.Int(random, pub.P)
  184. if err != nil {
  185. return
  186. }
  187. log.Println("Y", pub.Y)
  188. c1 = new(big.Int).Exp(pub.G, k, pub.P)
  189. s := new(big.Int).Exp(pub.Y, k, pub.P)
  190. c2 = s.Mul(s, m)
  191. c2.Mod(c2, pub.P)
  192. return
  193. }
  194. // Decrypt takes two integers, resulting from an ElGamal encryption, and
  195. // returns the plaintext of the message. An error can result only if the
  196. // ciphertext is invalid. Users should keep in mind that this is a padding
  197. // oracle and thus, if exposed to an adaptive chosen ciphertext attack, can
  198. // be used to break the cryptosystem. See “Chosen Ciphertext Attacks
  199. // Against Protocols Based on the RSA Encryption Standard PKCS #1”, Daniel
  200. // Bleichenbacher, Advances in Cryptology (Crypto '98),
  201. func Decrypt(priv *PrivateKey, c1, c2 *big.Int) (msg []byte, err error) {
  202. s := new(big.Int).Exp(c1, priv.X, priv.P)
  203. if s.ModInverse(s, priv.P) == nil {
  204. return nil, errors.New("elgamal: invalid private key")
  205. }
  206. s.Mul(s, c2)
  207. s.Mod(s, priv.P)
  208. em := s.Bytes()
  209. firstByteIsTwo := subtle.ConstantTimeByteEq(em[0], 2)
  210. // The remainder of the plaintext must be a string of non-zero random
  211. // octets, followed by a 0, followed by the message.
  212. // lookingForIndex: 1 iff we are still looking for the zero.
  213. // index: the offset of the first zero byte.
  214. var lookingForIndex, index int
  215. lookingForIndex = 1
  216. for i := 1; i < len(em); i++ {
  217. equals0 := subtle.ConstantTimeByteEq(em[i], 0)
  218. index = subtle.ConstantTimeSelect(lookingForIndex&equals0, i, index)
  219. lookingForIndex = subtle.ConstantTimeSelect(equals0, 0, lookingForIndex)
  220. }
  221. if firstByteIsTwo != 1 || lookingForIndex != 0 || index < 9 {
  222. return nil, errors.New("elgamal: decryption error")
  223. }
  224. return em[index+1:], nil
  225. }
  226. // nonZeroRandomBytes fills the given slice with non-zero random octets.
  227. func nonZeroRandomBytes(s []byte, rand io.Reader) (err error) {
  228. _, err = io.ReadFull(rand, s)
  229. if err != nil {
  230. return
  231. }
  232. for i := 0; i < len(s); i++ {
  233. for s[i] == 0 {
  234. _, err = io.ReadFull(rand, s[i:i+1])
  235. if err != nil {
  236. return
  237. }
  238. }
  239. }
  240. return
  241. }
  242. */