diff options
author | Simon Warta <[email protected]> | 2015-08-20 19:49:31 +0200 |
---|---|---|
committer | Simon Warta <[email protected]> | 2015-08-21 00:50:28 +0200 |
commit | 5bedae43e66002aefadce0b6d43bf6791d5156ca (patch) | |
tree | 859e7915f4bbb2fa50f449e6e755856670cc8773 /src | |
parent | a59f013165776fc57eb2b2bfd8aff95d536d2016 (diff) |
Refactor ./botan speed
* Add random_prime benchmark
* Add is_prime benchmark
* Respect runtime in benchmark_transform(). This sets default runtime
from 2s to 0.5s per configuration
Diffstat (limited to 'src')
-rw-r--r-- | src/cmd/implementation/speed.h | 28 | ||||
-rw-r--r-- | src/cmd/implementation/speed_prime.cpp | 96 | ||||
-rw-r--r-- | src/cmd/implementation/speed_public_key.cpp (renamed from src/cmd/speed_pk.cpp) | 6 | ||||
-rw-r--r-- | src/cmd/implementation/speed_transform.cpp | 67 | ||||
-rw-r--r-- | src/cmd/implementation/timer.cpp (renamed from src/cmd/timer.cpp) | 0 | ||||
-rw-r--r-- | src/cmd/implementation/timer.h (renamed from src/cmd/timer.h) | 0 | ||||
-rw-r--r-- | src/cmd/speed.cpp | 105 | ||||
-rw-r--r-- | src/cmd/speed.h | 16 | ||||
-rw-r--r-- | src/lib/misc/benchmark/benchmark.cpp | 18 | ||||
-rw-r--r-- | src/lib/utils/exceptn.h | 10 |
10 files changed, 245 insertions, 101 deletions
diff --git a/src/cmd/implementation/speed.h b/src/cmd/implementation/speed.h new file mode 100644 index 000000000..1f082eb52 --- /dev/null +++ b/src/cmd/implementation/speed.h @@ -0,0 +1,28 @@ +/* +* (C) 2014 Jack Lloyd +* (C) 2015 Simon Warta (Kullo GmbH) +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_CHECK_BENCHMARK_H__ +#define BOTAN_CHECK_BENCHMARK_H__ + +#include <botan/rng.h> +#include <string> +#include <chrono> + +void benchmark_public_key(Botan::RandomNumberGenerator& rng, + const std::string& algo, double seconds); + +std::map<std::string, double> benchmark_is_prime(Botan::RandomNumberGenerator &rng, + const std::chrono::milliseconds runtime); + +std::map<std::string, double> benchmark_random_prime(Botan::RandomNumberGenerator &rng, + const std::chrono::milliseconds runtime); + +bool benchmark_transform(Botan::RandomNumberGenerator& rng, const std::string& algo_name, + const std::chrono::milliseconds runtime); + + +#endif diff --git a/src/cmd/implementation/speed_prime.cpp b/src/cmd/implementation/speed_prime.cpp new file mode 100644 index 000000000..a7a344bef --- /dev/null +++ b/src/cmd/implementation/speed_prime.cpp @@ -0,0 +1,96 @@ +/* +* (C) 2015 Simon Warta (Kullo GmbH) +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include "speed.h" + +using namespace Botan; + +#if defined(BOTAN_HAS_NUMBERTHEORY) + +#include <botan/numthry.h> +#include <chrono> + +namespace { +const size_t RSA_EXP = 65537; +const size_t RSA_BITS = 2048; + +const auto SAMPLE_DATA = std::vector<BigInt>{ + BigInt("147572674850319649408425528388978190129147580193826207917614581140087181349813950149403694089438460074197915858493514824951402666113125007396293585089750170962882245605820159076002066981429137353341175732273168874025070408827561035943771554301600092787967626039381375658829078877390735440179859333066156895363"), + BigInt("147572674850319649408425528388978190129147580193826207917614581140087181349813950149403694089438460074197915858493514824951402666113125007396293585089750170962882245605820159076002066981429137353341175732273168874025070408827561035943771554301600092787967626039381375658829078877390735440179859333066156895377"), + BigInt("147572674850319649408425528388978190129147580193826207917614581140087181349813950149403694089438460074197915858493514824951402666113125007396293585089750170962882245605820159076002066981429137353341175732273168874025070408827561035943771554301600092787967626039381375658829078877390735440179859333066156895381"), + BigInt("147572674850319649408425528388978190129147580193826207917614581140087181349813950149403694089438460074197915858493514824951402666113125007396293585089750170962882245605820159076002066981429137353341175732273168874025070408827561035943771554301600092787967626039381375658829078877390735440179859333066156895389"), + BigInt("147572674850319649408425528388978190129147580193826207917614581140087181349813950149403694089438460074197915858493514824951402666113125007396293585089750170962882245605820159076002066981429137353341175732273168874025070408827561035943771554301600092787967626039381375658829078877390735440179859333066156895399"), + BigInt("147572674850319649408425528388978190129147580193826207917614581140087181349813950149403694089438460074197915858493514824951402666113125007396293585089750170962882245605820159076002066981429137353341175732273168874025070408827561035943771554301600092787967626039381375658829078877390735440179859333066156895401"), + BigInt("147572674850319649408425528388978190129147580193826207917614581140087181349813950149403694089438460074197915858493514824951402666113125007396293585089750170962882245605820159076002066981429137353341175732273168874025070408827561035943771554301600092787967626039381375658829078877390735440179859333066156895431"), + BigInt("147572674850319649408425528388978190129147580193826207917614581140087181349813950149403694089438460074197915858493514824951402666113125007396293585089750170962882245605820159076002066981429137353341175732273168874025070408827561035943771554301600092787967626039381375658829078877390735440179859333066156895441"), + BigInt("147572674850319649408425528388978190129147580193826207917614581140087181349813950149403694089438460074197915858493514824951402666113125007396293585089750170962882245605820159076002066981429137353341175732273168874025070408827561035943771554301600092787967626039381375658829078877390735440179859333066156895461"), + BigInt("147572674850319649408425528388978190129147580193826207917614581140087181349813950149403694089438460074197915858493514824951402666113125007396293585089750170962882245605820159076002066981429137353341175732273168874025070408827561035943771554301600092787967626039381375658829078877390735440179859333066156895471"), + }; +} + +#endif // BOTAN_HAS_NUMBERTHEORY + +std::map<std::string, double> benchmark_is_prime(RandomNumberGenerator& rng, + const std::chrono::milliseconds runtime) + { + std::map<std::string, double> speeds; + +#if defined(BOTAN_HAS_NUMBERTHEORY) + + std::chrono::nanoseconds time_used(0); + size_t reps = 0; + + auto start = std::chrono::high_resolution_clock::now(); + + while(time_used < runtime) + { + // main work + for (const BigInt &p : SAMPLE_DATA) + { + is_prime(p, rng, 64, true); + } + + ++reps; + time_used = std::chrono::high_resolution_clock::now() - start; + } + + const double seconds_used = static_cast<double>(time_used.count()) / 1000000000; + speeds["base"] = reps / seconds_used; // ie, return ops per second + +#endif // BOTAN_HAS_NUMBERTHEORY + + return speeds; + } + +std::map<std::string, double> benchmark_random_prime(RandomNumberGenerator& rng, + const std::chrono::milliseconds runtime) + { + std::map<std::string, double> speeds; + +#if defined(BOTAN_HAS_NUMBERTHEORY) + + std::chrono::nanoseconds time_used(0); + size_t reps = 0; + + auto start = std::chrono::high_resolution_clock::now(); + + while(time_used < runtime) + { + // main work + random_prime(rng, (RSA_BITS + 1) / 2, RSA_EXP); + + ++reps; + time_used = std::chrono::high_resolution_clock::now() - start; + } + + const double seconds_used = static_cast<double>(time_used.count()) / 1000000000; + speeds["base"] = reps / seconds_used; // ie, return ops per second + +#endif // BOTAN_HAS_NUMBERTHEORY + + return speeds; + } + diff --git a/src/cmd/speed_pk.cpp b/src/cmd/implementation/speed_public_key.cpp index 035b9a3af..1e14f7eca 100644 --- a/src/cmd/speed_pk.cpp +++ b/src/cmd/implementation/speed_public_key.cpp @@ -4,7 +4,7 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include "apps.h" +#include "../apps.h" #if defined(BOTAN_HAS_PUBLIC_KEY_CRYPTO) @@ -784,8 +784,8 @@ void benchmark_mce(RandomNumberGenerator& rng, } -void bench_pk(RandomNumberGenerator& rng, - const std::string& algo, double seconds) +void benchmark_public_key(RandomNumberGenerator& rng, + const std::string& algo, double seconds) { /* There is some strangeness going on here. It looks like algorithms diff --git a/src/cmd/implementation/speed_transform.cpp b/src/cmd/implementation/speed_transform.cpp new file mode 100644 index 000000000..2db5cdd70 --- /dev/null +++ b/src/cmd/implementation/speed_transform.cpp @@ -0,0 +1,67 @@ +/* +* (C) 2009 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include "speed.h" + +#include <iostream> +#include <iomanip> + +#include <botan/cipher_mode.h> +#include <botan/transform.h> + +using namespace Botan; + +namespace { +void benchmark_transform(std::unique_ptr<Transform> tf, + RandomNumberGenerator& rng, + const std::chrono::milliseconds runtime) + { + for(size_t buf_size : { 16, 64, 256, 1024, 8192 }) + { + secure_vector<byte> buffer(buf_size); + + std::chrono::nanoseconds time_used(0); + + tf->start(rng.random_vec(tf->default_nonce_length())); + + auto start = std::chrono::high_resolution_clock::now(); + + secure_vector<byte> buf(buf_size); + size_t reps = 0; + while(time_used < runtime) + { + tf->update(buf); + buf.resize(buf_size); + ++reps; + time_used = std::chrono::high_resolution_clock::now() - start; + } + + const u64bit nsec_used = std::chrono::duration_cast<std::chrono::nanoseconds>(time_used).count(); + + const double seconds_used = static_cast<double>(nsec_used) / 1000000000; + + const double Mbps = ((reps / seconds_used) * buf_size) / 1024 / 1024; + + std::cout << tf->name() << " " << std::setprecision(4) << Mbps + << " MiB / sec with " << buf_size << " byte blocks" << std::endl; + } + } +} + +bool benchmark_transform(RandomNumberGenerator& rng, const std::string& algo_name, + const std::chrono::milliseconds runtime) + { + std::unique_ptr<Transform> tf; + tf.reset(get_cipher_mode(algo_name, ENCRYPTION)); + if(!tf) + return false; + + if(Keyed_Transform* keyed = dynamic_cast<Keyed_Transform*>(tf.get())) + keyed->set_key(rng.random_vec(keyed->key_spec().maximum_keylength())); + + benchmark_transform(std::move(tf), rng, runtime); + return true; + } diff --git a/src/cmd/timer.cpp b/src/cmd/implementation/timer.cpp index 14e55316b..14e55316b 100644 --- a/src/cmd/timer.cpp +++ b/src/cmd/implementation/timer.cpp diff --git a/src/cmd/timer.h b/src/cmd/implementation/timer.h index ac5bd5cef..ac5bd5cef 100644 --- a/src/cmd/timer.h +++ b/src/cmd/implementation/timer.h diff --git a/src/cmd/speed.cpp b/src/cmd/speed.cpp index eea3a7c60..91b2f4fbd 100644 --- a/src/cmd/speed.cpp +++ b/src/cmd/speed.cpp @@ -8,27 +8,17 @@ #if defined(BOTAN_HAS_RUNTIME_BENCHMARKING) -#include "speed.h" +#include "implementation/speed.h" + #include <iostream> #include <iomanip> #include <botan/benchmark.h> #include <botan/auto_rng.h> -#include <botan/cipher_mode.h> -#include <botan/parsing.h> -#include <botan/symkey.h> -#include <botan/transform.h> -#include <botan/hex.h> - -#include <chrono> - -typedef std::chrono::high_resolution_clock benchmark_clock; - using namespace Botan; namespace { - const std::vector<std::string> default_benchmark_list = { /* Block ciphers */ "AES-128", @@ -90,7 +80,11 @@ const std::vector<std::string> default_benchmark_list = { /* MACs */ "CMAC(AES-128)", - "HMAC(SHA-1)" + "HMAC(SHA-1)", + + /* Misc */ + "is_prime", + "random_prime" }; void report_results(const std::string& algo, @@ -123,78 +117,43 @@ void report_results(const std::string& algo, std::cout.flags(flags); } -void time_transform(std::unique_ptr<Transform> tf, - RandomNumberGenerator& rng) +void bench_algo(const std::string& algo, + RandomNumberGenerator& rng, + double seconds, + size_t buf_size) { - const std::chrono::seconds runtime(2); - - for(size_t buf_size : { 16, 64, 256, 1024, 8192 }) - { - secure_vector<byte> buffer(buf_size); - - std::chrono::nanoseconds time_used(0); - - tf->start(rng.random_vec(tf->default_nonce_length())); - - auto start = std::chrono::high_resolution_clock::now(); - - secure_vector<byte> buf(buf_size); - size_t reps = 0; - while(time_used < runtime) - { - tf->update(buf); - buf.resize(buf_size); - ++reps; - time_used = std::chrono::high_resolution_clock::now() - start; - } + std::chrono::milliseconds runtime( + static_cast<std::chrono::milliseconds::rep>(seconds * 1000)); - const u64bit nsec_used = std::chrono::duration_cast<std::chrono::nanoseconds>(time_used).count(); - - const double seconds_used = static_cast<double>(nsec_used) / 1000000000; - - const double Mbps = ((reps / seconds_used) * buf_size) / 1024 / 1024; - - std::cout << tf->name() << " " << std::setprecision(4) << Mbps - << " MiB / sec with " << buf_size << " byte blocks" << std::endl; - } - } - -bool time_transform(const std::string& algo, RandomNumberGenerator& rng) + if (algo == "random_prime") { - std::unique_ptr<Transform> tf; - tf.reset(get_cipher_mode(algo, ENCRYPTION)); - if(!tf) - return false; - - if(Keyed_Transform* keyed = dynamic_cast<Keyed_Transform*>(tf.get())) - keyed->set_key(rng.random_vec(keyed->key_spec().maximum_keylength())); - - time_transform(std::move(tf), rng); - return true; + auto speeds = benchmark_random_prime(rng, runtime); + report_results(algo, speeds); + return; } -void bench_algo(const std::string& algo, - RandomNumberGenerator& rng, - double seconds, - size_t buf_size) + if (algo == "is_prime") { - std::chrono::milliseconds ms( - static_cast<std::chrono::milliseconds::rep>(seconds * 1000)); + auto speeds = benchmark_is_prime(rng, runtime); + report_results(algo, speeds); + return; + } - if(time_transform(algo, rng)) + // This does report itself + if (benchmark_transform(rng, algo, runtime)) return; - std::map<std::string, double> speeds = algorithm_benchmark(algo, rng, ms, buf_size); - - if(!speeds.empty()) + try { + auto speeds = algorithm_benchmark(algo, rng, runtime, buf_size); report_results(algo, speeds); - return; } - -#if defined(BOTAN_HAS_PUBLIC_KEY_CRYPTO) - bench_pk(rng, algo, seconds); -#endif + catch (No_Provider_Found) + { + #if defined(BOTAN_HAS_PUBLIC_KEY_CRYPTO) + benchmark_public_key(rng, algo, seconds); + #endif + } } int speed(int argc, char* argv[]) diff --git a/src/cmd/speed.h b/src/cmd/speed.h deleted file mode 100644 index 5f3918a3f..000000000 --- a/src/cmd/speed.h +++ /dev/null @@ -1,16 +0,0 @@ -/* -* (C) 2014 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#ifndef BOTAN_CHECK_BENCHMARK_H__ -#define BOTAN_CHECK_BENCHMARK_H__ - -#include <botan/rng.h> -#include <string> - -void bench_pk(Botan::RandomNumberGenerator& rng, - const std::string& algo, double seconds); - -#endif diff --git a/src/lib/misc/benchmark/benchmark.cpp b/src/lib/misc/benchmark/benchmark.cpp index 90d8b1aca..152b45d37 100644 --- a/src/lib/misc/benchmark/benchmark.cpp +++ b/src/lib/misc/benchmark/benchmark.cpp @@ -6,6 +6,7 @@ */ #include <botan/benchmark.h> +#include <botan/exceptn.h> #include <botan/lookup.h> #include <botan/buf_comp.h> #include <botan/cipher_mode.h> @@ -153,19 +154,18 @@ algorithm_benchmark(const std::string& name, size_t buf_size) { //Algorithm_Factory& af = global_state().algorithm_factory(); - const auto providers = get_all_providers_of(name); + const auto provider_names = get_all_providers_of(name); + if (provider_names.empty()) + throw No_Provider_Found(name); std::map<std::string, double> all_results; // provider -> ops/sec - if(!providers.empty()) - { - const std::chrono::nanoseconds ns_per_provider = milliseconds / providers.size(); + const std::chrono::nanoseconds ns_per_provider = milliseconds / provider_names.size(); - for(auto provider : providers) - { - auto results = time_algorithm_ops(name, provider, rng, ns_per_provider, buf_size); - all_results[provider] = find_first_in(results, { "", "update", "encrypt" }); - } + for(auto provider : provider_names) + { + auto results = time_algorithm_ops(name, provider, rng, ns_per_provider, buf_size); + all_results[provider] = find_first_in(results, { "", "update", "encrypt" }); } return all_results; diff --git a/src/lib/utils/exceptn.h b/src/lib/utils/exceptn.h index 7e16a5dec..eef1b4d43 100644 --- a/src/lib/utils/exceptn.h +++ b/src/lib/utils/exceptn.h @@ -113,6 +113,16 @@ struct BOTAN_DLL Algorithm_Not_Found : public Lookup_Error }; /** +* No_Provider_Found Exception +*/ +struct BOTAN_DLL No_Provider_Found : public Exception + { + No_Provider_Found(const std::string& name) : + Exception("Could not find any provider for algorithm named \"" + name + "\"") + {} + }; + +/** * Invalid_Algorithm_Name Exception */ struct BOTAN_DLL Invalid_Algorithm_Name : public Invalid_Argument |