| 
					
				 | 
			
			
				@@ -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() 
			 |