add tests for key generation
This commit is contained in:
parent
5957a77707
commit
62b87e57a7
@ -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)
|
||||
|
27
brandt.c
Normal file
27
brandt.c
Normal file
@ -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();
|
||||
}
|
6
brandt.h
6
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.
|
||||
*
|
||||
|
190
crypto.c
190
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;
|
||||
//}
|
||||
|
34
crypto.h
34
crypto.h
@ -25,13 +25,18 @@
|
||||
#include <gcrypt.h>
|
||||
#include <stdint.h>
|
||||
|
||||
extern gcry_mpi_point_t ec_gen;
|
||||
extern gcry_ctx_t ec_ctx;
|
||||
|
||||
|
||||
void brandt_crypto_init ();
|
||||
|
||||
|
||||
/* --- RANDOM --- */
|
||||
|
||||
|
||||
void brandt_rand_poll ();
|
||||
|
||||
|
||||
|
||||
/* --- HASHING --- */
|
||||
|
||||
struct brandt_hash_code {
|
||||
@ -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);
|
||||
|
||||
|
||||
/* --- EC --- */
|
||||
|
||||
/* --- ECDHE --- */
|
||||
|
||||
struct brandt_dhe_skey {
|
||||
unsigned char d[256 / 8];
|
||||
};
|
||||
|
||||
struct brandt_dhe_pkey {
|
||||
unsigned char q_y[256 / 8];
|
||||
};
|
||||
|
||||
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 */
|
||||
|
12
test.h
Normal file
12
test.h
Normal file
@ -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
|
59
test_crypto.c
Normal file
59
test_crypto.c
Normal file
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user