From a476620956f0b8d79720918b4ec4f186729e9479 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Meusel?= Date: Fri, 28 Jun 2024 13:07:36 +0200 Subject: [PATCH] Kyber/Dilithium_PK::key_length() returns canonical parameter set ID For Kyber those are {512,768,1024} and for Dilithium {44,65,87} depending on the respective choice of parameter set. --- .../dilithium/dilithium_common/dilithium.cpp | 2 +- .../dilithium_common/dilithium_constants.h | 3 ++ src/lib/pubkey/kyber/kyber_common/kyber.cpp | 3 +- .../kyber/kyber_common/kyber_constants.h | 3 ++ src/tests/test_dilithium.cpp | 38 ++++++++++--------- src/tests/test_kyber.cpp | 16 ++++---- 6 files changed, 38 insertions(+), 27 deletions(-) diff --git a/src/lib/pubkey/dilithium/dilithium_common/dilithium.cpp b/src/lib/pubkey/dilithium/dilithium_common/dilithium.cpp index d64d644ea00..f6c96028ab5 100644 --- a/src/lib/pubkey/dilithium/dilithium_common/dilithium.cpp +++ b/src/lib/pubkey/dilithium/dilithium_common/dilithium.cpp @@ -361,7 +361,7 @@ OID Dilithium_PublicKey::object_identifier() const { } size_t Dilithium_PublicKey::key_length() const { - return m_public->mode().public_key_bytes(); + return m_public->mode().canonical_parameter_set_identifier(); } size_t Dilithium_PublicKey::estimated_strength() const { diff --git a/src/lib/pubkey/dilithium/dilithium_common/dilithium_constants.h b/src/lib/pubkey/dilithium/dilithium_common/dilithium_constants.h index e8be9173e04..fa7785b7cbc 100644 --- a/src/lib/pubkey/dilithium/dilithium_common/dilithium_constants.h +++ b/src/lib/pubkey/dilithium/dilithium_common/dilithium_constants.h @@ -142,6 +142,9 @@ class DilithiumConstants final { DilithiumMode mode() const { return m_mode; } + /// @returns one of {44, 65, 87} + size_t canonical_parameter_set_identifier() const { return k() * 10 + l(); } + Dilithium_Symmetric_Primitives& symmetric_primitives() const { return *m_symmetric_primitives; } private: diff --git a/src/lib/pubkey/kyber/kyber_common/kyber.cpp b/src/lib/pubkey/kyber/kyber_common/kyber.cpp index abd77f66e22..a6b52cfa1f8 100644 --- a/src/lib/pubkey/kyber/kyber_common/kyber.cpp +++ b/src/lib/pubkey/kyber/kyber_common/kyber.cpp @@ -186,8 +186,7 @@ std::vector Kyber_PublicKey::public_key_bits() const { } size_t Kyber_PublicKey::key_length() const { - // TODO: this should report 512, 768, 1024 - return m_public->mode().public_key_bytes(); + return m_public->mode().canonical_parameter_set_identifier(); } bool Kyber_PublicKey::check_key(RandomNumberGenerator&, bool) const { diff --git a/src/lib/pubkey/kyber/kyber_common/kyber_constants.h b/src/lib/pubkey/kyber/kyber_common/kyber_constants.h index 96e3e48eeaf..153dd21c05c 100644 --- a/src/lib/pubkey/kyber/kyber_common/kyber_constants.h +++ b/src/lib/pubkey/kyber/kyber_common/kyber_constants.h @@ -65,6 +65,9 @@ class KyberConstants final { KyberMode mode() const { return m_mode; } + /// @returns one of {512, 768, 1024} + size_t canonical_parameter_set_identifier() const { return k() * N; } + /// \name Foundational constants /// @{ diff --git a/src/tests/test_dilithium.cpp b/src/tests/test_dilithium.cpp index 5d095affd98..e95d9d0992d 100644 --- a/src/tests/test_dilithium.cpp +++ b/src/tests/test_dilithium.cpp @@ -108,7 +108,8 @@ REGISTER_DILITHIUM_KAT_TEST(8x7_AES, Randomized); class DilithiumRoundtripTests final : public Test { public: - static Test::Result run_roundtrip(const char* test_name, Botan::DilithiumMode mode, bool randomized) { + static Test::Result run_roundtrip( + const char* test_name, Botan::DilithiumMode mode, bool randomized, size_t strength, size_t psid) { Test::Result result(test_name); auto rng = Test::new_rng(test_name); @@ -131,6 +132,11 @@ class DilithiumRoundtripTests final : public Test { Botan::Dilithium_PrivateKey priv_key(*rng, mode); const Botan::Dilithium_PublicKey& pub_key = priv_key; + result.test_eq("key strength", priv_key.estimated_strength(), strength); + result.test_eq("key length", priv_key.key_length(), psid); + result.test_eq("key strength", pub_key.estimated_strength(), strength); + result.test_eq("key length", pub_key.key_length(), psid); + const auto sig_before_codec = sign(priv_key, msgvec); const auto priv_key_encoded = priv_key.private_key_bits(); @@ -180,27 +186,25 @@ class DilithiumRoundtripTests final : public Test { } std::vector run() override { - std::vector results; - + return { #if defined(BOTAN_HAS_DILITHIUM) - results.push_back(run_roundtrip("Dilithium_4x4_Common", Botan::DilithiumMode::Dilithium4x4, false)); - results.push_back(run_roundtrip("Dilithium_6x5_Common", Botan::DilithiumMode::Dilithium6x5, false)); - results.push_back(run_roundtrip("Dilithium_8x7_Common", Botan::DilithiumMode::Dilithium8x7, false)); - results.push_back(run_roundtrip("Dilithium_4x4_Common_Randomized", Botan::DilithiumMode::Dilithium4x4, true)); - results.push_back(run_roundtrip("Dilithium_6x5_Common_Randomized", Botan::DilithiumMode::Dilithium6x5, true)); - results.push_back(run_roundtrip("Dilithium_8x7_Common_Randomized", Botan::DilithiumMode::Dilithium8x7, true)); + run_roundtrip("Dilithium_4x4_Common", Botan::DilithiumMode::Dilithium4x4, false, 128, 44), + run_roundtrip("Dilithium_6x5_Common", Botan::DilithiumMode::Dilithium6x5, false, 192, 65), + run_roundtrip("Dilithium_8x7_Common", Botan::DilithiumMode::Dilithium8x7, false, 256, 87), + run_roundtrip("Dilithium_4x4_Common_Randomized", Botan::DilithiumMode::Dilithium4x4, true, 128, 44), + run_roundtrip("Dilithium_6x5_Common_Randomized", Botan::DilithiumMode::Dilithium6x5, true, 192, 65), + run_roundtrip("Dilithium_8x7_Common_Randomized", Botan::DilithiumMode::Dilithium8x7, true, 256, 87), #endif #if defined(BOTAN_HAS_DILITHIUM_AES) - results.push_back(run_roundtrip("Dilithium_4x4_AES", Botan::DilithiumMode::Dilithium4x4_AES, false)); - results.push_back(run_roundtrip("Dilithium_6x5_AES", Botan::DilithiumMode::Dilithium6x5_AES, false)); - results.push_back(run_roundtrip("Dilithium_8x7_AES", Botan::DilithiumMode::Dilithium8x7_AES, false)); - results.push_back(run_roundtrip("Dilithium_4x4_AES_Randomized", Botan::DilithiumMode::Dilithium4x4_AES, true)); - results.push_back(run_roundtrip("Dilithium_6x5_AES_Randomized", Botan::DilithiumMode::Dilithium6x5_AES, true)); - results.push_back(run_roundtrip("Dilithium_8x7_AES_Randomized", Botan::DilithiumMode::Dilithium8x7_AES, true)); + run_roundtrip("Dilithium_4x4_AES", Botan::DilithiumMode::Dilithium4x4_AES, false, 128, 44), + run_roundtrip("Dilithium_6x5_AES", Botan::DilithiumMode::Dilithium6x5_AES, false, 192, 65), + run_roundtrip("Dilithium_8x7_AES", Botan::DilithiumMode::Dilithium8x7_AES, false, 256, 87), + run_roundtrip("Dilithium_4x4_AES_Randomized", Botan::DilithiumMode::Dilithium4x4_AES, true, 128, 44), + run_roundtrip("Dilithium_6x5_AES_Randomized", Botan::DilithiumMode::Dilithium6x5_AES, true, 192, 65), + run_roundtrip("Dilithium_8x7_AES_Randomized", Botan::DilithiumMode::Dilithium8x7_AES, true, 256, 87), #endif - - return results; + }; } }; diff --git a/src/tests/test_kyber.cpp b/src/tests/test_kyber.cpp index a450c1c3527..62efa2fcf02 100644 --- a/src/tests/test_kyber.cpp +++ b/src/tests/test_kyber.cpp @@ -38,7 +38,7 @@ namespace Botan_Tests { class KYBER_Tests final : public Test { public: - static Test::Result run_kyber_test(const char* test_name, Botan::KyberMode mode, size_t strength) { + static Test::Result run_kyber_test(const char* test_name, Botan::KyberMode mode, size_t strength, size_t psid) { Test::Result result(test_name); auto rng = Test::new_rng(test_name); @@ -51,6 +51,8 @@ class KYBER_Tests final : public Test { result.test_eq("estimated strength private", priv_key.estimated_strength(), strength); result.test_eq("estimated strength public", pub_key->estimated_strength(), strength); + result.test_eq("canonical parameter set identifier", priv_key.key_length(), psid); + result.test_eq("canonical parameter set identifier", pub_key->key_length(), psid); // Serialize const auto priv_key_bits = priv_key.private_key_bits(); @@ -97,14 +99,14 @@ class KYBER_Tests final : public Test { std::vector results; #if defined(BOTAN_HAS_KYBER_90S) - results.push_back(run_kyber_test("Kyber512_90s API", Botan::KyberMode::Kyber512_90s, 128)); - results.push_back(run_kyber_test("Kyber768_90s API", Botan::KyberMode::Kyber768_90s, 192)); - results.push_back(run_kyber_test("Kyber1024_90s API", Botan::KyberMode::Kyber1024_90s, 256)); + results.push_back(run_kyber_test("Kyber512_90s API", Botan::KyberMode::Kyber512_90s, 128, 512)); + results.push_back(run_kyber_test("Kyber768_90s API", Botan::KyberMode::Kyber768_90s, 192, 768)); + results.push_back(run_kyber_test("Kyber1024_90s API", Botan::KyberMode::Kyber1024_90s, 256, 1024)); #endif #if defined(BOTAN_HAS_KYBER) - results.push_back(run_kyber_test("Kyber512 API", Botan::KyberMode::Kyber512_R3, 128)); - results.push_back(run_kyber_test("Kyber768 API", Botan::KyberMode::Kyber768_R3, 192)); - results.push_back(run_kyber_test("Kyber1024 API", Botan::KyberMode::Kyber1024_R3, 256)); + results.push_back(run_kyber_test("Kyber512 API", Botan::KyberMode::Kyber512_R3, 128, 512)); + results.push_back(run_kyber_test("Kyber768 API", Botan::KyberMode::Kyber768_R3, 192, 768)); + results.push_back(run_kyber_test("Kyber1024 API", Botan::KyberMode::Kyber1024_R3, 256, 1024)); #endif return results;