|
@@ -0,0 +1,181 @@
|
|
|
+from curve import Curve
|
|
|
+import tools, random
|
|
|
+
|
|
|
+# Глобальные переменные эллептической кривой и пользовательских ключей
|
|
|
+cur = None
|
|
|
+p1KeyPriv = p1KeyPub = None
|
|
|
+p2KeyPriv = p2KeyPub = None
|
|
|
+
|
|
|
+# Проверка ввода целого числа
|
|
|
+def readInteger(text):
|
|
|
+ if len(text) > 0:
|
|
|
+ text += ': '
|
|
|
+ try:
|
|
|
+ return int(input(text))
|
|
|
+ except:
|
|
|
+ return None
|
|
|
+
|
|
|
+# Цикличная проверка ввода целого числа
|
|
|
+def readIntregerCycle(text):
|
|
|
+ res = None
|
|
|
+ while res is None:
|
|
|
+ res = readInteger(text)
|
|
|
+ if res is None:
|
|
|
+ print('Укажите целое число')
|
|
|
+ return res
|
|
|
+
|
|
|
+# Установка точки g эллиптической кривой
|
|
|
+def setupG(g):
|
|
|
+ cur.g = g
|
|
|
+ print('Точка g установлена. Вычисляется порядок подгруппы. Пожалуйста, подождите.')
|
|
|
+ cur.setupN()
|
|
|
+ input('Порядок подгруппы вычислен. Для продолжания нажмите ввод. ')
|
|
|
+
|
|
|
+# Вывод информции об эллиптической кривой
|
|
|
+def curveInfo():
|
|
|
+ print('Эллиптическая кривая:')
|
|
|
+ if cur == None:
|
|
|
+ print('Не определена')
|
|
|
+ return
|
|
|
+ print('Уравнение: y² = x³ + {}x + {}'.format(cur.a, cur.b))
|
|
|
+ print('Размер конечного поля: {}'.format(cur.p))
|
|
|
+ if cur.g.isNone():
|
|
|
+ print('Точка g не определена')
|
|
|
+ else:
|
|
|
+ print('Точка g: ({}, {})'.format(cur.g.x, cur.g.y))
|
|
|
+ if cur.n is None:
|
|
|
+ print('Порядок подгруппы (n) не определен')
|
|
|
+ else:
|
|
|
+ print('Порядок подгруппы (n): {}'.format(cur.n))
|
|
|
+ print('>>>>>>>>>>>>>>>>>>>>>>>>>')
|
|
|
+ if p1KeyPriv is None:
|
|
|
+ print('Пары ключей пользователей не определены')
|
|
|
+ else:
|
|
|
+ print('Пары ключей пользователей сгенерированы')
|
|
|
+ print('Пользователь 1 - priv: {}, pub ({}, {})'.format(p1KeyPriv, p1KeyPub.x, p1KeyPub.y))
|
|
|
+ print('Пользователь 2 - priv: {}, pub ({}, {})'.format(p2KeyPriv, p2KeyPub.x, p2KeyPub.y))
|
|
|
+ print('>>>>>>>>>>>>>>>>>>>>>>>>>')
|
|
|
+
|
|
|
+# Инициализиция эллиптической кривой
|
|
|
+def initCurve():
|
|
|
+ global cur
|
|
|
+ a = b = p = None
|
|
|
+ print('Укажите параметры эллиптической кривой:')
|
|
|
+ while True:
|
|
|
+ a = readIntregerCycle('a (коэффицент, целое число)')
|
|
|
+ b = readIntregerCycle('b (коэффицент, целое число)')
|
|
|
+ if tools.isCurveSingular(a, b):
|
|
|
+ mes = 'Кривая сингулярна (4a³ + 27b² = 0). Указать новые параметры кривой? [y/n] '
|
|
|
+ answ = input(mes)
|
|
|
+ if answ.lower() != 'y':
|
|
|
+ return
|
|
|
+ else:
|
|
|
+ break
|
|
|
+ while True:
|
|
|
+ p = readIntregerCycle('p (размер конечного поля, целое простое число)')
|
|
|
+ pp = tools.searchPrime(p)
|
|
|
+ if p != pp:
|
|
|
+ print('Число [{}] не является простым. Ближайшее простое число - [{}]'.format(p, pp))
|
|
|
+ answ = input('Установить число [{}] в качестве p эллептической кривой? [y/n] '.format(pp))
|
|
|
+ if answ.lower() == 'y':
|
|
|
+ p = pp
|
|
|
+ break
|
|
|
+ else:
|
|
|
+ break
|
|
|
+ cur = Curve(p, a, b)
|
|
|
+
|
|
|
+# Обработка ввода в главном меню
|
|
|
+def readMainMenu():
|
|
|
+ global cur
|
|
|
+ global p1KeyPriv
|
|
|
+ global p1KeyPub
|
|
|
+ global p2KeyPriv
|
|
|
+ global p2KeyPub
|
|
|
+ num = readInteger('>> ')
|
|
|
+ if num == 9:
|
|
|
+ exit(0)
|
|
|
+ if cur is None:
|
|
|
+ if num == 1:
|
|
|
+ initCurve()
|
|
|
+ else:
|
|
|
+ if num == 1:
|
|
|
+ cur = None
|
|
|
+ return
|
|
|
+ if cur.g.isNone():
|
|
|
+ if num == 2:
|
|
|
+ print('Вычисляется точка g. Пожалуйста, подождите.')
|
|
|
+ cur.setupGAuto()
|
|
|
+ setupG(cur.g)
|
|
|
+ elif num == 3:
|
|
|
+ while True:
|
|
|
+ x = readIntregerCycle('Укажите x (целое число)')
|
|
|
+ y = readIntregerCycle('Укажите y (целое число)')
|
|
|
+ p = cur.point(x, y)
|
|
|
+ if not p.isInCurve():
|
|
|
+ answ = input('Точка ({}, {}) не расположена на данной кривой. Указать другую точку? (y/n): '.format(p.x, p.y))
|
|
|
+ if answ.lower() != 'y':
|
|
|
+ break
|
|
|
+ else:
|
|
|
+ setupG()
|
|
|
+ break
|
|
|
+ elif num == 4:
|
|
|
+ rnd = random.randrange(1, cur.p - 1)
|
|
|
+ p1, p2 = cur.searchClosePoints(rnd)
|
|
|
+ print(p1.coords(), p2.coords())
|
|
|
+ readMainMenu()
|
|
|
+ else:
|
|
|
+ if p1KeyPriv is None:
|
|
|
+ if num == 2:
|
|
|
+ print('Генерация ключей для пользователя 1...')
|
|
|
+ p1KeyPriv, p1KeyPub = cur.randomKeypair()
|
|
|
+ print('Готово. p1KeyPriv: {}, p1KeyPub ({}, {})'.format(p1KeyPriv, p1KeyPub.x, p1KeyPub.y))
|
|
|
+ print('Генерация ключей для пользователя 2...')
|
|
|
+ p2KeyPriv, p2KeyPub = cur.randomKeypair()
|
|
|
+ print('Готово. p2KeyPriv: {}, p2KeyPub ({}, {})'.format(p2KeyPriv, p2KeyPub.x, p1KeyPub.y))
|
|
|
+ else:
|
|
|
+ if num == 2:
|
|
|
+ message = ""
|
|
|
+ while True:
|
|
|
+ message = input('Введите текстовое сообщение: ')
|
|
|
+ if len(message) == 0:
|
|
|
+ print('Сообщение пустое. Введите непустое сообщение.')
|
|
|
+ else:
|
|
|
+ break
|
|
|
+ print(p1KeyPriv, p2KeyPub)
|
|
|
+ p1KeySecret = cur.pointSecret(p1KeyPriv, p2KeyPub)
|
|
|
+ print('Секретный ключ пользователя 1: ({}, {})'.format(p1KeySecret.x, p1KeySecret.y))
|
|
|
+ p2KeySecret = cur.pointSecret(p2KeyPriv, p1KeyPub)
|
|
|
+ print('Секретный ключ пользователя 2: ({}, {})'.format(p2KeySecret.x, p2KeySecret.y))
|
|
|
+ p1MessageEncrypted = cur.encodeMessage(p1KeySecret, message)
|
|
|
+ print("Зашифрованное сообщение пользователем 1: {}".format(p1MessageEncrypted))
|
|
|
+ p1MessageDecrypted = cur.decodeMessage(p2KeySecret, p1MessageEncrypted)
|
|
|
+ print("Расшифрованное сообщение пользователем 2: {}".format(p1MessageDecrypted))
|
|
|
+ input('Демонстрация завершена. Для продолжения нажмите ввод.')
|
|
|
+
|
|
|
+# Вывод главного меню
|
|
|
+def mainMenu():
|
|
|
+ curveInfo()
|
|
|
+ print('')
|
|
|
+ print('Укажите пункт меню:')
|
|
|
+ if cur is None:
|
|
|
+ print('1) Определить эллиптическую кривую')
|
|
|
+ else:
|
|
|
+ print('1) Сбросить параметры эллептической кривой')
|
|
|
+ if cur.g.isNone():
|
|
|
+ print('2) Установить случайную точку g')
|
|
|
+ print('3) Указать координату точки g вручную')
|
|
|
+ print('4) Найти и показать случайную пару точек')
|
|
|
+ else:
|
|
|
+ if p1KeyPriv is None:
|
|
|
+ print('2) Сгенерировать ключевые пары пользователей')
|
|
|
+ else:
|
|
|
+ print('2) Демонстрация работы шифрования')
|
|
|
+ print('9) Выход из программы')
|
|
|
+ readMainMenu()
|
|
|
+ print('')
|
|
|
+ print('+++++++++++++++++++++++++++++++++')
|
|
|
+ print('')
|
|
|
+
|
|
|
+# Главный цикл программы
|
|
|
+while True:
|
|
|
+ mainMenu()
|