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