From 557fbe2cc32f3ff6d8c2c0c8aa272f7b55f45618 Mon Sep 17 00:00:00 2001 From: Markus Teich Date: Mon, 13 Jun 2016 21:01:14 +0200 Subject: [PATCH] add first ZKP including test case --- Makefile.am | 5 +-- crypto.c | 48 +++++++++++++++++++++++++-- crypto.h | 6 ++-- smc.c | 91 ++++++++++++++++++++++++--------------------------- smc.h | 10 ++++++ test.h | 2 +- test_crypto.c | 67 +++++++++++++++++++++++++------------ 7 files changed, 149 insertions(+), 80 deletions(-) create mode 100644 smc.h diff --git a/Makefile.am b/Makefile.am index 8264db3..76820c6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -7,10 +7,11 @@ lib_LTLIBRARIES = \ libbrandt_la_SOURCES = \ brandt.c \ crypto.c \ - util.c + util.c \ + smc.c libbrandt_la_LIBADD = \ - -lpari + -lgcrypt -lgpg-error libbrandt_la_LDFLAGS = \ -version-info 0:0:0 diff --git a/crypto.c b/crypto.c index e78032e..7f2940a 100644 --- a/crypto.c +++ b/crypto.c @@ -243,17 +243,19 @@ brandt_ec_skey_create (gcry_mpi_t* skey) { 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); gcry_sexp_release (s_keyparam); + rc = key_from_sexp (skey, priv_sexp, "private-key", "d"); brandt_assert_gpgerr (rc); + gcry_sexp_release (priv_sexp); } @@ -268,10 +270,10 @@ 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_ctx_t ctx; gcry_sexp_t s_keyparam; gcry_sexp_t priv_sexp; - gcry_ctx_t ctx; + gcry_error_t rc; rc = gcry_sexp_build (&s_keyparam, NULL, "(genkey(ecc(curve \"" CURVE "\")" "(flags)))"); @@ -294,6 +296,46 @@ 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) +{ + 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); +} + + +int +brandt_ec_point_cmp (const gcry_mpi_point_t a, const gcry_mpi_point_t b) +{ + int ret = 1; + gcry_mpi_t ax = gcry_mpi_new(0); + gcry_mpi_t bx = gcry_mpi_new(0); + gcry_mpi_t ay = gcry_mpi_new(0); + gcry_mpi_t by = gcry_mpi_new(0); + + brandt_assert (a && b); + if (!ax || !bx || !ay || !by) + { + weprintf("could not init point in point_cmp"); + return 1; + } + + 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); + } + + gcry_mpi_release(ax); + gcry_mpi_release(bx); + gcry_mpi_release(ay); + gcry_mpi_release(by); + return ret; +} + + /** * Convert the given private key from the network format to the * S-expression that can be used by libgcrypt. diff --git a/crypto.h b/crypto.h index 28bf4eb..0df73e4 100644 --- a/crypto.h +++ b/crypto.h @@ -25,10 +25,6 @@ #include #include -extern gcry_mpi_point_t ec_gen; -extern gcry_ctx_t ec_ctx; - - void brandt_crypto_init (); @@ -57,5 +53,7 @@ void brandt_mpi_scan_unsigned (gcry_mpi_t *result, const void *data, size_t size 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); +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 399f031..52afa35 100644 --- a/smc.c +++ b/smc.c @@ -19,17 +19,55 @@ * @brief Implementation of the smc primitives. */ +#include + +#include "crypto.h" #include "util.h" +#include "smc.h" -#include +extern gcry_ctx_t ec_ctx; +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) +{ + gcry_mpi_t z = gcry_mpi_new(0); + + brandt_ec_keypair_create_base(a, &z, g); + /**TODO: generate c from HASH(g,v,a) and don't output it */ + brandt_ec_skey_create(c); + *r = gcry_mpi_new(0); + gcry_mpi_mul(*r, *c, x); + gcry_mpi_add(*r, *r, z); + + gcry_mpi_release(z); +} + +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) +{ + int ret; + gcry_mpi_point_t left = gcry_mpi_point_new(0); + gcry_mpi_point_t right = gcry_mpi_point_new(0); + + gcry_mpi_ec_mul(left, r, g, ec_ctx); + gcry_mpi_ec_mul(right, c, v, ec_ctx); + gcry_mpi_ec_add(right, a, right, ec_ctx); + + ret = brandt_ec_point_cmp(left, right); + gcry_mpi_point_release(left); + gcry_mpi_point_release(right); + + return ret; +} + +/* GEN -smc_hextodec (const char *s) /* int */ +smc_hextodec (const char *s) { size_t i; char c; pari_sp ltop = avma; - GEN ret = gen_0; /* int */ + GEN ret = gen_0; for (i = 0; i < strlen (s); i++) { @@ -43,49 +81,4 @@ smc_hextodec (const char *s) /* int */ } return gerepilecopy (ltop, ret); } - - -void -smc_genbid (struct AuctionData *ad, uint16_t bid) -{ - uint16_t j; - pari_sp ltop = avma; - GEN ret = cgetg (itos (ad->k)+1, t_VEC); /* vec */ - - for (j = 1; j <= ad->k; j++) - { - gel (ret, j) = gpowgs (ad->g, bid == j); - } - ad->b = gerepilecopy (ltop, ret); -} - - -void -smc_genalpha (struct AuctionData *ad) -{ - uint16_t j; - pari_sp ltop = avma; - GEN ret = cgetg (ad->k+1, t_VEC); - - for (j = 1; j <= ad->k; ++j) - { - gel (ret, j) = gmul (gel (ad->b, j), gpowgi (ad->y, gel (ad->r, j))); - } - ad->alpha = gerepilecopy (ltop, ret); -} - - -void -smc_genbeta (struct AuctionData *ad) -{ - uint16_t j; - pari_sp ltop = avma; - GEN ret = cgetg (ad->k+1, t_VEC); - - for (j = 1; j <= ad->k; ++j) - { - gel (ret, j) = gpowgi (ad->g, gel (ad->r, j)); - } - ad->beta = gerepilecopy (ltop, ret); -} - +*/ diff --git a/smc.h b/smc.h new file mode 100644 index 0000000..d5a13cf --- /dev/null +++ b/smc.h @@ -0,0 +1,10 @@ + +#ifndef _BRANDT_SMC_H +#define _BRANDT_SMC_H + +#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); + +#endif diff --git a/test.h b/test.h index db63350..45ace82 100644 --- a/test.h +++ b/test.h @@ -6,7 +6,7 @@ int tests_run = 0; int ret = 0; -#define check(cond, message) do { if (!(cond)) { fputs(message, stderr); return 0; } } while (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) #endif diff --git a/test_crypto.c b/test_crypto.c index 67894eb..1bfc321 100644 --- a/test_crypto.c +++ b/test_crypto.c @@ -1,16 +1,16 @@ #include "brandt.h" #include "crypto.h" +#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_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); @@ -18,30 +18,58 @@ test_brandt_ec_keypair_create () 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"); + check(!brandt_ec_point_cmp(pkey1, pkey2), "pkeys do 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 +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_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"); + + if (first) + { + 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"); + + 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"); + + 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 main (int argc, char *argv[]) { - int repeat = 100; + int repeat = 50; int i; BRANDT_init(); @@ -49,11 +77,8 @@ main (int argc, char *argv[]) for (i = 0; i < repeat; i++) { run(test_brandt_ec_keypair_create); + run(test_smc_zkp_dl); } - if (!ret) - { - fputs("All tests passed", stderr); - } return ret; }