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