]> git.ipfire.org Git - thirdparty/nettle.git/commitdiff
Add benchmarking of sntrup761.
authorNiels Möller <nisse@lysator.liu.se>
Thu, 7 May 2026 18:14:37 +0000 (20:14 +0200)
committerNiels Möller <nisse@lysator.liu.se>
Thu, 7 May 2026 18:14:37 +0000 (20:14 +0200)
ChangeLog
examples/hogweed-benchmark.c

index 07113069396b7dd716d368f974a98a6953ca1d68..75200742e6f0c00e1070d1247164d0114a09f2e2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
        (TS_SC_HOGWEED): Add sc-sntrup761-test.
        (DISTFILES): Add sntrup761 reference files.
 
+       * examples/hogweed-benchmark.c (struct alg): Renamed, to...
+       (struct sign_alg): ... new name.
+       (alg_list): Renamed list, to...
+       (sign_alg_list): ... new name. Also declare as static const.
+       (struct kem_alg, struct sntrup_ctx): New structs.
+       (bench_kem_alg, bench_sntrup_init, bench_sntrup_keygen)
+       (bench_sntrup_encrypt, bench_sntrup_decrypt, bench_sntrup_clear):
+       New functions.
+       (kem_alg_list): New algorithm list.
+       (main): Benchmark both signature and kem algorithms.
+
 2026-05-03  Niels Möller  <nisse@lysator.liu.se>
 
        * testsuite/testutils.c (test_random_seed, test_get_seed): New functions.
index 467631cded7ea9ccf2e6663261bc5e3fa0807d60..563ec7181dafeb3909ec252113fde935a943f8d5 100644 (file)
@@ -1,6 +1,6 @@
 /* hogweed-benchmark.c
 
-   Copyright (C) 2013, 2014 Niels Möller
+   Copyright (C) 2013, 2014, 2026 Niels Möller
 
    This file is part of GNU Nettle.
 
@@ -52,6 +52,8 @@
 #include "curve25519.h"
 #include "curve448.h"
 #include "slh-dsa.h"
+#include "sntrup.h"
+
 #include "nettle-meta.h"
 #include "sexp.h"
 #include "knuth-lfib.h"
@@ -104,15 +106,6 @@ hash_string (const struct nettle_hash *hash, const char *s)
   return digest;
 }
 
-struct alg {
-  const char *name;
-  unsigned size;
-  void *(*init) (unsigned size);
-  void (*sign)  (void *);
-  void (*verify)(void *);
-  void (*clear) (void *);
-};
-
 /* Returns second per function call */
 static double
 time_function(void (*f)(void *arg), void *arg)
@@ -140,8 +133,18 @@ time_function(void (*f)(void *arg), void *arg)
   return elapsed / ncalls;
 }
 
+struct sign_alg
+{
+  const char *name;
+  unsigned size;
+  void *(*init) (unsigned size);
+  void (*sign)  (void *);
+  void (*verify)(void *);
+  void (*clear) (void *);
+};
+
 static void 
-bench_alg (const struct alg *alg)
+bench_sign_alg (const struct sign_alg *alg)
 {
   double sign;
   double verify;
@@ -167,6 +170,42 @@ bench_alg (const struct alg *alg)
            alg->name, alg->size, 1.0/sign, 1.0/verify);
 }
 
+struct kem_alg
+{
+  const char *name;
+  unsigned size;
+  void *(*init)  (unsigned size);
+  void (*keygen) (void *);
+  void (*encrypt)(void *);
+  void (*decrypt)(void *);
+  void (*clear)  (void *);
+};
+
+static void
+bench_kem_alg (const struct kem_alg *alg)
+{
+  double keygen;
+  double encrypt;
+  double decrypt;
+  void *ctx;
+
+  ctx = alg->init(alg->size);
+  if (ctx == NULL)
+    {
+      printf("%16s %4d N/A\n", alg->name, alg->size);
+      return;
+    }
+
+  keygen = time_function (alg->keygen, ctx);
+  encrypt = time_function (alg->encrypt, ctx);
+  decrypt = time_function (alg->decrypt, ctx);
+
+  alg->clear (ctx);
+
+  printf ("%16s %4d %9.1f %9.1f %9.1f\n",
+         alg->name, alg->size, 1.0/keygen, 1.0/encrypt, 1.0/decrypt);
+}
+
 struct rsa_ctx
 {
   struct rsa_public_key pub;
@@ -964,7 +1003,65 @@ bench_slh_dsa_clear (void *p)
   free (ctx);
 }
 
