Crypto++ 8.9 Free C++ class library of cryptographic schemes

xed25519.cpp
1 // xed25519.cpp - written and placed in public domain by Jeffrey Walton
2 // Crypto++ specific implementation wrapped around Andrew
3 // Moon's public domain curve25519-donna and ed25519-donna,
4 // https://github.com/floodyberry/curve25519-donna and
5 // https://github.com/floodyberry/ed25519-donna.
6
7 #include "pch.h"
8
9 #include "cryptlib.h"
10 #include "asn.h"
11 #include "integer.h"
12 #include "filters.h"
13 #include "stdcpp.h"
14
15 #include "xed25519.h"
16 #include "donna.h"
17
18 ANONYMOUS_NAMESPACE_BEGIN
19
20 using CryptoPP::byte;
21
22 CRYPTOPP_ALIGN_DATA(16)
23 const byte blacklist[][32] = {
24 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
25 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
26 { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
27 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
28 { 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3, 0xfa, 0xf1, 0x9f, 0xc4, 0x6a,
29 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, 0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00 },
30 { 0x5f, 0x9c, 0x95, 0xbc, 0xa3, 0x50, 0x8c, 0x24, 0xb1, 0xd0, 0xb1, 0x55, 0x9c, 0x83, 0xef, 0x5b,
31 0x04, 0x44, 0x5c, 0xc4, 0x58, 0x1c, 0x8e, 0x86, 0xd8, 0x22, 0x4e, 0xdd, 0xd0, 0x9f, 0x11, 0x57 },
32 { 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
33 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f },
34 { 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
35 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f },
36 { 0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
37 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f },
38 { 0xcd, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3, 0xfa, 0xf1, 0x9f, 0xc4, 0x6a,
39 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, 0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x80 },
40 { 0x4c, 0x9c, 0x95, 0xbc, 0xa3, 0x50, 0x8c, 0x24, 0xb1, 0xd0, 0xb1, 0x55, 0x9c, 0x83, 0xef, 0x5b,
41 0x04, 0x44, 0x5c, 0xc4, 0x58, 0x1c, 0x8e, 0x86, 0xd8, 0x22, 0x4e, 0xdd, 0xd0, 0x9f, 0x11, 0xd7 },
42 { 0xd9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
43 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
44 { 0xda, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
45 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
46 { 0xdb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
47 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }
48 };
49
50 bool HasSmallOrder(const byte y[32])
51 {
52 // The magic 12 is the count of blaklisted points
53 byte c[12] = { 0 };
54 for (size_t j = 0; j < 32; j++) {
55 for (size_t i = 0; i < COUNTOF(blacklist); i++) {
56 c[i] |= y[j] ^ blacklist[i][j];
57 }
58 }
59
60 unsigned int k = 0;
61 for (size_t i = 0; i < COUNTOF(blacklist); i++) {
62 k |= (c[i] - 1);
63 }
64
65 return (bool)((k >> 8) & 1);
66 }
67
68 ANONYMOUS_NAMESPACE_END
69
70 NAMESPACE_BEGIN(CryptoPP)
71
72 // ******************** x25519 Agreement ************************* //
73
74 x25519::x25519(const byte y[PUBLIC_KEYLENGTH], const byte x[SECRET_KEYLENGTH])
75 {
76 std::memcpy(m_pk, y, PUBLIC_KEYLENGTH);
77 std::memcpy(m_sk, x, SECRET_KEYLENGTH);
78
79 CRYPTOPP_ASSERT(IsClamped(m_sk) == true);
80 CRYPTOPP_ASSERT(IsSmallOrder(m_pk) == false);
81 }
82
83 x25519::x25519(const byte x[SECRET_KEYLENGTH])
84 {
85 std::memcpy(m_sk, x, SECRET_KEYLENGTH);
86 Donna::curve25519_mult(m_pk, m_sk);
87
88 CRYPTOPP_ASSERT(IsClamped(m_sk) == true);
89 CRYPTOPP_ASSERT(IsSmallOrder(m_pk) == false);
90 }
91
92 x25519::x25519(const Integer &y, const Integer &x)
93 {
94 CRYPTOPP_ASSERT(y.MinEncodedSize() <= PUBLIC_KEYLENGTH);
95 CRYPTOPP_ASSERT(x.MinEncodedSize() <= SECRET_KEYLENGTH);
96
97 y.Encode(m_pk, PUBLIC_KEYLENGTH); std::reverse(m_pk+0, m_pk+PUBLIC_KEYLENGTH);
98 x.Encode(m_sk, SECRET_KEYLENGTH); std::reverse(m_sk+0, m_sk+SECRET_KEYLENGTH);
99
100 CRYPTOPP_ASSERT(IsClamped(m_sk) == true);
101 CRYPTOPP_ASSERT(IsSmallOrder(m_pk) == false);
102 }
103
104 x25519::x25519(const Integer &x)
105 {
106 CRYPTOPP_ASSERT(x.MinEncodedSize() <= SECRET_KEYLENGTH);
107
108 x.Encode(m_sk, SECRET_KEYLENGTH);
109 std::reverse(m_sk+0, m_sk+SECRET_KEYLENGTH);
110 Donna::curve25519_mult(m_pk, m_sk);
111
112 CRYPTOPP_ASSERT(IsClamped(m_sk) == true);
113 CRYPTOPP_ASSERT(IsSmallOrder(m_pk) == false);
114 }
115
116 x25519::x25519(RandomNumberGenerator &rng)
117 {
118 rng.GenerateBlock(m_sk, SECRET_KEYLENGTH);
119 ClampKey(m_sk);
120 SecretToPublicKey(m_pk, m_sk);
121 }
122
123 x25519::x25519(BufferedTransformation &params)
124 {
125 Load(params);
126 }
127
128 void x25519::ClampKey(byte x[SECRET_KEYLENGTH]) const
129 {
130 x[0] &= 248; x[31] &= 127; x[31] |= 64;
131 }
132
133 bool x25519::IsClamped(const byte x[SECRET_KEYLENGTH]) const
134 {
135 return (x[0] & 248) == x[0] && (x[31] & 127) == x[31] && (x[31] | 64) == x[31];
136 }
137
138 bool x25519::IsSmallOrder(const byte y[PUBLIC_KEYLENGTH]) const
139 {
140 return HasSmallOrder(y);
141 }
142
143 void x25519::SecretToPublicKey(byte y[PUBLIC_KEYLENGTH], const byte x[SECRET_KEYLENGTH]) const
144 {
145 Donna::curve25519_mult(y, x);
146 }
147
148 void x25519::BERDecodeAndCheckAlgorithmID(BufferedTransformation &bt)
149 {
150 // We have not yet determined the OID to use for this object.
151 // We can't use OID's decoder because it throws BERDecodeError
152 // if the OIDs do not match.
153 OID oid(bt);
154
155 // 1.3.6.1.4.1.3029.1.5.1/curvey25519 from Cryptlib used by OpenPGP.
156 // https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-rfc4880bis
157 if (!m_oid.Empty() && m_oid != oid)
158 BERDecodeError(); // Only accept user specified OID
159 else if (oid == ASN1::curve25519() || oid == ASN1::X25519() ||
160 oid == OID(1)+3+6+1+4+1+3029+1+5)
161 m_oid = oid; // Accept any of the x25519 OIDs
162 else
163 BERDecodeError();
164 }
165
166 void x25519::BERDecode(BufferedTransformation &bt)
167 {
168 // https://tools.ietf.org/html/rfc8410, section 7 and
169 // https://www.cryptopp.com/wiki/curve25519_keys
170 BERSequenceDecoder privateKeyInfo(bt);
171 word32 version;
172 BERDecodeUnsigned<word32>(privateKeyInfo, version, INTEGER, 0, 1); // check version
173
174 BERSequenceDecoder algorithm(privateKeyInfo);
175 // GetAlgorithmID().BERDecodeAndCheck(algorithm);
176 BERDecodeAndCheckAlgorithmID(algorithm);
177 algorithm.MessageEnd();
178
179 BERGeneralDecoder octetString(privateKeyInfo, OCTET_STRING);
180 BERDecodePrivateKey(octetString, false, (size_t)privateKeyInfo.RemainingLength());
181 octetString.MessageEnd();
182
183 // publicKey [1] IMPLICIT PublicKey OPTIONAL
184 bool generatePublicKey = true;
185 if (privateKeyInfo.EndReached() == false /*version == 1?*/)
186 {
187 // Should we test this before decoding? In either case we
188 // just throw a BERDecodeErr() when we can't parse it.
189 BERGeneralDecoder publicKey(privateKeyInfo, CONTEXT_SPECIFIC | CONSTRUCTED | 1);
190 SecByteBlock subjectPublicKey;
191 unsigned int unusedBits;
192 BERDecodeBitString(publicKey, subjectPublicKey, unusedBits);
193 CRYPTOPP_ASSERT(unusedBits == 0);
194 CRYPTOPP_ASSERT(subjectPublicKey.size() == PUBLIC_KEYLENGTH);
195 if (subjectPublicKey.size() != PUBLIC_KEYLENGTH)
196 BERDecodeError();
197 std::memcpy(m_pk.begin(), subjectPublicKey, PUBLIC_KEYLENGTH);
198 generatePublicKey = false;
199 publicKey.MessageEnd();
200 }
201
202 privateKeyInfo.MessageEnd();
203
204 if (generatePublicKey)
205 Donna::curve25519_mult(m_pk, m_sk);
206
207 CRYPTOPP_ASSERT(IsClamped(m_sk) == true);
208 CRYPTOPP_ASSERT(IsSmallOrder(m_pk) == false);
209 }
210
211 void x25519::DEREncode(BufferedTransformation &bt, int version) const
212 {
213 // https://tools.ietf.org/html/rfc8410, section 7 and
214 // https://www.cryptopp.com/wiki/curve25519_keys
215 CRYPTOPP_ASSERT(version == 0 || version == 1);
216
217 DERSequenceEncoder privateKeyInfo(bt);
218 DEREncodeUnsigned<word32>(privateKeyInfo, version);
219
220 DERSequenceEncoder algorithm(privateKeyInfo);
221 GetAlgorithmID().DEREncode(algorithm);
222 algorithm.MessageEnd();
223
224 DERGeneralEncoder octetString(privateKeyInfo, OCTET_STRING);
225 DEREncodePrivateKey(octetString);
226 octetString.MessageEnd();
227
228 if (version == 1)
229 {
230 DERGeneralEncoder publicKey(privateKeyInfo, CONTEXT_SPECIFIC | CONSTRUCTED | 1);
231 DEREncodeBitString(publicKey, m_pk, PUBLIC_KEYLENGTH);
232 publicKey.MessageEnd();
233 }
234
235 privateKeyInfo.MessageEnd();
236 }
237
238 void x25519::BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t /*size*/)
239 {
240 // https://tools.ietf.org/html/rfc8410 and
241 // https://www.cryptopp.com/wiki/curve25519_keys
242
243 BERGeneralDecoder privateKey(bt, OCTET_STRING);
244
245 if (!privateKey.IsDefiniteLength())
246 BERDecodeError();
247
248 size_t size = privateKey.Get(m_sk, SECRET_KEYLENGTH);
249 if (size != SECRET_KEYLENGTH)
250 BERDecodeError();
251
252 // We don't know how to decode them
253 if (parametersPresent)
254 BERDecodeError();
255
256 privateKey.MessageEnd();
257 }
258
259 void x25519::DEREncodePrivateKey(BufferedTransformation &bt) const
260 {
261 // https://tools.ietf.org/html/rfc8410
262 DERGeneralEncoder privateKey(bt, OCTET_STRING);
263 privateKey.Put(m_sk, SECRET_KEYLENGTH);
264 privateKey.MessageEnd();
265 }
266
267 bool x25519::Validate(RandomNumberGenerator &rng, unsigned int level) const
268 {
269 CRYPTOPP_UNUSED(rng);
270 CRYPTOPP_ASSERT(IsClamped(m_sk) == true);
271 CRYPTOPP_ASSERT(IsSmallOrder(m_pk) == false);
272
273 if (level >= 1 && IsClamped(m_sk) == false)
274 return false;
275 if (level >= 2 && IsSmallOrder(m_pk) == true)
276 return false;
277 if (level >= 3)
278 {
279 // Verify m_pk is pairwise consistent with m_sk
280 SecByteBlock pk(PUBLIC_KEYLENGTH);
281 SecretToPublicKey(pk, m_sk);
282
283 if (VerifyBufsEqual(pk, m_pk, PUBLIC_KEYLENGTH) == false)
284 return false;
285 }
286
287 return true;
288 }
289
290 bool x25519::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
291 {
292 if (std::strcmp(name, Name::PrivateExponent()) == 0 || std::strcmp(name, "SecretKey") == 0)
293 {
294 this->ThrowIfTypeMismatch(name, typeid(ConstByteArrayParameter), valueType);
295 reinterpret_cast<ConstByteArrayParameter*>(pValue)->Assign(m_sk, SECRET_KEYLENGTH, false);
296 return true;
297 }
298
299 if (std::strcmp(name, Name::PublicElement()) == 0)
300 {
301 this->ThrowIfTypeMismatch(name, typeid(ConstByteArrayParameter), valueType);
302 reinterpret_cast<ConstByteArrayParameter*>(pValue)->Assign(m_pk, PUBLIC_KEYLENGTH, false);
303 return true;
304 }
305
306 if (std::strcmp(name, Name::GroupOID()) == 0)
307 {
308 if (m_oid.Empty())
309 return false;
310
311 this->ThrowIfTypeMismatch(name, typeid(OID), valueType);
312 *reinterpret_cast<OID *>(pValue) = m_oid;
313 return true;
314 }
315
316 return false;
317 }
318
319 void x25519::AssignFrom(const NameValuePairs &source)
320 {
321 ConstByteArrayParameter val;
322 if (source.GetValue(Name::PrivateExponent(), val) || source.GetValue("SecretKey", val))
323 {
324 std::memcpy(m_sk, val.begin(), SECRET_KEYLENGTH);
325 }
326
327 if (source.GetValue(Name::PublicElement(), val))
328 {
329 std::memcpy(m_pk, val.begin(), PUBLIC_KEYLENGTH);
330 }
331
332 OID oid;
333 if (source.GetValue(Name::GroupOID(), oid))
334 {
335 m_oid = oid;
336 }
337
338 bool derive = false;
339 if (source.GetValue("DerivePublicKey", derive) && derive == true)
340 SecretToPublicKey(m_pk, m_sk);
341 }
342
343 void x25519::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params)
344 {
345 ConstByteArrayParameter seed;
346 if (params.GetValue(Name::Seed(), seed) && rng.CanIncorporateEntropy())
347 rng.IncorporateEntropy(seed.begin(), seed.size());
348
349 rng.GenerateBlock(m_sk, SECRET_KEYLENGTH);
350 ClampKey(m_sk);
351 SecretToPublicKey(m_pk, m_sk);
352 }
353
354 void x25519::GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
355 {
356 rng.GenerateBlock(privateKey, SECRET_KEYLENGTH);
357 ClampKey(privateKey);
358 }
359
360 void x25519::GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
361 {
362 CRYPTOPP_UNUSED(rng);
363 SecretToPublicKey(publicKey, privateKey);
364 }
365
366 bool x25519::Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey) const
367 {
368 CRYPTOPP_ASSERT(agreedValue != NULLPTR);
369 CRYPTOPP_ASSERT(otherPublicKey != NULLPTR);
370
371 if (validateOtherPublicKey && IsSmallOrder(otherPublicKey))
372 return false;
373
374 return Donna::curve25519_mult(agreedValue, privateKey, otherPublicKey) == 0;
375 }
376
377 // ******************** ed25519 Signer ************************* //
378
379 void ed25519PrivateKey::SecretToPublicKey(byte y[PUBLIC_KEYLENGTH], const byte x[SECRET_KEYLENGTH]) const
380 {
381 int ret = Donna::ed25519_publickey(y, x);
382 CRYPTOPP_ASSERT(ret == 0); CRYPTOPP_UNUSED(ret);
383 }
384
385 bool ed25519PrivateKey::IsSmallOrder(const byte y[PUBLIC_KEYLENGTH]) const
386 {
387 return HasSmallOrder(y);
388 }
389
390 bool ed25519PrivateKey::Validate(RandomNumberGenerator &rng, unsigned int level) const
391 {
392 CRYPTOPP_UNUSED(rng);
393 CRYPTOPP_ASSERT(IsSmallOrder(m_pk) == false);
394
395 if (level >= 1 && IsSmallOrder(m_pk) == true)
396 return false;
397 if (level >= 3)
398 {
399 // Verify m_pk is pairwise consistent with m_sk
400 SecByteBlock pk(PUBLIC_KEYLENGTH);
401 SecretToPublicKey(pk, m_sk);
402
403 if (VerifyBufsEqual(pk, m_pk, PUBLIC_KEYLENGTH) == false)
404 return false;
405 }
406
407 return true;
408 }
409
410 bool ed25519PrivateKey::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
411 {
412 if (std::strcmp(name, Name::PrivateExponent()) == 0 || std::strcmp(name, "SecretKey") == 0)
413 {
414 this->ThrowIfTypeMismatch(name, typeid(ConstByteArrayParameter), valueType);
415 reinterpret_cast<ConstByteArrayParameter*>(pValue)->Assign(m_sk, SECRET_KEYLENGTH, false);
416 return true;
417 }
418
419 if (std::strcmp(name, Name::PublicElement()) == 0)
420 {
421 this->ThrowIfTypeMismatch(name, typeid(ConstByteArrayParameter), valueType);
422 reinterpret_cast<ConstByteArrayParameter*>(pValue)->Assign(m_pk, PUBLIC_KEYLENGTH, false);
423 return true;
424 }
425
426 if (std::strcmp(name, Name::GroupOID()) == 0)
427 {
428 if (m_oid.Empty())
429 return false;
430
431 this->ThrowIfTypeMismatch(name, typeid(OID), valueType);
432 *reinterpret_cast<OID *>(pValue) = m_oid;
433 return true;
434 }
435
436 return false;
437 }
438
439 void ed25519PrivateKey::AssignFrom(const NameValuePairs &source)
440 {
441 ConstByteArrayParameter val;
442 if (source.GetValue(Name::PrivateExponent(), val) || source.GetValue("SecretKey", val))
443 {
444 CRYPTOPP_ASSERT(val.size() == SECRET_KEYLENGTH);
445 std::memcpy(m_sk, val.begin(), SECRET_KEYLENGTH);
446 }
447 if (source.GetValue(Name::PublicElement(), val))
448 {
449 CRYPTOPP_ASSERT(val.size() == PUBLIC_KEYLENGTH);
450 std::memcpy(m_pk, val.begin(), PUBLIC_KEYLENGTH);
451 }
452
453 OID oid;
454 if (source.GetValue(Name::GroupOID(), oid))
455 {
456 m_oid = oid;
457 }
458
459 bool derive = false;
460 if (source.GetValue("DerivePublicKey", derive) && derive == true)
461 SecretToPublicKey(m_pk, m_sk);
462
463 CRYPTOPP_ASSERT(IsSmallOrder(m_pk) == false);
464 }
465
466 void ed25519PrivateKey::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params=g_nullNameValuePairs)
467 {
468 ConstByteArrayParameter seed;
469 if (params.GetValue(Name::Seed(), seed) && rng.CanIncorporateEntropy())
470 rng.IncorporateEntropy(seed.begin(), seed.size());
471
472 rng.GenerateBlock(m_sk, SECRET_KEYLENGTH);
473 int ret = Donna::ed25519_publickey(m_pk, m_sk);
474 CRYPTOPP_ASSERT(ret == 0); CRYPTOPP_UNUSED(ret);
475 }
476
477 void ed25519PrivateKey::MakePublicKey (PublicKey &pub) const
478 {
479 pub.AssignFrom(MakeParameters
480 (Name::PublicElement(), ConstByteArrayParameter(m_pk.begin(), PUBLIC_KEYLENGTH))
481 (Name::GroupOID(), GetAlgorithmID()));
482 }
483
484 void ed25519PrivateKey::BERDecodeAndCheckAlgorithmID(BufferedTransformation &bt)
485 {
486 // We have not yet determined the OID to use for this object.
487 // We can't use OID's decoder because it throws BERDecodeError
488 // if the OIDs do not match.
489 OID oid(bt);
490
491 if (!m_oid.Empty() && m_oid != oid)
492 BERDecodeError(); // Only accept user specified OID
493 else if (oid == ASN1::curve25519() || oid == ASN1::Ed25519())
494 m_oid = oid; // Accept any of the ed25519PrivateKey OIDs
495 else
496 BERDecodeError();
497 }
498
499 void ed25519PrivateKey::BERDecode(BufferedTransformation &bt)
500 {
501 // https://tools.ietf.org/html/rfc8410, section 7 and
502 // https://www.cryptopp.com/wiki/curve25519_keys
503 BERSequenceDecoder privateKeyInfo(bt);
504 word32 version;
505 BERDecodeUnsigned<word32>(privateKeyInfo, version, INTEGER, 0, 1); // check version
506
507 BERSequenceDecoder algorithm(privateKeyInfo);
508 // GetAlgorithmID().BERDecodeAndCheck(algorithm);
509 BERDecodeAndCheckAlgorithmID(algorithm);
510 algorithm.MessageEnd();
511
512 BERGeneralDecoder octetString(privateKeyInfo, OCTET_STRING);
513 BERDecodePrivateKey(octetString, false, (size_t)privateKeyInfo.RemainingLength());
514 octetString.MessageEnd();
515
516 // publicKey [1] IMPLICIT PublicKey OPTIONAL
517 bool generatePublicKey = true;
518 if (privateKeyInfo.EndReached() == false /*version == 1?*/)
519 {
520 // Should we test this before decoding? In either case we
521 // just throw a BERDecodeErr() when we can't parse it.
522 BERGeneralDecoder publicKey(privateKeyInfo, CONTEXT_SPECIFIC | CONSTRUCTED | 1);
523 SecByteBlock subjectPublicKey;
524 unsigned int unusedBits;
525 BERDecodeBitString(publicKey, subjectPublicKey, unusedBits);
526 CRYPTOPP_ASSERT(unusedBits == 0);
527 CRYPTOPP_ASSERT(subjectPublicKey.size() == PUBLIC_KEYLENGTH);
528 if (subjectPublicKey.size() != PUBLIC_KEYLENGTH)
529 BERDecodeError();
530 std::memcpy(m_pk.begin(), subjectPublicKey, PUBLIC_KEYLENGTH);
531 generatePublicKey = false;
532 publicKey.MessageEnd();
533 }
534
535 privateKeyInfo.MessageEnd();
536
537 if (generatePublicKey)
538 Donna::ed25519_publickey(m_pk, m_sk);
539
540 CRYPTOPP_ASSERT(IsSmallOrder(m_pk) == false);
541 }
542
543 void ed25519PrivateKey::DEREncode(BufferedTransformation &bt, int version) const
544 {
545 // https://tools.ietf.org/html/rfc8410, section 7 and
546 // https://www.cryptopp.com/wiki/curve25519_keys
547 CRYPTOPP_ASSERT(version == 0 || version == 1);
548
549 DERSequenceEncoder privateKeyInfo(bt);
550 DEREncodeUnsigned<word32>(privateKeyInfo, version);
551
552 DERSequenceEncoder algorithm(privateKeyInfo);
553 GetAlgorithmID().DEREncode(algorithm);
554 algorithm.MessageEnd();
555
556 DERGeneralEncoder octetString(privateKeyInfo, OCTET_STRING);
557 DEREncodePrivateKey(octetString);
558 octetString.MessageEnd();
559
560 if (version == 1)
561 {
562 DERGeneralEncoder publicKey(privateKeyInfo, CONTEXT_SPECIFIC | CONSTRUCTED | 1);
563 DEREncodeBitString(publicKey, m_pk, PUBLIC_KEYLENGTH);
564 publicKey.MessageEnd();
565 }
566
567 privateKeyInfo.MessageEnd();
568 }
569
570 void ed25519PrivateKey::BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t /*size*/)
571 {
572 // https://tools.ietf.org/html/rfc8410 and
573 // https://www.cryptopp.com/wiki/curve25519_keys
574
575 BERGeneralDecoder privateKey(bt, OCTET_STRING);
576
577 if (!privateKey.IsDefiniteLength())
578 BERDecodeError();
579
580 size_t size = privateKey.Get(m_sk, SECRET_KEYLENGTH);
581 if (size != SECRET_KEYLENGTH)
582 BERDecodeError();
583
584 // We don't know how to decode them
585 if (parametersPresent)
586 BERDecodeError();
587
588 privateKey.MessageEnd();
589 }
590
591 void ed25519PrivateKey::DEREncodePrivateKey(BufferedTransformation &bt) const
592 {
593 // https://tools.ietf.org/html/rfc8410
594 DERGeneralEncoder privateKey(bt, OCTET_STRING);
595 privateKey.Put(m_sk, SECRET_KEYLENGTH);
596 privateKey.MessageEnd();
597 }
598
599 void ed25519PrivateKey::SetPrivateExponent (const byte x[SECRET_KEYLENGTH])
600 {
601 AssignFrom(MakeParameters
602 (Name::PrivateExponent(), ConstByteArrayParameter(x, SECRET_KEYLENGTH))
603 ("DerivePublicKey", true));
604 }
605
606 void ed25519PrivateKey::SetPrivateExponent (const Integer &x)
607 {
608 CRYPTOPP_ASSERT(x.MinEncodedSize() <= SECRET_KEYLENGTH);
609
610 SecByteBlock bx(SECRET_KEYLENGTH);
611 x.Encode(bx, SECRET_KEYLENGTH); std::reverse(bx+0, bx+SECRET_KEYLENGTH);
612
613 AssignFrom(MakeParameters
614 (Name::PrivateExponent(), ConstByteArrayParameter(bx, SECRET_KEYLENGTH, false))
615 ("DerivePublicKey", true));
616 }
617
618 const Integer& ed25519PrivateKey::GetPrivateExponent() const
619 {
620 m_x = Integer(m_sk, SECRET_KEYLENGTH, Integer::UNSIGNED, LITTLE_ENDIAN_ORDER);
621 return m_x;
622 }
623
624 ////////////////////////
625
626 ed25519Signer::ed25519Signer(const byte y[PUBLIC_KEYLENGTH], const byte x[SECRET_KEYLENGTH])
627 {
628 AccessPrivateKey().AssignFrom(MakeParameters
629 (Name::PrivateExponent(), ConstByteArrayParameter(x, SECRET_KEYLENGTH, false))
630 (Name::PublicElement(), ConstByteArrayParameter(y, PUBLIC_KEYLENGTH, false)));
631 }
632
633 ed25519Signer::ed25519Signer(const byte x[SECRET_KEYLENGTH])
634 {
635 AccessPrivateKey().AssignFrom(MakeParameters
636 (Name::PrivateExponent(), ConstByteArrayParameter(x, SECRET_KEYLENGTH, false))
637 ("DerivePublicKey", true));
638 }
639
640 ed25519Signer::ed25519Signer(const Integer &y, const Integer &x)
641 {
642 CRYPTOPP_ASSERT(y.MinEncodedSize() <= PUBLIC_KEYLENGTH);
643 CRYPTOPP_ASSERT(x.MinEncodedSize() <= SECRET_KEYLENGTH);
644
645 SecByteBlock by(PUBLIC_KEYLENGTH), bx(SECRET_KEYLENGTH);
646 y.Encode(by, PUBLIC_KEYLENGTH); std::reverse(by+0, by+PUBLIC_KEYLENGTH);
647 x.Encode(bx, SECRET_KEYLENGTH); std::reverse(bx+0, bx+SECRET_KEYLENGTH);
648
649 AccessPrivateKey().AssignFrom(MakeParameters
650 (Name::PublicElement(), ConstByteArrayParameter(by, PUBLIC_KEYLENGTH, false))
651 (Name::PrivateExponent(), ConstByteArrayParameter(bx, SECRET_KEYLENGTH, false)));
652 }
653
654 ed25519Signer::ed25519Signer(const Integer &x)
655 {
656 CRYPTOPP_ASSERT(x.MinEncodedSize() <= SECRET_KEYLENGTH);
657
658 SecByteBlock bx(SECRET_KEYLENGTH);
659 x.Encode(bx, SECRET_KEYLENGTH); std::reverse(bx+0, bx+SECRET_KEYLENGTH);
660
661 AccessPrivateKey().AssignFrom(MakeParameters
662 (Name::PrivateExponent(), ConstByteArrayParameter(bx, SECRET_KEYLENGTH, false))
663 ("DerivePublicKey", true));
664 }
665
666 ed25519Signer::ed25519Signer(const PKCS8PrivateKey &key)
667 {
668 // Load all fields from the other key
669 ByteQueue queue;
670 key.Save(queue);
671 AccessPrivateKey().Load(queue);
672 }
673
674 ed25519Signer::ed25519Signer(RandomNumberGenerator &rng)
675 {
676 AccessPrivateKey().GenerateRandom(rng);
677 }
678
679 ed25519Signer::ed25519Signer(BufferedTransformation &params)
680 {
681 AccessPrivateKey().Load(params);
682 }
683
684 size_t ed25519Signer::SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const
685 {
686 CRYPTOPP_ASSERT(signature != NULLPTR); CRYPTOPP_UNUSED(rng);
687
688 ed25519_MessageAccumulator& accum = dynamic_cast<ed25519_MessageAccumulator&>(messageAccumulator);
689 const ed25519PrivateKey& pk = dynamic_cast<const ed25519PrivateKey&>(GetPrivateKey());
690 int ret = Donna::ed25519_sign(accum.data(), accum.size(), pk.GetPrivateKeyBytePtr(), pk.GetPublicKeyBytePtr(), signature);
691 CRYPTOPP_ASSERT(ret == 0);
692
693 if (restart)
694 accum.Restart();
695
696 return ret == 0 ? SIGNATURE_LENGTH : 0;
697 }
698
699 size_t ed25519Signer::SignStream (RandomNumberGenerator &rng, std::istream& stream, byte *signature) const
700 {
701 CRYPTOPP_ASSERT(signature != NULLPTR); CRYPTOPP_UNUSED(rng);
702
703 const ed25519PrivateKey& pk = dynamic_cast<const ed25519PrivateKey&>(GetPrivateKey());
704 int ret = Donna::ed25519_sign(stream, pk.GetPrivateKeyBytePtr(), pk.GetPublicKeyBytePtr(), signature);
705 CRYPTOPP_ASSERT(ret == 0);
706
707 return ret == 0 ? SIGNATURE_LENGTH : 0;
708 }
709
710 // ******************** ed25519 Verifier ************************* //
711
712 bool ed25519PublicKey::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
713 {
714 if (std::strcmp(name, Name::PublicElement()) == 0)
715 {
716 this->ThrowIfTypeMismatch(name, typeid(ConstByteArrayParameter), valueType);
717 reinterpret_cast<ConstByteArrayParameter*>(pValue)->Assign(m_pk, PUBLIC_KEYLENGTH, false);
718 return true;
719 }
720
721 if (std::strcmp(name, Name::GroupOID()) == 0)
722 {
723 if (m_oid.Empty())
724 return false;
725
726 this->ThrowIfTypeMismatch(name, typeid(OID), valueType);
727 *reinterpret_cast<OID *>(pValue) = m_oid;
728 return true;
729 }
730
731 return false;
732 }
733
734 void ed25519PublicKey::AssignFrom(const NameValuePairs &source)
735 {
736 ConstByteArrayParameter ba;
737 if (source.GetValue(Name::PublicElement(), ba))
738 {
739 std::memcpy(m_pk, ba.begin(), PUBLIC_KEYLENGTH);
740 }
741
742 OID oid;
743 if (source.GetValue(Name::GroupOID(), oid))
744 {
745 m_oid = oid;
746 }
747 }
748
749 void ed25519PublicKey::BERDecodeAndCheckAlgorithmID(BufferedTransformation& bt)
750 {
751 // We have not yet determined the OID to use for this object.
752 // We can't use OID's decoder because it throws BERDecodeError
753 // if the OIDs do not match.
754 OID oid(bt);
755
756 if (!m_oid.Empty() && m_oid != oid)
757 BERDecodeError(); // Only accept user specified OID
758 else if (oid == ASN1::curve25519() || oid == ASN1::Ed25519())
759 m_oid = oid; // Accept any of the ed25519PublicKey OIDs
760 else
761 BERDecodeError();
762 }
763
764 void ed25519PublicKey::BERDecode(BufferedTransformation &bt)
765 {
766 BERSequenceDecoder publicKeyInfo(bt);
767
768 BERSequenceDecoder algorithm(publicKeyInfo);
769 // GetAlgorithmID().BERDecodeAndCheck(algorithm);
770 BERDecodeAndCheckAlgorithmID(algorithm);
771 algorithm.MessageEnd();
772
773 BERDecodePublicKey(publicKeyInfo, false, (size_t)publicKeyInfo.RemainingLength());
774
775 publicKeyInfo.MessageEnd();
776 }
777
778 void ed25519PublicKey::DEREncode(BufferedTransformation &bt) const
779 {
780 DERSequenceEncoder publicKeyInfo(bt);
781
782 DERSequenceEncoder algorithm(publicKeyInfo);
783 GetAlgorithmID().DEREncode(algorithm);
784 algorithm.MessageEnd();
785
786 DEREncodePublicKey(publicKeyInfo);
787
788 publicKeyInfo.MessageEnd();
789 }
790
791 void ed25519PublicKey::BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t /*size*/)
792 {
793 // We don't know how to decode them
794 if (parametersPresent)
795 BERDecodeError();
796
797 SecByteBlock subjectPublicKey;
798 unsigned int unusedBits;
799 BERDecodeBitString(bt, subjectPublicKey, unusedBits);
800
801 CRYPTOPP_ASSERT(unusedBits == 0);
802 CRYPTOPP_ASSERT(subjectPublicKey.size() == PUBLIC_KEYLENGTH);
803 if (subjectPublicKey.size() != PUBLIC_KEYLENGTH)
804 BERDecodeError();
805
806 std::memcpy(m_pk.begin(), subjectPublicKey, PUBLIC_KEYLENGTH);
807 }
808
809 void ed25519PublicKey::DEREncodePublicKey(BufferedTransformation &bt) const
810 {
811 DEREncodeBitString(bt, m_pk, PUBLIC_KEYLENGTH);
812 }
813
814 void ed25519PublicKey::SetPublicElement (const byte y[PUBLIC_KEYLENGTH])
815 {
816 std::memcpy(m_pk, y, PUBLIC_KEYLENGTH);
817 }
818
819 void ed25519PublicKey::SetPublicElement (const Integer &y)
820 {
821 CRYPTOPP_ASSERT(y.MinEncodedSize() <= PUBLIC_KEYLENGTH);
822
823 SecByteBlock by(PUBLIC_KEYLENGTH);
824 y.Encode(by, PUBLIC_KEYLENGTH); std::reverse(by+0, by+PUBLIC_KEYLENGTH);
825
826 std::memcpy(m_pk, by, PUBLIC_KEYLENGTH);
827 }
828
829 const Integer& ed25519PublicKey::GetPublicElement() const
830 {
831 m_y = Integer(m_pk, PUBLIC_KEYLENGTH, Integer::UNSIGNED, LITTLE_ENDIAN_ORDER);
832 return m_y;
833 }
834
835 bool ed25519PublicKey::Validate(RandomNumberGenerator &rng, unsigned int level) const
836 {
837 CRYPTOPP_UNUSED(rng); CRYPTOPP_UNUSED(level);
838 return true;
839 }
840
841 ////////////////////////
842
843 ed25519Verifier::ed25519Verifier(const byte y[PUBLIC_KEYLENGTH])
844 {
845 AccessPublicKey().AssignFrom(MakeParameters
846 (Name::PublicElement(), ConstByteArrayParameter(y, PUBLIC_KEYLENGTH)));
847 }
848
849 ed25519Verifier::ed25519Verifier(const Integer &y)
850 {
851 CRYPTOPP_ASSERT(y.MinEncodedSize() <= PUBLIC_KEYLENGTH);
852
853 SecByteBlock by(PUBLIC_KEYLENGTH);
854 y.Encode(by, PUBLIC_KEYLENGTH); std::reverse(by+0, by+PUBLIC_KEYLENGTH);
855
856 AccessPublicKey().AssignFrom(MakeParameters
857 (Name::PublicElement(), ConstByteArrayParameter(by, PUBLIC_KEYLENGTH, false)));
858 }
859
860 ed25519Verifier::ed25519Verifier(const X509PublicKey &key)
861 {
862 // Load all fields from the other key
863 ByteQueue queue;
864 key.Save(queue);
865 AccessPublicKey().Load(queue);
866 }
867
868 ed25519Verifier::ed25519Verifier(BufferedTransformation &params)
869 {
870 AccessPublicKey().Load(params);
871 }
872
873 ed25519Verifier::ed25519Verifier(const ed25519Signer& signer)
874 {
875 const ed25519PrivateKey& priv = dynamic_cast<const ed25519PrivateKey&>(signer.GetPrivateKey());
876 priv.MakePublicKey(AccessPublicKey());
877 }
878
879 bool ed25519Verifier::VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const
880 {
881 ed25519_MessageAccumulator& accum = static_cast<ed25519_MessageAccumulator&>(messageAccumulator);
882 const ed25519PublicKey& pk = dynamic_cast<const ed25519PublicKey&>(GetPublicKey());
883 int ret = Donna::ed25519_sign_open(accum.data(), accum.size(), pk.GetPublicKeyBytePtr(), accum.signature());
884 accum.Restart();
885
886 return ret == 0;
887 }
888
889 bool ed25519Verifier::VerifyStream(std::istream& stream, const byte *signature, size_t signatureLen) const
890 {
891 CRYPTOPP_ASSERT(signatureLen == SIGNATURE_LENGTH);
892 CRYPTOPP_UNUSED(signatureLen);
893
894 const ed25519PublicKey& pk = static_cast<const ed25519PublicKey&>(GetPublicKey());
895 int ret = Donna::ed25519_sign_open(stream, pk.GetPublicKeyBytePtr(), signature);
896
897 return ret == 0;
898 }
899
900 NAMESPACE_END // CryptoPP
MakeParameters
AlgorithmParameters MakeParameters(const char *name, const T &value, bool throwIfNotUsed=true)
Create an object that implements NameValuePairs.
Definition: algparam.h:508
asn.h
Classes and functions for working with ANS.1 objects.
BERDecodeBitString
CRYPTOPP_DLL size_t BERDecodeBitString(BufferedTransformation &bt, SecByteBlock &str, unsigned int &unusedBits)
DER decode bit string.
DEREncodeBitString
CRYPTOPP_DLL size_t DEREncodeBitString(BufferedTransformation &bt, const byte *str, size_t strLen, unsigned int unusedBits=0)
DER encode bit string.
CONSTRUCTED
@ CONSTRUCTED
ASN.1 Constructed flag.
Definition: asn.h:94
CONTEXT_SPECIFIC
@ CONTEXT_SPECIFIC
ASN.1 Context specific class.
Definition: asn.h:98
OCTET_STRING
@ OCTET_STRING
ASN.1 Octet string.
Definition: asn.h:38
INTEGER
@ INTEGER
ASN.1 Integer.
Definition: asn.h:34
BERDecodeError
void BERDecodeError()
Raises a BERDecodeErr.
Definition: asn.h:104
ASN1CryptoMaterial::Save
void Save(BufferedTransformation &bt) const
DER encode ASN.1 object.
Definition: asn.h:692
BERGeneralDecoder
BER General Decoder.
Definition: asn.h:381
BERGeneralDecoder::EndReached
bool EndReached() const
Determine end of stream.
BERGeneralDecoder::RemainingLength
lword RemainingLength() const
Determine remaining length.
Definition: asn.h:413
BERGeneralDecoder::IsDefiniteLength
bool IsDefiniteLength() const
Determine length encoding.
Definition: asn.h:405
BERGeneralDecoder::MessageEnd
void MessageEnd()
Signals the end of messages to the object.
BERSequenceDecoder
BER Sequence Decoder.
Definition: asn.h:526
BufferedTransformation
Interface for buffered transformations.
Definition: cryptlib.h:1657
BufferedTransformation::Get
virtual size_t Get(byte &outByte)
Retrieve a 8-bit byte.
BufferedTransformation::Put
size_t Put(byte inByte, bool blocking=true)
Input a byte for processing.
Definition: cryptlib.h:1678
ByteQueue
Data structure used to store byte strings.
Definition: queue.h:23
ConstByteArrayParameter
Used to pass byte array input as part of a NameValuePairs object.
Definition: algparam.h:25
ConstByteArrayParameter::size
size_t size() const
Length of the memory block.
Definition: algparam.h:88
ConstByteArrayParameter::begin
const byte * begin() const
Pointer to the first byte in the memory block.
Definition: algparam.h:84
CryptoMaterial::AssignFrom
virtual void AssignFrom(const NameValuePairs &source)=0
Assign values to this object.
CryptoMaterial::Load
virtual void Load(BufferedTransformation &bt)
Loads a key from a BufferedTransformation.
Definition: cryptlib.h:2461
DERGeneralEncoder
DER General Encoder.
Definition: asn.h:492
DERGeneralEncoder::MessageEnd
void MessageEnd()
Signals the end of messages to the object.
DERSequenceEncoder
DER Sequence Encoder.
Definition: asn.h:558
GeneratableCryptoMaterial::GenerateRandom
virtual void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params=g_nullNameValuePairs)
Generate a random key or crypto parameters.
Definition: cryptlib.h:2525
Integer
Multiple precision integer with arithmetic operations.
Definition: integer.h:50
Integer::MinEncodedSize
size_t MinEncodedSize(Signedness sign=UNSIGNED) const
Minimum number of bytes to encode this integer.
Integer::UNSIGNED
@ UNSIGNED
an unsigned value
Definition: integer.h:85
Integer::Encode
void Encode(byte *output, size_t outputLen, Signedness sign=UNSIGNED) const
Encode in big-endian format.
NameValuePairs
Interface for retrieving values given their names.
Definition: cryptlib.h:327
NameValuePairs::GetValue
bool GetValue(const char *name, T &value) const
Get a named value.
Definition: cryptlib.h:384
NameValuePairs::ThrowIfTypeMismatch
static CRYPTOPP_DLL void ThrowIfTypeMismatch(const char *name, const std::type_info &stored, const std::type_info &retrieving)
Ensures an expected name and type is present.
Definition: cryptlib.h:459
OID
Object Identifier.
Definition: asn.h:265
OID::DEREncode
void DEREncode(BufferedTransformation &bt) const
DER encode this OID.
OID::Empty
bool Empty() const
Determine if OID is empty.
Definition: asn.h:311
PK_MessageAccumulator
Interface for accumulating messages to be signed or verified.
Definition: cryptlib.h:2866
PKCS8PrivateKey
Encodes and Decodes privateKeyInfo.
Definition: asn.h:749
PublicKey
Interface for public keys.
Definition: cryptlib.h:2541
RandomNumberGenerator
Interface for random number generators.
Definition: cryptlib.h:1440
RandomNumberGenerator::IncorporateEntropy
virtual void IncorporateEntropy(const byte *input, size_t length)
Update RNG state with additional unpredictable values.
Definition: cryptlib.h:1452
RandomNumberGenerator::CanIncorporateEntropy
virtual bool CanIncorporateEntropy() const
Determines if a generator can accept additional entropy.
Definition: cryptlib.h:1460
RandomNumberGenerator::GenerateBlock
virtual void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
SecBlock::begin
iterator begin()
Provides an iterator pointing to the first element in the memory block.
Definition: secblock.h:836
SecBlock::size
size_type size() const
Provides the count of elements in the SecBlock.
Definition: secblock.h:867
SecByteBlock
SecBlock<byte> typedef.
Definition: secblock.h:1226
X509PublicKey
Encodes and decodes subjectPublicKeyInfo.
Definition: asn.h:703
x25519
x25519 with key validation
Definition: xed25519.h:55
x25519::IsClamped
bool IsClamped(const byte x[SECRET_KEYLENGTH]) const
Determine if private key is clamped.
Definition: xed25519.cpp:133
x25519::BERDecodePrivateKey
void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
Decode privateKey part of privateKeyInfo.
Definition: xed25519.cpp:238
x25519::Agree
bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const
Derive agreed value.
Definition: xed25519.cpp:366
x25519::PUBLIC_KEYLENGTH
static const int PUBLIC_KEYLENGTH
Size of the public key.
Definition: xed25519.h:62
x25519::GetVoidValue
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
Definition: xed25519.cpp:290
x25519::GeneratePrivateKey
void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
Generate private key in this domain.
Definition: xed25519.cpp:354
x25519::IsSmallOrder
bool IsSmallOrder(const byte y[PUBLIC_KEYLENGTH]) const
Test if a key has small order.
Definition: xed25519.cpp:138
x25519::ClampKey
void ClampKey(byte x[SECRET_KEYLENGTH]) const
Clamp a private key.
Definition: xed25519.cpp:128
x25519::BERDecodeAndCheckAlgorithmID
void BERDecodeAndCheckAlgorithmID(BufferedTransformation &bt)
Determine if OID is valid for this object.
Definition: xed25519.cpp:148
x25519::DEREncodePrivateKey
void DEREncodePrivateKey(BufferedTransformation &bt) const
Encode privateKey part of privateKeyInfo.
Definition: xed25519.cpp:259
x25519::DEREncode
void DEREncode(BufferedTransformation &bt) const
Encode this object into a BufferedTransformation.
Definition: xed25519.h:200
x25519::Validate
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
Check this object for errors.
Definition: xed25519.cpp:267
x25519::Load
void Load(BufferedTransformation &bt)
BER decode ASN.1 object.
Definition: xed25519.h:194
x25519::BERDecode
void BERDecode(BufferedTransformation &bt)
Decode this object from a BufferedTransformation.
Definition: xed25519.cpp:166
x25519::x25519
x25519()
Create a x25519 object.
Definition: xed25519.h:74
x25519::SECRET_KEYLENGTH
static const int SECRET_KEYLENGTH
Size of the private key.
Definition: xed25519.h:59
x25519::AssignFrom
void AssignFrom(const NameValuePairs &source)
Assign values to this object.
Definition: xed25519.cpp:319
x25519::GeneratePublicKey
void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
Generate a public key from a private key in this domain.
Definition: xed25519.cpp:360
x25519::GetAlgorithmID
OID GetAlgorithmID() const
Get the Object Identifier.
Definition: xed25519.h:138
x25519::GenerateRandom
void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params)
Generate a random key or crypto parameters.
Definition: xed25519.cpp:343
byte
unsigned char byte
8-bit unsigned datatype
Definition: config_int.h:66
word32
unsigned int word32
32-bit unsigned datatype
Definition: config_int.h:72
cryptlib.h
Abstract base classes that provide a uniform interface to this library.
g_nullNameValuePairs
const NameValuePairs & g_nullNameValuePairs
An empty set of name-value pairs.
Definition: cryptlib.h:534
LITTLE_ENDIAN_ORDER
@ LITTLE_ENDIAN_ORDER
byte order is little-endian
Definition: cryptlib.h:150
donna.h
ed25519_sign_open
int ed25519_sign_open(const byte *message, size_t messageLength, const byte publicKey[32], const byte signature[64])
Verifies a signature on a message.
ed25519_sign
int ed25519_sign(const byte *message, size_t messageLength, const byte secretKey[32], const byte publicKey[32], byte signature[64])
Creates a signature on a message.
ed25519_publickey
int ed25519_publickey(byte publicKey[32], const byte secretKey[32])
Creates a public key from a secret key.
curve25519_mult
int curve25519_mult(byte publicKey[32], const byte secretKey[32])
Generate a public key.
filters.h
Implementation of BufferedTransformation's attachment interface.
integer.h
Multiple precision integer with arithmetic operations.
COUNTOF
#define COUNTOF(arr)
Counts elements in an array.
Definition: misc.h:193
VerifyBufsEqual
CRYPTOPP_DLL bool VerifyBufsEqual(const byte *buf1, const byte *buf2, size_t count)
Performs a near constant-time comparison of two equally sized buffers.
CryptoPP
Crypto++ library namespace.
Name::PrivateExponent
const char * PrivateExponent()
Integer.
Definition: argnames.h:35
Name::PublicElement
const char * PublicElement()
Integer.
Definition: argnames.h:36
Name::GroupOID
const char * GroupOID()
OID.
Definition: argnames.h:41
Name::Seed
const char * Seed()
ConstByteArrayParameter.
Definition: argnames.h:19
pch.h
Precompiled header file.
stdcpp.h
Common C++ header files.
ed25519_MessageAccumulator
ed25519 message accumulator
Definition: xed25519.h:279
ed25519_MessageAccumulator::Restart
void Restart()
Reset the accumulator.
Definition: xed25519.h:304
ed25519_MessageAccumulator::size
size_t size() const
Retrieve size of data buffer.
Definition: xed25519.h:329
ed25519_MessageAccumulator::signature
byte * signature()
Retrieve pointer to signature buffer.
Definition: xed25519.h:311
ed25519_MessageAccumulator::data
const byte * data() const
Retrieve pointer to data buffer.
Definition: xed25519.h:323
ed25519PrivateKey
Ed25519 private key.
Definition: xed25519.h:356
ed25519PrivateKey::GetVoidValue
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
Definition: xed25519.cpp:410
ed25519PrivateKey::GenerateRandom
void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params)
Generate a random key or crypto parameters.
Definition: xed25519.cpp:466
ed25519PrivateKey::MakePublicKey
void MakePublicKey(PublicKey &pub) const
Initializes a public key from this key.
Definition: xed25519.cpp:477
ed25519PrivateKey::GetAlgorithmID
OID GetAlgorithmID() const
Retrieves the OID of the algorithm.
Definition: xed25519.h:377
ed25519PrivateKey::Validate
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
Check this object for errors.
Definition: xed25519.cpp:390
ed25519PrivateKey::DEREncode
void DEREncode(BufferedTransformation &bt) const
Encode this object into a BufferedTransformation.
Definition: xed25519.h:429
ed25519PrivateKey::DEREncodePrivateKey
void DEREncodePrivateKey(BufferedTransformation &bt) const
Encode privateKey part of privateKeyInfo.
Definition: xed25519.cpp:591
ed25519PrivateKey::AssignFrom
void AssignFrom(const NameValuePairs &source)
Assign values to this object.
Definition: xed25519.cpp:439
ed25519PrivateKey::BERDecodeAndCheckAlgorithmID
void BERDecodeAndCheckAlgorithmID(BufferedTransformation &bt)
Determine if OID is valid for this object.
Definition: xed25519.cpp:484
ed25519PrivateKey::BERDecode
void BERDecode(BufferedTransformation &bt)
Decode this object from a BufferedTransformation.
Definition: xed25519.cpp:499
ed25519PrivateKey::IsSmallOrder
bool IsSmallOrder(const byte y[PUBLIC_KEYLENGTH]) const
Test if a key has small order.
Definition: xed25519.cpp:385
ed25519PrivateKey::BERDecodePrivateKey
void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
Decode privateKey part of privateKeyInfo.
Definition: xed25519.cpp:570
ed25519PrivateKey::GetPrivateKeyBytePtr
const byte * GetPrivateKeyBytePtr() const
Retrieve private key byte array.
Definition: xed25519.h:474
ed25519PrivateKey::GetPublicKeyBytePtr
const byte * GetPublicKeyBytePtr() const
Retrieve public key byte array.
Definition: xed25519.h:481
ed25519PrivateKey::SECRET_KEYLENGTH
static const int SECRET_KEYLENGTH
Size of the private key.
Definition: xed25519.h:359
ed25519PrivateKey::PUBLIC_KEYLENGTH
static const int PUBLIC_KEYLENGTH
Size of the public key.
Definition: xed25519.h:362
ed25519PublicKey
Ed25519 public key.
Definition: xed25519.h:635
ed25519PublicKey::BERDecode
void BERDecode(BufferedTransformation &bt)
Decode this object from a BufferedTransformation.
Definition: xed25519.cpp:764
ed25519PublicKey::PUBLIC_KEYLENGTH
static const int PUBLIC_KEYLENGTH
Size of the public key.
Definition: xed25519.h:638
ed25519PublicKey::BERDecodeAndCheckAlgorithmID
void BERDecodeAndCheckAlgorithmID(BufferedTransformation &bt)
Determine if OID is valid for this object.
Definition: xed25519.cpp:749
ed25519PublicKey::GetVoidValue
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
Definition: xed25519.cpp:712
ed25519PublicKey::DEREncodePublicKey
void DEREncodePublicKey(BufferedTransformation &bt) const
Encode subjectPublicKey part of subjectPublicKeyInfo.
Definition: xed25519.cpp:809
ed25519PublicKey::BERDecodePublicKey
void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
Decode subjectPublicKey part of subjectPublicKeyInfo.
Definition: xed25519.cpp:791
ed25519PublicKey::GetAlgorithmID
OID GetAlgorithmID() const
Retrieves the OID of the algorithm.
Definition: xed25519.h:643
ed25519PublicKey::DEREncode
void DEREncode(BufferedTransformation &bt) const
Encode this object into a BufferedTransformation.
Definition: xed25519.cpp:778
ed25519PublicKey::GetPublicKeyBytePtr
const byte * GetPublicKeyBytePtr() const
Retrieve public key byte array.
Definition: xed25519.h:700
ed25519PublicKey::Validate
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
Check this object for errors.
Definition: xed25519.cpp:835
ed25519PublicKey::AssignFrom
void AssignFrom(const NameValuePairs &source)
Assign values to this object.
Definition: xed25519.cpp:734
ed25519Signer
Ed25519 signature algorithm.
Definition: xed25519.h:499
ed25519Signer::ed25519Signer
ed25519Signer()
Create an ed25519Signer object.
Definition: xed25519.h:516
ed25519Signer::GetPrivateKey
const PrivateKey & GetPrivateKey() const
Retrieves a reference to a Private Key.
Definition: xed25519.h:572
ed25519Signer::SignAndRestart
size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const
Sign and restart messageAccumulator.
Definition: xed25519.cpp:684
ed25519Signer::PUBLIC_KEYLENGTH
static const int PUBLIC_KEYLENGTH
Size of the public key.
Definition: xed25519.h:505
ed25519Signer::SECRET_KEYLENGTH
static const int SECRET_KEYLENGTH
Size of the private key.
Definition: xed25519.h:502
ed25519Signer::SIGNATURE_LENGTH
static const int SIGNATURE_LENGTH
Size of the signature.
Definition: xed25519.h:510
ed25519Signer::SignStream
size_t SignStream(RandomNumberGenerator &rng, std::istream &stream, byte *signature) const
Sign a stream.
Definition: xed25519.cpp:699
ed25519Signer::AccessPrivateKey
PrivateKey & AccessPrivateKey()
Retrieves a reference to a Private Key.
Definition: xed25519.h:567
ed25519Verifier::VerifyAndRestart
bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const
Check whether messageAccumulator contains a valid signature and message, and restart messageAccumulat...
Definition: xed25519.cpp:879
ed25519Verifier::ed25519Verifier
ed25519Verifier()
Create an ed25519Verifier object.
Definition: xed25519.h:721
ed25519Verifier::VerifyStream
bool VerifyStream(std::istream &stream, const byte *signature, size_t signatureLen) const
Check whether input signature is a valid signature for input message.
Definition: xed25519.cpp:889
ed25519Verifier::GetPublicKey
const PublicKey & GetPublicKey() const
Retrieves a reference to a Public Key.
Definition: xed25519.h:765
ed25519Verifier::AccessPublicKey
PublicKey & AccessPublicKey()
Retrieves a reference to a Public Key.
Definition: xed25519.h:760
CRYPTOPP_ASSERT
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:68
xed25519.h
Classes for x25519 and ed25519 operations.