Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

validat1.cpp

00001 // validat1.cpp - written and placed in the public domain by Wei Dai
00002 
00003 #include "pch.h"
00004 
00005 #include "files.h"
00006 #include "hex.h"
00007 #include "base64.h"
00008 #include "modes.h"
00009 #include "cbcmac.h"
00010 #include "dmac.h"
00011 #include "idea.h"
00012 #include "des.h"
00013 #include "rc2.h"
00014 #include "arc4.h"
00015 #include "rc5.h"
00016 #include "blowfish.h"
00017 #include "diamond.h"
00018 #include "wake.h"
00019 #include "3way.h"
00020 #include "safer.h"
00021 #include "gost.h"
00022 #include "shark.h"
00023 #include "cast.h"
00024 #include "square.h"
00025 #include "seal.h"
00026 #include "rc6.h"
00027 #include "mars.h"
00028 #include "rijndael.h"
00029 #include "twofish.h"
00030 #include "serpent.h"
00031 #include "skipjack.h"
00032 #include "osrng.h"
00033 #include "zdeflate.h"
00034 
00035 #include <stdlib.h>
00036 #include <time.h>
00037 #include <memory>
00038 #include <iostream>
00039 #include <iomanip>
00040 
00041 #include "validate.h"
00042 
00043 USING_NAMESPACE(CryptoPP)
00044 USING_NAMESPACE(std)
00045 
00046 bool ValidateAll(bool thorough)
00047 {
00048         bool pass=TestSettings();
00049         pass=TestOS_RNG() && pass;
00050 
00051         pass=ValidateCRC32() && pass;
00052         pass=ValidateAdler32() && pass;
00053         pass=ValidateMD2() && pass;
00054         pass=ValidateMD5() && pass;
00055         pass=ValidateSHA() && pass;
00056         pass=ValidateSHA2() && pass;
00057         pass=ValidateHAVAL() && pass;
00058         pass=ValidateTiger() && pass;
00059         pass=ValidateRIPEMD() && pass;
00060         pass=ValidatePanama() && pass;
00061 
00062         pass=ValidateMD5MAC() && pass;
00063         pass=ValidateHMAC() && pass;
00064         pass=ValidateXMACC() && pass;
00065 
00066         pass=ValidatePBKDF() && pass;
00067 
00068         pass=ValidateDES() && pass;
00069         pass=ValidateCipherModes() && pass;
00070         pass=ValidateIDEA() && pass;
00071         pass=ValidateSAFER() && pass;
00072         pass=ValidateRC2() && pass;
00073         pass=ValidateARC4() && pass;
00074         pass=ValidateRC5() && pass;
00075         pass=ValidateBlowfish() && pass;
00076         pass=ValidateDiamond2() && pass;
00077         pass=ValidateThreeWay() && pass;
00078         pass=ValidateGOST() && pass;
00079         pass=ValidateSHARK() && pass;
00080         pass=ValidateCAST() && pass;
00081         pass=ValidateSquare() && pass;
00082         pass=ValidateSKIPJACK() && pass;
00083         pass=ValidateSEAL() && pass;
00084         pass=ValidateRC6() && pass;
00085         pass=ValidateMARS() && pass;
00086         pass=ValidateRijndael() && pass;
00087         pass=ValidateTwofish() && pass;
00088         pass=ValidateSerpent() && pass;
00089 
00090         pass=ValidateBBS() && pass;
00091         pass=ValidateDH() && pass;
00092         pass=ValidateMQV() && pass;
00093         pass=ValidateRSA() && pass;
00094         pass=ValidateElGamal() && pass;
00095         pass=ValidateDLIES() && pass;
00096         pass=ValidateNR() && pass;
00097         pass=ValidateDSA(thorough) && pass;
00098         pass=ValidateLUC() && pass;
00099         pass=ValidateLUC_DH() && pass;
00100         pass=ValidateLUC_DL() && pass;
00101         pass=ValidateXTR_DH() && pass;
00102         pass=ValidateRabin() && pass;
00103         pass=ValidateRW() && pass;
00104 //      pass=ValidateBlumGoldwasser() && pass;
00105         pass=ValidateECP() && pass;
00106         pass=ValidateEC2N() && pass;
00107         pass=ValidateECDSA() && pass;
00108         pass=ValidateESIGN() && pass;
00109 
00110         if (pass)
00111                 cout << "\nAll tests passed!\n";
00112         else
00113                 cout << "\nOops!  Not all tests passed.\n";
00114 
00115         return pass;
00116 }
00117 
00118 bool TestSettings()
00119 {
00120         bool pass = true;
00121 
00122         cout << "\nTesting Settings...\n\n";
00123 
00124         if (*(word32 *)"\x01\x02\x03\x04" == 0x04030201L)
00125         {
00126 #ifdef IS_LITTLE_ENDIAN
00127                 cout << "passed:  ";
00128 #else
00129                 cout << "FAILED:  ";
00130                 pass = false;
00131 #endif
00132                 cout << "Your machine is little endian.\n";
00133         }
00134         else if (*(word32 *)"\x01\x02\x03\x04" == 0x01020304L)
00135         {
00136 #ifndef IS_LITTLE_ENDIAN
00137                 cout << "passed:  ";
00138 #else
00139                 cout << "FAILED:  ";
00140                 pass = false;
00141 #endif
00142                 cout << "Your machine is big endian.\n";
00143         }
00144         else
00145         {
00146                 cout << "FAILED:  Your machine is neither big endian nor little endian.\n";
00147                 pass = false;
00148         }
00149 
00150         if (sizeof(byte) == 1)
00151                 cout << "passed:  ";
00152         else
00153         {
00154                 cout << "FAILED:  ";
00155                 pass = false;
00156         }
00157         cout << "sizeof(byte) == " << sizeof(byte) << endl;
00158 
00159         if (sizeof(word16) == 2)
00160                 cout << "passed:  ";
00161         else
00162         {
00163                 cout << "FAILED:  ";
00164                 pass = false;
00165         }
00166         cout << "sizeof(word16) == " << sizeof(word16) << endl;
00167 
00168         if (sizeof(word32) == 4)
00169                 cout << "passed:  ";
00170         else
00171         {
00172                 cout << "FAILED:  ";
00173                 pass = false;
00174         }
00175         cout << "sizeof(word32) == " << sizeof(word32) << endl;
00176 
00177 #ifdef WORD64_AVAILABLE
00178         if (sizeof(word64) == 8)
00179                 cout << "passed:  ";
00180         else
00181         {
00182                 cout << "FAILED:  ";
00183                 pass = false;
00184         }
00185         cout << "sizeof(word64) == " << sizeof(word64) << endl;
00186 #else
00187         if (sizeof(dword) >= 8)
00188         {
00189                 cout << "FAILED:  sizeof(dword) >= 8, but WORD64_AVAILABLE not defined" << endl;
00190                 pass = false;
00191         }
00192         else
00193                 cout << "passed:  word64 not available" << endl;
00194 #endif
00195 
00196         if (sizeof(dword) == 2*sizeof(word))
00197                 cout << "passed:  ";
00198         else
00199         {
00200                 cout << "FAILED:  ";
00201                 pass = false;
00202         }
00203         cout << "sizeof(word) == " << sizeof(word) << ", sizeof(dword) == " << sizeof(dword) << endl;
00204 
00205         dword test = (dword(1)<<WORD_BITS) + 2;
00206         if (HIGH_WORD(test) == 1 && LOW_WORD(test) == 2)
00207                 cout << "passed:  ";
00208         else
00209         {
00210                 cout << "FAILED:  ";
00211                 pass = false;
00212         }
00213         cout << "HIGH_WORD() and LOW_WORD() macros\n";
00214 
00215         if (!pass)
00216         {
00217                 cout << "Some critical setting in config.h is in error.  Please fix it and recompile." << endl;
00218                 abort();
00219         }
00220         return pass;
00221 }
00222 
00223 bool TestOS_RNG()
00224 {
00225         bool pass = true;
00226 
00227         member_ptr<RandomNumberGenerator> rng;
00228 #ifdef BLOCKING_RNG_AVAILABLE
00229         try {rng.reset(new BlockingRng);}
00230         catch (OS_RNG_Err &) {}
00231 #endif
00232 
00233         if (rng.get())
00234         {
00235                 cout << "\nTesting operating system provided blocking random number generator...\n\n";
00236 
00237                 ArraySink *sink;
00238                 RandomNumberSource test(*rng, UINT_MAX, false, new Deflator(sink=new ArraySink(NULL,0)));
00239                 unsigned long total=0, length=0;
00240                 time_t t = time(NULL), t1 = 0;
00241 
00242                 // check that it doesn't take too long to generate a reasonable amount of randomness
00243                 while (total < 16 && (t1 < 10 || total*8 > (unsigned long)t1))
00244                 {
00245                         test.Pump(1);
00246                         total += 1;
00247                         t1 = time(NULL) - t;
00248                 }
00249 
00250                 if (total < 16)
00251                 {
00252                         cout << "FAILED:";
00253                         pass = false;
00254                 }
00255                 else
00256                         cout << "passed:";
00257                 cout << "  it took " << t1 << " seconds to generate " << total << " bytes" << endl;
00258 
00259                 if (t1 < 2)
00260                 {
00261                         // that was fast, are we really blocking?
00262                         // first exhaust the extropy reserve
00263                         t = time(NULL);
00264                         while (time(NULL) - t < 2)
00265                         {
00266                                 test.Pump(1);
00267                                 total += 1;
00268                         }
00269 
00270                         // if it generates too many bytes in a certain amount of time,
00271                         // something's probably wrong
00272                         t = time(NULL);
00273                         while (time(NULL) - t < 2)
00274                         {
00275                                 test.Pump(1);
00276                                 total += 1;
00277                                 length += 1;
00278                         }
00279                         // turn off this test because it fails on several systems, including Darwin
00280                         // they don't block, or gather entropy too fast?
00281                         if (false) // (length > 1024)
00282                         {
00283                                 cout << "FAILED:";
00284                                 pass = false;
00285                         }
00286                         else
00287                                 cout << "passed:";
00288                         cout << "  it generated " << length << " bytes in " << time(NULL) - t << " seconds" << endl;
00289                 }
00290 
00291                 test.AttachedTransformation()->MessageEnd();
00292 
00293                 if (sink->TotalPutLength() < total)
00294                 {
00295                         cout << "FAILED:";
00296                         pass = false;
00297                 }
00298                 else
00299                         cout << "passed:";
00300                 cout << "  " << total << " generated bytes compressed to " << sink->TotalPutLength() << " bytes by DEFLATE" << endl;
00301         }
00302         else
00303                 cout << "\nNo operating system provided blocking random number generator, skipping test." << endl;
00304 
00305         rng.reset(NULL);
00306 #ifdef NONBLOCKING_RNG_AVAILABLE
00307         try {rng.reset(new NonblockingRng);}
00308         catch (OS_RNG_Err &) {}
00309 #endif
00310 
00311         if (rng.get())
00312         {
00313                 cout << "\nTesting operating system provided nonblocking random number generator...\n\n";
00314 
00315                 ArraySink *sink;
00316                 RandomNumberSource test(*rng, 100000, true, new Deflator(sink=new ArraySink(NULL, 0)));
00317                 
00318                 if (sink->TotalPutLength() < 100000)
00319                 {
00320                         cout << "FAILED:";
00321                         pass = false;
00322                 }
00323                 else
00324                         cout << "passed:";
00325                 cout << "  100000 generated bytes compressed to " << sink->TotalPutLength() << " bytes by DEFLATE" << endl;
00326         }
00327         else
00328                 cout << "\nNo operating system provided nonblocking random number generator, skipping test." << endl;
00329 
00330         return pass;
00331 }
00332 
00333 // VC50 workaround
00334 typedef auto_ptr<BlockTransformation> apbt;
00335 
00336 class CipherFactory
00337 {
00338 public:
00339         virtual unsigned int BlockSize() const =0;
00340         virtual unsigned int KeyLength() const =0;
00341 
00342         virtual apbt NewEncryption(const byte *key) const =0;
00343         virtual apbt NewDecryption(const byte *key) const =0;
00344 };
00345 
00346 template <class E, class D> class FixedRoundsCipherFactory : public CipherFactory
00347 {
00348 public:
00349         FixedRoundsCipherFactory(unsigned int keylen=0) : m_keylen(keylen?keylen:E::DEFAULT_KEYLENGTH) {}
00350         unsigned int BlockSize() const {return E::BLOCKSIZE;}
00351         unsigned int KeyLength() const {return m_keylen;}
00352 
00353         apbt NewEncryption(const byte *key) const
00354                 {return apbt(new E(key, m_keylen));}
00355         apbt NewDecryption(const byte *key) const
00356                 {return apbt(new D(key, m_keylen));}
00357 
00358         unsigned int m_keylen;
00359 };
00360 
00361 template <class E, class D> class VariableRoundsCipherFactory : public CipherFactory
00362 {
00363 public:
00364         VariableRoundsCipherFactory(unsigned int keylen=0, unsigned int rounds=0)
00365                 : m_keylen(keylen ? keylen : E::DEFAULT_KEYLENGTH), m_rounds(rounds ? rounds : E::DEFAULT_ROUNDS) {}
00366         unsigned int BlockSize() const {return E::BLOCKSIZE;}
00367         unsigned int KeyLength() const {return m_keylen;}
00368 
00369         apbt NewEncryption(const byte *key) const
00370                 {return apbt(new E(key, m_keylen, m_rounds));}
00371         apbt NewDecryption(const byte *key) const
00372                 {return apbt(new D(key, m_keylen, m_rounds));}
00373 
00374         unsigned int m_keylen, m_rounds;
00375 };
00376 
00377 bool BlockTransformationTest(const CipherFactory &cg, BufferedTransformation &valdata, unsigned int tuples = 0xffff)
00378 {
00379         HexEncoder output(new FileSink(cout));
00380         SecByteBlock plain(cg.BlockSize()), cipher(cg.BlockSize()), out(cg.BlockSize()), outplain(cg.BlockSize());
00381         SecByteBlock key(cg.KeyLength());
00382         bool pass=true, fail;
00383 
00384         while (valdata.MaxRetrievable() && tuples--)
00385         {
00386                 valdata.Get(key, cg.KeyLength());
00387                 valdata.Get(plain, cg.BlockSize());
00388                 valdata.Get(cipher, cg.BlockSize());
00389 
00390                 apbt transE = cg.NewEncryption(key);
00391                 transE->ProcessBlock(plain, out);
00392                 fail = memcmp(out, cipher, cg.BlockSize()) != 0;
00393 
00394                 apbt transD = cg.NewDecryption(key);
00395                 transD->ProcessBlock(out, outplain);
00396                 fail=fail || memcmp(outplain, plain, cg.BlockSize());
00397 
00398                 pass = pass && !fail;
00399 
00400                 cout << (fail ? "FAILED   " : "passed   ");
00401                 output.Put(key, cg.KeyLength());
00402                 cout << "   ";
00403                 output.Put(outplain, cg.BlockSize());
00404                 cout << "   ";
00405                 output.Put(out, cg.BlockSize());
00406                 cout << endl;
00407         }
00408         return pass;
00409 }
00410 
00411 class FilterTester : public Unflushable<Sink>
00412 {
00413 public:
00414         FilterTester(const byte *validOutput, unsigned int outputLen)
00415                 : validOutput(validOutput), outputLen(outputLen), counter(0), fail(false) {}
00416         void PutByte(byte inByte)
00417         {
00418                 if (counter >= outputLen || validOutput[counter] != inByte)
00419                 {
00420                         fail = true;
00421                         assert(false);
00422                 }
00423                 counter++;
00424         }
00425         unsigned int Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking)
00426         {
00427                 while (length--)
00428                         FilterTester::PutByte(*inString++);
00429 
00430                 if (messageEnd)
00431                         if (counter != outputLen)
00432                         {
00433                                 fail = true;
00434                                 assert(false);
00435                         }
00436 
00437                 return 0;
00438         }
00439         bool GetResult()
00440         {
00441                 return !fail;
00442         }
00443 
00444         const byte *validOutput;
00445         unsigned int outputLen, counter;
00446         bool fail;
00447 };
00448 
00449 bool TestFilter(BufferedTransformation &bt, const byte *in, unsigned int inLen, const byte *out, unsigned int outLen)
00450 {
00451         FilterTester *ft;
00452         bt.Attach(ft = new FilterTester(out, outLen));
00453 
00454         while (inLen)
00455         {
00456                 unsigned int randomLen = GlobalRNG().GenerateWord32(0, inLen);
00457                 bt.Put(in, randomLen);
00458                 in += randomLen;
00459                 inLen -= randomLen;
00460         }
00461         bt.MessageEnd();
00462         return ft->GetResult();
00463 }
00464 
00465 bool ValidateDES()
00466 {
00467         cout << "\nDES validation suite running...\n\n";
00468 
00469         FileSource valdata(PKGDATA("descert.dat"), true, new HexDecoder);
00470         bool pass = BlockTransformationTest(FixedRoundsCipherFactory<DESEncryption, DESDecryption>(), valdata);
00471 
00472         cout << "\nTesting EDE2, EDE3, and XEX3 variants...\n\n";
00473 
00474         FileSource valdata1(PKGDATA("3desval.dat"), true, new HexDecoder);
00475         pass = BlockTransformationTest(FixedRoundsCipherFactory<DES_EDE2_Encryption, DES_EDE2_Decryption>(), valdata1, 1) && pass;
00476         pass = BlockTransformationTest(FixedRoundsCipherFactory<DES_EDE3_Encryption, DES_EDE3_Decryption>(), valdata1, 1) && pass;
00477         pass = BlockTransformationTest(FixedRoundsCipherFactory<DES_XEX3_Encryption, DES_XEX3_Decryption>(), valdata1, 1) && pass;
00478 
00479         return pass;
00480 }
00481 
00482 bool TestModeIV(SymmetricCipher &e, SymmetricCipher &d)
00483 {
00484         SecByteBlock lastIV;
00485         StreamTransformationFilter filter(e, new StreamTransformationFilter(d));
00486         byte plaintext[20480];
00487 
00488         for (unsigned int i=1; i<sizeof(plaintext); i*=2)
00489         {
00490                 SecByteBlock iv(e.IVSize());
00491                 e.GetNextIV(iv);
00492 
00493                 if (iv == lastIV)
00494                         return false;
00495                 else
00496                         lastIV = iv;
00497 
00498                 e.Resynchronize(iv);
00499                 d.Resynchronize(iv);
00500 
00501                 unsigned int length = STDMAX(GlobalRNG().GenerateWord32(0, i), (word32)e.MinLastBlockSize());
00502                 GlobalRNG().GenerateBlock(plaintext, length);
00503 
00504                 if (!TestFilter(filter, plaintext, length, plaintext, length))
00505                         return false;
00506         }
00507 
00508         return true;
00509 }
00510 
00511 bool ValidateCipherModes()
00512 {
00513         cout << "\nTesting DES modes...\n\n";
00514         const byte key[] = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
00515         const byte iv[] = {0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef};
00516         const byte plain[] = {  // "Now is the time for all " without tailing 0
00517                 0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74,
00518                 0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20,
00519                 0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20};
00520         DESEncryption desE(key);
00521         DESDecryption desD(key);
00522         bool pass=true, fail;
00523 
00524         {
00525                 // from FIPS 81
00526                 const byte encrypted[] = {
00527                         0x3f, 0xa4, 0x0e, 0x8a, 0x98, 0x4d, 0x48, 0x15,
00528                         0x6a, 0x27, 0x17, 0x87, 0xab, 0x88, 0x83, 0xf9,
00529                         0x89, 0x3d, 0x51, 0xec, 0x4b, 0x56, 0x3b, 0x53};
00530 
00531                 ECB_Mode_ExternalCipher::Encryption modeE(desE);
00532                 fail = !TestFilter(StreamTransformationFilter(modeE, NULL, StreamTransformationFilter::NO_PADDING).Ref(),
00533                         plain, sizeof(plain), encrypted, sizeof(encrypted));
00534                 pass = pass && !fail;
00535                 cout << (fail ? "FAILED   " : "passed   ") << "ECB encryption" << endl;
00536                 
00537                 ECB_Mode_ExternalCipher::Decryption modeD(desD);
00538                 fail = !TestFilter(StreamTransformationFilter(modeD, NULL, StreamTransformationFilter::NO_PADDING).Ref(),
00539                         encrypted, sizeof(encrypted), plain, sizeof(plain));
00540                 pass = pass && !fail;
00541                 cout << (fail ? "FAILED   " : "passed   ") << "ECB decryption" << endl;
00542         }
00543         {
00544                 // from FIPS 81
00545                 const byte encrypted[] = {
00546                         0xE5, 0xC7, 0xCD, 0xDE, 0x87, 0x2B, 0xF2, 0x7C, 
00547                         0x43, 0xE9, 0x34, 0x00, 0x8C, 0x38, 0x9C, 0x0F, 
00548                         0x68, 0x37, 0x88, 0x49, 0x9A, 0x7C, 0x05, 0xF6};
00549 
00550                 CBC_Mode_ExternalCipher::Encryption modeE(desE, iv);
00551                 fail = !TestFilter(StreamTransformationFilter(modeE, NULL, StreamTransformationFilter::NO_PADDING).Ref(),
00552                         plain, sizeof(plain), encrypted, sizeof(encrypted));
00553                 pass = pass && !fail;
00554                 cout << (fail ? "FAILED   " : "passed   ") << "CBC encryption with no padding" << endl;
00555                 
00556                 CBC_Mode_ExternalCipher::Decryption modeD(desD, iv);
00557                 fail = !TestFilter(StreamTransformationFilter(modeD, NULL, StreamTransformationFilter::NO_PADDING).Ref(),
00558                         encrypted, sizeof(encrypted), plain, sizeof(plain));
00559                 pass = pass && !fail;
00560                 cout << (fail ? "FAILED   " : "passed   ") << "CBC decryption with no padding" << endl;
00561 
00562                 fail = !TestModeIV(modeE, modeD);
00563                 pass = pass && !fail;
00564                 cout << (fail ? "FAILED   " : "passed   ") << "CBC mode IV generation" << endl;
00565         }
00566         {
00567                 // generated with Crypto++, matches FIPS 81
00568                 // but has extra 8 bytes as result of padding
00569                 const byte encrypted[] = {
00570                         0xE5, 0xC7, 0xCD, 0xDE, 0x87, 0x2B, 0xF2, 0x7C, 
00571                         0x43, 0xE9, 0x34, 0x00, 0x8C, 0x38, 0x9C, 0x0F, 
00572                         0x68, 0x37, 0x88, 0x49, 0x9A, 0x7C, 0x05, 0xF6, 
00573                         0x62, 0xC1, 0x6A, 0x27, 0xE4, 0xFC, 0xF2, 0x77};
00574 
00575                 CBC_Mode_ExternalCipher::Encryption modeE(desE, iv);
00576                 fail = !TestFilter(StreamTransformationFilter(modeE).Ref(),
00577                         plain, sizeof(plain), encrypted, sizeof(encrypted));
00578                 pass = pass && !fail;
00579                 cout << (fail ? "FAILED   " : "passed   ") << "CBC encryption with PKCS #7 padding" << endl;
00580                 
00581                 CBC_Mode_ExternalCipher::Decryption modeD(desD, iv);
00582                 fail = !TestFilter(StreamTransformationFilter(modeD).Ref(),
00583                         encrypted, sizeof(encrypted), plain, sizeof(plain));
00584                 pass = pass && !fail;
00585                 cout << (fail ? "FAILED   " : "passed   ") << "CBC decryption with PKCS #7 padding" << endl;
00586         }
00587         {
00588                 // generated with Crypto++, matches FIPS 81
00589                 // but has extra 8 bytes as result of padding
00590                 const byte encrypted[] = {
00591                         0xE5, 0xC7, 0xCD, 0xDE, 0x87, 0x2B, 0xF2, 0x7C, 
00592                         0x43, 0xE9, 0x34, 0x00, 0x8C, 0x38, 0x9C, 0x0F, 
00593                         0x68, 0x37, 0x88, 0x49, 0x9A, 0x7C, 0x05, 0xF6, 
00594                         0x57, 0x25, 0x0C, 0x94, 0x83, 0xD5, 0x01, 0x79};
00595 
00596                 CBC_Mode_ExternalCipher::Encryption modeE(desE, iv);
00597                 fail = !TestFilter(StreamTransformationFilter(modeE, NULL, StreamTransformationFilter::ONE_AND_ZEROS_PADDING).Ref(),
00598                         plain, sizeof(plain), encrypted, sizeof(encrypted));
00599                 pass = pass && !fail;
00600                 cout << (fail ? "FAILED   " : "passed   ") << "CBC encryption with one-and-zeros padding" << endl;
00601 
00602                 CBC_Mode_ExternalCipher::Decryption modeD(desD, iv);
00603                 fail = !TestFilter(StreamTransformationFilter(modeD, NULL, StreamTransformationFilter::ONE_AND_ZEROS_PADDING).Ref(),
00604                         encrypted, sizeof(encrypted), plain, sizeof(plain));
00605                 pass = pass && !fail;
00606                 cout << (fail ? "FAILED   " : "passed   ") << "CBC decryption with one-and-zeros padding" << endl;
00607         }
00608         {
00609                 const byte plain[] = {'a', 0, 0, 0, 0, 0, 0, 0};
00610                 // generated with Crypto++
00611                 const byte encrypted[] = {
00612                         0x9B, 0x47, 0x57, 0x59, 0xD6, 0x9C, 0xF6, 0xD0};
00613 
00614                 CBC_Mode_ExternalCipher::Encryption modeE(desE, iv);
00615                 fail = !TestFilter(StreamTransformationFilter(modeE, NULL, StreamTransformationFilter::ZEROS_PADDING).Ref(),
00616                         plain, 1, encrypted, sizeof(encrypted));
00617                 pass = pass && !fail;
00618                 cout << (fail ? "FAILED   " : "passed   ") << "CBC encryption with zeros padding" << endl;
00619 
00620                 CBC_Mode_ExternalCipher::Decryption modeD(desD, iv);
00621                 fail = !TestFilter(StreamTransformationFilter(modeD, NULL, StreamTransformationFilter::ZEROS_PADDING).Ref(),
00622                         encrypted, sizeof(encrypted), plain, sizeof(plain));
00623                 pass = pass && !fail;
00624                 cout << (fail ? "FAILED   " : "passed   ") << "CBC decryption with zeros padding" << endl;
00625         }
00626         {
00627                 // generated with Crypto++, matches FIPS 81
00628                 // but with last two blocks swapped as result of CTS
00629                 const byte encrypted[] = {
00630                         0xE5, 0xC7, 0xCD, 0xDE, 0x87, 0x2B, 0xF2, 0x7C, 
00631                         0x68, 0x37, 0x88, 0x49, 0x9A, 0x7C, 0x05, 0xF6, 
00632                         0x43, 0xE9, 0x34, 0x00, 0x8C, 0x38, 0x9C, 0x0F};
00633 
00634                 CBC_CTS_Mode_ExternalCipher::Encryption modeE(desE, iv);
00635                 fail = !TestFilter(StreamTransformationFilter(modeE).Ref(),
00636                         plain, sizeof(plain), encrypted, sizeof(encrypted));
00637                 pass = pass && !fail;
00638                 cout << (fail ? "FAILED   " : "passed   ") << "CBC encryption with ciphertext stealing (CTS)" << endl;
00639                 
00640                 CBC_CTS_Mode_ExternalCipher::Decryption modeD(desD, iv);
00641                 fail = !TestFilter(StreamTransformationFilter(modeD).Ref(),
00642                         encrypted, sizeof(encrypted), plain, sizeof(plain));
00643                 pass = pass && !fail;
00644                 cout << (fail ? "FAILED   " : "passed   ") << "CBC decryption with ciphertext stealing (CTS)" << endl;
00645 
00646                 fail = !TestModeIV(modeE, modeD);
00647                 pass = pass && !fail;
00648                 cout << (fail ? "FAILED   " : "passed   ") << "CBC CTS IV generation" << endl;
00649         }
00650         {
00651                 // generated with Crypto++
00652                 const byte decryptionIV[] = {0x4D, 0xD0, 0xAC, 0x8F, 0x47, 0xCF, 0x79, 0xCE};
00653                 const byte encrypted[] = {0x12, 0x34, 0x56};
00654 
00655                 byte stolenIV[8];
00656 
00657                 CBC_CTS_Mode_ExternalCipher::Encryption modeE(desE, iv);
00658                 modeE.SetStolenIV(stolenIV);
00659                 fail = !TestFilter(StreamTransformationFilter(modeE).Ref(),
00660                         plain, 3, encrypted, sizeof(encrypted));
00661                 fail = memcmp(stolenIV, decryptionIV, 8) != 0 || fail;
00662                 pass = pass && !fail;
00663                 cout << (fail ? "FAILED   " : "passed   ") << "CBC encryption with ciphertext and IV stealing" << endl;
00664                 
00665                 CBC_CTS_Mode_ExternalCipher::Decryption modeD(desD, stolenIV);
00666                 fail = !TestFilter(StreamTransformationFilter(modeD).Ref(),
00667                         encrypted, sizeof(encrypted), plain, 3);
00668                 pass = pass && !fail;
00669                 cout << (fail ? "FAILED   " : "passed   ") << "CBC decryption with ciphertext and IV stealing" << endl;
00670         }
00671         {
00672                 const byte encrypted[] = {      // from FIPS 81
00673                         0xF3,0x09,0x62,0x49,0xC7,0xF4,0x6E,0x51,
00674                         0xA6,0x9E,0x83,0x9B,0x1A,0x92,0xF7,0x84,
00675                         0x03,0x46,0x71,0x33,0x89,0x8E,0xA6,0x22};
00676 
00677                 CFB_Mode_ExternalCipher::Encryption modeE(desE, iv);
00678                 fail = !TestFilter(StreamTransformationFilter(modeE).Ref(),
00679                         plain, sizeof(plain), encrypted, sizeof(encrypted));
00680                 pass = pass && !fail;
00681                 cout << (fail ? "FAILED   " : "passed   ") << "CFB encryption" << endl;
00682 
00683                 CFB_Mode_ExternalCipher::Decryption modeD(desE, iv);
00684                 fail = !TestFilter(StreamTransformationFilter(modeD).Ref(),
00685                         encrypted, sizeof(encrypted), plain, sizeof(plain));
00686                 pass = pass && !fail;
00687                 cout << (fail ? "FAILED   " : "passed   ") << "CFB decryption" << endl;
00688 
00689                 fail = !TestModeIV(modeE, modeD);
00690                 pass = pass && !fail;
00691                 cout << (fail ? "FAILED   " : "passed   ") << "CFB mode IV generation" << endl;
00692         }
00693         {
00694                 const byte plain[] = {  // "Now is the." without tailing 0
00695                         0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74,0x68,0x65};
00696                 const byte encrypted[] = {      // from FIPS 81
00697                         0xf3,0x1f,0xda,0x07,0x01,0x14,0x62,0xee,0x18,0x7f};
00698 
00699                 CFB_Mode_ExternalCipher::Encryption modeE(desE, iv, 1);
00700                 fail = !TestFilter(StreamTransformationFilter(modeE).Ref(),
00701                         plain, sizeof(plain), encrypted, sizeof(encrypted));
00702                 pass = pass && !fail;
00703                 cout << (fail ? "FAILED   " : "passed   ") << "CFB (8-bit feedback) encryption" << endl;
00704 
00705                 CFB_Mode_ExternalCipher::Decryption modeD(desE, iv, 1);
00706                 fail = !TestFilter(StreamTransformationFilter(modeD).Ref(),
00707                         encrypted, sizeof(encrypted), plain, sizeof(plain));
00708                 pass = pass && !fail;
00709                 cout << (fail ? "FAILED   " : "passed   ") << "CFB (8-bit feedback) decryption" << endl;
00710 
00711                 fail = !TestModeIV(modeE, modeD);
00712                 pass = pass && !fail;
00713                 cout << (fail ? "FAILED   " : "passed   ") << "CFB (8-bit feedback) IV generation" << endl;
00714         }
00715         {
00716                 const byte encrypted[] = {      // from Eric Young's libdes
00717                         0xf3,0x09,0x62,0x49,0xc7,0xf4,0x6e,0x51,
00718                         0x35,0xf2,0x4a,0x24,0x2e,0xeb,0x3d,0x3f,
00719                         0x3d,0x6d,0x5b,0xe3,0x25,0x5a,0xf8,0xc3};
00720 
00721                 OFB_Mode_ExternalCipher::Encryption modeE(desE, iv);
00722                 fail = !TestFilter(StreamTransformationFilter(modeE).Ref(),
00723                         plain, sizeof(plain), encrypted, sizeof(encrypted));
00724                 pass = pass && !fail;
00725                 cout << (fail ? "FAILED   " : "passed   ") << "OFB encryption" << endl;
00726 
00727                 OFB_Mode_ExternalCipher::Decryption modeD(desE, iv);
00728                 fail = !TestFilter(StreamTransformationFilter(modeD).Ref(),
00729                         encrypted, sizeof(encrypted), plain, sizeof(plain));
00730                 pass = pass && !fail;
00731                 cout << (fail ? "FAILED   " : "passed   ") << "OFB decryption" << endl;
00732 
00733                 fail = !TestModeIV(modeE, modeD);
00734                 pass = pass && !fail;
00735                 cout << (fail ? "FAILED   " : "passed   ") << "OFB IV generation" << endl;
00736         }
00737         {
00738                 const byte encrypted[] = {      // generated with Crypto++
00739                         0xF3, 0x09, 0x62, 0x49, 0xC7, 0xF4, 0x6E, 0x51, 
00740                         0x16, 0x3A, 0x8C, 0xA0, 0xFF, 0xC9, 0x4C, 0x27, 
00741                         0xFA, 0x2F, 0x80, 0xF4, 0x80, 0xB8, 0x6F, 0x75};
00742 
00743                 CTR_Mode_ExternalCipher::Encryption modeE(desE, iv);
00744                 fail = !TestFilter(StreamTransformationFilter(modeE).Ref(),
00745                         plain, sizeof(plain), encrypted, sizeof(encrypted));
00746                 pass = pass && !fail;
00747                 cout << (fail ? "FAILED   " : "passed   ") << "Counter Mode encryption" << endl;
00748 
00749                 CTR_Mode_ExternalCipher::Decryption modeD(desE, iv);
00750                 fail = !TestFilter(StreamTransformationFilter(modeD).Ref(),
00751                         encrypted, sizeof(encrypted), plain, sizeof(plain));
00752                 pass = pass && !fail;
00753                 cout << (fail ? "FAILED   " : "passed   ") << "Counter Mode decryption" << endl;
00754 
00755                 fail = !TestModeIV(modeE, modeD);
00756                 pass = pass && !fail;
00757                 cout << (fail ? "FAILED   " : "passed   ") << "Counter Mode IV generation" << endl;
00758         }
00759         {
00760                 const byte plain[] = {  // "7654321 Now is the time for "
00761                         0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20, 
00762                         0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74, 
00763                         0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 
00764                         0x66, 0x6f, 0x72, 0x20};
00765                 const byte mac1[] = {   // from FIPS 113
00766                         0xf1, 0xd3, 0x0f, 0x68, 0x49, 0x31, 0x2c, 0xa4};
00767                 const byte mac2[] = {   // generated with Crypto++
00768                         0x35, 0x80, 0xC5, 0xC4, 0x6B, 0x81, 0x24, 0xE2};
00769 
00770                 CBC_MAC<DES> cbcmac(key);
00771                 HashFilter cbcmacFilter(cbcmac);
00772                 fail = !TestFilter(cbcmacFilter, plain, sizeof(plain), mac1, sizeof(mac1));
00773                 pass = pass && !fail;
00774                 cout << (fail ? "FAILED   " : "passed   ") << "CBC MAC" << endl;
00775 
00776                 DMAC<DES> dmac(key);
00777                 HashFilter dmacFilter(dmac);
00778                 fail = !TestFilter(dmacFilter, plain, sizeof(plain), mac2, sizeof(mac2));
00779                 pass = pass && !fail;
00780                 cout << (fail ? "FAILED   " : "passed   ") << "DMAC" << endl;
00781         }
00782 
00783         return pass;
00784 }
00785 
00786 bool ValidateIDEA()
00787 {
00788         cout << "\nIDEA validation suite running...\n\n";
00789 
00790         FileSource valdata(PKGDATA("ideaval.dat"), true, new HexDecoder);
00791         return BlockTransformationTest(FixedRoundsCipherFactory<IDEAEncryption, IDEADecryption>(), valdata);
00792 }
00793 
00794 bool ValidateSAFER()
00795 {
00796         cout << "\nSAFER validation suite running...\n\n";
00797 
00798         FileSource valdata(PKGDATA("saferval.dat"), true, new HexDecoder);
00799         bool pass = true;
00800         pass = BlockTransformationTest(VariableRoundsCipherFactory<SAFER_K_Encryption, SAFER_K_Decryption>(8,6), valdata, 4) && pass;
00801         pass = BlockTransformationTest(VariableRoundsCipherFactory<SAFER_K_Encryption, SAFER_K_Decryption>(16,12), valdata, 4) && pass;
00802         pass = BlockTransformationTest(VariableRoundsCipherFactory<SAFER_SK_Encryption, SAFER_SK_Decryption>(8,6), valdata, 4) && pass;
00803         pass = BlockTransformationTest(VariableRoundsCipherFactory<SAFER_SK_Encryption, SAFER_SK_Decryption>(16,10), valdata, 4) && pass;
00804         return pass;
00805 }
00806 
00807 bool ValidateRC2()
00808 {
00809         cout << "\nRC2 validation suite running...\n\n";
00810 
00811         FileSource valdata(PKGDATA("rc2val.dat"), true, new HexDecoder);
00812         HexEncoder output(new FileSink(cout));
00813         SecByteBlock plain(RC2Encryption::BLOCKSIZE), cipher(RC2Encryption::BLOCKSIZE), out(RC2Encryption::BLOCKSIZE), outplain(RC2Encryption::BLOCKSIZE);
00814         SecByteBlock key(128);
00815         bool pass=true, fail;
00816 
00817         while (valdata.MaxRetrievable())
00818         {
00819                 byte keyLen, effectiveLen;
00820 
00821                 valdata.Get(keyLen);
00822                 valdata.Get(effectiveLen);
00823                 valdata.Get(key, keyLen);
00824                 valdata.Get(plain, RC2Encryption::BLOCKSIZE);
00825                 valdata.Get(cipher, RC2Encryption::BLOCKSIZE);
00826 
00827                 apbt transE(new RC2Encryption(key, keyLen, effectiveLen));
00828                 transE->ProcessBlock(plain, out);
00829                 fail = memcmp(out, cipher, RC2Encryption::BLOCKSIZE) != 0;
00830 
00831                 apbt transD(new RC2Decryption(key, keyLen, effectiveLen));
00832                 transD->ProcessBlock(out, outplain);
00833                 fail=fail || memcmp(outplain, plain, RC2Encryption::BLOCKSIZE);
00834 
00835                 pass = pass && !fail;
00836 
00837                 cout << (fail ? "FAILED   " : "passed   ");
00838                 output.Put(key, keyLen);
00839                 cout << "   ";
00840                 output.Put(outplain, RC2Encryption::BLOCKSIZE);
00841                 cout << "   ";
00842                 output.Put(out, RC2Encryption::BLOCKSIZE);
00843                 cout << endl;
00844         }
00845         return pass;
00846 }
00847 
00848 bool ValidateARC4()
00849 {
00850         unsigned char Key0[] = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef };
00851         unsigned char Input0[]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
00852         unsigned char Output0[] = {0x75,0xb7,0x87,0x80,0x99,0xe0,0xc5,0x96};
00853 
00854         unsigned char Key1[]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
00855         unsigned char Input1[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
00856         unsigned char Output1[]={0x74,0x94,0xc2,0xe7,0x10,0x4b,0x08,0x79};
00857 
00858         unsigned char Key2[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
00859         unsigned char Input2[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
00860         unsigned char Output2[]={0xde,0x18,0x89,0x41,0xa3,0x37,0x5d,0x3a};
00861 
00862         unsigned char Key3[]={0xef,0x01,0x23,0x45};
00863         unsigned char Input3[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
00864         unsigned char Output3[]={0xd6,0xa1,0x41,0xa7,0xec,0x3c,0x38,0xdf,0xbd,0x61};
00865 
00866         unsigned char Key4[]={ 0x01,0x23,0x45,0x67,0x89,0xab, 0xcd,0xef };
00867         unsigned char Input4[] =
00868         {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00869         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00870         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00871         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00872         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00873         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00874         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00875         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00876         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00877         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00878         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00879         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00880         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00881         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00882         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00883         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00884         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00885         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00886         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00887         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00888         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00889         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00890         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00891         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00892         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00893         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00894         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00895         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00896         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00897         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00898         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00899         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00900         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00901         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00902         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00903         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00904         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00905         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00906         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00907         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00908         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00909         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00910         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00911         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00912         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00913         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00914         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00915         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00916         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00917         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00918         0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
00919         0x01};
00920         unsigned char Output4[]= {
00921         0x75,0x95,0xc3,0xe6,0x11,0x4a,0x09,0x78,0x0c,0x4a,0xd4,
00922         0x52,0x33,0x8e,0x1f,0xfd,0x9a,0x1b,0xe9,0x49,0x8f,
00923         0x81,0x3d,0x76,0x53,0x34,0x49,0xb6,0x77,0x8d,0xca,
00924         0xd8,0xc7,0x8a,0x8d,0x2b,0xa9,0xac,0x66,0x08,0x5d,
00925         0x0e,0x53,0xd5,0x9c,0x26,0xc2,0xd1,0xc4,0x90,0xc1,
00926         0xeb,0xbe,0x0c,0xe6,0x6d,0x1b,0x6b,0x1b,0x13,0xb6,
00927         0xb9,0x19,0xb8,0x47,0xc2,0x5a,0x91,0x44,0x7a,0x95,
00928         0xe7,0x5e,0x4e,0xf1,0x67,0x79,0xcd,0xe8,0xbf,0x0a,
00929         0x95,0x85,0x0e,0x32,0xaf,0x96,0x89,0x44,0x4f,0xd3,
00930         0x77,0x10,0x8f,0x98,0xfd,0xcb,0xd4,0xe7,0x26,0x56,
00931         0x75,0x00,0x99,0x0b,0xcc,0x7e,0x0c,0xa3,0xc4,0xaa,
00932         0xa3,0x04,0xa3,0x87,0xd2,0x0f,0x3b,0x8f,0xbb,0xcd,
00933         0x42,0xa1,0xbd,0x31,0x1d,0x7a,0x43,0x03,0xdd,0xa5,
00934         0xab,0x07,0x88,0x96,0xae,0x80,0xc1,0x8b,0x0a,0xf6,
00935         0x6d,0xff,0x31,0x96,0x16,0xeb,0x78,0x4e,0x49,0x5a,
00936         0xd2,0xce,0x90,0xd7,0xf7,0x72,0xa8,0x17,0x47,0xb6,
00937         0x5f,0x62,0x09,0x3b,0x1e,0x0d,0xb9,0xe5,0xba,0x53,
00938         0x2f,0xaf,0xec,0x47,0x50,0x83,0x23,0xe6,0x71,0x32,
00939         0x7d,0xf9,0x44,0x44,0x32,0xcb,0x73,0x67,0xce,0xc8,
00940         0x2f,0x5d,0x44,0xc0,0xd0,0x0b,0x67,0xd6,0x50,0xa0,
00941         0x75,0xcd,0x4b,0x70,0xde,0xdd,0x77,0xeb,0x9b,0x10,
00942         0x23,0x1b,0x6b,0x5b,0x74,0x13,0x47,0x39,0x6d,0x62,
00943         0x89,0x74,0x21,0xd4,0x3d,0xf9,0xb4,0x2e,0x44,0x6e,
00944         0x35,0x8e,0x9c,0x11,0xa9,0xb2,0x18,0x4e,0xcb,0xef,
00945         0x0c,0xd8,0xe7,0xa8,0x77,0xef,0x96,0x8f,0x13,0x90,
00946         0xec,0x9b,0x3d,0x35,0xa5,0x58,0x5c,0xb0,0x09,0x29,
00947         0x0e,0x2f,0xcd,0xe7,0xb5,0xec,0x66,0xd9,0x08,0x4b,
00948         0xe4,0x40,0x55,0xa6,0x19,0xd9,0xdd,0x7f,0xc3,0x16,
00949         0x6f,0x94,0x87,0xf7,0xcb,0x27,0x29,0x12,0x42,0x64,
00950         0x45,0x99,0x85,0x14,0xc1,0x5d,0x53,0xa1,0x8c,0x86,
00951         0x4c,0xe3,0xa2,0xb7,0x55,0x57,0x93,0x98,0x81,0x26,
00952         0x52,0x0e,0xac,0xf2,0xe3,0x06,0x6e,0x23,0x0c,0x91,
00953         0xbe,0xe4,0xdd,0x53,0x04,0xf5,0xfd,0x04,0x05,0xb3,
00954         0x5b,0xd9,0x9c,0x73,0x13,0x5d,0x3d,0x9b,0xc3,0x35,
00955         0xee,0x04,0x9e,0xf6,0x9b,0x38,0x67,0xbf,0x2d,0x7b,
00956         0xd1,0xea,0xa5,0x95,0xd8,0xbf,0xc0,0x06,0x6f,0xf8,
00957         0xd3,0x15,0x09,0xeb,0x0c,0x6c,0xaa,0x00,0x6c,0x80,
00958         0x7a,0x62,0x3e,0xf8,0x4c,0x3d,0x33,0xc1,0x95,0xd2,
00959         0x3e,0xe3,0x20,0xc4,0x0d,0xe0,0x55,0x81,0x57,0xc8,
00960         0x22,0xd4,0xb8,0xc5,0x69,0xd8,0x49,0xae,0xd5,0x9d,
00961         0x4e,0x0f,0xd7,0xf3,0x79,0x58,0x6b,0x4b,0x7f,0xf6,
00962         0x84,0xed,0x6a,0x18,0x9f,0x74,0x86,0xd4,0x9b,0x9c,
00963         0x4b,0xad,0x9b,0xa2,0x4b,0x96,0xab,0xf9,0x24,0x37,
00964         0x2c,0x8a,0x8f,0xff,0xb1,0x0d,0x55,0x35,0x49,0x00,
00965         0xa7,0x7a,0x3d,0xb5,0xf2,0x05,0xe1,0xb9,0x9f,0xcd,
00966         0x86,0x60,0x86,0x3a,0x15,0x9a,0xd4,0xab,0xe4,0x0f,
00967         0xa4,0x89,0x34,0x16,0x3d,0xdd,0xe5,0x42,0xa6,0x58,
00968         0x55,0x40,0xfd,0x68,0x3c,0xbf,0xd8,0xc0,0x0f,0x12,
00969         0x12,0x9a,0x28,0x4d,0xea,0xcc,0x4c,0xde,0xfe,0x58,
00970         0xbe,0x71,0x37,0x54,0x1c,0x04,0x71,0x26,0xc8,0xd4,
00971         0x9e,0x27,0x55,0xab,0x18,0x1a,0xb7,0xe9,0x40,0xb0,
00972         0xc0};
00973 
00974         // VC60 workaround: auto_ptr lacks reset()
00975         member_ptr<ARC4> arc4;
00976         bool pass=true, fail;
00977         int i;
00978 
00979         cout << "\nARC4 validation suite running...\n\n";
00980 
00981         arc4.reset(new ARC4(Key0, sizeof(Key0)));
00982         arc4->ProcessString(Input0, sizeof(Input0));
00983         fail = memcmp(Input0, Output0, sizeof(Input0)) != 0;
00984         cout << (fail ? "FAILED" : "passed") << "    Test 0" << endl;
00985         pass = pass && !fail;
00986 
00987         arc4.reset(new ARC4(Key1, sizeof(Key1)));
00988         arc4->ProcessString(Key1, Input1, sizeof(Key1));
00989         fail = memcmp(Output1, Key1, sizeof(Key1)) != 0;
00990         cout << (fail ? "FAILED" : "passed") << "    Test 1" << endl;
00991         pass = pass && !fail;
00992 
00993         arc4.reset(new ARC4(Key2, sizeof(Key2)));
00994         for (i=0, fail=false; i<sizeof(Input2); i++)
00995                 if (arc4->ProcessByte(Input2[i]) != Output2[i])
00996                         fail = true;
00997         cout << (fail ? "FAILED" : "passed") << "    Test 2" << endl;
00998         pass = pass && !fail;
00999 
01000         arc4.reset(new ARC4(Key3, sizeof(Key3)));
01001         for (i=0, fail=false; i<sizeof(Input3); i++)
01002                 if (arc4->ProcessByte(Input3[i]) != Output3[i])
01003                         fail = true;
01004         cout << (fail ? "FAILED" : "passed") << "    Test 3" << endl;
01005         pass = pass && !fail;
01006 
01007         arc4.reset(new ARC4(Key4, sizeof(Key4)));
01008         for (i=0, fail=false; i<sizeof(Input4); i++)
01009                 if (arc4->ProcessByte(Input4[i]) != Output4[i])
01010                         fail = true;
01011         cout << (fail ? "FAILED" : "passed") << "    Test 4" << endl;
01012         pass = pass && !fail;
01013 
01014         return pass;
01015 }
01016 
01017 bool ValidateRC5()
01018 {
01019         cout << "\nRC5 validation suite running...\n\n";
01020 
01021         FileSource valdata(PKGDATA("rc5val.dat"), true, new HexDecoder);
01022         return BlockTransformationTest(VariableRoundsCipherFactory<RC5Encryption, RC5Decryption>(16, 12), valdata);
01023 }
01024 
01025 bool ValidateRC6()
01026 {
01027         cout << "\nRC6 validation suite running...\n\n";
01028 
01029         FileSource valdata(PKGDATA("rc6val.dat"), true, new HexDecoder);
01030         bool pass = true;
01031         pass = BlockTransformationTest(FixedRoundsCipherFactory<RC6Encryption, RC6Decryption>(16), valdata, 2) && pass;
01032         pass = BlockTransformationTest(FixedRoundsCipherFactory<RC6Encryption, RC6Decryption>(24), valdata, 2) && pass;
01033         pass = BlockTransformationTest(FixedRoundsCipherFactory<RC6Encryption, RC6Decryption>(32), valdata, 2) && pass;
01034         return pass;
01035 }
01036 
01037 bool ValidateMARS()
01038 {
01039         cout << "\nMARS validation suite running...\n\n";
01040 
01041         FileSource valdata(PKGDATA("marsval.dat"), true, new HexDecoder);
01042         bool pass = true;
01043         pass = BlockTransformationTest(FixedRoundsCipherFactory<MARSEncryption, MARSDecryption>(16), valdata, 4) && pass;
01044         pass = BlockTransformationTest(FixedRoundsCipherFactory<MARSEncryption, MARSDecryption>(24), valdata, 3) && pass;
01045         pass = BlockTransformationTest(FixedRoundsCipherFactory<MARSEncryption, MARSDecryption>(32), valdata, 2) && pass;
01046         return pass;
01047 }
01048 
01049 bool ValidateRijndael()
01050 {
01051         cout << "\nRijndael validation suite running...\n\n";
01052 
01053         FileSource valdata(PKGDATA("rijndael.dat"), true, new HexDecoder);
01054         bool pass = true;
01055         pass = BlockTransformationTest(FixedRoundsCipherFactory<RijndaelEncryption, RijndaelDecryption>(16), valdata, 4) && pass;
01056         pass = BlockTransformationTest(FixedRoundsCipherFactory<RijndaelEncryption, RijndaelDecryption>(24), valdata, 3) && pass;
01057         pass = BlockTransformationTest(FixedRoundsCipherFactory<RijndaelEncryption, RijndaelDecryption>(32), valdata, 2) && pass;
01058         return pass;
01059 }
01060 
01061 bool ValidateTwofish()
01062 {
01063         cout << "\nTwofish validation suite running...\n\n";
01064 
01065         FileSource valdata(PKGDATA("twofishv.dat"), true, new HexDecoder);
01066         bool pass = true;
01067         pass = BlockTransformationTest(FixedRoundsCipherFactory<TwofishEncryption, TwofishDecryption>(16), valdata, 4) && pass;
01068         pass = BlockTransformationTest(FixedRoundsCipherFactory<TwofishEncryption, TwofishDecryption>(24), valdata, 3) && pass;
01069         pass = BlockTransformationTest(FixedRoundsCipherFactory<TwofishEncryption, TwofishDecryption>(32), valdata, 2) && pass;
01070         return pass;
01071 }
01072 
01073 bool ValidateSerpent()
01074 {
01075         cout << "\nSerpent validation suite running...\n\n";
01076 
01077         FileSource valdata(PKGDATA("serpentv.dat"), true, new HexDecoder);
01078         bool pass = true;
01079         pass = BlockTransformationTest(FixedRoundsCipherFactory<SerpentEncryption, SerpentDecryption>(16), valdata, 4) && pass;
01080         pass = BlockTransformationTest(FixedRoundsCipherFactory<SerpentEncryption, SerpentDecryption>(24), valdata, 3) && pass;
01081         pass = BlockTransformationTest(FixedRoundsCipherFactory<SerpentEncryption, SerpentDecryption>(32), valdata, 2) && pass;
01082         return pass;
01083 }
01084 
01085 bool ValidateBlowfish()
01086 {
01087         cout << "\nBlowfish validation suite running...\n\n";
01088 
01089         HexEncoder output(new FileSink(cout));
01090         char *key[]={"abcdefghijklmnopqrstuvwxyz", "Who is John Galt?"};
01091         byte *plain[]={(byte *)"BLOWFISH", (byte *)"\xfe\xdc\xba\x98\x76\x54\x32\x10"};
01092         byte *cipher[]={(byte *)"\x32\x4e\xd0\xfe\xf4\x13\xa2\x03", (byte *)"\xcc\x91\x73\x2b\x80\x22\xf6\x84"};
01093         byte out[8], outplain[8];
01094         bool pass=true, fail;
01095 
01096         for (int i=0; i<2; i++)
01097         {
01098                 ECB_Mode<Blowfish>::Encryption enc((byte *)key[i], strlen(key[i]));
01099                 enc.ProcessData(out, plain[i], 8);
01100                 fail = memcmp(out, cipher[i], 8) != 0;
01101 
01102                 ECB_Mode<Blowfish>::Decryption dec((byte *)key[i], strlen(key[i]));
01103                 dec.ProcessData(outplain, cipher[i], 8);
01104                 fail = fail || memcmp(outplain, plain[i], 8);
01105                 pass = pass && !fail;
01106 
01107                 cout << (fail ? "FAILED    " : "passed    ");
01108                 cout << '\"' << key[i] << '\"';
01109                 for (int j=0; j<(signed int)(30-strlen(key[i])); j++)
01110                         cout << ' ';
01111                 output.Put(outplain, 8);
01112                 cout << "  ";
01113                 output.Put(out, 8);
01114                 cout << endl;
01115         }
01116         return pass;
01117 }
01118 
01119 bool ValidateDiamond2()
01120 {
01121         cout << "\nDiamond2 validation suite running...\n\n";
01122 
01123         FileSource valdata(PKGDATA("diamond.dat"), true, new HexDecoder);
01124         HexEncoder output(new FileSink(cout));
01125         byte key[32], plain[16], cipher[16], out[16], outplain[16];
01126         byte blocksize, rounds, keysize;
01127         bool pass=true, fail;
01128         member_ptr<BlockTransformation> diamond;        // VC60 workaround: auto_ptr lacks reset
01129 
01130         while (valdata.MaxRetrievable() >= 1)
01131         {
01132                 valdata.Get(blocksize);
01133                 valdata.Get(rounds);
01134                 valdata.Get(keysize);
01135                 valdata.Get(key, keysize);
01136                 valdata.Get(plain, blocksize);
01137                 valdata.Get(cipher, blocksize);
01138 
01139                 if (blocksize==16)
01140                         diamond.reset(new Diamond2Encryption(key, keysize, rounds));
01141                 else
01142                         diamond.reset(new Diamond2LiteEncryption(key, keysize, rounds));
01143 
01144                 diamond->ProcessBlock(plain, out);
01145                 fail=memcmp(out, cipher, blocksize) != 0;
01146 
01147                 if (blocksize==16)
01148                         diamond.reset(new Diamond2Decryption(key, keysize, rounds));
01149                 else
01150                         diamond.reset(new Diamond2LiteDecryption(key, keysize, rounds));
01151 
01152                 diamond->ProcessBlock(out, outplain);
01153                 fail=fail || memcmp(outplain, plain, blocksize);
01154 
01155                 pass = pass && !fail;
01156 
01157                 cout << (fail ? "FAILED    " : "passed    ");
01158                 output.Put(key, keysize);
01159                 cout << "\n          ";
01160                 output.Put(outplain, blocksize);
01161                 cout << "  ";
01162                 output.Put(out, blocksize);
01163                 cout << endl;
01164         }
01165         return pass;
01166 }
01167 
01168 bool ValidateThreeWay()
01169 {
01170         cout << "\n3-WAY validation suite running...\n\n";
01171 
01172         FileSource valdata(PKGDATA("3wayval.dat"), true, new HexDecoder);
01173         return BlockTransformationTest(FixedRoundsCipherFactory<ThreeWayEncryption, ThreeWayDecryption>(), valdata);
01174 }
01175 
01176 bool ValidateGOST()
01177 {
01178         cout << "\nGOST validation suite running...\n\n";
01179 
01180         FileSource valdata(PKGDATA("gostval.dat"), true, new HexDecoder);
01181         return BlockTransformationTest(FixedRoundsCipherFactory<GOSTEncryption, GOSTDecryption>(), valdata);
01182 }
01183 
01184 bool ValidateSHARK()
01185 {
01186         cout << "\nSHARK validation suite running...\n\n";
01187 
01188 #ifdef WORD64_AVAILABLE
01189         FileSource valdata(PKGDATA("sharkval.dat"), true, new HexDecoder);
01190         return BlockTransformationTest(FixedRoundsCipherFactory<SHARKEncryption, SHARKDecryption>(), valdata);
01191 #else
01192         cout << "word64 not available, skipping SHARK validation." << endl;
01193         return true;
01194 #endif
01195 }
01196 
01197 bool ValidateCAST()
01198 {
01199         bool pass = true;
01200 
01201         cout << "\nCAST-128 validation suite running...\n\n";
01202 
01203         FileSource val128(PKGDATA("cast128v.dat"), true, new HexDecoder);
01204         pass = BlockTransformationTest(FixedRoundsCipherFactory<CAST128Encryption, CAST128Decryption>(16), val128, 1) && pass;
01205         pass = BlockTransformationTest(FixedRoundsCipherFactory<CAST128Encryption, CAST128Decryption>(10), val128, 1) && pass;
01206         pass = BlockTransformationTest(FixedRoundsCipherFactory<CAST128Encryption, CAST128Decryption>(5), val128, 1) && pass;
01207 
01208         cout << "\nCAST-256 validation suite running...\n\n";
01209 
01210         FileSource val256(PKGDATA("cast256v.dat"), true, new HexDecoder);
01211         pass = BlockTransformationTest(FixedRoundsCipherFactory<CAST256Encryption, CAST256Decryption>(16), val256, 1) && pass;
01212         pass = BlockTransformationTest(FixedRoundsCipherFactory<CAST256Encryption, CAST256Decryption>(24), val256, 1) && pass;
01213         pass = BlockTransformationTest(FixedRoundsCipherFactory<CAST256Encryption, CAST256Decryption>(32), val256, 1) && pass;
01214 
01215         return pass;
01216 }
01217 
01218 bool ValidateSquare()
01219 {
01220         cout << "\nSquare validation suite running...\n\n";
01221 
01222         FileSource valdata(PKGDATA("squareva.dat"), true, new HexDecoder);
01223         return BlockTransformationTest(FixedRoundsCipherFactory<SquareEncryption, SquareDecryption>(), valdata);
01224 }
01225 
01226 bool ValidateSKIPJACK()
01227 {
01228         cout << "\nSKIPJACK validation suite running...\n\n";
01229 
01230         FileSource valdata(PKGDATA("skipjack.dat"), true, new HexDecoder);
01231         return BlockTransformationTest(FixedRoundsCipherFactory<SKIPJACKEncryption, SKIPJACKDecryption>(), valdata);
01232 }
01233 
01234 bool ValidateSEAL()
01235 {
01236         byte input[] = {0x37,0xa0,0x05,0x95,0x9b,0x84,0xc4,0x9c,0xa4,0xbe,0x1e,0x05,0x06,0x73,0x53,0x0f,0x5f,0xb0,0x97,0xfd,0xf6,0xa1,0x3f,0xbd,0x6c,0x2c,0xde,0xcd,0x81,0xfd,0xee,0x7c};
01237         byte output[32];
01238         byte key[] = {0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x89, 0x98, 0xba, 0xdc, 0xfe, 0x10, 0x32, 0x54, 0x76, 0xc3, 0xd2, 0xe1, 0xf0};
01239         byte iv[] = {0x01, 0x35, 0x77, 0xaf};
01240 
01241         cout << "\nSEAL validation suite running...\n\n";
01242 
01243         SEAL<>::Encryption seal(key);
01244         seal.Resynchronize(iv);
01245         unsigned int size = sizeof(input);
01246         bool pass = true;
01247 
01248         memset(output, 1, size);
01249         seal.ProcessString(output, input, size);
01250         for (unsigned int i=0; i<size; i++)
01251                 if (output[i] != 0)
01252                         pass = false;
01253 
01254         seal.Seek(1);
01255         output[1] = seal.ProcessByte(output[1]);
01256         seal.ProcessString(output+2, size-2);
01257         pass = pass && memcmp(output+1, input+1, size-1) == 0;
01258 
01259         cout << (pass ? "passed" : "FAILED") << endl;
01260         return pass;
01261 }
01262 
01263 bool ValidateBaseCode()
01264 {
01265         bool pass = true, fail;
01266         byte data[255];
01267         for (unsigned int i=0; i<255; i++)
01268                 data[i] = i;
01269         const char *hexEncoded = 
01270 "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627"
01271 "28292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F"
01272 "505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071727374757677"
01273 "78797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F"
01274 "A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7"
01275 "C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF"
01276 "F0F1F2F3F4F5F6F7F8F9FAFBFCFDFE";
01277         const char *base64AndHexEncoded = 
01278 "41414543417751464267634943516F4C4441304F4478415245684D554652595847426B6147787764"
01279 "486838674953496A4A43556D4A7967704B6973734C5334764D4445794D7A51310A4E6A63344F546F"
01280 "375044302B50304242516B4E4552555A4853456C4B5330784E546B395155564A5456465657563168"
01281 "5A576C746358563566594746695932526C5A6D646F615770720A6247317562334278636E4E306458"
01282 "5A3365486C3665337839666E2B4167594B44684957476834694A696F754D6A5936506B4A47536B35"
01283 "53566C7065596D5A71626E4A32656E3643680A6F714F6B7061616E714B6D717136797472712B7773"
01284 "624B7A744C573274376935757275387662362F774D484377385446787366497963724C7A4D334F7A"
01285 "39445230745055316462580A324E6E6132397A6433742F6734654C6A354F586D352B6A7036757673"
01286 "3765377638504879382F5431397666342B6672372F50332B0A";
01287 
01288         cout << "\nBase64 and hex coding validation suite running...\n\n";
01289 
01290         fail = !TestFilter(HexEncoder().Ref(), data, 255, (const byte *)hexEncoded, strlen(hexEncoded));
01291         cout << (fail ? "FAILED    " : "passed    ");
01292         cout << "Hex Encoding\n";
01293         pass = pass && !fail;
01294 
01295         fail = !TestFilter(HexDecoder().Ref(), (const byte *)hexEncoded, strlen(hexEncoded), data, 255);
01296         cout << (fail ? "FAILED    " : "passed    ");
01297         cout << "Hex Decoding\n";
01298         pass = pass && !fail;
01299 
01300         fail = !TestFilter(Base64Encoder(new HexEncoder).Ref(), data, 255, (const byte *)base64AndHexEncoded, strlen(base64AndHexEncoded));
01301         cout << (fail ? "FAILED    " : "passed    ");
01302         cout << "Base64 Encoding\n";
01303         pass = pass && !fail;
01304 
01305         fail = !TestFilter(HexDecoder(new Base64Decoder).Ref(), (const byte *)base64AndHexEncoded, strlen(base64AndHexEncoded), data, 255);
01306         cout << (fail ? "FAILED    " : "passed    ");
01307         cout << "Base64 Decoding\n";
01308         pass = pass && !fail;
01309 
01310         return pass;
01311 }

Generated on Sun Mar 14 20:44:29 2004 for Crypto++ by doxygen 1.3.6-20040222