def recover_x_coordinate(y: nat, sign: bool) -> felem_t: if y >= p25519: return None else: y = felem(y) p1 = fmul(d25519, fsqr(y)) p1_1 = fadd(p1, 1) x2 = fmul(fsub(fsqr(y), 1), finv(p1_1)) if x2 == 0 and sign: return None elif x2 == 0 and not sign: return felem(0) else: x = pow(x2, (p25519 + 3) // 8, p25519) if (fsub(fsqr(x), x2) != 0): x = fmul(x, fsqrt_m1) if (fsub(fsqr(x), x2) != 0): return None else: if (x % 2 == 1) != sign: return felem(p25519 - x) else: return x
def point_double(p: extended_point_t) -> extended_point_t: if p == (0, 1, 1, 0): return p (x1, y1, z1, t1) = p a = fmul(x1, x1) b = fmul(y1, y1) c = fmul(felem(2), fmul(z1, z1)) h = fadd(a, b) e = fsub(h, fmul(fadd(x1, y1), fadd(x1, y1))) g = fsub(a, b) f = fadd(c, g) x3 = fmul(e, f) y3 = fmul(g, h) t3 = fmul(e, h) z3 = fmul(f, g) return (x3, y3, z3, t3)
def point_add(p: extended_point_t, q: extended_point_t) -> extended_point_t: if p == (0, 1, 1, 0): return q if q == (0, 1, 1, 0): return p (x1, y1, z1, t1) = p (x2, y2, z2, t2) = q a = fmul(fsub(y1, x1), fsub(y2, x2)) b = fmul(fadd(y1, x1), fadd(y2, x2)) c = fmul(felem(2), fmul(fmul(d25519, t1), t2)) d = fmul(2, fmul(z1, z2)) e = fsub(b, a) f = fsub(d, c) g = fadd(d, c) h = fadd(b, a) x3 = fmul(e, f) y3 = fmul(g, h) t3 = fmul(e, h) z3 = fmul(f, g) p = (x3, y3, z3, t3) return p
def sha512_modq(s: vlbytes) -> felem_t: h = sha512(s) return (felem(bytes.to_nat_le(h) % q25519))
#!/usr/bin/python3 from speclib import * from curve25519 import felem_t, felem, fadd, fsub, fmul, fsqr, finv, serialized_scalar_t, serialized_point_t, scalar_t, p25519 from sha2 import sha512 # Define prime field d25519: felem_t = felem( 37095705934669439343138083508754565189542113879843219016388785533085940283555 ) q25519: felem_t = felem((1 << 252) + 27742317777372353535851937790883648493) def sha512_modq(s: vlbytes) -> felem_t: h = sha512(s) return (felem(bytes.to_nat_le(h) % q25519)) affine_point_t = tuple2(felem_t, felem_t) extended_point_t = tuple4(felem_t, felem_t, felem_t, felem_t) def point_add(p: extended_point_t, q: extended_point_t) -> extended_point_t: if p == (0, 1, 1, 0): return q if q == (0, 1, 1, 0): return p (x1, y1, z1, t1) = p (x2, y2, z2, t2) = q a = fmul(fsub(y1, x1), fsub(y2, x2)) b = fmul(fadd(y1, x1), fadd(y2, x2))