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

randombit / botan / 5079590438

25 May 2023 12:28PM UTC coverage: 92.228% (+0.5%) from 91.723%
5079590438

Pull #3502

github

Pull Request #3502: Apply clang-format to the codebase

75589 of 81959 relevant lines covered (92.23%)

12139530.51 hits per line

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

91.67
/src/tests/test_ecdsa.cpp
1
/*
2
* (C) 2014,2015 Jack Lloyd
3
* (C) 2017 René Korthaus, Rohde & Schwarz Cybersecurity
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7

8
#include "tests.h"
9

10
#include "test_rng.h"
11

12
#if defined(BOTAN_HAS_ECDSA)
13
   #include "test_pubkey.h"
14
   #include <botan/ecdsa.h>
15
   #include <botan/pk_algs.h>
16
#endif
17

18
namespace Botan_Tests {
19

20
namespace {
21

22
#if defined(BOTAN_HAS_ECDSA)
23

24
class ECDSA_Verification_Tests final : public PK_Signature_Verification_Test {
×
25
   public:
26
      ECDSA_Verification_Tests() :
1✔
27
            PK_Signature_Verification_Test("ECDSA", "pubkey/ecdsa_verify.vec", "Group,Px,Py,Msg,Signature", "Valid") {}
4✔
28

29
      bool clear_between_callbacks() const override { return false; }
16✔
30

31
      std::unique_ptr<Botan::Public_Key> load_public_key(const VarMap& vars) override {
16✔
32
         const std::string group_id = vars.get_req_str("Group");
16✔
33
         const BigInt px = vars.get_req_bn("Px");
16✔
34
         const BigInt py = vars.get_req_bn("Py");
16✔
35
         Botan::EC_Group group(Botan::OID::from_string(group_id));
16✔
36

37
         const Botan::EC_Point public_point = group.point(px, py);
16✔
38

39
         return std::make_unique<Botan::ECDSA_PublicKey>(group, public_point);
32✔
40
      }
48✔
41

42
      std::string default_padding(const VarMap& /*unused*/) const override { return "Raw"; }
16✔
43
};
44

45
class ECDSA_Wycheproof_Verification_Tests final : public PK_Signature_Verification_Test {
×
46
   public:
47
      ECDSA_Wycheproof_Verification_Tests() :
1✔
48
            PK_Signature_Verification_Test(
49
               "ECDSA", "pubkey/ecdsa_wycheproof.vec", "Group,Px,Py,Hash,Msg,Signature,Valid") {}
4✔
50

51
      bool clear_between_callbacks() const override { return false; }
11,864✔
52

53
      Botan::Signature_Format sig_format() const override { return Botan::Signature_Format::DerSequence; }
47,456✔
54

55
      bool test_random_invalid_sigs() const override { return false; }
3,475✔
56

57
      std::unique_ptr<Botan::Public_Key> load_public_key(const VarMap& vars) override {
11,864✔
58
         const std::string group_id = vars.get_req_str("Group");
11,864✔
59
         const BigInt px = vars.get_req_bn("Px");
11,864✔
60
         const BigInt py = vars.get_req_bn("Py");
11,864✔
61
         Botan::EC_Group group(Botan::OID::from_string(group_id));
11,864✔
62

63
         const Botan::EC_Point public_point = group.point(px, py);
11,864✔
64

65
         return std::make_unique<Botan::ECDSA_PublicKey>(group, public_point);
23,728✔
66
      }
35,592✔
67

68
      std::string default_padding(const VarMap& vars) const override { return vars.get_req_str("Hash"); }
23,728✔
69
};
70

71
class ECDSA_Signature_KAT_Tests final : public PK_Signature_Generation_Test {
×
72
   public:
73
      ECDSA_Signature_KAT_Tests() :
1✔
74
            PK_Signature_Generation_Test("ECDSA",
75
   #if defined(BOTAN_HAS_RFC6979_GENERATOR)
76
                                         "pubkey/ecdsa_rfc6979.vec",
77
                                         "Group,X,Hash,Msg,Signature") {
4✔
78
      }
1✔
79
   #else
80
                                         "pubkey/ecdsa_prob.vec",
81
                                         "Group,X,Hash,Msg,Nonce,Signature") {
82
      }
83
   #endif
84

85
      bool clear_between_callbacks() const override { return false; }
104✔
86

