Repository: randombit/botan
Pull request #3178 (2023-01-14 20:44:11)

Support encoding/decoding Kyber keys through the generic interfaces


Patch:
diff --git a/src/lib/pubkey/kyber/kyber_common/kyber.cpp b/src/lib/pubkey/kyber/kyber_common/kyber.cpp
index 3806c8905..84413125c 100644
--- a/src/lib/pubkey/kyber/kyber_common/kyber.cpp
+++ b/src/lib/pubkey/kyber/kyber_common/kyber.cpp
@@ -71,7 +71,7 @@ KyberMode::KyberMode(Mode mode)
    : m_mode(mode) {}
 
 KyberMode::KyberMode(const OID& oid)
-   : m_mode(mode_from_string(oid.to_string())) {}
+   : m_mode(mode_from_string(oid.to_formatted_string())) {}
 
 KyberMode::KyberMode(const std::string& str)
    : m_mode(mode_from_string(str)) {}
@@ -1345,6 +1345,13 @@ void Kyber_PublicKey::initialize_from_encoding(const std::vector<uint8_t>& pub_k
    m_public = std::make_shared<Kyber_PublicKeyInternal>(std::move(mode), std::move(poly_vec), std::move(seed));
    }
 
+Kyber_PublicKey::Kyber_PublicKey(const AlgorithmIdentifier& alg_id,
+                                 const std::vector<uint8_t>& key_bits) :
+   Kyber_PublicKey(key_bits,
+                   KyberMode(alg_id.get_oid()),
+                   KyberKeyEncoding::Full)
+   {}
+
 Kyber_PublicKey::Kyber_PublicKey(const std::vector<uint8_t>& pub_key,
                                  KyberMode m,
                                  KyberKeyEncoding encoding)
@@ -1428,6 +1435,13 @@ Kyber_PrivateKey::Kyber_PrivateKey(RandomNumberGenerator& rng, KyberMode m)
                rng.random_vec(KyberConstants::kZLength));
    }
 
+Kyber_PrivateKey::Kyber_PrivateKey(const AlgorithmIdentifier& alg_id,
+                                   const secure_vector<uint8_t>& key_bits) :
+   Kyber_PrivateKey(key_bits,
+                    KyberMode(alg_id.get_oid()),
+                    KyberKeyEncoding::Full)
+   {}
+
 Kyber_PrivateKey::Kyber_PrivateKey(const secure_vector<uint8_t>& sk,
                                    KyberMode m,
                                    KyberKeyEncoding encoding)
diff --git a/src/lib/pubkey/kyber/kyber_common/kyber.h b/src/lib/pubkey/kyber/kyber_common/kyber.h
index 23c6e3407..fd80f1a85 100644
--- a/src/lib/pubkey/kyber/kyber_common/kyber.h
+++ b/src/lib/pubkey/kyber/kyber_common/kyber.h
@@ -74,6 +74,9 @@ class BOTAN_PUBLIC_API(3, 0) Kyber_PublicKey : public virtual Public_Key
                       KyberMode mode,
                       KyberKeyEncoding encoding);
 
+      Kyber_PublicKey(const AlgorithmIdentifier& alg_id,
+                      const std::vector<uint8_t>& key_bits);
+
       Kyber_PublicKey(const Kyber_PublicKey& other);
 
       Kyber_PublicKey& operator=(const Kyber_PublicKey& other) = default;
@@ -108,9 +111,7 @@ class BOTAN_PUBLIC_API(3, 0) Kyber_PublicKey : public virtual Public_Key
          }
 
    protected:
