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