static int _crypto_scalarmult_ed25519(unsigned char *q, const unsigned char *n, const unsigned char *p, const int clamp) { unsigned char *t = q; ge25519_p3 Q; ge25519_p3 P; unsigned int i; if (ge25519_is_canonical(p) == 0 || ge25519_has_small_order(p) != 0 || ge25519_frombytes(&P, p) != 0 || ge25519_is_on_main_subgroup(&P) == 0) { return -1; } for (i = 0; i < 32; ++i) { t[i] = n[i]; } if (clamp != 0) { _crypto_scalarmult_ed25519_clamp(t); } ge25519_scalarmult(&Q, t, &P); ge25519_p3_tobytes(q, &Q); if (_crypto_scalarmult_ed25519_is_inf(q) != 0 || sodium_is_zero(n, 32)) { return -1; } return 0; }
int crypto_sign_ed25519_pk_to_curve25519(unsigned char *curve25519_pk, const unsigned char *ed25519_pk) { ge25519_p3 A; fe25519 x; fe25519 one_minus_y; if (ge25519_has_small_order(ed25519_pk) != 0 || ge25519_frombytes_negate_vartime(&A, ed25519_pk) != 0 || ge25519_is_on_main_subgroup(&A) == 0) { return -1; } fe25519_1(one_minus_y); fe25519_sub(one_minus_y, one_minus_y, A.Y); fe25519_1(x); fe25519_add(x, x, A.Y); fe25519_invert(one_minus_y, one_minus_y); fe25519_mul(x, x, one_minus_y); fe25519_tobytes(curve25519_pk, x); return 0; }