Botan  2.9.0
Crypto and TLS for C++11
ed25519_key.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/pk_ops_impl.h>
13 #include <botan/hash.h>
14 #include <botan/ber_dec.h>
15 #include <botan/der_enc.h>
16 #include <botan/rng.h>
17 
18 namespace Botan {
19 
21  {
23  }
24 
26  {
27  return true; // no tests possible?
28  // TODO could check cofactor
29  }
30 
32  const std::vector<uint8_t>& key_bits)
33  {
34  m_public = key_bits;
35 
36  if(m_public.size() != 32)
37  throw Decoding_Error("Invalid size for Ed25519 public key");
38  }
39 
40 std::vector<uint8_t> Ed25519_PublicKey::public_key_bits() const
41  {
42  return m_public;
43  }
44 
46  {
47  if(secret_key.size() == 64)
48  {
49  m_private = secret_key;
50  m_public.assign(&m_private[32], &m_private[64]);
51  }
52  else if(secret_key.size() == 32)
53  {
54  m_public.resize(32);
55  m_private.resize(64);
56  ed25519_gen_keypair(m_public.data(), m_private.data(), secret_key.data());
57  }
58  else
59  throw Decoding_Error("Invalid size for Ed25519 private key");
60  }
61 
63  {
64  const secure_vector<uint8_t> seed = rng.random_vec(32);
65  m_public.resize(32);
66  m_private.resize(64);
67  ed25519_gen_keypair(m_public.data(), m_private.data(), seed.data());
68  }
69 
71  const secure_vector<uint8_t>& key_bits)
72  {
75 
76  if(bits.size() != 32)
77  throw Decoding_Error("Invalid size for Ed25519 private key");
78  m_public.resize(32);
79  m_private.resize(64);
80  ed25519_gen_keypair(m_public.data(), m_private.data(), bits.data());
81  }
82 
84  {
85  secure_vector<uint8_t> bits(&m_private[0], &m_private[32]);
86  return DER_Encoder().encode(bits, OCTET_STRING).get_contents();
87  }
88 
90  {
91  return true; // ???
92  }
93 
94 namespace {
95 
96 /**
97 * Ed25519 verifying operation
98 */
99 class Ed25519_Pure_Verify_Operation final : public PK_Ops::Verification
100  {
101  public:
102  Ed25519_Pure_Verify_Operation(const Ed25519_PublicKey& key) : m_key(key)
103  {
104  }
105 
106  void update(const uint8_t msg[], size_t msg_len) override
107  {
108  m_msg.insert(m_msg.end(), msg, msg + msg_len);
109  }
110 
111  bool is_valid_signature(const uint8_t sig[], size_t sig_len) override
112  {
113  if(sig_len != 64)
114  return false;
115  const bool ok = ed25519_verify(m_msg.data(), m_msg.size(), sig, m_key.get_public_key().data());
116  m_msg.clear();
117  return ok;
118  }
119 
120  private:
121  std::vector<uint8_t> m_msg;
122  const Ed25519_PublicKey& m_key;
123  };
124 
125 /**
126 * Ed25519 verifying operation with pre-hash
127 */
128 class Ed25519_Hashed_Verify_Operation final : public PK_Ops::Verification
129  {
130  public:
131  Ed25519_Hashed_Verify_Operation(const Ed25519_PublicKey& key, const std::string& hash) : m_key(key)
132  {
134  }
135 
136  void update(const uint8_t msg[], size_t msg_len) override
137  {
138  m_hash->update(msg, msg_len);
139  }
140 
141  bool is_valid_signature(const uint8_t sig[], size_t sig_len) override
142  {
143  if(sig_len != 64)
144  return false;
145  std::vector<uint8_t> msg_hash(m_hash->output_length());
146  m_hash->final(msg_hash.data());
147  return ed25519_verify(msg_hash.data(), msg_hash.size(), sig, m_key.get_public_key().data());
148  }
149 
150  private:
151  std::unique_ptr<HashFunction> m_hash;
152  const Ed25519_PublicKey& m_key;
153  };
154 
155 /**
156 * Ed25519 signing operation ('pure' - signs message directly)
157 */
158 class Ed25519_Pure_Sign_Operation final : public PK_Ops::Signature
159  {
160  public:
161  Ed25519_Pure_Sign_Operation(const Ed25519_PrivateKey& key) : m_key(key)
162  {
163  }
164 
165  void update(const uint8_t msg[], size_t msg_len) override
166  {
167  m_msg.insert(m_msg.end(), msg, msg + msg_len);
168  }
169 
170  secure_vector<uint8_t> sign(RandomNumberGenerator&) override
171  {
172  secure_vector<uint8_t> sig(64);
173  ed25519_sign(sig.data(), m_msg.data(), m_msg.size(), m_key.get_private_key().data());
174  m_msg.clear();
175  return sig;
176  }
177 
178  size_t signature_length() const override { return 64; }
179 
180  private:
181  std::vector<uint8_t> m_msg;
182  const Ed25519_PrivateKey& m_key;
183  };
184 
185 /**
186 * Ed25519 signing operation with pre-hash
187 */
188 class Ed25519_Hashed_Sign_Operation final : public PK_Ops::Signature
189  {
190  public:
191  Ed25519_Hashed_Sign_Operation(const Ed25519_PrivateKey& key, const std::string& hash) : m_key(key)
192  {
194  }
195 
196  size_t signature_length() const override { return 64; }
197 
198  void update(const uint8_t msg[], size_t msg_len) override
199  {
200  m_hash->update(msg, msg_len);
201  }
202 
203  secure_vector<uint8_t> sign(RandomNumberGenerator&) override
204  {
205  secure_vector<uint8_t> sig(64);
206  std::vector<uint8_t> msg_hash(m_hash->output_length());
207  m_hash->final(msg_hash.data());
208  ed25519_sign(sig.data(), msg_hash.data(), msg_hash.size(), m_key.get_private_key().data());
209  return sig;
210  }
211 
212  private:
213  std::unique_ptr<HashFunction> m_hash;
214  const Ed25519_PrivateKey& m_key;
215  };
216 
217 }
218 
219 std::unique_ptr<PK_Ops::Verification>
221  const std::string& provider) const
222  {
223  if(provider == "base" || provider.empty())
224  {
225  if(params == "" || params == "Identity" || params == "Pure")
226  return std::unique_ptr<PK_Ops::Verification>(new Ed25519_Pure_Verify_Operation(*this));
227  else
228  return std::unique_ptr<PK_Ops::Verification>(new Ed25519_Hashed_Verify_Operation(*this, params));
229  }
230  throw Provider_Not_Found(algo_name(), provider);
231  }
232 
233 std::unique_ptr<PK_Ops::Signature>
235  const std::string& params,
236  const std::string& provider) const
237  {
238  if(provider == "base" || provider.empty())
239  {
240  if(params == "" || params == "Identity" || params == "Pure")
241  return std::unique_ptr<PK_Ops::Signature>(new Ed25519_Pure_Sign_Operation(*this));
242  else
243  return std::unique_ptr<PK_Ops::Signature>(new Ed25519_Hashed_Sign_Operation(*this, params));
244  }
245  throw Provider_Not_Found(algo_name(), provider);
246  }
247 
248 }
void ed25519_gen_keypair(uint8_t *pk, uint8_t *sk, const uint8_t seed[32])
Definition: ed25519.cpp:18
std::vector< uint8_t > m_public
Definition: ed25519.h:62
std::string algo_name() const override
Definition: ed25519.h:21
static std::unique_ptr< HashFunction > create_or_throw(const std::string &algo_spec, const std::string &provider="")
Definition: hash.cpp:359
std::unique_ptr< PK_Ops::Signature > create_signature_op(RandomNumberGenerator &rng, const std::string &params, const std::string &provider) const override
secure_vector< uint8_t > random_vec(size_t bytes)
Definition: rng.h:141
bool check_key(RandomNumberGenerator &rng, bool strong) const override
Definition: ed25519_key.cpp:25
int(* final)(unsigned char *, CTX *)
secure_vector< uint8_t > get_contents()
Definition: der_enc.cpp:152
BER_Decoder & decode(bool &out)
Definition: ber_dec.h:170
std::unique_ptr< PK_Ops::Verification > create_verification_op(const std::string &params, const std::string &provider) const override
secure_vector< uint8_t > private_key_bits() const override
Definition: ed25519_key.cpp:83
DER_Encoder & encode(bool b)
Definition: der_enc.cpp:285
virtual OID get_oid() const
Definition: pk_keys.cpp:53
bool check_key(RandomNumberGenerator &rng, bool strong) const override
Definition: ed25519_key.cpp:89
void ed25519_sign(uint8_t sig[64], const uint8_t *m, size_t mlen, const uint8_t *sk)
Definition: ed25519.cpp:36
std::vector< uint8_t > public_key_bits() const override
Definition: ed25519_key.cpp:40
Ed25519_PrivateKey(const AlgorithmIdentifier &alg_id, const secure_vector< uint8_t > &key_bits)
Definition: ed25519_key.cpp:70
BER_Decoder & discard_remaining()
Definition: ber_dec.cpp:226
Definition: alg_id.cpp:13
bool ed25519_verify(const uint8_t *m, size_t mlen, const uint8_t sig[64], const uint8_t *pk)
Definition: ed25519.cpp:68
int(* update)(CTX *, const void *, CC_LONG len)
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:65
AlgorithmIdentifier algorithm_identifier() const override
Definition: ed25519_key.cpp:20
const RSA_PrivateKey & m_key
Definition: rsa.cpp:289
MechanismType hash