From f5cae78afb3bdad3e7f8670d6a4c469a13ebb6fe Mon Sep 17 00:00:00 2001 From: Fabian Albert Date: Mon, 5 Feb 2024 10:47:35 +0100 Subject: [PATCH] cmce_parameters refactoring --- src/lib/pubkey/classic_mceliece/cmce.cpp | 2 +- .../classic_mceliece/cmce_parameter_set.h | 2 +- .../classic_mceliece/cmce_parameters.cpp | 190 ++++++++++++------ .../pubkey/classic_mceliece/cmce_parameters.h | 19 +- src/tests/test_cmce.cpp | 2 +- 5 files changed, 143 insertions(+), 72 deletions(-) diff --git a/src/lib/pubkey/classic_mceliece/cmce.cpp b/src/lib/pubkey/classic_mceliece/cmce.cpp index 2287cf11dce..9bbaa1d19dc 100644 --- a/src/lib/pubkey/classic_mceliece/cmce.cpp +++ b/src/lib/pubkey/classic_mceliece/cmce.cpp @@ -69,7 +69,7 @@ bool Classic_McEliece_PublicKey::check_key(RandomNumberGenerator&, bool) const { } std::unique_ptr Classic_McEliece_PublicKey::generate_another(RandomNumberGenerator& rng) const { - return std::make_unique(rng, m_public->params().set()); + return std::make_unique(rng, m_public->params().parameter_set()); } std::unique_ptr Classic_McEliece_PublicKey::create_kem_encryption_op( diff --git a/src/lib/pubkey/classic_mceliece/cmce_parameter_set.h b/src/lib/pubkey/classic_mceliece/cmce_parameter_set.h index c680d918be3..d06da313210 100644 --- a/src/lib/pubkey/classic_mceliece/cmce_parameter_set.h +++ b/src/lib/pubkey/classic_mceliece/cmce_parameter_set.h @@ -9,7 +9,7 @@ #ifndef BOTAN_CMCE_PARAMETER_SET_H_ #define BOTAN_CMCE_PARAMETER_SET_H_ -#include +#include namespace Botan { diff --git a/src/lib/pubkey/classic_mceliece/cmce_parameters.cpp b/src/lib/pubkey/classic_mceliece/cmce_parameters.cpp index 7c35f7bd512..36951ed3b72 100644 --- a/src/lib/pubkey/classic_mceliece/cmce_parameters.cpp +++ b/src/lib/pubkey/classic_mceliece/cmce_parameters.cpp @@ -13,81 +13,141 @@ namespace Botan { namespace { -std::vector determine_big_f_coef(size_t t, GF_Mod modulus) { - std::vector 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(); } @@ -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"); } @@ -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 Classic_McEliece_Parameters::prg(std::span seed) const { diff --git a/src/lib/pubkey/classic_mceliece/cmce_parameters.h b/src/lib/pubkey/classic_mceliece/cmce_parameters.h index 138cb29eb5e..edfa30ad3f8 100644 --- a/src/lib/pubkey/classic_mceliece/cmce_parameters.h +++ b/src/lib/pubkey/classic_mceliece/cmce_parameters.h @@ -9,9 +9,9 @@ #ifndef BOTAN_CMCE_PARAMS_H_ #define BOTAN_CMCE_PARAMS_H_ +#include #include #include -#include #include #include #include @@ -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. @@ -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. @@ -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. @@ -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; }; diff --git a/src/tests/test_cmce.cpp b/src/tests/test_cmce.cpp index 70e6671ce9a..2e910cba7b9 100644 --- a/src/tests/test_cmce.cpp +++ b/src/tests/test_cmce.cpp @@ -84,7 +84,7 @@ std::vector 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