• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 13274522654

11 Feb 2025 11:26PM UTC coverage: 91.645% (-0.007%) from 91.652%
13274522654

push

github

web-flow
Merge pull request #4647 from randombit/jack/internal-assert-and-mem-ops

Avoid using mem_ops.h or assert.h in public headers

94854 of 103501 relevant lines covered (91.65%)

11334975.77 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

64.66
/src/cli/perf_misc.cpp
1
/*
2
* (C) 2024 Jack Lloyd
3
*
4
* Botan is released under the Simplified BSD License (see license.txt)
5
*/
6

7
#include "perf.h"
8
#include <cstring>
9

10
// Always available:
11
#include <botan/assert.h>
12
#include <botan/hex.h>
13

14
#if defined(BOTAN_HAS_BASE64_CODEC)
15
   #include <botan/base64.h>
16
#endif
17

18
#if defined(BOTAN_HAS_FPE_FE1)
19
   #include <botan/fpe_fe1.h>
20
#endif
21

22
#if defined(BOTAN_HAS_RFC3394_KEYWRAP)
23
   #include <botan/rfc3394.h>
24
#endif
25

26
#if defined(BOTAN_HAS_ZFEC)
27
   #include <botan/zfec.h>
28
#endif
29

30
namespace Botan_CLI {
31

32
class PerfTest_Hex final : public PerfTest {
×
33
   public:
34
      void go(const PerfConfig& config) override {
×
35
         for(size_t buf_size : config.buffer_sizes()) {
×
36
            std::vector<uint8_t> ibuf(buf_size);
×
37
            std::vector<uint8_t> rbuf(buf_size);
×
38
            const size_t olen = 2 * buf_size;
×
39

40
            auto enc_timer = config.make_timer("hex", ibuf.size(), "encode", "", ibuf.size());
×
41

42
            auto dec_timer = config.make_timer("hex", olen, "decode", "", olen);
×
43

44
            const auto msec = config.runtime();
×
45

46
            while(enc_timer->under(msec) && dec_timer->under(msec)) {
×
47
               config.rng().randomize(ibuf);
×
48

49
               std::string hex = enc_timer->run([&]() { return Botan::hex_encode(ibuf); });
×
50

51
               dec_timer->run([&]() { Botan::hex_decode(rbuf.data(), hex); });
×
52
               BOTAN_ASSERT(rbuf == ibuf, "Encode/decode round trip ok");
×
53
            }
×
54

55
            config.record_result(*enc_timer);
×
56
            config.record_result(*dec_timer);
×
57
         }
×
58
      }
×
59
};
60

61
BOTAN_REGISTER_PERF_TEST("hex", PerfTest_Hex);
×
62

63
#if defined(BOTAN_HAS_BASE64_CODEC)
64
class PerfTest_Base64 final : public PerfTest {
×
65
   public:
66
      void go(const PerfConfig& config) override {
×
67
         for(size_t buf_size : config.buffer_sizes()) {
×
68
            std::vector<uint8_t> ibuf(buf_size);
×
69
            std::vector<uint8_t> rbuf(buf_size);
×
70
            const size_t olen = Botan::base64_encode_max_output(ibuf.size());
×
71

72
            auto enc_timer = config.make_timer("base64", ibuf.size(), "encode", "", ibuf.size());
×
73

74
            auto dec_timer = config.make_timer("base64", olen, "decode", "", olen);
×
75

76
            const auto msec = config.runtime();
×
77

78
            while(enc_timer->under(msec) && dec_timer->under(msec)) {
×
79
               config.rng().randomize(ibuf);
×
80

81
               std::string b64 = enc_timer->run([&]() { return Botan::base64_encode(ibuf); });
×
82

83
               dec_timer->run([&]() { Botan::base64_decode(rbuf.data(), b64); });
×
84
               BOTAN_ASSERT(rbuf == ibuf, "Encode/decode round trip ok");
×
85
            }
×
86

87
            config.record_result(*enc_timer);
×
88
            config.record_result(*dec_timer);
×
89
         }
×
90
      }
×
91
};
92

93
BOTAN_REGISTER_PERF_TEST("base64", PerfTest_Base64);
×
94

95
#endif
96

97
#if defined(BOTAN_HAS_FPE_FE1)
98

99
class PerfTest_FpeFe1 final : public PerfTest {
1✔
100
   public:
101
      void go(const PerfConfig& config) override {
1✔
102
         const auto n = Botan::BigInt::from_u64(1000000000000000);
1✔
103

104
         auto enc_timer = config.make_timer("FPE_FE1 encrypt");
2✔
105
         auto dec_timer = config.make_timer("FPE_FE1 decrypt");
2✔
106

107
         const Botan::SymmetricKey key(config.rng(), 32);
1✔
108
         const std::vector<uint8_t> tweak(8);  // 8 zeros
1✔
109

110
         auto x = Botan::BigInt::one();
1✔
111

112
         Botan::FPE_FE1 fpe_fe1(n);
1✔
113
         fpe_fe1.set_key(key);
1✔
114

115
         auto runtime = config.runtime();
1✔
116

117
         while(enc_timer->under(runtime)) {
3✔
118
            enc_timer->start();
2✔
119
            x = fpe_fe1.encrypt(x, tweak.data(), tweak.size());
2✔
120
            enc_timer->stop();
2✔
121
         }
122
         config.record_result(*enc_timer);
1✔
123

124
         for(size_t i = 0; i != enc_timer->events(); ++i) {
3✔
125
            dec_timer->start();
2✔
126
            x = fpe_fe1.decrypt(x, tweak.data(), tweak.size());
2✔
127
            dec_timer->stop();
2✔
128
         }
129
         config.record_result(*dec_timer);
1✔
130

131
         BOTAN_ASSERT(x == 1, "FPE works");
1✔
132
      }
4✔
133
};
134

135
BOTAN_REGISTER_PERF_TEST("fpe_fe1", PerfTest_FpeFe1);
1✔
136

137
#endif
138

139
#if defined(BOTAN_HAS_RFC3394_KEYWRAP)
140
class PerfTest_Rfc3394 final : public PerfTest {
1✔
141
      void go(const PerfConfig& config) override {
1✔
142
         auto wrap_timer = config.make_timer("RFC3394 AES-256 key wrap");
2✔
143
         auto unwrap_timer = config.make_timer("RFC3394 AES-256 key unwrap");
2✔
144

145
         const Botan::SymmetricKey kek(config.rng(), 32);
1✔
146
         Botan::secure_vector<uint8_t> key(64, 0);
1✔
147

148
         const auto runtime = config.runtime();
1✔
149

150
         while(wrap_timer->under(runtime)) {
50✔
151
            wrap_timer->start();
49✔
152
            key = Botan::rfc3394_keywrap(key, kek);
98✔
153
            wrap_timer->stop();
49✔
154

155
            unwrap_timer->start();
49✔
156
            key = Botan::rfc3394_keyunwrap(key, kek);
98✔
157
            unwrap_timer->stop();
49✔
158

159
            key[0] += 1;
49✔
160
         }
161

162
         config.record_result(*wrap_timer);
1✔
163
         config.record_result(*unwrap_timer);
2✔
164
      }
3✔
165
};
166

167
BOTAN_REGISTER_PERF_TEST("rfc3394", PerfTest_Rfc3394);
1✔
168

169
#endif
170

171
#if defined(BOTAN_HAS_ZFEC)
172

173
class PerfTest_Zfec final : public PerfTest {
1✔
174
   public:
175
      void go(const PerfConfig& config) override {
1✔
176
         const size_t k = 4;
1✔
177
         const size_t n = 16;
1✔
178

179
         Botan::ZFEC zfec(k, n);
1✔
180

181
         const size_t share_size = 256 * 1024;
1✔
182

183
         std::vector<uint8_t> input(share_size * k);
1✔
184
         config.rng().randomize(input.data(), input.size());
1✔
185

186
         std::vector<uint8_t> output(share_size * n);
1✔
187

188
         auto enc_fn = [&](size_t share, const uint8_t buf[], size_t len) {
17✔
189
            std::memcpy(&output[share * share_size], buf, len);
16✔
190
         };
17✔
191

192
         const auto msec = config.runtime();
1✔
193

194
         const std::string alg = Botan::fmt("zfec {}/{}", k, n);
1✔
195

196
         auto enc_timer = config.make_timer(alg, input.size(), "encode", "", input.size());
1✔
197

198
         enc_timer->run_until_elapsed(msec, [&]() { zfec.encode(input.data(), input.size(), enc_fn); });
3✔
199

200
         config.record_result(*enc_timer);
1✔
201

202
         auto dec_timer = config.make_timer(alg, input.size(), "decode", "", input.size());
1✔
203

204
         std::map<size_t, const uint8_t*> shares;
1✔
205
         for(size_t i = 0; i != n; ++i) {
17✔
206
            shares[i] = &output[share_size * i];
16✔
207
         }
208

209
         // remove data shares to make decoding maximally expensive:
210
         while(shares.size() != k) {
13✔
211
            shares.erase(shares.begin());
12✔
212
         }
213

214
         std::vector<uint8_t> recovered(share_size * k);
1✔
215

216
         auto dec_fn = [&](size_t share, const uint8_t buf[], size_t len) {
5✔
217
            std::memcpy(&recovered[share * share_size], buf, len);
4✔
218
         };
5✔
219

220
         dec_timer->run_until_elapsed(msec, [&]() { zfec.decode_shares(shares, share_size, dec_fn); });
3✔
221

222
         config.record_result(*dec_timer);
1✔
223

224
         if(recovered != input) {
1✔
225
            config.error_output() << "ZFEC recovery failed\n";
×
226
         }
227
      }
4✔
228
};
229

230
BOTAN_REGISTER_PERF_TEST("zfec", PerfTest_Zfec);
1✔
231

232
#endif
233

234
}  // namespace Botan_CLI
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc