Crypto++  8.8
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 {
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 
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 
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 
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 {
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  // 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 
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 
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
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 
320 {
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 
344 {
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
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 
440 {
442  if (source.GetValue(Name::PrivateExponent(), val) || source.GetValue("SecretKey", val))
443  {
445  std::memcpy(m_sk, val.begin(), SECRET_KEYLENGTH);
446  }
447  if (source.GetValue(Name::PublicElement(), val))
448  {
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 
467 {
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 
478 {
482 }
483 
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 
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 
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 
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 {
603  ("DerivePublicKey", true));
604 }
605 
606 void ed25519PrivateKey::SetPrivateExponent (const Integer &x)
607 {
608  CRYPTOPP_ASSERT(x.MinEncodedSize() <= SECRET_KEYLENGTH);
609 
611  x.Encode(bx, SECRET_KEYLENGTH); std::reverse(bx+0, bx+SECRET_KEYLENGTH);
612 
615  ("DerivePublicKey", true));
616 }
617 
618 const Integer& ed25519PrivateKey::GetPrivateExponent() const
619 {
621  return m_x;
622 }
623 
624 ////////////////////////
625 
626 ed25519Signer::ed25519Signer(const byte y[PUBLIC_KEYLENGTH], const byte x[SECRET_KEYLENGTH])
627 {
631 }
632 
633 ed25519Signer::ed25519Signer(const byte x[SECRET_KEYLENGTH])
634 {
637  ("DerivePublicKey", true));
638 }
639 
641 {
643  CRYPTOPP_ASSERT(x.MinEncodedSize() <= SECRET_KEYLENGTH);
644 
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 
652 }
653 
655 {
656  CRYPTOPP_ASSERT(x.MinEncodedSize() <= SECRET_KEYLENGTH);
657 
659  x.Encode(bx, SECRET_KEYLENGTH); std::reverse(bx+0, bx+SECRET_KEYLENGTH);
660 
663  ("DerivePublicKey", true));
664 }
665 
667 {
668  // Load all fields from the other key
669  ByteQueue queue;
670  key.Save(queue);
671  AccessPrivateKey().Load(queue);
672 }
673 
675 {
677 }
678 
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 
735 {
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 
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 
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 
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 
810 {
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 {
822 
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 {
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 {
846  (Name::PublicElement(), ConstByteArrayParameter(y, PUBLIC_KEYLENGTH)));
847 }
848 
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 
857  (Name::PublicElement(), ConstByteArrayParameter(by, PUBLIC_KEYLENGTH, false)));
858 }
859 
861 {
862  // Load all fields from the other key
863  ByteQueue queue;
864  key.Save(queue);
865  AccessPublicKey().Load(queue);
866 }
867 
869 {
870  AccessPublicKey().Load(params);
871 }
872 
874 {
875  const ed25519PrivateKey& priv = dynamic_cast<const ed25519PrivateKey&>(signer.GetPrivateKey());
877 }
878 
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
AlgorithmParameters MakeParameters(const char *name, const T &value, bool throwIfNotUsed=true)
Create an object that implements NameValuePairs.
Definition: algparam.h:508
Classes and functions for working with ANS.1 objects.
CRYPTOPP_DLL size_t BERDecodeBitString(BufferedTransformation &bt, SecByteBlock &str, unsigned int &unusedBits)
DER decode bit string.
CRYPTOPP_DLL size_t DEREncodeBitString(BufferedTransformation &bt, const byte *str, size_t strLen, unsigned int unusedBits=0)
DER encode bit string.
@ CONSTRUCTED
ASN.1 Constructed flag.
Definition: asn.h:94
@ CONTEXT_SPECIFIC
ASN.1 Context specific class.
Definition: asn.h:98
@ OCTET_STRING
ASN.1 Octet string.
Definition: asn.h:38
@ INTEGER
ASN.1 Integer.
Definition: asn.h:34
void BERDecodeError()
Raises a BERDecodeErr.
Definition: asn.h:104
void Save(BufferedTransformation &bt) const
DER encode ASN.1 object.
Definition: asn.h:691
BER General Decoder.
Definition: asn.h:380
bool EndReached() const
Determine end of stream.
lword RemainingLength() const
Determine remaining length.
Definition: asn.h:412
bool IsDefiniteLength() const
Determine length encoding.
Definition: asn.h:404
void MessageEnd()
Signals the end of messages to the object.
BER Sequence Decoder.
Definition: asn.h:525
Interface for buffered transformations.
Definition: cryptlib.h:1657
virtual size_t Get(byte &outByte)
Retrieve a 8-bit byte.
size_t Put(byte inByte, bool blocking=true)
Input a byte for processing.
Definition: cryptlib.h:1678
Data structure used to store byte strings.
Definition: queue.h:23
Used to pass byte array input as part of a NameValuePairs object.
Definition: algparam.h:25
size_t size() const
Length of the memory block.
Definition: algparam.h:88
const byte * begin() const
Pointer to the first byte in the memory block.
Definition: algparam.h:84
virtual void AssignFrom(const NameValuePairs &source)=0
Assign values to this object.
virtual void Load(BufferedTransformation &bt)
Loads a key from a BufferedTransformation.
Definition: cryptlib.h:2461
DER General Encoder.
Definition: asn.h:491
void MessageEnd()
Signals the end of messages to the object.
DER Sequence Encoder.
Definition: asn.h:557
virtual void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params=g_nullNameValuePairs)
Generate a random key or crypto parameters.
Definition: cryptlib.h:2525
Multiple precision integer with arithmetic operations.
Definition: integer.h:50
size_t MinEncodedSize(Signedness sign=UNSIGNED) const
Minimum number of bytes to encode this integer.
@ UNSIGNED
an unsigned value
Definition: integer.h:85
void Encode(byte *output, size_t outputLen, Signedness sign=UNSIGNED) const
Encode in big-endian format.
Interface for retrieving values given their names.
Definition: cryptlib.h:327
bool GetValue(const char *name, T &value) const
Get a named value.
Definition: cryptlib.h:384
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
Object Identifier.
Definition: asn.h:265
void DEREncode(BufferedTransformation &bt) const
DER encode this OID.
bool Empty() const
Determine if OID is empty.
Definition: asn.h:311
Interface for accumulating messages to be signed or verified.
Definition: cryptlib.h:2866
Encodes and Decodes privateKeyInfo.
Definition: asn.h:748
Interface for public keys.
Definition: cryptlib.h:2541
Interface for random number generators.
Definition: cryptlib.h:1440
virtual void IncorporateEntropy(const byte *input, size_t length)
Update RNG state with additional unpredictable values.
Definition: cryptlib.h:1452
virtual bool CanIncorporateEntropy() const
Determines if a generator can accept additional entropy.
Definition: cryptlib.h:1460
virtual void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
iterator begin()
Provides an iterator pointing to the first element in the memory block.
Definition: secblock.h:836
size_type size() const
Provides the count of elements in the SecBlock.
Definition: secblock.h:867
SecBlock<byte> typedef.
Definition: secblock.h:1226
Encodes and decodes subjectPublicKeyInfo.
Definition: asn.h:702
x25519 with key validation
Definition: xed25519.h:55
bool IsClamped(const byte x[SECRET_KEYLENGTH]) const
Determine if private key is clamped.
Definition: xed25519.cpp:133
void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
Decode privateKey part of privateKeyInfo.
Definition: xed25519.cpp:238
bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const
Derive agreed value.
Definition: xed25519.cpp:366
static const int PUBLIC_KEYLENGTH
Size of the public key.
Definition: xed25519.h:62
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
Definition: xed25519.cpp:290
void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
Generate private key in this domain.
Definition: xed25519.cpp:354
bool IsSmallOrder(const byte y[PUBLIC_KEYLENGTH]) const
Test if a key has small order.
Definition: xed25519.cpp:138
void ClampKey(byte x[SECRET_KEYLENGTH]) const
Clamp a private key.
Definition: xed25519.cpp:128
void BERDecodeAndCheckAlgorithmID(BufferedTransformation &bt)
Determine if OID is valid for this object.
Definition: xed25519.cpp:148
void DEREncodePrivateKey(BufferedTransformation &bt) const
Encode privateKey part of privateKeyInfo.
Definition: xed25519.cpp:259
void DEREncode(BufferedTransformation &bt) const
Encode this object into a BufferedTransformation.
Definition: xed25519.h:200
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
Check this object for errors.
Definition: xed25519.cpp:267
void Load(BufferedTransformation &bt)
BER decode ASN.1 object.
Definition: xed25519.h:194
void BERDecode(BufferedTransformation &bt)
Decode this object from a BufferedTransformation.
Definition: xed25519.cpp:166
x25519()
Create a x25519 object.
Definition: xed25519.h:74
static const int SECRET_KEYLENGTH
Size of the private key.
Definition: xed25519.h:59
void AssignFrom(const NameValuePairs &source)
Assign values to this object.
Definition: xed25519.cpp:319
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
OID GetAlgorithmID() const
Get the Object Identifier.
Definition: xed25519.h:138
void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params)
Generate a random key or crypto parameters.
Definition: xed25519.cpp:343
unsigned char byte
8-bit unsigned datatype
Definition: config_int.h:66
unsigned int word32
32-bit unsigned datatype
Definition: config_int.h:72
Abstract base classes that provide a uniform interface to this library.
const NameValuePairs & g_nullNameValuePairs
An empty set of name-value pairs.
Definition: cryptlib.h:534
@ LITTLE_ENDIAN_ORDER
byte order is little-endian
Definition: cryptlib.h:150
int ed25519_sign_open(const byte *message, size_t messageLength, const byte publicKey[32], const byte signature[64])
Verifies a signature on a message.
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.
int ed25519_publickey(byte publicKey[32], const byte secretKey[32])
Creates a public key from a secret key.
int curve25519_mult(byte publicKey[32], const byte secretKey[32])
Generate a public key.
Implementation of BufferedTransformation's attachment interface.
Multiple precision integer with arithmetic operations.
#define COUNTOF(arr)
Counts elements in an array.
Definition: misc.h:193
CRYPTOPP_DLL bool VerifyBufsEqual(const byte *buf1, const byte *buf2, size_t count)
Performs a near constant-time comparison of two equally sized buffers.
Crypto++ library namespace.
const char * PrivateExponent()
Integer.
Definition: argnames.h:35
const char * PublicElement()
Integer.
Definition: argnames.h:36
const char * GroupOID()
OID.
Definition: argnames.h:41
const char * Seed()
ConstByteArrayParameter.
Definition: argnames.h:19
Precompiled header file.
Common C++ header files.
ed25519 message accumulator
Definition: xed25519.h:279
void Restart()
Reset the accumulator.
Definition: xed25519.h:304
size_t size() const
Retrieve size of data buffer.
Definition: xed25519.h:329
byte * signature()
Retrieve pointer to signature buffer.
Definition: xed25519.h:311
const byte * data() const
Retrieve pointer to data buffer.
Definition: xed25519.h:323
Ed25519 private key.
Definition: xed25519.h:356
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
Definition: xed25519.cpp:410
void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params)
Generate a random key or crypto parameters.
Definition: xed25519.cpp:466
void MakePublicKey(PublicKey &pub) const
Initializes a public key from this key.
Definition: xed25519.cpp:477
OID GetAlgorithmID() const
Retrieves the OID of the algorithm.
Definition: xed25519.h:377
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
Check this object for errors.
Definition: xed25519.cpp:390
void DEREncode(BufferedTransformation &bt) const
Encode this object into a BufferedTransformation.
Definition: xed25519.h:429
void DEREncodePrivateKey(BufferedTransformation &bt) const
Encode privateKey part of privateKeyInfo.
Definition: xed25519.cpp:591
void AssignFrom(const NameValuePairs &source)
Assign values to this object.
Definition: xed25519.cpp:439
void BERDecodeAndCheckAlgorithmID(BufferedTransformation &bt)
Determine if OID is valid for this object.
Definition: xed25519.cpp:484
void BERDecode(BufferedTransformation &bt)
Decode this object from a BufferedTransformation.
Definition: xed25519.cpp:499
bool IsSmallOrder(const byte y[PUBLIC_KEYLENGTH]) const
Test if a key has small order.
Definition: xed25519.cpp:385
void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
Decode privateKey part of privateKeyInfo.
Definition: xed25519.cpp:570
const byte * GetPrivateKeyBytePtr() const
Retrieve private key byte array.
Definition: xed25519.h:474
const byte * GetPublicKeyBytePtr() const
Retrieve public key byte array.
Definition: xed25519.h:481
static const int SECRET_KEYLENGTH
Size of the private key.
Definition: xed25519.h:359
static const int PUBLIC_KEYLENGTH
Size of the public key.
Definition: xed25519.h:362
Ed25519 public key.
Definition: xed25519.h:635
void BERDecode(BufferedTransformation &bt)
Decode this object from a BufferedTransformation.
Definition: xed25519.cpp:764
static const int PUBLIC_KEYLENGTH
Size of the public key.
Definition: xed25519.h:638
void BERDecodeAndCheckAlgorithmID(BufferedTransformation &bt)
Determine if OID is valid for this object.
Definition: xed25519.cpp:749
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
Definition: xed25519.cpp:712
void DEREncodePublicKey(BufferedTransformation &bt) const
Encode subjectPublicKey part of subjectPublicKeyInfo.
Definition: xed25519.cpp:809
void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
Decode subjectPublicKey part of subjectPublicKeyInfo.
Definition: xed25519.cpp:791
OID GetAlgorithmID() const
Retrieves the OID of the algorithm.
Definition: xed25519.h:643
void DEREncode(BufferedTransformation &bt) const
Encode this object into a BufferedTransformation.
Definition: xed25519.cpp:778
const byte * GetPublicKeyBytePtr() const
Retrieve public key byte array.
Definition: xed25519.h:700
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
Check this object for errors.
Definition: xed25519.cpp:835
void AssignFrom(const NameValuePairs &source)
Assign values to this object.
Definition: xed25519.cpp:734
Ed25519 signature algorithm.
Definition: xed25519.h:499
ed25519Signer()
Create an ed25519Signer object.
Definition: xed25519.h:516
const PrivateKey & GetPrivateKey() const
Retrieves a reference to a Private Key.
Definition: xed25519.h:572
size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const
Sign and restart messageAccumulator.
Definition: xed25519.cpp:684
static const int PUBLIC_KEYLENGTH
Size of the public key.
Definition: xed25519.h:505
static const int SECRET_KEYLENGTH
Size of the private key.
Definition: xed25519.h:502
static const int SIGNATURE_LENGTH
Size of the signature.
Definition: xed25519.h:510
size_t SignStream(RandomNumberGenerator &rng, std::istream &stream, byte *signature) const
Sign a stream.
Definition: xed25519.cpp:699
PrivateKey & AccessPrivateKey()
Retrieves a reference to a Private Key.
Definition: xed25519.h:567
bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const
Check whether messageAccumulator contains a valid signature and message, and restart messageAccumulat...
Definition: xed25519.cpp:879
ed25519Verifier()
Create an ed25519Verifier object.
Definition: xed25519.h:721
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
const PublicKey & GetPublicKey() const
Retrieves a reference to a Public Key.
Definition: xed25519.h:765
PublicKey & AccessPublicKey()
Retrieves a reference to a Public Key.
Definition: xed25519.h:760
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:68
Classes for x25519 and ed25519 operations.