123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 |
- 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
- }
|