method.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. package main
  2. import (
  3. "context"
  4. "log"
  5. "math/big"
  6. "sync"
  7. "time"
  8. "git.ali33.ru/fcg-xvii/curve/v2"
  9. "git.ali33.ru/fcg-xvii/curve/v2/dhellman"
  10. "git.ali33.ru/fcg-xvii/curve/v2/elgamal"
  11. "git.ali33.ru/fcg-xvii/curve/v2/tools"
  12. "git.ali33.ru/fcg-xvii/go-tools/json"
  13. )
  14. func EventSingle(Type, method string, contextID int) *Event {
  15. res := &Event{
  16. ContextID: contextID,
  17. Type: Type,
  18. Value: json.Map{},
  19. }
  20. if len(method) > 0 {
  21. res.Value["method"] = method
  22. }
  23. return res
  24. }
  25. type Event struct {
  26. ContextID int
  27. Type string
  28. IsError bool
  29. Value json.Map
  30. }
  31. func (s *Event) Map() json.Map {
  32. return json.Map{
  33. "context_id": s.ContextID,
  34. "type": "event",
  35. "name": s.Type,
  36. "is_error": s.IsError,
  37. "data": s.Value,
  38. }
  39. }
  40. func (s *Event) MarshalJSON() ([]byte, error) {
  41. return s.Map().JSON(), nil
  42. }
  43. func (s *Event) String() string {
  44. return s.Map().JSONPrettyString()
  45. }
  46. func MethodExec(p1, p2 curve.KeyPair, ch chan<- *Event, ctx context.Context, message, method string, contextID int) {
  47. // генерация ключей
  48. t := time.Now()
  49. encoded, _ := p1.MessageEncode([]byte(message), p2.KeyPublic())
  50. select {
  51. case <-ctx.Done():
  52. return
  53. default:
  54. ch <- &Event{
  55. ContextID: contextID,
  56. Type: "Сообщение зашифровано пользователем 1",
  57. Value: json.Map{
  58. "method": method,
  59. "text": message,
  60. "encoded": encoded.Encoded(),
  61. "time": int64(time.Since(t) / time.Millisecond),
  62. },
  63. }
  64. }
  65. t = time.Now()
  66. decoded, _ := p2.MessageDecode(encoded, p1.KeyPublic())
  67. select {
  68. case <-ctx.Done():
  69. return
  70. default:
  71. ch <- &Event{
  72. ContextID: contextID,
  73. Type: "Сообщение расшифровано пользователем 2",
  74. Value: json.Map{
  75. "method": method,
  76. "text": message,
  77. "decoded": string(decoded),
  78. "time": int64(time.Since(t) / time.Millisecond),
  79. },
  80. }
  81. }
  82. // Атака посредника.
  83. ch <- EventSingle("Атака посредника. Запущен подбор ключа", method, contextID)
  84. t = time.Now()
  85. if aPair, err := p2.KeyPublic().Attack(ctx); err != nil {
  86. ch <- &Event{
  87. ContextID: contextID,
  88. Type: "Атака посредника",
  89. IsError: true,
  90. Value: json.Map{
  91. "method": method,
  92. "text": err.Error(),
  93. },
  94. }
  95. } else {
  96. decoded, _ = aPair.MessageDecode(encoded, p1.KeyPublic())
  97. ch <- &Event{
  98. ContextID: contextID,
  99. Type: "Атака посредника. Ключ найден",
  100. Value: json.Map{
  101. "method": method,
  102. "pair": p2,
  103. "cracked": aPair,
  104. "time": int64(time.Since(t) / time.Millisecond),
  105. "source": message,
  106. "decoded": string(decoded),
  107. },
  108. }
  109. }
  110. }
  111. func MethodCurve(randNum *big.Int, message string, ctx context.Context, contextID int) <-chan *Event {
  112. ch := make(chan *Event)
  113. go func() {
  114. defer close(ch)
  115. // Поиск параметров кривой
  116. a, b, p := tools.CurveRandomParams(randNum)
  117. select {
  118. case <-ctx.Done():
  119. return
  120. default:
  121. ch <- &Event{
  122. ContextID: contextID,
  123. Type: "Параметры кривой определены",
  124. Value: json.Map{
  125. "a": a,
  126. "b": b,
  127. "p": p,
  128. },
  129. }
  130. }
  131. ch <- EventSingle("Инициализация кривой", "", contextID)
  132. t := time.Now()
  133. c, err := curve.NewCurve(a, b, p, ctx)
  134. if err != nil {
  135. ch <- &Event{
  136. ContextID: contextID,
  137. Type: "Инициализация кривой",
  138. IsError: true,
  139. Value: json.Map{
  140. "text": err.Error(),
  141. },
  142. }
  143. return
  144. }
  145. ch <- &Event{
  146. ContextID: contextID,
  147. Type: "Кривая инициализирована",
  148. Value: json.Map{
  149. "g": c.G(),
  150. "time": int64(time.Since(t) / time.Millisecond),
  151. },
  152. }
  153. var wg sync.WaitGroup
  154. wg.Add(2)
  155. // метод Диффи-Хеллмана
  156. go func() {
  157. defer wg.Done()
  158. // Генерация ключей
  159. ch <- EventSingle("Генерация пар ключей", "Диффи-Хеллман", contextID)
  160. t := time.Now()
  161. p1, _ := dhellman.CurveKeyPair(c)
  162. p2, _ := dhellman.CurveKeyPair(c)
  163. select {
  164. case <-ctx.Done():
  165. return
  166. default:
  167. ch <- &Event{
  168. ContextID: contextID,
  169. Type: "Пары ключей сгенерированы",
  170. Value: json.Map{
  171. "method": "Диффи-Хеллман",
  172. "u1": p1,
  173. "u2": p2,
  174. "time": int64(time.Since(t) / time.Millisecond),
  175. },
  176. }
  177. }
  178. MethodExec(p1, p2, ch, ctx, message, "Диффи-Хеллман", contextID)
  179. }()
  180. // метод Эль-Гамаля
  181. go func() {
  182. defer wg.Done()
  183. // Генерация таблицы
  184. ch <- EventSingle("Построение таблицы (символ) -> (точка на кривой) для шифрования/расшифровки сообщений", "Эль-Гамаль", contextID)
  185. t := time.Now()
  186. cc, err := elgamal.NewCurve(c, ctx)
  187. if err != nil {
  188. ch <- &Event{
  189. ContextID: contextID,
  190. Type: "Построение таблицы (символ) -> (точка на кривой) для шифрования/расшифровки сообщений",
  191. IsError: true,
  192. Value: json.Map{
  193. "method": "Эль-Гамаль",
  194. "text": err.Error(),
  195. },
  196. }
  197. return
  198. }
  199. ch <- &Event{
  200. ContextID: contextID,
  201. Type: "Тиблица символов построена",
  202. Value: json.Map{
  203. "method": "Эль-Гамаль",
  204. "time": int64(time.Since(t) / time.Millisecond),
  205. "curve": cc.Map(),
  206. },
  207. }
  208. ch <- EventSingle("Генерация пар ключей", "Эль-Гамаль", contextID)
  209. t = time.Now()
  210. p1, _ := elgamal.CurveKeyPair(cc, ctx)
  211. p2, _ := elgamal.CurveKeyPair(cc, ctx)
  212. select {
  213. case <-ctx.Done():
  214. return
  215. default:
  216. ch <- &Event{
  217. ContextID: contextID,
  218. Type: "Пары ключей сгенерированы",
  219. Value: json.Map{
  220. "method": "Эль-Гамаль",
  221. "u1": p1,
  222. "u2": p2,
  223. "time": int64(time.Since(t) / time.Millisecond),
  224. },
  225. }
  226. }
  227. MethodExec(p1, p2, ch, ctx, message, "Эль-Гамаль", contextID)
  228. }()
  229. wg.Wait()
  230. ch <- EventSingle("Все работы завершены.", "", contextID)
  231. log.Println("FINISH")
  232. contextStore.Delete(contextID)
  233. }()
  234. return ch
  235. }