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

randombit / botan / 14138547150

28 Mar 2025 09:56PM UTC coverage: 91.521% (-0.02%) from 91.542%
14138547150

push

github

web-flow
Merge pull request #4793 from randombit/jack/pk-parsing-bench

Add benchmark for public and private key parsing

95407 of 104246 relevant lines covered (91.52%)

11501043.72 hits per line

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

66.18
/src/cli/perf_pk_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

9
#if defined(BOTAN_HAS_PUBLIC_KEY_CRYPTO)
10
   #include <botan/assert.h>
11
   #include <botan/pk_algs.h>
12
   #include <botan/pkcs8.h>
13
   #include <botan/x509_key.h>
14
   #include <botan/internal/fmt.h>
15
#endif
16

17
#if defined(BOTAN_HAS_ECDSA)
18
   #include <botan/ecdsa.h>
19
   #include <botan/pubkey.h>
20
#endif
21

22
namespace Botan_CLI {
23

24
#if defined(BOTAN_HAS_PUBLIC_KEY_CRYPTO)
25

26
class PerfTest_PKKeyParsing final : public PerfTest {
×
27
   public:
28
      void go(const PerfConfig& config) override {
×
29
         const auto runtime = config.runtime();
×
30
         auto& rng = config.rng();
×
31

32
         const std::pair<std::string, std::string> keygen_algos[] = {
×
33
            {"RSA", "2048"},
34
            {"ECDSA", "secp256r1"},
35
            {"ECDSA", "brainpool512r1"},
36
            {"DH", "modp/ietf/2048"},
37
            {"X25519", ""},
38
            {"Ed25519", ""},
39
            {"ML-DSA", "ML-DSA-6x5"},
40
            {"ML-KEM", "ML-KEM-768"},
41
         };
×
42

43
         for(const auto& [algo, params] : keygen_algos) {
×
44
            auto sk = Botan::create_private_key(algo, rng, params);
×
45

46
            if(!sk) {
×
47
               continue;
×
48
            }
49

50
            const auto pk = sk->public_key();
×
51

52
            const std::string nm = params.empty() ? algo : Botan::fmt("{} {}", algo, params);
×
53

54
            auto pk_parse = config.make_timer(nm, 1, "public key parse");
×
55
            const auto pk_bytes = pk->subject_public_key();
×
56
            pk_parse->run_until_elapsed(runtime, [&]() { Botan::X509::load_key(pk_bytes); });
×
57
            config.record_result(*pk_parse);
×
58

59
            auto sk_parse = config.make_timer(nm, 1, "private key parse");
×
60
            const auto sk_bytes = sk->private_key_info();
×
61
            sk_parse->run_until_elapsed(runtime, [&]() { Botan::PKCS8::load_key(sk_bytes); });
×
62
            config.record_result(*sk_parse);
×
63
         }
×
64
      }
×
65
};
66

67
BOTAN_REGISTER_PERF_TEST("key_parsing", PerfTest_PKKeyParsing);
×
68

69
#endif
70

71
#if defined(BOTAN_HAS_RSA)
72

73
class PerfTest_RSAKeyGen final : public PerfTest {
1✔
74
   public:
75
      void go(const PerfConfig& config) override {
1✔
76
         const auto runtime = config.runtime();
1✔
77
         auto& rng = config.rng();
1✔
78

79
         for(size_t keylen : {1024, 2048, 3072, 4096}) {
5✔
80
            const std::string nm = Botan::fmt("RSA-{}", keylen);
4✔
81
            auto keygen_timer = config.make_timer(nm, 1, "keygen");
8✔
82

83
            while(keygen_timer->under(runtime)) {
8✔
84
               auto key =
4✔
85
                  keygen_timer->run([&] { return Botan::create_private_key("RSA", rng, std::to_string(keylen)); });
8✔
86

87
               BOTAN_ASSERT(key->check_key(rng, true), "Key is ok");
4✔
88
            }
4✔
89

90
            config.record_result(*keygen_timer);
8✔
91
         }
4✔
92
      }
1✔
93
};
94

95
BOTAN_REGISTER_PERF_TEST("RSA_keygen", PerfTest_RSAKeyGen);
1✔
96

97
#endif
98

99
#if defined(BOTAN_HAS_ECDSA)
100

101
class PerfTest_ECDSAKeyRec final : public PerfTest {
1✔
102
   public:
103
      void go(const PerfConfig& config) override {
1✔
104
         const auto runtime = config.runtime();
1✔
105
         auto& rng = config.rng();
1✔
106

107
         for(const std::string& group_name : config.ecc_groups()) {
7✔
108
            const auto group = Botan::EC_Group::from_name(group_name);
6✔
109
            auto recovery_timer = config.make_timer("ECDSA recovery " + group_name);
12✔
110

111
            while(recovery_timer->under(runtime)) {
14✔
112
               Botan::ECDSA_PrivateKey key(rng, group);
8✔
113

114
               std::vector<uint8_t> message(group.get_order_bits() / 8);
8✔
115
               rng.randomize(message.data(), message.size());
8✔
116

117
               Botan::PK_Signer signer(key, rng, "Raw");
8✔
118
               signer.update(message);
8✔
119
               std::vector<uint8_t> signature = signer.signature(rng);
8✔
120

121
               Botan::PK_Verifier verifier(key, "Raw", Botan::Signature_Format::Standard, "base");
8✔
122
               verifier.update(message);
8✔
123
               BOTAN_ASSERT(verifier.check_signature(signature), "Valid signature");
8✔
124

125
               Botan::BigInt r(signature.data(), signature.size() / 2);
8✔
126
               Botan::BigInt s(signature.data() + signature.size() / 2, signature.size() / 2);
8✔
127

128
               const uint8_t v = key.recovery_param(message, r, s);
8✔
129

130
               recovery_timer->run([&]() {
8✔
131
                  Botan::ECDSA_PublicKey recovered_key(group, message, r, s, v);
8✔
132
                  BOTAN_ASSERT(recovered_key.public_key_bits() == key.public_key_bits(),
24✔
133
                               "Recovered public key correctly");
134
               });
8✔
135
            }
24✔
136

137
            config.record_result(*recovery_timer);
12✔
138
         }
6✔
139
      }
1✔
140
};
141

142
BOTAN_REGISTER_PERF_TEST("ecdsa_recovery", PerfTest_ECDSAKeyRec);
1✔
143

144
#endif
145

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