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