t_blowfish_crypto.cpp

Go to the documentation of this file.
00001 /*****************************************************************************\
00002 *                                                                             *
00003 *  Name   : test blowfish encryption                                          *
00004 *  Author : Chris Koeritz                                                     *
00005 *                                                                             *
00006 *  Purpose:                                                                   *
00007 *                                                                             *
00008 *    Exercises the BlowFish encryption methods in the crypto library.         *
00009 *                                                                             *
00010 *******************************************************************************
00011 * Copyright (c) 2005-$now By Author.  This program is free software; you can  *
00012 * redistribute it and/or modify it under the terms of the GNU General Public  *
00013 * License as published by the Free Software Foundation; either version 2 of   *
00014 * the License or (at your option) any later version.  This is online at:      *
00015 *     http://www.fsf.org/copyleft/gpl.html                                    *
00016 * Please send any updates to: fred@gruntose.com                               *
00017 \*****************************************************************************/
00018 
00019 #include <basis/byte_array.h>
00020 #include <basis/chaos.h>
00021 #include <basis/istring.h>
00022 #include <crypto/blowfish_crypto.h>
00023 #include <data_struct/unique_id.h>
00024 #include <mechanisms/ithread.h>
00025 #include <mechanisms/time_stamp.h>
00026 #include <mechanisms/thread_cabinet.h>
00027 #include <opsystem/application_shell.h>
00028 #include <data_struct/static_memory_gremlin.h>
00029 #include <textual/byte_format.h>
00030 #include <textual/string_manipulation.h>
00031 
00032 #include <stdio.h>
00033 #include <string.h>
00034 
00035 const int TEST_RUNS_PER_KEY = 20;  // encryption test cycles done on each key.
00036 
00037 const int THREAD_COUNT = 30;  // number of threads testing blowfish at once.
00038 
00039 const int ITERATIONS = 14;  // number of test runs in our testing threads.
00040 
00041 const int MAX_STRING = 1000000;  // largest chunk that we'll try to encrypt.
00042 
00044 
00045 class test_blowfish;  // forward.
00046 
00047 class blowfish_thread : public ithread
00048 {
00049 public:
00050   blowfish_thread(test_blowfish &parent) : ithread(), _parent(parent) {}
00051 
00052   void perform_activity(void *ptr);
00053     // try out random blowfish keys on randomly chosen chunks of the fodder.
00054 
00055 private:
00056   test_blowfish &_parent;
00057 };
00058 
00060 
00061 class test_blowfish : public application_shell
00062 {
00063 public:
00064   test_blowfish()
00065   : application_shell(static_class_name()),
00066    _fodder(string_manipulation::make_random_name
00067         (MAX_STRING + 1, MAX_STRING + 1)) {}
00068   virtual ~test_blowfish() {}
00069   IMPLEMENT_CLASS_NAME("test_blowfish");
00070 
00071   int execute();
00072 
00073 private:
00074   istring _fodder;  // chunks taken from this are encrypted and decrypted.
00075   time_stamp _program_start;  // the time at which we started executing.
00076   thread_cabinet _threads;  // manages our testing threads.
00077   friend class blowfish_thread;  // bad practice, but saves time in test app.
00078 };
00079 
00080 int test_blowfish::execute()
00081 {
00082   FUNCDEF("execute");
00083   int left = THREAD_COUNT;
00084   while (left--) {
00085     _threads.add_thread(new blowfish_thread(*this), true, NIL);
00086   }
00087 
00088   while (_threads.threads()) {
00089 printf("cleaning debris.\n");
00090     _threads.clean_debris();
00091     portable::sleep_ms(1000);
00092   }
00093 
00094   int duration = int(time_stamp().value() - _program_start.value());
00095   printf("duration for %d keys and encrypt/decrypt=%d ms,\n",
00096       ITERATIONS * TEST_RUNS_PER_KEY * THREAD_COUNT, duration);
00097   printf("that comes to %d ms per cycle.\n", int(double(duration
00098       / TEST_RUNS_PER_KEY / ITERATIONS / THREAD_COUNT)));
00099 
00100   return 0;
00101 }
00102 
00104 
00105 void blowfish_thread::perform_activity(void *)
00106 {
00107   FUNCDEF("perform_activity");
00108   int left = ITERATIONS;
00109   while (left--) {
00110     time_stamp key_start;
00111     blowfish_crypto bc(_parent.randomizer().inclusive
00112         (blowfish_crypto::minimum_key_size(),
00113          blowfish_crypto::maximum_key_size()));
00114     printf("%d bit key has:\n", bc.key_size());
00115     istring dumped_key = byte_format::text_dump(bc.get_key());
00116     printf("%s", dumped_key.s());
00117     int key_dur = int(time_stamp().value() - key_start.value());
00118 
00119     printf("  key generation took %d ms\n", key_dur);
00120 
00121     for (int i = 0; i < TEST_RUNS_PER_KEY; i++) {
00122       byte_array key;
00123       byte_array iv;
00124 
00125       int string_start = _parent.randomizer().inclusive(0, MAX_STRING - 1);
00126       int string_end = _parent.randomizer().inclusive(0, MAX_STRING - 1);
00127       flip_increasing(string_start, string_end);
00128       istring ranstring = _parent._fodder.substring(string_start, string_end);
00129 //printf("encoding %s\n", ranstring.s());
00130 //printf("string length encoded: %d\n", ranstring.length());
00131 
00132       byte_array target;
00133 
00134       time_stamp test_start;
00135       bool worked = bc.encrypt(byte_array(ranstring.length() + 1,
00136           (byte*)ranstring.s()), target);
00137       int enc_durat = int(time_stamp().value() - test_start.value());
00138       if (!worked)
00139         deadly_error("blowfish_test", "phase 1", "failed to encrypt the string!");
00140 
00141       byte_array recovered;
00142       test_start.reset();
00143       worked = bc.decrypt(target, recovered);
00144       int dec_durat = int(time_stamp().value() - test_start.value());
00145       if (!worked)
00146         deadly_error("blowfish_test", "phase 1", "failed to decrypt the string!");
00147 //    printf("original has %d chars, recovered has %d chars\n",
00148 //        ranstring.length(), recovered.length() - 1);
00149 
00150       istring teddro = (char *)recovered.observe();
00151 //printf("decoded %s\n", teddro.s());
00152 
00153       if (teddro != ranstring) {
00154         printf("error!\toriginal has %d chars, recovered has %d chars\n",
00155             ranstring.length(), recovered.length() - 1);
00156         printf("\tencoded %s\n", ranstring.s());
00157         printf("\tdecoded %s\n", teddro.s());
00158         deadly_error(class_name(), func, "failed to regenerate the "
00159             "original string!");
00160       }
00161 
00162       printf("  encrypt %d ms, decrypt %d ms, data %d bytes\n",
00163            enc_durat, dec_durat, string_end - string_start + 1);
00164       portable::sleep_ms(0);  // take a rest.
00165     }
00166     portable::sleep_ms(0);  // take a rest.
00167   }
00168 }
00169 
00170 HOOPLE_MAIN(test_blowfish, )
00171 

Generated on Fri Nov 28 04:29:36 2008 for HOOPLE Libraries by  doxygen 1.5.1