-      Kyber_PublicKey() : m_key_encoding(KyberKeyEncoding::Full)
-         {
-         }
+      Kyber_PublicKey() {}
 
       void initialize_from_encoding(const std::vector<uint8_t>& pub_key,
                                     KyberMode m,
@@ -124,7 +125,7 @@ class BOTAN_PUBLIC_API(3, 0) Kyber_PublicKey : public virtual Public_Key
       friend class Kyber_KEM_Decryptor;
 
       std::shared_ptr<Kyber_PublicKeyInternal> m_public;
-      KyberKeyEncoding m_key_encoding;
+      KyberKeyEncoding m_key_encoding = KyberKeyEncoding::Full;
    };
 
 class BOTAN_PUBLIC_API(3, 0) Kyber_PrivateKey final : public virtual Kyber_PublicKey, public virtual Private_Key
@@ -136,6 +137,9 @@ class BOTAN_PUBLIC_API(3, 0) Kyber_PrivateKey final : public virtual Kyber_Publi
                        KyberMode mode,
                        KyberKeyEncoding encoding);
 
+      Kyber_PrivateKey(const AlgorithmIdentifier& alg_id,
+                       const secure_vector<uint8_t>& key_bits);
+
       std::unique_ptr<Public_Key> public_key() const override;
 
       secure_vector<uint8_t> private_key_bits() const override;
diff --git a/src/lib/pubkey/pk_algs.cpp b/src/lib/pubkey/pk_algs.cpp
index 2fd2d0944..e24393b4f 100644
--- a/src/lib/pubkey/pk_algs.cpp
+++ b/src/lib/pubkey/pk_algs.cpp
@@ -101,8 +101,8 @@ load_public_key(const AlgorithmIdentifier& alg_id,
       return std::make_unique<McEliece_PublicKey>(key_bits);
 #endif
 
-#if 0 && (defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S))
-   if(alg_name == "Kyber")
+#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
+   if(alg_name == "Kyber" || alg_name.starts_with("Kyber-"))
       return std::make_unique<Kyber_PublicKey>(alg_id, key_bits);
 #endif
 
@@ -200,9 +200,9 @@ load_private_key(const AlgorithmIdentifier& alg_id,
       return std::make_unique<DSA_PrivateKey>(alg_id, key_bits);
 #endif
 
-#if 0 && (defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S))
-   if(alg_name == "Kyber")
-      return std::make_unique<Kyber_PrivateKey>(key_bits);
+#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
+   if(alg_name == "Kyber" || alg_name.starts_with("Kyber-"))
+      return std::make_unique<Kyber_PrivateKey>(alg_id, key_bits);
 #endif
 
 #if defined(BOTAN_HAS_MCELIECE)


Test patch:
diff --git a/src/tests/test_kyber.cpp b/src/tests/test_kyber.cpp
index 927814ba6..ce4d76f88 100644
--- a/src/tests/test_kyber.cpp
+++ b/src/tests/test_kyber.cpp
@@ -23,6 +23,7 @@
    #include <botan/oids.h>
    #include <botan/rng.h>
    #include <botan/pubkey.h>
+   #include "test_pubkey.h"
 #endif
 
 namespace Botan_Tests {
@@ -354,6 +355,32 @@ class Kyber_Encoding_Test : public Text_Based_Test
 
 BOTAN_REGISTER_TEST("kyber", "kyber_encodings", Kyber_Encoding_Test);
 
+class Kyber_Keygen_Tests final : public PK_Key_Generation_Test
+   {
+   public:
+      std::vector<std::string> keygen_params() const override
+         {
+         return
+            {
+#if defined(BOTAN_HAS_KYBER_90S)
+            "Kyber-512-90s-r3",
+            "Kyber-768-90s-r3",
+            "Kyber-1024-90s-r3",
+#endif
+#if defined(BOTAN_HAS_KYBER)
+            "Kyber-512-r3",
+            "Kyber-768-r3",
+            "Kyber-1024-r3",
+#endif
+            };
+         }
+      std::string algo_name() const override
+         {
+         return "Kyber";
+         }
+   };
+
+BOTAN_REGISTER_TEST("kyber", "kyber_keygen", Kyber_Keygen_Tests);
 #endif
 
 } // namespace Botan_Tests