add test vector generation for crypto ops
authorFlorian Dold <florian.dold@gmail.com>
Wed, 15 Jan 2020 12:29:47 +0000 (13:29 +0100)
committerFlorian Dold <florian.dold@gmail.com>
Wed, 15 Jan 2020 12:29:47 +0000 (13:29 +0100)
src/util/.gitignore
src/util/Makefile.am
src/util/gnunet-crypto-tvg.c [new file with mode: 0644]

index 0495dcf8f940abec0d54d73665559dbe151daaa0..84c13708ec1e8d6aa9e4145d439a70cf25b8cbf9 100644 (file)
@@ -1,6 +1,7 @@
 test_common_logging_dummy
 gnunet-config
 gnunet-config-diff
+gnunet-crypto-tvg
 gnunet-ecc
 gnunet-qr
 gnunet-resolver
index 369fcc6c1cb39d8aa9bb885894b4bb835b9b57ed..7d347424bb05e07a2485ec2d8e88c3d303226cff 100644 (file)
@@ -183,6 +183,7 @@ libexec_PROGRAMS = \
 bin_PROGRAMS = \
  gnunet-resolver \
  gnunet-config \
+ gnunet-crypto-tvg \
  $(GNUNET_ECC) \
  $(GNUNET_SCRYPT) \
  gnunet-uri
@@ -221,6 +222,11 @@ gnunet_resolver_LDADD = \
   libgnunetutil.la \
   $(GN_LIBINTL)
 
+gnunet_crypto_tvg_SOURCES = \
+ gnunet-crypto-tvg.c
+gnunet_crypto_tvg_LDADD = \
+  libgnunetutil.la \
+  $(GN_LIBINTL) -lgcrypt
 
 gnunet_ecc_SOURCES = \
  gnunet-ecc.c
