diff --git a/brandt.c b/brandt.c index dd88643..30cfd92 100644 --- a/brandt.c +++ b/brandt.c @@ -1,27 +1,47 @@ +/* This file is part of libbrandt. + * Copyright (C) 2016 GNUnet e.V. + * + * libbrandt is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * libbrandt 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * libbrandt. If not, see . + */ +/** + * @file brandt.c + * @brief TODO + */ #include #include "crypto.h" #include "util.h" -void BRANDT_init () +void +BRANDT_init () { gcry_error_t err = 0; - if (!gcry_check_version("1.6.0")) { - eprintf("libgcrypt version mismatch"); - } + + if (!gcry_check_version ("1.7.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)); + 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)); + 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(); + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + brandt_rand_poll (); + brandt_crypto_init (); } diff --git a/crypto.c b/crypto.c index 55ab26a..b4f71e4 100644 --- a/crypto.c +++ b/crypto.c @@ -34,8 +34,10 @@ struct brandt_ec_pkey { unsigned char q_y[256 / 8]; }; -gcry_mpi_point_t ec_gen; gcry_ctx_t ec_ctx; +gcry_mpi_point_t ec_gen; +gcry_mpi_point_t ec_zero; +gcry_mpi_t ec_n; /** * brandt_crypto_init @@ -49,10 +51,19 @@ brandt_crypto_init () 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); + + ec_zero = gcry_mpi_point_new (0); + brandt_assert (NULL != ec_zero); + gcry_mpi_ec_sub (ec_zero, ec_gen, ec_gen, ec_ctx); + + ec_n = gcry_mpi_ec_get_mpi ("n", ec_ctx, 1); + brandt_assert (NULL != ec_n); } + /* --- RANDOM --- */ void @@ -64,6 +75,7 @@ brandt_rand_poll () gcry_fast_random_poll (); } + /* --- HASHING --- */ /** @@ -79,6 +91,7 @@ brandt_hash (const void *block, size_t size, struct brandt_hash_code *ret) gcry_md_hash_buffer (GCRY_MD_SHA512, ret, block, size); } + /* --- MPI --- */ /** @@ -101,6 +114,7 @@ adjust (void *buf, size_t size, size_t target) } } + /** * Output the given MPI value to the given buffer in * network byte order. @@ -141,6 +155,7 @@ brandt_mpi_print_unsigned (void *buf, size_t size, gcry_mpi_t val) } } + /** * Convert data buffer into MPI value. * The buffer is interpreted as network @@ -159,6 +174,7 @@ brandt_mpi_scan_unsigned (gcry_mpi_t *result, const void *data, size_t size) brandt_assert_gpgerr (rc); } + //gcry_mpi_point_t //deserialize_point(const struct brandt_point* data, const int len) //{ @@ -184,74 +200,19 @@ brandt_mpi_scan_unsigned (gcry_mpi_t *result, const void *data, size_t size) /* --- EC --- */ -/** - * Extract values from an S-expression. - * - * @param array where to store the result(s) - * @param sexp S-expression to parse - * @param topname top-level name in the S-expression that is of interest - * @param elems names of the elements to extract - * @return 0 on success - */ -static int -key_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, const char *topname, - const char *elems) -{ - gcry_sexp_t list; - gcry_sexp_t l2; - const char *s; - unsigned int i; - unsigned int idx; - - list = gcry_sexp_find_token (sexp, topname, 0); - if (!list) - return 1; - l2 = gcry_sexp_cadr (list); - gcry_sexp_release (list); - list = l2; - if (!list) - return 2; - idx = 0; - for (s = elems; *s; s++, idx++) - { - l2 = gcry_sexp_find_token (list, s, 1); - if (!l2) - { - for (i = 0; i < idx; i++) - { - gcry_free (array[i]); - array[i] = NULL; - } - gcry_sexp_release (list); - return 3; /* required parameter not found */ - } - array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); - gcry_sexp_release (l2); - if (!array[idx]) - { - for (i = 0; i < idx; i++) - { - gcry_free (array[i]); - array[i] = NULL; - } - gcry_sexp_release (list); - return 4; /* required parameter is invalid */ - } - } - gcry_sexp_release (list); - return 0; -} - /** * brandt_ec_skey_create * * @param[out] skey where to store the generated secret key */ void -brandt_ec_skey_create (gcry_mpi_t *skey) +brandt_ec_skey_create (gcry_mpi_t skey) { + gcry_mpi_t ret; gcry_sexp_t s_keyparam; gcry_sexp_t priv_sexp; + gcry_sexp_t priv_key; + gcry_sexp_t priv_key2; gcry_error_t rc; rc = gcry_sexp_build (&s_keyparam, NULL, "(genkey(ecc(curve \"" CURVE "\")" @@ -262,23 +223,21 @@ brandt_ec_skey_create (gcry_mpi_t *skey) brandt_assert_gpgerr (rc); gcry_sexp_release (s_keyparam); - rc = key_from_sexp (skey, priv_sexp, "private-key", "d"); - brandt_assert_gpgerr (rc); - + priv_key = gcry_sexp_find_token (priv_sexp, "private-key", 11); + brandt_assert (NULL != priv_key); gcry_sexp_release (priv_sexp); + + priv_key2 = gcry_sexp_find_token (priv_key, "d", 1); + brandt_assert (NULL != priv_key2); + gcry_sexp_release (priv_key); + + ret = gcry_sexp_nth_mpi (priv_key2, 1, GCRYMPI_FMT_USG); + brandt_assert (NULL != ret); + gcry_sexp_release (priv_key2); + + gcry_mpi_snatch (skey, ret); } -/** - * brandt_ec_pkey_compute - * - * @param pkey TODO - * @param skey TODO - */ -void -brandt_ec_pkey_compute (gcry_mpi_point_t *pkey, const gcry_mpi_t skey) -{ - -} /** * brandt_ec_keypair_create @@ -287,33 +246,16 @@ brandt_ec_pkey_compute (gcry_mpi_point_t *pkey, const gcry_mpi_t skey) * @param[out] skey where to store the generated secret key */ void -brandt_ec_keypair_create (gcry_mpi_point_t *pkey, gcry_mpi_t *skey) +brandt_ec_keypair_create (gcry_mpi_point_t pkey, gcry_mpi_t skey) { - gcry_ctx_t ctx; - gcry_sexp_t s_keyparam; - gcry_sexp_t priv_sexp; - gcry_error_t rc; + brandt_assert (NULL != pkey); + brandt_assert (NULL != skey); - 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); + brandt_ec_skey_create (skey); + gcry_mpi_ec_mul (pkey, skey, ec_gen, ec_ctx); } + /** * brandt_ec_keypair_create_base * @@ -322,16 +264,19 @@ brandt_ec_keypair_create (gcry_mpi_point_t *pkey, gcry_mpi_t *skey) * @param[in] base which base point should be used to calculate the public key */ void -brandt_ec_keypair_create_base (gcry_mpi_point_t *pkey, gcry_mpi_t *skey, +brandt_ec_keypair_create_base (gcry_mpi_point_t pkey, + gcry_mpi_t skey, const gcry_mpi_point_t base) { + brandt_assert (NULL != pkey); + brandt_assert (NULL != skey); + brandt_assert (NULL != base); + brandt_ec_skey_create (skey); - brandt_assert (*skey); - *pkey = gcry_mpi_point_new (0); - brandt_assert (*pkey); - gcry_mpi_ec_mul (*pkey, *skey, base, ec_ctx); + gcry_mpi_ec_mul (pkey, skey, base, ec_ctx); } + /** * brandt_ec_point_cmp compares two curve points * @@ -356,8 +301,8 @@ brandt_ec_point_cmp (const gcry_mpi_point_t a, const gcry_mpi_point_t b) return 1; } - if (!gcry_mpi_ec_get_affine (ax, ay, a, ec_ctx) - && !gcry_mpi_ec_get_affine (bx, by, b, ec_ctx)) + if (!gcry_mpi_ec_get_affine (ax, ay, a, ec_ctx) && + !gcry_mpi_ec_get_affine (bx, by, b, ec_ctx)) { ret = gcry_mpi_cmp (ax, bx) || gcry_mpi_cmp (ay, by); } @@ -369,117 +314,6 @@ brandt_ec_point_cmp (const gcry_mpi_point_t a, const gcry_mpi_point_t b) return ret; } -/** - * 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; -} - -/** - * Extract the public key for the given private key. - * - * @param priv the private key - * @param pub where to write the public key - */ -void -brandt_ecdhe_key_get_public (const struct brandt_ec_skey *priv, - struct brandt_ec_pkey *pub) -{ - gcry_sexp_t sexp; - gcry_ctx_t ctx; - gcry_mpi_t q; - gcry_error_t rc; - - sexp = decode_private_ecdhe_key (priv); - brandt_assert (NULL != sexp); - rc = gcry_mpi_ec_new (&ctx, sexp, NULL); - brandt_assert_gpgerr (rc); - gcry_sexp_release (sexp); - q = gcry_mpi_ec_get_mpi ("q@eddsa", ctx, 0); - brandt_assert (NULL != q); - brandt_mpi_print_unsigned (pub->q_y, sizeof (pub->q_y), q); - gcry_mpi_release (q); - gcry_ctx_release (ctx); -} - -/** - * Derive key material from a public and a private ECDHE key. - * - * @param priv private key to use for the ECDH (x) - * @param pub public key to use for the ECDH (yG) - * @param key_material where to write the key material (xyG) - * @return 0 on error, 1 on success - */ -int -brandt_ecdhe (const struct brandt_ec_skey *priv, - const struct brandt_ec_pkey *pub, - struct brandt_hash_code *key_material) -{ - gcry_error_t rc; - int rc2; - gcry_mpi_point_t result; - gcry_mpi_point_t q; - gcry_mpi_t d; - gcry_ctx_t ctx; - gcry_sexp_t pub_sexpr; - gcry_mpi_t result_x; - unsigned char xbuf[256 / 8]; - size_t rsize; - - /* first, extract the q = dP value from the public key */ - if (0 != gcry_sexp_build (&pub_sexpr, NULL, - "(public-key(ecc(curve " CURVE ")(q %b)))", - (int)sizeof (pub->q_y), pub->q_y)) - return 0; - rc = gcry_mpi_ec_new (&ctx, pub_sexpr, NULL); - brandt_assert_gpgerr (rc); - gcry_sexp_release (pub_sexpr); - q = gcry_mpi_ec_get_point ("q", ctx, 0); - - /* second, extract the d value from our private key */ - brandt_mpi_scan_unsigned (&d, priv->d, sizeof (priv->d)); - - /* then call the 'multiply' function, to compute the product */ - result = gcry_mpi_point_new (0); - gcry_mpi_ec_mul (result, d, q, ctx); - gcry_mpi_point_release (q); - gcry_mpi_release (d); - - /* finally, convert point to string for hashing */ - result_x = gcry_mpi_new (256); - rc = gcry_mpi_ec_get_affine (result_x, NULL, result, ctx); - brandt_assert (0 == rc); - gcry_mpi_point_release (result); - gcry_ctx_release (ctx); - - rsize = sizeof (xbuf); - rc2 = gcry_mpi_get_flag (result_x, GCRYMPI_FLAG_OPAQUE); - brandt_assert (0 == rc2); - /* result_x can be negative here, so we do not use 'brandt_mpi_print_unsigned' - * as that does not include the sign bit; x should be a 255-bit - * value, so with the sign it should fit snugly into the 256-bit - * xbuf */ - rc = gcry_mpi_print (GCRYMPI_FMT_STD, xbuf, rsize, &rsize, result_x); - brandt_assert_gpgerr (rc); - brandt_hash (xbuf, rsize, key_material); - gcry_mpi_release (result_x); - return 1; -} /** * Clear memory that was used to store a private key. @@ -492,6 +326,7 @@ brandt_ec_key_clear (struct brandt_ec_skey *skey) memset (skey, 0, sizeof (struct brandt_ec_skey)); } + /** * Generate a random value mod n. * diff --git a/crypto.h b/crypto.h index acdce11..9596a7b 100644 --- a/crypto.h +++ b/crypto.h @@ -45,15 +45,19 @@ 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 --- */ -void brandt_ec_skey_create (gcry_mpi_t *skey); +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); -void brandt_ec_keypair_create_base (gcry_mpi_point_t *pkey, gcry_mpi_t *skey, const gcry_mpi_point_t base); +void brandt_ec_keypair_create (gcry_mpi_point_t pkey, gcry_mpi_t skey); +void brandt_ec_keypair_create_base (gcry_mpi_point_t pkey, + gcry_mpi_t skey, + const gcry_mpi_point_t base); int brandt_ec_point_cmp (const gcry_mpi_point_t a, const gcry_mpi_point_t b); #endif /* ifndef _BRANDT_CRYPTO_H */ diff --git a/smc.c b/smc.c index c58b1c2..9e4fd40 100644 --- a/smc.c +++ b/smc.c @@ -25,7 +25,10 @@ #include "smc.h" #include "util.h" -extern gcry_ctx_t ec_ctx; +extern gcry_ctx_t ec_ctx; +extern gcry_mpi_point_t ec_gen; +extern gcry_mpi_point_t ec_zero; +extern gcry_mpi_t ec_n; /** * smc_zkp_dl @@ -38,21 +41,24 @@ extern gcry_ctx_t ec_ctx; * @param r TODO */ void -smc_zkp_dl (gcry_mpi_point_t v, gcry_mpi_point_t g, gcry_mpi_t x, - gcry_mpi_point_t *a, gcry_mpi_t *c, - gcry_mpi_t *r) +smc_zkp_dl (const gcry_mpi_point_t v, + const gcry_mpi_point_t g, + const gcry_mpi_t x, + const gcry_mpi_point_t a, + gcry_mpi_t c, + gcry_mpi_t r) { gcry_mpi_t z = gcry_mpi_new (0); - brandt_ec_keypair_create_base (a, &z, g); + brandt_ec_keypair_create_base (a, z, g); /* compute challange c */ /**TODO: generate c from HASH(g,v,a) and don't output it */ brandt_ec_skey_create (c); + gcry_mpi_mod (c, c, ec_n); - *r = gcry_mpi_new (0); - gcry_mpi_mul (*r, *c, x); - gcry_mpi_add (*r, *r, z); + gcry_mpi_mulm (r, c, x, ec_n); + gcry_mpi_addm (r, r, z, ec_n); gcry_mpi_release (z); } @@ -69,9 +75,11 @@ smc_zkp_dl (gcry_mpi_point_t v, gcry_mpi_point_t g, gcry_mpi_t x, * @return 0 if the proof is correct, something else otherwise */ int -smc_zkp_dl_check (gcry_mpi_point_t v, gcry_mpi_point_t g, gcry_mpi_point_t a, - gcry_mpi_t c, - gcry_mpi_t r) +smc_zkp_dl_check (const gcry_mpi_point_t v, + const gcry_mpi_point_t g, + const gcry_mpi_point_t a, + const gcry_mpi_t c, + const gcry_mpi_t r) { int ret; gcry_mpi_point_t left = gcry_mpi_point_new (0); @@ -90,28 +98,42 @@ smc_zkp_dl_check (gcry_mpi_point_t v, gcry_mpi_point_t g, gcry_mpi_point_t a, void -smc_zkp_2dle (gcry_mpi_point_t v, gcry_mpi_point_t w, gcry_mpi_point_t g1, gcry_mpi_point_t g2, gcry_mpi_t x, gcry_mpi_point_t *a, gcry_mpi_point_t *b, gcry_mpi_t *c, gcry_mpi_t *r) +smc_zkp_2dle (const gcry_mpi_point_t v, + const gcry_mpi_point_t w, + const gcry_mpi_point_t g1, + const gcry_mpi_point_t g2, + const gcry_mpi_t x, + gcry_mpi_point_t a, + gcry_mpi_point_t b, + gcry_mpi_t c, + gcry_mpi_t r) { gcry_mpi_t z = gcry_mpi_new (0); - brandt_ec_keypair_create_base (a, &z, g1); - *b = gcry_mpi_point_new(0); - gcry_mpi_ec_mul(*b, z, g2, ec_ctx); + brandt_ec_keypair_create_base (a, z, g1); + gcry_mpi_ec_mul (b, z, g2, ec_ctx); /* compute challange c */ /**TODO: generate c from HASH(g1,g2,v,w,a,b) and don't output it */ brandt_ec_skey_create (c); + gcry_mpi_mod (c, c, ec_n); - *r = gcry_mpi_new (0); - gcry_mpi_mul (*r, *c, x); - gcry_mpi_add (*r, *r, z); + gcry_mpi_mulm (r, c, x, ec_n); + gcry_mpi_addm (r, r, z, ec_n); gcry_mpi_release (z); } int -smc_zkp_2dle_check (gcry_mpi_point_t v, gcry_mpi_point_t w, gcry_mpi_point_t g1, gcry_mpi_point_t g2, gcry_mpi_point_t a, gcry_mpi_point_t b, gcry_mpi_t c, gcry_mpi_t r) +smc_zkp_2dle_check (const gcry_mpi_point_t v, + const gcry_mpi_point_t w, + const gcry_mpi_point_t g1, + const gcry_mpi_point_t g2, + const gcry_mpi_point_t a, + const gcry_mpi_point_t b, + const gcry_mpi_t c, + const gcry_mpi_t r) { int ret; gcry_mpi_point_t left = gcry_mpi_point_new (0); @@ -125,7 +147,7 @@ smc_zkp_2dle_check (gcry_mpi_point_t v, gcry_mpi_point_t w, gcry_mpi_point_t g1, gcry_mpi_ec_mul (left, r, g2, ec_ctx); gcry_mpi_ec_mul (right, c, w, ec_ctx); gcry_mpi_ec_add (right, b, right, ec_ctx); - ret &= brandt_ec_point_cmp (left, right); + ret |= brandt_ec_point_cmp (left, right); gcry_mpi_point_release (left); gcry_mpi_point_release (right); @@ -133,6 +155,173 @@ smc_zkp_2dle_check (gcry_mpi_point_t v, gcry_mpi_point_t w, gcry_mpi_point_t g1, return ret; } + +void +smc_zkp_0og (gcry_mpi_point_t alpha, + const gcry_mpi_point_t m, + const gcry_mpi_point_t y, + gcry_mpi_point_t beta, + gcry_mpi_point_t a1, + gcry_mpi_point_t a2, + gcry_mpi_point_t b1, + gcry_mpi_point_t b2, + gcry_mpi_t c, + gcry_mpi_t d1, + gcry_mpi_t d2, + gcry_mpi_t r1, + gcry_mpi_t r2) +{ + gcry_mpi_t r = gcry_mpi_new (0); + gcry_mpi_t w = gcry_mpi_new (0); + int eq0 = !brandt_ec_point_cmp (m, ec_zero); + int eqg = !brandt_ec_point_cmp (m, ec_gen); + + if (!(eq0 ^ eqg)) + eprintf ("zero knowledge proof: m is neither 0 nor g"); + + /* beta = r*g */ + brandt_ec_keypair_create (beta, r); + gcry_mpi_mod (r, r, ec_n); + + /* alpha = m + r*y */ + gcry_mpi_ec_mul (alpha, r, y, ec_ctx); + gcry_mpi_ec_add (alpha, m, alpha, ec_ctx); + + if (eq0) + { /* m == 0 */ + brandt_ec_keypair_create_base (a1, d1, beta); + gcry_mpi_mod (d1, d1, ec_n); + brandt_ec_keypair_create_base (b1, r1, y); + gcry_mpi_mod (r1, r1, ec_n); + + /* a1 = r1*g + d1*beta */ + gcry_mpi_ec_mul (a2, r1, ec_gen, ec_ctx); + gcry_mpi_ec_add (a1, a2, a1, ec_ctx); + + /* b1 = r1*y + d1*(alpha-g) */ + gcry_mpi_ec_sub (b2, alpha, ec_gen, ec_ctx); + gcry_mpi_ec_mul (a2, d1, b2, ec_ctx); + gcry_mpi_ec_add (b1, b1, a2, ec_ctx); + + /* a2 = w * g */ + brandt_ec_keypair_create_base (a2, w, ec_gen); + gcry_mpi_mod (w, w, ec_n); + + /* b2 = w * y */ + gcry_mpi_ec_mul (b2, w, y, ec_ctx); + + /* compute challange c */ + /**TODO: generate c from HASH(alpha,beta,a1,b1,a2,b2) and don't output it */ + brandt_ec_skey_create (c); + gcry_mpi_mod (c, c, ec_n); + + /* d2 = c - d1 */ + gcry_mpi_subm (d2, c, d1, ec_n); + + /* r2 = w - r*d2 */ + gcry_mpi_mulm (r2, r, d2, ec_n); + gcry_mpi_subm (r2, w, r2, ec_n); + } + else + { /* m == g */ + brandt_ec_keypair_create_base (a2, d2, beta); + gcry_mpi_mod (d2, d2, ec_n); + brandt_ec_keypair_create_base (b2, r2, y); + gcry_mpi_mod (r2, r2, ec_n); + + /* a2 = r2*g + d2*beta */ + gcry_mpi_ec_mul (a1, r2, ec_gen, ec_ctx); + gcry_mpi_ec_add (a2, a1, a2, ec_ctx); + + /* b2 = r2*y + d2*(alpha-0) */ + /* useless subtraction to have same amount of operations as in m == 0 */ + gcry_mpi_ec_sub (b1, alpha, ec_zero, ec_ctx); + gcry_mpi_ec_mul (a1, d2, b1, ec_ctx); + gcry_mpi_ec_add (b2, b2, a1, ec_ctx); + + /* a1 = w * g */ + brandt_ec_keypair_create_base (a1, w, ec_gen); + gcry_mpi_mod (w, w, ec_n); + + /* b1 = w * y */ + gcry_mpi_ec_mul (b1, w, y, ec_ctx); + + /* compute challange c */ + /**TODO: generate c from HASH(alpha,beta,a1,b1,a2,b2) and don't output it */ + brandt_ec_skey_create (c); + gcry_mpi_mod (c, c, ec_n); + + /* d1 = c - d2 */ + gcry_mpi_subm (d1, c, d2, ec_n); + + /* r1 = w - r*d1 */ + gcry_mpi_mulm (r1, r, d1, ec_n); + gcry_mpi_subm (r1, w, r1, ec_n); + } + + gcry_mpi_release (r); + gcry_mpi_release (w); +} + + +int +smc_zkp_0og_check (const gcry_mpi_point_t alpha, + const gcry_mpi_point_t y, + const gcry_mpi_point_t beta, + const gcry_mpi_point_t a1, + const gcry_mpi_point_t a2, + const gcry_mpi_point_t b1, + const gcry_mpi_point_t b2, + const gcry_mpi_t c, + const gcry_mpi_t d1, + const gcry_mpi_t d2, + const gcry_mpi_t r1, + const gcry_mpi_t r2) +{ + int ret; + gcry_mpi_t sum = gcry_mpi_new (0); + gcry_mpi_point_t right = gcry_mpi_point_new (0); + gcry_mpi_point_t tmp = gcry_mpi_point_new (0); + + /* c == d1 + d2 */ + gcry_mpi_addm (sum, d1, d2, ec_n); + ret = gcry_mpi_cmp (c, sum); + + /* a1 == r1*g + d1*beta */ + gcry_mpi_ec_mul (tmp, r1, ec_gen, ec_ctx); + gcry_mpi_ec_mul (right, d1, beta, ec_ctx); + gcry_mpi_ec_add (right, tmp, right, ec_ctx); + ret |= brandt_ec_point_cmp (a1, right) << 1; + + /* b1 == r1*y + d1*(alpha-g) */ + gcry_mpi_ec_sub (right, alpha, ec_gen, ec_ctx); + gcry_mpi_ec_mul (tmp, d1, right, ec_ctx); + gcry_mpi_ec_mul (right, r1, y, ec_ctx); + gcry_mpi_ec_add (right, right, tmp, ec_ctx); + ret |= brandt_ec_point_cmp (b1, right) << 2; + + /* a2 == r2*g + d2*beta */ + gcry_mpi_ec_mul (tmp, d2, beta, ec_ctx); + gcry_mpi_ec_mul (right, r2, ec_gen, ec_ctx); + gcry_mpi_ec_add (right, right, tmp, ec_ctx); + ret |= brandt_ec_point_cmp (a2, right) << 3; + + /* b2 == r2*y + d2*alpha */ + gcry_mpi_ec_mul (tmp, d2, alpha, ec_ctx); + gcry_mpi_ec_mul (right, r2, y, ec_ctx); + gcry_mpi_ec_add (right, right, tmp, ec_ctx); + ret |= brandt_ec_point_cmp (b2, right) << 4; + + gcry_mpi_release (sum); + gcry_mpi_point_release (right); + gcry_mpi_point_release (tmp); + + if (ret) + weprintf ("ret: 0x%x", ret); + return ret; +} + + //GEN //smc_hextodec (const char *s) //{ diff --git a/smc.h b/smc.h index c2826c2..6309123 100644 --- a/smc.h +++ b/smc.h @@ -24,10 +24,60 @@ #include -void smc_zkp_dl (gcry_mpi_point_t v, gcry_mpi_point_t g, gcry_mpi_t x, gcry_mpi_point_t *a, gcry_mpi_t *c, gcry_mpi_t *r); -int smc_zkp_dl_check (gcry_mpi_point_t v, gcry_mpi_point_t g, gcry_mpi_point_t a, gcry_mpi_t c, gcry_mpi_t r); +void smc_zkp_dl (const gcry_mpi_point_t v, + const gcry_mpi_point_t g, + const gcry_mpi_t x, + const gcry_mpi_point_t a, + gcry_mpi_t c, + gcry_mpi_t r); +int smc_zkp_dl_check (const gcry_mpi_point_t v, + const gcry_mpi_point_t g, + const gcry_mpi_point_t a, + const gcry_mpi_t c, + const gcry_mpi_t r); -void smc_zkp_2dle (gcry_mpi_point_t v, gcry_mpi_point_t w, gcry_mpi_point_t g1, gcry_mpi_point_t g2, gcry_mpi_t x, gcry_mpi_point_t *a, gcry_mpi_point_t *b, gcry_mpi_t *c, gcry_mpi_t *r); -int smc_zkp_2dle_check (gcry_mpi_point_t v, gcry_mpi_point_t w, gcry_mpi_point_t g1, gcry_mpi_point_t g2, gcry_mpi_point_t a, gcry_mpi_point_t b, gcry_mpi_t c, gcry_mpi_t r); +void smc_zkp_2dle (const gcry_mpi_point_t v, + const gcry_mpi_point_t w, + const gcry_mpi_point_t g1, + const gcry_mpi_point_t g2, + const gcry_mpi_t x, + gcry_mpi_point_t a, + gcry_mpi_point_t b, + gcry_mpi_t c, + gcry_mpi_t r); +int smc_zkp_2dle_check (const gcry_mpi_point_t v, + const gcry_mpi_point_t w, + const gcry_mpi_point_t g1, + const gcry_mpi_point_t g2, + const gcry_mpi_point_t a, + const gcry_mpi_point_t b, + const gcry_mpi_t c, + const gcry_mpi_t r); + +void smc_zkp_0og (gcry_mpi_point_t alpha, + const gcry_mpi_point_t m, + const gcry_mpi_point_t y, + gcry_mpi_point_t beta, + gcry_mpi_point_t a1, + gcry_mpi_point_t a2, + gcry_mpi_point_t b1, + gcry_mpi_point_t b2, + gcry_mpi_t c, + gcry_mpi_t d1, + gcry_mpi_t d2, + gcry_mpi_t r1, + gcry_mpi_t r2); +int smc_zkp_0og_check (const gcry_mpi_point_t alpha, + const gcry_mpi_point_t y, + const gcry_mpi_point_t beta, + const gcry_mpi_point_t a1, + const gcry_mpi_point_t a2, + const gcry_mpi_point_t b1, + const gcry_mpi_point_t b2, + const gcry_mpi_t c, + const gcry_mpi_t d1, + const gcry_mpi_t d2, + const gcry_mpi_t r1, + const gcry_mpi_t r2); #endif // ifndef _BRANDT_SMC_H diff --git a/test.h b/test.h index dd1ead0..da9485e 100644 --- a/test.h +++ b/test.h @@ -27,6 +27,6 @@ int tests_run = 0; int ret = 0; #define check(cond, message) do { if (!(cond)) { fputs (message, stderr); fputc ('\n', stderr); return 0; } } while (0) -#define run(test) do { tests_run++; if (!test ()) { ret = 1; } } while (0) +#define run(test) do { if (!test ()) { ret = 1; } } while (0) #endif // ifndef _BRANDT_TEST_H diff --git a/test_crypto.c b/test_crypto.c index 610dc6d..5cc2ed1 100644 --- a/test_crypto.c +++ b/test_crypto.c @@ -23,111 +23,85 @@ #include "smc.h" #include "test.h" -extern gcry_mpi_point_t ec_gen; extern gcry_ctx_t ec_ctx; - -int -test_brandt_ec_keypair_create () -{ - gcry_mpi_t skey; - 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"); - - gcry_mpi_ec_mul (pkey2, skey, ec_gen, ec_ctx); - check (!brandt_ec_point_cmp (pkey1, pkey2), "pkeys do not match"); - - gcry_mpi_release (skey); - gcry_mpi_point_release (pkey1); - gcry_mpi_point_release (pkey2); -} +extern gcry_mpi_point_t ec_gen; +extern gcry_mpi_point_t ec_zero; +extern gcry_mpi_t ec_n; int test_smc_zkp_dl () { - static int first = 1; - gcry_mpi_t c; - gcry_mpi_t r; - gcry_mpi_t s; - gcry_mpi_t x; - gcry_mpi_point_t a; - gcry_mpi_point_t g; + gcry_mpi_t c = gcry_mpi_new (0); + gcry_mpi_t r = gcry_mpi_new (0); + gcry_mpi_t x = gcry_mpi_new (0); + gcry_mpi_point_t a = gcry_mpi_point_new (0); + gcry_mpi_point_t g = gcry_mpi_point_new (0); gcry_mpi_point_t v = gcry_mpi_point_new (0); - check (v, "no pub key initialized"); - brandt_ec_keypair_create (&g, &s); - check (g, "no gen created"); + brandt_ec_keypair_create (g, c); - if (first) + if (0 == tests_run) { + /**TODO: there has to be a better way to copy a point */ gcry_mpi_ec_mul (g, GCRYMPI_CONST_ONE, ec_gen, ec_ctx); - first = 0; } - brandt_ec_skey_create (&x); - check (x, "no sec key created"); - gcry_mpi_ec_mul (v, x, g, ec_ctx); - check (v, "no pub key created"); + brandt_ec_keypair_create_base (v, x, g); - smc_zkp_dl (v, g, x, &a, &c, &r); - check (!smc_zkp_dl_check (v, g, a, c, r), "zkp was false, should be true"); + smc_zkp_dl (v, g, x, a, c, r); + check (!smc_zkp_dl_check (v, g, a, c, r), "zkp dl wrong"); + + check (gcry_mpi_ec_curve_point (a, ec_ctx), "not on curve"); + check (gcry_mpi_ec_curve_point (g, ec_ctx), "not on curve"); + check (gcry_mpi_ec_curve_point (v, ec_ctx), "not on curve"); gcry_mpi_release (c); gcry_mpi_release (r); - gcry_mpi_release (s); gcry_mpi_release (x); gcry_mpi_point_release (a); gcry_mpi_point_release (g); gcry_mpi_point_release (v); } + int test_smc_zkp_2dle () { - static int first = 1; - gcry_mpi_t c; - gcry_mpi_t r; - gcry_mpi_t s; - gcry_mpi_t x; - gcry_mpi_point_t a; - gcry_mpi_point_t b; - gcry_mpi_point_t g1; - gcry_mpi_point_t g2; + gcry_mpi_t c = gcry_mpi_new (0); + gcry_mpi_t r = gcry_mpi_new (0); + gcry_mpi_t x = gcry_mpi_new (0); + gcry_mpi_point_t a = gcry_mpi_point_new (0); + gcry_mpi_point_t b = gcry_mpi_point_new (0); + gcry_mpi_point_t g1 = gcry_mpi_point_new (0); + gcry_mpi_point_t g2 = gcry_mpi_point_new (0); gcry_mpi_point_t v = gcry_mpi_point_new (0); gcry_mpi_point_t w = gcry_mpi_point_new (0); - check (v, "no pub1 key initialized"); - check (w, "no pub2 key initialized"); - brandt_ec_keypair_create (&g1, &s); - gcry_mpi_release (s); - brandt_ec_keypair_create (&g2, &s); - check (g1, "no gen1 created"); - check (g2, "no gen2 created"); + brandt_ec_keypair_create (g1, c); + brandt_ec_keypair_create (g2, c); - if (first) + if (0 == tests_run) { + /**TODO: there has to be a better way to copy a point */ gcry_mpi_ec_mul (g1, GCRYMPI_CONST_ONE, ec_gen, ec_ctx); gcry_mpi_ec_mul (g2, GCRYMPI_CONST_ONE, ec_gen, ec_ctx); - first = 0; } - brandt_ec_skey_create (&x); - check (x, "no sec key created"); - gcry_mpi_ec_mul (v, x, g1, ec_ctx); - check (v, "no pub1 key created"); + brandt_ec_keypair_create_base (v, x, g1); gcry_mpi_ec_mul (w, x, g2, ec_ctx); - check (w, "no pub2 key created"); - smc_zkp_2dle (v, w, g1, g2, x, &a, &b, &c, &r); - check (!smc_zkp_2dle_check (v, w, g1, g2, a, b, c, r), "zkp was false, should be true"); + smc_zkp_2dle (v, w, g1, g2, x, a, b, c, r); + check (!smc_zkp_2dle_check (v, w, g1, g2, a, b, c, r), "zkp 2dle wrong"); + + check (gcry_mpi_ec_curve_point (a, ec_ctx), "not on curve"); + check (gcry_mpi_ec_curve_point (b, ec_ctx), "not on curve"); + check (gcry_mpi_ec_curve_point (g1, ec_ctx), "not on curve"); + check (gcry_mpi_ec_curve_point (g2, ec_ctx), "not on curve"); + check (gcry_mpi_ec_curve_point (v, ec_ctx), "not on curve"); + check (gcry_mpi_ec_curve_point (w, ec_ctx), "not on curve"); gcry_mpi_release (c); gcry_mpi_release (r); - gcry_mpi_release (s); gcry_mpi_release (x); gcry_mpi_point_release (a); gcry_mpi_point_release (b); @@ -137,19 +111,65 @@ test_smc_zkp_2dle () gcry_mpi_point_release (w); } + +int +test_smc_zkp_0og () +{ + gcry_mpi_t c = gcry_mpi_new (0); + gcry_mpi_t d1 = gcry_mpi_new (0); + gcry_mpi_t d2 = gcry_mpi_new (0); + gcry_mpi_t r1 = gcry_mpi_new (0); + gcry_mpi_t r2 = gcry_mpi_new (0); + gcry_mpi_point_t y = gcry_mpi_point_new (0); + gcry_mpi_point_t alpha = gcry_mpi_point_new (0); + gcry_mpi_point_t beta = gcry_mpi_point_new (0); + gcry_mpi_point_t a1 = gcry_mpi_point_new (0); + gcry_mpi_point_t a2 = gcry_mpi_point_new (0); + gcry_mpi_point_t b1 = gcry_mpi_point_new (0); + gcry_mpi_point_t b2 = gcry_mpi_point_new (0); + + brandt_ec_keypair_create (y, c); + + smc_zkp_0og (alpha, (tests_run % 2 ? ec_zero : ec_gen), y, beta, a1, a2, b1, + b2, c, d1, d2, r1, r2); + check (!smc_zkp_0og_check (alpha, y, beta, a1, a2, b1, b2, c, d1, d2, r1, + r2), "zkp 0og is wrong"); + + check (gcry_mpi_ec_curve_point (y, ec_ctx), "not on curve"); + check (gcry_mpi_ec_curve_point (alpha, ec_ctx), "not on curve"); + check (gcry_mpi_ec_curve_point (beta, ec_ctx), "not on curve"); + check (gcry_mpi_ec_curve_point (a1, ec_ctx), "not on curve"); + check (gcry_mpi_ec_curve_point (a2, ec_ctx), "not on curve"); + check (gcry_mpi_ec_curve_point (b1, ec_ctx), "not on curve"); + check (gcry_mpi_ec_curve_point (b2, ec_ctx), "not on curve"); + + gcry_mpi_release (c); + gcry_mpi_release (d1); + gcry_mpi_release (d2); + gcry_mpi_release (r1); + gcry_mpi_release (r2); + gcry_mpi_point_release (y); + gcry_mpi_point_release (alpha); + gcry_mpi_point_release (beta); + gcry_mpi_point_release (a1); + gcry_mpi_point_release (a2); + gcry_mpi_point_release (b1); + gcry_mpi_point_release (b2); +} + + int main (int argc, char *argv[]) { - int repeat = 50; - int i; + int repeat = 32; BRANDT_init (); - for (i = 0; i < repeat; i++) + for (tests_run = 0; tests_run < repeat; tests_run++) { - run (test_brandt_ec_keypair_create); run (test_smc_zkp_dl); run (test_smc_zkp_2dle); + run (test_smc_zkp_0og); } return ret; diff --git a/uncrustify/conf b/uncrustify/conf index 8a04ef8..07a7816 100644 --- a/uncrustify/conf +++ b/uncrustify/conf @@ -908,7 +908,7 @@ nl_switch_brace = add # ignore/add/remove/force # Add a newline between ')' and '{' if the ')' is on a different line than the if/for/etc. # Overrides nl_for_brace, nl_if_brace, nl_switch_brace, nl_while_switch, and nl_catch_brace. -nl_multi_line_cond = false # false/true +nl_multi_line_cond = true # false/true # Force a newline in a define after the macro name for multi-line defines. nl_multi_line_define = false # false/true @@ -1093,14 +1093,14 @@ nl_create_while_one_liner = false # false/true # # The position of arithmetic operators in wrapped expressions -pos_arith = lead # ignore/lead/lead_break/lead_force/trail/trail_break/trail_force +pos_arith = trail # ignore/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of assignment in wrapped expressions. # Do not affect '=' followed by '{' pos_assign = trail # ignore/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of boolean operators in wrapped expressions -pos_bool = lead # ignore/lead/lead_break/lead_force/trail/trail_break/trail_force +pos_bool = trail # ignore/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of comparison operators in wrapped expressions pos_compare = lead # ignore/lead/lead_break/lead_force/trail/trail_break/trail_force @@ -1125,10 +1125,10 @@ pos_class_colon = ignore # ignore/lead/lead_break/lea code_width = 80 # number # Whether to fully split long 'for' statements at semi-colons -ls_for_split_full = false # false/true +ls_for_split_full = true # false/true # Whether to fully split long function protos/calls at commas -ls_func_split_full = false # false/true +ls_func_split_full = true # false/true # # Blank line options @@ -1144,7 +1144,7 @@ nl_after_func_proto = 0 # number nl_after_func_proto_group = 0 # number # The number of newlines after '}' of a multi-line function body -nl_after_func_body = 2 # number +nl_after_func_body = 3 # number # The number of newlines after '}' of a multi-line function body in a class declaration nl_after_func_body_class = 0 # number @@ -1212,20 +1212,20 @@ eat_blanks_before_close_brace = false # false/true # # Add or remove braces on single-line 'do' statement -mod_full_brace_do = remove # ignore/add/remove/force +mod_full_brace_do = force # ignore/add/remove/force # Add or remove braces on single-line 'for' statement -mod_full_brace_for = add # ignore/add/remove/force +mod_full_brace_for = remove # ignore/add/remove/force # Add or remove braces on single-line function definitions. (Pawn) mod_full_brace_function = ignore # ignore/add/remove/force # Add or remove braces on single-line 'if' statement. Will not remove the braces if they contain an 'else'. -mod_full_brace_if = add # ignore/add/remove/force +mod_full_brace_if = ignore # ignore/add/remove/force # Make all if/elseif/else statements in a chain be braced or not. Overrides mod_full_brace_if. # If any must be braced, they are all braced. If all can be unbraced, then the braces are removed. -mod_full_brace_if_chain = true # false/true +mod_full_brace_if_chain = false # false/true # Don't remove braces around statements that span N newlines mod_full_brace_nl = 3 # number @@ -1323,7 +1323,7 @@ cmt_cpp_nl_end = false # false/true cmt_cpp_to_c = false # false/true # Whether to put a star on subsequent comment lines -cmt_star_cont = true # false/true +cmt_star_cont = false # false/true # The number of spaces to insert at the start of subsequent comment lines cmt_sp_before_star_cont = 0 # number @@ -1346,7 +1346,8 @@ cmt_insert_file_footer = "" # string # The filename that contains text to insert before a function implementation if the function isn't preceded with a C/C++ comment. # Will substitute $(function) with the function name and $(javaparam) with the javadoc @param and @return stuff. # Will also substitute $(fclass) with the class name: void CFoo::Bar() { ... } -cmt_insert_func_header = "func_header" # string +cmt_insert_func_header = "" # string +#cmt_insert_func_header = "func_header" # string # The filename that contains text to insert before a class if the class isn't preceded with a C/C++ comment. # Will substitute $(class) with the class name.