curve.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. import random
  2. from point import Point
  3. from crypt import CipherAES
  4. class Curve:
  5. def __init__(self, p, a, b, gx, gy, n, h):
  6. # размер конечного поля
  7. self.p = p
  8. # коэффиценты уравнения a и b
  9. self.a = a
  10. self.b = b
  11. # базовая точка, определяющая подгруппу
  12. self.g = Point(
  13. curve = self,
  14. x = gx,
  15. y = gy
  16. )
  17. # порядок подруппы
  18. self.n = n
  19. # кофактор подгруппы
  20. self.h = h
  21. def point(self, x, y):
  22. return Point(
  23. curve = self,
  24. x = x,
  25. y = y
  26. )
  27. # Обратное деление по модулю p
  28. def inverseMod(self, k, point):
  29. if k == 0:
  30. raise ZeroDivisionError('Деление на 0 невозможно!!!')
  31. if k < 0:
  32. # k ** -1 = p - (-k) ** -1 (mod p)
  33. return point - self.inverseMod(-k, point)
  34. # Расширенный алгоритм Евклида
  35. s, old_s = 0, 1
  36. t, old_t = 1, 0
  37. r, old_r = point, k
  38. while r != 0:
  39. quotient = old_r // r
  40. old_r, r = r, old_r - quotient * r
  41. old_s, s = s, old_s - quotient * s
  42. old_t, t = t, old_t - quotient * t
  43. gcd, x, y = old_r, old_s, old_t
  44. return x % point
  45. def randomKeypair(self):
  46. keyPriv = random.randrange(1, self.n)
  47. keyPub = self.g * keyPriv
  48. return keyPriv, keyPub
  49. # Создание публичного ключа из приватного
  50. def keyPub(self, keyPriv):
  51. # Результат - умножение точки подгруппы на приватный ключ
  52. return self.g * keyPriv
  53. # Вычисление общего секретного ключа, по которому производится шифрование и расшифровка сообщений
  54. def pointSecret(self, myKeyPrivate, friendKeyPublic):
  55. return friendKeyPublic * myKeyPrivate
  56. # Шифровка сообщения секретным ключем
  57. def encodeMessage(self, secretPoint, text):
  58. cipher = CipherAES(self, secretPoint)
  59. return cipher.encrypt(text)
  60. # Расшифровка сообщения секретным ключем
  61. def decodeMessage(self, secretPoint, encodedText):
  62. cipher = CipherAES(self, secretPoint)
  63. return cipher.decrypt(encodedText)
  64. #################################
  65. # Тестирование
  66. if __name__ == '__main__':
  67. # Создание объекта эллиптической кривой (кривая из исходников openssl)
  68. cur = Curve(
  69. # Размер конечного поля
  70. p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f,
  71. # Коэффиценты
  72. a = 0,
  73. b = 7,
  74. # Координаты точки, определяющей подгруппу
  75. gx = 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,
  76. gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8,
  77. # Размер подгруппы
  78. n = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141,
  79. # Кофактор подгруппы
  80. h = 1
  81. )
  82. # В зашифрованном обмене данными принимают участие 2 пользователя.
  83. # Далее - п1 (пользователь 1) и п2 (пользователь 2)
  84. # Каждый из пользовательей должен создать свою пару ключей (приватный и публичный) исходя из параметров одной эллиптической кривой
  85. # Создание пары ключей п1
  86. p1KeyPriv, p1KeyPub = cur.randomKeypair()
  87. # Создание пары ключей п2
  88. p2KeyPriv, p2KeyPub = cur.randomKeypair()
  89. # Предположим, что п1 и п2 обменялись публичными ключами
  90. # Далее каждый из них может рассчитать общий секретный ключ, используя свой приватный ключ и полученный публичный ключ контрагента
  91. # Секретный ключ идентичен для п1 и п2 и используется в качестве ключа в алгоритме симметричного шифрования, который используется
  92. # для шифровки и расшифровки сообщений
  93. # Расчет секретного ключа п1
  94. p1KeySecret = cur.pointSecret(p1KeyPriv, p2KeyPub)
  95. # Расчет секретного ключа п2
  96. p2KeySecret = cur.pointSecret(p2KeyPriv, p1KeyPub)
  97. # Покажем, что полученные секретные ключи идентичны у п1 и п2
  98. print(p1KeySecret.isEqual(p2KeySecret))
  99. # Далее п1 отправляет зашифрованное сообщение п2
  100. p1MessageEncrypted = cur.encodeMessage(p1KeySecret, 'Привет, как дела?')
  101. #Покажем зашифрованное сообщение
  102. print("п1: ", p1MessageEncrypted)
  103. # п2 расшифровывает полученное сообщение
  104. p1MessageDecrypted = cur.decodeMessage(p2KeySecret, p1MessageEncrypted)
  105. # Покажем расшифрованное сообщение
  106. print("п1: ", p1MessageDecrypted)
  107. # п2 отправляет зашифрованным сообщением п1
  108. p2MessageEncrypted = cur.encodeMessage(p2KeySecret, 'Спасибо, у меня всё хорошо :)')
  109. #Покажем зашифрованное сообщение
  110. print("п2: ", p2MessageEncrypted)
  111. # п1 расшифровывает полученное сообщение
  112. p2MessageDecrypted = cur.decodeMessage(p1KeySecret, p2MessageEncrypted)
  113. # Покажем расшифрованное сообщение
  114. print("п2: ", p2MessageDecrypted)