87
      std::unique_ptr<Botan::Private_Key> load_private_key(const VarMap& vars) override {
104✔
88
         const std::string group_id = vars.get_req_str("Group");
104✔
89
         const BigInt x = vars.get_req_bn("X");
104✔
90
         Botan::EC_Group group(Botan::OID::from_string(group_id));
104✔
91

92
         return std::make_unique<Botan::ECDSA_PrivateKey>(Test::rng(), group, x);
208✔
93
      }
208✔
94

95
      std::string default_padding(const VarMap& vars) const override { return vars.get_req_str("Hash"); }
208✔
96

97
   #if !defined(BOTAN_HAS_RFC6979_GENERATOR)
98
      std::unique_ptr<Botan::RandomNumberGenerator> test_rng(const std::vector<uint8_t>& nonce) const override {
99
         // probabilistic ecdsa signature generation extracts more random than just the nonce,
100
         // but the nonce is extracted first
101
         return std::make_unique<Fixed_Output_Position_RNG>(nonce, 1);
102
      }
103
   #endif
104
};
105

106
class ECDSA_KAT_Verification_Tests final : public PK_Signature_Verification_Test {
×
107
   public:
108
      ECDSA_KAT_Verification_Tests() :
1✔
109
            PK_Signature_Verification_Test("ECDSA",
110
   #if !defined(BOTAN_HAS_RFC6979_GENERATOR)
111
                                           "pubkey/ecdsa_rfc6979.vec",
112
                                           "Group,X,Hash,Msg,Signature") {
113
      }
114
   #else
115
                                           "pubkey/ecdsa_prob.vec",
116
                                           "Group,X,Hash,Msg,Nonce,Signature") {
4✔
117
      }
1✔
118
   #endif
119

120
      bool clear_between_callbacks() const override { return false; }
187✔
121

122
      std::unique_ptr<Botan::Public_Key> load_public_key(const VarMap& vars) override {
187✔
123
         const std::string group_id = vars.get_req_str("Group");
187✔
124
         const BigInt x = vars.get_req_bn("X");
187✔
125
         Botan::EC_Group group(Botan::OID::from_string(group_id));
187✔
126

127
         Botan::ECDSA_PrivateKey priv_key(Test::rng(), group, x);
187✔
128

129
         return priv_key.public_key();
187✔
130
      }
374✔
131

132
      std::string default_padding(const VarMap& vars) const override { return vars.get_req_str("Hash"); }
374✔
133
};
134

135
class ECDSA_Sign_Verify_DER_Test final : public PK_Sign_Verify_DER_Test {
×
136
   public:
137
      ECDSA_Sign_Verify_DER_Test() : PK_Sign_Verify_DER_Test("ECDSA", "SHA-512") {}
2✔
138

139
      std::unique_ptr<Botan::Private_Key> key() const override {
1✔
140
         return Botan::create_private_key("ECDSA", Test::rng(), "secp256r1");
1✔
141
      }
142
};
143

144
class ECDSA_Keygen_Tests final : public PK_Key_Generation_Test {
×
145
   public:
146
      std::vector<std::string> keygen_params() const override {
1✔
147
         return {"secp256r1", "secp384r1", "secp521r1", "frp256v1"};
5✔
148
      }
149

150
      std::string algo_name() const override { return "ECDSA"; }
12✔
151
};
152

153
class ECDSA_Keygen_Stability_Tests final : public PK_Key_Generation_Stability_Test {
×
154
   public:
155
      ECDSA_Keygen_Stability_Tests() : PK_Key_Generation_Stability_Test("ECDSA", "pubkey/ecdsa_keygen.vec") {}
3✔
156
};
157

158
   #if defined(BOTAN_HAS_EMSA_RAW)
159

