diff options
559 files changed, 13364 insertions, 6939 deletions
diff --git a/.mtn-ignore b/.mtn-ignore index 63acd11e3..9472cff88 100644 --- a/.mtn-ignore +++ b/.mtn-ignore @@ -1,4 +1,4 @@ -^Makefile$ +^Makefile.*$ ^botan-config$ ^botan.pc$ ^build$ @@ -22,3 +22,6 @@ callgrind.out.* ^doc/.*\.log$ ^doc/.*\.toc$ ^doc/examples/.*\.pem$ +^src/wrap/perl-xs/Botan.(bs|c)$ +^src/wrap/perl-xs/Makefile(\.old)?$ +^src/wrap/perl-xs/.*blib$ diff --git a/checks/algos.cpp b/checks/algos.cpp deleted file mode 100644 index 2edaaf14c..000000000 --- a/checks/algos.cpp +++ /dev/null @@ -1,105 +0,0 @@ - -#include <botan/botan.h> -#include <string> -using namespace Botan; - -#include "common.h" - -std::vector<algorithm> get_algos() - { - std::vector<algorithm> algos; - - algos.push_back(algorithm("Block Cipher", "AES-128", "AES-128/ECB", 16)); - algos.push_back(algorithm("Block Cipher", "AES-192", "AES-192/ECB", 24)); - algos.push_back(algorithm("Block Cipher", "AES-256", "AES-256/ECB", 32)); - algos.push_back(algorithm("Block Cipher", "Blowfish", "Blowfish/ECB", 32)); - algos.push_back(algorithm("Block Cipher", "CAST-128", "CAST-128/ECB", 16)); - algos.push_back(algorithm("Block Cipher", "CAST-256", "CAST-256/ECB", 32)); - algos.push_back(algorithm("Block Cipher", "DES", "DES/ECB", 8)); - algos.push_back(algorithm("Block Cipher", "DESX", "DESX/ECB", 24)); - algos.push_back(algorithm("Block Cipher", "TripleDES", - "TripleDES/ECB", 24)); - algos.push_back(algorithm("Block Cipher", "GOST", "GOST/ECB", 32)); - algos.push_back(algorithm("Block Cipher", "IDEA", "IDEA/ECB", 16)); - algos.push_back(algorithm("Block Cipher", "KASUMI", "KASUMI/ECB", 16)); - - algos.push_back(algorithm("Block Cipher", - "Lion", - "Lion(SHA-256,Turing,8192)/ECB", 32)); - - algos.push_back(algorithm("Block Cipher", "Luby-Rackoff(SHA-512)", - "Luby-Rackoff(SHA-512)/ECB", 16)); - - algos.push_back(algorithm("Block Cipher", "MARS", "MARS/ECB", 32)); - algos.push_back(algorithm("Block Cipher", "MISTY1", "MISTY1/ECB", 16)); - algos.push_back(algorithm("Block Cipher", "Noekeon", "Noekeon/ECB", 16)); - algos.push_back(algorithm("Block Cipher", "RC2", "RC2/ECB", 16)); - algos.push_back(algorithm("Block Cipher", "RC5(12)", "RC5(12)/ECB", 16)); - algos.push_back(algorithm("Block Cipher", "RC5(16)", "RC5(16)/ECB", 16)); - algos.push_back(algorithm("Block Cipher", "RC6", "RC6/ECB", 32)); - algos.push_back(algorithm("Block Cipher", "SAFER-SK(10)", - "SAFER-SK(10)/ECB", 16)); - algos.push_back(algorithm("Block Cipher", "SEED", "SEED/ECB", 16)); - algos.push_back(algorithm("Block Cipher", "Serpent", "Serpent/ECB", 32)); - algos.push_back(algorithm("Block Cipher", "Skipjack", "Skipjack/ECB", 10)); - algos.push_back(algorithm("Block Cipher", "Square", "Square/ECB", 16)); - algos.push_back(algorithm("Block Cipher", "TEA", "TEA/ECB", 16)); - algos.push_back(algorithm("Block Cipher", "Twofish", "Twofish/ECB", 32)); - algos.push_back(algorithm("Block Cipher", "XTEA", "XTEA/ECB", 16)); - - algos.push_back(algorithm("Cipher Mode", "DES/CBC/PKCS7", 8, 8)); - algos.push_back(algorithm("Cipher Mode", "TripleDES/CBC/PKCS7", 24, 8)); - - algos.push_back(algorithm("Cipher Mode", "AES-128/CBC/PKCS7", 16, 16)); - algos.push_back(algorithm("Cipher Mode", "AES-128/CBC/CTS", 16, 16)); - algos.push_back(algorithm("Cipher Mode", "AES-128/CFB(128)", 16, 16)); - algos.push_back(algorithm("Cipher Mode", "AES-128/CFB(64)", 16, 16)); - algos.push_back(algorithm("Cipher Mode", "AES-128/CFB(32)", 16, 16)); - algos.push_back(algorithm("Cipher Mode", "AES-128/CFB(16)", 16, 16)); - algos.push_back(algorithm("Cipher Mode", "AES-128/CFB(8)", 16, 16)); - algos.push_back(algorithm("Cipher Mode", "AES-128/OFB", 16, 16)); - algos.push_back(algorithm("Cipher Mode", "AES-128/CTR", - "AES-128/CTR-BE", 16, 16)); - algos.push_back(algorithm("Cipher Mode", "AES-128/EAX", 16, 16)); - algos.push_back(algorithm("Cipher Mode", "AES-128/XTS", 32, 16)); - - algos.push_back(algorithm("Stream Cipher", "ARC4", 16)); - algos.push_back(algorithm("Stream Cipher", "Salsa20", 32)); - algos.push_back(algorithm("Stream Cipher", "Turing", 32)); - algos.push_back(algorithm("Stream Cipher", "WiderWake4+1", - "WiderWake4+1-BE", 16, 8)); - - algos.push_back(algorithm("Hash", "Adler32")); - algos.push_back(algorithm("Hash", "CRC24")); - algos.push_back(algorithm("Hash", "CRC32")); - algos.push_back(algorithm("Hash", "FORK-256")); - algos.push_back(algorithm("Hash", "GOST-34.11")); - algos.push_back(algorithm("Hash", "HAS-160")); - algos.push_back(algorithm("Hash", "HAS-V")); - algos.push_back(algorithm("Hash", "MD2")); - algos.push_back(algorithm("Hash", "MD4")); - algos.push_back(algorithm("Hash", "MD5")); - algos.push_back(algorithm("Hash", "RIPEMD-128")); - algos.push_back(algorithm("Hash", "RIPEMD-160")); - algos.push_back(algorithm("Hash", "SHA-160")); - algos.push_back(algorithm("Hash", "SHA-256")); - algos.push_back(algorithm("Hash", "SHA-384")); - algos.push_back(algorithm("Hash", "SHA-512")); - algos.push_back(algorithm("Hash", "Skein-512")); - algos.push_back(algorithm("Hash", "Tiger")); - algos.push_back(algorithm("Hash", "Whirlpool")); - - algos.push_back(algorithm("MAC", "CMAC(AES-128)", 16)); - algos.push_back(algorithm("MAC", "HMAC(SHA-1)", 16)); - algos.push_back(algorithm("MAC", "X9.19-MAC", 16)); - - algos.push_back(algorithm("RNG", "AutoSeeded", 4096)); - algos.push_back(algorithm("RNG", "HMAC_RNG", 4096)); - algos.push_back(algorithm("RNG", "Randpool", 4096)); - algos.push_back(algorithm("RNG", "X9.31-RNG", 4096)); - - algos.push_back(algorithm("Codec", "Base64_Encode")); - algos.push_back(algorithm("Codec", "Base64_Decode")); - - return algos; - } diff --git a/checks/bench.cpp b/checks/bench.cpp index 6df7319c0..f821e04e3 100644 --- a/checks/bench.cpp +++ b/checks/bench.cpp @@ -1,198 +1,230 @@ #include <iostream> #include <iomanip> -#include <cmath> -#include <string> -#include <exception> +#include <botan/benchmark.h> +#include <botan/libstate.h> +#include <botan/pipe.h> #include <botan/filters.h> -using Botan::byte; -using Botan::u64bit; +#include <botan/engine.h> +#include <botan/parsing.h> +#include <botan/symkey.h> #include "common.h" -#include "timer.h" #include "bench.h" -/* Discard output to reduce overhead */ -struct BitBucket : public Botan::Filter - { - void write(const byte[], u32bit) {} - }; - -Botan::Filter* lookup(const std::string&, - const std::vector<std::string>&, - const std::string& = "All"); - namespace { -double bench_filter(std::string name, Botan::Filter* filter, - Botan::RandomNumberGenerator& rng, - bool html, double seconds) +const std::string algos[] = { + + /* Block ciphers */ + "AES-128", + "AES-192", + "AES-256", + "Blowfish", + "CAST-128", + "CAST-256", + "DES", + "DESX", + "GOST", + "IDEA", + "KASUMI", + "Lion(SHA-256,Turing,8192)", + "Luby-Rackoff(SHA-512)", + "MARS", + "MISTY1", + "Noekeon", + "RC2", + "RC5(12)", + "RC5(16)", + "RC6", + "SAFER-SK(10)", + "SEED", + "Serpent", + "Skipjack", + "Square", + "TEA", + "TripleDES", + "Twofish", + "XTEA", + + /* Cipher modes */ + "TripleDES/CBC/PKCS7", + "TripleDES/CBC/CTS", + "TripleDES/CTR-BE", + "TripleDES/EAX", + "TripleDES/OFB", + "TripleDES/CFB(64)", + "TripleDES/CFB(32)", + "TripleDES/CFB(16)", + "TripleDES/CFB(8)", + + "AES-128/CBC/PKCS7", + "AES-128/CBC/CTS", + "AES-128/CTR-BE", + "AES-128/EAX", + "AES-128/OFB", + "AES-128/XTS", + "AES-128/CFB(128)", + "AES-128/CFB(64)", + "AES-128/CFB(32)", + "AES-128/CFB(16)", + "AES-128/CFB(8)", + + "Serpent/CBC/PKCS7", + "Serpent/CBC/CTS", + "Serpent/CTR-BE", + "Serpent/EAX", + "Serpent/OFB", + "Serpent/XTS", + "Serpent/CFB(128)", + "Serpent/CFB(64)", + "Serpent/CFB(32)", + "Serpent/CFB(16)", + "Serpent/CFB(8)", + + /* Stream ciphers */ + "ARC4", + "Salsa20", + "Turing", + "WiderWake4+1-BE", + + /* Checksums */ + "Adler32", + "CRC24", + "CRC32", + + /* Hashes */ + "BMW-512", + "FORK-256", + "GOST-34.11", + "HAS-160", + "MD2", + "MD4", + "MD5", + "RIPEMD-128", + "RIPEMD-160", + "SHA-160", + "SHA-256", + "SHA-384", + "SHA-512", + "Skein-512", + "Tiger", + "Whirlpool", + + /* MACs */ + "CMAC(AES-128)", + "HMAC(SHA-1)", + "X9.19-MAC", + "", +}; + +void report_results(const std::string& algo, + const std::map<std::string, double>& speeds) { - Botan::Pipe pipe(filter, new BitBucket); - - std::vector<byte> buf(128 * 1024); - rng.randomize(&buf[0], buf.size()); - - pipe.start_msg(); - - Timer timer(name, buf.size()); + // invert, showing fastest impl first + std::map<double, std::string> results; - while(timer.seconds() < seconds) + for(std::map<std::string, double>::const_iterator i = speeds.begin(); + i != speeds.end(); ++i) { - timer.start(); - pipe.write(&buf[0], buf.size()); - timer.stop(); + // Speeds might collide, tweak slightly to handle this + if(results[i->second] == "") + results[i->second] = i->first; + else + results[i->second - .01] = i->first; } - pipe.end_msg(); + std::cout << algo; - double bytes_per_sec = timer.events() / timer.seconds(); - double mbytes_per_sec = bytes_per_sec / (1024.0 * 1024.0); - - std::cout.setf(std::ios::fixed, std::ios::floatfield); - std::cout.precision(2); - if(html) - { - if(name.find("<") != std::string::npos) - name.replace(name.find("<"), 1, "<"); - if(name.find(">") != std::string::npos) - name.replace(name.find(">"), 1, ">"); - std::cout << " <TR><TH>" << name - << std::string(25 - name.length(), ' ') << " <TH>"; - std::cout.width(6); - std::cout << mbytes_per_sec << std::endl; - } - else + for(std::map<double, std::string>::const_reverse_iterator i = results.rbegin(); + i != results.rend(); ++i) { - std::cout << name << ": " << std::string(25 - name.length(), ' '); - std::cout.width(6); - std::cout << mbytes_per_sec << " MiB/sec" << std::endl; + std::cout << " [" << i->second << "] " + << std::fixed << std::setprecision(2) << i->first; } - return (mbytes_per_sec); + std::cout << "\n"; } -double bench(const std::string& name, const std::string& filtername, bool html, - double seconds, u32bit keylen, u32bit ivlen, - Botan::RandomNumberGenerator& rng) +} + +bool bench_algo(const std::string& algo, + Botan::RandomNumberGenerator& rng, + double seconds) { - std::vector<std::string> params; + Botan::Default_Benchmark_Timer timer; + Botan::Algorithm_Factory& af = Botan::global_state().algorithm_factory(); - Botan::SecureVector<byte> key(keylen); - rng.randomize(key, key.size()); - params.push_back(hex_encode(key, key.size())); + u32bit milliseconds = static_cast<u32bit>(seconds * 1000); - //params.push_back(std::string(int(2*keylen), 'A')); - params.push_back(std::string(int(2* ivlen), 'A')); + std::map<std::string, double> speeds = + algorithm_benchmark(algo, milliseconds, timer, rng, af); - Botan::Filter* filter = lookup(filtername, params); + if(speeds.empty()) // maybe a cipher mode, then? + { + Botan::Algorithm_Factory::Engine_Iterator i(af); - if(filter) - return bench_filter(name, filter, rng, html, seconds); - return 0; - } + std::vector<std::string> algo_parts = Botan::split_on(algo, '/'); -} + if(algo_parts.size() < 2) // not a cipher mode + return false; -void benchmark(const std::string& what, - Botan::RandomNumberGenerator& rng, - bool html, double seconds) - { - try { - if(html) - { - std::cout << "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD " - << "HTML 4.0 Transitional//EN\">\n" - << "<HTML>\n\n" - << "<TITLE>Botan Benchmarks</TITLE>\n\n" - << "<BODY>\n\n" - << "<P><TABLE BORDER CELLSPACING=1>\n" - << "<THEAD>\n" - << "<TR><TH>Algorithm " - << "<TH>Mib / second\n" - << "<TBODY>\n"; - } + std::string cipher = algo_parts[0]; - double sum = 0; - u32bit how_many = 0; + u32bit cipher_keylen = + af.prototype_block_cipher(cipher)->MAXIMUM_KEYLENGTH; + u32bit cipher_ivlen = + af.prototype_block_cipher(cipher)->BLOCK_SIZE; - std::vector<algorithm> algos = get_algos(); + if(algo_parts[1] == "XTS") + cipher_keylen *= 2; // hack! - for(u32bit j = 0; j != algos.size(); j++) - if(what == "All" || what == algos[j].type) - { - double speed = bench(algos[j].name, algos[j].filtername, - html, seconds, algos[j].keylen, - algos[j].ivlen, rng); - if(speed > .00001) /* log(0) == -inf -> messed up average */ - sum += std::log(speed); - how_many++; - } + std::vector<byte> buf(16 * 1024); + rng.randomize(&buf[0], buf.size()); - if(html) - std::cout << "</TABLE>\n\n"; + while(Botan::Engine* engine = i.next()) + { + u64bit nanoseconds_max = static_cast<u64bit>(seconds * 1000000000.0); - double average = std::exp(sum / static_cast<double>(how_many)); + Botan::Keyed_Filter* filt = + engine->get_cipher(algo, Botan::ENCRYPTION, af); - if(what == "All" && html) - std::cout << "\n<P>Overall speed average: " << average - << "\n\n"; - else if(what == "All") - std::cout << "\nOverall speed average: " << average - << std::endl; + if(!filt) + continue; - if(html) std::cout << "</BODY></HTML>\n"; - } - catch(Botan::Exception& e) - { - std::cout << "Botan exception caught: " << e.what() << std::endl; - return; - } - catch(std::exception& e) - { - std::cout << "Standard library exception caught: " << e.what() - << std::endl; - return; - } - catch(...) - { - std::cout << "Unknown exception caught." << std::endl; - return; - } - } + filt->set_key(Botan::SymmetricKey(&buf[0], cipher_keylen)); + filt->set_iv(Botan::InitializationVector(&buf[0], cipher_ivlen)); -u32bit bench_algo(const std::string& name, - Botan::RandomNumberGenerator& rng, - double seconds) - { - try { - std::vector<algorithm> algos = get_algos(); + Botan::Pipe pipe(filt, new Botan::BitBucket); + pipe.start_msg(); - for(u32bit j = 0; j != algos.size(); j++) - { - if(algos[j].name == name) + const u64bit start = timer.clock(); + u64bit nanoseconds_used = 0; + u64bit reps = 0; + + while(nanoseconds_used < nanoseconds_max) { - bench(algos[j].name, algos[j].filtername, false, seconds, - algos[j].keylen, algos[j].ivlen, rng); - return 1; + pipe.write(&buf[0], buf.size()); + ++reps; + nanoseconds_used = timer.clock() - start; } + + double mbytes_per_second = + (953.67 * (buf.size() * reps)) / nanoseconds_used; + + speeds[engine->provider_name()] = mbytes_per_second; } - return 0; - } - catch(Botan::Exception& e) - { - std::cout << "Botan exception caught: " << e.what() << std::endl; - return 0; - } - catch(std::exception& e) - { - std::cout << "Standard library exception caught: " << e.what() - << std::endl; - return 0; - } - catch(...) - { - std::cout << "Unknown exception caught." << std::endl; - return 0; } + + if(!speeds.empty()) + report_results(algo, speeds); + + return !speeds.empty(); + } + +void benchmark(Botan::RandomNumberGenerator& rng, + double seconds) + { + for(u32bit i = 0; algos[i] != ""; ++i) + bench_algo(algos[i], rng, seconds); } diff --git a/checks/bench.h b/checks/bench.h index 07d67e0d1..835db0101 100644 --- a/checks/bench.h +++ b/checks/bench.h @@ -1,37 +1,18 @@ -#ifndef BOTAN_BENCHMARCH_H__ -#define BOTAN_BENCHMARCH_H__ +#ifndef BOTAN_CHECK_BENCHMARK_H__ +#define BOTAN_CHECK_BENCHMARK_H__ #include <botan/rng.h> #include <string> -#include <map> -#include <set> -#include "timer.h" -#include <iostream> +void benchmark(Botan::RandomNumberGenerator& rng, + double seconds); -class Benchmark_Report - { - public: - void report(const std::string& name, Timer timer) - { - std::cout << name << " " << timer << std::endl; - data[name].insert(timer); - } - - private: - std::map<std::string, std::set<Timer> > data; - }; - - -void benchmark(const std::string&, Botan::RandomNumberGenerator&, - bool html, double seconds); +bool bench_algo(const std::string& algo_name, + Botan::RandomNumberGenerator& rng, + double seconds); void bench_pk(Botan::RandomNumberGenerator&, - const std::string&, bool html, double seconds); - -u32bit bench_algo(const std::string&, - Botan::RandomNumberGenerator&, - double); + const std::string&, double seconds); #endif diff --git a/checks/check.cpp b/checks/check.cpp index 678cf4b09..b460d34f7 100644 --- a/checks/check.cpp +++ b/checks/check.cpp @@ -94,7 +94,7 @@ int main(int argc, char* argv[]) { try { - OptionParser opts("help|html|test|validate|" + OptionParser opts("help|test|validate|" "benchmark|bench-type=|bench-algo=|seconds="); opts.parse(argv); @@ -111,9 +111,6 @@ int main(int argc, char* argv[]) << "Options:\n" << " --test || --validate: Run tests (do this at least once)\n" << " --benchmark: Benchmark everything\n" - << " --bench-type={block,mode,stream,hash,mac,rng,pk}:\n" - << " Benchmark only algorithms of a particular type\n" - << " --html: Produce HTML output for benchmarks\n" << " --seconds=n: Benchmark for n seconds\n" << " --init=<str>: Pass <str> to the library\n" << " --help: Print this message\n"; @@ -128,7 +125,7 @@ int main(int argc, char* argv[]) opts.is_set("benchmark") || opts.is_set("bench-type")) { - double seconds = 5; + double seconds = 2; if(opts.is_set("seconds")) { @@ -140,11 +137,9 @@ int main(int argc, char* argv[]) } } - const bool html = opts.is_set("html"); - if(opts.is_set("benchmark")) { - benchmark("All", rng, html, seconds); + benchmark(rng, seconds); } else if(opts.is_set("bench-algo")) { @@ -154,34 +149,10 @@ int main(int argc, char* argv[]) for(u32bit j = 0; j != algs.size(); j++) { const std::string alg = algs[j]; - u32bit found = bench_algo(alg, rng, seconds); - if(!found) // maybe it's a PK algorithm - bench_pk(rng, alg, html, seconds); + if(!bench_algo(alg, rng, seconds)) // maybe it's a PK algorithm + bench_pk(rng, alg, seconds); } } - else if(opts.is_set("bench-type")) - { - const std::string type = opts.value("bench-type"); - - if(type == "all") - benchmark("All", rng, html, seconds); - else if(type == "block") - benchmark("Block Cipher", rng, html, seconds); - else if(type == "stream") - benchmark("Stream Cipher", rng, html, seconds); - else if(type == "hash") - benchmark("Hash", rng, html, seconds); - else if(type == "mode") - benchmark("Cipher Mode", rng, html, seconds); - else if(type == "mac") - benchmark("MAC", rng, html, seconds); - else if(type == "rng") - benchmark("RNG", rng, html, seconds); - else if(type == "pk") - bench_pk(rng, "All", html, seconds); - else - std::cerr << "Unknown --bench-type " << type << "\n"; - } } } catch(std::exception& e) diff --git a/checks/clock.cpp b/checks/clock.cpp deleted file mode 100644 index e5565ff9c..000000000 --- a/checks/clock.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include "timer.h" -#include <botan/build.h> - -/************************************************* -* Platform specific settings for which clock type to use -*/ - -#if !defined(USE_CLOCK_GETTIME) && defined(BOTAN_TARGET_OS_IS_LINUX) - #define USE_GETTIMEOFDAY 1 -#endif - -#if !defined(USE_GETTIMEOFDAY) && defined(BOTAN_TARGET_OS_IS_FREEBSD) - #define USE_GETTIMEOFDAY 1 -#endif - -/************************************************* - Set the default, which is clock -*/ -#ifndef USE_CLOCK_GETTIME - #define USE_CLOCK_GETTIME 0 -#endif - -#ifndef USE_GETTIMEOFDAY - #define USE_GETTIMEOFDAY 0 -#endif - -#ifndef USE_TIMES - #define USE_TIMES 0 -#endif - -/* the default: ANSI/ISO clock */ -#ifndef USE_CLOCK - #define USE_CLOCK 1 -#endif - -#if USE_CLOCK_GETTIME - #include <time.h> -#elif USE_GETTIMEOFDAY - #include <sys/time.h> -#elif USE_TIMES - #include <sys/times.h> - #include <unistd.h> -#elif USE_CLOCK - #include <time.h> -#endif - -/* The implementation: */ -u64bit Timer::get_clock() - { - static const u64bit billion = 1000000000; - -#if USE_CLOCK_GETTIME - - struct timespec tv; - clock_gettime(CLOCK_REALTIME, &tv); - return (billion * tv.tv_sec + tv.tv_nsec); - -#elif USE_GETTIMEOFDAY - - struct timeval tv; - gettimeofday(&tv, 0); - return (billion * tv.tv_sec + 1000 * tv.tv_usec); - -#elif USE_TIMES - - struct tms tms; - times(&tms); - - static const u64bit clocks_to_nanoseconds = - (billion / sysconf(_SC_CLK_TCK)); - - return (tms.tms_utime * clocks_to_nanoseconds); - -#elif USE_CLOCK - - static const u64bit clocks_to_nanoseconds = - (billion / CLOCKS_PER_SEC); - - return clock() * clocks_to_nanoseconds; - -#endif - } diff --git a/checks/common.h b/checks/common.h index fa41882ee..5b8f0a5d0 100644 --- a/checks/common.h +++ b/checks/common.h @@ -14,20 +14,7 @@ using Botan::byte; using Botan::u32bit; - -struct algorithm - { - algorithm(const char* t, const char* n, - u32bit k = 0, u32bit i = 0) : - type(t), name(n), filtername(n), keylen(k), ivlen(i) {} - algorithm(const char* t, const char* n, - const char* f, u32bit k = 0, u32bit i = 0) : - type(t), name(n), filtername(f), keylen(k), ivlen(i) {} - std::string type, name, filtername; - u32bit keylen, ivlen, weight; - }; - -std::vector<algorithm> get_algos(); +using Botan::u64bit; void strip_comments(std::string& line); void strip_newlines(std::string& line); diff --git a/checks/cvc_tests.cpp b/checks/cvc_tests.cpp index 792e9c58d..d62099b6e 100644 --- a/checks/cvc_tests.cpp +++ b/checks/cvc_tests.cpp @@ -27,7 +27,7 @@ #include <botan/look_pk.h> #include <botan/cvc_self.h> #include <botan/cvc_cert.h> -#include <botan/util.h> +#include <botan/timer.h> #include <botan/cvc_ado.h> #define TEST_DATA_DIR "checks/ecc_testdata" diff --git a/checks/dolook.cpp b/checks/dolook.cpp index 0c20448af..b64c5a5a3 100644 --- a/checks/dolook.cpp +++ b/checks/dolook.cpp @@ -4,6 +4,11 @@ #include <botan/lookup.h> #include <botan/filters.h> #include <botan/libstate.h> +#include <botan/hmac.h> +#include <botan/aes.h> +#include <botan/sha2_32.h> +#include <botan/sha2_64.h> +#include <botan/parsing.h> #ifdef BOTAN_HAS_COMPRESSOR_BZIP2 #include <botan/bzip2.h> @@ -17,84 +22,203 @@ #include <botan/zlib.h> #endif +#if defined(BOTAN_HAS_RANDPOOL) + #include <botan/randpool.h> +#endif + +#if defined(BOTAN_HAS_HMAC_RNG) + #include <botan/hmac_rng.h> +#endif + +#if defined(BOTAN_HAS_X931_RNG) + #include <botan/x931_rng.h> + #include <botan/des.h> +#endif + +#if defined(BOTAN_HAS_AUTO_SEEDING_RNG) + #include <botan/auto_rng.h> +#endif + using namespace Botan; #include "common.h" -Filter* lookup(const std::string& algname, - const std::vector<std::string>& params, - const std::string& section) +/* A weird little hack to fit S2K algorithms into the validation suite + You probably wouldn't ever want to actually use the S2K algorithms like + this, the raw S2K interface is more convenient for actually using them +*/ +class S2K_Filter : public Filter { - std::string key = params[0]; - std::string iv = params[1]; - Filter* filter = 0; - - // The order of the lookup has to change based on how the names are - // formatted and parsed. - filter = lookup_kdf(algname, key, iv); - if(filter) return filter; + public: + void write(const byte in[], u32bit len) + { passphrase += std::string(reinterpret_cast<const char*>(in), len); } + void end_msg() + { + s2k->change_salt(salt, salt.size()); + s2k->set_iterations(iterations); + SymmetricKey x = s2k->derive_key(outlen, passphrase); + send(x.bits_of()); + } + S2K_Filter(S2K* algo, const SymmetricKey& s, u32bit o, u32bit i) + { + s2k = algo; + outlen = o; + iterations = i; + salt = s.bits_of(); - if(section == "Cipher Modes (Decryption)") - filter = lookup_cipher(algname, key, iv, false); - else - filter = lookup_cipher(algname, key, iv, true); - if(filter) return filter; + } + ~S2K_Filter() { delete s2k; } + private: + std::string passphrase; + S2K* s2k; + SecureVector<byte> salt; + u32bit outlen, iterations; + }; - filter = lookup_block(algname, key); - if(filter) return filter; - - filter = lookup_rng(algname, key); - if(filter) return filter; +/* Not too useful generally; just dumps random bits for benchmarking */ +class RNG_Filter : public Filter + { + public: + void write(const byte[], u32bit); - filter = lookup_encoder(algname); - if(filter) return filter; + RNG_Filter(RandomNumberGenerator* r) : rng(r) {} + ~RNG_Filter() { delete rng; } + private: + RandomNumberGenerator* rng; + }; - filter = lookup_hash(algname); - if(filter) return filter; +class KDF_Filter : public Filter + { + public: + void write(const byte in[], u32bit len) + { secret.append(in, len); } + void end_msg() + { + SymmetricKey x = kdf->derive_key(outlen, + secret, secret.size(), + salt, salt.size()); + send(x.bits_of(), x.length()); + } + KDF_Filter(KDF* algo, const SymmetricKey& s, u32bit o) + { + kdf = algo; + outlen = o; + salt = s.bits_of(); + } + ~KDF_Filter() { delete kdf; } + private: + SecureVector<byte> secret; + SecureVector<byte> salt; + KDF* kdf; + u32bit outlen; + }; - filter = lookup_mac(algname, key); - if(filter) return filter; +Filter* lookup_s2k(const std::string& algname, + const std::vector<std::string>& params) + { + S2K* s2k = 0; - filter = lookup_s2k(algname, params); - if(filter) return filter; + try { + s2k = get_s2k(algname); + } + catch(...) { } + if(s2k) + return new S2K_Filter(s2k, params[0], to_u32bit(params[1]), + to_u32bit(params[2])); return 0; } -Filter* lookup_hash(const std::string& algname) +void RNG_Filter::write(const byte[], u32bit length) { - Filter* hash = 0; - - try { - hash = new Hash_Filter(algname); + if(length) + { + SecureVector<byte> out(length); + rng->randomize(out, out.size()); + send(out); } - catch(Algorithm_Not_Found) {} - - return hash; } -Filter* lookup_mac(const std::string& algname, const std::string& key) +Filter* lookup_rng(const std::string& algname, + const std::string& key) { - Filter* mac = 0; - try { - mac = new MAC_Filter(algname, key); + RandomNumberGenerator* prng = 0; + +#if defined(BOTAN_HAS_AUTO_SEEDING_RNG) + if(algname == "AutoSeeded") + prng = new AutoSeeded_RNG; +#endif + +#if defined(BOTAN_HAS_X931_RNG) + if(algname == "X9.31-RNG(TripleDES)") + prng = new ANSI_X931_RNG(new TripleDES, + new Fixed_Output_RNG(decode_hex(key))); + else if(algname == "X9.31-RNG(AES-128)") + prng = new ANSI_X931_RNG(new AES_128, + new Fixed_Output_RNG(decode_hex(key))); + else if(algname == "X9.31-RNG(AES-192)") + prng = new ANSI_X931_RNG(new AES_192, + new Fixed_Output_RNG(decode_hex(key))); + else if(algname == "X9.31-RNG(AES-256)") + prng = new ANSI_X931_RNG(new AES_256, + new Fixed_Output_RNG(decode_hex(key))); +#endif + +#if defined(BOTAN_HAS_RANDPOOL) + if(algname == "Randpool") + { + prng = new Randpool(new AES_256, new HMAC(new SHA_256)); + + prng->add_entropy(reinterpret_cast<const byte*>(key.c_str()), + key.length()); + } +#endif + +#if defined(BOTAN_HAS_X931_RNG) + // these are used for benchmarking: AES-256/SHA-256 matches library + // defaults, so benchmark reflects real-world performance (maybe) + if(algname == "X9.31-RNG") + { + RandomNumberGenerator* rng = +#if defined(BOTAN_HAS_HMAC_RNG) + new HMAC_RNG(new HMAC(new SHA_512), new HMAC(new SHA_256)); +#elif defined(BOTAN_HAS_RANDPOOL) + new Randpool(new AES_256, new HMAC(new SHA_256)); +#endif + + prng = new ANSI_X931_RNG(new AES_256, rng); + + } +#endif + +#if defined(BOTAN_HAS_HMAC_RNG) + if(algname == "HMAC_RNG") + { + prng = new HMAC_RNG(new HMAC(new SHA_512), new HMAC(new SHA_256)); } - catch(Algorithm_Not_Found) {} +#endif - return mac; + if(prng) + { + prng->add_entropy(reinterpret_cast<const byte*>(key.c_str()), + key.length()); + return new RNG_Filter(prng); + } + + return 0; } -Filter* lookup_cipher(const std::string& algname, const std::string& key, - const std::string& iv, bool encrypt) +Filter* lookup_kdf(const std::string& algname, const std::string& salt, + const std::string& params) { + KDF* kdf = 0; try { - if(encrypt) - return get_cipher(algname, key, iv, ENCRYPTION); - else - return get_cipher(algname, key, iv, DECRYPTION); + kdf = get_kdf(algname); } - catch(Algorithm_Not_Found) {} - catch(Invalid_Algorithm_Name) {} + catch(...) { return 0; } + + if(kdf) + return new KDF_Filter(kdf, salt, to_u32bit(params)); return 0; } @@ -128,3 +252,28 @@ Filter* lookup_encoder(const std::string& algname) return 0; } + +Filter* lookup(const std::string& algname, + const std::vector<std::string>& params) + { + std::string key = params[0]; + std::string iv = params[1]; + Filter* filter = 0; + + // The order of the lookup has to change based on how the names are + // formatted and parsed. + filter = lookup_kdf(algname, key, iv); + if(filter) return filter; + + filter = lookup_rng(algname, key); + if(filter) return filter; + + filter = lookup_encoder(algname); + if(filter) return filter; + + filter = lookup_s2k(algname, params); + if(filter) return filter; + + return 0; + } + diff --git a/checks/dolook2.cpp b/checks/dolook2.cpp deleted file mode 100644 index 51ee8fec1..000000000 --- a/checks/dolook2.cpp +++ /dev/null @@ -1,212 +0,0 @@ -#include <vector> -#include <string> -#include <cstdlib> - -#include <botan/botan.h> -#include <botan/lookup.h> -#include <botan/filters.h> - -#include <botan/hmac.h> -#include <botan/aes.h> -#include <botan/sha2_32.h> -#include <botan/sha2_64.h> - -#if defined(BOTAN_HAS_RANDPOOL) - #include <botan/randpool.h> -#endif - -#if defined(BOTAN_HAS_HMAC_RNG) - #include <botan/hmac_rng.h> -#endif - -#if defined(BOTAN_HAS_X931_RNG) - #include <botan/x931_rng.h> - #include <botan/des.h> -#endif - -#if defined(BOTAN_HAS_AUTO_SEEDING_RNG) - #include <botan/auto_rng.h> -#endif - -#include "common.h" -using namespace Botan; - - -/* A weird little hack to fit S2K algorithms into the validation suite - You probably wouldn't ever want to actually use the S2K algorithms like - this, the raw S2K interface is more convenient for actually using them -*/ -class S2K_Filter : public Filter - { - public: - void write(const byte in[], u32bit len) - { passphrase += std::string(reinterpret_cast<const char*>(in), len); } - void end_msg() - { - s2k->change_salt(salt, salt.size()); - s2k->set_iterations(iterations); - SymmetricKey x = s2k->derive_key(outlen, passphrase); - send(x.bits_of()); - } - S2K_Filter(S2K* algo, const SymmetricKey& s, u32bit o, u32bit i) - { - s2k = algo; - outlen = o; - iterations = i; - salt = s.bits_of(); - - } - ~S2K_Filter() { delete s2k; } - private: - std::string passphrase; - S2K* s2k; - SecureVector<byte> salt; - u32bit outlen, iterations; - }; - -/* Not too useful generally; just dumps random bits for benchmarking */ -class RNG_Filter : public Filter - { - public: - void write(const byte[], u32bit); - - RNG_Filter(RandomNumberGenerator* r) : rng(r) {} - ~RNG_Filter() { delete rng; } - private: - RandomNumberGenerator* rng; - }; - -class KDF_Filter : public Filter - { - public: - void write(const byte in[], u32bit len) - { secret.append(in, len); } - void end_msg() - { - SymmetricKey x = kdf->derive_key(outlen, - secret, secret.size(), - salt, salt.size()); - send(x.bits_of(), x.length()); - } - KDF_Filter(KDF* algo, const SymmetricKey& s, u32bit o) - { - kdf = algo; - outlen = o; - salt = s.bits_of(); - } - ~KDF_Filter() { delete kdf; } - private: - SecureVector<byte> secret; - SecureVector<byte> salt; - KDF* kdf; - u32bit outlen; - }; - -Filter* lookup_s2k(const std::string& algname, - const std::vector<std::string>& params) - { - S2K* s2k = 0; - - try { - s2k = get_s2k(algname); - } - catch(...) { } - - if(s2k) - return new S2K_Filter(s2k, params[0], to_u32bit(params[1]), - to_u32bit(params[2])); - return 0; - } - -void RNG_Filter::write(const byte[], u32bit length) - { - if(length) - { - SecureVector<byte> out(length); - rng->randomize(out, out.size()); - send(out); - } - } - -Filter* lookup_rng(const std::string& algname, - const std::string& key) - { - RandomNumberGenerator* prng = 0; - -#if defined(BOTAN_HAS_AUTO_SEEDING_RNG) - if(algname == "AutoSeeded") - prng = new AutoSeeded_RNG; -#endif - -#if defined(BOTAN_HAS_X931_RNG) - if(algname == "X9.31-RNG(TripleDES)") - prng = new ANSI_X931_RNG(new TripleDES, - new Fixed_Output_RNG(decode_hex(key))); - else if(algname == "X9.31-RNG(AES-128)") - prng = new ANSI_X931_RNG(new AES_128, - new Fixed_Output_RNG(decode_hex(key))); - else if(algname == "X9.31-RNG(AES-192)") - prng = new ANSI_X931_RNG(new AES_192, - new Fixed_Output_RNG(decode_hex(key))); - else if(algname == "X9.31-RNG(AES-256)") - prng = new ANSI_X931_RNG(new AES_256, - new Fixed_Output_RNG(decode_hex(key))); -#endif - -#if defined(BOTAN_HAS_RANDPOOL) - if(algname == "Randpool") - { - prng = new Randpool(new AES_256, new HMAC(new SHA_256)); - - prng->add_entropy(reinterpret_cast<const byte*>(key.c_str()), - key.length()); - } -#endif - -#if defined(BOTAN_HAS_X931_RNG) - // these are used for benchmarking: AES-256/SHA-256 matches library - // defaults, so benchmark reflects real-world performance (maybe) - if(algname == "X9.31-RNG") - { - RandomNumberGenerator* rng = -#if defined(BOTAN_HAS_HMAC_RNG) - new HMAC_RNG(new HMAC(new SHA_512), new HMAC(new SHA_256)); -#elif defined(BOTAN_HAS_RANDPOOL) - new Randpool(new AES_256, new HMAC(new SHA_256)); -#endif - - prng = new ANSI_X931_RNG(new AES_256, rng); - - } -#endif - -#if defined(BOTAN_HAS_HMAC_RNG) - if(algname == "HMAC_RNG") - { - prng = new HMAC_RNG(new HMAC(new SHA_512), new HMAC(new SHA_256)); - } -#endif - - if(prng) - { - prng->add_entropy(reinterpret_cast<const byte*>(key.c_str()), - key.length()); - return new RNG_Filter(prng); - } - - return 0; - } - -Filter* lookup_kdf(const std::string& algname, const std::string& salt, - const std::string& params) - { - KDF* kdf = 0; - try { - kdf = get_kdf(algname); - } - catch(...) { return 0; } - - if(kdf) - return new KDF_Filter(kdf, salt, to_u32bit(params)); - return 0; - } diff --git a/checks/pk_bench.cpp b/checks/pk_bench.cpp index 88a72afde..9a94d8474 100644 --- a/checks/pk_bench.cpp +++ b/checks/pk_bench.cpp @@ -53,9 +53,23 @@ using namespace Botan; #include <fstream> #include <string> #include <memory> +#include <set> namespace { +class Benchmark_Report + { + public: + void report(const std::string& name, Timer timer) + { + std::cout << name << " " << timer << std::endl; + data[name].insert(timer); + } + + private: + std::map<std::string, std::set<Timer> > data; + }; + void benchmark_enc_dec(PK_Encryptor& enc, PK_Decryptor& dec, Timer& enc_timer, Timer& dec_timer, RandomNumberGenerator& rng, @@ -603,7 +617,7 @@ void benchmark_elg(RandomNumberGenerator& rng, } void bench_pk(RandomNumberGenerator& rng, - const std::string& algo, bool, double seconds) + const std::string& algo, double seconds) { /* There is some strangeness going on here. It looks like algorithms diff --git a/checks/timer.cpp b/checks/timer.cpp index c42aaa4b2..8460257d4 100644 --- a/checks/timer.cpp +++ b/checks/timer.cpp @@ -1,4 +1,5 @@ #include "timer.h" +#include <botan/benchmark.h> #include <iomanip> Timer::Timer(const std::string& n, u32bit e_mul) : @@ -29,6 +30,12 @@ void Timer::stop() } } +u64bit Timer::get_clock() + { + Botan::Default_Benchmark_Timer timer; + return timer.clock(); + } + std::ostream& operator<<(std::ostream& out, Timer& timer) { //out << timer.value() << " "; diff --git a/checks/validate.cpp b/checks/validate.cpp index 8fb225137..ff26e855a 100644 --- a/checks/validate.cpp +++ b/checks/validate.cpp @@ -10,6 +10,8 @@ #include <botan/filters.h> #include <botan/exceptn.h> +#include <botan/selftest.h> +#include <botan/libstate.h> using namespace Botan; #include "validate.h" @@ -43,11 +45,10 @@ u32bit random_word(Botan::RandomNumberGenerator& rng, } -Botan::Filter* lookup(const std::string&, const std::vector<std::string>&, - const std::string& = "All"); +Botan::Filter* lookup(const std::string&, const std::vector<std::string>&); bool failed_test(const std::string&, std::vector<std::string>, bool, bool, - const std::string&, std::string&, + std::string&, Botan::RandomNumberGenerator& rng); std::vector<std::string> parse(const std::string&); @@ -150,7 +151,7 @@ u32bit do_validation_tests(const std::string& filename, { failed = failed_test(algorithm, substr, is_extension, should_pass, - section, last_missing, rng); + last_missing, rng); } catch(std::exception& e) { @@ -180,21 +181,42 @@ u32bit do_validation_tests(const std::string& filename, bool failed_test(const std::string& algo, std::vector<std::string> params, bool is_extension, bool exp_pass, - const std::string& section, std::string& last_missing, Botan::RandomNumberGenerator& rng) { -#if DEBUG - std::cout << "Testing: " << algo; - if(!exp_pass) - std::cout << " (expecting failure)"; - std::cout << std::endl; -#endif - #if !EXTRA_TESTS if(!exp_pass) return true; #endif + std::map<std::string, std::string> vars; + vars["input"] = params[0]; + vars["output"] = params[1]; + + if(params.size() > 2) + vars["key"] = params[2]; + + if(params.size() > 3) + vars["iv"] = params[3]; + + std::map<std::string, bool> results = + algorithm_kat(algo, vars, global_state().algorithm_factory()); + + if(results.size()) + { + for(std::map<std::string, bool>::const_iterator i = results.begin(); + i != results.end(); ++i) + { + if(i->second == false) + { + std::cout << algo << " test with provider " + << i->first << " failed\n"; + return true; + } + } + + return false; // OK + } + const std::string in = params[0]; const std::string expected = params[1]; @@ -210,7 +232,7 @@ bool failed_test(const std::string& algo, Botan::Pipe pipe; try { - Botan::Filter* test = lookup(algo, params, section); + Botan::Filter* test = lookup(algo, params); if(test == 0 && is_extension) return !exp_pass; if(test == 0) { diff --git a/checks/validate.dat b/checks/validate.dat index 675e1afb0..875177868 100644 --- a/checks/validate.dat +++ b/checks/validate.dat @@ -19472,7 +19472,20 @@ D261D6041824D259290EABD3E9132DB8:7E3B14847526572FF2AA5D7BD626B560:\ 01000000000000000000000000000000:07E5E5AD7097B849BADC2D5D803B7F6A:\ 0000000000000000000000000000000000000000000000000000000000000000 +1032547698BADCFEEFCDAB8967452301:D5BAA00A4BB9D8A7C981C8DC90D89D92:\ +FFEEDDCCBBAA99887766554433221100 +145F0B8B663176B95DCAB7E9DCD5CC24:1032547698BADCFEEFCDAB8967452301:\ +FFEEDDCCBBAA99887766554433221100 + +1032547698BADCFEEFCDAB8967452301:DA860842B720802BF404A4C71034879A:\ +8899AABBCCDDEEFFFFEEDDCCBBAA99887766554433221100 + +B2696BD0D98C17953E4239225D27202C:1032547698BADCFEEFCDAB8967452301:\ +8899AABBCCDDEEFFFFEEDDCCBBAA99887766554433221100 + +1032547698BADCFEEFCDAB8967452301:93DF9A3CAFE387BD999EEBE393A17FCA:\ +00112233445566778899AABBCCDDEEFFFFEEDDCCBBAA99887766554433221100 # Corrected test vectors, based on NIST's clarification of May 9, 2002 [Skipjack] @@ -22932,12 +22945,85 @@ F922CA875B991A31:2763F255636A34C1:22EBE7A30E8855B3B453A6E926D4F187 B4ECC305C3DBD8E5:FBBEC8F5DBF4CEFD:1B5E23EBD915C1FEE59F57DD91AF7347 3DAADD7A9633E19B:4DE5C07EA1564A64:A6BFB85FA91B8CA4197C8B502A62F972 -# MARKER: Cipher Modes (Encryption) +# MARKER: Cipher Modes # Cipher mode format is plaintext:ciphertext:key:iv # The block cipher tests above are distinct from these ECB mode tests # for testing reasons. They could otherwise easily be CIPHER/ECB/NoPadding + +[AES/ECB/NoPadding] +D8F532538289EF7D06B506A4FD5BE9C9FD7A929E0FD917686D9520ED236A276D\ +69E63C821F9DE0BF23CF1D19C7374FD1C3139DE2E1BA4693C3E9D29D774C2FF4\ +69E63C821F9DE0BF23CF1D19C7374FD1C3139DE2E1BA4693C3E9D29D774C2FF4\ +D8F532538289EF7D06B506A4FD5BE9C9FD7A929E0FD917686D9520ED236A276D\ +D8F532538289EF7D06B506A4FD5BE9C9C3139DE2E1BA4693C3E9D29D774C2FF4:\ +FD7A929E0FD917686D9520ED236A276D69E63C821F9DE0BF23CF1D19C7374FD1\ +C3139DE2E1BA4693C3E9D29D774C2FF46BA2DCF84C0E7E4D75CB53AD11BA76D6\ +C3139DE2E1BA4693C3E9D29D774C2FF46BA2DCF84C0E7E4D75CB53AD11BA76D6\ +FD7A929E0FD917686D9520ED236A276D69E63C821F9DE0BF23CF1D19C7374FD1\ +FD7A929E0FD917686D9520ED236A276D6BA2DCF84C0E7E4D75CB53AD11BA76D6:\ +00010203050607080A0B0C0D0F101112 + +[Serpent/ECB/NoPadding] +D29D576FCEA3A3A7ED9099F29273D78E2D62A890CEA3A3A7ED9099F29273D78E\ +D29D576F315C5C58ED9099F29273D78E2D62A890315C5C58ED9099F29273D78E\ +D29D576FCEA3A3A7126F660D9273D78E2D62A890CEA3A3A7126F660D9273D78E\ +D29D576F315C5C58126F660D9273D78E2D62A890315C5C58126F660D9273D78E\ +D29D576FCEA3A3A7ED9099F26D8C28712D62A890CEA3A3A7ED9099F26D8C2871\ +D29D576F315C5C58ED9099F26D8C28712D62A890315C5C58ED9099F26D8C2871\ +D29D576FCEA3A3A7126F660D6D8C28712D62A890CEA3A3A7126F660D6D8C2871\ +D29D576F315C5C58126F660D6D8C28712D62A890315C5C58126F660D6D8C2871\ +AA26D561F567520E8AE47528C24C18D731A2193D9A97FED6922B17AAA6372B74\ +BE5DEBD559E303C9C92B174A5107BBFEB626D8F65EDCCDF3AEE475C8A1837722\ +41DDE7C1F1631F5FDED4F42746471BD651D238BA86176EFE39E4695AAEB73B52\ +EA5926CADAD8018962E469BA920CB8BF1EA9062E4D9CEDD5FAD4F4C7990367A4\ +B966E5C5D2277288C61B96A559CC84AFB6A6583C5AACFCD6212B0BD8AEF3C6A9\ +A11DDBD175639341052B0B384678D8D9352299B71DD880E29D1B96452DB86540\ +B2288B968AE8B08648D1CE9606FD992D717EB02EB81A2E939D54ACA91087112D\ +0D809C5EE82F477EBA7B956DBB23463B0F0190D616F5294112FFB7884E8B37F9\ +41BA1B505386B7428B88338188F7E718A3348230BF5CFA552F88D22463D9703A\ +115351622E016BCA26918D17E13225F67EE4E3F2C46FE52ECBDA044C585717DC\ +563A8403FF5309D62370B1DCF5A11EDD2F7D73602B70CD2553E44C1D3F170126\ +155BBD9BE3A965B345E834718F651CEF6CC65E8C5C566E894817350F497816F1\ +EEFA51FC91FEBB6E9F8CB141CC0EB6AF3C6F8380CBD3C996167F2F0E90E71B75\ +6C87EB62A4975356B28DCBF6A64A0BD107206D48FE6DBE19D50314B90AC87B83\ +35706F9B26007071AD8105CFAA1C1E2FF7FEAE5CEC4D11477F24E6B200906870\ +3C0E29E2950F2AC2DACD63DEEB5C7EFA9FDB9F3B740563D5518287DC981FC9CB\ +46D4B5A5A86FEC08FE70D18297DCF51072DDBE038DA040EBB12C509F5940A212\ +DDEB59F02132BE4581FC23EABAA960D6341D9352E36DFD6E4EAF0F6F439BC8CE\ +73A9AB3164FF30350F2DC08E939A104D6DF0C2C28F8E2D44468A61278BB6B429\ +4DAE45AE0CAA032FC97CD4D8C57FB83BBA8AFCAE22070BC882D3A42B38A09E65:\ +B2288B968AE8B08648D1CE9606FD992D717EB02EB81A2E939D54ACA91087112D\ +0D809C5EE82F477EBA7B956DBB23463B0F0190D616F5294112FFB7884E8B37F9\ +41BA1B505386B7428B88338188F7E718A3348230BF5CFA552F88D22463D9703A\ +115351622E016BCA26918D17E13225F67EE4E3F2C46FE52ECBDA044C585717DC\ +563A8403FF5309D62370B1DCF5A11EDD2F7D73602B70CD2553E44C1D3F170126\ +155BBD9BE3A965B345E834718F651CEF6CC65E8C5C566E894817350F497816F1\ +EEFA51FC91FEBB6E9F8CB141CC0EB6AF3C6F8380CBD3C996167F2F0E90E71B75\ +6C87EB62A4975356B28DCBF6A64A0BD107206D48FE6DBE19D50314B90AC87B83\ +35706F9B26007071AD8105CFAA1C1E2FF7FEAE5CEC4D11477F24E6B200906870\ +3C0E29E2950F2AC2DACD63DEEB5C7EFA9FDB9F3B740563D5518287DC981FC9CB\ +46D4B5A5A86FEC08FE70D18297DCF51072DDBE038DA040EBB12C509F5940A212\ +DDEB59F02132BE4581FC23EABAA960D6341D9352E36DFD6E4EAF0F6F439BC8CE\ +73A9AB3164FF30350F2DC08E939A104D6DF0C2C28F8E2D44468A61278BB6B429\ +4DAE45AE0CAA032FC97CD4D8C57FB83BBA8AFCAE22070BC882D3A42B38A09E65\ +58A51ED82169DE7027CBE72452626CA3FF6BBF2FB2C574EC9D5656505B516880\ +47AEA89DBBB5C4EBE819C5BDFDAB16033D2FE7D01071373624D99845D90E32C1\ +708C609C4E75BE40D8DE77F8EA78C2CC98852792C22E971F29C2E125247FB43C\ +AD1FD857DE9B8016C5971FFF86AD399ED669FEF7481FD73B9A45B1CFFE9C556D\ +AE9A816916FB1F5822B2CEC8986F6E5B156775D0F6F432D57D351C62A24AFE63\ +AE812270F7416D05E153E5AB703DCD3FF320F6AD3D00647C23F08699E0EE9F5E\ +DDB3C717C2A6D3E58D38269DBA0243926D64CCD92B1101086DD3F0DDB73312A3\ +1D5F5EA0FD18AB84E242C96FFCC222F9FE12D5B15F5A3C365E9FF3248FB43B38\ +5A0F73507F49A08E68952BEE09DC7D35E7B29A44C8970624CB3A93DA4AE7E498\ +35AE41A5BE2EE591750FF9A7D431B1EE8A69099E689A06324AA0AE431ACAE762\ +FD3B90A8B269090A4CEEA076CF1EB7A580DEDE896BED63917384B1C5E18B7B57\ +A7EB6B127A7A32898989E32CFF9A46BF6A62268500E53AD8A5FBC95226266BD9\ +AAE1BA501274C49A7A7EC67D7577114B7707DAB9D066AF086C09E7DD4116CEA6\ +EE25DA9A65EF05A31ED0BDF56D525EC8968D1D01AF7165C5AEAC76BD367A575A:\ +00000000000000000000000000000000 + [DES/ECB/NoPadding] 059B5E0851CF143A:86A560F10EC6D85B:0113B970FD34F2CE 4E6F772069732074:3FA40E8A984D4815:0123456789ABCDEF @@ -23569,6 +23655,13 @@ DC7E84BFDA79164B7ECD8486985D38604FEBDC6740D20B3AC88F6AD82A4FB08D\ 5AE4DF3EDBD5D35E5B4F09020DB03EAB1E031DDA2FBE03D1792170A0F3009CEE:\ 2B7E151628AED2A6ABF7158809CF4F3C:F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF +# Test with 15 byte IV (last byte implicit zero) +AE2D8A571E03AC9C9EB76FAC45AF8E51\ +30C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710:\ +9806F66B7970FDFF8617187BB9FFFDFF\ +5AE4DF3EDBD5D35E5B4F09020DB03EAB1E031DDA2FBE03D1792170A0F3009CEE:\ +2B7E151628AED2A6ABF7158809CF4F3C:F0F1F2F3F4F5F6F7F8F9FAFBFCFDFF + 6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E51\ 30C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710:\ 1ABC932417521CA24F2B0459FE7E6E0B090339EC0AA6FAEFD5CCC2C6F4CE8E94\ @@ -24214,6 +24307,142 @@ D05BC090A8E04F1B3D3ECDD5BAEC0FD4EDBF9DACE45D6F6A7306E64BE5DD82:\ FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0:\ 9A785634120000000000000000000000 +[Serpent/XTS] + +53514C69746520666F726D6174203300040001010040202091E4F9BE00000000\ +0000000000000000000000020000000100000000000000000000000100000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +000000000D00000002033B00039F033B00000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000006202071717\ +170181237461626C657465737432746573743203435245415445205441424C45\ +20277465737432272028696420494E5445474552205052494D415259204B4559\ +2C206E616D6520544558542C206372656174696F6E74696D652054455854295F\ +01071715150181217461626C6574657374746573740243524541544520544142\ +4C45202774657374272028696420494E5445474552205052494D415259204B45\ +592C206E616D6520544558542C206372656174696F6E74696D65205445585429:\ +EF1F13233DE8092DDE062280F8CA8F480EC61DD555396F41FB8ED9444844F837\ +89933DCF9AEEC1933D3DBB4D54A26C329D7461ECDD009CAF263EDE40007F2673\ +6782D95B629205E87D4747FADA1434EE74DB09505C43230A0E700EFD012A5F80\ +8FC713FB22624AF804FA318BDAC382773E2653B4D576D0BC1A42F9652F56280D\ +A21CF82595137F9C472938F7519B6CC24708FD5409B75C5309E2C85294A2D182\ +2A218D9891D56696ABBF569906CA0452478628A719E3F11AB097D62D3FFB4549\ +576159282232655AB69CE1A4103DA8428F74D73E540A95ACBCF347D4EDD299FE\ +8ED90AB8F09D5D16B35BC5925E0B191DD753E2617B9085F108CE6B445F604CAF\ +2B266D5A10B460DE08A307D7CDE626D84412B8938B24EDBAFD98205978207014\ +4413A7C354F99D89CA475ECB626E7D93687A505B0F3E7D48823E4133E1C59465\ +56D55266A90F8C213ADFB020CA2D55462FA400B26B159306A5D3A4C91815C3E4\ +ECB8545E394099B330659E9B9C188AB09A53838AA8D0119ED9E55837BBDA655C\ +FD4096C4E2227287195602F32A8239D69DF555145F4EFF077F69366416F800DC\ +30C03C50DE4AFA12CFB4A8CD2E86B36D54CB44C3848FAD7917642551A85C76A3\ +A3C616D32B471B5775A1662B997D392D0B091570710B1CCDE49DCEE634EE3BC3\ +BC85ACEBB7F8551DAF5D15EF19A9DCD3CC9C82B46A4B9EFF8AAD0F8971A0F26D\ +C37E2DDBBD7603298654AD6CE0829EB76F0892E81C569A71343BA8EF767B70B8\ +A24ECF342B832483B7C9375D07BDDE2F1D6D4E6D28E997B1CEE1254F70D17F7C\ +24EFB08A3634802B37C8C0081F501EBE9346B9DFF3705A449B5517984DDBC2BC\ +91F626045EE89276C137233D8560B15C11592082D11935FF68A2ED6087527030\ +E4FC31F37680132CC53DAC81DC3636DB5068FBFA3B6923A2DC7CA617707944FC\ +D0CF81D092916AA54D5D26151C259FAA9AFCF9CD77A5E22FEBC019694205A1D3\ +F999E59F00D42F26FB5B9BE68B45F37DD664A2E9BA3336CA8A37BBC7EB452585\ +8FCCD69B746C7B8EFD534AF44028F915743FC858B45DD12D7F637FFFCCB431B3\ +DB609578811A67BB80D954A16B456792084E0E828CAB146A11A84DDBE4C79859\ +C9302FC55EBF8BFE8CD2B6214098549EA67FA52C8E0DF383F3532D87816C7452\ +A7AD571C213307961F786C45FA3AA89A0B66766EF0775904A66BC17DF3EB5646\ +0444EA22EB838A555D58EAE5DD0628581B9709738A1D9B2A3F66D4CA254FDE4D\ +EF8DE858574672F34BAEC851C58E58209C9019A32E0C728A866D04C1A5524689\ +C11C97302E3BE145486887E7E6F11581F6751DEBD01C28CBEE855CB58F69D794\ +5831AE82AF364ADD56CFA0C160CAB270D963CBF82E324409690597D80F152025\ +0B8254B29B09BA74E3700F9E614D37728C373C15C1E92D2674686D811507C34E:\ +9F7DC5DB8ECF4302325E0A993D761186BD59BD247615E560B704F8C9B6126A85:\ +2B1B7B6EAF72CA6F7F6CD1C0ED88DAD0 + +0D0000000503920003EA03D403BE03A803920000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +0000000000000000000000000000000000000000000000000000000000000000\ +000000000000000000000000000000000000140504001B1F7769646765743235\ +74682074696D6532140404001B1F776964676574323474682074696D65321403\ +04001B1F776964676574323372642074696D6532140204001B1F776964676574\ +32326E642074696D6532140104001B1F776964676574323173742074696D6532:\ +3A88A5D687632C9EB390B37C721A2010006D31FC9D4E3D169D242E1E44A317C0\ +675566A5414EC5C5FB19FB10D329C9F8A0250AD8F07880459B98E079FBB1CA58\ +725EABB2CCD6427E14BA01580B402B9EE34C6B23CEE38F5AC5B50A8198C5441E\ +C3955B3290E2F7211C8B2970E3082EBFA1DA9233E0D94923D5F658A6BA1E0E5C\ +7FC01889E3486551180032304FE118BBF7484A487B20B356C89C2DC5C1C8DE94\ +882676B19FF952B3316B9C8C0187B5BF781D894AB1DE6E8537B57CAF45CF23E6\ +9B62B143E1AD9C47483525EB0D89AEAD9CAA731E6FB2A3ADFAB8C05E1F967460\ +B05ECD759B6485AEB2A87F8E9030AD6C01C1E3E7FB468C624C50B2A20A9564FF\ +5E1C164C0ADE0839099FF7AEA385AF3CD07D743B7C0812477AED4EE7EAF09AE2\ +45CB1A646F63A5B4A7741C1B223C73235A973FC08A7DA0B60D5B8BD8DA07C236\ +7DC32CDE9A468DE47570D8FE52BAA8088D75572671F227D8BF5031165581C7D0\ +24535729112182B38ABF9DBA5F15B3EC590A6BE6C4AEB987E851C9A850D8AA8D\ +E7CF93A60E8159130E94BCA5FB252A0089EABEFAB3E2FF77C7CB3193D3123CD2\ +929E336C2E183272F83AE13574A0595591619BCE9FBBBB5D9EAC69B5D8C8BBD1\ +27EA886544BF770DCD8FF9C96F0EBF63F9D9C20FC8F1962CAB0E5FA7D61CF41F\ +4F38A43E402FD91119ACD6F7EBB1BEE6D56C7BA2C014BF64018464E8D3938FC5\ +4F7A8B58A1B86C16859A9CDAFD5604954AC1BA17CC1057481FA8704FD3DA9B3E\ +EC91B850B9DB54B38F59438494A316A0D271D813C8B95FA21FE7776F112327F3\ +21D6DA9E1C2909CEE630856A53140D9905DA751F42BE351FCCEFBC44EB80F086\ +5A3EB6CB14A91471D9B0ACDFF0D65DA1CBB8E17E2234B20BA8D3555627A4356B\ +8C0D0851AB981DBFE79A293C242BF862D8487895D7B86DE8D77810D0AEDEC249\ +6063C9ECDC57B1D3B1B6BC54F9280984D532CF30CECFCF954B5D06DF949E405C\ +A68C12C2BC8584BAE50EAC0F98BD2D1E8B53237F10F414D61E90BF3FE927D950\ +8670D614EB1CFECF00C92AA3F50E2737F7BD3FB91C46D3677FC3F1EE03FE81EA\ +6E7ADCE6FCCF06719BF1385C6608D2F833CB926ADC03339D03CB45996B199BD9\ +C3B18AA60BD9841FBE5331CFF7544BCECFA79E44BAD1F8757DFCCE491267772F\ +0BFB4AE236E19DFE16BD166856851999614F38997EAB29EBA438D10FB7278FF3\ +1334B8AFA0D6CBDCA39DD2ABAF46560805BBD9F7B32A3C551A4BBEFEBABB8906\ +9640C7E310C0DD8BDA60641D2468E2C59933DF671C22B57190F973E8EF85F5C6\ +E05D89E412243366DC2947F3418198FF5A0A38A383354ACDB3B2D79E99E7F734\ +57A9EA05506307CFE13E8BB571B032DE8DD22F3DC33AE338185FC099E9A5693C\ +10B78D140F6B3BCD8F2ACBBADED84941AC3CFC8F2795BD94499B89E92E45B9C1:\ +9F7DC5DB8ECF4302325E0A993D761186BD59BD247615E560B704F8C9B6126A85:\ +92E8641C3A25F1A79D188D7DA317F4F1 + [Serpent/CTR-BE] F3:3A:\ 740614949B42870F0851A0D639A37AC8288898B0F9CC3B326B983ADA69BDBB76:\ @@ -24755,1049 +24984,2357 @@ DBCFC865520E4DEFAD4000CE0EC528916A415C4661E1ED7095E5777BF375DC31CED5F966\ 11C63D070095FCD408DC7E7596C177C0A09961B2BDCB6E7C0F300C918E7E830B:\ 41EF5DF5CF14D6D2C14CC4CBC4EADAB7 -# MARKER: Cipher Modes (Decryption) - -# Cipher mode format is plaintext:ciphertext:key:iv - -[DES/ECB/NoPadding] -86A560F10EC6D85B:059B5E0851CF143A:0113B970FD34F2CE -3FA40E8A984D4815:4E6F772069732074:0123456789ABCDEF - -[DES/ECB/PKCS7] -17AE296967C5D076::AD37078F3EA426EF -A9E2BD3B74E7F3CE:E7:9CBEDD92FF2A5B73 -059CF1BEEADC62C2:896D:2FDB746F903CAD45 -784F42BF01754613:C1B1C1:64EA8FC0D24CA010 -9F4559AC8F287060:0888EC54:4C836F4563DF32BC -9553EAE17C9554C7:5B0E9EFF57:C6B1BAA1CE9585AC -3ECDE9A96CC20C64:3D0B96172D78:D75487A2708B6667 -05CE6E5D61EF4C58:90628E099303AE:3B7C17F8189C21EF -DC9D7EEDF77F3B4685EF88B5E3736DF0:3216ACECC41D0D6B:D53C39F84A7E53A4 -EAFA4A1BEB450770265C5AF8A87B807D:8C04066386282D98D5:4637A64E19D8C59A -91A2C846731747F490596CC2C1354E2C:D2802A5A871F246AB192:0971FEDA66F7DD2E -8763EEF91B589B6706EE96108DDB9A70:D3E87AF21F0313835ADAC3:8E8F17C42B91EADB -C75CC89A8B528B1CFA9725A4F6F22C9F:D6FBF31C50BEF03DB36D9CFA:A87F5FF0B3545400 -3888F955A7079C88ADDFEE8C5DDDDE85:40C86D519650F7506BAE823B89:6DA82D72B5948390 -FACCCE40C05A410B329340EEE8E63E89:\ -0780C2ABA3516BDE2A2F8970EB75:040128669CE30F4C -7AFE6045F807102D354B17B45F3D9D70:\ -BEAFD7CBD536B9800B10F9CEE81E72:A25AA7C651B67CB2 -2985CE350364A85067F32C4E5D340F1658E77714063EA91C:\ -3D8DDC8C215EC27AE07C428D093DBEBB:E4E5E82C29060303 -C78110FF4EBD0FCC3EA2A8F1B3CFECDAC527FF08EE874167:\ -BD6FC0629E56D7E151AD3BC303B02852E4:587033C361C2413E -02F8DC588D26A55A5B8E441FC66804CAA198A38CF5837A96:\ -8AA4B5C93DB2727D4997927B4570DFDF630E:9A65A821B5FB59D9 -FDBFEBDE42AD8228D33B0032ED35B4AB687BB44CDDFBFC78:\ -13B6ED27218594D16AB5A8475BADA80C03E36E:ADFA49E8BD20F49A -43391357D31B758921A07ACABEDA50025421B9A15CFFD863:\ -4FAFFCA861CDD5B7393C2F1171E3EAFCFF1BBF09:7C4C08429BBC99D4 -1BEF25251A46159EDC6E7410E9A3804E4DE32A202E2D3FFA:\ -4F246C4C3F679CAE3D659820ADF948B04DA101AAC7:C4D15330927DB0D5 -BAB47B7AFAFD30234BC4E69F1A602788B294438296F6E046:\ -C00AFB680484638EE4BC8999CAAA7EDBF32ADD6A32CF:DBDEDFA4B3BCB30B -006EE0B1E90468292B72A70426DCD3975A6A4F21D6F6DC8A:\ -94CFEC7A15A35441AC72222DC4BE7508CE12B1D9690E86:95C9471D839AC3A0 -7DA18BB325DABC8F5DDFBAF9B41F4389C0FF9E37A86A1E318C9065FC7F3D654B:\ -95F6A941BBA9BA711BF1962D668996A315157A49EE32993B:F22460847CD66211 - -[DES/ECB/OneAndZeros] -D573EBC3919CB0FB::9EAEF4F67688739C -96205FA42306698E:56:FCC8C062DAAF3A6E -C2A09626D3200B09:7106:F4FA38ACB1D2A9C9 -64850779AD424E5B:9B5D19:FFAE7E198369326C -5A4D009F2ACFD643:30A671C3:585B8E1A64E346FA -BD29AF6B945A8413:371415B9FD:4B6C26F53E7317AE -6904EF148ECF10B4:1F5E2F5D845C:361DF31C6F8E772A -4A749E5874DC2FDE:FFCB40A7CDB5B6:050025D50D9773E9 -72EEC4B5CCB537C1AA223E5DF3368139:610F58A0A16D1303:D4F1D443093CF941 -25259E1C4C1E65966D933ED350668BC3:171A5D4E209F133F3B:CA2BD0CF16C9D7BD -70C87505241FAA9BE93633B16880856D:927D2B314B4CCD1F3D04:C64374B9C7E2A06E -393C836014C3A65EC36E6165CE192CE4:2CCC4DA982CF67BE929C4A:E30F4BDF1B96967E -858A4172FAFD4614B5263F418EB9EC56:4E92F895CAEA28B7208236F9:308DE63A2E3A5BCE -2716D7195AC4D979C3F81D3D08897E8E:E306358941C2BAFE286043A113:33482C296BD8D44F -5217205AC00B31FE8D7CDB916AD49773:\ -5ABDB2059249D0672AC52085985E:C893C0B250AAD5F9 -1651D5785652365C03541F62BDB343B8:\ -D9E343F4A600D4C5467FBBB923BFDF:9490B296D0EA218D -90C4F548C806B6B86EC2BAF6A96CEC5D9748FCA16CA51F44:\ -D3DCA72E82C0572ECC7C0DF2BE150C00:F5A1291B1A39F5E9 -39EBA35BF86A2926B0A489599B4BF94C31A9F7FEC351ECE2:\ -5E3786F3E7B3D91AFEE1295C314AFBAFC5:83B78C6CEB56CE78 -B32E06E80854E4B815E12F61A2431B7E9F378ED825168C33:\ -6DAFF95A4C3E781594AC22BE9E9E3067CBC5:1B5E0FD12573752C -BB8FE34DE658F8E9D7CBFCA9EF0D5AC7CC48949FD419663A:\ -8340DED8A3C5DFB4C59857E5C7B066D5FFEA84:D78448EA1E73DFF9 -A6CC24FE20B8D417592A12E4912A131BCCF69B71EE25B420:\ -5EFAB4221460C884D8E84FEF593E7AD2FC065AB5:A960C2DF2037A814 -4373F2160343E9E626A13A3D28B5D9A1A6E19455374A7070:\ -BB2EEC90C104A60DA2CF1C31A1D06B84C58C55B396:001247D9B6B26506 -F92FA72F2295337D949F8F2C34A0CCA63D0A2057CB2E6F5B:\ -A3F7B5142BE18B4F54F828F42D1BC5A3643016974399:E6FF6AD89409898A -06C29E86F4CE77256D64E320F6A6A9CA8A72336469DD1EBC:\ -249986A41700E34D49F01D21CC84059D824E9DA320FB6C:761B7C6F0F783305 -75190AC0CF194DD8620D6E6A664E5F7FFFCB615AAFBB098EF54F8430616767B6:\ -3234B4AF6F4B7CC0527C4D23DC7F22BDBE84E7BE010C2F39:F4399D05D289A404 - -[DES/CBC/NoPadding] -E5C7CDDE872BF27C43E934008C389C0F683788499A7C05F6:\ -4E6F77206973207468652074696D6520666F7220616C6C20:\ -0123456789ABCDEF:1234567890ABCDEF - -[DES/CBC/PKCS7] -07E8E4E137A70F64::FE4BA85E69877F56:C5C7186B1F9CD61C -D452289D1ECBFB88:DD:23FB4CBFC76F9906:550DF2EE0D0ECC39 -5270ADDA7C33A133:0AC3:4DC779C79E31D084:B6B763B034D4921A -215580AAAA09884F:5CA7BE:07AD83CA822CBB58:2FCDEC1E5CCC7DCA -1E89C0730B3ED0BC:7AD95A87:4C66AC5320597311:378EF56C445206CF -4D0B351457FB1D19:F1ED735A21:ACDA801121815F40:4254636AAF235A60 -4FBCCA8DBCE392AF:C284BFF3333A:66105A77286C96F9:4F4BAC49BFEE1523 -101115733330ECE5:3E918010C3A311:FA43D72CDD6A4F04:D8773D690E7EF671 -8996ADE0774169D11A1EF78E157AB3C9:3A913A52D35F6D41:\ -82BD7722A5704C2C:7D59C67162592989 -A0B1C44602858AFC9DF4FF3703561CF6:C4E77206DE7FBEC001:\ -C4FB35FB4CECCA1B:91C5204B300E9C8E -5EEC6084E8EA4CBD226B1CE9D03760D7:C2FFAB037354BBF6681A:\ -6462FEF31CD53A14:15F7C886C55B8C80 -635F4DA9940E6BFF3475718EC80A6032:B38993F0421A9482256C3E:\ -B1F09583E9F4332E:6B3A296CE234FFE4 -6C427B05365CE2C1CD7272F4580FF4E7:FC39AFC5C58A746797C64540:\ -C2509FECD82996B6:FCB3F5AC6122AAE6 -C48B1AED56789C2ABF1DC0A3F0F09D95:006F3067DA4F4EF4294925551F:\ -83FC0D025C2B27D4:8A9424DB9F60DB23 -ED198040B7F952B3B2C7B550B8D3E207:8953C0470CC17BEFDCFD7A178941:\ -B29FD310B15FF558:0D832323132E79B4 -F562D640B39DA7BBC5F7FBD0B84EC880:673D81110782DEB537CE33A0DD8F96:\ -E5F2856E63C54113:EEF1601F3C40CD8D -492862C0FA48CDBDE714A0B8881BC1CE6F9F17E9A2754D65:\ -8F4169CC8771200D0BF3D8F7140AA811:\ -5DE9685DEAE62242:3835A7308345E312 -F5B8D08D269EC0F196BA8BA6BB98273F8D90325CEC83424F:\ -8DC4099DC33743F0E6B903CBE8FFCB7C68:\ -1A99B0DAF28CC879:2AFF0DB963454727 -C2DC32BDDA790DADF329874B09727A14BE6F01E097AE5B1A:\ -6EE8C6C2C73E58C82D58105B005149DEAEC7:\ -5ED0CB977CA524B1:4F45E91DE65705AD -920184D9311F88F5D0725F4F40B066DB6FFD1CE2AA86F933:\ -968F75526E091CAC8BD85DD75AD15D49E38ED9:\ -6C9E8BCC4C9F7B91:21728BE0081A555B -A6744F04F97363A5EB120F09DFF42275092E587B14D12492:\ -CD4CBDDA85C9B9E7DE97209472BD2BCF9182150C:\ -9908A488E9ABB414:958C9C62D9593C5E -60B161ACFDEAB66C476EA55D13116F865687F06CFFD13CB3:\ -F58720F8B80AA229BD7642AD9807C647839D853033:\ -61F2CCFC031ECEFF:9F94F426B4ECDEBE -8751AA8954A97684A06B2BFBB85133B33D3DFCE1B8562156:\ -A95527CFC36EFDE34B771A0370ADB1E49879AC424D66:\ -F8A2DB331D17C3BE:AF6D13D63CD74439 -FC16DDB93CAB78299B5A18D9417DFC5A84565BE49057C394:\ -604570CF9BCCCC86FF411D0774AC6559F8D293BEBAB80D:\ -B8D057BA9652F60E:B23B7F81D64B4E5D -C3BF0218E9F75F284871BBD4D4CC6664D964EA0571FC40B1CA54BDB04105DD65:\ -4149D929BC228216A0D58E880112BE987BC1BFEA70D7D9FE:\ -283320F2BDBCECFF:06C528C2E7AAD887 - -E5C7CDDE872BF27C43E934008C389C0F683788499A7C05F662C16A27E4FCF277:\ -4E6F77206973207468652074696D6520666F7220616C6C20:\ -0123456789ABCDEF:1234567890ABCDEF - -[RC5(8)/CBC/PKCS7] -7875DBF6738C64788F34C3C681C99695:FFFFFFFFFFFFFFFF:0102030405:0000000000000000 -7875DBF6738C64787CB3F1DF34F948117FD1A023A5BBA217:\ -FFFFFFFFFFFFFFFF7875DBF6738C647811223344556677:0102030405:0000000000000000 - -[DES/CBC/OneAndZeros] -79FCDEE6F5A94E74::0741219814F4369E:DEFD8C15FEB10458 -54EC08B8ADBBCA8F:61:113F04B28F2A9B7E:46A8D61A1D40091E -7F5C2A6A9F539AD3:6162:7A1771070C736156:5DB9B23CCE795B60 -F0103B237AC98CE5:616263:C4FCD43F56E0AE9B:23A3C25145BE0D20 -65997360ABB15119:61626364:C4FCD43F56E0AE9B:23A3C25145BE0D20 -34D30333EFB7979B:6162636465:F0C27E2EA299D6B9:933CB62A4B934A86 -875E07E80AD49DA0:616263646566:32B6417E7DC574F4:7B42506B38E4A6E1 -994B8B68EE1B0599:61626364656667:3F269D9FF30313AD:DC044A49A694D3B1 - -C224E73B1564AD1FC49353481E6F5E1D:FE21E07064BE5336:\ -80A21AB24ED705D6:ED03EB0F3FB37D02 -55E901FB4BADDBDF1EAE173AFC8D7099:BBAC475C9BF8287A77:\ -CDCC24E1F5D9947C:EAF397A30C64F5FF -6105DF0EE9CF1EBDE42935D364D6C9FB:8C5350033553101EC583:\ -94DB8915D14857F3:91499DE2964505D3 -690EDC0411344EC2B0C7B41A31D2F1BA:F3DD004162E851F63D2340:\ -E32708EEC7FF69DA:5782AB9B02BBE4B6 -CC613B80C91901B3216AD10F6596D8F8:4C609BE7D7F14EA806AAFB56:\ -4F6A0EEDF83718D3:FCE76482531A27B5 -63AF78D1B2A15AECDA6897AD6007E5AE:CA17CCA6AF2B27A30B5F92A2B0:\ -C26991460E22605C:126CBBC4A9FC3EA5 -A096512FB2DA7D0A75A1DA41F234A83E:C2DFEE0749C5A21378D4506AB8A3:\ -07D0D1AF072F0737:B66510CA43FF801E -E641C41182D543E18932FC306FD30726:5A9450CF73A49F570860727C070012:\ -533571A680807F5E:D0FB32F8A2CB7D8E -9C1AD6A9705F9A72069BB0E4D51A968C2399686815F8DCDE:\ -04184EF5DD2105CC02AFA58B68C2C7F4:ED8250E6E97FA6E4:5CE0CB36A781C6AB - -EC41D8E3AA50FC221295274F65A76330:\ -6162636465666768:9F853348B078828A:1DA8B83A9ECB0F6D - -69E0288D17900DA45557053EE79CA771E90CCB8D28198E0D:\ -435255534820414C4C2048554D414E5A:\ -E3BB33E82BDB2B84:593A08135216F478 - -14D752E45A8D28EAB2A5C8E0A12E8A88E804451282F62CA5:\ -7777772E6D656761746F6B796F2E636F6D:\ -458FD140271920A6:605C41F0790BE4EA - -[DES/CBC/CTS] -1F807F8FB9678124B9:9E1CA14BE6538A35DB:88B23AFD0683D337:BAC170D943D262CE -C6FBE4158F2939D81685:673E242016F6BBA293C0:FFFFCD5B8461A7DB:6D688D63D006AFCB -F09F7DEA21F678D8FDF997:\ -15FC19F91682B6DD84E60E:4520E59F0868DA60:D572977CA711487C -80D4E9906F5E093CAB19C835:\ -07F07F2E6E08B791641A95F9:E6A1584C2D9B0F7B:CFDCEFA5DC5CEC3F -1D7DFB8D1670FFA2FDD99872E2:\ -CC5B006B635A022707AE5674A2:3F2B64EC09DB383A:CC26B1221547BBF3 -DEF7C893EFA8282FC430D92DEC8A:\ -25D30B3604955F5D9AB140C0CA08:41899DF2C47BB49D:E92788E786D65178 -4B0DA5D1E34EBC1AFD0EE115F6D6EB:\ -3736F5354719478759C0AE03FBA044:E15683D9B9731171:6055901E02CC51AA -13EBA3C09DA9A92CE12FB67D8D0EDED1:\ -121BE08F10A108CF04F6BD59F8A80EA2:EB1A14148700BE54:93AE09E97D6068AC -A3F29A3DE6B3D52054CDC85FEAEAD5440E:\ -B394FBF91C772ECF3964975819DDE9380C:166B1D73EC15EE53:477A1026883D68F8 -DF6B5B1591C712562A19631E8DAD95153F49:\ -E2416356E94211935EC4448BE0AB43EE1A80:2F01F85201D1B010:5066B27BF6719D41 -FB7FDF98254DA02C2FF2A7801EEC8CD4B5DE03:\ -50FD46F08A0EBC980F24C9484799EBC2028F75:2CA90BF9C26CCEB4:50446BBB5961F03C -DAF13C5B1DBB958869C0633E8F7EB75646A17647:\ -CF81978920DB7182CF7CA7B5D1177DA83C372C4A:29B6B35BBD8575B3:76EC8D7FA07B8BE5 -87F9684E940E9C410327370A9F10270081B0A5B431:\ -FFE5FC92FBBA432A381F0CA62691AFAD668A0AC192:54ACB83F531EE8EA:9CC628CC5BDEE576 -E2BBA60098114B85838CCA4F1FC8D22A3D8234E0D796:\ -F84EE66897F4D44F882304C3C7D5F630BFD47250B6BD:C562A007017EFC2E:9E4C18CAC2C60138 - -2DC5DBB9A4F55CEB1A65871417FB293A9726642DD02171:\ -3B4EB0E3405E17EDD17856D29AC97E7B6E3BC196802A24:\ -4A403657C2102B99:90474AFC765346AC - -B902D393A62F51E99CBC97B1310830767557835CC56BF88F:\ -506C86A1D0E325684DD23BE8445CDB08D734D6FAA48BC1F8:\ -CAC16F52CA80B183:CFF070594D1A8020 - -BE082E12FA28CEE1F24328D50FEF71C055D61A6B71466EE56C:\ -B03B09966AC8261CBD17E6CE218B4A826B3D0D36C735BE1CB6:\ -2FDF8948B7AD54C3:8CBDBEF17F1B1328 - -C9C4702752294E5C3410071A0BF19549AF90213619754EADA1F7:\ -4D790FAB1374E5387CFC5AE9E7FBE0ABD57F634024BB32FA6D95:\ -6A277A4D5B27FECA:6007E397C5E1B6B2 - -C91A1979FA1A4F93FB8FDA30BD82C26EDD397D91146C044D3C9AB5:\ -01FADB9D549F559E4BD4AABEA073166D76ACB68B3BC7C38E758CE2:\ -E554075663480335:287B947D8D85E403 - -ECAE28210D616F758CA9111276A10D2151E3F7D0BC567D88944FD697:\ -4DF4CF96C82CAFCCF4791A26DB3A55E8FFF1F374020B1495AFAC8B10:\ -81CCB226258A2BD9:48CEEAED7E7D2B60 - -DA5A434A5416AEDE9AD557F48183C32406EA78FF5B3B37D5069A8077F8:\ -EB80E96A60CBE0E7E430BCC748F4CBCD61382FEA8787AD11DD598A202F:\ -BAF7BA1C4F38A3FC:13D4AED7365948F1 - -243B2A015703ECD61FE8DCCC3B216389AE437C0582F5B96493BBEC9B4C68:\ -8FB383275E6F93391E97B13EFC3F7C99F731CB1B346EB15BB5F8DA6248A2:\ -24EC41340744EE04:811219783983A9A0 - -7CF27928B68E2A4CF007F5C740EF3D42E3C86AD0A768C50F65A92F7EF76CC3:\ -A3165F6001A3C69BDACEF31D924F4CE8AC9CC6CD10BE9948742A2E98DBFDF0:\ -A9A60A3BE162FA91:771A271B54C3DBDF - -0190C2294922A17D6E40B2595C9552F0D460F1552315D964818F01CFC7836E74:\ -E6DD056E42D117095F389321E259A004D467096DA28EEA534DC6568C3485B9D5:\ -47B469F51A41EC35:623A5F40A498554B - -BAEFF9B09693512CAE7CDEE14628C39898360AE20BAE66C845D920FE16F6D626DF:\ -4D0E59994E070D66F913698947E4AAE1F3044928F29D4ED59CAD18D24E134C52F8:\ -E8C7568DD459A5D9:F82C3042C634B503 - -B60D0279220B5AC636A861AEE3867B21533A579ABADD3EC5CCB7DD84B23AF3794CC6:\ -4786F439927802927B1AFB3B0DB3C059CA36E4E9D8851C304ABF12438A5F1D7C15E8:\ -5F4379FC61646FCB:8FFD75FA48D32230 - -245DD4A56151DCDBD0000DF64239D4E64CBC9E82878E3465BBEB86F8DB4782565DC96F:\ -12B6CCB90894783FEC5A375C1744BC7E276DF3D21433EC842373FDDEAAF4D2FCB4229C:\ -1B9F7251AF742AF2:61E984D8B88552DC - -3B7598C46993B7046BADB4240143B112CAD1955913073B61E1F77871300A3A4933CE98CC:\ -B84AA9F532EB1DAEEA5332BCAF2402E4CAC762CEB614A686A7A5483AC968FFE6FA84282E:\ -CDE1C86F35672CE4:4B1A4FD4B170196C - -5EF4F1E99D2B142769C82590356C5C69C0B3524FC5F849A583464F6448420A7E1FC3563BE0:\ -16064D069A02CF2F8E05953D3B94764568A1C9A1B12AB56CF1032BEE90DA83A807ED5B9670:\ -D427CDE3D72512B0:DC0C33ED870E2BFD - -BB8ACFD2BDCD37D952FCFB3C4E668AA5A4EAD2273BD6C84DFC0E8E55AF2DC54D7E3C908FADF7:\ -2E682E802242ACD731E439A7392A5F8701256FD23BA03A65A723671920228B34EC6484E53AB4:\ -57EEEBF7FD0D4E18:B88F867E5276A8CF - -[DES/CFB(64)] -F3096249C7F46E51A69E839B1A92F78403467133898EA622:\ -4E6F77206973207468652074696D6520666F7220616C6C20:\ -0123456789ABCDEF:1234567890ABCDEF - -F3096249C7F46E51A69E839B1A92F78403467133898EA622:\ -4E6F77206973207468652074696D6520666F7220616C6C20:\ -0123456789ABCDEF:1234567890ABCDEF - -0CB8929A854E61AB3BEB72CE0F13BA328BA73A:\ -D14FD67A9B4D7B0F65B7CA3DA91741603DA446:\ -7132D895529A7AFF:FA1FE8F921706C75 - -# Random tests, 1...17 byte inputs -8C:14:FC32B875389C53C0:6CAD29F658A72118 -4045:20A8:89D26DA778B3BA96:C6727E943ECFD50D -3C17ED:E13C5B:A9F4D6E479BDE314:271C258E90098CC9 -4B465AAD:DDFB818A:C0DF30CA0DC7B5A7:0F141E7F0EDD71DB -EA6E62D9AA:F70A23F77F:EB26600BD965DE91:6F700666CF4EDEAE -C486B45156B6:73B635137A36:C56CDC1349657886:5883CBD2A332FD55 -3030B2F0CF44EC:2160B2C75B616F:0DDBF5FF8489B870:F9E9C856200036D3 -C6D70FF570F90870:260C393389E6489A:4E96BA675101F1EE:4DFCB5C3570E2235 -966F556D1AB16D9A84:86083459660733A6EC:16ABBC1F03F13DCC:571EF2769E6DBDFE -42CD5A8DA77110EB8E56:300AB25A182F798D2195:DB2807197F31E79C:465C5C1BE8DC2699 -1A6829A79F40DBEA451043:2DFD811615ED4490B9AA6C:97D3995360F10777:B4D324EC37BC140B -D4736432091A2DBA9E7624D5:6BC6540B34674448AF311283:\ -6C7E65D7EECBDC07:2E41B63F4381C5AD -ACDDA761DDE4D7D23065726194:E7FE3DDC6257543EB319DD565E:\ -B55CB5A2BFED0E0C:C290747BAE6C2651 -E9CD9B31E903C3219D3D83D3B01F:1A17ADEB075B2A94777C8EF0ED11:\ -36982D604982EB26:B4AD47CB63991A37 -5501CAF4CB8843D460CE4D64AC9F3B:168583B6B5A1B5E8246EA11E1D5B25:\ -BD51A1B281929DC7:C5AAD3504E6C4BBD -D4FE93AD0BA52E4919308E1273714C52:CF0C5D133700651565A8C1885C1576B2:\ -A8C2FAA4B9EE7986:9B733E3380066255 -E4D2F1241759BDC21164DD17CEF53043E7:DB72BF34A34159D488F9C6537D062C8E56:\ -B90CAF95123094D8:48E6D697471B2639 - -[DES/CFB(32)] -13799E52F0BF6B0E:BF28A5B2F3FC788F:44FD92D1AF17DA22:5EF2AB4DE2C32258 - -BA696D0FEFF0882ABEF2E0BCC543CBE2:A6D36D854511809856A9911919FCF070:\ -5046A6A7584E015A:D006FDD64A63FFF5 -6A837A170812A9E6E1A5DC69AA6FBCE2:19359DAB792F0D020115A7722C171532:\ -B992C4C6A2320278:5AEF500DDD6608E5 -77672D81E388902A764B427DAC586F20:B4EABA09CC71CB3CFD191F20065A1B70:\ -E6862A4F40A85BE4:E743B2DD825BF2C0 -EF7DA9BCA94489CE200530EAFE1CD7E7:244273B4BD388B9099669BBEFDC4454A:\ -C4438F020753FE17:36AF1E8E06E278FB -9B51C216FBAD699636400C962F2E3405:3B9834AB792F727E788C7D32625455D3:\ -465537A2E2167EEB:CCFDB7E38ABF99D9 -19D49D5A54C8FD15EF317AFD5A87EBDE:302C49BF921E0516261F00B2FA2E96A6:\ -F15BD42AEA7F38FD:5E10F9CAF0730C4E - -[DES/CFB(16)] -D6522C5DEF57233BD3A6A30F457A079A:769DE609244B94A8B4E4727736DEA7BA:\ -E1D28FFDD5036622:7A3E915CE8A03836 - -E8E4A04E0F07E2D9:BD4E5489C5CC01C5:BFCA0E11D1ECFBA7:E115ACDCE0EADA59 -7DDE9ACFB699E9B4:CD42413995D601FE:EDFE86AC2EF8ADFE:4ABE7D04F174CA97 -5F803D644DE8B9E5:5D4B3F430AB38F6E:B94861B7AAB541D8:9EE77D9E68A0968A -3421750B8D2F984B:2230CF77A827A379:DCA93094B06CB02B:B7D1CF1634AC7D72 -4FBEFCBE20691E11:AA9DCA8BD9C31D51:6F4C469A7710EA31:D091690C4D0203A1 - -[DES/CFB(8)] -205EFAA6251E7659:C5A1343F4AC4DD7B:C42B0F47482DABA0:48848E073CF89946 -7B0CEB1D343B181B:BABB3F2ECEE17044:01E4B49A4C327C83:7837CB9035139E36 -FC48CB21644AA6A6:35BD7CBB4F42FE66:DF6B71F274CEAE61:8365BDF506BD2382 -7423BC2D230FF167:75648C39AF4DE0DC:2E1BAA1165A460A4:35E0A0149D95735E -8E511E034A21F8D4:6FFC4455799C1A52:FB029C10575CC9EF:DCC44B7A2C4912E0 -6AF4AA1647F5D301:BCFB89E0F3FEF946:468B7763A174FB3F:99057856B861F898 -8BCF14590ECECAB3:8A8907B5BAA3C332:60E50468766A6688:ADC6C30CDD00F54E -FB5984B0442353C5:59A6F97571EFBAAD:23A9AEAF310E7134:809E47BF2565701F -52ED7FC58FCD4DCF:B9B761F8C8AFD67C:E9480E1E6AFBA1D5:23D1BA6B06632D52 -7DFEED75F6A1306E:DB7A16136E5B71B7:C82593A34F75DF42:B6D33655396C925A - -[DES/OFB] -4E6F77206973207468652074696D6520666F7220616C6C20:\ -F3096249C7F46E5135F24A242EEB3D3F3D6D5BE3255AF8C3:\ -0123456789ABCDEF:1234567890ABCDEF - -B25330D1CAB11FDDFF278192AA2C935A9C7745733E6DA8:\ -39B9BF284D6DA6E639B8040B8DA01E469DBA4C6E50B1AB:\ -F871822C7FD1D6A3:B311792C8BC02EE8 - -73AD356623A1D6E0717E838B9344B4FFF21BDA:\ -0C06E63E9E81D9976E16D2009255F917797D51:\ -5860F4A413DE6C68:527A1E050A9D71F0 - -08A6091FA2987FDC682A8199A6D6BD1F:640B5033DCF26873FA8A34DB644F2BF2:\ -3307042DC775035E:99DE32FF0351509B - -[DES/CTR-BE] -4E6F77206973207468652074696D6520666F7220616C6C20:\ -F3096249C7F46E51163A8CA0FFC94C27FA2F80F480B86F75:\ -0123456789ABCDEF:1234567890ABCDEF - -11919B328564DA68D9F4216AE1B4FA7C46AFC7AD5BB867DF1834D77A3023ECAB940725AB:\ -F40235A0B8B2EC0B53F3C0D8799497463638AD0CC3E07F0E8B8B0DC7605AE6AEAFBA2A88:\ -A67ABE525A0E5AB2:727BECDE9FCEA20A -168A502D21D71F3BEB702BBF02D3F6D04B72EFF2F19EF01D217CC7AA739A67466AF3B14E:\ -3A73770D157C23EF8913D874CD92DD36C465679B2BC691DAA0DC6CD4591C4CA44D5D69D8:\ -CDB366CCD621D62B:1ACAAC3F760C674B -24889A268E11AEF80852C4FC4893DBEBDF4CB06115FD533650CA39A639C659F47C3D5556:\ -782B24067A2C5D61BF6ED2E980F6BB16A0A6E0B5639B4208AE273C0BDC0311D65464F217:\ -EF510AA740BE98CB:74E74E01E5C72084 -3078866926F75D18239A3DA92EC9EB88D18393440B47D46A49D003F2C3B5D51C1CFE3FF4:\ -DE4D9632BE88235D717B36DE4C67B81CF3331E8925726CAD1BCC05126B87A6CD5D5DE3B6:\ -E8CBB756DE4FDEB0:AEE751205CABA9BE -4602C97A25AFB1746DE8BC1A65AE0B635ADDAB9547A99421AD86AFB087997ABC1458F0CC:\ -754BD27902EE4248BEEE65D2BB035C9139F98735C85603BA9565EDAADE37A7FE29833DD9:\ -B050B286E47C6E6A:701F72AE37D31F2B -E344E0C2E45990C451C75BF74406821B99D4EA5F56F67BB2F9B0EA52FF5D1BB25D82A181:\ -1A23AD101A776F902B8DB40E273A1F5EAE8AA1E43CBA52546F2EC50EF32960BDD05101D3:\ -445A14B76AFEFBC0:EE2DD8860B75788A -2C3A117378B8DB1287CE8FE084EAA08EFCEB253DD4A92509EAD154E6AE483E25D2B790B5:\ -75235CB3E2BF7DD3ED893DA93AE25D7A34D43521DB620E2BC9072159357010E6D81E5884:\ -4B1B62B9D6B8F54F:036CC5145BCE2A01 -FBC7E48930ADF4A36DE18CABDE25ACDAC8F9AB727E3AA69FE8EC6F965C6E14EBE9AE437D:\ -B271913A8A58ADDF3C89132A15DF1263B63018CC8EE6763E6FCFB4DD5D4AA8EC4B3E2D78:\ -2E0F06AE7B1C30D7:05E144D6DB9E7939 -940C3FE78C56A0F922FBEDE7ADE31914C993BB84F5BC1557E5F8004CB75D7D339801FBBF:\ -9615A71536135E50946A8517E72A980CBB2378A3286F08E76E85E5FB62140C9B3720C7C4:\ -E6E85EABE538195C:B86615CDA5C9E9A2 -256ABA748AE0005A5F99F1C96F8A197E3867B8455A4D6BFD6795BBDB89062B222E6B0DD7:\ -2A6B043F07ACD99141C7AC616B7F89AB7E52174A41AFC1FD0C56BC77B9C2EC9CEC87A0A6:\ -9985CE7E0D79CFEF:25D1D57C3A6936F9 -44AC3E1333DE5CD00475317CBAD26AB4A812180DAA7405556C41335572F5A236C37CD36F:\ -155E5B86FC06AD433DAEFA05C329BC1407966220BA91EAC2FD32B35C5AD973D94A0B8792:\ -47550AB0F346ECB0:1C42F4559385E11B -9DEDC376CFD97AE823AB2E0CB0072DF26DAADC4FD9316C7E8F4F796026DA9ECB8ED69DCD:\ -EDE3E69EE5B55AC758EB39E70E6533CC4D89C148F6AD68293E743CD82B9638F020EE589D:\ -098EFEE0D594C332:88D9C46E992B27AE - -[AES/EAX] -B39AB9280E8E75FFB9A6C0423D94237757:A1:\ -32942F082B82885F3965397EC13315D8:79E2ABF57EAB5DCBB887FC38069FDA38 - -F28FF0575837BBF9B18E1AF21F086271224BDC:DFA72B:\ -16EBB23CE362FE4F9D75D7FD330C57AE:13A112FDD1A803DADD153FCFF5E6FA0B - -79B15D05BD1198BCAFDC4E5479C94479EED48273:8EDCC43E:\ -5D83726C0764B9DE12E97C81D925BD12:E2614B57C71FC5DDE11AB56FF67AAD53 - -6CF9258B79066C6D1D3CEF7DFDC07F1CD3A2C456:2CCE2B48:\ -898EEA34047E0896A49BD8EC9E5FEF10:86B46B759E771F7DD2F5D6FEC401474D - -2B098DF40219F5378FE910750AA62597BCE7F2BF91ADF6AB8933C113F81E9488:\ -C202A2C43538DFBED961D4C6B9628E3D:D41C09CE65EB3924456360D76B78C42D:\ -7A67F1AF9FD16E7832423FEBA5CD2879 - -3592BF54500CAEA6CBB6AAAB7CB3BFBE::\ -CA0F81BA5479F3B8AC847B7EF116C2A1:29D2ECC2C99C3676E7B9F85AB3B1E57D - -4DA9BE08E753EA123DEAB8DFFBA315DB50:B9:\ -D71D44511C92B390AC9C7961506D9E5B:032E8F2C3E7E0B152DC087E20FB59CE6 - -178CFF2FAA32FF902EC92AEB5B30834B5758:0ADA:\ -39F797C50D5BC13FE895367BF2ABB56C:58399D9AA144C8236655F51D81FFF7BA - -37ECF2F5E41D4DFDDA3DA85F1D82A3767E8360:3CD5B1:\ -DEC57BD1A4D6B9C0160E53492DEC88C5:3D60B53B4A64D1F9B6802AF9BD00AB9B - -3165D9ADB4E3CEC0831B85AF88C5787C0D145A92:09FEC8F9:\ -7A09C4F9265809EDF4BB32E3270D6F46:EEF79DD485F69FA5D0457DD94345D2BD - -05B76D5CBE49DE233B6F62E4D87763FDD0A210A84B:F3C0EAE690:\ -9FBD4E3CC8B0B54454788C5B68AAC81C:2F0269EAF6708D3B1B332EDB1E146BBD - -FF9CAF05A8107C410BFCDD14E3852C5A76F8EB5C116B:1F31923D5518:\ -85ABF08534075B6EE35AD7C550794BEB:AC962D0FE55AA2972BC2C8BDFF1ED584 - -81655A74F4F64E21B004F3D04D56512A7D1EDCB9B20200:C7C8F67C72E962:\ -170247F224B15FE3D501DFDB21EEA1AA:46FB86732B98C18460897ADCFB643E12 - -D81940ACDFB353AF804BB411C6950BD8FF9E15067B406830:06C456B3B74175FB:\ -CDC09E48511B3E38B75D14EA069BC885:CBF80EE76101BA67C5111A7C528F781F - -DE25F7B65F16113841D5AE12F80A1744A5F81B09EE5D29240C:0B2FC9C8FA81E7198E:\ -165372615FB7963B7A6E59364ADAE29D:401A0B4312344F41FD173B7FFF540D15 - -BB873E2B7A879E53F513F1834C54853FC2037D9893F65824CCB9:DA2057C6401125A5808F:\ -2F32841E15A6A883EC5CE8032E563BB0:B33743A1061DC15DE3026E09A7EF98D7 - -304864E3B8DA2359BAF5ED60C76DB298E2C12E94D18FC615F934BC:20DA4B54F8EDC93EE5DF91:\ -AD94D86D3D05ACCE0FED495B6FF5F23D:4DE497550471A059698E22A773013821 - -8CBAFB5678D47121DC5F0CABA76F0A1A306B22C19B86C883CCA36F39:\ -26C2C7533B8481560FA3F226:\ -9D59713C92F96FA1CB0469662541540E:B4AEC9DB70912EAB15AF012552F44BF0 - -7AEE2EA671EA8B5F25E99F000D181CBEDD36BEE605D35BB4AFE833CACA:\ -C0C7FF94C3588CEB45619BBA5C:\ -B98A22543794F9DA5C3419BD9A1FBFA3:CE98649597F858EF844335E5DFEF4198 - -D0FE64F8842CF1A4C0750C6F11F8364E72A23D80D139900C9883CCB64090:\ -924A4112C3B76FF98D45355A60A4:\ -4AFC52C6B9C20C594DDA2CDD347E72C7:CF05111017D4C887CD55CC02B02DA6FA - -CB869382EB0644E9D00736793D5E19A56799CBF313F87EEAF28B7D997FD34B:\ -B545B07CAC05C6ABA080EFE09F1B58:\ -4AD8D6A4A2E9A16C690EF49ED125F92E:DA3EDE56EAE31D96839D85633DA0BC87 - -E267E3C9701672235AA5B69C6491BB54CD490FE8F99A6668A94AE6DCD94035AE:\ -DB210878188D2D0A9E72BD7C674D3F5B:\ -4D3E720750529D0F513E92763E59A31A:7BAB929338BF9DD7315B5398A892F3F5 - -861567E2AD28833FE5B6F4D1A37D2D0D5984FB4EE2FA0AA91F7AE9BD7D24231BE5:\ -C1DE878D368F80A87C15BDF8A40026FAA9:\ -42353F4A310C9A8AC8C8514C792E0D58:B69A8E451A37C12FF4B9D3F4E0CD9D22 - -AB6C088C4E0C0EBEC2BCBBC9A98514B05A445D563FDB50BD62EB2B9C26958803A297:\ -9ABE34A69F182DCEBB766EC9181F2E083382:\ -2D35319C7307ED58372CFB6712952547:3BC55F69931ADF01E3F72111FF54942C - -C3B6CD7D76EFA2E354C4E8F7304C7075E18768F4289D7F3836FC8DE15474C7E29C58E5:\ -65CD9E4A150319445A8C66F02CC3BF651E9FE1:\ -3D837364406414252F703E8CD50B2A1F:212D386588C4CB78F08E3756ACD637E9 - -670B848D3BBB52E923AC9BCE4317E68D7962C73F3D467FCF5924EA7A3C6A49C815D7265D:\ -B3DEB5D5B958DFF8A64ECC1D146E33BA0A261A89:\ -CBA99B5D4C96D127F5C5B4A8A3697E5C:C25D5468AB2185C08FB97A99DF9522AA - -7682A2E42D701828D7DE633AC10F944CE42E00EAF52316AB023662E4D8A7FC16C1D06F7ABE:\ -D1B17D59C7BFD0F0E77B8EC21AFA78018B2ACD11A7:\ -CCE8F486487E7A451DAD16CE2B6F96EA:4086D1BB1594D50F0CD79A36A4ABDD70 - -F083A6CD239631E8CF3055108CE5BC491F57DDB5F57C3BAA188A12DBE43F1670BE36BE92241F:\ -A7AD209830FFCB8A89F2E90A5C4F57E3AB63559A0FEA:\ -C4EC64DD6D082CB6B2D363D26B94D136:1E5B2907658557BC690220BE9C2FA860 - -57FDB6E005621F3F5A23049803817D8B2982C20C3504B0\ -BAC825269431C3CF68D51A0E349E5DCF:\ -F6C8C495B93A0AE6F61EBA1773F05D7C2ED4B9F17E5E16:\ -76A0D567CE9CECED93B5B1286EEB3354:E1510EF8C5FF55412D29FA1EA758341D - -8BC73BB8EEFB46E742DE9EA40226DD48755B1049C0D01E75\ -47FC1A6537B61CE2F3573496F291D016:\ -F7012F6E6E938F7529E7905ED045D0558A5B168B3C6C815E:\ -E8280E1F06468BFD47BA6CB54EFB2A77:E3BAD5B3FFA50889001F143D8B959B73 - -AA1B16CDA20C35A84D0B7F89C4D6E9C061FC2469080F1AC929\ -8590EFDE1B39474005CB319B19EF3CB9:\ -8B8631197B30C7370B7FE540567D2CAE5C8E6053DBCCF75162:\ -7F52829F60F32AE6244462540B99608A:7EA0E1FCCC8F585BF0AB36BCA3871F22 - -6B2F99D7840808EECC6CC70DD6EE11038906EF6EC8C8B49BD121\ -B5199B440625D00CB38C327597AD9573:\ -F650F5F428CC5BF6B755CE90DC86F46A7DAB41B1CC9E8243A731:\ -A42FB43E3BAA8E309EB6FCF9ACB34F7A:432B0037957DE2D72FAF75B1F21CE296 - -FD24E4137BFB0BAA260C5263FBA35BE28E1ABE1928F2AA55C192DE\ -C841A8D08639F4721712E1CF737E9BF6:\ -0146825F3EB53904628D652D59F003EE604971226BA3BA2E8F3DD1:\ -552308A6244E28838DDDBD913F4AF76C:A3E7709248B9036A25A724533661258C - -52F6DC00BA21BF0A0718F5F931822EF23C94ACFFEDE0A7BE28E4DA74\ -6246F6B89B5899001060A42D0543DE26:\ -CCF9C55515CA3C5162D3847DF2C6B318314444CDB8AF9C34E985E351:\ -D209AE9F0273F4173E3069A004ED1DF6:B3D10EE41552B1CD024E02EBD3E53CA5 - -4A87AE20CDD8058A3507B1BDCF4AF6737D38C40F8AEF647DB8158D503B\ -E3A1C394C7438B171AB4E57CAC2FE274:\ -CEBE04BEE25C79D6167B220733336A5E2D7C27E888359C3D6F1F01E981:\ -FE034FBC070D9E6386757A01978134CA:EC92F768B9E0F0EF7C2D5E9B2E471C2D - -1D8B38719B5032629F5AB5B6EE59C3DD22F7A48735C5710802DF28704836\ -F8244F62E56E0E12479AE6C6EE0BBA0C:\ -C3D1992FB96CD9A6F3668EB54276600EA7DA9E9D3639C7CDFAE556D851D8:\ -9115AA2A4463971D0A8A84983FC60EA0:D4B67A7253B0AB1A7EA5FFD47D51AD0E - -6D030D5AECA8239E4BE536F5B9886AC6F38FF34B77909FDFA81C030348B701\ -3AEBE5C0889189A4B2F3F2B3E06A5DC8:\ -5BB719AAC1999824AD9AE817491AE0924A56628A895DA88EAFCDDBF5F32CB0:\ -4FE3C9F9A56391C9102BB12774CB0707:165E69A0E7C648767516516A097E1A58 - -C932628CBB4E53FCEE5C585F04BC9C08::\ -6ABE1356E6A4B484E454BC488E108979:B29D87C2BD94CDFD94DBD318309CDE9A - -C712CDA7CB6CAE9C067FB1006B33A740B7:61:\ -AC7A66CC944A177467DD30EBFFE24344:4034E0C5EF7B49AF710B8B86BABAE767 - -4BD4FB492AF9296BD50B0338A4D80BFCBFAE:5EAF:\ -C41CB4E2208A2AE49D59313AA3852A50:B23B3A8E850C41DC30448304C9E2B38D - -944500DA2B82C64DB63101760FAD9B04B7B5AE:8D2848:\ -CB5972D3FD65E49F000D5754664E4209:69C9F9FC392CB8055E4C52BDD97A05A4 - -EFAF16EABE3320C8C650AD585DFCBDB537E4E5A1:B29B9A22:\ -F57E5FA4371F40528911EB3168011F36:ED4B8BB9B6635CA38F871E4122B96318 - -F48C1026C094968A52983AEF848644390EF0AD887D:1D74EA6C4C:\ -13EBD6907963AFA2A38725D1C584C40F:809E32023528D14D9C626A114CD65D5F - -8A60BBDF08C42353DDB7932AECEFB220D692A8E8DA2B:44C3EA4929A1:\ -D5E9FD2260051E900851974AFF447B15:467F03F57C4A071F4D4CE237950CD86A - -BD6CFB5269FEFEA13CF4E32FF4CCD483A27B8A7A1D1B79:4928D4FE0CA3B9:\ -8B5E6F2B0EE6F1239D9BBDB7AAC91B00:7F9E64B73FBD80AE06A88205B425BE3F - -F9A4A1646EBB784A59D7CFCA193B3E9C2527FD92542D0006:44F885030002B7E4:\ -7065E368FFBDA1905BDEEEA754C0D5F5:35E4CDE820A334649BB9679CBB1E802B - -6896B0857D444F64787D6C61B71AFD5DCE6B9B143A1DF9DADC:5EF4B47926F72F4C43:\ -E6619897C6063BA60CC799EB1A05729A:D8F3B9E8F6A746EA5BBF1053EE5D96D5 - -9F75767C335CC510E6C814189ECD49E8841F84558AA47D491263:\ -90E00F618EB235500F89:\ -B64A720D683731BAAF132D6DF42600CD:98CE0D42969D23A5FEB158330167BDB7 - -29CCA4206E1C37A5BBF518BADCA66A13C0EF15C354C63CDFBBBC1F:\ -4F332A5B8C25A9113EB2DC:\ -FCC2E4AFFA189E41FCF0459C26DFF44D:CF12F4E161270BBCB33065C56F17A16B - -1BE9151414493D890F745B9C9810C915C679A03EC472007E07FFCBCA:\ -8A000D4EE11C4E34F75745A1:\ -29A10586F8D97606B9E41A679C348050:1709BBA10AC8EFEBE43E20DB95657CBE - -DF3DAF8B27B621FE4A580417174129C2DEDCD57170522DCF082B122707:\ -F5E09BB8E5DBD03E11BCB8D472:\ -CC41B73738199B467196B9A5D6D39682:2904770A9F30EF7A002D8CBCE5602FB1 - -F9A7C4844697FB986EC79D855EEBC2EFCBC7720F2A9FB9CF74213A49FDA2:\ -FF6503CEBD39F306CCA42EEE8508:\ -9BCD3AF2077CECB7A2FFD54AC8082C23:0A2B880DF94646EC4C12907B0016839B - -8ED7662492F58987CE4FDE4229EDC77BF0D32EC9D8F9B048F7846A34D85A3F:\ -449CCDB5F645CD9637511D12F0A3F0:\ -506B94A8633D7873D6C4AF0C6908AEFD:4D4ACB024110D0D74721F45A11974A61 - -BDA3847797F2B5D97A2E4B1F307B865E4F56543BF56C50BBA1F6020E91F592F0:\ -A66868B66D2467C7216A6338DE8FC825:\ -ECBBA42D11A978A354AE97A093300139:9869EF068E56CDAFC131E79FC0B0C5AC - -532AA827573A33F5B81E62BC9DEE898537A8ED67239B80CA3453B71020D864D90F:\ -037B870E75AC9115506E09A0230BCA03AC:\ -B72999FCFBA184A8B895A9B1FD3DB478:C5C2ED715403C2C20C62E5172DE9C3E4 - -FC2B9B937B6A7F4C9A0DB15278C5CB8A7BA136430DE5D201C66C50689351FC237BDC:\ -E71ED7DFF82A2797EC693B182D313B08C6B8:\ -3DA9289752DF9B669A9D8AB66A71D441:50CC6B776357E19F700ED0AB17966354 - -56CBFFC676262403ECAF1BC51C3D65E5E1CD293BB5B12546C264C79891160300842334:\ -3D4300526204967051D76410E3143B9C17CD80:\ -37AA0C11E0EB1F53AAC3EE8500318553:9489E904DAC168EBA47C264093F3C0CB - -B24D05663B3C762D59AE8B164047EAACE87695B82AE57520E0C87A2E6D1DCBD4407F4090:\ -0A22454378AAD07A5A541ADF20D54664BB7310BB:\ -8ADF49FC3784012C38A95042CC968544:4056BE9AAAD879CAADBF2E68323F24BC - -C79E13FADF1F05C15D7953D016FBAAAC7969DE1AD696F802231D449176C2DBB6BA56467B27:\ -FC30113613A67D7C64C63A8F8B664650ACB6DCD00A:\ -6D5300B815CB728A792086AA32BCBDD8:39393D0074CC8BDA12DB86C8B756D224 - -FAF932FE8F4422C8BECCB00EC76DA79257C56E1EE4ED314A0A1075D952CFB97621D4CF7CFE14:\ -0F1A561E0B0F7C0FD152926D0F90D57384D7FFC38D4B:\ -D64CA6972E6F91E7B2A00108BF0C183B:1BE98EAE579D3E2C10C2030F85905A5B - -1F09C21297176C1788562A8126B83E0F0CE3FC15309E6C5B46EF97E56AD125:\ -966B82E2C328FDBB167D085DC029A6:\ -274BAD60A536DE7D916F95CB2175AF9E:0B1B20EDDE48EB9A5E68A2BB28CC614F - -23DDEDDEF95C0B28FE8D5B305FD83D52F442D97D465CE637A648EE04578106C0:\ -5A899A3B0AEC81C95D7AA595E2FD72AB:\ -A7B1C1626B3ACA26D2C216EBD618B630:A1506BAB3DED749A67192F4A16A1F5BD - -7985DBCD7922D326F9C06DC90E0FC7F518A5B7B11C155EAFBB9A708D6E10CF9440:\ -A73151592F0952CCB9723ABF53269882A7:\ -F3D05C6CFF898C80E2FEC0CF063A7737:8CD0669522324E946D0EE793A6693A9A - -C843A2352EC2F9E40094A80D3C7B00D56F0F266128D4EE4CD2AA0EBA9FE98A21D4CD:\ -543D2E144B36DF48A1083735244C91FCC30D:\ -79DAE3A9A8D44798ADC660173CB4556A:C9A0A0A8E941B02077D56C08D130154A - -5EC8F04849BF9E61A2145BED2003B1784694AD418CD2944888848D03B16D717346359A:\ -3F5C581B378124D866EE6046CA54DB45993CB5:\ -5487234213607058995B0E949A6BECB6:A26DDA7AD3C8DA19922EF4D8C7308D1B - -7EE5D87A59A6B11072123E7B728EA99A0C89E3F4EC9D9E6D088D09C57F77ACA82B6B36D9:\ -0C1AABA9072AF4CA02D6AC2AD5B2329523AD8C7A:\ -8E9A279E45508D14A43293B14D3F5A54:694E1F6B24CB95F97EC78EA1751B1B03 - -83765858587AEA004B2D98A3E1841DAB06E251E5AB455B6E7434889B014BA4586ECD354880:\ -829F5237301335F035CC410BCE75C4C2E89E8109A4:\ -D96E6D0D53061BAD69902F08E26638F5:9C292B686A3637DFFAF9C7987AD03D54 - -15674158151BA6A84F7C8937712D65A5B4F61325685A19EEED471E2CA7E2EB43F15CC2DC1D36:\ -B9D5B9BD05F145CD977E358D799D637F093D797D8378:\ -AE3F3D269BC1B851DC7126952E2C8774:F91EF22FAB6BCC0EEAD54B6353CFDB01 - -4EC14FA09C85395DC42D807C64B052203FD889907B40E8\ -DBEC0AB58A1C92882CE226770FC4F5D5:\ -339431576AEE57FE6091D148E5F6CF7827F25C131F2CE0:\ -7CDA2113620FC51042594199C32FF1C2:8F8293D76789A6DFB1983BC4B868A434 - -3A1AFFDBF58441C6CF36D4E40A7D2DF0170D1EA2B99F53B7\ -37814376AA1BFE8B4E09363225EBFF25:\ -0ABA7C2506C0C304711B50BCC699B7C45F3DED61A794ACE5:\ -ECF144123590C83F4A44655005285576:43A532093EE9CE9E26BBFFCE4FABB33B - -7F3D6219C09BD6ADA2C02A8E7A6218E070A2D065F68BBDE76E\ -8CFDC872AEFCBFCDF237D789371BDBEA:\ -404C55DA8B61CAEA5ECDD03602058A07F28499944B86692B8C:\ -DFA17F19D8CA59241F34AF81FE99DFCB:6A15CD6F9FD462236DF66FF4609A803F - -A4140A86D0BC3A9383C19709D2C4E833F3474C8AF0C3DA63CA\ -6ADBDE7BCBE8EC0F11141C4D0E4415FBE1:\ -54B2BCC0182145BC510319425F6AD3B10A1A9BEB65C04B32DF65:\ -3B0E2A90CD7E438A3F5BAB8417FC8730:3EE79A1198A52B339091F3DBC3D340FF - -2718AB1822C8BD9DA39B479402449CE0834BC1616ECC3F1308A24D\ -EFA73CB7D1FBCC310686AECBE95F7532:\ -1A392F066BECDF3F15D95B92098028FEE4310A283094A3A81CFACF:\ -C4D21881ED51B0F3BD9DD2FCB2AB5744:B5D76DB3BB9EBDE3CE5287776E814632 - -1A6C33093FB3931CEBB1E7CCA95FE93B135F8D3768AEE395FDDF81A1\ -C60D528B0BF40326DD56FE8ED50F158A:\ -15E86BA59F0E3D5AE3A664967C1BC3F6022B8DC12986DB779273BBB0:\ -ABC25FC0AACA664AD9A3A4BC490952C6:2415BC27414AE86AD0C3E163369C13E1 - -585F73C77639D0DA807CFCEF82DD595E5F57866BBC2F619F49612792A9\ -6C2E4C739BAA2220F986801C95FE12DA:\ -7C9C82DEEC159CEB4E9890F0FCFF5010F9E574362A3D6D06B2147BD18F:\ -14440CB0C6EA9CDB8687291E181A1B17:6A2B104F9F4779DCB47F8FC8FB60580F - -F942097AE0852BFC7E5E4034BA987782575056C6340177427F61E313BC2C\ -A2CD299779B29E8D500D5B8F84D6CA5D:\ -7D4A2EE3D0CAEBC205B91F090E6195C472AB3C8F56587625ABA45EC236B6:\ -2FB3005D96D02881922D3BB1364912CB:0D84764913CCA18AF14C2E4F0E64053E - -3EAE2A7691FF14A55BF3364AC597A121FDA3816505447F6E656E6F90DE370A\ -B2F5301C67E32A4791273DC653CB9062:\ -8B64BB53067C0A54A3CE6747467225AD9E3C853FEC39257D37A9DDADAB277C:\ -368B378A91B494E657624D9FA8BFC456:5E00DB9DEC14C2694C6C46F9176D764E - -EEE5FB0FD6F649C34C45F27D661EF1148620351502B170EC1B0C677569FD210F\ -59C137EA5A5C0A:642F4682F88B96C3CF59B2E6FCD637AE208CF5C909ED77:\ -1F9CEB36B1C443E828722EAA6ABA412E:899AE06F96B7A644D73239A03B27185A - -A75638B27A2F4FE3582D82415D92D25C0B1619CCF369A212\ -D3821CD8268A2861E684DBF033DEA847:\ -9B20A4045D8350AED236E92ACCFD43608017D7CE19ED43C8:\ -923874D1FCA7C997C86D9C25F1ECD3C3:22BCEDEEB9304E3A48250861124B2AA5 - -DBE84456BCB905B3637422CA28EC7A35AC31EEFA1BF37A7487\ -8755F2FE39C2D2B2DCDCB2F31450E800:\ -EE45AD121C59A97B8CEBCFFF2BDF5DE934F0380DABC2BC109C:\ -F65DAEF41041E256EEF472479EEDD489:BCD3B49B309DD021D6DDCC989ADC3490 - -690F6EE8335B14038CE0C4503C2BB83B7A0198BB4CBEC743D187\ -F18DFD6D02E879B2FE69CD0EADDDB3A2:\ -40765E67929DE7BA3ADCFAD278046E20484408B14FCBF9CEF874:\ -6D3FD9D7C1194E1F80E0BD679AF74494:C9BC9838DCE17CE592CBB08B99A80007 - -D9A4B214F4E32DFCE30964284BBDCCD6BE6EE0189982ED45BD6CD0\ -64A073D0E97D1B750008C05466EF09AA:\ -45FF5A1365893BBEE1B34E6A127E4A73F8AD5BF102B15B346F23BD:\ -9CC43DB3093D0D1CA2965760780AAFE2:1D2D2C9025D9EC16DC9D72100D95CDA9 - -1978FD1154D9855E614E6916EE875ED1C938F9CB92D57E582D74018C\ -EFCF84BA0767344E0F4AE7D283DB8D89:\ -B81D674F959354838BED29ABDC7E3F7D8481C96CE99D67E0E4DE000C:\ -EBC521A3E388F3781C47FBA734245210:A2918D26125692FBF3FADBD7D8DCE4C3 - -43BAF08789367FCE02931A495923920B1220B3D5C80FAE8AE5D971C7\ -C325A84838578241E52E76B684EDD3DE73:\ -69786524F6287A494B81812425603368DE8E50EB1E437EB6EB478B163F:\ -4D5CA9C6C1CDBCE9480534C98659EFE6:8C57C41BA7AF39EA2DEFD6757BECB4C8 - -47D494E426676CE2F7008D773DECA0F70690502D89853406C6D7D2CCBA89\ -6CC0E0AA8E3F23E7F7DE8470305BAACF:\ -15C0756699C707CE22491F8EE3798CEB43F07A9C654CC5B0F6B1533BD430:\ -47E9F0BC4F89835757A6A0773483F0C0:6E33B1E8D0163595C62B4719661B49AD - -8F3E66BC1A646352B7F4CFF7D001CD9B86BB808E3A87DEEDA3E8B68C7B8315\ -D03ABB22AB91A9168498263FBEA483A2:\ -EA377982769604FE3A32422CBAD2D886D39B523DB489319FAFF15937C21E13:\ -AC558C2ECB2332C95D640B8A1FDE62A5:B1FDF8EEB1811F513010AA67D2C87B7E - -40310341FF81EA8A88D7E4A56587AF7C::\ -59A8A96ED2E623F4E9D947CAC18DC990:79674D1D63FCA5D519FFDB6C296F7082 - -8062337F189B40867709312776BF2EAB16:E8:\ -15BF347878D67E708238EDA55C887885:203E5B72637E6FA8A1073FDF3B20C750 - -01EB7399A21FCDB387D25DF865AA6BC1C267:72A9:\ -B896C67E8B41B87260D02A552F6308EC:5246679BC7FBC5624A8DB7CDE1297699 - -5F88883DDBE73A2F42C189785ECEF40C2840C2:015060:\ -099DEB942571FF3B10A92A6E906FC2C1:C2CF13025EC6D16B82C6284DC779ADD0 - -71EFC1445B39BDA3653BC6782E63CCC3972BF760:D82B67F4:\ -29C312A40B053890C346F9D28115EF8B:1962F49E4AF7703CD8470CB07373A49C - -8D3954997ED9F3520F6ECD1C9BC47DBF1C6CC57D26:504F42CE2D:\ -2988D5019BD60E616400FAB5477952A0:5B4054DF62AF337A438CCB93CE99C0F7 - -24EC9189DDB36C88F3FB33DE3ABCE099E43AF40EB1D8:611330C7AEBE:\ -561DDE748B1FCAE57C3DEFCFDE0271A6:83737F42C2AA4BCF18ACE248749007CA - -2A9BA364F8E7F57EFAC8109B1E03227934B549A3A0078A:298A24AD7D6DBF:\ -7BD999B1F33A36193E4EE6F028299388:BB9687C2176C6A4595F56A4272D701ED - -F6B6A2F6E1510711ECFC957C93C68919A5A45EE3D0B2AFD6:75FD2D40877B8432:\ -6D74EA617E714D793C8DB9395A49C63E:F42A025EC9BF043EBC317E44AC02761A - -0341E6D787948E8BC9A17F8B9A59590964FE0AB06987334169:0FB90FB34C5B9BD476:\ -2FCA567702AF585D40A48AF2DB191901:94FBCA24E072339981E6E6DD82BA53B1 - -2456A0634E033EB2C782A76127638297E61DA31BDA1F54909D3B:B3990AA14BEDA81F703E:\ -4A15134D809FBBC80CF4B079EFC6D4E9:E27795C82349622DEAAD1A92CC8AD116 - -6ACDCF1AF0A6C75858C37CB6320AB22BE515CA582A1F72DFAC1097:39829DB0BA6AD872DCAE5F:\ -B8457C4211064A0C8B73983C6EDBAFE6:883F1918789BB528561F00C8FCAE27B4 - -A215B0BD9C58AB3331F78C0EB238167F27B1AFE1EA4BD87CACC5B300:\ -F6C41B2D43AAC7F4F0DB482C:\ -1827B62D763ACFA140874AB706C80FF7:7BFB0171BF1C9E02C666F7B7413FE359 - -C2AE1B5AF7059EA891A6D1D467AE9817290A893586356F79C7381BF177:\ -9E10318744C56A3008A5EC8515:\ -1649066C2B19B5E549F90C0E0C0BEC53:AF08F2BF3A7904FFE4340889208D9E36 - -4F26AC6346CB5D7A8F8AA5FE8A3F721ECC63A3DA914B1AD48B1B93D22635:\ -60F4F38483E7AD0025500B8B437C:\ -FFFA2092F276F4B3FB5961F4E8059C6A:91FC5F8480E26C2DE2917EEE1CC16A1C - -EE5529B4F23A6D8B6D4A6116F512D755E38F05295A21E9C6B5239558FE06BF:\ -1589266048285014F882E3BAD57831:\ -94A5B81B06729AED640D236929A28F13:B7183917606167755AEA5814BFD04554 - -F801A572F43609E21B1B2CFC480CC255B6B3927C2B14205DCBF0930E388EA229:\ -EB0E42B7343D3A6EBEDBA8A6A049CE77:\ -95B69A2A04B2F33C552E7960EA802CD6:8E6E8DC2ACC7316AA2D9104322DEBAB7 - -F880860816D3A071426469345BA44BB27D070DF896D9AA2581A1D89689B56B9668:\ -D8DCB87E15D3BEAA03F05B2C77AAF23535:\ -78D92F1F74591CF5628909EC20E2C4FD:9B43126E01BD71F1189E68C2909EF708 - -F25661B5CB948FD1B2CCA4A7B124DAE53BBBA8FEE464FF95109DF4D1E02E4604426F:\ -AFB23921379CCB087180CD8A614FB6FDB2B4:\ -B16386FE78B6316264C22DF9DDDCAB17:FDE3B3C8EB2448B8AEA90764A6B91858 - -A900370A2EC7AC2CEDCEAA2C255294C9CB46D6D97131D8E1505F7B1C4340F843BD1CD3:\ -71F1F9A2A4A33361417CB1A99ECCD83BEE148D:\ -77A9689AB5DDF5645E678C57D87D507A:21F3AD82342933DEC7FFB603EDCB9064 - -BD005D094AC438EDE11B7D98482155DC8E86C614CB13D2FA0CABF8D2631988444A3E5D97:\ -AA6AD3EB14DA4E60BA09A9638DCE91CC31A66830:\ -CBC59EFCEBEB74619CF0AD465B81326F:5B80D015897978164709E279AF4AA97B - -57FCB6852E72126F5DB7B311D1CFFD5D879EE6E2013A1FB568CE1FE61A82F712256CE617C6:\ -A5E672D7BFFCADF0F12C81B2D06DA016C252D54522:\ -FF38036E82ADCD2EDBBCD4C12EAB802A:58701C85F1CE555E6F6B21C14066E33F - -A11936A7930617BFD935B7B380E052AB245B5EBAF26C8E7E55F28B9B1FFEA3BBCD3224F037CD:\ -A80EC62DA758DC5378B0F4E98DD8321C1D7E59FE55F4:\ -CA603873A7C460A7C409B58A365CE212:B05AC2A4444F7C766B9AF4C49849B862 - -9DA94E8A4F0D70643357D8D8C9B31D85::\ -69A8B04FB205D3FFD56C34E2C76E0D35:11262418D091320D2C04C8D0E810F751 - -7AE167B307C2F4DF79F63CF916B9BF1A58:25:\ -A3E94A0B4499F368B968B7C6FCACC234:025F7513BEC5B9744723A9FD4B7522EE - -C02B328AC966D363578406EC6781732A0441:E954:\ -FA133478073A08E890B4E159B4920BBB:901D53BCFFF7DD75AC0F1E3559078953 - -250BCF631D446250F8837F8FA83A6BF5386C84:E2FB3E:\ -E4F79E765765409D324E1B1EA414D227:FBDA962D22F40DD772DD774DBF728CA3 - -203D92FC604EA0896CE956A5DAF9EFB62714D238:373F1A06:\ -50070DC0D5244E49CB9C66AC7057CED5:7ADC4F5C39F9A000EF14B52653CF2CA4 - -757293841970FADFE86782CA41EAD6CEAA2EC957C2:EC3B7CC743:\ -103B1080C15BE0AC6124A0264938A10C:882023A6D7A67CB1FE759D39F2647C02 - -59C5C5C3EAA2D728B32BCF1B49E4C18870AE4C2F7098:BF1B83377790:\ -CF665E60D491E84EE5874AB04FA9D38B:A8021B4DDF9C63E58A23000D5A779E29 - -93C5B53F5C534BC3ADEFB928D3470DCFC8852C5E24BEA6:70CE6AB07A9A8C:\ -BDA78F4BE0174F8A04C5DCF1865E307F:6020C7248A4FE110BFAF7A702915FCE6 - -61D5E9CCB1E8A2F1458ADD75AE1BEB7800D6A37244109E83:C5814686F6429BF5:\ -55A89D0EAE5316F685F890E297E62AA7:FD97541DD6D93C9B5B822151C4BC4619 - -C818A94252A8257FC51501B6A67D4D008ACCE6A3B09E1B84AE:3D8F73596B10934BD7:\ -C9F99830A1E6B5BA8D8A1A48E7C2060B:5A1811DA7C2C170B9F7177AF04C287CD - -D987E31D050BCCD469D18C44A28640371A867DF44373D517DBAE:B8AFCF7A49212AD45FCF:\ -40E64886878D1D3ADFEC046F61D3E81F:FEA453D7F80C87C786D0E9B1A44880E5 - -5F2827FEDF63228EA08BFCDEA50C9D5D904D71618E6DAA63EB9C22:A3CF005672C1F2E6E1983C:\ -1B3A82403AF3B423CD1FDCC2E6714A28:8670E19913B19969235A5C093BF44657 - -E032CBD49F0D644C67A352AB9FB1107242BE2579D1C7A45D08B44DA7095E577D\ -9A897967CD41602B8608C8670914C13A009EC1AB9857143FF6E6A0681D24A75A\ -C222FA89CA68E7994A969D5974B4755C66FA404362F336B3D4DA9AF4AFEBB077\ -F9907F9FD674B8F80470819A0C09993B768F9F5A22D8057C416712E22E9B31C8\ -62626881CD3229D5364A5C949985177F0D8A3D1583571931CF2DF2D20D893E61\ -119313BA902831:\ -7F4E62DFB140ED5C948D666A2919BDB42905A549A8B6B97259A273C9E974AA68\ -C30C48744C35D0E1C2364BEC5008A0790D45C3B6FC7C28551F9B1E0810C871D3\ -D5B94721EE1702B04D4D9C9D563C176382DA197E5641D375DDF17EEDBAEFC08F\ -A807B0961EB3466B00E309561F20BAA1FAD31F5015F2C6F2E444DF9E339F2DDB\ -A6DD71C490B72F919A38E7BA58A15B52757BA38A6D697C:\ -51AD5BEFE0FA1CBBA0FA2C648AE3931B:7ECC033824A49377190E1AA37C831FCD - -E5CC4E45013E62EE928B519F369BBC2C49FA0F4A7E99419E2D67721DE413710B\ -2BF0D011EC4483BFA796635544016321C284DCE6EABB25D0DC72B52DE5F6C48C\ -384F516F96A2EBFAC4FA005C8DA36DFAC06BDC133A3BBDB64C51C3904E8CB149\ -272AAD85852F60F3673C8B14C1EA06F8C45ECCF898531547A5B928F893874BB6\ -51599DF89B31B158DA2DF6FB811E059F15DD49569BF3CC8103322A21F089FB80\ -41B026695E09E872D82F1533E9FB88B6C6E8A237C7294F6F72751F06CE9FFE85\ -74856C7006F9592FAA80332E74F7AAB78F:\ -D4B2954F1C16268C7C64BCC8066668635AD9CECE9E811018F948DF1560D6D734\ -886C83A582AA31FF0EEDC714532F78AD08467BA7C88BBFC1D39ED73375AE67FD\ -1AEBA29D95D39CA3C163B714932FC29B763D423EC902FF9CA0D6D0158437139F\ -22B53CB789D85A4A3B125ECE41206AB75EACF527AEF5C34FCB936450CB77EFED\ -2D2BA5B603FF003E115E0D537F770ADD230004D2F5C721C05B851026FDFF132A\ -2AB8E02DB8E06CC93E791CBDF0279A13279EE51C6606DCC18CEDE789ECFAB317\ -B3:\ -93446B73B034B129516F1978092D9FA8:12BB0E1997CFA584B62E71B0E1886374 - -17355698DF0456602166D82D5399F159D9BD771D3D23EDCD6364A855067E2CE4\ -AAC59A671D0C223B9D144B67DEFBCBB2025580F83EB5BF4C0AEC626C7297001C\ -A1A9A0EB46505265C591B1514F75B17EADC5667E991D3871F6EA8BCC1183601D\ -8D80E24CB6A2C22E27AD9A22F5B745033DF0960722D1176E9A162DFF184D8011\ -7DFCE09B8F97ADD449C3ADE8F7F0B45C2AAF447536EBCBC610BA543C3D3D91E7\ -37558D54C9F724B3501A5AA24B2DCBBA9CF2FC17D8700B356F5733A64535ACF9\ -325B48F40E28BF57649B73C63461B4EC9D7163:\ -407B43EE14D1B3CFD48F4FD112CD92E4DF5BC3A9AD29C4A5DB5A0C4E6151E4A2\ -CC2890E1F943B0CDD3FF9FE5CC31CAAC8C8D5539B61ADE9274EBE0D53CC57709\ -ED08EAE64B9AB31E9952046683CE120F5B6749128127A4F51284CB4F49425836\ -4A421C96DCD0B47522B8DBA686EDB5E255FEF4D62698CC381C978766D9DF9C24\ -21B9BAFD896E73AB274E51AD3C078F910583672B1B336438CAEB9EA4CB3AC8EC\ -F382EA7CF05D2817AB79C5E780547886D8E0B1F313152BDE01C982CC044AB8F7\ -CCA274:\ -BCFF9CD4AB15999296ED0B1CC5EBCDB9:FEE3E4DCE4AE5EB0B2A868A9740B1D31 - -8571D4B7665B32DF2A17849408AEBC9FFFE73BB7AD18FF8BB037227C54583C5D\ -B7A28B87193F94DA28F45C8D2EEFE4F765B3C0EFB5A3C09DEB3EEEABC7C78CBB\ -120C68C13129E4609B05CE484F5DA5BF07C3ADD4996DD14CD7F2D34420CF9E96\ -B529B573A8376317CA02B47A55156AB51FE0C713831C3FFB5E0ED8575FB3FC69\ -24996E6FC9BF0E20F5E58A137347A7532C75F2ED45C33061D0D3455A473FCFF3\ -41C0DBB260E583D4F499ACBE4DA22A19CE8D2BE53541BEEFCDFEB028793A60F7\ -156ACD1ABE5EC842B3B1F8B8A6A8DC028A5B15EF:\ -4DC29DC34D600238E38882EF62C982CDC34DED3A7EEBC36D99E11FDD3D523A8A\ -14D74D61374F991AD71B0939E48C06A8D9F4E257DFA5C47887E355C435904E49\ -679BAB9FEA44B9C160C3FA444F00EC28F4CE80D374444CFB28A1BF5D310DA799\ -A852389296F153F6B44D3B034D272C42F6AC156AF061651803247634311DCDD9\ -6F056B05F7BEFCAB0B37AF585EDB9A5487B0BE77112390144706497823165192\ -1CBC97137A93BE85CA6DDE2948787DCF283C473A5FD74EA7DD971F00AE7192CA\ -2D29DDA8:\ -BD9B2D87090BB051842E21AC6A68E6C9:3F35701CCC901C7A01AE442ED721D694 - -CDCC757B0721890851AF53EAB7DE0BC2C0BABDFCCAE5ED76E01B1351E7DC7C4D\ -882AC19EDC147C7B04B6203B1F4AE98251E13D7336B80B35BD42D5549951E2F9\ -F0CB913E3999527888D6B40737AE5EB9AB41B0051612D08F956B157D409EED5E\ -BB62BECD72B92A553DFA52B185357BB96F74E04D63EFB0AA7B239154698D4241\ -DE34ADC79D944FD8B0C0DB24826C57CBB4847CEFAE328418925FF3D6FC6EF3E0\ -2CC580A2D18DA0F6FA0E3E5BB44A7B7D058DF60024BA4F9866E804E05DA6FA77\ -453DCD3008430F314BF10E70FAB7BBEBC69B07CB60634F3D251FCE93AAE69702\ -010E5384D395CB82967BD606F9E686D3832C39497F1A9DF2DE621C2F92C785C7\ -CB0BDEBEBA5C4F1C7436B0FD931C9B245B8D0991215DD63F32CA48345EC64A89\ -68927310CCAB1E4B48813342EF6C24F92595763D2E5969F960C23D682A38AA4E\ -BA7C5E730FF289A58DC28762D79C15B249A0D31C7F6A7B07A41FB78A418429F8\ -5F58314D5D65F58C7C21B5657807FD8907CE47B5324C94D391676E86BAC4B9F6\ -CF870B2E1F7703BE8FCDF4E82C848712315C8C61BA10752AC59F90665C7C4830\ -CBA53E602292634422CBCA81D3C7CACA33F00FBF136358A921A0A7267D683A7D\ -2CFF3F35553CBE486BD7A4423E6F167D998930246EFF28CB33B042FC8AC78BAE\ -D594B5487D4FA8BC2F32712FEFDAA5B4A91085A5C75B43AAE3F5E753F0CDC68C\ -113C94C2030BA2C7E1C9C580592C8D4A08D0C46A0A45FE486369D72AC0AFFF21\ -5AA6CEECD32A781BC52566FFB25BE7975D724A825D2A74113A0840A00CEFA835\ -04C8DE918967EE89DCA99BDFEFF8C359FEC0023104BEBD00398E6EC01D38975F\ -4AB4027025ADE93B0BB7EF3FD24A9400DC304068221323CC87DF4A6AB69160F4\ -F683C6005BD32998B323750A58FC532C437BC40F0D453118D813178F332AD789\ -C2875EB6C3249C93EBD2CAAE6733093678F5A975A00D29D5931A1CA8FC07918C\ -5F232359F044558ABCC36520E75668886E9A8D33D088AB6F2B15FD571B220B71\ -4AA8D9B9014EE6EEAA0BC6F36EEB508B5914C1C13FAA9351C616221A7A880271\ -F84CE54FA9F377DAEFB738636C6D8C563F6D14362306D89F8EE8C9C3A13E04D0\ -01156654A41FF5405A6F8BDAC1FEA59EA0B6206E3E9364244E9C9DBB00836993\ -F7E19605E3D09B2918744DA5BDA9F396FA8D008A27DFCF63ACF7AAB37593BF3D\ -183146A59EA92D:\ -FCA1346D6430C5A6DF980E7E456D9296BEAA203C3A63704FADD47299AAC26FA6\ -63A313C7D4D86DB3717B31B6E9C44CA76E6DE3A8D053F77D276917D12B86778F\ -2A8A56FE63C4B1D43FE38A28A7D6CF1543B2BD1406B4912D1DA8FF492F76D859\ -012E5764F2083832EBC25A92982AA7DCDC64F0E2188110362A0F7F598557B286\ -8509EA781122AAFDE4048F7D2E37590B9B49EDB4CAFDEAF40C694D92C0FF1845\ -0803BD1A2567170A6CA6879ADDE0A57929932DF39017E89D80352F403547853D\ -4A435770AA6E7A161501B1F2E1566B0AE998FD7AAFE5172F1B466F508DF58DD8\ -38E548E253C2F968C3AA5BA400C6AEEA5FAB640E917B3EACC1ADFC4EA28926DA\ -6E6EBDC230B62AF3608597604C454AABF1AEB98229F72EEAA52A3947B35F2222\ -CEDFE4FE950EF2F5948955E0CFA08BC04E4442783C7062E19A9B284DFB4A6FC9\ -2953C7BE62B9B3F64309D612A961D2F7A5146FE184D2C21E6DEB6B6835DB315F\ -2EF91D90B2D186F5DA5C0783BDD97A63EDEA4471BC078F29F2FB9227D6C38604\ -BCA4956F751B644F786CD235454C983336DDA4F2E4341CD62FAEFD057184092E\ -289E9D9DBA01EC326DBE67B30A00E641DD8A33C1BE4F97EDFD94F26F18FC9D40\ -9A3ADD543BC986A987EE5C92EE42D3CBCC068C8B56237853B76BC2D0675F1001\ -99EE56D5B7DC7E3FCADAD1B81CA483E8AA0F730032EC54EA5716BABE76CABF0F\ -B815E470F262AFBC3C80755824F841CE08B4CF3AA02324F739DEB5AFA975BF61\ -8AA3D17C0680394200AE9B24A6DCF3AE90C2E931E50D281EECDECE95538DF6DD\ -30C85A364893794941146DE7F0609680227FB1078CDA2678B8F40D0B8104E8B1\ -CC42E814D5615D1675CBFE652B94E54E1397559F717B18296F2534F0291CA2F5\ -5F8A0A34EB674B603249C55EDDAAACF041018FB27DA7DBECCD0FDDF62C7FEC8B\ -09F6BFF45D0A54905319EE30C39A20059BB0B71857930524A2E21BCE6107596A\ -FD195E5A23B2EA77CBD8A78E72C8930E784B26CFDE2BF4800D0F4F6E16A8D813\ -C1366DE5E8585CB3300342A3CBD5B14320D713FE03077F1016CE7F2C76573F38\ -8EAC1D7604792A357C6CD84841898B62609E6063A5DF74BBADF3E7244A265CD8\ -D3794FD7F2790C6EE5E4B6266D4288CEE0E93186C8A5417698299AE34FF6BB22\ -6F0AFA618306CF68EB868F58C81726A800582EC9FD703F:\ -9699D979E8CF340B3E3F059FC20B6E2B:F6F4BA4FBCD17565D2CD939BCB03DA61 - -[AES/EAX(64)] -32E55CE0C3FAEA48::\ -C61A0851AB4E515D11525B92E2B9D850:C825FC7C4D539DC74887CECC70884F37 - -710DABD24D400F3B6B:60:\ -F956B879EC7F807F1FCB482B53623671:E64F90B4619D93137E6237929EABF297 - -[AES/XTS] -917CF69EBD68B2EC9B9FE9A3EADDA692CD43D2F59598ED858C02C2652FBF922E:\ -0000000000000000000000000000000000000000000000000000000000000000:\ -0000000000000000000000000000000000000000000000000000000000000000:\ -00000000000000000000000000000000 - -C454185E6A16936E39334038ACEF838BFB186FFF7480ADC4289382ECD6D394F0:\ -4444444444444444444444444444444444444444444444444444444444444444:\ -1111111111111111111111111111111122222222222222222222222222222222:\ -33333333330000000000000000000000 - -B01F86F8EDC1863706FA8A4253E34F28AF319DE38334870F4DD1F94CBE9832F1:\ -4444444444444444444444444444444444444444444444444444444444444444:\ -FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0:\ -9A785634120000000000000000000000 - -6C1625DB4671522D3D7599601DE7CA09ED:\ -000102030405060708090A0B0C0D0E0F10:\ -FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0:\ -9A785634120000000000000000000000 - -D069444B7A7E0CAB09E24447D24DEB1FEDBF:\ -000102030405060708090A0B0C0D0E0F1011:\ -FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0:\ -9A785634120000000000000000000000 - -E5DF1351C0544BA1350B3363CD8EF4BEEDBF9D:\ -000102030405060708090A0B0C0D0E0F101112:\ -FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0:\ -9A785634120000000000000000000000 - -9D84C813F719AA2C7BE3F66171C7C5C2EDBF9DAC:\ -000102030405060708090A0B0C0D0E0F10111213:\ -FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0:\ -9A785634120000000000000000000000 - -D05BC090A8E04F1B3D3ECDD5BAEC0FD4EDBF9DACE45D6F6A7306E64BE5DD82:\ -000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E:\ -FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0:\ -9A785634120000000000000000000000 +BFDA49CDF67A114D29A7949CEE9BBDE5D26FF8E35407A266E12F98FE1247D74A1005366F\ +526F7460FF5B5C45D6791069BDF075C8BD396BA71AED8B7F812F0A31403046F30418A11D\ +B134127434B14CAF1E696DE716B41AFAC8FAC96687ABB8A81E1EB37C0C518806673A7395\ +AFED27408AF1B83B3EDB1D1AAF54B3C754E8361F:\ +D645EE5B89B1FDDE1056BFE827B8F7C2DBEB72E89E8ABA4AD0915193916EA8E6AD540288\ +69D0B1E71E396881006482C013B25915563C492B55F6CFF5DEA950590228899EDCA68C81\ +9B9AC2A485CF40023CBD4465170232F429D06DBB42E4E2C9B5E201EC41E4DF5C9674A1D3\ +2DD33A341E2E0D13351CAA4267BD869BB5AF2804:\ +BF4DBB8609E7AB12773DEB38FA1FB31DEF23A89137E4B292EB569028B6A5F836:\ +FE53D28C28A8CD12C0D66B79CE6EE6C1 + +967DC68154B9B3957216DA8538588B899005DA3D2CB9500B1AB2FC4EE815232C01970F19\ +BF4068081EC07B041A6AC7A2FD97ABBB447C7AF73C0286EDCD99DBB6FDA189BA76212EC3\ +7B23A72FA8213D5C54AE716845E00262266400DC041D89AA69F1DE8B600F66B16485FFDB\ +5BFF89EA33625DADFB00DC35827C4CE73EB098B3A6639B26:\ +DAAC288ADD605085CBBC9867F0FBDD007472B15F34F8A7A91F16208CE15F0BD2DEF3FEF4\ +32DF84F66B1463777D3B2F0E3D2A41982BD845217383412BDDF2EB628EC8DF59240A32F9\ +FE442E334CA6670C6F3AFE7835C5D12E064F272C610F1084CE39380E029D050E5DC5676E\ +D7DD090FEF19A547EF90258670B3A49349728733E69CEC34:\ +B6E12C2EE1A50C4860591BC5AD7677BE5C77120BE31814A03B1B308198853950:\ +2E78B846599FB10E51D8AB906D7AC754 + +6A3C46C05E280864DA7660DD5600F4050AF7EDE52B786F246C2BCAD03C8A88B6BBEDAC3D\ +5FE79AD40697BD88EEE4CEB3F0C8DF2F0F5381321D8C6E89049728B0A0DA9A71AF00DF1B\ +9BA71565C73F042CE22FFAD7B9DE33084BEE400C11E6A6F8398AC35E816E63B42AC23098\ +E7C5CA9B4D78395019B6123EA198EFB6A2E92793BBE243B46B1DC872:\ +2178CB3861AC4ECCA38D4C31EF1EAB6575AE0012BB4AEE9615069F62013B920F13797DB8\ +E432A8DC486F62A9F219FEFA356B8AEE7B1BFCAECE0DFA4F94E22A2219F6468C2D15A69D\ +11CF93B67AFBBB98F185807D32B794C6FA8F22794EE880084F6BCCD8CB5A7D0C59D0B737\ +781A60B29F17290D39422BE10A6AE430AD37C717D5C461EABDF8862C:\ +91E98D4A6EE9D7FD83D643C3BA829746FF2EFF77FCBFA41D44CE95C4CD76CAF6:\ +7B659AC1248FECCA3EE765ABB8D93D1F + +B0B0645AFA0E15A28D3EB6ABCAF31C6996CEE3C93B76F957424FA82B174BB3E9945F3969\ +094C0E6E5544D64606B54575CB6CD6E40964B84E94DE2193E7B9A00D4C5D140976DEDEE0\ +40585741F7ABB55CF8EE815F7848C4CD48D30C16783E76ECC14D384F480CE896532CF6F3\ +67E23633642794E6A913B871BDD702934E8968EBE1B2859CC62C01BE12091CFB:\ +406EB5C237784660784E9A1F477E4B8655B07FC54D1C69515C1B046005C05B82D8065886\ +39EB44323FCAA1F797D210FC51C91E3A51AE8236C0C2D6C521F2FAB29E89361BDA2275C5\ +43B54110AF60C7829D6C5CBC42BAEE86FDB0FF22C08EE59E81E63F0A98A6781926770B5A\ +C7792CCEA9847055813F065225B49F387E474A333D8B50926E3D7864035D75C6:\ +DBD7D9C318FECB268FF109238110F96FCBF2400BE054071478C7A2AFF75B384E:\ +BCDEBB1E6BC37F18D49C0A4A1C7665A5 + +C47325105EFC7B78FF868A0E1CABEBB41B6A184780A52AA1D1E78A284C073089762B8029\ +9A628B3B22124250CC683CDB54DCE31E4072708C232129D437B89C0CB8BEC7A8F658291F\ +50AE9C66A0D62E26528032FBECD9B3112CCD022B7648BF995ABC46C57E821B3F3CE0EDA9\ +7358F31024F532C5D560D016CFD316A04FDD29588E6D50E681068EFDFB8361F93AA979F5:\ +D1043171968DF2B850257D7D14FBB7DE4E34FE62217E9972BDE0283E6EB2054874C6CB8F\ +B66A18A6F6885522D719EA965A0BE5F079370EB76587B8BBF5672FFD6B4390956C5B81E4\ +0AB21A15C8EF17D1189B6EF8E931A07B192ADDB3CEF0C66B28CF545774762CEC9968EC1C\ +06FCBA860BAEC78EE635495137D4E7B659100C59BD4496A850BC0FCF464531181F47EDAA:\ +B58E1583AFD26D09ECC1B81270BDA381ADCE90DA1A6096D27A61C8DAEDDD9F4E:\ +7BBB7496BA015237C080354FD061CBDA + +73DBE3EF41EA394F52138D24103977D8010166084F8FECFEA4C5327765735D5002FC7808\ +955D2DA9E786AC33F41A41E47D06E18B84344B4A5ADA2F925E536799ABE3367E0CB181EA\ +720EF44D286DF2223A34030E66FE161404724DB33DDB026FD5C88072D47AAE1BA89738DB\ +BE681D79E330856E4DDFCBD2E998E5065BBE6B3AB93DFFCC0EE04BBBB13E47080C511F74\ +61ECB802:\ +BCAA1E8F81FF49528EA23C4A62C40953CD98F16F91AE3EB6878C7DB5C3A6CAC4F8551A34\ +A5A624CC587A5A22E81CF9405E38913B77344DA59A53FA0BACFA1A4BBF64D234D1963AE5\ +E89159A24EB1237B93F25D652ECBB9EFD26E2881368287357D6783A8F3C1ACAB50FE60BE\ +7ABF7225F8AA0A06F54A63577634B9E930618A1CC8892D290ACD04F7933CF654A8A60AB9\ +00D8E0A1:\ +3A945A5C8FD52A46037A426C32946D59AA9B081C4993C634D9EAC2B7E144C040:\ +4C6D4D342E2582177F3641F777D337FC + +451FC9DCFBC3C8F106FC9C17A81D1C562E45341B4F05B5319C912CEBBE01743AE34D0693\ +0A5AAB36166780F9E75C154FBB1110375B271C297FC46D4B97BC70C1E8B378CB1E29F61B\ +5B0BCFBC8238E6D460054FEFB4A649430AAFDB7F01CF78A5406A3087E9C39FC2D60C4CAB\ +6CEE3DF6A3A8D2F0CD4134209C323D9CACF15308524519C40A81AFEC9736FF858D78927A\ +F66EFC5FCE806ECE:\ +C111527D486F8581AAB32257A7577B062AE1D781CF5B44333D12C3208BAF3C8E1276ACAB\ +0F4C325BC0D3FBF3913B13D2F06E8E64E2CF8017634AC9162EF32324A3465156613AFC57\ +779B9340CCCCBDEFC6476D2A4673DF123E435C6A98FBB8E59221C7667CB831EF2E7B5D49\ +26C9A022204F0B3564C66A9C8A7F494EBB337D148A8681982F70524C467D868BAABC86FD\ +50D5A2BC4C858342:\ +94EB2F6DAFC83A9FEEDF7081D40104F661916D4D68611AE3620A7E52D7C8F79A:\ +FCB50453BF443A452F735A2A7BFBC5D8 + +5C1DB0ADA94F46127F18B21406B6FA32EFD090B0FDEB549474CFC19EBF68D4BFCB3137F5\ +47C48174E79DC87CBF308E0E9306E68B5FA1F9F67E005A2E033DF9034BE4F1E8C53C5D47\ +73846E8EA3782C70E8B1026965C40CDC7D5884F763BE3E2B64AA7458F48B6BC76818B52A\ +FB743300BED3971A416C587BDDC713A8C5782E91AD001E8D3DDD0EBDB978427173AFA9AC\ +A2180F7DEE47FA5A76F7989A:\ +C8E1CCDE12CBE92D8E61F23DAEBC35123564A94BAF6F2511B4BAF697D04EAE69C9B1C8D7\ +8E6383F9EB053C6B09F9A2A91EC0EC1CEE7801B3B01AF1E9BA4A481A4C7B73B0DC086285\ +C43CE33919DA440C1EF892D9A254FEB9179BAA1183EF319702EDB67FA2EE08F43A719D5A\ +EE5D3D7E10F0599278C70F25104885DA2F3CE797D3064FE6400366950661B6F703C8FB9E\ +1F773D893DCAC13DA94162CB:\ +E667049150AA0CC53BAB66F3EDFD5C32FBCBA264A6EB12D4563EB5E1E73F2D86:\ +EB8D65B2A91A7003E9CB84241B1DC009 + +734BDE1B88BF91B571B7EF20524347DEA07BDFAEA8D194E00367A905DAB483F76F923087\ +B1E307EC990148E1C3B2E9DCDEF1694D9CEAE1A86A2D092D84B1247B5DD627B68E6CBEA1\ +7A539A5C650E8A6713ADDC2517B8FEEC7656264C795B1B0034B30B302DFBBEAAA12AA6C4\ +2BB3857A3C641A7A760C275F9C01521432A697984E12C2C7727A538834E90750D4FDF44D\ +F7083842090196A95D2E8143AAFF1D5E:\ +8289B871A4AE2E14F7398E510C5B522883893F59C8ABE42567FB879334A761E5332100EF\ +A7C6F6D4CEB8B6778D0C4B543BEA8B3EA58D198DC3FF02A8FB5CF063CB40E607087B5F08\ +DF86C906F14336ACB78832F20303533F8A7AE39A95C0AEBFA2985F97DB96E84EBB996F76\ +491D186ADC6D0C681F33F0FD3B42632E87E10DCEA36F222E4E7E8B4F2A5CF58D341BDA67\ +9516C829370C251824000BF463A75322:\ +F26DE261DCFE004B4F0B322D1CB4752F2D38279600B0A9421E1577C863A7978C:\ +2A4169C8E13B81AD96DC1CEC8723152A + +CCF6EDC92B1D17CC548C9973270FA54865DBEE4DD450683C7D542293BB2C59D2163027C2\ +29055943F7872D8CC2C9889B12E9B409D9EC55C346FE69998F013256A250FD23EC8C23E3\ +6B5412101FB35E7A0C78124BF23AD040327C608849E720EF644A552E35A2E98CB8ECC28F\ +FA8521BC4CD947E4BD24E4A70AE1A29572C746CDB98DE74477FF79101C9E75F45B55D6BC\ +2BD0FBC9CE24B569DBDC2DAB7FA88A07CF9BE2A0:\ +80FCDC8D13CDA4FD4653BE225654BD597279CE58C66A3CF67B95A8348DC976944477ADC2\ +0E9CD0E24C7913C928B2E0C531D43DD7F708FD4247D87954A7AFABE300085D169D280FCF\ +E16E580A0FF5AB435A7B64FAFE9928A11BDA14FD827D3B6DA14373879B4FF12F151BBEA4\ +17DB039CB8226AC91C8567B38DAE42015456FCBECE1C1CA8F0D2CAC3ED75F3D6F01D8F32\ +2F2822D2D4B0929D2831D9C0A801D49F77EEDA99:\ +32EA9D65FF14E80EB4AF36A9C6E8F663CB37CB6BFD131F14B49AB528614A613F:\ +3F1BFB148CB229C2E07719F6F99AAE22 + +428D69DB8D1BADDB36EA5950FB2F99124A78BCBB0A7A9B1398F84A7E121637B48D12BBF8\ +5F045718C3F0409633E263F62F4992F4C6D497AD7093BC8BB1BE5663B40789DA824AC2EC\ +929C5FBB5107969688A9DB02BACFDB400ED395091A98DA4F806CBD7A9229AB96FB12BF50\ +2243D810B6A9B905C48B7612F94AA37E671F543FAD6BCD9C6B181506F447E90F88F050B2\ +C7B7199B88AE55AB922FB1BF4A5EAD00F71E83EEA2FC4F25:\ +5050237A09192DB1FABDE4EC7E865E3969AECB8900CAFD72B223A8E08A34AF993B1F3018\ +32DB0620BFC6757BEE80D215DA0D6B23666371158876E0422D540B2DF889C9F8EA92D181\ +A79AA8BDE50ED123C0301527C0987C4EC1FC105E6B8C0EC12750AC13FEE9CFF30E5A6DFE\ +47A6E63992A803F94D6E79F5693292C4D12D963BAAF42727FB9F6B144F6AFBD819C54D37\ +B3558EDEB4A049C7947E83E68C6ACE0203C882D9A038727D:\ +4A1EA133F919B366E3084F80E89E091C87F5F703FC9185F5C8E34E14973DCB2C:\ +CC96182632AD38AF5273863621B25E55 + +C6092B37D8B6C14650D8AB31815C321B7923E9CAB069598003744F33EBEF1A693CC3E03E\ +B801BEE76182BBCE6CCAAFAA061250F5FC6BE6E07A3C39ED3F4344982E2DEC0A5075E5D2\ +A3218AD1C27F12C55D9BBC1B43BFBB79BAB35F74E1899517A839A54AD5274B8718F2AC2E\ +8F89A6CE94972A0AE020BE5256F8B5365B8AEBFEB63B886BAC9D263107A13B95E29A521D\ +3FBC7CCCD620E134D2D45082328AF1BAC6EB8B917B3F70A47B9D5CE5:\ +3F8FCC0A28C43035C055519FDBB13E8E5A4B35DDC04B62BD2AC7064BF7E4F7CA6C5194B4\ +0344F4C0D0C40AC3696C47A6CC2F800139EED2677E580BFF68399D8AA68DF7A28B95FA79\ +A1CD776739C1E2FB9C302EFB924013ED0FB2B06EB6B031FEC8AF7BB47E212859E1D13EA0\ +96E029EC051784317F63F5DFC2EB9C7E8E249BD88684537CC36785C54D8DA6F512450831\ +559BE2E67B024171A52F0481102C211DE9138120669D1C2A1F8BFB10:\ +C383B62616C48E3FCC6BB32DE3AFE5DC184E83ECB739AAEB94D82E942F0CFFCE:\ +52C109E1FAD94E490BD93584126E30A5 + +0D85590B10C077184BA269C135DD1558CAD1A3D792BEDFEF45BCCE14E9099CC4B64D9864\ +97223B4D3CC9193E37E31FDE74E31023C9D265ED49E8D7B1032F1FA13F50E486F68FBFA3\ +B449F671878BCACA4009CF4607556E85878A2769472D481D30CE43787E1065BAC0506045\ +A26456644E7D5149C54C5C8387F5E23DBCC762E4369D4E7E24C4EB7AA5F3FAC3D76EEA37\ +DB6DE27601FBD37EB44D4C3F30E5688B549A029C22EE2282E408F9EBB259A86F:\ +B317F91E9BABF4361F26F96D001E3D63F3A82F2C8DADC4E4080611711CB4A7D77FC58D71\ +9B6ED93D118C7ED676A5B65CD259B9E1AA77AC2813B62FB869C42DBB0A710D1C986C0F97\ +8517DB2EA942D0F76C06AAD414ADE04BBC908DC428A18729B4D55CA600874EAF530B38FD\ +4318F1B2D97513BD3FF17949BAF9FFF3BB84C3F0065A521B4595E9801B5233DB2023D17F\ +5204D87AE7ABE1ED73F091A63CEB338FE9BDB2B82463E6B6B05883FFBC0AABCE:\ +357D3ED5C533FBDB195DD88811F3D6D50EC133A5E0A36DD256BC0E561ED28CF4:\ +38670C0DFF42CB73FDC3295694CFA934 + +F8891DD530B83DD5EE3EF9050C7AA6A9C8A6EAAA4C8669FE126EC1C78A6F6583E57BEA88\ +84A368302C2D9C00D6F2D8DBBB98DC35152E43B1A9D744BF0FE1455A36B6164F09F55D4B\ +12290418E14A88F3F80A5EF558FF4EE01CA1ACE680FA028E81C12BF8A18A18792AE98513\ +636AB075C12320038C5BD733DCC8305551514D45E098E8E07EF0A293A489DA24BAB16973\ +D270E5D92AF34E6ADF9EBF945648192640BEE963281303D6DE6097E48D0AC4868E87A58D:\ +A54CF0CC7FF8A5B041A15C78F26EE7542BAC19254BD4D421E9A1843C66E9D8B136A80E28\ +31E6C52278CA54C79750CE64F6DAC5078BE3CAB44AE9F4D9019CBB310900282A6BD48313\ +7870CF8B0CDD002C61BBE679C2A87C7B1B1F1632DC57CC277FA4767D77BC2F0273879153\ +69012D0124BA8B2B85D8454499843C5F2FD9DBD584F9E2588BFDBA062C9F0761609BCE8E\ +0CF2B487F0F2C78A1C0B6D5C37D483F6B6EC52B7451B057C2D5FF2CD5F2BA443AFBA9215:\ +C2B6E94866DE53E7B7BF5827D5C0179A530094FE6AC5F44C9B3330D6C855E918:\ +A4EEEA6808FD5626B56AEB9206F86EF0 + +1712A86BFE8C268C84902ED230BACA2B7B1610B5E6837ECB817D5D945E009BF627039587\ +D42EFB7C3966B9E84FA3A8A5363E1077F287150387C3A9AF1719D91CD175A97156049340\ +13A8A39A90EF97974A419796DB11DF04F3AC7AD348F37969FCB4F560B02108674026C17D\ +59D191A92DA7C7E32292D3DBCCB6D3B29C09F794851BBABDF7F455A9F050A069578B6A30\ +315BFA63448CF7A6AE2EC87C507E0A762A18ADD0BE18DF7BBD4F622B1BDCB693B53AB440\ +6E88AA7E:\ +3C43430F459A8E942D7360E97A89B2AD6454DAC2E72F64A1B06233810334C549D63D0BE1\ +C90A419203632CFB5C52E205756B751630DD08008BFFD348CD67C96774AF48C50AF4057B\ +4A3CCEB8DCC2223481AFC79FE717CEA8EFA2759C4B64339B2987175D14B4C195CB8E1363\ +D4F4249BB6F8A769454237FCCA5F848BFC05158F1D27BF39E1777A3A1648B555A72DA4CF\ +5B297DE904DCD84E36EE569B3F0E1F943873576F97D65B8669ADCA2BDB322E4A864DA4A9\ +E09BFE3C:\ +CD9057AF000AAF8EEF7F304A770DA1394F8707E59917A82671449D336167E456:\ +4DF89B713AC1141D62E2C824896B80CF + +EC9A99CC500450A9EDC1E707A9480144E242DF106E840B9E8D3DEA995A0C9F63FCC02117\ +02E8807EC1ABA88F5E33645B754B2E28EDA71F1B88E25B4B03B0909BD075F3855B4F6E18\ +AB07406AD94E9C32730C09CEF69F7A4FEB3F09C83D46338926ED795ED4EFBD2917E47873\ +FB6F516F6E4AEDA8D0310A914DAA25A08CE4528D67C3E1DECA8754552619027FA6FE7CD7\ +A1D9638EDB529445113C09FCA8BD4AA540EABB931B6BE201BA372D213162E14141E3AD51\ +AF9E684896D3566C:\ +A7A266F5E6CADE688097C04788CFD45BD87FC636201D0F484927B42FADEE8F789EF93F31\ +19D0DDE8E3716C3176360B928D3006A9F42BDC12D0591817DBD82D75FBA44C784FDF2D86\ +5E11215AF461C7DD1F9E3B82A146942CEFC56DFA4F8F80C4F0CAEFDD323607F43B33FBDA\ +7B6BEDF9DDB2A8C908E6D172900D2B4CC633C610812B62CDF225CBA62E09A8A1A1D7CBDE\ +1BF1C14CBF4C24080678677AE59166314703A11607C983C5AB3C7F755B220F10DB049983\ +C1EC0ACCB1368305:\ +B86E45AB9929C8382C8B068D619CD8450FAC18D39F31D38310BE8DFB8BABC18D:\ +3B10255473C571368D678D36964404C6 + +02AD0113F276A03AE7A6C336B4DF4092F27AECFE4FE0DE526F6C548BBCA129FA24AAE385\ +0D0889FBB6F99324F7C01C749E5C7EA3F550594B98F4488F546C509CC256926174875DCB\ +99470F2D79EE7532E36A88BEAA0AB336197954B13171897727242BFE37DD15EE0F9BDEB5\ +E512A202AC3BC467C91191E83FAC86A80EEAFE0A8585E293558F7071C375A91824844347\ +5B57044ACA87243CDF11AA0838D9509A712626461E9DAFD0058A16DC7C4E8D69F53C165C\ +3CFD4AFAEC80E4F764DB4BE9:\ +7F3B26E6C98FACA940DE8DD01BF79AC15EBA4223AD8FF243909C321226B7497CCE5169E5\ +3A3A342FB1854C1802A38F87F393224EA8F518F633B04BB8EFB4ADDCD47CD2599249A40D\ +85A91CAC62ECE87834C028DD2F4FA50FAC1E6B591AEA8A454FE3BF3B41EF7C7FF533AD2A\ +5D4D690F899F5CCF8D4DF6D4FFF94E7F7567070B0309A905DC671515AA617018F7C37C13\ +763A445D48A5A4569D77815C1349A7E0BCB01D667EC0613A1EB0F12044DC748BFD1FFBF4\ +B173FE804CD0C91744302030:\ +CC207471BE9C6952378E60D263D69618DED46A78A21D8B7CA94E6BCBC4E3DEF1:\ +44F3D7AE3D2BA40BFBAA37A0709BEACB + +459C134A5BE569AFEBB4C7109D43FA4A5691B113D13CCBF47C06E90787A23C3F9C296B94\ +D47E2606B655C60C26E9DE647F4CC5BA5A49F5BCF458F40938E06BD259C20254F46F6932\ +C63C29EF311B63BE600E5BB7179FEA67EE10F7DA52C1A30E9EF1944D6321C3CE169123E2\ +E7D4B4074254D7C4998ED6C153BE0F79895CBE9B3462122BEA0FAE7B3FCCA09E5F980CB4\ +39A2F748D0E704C0184B56332921E85AAD4214EC7DA6EA8C6E852F7E1773A9602DF512C3\ +4895861E1C61D8EA0408F103E88702AD:\ +95042E5A21E494CF178601CE390B4F9AB388C698AB66ED4F2E7578A10984E30F63BED24E\ +BC839EA91BF852AB63AB170D8EAAF93FF2188D416DAFCF8C30B29455F70022284A6F934E\ +417F582B774B034ACC257C38C173556CC2909F5AF94C0E7E7CA69286CD7FC2C729DF2F6C\ +2543F4B12506DAA449CA990BFBAF39D386F36D490DE0932DFACA60644D7852007EA5532B\ +6EC98789F49E77239C236284FC94B77488FCB5EE37F0A3CF575541EE2F8FC0F2BFB67044\ +7A7E54C63AF122536C4B61B7A9C143F5:\ +DF3DE7C6FB886CE9DC51AEAC38374C29AC993630BEF81F21F725DFD4D6B799E2:\ +825A5B8F13472C46443D47145A1C136F + +158C45549636EE574B32800377F970320B9F861641425ED07021C9C4E44B5F1664046328\ +CCC1064397FCDB67015873B5EB433F52DF4936AB289A8CA161EC6A43E7459DC36332479C\ +704D956E18C86E11A8C1AABADD88E1EAA313A3D133004A34ADCF5E0F2301C3E0317834A6\ +A08CFEFD219DFB5F825CFA794DBA5971E6360DF22E3E0C15881021377DFD3EE69E53841E\ +F08B3F95D9D04CAA005ED15870B94557BB73CCE60B73495655C9C164098E2AFA19FA7420\ +6685D8103BFD9476808E38F8401FC582496A8EE5:\ +DF6250DDF592B446ED6D976462EEE2CB2D7830E67AB9567BC275CBA74CCCBBCF008441B7\ +B1593756DDAFAB05B1B728557F6D027A2A5EF2ABB072F456761AEECAA143795D93D6EC56\ +7D17F259013858513D20CB461BB51C3CD3D4204CBA768A5A3CD4B5D19563FADB62C4054C\ +9F7D8BCAF30F450F14AF29429E3E27C130FBC7B53840A00BACA0281A90293C6D60376B4C\ +6C455C771D1008A542E19B13AE1D4D14E3B8C69FB44550F74384C02861AF985BC210CF9C\ +4625012CEDA24B08842986E2DA30F9009113F0A8:\ +2DBCBA50DDC8EF3BFF1511BF0172A073CE37F42C83BA223D7573A82B13CFB813:\ +68A59DA89E8D3AEC1D4434F7A2EDD2AD + +F3087E4CCF4C82AA5B3CACFBFE367B2F501D1992D6455F10EA6C047A26ED06BF4393D53E\ +B0FD5B8B587B19ABE106269A74297B517D57D89D7CD26009B5DA7BD1B5CD40CB5B4DDA96\ +E495A02BF58108337A4F74E2A33C8EE14E730740F023560B70582EF4D1CE87C3AE5F5FE1\ +546F5C16683A0630342C319E2A5C43BBE7EE522BE44F955B4912A765B1AC476828C0C5E9\ +8948ABFC096ABCFC4FF2DD5077926C9A3F21F85D6B3EA941560A307BFB4714A11525C60E\ +4D70DCCA56ACF6FD3B95560CB6C3DE1342D8FF18828783C5:\ +996FC92E3A276EDF16CA8850CF8C9530364D170EFA51D1C5DFC2843A968E3CD1EFC50402\ +7C2E056AEB2E7AA5DC3EBED6CD25728812CEB545ED9FA552B1D0B1FCEFC4CDA5BC2646BC\ +5FAAA4C20B821A417980572112F737A7DDC93C39B533E9808D86A495547078087A678570\ +1D27D4632EA57D398F217BC191A30807999BDC509AC74AF3DEF4B1105FB8B904DD9F2CB4\ +158ED207614A07FC8F3803DC5BF81CAF15B709B099AC4F1F0968B7577A81819858D20967\ +77346AFC426792B9581202DDB4F1EB17EFFD81CDA476AF26:\ +B09FB55A95EDF75A610A03183D05A8D03D6CD9CCA7276530A72F6948CC074848:\ +0866EC523C35B5D03269F4F2FB004AE9 + +710647FB3C699E7E83D1601D49513706C54CADC3034E47F8C20E1523225BED6FAF93308A\ +653921AB1043732F142196A32329AB98094C580657617967787D738A4EEF541ADCAADE48\ +84113C020026F6AF952FAEB1F9745B6D450FC86A04A9C4D81F4AB15089DC0BF7B1548D4F\ +850CFD97C6732FEE47B2320A31BEFDA8398C4AB0D7FC123C43F642CE07AB8DFE87B114B2\ +28455479AF224BF82B04BC3341D257F4EC166D9CBDB1793946FC2BC08B72F7099128CB41\ +0140DF4FA38A2EA4A2569DDE2E3AFB3164DD2F9D830A831A323A09D1:\ +EE6EFF319198C6C10DDF6F10546A5F38490A9D9858E021F5DFDFAA8ACBBEF0A446358928\ +5E8F1EFA697D08ED42F9160C4E6EEAE1F15D78207FB207565B9DE9DFFCDD96E88766B2BD\ +A996CBD439E45578596D91E88F7706A94C9428CBCC3108E1F61CBAEB184C30E5BA0370E5\ +DEB1A9B8A42191BAA3D722CEB9DF9ADB69764820FA95BE1B48493BDA88030469CFD41F5F\ +13731A983FDC9B2CFE562881BC479253A126D57A8BD02BCEF2FC6DD8BF1AB265C924EA40\ +F5CF75F4E36EE10133923E2427E19BADB34F221CDF4673D871ACAD8B:\ +F6286D8D4FD9D8B373C7ACAACC517DD041E6E8A69578CD444B22579B4D3C3EBE:\ +621D087684EF405E7E49478F145FBD45 + +707ED22B1DE93A11A851C0B14B1CC4B09E6431FAF7F11E97730D1E9F5C729D9DF12E4DFA\ +53E88A5F8507FAD0AB721510E02EEBDB84EF9B34120FFA1FD80C5C0C3503AD02AF96E4F4\ +66C462C3B4F3D26C78DF8C08A551DC39AAAF7EE05B13D2E1B80DA5A1A532B13EF0D1B065\ +9D2A0B43246E52CF8B6CF4EC5918769C21C51C6D1DA8DCCD2F3B0360248480C36D4F5CB8\ +317973D42FF7DE23D34329FD57B204EDD045BB87DFA5913819F15C6D5049DF1DBCC696D2\ +4C34160249CD84AE0E94C9D50A5EC764C48B26C7C8E28BBBF418525F9FEB0DE1:\ +4F9221B68E45395D5C923C4A6F96826018E207CEECC5DF1560A7587D15427B75FF3188E2\ +19D5EA5F92F909B129D6CDA2AAFD9D52B8B0C05B9E9363E8117E9996923ED6C59287108D\ +A2F5FF3451823362B2CEAB17E862E622437A990F7B23A9FDB6791A9FBFC1C06214673C92\ +41164044EFCC6439AE42079D3B1130320A878581D2EBD264D4FB53ADF5A60091695636F3\ +EB58B73A3342D3CDF833F7E82D6EE1FAF65E327DBE4350307CBD631042517C448F91603F\ +2BD6038FBB847B53F98A8DF30205022C613365C8C69CC55C6B911CF3D5567004:\ +6886D97D7FB73175DA93375F14FBA49AAA7ABE901751EB42CD243B568AD6DC18:\ +9F9E1F292C86CFB45E0334700755C190 + +0612DA958E54589E58F7C2E70F374D0CC47109B326598E46FCFD23553E3D84C703475618\ +68DD38847E0096E2FDD36CE8997820679ECD5219FA16CC9FF0F2DF8AACF9116E6FC9F926\ +1674EAAC3142DE0B9941DE77172FCA477759531B77348D914017B5E1896DD87B3DC0CB84\ +4CF642C1919D25E21E2A94977065621A4433265F590DE23612FA6B16B031F6DB3648A42F\ +57DB126211F6FE7231849B5B54694DD736E512D1EEF0001BDD94DA84AF47C71FF61F4951\ +019CBFFAB709278DBCB60F17EBAFA7DDFC071ADB89EDD569CF4A8C7D566FF1B7E20CB0CE:\ +67943CFCC4B795A311DCDACCFDBE44FA84FAFD87889892F0410166017B032B78CE7B96D0\ +3D00222424E0D363DD321634F4D151E1E03C357BEE8AFC7C561E8629EC55EB52567EFC8D\ +906C2AF0E4C385A0011CCB9E254834E55F7870F10BB563BF0A732CD6AC6F8DDF19C0D3E9\ +AF3A7F54C38E66BBDF3CF7A00361FEC2F5A7EBEA03C4C42AAA0A74F11EC51D3F5E1F78B9\ +0B09CB524F7A5DC8CD561E15EB866449F4893FD49346290A63A8D478A0C5ACED66550BF6\ +4D2A0CC5AE29886DA6DF798D8EDA7258B74BECD3094D6E83A61A9288EA1A8D0FA91E6F19:\ +F1F03359760DEFBA1ED11309F0C1D27A311FA4DEC398107B2D0AB2E0EAA895D2:\ +2FF7028F78B7F5623CBE7D592EE5603A + +4202E5DAF05E4E2DA055A9B76CA4C678A5D7F1B5F130E68389A57A52AD82B1A08FD35CD6\ +1832A0964A5C66F91E9F7826DEA9C78F5257206DD3A78C099768524D1E3B01306A9AF70F\ +2FA7DFB02F9717C2C9D7CF037603B96AFB5B9A5C832FFD86793C0228F9F38593338D92FB\ +70CFE3EB0B4B0E149E52ECD784E0756C1934B3DE03B439292052C21B40CB5D39FDD7BF3D\ +81C314F927C6EF03FB4270BD1DFB796EF59F887AB566D2AC112C1EBBE1C98679D7F0B724\ +94BAA6735FBA58D3CD125ED42272E34A9D51407D5550FD3DBE0E06004D31CA3B5CC1874E\ +10A60668:\ +DB896F08DC3DD1224CAA35F8D841E6174E03595794F8C623987CD275AAFD213A0622D2CA\ +B9DA6C8FB847FAD852352CE37806529A4F06A1620AB065D157E8992981BC74DAAE1AAD30\ +0447E720146174D75C8C09F1A47D307C6492D93E7035A081D4B47EAA116BA2F2643CDF4B\ +26EE8B82BC90FAAE8BEDC463B93F2ABE99BB7A1FECFF8FBAADF907FDDC34AFE59484DFEA\ +97937C02EDECBD1F3827518F3183FAEE67798726A220624A7C5AFBCDCABA3ACCA8862B31\ +9DE90F4C59C13EF1B8FF43DDACBC0A18548F148676034A3D71E928B1D25609C539C3203B\ +7055498D:\ +8739533FF38CD3C2A5969CDF010BE33299B5772DA0F4A56FEFBCFB4C187A398B:\ +C28792697951BA0551162D5FAC70775D + +2A797C4F230EBA8E8D560B141D6F7498036F7C54D326F67E8A0894E7C7DEBB49A717E2FF\ +12E5020B8F4F3D00236075334BC1C1BE18609339FFE59A60DBCCA006446B05FF8C296E57\ +FCABA4121656638EB88214BB0252941598EAEE42966CC162D78D0DA6D54C037876AE0931\ +F94BA160CD17DE6FAFFACAA68C5F765CE64BC85B4B132366618C723B04ACBE5392991A1D\ +1570BB5D3FF257256473297D9DE7FA8901F69B8603C9BBC267E3629A33A6A79697CE70B9\ +37E6B15BC6DEE6C0298CEB375B40DB4E0FCEAF71D5302680DE2875F14750E45771D5538A\ +CA54A19EE9E438CB:\ +B0C2C84FA758C6144BC07E436E7C4A7FD9279C35256524329930F5934B6D7CF4BCE3C7ED\ +4D6603794393D85C28E4DB61D4FCD17A90EE2AA4E6C29E99FD6C4BE9E245329D4F33127F\ +05C903EE1360DC713132281D67D23BA2B738A0F8C66A071DD9C31A19E13489EB8681CA99\ +84B3020F497CC66E5CBB3979F09B0A7C5A043150D846EFE148E7871A45FA8DAC26416BE6\ +936E5D3289A5B7AB77762726F7E4EA82D00D3123183BAF7CC146C761A7FC483055C0D687\ +944BCF9072377A7F797EF2163FE07B7656A56083E351EF3F2026B19FF76C3162CAB2CC86\ +293C537407F0F569:\ +C7B7849FE8962C5670F745C8E26B979CCA21F1628305A75E9372A684EB8FAB87:\ +CE0C1E9870A5D615C9F6D8826D7B61A5 + +43328C5C5E30B0396CBCFC0E6BE81C49B9164FBCB9A9081CC22E223CA5CC5FD28922013E\ +4A9A95DEB0025DD15087D516FF4771182A67E2E69E55C19809A8B9BF4F77E02748DB3CD1\ +CC0718E37C0A9555E703C579F5761EE6DDC484BF619243A95BA97E8B0A5CE152F3C1D72F\ +D69519E9479F4B1C46C23194DD06050224A7C2F467BE08C7EFCB0AF1DF523E294FD7382F\ +4B60690CF7EE8B8AEC379363FF636111AD4CFEA81EF2953BF76C2C8E76DE5B29334FCD09\ +F01FD4902C1021C93BA381CEEE9ADC7CA08D18B00FB5E652839848999FABD577870DAD51\ +0E8115B01AFABDD683FB3CA1:\ +1775067911F026BEE6DAC1CB54B8FCD1AFEAAA98D610FE00C63524F9AB0EFFE7CB7861E1\ +C7B1243990514BFD92C1402305958731E5E730D2AC179916220291A604B479471A249874\ +D1B067558F0D61F29790DC82765A0C4B00DBC0AE2A3B1E608E9D1F429E64CEB08D2AC7E6\ +1DC0A3B8174D8F79CA27260991CBD7D739128012B6DF93DAD582B96603E61398BA8BEEDE\ +F70AF98CE871CB49F2557C239CD61BADE4F38E0CBE1EBDC4580B56CB1830B5A14179C55B\ +A1C3EBD60F60388B164CA51F1369900E9C3FFFDB39D0E9A594A329723CE60A21E7C87F8D\ +756EE5C92CBD45D7E5A57395:\ +BCCCB7F12DE82B841EF1C0171472BE0188C2468C8D660F268F2332530A2930DA:\ +570030C34B809C5D361636F477FA84CA + +033362424F88682DB69F71DFFB5C08A010BA4394CE1305A467B4BC7E6DFF93DFBBBD7FAB\ +DBE62567612AC8AC5581A7A506D13CB8FED0C856A89D84B4D14D98005C74616704E46CFF\ +43A878B66D1D6B3636949C19404EC55B61A1F5DBBC829AA720FB4A5D3FDB8919885E6CCC\ +35943AC13E655E4149A587C4A60DC54BEE8C64A0DF49656CD4F67FD5ABFE1A8090E48212\ +646D730B50E8255774A3A1756F63DDFBB33DC0D2EF5786B6BB6E303006A2FA3217143CD9\ +237D15F24FF27DF41A9099E53432EBCFBEAA0ECD5FD419D736857E57F8917DAB5C20274B\ +F0F61075BE07EC5383BDF320C8F04FE4:\ +11C73FFB2F85FE26E087184A4E7D0E74CA4769A072EC036EAAA0162984CBF53979926FC7\ +09BB59158685C6F131BB3E79886D13F0A644A420D14DE9DD497FBBF5C8CAF27E6C2CFD83\ +CFE6A5219EEB8B29DB9D2722FD7E1004BD1152F6698C4DADEC589BBBFA3EF96BCF4E90CB\ +1395EABA2F1D90D5B2F81F312F2AF94583B4F3A8DEF1EAB26FC8EC9C4C2663F4CBF856B1\ +BA593A3E3F54B3D3831E24B44C7A5217695F3FD36D834DF32488DF461A118A93264B2E66\ +57DDC66D246720E94EACD77ECF23642A036229143868ABD20F3B1FAE1B852C9669CCB0B3\ +334FBA0D8FEAFDD56D03E52F5D136E87:\ +2CFCC0880B1BCB48651602B2F653034A6B8406B143AED550F85F122DA3BC6E28:\ +68A553188B539B46214ADE17802A5ADB + +9481ACE7C47FEC3A22B41B81E1A72363D4F4EED3CB0C93200769415B4779755982EA26E0\ +F6363C973A7C59A43FD6CC4B2D1857EB38B5AE5BEA22DA4781AC36F5559A2A2A8EC111AC\ +33275AEB3863B2A7CAEF572A16523A1231FACDF0FEBAF9305B658A4E7B0CCB9A424D5838\ +4B385132389D5545ED6D2BDC3D615D229ACFBCE60205CE1119322C642F4D81ADAEA50995\ +E4DEEB23D9976A1FF4A9C8CE7F0CC7DE657690F9651E53DE4E58561E9570CC4526FE03DD\ +686BA1AF9557718D38641B080592C9BFB2FEAEE56AFACB4F811439FE29AD6BA8D6F0ACC3\ +FE3836369CE06AEAC64898DB676EA7640D7A7BE6:\ +8217EAB21AA0D8A541AB0CE258E96EDD82866A5460455B82C339F5157C2B159FD8CA8AF0\ +413BDB5995EBEE6AB6E1F8FBB03C67B086DD2E6AE05E0B37ECB43EC2C77E9510F24BA1D6\ +E5D4906A10BEDEC2D3ABC09019274E8D09CD3921B3DF7F9EA607011655C684C3FD435747\ +6F97C1FE8314A80AE372EC4C4B19B5D34469E66A94DDF0E0C5546A290FE42A3D00F071B5\ +846DDF4D88E320E4AFF2CE3D650DDCE965C16C3943F1EA5A63D9696F8DCA6D7D65C3FAA6\ +157549B214FC3B44E6C62D124EA327E97A91126256CC475A5C533CAF2EB3F6B08769436E\ +CCD52D2AB31A87E1E09D00D2F835BF9A7356EF71:\ +30A6450164DA25B43CA6DB430F827299AB79CA4A52C636C690F7BBDF82BA9B0E:\ +4A87D1FFB56ADFC374C09B2F8D021CE8 + +3F5E7DEA03EC52DD0CDB0030F676EDF2EC5B91C788D1AC9F8E88391FED510CC64123E47A\ +C2B685E5387365DC98DA305A832BE09C50F2E3E5B97E02C92F92EFCE59DD0A18E1227661\ +719B54397B0367359A1EE476E8106D2CAF3988E95BCA0947E2411574E3E61D79BC8C6FF5\ +F7D806BDA98E0C69E4F44F70E9B2F1178DA75DB504D3F8096AE002E2C7C36E95EA3D37CA\ +3807E760424D022697FD763B1B85E4D4D15D95153BFA3F74BADF46EC1906B1904D250E98\ +4D7CB5314EADD248A801373FBE2D9EF1B9D82AB3FB0C2CA0F3F9EC0F83268EB2464E40E0\ +C40EEEFC1B9C4859A357CC62C5537783D7437E6509689C6A:\ +E4E2000ACFA0762A90E16CE545060CB60961F69586A8845D37709DA643894EB7BB29B2A0\ +69E0533EABEA770AAEF101CEC381983F59278E7EF2A55B190F7B758DD97050315B3EF563\ +CF92CF9D2CF955F266C77AC4AC8BD7BBE39CD4F5EE6E57854C8F2DDC6462889E1F02DF8A\ +7C1AC02B65423A17299973745C7C4F17E4579F514F199932D98062E3F0E141A8133CD974\ +A4B1C8A066C4800CDDE54424F4BE19C4E0099A9AAF11692C27E182AA55DEF8A439A746E9\ +DDB83F674F76F297BBE8C1DD7F4A4582260DB38C14E6FC40FB1DD429FAD55769A89BCCF0\ +0677FBE04B07C5BF6380AC4DCF47FFE08AB15370ACF4082A:\ +9361EA127351940052051851106E32E21B5B74CAC5EE2C65A478DC07962653D1:\ +F6159606256712C7DCBB2F3E8ECEE258 + +378FB5CB6B0FAD01796C73A850C8EF78AF71CB2AAC0CF7FE9EDB58D64EFA6D138FB8FF48\ +4500C5E15F8013ED56BADC846334DB7AA6DD1B0C55BCD1A32B93A86B54B74D06F3224369\ +D5E2ABF310A13D76CD3C0E037E161047CCDB49C1F117097AB42E0CEEFB4B09EA86305C72\ +D1627D53C5D8DB79070F20BADF51DAC0F6D019C7520DF841978F0249E24F995D4C0823A5\ +CA663B67B25EEBB8A38A95D27F44E425DE53CF55E5E3811CADDB9C0AD3C415587DB968FB\ +1F2D93D3B02D5628BE64E09AAA0A79E9EB6B72D0088554E77574315F1152F489ECCC4B8B\ +9705B10C96CDF2368DD61D8A345570B4751DB4533643C8F10CA2E5E9:\ +6EC13D2297C89EBE84380FD858E68FEC5E09BA9F4974C03B0C1A098C42644170358B7926\ +01D88B40CDF56ABD6A2D8B7CA430AF87EC349C2B11D44731A0C219F0DF310832ECA798BE\ +E87C293C8834CD74724E96A6D7A1DFCEFA893DA180CC2CA8465274D176BB0D25B1FCD04A\ +3142EDE3B74A6D3E1ED86F3289DED1E37D32B9925C8BB51913B2850E5DA43159D4F70F64\ +06F5BCF600B1AFB2244BFEED3B40303C58892BA8A59151F8E2649964E767D918771E2681\ +26CE88156C4FA319F65CB1E2909F5A196399B45EF0B040C3DCA7E79232E4782041C7E6B6\ +5C9C82D8B4517B469493A46831B9E9094AEC31639E353F40D3AF1488:\ +2377222F39987D62CE8CB5F64E88437543E20EBB58F2DCB159E0AECAF439217D:\ +2DAD0FE823C71638F1910AB8D8924C87 + +41E99B44C7C94FD5B8978507A99DFCF6EC7A49304EC6099AD1C38DBF8BE918860AB5C37B\ +D13253B763406AA6DA1CE6779CED6F7F7B222CD51967BD3B61FA48F6B65B96891E34FB58\ +3E0935454ADCB3CF6419216B798A7C0CE5402A3232510940839D4DCA082247505CD68D73\ +B1AE4E352B9A95F6CD68CACF68F28A525CC3DAA1504DE85B51CFDC3B693DFAD28D4ED86B\ +70B93B02FAAA0BFE452544C81ADEEF99A59378CE0625234EA69E9F69ED52D5FBB6687F9E\ +E248479E1B29ACF0CC3BE7BA5B77537C29CAB662B2DD7D8937B9DEE577E7C8DE85D3CEF3\ +0912FF62687756C6F978FBB147E6B27E923C62F9A38BD7F50D8801E676FA07DA:\ +BC7838EBF0287786D89BAAEBA8ECA378E898BB36A6D3D6CC125938D71768BA704E30F9FB\ +7B09A43D85786790FCEEBB46A2A341C4EA50AEEFF3DC57005DFD7BE9C4052AB3CAB38B11\ +221EA39EA778AC6F4111CD1978E5D467301BC7ADDC54D084F36652A9AD3EDB8D70AE6380\ +3B077A39CF064017DC2A8CED0E4B1A7D6FAB58B0FC92684778B7B3F5D76477CAB7C6C1C6\ +AE6BCA1F661CF26DFEFCD1DB5DF58F1358D38406E3D880F30E43E1837132B5DEE65EC09B\ +7622CDA1F52A78F8EDF870D2AF375C7526C70E43FF650B8EDCF6A35D02CA479DD560A672\ +45C7087D0376C9915777FCCB390109115AAE52C4512ADAC046C8C1E9092F3018:\ +19F394E4AF235F4BDD3F0798E904A2E114041B351F0D71C5BB269845BB53D4B9:\ +093E57768A6107B8D6F31A083B23B3FE + +20143BDD828F687A93266C2E489909BFD6D85884A40018082FDE227841647D162DAFC241\ +40580495B6E0C393CFE2BBE80615C87CBF5E057D74A4CD7589DE69E136870A24AE67F9F0\ +FC7B92369903718B9268500155ABBD6C8D0E81FB1104403A02A56FC82F1DE4137EBA1433\ +AAD9CE7B34198ABE7D9845DC462DBB4FC6DA4F937EBEAC139339B405ABA51BFC9B06B38C\ +BF17352F47C6EF3968F06305123888130738B887911567A28DEFBCE943D18C73ACBE920C\ +386143E0B6B2C9EA30C84A7E4196481F93395C8BECE5F9B341725DA7883DD74792AD0140\ +7A05BE7A2121AFB2E9EAEBBA7574F9582D0455571A077603A511ABBEF9EABEF4553A48EF:\ +FC293D577FE018127C31A901490F19DD72D0A3212C828EA530B256E563874E03C7003668\ +84568B2F58B0478B8953F5A667E070BDC386404C47A45A862626D7F621C5E87C3F48A15B\ +8F7DFA5EC168ACBEE32E08551DC7AB5826F42A75CE8A0A61BB9E1F4AD5BE53AC87687961\ +388BB809ECEFDDD93782A956F9976242B20B1C2B5EAE31D28B48A44337AC677C6B865D89\ +954E1159353FCFA1741C287FEE15473CB4004E400FAF336995004964A79E2EB0FDF48C2E\ +A09120126443E8771F9700718BC94E5070DA8DAC17BB3F73555F3942AAC1C2830371D641\ +7EE51EBCB1ACB8B4C74BAAE38E6CED7F7622388FBE2B2153DB6945B77AADCF7DC99502D6:\ +BA516D7A4B7638995562CE54FEFC84B6DFB4B8A81A03F24BB065B060E4FA2966:\ +23C93FBB6EF742A576769819A5BC6AC3 + +[TEA/ECB/NoPadding] +2FA6A6449FB4F998EFA3F1679A638602:\ +4D3953E121FFDB4FD7F05FC74FC2ADFC:\ +F9506AECFD6B86C4E9D5D973B435E66B + +B4C8B417381DFC14CD6CFEDC0D83477F27B0B1BD842922D4:\ +7608D8A9F2BFFC14DCA6942B2867239BE3B4788D8748F314:\ +47BF1198D16C123C95496D0CCC9A5C8C + +18DE3130F51CD7A6172B3C79F6DF435B41F57D3B2D54DF7A436ECCE32ADB88EC:\ +58AA062B7B9EFAEA2E3ED1F9D19FA6F695B0642EA7FB6EB5C5ED914A4034134D:\ +3D8D2CFB7424BBD7B39BD9BB2C0CD794 + +64E00DCC29A3BE3695F2198E58EA42E323E99387CE99A0543F7594331E546EADD7163E62\ +5ED6B32E:\ +EA6EF6ECA267C02C2C98D03AED4402A85B8CC02326D1FFCF169D321F675C23BF530FD4E8\ +AF7A511C:\ +C1C1384840D2B15BF8751CBDFB2607CB + +CF70A73AD2C4714044C8953EA103DDD2848595C182BC6A703B2E6CB90E80357120AC671F\ +10C8060EB2A14451BD69C9F4:\ +FACC24C79AD55C3E2FDB55AD21F52595452E116FC526ED3F21C4386D0400F098F86D86C4\ +E630E638A24EFF839EB8AECE:\ +25EF77ACC4435B378B0A07AF35D7A283 + +5AAADAFF6BF18700ECF66DCDB2AA201A1B5C338422E654A9E769C0EC40982E2FD9A794E2\ +9951C6EF26AA3FBF41B29E7457B6A2BA4E39F75F:\ +260629AC2B3838BADABD4765B0BB6A65D34927FC51BD712A36C8AD74AF386422FC479EB5\ +1C5FA2072B4D4A3F259A761C4CDAC375E0FB7883:\ +B3763F385F9F53A76F59E9E9B8070886 + +10D5908E8AB77BBC4B6A2D89A13C899C9044E2823FCBA56FBE7312A7F475E16AB3B26E74\ +FA74390B5025C2399AC84EEA37326A6F8EF8D133A3E27EC6A01F97B1:\ +1421E0144AA1061EAA75F81B44E12A8DE1ADDCF46D4E29D636F17565AC1326B8B5E1F2EF\ +097E3BC22CA2FBB5B637E17BF164DAE5B8A0D503085EFDE1E36B82CE:\ +84A6AC5EDB9A96C8BA3BFF40AAD9ADFA + +C65601054E837A0BBC4D0A50CAC6CDCFD7EC9879316EEE2979F6FF139D881DBF7338DDAF\ +02F3700BBCD7ED67D605030187A588775A3604FFB20A989D6893FED3814179B336111DC4:\ +7F65DA6551B8C2A677054CBFA5BAC5B8CDFFE2593F3297B3C6014D8EE83B00DB0BF063C1\ +68A4C155705A7984BD961A0278BE247FAF01E3BDC6DF3EBA4D39A0566F59DBB3F1D682CA:\ +0B666EE6C0C5FDAAB1D3C528825B8262 + +73ABA32AA3A6D791EDF7C1FEDBDE65950ACA8E7CDA9AA303DAA259965726F7E54EE8E07B\ +6EC41EE05DF08A8030AC76CD419CAC55249E5454427C9EC1607721A0A8DFF4200175B5EA\ +B66D6A33CB1ACC08:\ +39D91242429514DB8B2715FF7CB1D12AE97AA9B31286E672DCD6D5FBF9FDF52739F50684\ +F629F7F8F47F4840E399725DB5383C4427FD920D0091B8466ADCE80AA86E945AB09F9999\ +DE7518991229A9DC:\ +6CFBA581ADFD1DEFA555D4B1F2924E67 + +A9956670B38BD99613696110B2717482945A798817EFCB34254271251C1D7912F966F78F\ +DD0D534BAABD440A80F75FF20C5D62C21327803FD957699302328B03F12F17A9D89CCE84\ +3227D99E3F223C2E1EB8541FA4DFFDC1:\ +27F0468A37ADD1F81E6C453DB2E89A741C4949D4994ED22D4473B40FE63642B0303933F7\ +4523055F9B2614DEB0A5E4BE8067C9EAE91C573C6508610FFC6CDE32DB8C3BBA9803F9FC\ +F1A1A3C8CDAD99F945FB9912BF38BF24:\ +35927642F001AF7BBA592C573D566B04 + +2AE6CFDEFCAB3176BB1D7C9125F75011127F87F068846B5BB17C04457AA795CAF2459C7C\ +351CCF870CDE051432CF0019A5C411A45979A3E318523366138501A8C167A05B959B4DC7\ +C8735B9B15691262F2828A22093EE2BC15BAA5CC06426663:\ +46594307F5E0E998848072D2690D97E32058FB1D4577521FE5AF518C325762D9F076B15E\ +77E04DCEA1C8A2C34A287EFC5F9A301B5FB4C75699A3DFDF7DB8B7EBD61D5BB2C1F880EF\ +CCDDA930A8478C7DD946A7BF9EA906F6C6C930DF1BCDC51F:\ +C4A3785214040158D8D9037A9D5FD25C + +BC139112FA244D06DF5FFFAA2E44F58F29AE8B092395B9A67ABB435610674E4FF71027FC\ +E2C3EB95F7CAF7E05DE6C095551AE224A97807297F64C87247A34BECC6ABDC900259EFD4\ +048D384AF5481DE995C8ADE6FA7F982A702A44422EC022699B783E7EA57B7A2F:\ +57D854129FB358772683BB1BA42AF91F7E945F1BFF27AC4EBE6B531A581914E8BB57834F\ +D16A9E287544CD2840475155E49B9F6859D9E3D235D56CF5E7ECFD47D43FCF50A378287F\ +9F9A33AF0E53983456D75A58FF5111E69D768F25DAF721AA9C69FBE01F2430A1:\ +4A9F7BC01C835442B5F4EAECC8FF50B5 + +51AB05548D117A49B3C47D2BDFD681A9FA39A1D270437AF03D5557BD5945C66D44842890\ +2152A2DEC23141E4366B55DA9A5FFF68C6C67CC2A7446EB28125986E945D6B7AE587EBAD\ +8EA14B066241B54A6485A9878837571346E7C416376908B74AEB4C5D022080BB79D0DA25\ +B837D53F:\ +BCF3B29D04DE30C8EB5345C444E3FEDC5D34EEAE60EA71BC355F21F69E31F759DED7AA43\ +6EC595505E1631A52F5416A41A529F39F6958499E99EA5DAAD023593A78DFE9C443C5AFF\ +B6E4D9EEC22BBD66545A67FB8F39799149A1601DA998694D7BD65AFF19AD1326F4B988F3\ +7E555D78:\ +A076529A62A7C604739522583E1EC20C + +EE99893A9B1087AC531F3C5C67902E6EE086A11F6D28B3A41A0A692A15EAD2E0A43A3432\ +AE88E9EB54944F4138BA95A4E52240B3CC34E1EA6B764AE2703696493F45467041578798\ +1CBB062910A3DA1D39ECFEE971EFD945B44A5FF4C4140B5893A89F6F454F9568D83AD429\ +272832258D3D0B82B7ECD00C:\ +641C64CD007BED6BA89AA7ABB2BA478717C84844D06D0F83251B8DCFB0AA02FE8991F06C\ +DF5328B4195B272807B242A0CD51D9C9CAFDBCA8773ED2048FA25360601197C1A8AAC3BC\ +AA05B087FF38F53072755C1AECB169CA4EDDECAE1B580433DA6CB30F4A7E33D02C6E3624\ +982853DC5A77BCE8E3E9217B:\ +7D9FC06731D5D44E7D137AFE5F7CB7AB + +E687266A896382127FCDF60A3F271BD3BD21C0306B8206FE9D9F2B00F4201418A4DACFA6\ +53DFD029639AAE03A6675D3E2B4ABA7E46CFBE14FED665E0F520F110BDCC4E5647BC3D82\ +723FFE0F588062E56DE991922E9F23FFBF2E1BE91625A190210654E0B2476664568B44EB\ +58117317C6B61645C6907ACCCCC4BE949C9D3ED2:\ +0058B2D35FDED2CBC91D454AA55F93B0A249152B3A5C9DFBE907E639CECF1B90580907A2\ +9920901AA5278EABF189DB980372C2A804B2B301F8262840D45A668564C634191E027F69\ +1630602423B9069279FFC20B181CEEB2CA6C15B5A66B9FDBBAE3B591FDEC91D41413AF30\ +36EF4A99E9E1B728E901405E5EACBAB539BD4796:\ +3652786521A31CD6A927E608CB2A87CB + +6A5A797BFCDB31CA65F7A0D720B679B5C7CBAD92508E93C565E3AC94DA5B84C041D2A0A9\ +7CE0D138C2D48E8F613C36F4C9A9ADA0A32EBD5E346A0A76078D2B49E559BDE592977285\ +77714F3EF016A607D3426297B4681CE7FFE958B5750F8DB6F88916C5DD61CA30DC2CD2A2\ +4742EA7AF3886C792E1D94ACD6DAD21649A8BFA6F907121166E51D97:\ +1DAFC103EF64B21BEA443931DD0111CB06D5BF42D1824C4E3F3A7D6718F2911756D94611\ +7A12CA4974F9BDE4A99012615D6D1B78B94349216FC73CFDF7BF91126F017A9206F78310\ +6E636AA89EA986A4F4942A8820FFF0D0B151E7A74397EA186AD85899DA5AF661566A3BCB\ +3C7305DCD5113F12E3532B803E0ABA376B232EC1328F3D0F1F884835:\ +FE97F4A2874358EEDDE14C5A1DBA9731 + +A420F0855799B02E78C5A8087857A62E10F6448E3B02257AA678A7895EB9CBDED44D0ECA\ +ADD6ECB78F06CD65ECB8ED2183F62691FB42383E4062A5EA5078F146964F1DE275CC4493\ +04D319A4EF99A07C09B35F4C59E6AE9F8799C074C42BAE060E463A25078A61CBBD1818CE\ +C67CCB08BB4CEC9A4D3B146007C990AF9E723F858F7D63B81D4536243694AAC2F4C02CCA:\ +6AA3148AA2E4676C3ABBEA8B883560168F04843310B7871174C21F906E4049752617F465\ +DAA843BDAC395FED435C32CD2B497D2A58993282E1FC36113060AE36620AD606E0A32FD9\ +E143578188FD408D98C36F2A4134B10431BC20779195F5BD01F915987C40622D6D813CC4\ +8684D043AC74994B61F2CFEC89DA1A8A8C44FA82355508605324B20346B62CBF42649803:\ +5F5B428DB8D1FF5165F7C6691BF21794 + +50A9163557E25C824A3DB605486E137772BFB26F3D60AF6431065B11DFFB65B5F46B4978\ +6612857935365BE801D978A860463351EB37A62BB66EE43E0B348BF509C3AB450334DDEB\ +1FB04F829311998D026F7A66FC6E06795F7268D0E4B71BCF674E42E9851AD830243EF28B\ +854A2CAA00541A5AF0A3E05EA7A4B445264204516A7B824CC8FEAABA992040939E2D13CB\ +832A821267928B88:\ +E905FBFB19EA75D647CAE71A3E4AD1FD1150101614109A06C4BEE3E8CE5E677FFFDE252D\ +BD7AD0B65E9A47683D10B32E5EA1DEC50746E8ABE6B562054F1F60AEDF267308583DD209\ +157ED0013F91C76A58740CC94D46584ABF2145D441C7721E5C41A7B33CBE13A09D05A569\ +C7C0E313232282FA72B2DDF8107930C6A697D9C87EE66DA240658EC5254A4F8E4A99425B\ +A77E6D36557FD32A:\ +93BFF08E9CC32466F4436111031037A9 + +BD4BCFC5B25FAAE48AA8F4DB7FE80F14ED076F13DED25A3EF4784882F38838EEBB4757B9\ +BFB1344D422DC20D93EF2947B5D741BF945BC679BFAD074EEA9DFF9CCA6E49B6C40EEAFA\ +40733AFD8A21E26E19E9EBF66074C1102AD6234D129B589AC7AF71096C128FD94566E1C1\ +29D07E220FBE9D4DDA25BC71112D62AE335702CAFB7B46DFAAD51F6D7B4462A86400D030\ +CE96B577F0F8C43DB342E4C700C21F89:\ +1C2FB8256D92E620276C95006DF21ECD2C0DC26BF5752369C57745A27538200A5FBA2A08\ +B3DC4C6B7037035E96A7E4F97DF66B5FFF4D0AABB520A15D83FBA17CAA84641142044A75\ +F675637143F2ABDEA9631533877D3E77CA68B615A4EB9DFC4B0C27BB777604EC60950D45\ +31D4C6DA5412661D2CFF573DB93D4D428EC974904BDC6CE92B0F137188891DCAE497084F\ +D3DD3A9BF0991E7D954C473DD7075978:\ +07EB031C2A50E81BFD6150BB8E279F6A + +C12B1B0A8CCFE8BB72CA3C353F855F7F226DF0F1FFA791785506E972E19D153A92DEF0D0\ +82CAC0B4318E5C0C597638EC01204BCA002AE8BE1624AA4DDBC50759B8813F6533184181\ +395AE665962CD6BA22D82C1B4CD82CC4D2DFC07884C784398D596095B4ADF4A4CB5561E5\ +2C5DD85A2EC4642EF902A91FFD4FA73094D9A10D410743B82B24FE1149A5BFDAC8469D4C\ +74282581DB20BF4DB73321184B29E08D0A3BEB0A56D12AB6:\ +06F1F55E98C7B67858AAB0EAB9ED413B2E8D7BCFDD95FBDE16151A76E3E314022918B276\ +403782EEC2810FB10B8E6742287685675C67935217023EBE32994E1B1C7FFAF3C8E18EEC\ +CCBFA47DAE25377A1D38CFCF9FAF92AC99EFCA34FC70F04B03D1A2E8685B2CB2F513EA6A\ +49130BD8F220267DA4FB22E2FA02AC9B4F2FF554395BA7E0F85C378474E185DE7B04E01C\ +8929560B399D768267B352CA4BDA75FEA3B022B2790146E7:\ +0347E502FE1FB58BCE93EBB16AF1671B + +7BCCB586FE4F343EB7DE9210AAF5A5F81E62CBA5ACCCD897ED221CDA61E2D4F177A25002\ +F5E12AE2AFA0B19113485EE793F3C85FF14D7BC94B23AF502ED0118E78192CB4FD680676\ +194A99157E9349353E907ED93A869A1A9BE721ECC94619E26F120A87C1E227589901C161\ +7328D76F6B1555693ABD6F847ADFAB14CC936D3DA4F8F47BC5B77E323F23BD4DD2488222\ +45213A03CE770FB50D40E174606D3318BE3F76FB07473ED7034314E16567098D:\ +B42FBD0AEC444319719ED521AF7CC522A2F1DD69ACB6C6FC08EF1AD52415DDAA4E94FDE1\ +A21BDF954DBD56681E2E3D89C6725E716414043C42B0CC842B6A326CD70770881E047D59\ +B611B6595FAE0385111BA18CB19359AA7FD318B528D48348EB51655AE17B6DF79DF383FF\ +2F3AD856BA42598DC2D94921B4A93E87BD12490DE43C454B30F4093B30878B5BDA7D6711\ +F68DCFBA6AD0AC92804E15B6DC141A0D06CB962244700554B0BA4D399BB9D935:\ +5922D69B966C705B91F8DDB19DFD15C5 + +7D578CFBB35A1026C7AE1B82405B5F93366BF2280C6E6FB42EC515374AA2294534B1ECB6\ +7CBC925E375D4F6B2E1451CA1BA569D494FD5C0FCE09F9637C83276AE3E1249815445D60\ +E47CA8DD9EC7B846449C73F1648640299EFA82C2E696A0F9CA9738DFA459F8AE04E3431B\ +B702D4F6D41526DF1543016A8E0FB1DE5E5258FAC9DF77CFC07CB297BA2A2921EFDBB0BE\ +4F355197409CEB98BBB08BD24F48748142321E66C9791E93E8156D3FEDF7B3CABC0C4014\ +8A866D28:\ +50E48B13EDB839D430DB28787D20DDD4C070730ACF59E9B235F101557E88905B2B8766F1\ +9421718D82EBFB7FD8075D1239DB19BE2151782075A761A7A1B78B1613D95340083BFE44\ +9B502D5744512CAF2C33ACDE1F1B18CB53B152AFF2078319399858A3356DD710A1D181A6\ +EAD0EB9C1ECA868CBCE049503E372BF3B9364B275A6D68D92F2DA3396FC045A816C2E9FF\ +E3797538483CBC25A97DD93E7CC997CF7469E66FEF432B9F3C5F2ADFC55235710EADD2E8\ +FCA5AFF8:\ +E5C7B48ADB3AB291EFE88CEBFDC612D9 + +FF2E2C4B8BF3223B6513D612666415DA018A608BEFBCE8141F40EABE933BE55782E1355B\ +5D87FD7A31374EDA7BEECD24CB798A458ACC60ED063322CBCDD796546C0D09AFC04042A3\ +48E30D83309DA1EDFC0D631F1D1264D02812AB2F1ACA5E71076FA681BEEBC71C0104CD63\ +807C1B1C5FA543A2F30D903FCA91B6E946923FD57E1F1396B33E4C44F057693AA8413917\ +002C185FE0E54C2E0FB478B324E7237C6F4A5B439C2B52E1AA4A190263F5B6941244919F\ +AA826358C3F5055A1F67AB4B:\ +44FC4977E72F10AD62AD3E3FC7D868FBB09C4B7CCAC299E9E299B3FD5DF116C837B5D985\ +7AF8F83E97699F021F673679296444F96EC481F2C71DEA77E571DDFC49D9E453235A9BC9\ +3DC7CF60B209F305A2420830777D4B3732ADAED70B55406C777EA7CBC71EE2E58F89FC1D\ +4A1AD84A80B8F57C958D887383EEC107D5EA2E8297D75D588B24C8E42C2AB11FB21322E9\ +97B11DCB9AD7C825638BCC25A04E7D9311F24638418095D28259C74E718123CE597D2204\ +1CCAAC3612D803335DB4E21B:\ +A830EC3F2B6EB4C27215F68C373D51CB + +796E00B9B9C314F46A6FC4D30E251CBC99C0A7EC1012D4C08B3C709F8C42A0A24B52AA86\ +A8B4EE6C0B40B9AA749751222CE2E40E97467F8E49498D3EE24BCA8C3F6271AAD7AC9F69\ +F56B6F911B8840AC28B10DD63EAB8249A85747F5B97CF2BD18CD163BAF26D57C8E5454F1\ +62BA6D9758151F53D3F45733C3464836491C28963962FEBC6985DD4BAD90418C5CC02758\ +F59E001179888D5C56310EF3BD19660C98B40F39618C12DB9DF20A1144E4D88F5849F2A6\ +19903B91A4F88EA8CB0448B2D02ED413C71619EE:\ +35D5A3EBBD297958E923D81114240262166A0E6BFC0C42EFA099C488005ED84257FB7432\ +4568308109E76AC28EC059E7F8E612C2F8639C4510F996D311581D898E13DF6031385A62\ +0C5ECE9FD0745C7E7BB28323A16186065AE236482CFC37F227C99B6EA79FDB095D2E13A0\ +0CEDF8D91648CBBCFE9A72423485899CFBFDBC2CA6AB2CFEFBEFB38522EF1CF2D07AC68F\ +29819E17E202AB863F0878713F1CE248349E4139DC8107328D9907FC8F4987FC0392B120\ +F06DB28B7767AABC735535BB9FE18178B5BB34CE:\ +201C9CFDE22F6BE8FC881A4BE6862199 + +85BD2383419FFC58425316A0B1D0EE6DB75CEF29BCB06C55D961F1880C930C4536BBD490\ +2DC33C528957409269CBF90C28468F4260225B30C1A11611F524B4FC28FCC6B1BA85064A\ +CD5AB63686E8DA93A938081F14FF0D7BB4FCDB12B68F9A2821B397A6FEF87511FF67B8FB\ +C20D4338A00B7AFBBBFC73CB832346030920A463617A8E046E5B9BDEE2950DB7BA80BBDF\ +04230094F8357062AC03E277AA68D14AEEF8DC810F7BE6C51FB8866CC9FD24BEDE265184\ +EF7EE936EA79B68C9ACD37EFB131F2647FC501826A4F4CC5D16D4666:\ +AD7D51359CF9E854759CB435669B098EA48DD89DCDF882E2781170086EB679D6C45AC3A0\ +4583FE8BEA6A315CB59541E3753F800BFB186E9177A8E299A9F55E1D034BF8CC876C2F46\ +3D1273E320FB6B35FBE5E6DE0C3C205B6FC0EFB2A0FDED8C606E0422B0C8D72222318BF9\ +B1A3D7A0B527253BEC8C9F66115655CE3175828B6659352BBC461ADFA2133808D872BC1C\ +DC597A2EEDC72A1D2E2644275C60144F6C7EC00C43B6BFE2E4433A6F42A4CD2073528174\ +C466AA9EE0AB24429726029FF1834254B7A839A0D8D4643C131C1BB7:\ +271A2BFE528BCBE7A13214409BAA2E12 + +89DCAACBE537D9028953B0BDD28FCFD1E745D6D457F48F9247F51A8F6E9719D85F106E8F\ +794C6CA57247966AD2F878421C35528E95CB5813413B6E8AAD530AB09168A012D0027068\ +D63ECF4D7D4783BCE8014D34852F5A52C66461E15C965B8750087C43176E70E24FD0D4FA\ +83D4B9166C6311E328E08BEDAB29DBF554AE268476E507D7791AB3475DFE90CA3F3A3B64\ +07BF67E4BFAA67292E3ABAF6967C5450E17C2CD3C096C501B0180BA891EA951E99FA418A\ +CB72BE2FCB74FF143BABE55264F6B1BCCA83B81856544B843FF59D9668BDCD7EFC2F1F0A:\ +91B44C174E57C20AFD631C5B21B329A8B438C3249B5E0A4587BB01EB3C3770BDF67C16B2\ +4DE0DE2D61A1ECF3E00094BF562A21B6E2B9DD904CED2FBBA18A18A4228B958EDB1C3FF5\ +5BDE7D544DDDE97C67C1EA5E1FA4F0B0FBD2775B93AA02F4E6E19A43ACC14D022CDA7DED\ +E8B2915D8D4D0EDAB2718E56B25A6AA3C79B63E5DC03D57F948CE7D78A15FE3C0C781B83\ +B5B116816D55D660F0B6ADDE327231069DE6015C622E456AD01DC1EBF527D05627AD3BF5\ +A09EBCAF9392BAD189B511F6E429C1052E05FDAA558CB8D720F5B08AF5C2B7E1D811DB11:\ +8588AF13229A77FB1006467AF02D6AF7 + +A3647B24A430D05146C564F62665B74242A393B47ADBF341DD56BB1855C0DEB052A6AD5F\ +4661A45F5107EF138BF5FBCF03F2DF6CA6FBDCE61D91CC9327D476B7D96061A4EFE06D77\ +A608A78A716541A4C1B4A9D99B473295D293F37F6F3E982CC8687B67ECD9C8B999FFE97F\ +1F28F23531F600D2D91865BD7144186A53B823887FBC4E5B25A6F233386393E40D9FABF5\ +B4119E83CB614CD4D302D999AE00E85F78F22687BDC1420784374B87CC7EB772BC468B01\ +AD895259E94FE55159FB5F6EC7FB5B7B1CACCD09884327F174A60C38DB31D6A8B8925D75\ +309D2D2850FE4E8F:\ +5ED0A794F77048023665D3B9FCF108C2794D98C4472136EC491F2EEFE3A2ACB89DC6A006\ +7DCF449AF304E0A43ACD79EF1C8118DCE1A73DEAB3CA002390E2DE166F24883619491723\ +AAE01FDCC31FCAB8996779604A36F22B1C8E418054BA9164D74CA8ABFD0C39E31A0FE97B\ +C4796802957CBCDA7ABC8AAF298C007F401B56EA023D26720B5DC3C9843CA604AA6F820C\ +EFFF2A38681A2B18DD37450CB853F5A5612C3F7083C78DE65CDBAAB5983337672AC050AC\ +CC013E6DF3EE7AAE6EBD91D328FEC89407668B5BBB40A94135E071A9E20D0420D24A9E71\ +9D0FC72A3136217B:\ +BFFD749F285E2BF09E6E1CF31F485D27 + +5A52582DAA9B17977B476F718A030152C8F4A9C8BFAC2CE9A3A78935B4B9D7DCBCE4237A\ +C8B51464E33568F6ED94CF29A2BD367D38D059116C57EC69BEEDD67858E9C06420C082C0\ +D4C18FAE8B617EFE427DE7BC07BA2BE9BC9FDD9CD15232FD9A9B8B3B9B9BDD2F801B69AC\ +5EFDA6FB9E2204FEEBC4FBEE4432407894C17DB0B8E0BBEAB451B15A3AEAD171B937E845\ +1664C3A80E9E28F8F4CFCD2F28C1B116CA3CC2775632BBB14832C36FC70073E6FF462B82\ +6F3EB092504BE6A14E78AA2E32148B2E63BB8EE4B2D7BED5E8E2E8F025852F03A65DA77D\ +3F9C6BB6B373C90F6B0D2CB5C2C1AC0A:\ +88FCDB413A956FDF038C69A5842363FC82F9D3BDF80D5574DC0C6867F7EE21EA4CF72DEC\ +9AD83D5F19F9A71B71A71EE76645A153047825B5FCE892CEFABE49F6B0D768951B2F03EC\ +A4EC7200141895AA87EBF85CC33AF12EBF0189DAE5F6218F4E485873E994BCEC2E007AB9\ +77BD2C8C77792F2DAC0F29B8F8161B2CA99C4E81DC9DA37FEA73E707200697647AB6C73E\ +0DD1D837D329801A7B5F56CB137A1C23F5FA66213E720156C9AB67398300DE5F979BF4E1\ +DB8C8DF0E927EAD3DD7F44302DC9B39AFDB4F287672114288E24BAB76CA10200DB56A428\ +A671CB66EB2E4FE80630B94152B06158:\ +C0DE2ED5FE62A1B2973360E18660DFB5 + +BC0990F88218EDE0DE9835353BCF340C5463CFA55FC4551DE21ABFE260A8173591D44A82\ +DCC62CA063F395396040F4B09E4CE63BFBC1C1F725FBCEC1A129124B111A9D393D53AE65\ +330569846DA3FD18A682B192773A76649BFA999859B9EC844C6B4496981FA13F8F7F0575\ +30879998BDBF8D3ACF090D5CF543ABA1E9DBB72B6A48B85794BF212BF5956DFCA7714BC2\ +38E5BC3E785916DF9D27A0FB4A0A391314B072EECEACF50DC8693D5777C45E932F5C0314\ +A882ED43AFF657935AFCA0B3FBCF97ADB513C754BD0EC82482DAAA8497D26A9E7F4320AA\ +382903AEEBC83B53CC297364446664424ED246037F063BDE:\ +41E85AED70C8464E353FC6E2D5975E0FAF5DB17A8573C7DDE4BBE0E29EB71CDEB210B794\ +D0FDFBF7ED7254B1EABEBD8CE203225CC4C2EBFF3B5D5BC51E3010F9946289BA3BBDBE4B\ +E7C3FEFE7E7A390B628E29798E732382B482D84D7863CB0A85F6F3CE1072CAB120960D05\ +FAE3510D36C9718DB4CB4750565C8745A076A7BE89F52A16DDE9D32A42CD635340F9ED1A\ +A39132E30DBDE32FB28354C1DBE9BBF817481903BD6EA8CA4805D03B42F2D5000B43475F\ +CC4103717BA2BEC3E2F1542BF308EDA7E2C71956F32F50680415685E8106E701E3F5303D\ +79F03214097A4874CFC0664BE4815BAE2769BA2CE11FD663:\ +C37E924EFECE82E275AA6115E2E2EEB7 + +C34B10E6DD28BEBD7DE1BCA43D8AAFC65917C51E848703C034284FAFDB04DB3FFC0F3059\ +9C923C6BDCF006B47786E1EC68B9D9BDE22D39294CA235E43CFD42DFDFD3D4C49FD778A4\ +F61F17198851FE3923CA6DCBC8A6215E2CD8F24E110DCBA58A63058CF169A4CA4A8EA557\ +8030CCB2EB03C95871AEDDF6A090FADF44F8D43D7FD36987F31E0409A7615687C1D3FC0F\ +25796973E96A4DE0382D0965824E9A81677D414EE29EEAE3547BCE77BF9F6D3E6ED1526C\ +F1F51130D7DF5B6B34E89EEC7D8866486E02D5E654C920BC42DA3DF7F08EAA0681F13504\ +62B29792166D951CE94E5125FACF103D591C0E819667E42082FDFB7763C8C559:\ +C2CAE1A03A0B7D37D3FB79D98E425DAFDBAA0E2BBCDBD0366690C05D495014915ACEBD34\ +D320614752D0D667BABFEB9E3D5EBF5C1501EAD8D3C9602E6D33843C18F2868E237DB697\ +6536FE28B02233BAF37E9EC308A4E163ABCD4BA5422F92F5AECC38818371FFFF5AF0FC66\ +CE57DE4E0692B1BD82AAF95CDA6FF3C3C2F85CE16C54C151E32F146FC20AEDD4985E13F6\ +8C2E2224C49226545A32EC6C47974D2778184FBE289B14DCB78CE6DE17377557B92AC2DD\ +3C1102B74B2B04EC74BDAF85D2FC8F659F4F067F6C3679709A8F2BDC2429BB7F78F5173E\ +B3026156F2EA8FC510D5AA4482E1F5639F5514EEA3B5E979A0E54324954D47C7:\ +FCE0F56F8DAE31186336ADE3B46D6FF5 + +2112DE278B42F0E058EBE6BF868F544F740F0AB25C30459B6F198F74E8CB4E8B677F59E9\ +15CFAE5C208770C3AE03AE597D5B41C97AC6497F67837C20B5D2AC3F01FA5E831C8F240D\ +8115279D81E315060A77B5971506D7DCA40939A81E377015BD6BAE084861A9044271D2CC\ +66EAC30473931B26B5ADBB14471B32591D405B2D7C9F30A1B0280D21D5EF49A1D24F0E80\ +783D31E2A156CCA3F12C7EED45E471BA42635A04057D3BE56E31936E0BEF6E705FAE0E46\ +DAB18F9AFF3582935BDE554F650B21DF6DA8BD4C5CD75A58BC9FE50C03FA3217CE60DB9F\ +AC52A4BABAB8223A05549532ED8386F6D621E2CB97B829C0FE9886DC67CDDA9E3A0D19E8\ +70DC8E09:\ +67315AF4A1B112817E9922FB3FC8D251CE6BB7CC1CBFBFED1927A172D14B0C1D20A9E382\ +833306A08A3222FF0E11F19FDAD5FDF44911E46FFE688D0226B096BB227A0777B2C5F971\ +01A386D65CE4E71CA590BA8DF68DE85D50511FE1CC08F6F569B9D3F47D37A93BA28B301A\ +72D9AA736B464343DEC323207FFCE6AE59CF22916531B6EB6E92E5674C226E06FFF18F5E\ +9306835957E93EBAD84711E4B059A19F554E3CB0F08ED7AD6EA58730BE7BA5572BECC892\ +28FF83BC11F3036EBD8BFE370C7D74ED1FA03530E86DE89638CC7A1E79EB121F7DF32EF1\ +64AA1D0570FA6191FD88F7D09C1CFF5C55F3C62618017879DBBE422C6BD51BB320F7B5FC\ +00276019:\ +A0C7A1DD857747698B49D1E6127F564E + +[TEA/CTR-BE] +0779B5A4D94C4B572257340F8F86FBDC5AE955DB72E588CB3D8298FE27ADC668:\ +6D787EAE01A5D7946C8526B75BAAF2A8D1F13CE4AF93E469A21B7C53965A1CE1:\ +F580309FD46FC90ABA15E05AD82078A4:AF4D336BEB213C0F + +6DC828712ECC5C470541DF1602B85F4007CF93FC070CC7762D7956B7BB549B6372DBC08B:\ +09DAE7B36CB22B70FD79C64244E6E45987B5F7EFC8CB0B8E3CA9F43764807BE1027B7BB9:\ +C86E8F484AEB12370C20A3A0EE5590BC:13DCCD64DDBC8E41 + +5B65BD1306636A3AD2E0022E02E85269F20F76F45B136EFDF4C899F8C9656129B4CA8046\ +2AE80783:\ +E89A69E8F2D8150C05B56F2A4A944857B645B16280612F58FB89B08EE8A20EBE11C862D3\ +9A1A59A1:\ +4C55B486E92B56E40276A86483AEE6B9:3967D01A6CA67F89 + +311BD2A8AA6E97C4E84A3C322A53181D72A6C189C7B1FE6DB283BE9EC3193EA91521C1CE\ +DE7304F0DE4995EF:\ +10C9482E1BC5FC5F3E0204D721A9840ED5921483104A783D46B376E9B74BCAD25C5C4632\ +F523CA72CC6733F6:\ +2803FC9BAF7D0373B2D479046AAAEDD9:B91B7AD2875C1EE4 + +55243E865867E2281B3DBF43521D984804AD038D8A4D113DD1E118358EF1366AA82854D8\ +7DEC5C8051C9915F685F55AF:\ +02BEBB951E42063A106A0797227CD7CD037BDF9FCF2DB5405645B1CE17C0D6C36A361109\ +7B9D74599AA5614E90BA6046:\ +B45B330DC5589E6AFFE1A11C09C4DC30:04F4F13187E04998 + +37B0677F9DDBD8DB1496F75439862C17100C2BC735087B9A0970DA487DFEB9520B2C5B22\ +EC089777A710FC7C5EF5B7AD83199993:\ +E8DF3BF04F4EB8209BA30532885CB16F4DC4CFCC9DAA5D195A8F92BCD9B41ADE5B7EAB7B\ +1BCEFED039E3A3F8810C2B34A3E3AB24:\ +9344248E661DDF45BCB9B6E529B39431:3444DD3711244051 + +DB572CD1DDEBF0C06AE910471B108064A73851F460F3F79A303E463230162B99452DBC0B\ +0BE88A17765D4E317B04BAC5693A5B2E5A1AFFE8:\ +19D1415407B422F155D1E8EF9C99F2C77F68B39516D4CCD3AD020A4B01A64244FC0E3012\ +A19FEDACCDD64D948372A2D8FD2F7B7BBDBA8CD6:\ +215C4753906EE909902B163EF367BEE5:A9C40171E5946170 + +98E56143F834948EC76D2D3651787E8B6D1959FBAA1E4A8A8917091E626D3A7FCAE23E59\ +726A9B7E6808CD6245ADAD71EC52EE49F8B6983AF90165DD:\ +A2F29D9B387237DE529BBF8FA26704D4246C68F0C71FB986A735BEFEB239DF8220B3EE66\ +F0C8BD4B764BD4C8DA951BF3F0589315F5AE3E7F172F3F17:\ +63689A7EA77EE56313EDCD9092EE74A6:4FC29C5D1A03780E + +05796CA4B977B4D81B3F898ADB404805F6418425C6FA44C77ED6CF8B3A5C6A4D4692A3E8\ +A1D0AA88429C73DC0931BEE46EBDF759E16C975D8528EBE66092C686:\ +B8AB041041D2E9E48909A193956F9CA68D6ADADA5C2EB9A6F6795BDB751E704B2F9F3E6B\ +5531F2A2449C7C710367B4BF7F0EB293FEAC04D3C387B5C3D4F1F2FE:\ +F6DB0F1401BF9E04BC31F0E5AAE3B6AA:FF0415F250ACEF92 + +5456E7301B77AF7E4E571D7A542B4DA79A6C3E198E29B973DD482CE44EDAD6C8BA2A7C6C\ +044B9187C0920BF626E55E844C8746F8FA3748DA84A49D2393AB68294304CEA2:\ +86927873D7469420C6E817A1A9382FC03BA4DFECEEC08400E3B0995F1C695D2599B3612D\ +DE5017E0B2422F233C86859CBA4A038D2F9E1DD886720ED63365A9184B1EDAAB:\ +CC5B8B7E1D9877A5845D9F2C4070061F:EF786B15E7F3F602 + +E7CE6B54133D74C1D1F6370AA96F6993354E1BA145221B91B689B5A759F808D7861A7384\ +BAD3A192FDA08A36E9287B20188DF4131BC2D47457FCD3705C0D510A565A6E7D8EF7B22A:\ +3F1DA63F3BC4BF2691FD10D71CDFEF4FEB29F9E3C918C432AA7A7BC8F804E693B0A25F2F\ +935F9F9A8009959A118884E626F23FBA1C624CF719951940690C890AA05E8C87E55E3098:\ +899D47EFFEEB386DE8342FE3A3242FEA:CE412E40677E5BF0 + +F2369B2BEEB9FB44CA09D59D3C9A22E107E960CA7588066E9B95EE6926DAD5E91ADC1320\ +6AFEFDBE39DB95BDD77655C132FB108F4721EDF687CEE1258CF5C43D60F8EC31D5A26B02\ +2B925EB2:\ +EABC0FE834E386A647EBCACC5FE48308E475C5DBB7D18F404A83F50FC2F93CE75E4591C0\ +334479B0A9920CC3D9389CFDA9E2D532B1C491B0F1F3057C797AEDBAE51CCEDF72023556\ +D98868B2:\ +08C7C0A9B04684B49554E83499D2F277:7D16029BCE205DD1 + +2A101F89BCCEE248AAAF5EB65D9AA97240B9644FFA73305AEE2498A085262573D23783BC\ +442D6C296F126017403421AA5AC8E4AEE44E020DA81BF52DF9D0652E42F2768F1428C43D\ +D25E63E2B2FD7344:\ +E70DC7AC1E4A4E1461F6DC51F64B0C236F3BE15D5AAFFECFC1D094A4D69063E14EB4059C\ +D14481A26FF7DBC6BA07059856C2C764338B07E1C961FA56275AA450929BF62399B42362\ +9565E3E7C1DEB293:\ +9D923AB332BA365F20DA39217C7D1650:49B9FB1F976B6EC7 + +375D52ADA62453CC4F83B43BEC349E85119D9233ACBA7328F3009041FBB9E83DB788B79E\ +E543D93859404A91D0166397908BE510D0FCB58F0033D3884A0AAFF9348E4E3825E3D4F0\ +E8B7D592C7ACFCBA11C2D9F7:\ +27F658DDDD613482AADFD44E832C372665EC2001697602A274D84BF3C2C76A5626D84C8A\ +80306E31FD8748256FBA279732AFD0CEA0102EB103511CAB71458F881841A3D49A43D450\ +558DAE85159310F67DB2B747:\ +7BD5159E4DD63ECF90DDA801DD608104:7A60E38CEE806006 + +F81D39C6A1A977FBEDADE7F2A1C516FEFED8621E0C3FE4CC01DDFC4035EFB3F2DFD468EB\ +8899C9368A4DD48327EBBE739E6A68B063BCD5C03A896B47C1DA723A5AF8DA8629964D43\ +73F38F297DA5FC11597E0F0AAC6A328F:\ +84DD988BEACF8442FB917A80408164008BFED0C6B66A05E5EF5F46CBF5C126108F3986F7\ +336E5BCECB7F4645FEEE00F20511C52A750029CA31D869340170F30933E92A0DCF703EAE\ +3A7F15AA004D84358F76C4D3965E67C2:\ +F0DCB57019B3CEA07D6F8B81F8A974C6:FBDD2704EA4830CD + +44176AC9FA9B8502B675B559FFC21164366F73BAD09982114F21D2CBDAA15F88651EDE4B\ +BE5B644EC78B375ED58DB3A4D814A6DF7563F282E8FEC7C9965668039AB4988F6E87DC94\ +13AB3367500C6AC1ED5968E5B31F44F176B02F7E:\ +DE0DC6FBA50CA8E81E265781993875746F2C30BC80F682F085C644C162AED09718D09B5B\ +FFA421F8B26FEF78F222D55C5CFC71048F805393377AFBE94775057B432D712CE65B62B2\ +E48A2F973D3882D10BA56AA3DFECD37DBCDD2D57:\ +92BEEED6E43A5D7A6F6211C85229D86A:6B0FFBA1B3FAB3D1 + +1788E3C83C04ECE0D95D27BEAE329CB99D5E84FC3EF4A45575C630C8B946365467386261\ +CAFF1FB8C615C840E6EC28FB0A42C633B373F5AC79C32FF90F4883E0DFABF01963C78681\ +70CEA96A30B4DA4BFC1107E31AB53D63A9543373E505C779:\ +BC545A4E753BF6BB554B13DE4CD53644AA7235F2593BB0B69B11EFD66B3CEC201790271C\ +83138945C5A7347635F788CA0883CECB6BB4B53610A64E384F769F6591D962620B660CAC\ +0A587FE9212B5A247001B5439D62E144F91608CE39756FAE:\ +2A70897594FA8D00C8792ADCEB16BAFC:530C2B6E298FFD38 + +4C8E284F44D41B80818BDB68A8D57BD63F267BC0888CDA54AA48386E32C561BF8E3B370B\ +CF9615A74659846F476DD0FA6CDEA8FF11FFD3FE7D5BA8590CCC66D419E9D96ED3CEE7A4\ +6CF559345FFE61AAFAE1ADC3868E6C9734AE56B41E35B6D8A2316E4C:\ +FD08FED590AA383CE472B91572CF6E2244A897AE7116F0821DCE23223AC1DDC28207EB5D\ +DDACA086188DC78FE5ABAE43D3FC4F0F259C521EC38B8DC0BDAAE7F80B7B27DB75B00E35\ +E8A88380FA5205B002961BC6F1A4E81BDE84F7A3079F10F8CE644588:\ +85EDC49CF905E1EE9A8205C3709E1304:82E743E483BEC9F2 + +F33FE0DF117BA01A850C2DEB6EF8CD86CB65433ECBB079FD69831A06096DDBFFFFB1EA23\ +F18EB4B4F397F51A5662462D8DC8DA6BE49F9DA578A90E12C8CA33F4579BBA602EC4F442\ +2D93C5FA8E8EC2C9640C0D3A0F0201A5F3D57DA94A163C25E185F5F4089F68BC:\ +17297C6EAB5EF458AAA16A1F0D7A1EE3496CAABBC623F2127307EAA81A78A756E4373F39\ +1DA290357927B703EE1F0623A3FF7101CB78C3525C059BFAC4A3DF3588021953445A521E\ +415AE2576948B323F08E3CE108989BE73EEF7F00FF01C1C587B312E5D80C0D6B:\ +F207A0C6B1A66ED1D50D256693DACDDC:6171F470E638F864 + +59170FF4B0A175B7EF8BC2B2E0AB81AF6C994FEAACDE9D255606A1DC476E89980A092763\ +2819B55DE0892DD43F0D7CBE5C4279E6251BF5296FA03C8A2F0260339BCE64DE16155F31\ +97792C2379F11D102A2F7825A97A03D6A62C85C3A1C5BDAA18E4BC25F6C0BA43595D194D:\ +64EDCCBCA6BC3C6880DFC6BBD62DA90084AD8CEC2A704A7FFBEA8751F467BFBB5DADEB43\ +039C6F17FFF1EE87844C7EFA72A2EDF1EAA332CC4F281E5E813672C7A7AF4F85FCCBCB1B\ +0AE11F869382015D7DCD676BD4B482D175A5AE61730C5A29DFE7B14F7549A7DA12579667:\ +358CAE6A62C661EB1B365BB5C37CB744:4F8E99D3BB7E3057 + +8FDA3A1460325CF70E0DED926596E870382B6B4D99FE89E86CDB6DC1B25C82C5816DD622\ +980FFBD4148AD82196865644B90A6B282DE1B92A99CD2AE0E804FB330F95724CA5B45A2F\ +C57B0926AB998EDCBB63E61E8673FAB199C2BC83998B7F43E8307B57222C4D76CBC606B6\ +B4AE8D1B:\ +55E3B003AC093190C81300E08533A11C4C96D30E3DF4E030DFBB1D2BE741A8F30188398D\ +AB8198972D85B44948AF438D6BBD9F47CB1307389F456F35238B1901F03D8FAB0669B66B\ +F7DC10619D5DB72AFA4990F52FEF4F96576542B55251B83E7EADFD984DE5554909C89758\ +65B78A61:\ +4ED8501303B4D3F924D5C7C4097E57C0:2B3A19E6E2EB6CA9 + +3599E1DB61A7B8E74620BE5965CB0E160A69767048BE47083BDE3FB650D0BAC5532976F2\ +5530580B7EA047A346F5E8D413B07CA19928444ABC3A94CC52C7DCFFA3CE402F395CC182\ +7B13DA3B33E4658041E2F7393D90C27D928EAF9731A5054F289F736429D6644FE7906440\ +58309B8607587B9D:\ +6AFCA1CE267A3A90C6CF0179699DCB96BE1C42F0E7985C2D4D8D725C5FBFD9F6996DFB59\ +C0A5BBD09A58418E1151C1BD847B44D58384837E9594E445CFD87F8E324A0BB938838AAB\ +D0A496DDA178C927810E674ED0E36D257EA79743261F555B0E04E1524460DED8C288D71B\ +330F5AB0A13A6FBA:\ +C8378142EA256625CDF42F9EF7DCB2BE:7E12641A0C703137 + +7B902233AF687EB4D0B8711FAACBCD2446038DE3F41FA72805BFBE69E00DC9AC5936C848\ +1539C1E97DABB61CFFE9D492D758F8D8DDFF7AE764DB8D4D946CB3207123A1F95F7DF76C\ +F0BD8B276004C9D685C93D123B407A78BC8342FAE45D91B5DCEB7EE5A2EAB15CFA38F4FB\ +3586C45E7279DEF3A5376CB8:\ +5554A20E71F2C86C77A13DCDB065D01EEA0880BD648F3C17937623934C7EFC77B37733F2\ +D1E96BEDAC273954C3F8301A749D14CF74AE76A9CDBFE559AD9643BA818080E1D8FAC761\ +B45B48D0E19F51657115E8ACFD6E81211D890EABF55E06946CB90599005B535A6D274E22\ +1F7A697B92BCA34D1F09FAA7:\ +DCBF96AF1456108A9B9227ED94CE806B:05C03EFCE65A8210 + +A226BAC3B9FAB88446697ABF579D5332EE60985E2EA7065AFC56FF26C16CD4B944C7BF3D\ +C3CEF4BD9AE3000F17CB304B649D3A30776EDFA7D067D439A5990F2B7BE3FA5A6447D22F\ +BAA0683E7ED683707C30557557E2291574A76C68F32BFBA14E2CDE9E1FABD5034FFA38EB\ +A9A18BA405412D3CAC48D0A6F8B5033E:\ +B22F813952B9667C95028571AD9F8731A41617A9192671573DAFEEC9821B1A82296C8BCF\ +6DFDFE16D31F2AEDD69E9B18E8B34BFEF7D08FE47466AC0299F8E08922E515307E284BCE\ +85E70C7BBD4F7783653BCCE054BB82A14EE89EEFDF53C772273442576D37F90D5E2E14C7\ +0769F2F3ACEFF8CF1E71281D4172BF65:\ +2B4B352CF67C87C3397A3CFD44E6758E:C5ACF3B41053377D + +C85A0F50724680DF59E0AC198F7412AEE6734C05E53F6957BDC33A89E40DDCFAA4F1E211\ +C1E3390EFE49F299478DCD9026CC2E3B49F35E893ABDF851C39F76ABCDF9B5E3E4FA2B52\ +0966A4E1AEB36E8EBD1BF5DDFFF64C9935E89B75DF0D78D1B54D9FA6F8A87A8A47215915\ +70B47E091B016A381A3E76B3AE92EA014EB03905:\ +13C3BEE2154D3C4A9109B1F3E0D1D21CF47FDC283A7ECEDF2338FADC4F893896A8EF03D9\ +98EBB98FB732FDD1B11061ED6FFCE2613DE72AA898931F4B5471BF1B96D35FA467629275\ +5C1B77AD5AB0345C6B3E8FF05F7EFACC393762A075D36E88CC5EE1AC3709DA398E21F452\ +CE9F255D93BDF03AD42444C2ABBE0211C38F9F84:\ +81BF9C41D2404B0A468380F8CEBD5996:2EC2328185E51927 + +EA03F0920CDB09256BB8D2DCBBF5E0F9C14FBF0449BAC0AD02BBC6F3C5646FD13F2995B0\ +B6E37B8BEFC5E85DEEEA696E4DA351DB87D694AD896EEC2F810538CEDAF434931E6A69A0\ +19A2C73C3309FE7FF028D7A8D387CEFF33A63C4FA3669B41EF3DD8D7A0A923B4AF8307E9\ +072C32020B42D4CA2F6933486762E8E3286582FEE0F1636D:\ +847772497AD58F8AD957CE4B2D83D16C8F6F0E7A693DED94B7D1D11832078CBBB9783AAB\ +878CC9AAD7CD731E74D314DE0B9E9B9F65A279C05ED1382D26882F8BFBF06192E587CBBB\ +EB2167B96DFB3269B4BAC805288365849EA703E56FAC7F13805AE140E894B8E684642E73\ +BAAC18E7F0EE1637FC17C42789525AF0DA8D10DFFD7BFA53:\ +5A6F131AD458C1E9B3C004109CC78E7A:FF6CC874B337996C + +4A90541507A87188EB104184D464D1A04B622CD3C706B5A800B57BEEFE5AFCA521568626\ +7D2BB696F64F4311D33A83C553022C482EC939A77D6F2961D668625E214AA9081056643A\ +CCB0FB9C67892D20B674E5AE2036214C41D162C7B44E453F87659943088A8468BC127357\ +41B2F3E7F3DDED053B73377E9E9CE47EBE52A4FD503245CDCEFA4919:\ +D3489D41497715E8CA4B828E86A03903AE435C170FC4DC149D599832EA64ED7917F30E45\ +91151B08E46986FD94C2983AF9713AF602DBECBA6B9F9692AF43E53A3A04AD8B8E33E846\ +B95C8CDE80AA03D46C923137938937FD7A285CF322D23405F2FFB8C836B2CBA663C4967B\ +FE61DB36860B6B741826BA4F22E5393879AB76330545BE2B62389491:\ +B0221D669075C7DA04EA353F6712C7FE:386BC7C0AA935689 + +8C52A4AFC465477D059AA22CE8CE343FF273987F10B249B1A19B6F95A69B0C82F122B22D\ +D4FC9AD3DA4AEDCA876DBEE1AF12101B5CF065EF20E2EFA1B50349659F77DA6928BB5108\ +BD9226424CA31C7ADF49C4F738F013AA5A55380ADD25E840A60A5113B08506D71B702A45\ +25DF234AA0BC459222879DE4EF24B305F6B6E7D5702E3EE7320D5C1FAEE2AC70:\ +B054E0553AE9BE63A3315509949DC984F145DD24B152E6FB15D712067AAFF77733F7AA8E\ +CC4D60E47E4CC1305BBEDD7D572ACEBEC9FA31F3E701E2DD5885C1C39B371B6582D14AE3\ +2D31BC04976E3805EE3BBA6C727A82C8009C1AE39F866C6C5C4333498B32337E435EDD70\ +0A48BDC28A7918B8DE08E02A6CD3BA196C7236379C12AA86FFFD0DAC3D7390AB:\ +5771D7A711C92CBB93CB776D54083382:7FC654F95497E5AB + +18AEB9393D3A19E52A9F83E7E419C40E533CD2547C186038B315787C3F9616CE14A5A022\ +C2718D35CF6B54227C4E496E1552D392CC060B87E843313705797996CC5E73BF43141BFC\ +11452B209BE877D7ECE2A7A4D4C02745179B90D5E6A205ACD8BB01405632D1813E31938A\ +37F43165A1F1C5AC87A1ABD8A69AE655D4FD70DB124FD3420D700726705224533C9F6713:\ +51E70E5CFD39FDB62418893CDC05469738E3E144E4915064F2ABB82F0DF1D1147AC59EC0\ +01A5EEBC6763AEA4748825814E4CB5A90B271007EB8FDFBB867A9911E9DAAABA4D692B1A\ +D9AE2465210037A18E64A742D831AF8AB925B696DC0D18F45B80C0F6A46A07E3322E26AA\ +DE193F64BC2BD998F819C440CD47781A4DC21B831476145093319BF8FF4C00FC9E33DB25:\ +CDE4F850BA8D7F1C9114149084656B49:A6250EFEB105609D + +9DEB4E27C4592FD5DB48D3DD21DE22342C3F6F1533F288D8BBF3FA65E67A66854479737C\ +03F2FA5C40E0001FD84D9EA4604594CF571F03BBFC06668D12DF9EE61CCC0385B4532924\ +3D5A5D06C19791389E89FB54A6B85D005B64C08EEAE5FFD7DC1C9F1DB87B5C55D06FFCEB\ +1C9BDC3F78E5CBD67E06AE24500546B17A756F9A1639DF24AA77CC53B6893A31D87435E3\ +3B1045C2:\ +44C52C48BC865C5FFBFD05C2B27C4D2B69F373CF704A2E91FB2CB0D429B957A6EB3089D7\ +9182311777705987FCB9D8539BB2CCCFA1FFC8D49EBE6820D01F10597315E46985F4B4A2\ +160FD97BDE4E5F5C7C7441E06E089540788121B761340DCC2BA676670432C0B0C712D6DC\ +3B565B25AC5C31177A50499F716522CB5ED67E9EC63C73E6FC6BC68B0C5C7B4102D4F59E\ +79439CF0:\ +44738E1E4B7A442D209F2661FBDA824F:6CEBF2964385D443 + +15DCFFF177841397C5B02A1586B9EC69250F7C397DAA9C0C2B172234B18072B894ECEDB7\ +6F839878EBD358AD6AB62D387456AAE59D865969E9398326B140B1B16867847F0BB30FEF\ +787EFD2E7F61ADBBC9CF13A519DBA56907787269D5FEB735F88A4C6A313DEA440C4FE07F\ +C374E01C83D65CA5A26631C745F35875BD58890A066F82F4A46846937792C9E893C87856\ +AABD0DEBC110AD4E:\ +C8065C6F95C74F52907EF0E1409608E15C1D9C97980891B93AC41A6100080658C4F84FF7\ +70F0BF240B653B60A91796AE3996C449447E6E1E19FD7C48B8A6C6481C2B5F59262C895A\ +57B4C65E0549DEF9603FBECFEFE9AFA60A26A417D5523B7E47E5C04F07323A88A447803F\ +40CC46D57ED5ECF43D6F1A1BF48F03D0D56D7594B83BBE856A476E9A49ED457A1FC76314\ +0EE67FE5F77D0769:\ +7D8DA95A23D6B81028BB069A712AFE2A:278E3C3D1962967D + +47743B5282C40BC1D37C6842C7DAFE01D49FEEC11D27D212DB0FBD852712416CD392ACF4\ +1E1A5CAD44B82032FDAE4E94BB5F94ED0ECF20EAF9C68B49F9F0D0D3A49A377C18210130\ +44070654606CBC11E69959DFF4E975868399C4BD3A3CDA32ACAAC037A8AF3155F8D20AA2\ +B76285C6EEDB5AF9E31865BE1A86E5615F8E0CDA4F0DAA44DD3EEB1360C262429038E8C9\ +D43054EEA4C67E9C26504FDE:\ +F7081D26253675F37E0E644CF5FD2E2DF27B760A57A2C9753B2BCDBAEE6EE70DFD83680C\ +B1B4166DCE85F48E52943A3A7E83969F4D674226323C12FB306F5BEE80B96A8BF99BC497\ +9753465E587E9FBB43BAD2003C8DA5F99CE06B6D198D024E7E41576539CA2176DE8C78EB\ +4926CFA264C108A153724F49E38B2215641BF885FDB366FE4975A6AE5B5C9DE89EEBE3F3\ +6406F0169F09FEDC9D582656:\ +D798EFF93075E16619C04C27B44B7710:81D4628D9577608D + +440DFA2B6F45BA97928C07323E7639678ED1B247376F8B51BD5107BC66538ACAE5D9F692\ +4B9060AC5CC37D360F951D81CC2680213B48BC1FB392235D9E74076BBB1A7277E4B4CC6D\ +A3D8B011A31B92EA82DDEC54E3A982988E9823F343E6638A6C8A8B4F9FA1020A81B7B707\ +776BB4991B5C7DBCC9BB9D041154122FAE8F6690675826AA20C251B29EE5647B160041C5\ +DEEC1B90BA21207B39FD0A657527D480:\ +6253441E82759549F5791B82541649A09600395E37DA34BBC9B075E084C1C027D3A533D3\ +1187C4F0F3FC26A2DACA5F10461953F3F2D8A0C152A367C0E2B99DB3831FB9691C815290\ +2954A26C0D14AB3B8B7B5DA82450FDC4B37D6904F8835326D35ABA9431F003E867AC26F9\ +170DDA423837F657E908493CFC06944B359A42D1761DB68A6A61D9EF03DA83DBD0B4F69F\ +020FDB560C687377021C09977BC8208F:\ +831246376C66B8468E7A6E6E897878A9:9955251D87DE0D7B + +D2F7A97B171A9C774D0DF23173044F51282364ED0F373E86EA57C6AA726F313FBF49DA8B\ +F30411F4D85BB62CA06C577396C0CD74D8F43DDA49EC5AACF46D9D3C20F68FC8E36FE6BE\ +E147040811CF9C6EE80F3B011494C828B6822DD83F635C1AE32A115FAB35E5A7186942C3\ +D5E3A25FB2A2D18D877994DC2F2066DFE5873889978DBC5E6686F24A9D4F69AB8F7B9F19\ +FB723D39982D2C22A68E0D526B35C3782518E721:\ +4B48E6C50D37471DB4D311A3303722020E874C6A578E4CFDDE95C44507906ABC4FBA603F\ +0494AD42CE4A660BF4CA06BC7FA1084DE0315DB0C85081D8A06CB823DC876930F948D594\ +020092F3AEB703F95DF7BC94DEE275572BF9D6D6A6FC51AEBF7579F0CD49369A8047D46A\ +B9E47B8D90C4EE61A24536F638987E4D343E2D66DEA1FD670CA98AC284DEA1FC28ED522A\ +B1F5AD0581357300799413CBE6A78C9571B134C2:\ +59C571414163AC80C5856A8E8EA9A524:9A6C05BA3212D92F + +0DFE5D7CDEF8C0EFA80C66136189518199FAC9A459DF9FA5369D4F1AE4E3938DCF790F65\ +939A4D8E27CEEB7F7BFA098607DF2C300D61B00E4821B3A52150F5C38A9B12983E0232E3\ +05419FCF9D01628CB18D22C88E69091EFC8ED328317894145BD9C7488EBC4C7DAEB5DC9C\ +ADC240CF47B1A0A6D720A8EBABB78A2BA0193F2C1485C77DDC47258A8B9E34A4F4066C6F\ +CA22E44AEAADC6FDD6C398EFECC6014662286D3BFB339D2C:\ +248E8FED5CED6F9FE5BF2F5FE9D668757A222AD0525861FDF8DC86BD52C75AAB502F3ACE\ +EDF16448107C65CEC8C462C50D9918C7CE84CD7C1F17BC16625D4D9CBA7A335E8DDF31CD\ +F86EB9A2CAB4E6D46136F05DB0FC7E9811CFFE1DFED75A1394860731187B3F4D053BE3FE\ +A79693327F6ED98C40277D747D8601447D5F02401C0AF31DE0816310F81F83683E405AA6\ +4CC47953CD922ECDE6ABA6AF4378BE5691B78FB0C2918187:\ +B69C5FBC4525445638D618F669F82347:346955985318F429 + +4A25E4F0F608CB42CE5E8EC7B48A822918236B42D074D0D7C8D1209E4F68E4DDC9F90B25\ +4BF967FAE9058DE032C1084A1BD9645B7647774FDE927DDF1776D5F829CA436C9E8F5D6B\ +4689B592E7EE0ED9F88C12D1C6F30165406BCB2177859523855BE160E7CB477EC73AE50C\ +66F827563B4173EDEEB4AA6DB82B3AFFD9E719BB0701AC3DF37AAE2992348F33BE426B85\ +151D7581F1553A0E99C339BC407CBBCD3EC9D603D3F9E7110CEC5A50:\ +89A0DDA3BA5012B8D10F97F1546BB16AD2123FB97A8DE83EDFD42222EF62A07920C93B8B\ +3A123F5CE5EAFE1F9645975DDBBF031AFA61166C90E2A5677A07590B483CF6FA9D1597CE\ +FF8734A3D9554AC4C946A4551EF8698CCCEC3AE7142595D3130AB2712719595A6A143856\ +53DB4B52FA784D75869926237F43C8077732A4DEE1C66220226815E0E77F868C68AF4268\ +BDD89ABD6DCCBE42CD2CD16617467E188D200517FDE85989BFF9A751:\ +14388CE990670FBE1D821E677B829621:E13F97C3B492F94E + +E0592FD880C54A90F4A3FC3F1057712CEBDED7CFCBDC017C9ADDFB9714C044F1A5AA11E9\ +300F9DE1C15F8368B5DAD6DDB87BE1B6B2D3A32EE21DDE6C1098D2B84787E12366B8734B\ +37130D010A91A76CB6CB153EEE3AB7736A2D6EA3F6FC6072870F5EF351FEE32777CDA4B7\ +936A1062CFA69CB94405E1624E2D56FA06CFF4D31616B20FEECC2D2CEE58C81E3DD0EB56\ +3EA825C87914C1F38FB9AC35C04812041F2D81A32A9C8546ABA9BD5AB6E71942:\ +003770A75B796934A5C6C8362381B47E9DD791DD860AADBF9F71D4F76D648D210EA1F16F\ +513FE403B0FC39EB84354F585756E95E9C114679A1FF6F90A98434110CB1EF5FE540280A\ +6A82C56855E3A0C83FEA2815C4BDCC22308DF7769A22033F6B2C91ABA1F6BA83D03CA788\ +2EA584E2C2183A1E74A75F1E934E3E0ABFFEE26515528704B669802FD6CDE0811B98BDE7\ +120BE82828E0E67837EBEE0DFC30FECFDFD5B4D5A251571DDD8A42E46583CAF0:\ +8E0E06D39EA04A2ED224FAB12F875169:4687DD18DF082821 + +01A8E66CFBC585451DDC5BE634C7C80DA329D3DF16239DE9EDE1B6EA4EC912B5106999EB\ +348DF1009AFD0ECB16FF5A7EE023BC8C4963D52FBD8BBBA5D99B0512D772608746FBBF36\ +A362761CDFD5DBA5A0AE5100D0FE1AF4EFF576CB1370A4B403DF7B06E22DFC37B1E1AB6E\ +1152E0DED0F1B5867CE72F924EB3D5A122EAD315C7EF570DB199DAF3042937205CA05E22\ +C101527F9B9187DBA80461DF3A0855CE0D32A80255DB81327849901FF16061A52BFF8410:\ +0FA83C7A283B563AD3A1D91FD96E5033EE3BD79C786E6398504D2B152E8174BB1F743D2B\ +5F209A7792E89D24B0E91F9A8B19FFB2AF659F0826C743E85F469E31BAFC645EF27DF183\ +CD7AE419ED8D83AD229D9CAC3C67E8C6F3B722215D24793B3AF04283A17DE3B36E34BD48\ +309B2C8DFC5A4B55C0DAFB7EF0E40355485B89C381E9227A7080C2353D05E2E97F58EA41\ +A72E3DABA27753D44EACF8B9C03F21FBBD96D5DE4D36EF0EE7F8E554E1B468126F5F3AC8:\ +282452A3EDEC7BA6850A6DBB481F18F0:AC2FC317AE3C2DE7 + +525585F116281D04FD8C06E92EFC21C91E936913C1247CEE67727653974C09F768F31F07\ +ED1F3FDBD6A21194846E9C7E96E94728D640639C77B299102A8D7F6CB35904B00DB8455F\ +1AF65B05DE83ADB6F2759BDFF79CBEE13FC46669771CBA432E6F777FD5D9C879C5B891BB\ +ABB568BB541CFC1A8E567D718DAF292697370206F4B69541F9F44DCE287FF966B62431BE\ +A035BEB6C13573E32233A9ED5C50A0D71457FD8B99390FF345D22AD61B23DCD0A0464B95\ +310097A2:\ +CD13EC2531031AFD1B215EDCE6B60C6F1E9E8FB13D83B9DC28EE9F586C3C82AB7FB3359B\ +6C2354703093C883C489AC1AA24D21255E2BDE7BECC0F77B55E23090B18129701553A908\ +ABF324C917EFF7CAB5B12D6FD4CCD0928748A223DB90F66B48D79333968EF22502A5EA9C\ +CCF588FF9FE70AC2DB669C2A56905EBEA7AF56BCF42031F3866C77E1D62A793F39827458\ +AB46132868CFB8D72216BD41327B8473F24F68FEF8D0F46F339D533949B609FC2723D953\ +C5F2BC6C:\ +A36BEA2CD9E5D98B4B63A2EED52F8C1B:C2BCD83BF070721C + +47A0196C08AE929B236B36A04B7441FA40E69EACAF3F087F160709AF390C5769E1452EA4\ +1F4325EEED011D33B82454C7B6CDF6775E0809BE8068772E66EC81CC0319A7D27BBB50C2\ +B7D0DCAA8040FAC70BF3947B6E57127422E979242ED79608566A4CE9C8E0EF3589249996\ +601013B4A32D3784403D52F6E0467FFFBED8AC31E2C200F169AF68ECEDAE791AD6D4E518\ +624D9BFF90116F154686DA7342B071E9A9435FC4AE2F42536FC93D98D6DA6697AEBEB47C\ +94451522116467E3:\ +A14B00431D6BB8042C402005AF87709D098F6366527099B8044FEA9C173323FFBE5F53C3\ +013DECC92616652FC26B8E46E0FE4116F3A44D8C2E5F08B0D2B0EFA3B42CDD4809D2B8BE\ +DC6940DDA928B58D7ABC1A7E753AD1DE54273C87FB18E77D58C4AA1867C7B01A6F8C291C\ +3EEC5DDCE8CD3722749F3DA01C9DCB4E7B62F220697B5EB47538FF8FFD78E4CE949A0265\ +E8346D2ABB62F5537789236072548D8588FFF3D8DABB7AA51634CE7051E824EB4BF7415A\ +2DE90CCC264E2917:\ +52874F3F111082522E9EF5ADED117EDA:2455286EA57BEB7E + +D32975CF8583D36F57C092295D8FBA7C44722ED0F385C102EF12E5BDBAE80037C5FF0725\ +E6B950EEC1413E628EA8088B9ADDF2CEA379235CD62FC01762AF3BE11DC766A17FC10F85\ +BAD826E94147DB78EF4E0974D4566900D87643370A8C88F42471C2479B7686FE97332D3F\ +014809711124619D13644E5C95FD083212F580F9FA3E2CCDDC0DC33D782C1D103093B9CD\ +54E4A3113B6C75A7822ED24D9A422D719B26C21F4FE73D74012E81D9FF58F13BF1B681C2\ +9A94068A47FF18B9610DDF80:\ +C8D6A2E21C15290F42BACC559380F1ECB797306B7B59EE22E452F971D049D24FC7C21BE4\ +DA40A91BC91A2FE47E35CDA7C6A63BA7F0F38D038002093FB5E83CF52D197B9DBD0160EE\ +6CD4BC690E0BAD9379352400453E85424E2583B9FB7502F2918C60E0976722395BD8FADA\ +4C1726B249E4E8BBEAB59AEA3EB8B0D833FDD9A934D43542404633299FCF6163A4327820\ +2CCAF90CEE44FF094FEEAAA88EB085606A50E96C447234CD2F4A6602C18F71522D58BCD8\ +02DD3B97D5247F61AF099FB1:\ +1CCD49253B736228C454B8331631042C:43666BD9D4555CB5 + +BD15B15611F5D38034351F16A47A50C53F9952D35B0C888663EE6164F5F228584F25536D\ +8EFC04FC9BB0CB228857440875E320CE25534AFED42F830F7BE88AAED5D91C128EFD7067\ +A30088B1A3AB3C00FCC3C658262230AE7541DB9ABD0E1288EC7B2091050FF3935575FD32\ +D7CFAC6D599655307F530304FBE4E16E647AFAA0EDFA51F4CD075182F2B6D1E8B2F15211\ +CD52A996430CB634B099965A37B442B1E1B8104AE9DA9978412F53FD9FB1F24E5AD0A2D7\ +BADA6011C87593392A629E1E916CF28D:\ +BA61E2BFF557EFD75AA4E9DCBDC95E3D02C4870AC3604E5DB01C38C5E489254CF4B4D062\ +FEFBB3CCB044B488909AF465ED13785E5034DC62F65DA7E7CD0B53E625D9090123E8DD54\ +8E377C4B9AB085A4AC083A2EF1815F115C08CD8AFB8B814C17B2DB422AF48EB71566F8D7\ +246C2001795FA20AFA9DC6F76519CBF7378267A1262B87A98E6773E61FF3211A5994E2D3\ +FE2E06AB52BA830CADA7EFD02A36A66F2D4C559CCEE4769C0339E56EF3946E736B048A39\ +F41C0FAE0C7650B3486DA5A2349624E1:\ +A9AB5A6AD1CFC14030B05F52CC27D166:81F7271353D4D8FC + +2AFE5901D507A488E8729205EABCB8158347BE7FCB6C4FBC5F20EB471F00AEF1FCD46892\ +E679EA9838E22882B80B1D68258D24392C219F9106EA1175D54F5AA495B6B3E0E60CE6EB\ +6E1E892F2CED18DFC18D62012A4328923FAD58CC04EC70F832E3E1B8B2F1327414C5EF9A\ +57DDA4D40C63289A5346520B7CF4909B41A8190B668EB9E5BE78F55155945936DB2C20E4\ +C184BD2D3F6DF976168373A1E465E89B0C2ED18E750643932EF45DB0661ABB74088AA216\ +3C06A19E917D7B6F513FD1DB784534D624EE5575:\ +4DDCA5CC4014C19993D857ED57876B384E8E06523066A86A4A4EE4EC597CCD3F1619D4C5\ +124C088B1E89E969335BDEF659CD3E2DBB2FE26079EF7F5352991D26B89CB324234E2608\ +A77BA1B66BB194D4CBAE3DFD6B80359ACCB81C3E69CE2BD30BF991930AA22FF0A2D02A0F\ +460951DC829FFD8F095CB245AD84A152BC59DF1925B0F1BCA25FC2355AD25B25D821B22D\ +C0AB2749AB7EC0442AE798674D8E11A87257AAA2767894914056C8287B139751DA5CB49E\ +8DBACE28E2D9DE52C508089F8DCA82C7386619B4:\ +E3D2CAB6F748F35DD4E72335A0241476:D97CFD5DEE5CAA6E + +4541B90A451368513D4A09BCBE2CD48155E512FDF240E76795905DAC75CA9BE0264E5A7F\ +924C4706925C7CD35392FF441031EECDF0D9EFCE0E6135E3F4C1CAE57286552C4AA4D407\ +4C9F7C922B53D0F4CAAF6914F81123EABF9B012AB45C9AB989AD979A197D7094AF9A0EBE\ +F2DA9AD8E32E5FF16E14475F0694A79346231E532660E0176224F21676E304A32405775A\ +937E26FD3C9AF3A4DA27F2FC131717805CBACFB554AD1ED56036C18456B5C8211F2CB2E9\ +E34AA5706E439D1FD5DF049FD63CF2490B74998AEEF3D63A:\ +37BE67361D55FDF19B8AD1A39BA3DD47210DA5B83614B00A72120BA2D9E5CD65890C58D8\ +1A3060A39A4E8CDABE0D2862419BDAEC7695B87E2894FA5A5B05E0E1D1E6B35D5369CE74\ +1BFE4EC755DE0BCAFCC1FC160A6260561AF899A735817258BA86062AC698CD50913E0043\ +AFA85640C52BD8F1B979011EC8A20A5A0C52BD73552B2E1DF1481C62F2BC74E8150943FF\ +4E888D944B253D0CC82848DFDC709792A2FD987EC564FA6D47AC98C3B271CC0A6ED3FA4E\ +DD159715AB1972E45D51926E42E88C309A95494AF55C9E7C:\ +801D788845FC6152E33E6A2CB42A2A22:5F5FC8B7D6B6C3A5 + +9550E29D3D0E9483B8746D24A72396DD16DD31F7538548C6090950908C51E4AA9250B171\ +3685E1A7337A1D917D197B72EE8A0969D58CAD94C73A9B24A63620BE8152013669BA44DA\ +A9652C99787B338FF96C6FC00ABD13561045A1C25214695C990360F505D83E9FF3FB3711\ +535164E06FFEA4A0050A09D7134FF72A98C67F3BD73BF90E2CCAC943DB049A788E7B62E9\ +2C9178E433255A5644DC67B17CBC87AF2AA145B3E4B657F31D28B9282B0E6B343C8759C5\ +1457D48EB5880CF255B2058A30388D306D896AAD42EDB05158223FBB:\ +22473327F8358F22AAC1473C942B78067FEA10319F52A6969A889AB87A09FB2A21878B30\ +8627C0FAB3C1358C5C30F198FD5EC27B9FFF78F4C4BB97ED9804443C18C01470CAC1D730\ +95E8B9E2CE4E6766EB4DBE31DB528CAA80B01AE979A3FB32F056F54B93704DE4E45D0EC1\ +9FC8E571294C279CE3C1DAB74DE63C741EDC1AA7C60A8DC1EEDEB738FD415F22F9E42A22\ +19A1BE56404E8921D95DB53F7B2873908C9A7E09A7B80EB40968319CAD1FEF85D31B916C\ +2F0810CFCEAC1E77976D0DD2105F71E9625209ABB16E7CCD3171AF38:\ +540E936A8F7DFA7E1069D1ECB6DA529F:7DD8BE5EED8A3B91 + +ED1ED1768831FE993379B5EA6091A5CECECAA6A1E4218F13755A75CE982B5901191B3F6F\ +EFAC14A3D68190F66D759389A4B72FC1965516E16412E1DAFAD962A23420E3D108738D6B\ +F1B7D8FD2B6DDDBD590E88EFE3353664085D1BFB7B8E2FF4169ADA322530724388BA3784\ +64B2DF93893FF936274E53916490A4917CBA6997BDCBB9A84ED1E7543B89B64AB70F8CF9\ +3713FF08A5E8EF164E33A6C85205173E9D2E3B0D31E565CBFEDE77FBDE48CF47E742F56B\ +A466AA124B725840B56A69F2F46543C31C5DB8E926A7FD968B94606B77CF9820:\ +6F5F24233FCF42897405065C047A15EDB1BD4AC5824498D186E76D44A01636E3BFA6FD96\ +B0FF5112FECC0F7D5E754505AF90F25F91FC121E5729D77E569744FA7095BE9C15216DA3\ +53AAF508D7A0BE30C64549A1D2F092FA65DF3C29144030A0B3407DF0C80D29A82CAFCB3A\ +FC106FDD282E3E3792D034262EEC388134F0A0ED182D29AD8EE98FFC3FC18256DAB7D237\ +4A31F293F88812AE33758A35521093334BD204CD2F01BCA1F914B9C1FEC402AD226102ED\ +6C77459CE4D20EBC89CFDAF01334AE4DCC07D48ABAC694B86A90A5DF236BCF06:\ +C3CCC1F40F2234124E8E44BE4D230D51:7BB01E9C965EEAB0 + +A9CA7C9133827D9AF63A9A2D98F12E96708714F3DBA3F887C044EE50BF508A4759124EE3\ +748CFF9E3F47976EFEF9E9E91DB6ADF75F2702C277D87E7EF2DECBC60E861FEAF695E93D\ +F183AFC6548AB8F5BFF6C12A25E62C81196F3AD2392FC77326DD521D374F54865532157C\ +75F1B77AA93EB2178F6117AF2AF8ABEAD69C2F4B3FCD3F0BCF24CA460FB596E47C4AC6D2\ +873A96C90788A425400D8CF579733E553B9C38E538F2B1C762D6201EFC132E92ABB69121\ +30F22547BAA1E44FF487D1C4B2B06B3A4768A1220716C44657F679E1F200164046325346:\ +1F1B86628E58A2F6220B26B25DC7723D22B02F2E5E011672C354C6D1CBF272100F066893\ +EE1A9E353E841AC24D0AEF62BBB5480ED978C84BD5B052F1424D6238641C9F11E5787D3B\ +94CD7D866FEA1D2DBACB58DE1B6A0582B6C103926953B3203C94CC8B87F0630E77650E85\ +1449A3BEDE5B2C1678A5F17F920234238C0C57C51181E5D1E7B1082EA9D4781F825574B9\ +3B69FFB03BE688210B74B0A6338370340C90442709591671D19FED7D44795B97409119B4\ +CAD30C84B296C7CD76C3C3B8ADB8B273A35AE34EF402D4B22458EEBB1992C7A32919D2C5:\ +A8E311DC7544747FA09537683A4979FA:F010A1D16F896398 + +CEF68DB7976679BD69BC5819CDBEA5749593FC2754D2B0860A87A3B16A680E9B634C7A23\ +EEB7ECACDBFCA2FBF26AD3AFDBF29E98230B43D410F27777010F09ABF76C69E0864BA2C3\ +7ED9BE1C0E812154E570509F0C8F07C45A52E5FBB3DF015FD54BE20D8DEE69FFDE644EFA\ +4DD93E7C8A7582DC19B5E1C69FBF190E43C7EAFA92C67083DAFB3890C25324E3590479D6\ +BAE27E8E90B6F28EC39BFD46A73CE92F17609B596CD2BE34700E37E423CC9B9160304198\ +D917357347E414627D7BD9D36ABB5BA07BEA6C9302F73F370D2DA6393F3CF310B65BBD45\ +374EC60D:\ +C8848BBA822123ACEF694A77E942F57FF02BCDAF6E6540FEF7A075B890A8CF32B9372A95\ +53B501526455EFF2B764B5C3E8C3BB08085074B4EA0FDE7D4CE94BF284603423068E8FB5\ +E9252C73DE7DB341AB624D1C44E79ECBC22874A73743004B99BD6316BD7C92415C1F2A54\ +675FC2D26B0EAEF760B329A1BC24D140BA8F28000649F1FF43F586E2899FE63C133A67FB\ +C542C87A4369539D8254DED0EF157425B379CF6F10BB0DDB7937441E3C091602C76424AD\ +5E856550CEA7FECB24D54333C437251122C72E4D21DF23371B01D05E32FE1907F198F18B\ +DBF68351:\ +6CEA1E32C1732B9AAF2F9A85A9022895:FCF3906F4227113E + +A7A87EEF419C8600662C5CBA01DA56DF0CE6977991502A27F5FEDAF68AC26AA89FADBD15\ +63ECF3810643174D9A2B6E940E65ECD0FC120281BF9F52C0AF2F768924111941FF1D8424\ +788E75CAF63FE7389ED1C736504F99BF1590C5B970DBD7E0D13C283209435EDE2360146F\ +4F734A06F1ED649324985857FD3CD80C82E896C368E44B52C35C958D5CDB1DE800BA7343\ +412CD66274A97037667767FB7C7E4B95C261106FF3D34A209B998C38F2639F74631D1BCE\ +BA04A436D8DDE90C2A1A38CB44EFA7AC782BD5EAD9F3A5FAC879AA63F6FEA44FF967D709\ +92533375BF94C2EE:\ +2F7335F36D102EABA78F04185805AB6F88BEFAF2ADC84DD6DE9629E34A00D934FF017D7E\ +C8195B8B7D380FAB765646FCEAACAC912EFCF6E522052531D04255964ADC147ED533AE5D\ +5917ED43F7E21BA784B121DEEB879B41B2D00C8A18FF075CD810F8C5DE84B8E3A137E9D1\ +911BAEAB91402AD0461E58A58F45AC901B0B741C63A78C13C82B4709B14F7DB1B3896206\ +7F5A08DE2FA8BCD91CD6BF3FC17950693D0DFAC9CB1680E68D9C9823AC12B1F37E4B6C16\ +63F5BBE7D8DAF7961C3D7B37C34FD2CB02918785E8B7B6777704AA4F11CD974EABCCD678\ +4504A583C56CFDA7:\ +808372C49B7BBBF65386566C6973A76F:805EC1D405B86CED + +4F25B31BA0783DD6842D607CEE8FCACF6ECD2D5D6D885A230874782F2441ED47DAEF2138\ +E6EC20333CFF9671E008481F80986EB91A46C08C9D22D2B6335F8E6BD10144324726FD7E\ +A311573B1A03E6E6262B89D145B01BFEEF14D7904E0C53966747316842DEF71AD1144CE3\ +B8C08C16980A2EBABE9A5501C89CF0B6F610808112123A56FE7F726639A20EDF2C531D8B\ +DD30D9F4032C9C3F9C165634A898442C3EDDB0D8A63A855CE44E650E428B60C536918BE0\ +45A902B0346F232545B27A0C5EB15F79BBD1190552A68EE7C1D29D04DF1C70A7CA254A6C\ +D47BCCECE1082A20F35E7E46:\ +AAA603EC1AAF270AAFC06A43317B6FEB2398633A9D1C130F2C67B6C19E9C391C9396914A\ +BD907B1419551202E6228FC7E06FB78FF669A2597AEA85DD4A372FDA60ED0E3C30E872E2\ +AF2A250DBC6972CBBE00A5F1B5BCB7353175B5D528E32CB035460E12C8A3DAF3D1D4B25D\ +0CE9CA5AE3F8250548EF24AF92F4346A0C5716619A640100922AAE13C7824341A938E14F\ +E9D51AD691932421669D958C252DBAAF943C5AAF64C89AC8B381602D3AD0937D8B8ED413\ +2803C2C9F40838CF1A2064D269A9CA2266DBB642852DEA101E4E6CCB40C377F17D195FED\ +673F030484DA66428B3C7D03:\ +299F9BF1E1B34A0D39E6D49B67DF754D:A4C997CF160DCAF7 + +3B0CA636F9F507E2D9CFDF06B3D69B44A3647FC9D6C824C3C1FF9F31162E7A40394D9558\ +9123310056EF2B668F59B93EA71CA45434D104A91878A6DD3C4349D374E39B7A4635FA0F\ +0841824D02BC92EA6EFDEC08BF8566CCA111E478C569A96B9F7A2306A2CD5464EC4EB0FD\ +642E91A01EFC0CBBD08EB28B34D99989BC3D55DBB5BF32FC8C0CFBC3E5B89DF3B01EC4EC\ +8FF3553DA1714004AC52A2F14EA090B3DBFACA8A7664053DE14A905339D2952964DD501B\ +638EADC396DC05814203C4568D5469D7E3FADE0302C14BED2FEEBBEE5A78ACD17D0D4425\ +9D4A47BEA7C4935967125BC0F0E228A2:\ +253D1DC003D0BA2B60422354551E3684951A5B77C142061BF86EB95DCAA1FA06E2E047F8\ +DD94D3080BA6345E2F72478110899AB51D5BCBC6E16E564C407AC37A08F34108FD9EBFAE\ +560FB59A6A37DDDE8F014EB525AE9F5F63046C263721E72B6E94151A129A3BD446D9AC21\ +602FE0D150251754B4334462A99B7C5792B901E03AF71FAB991AAC8B9A75C29B2FAF3517\ +8946735608DF583B27C80661A53FAA4AA581B5AAB2F7F034707C9B812C9A22FEBBBD21E1\ +BD4821C4E45E3A072F8301435E238C7489B23646CDF37800C9D40CE69BF17ADE4992F733\ +F71C2273B37D1F17B68D15FE61163E84:\ +CCDDD91BCCA1490EF312ABF7D7EB545B:B091FE75641EF510 + +74CF8F2B03009D38E874C23AC4A01855EC591D2014AC96C5F6C4D0BBA42C8C3764A3554B\ +9D5D44D9FFC259E266DD0A2649B5D299139F2ECDC1CF7E286C183F74051B150674E9407E\ +C8A6E151E174EE66012DA6E2303AAF3AE7F677C17BDFD546589F52756CC02ED3BF4483D1\ +B4BF49FFEA82F0A9111BCA3C2B5DE08FF67E5BEA7D2E74564D686D554DD9C31C291ACCDF\ +76A0AE0ECDBB17A427D4223BB53592EE37E398707CCDD0AA70F815AC3EF6585F35A5E1AC\ +D44C511CCB79CD85B5D1CFF534B0CC7F89C41CB4BBD351D8FBA99EC6717A98BCABDEB16D\ +242F4DE41CF5BEBA4BFFFFBE600386FE55CE9F0F:\ +2747D5D76CC1A15D8D410C081DFA56049B7421A90B01EBCDBE9E31B70C61A58E0D2D5985\ +596520528D6C0F64063C3F2386F4ACF2FFF68CBFB8A7C78B97A573FADA6AB69EC728CE77\ +666C89250F9942F80FA653CE60ED9B65949D491A38953C688821A1C4B39F88A72AD5F454\ +4D002456990F1C4F3CE293BDC8DD68BF8E13818A05454565D9B87AA9F4FC906E4AC61A52\ +3C1C65EE7467B498B5A06AF633A37B5287854365DF96A2675A3A454A25A345BC1F9A0375\ +E091C6BC55054E2FCA011B1E3BA1C964A3470DFCAE1A937F1286031FB8435FD7487768DA\ +018E69AD3029A1C6EF4EAFC302EACDCE8A02CC23:\ +80EB0BB542D844F4768820077D8B81C6:E6936F2688231B9B + +44F6EF40CB3EEDE73D0BCDEF4009F48EFE4045B1422ACDA5111D1BAAD4827B33B37911FC\ +BB51A9AF5E6E4D675A968F119DE1A64075DC4670B92FB83AD3B44796522B0D8187EDFF98\ +2D38C7E8EB63AD3B838FF50662685D4106BB1E0424B5631ECF069D988C446CD2E97CEFE1\ +A2C3194681873266F5E02C7018715A3DA9CD927FAECB6B8AE6366998141ACF652B49353A\ +8D6B9A6238C331138CDC90659BCADCE15CED1615B96D050250E5196F88F5601F6B538226\ +45825C88580AC543DF13FB4403BD895000A2CAAD12DDEB584D70A0CBB8C029573F5A530F\ +9E5BE2359E6011DDD4FC25E32397CACDE24178D0E0AB186E:\ +3AFAABBA1BA4E009171471B45D465F449D2F0DFE600893F2D60F9BD653B092C7CA980C4A\ +BA1F15C08028835A341C5E59423AF6BA5E6F5B3C34E69CB2CAAB42EE3DF6B1FA10F2A611\ +FB4871AF01815135426D60EB540D13B9058F154D6643FDB28542A079DA0549E9C62BFB6D\ +CF3F6FD40175C86B2CAF712E42538F3B6C5C57024D36AEE3FC93B5E70CACD49776302E51\ +CE84B4075BDA7B37FCD1968A6F561F625B1D32F3652D8A7BEEC11A11CD8737A9C9F87D1A\ +4CCC3F24D201BC8C1CE24589313CB0387C3911C924A572237705774C89840DB93D5BEAC4\ +7F75E04A10839355A775A02FD417FCC2A0BD104E81E3CA40:\ +89D3696A74D8D4A751C1219C3D742DA8:BCA7BD8D3A8B2682 + +950F2F4CD525EEC6CB634DEE121B847F35D083523526D9E20E329C263EB892E5FF2ED907\ +B354B057101C73C094476768A225268BCAE04C564EEE9EC9D855E478E192A9FC22F12D44\ +0803BC49C5F20683DA0CBB09CF704E4938AD0620A4C40CDA769EA03C236B0DAAAD30B432\ +84486A8D2619E94BD1B79F01B3AD9E70874BD6B929BAB1121FBD585CA2C0D25B799AA487\ +7FDF222097CF0B8CE95593D0CDDACC418FB1734ACC19D365B410DCB94C3E64B11B5E1C61\ +DB6B4BF2E291FE653E2EAA266C3CE7FA16857001FB6C2259BE0A9157F629B6E37BA037EC\ +3A716293AD59C1A254EA4FC60DE1B875F40BB328B5B6CC148D5FF5AF:\ +34E2E8205BC53EDB71913053F33227BD0CE67F1D509A0FFC5F70AE3B59A7226811821797\ +26A242F1AADA28E15C3B04589D5847C762A36A73B7D0696C7393D5AC73DFE5DBA39752C8\ +A06BC4DF90FB52372598B43726849B0907DD640C9D0D4C9990D5F2FDC9F1535400DBB392\ +1C046556B0F8DDF88C46D8D7924E954B177B936EBE1961C89D5616761C51D576D60C22FF\ +8973FD324DD7340B76D11F6612D80AE53CD3E5702AEA0EEEACB6FD21861B68CEF12AB12C\ +AB6BF023D6F6F3771B237A9F68D5516EB85BC0907E947D702AEBF2FD72C196A087EB38AA\ +F77E04BEA1F6798F6EC164BEAFAD1BDD2955B8721AA6717505EAB952:\ +F544BFEBA760D22BBF72BABC88528618:869958C2FDFA5C52 + +3F20E497CC4C46C5C0B145DC2D1208627A07F0426608F4C240CB2C0E1B78858FA22280BE\ +9DB77EA591738F57ECBB4F242386CDA36E926FDA022400566C2AA3AA885B5AC734DE191B\ +61B66817B9A81D9F9FA9AA5F061E85B75DEED7A7C8E4C047923C6BB484747C0447381452\ +444FDE4658AD1FD3FA214798B4119D0133DA8EEB08E4104F84B4485047E9E48195F4408E\ +3473565036388A53FB9D657A7166DB7FE8F0978F01FC8DB66DFAFFD2E9B9FCFAD241E05F\ +856A512BB70DDF8CB32B34F00A06F7A5547BA92DD905DED80937E3A1478142A549A34B19\ +05A2C0183975E4DE684458DB2F80F39138ADA478D425453909AE585EFA7A91E0:\ +AEB26738E31E6C09771AED38B68F236CC9B3B7C512B16DAE7BB44F2F8ED5BB38FA0FAA8F\ +B4F8C9E3BF003CC4342BCEDB7F978F0383C7677622468E5A4C76F9A91CE4F3C2B26B9547\ +E6384EE50BCA15D22A7EFF7BC69E749AFDF6F0BE7DA7E60BA86C399C34C580E18E5FB35B\ +2D52ABD64A31F508711C5AD753FCC47D38933C581AB33C6F57E90090C7824A345046492A\ +6A94293040ADF91673D8FF6FB1B6C989D0C0A962931504ED2E1E056FAE8EADE632D27B39\ +8D893F2D3B420AAAFCAE4EA0688AB45335BE5E8D5E1A7D70A4C6EF1EDA6BE64AA0CDE393\ +9230E8B027B400CBA2615525C0377E22D5DB9EF150C316680E545B28D5AB02BD:\ +CD3603440E0D4ABFB32196ABAEA29DBD:47D173BB5D14232E + +9FF2357073EA8FEB5696460CA5570F82A65C9C8B23CBBDB54161EDF09BBB952A57F9E02A\ +0E60B53B9B29E47F64982A9D3AAF92CECA9B1B4F899C37EC998679E1C6E608FFE780EC78\ +0517AE6EAFE48474BBDBC2F59FE732779AA27380BD7B003F1D9D9977DA835C52A6D67429\ +14276C92689190A1DCE67F31A165A08053063F08C01A5C25B5666540F0802C7F79E64DA6\ +A2E8EE51888918CFA3C5437891E1F7186ACD7B48CC2B7C6E961C95A10121D4B2F20D737F\ +74FE62D4401ABE8EE6EF748D646B02B117885D6F9F7BA65A01307454094C66AF68D25740\ +EE9F45D7B9E12D9FBE44C13D98BBB59FFBBDE75E4E217F9BF794968A4B55F2B16DF6DD40:\ +30E20775061AC476109DEBEEC9CA69882E3F6FF8D05B913CE1ACCCBFADEA87B15AEAB81A\ +8414EEFC3938D0149A0DEBC42E1B3E4CD4D6FA0CA171F7CA194A5F57BC2BA3221E43DE68\ +A269714F5BEDF0F12FA33C456F839D30C4A9C7667273350CAE1E25BF98CDE73BC10FC5B2\ +02F88C7477B2973A077C567DE8408C3FDE4EA6722056D7AA0AABA3E332D53B686423ECC8\ +D8C69524D3E94AE42FE6C70CDFE611C7DA0E300BD81FED416CC0952F008A9F4CC6795D85\ +DD0732228628A8A3266782BFD7E041D6D135C329BF7C02F209EA97C288C613049ADAA270\ +2F654FB81166C23F2EA91FB969679917CDCF22CD878AAFE6E2CD8BCA63468AB745762E7D:\ +7ECC2FA94DB28B0C4CD002EA020B6111:00519E7C6392488A + +7E508A73B21580529EF3C160A981240BA4A83989EC072F7F8296DC7DA3B9F785D11FA67D\ +A1843A31BEEDD09919738D6E98AC7F37402FA60968E0EA3890CD0A0238B31AE3A26EF28B\ +AE750FF2451D98D8B405FEC83672C3A531CDEE25AE5566EA23C51CE747CB44092B82AB89\ +D0C3D0731DE92D1C862E50DA27A7024338FD62311DBB7BD2029713263EE16F9FF37EACE7\ +1EE5F25AD185A9E0327173F4287A93BAF814ADAF5AF869F2436BAAD8D8D3EA4908A816FA\ +DEE43AAC1B7E408BC049D2383F91D25D4CFC3537784E0071B5BB1614CE40C8E1EB9FCEF2\ +99C8C10DF96597B10BFF0606CA3CDD6AB72BBF8D4341222E36675360FA3193A0E275C955\ +90056585:\ +A5B2EC64C27DDC68D99C9F82F0833898B11B2355DF8F1CAFA49C4B3D67327A2367AED1C8\ +330F5A700C788529F78AC260E0DB5231DF15E01BB616566CF4E3A64F1F42B503E4240386\ +7EA24A5DBB80E5B6403BAF272BB480E0B39C77E4D092FB8ED54360912930F36B91C94F39\ +689F6571D948D9660CE319E1D72EECC0AF93072417F4A65F0F1823581B9DCF874094E327\ +41BBA233F5A998C1CAEEE53C331BA9F9D437DDBA066160137AC5E7D006DE9EF709B1D033\ +145CE09F1FDDE0C5B278201665BB835726314E1B76E8DE23E4FBE36C22F5D7009E6B7DB7\ +F151DB23CD520666101F7D3F699016CDC3F286402EBAE4F59ABCCC3A86502112935EA87E\ +1A993F6C:\ +0C8D98BEA46840B22546EE369F77CFFB:4FD1822D02B9C1A3 + +[XTEA/ECB/NoPadding] +E197D59E064818B7C8AD72C29E227E09:\ +04CD161E422154E5BCA5249582B9D4C0:\ +DD0C8719A8DA117DD9D1DAA189E65654 + +AE53AA320088B4042EAAEE3649FE6E36445696F01CA40D3C:\ +A3B303C42178F97F719449529D51511491B41EB70E6101C6:\ +D8C8ACF6B4B68A837639320798994979 + +655A6B1D6970ABA078819E5AE1D08471A0E01E0A5C64E612504F4BD9BE4A8AE8:\ +7DB966E1A2B7C0E8EAA9D308EF89652A5857461D100DD0CEF9C6FE7BB4DFE33A:\ +24059EA6D8A9F0CA678ED6680362596F + +F3B1BB81C053DB02A8515885CA6DF124AB04927D2AAF6F0032BF17B4B437E1F2C7D82F89\ +BAD898DF:\ +215D5ABF53C4AA0D7571A0D9D05C3B6D33D65BF35EFFA4778FF59DEE90900ACDD4FC6645\ +368A294F:\ +2434D48F17E0A7D91F255FCE60F3D6EA + +06F0A1AD9F9EAA665044D0A2EFA10ABC30F7FBA3FC47C6AE1947B7E9B47733547E5C843D\ +AC59D09393835061D834971E:\ +066309B116A6692F279F2526FD284E75479BF7FB5F63096AD7108CFB0DB39062A2627594\ +F098F0BF5A3B4C67CF29E993:\ +18C1E1EB3925EEC61559DB74EC99491B + +2FA1106E95056E070352666F059A72DF6CC949BB3161D5FFD8FE46451444D096BBD606B0\ +BD443189AF001E5BBBA134DB1FEA7AE9B4587438:\ +1DF05B34A733F83B7DA1F194507904CDA99C374174AAB472CC598E06960263BD9DD0EFA2\ +F4C14CC8AF4039A55EC00125766D25FBB7139081:\ +5258617DB39A2968B1EB02565A2BDD1D + +E6ABE28FD1E9392CFC65978D586D31D344140673E345D6AA06C75E1C03E4E314831EB94A\ +BCAF6B23F2C34670A79500C6142EE722FD7E408D751DCB30E5C63F5D:\ +3EC6FE802F4EAA740DDF34EB79798F458049FE09190D12455EDD6129BAE85D22FF4E96AE\ +B59DB9413DC24D41730454F65C443C819265B4CDBFB87F5ADDE7F4EA:\ +C4A02982C1291093144C64DA1E7E3D67 + +213595590E62A55F241E3D4CFCA65C1BA23BF801ED05D25A8FD0A06A9846BE3C28B9BA45\ +A2B32BE80ED468E007EB6EFF0EECDA4460A700977B84464631B642135BAB8519248CA0E0:\ +5A6D52C19193A6C002D58C15BD2490CAA36550B684A726C33F1A12DFA2D4764FB75EA336\ +823833637765F37547103691B852FAB81BBD74EF6C20BB885AC42946998E74D2B8C2BB75:\ +58B61987700468A366178595E20A365A + +7DE080A1683521CEAF78AB4C3160D326A07FF4C6F446A94FEADFC0BC8464EB781D743694\ +734C5938F7D2DE4822EFFF34A82EF0C2E11F92CF1E0B2989786FA990DA3AAEC7FC647675\ +024BDB47F20C67A7:\ +1A5002651E1686F56A6BFDD8DC40DA9DCAE7E4773237720BAC8962DC2FEBCAAD885C4A62\ +F13476B303B2700150F5CBA1CA976A753E6971095F175E8BA2D97E1F1C18FEBB0F8658DC\ +E957E65DA18D38D8:\ +75E691CF7E511D4B1A114C0E80BC7C7E + +739D59F39F57C04D1450926AD161AE7CF1522C4929CB299C2EE03842E3DA7AFD54AF4DEF\ +19867E278678222C85D8901526E62A008D449478FE4249173B6E80980B9F91D09F7F5CA8\ +A174EC73A57AA878E74F0315B6F3E15C:\ +59E210F2DF601ECB05F4FBAED1077A9AE1B783526DABCB881881BCD103658E03FD6C1D12\ +2508DD039470226BA0AA50AA087D40732D77D137DD2CC96824E24C44BA8955D250297C02\ +E3D444F4F1E78F5A02C50C7314CE356C:\ +5161285DC54A3D9ECB691C0CDF987D33 + +3A483364A30C28F9B932A11152D741304802030C60453D1E9433823A21F033DF5A6FB43F\ +E9CCB423946DD363F9EEA9F0E60898652E8E4C4B6AB6410B468861CDCE22B3043BBF7252\ +0232EB34D1685274A3FDCBFD9753DAD0AE467CF7EE661145:\ +11AB2B4CC8CC30311EE2B979C6AF90C5EDF073CA2E483C2F0207E8E95AACC55F0120C9B0\ +DC689A2B645EA1560FEBF3D027F0F24E551205091D04A72657209E814A9DAF3457ED9653\ +9FC1CC8937D76E2EB4854313E2C067F86EF889757E014B35:\ +19B8DF4B8C9BEBE46AE4F71FDB4EF5D4 + +A9E72827F67035507B5F0747149A73AC2763000470087FD6F8F165FCB872AE7BA58CF568\ +E1D70D28891881F0464207E5FF67CD2A707B71286DA7635085B3B68F9228A646A186C8D0\ +9D3E31B56562ACABD0D5AA32F608C54086642AEBB72767643C90B7DC02FF772F:\ +5AC440B8C9AF2D5843B125711F519D34DACF4D86CDBC856933C96D5B3CEA980E9DEC2F0E\ +2BF6E8EEF38214D59B5562324C009953DCCC4ED2D6C6B55211AC5E0EDC7C8AD3F8760823\ +D55365D84525E09DD3145DB6D700D9BAA4A92F38EAAD8CE33000A0ED72A1FEAF:\ +3D29E84526A1D60D177C03632DBF1E96 + +D24A21AB1ECBCF2EF83A1FCBC1032EED930FE269AFF8EDCFEE26FB1A2DA9D063EAE522E8\ +41024B7FDEDCDD6BAA1126834C996B9FD09654901FA8830C64AB1F5CA3BE896D5E60BE29\ +D08C9E0A4F07956551E618F1FBF46DC8255A4E2F4DC8DE5729CCBB39FAECEA0A4C45F53F\ +CF5C3973:\ +2A2A34F1EB3F99FAFADAE4A68CC85799D9EB7B1F0277E71D56FBC395E3A93980B670D36B\ +87153B90B8154EA962C39A049088665EBFE6D43A5E9A04A93F4D683DD509E27BD3AC659E\ +5AEEE8B62EC3037C425EFEC0E726E8E572017940725A794E58817914308832AB59644B03\ +D1155D33:\ +10E1FEA37BE818FD0CC1421E16A3151F + +9CF0C3E72880B2C3FEB787D84866DB80D4B4EFA60E3708CE6FAF0ECC29EDED0C8D9EB269\ +57F1DF63FD39EB11158DD089B9622D161AA83E0BB921067F77D6F4479B17FB9C9F30C4F5\ +6A86EEF38733C8D557053BD4978E41B965CF1F2025402836AC90935E9564BF23F5FC76F2\ +9DDBA491446695A82D54514C:\ +3A8E38AC17AD900742F711491153A7FB93C04F981CF75FB34FC9B28A2C24A81C60AC4585\ +DFE04FC026B6731A8C2404E65DE9FDAFDD32685A3863EC4CC77490F8E0D3ED234152FAEF\ +3C8E1BCE7E4BAFD1171141D5ACE23BB3E5EAB0F20D000371DEF9E831BF716B6AC5EC2313\ +F013766071F3AAD4492FD780:\ +80477A99D76ADDF3DEBEF9E8FF185DFD + +C1BB0B801F25223FCDF8CF13251877AA8472CA6924C0F51F1C968E981CFEF665F99EC57E\ +4C33C3B083D7DC62DC0096B062CBB6DDF4D39DC28843A74E81A5F9558FD9F5F74D3857BF\ +01A341BA443A2440C85CF069A757AA0E1ADD2B67860F3BEA805EAE1316BFD5638C312E96\ +614607B5BD816B55FA16C301B71212B5B1203F2B:\ +D481D95387B075DDB6771A669D3E11AC591A629B53405802F016E710D5E919E195A4553C\ +F83337ABBBD506131F363D2BB5A8D3B542AE8A99B4D4641C373BABFE737C14AC6612FE46\ +6D2A83C867F42D4004685B230D3FC1C23D3410D767353A5C523B0B36E0D35D9B3D9605AE\ +9C8402D0F7679A3573F3354E6BE0F2D173355B6B:\ +978393BF38701AE612953AE4C060B632 + +0C0627A330788002C9DCDFBBF23F46ECFF4CF793D93D934CC553A64ABAD1DEA3710F775C\ +71D54412BB3B6361B54C5E2DE7244CED9B546D146F20D8730FDD8AA155EAFFBEF34C70BE\ +1F6199F67D88186ED039E00BB88B7DD13F071AA4C309CF92C10DE3882674B5C5C5EDB457\ +F826C2D62724E1AD328CC09FB4113E083E4C4D31717FFA66914890CC:\ +5AAE35C53504B9DB9CBD7C00B01AF71772BE3E911DC6EBE45C1EBD331DD81CAAE710F963\ +7B2B22C12BD16B0D84F0B41A59BF169938475F56B57347362C7E6EF4F9ABAEC9F44C3BF1\ +1BC2D02DD0DB00A8DB780A1D1B399C11485EAAE96E1AF12EDF48B4CF6FCCD343F16CD056\ +5E843EB4FE1DFFC1EE2FA8E0F73839D6F6E131442154A4972F552DC4:\ +9A4972A00B5C1B22AA07DA8C1C8B8FF9 + +F2DF92A7AF36169DF9F2CE6DAAB0788284FEFC9D1C43619FAE6CB75576EE173DA697A01D\ +96835B357C89B737794D0E5B2C7F02F8E5DB968E2D000AFCFDF9B17BFC8383832A2CA177\ +CBE99385C9314F94977350C2D4B4AC6D37E0EC8F36E666C54011B2ABAD25CA922946A7B0\ +C9FB5AAF54D618BBFE59C1751404200BA90051B5E54F64C7045B72B01681FCC6E7763F8B:\ +F090795579AE3AFE49B96ECD3A8C01D449DA8AD81AEABAC135EB9CBB904647D5B1522B20\ +8F325C0597A2294CC1A10164551549B69E96F5AE72DDE9A4656AA533FBD7E98A6E66BE29\ +663176D5621CD21F29494D1CF6D784432B1524BA56BC3E67E9FB4378190268B4DE6BA74B\ +8B2B0E1EA52B75C45FCEA715B8A00B7D2456BCE2B45B192EDC10FE777FE53260F8E25397:\ +8EBCF7F6F9025BD94D2985A4D3982A84 + +EE4C225C44528549B4F609723FB33467DBF135FAAB3F6C82DD9E3383714F39EBB31FA595\ +850389D1BB1C1E9DDC3D1E0439F21B819B3D294B15EF81EA1E95C36E75D20B4C0D7C3765\ +E97E9A2B9E03B5F5D5705DBB35C241779E232B0781EF9A3F371D89E451DC68F6F7E0AC8A\ +EB7F8E41DEE6A0A86ED9195CCF12BDBD820243865FDD31B8D0F33418023E2089BF65A5C9\ +D20E03DD7D4C8287:\ +355BDD01480727A7496347973315434AFD0D75AC1AAF3869A461F78EF5E5923A7C4F749F\ +7929C497CDCA398F4CA868A860E0296A952BC115C07B38D5460753D134E8111C0C108136\ +154EBC7A386921F754D1F116F474C4B7DC8B5515ECA301E30D1D4661FF2814621C0CE1CE\ +812B317C94EE900FD23FC2D941504B345B5BCB4DF7CC3A01BD3D759E4A7C4C4FA893B6B2\ +30D21FEFFB69C0E4:\ +C2A7EAFAE3BAD26025FBC1EC1F3B1342 + +FC2B09E77FD6C0DFAFA0EBA6AA058D2357A620E4EFE70E52E8136B5294EBCF97E3DB642E\ +3062EDA1DD93DAF24E97FB14F41C53D38729105BB46DB59507B6152CBF7747537F9FC8A8\ +CDAB5028AEBB26FA8B5E020D7E1D110C159425ADA07B6E2526106DB5C1B4E2F62B5FFDD3\ +98EF3581EEA831FC686389C19E679B394A79D24AA34403BAB37A8B313F82878605E027EE\ +D34926D390BCFBB1E786153B0379C382:\ +F330598D81495B8AEFCBEF71B791A872B394E7A472E4E9E4D4C4DAABF7C2EDA0AF52CC16\ +2FF5001DF22EB012792A509C25566AD0BEBA50529F015CF3C4E6139C80373604EABA6F75\ +93AF87B31E300A3A2C5B9DC10EB36DE921BDF7E5569BFE8A4155F6F5F272846194E0178B\ +228E15DF6787AD158F0907205FA941D76BA4A4F2C121652806B463CC1DB8BDDE50776BBF\ +19577A25A66B4DC3230870963E53A137:\ +86014B66CAE76E61371F64A580B3A3F7 + +2642676CAE2461ADAADCE76CB12F9BE1A85DA497B5B6FA3FFFDA136E5ED6E53ABE52AA96\ +1D3D12EDA92644D9CCF6EE1C0023744BE75786CE57FCA3102D0E4AEFB3F6CF7E0FC1C74D\ +37DDC4CBF3CD59560DE06209006A55E8C463156B8F1D81C7C9FDC270A39FDBD67F53A196\ +73514569BD75BD747076C2CDBCF51C98995EDFE830CA8372279EA41819DC68ECA82B2476\ +53BA8EB10A8F909A762B74D9D46D7BB3E29C725C74504D0D:\ +20401A5F52C04821DB0609B9113ECE78977DB9A614CAEF283062D84985985C50090D64F5\ +BE66BB90E68D75801900FEBFFEA8BD5790337BB0ED215011E541AE1285FB3B305E05F4A2\ +4E2CD6D3A62EE76CA4DDDD2E371A67E36DEA94EA5C26CA1D1B322F249DAD9C5DE435D770\ +4B4F29A7D960EB9582316EC193C97BB5B64BBB2ADE27F250C2BFBDD48D660825EBE99E75\ +C0E4354E0E5B84338E6361A5C9C368F095D3630C3E9878AD:\ +372ADAC63D66E934514CB2E26B388F25 + +26BA6EF5054908E2CE4618CFABAF79F8D87DA4605B7F33EFA1C6AA0F039E138CCA821C75\ +F0B2D17E52932B25CDCDE78DA2BC77432786E865CB153E0A0C637E9691D08679075095EA\ +47DC18F40435B2DDD071D066F3B2B792FA528C0A64725F2B07981A2FD91F658C49B75317\ +FB963B2BB68430EC9FAAE98963A8EA85F62AD4F77E115D3FD979DB421A773F2454E6AF49\ +BD950550B126921E2FA581EEDB2387EA285D652DA362BBABE6F7D8454074B6C9:\ +9CD37096F29ED2C56C7D2842883A79D712F6AB9F5F08AED655CFECAA2F482FF470D74597\ +188C280E8FAA0B19B51B56A4A8B2B8E3ACE48927A61787341F5DC153621C14110710895E\ +4AD3886ACE7599919C985C70A8B9A7891FA43D1CDDB30726A2D5027D77386E5E8B80BD7C\ +BCBAA250269C250A8F2276E052A88997182528B947751DECC3E8555A8D4C6D6C223F7B6D\ +431AE2C7931DB88200DA4D987FA0ADDF0C0C8997B7224E06F9701BFAAB2E99CB:\ +B4BB2D7C1DCCF12BF555DFBFF33BFA09 + +C1EFE0B080811DBEAB17EB4C00E62F695BA71BB8E27006187F6F224F29D83820BEF01EF2\ +6D3CD5FF85CD5B005FF0DE9A8795B20F31E4D98A3BAE15B7BFB60FB8642D77C12E488652\ +A26B5E32116AA0F7177D1E3F46C31DFDF212683B08E84C0EE72A15466974FC5024F3A0FA\ +2061F53AAA86B3A29114D165C150D6FBBF0F07645C91CB5C9EFBCB292ACCF7159203BF83\ +A28FD040E92711854CDB4679A6D885FBADD29438BA11E9ECBA68F8BCD4433F7DCC6C263E\ +41C3E64D:\ +781D45863F3047C63BDB423712F166E4E5D018A6CD05B70E1131622E93BD6E0CB56735B5\ +335001B9B971A671475DF0EDBEC0FAB32DDFD422504A941860C223D86B77EE2A4F7CBC44\ +34738CF7F59059EFC0CFE4693FA9BD553B5EF3C1F311FDB66C8B4117620126768A742278\ +74D9BC89FECA06CEBCEE39528378B1B5915543453E667860D94C0406543B341175650D86\ +5D245225B0964BE723516490D8F908DA7B73A72C790A5B6CD6B980D0FF8DEFE9BE085916\ +3D3527D5:\ +FB8C5F864EAD033E0F3D427E76B5C9F5 + +B863168DAF023E33D00F90F5BD076FA62F3BFADC93F0A1EE0E1466DC87507BE3E0420F88\ +4D40511F5C1A6DC912E70F33EC90D52E2F98FBE89EF076E3A95CF011F6ABA8A946B409C1\ +96ED86094597D35C548EF84ACAD0CB3E292CFC4D43183F4D97C43BFC5445A5DDF396159F\ +9662D0D844391075E5A209A00CFD49AA86519F7C3DE285D9DD02F3924D0836C725AA0669\ +F3B98C4B42AC893B90F55D4F07B83CAD7F693BF49D72423A369E7FC563D44229CBFB5F7A\ +25EEBB50DBDCA0852851D417:\ +3F22A08DF104CB891887000C0B975296A0A736B7D074739DBB7B16100EC96EA30F84438E\ +3C9B6F38063C2C4FD8B39262D828F000B8176D6793F8537598DA976A29228966AF45F698\ +BE394FD0FBFED864BB1B81BCEF8D9FED2BC7FBECEFC31D319D6C54648C9C0ADBB83B18A5\ +6E8C1D72DB37FD24EABA87F6C9767E3B3FA4566DA71D03539EB8E558390EFB8B1839AFEB\ +E11FCD2F81774674228FB965D4A78164E57F5348DB47E06C0D2507B9738F3750D1780D49\ +E485B9CF89A7C716F9A628AF:\ +4ABBB43F2BF9C69B02AED5D4D82310F2 + +FB669C4A5B01B8808E3A7A08E47D2ECE63202C4F896402163D88BDE3FA02A0C7EA924B80\ +8AC430A3A157B09FDA1991A18DE25F842E2DD3A221AD2804660791AE592E60D9991C59D6\ +D0E50CA49F1F4FF5AABA0C81DA2C36EC169B420745357B82201009C2E2EF15853C65647F\ +C93B587E25415AAABB8AAA7B441F8E1616A1DDBA24C83935C5A4755C19719837AC1EFC72\ +75B37E264B1AF004513D53BC94BFF7D6763AB8AEA592FFCE8725BF2CC06C711AA2691475\ +CDCDB82A28ABFBB1D166A20D3563B66060699F16:\ +EF73A9BB5596BC30BAF024316E5085A71F83CA9C8BBEBA4C0F5EACE57BD0F19A9688590B\ +4F255E048E90EE2F8316885ABBC82BD6F15FD6AD56C3C58D5FE6BF3BBBC6795E4E9D424E\ +B570CA5775B39EF117F4D0337F88E6B3096F0206F89D01F1EEB39A388F42C44CB03AD06A\ +6A4E914D545499852E2EC5F1F35556515FC7D04E884D48D92BB1ED179C485EE5E5B136F8\ +1BEDF14ABB843AC9292B80440FDB5CDD50EB573C744AF2444BDFFFD785FE3535F698F446\ +B533FECEFC1ADF7752916B2B77C68F1AD08A77B5:\ +8C366409428A56AD49CF09F5C790325F + +379AC957E6721F2C33CFA9C8E8FAA85B3AE28E346E99FAFE06C5F2497724D800C332A3DE\ +25424523CBDEBB0EA95AA31C88B8A00ED3CF0E90B42BC1CF690618CC15796E1966AA5706\ +7D5B7E172A1F818C1C7EAF58C27E6EB3F647879E9785FC8362210C8E8C458A60AF1CFDBE\ +F698869E3347645C6D9AE7407F8DC7A1F84B20C1CEB17E33320F9BECC4B3E8E450BE9F59\ +56F74CF33F764526F097DFCB63C57C9798F791B471C494062BB6675C374EA7273E69C12B\ +5349172AEED9C66AF0380490B74F2293AA22DA87976580994A5109B5:\ +7AE8556DD6A8EE6E86499658479AE39CC400452F06071044CD165FF5C2B85FD59DE4BFEC\ +7FBFE20F578C1E21A53BC896D3FE5D77C7F908FA96A68FADA439645F621ACDDD9E2F351F\ +1E4D87BE5BCA2D6C93584DC331DD623925B630EC01C296F64F71DF0DD92232C7B0A0DB82\ +1B1761A442CA73EC3FCBAB386B0FFA35754ED91B113D51CD9239DF73ED46BBE1485075BA\ +AAFAC363F541870AA96EE7F21C4ECDBC0DA9F309B2CAB1C77D6220B2BC9EF5F2319607D7\ +C3D32C9F007C21CCA676872818085C971FFB778138C5398EE372DEC9:\ +0D852CA9C6CB0FA6A95F2B0D414A6F19 + +84B35BBFE1FFE781B931EEA1556DBA23D38673BB229EDBAAEA95A93736104DF3805D4968\ +95F105FC5433F698CAC70526A74EB67935788C35D87E6ACB63A285999CB981173BA6EB6F\ +8402F89D4D2DBF0A5DE904D5BDFC4864C6E48B906090DC418E9A91BDA8BE63E3CB341B57\ +0EBA6C5095A478C0FF43C062E12FB180D0B74DA39F7B562FFE9F652B3FF4356BA024777A\ +C34D7F84C45FEA5EC21BBAB205C6FF43EC92782BEEFD471DD8703FBD5DE167A829443F5F\ +1EE398475A40049C2AB577B5A6BF2581420F38D22F46142B59C92ED80F44A22A49644843:\ +17B0379B31BE60CD613289C2176135F971DDAAC953B76C8B48BA9FFCA0A040EF00E97A32\ +0FD19C9D4CB269AC205DCEDA98DB7390992FA4FC567DE5A39ACF08DACE83858E03E3BDE0\ +7B75AB74CF4D90DA3FF2B95476F9A81853BFFEBD91450E71E4D5BB5291BEA641F8773611\ +12D65E7578390A71CA8778CFACD4D25F71C90D289AD29045358D1DC8E14983E75CCA03F1\ +2521969916432CB967202086B62B33AFE1FA5B5A68BD4BF19888922F814577ED0E4F09C5\ +0D884A7DAE5B08B2AABFA8FA159BEA131841CB0F3B63F826E36682208F78839D9E84D917:\ +C071C64B7DBA548A42CF9656521425FB + +AC1211AABCB5E081D8C95FDD138A42FD6F1D808E37077D65D8FEAC80791E5D169A32B2F3\ +33CED7B84CFA383B430BD7611726230664C2471C0413CE30006872B0707DBDA38F9640D5\ +E376D050DDD5526A3313AD1247B6CE98F1484D9FF0169B7190F8D4CBE10BC03234E3CA25\ +81EEB98DC5969E2EB57A4C5A10DD5B5619D80D5A9B9C3595EAD7E0B5B622A5A2F685D70C\ +D687BEA1876C74A29DE026C1F8F673D66F1171B1633A05393A9896705A8E504BC474083D\ +B285BF8DD893D3D699505345EB97985948DA52A17AEABF279CC28E9793D360E8D707D5C3\ +6C0047BDC6ABE83E:\ +40BF0E1D3B5D92417849BBAE059D7EA6F22D409F5563957BAD0A4398F963AC823AE33A6F\ +6E908AC004E94A5AB9E3E7C4184C94FC90EBFAC6CC70C60FE939453507BB65913FC9A977\ +21A730880EFE22439DF0C516009A06FAE30F6CED63D9CEB707C331D0EDC2945EE3561EDA\ +E176E525E66EEF01E4FE4880F8F7D79A32E45CF71300A262A5F78079C20D7A9EB543D226\ +9579EC077A33EBCFB9289EB85C979951923ED96ADAA2984D6DEB1F5B3FA9CDD859EF877B\ +7594E84B99E3A9D2C8B8F984428D18A1B59EBFB851CB8EF0B4719725CF07D73E580C18B5\ +37BE3AFB34186668:\ +BC12C0EA9A1D8C2F0CA4F4683EFB8E38 + +2D2E50EFC0C6378E1D6BF584C498600F883CB10A49E27325E20A018B0BB3F192C7462F1C\ +F76636CB86F3CE38DBE3A70502A7A6F72EEFB76990773407DA628C11FBEC2E8478EF2F98\ +F0BEDB6733F695CF0158B8CF5AF6097F84116CDF8B973F3B0A6BC863B12EFCEDF0AD18F4\ +755974E9A05E554654115EA2B309DC37D41B7C1C6686C6470A7A528BFD2E8ECA7E28657A\ +BB5BC34532C38365FA1BA9DAA3CEBC85A9F30195E6D4EB52EF8CD243AE7DB1D082501FCA\ +2A93A4A81C4E1DEF5F4E0625BB088D0B2F4C31DC26561179DC3B46DFCACE0E82CA9A0505\ +8E2118194F6021CFDBE0D8C1D7B6D41B:\ +A6A0348A6F587D6664381AE45F8A0BC69C51F7BF6C26755452CDDB4F1F101EA2224F61BC\ +DBA8E97067DA55F4BF59A5D7CF12ABCF4DF18B92E4B6921569051F5E70F25698FE0D6C19\ +B891B48A3E03EBD7FE4A79A250A8B5FE6662D4430725AC447B55BBDAFB259B323872B4EF\ +BB452FB968E979006EA49A789F4C3743DBC1306AFBF5A4B1F421C99A3AA07A2E98A47B4D\ +AF2204CECB2AA86FB9AB60125AD0CD94C799CF3EBEC65C6F4F2B864C11F513CEA9D6280C\ +DF16B1F0E1F943A444786E1DCB1851681572ACA9571699B82CE9E5275E6999A1EEB599CC\ +8A0583D11D47938324E95B67407A0D68:\ +A114856E299B436E09F437C57B15109B + +AFC793265B90D53B647275124998999B3D8C91440541DB7E8CB0E8837AEB4653FC35361B\ +55D659148D9F25E3C109B1BB92C037397DA8F91CD5AF0B6EDE7667BFCF1DDCEE76AE83F1\ +67D937EB67005D48A9503315476A43A45001F621444C562563DE6901E969F6662249A6BD\ +AB7A638405EA3AC01304FD2DB772CC7AC122CD3D65B749A3F31704910950B642C8E5654D\ +C10B07C614C65A07BDE2AB52196999066284CF0F6EB66CD1A62C29B683A436C5BBC15704\ +688BAB92972421903D53F2072F7B8D53B02B70F63E7A7503207360A4872E04CBADBFEB32\ +1BCDDEA5E89419FEDED04000065DF73BE58A79AB5BDF885E:\ +6CAE06C13E54BB2375E3D3C741E9C61D3813AB63CB157E54FAFD28E9A4D935E57D74032E\ +5E669844D277F211B480F0E54E4F0B09C2242FE1D5EEFF32E1313759A47E7450B55E09C4\ +37D1EF3F60A0572134C2D9B5258414BA5D84774D65FE545F1B80E7FC06BD7669D05AFAA2\ +271AEE74F8E0C247070CBA2FFCA62B6CE5BFB0B6E75055F099939AC44FEC6E9A3615FD57\ +B3723119FF14C927BA06DFFA36E91744E035AE7A9F21625D74BB62C41802782201D1043E\ +5B9AE266997FABBB42ED800EA1E2F2A4E78C265E3CBAA9979ED89A8FC6C9F16BC6802A5E\ +7D2D819A7D8357B9C40B5BCC50726EBA3DD0791E11489771:\ +C722C9F2A15369264DB7F54FEB0207B8 + +936C9695CF82D4241CAEDA1E8C80DA52CA4837BBDD2158E2CCDAA99EFEC6F1FA29D6ADDD\ +6FE3A660F50FC6C2AE456BF742081FB471A317707C523638AA27DD85621CDED72631C469\ +0A857512265A11C283193BE33BBA6E77EACD56E9DF9541BDC3567814E98F0E6D57D9B254\ +40FB7AB62AD9375B2A96F60C4E4B57AD02F62EAA06793D0C5761369447B9A0621EC2F9AF\ +BE8F52E8720CCF67E4A1BC7285463E8DEAADC248CD8207739F04FD13F72E0A7A0CDDD5EA\ +0B7111582A389C21F499BB4349E8BDFAB0925E4C299773A9A546913D37B7951C9052EE94\ +55391880A77CC66F133FB8AF5CBDDB2433F3F9D52F94A15D8A9143D0729F6D60:\ +8144D92331D338C920C0BA0C6B32C6EE28BBCE148F6B56B5D2A12D029734A41B8B4071E4\ +A7601A88E8CEB031DDD38E4588CCAA900E8E23AA1C3D4AAD39FB75B90A8C47ABE3641FC6\ +B04EA1E74FD4B4B9E72310F79D25509B3DCA63BEB093A08F7149A23E0D548DD5C20449C9\ +0FB41C88CBB6D1D51D35DE46D4112090926A7948563487E34E7507CCBA9825BB48EA8709\ +239CB49CBC0FC09447570E1FDE99E1316BC24A5CD38E53F613152BA9BAFEB065AE30CD73\ +DADEF90E4E907C0E55EA0488B9CDD20926B3893D8429E4C9FCEA17087B6933064976F250\ +3ACD2D8D0DF4CF6F10BFEC0C914B0C46E6FF575464FCEB1EDC01AFBE446F77AC:\ +BEF7E425E917D067300D40D19AE12ADE + +23D35E037CBBA0A76A46DD433B547E17B54A81782A51D13829BA301250ECBEB0EB598F76\ +BE470D8411E7E58516873B4C9BB87E4B41C4DA3BB941C3F8A9EEFAA507D30948692ADD5E\ +53AF8EF3CE42D6944D8E2994F45F4090B8934BCB09B94B3BF04726F42B00ECF9D9893BAA\ +ABFAF712E022F82317CFEC8AAEB7242BAADEF7526833C2EA481816856BD423CC652CC043\ +01C7212BBE69F251BEBFCACAF0F12A19F99EC4A88E4381403B24322133373ABE881C0F97\ +D706EE4CBF3F5F7E69B8624F50270E508ED0487B0B8116BE1AF904C23B4F704BCB8AF92B\ +118A912B5CD0D759C3F73A6331E1337B693B7EA65A017CB62C51A4E4AC7C6AB9530DE747\ +FFCEF27C:\ +D968A79959F5DCB6486FE846504AC0E8753E56410795AB9637BA84EDD9AFD692DA253ACF\ +DE1FCEF40280D30BAD93AF2386B755835AD1CB18D472DAF37D7C69109DE9898E09C69DD8\ +D5DAD6D6640246B28F905FC0B1329D44E9AD2DD4D5D467862AE364CE7A81D5433B00CAF1\ +1B9A1D7D54910CB2B01888348ED423A2BB40CE0CC23210CE10CB9B123AAA8F41A3B25114\ +398160C0E9241CEF67F52CC419AD31E5E04C4CE91716ED99702AE69E7A1D501C47A53F81\ +E611827C7694E9B4B9446F263FF1170F4CD70B432EFEF97F0916CC6BA81A8E11EC996526\ +E9202F6910FE8A427CD0BC8C7BFA23D0DCE30FDD6C2F36B582A3C9B698BC5CC6CEB3F951\ +B26D586B:\ +19796BDCABF22920277106075D0E0EB0 + +[XTEA/CTR-BE] +ABA78D16A7A85065A61F31B9C9CD4053444BA2A36C80E97C4C7BD0956676FA39:\ +4B33050781F6003A1A4CAD8B188DA93FAB60C28BBC1E5D822CF7551986E2A5C2:\ +EC1147D3A4CB70A20AA8664E88E60985:7A38520947DD623F + +14E75459D23667074E7A7373034443BB4B2C7CBF90EA1A18D59A93598090D92CAB4F8F15:\ +7C2E05A9570504B7751E4614FECEC7F7449FA1B25895C4435A29AD9DA8AB41A8CF06048A:\ +2FEBE8549A5DDDA945398955CBD4D3E9:2A95AD603EC4B59D + +9388E427E80A52FE5EB761560A2494526DDD7B4729FAD683E6C8B57FB46782B9D016AA0D\ +DFC9C313:\ +8020D203BE99C6EA448C64EC4CFC2F02AA220CC6194EAF81D938467E8BB69200B2F67AB6\ +D6CFF596:\ +62F04E49D6CC94750FA5CFC871DBDCCD:25723E1410D2EABC + +AE15285DF8745CF588C3D075C545591CE8C87E0840CD8EDC9336ED08E42D2A4A6BA0B7D6\ +045AAB25645208BB:\ +82777E8462001C6BE7990AD149ED8AA462CEF8FAA7F3377CDDF07BC89F0A2EB39439756C\ +31D21E932FEB672A:\ +F7E815767C7D7542BD8F0DB41C8C0E95:8FE94927EEB3ED8F + +94E0F6198EC8C7C7DF35262ED38CDFF2D5BC48A1FCA450D250345996EB01BFF3965F221A\ +F4EC43D8CB7FB89ACEB01B1A:\ +8468BE0862149C3CA03983C7AFFF1D61C33FAD83477714CC51D40C6F1F045530E9651757\ +DFFA70BB1C4780D6F44A0E9C:\ +B64DCBD21A7CB07620DEE39C74BD598F:74DFAD2D6C7375BB + +FDEBCC1AC9107EDAF4AF10F34B6E1C8EE15797901F35840504754EAB53BE680F30BDD571\ +E9B50289987C6292BF2CA838D932DE34:\ +76F9EC52A2E6C5EB209E7CFB4BD40EA0CAB974068A0CB4C3490349D3024CDC522D11FED4\ +D91D32223FFA8916B39D458999FFF43D:\ +728984B99C7E92CDEB49DE0B3FE42AA8:888F01082B9D2103 + +9B0E0711E375D8EA9735F98F38C58E9184E66EE71DD12B9E14F80095FFE53C6461A3A362\ +650D150C2FBB6F84DCB0789D6E7CF63D8DA9CD6F:\ +EC83CD5B6D2DD5B438CCFDE65580F1A45053D01E15370119219B39C124A4D99F8EFA44F5\ +001BE7F18C7E0033CB1411AAB97E104196434346:\ +E55ED01805B70BA13D785D8D859F15D8:5C8907CD33AFF98B + +22E53F89A5E86CD4A874D5CF372E51362E8F71728FD855730CC87BE1F57EF26577689C1F\ +5390C158B6E1ACDBFF1B5BA5D90D6B4F0C2D484D9F0F513E:\ +33F1FC8F0B7B13EA9F2676597870D55E285F7692B5F89CFCAC80127E5E85D1D3C5D624E2\ +2A4C36066F7EB9AF665AA1C7799863FF3F5EFA3FF027CB9D:\ +1D22726357C301EDA933D7910D3135B4:E046855FFD91DF19 + +C1EAE81700F699ABD728F04E671BC2623B70BE954A9CEF23CE43D492197DC55713406212\ +CF1E322EBEAE57601F2B717AEF4A3DD4EFEC18BD9FA55B226EC129DC:\ +25226E84529A261AF51E429148A35B389A88809B75D983720084586AD0A02F2851CD92A7\ +2372FAE97A65539219EA224A9B1BC6C7E8A0586CA4ED37C3D452DA4D:\ +065EC565D8BC713866CFF86B0ABC2BB1:27100BF3F22105DA + +325748DA5C629AFC738D34BF32C84DEB40543C276A3A2C13C6A4BF23B885B6AC348D2746\ +7BA3714BE4FB1B764B81FAD7EE2D062277B4EC428F0A6E6CADAF5EA55860F8AE:\ +A0FD6A60A1B8A729CC52D41FBDB2E5E7896EE8C9944E6E63CD1A769BF278AE2E8CF48115\ +ADEA864B00DC65B950C68D09079CD81D35459F5F483F9040FC38AD50778B4217:\ +6AA995999C4EA6C83070988AC0A795F7:01B5B1C6E92BBEE6 + +23019A5A7C61262EA124DAB215A517423781B9C1BE56B63E794BE6836026F7CD55531BFC\ +08665896FCC7CCDFDCEA09207A8785C8DCE932A00A5D105A2D6682A32604D1292207F195:\ +47CDB6D6BC25AEBAD70E99524CB0EBCDEB48E0531A35E505FFDA421A1F27ADD6BB9ADC57\ +C3525B989C0C1DCE37577877CE328E6D317D0655DFA80AA8B62273C7AE8DDDE05EECD178:\ +E6D35BBAC75EFAB74AB954C8C2D0D1C7:6582E6C1B4A47B2E + +9F8B703434DA473871B05A0D83EC424FFBB0DA17224C95D33178FD28641C1ADE87559E7D\ +ACD11F819CAED832B095F6F804FF63D4E239D620B8E6CE8DF1799D028926A3FFE28BF433\ +664B166A:\ +8E1F3C026E4885E3693FEEFAD56DB8A898269D61CC92CBFA0DE1DA833586619AE9D0B98E\ +54028A2AED24BF2878B1894F4BFE090CF0A7F2627106DC0700F43D31914586DD1A1CD7A1\ +A7F5D82A:\ +3145D3926C22A5AB4BBDCC163CE93E0B:CB8BEA9267176935 + +4592FFC1D25A2ADCC9FD5DE77DB143AA6E17934FF882E2F8E2BF0D8BFE6DFE10AA33D124\ +199BFAE8D3C2BC2B4B9EB37FC6289C0ED2A6CDDE407F78C035CAAB36653FF686FAC37E51\ +76B3A821E21CF7B1:\ +ADE67B169947C994E246676FB301C44204D8817BC3291DE6F35552E1E8BEFA5763F1C605\ +E2CA7442847030793EF1CD830F7103ECC9928FC98EE4B346872ADADF439464BA40CA0D78\ +63C4C9946E723E71:\ +353358DD5493234F6BE6E3AA3AA4D393:A17467FA740E2541 + +E3100B239057B16CE51A754047F20D6537DE016ADA61056761C1D9DF3939AC8C0AB155B4\ +2C9C3BCFF3B63BDADD21954C328B4CCA4F1EA6A57EA8B7A99BFCE72E57CA2C87C4ADF0C8\ +44CB76A4B8DA35BD0A3952AA:\ +AEBEC1E382AD5129278CB4C5A67EF92E64BAE93C1F4266FBD40AEEE0E28D5048E81B0CDD\ +2EB7851B7A3CA43BFAB751C54217DE5315D9EBCF94238FBA5A8114C28F1AF6B9110DBC84\ +EF13F621B8690AD7480E9E90:\ +C313724761DEC636790E38D93F299530:90C5A696C66726F2 + +6FEEE7F77DAE629397B0EEBCE6A4E7CD4FCB4F14EBC408A6798475F3EE5C560F0C38FB0F\ +9D2334E85B75C36632EB4C9ECF80F02B47EC1D589720C104B111197E5CCE4D08441FD98B\ +9D67E108BD5AE4313B5725F7B86BA4E6:\ +F73ED0FABED7812409A04F100F1523DA22E013055537803A3F6B2ABE9479A199B2DF80F3\ +F379640228C47C0475A68A86A455B4E53D2CC078A9EBB04F37764714EE9F0202BF15C393\ +CE87A6E339CD0EA52DA997091383D151:\ +3ED02192D605AB5AAE56CC630BE39141:09808B88D15118CD + +CC1B18F695290A169D5DAF220622250E4C3383C871CED8648365EC2DEC9A14D5A522441B\ +35B8AAA51FD6D06EF8E5C8F6A12F8EF068882B826E1B97844F0F088C1214DD1769E6F1B3\ +29CC62FEAE91D1AE9CA752AF80A966AFF9495BD6:\ +D86A1A79CE209972F3F5DCAB0389DBA578CB0EA6FF657E889CF6CF7C30C746131E71927A\ +3CB2DA42A823A19E176510CEFD9AEC30D7F648097AAB847840ED396FDFE4CD1EE0C131C7\ +63C17F551457E5D0D933EC1CD30ADABE4E69298F:\ +E53B03BD00F9E5817BBE38EB1760F950:D559750E3DC7CC19 + +D150BC8369DC06BA57F7CC241766549A52F2D49D7AAF9CF7D6BE0334FAE2327FCC76104D\ +E5EDF782E32B8CCF92669B62B25FC619DDAB77BF9AEBB2D175530AE97B56BE01065B9532\ +4EAF86AFDDED0C93DE01F139E6B0302DE8F59954F0B20793:\ +16DCB3F6A247FCECB4B5C7790796166540892230E00AACEF9EACE255ADF579F6BBAB2F2C\ +92E8389EC54A6F039963E980550B073C0CEC4FE554B2A23C69776D35AFCD128559104141\ +5CC9A15BD1A4A89AF43F702B06F1807FEA53490B80686A52:\ +48E7EF6FED168BCEC4069E3E622530BF:7C8A47B36E7EC263 + +1B1508A165845B4EA7692CD8BE5A38B42AB114B9A63E3243D3DC1AEA8D279E2A12BFFED8\ +88B7E4702CD51CE577E04B9E401C1D6ADAC4222FB87A5BC81CA331DE77BE79D3C9287839\ +8752DC9678D5ED422E40B469515A64D1E561DEC0D3599CBB88AD71FB:\ +AD25FC4AACEB3BF13B5620DD0437C0E5EC62869F5C0296C7A0666CFE974603D9509E2980\ +4075560D1674EC8DF26BB7FD8F9438731927DF583D8DEFC45E960F0F03CC71539E56F6F3\ +3FF324F265D4E3596F97630FEA0521C29210830BD5514E8DC390573D:\ +F931CF1396F15FE1FBED7A230961C729:5DC1DA62482AA6EC + +969875002E0CF955F29EC9651D8AC98B667A8700E96EAFB42AFEC3EFFC9A219B614BCBF0\ +C32028EA2ADBDDA5D0E3444E1658C7E0CE20362E00EA73B2428027FCA2061CF6B492DECC\ +FCBF06E519D05BCA2282342DED05B0CF2E1E25639F58DCD220922B690C5B5E23:\ +4A1A307B23136A6C15065ABE453209D1B87413260BE453F7231629F99709CC9F56D25FE6\ +D2976B2EB968B83C4F58DD21DDCC0DDB4434633181E4384EFB89EA93B679AFE93C77E477\ +6B28F504514DA0471C49F6E5E40BA90BF167B3849AC6D7D1C05460EB0D262936:\ +238F54FD6D70A8E8E03F305A8136A4C2:9C764FCE696A60F5 + +0116DE193FF6B1F703B18EDF87610137D14EBC3119A979CECDD460C38A38817CC12FE56D\ +2110442A56A1BFBBBF4A1CF701B502C6D37AD1A6269546E07539FB4EE8612216FD3E69CE\ +47513CDE9AEEA674D6DC1719EB4A08A513DA5CF063CC9C6C037425DF4A44766516E41FAD:\ +05CB3542A26697484D30EE15EAD8DDF8B5D940F5BEC00878DB6FA73D1015B758DA221815\ +AA1FE5F237AC3F9D6A24E946097A9B1F8DB04D5AC68B0B6F164596FD087E06649F05E750\ +3617BBDE7868085FA3053C79A1C878C8FB46CFFF98F782FEECCAADBD93A087497A9355AE:\ +84BFCFD08B09C9515D703EE5F629242E:8B22EEDB409EBD8D + +F8810BD894C82BA767986F98DE5CD7E7F9ABF6E82D88AFE84A6735547CBF1E13F285C35F\ +8C5B3DBDCD89D9DDA3AA4CC4C153426E573A585C9A21A77CDC1EC886F64874ECC2482458\ +706366950A1650A30BDDB73F9A619CEDA1B806CED6E1ED00F63650C09490CE87112F1319\ +431FA016:\ +8D2769AC11176C15B77F0CB8A72B34160A1E3939EFFA43E098B50271D9B031FB9F52E6D9\ +49B150AC630B2CFA85072F797C9AEAD9F15735C69274A9BFBFA4BE9E759552B8E02CDF6B\ +F07DDCBD6C5BEE9C01568D6129676D20DE0762C5D466252CB286E0A1B7C1CE6E4BB3FA4D\ +9B56761A:\ +EA279EDFB80A909C95158D9107E7BAB4:3D899C4A9C64C494 + +E1959869B615E838C4362ABDEB51A3D0BFF2CAC32AF78E27106B1161C5D6A893A5A31B78\ +FA92AC70DC3A9CF68DC62280D963BEE9C04CEA5F1FB32B15582B37FCDAEBA18DA3B22278\ +3D2E7484256508F26BA549AD56AFBA3F5B0161AB6A4A6EFEC326477E92B025FBFD29498D\ +DCE8B9D274DDE71C:\ +95936503497BB10E8C110CF1A819FBB13DB05DA88723055D8CBCFF2B15C8DCDF12BC7810\ +ADD4A82AE8A85DFD6D906B5936189B6F0B18B9979A0C55C08E53BDF37BE251AB364D85D9\ +E94F6AE957131AF7CA475BE7F19954B45CC3C00867B9EB574B614CAD4A66BB505EC9996B\ +7DF9467A39096CC3:\ +09EBFB4079E906C5F8BE9B2041A32305:998215883ADB9F54 + +8B2999AACD2CA034908EF05C394CCEF00F816E57FCA840C6010760EFCD6E3F3AA088784D\ +530AF024FD9E3BB2B4EBC5223FD3DB3493EB6E2E1876EBBFD4BD0090004ACCEFBF3756BB\ +82CD18EE4CEEF6FBBF09AB0DB0465134E848672FBCA3BBD6CF8AEB684C4A82244D7A5D44\ +468E0F31C41B908989B7EC26:\ +51BF0E20F1FDE6F5B7FD1B72749709999147D80866C7D12E8D37CA2896D67F889FD5510C\ +8F74C62B8D044F552EE7B009F943110CD3EEDACF20DB04F3522434D5BA4E0CCAA29DAE39\ +F18CCA49EE1CBB9515C13FBC38142775ECECD778BE72497487D5A0763F20A6F84BFEA19D\ +4674066E934D8D73ECA96C28:\ +809C0B33709493BA086F146697A9DCD5:F263A312E9A219B9 + +60C66BE7E8951C3E406F5635AA22FA1869BFC560F337DEB230EC6FBEAF805A778421CFBA\ +07166136F1C1F3AE674F895CE24BEED79C81BED23C320B12C45894AF037CDF91BD540563\ +7772D4BE4B06E72181286194BDA09BA7FE682972E1D8972A09096612114DAA9CABD80816\ +B5C50B2C1644FD6ED8521E7F82540F15:\ +64A20C4BD5F7949AD3583B00651404AAD4496D5C3C39A7D463CE22238A741DE32083AAA2\ +38E3320DE7FE007968BA55B1F14AB1E88064F2C112A0E97C37CDFA9D97355692E0E9552E\ +2A71D22DC2B5866902221B7AF4BA94810E74CD4D6FAA8E57263EA721C2959A240FB33634\ +6C602C177F95B40B11E0DE004CCDF6E8:\ +A794395BE934B5BF5FB38EBA5E0D5406:4ADDE2D9335FFEEB + +C37A738A4E6144F1E5EC5B8E1E61C71AA0449D83E3D207136CD63D1A8F978D8D0B00462F\ +3A10B193B2F5445D2BB8F0C71605F277388A23677CCAEF508041C406219D8FFF569E44F2\ +4D4DFD9216D261E244DB588FEDA33EC4B87A5114378984559004ACEE5DDC6C16C2A25D5A\ +FE42C961CD5C418B44E218A749A357351131CCE4:\ +64646829143CB4A25661723F772932F14BF4898344F70EEF3186889849AD9D1D98CB4805\ +26FFE8E7B6AA15F3A9346D10111E79C809FF435EB8851907A90530F2B96A2C0E1E1A2587\ +C8AE735222967BC82A8106C604C9F2FB15E4D7EF3D8F9806455ECA090A0027BA5D2D5228\ +7E0831422377336450F45D268A6D2BDDD474FD84:\ +D9653B71A3003270F83DFC49AA48C8EA:40E4D61971A2D857 + +2E3ACE745E2D36728751E0A18448971BEDA6F21A742E21DEEE68922E89E85747EA4BCA5A\ +BD903FDD7EF705359E847687C5C132BB2556634DE165F00BA0E4693CF364CB1DC100A073\ +253732050AAF7AD77C2983532908E888A8DAD84E43A4ED29335A5515940177F8325E5D36\ +C6892E42665EEB814E6689F0E06A3C5A69D042F50EAAC4DD:\ +287F31451FB5E6769B3EAAA58506EA403BC6F47DE662BC5BDB558523706DAA72B16174CB\ +F0DAA28C5ECA6EAF37EA0866467A8860ECE342104E63687A2191F2927A0FAA1624BAFFDB\ +8660DB0FA50627509D9AB5AC422ACD521436355FCE9DA020C11D402A02EBB46DA363A799\ +9F348DD815CF60B115166BA82581CC01358B5C7F52401E98:\ +F546A2AD3A1F291A995F4C058D9C9F78:7F993DF4D373BA6F + +F51E1F304ACBAA9CA94555934652761CEC135E591492912468C7FBDA2807A61EDABF838F\ +0EB47B99DD441C54A03C65AE73B2343A9E12C6B1B7474BA6E88755C90333110861AECF6E\ +EFE5CBEE18ECF2631FEDDABB3AC0FE36DC66B1E78D8FF5162BC5323F85932B2154089975\ +01E3FC0DAAD12A51AE1F1387C8ED8B132DEF421D0727AFE59788F4D3:\ +BED9B697D1DC34037DFD5245FB74D684103E9F6B649024911976336DF5451443FD4B32A9\ +AD91B2679BC138066DC9BA6C367277EB7A7AC67C505CDDEC6300D26FF5C9E5825420F356\ +532D78080459362399FB9F08684EC2693AACB90382E326431B1AE0822BC6E3C4D67DC93C\ +301951E8635E3A19A71F0EDB63D44E53951B097B5A0FE3681E2A472A:\ +B8A2DACE13F418A8C576AF7F5DC03E79:00C100EEA0489AE9 + +DD2B20530B72F4E675F1FD7AE4FA8B0EA84B2946F1ADAEBAC8DAE5D1168C4084744F879E\ +EB9507B340EACF728D0D10786A6E8A4408908A6ED0E6198D8D1675C918462B82EA0F544B\ +DB3E194ABDFC9B40E2AC4BE61E907A70352532648C1EB6D72FC114544DB439516DF681F6\ +42D487924ABF0524C068EE4B9E45009BB8E99DE5CA73372A2F7DE78439150ACD:\ +4A4EF7F6C0933D12A4825EF1C293FEE5F95DBC69521323B6BCF527437513B878D0DCC039\ +0708B64CCBB8C3D7D1D1FC574DE35C45C2D48770DA757A65A177F8AC25C3F1F59A848E5F\ +DEDC9ED2801300F1A3ED44EE8A9F5A79924BE7E9FEFBAF6836CF18E6F28DA81F87DD2ECD\ +B48CB009A448172B556D977315F798218EFA44A794F257D250CE73AF151F74B5:\ +3EC3D092356A5B6874DEE6031785E19C:96F16B8BBCECE7FA + +5BC87836612D3D7FCBAF662B16924062C237658471CEECC0F1300C84531215406420D7C2\ +02922DF63F6864345581EB8C3345BF47D5FD9769563EAABA49A042A21E1CB39F51165BC8\ +AF5418169C8A0A9222C4A333559CA6F3DAB374D6A342D8AE24E41C51424585520415590D\ +2874F93A7919F2BE0F25438F0953FD3F8FD2804435DBE1190660227330D5B0FB3BBBDDC8:\ +077DFDB7F6E7EDD024C475FD57BFAD68BEDDF0737C1A460A589A8647212A61B33827D953\ +A2FEFC7F48E2979C4DFBD4285D747C52E3CE232FBF2307FF9F04E39C3D817B7402FCE656\ +08E599E37F208BA8684611C8859B2DA1F7F6797DBE58132E0BB143BF990D1D3D8226C2B9\ +F6BC50E8A03DB6C6560582C03A3D68F48E781B054DD69615B5A63B6136F2AB75BB9585F7:\ +11132C6E22979CB5C213191045E750FD:ABDC21EA87125B00 + +673436400DC4FB49950303A83E0BDF18E477F638B5E768172D86C2223861A86E73A5C423\ +9FF593B84BC3B98B67C56897B6417C9E5BE8ABA361E4EDBFD95DC3B15FE96E51BA717742\ +C449F635C645CC3830CC7EDD36D1D34A1F09C46C33700BBABA29EE856A86BF6D146166CA\ +975B2BCAF3C7E3C6614A03FF47BDB498BF3BDFC328C79228303AFE01BD80FAB8D54A0F2B\ +E38FE911:\ +34723A46EED388E0A273E9DE120946892EEC04EA668325C654F43800D300970DB9009E29\ +9963EB08BDE37E4AAE1B3E540EA2BABE50534B93D3988DD1F93F0E49761D83C3F95EEA97\ +9241A22A80D969ED22D826686BEFF174896D74A1F7000CBD164DFC07B92EB66EDDAD1194\ +309CA143605094BB8C330F31F5232A0A24936594DD4E7BA41E6039A3CAA6205074656CD4\ +ACBEEFBB:\ +6A0DA91DBCA54101F99ACB1362CB882E:7ECFD1F603D67C77 + +B5FDD61F8E6110D7AF03DBA5AC5342F9119F2CC317F1985CB3305E7DECD07A1787EDBA37\ +BC47AD1329D0752F4400E506A098CC71B83ED798CA67A01863FDDB8BC2952C951B46BE9F\ +8D9F83B7E0FE32F8FF69FAEECD49D2ADFD62C405104DEC61B4C3AFB6088B5369E88D11C4\ +9E7B5F4DBA284CA2BF5846275C5C2DBDFF8EFCB4AEEF12E215AD6423E9D5E6213382D75C\ +27D0E6D14C78FC36:\ +E42423B8CE44B0C3F7BADCC2E0EC469969E9531CDD4A0B7DB8646014A5D4BDAAAE109619\ +8860270A1283724DCE0E886AC9489593FFDB00B478E8D6BEF839DE633D678BA945F26D5E\ +FADD08297AEF5D3618645D200C627D6B6097BE81248B23F825FA4442C34C2F25A1E41D44\ +5E283CA3BB723681E654DCD7932A637834958D0C80DE6AE92D298B72396BBA5119DCD873\ +A403358ED479D453:\ +08AFB509E7385CE045789878C4B13D46:A3E66AF196BDBAE9 + +CDD81737DA50063D7581BC6FC8918B542E0F161D0D4BA408B5890196320C71DA508651AB\ +850C565105C854872ECD8A336CDDB5511399219D1E15387F21ECE4CE0FD896508D041C3F\ +AAFA75EE42E24B6C5FB45BC7B98FBF17E734FFD7C9E7160571FED42DA5CCE42750D46989\ +CEBC803002B72C14390087AAD352BDA885B771AFF5EAE3E6CF1428AB628F2E792A92DE72\ +C5E0234BF0AE05599A15F829:\ +B492AA4DC9B8C4CB3CE1AE1FB256D0455444D5BA7495BA36D8EA9B6BDC89881C9AE6044E\ +FE078AA9525B71FA983D3DADC6A03B5B1E327262B21718CB7EC11F46E9CD18DD6D94A9C9\ +EA923A459DBC518578D17184C6B19647C6F6FD3A99CD1EA09B97508DDB6B7439FD6308FF\ +E609A7B1660B1399B07F637D7C20B8990A652177A3E634092784A6499A994F7B2644FC1E\ +A597EFB4A4E15F08749E5186:\ +178178B147A4454EBC944527EB05FE22:B3C0BCCC0FC8C398 + +45A13F4D44F679618C049E0F6451C1DF764CD6975A08ED9FC21B7F60938FAE7EFB90D9C1\ +FC9F6EE0653319532D6E5EF4C91415360C42B13F3E9C4467FB910D617AC9A73EF44AF243\ +75B1E8A7F5A5275E18024276DB173D723B9A834E4549980CCC09D5DC7D9AC3B6967C1127\ +9C3E3847C3D1E9BA98E7F9F577E322C1985E06ABF75557540E676ADC9741DB1C4B078814\ +A62E001C3F98B116E91A6E4601CA5F90:\ +59A7C4B96EE561294D33E83DBBD876250CFDFB91AD6A1F76E112DB95D9F0A2DC1C5BB58C\ +01F650C933C9948A18C879E2115DDCF59499DA33169481A521576695AE9A248A8078F5AD\ +D5DC1E63AD39A001346BA3E3B541A9FB101B327B0DE2363BF17FFDA8CBB33142B58484C9\ +C7D888E0CD7B4482CA3A883930E35D581C755537AD4A7876E1F028C8344BC76ECBBE2AD2\ +5BDE23FE9F5293C414D2FEB1FE94DC1F:\ +0A0035EE3EC39ABDD835B30D054E63CE:6345FFDCAEC79C12 + +36144BE61EC490E90F95D38A8FA17A2A9C00B4843AA12D8030D01536C349585814E7D280\ +F292BF5C8CF2F4F2E68CB991AB0253045626AF958C5F591FE34515B29694AF39899DC4EA\ +A1B526C3AB2BDFAF51378D0ABE33EC6892EF01D281CD2817112D1FC685C86693A2734C5B\ +5CFCF6C8145C990CAECC9B318EF7F5BE8B6740B280A39FBD8B9ABEC947277779ED62229D\ +2E67EDB26F34A9A72806FE1E93A4E2E2E5D119E1:\ +FFC4706302E667EC36B915B4298BB11B0D2D1FBCB0DA35A12D1255AD4048FF593B880E96\ +C2F9451C8AD38D304148E2DC920E9B26ABA72CC05603C6DFC21CBF7B528142422537CD56\ +4E0877FBABAFDA326B196814DDF9FA8515C91CBA0D45EA8D9550C6B95D8FF35DA3F3A1B3\ +CCA42FEFC562177FAC15DB5279CA50D6A7D342EBA98A426BC7943133F71A97E074AB87F5\ +B30F8F23CD26A8309D78F69D8B39FF2DCC3152F8:\ +EAD6297D0A3A3A8612A17C4C336E19D6:66B556952B67E560 + +9B46EF1D1046A03836BA53F6EC68FA57B382FAF02606B4F272404C754F368DFFB1225CA6\ +F9A26F22B0554818BB9F784F2AA5368B42E82A4C2C1052F656BD2C0272EDF95D997833EF\ +7D1547E08E407CFBE1C996E9DE05EA5166E1236FD6FBC70A494FCA1A6A17BF4B3AB12E92\ +A78939BDD5A538E55D39E789DCF2F4DF7A8F79452FB4ACEEC4FE364B973357518A79D761\ +10353CE90D48BAB713D7B7D63AE14AFD7913F4EE74F02B51:\ +6E9151C9F82CF529E7A2B63C97E451ACF59CF00971B9789FEA5E8B1FD3071A64B312FA65\ +65A89E42DAD21C9D6BB5197C7C944C69AD6071809316E8BE5B67A775916A7E8B633BE189\ +00DD59D26612FA4624D12AFEC3C1BC39D1C9146761E0B3815889D0B3C37B860D4D56DE04\ +2D163D9F7236D1293B42822870E4797EF63FC00D3A8900E85F5BE156EBF2D97A5B71B56F\ +B0AB95FBA03C4671CBF97B300D4E90569EE9D586A4305533:\ +4E7FC8BD2DCF8D0A6ED122C394D6464F:CE96ED105D3C7931 + +DD3C2F94FCFD7C101022B328D3F11A81E8A47A9CF36AB9C03AE81433B18581E5B1512417\ +BCE9AE91DFCFDDBC5BD6957FA2602E12223E98122BDF22F0DBBCBBDD4E88CD2A87C0334A\ +B108845CB44ED56BF25FE3C8AF0C1463D2A0C6E149C218B9942C20C4FA5F42CAAE9E0FE1\ +36B238B495FE1BB33EE712CD11FC78E2536D7DA293D5E624BFF86EFFDCBDEB7CCE8B05D7\ +FD4D6D4B926C6234E602D84B3E93FA5078EEA598C3E8CE3CD9BA61C8:\ +C749DB2D42DE856439612BFB902897122B6B57B6E5B3DBE2844312CF131DB3B7B65B4096\ +D1ADA9C665C95ABA1AF299385E8401310FE9A43DCF1D0239F4C88493827F7EAE7FF5B8AA\ +2F7A1F8E42F9D3B90EE84E92B4F136ADFB4D459B22195562AD525F0FF12E64C9072DEFEB\ +31CC0331B7AD8A78DAD43E18BF84A1AC2CEFA4858BA1895A15CD29F4AA29CED0B5D5590B\ +D1AE2DE335E795CF5645FE9F9253077144F30EDEDFBFD93F47DCA24C:\ +911E1A315CD2C8126019607442FD4279:CE1FB0B32F6FB617 + +FBE74B418AB2B39F83383824C6909FBF0750738CF218EBFE913492E6B458CD25BC79CF2D\ +1BBA62CD4EA9924F13E9BE3CAAE81F9393E1B01C213D13EC7B32D42C4B896614397EBD25\ +960F2543AEB59DAF8E061F80B2D34212202A91D35AB9E9E15F26A8BB1E20E9C8645EF0A4\ +0727C705EA03600CF88F58E2065E920DAAF41779281D02BA70DF465DEC7D34669F6D0D8C\ +527AC7BD9A0EC3519C8DF317A697D4745ED94B13FED3FC8ABCA76D6B4FFC1390:\ +79E20320F675AEDA7E1D50A32C6B6C17F1BE8FE14CA9818C30AE46830A41569059926D7A\ +1C238F7AF469C19705C5EDC127EAFFA45026A39F49A5E71E3034CF4EB738775CCE69ECAF\ +62CE39CEB45D1204709B26F809B53255D1513F3F8100DCE3EC915E162AB17C62EF70D804\ +8C24E2CA11D3958CA9D06A1F16E571CB5BB39B0F28478A68BA51AB7A5C14611DB5781C2F\ +3302A15A7635B60A849D9C0080C62D244FB03670EEC92A4FB403A7BD089027B3:\ +5283BDDEC2CFCE31E61A003516C9D151:7A2E404FB6C3B6BB + +5D22783F9FF3BBB0BD89621E7C18E4647BABA0C76563CE14EB2AD5C4F6F51A49C513A4F9\ +C12CEA6B8C24D27BFED626824109E9B39B7468F39FB856D6C3946AC95C1A211FAFB4F767\ +3717EC97182CB9EA000BDE3F2905439EA5F6579FB7E6A0E8BB33D2FA3F02A5D678F1002B\ +4F95B2FD4E1C2559BECFAAF1D712AD4E37F6EB9088F81484ABE54B3A959550A2B41F041D\ +AF19167E394FFB9410D71C2CD90682D0AA6CD22D8244B6C025B1F5E877DE97372286C835:\ +811F5009DE77855B575D9BE64ACD8272699862AEAFC0B6284F4481CFC5FC1D028BA072F6\ +A2398D1DD99A731261C5E4543A0FEB7E089DBC6FA7AE9DA555D0B92A58A4D8B16A39777D\ +3368B6F698144B3E5773EF0501A41EFBFB30A1FFED14E11CAF106AAA515AB9FFF8AD9AD4\ +917155083754A44FAAFE449205D47F5D7296CA3917C575FD3ED10B26FA6A218B00374DFE\ +8EB43AACFC5E7DA3B514CE47AD69016EEBEE87CA8AAD668CA270D6328F7BAF60B0647CAB:\ +D2EE5AD0C6B1277836223D2B8999EF6C:CE3B759B6881D0F0 + +87719A3ED11A24F7EB0AFCF7743456648E1E6F170A4C98AD8296CCE7DBC9C59F761CF8AE\ +0B7719E42798C45DB57477F8D6640B5BB5A07352DDCF46FAD9CC19FE8304C1000E2B177E\ +A8BB610BDCC989D34BE946F9F37C71BEC8922BB1B067EB8F6FC6295392DAFDCE5CA39419\ +87CF2072853297020A2397A0E1F71FDA7FA381196C942B01A8A3F82874AB7D6AA1BE59A5\ +B9B1FFA357F17302A8E717E0A664400505A183F5D1D89C1E7EDF87713C5C114E10D17412\ +C28AB68E:\ +1E52C0BE4B78C8B45805586FFD14DF7740DE330877913156D11D9185A2414BC5E1317CFF\ +85B416F2882E769B74F974F0161BF7D582D25FAD24820A08A4E1D43D214E8AE6B4EE382D\ +52C4754430628B26A4E5EC17FFD939A45C7C1EDB55329A20B3BDBDE7B62746D04A07CE7E\ +2F28BE210B6B188492719B6044ACDD221A12FE6977369FF0FA5D12E2A5F492A594992BDC\ +E86A62FF3CE6E5A42897830CA156E630EF707705D6BF171C250C965F5563E235E898BA0D\ +B9A30FAF:\ +B793A8EB1336E6F82E4CCBC6A2BABE79:B573079D57C8FEAD + +BC5477DFF13EC99549F3DBA37E83231F9182CEC72D1314BD587383E6585BF97CA9FC86BB\ +A7797EA49CEC4C09433946B82962FEEBFBA4DFDEC0BC60B38A9E142C92C0B3906B461D2A\ +AB94321860DF947F584E810D502F84097ACFF6223CF77801C59495ABB52EE88CB775DB7D\ +39D566B9C13DC47127A64A325D7AA12D9B7D63A272B92D2FCA91DF310CC58FFB5CB8B80C\ +F44B5F376AD8D06EB87C262456C10E3091ED47F85F6336F3FCE3BF04C2DB9DC0F622C158\ +0DFB14C9040DE592:\ +F2A1C03F2728F33CC8745FD021011F74D89F8EA351101CDCC26D5B164032E83BC7936562\ +88E124D597BADB78E0A1EE1DA1F2805ACEC4C6F5C45616465735362045C72650E48FE70D\ +8685A2B1F982C059FA7FA04E6FF22AE885BECC2D14F8540884AB6E0C438459E89AC8D4EA\ +C698FC0C516E59ADFE79800C3F49DE880C43E3745F9F3892E9808E24CC65DF92BCFB04EA\ +A60B37D752B73C5DF02EDD4805E5CB14398F2BFC0F15ED5556E653A4FE7643CB609AA7AF\ +839DDBB2772CB327:\ +639366B19DF1C6C56B84341ECF8DC970:874E59C9D25196C8 + +C55BA1C5035F6D543A356D3FAAE8E8227D29F3D5EE065592F980B8424CED3DEE76749570\ +8C0C720FE6EAC681146ADE443AF03055294294F138275D519E3466D698D8B48AC20164D3\ +9587DD97B26C1B6853B5B274183FC73A810F00F3D748B1E96E0E7B10DA3147DD917B314B\ +8DB75EAE7DAE87210D320BF5BB3E1A44A66761F91235BEED601C87EF419A4F18EBA54CD6\ +634454A5BA0675EF68F22A7DE5592D396A9BCC181AE411E9452F9973E4CC612F72F38CC1\ +0659E477E4293A46A4FD65D6:\ +66F3195F85BB50C69719AB217566E65C682D5571AA5A6A964FC013FCD12C0462124980D7\ +C8E423A9848BC784261924A4B76B8D3D56F2B0E5EA6BABED53C45FC11BD34B32C0AD7219\ +77FA61D896275584EA4AE3587101A5CE90DA4B9E874C1EB239FAFC0DA27487ADD0473591\ +5FAD188519B7C0451BE0CD042944F3E1BDA69C4617A6CA98D22A62DC6F1581983EC1A124\ +E76CF2AD611D7697C8EB76259C679917BF3535A1C04F53082003634F09111FA8467512D1\ +D69840BDA1A1A808B8664A85:\ +AF36BB2B821552C3949B694C33A04716:BCBD3B723C5FAF64 + +F8F640858D8A5169CFFE6F222302138E35DADF658FA53F9610C4A115F0460E9F44CF0259\ +AAF63714277B493E94FABD920F22E2585D0A3AE55812751A54D3E194E733FB14C6260677\ +E1D8B46F94B69E31B83F6826A93B6821C3F3CC6B64138650CAC4500447083D66422EA346\ +2D978FAA70A5D6369DE9FF066FCCC8AEAAF7C39705A3432C8F69D67179D92893CA230E8C\ +B0FC559E0CBDFF0AFB3108603C2A9786E2E7F6BD965F1098236D9910BF228FC8733F1687\ +27A209F57E7E4C6AF7EF620BB158C864:\ +4CB818690D084522ADD573C3ADCE75D50A65342D16C2BAB23153503E1D163B17E085EE92\ +80DC5C1D19B041B1D9ADC43D2426FDAD9B11B21CAB5E3AFE0FEC9CF3A9117C47F39066D0\ +041A1B7282E10F2F1791E7EEAC1DE2AC70A1A12BE2C646B2113F41216B5DCF6474B9ED8C\ +3AB2D1BE23A5AB533699D876DFD512661D6B18E9F29376AC0A0B12D7B6B2231EAB5D61E7\ +F7ACDA7503FF8E58E320980E83E877738B749C89C626FE24DF12089B973E50815EDB143F\ +21DFBA48C0B70DA7C1DDC43233AEEE35:\ +1CC4ADA25984BFF53CC86C7364278440:C9CB2BDB19911DBD + +BB97677E03C9259E9096A6B03EDFF049EF942C5FFEADD4C59B8FCC713E2F42BB547D58D9\ +487FACA73248BE2C38DCEDE9310B7844D68F3D0EFE4E1925433476D1618769306A571E2D\ +4768715398CD560B52CC492213F8BE3DBFFFBF35877061BEE5CEF46A8B8D43FAE2E41623\ +F0DED34DFB8DDE42D7492E75F2329CD4C17A8B86D60AEA10A8C68078955004B8CBE4BD80\ +E61FE9B01B9CA83EB5D902819D4A6D8997B75A7F1E86CABF7A5D7C8C44B93B66F8C80D32\ +A7438900740BDC2F7DEDF4B6E729FD5B8A1C8D5F:\ +B20E712CC5B0041E191ADDC5083A6014104E8DC5021B477CAA5AFA6395B7606E68640FB9\ +EF5E208FCF0515575BEA9C49FEB32749FEF89EB579A869DA3213F5DC86A4AE12CB02BAE9\ +D2F45AAD2B5FDFF1FAFC57AF290B70E47CD00648ADA75BC476D7E048DDE9D138133F081E\ +AA0C1475E0D1260AC0184CEAF6F99CDF5140CBBC282009F72272374E946A26BB2F0214C8\ +D7DB0BF7676CC582C8DB8D14048B99F7C99F550A4B6EC89D1B1D4A067591FD411D206878\ +A5F413F0A3E67671F0FE340811D6A77D55B6096D:\ +37910B573950EFE3AD2AC0F3229F34B8:6DC3FCC797E8B292 + +0BDF3471B6A535F918863F7C902519F33BF9A613CD5B265C20A4DA957AE43DABA8185A51\ +2C7215D58CE22B24567A986455AF60FF075232B9E540C6ECBFA71BEF3CBA65B275AA1A74\ +C91396CFEDDB7E39D2EB07C407C070CEB3486AD025295BE09FF74DDE2F1DD062EDBC294C\ +CFF0B0B3DA798E435EC727AA17E1088B6F9E2AE415A19F88A87F38B366EA6F3DD01BB05F\ +D65F73F8F97474EE5985400C25CECCBEA9D4F0118F81264933F6A61C307D148C43853C0A\ +5D93DF6EEF2A2206079850A05E08EA9876BA4F6B202E810A:\ +5D5C57860E0F0AF71142FED28B1FC0CEC703D8746AFDF5F93BC9B80F4D0A358A3B74EAF0\ +E128BD14A14A4F85BCF2FB40ECA5083D60473FFF6396C8C718EA44C5E64091F6C268CEE4\ +33D81B139E0532E7684CE4D2392B32383731C04829916A2B73F9FFB7D4BA1B9BC95E9D5B\ +BA4112FD0ABBF2BB0A3C5CD06FBF52CA87E91EF399E051309230BF61F84CAF9476787B59\ +10EC491855020A2838D19313FCCE4893030988162A8873A559522F1D4FA7BCC82183350F\ +31D0BD8CB4C846C72AACDA246330FD4E869D900004A5D655:\ +31AB675C93F77A7F5FE7A829DACD46E4:9200A442F4CFEA07 + +04DF7F049025BCBD7206B4A12F7E8B599C74A616A91A7B7A10F148DFA5DE56AAD4DA35DC\ +9F7580151EEF0F87FC3E630136AF059FC49AE77AA9809F7019ABC9A409E8EA5801F50671\ +672FB20D5CFB2ACF5B86C7FCA4805AD6864FA0062DBA39CCDB369FC7FC5F19047206A4E0\ +CBA96D0202AEDBBCADF69DFDAB7328FC40DA82491F429AA770E177D775F728FA32AD548E\ +4614162F84FD2EE5B8BEDA5BE1EF85460C4665782F44939DEB7571B6E2598EF78BF0661E\ +5D4E6DA2F493C1D0F2E6073302A19C26F2707BDE2D5A6936CB4F9F6B:\ +1111C0D8F2C9577D3707BC247D460104ADA84F30DFD8A8EDF6478092832F2E35200445B0\ +13BF16A419C6D231A66F34C76C4037C62C377654CACCF9B770F7339CCEA0DACAFF7DFC39\ +3535293E8B347DA29FB207C369853A9E3CD444C67CAECB7AE4DC42B60F3BF0EB2ECEC7A6\ +482F1BB767300C539E8FB9046B31A267D1C9ECBE997EDFEF4B46A0DB501F4FED4F81C99D\ +C15FEF56D4A7ADCAD808F8C6B16A4F62CC0A4C39F57BAEB0914F829E1D4E4B72D93D8167\ +BC3CAC068C327AF3D7C887B65B3400FC4C6E6400326945F7079C6EF5:\ +EB2BC3806990CEC6A01D863E1AA28056:7056216A1187E1C8 + +963524B3D92412DF49F8DF7CA10032FE6C56ABD03866ACCAFA9E45FDBA070FF683A52960\ +6900F1C7ECD437B56A74390858E4D3276DC8DCD04215470C0AC21611D8EC1EA9EF8E5120\ +06D876420F139007ABEE1397247BEB37DC37CD237E3909C75D576D8D37B5FF9F7B078D62\ +79A3B0500F308F991256394F78B7616B28CC6A622A98B43A9531BA25917F6D7BDFCA5FA1\ +9DA4F372AA871C7F253C065A4F923E734740A5534474B5B661164B00605430FD112B197B\ +8570D27A3B44A4C367471FC58F533146305CAE20D15DFD9539FA4C6920F09F73:\ +36FA83EAE79BCF08ED631AFA6C0619ABBC6731051763B61D2EA51B5D859E5069B0FFB480\ +1EFE8DC3EA79D9AAB849B98F0DC180C3A7BE4237A0283372B235553692A926F8C20B9466\ +935B5CF7254496FEE811BE2406563345C16ED4D37A1609683B3216DA5D01CEF1E2C0CC30\ +537AC8A9ADB668C0A8D7DE1EA14AD9619A064B1D9C11B8A224D76ED68838EBCA0D323D80\ +1E293EB2AB9D2F64F3C1B4588CBE074446A0EFE77C5E58F3715691FF50056B047444784C\ +154E230AB3C27A36DA7E61DB7774C9B402536013DF4DA7895E51AF1933A458E1:\ +7FD1AB8DDB8343643C4DB7D90BE1F9C1:F6CD6CE2D5F1DB56 + +C1EA094DE4B8DF3E530F4E75E08DC4793EB744FADB50E94D0C360CA08FD184E5B6E8B685\ +489335C6173CA117F2CF638CDCFF0F0E3329C36125D8780F4589EB76EF76AD722A359C84\ +632865A5ABC386F838EE6DA8E6DD96B6DD53C3AF3EF08315B71E53E442893EAEEF6D0022\ +AFC7D08DAD0DB051CD709608ADF4CE94988476CA95EEDF3CA63328B0EAB1211082655417\ +2E3F2ECE07C25C62992E81985B9B1D9E3186AC83B167D206EA7B180A656BB4A8C5F09DE3\ +9B2ECDBA96E1354706449717BF720E9F756FDF4074FA9F5B3C0016E32B94AAAB9484295E:\ +E66888E7F4A179F83B178AB7409D2C82E014922644F2276D4C308EAEB9A9F42F4062EB1B\ +DB77EDA72C4EE499CD970F1583F284523D375C33D5AFE5264220339604B46FEC19BF61C0\ +E7B07F7B710815801B02A4CAE2BF77F28A0EAAA026D1136580FE1B8AD1B1C40DB1A23FF7\ +878531DFE96B18EFB5CDC34198D23A22F005DD7DFEB91359DBC3BCB1E840A71EBF85DD94\ +663A906C315A1EAEA2E5FD673BB56B23B98D2F54AAF3E82370D75417DAA68C05CDFD15C9\ +592FB9BE87B5C37476A2559E56C4D95834C48ED6B6B0E4661A6F8017A358D0DDC9FF3080:\ +F674FCB74F8175532C3B888AA1F685A1:FD402E1071C463B0 + +47F823E98A8F3DC6E872A177EEEF167E82D23862AD0C28E8C2172EE541F28863A5530EC4\ +2EE5E6462A467BAB8372BE75990369F8FC299C13729CB508332906671E0F8BF40A82E865\ +51E9CA7FEB3E0FCF8BDD5EA5539756802A450D09637978E91A2DD4843DDCCA8C63EDCAD0\ +2B3AA18744FEF1C78D9618686E4B5A84E00069328F1988CE852AC7B17E2DC24280502154\ +D9B1604654CB54EA5E4D069643D6A43D988555AE9CCDF057F896CDB600ECA135406B5115\ +8694ED6C8BCC898E2E4335A9432157D306E12C77059CD3B296FD9C9A225719861D042ED7\ +26BE7302:\ +42300596CBD9EC098AAC697D227058DF9A88051904604063E95C509F9F03869C68AAEC10\ +63701259BD652E9AB275F07BFE164057367A74EED02C72A96B3673ED0510B782E6F4603B\ +ADA717221EDF098D13EFC76A41CF6261D36C64D7B747303B601B3114EA603F9BA42C12C3\ +B89642DF4AE2797569B8798604FCE8BC7906F09310858209A4F678748610DB9DFF24BE79\ +D3D5D41A4F0A449A7EA03628959E5D44B801048BD685A7541D57E9AEFD215D45227276BA\ +6B737908C2AB5066CD3FD555A69729B711ABC683E7236B3D0D82F112888006D30CB1DDC9\ +FD680FDC:\ +68101E5C1C4C16FBD08F90DD040E222A:F2B05714F3B87180 + +1D4C4CF8F819F57243A3CED7F2D8A284AF2588B0C808141A698C1C2C6B7470659344245A\ +D162D527A3E221AC8822668541D10A536B015E8AA35268321144D6D84A199FC147E12028\ +A3DA9171E8705CD65A54210ED4EAE211AB1F864383A2A9AA014E62ED69C60DC32B540126\ +71313B45319CAD64B0B26DDF9AA48E5D0AFBEA3EE2821459CBA5F4FCD798A8647526CF36\ +55E0421EAB46B558B57646C56DF3F6C62B92E8BA3D818811CE7BFF4975AE434B23E095F5\ +942827ECFDE9954C6823FD5198E0002E189C63006914672B08A61012FA7A37A800BCFB3E\ +C845D179DC210044:\ +1B98BAFD01369C2CDB5004819CA0E2075860A4543B1A6564B32F097C382F944436065859\ +9A71C29CE4791683E436DB052DAB361A68D6DBBE3587AB2F6AF60A102B59FB62DE152DCE\ +0737B968750174D95854AF51C95473D17060082051DCEC1766DCEFAEB2B0754D9B95980F\ +143DE1D6676DEB9FD6EEBD01652B4166072974DEB8F26CEE33D918CCCCFB915253797984\ +5E86428145E9225F69BFA8FDFCFFC80CDB0274B48522195CFA77F33328E472FD767B6C3F\ +F39B66CC42363018E38CFE221039EE5065B7A64FEFFAA441B6E87003DF7C60790B9CC46B\ +A6ACC7557609BD9D:\ +CE1972241FA1F27CF1AEE36A51432732:4DEDE955E0196744 + +2089A7FDB2728AEE9D176E603055E77ADBF6861C98A185B642BF02C04DAB8226570F746B\ +66C1AB8271FF590CC51A89E93F9C6108EA593F9135AE64CA62C11E165924C4734332BC34\ +C090E7383E7E1108392CBDC103C4BB847C443F7951F17AF7C610CA07889FFCB27B40AC17\ +F8E0594D6DEB391E3D6132C3998CF6F707CDABC13CB702F7F0E97F266175F0C1282682EC\ +FAC95C8A709CC3092010D48F58DF41DB72E04013C5B5323155CD2D9720E0D40B13BEBB08\ +1F97310FDEE5D00FCD7B5E5C7FEAA2A4FB756916FEFE38DC0025CE7381D83E52DE05B09B\ +1273FE3B16BE372DF94FDA35:\ +7DEC8416E69DCED8D5B6CC3B831307AFC33FECE9A0567DEE0A5999C804CF01FBC19AC1B8\ +555223D3DBE6CA50BB096A7A87ACAB5A5F0ABEB3111E98FBC09897708A18481B51EA78BF\ +E3CCB5AFFBA10F4B980E313E3ABE98EA7E13E38282778514F70D16F7940B6E382AA77BFB\ +4044D6F8EB9D95DA97A142DFC876746FB8338200787D3FA27905E57FCF861BFC8478745C\ +7C2DACC162115E5AFBC80917ABC5358957ECBB65B593010177CB1CE947235A94721541F9\ +0349011188A860D1D23CDD64C3B8D101A87114803690788337CC075B1D37DD21097FC730\ +E528D94FCDD4BE1E9D8FF00F:\ +17192110F1F1B1279CD586D5FAE45F4A:A01800F5D6B63103 + +6AB1E72EE86035D1E1E92B3E79DCE8E72C77E3AE2C4C17A345CE25C373C5B95833DF02C1\ +F34ED2FAC60F6EA77762C8F01AB976DCD2F24BD46136314AFC6F1336032ADCBEB1642A7B\ +46C8CC6B122D67C1EF3E578B6B4AADD9CC655FF37C2D7B5CD3878C32C3D5B0455A2C1DC9\ +FF743EF2ABBEFE2D8214D48413032133D821AB161F300CBEFFF376EEC0051D4A769F5203\ +E87B99DE52EB687EC12D747F2E55B84FF377F88E3F9B72900BD7A8B18E970FFD41BEECE4\ +D1978F25411B7EF8991122C4B4444F1FEB3E88A89E48B3CB721A62EAF0784CA549445852\ +10A91A593E2E3A02063D1F76BA62B997:\ +0D6121F6EC196C1AC20C818918A2F2683877EEE0189D94511CDEB2755D203F75851FBE49\ +8818C6013098FF6200E2262328B8084144CD2782DB5BD5C51E64B3FCC2F2D789B9CE3899\ +29E72BB65A264EB554213AB772140D7BBDAFFC818B2D6D0BF4ECBAD5E984BC17C1E7EB6B\ +1D435B92B2E1C5A8867233DD9534F3898C7F64E1DF8828BB765E382F9E2A46B5FC9C3802\ +2E1E5C7D09E791E187073DDB688921D22172AE4C972B1B6F802D4FD75A997803B9B87E9D\ +F2CBAE978C3E6E1FF18AC8D56CDEA3B9B1E9DAA74EF3FEFB018EBD9902AD4ADDC67BF010\ +0D9335569D6499563010DD12DD3E23C6:\ +190834E408E085E8CC3793E57146FEC8:1DD4835D46E42E15 + +12025BA46EB9326EB77DD3729B51E1A2E845C031B89DA66B8D73C02AD33263522AF4B92C\ +B5CB4BB254057012033B4D8A147AF3DDE90B7951DC0FBAF0C98D4530A367E945D6BA4C54\ +F57E9986A2452AFDDC8D64550823487168529B5D970A6CA0FB5A8B73D4E9576EA334E418\ +75DDB2955C1E81A8DBCFEAFE660C9A594AA169FDC78AB03783738175B4C974E28F8DC593\ +782C9AB44DBD49934C3AFA35E12A8ACE7F02A469B1A7847461D00B85D34BA01858B624B2\ +A50F192DBF4B7ACE9082FB2BD4B9E4C39CA49300FA69D3C1755B839C90184F7BFD322CEC\ +78F8221B0A9BAF3845AFE7447477EE4B1623B384:\ +6BF880E9AC252DA1FD73270B64018ECCEB005CCC89AC7D48B48A5E61F15D21F5524B0057\ +136BB21FBF084BB16B1E5D09C8BF6082AC285120945B63522255C943D137F76804F5B6B5\ +26459E9FA64B3B5CE1B2AEE7BBF621B864F42556E0251FC8829B536F565E929B5C61CB72\ +EEE11961B52A956E4B2D3BA81124952F6FD8B4EAB170544D0ACDD2D97977328549F851E8\ +9EFFDA3057D193189EFA71B60100C4719CF0D83132327828C48E452ED59EF0709F295349\ +E1141B003BC688800C86F3B778A18678403BA35309373967AD8B6F5B225B85D2F0C16C1D\ +5A155023A0010BD0FE1EF31139F18FF8CD9606C5:\ +B7029C1C72337170854CAEE83C38A031:DF167881D0D693C5 + +79E97D129AD18FC0B12C3CB00C872794D8AA7647BD743E507E0A67C0434BC32E58AF6F72\ +0668DC6FBB1CA58A0774F01AD16AD46A83A6A493719DE8D88B709632DD1BE56238F6C95A\ +599CC92B9B84EC18C43E2598C752BB9E2DD1AC58395A8278876AFE7F152F72934B903FD2\ +3BC1F76718A3518DB74DD8CE3E41918E62133B99742A5869450B09854ABA3E9466B7C44C\ +ADF80E126CBA30CD6117755701F6F5FAD161159425B197C4B9804B5A7940627D2A2257CC\ +D7645512002C4C5B09BC0DD4919AE3C96F70FAEEDD4E48CBBFAA2791109F2288B641F3AD\ +145B37EE68EA0CDE249F1669604E8B717A5D247A8BB25AEE:\ +7C5B40D0A68AFF288C04331EE8EDC20CCDC98512858E54C8888DBFD550231D7463F1BC49\ +3C23C9FCB93EE65F025ED0A0F470DA7E15A97B900F64D225B71D7C8CE6511A4B74EB0A7A\ +FE7E4EAD04517198635BEB48FE2C41D6552AD5DD48936CBDFBC9CDFC35248AF5BD85360D\ +D8A3BBF4CA4E87D6E345094CF9AC5725E32736B2AD12C0FDB4E9382372FEB011F6F7D222\ +175A92698D1D74B3795EA05C99DB64FD6E439B5DCF85859CB4D9398072C8843BA1D1F650\ +D5F2E2E2BAF2F1C3A66A10BFA879FFBF6203118771CF893982AA710C67C2347A8ABFD74E\ +B814400C306BB95458FF3EF850DA5E0300A1ED39A1B5611C:\ +F7430DF9CCACB9230AD4BC7AC46B52F0:F9059FC6D69FE7A7 + +57097A044B43E7A3E111EA95D9111CB2B7440A54A834416FE02A4F34C4C8C34741CB340C\ +F66750A9683E23DADFA23320EC4E0A0BBE692A8A2F816863BB078D7FCF6C056D5F2E8169\ +CD639B148A779618C32901CF37B85DEEE483DC0F30B522504070602CF032EB17CC48232F\ +86FECA67B63D06F0B25C717A62676B26DE840AEE70D39432567EA2868ABBE2EFEAED6E41\ +7BB02E0A2E9C30D7FF850503380343838E7EB155E1901547BCE29254F27DD1979C2608AF\ +0EE05696D5F3D3F678FD457AFB048E41CA852129B5D78A619231B60DE4E19B60E2F699CF\ +09E832CE02EB63543C02523C092B34FCFA10BF9BFD9E32766E412A27:\ +BEDB29A971B27E7959B48857AD56DC1FF2776EC258646F26C935928D4B1F0B874F0F34B1\ +6C5E1936D6F5E2263119EA967A9C441F016431059CF8B54CB1AF52A7BBD1D5F9C378E302\ +FB9C9910742D7E5FE8777F2F5D976A569D54CD54F37524A0FB9CB5BF5EA17763171F52D2\ +C823C1E12A99C2196C45FCB1AE3FF170B05D5EBF8EDAD51D7FAB7B6357B84AFFA19DF67A\ +DAE39C964CAA610889E1C79218C38762B7A4B522132D9F9235CCF8F8D810BC9D7EA44C77\ +599DCFD1404EC6BB219D1F1916C0685B23D79E57A280A1D3FF5356F948F15889527C4235\ +8A137CBDAF7ACD8750D5D317F295B821E450C7114279FEFFAB4121A7:\ +500E05FC7472AE721E0B9DF4629EE350:A791B3A28B063D6D + +AF72E9E989D375EF3D4B16E56B025B0B5E3732337894E5E5AA08D9763E905C625B782AF0\ +530E2E3C8BF1D3F336BD13208FC0A1D7F0A8BB91E3FCD7C9E45541C29809C8F7589042CB\ +AF994C56F5F96F10E2140AF452D376B5DBBA2C72542E1E59D63C99E08334ED6A82605737\ +236D4AABBD45A92610AF0C2852B2A63CE0A0C8D1D281D1002C8C37942791684475B10C1B\ +B81E8CC3E7CA9CA1BE881113AEE41857F25E5C6D404F903E93F16BF912D767ED6AD2604A\ +C8AA5937303699168D8B034DE7B15F25DD25002E22E7DF90B636457FD62E83731675E32F\ +6052BF1BEEADC5E65F1B2831A2702B0377816792EE9DFE04BC6410E9C597B633:\ +936EDF889D6629BC65F387545190C03C4AEF91B9A8A13E4E51B02A9DCAFE990CA303DD9F\ +F81EF1C83754657D4C2CD8A89BB5345DD280376FF8996F2204BF1ECADF126D992172CF45\ +2A5999C1CAA455A0AF9EAE12D8B5B8CB4992F215707542625DACB4C460ABE2A97B804ABA\ +14F365C4A99EBB92FE4174A59D74C0D942D75F920E46264D3FB929C60ACE11F4982F6E5C\ +DFC8AE73DCA838021D898E22916333075268A29D8BABC2A78AE5E54BC51791679203B812\ +C4CAC0A4251224C4E509F6677FB140B557665BD85AC3B3EF2D204129A84344654D6AEC97\ +A27C8FBE1D5FBFA272AB20615D2B97A31AD82D92F6457BD8B7A35A98CF8D8384:\ +19740BD949A0AAF7A2908411B588E75D:D0CB88F836751471 + +5C679ED0A8FA89F7763427FCEABFF3640D680E74B633889AF857418D8142B83322A084AA\ +E7521A5DFFF2C8F05A345D05359BFA873E24CE2259F98B9F40615F3CFAE9736629C988BE\ +0949924060A5A85A59BA733FD75F53F991EA3D37D9C53C58C4999F380DE813B73342F427\ +39B169AA3568834F3D3A8AC0912AF8E3F116B602DE32760D5F1A4DBF7F71F783E41A3AD2\ +73E54B76E4A6439C9739210F5A2B5FAE2806AB5811D22B8F5B5CF68E80B2921F2980C285\ +8861A66619CDBE4BA9A3B2F6094C9774B5F9C07D8B99BEE0E4FE02E0082ECD24497236C8\ +621A413E2F3DEE93F38E98DE28B95B621E8DA964C7419AB2DB4FBB5ECF3A9637697D35AF:\ +C5C9D588A11FC4EE03A6C8AC33064C73DCA48BF7C3813EDB9495FE0DEA94FE7F60B5E491\ +E802A06CD0593FB8169230144BED6A76CB353C564DFFEEC8793F28E659127CC9F4C25D33\ +1A0718AA2A91B463A3A686DA4A037C4217EAF907B70916A70229EFF66118D932F1EDAE98\ +7CAF21EA174582ECD8CBEFE7A3CE1F2683B408F56A6855A56BB9C8CA9F8B334F1C9F03D6\ +8D69CF500C0AAA729D0E7D8C40B9199D9A8484EA45F7A483E8052DF531541DD3E354A31D\ +7B2AC271A045A72AF306163DF714438930D6B16D15A1E0132804DF1A94C2CCE769FE37B2\ +0E84E147748653A2F4F6EB228AE7C1AD6BAEEC853F17C1AEF07756C42E2C09AD84538D26:\ +8CBEA7813B209C17DE9441053D8CF013:DB8858BD18B36B06 + +CBCB57CFD5F6E8E9FD5F987FB13C1ED23EDF09C2929F7C01FF6D4B0AE61E4F1B3A5CED6A\ +CBEEDF34831C96B9CAF72C2551BF6011A432DD25540EDD5C75E1018F34846404A912F23F\ +580BFFFFAF8CEB875E7274021B5E2B47F794ADB79699D3D1C6D26E0BF46203C3D4422754\ +6056CC2708224FF3FF9C5463733F41E10804A4F05F8DB4B2FF72B96BB4CF240A2EF2FBDA\ +20E7C91BD7D4E1F7F322533A03F3368A88DD08C36F21EB76CD59AA5C0C3E2537F7283B6D\ +42F6D24B8979246FB8970B6705B755D5EDEE4D7F71DF1595F9953E954D0775DAE56F1840\ +09764B5DF00C136920F887F4D78E8932E671455F98280317FAC41C0F5050E4A1CBB7CE46\ +0FE75EF9:\ +E5F790088393EC494F34AF1B4BE73B63666874BF31D74D64C749A0DD067F6BEC681AA339\ +6CCFFEB2E30572C7F9975727EF566827E98CBA94093499E4F666DF3BE4CECBB861AE5BBA\ +78D67B6686690A5A5069D47B1D3757F6BFD28F734A06F9E37980C574D2975F0A9925CA94\ +88A11926DB59F3B00639DF25C3FEC100688AA640AC67C9788103A9BB85D53E2420AB3374\ +953F00D49217A1AB8883B71D46D361E245C6F0A5F68A6154DD94D8380FA853F6517B7162\ +78F3CE4C75ADBB27B9F774C2FB749DA9FF98E1E52FA2C0B4746502BF360E77B56E623667\ +395A59F4FCC2EFF4D1C2476B014785404F62AC1570C464BB0DBDB3A767A2D8105BEB8955\ +1356289B:\ +281866EA198A1CEAD6E334039B2CA436:F8E76A4A26185CE7 # MARKER: Stream Ciphers @@ -27755,7 +29292,8 @@ BD348966C075CE6B78BA2918258538ED 00000000000000000000000000000000000000:\ 2DD5C3F7BA2B20F76802410C688688895AD8C1BD4\ EA6C9B140FB9B90E21049BF583F527970EBC1:\ -000102030405060708090A0B0C0D0E0F +000102030405060708090A0B0C0D0E0F:\ +0000000000000000 0000000000000000000000000000000000000000000000000000000000000000\ 0000000000000000000000000000000000000000000000000000000000000000\ @@ -27765,7 +29303,8 @@ AE39508EAC9AECE7BF97BB20B9DEE41F87D947F828913598DB72CC232948565E\ 837E0BF37D5D387B2D7102B43BB5D823B04ADF3CECB6D93B9BA752BEC5D45059\ 1514B40E40E653D1839C5BA092296B5E965B1E2FD3ACC192B1413F192FC43BC6\ 95464554E975030844AFE58A811209:\ -1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A +1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A:\ +0000000000000000 # From Crypto++ via Linux kernel 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F\ @@ -28026,7 +29565,8 @@ D2A3318DA4CD57CD133D64FD06CEE6DC0C2443314057F17217E33A636D35CF5D\ 974059DDF73C02F71C7E05BBA90D01B18EC030A95324C989846DAAD0CD91C24D\ 91B089E2BF8344AA287223A0C2ADAD1CFC3F097A0BDCC51B8713C65B598DF2C8\ AFDF1195:\ -000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F +000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F:\ +0000000000000000 [Turing] 0000000000000000000000000000000000000000:\ @@ -29931,6 +31471,2530 @@ D8C1D4BD9C3086F1FDA0ECD33C4FFAFF:72D73FE9 # MARKER: Hash Functions # Hash function format is input:hash +[BMW-512] +:\ +6A725655C42BC8A2A20549DD5A233A6A2BEB01616975851FD122504E604B46AF\ +7D96697D0B6333DB1D1709D6DF328D2A6C786551B0CCE2255E8C7332B4819C0E + +CC:\ +0309CD7A44E6022671E84C43CDB92F613931D1C6B71467C039034B1263C2BF92\ +203E27604BC53FCEA9C2DF3B10862C9B6FB6E8C617754EF49A2B80F51C74ACD3 + +41FB:\ +1FD4AC6551D39EF27B5F1F886D7A3A72EC60E0AE2966649C3701952F29B2DBF8\ +58AB6E18101D038BBF019299C7FE5F62A4BC3973E089EF929AAF25B9A8BB7D39 + +1F877C:\ +8987D458CF27D4C1B1DDD115FE5C15A67AF431561812B1D2028C3AF0A52FB8F7\ +334205CBE003CEAB1446261550870EEA6921C2315D750F9C49AD7877590A9BDE + +C1ECFDFC:\ +5A443348F0B3330CBA5060B16EF21D5597ECDD597603B3E86999099C5595BE38\ +F726D10090472DAF5EA77315B6BA62B2507A7C08A1B6786DCB30148DD1517882 + +21F134AC57:\ +C1ABFEF8AC91FDC20900045A226EA8D5FF2E3E5D0F00CC9194D19F6546075558\ +7F72492E5D5F5A30AE63F95E9DFEE6F07051A8E9856E701451BE1CC58D320E3D + +C6F50BB74E29:\ +B1EC7BD5A91DE2480BEE26C93A84E38030E2B2BC469B7D4A8D91D32CCB889805\ +436739DCB5A14B1D4C0811EE2A0D9A667C0FBA00F48800F39AEBE8D7DA7EDF1C + +119713CC83EEEF:\ +8652D6C03E8B42F46D96E2357DE252C9B4CC483C32ABCADFECED70A07C8E1C8B\ +637A6FA1E278C8BDF651D6FDD8A29A48DAA8ACA71C2277F709A83A80C62C5DA5 + +4A4F202484512526:\ +86E05AB43DEC6C078B18369AC5485B4FAFCA9C55C36E736BFB08E169A2667C67\ +C14A7D0409FC735B18618E84483E1B39DA47A41E48915096A8DEBACA7A148A03 + +1F66AB4185ED9B6375:\ +E072E9D923E334A5C0E129E46D4EE6E5FA2A1494F6CFC4D1498B80470A0B920F\ +2B2D56575A771D8271205D973F23A8DA0FCD3DE5E569269B50B3BD823DC8D955 + +EED7422227613B6F53C9:\ +6D8B04C1DAB6BEACDF7410B9FDBC96E74D9FB11A949DD164C817BDF4ED2DE978\ +B61ADABF27BE4FB8DDFE6B9AADEF8038C217BC56B17C78D19A80922CF84DF8F5 + +EAEED5CDFFD89DECE455F1:\ +66022F69F321D34378271556AD6793DEE887BB6DCD07344CB0C9F9FD8F6C9080\ +F296B99D7D42A6B4242A84889F41894258419CE871D54F21D78AD5BD7FC81A7C + +5BE43C90F22902E4FE8ED2D3:\ +BF48CFBDF5876FF02D095482F4DB28693A3D09B9FCE1DD25BDDB2F80D1100AA8\ +1D166E37421A3281B9F25A981DCD6741272E3F4E596B5003FD86F85C9C31BB92 + +A746273228122F381C3B46E4F1:\ +99F9C27A26186098430839356FD651A6C203E39ADC06EFB3A6C35C3265FE37F7\ +CD3B4EE520218D820F3189B44341EAA6CD753A472A8FDFD7386CB5E3A1D9DBB7 + +3C5871CD619C69A63B540EB5A625:\ +2630080B86DC7DBF5AC325F645B94E0A5FA967913AE02BCE4B762DC03E8DAC4B\ +463A881DEA606FCCD2767F6044040DFACFCB774E19FBDBB8CE89AF937077EC0C + +FA22874BCC068879E8EF11A69F0722:\ +9828CAC020097A5A74E5817EC37034DC0346F07E0CC17AC03E386C7045B6977B\ +9B276EEE6C591E970D0D1F2402515BB63E520C6737B4131BFD114E8D58B4F035 + +52A608AB21CCDD8A4457A57EDE782176:\ +7BE3BD61CECEE09EF1160C1CF7DBCF94F5E1BEE3A30F2B27B0580C3BAC5D2592\ +8291372CE81237B867D4CA09868A0CC7984F2CFA4EF14479761E2EA58FB78BA6 + +82E192E4043DDCD12ECF52969D0F807EED:\ +68A2B3C34D5E023F3BCA7508BB0B5E9BDA5375E245FA394D2CF508A03B48AF97\ +005B3A4DBFFC0D38CA4416ADF504745F94FE9B0D3F5CE334DA9805F1F3ECC978 + +75683DCB556140C522543BB6E9098B21A21E:\ +345692802192594F5516D2B22215DECB648E6611B9A24D159FD2978BF712846F\ +1FCB61F1E5A5AC25832D7E7BBCC0D0FF2E55EC2C9C90EC1E0078697117ADCFAD + +06E4EFE45035E61FAAF4287B4D8D1F12CA97E5:\ +3E3CBB918CF27C6A73D0145CDD3A8F159C56AEF938F69884AC6FC8C3207593FC\ +8D3E712ADFF0CE52FEAB8B693D8933D87DCF8A3F58BE330B4B5DF14EE3D635FA + +E26193989D06568FE688E75540AEA06747D9F851:\ +D1C6A2F12589D77610EC236DB751DCAFEF5A9DFEEA63E307DE01FB4B852DC577\ +6CD59CC6DC2369584B9DDB214BDDF5D5C89D0D1EAC9FB8F7C0F041452CBC11F7 + +D8DC8FDEFBDCE9D44E4CBAFE78447BAE3B5436102A:\ +64659D7B159C8F276DB1295039EB6FE2435405DC1A81BF4575B9C27A2C41208A\ +0BD331F34A60DFF31AD29F8730C0786ABDEE4ABC767092D448CEA3F97C7A6976 + +57085FD7E14216AB102D8317B0CB338A786D5FC32D8F:\ +6CEA91D04E9D4A3C994BE9BB24FEFAF967B4DE36D2566F368C04CC2ED9FAF736\ +DB71170C207F31A7F08B7B8D634E7C38FD591A38948DE4ABE70CC64F3A2EE108 + +A05404DF5DBB57697E2C16FA29DEFAC8AB3560D6126FA0:\ +5B5CDE06BF8B5AE80A67D96306AC7E96AD15575195B269378EA65C6F23DFF53E\ +A4E02639F3EC61D640D3D9B2776DEF2FBB3B8AFA1FCA3AA55BB5208788671770 + +AECBB02759F7433D6FCB06963C74061CD83B5B3FFA6F13C6:\ +0374C843999A2898BD79A0CC8DFB924E7BB9E5CCAECDD151B502C1A234F1D369\ +1F3CE29D0BC6F044A2CCA8174F7537078F3FF0CA73E8CF1D2040D25D1AF3295D + +AAFDC9243D3D4A096558A360CC27C8D862F0BE73DB5E88AA55:\ +7F1E7A420B60E6B42622E4B5E2900D6CF01230C962565A6F7CB8270C8CBCB4E4\ +77D171E183B3C856FCE7369FD25D5E285E21777E3C738090215D97E25ADF1FF6 + +7BC84867F6F9E9FDC3E1046CAE3A52C77ED485860EE260E30B15:\ +52A8179F441682C0CCF7F781C0CB905442ED82CA60ABED14BF032DBC5202CCE9\ +1A66369424DEC0E4C45AC16F156A9AC7982FA4A7AE941B4F24F8DA7A4FEEC4C7 + +FAC523575A99EC48279A7A459E98FF901918A475034327EFB55843:\ +50EC175DC458FB3DED1E3AF7CA87DD6CD08FD89B0BA403EF666E98787D3E38CA\ +48946DB41F38C8FDFB82FD0AA71B08D9069E7136775D22E0583BDA3D8228D3DC + +0F8B2D8FCFD9D68CFFC17CCFB117709B53D26462A3F346FB7C79B85E:\ +47BE44B33C90FD2EC18B839C5A60175EB76DF0A8A587D6EF4A6712868CADBCC5\ +4AC88BE47987F7A4875C16C31B8A6D691939C007B6724139187E76413716F226 + +A963C3E895FF5A0BE4824400518D81412F875FA50521E26E85EAC90C04:\ +E0F91DA11320E76952D42C897503DDF79670C841DFD059AD40F41D9C5BAE0526\ +27887F5EF09A214AB6F2E5425AA1C634C29C533C596B1BE95B1D39EA06335694 + +03A18688B10CC0EDF83ADF0A84808A9718383C4070C6C4F295098699AC2C:\ +0CF4B313265173B60D2F99B87E81E76C10E855A0F67FD5F2D61216CAEF046A86\ +BC2B7E907412C5499A162BD1D019729653F2A80969A534776494A00C8193B8EE + +84FB51B517DF6C5ACCB5D022F8F28DA09B10232D42320FFC32DBECC3835B29:\ +B3483C99D6B488DC2E34F5024BBEE33B55D9A66B7EFE39657748650AC4301BA6\ +DC64A3E3E8C15945575DA963D29399BA0B1AC3A6CECF549E132A5E2DB3B5BBE7 + +9F2FCC7C90DE090D6B87CD7E9718C1EA6CB21118FC2D5DE9F97E5DB6AC1E9C10:\ +DA79A14B066580178121D3F60E0D3370F667A297FD9C0435CF8C65D35BB3B4AA\ +894AF7946F65CCAA5F7D9FC199CBCA9BE3FBFA958C0DABC992A50DB2236ED51C + +DE8F1B3FAA4B7040ED4563C3B8E598253178E87E4D0DF75E4FF2F2DEDD5A0BE0\ +46:\ +4A7873D42769DA269B9869E0DFD5695AE343DBD69FF8A68D93542B5EBBE79480\ +6B2D84ADC69DEAA58F54008164FB3E2AB02577865FBDEA88A8BE7D23EAA9441C + +62F154EC394D0BC757D045C798C8B87A00E0655D0481A7D2D9FB58D93AEDC676\ +B5A0:\ +CF42B5F7ABF540B69018484583A7B1CD1A38064C6E4208CE0ACEE27B7EE74CCE\ +C544FB2FA1921E95B5CACC12546D35C628ECA4C7053F37FD236E63346D474D00 + +B2DCFE9FF19E2B23CE7DA2A4207D3E5EC7C6112A8A22AEC9675A886378E14E5B\ +FBAD4E:\ +9F955DF8BAA1A5ECF0BDFD408002B1EAC93B89C8AEDFABB9E5239D6D1AD1C129\ +9901E96C822BE23207570E1EAE9CB82429899158313AF79FBB06EA3915436F7A + +47F5697AC8C31409C0868827347A613A3562041C633CF1F1F86865A576E02835\ +ED2C2492:\ +0FD1772A21CF32F0D43C00DF44754096704B0DBBC3B323500C3B231C7FC47B8F\ +35E8F10017F4B1061E82E5CC1D823014DCD54AD7F3588614E2149020CD8989B4 + +512A6D292E67ECB2FE486BFE92660953A75484FF4C4F2ECA2B0AF0EDCDD4339C\ +6B2EE4E542:\ +41D2D44C32A90B30ACE1C7F6E4AF5C3DC3ABDB1AC7365262C56CB1AE6DB6B5D4\ +2AD2BCFD9228D9DFFD5664756E326E9E88D053FD3A3D252211463B7171F5CB5C + +973CF2B4DCF0BFA872B41194CB05BB4E16760A1840D8343301802576197EC19E\ +2A1493D8F4FB:\ +4AF72DFCF27B0CDA02F35AAD1A90C67378B63523E80DD50A2AB512F2CFF2969F\ +A48DD8EDDE239F6BD5484D98FB26F0757831D7AFAAB5A21DBADB1C1B5BEA2336 + +80BEEBCD2E3F8A9451D4499961C9731AE667CDC24EA020CE3B9AA4BBC0A7F79E\ +30A934467DA4B0:\ +7161CDE092AE657F61BFA5957B5BADB16712A173EADEA014F622BA0CCF8B4BF9\ +E0E87B92032A5E1EF762FC7B734BD3B2AA526303C7EDE369885CE63DA6DD6DAE + +7ABAA12EC2A7347674E444140AE0FB659D08E1C66DECD8D6EAE925FA451D65F3\ +C0308E29446B8ED3:\ +52E566F481EBA7268B1C9440CCCC29EDFA7E03B4D5BE7689D9E6B9C0E097FC07\ +E378D7F189A144A31A7CA4280B3D566732C3DF2213A534B37D19A1AEFC332E90 + +C88DEE9927679B8AF422ABCBACF283B904FF31E1CAC58C7819809F65D5807D46\ +723B20F67BA610C2B7:\ +CFB6068414E7ABFBA715292306824859C4A8034964CC77C5DB1208FAED6274C3\ +7196850F81071E904BDA8CD1ECE8D66ACAB354EC5802846CA42A217941186AC3 + +01E43FE350FCEC450EC9B102053E6B5D56E09896E0DDD9074FE138E603821027\ +0C834CE6EADC2BB86BF6:\ +7CBE1D832F1530C7527FB3D8BB8F0BF7A2AF523A507EFE68AFDD1DCDE2852DD7\ +89AE87BA2DE8C6CE85AA0D6FD8EB2C4C0DC9E489A1D10105B56D4FFB1260EC0C + +337023370A48B62EE43546F17C4EF2BF8D7ECD1D49F90BAB604B839C2E6E5BD2\ +1540D29BA27AB8E309A4B7:\ +2B4F480C3799B7FF87DC0DBE2DC4348E2D42522EE803D89165002E8810734373\ +7B8605909795397DCA7442CD95799B91EAAB9993641F0578D4C86C7D01F564AD + +6892540F964C8C74BD2DB02C0AD884510CB38AFD4438AF31FC912756F3EFEC6B\ +32B58EBC38FC2A6B913596A8:\ +1556B21828CD8C1F98BFCC63415D4A4F9A916403EE0D65ACAB7AF2280FFA044F\ +5A0B773B7B6210C2D390A17464A791F52398264714FA89F990B03E810155BEF4 + +F5961DFD2B1FFFFDA4FFBF30560C165BFEDAB8CE0BE525845DEB8DC61004B7DB\ +38467205F5DCFB34A2ACFE96C0:\ +C17C6DD9964329D4F1AB10C57967E985A15EDF1DD3DEF79436198459A4D33136\ +7FADE1D20967BF3EAB50A8FBB892F0E71B0BAB981BB1D3EC64EBAB88447A66E9 + +CA061A2EB6CEED8881CE2057172D869D73A1951E63D57261384B80CEB5451E77\ +B06CF0F5A0EA15CA907EE1C27EBA:\ +81B3181C9610CA1EB3359A05329F597A7EFB663B86B413246C0755583B04B0D8\ +B266AD0343AD5813195DBFEDD031AE5CECE6DBA846803CB1C1787B838D66F295 + +1743A77251D69242750C4F1140532CD3C33F9B5CCDF7514E8584D4A5F9FBD730\ +BCF84D0D4726364B9BF95AB251D9BB:\ +48D1EBCCBCEE10E72A9AEE1785A2E97D0612BA7443152514A6F59A232F6D1A17\ +EC4415044A946DF2073FB1B979501B24ECE23C380EA1246C3F09B024C53D83EC + +D8FABA1F5194C4DB5F176FABFFF856924EF627A37CD08CF55608BBA8F1E324D7\ +C7F157298EABC4DCE7D89CE5162499F9:\ +6470A4A9540F4B9DEBBAECF5A95D05AFA9646FAC17B57944602F37740BBC3FA3\ +1C8F1D199013D15D4227209F89C333A493C4D83C8AEB186A9394619EDD1EB8DA + +BE9684BE70340860373C9C482BA517E899FC81BAAA12E5C6D7727975D1D41BA8\ +BEF788CDB5CF4606C9C1C7F61AED59F97D:\ +4446970CCDF75D54F79CCB3881A1ACA24D6CA8DEFBF0C248FD6E477223F2758B\ +9369B8140EE48BD0229B097F514E7A688506A890605C816714279105BEFDF112 + +7E15D2B9EA74CA60F66C8DFAB377D9198B7B16DEB6A1BA0EA3C7EE2042F89D37\ +86E779CF053C77785AA9E692F821F14A7F51:\ +4FEB1F07404D63A06BCDB2BCC319480CA02BEB7981972A092AF5C27001042EF6\ +3500955E57F5C3C54E0E964BD94ABC50BBAAC74F635E522D9ACF6740F26FC4CC + +9A219BE43713BD578015E9FDA66C0F2D83CAC563B776AB9F38F3E4F7EF229CB4\ +43304FBA401EFB2BDBD7ECE939102298651C86:\ +DE3F70F58116EF74466997946469929B5283B0289513AAF1F8DF770AEA21D9E1\ +308A5D1A30CF3912F4351BA6B1ADC4C2B35185C6479E5D160D678EE34BFC6CE5 + +C8F2B693BD0D75EF99CAEBDC22ADF4088A95A3542F637203E283BBC3268780E7\ +87D68D28CC3897452F6A22AA8573CCEBF245972A:\ +89C23F143C74B2A3EA4E1B52765B01CD38725DD432813816CFEDCDEF7090C01D\ +9964DAF8F0EEC99A23B20F1502CC8CB41F77CD35D1E1B1CCFFD96821525705E2 + +EC0F99711016C6A2A07AD80D16427506CE6F441059FD269442BAAA28C6CA037B\ +22EEAC49D5D894C0BF66219F2C08E9D0E8AB21DE52:\ +770FDA46E0435A36A9F4B9E81BB9945CD82F05ECCD6B46DAD48FF92825E2B4F5\ +D21608AE6B945AFAC4650F2408168D3538488FC20A8447FD01EC2DFDF55F8F36 + +0DC45181337CA32A8222FE7A3BF42FC9F89744259CFF653504D6051FE84B1A7F\ +FD20CB47D4696CE212A686BB9BE9A8AB1C697B6D6A33:\ +6FD2A68D85527B6A15F4E7499FF2C6028C74DE9CD2AD0837DFA4FDF64FEC3164\ +6BB89A80125F27D244718C635B5997D7CF014B5ED30A7CC5547C6C24C188B223 + +DE286BA4206E8B005714F80FB1CDFAEBDE91D29F84603E4A3EBC04686F99A46C\ +9E880B96C574825582E8812A26E5A857FFC6579F63742F:\ +0AE21935400D5DEFDB036321F900999BC9AFD61703510168190CC8D36D2BE4F4\ +9DE95C902C286DBAA91F516D231EC4D2AC55425D05FCDEDD211E67A3EFE51E12 + +EEBCC18057252CBF3F9C070F1A73213356D5D4BC19AC2A411EC8CDEEE7A571E2\ +E20EAF61FD0C33A0FFEB297DDB77A97F0A415347DB66BCAF:\ +24DCD83A82A389C7DCBDE997F9F1D0A52A64566699E5D8B8CDBFF0F88A427AAE\ +7C6BBB419F013B8CFC780D47101616BAF0B2C41CFDDD24BAF46610364FC82A03 + +416B5CDC9FE951BD361BD7ABFC120A5054758EBA88FDD68FD84E39D3B09AC254\ +97D36B43CBE7B85A6A3CEBDA8DB4E5549C3EE51BB6FCB6AC1E:\ +DD99BE3D8FB3C4A307E6ADFB18B638904CC12A033D61D1095DDFDC0F6FC62AE5\ +27CC5AF45084D2BE4A416E1BDED2E855650A9CEC6FE618B0856563FA1FDDFF38 + +5C5FAF66F32E0F8311C32E8DA8284A4ED60891A5A7E50FB2956B3CBAA79FC66C\ +A376460E100415401FC2B8518C64502F187EA14BFC9503759705:\ +359D189247A6B503F66FBA5CCE4BEBC7F6551239301BFCC608CFCCF8E9896305\ +5A6E6DD96F6813605B486403BB943A747EDE6C9F8AC586ED6E73DD4D4DC0296E + +7167E1E02BE1A7CA69D788666F823AE4EEF39271F3C26A5CF7CEE05BCA831610\ +66DC2E217B330DF821103799DF6D74810EED363ADC4AB99F36046A:\ +347E5762FA00809092ED5E660E399CF51EA861687AF8AD6D4EA50BE431764442\ +5000D1B33D9F3B05D7A961E2B385C4AF3ED5B5E767E4580C931747E5D3005CC8 + +2FDA311DBBA27321C5329510FAE6948F03210B76D43E7448D1689A063877B6D1\ +4C4F6D0EAA96C150051371F7DD8A4119F7DA5C483CC3E6723C01FB7D:\ +710B3E6D37198D55FE6DF676CF727F982E2B24E38456627D711E18C789AB9D99\ +6276C12F9605A567D1B7FA524296DB2E53D4DAC2F6089874CA099EBBB10E2071 + +95D1474A5AAB5D2422ACA6E481187833A6212BD2D0F91451A67DD786DFC91DFE\ +D51B35F47E1DEB8A8AB4B9CB67B70179CC26F553AE7B569969CE151B8D:\ +9E8D69EEDAEEE8F426D478B39693767D1B28CAC4CB47CD1416C73F82E29EBE06\ +2FBC41AD10A398F4EF4C124A70D96384EC5DBD2BE869DD84C9BA6808BAE6368F + +C71BD7941F41DF044A2927A8FF55B4B467C33D089F0988AA253D294ADDBDB325\ +30C0D4208B10D9959823F0C0F0734684006DF79F7099870F6BF53211A88D:\ +8F109A4B2F65CFC881CB456966630C91EF26E79838CF1E090488B9DC348FAD9F\ +F050197B373BA326AC5F42FD81F3D9C944238918E748453233EC309FA0000670 + +F57C64006D9EA761892E145C99DF1B24640883DA79D9ED5262859DCDA8C3C32E\ +05B03D984F1AB4A230242AB6B78D368DC5AAA1E6D3498D53371E84B0C1D4BA:\ +A94A8BBAAF30DA2D1BC52EFCE0541B8BD109663AD73830261B6179CA31D08CC5\ +ABF512CE3DE1118DE1230B31AFD5A01B5D6A49B370BEEE77A3988F9CBD32618C + +E926AE8B0AF6E53176DBFFCC2A6B88C6BD765F939D3D178A9BDE9EF3AA131C61\ +E31C1E42CDFAF4B4DCDE579A37E150EFBEF5555B4C1CB40439D835A724E2FAE7:\ +548D7A65D8BEEBE56C466DA17F8DD80722A7A2A59352465A150F58C1CDC75E80\ +49F5734EA16F32F5CE5B339CDFD99D930D20A6B8655B6F20DE4E7E7438C405E8 + +16E8B3D8F988E9BB04DE9C96F2627811C973CE4A5296B4772CA3EEFEB80A652B\ +DF21F50DF79F32DB23F9F73D393B2D57D9A0297F7A2F2E79CFDA39FA393DF1AC\ +00:\ +19152CBECBB159ED38D70436671A47CC9373EBC74EBB31FB22E36DD22E0DA921\ +15745AD7B1B0114596F940B6BC90C19EDD53A9AD012BF1F5B6B419FC8A1A6597 + +FC424EEB27C18A11C01F39C555D8B78A805B88DBA1DC2A42ED5E2C0EC737FF68\ +B2456D80EB85E11714FA3F8EABFB906D3C17964CB4F5E76B29C1765DB03D91BE\ +37FC:\ +F08612959457304C50026B146FAED6FEFE60EC27008F986130DE8D487C9BB29F\ +7A6A5F51F5083C6EEDBD2E9DE7A7B7658B8C10AD6F01807B4460FD3B36FC01BC + +ABE3472B54E72734BDBA7D9158736464251C4F21B33FBBC92D7FAC9A35C4E332\ +2FF01D2380CBAA4EF8FB07D21A2128B7B9F5B6D9F34E13F39C7FFC2E72E47888\ +599BA5:\ +436A9BAE3CA9FA4E8627C359D8D2628B0E2C341C75502B3EA80253E5448A6A52\ +4201DFABA2A2B42185DF0F94B06A8074216F057E300E16669A0271AE69B1A54C + +36F9F0A65F2CA498D739B944D6EFF3DA5EBBA57E7D9C41598A2B0E4380F3CF4B\ +479EC2348D015FFE6256273511154AFCF3B4B4BF09D6C4744FDD0F62D75079D4\ +40706B05:\ +BDDEB8D9A990C8B92FFD27D8B0EDA074D9F1DAF0E3FCA1F1D708D7B3922D5FB7\ +A92BD49523F74516CF373ECD835E399EF6E8ACFEB2C7A61166FA3FA9FEE0B5C7 + +ABC87763CAE1CA98BD8C5B82CABA54AC83286F87E9610128AE4DE68AC95DF5E3\ +29C360717BD349F26B872528492CA7C94C2C1E1EF56B74DBB65C2AC351981FDB\ +31D06C77A4:\ +76D74B7AA7C1787F7D2689144A9665416AABBA5B2646EC52C22F7DF5A20C7F6F\ +B2B1FD5C45668EDB0EE468A99567766F594D3E18F1D8162321445EF8F25A3D20 + +94F7CA8E1A54234C6D53CC734BB3D3150C8BA8C5F880EAB8D25FED13793A9701\ +EBE320509286FD8E422E931D99C98DA4DF7E70AE447BAB8CFFD92382D8A77760\ +A259FC4FBD72:\ +2D26A2CA37790EA1ED334F854CB6127F9D6EBBC716341A175B7C6625511974AB\ +1B6ADBC71014F258677089C2BB397F0669C34F686C008706E1DEB560B5D43DEE + +13BD2811F6ED2B6F04FF3895ACEED7BEF8DCD45EB121791BC194A0F806206BFF\ +C3B9281C2B308B1A729CE008119DD3066E9378ACDCC50A98A82E20738800B6CD\ +DBE5FE9694AD6D:\ +B28CF291DB775DEC4E87BD30792BC2CCF1B528F62537176C9206CF255F8B7959\ +10C65E3C308FA2275B021FFD737F88856107BDA44AEB4199EE5675471E789A81 + +1EED9CBA179A009EC2EC5508773DD305477CA117E6D569E66B5F64C6BC64801C\ +E25A8424CE4A26D575B8A6FB10EAD3FD1992EDDDEEC2EBE7150DC98F63ADC323\ +7EF57B91397AA8A7:\ +DABF7F4D5455F3C9505CA6B49CABD8ABD3EE4928CCEF88DC60FAAC08607CD686\ +1C316294D3954AA514672A289182C3FBE49B15051D4645214C5D01A6FC783899 + +BA5B67B5EC3A3FFAE2C19DD8176A2EF75C0CD903725D45C9CB7009A900C0B0CA\ +7A2967A95AE68269A6DBF8466C7B6844A1D608AC661F7EFF00538E323DB5F2C6\ +44B78B2D48DE1A08AA:\ +D4B8A36DE3B40CBCA69B5819C5D4E524E8C36FECAEB8092A5B02FFD12C19A17D\ +EA1B09F1430F1F62EB046CB0F7697233FB51E3EEFEA61CA2C320E97B34BA6ED8 + +0EFA26AC5673167DCACAB860932ED612F65FF49B80FA9AE65465E5542CB62075\ +DF1C5AE54FBA4DB807BE25B070033EFA223BDD5B1D3C94C6E1909C02B620D4B1\ +B3A6C9FED24D70749604:\ +61CD40E83B900F9730DE8BC331EA9F75F81D138992E500082FCFA41610BEEBBB\ +5ACE85FFF570462D9960D17A67A2D2BDC8CAD0D401DD642957386C553310CD42 + +BBFD933D1FD7BF594AC7F435277DC17D8D5A5B8E4D13D96D2F64E771ABBD51A5\ +A8AEA741BECCBDDB177BCEA05243EBD003CFDEAE877CCA4DA94605B67691919D\ +8B033F77D384CA01593C1B:\ +DBE49B8A74C886BA4B5E3E1FBF23274D8122019F7E66C61DB04CF5F61D75340D\ +34811558A575B179F2B45C7C7B60D3FDC1C5D9BB8F6DE53591AB9BC905702157 + +90078999FD3C35B8AFBF4066CBDE335891365F0FC75C1286CDD88FA51FAB94F9\ +B8DEF7C9AC582A5DBCD95817AFB7D1B48F63704E19C2BAA4DF347F48D4A6D603\ +013C23F1E9611D595EBAC37C:\ +826E66301DC5F89FA5559170A9AE0E07B1DCE27A5EB90029DC4E7C9A2F005D25\ +EE319DBD74A0F2D3034027ED03566F2D6D768A4F4BF88BF208AED0AD623D339E + +64105ECA863515C20E7CFBAA0A0B8809046164F374D691CDBD6508AAABC1819F\ +9AC84B52BAFC1B0FE7CDDBC554B608C01C8904C669D8DB316A0953A4C68ECE32\ +4EC5A49FFDB59A1BD6A292AA0E:\ +70FFCA06DC5C2ECC63E938915A70755843AE11990C4285FF4448D5DECCF9CF00\ +4C04774B6419E80D5E96CACF830F16595C995F37F629D4C82D7D5837AF28E6FA + +D4654BE288B9F3B711C2D02015978A8CC57471D5680A092AA534F7372C71CEAA\ +B725A383C4FCF4D8DEAA57FCA3CE056F312961ECCF9B86F14981BA5BED6AB5B4\ +498E1F6C82C6CAE6FC14845B3C8A:\ +E5C313F54B334BAB5746161EDBEA426AB1EE8FB01521C0BBE3B10B41F88498C0\ +A53D14D4F0951C0BEF8110ED3DBB4FE93CF0C538E7B4FC04D9D87FF98B690736 + +12D9394888305AC96E65F2BF0E1B18C29C90FE9D714DD59F651F52B88B3008C5\ +88435548066EA2FC4C101118C91F32556224A540DE6EFDDBCA296EF1FB00341F\ +5B01FECFC146BDB251B3BDAD556CD2:\ +40A3015076E0BD34B7A5EDDABE5C948A93C0C62C84470CD24EA4B624CADDB37A\ +FF2A9C654988231085A216F619697175F5AA2B6211C9E32D0FF4253EA95FD7D5 + +871A0D7A5F36C3DA1DFCE57ACD8AB8487C274FAD336BC137EBD6FF4658B547C1\ +DCFAB65F037AA58F35EF16AFF4ABE77BA61F65826F7BE681B5B6D5A1EA8085E2\ +AE9CD5CF0991878A311B549A6D6AF230:\ +F69BD0F7B6AEF0BA7FCA622865756298B881A4E747090C77F48B5BE74BA70DB2\ +2BDFAA758FF43698CA821472A121D46B3CDCFC62D139243B757A9456660843B4 + +E90B4FFEF4D457BC7711FF4AA72231CA25AF6B2E206F8BF859D8758B89A7CD36\ +105DB2538D06DA83BAD5F663BA11A5F6F61F236FD5F8D53C5E89F183A3CEC615\ +B50C7C681E773D109FF7491B5CC22296C5:\ +7DC20435E62DEA8C32FA4D6F90D16D711F4E43A14D74FA29F648EC2D0F0FD22E\ +10BF36220A639AC67AA2F5DFA0454565C9AF02A90F97F0202A1EBBEFB5859A1F + +E728DE62D75856500C4C77A428612CD804F30C3F10D36FB219C5CA0AA30726AB\ +190E5F3F279E0733D77E7267C17BE27D21650A9A4D1E32F649627638DBADA970\ +2C7CA303269ED14014B2F3CF8B894EAC8554:\ +9C7CFFFBFFE1E8783080510B7F9F11E04B3F9C5A6D17F5ACA02E07650347C352\ +A3CC60096FBCF21055385B0BA1EB3C6E4282690BFB32413FD55DE09E06403BE9 + +6348F229E7B1DF3B770C77544E5166E081850FA1C6C88169DB74C76E42EB983F\ +ACB276AD6A0D1FA7B50D3E3B6FCD799EC97470920A7ABED47D288FF883E24CA2\ +1C7F8016B93BB9B9E078BDB9703D2B781B616E:\ +A0E94AEB83183E924DEA9C94DE5F76EBDED8FB2D344C3CDF46FA8D738FF331EF\ +1061F96FD3D5D1F75EB95525B8388F4AB481D5BF9A48B9DE8E5DDE2F6C0B526B + +4B127FDE5DE733A1680C2790363627E63AC8A3F1B4707D982CAEA258655D9BF1\ +8F89AFE54127482BA01E08845594B671306A025C9A5C5B6F93B0A39522DC8774\ +37BE5C2436CBF300CE7AB6747934FCFC30AEAAF6:\ +FAC419F422D0A0C09653EB9938D6FEDA794CFE6162FEA02D35AD0C53F70CDFBF\ +5D60C4D33A5FAE394AC6938371A088977413172BC2284EA3C78623508726508C + +08461F006CFF4CC64B752C957287E5A0FAABC05C9BFF89D23FD902D324C79903\ +B48FCB8F8F4B01F3E4DDB483593D25F000386698F5ADE7FAADE9615FDC50D327\ +85EA51D49894E45BAA3DC707E224688C6408B68B11:\ +3722EE99604E8C8C7069FB1CC07B67F9DB082BE5BA359AC8FBBA285FFCC00204\ +39F96DFAD898124A779E758D3E8D28A41F3B59990C027F6E88D1FAD75112779D + +68C8F8849B120E6E0C9969A5866AF591A829B92F33CD9A4A3196957A148C4913\ +8E1E2F5C7619A6D5EDEBE995ACD81EC8BB9C7B9CFCA678D081EA9E25A75D39DB\ +04E18D475920CE828B94E72241F24DB72546B352A0E4:\ +BC30D45D62D909FC5ACD1B87B9C70065228D2722A360A1D25F726A8469F725FC\ +163496C39E7D31AA2B3BD9016A2253D7CD05E4D678A35358847090A778D8CF8D + +B8D56472954E31FB54E28FCA743F84D8DC34891CB564C64B08F7B71636DEBD64\ +CA1EDBDBA7FC5C3E40049CE982BBA8C7E0703034E331384695E9DE76B5104F2F\ +BC4535ECBEEBC33BC27F29F18F6F27E8023B0FBB6F563C:\ +E1DF1CF42A685BAD183FE9E7C3A21DF52826174DB659CA114E8EAE39569E5B20\ +EACF33A97ED436207F95568248FFBF922833A1D7153785FD869BAFC494ED82B1 + +0D58AC665FA84342E60CEFEE31B1A4EACDB092F122DFC68309077AED1F3E528F\ +578859EE9E4CEFB4A728E946324927B675CD4F4AC84F64DB3DACFE850C1DD187\ +44C74CECCD9FE4DC214085108F404EAB6D8F452B5442A47D:\ +B986BEA853B9CA92ED1F11D2205CDD09ACD3DD7DD4A4F48ADB1892F9B0296AB3\ +99B4CEDD69A6EC8C1E8E4FB30FD3040EB7057CDD3C0104EA910875196F93C53D + +1755E2D2E5D1C1B0156456B539753FF416651D44698E87002DCF61DCFA2B4E72\ +F264D9AD591DF1FDEE7B41B2EB00283C5AEBB3411323B672EAA145C512518510\ +4F20F335804B02325B6DEA65603F349F4D5D8B782DD3469CCD:\ +4DCE35639B8F219455E77AB4E0B99A94CB2DE19842D9213F11552EE9DD7A57E8\ +54EEB7E91F7E13152F757068E40105BB355306B3F16540991B11D215C02E8B80 + +B180DE1A611111EE7584BA2C4B020598CD574AC77E404E853D15A101C6F5A2E5\ +C801D7D85DC95286A1804C870BB9F00FD4DCB03AA8328275158819DCAD7253F3\ +E3D237AEAA7979268A5DB1C6CE08A9EC7C2579783C8AFC1F91A7:\ +E71B2170F0F3761D1FFF4C20A01374886E483724954F5F683120E4CDE589011C\ +7EAF775F3E0CD93953513DC0A119412E12611757F3BA846A33545FD257E5591B + +CF3583CBDFD4CBC17063B1E7D90B02F0E6E2EE05F99D77E24E560392535E47E0\ +5077157F96813544A17046914F9EFB64762A23CF7A49FE52A0A4C01C630CFE87\ +27B81FB99A89FF7CC11DCA5173057E0417B8FE7A9EFBA6D95C555F:\ +29036EEE2CFF84925CE84157EC3B90EDE0A434B52AD89C0F91E84D0F2CFD0357\ +1F610E18829B9B69984BB57FA055DE6288F43C33A9A19CF71B4045195B2908AD + +072FC02340EF99115BAD72F92C01E4C093B9599F6CFC45CB380EE686CB5EB019\ +E806AB9BD55E634AB10AA62A9510CC0672CD3EDDB589C7DF2B67FCD3329F61B1\ +A4441ECA87A33C8F55DA4FBBAD5CF2B2527B8E983BB31A2FADEC7523:\ +06E45A1A77F1CA437BB4554E9AC2791C74D7C3E7202D94C64C6ACF258FF7217A\ +46A8FCC49C6C9E56B53ADE741FA30060E35E365FFC9CD7BD3AEA92D011924D7E + +76EECF956A52649F877528146DE33DF249CD800E21830F65E90F0F25CA9D6540\ +FDE40603230ECA6760F1139C7F268DEBA2060631EEA92B1FFF05F93FD5572FBE\ +29579ECD48BC3A8D6C2EB4A6B26E38D6C5FBF2C08044AEEA470A8F2F26:\ +3A08CE7F48E71FB89CA12701C6BFB6D6ACBC3847351E0C4840CEC0FEEF141B69\ +A7780128837FA082E6803FCAC832DD57E5E8AA776B058ED5062AAEE0D3B10EA2 + +7ADC0B6693E61C269F278E6944A5A2D8300981E40022F839AC644387BFAC9086\ +650085C2CDC585FEA47B9D2E52D65A2B29A7DC370401EF5D60DD0D21F9E2B90F\ +AE919319B14B8C5565B0423CEFB827D5F1203302A9D01523498A4DB10374:\ +797015514DF48346879712ED2AD3BE484DB7F19B94DD8A4A77DA987287298674\ +F68E331432B15CFA0CEB395E40E2BD424B850293CD3BEE39B6F042B58469FE54 + +E1FFFA9826CCE8B86BCCEFB8794E48C46CDF372013F782ECED1E378269B7BE2B\ +7BF51374092261AE120E822BE685F2E7A83664BCFBE38FE8633F24E633FFE198\ +8E1BC5ACF59A587079A57A910BDA60060E85B5F5B6F776F0529639D9CCE4BD:\ +8930CF8606BF372E0F355E6036146EA14AC2F0605B2C192CCF3E60DEE5DD95C7\ +730581274AAF4DF61438051FF8A566B0A537E1ED13FF250F11EFD7F3257F9F60 + +69F9ABBA65592EE01DB4DCE52DBAB90B08FC04193602792EE4DAA263033D5908\ +1587B09BBE49D0B49C9825D22840B2FF5D9C5155F975F8F2C2E7A90C75D2E4A8\ +040FE39F63BBAFB403D9E28CC3B86E04E394A9C9E8065BD3C85FA9F0C7891600:\ +375AD74C0E39D401D4022174A5FA4363447C85D72ECCF1D380845149240DFD32\ +09F81E4AF263F429B8FB6116062880152AD9E40F01EC23B61E390EAB9AE3F502 + +38A10A352CA5AEDFA8E19C64787D8E9C3A75DBF3B8674BFAB29B5DBFC15A63D1\ +0FAE66CD1A6E6D2452D557967EAAD89A4C98449787B0B3164CA5B717A93F24EB\ +0B506CEB70CBBCB8D72B2A72993F909AAD92F044E0B5A2C9AC9CB16A0CA2F81F\ +49:\ +B0DD4E0619AAD0B8C44B30D106A0A57B8C10172520E072865B6CF5B12CFCA23A\ +F742AE9FE222C5D900C84BCE529C87F93BE4264331A7EDF7A1C0071F2265B1F5 + +6D8C6E449BC13634F115749C248C17CD148B72157A2C37BF8969EA83B4D6BA8C\ +0EE2711C28EE11495F43049596520CE436004B026B6C1F7292B9C436B055CBB7\ +2D530D860D1276A1502A5140E3C3F54A93663E4D20EDEC32D284E25564F62495\ +5B52:\ +4F70DF19FFAA4650A834B1BF154B61F077C76467F2EB38B3A60E26D82702294C\ +7E91611C63522D62B1EF007981516018833F9C7030BDA0A3661373F4739C8E94 + +6EFCBCAF451C129DBE00B9CEF0C3749D3EE9D41C7BD500ADE40CDC65DEDBBBAD\ +B885A5B14B32A0C0D087825201E303288A733842FA7E599C0C514E078F05C821\ +C7A4498B01C40032E9F1872A1C925FA17CE253E8935E4C3C71282242CB716B20\ +89CCC1:\ +24B8C31CA0EA5A1C627BBAEE4BA822323AC4198415FB69D99B90B26DAF42520E\ +6B489F05F9C48AF52BB7E11FC4D72C37CBFAA04433559EFC388CE9C83008C9F6 + +433C5303131624C0021D868A30825475E8D0BD3052A022180398F4CA4423B982\ +14B6BEAAC21C8807A2C33F8C93BD42B092CC1B06CEDF3224D5ED1EC29784444F\ +22E08A55AA58542B524B02CD3D5D5F6907AFE71C5D7462224A3F9D9E53E7E084\ +6DCBB4CE:\ +E1573F9C0D6D49D8A1D6B29663DB387A1EBB5F107C37A4E6330673B1A23DF7D1\ +B1475E14EA001319D683CD902CABA8E33B90A10FB7F1C5468E9A4FDBC7BFD2E1 + +A873E0C67CA639026B6683008F7AA6324D4979550E9BCE064CA1E1FB97A30B14\ +7A24F3F666C0A72D71348EDE701CF2D17E2253C34D1EC3B647DBCEF2F879F4EB\ +881C4830B791378C901EB725EA5C172316C6D606E0AF7DF4DF7F76E490CD30B2\ +BADF45685F:\ +669CAA7CE8599AF49B6AA8963FF4C19E43247953E0EAA7453EB954217AB9CA86\ +A82245E4C0916F7E9631F763A12B8EF516E5AB33DAC41D8FEB1F88B8778BF185 + +006917B64F9DCDF1D2D87C8A6173B64F6587168E80FAA80F82D84F60301E561E\ +312D9FBCE62F39A6FB476E01E925F26BCC91DE621449BE6504C504830AAE3940\ +96C8FC7694651051365D4EE9070101EC9B68086F2EA8F8AB7B811EA8AD934D5C\ +9B62C60A4771:\ +B0D673B7F25D73616323175F04CD969285914F163CDD0513CC97350C4BC50574\ +228BF1271026013A82260281554EAF29471F4CE3CC4472AA8030A6CF20982C32 + +F13C972C52CB3CC4A4DF28C97F2DF11CE089B815466BE88863243EB318C2ADB1\ +A417CB1041308598541720197B9B1CB5BA2318BD5574D1DF2174AF14884149BA\ +9B2F446D609DF240CE335599957B8EC80876D9A085AE084907BC5961B20BF5F6\ +CA58D5DAB38ADB:\ +61FE4777C89455B9FA259F9F8DEA012CBE1DC51538C54E77CE7D95EAC48E73F9\ +00B77B51B00018A6AF84C407877EE9B0DC3FF5788638A52AC8B150E823416640 + +E35780EB9799AD4C77535D4DDB683CF33EF367715327CF4C4A58ED9CBDCDD486\ +F669F80189D549A9364FA82A51A52654EC721BB3AAB95DCEB4A86A6AFA93826D\ +B923517E928F33E3FBA850D45660EF83B9876ACCAFA2A9987A254B137C6E140A\ +21691E1069413848:\ +2227BF50BD45C41592EB42EDAB9FEE3E78DD0FCF0497BFA733B99D9B5699D3A2\ +7932F4F81F7D4AF43A23E94CA7A9A88D82C2781602EF5E1ECF4712CE6F72E8F4 + +64EC021C9585E01FFE6D31BB50D44C79B6993D72678163DB474947A053674619\ +D158016ADB243F5C8D50AA92F50AB36E579FF2DABB780A2B529370DAA299207C\ +FBCDD3A9A25006D19C4F1FE33E4B1EAEC315D8C6EE1E730623FD1941875B924E\ +B57D6D0C2EDC4E78D6:\ +67F82DCA717D47E9E0854BEDC55A1756CD624F58DF755CF9702DE5CD73B57F6A\ +EF7BBF40922A915F383D7D3A910FF95936EC74E35B3B2AA6146F30E11AF3725B + +5954BAB512CF327D66B5D9F296180080402624AD7628506B555EEA8382562324\ +CF452FBA4A2130DE3E165D11831A270D9CB97CE8C2D32A96F50D71600BB4CA26\ +8CF98E90D6496B0A6619A5A8C63DB6D8A0634DFC6C7EC8EA9C006B6C456F1B20\ +CD19E781AF20454AC880:\ +83665C2BCA49C95BBE584DF52242068193F7A9DAAA67B0EE36FA9A81516E4CD6\ +A3D15A222F95A2DDB7494C5DBB7E83EB30A72BA342DC98060D1F78B9C8F0E893 + +03D9F92B2C565709A568724A0AFF90F8F347F43B02338F94A03ED32E6F33666F\ +F5802DA4C81BDCE0D0E86C04AFD4EDC2FC8B4141C2975B6F07639B1994C973D9\ +A9AFCE3D9D365862003498513BFA166D2629E314D97441667B007414E739D7FE\ +BF0FE3C32C17AA188A8683:\ +C505A3841C5589D0B2A428D684C9D14520C6359A5AAED6A560663947899E42B5\ +88D5D7BE55D580931B25AC2E2FC5F3AF360D60741C0BA82D5A94BE61D2CCC830 + +F31E8B4F9E0621D531D22A380BE5D9ABD56FAEC53CBD39B1FAB230EA67184440\ +E5B1D15457BD25F56204FA917FA48E669016CB48C1FFC1E1E45274B3B47379E0\ +0A43843CF8601A5551411EC12503E5AAC43D8676A1B2297EC7A0800DBFEE0429\ +2E937F21C005F17411473041:\ +EB6FD4B2B90F79F0071C8D2744C352DBDC7807D40EAF5979DBF21410CEFC2CA2\ +B867010A213C34090E3AFD0C8EA65F43D1AC48EAB67721AF5508D6F193031611 + +758EA3FEA738973DB0B8BE7E599BBEF4519373D6E6DCD7195EA885FC991D8967\ +62992759C2A09002912FB08E0CB5B76F49162AEB8CF87B172CF3AD190253DF61\ +2F77B1F0C532E3B5FC99C2D31F8F65011695A087A35EE4EEE5E334C369D8EE5D\ +29F695815D866DA99DF3F79403:\ +FF96DEEADD3C3668F9C9FCF23EABB6C08A908D89B997ED4005FDB4ADDFDBC165\ +D47CBDC2A9A064D95BEDDEDFE1F5AE0D7A05EED7D1B30D3DC1D3AC8850425575 + +47C6E0C2B74948465921868804F0F7BD50DD323583DC784F998A93CD1CA4C6EF\ +84D41DC81C2C40F34B5BEE6A93867B3BDBA0052C5F59E6F3657918C382E771D3\ +3109122CC8BB0E1E53C4E3D13B43CE44970F5E0C079D2AD7D7A3549CD75760C2\ +1BB15B447589E86E8D76B1E9CED2:\ +E0269128AD1687BB7C35926E98CC9A9C7670C1276C3F10C37853928AA6C0AE7F\ +E414D379FCBAE20DF0161781690053B9322D8AD14D66C1A4B7B35FFFF9CF3F16 + +F690A132AB46B28EDFA6479283D6444E371C6459108AFD9C35DBD235E0B6B6FF\ +4C4EA58E7554BD002460433B2164CA51E868F7947D7D7A0D792E4ABF0BE5F450\ +853CC40D85485B2B8857EA31B5EA6E4CCFA2F3A7EF3380066D7D8979FDAC618A\ +AD3D7E886DEA4F005AE4AD05E5065F:\ +CA5FA777561C6C13ECBCAD526527343009BB1EB77B4BCE263FC24E00A5A5FB92\ +96D2BA13598A646BF936397E43A7BF9D303CAE83E3654CC25F636F7FAB03C2B1 + +58D6A99BC6458824B256916770A8417040721CCCFD4B79EACD8B65A3767CE5BA\ +7E74104C985AC56B8CC9AEBD16FEBD4CDA5ADB130B0FF2329CC8D611EB14DAC2\ +68A2F9E633C99DE33997FEA41C52A7C5E1317D5B5DAED35EBA7D5A60E45D1FA7\ +EAABC35F5C2B0A0F2379231953322C4E:\ +FBCAE8C494C5FD0ADB640CEB4A15BF634293EC37CCF119AFF5BEC95F55578ED9\ +0D26861A045E0F242302158D3EAC801185498D6D8033662F2E0E6BA5B6F04ACE + +BEFAB574396D7F8B6705E2D5B58B2C1C820BB24E3F4BAE3E8FBCD36DBF734EE1\ +4E5D6AB972AEDD3540235466E825850EE4C512EA9795ABFD33F330D9FD7F79E6\ +2BBB63A6EA85DE15BEAEEA6F8D204A28956059E2632D11861DFB0E65BC07AC8A\ +159388D5C3277E227286F65FF5E5B5AEC1:\ +28500180D6F48671A4ACD83C9BB5FE3665CF9A6163D8797A2A2F9EA3974619B3\ +12769F67C1BB279A409C05A6B4E371F57FC658096923B5EB086D920EE8C748E8 + +8E58144FA9179D686478622CE450C748260C95D1BA43B8F9B59ABECA8D93488D\ +A73463EF40198B4D16FB0B0707201347E0506FF19D01BEA0F42B8AF9E71A1F1B\ +D168781069D4D338FDEF00BF419FBB003031DF671F4A37979564F69282DE9C65\ +407847DD0DA505AB1641C02DEA4F0D834986:\ +B205C2E223BF2A741F35294E9B7E1C33EF745A31F5CE2A00F6EC43B05044034C\ +4993D5112E4BA7CEB2BDA4C2E2C8E09B52CE6C2AC7B5374260BFEED8752B65C1 + +B55C10EAE0EC684C16D13463F29291BF26C82E2FA0422A99C71DB4AF14DD9C7F\ +33EDA52FD73D017CC0F2DBE734D831F0D820D06D5F89DACC485739144F8CFD47\ +99223B1AFF9031A105CB6A029BA71E6E5867D85A554991C38DF3C9EF8C1E1E9A\ +7630BE61CAABCA69280C399C1FB7A12D12AEFC:\ +38FA9FFE97CA84452F56C26702F561BBB105D1AE19D78C3528132DAA809B006E\ +E2359EFE54EB35FE0760699070D2B33B2401A5C12132797DF0BDAF96A8DDB04A + +2EEEA693F585F4ED6F6F8865BBAE47A6908AECD7C429E4BEC4F0DE1D0CA0183F\ +A201A0CB14A529B7D7AC0E6FF6607A3243EE9FB11BCF3E2304FE75FFCDDD6C5C\ +2E2A4CD45F63C962D010645058D36571404A6D2B4F44755434D76998E83409C3\ +205AA1615DB44057DB991231D2CB42624574F545:\ +F5D3FCDDF5C8E2E0513700B11775B0B3C73CD16B18AE52BD3ED225306EE9B5E6\ +B5E402334BC5A4FD1AF5D47138D44217DABF5CBDFFD6978B956EED71C21E05CF + +DAB11DC0B047DB0420A585F56C42D93175562852428499F66A0DB811FCDDDAB2\ +F7CDFFED1543E5FB72110B64686BC7B6887A538AD44C050F1E42631BC4EC8A9F\ +2A047163D822A38989EE4AAB01B4C1F161B062D873B1CFA388FD301514F62224\ +157B9BEF423C7783B7AAC8D30D65CD1BBA8D689C2D:\ +1A25D0833B2CC0A1A0D7C892639D0DF281D10334860F70878287DD4015A3F731\ +2093AEF197D49A1BE99F1615EA38D52A5F3665AA87BF20E89DD7A04E3DC09CA7 + +42E99A2F80AEE0E001279A2434F731E01D34A44B1A8101726921C0590C30F312\ +0EB83059F325E894A5AC959DCA71CE2214799916424E859D27D789437B9D2724\ +0BF8C35ADBAFCECC322B48AA205B293962D858652ABACBD588BCF6CBC388D099\ +3BD622F96ED54614C25B6A9AA527589EAAFFCF17DDF7:\ +0942326FEECAAD788EEB7D50863FD9280211C9F63B16ECD51AC874A80B47988D\ +61799A10D3B23DC23AE26C179ED5EBC9E32B7697B0566079852BBFA5FA21FFAC + +3C9B46450C0F2CAE8E3823F8BDB4277F31B744CE2EB17054BDDC6DFF36AF7F49\ +FB8A2320CC3BDF8E0A2EA29AD3A55DE1165D219ADEDDB5175253E2D1489E9B6F\ +DD02E2C3D3A4B54D60E3A47334C37913C5695378A669E9B72DEC32AF5434F93F\ +46176EBF044C4784467C700470D0C0B40C8A088C815816:\ +E9F908BC91CE95ABBA48644FC7C1F8E211E3D2EEA459021FF7E4496C6F1AA3EC\ +A73AEF2813B33819139CEB6ADD5FCFB4EBEBCE72AA1E30DC328454CA69FFBF31 + +D1E654B77CB155F5C77971A64DF9E5D34C26A3CAD6C7F6B300D39DEB19100946\ +91ADAA095BE4BA5D86690A976428635D5526F3E946F7DC3BD4DBC78999E65344\ +1187A81F9ADCD5A3C5F254BC8256B0158F54673DCC1232F6E918EBFC6C51CE67\ +EAEB042D9F57EEC4BFE910E169AF78B3DE48D137DF4F2840:\ +5CEEE2800816DDF676BBD3C8B7D95012808E62A1838CD292893B05085DD08B95\ +EA245FB84283BEF479FD0E2B8BF9DD1BA722344E83DC391A85AEE2C930F985C5 + +626F68C18A69A6590159A9C46BE03D5965698F2DAC3DE779B878B3D9C421E0F2\ +1B955A16C715C1EC1E22CE3EB645B8B4F263F60660EA3028981EEBD6C8C3A367\ +285B691C8EE56944A7CD1217997E1D9C21620B536BDBD5DE8925FF71DEC6FBC0\ +6624AB6B21E329813DE90D1E572DFB89A18120C3F606355D25:\ +ED0C620D495F5190D8667F0F9B50C9FEA28FC01AE9B219027973A341BA87118A\ +821451D5EEE580C4FAEE46DAD21C43C72523AE86A8579576247EB8E38D0C6BA6 + +651A6FB3C4B80C7C68C6011675E6094EB56ABF5FC3057324EBC6477825061F9F\ +27E7A94633ABD1FA598A746E4A577CAF524C52EC1788471F92B8C37F23795CA1\ +9D559D446CAB16CBCDCE90B79FA1026CEE77BF4AB1B503C5B94C2256AD75B3EA\ +C6FD5DCB96ACA4B03A834BFB4E9AF988CECBF2AE597CB9097940:\ +138F2DF9686F705E5C55020B89F04AB66654B0CACCC1A8D374334B6BF6534335\ +C7514206B6F772DDB0550CFABA22D22B913928D3ADF78BFD25DF9DD517B2E3A3 + +8AAF072FCE8A2D96BC10B3C91C809EE93072FB205CA7F10ABD82ECD82CF040B1\ +BC49EA13D1857815C0E99781DE3ADBB5443CE1C897E55188CEAF221AA9681638\ +DE05AE1B322938F46BCE51543B57ECDB4C266272259D1798DE13BE90E10EFEC2\ +D07484D9B21A3870E2AA9E06C21AA2D0C9CF420080A80A91DEE16F:\ +3348F4E8C4768C3EF687A8E2A02E307FD8591B41235F8C14E5983AE7361968D0\ +CB877AF488B975001AA1E7ACF0E5844C107A102BF028FCEE89CFE751266D88A3 + +53F918FD00B1701BD504F8CDEA803ACCA21AC18C564AB90C2A17DA592C7D6968\ +8F6580575395551E8CD33E0FEF08CA6ED4588D4D140B3E44C032355DF1C53156\ +4D7F4835753344345A6781E11CD5E095B73DF5F82C8AE3AD00877936896671E9\ +47CC52E2B29DCD463D90A0C9929128DA222B5A211450BBC0E02448E2:\ +CA7257AC51700539DF617C3B7EE9ACC7C4576332996F905D9D3733F1AAF3287E\ +2F852BE394E533F64EA19733276B0E448496F88500770675835E133904E4071B + +A64599B8A61B5CCEC9E67AED69447459C8DA3D1EC6C7C7C82A7428B9B584FA67\ +E90F68E2C00FBBED4613666E5168DA4A16F395F7A3C3832B3B134BFC9CBAA95D\ +2A0FE252F44AC6681EB6D40AB91C1D0282FED6701C57463D3C5F2BB8C6A7301F\ +B4576AA3B5F15510DB8956FF77478C26A7C09BEA7B398CFC83503F538E:\ +ADB3B6E2083CB37ED5F822D1AA2ADA18560C663011CB16CFB804A5F24C0525F3\ +4D8CB10D19528BA02BB43BD501BF0D0AC67968B0687DCB21C013527A99AE9D84 + +0E3AB0E054739B00CDB6A87BD12CAE024B54CB5E550E6C425360C2E87E59401F\ +5EC24EF0314855F0F56C47695D56A7FB1417693AF2A1ED5291F2FEE95F75EED5\ +4A1B1C2E81226FBFF6F63ADE584911C71967A8EB70933BC3F5D15BC91B5C2644\ +D9516D3C3A8C154EE48E118BD1442C043C7A0DBA5AC5B1D5360AAE5B9065:\ +EA781FDD2DDDE4B42E1A6B75AB70CFCF17DC413CD9591254F91F1E9741811916\ +56EDC92823A3145DBE4AB491E86233DAACD748CCD2A86B551D6D47EDEA943C82 + +A62FC595B4096E6336E53FCDFC8D1CC175D71DAC9D750A6133D23199EAAC2882\ +07944CEA6B16D27631915B4619F743DA2E30A0C00BBDB1BBB35AB852EF3B9AEC\ +6B0A8DCC6E9E1ABAA3AD62AC0A6C5DE765DE2C3711B769E3FDE44A74016FFF82\ +AC46FA8F1797D3B2A726B696E3DEA5530439ACEE3A45C2A51BC32DD055650B:\ +B2DCDDF444C51976F2D71D020BEF76810C8CCAE2B94C34178C600CCDD04B233B\ +A2D27DB4E8F07EE01D611E490564B6071858BC8B8F8D23BC6B8DA746DAD4A132 + +2B6DB7CED8665EBE9DEB080295218426BDAA7C6DA9ADD2088932CDFFBAA1C141\ +29BCCDD70F369EFB149285858D2B1D155D14DE2FDB680A8B027284055182A0CA\ +E275234CC9C92863C1B4AB66F304CF0621CD54565F5BFF461D3B461BD40DF281\ +98E3732501B4860EADD503D26D6E69338F4E0456E9E9BAF3D827AE685FB1D817:\ +447C299F7E5C90CEE70A7577EC148FEF194F40BA7C3C8CBC96FF81D14490A16E\ +397CA01F3C0883E050F805239FBD4189122B45B1101EE1F303281D2AC1580E2C + +10DB509B2CDCABA6C062AE33BE48116A29EB18E390E1BBADA5CA0A2718AFBCD2\ +3431440106594893043CC7F2625281BF7DE2655880966A23705F0C5155C2F5CC\ +A9F2C2142E96D0A2E763B70686CD421B5DB812DACED0C6D65035FDE558E94F26\ +B3E6DDE5BD13980CC80292B723013BD033284584BFF27657871B0CF07A849F4A\ +E2:\ +E21AEB7109CA41F1C41F4B66E80A6A4248AED43341F1EFFABB61341C3F0B6355\ +EFE3DAA8D28D60F9BF851E6837625BF2EBFD8A68CDCB50718660D5CCBFD93910 + +9334DE60C997BDA6086101A6314F64E4458F5FF9450C509DF006E8C547983C65\ +1CA97879175AABA0C539E82D05C1E02C480975CBB30118121061B1EBAC4F8D9A\ +3781E2DB6B18042E01ECF9017A64A0E57447EC7FCBE6A7F82585F7403EE2223D\ +52D37B4BF426428613D6B4257980972A0ACAB508A7620C1CB28EB4E9D30FC413\ +61EC:\ +FC015B69F1AE0DC7004343FF941378B8A23AA45A3825310E9A81C2A9EA2D4F96\ +1F4C9B8CACBC91F0D2414590C389D24ED482B95252F37B5A6CC6BFAEA5C98C32 + +E88AB086891693AA535CEB20E64C7AB97C7DD3548F3786339897A5F0C3903154\ +9CA870166E477743CCFBE016B4428D89738E426F5FFE81626137F17AECFF61B7\ +2DBEE2DC20961880CFE281DFAB5EE38B1921881450E16032DE5E4D55AD8D4FCA\ +609721B0692BAC79BE5A06E177FE8C80C0C83519FB3347DE9F43D5561CB8107B\ +9B5EDC:\ +45CCB97F9524BA87A7E69354030C71A07D875C5E958EA167EFF581703B1D5037\ +BD91B8806980E3D4EAE0ACB010D210CD89F781DED33F5697DAC285AEB37629A4 + +FD19E01A83EB6EC810B94582CB8FBFA2FCB992B53684FB748D2264F020D3B960\ +CB1D6B8C348C2B54A9FCEA72330C2AAA9A24ECDB00C436ABC702361A82BB8828\ +B85369B8C72ECE0082FE06557163899C2A0EFA466C33C04343A839417057399A\ +63A3929BE1EE4805D6CE3E5D0D0967FE9004696A5663F4CAC9179006A2CEB755\ +42D75D68:\ +142922E983887BFF20D0EE26BCBCBA34A1A70717172B8FBDE0AEABC5CA258C39\ +85B00F7908A21A75C014D4B2542A1BFCB7469BA9454F66670B6C05BBBD7A92D3 + +59AE20B6F7E0B3C7A989AFB28324A40FCA25D8651CF1F46AE383EF6D8441587A\ +A1C04C3E3BF88E8131CE6145CFB8973D961E8432B202FA5AF3E09D625FAAD825\ +BC19DA9B5C6C20D02ABDA2FCC58B5BD3FE507BF201263F30543819510C12BC23\ +E2DDB4F711D087A86EDB1B355313363A2DE996B891025E147036087401CCF3CA\ +7815BF3C49:\ +41DF07681C94633DC430AD7FFF9AB7146F1CC3A66DF3A81D990ED3D247D8F9A5\ +880EFF20C2652FB6C6631EA41F54D6C331651FDC20783EED65B83AF458D0AC72 + +77EE804B9F3295AB2362798B72B0A1B2D3291DCEB8139896355830F34B3B3285\ +61531F8079B79A6E9980705150866402FDC176C05897E359A6CB1A7AB067383E\ +B497182A7E5AEF7038E4C96D133B2782917417E391535B5E1B51F47D8ED7E4D4\ +025FE98DC87B9C1622614BFF3D1029E68E372DE719803857CA52067CDDAAD958\ +951CB2068CC6:\ +9BEE78530C0A93CE8564AEDE785D7086CE066CB74C3B8F70D3851CD57DB8E647\ +E67DF0D543EAFEDED491613BD3268CC7CE8DE34614A79D6413C3FEE218B6965A + +B771D5CEF5D1A41A93D15643D7181D2A2EF0A8E84D91812F20ED21F147BEF732\ +BF3A60EF4067C3734B85BC8CD471780F10DC9E8291B58339A677B960218F71E7\ +93F2797AEA349406512829065D37BB55EA796FA4F56FD8896B49B2CD19B43215\ +AD967C712B24E5032D065232E02C127409D2ED4146B9D75D763D52DB98D949D3\ +B0FED6A8052FBB:\ +E2548952816803ED478241CBAB10F69DB4CBDD98447BFAF4E92AF9A3179B6EFA\ +CEC56C757944B519C69D1759811732FE3C52912611271231342D9D62F3472967 + +B32D95B0B9AAD2A8816DE6D06D1F86008505BD8C14124F6E9A163B5A2ADE55F8\ +35D0EC3880EF50700D3B25E42CC0AF050CCD1BE5E555B23087E04D7BF9813622\ +780C7313A1954F8740B6EE2D3F71F768DD417F520482BD3A08D4F222B4EE9DBD\ +015447B33507DD50F3AB4247C5DE9A8ABD62A8DECEA01E3B87C8B927F5B08BEB\ +37674C6F8E380C04:\ +0E673628FA620668F73E652DF7927EC7D9DF9426F157B055E39D23AD7FA9CCCD\ +C8013FB8F6A0D2EFFEBE00BB5563B100B5361F33808AE20E23580D414F909CED + +04410E31082A47584B406F051398A6ABE74E4DA59BB6F85E6B49E8A1F7F2CA00\ +DFBA5462C2CD2BFDE8B64FB21D70C083F11318B56A52D03B81CAC5EEC29EB31B\ +D0078B6156786DA3D6D8C33098C5C47BB67AC64DB14165AF65B44544D806DDE5\ +F487D5373C7F9792C299E9686B7E5821E7C8E2458315B996B5677D926DAC57B3\ +F22DA873C601016A0D:\ +1B0E41061FF47E71F22FCD508E8560F8E4C9748DD8E520A9CA478F3E3827330C\ +6F19E299E221367E6B02E1606A1B23F2B3F66762D0F408B3A68C9DA9018A45DD + +8B81E9BADDE026F14D95C019977024C9E13DB7A5CD21F9E9FC491D716164BBAC\ +DC7060D882615D411438AEA056C340CDF977788F6E17D118DE55026855F93270\ +472D1FD18B9E7E812BAE107E0DFDE7063301B71F6CFE4E225CAB3B232905A56E\ +994F08EE2891BA922D49C3DAFEB75F7C69750CB67D822C96176C46BD8A29F170\ +1373FB09A1A6E3C7158F:\ +FEE0EA0269154ADD8FCC28BC61D290CCE0CA04FEBD3EF646D5AEED6542461D4C\ +DA983932BE7ABF3E0C2639ACF75AE2770D1B511D996E19536542FB4D76505F69 + +FA6EED24DA6666A22208146B19A532C2EC9BA94F09F1DEF1E7FC13C399A48E41\ +ACC2A589D099276296348F396253B57CB0E40291BD282773656B6E0D8BEA1CDA\ +084A3738816A840485FCF3FB307F777FA5FEAC48695C2AF4769720258C77943F\ +B4556C362D9CBA8BF103AEB9034BAA8EA8BFB9C4F8E6742CE0D52C49EA8E974F\ +339612E830E9E7A9C29065:\ +82DFF74AC5CDFFA0D1D03049F2FC227DCB77E373381C2E74FA316BBF9F6D55AE\ +B7667A95AE4D4D367130620217E245E9DDC641AFF823475AE40E4E3CE56FCD40 + +9BB4AF1B4F09C071CE3CAFA92E4EB73CE8A6F5D82A85733440368DEE4EB1CBC7\ +B55AC150773B6FE47DBE036C45582ED67E23F4C74585DAB509DF1B8361056454\ +5642B2B1EC463E18048FC23477C6B2AA035594ECD33791AF6AF4CBC2A1166ABA\ +8D628C57E707F0B0E8707CAF91CD44BDB915E0296E0190D56D33D8DDE10B5B60\ +377838973C1D943C22ED335E:\ +97D7C677B7D8EA600DE069CC23C492C0C293EB8E9B8987978CD43B2CACE445A9\ +0D1CDFA4E0F347EC9B7E6394DEF55702A13DC5DE3C5E43B8B08F260BF0E654D5 + +2167F02118CC62043E9091A647CADBED95611A521FE0D64E8518F16C808AB297\ +725598AE296880A773607A798F7C3CFCE80D251EBEC6885015F9ABF7EAABAE46\ +798F82CB5926DE5C23F44A3F9F9534B3C6F405B5364C2F8A8BDC5CA49C749BED\ +8CE4BA48897062AE8424CA6DDE5F55C0E42A95D1E292CA54FB46A84FBC9CD87F\ +2D0C9E7448DE3043AE22FDD229:\ +A0A9203714A9DCAE2402958E6BCF759B7E900D13D5A8654501ADAC70B5CEDF27\ +D21F5E92219DAD31DDC8466D8F559470C638D9F9B45D4F539D36C54651C4852C + +94B7FA0BC1C44E949B1D7617D31B4720CBE7CA57C6FA4F4094D4761567E389EC\ +C64F6968E4064DF70DF836A47D0C713336B5028B35930D29EB7A7F9A5AF9AD5C\ +F441745BAEC9BB014CEEFF5A41BA5C1CE085FEB980BAB9CF79F2158E03EF7E63\ +E29C38D7816A84D4F71E0F548B7FC316085AE38A060FF9B8DEC36F91AD9EBC0A\ +5B6C338CBB8F6659D342A24368CF:\ +E6D9B97F5BDB0BB4F5D2322CEFF8A1A747361BB937BCFA69EB8C23D98BEA5C5E\ +E25F9587648912D5E7F90E73C031A27E27FB11276CCB63E47C25B18649AE5DD8 + +EA40E83CB18B3A242C1ECC6CCD0B7853A439DAB2C569CFC6DC38A19F5C90ACBF\ +76AEF9EA3742FF3B54EF7D36EB7CE4FF1C9AB3BC119CFF6BE93C03E208783335\ +C0AB8137BE5B10CDC66FF3F89A1BDDC6A1EED74F504CBE7290690BB295A872B9\ +E3FE2CEE9E6C67C41DB8EFD7D863CF10F840FE618E7936DA3DCA5CA6DF933F24\ +F6954BA0801A1294CD8D7E66DFAFEC:\ +0A14506B804455218133711A3BA8307615E4F80A5334B86555B9CEC77C93450A\ +92F6A18BED9BD55B1848F78C2A49A76057FCF3509663F2E9010C39D94FC9918C + +157D5B7E4507F66D9A267476D33831E7BB768D4D04CC3438DA12F9010263EA5F\ +CAFBDE2579DB2F6B58F911D593D5F79FB05FE3596E3FA80FF2F761D1B0E57080\ +055C118C53E53CDB63055261D7C9B2B39BD90ACC32520CBBDBDA2C4FD8856DBC\ +EE173132A2679198DAF83007A9B5C51511AE49766C792A29520388444EBEFE28\ +256FB33D4260439CBA73A9479EE00C63:\ +8D03AFCB3940007FCBCEEB023C105918E6540D87658E59109CC6568CF804BD3F\ +A2B3968C28C650E55276218482BB8E42944272673D6A137D326477A1BAFE8F3D + +836B34B515476F613FE447A4E0C3F3B8F20910AC89A3977055C960D2D5D2B72B\ +D8ACC715A9035321B86703A411DDE0466D58A59769672AA60AD587B8481DE4BB\ +A552A1645779789501EC53D540B904821F32B0BD1855B04E4848F9F8CFE9EBD8\ +911BE95781A759D7AD9724A7102DBE576776B7C632BC39B9B5E19057E226552A\ +5994C1DBB3B5C7871A11F5537011044C53:\ +4862476DDDADDCDE60A35260AB6C448B9B6DAD7ED296FC48B81E288D0E397E69\ +4535CC8999F4D7F2F3E09F5CE034DB0F71EF5C812F3C6BBD73FBEF14B252BC55 + +CC7784A4912A7AB5AD3620AAB29BA87077CD3CB83636ADC9F3DC94F51EDF521B\ +2161EF108F21A0A298557981C0E53CE6CED45BDF782C1EF200D29BAB81DD6460\ +586964EDAB7CEBDBBEC75FD7925060F7DA2B853B2B089588FA0F8C16EC6498B1\ +4C55DCEE335CB3A91D698E4D393AB8E8EAC0825F8ADEBEEE196DF41205C01167\ +4E53426CAA453F8DE1CBB57932B0B741D4C6:\ +4B239C5B1C8B83924AE736E9D30582D16BF00A547023244247B389259BC62649\ +81606439AC9DDE0A7D371B73A34CAC998823803D7BD62ABF8905C9BD550EBAB8 + +7639B461FFF270B2455AC1D1AFCE782944AEA5E9087EB4A39EB96BB5C3BAAF0E\ +868C8526D3404F9405E79E77BFAC5FFB89BF1957B523E17D341D7323C302EA70\ +83872DD5E8705694ACDDA36D5A1B895AAA16ECA6104C82688532C8BFE1790B5D\ +C9F4EC5FE95BAED37E1D287BE710431F1E5E8EE105BC42ED37D74B1E55984BF1\ +C09FE6A1FA13EF3B96FAEAED6A2A1950A12153:\ +2B0D1C2780D8826CCE4B71A77C9833AE59C2BD0213789A8892CCD7B4FFF1D8A7\ +80E81AD4C2C1228D55DF5BA3625DE4860DB05743E4D07934C434BAD5A769131B + +EB6513FC61B30CFBA58D4D7E80F94D14589090CF1D80B1DF2E68088DC6104959\ +BA0D583D585E9578AB0AEC0CF36C48435EB52ED9AB4BBCE7A5ABE679C97AE2DB\ +E35E8CC1D45B06DDA3CF418665C57CBEE4BBB47FA4CAF78F4EE656FEC237FE4E\ +EBBAFA206E1EF2BD0EE4AE71BD0E9B2F54F91DAADF1FEBFD7032381D636B733D\ +CB3BF76FB14E23AFF1F68ED3DBCF75C9B99C6F26:\ +0880376CD5FFC7EBCC6E80FAE0D78DBB3532500BAB96CD4B755584D23E68CF59\ +F5297A34AE0A90184773412BC9548A80E4C54391B4CB59CE292D704C614DD1A1 + +1594D74BF5DDE444265D4C04DAD9721FF3E34CBF622DAF341FE16B96431F6C4D\ +F1F760D34F296EB97D98D560AD5286FEC4DCE1724F20B54FD7DF51D4BF137ADD\ +656C80546FB1BF516D62EE82BAA992910EF4CC18B70F3F8698276FCFB44E0EC5\ +46C2C39CFD8EE91034FF9303058B4252462F86C823EB15BF481E6B79CC3A0221\ +8595B3658E8B37382BD5048EAED5FD02C37944E73B:\ +E725B8C82C8D1F3963A77D505B0A929FD58846061BEA2BA7040B7D3B2AD95EE3\ +781CACA60B372EB5258A44A65BB9EE655A1EF9102F8BBD9E41FCFB2871DAEC7D + +4CFA1278903026F66FEDD41374558BE1B585D03C5C55DAC94361DF286D4BD39C\ +7CB8037ED3B267B07C346626449D0CC5B0DD2CF221F7E4C3449A4BE99985D2D5\ +E67BFF2923357DDEAB5ABCB4619F3A3A57B2CF928A022EB27676C6CF80568900\ +4FCA4D41EA6C2D0A4789C7605F7BB838DD883B3AD3E6027E775BCF2628814280\ +99C7FFF95B14C095EA130E0B9938A5E22FC52650F591:\ +31175C65FF1133F5F53DB80DEB90F6B2E79727D4C8E77C5E3F5DEF70525B871B\ +50249C6F2EE1CA6F11A7CD9C578CF13D5FCBD74DE1D05AF6076A5459E10B4B9D + +D3E65CB92CFA79662F6AF493D696A07CCF32AAADCCEFF06E73E8D9F6F909209E\ +66715D6E978788C49EFB9087B170ECF3AA86D2D4D1A065AE0EFC8924F365D676\ +B3CB9E2BEC918FD96D0B43DEE83727C9A93BF56CA2B2E59ADBA85696546A8150\ +67FC7A78039629D4948D157E7B0D826D1BF8E81237BAB7321312FDAA4D521744\ +F988DB6FDF04549D0FDCA393D639C729AF716E9C8BBA48:\ +870B40EE6B774B732E15DEE647F75BF3D5DD6FD364C7E1BB184D8AC1F0C991E2\ +486DCE6BD6CEFA1DFFE13C50260D4A0FB6C23E29D7E62CFF0F8DE785CA53C2A2 + +842CC583504539622D7F71E7E31863A2B885C56A0BA62DB4C2A3F2FD12E79660\ +DC7205CA29A0DC0A87DB4DC62EE47A41DB36B9DDB3293B9AC4BAAE7DF5C6E720\ +1E17F717AB56E12CAD476BE49608AD2D50309E7D48D2D8DE4FA58AC3CFEAFEEE\ +48C0A9EEC88498E3EFC51F54D300D828DDDCCB9D0B06DD021A29CF5CB5B25069\ +15BEB8A11998B8B886E0F9B7A80E97D91A7D01270F9A7717:\ +8FDE68D448144F3B4BD12011DF94A463C40BE946821F80EC8197E36EB46554F7\ +AD8B6CA9F6FCC8C05B3C0C2C909966AACBA2A1AA6E980E57AEA1CB35B01DC991 + +6C4B0A0719573E57248661E98FEBE326571F9A1CA813D3638531AE28B4860F23\ +C3A3A8AC1C250034A660E2D71E16D3ACC4BF9CE215C6F15B1C0FC7E77D3D2715\ +7E66DA9CEEC9258F8F2BF9E02B4AC93793DD6E29E307EDE3695A0DF63CBDC0FC\ +66FB770813EB149CA2A916911BEE4902C47C7802E69E405FE3C04CEB5522792A\ +5503FA829F707272226621F7C488A7698C0D69AA561BE9F378:\ +F19E37E56DE97B6EF009CB1B0A8FEB42891DE80A9895C7413367C71FF34815F9\ +77A053FD621C30738C347262DF2B07EC3E455DC729803FA3D68BFBFF42415500 + +51B7DBB7CE2FFEB427A91CCFE5218FD40F9E0B7E24756D4C47CD55606008BDC2\ +7D16400933906FD9F30EFFDD4880022D081155342AF3FB6CD53672AB7FB5B3A3\ +BCBE47BE1FD3A2278CAE8A5FD61C1433F7D350675DD21803746CADCA574130F0\ +1200024C6340AB0CC2CF74F2234669F34E9009EF2EB94823D62B31407F4BA46F\ +1A1EEC41641E84D77727B59E746B8A671BEF936F05BE820759FA:\ +BC3199569054F2DBDC66744F3B6B7DC23D3708BCD96A8C7B7C5D9E58087E2E4A\ +5D5606CEF88AD63044C9A4F0D019358846EE83FE98CFE9C5B03B29A2D31B3134 + +83599D93F5561E821BD01A472386BC2FF4EFBD4AED60D5821E84AAE74D807102\ +9810F5E286F8F17651CD27DA07B1EB4382F754CD1C95268783AD09220F550284\ +0370D494BEB17124220F6AFCE91EC8A0F55231F9652433E5CE3489B727716CF4\ +AEBA7DCDA20CD29AA9A859201253F948DD94395ABA9E3852BD1D60DDA7AE5DC0\ +45B283DA006E1CBAD83CC13292A315DB5553305C628DD091146597:\ +C44780E409877812578CF0D738A6394B1EBF7183941323C2891D9604B93E5748\ +EAB2FD4732DCE6D9A5D1F27B7FADFD5DFDC87264BE97F86F700AE87A5D1B8227 + +2BE9BF526C9D5A75D565DD11EF63B979D068659C7F026C08BEA4AF161D85A462\ +D80E45040E91F4165C074C43AC661380311A8CBED59CC8E4C4518E80CD2C78AB\ +1CABF66BFF83EAB3A80148550307310950D034A6286C93A1ECE8929E6385C5E3\ +BB6EA8A7C0FB6D6332E320E71CC4EB462A2A62E2BFE08F0CCAD93E61BEDB5DD0\ +B786A728AB666F07E0576D189C92BF9FB20DCA49AC2D3956D47385E2:\ +98474C61C2639BA15B58D98429F0E3489504CC6ED3BF638ACCF6859443AF2BCB\ +F85EDBEF50191EDB6923636B21C2E76E985831F187575BA82E9AB4CA40CC482F + +CA76D3A12595A817682617006848675547D3E8F50C2210F9AF906C0E7CE50B44\ +60186FE70457A9E879E79FD4D1A688C70A347361C847BA0DD6AA52936EAF8E58\ +A1BE2F5C1C704E20146D366AEB3853BED9DE9BEFE9569AC8AAEA37A9FB7139A1\ +A1A7D5C748605A8DEFB297869EBEDD71D615A5DA23496D11E11ABBB126B206FA\ +0A7797EE7DE117986012D0362DCEF775C2FE145ADA6BDA1CCB326BF644:\ +F94556B89FA106C94D32F723061D2E88EBC4164B1B02D0485851782F84CC3229\ +7D7A3AF9A1CC430702B78B5BDC9E50ABDD703201AA73F8811AEB4A80A5992C64 + +F76B85DC67421025D64E93096D1D712B7BAF7FB001716F02D33B2160C2C882C3\ +10EF13A576B1C2D30EF8F78EF8D2F465007109AAD93F74CB9E7D7BEF7C9590E8\ +AF3B267C89C15DB238138C45833C98CC4A471A7802723EF4C744A853CF80A0C2\ +568DD4ED58A2C9644806F42104CEE53628E5BDF7B63B0B338E931E31B87C24B1\ +46C6D040605567CEEF5960DF9E022CB469D4C787F4CBA3C544A1AC91F95F:\ +60440509E00573D66609563D8F1504A196AF06D46F6CDBFEEAFF61FE46AD0845\ +6EE24BCA13DDED11818776CAC19376AE7415338A3D4F0035FF276188BF11420F + +25B8C9C032EA6BCD733FFC8718FBB2A503A4EA8F71DEA1176189F694304F0FF6\ +8E862A8197B839957549EF243A5279FC2646BD4C009B6D1EDEBF24738197ABB4\ +C992F6B1DC9BA891F570879ACCD5A6B18691A93C7D0A8D38F95B639C1DAEB48C\ +4C2F15CCF5B9D508F8333C32DE78781B41850F261B855C4BEBCC125A380C54D5\ +01C5D3BD07E6B52102116088E53D76583B0161E2A58D0778F091206AABD5A1:\ +2D552519EC54E5BBBFDBB543EAE5482D9B964A952E880A88567E7DDF1DCD0D5A\ +A353F7BE15D7634ADBDBEFA85355839FDA2B738DA987BA568103EABE2CB53D23 + +21CFDC2A7CCB7F331B3D2EEFFF37E48AD9FA9C788C3F3C200E0173D99963E1CB\ +CA93623B264E920394AE48BB4C3A5BB96FFBC8F0E53F30E22956ADABC2765F57\ +FB761E147ECBF8567533DB6E50C8A1F894310A94EDF806DD8CA6A0E141C0FA7C\ +9FAE6C6AE65F18C93A8529E6E5B553BF55F25BE2E80A9882BD37F145FECBEB3D\ +447A3C4E46C21524CC55CDD62F521AB92A8BA72B897996C49BB273198B7B1C9E:\ +AFB37A28A4F216A6CC3D6AED09E82F40B93E445F892040F21D1AABAFE99AF7F0\ +01837CF0AD8DD2E2983282F35ADFB9DCEB49B2C80C85153772A8E587ABE7F18A + +4E452BA42127DCC956EF4F8F35DD68CB225FB73B5BC7E1EC5A898BBA2931563E\ +74FAFF3B67314F241EC49F4A7061E3BD0213AE826BAB380F1F14FAAB8B0EFDDD\ +5FD1BB49373853A08F30553D5A55CCBBB8153DE4704F29CA2BDEEF0419468E05\ +DD51557CCC80C0A96190BBCC4D77ECFF21C66BDF486459D427F986410F883A80\ +A5BCC32C20F0478BB9A97A126FC5F95451E40F292A4614930D054C851ACD019C\ +CF:\ +721B1BC60845499B1A50B716F97FA9FD584132C1E30A1705779DBBAE644CBB57\ +51AD1B1B379CC91BA4C3054BD060B88050BABA98BE1864B1B96C3691A096EF21 + +FA85671DF7DADF99A6FFEE97A3AB9991671F5629195049880497487867A6C446\ +B60087FAC9A0F2FCC8E3B24E97E42345B93B5F7D3691829D3F8CCD4BB36411B8\ +5FC2328EB0C51CB3151F70860AD3246CE0623A8DC8B3C49F958F8690F8E3860E\ +71EB2B1479A5CEA0B3F8BEFD87ACAF5362435EAECCB52F38617BC6C5C2C6E269\ +EAD1FBD69E941D4AD2012DA2C5B21BCFBF98E4A77AB2AF1F3FDA3233F046D38F\ +1DC8:\ +EFFFB02598398243D8784EB8ADA33D314C8D396406BB7FB6A668085B23438AB4\ +580BFB5258E5D616F9030C6A8928F4F753D6800C90EA2812482BED268A806E8E + +E90847AE6797FBC0B6B36D6E588C0A743D725788CA50B6D792352EA8294F5BA6\ +54A15366B8E1B288D84F5178240827975A763BC45C7B0430E8A559DF4488505E\ +009C63DA994F1403F407958203CEBB6E37D89C94A5EACF6039A327F6C4DBBC7A\ +2A307D976AA39E41AF6537243FC218DFA6AB4DD817B6A397DF5CA69107A91987\ +99ED248641B63B42CB4C29BFDD7975AC96EDFC274AC562D0474C60347A078CE4\ +C25E88:\ +F1CF53FFC952C446EEF49F9D89370757C74CB8F2D99223C47EABD296151161CB\ +86C6A34833E7AC6B75E8119A8274FD2B9066EBB9B787A4A37C9036E6E01BA9CE + +F6D5C2B6C93954FC627602C00C4CA9A7D3ED12B27173F0B2C9B0E4A5939398A6\ +65E67E69D0B12FB7E4CEB253E8083D1CEB724AC07F009F094E42F2D6F2129489\ +E846EAFF0700A8D4453EF453A3EDDC18F408C77A83275617FABC4EA3A2833AA7\ +3406C0E966276079D38E8E38539A70E194CC5513AAA457C699383FD1900B1E72\ +BDFB835D1FD321B37BA80549B078A49EA08152869A918CA57F5B54ED71E4FD3A\ +C5C06729:\ +F1C9A73B10BA528A61AB86F91A9A05261B447049C7ECCF37AB1E0C1219F14F0F\ +0F2C5B419A7595550F2D651A17368C3FB7538A14FF9FFC4C4D9098803D942D3B + +CF8562B1BED89892D67DDAAF3DEEB28246456E972326DBCDB5CF3FB289ACA01E\ +68DA5D59896E3A6165358B071B304D6AB3D018944BE5049D5E0E2BB819ACF67A\ +6006111089E6767132D72DD85BEDDCBB2D64496DB0CC92955AB4C6234F1EEA24\ +F2D51483F2E209E4589BF9519FAC51B4D061E801125E605F8093BB6997BC163D\ +551596FE4AB7CFAE8FB9A90F6980480CE0C229FD1675409BD788354DAF316240\ +CFE0AF93EB:\ +5A1A31490BC85FACC5101EE18093BEC7C2CB717A54AFDEE47F98660032D912F2\ +3792F1D0AB0BE8A3C7F0D000DAC238DE843CC84178CBAA910090AC827197AD85 + +2ACE31ABB0A2E3267944D2F75E1559985DB7354C6E605F18DC8470423FCA30B7\ +331D9B33C4A4326783D1CAAE1B4F07060EFF978E4746BF0C7E30CD61040BD5EC\ +2746B29863EB7F103EBDA614C4291A805B6A4C8214230564A0557BC7102E0BD3\ +ED23719252F7435D64D210EE2AAFC585BE903FA41E1968C50FD5D5367926DF7A\ +05E3A42CF07E656FF92DE73B036CF8B19898C0CB34557C0C12C2D8B84E91181A\ +F467BC75A9D1:\ +24B5A99041785BC5C5519190B4AAAF92770E35D07213A6DE55EB8811324CC63E\ +3AFCF61F973A896CFB30315873C0071E2BF3BB976A53163422A01192915B9C1E + +0D8D09AED19F1013969CE5E7EB92F83A209AE76BE31C754844EA9116CEB39A22\ +EBB6003017BBCF26555FA6624185187DB8F0CB3564B8B1C06BF685D47F3286ED\ +A20B83358F599D2044BBF0583FAB8D78F854FE0A596183230C5EF8E54426750E\ +AF2CC4E29D3BDD037E734D863C2BD9789B4C243096138F7672C232314EFFDFC6\ +513427E2DA76916B5248933BE312EB5DDE4CF70804FB258AC5FB82D58D08177A\ +C6F4756017FFF5:\ +7FF6491E79CD3F743C3D735A0AC1BC5EC3395950C65111D7BC2E5E3719AB0FE9\ +20DDA443B1FD8A8D557633B95E68354EF8F78A91A769CF0798871F8B11B77478 + +C3236B73DEB7662BF3F3DAA58F137B358BA610560EF7455785A9BEFDB035A066\ +E90704F929BD9689CEF0CE3BDA5ACF4480BCEB8D09D10B098AD8500D9B6071DF\ +C3A14AF6C77511D81E3AA8844986C3BEA6F469F9E02194C92868CD5F51646256\ +798FF0424954C1434BDFED9FACB390B07D342E992936E0F88BFD0E884A0DDB67\ +9D0547CCDEC6384285A45429D115AC7D235A717242021D1DC35641F5F0A48E84\ +45DBA58E6CB2C8EA:\ +0154D5832EC5594FF994034BE3FD3E61E7EEBC8E43C20C6CC9910F15650FBAED\ +2915087AC641DBF60A2083FF14AB084A27B5CC9A4E84C54A6B361D38C72746D5 + +B39FEB8283EADC63E8184B51DF5AE3FD41AAC8A963BB0BE1CD08AA5867D8D910\ +C669221E73243360646F6553D1CA05A84E8DC0DE05B6419EC349CA994480193D\ +01C92525F3FB3DCEFB08AFC6D26947BDBBFD85193F53B50609C6140905C53A66\ +86B58E53A319A57B962331EDE98149AF3DE3118A819DA4D76706A0424B4E1D29\ +10B0ED26AF61D150EBCB46595D4266A0BD7F651BA47D0C7F179CA28545007D92\ +E8419D48FDFBD744CE:\ +5B617AB6F6FFA82197ED058D4CFDF54398FA3CD95074A745D389C05D8DCE1B9D\ +4B9E88CE4B519017EA3A55EB89D06D2CE321F4801D079D5867EAC366BC270968 + +A983D54F503803E8C7999F4EDBBE82E9084F422143A932DDDDC47A17B0B7564A\ +7F37A99D0786E99476428D29E29D3C197A72BFAB1342C12A0FC4787FD7017D7A\ +6174049EA43B5779169EF7472BDBBD941DCB82FC73AAC45A8A94C9F2BD3477F6\ +1FD3B796F02A1B8264A214C6FEA74B7051B226C722099EC7883A462B83B6AFDD\ +4009248B8A237F605FE5A08FE7D8B45321421EBBA67BD70A0B00DDBF94BAAB7F\ +359D5D1EEA105F28DCFB:\ +1D96D1CE0C82A43D4135ED8A022A5F145AB42FDFA024C894939D6FA422EC4F62\ +1A1402113E1105A96273DD4F7884879F63EF41830A1EA0B4516937BBB2DBE44D + +E4D1C1897A0A866CE564635B74222F9696BF2C7F640DD78D7E2ACA66E1B61C64\ +2BB03EA7536AAE597811E9BF4A7B453EDE31F97B46A5F0EF51A071A2B3918DF1\ +6B152519AE3776F9F1EDAB4C2A377C3292E96408359D3613844D5EB393000283\ +D5AD3401A318B12FD1474B8612F2BB50FB6A8B9E023A54D7DDE28C43D6D8854C\ +8D9D1155935C199811DBFC87E9E0072E90EB88681CC7529714F8FB8A2C9D8856\ +7ADFB974EE205A9BF7B848:\ +DE1255FCB5A191E19B663DF4A9DC5471F39F13BE5F8A9CC1C3F6FE2844EB8CF0\ +38E7FF1825D26A8F135AAA77120925ADDB6ACC12EA1BF0E60DFA236FBE38458F + +B10C59723E3DCADD6D75DF87D0A1580E73133A9B7D00CB95EC19F5547027323B\ +E75158B11F80B6E142C6A78531886D9047B08E551E75E6261E79785366D7024B\ +D7CD9CF322D9BE7D57FB661069F2481C7BB759CD71B4B36CA2BC2DF6D3A328FA\ +EBDB995A9794A8D72155ED551A1F87C80BF6059B43FC764900B18A1C2441F748\ +7743CF84E565F61F8DD2ECE6B6CCC9444049197AAAF53E926FBEE3BFCA8BE588\ +EC77F29D211BE89DE18B15F6:\ +B17A24CA14830ED093C39E8323EC0DFD903172458D023D10FE4125D0EB4AF0E7\ +578B1EA1D5148348AB8D6CAB98B20B18BCC52A6CBA85851D2B74B20735BE6E48 + +DB11F609BABA7B0CA634926B1DD539C8CBADA24967D7ADD4D9876F77C2D80C0F\ +4DCEFBD7121548373582705CCA2495BD2A43716FE64ED26D059CFB566B3364BD\ +49EE0717BDD9810DD14D8FAD80DBBDC4CAFB37CC60FB0FE2A80FB4541B8CA9D5\ +9DCE457738A9D3D8F641AF8C3FD6DA162DC16FC01AAC527A4A0255B4D231C0BE\ +50F44F0DB0B713AF03D968FE7F0F61ED0824C55C4B5265548FEBD6AAD5C5EEDF\ +63EFE793489C39B8FD29D104CE:\ +602B683C28F25E9F20C413D2B357DCDF3E339945C5BD41FCA69FFFD2E1658F9F\ +B654B94B62BEE72087EABEF2F2F6AEDE72C7DC45DD4549CBC75465CC10D4C554 + +BEBD4F1A84FC8B15E4452A54BD02D69E304B7F32616AADD90537937106AE4E28\ +DE9D8AAB02D19BC3E2FDE1D651559E296453E4DBA94370A14DBBB2D1D4E20223\ +02EE90E208321EFCD8528AD89E46DC839EA9DF618EA8394A6BFF308E7726BAE0\ +C19BCD4BE52DA6258E2EF4E96AA21244429F49EF5CB486D7FF35CAC1BACB7E95\ +711944BCCB2AB34700D42D1EB38B5D536B947348A458EDE3DC6BD6EC547B1B0C\ +AE5B257BE36A7124E1060C170FFA:\ +E90126404BFED0DCF726CA50A6D0620305D1A84EFB0E768044D2DB920FB041E7\ +DEAA465777D312E2867E6E9E50559BB5ECE3A4ED6F844504C39E12988917FFF5 + +5ACA56A03A13784BDC3289D9364F79E2A85C12276B49B92DB0ADAA4F206D5028\ +F213F678C3510E111F9DC4C1C1F8B6ACB17A6413AA227607C515C62A733817BA\ +5E762CC6748E7E0D6872C984D723C9BB3B117EB8963185300A80BFA65CDE495D\ +70A46C44858605FCCBED086C2B45CEF963D33294DBE9706B13AF22F1B7C4CD5A\ +001CFEC251FBA18E722C6E1C4B1166918B4F6F48A98B64B3C07FC86A6B17A6D0\ +480AB79D4E6415B520F1C484D675B1:\ +D98758D0CBE6C5FEF11A4EDD8E9170FFA7F37F40914B4D836025B3FD71FA2B51\ +8164266D974A40AE2D7C3C359CA675E94B04D08D3EE56346A51B82366F1EF0F0 + +A5AAD0E4646A32C85CFCAC73F02FC5300F1982FABB2F2179E28303E447854094\ +CDFC854310E5C0F60993CEFF54D84D6B46323D930ADB07C17599B35B505F09E7\ +84BCA5985E0172257797FB53649E2E9723EFD16865C31B5C3D5113B58BB0BFC8\ +920FABDDA086D7537E66D709D050BD14D0C960873F156FAD5B3D3840CDFCDC9B\ +E6AF519DB262A27F40896AB25CC39F96984D650611C0D5A3080D5B3A1BF186AB\ +D42956588B3B58CD948970D298776060:\ +7EA57C6B9741AE7C07E11766DC6F69C83A72533126ACAFCA968832FCBC7A28DF\ +18968BB582E6933898672E322235C9D8FA310F485169C55E04672FFDA2A01099 + +06CBBE67E94A978203EAD6C057A1A5B098478B4B4CBEF5A97E93C8E42F557271\ +3575FC2A884531D7622F8F879387A859A80F10EF02708CD8F7413AB385AFC357\ +678B9578C0EBF641EF076A1A30F1F75379E9DCB2A885BDD295905EE80C0168A6\ +2A9597D10CF12DD2D8CEE46645C7E5A141F6E0E23AA482ABE5661C16E69EF1E2\ +8371E2E236C359BA4E92C25626A7B7FF13F6EA4AE906E1CFE163E91719B1F750\ +A96CBDE5FBC953D9E576CD216AFC90323A:\ +CEFB46600FC757512E917DFA063BEC761DA6140893D3B7BA01677C6D142CA296\ +0B4B016CCF9C9A175D8E83CC2F1A9D4171D6074E2405B866CDEE57683BD4334F + +F1C528CF7739874707D4D8AD5B98F7C77169DE0B57188DF233B2DC8A5B31EDA5\ +DB4291DD9F68E6BAD37B8D7F6C9C0044B3BF74BBC3D7D1798E138709B0D75E7C\ +593D3CCCDC1B20C7174B4E692ADD820ACE262D45CCFAE2077E87879634716806\ +0A162ECCA8C38C1A88350BD63BB539134F700FD4ADDD5959E255337DAA06BC86\ +358FABCBEFDFB5BC889783D843C08AADC6C4F6C36F65F156E851C9A0F917E4A3\ +67B5AD93D874812A1DE6A7B93CD53AD97232:\ +EB861B333F0763CC1F0747ECE23FF46B98962B096CBF95335B6BA9992F291611\ +5887E77A812CE6F78B00530194C71B97ABF4082F31C09F547B025B4388199E75 + +9D9F3A7ECD51B41F6572FD0D0881E30390DFB780991DAE7DB3B47619134718E6\ +F987810E542619DFAA7B505C76B7350C6432D8BF1CFEBDF1069B90A35F0D04CB\ +DF130B0DFC7875F4A4E62CDB8E525AADD7CE842520A482AC18F09442D78305FE\ +85A74E39E760A4837482ED2F437DD13B2EC1042AFCF9DECDC3E877E50FF4106A\ +D10A525230D11920324A81094DA31DEAB6476AA42F20C84843CFC1C58545EE80\ +352BDD3740DD6A16792AE2D86F11641BB717C2:\ +51CBA976ABC7E8D55F67B1A056B311B861FEE85D2FD69BED53DD274024D87DBD\ +269C41B85F6A1C19FF3D32C444CC7BD8F11478147BBCE99DCBD29E34988EA808 + +5179888724819FBAD3AFA927D3577796660E6A81C52D98E9303261D5A4A83232\ +F6F758934D50AA83FF9E20A5926DFEBAAC49529D006EB923C5AE5048ED544EC4\ +71ED7191EDF46363383824F915769B3E688094C682B02151E5EE01E510B431C8\ +865AFF8B6B6F2F59CB6D129DA79E97C6D2B8FA6C6DA3F603199D2D1BCAB54768\ +2A81CD6CF65F6551121391D78BCC23B5BD0E922EC6D8BF97C952E84DD28AEF90\ +9ABA31EDB903B28FBFC33B7703CD996215A11238:\ +10863687D6D1144DCF9D03C10CB66B33E9813EFB9118EEFB947FC68997E6CCF6\ +D93DCD4C2E33A2D187F5E6F5569D291F16B985908F4015599A6214C24AF791B9 + +576EF3520D30B7A4899B8C0D5E359E45C5189ADD100E43BE429A02FB3DE5FF4F\ +8FD0E79D9663ACCA72CD29C94582B19292A557C5B1315297D168FBB54E9E2ECD\ +13809C2B5FCE998EDC6570545E1499DBE7FB74D47CD7F35823B212B05BF3F5A7\ +9CAA34224FDD670D335FCB106F5D92C3946F44D3AFCBAE2E41AC554D8E6759F3\ +32B76BE89A0324AA12C5482D1EA3EE89DED4936F3E3C080436F539FA137E74C6\ +D3389BDF5A45074C47BC7B20B0948407A66D855E2F:\ +DE8591FD57ABD6D73CF01C94083F916C897FC0CABC1049BCD75D64C768D3B4C4\ +2F05BA4DEAAB83BB643BA451CC224B0A61110647FA35AC14F63D9C2FEA5231C9 + +0DF2152FA4F4357C8741529DD77E783925D3D76E95BAFA2B542A2C33F3D1D117\ +D159CF473F82310356FEE4C90A9E505E70F8F24859656368BA09381FA245EB6C\ +3D763F3093F0C89B972E66B53D59406D9F01AEA07F8B3B615CAC4EE4D05F542E\ +7D0DAB45D67CCCCD3A606CCBEB31EA1FA7005BA07176E60DAB7D78F6810EF086\ +F42F08E595F0EC217372B98970CC6321576D92CE38F7C397A403BADA1548D205\ +C343AC09DECA86325373C3B76D9F32028FEA8EB32515:\ +4E529B73E0AFA555B75A7EF2B43F32D71002045F0ABF519C5C1E31F7213AE10B\ +B1474BED81450E9956779216B0DC2D4067B181744D9E66AF3F34306CEFD5FDE8 + +3E15350D87D6EBB5C8AD99D42515CFE17980933C7A8F6B8BBBF0A63728CEFAAD\ +2052623C0BD5931839112A48633FB3C2004E0749C87A41B26A8B48945539D1FF\ +41A4B269462FD199BFECD45374756F55A9116E92093AC99451AEFB2AF9FD32D6\ +D7F5FBC7F7A540D5097C096EBC3B3A721541DE073A1CC02F7FB0FB1B9327FB0B\ +1218CA49C9487AB5396622A13AE546C97ABDEF6B56380DDA7012A8384091B665\ +6D0AB272D363CEA78163FF765CDD13AB1738B940D16CAE:\ +CAD6B2E517A3A890D69C8058B427CF4CE48C775B84EC7E47D12C3D2BFD746D3F\ +6DD1814F6721B5DA519A6630E581846F999F727970C67940DFFF70015DAE9053 + +C38D6B0B757CB552BE40940ECE0009EF3B0B59307C1451686F1A22702922800D\ +58BCE7A636C1727EE547C01B214779E898FC0E560F8AE7F61BEF4D75EAA696B9\ +21FD6B735D171535E9EDD267C192B99880C87997711002009095D8A7A437E258\ +104A41A505E5EF71E5613DDD2008195F0C574E6BA3FE40099CFA116E5F1A2FA8\ +A6DA04BADCB4E2D5D0DE31FDC4800891C45781A0AAC7C907B56D631FCA5CE8B2\ +CDE620D11D1777ED9FA603541DE794DDC5758FCD5FAD78C0:\ +24C90C5D7F0C9471FA119437C8CA847E81D556F66FB6316DD0FB53DD57DFB3BA\ +7D14AC4D1C9C55F04FB6FE2EA9E67178890A3501567059015B7D993256CA1C54 + +8D2DE3F0B37A6385C90739805B170057F091CD0C7A0BC951540F26A5A75B3E69\ +4631BB64C7635EED316F51318E9D8DE13C70A2ABA04A14836855F35E480528B7\ +76D0A1E8A23B547C8B8D6A0D09B241D3BE9377160CCA4E6793D00A515DC2992C\ +B7FC741DACA171431DA99CCE6F7789F129E2AC5CF65B40D703035CD2185BB936\ +C82002DAF8CBC27A7A9E554B06196630446A6F0A14BA155ED26D95BD627B7205\ +C072D02B60DB0FD7E49EA058C2E0BA202DAFF0DE91E845CF79:\ +4BA61EFF8CEC62389A932E24775211189098BDCDFDC6615AE79948914D6361C6\ +BBC45B7DEAFB4A58B78AF4ABFBEB8991EDCF30A2A586BE8C6CECF9875C734D7A + +C464BBDAD275C50DCD983B65AD1019B9FF85A1E71C807F3204BB2C921DC31FBC\ +D8C5FC45868AE9EF85B6C9B83BBA2A5A822201ED68586EC5EC27FB2857A5D1A2\ +D09D09115F22DCC39FE61F5E1BA0FF6E8B4ACB4C6DA748BE7F3F0839739394FF\ +7FA8E39F7F7E84A33C3866875C01BCB1263C9405D91908E9E0B50E7459FABB63\ +D8C6BBB73D8E3483C099B55BC30FF092FF68B6ADEDFD477D63570C9F5515847F\ +36E24BA0B705557130CEC57EBAD1D0B31A378E91894EE26E3A04:\ +1F6CD40F56856615AAFD4103618908530C8EEF746389ADCE64E2CADFFBACB9DA\ +B4E5F973CBB86E607AF00F32948E4CF8BAFD2782653710B38FBF890922773AE5 + +8B8D68BB8A75732FE272815A68A1C9C5AA31B41DEDC8493E76525D1D013D33CE\ +BD9E21A5BB95DB2616976A8C07FCF411F5F6BC6F7E0B57ACA78CC2790A6F9B89\ +8858AC9C79B165FF24E66677531E39F572BE5D81EB3264524181115F32780257\ +BFB9AEEC6AF12AF28E587CAC068A1A2953B59AD680F4C245B2E3EC36F59940D3\ +7E1D3DB38E13EDB29B5C0F404F6FF87F80FC8BE7A225FF22FBB9C8B6B1D7330C\ +57840D24BC75B06B80D30DAD6806544D510AF6C4785E823AC3E0B8:\ +2E6D38768361D7BA583A5314947E43FA294E29F87BD7CC2D6F49890912885F90\ +7D8FA6BEF24B4824A4FF777C5FCF04D655FB0F9C2A6C7ADABEC9B92A6698D33E + +6B018710446F368E7421F1BC0CCF562D9C1843846BC8D98D1C9BF7D9D6FCB48B\ +FC3BF83B36D44C4FA93430AF75CD190BDE36A7F92F867F58A803900DF8018150\ +384D85D82132F123006AC2AEBA58E02A037FE6AFBD65ECA7C44977DD3DC74F48\ +B6E7A1BFD5CC4DCF24E4D52E92BD4455848E4928B0EAC8B7476FE3CC03E862AA\ +4DFF4470DBFED6DE48E410F25096487ECFC32A27277F3F5023B2725ADE461B13\ +55889554A8836C9CF53BD767F5737D55184EEA1AB3F53EDD0976C485:\ +EB395350C2557F16601D19DC75031348103F059A0FB890CC2A002932E0619CE8\ +E52F0F39688DF0DB724CB095B69A5643154C9336FBBA50F35C6A4C05477737EC + +C9534A24714BD4BE37C88A3DA1082EDA7CABD154C309D7BD670DCCD95AA53559\ +4463058A29F79031D6ECAA9F675D1211E9359BE82669A79C855EA8D89DD38C2C\ +761DDD0EC0CE9E97597432E9A1BEAE062CDD71EDFDFD464119BE9E69D18A7A7F\ +D7CE0E2106F0C8B0ABF4715E2CA48EF9F454DC203C96656653B727083513F8EF\ +B86E49C513BB758B3B052FE21F1C05BB33C37129D6CC81F1AEF6ADC45B0E8827\ +A830FE545CF57D0955802C117D23CCB55EA28F95C0D8C2F9C5A242B33F:\ +01449772284E566C1E31A6924A2D9157BDCDD694B5ED1039370BBB11F58851FE\ +5677B25276EC84FDD8472426735C532BCA3D59ACB6FDCE13C0DEA9376DDA8AAE + +07906C87297B867ABF4576E9F3CC7F82F22B154AFCBF293B9319F1B0584DA6A4\ +0C27B32E0B1B7F412C4F1B82480E70A9235B12EC27090A5A33175A2BB28D8ADC\ +475CEFE33F7803F8CE27967217381F02E67A3B4F84A71F1C5228E0C2AD971373\ +F6F672624FCEA8D1A9F85170FAD30FA0BBD25035C3B41A6175D467998BD1215F\ +6F3866F53847F9CF68EF3E2FBB54BC994DE2302B829C5EEA68EC441FCBAFD7D1\ +6AE4FE9FFF98BF00E5BC2AD54DD91FF9FDA4DD77B6C754A91955D1FBAAD0:\ +5E4DE3451E6BF67CEC13F960D86FA9035B1AA4A824F0AFF446271D39784A0E73\ +5FDD00AE53D6347DDFEC4EC6A552AD78AF145BBA1CD4C34C300E3AAEEF88838E + +588E94B9054ABC2189DF69B8BA34341B77CDD528E7860E5DEFCAA79B0C9A452A\ +D4B82AA306BE84536EB7CEDCBE058D7B84A6AEF826B028B8A0271B69AC3605A9\ +635EA9F5EA0AA700F3EB7835BC54611B922964300C953EFE7491E3677C2CEBE0\ +822E956CD16433B02C68C4A23252C3F9E151A416B4963257B783E038F6B4D5C9\ +F110F871652C7A649A7BCEDCBCCC6F2D0725BB903CC196BA76C76AA9F10A190B\ +1D1168993BAA9FFC96A1655216773458BEC72B0E39C9F2C121378FEAB4E76A:\ +814E7B36373B0276718212ABA4E0D9760E433B680FC59869533E4F1D34010047\ +977C91FA33C0C6DFC2F6A4DADCE34BC897A3F7E2CA9935B99D8E5425AB46060D + +08959A7E4BAAE874928813364071194E2939772F20DB7C3157078987C557C2A6\ +D5ABE68D520EEF3DC491692E1E21BCD880ADEBF63BB4213B50897FA005256ED4\ +1B5690F78F52855C8D9168A4B666FCE2DA2B456D7A7E7C17AB5F2FB1EE90B79E\ +698712E963715983FD07641AE4B4E9DC73203FAC1AE11FA1F8C7941FCC82EAB2\ +47ADDB56E2638447E9D609E610B60CE086656AAEBF1DA3C8A231D7D94E2FD0AF\ +E46B391FF14A72EAEB3F44AD4DF85866DEF43D4781A0B3578BC996C87970B132:\ +9B28504942E11B4FE971337FBB905DD772EF9D4982AC4D5EC7C3EFCEBBD1F32D\ +6BC7EDCE173A75DE81C5651A3D1DD22A5D63A2763986356331F18BD02D77B036 + +CB2A234F45E2ECD5863895A451D389A369AAB99CFEF0D5C9FFCA1E6E63F763B5\ +C14FB9B478313C8E8C0EFEB3AC9500CF5FD93791B789E67EAC12FD038E2547CC\ +8E0FC9DB591F33A1E4907C64A922DDA23EC9827310B306098554A4A78F050262\ +DB5B545B159E1FF1DCA6EB734B872343B842C57EAFCFDA8405EEDBB48EF32E99\ +696D135979235C3A05364E371C2D76F1902F1D83146DF9495C0A6C57D7BF9EE7\ +7E80F9787AEE27BE1FE126CDC9EF893A4A7DCBBC367E40FE4E1EE90B42EA25AF\ +01:\ +563AAB317672C0DAFC3578FD23DD1416A577D76099B850801C82B03A7FD9037D\ +DC84E7960817B893C2AA5444C46CC5ACED01821E0A299A8BFC13860B6DE3A0C2 + +D16BEADF02AB1D4DC6F88B8C4554C51E866DF830B89C06E786A5F8757E890931\ +0AF51C840EFE8D20B35331F4355D80F73295974653DDD620CDDE4730FB6C8D0D\ +2DCB2B45D92D4FBDB567C0A3E86BD1A8A795AF26FBF29FC6C65941CDDB090FF7\ +CD230AC5268AB4606FCCBA9EDED0A2B5D014EE0C34F0B2881AC036E24E151BE8\ +9EEB6CD9A7A790AFCCFF234D7CB11B99EBF58CD0C589F20BDAC4F9F0E28F75E3\ +E04E5B3DEBCE607A496D848D67FA7B49132C71B878FD5557E082A18ECA1FBDA9\ +4D4B:\ +7365A562E0A02312B2B26D583CA242C479A96F50827B4E87B4E7D4F4B4174C39\ +A76E843FB1D3D2F3731B06161A02BA5E64860D916E607BB5954765B34F57072C + +8F65F6BC59A85705016E2BAE7FE57980DE3127E5AB275F573D334F73F8603106\ +EC3553016608EF2DD6E69B24BE0B7113BF6A760BA6E9CE1C48F9E186012CF96A\ +1D4849D75DF5BB8315387FD78E9E153E76F8BA7EC6C8849810F59FB4BB9B0043\ +18210B37F1299526866F44059E017E22E96CBE418699D014C6EA01C9F0038B10\ +299884DBEC3199BB05ADC94E955A1533219C1115FED0E5F21228B071F40DD57C\ +4240D98D37B73E412FE0FA4703120D7C0C67972ED233E5DEB300A22605472FA3\ +A3BA86:\ +8B9F0CD8D4D56DCB17BB67DB05580A6B67296D4CA8297CA8A705ED9C9948EA9B\ +1DE211D205DF7836DA88C2CEA2ADDA29124E9DD9D5A95AA7E300BFC52E8931DB + +84891E52E0D451813210C3FD635B39A03A6B7A7317B221A7ABC270DFA946C426\ +69AACBBBDF801E1584F330E28C729847EA14152BD637B3D0F2B38B4BD5BF9C79\ +1C58806281103A3EABBAEDE5E711E539E6A8B2CF297CF351C078B4FA8F7F35CF\ +61BEBF8814BF248A01D41E86C5715EA40C63F7375379A7EB1D78F27622FB468A\ +B784AAABA4E534A6DFD1DF6FA15511341E725ED2E87F98737CCB7B6A6DFAE416\ +477472B046BF1811187D151BFA9F7B2BF9ACDB23A3BE507CDF14CFDF517D2CB5\ +FB9E4AB6:\ +34C0FFBFE39B0ABD5B261D66499A8508F360B0D61296DB24E2496C2EDEBE80C2\ +642C12976FA54EF41A766F6722393D7B154AA0BC5C4E20A2CE0527F9A16C3AAC + +FDD7A9433A3B4AFABD7A3A5E3457E56DEBF78E84B7A0B0CA0E8C6D53BD0C2DAE\ +31B2700C6128334F43981BE3B213B1D7A118D59C7E6B6493A86F866A1635C128\ +59CFB9AD17460A77B4522A5C1883C3D6ACC86E6162667EC414E9A104AA892053\ +A2B1D72165A855BACD8FAF8034A5DD9B716F47A0818C09BB6BAF22AA503C06B4\ +CA261F557761989D2AFBD88B6A678AD128AF68672107D0F1FC73C5CA74045929\ +7B3292B281E93BCEB761BDE7221C3A55708E5EC84472CDDCAA84ECF23723CC09\ +91355C6280:\ +2EB1C4BD6D8E41981756A7F83A41D5DF0FC770707AFE22DADEE6BF92DF54096F\ +C4AEB6E0114AC3CBB33BD8D6A47260BAF4127CDE97371979B21E8E32EA205265 + +70A40BFBEF92277A1AAD72F6B79D0177197C4EBD432668CFEC05D099ACCB6510\ +62B5DFF156C0B27336687A94B26679CFDD9DAF7AD204338DD9C4D14114033A5C\ +225BD11F217B5F4732DA167EE3F939262D4043FC9CBA92303B7B5E96AEA12ADD\ +A64859DF4B86E9EE0B58E39091E6B188B408AC94E1294A8911245EE361E60E60\ +1EFF58D1D37639F3753BEC80EBB4EFDE25817436076623FC65415FE51D1B0280\ +366D12C554D86743F3C3B6572E400361A60726131441BA493A83FBE9AFDA90F7\ +AF1AE717238D:\ +18485311BE9C848C38BFA25EC4C557196F1E39A4AC812B77AD2975182A9C2768\ +706905562B0722A2A1B92A56EB47E2500EC1621F59B6B0059EE6FF8C2DB29326 + +74356E449F4BF8644F77B14F4D67CB6BD9C1F5AE357621D5B8147E562B65C665\ +85CAF2E491B48529A01A34D226D436959153815380D5689E30B35357CDAC6E08\ +D3F2B0E88E200600D62BD9F5EAF488DF86A4470EA227006182E44809009868C4\ +C280C43D7D64A5268FA719074960087B3A6ABC837882F882C837834535929389\ +A12B2C78187E2EA07EF8B8EEF27DC85002C3AE35F1A50BEE6A1C48BA7E175F33\ +16670B27983472AA6A61EED0A683A39EE323080620EA44A9F74411AE5CE99030\ +528F9AB49C79F2:\ +753B20F511FD288F732ADE82C0F97D7A05DC4E6B931F7D1D0F266911A3C7DDBA\ +5DB2BB233A12D9508DC071E760844F376AC74CDACC5C8321DB2E6DDA9EF2F9D1 + +8C3798E51BC68482D7337D3ABB75DC9FFE860714A9AD73551E120059860DDE24\ +AB87327222B64CF774415A70F724CDF270DE3FE47DDA07B61C9EF2A3551F45A5\ +584860248FABDE676E1CD75F6355AA3EAEABE3B51DC813D9FB2EAA4F0F1D9F83\ +4D7CAD9C7C695AE84B329385BC0BEF895B9F1EDF44A03D4B410CC23A79A6B62E\ +4F346A5E8DD851C2857995DDBF5B2D717AEB847310E1F6A46AC3D26A7F9B4498\ +5AF656D2B7C9406E8A9E8F47DCB4EF6B83CAACF9AEFB6118BFCFF7E44BEF6937\ +EBDDC89186839B77:\ +E4ECE8FA8A82C0C44328A5B11C0C0EAB3B165A919555B8ECD121A828B0892E16\ +86EF62EAAD10C87B41BCCD85E60F37AEAE96503FBCE970D895E1E1E551CE1A85 + +FA56BF730C4F8395875189C10C4FB251605757A8FECC31F9737E3C2503B02608\ +E6731E85D7A38393C67DE516B85304824BFB135E33BF22B3A23B913BF6ACD2B7\ +AB85198B8187B2BCD454D5E3318CACB32FD6261C31AE7F6C54EF6A7A2A4C9F3E\ +CB81CE3555D4F0AD466DD4C108A90399D70041997C3B25345A9653F3C9A6711A\ +B1B91D6A9D2216442DA2C973CBD685EE7643BFD77327A2F7AE9CB283620A0871\ +6DFB462E5C1D65432CA9D56A90E811443CD1ECB8F0DE179C9CB48BA4F6FEC360\ +C66F252F6E64EDC96B:\ +0C2A1D85CB308CEA8D84108224FC6DA66A2654496A14CAB4457B672EF9BD2D25\ +F0D14098334846F0187D01D74CF8B18C22B3CF9E00ED31F1BE30E960E3C26AF1 + +B6134F9C3E91DD8000740D009DD806240811D51AB1546A974BCB18D344642BAA\ +5CD5903AF84D58EC5BA17301D5EC0F10CCD0509CBB3FD3FFF9172D193AF0F782\ +252FD1338C7244D40E0E42362275B22D01C4C3389F19DD69BDF958EBE28E31A4\ +FFE2B5F18A87831CFB7095F58A87C9FA21DB72BA269379B2DC2384B3DA953C79\ +25761FED324620ACEA435E52B424A7723F6A2357374157A34CD8252351C25A1B\ +232826CEFE1BD3E70FFC15A31E7C0598219D7F00436294D11891B82497BC78AA\ +5363892A2495DF8C1EEF:\ +46C390535747C9C16A4797C28DDEE9C2CECC3B8F1A89EE67C91A0D06220E6633\ +9E7B4A7D6C6B2B27D0A011D51BF7EA0DD61E6124D329269BCD4B92273C2A311D + +C941CDB9C28AB0A791F2E5C8E8BB52850626AA89205BEC3A7E22682313D198B1\ +FA33FC7295381354858758AE6C8EC6FAC3245C6E454D16FA2F51C4166FAB51DF\ +272858F2D603770C40987F64442D487AF49CD5C3991CE858EA2A60DAB6A65A34\ +414965933973AC2457089E359160B7CDEDC42F29E10A91921785F6B7224EE0B3\ +49393CDCFF6151B50B377D609559923D0984CDA6000829B916AB6896693EF6A2\ +199B3C22F7DC5500A15B8258420E314C222BC000BC4E5413E6DD82C993F8330F\ +5C6D1BE4BC79F08A1A0A46:\ +6C7060DBE2F17BAE9F4503FA61FCB2B3C6F9F8E1710FD2092CAB5865E05C6E3A\ +9A5D2E5A94E4C9DAFB9F3E47E52A6644990D8F397C93DAD4546A7C1C35BE8CA7 + +4499EFFFAC4BCEA52747EFD1E4F20B73E48758BE915C88A1FFE5299B0B005837\ +A46B2F20A9CB3C6E64A9E3C564A27C0F1C6AD1960373036EC5BFE1A8FC6A435C\ +2185ED0F114C50E8B3E4C7ED96B06A036819C9463E864A58D6286F785E32A804\ +443A56AF0B4DF6ABC57ED5C2B185DDEE8489EA080DEEEE66AA33C2E6DAB36251\ +C402682B6824821F998C32163164298E1FAFD31BABBCFFB594C91888C6219079\ +D907FDB438ED89529D6D96212FD55ABE20399DBEFD342248507436931CDEAD49\ +6EB6E4A80358ACC78647D043:\ +A614F68BE815612E5E571B06DC69C3C86A8A4EFF9BBA9A981413F60C7B612B90\ +6A7805BE3E292F1154CB0E1B003B86F40B23B99C579DA381D06C734E60A49806 + +EECBB8FDFA4DA62170FD06727F697D81F83F601FF61E478105D3CB7502F2C89B\ +F3E8F56EDD469D049807A38882A7EEFBC85FC9A950952E9FA84B8AFEBD3CE782\ +D4DA598002827B1EB98882EA1F0A8F7AA9CE013A6E9BC462FB66C8D4A18DA214\ +01E1B93356EB12F3725B6DB1684F2300A98B9A119E5D27FF704AFFB618E12708\ +E77E6E5F34139A5A41131FD1D6336C272A8FC37080F041C71341BEE6AB550CB4\ +A20A6DDB6A8E0299F2B14BC730C54B8B1C1C487B494BDCCFD3A53535AB2F2315\ +90BF2C4062FD2AD58F906A2D0D:\ +402CC283CF76060F64F0DE59D14910D710221F63537D5E30A1388496CC2260DE\ +1E3BCACE354FC1AB344458DD9BEDF3FC36336D67B10EF21FC6D6F48ACD265C8D + +E64F3E4ACE5C8418D65FEC2BC5D2A303DD458034736E3B0DF719098BE7A206DE\ +AF52D6BA82316CAF330EF852375188CDE2B39CC94AA449578A7E2A8E3F5A9D68\ +E816B8D16889FBC0EBF0939D04F63033AE9AE2BDAB73B88C26D6BD25EE460EE1\ +EF58FB0AFA92CC539F8C76D3D097E7A6A63EBB9B5887EDF3CF076028C5BBD5B9\ +DB3211371AD3FE121D4E9BF44229F4E1ECF5A0F9F0EBA4D5CEB72878AB22C3F0\ +EB5A625323AC66F7061F4A81FAC834471E0C59553F108475FE290D43E6A055AE\ +3EE46FB67422F814A68C4BE3E8C9:\ +AEF42FDB10807FDAEA631638A64C06A9125CDB7F94BB91AB345E1EA30E606FC5\ +FBC6322075A50FE2D13D19FD34AB072C41B96CED205CC5143A1A5C98DEA311D0 + +D2CB2D733033F9E91395312808383CC4F0CA974E87EC68400D52E96B3FA6984A\ +C58D9AD0938DDE5A973008D818C49607D9DE2284E7618F1B8AED8372FBD52ED5\ +4557AF4220FAC09DFA8443011699B97D743F8F2B1AEF3537EBB45DCC9E13DFB4\ +38428EE190A4EFDB3CAEB7F3933117BF63ABDC7E57BEB4171C7E1AD260AB0587\ +806C4D137B6316B50ABC9CCE0DFF3ACADA47BBB86BE777E617BBE578FF451984\ +4DB360E0A96C6701290E76BB95D26F0F804C8A4F2717EAC4E7DE9F2CFF3BBC55\ +A17E776C0D02856032A6CD10AD2838:\ +391C3A33EC4B5D75C910DF0F00F6AD5D4E8844CDB364B2D7B0155BDD4F9C0E1B\ +6C7825938F642840D06CD0E6F67F87DCCC34F6FD83587FD9266D603CA625548F + +F2998955613DD414CC111DF5CE30A995BB792E260B0E37A5B1D942FE90171A4A\ +C2F66D4928D7AD377F4D0554CBF4C523D21F6E5F379D6F4B028CDCB9B1758D3B\ +39663242FF3CB6EDE6A36A6F05DB3BC41E0D861B384B6DEC58BB096D0A422FD5\ +42DF175E1BE1571FB52AE66F2D86A2F6824A8CFAACBAC4A7492AD0433EEB1545\ +4AF8F312B3B2A577750E3EFBD370E8A8CAC1582581971FBA3BA4BD0D76E718DA\ +CF8433D33A59D287F8CC92234E7A271041B526E389EFB0E40B6A18B3AAF658E8\ +2ED1C78631FD23B4C3EB27C3FAEC8685:\ +E51079072C571D0E44C975F232F052F78B497A1C85995E194691A85AB026E4F8\ +0A4993D3A2B4D69F607558CEFF54D766915E5A4E0C7A42C8D307FA03C6DC4C74 + +447797E2899B72A356BA55BF4DF3ACCA6CDB1041EB477BD1834A9F9ACBC340A2\ +94D729F2F97DF3A610BE0FF15EDB9C6D5DB41644B9874360140FC64F52AA03F0\ +286C8A640670067A84E017926A70438DB1BB361DEFEE7317021425F8821DEF26\ +D1EFD77FC853B818545D055ADC9284796E583C76E6FE74C9AC2587AA46AA8F88\ +04F2FEB5836CC4B3ABABAB8429A5783E17D5999F32242EB59EF30CD7ADABC16D\ +72DBDB097623047C98989F88D14EAF02A7212BE16EC2D07981AAA99949DDF89E\ +CD90333A77BC4E1988A82ABF7C7CAF3291:\ +019BE27AC6E4B1FB3F1602025A8DE3EFA7AD6E1D0C6975E8D2D519A997328154\ +FE0738A00366205FDF8467B36D8970A92EF450C20F5BEC013BA4CF8091F571CB + +9F2C18ADE9B380C784E170FB763E9AA205F64303067EB1BCEA93DF5DAC4BF5A2\ +E00B78195F808DF24FC76E26CB7BE31DC35F0844CDED1567BBA29858CFFC97FB\ +29010331B01D6A3FB3159CC1B973D255DA9843E34A0A4061CABDB9ED37F241BF\ +ABB3C20D32743F4026B59A4CCC385A2301F83C0B0A190B0F2D01ACB8F0D41111\ +E10F2F4E149379275599A52DC089B35FDD5234B0CFB7B6D8AEBD563CA1FA653C\ +5C021DFD6F5920E6F18BFAFDBECBF0AB00281333ED50B9A999549C1C8F8C63D7\ +626C48322E9791D5FF72294049BDE91E73F8:\ +B996713F0A3AB5F0198C127B5C3079DACE7D4D98A9433D9B790833B62395A379\ +7B7924EB8B9F586903079A8413597E37448F3222B751DEBE8A5B83385864F7B8 + +AE159F3FA33619002AE6BCCE8CBBDD7D28E5ED9D61534595C4C9F43C402A9BB3\ +1F3B301CBFD4A43CE4C24CD5C9849CC6259ECA90E2A79E01FFBAC07BA0E147FA\ +42676A1D668570E0396387B5BCD599E8E66AAED1B8A191C5A47547F61373021F\ +A6DEADCB55363D233C24440F2C73DBB519F7C9FA5A8962EFD5F6252C0407F190\ +DFEFAD707F3C7007D69FF36B8489A5B6B7C557E79DD4F50C06511F599F56C896\ +B35C917B63BA35C6FF8092BAF7D1658E77FC95D8A6A43EEB4C01F33F03877F92\ +774BE89C1114DD531C011E53A34DC248A2F0E6:\ +FB71A3351EA2FD4C44E271EA793596B245C6F0634E79ED1EC72C6A4CC9DBC892\ +A9498A7ACA0915AB20B0DAED223FAD794A6F3822C847CF52B3F217D0BC605B76 + +3B8E97C5FFC2D6A40FA7DE7FCEFC90F3B12C940E7AB415321E29EE692DFAC799\ +B009C99DCDDB708FCE5A178C5C35EE2B8617143EDC4C40B4D313661F49ABDD93\ +CEA79D117518805496FE6ACF292C4C2A1F76B403A97D7C399DAF85B46AD84E16\ +246C67D6836757BDE336C290D5D401E6C1386AB32797AF6BB251E9B2D8FE754C\ +47482B72E0B394EAB76916126FD68EA7D65EB93D59F5B4C5AC40F7C3B37E7F36\ +94F29424C24AF8C8F0EF59CD9DBF1D28E0E10F799A6F78CAD1D45B9DB3D7DEE4\ +A7059ABE99182714983B9C9D44D7F5643596D4F3:\ +DBD3650B1739E8DA775381B5521C5CFDD689FE81309B3A69A4B3BCDC62DD6C45\ +68B84670E5E3B1B4E0E834600C36167E3447C5C1009E680C7932DB2BD91057A9 + +3434EC31B10FAFDBFEEC0DD6BD94E80F7BA9DCA19EF075F7EB017512AF66D6A4\ +BCF7D16BA0819A1892A6372F9B35BCC7CA8155EE19E8428BC22D214856ED5FA9\ +374C3C09BDE169602CC219679F65A1566FC7316F4CC3B631A18FB4449FA6AFA1\ +6A3DB2BC4212EFF539C67CF184680826535589C7111D73BFFCE431B4C40492E7\ +63D9279560AAA38EB2DC14A212D723F994A1FE656FF4DD14551CE4E7C621B2AA\ +5604A10001B2878A897A28A08095C325E10A26D2FB1A75BFD64C250309BB55A4\ +4F23BBAC0D5516A1C687D3B41EF2FBBF9CC56D4739:\ +55B84F2AC0B917467F20E9EC5F6CE98B3987C59A1ACAEFE3AD73D1C26D724CA0\ +C4D8052CE82E3C704C7834499BEC67620D4B073BF3DA41AAD2DE69AFA4943E3B + +7C7953D81C8D208FD1C97681D48F49DD003456DE60475B84070EF4847C333B74\ +575B1FC8D2A186964485A3B8634FEAA3595AAA1A2F4595A7D6B6153563DEE31B\ +BAC443C8A33EED6D5D956A980A68366C2527B550EE950250DFB691EACBD5D56A\ +E14B970668BE174C89DF2FEA43AE52F13142639C884FD62A3683C0C3792F0F24\ +AB1318BCB27E21F4737FAB62C77EA38BC8FD1CF41F7DAB64C13FEBE7152BF5BB\ +7AB5A78F5346D43CC741CB6F72B7B8980F268B68BF62ABDFB1577A52438FE14B\ +591498CC95F071228460C7C5D5CEB4A7BDE588E7F21C:\ +AD4231D8A6C04C1517D1091D399110019055D5C5EE1D3D75456DA17C5572C10B\ +B8B808493C3A69EBD668AFFD15A9E92A692A3C7A394F929B1E7798E692979665 + +7A6A4F4FDC59A1D223381AE5AF498D74B7252ECF59E389E49130C7EAEE626E7B\ +D9897EFFD92017F4CCDE66B0440462CDEDFD352D8153E6A4C8D7A0812F701CC7\ +37B5178C2556F07111200EB627DBC299CAA792DFA58F35935299FA3A3519E9B0\ +3166DFFA159103FFA35E8577F7C0A86C6B46FE13DB8E2CDD9DCFBA85BDDDCCE0\ +A7A8E155F81F712D8E9FE646153D3D22C811BD39F830433B2213DD46301941B5\ +9293FD0A33E2B63ADBD95239BC01315C46FDB678875B3C81E053A40F581CFBEC\ +24A1404B1671A1B88A6D06120229518FB13A74CA0AC5AE:\ +70CDAED98ECA25B7099C73201427DE23F51D7115160A105DED7A2FB6B20F2DEB\ +31B6A2734CFFC2AA6189DAEA538291B34D0AAC7CA9C57CA7063A31EF202F38EC + +D9FAA14CEBE9B7DE551B6C0765409A33938562013B5E8E0E1E0A6418DF7399D0\ +A6A771FB81C3CA9BD3BB8E2951B0BC792525A294EBD1083688806FE5E7F1E17F\ +D4E3A41D00C89E8FCF4A363CAEDB1ACB558E3D562F1302B3D83BB886ED27B760\ +33798131DAB05B4217381EAAA7BA15EC820BB5C13B516DD640EAEC5A27D05FDF\ +CA0F35B3A5312146806B4C0275BCD0AAA3B2017F346975DB566F9B4D137F4EE1\ +0644C2A2DA66DEECA5342E236495C3C6280528BFD32E90AF4CD9BB908F34012B\ +52B4BC56D48CC8A6B59BAB014988EABD12E1A0A1C2E170E7:\ +45186098139174A1D4D657A79B71E6E4FB3AE790A52FF0A1690D787FCB6FBA70\ +25CF74E3CDBFAA5B2B6D1880699315FAC59FB18714C65D5EA66E6B1D47AE17C4 + +2D8427433D0C61F2D96CFE80CF1E932265A191365C3B61AAA3D6DCC039F6BA2A\ +D52A6A8CC30FC10F705E6B7705105977FA496C1C708A277A124304F1FC40911E\ +7441D1B5E77B951AAD7B01FD5DB1B377D165B05BBF898042E39660CAF8B279FE\ +5229D1A8DB86C0999ED65E53D01CCBC4B43173CCF992B3A14586F6BA42F5FE30\ +AFA8AE40C5DF29966F9346DA5F8B35F16A1DE3AB6DE0F477D8D8660918060E88\ +B9B9E9CA6A4207033B87A812DBF5544D39E4882010F82B6CE005F8E8FF6FE3C3\ +806BC2B73C2B83AFB704345629304F9F86358712E9FAE3CA3E:\ +7E804307383AFF5BCC80306043721A173E61461E401C1331ED95B8ADB1CFF5CD\ +0943CB3BA8C9A7A02987DD9B6EA2912368284CF14A55566BF264CC244A353227 + +5E19D97887FCAAC0387E22C6F803C34A3DACD2604172433F7A8A7A526CA4A2A1\ +271ECFC5D5D7BE5AC0D85D921095350DFC65997D443C21C8094E0A3FEFD2961B\ +CB94AED03291AE310CCDA75D8ACE4BC7D89E7D3E5D1650BDA5D668B8B50BFC8E\ +608E184F4D3A9A2BADC4FF5F07E0C0BC8A9F2E0B2A26FD6D8C550008FAAAB75F\ +D71AF2A424BEC9A7CD9D83FAD4C8E9319115656A8717D3B523A68FF8004258B9\ +990ED362308461804BA3E3A7E92D8F2FFAE5C2FBA55BA5A3C27C0A2F71BD711D\ +2FE1799C2ADB31B200035481E9EE5C4ADF2AB9C0FA50B23975CF:\ +8B907F2B968634263C0CC229E917FDF0AD93D637299C10D8F76EFFEE6C6A6B83\ +85803FABEDEB1694EACBC11D94FD00CD310C287C2C537BDE39B88A4A15735DF3 + +C8E976AB4638909387CE3B8D4E510C3230E5690E02C45093B1D297910ABC481E\ +56EEA0F296F98379DFC9080AF69E73B2399D1C143BEE80AE1328162CE1BA7F6A\ +8374679B20AACD380EB4E61382C99998704D62701AFA914F9A2705CDB065885F\ +50D086C3EB5753700C387118BB142F3E6DA1E988DFB31AC75D7368931E45D139\ +1A274B22F83CEB072F9BCABC0B216685BFD789F5023971024B1878A205442522\ +F9EA7D8797A4102A3DF41703768251FD5E017C85D1200A464118AA35654E7CA3\ +9F3C375B8EF8CBE7534DBC64BC20BEFB417CF60EC92F63D9EE7397:\ +4739DB195476A74B06835BA91DD8DFDADE704A06557307E33019738083F36714\ +3C96ECF28523C1BE8CA272ADF7E0EEBB64EEF31FE4C5EF03CE7D46ED6FC86A71 + +7145FA124B7429A1FC2231237A949BA7201BCC1822D3272DE005B682398196C2\ +5F7E5CC2F289FBF44415F699CB7FE6757791B1443410234AE061EDF623359E2B\ +4E32C19BF88450432DD01CAA5EB16A1DC378F391CA5E3C4E5F356728BDDD4975\ +DB7C890DA8BBC84CC73FF244394D0D48954978765E4A00B593F70F2CA082673A\ +261ED88DBCEF1127728D8CD89BC2C597E9102CED6010F65FA75A14EBE467FA57\ +CE3BD4948B6867D74A9DF5C0EC6F530CBF2EE61CE6F06BC8F2864DFF5583776B\ +31DF8C7FFCB61428A56BF7BD37188B4A5123BBF338393AF46EDA85E6:\ +68B8AA5731F7D00D547D7E3690761046B54E91257984A46E2CF9BA2835ADB621\ +CE3DDCF81A02A95308300F1E992E3BEDF832FC0433F0A64D5CE277E679933E47 + +7FDFADCC9D29BAD23AE038C6C65CDA1AEF757221B8872ED3D75FF8DF7DA0627D\ +266E224E812C39F7983E4558BFD0A1F2BEF3FEB56BA09120EF762917B9C09386\ +7948547AEE98600D10D87B20106878A8D22C64378BF634F7F75900C03986B077\ +B0BF8B740A82447B61B99FEE5376C5EB6680EC9E3088F0BDD0C56883413D60C1\ +357D3C811950E5890E7600103C916341B80C743C6A852B7B4FB60C3BA21F3BC1\ +5B8382437A68454779CF3CD7F9F90CCC8EF28D0B706535B1E4108EB5627BB45D\ +719CB046839AEE311CA1ABDC8319E050D67972CB35A6B1601B25DBF487:\ +2CD87427875CC3480CD19F567B049B1181D7F46B85F3CDE505005452A0401A51\ +7E0E3D2A2157D789A6D63C8484386EFA9F9717498D35B20CA2A0FD2FDDDF7E15 + +988638219FD3095421F826F56E4F09E356296B628C3CE6930C9F2E758FD1A80C\ +8273F2F61E4DAAE65C4F110D3E7CA0965AC7D24E34C0DC4BA2D6FF0BF5BBE93B\ +3585F354D7543CB542A1AA54674D375077F2D360A8F4D42F3DB131C3B7AB7306\ +267BA107659864A90C8C909460A73621D1F5D9D3FD95BEB19B23DB1CB6C0D0FB\ +A91D36891529B8BD8263CAA1BAB56A4AFFAED44962DF096D8D5B1EB845EF3118\ +8B3E10F1AF811A13F156BEB7A288AAE593EBD1471B624AA1A7C6ADF01E2200B3\ +D72D88A3AED3100C88231E41EFC376906F0B580DC895F080FDA5741DB1CB:\ +5E0A947E07586E1A7EB441B4F44211F3731595E273FBE30FD5478E762C08411D\ +B9DDAA9F9B9D860F5768DF78FBEAF9EFEB9ECAEE9A9874FD38E9EBDE9DDF11E7 + +5AAB62756D307A669D146ABA988D9074C5A159B3DE85151A819B117CA1FF6597\ +F6156E80FDD28C9C3176835164D37DA7DA11D94E09ADD770B68A6E081CD22CA0\ +C004BFE7CD283BF43A588DA91F509B27A6584C474A4A2F3EE0F1F56447379240\ +A5AB1FB77FDCA49B305F07BA86B62756FB9EFB4FC225C86845F026EA542076B9\ +1A0BC2CDD136E122C659BE259D98E5841DF4C2F60330D4D8CDEE7BF1A0A24452\ +4EECC68FF2AEF5BF0069C9E87A11C6E519DE1A4062A10C83837388F7EF58598A\ +3846F49D499682B683C4A062B421594FAFBC1383C943BA83BDEF515EFCF10D:\ +B8098CB26FCC5ACD64C492919EA1C7ECDC9B3DE4854D69E7947E05BD0BF6E84C\ +240FA83ACEE02C829A959614107CE03DB8ACA40D38F9CC57B7F94C3C220DEEEB + +47B8216AA0FBB5D67966F2E82C17C07AA2D6327E96FCD83E3DE7333689F3EE79\ +994A1BF45082C4D725ED8D41205CB5BCDF5C341F77FACB1DA46A5B9B2CBC49EA\ +DF786BCD881F371A95FA17DF73F606519AEA0FF79D5A11427B98EE7F13A5C006\ +37E2854134691059839121FEA9ABE2CD1BCBBBF27C74CAF3678E05BFB1C94989\ +7EA01F56FFA4DAFBE8644611685C617A3206C7A7036E4AC816799F693DAFE7F1\ +9F303CE4EBA09D21E03610201BFC665B72400A547A1E00FA9B7AD8D84F84B34A\ +EF118515E74DEF11B9188BD1E1F97D9A12C30132EC2806339BDADACDA2FD8B78:\ +0F4C4ECFD9A8431D5AB9A245A77CD70974FB75F1824FE68583E9F25E73BA5725\ +88AD0C328D73BEBEDF1FC99D898B7D1C9EB9AB048896CD0446A3E932A97710AB + +8CFF1F67FE53C098896D9136389BD8881816CCAB34862BB67A656E3D98896F3C\ +E6FFD4DA73975809FCDF9666760D6E561C55238B205D8049C1CEDEEF374D1735\ +DAA533147BFA960B2CCE4A4F254176BB4D1BD1E89654432B8DBE1A135C42115B\ +394B024856A2A83DC85D6782BE4B444239567CCEC4B184D4548EAE3FF6A192F3\ +43292BA2E32A0F267F31CC26719EB85245D415FB897AC2DA433EE91A99424C9D\ +7F1766A44171D1651001C38FC79294ACCC68CEB5665D36218454D3BA169AE058\ +A831338C17743603F81EE173BFC0927464F9BD728DEE94C6AEAB7AAE6EE3A627\ +E8:\ +C90025BE7F02FA18134B63681B5A635A51C06EE37878C4833E0A853FA474AEFD\ +06BEEBA4597ED8E59255EE4DEC81B34D6EF3DF617A885F50B79F6EF9E47B4003 + +EACD07971CFF9B9939903F8C1D8CBB5D4DB1B548A85D04E037514A583604E787\ +F32992BF2111B97AC5E8A938233552731321522AB5E8583561260B7D13EBEEF7\ +85B23A41FD8576A6DA764A8ED6D822D4957A545D5244756C18AA80E1AAD4D1F9\ +C20D259DEE1711E2CC8FD013169FB7CC4CE38B362F8E0936AE9198B7E838DCEA\ +4F7A5B9429BB3F6BBCF2DC92565E3676C1C5E6EB3DD2A0F86AA23EDD3D0891F1\ +97447692794B3DFA269611AD97F72B795602B4FDB198F3FD3EB41B415064256E\ +345E8D8C51C555DC8A21904A9B0F1AD0EFFAB7786AAC2DA3B196507E9F33CA35\ +6427:\ +5C21E22D8B2887134F03D05945D91282B6321F122E53640C046FF9B1692F1210\ +CA46CD8471E95F3C74F7FEB1DA0DC8A421EEFFB3699351825F16BA621015EEEF + +23AC4E9A42C6EF45C3336CE6DFC2FF7DE8884CD23DC912FEF0F7756C09D335C1\ +89F3AD3A23697ABDA851A81881A0C8CCAFC980AB2C702564C2BE15FE4C4B9F10\ +DFB2248D0D0CB2E2887FD4598A1D4ACDA897944A2FFC580FF92719C95CF2AA42\ +DC584674CB5A9BC5765B9D6DDF5789791D15F8DD925AA12BFFAFBCE60827B490\ +BB7DF3DDA6F2A143C8BF96ABC903D83D59A791E2D62814A89B8080A28060568C\ +F24A80AE61179FE84E0FFAD00388178CB6A617D37EFD54CC01970A4A41D1A8D3\ +DDCE46EDBBA4AB7C90AD565398D376F431189CE8C1C33E132FEAE6A8CD17A61C\ +630012:\ +F1A7011447E8515E1502A3AE56F8BE61EB4200BC4D21C8E1875B73AB2A42DE46\ +13D6404B17A740B60B57F742C92F45C07880498C44C989C15CF1CD37B3F26E77 + +0172DF732282C9D488669C358E3492260CBE91C95CFBC1E3FEA6C4B0EC129B45\ +F242ACE09F152FC6234E1BEE8AAB8CD56E8B486E1DCBA9C05407C2F95DA8D8F1\ +C0AF78EE2ED82A3A79EC0CB0709396EE62AADB84F8A4EE8A7CCCA3C1EE84E302\ +A09EA802204AFECF04097E67D0F8E8A9D2651126C0A598A37081E42D168B0AE8\ +A71951C524259E4E2054E535B779679BDADE566FE55700858618E626B4A0FAF8\ +95BCCE9011504A49E05FD56127EAE3D1F8917AFB548ECADABDA1020111FEC931\ +4C413498A360B08640549A22CB23C731ACE743252A8227A0D2689D4C60016066\ +78DFB921:\ +02BE97BE60F581D73527490734CD5F8739DCB9A5089CC49C7619277CEB30D9A6\ +9B85C53EFC55C780A6494DD172B8BEB2B69F86DD4B7CBFA3E47F1720ED394383 + +3875B9240CF3E0A8B59C658540F26A701CF188496E2C2174788B126FD29402D6\ +A75453BA0635284D08835F40051A2A9683DC92AFB9383719191231170379BA6F\ +4ADC816FECBB0F9C446B785BF520796841E58878B73C58D3EBB097CE4761FDEA\ +BE15DE2F319DFBAF1742CDEB389559C788131A6793E193856661376C81CE9568\ +DA19AA6925B47FFD77A43C7A0E758C37D69254909FF0FBD415EF8EB937BCD49F\ +91468B49974C07DC819ABD67395DB0E05874FF83DDDAB895344ABD0E7111B2DF\ +9E58D76D85AD98106B36295826BE04D435615595605E4B4BB824B33C4AFEB5E7\ +BB0D19F909:\ +38652A2D6674A539559F3ED0996542C23D48D8D108C2AF9C10DA45C9DBC11906\ +CB4AEE8EB04C88789B763C66B743356336C8950303B950D72A8FCA05B9C67CD9 + +747CC1A59FEFBA94A9C75BA866C30DC5C1CB0C0F8E9361D98484956DD5D1A40F\ +6184AFBE3DAC9F76028D1CAECCFBF69199C6CE2B4C092A3F4D2A56FE5A33A007\ +57F4D7DEE5DFB0524311A97AE0668A47971B95766E2F6DD48C3F57841F91F04A\ +00AD5EA70F2D479A2620DC5CD78EAAB3A3B011719B7E78D19DDF70D9423798AF\ +77517EBC55392FCD01FC600D8D466B9E7A7A85BF33F9CC5419E9BD874DDFD609\ +81150DDAF8D7FEBAA4374F0872A5628D318000311E2F5655365AD4D407C20E5C\ +04DF17A222E7DEEC79C5AB1116D8572F91CD06E1CCC7CED53736FC867FD49ECE\ +BE6BF8082E8A:\ +BC091874BAF2195324C56EE8386E13AC3F49FDB329C2D5835848AF2A3653BCEA\ +26EC8C370912CBCFB1C20D3EB9AB53C6160CDD5351836527C5719084A575EF64 + +57AF971FCCAEC97435DC2EC9EF0429BCEDC6B647729EA168858A6E49AC1071E7\ +06F4A5A645CA14E8C7746D65511620682C906C8B86EC901F3DDED4167B3F00B0\ +6CBFAC6AEE3728051B3E5FF10B4F9ED8BD0B8DA94303C833755B3CA3AEDDF0B5\ +4BC8D6632138B5D25BAB03D17B3458A9D782108006F5BB7DE75B5C0BA854B423\ +D8BB801E701E99DC4FEAAD59BC1C7112453B04D33EA3635639FB802C73C2B71D\ +58A56BBD671B18FE34ED2E3DCA38827D63FDB1D4FB3285405004B2B3E26081A8\ +FF08CD6D2B08F8E7B7E90A2AB1ED7A41B1D0128522C2F8BFF56A7FE67969422C\ +E839A9D4608F03:\ +D8025F57C003DDCC6ABDDCE2CCFFDB9C11BE984311A749A632D7EE4EB073C58F\ +0074096C17CE0A46B37700581D9FF074143F34322D5460C4BD1E9EE6AD497F40 + +04E16DEDC1227902BAAF332D3D08923601BDD64F573FAA1BB7201918CFE16B1E\ +10151DAE875DA0C0D63C59C3DD050C4C6A874011B018421AFC4623AB0381831B\ +2DA2A8BA42C96E4F70864AC44E106F94311051E74C77C1291BF5DB9539E69567\ +BF6A11CF6932BBBAD33F8946BF5814C066D851633D1A513510039B349939BFD4\ +2B858C21827C8FF05F1D09B1B0765DC78A135B5CA4DFBA0801BCADDFA175623C\ +8B647EACFB4444B85A44F73890607D06D507A4F8393658788669F6EF4DEB58D0\ +8C50CA0756D5E2F49D1A7AD73E0F0B3D3B5F090ACF622B1878C59133E4A848E0\ +5153592EA81C6FBF:\ +99812EB8737BF609B3BF4B8ADE116403183DD7332DAB4F43BB4917DA0B62ABC5\ +A4772D572BDDA22FD555AF55309D31FB93492ED3EF4455FDE4FFFE7BF8DF84AE + +7C815C384EEE0F288ECE27CCED52A01603127B079C007378BC5D1E6C5E9E6D1C\ +735723ACBBD5801AC49854B2B569D4472D33F40BBB8882956245C366DC3582D7\ +1696A97A4E19557E41E54DEE482A14229005F93AFD2C4A7D8614D10A97A9DFA0\ +7F7CD946FA45263063DDD29DB8F9E34DB60DAA32684F0072EA2A9426ECEBFA52\ +39FB67F29C18CBAA2AF6ED4BF4283936823AC1790164FEC5457A9CBA7C767CA5\ +9392D94CAB7448F50EB34E9A93A80027471CE59736F099C886DEA1AB4CBA4D89\ +F5FC7AE2F21CCD27F611ECA4626B2D08DC22382E92C1EFB2F6AFDC8FDC3D2172\ +604F5035C46B8197D3:\ +6B242888A6E956F10A8BE75E09287D59CC25155B0AA8D8BA02E095D0AFAA2910\ +4CB2051AA4B3430B724D500AD0317208C3BA9FB1265BF19A974E90F4BF0CE006 + +E29D505158DBDD937D9E3D2145658EE6F5992A2FC790F4F608D9CDB44A091D5B\ +94B88E81FAC4FDF5C49442F13B911C55886469629551189EAFF62488F1A479B7\ +DB11A1560E198DDCCCCF50159093425FF7F1CB8D1D1246D0978764087D6BAC25\ +7026B090EFAE8CEC5F22B6F21C59ACE1AC7386F5B8837CA6A12B6FBF5534DD05\ +60EF05CA78104D3B943DDB220FEAEC89AA5E692A00F822A2AB9A2FE60350D75E\ +7BE16FF2526DC643872502D01F42F188ABED0A6E9A6F5FD0D1CE7D5755C9FFA6\ +6B0AF0B20BD806F08E06156690D81AC811778CA3DAC2C249B96002017FCE93E5\ +07E3B953ACF99964B847:\ +FF77EF8DE1483F8A498E3554083BB69F7567FCED495E6BF0C9902CDCB5247FAC\ +6A4B50D1CF9CEE89C400ED3E4E6FEBB642F1AC3BBD018ECC04CB1A43A1331ECC + +D85588696F576E65ECA0155F395F0CFACD83F36A99111ED5768DF2D116D2121E\ +32357BA4F54EDE927F189F297D3A97FAD4E9A0F5B41D8D89DD7FE20156799C2B\ +7B6BF9C957BA0D6763F5C3BC5129747BBB53652B49290CFF1C87E2CDF2C4B95D\ +8AAEE09BC8FBFA6883E62D237885810491BFC101F1D8C636E3D0EDE838AD05C2\ +07A3DF4FAD76452979EB99F29AFAECEDD1C63B8D36CF378454A1BB67A741C77A\ +C6B6B3F95F4F02B64DABC15438613EA49750DF42EE90101F115AA9ABB9FF6432\ +4DDE9DABBB01054E1BD6B4BCDC7930A44C2300D87CA78C06924D0323AD7887E4\ +6C90E8C4D100ACD9EED21E:\ +83E0BEDD263922F016CF539F9E7B43ACAFDDF35C8CE730434EE3E92ACD264006\ +031073A705F5585BFB66E53EA6A733901AE40634B6F4D86FB554CE0EBC5CD807 + +3A12F8508B40C32C74492B66323375DCFE49184C78F73179F3314B79E63376B8\ +AC683F5A51F1534BD729B02B04D002F55CBD8E8FC9B5EC1EA6BBE6A0D0E74315\ +18E6BA45D124035F9D3DCE0A8BB7BF1430A9F657E0B4EA9F20EB20C786A58181\ +A1E20A96F1628F8728A13BDF7A4B4B32FC8AA7054CC4881AE7FA19AFA65C6C3E\ +E1B3ADE3192AF42054A8A911B8EC1826865D46D93F1E7C5E2B7813C92A506E53\ +886F3D4701BB93D2A681AD109C845904BB861AF8AF0646B6E399B38B614051D3\ +4F6842563A0F37EC00CB3D865FC5D746C4987DE2A65071100883A2A9C7A2BFE1\ +E2DD603D9EA24DC7C5FD06BE:\ +E063490AC5C915BAF98C37660EB17A85798D728FB57CB0ACFAEDE8AFE847C902\ +5D8BF55B6EEA096A6F0B443B38D0BC77DD0BCB8228ED2681BB03A013D15CEB79 + +1861EDCE46FA5AD17E1FF1DEAE084DEC580F97D0A67885DFE834B9DFAC1AE076\ +742CE9E267512CA51F6DF5A455AF0C5FD6ABF94ACEA103A3370C354485A7846F\ +B84F3AC7C2904B5B2FBF227002CE512133BB7E1C4E50057BFD1E44DB33C7CDB9\ +69A99E284B184F50A14B068A1FC5009D9B298DBE92239572A7627AAC02ABE8F3\ +E3B473417F36D4D2505D16B7577F4526C9D94A270A2DFE450D06DA8F6FA95687\ +9A0A55CFE99E742EA555EA477BA3E9B44CCD508C375423611AF92E55345DC215\ +779B2D5119EBA49C71D49B9FE3F1569FA24E5CA3E332D042422A8B8158D3EC66\ +A80012976F31FFDF305F0C9C5E:\ +2F2FBA371016CD20ADC35C032B61100C298FBAF81506E83CC6E9BCC61244838A\ +D83465658A6436BD488C55D27B82BA3FFC5223BB97A03AE33E05CA750FDF56E2 + +08D0FFDE3A6E4EF65608EA672E4830C12943D7187CCFF08F4941CFC13E545F3B\ +9C7AD5EEBBE2B01642B486CAF855C2C73F58C1E4E3391DA8E2D63D96E15FD849\ +53AE5C231911B00AD6050CD7AAFDAAC9B0F663AE6AAB45519D0F5391A541707D\ +479034E73A6AD805AE3598096AF078F1393301493D663DD71F83869CA27BA508\ +B7E91E81E128C1716DC3ACFE3084B2201E04CF8006617EECF1B640474A5D45CF\ +DE9F4D3EF92D6D055B909892194D8A8218DB6D8203A84261D200D71473D7488F\ +3427416B6896C137D455F231071CACBC86E0415AB88AEC841D96B7B8AF41E05B\ +B461A40645BF176601F1E760DE5F:\ +783AF05873F418BAF09AA3479FFBA6CC9949F90D7CB9DF1355B46B020712EDD4\ +0477F7B2980DEFC4474B2D3C24BF92ECB5DA64FBDF167EDD9D9D48792D2B4DF8 + +D782ABB72A5BE3392757BE02D3E45BE6E2099D6F000D042C8A543F50ED6EBC05\ +5A7F133B0DD8E9BC348536EDCAAE2E12EC18E8837DF7A1B3C87EC46D50C241DE\ +E820FD586197552DC20BEEA50F445A07A38F1768A39E2B2FF05DDDEDF751F1DE\ +F612D2E4D810DAA3A0CC904516F9A43AF660315385178A529E51F8AAE141808C\ +8BC5D7B60CAC26BB984AC1890D0436EF780426C547E94A7B08F01ACBFC4A3825\ +EAE04F520A9016F2FB8BF5165ED12736FC71E36A49A73614739EAA3EC834069B\ +1B40F1350C2B3AB885C02C640B9F7686ED5F99527E41CFCD796FE4C256C91731\ +86C226169FF257954EBDA81C0E5F99:\ +B53D11E8514950F60345F266290DFD57B8550C011F2BBC1C7CD718E74CAA9847\ +3E98CF794975661C7D46D6DF10E14F0AF2E0EFBD480A350AC60E0881EA7090FD + +5FCE8109A358570E40983E1184E541833BB9091E280F258CFB144387B05D190E\ +431CB19BAA67273BA0C58ABE91308E1844DCD0B3678BAA42F335F2FA05267A02\ +40B3C718A5942B3B3E3BFA98A55C25A1466E8D7A603722CB2BBF03AFA54CD769\ +A99F310735EE5A05DAE2C22D397BD95635F58C48A67F90E1B73AAFCD3F82117F\ +0166657838691005B18DA6F341D6E90FC1CDB352B30FAE45D348294E501B6325\ +2DE14740F2B85AE5299DDEC3172DE8B6D0BA219A20A23BB5E10FF434D39DB3F5\ +83305E9F5C039D98569E377B75A70AB837D1DF269B8A4B566F40BB91B577455F\ +D3C356C914FA06B9A7CE24C7317A172D:\ +0E21302B185191492D2625F0FC4A3380ECD75D8EA945E35FD6E57EB7142DE249\ +90EEE2B6711392F8856874DE50E6D2FDF1D23A228877298C668251FD0F06B709 + +6172F1971A6E1E4E6170AFBAD95D5FEC99BF69B24B674BC17DD78011615E502D\ +E6F56B86B1A71D3F4348087218AC7B7D09302993BE272E4A591968AEF18A1262\ +D665610D1070EE91CC8DA36E1F841A69A7A682C580E836941D21D909A3AFC1F0\ +B963E1CA5AB193E124A1A53DF1C587470E5881FB54DAE1B0D840F0C8F9D1B04C\ +645BA1041C7D8DBF22030A623AA15638B3D99A2C400FF76F3252079AF88D2B37\ +F35EE66C1AD7801A28D3D388AC450B97D5F0F79E4541755356B3B1A5696B023F\ +39AB7AB5F28DF4202936BC97393B93BC915CB159EA1BD7A0A414CB4B7A1AC3AF\ +68F50D79F0C9C7314E750F7D02FAA58BFA:\ +1A77E749C8249D06F08943F5CDFEB5D65C804F1052B036CCD7A6F16120315AF7\ +B20C6BE56CA65861A2568F7E726420E909FAF47E4ED96A3C299AFF94EDFBF6EB + +5668ECD99DFBE215C4118398AC9C9EAF1A1433FAB4CCDD3968064752B625EA94\ +4731F75D48A27D047D67547F14DD0FFAA55FA5E29F7AF0D161D85EAFC4F2029B\ +717C918EAB9D304543290BDBA7158B68020C0BA4E079BC95B5BC0FC044A992B9\ +4B4CCD3BD66D0EABB5DBBAB904D62E00752C4E3B0091D773BCF4C14B4377DA3E\ +FFF824B1CB2FA01B32D1E46C909E626ED2DAE920F4C7DBEB635BC754FACBD8D4\ +9BEBA3F23C1C41CCBFCD0EE0C114E69737F5597C0BF1D859F0C767E18002AE8E\ +39C26261FFDE2920D3D0BAF0E906138696CFE5B7E32B600F45DF3AAA39932F3A\ +7DF95B60FA8712A2271FCAF3911CE7B511B1:\ +CDF5CC029A5946BB96A524D865C6BAB024A2B598A9A657EF631FA582ED9BEBF5\ +6C18D955528A3DD5BC0D2466F7EE0EF8AF1C814E3858E5DA3A2BA951BB2D79A0 + +03D625488354DF30E3F875A68EDFCF340E8366A8E1AB67F9D5C5486A96829DFA\ +C0578289082B2A62117E1CF418B43B90E0ADC881FC6AE8105C888E9ECD21AEA1\ +C9AE1A4038DFD17378FED71D02AE492087D7CDCD98F746855227967CB1AB4714\ +261EE3BEAD3F4DB118329D3EBEF4BC48A875C19BA763966DA0EBEA800E01B2F5\ +0B00E9DD4CACA6DCB314D00184EF71EA2391D760C950710DB4A70F9212FFC548\ +61F9DC752CE18867B8AD0C48DF8466EF7231E7AC567F0EB55099E622EBB86CB2\ +37520190A61C66AD34F1F4E289CB3282AE3EAAC6152ED24D2C92BAE5A7658252\ +A53C49B7B02DFE54FDB2E90074B6CF310AC661:\ +2A4B61FEAAC1BC466DD77EBE6E800F87950B28532F71BE5E4D56DE28F93C1F7E\ +61C793745A91B8CCDC29914989730B7DF933E6C7F1B1A08638953F966F092560 + +2EDC282FFB90B97118DD03AAA03B145F363905E3CBD2D50ECD692B37BF000185\ +C651D3E9726C690D3773EC1E48510E42B17742B0B0377E7DE6B8F55E00A8A4DB\ +4740CEE6DB0830529DD19617501DC1E9359AA3BCF147E0A76B3AB70C4984C13E\ +339E6806BB35E683AF8527093670859F3D8A0FC7D493BCBA6BB12B5F65E71E70\ +5CA5D6C948D66ED3D730B26DB395B3447737C26FAD089AA0AD0E306CB28BF0AC\ +F106F89AF3745F0EC72D534968CCA543CD2CA50C94B1456743254E358C1317C0\ +7A07BF2B0ECA438A709367FAFC89A57239028FC5FECFD53B8EF958EF10EE0608\ +B7F5CB9923AD97058EC067700CC746C127A61EE3:\ +A40028E17CD5DA2DB800437A58861565E0A55CD3DC017FE48C7D3F2D4706D7EC\ +742A21170CB86B32B5B9A1496C5C5DDE4E283915BFCDC883F08039679E29ED43 + +90B28A6AA1FE533915BCB8E81ED6CACDC10962B7FF82474F845EEB86977600CF\ +70B07BA8E3796141EE340E3FCE842A38A50AFBE90301A3BDCC591F2E7D9DE53E\ +495525560B908C892439990A2CA2679C5539FFDF636777AD9C1CDEF809CDA9E8\ +DCDB451ABB9E9C17EFA4379ABD24B182BD981CAFC792640A183B61694301D04C\ +5B3EAAD694A6BD4CC06EF5DA8FA23B4FA2A64559C5A68397930079D250C51BCF\ +00E2B16A6C49171433B0AADFD80231276560B80458DD77089B7A1BBCC9E7E4B9\ +F881EACD6C92C4318348A13F4914EB27115A1CFC5D16D7FD94954C3532EFACA2\ +CAB025103B2D02C6FD71DA3A77F417D7932685888A:\ +2A1F1C7FAFBE676D2A7BC67BD80C9387F493643E2395852AF8A6846A5DDC191C\ +B17FCAA17BB82266FEA390B3E45DED4A15408A29DF5AE390A1BC945D5D97C1C7 + +2969447D175490F2AA9BB055014DBEF2E6854C95F8D60950BFE8C0BE8DE254C2\ +6B2D31B9E4DE9C68C9ADF49E4EE9B1C2850967F29F5D08738483B417BB96B2A5\ +6F0C8ACA632B552059C59AAC3F61F7B45C966B75F1D9931FF4E596406378CEE9\ +1AAA726A3A84C33F37E9CDBE626B5745A0B06064A8A8D56E53AAF102D23DD9DF\ +0A3FDF7A638509A6761A33FA42FA8DDBD8E16159C93008B53765019C3F0E9F10\ +B144CE2AC57F5D7297F9C9949E4FF68B70D339F87501CE8550B772F32C6DA8AD\ +2CE2100A895D8B08FA1EEAD7C376B407709703C510B50F87E73E43F8E7348F87\ +C3832A547EF2BBE5799ABEDCF5E1F372EA809233F006:\ +80C5090FDDA7FB8B550602FBB156D650958E0EE131E21C09FCCB57FAA9A9C868\ +C5947E409BC5CFA89C8616619E625C7D1DAD8686FF59C2CD1D9940E336472145 + +721645633A44A2C78B19024EAECF58575AB23C27190833C26875DC0F0D50B46A\ +EA9C343D82EA7D5B3E50EC700545C615DAEAEA64726A0F05607576DCD396D812\ +B03FB6551C641087856D050B10E6A4D5577B82A98AFB89CEE8594C9DC19E79FE\ +FF0382FCFD127F1B803A4B9946F4AC9A4378E1E6E041B1389A53E3450CD32D9D\ +2941B0CBABDB50DA8EA2513145164C3AB6BCBD251C448D2D4B087AC57A59C228\ +5D564F16DA4ED5E607ED979592146FFB0EF3F3DB308FB342DF5EB5924A48256F\ +C763141A278814C82D6D6348577545870AE3A83C7230AC02A1540FE1798F7EF0\ +9E335A865A2AE0949B21E4F748FB8A51F44750E213A8FB:\ +A779BC3D4F6315BEFDA9CBBBDBA4C9E24D810CB46074D81A6E2D66947A30F62C\ +4D3EB92AFC6D9BFBF42DF3D8528982FCF7AECA66740D0E753040A2C6F71AC1DB + +6B860D39725A14B498BB714574B4D37CA787404768F64C648B1751B353AC92BA\ +C2C3A28EA909FDF0423336401A02E63EC24325300D823B6864BB701F9D7C7A1F\ +8EC9D0AE3584AA6DD62EA1997CD831B4BABD9A4DA50932D4EFDA745C61E41308\ +90E156AEE6113716DAF95764222A91187DB2EFFEA49D5D0596102D619BD26A61\ +6BBFDA8335505FBB0D90B4C180D1A2335B91538E1668F9F9642790B4E55F9CAB\ +0FE2BDD2935D001EE6419ABAB5457880D0DBFF20ED8758F4C20FE759EFB33141\ +CF0E892587FE8187E5FBC57786B7E8B089612C936DFC03D27EFBBE7C8673F160\ +6BD51D5FF386F4A7AB68EDF59F385EB1291F117BFE717399:\ +46D64790833ABF3E17BB4B8CCDB4F0A2DCD23FDFA3135744306F4916A658CC5B\ +0BB60DD65DD2287287CA645C0B5904A7227ED1B40730A6F335BEC41706769E9D + +6A01830AF3889A25183244DECB508BD01253D5B508AB490D3124AFBF42626B2E\ +70894E9B562B288D0A2450CFACF14A0DDAE5C04716E5A0082C33981F6037D23D\ +5E045EE1EF2283FB8B6378A914C5D9441627A722C282FF452E25A7EA608D69CE\ +E4393A0725D17963D0342684F255496D8A18C2961145315130549311FC07F031\ +2FB78E6077334F87EAA873BEE8AA95698996EB21375EB2B4EF53C14401207DEB\ +4568398E5DD9A7CF97E8C9663E23334B46912F8344C19EFCF8C2BA6F04325F1A\ +27E062B62A58D0766FC6DB4D2C6A1928604B0175D872D16B7908EBC041761187\ +CC785526C2A3873FEAC3A642BB39F5351550AF9770C328AF7B:\ +29EBB2B1BF14463500B983F8C9FE9EAD506514E9AF11202A9E0930B225EBC525\ +8A09324010C52FF35E902647D9701293A8F8A007ABC3D6A7BE629C5078A42BED + +B3C5E74B69933C2533106C563B4CA20238F2B6E675E8681E34A389894785BDAD\ +E59652D4A73D80A5C85BD454FD1E9FFDAD1C3815F5038E9EF432AAC5C3C4FE84\ +0CC370CF86580A6011778BBEDAF511A51B56D1A2EB68394AA299E26DA9ADA6A2\ +F39B9FAFF7FBA457689B9C1A577B2A1E505FDF75C7A0A64B1DF81B3A356001BF\ +0DF4E02A1FC59F651C9D585EC6224BB279C6BEBA2966E8882D68376081B98746\ +8E7AED1EF90EBD090AE825795CDCA1B4F09A979C8DFC21A48D8A53CDBB26C4DB\ +547FC06EFE2F9850EDD2685A4661CB4911F165D4B63EF25B87D0A96D3DFF6AB0\ +758999AAD214D07BD4F133A6734FDE445FE474711B69A98F7E2B:\ +8DB46A5D23103103746C2FE2480CEEC56FD9796AD357F5BC45BF0BC2D2E8B95E\ +A0C286090AB858183C2A051B80FCA8776670FA3DA8722329848F057C6EAD4991 + +83AF34279CCB5430FEBEC07A81950D30F4B66F484826AFEE7456F0071A51E1BB\ +C55570B5CC7EC6F9309C17BF5BEFDD7C6BA6E968CF218A2B34BD5CF927AB846E\ +38A40BBD81759E9E33381016A755F699DF35D660007B5EADF292FEEFB735207E\ +BF70B5BD17834F7BFA0E16CB219AD4AF524AB1EA37334AA66435E5D397FC0A06\ +5C411EBBCE32C240B90476D307CE802EC82C1C49BC1BEC48C0675EC2A6C6F3ED\ +3E5B741D13437095707C565E10D8A20B8C20468FF9514FCF31B4249CD82DCEE5\ +8C0A2AF538B291A87E3390D737191A07484A5D3F3FB8C8F15CE056E5E5F8FEBE\ +5E1FB59D6740980AA06CA8A0C20F5712B4CDE5D032E92AB89F0AE1:\ +BC933D42AD3267F608AB201D2813E54250499D87ECEEF837863F59D8ACE4ED6A\ +3239C4C7CD7E172F3CF3CDED5D84950E066E2F549A767BA421CAD4A223313C1D + +A7ED84749CCC56BB1DFBA57119D279D412B8A986886D810F067AF349E8749E9E\ +A746A60B03742636C464FC1EE233ACC52C1983914692B64309EDFDF29F1AB912\ +EC3E8DA074D3F1D231511F5756F0B6EEAD3E89A6A88FE330A10FACE267BFFBFC\ +3E3090C7FD9A850561F363AD75EA881E7244F80FF55802D5EF7A1A4E7B89FCFA\ +80F16DF54D1B056EE637E6964B9E0FFD15B6196BDD7DB270C56B47251485348E\ +49813B4EB9ED122A01B3EA45AD5E1A929DF61D5C0F3E77E1FDC356B63883A60E\ +9CBB9FC3E00C2F32DBD469659883F690C6772E335F617BC33F161D6F6984252E\ +E12E62B6000AC5231E0C9BC65BE223D8DFD94C5004A101AF9FD6C0FB:\ +D84DDA22FBE020F57EFBC8C612B2F781EAA81E4C9B0F013BFC1B3C926A5BA778\ +28F8C6684A25B2C567DAD1B705E7BB417F5EAE6D8BD2BFA6ACBC7284F3C19E81 + +A6FE30DCFCDA1A329E82AB50E32B5F50EB25C873C5D2305860A835AECEE6264A\ +A36A47429922C4B8B3AFD00DA16035830EDB897831C4E7B00F2C23FC0B15FDC3\ +0D85FB70C30C431C638E1A25B51CAF1D7E8B050B7F89BFB30F59F0F20FECFF3D\ +639ABC4255B3868FC45DD81E47EB12AB40F2AAC735DF5D1DC1AD997CEFC4D836\ +B854CEE9AC02900036F3867FE0D84AFFF37BDE3308C2206C62C4743375094108\ +877C73B87B2546FE05EA137BEDFC06A2796274099A0D554DA8F7D7223A48CBF3\ +1B7DECAA1EBC8B145763E3673168C1B1B715C1CD99ECD3DDB238B06049885ECA\ +D9347C2436DFF32C771F34A38587A44A82C5D3D137A03CAA27E66C8FF6:\ +C4966858DB87DFC7DAE95CB51A8B19DD481F75B3FF554B18458C0F25A285F613\ +5D73FF6F1B498B957E8481F16612D8B52E187BDE76B3A8D1A6324A3899F056D8 + +83167FF53704C3AA19E9FB3303539759C46DD4091A52DDAE9AD86408B6933598\ +9E61414BC20AB4D01220E35241EFF5C9522B079FBA597674C8D716FE441E5661\ +10B6211531CECCF8FD06BC8E511D00785E57788ED9A1C5C73524F01830D2E114\ +8C92D0EDC97113E3B7B5CD3049627ABDB8B39DD4D6890E0EE91993F92B03354A\ +88F52251C546E64434D9C3D74544F23FB93E5A2D2F1FB15545B4E1367C97335B\ +0291944C8B730AD3D4789273FA44FB98D78A36C3C3764ABEEAC7C569C1E43A35\ +2E5B770C3504F87090DEE075A1C4C85C0C39CF421BDCC615F9EFF6CB4FE64680\ +04AECE5F30E1ECC6DB22AD9939BB2B0CCC96521DFBF4AE008B5B46BC006E:\ +DEF5B398B53E2B884AAA19D86186EC7B386974386B24F5C993417C1B3377449D\ +0EE19D00AB789E2D63A56B01101E44692815644147D1C2D66A9A68579BEB2B50 + +3A3A819C48EFDE2AD914FBF00E18AB6BC4F14513AB27D0C178A188B61431E7F5\ +623CB66B23346775D386B50E982C493ADBBFC54B9A3CD383382336A1A0B2150A\ +15358F336D03AE18F666C7573D55C4FD181C29E6CCFDE63EA35F0ADF5885CFC0\ +A3D84A2B2E4DD24496DB789E663170CEF74798AA1BBCD4574EA0BBA40489D764\ +B2F83AADC66B148B4A0CD95246C127D5871C4F11418690A5DDF01246A0C80A43\ +C70088B6183639DCFDA4125BD113A8F49EE23ED306FAAC576C3FB0C1E256671D\ +817FC2534A52F5B439F72E424DE376F4C565CCA82307DD9EF76DA5B7C4EB7E08\ +5172E328807C02D011FFBF33785378D79DC266F6A5BE6BB0E4A92ECEEBAEB1:\ +59D674C09E78B40FADD298EE83FB2CB4468CA96AFAA75CE3F4B451C0D353C28A\ +632A0DE753800D49FDBD6EA190025C5340036910BDBACC91C2D988B6FB2F8789 + +724627916C50338643E6996F07877EAFD96BDF01DA7E991D4155B9BE1295EA7D\ +21C9391F4C4A41C75F77E5D27389253393725F1427F57914B273AB862B9E31DA\ +BCE506E558720520D33352D119F699E784F9E548FF91BC35CA14704212870982\ +0D69A8287EA3257857615EB0321270E94B84F446942765CE882B191FAEE7E1C8\ +7E0F0BD4E0CD8A927703524B559B769CA4ECE1F6DBF313FDCF67C572EC4185C1\ +A88E86EC11B6454B371980020F19633B6B95BD280E4FBCB0161E1A82470320CE\ +C6ECFA25AC73D09F1536F286D3F9DACAFB2CD1D0CE72D64D197F5C7520B3CCB2\ +FD74EB72664BA93853EF41EABF52F015DD591500D018DD162815CC993595B195:\ +7A3E81CDEA3E783B0D2E77373D7E3AD3E069DF3C9F16EA87E41CD7178EBA02D4\ +9AA344C562EA9DB6FB20645F5F3DB9B62EC1F18ADFB5C10C77C1EBACEECC5E25 + +3139840B8AD4BCD39092916FD9D01798FF5AA1E48F34702C72DFE74B12E98A11\ +4E318CDD2D47A9C320FFF908A8DBC2A5B1D87267C8E983829861A567558B37B2\ +92D4575E200DE9F1DE45755FAFF9EFAE34964E4336C259F1E66599A7C904EC02\ +539F1A8EAB8706E0B4F48F72FEC2794909EE4A7B092D6061C74481C9E21B9332\ +DC7C6E482D7F9CC3210B38A6F88F7918C2D8C55E64A428CE2B68FD07AB572A8B\ +0A2388664F99489F04EB54DF1376271810E0E7BCE396F52807710E0DEA94EB49\ +F4B367271260C3456B9818FC7A72234E6BF2205FF6A36546205015EBD7D8C252\ +7AA430F58E0E8AC97A7B6B793CD403D517D66295F37A34D0B7D2FA7BC345AC04\ +CA1E266480DEEC39F5C88641C9DC0BD1358158FDECDD96685BBBB5C1FE5EA89D\ +2CB4A9D5D12BB8C893281FF38E87D6B4841F0650092D447E013F20EA934E18:\ +B26C758C740DA514E7BE7966C2E371F96C263796688A771A955005D907AF23D1\ +9C47FB0FF920CA3DEF21E13B4C827E4AD586DBC3D28F3576DBC6694F48E8BC37 + +023D91AC532601C7CA3942D62827566D9268BB4276FCAA1AE927693A69616526\ +76DBA09219A01B3D5ADFA12547A946E78F3C5C62DD880B02D2EEEB4B96636529\ +C6B01120B23EFC49CCFB36B8497CD19767B53710A636683BC5E0E5C9534CFC00\ +4691E87D1BEE39B86B953572927BD668620EAB87836D9F3F8F28ACE41150776C\ +0BC6657178EBF297FE1F7214EDD9F215FFB491B681B06AC2032D35E6FDF832A8\ +B06056DA70D77F1E9B4D26AE712D8523C86F79250718405F91B0A87C725F2D3F\ +52088965F887D8CF87206DFDE422386E58EDDA34DDE2783B3049B86917B46280\ +27A05D4D1F429D2B49C4B1C898DDDCB82F343E145596DE11A54182F39F4718EC\ +AE8F506BD9739F5CD5D5686D7FEFC834514CD1B2C91C33B381B45E2E5335D7A8\ +720A8F17AFC8C2CB2BD88B14AA2DCA099B00AA575D0A0CCF099CDEC4870FB710\ +D2680E60C48BFC291FF0CEF2EEBF9B36902E9FBA8C889BF6B4B9F5CE53A19B0D\ +9399CD19D61BD08C0C2EC25E099959848E6A550CA7137B63F43138D7B651:\ +919998132C03BB57E2748C5715C4D3CCD72250633983A61174E5A9B53BFD3ED7\ +FA7BA8698BDF766B31B29E387B1E44E1C10402C3A9F4FCE845865803F805CB18 + +20FF454369A5D05B81A78F3DB05819FEA9B08C2384F75CB0AB6AA115DD690DA3\ +131874A1CA8F708AD1519EA952C1E249CB540D196392C79E87755424FEE7C890\ +808C562722359EEA52E8A12FBBB969DD7961D2BA52037493755A5FA04F0D50A1\ +AA26C9B44148C0D3B94D1C4A59A31ACA15AE8BD44ACB7833D8E91C4B86FA3135\ +A423387B8151B4133ED23F6D7187B50EC2204AD901AD74D396E44274E0ECAFAA\ +E17B3B9085E22260B35CA53B15CC52ABBA758AF6798FBD04ECEECED648F3AF4F\ +DB3DED7557A9A5CFB7382612A8A8F3F45947D1A29CE29072928EC193CA25D510\ +71BD5E1984ECF402F306EA762F0F25282F5296D997658BE3F983696FFA6D095C\ +6369B4DAF79E9A5D3136229128F8EB63C12B9E9FA78AFF7A3E9E19A62022493C\ +D136DEFBB5BB7BA1B938F367FD2F63EB5CA76C0B0FF21B9E36C3F07230CF3C30\ +74E5DA587040A76975D7E39F4494ACE5486FCBF380AB7558C4FE89656335B82E\ +4DB8659509EAB46A19613126E594042732DD4C411F41AA8CDEAC71C0FB40A94E\ +6DA558C05E77B6182806F26D9AFDF3DA00C69419222C8186A6EFAD600B410E6C\ +E2F2A797E49DC1F135319801FA6F396B06F975E2A190A023E474B618E7:\ +F0EECEC5514F8001BD7AF333B78AE40E0D20944AAA2710EB3524236ABE3EAF3C\ +999DB788869647B5737B60FD4BE4753722C2CA6E905E030EFD04749BA46251A5 + +4FBDC596508D24A2A0010E140980B809FB9C6D55EC75125891DD985D37665BD8\ +0F9BEB6A50207588ABF3CEEE8C77CD8A5AD48A9E0AA074ED388738362496D2FB\ +2C87543BB3349EA64997CE3E7B424EA92D122F57DBB0855A803058437FE08AFB\ +0C8B5E7179B9044BBF4D81A7163B3139E30888B536B0F957EFF99A7162F4CA5A\ +A756A4A982DFADBF31EF255083C4B5C6C1B99A107D7D3AFFFDB89147C2CC4C9A\ +2643F478E5E2D393AEA37B4C7CB4B5E97DADCF16B6B50AAE0F3B549ECE47746D\ +B6CE6F67DD4406CD4E75595D5103D13F9DFA79372924D328F8DD1FCBEB5A8E2E\ +8BF4C76DE08E3FC46AA021F989C49329C7ACAC5A688556D7BCBCB2A5D4BE69D3\ +284E9C40EC4838EE8592120CE20A0B635ECADAA84FD5690509F54F77E35A417C\ +584648BC9839B974E07BFAB0038E90295D0B13902530A830D1C2BDD53F1F9C9F\ +AED43CA4EED0A8DD761BC7EDBDDA28A287C60CD42AF5F9C758E5C7250231C09A\ +582563689AFC65E2B79A7A2B68200667752E9101746F03184E2399E4ED8835CB\ +8E9AE90E296AF220AE234259FE0BD0BCC60F7A4A5FF3F70C5ED4DE9C8C519A10\ +E962F673C82C5E9351786A8A3BFD570031857BD4C87F4FCA31ED4D50E14F2107\ +DA02CB5058700B74EA241A8B41D78461658F1B2B90BFD84A4C2C9D6543861AB3\ +C56451757DCFB9BA60333488DBDD02D601B41AAE317CA7474EB6E6DD:\ +E57A285664BF66D2D2C7F8AAB8B75224A793C799D16A4774BC0C8693976F33E3\ +10979C84FDC302822542581BAC488F68CA0987E7147A782B036DD211DC798408 + +D1890B4704E169C28E44DDF62A1091450404910539FC2DAEB26E8ACF4533B024\ +E5215C2D02820DD8FB2CFC1743955CBACFF0F8F35DFBB5E3F942F36247F68211\ +D518F3F601AAE12A1CDC000BAB43D4C973F287E80741DD1FCF6C34F2E6B4B6C3\ +13D01C4FF3CBF9166F26946F18EF2D58271BA9233F09A6B77BFD4F48B36EB3D7\ +3D1133C4F842A7DC3907F680B0B773242C11E3DD973A44327EA7CEA9C0F8E07D\ +682B6651E506B587559FE01ED721000BAF570A16FBDD9EA29FA3DEF4BE912058\ +321A8B720C5C102E48A6E7ED6F8838D400DD57D06EEDBCD15323F86D855C94B2\ +1E41B14EC9E1BBC8019211FD88138C91F9ABBD9BB3914D26C1DDC21673D2D512\ +63B39D66E741D924CF2B192C5D2C1A140126A3D64A2C77BE6C2C6EBE8599978A\ +E90BD36CBB9AF64D078910C4094AB3BF399C34F2AB8EF843E9FE1BF88BF443BA\ +21E4377E5F49C07FD9653B526E14562237F02D11B904BCA6AC31AE721A43E3C4\ +910A24AF6F4D80C031C109FC0FE49F15274BCA92BDA04C3B4196C192F6CE489C\ +63A806ACFC895AB52CAD657C1783B528E12D0ED856E1F8FC91F2AAFDFA0A9249\ +8D68530772EE73B359FCF1418D1096C46B34DCF90E5B468BBB2970BECBD70089\ +CFB039D64CC50FFF5EEF26384D34F24515A6558B06A1FDD88F1050C5BD78CC6E\ +D83D4C2B0E882AEBCF84AFB0430D0BF09F2FB42B8B4589158093A7709AAE75A7\ +90910E211EE1333FFB6FD80778DA3BF73858978E9DD647978841B18001DBAAEA\ +43CA0C0A03DBB9BCF30CE76A6F4B2CF2A9B6531B3E4051E7E05090CD421BC66C\ +4731E7122AD129FC42DEDC83BB460E3F889992FBD3CA072686E56B72C720FBC9\ +8D723EF7F247286F77CCDDC728738E941B1A74D4F16671C21FDD5643A115DDBC\ +B88EE7EC67EA66FD2BCE718DF6E085D4B5FC71A72696636A8F7B3A68AFA51A89\ +6771FAAA7F1F827430AC5E8089DBC0D4175E1B22A057BC5F1724EADC1A41E78F\ +A3ACAA8B97E5F2E19EF9D59AE12B04E7F0E8A621E098A66910E2A5ED2102B824\ +CD3EA044A854F1CD0B33E61E7F737414B2953549F25DD34D19AA1981DE7CD564\ +9FF6C6364A4F25312EF62395A747AB88AAD722C05AEC40DEEA8EEE5E779EF458\ +A68840BC6BD5D29AD40F98B3AE010B6213372ABB7BB8B8:\ +53BCB0FD89D9CF4A3738A01154D2B280F03B1D68EF7B512F6C657A0264488CA1\ +093D70F88C08DFE60CD418E938D74FE18EB3D525CD0492C8BF85FD2B2709516A + +4FA3DF1DEA75AD4B9C379206A95FED930000482E5B683FD2B17DC8E7D5C4BC1B\ +73186CCC13C9FF2DD09FC1D4F68034D120E84CA73A00B71A3B46D1EFC6FF88CF\ +2EDA65810B098CC5E651D9CF064E87076D5A871849F3B405D3D58EF5B1F10520\ +A9FB4FC84A81A87B13DBFBF9D8674943E28C257E46D8AD7BE1785F1DC7C9B1BD\ +574AD1DDA48F0255C853D2490BD3D63DA22A8369CFD02594999A2EF443308FB8\ +298266A11EFA177102C75DC674E89FC9DCC1A0D3C863BC26141102175D2678EB\ +6E13D90BBD9A5EB89AE8C0CB47D7F340D3D32042A2762BC9BF2B40EB40E87FB4\ +2610FE7E357051F01494704FBFF73321B47301A0799B7EE3FE5E62200F397A61\ +ED4509A62F7106ED0EFB0ABD6AE9E4A1FE9B02C092DCDC75015CF602F3B9A898\ +8B609E6C0D1C5C3E219FF57875C2EF01615F89447EA602DFC94EEC17A398C014\ +BD346691FE209A002771DC8164422CD166AFB457A8B3071282178A3EBD201D9B\ +07B27E711E7EE7D33AA5210ED4E4E92486775D14A6CED092E34A7AC826709399\ +48FEC149F9C018FCAAD3FC597D315713F44FC5E1725F448ECAED40E8D841BD02\ +F1E81C019B08F99412E360C0BD378391C67D964B47F50C26F0A483ED66402361\ +6B0FC9AFE43620DBE9CCFE070EF295C049EAC754C2123130C6B2C0232F6403AA\ +7F0DC35A5999BF95D34AD612234C6289277ADB60E4F72EC2DF570F05395B3BE8\ +A0A3C78B732821AA08927C524E15D65F66A3DB8C1C96FB70BC0686AAC310051F\ +469FC5EF880C0F66947C1C328F97684EA24CBE63BAED8D114F40507C2901034E\ +6AB3893F366D53F1CFCA309309218CABCECA4722FA9CCBC7249B87C12FF8397F\ +40487EB00082E7F551D27E301C3BC7B5389F7042534BF7E692DFEA4DA24F7C34\ +B8D2FF145F54B517FC97134EC5AC2CB925C508D7A6BD01FE7B764648274972BF\ +08560D30802E0EB7EDCC57AF4797BBF92E8688268606B0F1BC901FCC22136281\ +665EC16393FA9601C4FBDB18CD1D1EE382BC07973903E91FFA87399D1141D49F\ +4F0C064ACF3AC9897891DF10BCA0116F2C3FEF180FE6A8E937C478F2EF293AE9\ +186DCB1F76B6E48101DF64E57EA7C64C5C0025E221C8F5CBA5CC92D9CEC62814\ +0996B26D17F439B780F59A999301122F82D0495F8AB5AE1EA5790F45E992DFE0\ +0D5F82A7FF1354AEFDCEFC0D2D1731D22FA2B75AFD4FDA25AB194055FA962838\ +1055247C8C7587D22E73C60136C4282452D47AE03AA035FEBC26FCCD42A1CB79\ +CF866DB6418A49FD8261E877DDBB839CC39514DDB87A8A40D795532626FEA4A4\ +C35D13E028F9ED1BC09B06BE999B8DDD2258AA0596BCBBF72AF67E10BEDD58D5\ +99B8D577A583D676BF5561F80CE5E9528729A92DF578FE75DBC70474B75747A8\ +D55DE70E57BDD62D4344DC2115ED4DD62F1FC98BFA1E7421FC0700025C46D0ED\ +1BEF35C3B778563211B9FA9E8BA4BBCBF01C2FB626AB7EF325CE9F468DF2CACD\ +B178D36557CD85D542C067C289E926C1EA2F20ABD329E984168BB6DEF1DDCCF2\ +14DCB6A53AFD462F0E7E7A19E8C88F049244125A6D7DD41E58BC9B2FF7FA2478\ +DF76AF73090CB1AB59E388BA20E2C297C967737A1AF61793B68ECD7439444C48\ +E28E2D09C48FADA5E0D1D15E5B340A52F8B3B854CCA479F0A598445E14F53B3B\ +A36891050C79673DF3E2B5825C955A29E5C9A22F3991D0AA785718CFEA1D2385\ +F8E47E4A75ACBC7988D0558D541D71C4E6C5F1CB15B60CEA0C34A67BBCE105D7\ +A896025E0254DE7D7AF724C9027D44B8642192A08AB8E1EF3046DDA6014DF7F4\ +C9E63C635E48AB2E70B640D480998EC9357E665F99D76FE5529EF23C1BDFE017\ +C3A66CD4EB2DDB42EF85EA0CD65534:\ +6A6ACBD03B4A2CF63356C7B40B1C11B4E407349F13BE2A5EE0162D511B053760\ +CA9869B3036FE9D68475BFE3957B7007E0380F174B2CEC30ADD94DB65E43B4D0 + +523DE8B1F4CBB65E81FF0B6CCD6EB8EF0A0F0A691ACAF4A77F25ACD2D66AD4B3\ +EFD25BE70308853C094412A518A32020E3020A9F6AB32F0CD60EC0D7A194917D\ +6C457B168A54A4B46F7B0D0C71BD61CD202F4C718776A701E0770B0EFA054187\ +70F98E4E79CD066366FB3300E8BE359A98B82B764BC2FBBF59C7E8F94A157B01\ +C6C7577B1428138CD422BC47330F8ED99F4C0AAB0D984287445539839389EE08\ +D6345108AF26ADED0EC1D7BE774CFB8C5205DFE07CF6CAF8C1AFE37C7A2E4FE6\ +013B93EB2463DE4E0971C7178D6A76B16A0E8960C984CE8BBE71B3B466EDF044\ +5B835F09414D01F14C7B6167FF78FF118127BBD5F812C27FACD57B3B120E2BCF\ +E87315C7A92B82EF5D50CA14A7174D1BEA7E056523E055A6AE42EA3765094E55\ +44E5ED003C989C2F98F38A17E3DDA74DBAF9C669A319638A2698B0E4A611480D\ +8AD3CF016792ECD1034925F42B9811A7214D623D047ABCA31997DDEB03275F80\ +DD21F40DDC80616E7AD3D481E8EBC0A1A6A398E16A78369215541ED10B75671A\ +DEB1AAE6E11142A1CF665FC1B7332DFBB0E10C21A2B48F78E57319AC9C58DFA8\ +B1C2548E2979EF1ACCFEB215AFCD6C2C1B46FE97DD491758378330EFFC728366\ +1D2CB84FA05281E9E517408508D24D042E7B9BCD34DB87CE972E4CBCDB98615F\ +B93093369DFEDC782F44BCD03E81CF93051318B2401FF29F753A264BDA65AF19\ +9E3FCBB8B5D39C838A67D6C7A3DB046DC56C323DDBB5340CBC229E47CFF8C9D2\ +9B7A49AC0EC8C1440AE498C7D150EF91C29BEA7DF3EFCC2871A13A1D72D139CB\ +4603D9FFFE85F6DDD544850EF63C3944FB35DBC00D4308CEAA6394B6E23F650D\ +323F8F7EF50DDB68F1486EABF989BF44451F620EC9485C0B52D1415D3C909A2C\ +FBE9D77DB19D069D33BAEE4D77292E63FCBF65C1EBA24BFFDDEFE95211EF0AAF\ +8ABFDA9F94445E582976F986F5382CB669506AF2B4A5A0C43000A3C72C5CA4AA\ +CDC9D3D39FC5C492A393B6C341B86DACBBF6BA8B465100CC683EDB2D9B9F83ED\ +F9C6A32645F51CC79ADC22A52A007BAACA618BE35E356D1FD1CFBDA73F1ED092\ +53039DEF609450FD2D5943B9CD49CBD52A318EE3510D7CF3FD8FB388AC6CB9C6\ +EEFEF3D3CAD8501B91CC04A888D33E16D6A4C9666F5F5F3B257193F2B46DEDDE\ +11842909D8C48ADE57775B0B272E2DC9CEF1A083EB2CE58F4D1F211922FD6ADE\ +D1B82FE6F5B11251CD396E5A3666ED9626036E4E356231C146BBA0A91AFD3648\ +EB7BFE0B9C14F15AF2F92309826F468945CAD0AC422DE3D6A773B76178422107\ +CE0270E7F580B5CCEBA82CA0184AAFA8341141E65E39859885768FBC5CE63B96\ +5A0604B659E71D9DA2C7A43646088D8071D76926163AAFC69E25355BB0A222B7\ +B2DA9F0A20C021ADC462E905A9C3BF31C16D87FBEC3F014F3957A720F1432E17\ +41553092052FB58A198640479ABCAA51B104CC93E2636E1460643EA812BD44E8\ +19C2166EB6B349BA5BDEBAD59078910B5C22A56F004B8D9E4B1224D8D204B48A\ +BE7355548A402736C5CB110F3A1476ED631FF168F4F3EFD89B38DE4751536548\ +647523D334FAD7CC2D142973F2DB3C1FE08FC5CF83F9F2BD2DAA524B37864816\ +AF29EE05951FA09D1C51D9D14EE4F72FD7BBF18B1A724FF5A0958A063947C430\ +142AD2356E4400AAECA442E163372A8F1CD36E2DB988E7781165E5D4E7074ACE\ +40858E8370E883694AF09977704347FB735C8717C42BC4EEEB2AAA50DFE637C6\ +40909CE379BFB9E2608F88751377038D1669F248178AD580A908D7A1B8DCC7E5\ +3E01801F1E485B5893F103F03E0F53B2B1440BE95644D85AA7F6EB7EDFBB4665\ +2196695EA23C08573397B111FF909025E20C5201293B4D223BF7AA01DE7CB28B\ +94714370434B9588097E2401B62C7A0DEF1FBF89809E810749FD3CE9EC3C07CE\ +4BF4C43DC966429B2BEB4D711FC6C448A12097B36F1E6817EAF4937A983F85D9\ +CF3E62CC1B2AC6AE1EC9EAA8CD8EE2C3322239CFE5DB3D4E8786282E630A7D25\ +9C2FEFECA03031C960A66A71E436A3ED6F2F3CFAB4BD77C660D14205ABF606FE\ +561A346F7D849B69475AC9F6822D80B9A2E56D5D495E4B309B0EA963C9FC5C7E\ +F94B217EE5337989AFBC7107D233A8B362AC27C4F69DF9E191CD65AE97D6EB9E\ +5484EB6F10349575E4CAE51452380151F902415AC9CF42C824EB23C9541D2DA1\ +C26DB85F53CDAFB06A12B8393CD580A8E494EDB6710C720DCAE30832967E33E6\ +303A92B1DF0841D7724284FFD2E00B95C6D623B168D21AC1BD3C675EDA33182A\ +2C22370998DE1E5EB905372CC6EF32D5B765F5C94870DF4842D011603BE4CDB1\ +C227E41EB2F2E8542CD325884FEDC9C5C7BB07A92D20D64B836215C59F162A3D\ +A8BB67D6FC13FEF97CAB6ECB8A29E431A6519A6261C4521CCB90E6E609869E6F\ +E398404AE047F64EC4263566DEFEE66329DD40AC985EB8A08D26529A544891B6\ +F57CC235C63C09057AB6B6ED720EF41A3C9AE65768B43F6DCF4962A103DD93C2\ +13171DC2C9194E43265C689B49331450281A3FEBC618D1AA4D65A135137051FD\ +46B568CE294C89:\ +DE11315ECF713973B7D6E548DA33F68B53D8E9BC11F7E89C3CDD334EF748A58F\ +84B03B296F1B05357A8873449CDC49CEC6C893A629439B48B6DB517F4B0C9773 + +F5080D4C59E804BF8F34B334CABBCC7D32011BDE3677F4B9069416AC204114CD\ +9DA7A0ED0F4B4D8344416336EEC15553EF526B6DEC267B1242657DD0B508AF81\ +FECF9CFF9C82A6A7A9539814DD7E097615EF15373836B5D2F765CC8D5F82E904\ +49F13AA741D5EE2FE63898E55ACD85116846807606FE1E2E29F98F9940B067D0\ +D1DF01F080211B2EE4B0A30803782A7BC2EAFDC5EBDBA91EB05F7D7DC8E34BF6\ +D44FEC05824F53418F235FB64E899EE147BCB403C8855E94AF378D182D79C3EA\ +F977CB4E9D4A16D990A6C388CEB567B97785E6F2BC6745102B99AE765E960B6B\ +32BAF01E2379CD6ECB74D3E1A56552F5976DFE5C742BC92BE596CA742FFC3D0F\ +A032AC29F9F7C1A5C43BCCA62DF7D9DE35D0C7C179DB2E1AA255CEDCCA55064C\ +2049FEE1AF2CE5EF696ED4BC46B7C55BDD51F2D44C8713FB2475C0B85246AC01\ +03CC3863B7EB026AE076A600313F6FB40A4DF62A2AF81B7E917951EA870ECB31\ +B3401928B5046D9A1E62D14B30FDEBAF262868517318FE17EC3C0D52524F4412\ +0ED8ED3BA70C643300CD0BC70DA72C964A88F52C3A91EC20BFEB5CAEFCD4D9C7\ +685D8407476B5F34676C5EBD1E88A6CFF1C625322F8CD59B9ED60CEFB21F9491\ +B95E72791F7AC7EAA3C16159FE9DF7A989ADD6C2282C47585E11397EDA9F47DF\ +2B40166E03BCDD6186B46C6835118268DDBEF19A28BBADE1BDE0228FFD7E8B3C\ +3C598D89E24B8CDEE79C940254DE26CC6814BA2722E42F7571600B7325E1FF30\ +0251D52A895B8CCBD049B2953B8D231445F68F7C26EC25A4B8695C8AC116F736\ +BE939EDD762C9B4743E463C9B9B2F88E0BC0CE78781CDDC3BCA825ACD463C7CA\ +C2AA6C430BBE820EA94AF9A40B1B5C006E9641A2FFA6E427379E1AD49C81B983\ +20B3431FF0030DC683D61026438BC6A6D34B2C73704D9F62EAEB13ABB3E4B056\ +2B4E0482CD6B2D7AEBC0367EA29A88F4A76F3D76FA1197E1DCA92C8216C84C1A\ +F9B8C78C9E3A7799A4A79A783033B0F5547E8E75E69CF3615AB04EF989FE1A46\ +3B1672C571D50AB56972896E8A50C242F22C7F6E27CA4CA793F627E79608680F\ +5421B28BDD2589F05E65430DF774EE873FCD1234064F7A33CF5A1FA4E368137F\ +F9C1597F1FA0FA36493F20538077669EADFD3B06F788C912C715FB5D334DB6BE\ +D133A8FDC40F5496E66AD63881F0BA3727416715865253DC5290327B515BF68D\ +A188DD5B4B0EAC7CA712CAFA8FCAE0C5503FE58A219182F1C30DA6D0C19CFEE8\ +97B7D837C97996A35F4CA8CF0537A01D17E7DE0CC9C129E4DA0ADAF1FDA85030\ +DF9127BE628263B0624F372C47C3AC87EB945A57F5C732BEEE81A74030017989\ +92F3DC944114FF3D54C4666AC5AC8C98D0D5596CBDEB420665F5EDAAE747D54C\ +F7EDD37B162E372249D135938CF17D174D12D88279CB4C32BD6F018C766DA698\ +3D4EA51D6BD8FF0A9B34E9A93BBDA70CF1B4B867D60A74811FD98D52FAA559B5\ +2C755CB70A76C94BD19654CAE7017CCD70222BF08C5D7AD1F5E4E6344FDB3ABE\ +703452C29A696F39F9826ED8BC510A4A148E5BF8A5DBE6B82D7220164F08011C\ +05AC5159D52CE9D45D758B645BBB248C2D341DBEFA1F8602C5D458A64F38F3B0\ +4DB39089807B6A10E1BB52770B92CE72E2D3BB0C2241CDED35054B84558D1CC0\ +99EF7B2296951951D5B6A22F93BF962AC5EF8FB55EC6CC2B316428EDF12078ED\ +1B66D525D022819CBD489E1BEDB02FFBD507D55F9B5D4E22F6396EA233453754\ +688D20151A09C70044B8A5A9AC033C3C3B847AD833D5C05B33407666EE82F958\ +1DF9034EE15A9CA67D52F1D9B634B84C1B8BA9E515F1F060A5AC5CBAE2DE75F9\ +4E112F7198E239DF08D3103F065627438995026DF511C6E5BFDEEE5667D511D4\ +181850C7C5D179107C1B86D24D5532A88A4149A2810DCAE73731B0E1247281A6\ +FD31613DF6891B4C17B7A6A9AD9B77468254B93F85958AA0F01CEFC10B25169D\ +C46E035D3F24557B4BF0E7D60174219108D916FFDC55E25BFFD9809EFD058E12\ +C14F39C69D8FB73D3EC6458F47F2F8DB901BA76C86550B11B54D0641D4DB3EB0\ +00057DD00F2E511FB7A47E959A4402A3AC5462234B40B184020FCF7A0396C4D0\ +0A987C8741A4537BC17102A5C42AFEAB9F71EA66ED4CBC7B5EE682FF04F56F4B\ +A1EA0BB326C4089930F9E3F3FFA3E06637CCE32113881A06CC3A13837448145C\ +2BD01307A580FDBC385D8F46FB92FFEDBC8918D269DD1871164D4B3E2023441E\ +C8B99C82A5F09821CDDF6B38C9ACC3BF3A38D5628016159588C33EAA29D9463A\ +537C000A16AD8C177DC4CF716E625F46FC4CA8C19FBD8EF320F1D680639195C8\ +B195B0A02738E0665F4190D6287E589CD6DD45B9E8CC23B08E1681BFC6F66B88\ +DE6B091E825EA4BBFBD697E10BC407570AE4F2A3EBE569554639C2B8E051656C\ +C30C837F5A92260EAD1D552B45801B6D28134166796C87F900225CFDC3CC49D7\ +2DFBC18D8D95B1E160ED3CAFD5C3467D48AFF87402CBCB1E1420E3FCB588AA19\ +C8F42753B59DB6FB6A9FDBA127CA806DBA7DD97F2488FC2E438EEF57A4CC85B8\ +8DCFDE76AE1FF61225A1CA8BF4A14F729950322EA681B16D6492902506702DC8\ +F348E4D3AE7FB55FAC1231FDE82091B34F1791B6AE37587B10325F6FF5E23B85\ +5845B86EAE90785B9D10D90A16644D01BB626F343B908A9591F4069B21822CA4\ +ECF985C1E710475F33DF9AF4764CFB0FFE649063775338F15BEA7CFF29F16467\ +8160960A80ED148C9B7FAA58E9139911D3DD9536F69646F718F083DC9029D629\ +4FC4C607688AA75AF350AC2C0B001A157D023D73D86ED8133809FCB9592D1208\ +9CBD7A1BB6BBA882FE227C09A53FF088907CB4BC2FB4B7F62D41D3D397C4FE0A\ +D12BB3964370E21712951C679814D506E738C0201E42181D231136A435AE0397\ +B61CCBC5E8BBEBF8EA77C8BC48BD6211F29248F9D498D818E2B544D28A5E60BA\ +727F32EF4BA2707962230C900076FB764D0ED5CE078C9DB14DE894BBB836C6DE\ +9E83202AE89F9A8D8CB0341E1C81B5FA8B16731B8E231E969C0F1EF95336D4E7\ +3EAD6DA23DE3AD1EB608ACCE4D4D93996DD76EC1F5F2C576F6B3B76E07BD8A81\ +0FF5D88B00FFE48C42700B61CC499336E7FB57AD72FF44FC631C7222C9A3D1AB\ +F6E77B5ED7FE2F7228FED6C849BF7142C4103989A80F7C15642AE61650CDCA7E\ +854EB25E9E72F4C3E3768E6CCC8BFD556B56D3507EDDE9E5C331DDEA75568B07\ +813D20E8F4C9547838ED28448F2E67158ACF0C00B131473847816C5E2DC215:\ +740168046E1DE04598A62F5B92372B5198F2C44F579094D274EB5171CB4CD777\ +0763D54CB75D070184921C3CF65FA371E96F8FEC8138E7E1E1590CB0CA26007A + +08944CB473B828B118A31986DB67FC757F238182E790553404B792AA4F0095A6\ +A83291E287CDD16521A3AE8C48F56FBC909DFCCFAA7BCC570C2159F26592DCD6\ +B15BC4DD55CC05595AC634B2C3DE15360B0F07A03B5957BC9333CC5097919399\ +DD9973ACE15E55940178C4C96BB5E0A0A10BAE175769548EBCE11E0D7D9DB296\ +47F197D4B87F7039F5D4E59E016531DBEBF55A797AC9A6835032CDF34240A7EE\ +7423E89C09124829CAFC5F89431C8AFC54FD979E50D48A82B47A53523C84B600\ +4DAA323EFB708203E5388A6A5110C6CE2E341048A65FDEADEB3837A03420F9FA\ +DDC3F02A544F1E46D96B07C90C7971A7040A179E8198E90AA019268E00367120\ +D5F3D98A5CCE82C885E77144B1AAD66EE682847776B04F01F501DCBEFE390308\ +0A8058B3B8F1D823D917ECF31FC2D5B0795BF95A55C7093ECA7C801DD0BD0DBD\ +BEDE7D56513128B29FC0B4D25A6240B24C99E017BDFF7ACAFC8F8DE9FAF5A294\ +4384AECE82BEA04DCCC6D51FC6E6F27AA38F131B7959B13681A09B311D242E62\ +22A1CE5687DE5C080508B1DB16B6F8290D33A3CC0D0138AC61FD9093825E9D37\ +52889E9F20DB9F80F92750EAC88B38AC81C0016D40371EAB4A87E845E91446B0\ +A07081B84F559CDB95340CB020AF22AEA1BFF2FDA12F7A42973FF163A1C6F33D\ +B8B8214AE27ABDF1C54F5B03E29310FA210125E1296E8AF93A2996DBAEFBADD4\ +C51C2C3B8A3E2BC9FE060C42BA32768F6992A99599206CD2291CCC5BBD50856F\ +7F8D2D0AE1EFB5892C15A799B77482DE4553736B162ABB06631F1688F6746E7D\ +7A37EE7EF24E6CC901175F04960C01990178F81E957E941DEAAC8846B3704E24\ +204F43DDB0765C433F3F7D4D201459CD65682B7DDF3D47E95CDB31B96A4CB229\ +07F08BA6E92A4A07703B2DCF150F922C4B7CF181380303FB72547847305999C3\ +C8F9AC877D05D9DC4159DEB8A13D36AD1D533A56950E20F906D29D51DDC45BD1\ +5C1773991707480E37B827044BDC6473181B760A9036E0D3FA491C2F08C55130\ +D8CDD5AC8E97D0813164AF3D28A585F0C2EC7004D498F95C6B62231A632A56C2\ +D0C48FC3A6992D4051957B9ED6D9A86DBCCD962A8883CF82CAF01DA2F51A203D\ +56B6089BC8FD0B1BD414C8063031ED469555E22EF872689C130B1C101034D572\ +FD8CD0EDDABEC9EF1503D7F728B0941EFE2B9512438C7DDB176BE2EC2D9FFCD5\ +6495A4511428DF02819CDDA18D1ED5D3B16C6F42AA0AC681A9FAB51E8A1A856C\ +15C51A3EC1031427142EA12543014DD4ACAC640B8A7729E63AB7DF1051112CDE\ +FD4B988A2258334FA9A7F5B3A87A02074B9F69DD81B83FC74089A91D76AA4041\ +259E80FA255F2084902AEB9E996AC2288AB464BDEC47AAB26A28A2A819498975\ +5D48FC9A5C9279285F2F1DBB8B8018F3E4E13115D78A879792E45A8F4F24ED4A\ +317440BA63E6929056EFC1D2529B75A709D6C0097DC2D97F646F334EBE6195EC\ +5630132FDE58E25DBC17DAD822D9FA0938A2A2C926B105D108403DC29CF371C3\ +504FF73BCE9C7ACF9A74C4954CE6A32DA96B21CF3211B3E49953DAB78C49C3E5\ +32A349003C59C62F7D40261CBA63A9EA21C89A38AA63CE431C43AE261C4D9999\ +B1CAF491FAB8E7BE6E8C3454F1BE8793B2D27141FC107DA599A4694C41353D77\ +85C05B5E31440458D17C6DB66FEB8A9C5C073FB946A67AC0312BB669D9B12FAB\ +AA5272CA6631379EF4ED420A4424A5CD08526384C047C33A84D5D7DC0C215366\ +3B54C73DD799A3568C01B818992CDF8143F1DADD6B50CAE6EAE13AC66F31FFA2\ +B362CC4D2880592B7FEE4B9E4CD6AA5E5DE27AAB9B5DAD9F7D39407AE927530C\ +AB2B61CD7394A21EF47BFB813B5EA6091458D239664923280ED0D5CCA8285BB2\ +281A2F9FB3FFECC8E9147E1E8FAC957D90C9E5F513738745A47C2AD0C31FD898\ +6EF3B6388C6E821F166513811D547AB4336B5E04643497FC9F8D6E380EF6478B\ +82B6E2F5F65DD98A63C68C32B94610E1D3B9538F13A7688FBB1EC3448BE9BD77\ +BB93A34546172AE8D614F85228988E7FEB18C9A0C9827699E8B3CBC69750BDFE\ +CDA8268F694F4C509BEFC1A1166F85C829725299D173F867A300987A2D36D1BB\ +BE37BE3208FB8EFE9152A41A5F0E931B6382FF7F9B18937958FB180E61F2A8C2\ +8F36C3C80C3722935AACB81C24AA17FB3E7A1026F7031A7449818ED62BA7705C\ +A27C2D3268F90B6322921683DFF800A306CFC186CF2A61B37F35837B217E3B2C\ +ECB0843D84EAC67431E3D689F01522D4A4C73618B7C2965C9DABB15C0BE637D1\ +0CEEF72271CF39A7B803B41767BC34433C3E6FF449A439AE13DA1EAFA038CB9F\ +2E1C84F1CE39C05DF56FE3D7B82386C4E628B6E27CBC5D575C66ADA3510C246B\ +D04DB48F4AFC2D7352966DA2266C2BC9831532F53655D8BE42B421AC0D70D8AD\ +1D3587257886DBF93668E907E861BA64F45999BADB0F766EADCE5238B5ED397F\ +265935194812C03C5769137BAC97140525303CF48D65F39004A3F59B1FAB0989\ +5CEE05335D15B9B12265892F4ABB92AB1DD2002ED00CF3562CB67DFE1055968E\ +4AB3306BB34BB87D0F64B26848812A2F7B50424A21FF94081A7F70F7B684AB0F\ +092B2B085DCF84CA38414CF7290F607BF79C37EA84253ABCA8D4184D2DBE2E90\ +0200B81479E1CE8B71DCF2BD6E3C557A8E431D627BA669C2EA03068E0F7EA62C\ +29777B22142D7A1D451BD541EF8EBDDBBA4E3BD8FFCD340E935BE7C66EFC14A1\ +3EA48134F655B0DE3180101F09D204C379743A357E6DF1268B55A9F7524398EC\ +F3A59849A27B142239059998083E8FA91785E91C4D220B2FB17E3389EBAA384A\ +49D89B5D78136DD2454F06CDE9837F096B744D53221127869904AC227CDF30BF\ +EA78CC5545583F999B9C42A1184E2FB9FF3EC095B9DA0D138205C4EAC4C8C480\ +C43153608849F63E161135C79D8B6C9CFE9B8DFD8AFAB559D8B595DDD4383503\ +3B4BBD391E028BB2A60832D9B697EE61408F149744DCE71AA11BB2B0436C1E26\ +26AC3A27CDA293366B90B9CDE2D927855130758D3946B867192DCF3FCE9A3B9A\ +5276E8C37B8CB136FC90A6DC22650F95E796A9886EFD3F424BE63A66DBB1041C\ +B3D4A06F4E7EEE89F0B6D15C36F9EA010C66B332011C8888E8E4AB2B3AB52231\ +91E1388613A0FD0F07C1B26D7CC7CDF1AC62A226454D6291B431CC3EF2DB2B24\ +42B37DEFB942117FA247096BEAE598611B8104F37BEBEDD8BB8B949A89B5BF8E\ +228ECA1D8F16BFEC75A02FFBB4EEE3A6D4A6087C43634D675311E72A9F3253BB\ +5DD364E07EB4B9C84F586BA267BAFFAEFEC79E03B83B18595FE06D7E063EE604\ +FF287004D141C1A43AF0CA7C5651D98F633FA875B4743353FB07BDE59B6567AE\ +25F7095F1D9EDF30570E2F7D7EC194216898D910F9E295A41DFEE072CB56F914\ +BB78CC9854129250F9874B63BB3EBE9A1CDC6EBCB0916E1C440354DED6AA818F\ +2811DA913912A21D3961AC94A39F0827D3A419616905DC45842C8E69A43004B8\ +AE922C8DE1E8CD0668674A7760153213835BC63FAE4F8D65614AFD74A34D42AB\ +AD5025B884B34639340B45D49CCED423771916E18AA077291923017CA50795F3\ +B7A3F349A3D29923833CE57801C631576E23B838A7767CA1BDA92B82AC502DB3\ +688FFC83C09A4E40CAC31D20D9D32FA6724A80BE7091CDE9C7A6560CFB326B46\ +7CADDB9E9B7A491EDA283EFB0B61B4A1116DD859D5C0897EAA2A3FB2CD82FFB3\ +3770BF9E08091363B6B81D23E61C2A647D2BE440C5C79EA89690656D9F10B1F0\ +7942834E1CB6E2D2DF106EB6D6A21FA23819E65028515E88BD279F9317BEAFFD\ +394EA51F8639371C3A89F11305A4CA35FB0711F5E2C7C3DD1659C79024581211\ +3204B4ED8AAE9FF09D43C6DDB13F5070D98831B2C7639FB6B9B01C288812DDFA\ +8861DB32DC8268C07D30CF969953042B3DAD530D9D744C06AABE7A886C0FE57B\ +09B7F42D193FB3E9C06329818251A2F7E6474462C95DED:\ +9EF7A93FB957D1B7EF09E156186699159E65461C9C5F478CA8F1B25C6C6AF982\ +AC15F65E57ACD3ACACA75CC15C38616E0016685417E37DED05B4FE579EE2955D + +1A3DEAFCE70AF6F3F55D66AD9CE78D5F4D5C5F2638A810AFCD07D67E9F9A1380\ +D6B34BE482EF030C22F1E978F544609CCE35A74C5109EE7038495B6210CDBCA8\ +DC82C6E9E7B0D593FAD9665382B3C401AB8941DF71307DD77EBAF140AA66A1F7\ +6316478850E58886A9610631E9C722F459FA00C0B53124FB4F12778BBBA37608\ +26D3DBA67CD030A96B654AF93F8E395F5F439549489F8161683F124BC980E693\ +9C83A6085E4B6CAAF8BCD89A0E01ED70DB487166CC29735D9235A9CDC57B80C9\ +C2E591DF6322F5BEDD32937073F781A30389552AE83FBE147D1B3D3461A3DF96\ +C15CD96900C56718EAAE838417057579115936862679F5F2A45DADF65D14108A\ +F1641DF987B57986384FA1433789F5DFBE87E90BD4E9D8D4D0741FCDA7348322\ +B967B566B18612DBB8FE64F151947C3F7E361EE868676BCCD0CB3A1AFE046BE7\ +0057A05ADD3E65AF31E3FF414A627C0183E8FF583B41B75B203650420216E6DF\ +CAB289665F054CFE3EA0943647528518573BBB1D0F27E1449E98739EAF0D0094\ +32DF0C1EDC1625264B94A71DB762659FF5A3A7A867F182D1F1FD34B341A4A181\ +221870DC4A494013091A7E3B2B07E0160C438F1EE1E8A2B989C4FFEC36B5083E\ +A427606767C29672F44779A8505B422B25A56907F565B27690D011426A62DF00\ +36D57D967CD1D14E915BBC2691E7AF818C769D9E1F9EDD40894BE88FA1D7A595\ +2AFD898E837716ACD73953BF2D1D448123FD1A0276D2C2EBDC760A4B787416CF\ +AE5E963FCBDC8B551CB70F91DA0ED4A8090FEF178E879F2C34F3A269DFFFF097\ +72D44A13D7A17468B5834C460957D5243C325F63F05F89D4ED98D361E7F0AB8A\ +83948A64D0CFF8514841AA21C7F337920A9983E59BE4A0F1339E1E462F92DC1F\ +C070126206012458A499A8111FAE078E00B0CA3BC1D6C7087CD318D5603C1C7E\ +0425E6F729CEECA5F35B82F8A42E0E9B950EFB0904C5FB5C06D91D239913665E\ +D1F1EE4B82185A01BA86CA2D3EA94E5A8842231A94C05280183B7ACA28998410\ +3F122203EC2FBA4A382E6F5236D6F68DA05E3BB0C558421F0EFAB91DCEEF6D1E\ +CDC60F9B88F8BEFE31CDC3C2F024A1AF2C7336AA5D151E8CDA814A5FE898BADE\ +B9DD680E337E682EBC22BFAE445417E37D2D89A338659A280AB1206DB74DD42C\ +6F25639C1803BFDF2156DF613B0F5924D209F7F9003CE8794F989F4F27B82121\ +210F4F65EC5A1F7723305CEE438C41F793EE04496BBE337BBD2FD3023830B1C8\ +889C6F4D0C1192E364EDBE1CD987BA5D66224EE9C9405E1DFCEC0EEFFC5C73D3\ +123F6731C6295D1E6B854B884FD22B6A3BBBE5395312585CD138BCA67532C6AB\ +71BEBC6657C50DA87D2AC6068FA3970202C5E15EB7B4B3D2676C0134BCF1EAC2\ +B26BA46930B5E660B16060894884C88BFACD6779276B86F685AB6F17C6D53F62\ +1275FAD66D021D26D1D480AFAB4B5EC75E0E763FFC45F599EA02504DA5D91EB5\ +EFC3E4AE196F219E45E7CB05594958C876FF474A020EF73C1F09B1F7F7457E81\ +6D3AF51D86663D4D461754CD5E907456691E02446D6CACFD33516206A3187054\ +3D574592087773653D4086C2BDCBAB3C9B65CA11AD0D4E58DDDA8B4403099898\ +57103929549B7300CED42651D4086661694092C42875CB62858E6D1BE5F7274B\ +4BCD83AA4DA05CACA186A30902830790F9FFA24418E1F9DB00FA40477E83B05C\ +2D11AD7D81DDDB1E31F94A9DD5E9E13391C22479B570976E3AFC1BE41086D3BE\ +6689D87CA4326A7CDE8E5B396A678D3CDB2C80FECFBA2BC799AE8B1528E96D88\ +0CD098DDE910D097EAAE660AD4D7EA51C18F18AA1B39614299A172512521DFD2\ +31B9840909839EB69C892EE23F1BCEEC1FADBA75786C7DED93BC9983F74CEAB3\ +97EB8BA84F7E4130B34258D628594A6F9E2348FD91BA2594E07B8057E8A2AE3A\ +DFEA0EF919555385977041C5B6DC4F3880569171F7217AAA9A85F2F5BBDFE3FF\ +DF79248F2A35FD4DEC34980C67290339B1C0A5A6AB8838157AE2F5140B4A2492\ +4A6688AE5CE72A48103EE9029CE8A0F15B1FBB19A12FAAB80A7CD9C0E389FC27\ +75833E3190F1CF735ECDFE7F6B6C326506AA82613CBEDA8DD3691B81F4C1E3B0\ +FC32D7E6719CBFC12F4A26E0FC29D6417953ABC9568DB4ED9A294B9FD5F2A666\ +DDA546ABA301B1C60985033953EFD6F4538333B5C7DD3148814A3FD7927C366F\ +40B3D7ABBDEB2332DDB586AF80959097663CFAB2FEECAD6D368AE10EFF9663D5\ +F8BAB95935D25F45776F7F04B46817D05165A9DD4770509ABB92F8B9E7373CA7\ +80703569981754A51D6D376D65C57F55CD70E2DF5FDF5A6B829AE30CE3BF9428\ +15C8B4BE858DB58151D02A68AAB9FD373E047EFA51BD1A0CD1B61744D9E97CEB\ +A3334B3BAAFEA3BC9E43AE097CF2C3D713EECC247FF43EC74D54907D8BF45E45\ +B2E0E11D82B126A8179D3F66C055E11F69EA67AACC5FEE8AF01FAA379E51998F\ +5070F9EE0FD30A2EB22A925586FB1B39024EB5EB1E127C76A149E7F02AF1B73C\ +16E9E5A5DBE378E08A9FADF1194C625132AB3FDEFE8FE9A89BB8E0035A1A3AC5\ +278F5D3D0ADE0E41C81C6853A41C4AC45BE3F68180FE23F27F18BE2E339DE1D5\ +59D75DE63ADF7A32BAE42B037AEAA3E123A5314891BCD35CA48D57DF4C17540E\ +97202A8EA1328DA25B1FD6BE2B56AEC1E5DEB209F3B7A13ADB1CBE53EB645956\ +E577A7621D74E42376D70BC5C4AACD239A852FBB7B3F62CF59FE10438C1DC8E1\ +E46566325DA0CA43AAA63FB7E0B450A2DB3E3A2204704D894DB24B72B3078106\ +E096CD543DCF027650CB4965E38AC36A8AD588C5962B4E26548AB88F0BC20E10\ +ACC1C3FC00EF415B3C32499264552B14E2C0E789A3B8A8BFF9620FD939D0B34E\ +806177EC696A4B3B1CA4B32BA979B2690CFB3A6B17BCEE6877FFCE757E4116DA\ +01099FFE82ADD5A0C593E73449A96DB9CC2B9E846D166B095174F2CAF8B35DD8\ +78C836D9BB6EEEAF8E1BC5D0E149C739828CC480D731DC16B35B80D4AD82ED7D\ +29BD05018239EFECF8DEAE180C6A459DBCBFE4AAB9A5E2C1E1BC31418CF2EEEB\ +31FDF8BA02C9A91525E9163F672BAE2EDEC38C1BDB84EA237B4EF86BF5C0F0FF\ +E178E3761E82D94F66E5EA40BA8170BF768409E1B4177AAFD9937BCE3FBFF590\ +320D7C445372463FBBFB34F57447F42C16E026F179CBF82F617C86D1E8D42F6C\ +908F9C6B77E38D25D51303DBD781FFAB569B4CF31FD0B947C45E1768A2E9DFE8\ +369F520DC38D77937B69B821DB4FFEA8F50EBC404F0587B5598189F54B5A5B98\ +966FD16801C87DE2C3C7813DD70DC600824D426D88C55E89D47214D59206A7A6\ +5A65DA7CA2E42FA62ED17E7AA5B3ED446BCC71F17FEC8593BE96D2037BD07F94\ +76D4D732B32BC5DF8C921316B45699004716FC89F8D45BAE402C26DBCDF1A340\ +847B932FF882DBEAFBEDD252E126C89A1E1FDD8908A1F67D15D8E432DAD8E08E\ +950A3BC46B96CB89CC5BDAC703B3FA3E986EF1C6E7E6606E6845BA1EB2FBDCFE\ +E744B5E45206F4A419E1CB103C8490EB293EE9AEC1F0A0D294F9D3847737413D\ +30873F3C94740E8FD072817815EBBCE3F09EDEC9D1211A9E99547D620B2EC56C\ +89E9CB8144AE9E46636324BD13C6CCA3AB9CD9FD8F7F937ABABC598232384427\ +A2D4CE0CBF9765F7225E208C3CE128602B0AD08A1BAAB77EDB3111F0C6CA7BA0\ +EAC9D89D5B4378EB82C17F6EA08308A79A53D150D3F85EFAB77294F02EE0E288\ +5EE2AB2793392B87DB11FA77992F5B4FD75EF2F1A822E87407A4878894215AB8\ +9B6CC4A120F5A78B3C31AB80FFCC9ACEF53FC6F7F85685EB9D56D30D87C21ABB\ +F1652EEF8F32C7C567BD1F08623B09C29F33561D42727A5649A3850071AA6C11\ +735AE63C4FD31559CE560B27A362786A83353FE460B37074664A9421D3B2F6A8\ +64D5ACA087187B27E2B82F31CB3DF5E985CEA271C609B94B4E58356D40C7D5C7\ +FF2E5990FB39588154843EA5FCA92F120075D4C4D006661A0FA1B0585454BEA7\ +25473EEF7D58117D5840C8348999003736C5EEB7858FFD273A1C3EB2812F5697\ +C59110275B08F6BEFBE84C92497D5F73B7B6F794A849713B23AC5F29D5C7112F\ +B2E7A6E89EB54DDFA3122E6C79624C1BF25EBFB9FE5CE6DAA779F3ECB2984DA4\ +2F8C6ADC77B21DD291E684FCA50E46070962A2D4F00813D8DE1B8ED33FED9715\ +180C7EA8E2BB74FA65D9C7F6E142F3C81CDC59172E1020F62F65CA5A12CF2BED\ +9DEA04A4D8CABC2948F7BE823A3E792625275B3925A6C8D8E2B428C75A5DB0F7\ +120278CD7D6CAB768755C7FE2FBF89FDED1FB38AC7F76A2F8798CA36ED42CB7C\ +07F006271205F546A4812C20077F050D4CDC79459FA686E97F0704B7A9FF7DE1\ +6318E862C53D361BC635A55A264BE15016545DBFCE3C6D6849576ADEFB6884ED\ +D768214E0B438B0231B4F2692C2C0B5C177674F8A0DE236EACD9E0CEC7C8647E\ +4E9A5861B957EC834A2F8572F01304C3FD6A06019E5F1499B62BAA8670B65246\ +7FA9A4F10F053263BFE9743CC7D933F86136AAE3A6FB56754D7D238397A0030C\ +EBEA87CB255AF36138C373DBBAC41DD4A697032E4796C552AD9C9B3FA713C3A4\ +E09E0EC5581E94BE7F31065157662F9E9C678B1EF1B8B8A847C51789C22B1841\ +BCFC855820AF3258AF9E08231090B45D10046A00178E89BD515616B8A44E77BF\ +57795DABAF40687B2CDA7A5014168F:\ +A2C211D36CF26297E82789FDC7E1564AB1A615FC6277E2AE77E1FE7370C0FEF4\ +FB7B360424C44F393FC4EC2AD5061E633AFBC8D3FBB961322CDFB7AD5A4A443C + +1633256AB03B20CE079196B708A1C02D1B6072219070712C8589EE21341D5075\ +2ACB6CFDA17E982D828BBD6CDF54BC7232FD418A323D64939928597B9B52F07C\ +F488250C5E42BFD3AB48012D709F8D747225839296386FCE5FC5AECC4BA7A107\ +6D089DEA8ECEFAA0CF66FCA8602395719C12A04F929321784D7AB8239FCE2FF3\ +BDAE046A266132B5C2AD9F7261F3014E87B389A6695978693D9371D0B1FF9C40\ +5F338C2FDE4687359603950A54CF4B9CDD9B24480B239ACC5405C14C886BBB03\ +78391CEF0662A38882BDD09E3866AB9A66CFBD28EB5EE4F8009BDEFC4AEB1670\ +0EBA7DC557B489190A71FDA75E85F7EF841697F70FFD4FEA185E7A67C81C5B8F\ +273BFB97B2CEF695C1C74446C4B425BE6B2E66DC0AAACB247E4467B7C7D84EC3\ +3B6B5AB8FA1979F503008BDCFF948CDBF1226B1B066CBCF34797298F3BA8C60F\ +A01E0AC8B803223C656112FB91435D75453BAE4707B63330467DD13E0A4B992E\ +6F7E46995899A2D95D23F4AC3D0802B2A6E7D024DEA19CA408C4BBE053F14C9C\ +E264F129724A18BCB18F385B1CA091A11434EA96D98C8D0602E98EDC8DFA1414\ +1AF93ED0BA66E885E9FA108591AE59E109AE34D6B9F5586E4B4D75E7DF7C3295\ +8A65E88A9BAF41082A0A3F11539DC4EA2CBD9E1C6C3C439B622F1DE574FA7547\ +0C8C939B51D2D1C2A7204B859881D43086BFD8FB90346218D099C5AB36846F3B\ +98A7C847318BDFA01E09717943FCD864C5A8A17B6CEB89D98E872D388F20ADC2\ +BE5E2006846904F41682FB1283214F3D20DBC9FC9E0FF571844A1282E88590D7\ +C085B2C568EC5ACC4462B389FEAA5757F7033187E2DE31955FCE55FEDC909255\ +048B327CCAB2E582BBC9D8054BF5CB45145C7D3A3AF9CD5CF6ECBA490C634ECF\ +00E646BF95E8642C43A4978EF08A574EF1F78F6CE57C3B34B5A123D123617FC8\ +EC9B2AC0F9B70A7F6062D38DD7B8E9FB4ECCEF13DED5C0477483ADDAE4F1CC0C\ +FCA274B1307ED0DE72FBCB819154CDA897D7575213042615F1741A8CB646A39F\ +8D134FDF9E60E000EB8220F65CC30F5FA52C431B9E3B6101B96E25B8D0440B96\ +E572A18A01747C02AFCD7513542F7AACE194632099D16274F31EBABB60DDD94F\ +E43DACCE900EC0902EB5E686D48ED8D09AE63DA0E15C736809903A0297A92DE8\ +4E0260F11F446E1FC448E0EBF59FAEA3C726F97925C57CBDF85B1F77078D3625\ +7C85D56CBBEDCE180FE12B687ADA2DC9912FAC60334166BD2CEF06B089ED5C95\ +63844D71D8FEAD2F3A93F3C07C52537336A8A70BF5B596B9007B9FDF2D082000\ +F20E6B70D2A7E6C7ED27C4146895A6D85A246F623C1B9258A2F891F823ADE4CE\ +FFD59D4FFAD077351E2F506E9A5BDD3900F0204B9E8969AFE72F5DCCB9CDF986\ +D197AE4C4DB53014041AE6221B750E5290E307AD292C8DE6B899235212EF8CE9\ +54785537DC9435AF11E0F3427A9C7B22EFA752EA0B7EADE5F6EB4093BACB7867\ +6E506698139E4F774423B8942166F9A7D22480D814FC0AE19CF4960FBF6E01FF\ +A65C8DA5BED4F1AE2B9ECEC5BE7B3C38DD4045B0C93EE6CC77A7E61E85D331B2\ +3C0D164B104518B3405497054445A353E9B48F2AC5E8E96298D6655614336CFF\ +E6D8C9C915E387391519AD2632366AA3BC935030FD12927EFCA17505ED74C946\ +50C778539004854DF6C24269AAB9C273A493D3E5B0B1D687C33C2FACE46B4BB3\ +742D6DF743D09164D2E0EE7F6BA128BD5FBA2E3B33C199AE80FA9DEE3AD811D0\ +2BAA3D42A6362B2AD47BBA8A2C5CD00B46CF22CFE367281488A4852EB8B7FACE\ +79F0CA6F8E78D32578DFEE01711C4DCF3C26D0BA13F3075478E708C5C5315AFD\ +C2E4C0062D16458213BEC506A9E991A61825FF78DA9BA1BAABBEFA56B4A8C9E2\ +E7B60EC4B7B541C8E0F79C86BB5F03F736761A37169B2AAB8884EC6EA217B02C\ +59035F5BB327243D126B78D4AAB430212439B5A75B80618DAFEB66AA3AFF866C\ +4DAEE47D374B512E74ADA933EF24A841BA271C6F02C870E8AB950FE06E93C91D\ +F0E99165DC01BCB190E411ECCD85358FD4A88127A22E4CF4266A90845124BF97\ +B25D7B1C46D3A0D68A684F84E2A638C692A52CB6E8C651A3AC492B0460004073\ +D5349E35552359CA37660F77B2770D6B2B3F7B1922424AC4A8598B4C61A6DB50\ +7608A72A6A7D573CC055206276E14005A28A0EC41F28D7E260611D40F089FFE5\ +E529375691412F4E9E12E62C3BE2C563C26D2444EA9C69E6C935FEB4DC4E802E\ +5FE3906F8ACEF4798D940C3CD574BB5E74506C3E0B70CB62454A25F589EADB6B\ +0709FE3B50417CD1D98F08E08B7CF68A04CCCF8D6588F9FC2F31E533CDA6159B\ +AA4297FA446450D71C16EA2324EC09773E7C8817ECF680ED12F64A04863EFE3D\ +9D8760F34DE5B0860B3991FF0EE5EDBA22C4D69120DE19D5429E4AAE91C9E7CF\ +05CC807159A58F13B480872AC1609D87E7009DEDB71C09CEAAB640A2B6135855\ +CEAE4AC2954933A0255B425D9FDCD9C246F82AEB7C3BB78C6E73E03DB7AEC424\ +5A28693FBD36EF4938D59CCE19EAFC00671A0851612406A075713C5D1154D8E1\ +3B59B7C5B0902239D4BACFA386AC817AC5EE02A181A9A47C622B3ECF287E1484\ +3D452AF347110498A620B34AB4E116308D976062C9EE9CD35DB6CB79805B93AC\ +9A15AFBCB52F1ED4309879D1924A4BA190B0B86E60A516E77D34B4E0A49D4EF2\ +CEF3CC2F410FD8EC901363FC9EBD75EB460D4D8910BDF27CE26A8B4AEB94F9F7\ +6242401DC35D0644842B99FB6C439B82D82ECFE1AF0D01F9BECB15BEC83F13B2\ +60F7F714AA381032923FDE8F8018F3518547451435C9A5207294D08A907C7369\ +6F6CB000745E072E25B73B3EE11595433D27A1F11468686F08094F1D31F5ADA8\ +1F11F0677A29D72EBB2E1C4792CCC607CB938647E1F153F9EEF03D982595C631\ +E49B6B7C1FA003A6EB8D59CB8892CD0888B05240F12701753F89007C859515A2\ +FEF944BC60B36003A26702AC6FE04D2E942978FC31A97EB29871D6752399D352\ +1720729007B6A7215A4282B2A4EFC2C56BD129E74C9B00847692B96FCC71CF7A\ +7F19F3FD6B45C519FD73B4860880A2DD74E5727B31A93F0A87F0078155344AE9\ +F7BDBF00D83393B634B5DCA88A398E42C320EB95C4A826ACEA90B65E4767B2EB\ +A748F97C247568393E2FD3A66075CC12935B6D7EB5C2FF5282185CB62C73972A\ +37B3CA508004B4F796BDF82B83B5BDF90D6BFD32B5089B0CA2683DC7FB2337DE\ +42E650ED911DBEE1EF98257F9BA5AF54B1A54B04C0087A5A64BA779D86461BA1\ +5337C2E7D4955FDD777A025DE226306A17C384F1C52CDB5946FB0B46DD5C13BD\ +7A55FE2E27E4C6D40D61D6FFC024468F8EDFC7C7992DF5DC5D05063FE7231992\ +24F53678E48F25250EA28BDF1089718EB8B730D1C06735C2F871164E2EB5E885\ +A8DFD2A083BE97EDC94159CE9BF75D2433F1D782762F771903CBF9A1C9D13F71\ +0BA0E151B079DC0A8262BCEB1DBCBBC0F35DF6EECF7BAA7105B9808745853C96\ +B4372E95E482035916B726DAC7BE95A72B19DAD48DB1B19E6EB2EDAB5AC1B301\ +3839E7806625ABC129F41813E6D71EE4AB2040D81E42E6ED73ABBA64FF2EB433\ +B910EA7D4F5ED3D8D27D39BB454EC019DF6114F544D7B155549D0C56D14551FA\ +F353994A80F30F3C97E863A4F2AF316468A568038EB4D799350A6FACAFF90ECD\ +44E0F44EFB6DC42EE4B0DC2C59EA9C1827326DF08C0A6E55CF4F9C3EA0E78CFF\ +3635F5D08E44F1400D20F638D56BA84B4832090454DE57EF04B6C8805A36F63E\ +5CCC6E830C87FFC164647CED20E4C486D09DE7A5F9E4B68D5456CDB22B0DDED2\ +B95B3BCAE529215C2D25D6823C7D66A4FAE0A1E9F022BA5663204F2314DFA51A\ +1F10E11D6D62A8BA6C28B6AE7DA1DEB5B57F2B65D7456059AD9F03DC5A524054\ +DA39DD100D74EB657DE219795E3C45A0E4C762BA22F9DA9D8159E425A1EE783B\ +4B22C250D8894CBEC706CE16D5CA393404FF478F141BE7CC69E45B077BA1955F\ +1F49EFBE4847C795347F703300F672334F490ABF8B644A34B56DA00EC45A3503\ +14B9ADF27CAF7C51CB7DBA0C5477E7D37662F4F23247BCB8F7DD5F3E9CB8BDA4\ +0FA97568832AF0ADC68F71422E412254A6BFC8943BB465B01FCC8DE0B957677C\ +78BC1F7566953E9D2446239F602C682A521C14F741FEA98C7E27AABEC339B6F5\ +B94C78287A894AFDAE971F8DA7C7E4A4C92C8DA47BE82DC2532EC2DA9BACEDD2\ +BE6DB2B2FB34DCCDCB34116507376578CBCA105E5E443BEC0F2EF23BE34CDF86\ +2EDAB34F0FF21335E3ACD92F59688B419F824EA61EEA82BC80E3463452192377\ +131BA51FB0795E089FC077D0ECA8012E58B0637AD7022206887FE9EC00EE5DF7\ +AD2E26FE819EE35C7A179C579098AA3DF645D9064CD557DA90BDD21F871CEB04\ +8CA56DF9653A10ED60F5E9F0ED7F8D89BCF5C22D1143CF44718FF2DFD8E10CEF\ +8AABB67D2305F18177C1426BD4CD03F2625E459CE905067826A214E08E56D8F9\ +455593E6B324E72DEDCC429D3BEFE2AE0599E360DF95E80D453A3A849E48389F\ +A745635BEDE30E7932DE6A3816E31A2217F98D5E40238963D0A36C159FD4EC32\ +D8A5CF59D433DEF3378634AF6887FDB3F3EDB96FC8840FE1B538C329674AE810\ +E8C8B2B46DB208716D38E9D1AEAB097068AD83ADD7DD2647839B3A7388B0615B\ +DE26F8692E9C07D8ADECC2A875203C3D3A9C6CB1D7D06307E9E1D9C3BC536DD8\ +EB271E9A2159C904E61E8C9357FE759F36366AEF5A3D14CEE82913CD2708AA60\ +69369CED763C8E830D70924E82E9015C2998E86EFC1DCE6AC2EBCB49455542A6\ +D7DAB265AD6D7381FFEEE1AA40F8FAC0659B6FB56BB03CD8CAFAACD48D13672F\ +7D524EB9684CFED4DBB7476E99149C28EC08F33BA6AFF839AA178F86B8EEAF17\ +39C829177BA78547AD394136AA3FAD451A11E9642506568B39668B2436610E06\ +EA45FA11D04D3759B033B5382645F15B3C39270B81B80487643913A24F2F1C1A\ +1ED57C85CCDDC8CD6D59B62FA67CC80572968C8FD01894F0153634C88792A7C4\ +A407A4A4CE46CEC5FE5D2569F95A27DE242444EA0C715B357518CAEA23E767E8\ +545983F0D3A4DF66111B4AA1D399CCAFD796D7A80E592D5A51D2B3F60B5B04F8\ +D9C009CA56CBD4DD84127A29B72ADB7645FB7279C9818B2B43963BD605F45B65\ +75A5E2E369E0B401F5EC10EC703F1179B0AB9D4A89D6F096573952E513827364\ +A84D38922734137E969D8167D6959B70F42F2BDA37E4C989ABAA8024C1A84ED6\ +BEB74780927F78B32EA736B9B2B4A795C355C0319811729D9CC399D235197303\ +38D62E16E5035FC52A817090703FE776D65EF9FEF5BA5F4FFEC3CC8E9EB2E312\ +C50A479BDD4E6AB0A56C18C2DF69ED408417BEE28BB41DD13F8366FF6EDA4B34\ +090FC9BC045271:\ +B5BA769BC397D0F2B541E1C996C40F64C3E6BE52950898BC0380513F8E6F754A\ +41025B104D2B5BD872D1D427A8E98F089C9AAF3B5071668C65437F0EF48855CD + # FORK-256 vectors generated by the implementation in Botan; there is only one # test vector, and it only covers the compression function, not the entire # hash. The implementation of FORK-256 used to generate these vectors did pass @@ -31768,7 +35832,6 @@ B8847AA6FE095FA629D090307AA2D686C7D628B12D63BCFD8E4F6BE8CCE039E8CB69\ 90AFA11E57550766745BD3401459373A418A360D4C4B9275714679517C73F60FAE:\ 81D2AC8F3A2C92E190ED1AAA0F7EEF24579E697A -:DA39A3EE5E6B4B0D3255BFEF95601890AFD80709 616263:A9993E364706816ABA3E25717850C26C9CD0D89D 6162636462636465636465666465666765666768666768696768696A\ 68696A6B696A6B6C6A6B6C6D6B6C6D6E6C6D6E6F6D6E6F706E6F7071:\ @@ -42748,6 +46811,47 @@ C65D515D8FDF3465396DBEA4C44F6F069C597FF9AAA32227:\ 0123456789ABCDEF0123456789ABCDEF:98E523EADE38B3BF4EBF51D7EE814316C9EB3159:\ 0123456789ABCDEF0123456789ABCDEF01234567 +# From the NIST submission package +[HMAC(BMW-512)] +53616D706C65202331:\ +7017DB5D590A803ECDD0E87818083D657BB85636ED039BAAD3185D8CAB82E017\ +2D1957757D6E5E2F288D43E032635E8FC4B9FAA9FD445CB1161F7786D805529F:\ +000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F\ +202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F + +53616D706C65202332:\ +CEF9110B1F90A24080C8CE794FD922F8669A1A0A74299DB9789D9BD9CCC8BA7E\ +9438BD2383F14D3C9278FDB65C0A3FCFCBF2EB570C08588488F5F9AF428D8F67:\ +303132333435363738393A3B3C3D3E3F40414243 + +546865207375636365737366756C20766572696669636174696F6E206F662061\ +204D414320646F6573206E6F7420636F6D706C6574656C792067756172616E74\ +6565207468617420746865206163636F6D70616E79696E67206D657373616765\ +2069732061757468656E7469632E:\ +8519939233A4547258AFB322FAABDECFBE3F99B83CD0F760944B3F9B9FC0CD2D\ +BBA98A069CC267CA80B53D9BA6D9E89C5A02173C661E5E715902D5F5B23FEA9F:\ +505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F\ +707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F\ +909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAF\ +B0B1B2B3505152535455565758595A5B5C5D5E5F606162636465666768696A6B\ +6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B\ +8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAAB\ +ACADAEAFB0B1B2B3 + +546865207375636365737366756C20766572696669636174696F6E206F662061\ +204D414320646F6573206E6F7420636F6D706C6574656C792067756172616E74\ +6565207468617420746865206163636F6D70616E79696E67206D657373616765\ +2069732061757468656E7469633A2074686572652069732061206368616E6365\ +2074686174206120736F757263652077697468206E6F206B6E6F776C65646765\ +206F6620746865206B65792063616E2070726573656E74206120707572706F72\ +746564204D41432E:\ +44FCDF6C712B75BE3CA93EB2F98ECEAB23D7C5A3839C2D267CFE0A9A202E7375\ +6B8B30882D94725A82D2C705B5256154231EC14756CCF4A7132E911CA24C1AAB:\ +505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F\ +707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F\ +909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAF\ +B0B1B2B3 + # From draft-ietf-tls-seedhas-00.txt [HMAC(HAS-160)] 4869205468657265:\ diff --git a/configure.py b/configure.py index 7f597a853..2e0c31fe2 100755 --- a/configure.py +++ b/configure.py @@ -36,8 +36,8 @@ class BuildConfigurationInformation(object): Version information """ version_major = 1 - version_minor = 8 - version_patch = 8 + version_minor = 9 + version_patch = 2 version_so_patch = 2 version_suffix = '' @@ -55,6 +55,12 @@ class BuildConfigurationInformation(object): self.checkobj_dir = os.path.join(self.build_dir, 'checks') self.libobj_dir = os.path.join(self.build_dir, 'lib') + self.python_dir = os.path.join(options.src_dir, 'wrap', 'python') + + self.use_boost_python = options.boost_python + + self.pyobject_dir = os.path.join(self.build_dir, 'python') + self.include_dir = os.path.join(self.build_dir, 'include') self.full_include_dir = os.path.join(self.include_dir, 'botan') @@ -71,6 +77,10 @@ class BuildConfigurationInformation(object): [os.path.join(checks_dir, file) for file in os.listdir(checks_dir) if file.endswith('.cpp')]) + self.python_sources = sorted( + [os.path.join(self.python_dir, file) for file in os.listdir(self.python_dir) + if file.endswith('.cpp')]) + def doc_files(self): docs = ['readme.txt'] @@ -87,6 +97,14 @@ class BuildConfigurationInformation(object): return 'botan-%d.%d.pc' % (self.version_major, self.version_minor) + def build_dirs(self): + dirs = [self.checkobj_dir, + self.libobj_dir, + self.full_include_dir] + if self.use_boost_python: + dirs.append(self.pyobject_dir) + return dirs + def username(self): return getpass.getuser() @@ -115,6 +133,15 @@ def process_command_line(args): target_group.add_option('--with-endian', metavar='ORDER', default=None, help='override guess of CPU byte order') + target_group.add_option('--with-unaligned-mem', + dest='unaligned_mem', action='store_true', + default=None, + help='enable unaligned memory accesses') + + target_group.add_option('--without-unaligned-mem', + dest='unaligned_mem', action='store_false', + help=SUPPRESS_HELP) + build_group = OptionGroup(parser, 'Build options') build_group.add_option('--enable-shared', dest='build_shared_lib', @@ -137,6 +164,10 @@ def process_command_line(args): build_group.add_option('--disable-debug', dest='debug_build', action='store_false', help=SUPPRESS_HELP) + build_group.add_option('--use-boost-python', dest='boost_python', + default=False, action='store_true', + help='enable Boost.Python wrapper') + build_group.add_option('--with-tr1-implementation', metavar='WHICH', dest='with_tr1', default=None, help='enable TR1 (options: none, system, boost)') @@ -326,14 +357,21 @@ class ModuleInfo(object): lex_me_harder(infofile, self, ['add', 'requires', 'os', 'arch', 'cc', 'libs'], - { 'realname': '<UNKNOWN>', - 'load_on': 'request', + { 'load_on': 'auto', 'define': None, 'modset': None, 'uses_tr1': 'false', 'note': '', 'mp_bits': 0 }) + if self.add == []: + for (dirpath, dirnames, filenames) in os.walk(self.lives_in): + if dirpath == self.lives_in: + self.add = [filename for filename in filenames + if filename.endswith('.cpp') or + filename.endswith('.h') or + filename.endswith('.S')] + # Coerce to more useful types self.libs = force_to_dict(self.libs) @@ -386,8 +424,7 @@ class ArchInfo(object): def __init__(self, infofile): lex_me_harder(infofile, self, ['aliases', 'submodels', 'submodel_aliases'], - { 'realname': '<UNKNOWN>', - 'default_submodel': None, + { 'default_submodel': None, 'endian': None, 'unaligned': 'no' }) @@ -404,7 +441,7 @@ class ArchInfo(object): self.submodel_aliases.items(), key = lambda k: len(k[0]), reverse = True) - def defines(self, target_submodel, with_endian): + def defines(self, target_submodel, with_endian, unaligned_ok): macros = ['TARGET_ARCH_IS_%s' % (self.basename.upper())] def form_cpu_macro(cpu_name): @@ -419,7 +456,12 @@ class ArchInfo(object): elif self.endian != None: macros.append('TARGET_CPU_IS_%s_ENDIAN' % (self.endian.upper())) - macros.append('TARGET_UNALIGNED_LOADSTOR_OK %d' % (self.unaligned_ok)) + if unaligned_ok is None: + unaligned_ok = self.unaligned_ok + + if unaligned_ok: + logging.info('Assuming unaligned memory access works on this CPU') + macros.append('TARGET_UNALIGNED_LOADSTOR_OK %d' % (unaligned_ok)) return macros @@ -427,8 +469,8 @@ class CompilerInfo(object): def __init__(self, infofile): lex_me_harder(infofile, self, ['so_link_flags', 'mach_opt', 'mach_abi_linking'], - { 'realname': '<UNKNOWN>', - 'binary_name': None, + { 'binary_name': None, + 'macro_name': None, 'compile_option': '-c ', 'output_to_option': '-o ', 'add_include_dir_option': '-I', @@ -469,6 +511,7 @@ class CompilerInfo(object): del self.mach_opt + def mach_abi_link_flags(self, osname, arch, submodel): abi_link = set() @@ -495,28 +538,38 @@ class CompilerInfo(object): return '' + def library_opt_flags(self, debug_build): + flags = self.lib_opt_flags + if debug_build and self.debug_flags != '': + flags += ' ' + self.debug_flags + if not debug_build and self.no_debug_flags != '': + flags += ' ' + self.no_debug_flags + return flags + def so_link_command_for(self, osname): if osname in self.so_link_flags: return self.so_link_flags[osname] return self.so_link_flags['default'] def defines(self, with_tr1): - if with_tr1: - if with_tr1 == 'boost': - return ['USE_BOOST_TR1'] - elif with_tr1 == 'system': + + def tr1_macro(): + if with_tr1: + if with_tr1 == 'boost': + return ['USE_BOOST_TR1'] + elif with_tr1 == 'system': + return ['USE_STD_TR1'] + elif self.compiler_has_tr1: return ['USE_STD_TR1'] - elif self.compiler_has_tr1: - return ['USE_STD_TR1'] + return [] - return [] + return ['BUILD_COMPILER_IS_' + self.macro_name] + tr1_macro() class OsInfo(object): def __init__(self, infofile): lex_me_harder(infofile, self, ['aliases', 'target_features', 'supports_shared'], - { 'realname': '<UNKNOWN>', - 'os_type': None, + { 'os_type': None, 'obj_suffix': 'o', 'so_suffix': 'so', 'static_suffix': 'a', @@ -543,7 +596,15 @@ class OsInfo(object): ['TARGET_OS_HAS_' + feat.upper() for feat in self.target_features] +def fixup_proc_name(proc): + proc = proc.lower().replace(' ', '') + for junk in ['(tm)', '(r)']: + proc = proc.replace(junk, '') + return proc + def canon_processor(archinfo, proc): + proc = fixup_proc_name(proc) + for ainfo in archinfo.values(): if ainfo.basename == proc or proc in ainfo.aliases: return (ainfo.basename, ainfo.basename) @@ -560,12 +621,7 @@ def guess_processor(archinfo): if base_proc == '': raise Exception('Could not determine target CPU; set with --cpu') - full_proc = platform.processor().lower().replace(' ', '') - for junk in ['(tm)', '(r)']: - full_proc = full_proc.replace(junk, '') - - if full_proc == '': - full_proc = base_proc + full_proc = fixup_proc_name(platform.processor()) or base_proc for ainfo in archinfo.values(): if ainfo.basename == base_proc or base_proc in ainfo.aliases: @@ -704,7 +760,7 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo): options.arch, options.cpu), - 'lib_opt': cc.lib_opt_flags, + 'lib_opt': cc.library_opt_flags(options.debug_build), 'mach_opt': cc.mach_opts(options.arch, options.cpu), 'check_opt': cc.check_opt_flags, 'lang_flags': cc.lang_flags + options.extra_flags, @@ -725,7 +781,8 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo): cc.defines(options.with_tr1)), 'target_cpu_defines': make_cpp_macros( - arch.defines(options.cpu, options.with_endian)), + arch.defines(options.cpu, options.with_endian, + options.unaligned_mem)), 'include_files': makefile_list(build_config.headers), @@ -745,6 +802,14 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo): build_commands(build_config.check_sources, build_config.checkobj_dir, 'CHECK')), + 'python_objs': makefile_list( + objectfile_list(build_config.python_sources, + build_config.pyobject_dir)), + + 'python_build_cmds': '\n'.join( + build_commands(build_config.python_sources, + build_config.pyobject_dir, 'PYTHON')), + 'ar_command': cc.ar_command or osinfo.ar_command, 'ranlib_command': osinfo.ranlib_command(), 'install_cmd_exec': osinfo.install_cmd_exec, @@ -764,8 +829,9 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo): 'doc_files': makefile_list(build_config.doc_files()), - 'mod_list': '\n'.join(['%s (%s)' % (m.basename, m.realname) - for m in sorted(modules)]), + 'mod_list': '\n'.join(sorted([m.basename for m in modules])), + + 'python_version': '.'.join(map(str, sys.version_info[0:2])) } """ @@ -957,10 +1023,8 @@ def setup_build(build_config, options, template_vars): except OSError, e: logging.debug('Error while removing build dir: %s' % (e)) - for dirs in [build_config.checkobj_dir, - build_config.libobj_dir, - build_config.full_include_dir]: - os.makedirs(dirs) + for dir in build_config.build_dirs(): + os.makedirs(dir) makefile_template = os.path.join( options.makefile_dir, @@ -979,6 +1043,10 @@ def setup_build(build_config, options, template_vars): templates_to_proc[os.path.join(options.build_data, template)] = \ os.path.join(build_config.build_dir, sink) + if options.boost_python: + templates_to_proc[ + os.path.join(options.makefile_dir, 'python.in')] = 'Makefile.python' + for (template, sink) in templates_to_proc.items(): try: f = open(sink, 'w') diff --git a/doc/building.tex b/doc/building.tex index aa4435c14..f58786e76 100644 --- a/doc/building.tex +++ b/doc/building.tex @@ -13,7 +13,7 @@ \title{\textbf{Botan Build Guide}} \author{Jack Lloyd \\ \texttt{[email protected]}} -\date{2008-11-24} +\date{2009-10-09} \newcommand{\filename}[1]{\texttt{#1}} \newcommand{\module}[1]{\texttt{#1}} @@ -41,61 +41,58 @@ POSIX (such as VMS, MacOS 9, OS/390, OS/400, ...) are not supported by the build system, primarily due to lack of access. Please contact the maintainer if you would like to build Botan on such a system. -Botan's build is controlled by configure.pl, which is a Perl -script. Perl 5.6 or later is required. +Botan's build is controlled by configure.py, which is a Python +script. Python 2.4 or later is required. \section{For the Impatient} \begin{verbatim} -$ ./configure.pl [--prefix=/some/directory] +$ ./configure.py [--prefix=/some/directory] $ make $ make install \end{verbatim} Or using \verb|nmake|, if you're compiling on Windows with Visual C++. On platforms that do not understand the '\#!' convention for -beginning script files, or that have Perl installed in an unusual -spot, you might need to prefix the \texttt{configure.pl} command with -\texttt{perl} or \texttt{/path/to/perl}. +beginning script files, or that have Python installed in an unusual +spot, you might need to prefix the \texttt{configure.py} command with +\texttt{python} or \texttt{/path/to/python}. \section{Building the Library} -The first step is to run \filename{configure.pl}, which is a Perl +The first step is to run \filename{configure.py}, which is a Python script that creates various directories, config files, and a Makefile -for building everything. The script requires at least Perl 5.6; any -later version should also work. +for building everything. The script requires at least Python 2.4; any +later version of Python 2.x should also work. The script will attempt to guess what kind of system you are trying to compile for (and will print messages telling you what it guessed). You can override this process by passing the options \verb|--cc|, -\verb|--os|, and \verb|--cpu| -- acceptable values are printed if -you run \verb|configure.pl| with \verb|--help|. +\verb|--os|, and \verb|--cpu|. You can pass basically anything reasonable with \verb|--cpu|: the script knows about a large number of different architectures, their -sub-models, and common aliases for them. The script does not display -all the possibilities in its help message because there are simply too -many entries. You should only select the 64-bit version of a CPU (such -as ``sparc64'' or ``mips64'') if your operating system knows how to -handle 64-bit object code -- a 32-bit kernel on a 64-bit CPU will -generally not like 64-bit code. +sub-models, and common aliases for them. You should only select the +64-bit version of a CPU (such as ``sparc64'' or ``mips64'') if your +operating system knows how to handle 64-bit object code -- a 32-bit +kernel on a 64-bit CPU will generally not like 64-bit code. By default the script tries to figure out what will work on your -system, and use that. It will print a display at the end showing -which algorithms have and have not been abled. For instance on one -system we might see the line: +system, and use that. It will print a display at the end showing which +algorithms have and have not been enabled. For instance on one system +we might see lines like: \begin{verbatim} - (loading): entropy: [beos_stats] buf_es [cryptoapi_rng] - dev_random egd proc_walk unix_procs [win32_stats] + INFO: Skipping mod because CPU incompatible - asm_amd64 mp_amd64 mp_asm64 sha1_amd64 + INFO: Skipping mod because OS incompatible - cryptoapi_rng win32_stats + INFO: Skipping mod because compiler incompatible - mp_ia32_msvc + INFO: Skipping mod because loaded on request only - bzip2 gnump openssl qt_mutex zlib \end{verbatim} -The names listed in brackets are disabled, the others are -enabled. Here we see the list of entropy sources which are going to be -compiled into Botan. Since this particular line comes when Botan was -configuring for a Linux system, the Win32 and BeOS specific modules -were disabled, while modules that use Unix APIs and /dev/random are -built. +The ones that are 'loaded on request only' have to be explicitly asked +for, because they rely on third party libraries which your system +might not have. For instance to enable zlib support, add +\verb|--with-zlib| to your invocation of \verb|configure.py|. You can control which algorithms and modules are built using the options ``\verb|--enable-modules=MODS|'' and @@ -104,20 +101,6 @@ options ``\verb|--enable-modules=MODS|'' and Modules not listed on the command line will simply be loaded if needed or if configured to load by default. -Not all OSes or CPUs have specific support in -\filename{configure.pl}. If the CPU architecture of your system isn't -supported by \filename{configure.pl}, use 'generic'. This setting -disables machine-specific optimization flags. Similarly, setting OS to -'generic' disables things which depend greatly on OS support -(specifically, shared libraries). - -However, it's impossible to guess which options to give to a system -compiler. Thus, if you want to compile Botan with a compiler which -\filename{configure.pl} does not support, you will need to tell it how -that compiler works. This is done by adding a new file in the -directory \filename{src/build-data/cc}; the existing files should put you -in the right direction. - The script tries to guess what kind of makefile to generate, and it almost always guesses correctly (basically, Visual C++ uses NMAKE with Windows commands, and everything else uses Unix make with POSIX @@ -128,14 +111,12 @@ commonly used by Windows compilers. To add a new variant (eg, a build script for VMS), you will need to create a new template file in \filename{src/build-data/makefile}. -\pagebreak - \subsection{POSIX / Unix} The basic build procedure on Unix and Unix-like systems is: \begin{verbatim} - $ ./configure.pl [--enable-modules=<list>] [--cc=CC] + $ ./configure.py [--enable-modules=<list>] [--cc=CC] $ make # You may need to set your LD_LIBRARY_PATH or equivalent for ./check to run $ make check # optional, but a good idea @@ -148,9 +129,9 @@ found within your PATH. The \verb|make install| target has a default directory in which it will install Botan (typically \verb|/usr/local|). You can override this by using the \texttt{--prefix} argument to -\filename{configure.pl}, like so: +\filename{configure.py}, like so: -\verb|./configure.pl --prefix=/opt <other arguments>| +\verb|./configure.py --prefix=/opt <other arguments>| On some systems shared libraries might not be immediately visible to the runtime linker. For example, on Linux you may have to edit @@ -163,10 +144,10 @@ to include the directory that the Botan libraries were installed into. The situation is not much different here. We'll assume you're using Visual C++ (for Cygwin, the Unix instructions are probably more relevant). You need to -have a copy of Perl installed, and have both Perl and Visual C++ in your path. +have a copy of Python installed, and have both Python and Visual C++ in your path. \begin{verbatim} - > perl configure.pl --cc=msvc (or --cc=gcc for MinGW) [--cpu=CPU] + > python configure.py --cc=msvc (or --cc=gcc for MinGW) [--cpu=CPU] > nmake > nmake check # optional, but recommended \end{verbatim} @@ -244,7 +225,7 @@ environment in a different directory. \subsection{Local Configuration} You may want to do something peculiar with the configuration; to -support this there is a flag to \filename{configure.pl} called +support this there is a flag to \filename{configure.py} called \texttt{--with-local-config=<file>}. The contents of the file are inserted into \filename{build/build.h} which is (indirectly) included into every Botan header and source file. @@ -395,4 +376,70 @@ is less of a problem - only the developer needs to worry about it. As long as they can remember where they installed Botan, they just have to set the appropriate flags in their Makefile/project file. +\pagebreak + +\section{Language Wrappers} + +\subsection{Building the Python wrappers} + +The Python wrappers for Botan use Boost.Python, so you must have Boost +installed. To build the wrappers, add the flag + +\verb|--use-boost-python| + +to \verb|configure.py|. This will create a second makefile, +\verb|Makefile.python|, with instructions for building the Python +module. After building the library, execute + +\begin{verbatim} +$ make -f Makefile.python +\end{verbatim} + +to build the module. Currently only Unix systems are supported, and +the Makefile assumes that the version of Python you want to build +against is the same one you used to run \verb|configure.py|. + +To install the module, use the \verb|install| target. + +Examples of using the Python module can be seen in \filename{doc/python} + +\subsection{Building the Perl XS wrappers} + +To build the Perl XS wrappers, change your directory to +\filename{src/wrap/perl-xs} and run \verb|perl Makefile.PL|, then run +\verb|make| to build the module and \verb|make test| to run the test +suite. + +\begin{verbatim} +$ perl Makefile.PL +Checking if your kit is complete... +Looks good +Writing Makefile for Botan +$ make +cp Botan.pm blib/lib/Botan.pm +AutoSplitting blib/lib/Botan.pm (blib/lib/auto/Botan) +/usr/bin/perl5.8.8 /usr/lib64/perl5/5.8.8/ExtUtils/xsubpp [...] +g++ -c -Wno-write-strings -fexceptions -g [...] +Running Mkbootstrap for Botan () +chmod 644 Botan.bs +rm -f blib/arch/auto/Botan/Botan.so +g++ -shared Botan.o -o blib/arch/auto/Botan/Botan.so \ + -lbotan -lbz2 -lpthread -lrt -lz \ + +chmod 755 blib/arch/auto/Botan/Botan.so +cp Botan.bs blib/arch/auto/Botan/Botan.bs +chmod 644 blib/arch/auto/Botan/Botan.bs +Manifying blib/man3/Botan.3pm +$ make test +PERL_DL_NONLAZY=1 /usr/bin/perl5.8.8 [...] +t/base64......ok +t/filt........ok +t/hex.........ok +t/oid.........ok +t/pipe........ok +t/x509cert....ok +All tests successful. +Files=6, Tests=83, 0 wallclock secs ( 0.08 cusr + 0.02 csys = 0.10 CPU) +\end{verbatim} + \end{document} diff --git a/doc/examples/GNUmakefile b/doc/examples/GNUmakefile index d854c81d8..44fcfeea5 100644 --- a/doc/examples/GNUmakefile +++ b/doc/examples/GNUmakefile @@ -2,8 +2,8 @@ BOTAN_CONFIG = botan-config CXX = g++ -CFLAGS = -O2 -ansi -W -Wall $(shell $(BOTAN_CONFIG) --cflags) -LIBS = $(shell $(BOTAN_CONFIG) --libs) +CFLAGS = -O2 -ansi -W -Wall -I../../build/include +LIBS = -L../.. -lbotan SRCS=$(wildcard *.cpp) diff --git a/doc/examples/bench.cpp b/doc/examples/bench.cpp index 37ef1104d..cc43fade0 100644 --- a/doc/examples/bench.cpp +++ b/doc/examples/bench.cpp @@ -7,26 +7,6 @@ using namespace Botan; #include <iostream> -double best_speed(const std::string& algorithm, - u32bit milliseconds, - RandomNumberGenerator& rng, - Timer& timer) - { - std::map<std::string, double> speeds = - algorithm_benchmark(algorithm, milliseconds, - timer, rng, - global_state().algorithm_factory()); - - double best_time = 0; - - for(std::map<std::string, double>::const_iterator i = speeds.begin(); - i != speeds.end(); ++i) - if(i->second > best_time) - best_time = i->second; - - return best_time; - } - const std::string algos[] = { "AES-128", "AES-192", @@ -62,7 +42,6 @@ const std::string algos[] = { "FORK-256", "GOST-34.11", "HAS-160", - "HAS-V", "MD2", "MD4", "MD5", @@ -81,18 +60,40 @@ const std::string algos[] = { "", }; -int main() +void benchmark_algo(const std::string& algo, + RandomNumberGenerator& rng) + { + u32bit milliseconds = 3000; + Default_Benchmark_Timer timer; + Algorithm_Factory& af = global_state().algorithm_factory(); + + std::map<std::string, double> speeds = + algorithm_benchmark(algo, milliseconds, timer, rng, af); + + std::cout << algo << ":"; + + for(std::map<std::string, double>::const_iterator i = speeds.begin(); + i != speeds.end(); ++i) + { + std::cout << " " << i->second << " [" << i->first << "]"; + } + std::cout << "\n"; + } + +int main(int argc, char* argv[]) { LibraryInitializer init; - u32bit milliseconds = 1000; AutoSeeded_RNG rng; - Default_Benchmark_Timer timer; - for(u32bit i = 0; algos[i] != ""; ++i) + if(argc == 1) // no args, benchmark everything + { + for(u32bit i = 0; algos[i] != ""; ++i) + benchmark_algo(algos[i], rng); + } + else { - std::string algo = algos[i]; - std::cout << algo << ' ' - << best_speed(algo, milliseconds, rng, timer) << "\n"; + for(int i = 1; argv[i]; ++i) + benchmark_algo(argv[i], rng); } } diff --git a/doc/examples/cms_dec.cpp b/doc/examples/cms_dec.cpp index 3fa285395..de4d732f0 100644 --- a/doc/examples/cms_dec.cpp +++ b/doc/examples/cms_dec.cpp @@ -10,7 +10,7 @@ int main(int argc, char* argv[]) { if(argc != 2) { - printf("Usage: %s <filename>\n", argv[0]); + std::cout << "Usage: " << argv[0] << " <filename>\n"; return 1; } diff --git a/doc/examples/cpuid.cpp b/doc/examples/cpuid.cpp new file mode 100644 index 000000000..1bdee787c --- /dev/null +++ b/doc/examples/cpuid.cpp @@ -0,0 +1,17 @@ +#include <stdio.h> + +#include <botan/cpuid.h> + +using namespace Botan; + +int main() + { + printf("Cache line size: %d\n", CPUID::cache_line_size()); + printf("RDTSC: %d\n", CPUID::has_rdtsc()); + printf("SSE2 %d\n", CPUID::has_sse2()); + printf("SSSE3 %d\n", CPUID::has_ssse3()); + printf("SSE41 %d\n", CPUID::has_sse41()); + printf("SSE42 %d\n", CPUID::has_sse42()); + + printf("AltiVec %d\n", CPUID::has_altivec()); + } diff --git a/doc/examples/package.cpp b/doc/examples/package.cpp new file mode 100644 index 000000000..866dd7e96 --- /dev/null +++ b/doc/examples/package.cpp @@ -0,0 +1,61 @@ + +#include <botan/botan.h> +#include <botan/serpent.h> +#include <botan/package.h> + +#include <iostream> +#include <fstream> +#include <vector> + +using namespace Botan; + +std::vector<byte> slurp_file(const std::string& filename) + { + std::ifstream in(filename.c_str()); + + std::vector<byte> out; + byte buf[4096] = { 0 }; + + while(in.good()) + { + in.read((char*)buf, sizeof(buf)); + ssize_t got = in.gcount(); + + out.insert(out.end(), buf, buf+got); + } + + return out; + } + +int main(int argc, char* argv[]) + { + if(argc != 2) + { + std::cout << "Usage: " << argv[0] << " filename\n"; + return 1; + } + + LibraryInitializer init; + + AutoSeeded_RNG rng; + + BlockCipher* cipher = new Serpent; + + std::vector<byte> input = slurp_file(argv[1]); + std::vector<byte> output(input.size() + cipher->BLOCK_SIZE); + + AllOrNothingTransform::package(rng, new Serpent, + &input[0], input.size(), + &output[0]); + + std::vector<byte> unpackage_output(output.size() - cipher->BLOCK_SIZE); + + AllOrNothingTransform::unpackage(new Serpent, + &output[0], output.size(), + &unpackage_output[0]); + + if(unpackage_output == input) + std::cout << "Package/unpackage worked\n"; + else + std::cout << "Something went wrong :(\n"; + } diff --git a/doc/examples/tss.cpp b/doc/examples/tss.cpp new file mode 100644 index 000000000..1881ffe24 --- /dev/null +++ b/doc/examples/tss.cpp @@ -0,0 +1,38 @@ +#include <botan/botan.h> +#include <botan/tss.h> +#include <iostream> +#include <stdio.h> + +namespace { + +void print(const Botan::SecureVector<Botan::byte>& r) + { + for(Botan::u32bit i = 0; i != r.size(); ++i) + printf("%02X", r[i]); + printf("\n"); + } + +} + +int main() + { + using namespace Botan; + + LibraryInitializer init; + + AutoSeeded_RNG rng; + + byte id[16]; + for(int i = 0; i != 16; ++i) + id[i] = i; + + const byte S2[] = { 0xDE, 0xAD, 0xCA, 0xFE, 0xBA, 0xBE, 0xBE, 0xEF }; + + std::vector<RTSS_Share> shares = + RTSS_Share::split(4, 6, S2, sizeof(S2), id, rng); + + for(size_t i = 0; i != shares.size(); ++i) + std::cout << i << " = " << shares[i].to_string() << "\n"; + + print(RTSS_Share::reconstruct(shares)); + } diff --git a/doc/log.txt b/doc/log.txt index 97476c381..97e40db5e 100644 --- a/doc/log.txt +++ b/doc/log.txt @@ -1,4 +1,34 @@ +* 1.9.2, 2009-11-03 + - Add SIMD version of XTEA + - Support both SSE2 and AltiVec SIMD for Serpent and XTEA + - Optimizations for SHA-1 and SHA-2 + - Add AltiVec runtime detection + - Fix x86 CPU identification with Intel C++ and Visual C++ + +* 1.9.1, 2009-10-23 + - Better support for Python and Perl wrappers + - Add an implementation of Blue Midnight Wish (Round 2 tweak version) + - Modify Skein-512 to match the tweaked 1.2 specification + - Add threshold secret sharing (draft-mcgrew-tss-02) + - Add runtime cpu feature detection for x86/x86-64 + - Add code for general runtime self testing for hashes, MACs, and ciphers + - Optimize XTEA; twice as fast as before on Core2 and Opteron + - Convert CTR_BE and OFB from filters to stream ciphers + - New parsing code for SCAN algorithm names + - Enable SSE2 optimizations under Visual C++ + - Remove all use of C++ exception specifications + - Add support for GNU/Hurd and Clang/LLVM + +* 1.9.0, 2009-09-09 + - Add support for parallel invocation of block ciphers where possible + - Add SSE2 implementation of Serpent + - Add Rivest's package transform (an all or nothing transform) + - Minor speedups to the Turing key schedule + - Fix processing multiple messages in XTS mode + - Add --no-autoload option to configure.py, for minimized builds + - The previously used configure.pl script is no longer supported + * 1.8.8, 2009-11-03 - Alter Skein-512 to match the tweaked 1.2 specification - Fix use of inline asm for access to x86 bswap function diff --git a/doc/python.tex b/doc/python.tex new file mode 100644 index 000000000..afdd66b6a --- /dev/null +++ b/doc/python.tex @@ -0,0 +1,68 @@ +\documentclass{article} + +\setlength{\textwidth}{6.5in} % 1 inch side margins +\setlength{\textheight}{9in} % ~1 inch top and bottom margins + +\setlength{\headheight}{0in} +\setlength{\topmargin}{0in} +\setlength{\headsep}{0in} + +\setlength{\oddsidemargin}{0in} +\setlength{\evensidemargin}{0in} + +\title{\textbf{Botan Python Interface Documentation}} +\author{Jack Lloyd \\ + \texttt{[email protected]}} +\date{2009/10/10} + +\newcommand{\filename}[1]{\texttt{#1}} +\newcommand{\manpage}[2]{\texttt{#1}(#2)} + +\newcommand{\macro}[1]{\texttt{#1}} + +\newcommand{\function}[1]{\textbf{#1}} +\newcommand{\type}[1]{\texttt{#1}} +\renewcommand{\arg}[1]{\textsl{#1}} +\newcommand{\variable}[1]{\textsl{#1}} + +\begin{document} + +\maketitle + +\tableofcontents + +\parskip=5pt +\pagebreak + +\section{Ciphers} + +Botan's Python interface provides a generic interface to any cipher +supported by the library. The class \type{botan.Cipher} takes three +arguments, all strings: first, the name of the algorith, second the +direction (which can be either ``encrypt'' or ``decrypt''), and +lastly, the key to use. For instance + +\begin{verbatim} + encryptor = botan.Cipher("AES-128/EAX", "encrypt", key) +\end{verbatim} + +creates an object that will encrypt and authenticate messages using +the EAX mode of operation using the AES cipher. To use this object, +call the \function{cipher} function with two arguments - the input +to encrypt, and the IV to use: + +\begin{verbatim} + ciphertext = encryptor.cipher(input, salt) +\end{verbatim} + + +\subsection{Cryptobox} + + +\subsection{RNGs} + +\section{RSA} + + + +\end{document} diff --git a/doc/python/cipher.py b/doc/python/cipher.py new file mode 100755 index 000000000..1be2759ae --- /dev/null +++ b/doc/python/cipher.py @@ -0,0 +1,44 @@ +#!/usr/bin/python + +import botan +import sys + +def encrypt(input, passphrase): + rng = botan.RandomNumberGenerator() + + # Use as both EAX IV and PBKDF2 salt + salt = rng.gen_random(10) + + iterations = 10000 + output_size = 16 + + key = botan.pbkdf2(passphrase, salt, iterations, output_size, "SHA-1") + + encryptor = botan.Cipher("AES-128/EAX", "encrypt", key) + + ciphertext = encryptor.cipher(input, salt) + return (ciphertext, salt) + +def decrypt(input, salt, passphrase): + iterations = 10000 + output_size = 16 + + key = botan.pbkdf2(passphrase, salt, iterations, output_size, "SHA-1") + + decryptor = botan.Cipher("AES-128/EAX", "decrypt", key) + + return decryptor.cipher(input, salt) + +def main(args = None): + if args is None: + args = sys.argv + + passphrase = args[1] + input = ''.join(open(args[2]).readlines()) + + (ciphertext, salt) = encrypt(input, passphrase) + + print decrypt(ciphertext, salt, passphrase) + +if __name__ == '__main__': + sys.exit(main()) diff --git a/doc/python/cryptobox.py b/doc/python/cryptobox.py new file mode 100755 index 000000000..1968b40e1 --- /dev/null +++ b/doc/python/cryptobox.py @@ -0,0 +1,34 @@ +#!/usr/bin/python + +import sys +import botan + +def main(args = None): + if args is None: + args = sys.argv + + if len(args) != 3: + raise Exception("Bad usage") + + password = args[1] + input = ''.join(open(args[2]).readlines()) + + rng = botan.RandomNumberGenerator() + + ciphertext = botan.cryptobox_encrypt(input, password, rng) + + print ciphertext + + plaintext = '' + + try: + plaintext = botan.cryptobox_decrypt(ciphertext, password + 'FAIL') + except Exception, e: + print "Oops -- ", e + + plaintext = botan.cryptobox_decrypt(ciphertext, password) + + print plaintext + +if __name__ == '__main__': + sys.exit(main()) diff --git a/wrappers/boost-python/nisttest.py b/doc/python/nisttest.py index 3ea8fda0f..3ea8fda0f 100755 --- a/wrappers/boost-python/nisttest.py +++ b/doc/python/nisttest.py diff --git a/wrappers/boost-python/results.txt b/doc/python/results.txt index 7a3824001..7a3824001 100644 --- a/wrappers/boost-python/results.txt +++ b/doc/python/results.txt diff --git a/wrappers/boost-python/rng_test.py b/doc/python/rng_test.py index 06c79b84e..06c79b84e 100755 --- a/wrappers/boost-python/rng_test.py +++ b/doc/python/rng_test.py diff --git a/doc/python/rsa.py b/doc/python/rsa.py new file mode 100755 index 000000000..15ffcffa3 --- /dev/null +++ b/doc/python/rsa.py @@ -0,0 +1,31 @@ +#!/usr/bin/python + +import botan + +rng = botan.RandomNumberGenerator() + +rsa_priv = botan.RSA_PrivateKey(768, rng) + +print rsa_priv.to_string() +print int(rsa_priv.get_N()) +print int(rsa_priv.get_E()) + + +rsa_pub = botan.RSA_PublicKey(rsa_priv) + +key = rng.gen_random(20) + +ciphertext = rsa_pub.encrypt(key, 'EME1(SHA-1)', rng) + +print ciphertext.encode('hex') + +plaintext = rsa_priv.decrypt(ciphertext, 'EME1(SHA-1)') + +print plaintext == key + + +signature = rsa_priv.sign(key, 'EMSA4(SHA-256)', rng) + +key = key.replace('a', 'b') + +print rsa_pub.verify(key, signature, 'EMSA4(SHA-256)') diff --git a/configure.pl b/doc/scripts/configure.pl index 1ce01e2b4..1ce01e2b4 100755 --- a/configure.pl +++ b/doc/scripts/configure.pl diff --git a/doc/scripts/dist.sh b/doc/scripts/dist.sh index 9629446cf..152b7e89b 100755 --- a/doc/scripts/dist.sh +++ b/doc/scripts/dist.sh @@ -3,10 +3,10 @@ # This is probably only useful if run on my machine, which is not # exactly ideal -SELECTOR=h:net.randombit.botan.1_8 +SELECTOR=h:net.randombit.botan KEY_ID=EFBADFBC MTN_DB=/storage/mtn/botan.mtn -WEB_DIR=~/projects/www +WEB_DIR=$HOME/projects/www/files/botan/v1.9/ DIST_DIR=~/Botan-dist # You shouldn't have to change anything after this @@ -26,7 +26,7 @@ rm -f .mtn-ignore # Build docs cd doc -for doc in api tutorial building +for doc in api tutorial building python do latex $doc.tex latex $doc.tex @@ -60,5 +60,5 @@ read -a PASSWORD -p "Enter PGP password (or ^C to skip signatures): " echo $PASSWORD | gpg --batch --armor -b --passphrase-fd 0 -u $KEY_ID Botan-$VERSION.tgz echo $PASSWORD | gpg --batch --armor -b --passphrase-fd 0 -u $KEY_ID Botan-$VERSION.tbz -mv Botan-$VERSION.tgz* $WEB_DIR/files/botan/v1.8 -mv Botan-$VERSION.tbz* $WEB_DIR/files/botan/v1.8 +mv Botan-$VERSION.tgz* $WEB_DIR +mv Botan-$VERSION.tbz* $WEB_DIR diff --git a/readme.txt b/readme.txt index 965de00cf..a192a1e1e 100644 --- a/readme.txt +++ b/readme.txt @@ -1,4 +1,4 @@ -Botan 1.8.8 2009-11-03 +Botan 1.9.2, 2009-11-03 Botan is a C++ class library for performing a wide variety of cryptographic operations. diff --git a/src/algo_factory/algo_cache.h b/src/algo_factory/algo_cache.h index 17ea9964a..08b25cd47 100644 --- a/src/algo_factory/algo_cache.h +++ b/src/algo_factory/algo_cache.h @@ -1,5 +1,8 @@ -/** +/* * An algorithm cache (used by Algorithm_Factory) +* (C) 2008-2009 Jack Lloyd +* +* Distributed under the terms of the Botan license */ #ifndef BOTAN_ALGORITHM_CACHE_TEMPLATE_H__ diff --git a/src/algo_factory/algo_factory.cpp b/src/algo_factory/algo_factory.cpp index 269c58c3b..22915d97c 100644 --- a/src/algo_factory/algo_factory.cpp +++ b/src/algo_factory/algo_factory.cpp @@ -1,6 +1,6 @@ /* -Algorithm Factory -(C) 2008 Jack Lloyd +* Algorithm Factory +* (C) 2008 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -62,6 +62,10 @@ const T* factory_prototype(const std::string& algo_spec, return cache_hit; SCAN_Name scan_name(algo_spec); + + if(scan_name.cipher_mode() != "") + return 0; + for(u32bit i = 0; i != engines.size(); ++i) { if(provider == "" || engines[i]->provider_name() == provider) diff --git a/src/algo_factory/info.txt b/src/algo_factory/info.txt index dfc42230a..4b25c7fc5 100644 --- a/src/algo_factory/info.txt +++ b/src/algo_factory/info.txt @@ -1,5 +1,3 @@ -realname "Algorithm Factory" - load_on auto define ALGORITHM_FACTORY diff --git a/src/algo_factory/prov_weight.cpp b/src/algo_factory/prov_weight.cpp index a55a8b1e6..d7e84a323 100644 --- a/src/algo_factory/prov_weight.cpp +++ b/src/algo_factory/prov_weight.cpp @@ -22,7 +22,7 @@ u32bit static_provider_weight(const std::string& prov_name) if(prov_name == "core") return 5; if(prov_name == "ia32") return 6; if(prov_name == "amd64") return 7; - if(prov_name == "sse2") return 8; + if(prov_name == "simd") return 8; if(prov_name == "openssl") return 2; if(prov_name == "gmp") return 1; diff --git a/src/alloc/alloc_mmap/info.txt b/src/alloc/alloc_mmap/info.txt index 65d9b2977..e6bded3fb 100644 --- a/src/alloc/alloc_mmap/info.txt +++ b/src/alloc/alloc_mmap/info.txt @@ -1,5 +1,3 @@ -realname "Disk Based Allocation System" - define ALLOC_MMAP modset unix diff --git a/src/alloc/info.txt b/src/alloc/info.txt index fa50aa09f..99dbe3a4d 100644 --- a/src/alloc/info.txt +++ b/src/alloc/info.txt @@ -1,5 +1,3 @@ -realname "Allocator" - load_on auto <add> diff --git a/src/alloc/mem_pool/info.txt b/src/alloc/mem_pool/info.txt index 0a762ccc4..73a548292 100644 --- a/src/alloc/mem_pool/info.txt +++ b/src/alloc/mem_pool/info.txt @@ -1,5 +1,3 @@ -realname "Memory Pool Allocator" - load_on auto <add> diff --git a/src/alloc/mem_pool/mem_pool.cpp b/src/alloc/mem_pool/mem_pool.cpp index 38e0c3285..e30a7b98a 100644 --- a/src/alloc/mem_pool/mem_pool.cpp +++ b/src/alloc/mem_pool/mem_pool.cpp @@ -8,7 +8,7 @@ */ #include <botan/mem_pool.h> -#include <botan/util.h> +#include <botan/rounding.h> #include <botan/mem_ops.h> #include <algorithm> #include <exception> @@ -42,7 +42,7 @@ Pooling_Allocator::Memory_Block::Memory_Block(void* buf) * See if ptr is contained by this block */ bool Pooling_Allocator::Memory_Block::contains(void* ptr, - u32bit length) const throw() + u32bit length) const { return ((buffer <= ptr) && (buffer_end >= static_cast<byte*>(ptr) + length * BLOCK_SIZE)); @@ -51,7 +51,7 @@ bool Pooling_Allocator::Memory_Block::contains(void* ptr, /* * Allocate some memory, if possible */ -byte* Pooling_Allocator::Memory_Block::alloc(u32bit n) throw() +byte* Pooling_Allocator::Memory_Block::alloc(u32bit n) { if(n == 0 || n > BITMAP_SIZE) return 0; @@ -91,7 +91,7 @@ byte* Pooling_Allocator::Memory_Block::alloc(u32bit n) throw() /* * Mark this memory as free, if we own it */ -void Pooling_Allocator::Memory_Block::free(void* ptr, u32bit blocks) throw() +void Pooling_Allocator::Memory_Block::free(void* ptr, u32bit blocks) { clear_mem(static_cast<byte*>(ptr), blocks * BLOCK_SIZE); diff --git a/src/alloc/mem_pool/mem_pool.h b/src/alloc/mem_pool/mem_pool.h index a57800972..51571405e 100644 --- a/src/alloc/mem_pool/mem_pool.h +++ b/src/alloc/mem_pool/mem_pool.h @@ -44,9 +44,9 @@ class BOTAN_DLL Pooling_Allocator : public Allocator static u32bit bitmap_size() { return BITMAP_SIZE; } static u32bit block_size() { return BLOCK_SIZE; } - bool contains(void*, u32bit) const throw(); - byte* alloc(u32bit) throw(); - void free(void*, u32bit) throw(); + bool contains(void*, u32bit) const; + byte* alloc(u32bit); + void free(void*, u32bit); bool operator<(const Memory_Block& other) const { diff --git a/src/alloc/system_alloc/defalloc.cpp b/src/alloc/system_alloc/defalloc.cpp index 8791c74e4..b1b338d71 100644 --- a/src/alloc/system_alloc/defalloc.cpp +++ b/src/alloc/system_alloc/defalloc.cpp @@ -7,7 +7,7 @@ #include <botan/defalloc.h> #include <botan/libstate.h> -#include <botan/util.h> +#include <botan/mlock.h> #include <cstdlib> #include <cstring> diff --git a/src/alloc/system_alloc/info.txt b/src/alloc/system_alloc/info.txt index 5fade38cf..8b9a2f067 100644 --- a/src/alloc/system_alloc/info.txt +++ b/src/alloc/system_alloc/info.txt @@ -1,5 +1,3 @@ -realname "Default (Malloc) Allocators" - load_on auto <add> diff --git a/src/aont/info.txt b/src/aont/info.txt new file mode 100644 index 000000000..533b70eb5 --- /dev/null +++ b/src/aont/info.txt @@ -0,0 +1,15 @@ +define PACKAGE_TRANSFORM + +load_on auto + +<add> +package.cpp +package.h +</add> + +<requires> +block +ctr +rng +filters +</requires> diff --git a/src/aont/package.cpp b/src/aont/package.cpp new file mode 100644 index 000000000..37bad46c8 --- /dev/null +++ b/src/aont/package.cpp @@ -0,0 +1,120 @@ +/* +* Rivest's Package Tranform +* +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/package.h> +#include <botan/filters.h> +#include <botan/ctr.h> +#include <botan/loadstor.h> +#include <botan/xor_buf.h> + +namespace Botan { + +namespace AllOrNothingTransform { + +void package(RandomNumberGenerator& rng, + BlockCipher* cipher, + const byte input[], u32bit input_len, + byte output[]) + { + if(!cipher->valid_keylength(cipher->BLOCK_SIZE)) + throw Invalid_Argument("AONT::package: Invalid cipher"); + + // The all-zero string which is used both as the CTR IV and as K0 + const std::string all_zeros(cipher->BLOCK_SIZE*2, '0'); + + SymmetricKey package_key(rng, cipher->BLOCK_SIZE); + + Pipe pipe(new StreamCipher_Filter(new CTR_BE(cipher), package_key)); + + pipe.process_msg(input, input_len); + pipe.read(output, pipe.remaining()); + + // Set K0 (the all zero key) + cipher->set_key(SymmetricKey(all_zeros)); + + SecureVector<byte> buf(cipher->BLOCK_SIZE); + + const u32bit blocks = + (input_len + cipher->BLOCK_SIZE - 1) / cipher->BLOCK_SIZE; + + byte* final_block = output + input_len; + clear_mem(final_block, cipher->BLOCK_SIZE); + + // XOR the hash blocks into the final block + for(u32bit i = 0; i != blocks; ++i) + { + u32bit left = std::min<u32bit>(cipher->BLOCK_SIZE, + input_len - cipher->BLOCK_SIZE * i); + + buf.clear(); + copy_mem(&buf[0], output + cipher->BLOCK_SIZE * i, left); + + for(u32bit j = 0; j != 4; ++j) + buf[cipher->BLOCK_SIZE - 1 - j] ^= get_byte(3-j, i); + + cipher->encrypt(buf); + + xor_buf(final_block, buf, cipher->BLOCK_SIZE); + } + + // XOR the random package key into the final block + xor_buf(final_block, package_key.begin(), cipher->BLOCK_SIZE); + } + +void unpackage(BlockCipher* cipher, + const byte input[], u32bit input_len, + byte output[]) + { + if(!cipher->valid_keylength(cipher->BLOCK_SIZE)) + throw Invalid_Argument("AONT::unpackage: Invalid cipher"); + + if(input_len < cipher->BLOCK_SIZE) + throw Invalid_Argument("AONT::unpackage: Input too short"); + + // The all-zero string which is used both as the CTR IV and as K0 + const std::string all_zeros(cipher->BLOCK_SIZE*2, '0'); + + cipher->set_key(SymmetricKey(all_zeros)); + + SecureVector<byte> package_key(cipher->BLOCK_SIZE); + SecureVector<byte> buf(cipher->BLOCK_SIZE); + + // Copy the package key (masked with the block hashes) + copy_mem(&package_key[0], + input + (input_len - cipher->BLOCK_SIZE), + cipher->BLOCK_SIZE); + + const u32bit blocks = ((input_len - 1) / cipher->BLOCK_SIZE); + + // XOR the blocks into the package key bits + for(u32bit i = 0; i != blocks; ++i) + { + u32bit left = std::min<u32bit>(cipher->BLOCK_SIZE, + input_len - cipher->BLOCK_SIZE * (i+1)); + + buf.clear(); + copy_mem(&buf[0], input + cipher->BLOCK_SIZE * i, left); + + for(u32bit j = 0; j != 4; ++j) + buf[cipher->BLOCK_SIZE - 1 - j] ^= get_byte(3-j, i); + + cipher->encrypt(buf); + + xor_buf(&package_key[0], buf, cipher->BLOCK_SIZE); + } + + Pipe pipe(new StreamCipher_Filter(new CTR_BE(cipher), package_key)); + + pipe.process_msg(input, input_len - cipher->BLOCK_SIZE); + + pipe.read(output, pipe.remaining()); + } + +} + +} diff --git a/src/aont/package.h b/src/aont/package.h new file mode 100644 index 000000000..35d2a23fc --- /dev/null +++ b/src/aont/package.h @@ -0,0 +1,45 @@ +/* +* Rivest's Package Tranform +* +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/block_cipher.h> +#include <botan/rng.h> + +namespace Botan { + +namespace AllOrNothingTransform { + +/** +* Rivest's Package Tranform +* @arg rng the random number generator to use +* @arg cipher the block cipher to use +* @arg input the input data buffer +* @arg input_len the length of the input data in bytes +* @arg output the output data buffer (must be at least +* input_len + cipher->BLOCK_SIZE bytes long) +*/ +void package(RandomNumberGenerator& rng, + BlockCipher* cipher, + const byte input[], u32bit input_len, + byte output[]); + +/** +* Rivest's Package Tranform (Inversion) +* @arg rng the random number generator to use +* @arg cipher the block cipher to use +* @arg input the input data buffer +* @arg input_len the length of the input data in bytes +* @arg output the output data buffer (must be at least +* input_len - cipher->BLOCK_SIZE bytes long) +*/ +void unpackage(BlockCipher* cipher, + const byte input[], u32bit input_len, + byte output[]); + +} + +} diff --git a/src/asn1/asn1_tm.cpp b/src/asn1/asn1_tm.cpp index f85ea128b..09bc4d347 100644 --- a/src/asn1/asn1_tm.cpp +++ b/src/asn1/asn1_tm.cpp @@ -10,28 +10,10 @@ #include <botan/ber_dec.h> #include <botan/charset.h> #include <botan/parsing.h> -#include <ctime> +#include <botan/timer.h> namespace Botan { -namespace { - -/* -* Convert a time_t to a struct tm -*/ -std::tm get_tm(u64bit timer) - { - std::time_t time_val = static_cast<std::time_t>(timer); - - std::tm* tm_p = std::gmtime(&time_val); - if(tm_p == 0) - throw Encoding_Error("X509_Time: gmtime could not encode " + - to_string(timer)); - return (*tm_p); - } - -} - /* * Create an X509_Time */ @@ -45,7 +27,7 @@ X509_Time::X509_Time(const std::string& time_str) */ X509_Time::X509_Time(u64bit timer) { - std::tm time_info = get_tm(timer); + std::tm time_info = time_t_to_tm(timer); year = time_info.tm_year + 1900; month = time_info.tm_mon + 1; diff --git a/src/asn1/info.txt b/src/asn1/info.txt index 7b8110c10..d836b4c0b 100644 --- a/src/asn1/info.txt +++ b/src/asn1/info.txt @@ -1,5 +1,3 @@ -realname "ASN.1/BER/DER module" - define ASN1 load_on auto diff --git a/src/benchmark/benchmark.cpp b/src/benchmark/benchmark.cpp index 01e3b94f3..41c9cd10c 100644 --- a/src/benchmark/benchmark.cpp +++ b/src/benchmark/benchmark.cpp @@ -11,7 +11,6 @@ #include <botan/stream_cipher.h> #include <botan/hash.h> #include <botan/mac.h> -#include <botan/util.h> #include <memory> namespace Botan { @@ -55,10 +54,11 @@ bench_block_cipher(BlockCipher* block_cipher, const u32bit in_blocks = buf_len / block_cipher->BLOCK_SIZE; + block_cipher->set_key(buf, block_cipher->MAXIMUM_KEYLENGTH); + while(nanoseconds_used < nanoseconds_max) { - for(u32bit i = 0; i != in_blocks; ++i) - block_cipher->encrypt(buf + block_cipher->BLOCK_SIZE * i); + block_cipher->encrypt_n(buf, buf, in_blocks); ++reps; nanoseconds_used = timer.clock() - start; @@ -81,9 +81,11 @@ bench_stream_cipher(StreamCipher* stream_cipher, u64bit nanoseconds_used = 0; u64bit reps = 0; + stream_cipher->set_key(buf, stream_cipher->MAXIMUM_KEYLENGTH); + while(nanoseconds_used < nanoseconds_max) { - stream_cipher->encrypt(buf, buf_len); + stream_cipher->cipher1(buf, buf_len); ++reps; nanoseconds_used = timer.clock() - start; } diff --git a/src/benchmark/info.txt b/src/benchmark/info.txt index 0fbcdb2de..f148ae5ce 100644 --- a/src/benchmark/info.txt +++ b/src/benchmark/info.txt @@ -1,5 +1,3 @@ -realname "Benchmarking" - define RUNTIME_BENCHMARKING load_on auto diff --git a/src/block/aes/aes.cpp b/src/block/aes/aes.cpp index 9072b507b..7ba8136ec 100644 --- a/src/block/aes/aes.cpp +++ b/src/block/aes/aes.cpp @@ -1,6 +1,6 @@ /** * AES -* (C) 1999-2007 Jack Lloyd +* (C) 1999-2009 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -13,163 +13,175 @@ namespace Botan { /** * AES Encryption */ -void AES::enc(const byte in[], byte out[]) const +void AES::encrypt_n(const byte in[], byte out[], u32bit blocks) const { const u32bit* TE0 = TE; const u32bit* TE1 = TE + 256; const u32bit* TE2 = TE + 512; const u32bit* TE3 = TE + 768; - u32bit T0 = load_be<u32bit>(in, 0) ^ EK[0]; - u32bit T1 = load_be<u32bit>(in, 1) ^ EK[1]; - u32bit T2 = load_be<u32bit>(in, 2) ^ EK[2]; - u32bit T3 = load_be<u32bit>(in, 3) ^ EK[3]; - - u32bit B0, B1, B2, B3; - B0 = TE0[get_byte(0, T0)] ^ TE1[get_byte(1, T1)] ^ - TE2[get_byte(2, T2)] ^ TE3[get_byte(3, T3)] ^ EK[4]; - B1 = TE0[get_byte(0, T1)] ^ TE1[get_byte(1, T2)] ^ - TE2[get_byte(2, T3)] ^ TE3[get_byte(3, T0)] ^ EK[5]; - B2 = TE0[get_byte(0, T2)] ^ TE1[get_byte(1, T3)] ^ - TE2[get_byte(2, T0)] ^ TE3[get_byte(3, T1)] ^ EK[6]; - B3 = TE0[get_byte(0, T3)] ^ TE1[get_byte(1, T0)] ^ - TE2[get_byte(2, T1)] ^ TE3[get_byte(3, T2)] ^ EK[7]; - - for(u32bit j = 2; j != ROUNDS; j += 2) + for(u32bit i = 0; i != blocks; ++i) { - const u32bit K0 = EK[4*j]; - const u32bit K1 = EK[4*j+1]; - const u32bit K2 = EK[4*j+2]; - const u32bit K3 = EK[4*j+3]; - - T0 = TE0[get_byte(0, B0)] ^ TE1[get_byte(1, B1)] ^ - TE2[get_byte(2, B2)] ^ TE3[get_byte(3, B3)] ^ K0; - T1 = TE0[get_byte(0, B1)] ^ TE1[get_byte(1, B2)] ^ - TE2[get_byte(2, B3)] ^ TE3[get_byte(3, B0)] ^ K1; - T2 = TE0[get_byte(0, B2)] ^ TE1[get_byte(1, B3)] ^ - TE2[get_byte(2, B0)] ^ TE3[get_byte(3, B1)] ^ K2; - T3 = TE0[get_byte(0, B3)] ^ TE1[get_byte(1, B0)] ^ - TE2[get_byte(2, B1)] ^ TE3[get_byte(3, B2)] ^ K3; - - const u32bit K4 = EK[4*(j+1)+0]; - const u32bit K5 = EK[4*(j+1)+1]; - const u32bit K6 = EK[4*(j+1)+2]; - const u32bit K7 = EK[4*(j+1)+3]; + u32bit T0 = load_be<u32bit>(in, 0) ^ EK[0]; + u32bit T1 = load_be<u32bit>(in, 1) ^ EK[1]; + u32bit T2 = load_be<u32bit>(in, 2) ^ EK[2]; + u32bit T3 = load_be<u32bit>(in, 3) ^ EK[3]; + u32bit B0, B1, B2, B3; B0 = TE0[get_byte(0, T0)] ^ TE1[get_byte(1, T1)] ^ - TE2[get_byte(2, T2)] ^ TE3[get_byte(3, T3)] ^ K4; + TE2[get_byte(2, T2)] ^ TE3[get_byte(3, T3)] ^ EK[4]; B1 = TE0[get_byte(0, T1)] ^ TE1[get_byte(1, T2)] ^ - TE2[get_byte(2, T3)] ^ TE3[get_byte(3, T0)] ^ K5; + TE2[get_byte(2, T3)] ^ TE3[get_byte(3, T0)] ^ EK[5]; B2 = TE0[get_byte(0, T2)] ^ TE1[get_byte(1, T3)] ^ - TE2[get_byte(2, T0)] ^ TE3[get_byte(3, T1)] ^ K6; + TE2[get_byte(2, T0)] ^ TE3[get_byte(3, T1)] ^ EK[6]; B3 = TE0[get_byte(0, T3)] ^ TE1[get_byte(1, T0)] ^ - TE2[get_byte(2, T1)] ^ TE3[get_byte(3, T2)] ^ K7; - } + TE2[get_byte(2, T1)] ^ TE3[get_byte(3, T2)] ^ EK[7]; + + for(u32bit j = 2; j != ROUNDS; j += 2) + { + const u32bit K0 = EK[4*j]; + const u32bit K1 = EK[4*j+1]; + const u32bit K2 = EK[4*j+2]; + const u32bit K3 = EK[4*j+3]; + + T0 = TE0[get_byte(0, B0)] ^ TE1[get_byte(1, B1)] ^ + TE2[get_byte(2, B2)] ^ TE3[get_byte(3, B3)] ^ K0; + T1 = TE0[get_byte(0, B1)] ^ TE1[get_byte(1, B2)] ^ + TE2[get_byte(2, B3)] ^ TE3[get_byte(3, B0)] ^ K1; + T2 = TE0[get_byte(0, B2)] ^ TE1[get_byte(1, B3)] ^ + TE2[get_byte(2, B0)] ^ TE3[get_byte(3, B1)] ^ K2; + T3 = TE0[get_byte(0, B3)] ^ TE1[get_byte(1, B0)] ^ + TE2[get_byte(2, B1)] ^ TE3[get_byte(3, B2)] ^ K3; + + const u32bit K4 = EK[4*(j+1)+0]; + const u32bit K5 = EK[4*(j+1)+1]; + const u32bit K6 = EK[4*(j+1)+2]; + const u32bit K7 = EK[4*(j+1)+3]; - /* - Joseph Bonneau and Ilya Mironov's paper - <a href = "http://icme2007.org/users/mironov/papers/aes-timing.pdf"> - Cache-Collision Timing Attacks Against AES</a> describes an attack - that can recover AES keys with as few as 2<sup>13</sup> samples. - - """In addition to OpenSSL v. 0.9.8.(a), which was used in our - experiments, the AES implementations of Crypto++ 5.2.1 and - LibTomCrypt 1.09 use the original Rijndael C implementation with - very few changes and are highly vulnerable. The AES implementations - in libgcrypt v. 1.2.2 and Botan v. 1.4.2 are also vulnerable, but - use a smaller byte-wide final table which lessens the effectiveness - of the attacks.""" - */ - out[ 0] = SE[get_byte(0, B0)] ^ ME[0]; - out[ 1] = SE[get_byte(1, B1)] ^ ME[1]; - out[ 2] = SE[get_byte(2, B2)] ^ ME[2]; - out[ 3] = SE[get_byte(3, B3)] ^ ME[3]; - out[ 4] = SE[get_byte(0, B1)] ^ ME[4]; - out[ 5] = SE[get_byte(1, B2)] ^ ME[5]; - out[ 6] = SE[get_byte(2, B3)] ^ ME[6]; - out[ 7] = SE[get_byte(3, B0)] ^ ME[7]; - out[ 8] = SE[get_byte(0, B2)] ^ ME[8]; - out[ 9] = SE[get_byte(1, B3)] ^ ME[9]; - out[10] = SE[get_byte(2, B0)] ^ ME[10]; - out[11] = SE[get_byte(3, B1)] ^ ME[11]; - out[12] = SE[get_byte(0, B3)] ^ ME[12]; - out[13] = SE[get_byte(1, B0)] ^ ME[13]; - out[14] = SE[get_byte(2, B1)] ^ ME[14]; - out[15] = SE[get_byte(3, B2)] ^ ME[15]; + B0 = TE0[get_byte(0, T0)] ^ TE1[get_byte(1, T1)] ^ + TE2[get_byte(2, T2)] ^ TE3[get_byte(3, T3)] ^ K4; + B1 = TE0[get_byte(0, T1)] ^ TE1[get_byte(1, T2)] ^ + TE2[get_byte(2, T3)] ^ TE3[get_byte(3, T0)] ^ K5; + B2 = TE0[get_byte(0, T2)] ^ TE1[get_byte(1, T3)] ^ + TE2[get_byte(2, T0)] ^ TE3[get_byte(3, T1)] ^ K6; + B3 = TE0[get_byte(0, T3)] ^ TE1[get_byte(1, T0)] ^ + TE2[get_byte(2, T1)] ^ TE3[get_byte(3, T2)] ^ K7; + } + + /* + Joseph Bonneau and Ilya Mironov's paper + <a href = "http://icme2007.org/users/mironov/papers/aes-timing.pdf"> + Cache-Collision Timing Attacks Against AES</a> describes an attack + that can recover AES keys with as few as 2<sup>13</sup> samples. + + """In addition to OpenSSL v. 0.9.8.(a), which was used in our + experiments, the AES implementations of Crypto++ 5.2.1 and + LibTomCrypt 1.09 use the original Rijndael C implementation with + very few changes and are highly vulnerable. The AES implementations + in libgcrypt v. 1.2.2 and Botan v. 1.4.2 are also vulnerable, but + use a smaller byte-wide final table which lessens the effectiveness + of the attacks.""" + */ + out[ 0] = SE[get_byte(0, B0)] ^ ME[0]; + out[ 1] = SE[get_byte(1, B1)] ^ ME[1]; + out[ 2] = SE[get_byte(2, B2)] ^ ME[2]; + out[ 3] = SE[get_byte(3, B3)] ^ ME[3]; + out[ 4] = SE[get_byte(0, B1)] ^ ME[4]; + out[ 5] = SE[get_byte(1, B2)] ^ ME[5]; + out[ 6] = SE[get_byte(2, B3)] ^ ME[6]; + out[ 7] = SE[get_byte(3, B0)] ^ ME[7]; + out[ 8] = SE[get_byte(0, B2)] ^ ME[8]; + out[ 9] = SE[get_byte(1, B3)] ^ ME[9]; + out[10] = SE[get_byte(2, B0)] ^ ME[10]; + out[11] = SE[get_byte(3, B1)] ^ ME[11]; + out[12] = SE[get_byte(0, B3)] ^ ME[12]; + out[13] = SE[get_byte(1, B0)] ^ ME[13]; + out[14] = SE[get_byte(2, B1)] ^ ME[14]; + out[15] = SE[get_byte(3, B2)] ^ ME[15]; + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /** * AES Decryption */ -void AES::dec(const byte in[], byte out[]) const +void AES::decrypt_n(const byte in[], byte out[], u32bit blocks) const { const u32bit* TD0 = TD; const u32bit* TD1 = TD + 256; const u32bit* TD2 = TD + 512; const u32bit* TD3 = TD + 768; - u32bit T0 = load_be<u32bit>(in, 0) ^ DK[0]; - u32bit T1 = load_be<u32bit>(in, 1) ^ DK[1]; - u32bit T2 = load_be<u32bit>(in, 2) ^ DK[2]; - u32bit T3 = load_be<u32bit>(in, 3) ^ DK[3]; - - u32bit B0, B1, B2, B3; - B0 = TD0[get_byte(0, T0)] ^ TD1[get_byte(1, T3)] ^ - TD2[get_byte(2, T2)] ^ TD3[get_byte(3, T1)] ^ DK[4]; - B1 = TD0[get_byte(0, T1)] ^ TD1[get_byte(1, T0)] ^ - TD2[get_byte(2, T3)] ^ TD3[get_byte(3, T2)] ^ DK[5]; - B2 = TD0[get_byte(0, T2)] ^ TD1[get_byte(1, T1)] ^ - TD2[get_byte(2, T0)] ^ TD3[get_byte(3, T3)] ^ DK[6]; - B3 = TD0[get_byte(0, T3)] ^ TD1[get_byte(1, T2)] ^ - TD2[get_byte(2, T1)] ^ TD3[get_byte(3, T0)] ^ DK[7]; - - for(u32bit j = 2; j != ROUNDS; j += 2) + for(u32bit i = 0; i != blocks; ++i) { - const u32bit K0 = DK[4*j+0]; - const u32bit K1 = DK[4*j+1]; - const u32bit K2 = DK[4*j+2]; - const u32bit K3 = DK[4*j+3]; - - T0 = TD0[get_byte(0, B0)] ^ TD1[get_byte(1, B3)] ^ - TD2[get_byte(2, B2)] ^ TD3[get_byte(3, B1)] ^ K0; - T1 = TD0[get_byte(0, B1)] ^ TD1[get_byte(1, B0)] ^ - TD2[get_byte(2, B3)] ^ TD3[get_byte(3, B2)] ^ K1; - T2 = TD0[get_byte(0, B2)] ^ TD1[get_byte(1, B1)] ^ - TD2[get_byte(2, B0)] ^ TD3[get_byte(3, B3)] ^ K2; - T3 = TD0[get_byte(0, B3)] ^ TD1[get_byte(1, B2)] ^ - TD2[get_byte(2, B1)] ^ TD3[get_byte(3, B0)] ^ K3; - - const u32bit K4 = DK[4*(j+1)+0]; - const u32bit K5 = DK[4*(j+1)+1]; - const u32bit K6 = DK[4*(j+1)+2]; - const u32bit K7 = DK[4*(j+1)+3]; + u32bit T0 = load_be<u32bit>(in, 0) ^ DK[0]; + u32bit T1 = load_be<u32bit>(in, 1) ^ DK[1]; + u32bit T2 = load_be<u32bit>(in, 2) ^ DK[2]; + u32bit T3 = load_be<u32bit>(in, 3) ^ DK[3]; + u32bit B0, B1, B2, B3; B0 = TD0[get_byte(0, T0)] ^ TD1[get_byte(1, T3)] ^ - TD2[get_byte(2, T2)] ^ TD3[get_byte(3, T1)] ^ K4; + TD2[get_byte(2, T2)] ^ TD3[get_byte(3, T1)] ^ DK[4]; B1 = TD0[get_byte(0, T1)] ^ TD1[get_byte(1, T0)] ^ - TD2[get_byte(2, T3)] ^ TD3[get_byte(3, T2)] ^ K5; + TD2[get_byte(2, T3)] ^ TD3[get_byte(3, T2)] ^ DK[5]; B2 = TD0[get_byte(0, T2)] ^ TD1[get_byte(1, T1)] ^ - TD2[get_byte(2, T0)] ^ TD3[get_byte(3, T3)] ^ K6; + TD2[get_byte(2, T0)] ^ TD3[get_byte(3, T3)] ^ DK[6]; B3 = TD0[get_byte(0, T3)] ^ TD1[get_byte(1, T2)] ^ - TD2[get_byte(2, T1)] ^ TD3[get_byte(3, T0)] ^ K7; - } + TD2[get_byte(2, T1)] ^ TD3[get_byte(3, T0)] ^ DK[7]; + + for(u32bit j = 2; j != ROUNDS; j += 2) + { + const u32bit K0 = DK[4*j+0]; + const u32bit K1 = DK[4*j+1]; + const u32bit K2 = DK[4*j+2]; + const u32bit K3 = DK[4*j+3]; + + T0 = TD0[get_byte(0, B0)] ^ TD1[get_byte(1, B3)] ^ + TD2[get_byte(2, B2)] ^ TD3[get_byte(3, B1)] ^ K0; + T1 = TD0[get_byte(0, B1)] ^ TD1[get_byte(1, B0)] ^ + TD2[get_byte(2, B3)] ^ TD3[get_byte(3, B2)] ^ K1; + T2 = TD0[get_byte(0, B2)] ^ TD1[get_byte(1, B1)] ^ + TD2[get_byte(2, B0)] ^ TD3[get_byte(3, B3)] ^ K2; + T3 = TD0[get_byte(0, B3)] ^ TD1[get_byte(1, B2)] ^ + TD2[get_byte(2, B1)] ^ TD3[get_byte(3, B0)] ^ K3; + + const u32bit K4 = DK[4*(j+1)+0]; + const u32bit K5 = DK[4*(j+1)+1]; + const u32bit K6 = DK[4*(j+1)+2]; + const u32bit K7 = DK[4*(j+1)+3]; - out[ 0] = SD[get_byte(0, B0)] ^ MD[0]; - out[ 1] = SD[get_byte(1, B3)] ^ MD[1]; - out[ 2] = SD[get_byte(2, B2)] ^ MD[2]; - out[ 3] = SD[get_byte(3, B1)] ^ MD[3]; - out[ 4] = SD[get_byte(0, B1)] ^ MD[4]; - out[ 5] = SD[get_byte(1, B0)] ^ MD[5]; - out[ 6] = SD[get_byte(2, B3)] ^ MD[6]; - out[ 7] = SD[get_byte(3, B2)] ^ MD[7]; - out[ 8] = SD[get_byte(0, B2)] ^ MD[8]; - out[ 9] = SD[get_byte(1, B1)] ^ MD[9]; - out[10] = SD[get_byte(2, B0)] ^ MD[10]; - out[11] = SD[get_byte(3, B3)] ^ MD[11]; - out[12] = SD[get_byte(0, B3)] ^ MD[12]; - out[13] = SD[get_byte(1, B2)] ^ MD[13]; - out[14] = SD[get_byte(2, B1)] ^ MD[14]; - out[15] = SD[get_byte(3, B0)] ^ MD[15]; + B0 = TD0[get_byte(0, T0)] ^ TD1[get_byte(1, T3)] ^ + TD2[get_byte(2, T2)] ^ TD3[get_byte(3, T1)] ^ K4; + B1 = TD0[get_byte(0, T1)] ^ TD1[get_byte(1, T0)] ^ + TD2[get_byte(2, T3)] ^ TD3[get_byte(3, T2)] ^ K5; + B2 = TD0[get_byte(0, T2)] ^ TD1[get_byte(1, T1)] ^ + TD2[get_byte(2, T0)] ^ TD3[get_byte(3, T3)] ^ K6; + B3 = TD0[get_byte(0, T3)] ^ TD1[get_byte(1, T2)] ^ + TD2[get_byte(2, T1)] ^ TD3[get_byte(3, T0)] ^ K7; + } + + out[ 0] = SD[get_byte(0, B0)] ^ MD[0]; + out[ 1] = SD[get_byte(1, B3)] ^ MD[1]; + out[ 2] = SD[get_byte(2, B2)] ^ MD[2]; + out[ 3] = SD[get_byte(3, B1)] ^ MD[3]; + out[ 4] = SD[get_byte(0, B1)] ^ MD[4]; + out[ 5] = SD[get_byte(1, B0)] ^ MD[5]; + out[ 6] = SD[get_byte(2, B3)] ^ MD[6]; + out[ 7] = SD[get_byte(3, B2)] ^ MD[7]; + out[ 8] = SD[get_byte(0, B2)] ^ MD[8]; + out[ 9] = SD[get_byte(1, B1)] ^ MD[9]; + out[10] = SD[get_byte(2, B0)] ^ MD[10]; + out[11] = SD[get_byte(3, B3)] ^ MD[11]; + out[12] = SD[get_byte(0, B3)] ^ MD[12]; + out[13] = SD[get_byte(1, B2)] ^ MD[13]; + out[14] = SD[get_byte(2, B1)] ^ MD[14]; + out[15] = SD[get_byte(3, B0)] ^ MD[15]; + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /** @@ -246,7 +258,7 @@ AES::AES(u32bit key_size) : BlockCipher(16, key_size) /** * Clear memory of sensitive data */ -void AES::clear() throw() +void AES::clear() { EK.clear(); DK.clear(); diff --git a/src/block/aes/aes.h b/src/block/aes/aes.h index 05e2e3123..229ce307c 100644 --- a/src/block/aes/aes.h +++ b/src/block/aes/aes.h @@ -1,6 +1,6 @@ /** * AES -* (C) 1999-2007 Jack Lloyd +* (C) 1999-2009 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -18,14 +18,16 @@ namespace Botan { class BOTAN_DLL AES : public BlockCipher { public: - void clear() throw(); + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + + void clear(); std::string name() const { return "AES"; } BlockCipher* clone() const { return new AES; } + AES() : BlockCipher(16, 16, 32, 8) { ROUNDS = 14; } AES(u32bit); private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; void key_schedule(const byte[], u32bit); static u32bit S(u32bit); diff --git a/src/block/aes/info.txt b/src/block/aes/info.txt index 2803ccc4e..480973100 100644 --- a/src/block/aes/info.txt +++ b/src/block/aes/info.txt @@ -1,11 +1 @@ -realname "AES" - define AES - -load_on auto - -<add> -aes.cpp -aes.h -aes_tab.cpp -</add> diff --git a/src/block/block_cipher.h b/src/block/block_cipher.h index 01c45af04..1dcdde7c7 100644 --- a/src/block/block_cipher.h +++ b/src/block/block_cipher.h @@ -1,6 +1,6 @@ /** * Block Cipher Base Class -* (C) 1999-2007 Jack Lloyd +* (C) 1999-2009 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -45,7 +45,8 @@ class BOTAN_DLL BlockCipher : public SymmetricAlgorithm * @param out The byte array designated to hold the encrypted block. * Must be of length BLOCK_SIZE. */ - void encrypt(const byte in[], byte out[]) const { enc(in, out); } + void encrypt(const byte in[], byte out[]) const + { encrypt_n(in, out, 1); } /** * Decrypt a block. @@ -54,7 +55,8 @@ class BOTAN_DLL BlockCipher : public SymmetricAlgorithm * @param out The byte array designated to hold the decrypted block. * Must be of length BLOCK_SIZE. */ - void decrypt(const byte in[], byte out[]) const { dec(in, out); } + void decrypt(const byte in[], byte out[]) const + { decrypt_n(in, out, 1); } /** * Encrypt a block. @@ -62,7 +64,7 @@ class BOTAN_DLL BlockCipher : public SymmetricAlgorithm * Must be of length BLOCK_SIZE. Will hold the result when the function * has finished. */ - void encrypt(byte block[]) const { enc(block, block); } + void encrypt(byte block[]) const { encrypt_n(block, block, 1); } /** * Decrypt a block. @@ -70,7 +72,12 @@ class BOTAN_DLL BlockCipher : public SymmetricAlgorithm * Must be of length BLOCK_SIZE. Will hold the result when the function * has finished. */ - void decrypt(byte block[]) const { dec(block, block); } + void decrypt(byte block[]) const { decrypt_n(block, block, 1); } + + virtual void encrypt_n(const byte in[], byte out[], + u32bit blocks) const = 0; + virtual void decrypt_n(const byte in[], byte out[], + u32bit blocks) const = 0; /** * Get a new object representing the same algorithm as *this @@ -80,7 +87,7 @@ class BOTAN_DLL BlockCipher : public SymmetricAlgorithm /** * Zeroize internal state */ - virtual void clear() throw() = 0; + virtual void clear() = 0; BlockCipher(u32bit block_size, u32bit key_min, @@ -90,9 +97,6 @@ class BOTAN_DLL BlockCipher : public SymmetricAlgorithm BLOCK_SIZE(block_size) {} virtual ~BlockCipher() {} - private: - virtual void enc(const byte[], byte[]) const = 0; - virtual void dec(const byte[], byte[]) const = 0; }; } diff --git a/src/block/blowfish/blowfish.cpp b/src/block/blowfish/blowfish.cpp index b0599d6c5..d0b182a84 100644 --- a/src/block/blowfish/blowfish.cpp +++ b/src/block/blowfish/blowfish.cpp @@ -1,6 +1,6 @@ /* * Blowfish -* (C) 1999-2007 Jack Lloyd +* (C) 1999-2009 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -13,59 +13,71 @@ namespace Botan { /* * Blowfish Encryption */ -void Blowfish::enc(const byte in[], byte out[]) const +void Blowfish::encrypt_n(const byte in[], byte out[], u32bit blocks) const { const u32bit* S1 = S + 0; const u32bit* S2 = S + 256; const u32bit* S3 = S + 512; const u32bit* S4 = S + 768; - u32bit L = load_be<u32bit>(in, 0); - u32bit R = load_be<u32bit>(in, 1); - - for(u32bit j = 0; j != 16; j += 2) + for(u32bit i = 0; i != blocks; ++i) { - L ^= P[j]; - R ^= ((S1[get_byte(0, L)] + S2[get_byte(1, L)]) ^ - S3[get_byte(2, L)]) + S4[get_byte(3, L)]; + u32bit L = load_be<u32bit>(in, 0); + u32bit R = load_be<u32bit>(in, 1); - R ^= P[j+1]; - L ^= ((S1[get_byte(0, R)] + S2[get_byte(1, R)]) ^ - S3[get_byte(2, R)]) + S4[get_byte(3, R)]; - } + for(u32bit j = 0; j != 16; j += 2) + { + L ^= P[j]; + R ^= ((S1[get_byte(0, L)] + S2[get_byte(1, L)]) ^ + S3[get_byte(2, L)]) + S4[get_byte(3, L)]; - L ^= P[16]; R ^= P[17]; + R ^= P[j+1]; + L ^= ((S1[get_byte(0, R)] + S2[get_byte(1, R)]) ^ + S3[get_byte(2, R)]) + S4[get_byte(3, R)]; + } + + L ^= P[16]; R ^= P[17]; - store_be(out, R, L); + store_be(out, R, L); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* * Blowfish Decryption */ -void Blowfish::dec(const byte in[], byte out[]) const +void Blowfish::decrypt_n(const byte in[], byte out[], u32bit blocks) const { const u32bit* S1 = S + 0; const u32bit* S2 = S + 256; const u32bit* S3 = S + 512; const u32bit* S4 = S + 768; - u32bit L = load_be<u32bit>(in, 0); - u32bit R = load_be<u32bit>(in, 1); - - for(u32bit j = 17; j != 1; j -= 2) + for(u32bit i = 0; i != blocks; ++i) { - L ^= P[j]; - R ^= ((S1[get_byte(0, L)] + S2[get_byte(1, L)]) ^ - S3[get_byte(2, L)]) + S4[get_byte(3, L)]; + u32bit L = load_be<u32bit>(in, 0); + u32bit R = load_be<u32bit>(in, 1); - R ^= P[j-1]; - L ^= ((S1[get_byte(0, R)] + S2[get_byte(1, R)]) ^ - S3[get_byte(2, R)]) + S4[get_byte(3, R)]; - } + for(u32bit j = 17; j != 1; j -= 2) + { + L ^= P[j]; + R ^= ((S1[get_byte(0, L)] + S2[get_byte(1, L)]) ^ + S3[get_byte(2, L)]) + S4[get_byte(3, L)]; - L ^= P[1]; R ^= P[0]; + R ^= P[j-1]; + L ^= ((S1[get_byte(0, R)] + S2[get_byte(1, R)]) ^ + S3[get_byte(2, R)]) + S4[get_byte(3, R)]; + } + + L ^= P[1]; R ^= P[0]; - store_be(out, R, L); + store_be(out, R, L); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* @@ -116,7 +128,7 @@ void Blowfish::generate_sbox(u32bit Box[], u32bit size, /* * Clear memory of sensitive data */ -void Blowfish::clear() throw() +void Blowfish::clear() { P.copy(P_INIT, 18); S.copy(S_INIT, 1024); diff --git a/src/block/blowfish/blowfish.h b/src/block/blowfish/blowfish.h index f0f26418d..5419308ca 100644 --- a/src/block/blowfish/blowfish.h +++ b/src/block/blowfish/blowfish.h @@ -1,6 +1,6 @@ /* * Blowfish -* (C) 1999-2008 Jack Lloyd +* (C) 1999-2009 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -18,13 +18,15 @@ namespace Botan { class BOTAN_DLL Blowfish : public BlockCipher { public: - void clear() throw(); + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + + void clear(); std::string name() const { return "Blowfish"; } BlockCipher* clone() const { return new Blowfish; } + Blowfish() : BlockCipher(8, 1, 56) {} private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; void key_schedule(const byte[], u32bit); void generate_sbox(u32bit[], u32bit, u32bit&, u32bit&) const; diff --git a/src/block/blowfish/info.txt b/src/block/blowfish/info.txt index 0a9d2adc2..c935fb3ab 100644 --- a/src/block/blowfish/info.txt +++ b/src/block/blowfish/info.txt @@ -1,11 +1 @@ -realname "Blowfish" - define BLOWFISH - -load_on auto - -<add> -blfs_tab.cpp -blowfish.cpp -blowfish.h -</add> diff --git a/src/block/cast/cast128.cpp b/src/block/cast/cast128.cpp index 046638ab9..887dcf994 100644 --- a/src/block/cast/cast128.cpp +++ b/src/block/cast/cast128.cpp @@ -48,57 +48,69 @@ inline void R3(u32bit& L, u32bit R, u32bit MK, u32bit RK) /* * CAST-128 Encryption */ -void CAST_128::enc(const byte in[], byte out[]) const +void CAST_128::encrypt_n(const byte in[], byte out[], u32bit blocks) const { - u32bit L = load_be<u32bit>(in, 0); - u32bit R = load_be<u32bit>(in, 1); - - R1(L, R, MK[ 0], RK[ 0]); - R2(R, L, MK[ 1], RK[ 1]); - R3(L, R, MK[ 2], RK[ 2]); - R1(R, L, MK[ 3], RK[ 3]); - R2(L, R, MK[ 4], RK[ 4]); - R3(R, L, MK[ 5], RK[ 5]); - R1(L, R, MK[ 6], RK[ 6]); - R2(R, L, MK[ 7], RK[ 7]); - R3(L, R, MK[ 8], RK[ 8]); - R1(R, L, MK[ 9], RK[ 9]); - R2(L, R, MK[10], RK[10]); - R3(R, L, MK[11], RK[11]); - R1(L, R, MK[12], RK[12]); - R2(R, L, MK[13], RK[13]); - R3(L, R, MK[14], RK[14]); - R1(R, L, MK[15], RK[15]); - - store_be(out, R, L); + for(u32bit i = 0; i != blocks; ++i) + { + u32bit L = load_be<u32bit>(in, 0); + u32bit R = load_be<u32bit>(in, 1); + + R1(L, R, MK[ 0], RK[ 0]); + R2(R, L, MK[ 1], RK[ 1]); + R3(L, R, MK[ 2], RK[ 2]); + R1(R, L, MK[ 3], RK[ 3]); + R2(L, R, MK[ 4], RK[ 4]); + R3(R, L, MK[ 5], RK[ 5]); + R1(L, R, MK[ 6], RK[ 6]); + R2(R, L, MK[ 7], RK[ 7]); + R3(L, R, MK[ 8], RK[ 8]); + R1(R, L, MK[ 9], RK[ 9]); + R2(L, R, MK[10], RK[10]); + R3(R, L, MK[11], RK[11]); + R1(L, R, MK[12], RK[12]); + R2(R, L, MK[13], RK[13]); + R3(L, R, MK[14], RK[14]); + R1(R, L, MK[15], RK[15]); + + store_be(out, R, L); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* * CAST-128 Decryption */ -void CAST_128::dec(const byte in[], byte out[]) const +void CAST_128::decrypt_n(const byte in[], byte out[], u32bit blocks) const { - u32bit L = load_be<u32bit>(in, 0); - u32bit R = load_be<u32bit>(in, 1); - - R1(L, R, MK[15], RK[15]); - R3(R, L, MK[14], RK[14]); - R2(L, R, MK[13], RK[13]); - R1(R, L, MK[12], RK[12]); - R3(L, R, MK[11], RK[11]); - R2(R, L, MK[10], RK[10]); - R1(L, R, MK[ 9], RK[ 9]); - R3(R, L, MK[ 8], RK[ 8]); - R2(L, R, MK[ 7], RK[ 7]); - R1(R, L, MK[ 6], RK[ 6]); - R3(L, R, MK[ 5], RK[ 5]); - R2(R, L, MK[ 4], RK[ 4]); - R1(L, R, MK[ 3], RK[ 3]); - R3(R, L, MK[ 2], RK[ 2]); - R2(L, R, MK[ 1], RK[ 1]); - R1(R, L, MK[ 0], RK[ 0]); - - store_be(out, R, L); + for(u32bit i = 0; i != blocks; ++i) + { + u32bit L = load_be<u32bit>(in, 0); + u32bit R = load_be<u32bit>(in, 1); + + R1(L, R, MK[15], RK[15]); + R3(R, L, MK[14], RK[14]); + R2(L, R, MK[13], RK[13]); + R1(R, L, MK[12], RK[12]); + R3(L, R, MK[11], RK[11]); + R2(R, L, MK[10], RK[10]); + R1(L, R, MK[ 9], RK[ 9]); + R3(R, L, MK[ 8], RK[ 8]); + R2(L, R, MK[ 7], RK[ 7]); + R1(R, L, MK[ 6], RK[ 6]); + R3(L, R, MK[ 5], RK[ 5]); + R2(R, L, MK[ 4], RK[ 4]); + R1(L, R, MK[ 3], RK[ 3]); + R3(R, L, MK[ 2], RK[ 2]); + R2(L, R, MK[ 1], RK[ 1]); + R1(R, L, MK[ 0], RK[ 0]); + + store_be(out, R, L); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* diff --git a/src/block/cast/cast128.h b/src/block/cast/cast128.h index 680481482..caffb97ea 100644 --- a/src/block/cast/cast128.h +++ b/src/block/cast/cast128.h @@ -18,13 +18,15 @@ namespace Botan { class BOTAN_DLL CAST_128 : public BlockCipher { public: - void clear() throw() { MK.clear(); RK.clear(); } + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + + void clear() { MK.clear(); RK.clear(); } std::string name() const { return "CAST-128"; } BlockCipher* clone() const { return new CAST_128; } + CAST_128() : BlockCipher(8, 11, 16) {} private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; void key_schedule(const byte[], u32bit); static void key_schedule(u32bit[16], u32bit[4]); diff --git a/src/block/cast/cast256.cpp b/src/block/cast/cast256.cpp index 22ff876fa..7a4a4e805 100644 --- a/src/block/cast/cast256.cpp +++ b/src/block/cast/cast256.cpp @@ -48,77 +48,89 @@ void round3(u32bit& out, u32bit in, u32bit mask, u32bit rot) /* * CAST-256 Encryption */ -void CAST_256::enc(const byte in[], byte out[]) const +void CAST_256::encrypt_n(const byte in[], byte out[], u32bit blocks) const { - u32bit A = load_be<u32bit>(in, 0); - u32bit B = load_be<u32bit>(in, 1); - u32bit C = load_be<u32bit>(in, 2); - u32bit D = load_be<u32bit>(in, 3); - - round1(C, D, MK[ 0], RK[ 0]); round2(B, C, MK[ 1], RK[ 1]); - round3(A, B, MK[ 2], RK[ 2]); round1(D, A, MK[ 3], RK[ 3]); - round1(C, D, MK[ 4], RK[ 4]); round2(B, C, MK[ 5], RK[ 5]); - round3(A, B, MK[ 6], RK[ 6]); round1(D, A, MK[ 7], RK[ 7]); - round1(C, D, MK[ 8], RK[ 8]); round2(B, C, MK[ 9], RK[ 9]); - round3(A, B, MK[10], RK[10]); round1(D, A, MK[11], RK[11]); - round1(C, D, MK[12], RK[12]); round2(B, C, MK[13], RK[13]); - round3(A, B, MK[14], RK[14]); round1(D, A, MK[15], RK[15]); - round1(C, D, MK[16], RK[16]); round2(B, C, MK[17], RK[17]); - round3(A, B, MK[18], RK[18]); round1(D, A, MK[19], RK[19]); - round1(C, D, MK[20], RK[20]); round2(B, C, MK[21], RK[21]); - round3(A, B, MK[22], RK[22]); round1(D, A, MK[23], RK[23]); - round1(D, A, MK[27], RK[27]); round3(A, B, MK[26], RK[26]); - round2(B, C, MK[25], RK[25]); round1(C, D, MK[24], RK[24]); - round1(D, A, MK[31], RK[31]); round3(A, B, MK[30], RK[30]); - round2(B, C, MK[29], RK[29]); round1(C, D, MK[28], RK[28]); - round1(D, A, MK[35], RK[35]); round3(A, B, MK[34], RK[34]); - round2(B, C, MK[33], RK[33]); round1(C, D, MK[32], RK[32]); - round1(D, A, MK[39], RK[39]); round3(A, B, MK[38], RK[38]); - round2(B, C, MK[37], RK[37]); round1(C, D, MK[36], RK[36]); - round1(D, A, MK[43], RK[43]); round3(A, B, MK[42], RK[42]); - round2(B, C, MK[41], RK[41]); round1(C, D, MK[40], RK[40]); - round1(D, A, MK[47], RK[47]); round3(A, B, MK[46], RK[46]); - round2(B, C, MK[45], RK[45]); round1(C, D, MK[44], RK[44]); - - store_be(out, A, B, C, D); + for(u32bit i = 0; i != blocks; ++i) + { + u32bit A = load_be<u32bit>(in, 0); + u32bit B = load_be<u32bit>(in, 1); + u32bit C = load_be<u32bit>(in, 2); + u32bit D = load_be<u32bit>(in, 3); + + round1(C, D, MK[ 0], RK[ 0]); round2(B, C, MK[ 1], RK[ 1]); + round3(A, B, MK[ 2], RK[ 2]); round1(D, A, MK[ 3], RK[ 3]); + round1(C, D, MK[ 4], RK[ 4]); round2(B, C, MK[ 5], RK[ 5]); + round3(A, B, MK[ 6], RK[ 6]); round1(D, A, MK[ 7], RK[ 7]); + round1(C, D, MK[ 8], RK[ 8]); round2(B, C, MK[ 9], RK[ 9]); + round3(A, B, MK[10], RK[10]); round1(D, A, MK[11], RK[11]); + round1(C, D, MK[12], RK[12]); round2(B, C, MK[13], RK[13]); + round3(A, B, MK[14], RK[14]); round1(D, A, MK[15], RK[15]); + round1(C, D, MK[16], RK[16]); round2(B, C, MK[17], RK[17]); + round3(A, B, MK[18], RK[18]); round1(D, A, MK[19], RK[19]); + round1(C, D, MK[20], RK[20]); round2(B, C, MK[21], RK[21]); + round3(A, B, MK[22], RK[22]); round1(D, A, MK[23], RK[23]); + round1(D, A, MK[27], RK[27]); round3(A, B, MK[26], RK[26]); + round2(B, C, MK[25], RK[25]); round1(C, D, MK[24], RK[24]); + round1(D, A, MK[31], RK[31]); round3(A, B, MK[30], RK[30]); + round2(B, C, MK[29], RK[29]); round1(C, D, MK[28], RK[28]); + round1(D, A, MK[35], RK[35]); round3(A, B, MK[34], RK[34]); + round2(B, C, MK[33], RK[33]); round1(C, D, MK[32], RK[32]); + round1(D, A, MK[39], RK[39]); round3(A, B, MK[38], RK[38]); + round2(B, C, MK[37], RK[37]); round1(C, D, MK[36], RK[36]); + round1(D, A, MK[43], RK[43]); round3(A, B, MK[42], RK[42]); + round2(B, C, MK[41], RK[41]); round1(C, D, MK[40], RK[40]); + round1(D, A, MK[47], RK[47]); round3(A, B, MK[46], RK[46]); + round2(B, C, MK[45], RK[45]); round1(C, D, MK[44], RK[44]); + + store_be(out, A, B, C, D); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* * CAST-256 Decryption */ -void CAST_256::dec(const byte in[], byte out[]) const +void CAST_256::decrypt_n(const byte in[], byte out[], u32bit blocks) const { - u32bit A = load_be<u32bit>(in, 0); - u32bit B = load_be<u32bit>(in, 1); - u32bit C = load_be<u32bit>(in, 2); - u32bit D = load_be<u32bit>(in, 3); - - round1(C, D, MK[44], RK[44]); round2(B, C, MK[45], RK[45]); - round3(A, B, MK[46], RK[46]); round1(D, A, MK[47], RK[47]); - round1(C, D, MK[40], RK[40]); round2(B, C, MK[41], RK[41]); - round3(A, B, MK[42], RK[42]); round1(D, A, MK[43], RK[43]); - round1(C, D, MK[36], RK[36]); round2(B, C, MK[37], RK[37]); - round3(A, B, MK[38], RK[38]); round1(D, A, MK[39], RK[39]); - round1(C, D, MK[32], RK[32]); round2(B, C, MK[33], RK[33]); - round3(A, B, MK[34], RK[34]); round1(D, A, MK[35], RK[35]); - round1(C, D, MK[28], RK[28]); round2(B, C, MK[29], RK[29]); - round3(A, B, MK[30], RK[30]); round1(D, A, MK[31], RK[31]); - round1(C, D, MK[24], RK[24]); round2(B, C, MK[25], RK[25]); - round3(A, B, MK[26], RK[26]); round1(D, A, MK[27], RK[27]); - round1(D, A, MK[23], RK[23]); round3(A, B, MK[22], RK[22]); - round2(B, C, MK[21], RK[21]); round1(C, D, MK[20], RK[20]); - round1(D, A, MK[19], RK[19]); round3(A, B, MK[18], RK[18]); - round2(B, C, MK[17], RK[17]); round1(C, D, MK[16], RK[16]); - round1(D, A, MK[15], RK[15]); round3(A, B, MK[14], RK[14]); - round2(B, C, MK[13], RK[13]); round1(C, D, MK[12], RK[12]); - round1(D, A, MK[11], RK[11]); round3(A, B, MK[10], RK[10]); - round2(B, C, MK[ 9], RK[ 9]); round1(C, D, MK[ 8], RK[ 8]); - round1(D, A, MK[ 7], RK[ 7]); round3(A, B, MK[ 6], RK[ 6]); - round2(B, C, MK[ 5], RK[ 5]); round1(C, D, MK[ 4], RK[ 4]); - round1(D, A, MK[ 3], RK[ 3]); round3(A, B, MK[ 2], RK[ 2]); - round2(B, C, MK[ 1], RK[ 1]); round1(C, D, MK[ 0], RK[ 0]); - - store_be(out, A, B, C, D); + for(u32bit i = 0; i != blocks; ++i) + { + u32bit A = load_be<u32bit>(in, 0); + u32bit B = load_be<u32bit>(in, 1); + u32bit C = load_be<u32bit>(in, 2); + u32bit D = load_be<u32bit>(in, 3); + + round1(C, D, MK[44], RK[44]); round2(B, C, MK[45], RK[45]); + round3(A, B, MK[46], RK[46]); round1(D, A, MK[47], RK[47]); + round1(C, D, MK[40], RK[40]); round2(B, C, MK[41], RK[41]); + round3(A, B, MK[42], RK[42]); round1(D, A, MK[43], RK[43]); + round1(C, D, MK[36], RK[36]); round2(B, C, MK[37], RK[37]); + round3(A, B, MK[38], RK[38]); round1(D, A, MK[39], RK[39]); + round1(C, D, MK[32], RK[32]); round2(B, C, MK[33], RK[33]); + round3(A, B, MK[34], RK[34]); round1(D, A, MK[35], RK[35]); + round1(C, D, MK[28], RK[28]); round2(B, C, MK[29], RK[29]); + round3(A, B, MK[30], RK[30]); round1(D, A, MK[31], RK[31]); + round1(C, D, MK[24], RK[24]); round2(B, C, MK[25], RK[25]); + round3(A, B, MK[26], RK[26]); round1(D, A, MK[27], RK[27]); + round1(D, A, MK[23], RK[23]); round3(A, B, MK[22], RK[22]); + round2(B, C, MK[21], RK[21]); round1(C, D, MK[20], RK[20]); + round1(D, A, MK[19], RK[19]); round3(A, B, MK[18], RK[18]); + round2(B, C, MK[17], RK[17]); round1(C, D, MK[16], RK[16]); + round1(D, A, MK[15], RK[15]); round3(A, B, MK[14], RK[14]); + round2(B, C, MK[13], RK[13]); round1(C, D, MK[12], RK[12]); + round1(D, A, MK[11], RK[11]); round3(A, B, MK[10], RK[10]); + round2(B, C, MK[ 9], RK[ 9]); round1(C, D, MK[ 8], RK[ 8]); + round1(D, A, MK[ 7], RK[ 7]); round3(A, B, MK[ 6], RK[ 6]); + round2(B, C, MK[ 5], RK[ 5]); round1(C, D, MK[ 4], RK[ 4]); + round1(D, A, MK[ 3], RK[ 3]); round3(A, B, MK[ 2], RK[ 2]); + round2(B, C, MK[ 1], RK[ 1]); round1(C, D, MK[ 0], RK[ 0]); + + store_be(out, A, B, C, D); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* diff --git a/src/block/cast/cast256.h b/src/block/cast/cast256.h index cd48edd5e..0db3682ba 100644 --- a/src/block/cast/cast256.h +++ b/src/block/cast/cast256.h @@ -18,13 +18,15 @@ namespace Botan { class BOTAN_DLL CAST_256 : public BlockCipher { public: - void clear() throw() { MK.clear(); RK.clear(); } + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + + void clear() { MK.clear(); RK.clear(); } std::string name() const { return "CAST-256"; } BlockCipher* clone() const { return new CAST_256; } + CAST_256() : BlockCipher(16, 4, 32, 4) {} private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; void key_schedule(const byte[], u32bit); static const u32bit KEY_MASK[192]; diff --git a/src/block/cast/info.txt b/src/block/cast/info.txt index 73d3f900f..faba491c2 100644 --- a/src/block/cast/info.txt +++ b/src/block/cast/info.txt @@ -1,13 +1 @@ -realname "CAST" - define CAST - -load_on auto - -<add> -cast128.cpp -cast128.h -cast256.cpp -cast256.h -cast_tab.cpp -</add> diff --git a/src/block/des/des.cpp b/src/block/des/des.cpp index 37520e0fc..05287304f 100644 --- a/src/block/des/des.cpp +++ b/src/block/des/des.cpp @@ -139,51 +139,62 @@ void des_decrypt(u32bit& L, u32bit& R, /* * DES Encryption */ -void DES::enc(const byte in[], byte out[]) const +void DES::encrypt_n(const byte in[], byte out[], u32bit blocks) const { - u64bit T = (DES_IPTAB1[in[0]] ) | (DES_IPTAB1[in[1]] << 1) | - (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) | - (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) | - (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]] ); + for(u32bit i = 0; i != blocks; ++i) + { + u64bit T = (DES_IPTAB1[in[0]] ) | (DES_IPTAB1[in[1]] << 1) | + (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) | + (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) | + (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]] ); - u32bit L = static_cast<u32bit>(T >> 32); - u32bit R = static_cast<u32bit>(T); + u32bit L = static_cast<u32bit>(T >> 32); + u32bit R = static_cast<u32bit>(T); - des_encrypt(L, R, round_key); + des_encrypt(L, R, round_key); - T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) | - (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) | - (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) | - (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] ); + T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) | + (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) | + (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) | + (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] ); + T = rotate_left(T, 32); - T = rotate_left(T, 32); + store_be(T, out); - store_be(T, out); + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* * DES Decryption */ -void DES::dec(const byte in[], byte out[]) const +void DES::decrypt_n(const byte in[], byte out[], u32bit blocks) const { - u64bit T = (DES_IPTAB1[in[0]] ) | (DES_IPTAB1[in[1]] << 1) | - (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) | - (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) | - (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]] ); + for(u32bit i = 0; i != blocks; ++i) + { + u64bit T = (DES_IPTAB1[in[0]] ) | (DES_IPTAB1[in[1]] << 1) | + (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) | + (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) | + (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]] ); - u32bit L = static_cast<u32bit>(T >> 32); - u32bit R = static_cast<u32bit>(T); + u32bit L = static_cast<u32bit>(T >> 32); + u32bit R = static_cast<u32bit>(T); - des_decrypt(L, R, round_key); + des_decrypt(L, R, round_key); - T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) | - (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) | - (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) | - (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] ); + T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) | + (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) | + (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) | + (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] ); - T = rotate_left(T, 32); + T = rotate_left(T, 32); - store_be(T, out); + store_be(T, out); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* @@ -197,55 +208,67 @@ void DES::key_schedule(const byte key[], u32bit) /* * TripleDES Encryption */ -void TripleDES::enc(const byte in[], byte out[]) const +void TripleDES::encrypt_n(const byte in[], byte out[], u32bit blocks) const { - u64bit T = (DES_IPTAB1[in[0]] ) | (DES_IPTAB1[in[1]] << 1) | - (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) | - (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) | - (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]] ); + for(u32bit i = 0; i != blocks; ++i) + { + u64bit T = (DES_IPTAB1[in[0]] ) | (DES_IPTAB1[in[1]] << 1) | + (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) | + (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) | + (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]] ); - u32bit L = static_cast<u32bit>(T >> 32); - u32bit R = static_cast<u32bit>(T); + u32bit L = static_cast<u32bit>(T >> 32); + u32bit R = static_cast<u32bit>(T); - des_encrypt(L, R, round_key); - des_decrypt(R, L, round_key + 32); - des_encrypt(L, R, round_key + 64); + des_encrypt(L, R, round_key); + des_decrypt(R, L, round_key + 32); + des_encrypt(L, R, round_key + 64); - T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) | - (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) | - (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) | - (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] ); + T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) | + (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) | + (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) | + (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] ); - T = rotate_left(T, 32); + T = rotate_left(T, 32); - store_be(T, out); + store_be(T, out); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* * TripleDES Decryption */ -void TripleDES::dec(const byte in[], byte out[]) const +void TripleDES::decrypt_n(const byte in[], byte out[], u32bit blocks) const { - u64bit T = (DES_IPTAB1[in[0]] ) | (DES_IPTAB1[in[1]] << 1) | - (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) | - (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) | - (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]] ); + for(u32bit i = 0; i != blocks; ++i) + { + u64bit T = (DES_IPTAB1[in[0]] ) | (DES_IPTAB1[in[1]] << 1) | + (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) | + (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) | + (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]] ); - u32bit L = static_cast<u32bit>(T >> 32); - u32bit R = static_cast<u32bit>(T); + u32bit L = static_cast<u32bit>(T >> 32); + u32bit R = static_cast<u32bit>(T); - des_decrypt(L, R, round_key + 64); - des_encrypt(R, L, round_key + 32); - des_decrypt(L, R, round_key); + des_decrypt(L, R, round_key + 64); + des_encrypt(R, L, round_key + 32); + des_decrypt(L, R, round_key); - T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) | - (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) | - (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) | - (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] ); + T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) | + (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) | + (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) | + (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] ); - T = rotate_left(T, 32); + T = rotate_left(T, 32); - store_be(T, out); + store_be(T, out); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* diff --git a/src/block/des/des.h b/src/block/des/des.h index 6fa59de5e..b28990178 100644 --- a/src/block/des/des.h +++ b/src/block/des/des.h @@ -18,13 +18,15 @@ namespace Botan { class BOTAN_DLL DES : public BlockCipher { public: - void clear() throw() { round_key.clear(); } + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + + void clear() { round_key.clear(); } std::string name() const { return "DES"; } BlockCipher* clone() const { return new DES; } + DES() : BlockCipher(8, 8) {} private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; void key_schedule(const byte[], u32bit); SecureBuffer<u32bit, 32> round_key; @@ -36,13 +38,15 @@ class BOTAN_DLL DES : public BlockCipher class BOTAN_DLL TripleDES : public BlockCipher { public: - void clear() throw() { round_key.clear(); } + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + + void clear() { round_key.clear(); } std::string name() const { return "TripleDES"; } BlockCipher* clone() const { return new TripleDES; } + TripleDES() : BlockCipher(8, 16, 24, 8) {} private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; void key_schedule(const byte[], u32bit); SecureBuffer<u32bit, 96> round_key; diff --git a/src/block/des/desx.cpp b/src/block/des/desx.cpp index e557901d3..1fc1c47f2 100644 --- a/src/block/des/desx.cpp +++ b/src/block/des/desx.cpp @@ -13,21 +13,33 @@ namespace Botan { /* * DESX Encryption */ -void DESX::enc(const byte in[], byte out[]) const +void DESX::encrypt_n(const byte in[], byte out[], u32bit blocks) const { - xor_buf(out, in, K1.begin(), BLOCK_SIZE); - des.encrypt(out); - xor_buf(out, K2.begin(), BLOCK_SIZE); + for(u32bit i = 0; i != blocks; ++i) + { + xor_buf(out, in, K1.begin(), BLOCK_SIZE); + des.encrypt(out); + xor_buf(out, K2.begin(), BLOCK_SIZE); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* * DESX Decryption */ -void DESX::dec(const byte in[], byte out[]) const +void DESX::decrypt_n(const byte in[], byte out[], u32bit blocks) const { - xor_buf(out, in, K2.begin(), BLOCK_SIZE); - des.decrypt(out); - xor_buf(out, K1.begin(), BLOCK_SIZE); + for(u32bit i = 0; i != blocks; ++i) + { + xor_buf(out, in, K2.begin(), BLOCK_SIZE); + des.decrypt(out); + xor_buf(out, K1.begin(), BLOCK_SIZE); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* diff --git a/src/block/des/desx.h b/src/block/des/desx.h index 49ecc2421..89664d064 100644 --- a/src/block/des/desx.h +++ b/src/block/des/desx.h @@ -18,13 +18,15 @@ namespace Botan { class BOTAN_DLL DESX : public BlockCipher { public: - void clear() throw() { des.clear(); K1.clear(); K2.clear(); } + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + + void clear() { des.clear(); K1.clear(); K2.clear(); } std::string name() const { return "DESX"; } BlockCipher* clone() const { return new DESX; } + DESX() : BlockCipher(8, 24) {} private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; void key_schedule(const byte[], u32bit); SecureBuffer<byte, 8> K1, K2; DES des; diff --git a/src/block/des/info.txt b/src/block/des/info.txt index ed05979c9..8e4f4e82d 100644 --- a/src/block/des/info.txt +++ b/src/block/des/info.txt @@ -1,13 +1 @@ -realname "DES" - define DES - -load_on auto - -<add> -des.cpp -des.h -des_tab.cpp -desx.h -desx.cpp -</add> diff --git a/src/block/gost_28147/gost_28147.cpp b/src/block/gost_28147/gost_28147.cpp index bfd092c56..272f1bcab 100644 --- a/src/block/gost_28147/gost_28147.cpp +++ b/src/block/gost_28147/gost_28147.cpp @@ -84,47 +84,58 @@ GOST_28147_89::GOST_28147_89(const GOST_28147_89_Params& param) : /* * GOST Encryption */ -void GOST_28147_89::enc(const byte in[], byte out[]) const +void GOST_28147_89::encrypt_n(const byte in[], byte out[], u32bit blocks) const { - u32bit N1 = load_le<u32bit>(in, 0), N2 = load_le<u32bit>(in, 1); - - for(size_t i = 0; i != 3; ++i) + for(u32bit i = 0; i != blocks; ++i) { - GOST_2ROUND(N1, N2, 0, 1); - GOST_2ROUND(N1, N2, 2, 3); - GOST_2ROUND(N1, N2, 4, 5); - GOST_2ROUND(N1, N2, 6, 7); - } + u32bit N1 = load_le<u32bit>(in, 0), N2 = load_le<u32bit>(in, 1); - GOST_2ROUND(N1, N2, 7, 6); - GOST_2ROUND(N1, N2, 5, 4); - GOST_2ROUND(N1, N2, 3, 2); - GOST_2ROUND(N1, N2, 1, 0); + for(size_t j = 0; j != 3; ++j) + { + GOST_2ROUND(N1, N2, 0, 1); + GOST_2ROUND(N1, N2, 2, 3); + GOST_2ROUND(N1, N2, 4, 5); + GOST_2ROUND(N1, N2, 6, 7); + } - store_le(out, N2, N1); + GOST_2ROUND(N1, N2, 7, 6); + GOST_2ROUND(N1, N2, 5, 4); + GOST_2ROUND(N1, N2, 3, 2); + GOST_2ROUND(N1, N2, 1, 0); + + store_le(out, N2, N1); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* * GOST Decryption */ -void GOST_28147_89::dec(const byte in[], byte out[]) const +void GOST_28147_89::decrypt_n(const byte in[], byte out[], u32bit blocks) const { - u32bit N1 = load_le<u32bit>(in, 0), N2 = load_le<u32bit>(in, 1); + for(u32bit i = 0; i != blocks; ++i) + { + u32bit N1 = load_le<u32bit>(in, 0), N2 = load_le<u32bit>(in, 1); - GOST_2ROUND(N1, N2, 0, 1); - GOST_2ROUND(N1, N2, 2, 3); - GOST_2ROUND(N1, N2, 4, 5); - GOST_2ROUND(N1, N2, 6, 7); + GOST_2ROUND(N1, N2, 0, 1); + GOST_2ROUND(N1, N2, 2, 3); + GOST_2ROUND(N1, N2, 4, 5); + GOST_2ROUND(N1, N2, 6, 7); - for(size_t i = 0; i != 3; ++i) - { - GOST_2ROUND(N1, N2, 7, 6); - GOST_2ROUND(N1, N2, 5, 4); - GOST_2ROUND(N1, N2, 3, 2); - GOST_2ROUND(N1, N2, 1, 0); - } + for(size_t i = 0; i != 3; ++i) + { + GOST_2ROUND(N1, N2, 7, 6); + GOST_2ROUND(N1, N2, 5, 4); + GOST_2ROUND(N1, N2, 3, 2); + GOST_2ROUND(N1, N2, 1, 0); + } - store_le(out, N2, N1); + store_le(out, N2, N1); + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* diff --git a/src/block/gost_28147/gost_28147.h b/src/block/gost_28147/gost_28147.h index 96d24c669..bf6f8178b 100644 --- a/src/block/gost_28147/gost_28147.h +++ b/src/block/gost_28147/gost_28147.h @@ -44,7 +44,10 @@ class GOST_28147_89_Params class BOTAN_DLL GOST_28147_89 : public BlockCipher { public: - void clear() throw() { EK.clear(); } + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + + void clear() { EK.clear(); } std::string name() const { return "GOST-28147-89"; } BlockCipher* clone() const { return new GOST_28147_89(SBOX); } @@ -54,8 +57,6 @@ class BOTAN_DLL GOST_28147_89 : public BlockCipher GOST_28147_89(const SecureBuffer<u32bit, 1024>& other_SBOX) : BlockCipher(8, 32), SBOX(other_SBOX) {} - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; void key_schedule(const byte[], u32bit); SecureBuffer<u32bit, 1024> SBOX; diff --git a/src/block/gost_28147/info.txt b/src/block/gost_28147/info.txt index 6e187fd48..530f147e5 100644 --- a/src/block/gost_28147/info.txt +++ b/src/block/gost_28147/info.txt @@ -1,10 +1 @@ -realname "GOST 28147-89" - define GOST_28147_89 - -load_on auto - -<add> -gost_28147.cpp -gost_28147.h -</add> diff --git a/src/block/idea/idea.cpp b/src/block/idea/idea.cpp index 5bbe47087..fb5fe83f1 100644 --- a/src/block/idea/idea.cpp +++ b/src/block/idea/idea.cpp @@ -60,77 +60,89 @@ u16bit mul_inv(u16bit x) /* * IDEA Encryption */ -void IDEA::enc(const byte in[], byte out[]) const +void IDEA::encrypt_n(const byte in[], byte out[], u32bit blocks) const { - u16bit X1 = load_be<u16bit>(in, 0); - u16bit X2 = load_be<u16bit>(in, 1); - u16bit X3 = load_be<u16bit>(in, 2); - u16bit X4 = load_be<u16bit>(in, 3); - - for(u32bit j = 0; j != 8; ++j) + for(u32bit i = 0; i != blocks; ++i) { - X1 = mul(X1, EK[6*j+0]); - X2 += EK[6*j+1]; - X3 += EK[6*j+2]; - X4 = mul(X4, EK[6*j+3]); - - u16bit T0 = X3; - X3 = mul(X3 ^ X1, EK[6*j+4]); - - u16bit T1 = X2; - X2 = mul((X2 ^ X4) + X3, EK[6*j+5]); - X3 += X2; - - X1 ^= X2; - X4 ^= X3; - X2 ^= T0; - X3 ^= T1; + u16bit X1 = load_be<u16bit>(in, 0); + u16bit X2 = load_be<u16bit>(in, 1); + u16bit X3 = load_be<u16bit>(in, 2); + u16bit X4 = load_be<u16bit>(in, 3); + + for(u32bit j = 0; j != 8; ++j) + { + X1 = mul(X1, EK[6*j+0]); + X2 += EK[6*j+1]; + X3 += EK[6*j+2]; + X4 = mul(X4, EK[6*j+3]); + + u16bit T0 = X3; + X3 = mul(X3 ^ X1, EK[6*j+4]); + + u16bit T1 = X2; + X2 = mul((X2 ^ X4) + X3, EK[6*j+5]); + X3 += X2; + + X1 ^= X2; + X4 ^= X3; + X2 ^= T0; + X3 ^= T1; + } + + X1 = mul(X1, EK[48]); + X2 += EK[50]; + X3 += EK[49]; + X4 = mul(X4, EK[51]); + + store_be(out, X1, X3, X2, X4); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; } - - X1 = mul(X1, EK[48]); - X2 += EK[50]; - X3 += EK[49]; - X4 = mul(X4, EK[51]); - - store_be(out, X1, X3, X2, X4); } /* * IDEA Decryption */ -void IDEA::dec(const byte in[], byte out[]) const +void IDEA::decrypt_n(const byte in[], byte out[], u32bit blocks) const { - u16bit X1 = load_be<u16bit>(in, 0); - u16bit X2 = load_be<u16bit>(in, 1); - u16bit X3 = load_be<u16bit>(in, 2); - u16bit X4 = load_be<u16bit>(in, 3); - - for(u32bit j = 0; j != 8; ++j) + for(u32bit i = 0; i != blocks; ++i) { - X1 = mul(X1, DK[6*j+0]); - X2 += DK[6*j+1]; - X3 += DK[6*j+2]; - X4 = mul(X4, DK[6*j+3]); - - u16bit T0 = X3; - X3 = mul(X3 ^ X1, DK[6*j+4]); - - u16bit T1 = X2; - X2 = mul((X2 ^ X4) + X3, DK[6*j+5]); - X3 += X2; - - X1 ^= X2; - X4 ^= X3; - X2 ^= T0; - X3 ^= T1; + u16bit X1 = load_be<u16bit>(in, 0); + u16bit X2 = load_be<u16bit>(in, 1); + u16bit X3 = load_be<u16bit>(in, 2); + u16bit X4 = load_be<u16bit>(in, 3); + + for(u32bit j = 0; j != 8; ++j) + { + X1 = mul(X1, DK[6*j+0]); + X2 += DK[6*j+1]; + X3 += DK[6*j+2]; + X4 = mul(X4, DK[6*j+3]); + + u16bit T0 = X3; + X3 = mul(X3 ^ X1, DK[6*j+4]); + + u16bit T1 = X2; + X2 = mul((X2 ^ X4) + X3, DK[6*j+5]); + X3 += X2; + + X1 ^= X2; + X4 ^= X3; + X2 ^= T0; + X3 ^= T1; + } + + X1 = mul(X1, DK[48]); + X2 += DK[50]; + X3 += DK[49]; + X4 = mul(X4, DK[51]); + + store_be(out, X1, X3, X2, X4); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; } - - X1 = mul(X1, DK[48]); - X2 += DK[50]; - X3 += DK[49]; - X4 = mul(X4, DK[51]); - - store_be(out, X1, X3, X2, X4); } /* diff --git a/src/block/idea/idea.h b/src/block/idea/idea.h index 2c53cd0e4..c1a79f423 100644 --- a/src/block/idea/idea.h +++ b/src/block/idea/idea.h @@ -18,13 +18,15 @@ namespace Botan { class BOTAN_DLL IDEA : public BlockCipher { public: - void clear() throw() { EK.clear(); DK.clear(); } + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + + void clear() { EK.clear(); DK.clear(); } std::string name() const { return "IDEA"; } BlockCipher* clone() const { return new IDEA; } + IDEA() : BlockCipher(8, 16) {} private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; void key_schedule(const byte[], u32bit); SecureBuffer<u16bit, 52> EK, DK; }; diff --git a/src/block/idea/info.txt b/src/block/idea/info.txt index 2da3ffb43..a868d7cc7 100644 --- a/src/block/idea/info.txt +++ b/src/block/idea/info.txt @@ -1,10 +1 @@ -realname "IDEA" - define IDEA - -load_on auto - -<add> -idea.cpp -idea.h -</add> diff --git a/src/block/info.txt b/src/block/info.txt index ff48fb04a..b4302a6d8 100644 --- a/src/block/info.txt +++ b/src/block/info.txt @@ -1,13 +1,5 @@ -realname "Block Ciphers" - -load_on auto - define BLOCK_CIPHER -<add> -block_cipher.h -</add> - <requires> sym_algo </requires> diff --git a/src/block/kasumi/info.txt b/src/block/kasumi/info.txt index 8ea879b6d..cb8340fad 100644 --- a/src/block/kasumi/info.txt +++ b/src/block/kasumi/info.txt @@ -1,10 +1 @@ -realname "Kasumi" - define KASUMI - -load_on auto - -<add> -kasumi.cpp -kasumi.h -</add> diff --git a/src/block/kasumi/kasumi.cpp b/src/block/kasumi/kasumi.cpp index e051ddefb..dff6db13c 100644 --- a/src/block/kasumi/kasumi.cpp +++ b/src/block/kasumi/kasumi.cpp @@ -109,79 +109,91 @@ u16bit FI(u16bit I, u16bit K) /* * KASUMI Encryption */ -void KASUMI::enc(const byte in[], byte out[]) const +void KASUMI::encrypt_n(const byte in[], byte out[], u32bit blocks) const { - u16bit B0 = load_be<u16bit>(in, 0); - u16bit B1 = load_be<u16bit>(in, 1); - u16bit B2 = load_be<u16bit>(in, 2); - u16bit B3 = load_be<u16bit>(in, 3); - - for(u32bit j = 0; j != 8; j += 2) + for(u32bit i = 0; i != blocks; ++i) { - const u16bit* K = EK + 8*j; + u16bit B0 = load_be<u16bit>(in, 0); + u16bit B1 = load_be<u16bit>(in, 1); + u16bit B2 = load_be<u16bit>(in, 2); + u16bit B3 = load_be<u16bit>(in, 3); - u16bit R = B1 ^ (rotate_left(B0, 1) & K[0]); - u16bit L = B0 ^ (rotate_left(R, 1) | K[1]); + for(u32bit j = 0; j != 8; j += 2) + { + const u16bit* K = EK + 8*j; - L = FI(L ^ K[ 2], K[ 3]) ^ R; - R = FI(R ^ K[ 4], K[ 5]) ^ L; - L = FI(L ^ K[ 6], K[ 7]) ^ R; + u16bit R = B1 ^ (rotate_left(B0, 1) & K[0]); + u16bit L = B0 ^ (rotate_left(R, 1) | K[1]); - R = B2 ^= R; - L = B3 ^= L; + L = FI(L ^ K[ 2], K[ 3]) ^ R; + R = FI(R ^ K[ 4], K[ 5]) ^ L; + L = FI(L ^ K[ 6], K[ 7]) ^ R; - R = FI(R ^ K[10], K[11]) ^ L; - L = FI(L ^ K[12], K[13]) ^ R; - R = FI(R ^ K[14], K[15]) ^ L; + R = B2 ^= R; + L = B3 ^= L; - R ^= (rotate_left(L, 1) & K[8]); - L ^= (rotate_left(R, 1) | K[9]); + R = FI(R ^ K[10], K[11]) ^ L; + L = FI(L ^ K[12], K[13]) ^ R; + R = FI(R ^ K[14], K[15]) ^ L; - B0 ^= L; - B1 ^= R; - } + R ^= (rotate_left(L, 1) & K[8]); + L ^= (rotate_left(R, 1) | K[9]); + + B0 ^= L; + B1 ^= R; + } - store_be(out, B0, B1, B2, B3); + store_be(out, B0, B1, B2, B3); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* * KASUMI Decryption */ -void KASUMI::dec(const byte in[], byte out[]) const +void KASUMI::decrypt_n(const byte in[], byte out[], u32bit blocks) const { - u16bit B0 = load_be<u16bit>(in, 0); - u16bit B1 = load_be<u16bit>(in, 1); - u16bit B2 = load_be<u16bit>(in, 2); - u16bit B3 = load_be<u16bit>(in, 3); - - for(u32bit j = 0; j != 8; j += 2) + for(u32bit i = 0; i != blocks; ++i) { - const u16bit* K = EK + 8*(6-j); + u16bit B0 = load_be<u16bit>(in, 0); + u16bit B1 = load_be<u16bit>(in, 1); + u16bit B2 = load_be<u16bit>(in, 2); + u16bit B3 = load_be<u16bit>(in, 3); - u16bit L = B2, R = B3; + for(u32bit j = 0; j != 8; j += 2) + { + const u16bit* K = EK + 8*(6-j); - L = FI(L ^ K[10], K[11]) ^ R; - R = FI(R ^ K[12], K[13]) ^ L; - L = FI(L ^ K[14], K[15]) ^ R; + u16bit L = B2, R = B3; - L ^= (rotate_left(R, 1) & K[8]); - R ^= (rotate_left(L, 1) | K[9]); + L = FI(L ^ K[10], K[11]) ^ R; + R = FI(R ^ K[12], K[13]) ^ L; + L = FI(L ^ K[14], K[15]) ^ R; - R = B0 ^= R; - L = B1 ^= L; + L ^= (rotate_left(R, 1) & K[8]); + R ^= (rotate_left(L, 1) | K[9]); - L ^= (rotate_left(R, 1) & K[0]); - R ^= (rotate_left(L, 1) | K[1]); + R = B0 ^= R; + L = B1 ^= L; - R = FI(R ^ K[2], K[3]) ^ L; - L = FI(L ^ K[4], K[5]) ^ R; - R = FI(R ^ K[6], K[7]) ^ L; + L ^= (rotate_left(R, 1) & K[0]); + R ^= (rotate_left(L, 1) | K[1]); - B2 ^= L; - B3 ^= R; - } + R = FI(R ^ K[2], K[3]) ^ L; + L = FI(L ^ K[4], K[5]) ^ R; + R = FI(R ^ K[6], K[7]) ^ L; + + B2 ^= L; + B3 ^= R; + } - store_be(out, B0, B1, B2, B3); + store_be(out, B0, B1, B2, B3); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* diff --git a/src/block/kasumi/kasumi.h b/src/block/kasumi/kasumi.h index df49fa9eb..c3db1cb05 100644 --- a/src/block/kasumi/kasumi.h +++ b/src/block/kasumi/kasumi.h @@ -18,14 +18,15 @@ namespace Botan { class BOTAN_DLL KASUMI : public BlockCipher { public: - void clear() throw() { EK.clear(); } + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + + void clear() { EK.clear(); } std::string name() const { return "KASUMI"; } BlockCipher* clone() const { return new KASUMI; } KASUMI() : BlockCipher(8, 16) {} private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; void key_schedule(const byte[], u32bit); SecureBuffer<u16bit, 64> EK; diff --git a/src/block/lion/info.txt b/src/block/lion/info.txt index 81ef58511..9562be1d0 100644 --- a/src/block/lion/info.txt +++ b/src/block/lion/info.txt @@ -1,14 +1,5 @@ -realname "Lion" - define LION -load_on auto - -<add> -lion.cpp -lion.h -</add> - <requires> hash stream diff --git a/src/block/lion/lion.cpp b/src/block/lion/lion.cpp index c7cdf6d13..e71091258 100644 --- a/src/block/lion/lion.cpp +++ b/src/block/lion/lion.cpp @@ -14,41 +14,53 @@ namespace Botan { /* * Lion Encryption */ -void Lion::enc(const byte in[], byte out[]) const +void Lion::encrypt_n(const byte in[], byte out[], u32bit blocks) const { SecureVector<byte> buffer(LEFT_SIZE); - xor_buf(buffer, in, key1, LEFT_SIZE); - cipher->set_key(buffer, LEFT_SIZE); - cipher->encrypt(in + LEFT_SIZE, out + LEFT_SIZE, RIGHT_SIZE); + for(u32bit i = 0; i != blocks; ++i) + { + xor_buf(buffer, in, key1, LEFT_SIZE); + cipher->set_key(buffer, LEFT_SIZE); + cipher->cipher(in + LEFT_SIZE, out + LEFT_SIZE, RIGHT_SIZE); - hash->update(out + LEFT_SIZE, RIGHT_SIZE); - hash->final(buffer); - xor_buf(out, in, buffer, LEFT_SIZE); + hash->update(out + LEFT_SIZE, RIGHT_SIZE); + hash->final(buffer); + xor_buf(out, in, buffer, LEFT_SIZE); - xor_buf(buffer, out, key2, LEFT_SIZE); - cipher->set_key(buffer, LEFT_SIZE); - cipher->encrypt(out + LEFT_SIZE, RIGHT_SIZE); + xor_buf(buffer, out, key2, LEFT_SIZE); + cipher->set_key(buffer, LEFT_SIZE); + cipher->cipher1(out + LEFT_SIZE, RIGHT_SIZE); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* * Lion Decryption */ -void Lion::dec(const byte in[], byte out[]) const +void Lion::decrypt_n(const byte in[], byte out[], u32bit blocks) const { SecureVector<byte> buffer(LEFT_SIZE); - xor_buf(buffer, in, key2, LEFT_SIZE); - cipher->set_key(buffer, LEFT_SIZE); - cipher->encrypt(in + LEFT_SIZE, out + LEFT_SIZE, RIGHT_SIZE); + for(u32bit i = 0; i != blocks; ++i) + { + xor_buf(buffer, in, key2, LEFT_SIZE); + cipher->set_key(buffer, LEFT_SIZE); + cipher->cipher(in + LEFT_SIZE, out + LEFT_SIZE, RIGHT_SIZE); + + hash->update(out + LEFT_SIZE, RIGHT_SIZE); + hash->final(buffer); + xor_buf(out, in, buffer, LEFT_SIZE); - hash->update(out + LEFT_SIZE, RIGHT_SIZE); - hash->final(buffer); - xor_buf(out, in, buffer, LEFT_SIZE); + xor_buf(buffer, out, key1, LEFT_SIZE); + cipher->set_key(buffer, LEFT_SIZE); + cipher->cipher1(out + LEFT_SIZE, RIGHT_SIZE); - xor_buf(buffer, out, key1, LEFT_SIZE); - cipher->set_key(buffer, LEFT_SIZE); - cipher->encrypt(out + LEFT_SIZE, RIGHT_SIZE); + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* @@ -83,7 +95,7 @@ BlockCipher* Lion::clone() const /* * Clear memory of sensitive data */ -void Lion::clear() throw() +void Lion::clear() { hash->clear(); cipher->clear(); diff --git a/src/block/lion/lion.h b/src/block/lion/lion.h index 5bc4e72c0..f24acdb72 100644 --- a/src/block/lion/lion.h +++ b/src/block/lion/lion.h @@ -20,15 +20,16 @@ namespace Botan { class BOTAN_DLL Lion : public BlockCipher { public: - void clear() throw(); + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + + void clear(); std::string name() const; BlockCipher* clone() const; Lion(HashFunction*, StreamCipher*, u32bit); ~Lion() { delete hash; delete cipher; } private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; void key_schedule(const byte[], u32bit); const u32bit LEFT_SIZE, RIGHT_SIZE; diff --git a/src/block/lubyrack/info.txt b/src/block/lubyrack/info.txt index a478526f4..41c395097 100644 --- a/src/block/lubyrack/info.txt +++ b/src/block/lubyrack/info.txt @@ -1,14 +1,5 @@ -realname "Luby-Rackoff" - define LUBY_RACKOFF -load_on auto - -<add> -lubyrack.cpp -lubyrack.h -</add> - <requires> hash </requires> diff --git a/src/block/lubyrack/lubyrack.cpp b/src/block/lubyrack/lubyrack.cpp index a9d2b1db2..2003d2a89 100644 --- a/src/block/lubyrack/lubyrack.cpp +++ b/src/block/lubyrack/lubyrack.cpp @@ -13,59 +13,71 @@ namespace Botan { /* * Luby-Rackoff Encryption */ -void LubyRackoff::enc(const byte in[], byte out[]) const +void LubyRackoff::encrypt_n(const byte in[], byte out[], u32bit blocks) const { - const u32bit len = hash->OUTPUT_LENGTH; - - SecureVector<byte> buffer(len); - hash->update(K1); - hash->update(in, len); - hash->final(buffer); - xor_buf(out + len, in + len, buffer, len); - - hash->update(K2); - hash->update(out + len, len); - hash->final(buffer); - xor_buf(out, in, buffer, len); - - hash->update(K1); - hash->update(out, len); - hash->final(buffer); - xor_buf(out + len, buffer, len); - - hash->update(K2); - hash->update(out + len, len); - hash->final(buffer); - xor_buf(out, buffer, len); + for(u32bit i = 0; i != blocks; ++i) + { + const u32bit len = hash->OUTPUT_LENGTH; + + SecureVector<byte> buffer(len); + hash->update(K1); + hash->update(in, len); + hash->final(buffer); + xor_buf(out + len, in + len, buffer, len); + + hash->update(K2); + hash->update(out + len, len); + hash->final(buffer); + xor_buf(out, in, buffer, len); + + hash->update(K1); + hash->update(out, len); + hash->final(buffer); + xor_buf(out + len, buffer, len); + + hash->update(K2); + hash->update(out + len, len); + hash->final(buffer); + xor_buf(out, buffer, len); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* * Luby-Rackoff Decryption */ -void LubyRackoff::dec(const byte in[], byte out[]) const +void LubyRackoff::decrypt_n(const byte in[], byte out[], u32bit blocks) const { - const u32bit len = hash->OUTPUT_LENGTH; - - SecureVector<byte> buffer(len); - hash->update(K2); - hash->update(in + len, len); - hash->final(buffer); - xor_buf(out, in, buffer, len); - - hash->update(K1); - hash->update(out, len); - hash->final(buffer); - xor_buf(out + len, in + len, buffer, len); - - hash->update(K2); - hash->update(out + len, len); - hash->final(buffer); - xor_buf(out, buffer, len); - - hash->update(K1); - hash->update(out, len); - hash->final(buffer); - xor_buf(out + len, buffer, len); + for(u32bit i = 0; i != blocks; ++i) + { + const u32bit len = hash->OUTPUT_LENGTH; + + SecureVector<byte> buffer(len); + hash->update(K2); + hash->update(in + len, len); + hash->final(buffer); + xor_buf(out, in, buffer, len); + + hash->update(K1); + hash->update(out, len); + hash->final(buffer); + xor_buf(out + len, in + len, buffer, len); + + hash->update(K2); + hash->update(out + len, len); + hash->final(buffer); + xor_buf(out, buffer, len); + + hash->update(K1); + hash->update(out, len); + hash->final(buffer); + xor_buf(out + len, buffer, len); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* @@ -80,7 +92,7 @@ void LubyRackoff::key_schedule(const byte key[], u32bit length) /* * Clear memory of sensitive data */ -void LubyRackoff::clear() throw() +void LubyRackoff::clear() { K1.clear(); K2.clear(); diff --git a/src/block/lubyrack/lubyrack.h b/src/block/lubyrack/lubyrack.h index ebde31304..7249cf157 100644 --- a/src/block/lubyrack/lubyrack.h +++ b/src/block/lubyrack/lubyrack.h @@ -19,16 +19,18 @@ namespace Botan { class BOTAN_DLL LubyRackoff : public BlockCipher { public: - void clear() throw(); + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + + void clear(); std::string name() const; BlockCipher* clone() const; LubyRackoff(HashFunction* hash); ~LubyRackoff() { delete hash; } private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; void key_schedule(const byte[], u32bit); + HashFunction* hash; SecureVector<byte> K1, K2; }; diff --git a/src/block/mars/info.txt b/src/block/mars/info.txt index b0ad8af9c..afdcebe67 100644 --- a/src/block/mars/info.txt +++ b/src/block/mars/info.txt @@ -1,11 +1 @@ -realname "MARS" - define MARS - -load_on auto - -<add> -mars.cpp -mars.h -mars_tab.cpp -</add> diff --git a/src/block/mars/mars.cpp b/src/block/mars/mars.cpp index 08c8409c5..69556acb3 100644 --- a/src/block/mars/mars.cpp +++ b/src/block/mars/mars.cpp @@ -1,6 +1,6 @@ /* * MARS -* (C) 1999-2007 Jack Lloyd +* (C) 1999-2009 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -50,75 +50,87 @@ u32bit gen_mask(u32bit input) /* * MARS Encryption */ -void MARS::enc(const byte in[], byte out[]) const +void MARS::encrypt_n(const byte in[], byte out[], u32bit blocks) const { - u32bit A = load_le<u32bit>(in, 0) + EK[0]; - u32bit B = load_le<u32bit>(in, 1) + EK[1]; - u32bit C = load_le<u32bit>(in, 2) + EK[2]; - u32bit D = load_le<u32bit>(in, 3) + EK[3]; - - forward_mix(A, B, C, D); - - encrypt_round(A, B, C, D, 0); - encrypt_round(B, C, D, A, 1); - encrypt_round(C, D, A, B, 2); - encrypt_round(D, A, B, C, 3); - encrypt_round(A, B, C, D, 4); - encrypt_round(B, C, D, A, 5); - encrypt_round(C, D, A, B, 6); - encrypt_round(D, A, B, C, 7); - - encrypt_round(A, D, C, B, 8); - encrypt_round(B, A, D, C, 9); - encrypt_round(C, B, A, D, 10); - encrypt_round(D, C, B, A, 11); - encrypt_round(A, D, C, B, 12); - encrypt_round(B, A, D, C, 13); - encrypt_round(C, B, A, D, 14); - encrypt_round(D, C, B, A, 15); - - reverse_mix(A, B, C, D); - - A -= EK[36]; B -= EK[37]; C -= EK[38]; D -= EK[39]; - - store_le(out, A, B, C, D); + for(u32bit i = 0; i != blocks; ++i) + { + u32bit A = load_le<u32bit>(in, 0) + EK[0]; + u32bit B = load_le<u32bit>(in, 1) + EK[1]; + u32bit C = load_le<u32bit>(in, 2) + EK[2]; + u32bit D = load_le<u32bit>(in, 3) + EK[3]; + + forward_mix(A, B, C, D); + + encrypt_round(A, B, C, D, 0); + encrypt_round(B, C, D, A, 1); + encrypt_round(C, D, A, B, 2); + encrypt_round(D, A, B, C, 3); + encrypt_round(A, B, C, D, 4); + encrypt_round(B, C, D, A, 5); + encrypt_round(C, D, A, B, 6); + encrypt_round(D, A, B, C, 7); + + encrypt_round(A, D, C, B, 8); + encrypt_round(B, A, D, C, 9); + encrypt_round(C, B, A, D, 10); + encrypt_round(D, C, B, A, 11); + encrypt_round(A, D, C, B, 12); + encrypt_round(B, A, D, C, 13); + encrypt_round(C, B, A, D, 14); + encrypt_round(D, C, B, A, 15); + + reverse_mix(A, B, C, D); + + A -= EK[36]; B -= EK[37]; C -= EK[38]; D -= EK[39]; + + store_le(out, A, B, C, D); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* * MARS Decryption */ -void MARS::dec(const byte in[], byte out[]) const +void MARS::decrypt_n(const byte in[], byte out[], u32bit blocks) const { - u32bit A = load_le<u32bit>(in, 3) + EK[39]; - u32bit B = load_le<u32bit>(in, 2) + EK[38]; - u32bit C = load_le<u32bit>(in, 1) + EK[37]; - u32bit D = load_le<u32bit>(in, 0) + EK[36]; - - forward_mix(A, B, C, D); - - decrypt_round(A, B, C, D, 15); - decrypt_round(B, C, D, A, 14); - decrypt_round(C, D, A, B, 13); - decrypt_round(D, A, B, C, 12); - decrypt_round(A, B, C, D, 11); - decrypt_round(B, C, D, A, 10); - decrypt_round(C, D, A, B, 9); - decrypt_round(D, A, B, C, 8); - - decrypt_round(A, D, C, B, 7); - decrypt_round(B, A, D, C, 6); - decrypt_round(C, B, A, D, 5); - decrypt_round(D, C, B, A, 4); - decrypt_round(A, D, C, B, 3); - decrypt_round(B, A, D, C, 2); - decrypt_round(C, B, A, D, 1); - decrypt_round(D, C, B, A, 0); - - reverse_mix(A, B, C, D); - - A -= EK[3]; B -= EK[2]; C -= EK[1]; D -= EK[0]; - - store_le(out, D, C, B, A); + for(u32bit i = 0; i != blocks; ++i) + { + u32bit A = load_le<u32bit>(in, 3) + EK[39]; + u32bit B = load_le<u32bit>(in, 2) + EK[38]; + u32bit C = load_le<u32bit>(in, 1) + EK[37]; + u32bit D = load_le<u32bit>(in, 0) + EK[36]; + + forward_mix(A, B, C, D); + + decrypt_round(A, B, C, D, 15); + decrypt_round(B, C, D, A, 14); + decrypt_round(C, D, A, B, 13); + decrypt_round(D, A, B, C, 12); + decrypt_round(A, B, C, D, 11); + decrypt_round(B, C, D, A, 10); + decrypt_round(C, D, A, B, 9); + decrypt_round(D, A, B, C, 8); + + decrypt_round(A, D, C, B, 7); + decrypt_round(B, A, D, C, 6); + decrypt_round(C, B, A, D, 5); + decrypt_round(D, C, B, A, 4); + decrypt_round(A, D, C, B, 3); + decrypt_round(B, A, D, C, 2); + decrypt_round(C, B, A, D, 1); + decrypt_round(D, C, B, A, 0); + + reverse_mix(A, B, C, D); + + A -= EK[3]; B -= EK[2]; C -= EK[1]; D -= EK[0]; + + store_le(out, D, C, B, A); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* diff --git a/src/block/mars/mars.h b/src/block/mars/mars.h index ca49695af..8173fb984 100644 --- a/src/block/mars/mars.h +++ b/src/block/mars/mars.h @@ -15,13 +15,15 @@ namespace Botan { class BOTAN_DLL MARS : public BlockCipher { public: - void clear() throw() { EK.clear(); } + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + + void clear() { EK.clear(); } std::string name() const { return "MARS"; } BlockCipher* clone() const { return new MARS; } + MARS() : BlockCipher(16, 16, 32, 4) {} private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; void key_schedule(const byte[], u32bit); void encrypt_round(u32bit&, u32bit&, u32bit&, u32bit&, u32bit) const; diff --git a/src/block/misty1/info.txt b/src/block/misty1/info.txt index d45058bd4..290b8b1d7 100644 --- a/src/block/misty1/info.txt +++ b/src/block/misty1/info.txt @@ -1,10 +1 @@ -realname "MISTY-1" - define MISTY1 - -load_on auto - -<add> -misty1.cpp -misty1.h -</add> diff --git a/src/block/misty1/misty1.cpp b/src/block/misty1/misty1.cpp index a35ff584d..8a92824cc 100644 --- a/src/block/misty1/misty1.cpp +++ b/src/block/misty1/misty1.cpp @@ -1,6 +1,6 @@ /* * MISTY1 -* (C) 1999-2007 Jack Lloyd +* (C) 1999-2009 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -102,89 +102,101 @@ u16bit FI(u16bit input, u16bit key7, u16bit key9) /* * MISTY1 Encryption */ -void MISTY1::enc(const byte in[], byte out[]) const +void MISTY1::encrypt_n(const byte in[], byte out[], u32bit blocks) const { - u16bit B0 = load_be<u16bit>(in, 0); - u16bit B1 = load_be<u16bit>(in, 1); - u16bit B2 = load_be<u16bit>(in, 2); - u16bit B3 = load_be<u16bit>(in, 3); - - for(u32bit j = 0; j != 12; j += 3) + for(u32bit i = 0; i != blocks; ++i) { - const u16bit* RK = EK + 8 * j; + u16bit B0 = load_be<u16bit>(in, 0); + u16bit B1 = load_be<u16bit>(in, 1); + u16bit B2 = load_be<u16bit>(in, 2); + u16bit B3 = load_be<u16bit>(in, 3); - B1 ^= B0 & RK[0]; - B0 ^= B1 | RK[1]; - B3 ^= B2 & RK[2]; - B2 ^= B3 | RK[3]; + for(u32bit j = 0; j != 12; j += 3) + { + const u16bit* RK = EK + 8 * j; - u32bit T0, T1; + B1 ^= B0 & RK[0]; + B0 ^= B1 | RK[1]; + B3 ^= B2 & RK[2]; + B2 ^= B3 | RK[3]; - T0 = FI(B0 ^ RK[ 4], RK[ 5], RK[ 6]) ^ B1; - T1 = FI(B1 ^ RK[ 7], RK[ 8], RK[ 9]) ^ T0; - T0 = FI(T0 ^ RK[10], RK[11], RK[12]) ^ T1; + u32bit T0, T1; - B2 ^= T1 ^ RK[13]; - B3 ^= T0; + T0 = FI(B0 ^ RK[ 4], RK[ 5], RK[ 6]) ^ B1; + T1 = FI(B1 ^ RK[ 7], RK[ 8], RK[ 9]) ^ T0; + T0 = FI(T0 ^ RK[10], RK[11], RK[12]) ^ T1; - T0 = FI(B2 ^ RK[14], RK[15], RK[16]) ^ B3; - T1 = FI(B3 ^ RK[17], RK[18], RK[19]) ^ T0; - T0 = FI(T0 ^ RK[20], RK[21], RK[22]) ^ T1; + B2 ^= T1 ^ RK[13]; + B3 ^= T0; - B0 ^= T1 ^ RK[23]; - B1 ^= T0; - } + T0 = FI(B2 ^ RK[14], RK[15], RK[16]) ^ B3; + T1 = FI(B3 ^ RK[17], RK[18], RK[19]) ^ T0; + T0 = FI(T0 ^ RK[20], RK[21], RK[22]) ^ T1; + + B0 ^= T1 ^ RK[23]; + B1 ^= T0; + } - B1 ^= B0 & EK[96]; - B0 ^= B1 | EK[97]; - B3 ^= B2 & EK[98]; - B2 ^= B3 | EK[99]; + B1 ^= B0 & EK[96]; + B0 ^= B1 | EK[97]; + B3 ^= B2 & EK[98]; + B2 ^= B3 | EK[99]; - store_be(out, B2, B3, B0, B1); + store_be(out, B2, B3, B0, B1); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* * MISTY1 Decryption */ -void MISTY1::dec(const byte in[], byte out[]) const +void MISTY1::decrypt_n(const byte in[], byte out[], u32bit blocks) const { - u16bit B0 = load_be<u16bit>(in, 2); - u16bit B1 = load_be<u16bit>(in, 3); - u16bit B2 = load_be<u16bit>(in, 0); - u16bit B3 = load_be<u16bit>(in, 1); - - for(u32bit j = 0; j != 12; j += 3) + for(u32bit i = 0; i != blocks; ++i) { - const u16bit* RK = DK + 8 * j; + u16bit B0 = load_be<u16bit>(in, 2); + u16bit B1 = load_be<u16bit>(in, 3); + u16bit B2 = load_be<u16bit>(in, 0); + u16bit B3 = load_be<u16bit>(in, 1); - B2 ^= B3 | RK[0]; - B3 ^= B2 & RK[1]; - B0 ^= B1 | RK[2]; - B1 ^= B0 & RK[3]; + for(u32bit j = 0; j != 12; j += 3) + { + const u16bit* RK = DK + 8 * j; - u32bit T0, T1; + B2 ^= B3 | RK[0]; + B3 ^= B2 & RK[1]; + B0 ^= B1 | RK[2]; + B1 ^= B0 & RK[3]; - T0 = FI(B2 ^ RK[ 4], RK[ 5], RK[ 6]) ^ B3; - T1 = FI(B3 ^ RK[ 7], RK[ 8], RK[ 9]) ^ T0; - T0 = FI(T0 ^ RK[10], RK[11], RK[12]) ^ T1; + u32bit T0, T1; - B0 ^= T1 ^ RK[13]; - B1 ^= T0; + T0 = FI(B2 ^ RK[ 4], RK[ 5], RK[ 6]) ^ B3; + T1 = FI(B3 ^ RK[ 7], RK[ 8], RK[ 9]) ^ T0; + T0 = FI(T0 ^ RK[10], RK[11], RK[12]) ^ T1; - T0 = FI(B0 ^ RK[14], RK[15], RK[16]) ^ B1; - T1 = FI(B1 ^ RK[17], RK[18], RK[19]) ^ T0; - T0 = FI(T0 ^ RK[20], RK[21], RK[22]) ^ T1; + B0 ^= T1 ^ RK[13]; + B1 ^= T0; - B2 ^= T1 ^ RK[23]; - B3 ^= T0; - } + T0 = FI(B0 ^ RK[14], RK[15], RK[16]) ^ B1; + T1 = FI(B1 ^ RK[17], RK[18], RK[19]) ^ T0; + T0 = FI(T0 ^ RK[20], RK[21], RK[22]) ^ T1; + + B2 ^= T1 ^ RK[23]; + B3 ^= T0; + } - B2 ^= B3 | DK[96]; - B3 ^= B2 & DK[97]; - B0 ^= B1 | DK[98]; - B1 ^= B0 & DK[99]; + B2 ^= B3 | DK[96]; + B3 ^= B2 & DK[97]; + B0 ^= B1 | DK[98]; + B1 ^= B0 & DK[99]; - store_be(out, B0, B1, B2, B3); + store_be(out, B0, B1, B2, B3); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* diff --git a/src/block/misty1/misty1.h b/src/block/misty1/misty1.h index 62d4f856f..000830915 100644 --- a/src/block/misty1/misty1.h +++ b/src/block/misty1/misty1.h @@ -18,13 +18,15 @@ namespace Botan { class BOTAN_DLL MISTY1 : public BlockCipher { public: - void clear() throw() { EK.clear(); DK.clear(); } + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + + void clear() { EK.clear(); DK.clear(); } std::string name() const { return "MISTY1"; } BlockCipher* clone() const { return new MISTY1; } + MISTY1(u32bit = 8); private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; void key_schedule(const byte[], u32bit); SecureBuffer<u16bit, 100> EK, DK; diff --git a/src/block/noekeon/info.txt b/src/block/noekeon/info.txt index 8025c2073..31f7e7de3 100644 --- a/src/block/noekeon/info.txt +++ b/src/block/noekeon/info.txt @@ -1,10 +1 @@ -realname "Noekeon" - define NOEKEON - -load_on auto - -<add> -noekeon.cpp -noekeon.h -</add> diff --git a/src/block/noekeon/noekeon.cpp b/src/block/noekeon/noekeon.cpp index 90eb9ad2b..0bfce1882 100644 --- a/src/block/noekeon/noekeon.cpp +++ b/src/block/noekeon/noekeon.cpp @@ -84,65 +84,77 @@ const byte Noekeon::RC[] = { /* * Noekeon Encryption */ -void Noekeon::enc(const byte in[], byte out[]) const +void Noekeon::encrypt_n(const byte in[], byte out[], u32bit blocks) const { - u32bit A0 = load_be<u32bit>(in, 0); - u32bit A1 = load_be<u32bit>(in, 1); - u32bit A2 = load_be<u32bit>(in, 2); - u32bit A3 = load_be<u32bit>(in, 3); - - for(u32bit j = 0; j != 16; ++j) + for(u32bit i = 0; i != blocks; ++i) { - A0 ^= RC[j]; - theta(A0, A1, A2, A3, EK); + u32bit A0 = load_be<u32bit>(in, 0); + u32bit A1 = load_be<u32bit>(in, 1); + u32bit A2 = load_be<u32bit>(in, 2); + u32bit A3 = load_be<u32bit>(in, 3); - A1 = rotate_left(A1, 1); - A2 = rotate_left(A2, 5); - A3 = rotate_left(A3, 2); + for(u32bit j = 0; j != 16; ++j) + { + A0 ^= RC[j]; + theta(A0, A1, A2, A3, EK); - gamma(A0, A1, A2, A3); + A1 = rotate_left(A1, 1); + A2 = rotate_left(A2, 5); + A3 = rotate_left(A3, 2); - A1 = rotate_right(A1, 1); - A2 = rotate_right(A2, 5); - A3 = rotate_right(A3, 2); - } + gamma(A0, A1, A2, A3); - A0 ^= RC[16]; - theta(A0, A1, A2, A3, EK); + A1 = rotate_right(A1, 1); + A2 = rotate_right(A2, 5); + A3 = rotate_right(A3, 2); + } + + A0 ^= RC[16]; + theta(A0, A1, A2, A3, EK); + + store_be(out, A0, A1, A2, A3); - store_be(out, A0, A1, A2, A3); + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* * Noekeon Encryption */ -void Noekeon::dec(const byte in[], byte out[]) const +void Noekeon::decrypt_n(const byte in[], byte out[], u32bit blocks) const { - u32bit A0 = load_be<u32bit>(in, 0); - u32bit A1 = load_be<u32bit>(in, 1); - u32bit A2 = load_be<u32bit>(in, 2); - u32bit A3 = load_be<u32bit>(in, 3); - - for(u32bit j = 16; j != 0; --j) + for(u32bit i = 0; i != blocks; ++i) { - theta(A0, A1, A2, A3, DK); - A0 ^= RC[j]; + u32bit A0 = load_be<u32bit>(in, 0); + u32bit A1 = load_be<u32bit>(in, 1); + u32bit A2 = load_be<u32bit>(in, 2); + u32bit A3 = load_be<u32bit>(in, 3); - A1 = rotate_left(A1, 1); - A2 = rotate_left(A2, 5); - A3 = rotate_left(A3, 2); + for(u32bit j = 16; j != 0; --j) + { + theta(A0, A1, A2, A3, DK); + A0 ^= RC[j]; - gamma(A0, A1, A2, A3); + A1 = rotate_left(A1, 1); + A2 = rotate_left(A2, 5); + A3 = rotate_left(A3, 2); - A1 = rotate_right(A1, 1); - A2 = rotate_right(A2, 5); - A3 = rotate_right(A3, 2); - } + gamma(A0, A1, A2, A3); - theta(A0, A1, A2, A3, DK); - A0 ^= RC[0]; + A1 = rotate_right(A1, 1); + A2 = rotate_right(A2, 5); + A3 = rotate_right(A3, 2); + } - store_be(out, A0, A1, A2, A3); + theta(A0, A1, A2, A3, DK); + A0 ^= RC[0]; + + store_be(out, A0, A1, A2, A3); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* @@ -189,7 +201,7 @@ void Noekeon::key_schedule(const byte key[], u32bit) /* * Clear memory of sensitive data */ -void Noekeon::clear() throw() +void Noekeon::clear() { EK.clear(); DK.clear(); diff --git a/src/block/noekeon/noekeon.h b/src/block/noekeon/noekeon.h index 893892446..4532c1be2 100644 --- a/src/block/noekeon/noekeon.h +++ b/src/block/noekeon/noekeon.h @@ -18,13 +18,15 @@ namespace Botan { class BOTAN_DLL Noekeon : public BlockCipher { public: - void clear() throw(); + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + + void clear(); std::string name() const { return "Noekeon"; } BlockCipher* clone() const { return new Noekeon; } + Noekeon() : BlockCipher(16, 16) {} private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; void key_schedule(const byte[], u32bit); static const byte RC[17]; diff --git a/src/block/rc2/info.txt b/src/block/rc2/info.txt index 099141de7..7eee38d6b 100644 --- a/src/block/rc2/info.txt +++ b/src/block/rc2/info.txt @@ -1,10 +1 @@ -realname "RC2" - define RC2 - -load_on auto - -<add> -rc2.cpp -rc2.h -</add> diff --git a/src/block/rc2/rc2.cpp b/src/block/rc2/rc2.cpp index 5827bdb68..b5e4a7d50 100644 --- a/src/block/rc2/rc2.cpp +++ b/src/block/rc2/rc2.cpp @@ -14,73 +14,85 @@ namespace Botan { /* * RC2 Encryption */ -void RC2::enc(const byte in[], byte out[]) const +void RC2::encrypt_n(const byte in[], byte out[], u32bit blocks) const { - u16bit R0 = load_le<u16bit>(in, 0); - u16bit R1 = load_le<u16bit>(in, 1); - u16bit R2 = load_le<u16bit>(in, 2); - u16bit R3 = load_le<u16bit>(in, 3); - - for(u32bit j = 0; j != 16; ++j) + for(u32bit i = 0; i != blocks; ++i) { - R0 += (R1 & ~R3) + (R2 & R3) + K[4*j]; - R0 = rotate_left(R0, 1); + u16bit R0 = load_le<u16bit>(in, 0); + u16bit R1 = load_le<u16bit>(in, 1); + u16bit R2 = load_le<u16bit>(in, 2); + u16bit R3 = load_le<u16bit>(in, 3); + + for(u32bit j = 0; j != 16; ++j) + { + R0 += (R1 & ~R3) + (R2 & R3) + K[4*j]; + R0 = rotate_left(R0, 1); - R1 += (R2 & ~R0) + (R3 & R0) + K[4*j + 1]; - R1 = rotate_left(R1, 2); + R1 += (R2 & ~R0) + (R3 & R0) + K[4*j + 1]; + R1 = rotate_left(R1, 2); - R2 += (R3 & ~R1) + (R0 & R1) + K[4*j + 2]; - R2 = rotate_left(R2, 3); + R2 += (R3 & ~R1) + (R0 & R1) + K[4*j + 2]; + R2 = rotate_left(R2, 3); - R3 += (R0 & ~R2) + (R1 & R2) + K[4*j + 3]; - R3 = rotate_left(R3, 5); + R3 += (R0 & ~R2) + (R1 & R2) + K[4*j + 3]; + R3 = rotate_left(R3, 5); - if(j == 4 || j == 10) - { - R0 += K[R3 % 64]; - R1 += K[R0 % 64]; - R2 += K[R1 % 64]; - R3 += K[R2 % 64]; + if(j == 4 || j == 10) + { + R0 += K[R3 % 64]; + R1 += K[R0 % 64]; + R2 += K[R1 % 64]; + R3 += K[R2 % 64]; + } } - } - store_le(out, R0, R1, R2, R3); + store_le(out, R0, R1, R2, R3); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* * RC2 Decryption */ -void RC2::dec(const byte in[], byte out[]) const +void RC2::decrypt_n(const byte in[], byte out[], u32bit blocks) const { - u16bit R0 = load_le<u16bit>(in, 0); - u16bit R1 = load_le<u16bit>(in, 1); - u16bit R2 = load_le<u16bit>(in, 2); - u16bit R3 = load_le<u16bit>(in, 3); - - for(u32bit j = 0; j != 16; ++j) + for(u32bit i = 0; i != blocks; ++i) { - R3 = rotate_right(R3, 5); - R3 -= (R0 & ~R2) + (R1 & R2) + K[63 - (4*j + 0)]; + u16bit R0 = load_le<u16bit>(in, 0); + u16bit R1 = load_le<u16bit>(in, 1); + u16bit R2 = load_le<u16bit>(in, 2); + u16bit R3 = load_le<u16bit>(in, 3); + + for(u32bit j = 0; j != 16; ++j) + { + R3 = rotate_right(R3, 5); + R3 -= (R0 & ~R2) + (R1 & R2) + K[63 - (4*j + 0)]; - R2 = rotate_right(R2, 3); - R2 -= (R3 & ~R1) + (R0 & R1) + K[63 - (4*j + 1)]; + R2 = rotate_right(R2, 3); + R2 -= (R3 & ~R1) + (R0 & R1) + K[63 - (4*j + 1)]; - R1 = rotate_right(R1, 2); - R1 -= (R2 & ~R0) + (R3 & R0) + K[63 - (4*j + 2)]; + R1 = rotate_right(R1, 2); + R1 -= (R2 & ~R0) + (R3 & R0) + K[63 - (4*j + 2)]; - R0 = rotate_right(R0, 1); - R0 -= (R1 & ~R3) + (R2 & R3) + K[63 - (4*j + 3)]; + R0 = rotate_right(R0, 1); + R0 -= (R1 & ~R3) + (R2 & R3) + K[63 - (4*j + 3)]; - if(j == 4 || j == 10) - { - R3 -= K[R2 % 64]; - R2 -= K[R1 % 64]; - R1 -= K[R0 % 64]; - R0 -= K[R3 % 64]; + if(j == 4 || j == 10) + { + R3 -= K[R2 % 64]; + R2 -= K[R1 % 64]; + R1 -= K[R0 % 64]; + R0 -= K[R3 % 64]; + } } - } - store_le(out, R0, R1, R2, R3); + store_le(out, R0, R1, R2, R3); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* diff --git a/src/block/rc2/rc2.h b/src/block/rc2/rc2.h index cb6f58f04..c6e4946f9 100644 --- a/src/block/rc2/rc2.h +++ b/src/block/rc2/rc2.h @@ -18,15 +18,17 @@ namespace Botan { class BOTAN_DLL RC2 : public BlockCipher { public: + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + static byte EKB_code(u32bit); - void clear() throw() { K.clear(); } + void clear() { K.clear(); } std::string name() const { return "RC2"; } BlockCipher* clone() const { return new RC2; } + RC2() : BlockCipher(8, 1, 32) {} private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; void key_schedule(const byte[], u32bit); SecureBuffer<u16bit, 64> K; diff --git a/src/block/rc5/info.txt b/src/block/rc5/info.txt index 4a150c3b0..3da32710d 100644 --- a/src/block/rc5/info.txt +++ b/src/block/rc5/info.txt @@ -1,10 +1 @@ -realname "RC5" - define RC5 - -load_on auto - -<add> -rc5.cpp -rc5.h -</add> diff --git a/src/block/rc5/rc5.cpp b/src/block/rc5/rc5.cpp index 5d83d5a4e..4bfa27ea0 100644 --- a/src/block/rc5/rc5.cpp +++ b/src/block/rc5/rc5.cpp @@ -16,47 +16,59 @@ namespace Botan { /* * RC5 Encryption */ -void RC5::enc(const byte in[], byte out[]) const +void RC5::encrypt_n(const byte in[], byte out[], u32bit blocks) const { - u32bit A = load_le<u32bit>(in, 0), B = load_le<u32bit>(in, 1); - - A += S[0]; B += S[1]; - for(u32bit j = 0; j != ROUNDS; j += 4) + for(u32bit i = 0; i != blocks; ++i) { - A = rotate_left(A ^ B, B % 32) + S[2*j+2]; - B = rotate_left(B ^ A, A % 32) + S[2*j+3]; - A = rotate_left(A ^ B, B % 32) + S[2*j+4]; - B = rotate_left(B ^ A, A % 32) + S[2*j+5]; - A = rotate_left(A ^ B, B % 32) + S[2*j+6]; - B = rotate_left(B ^ A, A % 32) + S[2*j+7]; - A = rotate_left(A ^ B, B % 32) + S[2*j+8]; - B = rotate_left(B ^ A, A % 32) + S[2*j+9]; - } + u32bit A = load_le<u32bit>(in, 0), B = load_le<u32bit>(in, 1); + + A += S[0]; B += S[1]; + for(u32bit j = 0; j != ROUNDS; j += 4) + { + A = rotate_left(A ^ B, B % 32) + S[2*j+2]; + B = rotate_left(B ^ A, A % 32) + S[2*j+3]; + A = rotate_left(A ^ B, B % 32) + S[2*j+4]; + B = rotate_left(B ^ A, A % 32) + S[2*j+5]; + A = rotate_left(A ^ B, B % 32) + S[2*j+6]; + B = rotate_left(B ^ A, A % 32) + S[2*j+7]; + A = rotate_left(A ^ B, B % 32) + S[2*j+8]; + B = rotate_left(B ^ A, A % 32) + S[2*j+9]; + } - store_le(out, A, B); + store_le(out, A, B); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* * RC5 Decryption */ -void RC5::dec(const byte in[], byte out[]) const +void RC5::decrypt_n(const byte in[], byte out[], u32bit blocks) const { - u32bit A = load_le<u32bit>(in, 0), B = load_le<u32bit>(in, 1); - - for(u32bit j = ROUNDS; j != 0; j -= 4) + for(u32bit i = 0; i != blocks; ++i) { - B = rotate_right(B - S[2*j+1], A % 32) ^ A; - A = rotate_right(A - S[2*j ], B % 32) ^ B; - B = rotate_right(B - S[2*j-1], A % 32) ^ A; - A = rotate_right(A - S[2*j-2], B % 32) ^ B; - B = rotate_right(B - S[2*j-3], A % 32) ^ A; - A = rotate_right(A - S[2*j-4], B % 32) ^ B; - B = rotate_right(B - S[2*j-5], A % 32) ^ A; - A = rotate_right(A - S[2*j-6], B % 32) ^ B; - } - B -= S[1]; A -= S[0]; + u32bit A = load_le<u32bit>(in, 0), B = load_le<u32bit>(in, 1); + + for(u32bit j = ROUNDS; j != 0; j -= 4) + { + B = rotate_right(B - S[2*j+1], A % 32) ^ A; + A = rotate_right(A - S[2*j ], B % 32) ^ B; + B = rotate_right(B - S[2*j-1], A % 32) ^ A; + A = rotate_right(A - S[2*j-2], B % 32) ^ B; + B = rotate_right(B - S[2*j-3], A % 32) ^ A; + A = rotate_right(A - S[2*j-4], B % 32) ^ B; + B = rotate_right(B - S[2*j-5], A % 32) ^ A; + A = rotate_right(A - S[2*j-6], B % 32) ^ B; + } + B -= S[1]; A -= S[0]; - store_le(out, A, B); + store_le(out, A, B); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* diff --git a/src/block/rc5/rc5.h b/src/block/rc5/rc5.h index 083224720..82931c1d2 100644 --- a/src/block/rc5/rc5.h +++ b/src/block/rc5/rc5.h @@ -18,13 +18,15 @@ namespace Botan { class BOTAN_DLL RC5 : public BlockCipher { public: - void clear() throw() { S.clear(); } + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + + void clear() { S.clear(); } std::string name() const; BlockCipher* clone() const { return new RC5(ROUNDS); } + RC5(u32bit); private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; void key_schedule(const byte[], u32bit); SecureVector<u32bit> S; const u32bit ROUNDS; diff --git a/src/block/rc6/info.txt b/src/block/rc6/info.txt index 1457e78c1..fc7d2acb4 100644 --- a/src/block/rc6/info.txt +++ b/src/block/rc6/info.txt @@ -1,10 +1 @@ -realname "RC6" - define RC6 - -load_on auto - -<add> -rc6.cpp -rc6.h -</add> diff --git a/src/block/rc6/rc6.cpp b/src/block/rc6/rc6.cpp index 3b30ea93a..8bda62259 100644 --- a/src/block/rc6/rc6.cpp +++ b/src/block/rc6/rc6.cpp @@ -15,85 +15,97 @@ namespace Botan { /* * RC6 Encryption */ -void RC6::enc(const byte in[], byte out[]) const +void RC6::encrypt_n(const byte in[], byte out[], u32bit blocks) const { - u32bit A = load_le<u32bit>(in, 0); - u32bit B = load_le<u32bit>(in, 1); - u32bit C = load_le<u32bit>(in, 2); - u32bit D = load_le<u32bit>(in, 3); + for(u32bit i = 0; i != blocks; ++i) + { + u32bit A = load_le<u32bit>(in, 0); + u32bit B = load_le<u32bit>(in, 1); + u32bit C = load_le<u32bit>(in, 2); + u32bit D = load_le<u32bit>(in, 3); - B += S[0]; D += S[1]; + B += S[0]; D += S[1]; - for(u32bit j = 0; j != 20; j += 4) - { - u32bit T1, T2; - - T1 = rotate_left(B*(2*B+1), 5); - T2 = rotate_left(D*(2*D+1), 5); - A = rotate_left(A ^ T1, T2 % 32) + S[2*j+2]; - C = rotate_left(C ^ T2, T1 % 32) + S[2*j+3]; - - T1 = rotate_left(C*(2*C+1), 5); - T2 = rotate_left(A*(2*A+1), 5); - B = rotate_left(B ^ T1, T2 % 32) + S[2*j+4]; - D = rotate_left(D ^ T2, T1 % 32) + S[2*j+5]; - - T1 = rotate_left(D*(2*D+1), 5); - T2 = rotate_left(B*(2*B+1), 5); - C = rotate_left(C ^ T1, T2 % 32) + S[2*j+6]; - A = rotate_left(A ^ T2, T1 % 32) + S[2*j+7]; - - T1 = rotate_left(A*(2*A+1), 5); - T2 = rotate_left(C*(2*C+1), 5); - D = rotate_left(D ^ T1, T2 % 32) + S[2*j+8]; - B = rotate_left(B ^ T2, T1 % 32) + S[2*j+9]; - } + for(u32bit j = 0; j != 20; j += 4) + { + u32bit T1, T2; + + T1 = rotate_left(B*(2*B+1), 5); + T2 = rotate_left(D*(2*D+1), 5); + A = rotate_left(A ^ T1, T2 % 32) + S[2*j+2]; + C = rotate_left(C ^ T2, T1 % 32) + S[2*j+3]; + + T1 = rotate_left(C*(2*C+1), 5); + T2 = rotate_left(A*(2*A+1), 5); + B = rotate_left(B ^ T1, T2 % 32) + S[2*j+4]; + D = rotate_left(D ^ T2, T1 % 32) + S[2*j+5]; - A += S[42]; C += S[43]; + T1 = rotate_left(D*(2*D+1), 5); + T2 = rotate_left(B*(2*B+1), 5); + C = rotate_left(C ^ T1, T2 % 32) + S[2*j+6]; + A = rotate_left(A ^ T2, T1 % 32) + S[2*j+7]; - store_le(out, A, B, C, D); + T1 = rotate_left(A*(2*A+1), 5); + T2 = rotate_left(C*(2*C+1), 5); + D = rotate_left(D ^ T1, T2 % 32) + S[2*j+8]; + B = rotate_left(B ^ T2, T1 % 32) + S[2*j+9]; + } + + A += S[42]; C += S[43]; + + store_le(out, A, B, C, D); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* * RC6 Decryption */ -void RC6::dec(const byte in[], byte out[]) const +void RC6::decrypt_n(const byte in[], byte out[], u32bit blocks) const { - u32bit A = load_le<u32bit>(in, 0); - u32bit B = load_le<u32bit>(in, 1); - u32bit C = load_le<u32bit>(in, 2); - u32bit D = load_le<u32bit>(in, 3); + for(u32bit i = 0; i != blocks; ++i) + { + u32bit A = load_le<u32bit>(in, 0); + u32bit B = load_le<u32bit>(in, 1); + u32bit C = load_le<u32bit>(in, 2); + u32bit D = load_le<u32bit>(in, 3); - C -= S[43]; A -= S[42]; + C -= S[43]; A -= S[42]; - for(u32bit j = 0; j != 20; j += 4) - { - u32bit T1, T2; - - T1 = rotate_left(A*(2*A+1), 5); - T2 = rotate_left(C*(2*C+1), 5); - B = rotate_right(B - S[41 - 2*j], T1 % 32) ^ T2; - D = rotate_right(D - S[40 - 2*j], T2 % 32) ^ T1; - - T1 = rotate_left(D*(2*D+1), 5); - T2 = rotate_left(B*(2*B+1), 5); - A = rotate_right(A - S[39 - 2*j], T1 % 32) ^ T2; - C = rotate_right(C - S[38 - 2*j], T2 % 32) ^ T1; - - T1 = rotate_left(C*(2*C+1), 5); - T2 = rotate_left(A*(2*A+1), 5); - D = rotate_right(D - S[37 - 2*j], T1 % 32) ^ T2; - B = rotate_right(B - S[36 - 2*j], T2 % 32) ^ T1; - - T1 = rotate_left(B*(2*B+1), 5); - T2 = rotate_left(D*(2*D+1), 5); - C = rotate_right(C - S[35 - 2*j], T1 % 32) ^ T2; - A = rotate_right(A - S[34 - 2*j], T2 % 32) ^ T1; - } + for(u32bit j = 0; j != 20; j += 4) + { + u32bit T1, T2; + + T1 = rotate_left(A*(2*A+1), 5); + T2 = rotate_left(C*(2*C+1), 5); + B = rotate_right(B - S[41 - 2*j], T1 % 32) ^ T2; + D = rotate_right(D - S[40 - 2*j], T2 % 32) ^ T1; + + T1 = rotate_left(D*(2*D+1), 5); + T2 = rotate_left(B*(2*B+1), 5); + A = rotate_right(A - S[39 - 2*j], T1 % 32) ^ T2; + C = rotate_right(C - S[38 - 2*j], T2 % 32) ^ T1; - D -= S[1]; B -= S[0]; + T1 = rotate_left(C*(2*C+1), 5); + T2 = rotate_left(A*(2*A+1), 5); + D = rotate_right(D - S[37 - 2*j], T1 % 32) ^ T2; + B = rotate_right(B - S[36 - 2*j], T2 % 32) ^ T1; - store_le(out, A, B, C, D); + T1 = rotate_left(B*(2*B+1), 5); + T2 = rotate_left(D*(2*D+1), 5); + C = rotate_right(C - S[35 - 2*j], T1 % 32) ^ T2; + A = rotate_right(A - S[34 - 2*j], T2 % 32) ^ T1; + } + + D -= S[1]; B -= S[0]; + + store_le(out, A, B, C, D); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* diff --git a/src/block/rc6/rc6.h b/src/block/rc6/rc6.h index cb2800be7..6cd0f54db 100644 --- a/src/block/rc6/rc6.h +++ b/src/block/rc6/rc6.h @@ -18,13 +18,15 @@ namespace Botan { class BOTAN_DLL RC6 : public BlockCipher { public: - void clear() throw() { S.clear(); } + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + + void clear() { S.clear(); } std::string name() const { return "RC6"; } BlockCipher* clone() const { return new RC6; } + RC6() : BlockCipher(16, 1, 32) {} private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; void key_schedule(const byte[], u32bit); SecureBuffer<u32bit, 44> S; diff --git a/src/block/safer/info.txt b/src/block/safer/info.txt index 973cbff19..0ca49602d 100644 --- a/src/block/safer/info.txt +++ b/src/block/safer/info.txt @@ -1,11 +1 @@ -realname "SAFER" - define SAFER - -load_on auto - -<add> -safe_tab.cpp -safer_sk.cpp -safer_sk.h -</add> diff --git a/src/block/safer/safer_sk.cpp b/src/block/safer/safer_sk.cpp index f72c4773b..eb5c22fc9 100644 --- a/src/block/safer/safer_sk.cpp +++ b/src/block/safer/safer_sk.cpp @@ -1,6 +1,6 @@ /* * SAFER-SK -* (C) 1999-2007 Jack Lloyd +* (C) 1999-2009 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -15,54 +15,75 @@ namespace Botan { /* * SAFER-SK Encryption */ -void SAFER_SK::enc(const byte in[], byte out[]) const +void SAFER_SK::encrypt_n(const byte in[], byte out[], u32bit blocks) const { - byte A = in[0], B = in[1], C = in[2], D = in[3], - E = in[4], F = in[5], G = in[6], H = in[7], X, Y; - for(u32bit j = 0; j != 16*ROUNDS; j += 16) + for(u32bit i = 0; i != blocks; ++i) { - A = EXP[A ^ EK[j ]]; B = LOG[B + EK[j+1]]; - C = LOG[C + EK[j+2]]; D = EXP[D ^ EK[j+3]]; - E = EXP[E ^ EK[j+4]]; F = LOG[F + EK[j+5]]; - G = LOG[G + EK[j+6]]; H = EXP[H ^ EK[j+7]]; - A += EK[j+ 8]; B ^= EK[j+ 9]; C ^= EK[j+10]; D += EK[j+11]; - E += EK[j+12]; F ^= EK[j+13]; G ^= EK[j+14]; H += EK[j+15]; - B += A; D += C; F += E; H += G; A += B; C += D; E += F; G += H; - C += A; G += E; D += B; H += F; A += C; E += G; B += D; F += H; - H += D; Y = D + H; D = B + F; X = B + D; B = A + E; - A += B; F = C + G; E = C + F; C = X; G = Y; + byte A = in[0], B = in[1], C = in[2], D = in[3], + E = in[4], F = in[5], G = in[6], H = in[7], X, Y; + + for(u32bit j = 0; j != 16*ROUNDS; j += 16) + { + A = EXP[A ^ EK[j ]]; B = LOG[B + EK[j+1]]; + C = LOG[C + EK[j+2]]; D = EXP[D ^ EK[j+3]]; + E = EXP[E ^ EK[j+4]]; F = LOG[F + EK[j+5]]; + G = LOG[G + EK[j+6]]; H = EXP[H ^ EK[j+7]]; + + A += EK[j+ 8]; B ^= EK[j+ 9]; C ^= EK[j+10]; D += EK[j+11]; + E += EK[j+12]; F ^= EK[j+13]; G ^= EK[j+14]; H += EK[j+15]; + + B += A; D += C; F += E; H += G; A += B; C += D; E += F; G += H; + C += A; G += E; D += B; H += F; A += C; E += G; B += D; F += H; + H += D; Y = D + H; D = B + F; X = B + D; B = A + E; + A += B; F = C + G; E = C + F; C = X; G = Y; + } + + out[0] = A ^ EK[16*ROUNDS+0]; out[1] = B + EK[16*ROUNDS+1]; + out[2] = C + EK[16*ROUNDS+2]; out[3] = D ^ EK[16*ROUNDS+3]; + out[4] = E ^ EK[16*ROUNDS+4]; out[5] = F + EK[16*ROUNDS+5]; + out[6] = G + EK[16*ROUNDS+6]; out[7] = H ^ EK[16*ROUNDS+7]; + + in += BLOCK_SIZE; + out += BLOCK_SIZE; } - out[0] = A ^ EK[16*ROUNDS+0]; out[1] = B + EK[16*ROUNDS+1]; - out[2] = C + EK[16*ROUNDS+2]; out[3] = D ^ EK[16*ROUNDS+3]; - out[4] = E ^ EK[16*ROUNDS+4]; out[5] = F + EK[16*ROUNDS+5]; - out[6] = G + EK[16*ROUNDS+6]; out[7] = H ^ EK[16*ROUNDS+7]; } /* * SAFER-SK Decryption */ -void SAFER_SK::dec(const byte in[], byte out[]) const +void SAFER_SK::decrypt_n(const byte in[], byte out[], u32bit blocks) const { - byte A = in[0], B = in[1], C = in[2], D = in[3], - E = in[4], F = in[5], G = in[6], H = in[7]; - A ^= EK[16*ROUNDS+0]; B -= EK[16*ROUNDS+1]; C -= EK[16*ROUNDS+2]; - D ^= EK[16*ROUNDS+3]; E ^= EK[16*ROUNDS+4]; F -= EK[16*ROUNDS+5]; - G -= EK[16*ROUNDS+6]; H ^= EK[16*ROUNDS+7]; - for(s32bit j = 16*(ROUNDS-1); j >= 0; j -= 16) + for(u32bit i = 0; i != blocks; ++i) { - byte T = E; E = B; B = C; C = T; T = F; F = D; D = G; G = T; - A -= E; B -= F; C -= G; D -= H; E -= A; F -= B; G -= C; H -= D; - A -= C; E -= G; B -= D; F -= H; C -= A; G -= E; D -= B; H -= F; - A -= B; C -= D; E -= F; G -= H; B -= A; D -= C; F -= E; H -= G; - A = LOG[A - EK[j+8 ] + 256]; B = EXP[B ^ EK[j+9 ]]; - C = EXP[C ^ EK[j+10]]; D = LOG[D - EK[j+11] + 256]; - E = LOG[E - EK[j+12] + 256]; F = EXP[F ^ EK[j+13]]; - G = EXP[G ^ EK[j+14]]; H = LOG[H - EK[j+15] + 256]; - A ^= EK[j+0]; B -= EK[j+1]; C -= EK[j+2]; D ^= EK[j+3]; - E ^= EK[j+4]; F -= EK[j+5]; G -= EK[j+6]; H ^= EK[j+7]; + byte A = in[0], B = in[1], C = in[2], D = in[3], + E = in[4], F = in[5], G = in[6], H = in[7]; + + A ^= EK[16*ROUNDS+0]; B -= EK[16*ROUNDS+1]; C -= EK[16*ROUNDS+2]; + D ^= EK[16*ROUNDS+3]; E ^= EK[16*ROUNDS+4]; F -= EK[16*ROUNDS+5]; + G -= EK[16*ROUNDS+6]; H ^= EK[16*ROUNDS+7]; + + for(s32bit j = 16*(ROUNDS-1); j >= 0; j -= 16) + { + byte T = E; E = B; B = C; C = T; T = F; F = D; D = G; G = T; + A -= E; B -= F; C -= G; D -= H; E -= A; F -= B; G -= C; H -= D; + A -= C; E -= G; B -= D; F -= H; C -= A; G -= E; D -= B; H -= F; + A -= B; C -= D; E -= F; G -= H; B -= A; D -= C; F -= E; H -= G; + + A = LOG[A - EK[j+8 ] + 256]; B = EXP[B ^ EK[j+9 ]]; + C = EXP[C ^ EK[j+10]]; D = LOG[D - EK[j+11] + 256]; + E = LOG[E - EK[j+12] + 256]; F = EXP[F ^ EK[j+13]]; + G = EXP[G ^ EK[j+14]]; H = LOG[H - EK[j+15] + 256]; + + A ^= EK[j+0]; B -= EK[j+1]; C -= EK[j+2]; D ^= EK[j+3]; + E ^= EK[j+4]; F -= EK[j+5]; G -= EK[j+6]; H ^= EK[j+7]; + } + + out[0] = A; out[1] = B; out[2] = C; out[3] = D; + out[4] = E; out[5] = F; out[6] = G; out[7] = H; + + in += BLOCK_SIZE; + out += BLOCK_SIZE; } - out[0] = A; out[1] = B; out[2] = C; out[3] = D; - out[4] = E; out[5] = F; out[6] = G; out[7] = H; } /* diff --git a/src/block/safer/safer_sk.h b/src/block/safer/safer_sk.h index e52c5837c..80d2dc069 100644 --- a/src/block/safer/safer_sk.h +++ b/src/block/safer/safer_sk.h @@ -18,19 +18,22 @@ namespace Botan { class BOTAN_DLL SAFER_SK : public BlockCipher { public: - void clear() throw() { EK.clear(); } + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + + void clear() { EK.clear(); } std::string name() const; BlockCipher* clone() const; + SAFER_SK(u32bit); private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; void key_schedule(const byte[], u32bit); static const byte EXP[256]; static const byte LOG[512]; static const byte BIAS[208]; static const byte KEY_INDEX[208]; + SecureVector<byte> EK; const u32bit ROUNDS; }; diff --git a/src/block/seed/info.txt b/src/block/seed/info.txt index d04979335..96f4b75f2 100644 --- a/src/block/seed/info.txt +++ b/src/block/seed/info.txt @@ -1,11 +1 @@ -realname "SEED" - define SEED - -load_on auto - -<add> -seed.cpp -seed.h -seed_tab.cpp -</add> diff --git a/src/block/seed/seed.cpp b/src/block/seed/seed.cpp index b06a7cd77..378be16e4 100644 --- a/src/block/seed/seed.cpp +++ b/src/block/seed/seed.cpp @@ -22,69 +22,81 @@ u32bit SEED::G_FUNC::operator()(u32bit X) const /* * SEED Encryption */ -void SEED::enc(const byte in[], byte out[]) const +void SEED::encrypt_n(const byte in[], byte out[], u32bit blocks) const { - u32bit B0 = load_be<u32bit>(in, 0); - u32bit B1 = load_be<u32bit>(in, 1); - u32bit B2 = load_be<u32bit>(in, 2); - u32bit B3 = load_be<u32bit>(in, 3); - - G_FUNC G; - - for(u32bit j = 0; j != 16; j += 2) + for(u32bit i = 0; i != blocks; ++i) { - u32bit T0, T1; - - T0 = B2 ^ K[2*j]; - T1 = G(B2 ^ B3 ^ K[2*j+1]); - T0 = G(T1 + T0); - T1 = G(T1 + T0); - B1 ^= T1; - B0 ^= T0 + T1; - - T0 = B0 ^ K[2*j+2]; - T1 = G(B0 ^ B1 ^ K[2*j+3]); - T0 = G(T1 + T0); - T1 = G(T1 + T0); - B3 ^= T1; - B2 ^= T0 + T1; + u32bit B0 = load_be<u32bit>(in, 0); + u32bit B1 = load_be<u32bit>(in, 1); + u32bit B2 = load_be<u32bit>(in, 2); + u32bit B3 = load_be<u32bit>(in, 3); + + G_FUNC G; + + for(u32bit j = 0; j != 16; j += 2) + { + u32bit T0, T1; + + T0 = B2 ^ K[2*j]; + T1 = G(B2 ^ B3 ^ K[2*j+1]); + T0 = G(T1 + T0); + T1 = G(T1 + T0); + B1 ^= T1; + B0 ^= T0 + T1; + + T0 = B0 ^ K[2*j+2]; + T1 = G(B0 ^ B1 ^ K[2*j+3]); + T0 = G(T1 + T0); + T1 = G(T1 + T0); + B3 ^= T1; + B2 ^= T0 + T1; + } + + store_be(out, B2, B3, B0, B1); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; } - - store_be(out, B2, B3, B0, B1); } /* * SEED Decryption */ -void SEED::dec(const byte in[], byte out[]) const +void SEED::decrypt_n(const byte in[], byte out[], u32bit blocks) const { - u32bit B0 = load_be<u32bit>(in, 0); - u32bit B1 = load_be<u32bit>(in, 1); - u32bit B2 = load_be<u32bit>(in, 2); - u32bit B3 = load_be<u32bit>(in, 3); - - G_FUNC G; - - for(u32bit j = 0; j != 16; j += 2) + for(u32bit i = 0; i != blocks; ++i) { - u32bit T0, T1; - - T0 = B2 ^ K[30-2*j]; - T1 = G(B2 ^ B3 ^ K[31-2*j]); - T0 = G(T1 + T0); - T1 = G(T1 + T0); - B1 ^= T1; - B0 ^= T0 + T1; - - T0 = B0 ^ K[28-2*j]; - T1 = G(B0 ^ B1 ^ K[29-2*j]); - T0 = G(T1 + T0); - T1 = G(T1 + T0); - B3 ^= T1; - B2 ^= T0 + T1; + u32bit B0 = load_be<u32bit>(in, 0); + u32bit B1 = load_be<u32bit>(in, 1); + u32bit B2 = load_be<u32bit>(in, 2); + u32bit B3 = load_be<u32bit>(in, 3); + + G_FUNC G; + + for(u32bit j = 0; j != 16; j += 2) + { + u32bit T0, T1; + + T0 = B2 ^ K[30-2*j]; + T1 = G(B2 ^ B3 ^ K[31-2*j]); + T0 = G(T1 + T0); + T1 = G(T1 + T0); + B1 ^= T1; + B0 ^= T0 + T1; + + T0 = B0 ^ K[28-2*j]; + T1 = G(B0 ^ B1 ^ K[29-2*j]); + T0 = G(T1 + T0); + T1 = G(T1 + T0); + B3 ^= T1; + B2 ^= T0 + T1; + } + + store_be(out, B2, B3, B0, B1); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; } - - store_be(out, B2, B3, B0, B1); } /* diff --git a/src/block/seed/seed.h b/src/block/seed/seed.h index 54c25d580..5a4b44057 100644 --- a/src/block/seed/seed.h +++ b/src/block/seed/seed.h @@ -18,13 +18,15 @@ namespace Botan { class BOTAN_DLL SEED : public BlockCipher { public: - void clear() throw() { K.clear(); } + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + + void clear() { K.clear(); } std::string name() const { return "SEED"; } BlockCipher* clone() const { return new SEED; } + SEED() : BlockCipher(16, 16) {} private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; void key_schedule(const byte[], u32bit); class G_FUNC diff --git a/src/block/serpent/info.txt b/src/block/serpent/info.txt index baaccbf01..5fcc14f74 100644 --- a/src/block/serpent/info.txt +++ b/src/block/serpent/info.txt @@ -1,10 +1 @@ -realname "Serpent" - define SERPENT - -load_on auto - -<add> -serpent.cpp -serpent.h -</add> diff --git a/src/block/serpent/serpent.cpp b/src/block/serpent/serpent.cpp index df7592fea..2fa27308f 100644 --- a/src/block/serpent/serpent.cpp +++ b/src/block/serpent/serpent.cpp @@ -243,93 +243,105 @@ inline void i_transform(u32bit& B0, u32bit& B1, u32bit& B2, u32bit& B3) /* * Serpent Encryption */ -void Serpent::enc(const byte in[], byte out[]) const +void Serpent::encrypt_n(const byte in[], byte out[], u32bit blocks) const { - u32bit B0 = load_le<u32bit>(in, 0); - u32bit B1 = load_le<u32bit>(in, 1); - u32bit B2 = load_le<u32bit>(in, 2); - u32bit B3 = load_le<u32bit>(in, 3); - - key_xor( 0,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor( 1,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor( 2,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor( 3,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor( 4,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor( 5,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor( 6,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor( 7,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor( 8,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor( 9,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(10,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(11,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(12,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(13,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(14,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(15,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(16,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(17,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(18,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(19,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(20,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(21,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(22,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(23,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(24,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(25,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(26,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(27,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(28,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(29,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(30,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3); - key_xor(31,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); key_xor(32,B0,B1,B2,B3); - - store_le(out, B0, B1, B2, B3); + for(u32bit i = 0; i != blocks; ++i) + { + u32bit B0 = load_le<u32bit>(in, 0); + u32bit B1 = load_le<u32bit>(in, 1); + u32bit B2 = load_le<u32bit>(in, 2); + u32bit B3 = load_le<u32bit>(in, 3); + + key_xor( 0,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor( 1,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor( 2,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor( 3,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor( 4,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor( 5,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor( 6,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor( 7,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor( 8,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor( 9,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(10,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(11,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(12,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(13,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(14,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(15,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(16,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(17,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(18,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(19,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(20,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(21,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(22,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(23,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(24,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(25,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(26,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(27,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(28,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(29,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(30,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(31,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); key_xor(32,B0,B1,B2,B3); + + store_le(out, B0, B1, B2, B3); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* * Serpent Decryption */ -void Serpent::dec(const byte in[], byte out[]) const +void Serpent::decrypt_n(const byte in[], byte out[], u32bit blocks) const { - u32bit B0 = load_le<u32bit>(in, 0); - u32bit B1 = load_le<u32bit>(in, 1); - u32bit B2 = load_le<u32bit>(in, 2); - u32bit B3 = load_le<u32bit>(in, 3); - - key_xor(32,B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor(31,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(30,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(29,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(28,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(27,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(26,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor(25,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor(24,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor(23,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(22,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(21,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(20,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(19,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(18,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor(17,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor(16,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor(15,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(14,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(13,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(12,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(11,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(10,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor( 9,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor( 8,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor( 7,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor( 6,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor( 5,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor( 4,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor( 3,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor( 2,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor( 1,B0,B1,B2,B3); - i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor( 0,B0,B1,B2,B3); - - store_le(out, B0, B1, B2, B3); + for(u32bit i = 0; i != blocks; ++i) + { + u32bit B0 = load_le<u32bit>(in, 0); + u32bit B1 = load_le<u32bit>(in, 1); + u32bit B2 = load_le<u32bit>(in, 2); + u32bit B3 = load_le<u32bit>(in, 3); + + key_xor(32,B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor(31,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(30,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(29,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(28,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(27,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(26,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor(25,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor(24,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor(23,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(22,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(21,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(20,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(19,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(18,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor(17,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor(16,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor(15,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(14,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(13,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(12,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(11,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(10,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor( 9,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor( 8,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor( 7,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor( 6,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor( 5,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor( 4,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor( 3,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor( 2,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor( 1,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor( 0,B0,B1,B2,B3); + + store_le(out, B0, B1, B2, B3); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* diff --git a/src/block/serpent/serpent.h b/src/block/serpent/serpent.h index 5b9be257f..4fa7451b9 100644 --- a/src/block/serpent/serpent.h +++ b/src/block/serpent/serpent.h @@ -18,13 +18,14 @@ namespace Botan { class BOTAN_DLL Serpent : public BlockCipher { public: - void clear() throw() { round_key.clear(); } + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + + void clear() { round_key.clear(); } std::string name() const { return "Serpent"; } BlockCipher* clone() const { return new Serpent; } Serpent() : BlockCipher(16, 16, 32, 8) {} protected: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; void key_schedule(const byte[], u32bit); SecureBuffer<u32bit, 132> round_key; diff --git a/src/block/serpent_ia32/info.txt b/src/block/serpent_ia32/info.txt index ea0506299..fa6d9b9d9 100644 --- a/src/block/serpent_ia32/info.txt +++ b/src/block/serpent_ia32/info.txt @@ -1,15 +1,7 @@ -realname "Serpent (IA-32)" - define SERPENT_IA32 load_on asm_ok -<add> -serp_ia32_imp.S -serp_ia32.cpp -serp_ia32.h -</add> - <arch> ia32 </arch> diff --git a/src/block/serpent_ia32/serp_ia32.cpp b/src/block/serpent_ia32/serp_ia32.cpp index 37dd4e637..721584b18 100644 --- a/src/block/serpent_ia32/serp_ia32.cpp +++ b/src/block/serpent_ia32/serp_ia32.cpp @@ -21,17 +21,27 @@ void botan_serpent_ia32_key_schedule(u32bit[140]); /* * Serpent Encryption */ -void Serpent_IA32::enc(const byte in[], byte out[]) const +void Serpent_IA32::encrypt_n(const byte in[], byte out[], u32bit blocks) const { - botan_serpent_ia32_encrypt(in, out, round_key); + for(u32bit i = 0; i != blocks; ++i) + { + botan_serpent_ia32_encrypt(in, out, round_key); + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* * Serpent Decryption */ -void Serpent_IA32::dec(const byte in[], byte out[]) const +void Serpent_IA32::decrypt_n(const byte in[], byte out[], u32bit blocks) const { - botan_serpent_ia32_decrypt(in, out, round_key); + for(u32bit i = 0; i != blocks; ++i) + { + botan_serpent_ia32_decrypt(in, out, round_key); + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* @@ -41,7 +51,7 @@ void Serpent_IA32::key_schedule(const byte key[], u32bit length) { SecureBuffer<u32bit, 140> W; for(u32bit j = 0; j != length / 4; ++j) - W[j] = make_u32bit(key[4*j+3], key[4*j+2], key[4*j+1], key[4*j]); + W[j] = load_le<u32bit>(key, j); W[length / 4] |= u32bit(1) << ((length%4)*8); botan_serpent_ia32_key_schedule(W); diff --git a/src/block/serpent_ia32/serp_ia32.h b/src/block/serpent_ia32/serp_ia32.h index 565e9889d..dc6beaf13 100644 --- a/src/block/serpent_ia32/serp_ia32.h +++ b/src/block/serpent_ia32/serp_ia32.h @@ -18,10 +18,11 @@ namespace Botan { class BOTAN_DLL Serpent_IA32 : public Serpent { public: + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + BlockCipher* clone() const { return new Serpent_IA32; } private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; void key_schedule(const byte[], u32bit); }; diff --git a/src/block/serpent_simd/info.txt b/src/block/serpent_simd/info.txt new file mode 100644 index 000000000..d65b41235 --- /dev/null +++ b/src/block/serpent_simd/info.txt @@ -0,0 +1,7 @@ +define SERPENT_SIMD + +<requires> +serpent +simd_32 +simd_engine +</requires> diff --git a/src/block/serpent_simd/serp_simd.cpp b/src/block/serpent_simd/serp_simd.cpp new file mode 100644 index 000000000..b394b0c26 --- /dev/null +++ b/src/block/serpent_simd/serp_simd.cpp @@ -0,0 +1,206 @@ +/* +* Serpent (SIMD) +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/serp_simd.h> +#include <botan/serp_simd_sbox.h> +#include <botan/simd_32.h> +#include <botan/loadstor.h> + +namespace Botan { + +namespace { + +#define key_xor(round, B0, B1, B2, B3) \ + do { \ + B0 ^= SIMD_32(keys[4*round ]); \ + B1 ^= SIMD_32(keys[4*round+1]); \ + B2 ^= SIMD_32(keys[4*round+2]); \ + B3 ^= SIMD_32(keys[4*round+3]); \ + } while(0); + +/* +* Serpent's linear transformations +*/ +#define transform(B0, B1, B2, B3) \ + do { \ + B0.rotate_left(13); \ + B2.rotate_left(3); \ + B1 ^= B0 ^ B2; \ + B3 ^= B2 ^ (B0 << 3); \ + B1.rotate_left(1); \ + B3.rotate_left(7); \ + B0 ^= B1 ^ B3; \ + B2 ^= B3 ^ (B1 << 7); \ + B0.rotate_left(5); \ + B2.rotate_left(22); \ + } while(0); + +#define i_transform(B0, B1, B2, B3) \ + do { \ + B2.rotate_right(22); \ + B0.rotate_right(5); \ + B2 ^= B3 ^ (B1 << 7); \ + B0 ^= B1 ^ B3; \ + B3.rotate_right(7); \ + B1.rotate_right(1); \ + B3 ^= B2 ^ (B0 << 3); \ + B1 ^= B0 ^ B2; \ + B2.rotate_right(3); \ + B0.rotate_right(13); \ + } while(0); + +/* +* SIMD Serpent Encryption of 4 blocks in parallel +*/ +void serpent_encrypt_4(const byte in[64], + byte out[64], + const u32bit keys[132]) + { + SIMD_32 B0 = SIMD_32::load_le(in); + SIMD_32 B1 = SIMD_32::load_le(in + 16); + SIMD_32 B2 = SIMD_32::load_le(in + 32); + SIMD_32 B3 = SIMD_32::load_le(in + 48); + + SIMD_32::transpose(B0, B1, B2, B3); + + key_xor( 0,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor( 1,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor( 2,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor( 3,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor( 4,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor( 5,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor( 6,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor( 7,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); transform(B0,B1,B2,B3); + + key_xor( 8,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor( 9,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(10,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(11,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(12,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(13,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(14,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(15,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); transform(B0,B1,B2,B3); + + key_xor(16,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(17,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(18,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(19,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(20,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(21,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(22,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(23,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); transform(B0,B1,B2,B3); + + key_xor(24,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(25,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(26,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(27,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(28,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(29,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(30,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3); + key_xor(31,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); key_xor(32,B0,B1,B2,B3); + + SIMD_32::transpose(B0, B1, B2, B3); + + B0.store_le(out); + B1.store_le(out + 16); + B2.store_le(out + 32); + B3.store_le(out + 48); + } + +/* +* SIMD Serpent Decryption of 4 blocks in parallel +*/ +void serpent_decrypt_4(const byte in[64], + byte out[64], + const u32bit keys[132]) + { + SIMD_32 B0 = SIMD_32::load_le(in); + SIMD_32 B1 = SIMD_32::load_le(in + 16); + SIMD_32 B2 = SIMD_32::load_le(in + 32); + SIMD_32 B3 = SIMD_32::load_le(in + 48); + + SIMD_32::transpose(B0, B1, B2, B3); + + key_xor(32,B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor(31,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(30,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(29,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(28,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(27,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(26,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor(25,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor(24,B0,B1,B2,B3); + + i_transform(B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor(23,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(22,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(21,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(20,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(19,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(18,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor(17,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor(16,B0,B1,B2,B3); + + i_transform(B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor(15,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(14,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(13,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(12,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(11,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(10,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor( 9,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor( 8,B0,B1,B2,B3); + + i_transform(B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor( 7,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor( 6,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor( 5,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor( 4,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor( 3,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor( 2,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor( 1,B0,B1,B2,B3); + i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor( 0,B0,B1,B2,B3); + + SIMD_32::transpose(B0, B1, B2, B3); + + B0.store_le(out); + B1.store_le(out + 16); + B2.store_le(out + 32); + B3.store_le(out + 48); + } + +} + +/* +* Serpent Encryption +*/ +void Serpent_SIMD::encrypt_n(const byte in[], byte out[], u32bit blocks) const + { + while(blocks >= 4) + { + serpent_encrypt_4(in, out, this->round_key); + in += 4 * BLOCK_SIZE; + out += 4 * BLOCK_SIZE; + blocks -= 4; + } + + Serpent::encrypt_n(in, out, blocks); + } + +/* +* Serpent Decryption +*/ +void Serpent_SIMD::decrypt_n(const byte in[], byte out[], u32bit blocks) const + { + while(blocks >= 4) + { + serpent_decrypt_4(in, out, this->round_key); + in += 4 * BLOCK_SIZE; + out += 4 * BLOCK_SIZE; + blocks -= 4; + } + + Serpent::decrypt_n(in, out, blocks); + } + +} diff --git a/src/block/serpent_simd/serp_simd.h b/src/block/serpent_simd/serp_simd.h new file mode 100644 index 000000000..1ecb70159 --- /dev/null +++ b/src/block/serpent_simd/serp_simd.h @@ -0,0 +1,29 @@ +/* +* Serpent (SIMD) +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_SERPENT_SIMD_H__ +#define BOTAN_SERPENT_SIMD_H__ + +#include <botan/serpent.h> + +namespace Botan { + +/* +* Serpent +*/ +class BOTAN_DLL Serpent_SIMD : public Serpent + { + public: + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + + BlockCipher* clone() const { return new Serpent_SIMD; } + }; + +} + +#endif diff --git a/src/block/serpent_simd/serp_simd_sbox.h b/src/block/serpent_simd/serp_simd_sbox.h new file mode 100644 index 000000000..6e3da7359 --- /dev/null +++ b/src/block/serpent_simd/serp_simd_sbox.h @@ -0,0 +1,426 @@ +/* +* Serpent Sboxes in SIMD form +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef SERPENT_SIMD_SBOXES_H__ +#define SERPENT_SIMD_SBOXES_H__ + +#define SBoxE1(B0, B1, B2, B3) \ + do { \ + B3 ^= B0; \ + SIMD_32 B4 = B1; \ + B1 &= B3; \ + B4 ^= B2; \ + B1 ^= B0; \ + B0 |= B3; \ + B0 ^= B4; \ + B4 ^= B3; \ + B3 ^= B2; \ + B2 |= B1; \ + B2 ^= B4; \ + B4 = ~B4; \ + B4 |= B1; \ + B1 ^= B3; \ + B1 ^= B4; \ + B3 |= B0; \ + B1 ^= B3; \ + B4 ^= B3; \ + B3 = B0; \ + B0 = B1; \ + B1 = B4; \ + } while(0); + +#define SBoxE2(B0, B1, B2, B3) \ + do { \ + B0 = ~B0; \ + B2 = ~B2; \ + SIMD_32 B4 = B0; \ + B0 &= B1; \ + B2 ^= B0; \ + B0 |= B3; \ + B3 ^= B2; \ + B1 ^= B0; \ + B0 ^= B4; \ + B4 |= B1; \ + B1 ^= B3; \ + B2 |= B0; \ + B2 &= B4; \ + B0 ^= B1; \ + B1 &= B2; \ + B1 ^= B0; \ + B0 &= B2; \ + B4 ^= B0; \ + B0 = B2; \ + B2 = B3; \ + B3 = B1; \ + B1 = B4; \ + } while(0); + +#define SBoxE3(B0, B1, B2, B3) \ + do { \ + SIMD_32 B4 = B0; \ + B0 &= B2; \ + B0 ^= B3; \ + B2 ^= B1; \ + B2 ^= B0; \ + B3 |= B4; \ + B3 ^= B1; \ + B4 ^= B2; \ + B1 = B3; \ + B3 |= B4; \ + B3 ^= B0; \ + B0 &= B1; \ + B4 ^= B0; \ + B1 ^= B3; \ + B1 ^= B4; \ + B4 = ~B4; \ + B0 = B2; \ + B2 = B1; \ + B1 = B3; \ + B3 = B4; \ + } while(0); + +#define SBoxE4(B0, B1, B2, B3) \ + do { \ + SIMD_32 B4 = B0; \ + B0 |= B3; \ + B3 ^= B1; \ + B1 &= B4; \ + B4 ^= B2; \ + B2 ^= B3; \ + B3 &= B0; \ + B4 |= B1; \ + B3 ^= B4; \ + B0 ^= B1; \ + B4 &= B0; \ + B1 ^= B3; \ + B4 ^= B2; \ + B1 |= B0; \ + B1 ^= B2; \ + B0 ^= B3; \ + B2 = B1; \ + B1 |= B3; \ + B0 ^= B1; \ + B1 = B2; \ + B2 = B3; \ + B3 = B4; \ + } while(0); + +#define SBoxE5(B0, B1, B2, B3) \ + do { \ + B1 ^= B3; \ + B3 = ~B3; \ + B2 ^= B3; \ + B3 ^= B0; \ + SIMD_32 B4 = B1; \ + B1 &= B3; \ + B1 ^= B2; \ + B4 ^= B3; \ + B0 ^= B4; \ + B2 &= B4; \ + B2 ^= B0; \ + B0 &= B1; \ + B3 ^= B0; \ + B4 |= B1; \ + B4 ^= B0; \ + B0 |= B3; \ + B0 ^= B2; \ + B2 &= B3; \ + B0 = ~B0; \ + B4 ^= B2; \ + B2 = B0; \ + B0 = B1; \ + B1 = B4; \ + } while(0); + +#define SBoxE6(B0, B1, B2, B3) \ + do { \ + B0 ^= B1; \ + B1 ^= B3; \ + B3 = ~B3; \ + SIMD_32 B4 = B1; \ + B1 &= B0; \ + B2 ^= B3; \ + B1 ^= B2; \ + B2 |= B4; \ + B4 ^= B3; \ + B3 &= B1; \ + B3 ^= B0; \ + B4 ^= B1; \ + B4 ^= B2; \ + B2 ^= B0; \ + B0 &= B3; \ + B2 = ~B2; \ + B0 ^= B4; \ + B4 |= B3; \ + B4 ^= B2; \ + B2 = B0; \ + B0 = B1; \ + B1 = B3; \ + B3 = B4; \ + } while(0); + +#define SBoxE7(B0, B1, B2, B3) \ + do { \ + B2 = ~B2; \ + SIMD_32 B4 = B3; \ + B3 &= B0; \ + B0 ^= B4; \ + B3 ^= B2; \ + B2 |= B4; \ + B1 ^= B3; \ + B2 ^= B0; \ + B0 |= B1; \ + B2 ^= B1; \ + B4 ^= B0; \ + B0 |= B3; \ + B0 ^= B2; \ + B4 ^= B3; \ + B4 ^= B0; \ + B3 = ~B3; \ + B2 &= B4; \ + B3 ^= B2; \ + B2 = B4; \ + } while(0); + +#define SBoxE8(B0, B1, B2, B3) \ + do { \ + SIMD_32 B4 = B1; \ + B1 |= B2; \ + B1 ^= B3; \ + B4 ^= B2; \ + B2 ^= B1; \ + B3 |= B4; \ + B3 &= B0; \ + B4 ^= B2; \ + B3 ^= B1; \ + B1 |= B4; \ + B1 ^= B0; \ + B0 |= B4; \ + B0 ^= B2; \ + B1 ^= B4; \ + B2 ^= B1; \ + B1 &= B0; \ + B1 ^= B4; \ + B2 = ~B2; \ + B2 |= B0; \ + B4 ^= B2; \ + B2 = B1; \ + B1 = B3; \ + B3 = B0; \ + B0 = B4; \ + } while(0); + +#define SBoxD1(B0, B1, B2, B3) \ + do { \ + B2 = ~B2; \ + SIMD_32 B4 = B1; \ + B1 |= B0; \ + B4 = ~B4; \ + B1 ^= B2; \ + B2 |= B4; \ + B1 ^= B3; \ + B0 ^= B4; \ + B2 ^= B0; \ + B0 &= B3; \ + B4 ^= B0; \ + B0 |= B1; \ + B0 ^= B2; \ + B3 ^= B4; \ + B2 ^= B1; \ + B3 ^= B0; \ + B3 ^= B1; \ + B2 &= B3; \ + B4 ^= B2; \ + B2 = B1; \ + B1 = B4; \ + } while(0); + +#define SBoxD2(B0, B1, B2, B3) \ + do { \ + SIMD_32 B4 = B1; \ + B1 ^= B3; \ + B3 &= B1; \ + B4 ^= B2; \ + B3 ^= B0; \ + B0 |= B1; \ + B2 ^= B3; \ + B0 ^= B4; \ + B0 |= B2; \ + B1 ^= B3; \ + B0 ^= B1; \ + B1 |= B3; \ + B1 ^= B0; \ + B4 = ~B4; \ + B4 ^= B1; \ + B1 |= B0; \ + B1 ^= B0; \ + B1 |= B4; \ + B3 ^= B1; \ + B1 = B0; \ + B0 = B4; \ + B4 = B2; \ + B2 = B3; \ + B3 = B4; \ + } while(0); + +#define SBoxD3(B0, B1, B2, B3) \ + do { \ + B2 ^= B3; \ + B3 ^= B0; \ + SIMD_32 B4 = B3; \ + B3 &= B2; \ + B3 ^= B1; \ + B1 |= B2; \ + B1 ^= B4; \ + B4 &= B3; \ + B2 ^= B3; \ + B4 &= B0; \ + B4 ^= B2; \ + B2 &= B1; \ + B2 |= B0; \ + B3 = ~B3; \ + B2 ^= B3; \ + B0 ^= B3; \ + B0 &= B1; \ + B3 ^= B4; \ + B3 ^= B0; \ + B0 = B1; \ + B1 = B4; \ + } while(0); + +#define SBoxD4(B0, B1, B2, B3) \ + do { \ + SIMD_32 B4 = B2; \ + B2 ^= B1; \ + B0 ^= B2; \ + B4 &= B2; \ + B4 ^= B0; \ + B0 &= B1; \ + B1 ^= B3; \ + B3 |= B4; \ + B2 ^= B3; \ + B0 ^= B3; \ + B1 ^= B4; \ + B3 &= B2; \ + B3 ^= B1; \ + B1 ^= B0; \ + B1 |= B2; \ + B0 ^= B3; \ + B1 ^= B4; \ + B0 ^= B1; \ + B4 = B0; \ + B0 = B2; \ + B2 = B3; \ + B3 = B4; \ + } while(0); + +#define SBoxD5(B0, B1, B2, B3) \ + do { \ + SIMD_32 B4 = B2; \ + B2 &= B3; \ + B2 ^= B1; \ + B1 |= B3; \ + B1 &= B0; \ + B4 ^= B2; \ + B4 ^= B1; \ + B1 &= B2; \ + B0 = ~B0; \ + B3 ^= B4; \ + B1 ^= B3; \ + B3 &= B0; \ + B3 ^= B2; \ + B0 ^= B1; \ + B2 &= B0; \ + B3 ^= B0; \ + B2 ^= B4; \ + B2 |= B3; \ + B3 ^= B0; \ + B2 ^= B1; \ + B1 = B3; \ + B3 = B4; \ + } while(0); + +#define SBoxD6(B0, B1, B2, B3) \ + do { \ + B1 = ~B1; \ + SIMD_32 B4 = B3; \ + B2 ^= B1; \ + B3 |= B0; \ + B3 ^= B2; \ + B2 |= B1; \ + B2 &= B0; \ + B4 ^= B3; \ + B2 ^= B4; \ + B4 |= B0; \ + B4 ^= B1; \ + B1 &= B2; \ + B1 ^= B3; \ + B4 ^= B2; \ + B3 &= B4; \ + B4 ^= B1; \ + B3 ^= B4; \ + B4 = ~B4; \ + B3 ^= B0; \ + B0 = B1; \ + B1 = B4; \ + B4 = B3; \ + B3 = B2; \ + B2 = B4; \ + } while(0); + +#define SBoxD7(B0, B1, B2, B3) \ + do { \ + B0 ^= B2; \ + SIMD_32 B4 = B2; \ + B2 &= B0; \ + B4 ^= B3; \ + B2 = ~B2; \ + B3 ^= B1; \ + B2 ^= B3; \ + B4 |= B0; \ + B0 ^= B2; \ + B3 ^= B4; \ + B4 ^= B1; \ + B1 &= B3; \ + B1 ^= B0; \ + B0 ^= B3; \ + B0 |= B2; \ + B3 ^= B1; \ + B4 ^= B0; \ + B0 = B1; \ + B1 = B2; \ + B2 = B4; \ + } while(0); + +#define SBoxD8(B0, B1, B2, B3) \ + do { \ + SIMD_32 B4 = B2; \ + B2 ^= B0; \ + B0 &= B3; \ + B4 |= B3; \ + B2 = ~B2; \ + B3 ^= B1; \ + B1 |= B0; \ + B0 ^= B2; \ + B2 &= B4; \ + B3 &= B4; \ + B1 ^= B2; \ + B2 ^= B0; \ + B0 |= B2; \ + B4 ^= B1; \ + B0 ^= B3; \ + B3 ^= B4; \ + B4 |= B0; \ + B3 ^= B2; \ + B4 ^= B2; \ + B2 = B1; \ + B1 = B0; \ + B0 = B3; \ + B3 = B4; \ + } while(0); + +#endif diff --git a/src/block/skipjack/info.txt b/src/block/skipjack/info.txt index 4b38d6d28..7dfffda4e 100644 --- a/src/block/skipjack/info.txt +++ b/src/block/skipjack/info.txt @@ -1,10 +1 @@ -realname "Skipjack" - define SKIPJACK - -load_on auto - -<add> -skipjack.cpp -skipjack.h -</add> diff --git a/src/block/skipjack/skipjack.cpp b/src/block/skipjack/skipjack.cpp index f5ffc861e..e8b2cfb8d 100644 --- a/src/block/skipjack/skipjack.cpp +++ b/src/block/skipjack/skipjack.cpp @@ -13,51 +13,63 @@ namespace Botan { /* * Skipjack Encryption */ -void Skipjack::enc(const byte in[], byte out[]) const +void Skipjack::encrypt_n(const byte in[], byte out[], u32bit blocks) const { - u16bit W1 = load_le<u16bit>(in, 3); - u16bit W2 = load_le<u16bit>(in, 2); - u16bit W3 = load_le<u16bit>(in, 1); - u16bit W4 = load_le<u16bit>(in, 0); + for(u32bit i = 0; i != blocks; ++i) + { + u16bit W1 = load_le<u16bit>(in, 3); + u16bit W2 = load_le<u16bit>(in, 2); + u16bit W3 = load_le<u16bit>(in, 1); + u16bit W4 = load_le<u16bit>(in, 0); - step_A(W1,W4, 1); step_A(W4,W3, 2); step_A(W3,W2, 3); step_A(W2,W1, 4); - step_A(W1,W4, 5); step_A(W4,W3, 6); step_A(W3,W2, 7); step_A(W2,W1, 8); + step_A(W1,W4, 1); step_A(W4,W3, 2); step_A(W3,W2, 3); step_A(W2,W1, 4); + step_A(W1,W4, 5); step_A(W4,W3, 6); step_A(W3,W2, 7); step_A(W2,W1, 8); - step_B(W1,W2, 9); step_B(W4,W1,10); step_B(W3,W4,11); step_B(W2,W3,12); - step_B(W1,W2,13); step_B(W4,W1,14); step_B(W3,W4,15); step_B(W2,W3,16); + step_B(W1,W2, 9); step_B(W4,W1,10); step_B(W3,W4,11); step_B(W2,W3,12); + step_B(W1,W2,13); step_B(W4,W1,14); step_B(W3,W4,15); step_B(W2,W3,16); - step_A(W1,W4,17); step_A(W4,W3,18); step_A(W3,W2,19); step_A(W2,W1,20); - step_A(W1,W4,21); step_A(W4,W3,22); step_A(W3,W2,23); step_A(W2,W1,24); + step_A(W1,W4,17); step_A(W4,W3,18); step_A(W3,W2,19); step_A(W2,W1,20); + step_A(W1,W4,21); step_A(W4,W3,22); step_A(W3,W2,23); step_A(W2,W1,24); - step_B(W1,W2,25); step_B(W4,W1,26); step_B(W3,W4,27); step_B(W2,W3,28); - step_B(W1,W2,29); step_B(W4,W1,30); step_B(W3,W4,31); step_B(W2,W3,32); + step_B(W1,W2,25); step_B(W4,W1,26); step_B(W3,W4,27); step_B(W2,W3,28); + step_B(W1,W2,29); step_B(W4,W1,30); step_B(W3,W4,31); step_B(W2,W3,32); - store_le(out, W4, W3, W2, W1); + store_le(out, W4, W3, W2, W1); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* * Skipjack Decryption */ -void Skipjack::dec(const byte in[], byte out[]) const +void Skipjack::decrypt_n(const byte in[], byte out[], u32bit blocks) const { - u16bit W1 = load_le<u16bit>(in, 3); - u16bit W2 = load_le<u16bit>(in, 2); - u16bit W3 = load_le<u16bit>(in, 1); - u16bit W4 = load_le<u16bit>(in, 0); + for(u32bit i = 0; i != blocks; ++i) + { + u16bit W1 = load_le<u16bit>(in, 3); + u16bit W2 = load_le<u16bit>(in, 2); + u16bit W3 = load_le<u16bit>(in, 1); + u16bit W4 = load_le<u16bit>(in, 0); + + step_Bi(W2,W3,32); step_Bi(W3,W4,31); step_Bi(W4,W1,30); step_Bi(W1,W2,29); + step_Bi(W2,W3,28); step_Bi(W3,W4,27); step_Bi(W4,W1,26); step_Bi(W1,W2,25); - step_Bi(W2,W3,32); step_Bi(W3,W4,31); step_Bi(W4,W1,30); step_Bi(W1,W2,29); - step_Bi(W2,W3,28); step_Bi(W3,W4,27); step_Bi(W4,W1,26); step_Bi(W1,W2,25); + step_Ai(W1,W2,24); step_Ai(W2,W3,23); step_Ai(W3,W4,22); step_Ai(W4,W1,21); + step_Ai(W1,W2,20); step_Ai(W2,W3,19); step_Ai(W3,W4,18); step_Ai(W4,W1,17); - step_Ai(W1,W2,24); step_Ai(W2,W3,23); step_Ai(W3,W4,22); step_Ai(W4,W1,21); - step_Ai(W1,W2,20); step_Ai(W2,W3,19); step_Ai(W3,W4,18); step_Ai(W4,W1,17); + step_Bi(W2,W3,16); step_Bi(W3,W4,15); step_Bi(W4,W1,14); step_Bi(W1,W2,13); + step_Bi(W2,W3,12); step_Bi(W3,W4,11); step_Bi(W4,W1,10); step_Bi(W1,W2, 9); - step_Bi(W2,W3,16); step_Bi(W3,W4,15); step_Bi(W4,W1,14); step_Bi(W1,W2,13); - step_Bi(W2,W3,12); step_Bi(W3,W4,11); step_Bi(W4,W1,10); step_Bi(W1,W2, 9); + step_Ai(W1,W2, 8); step_Ai(W2,W3, 7); step_Ai(W3,W4, 6); step_Ai(W4,W1, 5); + step_Ai(W1,W2, 4); step_Ai(W2,W3, 3); step_Ai(W3,W4, 2); step_Ai(W4,W1, 1); - step_Ai(W1,W2, 8); step_Ai(W2,W3, 7); step_Ai(W3,W4, 6); step_Ai(W4,W1, 5); - step_Ai(W1,W2, 4); step_Ai(W2,W3, 3); step_Ai(W3,W4, 2); step_Ai(W4,W1, 1); + store_le(out, W4, W3, W2, W1); - store_le(out, W4, W3, W2, W1); + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* @@ -153,7 +165,7 @@ void Skipjack::key_schedule(const byte key[], u32bit) /* * Clear memory of sensitive data */ -void Skipjack::clear() throw() +void Skipjack::clear() { for(u32bit j = 0; j != 10; ++j) FTABLE[j].clear(); diff --git a/src/block/skipjack/skipjack.h b/src/block/skipjack/skipjack.h index 231cd9c87..60fad6310 100644 --- a/src/block/skipjack/skipjack.h +++ b/src/block/skipjack/skipjack.h @@ -18,18 +18,21 @@ namespace Botan { class BOTAN_DLL Skipjack : public BlockCipher { public: - void clear() throw(); + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + + void clear(); std::string name() const { return "Skipjack"; } BlockCipher* clone() const { return new Skipjack; } + Skipjack() : BlockCipher(8, 10) {} private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; void key_schedule(const byte[], u32bit); void step_A(u16bit&, u16bit&, u32bit) const; void step_B(u16bit&, u16bit&, u32bit) const; void step_Ai(u16bit&, u16bit&, u32bit) const; void step_Bi(u16bit&, u16bit&, u32bit) const; + SecureBuffer<byte, 256> FTABLE[10]; }; diff --git a/src/block/square/info.txt b/src/block/square/info.txt index a20697923..d33379815 100644 --- a/src/block/square/info.txt +++ b/src/block/square/info.txt @@ -1,11 +1 @@ -realname "Square" - define SQUARE - -load_on auto - -<add> -sqr_tab.cpp -square.cpp -square.h -</add> diff --git a/src/block/square/square.cpp b/src/block/square/square.cpp index cb226542d..90f2301cf 100644 --- a/src/block/square/square.cpp +++ b/src/block/square/square.cpp @@ -14,103 +14,123 @@ namespace Botan { /* * Square Encryption */ -void Square::enc(const byte in[], byte out[]) const +void Square::encrypt_n(const byte in[], byte out[], u32bit blocks) const { - u32bit T0, T1, T2, T3, B0, B1, B2, B3; - B0 = TE0[in[ 0] ^ ME[ 0]] ^ TE1[in[ 4] ^ ME[ 4]] ^ - TE2[in[ 8] ^ ME[ 8]] ^ TE3[in[12] ^ ME[12]] ^ EK[0]; - B1 = TE0[in[ 1] ^ ME[ 1]] ^ TE1[in[ 5] ^ ME[ 5]] ^ - TE2[in[ 9] ^ ME[ 9]] ^ TE3[in[13] ^ ME[13]] ^ EK[1]; - B2 = TE0[in[ 2] ^ ME[ 2]] ^ TE1[in[ 6] ^ ME[ 6]] ^ - TE2[in[10] ^ ME[10]] ^ TE3[in[14] ^ ME[14]] ^ EK[2]; - B3 = TE0[in[ 3] ^ ME[ 3]] ^ TE1[in[ 7] ^ ME[ 7]] ^ - TE2[in[11] ^ ME[11]] ^ TE3[in[15] ^ ME[15]] ^ EK[3]; - for(u32bit j = 1; j != 7; j += 2) + for(u32bit i = 0; i != blocks; ++i) { - T0 = TE0[get_byte(0, B0)] ^ TE1[get_byte(0, B1)] ^ - TE2[get_byte(0, B2)] ^ TE3[get_byte(0, B3)] ^ EK[4*j+0]; - T1 = TE0[get_byte(1, B0)] ^ TE1[get_byte(1, B1)] ^ - TE2[get_byte(1, B2)] ^ TE3[get_byte(1, B3)] ^ EK[4*j+1]; - T2 = TE0[get_byte(2, B0)] ^ TE1[get_byte(2, B1)] ^ - TE2[get_byte(2, B2)] ^ TE3[get_byte(2, B3)] ^ EK[4*j+2]; - T3 = TE0[get_byte(3, B0)] ^ TE1[get_byte(3, B1)] ^ - TE2[get_byte(3, B2)] ^ TE3[get_byte(3, B3)] ^ EK[4*j+3]; - B0 = TE0[get_byte(0, T0)] ^ TE1[get_byte(0, T1)] ^ - TE2[get_byte(0, T2)] ^ TE3[get_byte(0, T3)] ^ EK[4*j+4]; - B1 = TE0[get_byte(1, T0)] ^ TE1[get_byte(1, T1)] ^ - TE2[get_byte(1, T2)] ^ TE3[get_byte(1, T3)] ^ EK[4*j+5]; - B2 = TE0[get_byte(2, T0)] ^ TE1[get_byte(2, T1)] ^ - TE2[get_byte(2, T2)] ^ TE3[get_byte(2, T3)] ^ EK[4*j+6]; - B3 = TE0[get_byte(3, T0)] ^ TE1[get_byte(3, T1)] ^ - TE2[get_byte(3, T2)] ^ TE3[get_byte(3, T3)] ^ EK[4*j+7]; + u32bit T0, T1, T2, T3, B0, B1, B2, B3; + + B0 = TE0[in[ 0] ^ ME[ 0]] ^ TE1[in[ 4] ^ ME[ 4]] ^ + TE2[in[ 8] ^ ME[ 8]] ^ TE3[in[12] ^ ME[12]] ^ EK[0]; + B1 = TE0[in[ 1] ^ ME[ 1]] ^ TE1[in[ 5] ^ ME[ 5]] ^ + TE2[in[ 9] ^ ME[ 9]] ^ TE3[in[13] ^ ME[13]] ^ EK[1]; + B2 = TE0[in[ 2] ^ ME[ 2]] ^ TE1[in[ 6] ^ ME[ 6]] ^ + TE2[in[10] ^ ME[10]] ^ TE3[in[14] ^ ME[14]] ^ EK[2]; + B3 = TE0[in[ 3] ^ ME[ 3]] ^ TE1[in[ 7] ^ ME[ 7]] ^ + TE2[in[11] ^ ME[11]] ^ TE3[in[15] ^ ME[15]] ^ EK[3]; + + for(u32bit j = 1; j != 7; j += 2) + { + T0 = TE0[get_byte(0, B0)] ^ TE1[get_byte(0, B1)] ^ + TE2[get_byte(0, B2)] ^ TE3[get_byte(0, B3)] ^ EK[4*j+0]; + T1 = TE0[get_byte(1, B0)] ^ TE1[get_byte(1, B1)] ^ + TE2[get_byte(1, B2)] ^ TE3[get_byte(1, B3)] ^ EK[4*j+1]; + T2 = TE0[get_byte(2, B0)] ^ TE1[get_byte(2, B1)] ^ + TE2[get_byte(2, B2)] ^ TE3[get_byte(2, B3)] ^ EK[4*j+2]; + T3 = TE0[get_byte(3, B0)] ^ TE1[get_byte(3, B1)] ^ + TE2[get_byte(3, B2)] ^ TE3[get_byte(3, B3)] ^ EK[4*j+3]; + + B0 = TE0[get_byte(0, T0)] ^ TE1[get_byte(0, T1)] ^ + TE2[get_byte(0, T2)] ^ TE3[get_byte(0, T3)] ^ EK[4*j+4]; + B1 = TE0[get_byte(1, T0)] ^ TE1[get_byte(1, T1)] ^ + TE2[get_byte(1, T2)] ^ TE3[get_byte(1, T3)] ^ EK[4*j+5]; + B2 = TE0[get_byte(2, T0)] ^ TE1[get_byte(2, T1)] ^ + TE2[get_byte(2, T2)] ^ TE3[get_byte(2, T3)] ^ EK[4*j+6]; + B3 = TE0[get_byte(3, T0)] ^ TE1[get_byte(3, T1)] ^ + TE2[get_byte(3, T2)] ^ TE3[get_byte(3, T3)] ^ EK[4*j+7]; + } + + out[ 0] = SE[get_byte(0, B0)] ^ ME[16]; + out[ 1] = SE[get_byte(0, B1)] ^ ME[17]; + out[ 2] = SE[get_byte(0, B2)] ^ ME[18]; + out[ 3] = SE[get_byte(0, B3)] ^ ME[19]; + out[ 4] = SE[get_byte(1, B0)] ^ ME[20]; + out[ 5] = SE[get_byte(1, B1)] ^ ME[21]; + out[ 6] = SE[get_byte(1, B2)] ^ ME[22]; + out[ 7] = SE[get_byte(1, B3)] ^ ME[23]; + out[ 8] = SE[get_byte(2, B0)] ^ ME[24]; + out[ 9] = SE[get_byte(2, B1)] ^ ME[25]; + out[10] = SE[get_byte(2, B2)] ^ ME[26]; + out[11] = SE[get_byte(2, B3)] ^ ME[27]; + out[12] = SE[get_byte(3, B0)] ^ ME[28]; + out[13] = SE[get_byte(3, B1)] ^ ME[29]; + out[14] = SE[get_byte(3, B2)] ^ ME[30]; + out[15] = SE[get_byte(3, B3)] ^ ME[31]; + + in += BLOCK_SIZE; + out += BLOCK_SIZE; } - out[ 0] = SE[get_byte(0, B0)] ^ ME[16]; - out[ 1] = SE[get_byte(0, B1)] ^ ME[17]; - out[ 2] = SE[get_byte(0, B2)] ^ ME[18]; - out[ 3] = SE[get_byte(0, B3)] ^ ME[19]; - out[ 4] = SE[get_byte(1, B0)] ^ ME[20]; - out[ 5] = SE[get_byte(1, B1)] ^ ME[21]; - out[ 6] = SE[get_byte(1, B2)] ^ ME[22]; - out[ 7] = SE[get_byte(1, B3)] ^ ME[23]; - out[ 8] = SE[get_byte(2, B0)] ^ ME[24]; - out[ 9] = SE[get_byte(2, B1)] ^ ME[25]; - out[10] = SE[get_byte(2, B2)] ^ ME[26]; - out[11] = SE[get_byte(2, B3)] ^ ME[27]; - out[12] = SE[get_byte(3, B0)] ^ ME[28]; - out[13] = SE[get_byte(3, B1)] ^ ME[29]; - out[14] = SE[get_byte(3, B2)] ^ ME[30]; - out[15] = SE[get_byte(3, B3)] ^ ME[31]; } /* * Square Decryption */ -void Square::dec(const byte in[], byte out[]) const +void Square::decrypt_n(const byte in[], byte out[], u32bit blocks) const { - u32bit T0, T1, T2, T3, B0, B1, B2, B3; - B0 = TD0[in[ 0] ^ MD[ 0]] ^ TD1[in[ 4] ^ MD[ 4]] ^ - TD2[in[ 8] ^ MD[ 8]] ^ TD3[in[12] ^ MD[12]] ^ DK[0]; - B1 = TD0[in[ 1] ^ MD[ 1]] ^ TD1[in[ 5] ^ MD[ 5]] ^ - TD2[in[ 9] ^ MD[ 9]] ^ TD3[in[13] ^ MD[13]] ^ DK[1]; - B2 = TD0[in[ 2] ^ MD[ 2]] ^ TD1[in[ 6] ^ MD[ 6]] ^ - TD2[in[10] ^ MD[10]] ^ TD3[in[14] ^ MD[14]] ^ DK[2]; - B3 = TD0[in[ 3] ^ MD[ 3]] ^ TD1[in[ 7] ^ MD[ 7]] ^ - TD2[in[11] ^ MD[11]] ^ TD3[in[15] ^ MD[15]] ^ DK[3]; - for(u32bit j = 1; j != 7; j += 2) + for(u32bit i = 0; i != blocks; ++i) { - T0 = TD0[get_byte(0, B0)] ^ TD1[get_byte(0, B1)] ^ - TD2[get_byte(0, B2)] ^ TD3[get_byte(0, B3)] ^ DK[4*j+0]; - T1 = TD0[get_byte(1, B0)] ^ TD1[get_byte(1, B1)] ^ - TD2[get_byte(1, B2)] ^ TD3[get_byte(1, B3)] ^ DK[4*j+1]; - T2 = TD0[get_byte(2, B0)] ^ TD1[get_byte(2, B1)] ^ - TD2[get_byte(2, B2)] ^ TD3[get_byte(2, B3)] ^ DK[4*j+2]; - T3 = TD0[get_byte(3, B0)] ^ TD1[get_byte(3, B1)] ^ - TD2[get_byte(3, B2)] ^ TD3[get_byte(3, B3)] ^ DK[4*j+3]; - B0 = TD0[get_byte(0, T0)] ^ TD1[get_byte(0, T1)] ^ - TD2[get_byte(0, T2)] ^ TD3[get_byte(0, T3)] ^ DK[4*j+4]; - B1 = TD0[get_byte(1, T0)] ^ TD1[get_byte(1, T1)] ^ - TD2[get_byte(1, T2)] ^ TD3[get_byte(1, T3)] ^ DK[4*j+5]; - B2 = TD0[get_byte(2, T0)] ^ TD1[get_byte(2, T1)] ^ - TD2[get_byte(2, T2)] ^ TD3[get_byte(2, T3)] ^ DK[4*j+6]; - B3 = TD0[get_byte(3, T0)] ^ TD1[get_byte(3, T1)] ^ - TD2[get_byte(3, T2)] ^ TD3[get_byte(3, T3)] ^ DK[4*j+7]; + u32bit T0, T1, T2, T3, B0, B1, B2, B3; + + B0 = TD0[in[ 0] ^ MD[ 0]] ^ TD1[in[ 4] ^ MD[ 4]] ^ + TD2[in[ 8] ^ MD[ 8]] ^ TD3[in[12] ^ MD[12]] ^ DK[0]; + B1 = TD0[in[ 1] ^ MD[ 1]] ^ TD1[in[ 5] ^ MD[ 5]] ^ + TD2[in[ 9] ^ MD[ 9]] ^ TD3[in[13] ^ MD[13]] ^ DK[1]; + B2 = TD0[in[ 2] ^ MD[ 2]] ^ TD1[in[ 6] ^ MD[ 6]] ^ + TD2[in[10] ^ MD[10]] ^ TD3[in[14] ^ MD[14]] ^ DK[2]; + B3 = TD0[in[ 3] ^ MD[ 3]] ^ TD1[in[ 7] ^ MD[ 7]] ^ + TD2[in[11] ^ MD[11]] ^ TD3[in[15] ^ MD[15]] ^ DK[3]; + + for(u32bit j = 1; j != 7; j += 2) + { + T0 = TD0[get_byte(0, B0)] ^ TD1[get_byte(0, B1)] ^ + TD2[get_byte(0, B2)] ^ TD3[get_byte(0, B3)] ^ DK[4*j+0]; + T1 = TD0[get_byte(1, B0)] ^ TD1[get_byte(1, B1)] ^ + TD2[get_byte(1, B2)] ^ TD3[get_byte(1, B3)] ^ DK[4*j+1]; + T2 = TD0[get_byte(2, B0)] ^ TD1[get_byte(2, B1)] ^ + TD2[get_byte(2, B2)] ^ TD3[get_byte(2, B3)] ^ DK[4*j+2]; + T3 = TD0[get_byte(3, B0)] ^ TD1[get_byte(3, B1)] ^ + TD2[get_byte(3, B2)] ^ TD3[get_byte(3, B3)] ^ DK[4*j+3]; + + B0 = TD0[get_byte(0, T0)] ^ TD1[get_byte(0, T1)] ^ + TD2[get_byte(0, T2)] ^ TD3[get_byte(0, T3)] ^ DK[4*j+4]; + B1 = TD0[get_byte(1, T0)] ^ TD1[get_byte(1, T1)] ^ + TD2[get_byte(1, T2)] ^ TD3[get_byte(1, T3)] ^ DK[4*j+5]; + B2 = TD0[get_byte(2, T0)] ^ TD1[get_byte(2, T1)] ^ + TD2[get_byte(2, T2)] ^ TD3[get_byte(2, T3)] ^ DK[4*j+6]; + B3 = TD0[get_byte(3, T0)] ^ TD1[get_byte(3, T1)] ^ + TD2[get_byte(3, T2)] ^ TD3[get_byte(3, T3)] ^ DK[4*j+7]; + } + + out[ 0] = SD[get_byte(0, B0)] ^ MD[16]; + out[ 1] = SD[get_byte(0, B1)] ^ MD[17]; + out[ 2] = SD[get_byte(0, B2)] ^ MD[18]; + out[ 3] = SD[get_byte(0, B3)] ^ MD[19]; + out[ 4] = SD[get_byte(1, B0)] ^ MD[20]; + out[ 5] = SD[get_byte(1, B1)] ^ MD[21]; + out[ 6] = SD[get_byte(1, B2)] ^ MD[22]; + out[ 7] = SD[get_byte(1, B3)] ^ MD[23]; + out[ 8] = SD[get_byte(2, B0)] ^ MD[24]; + out[ 9] = SD[get_byte(2, B1)] ^ MD[25]; + out[10] = SD[get_byte(2, B2)] ^ MD[26]; + out[11] = SD[get_byte(2, B3)] ^ MD[27]; + out[12] = SD[get_byte(3, B0)] ^ MD[28]; + out[13] = SD[get_byte(3, B1)] ^ MD[29]; + out[14] = SD[get_byte(3, B2)] ^ MD[30]; + out[15] = SD[get_byte(3, B3)] ^ MD[31]; + + in += BLOCK_SIZE; + out += BLOCK_SIZE; } - out[ 0] = SD[get_byte(0, B0)] ^ MD[16]; - out[ 1] = SD[get_byte(0, B1)] ^ MD[17]; - out[ 2] = SD[get_byte(0, B2)] ^ MD[18]; - out[ 3] = SD[get_byte(0, B3)] ^ MD[19]; - out[ 4] = SD[get_byte(1, B0)] ^ MD[20]; - out[ 5] = SD[get_byte(1, B1)] ^ MD[21]; - out[ 6] = SD[get_byte(1, B2)] ^ MD[22]; - out[ 7] = SD[get_byte(1, B3)] ^ MD[23]; - out[ 8] = SD[get_byte(2, B0)] ^ MD[24]; - out[ 9] = SD[get_byte(2, B1)] ^ MD[25]; - out[10] = SD[get_byte(2, B2)] ^ MD[26]; - out[11] = SD[get_byte(2, B3)] ^ MD[27]; - out[12] = SD[get_byte(3, B0)] ^ MD[28]; - out[13] = SD[get_byte(3, B1)] ^ MD[29]; - out[14] = SD[get_byte(3, B2)] ^ MD[30]; - out[15] = SD[get_byte(3, B3)] ^ MD[31]; } /* @@ -176,7 +196,7 @@ void Square::transform(u32bit round_key[4]) /* * Clear memory of sensitive data */ -void Square::clear() throw() +void Square::clear() { EK.clear(); DK.clear(); diff --git a/src/block/square/square.h b/src/block/square/square.h index 94a1fc370..088122181 100644 --- a/src/block/square/square.h +++ b/src/block/square/square.h @@ -18,13 +18,15 @@ namespace Botan { class BOTAN_DLL Square : public BlockCipher { public: - void clear() throw(); + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + + void clear(); std::string name() const { return "Square"; } BlockCipher* clone() const { return new Square; } + Square() : BlockCipher(16, 16) {} private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; void key_schedule(const byte[], u32bit); static void transform(u32bit[4]); diff --git a/src/block/tea/info.txt b/src/block/tea/info.txt index 6a0e76b15..67ed5a656 100644 --- a/src/block/tea/info.txt +++ b/src/block/tea/info.txt @@ -1,10 +1 @@ -realname "TEA" - define TEA - -load_on auto - -<add> -tea.cpp -tea.h -</add> diff --git a/src/block/tea/tea.cpp b/src/block/tea/tea.cpp index 2b4212d9c..de30858da 100644 --- a/src/block/tea/tea.cpp +++ b/src/block/tea/tea.cpp @@ -13,37 +13,49 @@ namespace Botan { /* * TEA Encryption */ -void TEA::enc(const byte in[], byte out[]) const +void TEA::encrypt_n(const byte in[], byte out[], u32bit blocks) const { - u32bit L = load_be<u32bit>(in, 0), R = load_be<u32bit>(in, 1); - - u32bit S = 0; - for(u32bit j = 0; j != 32; ++j) + for(u32bit i = 0; i != blocks; ++i) { - S += 0x9E3779B9; - L += ((R << 4) + K[0]) ^ (R + S) ^ ((R >> 5) + K[1]); - R += ((L << 4) + K[2]) ^ (L + S) ^ ((L >> 5) + K[3]); - } + u32bit L = load_be<u32bit>(in, 0), R = load_be<u32bit>(in, 1); + + u32bit S = 0; + for(u32bit j = 0; j != 32; ++j) + { + S += 0x9E3779B9; + L += ((R << 4) + K[0]) ^ (R + S) ^ ((R >> 5) + K[1]); + R += ((L << 4) + K[2]) ^ (L + S) ^ ((L >> 5) + K[3]); + } - store_be(out, L, R); + store_be(out, L, R); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* * TEA Decryption */ -void TEA::dec(const byte in[], byte out[]) const +void TEA::decrypt_n(const byte in[], byte out[], u32bit blocks) const { - u32bit L = load_be<u32bit>(in, 0), R = load_be<u32bit>(in, 1); - - u32bit S = 0xC6EF3720; - for(u32bit j = 0; j != 32; ++j) + for(u32bit i = 0; i != blocks; ++i) { - R -= ((L << 4) + K[2]) ^ (L + S) ^ ((L >> 5) + K[3]); - L -= ((R << 4) + K[0]) ^ (R + S) ^ ((R >> 5) + K[1]); - S -= 0x9E3779B9; - } + u32bit L = load_be<u32bit>(in, 0), R = load_be<u32bit>(in, 1); + + u32bit S = 0xC6EF3720; + for(u32bit j = 0; j != 32; ++j) + { + R -= ((L << 4) + K[2]) ^ (L + S) ^ ((L >> 5) + K[3]); + L -= ((R << 4) + K[0]) ^ (R + S) ^ ((R >> 5) + K[1]); + S -= 0x9E3779B9; + } - store_be(out, L, R); + store_be(out, L, R); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* diff --git a/src/block/tea/tea.h b/src/block/tea/tea.h index 8ddf3e330..c19f272a6 100644 --- a/src/block/tea/tea.h +++ b/src/block/tea/tea.h @@ -18,13 +18,15 @@ namespace Botan { class BOTAN_DLL TEA : public BlockCipher { public: - void clear() throw() { K.clear(); } + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + + void clear() { K.clear(); } std::string name() const { return "TEA"; } BlockCipher* clone() const { return new TEA; } + TEA() : BlockCipher(8, 16) {} private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; void key_schedule(const byte[], u32bit); SecureBuffer<u32bit, 4> K; }; diff --git a/src/block/twofish/info.txt b/src/block/twofish/info.txt index 35639d858..88eae9ce7 100644 --- a/src/block/twofish/info.txt +++ b/src/block/twofish/info.txt @@ -1,11 +1 @@ -realname "Twofish" - define TWOFISH - -load_on auto - -<add> -two_tab.cpp -twofish.cpp -twofish.h -</add> diff --git a/src/block/twofish/twofish.cpp b/src/block/twofish/twofish.cpp index 9784b00a2..3136837aa 100644 --- a/src/block/twofish/twofish.cpp +++ b/src/block/twofish/twofish.cpp @@ -14,91 +14,103 @@ namespace Botan { /* * Twofish Encryption */ -void Twofish::enc(const byte in[], byte out[]) const +void Twofish::encrypt_n(const byte in[], byte out[], u32bit blocks) const { - u32bit A = load_le<u32bit>(in, 0) ^ round_key[0]; - u32bit B = load_le<u32bit>(in, 1) ^ round_key[1]; - u32bit C = load_le<u32bit>(in, 2) ^ round_key[2]; - u32bit D = load_le<u32bit>(in, 3) ^ round_key[3]; - - for(u32bit j = 0; j != 16; j += 2) + for(u32bit i = 0; i != blocks; ++i) { - u32bit X, Y; - - X = SBox0[get_byte(3, A)] ^ SBox1[get_byte(2, A)] ^ - SBox2[get_byte(1, A)] ^ SBox3[get_byte(0, A)]; - Y = SBox0[get_byte(0, B)] ^ SBox1[get_byte(3, B)] ^ - SBox2[get_byte(2, B)] ^ SBox3[get_byte(1, B)]; - X += Y; - Y += X + round_key[2*j + 9]; - X += round_key[2*j + 8]; - - C = rotate_right(C ^ X, 1); - D = rotate_left(D, 1) ^ Y; - - X = SBox0[get_byte(3, C)] ^ SBox1[get_byte(2, C)] ^ - SBox2[get_byte(1, C)] ^ SBox3[get_byte(0, C)]; - Y = SBox0[get_byte(0, D)] ^ SBox1[get_byte(3, D)] ^ - SBox2[get_byte(2, D)] ^ SBox3[get_byte(1, D)]; - X += Y; - Y += X + round_key[2*j + 11]; - X += round_key[2*j + 10]; - - A = rotate_right(A ^ X, 1); - B = rotate_left(B, 1) ^ Y; - } + u32bit A = load_le<u32bit>(in, 0) ^ round_key[0]; + u32bit B = load_le<u32bit>(in, 1) ^ round_key[1]; + u32bit C = load_le<u32bit>(in, 2) ^ round_key[2]; + u32bit D = load_le<u32bit>(in, 3) ^ round_key[3]; - C ^= round_key[4]; - D ^= round_key[5]; - A ^= round_key[6]; - B ^= round_key[7]; + for(u32bit j = 0; j != 16; j += 2) + { + u32bit X, Y; + + X = SBox0[get_byte(3, A)] ^ SBox1[get_byte(2, A)] ^ + SBox2[get_byte(1, A)] ^ SBox3[get_byte(0, A)]; + Y = SBox0[get_byte(0, B)] ^ SBox1[get_byte(3, B)] ^ + SBox2[get_byte(2, B)] ^ SBox3[get_byte(1, B)]; + X += Y; + Y += X + round_key[2*j + 9]; + X += round_key[2*j + 8]; + + C = rotate_right(C ^ X, 1); + D = rotate_left(D, 1) ^ Y; + + X = SBox0[get_byte(3, C)] ^ SBox1[get_byte(2, C)] ^ + SBox2[get_byte(1, C)] ^ SBox3[get_byte(0, C)]; + Y = SBox0[get_byte(0, D)] ^ SBox1[get_byte(3, D)] ^ + SBox2[get_byte(2, D)] ^ SBox3[get_byte(1, D)]; + X += Y; + Y += X + round_key[2*j + 11]; + X += round_key[2*j + 10]; + + A = rotate_right(A ^ X, 1); + B = rotate_left(B, 1) ^ Y; + } - store_le(out, C, D, A, B); + C ^= round_key[4]; + D ^= round_key[5]; + A ^= round_key[6]; + B ^= round_key[7]; + + store_le(out, C, D, A, B); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* * Twofish Decryption */ -void Twofish::dec(const byte in[], byte out[]) const +void Twofish::decrypt_n(const byte in[], byte out[], u32bit blocks) const { - u32bit A = load_le<u32bit>(in, 0) ^ round_key[4]; - u32bit B = load_le<u32bit>(in, 1) ^ round_key[5]; - u32bit C = load_le<u32bit>(in, 2) ^ round_key[6]; - u32bit D = load_le<u32bit>(in, 3) ^ round_key[7]; - - for(u32bit j = 0; j != 16; j += 2) + for(u32bit i = 0; i != blocks; ++i) { - u32bit X, Y; - - X = SBox0[get_byte(3, A)] ^ SBox1[get_byte(2, A)] ^ - SBox2[get_byte(1, A)] ^ SBox3[get_byte(0, A)]; - Y = SBox0[get_byte(0, B)] ^ SBox1[get_byte(3, B)] ^ - SBox2[get_byte(2, B)] ^ SBox3[get_byte(1, B)]; - X += Y; - Y += X + round_key[39 - 2*j]; - X += round_key[38 - 2*j]; - - C = rotate_left(C, 1) ^ X; - D = rotate_right(D ^ Y, 1); - - X = SBox0[get_byte(3, C)] ^ SBox1[get_byte(2, C)] ^ - SBox2[get_byte(1, C)] ^ SBox3[get_byte(0, C)]; - Y = SBox0[get_byte(0, D)] ^ SBox1[get_byte(3, D)] ^ - SBox2[get_byte(2, D)] ^ SBox3[get_byte(1, D)]; - X += Y; - Y += X + round_key[37 - 2*j]; - X += round_key[36 - 2*j]; - - A = rotate_left(A, 1) ^ X; - B = rotate_right(B ^ Y, 1); - } + u32bit A = load_le<u32bit>(in, 0) ^ round_key[4]; + u32bit B = load_le<u32bit>(in, 1) ^ round_key[5]; + u32bit C = load_le<u32bit>(in, 2) ^ round_key[6]; + u32bit D = load_le<u32bit>(in, 3) ^ round_key[7]; - C ^= round_key[0]; - D ^= round_key[1]; - A ^= round_key[2]; - B ^= round_key[3]; + for(u32bit j = 0; j != 16; j += 2) + { + u32bit X, Y; + + X = SBox0[get_byte(3, A)] ^ SBox1[get_byte(2, A)] ^ + SBox2[get_byte(1, A)] ^ SBox3[get_byte(0, A)]; + Y = SBox0[get_byte(0, B)] ^ SBox1[get_byte(3, B)] ^ + SBox2[get_byte(2, B)] ^ SBox3[get_byte(1, B)]; + X += Y; + Y += X + round_key[39 - 2*j]; + X += round_key[38 - 2*j]; + + C = rotate_left(C, 1) ^ X; + D = rotate_right(D ^ Y, 1); + + X = SBox0[get_byte(3, C)] ^ SBox1[get_byte(2, C)] ^ + SBox2[get_byte(1, C)] ^ SBox3[get_byte(0, C)]; + Y = SBox0[get_byte(0, D)] ^ SBox1[get_byte(3, D)] ^ + SBox2[get_byte(2, D)] ^ SBox3[get_byte(1, D)]; + X += Y; + Y += X + round_key[37 - 2*j]; + X += round_key[36 - 2*j]; + + A = rotate_left(A, 1) ^ X; + B = rotate_right(B ^ Y, 1); + } - store_le(out, C, D, A, B); + C ^= round_key[0]; + D ^= round_key[1]; + A ^= round_key[2]; + B ^= round_key[3]; + + store_le(out, C, D, A, B); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* @@ -206,7 +218,7 @@ void Twofish::rs_mul(byte S[4], byte key, u32bit offset) /* * Clear memory of sensitive data */ -void Twofish::clear() throw() +void Twofish::clear() { SBox0.clear(); SBox1.clear(); diff --git a/src/block/twofish/twofish.h b/src/block/twofish/twofish.h index 0640e32f8..71a1e8781 100644 --- a/src/block/twofish/twofish.h +++ b/src/block/twofish/twofish.h @@ -18,13 +18,15 @@ namespace Botan { class BOTAN_DLL Twofish : public BlockCipher { public: - void clear() throw(); + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + + void clear(); std::string name() const { return "Twofish"; } BlockCipher* clone() const { return new Twofish; } + Twofish() : BlockCipher(16, 16, 32, 8) {} private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; void key_schedule(const byte[], u32bit); static void rs_mul(byte[4], byte, u32bit); diff --git a/src/block/xtea/info.txt b/src/block/xtea/info.txt index 0120a3bce..d9d37607c 100644 --- a/src/block/xtea/info.txt +++ b/src/block/xtea/info.txt @@ -1,10 +1 @@ -realname "XTEA" - define XTEA - -load_on auto - -<add> -xtea.cpp -xtea.h -</add> diff --git a/src/block/xtea/xtea.cpp b/src/block/xtea/xtea.cpp index 5047f6594..fc14c0a57 100644 --- a/src/block/xtea/xtea.cpp +++ b/src/block/xtea/xtea.cpp @@ -7,40 +7,113 @@ #include <botan/xtea.h> #include <botan/loadstor.h> -#include <botan/parsing.h> namespace Botan { +namespace { + +void xtea_encrypt_4(const byte in[32], byte out[32], const u32bit EK[64]) + { + u32bit L0, R0, L1, R1, L2, R2, L3, R3; + load_be(in, L0, R0, L1, R1, L2, R2, L3, R3); + + for(u32bit i = 0; i != 32; ++i) + { + L0 += (((R0 << 4) ^ (R0 >> 5)) + R0) ^ EK[2*i]; + L1 += (((R1 << 4) ^ (R1 >> 5)) + R1) ^ EK[2*i]; + L2 += (((R2 << 4) ^ (R2 >> 5)) + R2) ^ EK[2*i]; + L3 += (((R3 << 4) ^ (R3 >> 5)) + R3) ^ EK[2*i]; + + R0 += (((L0 << 4) ^ (L0 >> 5)) + L0) ^ EK[2*i+1]; + R1 += (((L1 << 4) ^ (L1 >> 5)) + L1) ^ EK[2*i+1]; + R2 += (((L2 << 4) ^ (L2 >> 5)) + L2) ^ EK[2*i+1]; + R3 += (((L3 << 4) ^ (L3 >> 5)) + L3) ^ EK[2*i+1]; + } + + store_be(out, L0, R0, L1, R1, L2, R2, L3, R3); + } + +void xtea_decrypt_4(const byte in[32], byte out[32], const u32bit EK[64]) + { + u32bit L0, R0, L1, R1, L2, R2, L3, R3; + load_be(in, L0, R0, L1, R1, L2, R2, L3, R3); + + for(u32bit i = 0; i != 32; ++i) + { + R0 -= (((L0 << 4) ^ (L0 >> 5)) + L0) ^ EK[63 - 2*i]; + R1 -= (((L1 << 4) ^ (L1 >> 5)) + L1) ^ EK[63 - 2*i]; + R2 -= (((L2 << 4) ^ (L2 >> 5)) + L2) ^ EK[63 - 2*i]; + R3 -= (((L3 << 4) ^ (L3 >> 5)) + L3) ^ EK[63 - 2*i]; + + L0 -= (((R0 << 4) ^ (R0 >> 5)) + R0) ^ EK[62 - 2*i]; + L1 -= (((R1 << 4) ^ (R1 >> 5)) + R1) ^ EK[62 - 2*i]; + L2 -= (((R2 << 4) ^ (R2 >> 5)) + R2) ^ EK[62 - 2*i]; + L3 -= (((R3 << 4) ^ (R3 >> 5)) + R3) ^ EK[62 - 2*i]; + } + + store_be(out, L0, R0, L1, R1, L2, R2, L3, R3); + } + +} + /* * XTEA Encryption */ -void XTEA::enc(const byte in[], byte out[]) const +void XTEA::encrypt_n(const byte in[], byte out[], u32bit blocks) const { - u32bit L = load_be<u32bit>(in, 0), R = load_be<u32bit>(in, 1); - - for(u32bit j = 0; j != 32; ++j) + while(blocks >= 4) { - L += (((R << 4) ^ (R >> 5)) + R) ^ EK[2*j]; - R += (((L << 4) ^ (L >> 5)) + L) ^ EK[2*j+1]; + xtea_encrypt_4(in, out, this->EK); + in += 4 * BLOCK_SIZE; + out += 4 * BLOCK_SIZE; + blocks -= 4; } - store_be(out, L, R); + for(u32bit i = 0; i != blocks; ++i) + { + u32bit L = load_be<u32bit>(in, 0), R = load_be<u32bit>(in, 1); + + for(u32bit j = 0; j != 32; ++j) + { + L += (((R << 4) ^ (R >> 5)) + R) ^ EK[2*j]; + R += (((L << 4) ^ (L >> 5)) + L) ^ EK[2*j+1]; + } + + store_be(out, L, R); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* * XTEA Decryption */ -void XTEA::dec(const byte in[], byte out[]) const +void XTEA::decrypt_n(const byte in[], byte out[], u32bit blocks) const { - u32bit L = load_be<u32bit>(in, 0), R = load_be<u32bit>(in, 1); - - for(u32bit j = 0; j != 32; ++j) + while(blocks >= 4) { - R -= (((L << 4) ^ (L >> 5)) + L) ^ EK[63 - 2*j]; - L -= (((R << 4) ^ (R >> 5)) + R) ^ EK[62 - 2*j]; + xtea_decrypt_4(in, out, this->EK); + in += 4 * BLOCK_SIZE; + out += 4 * BLOCK_SIZE; + blocks -= 4; } - store_be(out, L, R); + for(u32bit i = 0; i != blocks; ++i) + { + u32bit L = load_be<u32bit>(in, 0), R = load_be<u32bit>(in, 1); + + for(u32bit j = 0; j != 32; ++j) + { + R -= (((L << 4) ^ (L >> 5)) + L) ^ EK[63 - 2*j]; + L -= (((R << 4) ^ (R >> 5)) + R) ^ EK[62 - 2*j]; + } + + store_be(out, L, R); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } } /* diff --git a/src/block/xtea/xtea.h b/src/block/xtea/xtea.h index d9c6066cb..9982d0712 100644 --- a/src/block/xtea/xtea.h +++ b/src/block/xtea/xtea.h @@ -18,13 +18,15 @@ namespace Botan { class BOTAN_DLL XTEA : public BlockCipher { public: - void clear() throw() { EK.clear(); } + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + + void clear() { EK.clear(); } std::string name() const { return "XTEA"; } BlockCipher* clone() const { return new XTEA; } + XTEA() : BlockCipher(8, 16) {} - private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; + protected: void key_schedule(const byte[], u32bit); SecureBuffer<u32bit, 64> EK; }; diff --git a/src/block/xtea_simd/info.txt b/src/block/xtea_simd/info.txt new file mode 100644 index 000000000..98a6e941f --- /dev/null +++ b/src/block/xtea_simd/info.txt @@ -0,0 +1,14 @@ +define XTEA_SIMD + +load_on auto + +<add> +xtea_simd.cpp +xtea_simd.h +</add> + +<requires> +xtea +simd_32 +simd_engine +</requires> diff --git a/src/block/xtea_simd/xtea_simd.cpp b/src/block/xtea_simd/xtea_simd.cpp new file mode 100644 index 000000000..6151c355c --- /dev/null +++ b/src/block/xtea_simd/xtea_simd.cpp @@ -0,0 +1,124 @@ +/* +* XTEA in SIMD +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/xtea_simd.h> +#include <botan/loadstor.h> +#include <botan/simd_32.h> + +namespace Botan { + +namespace { + +void xtea_encrypt_8(const byte in[64], byte out[64], const u32bit EK[64]) + { + SIMD_32 L0 = SIMD_32::load_be(in ); + SIMD_32 R0 = SIMD_32::load_be(in + 16); + SIMD_32 L1 = SIMD_32::load_be(in + 32); + SIMD_32 R1 = SIMD_32::load_be(in + 48); + + SIMD_32::transpose(L0, R0, L1, R1); + + for(u32bit i = 0; i != 32; i += 2) + { + SIMD_32 K0(EK[2*i ]); + SIMD_32 K1(EK[2*i+1]); + SIMD_32 K2(EK[2*i+2]); + SIMD_32 K3(EK[2*i+3]); + + L0 += (((R0 << 4) ^ (R0 >> 5)) + R0) ^ K0; + L1 += (((R1 << 4) ^ (R1 >> 5)) + R1) ^ K0; + + R0 += (((L0 << 4) ^ (L0 >> 5)) + L0) ^ K1; + R1 += (((L1 << 4) ^ (L1 >> 5)) + L1) ^ K1; + + L0 += (((R0 << 4) ^ (R0 >> 5)) + R0) ^ K2; + L1 += (((R1 << 4) ^ (R1 >> 5)) + R1) ^ K2; + + R0 += (((L0 << 4) ^ (L0 >> 5)) + L0) ^ K3; + R1 += (((L1 << 4) ^ (L1 >> 5)) + L1) ^ K3; + } + + SIMD_32::transpose(L0, R0, L1, R1); + + L0.store_be(out); + R0.store_be(out + 16); + L1.store_be(out + 32); + R1.store_be(out + 48); + } + +void xtea_decrypt_8(const byte in[64], byte out[64], const u32bit EK[64]) + { + SIMD_32 L0 = SIMD_32::load_be(in ); + SIMD_32 R0 = SIMD_32::load_be(in + 16); + SIMD_32 L1 = SIMD_32::load_be(in + 32); + SIMD_32 R1 = SIMD_32::load_be(in + 48); + + SIMD_32::transpose(L0, R0, L1, R1); + + for(u32bit i = 0; i != 32; i += 2) + { + SIMD_32 K0(EK[63 - 2*i]); + SIMD_32 K1(EK[62 - 2*i]); + SIMD_32 K2(EK[61 - 2*i]); + SIMD_32 K3(EK[60 - 2*i]); + + R0 -= (((L0 << 4) ^ (L0 >> 5)) + L0) ^ K0; + R1 -= (((L1 << 4) ^ (L1 >> 5)) + L1) ^ K0; + + L0 -= (((R0 << 4) ^ (R0 >> 5)) + R0) ^ K1; + L1 -= (((R1 << 4) ^ (R1 >> 5)) + R1) ^ K1; + + R0 -= (((L0 << 4) ^ (L0 >> 5)) + L0) ^ K2; + R1 -= (((L1 << 4) ^ (L1 >> 5)) + L1) ^ K2; + + L0 -= (((R0 << 4) ^ (R0 >> 5)) + R0) ^ K3; + L1 -= (((R1 << 4) ^ (R1 >> 5)) + R1) ^ K3; + } + + SIMD_32::transpose(L0, R0, L1, R1); + + L0.store_be(out); + R0.store_be(out + 16); + L1.store_be(out + 32); + R1.store_be(out + 48); + } + +} + +/* +* XTEA Encryption +*/ +void XTEA_SIMD::encrypt_n(const byte in[], byte out[], u32bit blocks) const + { + while(blocks >= 8) + { + xtea_encrypt_8(in, out, this->EK); + in += 8 * BLOCK_SIZE; + out += 8 * BLOCK_SIZE; + blocks -= 8; + } + + XTEA::encrypt_n(in, out, blocks); + } + +/* +* XTEA Decryption +*/ +void XTEA_SIMD::decrypt_n(const byte in[], byte out[], u32bit blocks) const + { + while(blocks >= 8) + { + xtea_decrypt_8(in, out, this->EK); + in += 8 * BLOCK_SIZE; + out += 8 * BLOCK_SIZE; + blocks -= 8; + } + + XTEA::decrypt_n(in, out, blocks); + } + +} diff --git a/src/block/xtea_simd/xtea_simd.h b/src/block/xtea_simd/xtea_simd.h new file mode 100644 index 000000000..e4ce734ed --- /dev/null +++ b/src/block/xtea_simd/xtea_simd.h @@ -0,0 +1,28 @@ +/* +* XTEA in SIMD +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_XTEA_SIMD_H__ +#define BOTAN_XTEA_SIMD_H__ + +#include <botan/xtea.h> + +namespace Botan { + +/* +* XTEA (SIMD variant) +*/ +class BOTAN_DLL XTEA_SIMD : public XTEA + { + public: + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; + BlockCipher* clone() const { return new XTEA_SIMD; } + }; + +} + +#endif diff --git a/src/build-data/arch/alpha.txt b/src/build-data/arch/alpha.txt index 60b264396..b1d939ed1 100644 --- a/src/build-data/arch/alpha.txt +++ b/src/build-data/arch/alpha.txt @@ -1,5 +1,3 @@ -realname "DEC Alpha" - default_submodel alpha-ev4 endian little diff --git a/src/build-data/arch/amd64.txt b/src/build-data/arch/amd64.txt index 216588e7b..96da0e3a9 100644 --- a/src/build-data/arch/amd64.txt +++ b/src/build-data/arch/amd64.txt @@ -1,5 +1,3 @@ -realname "x86-64" - default_submodel opteron endian little diff --git a/src/build-data/arch/arm.txt b/src/build-data/arch/arm.txt index c6be4ad46..5f05d4cad 100644 --- a/src/build-data/arch/arm.txt +++ b/src/build-data/arch/arm.txt @@ -1,5 +1,3 @@ -realname "ARM" - default_submodel arm2 <submodels> diff --git a/src/build-data/arch/hitachi-sh.txt b/src/build-data/arch/hitachi-sh.txt index 8e9f7eee3..85a741f59 100644 --- a/src/build-data/arch/hitachi-sh.txt +++ b/src/build-data/arch/hitachi-sh.txt @@ -1,5 +1,3 @@ -realname "Hitachi SH" - default_submodel hitachi-sh1 <submodels> diff --git a/src/build-data/arch/hppa.txt b/src/build-data/arch/hppa.txt index 4cdd40889..67bca263d 100644 --- a/src/build-data/arch/hppa.txt +++ b/src/build-data/arch/hppa.txt @@ -1,5 +1,3 @@ -realname "HP-PA" - default_submodel hppa1.0 <aliases> diff --git a/src/build-data/arch/ia32.txt b/src/build-data/arch/ia32.txt index aafcf9a77..0fe665e68 100644 --- a/src/build-data/arch/ia32.txt +++ b/src/build-data/arch/ia32.txt @@ -1,5 +1,3 @@ -realname "IA-32" - default_submodel i386 endian little diff --git a/src/build-data/arch/ia64.txt b/src/build-data/arch/ia64.txt index 7ca84c007..65309f0ff 100644 --- a/src/build-data/arch/ia64.txt +++ b/src/build-data/arch/ia64.txt @@ -1,5 +1,3 @@ -realname "IA-64" - # This is safe: only affects tuning, not ISA default_submodel itanium2 diff --git a/src/build-data/arch/m68k.txt b/src/build-data/arch/m68k.txt index 27f246abc..3a8b5e8b3 100644 --- a/src/build-data/arch/m68k.txt +++ b/src/build-data/arch/m68k.txt @@ -1,7 +1,10 @@ -realname "Motorola 680x0" - default_submodel 68020 +endian big + +# Except for Coldfire +#unaligned ok + <aliases> 680x0 68k diff --git a/src/build-data/arch/mips32.txt b/src/build-data/arch/mips32.txt index 9846c8fb2..ec9d4b5bf 100644 --- a/src/build-data/arch/mips32.txt +++ b/src/build-data/arch/mips32.txt @@ -1,5 +1,3 @@ -realname "MIPS" - default_submodel r3000 <aliases> diff --git a/src/build-data/arch/mips64.txt b/src/build-data/arch/mips64.txt index dbb49d028..666ba7e18 100644 --- a/src/build-data/arch/mips64.txt +++ b/src/build-data/arch/mips64.txt @@ -1,5 +1,3 @@ -realname "MIPS64" - default_submodel r4400 <submodels> diff --git a/src/build-data/arch/ppc.txt b/src/build-data/arch/ppc.txt index 16112f389..254643fdd 100644 --- a/src/build-data/arch/ppc.txt +++ b/src/build-data/arch/ppc.txt @@ -1,6 +1,5 @@ -realname "PowerPC" - endian big +unaligned ok default_submodel ppc604 diff --git a/src/build-data/arch/ppc64.txt b/src/build-data/arch/ppc64.txt index 7c8944faf..f044ba98d 100644 --- a/src/build-data/arch/ppc64.txt +++ b/src/build-data/arch/ppc64.txt @@ -1,5 +1,3 @@ -realname "PowerPC 64" - endian big default_submodel power4 diff --git a/src/build-data/arch/s390.txt b/src/build-data/arch/s390.txt index 392f51397..8024a4315 100644 --- a/src/build-data/arch/s390.txt +++ b/src/build-data/arch/s390.txt @@ -1,7 +1,8 @@ -realname "S/390 31-bit" - default_submodel s390 +endian big +unaligned ok + <submodels> s390 </submodels> diff --git a/src/build-data/arch/s390x.txt b/src/build-data/arch/s390x.txt index 49fb0bda7..00daab8b4 100644 --- a/src/build-data/arch/s390x.txt +++ b/src/build-data/arch/s390x.txt @@ -1,7 +1,8 @@ -realname "S/390 64-bit" - default_submodel s390x +endian big +unaligned ok + <submodels> s390x </submodels> diff --git a/src/build-data/arch/sparc32.txt b/src/build-data/arch/sparc32.txt index 6b752df87..57b19c519 100644 --- a/src/build-data/arch/sparc32.txt +++ b/src/build-data/arch/sparc32.txt @@ -1,5 +1,3 @@ -realname "SPARC" - # V7 doesn't have integer multiply, so it will be bitterly slow for some things # (especially BigInt). Also, it's fairly rare nowadays, so we default to V8. default_submodel sparc32-v8 @@ -31,4 +29,3 @@ sparc-v7 -> sparc32-v7 sparc-v8 -> sparc32-v8 sparc-v9 -> sparc32-v9 </submodel_aliases> - diff --git a/src/build-data/arch/sparc64.txt b/src/build-data/arch/sparc64.txt index c0575efc4..e308055fa 100644 --- a/src/build-data/arch/sparc64.txt +++ b/src/build-data/arch/sparc64.txt @@ -1,5 +1,3 @@ -realname "SPARC64" - default_submodel sparc64-ultra <submodels> diff --git a/src/build-data/buildh.in b/src/build-data/buildh.in index e4ab0f44b..e0d8368ed 100644 --- a/src/build-data/buildh.in +++ b/src/build-data/buildh.in @@ -22,6 +22,18 @@ #define BOTAN_KARAT_SQR_THRESHOLD 32 #define BOTAN_PRIVATE_KEY_OP_BLINDING_BITS 64 +/* +* Toggles for parallel block cipher mode processing +* +* CBC and CFB can only use parallel processing in decryption mode +*/ +#define BOTAN_PARALLEL_BLOCKS_ECB 8 +#define BOTAN_PARALLEL_BLOCKS_CBC 8 +#define BOTAN_PARALLEL_BLOCKS_CFB 8 +#define BOTAN_PARALLEL_BLOCKS_CTR 8 +#define BOTAN_PARALLEL_BLOCKS_EAX 8 +#define BOTAN_PARALLEL_BLOCKS_XTS 8 + /* PK key consistency checking toggles */ #define BOTAN_PUBLIC_KEY_STRONG_CHECKS_ON_LOAD 1 #define BOTAN_PRIVATE_KEY_STRONG_CHECKS_ON_LOAD 1 diff --git a/src/build-data/cc/bcc.txt b/src/build-data/cc/bcc.txt index df09daff0..4315c379f 100644 --- a/src/build-data/cc/bcc.txt +++ b/src/build-data/cc/bcc.txt @@ -1,4 +1,4 @@ -realname "Borland C++" +macro_name "BORLAND" binary_name "bcc32" diff --git a/src/build-data/cc/clang.txt b/src/build-data/cc/clang.txt new file mode 100644 index 000000000..18f3580ce --- /dev/null +++ b/src/build-data/cc/clang.txt @@ -0,0 +1,44 @@ +# Largely copied from the gcc config + +macro_name "CLANG" + +binary_name clang + +compile_option "-c " +output_to_option "-o " +add_include_dir_option "-I" +add_lib_dir_option "-L" +add_lib_option "-l" + +lang_flags "-D_REENTRANT -ansi -Wno-long-long" +warning_flags "-W -Wall" + +makefile_style unix + +lib_opt_flags "-O2" +check_opt_flags "-O2" +shared_flags "-fPIC" +debug_flags "-g" +no_debug_flags "-finline-functions" + +<so_link_flags> +# The default works for GNU ld and several other Unix linkers +default -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME)" +</so_link_flags> + +<mach_abi_linking> +amd64 -> "-m64" +mips64 -> "-mabi=64" +s390 -> "-m31" +s390x -> "-m64" +sparc32 -> "-m32 -mno-app-regs" +sparc64 -> "-m64 -mno-app-regs" +ppc64 -> "-m64" + +# This should probably be used on most/all targets, but the docs are incomplete +openbsd -> "-pthread" +freebsd -> "-pthread" +dragonfly -> "-pthread" +netbsd -> "-pthread -D_NETBSD_SOURCE" +qnx -> "-fexceptions -D_QNX_SOURCE" +</mach_abi_linking> diff --git a/src/build-data/cc/compaq.txt b/src/build-data/cc/compaq.txt index 66d3a5219..9ad6514ab 100644 --- a/src/build-data/cc/compaq.txt +++ b/src/build-data/cc/compaq.txt @@ -1,4 +1,4 @@ -realname "Compaq C++" +macro_name "COMPAQ" binary_name "cxx" diff --git a/src/build-data/cc/ekopath.txt b/src/build-data/cc/ekopath.txt index ca2471059..ecd813629 100644 --- a/src/build-data/cc/ekopath.txt +++ b/src/build-data/cc/ekopath.txt @@ -1,4 +1,4 @@ -realname "PathScale EKOPath C++" +macro_name "PATHSCALE" binary_name "pathCC" diff --git a/src/build-data/cc/gcc.txt b/src/build-data/cc/gcc.txt index 978ed6d58..370bb84d7 100644 --- a/src/build-data/cc/gcc.txt +++ b/src/build-data/cc/gcc.txt @@ -1,4 +1,4 @@ -realname "GNU C++" +macro_name "GCC" binary_name "g++" @@ -14,10 +14,11 @@ lang_flags "-D_REENTRANT -ansi -Wno-long-long" warning_flags "-W -Wall" #warning_flags "-Wextra -Wall -Wstrict-aliasing -Wstrict-overflow=5 -Wcast-align -Wmissing-declarations -Wno-unused-parameter" -lib_opt_flags "-O2 -finline-functions" -check_opt_flags "-O2" +lib_opt_flags "-O2" +check_opt_flags "-O" shared_flags "-fPIC" debug_flags "-g" +no_debug_flags "-finline-functions" dll_import_flags "" dll_export_flags "" diff --git a/src/build-data/cc/hpcc.txt b/src/build-data/cc/hpcc.txt index 284e92ca6..5bde87de9 100644 --- a/src/build-data/cc/hpcc.txt +++ b/src/build-data/cc/hpcc.txt @@ -1,4 +1,4 @@ -realname "HP-UX C++" +macro_name "HP_ACC" binary_name "aCC" diff --git a/src/build-data/cc/icc.txt b/src/build-data/cc/icc.txt index 7d8e9682f..628a59e2d 100644 --- a/src/build-data/cc/icc.txt +++ b/src/build-data/cc/icc.txt @@ -1,4 +1,4 @@ -realname "Intel C++" +macro_name "INTEL" binary_name "icpc" diff --git a/src/build-data/cc/kai.txt b/src/build-data/cc/kai.txt index 8585e54e0..d0ff1c28a 100644 --- a/src/build-data/cc/kai.txt +++ b/src/build-data/cc/kai.txt @@ -1,4 +1,4 @@ -realname "KAI C++" +macro_name "KAI" binary_name "KCC" diff --git a/src/build-data/cc/mipspro.txt b/src/build-data/cc/mipspro.txt index b75fc4fb3..c518f4c26 100644 --- a/src/build-data/cc/mipspro.txt +++ b/src/build-data/cc/mipspro.txt @@ -1,4 +1,4 @@ -realname "SGI MIPSPro C++" +macro_name "MIPSPRO" binary_name "CC" diff --git a/src/build-data/cc/msvc.txt b/src/build-data/cc/msvc.txt index 68e4517f8..603ea449b 100644 --- a/src/build-data/cc/msvc.txt +++ b/src/build-data/cc/msvc.txt @@ -1,4 +1,4 @@ -realname "Visual C++" +macro_name "MSVC" binary_name "cl.exe" diff --git a/src/build-data/cc/open64.txt b/src/build-data/cc/open64.txt index b7c1e9e99..e794c755e 100644 --- a/src/build-data/cc/open64.txt +++ b/src/build-data/cc/open64.txt @@ -1,4 +1,4 @@ -realname "Open64" +macro_name "OPEN64" binary_name "openCC" diff --git a/src/build-data/cc/pgi.txt b/src/build-data/cc/pgi.txt index 35f466477..a6d2416ab 100644 --- a/src/build-data/cc/pgi.txt +++ b/src/build-data/cc/pgi.txt @@ -1,4 +1,4 @@ -realname "Portland Group C++" +macro_name "PORTLAND_GROUP" binary_name "pgCC" diff --git a/src/build-data/cc/sgipro64.txt b/src/build-data/cc/sgipro64.txt index 28132ffcc..073f2fec0 100644 --- a/src/build-data/cc/sgipro64.txt +++ b/src/build-data/cc/sgipro64.txt @@ -1,4 +1,4 @@ -realname "SGI Pro64" +macro_name "SGI_PRO64" binary_name "sgiCC" diff --git a/src/build-data/cc/sunwspro.txt b/src/build-data/cc/sunwspro.txt index e1bc0b26f..7065d4129 100644 --- a/src/build-data/cc/sunwspro.txt +++ b/src/build-data/cc/sunwspro.txt @@ -1,4 +1,4 @@ -realname "Sun Workshop Pro C++" +macro_name "SUN_WORKSHOP" binary_name "CC" diff --git a/src/build-data/cc/xlc.txt b/src/build-data/cc/xlc.txt index 64b888421..521624395 100644 --- a/src/build-data/cc/xlc.txt +++ b/src/build-data/cc/xlc.txt @@ -1,4 +1,4 @@ -realname "IBM XL C/C++" +macro_name "IBM_XLC" binary_name "xlC" diff --git a/src/build-data/makefile/python.in b/src/build-data/makefile/python.in new file mode 100644 index 000000000..9658c70ce --- /dev/null +++ b/src/build-data/makefile/python.in @@ -0,0 +1,29 @@ +CXX = g++ + +PYTHON_ROOT = /usr/lib/python%{python_version}/config +PYTHON_INC = -I/usr/include/python%{python_version} +PYTHON_SITE_PACKAGE_DIR = /usr/lib/python%{python_version}/site-packages/ + +PYTHON_FLAGS = -Isrc/wrap/python -Os -fPIC -ftemplate-depth-255 -Wall -Wno-unused $(PYTHON_INC) + +PYTHON_OBJS = %{python_objs} + +BOTAN_PYTHON_MODDIR = build/botan-python + +all: $(BOTAN_PYTHON_MODDIR)/_botan.so + +%{python_build_cmds} + +$(BOTAN_PYTHON_MODDIR)/_botan.so: $(PYTHON_OBJS) + rm -rf $(BOTAN_PYTHON_MODDIR) + mkdir $(BOTAN_PYTHON_MODDIR) + cp src/wrap/python/*.py $(BOTAN_PYTHON_MODDIR) + $(CXX) -shared -o $@ $(PYTHON_OBJS) -L. -L$(PYTHON_ROOT) -lbotan -lboost_python -Wl,-rpath-link,. -Wl,-soname,$@ + +clean: + rm -f $(PYTHON_OBJS) $(BOTAN_PYTHON_MODDIR) + +install: + mkdir -p $(PYTHON_SITE_PACKAGE_DIR)/botan + cp $(BOTAN_PYTHON_MODDIR)/* $(PYTHON_SITE_PACKAGE_DIR)/botan + chmod -R u=rwX,go=rX $(PYTHON_SITE_PACKAGE_DIR)/botan diff --git a/src/build-data/makefile/unix.in b/src/build-data/makefile/unix.in index a48a5a17e..8e0e35b87 100644 --- a/src/build-data/makefile/unix.in +++ b/src/build-data/makefile/unix.in @@ -101,7 +101,7 @@ clean: distclean: clean $(RM_R) %{build_dir} $(RM_R) %{doc_src_dir}/doxygen %{doc_src_dir}/botan.doxy - $(RM) Makefile $(CONFIG_SCRIPT) $(PKGCONFIG) + $(RM) Makefile* $(CONFIG_SCRIPT) $(PKGCONFIG) install: $(LIBRARIES) $(ECHO) "Installing Botan into $(DESTDIR)... " diff --git a/src/build-data/makefile/unix_shr.in b/src/build-data/makefile/unix_shr.in index f718d1160..cfc8e3223 100644 --- a/src/build-data/makefile/unix_shr.in +++ b/src/build-data/makefile/unix_shr.in @@ -115,7 +115,7 @@ clean: distclean: clean $(RM_R) %{build_dir} $(RM_R) %{doc_src_dir}/doxygen %{doc_src_dir}/botan.doxy - $(RM) Makefile $(CONFIG_SCRIPT) $(PKGCONFIG) + $(RM) Makefile* $(CONFIG_SCRIPT) $(PKGCONFIG) install: $(LIBRARIES) $(ECHO) "Installing Botan into $(DESTDIR)... " diff --git a/src/build-data/os/aix.txt b/src/build-data/os/aix.txt index cec818580..0063948c7 100644 --- a/src/build-data/os/aix.txt +++ b/src/build-data/os/aix.txt @@ -1,5 +1,3 @@ -realname "AIX" - os_type unix <supports_shared> diff --git a/src/build-data/os/beos.txt b/src/build-data/os/beos.txt index 2b12792bb..b843bd525 100644 --- a/src/build-data/os/beos.txt +++ b/src/build-data/os/beos.txt @@ -1,5 +1,3 @@ -realname "BeOS" - os_type beos install_root /boot/beos diff --git a/src/build-data/os/cygwin.txt b/src/build-data/os/cygwin.txt index c2aadea98..7290648c2 100644 --- a/src/build-data/os/cygwin.txt +++ b/src/build-data/os/cygwin.txt @@ -1,5 +1,3 @@ -realname "Cygwin" - os_type unix install_root c:\Botan diff --git a/src/build-data/os/darwin.txt b/src/build-data/os/darwin.txt index 298621216..fb18ee191 100644 --- a/src/build-data/os/darwin.txt +++ b/src/build-data/os/darwin.txt @@ -1,5 +1,3 @@ -realname "Darwin / MacOS X" - os_type unix so_suffix dylib diff --git a/src/build-data/os/dragonfly.txt b/src/build-data/os/dragonfly.txt index 7e3663435..6823de5b6 100644 --- a/src/build-data/os/dragonfly.txt +++ b/src/build-data/os/dragonfly.txt @@ -1,5 +1,3 @@ -realname "DragonFly" - os_type unix <target_features> diff --git a/src/build-data/os/freebsd.txt b/src/build-data/os/freebsd.txt index ea96b0c88..6823de5b6 100644 --- a/src/build-data/os/freebsd.txt +++ b/src/build-data/os/freebsd.txt @@ -1,5 +1,3 @@ -realname "FreeBSD" - os_type unix <target_features> diff --git a/src/build-data/os/hpux.txt b/src/build-data/os/hpux.txt index 6e17d3b73..9ff0f7f62 100644 --- a/src/build-data/os/hpux.txt +++ b/src/build-data/os/hpux.txt @@ -1,5 +1,3 @@ -realname "HP-UX" - os_type unix so_suffix sl diff --git a/src/build-data/os/hurd.txt b/src/build-data/os/hurd.txt new file mode 100644 index 000000000..f0ab18a98 --- /dev/null +++ b/src/build-data/os/hurd.txt @@ -0,0 +1,14 @@ +os_type unix + +<target_features> +posix_mlock +</target_features> + +# Is this correct? +<supports_shared> +all +</supports_shared> + +<aliases> +gnu +</aliases> diff --git a/src/build-data/os/irix.txt b/src/build-data/os/irix.txt index fd8b43287..0063948c7 100644 --- a/src/build-data/os/irix.txt +++ b/src/build-data/os/irix.txt @@ -1,5 +1,3 @@ -realname "IRIX" - os_type unix <supports_shared> diff --git a/src/build-data/os/linux.txt b/src/build-data/os/linux.txt index 53528511a..3a92f9dd7 100644 --- a/src/build-data/os/linux.txt +++ b/src/build-data/os/linux.txt @@ -1,5 +1,3 @@ -realname "Linux" - os_type unix <target_features> diff --git a/src/build-data/os/mingw.txt b/src/build-data/os/mingw.txt index eb25017fc..2b7a16cf7 100644 --- a/src/build-data/os/mingw.txt +++ b/src/build-data/os/mingw.txt @@ -1,4 +1,3 @@ -realname "MS Windows (MinGW)" os_type windows obj_suffix o diff --git a/src/build-data/os/netbsd.txt b/src/build-data/os/netbsd.txt index 435d8f5e8..0063948c7 100644 --- a/src/build-data/os/netbsd.txt +++ b/src/build-data/os/netbsd.txt @@ -1,5 +1,3 @@ -realname "NetBSD" - os_type unix <supports_shared> diff --git a/src/build-data/os/openbsd.txt b/src/build-data/os/openbsd.txt index cb44bd115..0063948c7 100644 --- a/src/build-data/os/openbsd.txt +++ b/src/build-data/os/openbsd.txt @@ -1,5 +1,3 @@ -realname "OpenBSD" - os_type unix <supports_shared> diff --git a/src/build-data/os/qnx.txt b/src/build-data/os/qnx.txt index 28bc8dea9..0063948c7 100644 --- a/src/build-data/os/qnx.txt +++ b/src/build-data/os/qnx.txt @@ -1,5 +1,3 @@ -realname "QNX" - os_type unix <supports_shared> diff --git a/src/build-data/os/solaris.txt b/src/build-data/os/solaris.txt index 8610b4898..47b06dcc4 100644 --- a/src/build-data/os/solaris.txt +++ b/src/build-data/os/solaris.txt @@ -1,5 +1,3 @@ -realname "Solaris" - os_type unix <target_features> diff --git a/src/build-data/os/tru64.txt b/src/build-data/os/tru64.txt index e320c1df4..8fc301d79 100644 --- a/src/build-data/os/tru64.txt +++ b/src/build-data/os/tru64.txt @@ -1,5 +1,3 @@ -realname "Tru64" - os_type unix <supports_shared> diff --git a/src/build-data/os/windows.txt b/src/build-data/os/windows.txt index a04d609b8..e2e8bb665 100644 --- a/src/build-data/os/windows.txt +++ b/src/build-data/os/windows.txt @@ -1,5 +1,3 @@ -realname "MS Windows" - os_type windows obj_suffix obj diff --git a/src/cert/cvc/asn1_eac_tm.cpp b/src/cert/cvc/asn1_eac_tm.cpp index 05533b520..947b9e66d 100644 --- a/src/cert/cvc/asn1_eac_tm.cpp +++ b/src/cert/cvc/asn1_eac_tm.cpp @@ -11,53 +11,39 @@ #include <botan/ber_dec.h> #include <botan/charset.h> #include <botan/parsing.h> -#include <ctime> -#include <sstream> +#include <botan/rounding.h> +#include <botan/timer.h> namespace Botan { namespace { -/* -* Convert a time_t to a struct tm -*/ -std::tm get_tm(u64bit timer) - { - std::time_t time_val = static_cast<std::time_t>(timer); - - std::tm* tm_p = std::gmtime(&time_val); - if (tm_p == 0) - throw Encoding_Error("EAC_Time: gmtime could not encode " + - to_string(timer)); - return (*tm_p); - } SecureVector<byte> enc_two_digit(u32bit in) { SecureVector<byte> result; in %= 100; if (in < 10) - { result.append(0x00); - } else { - u32bit y_first_pos = (in - (in%10))/10; + u32bit y_first_pos = round_down(in, 10) / 10; result.append(static_cast<byte>(y_first_pos)); } - u32bit y_sec_pos = in%10; + + u32bit y_sec_pos = in % 10; result.append(static_cast<byte>(y_sec_pos)); return result; } + u32bit dec_two_digit(byte b1, byte b2) { u32bit upper = (u32bit)b1; u32bit lower = (u32bit)b2; - if (upper > 9 || lower > 9) - { - throw Invalid_Argument("u32bit dec_two_digit(byte b1, byte b2): value too large"); - } - return upper*10 + lower; + if(upper > 9 || lower > 9) + throw Invalid_Argument("CVC dec_two_digit value too large"); + + return upper*10 + lower; } } @@ -67,12 +53,11 @@ u32bit dec_two_digit(byte b1, byte b2) EAC_Time::EAC_Time(u64bit timer, ASN1_Tag t) :tag(t) { - std::tm time_info = get_tm(timer); + std::tm time_info = time_t_to_tm(timer); year = time_info.tm_year + 1900; month = time_info.tm_mon + 1; day = time_info.tm_mday; - } /* @@ -272,27 +257,15 @@ bool operator<(const EAC_Time& t1, const EAC_Time& t2) void EAC_Time::decode_from(BER_Decoder& source) { BER_Object obj = source.get_next_object(); - if (obj.type_tag != this->tag) - { - std::string message("decoding type mismatch for EAC_Time, tag is "); - std::stringstream ss; - std::string str_is; - ss << std::hex << obj.type_tag; - ss >> str_is; - message.append(str_is); - message.append(", while it should be "); - std::stringstream ss2; - std::string str_should; - ss2 << std::hex << this->tag; - ss2 >> str_should; - message.append(str_should); - throw Decoding_Error(message); - } - if (obj.value.size() != 6) + if(obj.type_tag != this->tag) + throw BER_Decoding_Error("Tag mismatch when decoding"); + + if(obj.value.size() != 6) { throw Decoding_Error("EAC_Time decoding failed"); } + try { u32bit tmp_year = dec_two_digit(obj.value[0], obj.value[1]); diff --git a/src/cert/cvc/cvc_ca.cpp b/src/cert/cvc/cvc_ca.cpp index 638d3f984..8ca8db0c2 100644 --- a/src/cert/cvc/cvc_ca.cpp +++ b/src/cert/cvc/cvc_ca.cpp @@ -1,7 +1,6 @@ #include <botan/cvc_ca.h> #include <botan/cvc_cert.h> #include <botan/der_enc.h> -#include <botan/util.h> #include <botan/oids.h> namespace Botan { diff --git a/src/cert/cvc/cvc_self.cpp b/src/cert/cvc/cvc_self.cpp index 91ea38724..777347a18 100644 --- a/src/cert/cvc/cvc_self.cpp +++ b/src/cert/cvc/cvc_self.cpp @@ -14,7 +14,7 @@ #include <botan/look_pk.h> #include <botan/cvc_req.h> #include <botan/cvc_ado.h> -#include <botan/util.h> +#include <botan/timer.h> #include <sstream> namespace Botan { diff --git a/src/cert/cvc/info.txt b/src/cert/cvc/info.txt index e3e11f5fe..bdd496614 100644 --- a/src/cert/cvc/info.txt +++ b/src/cert/cvc/info.txt @@ -1,5 +1,3 @@ -realname "Card Verifiable Certificates" - define CARD_VERIFIABLE_CERTIFICATES uses_tr1 yes diff --git a/src/cert/x509/crl_ent.cpp b/src/cert/x509/crl_ent.cpp index afea8cf6b..a8a989c24 100644 --- a/src/cert/x509/crl_ent.cpp +++ b/src/cert/x509/crl_ent.cpp @@ -11,7 +11,7 @@ #include <botan/ber_dec.h> #include <botan/bigint.h> #include <botan/oids.h> -#include <botan/util.h> +#include <botan/timer.h> namespace Botan { diff --git a/src/cert/x509/info.txt b/src/cert/x509/info.txt index 552e2aacb..37faea9fa 100644 --- a/src/cert/x509/info.txt +++ b/src/cert/x509/info.txt @@ -1,5 +1,3 @@ -realname "X.509" - define X509 load_on auto diff --git a/src/cert/x509/x509_ca.cpp b/src/cert/x509/x509_ca.cpp index 41e314724..f0eb9c3e5 100644 --- a/src/cert/x509/x509_ca.cpp +++ b/src/cert/x509/x509_ca.cpp @@ -13,7 +13,7 @@ #include <botan/bigint.h> #include <botan/parsing.h> #include <botan/oids.h> -#include <botan/util.h> +#include <botan/timer.h> #include <algorithm> #include <typeinfo> #include <iterator> diff --git a/src/cert/x509/x509opt.cpp b/src/cert/x509/x509opt.cpp index de9d589a3..03bcd20f4 100644 --- a/src/cert/x509/x509opt.cpp +++ b/src/cert/x509/x509opt.cpp @@ -6,10 +6,9 @@ */ #include <botan/x509self.h> -#include <botan/util.h> -#include <botan/parsing.h> #include <botan/oids.h> -#include <ctime> +#include <botan/parsing.h> +#include <botan/timer.h> namespace Botan { diff --git a/src/cert/x509/x509stor.cpp b/src/cert/x509/x509stor.cpp index cb61bc2d2..40801148c 100644 --- a/src/cert/x509/x509stor.cpp +++ b/src/cert/x509/x509stor.cpp @@ -10,7 +10,7 @@ #include <botan/pubkey.h> #include <botan/look_pk.h> #include <botan/oids.h> -#include <botan/util.h> +#include <botan/timer.h> #include <algorithm> #include <memory> diff --git a/src/checksum/adler32/adler32.h b/src/checksum/adler32/adler32.h index 98a28bc81..79804a842 100644 --- a/src/checksum/adler32/adler32.h +++ b/src/checksum/adler32/adler32.h @@ -18,7 +18,7 @@ namespace Botan { class BOTAN_DLL Adler32 : public HashFunction { public: - void clear() throw() { S1 = 1; S2 = 0; } + void clear() { S1 = 1; S2 = 0; } std::string name() const { return "Adler32"; } HashFunction* clone() const { return new Adler32; } Adler32() : HashFunction(4) { clear(); } diff --git a/src/checksum/adler32/info.txt b/src/checksum/adler32/info.txt index 76662cdec..53bc66354 100644 --- a/src/checksum/adler32/info.txt +++ b/src/checksum/adler32/info.txt @@ -1,5 +1,3 @@ -realname "Adler32" - define ADLER32 load_on auto diff --git a/src/checksum/crc24/crc24.h b/src/checksum/crc24/crc24.h index bca4d0e89..f59ac4a45 100644 --- a/src/checksum/crc24/crc24.h +++ b/src/checksum/crc24/crc24.h @@ -18,7 +18,7 @@ namespace Botan { class BOTAN_DLL CRC24 : public HashFunction { public: - void clear() throw() { crc = 0xB704CE; } + void clear() { crc = 0xB704CE; } std::string name() const { return "CRC24"; } HashFunction* clone() const { return new CRC24; } CRC24() : HashFunction(3) { clear(); } diff --git a/src/checksum/crc24/info.txt b/src/checksum/crc24/info.txt index 33b86a9da..8c61aa58b 100644 --- a/src/checksum/crc24/info.txt +++ b/src/checksum/crc24/info.txt @@ -1,5 +1,3 @@ -realname "CRC-24" - define CRC24 load_on auto diff --git a/src/checksum/crc32/crc32.h b/src/checksum/crc32/crc32.h index 390fb100e..998e8489e 100644 --- a/src/checksum/crc32/crc32.h +++ b/src/checksum/crc32/crc32.h @@ -18,7 +18,7 @@ namespace Botan { class BOTAN_DLL CRC32 : public HashFunction { public: - void clear() throw() { crc = 0xFFFFFFFF; } + void clear() { crc = 0xFFFFFFFF; } std::string name() const { return "CRC32"; } HashFunction* clone() const { return new CRC32; } CRC32() : HashFunction(4) { clear(); } diff --git a/src/checksum/crc32/info.txt b/src/checksum/crc32/info.txt index 15933b375..d86848cf4 100644 --- a/src/checksum/crc32/info.txt +++ b/src/checksum/crc32/info.txt @@ -1,5 +1,3 @@ -realname "CRC-32" - define CRC32 load_on auto diff --git a/src/cms/info.txt b/src/cms/info.txt index 82c31b564..55d559f83 100644 --- a/src/cms/info.txt +++ b/src/cms/info.txt @@ -1,5 +1,3 @@ -realname "CMS" - define CMS load_on auto diff --git a/src/codec/base64/info.txt b/src/codec/base64/info.txt index d4ed80976..1d36b948e 100644 --- a/src/codec/base64/info.txt +++ b/src/codec/base64/info.txt @@ -1,5 +1,3 @@ -realname "Base64 Codec" - define BASE64_CODEC load_on auto diff --git a/src/codec/bzip2/info.txt b/src/codec/bzip2/info.txt index 1be84e405..7fd426f90 100644 --- a/src/codec/bzip2/info.txt +++ b/src/codec/bzip2/info.txt @@ -1,6 +1,5 @@ # This module was written by Peter J. Jones -realname "Bzip2 Compressor" define COMPRESSOR_BZIP2 modset compression diff --git a/src/codec/hex/hex.cpp b/src/codec/hex/hex.cpp index fbacc278b..201c9bfdf 100644 --- a/src/codec/hex/hex.cpp +++ b/src/codec/hex/hex.cpp @@ -13,13 +13,15 @@ namespace Botan { +const u32bit HEX_CODEC_BUFFER_SIZE = 256; + /* * Hex_Encoder Constructor */ Hex_Encoder::Hex_Encoder(bool breaks, u32bit length, Case c) : casing(c), line_length(breaks ? length : 0) { - in.create(64); + in.create(HEX_CODEC_BUFFER_SIZE); out.create(2*in.size()); counter = position = 0; } @@ -29,7 +31,7 @@ Hex_Encoder::Hex_Encoder(bool breaks, u32bit length, Case c) : */ Hex_Encoder::Hex_Encoder(Case c) : casing(c), line_length(0) { - in.create(64); + in.create(HEX_CODEC_BUFFER_SIZE); out.create(2*in.size()); counter = position = 0; } @@ -114,7 +116,7 @@ void Hex_Encoder::end_msg() */ Hex_Decoder::Hex_Decoder(Decoder_Checking c) : checking(c) { - in.create(64); + in.create(HEX_CODEC_BUFFER_SIZE); out.create(in.size() / 2); position = 0; } diff --git a/src/codec/hex/info.txt b/src/codec/hex/info.txt index 512a5de8b..817ff1a00 100644 --- a/src/codec/hex/info.txt +++ b/src/codec/hex/info.txt @@ -1,5 +1,3 @@ -realname "Hex Codec" - define HEX_CODEC load_on auto diff --git a/src/codec/openpgp/info.txt b/src/codec/openpgp/info.txt index 6b30850d0..f7774b147 100644 --- a/src/codec/openpgp/info.txt +++ b/src/codec/openpgp/info.txt @@ -1,5 +1,3 @@ -realname "OpenPGP Codec" - define OPENPGP_CODEC load_on auto diff --git a/src/codec/openpgp/openpgp.cpp b/src/codec/openpgp/openpgp.cpp index 7f9cf5f9c..bfba828af 100644 --- a/src/codec/openpgp/openpgp.cpp +++ b/src/codec/openpgp/openpgp.cpp @@ -7,6 +7,7 @@ #include <botan/openpgp.h> #include <botan/filters.h> +#include <botan/basefilt.h> #include <botan/charset.h> #include <botan/crc24.h> diff --git a/src/codec/pem/info.txt b/src/codec/pem/info.txt index bbe8d4c70..5544e1bb0 100644 --- a/src/codec/pem/info.txt +++ b/src/codec/pem/info.txt @@ -1,5 +1,3 @@ -realname "PEM Codec" - define PEM_CODEC load_on auto diff --git a/src/codec/zlib/info.txt b/src/codec/zlib/info.txt index 9b1c35d84..6556359a8 100644 --- a/src/codec/zlib/info.txt +++ b/src/codec/zlib/info.txt @@ -1,6 +1,3 @@ -realname "Zlib Compressor" -#realname "Zlib/Gzip Compressor" - define COMPRESSOR_ZLIB #define COMPRESSOR_ZLIB,COMPRESSOR_GZIP diff --git a/src/cryptobox/cryptobox.cpp b/src/cryptobox/cryptobox.cpp index c27bbaffa..ba7553c55 100644 --- a/src/cryptobox/cryptobox.cpp +++ b/src/cryptobox/cryptobox.cpp @@ -8,9 +8,8 @@ #include <botan/cryptobox.h> #include <botan/filters.h> #include <botan/pipe.h> -#include <botan/serpent.h> +#include <botan/lookup.h> #include <botan/sha2_64.h> -#include <botan/ctr.h> #include <botan/hmac.h> #include <botan/pbkdf2.h> #include <botan/pem.h> @@ -59,7 +58,7 @@ std::string encrypt(const byte input[], u32bit input_len, InitializationVector iv(mk.begin() + CIPHER_KEY_LEN + MAC_KEY_LEN, CIPHER_IV_LEN); - Pipe pipe(new CTR_BE(new Serpent, cipher_key, iv), + Pipe pipe(get_cipher("Serpent/CTR-BE", cipher_key, iv, ENCRYPTION), new Fork( 0, new MAC_Filter(new HMAC(new SHA_512), @@ -121,7 +120,7 @@ std::string decrypt(const byte input[], u32bit input_len, CIPHER_IV_LEN); Pipe pipe(new Fork( - new CTR_BE(new Serpent, cipher_key, iv), + get_cipher("Serpent/CTR-BE", cipher_key, iv, ENCRYPTION), new MAC_Filter(new HMAC(new SHA_512), mac_key, MAC_OUTPUT_LEN))); diff --git a/src/cryptobox/info.txt b/src/cryptobox/info.txt index b9b98060f..0780f55aa 100644 --- a/src/cryptobox/info.txt +++ b/src/cryptobox/info.txt @@ -1,5 +1,3 @@ -realname "Crypto Box" - load_on auto define CRYPTO_BOX diff --git a/src/engine/amd64_eng/info.txt b/src/engine/amd64_eng/info.txt index 47f891445..03baf76ee 100644 --- a/src/engine/amd64_eng/info.txt +++ b/src/engine/amd64_eng/info.txt @@ -1,5 +1,3 @@ -realname "AMD64 Assembler Engine" - define ENGINE_AMD64_ASSEMBLER load_on dep diff --git a/src/engine/def_engine/def_eng.h b/src/engine/def_engine/def_eng.h index 2d7145480..ba5bee8ef 100644 --- a/src/engine/def_engine/def_eng.h +++ b/src/engine/def_engine/def_eng.h @@ -78,6 +78,11 @@ class BOTAN_DLL Default_Engine : public Engine Algorithm_Factory&) const; }; +Keyed_Filter* get_cipher_mode(const BlockCipher* block_cipher, + Cipher_Dir direction, + const std::string& mode, + const std::string& padding); + } #endif diff --git a/src/engine/def_engine/def_mode.cpp b/src/engine/def_engine/def_mode.cpp index 2b093a0a3..b7373ef84 100644 --- a/src/engine/def_engine/def_mode.cpp +++ b/src/engine/def_engine/def_mode.cpp @@ -32,7 +32,7 @@ #include <botan/ofb.h> #endif -#if defined(BOTAN_HAS_CTR) +#if defined(BOTAN_HAS_CTR_BE) #include <botan/ctr.h> #endif @@ -51,22 +51,22 @@ namespace { /** * Get a block cipher padding method by name */ -BlockCipherModePaddingMethod* get_bc_pad(const std::string& algo_spec) +BlockCipherModePaddingMethod* get_bc_pad(const std::string& algo_spec, + const std::string& def_if_empty) { - SCAN_Name request(algo_spec); - #if defined(BOTAN_HAS_CIPHER_MODE_PADDING) - if(request.algo_name() == "PKCS7") + if(algo_spec == "NoPadding" || (algo_spec == "" && def_if_empty == "NoPadding")) + return new Null_Padding; + + if(algo_spec == "PKCS7" || (algo_spec == "" && def_if_empty == "PKCS7")) return new PKCS7_Padding; - if(request.algo_name() == "OneAndZeros") + if(algo_spec == "OneAndZeros") return new OneAndZeros_Padding; - if(request.algo_name() == "X9.23") + if(algo_spec == "X9.23") return new ANSI_X923_Padding; - if(request.algo_name() == "NoPadding") - return new Null_Padding; #endif throw Algorithm_Not_Found(algo_spec); @@ -74,85 +74,30 @@ BlockCipherModePaddingMethod* get_bc_pad(const std::string& algo_spec) } -/* -* Get a cipher object -*/ -Keyed_Filter* Default_Engine::get_cipher(const std::string& algo_spec, - Cipher_Dir direction, - Algorithm_Factory& af) +Keyed_Filter* get_cipher_mode(const BlockCipher* block_cipher, + Cipher_Dir direction, + const std::string& mode, + const std::string& padding) { - std::vector<std::string> algo_parts = split_on(algo_spec, '/'); - if(algo_parts.empty()) - throw Invalid_Algorithm_Name(algo_spec); - - const std::string cipher_name = algo_parts[0]; - - // check if it is a stream cipher first (easy case) - const StreamCipher* stream_cipher = af.prototype_stream_cipher(cipher_name); - if(stream_cipher) - return new StreamCipher_Filter(stream_cipher->clone()); - - const BlockCipher* block_cipher = af.prototype_block_cipher(cipher_name); - if(!block_cipher) - return 0; - - if(algo_parts.size() != 2 && algo_parts.size() != 3) - return 0; - - std::string mode = algo_parts[1]; - u32bit bits = 0; - - if(mode.find("CFB") != std::string::npos || - mode.find("EAX") != std::string::npos) - { - std::vector<std::string> algo_info = parse_algorithm_name(mode); - mode = algo_info[0]; - if(algo_info.size() == 1) - bits = 8*block_cipher->BLOCK_SIZE; - else if(algo_info.size() == 2) - bits = to_u32bit(algo_info[1]); - else - throw Invalid_Algorithm_Name(algo_spec); - } - - std::string padding; - if(algo_parts.size() == 3) - padding = algo_parts[2]; - else - padding = (mode == "CBC") ? "PKCS7" : "NoPadding"; - - if(mode == "ECB" && padding == "CTS") - return 0; - else if((mode != "CBC" && mode != "ECB") && padding != "NoPadding") - throw Invalid_Algorithm_Name(algo_spec); - #if defined(BOTAN_HAS_OFB) if(mode == "OFB") - return new OFB(block_cipher->clone()); + return new StreamCipher_Filter(new OFB(block_cipher->clone())); #endif -#if defined(BOTAN_HAS_CTR) +#if defined(BOTAN_HAS_CTR_BE) if(mode == "CTR-BE") - return new CTR_BE(block_cipher->clone()); + return new StreamCipher_Filter(new CTR_BE(block_cipher->clone())); #endif #if defined(BOTAN_HAS_ECB) - if(mode == "ECB") - { - if(direction == ENCRYPTION) - return new ECB_Encryption(block_cipher->clone(), get_bc_pad(padding)); - else - return new ECB_Decryption(block_cipher->clone(), get_bc_pad(padding)); - } -#endif - -#if defined(BOTAN_HAS_CFB) - if(mode == "CFB") + if(mode == "ECB" || mode == "") { if(direction == ENCRYPTION) - return new CFB_Encryption(block_cipher->clone(), bits); + return new ECB_Encryption(block_cipher->clone(), + get_bc_pad(padding, "NoPadding")); else - return new CFB_Decryption(block_cipher->clone(), bits); + return new ECB_Decryption(block_cipher->clone(), + get_bc_pad(padding, "NoPadding")); } #endif @@ -173,25 +118,15 @@ Keyed_Filter* Default_Engine::get_cipher(const std::string& algo_spec, #if defined(BOTAN_HAS_CBC) if(direction == ENCRYPTION) return new CBC_Encryption(block_cipher->clone(), - get_bc_pad(padding)); + get_bc_pad(padding, "PKCS7")); else return new CBC_Decryption(block_cipher->clone(), - get_bc_pad(padding)); + get_bc_pad(padding, "PKCS7")); #else return 0; #endif } -#if defined(BOTAN_HAS_EAX) - if(mode == "EAX") - { - if(direction == ENCRYPTION) - return new EAX_Encryption(block_cipher->clone(), bits); - else - return new EAX_Decryption(block_cipher->clone(), bits); - } -#endif - #if defined(BOTAN_HAS_XTS) if(mode == "XTS") { @@ -202,6 +137,86 @@ Keyed_Filter* Default_Engine::get_cipher(const std::string& algo_spec, } #endif + if(mode.find("CFB") != std::string::npos || + mode.find("EAX") != std::string::npos) + { + u32bit bits = 0; + + std::vector<std::string> algo_info = parse_algorithm_name(mode); + std::string mode_name = algo_info[0]; + if(algo_info.size() == 1) + bits = 8*block_cipher->BLOCK_SIZE; + else if(algo_info.size() == 2) + bits = to_u32bit(algo_info[1]); + else + return 0; + +#if defined(BOTAN_HAS_CFB) + if(mode_name == "CFB") + { + if(direction == ENCRYPTION) + return new CFB_Encryption(block_cipher->clone(), bits); + else + return new CFB_Decryption(block_cipher->clone(), bits); + } +#endif + +#if defined(BOTAN_HAS_EAX) + if(mode_name == "EAX") + { + if(direction == ENCRYPTION) + return new EAX_Encryption(block_cipher->clone(), bits); + else + return new EAX_Decryption(block_cipher->clone(), bits); + } +#endif + } + + return 0; + } + +/* +* Get a cipher object +*/ +Keyed_Filter* Default_Engine::get_cipher(const std::string& algo_spec, + Cipher_Dir direction, + Algorithm_Factory& af) + { + std::vector<std::string> algo_parts = split_on(algo_spec, '/'); + if(algo_parts.empty()) + throw Invalid_Algorithm_Name(algo_spec); + + const std::string cipher_name = algo_parts[0]; + + // check if it is a stream cipher first (easy case) + const StreamCipher* stream_cipher = af.prototype_stream_cipher(cipher_name); + if(stream_cipher) + return new StreamCipher_Filter(stream_cipher->clone()); + + const BlockCipher* block_cipher = af.prototype_block_cipher(cipher_name); + if(!block_cipher) + return 0; + + if(algo_parts.size() != 2 && algo_parts.size() != 3) + return 0; + + std::string mode = algo_parts[1]; + + std::string padding; + if(algo_parts.size() == 3) + padding = algo_parts[2]; + else + padding = (mode == "CBC") ? "PKCS7" : "NoPadding"; + + if(mode == "ECB" && padding == "CTS") + return 0; + else if((mode != "CBC" && mode != "ECB") && padding != "NoPadding") + throw Invalid_Algorithm_Name(algo_spec); + + Keyed_Filter* filt = get_cipher_mode(block_cipher, direction, mode, padding); + if(filt) + return filt; + throw Algorithm_Not_Found("get_mode: " + cipher_name + "/" + mode + "/" + padding); } diff --git a/src/engine/def_engine/info.txt b/src/engine/def_engine/info.txt index fd31ee2d0..e307fbf8e 100644 --- a/src/engine/def_engine/info.txt +++ b/src/engine/def_engine/info.txt @@ -1,5 +1,3 @@ -realname "Default Engine" - define DEFAULT_ENGINE load_on auto diff --git a/src/engine/def_engine/lookup_hash.cpp b/src/engine/def_engine/lookup_hash.cpp index 58136fc5a..9b2018736 100644 --- a/src/engine/def_engine/lookup_hash.cpp +++ b/src/engine/def_engine/lookup_hash.cpp @@ -22,6 +22,10 @@ #include <botan/crc32.h> #endif +#if defined(BOTAN_HAS_BMW_512) + #include <botan/bmw_512.h> +#endif + #if defined(BOTAN_HAS_FORK_256) #include <botan/fork256.h> #endif @@ -103,6 +107,11 @@ Default_Engine::find_hash(const SCAN_Name& request, return new CRC32; #endif +#if defined(BOTAN_HAS_BMW_512) + if(request.algo_name() == "BMW-512") + return new BMW_512; +#endif + #if defined(BOTAN_HAS_FORK_256) if(request.algo_name() == "FORK-256") return new FORK_256; diff --git a/src/engine/gnump/info.txt b/src/engine/gnump/info.txt index 67a9bcd70..0805c1ba8 100644 --- a/src/engine/gnump/info.txt +++ b/src/engine/gnump/info.txt @@ -1,5 +1,3 @@ -realname "GMP Engine" - define ENGINE_GNU_MP load_on request diff --git a/src/engine/ia32_eng/info.txt b/src/engine/ia32_eng/info.txt index 3bf2a7f2b..98fd1f2cc 100644 --- a/src/engine/ia32_eng/info.txt +++ b/src/engine/ia32_eng/info.txt @@ -1,5 +1,3 @@ -realname "IA32 Assembler Engine" - define ENGINE_IA32_ASSEMBLER load_on dep diff --git a/src/engine/info.txt b/src/engine/info.txt index eef3c03b6..dcb26d9d6 100644 --- a/src/engine/info.txt +++ b/src/engine/info.txt @@ -1,5 +1,3 @@ -realname "Engines" - define ENGINES load_on auto diff --git a/src/engine/openssl/arc4_openssl.cpp b/src/engine/openssl/arc4_openssl.cpp index 08ed3eb10..793e1faff 100644 --- a/src/engine/openssl/arc4_openssl.cpp +++ b/src/engine/openssl/arc4_openssl.cpp @@ -19,7 +19,7 @@ namespace { class ARC4_OpenSSL : public StreamCipher { public: - void clear() throw() { std::memset(&state, 0, sizeof(state)); } + void clear() { std::memset(&state, 0, sizeof(state)); } std::string name() const; StreamCipher* clone() const { return new ARC4_OpenSSL(SKIP); } diff --git a/src/engine/openssl/info.txt b/src/engine/openssl/info.txt index 3f2f1ab14..9f8c84b31 100644 --- a/src/engine/openssl/info.txt +++ b/src/engine/openssl/info.txt @@ -1,5 +1,3 @@ -realname "OpenSSL Engine" - define ENGINE_OPENSSL load_on request diff --git a/src/engine/openssl/ossl_bc.cpp b/src/engine/openssl/ossl_bc.cpp index 4d3761adb..7fdf54e42 100644 --- a/src/engine/openssl/ossl_bc.cpp +++ b/src/engine/openssl/ossl_bc.cpp @@ -18,7 +18,7 @@ namespace { class EVP_BlockCipher : public BlockCipher { public: - void clear() throw(); + void clear(); std::string name() const { return cipher_name; } BlockCipher* clone() const; EVP_BlockCipher(const EVP_CIPHER*, const std::string&); @@ -27,8 +27,8 @@ class EVP_BlockCipher : public BlockCipher ~EVP_BlockCipher(); private: - void enc(const byte[], byte[]) const; - void dec(const byte[], byte[]) const; + void encrypt_n(const byte in[], byte out[], u32bit blocks) const; + void decrypt_n(const byte in[], byte out[], u32bit blocks) const; void key_schedule(const byte[], u32bit); std::string cipher_name; mutable EVP_CIPHER_CTX encrypt, decrypt; @@ -90,19 +90,21 @@ EVP_BlockCipher::~EVP_BlockCipher() /* * Encrypt a block */ -void EVP_BlockCipher::enc(const byte in[], byte out[]) const +void EVP_BlockCipher::encrypt_n(const byte in[], byte out[], + u32bit blocks) const { int out_len = 0; - EVP_EncryptUpdate(&encrypt, out, &out_len, in, BLOCK_SIZE); + EVP_EncryptUpdate(&encrypt, out, &out_len, in, blocks * BLOCK_SIZE); } /* * Decrypt a block */ -void EVP_BlockCipher::dec(const byte in[], byte out[]) const +void EVP_BlockCipher::decrypt_n(const byte in[], byte out[], + u32bit blocks) const { int out_len = 0; - EVP_DecryptUpdate(&decrypt, out, &out_len, in, BLOCK_SIZE); + EVP_DecryptUpdate(&decrypt, out, &out_len, in, blocks * BLOCK_SIZE); } /* @@ -143,7 +145,7 @@ BlockCipher* EVP_BlockCipher::clone() const /* * Clear memory of sensitive data */ -void EVP_BlockCipher::clear() throw() +void EVP_BlockCipher::clear() { const EVP_CIPHER* algo = EVP_CIPHER_CTX_cipher(&encrypt); @@ -174,7 +176,7 @@ OpenSSL_Engine::find_block_cipher(const SCAN_Name& request, if(request.algo_name() == NAME && request.arg_count() == 0) \ return new EVP_BlockCipher(EVP, NAME, MIN, MAX, MOD); -#if 0 +#if !defined(OPENSSL_NO_AES) /* Using OpenSSL's AES causes crashes inside EVP on x86-64 with OpenSSL 0.9.8g cause is unknown @@ -184,12 +186,36 @@ OpenSSL_Engine::find_block_cipher(const SCAN_Name& request, HANDLE_EVP_CIPHER("AES-256", EVP_aes_256_ecb()); #endif +#if !defined(OPENSSL_NO_DES) HANDLE_EVP_CIPHER("DES", EVP_des_ecb()); HANDLE_EVP_CIPHER_KEYLEN("TripleDES", EVP_des_ede3_ecb(), 16, 24, 8); +#endif +#if !defined(OPENSSL_NO_BF) HANDLE_EVP_CIPHER_KEYLEN("Blowfish", EVP_bf_ecb(), 1, 56, 1); +#endif + +#if !defined(OPENSSL_NO_CAST) HANDLE_EVP_CIPHER_KEYLEN("CAST-128", EVP_cast5_ecb(), 1, 16, 1); +#endif + +#if !defined(OPENSSL_NO_RC2) HANDLE_EVP_CIPHER_KEYLEN("RC2", EVP_rc2_ecb(), 1, 32, 1); +#endif + +#if !defined(OPENSSL_NO_RC5) + if(request.algo_name() == "RC5") + if(request.arg_as_u32bit(0, 12) == 12) + return new EVP_BlockCipher(EVP_rc5_32_12_16_ecb(), "RC5(12)", 1, 32, 1); +#endif + +#if !defined(OPENSSL_NO_IDEA) + HANDLE_EVP_CIPHER("IDEA", EVP_idea_ecb()); +#endif + +#if !defined(OPENSSL_NO_SEED) + HANDLE_EVP_CIPHER("SEED", EVP_seed_ecb()); +#endif #undef HANDLE_EVP_CIPHER #undef HANDLE_EVP_CIPHER_KEYLEN diff --git a/src/engine/openssl/ossl_md.cpp b/src/engine/openssl/ossl_md.cpp index 7c8fb678c..1e01a6f25 100644 --- a/src/engine/openssl/ossl_md.cpp +++ b/src/engine/openssl/ossl_md.cpp @@ -18,7 +18,7 @@ namespace { class EVP_HashFunction : public HashFunction { public: - void clear() throw(); + void clear(); std::string name() const { return algo_name; } HashFunction* clone() const; EVP_HashFunction(const EVP_MD*, const std::string&); @@ -52,7 +52,7 @@ void EVP_HashFunction::final_result(byte output[]) /* * Clear memory of sensitive data */ -void EVP_HashFunction::clear() throw() +void EVP_HashFunction::clear() { const EVP_MD* algo = EVP_MD_CTX_md(&md); EVP_DigestInit_ex(&md, algo, 0); @@ -95,27 +95,41 @@ EVP_HashFunction::~EVP_HashFunction() HashFunction* OpenSSL_Engine::find_hash(const SCAN_Name& request, Algorithm_Factory&) const { -#ifndef OPENSSL_NO_SHA +#if !defined(OPENSSL_NO_SHA) if(request.algo_name() == "SHA-160") return new EVP_HashFunction(EVP_sha1(), "SHA-160"); #endif -#ifndef OPENSSL_NO_MD2 +#if !defined(OPENSSL_NO_SHA256) + if(request.algo_name() == "SHA-224") + return new EVP_HashFunction(EVP_sha224(), "SHA-224"); + if(request.algo_name() == "SHA-256") + return new EVP_HashFunction(EVP_sha256(), "SHA-256"); +#endif + +#if !defined(OPENSSL_NO_SHA512) + if(request.algo_name() == "SHA-384") + return new EVP_HashFunction(EVP_sha384(), "SHA-384"); + if(request.algo_name() == "SHA-512") + return new EVP_HashFunction(EVP_sha512(), "SHA-512"); +#endif + +#if !defined(OPENSSL_NO_MD2) if(request.algo_name() == "MD2") return new EVP_HashFunction(EVP_md2(), "MD2"); #endif -#ifndef OPENSSL_NO_MD4 +#if !defined(OPENSSL_NO_MD4) if(request.algo_name() == "MD4") return new EVP_HashFunction(EVP_md4(), "MD4"); #endif -#ifndef OPENSSL_NO_MD5 +#if !defined(OPENSSL_NO_MD5) if(request.algo_name() == "MD5") return new EVP_HashFunction(EVP_md5(), "MD5"); #endif -#ifndef OPENSSL_NO_RIPEMD +#if !defined(OPENSSL_NO_RIPEMD) if(request.algo_name() == "RIPEMD-160") return new EVP_HashFunction(EVP_ripemd160(), "RIPEMD-160"); #endif diff --git a/src/engine/simd_engine/info.txt b/src/engine/simd_engine/info.txt new file mode 100644 index 000000000..b0523285f --- /dev/null +++ b/src/engine/simd_engine/info.txt @@ -0,0 +1,3 @@ +define ENGINE_SIMD + +load_on dep diff --git a/src/engine/simd_engine/simd_engine.cpp b/src/engine/simd_engine/simd_engine.cpp new file mode 100644 index 000000000..7e15f9ec1 --- /dev/null +++ b/src/engine/simd_engine/simd_engine.cpp @@ -0,0 +1,54 @@ +/** +* SIMD Engine +* (C) 1999-2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/simd_engine.h> +#include <botan/cpuid.h> + +#if defined(BOTAN_HAS_SERPENT_SIMD) + #include <botan/serp_simd.h> +#endif + +#if defined(BOTAN_HAS_XTEA_SIMD) + #include <botan/xtea_simd.h> +#endif + +#if defined(BOTAN_HAS_SHA1_SSE2) + #include <botan/sha1_sse2.h> +#endif + +namespace Botan { + +BlockCipher* +SIMD_Engine::find_block_cipher(const SCAN_Name& request, + Algorithm_Factory&) const + { +#if defined(BOTAN_HAS_SERPENT_SIMD) + if(request.algo_name() == "Serpent") + return new Serpent_SIMD; +#endif + +#if defined(BOTAN_HAS_XTEA_SIMD) + if(request.algo_name() == "XTEA") + return new XTEA_SIMD; +#endif + + return 0; + } + +HashFunction* +SIMD_Engine::find_hash(const SCAN_Name& request, + Algorithm_Factory&) const + { +#if defined(BOTAN_HAS_SHA1_SSE2) + if(request.algo_name() == "SHA-160" && CPUID::has_sse2()) + return new SHA_160_SSE2; +#endif + + return 0; + } + +} diff --git a/src/engine/simd_engine/simd_engine.h b/src/engine/simd_engine/simd_engine.h new file mode 100644 index 000000000..22a58e203 --- /dev/null +++ b/src/engine/simd_engine/simd_engine.h @@ -0,0 +1,29 @@ +/** +* SIMD Assembly Engine +* (C) 1999-2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_SIMD_ENGINE_H__ +#define BOTAN_SIMD_ENGINE_H__ + +#include <botan/engine.h> + +namespace Botan { + +class BOTAN_DLL SIMD_Engine : public Engine + { + public: + std::string provider_name() const { return "simd"; } + private: + BlockCipher* find_block_cipher(const SCAN_Name&, + Algorithm_Factory&) const; + + HashFunction* find_hash(const SCAN_Name& reqeust, + Algorithm_Factory&) const; + }; + +} + +#endif diff --git a/src/engine/sse2_eng/eng_sse2.cpp b/src/engine/sse2_eng/eng_sse2.cpp deleted file mode 100644 index c738b3d96..000000000 --- a/src/engine/sse2_eng/eng_sse2.cpp +++ /dev/null @@ -1,27 +0,0 @@ -/** -* SSE2 Assembly Engine -* (C) 1999-2008 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/eng_sse2.h> - -#if defined(BOTAN_HAS_SHA1_SSE2) - #include <botan/sha1_sse2.h> -#endif - -namespace Botan { - -HashFunction* SSE2_Assembler_Engine::find_hash(const SCAN_Name& request, - Algorithm_Factory&) const - { -#if defined(BOTAN_HAS_SHA1_SSE2) - if(request.algo_name() == "SHA-160") - return new SHA_160_SSE2; -#endif - - return 0; - } - -} diff --git a/src/engine/sse2_eng/eng_sse2.h b/src/engine/sse2_eng/eng_sse2.h deleted file mode 100644 index 129697e8f..000000000 --- a/src/engine/sse2_eng/eng_sse2.h +++ /dev/null @@ -1,26 +0,0 @@ -/** -* SSE2 Assembly Engine -* (C) 1999-2008 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_SSE2_ASM_ENGINE_H__ -#define BOTAN_SSE2_ASM_ENGINE_H__ - -#include <botan/engine.h> - -namespace Botan { - -class BOTAN_DLL SSE2_Assembler_Engine : public Engine - { - public: - std::string provider_name() const { return "sse2"; } - private: - HashFunction* find_hash(const SCAN_Name& reqeust, - Algorithm_Factory&) const; - }; - -} - -#endif diff --git a/src/engine/sse2_eng/info.txt b/src/engine/sse2_eng/info.txt deleted file mode 100644 index 6242c7fee..000000000 --- a/src/engine/sse2_eng/info.txt +++ /dev/null @@ -1,15 +0,0 @@ -realname "SSE2 Assembler Engine" - -define ENGINE_SSE2_ASSEMBLER - -load_on dep - -<add> -eng_sse2.cpp -eng_sse2.h -</add> - -<arch> -ia32 -amd64 -</arch> diff --git a/src/entropy/beos_stats/info.txt b/src/entropy/beos_stats/info.txt index a7e62cfb3..84ecf601d 100644 --- a/src/entropy/beos_stats/info.txt +++ b/src/entropy/beos_stats/info.txt @@ -1,5 +1,3 @@ -realname "BeOS Entropy Source" - define ENTROPY_SRC_BEOS modset beos diff --git a/src/entropy/cryptoapi_rng/info.txt b/src/entropy/cryptoapi_rng/info.txt index 643c67d2e..d7a5dbca0 100644 --- a/src/entropy/cryptoapi_rng/info.txt +++ b/src/entropy/cryptoapi_rng/info.txt @@ -1,5 +1,3 @@ -realname "Win32 CryptoAPI Entropy Source" - define ENTROPY_SRC_CAPI load_on auto modset win32 diff --git a/src/entropy/dev_random/info.txt b/src/entropy/dev_random/info.txt index fddb7ac06..376f3b4ba 100644 --- a/src/entropy/dev_random/info.txt +++ b/src/entropy/dev_random/info.txt @@ -1,5 +1,3 @@ -realname "RNG Device Reader" - define ENTROPY_SRC_DEVICE load_on auto @@ -18,6 +16,7 @@ darwin freebsd dragonfly hpux +hurd irix linux netbsd diff --git a/src/entropy/egd/info.txt b/src/entropy/egd/info.txt index 85ba86c00..77e7197dc 100644 --- a/src/entropy/egd/info.txt +++ b/src/entropy/egd/info.txt @@ -1,5 +1,3 @@ -realname "EGD Entropy Source" - define ENTROPY_SRC_EGD load_on auto diff --git a/src/entropy/info.txt b/src/entropy/info.txt index ec3be5f58..5f3d39dd5 100644 --- a/src/entropy/info.txt +++ b/src/entropy/info.txt @@ -1,5 +1,3 @@ -realname "Entropy Sources" - load_on auto <add> diff --git a/src/entropy/proc_walk/info.txt b/src/entropy/proc_walk/info.txt index db96ccdb8..f6302df1a 100644 --- a/src/entropy/proc_walk/info.txt +++ b/src/entropy/proc_walk/info.txt @@ -1,5 +1,3 @@ -realname "File Tree Walking Entropy Source" - define ENTROPY_SRC_FTW load_on auto @@ -17,6 +15,7 @@ darwin freebsd dragonfly hpux +hurd irix linux openbsd diff --git a/src/entropy/unix_procs/info.txt b/src/entropy/unix_procs/info.txt index 928ec13b3..de88cc1b8 100644 --- a/src/entropy/unix_procs/info.txt +++ b/src/entropy/unix_procs/info.txt @@ -1,5 +1,3 @@ -realname "Generic Unix Entropy Source" - define ENTROPY_SRC_UNIX modset unix,beos diff --git a/src/entropy/win32_stats/info.txt b/src/entropy/win32_stats/info.txt index ca7100923..da8ea72ff 100644 --- a/src/entropy/win32_stats/info.txt +++ b/src/entropy/win32_stats/info.txt @@ -1,5 +1,3 @@ -realname "Win32 Entropy Source" - # Probably not much of an issue anymore #note "This module will not run under NT4" diff --git a/src/filters/algo_filt.cpp b/src/filters/algo_filt.cpp index 23f7a20cf..51bf92380 100644 --- a/src/filters/algo_filt.cpp +++ b/src/filters/algo_filt.cpp @@ -14,20 +14,31 @@ namespace Botan { /* * StreamCipher_Filter Constructor */ -StreamCipher_Filter::StreamCipher_Filter(const std::string& sc_name) : +StreamCipher_Filter::StreamCipher_Filter(StreamCipher* stream_cipher) : buffer(DEFAULT_BUFFERSIZE) { - Algorithm_Factory& af = global_state().algorithm_factory(); - base_ptr = cipher = af.make_stream_cipher(sc_name); + cipher = stream_cipher; } /* * StreamCipher_Filter Constructor */ -StreamCipher_Filter::StreamCipher_Filter(StreamCipher* stream_cipher) : +StreamCipher_Filter::StreamCipher_Filter(StreamCipher* stream_cipher, + const SymmetricKey& key) : buffer(DEFAULT_BUFFERSIZE) { - base_ptr = cipher = stream_cipher; + cipher = stream_cipher; + cipher->set_key(key); + } + +/* +* StreamCipher_Filter Constructor +*/ +StreamCipher_Filter::StreamCipher_Filter(const std::string& sc_name) : + buffer(DEFAULT_BUFFERSIZE) + { + Algorithm_Factory& af = global_state().algorithm_factory(); + cipher = af.make_stream_cipher(sc_name); } /* @@ -38,7 +49,7 @@ StreamCipher_Filter::StreamCipher_Filter(const std::string& sc_name, buffer(DEFAULT_BUFFERSIZE) { Algorithm_Factory& af = global_state().algorithm_factory(); - base_ptr = cipher = af.make_stream_cipher(sc_name); + cipher = af.make_stream_cipher(sc_name); cipher->set_key(key); } @@ -47,7 +58,7 @@ StreamCipher_Filter::StreamCipher_Filter(const std::string& sc_name, */ void StreamCipher_Filter::set_iv(const InitializationVector& iv) { - cipher->resync(iv.begin(), iv.length()); + cipher->set_iv(iv.begin(), iv.length()); } /* @@ -58,7 +69,7 @@ void StreamCipher_Filter::write(const byte input[], u32bit length) while(length) { u32bit copied = std::min(length, buffer.size()); - cipher->encrypt(input, buffer, copied); + cipher->cipher(input, buffer, copied); send(buffer, copied); input += copied; length -= copied; @@ -95,7 +106,7 @@ MAC_Filter::MAC_Filter(const std::string& mac_name, u32bit len) : OUTPUT_LENGTH(len) { Algorithm_Factory& af = global_state().algorithm_factory(); - base_ptr = mac = af.make_mac(mac_name); + mac = af.make_mac(mac_name); } /* @@ -105,7 +116,7 @@ MAC_Filter::MAC_Filter(const std::string& mac_name, const SymmetricKey& key, u32bit len) : OUTPUT_LENGTH(len) { Algorithm_Factory& af = global_state().algorithm_factory(); - base_ptr = mac = af.make_mac(mac_name); + mac = af.make_mac(mac_name); mac->set_key(key); } diff --git a/src/filters/basefilt.cpp b/src/filters/basefilt.cpp index 02dbd8a73..c91a5aa62 100644 --- a/src/filters/basefilt.cpp +++ b/src/filters/basefilt.cpp @@ -50,25 +50,4 @@ Fork::Fork(Filter* filters[], u32bit count) set_next(filters, count); } -/* -* Set the algorithm key -*/ -void Keyed_Filter::set_key(const SymmetricKey& key) - { - if(base_ptr) - base_ptr->set_key(key); - else - throw Invalid_State("Keyed_Filter::set_key: No base algorithm set"); - } - -/* -* Check if a keylength is valid -*/ -bool Keyed_Filter::valid_keylength(u32bit n) const - { - if(base_ptr) - return base_ptr->valid_keylength(n); - throw Invalid_State("Keyed_Filter::valid_keylength: No base algorithm set"); - } - } diff --git a/src/filters/basefilt.h b/src/filters/basefilt.h index 75625abb0..b1bcb1a00 100644 --- a/src/filters/basefilt.h +++ b/src/filters/basefilt.h @@ -9,11 +9,18 @@ #define BOTAN_BASEFILT_H__ #include <botan/filter.h> -#include <botan/sym_algo.h> namespace Botan { /** +* BitBucket is a filter which simply discards all inputs +*/ +struct BitBucket : public Filter + { + void write(const byte[], u32bit) {} + }; + +/** * This class represents Filter chains. A Filter chain is an ordered * concatenation of Filters, the input to a Chain sequentially passes * through all the Filters contained in the Chain. @@ -62,38 +69,6 @@ class BOTAN_DLL Fork : public Fanout_Filter Fork(Filter* filter_arr[], u32bit length); }; -/** -* This class represents keyed filters, i.e. filters that have to be -* fed with a key in order to function. -*/ -class BOTAN_DLL Keyed_Filter : public Filter - { - public: - - /** - * Set the key of this filter. - * @param key the key to set - */ - virtual void set_key(const SymmetricKey& key); - - /** - * Set the initialization vector of this filter. - * @param iv the initialization vector to set - */ - virtual void set_iv(const InitializationVector&) {} - - /** - * Check whether a key length is valid for this filter. - * @param length the key length to be checked for validity - * @return true if the key length is valid, false otherwise - */ - virtual bool valid_keylength(u32bit length) const; - - Keyed_Filter() { base_ptr = 0; } - protected: - SymmetricAlgorithm* base_ptr; - }; - } #endif diff --git a/src/filters/fd_unix/info.txt b/src/filters/fd_unix/info.txt index d87978cb0..bdd9b957f 100644 --- a/src/filters/fd_unix/info.txt +++ b/src/filters/fd_unix/info.txt @@ -1,5 +1,3 @@ -realname "Unix I/O support for Pipe" - define PIPE_UNIXFD_IO modset unix,beos diff --git a/src/filters/filters.h b/src/filters/filters.h index 725651f7d..208332a56 100644 --- a/src/filters/filters.h +++ b/src/filters/filters.h @@ -15,7 +15,9 @@ #include <botan/pipe.h> #include <botan/basefilt.h> +#include <botan/key_filt.h> #include <botan/data_snk.h> + #include <botan/scan_name.h> #if defined(BOTAN_HAS_BASE64_CODEC) @@ -36,24 +38,34 @@ class BOTAN_DLL StreamCipher_Filter : public Keyed_Filter public: /** - * Seek in the stream. - * @param position the position to seek ahead + * Write input data + * @param input data + * @param input_len length of input in bytes */ - void seek(u32bit position) { cipher->seek(position); } + void write(const byte input[], u32bit input_len); - /** - * Find out whether the cipher underlying this filter supports - * resyncing. - * @return true if the cipher supports resyncing - */ - bool supports_resync() const { return (cipher->IV_LENGTH != 0); } + bool valid_iv_length(u32bit iv_len) + { return cipher->valid_iv_length(iv_len); } /** * Set the initialization vector for this filter. * @param iv the initialization vector to set */ void set_iv(const InitializationVector& iv); - void write(const byte[], u32bit); + + /** + * Set the key of this filter. + * @param key the key to set + */ + void set_key(const SymmetricKey& key) { cipher->set_key(key); } + + /** + * Check whether a key length is valid for this filter. + * @param length the key length to be checked for validity + * @return true if the key length is valid, false otherwise + */ + bool valid_keylength(u32bit length) const + { return cipher->valid_keylength(length); } /** * Construct a stream cipher filter. @@ -63,6 +75,13 @@ class BOTAN_DLL StreamCipher_Filter : public Keyed_Filter /** * Construct a stream cipher filter. + * @param cipher_obj a cipher object to use + * @param key the key to use inside this filter + */ + StreamCipher_Filter(StreamCipher* cipher_obj, const SymmetricKey& key); + + /** + * Construct a stream cipher filter. * @param cipher the name of the desired cipher */ StreamCipher_Filter(const std::string& cipher); @@ -126,6 +145,20 @@ class BOTAN_DLL MAC_Filter : public Keyed_Filter void end_msg(); /** + * Set the key of this filter. + * @param key the key to set + */ + void set_key(const SymmetricKey& key) { mac->set_key(key); } + + /** + * Check whether a key length is valid for this filter. + * @param length the key length to be checked for validity + * @return true if the key length is valid, false otherwise + */ + bool valid_keylength(u32bit length) const + { return mac->valid_keylength(length); } + + /** * Construct a MAC filter. The MAC key will be left empty. * @param mac the MAC to use * @param len the output length of this filter. Leave the default @@ -136,7 +169,7 @@ class BOTAN_DLL MAC_Filter : public Keyed_Filter MAC_Filter(MessageAuthenticationCode* mac_obj, u32bit out_len = 0) : OUTPUT_LENGTH(out_len) { - base_ptr = mac = mac_obj; + mac = mac_obj; } /** @@ -152,7 +185,7 @@ class BOTAN_DLL MAC_Filter : public Keyed_Filter const SymmetricKey& key, u32bit out_len = 0) : OUTPUT_LENGTH(out_len) { - base_ptr = mac = mac_obj; + mac = mac_obj; mac->set_key(key); } diff --git a/src/filters/info.txt b/src/filters/info.txt index 79a92a9c5..a76b6b4fe 100644 --- a/src/filters/info.txt +++ b/src/filters/info.txt @@ -1,5 +1,3 @@ -realname "Pipe/Filter" - load_on auto define FILTERS @@ -17,6 +15,7 @@ data_src.h filter.cpp filter.h filters.h +key_filt.h out_buf.cpp out_buf.h pbe.h diff --git a/src/filters/key_filt.h b/src/filters/key_filt.h new file mode 100644 index 000000000..36af91f88 --- /dev/null +++ b/src/filters/key_filt.h @@ -0,0 +1,45 @@ +/* +* Keyed_Filter +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_KEYED_FILTER_H__ +#define BOTAN_KEYED_FILTER_H__ + +#include <botan/filter.h> +#include <botan/sym_algo.h> + +namespace Botan { + +/** +* This class represents keyed filters, i.e. filters that have to be +* fed with a key in order to function. +*/ +class BOTAN_DLL Keyed_Filter : public Filter + { + public: + /** + * Set the key of this filter. + * @param key the key to set + */ + virtual void set_key(const SymmetricKey& key) = 0; + + /** + * Set the initialization vector of this filter. + * @param iv the initialization vector to set + */ + virtual void set_iv(const InitializationVector&) {} + + /** + * Check whether a key length is valid for this filter. + * @param length the key length to be checked for validity + * @return true if the key length is valid, false otherwise + */ + virtual bool valid_keylength(u32bit length) const = 0; + }; + +} + +#endif diff --git a/src/hash/bmw/bmw_512.cpp b/src/hash/bmw/bmw_512.cpp new file mode 100644 index 000000000..5ccb09579 --- /dev/null +++ b/src/hash/bmw/bmw_512.cpp @@ -0,0 +1,202 @@ +/* +* Blue Midnight Wish 512 (Round 2 tweaked) +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/bmw_512.h> +#include <botan/loadstor.h> +#include <botan/rotate.h> + +namespace Botan { + +namespace { + +inline u64bit S0(u64bit X) + { + return (X >> 1) ^ (X << 3) ^ rotate_left(X, 4) ^ rotate_left(X, 37); + } + +inline u64bit S1(u64bit X) + { + return (X >> 1) ^ (X << 2) ^ rotate_left(X, 13) ^ rotate_left(X, 43); + } + +inline u64bit S2(u64bit X) + { + return (X >> 2) ^ (X << 1) ^ rotate_left(X, 19) ^ rotate_left(X, 53); + } + +inline u64bit S3(u64bit X) + { + return (X >> 2) ^ (X << 2) ^ rotate_left(X, 28) ^ rotate_left(X, 59); + } + +inline u64bit S4(u64bit X) + { + return (X >> 1) ^ X; + } + +/** +* Blue Midnight Wish 512 compression function +*/ +void BMW_512_compress(u64bit H[16], const u64bit M[16], u64bit Q[32]) + { + const u32bit EXPAND_1_ROUNDS = 2; + + for(u32bit i = 0; i != 16; ++i) + Q[i] = H[i] ^ M[i]; + + Q[16] = Q[ 5] - Q[ 7] + Q[10] + Q[13] + Q[14]; + Q[17] = Q[ 6] - Q[ 8] + Q[11] + Q[14] - Q[15]; + Q[18] = Q[ 0] + Q[ 7] + Q[ 9] - Q[12] + Q[15]; + Q[19] = Q[ 0] - Q[ 1] + Q[ 8] - Q[10] + Q[13]; + Q[20] = Q[ 1] + Q[ 2] + Q[ 9] - Q[11] - Q[14]; + Q[21] = Q[ 3] - Q[ 2] + Q[10] - Q[12] + Q[15]; + Q[22] = Q[ 4] - Q[ 0] - Q[ 3] - Q[11] + Q[13]; + Q[23] = Q[ 1] - Q[ 4] - Q[ 5] - Q[12] - Q[14]; + Q[24] = Q[ 2] - Q[ 5] - Q[ 6] + Q[13] - Q[15]; + Q[25] = Q[ 0] - Q[ 3] + Q[ 6] - Q[ 7] + Q[14]; + Q[26] = Q[ 8] - Q[ 1] - Q[ 4] - Q[ 7] + Q[15]; + Q[27] = Q[ 8] - Q[ 0] - Q[ 2] - Q[ 5] + Q[ 9]; + Q[28] = Q[ 1] + Q[ 3] - Q[ 6] - Q[ 9] + Q[10]; + Q[29] = Q[ 2] + Q[ 4] + Q[ 7] + Q[10] + Q[11]; + Q[30] = Q[ 3] - Q[ 5] + Q[ 8] - Q[11] - Q[12]; + Q[31] = Q[12] - Q[ 4] - Q[ 6] - Q[ 9] + Q[13]; + + Q[ 0] = S0(Q[16]) + H[ 1]; + Q[ 1] = S1(Q[17]) + H[ 2]; + Q[ 2] = S2(Q[18]) + H[ 3]; + Q[ 3] = S3(Q[19]) + H[ 4]; + Q[ 4] = S4(Q[20]) + H[ 5]; + Q[ 5] = S0(Q[21]) + H[ 6]; + Q[ 6] = S1(Q[22]) + H[ 7]; + Q[ 7] = S2(Q[23]) + H[ 8]; + Q[ 8] = S3(Q[24]) + H[ 9]; + Q[ 9] = S4(Q[25]) + H[10]; + Q[10] = S0(Q[26]) + H[11]; + Q[11] = S1(Q[27]) + H[12]; + Q[12] = S2(Q[28]) + H[13]; + Q[13] = S3(Q[29]) + H[14]; + Q[14] = S4(Q[30]) + H[15]; + Q[15] = S0(Q[31]) + H[ 0]; + + for(u32bit i = 16; i != 16 + EXPAND_1_ROUNDS; ++i) + { + Q[i] = S1(Q[i-16]) + S2(Q[i-15]) + S3(Q[i-14]) + S0(Q[i-13]) + + S1(Q[i-12]) + S2(Q[i-11]) + S3(Q[i-10]) + S0(Q[i- 9]) + + S1(Q[i- 8]) + S2(Q[i- 7]) + S3(Q[i- 6]) + S0(Q[i- 5]) + + S1(Q[i- 4]) + S2(Q[i- 3]) + S3(Q[i- 2]) + S0(Q[i- 1]) + + ((rotate_left(M[(i-16) % 16], ((i-16)%16) + 1) + + rotate_left(M[(i-13) % 16], ((i-13)%16) + 1) - + rotate_left(M[(i- 6) % 16], ((i-6)%16) + 1) + + (0x0555555555555555 * i)) ^ H[(i-16+7)%16]); + } + + for(u32bit i = 16 + EXPAND_1_ROUNDS; i != 32; ++i) + { + Q[i] = Q[i-16] + rotate_left(Q[i-15], 5) + + Q[i-14] + rotate_left(Q[i-13], 11) + + Q[i-12] + rotate_left(Q[i-11], 27) + + Q[i-10] + rotate_left(Q[i- 9], 32) + + Q[i- 8] + rotate_left(Q[i- 7], 37) + + Q[i- 6] + rotate_left(Q[i- 5], 43) + + Q[i- 4] + rotate_left(Q[i- 3], 53) + + S4(Q[i - 2]) + ((Q[i-1] >> 2) ^ Q[i-1]) + + ((rotate_left(M[(i-16) % 16], ((i-16)%16 + 1)) + + rotate_left(M[(i-13) % 16], ((i-13)%16 + 1)) - + rotate_left(M[(i- 6) % 16], ((i-6)%16 + 1)) + + (0x0555555555555555 * i)) ^ H[(i-16+7)%16]); + } + + u64bit XL = Q[16] ^ Q[17] ^ Q[18] ^ Q[19] ^ + Q[20] ^ Q[21] ^ Q[22] ^ Q[23]; + + u64bit XH = Q[24] ^ Q[25] ^ Q[26] ^ Q[27] ^ + Q[28] ^ Q[29] ^ Q[30] ^ Q[31]; + + XH ^= XL; + + H[ 0] = ((XH << 5) ^ (Q[16] >> 5) ^ M[0]) + (XL ^ Q[24] ^ Q[0]); + H[ 1] = ((XH >> 7) ^ (Q[17] << 8) ^ M[1]) + (XL ^ Q[25] ^ Q[1]); + H[ 2] = ((XH >> 5) ^ (Q[18] << 5) ^ M[2]) + (XL ^ Q[26] ^ Q[2]); + H[ 3] = ((XH >> 1) ^ (Q[19] << 5) ^ M[3]) + (XL ^ Q[27] ^ Q[3]); + H[ 4] = ((XH >> 3) ^ (Q[20] ) ^ M[4]) + (XL ^ Q[28] ^ Q[4]); + H[ 5] = ((XH << 6) ^ (Q[21] >> 6) ^ M[5]) + (XL ^ Q[29] ^ Q[5]); + H[ 6] = ((XH >> 4) ^ (Q[22] << 6) ^ M[6]) + (XL ^ Q[30] ^ Q[6]); + H[ 7] = ((XH >> 11) ^ (Q[23] << 2) ^ M[7]) + (XL ^ Q[31] ^ Q[7]); + + H[ 8] = rotate_left(H[4], 9) + (XH ^ Q[24] ^ M[ 8]) + ((XL << 8) ^ Q[23] ^ Q[ 8]); + H[ 9] = rotate_left(H[5], 10) + (XH ^ Q[25] ^ M[ 9]) + ((XL >> 6) ^ Q[16] ^ Q[ 9]); + H[10] = rotate_left(H[6], 11) + (XH ^ Q[26] ^ M[10]) + ((XL << 6) ^ Q[17] ^ Q[10]); + H[11] = rotate_left(H[7], 12) + (XH ^ Q[27] ^ M[11]) + ((XL << 4) ^ Q[18] ^ Q[11]); + H[12] = rotate_left(H[0], 13) + (XH ^ Q[28] ^ M[12]) + ((XL >> 3) ^ Q[19] ^ Q[12]); + H[13] = rotate_left(H[1], 14) + (XH ^ Q[29] ^ M[13]) + ((XL >> 4) ^ Q[20] ^ Q[13]); + H[14] = rotate_left(H[2], 15) + (XH ^ Q[30] ^ M[14]) + ((XL >> 7) ^ Q[21] ^ Q[14]); + H[15] = rotate_left(H[3], 16) + (XH ^ Q[31] ^ M[15]) + ((XL >> 2) ^ Q[22] ^ Q[15]); + } + +} + +void BMW_512::compress_n(const byte input[], u32bit blocks) + { + for(u32bit i = 0; i != blocks; ++i) + { + load_le(M.begin(), input, M.size()); + + BMW_512_compress(H, M, Q); + + input += HASH_BLOCK_SIZE; + } + } + +/* +* Copy out the digest +*/ +void BMW_512::copy_out(byte output[]) + { + u64bit final[16] = { + 0xAAAAAAAAAAAAAAA0, 0xAAAAAAAAAAAAAAA1, + 0xAAAAAAAAAAAAAAA2, 0xAAAAAAAAAAAAAAA3, + 0xAAAAAAAAAAAAAAA4, 0xAAAAAAAAAAAAAAA5, + 0xAAAAAAAAAAAAAAA6, 0xAAAAAAAAAAAAAAA7, + 0xAAAAAAAAAAAAAAA8, 0xAAAAAAAAAAAAAAA9, + 0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAB, + 0xAAAAAAAAAAAAAAAC, 0xAAAAAAAAAAAAAAAD, + 0xAAAAAAAAAAAAAAAE, 0xAAAAAAAAAAAAAAAF }; + + BMW_512_compress(final, H, Q); + + for(u32bit i = 0; i != OUTPUT_LENGTH; i += 8) + store_le(final[8 + i/8], output + i); + } + +/* +* Clear memory of sensitive data +*/ +void BMW_512::clear() + { + MDx_HashFunction::clear(); + M.clear(); + Q.clear(); + + H[ 0] = 0x8081828384858687; + H[ 1] = 0x88898A8B8C8D8E8F; + H[ 2] = 0x9091929394959697; + H[ 3] = 0x98999A9B9C9D9E9F; + H[ 4] = 0xA0A1A2A3A4A5A6A7; + H[ 5] = 0xA8A9AAABACADAEAF; + H[ 6] = 0xB0B1B2B3B4B5B6B7; + H[ 7] = 0xB8B9BABBBCBDBEBF; + H[ 8] = 0xC0C1C2C3C4C5C6C7; + H[ 9] = 0xC8C9CACBCCCDCECF; + H[10] = 0xD0D1D2D3D4D5D6D7; + H[11] = 0xD8D9DADBDCDDDEDF; + H[12] = 0xE0E1E2E3E4E5E6E7; + H[13] = 0xE8E9EAEBECEDEEEF; + H[14] = 0xF0F1F2F3F4F5F6F7; + H[15] = 0xF8F9FAFBFCFDFEFF; + } + +} diff --git a/src/hash/bmw/bmw_512.h b/src/hash/bmw/bmw_512.h new file mode 100644 index 000000000..55cd761a9 --- /dev/null +++ b/src/hash/bmw/bmw_512.h @@ -0,0 +1,32 @@ +/* +* Blue Midnight Wish 512 (Round 2 tweaked) +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_BMW_512_H__ +#define BOTAN_BMW_512_H__ + +#include <botan/mdx_hash.h> + +namespace Botan { + +class BMW_512 : public MDx_HashFunction + { + public: + void clear(); + std::string name() const { return "BMW512"; } + HashFunction* clone() const { return new BMW_512; } + BMW_512() : MDx_HashFunction(64, 128, false, true) { clear(); } + private: + void compress_n(const byte input[], u32bit blocks); + void copy_out(byte output[]); + + SecureBuffer<u64bit, 16> H, M; + SecureBuffer<u64bit, 32> Q; + }; + +} + +#endif diff --git a/src/hash/bmw/info.txt b/src/hash/bmw/info.txt new file mode 100644 index 000000000..7170223d7 --- /dev/null +++ b/src/hash/bmw/info.txt @@ -0,0 +1,5 @@ +define BMW_512 + +<requires> +mdx_hash +</requires> diff --git a/src/hash/fork256/fork256.cpp b/src/hash/fork256/fork256.cpp index f80bff43a..bd85dfd7c 100644 --- a/src/hash/fork256/fork256.cpp +++ b/src/hash/fork256/fork256.cpp @@ -66,9 +66,7 @@ void FORK_256::compress_n(const byte input[], u32bit blocks) G1 = G2 = G3 = G4 = digest[6]; H1 = H2 = H3 = H4 = digest[7]; - for(u32bit j = 0; j != 16; ++j) - M[j] = load_be<u32bit>(input, j); - input += HASH_BLOCK_SIZE; + load_be(M.begin(), input, M.size()); step(A1, B1, C1, D1, E1, F1, G1, H1, M[ 0], M[ 1], DELTA[ 0], DELTA[ 1]); step(A2, B2, C2, D2, E2, F2, G2, H2, M[14], M[15], DELTA[15], DELTA[14]); @@ -118,6 +116,8 @@ void FORK_256::compress_n(const byte input[], u32bit blocks) digest[5] += (F1 + F2) ^ (F3 + F4); digest[6] += (G1 + G2) ^ (G3 + G4); digest[7] += (H1 + H2) ^ (H3 + H4); + + input += HASH_BLOCK_SIZE; } } @@ -133,7 +133,7 @@ void FORK_256::copy_out(byte output[]) /* * Clear memory of sensitive data */ -void FORK_256::clear() throw() +void FORK_256::clear() { MDx_HashFunction::clear(); digest[0] = 0x6A09E667; diff --git a/src/hash/fork256/fork256.h b/src/hash/fork256/fork256.h index 70d336cc9..f535370e6 100644 --- a/src/hash/fork256/fork256.h +++ b/src/hash/fork256/fork256.h @@ -18,7 +18,7 @@ namespace Botan { class BOTAN_DLL FORK_256 : public MDx_HashFunction { public: - void clear() throw(); + void clear(); std::string name() const { return "FORK-256"; } HashFunction* clone() const { return new FORK_256; } FORK_256() : MDx_HashFunction(32, 64, true, true) { clear(); } diff --git a/src/hash/fork256/info.txt b/src/hash/fork256/info.txt index ae0c9f1a4..c2f8c47f2 100644 --- a/src/hash/fork256/info.txt +++ b/src/hash/fork256/info.txt @@ -1,14 +1,5 @@ -realname "FORK-256" - define FORK_256 -load_on auto - -<add> -fork256.cpp -fork256.h -</add> - <requires> mdx_hash </requires> diff --git a/src/hash/gost_3411/gost_3411.cpp b/src/hash/gost_3411/gost_3411.cpp index 3c7f5f92b..16b1311da 100644 --- a/src/hash/gost_3411/gost_3411.cpp +++ b/src/hash/gost_3411/gost_3411.cpp @@ -1,6 +1,8 @@ /* * GOST 34.11 * (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license */ #include <botan/gost_3411.h> @@ -21,7 +23,7 @@ GOST_34_11::GOST_34_11() : position = 0; } -void GOST_34_11::clear() throw() +void GOST_34_11::clear() { cipher.clear(); sum.clear(); @@ -77,12 +79,8 @@ void GOST_34_11::compress_n(const byte input[], u32bit blocks) byte S[32] = { 0 }; u64bit U[4], V[4]; - - for(u32bit j = 0; j != 4; ++j) - { - U[j] = load_be<u64bit>(hash, j); - V[j] = load_be<u64bit>(input + 32*i, j); - } + load_be(U, hash, 4); + load_be(V, input + 32*i, 4); for(u32bit j = 0; j != 4; ++j) { diff --git a/src/hash/gost_3411/gost_3411.h b/src/hash/gost_3411/gost_3411.h index c69555052..7b17bdc1f 100644 --- a/src/hash/gost_3411/gost_3411.h +++ b/src/hash/gost_3411/gost_3411.h @@ -1,6 +1,8 @@ /** * GOST 34.11 * (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license */ #ifndef BOTAN_GOST_3411_H__ @@ -17,7 +19,7 @@ namespace Botan { class BOTAN_DLL GOST_34_11 : public HashFunction { public: - void clear() throw(); + void clear(); std::string name() const { return "GOST-R-34.11-94" ; } HashFunction* clone() const { return new GOST_34_11; } diff --git a/src/hash/gost_3411/info.txt b/src/hash/gost_3411/info.txt index 65b9475e1..c4cb4e1a5 100644 --- a/src/hash/gost_3411/info.txt +++ b/src/hash/gost_3411/info.txt @@ -1,14 +1,5 @@ -realname "GOST 34.11" - define GOST_34_11 -load_on auto - -<add> -gost_3411.cpp -gost_3411.h -</add> - <requires> gost_28147 </requires> diff --git a/src/hash/has160/has160.cpp b/src/hash/has160/has160.cpp index 9a505d31d..ae45418ce 100644 --- a/src/hash/has160/has160.cpp +++ b/src/hash/has160/has160.cpp @@ -60,13 +60,12 @@ inline void F4(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, */ void HAS_160::compress_n(const byte input[], u32bit blocks) { + u32bit A = digest[0], B = digest[1], C = digest[2], + D = digest[3], E = digest[4]; + for(u32bit i = 0; i != blocks; ++i) { - for(u32bit j = 0; j != 16; ++j) - X[j] = load_le<u32bit>(input, j); - - u32bit A = digest[0], B = digest[1], C = digest[2], - D = digest[3], E = digest[4]; + load_le(X.begin(), input, 16); X[16] = X[ 0] ^ X[ 1] ^ X[ 2] ^ X[ 3]; X[17] = X[ 4] ^ X[ 5] ^ X[ 6] ^ X[ 7]; @@ -128,8 +127,13 @@ void HAS_160::compress_n(const byte input[], u32bit blocks) F4(E,A,B,C,D,X[11], 9); F4(D,E,A,B,C,X[ 6],14); F4(C,D,E,A,B,X[ 1], 5); F4(B,C,D,E,A,X[12],13); - digest[0] += A; digest[1] += B; digest[2] += C; - digest[3] += D; digest[4] += E; + A = (digest[0] += A); + B = (digest[1] += B); + C = (digest[2] += C); + D = (digest[3] += D); + E = (digest[4] += E); + + input += HASH_BLOCK_SIZE; } } @@ -145,7 +149,7 @@ void HAS_160::copy_out(byte output[]) /* * Clear memory of sensitive data */ -void HAS_160::clear() throw() +void HAS_160::clear() { MDx_HashFunction::clear(); X.clear(); diff --git a/src/hash/has160/has160.h b/src/hash/has160/has160.h index 44bb63b9d..cae66c93a 100644 --- a/src/hash/has160/has160.h +++ b/src/hash/has160/has160.h @@ -18,7 +18,7 @@ namespace Botan { class BOTAN_DLL HAS_160 : public MDx_HashFunction { public: - void clear() throw(); + void clear(); std::string name() const { return "HAS-160"; } HashFunction* clone() const { return new HAS_160; } HAS_160() : MDx_HashFunction(20, 64, false, true) { clear(); } diff --git a/src/hash/has160/info.txt b/src/hash/has160/info.txt index a945f3225..f862bdb20 100644 --- a/src/hash/has160/info.txt +++ b/src/hash/has160/info.txt @@ -1,14 +1,5 @@ -realname "HAS-160" - define HAS_160 -load_on auto - -<add> -has160.cpp -has160.h -</add> - <requires> mdx_hash </requires> diff --git a/src/hash/hash.h b/src/hash/hash.h index a30234be0..1098951d8 100644 --- a/src/hash/hash.h +++ b/src/hash/hash.h @@ -38,7 +38,7 @@ class BOTAN_DLL HashFunction : public BufferedComputation /** * Reset the internal state of this object. */ - virtual void clear() throw() = 0; + virtual void clear() = 0; HashFunction(u32bit hash_len, u32bit block_len = 0) : BufferedComputation(hash_len), HASH_BLOCK_SIZE(block_len) {} diff --git a/src/hash/info.txt b/src/hash/info.txt index ce55f7ddc..0e45806f8 100644 --- a/src/hash/info.txt +++ b/src/hash/info.txt @@ -1,5 +1,3 @@ -realname "Hash Functions" - load_on auto <add> diff --git a/src/hash/md2/info.txt b/src/hash/md2/info.txt index ff33e1eb3..2359c5df7 100644 --- a/src/hash/md2/info.txt +++ b/src/hash/md2/info.txt @@ -1,10 +1 @@ -realname "MD2" - define MD2 - -load_on auto - -<add> -md2.cpp -md2.h -</add> diff --git a/src/hash/md2/md2.cpp b/src/hash/md2/md2.cpp index c67e72b5a..f03518ec0 100644 --- a/src/hash/md2/md2.cpp +++ b/src/hash/md2/md2.cpp @@ -97,7 +97,7 @@ void MD2::final_result(byte output[]) /** * Clear memory of sensitive data */ -void MD2::clear() throw() +void MD2::clear() { X.clear(); checksum.clear(); diff --git a/src/hash/md2/md2.h b/src/hash/md2/md2.h index 9337c43f4..0a7125759 100644 --- a/src/hash/md2/md2.h +++ b/src/hash/md2/md2.h @@ -18,7 +18,7 @@ namespace Botan { class BOTAN_DLL MD2 : public HashFunction { public: - void clear() throw(); + void clear(); std::string name() const { return "MD2"; } HashFunction* clone() const { return new MD2; } MD2() : HashFunction(16, 16) { clear(); } diff --git a/src/hash/md4/info.txt b/src/hash/md4/info.txt index fc9cbe116..2b276e168 100644 --- a/src/hash/md4/info.txt +++ b/src/hash/md4/info.txt @@ -1,14 +1,5 @@ -realname "MD4" - define MD4 -load_on auto - -<add> -md4.cpp -md4.h -</add> - <requires> mdx_hash </requires> diff --git a/src/hash/md4/md4.cpp b/src/hash/md4/md4.cpp index 39e3c8c41..f573dae25 100644 --- a/src/hash/md4/md4.cpp +++ b/src/hash/md4/md4.cpp @@ -51,35 +51,41 @@ void MD4::compress_n(const byte input[], u32bit blocks) for(u32bit i = 0; i != blocks; ++i) { - for(u32bit j = 0; j != 16; ++j) - M[j] = load_le<u32bit>(input, j); - input += HASH_BLOCK_SIZE; - - FF(A,B,C,D,M[ 0], 3); FF(D,A,B,C,M[ 1], 7); FF(C,D,A,B,M[ 2],11); - FF(B,C,D,A,M[ 3],19); FF(A,B,C,D,M[ 4], 3); FF(D,A,B,C,M[ 5], 7); - FF(C,D,A,B,M[ 6],11); FF(B,C,D,A,M[ 7],19); FF(A,B,C,D,M[ 8], 3); - FF(D,A,B,C,M[ 9], 7); FF(C,D,A,B,M[10],11); FF(B,C,D,A,M[11],19); - FF(A,B,C,D,M[12], 3); FF(D,A,B,C,M[13], 7); FF(C,D,A,B,M[14],11); - FF(B,C,D,A,M[15],19); - - GG(A,B,C,D,M[ 0], 3); GG(D,A,B,C,M[ 4], 5); GG(C,D,A,B,M[ 8], 9); - GG(B,C,D,A,M[12],13); GG(A,B,C,D,M[ 1], 3); GG(D,A,B,C,M[ 5], 5); - GG(C,D,A,B,M[ 9], 9); GG(B,C,D,A,M[13],13); GG(A,B,C,D,M[ 2], 3); - GG(D,A,B,C,M[ 6], 5); GG(C,D,A,B,M[10], 9); GG(B,C,D,A,M[14],13); - GG(A,B,C,D,M[ 3], 3); GG(D,A,B,C,M[ 7], 5); GG(C,D,A,B,M[11], 9); - GG(B,C,D,A,M[15],13); - - HH(A,B,C,D,M[ 0], 3); HH(D,A,B,C,M[ 8], 9); HH(C,D,A,B,M[ 4],11); - HH(B,C,D,A,M[12],15); HH(A,B,C,D,M[ 2], 3); HH(D,A,B,C,M[10], 9); - HH(C,D,A,B,M[ 6],11); HH(B,C,D,A,M[14],15); HH(A,B,C,D,M[ 1], 3); - HH(D,A,B,C,M[ 9], 9); HH(C,D,A,B,M[ 5],11); HH(B,C,D,A,M[13],15); - HH(A,B,C,D,M[ 3], 3); HH(D,A,B,C,M[11], 9); HH(C,D,A,B,M[ 7],11); - HH(B,C,D,A,M[15],15); + load_le(M.begin(), input, M.size()); + + FF(A,B,C,D,M[ 0], 3); FF(D,A,B,C,M[ 1], 7); + FF(C,D,A,B,M[ 2],11); FF(B,C,D,A,M[ 3],19); + FF(A,B,C,D,M[ 4], 3); FF(D,A,B,C,M[ 5], 7); + FF(C,D,A,B,M[ 6],11); FF(B,C,D,A,M[ 7],19); + FF(A,B,C,D,M[ 8], 3); FF(D,A,B,C,M[ 9], 7); + FF(C,D,A,B,M[10],11); FF(B,C,D,A,M[11],19); + FF(A,B,C,D,M[12], 3); FF(D,A,B,C,M[13], 7); + FF(C,D,A,B,M[14],11); FF(B,C,D,A,M[15],19); + + GG(A,B,C,D,M[ 0], 3); GG(D,A,B,C,M[ 4], 5); + GG(C,D,A,B,M[ 8], 9); GG(B,C,D,A,M[12],13); + GG(A,B,C,D,M[ 1], 3); GG(D,A,B,C,M[ 5], 5); + GG(C,D,A,B,M[ 9], 9); GG(B,C,D,A,M[13],13); + GG(A,B,C,D,M[ 2], 3); GG(D,A,B,C,M[ 6], 5); + GG(C,D,A,B,M[10], 9); GG(B,C,D,A,M[14],13); + GG(A,B,C,D,M[ 3], 3); GG(D,A,B,C,M[ 7], 5); + GG(C,D,A,B,M[11], 9); GG(B,C,D,A,M[15],13); + + HH(A,B,C,D,M[ 0], 3); HH(D,A,B,C,M[ 8], 9); + HH(C,D,A,B,M[ 4],11); HH(B,C,D,A,M[12],15); + HH(A,B,C,D,M[ 2], 3); HH(D,A,B,C,M[10], 9); + HH(C,D,A,B,M[ 6],11); HH(B,C,D,A,M[14],15); + HH(A,B,C,D,M[ 1], 3); HH(D,A,B,C,M[ 9], 9); + HH(C,D,A,B,M[ 5],11); HH(B,C,D,A,M[13],15); + HH(A,B,C,D,M[ 3], 3); HH(D,A,B,C,M[11], 9); + HH(C,D,A,B,M[ 7],11); HH(B,C,D,A,M[15],15); A = (digest[0] += A); B = (digest[1] += B); C = (digest[2] += C); D = (digest[3] += D); + + input += HASH_BLOCK_SIZE; } } @@ -95,7 +101,7 @@ void MD4::copy_out(byte output[]) /* * Clear memory of sensitive data */ -void MD4::clear() throw() +void MD4::clear() { MDx_HashFunction::clear(); M.clear(); diff --git a/src/hash/md4/md4.h b/src/hash/md4/md4.h index df6f2292d..0b76a70e4 100644 --- a/src/hash/md4/md4.h +++ b/src/hash/md4/md4.h @@ -18,7 +18,7 @@ namespace Botan { class BOTAN_DLL MD4 : public MDx_HashFunction { public: - void clear() throw(); + void clear(); std::string name() const { return "MD4"; } HashFunction* clone() const { return new MD4; } MD4() : MDx_HashFunction(16, 64, false, true) { clear(); } diff --git a/src/hash/md4_ia32/info.txt b/src/hash/md4_ia32/info.txt index fee7dd1a8..732285c56 100644 --- a/src/hash/md4_ia32/info.txt +++ b/src/hash/md4_ia32/info.txt @@ -1,15 +1,7 @@ -realname "MD4 (IA-32)" - define MD4_IA32 load_on asm_ok -<add> -md4_ia32_imp.S -md4_ia32.cpp -md4_ia32.h -</add> - <arch> ia32 </arch> diff --git a/src/hash/md5/info.txt b/src/hash/md5/info.txt index 525a45ab5..a4ad1462c 100644 --- a/src/hash/md5/info.txt +++ b/src/hash/md5/info.txt @@ -1,14 +1,5 @@ -realname "MD5" - define MD5 -load_on auto - -<add> -md5.cpp -md5.h -</add> - <requires> mdx_hash </requires> diff --git a/src/hash/md5/md5.cpp b/src/hash/md5/md5.cpp index 7c280aab7..8c1e5a8e1 100644 --- a/src/hash/md5/md5.cpp +++ b/src/hash/md5/md5.cpp @@ -64,9 +64,7 @@ void MD5::compress_n(const byte input[], u32bit blocks) for(u32bit i = 0; i != blocks; ++i) { - for(u32bit j = 0; j != 16; ++j) - M[j] = load_le<u32bit>(input, j); - input += HASH_BLOCK_SIZE; + load_le(M.begin(), input, M.size()); FF(A,B,C,D,M[ 0], 7,0xD76AA478); FF(D,A,B,C,M[ 1],12,0xE8C7B756); FF(C,D,A,B,M[ 2],17,0x242070DB); FF(B,C,D,A,M[ 3],22,0xC1BDCEEE); @@ -108,6 +106,8 @@ void MD5::compress_n(const byte input[], u32bit blocks) B = (digest[1] += B); C = (digest[2] += C); D = (digest[3] += D); + + input += HASH_BLOCK_SIZE; } } @@ -123,7 +123,7 @@ void MD5::copy_out(byte output[]) /* * Clear memory of sensitive data */ -void MD5::clear() throw() +void MD5::clear() { MDx_HashFunction::clear(); M.clear(); diff --git a/src/hash/md5/md5.h b/src/hash/md5/md5.h index 85f684d8b..456a02c28 100644 --- a/src/hash/md5/md5.h +++ b/src/hash/md5/md5.h @@ -18,7 +18,7 @@ namespace Botan { class BOTAN_DLL MD5 : public MDx_HashFunction { public: - void clear() throw(); + void clear(); std::string name() const { return "MD5"; } HashFunction* clone() const { return new MD5; } MD5() : MDx_HashFunction(16, 64, false, true) { clear(); } diff --git a/src/hash/md5_ia32/info.txt b/src/hash/md5_ia32/info.txt index ad9923b26..48a8b4a10 100644 --- a/src/hash/md5_ia32/info.txt +++ b/src/hash/md5_ia32/info.txt @@ -1,15 +1,7 @@ -realname "MD5 (IA-32)" - define MD5_IA32 load_on asm_ok -<add> -md5_ia32_imp.S -md5_ia32.cpp -md5_ia32.h -</add> - <arch> ia32 </arch> diff --git a/src/hash/mdx_hash/info.txt b/src/hash/mdx_hash/info.txt index 412c93350..0c30a1a54 100644 --- a/src/hash/mdx_hash/info.txt +++ b/src/hash/mdx_hash/info.txt @@ -1,10 +1,3 @@ -realname "MDx Hash Base" - define MDX_HASH_FUNCTION load_on dep - -<add> -mdx_hash.cpp -mdx_hash.h -</add> diff --git a/src/hash/mdx_hash/mdx_hash.cpp b/src/hash/mdx_hash/mdx_hash.cpp index b630ec227..28402c2c5 100644 --- a/src/hash/mdx_hash/mdx_hash.cpp +++ b/src/hash/mdx_hash/mdx_hash.cpp @@ -28,7 +28,7 @@ MDx_HashFunction::MDx_HashFunction(u32bit hash_len, u32bit block_len, /** * Clear memory of sensitive data */ -void MDx_HashFunction::clear() throw() +void MDx_HashFunction::clear() { buffer.clear(); count = position = 0; diff --git a/src/hash/mdx_hash/mdx_hash.h b/src/hash/mdx_hash/mdx_hash.h index 0c3aa7806..2d70deed3 100644 --- a/src/hash/mdx_hash/mdx_hash.h +++ b/src/hash/mdx_hash/mdx_hash.h @@ -25,7 +25,7 @@ class BOTAN_DLL MDx_HashFunction : public HashFunction void final_result(byte output[]); virtual void compress_n(const byte block[], u32bit block_n) = 0; - void clear() throw(); + void clear(); virtual void copy_out(byte[]) = 0; virtual void write_count(byte[]); private: diff --git a/src/hash/par_hash/info.txt b/src/hash/par_hash/info.txt index 45716aac8..d641a9cee 100644 --- a/src/hash/par_hash/info.txt +++ b/src/hash/par_hash/info.txt @@ -1,10 +1 @@ -realname "Parallel Hash" - define PARALLEL_HASH - -load_on auto - -<add> -par_hash.cpp -par_hash.h -</add> diff --git a/src/hash/par_hash/par_hash.cpp b/src/hash/par_hash/par_hash.cpp index 4b0c7c466..0ba3f5a4f 100644 --- a/src/hash/par_hash/par_hash.cpp +++ b/src/hash/par_hash/par_hash.cpp @@ -77,7 +77,7 @@ HashFunction* Parallel::clone() const /* * Clear memory of sensitive data */ -void Parallel::clear() throw() +void Parallel::clear() { for(u32bit j = 0; j != hashes.size(); ++j) hashes[j]->clear(); diff --git a/src/hash/par_hash/par_hash.h b/src/hash/par_hash/par_hash.h index 7e75c27be..874e491b1 100644 --- a/src/hash/par_hash/par_hash.h +++ b/src/hash/par_hash/par_hash.h @@ -19,7 +19,7 @@ namespace Botan { class BOTAN_DLL Parallel : public HashFunction { public: - void clear() throw(); + void clear(); std::string name() const; HashFunction* clone() const; diff --git a/src/hash/rmd128/info.txt b/src/hash/rmd128/info.txt index 402271da5..11e4181f4 100644 --- a/src/hash/rmd128/info.txt +++ b/src/hash/rmd128/info.txt @@ -1,14 +1,5 @@ -realname "RIPEMD-128" - define RIPEMD_128 -load_on auto - -<add> -rmd128.cpp -rmd128.h -</add> - <requires> mdx_hash </requires> diff --git a/src/hash/rmd128/rmd128.cpp b/src/hash/rmd128/rmd128.cpp index 8b2c0ccf8..7e9da3bdd 100644 --- a/src/hash/rmd128/rmd128.cpp +++ b/src/hash/rmd128/rmd128.cpp @@ -60,18 +60,16 @@ inline void F4(u32bit& A, u32bit B, u32bit C, u32bit D, */ void RIPEMD_128::compress_n(const byte input[], u32bit blocks) { + const u32bit MAGIC2 = 0x5A827999, MAGIC3 = 0x6ED9EBA1, + MAGIC4 = 0x8F1BBCDC, MAGIC5 = 0x50A28BE6, + MAGIC6 = 0x5C4DD124, MAGIC7 = 0x6D703EF3; + for(u32bit i = 0; i != blocks; ++i) { - for(u32bit j = 0; j != 16; ++j) - M[j] = load_le<u32bit>(input, j); - input += HASH_BLOCK_SIZE; + load_le(M.begin(), input, M.size()); u32bit A1 = digest[0], A2 = A1, B1 = digest[1], B2 = B1, - C1 = digest[2], C2 = C1, D1 = digest[3], D2 = D1; - - const u32bit MAGIC2 = 0x5A827999, MAGIC3 = 0x6ED9EBA1, - MAGIC4 = 0x8F1BBCDC, MAGIC5 = 0x50A28BE6, - MAGIC6 = 0x5C4DD124, MAGIC7 = 0x6D703EF3; + C1 = digest[2], C2 = C1, D1 = digest[3], D2 = D1; F1(A1,B1,C1,D1,M[ 0],11 ); F4(A2,B2,C2,D2,M[ 5], 8,MAGIC5); F1(D1,A1,B1,C1,M[ 1],14 ); F4(D2,A2,B2,C2,M[14], 9,MAGIC5); @@ -141,9 +139,13 @@ void RIPEMD_128::compress_n(const byte input[], u32bit blocks) F4(C1,D1,A1,B1,M[ 6], 5,MAGIC4); F1(C2,D2,A2,B2,M[10],15 ); F4(B1,C1,D1,A1,M[ 2],12,MAGIC4); F1(B2,C2,D2,A2,M[14], 8 ); - D2 = digest[1] + C1 + D2; digest[1] = digest[2] + D1 + A2; - digest[2] = digest[3] + A1 + B2; digest[3] = digest[0] + B1 + C2; + D2 = digest[1] + C1 + D2; + digest[1] = digest[2] + D1 + A2; + digest[2] = digest[3] + A1 + B2; + digest[3] = digest[0] + B1 + C2; digest[0] = D2; + + input += HASH_BLOCK_SIZE; } } @@ -159,7 +161,7 @@ void RIPEMD_128::copy_out(byte output[]) /* * Clear memory of sensitive data */ -void RIPEMD_128::clear() throw() +void RIPEMD_128::clear() { MDx_HashFunction::clear(); M.clear(); diff --git a/src/hash/rmd128/rmd128.h b/src/hash/rmd128/rmd128.h index 031ae5746..d9cb4ebb4 100644 --- a/src/hash/rmd128/rmd128.h +++ b/src/hash/rmd128/rmd128.h @@ -18,7 +18,7 @@ namespace Botan { class BOTAN_DLL RIPEMD_128 : public MDx_HashFunction { public: - void clear() throw(); + void clear(); std::string name() const { return "RIPEMD-128"; } HashFunction* clone() const { return new RIPEMD_128; } RIPEMD_128() : MDx_HashFunction(16, 64, false, true) { clear(); } diff --git a/src/hash/rmd160/info.txt b/src/hash/rmd160/info.txt index af4b5c230..28be6854d 100644 --- a/src/hash/rmd160/info.txt +++ b/src/hash/rmd160/info.txt @@ -1,14 +1,5 @@ -realname "RIPEMD-160" - define RIPEMD_160 -load_on auto - -<add> -rmd160.cpp -rmd160.h -</add> - <requires> mdx_hash </requires> diff --git a/src/hash/rmd160/rmd160.cpp b/src/hash/rmd160/rmd160.cpp index 863de8487..5237f1e12 100644 --- a/src/hash/rmd160/rmd160.cpp +++ b/src/hash/rmd160/rmd160.cpp @@ -82,9 +82,7 @@ void RIPEMD_160::compress_n(const byte input[], u32bit blocks) for(u32bit i = 0; i != blocks; ++i) { - for(u32bit j = 0; j != 16; ++j) - M[j] = load_le<u32bit>(input, j); - input += HASH_BLOCK_SIZE; + load_le(M.begin(), input, M.size()); u32bit A1 = digest[0], A2 = A1, B1 = digest[1], B2 = B1, C1 = digest[2], C2 = C1, D1 = digest[3], D2 = D1, @@ -181,6 +179,8 @@ void RIPEMD_160::compress_n(const byte input[], u32bit blocks) digest[3] = digest[4] + A1 + B2; digest[4] = digest[0] + B1 + C2; digest[0] = C1; + + input += HASH_BLOCK_SIZE; } } @@ -196,7 +196,7 @@ void RIPEMD_160::copy_out(byte output[]) /* * Clear memory of sensitive data */ -void RIPEMD_160::clear() throw() +void RIPEMD_160::clear() { MDx_HashFunction::clear(); M.clear(); diff --git a/src/hash/rmd160/rmd160.h b/src/hash/rmd160/rmd160.h index f2babc582..aee007b98 100644 --- a/src/hash/rmd160/rmd160.h +++ b/src/hash/rmd160/rmd160.h @@ -18,7 +18,7 @@ namespace Botan { class BOTAN_DLL RIPEMD_160 : public MDx_HashFunction { public: - void clear() throw(); + void clear(); std::string name() const { return "RIPEMD-160"; } HashFunction* clone() const { return new RIPEMD_160; } RIPEMD_160() : MDx_HashFunction(20, 64, false, true) { clear(); } diff --git a/src/hash/sha1/info.txt b/src/hash/sha1/info.txt index a0ae30b4b..56403db21 100644 --- a/src/hash/sha1/info.txt +++ b/src/hash/sha1/info.txt @@ -1,14 +1,5 @@ -realname "SHA-1" - define SHA1 -load_on auto - -<add> -sha160.cpp -sha160.h -</add> - <requires> mdx_hash </requires> diff --git a/src/hash/sha1/sha160.cpp b/src/hash/sha1/sha160.cpp index 45323a11b..ff44593f6 100644 --- a/src/hash/sha1/sha160.cpp +++ b/src/hash/sha1/sha160.cpp @@ -61,60 +61,71 @@ void SHA_160::compress_n(const byte input[], u32bit blocks) for(u32bit i = 0; i != blocks; ++i) { - for(u32bit j = 0; j != 16; j += 4) - { - W[j ] = load_be<u32bit>(input, j); - W[j+1] = load_be<u32bit>(input, j+1); - W[j+2] = load_be<u32bit>(input, j+2); - W[j+3] = load_be<u32bit>(input, j+3); - } - input += HASH_BLOCK_SIZE; + load_be(W.begin(), input, 16); - for(u32bit j = 16; j != 80; j += 4) + for(u32bit j = 16; j != 80; j += 8) { W[j ] = rotate_left((W[j-3] ^ W[j-8] ^ W[j-14] ^ W[j-16]), 1); W[j+1] = rotate_left((W[j-2] ^ W[j-7] ^ W[j-13] ^ W[j-15]), 1); W[j+2] = rotate_left((W[j-1] ^ W[j-6] ^ W[j-12] ^ W[j-14]), 1); W[j+3] = rotate_left((W[j ] ^ W[j-5] ^ W[j-11] ^ W[j-13]), 1); + W[j+4] = rotate_left((W[j+1] ^ W[j-4] ^ W[j-10] ^ W[j-12]), 1); + W[j+5] = rotate_left((W[j+2] ^ W[j-3] ^ W[j- 9] ^ W[j-11]), 1); + W[j+6] = rotate_left((W[j+3] ^ W[j-2] ^ W[j- 8] ^ W[j-10]), 1); + W[j+7] = rotate_left((W[j+4] ^ W[j-1] ^ W[j- 7] ^ W[j- 9]), 1); } - F1(A,B,C,D,E,W[ 0]); F1(E,A,B,C,D,W[ 1]); F1(D,E,A,B,C,W[ 2]); - F1(C,D,E,A,B,W[ 3]); F1(B,C,D,E,A,W[ 4]); F1(A,B,C,D,E,W[ 5]); - F1(E,A,B,C,D,W[ 6]); F1(D,E,A,B,C,W[ 7]); F1(C,D,E,A,B,W[ 8]); - F1(B,C,D,E,A,W[ 9]); F1(A,B,C,D,E,W[10]); F1(E,A,B,C,D,W[11]); - F1(D,E,A,B,C,W[12]); F1(C,D,E,A,B,W[13]); F1(B,C,D,E,A,W[14]); - F1(A,B,C,D,E,W[15]); F1(E,A,B,C,D,W[16]); F1(D,E,A,B,C,W[17]); - F1(C,D,E,A,B,W[18]); F1(B,C,D,E,A,W[19]); - - F2(A,B,C,D,E,W[20]); F2(E,A,B,C,D,W[21]); F2(D,E,A,B,C,W[22]); - F2(C,D,E,A,B,W[23]); F2(B,C,D,E,A,W[24]); F2(A,B,C,D,E,W[25]); - F2(E,A,B,C,D,W[26]); F2(D,E,A,B,C,W[27]); F2(C,D,E,A,B,W[28]); - F2(B,C,D,E,A,W[29]); F2(A,B,C,D,E,W[30]); F2(E,A,B,C,D,W[31]); - F2(D,E,A,B,C,W[32]); F2(C,D,E,A,B,W[33]); F2(B,C,D,E,A,W[34]); - F2(A,B,C,D,E,W[35]); F2(E,A,B,C,D,W[36]); F2(D,E,A,B,C,W[37]); - F2(C,D,E,A,B,W[38]); F2(B,C,D,E,A,W[39]); - - F3(A,B,C,D,E,W[40]); F3(E,A,B,C,D,W[41]); F3(D,E,A,B,C,W[42]); - F3(C,D,E,A,B,W[43]); F3(B,C,D,E,A,W[44]); F3(A,B,C,D,E,W[45]); - F3(E,A,B,C,D,W[46]); F3(D,E,A,B,C,W[47]); F3(C,D,E,A,B,W[48]); - F3(B,C,D,E,A,W[49]); F3(A,B,C,D,E,W[50]); F3(E,A,B,C,D,W[51]); - F3(D,E,A,B,C,W[52]); F3(C,D,E,A,B,W[53]); F3(B,C,D,E,A,W[54]); - F3(A,B,C,D,E,W[55]); F3(E,A,B,C,D,W[56]); F3(D,E,A,B,C,W[57]); - F3(C,D,E,A,B,W[58]); F3(B,C,D,E,A,W[59]); - - F4(A,B,C,D,E,W[60]); F4(E,A,B,C,D,W[61]); F4(D,E,A,B,C,W[62]); - F4(C,D,E,A,B,W[63]); F4(B,C,D,E,A,W[64]); F4(A,B,C,D,E,W[65]); - F4(E,A,B,C,D,W[66]); F4(D,E,A,B,C,W[67]); F4(C,D,E,A,B,W[68]); - F4(B,C,D,E,A,W[69]); F4(A,B,C,D,E,W[70]); F4(E,A,B,C,D,W[71]); - F4(D,E,A,B,C,W[72]); F4(C,D,E,A,B,W[73]); F4(B,C,D,E,A,W[74]); - F4(A,B,C,D,E,W[75]); F4(E,A,B,C,D,W[76]); F4(D,E,A,B,C,W[77]); - F4(C,D,E,A,B,W[78]); F4(B,C,D,E,A,W[79]); + F1(A, B, C, D, E, W[ 0]); F1(E, A, B, C, D, W[ 1]); + F1(D, E, A, B, C, W[ 2]); F1(C, D, E, A, B, W[ 3]); + F1(B, C, D, E, A, W[ 4]); F1(A, B, C, D, E, W[ 5]); + F1(E, A, B, C, D, W[ 6]); F1(D, E, A, B, C, W[ 7]); + F1(C, D, E, A, B, W[ 8]); F1(B, C, D, E, A, W[ 9]); + F1(A, B, C, D, E, W[10]); F1(E, A, B, C, D, W[11]); + F1(D, E, A, B, C, W[12]); F1(C, D, E, A, B, W[13]); + F1(B, C, D, E, A, W[14]); F1(A, B, C, D, E, W[15]); + F1(E, A, B, C, D, W[16]); F1(D, E, A, B, C, W[17]); + F1(C, D, E, A, B, W[18]); F1(B, C, D, E, A, W[19]); + + F2(A, B, C, D, E, W[20]); F2(E, A, B, C, D, W[21]); + F2(D, E, A, B, C, W[22]); F2(C, D, E, A, B, W[23]); + F2(B, C, D, E, A, W[24]); F2(A, B, C, D, E, W[25]); + F2(E, A, B, C, D, W[26]); F2(D, E, A, B, C, W[27]); + F2(C, D, E, A, B, W[28]); F2(B, C, D, E, A, W[29]); + F2(A, B, C, D, E, W[30]); F2(E, A, B, C, D, W[31]); + F2(D, E, A, B, C, W[32]); F2(C, D, E, A, B, W[33]); + F2(B, C, D, E, A, W[34]); F2(A, B, C, D, E, W[35]); + F2(E, A, B, C, D, W[36]); F2(D, E, A, B, C, W[37]); + F2(C, D, E, A, B, W[38]); F2(B, C, D, E, A, W[39]); + + F3(A, B, C, D, E, W[40]); F3(E, A, B, C, D, W[41]); + F3(D, E, A, B, C, W[42]); F3(C, D, E, A, B, W[43]); + F3(B, C, D, E, A, W[44]); F3(A, B, C, D, E, W[45]); + F3(E, A, B, C, D, W[46]); F3(D, E, A, B, C, W[47]); + F3(C, D, E, A, B, W[48]); F3(B, C, D, E, A, W[49]); + F3(A, B, C, D, E, W[50]); F3(E, A, B, C, D, W[51]); + F3(D, E, A, B, C, W[52]); F3(C, D, E, A, B, W[53]); + F3(B, C, D, E, A, W[54]); F3(A, B, C, D, E, W[55]); + F3(E, A, B, C, D, W[56]); F3(D, E, A, B, C, W[57]); + F3(C, D, E, A, B, W[58]); F3(B, C, D, E, A, W[59]); + + F4(A, B, C, D, E, W[60]); F4(E, A, B, C, D, W[61]); + F4(D, E, A, B, C, W[62]); F4(C, D, E, A, B, W[63]); + F4(B, C, D, E, A, W[64]); F4(A, B, C, D, E, W[65]); + F4(E, A, B, C, D, W[66]); F4(D, E, A, B, C, W[67]); + F4(C, D, E, A, B, W[68]); F4(B, C, D, E, A, W[69]); + F4(A, B, C, D, E, W[70]); F4(E, A, B, C, D, W[71]); + F4(D, E, A, B, C, W[72]); F4(C, D, E, A, B, W[73]); + F4(B, C, D, E, A, W[74]); F4(A, B, C, D, E, W[75]); + F4(E, A, B, C, D, W[76]); F4(D, E, A, B, C, W[77]); + F4(C, D, E, A, B, W[78]); F4(B, C, D, E, A, W[79]); A = (digest[0] += A); B = (digest[1] += B); C = (digest[2] += C); D = (digest[3] += D); E = (digest[4] += E); + + input += HASH_BLOCK_SIZE; } } @@ -130,7 +141,7 @@ void SHA_160::copy_out(byte output[]) /* * Clear memory of sensitive data */ -void SHA_160::clear() throw() +void SHA_160::clear() { MDx_HashFunction::clear(); W.clear(); diff --git a/src/hash/sha1/sha160.h b/src/hash/sha1/sha160.h index 232cf0322..142c6bf17 100644 --- a/src/hash/sha1/sha160.h +++ b/src/hash/sha1/sha160.h @@ -18,7 +18,7 @@ namespace Botan { class BOTAN_DLL SHA_160 : public MDx_HashFunction { public: - void clear() throw(); + void clear(); std::string name() const { return "SHA-160"; } HashFunction* clone() const { return new SHA_160; } SHA_160(); diff --git a/src/hash/sha1_amd64/info.txt b/src/hash/sha1_amd64/info.txt index ddbc7d380..e54b032ca 100644 --- a/src/hash/sha1_amd64/info.txt +++ b/src/hash/sha1_amd64/info.txt @@ -1,15 +1,7 @@ -realname "SHA-1 (x86-64 assembler)" - define SHA1_AMD64 load_on asm_ok -<add> -sha1_amd64_imp.S -sha1_amd64.cpp -sha1_amd64.h -</add> - <arch> amd64 </arch> diff --git a/src/hash/sha1_ia32/info.txt b/src/hash/sha1_ia32/info.txt index bfb321145..0361395fe 100644 --- a/src/hash/sha1_ia32/info.txt +++ b/src/hash/sha1_ia32/info.txt @@ -1,15 +1,7 @@ -realname "SHA-1 (IA-32)" - define SHA1_IA32 load_on asm_ok -<add> -sha1_ia32_imp.S -sha1_ia32.cpp -sha1_ia32.h -</add> - <arch> ia32 </arch> diff --git a/src/hash/sha1_sse2/info.txt b/src/hash/sha1_sse2/info.txt index b8d693b70..ee61076b4 100644 --- a/src/hash/sha1_sse2/info.txt +++ b/src/hash/sha1_sse2/info.txt @@ -1,14 +1,9 @@ -realname "SHA-1 (SSE2)" - define SHA1_SSE2 -load_on auto - -<add> -sha1_sse2_imp.cpp -sha1_sse2.cpp -sha1_sse2.h -</add> +<requires> +sha1 +simd_engine +</requires> <arch> pentium-m @@ -20,9 +15,5 @@ amd64 <cc> gcc icc +msvc </cc> - -<requires> -sha1 -sse2_eng -</requires> diff --git a/src/hash/sha1_sse2/sha1_sse2.cpp b/src/hash/sha1_sse2/sha1_sse2.cpp index dddc06b7b..fc6466dd0 100644 --- a/src/hash/sha1_sse2/sha1_sse2.cpp +++ b/src/hash/sha1_sse2/sha1_sse2.cpp @@ -1,23 +1,278 @@ /* -* SHA-160 (SSE2) -* (C) 1999-2007 Jack Lloyd +* SHA-1 using SSE2 +* (C) 2009 Jack Lloyd * * Distributed under the terms of the Botan license +* +* Based on public domain code by Dean Gaudet <[email protected]> +* Source - http://arctic.org/~dean/crypto/sha1.html */ #include <botan/sha1_sse2.h> +#include <botan/rotate.h> +#include <emmintrin.h> namespace Botan { +namespace { + +/* +First 16 bytes just need byte swapping. Preparing just means +adding in the round constants. +*/ + +#define prep00_15(P, W) \ + do { \ + W = _mm_shufflehi_epi16(W, _MM_SHUFFLE(2, 3, 0, 1)); \ + W = _mm_shufflelo_epi16(W, _MM_SHUFFLE(2, 3, 0, 1)); \ + W = _mm_or_si128(_mm_slli_epi16(W, 8), \ + _mm_srli_epi16(W, 8)); \ + P.u128 = _mm_add_epi32(W, K00_19); \ + } while(0) + +/* +for each multiple of 4, t, we want to calculate this: + +W[t+0] = rol(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16], 1); +W[t+1] = rol(W[t-2] ^ W[t-7] ^ W[t-13] ^ W[t-15], 1); +W[t+2] = rol(W[t-1] ^ W[t-6] ^ W[t-12] ^ W[t-14], 1); +W[t+3] = rol(W[t] ^ W[t-5] ^ W[t-11] ^ W[t-13], 1); + +we'll actually calculate this: + +W[t+0] = rol(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16], 1); +W[t+1] = rol(W[t-2] ^ W[t-7] ^ W[t-13] ^ W[t-15], 1); +W[t+2] = rol(W[t-1] ^ W[t-6] ^ W[t-12] ^ W[t-14], 1); +W[t+3] = rol( 0 ^ W[t-5] ^ W[t-11] ^ W[t-13], 1); +W[t+3] ^= rol(W[t+0], 1); + +the parameters are: + +W0 = &W[t-16]; +W1 = &W[t-12]; +W2 = &W[t- 8]; +W3 = &W[t- 4]; + +and on output: +prepared = W0 + K +W0 = W[t]..W[t+3] +*/ + +/* note that there is a step here where i want to do a rol by 1, which +* normally would look like this: +* +* r1 = psrld r0,$31 +* r0 = pslld r0,$1 +* r0 = por r0,r1 +* +* but instead i do this: +* +* r1 = pcmpltd r0,zero +* r0 = paddd r0,r0 +* r0 = psub r0,r1 +* +* because pcmpltd and paddd are availabe in both MMX units on +* efficeon, pentium-m, and opteron but shifts are available in +* only one unit. +*/ +#define prep(prep, XW0, XW1, XW2, XW3, K) \ + do { \ + __m128i r0, r1, r2, r3; \ + \ + /* load W[t-4] 16-byte aligned, and shift */ \ + r3 = _mm_srli_si128((XW3), 4); \ + r0 = (XW0); \ + /* get high 64-bits of XW0 into low 64-bits */ \ + r1 = _mm_shuffle_epi32((XW0), _MM_SHUFFLE(1,0,3,2)); \ + /* load high 64-bits of r1 */ \ + r1 = _mm_unpacklo_epi64(r1, (XW1)); \ + r2 = (XW2); \ + \ + r0 = _mm_xor_si128(r1, r0); \ + r2 = _mm_xor_si128(r3, r2); \ + r0 = _mm_xor_si128(r2, r0); \ + /* unrotated W[t]..W[t+2] in r0 ... still need W[t+3] */ \ + \ + r2 = _mm_slli_si128(r0, 12); \ + r1 = _mm_cmplt_epi32(r0, _mm_setzero_si128()); \ + r0 = _mm_add_epi32(r0, r0); /* shift left by 1 */ \ + r0 = _mm_sub_epi32(r0, r1); /* r0 has W[t]..W[t+2] */ \ + \ + r3 = _mm_srli_epi32(r2, 30); \ + r2 = _mm_slli_epi32(r2, 2); \ + \ + r0 = _mm_xor_si128(r0, r3); \ + r0 = _mm_xor_si128(r0, r2); /* r0 now has W[t+3] */ \ + \ + (XW0) = r0; \ + (prep).u128 = _mm_add_epi32(r0, K); \ + } while(0) + +/* +* SHA-160 F1 Function +*/ +inline void F1(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg) + { + E += (D ^ (B & (C ^ D))) + msg + rotate_left(A, 5); + B = rotate_left(B, 30); + } + /* -* SHA-160 Compression Function +* SHA-160 F2 Function */ -void SHA_160_SSE2::compress_n(const byte input[], u32bit blocks) +inline void F2(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg) { + E += (B ^ C ^ D) + msg + rotate_left(A, 5); + B = rotate_left(B, 30); + } + +/* +* SHA-160 F3 Function +*/ +inline void F3(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg) + { + E += ((B & C) | ((B | C) & D)) + msg + rotate_left(A, 5); + B = rotate_left(B, 30); + } + +/* +* SHA-160 F4 Function +*/ +inline void F4(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg) + { + E += (B ^ C ^ D) + msg + rotate_left(A, 5); + B = rotate_left(B, 30); + } + +} + +/* +* SHA-160 Compression Function using SSE for message expansion +*/ +void SHA_160_SSE2::compress_n(const byte input_bytes[], u32bit blocks) + { + const __m128i K00_19 = _mm_set1_epi32(0x5A827999); + const __m128i K20_39 = _mm_set1_epi32(0x6ED9EBA1); + const __m128i K40_59 = _mm_set1_epi32(0x8F1BBCDC); + const __m128i K60_79 = _mm_set1_epi32(0xCA62C1D6); + + u32bit A = digest[0], B = digest[1], C = digest[2], + D = digest[3], E = digest[4]; + + const __m128i* input = (const __m128i *)input_bytes; + for(u32bit i = 0; i != blocks; ++i) { - botan_sha1_sse2_compress(digest, reinterpret_cast<const u32bit*>(input)); - input += HASH_BLOCK_SIZE; + + /* I've tried arranging the SSE2 code to be 4, 8, 12, and 16 + * steps ahead of the integer code. 12 steps ahead seems to + * produce the best performance. -dean + * + * Todo: check this is still true on Barcelona and Core2 -Jack + */ + + union v4si { + u32bit u32[4]; + __m128i u128; + }; + + v4si P0, P1, P2; + + __m128i W0 = _mm_loadu_si128(&input[0]); + prep00_15(P0, W0); + + __m128i W1 = _mm_loadu_si128(&input[1]); + prep00_15(P1, W1); + + __m128i W2 = _mm_loadu_si128(&input[2]); + prep00_15(P2, W2); + + __m128i W3 = _mm_loadu_si128(&input[3]); + + F1(A, B, C, D, E, P0.u32[0]); F1(E, A, B, C, D, P0.u32[1]); + F1(D, E, A, B, C, P0.u32[2]); F1(C, D, E, A, B, P0.u32[3]); + prep00_15(P0, W3); + + F1(B, C, D, E, A, P1.u32[0]); F1(A, B, C, D, E, P1.u32[1]); + F1(E, A, B, C, D, P1.u32[2]); F1(D, E, A, B, C, P1.u32[3]); + prep(P1, W0, W1, W2, W3, K00_19); + + F1(C, D, E, A, B, P2.u32[0]); F1(B, C, D, E, A, P2.u32[1]); + F1(A, B, C, D, E, P2.u32[2]); F1(E, A, B, C, D, P2.u32[3]); + prep(P2, W1, W2, W3, W0, K20_39); + + F1(D, E, A, B, C, P0.u32[0]); F1(C, D, E, A, B, P0.u32[1]); + F1(B, C, D, E, A, P0.u32[2]); F1(A, B, C, D, E, P0.u32[3]); + prep(P0, W2, W3, W0, W1, K20_39); + + F1(E, A, B, C, D, P1.u32[0]); F1(D, E, A, B, C, P1.u32[1]); + F1(C, D, E, A, B, P1.u32[2]); F1(B, C, D, E, A, P1.u32[3]); + prep(P1, W3, W0, W1, W2, K20_39); + + F2(A, B, C, D, E, P2.u32[0]); F2(E, A, B, C, D, P2.u32[1]); + F2(D, E, A, B, C, P2.u32[2]); F2(C, D, E, A, B, P2.u32[3]); + prep(P2, W0, W1, W2, W3, K20_39); + + F2(B, C, D, E, A, P0.u32[0]); F2(A, B, C, D, E, P0.u32[1]); + F2(E, A, B, C, D, P0.u32[2]); F2(D, E, A, B, C, P0.u32[3]); + prep(P0, W1, W2, W3, W0, K20_39); + + F2(C, D, E, A, B, P1.u32[0]); F2(B, C, D, E, A, P1.u32[1]); + F2(A, B, C, D, E, P1.u32[2]); F2(E, A, B, C, D, P1.u32[3]); + prep(P1, W2, W3, W0, W1, K40_59); + + F2(D, E, A, B, C, P2.u32[0]); F2(C, D, E, A, B, P2.u32[1]); + F2(B, C, D, E, A, P2.u32[2]); F2(A, B, C, D, E, P2.u32[3]); + prep(P2, W3, W0, W1, W2, K40_59); + + F2(E, A, B, C, D, P0.u32[0]); F2(D, E, A, B, C, P0.u32[1]); + F2(C, D, E, A, B, P0.u32[2]); F2(B, C, D, E, A, P0.u32[3]); + prep(P0, W0, W1, W2, W3, K40_59); + + F3(A, B, C, D, E, P1.u32[0]); F3(E, A, B, C, D, P1.u32[1]); + F3(D, E, A, B, C, P1.u32[2]); F3(C, D, E, A, B, P1.u32[3]); + prep(P1, W1, W2, W3, W0, K40_59); + + F3(B, C, D, E, A, P2.u32[0]); F3(A, B, C, D, E, P2.u32[1]); + F3(E, A, B, C, D, P2.u32[2]); F3(D, E, A, B, C, P2.u32[3]); + prep(P2, W2, W3, W0, W1, K40_59); + + F3(C, D, E, A, B, P0.u32[0]); F3(B, C, D, E, A, P0.u32[1]); + F3(A, B, C, D, E, P0.u32[2]); F3(E, A, B, C, D, P0.u32[3]); + prep(P0, W3, W0, W1, W2, K60_79); + + F3(D, E, A, B, C, P1.u32[0]); F3(C, D, E, A, B, P1.u32[1]); + F3(B, C, D, E, A, P1.u32[2]); F3(A, B, C, D, E, P1.u32[3]); + prep(P1, W0, W1, W2, W3, K60_79); + + F3(E, A, B, C, D, P2.u32[0]); F3(D, E, A, B, C, P2.u32[1]); + F3(C, D, E, A, B, P2.u32[2]); F3(B, C, D, E, A, P2.u32[3]); + prep(P2, W1, W2, W3, W0, K60_79); + + F4(A, B, C, D, E, P0.u32[0]); F4(E, A, B, C, D, P0.u32[1]); + F4(D, E, A, B, C, P0.u32[2]); F4(C, D, E, A, B, P0.u32[3]); + prep(P0, W2, W3, W0, W1, K60_79); + + F4(B, C, D, E, A, P1.u32[0]); F4(A, B, C, D, E, P1.u32[1]); + F4(E, A, B, C, D, P1.u32[2]); F4(D, E, A, B, C, P1.u32[3]); + prep(P1, W3, W0, W1, W2, K60_79); + + F4(C, D, E, A, B, P2.u32[0]); F4(B, C, D, E, A, P2.u32[1]); + F4(A, B, C, D, E, P2.u32[2]); F4(E, A, B, C, D, P2.u32[3]); + + F4(D, E, A, B, C, P0.u32[0]); F4(C, D, E, A, B, P0.u32[1]); + F4(B, C, D, E, A, P0.u32[2]); F4(A, B, C, D, E, P0.u32[3]); + + F4(E, A, B, C, D, P1.u32[0]); F4(D, E, A, B, C, P1.u32[1]); + F4(C, D, E, A, B, P1.u32[2]); F4(B, C, D, E, A, P1.u32[3]); + + A = (digest[0] += A); + B = (digest[1] += B); + C = (digest[2] += C); + D = (digest[3] += D); + E = (digest[4] += E); + + input += (HASH_BLOCK_SIZE / 16); } } diff --git a/src/hash/sha1_sse2/sha1_sse2_imp.cpp b/src/hash/sha1_sse2/sha1_sse2_imp.cpp deleted file mode 100644 index 90a8dccd5..000000000 --- a/src/hash/sha1_sse2/sha1_sse2_imp.cpp +++ /dev/null @@ -1,331 +0,0 @@ -/* this code is public domain. - - * dean gaudet <[email protected]> - - * this code was inspired by this paper: - - * SHA: A Design for Parallel Architectures? - * Antoon Bosselaers, Ren�e Govaerts and Joos Vandewalle - * <http://www.esat.kuleuven.ac.be/~cosicart/pdf/AB-9700.pdf> - - * more information available on this implementation here: - - * http://arctic.org/~dean/crypto/sha1.html - - * version: 2 - */ - -/* - * Lightly modified for Botan, tested under GCC 4.1.1 and ICC 9.1 - * on a Linux/Core2 system. - - */ -#include <botan/sha1_sse2.h> -#include <xmmintrin.h> - -namespace Botan { - -namespace { - -typedef union { - u32bit u32[4]; - __m128i u128; - } v4si __attribute__((aligned(16))); - -static const v4si K00_19 = { { 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999 } }; -static const v4si K20_39 = { { 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1 } }; -static const v4si K40_59 = { { 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc } }; -static const v4si K60_79 = { { 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6 } }; - -#define UNALIGNED 1 -#if UNALIGNED -#define load(p) _mm_loadu_si128(p) -#else -#define load(p) (*p) -#endif - - -/* -the first 16 bytes only need byte swapping - -prepared points to 4x u32bit, 16-byte aligned - -W points to the 4 dwords which need preparing -- -and is overwritten with the swapped bytes -*/ -#define prep00_15(prep, W) do { \ - __m128i r1, r2; \ - \ - r1 = (W); \ - if (1) { \ - r1 = _mm_shufflehi_epi16(r1, _MM_SHUFFLE(2, 3, 0, 1)); \ - r1 = _mm_shufflelo_epi16(r1, _MM_SHUFFLE(2, 3, 0, 1)); \ - r2 = _mm_slli_epi16(r1, 8); \ - r1 = _mm_srli_epi16(r1, 8); \ - r1 = _mm_or_si128(r1, r2); \ - (W) = r1; \ - } \ - (prep).u128 = _mm_add_epi32(K00_19.u128, r1); \ - } while(0) - - - -/* -for each multiple of 4, t, we want to calculate this: - -W[t+0] = rol(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16], 1); -W[t+1] = rol(W[t-2] ^ W[t-7] ^ W[t-13] ^ W[t-15], 1); -W[t+2] = rol(W[t-1] ^ W[t-6] ^ W[t-12] ^ W[t-14], 1); -W[t+3] = rol(W[t] ^ W[t-5] ^ W[t-11] ^ W[t-13], 1); - -we'll actually calculate this: - -W[t+0] = rol(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16], 1); -W[t+1] = rol(W[t-2] ^ W[t-7] ^ W[t-13] ^ W[t-15], 1); -W[t+2] = rol(W[t-1] ^ W[t-6] ^ W[t-12] ^ W[t-14], 1); -W[t+3] = rol( 0 ^ W[t-5] ^ W[t-11] ^ W[t-13], 1); -W[t+3] ^= rol(W[t+0], 1); - -the parameters are: - -W0 = &W[t-16]; -W1 = &W[t-12]; -W2 = &W[t- 8]; -W3 = &W[t- 4]; - -and on output: -prepared = W0 + K -W0 = W[t]..W[t+3] -*/ - -/* note that there is a step here where i want to do a rol by 1, which -* normally would look like this: -* -* r1 = psrld r0,$31 -* r0 = pslld r0,$1 -* r0 = por r0,r1 -* -* but instead i do this: -* -* r1 = pcmpltd r0,zero -* r0 = paddd r0,r0 -* r0 = psub r0,r1 -* -* because pcmpltd and paddd are availabe in both MMX units on -* efficeon, pentium-m, and opteron but shifts are available in -* only one unit. -*/ -#define prep(prep, XW0, XW1, XW2, XW3, K) do { \ - __m128i r0, r1, r2, r3; \ - \ - /* load W[t-4] 16-byte aligned, and shift */ \ - r3 = _mm_srli_si128((XW3), 4); \ - r0 = (XW0); \ - /* get high 64-bits of XW0 into low 64-bits */ \ - r1 = _mm_shuffle_epi32((XW0), _MM_SHUFFLE(1,0,3,2)); \ - /* load high 64-bits of r1 */ \ - r1 = _mm_unpacklo_epi64(r1, (XW1)); \ - r2 = (XW2); \ - \ - r0 = _mm_xor_si128(r1, r0); \ - r2 = _mm_xor_si128(r3, r2); \ - r0 = _mm_xor_si128(r2, r0); \ - /* unrotated W[t]..W[t+2] in r0 ... still need W[t+3] */ \ - \ - r2 = _mm_slli_si128(r0, 12); \ - r1 = _mm_cmplt_epi32(r0, _mm_setzero_si128()); \ - r0 = _mm_add_epi32(r0, r0); /* shift left by 1 */ \ - r0 = _mm_sub_epi32(r0, r1); /* r0 has W[t]..W[t+2] */ \ - \ - r3 = _mm_srli_epi32(r2, 30); \ - r2 = _mm_slli_epi32(r2, 2); \ - \ - r0 = _mm_xor_si128(r0, r3); \ - r0 = _mm_xor_si128(r0, r2); /* r0 now has W[t+3] */ \ - \ - (XW0) = r0; \ - (prep).u128 = _mm_add_epi32(r0, (K).u128); \ - } while(0) - - -static inline u32bit rol(u32bit src, u32bit amt) - { - /* gcc and icc appear to turn this into a rotate */ - return (src << amt) | (src >> (32 - amt)); - } - - -static inline u32bit f00_19(u32bit x, u32bit y, u32bit z) - { - /* FIPS 180-2 says this: (x & y) ^ (~x & z) - * but we can calculate it in fewer steps. - */ - return ((y ^ z) & x) ^ z; - } - - -static inline u32bit f20_39(u32bit x, u32bit y, u32bit z) - { - return (x ^ z) ^ y; - } - - -static inline u32bit f40_59(u32bit x, u32bit y, u32bit z) - { - /* FIPS 180-2 says this: (x & y) ^ (x & z) ^ (y & z) - * but we can calculate it in fewer steps. - */ - return (x & z) | ((x | z) & y); - } - - -static inline u32bit f60_79(u32bit x, u32bit y, u32bit z) - { - return f20_39(x, y, z); - } - -#define step(nn_mm, xa, xb, xc, xd, xe, xt, input) do { \ - (xt) = (input) + f##nn_mm((xb), (xc), (xd)); \ - (xb) = rol((xb), 30); \ - (xt) += ((xe) + rol((xa), 5)); \ - } while(0) - -} - -extern "C" void botan_sha1_sse2_compress(u32bit H[5], - const u32bit* inputu) - { - const __m128i * input = (const __m128i *)inputu; - __m128i W0, W1, W2, W3; - v4si prep0, prep1, prep2; - u32bit a, b, c, d, e, t; - - a = H[0]; - b = H[1]; - c = H[2]; - d = H[3]; - e = H[4]; - - /* i've tried arranging the SSE2 code to be 4, 8, 12, and 16 - * steps ahead of the integer code. 12 steps ahead seems - * to produce the best performance. -dean - */ - W0 = load(&input[0]); - prep00_15(prep0, W0); /* prepare for 00 through 03 */ - W1 = load(&input[1]); - prep00_15(prep1, W1); /* prepare for 04 through 07 */ - W2 = load(&input[2]); - prep00_15(prep2, W2); /* prepare for 08 through 11 */ - - W3 = load(&input[3]); - step(00_19, a, b, c, d, e, t, prep0.u32[0]); /* 00 */ - step(00_19, t, a, b, c, d, e, prep0.u32[1]); /* 01 */ - step(00_19, e, t, a, b, c, d, prep0.u32[2]); /* 02 */ - step(00_19, d, e, t, a, b, c, prep0.u32[3]); /* 03 */ - prep00_15(prep0, W3); - step(00_19, c, d, e, t, a, b, prep1.u32[0]); /* 04 */ - step(00_19, b, c, d, e, t, a, prep1.u32[1]); /* 05 */ - step(00_19, a, b, c, d, e, t, prep1.u32[2]); /* 06 */ - step(00_19, t, a, b, c, d, e, prep1.u32[3]); /* 07 */ - prep(prep1, W0, W1, W2, W3, K00_19); /* prepare for 16 through 19 */ - step(00_19, e, t, a, b, c, d, prep2.u32[0]); /* 08 */ - step(00_19, d, e, t, a, b, c, prep2.u32[1]); /* 09 */ - step(00_19, c, d, e, t, a, b, prep2.u32[2]); /* 10 */ - step(00_19, b, c, d, e, t, a, prep2.u32[3]); /* 11 */ - prep(prep2, W1, W2, W3, W0, K20_39); /* prepare for 20 through 23 */ - step(00_19, a, b, c, d, e, t, prep0.u32[0]); /* 12 */ - step(00_19, t, a, b, c, d, e, prep0.u32[1]); /* 13 */ - step(00_19, e, t, a, b, c, d, prep0.u32[2]); /* 14 */ - step(00_19, d, e, t, a, b, c, prep0.u32[3]); /* 15 */ - prep(prep0, W2, W3, W0, W1, K20_39); - step(00_19, c, d, e, t, a, b, prep1.u32[0]); /* 16 */ - step(00_19, b, c, d, e, t, a, prep1.u32[1]); /* 17 */ - step(00_19, a, b, c, d, e, t, prep1.u32[2]); /* 18 */ - step(00_19, t, a, b, c, d, e, prep1.u32[3]); /* 19 */ - - prep(prep1, W3, W0, W1, W2, K20_39); - step(20_39, e, t, a, b, c, d, prep2.u32[0]); /* 20 */ - step(20_39, d, e, t, a, b, c, prep2.u32[1]); /* 21 */ - step(20_39, c, d, e, t, a, b, prep2.u32[2]); /* 22 */ - step(20_39, b, c, d, e, t, a, prep2.u32[3]); /* 23 */ - prep(prep2, W0, W1, W2, W3, K20_39); - step(20_39, a, b, c, d, e, t, prep0.u32[0]); /* 24 */ - step(20_39, t, a, b, c, d, e, prep0.u32[1]); /* 25 */ - step(20_39, e, t, a, b, c, d, prep0.u32[2]); /* 26 */ - step(20_39, d, e, t, a, b, c, prep0.u32[3]); /* 27 */ - prep(prep0, W1, W2, W3, W0, K20_39); - step(20_39, c, d, e, t, a, b, prep1.u32[0]); /* 28 */ - step(20_39, b, c, d, e, t, a, prep1.u32[1]); /* 29 */ - step(20_39, a, b, c, d, e, t, prep1.u32[2]); /* 30 */ - step(20_39, t, a, b, c, d, e, prep1.u32[3]); /* 31 */ - prep(prep1, W2, W3, W0, W1, K40_59); - step(20_39, e, t, a, b, c, d, prep2.u32[0]); /* 32 */ - step(20_39, d, e, t, a, b, c, prep2.u32[1]); /* 33 */ - step(20_39, c, d, e, t, a, b, prep2.u32[2]); /* 34 */ - step(20_39, b, c, d, e, t, a, prep2.u32[3]); /* 35 */ - prep(prep2, W3, W0, W1, W2, K40_59); - step(20_39, a, b, c, d, e, t, prep0.u32[0]); /* 36 */ - step(20_39, t, a, b, c, d, e, prep0.u32[1]); /* 37 */ - step(20_39, e, t, a, b, c, d, prep0.u32[2]); /* 38 */ - step(20_39, d, e, t, a, b, c, prep0.u32[3]); /* 39 */ - - prep(prep0, W0, W1, W2, W3, K40_59); - step(40_59, c, d, e, t, a, b, prep1.u32[0]); /* 40 */ - step(40_59, b, c, d, e, t, a, prep1.u32[1]); /* 41 */ - step(40_59, a, b, c, d, e, t, prep1.u32[2]); /* 42 */ - step(40_59, t, a, b, c, d, e, prep1.u32[3]); /* 43 */ - prep(prep1, W1, W2, W3, W0, K40_59); - step(40_59, e, t, a, b, c, d, prep2.u32[0]); /* 44 */ - step(40_59, d, e, t, a, b, c, prep2.u32[1]); /* 45 */ - step(40_59, c, d, e, t, a, b, prep2.u32[2]); /* 46 */ - step(40_59, b, c, d, e, t, a, prep2.u32[3]); /* 47 */ - prep(prep2, W2, W3, W0, W1, K40_59); - step(40_59, a, b, c, d, e, t, prep0.u32[0]); /* 48 */ - step(40_59, t, a, b, c, d, e, prep0.u32[1]); /* 49 */ - step(40_59, e, t, a, b, c, d, prep0.u32[2]); /* 50 */ - step(40_59, d, e, t, a, b, c, prep0.u32[3]); /* 51 */ - prep(prep0, W3, W0, W1, W2, K60_79); - step(40_59, c, d, e, t, a, b, prep1.u32[0]); /* 52 */ - step(40_59, b, c, d, e, t, a, prep1.u32[1]); /* 53 */ - step(40_59, a, b, c, d, e, t, prep1.u32[2]); /* 54 */ - step(40_59, t, a, b, c, d, e, prep1.u32[3]); /* 55 */ - prep(prep1, W0, W1, W2, W3, K60_79); - step(40_59, e, t, a, b, c, d, prep2.u32[0]); /* 56 */ - step(40_59, d, e, t, a, b, c, prep2.u32[1]); /* 57 */ - step(40_59, c, d, e, t, a, b, prep2.u32[2]); /* 58 */ - step(40_59, b, c, d, e, t, a, prep2.u32[3]); /* 59 */ - - prep(prep2, W1, W2, W3, W0, K60_79); - step(60_79, a, b, c, d, e, t, prep0.u32[0]); /* 60 */ - step(60_79, t, a, b, c, d, e, prep0.u32[1]); /* 61 */ - step(60_79, e, t, a, b, c, d, prep0.u32[2]); /* 62 */ - step(60_79, d, e, t, a, b, c, prep0.u32[3]); /* 63 */ - prep(prep0, W2, W3, W0, W1, K60_79); - step(60_79, c, d, e, t, a, b, prep1.u32[0]); /* 64 */ - step(60_79, b, c, d, e, t, a, prep1.u32[1]); /* 65 */ - step(60_79, a, b, c, d, e, t, prep1.u32[2]); /* 66 */ - step(60_79, t, a, b, c, d, e, prep1.u32[3]); /* 67 */ - prep(prep1, W3, W0, W1, W2, K60_79); - step(60_79, e, t, a, b, c, d, prep2.u32[0]); /* 68 */ - step(60_79, d, e, t, a, b, c, prep2.u32[1]); /* 69 */ - step(60_79, c, d, e, t, a, b, prep2.u32[2]); /* 70 */ - step(60_79, b, c, d, e, t, a, prep2.u32[3]); /* 71 */ - - step(60_79, a, b, c, d, e, t, prep0.u32[0]); /* 72 */ - step(60_79, t, a, b, c, d, e, prep0.u32[1]); /* 73 */ - step(60_79, e, t, a, b, c, d, prep0.u32[2]); /* 74 */ - step(60_79, d, e, t, a, b, c, prep0.u32[3]); /* 75 */ - /* no more input to prepare */ - step(60_79, c, d, e, t, a, b, prep1.u32[0]); /* 76 */ - step(60_79, b, c, d, e, t, a, prep1.u32[1]); /* 77 */ - step(60_79, a, b, c, d, e, t, prep1.u32[2]); /* 78 */ - step(60_79, t, a, b, c, d, e, prep1.u32[3]); /* 79 */ - /* e, t, a, b, c, d */ - H[0] += e; - H[1] += t; - H[2] += a; - H[3] += b; - H[4] += c; - } - -} diff --git a/src/hash/sha2/info.txt b/src/hash/sha2/info.txt index 9b92ff385..e12f2b694 100644 --- a/src/hash/sha2/info.txt +++ b/src/hash/sha2/info.txt @@ -1,16 +1,5 @@ -realname "SHA-2 (224, 256, 384, 512)" - define SHA2 -load_on auto - -<add> -sha2_32.cpp -sha2_32.h -sha2_64.cpp -sha2_64.h -</add> - <requires> mdx_hash </requires> diff --git a/src/hash/sha2/sha2_32.cpp b/src/hash/sha2/sha2_32.cpp index 9da2ec23f..7068dd63f 100644 --- a/src/hash/sha2/sha2_32.cpp +++ b/src/hash/sha2/sha2_32.cpp @@ -56,13 +56,27 @@ void SHA_224_256_BASE::compress_n(const byte input[], u32bit blocks) for(u32bit i = 0; i != blocks; ++i) { - for(u32bit j = 0; j != 16; ++j) - W[j] = load_be<u32bit>(input, j); - input += HASH_BLOCK_SIZE; - - for(u32bit j = 16; j != 64; ++j) - W[j] = sigma(W[j- 2], 17, 19, 10) + W[j- 7] + - sigma(W[j-15], 7, 18, 3) + W[j-16]; + load_be(W.begin(), input, 16); + + for(u32bit j = 16; j != 64; j += 8) + { + W[j ] = sigma(W[j- 2], 17, 19, 10) + W[j-7] + + sigma(W[j-15], 7, 18, 3) + W[j-16]; + W[j+1] = sigma(W[j- 1], 17, 19, 10) + W[j-6] + + sigma(W[j-14], 7, 18, 3) + W[j-15]; + W[j+2] = sigma(W[j ], 17, 19, 10) + W[j-5] + + sigma(W[j-13], 7, 18, 3) + W[j-14]; + W[j+3] = sigma(W[j+ 1], 17, 19, 10) + W[j-4] + + sigma(W[j-12], 7, 18, 3) + W[j-13]; + W[j+4] = sigma(W[j+ 2], 17, 19, 10) + W[j-3] + + sigma(W[j-11], 7, 18, 3) + W[j-12]; + W[j+5] = sigma(W[j+ 3], 17, 19, 10) + W[j-2] + + sigma(W[j-10], 7, 18, 3) + W[j-11]; + W[j+6] = sigma(W[j+ 4], 17, 19, 10) + W[j-1] + + sigma(W[j- 9], 7, 18, 3) + W[j-10]; + W[j+7] = sigma(W[j+ 5], 17, 19, 10) + W[j ] + + sigma(W[j- 8], 7, 18, 3) + W[j- 9]; + } F1(A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98); F1(H, A, B, C, D, E, F, G, W[ 1], 0x71374491); @@ -137,6 +151,8 @@ void SHA_224_256_BASE::compress_n(const byte input[], u32bit blocks) F = (digest[5] += F); G = (digest[6] += G); H = (digest[7] += H); + + input += HASH_BLOCK_SIZE; } } @@ -152,7 +168,7 @@ void SHA_224_256_BASE::copy_out(byte output[]) /* * Clear memory of sensitive data */ -void SHA_224_256_BASE::clear() throw() +void SHA_224_256_BASE::clear() { MDx_HashFunction::clear(); W.clear(); @@ -161,23 +177,23 @@ void SHA_224_256_BASE::clear() throw() /* * Clear memory of sensitive data */ -void SHA_224::clear() throw() +void SHA_224::clear() { SHA_224_256_BASE::clear(); - digest[0] = 0xc1059ed8; - digest[1] = 0x367cd507; - digest[2] = 0x3070dd17; - digest[3] = 0xf70e5939; - digest[4] = 0xffc00b31; + digest[0] = 0xC1059ED8; + digest[1] = 0x367CD507; + digest[2] = 0x3070DD17; + digest[3] = 0xF70E5939; + digest[4] = 0xFFC00B31; digest[5] = 0x68581511; - digest[6] = 0x64f98fa7; - digest[7] = 0xbefa4fa4; + digest[6] = 0x64F98FA7; + digest[7] = 0xBEFA4FA4; } /* * Clear memory of sensitive data */ -void SHA_256::clear() throw() +void SHA_256::clear() { SHA_224_256_BASE::clear(); digest[0] = 0x6A09E667; diff --git a/src/hash/sha2/sha2_32.h b/src/hash/sha2/sha2_32.h index 05083d19d..313eec676 100644 --- a/src/hash/sha2/sha2_32.h +++ b/src/hash/sha2/sha2_32.h @@ -19,7 +19,7 @@ namespace Botan { class BOTAN_DLL SHA_224_256_BASE : public MDx_HashFunction { protected: - void clear() throw(); + void clear(); SHA_224_256_BASE(u32bit out) : MDx_HashFunction(out, 64, true, true) { clear(); } @@ -36,7 +36,7 @@ class BOTAN_DLL SHA_224_256_BASE : public MDx_HashFunction class BOTAN_DLL SHA_224 : public SHA_224_256_BASE { public: - void clear() throw(); + void clear(); std::string name() const { return "SHA-224"; } HashFunction* clone() const { return new SHA_224; } SHA_224() : SHA_224_256_BASE(28) { clear(); } @@ -48,7 +48,7 @@ class BOTAN_DLL SHA_224 : public SHA_224_256_BASE class BOTAN_DLL SHA_256 : public SHA_224_256_BASE { public: - void clear() throw(); + void clear(); std::string name() const { return "SHA-256"; } HashFunction* clone() const { return new SHA_256; } SHA_256() : SHA_224_256_BASE(32) { clear (); } diff --git a/src/hash/sha2/sha2_64.cpp b/src/hash/sha2/sha2_64.cpp index e9b4c2e5a..3e7c0e228 100644 --- a/src/hash/sha2/sha2_64.cpp +++ b/src/hash/sha2/sha2_64.cpp @@ -55,13 +55,19 @@ void SHA_384_512_BASE::compress_n(const byte input[], u32bit blocks) for(u32bit i = 0; i != blocks; ++i) { - for(u32bit j = 0; j != 16; ++j) - W[j] = load_be<u64bit>(input, j); - input += HASH_BLOCK_SIZE; - - for(u32bit j = 16; j != 80; ++j) - W[j] = sigma(W[j- 2], 19, 61, 6) + W[j- 7] + - sigma(W[j-15], 1, 8, 7) + W[j-16]; + load_be(W.begin(), input, 16); + + for(u32bit j = 16; j != 80; j += 8) + { + W[j ] = sigma(W[j-2], 19, 61, 6) + W[j-7] + sigma(W[j-15], 1, 8, 7) + W[j-16]; + W[j+1] = sigma(W[j-1], 19, 61, 6) + W[j-6] + sigma(W[j-14], 1, 8, 7) + W[j-15]; + W[j+2] = sigma(W[j ], 19, 61, 6) + W[j-5] + sigma(W[j-13], 1, 8, 7) + W[j-14]; + W[j+3] = sigma(W[j+1], 19, 61, 6) + W[j-4] + sigma(W[j-12], 1, 8, 7) + W[j-13]; + W[j+4] = sigma(W[j+2], 19, 61, 6) + W[j-3] + sigma(W[j-11], 1, 8, 7) + W[j-12]; + W[j+5] = sigma(W[j+3], 19, 61, 6) + W[j-2] + sigma(W[j-10], 1, 8, 7) + W[j-11]; + W[j+6] = sigma(W[j+4], 19, 61, 6) + W[j-1] + sigma(W[j- 9], 1, 8, 7) + W[j-10]; + W[j+7] = sigma(W[j+5], 19, 61, 6) + W[j ] + sigma(W[j- 8], 1, 8, 7) + W[j- 9]; + } F1(A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98D728AE22); F1(H, A, B, C, D, E, F, G, W[ 1], 0x7137449123EF65CD); @@ -152,6 +158,8 @@ void SHA_384_512_BASE::compress_n(const byte input[], u32bit blocks) F = (digest[5] += F); G = (digest[6] += G); H = (digest[7] += H); + + input += HASH_BLOCK_SIZE; } } @@ -167,7 +175,7 @@ void SHA_384_512_BASE::copy_out(byte output[]) /* * Clear memory of sensitive data */ -void SHA_384_512_BASE::clear() throw() +void SHA_384_512_BASE::clear() { MDx_HashFunction::clear(); W.clear(); @@ -176,7 +184,7 @@ void SHA_384_512_BASE::clear() throw() /* * Clear memory of sensitive data */ -void SHA_384::clear() throw() +void SHA_384::clear() { SHA_384_512_BASE::clear(); digest[0] = 0xCBBB9D5DC1059ED8; @@ -192,7 +200,7 @@ void SHA_384::clear() throw() /* * Clear memory of sensitive data */ -void SHA_512::clear() throw() +void SHA_512::clear() { SHA_384_512_BASE::clear(); digest[0] = 0x6A09E667F3BCC908; diff --git a/src/hash/sha2/sha2_64.h b/src/hash/sha2/sha2_64.h index dcc6dc83b..8e4d171f8 100644 --- a/src/hash/sha2/sha2_64.h +++ b/src/hash/sha2/sha2_64.h @@ -18,7 +18,7 @@ namespace Botan { class BOTAN_DLL SHA_384_512_BASE : public MDx_HashFunction { protected: - void clear() throw(); + void clear(); SHA_384_512_BASE(u32bit out) : MDx_HashFunction(out, 128, true, true, 16) {} @@ -37,7 +37,7 @@ class BOTAN_DLL SHA_384_512_BASE : public MDx_HashFunction class BOTAN_DLL SHA_384 : public SHA_384_512_BASE { public: - void clear() throw(); + void clear(); std::string name() const { return "SHA-384"; } HashFunction* clone() const { return new SHA_384; } SHA_384() : SHA_384_512_BASE(48) { clear(); } @@ -49,7 +49,7 @@ class BOTAN_DLL SHA_384 : public SHA_384_512_BASE class BOTAN_DLL SHA_512 : public SHA_384_512_BASE { public: - void clear() throw(); + void clear(); std::string name() const { return "SHA-512"; } HashFunction* clone() const { return new SHA_512; } SHA_512() : SHA_384_512_BASE(64) { clear(); } diff --git a/src/hash/skein/info.txt b/src/hash/skein/info.txt index bab8497c5..427f59121 100644 --- a/src/hash/skein/info.txt +++ b/src/hash/skein/info.txt @@ -1,14 +1,5 @@ -realname "Skein" - define SKEIN_512 -load_on auto - -<add> -skein_512.cpp -skein_512.h -</add> - <requires> alloc </requires> diff --git a/src/hash/skein/skein_512.cpp b/src/hash/skein/skein_512.cpp index a48cfc186..e1ca08c15 100644 --- a/src/hash/skein/skein_512.cpp +++ b/src/hash/skein/skein_512.cpp @@ -34,8 +34,8 @@ void ubi_512(u64bit H[9], u64bit T[], const byte msg[], u64bit msg_len) T[0] += to_proc; u64bit M[8] = { 0 }; - for(u32bit j = 0; j != to_proc / 8; ++j) - M[j] = load_le<u64bit>(msg, j); + + load_le(M, msg, to_proc / 8); if(to_proc % 8) { @@ -183,7 +183,7 @@ HashFunction* Skein_512::clone() const return new Skein_512(output_bits, personalization); } -void Skein_512::clear() throw() +void Skein_512::clear() { H.clear(); T.clear(); diff --git a/src/hash/skein/skein_512.h b/src/hash/skein/skein_512.h index fa558fc0d..db8d3c8b7 100644 --- a/src/hash/skein/skein_512.h +++ b/src/hash/skein/skein_512.h @@ -22,7 +22,7 @@ class BOTAN_DLL Skein_512 : public HashFunction HashFunction* clone() const; std::string name() const; - void clear() throw(); + void clear(); private: void add_data(const byte input[], u32bit length); void final_result(byte out[]); diff --git a/src/hash/tiger/info.txt b/src/hash/tiger/info.txt index 7d4cd7177..b50b745e3 100644 --- a/src/hash/tiger/info.txt +++ b/src/hash/tiger/info.txt @@ -1,15 +1,5 @@ -realname "Tiger" - define TIGER -load_on auto - -<add> -tig_tab.cpp -tiger.cpp -tiger.h -</add> - <requires> mdx_hash </requires> diff --git a/src/hash/tiger/tiger.cpp b/src/hash/tiger/tiger.cpp index e46f2cb77..4f4d4dc83 100644 --- a/src/hash/tiger/tiger.cpp +++ b/src/hash/tiger/tiger.cpp @@ -21,9 +21,7 @@ void Tiger::compress_n(const byte input[], u32bit blocks) for(u32bit i = 0; i != blocks; ++i) { - for(u32bit j = 0; j != 8; ++j) - X[j] = load_le<u64bit>(input, j); - input += HASH_BLOCK_SIZE; + load_le(X.begin(), input, X.size()); pass(A, B, C, X, 5); mix(X); pass(C, A, B, X, 7); mix(X); @@ -39,6 +37,8 @@ void Tiger::compress_n(const byte input[], u32bit blocks) A = (digest[0] ^= A); B = digest[1] = B - digest[1]; C = (digest[2] += C); + + input += HASH_BLOCK_SIZE; } } @@ -129,7 +129,7 @@ void Tiger::mix(u64bit X[8]) /* * Clear memory of sensitive data */ -void Tiger::clear() throw() +void Tiger::clear() { MDx_HashFunction::clear(); X.clear(); diff --git a/src/hash/tiger/tiger.h b/src/hash/tiger/tiger.h index 63184a938..86ddcd270 100644 --- a/src/hash/tiger/tiger.h +++ b/src/hash/tiger/tiger.h @@ -18,7 +18,7 @@ namespace Botan { class BOTAN_DLL Tiger : public MDx_HashFunction { public: - void clear() throw(); + void clear(); std::string name() const; HashFunction* clone() const { return new Tiger(OUTPUT_LENGTH); } Tiger(u32bit = 24, u32bit = 3); diff --git a/src/hash/whirlpool/info.txt b/src/hash/whirlpool/info.txt index be55b5c3b..7bec0c6cf 100644 --- a/src/hash/whirlpool/info.txt +++ b/src/hash/whirlpool/info.txt @@ -1,15 +1,5 @@ -realname "Whirlpool" - define WHIRLPOOL -load_on auto - -<add> -whrl_tab.cpp -whrlpool.cpp -whrlpool.h -</add> - <requires> mdx_hash </requires> diff --git a/src/hash/whirlpool/whrlpool.cpp b/src/hash/whirlpool/whrlpool.cpp index 8548d6192..06755fe77 100644 --- a/src/hash/whirlpool/whrlpool.cpp +++ b/src/hash/whirlpool/whrlpool.cpp @@ -25,9 +25,7 @@ void Whirlpool::compress_n(const byte in[], u32bit blocks) for(u32bit i = 0; i != blocks; ++i) { - for(u32bit j = 0; j != 8; ++j) - M[j] = load_be<u64bit>(in, j); - in += HASH_BLOCK_SIZE; + load_be(M.begin(), in, M.size()); u64bit K0, K1, K2, K3, K4, K5, K6, K7; K0 = digest[0]; K1 = digest[1]; K2 = digest[2]; K3 = digest[3]; @@ -121,6 +119,8 @@ void Whirlpool::compress_n(const byte in[], u32bit blocks) digest[5] ^= B5 ^ M[5]; digest[6] ^= B6 ^ M[6]; digest[7] ^= B7 ^ M[7]; + + in += HASH_BLOCK_SIZE; } } @@ -136,7 +136,7 @@ void Whirlpool::copy_out(byte output[]) /* * Clear memory of sensitive data */ -void Whirlpool::clear() throw() +void Whirlpool::clear() { MDx_HashFunction::clear(); M.clear(); diff --git a/src/hash/whirlpool/whrlpool.h b/src/hash/whirlpool/whrlpool.h index b72ff609f..34b4d2302 100644 --- a/src/hash/whirlpool/whrlpool.h +++ b/src/hash/whirlpool/whrlpool.h @@ -18,7 +18,7 @@ namespace Botan { class BOTAN_DLL Whirlpool : public MDx_HashFunction { public: - void clear() throw(); + void clear(); std::string name() const { return "Whirlpool"; } HashFunction* clone() const { return new Whirlpool; } Whirlpool() : MDx_HashFunction(64, 64, true, true, 32) { clear(); } diff --git a/src/kdf/info.txt b/src/kdf/info.txt index 1965a2098..8eb4fc6e9 100644 --- a/src/kdf/info.txt +++ b/src/kdf/info.txt @@ -1,5 +1,3 @@ -realname "KDF Base Class" - define KDF_BASE load_on auto diff --git a/src/kdf/kdf.h b/src/kdf/kdf.h index 70f636b6c..67078218f 100644 --- a/src/kdf/kdf.h +++ b/src/kdf/kdf.h @@ -22,6 +22,7 @@ class BOTAN_DLL KDF SecureVector<byte> derive_key(u32bit key_len, const MemoryRegion<byte>& secret, const std::string& salt = "") const; + SecureVector<byte> derive_key(u32bit key_len, const MemoryRegion<byte>& secret, const MemoryRegion<byte>& salt) const; @@ -33,14 +34,17 @@ class BOTAN_DLL KDF SecureVector<byte> derive_key(u32bit key_len, const byte secret[], u32bit secret_len, const std::string& salt = "") const; + SecureVector<byte> derive_key(u32bit key_len, const byte secret[], u32bit secret_len, const byte salt[], u32bit salt_len) const; virtual ~KDF() {} private: - virtual SecureVector<byte> derive(u32bit, const byte[], u32bit, - const byte[], u32bit) const = 0; + virtual SecureVector<byte> + derive(u32bit key_len, + const byte secret[], u32bit secret_len, + const byte salt[], u32bit salt_len) const = 0; }; /* @@ -50,7 +54,7 @@ class BOTAN_DLL MGF { public: virtual void mask(const byte in[], u32bit in_len, - byte out[], u32bit out_len) const = 0; + byte out[], u32bit out_len) const = 0; virtual ~MGF() {} }; diff --git a/src/kdf/kdf1/info.txt b/src/kdf/kdf1/info.txt index ede10017e..2557f9472 100644 --- a/src/kdf/kdf1/info.txt +++ b/src/kdf/kdf1/info.txt @@ -1,5 +1,3 @@ -realname "KDF1" - define KDF1 load_on auto diff --git a/src/kdf/kdf2/info.txt b/src/kdf/kdf2/info.txt index 1858f8929..b71595449 100644 --- a/src/kdf/kdf2/info.txt +++ b/src/kdf/kdf2/info.txt @@ -1,5 +1,3 @@ -realname "KDF2" - define KDF2 load_on auto diff --git a/src/kdf/mgf1/info.txt b/src/kdf/mgf1/info.txt index f9e952f82..0f104c3b3 100644 --- a/src/kdf/mgf1/info.txt +++ b/src/kdf/mgf1/info.txt @@ -1,5 +1,3 @@ -realname "MGF1" - define MGF1 load_on dep diff --git a/src/kdf/ssl_prf/info.txt b/src/kdf/ssl_prf/info.txt index f862905a2..b306721b9 100644 --- a/src/kdf/ssl_prf/info.txt +++ b/src/kdf/ssl_prf/info.txt @@ -1,5 +1,3 @@ -realname "SSLv3 PRF" - define SSL_V3_PRF load_on auto diff --git a/src/kdf/tls_prf/info.txt b/src/kdf/tls_prf/info.txt index f95ef9c24..11a0d44f5 100644 --- a/src/kdf/tls_prf/info.txt +++ b/src/kdf/tls_prf/info.txt @@ -1,5 +1,3 @@ -realname "TLS v1.0 PRF" - define TLS_V10_PRF load_on auto diff --git a/src/kdf/x942_prf/info.txt b/src/kdf/x942_prf/info.txt index 295c2cde6..e38b2aac1 100644 --- a/src/kdf/x942_prf/info.txt +++ b/src/kdf/x942_prf/info.txt @@ -1,5 +1,3 @@ -realname "X942 PRF" - define X942_PRF load_on auto diff --git a/src/libstate/info.txt b/src/libstate/info.txt index 6eaa2f70b..e8271ce99 100644 --- a/src/libstate/info.txt +++ b/src/libstate/info.txt @@ -1,5 +1,3 @@ -realname "Botan Libstate Module" - load_on always define LIBSTATE_MODULE diff --git a/src/libstate/libstate.cpp b/src/libstate/libstate.cpp index 3275c6493..c78bce62d 100644 --- a/src/libstate/libstate.cpp +++ b/src/libstate/libstate.cpp @@ -7,6 +7,7 @@ #include <botan/libstate.h> #include <botan/init.h> +#include <botan/selftest.h> #include <botan/engine.h> #include <botan/stl_util.h> #include <botan/mutex.h> @@ -36,8 +37,8 @@ #include <botan/eng_amd64.h> #endif -#if defined(BOTAN_HAS_ENGINE_SSE2_ASSEMBLER) - #include <botan/eng_sse2.h> +#if defined(BOTAN_HAS_ENGINE_SIMD) + #include <botan/simd_engine.h> #endif #if defined(BOTAN_HAS_ENGINE_GNU_MP) @@ -212,7 +213,7 @@ std::string Library_State::deref_alias(const std::string& key) const /* * Set/Add an option */ -void Library_State::set_option(const std::string key, +void Library_State::set_option(const std::string& key, const std::string& value) { set("conf", key, value); @@ -287,8 +288,8 @@ void Library_State::initialize(bool thread_safe) engines.push_back(new OpenSSL_Engine); #endif -#if defined(BOTAN_HAS_ENGINE_SSE2_ASSEMBLER) - engines.push_back(new SSE2_Assembler_Engine); +#if defined(BOTAN_HAS_ENGINE_SIMD) + engines.push_back(new SIMD_Engine); #endif #if defined(BOTAN_HAS_ENGINE_AMD64_ASSEMBLER) @@ -302,6 +303,9 @@ void Library_State::initialize(bool thread_safe) engines.push_back(new Default_Engine); m_algorithm_factory = new Algorithm_Factory(engines, *mutex_factory); + + if(!passes_self_tests(algorithm_factory())) + throw Self_Test_Failure("Startup self tests failed"); } /* diff --git a/src/libstate/libstate.h b/src/libstate/libstate.h index 2493863a9..a0421953e 100644 --- a/src/libstate/libstate.h +++ b/src/libstate/libstate.h @@ -77,7 +77,7 @@ class BOTAN_DLL Library_State * @param key the key of the option to set * @param value the value to set */ - void set_option(const std::string key, const std::string& value); + void set_option(const std::string& key, const std::string& value); /** * Add a parameter value to the "alias" section. diff --git a/src/libstate/oid_lookup/info.txt b/src/libstate/oid_lookup/info.txt index 609eb9199..e0f6f099c 100644 --- a/src/libstate/oid_lookup/info.txt +++ b/src/libstate/oid_lookup/info.txt @@ -1,5 +1,3 @@ -realname "OID Lookup" - load_on dep define OID_LOOKUP diff --git a/src/libstate/scan_name.cpp b/src/libstate/scan_name.cpp index ef771871d..224d2e509 100644 --- a/src/libstate/scan_name.cpp +++ b/src/libstate/scan_name.cpp @@ -1,6 +1,6 @@ /** -SCAN Name Abstraction -(C) 2008 Jack Lloyd +* SCAN Name Abstraction +* (C) 2008 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -14,28 +14,50 @@ namespace Botan { namespace { -std::vector<std::string> -parse_and_deref_aliases(const std::string& algo_spec) +std::string make_arg( + const std::vector<std::pair<u32bit, std::string> >& name, u32bit start) { - std::vector<std::string> parts = parse_algorithm_name(algo_spec); - std::vector<std::string> out; + std::string output = name[start].second; + u32bit level = name[start].first; - for(size_t i = 0; i != parts.size(); ++i) + u32bit paren_depth = 0; + + for(u32bit i = start + 1; i != name.size(); ++i) { - std::string part_i = global_state().deref_alias(parts[i]); + if(name[i].first <= name[start].first) + break; - if(i == 0 && part_i.find_first_of(",()") != std::string::npos) + if(name[i].first > level) { - std::vector<std::string> parts_i = parse_and_deref_aliases(part_i); - - for(size_t j = 0; j != parts_i.size(); ++j) - out.push_back(parts_i[j]); + output += '(' + name[i].second; + ++paren_depth; + } + else if(name[i].first < level) + { + output += ")," + name[i].second; + --paren_depth; } else - out.push_back(part_i); + { + if(output[output.size() - 1] != '(') + output += ","; + output += name[i].second; + } + + level = name[i].first; } - return out; + for(u32bit i = 0; i != paren_depth; ++i) + output += ')'; + + return output; + } + +std::pair<u32bit, std::string> +deref_aliases(const std::pair<u32bit, std::string>& in) + { + return std::make_pair(in.first, + global_state().deref_alias(in.second)); } } @@ -44,31 +66,101 @@ SCAN_Name::SCAN_Name(const std::string& algo_spec) { orig_algo_spec = algo_spec; - name = parse_and_deref_aliases(algo_spec); + std::vector<std::pair<u32bit, std::string> > name; + u32bit level = 0; + std::pair<u32bit, std::string> accum = std::make_pair(level, ""); + + for(u32bit i = 0; i != algo_spec.size(); ++i) + { + char c = algo_spec[i]; + + if(c == '/' || c == ',' || c == '(' || c == ')') + { + if(c == '(') + ++level; + else if(c == ')') + { + if(level == 0) + throw Decoding_Error("Bad SCAN name " + algo_spec); + --level; + } + + if(c == '/' && level > 0) + accum.second.push_back(c); + else + { + if(accum.second != "") + name.push_back(deref_aliases(accum)); + accum = std::make_pair(level, ""); + } + } + else + accum.second.push_back(c); + } + + if(accum.second != "") + name.push_back(deref_aliases(accum)); - if(name.size() == 0) + if(level != 0 || name.size() == 0) throw Decoding_Error("Bad SCAN name " + algo_spec); + + alg_name = name[0].second; + + bool in_modes = false; + + for(u32bit i = 1; i != name.size(); ++i) + { + if(name[i].first == 0) + { + mode_info.push_back(make_arg(name, i)); + in_modes = true; + } + else if(name[i].first == 1 && !in_modes) + args.push_back(make_arg(name, i)); + } + } + +std::string SCAN_Name::algo_name_and_args() const + { + std::string out; + + out = algo_name(); + + if(arg_count()) + { + out += '('; + for(u32bit i = 0; i != arg_count(); ++i) + { + out += arg(i); + if(i != arg_count() - 1) + out += ','; + } + out += ')'; + + } + + return out; } std::string SCAN_Name::arg(u32bit i) const { if(i >= arg_count()) throw std::range_error("SCAN_Name::argument"); - return name[i+1]; + return args[i]; } std::string SCAN_Name::arg(u32bit i, const std::string& def_value) const { if(i >= arg_count()) return def_value; - return name[i+1]; + return args[i]; } u32bit SCAN_Name::arg_as_u32bit(u32bit i, u32bit def_value) const { if(i >= arg_count()) return def_value; - return to_u32bit(name[i+1]); + return to_u32bit(args[i]); } } diff --git a/src/libstate/scan_name.h b/src/libstate/scan_name.h index 9e7af40d6..ced5f3e15 100644 --- a/src/libstate/scan_name.h +++ b/src/libstate/scan_name.h @@ -1,6 +1,6 @@ /** -SCAN Name Abstraction -(C) 2008 Jack Lloyd +* SCAN Name Abstraction +* (C) 2008 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -35,12 +35,17 @@ class SCAN_Name /** @return the algorithm name */ - std::string algo_name() const { return name[0]; } + std::string algo_name() const { return alg_name; } + + /** + @return the algorithm name plus any arguments + */ + std::string algo_name_and_args() const; /** @return the number of arguments */ - u32bit arg_count() const { return name.size() - 1; } + u32bit arg_count() const { return args.size(); } /** @return if the number of arguments is between lower and upper @@ -67,9 +72,24 @@ class SCAN_Name @return the ith argument as a u32bit, or the default value */ u32bit arg_as_u32bit(u32bit i, u32bit def_value) const; + + /** + @return the cipher mode (if any) + */ + std::string cipher_mode() const + { return (mode_info.size() >= 1) ? mode_info[0] : ""; } + + /** + @return the cipher mode padding (if any) + */ + std::string cipher_mode_pad() const + { return (mode_info.size() >= 2) ? mode_info[1] : ""; } + private: std::string orig_algo_spec; - std::vector<std::string> name; + std::string alg_name; + std::vector<std::string> args; + std::vector<std::string> mode_info; }; } diff --git a/src/mac/cbc_mac/cbc_mac.cpp b/src/mac/cbc_mac/cbc_mac.cpp index f5d9e1567..0617e3e90 100644 --- a/src/mac/cbc_mac/cbc_mac.cpp +++ b/src/mac/cbc_mac/cbc_mac.cpp @@ -62,7 +62,7 @@ void CBC_MAC::key_schedule(const byte key[], u32bit length) /* * Clear memory of sensitive data */ -void CBC_MAC::clear() throw() +void CBC_MAC::clear() { e->clear(); state.clear(); diff --git a/src/mac/cbc_mac/cbc_mac.h b/src/mac/cbc_mac/cbc_mac.h index d17d792d3..15026c0a9 100644 --- a/src/mac/cbc_mac/cbc_mac.h +++ b/src/mac/cbc_mac/cbc_mac.h @@ -19,7 +19,7 @@ namespace Botan { class BOTAN_DLL CBC_MAC : public MessageAuthenticationCode { public: - void clear() throw(); + void clear(); std::string name() const; MessageAuthenticationCode* clone() const; diff --git a/src/mac/cbc_mac/info.txt b/src/mac/cbc_mac/info.txt index 3a5434974..80adc5fd0 100644 --- a/src/mac/cbc_mac/info.txt +++ b/src/mac/cbc_mac/info.txt @@ -1,5 +1,3 @@ -realname "CBC-MAC" - define CBC_MAC load_on auto diff --git a/src/mac/cmac/cmac.cpp b/src/mac/cmac/cmac.cpp index 84aa61e03..58923138b 100644 --- a/src/mac/cmac/cmac.cpp +++ b/src/mac/cmac/cmac.cpp @@ -101,7 +101,7 @@ void CMAC::key_schedule(const byte key[], u32bit length) /* * Clear memory of sensitive data */ -void CMAC::clear() throw() +void CMAC::clear() { e->clear(); state.clear(); diff --git a/src/mac/cmac/cmac.h b/src/mac/cmac/cmac.h index 5a6deb7b0..8297e5ea1 100644 --- a/src/mac/cmac/cmac.h +++ b/src/mac/cmac/cmac.h @@ -19,7 +19,7 @@ namespace Botan { class BOTAN_DLL CMAC : public MessageAuthenticationCode { public: - void clear() throw(); + void clear(); std::string name() const; MessageAuthenticationCode* clone() const; diff --git a/src/mac/cmac/info.txt b/src/mac/cmac/info.txt index b593c9d38..5dad789de 100644 --- a/src/mac/cmac/info.txt +++ b/src/mac/cmac/info.txt @@ -1,5 +1,3 @@ -realname "CMAC" - define CMAC load_on auto diff --git a/src/mac/hmac/hmac.cpp b/src/mac/hmac/hmac.cpp index 717e2640c..99be479fa 100644 --- a/src/mac/hmac/hmac.cpp +++ b/src/mac/hmac/hmac.cpp @@ -58,7 +58,7 @@ void HMAC::key_schedule(const byte key[], u32bit length) /* * Clear memory of sensitive data */ -void HMAC::clear() throw() +void HMAC::clear() { hash->clear(); i_key.clear(); diff --git a/src/mac/hmac/hmac.h b/src/mac/hmac/hmac.h index 932af71fc..62bb69853 100644 --- a/src/mac/hmac/hmac.h +++ b/src/mac/hmac/hmac.h @@ -19,7 +19,7 @@ namespace Botan { class BOTAN_DLL HMAC : public MessageAuthenticationCode { public: - void clear() throw(); + void clear(); std::string name() const; MessageAuthenticationCode* clone() const; diff --git a/src/mac/hmac/info.txt b/src/mac/hmac/info.txt index cdf2e67ab..26da83533 100644 --- a/src/mac/hmac/info.txt +++ b/src/mac/hmac/info.txt @@ -1,5 +1,3 @@ -realname "HMAC" - define HMAC load_on auto diff --git a/src/mac/info.txt b/src/mac/info.txt index 239eb633f..9a839d04d 100644 --- a/src/mac/info.txt +++ b/src/mac/info.txt @@ -1,5 +1,3 @@ -realname "Message Authentication Codes" - load_on auto <add> diff --git a/src/mac/mac.cpp b/src/mac/mac.cpp index 96df25503..04b259647 100644 --- a/src/mac/mac.cpp +++ b/src/mac/mac.cpp @@ -1,6 +1,6 @@ /** -Message Authentication Code base class -(C) 1999-2008 Jack Lloyd +* Message Authentication Code base class +* (C) 1999-2008 Jack Lloyd * * Distributed under the terms of the Botan license */ diff --git a/src/mac/mac.h b/src/mac/mac.h index 3ec5fff5f..7c73a2900 100644 --- a/src/mac/mac.h +++ b/src/mac/mac.h @@ -43,7 +43,7 @@ class BOTAN_DLL MessageAuthenticationCode : public BufferedComputation, /** * Reset the internal state of this object. */ - virtual void clear() throw() = 0; + virtual void clear() = 0; MessageAuthenticationCode(u32bit mac_len, u32bit key_min, diff --git a/src/mac/ssl3mac/info.txt b/src/mac/ssl3mac/info.txt index f8791169c..c4ef54629 100644 --- a/src/mac/ssl3mac/info.txt +++ b/src/mac/ssl3mac/info.txt @@ -1,5 +1,3 @@ -realname "SSLv3 MAC" - define SSL3_MAC load_on auto diff --git a/src/mac/ssl3mac/ssl3_mac.cpp b/src/mac/ssl3mac/ssl3_mac.cpp index c29296ced..23a636424 100644 --- a/src/mac/ssl3mac/ssl3_mac.cpp +++ b/src/mac/ssl3mac/ssl3_mac.cpp @@ -46,7 +46,7 @@ void SSL3_MAC::key_schedule(const byte key[], u32bit length) /* * Clear memory of sensitive data */ -void SSL3_MAC::clear() throw() +void SSL3_MAC::clear() { hash->clear(); i_key.clear(); diff --git a/src/mac/ssl3mac/ssl3_mac.h b/src/mac/ssl3mac/ssl3_mac.h index dcaf7f404..828b072ed 100644 --- a/src/mac/ssl3mac/ssl3_mac.h +++ b/src/mac/ssl3mac/ssl3_mac.h @@ -19,7 +19,7 @@ namespace Botan { class BOTAN_DLL SSL3_MAC : public MessageAuthenticationCode { public: - void clear() throw(); + void clear(); std::string name() const; MessageAuthenticationCode* clone() const; diff --git a/src/mac/x919_mac/info.txt b/src/mac/x919_mac/info.txt index f2ebd5b35..16955816c 100644 --- a/src/mac/x919_mac/info.txt +++ b/src/mac/x919_mac/info.txt @@ -1,5 +1,3 @@ -realname "ANSI X9.19 MAC" - define ANSI_X919_MAC load_on auto diff --git a/src/mac/x919_mac/x919_mac.cpp b/src/mac/x919_mac/x919_mac.cpp index ef89cac9c..52260494a 100644 --- a/src/mac/x919_mac/x919_mac.cpp +++ b/src/mac/x919_mac/x919_mac.cpp @@ -63,7 +63,7 @@ void ANSI_X919_MAC::key_schedule(const byte key[], u32bit length) /* * Clear memory of sensitive data */ -void ANSI_X919_MAC::clear() throw() +void ANSI_X919_MAC::clear() { e->clear(); d->clear(); diff --git a/src/mac/x919_mac/x919_mac.h b/src/mac/x919_mac/x919_mac.h index 1c2a06bee..a4690fdcd 100644 --- a/src/mac/x919_mac/x919_mac.h +++ b/src/mac/x919_mac/x919_mac.h @@ -19,7 +19,7 @@ namespace Botan { class BOTAN_DLL ANSI_X919_MAC : public MessageAuthenticationCode { public: - void clear() throw(); + void clear(); std::string name() const; MessageAuthenticationCode* clone() const; diff --git a/src/math/bigint/bigint.cpp b/src/math/bigint/bigint.cpp index 926bedc02..63bdc3605 100644 --- a/src/math/bigint/bigint.cpp +++ b/src/math/bigint/bigint.cpp @@ -9,7 +9,7 @@ #include <botan/mp_core.h> #include <botan/loadstor.h> #include <botan/parsing.h> -#include <botan/util.h> +#include <botan/rounding.h> namespace Botan { diff --git a/src/math/bigint/info.txt b/src/math/bigint/info.txt index 513703deb..30018b795 100644 --- a/src/math/bigint/info.txt +++ b/src/math/bigint/info.txt @@ -1,5 +1,3 @@ -realname "BigInt" - load_on auto define BIGINT diff --git a/src/math/bigint/monty_amd64/info.txt b/src/math/bigint/monty_amd64/info.txt index a897045b2..657cd0353 100644 --- a/src/math/bigint/monty_amd64/info.txt +++ b/src/math/bigint/monty_amd64/info.txt @@ -1,5 +1,3 @@ -realname "Montgomery Reduction (x86-64)" - mp_bits 64 load_on never diff --git a/src/math/bigint/monty_generic/info.txt b/src/math/bigint/monty_generic/info.txt index 6f5f0e722..c709229e6 100644 --- a/src/math/bigint/monty_generic/info.txt +++ b/src/math/bigint/monty_generic/info.txt @@ -1,5 +1,3 @@ -realname "Montgomery Reduction" - load_on dep <add> diff --git a/src/math/bigint/mp_amd64/info.txt b/src/math/bigint/mp_amd64/info.txt index 84a5bcf53..a7da8806e 100644 --- a/src/math/bigint/mp_amd64/info.txt +++ b/src/math/bigint/mp_amd64/info.txt @@ -1,5 +1,3 @@ -realname "MPI Core (x86-64)" - mp_bits 64 load_on dep diff --git a/src/math/bigint/mp_amd64/mp_asmi.h b/src/math/bigint/mp_amd64/mp_asmi.h index 8bccbaaf4..1a3ac1aaa 100644 --- a/src/math/bigint/mp_amd64/mp_asmi.h +++ b/src/math/bigint/mp_amd64/mp_asmi.h @@ -70,20 +70,12 @@ extern "C" { */ inline word word_add(word x, word y, word* carry) { -#if 0 asm( ADD_OR_SUBTRACT(ASM("adcq %[y],%[x]")) : [x]"=r"(x), [carry]"=r"(*carry) : "0"(x), [y]"rm"(y), "1"(*carry) : "cc"); return x; -#else - word z = x + y; - word c1 = (z < x); - z += *carry; - *carry = c1 | (z < *carry); - return z; -#endif } /* diff --git a/src/math/bigint/mp_asm64/info.txt b/src/math/bigint/mp_asm64/info.txt index 5c112c490..7bdbffb2c 100644 --- a/src/math/bigint/mp_asm64/info.txt +++ b/src/math/bigint/mp_asm64/info.txt @@ -1,5 +1,3 @@ -realname "MPI Core (Alpha/IA-64/MIPS64/PowerPC-64/SPARC64)" - mp_bits 64 load_on dep diff --git a/src/math/bigint/mp_generic/info.txt b/src/math/bigint/mp_generic/info.txt index 8bf75fec3..28f258ebb 100644 --- a/src/math/bigint/mp_generic/info.txt +++ b/src/math/bigint/mp_generic/info.txt @@ -1,5 +1,3 @@ -realname "MPI Core (C++)" - load_on dep <add> diff --git a/src/math/bigint/mp_ia32/info.txt b/src/math/bigint/mp_ia32/info.txt index 51f98fda8..6e093a7e5 100644 --- a/src/math/bigint/mp_ia32/info.txt +++ b/src/math/bigint/mp_ia32/info.txt @@ -1,5 +1,3 @@ -realname "MPI Core (IA-32)" - mp_bits 32 load_on asm_ok diff --git a/src/math/bigint/mp_ia32/mp_asmi.h b/src/math/bigint/mp_ia32/mp_asmi.h index 28b99abcc..46bf302d5 100644 --- a/src/math/bigint/mp_ia32/mp_asmi.h +++ b/src/math/bigint/mp_ia32/mp_asmi.h @@ -70,20 +70,12 @@ extern "C" { */ inline word word_add(word x, word y, word* carry) { -#if 0 asm( ADD_OR_SUBTRACT(ASM("adcl %[y],%[x]")) : [x]"=r"(x), [carry]"=r"(*carry) : "0"(x), [y]"rm"(y), "1"(*carry) : "cc"); return x; -#else - word z = x + y; - word c1 = (z < x); - z += *carry; - *carry = c1 | (z < *carry); - return z; -#endif } /* diff --git a/src/math/bigint/mp_ia32_msvc/info.txt b/src/math/bigint/mp_ia32_msvc/info.txt index 9c7ac9b43..52839d89b 100644 --- a/src/math/bigint/mp_ia32_msvc/info.txt +++ b/src/math/bigint/mp_ia32_msvc/info.txt @@ -1,5 +1,3 @@ -realname "x86 MPI Assembler Core (MSVC)" - mp_bits 32 load_on dep diff --git a/src/math/bigint/mulop_amd64/info.txt b/src/math/bigint/mulop_amd64/info.txt index 77990df80..704e4dad8 100644 --- a/src/math/bigint/mulop_amd64/info.txt +++ b/src/math/bigint/mulop_amd64/info.txt @@ -1,5 +1,3 @@ -realname "BigInt Multiply-Add (x86-64)" - mp_bits 64 load_on never diff --git a/src/math/bigint/mulop_generic/info.txt b/src/math/bigint/mulop_generic/info.txt index 28ebe41eb..8fa2a40c9 100644 --- a/src/math/bigint/mulop_generic/info.txt +++ b/src/math/bigint/mulop_generic/info.txt @@ -1,5 +1,3 @@ -realname "BigInt Multiply-Add" - load_on dep <add> diff --git a/src/math/bigint/mulop_ia32/info.txt b/src/math/bigint/mulop_ia32/info.txt index b995dd8d7..dd554773f 100644 --- a/src/math/bigint/mulop_ia32/info.txt +++ b/src/math/bigint/mulop_ia32/info.txt @@ -1,5 +1,3 @@ -realname "BigInt Multiply-Add (IA-32)" - mp_bits 32 # Out of date, still implements bigint_mul_add_words diff --git a/src/math/gfpmath/curve_gfp.cpp b/src/math/gfpmath/curve_gfp.cpp index e12ade081..9a3ffd482 100644 --- a/src/math/gfpmath/curve_gfp.cpp +++ b/src/math/gfpmath/curve_gfp.cpp @@ -1,11 +1,11 @@ -/****** +/* * Elliptic curves over GF(p) * -* (C) 2007 Martin Doering -* Christoph Ludwig -* Falko Strenzke +* (C) 2007 Martin Doering, Christoph Ludwig, Falko Strenzke * 2008 Jack Lloyd -******/ +* +* Distributed under the terms of the Botan license +*/ #include <botan/curve_gfp.h> #include <botan/bigint.h> diff --git a/src/math/gfpmath/gfp_element.cpp b/src/math/gfpmath/gfp_element.cpp index b71809301..8ae9b3c3a 100644 --- a/src/math/gfpmath/gfp_element.cpp +++ b/src/math/gfpmath/gfp_element.cpp @@ -1,13 +1,15 @@ -/****** - * Arithmetic for prime fields GF(p) (source file) - * - * (C) 2007 Martin Doering - * Christoph Ludwig - * Falko Strenzke - ******/ +/* +* Arithmetic for prime fields GF(p) +* +* (C) 2007 Martin Doering +* Christoph Ludwig +* Falko Strenzke +* +* Distributed under the terms of the Botan license +*/ #include <botan/gfp_element.h> #include <botan/numthry.h> @@ -15,8 +17,8 @@ #include <botan/mp_types.h> #include <botan/mp_asm.h> #include <botan/mp_asmi.h> -#include <assert.h> #include <ostream> +#include <assert.h> namespace Botan { @@ -66,7 +68,9 @@ void inner_montg_mult_sos(word result[], const word* a_bar, const word* b_bar, c while (C > 0) { // we need not worry here about C > 1, because the other operand is zero - word tmp = word_add(t[i+s+cnt], 0, &C); + + word tmp = t[i+s+cnt] + C; + C = (tmp < t[i+s+cnt]); t[i+s+cnt] = tmp; cnt++; } diff --git a/src/math/gfpmath/gfp_element.h b/src/math/gfpmath/gfp_element.h index 4e0ee985b..18d9e51f9 100644 --- a/src/math/gfpmath/gfp_element.h +++ b/src/math/gfpmath/gfp_element.h @@ -1,13 +1,15 @@ -/****** - * Arithmetic for prime fields GF(p) (header file) - * - * (C) 2007 Martin Doering - * Christoph Ludwig - * Falko Strenzke - ******/ +/* +* Arithmetic for prime fields GF(p) +* +* (C) 2007 Martin Doering +* Christoph Ludwig +* Falko Strenzke +* +* Distributed under the terms of the Botan license +*/ #ifndef BOTAN_GFP_ELEMENT_H__ #define BOTAN_GFP_ELEMENT_H__ @@ -26,11 +28,11 @@ namespace Botan { -struct Illegal_Transformation : public Exception +struct BOTAN_DLL Illegal_Transformation : public Exception { Illegal_Transformation(const std::string& err = - "Requested transformation is not possible") - : Exception(err) {} + "Requested transformation is not possible") : + Exception(err) {} }; /** @@ -39,23 +41,6 @@ struct Illegal_Transformation : public Exception */ class BOTAN_DLL GFpElement { - private: - std::tr1::shared_ptr<GFpModulus> mp_mod; - mutable BigInt m_value; // ordinary residue or m-residue respectively - mutable BigInt workspace; - - // ***************************************** - // data members for montgomery multiplication - mutable bool m_use_montgm; - //mutable BigInt m_mres; - // this bool tells use whether the m_mres carries - // the actual value (in this case mValue doesn´t) - mutable bool m_is_trf; - - void ensure_montgm_precomp() const; - void trf_to_mres() const; - void trf_to_ordres() const; - public: /** construct an element of GF(p) with the given value. @@ -260,7 +245,22 @@ class BOTAN_DLL GFpElement * @param other The value to swap with */ void swap(GFpElement& other); + private: + void ensure_montgm_precomp() const; + void trf_to_mres() const; + void trf_to_ordres() const; + + std::tr1::shared_ptr<GFpModulus> mp_mod; + mutable BigInt m_value; // ordinary residue or m-residue respectively + mutable BigInt workspace; + // ***************************************** + // data members for montgomery multiplication + mutable bool m_use_montgm; + //mutable BigInt m_mres; + // this bool tells use whether the m_mres carries + // the actual value (in this case mValue doesn´t) + mutable bool m_is_trf; }; // relational operators diff --git a/src/math/gfpmath/gfp_modulus.h b/src/math/gfpmath/gfp_modulus.h index b5c085775..8e37e9a73 100644 --- a/src/math/gfpmath/gfp_modulus.h +++ b/src/math/gfpmath/gfp_modulus.h @@ -1,39 +1,33 @@ -/****** - * Modulus and related data for a specific - * implementation of GF(p) (header file) - * - * (C) 2008 Martin Döring - * Christoph Ludwig - * Falko Strenzke - ******/ +/* +* Modulus and related data for a specific implementation of GF(p) +* +* (C) 2008 Martin Döring +* <[email protected]> +* Christoph Ludwig +* <[email protected]> +* Falko Strenzke +* <[email protected]> +* +* Distributed under the terms of the Botan license +*/ #ifndef BOTAN_GFP_MODULUS_H__ #define BOTAN_GFP_MODULUS_H__ #include <botan/bigint.h> -namespace Botan -{ +namespace Botan { class BOTAN_DLL GFpElement; + /** -* This class represents a GFpElement modulus including the modulus related -* values necessary for the montgomery multiplication. -* -* Distributed under the terms of the Botan license +* This class represents a GFpElement modulus including the modulus +* related values necessary for the montgomery multiplication. */ class BOTAN_DLL GFpModulus { - friend class GFpElement; - private: - BigInt m_p; // the modulus itself - mutable BigInt m_p_dash; - mutable BigInt m_r; - mutable BigInt m_r_inv; public: + friend class GFpElement; /** * Construct a GF(P)-Modulus from a BigInt @@ -119,9 +113,14 @@ class BOTAN_DLL GFpModulus return m_p_dash; } // default cp-ctor, op= are fine + + private: + BigInt m_p; // the modulus itself + mutable BigInt m_p_dash; + mutable BigInt m_r; + mutable BigInt m_r_inv; }; } #endif - diff --git a/src/math/gfpmath/info.txt b/src/math/gfpmath/info.txt index 1a52144b7..abbdb0a47 100644 --- a/src/math/gfpmath/info.txt +++ b/src/math/gfpmath/info.txt @@ -1,5 +1,3 @@ -realname "GF(p) Math" - uses_tr1 yes load_on auto diff --git a/src/math/gfpmath/point_gfp.cpp b/src/math/gfpmath/point_gfp.cpp index 9139c3ef9..b67631f7b 100644 --- a/src/math/gfpmath/point_gfp.cpp +++ b/src/math/gfpmath/point_gfp.cpp @@ -1,12 +1,11 @@ -/****** -* Arithmetic for point groups of elliptic curves -* over GF(p) (source file) +/* +* Arithmetic for point groups of elliptic curves over GF(p) * -* (C) 2007 Martin Doering -* Christoph Ludwig -* Falko Strenzke +* (C) 2007 Martin Doering, Christoph Ludwig, Falko Strenzke * 2008 Jack Lloyd -******/ +* +* Distributed under the terms of the Botan license +*/ #include <botan/point_gfp.h> #include <botan/numthry.h> @@ -688,8 +687,6 @@ void PointGFp::turn_on_sp_red_mul() const * returns a point equivalent to *this but were * Z has value one, i.e. x and y correspond to * their values in affine coordinates -* -* Distributed under the terms of the Botan license */ PointGFp const PointGFp::get_z_to_one() const { diff --git a/src/math/gfpmath/point_gfp.h b/src/math/gfpmath/point_gfp.h index 771605efc..62b3bc7da 100644 --- a/src/math/gfpmath/point_gfp.h +++ b/src/math/gfpmath/point_gfp.h @@ -1,10 +1,8 @@ /* -* Arithmetic over GF(p) +* Arithmetic for point groups of elliptic curves over GF(p) * -* (C) 2007 Martin Doering -* Christoph Ludwig -* Falko Strenzke -* (C) 2008 Jack Lloyd +* (C) 2007 Martin Doering, Christoph Ludwig, Falko Strenzke +* 2008 Jack Lloyd * * Distributed under the terms of the Botan license */ diff --git a/src/math/numbertheory/info.txt b/src/math/numbertheory/info.txt index 1595c7305..527f4fa29 100644 --- a/src/math/numbertheory/info.txt +++ b/src/math/numbertheory/info.txt @@ -1,5 +1,3 @@ -realname "Math Functions" - load_on auto define BIGINT_MATH diff --git a/src/math/numbertheory/mp_numth.cpp b/src/math/numbertheory/mp_numth.cpp index 45a398440..2cb36b8a3 100644 --- a/src/math/numbertheory/mp_numth.cpp +++ b/src/math/numbertheory/mp_numth.cpp @@ -7,7 +7,7 @@ #include <botan/numthry.h> #include <botan/mp_core.h> -#include <botan/util.h> +#include <botan/rounding.h> #include <algorithm> namespace Botan { diff --git a/src/modes/cbc/info.txt b/src/modes/cbc/info.txt index de81dcb8c..9b4be1b58 100644 --- a/src/modes/cbc/info.txt +++ b/src/modes/cbc/info.txt @@ -1,5 +1,3 @@ -realname "CBC block cipher mode" - define CBC load_on auto diff --git a/src/modes/cfb/info.txt b/src/modes/cfb/info.txt index d66df1ee7..b68afc7d0 100644 --- a/src/modes/cfb/info.txt +++ b/src/modes/cfb/info.txt @@ -1,5 +1,3 @@ -realname "CFB block cipher mode" - define CFB load_on auto @@ -12,4 +10,3 @@ cfb.h <requires> modes </requires> - diff --git a/src/modes/ctr/ctr.cpp b/src/modes/ctr/ctr.cpp deleted file mode 100644 index 9eb42ec5a..000000000 --- a/src/modes/ctr/ctr.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* -* CTR Mode -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/ctr.h> -#include <botan/xor_buf.h> -#include <algorithm> - -namespace Botan { - -/* -* CTR-BE Constructor -*/ -CTR_BE::CTR_BE(BlockCipher* ciph) : - BlockCipherMode(ciph, "CTR-BE", ciph->BLOCK_SIZE, 1) - { - } - -/* -* CTR-BE Constructor -*/ -CTR_BE::CTR_BE(BlockCipher* ciph, const SymmetricKey& key, - const InitializationVector& iv) : - BlockCipherMode(ciph, "CTR-BE", ciph->BLOCK_SIZE, 1) - { - set_key(key); - set_iv(iv); - } - -/* -* CTR-BE Encryption/Decryption -*/ -void CTR_BE::write(const byte input[], u32bit length) - { - u32bit copied = std::min(BLOCK_SIZE - position, length); - xor_buf(buffer + position, input, copied); - send(buffer + position, copied); - input += copied; - length -= copied; - position += copied; - - if(position == BLOCK_SIZE) - increment_counter(); - - while(length >= BLOCK_SIZE) - { - xor_buf(buffer, input, BLOCK_SIZE); - send(buffer, BLOCK_SIZE); - - input += BLOCK_SIZE; - length -= BLOCK_SIZE; - increment_counter(); - } - - xor_buf(buffer + position, input, length); - send(buffer + position, length); - position += length; - } - -/* -* Increment the counter and update the buffer -*/ -void CTR_BE::increment_counter() - { - for(s32bit j = BLOCK_SIZE - 1; j >= 0; --j) - if(++state[j]) - break; - cipher->encrypt(state, buffer); - position = 0; - } - -} diff --git a/src/modes/ctr/ctr.h b/src/modes/ctr/ctr.h deleted file mode 100644 index aa0db5761..000000000 --- a/src/modes/ctr/ctr.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -* CTR Mode -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_COUNTER_MODE_H__ -#define BOTAN_COUNTER_MODE_H__ - -#include <botan/modebase.h> -#include <botan/modebase.h> - -namespace Botan { - -/* -* CTR-BE Mode -*/ -class BOTAN_DLL CTR_BE : public BlockCipherMode - { - public: - CTR_BE(BlockCipher*); - CTR_BE(BlockCipher*, const SymmetricKey&, const InitializationVector&); - private: - void write(const byte[], u32bit); - void increment_counter(); - }; - -} - -#endif diff --git a/src/modes/cts/info.txt b/src/modes/cts/info.txt index 9eb16add5..773254a30 100644 --- a/src/modes/cts/info.txt +++ b/src/modes/cts/info.txt @@ -1,5 +1,3 @@ -realname "CTS block cipher mode" - define CTS load_on auto diff --git a/src/modes/eax/eax.h b/src/modes/eax/eax.h index 1bb2e510d..f569f2ede 100644 --- a/src/modes/eax/eax.h +++ b/src/modes/eax/eax.h @@ -8,7 +8,7 @@ #ifndef BOTAN_EAX_H__ #define BOTAN_EAX_H__ -#include <botan/basefilt.h> +#include <botan/key_filt.h> #include <botan/block_cipher.h> #include <botan/mac.h> diff --git a/src/modes/eax/info.txt b/src/modes/eax/info.txt index d1fc7e0e3..143944f03 100644 --- a/src/modes/eax/info.txt +++ b/src/modes/eax/info.txt @@ -1,5 +1,3 @@ -realname "EAX block cipher mode" - define EAX load_on auto diff --git a/src/modes/ecb/ecb.cpp b/src/modes/ecb/ecb.cpp index 8da0a4802..988a8b3f2 100644 --- a/src/modes/ecb/ecb.cpp +++ b/src/modes/ecb/ecb.cpp @@ -9,22 +9,60 @@ namespace Botan { +namespace { + +const u32bit PARALLEL_BLOCKS = BOTAN_PARALLEL_BLOCKS_ECB; + +} + /* -* Verify the IV is not set +* ECB_Encryption Constructor */ -bool ECB::valid_iv_size(u32bit iv_size) const +ECB_Encryption::ECB_Encryption(BlockCipher* ciph, + BlockCipherModePaddingMethod* pad) { - if(iv_size == 0) - return true; - return false; + cipher = ciph; + padder = pad; + + plaintext.create(cipher->BLOCK_SIZE); + ciphertext.create(cipher->BLOCK_SIZE * PARALLEL_BLOCKS); + + position = 0; + } + +/* +* ECB_Encryption Constructor +*/ +ECB_Encryption::ECB_Encryption(BlockCipher* ciph, + BlockCipherModePaddingMethod* pad, + const SymmetricKey& key) + { + cipher = ciph; + padder = pad; + + plaintext.create(cipher->BLOCK_SIZE); + ciphertext.create(cipher->BLOCK_SIZE * PARALLEL_BLOCKS); + + position = 0; + + cipher->set_key(key); + } + +/* +* ECB_Encryption Destructor +*/ +ECB_Encryption::~ECB_Encryption() + { + delete cipher; + delete padder; } /* * Return an ECB mode name */ -std::string ECB::name() const +std::string ECB_Encryption::name() const { - return (cipher->name() + "/" + mode_name + "/" + padder->name()); + return (cipher->name() + "/ECB/" + padder->name()); } /* @@ -32,23 +70,34 @@ std::string ECB::name() const */ void ECB_Encryption::write(const byte input[], u32bit length) { - buffer.copy(position, input, length); - if(position + length >= BLOCK_SIZE) + const u32bit BLOCK_SIZE = cipher->BLOCK_SIZE; + + if(position) { - cipher->encrypt(buffer); - send(buffer, BLOCK_SIZE); - input += (BLOCK_SIZE - position); - length -= (BLOCK_SIZE - position); - while(length >= BLOCK_SIZE) + plaintext.copy(position, input, length); + + if(position + length >= BLOCK_SIZE) { - cipher->encrypt(input, buffer); - send(buffer, BLOCK_SIZE); - input += BLOCK_SIZE; - length -= BLOCK_SIZE; + cipher->encrypt(plaintext, ciphertext); + send(ciphertext, BLOCK_SIZE); + input += (BLOCK_SIZE - position); + length -= (BLOCK_SIZE - position); + position = 0; } - buffer.copy(input, length); - position = 0; } + + while(length >= BLOCK_SIZE) + { + const u32bit to_proc = + std::min<u32bit>(length, ciphertext.size()) / BLOCK_SIZE; + + cipher->encrypt_n(input, ciphertext, to_proc); + send(ciphertext, to_proc * BLOCK_SIZE); + input += to_proc * BLOCK_SIZE; + length -= to_proc * BLOCK_SIZE; + } + + plaintext.copy(position, input, length); position += length; } @@ -57,6 +106,8 @@ void ECB_Encryption::write(const byte input[], u32bit length) */ void ECB_Encryption::end_msg() { + const u32bit BLOCK_SIZE = cipher->BLOCK_SIZE; + SecureVector<byte> padding(BLOCK_SIZE); padder->pad(padding, padding.size(), position); write(padding, padder->pad_bytes(BLOCK_SIZE, position)); @@ -65,27 +116,93 @@ void ECB_Encryption::end_msg() } /* +* ECB_Decryption Constructor +*/ +ECB_Decryption::ECB_Decryption(BlockCipher* ciph, + BlockCipherModePaddingMethod* pad) + { + cipher = ciph; + padder = pad; + + ciphertext.create(cipher->BLOCK_SIZE); + plaintext.create(cipher->BLOCK_SIZE * PARALLEL_BLOCKS); + + position = 0; + } + +/* +* ECB_Decryption Constructor +*/ +ECB_Decryption::ECB_Decryption(BlockCipher* ciph, + BlockCipherModePaddingMethod* pad, + const SymmetricKey& key) + { + cipher = ciph; + padder = pad; + + ciphertext.create(cipher->BLOCK_SIZE); + plaintext.create(cipher->BLOCK_SIZE * PARALLEL_BLOCKS); + + position = 0; + + cipher->set_key(key); + } + +/* +* ECB_Decryption Destructor +*/ +ECB_Decryption::~ECB_Decryption() + { + delete cipher; + delete padder; + } + +/* +* Return an ECB mode name +*/ +std::string ECB_Decryption::name() const + { + return (cipher->name() + "/ECB/" + padder->name()); + } + +/* * Decrypt in ECB mode */ void ECB_Decryption::write(const byte input[], u32bit length) { - buffer.copy(position, input, length); - if(position + length > BLOCK_SIZE) + const u32bit BLOCK_SIZE = cipher->BLOCK_SIZE; + + if(position) { - cipher->decrypt(buffer); - send(buffer, BLOCK_SIZE); - input += (BLOCK_SIZE - position); - length -= (BLOCK_SIZE - position); - while(length > BLOCK_SIZE) + ciphertext.copy(position, input, length); + + if(position + length > BLOCK_SIZE) { - cipher->decrypt(input, buffer); - send(buffer, BLOCK_SIZE); - input += BLOCK_SIZE; - length -= BLOCK_SIZE; + cipher->decrypt(ciphertext, plaintext); + send(plaintext, BLOCK_SIZE); + input += (BLOCK_SIZE - position); + length -= (BLOCK_SIZE - position); + position = 0; } - buffer.copy(input, length); - position = 0; } + + while(length > BLOCK_SIZE) + { + /* Always leave at least 1 byte left over, to ensure that (as long + as the input message actually is a multiple of the block size) + we will have the full final block left over in end_msg so as + to remove the padding + */ + const u32bit to_proc = + std::min<u32bit>(length - 1, plaintext.size()) / BLOCK_SIZE; + + cipher->decrypt_n(input, plaintext, to_proc); + send(plaintext, to_proc * BLOCK_SIZE); + input += to_proc * BLOCK_SIZE; + length -= to_proc * BLOCK_SIZE; + } + + ciphertext.copy(position, input, length); position += length; } @@ -94,11 +211,11 @@ void ECB_Decryption::write(const byte input[], u32bit length) */ void ECB_Decryption::end_msg() { - if(position != BLOCK_SIZE) + if(position != cipher->BLOCK_SIZE) throw Decoding_Error(name()); - cipher->decrypt(buffer); - send(buffer, padder->unpad(buffer, BLOCK_SIZE)); - state = buffer; + + cipher->decrypt(ciphertext); + send(ciphertext, padder->unpad(ciphertext, cipher->BLOCK_SIZE)); position = 0; } diff --git a/src/modes/ecb/ecb.h b/src/modes/ecb/ecb.h index 5230f9b14..ff9ea9635 100644 --- a/src/modes/ecb/ecb.h +++ b/src/modes/ecb/ecb.h @@ -1,6 +1,6 @@ /* * ECB Mode -* (C) 1999-2007 Jack Lloyd +* (C) 1999-2009 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -8,64 +8,74 @@ #ifndef BOTAN_ECB_H__ #define BOTAN_ECB_H__ -#include <botan/modebase.h> -#include <botan/mode_pad.h> +#include <botan/basefilt.h> #include <botan/block_cipher.h> +#include <botan/mode_pad.h> -namespace Botan { - -/* -* ECB -*/ -class BOTAN_DLL ECB : public BlockCipherMode - { - protected: - ECB(BlockCipher* ciph, BlockCipherModePaddingMethod* pad) : - BlockCipherMode(ciph, "ECB", 0), padder(pad) {} - ~ECB() { delete padder; } +#include <botan/modebase.h> - std::string name() const; - BlockCipherModePaddingMethod* padder; - private: - bool valid_iv_size(u32bit) const; - }; +namespace Botan { /* * ECB Encryption */ -class BOTAN_DLL ECB_Encryption : public ECB +class BOTAN_DLL ECB_Encryption : public Keyed_Filter { public: + std::string name() const; + + void set_key(const SymmetricKey& key) { cipher->set_key(key); } + + bool valid_keylength(u32bit key_len) const + { return cipher->valid_keylength(key_len); } + ECB_Encryption(BlockCipher* ciph, - BlockCipherModePaddingMethod* pad) : - ECB(ciph, pad) {} + BlockCipherModePaddingMethod* pad); ECB_Encryption(BlockCipher* ciph, BlockCipherModePaddingMethod* pad, - const SymmetricKey& key) : - ECB(ciph, pad) { set_key(key); } + const SymmetricKey& key); + + ~ECB_Encryption(); private: void write(const byte[], u32bit); void end_msg(); + + BlockCipher* cipher; + BlockCipherModePaddingMethod* padder; + SecureVector<byte> plaintext, ciphertext; + u32bit position; }; /* * ECB Decryption */ -class BOTAN_DLL ECB_Decryption : public ECB +class BOTAN_DLL ECB_Decryption : public Keyed_Filter { public: + std::string name() const; + + void set_key(const SymmetricKey& key) { cipher->set_key(key); } + + bool valid_keylength(u32bit key_len) const + { return cipher->valid_keylength(key_len); } + ECB_Decryption(BlockCipher* ciph, - BlockCipherModePaddingMethod* pad) : - ECB(ciph, pad) {} + BlockCipherModePaddingMethod* pad); ECB_Decryption(BlockCipher* ciph, BlockCipherModePaddingMethod* pad, - const SymmetricKey& key) : - ECB(ciph, pad) { set_key(key); } + const SymmetricKey& key); + + ~ECB_Decryption(); private: void write(const byte[], u32bit); void end_msg(); + + BlockCipher* cipher; + BlockCipherModePaddingMethod* padder; + SecureVector<byte> plaintext, ciphertext; + u32bit position; }; } diff --git a/src/modes/ecb/info.txt b/src/modes/ecb/info.txt index 06b7b4fd2..f5c831169 100644 --- a/src/modes/ecb/info.txt +++ b/src/modes/ecb/info.txt @@ -1,5 +1,3 @@ -realname "ECB block cipher mode" - define ECB load_on auto diff --git a/src/modes/info.txt b/src/modes/info.txt index e089e74a9..420233b46 100644 --- a/src/modes/info.txt +++ b/src/modes/info.txt @@ -1,5 +1,3 @@ -realname "Cipher Mode Base Class" - define CIPHER_MODEBASE load_on auto diff --git a/src/modes/mode_pad/info.txt b/src/modes/mode_pad/info.txt index f22cf7411..9629a7202 100644 --- a/src/modes/mode_pad/info.txt +++ b/src/modes/mode_pad/info.txt @@ -1,5 +1,3 @@ -realname "Cipher Mode Padding Method" - define CIPHER_MODE_PADDING load_on auto diff --git a/src/modes/mode_pad/mode_pad.cpp b/src/modes/mode_pad/mode_pad.cpp index b8badd7a7..2204c28b5 100644 --- a/src/modes/mode_pad/mode_pad.cpp +++ b/src/modes/mode_pad/mode_pad.cpp @@ -7,7 +7,6 @@ #include <botan/mode_pad.h> #include <botan/exceptn.h> -#include <botan/util.h> namespace Botan { diff --git a/src/modes/modebase.cpp b/src/modes/modebase.cpp index 8293acc54..b048862a4 100644 --- a/src/modes/modebase.cpp +++ b/src/modes/modebase.cpp @@ -19,7 +19,7 @@ BlockCipherMode::BlockCipherMode(BlockCipher* cipher_ptr, BLOCK_SIZE(cipher_ptr->BLOCK_SIZE), BUFFER_SIZE(buf_mult * BLOCK_SIZE), IV_METHOD(iv_meth), mode_name(cipher_mode_name) { - base_ptr = cipher = cipher_ptr; + cipher = cipher_ptr; buffer.create(BUFFER_SIZE); state.create(iv_size); position = 0; diff --git a/src/modes/modebase.h b/src/modes/modebase.h index 173fde58c..4a15524b6 100644 --- a/src/modes/modebase.h +++ b/src/modes/modebase.h @@ -8,7 +8,7 @@ #ifndef BOTAN_MODEBASE_H__ #define BOTAN_MODEBASE_H__ -#include <botan/basefilt.h> +#include <botan/key_filt.h> #include <botan/block_cipher.h> namespace Botan { @@ -21,12 +21,17 @@ class BOTAN_DLL BlockCipherMode : public Keyed_Filter public: std::string name() const; + void set_iv(const InitializationVector&); + void set_key(const SymmetricKey& key) { cipher->set_key(key); } + + bool valid_keylength(u32bit key_len) const + { return cipher->valid_keylength(key_len); } + BlockCipherMode(BlockCipher*, const std::string&, u32bit, u32bit = 0, u32bit = 1); virtual ~BlockCipherMode() { delete cipher; } protected: - void set_iv(const InitializationVector&); const u32bit BLOCK_SIZE, BUFFER_SIZE, IV_METHOD; const std::string mode_name; BlockCipher* cipher; diff --git a/src/modes/ofb/ofb.cpp b/src/modes/ofb/ofb.cpp deleted file mode 100644 index cb40fdeaa..000000000 --- a/src/modes/ofb/ofb.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* -* OFB Mode -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/ofb.h> -#include <botan/xor_buf.h> -#include <algorithm> - -namespace Botan { - -/* -* OFB Constructor -*/ -OFB::OFB(BlockCipher* ciph) : - BlockCipherMode(ciph, "OFB", ciph->BLOCK_SIZE, 2) - { - } - -/* -* OFB Constructor -*/ -OFB::OFB(BlockCipher* ciph, const SymmetricKey& key, - const InitializationVector& iv) : - BlockCipherMode(ciph, "OFB", ciph->BLOCK_SIZE, 2) - { - set_key(key); - set_iv(iv); - } - -/* -* OFB Encryption/Decryption -*/ -void OFB::write(const byte input[], u32bit length) - { - u32bit copied = std::min(BLOCK_SIZE - position, length); - xor_buf(buffer, input, state + position, copied); - send(buffer, copied); - input += copied; - length -= copied; - position += copied; - - if(position == BLOCK_SIZE) - { - cipher->encrypt(state); - position = 0; - } - - while(length >= BLOCK_SIZE) - { - xor_buf(buffer, input, state, BLOCK_SIZE); - send(buffer, BLOCK_SIZE); - - input += BLOCK_SIZE; - length -= BLOCK_SIZE; - cipher->encrypt(state); - } - - xor_buf(buffer, input, state + position, length); - send(buffer, length); - position += length; - } - -} diff --git a/src/modes/ofb/ofb.h b/src/modes/ofb/ofb.h deleted file mode 100644 index a3aadc137..000000000 --- a/src/modes/ofb/ofb.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -* OFB Mode -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_OUTPUT_FEEDBACK_MODE_H__ -#define BOTAN_OUTPUT_FEEDBACK_MODE_H__ - -#include <botan/modebase.h> -#include <botan/block_cipher.h> - -namespace Botan { - -/* -* OFB Mode -*/ -class BOTAN_DLL OFB : public BlockCipherMode - { - public: - OFB(BlockCipher* cipher); - - OFB(BlockCipher* cipher, - const SymmetricKey& key, - const InitializationVector& iv); - private: - void write(const byte[], u32bit); - }; - -} - -#endif diff --git a/src/modes/xts/info.txt b/src/modes/xts/info.txt index 65c7df2f8..871bb987a 100644 --- a/src/modes/xts/info.txt +++ b/src/modes/xts/info.txt @@ -1,5 +1,3 @@ -realname "XTS block cipher mode" - define XTS load_on auto diff --git a/src/modes/xts/xts.h b/src/modes/xts/xts.h index 01558175b..9badd3666 100644 --- a/src/modes/xts/xts.h +++ b/src/modes/xts/xts.h @@ -8,7 +8,7 @@ #ifndef BOTAN_XTS_H__ #define BOTAN_XTS_H__ -#include <botan/basefilt.h> +#include <botan/key_filt.h> #include <botan/block_cipher.h> namespace Botan { @@ -22,6 +22,9 @@ class BOTAN_DLL XTS_Encryption : public Keyed_Filter void set_key(const SymmetricKey& key); void set_iv(const InitializationVector& iv); + bool valid_keylength(u32bit key_len) const + { return cipher->valid_keylength(key_len); } + std::string name() const; XTS_Encryption(BlockCipher* ciph); @@ -52,6 +55,9 @@ class BOTAN_DLL XTS_Decryption : public Keyed_Filter void set_key(const SymmetricKey& key); void set_iv(const InitializationVector& iv); + bool valid_keylength(u32bit key_len) const + { return cipher->valid_keylength(key_len); } + std::string name() const; XTS_Decryption(BlockCipher* ciph); diff --git a/src/mutex/info.txt b/src/mutex/info.txt index ff79bf753..0f2836b64 100644 --- a/src/mutex/info.txt +++ b/src/mutex/info.txt @@ -1,5 +1,3 @@ -realname "Mutex Wrappers" - define MUTEX_WRAPPERS load_on auto diff --git a/src/mutex/noop_mutex/info.txt b/src/mutex/noop_mutex/info.txt index 1f49f5e1c..6025959c2 100644 --- a/src/mutex/noop_mutex/info.txt +++ b/src/mutex/noop_mutex/info.txt @@ -1,5 +1,3 @@ -realname "No-Op Mutex" - load_on auto define MUTEX_NOOP diff --git a/src/mutex/pthreads/info.txt b/src/mutex/pthreads/info.txt index f135dea48..7315c186a 100644 --- a/src/mutex/pthreads/info.txt +++ b/src/mutex/pthreads/info.txt @@ -1,5 +1,3 @@ -realname "Pthread Mutex" - define MUTEX_PTHREAD load_on auto diff --git a/src/mutex/qt_mutex/info.txt b/src/mutex/qt_mutex/info.txt index a21108c79..922c38ed1 100644 --- a/src/mutex/qt_mutex/info.txt +++ b/src/mutex/qt_mutex/info.txt @@ -1,5 +1,3 @@ -realname "Qt Mutex" - define MUTEX_QT note "You'll probably have to add -I/-L flags to the Makefile to find Qt" diff --git a/src/mutex/win32_crit_section/info.txt b/src/mutex/win32_crit_section/info.txt index a2d339c3b..ffa8a98e3 100644 --- a/src/mutex/win32_crit_section/info.txt +++ b/src/mutex/win32_crit_section/info.txt @@ -1,5 +1,3 @@ -realname "Win32 Mutex" - define MUTEX_WIN32 modset win32 diff --git a/src/pbe/info.txt b/src/pbe/info.txt index c4210b2a7..f58ed1da4 100644 --- a/src/pbe/info.txt +++ b/src/pbe/info.txt @@ -1,5 +1,3 @@ -realname "PBE Base" - load_on dep define PASSWORD_BASED_ENCRYPTION diff --git a/src/pbe/pbes1/info.txt b/src/pbe/pbes1/info.txt index 70c6baeee..5dcbf9510 100644 --- a/src/pbe/pbes1/info.txt +++ b/src/pbe/pbes1/info.txt @@ -1,5 +1,3 @@ -realname "PKCS5 v1.5 PBE" - define PBE_PKCS_V15 load_on auto diff --git a/src/pbe/pbes2/info.txt b/src/pbe/pbes2/info.txt index cd37b1e69..71fb6ea72 100644 --- a/src/pbe/pbes2/info.txt +++ b/src/pbe/pbes2/info.txt @@ -1,5 +1,3 @@ -realname "PKCS5 v2.0 PBE" - define PBE_PKCS_V20 load_on auto diff --git a/src/pk_pad/eme1/info.txt b/src/pk_pad/eme1/info.txt index 2f61265e2..794254e8e 100644 --- a/src/pk_pad/eme1/info.txt +++ b/src/pk_pad/eme1/info.txt @@ -1,5 +1,3 @@ -realname "EME1" - define EME1 load_on auto diff --git a/src/pk_pad/eme_pkcs/info.txt b/src/pk_pad/eme_pkcs/info.txt index 88d9caf17..95c568452 100644 --- a/src/pk_pad/eme_pkcs/info.txt +++ b/src/pk_pad/eme_pkcs/info.txt @@ -1,5 +1,3 @@ -realname "PKCSv1 v1.5 EME" - define EME_PKCS1v15 load_on auto diff --git a/src/pk_pad/emsa.h b/src/pk_pad/emsa.h index e2491e40f..8b19d3cb2 100644 --- a/src/pk_pad/emsa.h +++ b/src/pk_pad/emsa.h @@ -27,7 +27,7 @@ class BOTAN_DLL EMSA RandomNumberGenerator& rng) = 0; virtual bool verify(const MemoryRegion<byte>&, const MemoryRegion<byte>&, - u32bit) throw() = 0; + u32bit) = 0; virtual ~EMSA() {} }; diff --git a/src/pk_pad/emsa1/emsa1.cpp b/src/pk_pad/emsa1/emsa1.cpp index 26d709c28..0ae7e8d2d 100644 --- a/src/pk_pad/emsa1/emsa1.cpp +++ b/src/pk_pad/emsa1/emsa1.cpp @@ -72,7 +72,7 @@ SecureVector<byte> EMSA1::encoding_of(const MemoryRegion<byte>& msg, * EMSA1 Decode/Verify Operation */ bool EMSA1::verify(const MemoryRegion<byte>& coded, - const MemoryRegion<byte>& raw, u32bit key_bits) throw() + const MemoryRegion<byte>& raw, u32bit key_bits) { try { if(raw.size() != hash->OUTPUT_LENGTH) diff --git a/src/pk_pad/emsa1/emsa1.h b/src/pk_pad/emsa1/emsa1.h index a5dac07e2..d86020966 100644 --- a/src/pk_pad/emsa1/emsa1.h +++ b/src/pk_pad/emsa1/emsa1.h @@ -31,7 +31,7 @@ class BOTAN_DLL EMSA1 : public EMSA RandomNumberGenerator& rng); bool verify(const MemoryRegion<byte>&, const MemoryRegion<byte>&, - u32bit) throw(); + u32bit); HashFunction* hash; }; diff --git a/src/pk_pad/emsa1/info.txt b/src/pk_pad/emsa1/info.txt index 086270b96..55832307b 100644 --- a/src/pk_pad/emsa1/info.txt +++ b/src/pk_pad/emsa1/info.txt @@ -1,5 +1,3 @@ -realname "EMSA1" - define EMSA1 load_on auto diff --git a/src/pk_pad/emsa1_bsi/info.txt b/src/pk_pad/emsa1_bsi/info.txt index 14a9fd396..5e8fe09ca 100644 --- a/src/pk_pad/emsa1_bsi/info.txt +++ b/src/pk_pad/emsa1_bsi/info.txt @@ -1,5 +1,3 @@ -realname "EMSA1 (BSI variant)" - define EMSA1_BSI load_on auto diff --git a/src/pk_pad/emsa2/emsa2.cpp b/src/pk_pad/emsa2/emsa2.cpp index 168f9209e..74a045931 100644 --- a/src/pk_pad/emsa2/emsa2.cpp +++ b/src/pk_pad/emsa2/emsa2.cpp @@ -79,7 +79,7 @@ SecureVector<byte> EMSA2::encoding_of(const MemoryRegion<byte>& msg, */ bool EMSA2::verify(const MemoryRegion<byte>& coded, const MemoryRegion<byte>& raw, - u32bit key_bits) throw() + u32bit key_bits) { try { diff --git a/src/pk_pad/emsa2/emsa2.h b/src/pk_pad/emsa2/emsa2.h index 76888d1f6..7efc80873 100644 --- a/src/pk_pad/emsa2/emsa2.h +++ b/src/pk_pad/emsa2/emsa2.h @@ -29,7 +29,7 @@ class BOTAN_DLL EMSA2 : public EMSA RandomNumberGenerator& rng); bool verify(const MemoryRegion<byte>&, const MemoryRegion<byte>&, - u32bit) throw(); + u32bit); SecureVector<byte> empty_hash; HashFunction* hash; diff --git a/src/pk_pad/emsa2/info.txt b/src/pk_pad/emsa2/info.txt index 1c8161c5e..a6fff2a02 100644 --- a/src/pk_pad/emsa2/info.txt +++ b/src/pk_pad/emsa2/info.txt @@ -1,5 +1,3 @@ -realname "EMSA2" - define EMSA2 load_on auto diff --git a/src/pk_pad/emsa3/emsa3.cpp b/src/pk_pad/emsa3/emsa3.cpp index 4d50abd84..dc905a464 100644 --- a/src/pk_pad/emsa3/emsa3.cpp +++ b/src/pk_pad/emsa3/emsa3.cpp @@ -72,7 +72,7 @@ SecureVector<byte> EMSA3::encoding_of(const MemoryRegion<byte>& msg, */ bool EMSA3::verify(const MemoryRegion<byte>& coded, const MemoryRegion<byte>& raw, - u32bit key_bits) throw() + u32bit key_bits) { if(raw.size() != hash->OUTPUT_LENGTH) return false; @@ -137,7 +137,7 @@ SecureVector<byte> EMSA3_Raw::encoding_of(const MemoryRegion<byte>& msg, */ bool EMSA3_Raw::verify(const MemoryRegion<byte>& coded, const MemoryRegion<byte>& raw, - u32bit key_bits) throw() + u32bit key_bits) { try { diff --git a/src/pk_pad/emsa3/emsa3.h b/src/pk_pad/emsa3/emsa3.h index 301f2142a..c4a3d658b 100644 --- a/src/pk_pad/emsa3/emsa3.h +++ b/src/pk_pad/emsa3/emsa3.h @@ -32,7 +32,7 @@ class BOTAN_DLL EMSA3 : public EMSA RandomNumberGenerator& rng); bool verify(const MemoryRegion<byte>&, const MemoryRegion<byte>&, - u32bit) throw(); + u32bit); private: HashFunction* hash; SecureVector<byte> hash_id; @@ -54,7 +54,7 @@ class BOTAN_DLL EMSA3_Raw : public EMSA RandomNumberGenerator& rng); bool verify(const MemoryRegion<byte>&, const MemoryRegion<byte>&, - u32bit) throw(); + u32bit); private: SecureVector<byte> message; diff --git a/src/pk_pad/emsa3/info.txt b/src/pk_pad/emsa3/info.txt index 90e4b9bfc..babd98711 100644 --- a/src/pk_pad/emsa3/info.txt +++ b/src/pk_pad/emsa3/info.txt @@ -1,5 +1,3 @@ -realname "EMSA3" - define EMSA3 load_on auto diff --git a/src/pk_pad/emsa4/emsa4.cpp b/src/pk_pad/emsa4/emsa4.cpp index cff9a1537..dba248662 100644 --- a/src/pk_pad/emsa4/emsa4.cpp +++ b/src/pk_pad/emsa4/emsa4.cpp @@ -68,7 +68,7 @@ SecureVector<byte> EMSA4::encoding_of(const MemoryRegion<byte>& msg, * EMSA4 Decode/Verify Operation */ bool EMSA4::verify(const MemoryRegion<byte>& const_coded, - const MemoryRegion<byte>& raw, u32bit key_bits) throw() + const MemoryRegion<byte>& raw, u32bit key_bits) { const u32bit HASH_SIZE = hash->OUTPUT_LENGTH; const u32bit KEY_BYTES = (key_bits + 7) / 8; diff --git a/src/pk_pad/emsa4/emsa4.h b/src/pk_pad/emsa4/emsa4.h index b716178a9..9e37684f5 100644 --- a/src/pk_pad/emsa4/emsa4.h +++ b/src/pk_pad/emsa4/emsa4.h @@ -31,7 +31,7 @@ class BOTAN_DLL EMSA4 : public EMSA SecureVector<byte> encoding_of(const MemoryRegion<byte>&, u32bit, RandomNumberGenerator& rng); bool verify(const MemoryRegion<byte>&, const MemoryRegion<byte>&, - u32bit) throw(); + u32bit); u32bit SALT_SIZE; HashFunction* hash; diff --git a/src/pk_pad/emsa4/info.txt b/src/pk_pad/emsa4/info.txt index 29ef4e0cf..ea1db30a1 100644 --- a/src/pk_pad/emsa4/info.txt +++ b/src/pk_pad/emsa4/info.txt @@ -1,5 +1,3 @@ -realname "EMSA4" - define EMSA4 load_on auto diff --git a/src/pk_pad/emsa_raw/emsa_raw.cpp b/src/pk_pad/emsa_raw/emsa_raw.cpp index d5973ee55..5dfe20a50 100644 --- a/src/pk_pad/emsa_raw/emsa_raw.cpp +++ b/src/pk_pad/emsa_raw/emsa_raw.cpp @@ -42,7 +42,7 @@ SecureVector<byte> EMSA_Raw::encoding_of(const MemoryRegion<byte>& msg, */ bool EMSA_Raw::verify(const MemoryRegion<byte>& coded, const MemoryRegion<byte>& raw, - u32bit) throw() + u32bit) { return (coded == raw); } diff --git a/src/pk_pad/emsa_raw/emsa_raw.h b/src/pk_pad/emsa_raw/emsa_raw.h index 1b0ad516e..5f2eaa2fe 100644 --- a/src/pk_pad/emsa_raw/emsa_raw.h +++ b/src/pk_pad/emsa_raw/emsa_raw.h @@ -24,7 +24,7 @@ class BOTAN_DLL EMSA_Raw : public EMSA SecureVector<byte> encoding_of(const MemoryRegion<byte>&, u32bit, RandomNumberGenerator&); bool verify(const MemoryRegion<byte>&, const MemoryRegion<byte>&, - u32bit) throw(); + u32bit); SecureVector<byte> message; }; diff --git a/src/pk_pad/emsa_raw/info.txt b/src/pk_pad/emsa_raw/info.txt index 2a88d10fa..4bd850e11 100644 --- a/src/pk_pad/emsa_raw/info.txt +++ b/src/pk_pad/emsa_raw/info.txt @@ -1,5 +1,3 @@ -realname "EMSA-Raw" - define EMSA_RAW load_on auto diff --git a/src/pk_pad/hash_id/info.txt b/src/pk_pad/hash_id/info.txt index 935432588..af9f5cd4f 100644 --- a/src/pk_pad/hash_id/info.txt +++ b/src/pk_pad/hash_id/info.txt @@ -1,5 +1,3 @@ -realname "Hash Function Identifiers" - define HASH_ID load_on auto diff --git a/src/pk_pad/info.txt b/src/pk_pad/info.txt index c281b1563..14b05f458 100644 --- a/src/pk_pad/info.txt +++ b/src/pk_pad/info.txt @@ -1,5 +1,3 @@ -realname "Public Key EME/EMSA Padding Modes" - define PK_PADDING load_on auto diff --git a/src/pubkey/dh/dh.cpp b/src/pubkey/dh/dh.cpp index 0c9d02f0e..149bc5882 100644 --- a/src/pubkey/dh/dh.cpp +++ b/src/pubkey/dh/dh.cpp @@ -7,7 +7,7 @@ #include <botan/dh.h> #include <botan/numthry.h> -#include <botan/util.h> +#include <botan/workfactor.h> namespace Botan { diff --git a/src/pubkey/dh/info.txt b/src/pubkey/dh/info.txt index 33af9a8e5..8295a74f4 100644 --- a/src/pubkey/dh/info.txt +++ b/src/pubkey/dh/info.txt @@ -1,5 +1,3 @@ -realname "Diffie-Hellman Key Agreement" - define DIFFIE_HELLMAN load_on auto diff --git a/src/pubkey/dl_algo/info.txt b/src/pubkey/dl_algo/info.txt index 15a77516b..0ac91c887 100644 --- a/src/pubkey/dl_algo/info.txt +++ b/src/pubkey/dl_algo/info.txt @@ -1,5 +1,3 @@ -realname "Discrete Logarithm PK Algorithms" - define DL_PUBLIC_KEY_FAMILY load_on auto diff --git a/src/pubkey/dl_group/dl_group.cpp b/src/pubkey/dl_group/dl_group.cpp index 81c5d5e1d..13ea03016 100644 --- a/src/pubkey/dl_group/dl_group.cpp +++ b/src/pubkey/dl_group/dl_group.cpp @@ -12,7 +12,7 @@ #include <botan/der_enc.h> #include <botan/ber_dec.h> #include <botan/pipe.h> -#include <botan/util.h> +#include <botan/workfactor.h> #include <botan/pem.h> namespace Botan { diff --git a/src/pubkey/dl_group/info.txt b/src/pubkey/dl_group/info.txt index 6b9884a4d..2e5273ac4 100644 --- a/src/pubkey/dl_group/info.txt +++ b/src/pubkey/dl_group/info.txt @@ -1,5 +1,3 @@ -realname "DL Group" - load_on auto define DL_GROUP diff --git a/src/pubkey/dlies/info.txt b/src/pubkey/dlies/info.txt index 5138aafc5..d3e950427 100644 --- a/src/pubkey/dlies/info.txt +++ b/src/pubkey/dlies/info.txt @@ -1,5 +1,3 @@ -realname "DLIES" - define DLIES load_on auto diff --git a/src/pubkey/dsa/info.txt b/src/pubkey/dsa/info.txt index c70e02d90..776a5da28 100644 --- a/src/pubkey/dsa/info.txt +++ b/src/pubkey/dsa/info.txt @@ -1,5 +1,3 @@ -realname "DSA" - define DSA load_on auto diff --git a/src/pubkey/ec_dompar/ec_dompar.cpp b/src/pubkey/ec_dompar/ec_dompar.cpp index 6cfcc0619..0b5a6e681 100644 --- a/src/pubkey/ec_dompar/ec_dompar.cpp +++ b/src/pubkey/ec_dompar/ec_dompar.cpp @@ -1,3 +1,11 @@ +/* +* ECC Domain Parameters +* +* (C) 2007 Falko Strenzke, FlexSecure GmbH +* 2008 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ #include <botan/ec_dompar.h> #include <botan/pubkey_enums.h> diff --git a/src/pubkey/ec_dompar/ec_dompar.h b/src/pubkey/ec_dompar/ec_dompar.h index 47971d802..5ea599c9d 100644 --- a/src/pubkey/ec_dompar/ec_dompar.h +++ b/src/pubkey/ec_dompar/ec_dompar.h @@ -1,5 +1,6 @@ /* -* ECDSA Domain Parameters +* ECC Domain Parameters +* * (C) 2007 Falko Strenzke, FlexSecure GmbH * 2008 Jack Lloyd * diff --git a/src/pubkey/ec_dompar/info.txt b/src/pubkey/ec_dompar/info.txt index 212783725..f32e4fc2f 100644 --- a/src/pubkey/ec_dompar/info.txt +++ b/src/pubkey/ec_dompar/info.txt @@ -1,5 +1,3 @@ -realname "ECC Domain Parameters" - define ECC_DOMAIN_PARAMATERS load_on auto diff --git a/src/pubkey/ecc_key/ecc_key.cpp b/src/pubkey/ecc_key/ecc_key.cpp index 615efecf1..677a5088e 100644 --- a/src/pubkey/ecc_key/ecc_key.cpp +++ b/src/pubkey/ecc_key/ecc_key.cpp @@ -10,7 +10,6 @@ #include <botan/ecc_key.h> #include <botan/x509_key.h> #include <botan/numthry.h> -#include <botan/util.h> #include <botan/der_enc.h> #include <botan/ber_dec.h> #include <botan/secmem.h> diff --git a/src/pubkey/ecc_key/info.txt b/src/pubkey/ecc_key/info.txt index 2a3c9a3b2..f45533129 100644 --- a/src/pubkey/ecc_key/info.txt +++ b/src/pubkey/ecc_key/info.txt @@ -1,5 +1,3 @@ -realname "ECC Public Key" - define ECC_PUBLIC_KEY_CRYPTO load_on auto diff --git a/src/pubkey/ecdsa/ecdsa.cpp b/src/pubkey/ecdsa/ecdsa.cpp index 9640c6397..ea2c35a19 100644 --- a/src/pubkey/ecdsa/ecdsa.cpp +++ b/src/pubkey/ecdsa/ecdsa.cpp @@ -9,7 +9,6 @@ #include <botan/ecdsa.h> #include <botan/numthry.h> -#include <botan/util.h> #include <botan/der_enc.h> #include <botan/ber_dec.h> #include <botan/secmem.h> diff --git a/src/pubkey/ecdsa/info.txt b/src/pubkey/ecdsa/info.txt index 743440f8f..3da73dd34 100644 --- a/src/pubkey/ecdsa/info.txt +++ b/src/pubkey/ecdsa/info.txt @@ -1,5 +1,3 @@ -realname "ECDSA" - define ECDSA load_on auto diff --git a/src/pubkey/eckaeg/eckaeg.cpp b/src/pubkey/eckaeg/eckaeg.cpp index b8ff75d89..dc6eb925b 100644 --- a/src/pubkey/eckaeg/eckaeg.cpp +++ b/src/pubkey/eckaeg/eckaeg.cpp @@ -9,7 +9,6 @@ #include <botan/eckaeg.h> #include <botan/numthry.h> -#include <botan/util.h> #include <botan/der_enc.h> #include <botan/ber_dec.h> #include <botan/secmem.h> diff --git a/src/pubkey/eckaeg/info.txt b/src/pubkey/eckaeg/info.txt index 6b78f7de5..3a9768df1 100644 --- a/src/pubkey/eckaeg/info.txt +++ b/src/pubkey/eckaeg/info.txt @@ -1,5 +1,3 @@ -realname "ECKAEG" - define ECKAEG load_on auto diff --git a/src/pubkey/elgamal/elgamal.cpp b/src/pubkey/elgamal/elgamal.cpp index 1f79df57a..8c07c5735 100644 --- a/src/pubkey/elgamal/elgamal.cpp +++ b/src/pubkey/elgamal/elgamal.cpp @@ -9,7 +9,7 @@ #include <botan/numthry.h> #include <botan/keypair.h> #include <botan/look_pk.h> -#include <botan/util.h> +#include <botan/workfactor.h> namespace Botan { diff --git a/src/pubkey/elgamal/info.txt b/src/pubkey/elgamal/info.txt index d7ae614ea..8c55eb909 100644 --- a/src/pubkey/elgamal/info.txt +++ b/src/pubkey/elgamal/info.txt @@ -1,5 +1,3 @@ -realname "ElGamal" - define ELGAMAL load_on auto diff --git a/src/pubkey/if_algo/info.txt b/src/pubkey/if_algo/info.txt index d2142f42f..ec948aec3 100644 --- a/src/pubkey/if_algo/info.txt +++ b/src/pubkey/if_algo/info.txt @@ -1,5 +1,3 @@ -realname "Integer Factorization Algorithms" - define IF_PUBLIC_KEY_FAMILY load_on dep diff --git a/src/pubkey/info.txt b/src/pubkey/info.txt index ee8da5b9d..13cac9ca0 100644 --- a/src/pubkey/info.txt +++ b/src/pubkey/info.txt @@ -1,5 +1,3 @@ -realname "Public Key Base" - define PUBLIC_KEY_CRYPTO load_on auto @@ -15,6 +13,8 @@ pubkey.cpp pubkey.h pubkey_enums.cpp pubkey_enums.h +workfactor.cpp +workfactor.h </add> <requires> diff --git a/src/pubkey/keypair/info.txt b/src/pubkey/keypair/info.txt index 9e758643f..360d317c5 100644 --- a/src/pubkey/keypair/info.txt +++ b/src/pubkey/keypair/info.txt @@ -1,5 +1,3 @@ -realname "Keypair Testing" - define KEYPAIR_TESTING load_on auto diff --git a/src/pubkey/nr/info.txt b/src/pubkey/nr/info.txt index c89820aeb..dcf22033e 100644 --- a/src/pubkey/nr/info.txt +++ b/src/pubkey/nr/info.txt @@ -1,5 +1,3 @@ -realname "Nyberg-Rueppel" - define NYBERG_RUEPPEL load_on auto diff --git a/src/pubkey/pk_codecs/info.txt b/src/pubkey/pk_codecs/info.txt index 96511a663..55c71b0c9 100644 --- a/src/pubkey/pk_codecs/info.txt +++ b/src/pubkey/pk_codecs/info.txt @@ -1,5 +1,3 @@ -realname "PK codecs (PKCS8, X.509)" - load_on auto <add> diff --git a/src/pubkey/rsa/info.txt b/src/pubkey/rsa/info.txt index 7729fd83d..c8bde68d0 100644 --- a/src/pubkey/rsa/info.txt +++ b/src/pubkey/rsa/info.txt @@ -1,5 +1,3 @@ -realname "RSA" - define RSA load_on auto diff --git a/src/pubkey/rsa/rsa.h b/src/pubkey/rsa/rsa.h index f07533a4f..0580fe8eb 100644 --- a/src/pubkey/rsa/rsa.h +++ b/src/pubkey/rsa/rsa.h @@ -28,7 +28,13 @@ class BOTAN_DLL RSA_PublicKey : public PK_Encrypting_Key, SecureVector<byte> verify(const byte[], u32bit) const; RSA_PublicKey() {} - RSA_PublicKey(const BigInt&, const BigInt&); + + /** + * Create a RSA_PublicKey + * @arg n the modulus + * @arg e the exponent + */ + RSA_PublicKey(const BigInt& n, const BigInt& e); protected: BigInt public_op(const BigInt&) const; }; diff --git a/src/pubkey/rw/info.txt b/src/pubkey/rw/info.txt index ada6c37d6..39857bccc 100644 --- a/src/pubkey/rw/info.txt +++ b/src/pubkey/rw/info.txt @@ -1,5 +1,3 @@ -realname "Rabin-Williams" - define RW load_on auto diff --git a/src/utils/util.cpp b/src/pubkey/workfactor.cpp index 84dfd1a14..e40b7919c 100644 --- a/src/utils/util.cpp +++ b/src/pubkey/workfactor.cpp @@ -1,35 +1,17 @@ /* -* Utility Functions +* Public Key Work Factor Functions * (C) 1999-2007 Jack Lloyd * * Distributed under the terms of the Botan license */ -#include <botan/util.h> +#include <botan/workfactor.h> #include <algorithm> #include <cmath> namespace Botan { /* -* Round up n to multiple of align_to -*/ -u32bit round_up(u32bit n, u32bit align_to) - { - if(n % align_to || n == 0) - n += align_to - (n % align_to); - return n; - } - -/* -* Round down n to multiple of align_to -*/ -u32bit round_down(u32bit n, u32bit align_to) - { - return (n - (n % align_to)); - } - -/* * Choose the exponent size for a DL group */ u32bit dl_work_factor(u32bit bits) @@ -65,4 +47,5 @@ u32bit dl_work_factor(u32bit bits) #endif } + } diff --git a/src/pubkey/workfactor.h b/src/pubkey/workfactor.h new file mode 100644 index 000000000..653f697e3 --- /dev/null +++ b/src/pubkey/workfactor.h @@ -0,0 +1,22 @@ +/* +* Public Key Work Factor Functions +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_WORKFACTOR_H__ +#define BOTAN_WORKFACTOR_H__ + +#include <botan/types.h> + +namespace Botan { + +/* +* Work Factor Estimates +*/ +BOTAN_DLL u32bit dl_work_factor(u32bit prime_group_size); + +} + +#endif diff --git a/src/rng/auto_rng/auto_rng.cpp b/src/rng/auto_rng/auto_rng.cpp index 8405170ad..f02a9249f 100644 --- a/src/rng/auto_rng/auto_rng.cpp +++ b/src/rng/auto_rng/auto_rng.cpp @@ -143,7 +143,7 @@ AutoSeeded_RNG::AutoSeeded_RNG(u32bit poll_bits) #endif if(!rng) - throw Algorithm_Not_Found("No usable RNG found enabled in build"); + throw Internal_Error("No usable RNG found enabled in build"); /* If X9.31 is available, use it to wrap the other RNG as a failsafe */ #if defined(BOTAN_HAS_X931_RNG) && defined(BOTAN_HAS_AES) diff --git a/src/rng/auto_rng/auto_rng.h b/src/rng/auto_rng/auto_rng.h index f18f8e5cd..a15b11b13 100644 --- a/src/rng/auto_rng/auto_rng.h +++ b/src/rng/auto_rng/auto_rng.h @@ -23,7 +23,7 @@ class BOTAN_DLL AutoSeeded_RNG : public RandomNumberGenerator { rng->randomize(out, len); } bool is_seeded() const { return rng->is_seeded(); } - void clear() throw() { rng->clear(); } + void clear() { rng->clear(); } std::string name() const { return "AutoSeeded(" + rng->name() + ")"; } diff --git a/src/rng/auto_rng/info.txt b/src/rng/auto_rng/info.txt index 7d5d5ddcc..d5abfc757 100644 --- a/src/rng/auto_rng/info.txt +++ b/src/rng/auto_rng/info.txt @@ -1,5 +1,3 @@ -realname "Auto-seeded Random Number Generator" - define AUTO_SEEDING_RNG load_on auto diff --git a/src/rng/hmac_rng/hmac_rng.cpp b/src/rng/hmac_rng/hmac_rng.cpp index 113489db3..9d5ee97e4 100644 --- a/src/rng/hmac_rng/hmac_rng.cpp +++ b/src/rng/hmac_rng/hmac_rng.cpp @@ -8,7 +8,6 @@ #include <botan/hmac_rng.h> #include <botan/loadstor.h> #include <botan/xor_buf.h> -#include <botan/util.h> #include <botan/stl_util.h> #include <algorithm> @@ -148,7 +147,7 @@ void HMAC_RNG::add_entropy_source(EntropySource* src) /* * Clear memory of sensitive data */ -void HMAC_RNG::clear() throw() +void HMAC_RNG::clear() { extractor->clear(); prf->clear(); diff --git a/src/rng/hmac_rng/hmac_rng.h b/src/rng/hmac_rng/hmac_rng.h index 318e2a931..97b0baf15 100644 --- a/src/rng/hmac_rng/hmac_rng.h +++ b/src/rng/hmac_rng/hmac_rng.h @@ -29,7 +29,7 @@ class BOTAN_DLL HMAC_RNG : public RandomNumberGenerator public: void randomize(byte buf[], u32bit len); bool is_seeded() const { return seeded; } - void clear() throw(); + void clear(); std::string name() const; void reseed(u32bit poll_bits); diff --git a/src/rng/hmac_rng/info.txt b/src/rng/hmac_rng/info.txt index 2c7f13e0a..f6135ee5a 100644 --- a/src/rng/hmac_rng/info.txt +++ b/src/rng/hmac_rng/info.txt @@ -1,5 +1,3 @@ -realname "HMAC RNG" - define HMAC_RNG load_on auto diff --git a/src/rng/info.txt b/src/rng/info.txt index 44a41665d..eea122cf9 100644 --- a/src/rng/info.txt +++ b/src/rng/info.txt @@ -1,5 +1,3 @@ -realname "Random Number Generators" - load_on auto <add> diff --git a/src/rng/randpool/info.txt b/src/rng/randpool/info.txt index cc7f61552..cab276e15 100644 --- a/src/rng/randpool/info.txt +++ b/src/rng/randpool/info.txt @@ -1,5 +1,3 @@ -realname "Randpool RNG" - define RANDPOOL load_on auto diff --git a/src/rng/randpool/randpool.cpp b/src/rng/randpool/randpool.cpp index 77a5228c6..9ec92267d 100644 --- a/src/rng/randpool/randpool.cpp +++ b/src/rng/randpool/randpool.cpp @@ -8,7 +8,7 @@ #include <botan/randpool.h> #include <botan/loadstor.h> #include <botan/xor_buf.h> -#include <botan/util.h> +#include <botan/timer.h> #include <botan/stl_util.h> #include <algorithm> @@ -149,7 +149,7 @@ void Randpool::add_entropy_source(EntropySource* src) /** * Clear memory of sensitive data */ -void Randpool::clear() throw() +void Randpool::clear() { cipher->clear(); mac->clear(); diff --git a/src/rng/randpool/randpool.h b/src/rng/randpool/randpool.h index b6a3adda4..ab6ed6748 100644 --- a/src/rng/randpool/randpool.h +++ b/src/rng/randpool/randpool.h @@ -23,7 +23,7 @@ class BOTAN_DLL Randpool : public RandomNumberGenerator public: void randomize(byte[], u32bit); bool is_seeded() const { return seeded; } - void clear() throw(); + void clear(); std::string name() const; void reseed(u32bit bits_to_collect); diff --git a/src/rng/rng.h b/src/rng/rng.h index 41904dbef..c53d8e22d 100644 --- a/src/rng/rng.h +++ b/src/rng/rng.h @@ -47,7 +47,7 @@ class BOTAN_DLL RandomNumberGenerator /** * Clear all internally held values of this RNG. */ - virtual void clear() throw() = 0; + virtual void clear() = 0; /** * Return the name of this object @@ -89,7 +89,7 @@ class BOTAN_DLL Null_RNG : public RandomNumberGenerator { public: void randomize(byte[], u32bit) { throw PRNG_Unseeded("Null_RNG"); } - void clear() throw() {} + void clear() {} std::string name() const { return "Null_RNG"; } void reseed(u32bit) {} diff --git a/src/rng/x931_rng/info.txt b/src/rng/x931_rng/info.txt index 633eb0268..35836b33b 100644 --- a/src/rng/x931_rng/info.txt +++ b/src/rng/x931_rng/info.txt @@ -1,5 +1,3 @@ -realname "ANSI X9.31 PRNG" - define X931_RNG load_on auto diff --git a/src/rng/x931_rng/x931_rng.cpp b/src/rng/x931_rng/x931_rng.cpp index e239bce84..64d57ac1c 100644 --- a/src/rng/x931_rng/x931_rng.cpp +++ b/src/rng/x931_rng/x931_rng.cpp @@ -108,7 +108,7 @@ bool ANSI_X931_RNG::is_seeded() const /** * Clear memory of sensitive data */ -void ANSI_X931_RNG::clear() throw() +void ANSI_X931_RNG::clear() { cipher->clear(); prng->clear(); diff --git a/src/rng/x931_rng/x931_rng.h b/src/rng/x931_rng/x931_rng.h index 44e9b4428..d5ba2e9eb 100644 --- a/src/rng/x931_rng/x931_rng.h +++ b/src/rng/x931_rng/x931_rng.h @@ -21,7 +21,7 @@ class BOTAN_DLL ANSI_X931_RNG : public RandomNumberGenerator public: void randomize(byte[], u32bit); bool is_seeded() const; - void clear() throw(); + void clear(); std::string name() const; void reseed(u32bit poll_bits); diff --git a/src/s2k/info.txt b/src/s2k/info.txt index e603fd937..17f2a8c42 100644 --- a/src/s2k/info.txt +++ b/src/s2k/info.txt @@ -1,5 +1,3 @@ -realname "String to Key Functions" - load_on auto <add> diff --git a/src/s2k/pbkdf1/info.txt b/src/s2k/pbkdf1/info.txt index 4c5b27546..387043f1b 100644 --- a/src/s2k/pbkdf1/info.txt +++ b/src/s2k/pbkdf1/info.txt @@ -1,5 +1,3 @@ -realname "Pbkdf1" - define PBKDF1 load_on auto diff --git a/src/s2k/pbkdf2/info.txt b/src/s2k/pbkdf2/info.txt index 921aeb1ab..56359d13d 100644 --- a/src/s2k/pbkdf2/info.txt +++ b/src/s2k/pbkdf2/info.txt @@ -1,5 +1,3 @@ -realname "Pbkdf2" - define PBKDF2 load_on auto diff --git a/src/s2k/pgps2k/info.txt b/src/s2k/pgps2k/info.txt index 14b75a02b..a1f5b3dfd 100644 --- a/src/s2k/pgps2k/info.txt +++ b/src/s2k/pgps2k/info.txt @@ -1,5 +1,3 @@ -realname "Pgps2k" - define PGPS2K load_on auto diff --git a/src/selftest/info.txt b/src/selftest/info.txt index 323a610a6..079fd5030 100644 --- a/src/selftest/info.txt +++ b/src/selftest/info.txt @@ -1,5 +1,3 @@ -realname "Selftests" - define SELFTESTS load_on auto @@ -11,11 +9,6 @@ selftest.h <requires> algo_factory -cbc -cfb -ctr -ecb filters -hmac -ofb +def_engine </requires> diff --git a/src/selftest/selftest.cpp b/src/selftest/selftest.cpp index d644e866e..660be36e4 100644 --- a/src/selftest/selftest.cpp +++ b/src/selftest/selftest.cpp @@ -7,12 +7,8 @@ #include <botan/selftest.h> #include <botan/filters.h> -#include <botan/ecb.h> -#include <botan/cbc.h> -#include <botan/cfb.h> -#include <botan/ofb.h> -#include <botan/ctr.h> -#include <botan/hmac.h> +#include <botan/def_eng.h> +#include <botan/stl_util.h> namespace Botan { @@ -21,23 +17,143 @@ namespace { /* * Perform a Known Answer Test */ -void do_kat(const std::string& in, const std::string& out, - const std::string& algo_name, Filter* filter) +bool test_filter_kat(Filter* filter, + const std::string& input, + const std::string& output) { - if(out.length()) + Pipe pipe(new Hex_Decoder, filter, new Hex_Encoder); + pipe.process_msg(input); + + return (output == pipe.read_all_as_string()); + } + +} + +/* +* Run a set of KATs +*/ +std::map<std::string, bool> +algorithm_kat(const SCAN_Name& algo_name, + const std::map<std::string, std::string>& vars, + Algorithm_Factory& af) + { + const std::string& algo = algo_name.algo_name_and_args(); + + std::vector<std::string> providers = af.providers_of(algo); + std::map<std::string, bool> all_results; + + if(providers.empty()) // no providers, nothing to do + return all_results; + + const std::string input = search_map(vars, std::string("input")); + const std::string output = search_map(vars, std::string("output")); + const std::string key = search_map(vars, std::string("key")); + const std::string iv = search_map(vars, std::string("iv")); + + for(u32bit i = 0; i != providers.size(); ++i) { - Pipe pipe(new Hex_Decoder, filter, new Hex_Encoder); - pipe.process_msg(in); + const std::string provider = providers[i]; - if(out != pipe.read_all_as_string()) - throw Self_Test_Failure(algo_name + " startup test"); + if(const HashFunction* proto = + af.prototype_hash_function(algo, provider)) + { + Filter* filt = new Hash_Filter(proto->clone()); + all_results[provider] = test_filter_kat(filt, input, output); + } + else if(const MessageAuthenticationCode* proto = + af.prototype_mac(algo, provider)) + { + Keyed_Filter* filt = new MAC_Filter(proto->clone(), key); + all_results[provider] = test_filter_kat(filt, input, output); + } + else if(const StreamCipher* proto = + af.prototype_stream_cipher(algo, provider)) + { + Keyed_Filter* filt = new StreamCipher_Filter(proto->clone()); + filt->set_key(key); + filt->set_iv(iv); + + all_results[provider] = test_filter_kat(filt, input, output); + } + else if(const BlockCipher* proto = + af.prototype_block_cipher(algo, provider)) + { + Keyed_Filter* enc = get_cipher_mode(proto, ENCRYPTION, + algo_name.cipher_mode(), + algo_name.cipher_mode_pad()); + + Keyed_Filter* dec = get_cipher_mode(proto, DECRYPTION, + algo_name.cipher_mode(), + algo_name.cipher_mode_pad()); + + if(!enc || !dec) + { + delete enc; + delete dec; + continue; + } + + enc->set_key(key); + enc->set_iv(iv); + + dec->set_key(key); + dec->set_iv(iv); + + bool enc_ok = test_filter_kat(enc, input, output); + bool dec_ok = test_filter_kat(dec, output, input); + + all_results[provider] = enc_ok && dec_ok; + } } + + return all_results; + } + +namespace { + +void verify_results(const std::string& algo, + const std::map<std::string, bool>& results) + { + for(std::map<std::string, bool>::const_iterator i = results.begin(); + i != results.end(); ++i) + { + if(!i->second) + throw Self_Test_Failure(algo + " self-test failed, provider "+ + i->first); + } + } + +void hash_test(Algorithm_Factory& af, + const std::string& name, + const std::string& in, + const std::string& out) + { + std::map<std::string, std::string> vars; + vars["input"] = in; + vars["output"] = out; + + verify_results(name, algorithm_kat(name, vars, af)); + } + +void mac_test(Algorithm_Factory& af, + const std::string& name, + const std::string& in, + const std::string& out, + const std::string& key) + { + std::map<std::string, std::string> vars; + vars["input"] = in; + vars["output"] = out; + vars["key"] = key; + + verify_results(name, algorithm_kat(name, vars, af)); } /* * Perform a KAT for a cipher */ -void cipher_kat(const BlockCipher* proto, +void cipher_kat(Algorithm_Factory& af, + const std::string& algo, const std::string& key_str, const std::string& iv_str, const std::string& in, @@ -50,27 +166,28 @@ void cipher_kat(const BlockCipher* proto, SymmetricKey key(key_str); InitializationVector iv(iv_str); - std::string name = proto->name(); + std::map<std::string, std::string> vars; + vars["key"] = key_str; + vars["iv"] = iv_str; + vars["input"] = in; + + std::map<std::string, bool> results; - do_kat(in, ecb_out, name + "/ECB", - new ECB_Encryption(proto->clone(), new Null_Padding, key)); - do_kat(ecb_out, in, name + "/ECB", - new ECB_Decryption(proto->clone(), new Null_Padding, key)); + vars["output"] = ecb_out; + verify_results(algo + "/ECB", algorithm_kat(algo + "/ECB", vars, af)); - do_kat(in, cbc_out, name + "/CBC", - new CBC_Encryption(proto->clone(), new Null_Padding, key, iv)); - do_kat(cbc_out, in, name + "/CBC", - new CBC_Decryption(proto->clone(), new Null_Padding, key, iv)); + vars["output"] = cbc_out; + verify_results(algo + "/CBC", + algorithm_kat(algo + "/CBC/NoPadding", vars, af)); - do_kat(in, cfb_out, name + "/CFB", - new CFB_Encryption(proto->clone(), key, iv)); - do_kat(cfb_out, in, name + "/CFB", - new CFB_Decryption(proto->clone(), key, iv)); + vars["output"] = cfb_out; + verify_results(algo + "/CFB", algorithm_kat(algo + "/CFB", vars, af)); - do_kat(in, ofb_out, name + "/OFB", new OFB(proto->clone(), key, iv)); + vars["output"] = ofb_out; + verify_results(algo + "/OFB", algorithm_kat(algo + "/OFB", vars, af)); - do_kat(in, ctr_out, name + "/CTR-BE", - new CTR_BE(proto->clone(), key, iv)); + vars["output"] = ctr_out; + verify_results(algo + "/CTR", algorithm_kat(algo + "/CTR-BE", vars, af)); } } @@ -82,9 +199,7 @@ bool passes_self_tests(Algorithm_Factory& af) { try { - if(const BlockCipher* proto = af.prototype_block_cipher("DES")) - { - cipher_kat(proto, + cipher_kat(af, "DES", "0123456789ABCDEF", "1234567890ABCDEF", "4E6F77206973207468652074696D6520666F7220616C6C20", "3FA40E8A984D48156A271787AB8883F9893D51EC4B563B53", @@ -92,11 +207,8 @@ bool passes_self_tests(Algorithm_Factory& af) "F3096249C7F46E51A69E839B1A92F78403467133898EA622", "F3096249C7F46E5135F24A242EEB3D3F3D6D5BE3255AF8C3", "F3096249C7F46E51163A8CA0FFC94C27FA2F80F480B86F75"); - } - if(const BlockCipher* proto = af.prototype_block_cipher("TripleDES")) - { - cipher_kat(proto, + cipher_kat(af, "TripleDES", "385D7189A5C3D485E1370AA5D408082B5CCCCB5E19F2D90E", "C141B5FCCD28DC8A", "6E1BD7C6120947A464A6AAB293A0F89A563D8D40D3461B68", @@ -105,75 +217,63 @@ bool passes_self_tests(Algorithm_Factory& af) "E26BA806A59B0330DE40CA38E77A3E494BE2B212F6DD624B", "E26BA806A59B03307DE2BCC25A08BA40A8BA335F5D604C62", "E26BA806A59B03303C62C2EFF32D3ACDD5D5F35EBCC53371"); - } - - if(const BlockCipher* proto = af.prototype_block_cipher("AES")) - { - cipher_kat(proto, - "2B7E151628AED2A6ABF7158809CF4F3C", - "000102030405060708090A0B0C0D0E0F", - "6BC1BEE22E409F96E93D7E117393172A" - "AE2D8A571E03AC9C9EB76FAC45AF8E51", - "3AD77BB40D7A3660A89ECAF32466EF97" - "F5D3D58503B9699DE785895A96FDBAAF", - "7649ABAC8119B246CEE98E9B12E9197D" - "5086CB9B507219EE95DB113A917678B2", - "3B3FD92EB72DAD20333449F8E83CFB4A" - "C8A64537A0B3A93FCDE3CDAD9F1CE58B", - "3B3FD92EB72DAD20333449F8E83CFB4A" - "7789508D16918F03F53C52DAC54ED825", - "3B3FD92EB72DAD20333449F8E83CFB4A" - "010C041999E03F36448624483E582D0E"); - } - - if(const HashFunction* proto = af.prototype_hash_function("SHA-1")) - { - do_kat("", "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709", - proto->name(), new Hash_Filter(proto->clone())); - - do_kat("616263", "A9993E364706816ABA3E25717850C26C9CD0D89D", - proto->name(), new Hash_Filter(proto->clone())); - - do_kat("6162636462636465636465666465666765666768666768696768696A" + + cipher_kat(af, "AES-128", + "2B7E151628AED2A6ABF7158809CF4F3C", + "000102030405060708090A0B0C0D0E0F", + "6BC1BEE22E409F96E93D7E117393172A" + "AE2D8A571E03AC9C9EB76FAC45AF8E51", + "3AD77BB40D7A3660A89ECAF32466EF97" + "F5D3D58503B9699DE785895A96FDBAAF", + "7649ABAC8119B246CEE98E9B12E9197D" + "5086CB9B507219EE95DB113A917678B2", + "3B3FD92EB72DAD20333449F8E83CFB4A" + "C8A64537A0B3A93FCDE3CDAD9F1CE58B", + "3B3FD92EB72DAD20333449F8E83CFB4A" + "7789508D16918F03F53C52DAC54ED825", + "3B3FD92EB72DAD20333449F8E83CFB4A" + "010C041999E03F36448624483E582D0E"); + + hash_test(af, "SHA-1", + "", "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709"); + + hash_test(af, "SHA-1", + "616263", "A9993E364706816ABA3E25717850C26C9CD0D89D"); + + hash_test(af, "SHA-1", + "6162636462636465636465666465666765666768666768696768696A" "68696A6B696A6B6C6A6B6C6D6B6C6D6E6C6D6E6F6D6E6F706E6F7071", - "84983E441C3BD26EBAAE4AA1F95129E5E54670F1", - proto->name(), new Hash_Filter(proto->clone())); - - do_kat("4869205468657265", - "B617318655057264E28BC0B6FB378C8EF146BE00", - "HMAC(" + proto->name() + ")", - new MAC_Filter(new HMAC(proto->clone()), - SymmetricKey("0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B"))); - } - - if(const HashFunction* proto = af.prototype_hash_function("SHA-256")) - { - do_kat("", - "E3B0C44298FC1C149AFBF4C8996FB924" - "27AE41E4649B934CA495991B7852B855", - proto->name(), new Hash_Filter(proto->clone())); - - do_kat("616263", - "BA7816BF8F01CFEA414140DE5DAE2223" - "B00361A396177A9CB410FF61F20015AD", - proto->name(), new Hash_Filter(proto->clone())); - - do_kat("6162636462636465636465666465666765666768666768696768696A" + "84983E441C3BD26EBAAE4AA1F95129E5E54670F1"); + + mac_test(af, "HMAC(SHA-1)", + "4869205468657265", + "B617318655057264E28BC0B6FB378C8EF146BE00", + "0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B"); + + hash_test(af, "SHA-256", + "", + "E3B0C44298FC1C149AFBF4C8996FB924" + "27AE41E4649B934CA495991B7852B855"); + + hash_test(af, "SHA-256", + "616263", + "BA7816BF8F01CFEA414140DE5DAE2223" + "B00361A396177A9CB410FF61F20015AD"); + + hash_test(af, "SHA-256", + "6162636462636465636465666465666765666768666768696768696A" "68696A6B696A6B6C6A6B6C6D6B6C6D6E6C6D6E6F6D6E6F706E6F7071", "248D6A61D20638B8E5C026930C3E6039" - "A33CE45964FF2167F6ECEDD419DB06C1", - proto->name(), new Hash_Filter(proto->clone())); - - do_kat("4869205468657265", - "198A607EB44BFBC69903A0F1CF2BBDC5" - "BA0AA3F3D9AE3C1C7A3B1696A0B68CF7", - "HMAC(" + proto->name() + ")", - new MAC_Filter(new HMAC(proto->clone()), - SymmetricKey("0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B" - "0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B"))); - } + "A33CE45964FF2167F6ECEDD419DB06C1"); + + mac_test(af, "HMAC(SHA-256)", + "4869205468657265", + "198A607EB44BFBC69903A0F1CF2BBDC5" + "BA0AA3F3D9AE3C1C7A3B1696A0B68CF7", + "0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B" + "0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B"); } - catch(std::exception) + catch(Self_Test_Failure) { return false; } diff --git a/src/selftest/selftest.h b/src/selftest/selftest.h index 9e36d2298..4cb6e23d7 100644 --- a/src/selftest/selftest.h +++ b/src/selftest/selftest.h @@ -9,6 +9,9 @@ #define BOTAN_SELF_TESTS_H__ #include <botan/algo_factory.h> +#include <botan/scan_name.h> +#include <map> +#include <string> namespace Botan { @@ -17,6 +20,11 @@ namespace Botan { */ BOTAN_DLL bool passes_self_tests(Algorithm_Factory& af); +BOTAN_DLL std::map<std::string, bool> +algorithm_kat(const SCAN_Name& algo_name, + const std::map<std::string, std::string>& vars, + Algorithm_Factory& af); + } #endif diff --git a/src/stream/arc4/arc4.cpp b/src/stream/arc4/arc4.cpp index 0f78f7362..293a0a336 100644 --- a/src/stream/arc4/arc4.cpp +++ b/src/stream/arc4/arc4.cpp @@ -87,7 +87,7 @@ std::string ARC4::name() const /* * Clear memory of sensitive data */ -void ARC4::clear() throw() +void ARC4::clear() { state.clear(); buffer.clear(); diff --git a/src/stream/arc4/arc4.h b/src/stream/arc4/arc4.h index aa2cea7fe..ae37cb165 100644 --- a/src/stream/arc4/arc4.h +++ b/src/stream/arc4/arc4.h @@ -19,13 +19,16 @@ namespace Botan { class BOTAN_DLL ARC4 : public StreamCipher { public: - void clear() throw(); + void cipher(const byte in[], byte out[], u32bit length); + + void clear(); std::string name() const; + StreamCipher* clone() const { return new ARC4(SKIP); } + ARC4(u32bit = 0); ~ARC4() { clear(); } private: - void cipher(const byte[], byte[], u32bit); void key_schedule(const byte[], u32bit); void generate(); diff --git a/src/stream/arc4/info.txt b/src/stream/arc4/info.txt index e4689cf69..bb373dbc5 100644 --- a/src/stream/arc4/info.txt +++ b/src/stream/arc4/info.txt @@ -1,5 +1,3 @@ -realname "ARC4" - define ARC4 load_on auto diff --git a/src/stream/ctr/ctr.cpp b/src/stream/ctr/ctr.cpp new file mode 100644 index 000000000..5f0880fa5 --- /dev/null +++ b/src/stream/ctr/ctr.cpp @@ -0,0 +1,141 @@ +/* +* CTR-BE Mode Cipher +* (C) 1999-2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/ctr.h> +#include <botan/xor_buf.h> + +namespace Botan { + +/* +* CTR-BE Constructor +*/ + +CTR_BE::CTR_BE(BlockCipher* ciph) : + StreamCipher(ciph->MINIMUM_KEYLENGTH, + ciph->MAXIMUM_KEYLENGTH, + ciph->KEYLENGTH_MULTIPLE), + permutation(ciph) + { + position = 0; + + counter.create(permutation->BLOCK_SIZE * BOTAN_PARALLEL_BLOCKS_CTR); + buffer.create(permutation->BLOCK_SIZE * BOTAN_PARALLEL_BLOCKS_CTR); + } + +/* +* CTR_BE Destructor +*/ +CTR_BE::~CTR_BE() + { + delete permutation; + } + +/* +* Zeroize +*/ +void CTR_BE::clear() + { + permutation->clear(); + buffer.clear(); + counter.clear(); + position = 0; + } + +/* +* Set the key +*/ +void CTR_BE::key_schedule(const byte key[], u32bit key_len) + { + permutation->set_key(key, key_len); + + // Set a default all-zeros IV + set_iv(0, 0); + } + +/* +* Return the name of this type +*/ +std::string CTR_BE::name() const + { + return ("CTR-BE(" + permutation->name() + ")"); + } + +/* +* CTR-BE Encryption/Decryption +*/ +void CTR_BE::cipher(const byte in[], byte out[], u32bit length) + { + while(length >= buffer.size() - position) + { + xor_buf(out, in, buffer.begin() + position, buffer.size() - position); + length -= (buffer.size() - position); + in += (buffer.size() - position); + out += (buffer.size() - position); + increment_counter(); + } + xor_buf(out, in, buffer.begin() + position, length); + position += length; + } + +/* +* Set CTR-BE IV +*/ +void CTR_BE::set_iv(const byte iv[], u32bit iv_len) + { + if(!valid_iv_length(iv_len)) + throw Invalid_IV_Length(name(), iv_len); + + const u32bit BLOCK_SIZE = permutation->BLOCK_SIZE; + + counter.clear(); + + counter.copy(0, iv, iv_len); + + const u32bit PARALLEL_BLOCKS = counter.size() / BLOCK_SIZE; + + for(u32bit i = 1; i != PARALLEL_BLOCKS; ++i) + { + counter.copy(i*BLOCK_SIZE, + counter.begin() + (i-1)*BLOCK_SIZE, BLOCK_SIZE); + + for(s32bit j = BLOCK_SIZE - 1; j >= 0; --j) + if(++counter[i*BLOCK_SIZE+j]) + break; + } + + permutation->encrypt_n(counter, buffer, PARALLEL_BLOCKS); + position = 0; + } + +/* +* Increment the counter and update the buffer +*/ +void CTR_BE::increment_counter() + { + const u32bit PARALLEL_BLOCKS = counter.size() / permutation->BLOCK_SIZE; + + for(u32bit i = 0; i != PARALLEL_BLOCKS; ++i) + { + byte* this_ctr = counter + i*permutation->BLOCK_SIZE; + + byte last_byte = this_ctr[permutation->BLOCK_SIZE-1]; + last_byte += PARALLEL_BLOCKS; + + if(this_ctr[permutation->BLOCK_SIZE-1] > last_byte) + for(s32bit j = permutation->BLOCK_SIZE - 2; j >= 0; --j) + if(++this_ctr[j]) + break; + + this_ctr[permutation->BLOCK_SIZE-1] = last_byte; + } + + permutation->encrypt_n(counter, buffer, PARALLEL_BLOCKS); + + position = 0; + } + +} diff --git a/src/stream/ctr/ctr.h b/src/stream/ctr/ctr.h new file mode 100644 index 000000000..5f94170cc --- /dev/null +++ b/src/stream/ctr/ctr.h @@ -0,0 +1,49 @@ +/* +* CTR-BE Mode +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_CTR_BE_H__ +#define BOTAN_CTR_BE_H__ + +#include <botan/block_cipher.h> +#include <botan/stream_cipher.h> + +namespace Botan { + +/* +* CTR-BE (Counter, big-endian) +*/ +class BOTAN_DLL CTR_BE : public StreamCipher + { + public: + void cipher(const byte in[], byte out[], u32bit length); + + void set_iv(const byte iv[], u32bit iv_len); + + bool valid_iv_length(u32bit iv_len) const + { return (iv_len <= permutation->BLOCK_SIZE); } + + std::string name() const; + + CTR_BE* clone() const + { return new CTR_BE(permutation->clone()); } + + void clear(); + + CTR_BE(BlockCipher*); + ~CTR_BE(); + private: + void key_schedule(const byte key[], u32bit key_len); + void increment_counter(); + + BlockCipher* permutation; + SecureVector<byte> counter, buffer; + u32bit position; + }; + +} + +#endif diff --git a/src/modes/ctr/info.txt b/src/stream/ctr/info.txt index cb291a2c1..ac4f3f710 100644 --- a/src/modes/ctr/info.txt +++ b/src/stream/ctr/info.txt @@ -1,6 +1,4 @@ -realname "CTR block cipher mode" - -define CTR +define CTR_BE load_on auto @@ -10,6 +8,6 @@ ctr.h </add> <requires> -modes +block +stream </requires> - diff --git a/src/stream/info.txt b/src/stream/info.txt index 295c73708..213c42137 100644 --- a/src/stream/info.txt +++ b/src/stream/info.txt @@ -1,12 +1,9 @@ -realname "Stream Ciphers" - load_on auto define STREAM_CIPHER <add> stream_cipher.h -stream_cipher.cpp </add> <requires> diff --git a/src/modes/ofb/info.txt b/src/stream/ofb/info.txt index 3cba4151e..a01e9e1a6 100644 --- a/src/modes/ofb/info.txt +++ b/src/stream/ofb/info.txt @@ -1,5 +1,3 @@ -realname "OFB block cipher mode" - define OFB load_on auto @@ -11,4 +9,5 @@ ofb.h <requires> block +stream </requires> diff --git a/src/stream/ofb/ofb.cpp b/src/stream/ofb/ofb.cpp new file mode 100644 index 000000000..0d12d23bd --- /dev/null +++ b/src/stream/ofb/ofb.cpp @@ -0,0 +1,97 @@ +/* +* OFB Mode +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/ofb.h> +#include <botan/xor_buf.h> +#include <algorithm> + +namespace Botan { + +/* +* OFB Constructor +*/ +OFB::OFB(BlockCipher* ciph) : + StreamCipher(ciph->MINIMUM_KEYLENGTH, + ciph->MAXIMUM_KEYLENGTH, + ciph->KEYLENGTH_MULTIPLE), + permutation(ciph) + { + position = 0; + buffer.create(permutation->BLOCK_SIZE); + } + +/* +* OFB Destructor +*/ +OFB::~OFB() + { + delete permutation; + } + +/* +* Zeroize +*/ +void OFB::clear() + { + permutation->clear(); + buffer.clear(); + position = 0; + } + +/* +* Set the key +*/ +void OFB::key_schedule(const byte key[], u32bit key_len) + { + permutation->set_key(key, key_len); + + // Set a default all-zeros IV + set_iv(0, 0); + } + +/* +* Return the name of this type +*/ +std::string OFB::name() const + { + return ("OFB(" + permutation->name() + ")"); + } + +/* +* CTR-BE Encryption/Decryption +*/ +void OFB::cipher(const byte in[], byte out[], u32bit length) + { + while(length >= buffer.size() - position) + { + xor_buf(out, in, buffer.begin() + position, buffer.size() - position); + length -= (buffer.size() - position); + in += (buffer.size() - position); + out += (buffer.size() - position); + permutation->encrypt(buffer); + position = 0; + } + xor_buf(out, in, buffer.begin() + position, length); + position += length; + } + +/* +* Set CTR-BE IV +*/ +void OFB::set_iv(const byte iv[], u32bit iv_len) + { + if(!valid_iv_length(iv_len)) + throw Invalid_IV_Length(name(), iv_len); + + buffer.clear(); + buffer.copy(0, iv, iv_len); + + permutation->encrypt(buffer); + position = 0; + } + +} diff --git a/src/stream/ofb/ofb.h b/src/stream/ofb/ofb.h new file mode 100644 index 000000000..1985ae5a9 --- /dev/null +++ b/src/stream/ofb/ofb.h @@ -0,0 +1,48 @@ +/* +* OFB Mode +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_OUTPUT_FEEDBACK_MODE_H__ +#define BOTAN_OUTPUT_FEEDBACK_MODE_H__ + +#include <botan/stream_cipher.h> +#include <botan/block_cipher.h> + +namespace Botan { + +/* +* OFB Mode +*/ +class BOTAN_DLL OFB : public StreamCipher + { + public: + void cipher(const byte in[], byte out[], u32bit length); + + void set_iv(const byte iv[], u32bit iv_len); + + bool valid_iv_length(u32bit iv_len) const + { return (iv_len <= permutation->BLOCK_SIZE); } + + std::string name() const; + + OFB* clone() const + { return new OFB(permutation->clone()); } + + void clear(); + + OFB(BlockCipher*); + ~OFB(); + private: + void key_schedule(const byte key[], u32bit key_len); + + BlockCipher* permutation; + SecureVector<byte> buffer; + u32bit position; + }; + +} + +#endif diff --git a/src/stream/salsa20/info.txt b/src/stream/salsa20/info.txt index db938307b..8171708b0 100644 --- a/src/stream/salsa20/info.txt +++ b/src/stream/salsa20/info.txt @@ -1,5 +1,3 @@ -realname "Salsa20" - define SALSA20 load_on auto diff --git a/src/stream/salsa20/salsa20.cpp b/src/stream/salsa20/salsa20.cpp index 75137798c..3aae64eae 100644 --- a/src/stream/salsa20/salsa20.cpp +++ b/src/stream/salsa20/salsa20.cpp @@ -6,10 +6,8 @@ */ #include <botan/salsa20.h> -#include <botan/mem_ops.h> #include <botan/xor_buf.h> #include <botan/loadstor.h> -#include <botan/parsing.h> namespace Botan { @@ -164,15 +162,15 @@ void Salsa20::key_schedule(const byte key[], u32bit length) } const byte ZERO[8] = { 0 }; - resync(ZERO, sizeof(ZERO)); + set_iv(ZERO, sizeof(ZERO)); } /* * Return the name of this type */ -void Salsa20::resync(const byte iv[], u32bit length) +void Salsa20::set_iv(const byte iv[], u32bit length) { - if(length != IV_LENGTH) + if(!valid_iv_length(length)) throw Invalid_IV_Length(name(), length); state[6] = load_le<u32bit>(iv, 0); @@ -199,7 +197,7 @@ std::string Salsa20::name() const /* * Clear memory of sensitive data */ -void Salsa20::clear() throw() +void Salsa20::clear() { state.clear(); buffer.clear(); @@ -209,7 +207,7 @@ void Salsa20::clear() throw() /* * Salsa20 Constructor */ -Salsa20::Salsa20() : StreamCipher(16, 32, 16, 8) +Salsa20::Salsa20() : StreamCipher(16, 32, 16) { clear(); } diff --git a/src/stream/salsa20/salsa20.h b/src/stream/salsa20/salsa20.h index 3dbfddb50..3ca781ea2 100644 --- a/src/stream/salsa20/salsa20.h +++ b/src/stream/salsa20/salsa20.h @@ -18,17 +18,21 @@ namespace Botan { class BOTAN_DLL Salsa20 : public StreamCipher { public: - void clear() throw(); + void cipher(const byte in[], byte out[], u32bit length); + + void set_iv(const byte iv[], u32bit iv_len); + + bool valid_iv_length(u32bit iv_len) const + { return (iv_len == 8); } + + void clear(); std::string name() const; StreamCipher* clone() const { return new Salsa20; } - void resync(const byte[], u32bit); - Salsa20(); ~Salsa20() { clear(); } private: - void cipher(const byte[], byte[], u32bit); - void key_schedule(const byte[], u32bit); + void key_schedule(const byte key[], u32bit key_len); SecureBuffer<u32bit, 16> state; diff --git a/src/stream/stream_cipher.cpp b/src/stream/stream_cipher.cpp deleted file mode 100644 index 68bb5d4f0..000000000 --- a/src/stream/stream_cipher.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/** -* Stream Cipher Default Implementation for IV and Seek -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/stream_cipher.h> - -namespace Botan { - -/* -* Default StreamCipher Resync Operation -*/ -void StreamCipher::resync(const byte[], u32bit length) - { - if(length) - throw Exception("The stream cipher " + name() + - " does not support resyncronization"); - } - -/* -* Default StreamCipher Seek Operation -*/ -void StreamCipher::seek(u32bit) - { - throw Exception("The stream cipher " + name() + " does not support seek()"); - } - -} diff --git a/src/stream/stream_cipher.h b/src/stream/stream_cipher.h index 8ea359131..29c16c8b5 100644 --- a/src/stream/stream_cipher.h +++ b/src/stream/stream_cipher.h @@ -18,53 +18,40 @@ namespace Botan { class BOTAN_DLL StreamCipher : public SymmetricAlgorithm { public: - const u32bit IV_LENGTH; - - /** - * Encrypt a message. - * @param i the plaintext - * @param o the byte array to hold the output, i.e. the ciphertext - * @param len the length of both i and o - */ - void encrypt(const byte i[], byte o[], u32bit len) { cipher(i, o, len); } - /** - * Decrypt a message. - * @param i the ciphertext to decrypt - * @param o the byte array to hold the output, i.e. the plaintext - * @param len the length of both i and o + * Encrypt or decrypt a message + * @param in the plaintext + * @param out the byte array to hold the output, i.e. the ciphertext + * @param len the length of both in and out in bytes */ - void decrypt(const byte i[], byte o[], u32bit len) { cipher(i, o, len); } + virtual void cipher(const byte in[], byte out[], u32bit len) = 0; /** - * Encrypt a message. - * @param in the plaintext as input, after the function has - * returned it will hold the ciphertext - - * @param len the length of in + * Encrypt or decrypt a message + * @param buf the plaintext / ciphertext + * @param len the length of buf in bytes */ - void encrypt(byte in[], u32bit len) { cipher(in, in, len); } - - /** - * Decrypt a message. - * @param in the ciphertext as input, after the function has - * returned it will hold the plaintext - * @param len the length of in - */ - void decrypt(byte in[], u32bit len) { cipher(in, in, len); } + void cipher1(byte buf[], u32bit len) + { cipher(buf, buf, len); } /** * Resync the cipher using the IV * @param iv the initialization vector * @param iv_len the length of the IV in bytes */ - virtual void resync(const byte iv[], u32bit iv_len); + virtual void set_iv(const byte[], u32bit iv_len) + { + if(iv_len) + throw Exception("The stream cipher " + name() + + " does not support resyncronization"); + } /** - * Seek ahead in the stream. - * @param len the length to seek ahead. + * @param iv_len the length of the IV in bytes + * @return if the length is valid for this algorithm */ - virtual void seek(u32bit len); + virtual bool valid_iv_length(u32bit iv_len) const + { return (iv_len == 0); } /** * Get a new object representing the same algorithm as *this @@ -74,17 +61,17 @@ class BOTAN_DLL StreamCipher : public SymmetricAlgorithm /** * Zeroize internal state */ - virtual void clear() throw() = 0; + virtual void clear() = 0; - StreamCipher(u32bit key_min, u32bit key_max = 0, - u32bit key_mod = 1, - u32bit iv_len = 0) : - SymmetricAlgorithm(key_min, key_max, key_mod), - IV_LENGTH(iv_len) {} + /** + * StreamCipher constructor + */ + StreamCipher(u32bit key_min, + u32bit key_max = 0, + u32bit key_mod = 1) : + SymmetricAlgorithm(key_min, key_max, key_mod) {} virtual ~StreamCipher() {} - private: - virtual void cipher(const byte[], byte[], u32bit) = 0; }; } diff --git a/src/stream/turing/info.txt b/src/stream/turing/info.txt index c251a0a30..dede0dd39 100644 --- a/src/stream/turing/info.txt +++ b/src/stream/turing/info.txt @@ -1,5 +1,3 @@ -realname "Turing" - define TURING load_on auto diff --git a/src/stream/turing/turing.cpp b/src/stream/turing/turing.cpp index b988568c3..810f65ca4 100644 --- a/src/stream/turing/turing.cpp +++ b/src/stream/turing/turing.cpp @@ -218,25 +218,6 @@ u32bit Turing::fixedS(u32bit W) } /* -* Generate the expanded Turing Sbox tables -*/ -void Turing::gen_sbox(MemoryRegion<u32bit>& S, u32bit which, - const MemoryRegion<u32bit>& K) - { - for(u32bit j = 0; j != 256; ++j) - { - u32bit W = 0, C = j; - - for(u32bit k = 0; k < K.size(); ++k) - { - C = SBOX[get_byte(which, K[k]) ^ C]; - W ^= rotate_left(Q_BOX[C], k + 8*which); - } - S[j] = (W & rotate_right(0x00FFFFFF, 8*which)) | (C << (24 - 8*which)); - } - } - -/* * Turing Key Schedule */ void Turing::key_schedule(const byte key[], u32bit length) @@ -250,20 +231,41 @@ void Turing::key_schedule(const byte key[], u32bit length) PHT(K); - gen_sbox(S0, 0, K); - gen_sbox(S1, 1, K); - gen_sbox(S2, 2, K); - gen_sbox(S3, 3, K); + for(u32bit i = 0; i != 256; ++i) + { + u32bit W0 = 0, C0 = i; + u32bit W1 = 0, C1 = i; + u32bit W2 = 0, C2 = i; + u32bit W3 = 0, C3 = i; + + for(u32bit j = 0; j < K.size(); ++j) + { + C0 = SBOX[get_byte(0, K[j]) ^ C0]; + C1 = SBOX[get_byte(1, K[j]) ^ C1]; + C2 = SBOX[get_byte(2, K[j]) ^ C2]; + C3 = SBOX[get_byte(3, K[j]) ^ C3]; + + W0 ^= rotate_left(Q_BOX[C0], j); + W1 ^= rotate_left(Q_BOX[C1], j + 8); + W2 ^= rotate_left(Q_BOX[C2], j + 16); + W3 ^= rotate_left(Q_BOX[C3], j + 24); + } + + S0[i] = (W0 & 0x00FFFFFF) | (C0 << 24); + S1[i] = (W1 & 0xFF00FFFF) | (C1 << 16); + S2[i] = (W2 & 0xFFFF00FF) | (C2 << 8); + S3[i] = (W3 & 0xFFFFFF00) | C3; + } - resync(0, 0); + set_iv(0, 0); } /* * Resynchronization */ -void Turing::resync(const byte iv[], u32bit length) +void Turing::set_iv(const byte iv[], u32bit length) { - if(length % 4 != 0 || length > 16) + if(!valid_iv_length(length)) throw Invalid_IV_Length(name(), length); SecureVector<u32bit> IV(length / 4); @@ -293,7 +295,7 @@ void Turing::resync(const byte iv[], u32bit length) /* * Clear memory of sensitive data */ -void Turing::clear() throw() +void Turing::clear() { S0.clear(); S1.clear(); diff --git a/src/stream/turing/turing.h b/src/stream/turing/turing.h index d48c1d8a8..7291647ea 100644 --- a/src/stream/turing/turing.h +++ b/src/stream/turing/turing.h @@ -18,19 +18,21 @@ namespace Botan { class BOTAN_DLL Turing : public StreamCipher { public: - void clear() throw(); + void cipher(const byte in[], byte out[], u32bit length); + void set_iv(const byte[], u32bit); + + bool valid_iv_length(u32bit iv_len) const + { return (iv_len % 4 == 0 && iv_len <= 16); } + + void clear(); std::string name() const { return "Turing"; } StreamCipher* clone() const { return new Turing; } Turing() : StreamCipher(4, 32, 4) { position = 0; } private: - void cipher(const byte[], byte[], u32bit); void key_schedule(const byte[], u32bit); - void resync(const byte[], u32bit); void generate(); static u32bit fixedS(u32bit); - static void gen_sbox(MemoryRegion<u32bit>&, u32bit, - const MemoryRegion<u32bit>&); static const u32bit Q_BOX[256]; static const byte SBOX[256]; diff --git a/src/stream/wid_wake/info.txt b/src/stream/wid_wake/info.txt index 94416417e..6289e0369 100644 --- a/src/stream/wid_wake/info.txt +++ b/src/stream/wid_wake/info.txt @@ -1,5 +1,3 @@ -realname "WiderWake" - define WID_WAKE load_on auto diff --git a/src/stream/wid_wake/wid_wake.cpp b/src/stream/wid_wake/wid_wake.cpp index 1dc0fd7f9..2a8946649 100644 --- a/src/stream/wid_wake/wid_wake.cpp +++ b/src/stream/wid_wake/wid_wake.cpp @@ -110,16 +110,17 @@ void WiderWake_41_BE::key_schedule(const byte key[], u32bit) T[X] = Z; position = 0; - const byte iv[8] = { 0 }; - resync(iv, 8); + + const byte ZEROS[8] = { 0 }; + set_iv(ZEROS, sizeof(ZEROS)); } /* * Resynchronization */ -void WiderWake_41_BE::resync(const byte iv[], u32bit length) +void WiderWake_41_BE::set_iv(const byte iv[], u32bit length) { - if(length != 8) + if(!valid_iv_length(length)) throw Invalid_IV_Length(name(), length); for(u32bit j = 0; j != 4; ++j) @@ -135,7 +136,7 @@ void WiderWake_41_BE::resync(const byte iv[], u32bit length) /* * Clear memory of sensitive data */ -void WiderWake_41_BE::clear() throw() +void WiderWake_41_BE::clear() { position = 0; t_key.clear(); diff --git a/src/stream/wid_wake/wid_wake.h b/src/stream/wid_wake/wid_wake.h index 4720afdb2..23e1eacab 100644 --- a/src/stream/wid_wake/wid_wake.h +++ b/src/stream/wid_wake/wid_wake.h @@ -18,14 +18,18 @@ namespace Botan { class BOTAN_DLL WiderWake_41_BE : public StreamCipher { public: - void clear() throw(); + void cipher(const byte[], byte[], u32bit); + void set_iv(const byte[], u32bit); + + bool valid_iv_length(u32bit iv_len) const + { return (iv_len == 8); } + + void clear(); std::string name() const { return "WiderWake4+1-BE"; } StreamCipher* clone() const { return new WiderWake_41_BE; } - WiderWake_41_BE() : StreamCipher(16, 16, 1, 8) {} + WiderWake_41_BE() : StreamCipher(16, 16, 1) {} private: - void cipher(const byte[], byte[], u32bit); void key_schedule(const byte[], u32bit); - void resync(const byte[], u32bit); void generate(u32bit); diff --git a/src/sym_algo/info.txt b/src/sym_algo/info.txt index 03804a92d..fab46270e 100644 --- a/src/sym_algo/info.txt +++ b/src/sym_algo/info.txt @@ -1,5 +1,3 @@ -realname "Symmetric Algorithms" - load_on auto <add> diff --git a/src/sym_algo/sym_algo.h b/src/sym_algo/sym_algo.h index 1c8b816fd..929f2a6f0 100644 --- a/src/sym_algo/sym_algo.h +++ b/src/sym_algo/sym_algo.h @@ -46,7 +46,7 @@ class BOTAN_DLL SymmetricAlgorithm * Set the symmetric key of this object. * @param key the SymmetricKey to be set. */ - void set_key(const SymmetricKey& key) throw(Invalid_Key_Length) + void set_key(const SymmetricKey& key) { set_key(key.begin(), key.length()); } /** @@ -54,7 +54,7 @@ class BOTAN_DLL SymmetricAlgorithm * @param key the to be set as a byte array. * @param the length of the byte array. */ - void set_key(const byte key[], u32bit length) throw(Invalid_Key_Length) + void set_key(const byte key[], u32bit length) { if(!valid_keylength(length)) throw Invalid_Key_Length(name(), length); diff --git a/src/timer/cpu_counter/info.txt b/src/timer/cpu_counter/info.txt index 025663a84..d95e0fec5 100644 --- a/src/timer/cpu_counter/info.txt +++ b/src/timer/cpu_counter/info.txt @@ -1,5 +1,3 @@ -realname "Hardware Timer" - define TIMER_HARDWARE load_on asm_ok diff --git a/src/timer/gettimeofday/info.txt b/src/timer/gettimeofday/info.txt index a58e8088d..f8b65b4ba 100644 --- a/src/timer/gettimeofday/info.txt +++ b/src/timer/gettimeofday/info.txt @@ -1,5 +1,3 @@ -realname "Unix Timer" - define TIMER_UNIX load_on auto @@ -30,4 +28,3 @@ tru64 <requires> timer </requires> - diff --git a/src/timer/gettimeofday/tm_unix.cpp b/src/timer/gettimeofday/tm_unix.cpp index e32df7166..9d8ac4a04 100644 --- a/src/timer/gettimeofday/tm_unix.cpp +++ b/src/timer/gettimeofday/tm_unix.cpp @@ -6,7 +6,6 @@ */ #include <botan/tm_unix.h> -#include <botan/util.h> #include <sys/time.h> namespace Botan { diff --git a/src/timer/info.txt b/src/timer/info.txt index 6408dca45..1dff5ab6f 100644 --- a/src/timer/info.txt +++ b/src/timer/info.txt @@ -1,5 +1,3 @@ -realname "Timer Base Class" - define TIMER load_on auto diff --git a/src/timer/posix_rt/info.txt b/src/timer/posix_rt/info.txt index fa530ea1a..4b23a74fc 100644 --- a/src/timer/posix_rt/info.txt +++ b/src/timer/posix_rt/info.txt @@ -1,5 +1,3 @@ -realname "POSIX Timer" - define TIMER_POSIX load_on auto @@ -26,4 +24,3 @@ dragonfly <requires> timer </requires> - diff --git a/src/timer/posix_rt/tm_posix.cpp b/src/timer/posix_rt/tm_posix.cpp index d356384ab..96182025c 100644 --- a/src/timer/posix_rt/tm_posix.cpp +++ b/src/timer/posix_rt/tm_posix.cpp @@ -6,7 +6,6 @@ */ #include <botan/tm_posix.h> -#include <botan/util.h> #ifndef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 199309 diff --git a/src/timer/timer.cpp b/src/timer/timer.cpp index 035c217f9..16d7dc368 100644 --- a/src/timer/timer.cpp +++ b/src/timer/timer.cpp @@ -7,7 +7,6 @@ #include <botan/timer.h> #include <botan/loadstor.h> -#include <botan/util.h> #include <ctime> namespace Botan { @@ -20,6 +19,19 @@ u64bit system_time() return static_cast<u64bit>(std::time(0)); } +/* +* Convert a time_t to a struct tm +*/ +std::tm time_t_to_tm(u64bit timer) + { + std::time_t time_val = static_cast<std::time_t>(timer); + + std::tm* tm_p = std::gmtime(&time_val); + if (tm_p == 0) + throw Encoding_Error("time_t_to_tm could not convert"); + return (*tm_p); + } + /** * Read the clock and return the output */ diff --git a/src/timer/timer.h b/src/timer/timer.h index b6e8ef448..603027f6d 100644 --- a/src/timer/timer.h +++ b/src/timer/timer.h @@ -9,9 +9,17 @@ #define BOTAN_TIMERS_H__ #include <botan/rng.h> +#include <ctime> namespace Botan { +/* +* Time Access/Conversion Functions +*/ +BOTAN_DLL u64bit system_time(); + +BOTAN_DLL std::tm time_t_to_tm(u64bit); + /** * Timer Interface */ diff --git a/src/timer/win32_query_perf_ctr/info.txt b/src/timer/win32_query_perf_ctr/info.txt index 4bb1ddb34..d8611027a 100644 --- a/src/timer/win32_query_perf_ctr/info.txt +++ b/src/timer/win32_query_perf_ctr/info.txt @@ -1,5 +1,3 @@ -realname "Win32 Timer" - define TIMER_WIN32 modset win32 @@ -23,4 +21,3 @@ windows -> user32.lib <requires> timer </requires> - diff --git a/src/tss/info.txt b/src/tss/info.txt new file mode 100644 index 000000000..11cc471d2 --- /dev/null +++ b/src/tss/info.txt @@ -0,0 +1,6 @@ +<requires> +hash +rng +filters +hex +</requires> diff --git a/src/tss/tss.cpp b/src/tss/tss.cpp new file mode 100644 index 000000000..3bd799727 --- /dev/null +++ b/src/tss/tss.cpp @@ -0,0 +1,263 @@ +/* +* RTSS (threshold secret sharing) +* (C) 2009 Jack Lloyd <[email protected]> +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/tss.h> +#include <botan/loadstor.h> +#include <botan/pipe.h> +#include <botan/hex.h> +#include <botan/sha2_32.h> +#include <botan/sha160.h> +#include <memory> + +namespace Botan { + +namespace { + +/** +Table for GF(2^8) arithmetic (exponentials) +*/ +const byte EXP[256] = { +0x01, 0x03, 0x05, 0x0F, 0x11, 0x33, 0x55, 0xFF, 0x1A, 0x2E, 0x72, +0x96, 0xA1, 0xF8, 0x13, 0x35, 0x5F, 0xE1, 0x38, 0x48, 0xD8, 0x73, +0x95, 0xA4, 0xF7, 0x02, 0x06, 0x0A, 0x1E, 0x22, 0x66, 0xAA, 0xE5, +0x34, 0x5C, 0xE4, 0x37, 0x59, 0xEB, 0x26, 0x6A, 0xBE, 0xD9, 0x70, +0x90, 0xAB, 0xE6, 0x31, 0x53, 0xF5, 0x04, 0x0C, 0x14, 0x3C, 0x44, +0xCC, 0x4F, 0xD1, 0x68, 0xB8, 0xD3, 0x6E, 0xB2, 0xCD, 0x4C, 0xD4, +0x67, 0xA9, 0xE0, 0x3B, 0x4D, 0xD7, 0x62, 0xA6, 0xF1, 0x08, 0x18, +0x28, 0x78, 0x88, 0x83, 0x9E, 0xB9, 0xD0, 0x6B, 0xBD, 0xDC, 0x7F, +0x81, 0x98, 0xB3, 0xCE, 0x49, 0xDB, 0x76, 0x9A, 0xB5, 0xC4, 0x57, +0xF9, 0x10, 0x30, 0x50, 0xF0, 0x0B, 0x1D, 0x27, 0x69, 0xBB, 0xD6, +0x61, 0xA3, 0xFE, 0x19, 0x2B, 0x7D, 0x87, 0x92, 0xAD, 0xEC, 0x2F, +0x71, 0x93, 0xAE, 0xE9, 0x20, 0x60, 0xA0, 0xFB, 0x16, 0x3A, 0x4E, +0xD2, 0x6D, 0xB7, 0xC2, 0x5D, 0xE7, 0x32, 0x56, 0xFA, 0x15, 0x3F, +0x41, 0xC3, 0x5E, 0xE2, 0x3D, 0x47, 0xC9, 0x40, 0xC0, 0x5B, 0xED, +0x2C, 0x74, 0x9C, 0xBF, 0xDA, 0x75, 0x9F, 0xBA, 0xD5, 0x64, 0xAC, +0xEF, 0x2A, 0x7E, 0x82, 0x9D, 0xBC, 0xDF, 0x7A, 0x8E, 0x89, 0x80, +0x9B, 0xB6, 0xC1, 0x58, 0xE8, 0x23, 0x65, 0xAF, 0xEA, 0x25, 0x6F, +0xB1, 0xC8, 0x43, 0xC5, 0x54, 0xFC, 0x1F, 0x21, 0x63, 0xA5, 0xF4, +0x07, 0x09, 0x1B, 0x2D, 0x77, 0x99, 0xB0, 0xCB, 0x46, 0xCA, 0x45, +0xCF, 0x4A, 0xDE, 0x79, 0x8B, 0x86, 0x91, 0xA8, 0xE3, 0x3E, 0x42, +0xC6, 0x51, 0xF3, 0x0E, 0x12, 0x36, 0x5A, 0xEE, 0x29, 0x7B, 0x8D, +0x8C, 0x8F, 0x8A, 0x85, 0x94, 0xA7, 0xF2, 0x0D, 0x17, 0x39, 0x4B, +0xDD, 0x7C, 0x84, 0x97, 0xA2, 0xFD, 0x1C, 0x24, 0x6C, 0xB4, 0xC7, +0x52, 0xF6, 0x01 }; + +/** +Table for GF(2^8) arithmetic (logarithms) +*/ +const byte LOG[] = { +0x90, 0x00, 0x19, 0x01, 0x32, 0x02, 0x1A, 0xC6, 0x4B, 0xC7, 0x1B, +0x68, 0x33, 0xEE, 0xDF, 0x03, 0x64, 0x04, 0xE0, 0x0E, 0x34, 0x8D, +0x81, 0xEF, 0x4C, 0x71, 0x08, 0xC8, 0xF8, 0x69, 0x1C, 0xC1, 0x7D, +0xC2, 0x1D, 0xB5, 0xF9, 0xB9, 0x27, 0x6A, 0x4D, 0xE4, 0xA6, 0x72, +0x9A, 0xC9, 0x09, 0x78, 0x65, 0x2F, 0x8A, 0x05, 0x21, 0x0F, 0xE1, +0x24, 0x12, 0xF0, 0x82, 0x45, 0x35, 0x93, 0xDA, 0x8E, 0x96, 0x8F, +0xDB, 0xBD, 0x36, 0xD0, 0xCE, 0x94, 0x13, 0x5C, 0xD2, 0xF1, 0x40, +0x46, 0x83, 0x38, 0x66, 0xDD, 0xFD, 0x30, 0xBF, 0x06, 0x8B, 0x62, +0xB3, 0x25, 0xE2, 0x98, 0x22, 0x88, 0x91, 0x10, 0x7E, 0x6E, 0x48, +0xC3, 0xA3, 0xB6, 0x1E, 0x42, 0x3A, 0x6B, 0x28, 0x54, 0xFA, 0x85, +0x3D, 0xBA, 0x2B, 0x79, 0x0A, 0x15, 0x9B, 0x9F, 0x5E, 0xCA, 0x4E, +0xD4, 0xAC, 0xE5, 0xF3, 0x73, 0xA7, 0x57, 0xAF, 0x58, 0xA8, 0x50, +0xF4, 0xEA, 0xD6, 0x74, 0x4F, 0xAE, 0xE9, 0xD5, 0xE7, 0xE6, 0xAD, +0xE8, 0x2C, 0xD7, 0x75, 0x7A, 0xEB, 0x16, 0x0B, 0xF5, 0x59, 0xCB, +0x5F, 0xB0, 0x9C, 0xA9, 0x51, 0xA0, 0x7F, 0x0C, 0xF6, 0x6F, 0x17, +0xC4, 0x49, 0xEC, 0xD8, 0x43, 0x1F, 0x2D, 0xA4, 0x76, 0x7B, 0xB7, +0xCC, 0xBB, 0x3E, 0x5A, 0xFB, 0x60, 0xB1, 0x86, 0x3B, 0x52, 0xA1, +0x6C, 0xAA, 0x55, 0x29, 0x9D, 0x97, 0xB2, 0x87, 0x90, 0x61, 0xBE, +0xDC, 0xFC, 0xBC, 0x95, 0xCF, 0xCD, 0x37, 0x3F, 0x5B, 0xD1, 0x53, +0x39, 0x84, 0x3C, 0x41, 0xA2, 0x6D, 0x47, 0x14, 0x2A, 0x9E, 0x5D, +0x56, 0xF2, 0xD3, 0xAB, 0x44, 0x11, 0x92, 0xD9, 0x23, 0x20, 0x2E, +0x89, 0xB4, 0x7C, 0xB8, 0x26, 0x77, 0x99, 0xE3, 0xA5, 0x67, 0x4A, +0xED, 0xDE, 0xC5, 0x31, 0xFE, 0x18, 0x0D, 0x63, 0x8C, 0x80, 0xC0, +0xF7, 0x70, 0x07 }; + +byte gfp_mul(byte x, byte y) + { + if(x == 0 || y == 0) + return 0; + return EXP[(LOG[x] + LOG[y]) % 255]; + } + +byte rtss_hash_id(const std::string& hash_name) + { + if(hash_name == "SHA-160") + return 1; + else if(hash_name == "SHA-256") + return 2; + else + throw Invalid_Argument("RTSS only supports SHA-1 and SHA-256"); + } + +HashFunction* get_rtss_hash_by_id(byte id) + { + if(id == 1) + return new SHA_160; + else if(id == 2) + return new SHA_256; + else + throw Decoding_Error("Bad RTSS hash identifier"); + } + +} + +RTSS_Share::RTSS_Share(const std::string& hex_input) + { + Pipe pipe(new Hex_Decoder); + pipe.process_msg(hex_input); + contents = pipe.read_all(); + } + +byte RTSS_Share::share_id() const + { + if(!initialized()) + throw Invalid_State("RTSS_Share::share_id not initialized"); + + return contents[20]; + } + +std::string RTSS_Share::to_string() const + { + Pipe pipe(new Hex_Encoder); + pipe.process_msg(contents); + return pipe.read_all_as_string(); + } + +std::vector<RTSS_Share> +RTSS_Share::split(byte M, byte N, + const byte S[], u16bit S_len, + const byte identifier[16], + RandomNumberGenerator& rng) + { + if(M == 0 || N == 0 || M > N) + throw Encoding_Error("RTSS_Share::split: M == 0 or N == 0 or M > N"); + + SHA_256 hash; // always use SHA-256 when generating shares + + std::vector<RTSS_Share> shares(N); + + // Create RTSS header in each share + for(byte i = 0; i != N; ++i) + { + shares[i].contents.append(identifier, 16); + shares[i].contents.append(rtss_hash_id(hash.name())); + shares[i].contents.append(M); + shares[i].contents.append(get_byte(0, S_len)); + shares[i].contents.append(get_byte(1, S_len)); + } + + // Choose sequential values for X starting from 1 + for(byte i = 0; i != N; ++i) + shares[i].contents.append(i+1); + + // secret = S || H(S) + SecureVector<byte> secret(S, S_len); + secret.append(hash.process(S, S_len)); + + for(size_t i = 0; i != secret.size(); ++i) + { + std::vector<byte> coefficients(M-1); + rng.randomize(&coefficients[0], coefficients.size()); + + for(byte j = 0; j != N; ++j) + { + const byte X = j + 1; + + byte sum = secret[i]; + byte X_i = X; + + for(size_t k = 0; k != coefficients.size(); ++k) + { + sum ^= gfp_mul(X_i, coefficients[k]); + X_i = gfp_mul(X_i, X); + } + + shares[j].contents.append(sum); + } + } + + return shares; + } + +SecureVector<byte> +RTSS_Share::reconstruct(const std::vector<RTSS_Share>& shares) + { + const u32bit RTSS_HEADER_SIZE = 20; + + for(size_t i = 0; i != shares.size(); ++i) + { + if(shares[i].size() != shares[0].size()) + throw Decoding_Error("Different sized RTSS shares detected"); + if(shares[i].share_id() == 0) + throw Decoding_Error("Invalid (id = 0) RTSS share detected"); + if(shares[i].size() < RTSS_HEADER_SIZE) + throw Decoding_Error("Missing or malformed RTSS header"); + + if(!same_mem(shares[0].contents.begin(), + shares[i].contents.begin(), RTSS_HEADER_SIZE)) + throw Decoding_Error("Different RTSS headers detected"); + } + + if(shares.size() < shares[0].contents[17]) + throw Decoding_Error("Insufficient shares to do TSS reconstruction"); + + u16bit secret_len = make_u16bit(shares[0].contents[18], + shares[0].contents[19]); + + byte hash_id = shares[0].contents[16]; + + std::auto_ptr<HashFunction> hash(get_rtss_hash_by_id(hash_id)); + + if(shares[0].size() != secret_len + hash->OUTPUT_LENGTH + RTSS_HEADER_SIZE + 1) + throw Decoding_Error("Bad RTSS length field in header"); + + std::vector<byte> V(shares.size()); + SecureVector<byte> secret; + + for(size_t i = RTSS_HEADER_SIZE + 1; i != shares[0].size(); ++i) + { + for(size_t j = 0; j != V.size(); ++j) + V[j] = shares[j].contents[i]; + + byte r = 0; + for(size_t k = 0; k != shares.size(); ++k) + { + // L_i function: + byte r2 = 1; + for(size_t l = 0; l != shares.size(); ++l) + { + if(k == l) + continue; + + byte share_k = shares[k].share_id(); + byte share_l = shares[l].share_id(); + + if(share_k == share_l) + throw Decoding_Error("Duplicate shares found in RTSS recovery"); + + byte div = EXP[(255 + LOG[share_l] - LOG[share_k ^ share_l]) % 255]; + + r2 = gfp_mul(r2, div); + } + + r ^= gfp_mul(V[k], r2); + } + secret.append(r); + } + + if(secret.size() != secret_len + hash->OUTPUT_LENGTH) + throw Decoding_Error("Bad length in RTSS output"); + + hash->update(secret, secret_len); + SecureVector<byte> hash_check = hash->final(); + + if(!same_mem(hash_check.begin(), secret + secret_len, hash->OUTPUT_LENGTH)) + throw Decoding_Error("RTSS hash check failed"); + + return SecureVector<byte>(secret, secret_len); + } + +} diff --git a/src/tss/tss.h b/src/tss/tss.h new file mode 100644 index 000000000..0b26bfdcb --- /dev/null +++ b/src/tss/tss.h @@ -0,0 +1,55 @@ +/* +* RTSS (threshold secret sharing) +* (C) 2009 Jack Lloyd <[email protected]> +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_RTSS_H__ +#define BOTAN_RTSS_H__ + +#include <botan/secmem.h> +#include <botan/hash.h> +#include <botan/rng.h> +#include <vector> + +namespace Botan { + +class RTSS_Share + { + public: + /** + * @arg M the number of shares needed to reconstruct + * @arg N the number of shares generated + * @arg secret the secret to split + * @arg secret_len the length of the secret + * @arg identifier the 16 byte share identifier + * @arg rng the random number generator to use + */ + static std::vector<RTSS_Share> + split(byte M, byte N, + const byte secret[], u16bit secret_len, + const byte identifier[16], + RandomNumberGenerator& rng); + + /** + * @arg shares the list of shares + */ + static SecureVector<byte> + reconstruct(const std::vector<RTSS_Share>& shares); + + RTSS_Share() {} + RTSS_Share(const std::string&); + + std::string to_string() const; + byte share_id() const; + + u32bit size() const { return contents.size(); } + bool initialized() const { return contents.size(); } + private: + SecureVector<byte> contents; + }; + +} + +#endif diff --git a/src/utils/asm_amd64/info.txt b/src/utils/asm_amd64/info.txt index 19035b545..a5588669c 100644 --- a/src/utils/asm_amd64/info.txt +++ b/src/utils/asm_amd64/info.txt @@ -1,5 +1,3 @@ -realname "Assembler Macros (x86-64)" - load_on dep <add> @@ -14,3 +12,7 @@ amd64 gcc icc </cc> + +<requires> +amd64_eng +</requires> diff --git a/src/utils/asm_ia32/info.txt b/src/utils/asm_ia32/info.txt index 4340c35aa..63b57e0f8 100644 --- a/src/utils/asm_ia32/info.txt +++ b/src/utils/asm_ia32/info.txt @@ -1,5 +1,3 @@ -realname "Assembler Macros (IA-32)" - load_on dep <add> @@ -14,3 +12,7 @@ ia32 gcc icc </cc> + +<requires> +ia32_eng +</requires> diff --git a/src/utils/buf_comp/info.txt b/src/utils/buf_comp/info.txt index bcbbc23e2..7aea580ce 100644 --- a/src/utils/buf_comp/info.txt +++ b/src/utils/buf_comp/info.txt @@ -1,5 +1,3 @@ -realname "Buffered Computation" - load_on auto <add> diff --git a/src/utils/cpuid.cpp b/src/utils/cpuid.cpp new file mode 100644 index 000000000..2ba7f9b77 --- /dev/null +++ b/src/utils/cpuid.cpp @@ -0,0 +1,168 @@ +/** +* Runtime CPU detection +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/cpuid.h> +#include <botan/types.h> +#include <botan/loadstor.h> +#include <botan/mem_ops.h> + +#if defined(BOTAN_TARGET_ARCH_IS_IA32) || defined(BOTAN_TARGET_ARCH_IS_AMD64) + +#if defined(BOTAN_BUILD_COMPILER_IS_MSVC) + + #include <intrin.h> + #define CALL_CPUID(type, out) do { __cpuid((int*)out, type); } while(0) + +#elif defined(BOTAN_BUILD_COMPILER_IS_INTEL) + + #include <ia32intrin.h> + #define CALL_CPUID(type, out) do { __cpuid(out, type); } while(0); + +#elif defined(BOTAN_BUILD_COMPILER_IS_GCC) + + #include <cpuid.h> + #define CALL_CPUID(type, out) \ + do { __get_cpuid(type, out, out+1, out+2, out+3); } while(0); + +#endif + +#endif + +#ifndef CALL_CPUID + // In all other cases, just zeroize the supposed cpuid output + #define CALL_CPUID(type, out) \ + do { out[0] = out[1] = out[2] = out[3] = 0; } while(0); +#endif + +namespace Botan { + +namespace { + +u32bit get_x86_cache_line_size() + { + const u32bit INTEL_CPUID[3] = { 0x756E6547, 0x6C65746E, 0x49656E69 }; + const u32bit AMD_CPUID[3] = { 0x68747541, 0x444D4163, 0x69746E65 }; + + u32bit cpuid[4] = { 0 }; + CALL_CPUID(0, cpuid); + + if(same_mem(cpuid + 1, INTEL_CPUID, 3)) + { + CALL_CPUID(1, cpuid); + return 8 * get_byte(2, cpuid[1]); + } + else if(same_mem(cpuid + 1, AMD_CPUID, 3)) + { + CALL_CPUID(0x80000005, cpuid); + return get_byte(3, cpuid[2]); + } + else + return 32; // default cache line guess + } + +} + +/* +* Call the x86 CPUID instruction and return the contents of ecx and +* edx, which contain the feature masks. +*/ +u64bit CPUID::x86_processor_flags() + { + static u64bit proc_flags = 0; + + if(proc_flags) + return proc_flags; + + u32bit cpuid[4] = { 0 }; + CALL_CPUID(1, cpuid); + + // Set the FPU bit on to force caching in proc_flags + proc_flags = ((u64bit)cpuid[2] << 32) | cpuid[3] | 1; + + return proc_flags; + } + +u32bit CPUID::cache_line_size() + { + static u32bit cl_size = 0; + + if(cl_size) + return cl_size; + + cl_size = get_x86_cache_line_size(); + + return cl_size; + } + +bool CPUID::has_altivec() + { + static bool first_time = true; + static bool altivec_capable = false; + + if(first_time) + { +#if defined(BOTAN_TARGET_ARCH_IS_PPC) || defined(BOTAN_TARGET_ARCH_IS_PPC64) + + /* + PVR identifiers for various AltiVec enabled CPUs. Taken from + PearPC and Linux sources, mostly. + */ + const u16bit PVR_G4_7400 = 0x000C; + const u16bit PVR_G5_970 = 0x0039; + const u16bit PVR_G5_970FX = 0x003C; + const u16bit PVR_G5_970MP = 0x0044; + const u16bit PVR_G5_970GX = 0x0045; + const u16bit PVR_POWER6 = 0x003E; + const u16bit PVR_CELL_PPU = 0x0070; + + // Motorola produced G4s with PVR 0x800[0123C] (at least) + const u16bit PVR_G4_74xx_24 = 0x800; + + /* + On PowerPC, MSR 287 is PVR, the Processor Version Number + + Normally it is only accessible to ring 0, but Linux and NetBSD + (at least) will trap and emulate it for us. This is roughly 20x + saner than every other approach I've seen for AltiVec detection + (all of which are entirely OS specific, to boot). + + Apparently OS X doesn't support this, but then again OS X + doesn't really support PPC anymore, so I'm not worrying about it. + + For OSes that aren't (known to) support the emulation, skip the + call, leaving pvr as 0 which will cause all subsequent model + number checks to fail (and we'll assume no AltiVec) + */ + +#if defined(BOTAN_TARGET_OS_IS_LINUX) || defined(BOTAN_TARGET_OS_IS_NETBSD) + #define BOTAN_TARGET_OS_SUPPORTS_MFSPR_EMUL +#endif + + u32bit pvr = 0; + +#if defined(BOTAN_TARGET_OS_SUPPORTS_MFSPR_EMUL) + asm volatile("mfspr %0, 287" : "=r" (pvr)); +#endif + // Top 16 bit suffice to identify model + pvr >>= 16; + + altivec_capable |= (pvr == PVR_G4_7400); + altivec_capable |= ((pvr >> 8) == PVR_G4_74xx_24); + altivec_capable |= (pvr == PVR_G5_970); + altivec_capable |= (pvr == PVR_G5_970FX); + altivec_capable |= (pvr == PVR_G5_970MP); + altivec_capable |= (pvr == PVR_G5_970GX); + altivec_capable |= (pvr == PVR_CELL_PPU); +#endif + + first_time = false; + } + + return altivec_capable; + } + +} diff --git a/src/utils/cpuid.h b/src/utils/cpuid.h new file mode 100644 index 000000000..8b8021754 --- /dev/null +++ b/src/utils/cpuid.h @@ -0,0 +1,75 @@ +/** +* Runtime CPU detection +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_CPUID_H__ +#define BOTAN_CPUID_H__ + +#include <botan/types.h> + +namespace Botan { + +class CPUID + { + public: + enum CPUID_bits { + CPUID_RDTSC_BIT = 4, + CPUID_SSE2_BIT = 26, + CPUID_SSSE3_BIT = 41, + CPUID_SSE41_BIT = 51, + CPUID_SSE42_BIT = 52, + CPUID_INTEL_AES_BIT = 57, + }; + + /** + * Return a best guess of the cache line size + */ + static u32bit cache_line_size(); + + /** + * Check if the processor supports RDTSC + */ + static bool has_rdtsc() + { return ((x86_processor_flags() >> CPUID_RDTSC_BIT) & 1); } + + /** + * Check if the processor supports SSE2 + */ + static bool has_sse2() + { return ((x86_processor_flags() >> CPUID_SSE2_BIT) & 1); } + + /** + * Check if the processor supports SSSE3 + */ + static bool has_ssse3() + { return ((x86_processor_flags() >> CPUID_SSSE3_BIT) & 1); } + + /** + * Check if the processor supports SSE4.1 + */ + static bool has_sse41() + { return ((x86_processor_flags() >> CPUID_SSE41_BIT) & 1); } + + /** + * Check if the processor supports SSE4.2 + */ + static bool has_sse42() + { return ((x86_processor_flags() >> CPUID_SSE42_BIT) & 1); } + + /** + * Check if the processor supports Intel AES instructions + */ + static bool has_intel_aes() + { return ((x86_processor_flags() >> CPUID_INTEL_AES_BIT) & 1); } + + static bool has_altivec(); + private: + static u64bit x86_processor_flags(); + }; + +} + +#endif diff --git a/src/utils/datastor/info.txt b/src/utils/datastor/info.txt index 8c38a3ac8..9c995adaf 100644 --- a/src/utils/datastor/info.txt +++ b/src/utils/datastor/info.txt @@ -1,5 +1,3 @@ -realname "Datastore" - load_on auto <add> diff --git a/src/utils/info.txt b/src/utils/info.txt index ab50b88ad..3d024fa09 100644 --- a/src/utils/info.txt +++ b/src/utils/info.txt @@ -1,5 +1,3 @@ -realname "Utility Functions" - define UTIL_FUNCTIONS load_on always @@ -7,27 +5,3 @@ load_on always <libs> tru64 -> rt </libs> - -<add> -bit_ops.h -bswap.h -charset.cpp -charset.h -exceptn.cpp -exceptn.h -loadstor.h -mem_ops.h -mlock.cpp -parsing.cpp -parsing.h -rotate.h -stl_util.h -types.h -ui.cpp -ui.h -util.cpp -util.h -version.cpp -version.h -xor_buf.h -</add> diff --git a/src/utils/loadstor.h b/src/utils/loadstor.h index 77ed1554e..8f430f36c 100644 --- a/src/utils/loadstor.h +++ b/src/utils/loadstor.h @@ -12,6 +12,7 @@ #include <botan/types.h> #include <botan/bswap.h> #include <botan/rotate.h> +#include <botan/prefetch.h> #if BOTAN_TARGET_UNALIGNED_LOADSTOR_OK @@ -165,6 +166,116 @@ inline u64bit load_le<u64bit>(const byte in[], u32bit off) #endif } +template<typename T> +inline void load_le(const byte in[], T& x0, T& x1) + { + x0 = load_le<T>(in, 0); + x1 = load_le<T>(in, 1); + } + +template<typename T> +inline void load_le(const byte in[], + T& x0, T& x1, T& x2, T& x3) + { + x0 = load_le<T>(in, 0); + x1 = load_le<T>(in, 1); + x2 = load_le<T>(in, 2); + x3 = load_le<T>(in, 3); + } + +template<typename T> +inline void load_le(const byte in[], + T& x0, T& x1, T& x2, T& x3, + T& x4, T& x5, T& x6, T& x7) + { + x0 = load_le<T>(in, 0); + x1 = load_le<T>(in, 1); + x2 = load_le<T>(in, 2); + x3 = load_le<T>(in, 3); + x4 = load_le<T>(in, 4); + x5 = load_le<T>(in, 5); + x6 = load_le<T>(in, 6); + x7 = load_le<T>(in, 7); + } + +template<typename T> +inline void load_le(T out[], + const byte in[], + u32bit count) + { + const u32bit blocks = count - (count % 4); + const u32bit left = count - blocks; + + for(u32bit i = 0; i != blocks; i += 4) + { + out[0] = load_le<T>(in, 0); + out[1] = load_le<T>(in, 1); + out[2] = load_le<T>(in, 2); + out[3] = load_le<T>(in, 3); + + out += 4; + in += 4*sizeof(T); + } + + for(u32bit i = 0; i != left; ++i) + out[i] = load_le<T>(in, i); + } + +template<typename T> +inline void load_be(const byte in[], T& x0, T& x1) + { + x0 = load_be<T>(in, 0); + x1 = load_be<T>(in, 1); + } + +template<typename T> +inline void load_be(const byte in[], + T& x0, T& x1, T& x2, T& x3) + { + x0 = load_be<T>(in, 0); + x1 = load_be<T>(in, 1); + x2 = load_be<T>(in, 2); + x3 = load_be<T>(in, 3); + } + +template<typename T> +inline void load_be(const byte in[], + T& x0, T& x1, T& x2, T& x3, + T& x4, T& x5, T& x6, T& x7) + { + x0 = load_be<T>(in, 0); + x1 = load_be<T>(in, 1); + x2 = load_be<T>(in, 2); + x3 = load_be<T>(in, 3); + x4 = load_be<T>(in, 4); + x5 = load_be<T>(in, 5); + x6 = load_be<T>(in, 6); + x7 = load_be<T>(in, 7); + } + +template<typename T> +inline void load_be(T out[], + const byte in[], + u32bit count) + { + const u32bit blocks = count - (count % 4); + const u32bit left = count - blocks; + + for(u32bit i = 0; i != blocks; i += 4) + { + out[0] = load_be<T>(in, 0); + out[1] = load_be<T>(in, 1); + out[2] = load_be<T>(in, 2); + out[3] = load_be<T>(in, 3); + + out += 4; + in += 4*sizeof(T); + } + + for(u32bit i = 0; i != left; ++i) + out[i] = load_be<T>(in, i); + } + /* * Endian-Specific Word Storing Operations */ @@ -245,35 +356,63 @@ inline void store_le(u64bit in, byte out[8]) } template<typename T> -inline void store_le(byte out[], T a, T b) +inline void store_le(byte out[], T x0, T x1) + { + store_le(x0, out + (0 * sizeof(T))); + store_le(x1, out + (1 * sizeof(T))); + } + +template<typename T> +inline void store_be(byte out[], T x0, T x1) + { + store_be(x0, out + (0 * sizeof(T))); + store_be(x1, out + (1 * sizeof(T))); + } + +template<typename T> +inline void store_le(byte out[], T x0, T x1, T x2, T x3) { - store_le(a, out + (0 * sizeof(T))); - store_le(b, out + (1 * sizeof(T))); + store_le(x0, out + (0 * sizeof(T))); + store_le(x1, out + (1 * sizeof(T))); + store_le(x2, out + (2 * sizeof(T))); + store_le(x3, out + (3 * sizeof(T))); } template<typename T> -inline void store_be(byte out[], T a, T b) +inline void store_be(byte out[], T x0, T x1, T x2, T x3) { - store_be(a, out + (0 * sizeof(T))); - store_be(b, out + (1 * sizeof(T))); + store_be(x0, out + (0 * sizeof(T))); + store_be(x1, out + (1 * sizeof(T))); + store_be(x2, out + (2 * sizeof(T))); + store_be(x3, out + (3 * sizeof(T))); } template<typename T> -inline void store_le(byte out[], T a, T b, T c, T d) +inline void store_le(byte out[], T x0, T x1, T x2, T x3, + T x4, T x5, T x6, T x7) { - store_le(a, out + (0 * sizeof(T))); - store_le(b, out + (1 * sizeof(T))); - store_le(c, out + (2 * sizeof(T))); - store_le(d, out + (3 * sizeof(T))); + store_le(x0, out + (0 * sizeof(T))); + store_le(x1, out + (1 * sizeof(T))); + store_le(x2, out + (2 * sizeof(T))); + store_le(x3, out + (3 * sizeof(T))); + store_le(x4, out + (4 * sizeof(T))); + store_le(x5, out + (5 * sizeof(T))); + store_le(x6, out + (6 * sizeof(T))); + store_le(x7, out + (7 * sizeof(T))); } template<typename T> -inline void store_be(byte out[], T a, T b, T c, T d) +inline void store_be(byte out[], T x0, T x1, T x2, T x3, + T x4, T x5, T x6, T x7) { - store_be(a, out + (0 * sizeof(T))); - store_be(b, out + (1 * sizeof(T))); - store_be(c, out + (2 * sizeof(T))); - store_be(d, out + (3 * sizeof(T))); + store_be(x0, out + (0 * sizeof(T))); + store_be(x1, out + (1 * sizeof(T))); + store_be(x2, out + (2 * sizeof(T))); + store_be(x3, out + (3 * sizeof(T))); + store_be(x4, out + (4 * sizeof(T))); + store_be(x5, out + (5 * sizeof(T))); + store_be(x6, out + (6 * sizeof(T))); + store_be(x7, out + (7 * sizeof(T))); } } diff --git a/src/utils/mlock.cpp b/src/utils/mlock.cpp index 9bb062da5..6453d8a30 100644 --- a/src/utils/mlock.cpp +++ b/src/utils/mlock.cpp @@ -5,7 +5,7 @@ * Distributed under the terms of the Botan license */ -#include <botan/util.h> +#include <botan/mlock.h> #if defined(BOTAN_TARGET_OS_HAS_POSIX_MLOCK) #include <sys/types.h> diff --git a/src/utils/mlock.h b/src/utils/mlock.h new file mode 100644 index 000000000..0811e8190 --- /dev/null +++ b/src/utils/mlock.h @@ -0,0 +1,32 @@ +/* +* Memory Locking Functions +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_MLOCK_H__ +#define BOTAN_MLOCK_H__ + +#include <botan/types.h> + +namespace Botan { + +/** +* Lock memory into RAM if possible +* @param addr the start of the memory block +* @param length the length of the memory block in bytes +* @returns true if successful, false otherwise +*/ +BOTAN_DLL bool lock_mem(void* addr, u32bit length); + +/** +* Unlock memory locked with lock_mem() +* @param addr the start of the memory block +* @param length the length of the memory block in bytes +*/ +BOTAN_DLL void unlock_mem(void* addr, u32bit length); + +} + +#endif diff --git a/src/utils/parsing.cpp b/src/utils/parsing.cpp index bdb9e79dc..58a8e0b38 100644 --- a/src/utils/parsing.cpp +++ b/src/utils/parsing.cpp @@ -23,6 +23,9 @@ u32bit to_u32bit(const std::string& number) { const u32bit OVERFLOW_MARK = 0xFFFFFFFF / 10; + if(*j == ' ') + continue; + byte digit = Charset::char2digit(*j); if((n > OVERFLOW_MARK) || (n == OVERFLOW_MARK && digit > 5)) diff --git a/src/utils/prefetch.h b/src/utils/prefetch.h new file mode 100644 index 000000000..7afdbda0a --- /dev/null +++ b/src/utils/prefetch.h @@ -0,0 +1,43 @@ +/* +* Prefetching Operations +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_PREFETCH_H__ +#define BOTAN_PREFETCH_H__ + +#include <botan/cpuid.h> + +namespace Botan { + +namespace PREFETCH { + +template<typename T> +inline void readonly(const T* addr, u32bit length) + { +#if defined(__GNUG__) + const u32bit Ts_per_cache_line = CPUID::cache_line_size() / sizeof(T); + + for(u32bit i = 0; i <= length; i += Ts_per_cache_line) + __builtin_prefetch(addr + i, 0); +#endif + } + +template<typename T> +inline void readwrite(const T* addr, u32bit length) + { +#if defined(__GNUG__) + const u32bit Ts_per_cache_line = CPUID::cache_line_size() / sizeof(T); + + for(u32bit i = 0; i <= length; i += Ts_per_cache_line) + __builtin_prefetch(addr + i, 0); +#endif + } + +} + +} + +#endif diff --git a/src/utils/rounding.h b/src/utils/rounding.h new file mode 100644 index 000000000..11ab90b8d --- /dev/null +++ b/src/utils/rounding.h @@ -0,0 +1,35 @@ +/* +* Integer Rounding Functions +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_ROUNDING_H__ +#define BOTAN_ROUNDING_H__ + +#include <botan/types.h> + +namespace Botan { + +/* +* Round up n to multiple of align_to +*/ +inline u32bit round_up(u32bit n, u32bit align_to) + { + if(n % align_to || n == 0) + n += align_to - (n % align_to); + return n; + } + +/* +* Round down n to multiple of align_to +*/ +inline u32bit round_down(u32bit n, u32bit align_to) + { + return (n - (n % align_to)); + } + +} + +#endif diff --git a/src/utils/simd_32/info.txt b/src/utils/simd_32/info.txt new file mode 100644 index 000000000..64707c1e4 --- /dev/null +++ b/src/utils/simd_32/info.txt @@ -0,0 +1,16 @@ +define SIMD_32 + +load_on always + +<arch> +pentium-m +pentium4 +prescott +amd64 +</arch> + +<cc> +gcc +icc +msvc +</cc> diff --git a/src/utils/simd_32/simd_32.h b/src/utils/simd_32/simd_32.h new file mode 100644 index 000000000..be426efd6 --- /dev/null +++ b/src/utils/simd_32/simd_32.h @@ -0,0 +1,32 @@ +/** +* Lightweight wrappers for SIMD operations +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_SIMD_32_H__ +#define BOTAN_SIMD_32_H__ + +#include <botan/types.h> + +//#define BOTAN_TARGET_CPU_HAS_SSE2 + +#if defined(BOTAN_TARGET_CPU_HAS_SSE2) + + #include <botan/simd_sse.h> + namespace Botan { typedef SIMD_SSE2 SIMD_32; } + +#elif defined(BOTAN_TARGET_CPU_HAS_ALTIVEC) + + #include <botan/simd_altivec.h> + namespace Botan { typedef SIMD_Altivec SIMD_32; } + +#else + + #include <botan/simd_scalar.h> + namespace Botan { typedef SIMD_Scalar SIMD_32; } + +#endif + +#endif diff --git a/src/utils/simd_32/simd_altivec.h b/src/utils/simd_32/simd_altivec.h new file mode 100644 index 000000000..e1aa62002 --- /dev/null +++ b/src/utils/simd_32/simd_altivec.h @@ -0,0 +1,202 @@ +/** +* Lightweight wrappers around AltiVec for 32-bit operations +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_SIMD_ALTIVEC_H__ +#define BOTAN_SIMD_ALTIVEC_H__ + +#include <botan/loadstor.h> +#include <botan/cpuid.h> + +#include <altivec.h> +#undef vector + +namespace Botan { + +class SIMD_Altivec + { + public: + bool enabled() const { return CPUID::has_altivec(); } + + SIMD_Altivec(const u32bit B[4]) + { + reg = (__vector unsigned int){B[0], B[1], B[2], B[3]}; + } + + SIMD_Altivec(u32bit B0, u32bit B1, u32bit B2, u32bit B3) + { + reg = (__vector unsigned int){B0, B1, B2, B3}; + } + + SIMD_Altivec(u32bit B) + { + reg = (__vector unsigned int){B, B, B, B}; + } + + static SIMD_Altivec load_le(const void* in) + { + const u32bit* in_32 = static_cast<const u32bit*>(in); + + __vector unsigned int R0 = vec_ld(0, in_32); + __vector unsigned int R1 = vec_ld(12, in_32); + + __vector unsigned char perm = vec_lvsl(0, in_32); + + perm = vec_xor(perm, vec_splat_u8(3)); + + R0 = vec_perm(R0, R1, perm); + + return SIMD_Altivec(R0); + } + + static SIMD_Altivec load_be(const void* in) + { + const u32bit* in_32 = static_cast<const u32bit*>(in); + + __vector unsigned int R0 = vec_ld(0, in_32); + __vector unsigned int R1 = vec_ld(12, in_32); + + __vector unsigned char perm = vec_lvsl(0, in_32); + + R0 = vec_perm(R0, R1, perm); + + return SIMD_Altivec(R0); + } + + void store_le(byte out[]) const + { + __vector unsigned char perm = vec_lvsl(0, (u32bit*)0); + + perm = vec_xor(perm, vec_splat_u8(3)); + + union { + __vector unsigned int V; + u32bit R[4]; + } vec; + + vec.V = vec_perm(reg, reg, perm); + + Botan::store_be(out, vec.R[0], vec.R[1], vec.R[2], vec.R[3]); + } + + void store_be(byte out[]) const + { + union { + __vector unsigned int V; + u32bit R[4]; + } vec; + + vec.V = reg; + + Botan::store_be(out, vec.R[0], vec.R[1], vec.R[2], vec.R[3]); + } + + void rotate_left(u32bit rot) + { + __vector unsigned int rot_vec = + (__vector unsigned int){rot, rot, rot, rot}; + + reg = vec_rl(reg, rot_vec); + } + + void rotate_right(u32bit rot) + { + rotate_left(32 - rot); + } + + void operator+=(const SIMD_Altivec& other) + { + reg = vec_add(reg, other.reg); + } + + SIMD_Altivec operator+(const SIMD_Altivec& other) const + { + return vec_add(reg, other.reg); + } + + void operator-=(const SIMD_Altivec& other) + { + reg = vec_sub(reg, other.reg); + } + + SIMD_Altivec operator-(const SIMD_Altivec& other) const + { + return vec_sub(reg, other.reg); + } + + void operator^=(const SIMD_Altivec& other) + { + reg = vec_xor(reg, other.reg); + } + + SIMD_Altivec operator^(const SIMD_Altivec& other) const + { + return vec_xor(reg, other.reg); + } + + void operator|=(const SIMD_Altivec& other) + { + reg = vec_or(reg, other.reg); + } + + void operator&=(const SIMD_Altivec& other) + { + reg = vec_and(reg, other.reg); + } + + SIMD_Altivec operator<<(u32bit shift) const + { + __vector unsigned int shift_vec = + (__vector unsigned int){shift, shift, shift, shift}; + + return vec_sl(reg, shift_vec); + } + + SIMD_Altivec operator>>(u32bit shift) const + { + __vector unsigned int shift_vec = + (__vector unsigned int){shift, shift, shift, shift}; + + return vec_sr(reg, shift_vec); + } + + SIMD_Altivec operator~() const + { + return vec_nor(reg, reg); + } + + SIMD_Altivec bswap() const + { + __vector unsigned char perm = vec_lvsl(0, (u32bit*)0); + + perm = vec_xor(perm, vec_splat_u8(3)); + + return SIMD_Altivec(vec_perm(reg, reg, perm)); + } + + static void transpose(SIMD_Altivec& B0, SIMD_Altivec& B1, + SIMD_Altivec& B2, SIMD_Altivec& B3) + { + __vector unsigned int T0 = vec_mergeh(B0.reg, B2.reg); + __vector unsigned int T1 = vec_mergel(B0.reg, B2.reg); + __vector unsigned int T2 = vec_mergeh(B1.reg, B3.reg); + __vector unsigned int T3 = vec_mergel(B1.reg, B3.reg); + + B0.reg = vec_mergeh(T0, T2); + B1.reg = vec_mergel(T0, T2); + B2.reg = vec_mergeh(T1, T3); + B3.reg = vec_mergel(T1, T3); + } + + private: + SIMD_Altivec(__vector unsigned int input) { reg = input; } + + __vector unsigned int reg; + }; + +} + +#endif diff --git a/src/utils/simd_32/simd_scalar.h b/src/utils/simd_32/simd_scalar.h new file mode 100644 index 000000000..5fc20b462 --- /dev/null +++ b/src/utils/simd_32/simd_scalar.h @@ -0,0 +1,202 @@ +/** +* Scalar emulation of SIMD 32-bit operations +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_SIMD_SCALAR_H__ +#define BOTAN_SIMD_SCALAR_H__ + +#include <botan/loadstor.h> +#include <botan/bswap.h> + +namespace Botan { + +class SIMD_Scalar + { + public: + bool enabled() const { return true; } + + SIMD_Scalar(const u32bit B[4]) + { + R0 = B[0]; + R1 = B[1]; + R2 = B[2]; + R3 = B[3]; + } + + SIMD_Scalar(u32bit B0, u32bit B1, u32bit B2, u32bit B3) + { + R0 = B0; + R1 = B1; + R2 = B2; + R3 = B3; + } + + SIMD_Scalar(u32bit B) + { + R0 = B; + R1 = B; + R2 = B; + R3 = B; + } + + static SIMD_Scalar load_le(const void* in) + { + const byte* in_b = static_cast<const byte*>(in); + return SIMD_Scalar(Botan::load_le<u32bit>(in_b, 0), + Botan::load_le<u32bit>(in_b, 1), + Botan::load_le<u32bit>(in_b, 2), + Botan::load_le<u32bit>(in_b, 3)); + } + + static SIMD_Scalar load_be(const void* in) + { + const byte* in_b = static_cast<const byte*>(in); + return SIMD_Scalar(Botan::load_be<u32bit>(in_b, 0), + Botan::load_be<u32bit>(in_b, 1), + Botan::load_be<u32bit>(in_b, 2), + Botan::load_be<u32bit>(in_b, 3)); + } + + void store_le(byte out[]) const + { + Botan::store_le(out, R0, R1, R2, R3); + } + + void store_be(byte out[]) const + { + Botan::store_be(out, R0, R1, R2, R3); + } + + void rotate_left(u32bit rot) + { + R0 = Botan::rotate_left(R0, rot); + R1 = Botan::rotate_left(R1, rot); + R2 = Botan::rotate_left(R2, rot); + R3 = Botan::rotate_left(R3, rot); + } + + void rotate_right(u32bit rot) + { + R0 = Botan::rotate_right(R0, rot); + R1 = Botan::rotate_right(R1, rot); + R2 = Botan::rotate_right(R2, rot); + R3 = Botan::rotate_right(R3, rot); + } + + void operator+=(const SIMD_Scalar& other) + { + R0 += other.R0; + R1 += other.R1; + R2 += other.R2; + R3 += other.R3; + } + + SIMD_Scalar operator+(const SIMD_Scalar& other) const + { + return SIMD_Scalar(R0 + other.R0, + R1 + other.R1, + R2 + other.R2, + R3 + other.R3); + } + + void operator-=(const SIMD_Scalar& other) + { + R0 -= other.R0; + R1 -= other.R1; + R2 -= other.R2; + R3 -= other.R3; + } + + SIMD_Scalar operator-(const SIMD_Scalar& other) const + { + return SIMD_Scalar(R0 - other.R0, + R1 - other.R1, + R2 - other.R2, + R3 - other.R3); + } + + void operator^=(const SIMD_Scalar& other) + { + R0 ^= other.R0; + R1 ^= other.R1; + R2 ^= other.R2; + R3 ^= other.R3; + } + + SIMD_Scalar operator^(const SIMD_Scalar& other) const + { + return SIMD_Scalar(R0 ^ other.R0, + R1 ^ other.R1, + R2 ^ other.R2, + R3 ^ other.R3); + } + + void operator|=(const SIMD_Scalar& other) + { + R0 |= other.R0; + R1 |= other.R1; + R2 |= other.R2; + R3 |= other.R3; + } + + void operator&=(const SIMD_Scalar& other) + { + R0 &= other.R0; + R1 &= other.R1; + R2 &= other.R2; + R3 &= other.R3; + } + + SIMD_Scalar operator<<(u32bit shift) const + { + return SIMD_Scalar(R0 << shift, + R1 << shift, + R2 << shift, + R3 << shift); + } + + SIMD_Scalar operator>>(u32bit shift) const + { + return SIMD_Scalar(R0 >> shift, + R1 >> shift, + R2 >> shift, + R3 >> shift); + } + + SIMD_Scalar operator~() const + { + return SIMD_Scalar(~R0, ~R1, ~R2, ~R3); + } + + SIMD_Scalar bswap() const + { + return SIMD_Scalar(reverse_bytes(R0), + reverse_bytes(R1), + reverse_bytes(R2), + reverse_bytes(R3)); + } + + static void transpose(SIMD_Scalar& B0, SIMD_Scalar& B1, + SIMD_Scalar& B2, SIMD_Scalar& B3) + { + SIMD_Scalar T0(B0.R0, B1.R0, B2.R0, B3.R0); + SIMD_Scalar T1(B0.R1, B1.R1, B2.R1, B3.R1); + SIMD_Scalar T2(B0.R2, B1.R2, B2.R2, B3.R2); + SIMD_Scalar T3(B0.R3, B1.R3, B2.R3, B3.R3); + + B0 = T0; + B1 = T1; + B2 = T2; + B3 = T3; + } + + private: + u32bit R0, R1, R2, R3; + }; + +} + +#endif diff --git a/src/utils/simd_32/simd_sse.h b/src/utils/simd_32/simd_sse.h new file mode 100644 index 000000000..c45d8032f --- /dev/null +++ b/src/utils/simd_32/simd_sse.h @@ -0,0 +1,156 @@ +/** +* Lightweight wrappers for SSE2 intrinsics for 32-bit operations +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_SIMD_SSE_H__ +#define BOTAN_SIMD_SSE_H__ + +#include <botan/cpuid.h> + +#include <emmintrin.h> + +namespace Botan { + +class SIMD_SSE2 + { + public: + bool enabled() const { return CPUID::has_sse2(); } + + SIMD_SSE2(const u32bit B[4]) + { + reg = _mm_loadu_si128((const __m128i*)B); + } + + SIMD_SSE2(u32bit B0, u32bit B1, u32bit B2, u32bit B3) + { + reg = _mm_set_epi32(B0, B1, B2, B3); + } + + SIMD_SSE2(u32bit B) + { + reg = _mm_set1_epi32(B); + } + + static SIMD_SSE2 load_le(const void* in) + { + return _mm_loadu_si128((const __m128i*)in); + } + + static SIMD_SSE2 load_be(const void* in) + { + return load_le(in).bswap(); + } + + void store_le(byte out[]) const + { + _mm_storeu_si128((__m128i*)out, reg); + } + + void store_be(byte out[]) const + { + bswap().store_le(out); + } + + void rotate_left(u32bit rot) + { + reg = _mm_or_si128(_mm_slli_epi32(reg, rot), + _mm_srli_epi32(reg, 32-rot)); + } + + void rotate_right(u32bit rot) + { + rotate_left(32 - rot); + } + + void operator+=(const SIMD_SSE2& other) + { + reg = _mm_add_epi32(reg, other.reg); + } + + SIMD_SSE2 operator+(const SIMD_SSE2& other) const + { + return _mm_add_epi32(reg, other.reg); + } + + void operator-=(const SIMD_SSE2& other) + { + reg = _mm_sub_epi32(reg, other.reg); + } + + SIMD_SSE2 operator-(const SIMD_SSE2& other) const + { + return _mm_sub_epi32(reg, other.reg); + } + + void operator^=(const SIMD_SSE2& other) + { + reg = _mm_xor_si128(reg, other.reg); + } + + SIMD_SSE2 operator^(const SIMD_SSE2& other) const + { + return _mm_xor_si128(reg, other.reg); + } + + void operator|=(const SIMD_SSE2& other) + { + reg = _mm_or_si128(reg, other.reg); + } + + void operator&=(const SIMD_SSE2& other) + { + reg = _mm_and_si128(reg, other.reg); + } + + SIMD_SSE2 operator<<(u32bit shift) const + { + return _mm_slli_epi32(reg, shift); + } + + SIMD_SSE2 operator>>(u32bit shift) const + { + return _mm_srli_epi32(reg, shift); + } + + SIMD_SSE2 operator~() const + { + static const __m128i all_ones = _mm_set1_epi32(0xFFFFFFFF); + return _mm_xor_si128(reg, all_ones); + } + + SIMD_SSE2 bswap() const + { + __m128i T = reg; + + T = _mm_shufflehi_epi16(T, _MM_SHUFFLE(2, 3, 0, 1)); + T = _mm_shufflelo_epi16(T, _MM_SHUFFLE(2, 3, 0, 1)); + + return _mm_or_si128(_mm_srli_epi16(T, 8), + _mm_slli_epi16(T, 8)); + } + + static void transpose(SIMD_SSE2& B0, SIMD_SSE2& B1, + SIMD_SSE2& B2, SIMD_SSE2& B3) + { + __m128i T0 = _mm_unpacklo_epi32(B0.reg, B1.reg); + __m128i T1 = _mm_unpacklo_epi32(B2.reg, B3.reg); + __m128i T2 = _mm_unpackhi_epi32(B0.reg, B1.reg); + __m128i T3 = _mm_unpackhi_epi32(B2.reg, B3.reg); + B0.reg = _mm_unpacklo_epi64(T0, T1); + B1.reg = _mm_unpackhi_epi64(T0, T1); + B2.reg = _mm_unpacklo_epi64(T2, T3); + B3.reg = _mm_unpackhi_epi64(T2, T3); + } + + private: + SIMD_SSE2(__m128i in) { reg = in; } + + __m128i reg; + }; + +} + +#endif diff --git a/src/utils/util.h b/src/utils/util.h deleted file mode 100644 index ac7867390..000000000 --- a/src/utils/util.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -* Utility Functions -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_UTIL_H__ -#define BOTAN_UTIL_H__ - -#include <botan/types.h> - -namespace Botan { - -/* -* Time Access Functions -*/ -BOTAN_DLL u64bit system_time(); - -/* -* Memory Locking Functions -*/ -BOTAN_DLL bool lock_mem(void*, u32bit); -BOTAN_DLL void unlock_mem(void*, u32bit); - -/* -* Misc Utility Functions -*/ -BOTAN_DLL u32bit round_up(u32bit, u32bit); -BOTAN_DLL u32bit round_down(u32bit, u32bit); - -/* -* Work Factor Estimates -*/ -BOTAN_DLL u32bit dl_work_factor(u32bit); - -} - -#endif diff --git a/wrappers/perl-xs/Botan.pm b/src/wrap/perl-xs/Botan.pm index ac4ad91fb..ac4ad91fb 100644 --- a/wrappers/perl-xs/Botan.pm +++ b/src/wrap/perl-xs/Botan.pm diff --git a/wrappers/perl-xs/Botan.xs b/src/wrap/perl-xs/Botan.xs index ded129d2e..ded129d2e 100644 --- a/wrappers/perl-xs/Botan.xs +++ b/src/wrap/perl-xs/Botan.xs diff --git a/wrappers/perl-xs/Changes b/src/wrap/perl-xs/Changes index 5f32b0c63..5f32b0c63 100644 --- a/wrappers/perl-xs/Changes +++ b/src/wrap/perl-xs/Changes diff --git a/wrappers/perl-xs/MANIFEST b/src/wrap/perl-xs/MANIFEST index b9d8454d6..b9d8454d6 100644 --- a/wrappers/perl-xs/MANIFEST +++ b/src/wrap/perl-xs/MANIFEST diff --git a/wrappers/perl-xs/Makefile.PL b/src/wrap/perl-xs/Makefile.PL index d35c99168..46317e72b 100644 --- a/wrappers/perl-xs/Makefile.PL +++ b/src/wrap/perl-xs/Makefile.PL @@ -9,7 +9,7 @@ if ( $^O eq 'MSWin32' ) else { $cc = 'g++'; - $cflags = '-fexceptions ' . qx( botan-config --cflags ); + $cflags = '-Wno-write-strings -fexceptions ' . qx( botan-config --cflags ); $libs = qx( botan-config --libs ); } diff --git a/wrappers/perl-xs/data/ca.cert.der b/src/wrap/perl-xs/data/ca.cert.der Binary files differindex d6ed8aeaf..d6ed8aeaf 100644 --- a/wrappers/perl-xs/data/ca.cert.der +++ b/src/wrap/perl-xs/data/ca.cert.der diff --git a/wrappers/perl-xs/data/ca.cert.pem b/src/wrap/perl-xs/data/ca.cert.pem index 012913b26..012913b26 100644 --- a/wrappers/perl-xs/data/ca.cert.pem +++ b/src/wrap/perl-xs/data/ca.cert.pem diff --git a/wrappers/perl-xs/t/base64.t b/src/wrap/perl-xs/t/base64.t index f0973e13e..f0973e13e 100644 --- a/wrappers/perl-xs/t/base64.t +++ b/src/wrap/perl-xs/t/base64.t diff --git a/wrappers/perl-xs/t/filt.t b/src/wrap/perl-xs/t/filt.t index 2a7b4c8ba..2a7b4c8ba 100644 --- a/wrappers/perl-xs/t/filt.t +++ b/src/wrap/perl-xs/t/filt.t diff --git a/wrappers/perl-xs/t/hex.t b/src/wrap/perl-xs/t/hex.t index 6f447b25c..6f447b25c 100644 --- a/wrappers/perl-xs/t/hex.t +++ b/src/wrap/perl-xs/t/hex.t diff --git a/wrappers/perl-xs/t/oid.t b/src/wrap/perl-xs/t/oid.t index 66204541f..66204541f 100644 --- a/wrappers/perl-xs/t/oid.t +++ b/src/wrap/perl-xs/t/oid.t diff --git a/wrappers/perl-xs/t/pipe.t b/src/wrap/perl-xs/t/pipe.t index f850d8519..f850d8519 100644 --- a/wrappers/perl-xs/t/pipe.t +++ b/src/wrap/perl-xs/t/pipe.t diff --git a/wrappers/perl-xs/t/testutl.pl b/src/wrap/perl-xs/t/testutl.pl index add6f6a45..add6f6a45 100644 --- a/wrappers/perl-xs/t/testutl.pl +++ b/src/wrap/perl-xs/t/testutl.pl diff --git a/wrappers/perl-xs/t/x509cert.t b/src/wrap/perl-xs/t/x509cert.t index 2a943aeac..2a943aeac 100644 --- a/wrappers/perl-xs/t/x509cert.t +++ b/src/wrap/perl-xs/t/x509cert.t diff --git a/wrappers/perl-xs/typemap b/src/wrap/perl-xs/typemap index d7403d40d..d7403d40d 100644 --- a/wrappers/perl-xs/typemap +++ b/src/wrap/perl-xs/typemap diff --git a/src/wrap/python/__init__.py b/src/wrap/python/__init__.py new file mode 100644 index 000000000..2df9a456f --- /dev/null +++ b/src/wrap/python/__init__.py @@ -0,0 +1,4 @@ +from _botan import * + +# Initialize the library when the module is imported +init = LibraryInitializer() diff --git a/src/wrap/python/core.cpp b/src/wrap/python/core.cpp new file mode 100644 index 000000000..fe26e16ee --- /dev/null +++ b/src/wrap/python/core.cpp @@ -0,0 +1,216 @@ +/* +* Boost.Python module definition +* (C) 1999-2007 Jack Lloyd +*/ + +#include <botan/init.h> +#include <botan/pipe.h> +#include <botan/lookup.h> +#include <botan/cryptobox.h> +#include <botan/pbkdf2.h> +#include <botan/hmac.h> +using namespace Botan; + +#include "python_botan.h" + +class Py_Cipher + { + public: + Py_Cipher(std::string algo_name, std::string direction, + std::string key); + + std::string cipher_noiv(const std::string& text); + + std::string cipher(const std::string& text, + const std::string& iv); + + std::string name() const { return algo_name; } + private: + std::string algo_name; + Keyed_Filter* filter; + Pipe pipe; + }; + +std::string Py_Cipher::cipher(const std::string& input, + const std::string& iv_str) + { + if(iv_str.size()) + { + const byte* iv_bytes = reinterpret_cast<const byte*>(iv_str.data()); + u32bit iv_len = iv_str.size(); + filter->set_iv(InitializationVector(iv_bytes, iv_len)); + } + + pipe.process_msg(input); + return pipe.read_all_as_string(Pipe::LAST_MESSAGE); + } + +// For IV-less algorithms +std::string Py_Cipher::cipher_noiv(const std::string& input) + { + pipe.process_msg(input); + return pipe.read_all_as_string(Pipe::LAST_MESSAGE); + } + +Py_Cipher::Py_Cipher(std::string algo_name, + std::string direction, + std::string key_str) + { + const byte* key_bytes = reinterpret_cast<const byte*>(key_str.data()); + u32bit key_len = key_str.size(); + + Cipher_Dir dir; + + if(direction == "encrypt") + dir = ENCRYPTION; + else if(direction == "decrypt") + dir = DECRYPTION; + else + throw std::invalid_argument("Bad cipher direction " + direction); + + filter = get_cipher(algo_name, dir); + filter->set_key(SymmetricKey(key_bytes, key_len)); + pipe.append(filter); + } + +class Py_HashFunction + { + public: + Py_HashFunction(const std::string& algo_name) + { + hash = get_hash(algo_name); + } + + ~Py_HashFunction() { delete hash; } + + void update(const std::string& input) + { + hash->update(input); + } + + std::string final() + { + std::string out(output_length(), 0); + hash->final(reinterpret_cast<byte*>(&out[0])); + return out; + } + + std::string name() const + { + return hash->name(); + } + + u32bit output_length() const + { + return hash->OUTPUT_LENGTH; + } + + private: + HashFunction* hash; + }; + +class Py_MAC + { + public: + + Py_MAC(const std::string& name, const std::string& key_str) + { + mac = get_mac(name); + + mac->set_key(reinterpret_cast<const byte*>(key_str.data()), + key_str.size()); + } + + ~Py_MAC() { delete mac; } + + u32bit output_length() const { return mac->OUTPUT_LENGTH; } + + std::string name() const { return mac->name(); } + + void update(const std::string& in) { mac->update(in); } + + std::string final() + { + std::string out(output_length(), 0); + mac->final(reinterpret_cast<byte*>(&out[0])); + return out; + } + private: + MessageAuthenticationCode* mac; + }; + +std::string cryptobox_encrypt(const std::string& in, + const std::string& passphrase, + Python_RandomNumberGenerator& rng) + { + const byte* in_bytes = reinterpret_cast<const byte*>(in.data()); + + return CryptoBox::encrypt(in_bytes, in.size(), + passphrase, rng.get_underlying_rng()); + } + +std::string cryptobox_decrypt(const std::string& in, + const std::string& passphrase) + { + const byte* in_bytes = reinterpret_cast<const byte*>(in.data()); + + return CryptoBox::decrypt(in_bytes, in.size(), + passphrase); + } + +std::string python_pbkdf2(const std::string& passphrase, + const std::string& salt, + u32bit iterations, + u32bit output_size, + const std::string& hash_fn) + { + PKCS5_PBKDF2 pbkdf2(new HMAC(get_hash(hash_fn))); + + pbkdf2.set_iterations(iterations); + pbkdf2.change_salt(reinterpret_cast<const byte*>(salt.data()), salt.size()); + + return make_string(pbkdf2.derive_key(output_size, passphrase).bits_of()); + } + +BOOST_PYTHON_MODULE(_botan) + { + python::class_<LibraryInitializer>("LibraryInitializer") + .def(python::init< python::optional<std::string> >()); + + python::class_<Python_RandomNumberGenerator>("RandomNumberGenerator") + .def(python::init<>()) + .def("__str__", &Python_RandomNumberGenerator::name) + .def("name", &Python_RandomNumberGenerator::name) + .def("reseed", &Python_RandomNumberGenerator::reseed) + .def("add_entropy", &Python_RandomNumberGenerator::add_entropy) + .def("gen_random_byte", &Python_RandomNumberGenerator::gen_random_byte) + .def("gen_random", &Python_RandomNumberGenerator::gen_random); + + python::class_<Py_Cipher, boost::noncopyable> + ("Cipher", python::init<std::string, std::string, std::string>()) + .def("name", &Py_Cipher::name) + .def("cipher", &Py_Cipher::cipher) + .def("cipher", &Py_Cipher::cipher_noiv); + + python::class_<Py_HashFunction, boost::noncopyable> + ("HashFunction", python::init<std::string>()) + .def("update", &Py_HashFunction::update) + .def("final", &Py_HashFunction::final) + .def("name", &Py_HashFunction::name) + .def("output_length", &Py_HashFunction::output_length); + + python::class_<Py_MAC, boost::noncopyable> + ("MAC", python::init<std::string, std::string>()) + .def("update", &Py_MAC::update) + .def("final", &Py_MAC::final) + .def("name", &Py_MAC::name) + .def("output_length", &Py_MAC::output_length); + + python::def("cryptobox_encrypt", cryptobox_encrypt); + python::def("cryptobox_decrypt", cryptobox_decrypt); + python::def("pbkdf2", python_pbkdf2); + + export_filters(); + export_rsa(); + export_x509(); + } diff --git a/wrappers/boost-python/src/filter.cpp b/src/wrap/python/filter.cpp index 830e090de..a678af9e5 100644 --- a/wrappers/boost-python/src/filter.cpp +++ b/src/wrap/python/filter.cpp @@ -159,8 +159,10 @@ void export_filters() class_<Pipe, boost::noncopyable>("PipeObj") .def(init<>()) + /* .def_readonly("LAST_MESSAGE", &Pipe::LAST_MESSAGE) .def_readonly("DEFAULT_MESSAGE", &Pipe::DEFAULT_MESSAGE) + */ .add_property("default_msg", &Pipe::default_msg, &Pipe::set_default_msg) .add_property("msg_count", &Pipe::message_count) .def("append", append_filter) diff --git a/wrappers/boost-python/src/python_botan.h b/src/wrap/python/python_botan.h index d0fd10207..646c2e2c1 100644 --- a/wrappers/boost-python/src/python_botan.h +++ b/src/wrap/python/python_botan.h @@ -2,19 +2,16 @@ #ifndef BOTAN_BOOST_PYTHON_COMMON_H__ #define BOTAN_BOOST_PYTHON_COMMON_H__ -#include <botan/base.h> +#include <botan/exceptn.h> +#include <botan/parsing.h> +#include <botan/secmem.h> using namespace Botan; #include <boost/python.hpp> namespace python = boost::python; - -extern void export_block_ciphers(); -extern void export_stream_ciphers(); -extern void export_hash_functions(); -extern void export_macs(); extern void export_filters(); -extern void export_pk(); +extern void export_rsa(); extern void export_x509(); class Bad_Size : public Exception @@ -51,4 +48,32 @@ inline python::object get_owner(T* me) python::borrowed(python::detail::wrapper_base_::get_owner(*me)))); } +class Python_RandomNumberGenerator + { + public: + Python_RandomNumberGenerator() + { rng = RandomNumberGenerator::make_rng(); } + ~Python_RandomNumberGenerator() { delete rng; } + + std::string name() const { return rng->name(); } + + void reseed() { rng->reseed(192); } + + int gen_random_byte() { return rng->next_byte(); } + + std::string gen_random(int n) + { + std::string s(n, 0); + rng->randomize(reinterpret_cast<byte*>(&s[0]), n); + return s; + } + + void add_entropy(const std::string& in) + { rng->add_entropy(reinterpret_cast<const byte*>(in.c_str()), in.length()); } + + RandomNumberGenerator& get_underlying_rng() { return *rng; } + private: + RandomNumberGenerator* rng; + }; + #endif diff --git a/src/wrap/python/rsa.cpp b/src/wrap/python/rsa.cpp new file mode 100644 index 000000000..900c3f93d --- /dev/null +++ b/src/wrap/python/rsa.cpp @@ -0,0 +1,187 @@ +/* +* Boost.Python module definition +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/rsa.h> +#include <botan/look_pk.h> +#include <botan/pubkey.h> +#include <botan/x509_key.h> +using namespace Botan; + +#include "python_botan.h" +#include <sstream> + +std::string bigint2str(const BigInt& n) + { + std::ostringstream out; + out << n; + return out.str(); + } + +class Py_RSA_PrivateKey + { + public: + Py_RSA_PrivateKey(std::string pem_str, + Python_RandomNumberGenerator& rng, + std::string pass); + + Py_RSA_PrivateKey(u32bit bits, Python_RandomNumberGenerator& rng); + ~Py_RSA_PrivateKey() { delete rsa_key; } + + std::string to_string() const + { + return PKCS8::PEM_encode(*rsa_key); + } + + std::string get_N() const { return bigint2str(get_bigint_N()); } + std::string get_E() const { return bigint2str(get_bigint_E()); } + + const BigInt& get_bigint_N() const { return rsa_key->get_n(); } + const BigInt& get_bigint_E() const { return rsa_key->get_e(); } + + std::string decrypt(const std::string& in, + const std::string& padding); + + std::string sign(const std::string& in, + const std::string& padding, + Python_RandomNumberGenerator& rng); + private: + RSA_PrivateKey* rsa_key; + }; + +std::string Py_RSA_PrivateKey::decrypt(const std::string& in, + const std::string& padding) + { + std::auto_ptr<PK_Decryptor> enc(get_pk_decryptor(*rsa_key, padding)); + + const byte* in_bytes = reinterpret_cast<const byte*>(in.data()); + + return make_string(enc->decrypt(in_bytes, in.size())); + } + +std::string Py_RSA_PrivateKey::sign(const std::string& in, + const std::string& padding, + Python_RandomNumberGenerator& rng) + { + std::auto_ptr<PK_Signer> sign(get_pk_signer(*rsa_key, padding)); + const byte* in_bytes = reinterpret_cast<const byte*>(in.data()); + sign->update(in_bytes, in.size()); + return make_string(sign->signature(rng.get_underlying_rng())); + } + +Py_RSA_PrivateKey::Py_RSA_PrivateKey(u32bit bits, + Python_RandomNumberGenerator& rng) + { + rsa_key = new RSA_PrivateKey(rng.get_underlying_rng(), bits); + } + +Py_RSA_PrivateKey::Py_RSA_PrivateKey(std::string pem_str, + Python_RandomNumberGenerator& rng, + std::string passphrase) + { + DataSource_Memory in(pem_str); + + Private_Key* pkcs8_key = + PKCS8::load_key(in, + rng.get_underlying_rng(), + passphrase); + + rsa_key = dynamic_cast<RSA_PrivateKey*>(pkcs8_key); + + if(!rsa_key) + throw std::invalid_argument("Key is not an RSA key"); + } + +class Py_RSA_PublicKey + { + public: + Py_RSA_PublicKey(std::string pem_str); + Py_RSA_PublicKey(const Py_RSA_PrivateKey&); + ~Py_RSA_PublicKey() { delete rsa_key; } + + std::string get_N() const { return bigint2str(get_bigint_N()); } + std::string get_E() const { return bigint2str(get_bigint_E()); } + + const BigInt& get_bigint_N() const { return rsa_key->get_n(); } + const BigInt& get_bigint_E() const { return rsa_key->get_e(); } + + std::string to_string() const + { + return X509::PEM_encode(*rsa_key); + } + + std::string encrypt(const std::string& in, + const std::string& padding, + Python_RandomNumberGenerator& rng); + + bool verify(const std::string& in, + const std::string& padding, + const std::string& signature); + private: + RSA_PublicKey* rsa_key; + }; + +Py_RSA_PublicKey::Py_RSA_PublicKey(const Py_RSA_PrivateKey& priv) + { + rsa_key = new RSA_PublicKey(priv.get_bigint_N(), priv.get_bigint_E()); + } + +Py_RSA_PublicKey::Py_RSA_PublicKey(std::string pem_str) + { + DataSource_Memory in(pem_str); + Public_Key* x509_key = X509::load_key(in); + + rsa_key = dynamic_cast<RSA_PublicKey*>(x509_key); + + if(!rsa_key) + throw std::invalid_argument("Key is not an RSA key"); + } + +std::string Py_RSA_PublicKey::encrypt(const std::string& in, + const std::string& padding, + Python_RandomNumberGenerator& rng) + { + std::auto_ptr<PK_Encryptor> enc(get_pk_encryptor(*rsa_key, padding)); + + const byte* in_bytes = reinterpret_cast<const byte*>(in.data()); + + return make_string(enc->encrypt(in_bytes, in.size(), + rng.get_underlying_rng())); + } + +bool Py_RSA_PublicKey::verify(const std::string& in, + const std::string& signature, + const std::string& padding) + { + std::auto_ptr<PK_Verifier> ver(get_pk_verifier(*rsa_key, padding)); + + const byte* in_bytes = reinterpret_cast<const byte*>(in.data()); + const byte* sig_bytes = reinterpret_cast<const byte*>(signature.data()); + + ver->update(in_bytes, in.size()); + return ver->check_signature(sig_bytes, signature.size()); + } + +void export_rsa() + { + python::class_<Py_RSA_PublicKey> + ("RSA_PublicKey", python::init<std::string>()) + .def(python::init<const Py_RSA_PrivateKey&>()) + .def("to_string", &Py_RSA_PublicKey::to_string) + .def("encrypt", &Py_RSA_PublicKey::encrypt) + .def("verify", &Py_RSA_PublicKey::verify) + .def("get_N", &Py_RSA_PublicKey::get_N) + .def("get_E", &Py_RSA_PublicKey::get_E); + + python::class_<Py_RSA_PrivateKey> + ("RSA_PrivateKey", python::init<std::string, Python_RandomNumberGenerator&, std::string>()) + .def(python::init<u32bit, Python_RandomNumberGenerator&>()) + .def("to_string", &Py_RSA_PrivateKey::to_string) + .def("decrypt", &Py_RSA_PrivateKey::decrypt) + .def("sign", &Py_RSA_PrivateKey::sign) + .def("get_N", &Py_RSA_PrivateKey::get_N) + .def("get_E", &Py_RSA_PrivateKey::get_E); + } diff --git a/wrappers/boost-python/src/x509.cpp b/src/wrap/python/x509.cpp index 90c2bba1c..90c2bba1c 100644 --- a/wrappers/boost-python/src/x509.cpp +++ b/src/wrap/python/x509.cpp diff --git a/wrappers/boost-python/Makefile b/wrappers/boost-python/Makefile deleted file mode 100644 index e3a1acf37..000000000 --- a/wrappers/boost-python/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -CXX = g++ -LANG_FLAGS = -fPIC -Wall -Wno-unused -ftemplate-depth-255 -OPT_FLAGS = -g -Os - -PYTHON_ROOT = /usr/lib/python2.5/config -PYTHON_INC = -I/usr/include/python2.5 -PYTHON_DEF = -DBOOST_PYTHON_DYNAMIC_LIB -DBOOST_PYTHON_SOURCE - -WRAPPER_CFLAGS = $(shell botan-config --cflags) -SHARED_CFLAGS = $(LANG_FLAGS) $(OPT_FLAGS) $(PYTHON_INC) - -BOOST_CFLAGS = $(PYTHON_DEF) $(SHARED_CFLAGS) - -WRAP_SRC = $(wildcard src/*.cpp) -WRAP_OBJS = $(patsubst src/%.cpp,build/%.o,$(WRAP_SRC)) - -all: botan/_botan.so - -build/%.o: src/%.cpp - $(CXX) -Isrc/ $(SHARED_CFLAGS) $(WRAPPER_CFLAGS) -c $< -o $@ - -botan/_botan.so: $(WRAP_OBJS) - $(CXX) -shared -o $@ $(shell botan-config --libs) -L$(PYTHON_ROOT) $(WRAP_OBJS) -lboost_python -Wl,-rpath-link,. -Wl,-soname,$@ - -clean: - rm -f $(WRAP_OBJS) botan/_botan.so botan/*.pyc diff --git a/wrappers/boost-python/botan/__init__.py b/wrappers/boost-python/botan/__init__.py deleted file mode 100644 index 9e136ed39..000000000 --- a/wrappers/boost-python/botan/__init__.py +++ /dev/null @@ -1,27 +0,0 @@ -from _botan import * - -# Initialize the library when the module is imported -init = LibraryInitializer() - -class SymmetricKey(OctetString): - pass - -class InitializationVector(OctetString): - pass - -def Filter(name, key = None, iv = None, dir = None): - if key != None and iv != None and dir != None: - return make_filter(name, key, iv, dir) - elif key != None and dir != None: - return make_filter(name, key, dir) - elif key != None: - return make_filter(name, key) - else: - return make_filter(name) - -def Pipe(*filters): - pipe = PipeObj() - for filter in filters: - if filter: - pipe.append(filter) - return pipe diff --git a/wrappers/boost-python/src/block.cpp b/wrappers/boost-python/src/block.cpp deleted file mode 100644 index 185b88811..000000000 --- a/wrappers/boost-python/src/block.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/************************************************* -* Boost.Python module definition * -* (C) 1999-2007 Jack Lloyd * -*************************************************/ - -#include <botan/botan.h> -using namespace Botan; - -#include "python_botan.h" - -class Py_BlockCipher : public BlockCipher - { - public: - virtual std::string enc_str(const std::string&) const = 0; - virtual std::string dec_str(const std::string&) const = 0; - virtual void set_key_obj(const OctetString&) = 0; - - void clear() throw() {} - - void enc(const byte in[], byte out[]) const - { - string2binary( - enc_str(make_string(in, BLOCK_SIZE)), - out, BLOCK_SIZE); - } - - void dec(const byte in[], byte out[]) const - { - string2binary( - dec_str(make_string(in, BLOCK_SIZE)), - out, BLOCK_SIZE); - } - - void key(const byte key[], u32bit len) - { - set_key_obj(OctetString(key, len)); - } - - Py_BlockCipher(u32bit bs, u32bit kmin, u32bit kmax, u32bit kmod) : - BlockCipher(bs, kmin, kmax, kmod) - { - } - }; - -std::string encrypt_string(BlockCipher* cipher, const std::string& in) - { - if(in.size() != cipher->BLOCK_SIZE) - throw Bad_Size(in.size(), cipher->BLOCK_SIZE); - - SecureVector<byte> out(cipher->BLOCK_SIZE); - cipher->encrypt((const byte*)in.data(), out); - return make_string(out); - } - -std::string decrypt_string(BlockCipher* cipher, const std::string& in) - { - if(in.size() != cipher->BLOCK_SIZE) - throw Bad_Size(in.size(), cipher->BLOCK_SIZE); - - SecureVector<byte> out(cipher->BLOCK_SIZE); - cipher->decrypt((const byte*)in.data(), out); - return make_string(out); - } - -class Wrapped_Block_Cipher : public BlockCipher - { - public: - void clear() throw() { cipher->clear(); } - - void enc(const byte in[], byte out[]) const { cipher->encrypt(in, out); } - void dec(const byte in[], byte out[]) const { cipher->decrypt(in, out); } - void key(const byte key[], u32bit len) { cipher->set_key(key, len); } - std::string name() const { return cipher->name(); } - BlockCipher* clone() const { return cipher->clone(); } - - Wrapped_Block_Cipher(python::object py_obj, BlockCipher* c) : - BlockCipher(c->BLOCK_SIZE, c->MINIMUM_KEYLENGTH, - c->MAXIMUM_KEYLENGTH, c->KEYLENGTH_MULTIPLE), - obj(py_obj), cipher(c) {} - private: - python::object obj; - BlockCipher* cipher; - }; - -class Py_BlockCipher_Wrapper : public Py_BlockCipher, - public python::wrapper<Py_BlockCipher> - { - public: - BlockCipher* clone() const - { - python::object self = get_owner(this); - python::object py_clone = self.attr("__class__")(); - BlockCipher* bc = python::extract<BlockCipher*>(py_clone); - return new Wrapped_Block_Cipher(py_clone, bc); - } - - void clear() throw() - { - this->get_override("clear")(); - } - - std::string name() const - { - return this->get_override("name")(); - } - - std::string enc_str(const std::string& in) const - { - return this->get_override("encrypt")(in); - } - - std::string dec_str(const std::string& in) const - { - return this->get_override("decrypt")(in); - } - - void set_key_obj(const OctetString& key) - { - this->get_override("set_key")(key); - } - - Py_BlockCipher_Wrapper(u32bit bs, u32bit kmin, - u32bit kmax, u32bit kmod) : - Py_BlockCipher(bs, kmin, kmax, kmod) {} - }; - -void export_block_ciphers() - { - void (BlockCipher::*set_key_ptr)(const OctetString&) = - &BlockCipher::set_key; - - python::class_<BlockCipher, boost::noncopyable> - ("BlockCipher", python::no_init) - .def("__init__", python::make_constructor(get_block_cipher)) - .def_readonly("block_size", &BlockCipher::BLOCK_SIZE) - .def_readonly("keylength_min", &BlockCipher::MINIMUM_KEYLENGTH) - .def_readonly("keylength_max", &BlockCipher::MAXIMUM_KEYLENGTH) - .def_readonly("keylength_mod", &BlockCipher::KEYLENGTH_MULTIPLE) - .def("valid_keylength", &BlockCipher::valid_keylength) - .def("name", &BlockCipher::name) - .def("set_key", set_key_ptr) - .def("encrypt", encrypt_string) - .def("decrypt", decrypt_string); - - python::class_<Py_BlockCipher_Wrapper, python::bases<BlockCipher>, - boost::noncopyable> - ("BlockCipherImpl", python::init<u32bit, u32bit, u32bit, u32bit>()) - .def("name", python::pure_virtual(&Py_BlockCipher::name)) - .def("encrypt", python::pure_virtual(&Py_BlockCipher::enc_str)) - .def("decrypt", python::pure_virtual(&Py_BlockCipher::dec_str)) - .def("set_key", python::pure_virtual(&Py_BlockCipher::set_key_obj)); - } diff --git a/wrappers/boost-python/src/core.cpp b/wrappers/boost-python/src/core.cpp deleted file mode 100644 index 7ef2a9970..000000000 --- a/wrappers/boost-python/src/core.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/************************************************* -* Boost.Python module definition * -* (C) 1999-2007 Jack Lloyd * -*************************************************/ - -#include <botan/botan.h> -using namespace Botan; - -#include <boost/python.hpp> -namespace python = boost::python; - -#include "python_botan.h" - -class Python_RandomNumberGenerator - { - public: - Python_RandomNumberGenerator() - { rng = RandomNumberGenerator::make_rng(); } - ~Python_RandomNumberGenerator() { delete rng; } - - std::string name() const { return rng->name(); } - - void reseed() { rng->reseed(); } - - int gen_random_byte() { return rng->next_byte(); } - - std::string gen_random(int n) - { - std::string s(n, 0); - rng->randomize(reinterpret_cast<byte*>(&s[0]), n); - return s; - } - - void add_entropy(const std::string& in) - { rng->add_entropy(reinterpret_cast<const byte*>(in.c_str()), in.length()); } - - private: - RandomNumberGenerator* rng; - }; - -BOOST_PYTHON_MODULE(_botan) - { - python::class_<LibraryInitializer>("LibraryInitializer") - .def(python::init< python::optional<std::string> >()); - - python::class_<Python_RandomNumberGenerator>("RandomNumberGenerator") - .def(python::init<>()) - .def("__str__", &Python_RandomNumberGenerator::name) - .def("name", &Python_RandomNumberGenerator::name) - .def("reseed", &Python_RandomNumberGenerator::reseed) - .def("add_entropy", &Python_RandomNumberGenerator::add_entropy) - .def("gen_random_byte", &Python_RandomNumberGenerator::gen_random_byte) - .def("gen_random", &Python_RandomNumberGenerator::gen_random); - - python::class_<OctetString>("OctetString") - .def(python::init< python::optional<std::string> >()) - //.def(python::init< u32bit >()) - .def("__str__", &OctetString::as_string) - .def("__len__", &OctetString::length); - - python::enum_<Cipher_Dir>("cipher_dir") - .value("encryption", ENCRYPTION) - .value("decryption", DECRYPTION); - - export_block_ciphers(); - export_stream_ciphers(); - export_hash_functions(); - export_macs(); - - export_filters(); - export_pk(); - export_x509(); - } diff --git a/wrappers/boost-python/src/hash.cpp b/wrappers/boost-python/src/hash.cpp deleted file mode 100644 index 6ef198087..000000000 --- a/wrappers/boost-python/src/hash.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/************************************************* -* Boost.Python module definition * -* (C) 1999-2007 Jack Lloyd * -*************************************************/ - -#include <botan/botan.h> -using namespace Botan; - -#include "python_botan.h" - -class Py_HashFunction : public HashFunction - { - public: - virtual void hash_str(const std::string&) = 0; - virtual std::string final_str() = 0; - - void clear() throw() {} - - void add_data(const byte input[], u32bit length) - { - hash_str(make_string(input, length)); - } - - void final_result(byte output[]) - { - string2binary(final_str(), output, OUTPUT_LENGTH); - } - - Py_HashFunction(u32bit digest_size, u32bit block_size) : - HashFunction(digest_size, block_size) {} - }; - -class Wrapped_HashFunction : public HashFunction - { - public: - void add_data(const byte in[], u32bit len) { hash->update(in, len); } - void final_result(byte out[]) { hash->final(out); } - - void clear() throw() {} - - std::string name() const { return hash->name(); } - HashFunction* clone() const { return hash->clone(); } - - Wrapped_HashFunction(python::object py_obj, HashFunction* h) : - HashFunction(h->OUTPUT_LENGTH, h->HASH_BLOCK_SIZE), - obj(py_obj), hash(h) {} - private: - python::object obj; - HashFunction* hash; - }; - -class Py_HashFunction_Wrapper : public Py_HashFunction, - public python::wrapper<Py_HashFunction> - { - public: - HashFunction* clone() const - { - python::object self = get_owner(this); - python::object py_clone = self.attr("__class__")(); - HashFunction* hf = python::extract<HashFunction*>(py_clone); - return new Wrapped_HashFunction(py_clone, hf); - } - - std::string name() const - { - return this->get_override("name")(); - } - - void hash_str(const std::string& in) - { - this->get_override("update")(in); - } - - std::string final_str() - { - return this->get_override("final")(); - } - - Py_HashFunction_Wrapper(u32bit digest_size, u32bit block_size) : - Py_HashFunction(digest_size, block_size) {} - }; - -std::string final_str(HashFunction* hash) - { - SecureVector<byte> digest = hash->final(); - return std::string((const char*)digest.begin(), digest.size()); - } - -void export_hash_functions() - { - void (HashFunction::*update_str)(const std::string&) = - &HashFunction::update; - - python::class_<HashFunction, boost::noncopyable> - ("HashFunction", python::no_init) - .def("__init__", python::make_constructor(get_hash)) - .def_readonly("digest_size", &HashFunction::OUTPUT_LENGTH) - .def("name", &HashFunction::name) - .def("update", update_str) - .def("final", final_str); - - python::class_<Py_HashFunction_Wrapper, python::bases<HashFunction>, - boost::noncopyable> - ("HashFunctionImpl", python::init<u32bit, u32bit>()) - .def("name", python::pure_virtual(&Py_HashFunction::name)) - .def("update", python::pure_virtual(&Py_HashFunction::hash_str)) - .def("final", python::pure_virtual(&Py_HashFunction::final_str)); - } diff --git a/wrappers/boost-python/src/macs.cpp b/wrappers/boost-python/src/macs.cpp deleted file mode 100644 index 54a55afe2..000000000 --- a/wrappers/boost-python/src/macs.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/************************************************* -* Boost.Python module definition * -* (C) 1999-2007 Jack Lloyd * -*************************************************/ - -#include <botan/botan.h> -using namespace Botan; - -#include <boost/python.hpp> -namespace python = boost::python; - -class Py_MAC - { - public: - u32bit output_length() const { return mac->OUTPUT_LENGTH; } - u32bit keylength_min() const { return mac->MINIMUM_KEYLENGTH; } - u32bit keylength_max() const { return mac->MAXIMUM_KEYLENGTH; } - u32bit keylength_mod() const { return mac->KEYLENGTH_MULTIPLE; } - std::string name() const { return mac->name(); } - void clear() throw() { mac->clear(); } - - void set_key(const OctetString& key) { mac->set_key(key); } - - bool valid_keylength(u32bit kl) const - { - return mac->valid_keylength(kl); - } - - void update(const std::string& in) { mac->update(in); } - - std::string final() - { - SecureVector<byte> result = mac->final(); - return std::string((const char*)result.begin(), result.size()); - } - - Py_MAC(const std::string& name) - { - mac = get_mac(name); - } - ~Py_MAC() { delete mac; } - private: - MessageAuthenticationCode* mac; - }; - -void export_macs() - { - python::class_<Py_MAC>("MAC", python::init<std::string>()) - .add_property("output_length", &Py_MAC::output_length) - .add_property("keylength_min", &Py_MAC::keylength_min) - .add_property("keylength_max", &Py_MAC::keylength_max) - .add_property("keylength_mod", &Py_MAC::keylength_mod) - .add_property("name", &Py_MAC::name) - .def("valid_keylength", &Py_MAC::valid_keylength) - .def("set_key", &Py_MAC::set_key) - .def("clear", &Py_MAC::clear) - .def("update", &Py_MAC::update) - .def("final", &Py_MAC::final); - } diff --git a/wrappers/boost-python/src/pk.cpp b/wrappers/boost-python/src/pk.cpp deleted file mode 100644 index 72d3294b8..000000000 --- a/wrappers/boost-python/src/pk.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/************************************************* -* Boost.Python module definition * -* (C) 1999-2007 Jack Lloyd * -*************************************************/ - -#include <botan/rsa.h> -#include <botan/dsa.h> -#include <botan/dh.h> -#include <botan/look_pk.h> -using namespace Botan; - -#include <boost/python.hpp> -namespace python = boost::python; - -std::string encode_pub(const Public_Key* key, - const std::string& type) - { - if(type == "DER") - { - Pipe pipe; - pipe.start_msg(); - X509::encode(*key, pipe, RAW_BER); - pipe.end_msg(); - return pipe.read_all_as_string(); - } - else if(type == "PEM") - return X509::PEM_encode(*key); - else - throw Encoding_Error("Unknown key encoding method " + type); - } - -std::string encode_priv(const Private_Key* key, - const std::string& type) - { - if(type == "DER") - { - Pipe pipe; - PKCS8::encode(*key, pipe, RAW_BER); - return pipe.read_all_as_string(); - } - else if(type == "PEM") - return PKCS8::PEM_encode(*key); - else - throw Encoding_Error("Unknown key encoding method " + type); - } - -/* -Private_Key* load_priv(const std::string& file, const std::string& pass) - { - return PKCS8::load_key(file, pass); - } - -Public_Key* load_public(const std::string& file) - { - return X509::load_key(file); - } -*/ - -/* -std::string encrypt_string(const PK_Encryptor* enc, const std::string& in) - { - SecureVector<byte> cipher = enc->encrypt((const byte*)in.data(), in.length()); - return std::string((const char*)cipher.begin(), cipher.size()); - } - -std::string decrypt_string(const PK_Decryptor* dec, const std::string& in) - { - SecureVector<byte> plain = dec->decrypt((const byte*)in.data(), in.length()); - return std::string((const char*)plain.begin(), plain.size()); - } -*/ - -void export_pk() - { - /* - python::def("private_key", load_priv, - python::return_value_policy<python::manage_new_object>()); - python::def("public_key", load_public, - python::return_value_policy<python::manage_new_object>()); - */ - - python::class_<Public_Key, boost::noncopyable> - ("Public_Key", python::no_init) - .add_property("name", &Public_Key::algo_name) - .add_property("max_input_bits", &Public_Key::max_input_bits) - .def("public_key", encode_pub); - - python::class_<PK_Encrypting_Key, python::bases<Public_Key>, boost::noncopyable> - ("PK_Encrypting_Key", python::no_init); - - python::class_<Private_Key, python::bases<Public_Key>, boost::noncopyable> - ("Private_Key", python::no_init) - .def("private_key", encode_priv); - - python::class_<PK_Decrypting_Key, python::bases<Private_Key>, boost::noncopyable> - ("PK_Decrypting_Key", python::no_init); - - python::class_<RSA_PublicKey, python::bases<PK_Encrypting_Key> > - ("RSA_PublicKey", python::no_init); - - python::class_<DSA_PublicKey, python::bases<Public_Key> > - ("DSA_PublicKey", python::no_init); - - /* - python::class_<RSA_PrivateKey, python::bases<RSA_PublicKey, PK_Decrypting_Key> > - ("RSA_PrivateKey", python::init<u32bit>()); - */ - - /* - python::class_<PK_Encryptor, boost::noncopyable> - ("PK_Encryptor", python::no_init) - .def("__init__", - python::make_constructor(get_pk_encryptor, - python::with_custodian_and_ward_postcall<0, 1>())) - .def("max_input", &PK_Encryptor::maximum_input_size) - .def("encrypt", encrypt_string); - */ - - /* - python::class_<PK_Decryptor, boost::noncopyable> - ("PK_Decryptor", python::no_init) - .def("__init__", python::make_constructor(get_pk_decryptor)) - .def("decrypt", decrypt_string); - */ - } diff --git a/wrappers/boost-python/src/stream.cpp b/wrappers/boost-python/src/stream.cpp deleted file mode 100644 index f94bd7fd5..000000000 --- a/wrappers/boost-python/src/stream.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/************************************************* -* Boost.Python module definition * -* (C) 1999-2007 Jack Lloyd * -*************************************************/ - -#include <botan/botan.h> -using namespace Botan; - -#include "python_botan.h" - -class Py_StreamCipher - { - public: - u32bit keylength_min() const { return cipher->MINIMUM_KEYLENGTH; } - u32bit keylength_max() const { return cipher->MAXIMUM_KEYLENGTH; } - u32bit keylength_mod() const { return cipher->KEYLENGTH_MULTIPLE; } - - void set_key(const OctetString& key) { cipher->set_key(key); } - bool valid_keylength(u32bit kl) const - { - return cipher->valid_keylength(kl); - } - - std::string name() const { return cipher->name(); } - void clear() throw() { cipher->clear(); } - - std::string crypt(const std::string& in) const - { - SecureVector<byte> out(in.size()); - cipher->encrypt((const byte*)in.data(), out.begin(), in.size()); - return std::string((const char*)out.begin(), out.size()); - } - - Py_StreamCipher(const std::string& name) - { - cipher = get_stream_cipher(name); - } - ~Py_StreamCipher() { delete cipher; } - private: - StreamCipher* cipher; - }; - -void export_stream_ciphers() - { - python::class_<Py_StreamCipher>("StreamCipher", python::init<std::string>()) - .add_property("keylength_min", &Py_StreamCipher::keylength_min) - .add_property("keylength_max", &Py_StreamCipher::keylength_max) - .add_property("keylength_mod", &Py_StreamCipher::keylength_mod) - .add_property("name", &Py_StreamCipher::name) - .def("clear", &Py_StreamCipher::clear) - .def("valid_keylength", &Py_StreamCipher::valid_keylength) - .def("set_key", &Py_StreamCipher::set_key) - .def("crypt", &Py_StreamCipher::crypt); - } diff --git a/wrappers/swig/Makefile b/wrappers/swig/Makefile deleted file mode 100644 index ff55c793c..000000000 --- a/wrappers/swig/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -LANG=-python -LANG_INC=/usr/include/python2.3 - -CFLAGS=$(shell botan-config --cflags) -LIBS=$(shell botan-config --libs) - -CXX = g++ -g -SWIG = swig -Wall - -all: _botan.so - -_botan.so: base.o pipe.o filter.o botan_wrap.o - $(CXX) -shared $^ $(LIBS) -o $@ - -botan_wrap.cpp: botan.swg base.h - $(SWIG) $(LANG) -c++ -o $@ $< - -botan_wrap.o: botan_wrap.cpp - $(CXX) $(CFLAGS) -I$(LANG_INC) -c $^ -o $@ - -base.o: base.cpp base.h - $(CXX) $(CFLAGS) -c $< -o $@ - -pipe.o: pipe.cpp base.h - $(CXX) $(CFLAGS) -c $< -o $@ - -filter.o: filter.cpp base.h - $(CXX) $(CFLAGS) -c $< -o $@ - -clean: - rm -f *.o _botan.so botan.py botan.pyc - rm -f *_wrap.o *_wrap.cpp diff --git a/wrappers/swig/base.cpp b/wrappers/swig/base.cpp deleted file mode 100644 index 448b3d48e..000000000 --- a/wrappers/swig/base.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/************************************************* -* SWIG Interface for basic Botan interface * -* (C) 1999-2003 Jack Lloyd * -*************************************************/ - -#include "base.h" -#include <botan/init.h> - -#include <stdio.h> - -/************************************************* -* Initialize the library * -*************************************************/ -LibraryInitializer::LibraryInitializer(const char* args) - { - Botan::Init::initialize(args); - } - -/************************************************* -* Shut down the library * -*************************************************/ -LibraryInitializer::~LibraryInitializer() - { - Botan::Init::deinitialize(); - } - -/************************************************* -* Create a SymmetricKey * -*************************************************/ -SymmetricKey::SymmetricKey(const std::string& str) - { - key = new Botan::SymmetricKey(str); - printf("STR CON: %p %p\n", this, key); - } - -/************************************************* -* Create a SymmetricKey * -*************************************************/ -SymmetricKey::SymmetricKey(u32bit n) - { - key = new Botan::SymmetricKey(n); - printf("N CON: %p %p\n", this, key); - } - -/************************************************* -* Destroy a SymmetricKey * -*************************************************/ -SymmetricKey::~SymmetricKey() - { - printf("DESTR: %p %p\n", this, key); - delete key; - key = 0; - //printf("deleted\n"); - } - -/************************************************* -* Create an InitializationVector * -*************************************************/ -InitializationVector::InitializationVector(const std::string& str) : iv(str) - { - } diff --git a/wrappers/swig/base.h b/wrappers/swig/base.h deleted file mode 100644 index 341a5c35a..000000000 --- a/wrappers/swig/base.h +++ /dev/null @@ -1,102 +0,0 @@ -/************************************************* -* SWIG Interface for Botan * -* (C) 1999-2003 Jack Lloyd * -*************************************************/ - -#ifndef BOTAN_WRAP_BASE_H__ -#define BOTAN_WRAP_BASE_H__ - -#include <botan/pipe.h> - -#if !defined(SWIG) - #define OUTPUT - #define INOUT -#endif - -/************************************************* -* Typedefs * -*************************************************/ -typedef unsigned char byte; -typedef unsigned int u32bit; - -/************************************************* -* Library Initalization/Shutdown Object * -*************************************************/ -class LibraryInitializer - { - public: - LibraryInitializer(const char*); - ~LibraryInitializer(); - }; - -/************************************************* -* Symmetric Key Object * -*************************************************/ -class SymmetricKey - { - public: - std::string as_string() const { return key->as_string(); } - u32bit length() const { return key->length(); } - SymmetricKey(u32bit = 0); - SymmetricKey(const std::string&); - ~SymmetricKey(); - private: - Botan::SymmetricKey* key; - }; - -/************************************************* -* Initialization Vector Object * -*************************************************/ -class InitializationVector - { - public: - std::string as_string() const { return iv.as_string(); } - u32bit length() const { return iv.length(); } - InitializationVector(u32bit n = 0) { iv.change(n); } - InitializationVector(const std::string&); - private: - Botan::InitializationVector iv; - }; - -/************************************************* -* Filter Object * -*************************************************/ -class Filter - { - public: - Filter(const char*); - //Filter(const char*, const SymmetricKey&); - //Filter(const char*, const SymmetricKey&, const InitializationVector&); - ~Filter(); - private: - friend class Pipe; - Botan::Filter* filter; - bool pipe_owns; - }; - -/************************************************* -* Pipe Object * -*************************************************/ -class Pipe - { - public: - static const u32bit DEFAULT_MESSAGE = 0xFFFFFFFF; - - void write_file(const char*); - void write_string(const char*); - - u32bit read(byte*, u32bit, u32bit = DEFAULT_MESSAGE); - std::string read_all_as_string(u32bit = DEFAULT_MESSAGE); - - u32bit remaining(u32bit = DEFAULT_MESSAGE); - - void start_msg(); - void end_msg(); - - Pipe(Filter* = 0, Filter* = 0, Filter* = 0, Filter* = 0); - ~Pipe(); - private: - Botan::Pipe* pipe; - }; - -#endif diff --git a/wrappers/swig/botan.swg b/wrappers/swig/botan.swg deleted file mode 100644 index 9088f4272..000000000 --- a/wrappers/swig/botan.swg +++ /dev/null @@ -1,26 +0,0 @@ -/************************************************* -* SWIG Interface for Botan * -*************************************************/ -%module botan - -%include "typemaps.i" -%include "std_string.i" -%include "exception.i" -%include "constraints.i" -%include "carrays.i" - -%{ -#include "base.h" -%} - -%exception { - try { - $action - } - catch(std::exception& e) - { - SWIG_exception(SWIG_RuntimeError, e.what()); - } -} - -%include "base.h" diff --git a/wrappers/swig/doit.py b/wrappers/swig/doit.py deleted file mode 100755 index 98bc97087..000000000 --- a/wrappers/swig/doit.py +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/python2 - -import botan - -def hash_it(hash, input): - f1 = botan.Filter("MD5") - f2 = botan.Filter("Hex_Encoder") - pipe = botan.Pipe(f1, f2) - - pipe.start_msg() - pipe.write_string(input) - pipe.end_msg() - - print pipe.remaining() - - out = pipe.read(0) - - - - -def main: - init = botan.LibraryInitializer - - print hash_it("MD5", "foo") - - - key1 = botan.SymmetricKey("ABCD") - print key1.as_string() - key2 = botan.SymmetricKey(16) - print key2.as_string() - - iv1 = botan.InitializationVector(8) - print iv1.as_string() - - - f3 = pipe.read(pipe.remaining()) - - size = pipe.remaining() - out = botan.byte_array(size) - pipe.read(out.cast,size) - - for i in range (0,size): - print "%02X" % out[i] - - print pipe.read_all_as_string() - -if __name__ == "__main__": - sys.exit(main()) - diff --git a/wrappers/swig/filter.cpp b/wrappers/swig/filter.cpp deleted file mode 100644 index 53ff0e6a3..000000000 --- a/wrappers/swig/filter.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/************************************************* -* SWIG Interface for Filter Retrieval * -* (C) 1999-2003 Jack Lloyd * -*************************************************/ - -#include "base.h" -#include <botan/lookup.h> -#include <botan/filters.h> - -/************************************************* -* Filter Creation * -*************************************************/ -Filter::Filter(const char* filt_string) - { - filter = 0; - pipe_owns = false; - - /* - Fixme: This is all so totally wrong. It needs to have full argument - processing for everything, all that kind of crap. - */ - const std::string filt_name = filt_string; - - if(Botan::have_hash(filt_name)) - filter = new Botan::Hash_Filter(filt_name); - else if(filt_name == "Hex_Encoder") - filter = new Botan::Hex_Encoder; - } - -/************************************************* -* Filter Destruction * -*************************************************/ -Filter::~Filter() - { - /* - if(!pipe_owns) - delete filter; - */ - } diff --git a/wrappers/swig/pipe.cpp b/wrappers/swig/pipe.cpp deleted file mode 100644 index 0f35d5a43..000000000 --- a/wrappers/swig/pipe.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/************************************************* -* SWIG Interface for Botan Pipe API * -* (C) 1999-2003 Jack Lloyd * -*************************************************/ - -#include "base.h" -#include <botan/pipe.h> - -#include <stdio.h> - -/************************************************* -* Write the contents of a file into a Pipe * -*************************************************/ -void Pipe::write_file(const char* filename) - { - Botan::DataSource_Stream in(filename); - pipe->write(in); - } - -/************************************************* -* Write the contents of a string into a Pipe * -*************************************************/ -void Pipe::write_string(const char* string) - { - pipe->write(string); - } - -/************************************************* -* Read the contents of a Pipe into a buffer * -*************************************************/ -u32bit Pipe::read(byte* buf, u32bit length, u32bit msg) - { - printf("read %p %d\n", buf, length); - return 0; - //return pipe->read(buf, length, msg); - } - -/************************************************* -* Read the contents of a Pipe as a string * -*************************************************/ -std::string Pipe::read_all_as_string(u32bit msg) - { - return pipe->read_all_as_string(msg); - } - -/************************************************* -* Find out how much stuff the Pipe still has * -*************************************************/ -u32bit Pipe::remaining(u32bit msg) - { - return pipe->remaining(); - } - -/************************************************* -* Start a new message * -*************************************************/ -void Pipe::start_msg() - { - pipe->start_msg(); - } - -/************************************************* -* End the current msessage * -*************************************************/ -void Pipe::end_msg() - { - pipe->end_msg(); - } - -/************************************************* -* Create a new Pipe * -*************************************************/ -Pipe::Pipe(Filter* f1, Filter* f2, Filter* f3, Filter* f4) - { - pipe = new Botan::Pipe(); - - if(f1) { pipe->append(f1->filter); f1->pipe_owns = true; } - if(f2) { pipe->append(f2->filter); f2->pipe_owns = true; } - if(f3) { pipe->append(f3->filter); f3->pipe_owns = true; } - if(f4) { pipe->append(f4->filter); f4->pipe_owns = true; } - } - -/************************************************* -* Destroy this Pipe * -*************************************************/ -Pipe::~Pipe() - { - delete pipe; - } diff --git a/wrappers/swig/pk.swg b/wrappers/swig/pk.swg deleted file mode 100644 index 8e03cf120..000000000 --- a/wrappers/swig/pk.swg +++ /dev/null @@ -1,8 +0,0 @@ -%module botan - -%{ -#undef ANY -#include "botan/pubkey.h" -%} - -%include "botan/pubkey.h" diff --git a/wrappers/swig/readme.txt b/wrappers/swig/readme.txt deleted file mode 100644 index a9965d914..000000000 --- a/wrappers/swig/readme.txt +++ /dev/null @@ -1,34 +0,0 @@ -This is the beginning of an attempt to SWIG-ify Botan so it can be accessed by -other languages. You should use the latest SWIG 1.3 release (I am currently -using SWIG 1.3.19). Currently I am only testing this code with Python 2.2.1, -since that is the language I am mainly interested in at this point. Feel free -to send me patches so this is usable with Perl or whatever. - -I'm not attempting to make everything in Botan usable from a script - -basically, I just want the parts that *I* want to use. Most things are not -supported yet, and there are lots of bugs in the stuff that does exist. If -there is something in particular that you would like to be able to use from a -script, let me know (patches are good, too). - -Todo: - * Why does it seg fault if we don't create a LibraryInitializer. It should - throw an exception, like it does in C++. Maybe have it init Botan when the - module is loaded? That seems a lot cleaner/nicer, but I don't know how to - do it yet. - * Lots of problems with exceptions - * Use constraints to prevent bad args when possible - * Pipe/Filter - - Better argument processing for all filters - - Support for ciphers, MACs, etc - - Chain + Fork - - Support for append/prepend/pop/reset in Pipe? - * Public Key Crypto - - RSA - - DSA - - DH - - Generic X.509 and PKCS #8 stuff - * PKI - - X.509 certs + CRLs - - PKCS #10 requests - - X.509 stores - - X.509 CA diff --git a/wrappers/swig/tests/block.py b/wrappers/swig/tests/block.py deleted file mode 100644 index 593937c81..000000000 --- a/wrappers/swig/tests/block.py +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/python - -import botan, base64 - -class MyCipher(botan.BlockCipher): - def __init__(self): - botan.BlockCipher.__init__(self, 16, 16, 32, 8) - def encrypt(self, val): - print "encrypt", val - return val.swapcase() - def decrypt(self, val): - print "decrypt", val - return val.swapcase() - def set_key(self, key): - print "set_key", key - def clone(self): - print "cloning" - return MyCipher() - def name(self): - print "naming" - return "MyCipher" - -cipher = botan.BlockCipher("AES-128") - -print cipher.block_size -print cipher.keylength_min -print cipher.keylength_max -print cipher.keylength_mod -print cipher.name() - -for kl in range(1, 128): - if cipher.valid_keylength(kl): - print "1", - else: - print "0", -print -key = botan.SymmetricKey(16) - -cipher.set_key(key) -ciphertext = cipher.encrypt("ABCDEFGH12345678") -print base64.b16encode(ciphertext) - -cipher2 = cipher.clone() -cipher2.set_key(key) - -plaintext = cipher2.decrypt(ciphertext) -print plaintext - -botan.get_info(cipher) - -mycipher = MyCipher() -botan.get_info(mycipher) diff --git a/wrappers/swig/tests/block2.py b/wrappers/swig/tests/block2.py deleted file mode 100644 index 5faccaf9a..000000000 --- a/wrappers/swig/tests/block2.py +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/python - -import botan, base64 - -class MyCipher(botan.BlockCipherImpl): - def __init__(self): - botan.BlockCipherImpl.__init__(self, 8, 8, 16, 1) - - def name(self): - return "MyCipher" - - def encrypt(self, input): - return input.swapcase() - - def decrypt(self, input): - return input.swapcase() - - def set_key(self, key): - print "Got key",key - -def test(cipher): - print - print cipher - print "Testing", cipher.name() - print cipher.block_size - print cipher.keylength_min, cipher.keylength_max, cipher.keylength_mod - for i in range(1, 64): - if cipher.valid_keylength(i): - print "1", - else: - print "0", - print - cipher.set_key(botan.SymmetricKey(16)) - ciphertext = cipher.encrypt("aBcDeFgH" * (cipher.block_size / 8)) - print repr(ciphertext) - print cipher.decrypt(ciphertext) - -def main(): - test(botan.BlockCipher("Blowfish")) - test(MyCipher()) - test(botan.BlockCipher("AES")) - -if __name__ == "__main__": - main() diff --git a/wrappers/swig/tests/encrypt.py b/wrappers/swig/tests/encrypt.py deleted file mode 100644 index 9896777d4..000000000 --- a/wrappers/swig/tests/encrypt.py +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/python - -import sys, botan - -def encrypt(input): - cipher_key = botan.SymmetricKey("AABB") - print cipher_key.length - cipher_key = botan.SymmetricKey("AABBCCDD") - print cipher_key.length - - cipher = botan.Filter("ARC4", key = cipher_key) - - pipe = botan.Pipe(cipher, botan.Filter("Hex_Encoder")) - - pipe.start_msg() - pipe.write(input) - pipe.end_msg() - - str = pipe.read_all() - print str - return str - -def decrypt(input): - pipe = botan.Pipe(botan.Filter("Hex_Decoder"), - botan.Filter("ARC4", - key = botan.SymmetricKey("AABBCCDD"))) - - pipe.process_msg(input) - return pipe.read_all() - -def main(): - ciphertext = encrypt("hi chappy") - print ciphertext - print decrypt(ciphertext) - -if __name__ == "__main__": - sys.exit(main()) diff --git a/wrappers/swig/tests/filter.py b/wrappers/swig/tests/filter.py deleted file mode 100644 index 2b65d9ff2..000000000 --- a/wrappers/swig/tests/filter.py +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/python - -import sys, botan - -class MyFilter(botan.FilterObj): - def write(self, input): - print "MyFilter::write",input - self.send(input) - def start_msg(self): - print "MyFilter::start_msg" - def end_msg(self): - print "MyFilter::end_msg" - def __del__(self): - print "~MyFilter" - -def main(): - filter = MyFilter() - - pipe = botan.Pipe(botan.Filter("Hex_Encoder"), filter, - botan.Filter("Hex_Decoder")) - pipe.start_msg() - pipe.write("hi chappy") - pipe.end_msg() - print pipe.read_all() - -if __name__ == "__main__": - sys.exit(main()) diff --git a/wrappers/swig/tests/hash.py b/wrappers/swig/tests/hash.py deleted file mode 100644 index 930b8c81a..000000000 --- a/wrappers/swig/tests/hash.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/python - -import botan, base64, md5 - -class PyMD5(botan.HashFunctionImpl): - def name(self): - return "PyMD5" - def update(self, input): - self.md5.update(input) - def final(self): - output = self.md5.digest() - self.md5 = md5.new() - return output - def __init__(self): - botan.HashFunctionImpl.__init__(self, 16, 64) - self.md5 = md5.new() - -hash = botan.HashFunction("SHA-256") - -print hash.name() -print hash.digest_size - -hash.update("hi") -hash.update(" ") -hash.update("chappy") -print base64.b16encode(hash.final()) - -hash2 = PyMD5() -hash2.update("hi chappy") -print base64.b16encode(hash2.final()) diff --git a/wrappers/swig/tests/mac.py b/wrappers/swig/tests/mac.py deleted file mode 100644 index 6110b6102..000000000 --- a/wrappers/swig/tests/mac.py +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/python - -import botan, base64 - -mac = botan.MAC("HMAC(SHA-512)") - -print mac.name -print mac.output_length - -mac.set_key(botan.SymmetricKey("abcd")) -mac.update("hi chappy") -print base64.b16encode(mac.final()) diff --git a/wrappers/swig/tests/pubkey.py b/wrappers/swig/tests/pubkey.py deleted file mode 100644 index 456c52069..000000000 --- a/wrappers/swig/tests/pubkey.py +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/python - -import botan - -key = botan.X509_PublicKey("rsapub.pem") -print key -print key.key_id() -print key.max_input_bits -print key.algo -print key.oid diff --git a/wrappers/swig/tests/stream.py b/wrappers/swig/tests/stream.py deleted file mode 100644 index 59d3ffa16..000000000 --- a/wrappers/swig/tests/stream.py +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/python - -import botan, base64 - -cipher = botan.StreamCipher("ARC4") - -print cipher.name - -key = botan.SymmetricKey(16) - -cipher.set_key(key) -ciphertext = cipher.crypt("hi chappy") - -cipher.set_key(key) -plaintext = cipher.crypt(ciphertext) - -print plaintext diff --git a/wrappers/swig/x509.swg b/wrappers/swig/x509.swg deleted file mode 100644 index 736d3a385..000000000 --- a/wrappers/swig/x509.swg +++ /dev/null @@ -1,9 +0,0 @@ -%module botan - -class X509_Certificate - { - public: - - - private: - }; |