Botan 3.0.0
Crypto and TLS for C&
ed25519.cpp
Go to the documentation of this file.
1/*
2* Ed25519
3* (C) 2017 Ribose Inc
4*
5* Based on the public domain code from SUPERCOP ref10 by
6* Peter Schwabe, Daniel J. Bernstein, Niels Duif, Tanja Lange, Bo-Yin Yang
7*
8* Botan is released under the Simplified BSD License (see license.txt)
9*/
10
11#include <botan/ed25519.h>
12#include <botan/internal/ed25519_internal.h>
13#include <botan/internal/sha2_64.h>
14#include <botan/rng.h>
15
16namespace Botan {
17
18void ed25519_gen_keypair(uint8_t* pk, uint8_t* sk, const uint8_t seed[32])
19 {
20 uint8_t az[64];
21
22 SHA_512 sha;
23 sha.update(seed, 32);
24 sha.final(az);
25 az[0] &= 248;
26 az[31] &= 63;
27 az[31] |= 64;
28
29 ge_scalarmult_base(pk, az);
30
31 // todo copy_mem
32 copy_mem(sk, seed, 32);
33 copy_mem(sk + 32, pk, 32);
34 }
35
36void ed25519_sign(uint8_t sig[64],
37 const uint8_t m[], size_t mlen,
38 const uint8_t sk[64],
39 const uint8_t domain_sep[], size_t domain_sep_len)
40 {
41 uint8_t az[64];
42 uint8_t nonce[64];
43 uint8_t hram[64];
44
45 SHA_512 sha;
46
47 sha.update(sk, 32);
48 sha.final(az);
49 az[0] &= 248;
50 az[31] &= 63;
51 az[31] |= 64;
52
53 sha.update(domain_sep, domain_sep_len);
54 sha.update(az + 32, 32);
55 sha.update(m, mlen);
56 sha.final(nonce);
57
58 sc_reduce(nonce);
59 ge_scalarmult_base(sig, nonce);
60
61 sha.update(domain_sep, domain_sep_len);
62 sha.update(sig, 32);
63 sha.update(sk + 32, 32);
64 sha.update(m, mlen);
65 sha.final(hram);
66
67 sc_reduce(hram);
68 sc_muladd(sig + 32, hram, az, nonce);
69 }
70
71bool ed25519_verify(const uint8_t* m, size_t mlen,
72 const uint8_t sig[64],
73 const uint8_t* pk,
74 const uint8_t domain_sep[], size_t domain_sep_len)
75 {
76 uint8_t h[64];
77 uint8_t rcheck[32];
78 ge_p3 A;
79 SHA_512 sha;
80
81 if(sig[63] & 224)
82 {
83 return false;
84 }
85 if(ge_frombytes_negate_vartime(&A, pk) != 0)
86 {
87 return false;
88 }
89
90 const uint64_t CURVE25519_ORDER[4] = {
91 0x1000000000000000,
92 0x0000000000000000,
93 0x14def9dea2f79cd6,
94 0x5812631a5cf5d3ed,
95 };
96
97 const uint64_t s[4] = {
98 load_le<uint64_t>(sig + 32, 3),
99 load_le<uint64_t>(sig + 32, 2),
100 load_le<uint64_t>(sig + 32, 1),
101 load_le<uint64_t>(sig + 32, 0)
102 };
103
104 // RFC 8032 adds the requirement that we verify that s < order in
105 // the signature; this did not exist in the original Ed25519 spec.
106 for(size_t i = 0; i != 4; ++i)
107 {
108 if(s[i] > CURVE25519_ORDER[i])
109 return false;
110 if(s[i] < CURVE25519_ORDER[i])
111 break;
112 if(i == 3) // here s == order
113 return false;
114 }
115
116 sha.update(domain_sep, domain_sep_len);
117 sha.update(sig, 32);
118 sha.update(pk, 32);
119 sha.update(m, mlen);
120 sha.final(h);
121 sc_reduce(h);
122
123 ge_double_scalarmult_vartime(rcheck, h, &A, sig + 32);
124
125 return constant_time_compare(rcheck, sig, 32);
126 }
127
128}
void update(const uint8_t in[], size_t length)
Definition: buf_comp.h:35
void final(uint8_t out[])
Definition: buf_comp.h:76
Definition: alg_id.cpp:12
int ge_frombytes_negate_vartime(ge_p3 *v, const uint8_t *)
Definition: ge.cpp:457
void ed25519_sign(uint8_t sig[64], const uint8_t m[], size_t mlen, const uint8_t sk[64], const uint8_t domain_sep[], size_t domain_sep_len)
Definition: ed25519.cpp:36
void ed25519_gen_keypair(uint8_t *pk, uint8_t *sk, const uint8_t seed[32])
Definition: ed25519.cpp:18
constexpr void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:126
void ge_scalarmult_base(uint8_t out[32], const uint8_t in[32])
Definition: ge.cpp:2118
bool constant_time_compare(const uint8_t x[], const uint8_t y[], size_t len)
Definition: mem_ops.h:82
constexpr uint64_t load_le< uint64_t >(const uint8_t in[], size_t off)
Definition: loadstor.h:248
bool ed25519_verify(const uint8_t *m, size_t mlen, const uint8_t sig[64], const uint8_t *pk, const uint8_t domain_sep[], size_t domain_sep_len)
Definition: ed25519.cpp:71
void sc_reduce(uint8_t *)
Definition: sc_reduce.cpp:25
void ge_double_scalarmult_vartime(uint8_t out[32], const uint8_t a[], const ge_p3 *A, const uint8_t b[])
void sc_muladd(uint8_t *, const uint8_t *, const uint8_t *, const uint8_t *)
Definition: sc_muladd.cpp:26