Botan 3.6.1
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
13#include <botan/rng.h>
14#include <botan/internal/ct_utils.h>
15#include <botan/internal/ed25519_internal.h>
16#include <botan/internal/sha2_64.h>
17
18namespace Botan {
19
20void ed25519_gen_keypair(uint8_t* pk, uint8_t* sk, const uint8_t seed[32]) {
21 uint8_t az[64];
22
23 SHA_512 sha;
24 sha.update(seed, 32);
25 sha.final(az);
26 az[0] &= 248;
27 az[31] &= 63;
28 az[31] |= 64;
29
30 ge_scalarmult_base(pk, az);
31
32 // todo copy_mem
33 copy_mem(sk, seed, 32);
34 copy_mem(sk + 32, pk, 32);
35}
36
37void ed25519_sign(uint8_t sig[64],
38 const uint8_t m[],
39 size_t mlen,
40 const uint8_t sk[64],
41 const uint8_t domain_sep[],
42 size_t domain_sep_len) {
43 uint8_t az[64];
44 uint8_t nonce[64];
45 uint8_t hram[64];
46
47 SHA_512 sha;
48
49 sha.update(sk, 32);
50 sha.final(az);
51 az[0] &= 248;
52 az[31] &= 63;
53 az[31] |= 64;
54
55 sha.update(domain_sep, domain_sep_len);
56 sha.update(az + 32, 32);
57 sha.update(m, mlen);
58 sha.final(nonce);
59
60 sc_reduce(nonce);
61 ge_scalarmult_base(sig, nonce);
62
63 sha.update(domain_sep, domain_sep_len);
64 sha.update(sig, 32);
65 sha.update(sk + 32, 32);
66 sha.update(m, mlen);
67 sha.final(hram);
68
69 sc_reduce(hram);
70 sc_muladd(sig + 32, hram, az, nonce);
71}
72
73bool ed25519_verify(const uint8_t* m,
74 size_t mlen,
75 const uint8_t sig[64],
76 const uint8_t* pk,
77 const uint8_t domain_sep[],
78 size_t domain_sep_len) {
79 uint8_t h[64];
80 uint8_t rcheck[32];
81 ge_p3 A;
82 SHA_512 sha;
83
84 if(sig[63] & 224) {
85 return false;
86 }
87 if(ge_frombytes_negate_vartime(&A, pk) != 0) {
88 return false;
89 }
90
91 const uint64_t CURVE25519_ORDER[4] = {
92 0x1000000000000000,
93 0x0000000000000000,
94 0x14def9dea2f79cd6,
95 0x5812631a5cf5d3ed,
96 };
97
98 const uint64_t s[4] = {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 // RFC 8032 adds the requirement that we verify that s < order in
104 // the signature; this did not exist in the original Ed25519 spec.
105 for(size_t i = 0; i != 4; ++i) {
106 if(s[i] > CURVE25519_ORDER[i]) {
107 return false;
108 }
109 if(s[i] < CURVE25519_ORDER[i]) {
110 break;
111 }
112 if(i == 3) { // here s == order
113 return false;
114 }
115 }
116
117 sha.update(domain_sep, domain_sep_len);
118 sha.update(sig, 32);
119 sha.update(pk, 32);
120 sha.update(m, mlen);
121 sha.final(h);
122 sc_reduce(h);
123
124 ge_double_scalarmult_vartime(rcheck, h, &A, sig + 32);
125
126 return CT::is_equal(rcheck, sig, 32).as_bool();
127}
128
129} // namespace Botan
void update(const uint8_t in[], size_t length)
Definition buf_comp.h:35
void final(uint8_t out[])
Definition buf_comp.h:70
constexpr CT::Mask< T > is_equal(const T x[], const T y[], size_t len)
Definition ct_utils.h:759
int ge_frombytes_negate_vartime(ge_p3 *v, const uint8_t *)
Definition ge.cpp:425
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:37
void ed25519_gen_keypair(uint8_t *pk, uint8_t *sk, const uint8_t seed[32])
Definition ed25519.cpp:20
void ge_scalarmult_base(uint8_t out[32], const uint8_t in[32])
Definition ge.cpp:2043
constexpr auto load_le(ParamTs &&... params)
Definition loadstor.h:521
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:73
constexpr void copy_mem(T *out, const T *in, size_t n)
Definition mem_ops.h:146
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