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

randombit / botan / 5111374265

29 May 2023 11:19AM UTC coverage: 92.227% (+0.5%) from 91.723%
5111374265

push

github

randombit
Next release will be 3.1.0. Update release notes

75588 of 81959 relevant lines covered (92.23%)

11886470.91 hits per line

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

92.23
/src/tests/test_mceliece.cpp
1
/*
2
* (C) 2014 cryptosource GmbH
3
* (C) 2014 Falko Strenzke fstrenzke@cryptosource.de
4
* (C) 2014,2015 Jack Lloyd
5
*
6
* Botan is released under the Simplified BSD License (see license.txt)
7
*/
8

9
#include "tests.h"
10

11
#if defined(BOTAN_HAS_MCELIECE)
12

13
   #include <botan/hash.h>
14
   #include <botan/hex.h>
15
   #include <botan/mceliece.h>
16
   #include <botan/pubkey.h>
17
   #include <botan/internal/loadstor.h>
18

19
   #if defined(BOTAN_HAS_HMAC_DRBG)
20
      #include <botan/hmac_drbg.h>
21
   #endif
22

23
#endif
24

25
namespace Botan_Tests {
26

27
namespace {
28

29
#if defined(BOTAN_HAS_MCELIECE)
30

31
   #if defined(BOTAN_HAS_HMAC_DRBG) && defined(BOTAN_HAS_SHA2_32) && defined(BOTAN_HAS_SHA2_64)
32
class McEliece_Keygen_Encrypt_Test final : public Text_Based_Test {
×
33
   public:
34
      McEliece_Keygen_Encrypt_Test() :
1✔
35
            Text_Based_Test("pubkey/mce.vec",
36
                            "McElieceSeed,KeyN,KeyT,PublicKeyFingerprint,PrivateKeyFingerprint,"
37
                            "EncryptPRNGSeed,SharedKey,Ciphertext",
38
                            "") {}
3✔
39

40
      Test::Result run_one_test(const std::string& /*header*/, const VarMap& vars) override {
6✔
41
         const std::vector<uint8_t> keygen_seed = vars.get_req_bin("McElieceSeed");
6✔
42
         const std::vector<uint8_t> fprint_pub = vars.get_req_bin("PublicKeyFingerprint");
6✔
43
         const std::vector<uint8_t> fprint_priv = vars.get_req_bin("PrivateKeyFingerprint");
6✔
44
         const std::vector<uint8_t> encrypt_seed = vars.get_req_bin("EncryptPRNGSeed");
6✔
45
         const std::vector<uint8_t> ciphertext = vars.get_req_bin("Ciphertext");
6✔
46
         const std::vector<uint8_t> shared_key = vars.get_req_bin("SharedKey");
6✔
47
         const size_t keygen_n = vars.get_req_sz("KeyN");
6✔
48
         const size_t keygen_t = vars.get_req_sz("KeyT");
6✔
49

50
         Test::Result result("McEliece keygen");
6✔
51
         result.start_timer();
6✔
52

53
         if(Test::run_long_tests() == false && keygen_n > 3072) {
6✔
54
            result.test_note("Skipping because long");
×
55
            return result;
×
56
         }
57

58
         Botan::HMAC_DRBG rng("SHA-384");
6✔
59
         rng.initialize_with(keygen_seed.data(), keygen_seed.size());
6✔
60
         Botan::McEliece_PrivateKey mce_priv(rng, keygen_n, keygen_t);
6✔
61

62
         result.test_eq("public key fingerprint", hash_bytes(mce_priv.public_key_bits()), fprint_pub);
18✔
63
         result.test_eq("private key fingerprint", hash_bytes(mce_priv.private_key_bits()), fprint_priv);
18✔
64

65
         rng.clear();
6✔
66
         rng.initialize_with(encrypt_seed.data(), encrypt_seed.size());
6✔
67

68
         try {
6✔
69
            Botan::PK_KEM_Encryptor kem_enc(mce_priv, "KDF1(SHA-512)");
6✔
70
            Botan::PK_KEM_Decryptor kem_dec(mce_priv, Test::rng(), "KDF1(SHA-512)");
6✔
71

72
            Botan::secure_vector<uint8_t> encap_key, prod_shared_key;
6✔
73
            kem_enc.encrypt(encap_key, prod_shared_key, 64, rng);
6✔
74

75
            Botan::secure_vector<uint8_t> dec_shared_key = kem_dec.decrypt(encap_key.data(), encap_key.size(), 64);
6✔
76

77
            result.test_eq("ciphertext", encap_key, ciphertext);
6✔
78
            result.test_eq("encrypt shared", prod_shared_key, shared_key);
6✔
79
            result.test_eq("decrypt shared", dec_shared_key, shared_key);
12✔
80
         } catch(Botan::Lookup_Error&) {}
18✔
81

82
         result.end_timer();
6✔
83
         return result;
6✔
84
      }
42✔
85

86
   private:
87
      static std::vector<uint8_t> hash_bytes(const uint8_t b[], size_t len, const std::string& hash_fn = "SHA-256") {
12✔
88
         auto hash = Botan::HashFunction::create(hash_fn);
12✔
89
         hash->update(b, len);
12✔
90
         std::vector<uint8_t> r(hash->output_length());
12✔
91
         hash->final(r.data());
12✔
92
         return r;
12✔
93
      }
12✔
94

95
      template <typename A>
96
      std::vector<uint8_t> hash_bytes(const std::vector<uint8_t, A>& v) {
12✔
97
         return hash_bytes(v.data(), v.size());
24✔
98
      }
99
};
100

101
BOTAN_REGISTER_TEST("pubkey", "mce_keygen", McEliece_Keygen_Encrypt_Test);
102
   #endif
103

104
   #if defined(BOTAN_HAS_SHA2_32)
105

106
class McEliece_Tests final : public Test {
×
107
   public:
108
      static std::string fingerprint(const Botan::Private_Key& key, const std::string& hash_algo = "SHA-256") {
170✔
109
         auto hash = Botan::HashFunction::create(hash_algo);
170✔
110
         if(!hash) {
170✔
111
            throw Test_Error("Hash " + hash_algo + " not available");
×
112
         }
113

114
         hash->update(key.private_key_bits());
170✔
115
         return Botan::hex_encode(hash->final());
340✔
116
      }
170✔
117

118
      static std::string fingerprint(const Botan::Public_Key& key, const std::string& hash_algo = "SHA-256") {
170✔
119
         auto hash = Botan::HashFunction::create(hash_algo);
170✔
120
         if(!hash) {
170✔
121
            throw Test_Error("Hash " + hash_algo + " not available");
×
122
         }
123

124
         hash->update(key.public_key_bits());
170✔
125
         return Botan::hex_encode(hash->final());
340✔
126
      }
170✔
127

128
      std::vector<Test::Result> run() override {
1✔
129
         struct keygen_params {
1✔
130
               size_t code_length, t_min, t_max;
131
         };
132

133
         const keygen_params param_sets[] = {
1✔
134
            {256, 5, 15}, {512, 5, 33}, {1024, 15, 35}, {2048, 33, 50}, {6624, 110, 115}};
135

136
         std::vector<Test::Result> results;
1✔
137

138
         for(size_t i = 0; i < sizeof(param_sets) / sizeof(param_sets[0]); ++i) {
6✔
139
            if(Test::run_long_tests() == false && param_sets[i].code_length >= 2048) {
5✔
140
               continue;
×
141
            }
142

143
            for(size_t t = param_sets[i].t_min; t <= param_sets[i].t_max; ++t) {
90✔
144
               Test::Result result("McEliece keygen");
85✔
145
               result.start_timer();
85✔
146

147
               Botan::McEliece_PrivateKey sk1(Test::rng(), param_sets[i].code_length, t);
85✔
148
               const Botan::McEliece_PublicKey& pk1 = sk1;
85✔
149

150
               const std::vector<uint8_t> pk_enc = pk1.public_key_bits();
85✔
151
               const Botan::secure_vector<uint8_t> sk_enc = sk1.private_key_bits();
85✔
152

153
               Botan::McEliece_PublicKey pk(pk_enc);
85✔
154
               Botan::McEliece_PrivateKey sk(sk_enc);
85✔
155

156
               result.test_eq("decoded public key equals original", fingerprint(pk1), fingerprint(pk));
425✔
157
               result.test_eq("decoded private key equals original", fingerprint(sk1), fingerprint(sk));
340✔
158
               result.test_eq("key validation passes", sk.check_key(Test::rng(), false), true);
85✔
159
               result.end_timer();
85✔
160

161
               result.end_timer();
85✔
162

163
               results.push_back(result);
85✔
164

165
      #if defined(BOTAN_HAS_KDF2)
166
               results.push_back(test_kem(sk, pk));
170✔
167
      #endif
168
            }
255✔
169
         }
170

171
         return results;
1✔
172
      }
×
173

174
   private:
175
      static Test::Result test_kem(const Botan::McEliece_PrivateKey& sk, const Botan::McEliece_PublicKey& pk) {
85✔
176
         Test::Result result("McEliece KEM");
85✔
177
         result.start_timer();
85✔
178

179
         Botan::PK_KEM_Encryptor enc_op(pk, "KDF2(SHA-256)");
85✔
180
         Botan::PK_KEM_Decryptor dec_op(sk, Test::rng(), "KDF2(SHA-256)");
85✔
181

182
         const size_t trials = (Test::run_long_tests() ? 30 : 10);
85✔
183
         for(size_t i = 0; i < trials; i++) {
2,635✔
184
            Botan::secure_vector<uint8_t> salt = Test::rng().random_vec(i);
2,550✔
185

186
            Botan::secure_vector<uint8_t> encap_key, shared_key;
2,550✔
187
            enc_op.encrypt(encap_key, shared_key, 64, Test::rng(), salt);
2,550✔
188

189
            Botan::secure_vector<uint8_t> shared_key2 = dec_op.decrypt(encap_key, 64, salt);
2,550✔
190

191
            result.test_eq("same key", shared_key, shared_key2);
5,100✔
192
         }
10,115✔
193
         result.end_timer();
85✔
194
         return result;
85✔
195
      }
85✔
196
};
197

198
BOTAN_REGISTER_TEST("pubkey", "mceliece", McEliece_Tests);
199

200
   #endif
201

202
#endif
203

204
}  // namespace
205

206
}  // namespace Botan_Tests
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