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

randombit / botan / 29673219783

18 Jul 2026 10:42PM UTC coverage: 89.416% (+0.009%) from 89.407%
29673219783

push

github

randombit
Fix EC_Scalar_Data_BN::square_self

It computed the square then failed to update the stored value

114352 of 127887 relevant lines covered (89.42%)

10766049.99 hits per line

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

93.0
/src/tests/test_ecdh.cpp
1
/*
2
* (C) 2015,2016 Jack Lloyd
3
*
4
* Botan is released under the Simplified BSD License (see license.txt)
5
*/
6

7
#include "tests.h"
8

9
#if defined(BOTAN_HAS_ECDH)
10
   #include "test_pubkey.h"
11
   #include <botan/asn1_obj.h>
12
   #include <botan/ec_group.h>
13
   #include <botan/ecdh.h>
14
   #include <botan/pubkey.h>
15
#endif
16

17
namespace Botan_Tests {
18

19
namespace {
20

21
#if defined(BOTAN_HAS_ECDH)
22

23
class ECDH_KAT_Tests final : public PK_Key_Agreement_Test {
24
   public:
25
      ECDH_KAT_Tests() : PK_Key_Agreement_Test("ECDH", "pubkey/ecdh.vec", "Secret,CounterKey,K", "KDF") {}
2✔
26

27
      std::string default_kdf(const VarMap& /*unused*/) const override { return "Raw"; }
156✔
28

29
      bool skip_this_test(const std::string& group_id, const VarMap& /*vars*/) override {
156✔
30
         return !Botan::EC_Group::supports_named_group(group_id);
156✔
31
      }
32

33
      std::unique_ptr<Botan::Private_Key> load_our_key(const std::string& group_id, const VarMap& vars) override {
156✔
34
         const auto group = Botan::EC_Group::from_name(group_id);
156✔
35
         const Botan::BigInt secret = vars.get_req_bn("Secret");
156✔
36
         return std::make_unique<Botan::ECDH_PrivateKey>(this->rng(), group, secret);
468✔
37
      }
156✔
38

39
      std::vector<uint8_t> load_their_key(const std::string& /*header*/, const VarMap& vars) override {
156✔
40
         return vars.get_req_bin("CounterKey");
156✔
41
      }
42
};
43

44
class ECDH_Keygen_Tests final : public PK_Key_Generation_Test {
1✔
45
   public:
46
      std::vector<std::string> keygen_params() const override {
1✔
47
         return {
1✔
48
            "secp256r1", "secp384r1", "secp521r1", "brainpool256r1", "brainpool384r1", "brainpool512r1", "frp256v1"};
1✔
49
      }
50

51
      std::string algo_name() const override { return "ECDH"; }
7✔
52

53
      std::unique_ptr<Botan::Public_Key> public_key_from_raw(std::string_view keygen_params,
7✔
54
                                                             std::string_view /* provider */,
55
                                                             std::span<const uint8_t> raw_pk) const override {
56
         const auto group = Botan::EC_Group(keygen_params);
7✔
57
         const auto public_key = Botan::EC_AffinePoint(group, raw_pk);
7✔
58
         return std::make_unique<Botan::ECDH_PublicKey>(group, public_key);
21✔
59
      }
7✔
60
};
61

62
class ECDH_AllGroups_Tests : public Test {
1✔
63
   public:
64
      std::vector<Test::Result> run() override {
1✔
65
         std::vector<Test::Result> results;
1✔
66

67
         for(const std::string& group_name : Botan::EC_Group::known_named_groups()) {
29✔
68
            Test::Result result("ECDH " + group_name);
28✔
69

70
            result.start_timer();
28✔
71

72
            const std::string kdf = "Raw";
28✔
73

74
            try {
28✔
75
               const auto group = Botan::EC_Group::from_name(group_name);
28✔
76

77
               // Regression test: prohibit loading an all-zero private key
78
               result.test_throws<Botan::Invalid_Argument>("all-zero private key is unacceptable", [&] {
28✔
79
                  const auto one = Botan::EC_Scalar::one(group);
28✔
80
                  const auto zero = one - one;  // NOLINT(*-redundant-expression)
28✔
81
                  Botan::ECDH_PrivateKey(group, zero);
28✔
82
               });
56✔
83

84
               // Regression test: prohibit loading a public point that is the identity (point at infinity)
85
               result.test_throws<Botan::Invalid_Argument>("point at infinity isn't a valid public key", [&] {
28✔
86
                  const auto infinity = Botan::EC_AffinePoint::identity(group);
28✔
87
                  Botan::ECDH_PublicKey(group, infinity);
28✔
88
               });
28✔
89

90
               // Regression test: prohibit ECDH-agreement with all-zero public value
91
               result.test_throws<Botan::Decoding_Error>("ECDH public value is point-at-infinity", [&] {
28✔
92
                  const auto sk = Botan::ECDH_PrivateKey(rng(), group);
28✔
93
                  const Botan::PK_Key_Agreement ka(sk, rng(), kdf);
28✔
94
                  std::vector<uint8_t> sec1_infinity(1, 0x00);
28✔
95
                  const auto a_ss = ka.derive_key(0, sec1_infinity);
28✔
96
               });
56✔
97

98
               // Regression test: prohibit loading a point not on the curve
99
               result.test_throws<Botan::Decoding_Error>("point is not on curve", [&] {
28✔
100
                  const auto& base_point = Botan::EC_AffinePoint::generator(group);
28✔
101
                  auto encoded = base_point.serialize_uncompressed();
28✔
102
                  encoded[3] -= 1;
28✔
103

104
                  const Botan::ECDH_PrivateKey a_priv(rng(), group);
28✔
105
                  const auto a_pub = a_priv.public_value();
28✔
106
                  const Botan::PK_Key_Agreement a_ka(a_priv, rng(), kdf);
56✔
107
                  const auto a_ss = a_ka.derive_key(0, encoded);
28✔
108
               });
84✔
109

110
               for(size_t i = 0; i != 100; ++i) {
2,828✔
111
                  const Botan::ECDH_PrivateKey a_priv(rng(), group);
2,800✔
112
                  const auto a_pub = a_priv.public_value();
2,800✔
113

114
                  const Botan::ECDH_PrivateKey b_priv(rng(), group);
2,800✔
115
                  const auto b_pub = b_priv.public_value();
2,800✔
116

117
                  const Botan::PK_Key_Agreement a_ka(a_priv, rng(), kdf);
2,800✔
118
                  const auto a_ss = a_ka.derive_key(0, b_pub);
2,800✔
119

120
                  const Botan::PK_Key_Agreement b_ka(b_priv, rng(), kdf);
2,800✔
121
                  const auto b_ss = b_ka.derive_key(0, a_pub);
2,800✔
122

123
                  result.test_bin_eq("Same shared secret", a_ss.bits_of(), b_ss.bits_of());
8,400✔
124
               }
11,200✔
125
            } catch(std::exception& e) {
28✔
126
               result.test_failure("Exception", e.what());
×
127
            }
×
128

129
            result.end_timer();
28✔
130

131
            results.push_back(result);
28✔
132
         }
28✔
133

134
         return results;
1✔
135
      }
×
136
};
137

138
/**
139
 * @brief Testing PK key decoding
140
 */
141
class ECC_Private_Key_Param_Decoding_Test : public Text_Based_Test {
×
142
   public:
143
      ECC_Private_Key_Param_Decoding_Test() : Text_Based_Test("pubkey/ecc-key-and-param.vec", "key,param,valid") {}
2✔
144

145
   protected:
146
      Test::Result run_one_test(const std::string& /*header*/, const VarMap& vars) final {
5✔
147
         const auto key_bin = vars.get_req_bin("key");
5✔
148
         const auto param_str = vars.get_req_str("param");
5✔
149
         const auto valid_pair = vars.get_req_bool("valid");
5✔
150

151
         Test::Result result("ECC Private Key Decoding with external AlgorithmIdentifier parameter");
5✔
152
         try {
5✔
153
            const auto alg_id = [&]() {
10✔
154
               const auto oid_ecdh = Botan::OID("1.3.132.1.12");
5✔
155
               if(param_str.empty()) {
5✔
156
                  return Botan::AlgorithmIdentifier(oid_ecdh,
2✔
157
                                                    Botan::AlgorithmIdentifier::Encoding_Option::USE_EMPTY_PARAM);
2✔
158
               }
159
               const auto enc_param = Botan::OID(param_str).BER_encode();
3✔
160
               return Botan::AlgorithmIdentifier(oid_ecdh, enc_param);
3✔
161
            };
8✔
162
            const auto create_key = [&]() { const Botan::ECDH_PrivateKey priv_key(alg_id(), key_bin); };
5✔
163
            if(valid_pair) {
5✔
164
               create_key();
3✔
165
               result.test_success("deserialize valid combination of ECC private key and AlgorithmIdentifier");
3✔
166
            } else {
167
               result.test_throws(
2✔
168
                  "exception when decoding invalid pair of private key group parameters and AlgorithmIdentifier",
169
                  [&]() { create_key(); });
4✔
170
            }
171
         } catch(Botan::Exception& e) {
×
172
            result.test_failure("Failed to deserialize key", e.what());
×
173
         }
×
174
         return result;
5✔
175
      }
10✔
176
};
177

178
BOTAN_REGISTER_TEST("pubkey", "ecdh_kat", ECDH_KAT_Tests);
179
BOTAN_REGISTER_TEST("pubkey", "ecdh_keygen", ECDH_Keygen_Tests);
180
BOTAN_REGISTER_TEST("pubkey", "ecdh_all_groups", ECDH_AllGroups_Tests);
181
BOTAN_REGISTER_TEST("pubkey", "ecc_key_and_params", ECC_Private_Key_Param_Decoding_Test);
182

183
#endif
184

185
}  // namespace
186

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

© 2026 Coveralls, Inc