package main import ( "context" "log" "math/big" "sync" "time" "git.ali33.ru/fcg-xvii/curve/v2" "git.ali33.ru/fcg-xvii/curve/v2/dhellman" "git.ali33.ru/fcg-xvii/curve/v2/elgamal" "git.ali33.ru/fcg-xvii/curve/v2/tools" "git.ali33.ru/fcg-xvii/go-tools/json" ) func EventSingle(Type, method string, contextID int) *Event { res := &Event{ ContextID: contextID, Type: Type, Value: json.Map{}, } if len(method) > 0 { res.Value["method"] = method } return res } type Event struct { ContextID int Type string IsError bool Value json.Map } func (s *Event) Map() json.Map { return json.Map{ "context_id": s.ContextID, "type": "event", "name": s.Type, "is_error": s.IsError, "data": s.Value, } } func (s *Event) MarshalJSON() ([]byte, error) { return s.Map().JSON(), nil } func (s *Event) String() string { return s.Map().JSONPrettyString() } func MethodExec(p1, p2 curve.KeyPair, ch chan<- *Event, ctx context.Context, message, method string, contextID int) { // генерация ключей t := time.Now() encoded, _ := p1.MessageEncode([]byte(message), p2.KeyPublic()) select { case <-ctx.Done(): return default: ch <- &Event{ ContextID: contextID, Type: "Сообщение зашифровано пользователем 1", Value: json.Map{ "method": method, "text": message, "encoded": encoded.Encoded(), "time": int64(time.Since(t) / time.Millisecond), }, } } t = time.Now() decoded, _ := p2.MessageDecode(encoded, p1.KeyPublic()) select { case <-ctx.Done(): return default: ch <- &Event{ ContextID: contextID, Type: "Сообщение расшифровано пользователем 2", Value: json.Map{ "method": method, "text": message, "decoded": string(decoded), "time": int64(time.Since(t) / time.Millisecond), }, } } // Атака посредника. ch <- EventSingle("Атака посредника. Запущен подбор ключа", method, contextID) t = time.Now() if aPair, err := p2.KeyPublic().Attack(ctx); err != nil { ch <- &Event{ ContextID: contextID, Type: "Атака посредника", IsError: true, Value: json.Map{ "method": method, "text": err.Error(), }, } } else { decoded, _ = aPair.MessageDecode(encoded, p1.KeyPublic()) ch <- &Event{ ContextID: contextID, Type: "Атака посредника. Ключ найден", Value: json.Map{ "method": method, "pair": p2, "cracked": aPair, "time": int64(time.Since(t) / time.Millisecond), "source": message, "decoded": string(decoded), }, } } } func MethodCurve(randNum *big.Int, message string, ctx context.Context, contextID int) <-chan *Event { ch := make(chan *Event) go func() { defer close(ch) // Поиск параметров кривой a, b, p := tools.CurveRandomParams(randNum) select { case <-ctx.Done(): return default: ch <- &Event{ ContextID: contextID, Type: "Параметры кривой определены", Value: json.Map{ "a": a, "b": b, "p": p, }, } } ch <- EventSingle("Инициализация кривой", "", contextID) t := time.Now() c, err := curve.NewCurve(a, b, p, ctx) if err != nil { ch <- &Event{ ContextID: contextID, Type: "Инициализация кривой", IsError: true, Value: json.Map{ "text": err.Error(), }, } return } ch <- &Event{ ContextID: contextID, Type: "Кривая инициализирована", Value: json.Map{ "g": c.G(), "time": int64(time.Since(t) / time.Millisecond), }, } var wg sync.WaitGroup wg.Add(2) // метод Диффи-Хеллмана go func() { defer wg.Done() // Генерация ключей ch <- EventSingle("Генерация пар ключей", "Диффи-Хеллман", contextID) t := time.Now() p1, _ := dhellman.CurveKeyPair(c) p2, _ := dhellman.CurveKeyPair(c) select { case <-ctx.Done(): return default: ch <- &Event{ ContextID: contextID, Type: "Пары ключей сгенерированы", Value: json.Map{ "method": "Диффи-Хеллман", "u1": p1, "u2": p2, "time": int64(time.Since(t) / time.Millisecond), }, } } MethodExec(p1, p2, ch, ctx, message, "Диффи-Хеллман", contextID) }() // метод Эль-Гамаля go func() { defer wg.Done() // Генерация таблицы ch <- EventSingle("Построение таблицы (символ) -> (точка на кривой) для шифрования/расшифровки сообщений", "Эль-Гамаль", contextID) t := time.Now() cc, err := elgamal.NewCurve(c, ctx) if err != nil { ch <- &Event{ ContextID: contextID, Type: "Построение таблицы (символ) -> (точка на кривой) для шифрования/расшифровки сообщений", IsError: true, Value: json.Map{ "method": "Эль-Гамаль", "text": err.Error(), }, } return } ch <- &Event{ ContextID: contextID, Type: "Тиблица символов построена", Value: json.Map{ "method": "Эль-Гамаль", "time": int64(time.Since(t) / time.Millisecond), "curve": cc.Map(), }, } ch <- EventSingle("Генерация пар ключей", "Эль-Гамаль", contextID) t = time.Now() p1, _ := elgamal.CurveKeyPair(cc, ctx) p2, _ := elgamal.CurveKeyPair(cc, ctx) select { case <-ctx.Done(): return default: ch <- &Event{ ContextID: contextID, Type: "Пары ключей сгенерированы", Value: json.Map{ "method": "Эль-Гамаль", "u1": p1, "u2": p2, "time": int64(time.Since(t) / time.Millisecond), }, } } MethodExec(p1, p2, ch, ctx, message, "Эль-Гамаль", contextID) }() wg.Wait() ch <- EventSingle("Все работы завершены.", "", contextID) log.Println("FINISH") contextStore.Delete(contextID) }() return ch }