1 2#include <string.h> 3 4#include "crypto_hash_sha512.h" 5#include "crypto_scalarmult_curve25519.h" 6#include "crypto_sign_ed25519.h" 7#include "sign_ed25519_ref10.h" 8#include "private/ed25519_ref10.h" 9#include "randombytes.h" 10#include "utils.h" 11 12int 13crypto_sign_ed25519_seed_keypair(unsigned char *pk, unsigned char *sk, 14 const unsigned char *seed) 15{ 16 ge25519_p3 A; 17 18#ifdef ED25519_NONDETERMINISTIC 19 memmove(sk, seed, 32); 20#else 21 crypto_hash_sha512(sk, seed, 32); 22#endif 23 sk[0] &= 248; 24 sk[31] &= 127; 25 sk[31] |= 64; 26 27 ge25519_scalarmult_base(&A, sk); 28 ge25519_p3_tobytes(pk, &A); 29 30 memmove(sk, seed, 32); 31 memmove(sk + 32, pk, 32); 32 33 return 0; 34} 35 36int 37crypto_sign_ed25519_keypair(unsigned char *pk, unsigned char *sk) 38{ 39 unsigned char seed[32]; 40 int ret; 41 42 randombytes_buf(seed, sizeof seed); 43 ret = crypto_sign_ed25519_seed_keypair(pk, sk, seed); 44 sodium_memzero(seed, sizeof seed); 45 46 return ret; 47} 48 49int 50crypto_sign_ed25519_pk_to_curve25519(unsigned char *curve25519_pk, 51 const unsigned char *ed25519_pk) 52{ 53 ge25519_p3 A; 54 fe25519 x; 55 fe25519 one_minus_y; 56 57 if (ge25519_has_small_order(ed25519_pk) != 0 || 58 ge25519_frombytes_negate_vartime(&A, ed25519_pk) != 0 || 59 ge25519_is_on_main_subgroup(&A) == 0) { 60 return -1; 61 } 62 fe25519_1(one_minus_y); 63 fe25519_sub(one_minus_y, one_minus_y, A.Y); 64 fe25519_1(x); 65 fe25519_add(x, x, A.Y); 66 fe25519_invert(one_minus_y, one_minus_y); 67 fe25519_mul(x, x, one_minus_y); 68 fe25519_tobytes(curve25519_pk, x); 69 70 return 0; 71} 72 73int 74crypto_sign_ed25519_sk_to_curve25519(unsigned char *curve25519_sk, 75 const unsigned char *ed25519_sk) 76{ 77 unsigned char h[crypto_hash_sha512_BYTES]; 78 79#ifdef ED25519_NONDETERMINISTIC 80 memcpy(h, ed25519_sk, 32); 81#else 82 crypto_hash_sha512(h, ed25519_sk, 32); 83#endif 84 h[0] &= 248; 85 h[31] &= 127; 86 h[31] |= 64; 87 memcpy(curve25519_sk, h, crypto_scalarmult_curve25519_BYTES); 88 sodium_memzero(h, sizeof h); 89 90 return 0; 91} 92