Coverage Report

Created: 2024-11-29 06:10

/src/botan/src/lib/pubkey/classic_mceliece/cmce_parameters.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Classic McEliece Parameters
3
 * (C) 2023 Jack Lloyd
4
 *     2023,2024 Fabian Albert, Amos Treiber - Rohde & Schwarz Cybersecurity
5
 *
6
 * Botan is released under the Simplified BSD License (see license.txt)
7
 **/
8
9
#include <botan/internal/cmce_parameters.h>
10
#include <botan/internal/cmce_poly.h>
11
12
namespace Botan {
13
14
namespace {
15
16
0
CmceGfMod determine_poly_f(Classic_McEliece_Parameter_Set param_set) {
17
0
   switch(param_set.code()) {
18
0
      case Classic_McEliece_Parameter_Set::mceliece348864:
19
0
      case Classic_McEliece_Parameter_Set::mceliece348864f:
20
         // z^12 + z^3 + 1
21
0
         return CmceGfMod(0b0001000000001001);
22
0
      case Classic_McEliece_Parameter_Set::mceliece460896:
23
0
      case Classic_McEliece_Parameter_Set::mceliece460896f:
24
0
      case Classic_McEliece_Parameter_Set::mceliece6688128:
25
0
      case Classic_McEliece_Parameter_Set::mceliece6688128f:
26
0
      case Classic_McEliece_Parameter_Set::mceliece6688128pc:
27
0
      case Classic_McEliece_Parameter_Set::mceliece6688128pcf:
28
0
      case Classic_McEliece_Parameter_Set::mceliece6960119:
29
0
      case Classic_McEliece_Parameter_Set::mceliece6960119f:
30
0
      case Classic_McEliece_Parameter_Set::mceliece6960119pc:
31
0
      case Classic_McEliece_Parameter_Set::mceliece6960119pcf:
32
0
      case Classic_McEliece_Parameter_Set::mceliece8192128:
33
0
      case Classic_McEliece_Parameter_Set::mceliece8192128f:
34
0
      case Classic_McEliece_Parameter_Set::mceliece8192128pc:
35
0
      case Classic_McEliece_Parameter_Set::mceliece8192128pcf:
36
         // z^12 + z^3 + 1
37
0
         return CmceGfMod(0b0010000000011011);
38
0
   }
39
0
   BOTAN_ASSERT_UNREACHABLE();
40
0
}
41
42
0
Classic_McEliece_Polynomial_Ring determine_poly_ring(Classic_McEliece_Parameter_Set param_set) {
43
0
   CmceGfMod poly_f = determine_poly_f(param_set);
44
45
0
   switch(param_set.code()) {
46
0
      case Classic_McEliece_Parameter_Set::mceliece348864:
47
0
      case Classic_McEliece_Parameter_Set::mceliece348864f:
48
         // y^64 + y^3 + y + z
49
0
         return {{{3, Classic_McEliece_GF(CmceGfElem(1), poly_f)},
50
0
                  {1, Classic_McEliece_GF(CmceGfElem(1), poly_f)},
51
0
                  {0, Classic_McEliece_GF(CmceGfElem(2), poly_f)}},
52
0
                 poly_f,
53
0
                 64};
54
0
      case Classic_McEliece_Parameter_Set::mceliece460896:
55
0
      case Classic_McEliece_Parameter_Set::mceliece460896f:
56
         // y^96 + y^10 + y^9 + y^6 + 1
57
0
         return {{{10, Classic_McEliece_GF(CmceGfElem(1), poly_f)},
58
0
                  {9, Classic_McEliece_GF(CmceGfElem(1), poly_f)},
59
0
                  {6, Classic_McEliece_GF(CmceGfElem(1), poly_f)},
60
0
                  {0, Classic_McEliece_GF(CmceGfElem(1), poly_f)}},
61
0
                 poly_f,
62
0
                 96};
63
0
      case Classic_McEliece_Parameter_Set::mceliece6960119:
64
0
      case Classic_McEliece_Parameter_Set::mceliece6960119f:
65
0
      case Classic_McEliece_Parameter_Set::mceliece6960119pc:
66
0
      case Classic_McEliece_Parameter_Set::mceliece6960119pcf:
67
         // y^119 + y^8 + 1
68
         // clang-format off
69
0
         return {{{8, Classic_McEliece_GF(CmceGfElem(1), poly_f)},
70
0
                  {0, Classic_McEliece_GF(CmceGfElem(1), poly_f)}},
71
0
                  poly_f,
72
0
                  119};
73
         // clang-format on
74
0
      case Classic_McEliece_Parameter_Set::mceliece6688128:
75
0
      case Classic_McEliece_Parameter_Set::mceliece6688128f:
76
0
      case Classic_McEliece_Parameter_Set::mceliece6688128pc:
77
0
      case Classic_McEliece_Parameter_Set::mceliece6688128pcf:
78
0
      case Classic_McEliece_Parameter_Set::mceliece8192128:
79
0
      case Classic_McEliece_Parameter_Set::mceliece8192128f:
80
0
      case Classic_McEliece_Parameter_Set::mceliece8192128pc:
81
0
      case Classic_McEliece_Parameter_Set::mceliece8192128pcf:
82
         // y^128 + y^7 + y^2 + y + 1
83
0
         return {{{7, Classic_McEliece_GF(CmceGfElem(1), poly_f)},
84
0
                  {2, Classic_McEliece_GF(CmceGfElem(1), poly_f)},
85
0
                  {1, Classic_McEliece_GF(CmceGfElem(1), poly_f)},
86
0
                  {0, Classic_McEliece_GF(CmceGfElem(1), poly_f)}},
87
0
                 poly_f,
88
0
                 128};
89
0
   }
90
0
   BOTAN_ASSERT_UNREACHABLE();
91
0
}
92
93
}  //namespace
94
95
0
Classic_McEliece_Parameters Classic_McEliece_Parameters::create(Classic_McEliece_Parameter_Set set) {
96
0
   auto poly_ring = determine_poly_ring(set);
97
98
0
   switch(set.code()) {
99
0
      case Classic_McEliece_Parameter_Set::mceliece348864:
100
0
      case Classic_McEliece_Parameter_Set::mceliece348864f:
101
0
         return Classic_McEliece_Parameters(set, 12, 3488, std::move(poly_ring));
102
103
0
      case Classic_McEliece_Parameter_Set::mceliece460896:
104
0
      case Classic_McEliece_Parameter_Set::mceliece460896f:
105
0
         return Classic_McEliece_Parameters(set, 13, 4608, std::move(poly_ring));
106
107
0
      case Classic_McEliece_Parameter_Set::mceliece6688128:
108
0
      case Classic_McEliece_Parameter_Set::mceliece6688128f:
109
0
      case Classic_McEliece_Parameter_Set::mceliece6688128pc:
110
0
      case Classic_McEliece_Parameter_Set::mceliece6688128pcf:
111
0
         return Classic_McEliece_Parameters(set, 13, 6688, std::move(poly_ring));
112
113
0
      case Classic_McEliece_Parameter_Set::mceliece6960119:
114
0
      case Classic_McEliece_Parameter_Set::mceliece6960119f:
115
0
      case Classic_McEliece_Parameter_Set::mceliece6960119pc:
116
0
      case Classic_McEliece_Parameter_Set::mceliece6960119pcf:
117
0
         return Classic_McEliece_Parameters(set, 13, 6960, std::move(poly_ring));
118
119
0
      case Classic_McEliece_Parameter_Set::mceliece8192128:
120
0
      case Classic_McEliece_Parameter_Set::mceliece8192128f:
121
0
      case Classic_McEliece_Parameter_Set::mceliece8192128pc:
122
0
      case Classic_McEliece_Parameter_Set::mceliece8192128pcf:
123
0
         return Classic_McEliece_Parameters(set, 13, 8192, std::move(poly_ring));
124
0
   }
125
0
   BOTAN_ASSERT_UNREACHABLE();
126
0
}
127
128
0
Classic_McEliece_Parameters Classic_McEliece_Parameters::create(std::string_view name) {
129
0
   return Classic_McEliece_Parameters::create(Classic_McEliece_Parameter_Set::from_string(name));
130
0
}
131
132
0
Classic_McEliece_Parameters Classic_McEliece_Parameters::create(const OID& oid) {
133
0
   return create(Classic_McEliece_Parameter_Set::from_oid(oid));
134
0
}
135
136
0
OID Classic_McEliece_Parameters::object_identifier() const {
137
0
   return OID::from_string(m_set.to_string());
138
0
}
139
140
Classic_McEliece_Parameters::Classic_McEliece_Parameters(Classic_McEliece_Parameter_Set param_set,
141
                                                         size_t m,
142
                                                         size_t n,
143
                                                         Classic_McEliece_Polynomial_Ring poly_ring) :
144
0
      m_set(param_set), m_m(m), m_n(n), m_poly_ring(std::move(poly_ring)) {
145
0
   BOTAN_ASSERT(n % 8 == 0, "We require that n is a multiple of 8");
146
0
}
147
148
0
size_t Classic_McEliece_Parameters::estimated_strength() const {
149
   // Classic McEliece NIST Round 4 submission, Guide for security reviewers, Table 1:
150
   // For each instance, the minimal strength against the best attack (with free memory access)
151
   // is used as the overall security strength estimate. The strength is capped at 256, since the
152
   // seed is only 256 bits long.
153
0
   switch(m_set.code()) {
154
0
      case Botan::Classic_McEliece_Parameter_Set::mceliece348864:
155
0
      case Botan::Classic_McEliece_Parameter_Set::mceliece348864f:
156
0
         return 140;
157
0
      case Botan::Classic_McEliece_Parameter_Set::mceliece460896:
158
0
      case Botan::Classic_McEliece_Parameter_Set::mceliece460896f:
159
0
         return 179;
160
0
      case Botan::Classic_McEliece_Parameter_Set::mceliece6688128:
161
0
      case Botan::Classic_McEliece_Parameter_Set::mceliece6688128f:
162
0
      case Botan::Classic_McEliece_Parameter_Set::mceliece6688128pc:
163
0
      case Botan::Classic_McEliece_Parameter_Set::mceliece6688128pcf:
164
0
         return 246;
165
0
      case Botan::Classic_McEliece_Parameter_Set::mceliece6960119:
166
0
      case Botan::Classic_McEliece_Parameter_Set::mceliece6960119f:
167
0
      case Botan::Classic_McEliece_Parameter_Set::mceliece6960119pc:
168
0
      case Botan::Classic_McEliece_Parameter_Set::mceliece6960119pcf:
169
0
         return 245;
170
0
      case Botan::Classic_McEliece_Parameter_Set::mceliece8192128:
171
0
      case Botan::Classic_McEliece_Parameter_Set::mceliece8192128f:
172
0
      case Botan::Classic_McEliece_Parameter_Set::mceliece8192128pc:
173
0
      case Botan::Classic_McEliece_Parameter_Set::mceliece8192128pcf:
174
0
         return 256;  // 275 in the document. Capped at 256 because of the seed length.
175
0
   }
176
0
   BOTAN_ASSERT_UNREACHABLE();
177
0
}
178
179
0
std::unique_ptr<XOF> Classic_McEliece_Parameters::prg(std::span<const uint8_t> seed) const {
180
0
   BOTAN_ASSERT_EQUAL(seed.size(), 32, "Valid seed length");
181
0
   auto xof = XOF::create_or_throw("SHAKE-256");
182
183
0
   xof->update(std::array<uint8_t, 1>({64}));
184
0
   xof->update(seed);
185
186
0
   return xof;
187
0
}
188
189
}  // namespace Botan