Botan: src/benchmark/benchmark.cpp Source File

Botan 1.10.17

benchmark.cpp
Go to the documentation of this file.
1 /*
2 * Runtime benchmarking
3 * (C) 2008 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
6 */
7
8 #include <botan/benchmark.h>
9 #include <botan/buf_comp.h>
10 #include <botan/block_cipher.h>
11 #include <botan/stream_cipher.h>
12 #include <botan/hash.h>
13 #include <botan/mac.h>
14 #include <botan/time.h>
15 #include <memory>
16
17 namespace Botan {
18
19 namespace {
20
21 /**
22 * Benchmark Buffered_Computation (hash or MAC)
23 */
24 std::pair<u64bit, u64bit> bench_buf_comp(Buffered_Computation* buf_comp,
25 u64bit nanoseconds_max,
26 const byte buf[], size_t buf_len)
27 {
28 u64bit reps = 0;
29 u64bit nanoseconds_used = 0;
30
31 while(nanoseconds_used < nanoseconds_max)
32 {
33 const u64bit start = get_nanoseconds_clock();
34 buf_comp->update(buf, buf_len);
35 nanoseconds_used += get_nanoseconds_clock() - start;
36
37 ++reps;
38 }
39
40 return std::make_pair(reps * buf_len, nanoseconds_used);
41 }
42
43 /**
44 * Benchmark block cipher
45 */
46 std::pair<u64bit, u64bit>
47 bench_block_cipher(BlockCipher* block_cipher,
48 u64bit nanoseconds_max,
49 byte buf[], size_t buf_len)
50 {
51 const size_t in_blocks = buf_len / block_cipher->block_size();
52
53 u64bit reps = 0;
54 u64bit nanoseconds_used = 0;
55
56 block_cipher->set_key(buf, block_cipher->maximum_keylength());
57
58 while(nanoseconds_used < nanoseconds_max)
59 {
60 const u64bit start = get_nanoseconds_clock();
61 block_cipher->encrypt_n(buf, buf, in_blocks);
62 nanoseconds_used += get_nanoseconds_clock() - start;
63
64 ++reps;
65 }
66
67 return std::make_pair(reps * in_blocks * block_cipher->block_size(),
68 nanoseconds_used);
69 }
70
71 /**
72 * Benchmark stream
73 */
74 std::pair<u64bit, u64bit>
75 bench_stream_cipher(StreamCipher* stream_cipher,
76 u64bit nanoseconds_max,
77 byte buf[], size_t buf_len)
78 {
79 u64bit reps = 0;
80 u64bit nanoseconds_used = 0;
81
82 stream_cipher->set_key(buf, stream_cipher->maximum_keylength());
83
84 while(nanoseconds_used < nanoseconds_max)
85 {
86 const u64bit start = get_nanoseconds_clock();
87 stream_cipher->cipher1(buf, buf_len);
88 nanoseconds_used += get_nanoseconds_clock() - start;
89
90 ++reps;
91 }
92
93 return std::make_pair(reps * buf_len, nanoseconds_used);
94 }
95
96 /**
97 * Benchmark hash
98 */
99 std::pair<u64bit, u64bit>
100 bench_hash(HashFunction* hash,
101 u64bit nanoseconds_max,
102 const byte buf[], size_t buf_len)
103 {
104 return bench_buf_comp(hash, nanoseconds_max, buf, buf_len);
105 }
106
107 /**
108 * Benchmark MAC
109 */
110 std::pair<u64bit, u64bit>
111 bench_mac(MessageAuthenticationCode* mac,
112 u64bit nanoseconds_max,
113 const byte buf[], size_t buf_len)
114 {
115 mac->set_key(buf, mac->maximum_keylength());
116 return bench_buf_comp(mac, nanoseconds_max, buf, buf_len);
117 }
118
119 }
120
121 std::map<std::string, double>
122 algorithm_benchmark(const std::string& name,
123 Algorithm_Factory& af,
124 RandomNumberGenerator& rng,
125 u32bit milliseconds,
126 size_t buf_size)
127 {
128 std::vector<std::string> providers = af.providers_of(name);
129 std::map<std::string, double> all_results;
130
131 if(providers.empty()) // no providers, nothing to do
132 return all_results;
133
134 const u64bit ns_per_provider =
135 (static_cast<u64bit>(milliseconds) * 1000 * 1000) / providers.size();
136
137 std::vector<byte> buf(buf_size * 1024);
138 rng.randomize(&buf[0], buf.size());
139
140 for(size_t i = 0; i != providers.size(); ++i)
141 {
142 const std::string provider = providers[i];
143
144 std::pair<u64bit, u64bit> results(0, 0);
145
146 if(const BlockCipher* proto =
147 af.prototype_block_cipher(name, provider))
148 {
149 std::auto_ptr<BlockCipher> block_cipher(proto->clone());
150 results = bench_block_cipher(block_cipher.get(),
151 ns_per_provider,
152 &buf[0], buf.size());
153 }
154 else if(const StreamCipher* proto =
155 af.prototype_stream_cipher(name, provider))
156 {
157 std::auto_ptr<StreamCipher> stream_cipher(proto->clone());
158 results = bench_stream_cipher(stream_cipher.get(),
159 ns_per_provider,
160 &buf[0], buf.size());
161 }
162 else if(const HashFunction* proto =
163 af.prototype_hash_function(name, provider))
164 {
165 std::auto_ptr<HashFunction> hash(proto->clone());
166 results = bench_hash(hash.get(), ns_per_provider,
167 &buf[0], buf.size());
168 }
169 else if(const MessageAuthenticationCode* proto =
170 af.prototype_mac(name, provider))
171 {
172 std::auto_ptr<MessageAuthenticationCode> mac(proto->clone());
173 results = bench_mac(mac.get(), ns_per_provider,
174 &buf[0], buf.size());
175 }
176
177 if(results.first && results.second)
178 {
179 /* 953.67 == 1000 * 1000 * 1000 / 1024 / 1024 - the conversion
180 factor from bytes per nanosecond to mebibytes per second.
181 */
182 double speed = (953.67 * results.first) / results.second;
183 all_results[provider] = speed;
184 }
185 }
186
187 return all_results;
188 }
189
190 }
Botan::RandomNumberGenerator::randomize
virtual void randomize(byte output[], size_t length)=0
Botan::get_nanoseconds_clock
u64bit get_nanoseconds_clock()
Definition: time.cpp:93
Botan::Algorithm_Factory
Definition: algo_factory.h:34
Botan::RandomNumberGenerator
Definition: rng.h:20
Botan::Algorithm_Factory::prototype_block_cipher
const BlockCipher * prototype_block_cipher(const std::string &algo_spec, const std::string &provider="")
Definition: algo_factory.cpp:193
Botan::MessageAuthenticationCode
Definition: mac.h:20
Botan::byte
unsigned char byte
Definition: types.h:22
Botan::Algorithm_Factory::prototype_hash_function
const HashFunction * prototype_hash_function(const std::string &algo_spec, const std::string &provider="")
Definition: algo_factory.cpp:215
Botan::u64bit
unsigned long long u64bit
Definition: types.h:49
Botan::SymmetricAlgorithm::maximum_keylength
size_t maximum_keylength() const
Definition: sym_algo.h:33
Botan::SymmetricAlgorithm::set_key
void set_key(const SymmetricKey &key)
Definition: sym_algo.h:60
Botan::StreamCipher
Definition: stream_cipher.h:18
Botan::Algorithm_Factory::prototype_mac
const MessageAuthenticationCode * prototype_mac(const std::string &algo_spec, const std::string &provider="")
Definition: algo_factory.cpp:226
Botan
Definition: algo_base.h:14
Botan::Algorithm_Factory::providers_of
std::vector< std::string > providers_of(const std::string &algo_spec)
Definition: algo_factory.cpp:168
Botan::HashFunction
Definition: hash.h:20
Botan::algorithm_benchmark
std::map< std::string, double > algorithm_benchmark(const std::string &name, Algorithm_Factory &af, RandomNumberGenerator &rng, u32bit milliseconds, size_t buf_size)
Definition: benchmark.cpp:122
Botan::u32bit
unsigned int u32bit
Definition: types.h:32
Botan::Algorithm_Factory::prototype_stream_cipher
const StreamCipher * prototype_stream_cipher(const std::string &algo_spec, const std::string &provider="")
Definition: algo_factory.cpp:204
Botan::BlockCipher
Definition: block_cipher.h:18