Skip to content

Commit

Permalink
cmce_parameters refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
FAlbertDev committed Feb 5, 2024
1 parent 093b5e5 commit f5cae78
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 72 deletions.
2 changes: 1 addition & 1 deletion src/lib/pubkey/classic_mceliece/cmce.cpp
Expand Up @@ -69,7 +69,7 @@ bool Classic_McEliece_PublicKey::check_key(RandomNumberGenerator&, bool) const {
}

std::unique_ptr<Private_Key> Classic_McEliece_PublicKey::generate_another(RandomNumberGenerator& rng) const {
return std::make_unique<Classic_McEliece_PrivateKey>(rng, m_public->params().set());
return std::make_unique<Classic_McEliece_PrivateKey>(rng, m_public->params().parameter_set());
}

std::unique_ptr<PK_Ops::KEM_Encryption> Classic_McEliece_PublicKey::create_kem_encryption_op(
Expand Down
2 changes: 1 addition & 1 deletion src/lib/pubkey/classic_mceliece/cmce_parameter_set.h
Expand Up @@ -9,7 +9,7 @@
#ifndef BOTAN_CMCE_PARAMETER_SET_H_
#define BOTAN_CMCE_PARAMETER_SET_H_

#include <botan/oids.h>
#include <botan/asn1_obj.h>

namespace Botan {

Expand Down
190 changes: 131 additions & 59 deletions src/lib/pubkey/classic_mceliece/cmce_parameters.cpp
Expand Up @@ -13,81 +13,141 @@ namespace Botan {

namespace {

std::vector<Classic_McEliece_Polynomial_Ring::Big_F_Coefficient> determine_big_f_coef(size_t t, GF_Mod modulus) {
std::vector<Classic_McEliece_Polynomial_Ring::Big_F_Coefficient> big_f_coef;
switch(t) {
// TODO: Remove test instance on final PR
case 8: //y^8 + y^4 + y^3 + y^2 + 1 (test instances)
big_f_coef.push_back({0, Classic_McEliece_GF(GF_Elem(1), modulus)});
big_f_coef.push_back({2, Classic_McEliece_GF(GF_Elem(1), modulus)});
big_f_coef.push_back({3, Classic_McEliece_GF(GF_Elem(1), modulus)});
big_f_coef.push_back({4, Classic_McEliece_GF(GF_Elem(1), modulus)});
break;
case 64: //y^64 + y^3 + y + z
big_f_coef.push_back({3, Classic_McEliece_GF(GF_Elem(1), modulus)});
big_f_coef.push_back({1, Classic_McEliece_GF(GF_Elem(1), modulus)});
big_f_coef.push_back({0, Classic_McEliece_GF(GF_Elem(2), modulus)});
break;
case 96: //y^96 + y^10 + y^9 + y^6 + 1
big_f_coef.push_back({10, Classic_McEliece_GF(GF_Elem(1), modulus)});
big_f_coef.push_back({9, Classic_McEliece_GF(GF_Elem(1), modulus)});
big_f_coef.push_back({6, Classic_McEliece_GF(GF_Elem(1), modulus)});
big_f_coef.push_back({0, Classic_McEliece_GF(GF_Elem(1), modulus)});
break;
case 119: //y^119 + y^8 + 1
big_f_coef.push_back({8, Classic_McEliece_GF(GF_Elem(1), modulus)});
big_f_coef.push_back({0, Classic_McEliece_GF(GF_Elem(1), modulus)});
break;
case 128: // y^128 + y^7 + y^2 + y + 1
big_f_coef.push_back({7, Classic_McEliece_GF(GF_Elem(1), modulus)});
big_f_coef.push_back({2, Classic_McEliece_GF(GF_Elem(1), modulus)});
big_f_coef.push_back({1, Classic_McEliece_GF(GF_Elem(1), modulus)});
big_f_coef.push_back({0, Classic_McEliece_GF(GF_Elem(1), modulus)});
break;
default:
throw Decoding_Error("No instance with this t value is supported");
GF_Mod determine_poly_f(Classic_McEliece_Parameter_Set param_set) {
switch(param_set) {
case Classic_McEliece_Parameter_Set::mceliece348864:
case Classic_McEliece_Parameter_Set::mceliece348864f:
// z^12 + z^3 + 1
return GF_Mod(0b0001000000001001);
case Classic_McEliece_Parameter_Set::mceliece460896:
case Classic_McEliece_Parameter_Set::mceliece460896f:
case Classic_McEliece_Parameter_Set::mceliece6688128:
case Classic_McEliece_Parameter_Set::mceliece6688128f:
case Classic_McEliece_Parameter_Set::mceliece6688128pc:
case Classic_McEliece_Parameter_Set::mceliece6688128pcf:
case Classic_McEliece_Parameter_Set::mceliece6960119:
case Classic_McEliece_Parameter_Set::mceliece6960119f:
case Classic_McEliece_Parameter_Set::mceliece6960119pc:
case Classic_McEliece_Parameter_Set::mceliece6960119pcf:
case Classic_McEliece_Parameter_Set::mceliece8192128:
case Classic_McEliece_Parameter_Set::mceliece8192128f:
case Classic_McEliece_Parameter_Set::mceliece8192128pc:
case Classic_McEliece_Parameter_Set::mceliece8192128pcf:
// z^12 + z^3 + 1
return GF_Mod(0b0010000000011011);
// TODO: Remove on final PR
case Botan::Classic_McEliece_Parameter_Set::test:
case Botan::Classic_McEliece_Parameter_Set::testf:
case Botan::Classic_McEliece_Parameter_Set::testpc:
case Botan::Classic_McEliece_Parameter_Set::testpcf:
// z^8 + z^7 + z^2 + z + 1 (test instance)
return GF_Mod(0b0000000110000111);
}
BOTAN_ASSERT_UNREACHABLE();
}

return big_f_coef;
Classic_McEliece_Polynomial_Ring determine_poly_ring(Classic_McEliece_Parameter_Set param_set) {
GF_Mod poly_f = determine_poly_f(param_set);

switch(param_set) {
// TODO: Remove test instance on final PR
case Botan::Classic_McEliece_Parameter_Set::test:
case Botan::Classic_McEliece_Parameter_Set::testf:
case Botan::Classic_McEliece_Parameter_Set::testpc:
case Botan::Classic_McEliece_Parameter_Set::testpcf:
// y^8 + y^4 + y^3 + y^2 + 1 (test instances)
return {{{0, Classic_McEliece_GF(GF_Elem(1), poly_f)},
{2, Classic_McEliece_GF(GF_Elem(1), poly_f)},
{3, Classic_McEliece_GF(GF_Elem(1), poly_f)},
{4, Classic_McEliece_GF(GF_Elem(1), poly_f)}},
poly_f,
8};
case Classic_McEliece_Parameter_Set::mceliece348864:
case Classic_McEliece_Parameter_Set::mceliece348864f:
// y^64 + y^3 + y + z
return {{{3, Classic_McEliece_GF(GF_Elem(1), poly_f)},
{1, Classic_McEliece_GF(GF_Elem(1), poly_f)},
{0, Classic_McEliece_GF(GF_Elem(2), poly_f)}},
poly_f,
64};
case Classic_McEliece_Parameter_Set::mceliece460896:
case Classic_McEliece_Parameter_Set::mceliece460896f:
// y^96 + y^10 + y^9 + y^6 + 1
return {{{10, Classic_McEliece_GF(GF_Elem(1), poly_f)},
{9, Classic_McEliece_GF(GF_Elem(1), poly_f)},
{6, Classic_McEliece_GF(GF_Elem(1), poly_f)},
{0, Classic_McEliece_GF(GF_Elem(1), poly_f)}},
poly_f,
96};
case Classic_McEliece_Parameter_Set::mceliece6960119:
case Classic_McEliece_Parameter_Set::mceliece6960119f:
case Classic_McEliece_Parameter_Set::mceliece6960119pc:
case Classic_McEliece_Parameter_Set::mceliece6960119pcf:
// y^119 + y^8 + 1
// clang-format off
return {{{8, Classic_McEliece_GF(GF_Elem(1), poly_f)},
{0, Classic_McEliece_GF(GF_Elem(1), poly_f)}},
poly_f,
119};
// clang-format on
case Classic_McEliece_Parameter_Set::mceliece6688128:
case Classic_McEliece_Parameter_Set::mceliece6688128f:
case Classic_McEliece_Parameter_Set::mceliece6688128pc:
case Classic_McEliece_Parameter_Set::mceliece6688128pcf:
case Classic_McEliece_Parameter_Set::mceliece8192128:
case Classic_McEliece_Parameter_Set::mceliece8192128f:
case Classic_McEliece_Parameter_Set::mceliece8192128pc:
case Classic_McEliece_Parameter_Set::mceliece8192128pcf:
// y^128 + y^7 + y^2 + y + 1
return {{{7, Classic_McEliece_GF(GF_Elem(1), poly_f)},
{2, Classic_McEliece_GF(GF_Elem(1), poly_f)},
{1, Classic_McEliece_GF(GF_Elem(1), poly_f)},
{0, Classic_McEliece_GF(GF_Elem(1), poly_f)}},
poly_f,
128};
}
BOTAN_ASSERT_UNREACHABLE();
}

} //namespace

Classic_McEliece_Parameters Classic_McEliece_Parameters::create(Classic_McEliece_Parameter_Set set) {
auto poly_ring = determine_poly_ring(set);

switch(set) {
case Classic_McEliece_Parameter_Set::mceliece348864:
case Classic_McEliece_Parameter_Set::mceliece348864f:
return Classic_McEliece_Parameters(set, 12, 3488, 64, GF_Mod(0b0001000000001001));
return Classic_McEliece_Parameters(set, 12, 3488, std::move(poly_ring));

case Classic_McEliece_Parameter_Set::mceliece460896:
case Classic_McEliece_Parameter_Set::mceliece460896f:
return Classic_McEliece_Parameters(set, 13, 4608, 96, GF_Mod(0b0010000000011011));
return Classic_McEliece_Parameters(set, 13, 4608, std::move(poly_ring));

case Classic_McEliece_Parameter_Set::mceliece6688128:
case Classic_McEliece_Parameter_Set::mceliece6688128f:
case Classic_McEliece_Parameter_Set::mceliece6688128pc:
case Classic_McEliece_Parameter_Set::mceliece6688128pcf:
return Classic_McEliece_Parameters(set, 13, 6688, 128, GF_Mod(0b0010000000011011));
return Classic_McEliece_Parameters(set, 13, 6688, std::move(poly_ring));

case Classic_McEliece_Parameter_Set::mceliece6960119:
case Classic_McEliece_Parameter_Set::mceliece6960119f:
case Classic_McEliece_Parameter_Set::mceliece6960119pc:
case Classic_McEliece_Parameter_Set::mceliece6960119pcf:
return Classic_McEliece_Parameters(set, 13, 6960, 119, GF_Mod(0b0010000000011011));
return Classic_McEliece_Parameters(set, 13, 6960, std::move(poly_ring));

case Classic_McEliece_Parameter_Set::mceliece8192128:
case Classic_McEliece_Parameter_Set::mceliece8192128f:
case Classic_McEliece_Parameter_Set::mceliece8192128pc:
case Classic_McEliece_Parameter_Set::mceliece8192128pcf:
return Classic_McEliece_Parameters(set, 13, 8192, 128, GF_Mod(0b0010000000011011));
return Classic_McEliece_Parameters(set, 13, 8192, std::move(poly_ring));

// TODO: Remove on final PR
case Botan::Classic_McEliece_Parameter_Set::test:
case Botan::Classic_McEliece_Parameter_Set::testf:
case Botan::Classic_McEliece_Parameter_Set::testpc:
case Botan::Classic_McEliece_Parameter_Set::testpcf:
return Classic_McEliece_Parameters(set, 8, 128, 8, GF_Mod(0b0000000110000111));
return Classic_McEliece_Parameters(set, 8, 128, std::move(poly_ring));
}

BOTAN_ASSERT_UNREACHABLE();
}

Expand All @@ -96,22 +156,18 @@ Classic_McEliece_Parameters Classic_McEliece_Parameters::create(std::string_view
}

Classic_McEliece_Parameters Classic_McEliece_Parameters::create(const OID& oid) {
auto param_set = cmce_param_set_from_oid(oid);
return create(param_set);
return create(cmce_param_set_from_oid(oid));
}

OID Classic_McEliece_Parameters::object_identifier() const {
return OID::from_string(cmce_str_from_param_set(m_set));
}

Classic_McEliece_Parameters::Classic_McEliece_Parameters(
Classic_McEliece_Parameter_Set param_set, size_t m, size_t n, size_t t, GF_Mod poly_f) :
m_set(param_set),
m_m(m),
m_n(n),
m_t(t),
m_poly_f(poly_f),
m_poly_ring(determine_big_f_coef(t, poly_f), poly_f, t) {
Classic_McEliece_Parameters::Classic_McEliece_Parameters(Classic_McEliece_Parameter_Set param_set,
size_t m,
size_t n,
Classic_McEliece_Polynomial_Ring poly_ring) :
m_set(param_set), m_m(m), m_n(n), m_poly_ring(std::move(poly_ring)) {
BOTAN_ASSERT(n % 8 == 0, "We require that n is a multiple of 8");
}

Expand All @@ -120,20 +176,36 @@ size_t Classic_McEliece_Parameters::estimated_strength() const {
// For each instance, the minimal strength against the best attack (with free memory access)
// is used as the overall security strength estimate. The strength is capped at 256, since the
// seed is only 256 bits long.
switch(n()) {
case 3488:
switch(m_set) {
case Botan::Classic_McEliece_Parameter_Set::mceliece348864:
case Botan::Classic_McEliece_Parameter_Set::mceliece348864f:
return 140;
case 4608:
case Botan::Classic_McEliece_Parameter_Set::mceliece460896:
case Botan::Classic_McEliece_Parameter_Set::mceliece460896f:
return 179;
case 6688:
case Botan::Classic_McEliece_Parameter_Set::mceliece6688128:
case Botan::Classic_McEliece_Parameter_Set::mceliece6688128f:
case Botan::Classic_McEliece_Parameter_Set::mceliece6688128pc:
case Botan::Classic_McEliece_Parameter_Set::mceliece6688128pcf:
return 246;
case 6960:
case Botan::Classic_McEliece_Parameter_Set::mceliece6960119:
case Botan::Classic_McEliece_Parameter_Set::mceliece6960119f:
case Botan::Classic_McEliece_Parameter_Set::mceliece6960119pc:
case Botan::Classic_McEliece_Parameter_Set::mceliece6960119pcf:
return 245;
case 8192:
case Botan::Classic_McEliece_Parameter_Set::mceliece8192128:
case Botan::Classic_McEliece_Parameter_Set::mceliece8192128f:
case Botan::Classic_McEliece_Parameter_Set::mceliece8192128pc:
case Botan::Classic_McEliece_Parameter_Set::mceliece8192128pcf:
return 256; // 275 in the document. Capped at 256 because of the seed length.
default:
throw Decoding_Error("Strength for parameter set ist not registed.");
// TODO: Remove on final PR
case Botan::Classic_McEliece_Parameter_Set::test:
case Botan::Classic_McEliece_Parameter_Set::testf:
case Botan::Classic_McEliece_Parameter_Set::testpc:
case Botan::Classic_McEliece_Parameter_Set::testpcf:
return 0;
}
BOTAN_ASSERT_UNREACHABLE();
}

std::unique_ptr<XOF> Classic_McEliece_Parameters::prg(std::span<const uint8_t> seed) const {
Expand Down
19 changes: 9 additions & 10 deletions src/lib/pubkey/classic_mceliece/cmce_parameters.h
Expand Up @@ -9,9 +9,9 @@
#ifndef BOTAN_CMCE_PARAMS_H_
#define BOTAN_CMCE_PARAMS_H_

#include <botan/asn1_obj.h>
#include <botan/cmce_parameter_set.h>
#include <botan/hash.h>
#include <botan/oids.h>
#include <botan/xof.h>
#include <botan/internal/bitvector.h>
#include <botan/internal/cmce_gf.h>
Expand Down Expand Up @@ -55,7 +55,7 @@ class BOTAN_TEST_API Classic_McEliece_Parameters final {
/**
* @brief The parameter set for this Classic McEliece instance.
*/
Classic_McEliece_Parameter_Set set() const { return m_set; }
Classic_McEliece_Parameter_Set parameter_set() const { return m_set; }

/**
* @brief The OID for the Classic McEliece instance.
Expand Down Expand Up @@ -113,7 +113,7 @@ class BOTAN_TEST_API Classic_McEliece_Parameters final {
/**
* @brief The weight of the error vector e.
*/
size_t t() const { return m_t; }
size_t t() const { return m_poly_ring.degree(); }

/**
* @brief Bit output length of the hash function H.
Expand Down Expand Up @@ -154,7 +154,7 @@ class BOTAN_TEST_API Classic_McEliece_Parameters final {
* @brief The monic irreducible polynomial f(z) of degree m over GF(2). Used for modular
* reduction in GF(2^m).
*/
GF_Mod poly_f() const { return m_poly_f; }
GF_Mod poly_f() const { return m_poly_ring.poly_f(); }

/**
* @brief The estimated bit security strength of the Classic McEliece instance.
Expand Down Expand Up @@ -273,18 +273,17 @@ class BOTAN_TEST_API Classic_McEliece_Parameters final {
* @param elem The GF(q) element value.
* @return The GF(q) element.
*/
Classic_McEliece_GF gf(GF_Elem elem) const { return Classic_McEliece_GF(elem, m_poly_f); }
Classic_McEliece_GF gf(GF_Elem elem) const { return Classic_McEliece_GF(elem, poly_f()); }

private:
Classic_McEliece_Parameters(
Classic_McEliece_Parameter_Set param_set, size_t m, size_t n, size_t t, GF_Mod poly_f);
Classic_McEliece_Parameters(Classic_McEliece_Parameter_Set param_set,
size_t m,
size_t n,
Classic_McEliece_Polynomial_Ring poly_ring);

Classic_McEliece_Parameter_Set m_set;

size_t m_m;
size_t m_n;
size_t m_t;
GF_Mod m_poly_f;
Classic_McEliece_Polynomial_Ring m_poly_ring;
};

Expand Down
2 changes: 1 addition & 1 deletion src/tests/test_cmce.cpp
Expand Up @@ -84,7 +84,7 @@ std::vector<Botan::Classic_McEliece_Parameter_Set> instances_to_test() {
bool skip_cmce_test(const std::string& params_str) {
auto params = Botan::Classic_McEliece_Parameters::create(params_str);
auto to_test = instances_to_test();
return std::find(to_test.begin(), to_test.end(), params.set()) == to_test.end();
return std::find(to_test.begin(), to_test.end(), params.parameter_set()) == to_test.end();
}
} // namespace

Expand Down

0 comments on commit f5cae78

Please sign in to comment.