add outcome decryption plus test

This commit is contained in:
Markus Teich 2016-06-28 17:24:59 +02:00
parent 81fb449262
commit 1a6dc56f1a
3 changed files with 147 additions and 3 deletions

110
crypto.c
View File

@ -820,7 +820,7 @@ smc_compute_outcome (struct AuctionData *ad, size_t *buflen)
brandt_assert (ad && buflen); brandt_assert (ad && buflen);
*buflen = (ad->n * ad->k * /* nk * (gamma, delta, proof2) */ *buflen = (ad->n * ad->k * /* nk * (gamma, delta, proof2) */
(sizeof (*gamma) + sizeof (*delta) + sizeof (*proof2))); (sizeof (*gamma) + sizeof (*delta) + sizeof (*proof2)));
if (NULL == (cur = (ret = calloc (1, *buflen))) || if (NULL == (cur = (ret = calloc (1, *buflen))) ||
NULL == (ad->gamma = smc_init3 (ad->n, ad->n, ad->k)) || NULL == (ad->gamma = smc_init3 (ad->n, ad->n, ad->k)) ||
@ -963,7 +963,7 @@ smc_recv_outcome (struct AuctionData *ad,
if (buflen != (ad->n * ad->k * if (buflen != (ad->n * ad->k *
(2 * sizeof (struct ec_mpi) + sizeof (*proof2)))) (2 * sizeof (struct ec_mpi) + sizeof (*proof2))))
{ {
weprintf ("wrong size of received encrypted bid"); weprintf ("wrong size of received outcome");
goto quit; goto quit;
} }
@ -997,6 +997,112 @@ quit:
} }
/**
* smc_decrypt_outcome \todo
*
* @param ad TODO
* @param buflen TODO
*/
unsigned char *
smc_decrypt_outcome (struct AuctionData *ad, size_t *buflen)
{
unsigned char *ret;
unsigned char *cur;
gcry_mpi_point_t tmp = gcry_mpi_point_new (0);
struct ec_mpi *phi;
struct proof_2dle *proof2;
brandt_assert (ad && buflen);
*buflen = (ad->n * ad->k * (sizeof (*phi) + sizeof (*proof2)));
if (NULL == (cur = (ret = calloc (1, *buflen))) ||
NULL == (ad->phi = smc_init3 (ad->n, ad->n, ad->k)))
{
weprintf ("unable to alloc memory for first price outcome decryption");
return NULL;
}
for (uint16_t i = 0; i < ad->n; i++)
{
for (uint16_t j = 0; j < ad->k; j++)
{
phi = (struct ec_mpi *)cur;
proof2 = (struct proof_2dle *)(cur + sizeof (*phi));
smc_sum (tmp, &ad->delta[0][i][j], ad->n, ad->n * ad->k);
/* copy still encrypted 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 decryption messages */
for (uint16_t a = 0; a < ad->n; a++)
/**\todo: how to copy a point more efficiently? */
gcry_mpi_ec_add (ad->phi[a][i][j], ec_zero, tmp, ec_ctx);
/* decrypt outcome component and prove the correct key was used */
smc_zkp_2dle (ad->phi[ad->i][i][j],
NULL,
tmp,
ec_gen,
ad->x,
proof2);
ec_point_serialize (phi, ad->phi[ad->i][i][j]);
cur += sizeof (*phi) + sizeof (*proof2);
}
}
gcry_mpi_point_release (tmp);
return ret;
}
int
smc_recv_decryption (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 phi = gcry_mpi_point_new (0);
brandt_assert (ad && buf);
if (buflen != (ad->n * ad->k * (sizeof (struct ec_mpi) + sizeof (*proof2))))
{
weprintf ("wrong size of received outcome decryption");
goto quit;
}
for (uint16_t i = 0; i < ad->n; i++)
{
for (uint16_t j = 0; j < ad->k; j++)
{
ec_point_parse (phi, (struct ec_mpi *)cur);
proof2 = (struct proof_2dle *)(cur + sizeof (struct ec_mpi));
if (smc_zkp_2dle_check (phi,
ad->y[sender],
ad->phi[sender][i][j],
ec_gen,
proof2))
{
weprintf ("wrong zkp2 for phi, y received");
goto quit;
}
gcry_mpi_ec_add (ad->phi[sender][i][j], phi, ec_zero, ec_ctx);
cur += sizeof (struct ec_mpi) + sizeof (*proof2);
}
}
ret = 1;
quit:
gcry_mpi_point_release (phi);
return ret;
}
/** /**
* smc_zkp_dl creates a proof of knowledge of @a x with \f$v = xg\f$ where * smc_zkp_dl creates a proof of knowledge of @a x with \f$v = xg\f$ where
* \f$g\f$ is the base point on Ed25519. * \f$g\f$ is the base point on Ed25519.

View File

@ -128,4 +128,11 @@ int smc_recv_outcome (struct AuctionData *ad,
unsigned char *buf, unsigned char *buf,
size_t buflen, size_t buflen,
uint16_t sender); uint16_t sender);
unsigned char *smc_decrypt_outcome (struct AuctionData *ad, size_t *buflen);
int smc_recv_decryption (struct AuctionData *ad,
unsigned char *buf,
size_t buflen,
uint16_t sender);
#endif /* ifndef _BRANDT_CRYPTO_H */ #endif /* ifndef _BRANDT_CRYPTO_H */

View File

@ -267,7 +267,7 @@ test_round2 ()
for (i = 0; i < bidders; i++) for (i = 0; i < bidders; i++)
{ {
bufs[i] = smc_compute_outcome (&ad[i], &lens[i]); bufs[i] = smc_compute_outcome (&ad[i], &lens[i]);
check (bufs[i], "failed to encrypt bid"); check (bufs[i], "failed to compute outcome");
} }
for (i = 0; i < bidders; i++) for (i = 0; i < bidders; i++)
@ -287,6 +287,36 @@ test_round2 ()
} }
int
test_round3 ()
{
uint16_t i, s;
unsigned char *bufs[bidders];
size_t lens[bidders];
for (i = 0; i < bidders; i++)
{
bufs[i] = smc_decrypt_outcome (&ad[i], &lens[i]);
check (bufs[i], "failed to decrypt outcome");
}
for (i = 0; i < bidders; i++)
{
for (s = 0; s < bidders; s++)
{
if (s == i)
continue;
check (smc_recv_decryption (&ad[i], bufs[s], lens[s], s),
"failed checking decrypted outcome");
}
}
for (i = 0; i < bidders; i++)
free (bufs[i]);
return 1;
}
void void
cleanup_auction_data () cleanup_auction_data ()
{ {
@ -330,6 +360,7 @@ main (int argc, char *argv[])
run (test_prologue); run (test_prologue);
run (test_round1); run (test_round1);
run (test_round2); run (test_round2);
run (test_round3);
cleanup_auction_data (); cleanup_auction_data ();
} }