def _test_square_roots(self, p): all_squares = set() not_squares = set(range(1, p)) for x in xrange(1, p): all_squares.add((x, pow(x, 2, p))) for x, xx in all_squares: self.assertTrue(x in sqrt_modp(xx, p)) if xx in not_squares: not_squares.remove(xx) for x in not_squares: self.assertEquals([], sqrt_modp(x, p))
def get_x(self, y): result = [] # HACK: Instead of brute forcing the square roots pick the right one directly. top = sqrt_modp((y**2 - self.c**2) % self.gf.p, self.gf.p) + sqrt_modp(-(y**2 - self.c**2) % self.gf.p, self.gf.p) bottom = sqrt_modp((self.c**2 * self.d * y**2 - 1) % self.gf.p, self.gf.p) + sqrt_modp(-(self.c**2 * self.d * y**2 - 1) % self.gf.p, self.gf.p) for t in top: for b in bottom: x = self.gf.div(t, b) if self.point_on_curve((x, y)): result.append((x, y)) if self.point_on_curve((-x % self.gf.p, y)): result.append((-x % self.gf.p, y)) return list(set(result))
def get_x(self, y): # ax^2 + y^2 = 1 + dx^2y^2 # x^2 (a - 2*y^2) = 1 - y^2 result = [] top = sqrt_modp(1 - y**2, self.gf.p) bottom = sqrt_modp(self.a - self.d * y**2, self.gf.p) for t in top: for b in bottom: x = self.gf.div(t, b) if self.point_on_curve((x, y)): result.append((x, y)) if self.point_on_curve((-x % self.gf.p, y)): result.append((-x % self.gf.p, y)) return list(set(result))
def __init__(self, c, d, field): assert c == 1 self.c = c self.d = d self.gf = field if self.gf.mul(d, 1-d) == 0: raise ValueError('invalid params') if sqrt_modp(d, self.gf.p): print 'WARNING: Edwards curve not complete'
def __init__(self, c, d, field): assert c == 1 self.c = c self.d = d self.gf = field if self.gf.mul(d, 1 - d) == 0: raise ValueError('invalid params') if sqrt_modp(d, self.gf.p): print 'WARNING: Edwards curve not complete'
def map_random_to_point(self, r): sqrt = lambda a: numbertheory.sqrt_modp(a, self.curve.gf.p) div = self.curve.gf.div sub = self.curve.gf.sub mul = self.curve.gf.mul v = div(-self.curve.a, 1 + self.u*r**2) epsilon = numbertheory.legendre_symbol(v**3 + self.curve.a*v**2 + self.curve.b*v, self.curve.gf.p) x = sub(epsilon*v, div((1 - epsilon)*self.curve.a, 2)) y = mul(-epsilon, sqrt(x**3 + self.curve.a*x**2 + self.curve.b*x)[0]) # XXX: First return (x, y)
def get_x(self, y): result = [] # HACK: Instead of brute forcing the square roots pick the right one directly. top = sqrt_modp((y**2 - self.c**2) % self.gf.p, self.gf.p) + sqrt_modp( -(y**2 - self.c**2) % self.gf.p, self.gf.p) bottom = sqrt_modp( (self.c**2 * self.d * y**2 - 1) % self.gf.p, self.gf.p) + sqrt_modp( -(self.c**2 * self.d * y**2 - 1) % self.gf.p, self.gf.p) for t in top: for b in bottom: x = self.gf.div(t, b) if self.point_on_curve((x, y)): result.append((x, y)) if self.point_on_curve((-x % self.gf.p, y)): result.append((-x % self.gf.p, y)) return list(set(result))
def map_point_to_random(self, P): x, y = P sqrt = lambda a: numbertheory.sqrt_modp(a, self.curve.gf.p) div = self.curve.gf.div if y <= ((self.curve.gf.p - 1) / 2): r = sqrt(div(-x, (x + self.curve.a) * self.u)) else: r = sqrt(div(-(x + self.curve.a), x * self.u)) # XXX: First return r[0]
def get_y(self, x): """Returns a list of the y-coordinates on the curve at given x.""" yy = self.gf.normalize(x**3 + self.a*x + self.b) sqrs = sqrt_modp(yy, self.gf.p) result = [] for y in sqrs: # TODO: check inverted point? if self.point_on_curve((x, y)): result.append((x, y)) return result
def map_point_to_random(self, P): x, y = P sqrt = lambda a: numbertheory.sqrt_modp(a, self.curve.gf.p) div = self.curve.gf.div if y <= ((self.curve.gf.p - 1) / 2): r = sqrt(div(-x, (x + self.curve.a)*self.u)) else: r = sqrt(div(-(x + self.curve.a), x*self.u)) # XXX: First return r[0]
def get_y(self, x): """Returns a list of the y-coordinates on the curve at given x.""" yy = self.gf.normalize(x**3 + self.a * x + self.b) sqrs = sqrt_modp(yy, self.gf.p) result = [] for y in sqrs: # TODO: check inverted point? if self.point_on_curve((x, y)): result.append((x, y)) return result
def map_random_to_point(self, r): sqrt = lambda a: numbertheory.sqrt_modp(a, self.curve.gf.p) div = self.curve.gf.div sub = self.curve.gf.sub mul = self.curve.gf.mul v = div(-self.curve.a, 1 + self.u * r**2) epsilon = numbertheory.legendre_symbol( v**3 + self.curve.a * v**2 + self.curve.b * v, self.curve.gf.p) x = sub(epsilon * v, div((1 - epsilon) * self.curve.a, 2)) y = mul(-epsilon, sqrt(x**3 + self.curve.a * x**2 + self.curve.b * x)[0]) # XXX: First return (x, y)