void ge25519_pack(unsigned char r[32], const ge25519_p3 *p) { fe25519 tx, ty, zi; fe25519_invert(&zi, &p->z); fe25519_mul(&tx, &p->x, &zi); fe25519_mul(&ty, &p->y, &zi); fe25519_pack(r, &ty); r[31] ^= fe25519_getparity(&tx) << 7; }
void x25519_x86_64(uint8_t out[32], const uint8_t scalar[32], const uint8_t point[32]) { uint8_t e[32]; OPENSSL_memcpy(e, scalar, sizeof(e)); e[0] &= 248; e[31] &= 127; e[31] |= 64; fe25519 t; fe25519 z; fe25519_unpack(&t, point); mladder(&t, &z, e); fe25519_invert(&z, &z); x25519_x86_64_mul(&t, &t, &z); fe25519_pack(out, &t); }
int edmont_conv(unsigned char r[crypto_scalarmult_curve25519_BYTES], const unsigned char p[ED25519_PUBLICKEYBYTES]) { fe25519 u, y, num, den, inv, one; fe25519_unpack(&y, p); // u = (1 + y) / (1 -y) fe25519_setone(&one); fe25519_add(&num, &one, &y); fe25519_sub(&den, &one, &y); fe25519_invert(&inv, &den); fe25519_mul(&u, &num, &inv); fe25519_pack(r, &u); return 0; }