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

randombit / botan / 22842226849

09 Mar 2026 07:05AM UTC coverage: 90.19% (-1.5%) from 91.672%
22842226849

Pull #5307

github

web-flow
Merge 62224a153 into cdaa9c0ff
Pull Request #5307: Fix ML-DSA private key encoding

103883 of 115183 relevant lines covered (90.19%)

11608594.55 hits per line

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

26.44
/src/cli/perf_pwdhash.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

9
#include <botan/internal/fmt.h>
10
#include <array>
11

12
#if defined(BOTAN_HAS_PASSWORD_HASHING)
13
   #include <botan/pwdhash.h>
14
   #include <botan/rng.h>
15
   #include <cstring>
16
#endif
17

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

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

26
namespace Botan_CLI {
27

28
#if defined(BOTAN_HAS_BCRYPT)
29

30
class PerfTest_Bcrypt final : public PerfTest {
×
31
   public:
32
      void go(const PerfConfig& config) override {
×
33
         const std::string password = "not a very good password";
×
34

35
         for(size_t work_factor = 4; work_factor <= 14; ++work_factor) {
×
36
            auto timer = config.make_timer(Botan::fmt("bcrypt wf={}", work_factor));
×
37

38
            timer->run([&] { Botan::generate_bcrypt(password, config.rng(), static_cast<uint16_t>(work_factor)); });
×
39

40
            config.record_result(*timer);
×
41
         }
×
42
      }
×
43
};
44

45
BOTAN_REGISTER_PERF_TEST("bcrypt", PerfTest_Bcrypt);
×
46

47
#endif
48

49
#if defined(BOTAN_HAS_PASSHASH9)
50

51
class PerfTest_Passhash9 final : public PerfTest {
×
52
   public:
53
      void go(const PerfConfig& config) override {
×
54
         const std::string password = "not a very good password";
×
55

56
         for(uint8_t alg = 0; alg <= 4; ++alg) {
×
57
            if(!Botan::is_passhash9_alg_supported(alg)) {
×
58
               continue;
×
59
            }
60

61
            for(auto work_factor : {10, 15}) {
×
62
               auto timer = config.make_timer(Botan::fmt("passhash9 alg={} wf={}", alg, work_factor));
×
63

64
               timer->run(
×
65
                  [&] { Botan::generate_passhash9(password, config.rng(), static_cast<uint8_t>(work_factor), alg); });
×
66

67
               config.record_result(*timer);
×
68
            }
×
69
         }
70
      }
×
71
};
72

73
BOTAN_REGISTER_PERF_TEST("passhash9", PerfTest_Passhash9);
×
74

75
#endif
76

77
#if defined(BOTAN_HAS_SCRYPT)
78

79
class PerfTest_Scrypt final : public PerfTest {
1✔
80
   public:
81
      void go(const PerfConfig& config) override {
1✔
82
         auto pwdhash_fam = Botan::PasswordHashFamily::create_or_throw("Scrypt");
1✔
83

84
         for(const size_t N : {8192, 16384, 32768, 65536}) {
5✔
85
            for(const size_t r : {1, 8, 16}) {
16✔
86
               for(const size_t p : {1}) {
12✔
87
                  auto pwdhash = pwdhash_fam->from_params(N, r, p);
12✔
88

89
                  const size_t mem_usage = pwdhash->total_memory_usage() / (1024 * 1024);
12✔
90
                  auto scrypt_timer = config.make_timer(Botan::fmt("scrypt-{}-{}-{} ({} MiB)", N, r, p, mem_usage));
24✔
91

92
                  uint8_t out[64];
12✔
93
                  uint8_t salt[8];
12✔
94
                  config.rng().randomize(salt, sizeof(salt));
12✔
95

96
                  auto runtime = config.runtime();
12✔
97

98
                  while(scrypt_timer->under(runtime)) {
24✔
99
                     scrypt_timer->run([&] {
12✔
100
                        pwdhash->derive_key(out, sizeof(out), "password", 8, salt, sizeof(salt));
12✔
101
                        std::memcpy(salt, out, 8);
12✔
102
                     });
12✔
103
                  }
104

105
                  config.record_result(*scrypt_timer);
12✔
106

107
                  if(scrypt_timer->events() == 1) {
12✔
108
                     break;
109
                  }
110
               }
24✔
111
            }
112
         }
113
      }
1✔
114
};
115

116
BOTAN_REGISTER_PERF_TEST("scrypt", PerfTest_Scrypt);
1✔
117

118
#endif
119

120
#if defined(BOTAN_HAS_PBKDF2) && defined(BOTAN_HAS_PASSWORD_HASHING)
121

122
class PerfTest_PBKDF2 final : public PerfTest {
×
123
   public:
124
      void go(const PerfConfig& config) override {
×
125
         const std::string hash = "SHA-256";
×
126
         auto pwdhash_fam = Botan::PasswordHashFamily::create(Botan::fmt("PBKDF2({})", hash));
×
127

128
         if(pwdhash_fam != nullptr) {
×
129
            for(const size_t iter : {10000, 100000}) {
×
130
               auto pwdhash = pwdhash_fam->from_params(iter);
×
131

132
               auto pbkdf2_timer = config.make_timer(Botan::fmt("PBKDF2({},{})", hash, iter));
×
133

134
               std::array<uint8_t, 16> salt{};
×
135
               config.rng().randomize(salt);
×
136

137
               const std::string password = "password";
×
138
               auto runtime = config.runtime();
×
139

140
               std::array<uint8_t, 32> out{};
×
141

142
               while(pbkdf2_timer->under(runtime)) {
×
143
                  pbkdf2_timer->run([&] {
×
144
                     pwdhash->hash(out, password, salt);
×
145
                     std::memcpy(salt.data(), out.data(), 8);
×
146
                  });
×
147
               }
148

149
               config.record_result(*pbkdf2_timer);
×
150
            }
×
151
         }
152
      }
×
153
};
154

155
BOTAN_REGISTER_PERF_TEST("pbkdf2", PerfTest_PBKDF2);
×
156

157
#endif
158

159
#if defined(BOTAN_HAS_ARGON2)
160

161
class PerfTest_Argon2 final : public PerfTest {
×
162
   public:
163
      void go(const PerfConfig& config) override {
×
164
         auto pwhash_fam = Botan::PasswordHashFamily::create_or_throw("Argon2id");
×
165

166
         const auto msec = config.runtime();
×
167

168
         for(const size_t M : {8 * 1024, 64 * 1024, 256 * 1024}) {
×
169
            for(const size_t t : {1, 4}) {
×
170
               for(const size_t p : {1, 4}) {
×
171
                  auto pwhash = pwhash_fam->from_params(M, t, p);
×
172
                  auto timer = config.make_timer(pwhash->to_string());
×
173

174
                  uint8_t out[64];
×
175
                  uint8_t salt[16];
×
176
                  config.rng().randomize(salt, sizeof(salt));
×
177

178
                  while(timer->under(msec)) {
×
179
                     timer->run([&] { pwhash->derive_key(out, sizeof(out), "password", 8, salt, sizeof(salt)); });
×
180
                  }
181

182
                  config.record_result(*timer);
×
183
               }
×
184
            }
185
         }
186
      }
×
187
};
188

189
BOTAN_REGISTER_PERF_TEST("argon2", PerfTest_Argon2);
×
190

191
#endif
192

193
}  // 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