def point_add2(p1, p2): x1, y1 = p1 x2, y2 = p2 z1, z2 = (fe(1), fe(1)) x, y, z = point_add((x1, y1, z1), (x2, y2, z2)) div = z.invert() return (x * div, y * div)
def check_low_order_point(): lop2 = point_add2(low_order_point, low_order_point) lop4 = point_add2(lop2, lop2) lop8 = point_add2(lop4, lop4) zero = (fe(0), fe(1)) if lop8 != zero: raise ValueError('low_order_point does not have low order') if lop2 == zero: raise ValueError('low_order_point only has order 2') if lop4 == zero: raise ValueError('low_order_point only has order 4')
def ed_scalarmult(point, scalar): affine = (point[0], point[1], fe(1)) acc = (fe(0), fe(1), fe(1)) binary = [int(c) for c in list(format(scalar, 'b'))] for i in binary: acc = point_add(acc, acc) if i == 1: acc = point_add(acc, affine) return acc
def check_low_order_point(): lop2 = low_order_point_2 lop4 = low_order_point_4 lop8 = low_order_point_8 zero = (fe(0), fe(1)) if lop8 != zero: raise ValueError('low_order_point does not have low order') if lop2 == zero: raise ValueError('low_order_point only has order 2') if lop4 == zero: raise ValueError('low_order_point only has order 4')
def mt_scalarmult(u, scalar): x1 = u x2, z2 = fe(1), fe(0) # "zero" point x3, z3 = x1, fe(1) # "one" point binary = [int(c) for c in list(format(scalar, 'b'))] for b in binary: # Montgomery ladder step: # if b == 0, then (P2, P3) == (P2*2 , P2+P3) # if b == 1, then (P2, P3) == (P2+P3, P3*2 ) if b == 1: x2, x3 = x3, x2 z2, z3 = z3, z2 x3, z3 = ((x2 * x3 - z2 * z3)**2, (x2 * z3 - z2 * x3)**2 * x1) x2, z2 = ((x2**2 - z2**2)**2, fe(4) * x2 * z2 * (x2**2 + A * x2 * z2 + z2**2)) if b == 1: x2, x3 = x3, x2 z2, z3 = z3, z2 return x2 / z2
# You should have received a copy of the CC0 Public Domain Dedication along # with this software. If not, see # <https://creativecommons.org/publicdomain/zero/1.0/> from elligator import fe from elligator import sqrt from elligator import sqrtm1 from elligator import A ######################################### # scalar multiplication (Edwards space) # ######################################### # Edwards25519 equation (d defined below): # -x^2 + y^2 = 1 + d*x^2*y^2 d = fe(-121665) / fe(121666) # Point addition: # denum = d*x1*x2*y1*y2 # x = (x1*y2 + x2*y1) / (1 + denum) # y = (y1*y2 + x1*x2) / (1 - denum) # To avoid divisions, we use affine coordinates: x = X/Z, y = Y/Z. # We can multiply Z instead of dividing X and Y. def point_add(a, b): x1, y1, z1 = a x2, y2, z2 = b denum = d * x1 * x2 * y1 * y2 z1z2 = z1 * z2 z1z22 = z1z2**2 xt = z1z2 * (x1 * y2 + x2 * y1)
# You should have received a copy of the CC0 Public Domain Dedication along # with this software. If not, see # <https://creativecommons.org/publicdomain/zero/1.0/> from elligator import fe from elligator import curve_to_hash from elligator import hash_to_curve from elligator import fast_hash_to_curve from elligator import p from elligator import print_raw from random import randrange def direct(r1, padding): q1 = hash_to_curve(r1) q2 = fast_hash_to_curve(r1) r2 = curve_to_hash(q1[0], q1[1].is_negative()) if q1 != q2: raise ValueError('Incorrect fast_hash_to_curve') if r1 != r2: raise ValueError('Round trip failure') print_raw(r1.val + padding * 2**254) q1[0].print() # u coordinate only print() direct(fe(0), 0) # representative 0 maps to point (0, 0) direct(fe(0), 1) # representative 0 maps to point (0, 0) direct(fe(0), 2) # representative 0 maps to point (0, 0) direct(fe(0), 3) # representative 0 maps to point (0, 0) for i in range(50): direct(fe(randrange(0, (p - 1) / 2)), i % 4)
# You should have received a copy of the CC0 Public Domain Dedication along # with this software. If not, see # <https://creativecommons.org/publicdomain/zero/1.0/> from elligator import fe from elligator import sqrt from elligator import sqrtm1 from elligator import A ######################################### # scalar multiplication (Edwards space) # ######################################### # Edwards25519 equation (d defined below): # -x^2 + y^2 = 1 + d*x^2*y^2 d = fe(-121665) / fe(121666) # Point addition: # denum = d*x1*x2*y1*y2 # x = (x1*y2 + x2*y1) / (1 + denum) # y = (y1*y2 + x1*x2) / (1 - denum) # To avoid divisions, we use affine coordinates: x = X/Z, y = Y/Z. # We can multiply Z instead of dividing X and Y. def point_add(a, b): x1, y1, z1 = a x2, y2, z2 = b denum = d*x1*x2*y1*y2 z1z2 = z1 * z2 z1z22 = z1z2**2 xt = z1z2 * (x1*y2 + x2*y1) yt = z1z2 * (y1*y2 + x1*x2)