Crypto++  8.3
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 {
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 
105 {
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 
117 {
118  rng.GenerateBlock(m_sk, SECRET_KEYLENGTH);
119  ClampKey(m_sk);
120  SecretToPublicKey(m_pk, m_sk);
121 }
122 
124 {
125  Load(params);
126 }
127 
129 {
130  x[0] &= 248; x[31] &= 127; x[31] |= 64;
131 }
132 
134 {
135  return (x[0] & 248) == x[0] && (x[31] & 127) == x[31] && (x[31] | 64) == x[31];
136 }
137 
139 {
140  return HasSmallOrder(y);
141 }
142 
143 void x25519::SecretToPublicKey(byte y[PUBLIC_KEYLENGTH], const byte x[SECRET_KEYLENGTH]) const
144 {
146 }
147 
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 
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 
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 
317 {
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 
341 {
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 
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 
437 {
439  if (source.GetValue(Name::PrivateExponent(), val) || source.GetValue("SecretKey", val))
440  {
442  std::memcpy(m_sk, val.begin(), SECRET_KEYLENGTH);
443  }
444  if (source.GetValue(Name::PublicElement(), val))
445  {
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 
464 {
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 
475 {
479 }
480 
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 
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 
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 
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 {
599  (Name::PrivateExponent(), ConstByteArrayParameter(x, SECRET_KEYLENGTH))
600  ("DerivePublicKey", true));
601 }
602 
603 void ed25519PrivateKey::SetPrivateExponent (const Integer &x)
604 {
606 
607  SecByteBlock bx(SECRET_KEYLENGTH);
608  x.Encode(bx, SECRET_KEYLENGTH); std::reverse(bx+0, bx+SECRET_KEYLENGTH);
609 
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 
638 {
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 
652 {
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 
664 {
665  AccessPrivateKey().GenerateRandom(rng);
666 }
667 
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 
724 {
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 
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 
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 
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 
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 {
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 
839 {
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 
850 {
851  AccessPublicKey().Load(params);
852 }
853 
855 {
856  const ed25519PrivateKey& priv = dynamic_cast<const ed25519PrivateKey&>(signer.GetPrivateKey());
857  priv.MakePublicKey(AccessPublicKey());
858 }
859 
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
Used to pass byte array input as part of a NameValuePairs object.
Definition: algparam.h:24
virtual void AssignFrom(const NameValuePairs &source)=0
Assign values to this object.
x25519 with key validation
Definition: xed25519.h:54
Ed25519 private key.
Definition: xed25519.h:355
x25519()
Create a x25519 object.
Definition: xed25519.h:74
void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params)
Generate a random key or crypto parameters.
Definition: xed25519.cpp:340
void DEREncode(BufferedTransformation &bt) const
Encode this object into a BufferedTransformation.
Definition: xed25519.h:200
bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const
Check whether messageAccumulator contains a valid signature and message, and restart messageAccumulat...
Definition: xed25519.cpp:860
an unsigned value
Definition: integer.h:85
virtual size_t Get(byte &outByte)
Retrieve a 8-bit byte.
size_t size() const
Length of the memory block.
Definition: algparam.h:88
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
Check this object for errors.
Definition: xed25519.cpp:824
ASN.1 Integer.
Definition: asn.h:34
const byte * GetPublicKeyBytePtr() const
Retrieve public key byte array.
Definition: xed25519.h:689
void MessageEnd()
Signals the end of messages to the object.
unsigned int word32
32-bit unsigned datatype
Definition: config_int.h:62
void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
Decode subjectPublicKey part of subjectPublicKeyInfo.
Definition: xed25519.cpp:780
Abstract base classes that provide a uniform interface to this library.
void Restart()
Reset the accumulator.
Definition: xed25519.h:304
size_t size() const
Retrieve size of data buffer.
Definition: xed25519.h:329
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
Interface for random number generators.
Definition: cryptlib.h:1417
void MakePublicKey(PublicKey &pub) const
Initializes a public key from this key.
Definition: xed25519.cpp:474
Common C++ header files.
ed25519Verifier()
Create a ed25519Verifier object.
Definition: xed25519.h:710
CRYPTOPP_DLL size_t DEREncodeBitString(BufferedTransformation &bt, const byte *str, size_t strLen, unsigned int unusedBits=0)
DER encode bit string.
static const int SECRET_KEYLENGTH
Size of the private key.
Definition: xed25519.h:59
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:454
void DEREncodePublicKey(BufferedTransformation &bt) const
Encode subjectPublicKey part of subjectPublicKeyInfo.
Definition: xed25519.cpp:798
SecBlock<byte> typedef.
Definition: secblock.h:1103
BER Sequence Decoder.
Definition: asn.h:524
Interface for buffered transformations.
Definition: cryptlib.h:1634
ASN.1 Constructed flag.
Definition: asn.h:94
void DEREncode(BufferedTransformation &bt) const
Encode this object into a BufferedTransformation.
Definition: xed25519.cpp:767
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
Definition: xed25519.cpp:407
byte order is little-endian
Definition: cryptlib.h:145
const char * PrivateExponent()
Integer.
Definition: argnames.h:35
size_t SignStream(RandomNumberGenerator &rng, std::istream &stream, byte *signature) const
Sign a stream.
Definition: xed25519.cpp:688
bool Empty() const
Determine if OID is empty.
Definition: asn.h:311
ASN.1 Octet string.
Definition: asn.h:38
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.
size_t MinEncodedSize(Signedness sign=UNSIGNED) const
Minimum number of bytes to encode this integer.
void ClampKey(byte x[SECRET_KEYLENGTH]) const
Clamp a private key.
Definition: xed25519.cpp:128
int curve25519_mult(byte publicKey[32], const byte secretKey[32])
Generate a public key.
void BERDecode(BufferedTransformation &bt)
Decode this object from a BufferedTransformation.
Definition: xed25519.cpp:496
void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
Generate private key in this domain.
Definition: xed25519.cpp:351
const byte * data() const
Retrieve pointer to data buffer.
Definition: xed25519.h:323
const byte * begin() const
Pointer to the first byte in the memory block.
Definition: algparam.h:84
size_t Put(byte inByte, bool blocking=true)
Input a byte for processing.
Definition: cryptlib.h:1656
AlgorithmParameters MakeParameters(const char *name, const T &value, bool throwIfNotUsed=true)
Create an object that implements NameValuePairs.
Definition: algparam.h:508
ASN.1 Context specific class.
Definition: asn.h:98
void BERDecode(BufferedTransformation &bt)
Decode this object from a BufferedTransformation.
Definition: xed25519.cpp:753
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
Check this object for errors.
Definition: xed25519.cpp:387
void DEREncode(BufferedTransformation &bt) const
DER encode this OID.
bool IsDefiniteLength() const
Determine length encoding.
Definition: asn.h:404
const char * GroupOID()
OID.
Definition: argnames.h:41
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
Definition: xed25519.cpp:287
static const int PUBLIC_KEYLENGTH
Size of the public key.
Definition: xed25519.h:62
Multiple precision integer with arithmetic operations.
Definition: integer.h:49
const PrivateKey & GetPrivateKey() const
Retrieves a reference to a Private Key.
Definition: xed25519.h:563
Precompiled header file.
void DEREncode(BufferedTransformation &bt) const
Encode this object into a BufferedTransformation.
Definition: xed25519.h:427
int ed25519_sign_open(const byte *message, size_t messageLength, const byte publicKey[32], const byte signature[64])
Verifies a signature on a message.
const NameValuePairs & g_nullNameValuePairs
An empty set of name-value pairs.
Definition: cryptlib.h:529
virtual bool CanIncorporateEntropy() const
Determines if a generator can accept additional entropy.
Definition: cryptlib.h:1438
#define COUNTOF(arr)
Counts elements in an array.
Definition: misc.h:189
virtual void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
const char * Seed()
ConstByteArrayParameter.
Definition: argnames.h:19
Classes for x25519 and ed25519 operations.
void BERDecode(BufferedTransformation &bt)
Decode this object from a BufferedTransformation.
Definition: xed25519.cpp:163
void AssignFrom(const NameValuePairs &source)
Assign values to this object.
Definition: xed25519.cpp:436
void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
Decode privateKey part of privateKeyInfo.
Definition: xed25519.cpp:235
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:68
void BERDecodeError()
Raises a BERDecodeErr.
Definition: asn.h:104
Classes and functions for working with ANS.1 objects.
ed25519 message accumulator
Definition: xed25519.h:278
iterator begin()
Provides an iterator pointing to the first element in the memory block.
Definition: secblock.h:812
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
Check this object for errors.
Definition: xed25519.cpp:264
Implementation of BufferedTransformation&#39;s attachment interface.
void MessageEnd()
Signals the end of messages to the object.
Ed25519 signature algorithm.
Definition: xed25519.h:496
Interface for accumulating messages to be signed or verified.
Definition: cryptlib.h:2843
unsigned char byte
8-bit unsigned datatype
Definition: config_int.h:56
size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const
Sign and restart messageAccumulator.
Definition: xed25519.cpp:673
bool IsClamped(const byte x[SECRET_KEYLENGTH]) const
Determine if private key is clamped.
Definition: xed25519.cpp:133
DER Sequence Encoder.
Definition: asn.h:556
void Encode(byte *output, size_t outputLen, Signedness sign=UNSIGNED) const
Encode in big-endian format.
bool IsSmallOrder(const byte y[PUBLIC_KEYLENGTH]) const
Test if a key has small order.
Definition: xed25519.cpp:138
CRYPTOPP_DLL size_t BERDecodeBitString(BufferedTransformation &bt, SecByteBlock &str, unsigned int &unusedBits)
DER decode bit string.
DER General Encoder.
Definition: asn.h:490
OID GetAlgorithmID() const
Get the Object Identifier.
Definition: xed25519.h:138
Multiple precision integer with arithmetic operations.
void AssignFrom(const NameValuePairs &source)
Assign values to this object.
Definition: xed25519.cpp:723
void BERDecodeAndCheckAlgorithmID(BufferedTransformation &bt)
Determine if OID is valid for this object.
Definition: xed25519.cpp:481
bool IsSmallOrder(const byte y[PUBLIC_KEYLENGTH]) const
Test if a key has small order.
Definition: xed25519.cpp:382
CRYPTOPP_DLL bool VerifyBufsEqual(const byte *buf1, const byte *buf2, size_t count)
Performs a near constant-time comparison of two equally sized buffers.
Interface for public keys.
Definition: cryptlib.h:2518
Crypto++ library namespace.
int ed25519_publickey(byte publicKey[32], const byte secretKey[32])
Creates a public key from a secret key.
bool GetValue(const char *name, T &value) const
Get a named value.
Definition: cryptlib.h:379
bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const
Derive agreed value.
Definition: xed25519.cpp:363
ed25519Signer()
Create a ed25519Signer object.
Definition: xed25519.h:514
void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
Decode privateKey part of privateKeyInfo.
Definition: xed25519.cpp:567
BER General Decoder.
Definition: asn.h:379
const byte * GetPrivateKeyBytePtr() const
Retrieve private key byte array.
Definition: xed25519.h:472
void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params)
Generate a random key or crypto parameters.
Definition: xed25519.cpp:463
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
Definition: xed25519.cpp:701
Ed25519 public key.
Definition: xed25519.h:625
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
void AssignFrom(const NameValuePairs &source)
Assign values to this object.
Definition: xed25519.cpp:316
void DEREncodePrivateKey(BufferedTransformation &bt) const
Encode privateKey part of privateKeyInfo.
Definition: xed25519.cpp:588
Object Identifier.
Definition: asn.h:264
void BERDecodeAndCheckAlgorithmID(BufferedTransformation &bt)
Determine if OID is valid for this object.
Definition: xed25519.cpp:148
const char * PublicElement()
Integer.
Definition: argnames.h:36
void DEREncodePrivateKey(BufferedTransformation &bt) const
Encode privateKey part of privateKeyInfo.
Definition: xed25519.cpp:256
void Load(BufferedTransformation &bt)
BER decode ASN.1 object.
Definition: xed25519.h:194
size_type size() const
Provides the count of elements in the SecBlock.
Definition: secblock.h:837
lword RemainingLength() const
Determine remaining length.
Definition: asn.h:412
const byte * GetPublicKeyBytePtr() const
Retrieve public key byte array.
Definition: xed25519.h:479
virtual void IncorporateEntropy(const byte *input, size_t length)
Update RNG state with additional unpredictable values.
Definition: cryptlib.h:1430
byte * signature()
Retrieve pointer to signature buffer.
Definition: xed25519.h:311
Interface for retrieving values given their names.
Definition: cryptlib.h:321
void BERDecodeAndCheckAlgorithmID(BufferedTransformation &bt)
Determine if OID is valid for this object.
Definition: xed25519.cpp:738