diff --git a/crypto.c b/crypto.c index 186a704..f892e7d 100644 --- a/crypto.c +++ b/crypto.c @@ -88,89 +88,6 @@ brandt_hash (const void *block, size_t size, struct brandt_hash_code *ret) } -/* --- MPI --- */ - -/** - * If target != size, move @a target bytes to the end of the size-sized - * buffer and zero out the first @a target - @a size bytes. - * - * @param buf original buffer - * @param size number of bytes in @a buf - * @param target target size of the buffer - */ -static void -adjust (void *buf, size_t size, size_t target) -{ - char *p = buf; - - if (size < target) - { - memmove (&p[target - size], buf, size); - memset (buf, 0, target - size); - } -} - - -/** - * Output the given MPI value to the given buffer in - * network byte order. - * The MPI @a val may not be negative. - * - * @param buf where to output to - * @param size number of bytes in @a buf - * @param val value to write to @a buf - */ -void -brandt_mpi_print_unsigned (void *buf, size_t size, gcry_mpi_t val) -{ - size_t rsize; - gcry_error_t rc; - - if (gcry_mpi_get_flag (val, GCRYMPI_FLAG_OPAQUE)) - { - /* Store opaque MPIs left aligned into the buffer. */ - unsigned int nbits; - const void *p; - - p = gcry_mpi_get_opaque (val, &nbits); - brandt_assert (NULL != p); - rsize = (nbits + 7) / 8; - if (rsize > size) - rsize = size; - memcpy (buf, p, rsize); - if (rsize < size) - memset (((char *)buf) + rsize, 0, size - rsize); - } - else - { - /* Store regular MPIs as unsigned integers right aligned into the buffer. */ - rsize = size; - rc = gcry_mpi_print (GCRYMPI_FMT_USG, buf, rsize, &rsize, val); - brandt_assert_gpgerr (rc); - adjust (buf, rsize, size); - } -} - - -/** - * Convert data buffer into MPI value. - * The buffer is interpreted as network - * byte order, unsigned integer. - * - * @param result where to store MPI value (allocated) - * @param data raw data (GCRYMPI_FMT_USG) - * @param size number of bytes in @a data - */ -void -brandt_mpi_scan_unsigned (gcry_mpi_t *result, const void *data, size_t size) -{ - gcry_error_t rc; - - rc = gcry_mpi_scan (result, GCRYMPI_FMT_USG, data, size, &size); - brandt_assert_gpgerr (rc); -} - - /* --- EC --- */ /** @@ -289,6 +206,145 @@ ec_point_cmp (const gcry_mpi_point_t a, const gcry_mpi_point_t b) } +/** + * mpi_serialize outputs the given MPI value to the given destination buffer in + * network byte order. The MPI @a src may not be negative. + * + * @param[out] dst where to output to + * @param[in] src value to write to @a dst + */ +void +mpi_serialize (struct ec_mpi *dst, gcry_mpi_t src) +{ + size_t rsize = 0; + unsigned int nbits; + const void *p; + gcry_error_t rc; + + if (gcry_mpi_get_flag (src, GCRYMPI_FLAG_OPAQUE)) + { + /* Store opaque MPIs left aligned into the buffer. Used by Ed25519 point + * compression */ + p = gcry_mpi_get_opaque (src, &nbits); + brandt_assert (p); + rsize = (nbits + 7) / 8; + if (rsize > sizeof (struct ec_mpi)) + rsize = sizeof (struct ec_mpi); + memcpy (dst, p, rsize); + if (rsize < sizeof (struct ec_mpi)) + memset (((char *)dst) + rsize, 0, sizeof (struct ec_mpi) - rsize); + } + else + { + /* Store regular MPIs as unsigned ints right aligned into the buffer. */ + rc = gcry_mpi_print (GCRYMPI_FMT_USG, (void *)dst, + sizeof (struct ec_mpi), &rsize, src); + brandt_assert_gpgerr (rc); + + /* Shift the output to the right, if shorter than available space */ + if (rsize && rsize < sizeof (struct ec_mpi)) + { + memmove (&dst[sizeof (struct ec_mpi) - rsize], dst, rsize); + memset (dst, 0, sizeof (struct ec_mpi) - rsize); + } + } +} + + +/** + * mpi_parse converts src buffer into MPI value. + * The buffer is interpreted as network byte order, unsigned integer. + * + * @param[out] dst where to store MPI value. Must be initialized. + * @param[in] src raw data source (GCRYMPI_FMT_USG) + */ +void +mpi_parse (gcry_mpi_t dst, const struct ec_mpi *src) +{ + gcry_mpi_t ret; + gcry_error_t rc; + + rc = gcry_mpi_scan (&ret, GCRYMPI_FMT_USG, + src, sizeof (struct ec_mpi), NULL); + brandt_assert_gpgerr (rc); + + gcry_mpi_snatch (dst, ret); +} + + +/** + * ec_point_serialize outputs the given curve point to the @a dst buffer. + * + * @param[out] dst where to write the raw data to + * @param[in] src curve point to write to @a dst + */ +void +ec_point_serialize (struct ec_mpi *dst, const gcry_mpi_point_t src) +{ + gcry_sexp_t s; + gcry_ctx_t ctx; + gcry_error_t rc; + gcry_mpi_t q; + + brandt_assert (dst); + + rc = gcry_sexp_build (&s, NULL, "(public-key(ecc(curve " CURVE ")))"); + brandt_assert_gpgerr (rc); + brandt_assert (NULL != s); + + rc = gcry_mpi_ec_new (&ctx, s, NULL); + brandt_assert_gpgerr (rc); + gcry_sexp_release (s); + + rc = gcry_mpi_ec_set_point ("q", src, ctx); + brandt_assert_gpgerr (rc); + + q = gcry_mpi_ec_get_mpi ("q@eddsa", ctx, 0); + brandt_assert (NULL != q); + gcry_ctx_release (ctx); + + mpi_serialize (dst, q); + gcry_mpi_release (q); +} + + +/** + * ec_point_parse parses a point on the Ed25519 curve from @a src into @a dst. + * + * @param[out] dst where to store the curve point. Must be initialized + * @param[in] src raw data source + */ +void +ec_point_parse (gcry_mpi_point_t dst, const struct ec_mpi *src) +{ + gcry_sexp_t s; + gcry_ctx_t ctx; + gcry_mpi_point_t ret; + gcry_error_t rc; + + rc = gcry_sexp_build (&s, NULL, "(public-key(ecc(curve " CURVE ")(q %b)))", + sizeof (struct ec_mpi), src); + 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); + gcry_mpi_ec_mul (dst, GCRYMPI_CONST_ONE, ret, ec_ctx); +} + + +/** + * smc_init2 creates a 2 dimensional array of curve points + * + * @param[in] size1 size of the first dimension + * @param[in] size2 size of the second dimension + * @return a pointer to the array. If not used anymore use smc_free2 to reclaim + * the memory. + */ static gcry_mpi_point_t ** smc_init2 (uint16_t size1, uint16_t size2) { @@ -310,6 +366,13 @@ smc_init2 (uint16_t size1, uint16_t size2) } +/** + * smc_free2 releases all points in @a dst and frees the memory + * + * @param[in,out] dst The 2 dimensional array to clean up + * @param[in] size1 size of the first dimension + * @param[in] size2 size of the second dimension + */ static void smc_free2 (gcry_mpi_point_t **dst, uint16_t size1, uint16_t size2) { @@ -322,6 +385,15 @@ smc_free2 (gcry_mpi_point_t **dst, uint16_t size1, uint16_t size2) } +/** + * smc_init3 creates a 3 dimensional array of curve points + * + * @param[in] size1 size of the first dimension + * @param[in] size2 size of the second dimension + * @param[in] size3 size of the third dimension + * @return a pointer to the array. If not used anymore use smc_free3 to reclaim + * the memory. + */ static gcry_mpi_point_t *** smc_init3 (uint16_t size1, uint16_t size2, uint16_t size3) { @@ -351,6 +423,14 @@ smc_init3 (uint16_t size1, uint16_t size2, uint16_t size3) } +/** + * smc_free3 releases all points in @a dst and frees the memory + * + * @param[in,out] dst The 3 dimensional array to clean up + * @param[in] size1 size of the first dimension + * @param[in] size2 size of the second dimension + * @param[in] size3 size of the third dimension + */ static void smc_free3 (gcry_mpi_point_t ***dst, uint16_t size1, @@ -425,6 +505,12 @@ smc_compute_pkey (struct AuctionData *ad) } +/** + * smc_gen_keyshare creates the private additive keyshare and computes the + * public multiplicative key share + * + * @param[in,out] ad Pointer to the AuctionData struct to operate on + */ void smc_gen_keyshare (struct AuctionData *ad) { @@ -439,6 +525,21 @@ smc_gen_keyshare (struct AuctionData *ad) } +/** + * smc_encrypt_bid \todo + * + * @param ad TODO + * @param j TODO + * @param a1 TODO + * @param a2 TODO + * @param b1 TODO + * @param b2 TODO + * @param c TODO + * @param d1 TODO + * @param d2 TODO + * @param r1 TODO + * @param r2 TODO + */ void smc_encrypt_bid (struct AuctionData *ad, uint16_t j, @@ -457,6 +558,27 @@ smc_encrypt_bid (struct AuctionData *ad, } +/** + * smc_compute_outcome \todo + * + * @param ad TODO + */ +void +smc_compute_outcome (struct AuctionData *ad) +{ + uint16_t i, j; + + // create temporary table with partial sums + + + for (i = 0; i < ad->n; i++) + { + + } + /*\todo ZKP*/ +} + + /** * smc_zkp_dl * @@ -481,6 +603,7 @@ smc_zkp_dl (const gcry_mpi_point_t v, /* compute challange c */ /**\todo: generate c from HASH(g,v,a) and don't output it */ +// brandt_hash (const void *block, size_t size, struct brandt_hash_code *ret) ec_skey_create (c); gcry_mpi_mod (c, c, ec_n); @@ -524,6 +647,19 @@ smc_zkp_dl_check (const gcry_mpi_point_t v, } +/** + * smc_zkp_2dle \todo + * + * @param v TODO + * @param w TODO + * @param g1 TODO + * @param g2 TODO + * @param x TODO + * @param a TODO + * @param b TODO + * @param c TODO + * @param r TODO + */ void smc_zkp_2dle (const gcry_mpi_point_t v, const gcry_mpi_point_t w, @@ -552,6 +688,19 @@ smc_zkp_2dle (const gcry_mpi_point_t v, } +/** + * smc_zkp_2dle_check \todo + * + * @param v TODO + * @param w TODO + * @param g1 TODO + * @param g2 TODO + * @param a TODO + * @param b TODO + * @param c TODO + * @param r TODO + * @return TODO + */ int smc_zkp_2dle_check (const gcry_mpi_point_t v, const gcry_mpi_point_t w, @@ -583,6 +732,23 @@ smc_zkp_2dle_check (const gcry_mpi_point_t v, } +/** + * smc_zkp_0og \todo + * + * @param alpha TODO + * @param m TODO + * @param y TODO + * @param beta TODO + * @param a1 TODO + * @param a2 TODO + * @param b1 TODO + * @param b2 TODO + * @param c TODO + * @param d1 TODO + * @param d2 TODO + * @param r1 TODO + * @param r2 TODO + */ void smc_zkp_0og (gcry_mpi_point_t alpha, const gcry_mpi_point_t m, @@ -691,6 +857,23 @@ smc_zkp_0og (gcry_mpi_point_t alpha, } +/** + * smc_zkp_0og_check \todo + * + * @param alpha TODO + * @param y TODO + * @param beta TODO + * @param a1 TODO + * @param a2 TODO + * @param b1 TODO + * @param b2 TODO + * @param c TODO + * @param d1 TODO + * @param d2 TODO + * @param r1 TODO + * @param r2 TODO + * @return TODO + */ int smc_zkp_0og_check (const gcry_mpi_point_t alpha, const gcry_mpi_point_t y, @@ -764,29 +947,6 @@ smc_zkp_0og_check (const gcry_mpi_point_t alpha, //} -//gcry_mpi_point_t -//deserialize_point(const struct brandt_point* data, const int len) -//{ -// gcry_sexp_t s; -// gcry_ctx_t ctx; -// gcry_mpi_point_t ret; -// gcry_error_t rc; -// -// 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; -//} - - ///** // * Generate a random value mod n. // * diff --git a/crypto.h b/crypto.h index aa518cd..4ccd1ca 100644 --- a/crypto.h +++ b/crypto.h @@ -44,17 +44,11 @@ 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); - - /* --- EC --- */ -struct ec_point { +/* used for serialized mpis and serialized curve points (they are the same size + * when compressed) */ +struct ec_mpi { unsigned char data[256 / 8]; }; diff --git a/test_crypto.c b/test_crypto.c index a9acdde..5f72c71 100644 --- a/test_crypto.c +++ b/test_crypto.c @@ -67,6 +67,34 @@ test_smc_3d_array () } +int +test_serialization () +{ + gcry_mpi_point_t oldp = gcry_mpi_point_new (0); + gcry_mpi_point_t newp = gcry_mpi_point_new (0); + gcry_mpi_t oldi = gcry_mpi_new (0); + gcry_mpi_t newi = gcry_mpi_new (0); + struct ec_mpi serp; + struct ec_mpi seri; + + ec_keypair_create (oldp, oldi); + + ec_point_serialize (&serp, oldp); + mpi_serialize (&seri, oldi); + + ec_point_parse (newp, &serp); + mpi_parse (newi, &seri); + + check (!ec_point_cmp (oldp, newp), "serialization changed point"); + check (!gcry_mpi_cmp (oldi, newi), "serialization changed mpi"); + + gcry_mpi_point_release (oldp); + gcry_mpi_point_release (newp); + gcry_mpi_release (oldi); + gcry_mpi_release (newi); +} + + int test_smc_zkp_dl () { @@ -210,6 +238,7 @@ main (int argc, char *argv[]) for (tests_run = 0; tests_run < repeat; tests_run++) { + run (test_serialization); run (test_smc_zkp_dl); run (test_smc_zkp_2dle); run (test_smc_zkp_0og);