Crypto++
validat2.cpp
1 // validat2.cpp - written and placed in the public domain by Wei Dai
2 
3 #include "pch.h"
4 
5 #define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
6 #include "blumshub.h"
7 #include "rsa.h"
8 #include "md2.h"
9 #include "elgamal.h"
10 #include "nr.h"
11 #include "dsa.h"
12 #include "dh.h"
13 #include "mqv.h"
14 #include "luc.h"
15 #include "xtrcrypt.h"
16 #include "rabin.h"
17 #include "rw.h"
18 #include "eccrypto.h"
19 #include "ecp.h"
20 #include "ec2n.h"
21 #include "asn.h"
22 #include "rng.h"
23 #include "files.h"
24 #include "hex.h"
25 #include "oids.h"
26 #include "esign.h"
27 #include "osrng.h"
28 
29 #include <iostream>
30 #include <iomanip>
31 
32 #include "validate.h"
33 
34 USING_NAMESPACE(CryptoPP)
35 USING_NAMESPACE(std)
36 
38 {
39 public:
40  FixedRNG(BufferedTransformation &source) : m_source(source) {}
41 
42  void GenerateBlock(byte *output, size_t size)
43  {
44  m_source.Get(output, size);
45  }
46 
47 private:
48  BufferedTransformation &m_source;
49 };
50 
51 bool ValidateBBS()
52 {
53  cout << "\nBlumBlumShub validation suite running...\n\n";
54 
55  Integer p("212004934506826557583707108431463840565872545889679278744389317666981496005411448865750399674653351");
56  Integer q("100677295735404212434355574418077394581488455772477016953458064183204108039226017738610663984508231");
57  Integer seed("63239752671357255800299643604761065219897634268887145610573595874544114193025997412441121667211431");
58  BlumBlumShub bbs(p, q, seed);
59  bool pass = true, fail;
60  int j;
61 
62  const byte output1[] = {
63  0x49,0xEA,0x2C,0xFD,0xB0,0x10,0x64,0xA0,0xBB,0xB9,
64  0x2A,0xF1,0x01,0xDA,0xC1,0x8A,0x94,0xF7,0xB7,0xCE};
65  const byte output2[] = {
66  0x74,0x45,0x48,0xAE,0xAC,0xB7,0x0E,0xDF,0xAF,0xD7,
67  0xD5,0x0E,0x8E,0x29,0x83,0x75,0x6B,0x27,0x46,0xA1};
68 
69  byte buf[20];
70 
71  bbs.GenerateBlock(buf, 20);
72  fail = memcmp(output1, buf, 20) != 0;
73  pass = pass && !fail;
74 
75  cout << (fail ? "FAILED " : "passed ");
76  for (j=0;j<20;j++)
77  cout << setw(2) << setfill('0') << hex << (int)buf[j];
78  cout << endl;
79 
80  bbs.Seek(10);
81  bbs.GenerateBlock(buf, 10);
82  fail = memcmp(output1+10, buf, 10) != 0;
83  pass = pass && !fail;
84 
85  cout << (fail ? "FAILED " : "passed ");
86  for (j=0;j<10;j++)
87  cout << setw(2) << setfill('0') << hex << (int)buf[j];
88  cout << endl;
89 
90  bbs.Seek(1234567);
91  bbs.GenerateBlock(buf, 20);
92  fail = memcmp(output2, buf, 20) != 0;
93  pass = pass && !fail;
94 
95  cout << (fail ? "FAILED " : "passed ");
96  for (j=0;j<20;j++)
97  cout << setw(2) << setfill('0') << hex << (int)buf[j];
98  cout << endl;
99 
100  return pass;
101 }
102 
103 bool SignatureValidate(PK_Signer &priv, PK_Verifier &pub, bool thorough = false)
104 {
105  bool pass = true, fail;
106 
107  fail = !pub.GetMaterial().Validate(GlobalRNG(), thorough ? 3 : 2) || !priv.GetMaterial().Validate(GlobalRNG(), thorough ? 3 : 2);
108  pass = pass && !fail;
109 
110  cout << (fail ? "FAILED " : "passed ");
111  cout << "signature key validation\n";
112 
113  const byte *message = (byte *)"test message";
114  const int messageLen = 12;
115 
116  SecByteBlock signature(priv.MaxSignatureLength());
117  size_t signatureLength = priv.SignMessage(GlobalRNG(), message, messageLen, signature);
118  fail = !pub.VerifyMessage(message, messageLen, signature, signatureLength);
119  pass = pass && !fail;
120 
121  cout << (fail ? "FAILED " : "passed ");
122  cout << "signature and verification\n";
123 
124  ++signature[0];
125  fail = pub.VerifyMessage(message, messageLen, signature, signatureLength);
126  pass = pass && !fail;
127 
128  cout << (fail ? "FAILED " : "passed ");
129  cout << "checking invalid signature" << endl;
130 
131  if (priv.MaxRecoverableLength() > 0)
132  {
133  signatureLength = priv.SignMessageWithRecovery(GlobalRNG(), message, messageLen, NULL, 0, signature);
134  SecByteBlock recovered(priv.MaxRecoverableLengthFromSignatureLength(signatureLength));
135  DecodingResult result = pub.RecoverMessage(recovered, NULL, 0, signature, signatureLength);
136  fail = !(result.isValidCoding && result.messageLength == messageLen && memcmp(recovered, message, messageLen) == 0);
137  pass = pass && !fail;
138 
139  cout << (fail ? "FAILED " : "passed ");
140  cout << "signature and verification with recovery" << endl;
141 
142  ++signature[0];
143  result = pub.RecoverMessage(recovered, NULL, 0, signature, signatureLength);
144  fail = result.isValidCoding;
145  pass = pass && !fail;
146 
147  cout << (fail ? "FAILED " : "passed ");
148  cout << "recovery with invalid signature" << endl;
149  }
150 
151  return pass;
152 }
153 
154 bool CryptoSystemValidate(PK_Decryptor &priv, PK_Encryptor &pub, bool thorough = false)
155 {
156  bool pass = true, fail;
157 
158  fail = !pub.GetMaterial().Validate(GlobalRNG(), thorough ? 3 : 2) || !priv.GetMaterial().Validate(GlobalRNG(), thorough ? 3 : 2);
159  pass = pass && !fail;
160 
161  cout << (fail ? "FAILED " : "passed ");
162  cout << "cryptosystem key validation\n";
163 
164  const byte *message = (byte *)"test message";
165  const int messageLen = 12;
166  SecByteBlock ciphertext(priv.CiphertextLength(messageLen));
167  SecByteBlock plaintext(priv.MaxPlaintextLength(ciphertext.size()));
168 
169  pub.Encrypt(GlobalRNG(), message, messageLen, ciphertext);
170  fail = priv.Decrypt(GlobalRNG(), ciphertext, priv.CiphertextLength(messageLen), plaintext) != DecodingResult(messageLen);
171  fail = fail || memcmp(message, plaintext, messageLen);
172  pass = pass && !fail;
173 
174  cout << (fail ? "FAILED " : "passed ");
175  cout << "encryption and decryption\n";
176 
177  return pass;
178 }
179 
180 bool SimpleKeyAgreementValidate(SimpleKeyAgreementDomain &d)
181 {
182  if (d.GetCryptoParameters().Validate(GlobalRNG(), 3))
183  cout << "passed simple key agreement domain parameters validation" << endl;
184  else
185  {
186  cout << "FAILED simple key agreement domain parameters invalid" << endl;
187  return false;
188  }
189 
190  SecByteBlock priv1(d.PrivateKeyLength()), priv2(d.PrivateKeyLength());
191  SecByteBlock pub1(d.PublicKeyLength()), pub2(d.PublicKeyLength());
192  SecByteBlock val1(d.AgreedValueLength()), val2(d.AgreedValueLength());
193 
194  d.GenerateKeyPair(GlobalRNG(), priv1, pub1);
195  d.GenerateKeyPair(GlobalRNG(), priv2, pub2);
196 
197  memset(val1.begin(), 0x10, val1.size());
198  memset(val2.begin(), 0x11, val2.size());
199 
200  if (!(d.Agree(val1, priv1, pub2) && d.Agree(val2, priv2, pub1)))
201  {
202  cout << "FAILED simple key agreement failed" << endl;
203  return false;
204  }
205 
206  if (memcmp(val1.begin(), val2.begin(), d.AgreedValueLength()))
207  {
208  cout << "FAILED simple agreed values not equal" << endl;
209  return false;
210  }
211 
212  cout << "passed simple key agreement" << endl;
213  return true;
214 }
215 
216 bool AuthenticatedKeyAgreementValidate(AuthenticatedKeyAgreementDomain &d)
217 {
218  if (d.GetCryptoParameters().Validate(GlobalRNG(), 3))
219  cout << "passed authenticated key agreement domain parameters validation" << endl;
220  else
221  {
222  cout << "FAILED authenticated key agreement domain parameters invalid" << endl;
223  return false;
224  }
225 
230  SecByteBlock val1(d.AgreedValueLength()), val2(d.AgreedValueLength());
231 
232  d.GenerateStaticKeyPair(GlobalRNG(), spriv1, spub1);
233  d.GenerateStaticKeyPair(GlobalRNG(), spriv2, spub2);
234  d.GenerateEphemeralKeyPair(GlobalRNG(), epriv1, epub1);
235  d.GenerateEphemeralKeyPair(GlobalRNG(), epriv2, epub2);
236 
237  memset(val1.begin(), 0x10, val1.size());
238  memset(val2.begin(), 0x11, val2.size());
239 
240  if (!(d.Agree(val1, spriv1, epriv1, spub2, epub2) && d.Agree(val2, spriv2, epriv2, spub1, epub1)))
241  {
242  cout << "FAILED authenticated key agreement failed" << endl;
243  return false;
244  }
245 
246  if (memcmp(val1.begin(), val2.begin(), d.AgreedValueLength()))
247  {
248  cout << "FAILED authenticated agreed values not equal" << endl;
249  return false;
250  }
251 
252  cout << "passed authenticated key agreement" << endl;
253  return true;
254 }
255 
256 bool ValidateRSA()
257 {
258  cout << "\nRSA validation suite running...\n\n";
259 
260  byte out[100], outPlain[100];
261  bool pass = true, fail;
262 
263  {
264  const char *plain = "Everyone gets Friday off.";
265  byte *signature = (byte *)
266  "\x05\xfa\x6a\x81\x2f\xc7\xdf\x8b\xf4\xf2\x54\x25\x09\xe0\x3e\x84"
267  "\x6e\x11\xb9\xc6\x20\xbe\x20\x09\xef\xb4\x40\xef\xbc\xc6\x69\x21"
268  "\x69\x94\xac\x04\xf3\x41\xb5\x7d\x05\x20\x2d\x42\x8f\xb2\xa2\x7b"
269  "\x5c\x77\xdf\xd9\xb1\x5b\xfc\x3d\x55\x93\x53\x50\x34\x10\xc1\xe1";
270 
271  FileSource keys(PACKAGE_DATA_DIR "TestData/rsa512a.dat", true, new HexDecoder);
272  Weak::RSASSA_PKCS1v15_MD2_Signer rsaPriv(keys);
273  Weak::RSASSA_PKCS1v15_MD2_Verifier rsaPub(rsaPriv);
274 
275  size_t signatureLength = rsaPriv.SignMessage(GlobalRNG(), (byte *)plain, strlen(plain), out);
276  fail = memcmp(signature, out, 64) != 0;
277  pass = pass && !fail;
278 
279  cout << (fail ? "FAILED " : "passed ");
280  cout << "signature check against test vector\n";
281 
282  fail = !rsaPub.VerifyMessage((byte *)plain, strlen(plain), out, signatureLength);
283  pass = pass && !fail;
284 
285  cout << (fail ? "FAILED " : "passed ");
286  cout << "verification check against test vector\n";
287 
288  out[10]++;
289  fail = rsaPub.VerifyMessage((byte *)plain, strlen(plain), out, signatureLength);
290  pass = pass && !fail;
291 
292  cout << (fail ? "FAILED " : "passed ");
293  cout << "invalid signature verification\n";
294  }
295  {
296  FileSource keys(PACKAGE_DATA_DIR "TestData/rsa1024.dat", true, new HexDecoder);
297  RSAES_PKCS1v15_Decryptor rsaPriv(keys);
298  RSAES_PKCS1v15_Encryptor rsaPub(rsaPriv);
299 
300  pass = CryptoSystemValidate(rsaPriv, rsaPub) && pass;
301  }
302  {
303  RSAES<OAEP<SHA> >::Decryptor rsaPriv(GlobalRNG(), 512);
304  RSAES<OAEP<SHA> >::Encryptor rsaPub(rsaPriv);
305 
306  pass = CryptoSystemValidate(rsaPriv, rsaPub) && pass;
307  }
308  {
309  byte *plain = (byte *)
310  "\x54\x85\x9b\x34\x2c\x49\xea\x2a";
311  byte *encrypted = (byte *)
312  "\x14\xbd\xdd\x28\xc9\x83\x35\x19\x23\x80\xe8\xe5\x49\xb1\x58\x2a"
313  "\x8b\x40\xb4\x48\x6d\x03\xa6\xa5\x31\x1f\x1f\xd5\xf0\xa1\x80\xe4"
314  "\x17\x53\x03\x29\xa9\x34\x90\x74\xb1\x52\x13\x54\x29\x08\x24\x52"
315  "\x62\x51";
316  byte *oaepSeed = (byte *)
317  "\xaa\xfd\x12\xf6\x59\xca\xe6\x34\x89\xb4\x79\xe5\x07\x6d\xde\xc2"
318  "\xf0\x6c\xb5\x8f";
319  ByteQueue bq;
320  bq.Put(oaepSeed, 20);
321  FixedRNG rng(bq);
322 
323  FileSource privFile(PACKAGE_DATA_DIR "TestData/rsa400pv.dat", true, new HexDecoder);
324  FileSource pubFile(PACKAGE_DATA_DIR "TestData/rsa400pb.dat", true, new HexDecoder);
325  RSAES_OAEP_SHA_Decryptor rsaPriv;
326  rsaPriv.AccessKey().BERDecodePrivateKey(privFile, false, 0);
327  RSAES_OAEP_SHA_Encryptor rsaPub(pubFile);
328 
329  memset(out, 0, 50);
330  memset(outPlain, 0, 8);
331  rsaPub.Encrypt(rng, plain, 8, out);
332  DecodingResult result = rsaPriv.FixedLengthDecrypt(GlobalRNG(), encrypted, outPlain);
333  fail = !result.isValidCoding || (result.messageLength!=8) || memcmp(out, encrypted, 50) || memcmp(plain, outPlain, 8);
334  pass = pass && !fail;
335 
336  cout << (fail ? "FAILED " : "passed ");
337  cout << "PKCS 2.0 encryption and decryption\n";
338  }
339 
340  return pass;
341 }
342 
343 bool ValidateDH()
344 {
345  cout << "\nDH validation suite running...\n\n";
346 
347  FileSource f(PACKAGE_DATA_DIR "TestData/dh1024.dat", true, new HexDecoder());
348  DH dh(f);
349  return SimpleKeyAgreementValidate(dh);
350 }
351 
352 bool ValidateMQV()
353 {
354  cout << "\nMQV validation suite running...\n\n";
355 
356  FileSource f(PACKAGE_DATA_DIR "TestData/mqv1024.dat", true, new HexDecoder());
357  MQV mqv(f);
358  return AuthenticatedKeyAgreementValidate(mqv);
359 }
360 
361 bool ValidateLUC_DH()
362 {
363  cout << "\nLUC-DH validation suite running...\n\n";
364 
365  FileSource f(PACKAGE_DATA_DIR "TestData/lucd512.dat", true, new HexDecoder());
366  LUC_DH dh(f);
367  return SimpleKeyAgreementValidate(dh);
368 }
369 
370 bool ValidateXTR_DH()
371 {
372  cout << "\nXTR-DH validation suite running...\n\n";
373 
374  FileSource f(PACKAGE_DATA_DIR "TestData/xtrdh171.dat", true, new HexDecoder());
375  XTR_DH dh(f);
376  return SimpleKeyAgreementValidate(dh);
377 }
378 
379 bool ValidateElGamal()
380 {
381  cout << "\nElGamal validation suite running...\n\n";
382  bool pass = true;
383  {
384  FileSource fc(PACKAGE_DATA_DIR "TestData/elgc1024.dat", true, new HexDecoder);
385  ElGamalDecryptor privC(fc);
386  ElGamalEncryptor pubC(privC);
387  privC.AccessKey().Precompute();
388  ByteQueue queue;
389  privC.AccessKey().SavePrecomputation(queue);
390  privC.AccessKey().LoadPrecomputation(queue);
391 
392  pass = CryptoSystemValidate(privC, pubC) && pass;
393  }
394  return pass;
395 }
396 
397 bool ValidateDLIES()
398 {
399  cout << "\nDLIES validation suite running...\n\n";
400  bool pass = true;
401  {
402  FileSource fc(PACKAGE_DATA_DIR "TestData/dlie1024.dat", true, new HexDecoder);
403  DLIES<>::Decryptor privC(fc);
404  DLIES<>::Encryptor pubC(privC);
405  pass = CryptoSystemValidate(privC, pubC) && pass;
406  }
407  {
408  cout << "Generating new encryption key..." << endl;
410  gp.GenerateRandomWithKeySize(GlobalRNG(), 128);
411  DLIES<>::Decryptor decryptor;
412  decryptor.AccessKey().GenerateRandom(GlobalRNG(), gp);
413  DLIES<>::Encryptor encryptor(decryptor);
414 
415  pass = CryptoSystemValidate(decryptor, encryptor) && pass;
416  }
417  return pass;
418 }
419 
420 bool ValidateNR()
421 {
422  cout << "\nNR validation suite running...\n\n";
423  bool pass = true;
424  {
425  FileSource f(PACKAGE_DATA_DIR "TestData/nr2048.dat", true, new HexDecoder);
426  NR<SHA>::Signer privS(f);
427  privS.AccessKey().Precompute();
428  NR<SHA>::Verifier pubS(privS);
429 
430  pass = SignatureValidate(privS, pubS) && pass;
431  }
432  {
433  cout << "Generating new signature key..." << endl;
434  NR<SHA>::Signer privS(GlobalRNG(), 256);
435  NR<SHA>::Verifier pubS(privS);
436 
437  pass = SignatureValidate(privS, pubS) && pass;
438  }
439  return pass;
440 }
441 
442 bool ValidateDSA(bool thorough)
443 {
444  cout << "\nDSA validation suite running...\n\n";
445 
446  bool pass = true, fail;
447  {
448  FileSource fs(PACKAGE_DATA_DIR "TestData/dsa512.dat", true, new HexDecoder());
449  GDSA<SHA>::Signer priv(fs);
450  priv.AccessKey().Precompute(16);
451  GDSA<SHA>::Verifier pub(priv);
452 
453  byte seed[]={0xd5, 0x01, 0x4e, 0x4b, 0x60, 0xef, 0x2b, 0xa8, 0xb6, 0x21,
454  0x1b, 0x40, 0x62, 0xba, 0x32, 0x24, 0xe0, 0x42, 0x7d, 0xd3};
455  Integer k("358dad57 1462710f 50e254cf 1a376b2b deaadfbfh");
456  Integer h("a9993e36 4706816a ba3e2571 7850c26c 9cd0d89dh");
457  byte sig[]={0x8b, 0xac, 0x1a, 0xb6, 0x64, 0x10, 0x43, 0x5c, 0xb7, 0x18,
458  0x1f, 0x95, 0xb1, 0x6a, 0xb9, 0x7c, 0x92, 0xb3, 0x41, 0xc0,
459  0x41, 0xe2, 0x34, 0x5f, 0x1f, 0x56, 0xdf, 0x24, 0x58, 0xf4,
460  0x26, 0xd1, 0x55, 0xb4, 0xba, 0x2d, 0xb6, 0xdc, 0xd8, 0xc8};
461  Integer r(sig, 20);
462  Integer s(sig+20, 20);
463 
464  Integer pGen, qGen, rOut, sOut;
465  int c;
466 
467  fail = !DSA::GeneratePrimes(seed, 160, c, pGen, 512, qGen);
468  fail = fail || (pGen != pub.GetKey().GetGroupParameters().GetModulus()) || (qGen != pub.GetKey().GetGroupParameters().GetSubgroupOrder());
469  pass = pass && !fail;
470 
471  cout << (fail ? "FAILED " : "passed ");
472  cout << "prime generation test\n";
473 
474  priv.RawSign(k, h, rOut, sOut);
475  fail = (rOut != r) || (sOut != s);
476  pass = pass && !fail;
477 
478  cout << (fail ? "FAILED " : "passed ");
479  cout << "signature check against test vector\n";
480 
481  fail = !pub.VerifyMessage((byte *)"abc", 3, sig, sizeof(sig));
482  pass = pass && !fail;
483 
484  cout << (fail ? "FAILED " : "passed ");
485  cout << "verification check against test vector\n";
486 
487  fail = pub.VerifyMessage((byte *)"xyz", 3, sig, sizeof(sig));
488  pass = pass && !fail;
489  }
490  FileSource fs1(PACKAGE_DATA_DIR "TestData/dsa1024.dat", true, new HexDecoder());
491  DSA::Signer priv(fs1);
492  DSA::Verifier pub(priv);
493  FileSource fs2(PACKAGE_DATA_DIR "TestData/dsa1024b.dat", true, new HexDecoder());
494  DSA::Verifier pub1(fs2);
495  assert(pub.GetKey() == pub1.GetKey());
496  pass = SignatureValidate(priv, pub, thorough) && pass;
497  return pass;
498 }
499 
500 bool ValidateLUC()
501 {
502  cout << "\nLUC validation suite running...\n\n";
503  bool pass=true;
504 
505  {
506  FileSource f(PACKAGE_DATA_DIR "TestData/luc1024.dat", true, new HexDecoder);
509  pass = SignatureValidate(priv, pub) && pass;
510  }
511  {
512  LUCES_OAEP_SHA_Decryptor priv(GlobalRNG(), 512);
513  LUCES_OAEP_SHA_Encryptor pub(priv);
514  pass = CryptoSystemValidate(priv, pub) && pass;
515  }
516  return pass;
517 }
518 
519 bool ValidateLUC_DL()
520 {
521  cout << "\nLUC-HMP validation suite running...\n\n";
522 
523  FileSource f(PACKAGE_DATA_DIR "TestData/lucs512.dat", true, new HexDecoder);
524  LUC_HMP<SHA>::Signer privS(f);
525  LUC_HMP<SHA>::Verifier pubS(privS);
526  bool pass = SignatureValidate(privS, pubS);
527 
528  cout << "\nLUC-IES validation suite running...\n\n";
529 
530  FileSource fc(PACKAGE_DATA_DIR "TestData/lucc512.dat", true, new HexDecoder);
531  LUC_IES<>::Decryptor privC(fc);
532  LUC_IES<>::Encryptor pubC(privC);
533  pass = CryptoSystemValidate(privC, pubC) && pass;
534 
535  return pass;
536 }
537 
538 bool ValidateRabin()
539 {
540  cout << "\nRabin validation suite running...\n\n";
541  bool pass=true;
542 
543  {
544  FileSource f(PACKAGE_DATA_DIR "TestData/rabi1024.dat", true, new HexDecoder);
547  pass = SignatureValidate(priv, pub) && pass;
548  }
549  {
550  RabinES<OAEP<SHA> >::Decryptor priv(GlobalRNG(), 512);
551  RabinES<OAEP<SHA> >::Encryptor pub(priv);
552  pass = CryptoSystemValidate(priv, pub) && pass;
553  }
554  return pass;
555 }
556 
557 bool ValidateRW()
558 {
559  cout << "\nRW validation suite running...\n\n";
560 
561  FileSource f(PACKAGE_DATA_DIR "TestData/rw1024.dat", true, new HexDecoder);
562  RWSS<PSSR, SHA>::Signer priv(f);
563  RWSS<PSSR, SHA>::Verifier pub(priv);
564 
565  return SignatureValidate(priv, pub);
566 }
567 
568 /*
569 bool ValidateBlumGoldwasser()
570 {
571  cout << "\nBlumGoldwasser validation suite running...\n\n";
572 
573  FileSource f(PACKAGE_DATA_DIR "TestData/blum512.dat", true, new HexDecoder);
574  BlumGoldwasserPrivateKey priv(f);
575  BlumGoldwasserPublicKey pub(priv);
576 
577  return CryptoSystemValidate(priv, pub);
578 }
579 */
580 
581 bool ValidateECP()
582 {
583  cout << "\nECP validation suite running...\n\n";
584 
585  ECIES<ECP>::Decryptor cpriv(GlobalRNG(), ASN1::secp192r1());
586  ECIES<ECP>::Encryptor cpub(cpriv);
587  ByteQueue bq;
588  cpriv.GetKey().DEREncode(bq);
589  cpub.AccessKey().AccessGroupParameters().SetEncodeAsOID(true);
590  cpub.GetKey().DEREncode(bq);
591  ECDSA<ECP, SHA>::Signer spriv(bq);
592  ECDSA<ECP, SHA>::Verifier spub(bq);
593  ECDH<ECP>::Domain ecdhc(ASN1::secp192r1());
594  ECMQV<ECP>::Domain ecmqvc(ASN1::secp192r1());
595 
596  spriv.AccessKey().Precompute();
597  ByteQueue queue;
598  spriv.AccessKey().SavePrecomputation(queue);
599  spriv.AccessKey().LoadPrecomputation(queue);
600 
601  bool pass = SignatureValidate(spriv, spub);
602  cpub.AccessKey().Precompute();
603  cpriv.AccessKey().Precompute();
604  pass = CryptoSystemValidate(cpriv, cpub) && pass;
605  pass = SimpleKeyAgreementValidate(ecdhc) && pass;
606  pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass;
607 
608  cout << "Turning on point compression..." << endl;
609  cpriv.AccessKey().AccessGroupParameters().SetPointCompression(true);
610  cpub.AccessKey().AccessGroupParameters().SetPointCompression(true);
611  ecdhc.AccessGroupParameters().SetPointCompression(true);
612  ecmqvc.AccessGroupParameters().SetPointCompression(true);
613  pass = CryptoSystemValidate(cpriv, cpub) && pass;
614  pass = SimpleKeyAgreementValidate(ecdhc) && pass;
615  pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass;
616 
617  cout << "Testing SEC 2, NIST, and Brainpool recommended curves..." << endl;
618  OID oid;
619  while (!(oid = DL_GroupParameters_EC<ECP>::GetNextRecommendedParametersOID(oid)).m_values.empty())
620  {
621  DL_GroupParameters_EC<ECP> params(oid);
622  bool fail = !params.Validate(GlobalRNG(), 2);
623  cout << (fail ? "FAILED" : "passed") << " " << dec << params.GetCurve().GetField().MaxElementBitLength() << " bits" << endl;
624  pass = pass && !fail;
625  }
626 
627  return pass;
628 }
629 
630 bool ValidateEC2N()
631 {
632  cout << "\nEC2N validation suite running...\n\n";
633 
634  ECIES<EC2N>::Decryptor cpriv(GlobalRNG(), ASN1::sect193r1());
635  ECIES<EC2N>::Encryptor cpub(cpriv);
636  ByteQueue bq;
637  cpriv.DEREncode(bq);
638  cpub.AccessKey().AccessGroupParameters().SetEncodeAsOID(true);
639  cpub.DEREncode(bq);
640  ECDSA<EC2N, SHA>::Signer spriv(bq);
642  ECDH<EC2N>::Domain ecdhc(ASN1::sect193r1());
643  ECMQV<EC2N>::Domain ecmqvc(ASN1::sect193r1());
644 
645  spriv.AccessKey().Precompute();
646  ByteQueue queue;
647  spriv.AccessKey().SavePrecomputation(queue);
648  spriv.AccessKey().LoadPrecomputation(queue);
649 
650  bool pass = SignatureValidate(spriv, spub);
651  pass = CryptoSystemValidate(cpriv, cpub) && pass;
652  pass = SimpleKeyAgreementValidate(ecdhc) && pass;
653  pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass;
654 
655  cout << "Turning on point compression..." << endl;
656  cpriv.AccessKey().AccessGroupParameters().SetPointCompression(true);
657  cpub.AccessKey().AccessGroupParameters().SetPointCompression(true);
658  ecdhc.AccessGroupParameters().SetPointCompression(true);
659  ecmqvc.AccessGroupParameters().SetPointCompression(true);
660  pass = CryptoSystemValidate(cpriv, cpub) && pass;
661  pass = SimpleKeyAgreementValidate(ecdhc) && pass;
662  pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass;
663 
664 #if 0 // TODO: turn this back on when I make EC2N faster for pentanomial basis
665  cout << "Testing SEC 2 recommended curves..." << endl;
666  OID oid;
667  while (!(oid = DL_GroupParameters_EC<EC2N>::GetNextRecommendedParametersOID(oid)).m_values.empty())
668  {
669  DL_GroupParameters_EC<EC2N> params(oid);
670  bool fail = !params.Validate(GlobalRNG(), 2);
671  cout << (fail ? "FAILED" : "passed") << " " << params.GetCurve().GetField().MaxElementBitLength() << " bits" << endl;
672  pass = pass && !fail;
673  }
674 #endif
675 
676  return pass;
677 }
678 
679 bool ValidateECDSA()
680 {
681  cout << "\nECDSA validation suite running...\n\n";
682 
683  // from Sample Test Vectors for P1363
684  GF2NT gf2n(191, 9, 0);
685  byte a[]="\x28\x66\x53\x7B\x67\x67\x52\x63\x6A\x68\xF5\x65\x54\xE1\x26\x40\x27\x6B\x64\x9E\xF7\x52\x62\x67";
686  byte b[]="\x2E\x45\xEF\x57\x1F\x00\x78\x6F\x67\xB0\x08\x1B\x94\x95\xA3\xD9\x54\x62\xF5\xDE\x0A\xA1\x85\xEC";
687  EC2N ec(gf2n, PolynomialMod2(a,24), PolynomialMod2(b,24));
688 
689  EC2N::Point P;
690  ec.DecodePoint(P, (byte *)"\x04\x36\xB3\xDA\xF8\xA2\x32\x06\xF9\xC4\xF2\x99\xD7\xB2\x1A\x9C\x36\x91\x37\xF2\xC8\x4A\xE1\xAA\x0D"
691  "\x76\x5B\xE7\x34\x33\xB3\xF9\x5E\x33\x29\x32\xE7\x0E\xA2\x45\xCA\x24\x18\xEA\x0E\xF9\x80\x18\xFB", ec.EncodedPointSize());
692  Integer n("40000000000000000000000004a20e90c39067c893bbb9a5H");
693  Integer d("340562e1dda332f9d2aec168249b5696ee39d0ed4d03760fH");
694  EC2N::Point Q(ec.Multiply(d, P));
695  ECDSA<EC2N, SHA>::Signer priv(ec, P, n, d);
696  ECDSA<EC2N, SHA>::Verifier pub(priv);
697 
698  Integer h("A9993E364706816ABA3E25717850C26C9CD0D89DH");
699  Integer k("3eeace72b4919d991738d521879f787cb590aff8189d2b69H");
700  byte sig[]="\x03\x8e\x5a\x11\xfb\x55\xe4\xc6\x54\x71\xdc\xd4\x99\x84\x52\xb1\xe0\x2d\x8a\xf7\x09\x9b\xb9\x30"
701  "\x0c\x9a\x08\xc3\x44\x68\xc2\x44\xb4\xe5\xd6\xb2\x1b\x3c\x68\x36\x28\x07\x41\x60\x20\x32\x8b\x6e";
702  Integer r(sig, 24);
703  Integer s(sig+24, 24);
704 
705  Integer rOut, sOut;
706  bool fail, pass=true;
707 
708  priv.RawSign(k, h, rOut, sOut);
709  fail = (rOut != r) || (sOut != s);
710  pass = pass && !fail;
711 
712  cout << (fail ? "FAILED " : "passed ");
713  cout << "signature check against test vector\n";
714 
715  fail = !pub.VerifyMessage((byte *)"abc", 3, sig, sizeof(sig));
716  pass = pass && !fail;
717 
718  cout << (fail ? "FAILED " : "passed ");
719  cout << "verification check against test vector\n";
720 
721  fail = pub.VerifyMessage((byte *)"xyz", 3, sig, sizeof(sig));
722  pass = pass && !fail;
723 
724  pass = SignatureValidate(priv, pub) && pass;
725 
726  return pass;
727 }
728 
729 bool ValidateESIGN()
730 {
731  cout << "\nESIGN validation suite running...\n\n";
732 
733  bool pass = true, fail;
734 
735  const char *plain = "test";
736  const byte *signature = (byte *)
737  "\xA3\xE3\x20\x65\xDE\xDA\xE7\xEC\x05\xC1\xBF\xCD\x25\x79\x7D\x99\xCD\xD5\x73\x9D\x9D\xF3\xA4\xAA\x9A\xA4\x5A\xC8\x23\x3D\x0D\x37\xFE\xBC\x76\x3F\xF1\x84\xF6\x59"
738  "\x14\x91\x4F\x0C\x34\x1B\xAE\x9A\x5C\x2E\x2E\x38\x08\x78\x77\xCB\xDC\x3C\x7E\xA0\x34\x44\x5B\x0F\x67\xD9\x35\x2A\x79\x47\x1A\x52\x37\x71\xDB\x12\x67\xC1\xB6\xC6"
739  "\x66\x73\xB3\x40\x2E\xD6\xF2\x1A\x84\x0A\xB6\x7B\x0F\xEB\x8B\x88\xAB\x33\xDD\xE4\x83\x21\x90\x63\x2D\x51\x2A\xB1\x6F\xAB\xA7\x5C\xFD\x77\x99\xF2\xE1\xEF\x67\x1A"
740  "\x74\x02\x37\x0E\xED\x0A\x06\xAD\xF4\x15\x65\xB8\xE1\xD1\x45\xAE\x39\x19\xB4\xFF\x5D\xF1\x45\x7B\xE0\xFE\x72\xED\x11\x92\x8F\x61\x41\x4F\x02\x00\xF2\x76\x6F\x7C"
741  "\x79\xA2\xE5\x52\x20\x5D\x97\x5E\xFE\x39\xAE\x21\x10\xFB\x35\xF4\x80\x81\x41\x13\xDD\xE8\x5F\xCA\x1E\x4F\xF8\x9B\xB2\x68\xFB\x28";
742 
743  FileSource keys(PACKAGE_DATA_DIR "TestData/esig1536.dat", true, new HexDecoder);
744  ESIGN<SHA>::Signer signer(keys);
745  ESIGN<SHA>::Verifier verifier(signer);
746 
747  fail = !SignatureValidate(signer, verifier);
748  pass = pass && !fail;
749 
750  fail = !verifier.VerifyMessage((byte *)plain, strlen(plain), signature, verifier.SignatureLength());
751  pass = pass && !fail;
752 
753  cout << (fail ? "FAILED " : "passed ");
754  cout << "verification check against test vector\n";
755 
756  cout << "Generating signature key from seed..." << endl;
757  signer.AccessKey().GenerateRandom(GlobalRNG(), MakeParameters("Seed", ConstByteArrayParameter((const byte *)"test", 4))("KeySize", 3*512));
758  verifier = signer;
759 
760  fail = !SignatureValidate(signer, verifier);
761  pass = pass && !fail;
762 
763  return pass;
764 }