Repository: randombit/botan
Pull request #3100 (2022-12-03 12:47:16)

Add speed cmdlet for benchmarking Kyber


Patch:
diff --git a/src/cli/speed.cpp b/src/cli/speed.cpp
index 3f8838969..ed04c0f26 100644
--- a/src/cli/speed.cpp
+++ b/src/cli/speed.cpp
@@ -111,6 +111,10 @@
    #include <botan/mceliece.h>
 #endif
 
+#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
+   #include <botan/kyber.h>
+#endif
+
 #if defined(BOTAN_HAS_ECDSA)
    #include <botan/ecdsa.h>
 #endif
@@ -407,6 +411,7 @@ class Speed final : public Command
             "Curve25519",
             "NEWHOPE",
             "McEliece",
+            "Kyber",
             };
          }
 
@@ -633,6 +638,12 @@ class Speed final : public Command
                bench_mceliece(provider, msec);
                }
 #endif
+#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
+            else if(algo == "Kyber")
+               {
+               bench_kyber(provider, msec);
+               }
+#endif
 #if defined(BOTAN_HAS_XMSS_RFC8391)
             else if(algo == "XMSS")
                {
@@ -2168,6 +2179,47 @@ class Speed final : public Command
          }
 #endif
 
+#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
+      void bench_kyber(const std::string& provider,
+                       std::chrono::milliseconds msec)
+         {
+         const Botan::KyberMode::Mode all_modes[] = {
+            Botan::KyberMode::Kyber512,
+            Botan::KyberMode::Kyber512_90s,
+            Botan::KyberMode::Kyber768,
+            Botan::KyberMode::Kyber768_90s,
+            Botan::KyberMode::Kyber1024,
+            Botan::KyberMode::Kyber1024_90s,
+         };
+
+         for(auto modet: all_modes)
+            {
+            Botan::KyberMode mode(modet);
+
+#if !defined(BOTAN_HAS_KYBER)
+            if(mode.is_modern())
+               continue;
+#endif
+
+#if !defined(BOTAN_HAS_KYBER_90S)
+            if(mode.is_90s())
+               continue;
+#endif
+
+            auto keygen_timer = make_timer(mode.to_string(), provider, "keygen");
+
+            auto key = keygen_timer->run([&]
+               {
+               return Botan::Kyber_PrivateKey(rng(), mode);
+               });
+
+            record_result(keygen_timer);
+
+            bench_pk_kem(key, mode.to_string(), provider, "Raw", msec);
+            }
+         }
+#endif
+
 #if defined(BOTAN_HAS_XMSS_RFC8391)
       void bench_xmss(const std::string& provider,
                       std::chrono::milliseconds msec)
diff --git a/src/lib/pubkey/kyber/kyber_common/kyber.h b/src/lib/pubkey/kyber/kyber_common/kyber.h
index 8aafc48f3..8977b0017 100644
--- a/src/lib/pubkey/kyber/kyber_common/kyber.h
+++ b/src/lib/pubkey/kyber/kyber_common/kyber.h
@@ -48,6 +48,7 @@ class BOTAN_PUBLIC_API(3, 0) KyberMode
 
       Mode mode() const { return m_mode; }
       bool is_90s() const { return m_mode == Kyber512_90s || m_mode == Kyber768_90s || m_mode == Kyber1024_90s; }
+      bool is_modern() const { return !is_90s(); }
 
       bool operator==(const KyberMode& other) const { return m_mode == other.m_mode; }
       bool operator!=(const KyberMode& other) const { return !(*this == other); }


Test patch:
diff --git a/src/scripts/test_cli.py b/src/scripts/test_cli.py
index bf12d45e2..95f071af7 100755
--- a/src/scripts/test_cli.py
+++ b/src/scripts/test_cli.py
@@ -1149,7 +1149,7 @@ def cli_speed_pk_tests(_tmp_dir):
 
     pk_algos = ["ECDSA", "ECDH", "SM2", "ECKCDSA", "ECGDSA", "GOST-34.10",
                 "DH", "DSA", "ElGamal", "Ed25519", "Curve25519", "NEWHOPE", "McEliece",
-                "RSA", "RSA_keygen", "XMSS", "ec_h2c"]
+                "RSA", "RSA_keygen", "XMSS", "ec_h2c", "Kyber"]
 
     output = test_cli("speed", ["--msec=%d" % (msec)] + pk_algos, None).split('\n')