123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- import random
- from point import Point
- from crypt import CipherAES
- class Curve:
-
- def __init__(self, p, a, b, gx, gy, n, h):
- # размер конечного поля
- self.p = p
- # коэффиценты уравнения a и b
- self.a = a
- self.b = b
- # базовая точка, определяющая подгруппу
- self.g = Point(
- curve = self,
- x = gx,
- y = gy
- )
- # порядок подруппы
- self.n = n
- # кофактор подгруппы
- self.h = h
- def point(self, x, y):
- return Point(
- curve = self,
- x = x,
- y = y
- )
- # Обратное деление по модулю p
- def inverseMod(self, k, point):
- if k == 0:
- raise ZeroDivisionError('Деление на 0 невозможно!!!')
- if k < 0:
- # k ** -1 = p - (-k) ** -1 (mod p)
- return point - self.inverseMod(-k, point)
- # Расширенный алгоритм Евклида
- s, old_s = 0, 1
- t, old_t = 1, 0
- r, old_r = point, k
- while r != 0:
- quotient = old_r // r
- old_r, r = r, old_r - quotient * r
- old_s, s = s, old_s - quotient * s
- old_t, t = t, old_t - quotient * t
- gcd, x, y = old_r, old_s, old_t
- return x % point
- def randomKeypair(self):
- keyPriv = random.randrange(1, self.n)
- keyPub = self.g * keyPriv
- return keyPriv, keyPub
- # Создание публичного ключа из приватного
- def keyPub(self, keyPriv):
- # Результат - умножение точки подгруппы на приватный ключ
- return self.g * keyPriv
- # Вычисление общего секретного ключа, по которому производится шифрование и расшифровка сообщений
- def pointSecret(self, myKeyPrivate, friendKeyPublic):
- return friendKeyPublic * myKeyPrivate
- # Шифровка сообщения секретным ключем
- def encodeMessage(self, secretPoint, text):
- cipher = CipherAES(self, secretPoint)
- return cipher.encrypt(text)
- # Расшифровка сообщения секретным ключем
- def decodeMessage(self, secretPoint, encodedText):
- cipher = CipherAES(self, secretPoint)
- return cipher.decrypt(encodedText)
-
- #################################
- # Тестирование
- if __name__ == '__main__':
- # Создание объекта эллиптической кривой (кривая из исходников openssl)
- cur = Curve(
- # Размер конечного поля
- p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f,
- # Коэффиценты
- a = 0,
- b = 7,
- # Координаты точки, определяющей подгруппу
- gx = 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,
- gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8,
- # Размер подгруппы
- n = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141,
- # Кофактор подгруппы
- h = 1
- )
- # В зашифрованном обмене данными принимают участие 2 пользователя.
- # Далее - п1 (пользователь 1) и п2 (пользователь 2)
- # Каждый из пользовательей должен создать свою пару ключей (приватный и публичный) исходя из параметров одной эллиптической кривой
- # Создание пары ключей п1
- p1KeyPriv, p1KeyPub = cur.randomKeypair()
- # Создание пары ключей п2
- p2KeyPriv, p2KeyPub = cur.randomKeypair()
- # Предположим, что п1 и п2 обменялись публичными ключами
- # Далее каждый из них может рассчитать общий секретный ключ, используя свой приватный ключ и полученный публичный ключ контрагента
- # Секретный ключ идентичен для п1 и п2 и используется в качестве ключа в алгоритме симметричного шифрования, который используется
- # для шифровки и расшифровки сообщений
-
- # Расчет секретного ключа п1
- p1KeySecret = cur.pointSecret(p1KeyPriv, p2KeyPub)
- # Расчет секретного ключа п2
- p2KeySecret = cur.pointSecret(p2KeyPriv, p1KeyPub)
- # Покажем, что полученные секретные ключи идентичны у п1 и п2
- print(p1KeySecret.isEqual(p2KeySecret))
- # Далее п1 отправляет зашифрованное сообщение п2
- p1MessageEncrypted = cur.encodeMessage(p1KeySecret, 'Привет, как дела?')
- #Покажем зашифрованное сообщение
- print("п1: ", p1MessageEncrypted)
- # п2 расшифровывает полученное сообщение
- p1MessageDecrypted = cur.decodeMessage(p2KeySecret, p1MessageEncrypted)
- # Покажем расшифрованное сообщение
- print("п1: ", p1MessageDecrypted)
- # п2 отправляет зашифрованным сообщением п1
- p2MessageEncrypted = cur.encodeMessage(p2KeySecret, 'Спасибо, у меня всё хорошо :)')
- #Покажем зашифрованное сообщение
- print("п2: ", p2MessageEncrypted)
- # п1 расшифровывает полученное сообщение
- p2MessageDecrypted = cur.decodeMessage(p1KeySecret, p2MessageEncrypted)
- # Покажем расшифрованное сообщение
- print("п2: ", p2MessageDecrypted)
|