aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarkus Teich <markus.teich@stusta.mhn.de>2016-06-12 20:52:22 +0200
committerMarkus Teich <markus.teich@stusta.mhn.de>2016-06-12 20:52:22 +0200
commit62b87e57a7f7042d27fe0a80b9194aeae0c14a50 (patch)
tree961a43363dbca413e4b1e65b367c0ffd553cfaf0
parent5957a777076d014b17aada25afe0991397edbacc (diff)
add tests for key generation
-rw-r--r--Makefile.am9
-rw-r--r--brandt.c27
-rw-r--r--brandt.h6
-rw-r--r--crypto.c190
-rw-r--r--crypto.h34
-rw-r--r--test.h12
-rw-r--r--test_crypto.c59
7 files changed, 274 insertions, 63 deletions
diff --git a/Makefile.am b/Makefile.am
index d13e662..8264db3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -5,6 +5,7 @@ lib_LTLIBRARIES = \
libbrandt.la
libbrandt_la_SOURCES = \
+ brandt.c \
crypto.c \
util.c
@@ -13,3 +14,11 @@ libbrandt_la_LIBADD = \
libbrandt_la_LDFLAGS = \
-version-info 0:0:0
+
+check_PROGRAMS = \
+ test_crypto
+
+test_crypto_SOURCES = test_crypto.c
+test_crypto_LDADD = libbrandt.la -lgcrypt -lgpg-error
+
+TESTS = $(check_PROGRAMS)
diff --git a/brandt.c b/brandt.c
new file mode 100644
index 0000000..dd88643
--- /dev/null
+++ b/brandt.c
@@ -0,0 +1,27 @@
+
+#include <gcrypt.h>
+
+#include "crypto.h"
+#include "util.h"
+
+void BRANDT_init ()
+{
+ gcry_error_t err = 0;
+ if (!gcry_check_version("1.6.0")) {
+ eprintf("libgcrypt version mismatch");
+ }
+
+ /* SECMEM cannot be resized dynamically. We do not know how much we need */
+ if ((err = gcry_control(GCRYCTL_DISABLE_SECMEM, 0)))
+ weprintf("failed to set libgcrypt option DISABLE_SECMEM: %s",
+ gcry_strerror(err));
+
+ /* ecc is slow otherwise. */
+ if ((err = gcry_control(GCRYCTL_ENABLE_QUICK_RANDOM, 0)))
+ weprintf("failed to set libgcrypt option ENABLE_QUICK_RANDOM: %s",
+ gcry_strerror(err));
+
+ gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
+ brandt_rand_poll();
+ brandt_crypto_init();
+}
diff --git a/brandt.h b/brandt.h
index 1f95d40..b7ebf5b 100644
--- a/brandt.h
+++ b/brandt.h
@@ -22,6 +22,9 @@
#ifndef _BRANDT_BRANDT_H
#define _BRANDT_BRANDT_H
+#include <unistd.h>
+#include <stdint.h>
+
/**
* FIXME.
*/
@@ -86,6 +89,9 @@ typedef void
uint16_t price);
+void
+BRANDT_init ();
+
/**
* Join an auction described by the @a auction_data parameter.
*
diff --git a/crypto.c b/crypto.c
index 399cd21..e78032e 100644
--- a/crypto.c
+++ b/crypto.c
@@ -26,6 +26,28 @@
#define CURVE "Ed25519"
+struct brandt_ec_skey {
+ unsigned char d[256 / 8];
+};
+
+struct brandt_ec_pkey {
+ unsigned char q_y[256 / 8];
+};
+
+gcry_mpi_point_t ec_gen;
+gcry_ctx_t ec_ctx;
+
+void
+brandt_crypto_init ()
+{
+ gcry_error_t rc;
+
+ rc = gcry_mpi_ec_new (&ec_ctx, NULL, CURVE);
+ brandt_assert_gpgerr (rc);
+ ec_gen = gcry_mpi_ec_get_point ("g", ec_ctx, 0);
+ brandt_assert (NULL != ec_gen);
+}
+
/* --- RANDOM --- */
void
@@ -132,28 +154,31 @@ brandt_mpi_scan_unsigned (gcry_mpi_t *result, const void *data, size_t size)
brandt_assert_gpgerr (rc);
}
-/* --- ECDHE --- */
-
-/**
- * Convert the given private key from the network format to the
- * S-expression that can be used by libgcrypt.
- *
- * @param priv private key to decode
- * @return NULL on error
- */
-static gcry_sexp_t
-decode_private_ecdhe_key (const struct brandt_dhe_skey *priv)
+/*
+gcry_mpi_point_t
+deserialize_point(const struct brandt_point* data, const int len)
{
- gcry_sexp_t result;
+ gcry_sexp_t s;
+ gcry_ctx_t ctx;
+ gcry_mpi_point_t ret;
gcry_error_t rc;
- rc = gcry_sexp_build (&result, NULL,
- "(private-key(ecc(curve \"" CURVE "\")"
- "(d %b)))",
- (int)sizeof (priv->d), priv->d);
- brandt_assert_gpgerr (rc);
- return result;
+ rc = gcry_sexp_build(&s, NULL, "(public-key(ecc(curve " CURVE ")(q %b)))",
+ len, data);
+ brandt_assert_gpgerr(rc);
+
+ rc = gcry_mpi_ec_new(&ctx, s, NULL);
+ brandt_assert_gpgerr(rc);
+ gcry_sexp_release(s);
+
+ ret = gcry_mpi_ec_get_point("q", ctx, 0);
+ brandt_assert(ret);
+ gcry_ctx_release(ctx);
+ return ret;
}
+*/
+
+/* --- EC --- */
/**
* Extract values from an S-expression.
@@ -213,30 +238,81 @@ key_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, const char *topname,
return 0;
}
-/**
- * Create a new private key.
- *
- * @param priv where to write the private key
- */
void
-brandt_ecdhe_key_create (struct brandt_dhe_skey *priv)
+brandt_ec_skey_create (gcry_mpi_t* skey)
{
- gcry_sexp_t priv_sexp;
gcry_sexp_t s_keyparam;
+ gcry_sexp_t priv_sexp;
gcry_mpi_t d;
gcry_error_t rc;
rc = gcry_sexp_build (&s_keyparam, NULL, "(genkey(ecc(curve \"" CURVE "\")"
- "(flags)))")
- brandt_assert_gpgerr (rc);
- rc = gcry_pk_genkey (&priv_sexp, s_keyparam)
- brandt_assert_gpgerr (rc);
+ "(flags)))");
+ brandt_assert_gpgerr (rc);
+ rc = gcry_pk_genkey (&priv_sexp, s_keyparam);
+ brandt_assert_gpgerr (rc);
gcry_sexp_release (s_keyparam);
- rc = key_from_sexp (&d, priv_sexp, "private-key", "d")
- brandt_assert_gpgerr (rc);
+ rc = key_from_sexp (skey, priv_sexp, "private-key", "d");
+ brandt_assert_gpgerr (rc);
gcry_sexp_release (priv_sexp);
- brandt_mpi_print_unsigned (priv->d, sizeof (priv->d), d);
- gcry_mpi_release (d);
+}
+
+
+void
+brandt_ec_pkey_compute (gcry_mpi_point_t* pkey, const gcry_mpi_t skey)
+{
+
+}
+
+
+void
+brandt_ec_keypair_create (gcry_mpi_point_t* pkey, gcry_mpi_t* skey)
+{
+ gcry_error_t rc;
+ gcry_sexp_t s_keyparam;
+ gcry_sexp_t priv_sexp;
+ gcry_ctx_t ctx;
+
+ rc = gcry_sexp_build (&s_keyparam, NULL, "(genkey(ecc(curve \"" CURVE "\")"
+ "(flags)))");
+ brandt_assert_gpgerr (rc);
+
+ rc = gcry_pk_genkey (&priv_sexp, s_keyparam);
+ brandt_assert_gpgerr (rc);
+ gcry_sexp_release (s_keyparam);
+
+ rc = key_from_sexp (skey, priv_sexp, "private-key", "d");
+ brandt_assert_gpgerr (rc);
+
+ rc = gcry_mpi_ec_new (&ctx, priv_sexp, NULL);
+ brandt_assert_gpgerr (rc);
+ gcry_sexp_release (priv_sexp);
+
+ *pkey = gcry_mpi_ec_get_point("q", ctx, 0);
+ brandt_assert (NULL != *pkey);
+ gcry_ctx_release (ctx);
+}
+
+
+/**
+ * Convert the given private key from the network format to the
+ * S-expression that can be used by libgcrypt.
+ *
+ * @param priv private key to decode
+ * @return NULL on error
+ */
+static gcry_sexp_t
+decode_private_ecdhe_key (const struct brandt_ec_skey *priv)
+{
+ gcry_sexp_t result;
+ gcry_error_t rc;
+
+ rc = gcry_sexp_build (&result, NULL,
+ "(private-key(ecc(curve \"" CURVE "\")"
+ "(d %b)))",
+ (int)sizeof (priv->d), priv->d);
+ brandt_assert_gpgerr (rc);
+ return result;
}
/**
@@ -246,8 +322,8 @@ brandt_ecdhe_key_create (struct brandt_dhe_skey *priv)
* @param pub where to write the public key
*/
void
-brandt_ecdhe_key_get_public (const struct brandt_dhe_skey *priv,
- struct brandt_dhe_pkey *pub)
+brandt_ecdhe_key_get_public (const struct brandt_ec_skey *priv,
+ struct brandt_ec_pkey *pub)
{
gcry_sexp_t sexp;
gcry_ctx_t ctx;
@@ -275,8 +351,8 @@ brandt_ecdhe_key_get_public (const struct brandt_dhe_skey *priv,
* @return 0 on error, 1 on success
*/
int
-brandt_ecdhe (const struct brandt_dhe_skey *priv,
- const struct brandt_dhe_pkey *pub,
+brandt_ecdhe (const struct brandt_ec_skey *priv,
+ const struct brandt_ec_pkey *pub,
struct brandt_hash_code *key_material)
{
gcry_error_t rc;
@@ -331,13 +407,45 @@ brandt_ecdhe (const struct brandt_dhe_skey *priv,
}
/**
- * @ingroup crypto
* Clear memory that was used to store a private key.
*
- * @param pk location of the key
+ * @param skey location of the key
*/
void
-brandt_ecdhe_key_clear (struct brandt_dhe_skey *pk)
+brandt_ec_key_clear (struct brandt_ec_skey *skey)
{
- memset (pk, 0, sizeof (struct brandt_dhe_skey));
+ memset (skey, 0, sizeof (struct brandt_ec_skey));
}
+
+/**
+ * Generate a random value mod n.
+ *
+ * @param edc ECC context
+ * @return random value mod n.
+ */
+//gcry_mpi_t
+//GNUNET_CRYPTO_ecc_random_mod_n (struct GNUNET_CRYPTO_EccDlogContext *edc)
+//{
+// gcry_mpi_t n;
+// unsigned int highbit;
+// gcry_mpi_t r;
+//
+// n = gcry_mpi_ec_get_mpi ("n", edc->ctx, 1);
+//
+// /* check public key for number of bits, bail out if key is all zeros */
+// highbit = 256; /* Curve25519 */
+// while ( (! gcry_mpi_test_bit (n, highbit)) &&
+// (0 != highbit) )
+// highbit--;
+// GNUNET_assert (0 != highbit);
+// /* generate fact < n (without bias) */
+// GNUNET_assert (NULL != (r = gcry_mpi_new (0)));
+// do {
+// gcry_mpi_randomize (r,
+// highbit + 1,
+// GCRY_STRONG_RANDOM);
+// }
+// while (gcry_mpi_cmp (r, n) >= 0);
+// gcry_mpi_release (n);
+// return r;
+//}
diff --git a/crypto.h b/crypto.h
index c7ba816..28bf4eb 100644
--- a/crypto.h
+++ b/crypto.h
@@ -25,11 +25,16 @@
#include <gcrypt.h>
#include <stdint.h>
-/* --- RANDOM --- */
+extern gcry_mpi_point_t ec_gen;
+extern gcry_ctx_t ec_ctx;
-void brandt_rand_poll ();
+void brandt_crypto_init ();
+
+/* --- RANDOM --- */
+
+void brandt_rand_poll ();
/* --- HASHING --- */
@@ -41,31 +46,16 @@ struct brandt_hash_code {
void brandt_hash (const void *block, size_t size, struct brandt_hash_code *ret);
-
/* --- MPI --- */
void brandt_mpi_print_unsigned (void *buf, size_t size, gcry_mpi_t val);
-void brandt_mpi_scan_unsigned (gcry_mpi_t *result, const void *data,
- size_t size);
-
-
+void brandt_mpi_scan_unsigned (gcry_mpi_t *result, const void *data, size_t size);
-/* --- ECDHE --- */
-struct brandt_dhe_skey {
- unsigned char d[256 / 8];
-};
-
-struct brandt_dhe_pkey {
- unsigned char q_y[256 / 8];
-};
+/* --- EC --- */
-void brandt_ecdhe_key_create (struct brandt_dhe_skey *priv);
-void brandt_ecdhe_key_get_public (const struct brandt_dhe_skey *priv,
- struct brandt_dhe_pkey *pub);
-int brandt_ecdhe (const struct brandt_dhe_skey *priv,
- const struct brandt_dhe_pkey *pub,
- struct brandt_hash_code *key_material);
-void brandt_ecdhe_key_clear (struct brandt_dhe_skey *priv);
+void brandt_ec_skey_create (gcry_mpi_t* skey);
+void brandt_ec_pkey_compute (gcry_mpi_point_t* pkey, const gcry_mpi_t skey);
+void brandt_ec_keypair_create (gcry_mpi_point_t* pkey, gcry_mpi_t* skey);
#endif /* ifndef _BRANDT_CRYPTO_H */
diff --git a/test.h b/test.h
new file mode 100644
index 0000000..db63350
--- /dev/null
+++ b/test.h
@@ -0,0 +1,12 @@
+#ifndef _BRANDT_TEST_H
+#define _BRANDT_TEST_H
+
+#include <stdio.h>
+
+int tests_run = 0;
+int ret = 0;
+
+#define check(cond, message) do { if (!(cond)) { fputs(message, stderr); return 0; } } while (0)
+#define run(test) do { tests_run++; if (!test()) ret = 1; } while (0)
+
+#endif
diff --git a/test_crypto.c b/test_crypto.c
new file mode 100644
index 0000000..67894eb
--- /dev/null
+++ b/test_crypto.c
@@ -0,0 +1,59 @@
+
+#include "brandt.h"
+#include "crypto.h"
+#include "test.h"
+
+int
+test_brandt_ec_keypair_create ()
+{
+ gcry_mpi_t skey;
+ gcry_mpi_t x1 = gcry_mpi_new(0);
+ gcry_mpi_t x2 = gcry_mpi_new(0);
+ gcry_mpi_t y1 = gcry_mpi_new(0);
+ gcry_mpi_t y2 = gcry_mpi_new(0);
+ gcry_mpi_point_t pkey1;
+ gcry_mpi_point_t pkey2 = gcry_mpi_point_new(0);
+
+ brandt_ec_keypair_create (&pkey1, &skey);
+ check(skey, "no sec key created");
+ check(pkey1, "no pub key created");
+ check(pkey2, "could not init pkey2");
+ check(x1, "could not init x1");
+ check(x2, "could not init x2");
+ check(y1, "could not init y1");
+ check(y2, "could not init y2");
+
+ gcry_mpi_ec_mul(pkey2, skey, ec_gen, ec_ctx);
+ check(!gcry_mpi_ec_get_affine(x1, y1, pkey1, ec_ctx), "could not get affine coords for pkey1");
+ check(!gcry_mpi_ec_get_affine(x2, y2, pkey2, ec_ctx), "could not get affine coords for pkey1");
+ check(!gcry_mpi_cmp(x1, x2), "x component does not match");
+ check(!gcry_mpi_cmp(y1, y2), "y component does not match");
+
+ gcry_mpi_release(skey);
+ gcry_mpi_release(x1);
+ gcry_mpi_release(x2);
+ gcry_mpi_release(y1);
+ gcry_mpi_release(y2);
+ gcry_mpi_point_release(pkey1);
+ gcry_mpi_point_release(pkey2);
+}
+
+int
+main (int argc, char *argv[])
+{
+ int repeat = 100;
+ int i;
+
+ BRANDT_init();
+
+ for (i = 0; i < repeat; i++)
+ {
+ run(test_brandt_ec_keypair_create);
+ }
+
+ if (!ret)
+ {
+ fputs("All tests passed", stderr);
+ }
+ return ret;
+}