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