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(to_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(to_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 recover_x_coordinate(y:nat,sign:bool) -> felem_t: if y >= p25519: return None else: y = to_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 to_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 to_felem(p25519 - x) else: return x