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 }

Generated on Tue Jul 8 23:34:27 2003 for Crypto++ by doxygen 1.3.2