diff --git a/src/util/gnunet-crypto-tvg.c b/src/util/gnunet-crypto-tvg.c
new file mode 100644 (file)
index 0000000..7d151c1
--- /dev/null
@@ -0,0 +1,278 @@
+/*
+     This file is part of GNUnet.
+     Copyright (C) 2020 GNUnet e.V.
+
+     GNUnet is free software: you can redistribute it and/or modify it
+     under the terms of the GNU Affero General Public License as published
+     by the Free Software Foundation, either version 3 of the License,
+     or (at your option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     Affero General Public License for more details.
+
+     You should have received a copy of the GNU Affero General Public License
+     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+     SPDX-License-Identifier: AGPL3.0-or-later
+ */
+
+/**
+ * @file util/gnunet-crypto-tgv.c
+ * @brief Generate test vectors for cryptographic operations.
+ * @author Florian Dold
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_signatures.h"
+#include "gnunet_testing_lib.h"
+#include <gcrypt.h>
+
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * Sample signature struct.
+ *
+ * Purpose is #GNUNET_SIGNATURE_PURPOSE_TEST
+ */
+struct TestSignatureDataPS
+{
+  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+  uint32_t testval;
+};
+
+GNUNET_NETWORK_STRUCT_END
+
+
+/**
+ * Print data base32-crockford with a preceding label.
+ *
+ * @param label label to print
+ * @param data data to print
+ * @param size size of data
+ */
+static void
+display_data (char *label, void *data, size_t size)
+{
+  char *enc = GNUNET_STRINGS_data_to_string_alloc (data, size);
+  printf ("%s %s\n", label, enc);
+  GNUNET_free (enc);
+}
+
+
+/**
+ * Main function that will be run.
+ *
+ * @param cls closure
+ * @param args remaining command-line arguments
+ * @param cfgfile name of the configuration file used (for saving, can be NULL!)
+ * @param cfg configuration
+ */
+static void
+run (void *cls,
+     char *const *args,
+     const char *cfgfile,
+     const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+  {
+    struct GNUNET_HashCode hc;
+    char *str = "Hello, GNUnet";
+
+    GNUNET_CRYPTO_hash (str, strlen (str), &hc);
+
+    printf ("hash code:\n");
+    display_data ("  input", str, strlen (str));
+    display_data ("  output", &hc, sizeof (struct GNUNET_HashCode));
+  }
+  {
+    struct GNUNET_CRYPTO_EcdhePrivateKey *priv1;
+    struct GNUNET_CRYPTO_EcdhePublicKey pub1;
+    struct GNUNET_CRYPTO_EcdhePrivateKey *priv2;
+    struct GNUNET_HashCode skm;
+    priv1 = GNUNET_CRYPTO_ecdhe_key_create ();
+    priv2 = GNUNET_CRYPTO_ecdhe_key_create ();
+    GNUNET_CRYPTO_ecdhe_key_get_public (priv1, &pub1);
+    GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecc_ecdh (priv2, &pub1, &skm));
+
+    printf ("ecdhe key:\n");
+    display_data ("  priv1", priv1, sizeof (struct
+                                            GNUNET_CRYPTO_EcdhePrivateKey));
+    display_data ("  pub1", &pub1, sizeof (struct
+                                           GNUNET_CRYPTO_EcdhePublicKey));
+    display_data ("  priv2", priv2, sizeof (struct
+                                            GNUNET_CRYPTO_EcdhePrivateKey));
+    display_data ("  skm", &skm, sizeof (struct GNUNET_HashCode));
+    GNUNET_free (priv1);
+    GNUNET_free (priv2);
+  }
+
+  {
+    struct GNUNET_CRYPTO_EddsaPrivateKey *priv;
+    struct GNUNET_CRYPTO_EddsaPublicKey pub;
+    priv = GNUNET_CRYPTO_eddsa_key_create ();
+    GNUNET_CRYPTO_eddsa_key_get_public (priv, &pub);
+
+    printf ("eddsa key:\n");
+    display_data ("  priv", priv, sizeof (struct
+                                          GNUNET_CRYPTO_EddsaPrivateKey));
+    display_data ("  pub", &pub, sizeof (struct GNUNET_CRYPTO_EddsaPublicKey));
+    GNUNET_free (priv);
+  }
+  {
+    struct GNUNET_CRYPTO_EddsaPrivateKey *priv;
+    struct GNUNET_CRYPTO_EddsaPublicKey pub;
+    struct GNUNET_CRYPTO_EddsaSignature sig;
+    struct TestSignatureDataPS data = { 0 };
+    priv = GNUNET_CRYPTO_eddsa_key_create ();
+    GNUNET_CRYPTO_eddsa_key_get_public (priv, &pub);
+    data.purpose.size = htonl (sizeof (struct TestSignatureDataPS));
+    data.purpose.size = htonl (GNUNET_SIGNATURE_PURPOSE_TEST);
+    GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_eddsa_sign (priv, &data.purpose,
+                                                          &sig));
+    GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_eddsa_verify (0,
+                                                            &data.purpose,
+                                                            &sig,
+                                                            &pub));
+
+    printf ("eddsa sig:\n");
+    display_data ("  priv", priv, sizeof (struct
+                                          GNUNET_CRYPTO_EddsaPrivateKey));
+    display_data ("  pub", &pub, sizeof (struct GNUNET_CRYPTO_EddsaPublicKey));
+    display_data ("  data", &data, sizeof (struct TestSignatureDataPS));
+    display_data ("  sig", &sig, sizeof (struct GNUNET_CRYPTO_EddsaSignature));
+    GNUNET_free (priv);
+  }
+
+  {
+    size_t out_len = 64;
+    char out[out_len];
+    char *ikm = "I'm the secret input key material";
+    char *salt = "I'm very salty";
+    char *ctx = "I'm a context chunk, also known as 'info' in the RFC";
+
+    GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_kdf (&out,
+                                                   out_len,
+                                                   salt,
+                                                   strlen (salt),
+                                                   ikm,
+                                                   strlen (ikm),
+                                                   ctx,
+                                                   strlen (ctx),
+                                                   NULL));
+
+    printf ("kdf:\n");
+    display_data ("  salt", salt, strlen (salt));
+    display_data ("  ikm", ikm, strlen (ikm));
+    display_data ("  ctx", ctx, strlen (ctx));
+    printf ("  out_len %u\n", (unsigned int) out_len);
+    display_data ("  out", out, out_len);
+  }
+  {
+    struct GNUNET_CRYPTO_EcdhePrivateKey *priv_ecdhe;
+    struct GNUNET_CRYPTO_EcdhePublicKey pub_ecdhe;
+    struct GNUNET_CRYPTO_EddsaPrivateKey *priv_eddsa;
+    struct GNUNET_CRYPTO_EddsaPublicKey pub_eddsa;
+    struct GNUNET_HashCode key_material;
+    priv_ecdhe = GNUNET_CRYPTO_ecdhe_key_create ();
+    GNUNET_CRYPTO_ecdhe_key_get_public (priv_ecdhe, &pub_ecdhe);
+    priv_eddsa = GNUNET_CRYPTO_eddsa_key_create ();
+    GNUNET_CRYPTO_eddsa_key_get_public (priv_eddsa, &pub_eddsa);
+    GNUNET_CRYPTO_ecdh_eddsa (priv_ecdhe, &pub_eddsa, &key_material);
+
+    printf ("eddsa_ecdh:\n");
+    display_data ("  priv_ecdhe", priv_ecdhe, sizeof (struct
+                                                      GNUNET_CRYPTO_EcdhePrivateKey));
+    display_data ("  pub_ecdhe", &pub_ecdhe, sizeof (struct
+                                                     GNUNET_CRYPTO_EcdhePublicKey));
+    display_data ("  priv_eddsa", priv_eddsa, sizeof (struct
+                                                      GNUNET_CRYPTO_EddsaPrivateKey));
+    display_data ("  pub_eddsa", &pub_eddsa, sizeof (struct
+                                                     GNUNET_CRYPTO_EddsaPublicKey));
+    display_data ("  key_material", &key_material, sizeof (struct
+                                                           GNUNET_HashCode));
+  }
+
+  {
+    struct GNUNET_CRYPTO_RsaPrivateKey *skey;
+    struct GNUNET_CRYPTO_RsaPublicKey *pkey;
+    struct GNUNET_HashCode message_hash;
+    struct GNUNET_CRYPTO_RsaBlindingKeySecret bks;
+    struct GNUNET_CRYPTO_RsaSignature *blinded_sig;
+    struct GNUNET_CRYPTO_RsaSignature *sig;
+    char *blinded_data;
+    size_t blinded_len;
+    char *public_enc_data;
+    size_t public_enc_len;
+    char *blinded_sig_enc_data;
+    size_t blinded_sig_enc_length;
+    char *sig_enc_data;
+    size_t sig_enc_length;
+    skey = GNUNET_CRYPTO_rsa_private_key_create (2048);
+    pkey = GNUNET_CRYPTO_rsa_private_key_get_public (skey);
+    GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, &message_hash,
+                                sizeof (struct GNUNET_HashCode));
+    GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, &bks, sizeof (struct
+                                                                          GNUNET_CRYPTO_RsaBlindingKeySecret));
+    GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_rsa_blind (&message_hash, &bks,
+                                                          pkey, &blinded_data,
+                                                          &blinded_len));
+    blinded_sig = GNUNET_CRYPTO_rsa_sign_blinded (skey, blinded_data,
+                                                  blinded_len);
+    sig = GNUNET_CRYPTO_rsa_unblind (blinded_sig, &bks, pkey);
+    GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_rsa_verify (&message_hash, sig,
+                                                           pkey));
+    public_enc_len = GNUNET_CRYPTO_rsa_public_key_encode (pkey,
+                                                          &public_enc_data);
+    blinded_sig_enc_length = GNUNET_CRYPTO_rsa_signature_encode (blinded_sig,
+                                                                 &
+                                                                 blinded_sig_enc_data);
+    sig_enc_length = GNUNET_CRYPTO_rsa_signature_encode (sig, &sig_enc_data);
+    printf ("blind signing:\n");
+    display_data ("  message_hash", &message_hash, sizeof (struct
+                                                           GNUNET_HashCode));
+    display_data ("  rsa_public_key", public_enc_data, public_enc_len);
+    display_data ("  blinding_key_secret", &bks, sizeof (struct
+                                                         GNUNET_CRYPTO_RsaBlindingKeySecret));
+    display_data ("  blinded_message", blinded_data, blinded_len);
+    display_data ("  blinded_sig", blinded_sig_enc_data,
+                  blinded_sig_enc_length);
+    display_data ("  sig", sig_enc_data, sig_enc_length);
+    GNUNET_CRYPTO_rsa_private_key_free (skey);
+    GNUNET_CRYPTO_rsa_public_key_free (pkey);
+    GNUNET_CRYPTO_rsa_signature_free (sig);
+    GNUNET_CRYPTO_rsa_signature_free (blinded_sig);
+  }
+}
+
+
+/**
+ * The main function of the test vector generation tool.
+ *
+ * @param argc number of arguments from the command line
+ * @param argv command line arguments
+ * @return 0 ok, 1 on error
+ */
+int
+main (int argc,
+      char *const *argv)
+{
+  const struct GNUNET_GETOPT_CommandLineOption options[] = {
+    GNUNET_GETOPT_OPTION_END
+  };
+
+  GNUNET_assert (GNUNET_OK ==
+                 GNUNET_log_setup ("gnunet-crypto-tvg",
+                                   "INFO",
+                                   NULL));
+  if (GNUNET_OK !=
+      GNUNET_PROGRAM_run (argc, argv,
+                          "gnunet-crypto-tvg",
+                          "Generate test vectors for cryptographic operations",
+                          options,
+                          &run, NULL))
+    return 1;
+  return 0;
+}
+
+/* end of gnunet-crypto-tvg.c */