79 lines
2.0 KiB
Python

from util import Object
import numpy as np
import libnum
CURVE_LINSPACE_OFFSET = 10
CURVE_LINSPACE_NUM = 2000
# NOTE: ADD NEW CURVES HERE
# this way they are automatically added to the gui
DEFAULT_CURVES = {
'Default': (3, 3, 11),
'secp384r1 (NSA backdoor)': (3, 0, 2**384 - 2**128 - 2**96 + 2**32 - 1),
'secp256k1 (BTC)': (0, 7, 2**256 - 2**32 - 2**9 - 2**8 - 2**7 - 2**6 - 2**4 - 1),
}
# XXX
def init_arg_getter_righer(f, *args):
def g(*args):
return f(args[0], args[1], args[2])
return g
class EllipticCurve(Object):
@init_arg_getter_righer
def __init__(self, a, b):
self.a = a
self.b = b
self._points()
def _points(self):
def iterih_squre(x):
return (x**3) + (self.a * x**2) + self.b
start = -1
for start in np.linspace(-10, 0, 2000):
if iterih_squre(start) > 0:
break
self.pp = np.empty((2, CURVE_LINSPACE_NUM))
self.np = np.empty((2, CURVE_LINSPACE_NUM))
for i, xi in enumerate(np.linspace(start, start + CURVE_LINSPACE_OFFSET, CURVE_LINSPACE_NUM)):
t = np.sqrt(iterih_squre(xi))
self.pp[0][i] = xi
self.pp[1][i] = t
self.np[0][i] = xi
self.np[1][i] = -t
def points(self):
return np.concatenate((self.pp, self.np), axis=0)
def add(self, p1, p2):
p1x, p1y = p1
p2x, p2y = p2
s = (p2y - p1y) / (p2x - p1x)
x = s**2 - p1x - p2x
y = s * (p1x - x) - p1y
return (x, y)
def scalar_multiply(point, n):
pass
def yfromx(self, x, is_top = True):
r = np.sqrt((x**3) + (self.a * x**2) + self.b)
r = +r if is_top else -r
return r
def EllipticCurveOverFiniteField(Object):
def __init__(self, a, b, mod):
self.a = a
self.b = b
self.mod = mod
self._points()
def _points(self):
self.xs = []
self.ys = []
def y_squared(x):
return (x**a + b) % mod
for x in range(0, mod):
if libnum.has_sqrtmod_prime_power(y_squared(x), mod, 1):
square_roots = libnum.sqrtmod_prime_power(y_squared(x), mod, 1)
for sr in square_roots:
self.ys.append(sr)
self.xs.append(x)
def points(self):
return self.xs, self.ys