Botan 2.13.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

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(), nullptr, 0);
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, bool rfc8032) :
142 m_key(key)
143 {
144 m_hash = HashFunction::create_or_throw(hash);
145
146 if(rfc8032)
147 {
148 m_domain_sep = {
149 0x53, 0x69, 0x67, 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x20, 0x6E, 0x6F, 0x20, 0x45, 0x64,
150 0x32, 0x35, 0x35, 0x31, 0x39, 0x20, 0x63, 0x6F, 0x6C, 0x6C, 0x69, 0x73, 0x69, 0x6F, 0x6E, 0x73,
151 0x01, 0x00 };
152 }
153 }
154
155 void update(const uint8_t msg[], size_t msg_len) override
156 {
157 m_hash->update(msg, msg_len);
158 }
159
160 bool is_valid_signature(const uint8_t sig[], size_t sig_len) override
161 {
162 if(sig_len != 64)
163 return false;
164 std::vector<uint8_t> msg_hash(m_hash->output_length());
165 m_hash->final(msg_hash.data());
166
167 const std::vector<uint8_t>& pub_key = m_key.get_public_key();
168 BOTAN_ASSERT_EQUAL(pub_key.size(), 32, "Expected size");
169 return ed25519_verify(msg_hash.data(), msg_hash.size(), sig, pub_key.data(), m_domain_sep.data(), m_domain_sep.size());
170 }
171
172 private:
173 std::unique_ptr<HashFunction> m_hash;
174 const Ed25519_PublicKey& m_key;
175 std::vector<uint8_t> m_domain_sep;
176 };
177
178 /**
179 * Ed25519 signing operation ('pure' - signs message directly)
180 */
181 class Ed25519_Pure_Sign_Operation final : public PK_Ops::Signature
182 {
183 public:
184 Ed25519_Pure_Sign_Operation(const Ed25519_PrivateKey& key) : m_key(key)
185 {
186 }
187
188 void update(const uint8_t msg[], size_t msg_len) override
189 {
190 m_msg.insert(m_msg.end(), msg, msg + msg_len);
191 }
192
193 secure_vector<uint8_t> sign(RandomNumberGenerator&) override
194 {
195 secure_vector<uint8_t> sig(64);
196 ed25519_sign(sig.data(), m_msg.data(), m_msg.size(), m_key.get_private_key().data(), nullptr, 0);
197 m_msg.clear();
198 return sig;
199 }
200
201 size_t signature_length() const override { return 64; }
202
203 private:
204 std::vector<uint8_t> m_msg;
205 const Ed25519_PrivateKey& m_key;
206 };
207
208 /**
209 * Ed25519 signing operation with pre-hash
210 */
211 class Ed25519_Hashed_Sign_Operation final : public PK_Ops::Signature
212 {
213 public:
214 Ed25519_Hashed_Sign_Operation(const Ed25519_PrivateKey& key, const std::string& hash, bool rfc8032) :
215 m_key(key)
216 {
217 m_hash = HashFunction::create_or_throw(hash);
218
219 if(rfc8032)
220 {
221 m_domain_sep = std::vector<uint8_t>{
222 0x53, 0x69, 0x67, 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x20, 0x6E, 0x6F, 0x20, 0x45, 0x64,
223 0x32, 0x35, 0x35, 0x31, 0x39, 0x20, 0x63, 0x6F, 0x6C, 0x6C, 0x69, 0x73, 0x69, 0x6F, 0x6E, 0x73,
224 0x01, 0x00 };
225 }
226 }
227
228 size_t signature_length() const override { return 64; }
229
230 void update(const uint8_t msg[], size_t msg_len) override
231 {
232 m_hash->update(msg, msg_len);
233 }
234
235 secure_vector<uint8_t> sign(RandomNumberGenerator&) override
236 {
237 secure_vector<uint8_t> sig(64);
238 std::vector<uint8_t> msg_hash(m_hash->output_length());
239 m_hash->final(msg_hash.data());
240 ed25519_sign(sig.data(),
241 msg_hash.data(), msg_hash.size(),
242 m_key.get_private_key().data(),
243 m_domain_sep.data(), m_domain_sep.size());
244 return sig;
245 }
246
247 private:
248 std::unique_ptr<HashFunction> m_hash;
249 const Ed25519_PrivateKey& m_key;
250 std::vector<uint8_t> m_domain_sep;
251 };
252
253 }
254
255 std::unique_ptr<PK_Ops::Verification>
256 Ed25519_PublicKey::create_verification_op(const std::string& params,
257 const std::string& provider) const
258 {
259 if(provider == "base" || provider.empty())
260 {
261 if(params == "" || params == "Identity" || params == "Pure")
262 return std::unique_ptr<PK_Ops::Verification>(new Ed25519_Pure_Verify_Operation(*this));
263 else if(params == "Ed25519ph")
264 return std::unique_ptr<PK_Ops::Verification>(new Ed25519_Hashed_Verify_Operation(*this, "SHA-512", true));
265 else
266 return std::unique_ptr<PK_Ops::Verification>(new Ed25519_Hashed_Verify_Operation(*this, params, false));
267 }
268 throw Provider_Not_Found(algo_name(), provider);
269 }
270
271 std::unique_ptr<PK_Ops::Signature>
272 Ed25519_PrivateKey::create_signature_op(RandomNumberGenerator&,
273 const std::string& params,
274 const std::string& provider) const
275 {
276 if(provider == "base" || provider.empty())
277 {
278 if(params == "" || params == "Identity" || params == "Pure")
279 return std::unique_ptr<PK_Ops::Signature>(new Ed25519_Pure_Sign_Operation(*this));
280 else if(params == "Ed25519ph")
281 return std::unique_ptr<PK_Ops::Signature>(new Ed25519_Hashed_Sign_Operation(*this, "SHA-512", true));
282 else
283 return std::unique_ptr<PK_Ops::Signature>(new Ed25519_Hashed_Sign_Operation(*this, params, false));
284 }
285 throw Provider_Not_Found(algo_name(), provider);
286 }
287
288 }
Botan::ed25519_gen_keypair
void ed25519_gen_keypair(uint8_t *pk, uint8_t *sk, const uint8_t seed[32])
Definition: ed25519.cpp:18
Botan::Ed25519_PublicKey::m_public
std::vector< uint8_t > m_public
Definition: ed25519.h:55
Botan::Ed25519_PublicKey::Ed25519_PublicKey
Ed25519_PublicKey()=default
Botan::Ed25519_PublicKey::algo_name
std::string algo_name() const override
Definition: ed25519.h:21
Botan::HashFunction::create_or_throw
static std::unique_ptr< HashFunction > create_or_throw(const std::string &algo_spec, const std::string &provider="")
Definition: hash.cpp:344
Botan::Ed25519_PrivateKey::create_signature_op
std::unique_ptr< PK_Ops::Signature > create_signature_op(RandomNumberGenerator &rng, const std::string &params, const std::string &provider) const override
Definition: ed25519_key.cpp:272
m_hash
std::unique_ptr< HashFunction > m_hash
Definition: ed25519_key.cpp:173
Botan::RandomNumberGenerator::random_vec
secure_vector< uint8_t > random_vec(size_t bytes)
Definition: rng.h:141
Botan::Ed25519_PublicKey
Definition: ed25519.h:18
Botan::RandomNumberGenerator
Definition: rng.h:24
Botan::Ed25519_PublicKey::check_key
bool check_key(RandomNumberGenerator &rng, bool strong) const override
Definition: ed25519_key.cpp:25
final
int(* final)(unsigned char *, CTX *)
Definition: commoncrypto_hash.cpp:28
Botan::DER_Encoder::get_contents
secure_vector< uint8_t > get_contents()
Definition: der_enc.cpp:152
m_msg
std::vector< uint8_t > m_msg
Definition: ed25519_key.cpp:131
Botan::BER_Decoder::decode
BER_Decoder & decode(bool &out)
Definition: ber_dec.h:170
Botan::Ed25519_PublicKey::create_verification_op
std::unique_ptr< PK_Ops::Verification > create_verification_op(const std::string &params, const std::string &provider) const override
Definition: ed25519_key.cpp:256
Botan::Ed25519_PrivateKey::private_key_bits
secure_vector< uint8_t > private_key_bits() const override
Definition: ed25519_key.cpp:90
Botan::Public_Key::get_oid
virtual OID get_oid() const
Definition: pk_keys.cpp:53
m_domain_sep
std::vector< uint8_t > m_domain_sep
Definition: ed25519_key.cpp:175
Botan::Decoding_Error
Definition: exceptn.h:199
Botan::DER_Encoder::encode
DER_Encoder & encode(bool b)
Definition: der_enc.cpp:285
Botan::DER_Encoder
Definition: der_enc.h:23
Botan::secure_vector
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:65
Botan::Ed25519_PrivateKey::check_key
bool check_key(RandomNumberGenerator &rng, bool strong) const override
Definition: ed25519_key.cpp:96
m_key
const Ed25519_PublicKey & m_key
Definition: ed25519_key.cpp:132
BOTAN_ASSERT_EQUAL
#define BOTAN_ASSERT_EQUAL(expr1, expr2, assertion_made)
Definition: assert.h:81
Botan::Ed25519_PublicKey::public_key_bits
std::vector< uint8_t > public_key_bits() const override
Definition: ed25519_key.cpp:47
Botan::Ed25519_PrivateKey::Ed25519_PrivateKey
Ed25519_PrivateKey(const AlgorithmIdentifier &alg_id, const secure_vector< uint8_t > &key_bits)
Definition: ed25519_key.cpp:77
Botan::AlgorithmIdentifier::USE_EMPTY_PARAM
Definition: alg_id.h:24
Botan::BER_Decoder::discard_remaining
BER_Decoder & discard_remaining()
Definition: ber_dec.cpp:226
Botan
Definition: alg_id.cpp:13
Botan::OCTET_STRING
Definition: asn1_obj.h:36
update
int(* update)(CTX *, const void *, CC_LONG len)
Definition: commoncrypto_hash.cpp:27
Botan::AlgorithmIdentifier
Definition: alg_id.h:21
Botan::ed25519_verify
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
Botan::Provider_Not_Found
Definition: exceptn.h:278
Botan::BER_Decoder
Definition: ber_dec.h:21
Botan::Ed25519_PublicKey::algorithm_identifier
AlgorithmIdentifier algorithm_identifier() const override
Definition: ed25519_key.cpp:20
hash
MechanismType hash
Definition: p11_mechanism.cpp:64
Botan::PK_Ops::Verification
Definition: pk_ops.h:68
Botan::ed25519_sign
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