123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- import random, sympy
- from point import Point
- '''
- 'secp256k1',
- p=0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f,
- a=0,
- b=7,
- g=(0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8),
- # Subgroup order.
- n=0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141,
- # Subgroup cofactor.
- h=1,
- '''
- # y2 = x3 + ax + b
- 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 isSingular(self):
- res = 4 * self.a ** 3 + 27 * self.b ** 2 == 0
- return res
- def setupN(self):
- for self.n in range(self.p - 1, 1, -1):
- if sympy.isprime(self.n):
- return
- def setupG(self, processCallback = None):
- percent = 0
- for x in range(self.n, 0, -1):
- if processCallback is not None:
- dPercent = round(100 - x * 100 / self.n, 5)
- if dPercent != percent:
- percent = dPercent
- processCallback(percent)
- p1, p2 = self.pointsCurve(x)
- if p1.isInCurve():
- self.g = p1
- #print(p1.coords(), p1.isInCurve())
- #print(p2.coords(), p2.isInCurve())
- return
- def point(self, x = None, y = None):
- return Point(
- curve = self,
- x = x,
- y = y
- )
- # Определение координат пары зеркальных точек через координату x
- def pointsCurve(self, dx):
- # Инициализируем результирующие точки пустыми
- p1, p2 = self.point(), self.point()
- dy = None
- # Операции, обратной делению по модулю, не существует, поэтому
- # для определения координаты по y, необходимо, путем перебора с подстановкой y,
- # проверить равенство левой части уравнения, разделенного по модулю на p с
- # правой частью, так же разделенной по модулю на p
- for i in range(0, self.p):
- if i ** 2 % self.p == (dx **3 + self.a * dx + self.b) % self.p:
- dy = i
- break
- # Если dy не найден, точки не существуют, возвращаем нулевые точки
- if dy is None:
- return p1, p2
- # Точка найдена
- p1.x, p1.y = dx, dy
- # Расчет зеркальной точки
- p2.x = p1.x
- p2.y = -1 * p1.y % self.p
- return p1, p2
- # Обратное деление по модулю p кривой
- def inverseMod(self, k, point):
- if k == 0:
- raise ZeroDivisionError('division by zero')
- 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
- #assert gcd == 1
- #assert (k * x) % p == 1
- 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
- #################################
- '''
- c = Curve(
- p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f,
- a = 0,
- b = 7,
- gx = 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,
- gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8,
- n = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141,
- h = 1
- )
- c = Curve(
- p = 6277101735386680763835789423207666416083908700390324961279,
- a = -3,
- b = 2455155546008943817740293915197451784769108058161191238065,
- gx = 602046282375688656758213480587526111916698976636884684818,
- gy = 174050332293622031404857552280219410364023488927386650641,
- n = 6277101735386680763835789423176059013767194773182842284081,
- h = 1
- )
- '''
- c = Curve(
- p = 2 ** 20,
- a = 5,
- b = 4,
- gx = 2,
- gy = 2,
- n = 54534432,
- h = 1
- )
- if c.isSingular():
- print('Кривая сингулярна')
- exit(0)
- def process(percent):
- print(percent)
- c.setupN()
- c.setupG(process)
- print(c.n)
- aPriv, aPub = c.randomKeypair()
- bPriv, bPub = c.randomKeypair()
- print(hex(aPriv))
- print(aPub.show())
- #aS = scalar_mult(alice_private_key, bob_public_key)
- aS = bPub * aPriv
- bS = aPub * bPriv
- print(aS.show())
- print(bS.show())
|