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