add outcome computation with test
also: - enhance smc_zkp_2dle: secret can now be auto generated. - enhance sum functions: can now use custom step advancing. - add init1 and free1 for 1-dimensional point arrays. - declare loop variables inside loop header. - narrow some variable scopes.
This commit is contained in:
parent
5dbbef588d
commit
fb2bf04d38
384
crypto.c
384
crypto.c
@ -238,18 +238,13 @@ ec_point_cmp (const gcry_mpi_point_t a, const gcry_mpi_point_t b)
|
|||||||
void
|
void
|
||||||
mpi_serialize (struct ec_mpi *dst, gcry_mpi_t src)
|
mpi_serialize (struct ec_mpi *dst, gcry_mpi_t src)
|
||||||
{
|
{
|
||||||
size_t rsize = 0;
|
size_t rsize = 0;
|
||||||
unsigned int nbits;
|
|
||||||
const void *vp;
|
|
||||||
char *cp = (char *)dst;
|
|
||||||
gcry_error_t rc;
|
|
||||||
|
|
||||||
|
|
||||||
if (gcry_mpi_get_flag (src, GCRYMPI_FLAG_OPAQUE))
|
if (gcry_mpi_get_flag (src, GCRYMPI_FLAG_OPAQUE))
|
||||||
{
|
{ /* Store opaque MPIs left aligned. Used by Ed25519 point compression */
|
||||||
/* Store opaque MPIs left aligned into the buffer. Used by Ed25519 point
|
unsigned int nbits;
|
||||||
* compression */
|
const void *vp = gcry_mpi_get_opaque (src, &nbits);
|
||||||
vp = gcry_mpi_get_opaque (src, &nbits);
|
|
||||||
brandt_assert (vp);
|
brandt_assert (vp);
|
||||||
rsize = (nbits + 7) / 8;
|
rsize = (nbits + 7) / 8;
|
||||||
if (rsize > sizeof (struct ec_mpi))
|
if (rsize > sizeof (struct ec_mpi))
|
||||||
@ -259,8 +254,10 @@ mpi_serialize (struct ec_mpi *dst, gcry_mpi_t src)
|
|||||||
memset (((char *)dst) + rsize, 0, sizeof (struct ec_mpi) - rsize);
|
memset (((char *)dst) + rsize, 0, sizeof (struct ec_mpi) - rsize);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{ /* Store regular MPIs as unsigned ints right aligned into the buffer. */
|
||||||
/* Store regular MPIs as unsigned ints right aligned into the buffer. */
|
char *cp = (char *)dst;
|
||||||
|
gcry_error_t rc;
|
||||||
|
|
||||||
rc = gcry_mpi_print (GCRYMPI_FMT_USG, (void *)dst,
|
rc = gcry_mpi_print (GCRYMPI_FMT_USG, (void *)dst,
|
||||||
sizeof (struct ec_mpi), &rsize, src);
|
sizeof (struct ec_mpi), &rsize, src);
|
||||||
brandt_assert_gpgerr (rc);
|
brandt_assert_gpgerr (rc);
|
||||||
@ -365,6 +362,57 @@ ec_point_parse (gcry_mpi_point_t dst, const struct ec_mpi *src)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* smc_free1 releases all points in @a dst and frees the memory
|
||||||
|
*
|
||||||
|
* @param[in,out] dst The 1 dimensional array to clean up
|
||||||
|
* @param[in] size1 size of the first dimension
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
smc_free1 (gcry_mpi_point_t *dst, uint16_t size1)
|
||||||
|
{
|
||||||
|
if (NULL == dst)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (uint16_t i = 0; i < size1; i++)
|
||||||
|
if (NULL != dst[i])
|
||||||
|
gcry_mpi_point_release (dst[i]);
|
||||||
|
free (dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* smc_init1 creates a 1 dimensional array of curve points
|
||||||
|
*
|
||||||
|
* @param[in] size1 size of the first dimension
|
||||||
|
* @return a pointer to the array or NULL on error.
|
||||||
|
* If not used anymore use smc_free2 to reclaim the memory.
|
||||||
|
*/
|
||||||
|
static gcry_mpi_point_t *
|
||||||
|
smc_init1 (uint16_t size1)
|
||||||
|
{
|
||||||
|
gcry_mpi_point_t *ret;
|
||||||
|
|
||||||
|
if (NULL == (ret = calloc (size1, sizeof (*ret))))
|
||||||
|
{
|
||||||
|
weprintf ("could not alloc memory for 1 dimensional point array");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint16_t i = 0; i < size1; i++)
|
||||||
|
{
|
||||||
|
if (NULL == (ret[i] = gcry_mpi_point_new (0)))
|
||||||
|
{
|
||||||
|
weprintf ("could not init point in 1 dimensional array. "
|
||||||
|
"out of memory?");
|
||||||
|
smc_free1 (ret, size1);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* smc_free2 releases all points in @a dst and frees the memory
|
* smc_free2 releases all points in @a dst and frees the memory
|
||||||
*
|
*
|
||||||
@ -375,14 +423,11 @@ ec_point_parse (gcry_mpi_point_t dst, const struct ec_mpi *src)
|
|||||||
static void
|
static void
|
||||||
smc_free2 (gcry_mpi_point_t **dst, uint16_t size1, uint16_t size2)
|
smc_free2 (gcry_mpi_point_t **dst, uint16_t size1, uint16_t size2)
|
||||||
{
|
{
|
||||||
uint16_t i;
|
|
||||||
uint16_t j;
|
|
||||||
|
|
||||||
if (NULL == dst)
|
if (NULL == dst)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < size1; i++)
|
for (uint16_t i = 0; i < size1; i++)
|
||||||
for (j = 0; j < size2; j++)
|
for (uint16_t j = 0; j < size2; j++)
|
||||||
if (NULL != dst[i][j])
|
if (NULL != dst[i][j])
|
||||||
gcry_mpi_point_release (dst[i][j]);
|
gcry_mpi_point_release (dst[i][j]);
|
||||||
free (dst);
|
free (dst);
|
||||||
@ -400,8 +445,6 @@ smc_free2 (gcry_mpi_point_t **dst, uint16_t size1, uint16_t size2)
|
|||||||
static gcry_mpi_point_t **
|
static gcry_mpi_point_t **
|
||||||
smc_init2 (uint16_t size1, uint16_t size2)
|
smc_init2 (uint16_t size1, uint16_t size2)
|
||||||
{
|
{
|
||||||
uint16_t i;
|
|
||||||
uint16_t j;
|
|
||||||
gcry_mpi_point_t **ret;
|
gcry_mpi_point_t **ret;
|
||||||
gcry_mpi_point_t *data;
|
gcry_mpi_point_t *data;
|
||||||
|
|
||||||
@ -412,10 +455,10 @@ smc_init2 (uint16_t size1, uint16_t size2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
data = (gcry_mpi_point_t *)&ret[size1];
|
data = (gcry_mpi_point_t *)&ret[size1];
|
||||||
for (i = 0; i < size1; i++)
|
for (uint16_t i = 0; i < size1; i++)
|
||||||
{
|
{
|
||||||
ret[i] = &data[i * size2];
|
ret[i] = &data[i * size2];
|
||||||
for (j = 0; j < size2; j++)
|
for (uint16_t j = 0; j < size2; j++)
|
||||||
{
|
{
|
||||||
if (NULL == (ret[i][j] = gcry_mpi_point_new (0)))
|
if (NULL == (ret[i][j] = gcry_mpi_point_new (0)))
|
||||||
{
|
{
|
||||||
@ -444,16 +487,12 @@ smc_free3 (gcry_mpi_point_t ***dst,
|
|||||||
uint16_t size2,
|
uint16_t size2,
|
||||||
uint16_t size3)
|
uint16_t size3)
|
||||||
{
|
{
|
||||||
uint16_t i;
|
|
||||||
uint16_t j;
|
|
||||||
uint16_t k;
|
|
||||||
|
|
||||||
if (NULL == dst)
|
if (NULL == dst)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < size1; i++)
|
for (uint16_t i = 0; i < size1; i++)
|
||||||
for (j = 0; j < size2; j++)
|
for (uint16_t j = 0; j < size2; j++)
|
||||||
for (k = 0; k < size3; k++)
|
for (uint16_t k = 0; k < size3; k++)
|
||||||
if (NULL != dst[i][j][k])
|
if (NULL != dst[i][j][k])
|
||||||
gcry_mpi_point_release (dst[i][j][k]);
|
gcry_mpi_point_release (dst[i][j][k]);
|
||||||
free (dst);
|
free (dst);
|
||||||
@ -472,9 +511,6 @@ smc_free3 (gcry_mpi_point_t ***dst,
|
|||||||
static gcry_mpi_point_t ***
|
static gcry_mpi_point_t ***
|
||||||
smc_init3 (uint16_t size1, uint16_t size2, uint16_t size3)
|
smc_init3 (uint16_t size1, uint16_t size2, uint16_t size3)
|
||||||
{
|
{
|
||||||
uint16_t i;
|
|
||||||
uint16_t j;
|
|
||||||
uint16_t k;
|
|
||||||
gcry_mpi_point_t ***ret;
|
gcry_mpi_point_t ***ret;
|
||||||
gcry_mpi_point_t **layer1;
|
gcry_mpi_point_t **layer1;
|
||||||
gcry_mpi_point_t *layer2;
|
gcry_mpi_point_t *layer2;
|
||||||
@ -489,13 +525,13 @@ smc_init3 (uint16_t size1, uint16_t size2, uint16_t size3)
|
|||||||
|
|
||||||
layer1 = (gcry_mpi_point_t **)&ret[size1];
|
layer1 = (gcry_mpi_point_t **)&ret[size1];
|
||||||
layer2 = (gcry_mpi_point_t *)&layer1[size1 * size2];
|
layer2 = (gcry_mpi_point_t *)&layer1[size1 * size2];
|
||||||
for (i = 0; i < size1; i++)
|
for (uint16_t i = 0; i < size1; i++)
|
||||||
{
|
{
|
||||||
ret[i] = &layer1[i * size2];
|
ret[i] = &layer1[i * size2];
|
||||||
for (j = 0; j < size2; j++)
|
for (uint16_t j = 0; j < size2; j++)
|
||||||
{
|
{
|
||||||
layer1[i * size2 + j] = &layer2[(i * size2 + j) * size3];
|
layer1[i * size2 + j] = &layer2[(i * size2 + j) * size3];
|
||||||
for (k = 0; k < size3; k++)
|
for (uint16_t k = 0; k < size3; k++)
|
||||||
{
|
{
|
||||||
if (NULL == (ret[i][j][k] = gcry_mpi_point_new (0)))
|
if (NULL == (ret[i][j][k] = gcry_mpi_point_new (0)))
|
||||||
{
|
{
|
||||||
@ -515,23 +551,26 @@ smc_init3 (uint16_t size1, uint16_t size2, uint16_t size3)
|
|||||||
* smc_sums_partial calculates sums up until the current index and stores them
|
* smc_sums_partial calculates sums up until the current index and stores them
|
||||||
* in @a out. \f$\forall i \leq len: out_i=\sum_{h=1}^iin_h\f$
|
* in @a out. \f$\forall i \leq len: out_i=\sum_{h=1}^iin_h\f$
|
||||||
*
|
*
|
||||||
* @param[out] out Where to store the resulting sums. Points may be given
|
* @param[out] out Where to store the resulting sums. Points must already be
|
||||||
* uninitialized, but the appropriate amount of memory has to be allocated
|
* initialized beforehand.
|
||||||
* beforehand.
|
|
||||||
* @param[in] in Input points.
|
* @param[in] in Input points.
|
||||||
* @param[in] len The length of both @a out and @a in.
|
* @param[in] len The length of @a out. @a in must be at least @a step times @a
|
||||||
|
* len elements long.
|
||||||
|
* @param[in] stepi The amount of items to advance in @a in each step. Can be
|
||||||
|
* used to sum over multi-dimensional arrays.
|
||||||
|
* @param[in] stepo The amount of items to advance in @a out each step. Can be
|
||||||
|
* used to store the sum in multi-dimensional arrays.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
smc_sums_partial (gcry_mpi_point_t out[], gcry_mpi_point_t in[], uint16_t len)
|
smc_sums_partial (gcry_mpi_point_t out[],
|
||||||
|
gcry_mpi_point_t in[],
|
||||||
|
uint16_t len,
|
||||||
|
uint16_t stepi,
|
||||||
|
uint16_t stepo)
|
||||||
{
|
{
|
||||||
uint16_t i;
|
brandt_assert (NULL != out);
|
||||||
|
for (uint16_t i = 0, o = 0; o < len * stepo; i += stepi, o += stepo)
|
||||||
for (i = 0; i < len; i++)
|
gcry_mpi_ec_add (out[o], (o ? out[o - stepo] : ec_zero), in[i], ec_ctx);
|
||||||
{
|
|
||||||
out[i] = gcry_mpi_point_new (0);
|
|
||||||
gcry_mpi_ec_add (out[i], in[i], (i ? out[i - 1] : ec_zero), ec_ctx);
|
|
||||||
brandt_assert (NULL != out[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -541,17 +580,21 @@ smc_sums_partial (gcry_mpi_point_t out[], gcry_mpi_point_t in[], uint16_t len)
|
|||||||
*
|
*
|
||||||
* @param[out] out Where to store the result
|
* @param[out] out Where to store the result
|
||||||
* @param[in] in Input points.
|
* @param[in] in Input points.
|
||||||
* @param[in] len The length of @a in.
|
* @param[in] len The amount of summands to use from @a in. @a in must be at
|
||||||
|
* least @a step times @a len elements long.
|
||||||
|
* @param[in] step The amount of items to advance in @a in each step. Can be
|
||||||
|
* used to sum over multi-dimensional arrays.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
smc_sum (gcry_mpi_point_t out, gcry_mpi_point_t in[], uint16_t len)
|
smc_sum (gcry_mpi_point_t out,
|
||||||
|
gcry_mpi_point_t in[],
|
||||||
|
uint16_t len,
|
||||||
|
uint16_t step)
|
||||||
{
|
{
|
||||||
uint16_t i;
|
|
||||||
|
|
||||||
brandt_assert (NULL != out);
|
brandt_assert (NULL != out);
|
||||||
/**\todo: how to copy a point more efficiently? */
|
/**\todo: how to copy a point more efficiently? */
|
||||||
gcry_mpi_ec_add (out, ec_zero, ec_zero, ec_ctx);
|
gcry_mpi_ec_add (out, ec_zero, ec_zero, ec_ctx);
|
||||||
for (i = 0; i < len; i++)
|
for (uint16_t i = 0; i < len; i += step)
|
||||||
gcry_mpi_ec_add (out, out, in[i], ec_ctx);
|
gcry_mpi_ec_add (out, out, in[i], ec_ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -567,7 +610,6 @@ smc_sum (gcry_mpi_point_t out, gcry_mpi_point_t in[], uint16_t len)
|
|||||||
unsigned char *
|
unsigned char *
|
||||||
smc_gen_keyshare (struct AuctionData *ad, size_t *buflen)
|
smc_gen_keyshare (struct AuctionData *ad, size_t *buflen)
|
||||||
{
|
{
|
||||||
uint16_t i;
|
|
||||||
unsigned char *ret;
|
unsigned char *ret;
|
||||||
struct proof_dl *proof1;
|
struct proof_dl *proof1;
|
||||||
|
|
||||||
@ -581,7 +623,7 @@ smc_gen_keyshare (struct AuctionData *ad, size_t *buflen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
proof1 = (struct proof_dl *)(ret + sizeof (struct ec_mpi));
|
proof1 = (struct proof_dl *)(ret + sizeof (struct ec_mpi));
|
||||||
for (i = 0; i < ad->n; i++)
|
for (uint16_t i = 0; i < ad->n; i++)
|
||||||
ad->y[i] = gcry_mpi_point_new (0);
|
ad->y[i] = gcry_mpi_point_new (0);
|
||||||
|
|
||||||
ad->x = gcry_mpi_new (0);
|
ad->x = gcry_mpi_new (0);
|
||||||
@ -596,7 +638,7 @@ int
|
|||||||
smc_recv_keyshare (struct AuctionData *ad,
|
smc_recv_keyshare (struct AuctionData *ad,
|
||||||
unsigned char *buf,
|
unsigned char *buf,
|
||||||
size_t buflen,
|
size_t buflen,
|
||||||
uint16_t sender_index)
|
uint16_t sender)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct proof_dl *proof1;
|
struct proof_dl *proof1;
|
||||||
@ -619,7 +661,7 @@ smc_recv_keyshare (struct AuctionData *ad,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**\todo: how to copy a point more efficiently? */
|
/**\todo: how to copy a point more efficiently? */
|
||||||
gcry_mpi_ec_add (ad->y[sender_index], ec_zero, y, ec_ctx);
|
gcry_mpi_ec_add (ad->y[sender], ec_zero, y, ec_ctx);
|
||||||
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
quit:
|
quit:
|
||||||
@ -637,7 +679,6 @@ quit:
|
|||||||
unsigned char *
|
unsigned char *
|
||||||
smc_encrypt_bid (struct AuctionData *ad, size_t *buflen)
|
smc_encrypt_bid (struct AuctionData *ad, size_t *buflen)
|
||||||
{
|
{
|
||||||
uint16_t j;
|
|
||||||
unsigned char *ret;
|
unsigned char *ret;
|
||||||
unsigned char *cur;
|
unsigned char *cur;
|
||||||
struct proof_0og *proof3;
|
struct proof_0og *proof3;
|
||||||
@ -658,12 +699,12 @@ smc_encrypt_bid (struct AuctionData *ad, size_t *buflen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ad->Y = gcry_mpi_point_new (0);
|
ad->Y = gcry_mpi_point_new (0);
|
||||||
smc_sum (ad->Y, ad->y, ad->n);
|
smc_sum (ad->Y, ad->y, ad->n, 1);
|
||||||
|
|
||||||
r_sum = gcry_mpi_new (0);
|
r_sum = gcry_mpi_new (0);
|
||||||
r_part = gcry_mpi_new (0);
|
r_part = gcry_mpi_new (0);
|
||||||
|
|
||||||
for (j = 0; j < ad->k; j++)
|
for (uint16_t j = 0; j < ad->k; j++)
|
||||||
{
|
{
|
||||||
proof3 = (struct proof_0og *)(cur + 2 * sizeof (struct ec_mpi));
|
proof3 = (struct proof_0og *)(cur + 2 * sizeof (struct ec_mpi));
|
||||||
smc_zkp_0og (j == ad->b,
|
smc_zkp_0og (j == ad->b,
|
||||||
@ -690,10 +731,9 @@ int
|
|||||||
smc_recv_encrypted_bid (struct AuctionData *ad,
|
smc_recv_encrypted_bid (struct AuctionData *ad,
|
||||||
unsigned char *buf,
|
unsigned char *buf,
|
||||||
size_t buflen,
|
size_t buflen,
|
||||||
uint16_t sender_index)
|
uint16_t sender)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
uint16_t j;
|
|
||||||
unsigned char *cur = buf;
|
unsigned char *cur = buf;
|
||||||
struct proof_0og *proof3;
|
struct proof_0og *proof3;
|
||||||
gcry_mpi_point_t **ct; /* ciphertexts */
|
gcry_mpi_point_t **ct; /* ciphertexts */
|
||||||
@ -713,7 +753,7 @@ smc_recv_encrypted_bid (struct AuctionData *ad,
|
|||||||
gcry_mpi_ec_mul (alpha_sum, GCRYMPI_CONST_ONE, ec_zero, ec_ctx);
|
gcry_mpi_ec_mul (alpha_sum, GCRYMPI_CONST_ONE, ec_zero, ec_ctx);
|
||||||
gcry_mpi_ec_mul (beta_sum, GCRYMPI_CONST_ONE, ec_zero, ec_ctx);
|
gcry_mpi_ec_mul (beta_sum, GCRYMPI_CONST_ONE, ec_zero, ec_ctx);
|
||||||
|
|
||||||
for (j = 0; j < ad->k; j++)
|
for (uint16_t j = 0; j < ad->k; j++)
|
||||||
{
|
{
|
||||||
ec_point_parse (ct[0][j], (struct ec_mpi *)cur);
|
ec_point_parse (ct[0][j], (struct ec_mpi *)cur);
|
||||||
ec_point_parse (ct[1][j], &((struct ec_mpi *)cur)[1]);
|
ec_point_parse (ct[1][j], &((struct ec_mpi *)cur)[1]);
|
||||||
@ -739,11 +779,11 @@ smc_recv_encrypted_bid (struct AuctionData *ad,
|
|||||||
goto quit;
|
goto quit;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (j = 0; j < ad->k; j++)
|
for (uint16_t j = 0; j < ad->k; j++)
|
||||||
{
|
{
|
||||||
/**\todo: how to copy a point more efficiently? */
|
/**\todo: how to copy a point more efficiently? */
|
||||||
gcry_mpi_ec_add (ad->alpha[sender_index][j], ec_zero, ct[0][j], ec_ctx);
|
gcry_mpi_ec_add (ad->alpha[sender][j], ec_zero, ct[0][j], ec_ctx);
|
||||||
gcry_mpi_ec_add (ad->beta[sender_index][j], ec_zero, ct[1][j], ec_ctx);
|
gcry_mpi_ec_add (ad->beta[sender][j], ec_zero, ct[1][j], ec_ctx);
|
||||||
}
|
}
|
||||||
smc_free2 (ct, 2, ad->k);
|
smc_free2 (ct, 2, ad->k);
|
||||||
|
|
||||||
@ -759,21 +799,201 @@ quit:
|
|||||||
* smc_compute_outcome \todo
|
* smc_compute_outcome \todo
|
||||||
*
|
*
|
||||||
* @param ad TODO
|
* @param ad TODO
|
||||||
|
* @param buflen TODO
|
||||||
*/
|
*/
|
||||||
void
|
unsigned char *
|
||||||
smc_compute_outcome (struct AuctionData *ad)
|
smc_compute_outcome (struct AuctionData *ad, size_t *buflen)
|
||||||
{
|
{
|
||||||
uint16_t i;
|
unsigned char *ret;
|
||||||
uint16_t j;
|
unsigned char *cur;
|
||||||
|
gcry_mpi_point_t tmpa = gcry_mpi_point_new (0);
|
||||||
|
gcry_mpi_point_t tmpb = gcry_mpi_point_new (0);
|
||||||
|
gcry_mpi_point_t *tlta1;
|
||||||
|
gcry_mpi_point_t *tltb1;
|
||||||
|
gcry_mpi_point_t **tlta2;
|
||||||
|
gcry_mpi_point_t **tltb2;
|
||||||
|
gcry_mpi_point_t **tlta3;
|
||||||
|
gcry_mpi_point_t **tltb3;
|
||||||
|
struct ec_mpi *gamma;
|
||||||
|
struct ec_mpi *delta;
|
||||||
|
struct proof_2dle *proof2;
|
||||||
|
|
||||||
// create temporary table with partial sums
|
brandt_assert (ad && buflen);
|
||||||
|
|
||||||
|
*buflen = (ad->n * ad->k * /* nk * (gamma, delta, proof2) */
|
||||||
for (i = 0; i < ad->n; i++)
|
(sizeof (*gamma) + sizeof (*delta) + sizeof (*proof2)));
|
||||||
|
if (NULL == (cur = (ret = calloc (1, *buflen))) ||
|
||||||
|
NULL == (ad->gamma = smc_init3 (ad->n, ad->n, ad->k)) ||
|
||||||
|
NULL == (ad->delta = smc_init3 (ad->n, ad->n, ad->k)))
|
||||||
{
|
{
|
||||||
|
weprintf ("unable to alloc memory for first price outcome computation");
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
/*\todo ZKP*/
|
|
||||||
|
/* create temporary lookup tables with partial sums */
|
||||||
|
tlta1 = smc_init1 (ad->k);
|
||||||
|
tltb1 = smc_init1 (ad->k);
|
||||||
|
tlta2 = smc_init2 (ad->n, ad->k);
|
||||||
|
tltb2 = smc_init2 (ad->n, ad->k);
|
||||||
|
tlta3 = smc_init2 (ad->n, ad->k);
|
||||||
|
tltb3 = smc_init2 (ad->n, ad->k);
|
||||||
|
|
||||||
|
/* temporary lookup table for first summand (no one has a higher bid) */
|
||||||
|
for (uint16_t i = 0; i < ad->n; i++)
|
||||||
|
{
|
||||||
|
smc_sums_partial (tlta2[i], ad->alpha[i], ad->k, 1, 1);
|
||||||
|
smc_sums_partial (tltb2[i], ad->beta[i], ad->k, 1, 1);
|
||||||
|
for (uint16_t j = 0; j < ad->k; j++)
|
||||||
|
{
|
||||||
|
gcry_mpi_ec_sub (tlta3[i][j],
|
||||||
|
tlta2[i][ad->k - 1],
|
||||||
|
tlta2[i][j],
|
||||||
|
ec_ctx);
|
||||||
|
gcry_mpi_ec_sub (tltb3[i][j],
|
||||||
|
tltb2[i][ad->k - 1],
|
||||||
|
tltb2[i][j],
|
||||||
|
ec_ctx);
|
||||||
|
}
|
||||||
|
brandt_assert (!ec_point_cmp (ec_zero, tlta3[i][ad->k - 1]));
|
||||||
|
brandt_assert (!ec_point_cmp (ec_zero, tltb3[i][ad->k - 1]));
|
||||||
|
}
|
||||||
|
for (uint16_t j = 0; j < ad->k; j++)
|
||||||
|
{
|
||||||
|
smc_sum (tlta1[j], &tlta3[0][j], ad->n, ad->k);
|
||||||
|
smc_sum (tltb1[j], &tltb3[0][j], ad->n, ad->k);
|
||||||
|
}
|
||||||
|
brandt_assert (!ec_point_cmp (ec_zero, tlta1[ad->k - 1]));
|
||||||
|
brandt_assert (!ec_point_cmp (ec_zero, tltb1[ad->k - 1]));
|
||||||
|
/* \todo: merge into one nested i,j loop and one nested j,i loop? */
|
||||||
|
|
||||||
|
/* temporary lookup table for second summand (my bid is not lower) */
|
||||||
|
for (uint16_t i = 0; i < ad->n; i++)
|
||||||
|
{
|
||||||
|
for (uint16_t j = 0; j < ad->k; j++)
|
||||||
|
{
|
||||||
|
gcry_mpi_ec_sub (tlta2[i][j], tlta2[i][j], ad->alpha[i][j], ec_ctx);
|
||||||
|
gcry_mpi_ec_sub (tltb2[i][j], tltb2[i][j], ad->beta[i][j], ec_ctx);
|
||||||
|
}
|
||||||
|
brandt_assert (!ec_point_cmp (ec_zero, tlta2[i][0]));
|
||||||
|
brandt_assert (!ec_point_cmp (ec_zero, tltb2[i][0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* temporary lookup table for third summand (no one with a lower index has
|
||||||
|
* the same bid) */
|
||||||
|
for (uint16_t j = 0; j < ad->k; j++)
|
||||||
|
{
|
||||||
|
smc_sums_partial (&tlta3[0][j], &ad->alpha[0][j], ad->n, ad->k, ad->k);
|
||||||
|
smc_sums_partial (&tltb3[0][j], &ad->beta[0][j], ad->n, ad->k, ad->k);
|
||||||
|
for (uint16_t i = 0; i < ad->n; i++)
|
||||||
|
{
|
||||||
|
gcry_mpi_ec_sub (tlta3[i][j], tlta3[i][j], ad->alpha[i][j], ec_ctx);
|
||||||
|
gcry_mpi_ec_sub (tltb3[i][j], tltb3[i][j], ad->beta[i][j], ec_ctx);
|
||||||
|
}
|
||||||
|
brandt_assert (!ec_point_cmp (ec_zero, tlta3[0][j]));
|
||||||
|
brandt_assert (!ec_point_cmp (ec_zero, tltb3[0][j]));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint16_t i = 0; i < ad->n; i++)
|
||||||
|
{
|
||||||
|
for (uint16_t j = 0; j < ad->k; j++)
|
||||||
|
{
|
||||||
|
gamma = (struct ec_mpi *)cur;
|
||||||
|
delta = &((struct ec_mpi *)cur)[1];
|
||||||
|
proof2 = (struct proof_2dle *)(cur + 2 * sizeof (struct ec_mpi));
|
||||||
|
|
||||||
|
/* compute inner gamma */
|
||||||
|
gcry_mpi_ec_add (tmpa, tlta1[j], tlta2[i][j], ec_ctx);
|
||||||
|
gcry_mpi_ec_add (tmpa, tmpa, tlta3[i][j], ec_ctx);
|
||||||
|
|
||||||
|
/* compute inner delta */
|
||||||
|
gcry_mpi_ec_add (tmpb, tltb1[j], tltb2[i][j], ec_ctx);
|
||||||
|
gcry_mpi_ec_add (tmpb, tmpb, tltb3[i][j], ec_ctx);
|
||||||
|
|
||||||
|
/* copy unmasked outcome to all other bidder layers so they don't
|
||||||
|
* have to be recomputed to check the ZK proof_2dle's from other
|
||||||
|
* bidders when receiving their outcome messages */
|
||||||
|
for (uint16_t a = 0; a < ad->n; a++)
|
||||||
|
{
|
||||||
|
/**\todo: how to copy a point more efficiently? */
|
||||||
|
gcry_mpi_ec_add (ad->gamma[a][i][j], ec_zero, tmpa, ec_ctx);
|
||||||
|
gcry_mpi_ec_add (ad->delta[a][i][j], ec_zero, tmpb, ec_ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* apply random masking for losing bidders */
|
||||||
|
smc_zkp_2dle (ad->gamma[ad->i][i][j],
|
||||||
|
ad->delta[ad->i][i][j],
|
||||||
|
tmpa,
|
||||||
|
tmpb,
|
||||||
|
NULL,
|
||||||
|
proof2);
|
||||||
|
|
||||||
|
ec_point_serialize (gamma, ad->gamma[ad->i][i][j]);
|
||||||
|
ec_point_serialize (delta, ad->delta[ad->i][i][j]);
|
||||||
|
|
||||||
|
cur += sizeof (*gamma) + sizeof (*delta) + sizeof (*proof2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gcry_mpi_point_release (tmpa);
|
||||||
|
gcry_mpi_point_release (tmpb);
|
||||||
|
smc_free1 (tlta1, ad->n);
|
||||||
|
smc_free1 (tltb1, ad->n);
|
||||||
|
smc_free2 (tlta2, ad->n, ad->k);
|
||||||
|
smc_free2 (tltb2, ad->n, ad->k);
|
||||||
|
smc_free2 (tlta3, ad->n, ad->k);
|
||||||
|
smc_free2 (tltb3, ad->n, ad->k);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
smc_recv_outcome (struct AuctionData *ad,
|
||||||
|
unsigned char *buf,
|
||||||
|
size_t buflen,
|
||||||
|
uint16_t sender)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
unsigned char *cur = buf;
|
||||||
|
struct proof_2dle *proof2;
|
||||||
|
gcry_mpi_point_t gamma = gcry_mpi_point_new (0);
|
||||||
|
gcry_mpi_point_t delta = gcry_mpi_point_new (0);
|
||||||
|
|
||||||
|
brandt_assert (ad && buf);
|
||||||
|
|
||||||
|
if (buflen != (ad->n * ad->k *
|
||||||
|
(2 * sizeof (struct ec_mpi) + sizeof (*proof2))))
|
||||||
|
{
|
||||||
|
weprintf ("wrong size of received encrypted bid");
|
||||||
|
goto quit;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint16_t i = 0; i < ad->n; i++)
|
||||||
|
{
|
||||||
|
for (uint16_t j = 0; j < ad->k; j++)
|
||||||
|
{
|
||||||
|
ec_point_parse (gamma, (struct ec_mpi *)cur);
|
||||||
|
ec_point_parse (delta, &((struct ec_mpi *)cur)[1]);
|
||||||
|
proof2 = (struct proof_2dle *)(cur + 2 * sizeof (struct ec_mpi));
|
||||||
|
if (smc_zkp_2dle_check (gamma,
|
||||||
|
delta,
|
||||||
|
ad->gamma[sender][i][j],
|
||||||
|
ad->delta[sender][i][j],
|
||||||
|
proof2))
|
||||||
|
{
|
||||||
|
weprintf ("wrong zkp2 for gamma, delta received");
|
||||||
|
goto quit;
|
||||||
|
}
|
||||||
|
gcry_mpi_ec_add (ad->gamma[sender][i][j], gamma, ec_zero, ec_ctx);
|
||||||
|
gcry_mpi_ec_add (ad->delta[sender][i][j], delta, ec_zero, ec_ctx);
|
||||||
|
cur += 2 * sizeof (struct ec_mpi) + sizeof (*proof2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 1;
|
||||||
|
quit:
|
||||||
|
gcry_mpi_point_release (gamma);
|
||||||
|
gcry_mpi_point_release (delta);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -885,7 +1105,8 @@ smc_zkp_dl_check (const gcry_mpi_point_t v,
|
|||||||
* Must be known to the verifier.
|
* Must be known to the verifier.
|
||||||
* @param[in] g1 first base point. Must be known to the verifier.
|
* @param[in] g1 first base point. Must be known to the verifier.
|
||||||
* @param[in] g2 second base point. Must be known to the verifier.
|
* @param[in] g2 second base point. Must be known to the verifier.
|
||||||
* @param[in] x private number to prove knowledge of.
|
* @param[in] x private number to prove knowledge of. May be NULL if not used by
|
||||||
|
* the caller.
|
||||||
* @param[out] proof pointer where to save the output proof structure. Must be
|
* @param[out] proof pointer where to save the output proof structure. Must be
|
||||||
* shared with the verifier.
|
* shared with the verifier.
|
||||||
*/
|
*/
|
||||||
@ -901,6 +1122,7 @@ smc_zkp_2dle (gcry_mpi_point_t v,
|
|||||||
struct brandt_hash_code challhash;
|
struct brandt_hash_code challhash;
|
||||||
gcry_mpi_point_t rv;
|
gcry_mpi_point_t rv;
|
||||||
gcry_mpi_point_t rw;
|
gcry_mpi_point_t rw;
|
||||||
|
gcry_mpi_t rx;
|
||||||
gcry_mpi_point_t a = gcry_mpi_point_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 b = gcry_mpi_point_new (0);
|
||||||
gcry_mpi_t r = gcry_mpi_new (0);
|
gcry_mpi_t r = gcry_mpi_new (0);
|
||||||
@ -909,12 +1131,16 @@ smc_zkp_2dle (gcry_mpi_point_t v,
|
|||||||
|
|
||||||
rv = (NULL == v) ? gcry_mpi_point_new (0) : v;
|
rv = (NULL == v) ? gcry_mpi_point_new (0) : v;
|
||||||
rw = (NULL == w) ? gcry_mpi_point_new (0) : w;
|
rw = (NULL == w) ? gcry_mpi_point_new (0) : w;
|
||||||
|
rx = (NULL == x) ? gcry_mpi_new (0) : x;
|
||||||
|
|
||||||
|
if (NULL == x)
|
||||||
|
ec_skey_create (rx);
|
||||||
|
|
||||||
/* v = x*g1 */
|
/* v = x*g1 */
|
||||||
gcry_mpi_ec_mul (rv, x, g1, ec_ctx);
|
gcry_mpi_ec_mul (rv, rx, g1, ec_ctx);
|
||||||
|
|
||||||
/* w = x*g2 */
|
/* w = x*g2 */
|
||||||
gcry_mpi_ec_mul (rw, x, g2, ec_ctx);
|
gcry_mpi_ec_mul (rw, rx, g2, ec_ctx);
|
||||||
|
|
||||||
/* a = z*g1 */
|
/* a = z*g1 */
|
||||||
ec_keypair_create_base (a, z, g1);
|
ec_keypair_create_base (a, z, g1);
|
||||||
@ -934,7 +1160,7 @@ smc_zkp_2dle (gcry_mpi_point_t v,
|
|||||||
gcry_mpi_mod (c, c, ec_n);
|
gcry_mpi_mod (c, c, ec_n);
|
||||||
|
|
||||||
/* r = z + cx */
|
/* r = z + cx */
|
||||||
gcry_mpi_mulm (r, c, x, ec_n);
|
gcry_mpi_mulm (r, c, rx, ec_n);
|
||||||
gcry_mpi_addm (r, r, z, ec_n);
|
gcry_mpi_addm (r, r, z, ec_n);
|
||||||
|
|
||||||
mpi_serialize (&proof->r, r);
|
mpi_serialize (&proof->r, r);
|
||||||
@ -945,6 +1171,8 @@ smc_zkp_2dle (gcry_mpi_point_t v,
|
|||||||
gcry_mpi_point_release (rv);
|
gcry_mpi_point_release (rv);
|
||||||
if (NULL == w)
|
if (NULL == w)
|
||||||
gcry_mpi_point_release (rw);
|
gcry_mpi_point_release (rw);
|
||||||
|
if (NULL == x)
|
||||||
|
gcry_mpi_release (rx);
|
||||||
gcry_mpi_point_release (a);
|
gcry_mpi_point_release (a);
|
||||||
gcry_mpi_point_release (b);
|
gcry_mpi_point_release (b);
|
||||||
gcry_mpi_release (r);
|
gcry_mpi_release (r);
|
||||||
|
5
crypto.h
5
crypto.h
@ -123,4 +123,9 @@ int smc_recv_encrypted_bid (struct AuctionData *ad,
|
|||||||
size_t buflen,
|
size_t buflen,
|
||||||
uint16_t sender_index);
|
uint16_t sender_index);
|
||||||
|
|
||||||
|
unsigned char *smc_compute_outcome (struct AuctionData *ad, size_t *buflen);
|
||||||
|
int smc_recv_outcome (struct AuctionData *ad,
|
||||||
|
unsigned char *buf,
|
||||||
|
size_t buflen,
|
||||||
|
uint16_t sender);
|
||||||
#endif /* ifndef _BRANDT_CRYPTO_H */
|
#endif /* ifndef _BRANDT_CRYPTO_H */
|
||||||
|
@ -257,6 +257,36 @@ test_round1 ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
test_round2 ()
|
||||||
|
{
|
||||||
|
uint16_t i, s;
|
||||||
|
unsigned char *bufs[bidders];
|
||||||
|
size_t lens[bidders];
|
||||||
|
|
||||||
|
for (i = 0; i < bidders; i++)
|
||||||
|
{
|
||||||
|
bufs[i] = smc_compute_outcome (&ad[i], &lens[i]);
|
||||||
|
check (bufs[i], "failed to encrypt bid");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < bidders; i++)
|
||||||
|
{
|
||||||
|
for (s = 0; s < bidders; s++)
|
||||||
|
{
|
||||||
|
if (s == i)
|
||||||
|
continue;
|
||||||
|
check (smc_recv_outcome (&ad[i], bufs[s], lens[s], s),
|
||||||
|
"failed checking outcome");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < bidders; i++)
|
||||||
|
free (bufs[i]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
cleanup_auction_data ()
|
cleanup_auction_data ()
|
||||||
{
|
{
|
||||||
@ -299,6 +329,7 @@ main (int argc, char *argv[])
|
|||||||
run (test_setup_auction_data);
|
run (test_setup_auction_data);
|
||||||
run (test_prologue);
|
run (test_prologue);
|
||||||
run (test_round1);
|
run (test_round1);
|
||||||
|
run (test_round2);
|
||||||
cleanup_auction_data ();
|
cleanup_auction_data ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user