-struct alg alg_list[] = {
+struct sntrup_ctx
+{
+  uint8_t public_key[SNTRUP761_PUBLIC_KEY_SIZE];
+  uint8_t secret_key[SNTRUP761_PRIVATE_KEY_SIZE];
+  uint8_t ciphertext[SNTRUP761_CIPHER_SIZE];
+  struct knuth_lfib_ctx lfib;
+};
+
+static void *
+bench_sntrup_init (unsigned size)
+{
+  struct sntrup_ctx *ctx;
+  uint8_t session_key[SNTRUP_SESSION_KEY_SIZE];
+  assert (size == 761);
+  ctx = xalloc (sizeof (*ctx));
+
+  knuth_lfib_init (&ctx->lfib, 1);
+  sntrup761_generate_keypair (ctx->public_key, ctx->secret_key,
+                             &ctx->lfib,(nettle_random_func *)knuth_lfib_random);
+  sntrup761_encap (ctx->public_key, session_key, ctx->ciphertext,
+                  &ctx->lfib,(nettle_random_func *)knuth_lfib_random);
+
+  return ctx;
+}
+
+static void
+bench_sntrup_keygen (void *p)
+{
+  struct sntrup_ctx *ctx = p;
+  uint8_t public_key[SNTRUP761_PUBLIC_KEY_SIZE];
+  uint8_t secret_key[SNTRUP761_PRIVATE_KEY_SIZE];
+  sntrup761_generate_keypair (public_key, secret_key,
+                             &ctx->lfib,(nettle_random_func *)knuth_lfib_random);
+}
+
+static void
+bench_sntrup_encrypt (void *p)
+{
+  struct sntrup_ctx *ctx = p;
+  uint8_t session_key[SNTRUP_SESSION_KEY_SIZE];
+  sntrup761_encap (ctx->public_key, session_key, ctx->ciphertext,
+                  &ctx->lfib,(nettle_random_func *)knuth_lfib_random);
+}
+
+static void
+bench_sntrup_decrypt (void *p)
+{
+  struct sntrup_ctx *ctx = p;
+  uint8_t session_key[SNTRUP_SESSION_KEY_SIZE];
+  sntrup761_decap (ctx->secret_key, session_key, ctx->ciphertext);
+}
+
+static void
+bench_sntrup_clear (void *p)
+{
+  free (p);
+}
+
+static const struct sign_alg sign_alg_list[] = {
   { "rsa",   1024, bench_rsa_init,   bench_rsa_sign,   bench_rsa_verify,   bench_rsa_clear },
   { "rsa",   2048, bench_rsa_init,   bench_rsa_sign,   bench_rsa_verify,   bench_rsa_clear },
   { "rsa-tr",   1024, bench_rsa_init,   bench_rsa_sign_tr,   bench_rsa_verify,   bench_rsa_clear },
@@ -1001,6 +1098,9 @@ struct alg alg_list[] = {
   { "slh-dsa-sha2-f", 128, bench_slh_dsa_init_sha2_f, bench_slh_dsa_sign, bench_slh_dsa_verify, bench_slh_dsa_clear },
 };
 
+static const struct kem_alg kem_alg_list[] = {
+  { "sntrup", 761, bench_sntrup_init, bench_sntrup_keygen, bench_sntrup_encrypt, bench_sntrup_decrypt, bench_sntrup_clear },
+};
 #define numberof(x)  (sizeof (x) / sizeof ((x)[0]))
 
 int
@@ -1016,9 +1116,16 @@ main (int argc, char **argv)
   printf ("%16s %4s %9s %9s\n",
          "name", "size", "sign/s", "verify/s");
 
-  for (i = 0; i < numberof(alg_list); i++)
-    if (!filter || strstr (alg_list[i].name, filter))
-      bench_alg (&alg_list[i]);
+  for (i = 0; i < numberof(sign_alg_list); i++)
+    if (!filter || strstr (sign_alg_list[i].name, filter))
+      bench_sign_alg (&sign_alg_list[i]);
+
+  printf ("%16s %4s %9s %9s %9s\n",
+         "name", "size", "gen/s", "enc/s", "dec/s");
+
+  for (i = 0; i < numberof(kem_alg_list); i++)
+    if (!filter || strstr (kem_alg_list[i].name, filter))
+      bench_kem_alg (&kem_alg_list[i]);
 
   return EXIT_SUCCESS;
 }