Botan  2.18.1
Crypto and TLS for C++11
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/sha2_64.h>
14 #include <botan/rng.h>
15 
16 namespace Botan {
17 
18 void 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 
36 void 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 
71 bool 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  sha.update(domain_sep, domain_sep_len);
91  sha.update(sig, 32);
92  sha.update(pk, 32);
93  sha.update(m, mlen);
94  sha.final(h);
95  sc_reduce(h);
96 
97  ge_double_scalarmult_vartime(rcheck, h, &A, sig + 32);
98 
99  return constant_time_compare(rcheck, sig, 32);
100  }
101 
102 }
void ed25519_gen_keypair(uint8_t *pk, uint8_t *sk, const uint8_t seed[32])
Definition: ed25519.cpp:18
void sc_muladd(uint8_t *, const uint8_t *, const uint8_t *, const uint8_t *)
Definition: sc_muladd.cpp:26
void sc_reduce(uint8_t *)
Definition: sc_reduce.cpp:25
bool constant_time_compare(const uint8_t x[], const uint8_t y[], size_t len)
Definition: mem_ops.h:82
void final(uint8_t out[])
Definition: buf_comp.h:83
int ge_frombytes_negate_vartime(ge_p3 *, const uint8_t *)
Definition: ge.cpp:458
void ge_double_scalarmult_vartime(uint8_t out[32], const uint8_t a[], const ge_p3 *A, const uint8_t b[])
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:133
Definition: alg_id.cpp:13
void update(const uint8_t in[], size_t length)
Definition: buf_comp.h:33
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 ge_scalarmult_base(uint8_t out[32], const uint8_t in[32])
Definition: ge.cpp:2118
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