160
class ECDSA_Key_Recovery_Tests final : public Text_Based_Test {
×
161
   public:
162
      ECDSA_Key_Recovery_Tests() :
1✔
163
            Text_Based_Test("pubkey/ecdsa_key_recovery.vec", "Group,Msg,R,S,V,PubkeyX,PubkeyY") {}
3✔
164

165
      Test::Result run_one_test(const std::string& /*header*/, const VarMap& vars) override {
2✔
166
         Test::Result result("ECDSA key recovery");
2✔
167

168
         const std::string group_id = vars.get_req_str("Group");
2✔
169
         Botan::EC_Group group(group_id);
2✔
170

171
         const BigInt R = vars.get_req_bn("R");
2✔
172
         const BigInt S = vars.get_req_bn("S");
2✔
173
         const uint8_t V = vars.get_req_u8("V");
2✔
174
         const std::vector<uint8_t> msg = vars.get_req_bin("Msg");
2✔
175
         const BigInt pubkey_x = vars.get_req_bn("PubkeyX");
2✔
176
         const BigInt pubkey_y = vars.get_req_bn("PubkeyY");
2✔
177

178
         try {
2✔
179
            Botan::ECDSA_PublicKey pubkey(group, msg, R, S, V);
2✔
180
            result.test_eq("Pubkey X coordinate", pubkey.public_point().get_affine_x(), pubkey_x);
4✔
181
            result.test_eq("Pubkey Y coordinate", pubkey.public_point().get_affine_y(), pubkey_y);
4✔
182

183
            const uint8_t computed_V = pubkey.recovery_param(msg, R, S);
2✔
184
            result.test_eq("Recovery param is correct", static_cast<size_t>(computed_V), static_cast<size_t>(V));
2✔
185

186
            Botan::PK_Verifier verifier(pubkey, "Raw");
2✔
187

188
            auto sig = Botan::BigInt::encode_fixed_length_int_pair(R, S, group.get_order_bytes());
2✔
189

190
            result.confirm("Signature verifies", verifier.verify_message(msg, sig));
6✔
191
         } catch(Botan::Exception& e) { result.test_failure("Failed to recover ECDSA public key", e.what()); }
2✔
192

193
         return result;
2✔
194
      }
10✔
195
};
196

197
BOTAN_REGISTER_TEST("pubkey", "ecdsa_key_recovery", ECDSA_Key_Recovery_Tests);
198

199
   #endif
200

201
class ECDSA_Invalid_Key_Tests final : public Text_Based_Test {
×
202
   public:
203
      ECDSA_Invalid_Key_Tests() : Text_Based_Test("pubkey/ecdsa_invalid.vec", "Group,InvalidKeyX,InvalidKeyY") {}
3✔
204

205
      bool clear_between_callbacks() const override { return false; }
78✔
206

207
      Test::Result run_one_test(const std::string& /*header*/, const VarMap& vars) override {
78✔
208
         Test::Result result("ECDSA invalid keys");
78✔
209

210
         const std::string group_id = vars.get_req_str("Group");
78✔
211
         Botan::EC_Group group(Botan::OID::from_string(group_id));
78✔
212
         const Botan::BigInt x = vars.get_req_bn("InvalidKeyX");
78✔
213
         const Botan::BigInt y = vars.get_req_bn("InvalidKeyY");
78✔
214

215
         std::unique_ptr<Botan::EC_Point> public_point;
78✔
216

217
         try {
78✔
218
            public_point = std::make_unique<Botan::EC_Point>(group.point(x, y));
117✔
219
         } catch(Botan::Invalid_Argument&) {
39✔
220
            // EC_Point() performs a range check on x, y in [0, p−1],
221
            // which is also part of the EC public key checks, e.g.,
222
            // in NIST SP800-56A rev2, sec. 5.6.2.3.2
223
            result.test_success("public key fails check");
39✔
224
            return result;
39✔
225
         }
39✔
226

227
         auto key = std::make_unique<Botan::ECDSA_PublicKey>(group, *public_point);
39✔
228
         result.test_eq("public key fails check", key->check_key(Test::rng(), false), false);
39✔
229
         return result;
39✔
230
      }
234✔
231
};
232

233
BOTAN_REGISTER_TEST("pubkey", "ecdsa_verify", ECDSA_Verification_Tests);
234
BOTAN_REGISTER_TEST("pubkey", "ecdsa_verify_wycheproof", ECDSA_Wycheproof_Verification_Tests);
235
BOTAN_REGISTER_TEST("pubkey", "ecdsa_sign", ECDSA_Signature_KAT_Tests);
236
BOTAN_REGISTER_TEST("pubkey", "ecdsa_verify_kat", ECDSA_KAT_Verification_Tests);
237
BOTAN_REGISTER_TEST("pubkey", "ecdsa_sign_verify_der", ECDSA_Sign_Verify_DER_Test);
238
BOTAN_REGISTER_TEST("pubkey", "ecdsa_keygen", ECDSA_Keygen_Tests);
239
BOTAN_REGISTER_TEST("pubkey", "ecdsa_keygen_stability", ECDSA_Keygen_Stability_Tests);
240
BOTAN_REGISTER_TEST("pubkey", "ecdsa_invalid", ECDSA_Invalid_Key_Tests);
241

242
#endif
243

244
}
245

246
}
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

© 2025 Coveralls, Inc