temporary dump for discussion

This commit is contained in:
Markus Teich 2016-08-31 14:37:22 +02:00
parent 0d3b32b248
commit 9f0e72f1e8
7 changed files with 549 additions and 238 deletions

View File

@ -52,11 +52,35 @@ BRANDT_init (struct GNUNET_CRYPTO_EccDlogContext *dlogctx)
void void
BRANDT_bidder_start (struct BRANDT_Auction *auction, BRANDT_bidder_start (struct BRANDT_Auction *auction,
uint16_t i,
uint16_t n) uint16_t n)
{ {
GNUNET_assert (n > 0); GNUNET_assert (auction && n > 0 && i < n);
auction->n = n; auction->n = n;
/** \todo: send first message */ auction->i = i;
enum auction_type atype;
enum outcome_type outcome;
unsigned char *buf;
size_t buflen;
atype = auction->m > 0 ? auction_mPlusFirstPrice : auction_firstPrice;
outcome = auction->outcome_public ? outcome_public : outcome_private;
if (handler_prep[atype][outcome][msg_init])
handler_prep[atype][outcome][msg_init] (auction);
if (!handler_out[atype][outcome][msg_init] ||
!(buf = handler_out[atype][outcome][msg_init](auction, &buflen)))
{
/** \todo */
weprintf ("wow fail out");
return;
}
weprintf("broadcasting msg_init %p from bidder %d", buf, i);
if (0 == auction->bcast (auction->closure, buf, buflen))
gcry_mpi_set_bit (auction->round_progress, auction->i);
free (buf);
} }
@ -65,10 +89,12 @@ seller_start (void *arg)
{ {
struct BRANDT_Auction *ad = (struct BRANDT_Auction *)arg; struct BRANDT_Auction *ad = (struct BRANDT_Auction *)arg;
ad->task = NULL;
if (0 == (ad->n = ad->start (ad->closure))) if (0 == (ad->n = ad->start (ad->closure)))
{ {
weprintf ("no bidders registered for auction"); weprintf ("no bidders registered for auction");
ad->result (ad->closure, -1, result_no_bidders, 0); /** todo: somehow mark auction as done / ready for cleanup */
return; return;
} }
} }
@ -201,7 +227,8 @@ BRANDT_join (BRANDT_CbResult result,
const void *auction_desc, const void *auction_desc,
size_t auction_desc_len, size_t auction_desc_len,
const void *description, const void *description,
uint32_t description_len) uint32_t description_len,
uint16_t bid)
{ {
struct BRANDT_Auction *ret = GNUNET_new (struct BRANDT_Auction); struct BRANDT_Auction *ret = GNUNET_new (struct BRANDT_Auction);
@ -220,6 +247,7 @@ BRANDT_join (BRANDT_CbResult result,
} }
ret->cur_round = msg_init; ret->cur_round = msg_init;
ret->round_progress = gcry_mpi_new (256); ret->round_progress = gcry_mpi_new (256);
ret->b = bid;
/* we are the seller */ /* we are the seller */
ret->seller_mode = 0; ret->seller_mode = 0;
@ -261,8 +289,8 @@ advance_round (struct BRANDT_Auction *ad,
enum auction_type atype, enum auction_type atype,
enum outcome_type outcome) enum outcome_type outcome)
{ {
uint32_t price; struct BRANDT_Result *res;
uint16_t winner = -1; uint16_t reslen = 0;
unsigned char *buf; unsigned char *buf;
size_t buflen; size_t buflen;
@ -278,21 +306,25 @@ advance_round (struct BRANDT_Auction *ad,
if (msg_last == ++(ad->cur_round)) if (msg_last == ++(ad->cur_round))
{ {
/* done with all rounds, determine outcome here */ /* done with all rounds, determine outcome here */
/** \todo: unify …_determine_outcome function signature? */ if (!handler_res[atype][outcome] ||
if (auction_firstPrice == atype && outcome_private == outcome) !(res = handler_res[atype][outcome] (ad, &reslen)))
{ {
if (-1 == (price = fp_priv_determine_outcome (ad))) /** \todo */
ad->result (ad->closure, ad->i, 0, 0); weprintf ("wow fail result");
else /** \todo: call result with null pointer here? */
ad->result (ad->closure, ad->i, 1, price); return;
} }
else if (auction_firstPrice == atype && outcome_public == outcome)
ad->result (ad->closure, res, reslen);
return;
}
if (handler_prep[atype][outcome][ad->cur_round])
handler_prep[atype][outcome][ad->cur_round] (ad);
if (ad->seller_mode)
{ {
if (-1 == (price = fp_pub_determine_outcome (ad, &winner))) /** \todo: setup round timeout trigger */
ad->result (ad->closure, ad->i, 0, 0);
else
ad->result (ad->closure, winner, 1, price);
}
return; return;
} }
@ -306,9 +338,15 @@ advance_round (struct BRANDT_Auction *ad,
/* last message only sent to seller, others are broadcasted */ /* last message only sent to seller, others are broadcasted */
if (msg_decrypt == ad->cur_round) if (msg_decrypt == ad->cur_round)
ad->ucast (ad->closure, buf, buflen); {
if (0 == ad->ucast (ad->closure, buf, buflen))
gcry_mpi_set_bit (ad->round_progress, ad->i);
}
else else
ad->bcast (ad->closure, buf, buflen); {
if (0 == ad->bcast (ad->closure, buf, buflen))
gcry_mpi_set_bit (ad->round_progress, ad->i);
}
} }
@ -329,6 +367,7 @@ BRANDT_got_message (struct BRANDT_Auction *auction,
/** \todo: cache out of order messages instead of discarding */ /** \todo: cache out of order messages instead of discarding */
if (ntohl (head->msg_type) != round || ntohl (head->prot_version) != 0) if (ntohl (head->msg_type) != round || ntohl (head->prot_version) != 0)
{ {
weprintf ("%d", auction->i);
weprintf ("got unexpected message, ignoring..."); weprintf ("got unexpected message, ignoring...");
return; return;
} }
@ -351,6 +390,7 @@ BRANDT_got_message (struct BRANDT_Auction *auction,
return; return;
} }
gcry_mpi_set_bit (auction->round_progress, sender); gcry_mpi_set_bit (auction->round_progress, sender);
DM(auction->round_progress);
/** \todo: seller_mode and new task for round timing */ /** \todo: seller_mode and new task for round timing */
advance_round (auction, atype, outcome); advance_round (auction, atype, outcome);

View File

@ -28,9 +28,31 @@
#include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_util_lib.h>
/** defined in internals.h */ /** Enumeration of all possible status reports for a single bidder */
enum BRANDT_BidderStatus
{
BRANDT_bidder_won,
};
/** opaque, defined in internals.h */
struct BRANDT_Auction; struct BRANDT_Auction;
/**
* An array of this struct is given to the application by the BRANDT_CbResult()
* callback. One instance represents the status of a single bidder.
*/
struct BRANDT_Result
{
/** Id of the bidder this instance refers to */
uint16_t bidder;
/** The price the bidder has to pay. This value is only set if the #status
* indicates the bidder has won. */
uint16_t price;
/** Status of the bidder */
enum BRANDT_BidderStatus status;
};
/** /**
* Functions of this type are called by libbrandt when the auction should be * Functions of this type are called by libbrandt when the auction should be
@ -86,22 +108,19 @@ typedef int
* Functions of this type are called by libbrandt to report the auction outcome * Functions of this type are called by libbrandt to report the auction outcome
* or malicious/erroneous participants. * or malicious/erroneous participants.
* *
* \todo: export proof of erroneous behaviour / outcome. * \todo: export *proof* of erroneous behaviour / outcome.
* *
* @param[in] auction_closure Closure pointer representing the respective * @param[in] auction_closure Closure pointer representing the respective
* auction. This is the Pointer given to BRANDT_join() / BRANDT_new(). * auction. This is the Pointer given to BRANDT_join() / BRANDT_new().
* @param[in] bidder_id The numeric Id of the bidder this report refers to. * @param[in] results An array of results for one or more bidders. Each bidder
* @param[in] status 1 if the user @a bidder_id has won the auction, 0 if he has * will only be listed once. Misbehaving bidder results and auction completion
* lost, negative if erroneous behaviour was detected. Check the result_code * results are not mixed.
* enum for more information. * @param[in] results_len Amount of items in @a results.
* @param[in] price The price, the winner has to pay or 0 if the auction result
* is private and the user did not win.
*/ */
typedef void typedef void
(*BRANDT_CbResult)(void *auction_closure, (*BRANDT_CbResult)(void *auction_closure,
int32_t bidder_id, struct BRANDT_Result results[],
int status, uint16_t results_len);
uint16_t price);
void void
@ -159,8 +178,8 @@ BRANDT_join (BRANDT_CbResult result,
const void *auction_desc, const void *auction_desc,
size_t auction_desc_len, size_t auction_desc_len,
const void *description, const void *description,
uint32_t description_len); uint32_t description_len,
/* \todo: where do I specify my bid? */ uint16_t bid);
/* \todo: Distinguish handles for seller/buyers */ /* \todo: Distinguish handles for seller/buyers */
@ -219,10 +238,13 @@ BRANDT_new (BRANDT_CbResult result,
* notification from the seller. * notification from the seller.
* *
* @param[in] auction The pointer returned by BRANDT_join(). * @param[in] auction The pointer returned by BRANDT_join().
* @param[in] i The index of this bidder assigned by the seller (from the start
* announcement message).
* @param[in] n The amount of bidders (from the start announcement message). * @param[in] n The amount of bidders (from the start announcement message).
*/ */
void void
BRANDT_bidder_start (struct BRANDT_Auction *auction, BRANDT_bidder_start (struct BRANDT_Auction *auction,
uint16_t i,
uint16_t n); uint16_t n);

268
crypto.c
View File

@ -609,6 +609,14 @@ smc_sum (gcry_mpi_point_t out,
} }
void
smc_prep_keyshare (struct BRANDT_Auction *ad)
{
ad->y = smc_init1 (ad->n);
brandt_assert (ad->y);
}
/** /**
* smc_gen_keyshare creates the private keyshare and computes the * smc_gen_keyshare creates the private keyshare and computes the
* public key share * public key share
@ -622,20 +630,15 @@ unsigned char *
smc_gen_keyshare (struct BRANDT_Auction *ad, size_t *buflen) smc_gen_keyshare (struct BRANDT_Auction *ad, size_t *buflen)
{ {
unsigned char *ret; unsigned char *ret;
struct proof_dl *proof1;
struct msg_head *head; struct msg_head *head;
struct ec_mpi *pubkey_share; struct ec_mpi *pubkey_share;
struct proof_dl *proof1;
brandt_assert (ad && buflen); brandt_assert (ad && buflen);
*buflen = (sizeof (*head) + *buflen = (sizeof (*head) +
sizeof (*pubkey_share) + sizeof (*pubkey_share) +
sizeof (*proof1)); sizeof (*proof1));
ret = GNUNET_new_array (*buflen, unsigned char); ret = GNUNET_new_array (*buflen, unsigned char);
if (NULL == (ad->y = smc_init1 (ad->n)))
{
weprintf ("unable to alloc memory for key shares");
return NULL;
}
head = (struct msg_head *)ret; head = (struct msg_head *)ret;
head->prot_version = htonl (0); head->prot_version = htonl (0);
@ -688,6 +691,22 @@ quit:
} }
void
smc_prep_bid (struct BRANDT_Auction *ad)
{
ad->alpha = smc_init2 (ad->n, ad->k);
brandt_assert (ad->alpha);
ad->beta = smc_init2 (ad->n, ad->k);
brandt_assert (ad->beta);
ad->Y = gcry_mpi_point_new (0);
brandt_assert (ad->Y);
smc_sum (ad->Y, ad->y, ad->n, 1);
brandt_assert (ad->Y);
}
/** /**
* smc_encrypt_bid encrypts the own bid with the shared public key and packs it * smc_encrypt_bid encrypts the own bid with the shared public key and packs it
* into a message together with proofs of correctnes. * into a message together with proofs of correctnes.
@ -702,33 +721,24 @@ smc_encrypt_bid (struct BRANDT_Auction *ad, size_t *buflen)
{ {
unsigned char *ret; unsigned char *ret;
unsigned char *cur; unsigned char *cur;
struct proof_0og *proof3;
struct msg_head *head; struct msg_head *head;
struct proof_0og *proof3;
gcry_mpi_t r_sum; gcry_mpi_t r_sum;
gcry_mpi_t r_part; gcry_mpi_t r_part;
brandt_assert (ad && buflen); brandt_assert (ad && buflen);
*buflen = (sizeof (*head) + /* msg header */ *buflen = (sizeof (*head) + /* msg header */
ad->k * /* k * (alpha, beta, proof3) */ ad->k * /* k * (alpha, beta, proof3) */
(sizeof (struct ec_mpi) * 2 + /* alpha, beta */ (sizeof (struct ec_mpi) * 2 +
sizeof (*proof3)) + sizeof (*proof3)) +
sizeof (struct proof_2dle)); sizeof (struct proof_2dle)); /* proof2 */
ret = GNUNET_new_array (*buflen, unsigned char); ret = GNUNET_new_array (*buflen, unsigned char);
if (NULL == (ad->alpha = smc_init2 (ad->n, ad->k)) ||
NULL == (ad->beta = smc_init2 (ad->n, ad->k)))
{
weprintf ("unable to alloc memory for encrypted bids");
return NULL;
}
head = (struct msg_head *)ret; head = (struct msg_head *)ret;
head->prot_version = htonl (0); head->prot_version = htonl (0);
head->msg_type = htonl (msg_bid); head->msg_type = htonl (msg_bid);
cur = ret + sizeof (*head); cur = ret + sizeof (*head);
ad->Y = gcry_mpi_point_new (0);
smc_sum (ad->Y, ad->y, ad->n, 1);
r_sum = gcry_mpi_new (256); r_sum = gcry_mpi_new (256);
r_part = gcry_mpi_new (256); r_part = gcry_mpi_new (256);
@ -822,52 +832,27 @@ quit:
} }
/** void
* fp_pub_compute_outcome computes the outcome for first price auctions with a fp_pub_prep_outcome (struct BRANDT_Auction *ad)
* public outcome and packs it into a message buffer together with proofs of
* correctnes.
*
* @param[in] ad Pointer to the BRANDT_Auction struct to operate on
* @param[out] buflen Size of the returned message buffer in bytes
* @return A buffer containing the encrypted outcome vectors
* which needs to be broadcast
*/
unsigned char *
fp_pub_compute_outcome (struct BRANDT_Auction *ad, size_t *buflen)
{ {
unsigned char *ret;
unsigned char *cur;
struct msg_head *head;
gcry_mpi_t coeff = gcry_mpi_copy (GCRYMPI_CONST_ONE); gcry_mpi_t coeff = gcry_mpi_copy (GCRYMPI_CONST_ONE);
gcry_mpi_point_t tmp = gcry_mpi_point_new (0); gcry_mpi_point_t tmp = gcry_mpi_point_new (0);
gcry_mpi_point_t *tlta1; gcry_mpi_point_t *tlta1;
gcry_mpi_point_t *tltb1; gcry_mpi_point_t *tltb1;
gcry_mpi_point_t **tlta2; gcry_mpi_point_t **tlta2;
gcry_mpi_point_t **tltb2; gcry_mpi_point_t **tltb2;
struct ec_mpi *gamma;
struct ec_mpi *delta;
struct proof_2dle *proof2;
brandt_assert (ad && buflen); ad->gamma2 = smc_init2 (ad->n, ad->k);
brandt_assert (ad->gamma2);
*buflen = (sizeof (*head) + ad->delta2 = smc_init2 (ad->n, ad->k);
ad->k * (sizeof (*gamma) + brandt_assert (ad->delta2);
sizeof (*delta) +
sizeof (*proof2)));
ret = GNUNET_new_array (*buflen, unsigned char);
if (NULL == (ad->gamma2 = smc_init2 (ad->n, ad->k)) ||
NULL == (ad->delta2 = smc_init2 (ad->n, ad->k)) ||
NULL == (ad->tmpa1 = smc_init1 (ad->k)) ||
NULL == (ad->tmpb1 = smc_init1 (ad->k)))
{
weprintf ("unable to alloc memory for first price outcome computation");
return NULL;
}
head = (struct msg_head *)ret; ad->tmpa1 = smc_init1 (ad->k);
head->prot_version = htonl (0); brandt_assert (ad->tmpa1);
head->msg_type = htonl (msg_outcome);
cur = ret + sizeof (*head); ad->tmpb1 = smc_init1 (ad->k);
brandt_assert (ad->tmpb1);
/* create temporary lookup tables with partial sums */ /* create temporary lookup tables with partial sums */
tlta1 = smc_init1 (ad->k); tlta1 = smc_init1 (ad->k);
@ -927,10 +912,6 @@ fp_pub_compute_outcome (struct BRANDT_Auction *ad, size_t *buflen)
for (uint16_t j = 0; j < ad->k; j++) 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));
/* copy unmasked outcome to all other bidder layers so they don't /* 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 * have to be recomputed to check the ZK proof_2dle's from other
* bidders when receiving their outcome messages */ * bidders when receiving their outcome messages */
@ -939,12 +920,64 @@ fp_pub_compute_outcome (struct BRANDT_Auction *ad, size_t *buflen)
ec_point_copy (ad->gamma2[a][j], tlta1[j]); ec_point_copy (ad->gamma2[a][j], tlta1[j]);
ec_point_copy (ad->delta2[a][j], tltb1[j]); ec_point_copy (ad->delta2[a][j], tltb1[j]);
} }
}
gcry_mpi_release (coeff);
gcry_mpi_point_release (tmp);
smc_free1 (tlta1, ad->k);
smc_free1 (tltb1, ad->k);
}
/**
* fp_pub_compute_outcome computes the outcome for first price auctions with a
* public outcome and packs it into a message buffer together with proofs of
* correctnes.
*
* @param[in] ad Pointer to the BRANDT_Auction struct to operate on
* @param[out] buflen Size of the returned message buffer in bytes
* @return A buffer containing the encrypted outcome vectors
* which needs to be broadcast
*/
unsigned char *
fp_pub_compute_outcome (struct BRANDT_Auction *ad, size_t *buflen)
{
unsigned char *ret;
unsigned char *cur;
gcry_mpi_point_t tmpa = gcry_mpi_point_new (0);
gcry_mpi_point_t tmpb = gcry_mpi_point_new (0);
struct msg_head *head;
struct ec_mpi *gamma;
struct ec_mpi *delta;
struct proof_2dle *proof2;
brandt_assert (ad && buflen);
*buflen = (sizeof (*head) +
ad->k * (sizeof (*gamma) +
sizeof (*delta) +
sizeof (*proof2)));
ret = GNUNET_new_array (*buflen, unsigned char);
head = (struct msg_head *)ret;
head->prot_version = htonl (0);
head->msg_type = htonl (msg_outcome);
cur = ret + sizeof (*head);
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));
ec_point_copy (tmpa, ad->gamma2[ad->i][j]);
ec_point_copy (tmpb, ad->delta2[ad->i][j]);
/* apply random masking for losing bidders */ /* apply random masking for losing bidders */
smc_zkp_2dle (ad->gamma2[ad->i][j], smc_zkp_2dle (ad->gamma2[ad->i][j],
ad->delta2[ad->i][j], ad->delta2[ad->i][j],
tlta1[j], tmpa,
tltb1[j], tmpb,
NULL, NULL,
proof2); proof2);
@ -964,10 +997,8 @@ fp_pub_compute_outcome (struct BRANDT_Auction *ad, size_t *buflen)
cur += sizeof (*gamma) + sizeof (*delta) + sizeof (*proof2); cur += sizeof (*gamma) + sizeof (*delta) + sizeof (*proof2);
} }
gcry_mpi_release (coeff); gcry_mpi_point_release (tmpa);
gcry_mpi_point_release (tmp); gcry_mpi_point_release (tmpb);
smc_free1 (tlta1, ad->k);
smc_free1 (tltb1, ad->k);
return ret; return ret;
} }
@ -1030,6 +1061,29 @@ quit:
} }
void
fp_pub_prep_decryption (struct BRANDT_Auction *ad)
{
gcry_mpi_point_t tmp = gcry_mpi_point_new (0);
ad->phi2 = smc_init2 (ad->n, ad->k);
brandt_assert (ad->phi2);
for (uint16_t j = 0; j < ad->k; j++)
{
smc_sum (tmp, &ad->delta2[0][j], 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++)
ec_point_copy (ad->phi2[a][j], tmp);
}
gcry_mpi_point_release (tmp);
}
/** /**
* fp_pub_decrypt_outcome decrypts part of the outcome and packs it into a * fp_pub_decrypt_outcome decrypts part of the outcome and packs it into a
* message buffer together with proofs of correctnes. * message buffer together with proofs of correctnes.
@ -1044,8 +1098,8 @@ fp_pub_decrypt_outcome (struct BRANDT_Auction *ad, size_t *buflen)
{ {
unsigned char *ret; unsigned char *ret;
unsigned char *cur; unsigned char *cur;
struct msg_head *head;
gcry_mpi_point_t tmp = gcry_mpi_point_new (0); gcry_mpi_point_t tmp = gcry_mpi_point_new (0);
struct msg_head *head;
struct ec_mpi *phi; struct ec_mpi *phi;
struct proof_2dle *proof2; struct proof_2dle *proof2;
@ -1053,11 +1107,6 @@ fp_pub_decrypt_outcome (struct BRANDT_Auction *ad, size_t *buflen)
*buflen = (sizeof (*head) + ad->k * (sizeof (*phi) + sizeof (*proof2))); *buflen = (sizeof (*head) + ad->k * (sizeof (*phi) + sizeof (*proof2)));
ret = GNUNET_new_array (*buflen, unsigned char); ret = GNUNET_new_array (*buflen, unsigned char);
if (NULL == (ad->phi2 = smc_init2 (ad->n, ad->k)))
{
weprintf ("unable to alloc memory for first price outcome decryption");
return NULL;
}
head = (struct msg_head *)ret; head = (struct msg_head *)ret;
head->prot_version = htonl (0); head->prot_version = htonl (0);
@ -1069,13 +1118,7 @@ fp_pub_decrypt_outcome (struct BRANDT_Auction *ad, size_t *buflen)
phi = (struct ec_mpi *)cur; phi = (struct ec_mpi *)cur;
proof2 = (struct proof_2dle *)(cur + sizeof (*phi)); proof2 = (struct proof_2dle *)(cur + sizeof (*phi));
smc_sum (tmp, &ad->delta2[0][j], ad->n, ad->k); ec_point_copy (tmp, ad->phi2[ad->i][j]);
/* 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++)
ec_point_copy (ad->phi2[a][j], tmp);
/* decrypt outcome component and prove the correct key was used */ /* decrypt outcome component and prove the correct key was used */
smc_zkp_2dle (ad->phi2[ad->i][j], smc_zkp_2dle (ad->phi2[ad->i][j],
@ -1138,12 +1181,13 @@ quit:
} }
int32_t struct BRANDT_Result *fp_pub_determine_outcome (struct BRANDT_Auction *ad,
fp_pub_determine_outcome (struct BRANDT_Auction *ad, uint16_t *winner) uint16_t *len)
{ {
int32_t ret = -1; struct BRANDT_Result *ret;
int32_t price = -1;
int32_t winner = -1;
int dlogi = -1; int dlogi = -1;
gcry_mpi_t dlog = gcry_mpi_new (256);
gcry_mpi_point_t sum_gamma = gcry_mpi_point_new (0); gcry_mpi_point_t sum_gamma = gcry_mpi_point_new (0);
gcry_mpi_point_t sum_phi = gcry_mpi_point_new (0); gcry_mpi_point_t sum_phi = gcry_mpi_point_new (0);
@ -1157,28 +1201,38 @@ fp_pub_determine_outcome (struct BRANDT_Auction *ad, uint16_t *winner)
/* first non-zero component determines the price */ /* first non-zero component determines the price */
if (ec_point_cmp (sum_gamma, ec_zero)) if (ec_point_cmp (sum_gamma, ec_zero))
{ {
ret = j; price = j;
break; break;
} }
} }
dlogi = GNUNET_CRYPTO_ecc_dlog (ec_dlogctx, sum_gamma); dlogi = GNUNET_CRYPTO_ecc_dlog (ec_dlogctx, sum_gamma);
brandt_assert (dlogi > 0); brandt_assert (dlogi > 0);
gcry_mpi_set_ui (dlog, (unsigned long)dlogi);
/* can only support up to bits(dlogi) bidders */
brandt_assert (sizeof (int) * 8 - 1 >= ad->n);
for (uint16_t i = 0; i < ad->n; i++) for (uint16_t i = 0; i < ad->n; i++)
{ {
if (gcry_mpi_test_bit (dlog, i)) /* first set bit determines the winner */
if (dlogi & (1 << i))
{ {
if (winner) winner = i;
*winner = i;
break; break;
} }
} }
gcry_mpi_release (dlog);
gcry_mpi_point_release (sum_gamma); gcry_mpi_point_release (sum_gamma);
gcry_mpi_point_release (sum_phi); gcry_mpi_point_release (sum_phi);
if (-1 == winner || -1 == price)
return NULL;
ret = GNUNET_new(struct BRANDT_Result);
ret->bidder = winner;
ret->price = price;
ret->status = BRANDT_bidder_won;
if (len)
*len = 1;
return ret; return ret;
} }
@ -1509,33 +1563,57 @@ quit:
} }
int32_t struct BRANDT_Result *fp_priv_determine_outcome (struct BRANDT_Auction *ad,
fp_priv_determine_outcome (struct BRANDT_Auction *ad) uint16_t *len)
{ {
int32_t ret = -1; struct BRANDT_Result *ret;
int32_t price = -1;
int32_t winner = -1;
gcry_mpi_point_t sum_gamma = gcry_mpi_point_new (0); gcry_mpi_point_t sum_gamma = gcry_mpi_point_new (0);
gcry_mpi_point_t sum_phi = gcry_mpi_point_new (0); gcry_mpi_point_t sum_phi = gcry_mpi_point_new (0);
brandt_assert (ad); brandt_assert (ad);
for (uint16_t i = 0; i < ad->n; i++)
{
if (!ad->seller_mode && i != ad->i)
continue;
for (uint16_t j = 0; j < ad->k; j++) for (uint16_t j = 0; j < ad->k; j++)
{ {
smc_sum (sum_gamma, &ad->gamma3[0][ad->i][j], ad->n, ad->n * ad->k); smc_sum (sum_gamma, &ad->gamma3[0][i][j], ad->n, ad->n * ad->k);
smc_sum (sum_phi, &ad->phi3[0][ad->i][j], ad->n, ad->n * ad->k); smc_sum (sum_phi, &ad->phi3[0][i][j], ad->n, ad->n * ad->k);
gcry_mpi_ec_sub (sum_gamma, sum_gamma, sum_phi, ec_ctx); gcry_mpi_ec_sub (sum_gamma, sum_gamma, sum_phi, ec_ctx);
if (!ec_point_cmp (sum_gamma, ec_zero)) if (!ec_point_cmp (sum_gamma, ec_zero))
{ {
if (-1 != ret) if (-1 != price)
{ {
weprintf ("multiple winning prices detected"); weprintf ("multiple winning prices detected");
return -1; return NULL;
}
if (-1 != winner)
{
weprintf ("multiple winners detected");
return NULL;
}
price = j;
winner = i;
} }
ret = j;
} }
} }
gcry_mpi_point_release (sum_gamma); gcry_mpi_point_release (sum_gamma);
gcry_mpi_point_release (sum_phi); gcry_mpi_point_release (sum_phi);
if (-1 == winner || -1 == price)
return NULL;
ret = GNUNET_new(struct BRANDT_Result);
ret->bidder = winner;
ret->price = price;
ret->status = BRANDT_bidder_won;
if (len)
*len = 1;
return ret; return ret;
} }

View File

@ -116,12 +116,14 @@ int smc_zkp_0og_check (const gcry_mpi_point_t y,
/* --- Protocol implementation --- */ /* --- Protocol implementation --- */
void smc_prep_keyshare (struct BRANDT_Auction *ad);
unsigned char *smc_gen_keyshare (struct BRANDT_Auction *ad, size_t *buflen); unsigned char *smc_gen_keyshare (struct BRANDT_Auction *ad, size_t *buflen);
int smc_recv_keyshare (struct BRANDT_Auction *ad, int smc_recv_keyshare (struct BRANDT_Auction *ad,
const unsigned char *buf, const unsigned char *buf,
size_t buflen, size_t buflen,
uint16_t sender_index); uint16_t sender_index);
void smc_prep_bid (struct BRANDT_Auction *ad);
unsigned char *smc_encrypt_bid (struct BRANDT_Auction *ad, size_t *buflen); unsigned char *smc_encrypt_bid (struct BRANDT_Auction *ad, size_t *buflen);
int smc_recv_encrypted_bid (struct BRANDT_Auction *ad, int smc_recv_encrypted_bid (struct BRANDT_Auction *ad,
const unsigned char *buf, const unsigned char *buf,
@ -142,8 +144,10 @@ int fp_priv_recv_decryption (struct BRANDT_Auction *ad,
size_t buflen, size_t buflen,
uint16_t sender); uint16_t sender);
int32_t fp_priv_determine_outcome (struct BRANDT_Auction *ad); struct BRANDT_Result *fp_priv_determine_outcome (struct BRANDT_Auction *ad,
uint16_t *len);
void fp_pub_prep_outcome (struct BRANDT_Auction *ad);
unsigned char *fp_pub_compute_outcome (struct BRANDT_Auction *ad, unsigned char *fp_pub_compute_outcome (struct BRANDT_Auction *ad,
size_t *buflen); size_t *buflen);
int fp_pub_recv_outcome (struct BRANDT_Auction *ad, int fp_pub_recv_outcome (struct BRANDT_Auction *ad,
@ -151,6 +155,7 @@ int fp_pub_recv_outcome (struct BRANDT_Auction *ad,
size_t buflen, size_t buflen,
uint16_t sender); uint16_t sender);
void fp_pub_prep_decryption (struct BRANDT_Auction *ad);
unsigned char *fp_pub_decrypt_outcome (struct BRANDT_Auction *ad, unsigned char *fp_pub_decrypt_outcome (struct BRANDT_Auction *ad,
size_t *buflen); size_t *buflen);
int fp_pub_recv_decryption (struct BRANDT_Auction *ad, int fp_pub_recv_decryption (struct BRANDT_Auction *ad,
@ -158,23 +163,70 @@ int fp_pub_recv_decryption (struct BRANDT_Auction *ad,
size_t buflen, size_t buflen,
uint16_t sender); uint16_t sender);
int32_t fp_pub_determine_outcome (struct BRANDT_Auction *ad, uint16_t *winner); struct BRANDT_Result *fp_pub_determine_outcome (struct BRANDT_Auction *ad,
uint16_t *len);
/* --- Round dictionaries --- */ /* --- Round dictionaries --- */
typedef void
(*RoundPrep)(struct BRANDT_Auction *ad);
typedef int typedef int
(*msg_in)(struct BRANDT_Auction *ad, (*MsgIn)(struct BRANDT_Auction *ad,
const unsigned char *buf, const unsigned char *buf,
size_t buflen, size_t buflen,
uint16_t sender); uint16_t sender);
typedef unsigned char * typedef unsigned char *
(*msg_out)(struct BRANDT_Auction *ad, (*MsgOut)(struct BRANDT_Auction *ad,
size_t *buflen); size_t *buflen);
/**
* Functions of this type determine the outcome of an auction.
*
* \todo: export *proof* of erroneous behaviour / outcome.
*
* @param[in] ad Pointer to the auction data struct.
* @param[out] len Amount of items in @a results.
* @return An array of results for one or more bidders. Each bidder
* will only be listed once.
*/
typedef struct BRANDT_Result *
(*Result)(struct BRANDT_Auction *ad,
uint16_t *len);
static const RoundPrep handler_prep[auction_last][outcome_last][msg_last] = {
[auction_firstPrice] = {
[outcome_private] = {
[msg_init] = &smc_prep_keyshare,
[msg_bid] = &smc_prep_bid,
// [msg_outcome] = &fp_priv_prep_outcome,
// [msg_decrypt] = &fp_priv_prep_decryption,
},
[outcome_public] = {
[msg_init] = &smc_prep_keyshare,
[msg_bid] = &smc_prep_bid,
[msg_outcome] = &fp_pub_prep_outcome,
[msg_decrypt] = &fp_pub_prep_decryption,
},
},
[auction_mPlusFirstPrice] = {
[outcome_private] = {
[msg_init] = &smc_prep_keyshare,
[msg_bid] = &smc_prep_bid,
},
[outcome_public] = {
[msg_init] = &smc_prep_keyshare,
[msg_bid] = &smc_prep_bid,
},
},
};
/** /**
* stores the function pointers to receive functions for each state. * stores the function pointers to receive functions for each state.
* *
@ -185,7 +237,7 @@ typedef unsigned char *
* The second index denotes if the outcome should be public or private. A value * The second index denotes if the outcome should be public or private. A value
* of 0 means a private outcome, while a value of 1 means public outcome. * of 0 means a private outcome, while a value of 1 means public outcome.
*/ */
static const msg_in handler_in[auction_last][outcome_last][msg_last] = { static const MsgIn handler_in[auction_last][outcome_last][msg_last] = {
[auction_firstPrice] = { [auction_firstPrice] = {
[outcome_private] = { [outcome_private] = {
[msg_init] = &smc_recv_keyshare, [msg_init] = &smc_recv_keyshare,
@ -224,7 +276,7 @@ static const msg_in handler_in[auction_last][outcome_last][msg_last] = {
* The second index denotes if the outcome should be public or private. A value * The second index denotes if the outcome should be public or private. A value
* of 0 means a private outcome, while a value of 1 means public outcome. * of 0 means a private outcome, while a value of 1 means public outcome.
*/ */
static const msg_out handler_out[auction_last][outcome_last][msg_last] = { static const MsgOut handler_out[auction_last][outcome_last][msg_last] = {
[auction_firstPrice] = { [auction_firstPrice] = {
[outcome_private] = { [outcome_private] = {
[msg_init] = &smc_gen_keyshare, [msg_init] = &smc_gen_keyshare,
@ -251,5 +303,28 @@ static const msg_out handler_out[auction_last][outcome_last][msg_last] = {
}, },
}; };
/**
* stores the function pointers to outcome determination functions for each
* auction mode.
*
* The first index denotes if a first price auction or a M+1st price auction is
* used. If it is 0, it is a first price auction, if it is 1, it is a M+1st
* price auction.
*
* The second index denotes if the outcome should be public or private. A value
* of 0 means a private outcome, while a value of 1 means public outcome.
*/
static const Result handler_res[auction_last][outcome_last] = {
[auction_firstPrice] = {
[outcome_private] = &fp_priv_determine_outcome,
[outcome_public] = &fp_pub_determine_outcome,
},
// [auction_mPlusFirstPrice] = {
// [outcome_private] = ,
// [outcome_public] = ,
// },
};
#endif /* ifndef _BRANDT_CRYPTO_H */ #endif /* ifndef _BRANDT_CRYPTO_H */

View File

@ -51,13 +51,6 @@ enum outcome_type {
}; };
enum result_code {
result_loser = 0,
result_winner = 1,
result_no_bidders = -2
};
GNUNET_NETWORK_STRUCT_BEGIN GNUNET_NETWORK_STRUCT_BEGIN
struct msg_head { struct msg_head {

View File

@ -30,69 +30,159 @@
#include "util.h" #include "util.h"
struct msg
{
uint16_t sender;
uint16_t receiver;
void *buf;
size_t buf_len;
};
static uint16_t *id;
static struct BRANDT_Auction **ad;
static uint16_t bidders = 3;
static uint16_t prizes = 8;
static void
bidder_start (void *arg)
{
uint16_t i = *(uint16_t *)arg;
weprintf("starting bidder %d", i);
BRANDT_bidder_start (ad[i], i, bidders);
}
static void
transfer_message (void *arg)
{
struct msg *m = (struct msg *)arg;
struct msg_head *h = (struct msg_head *)m->buf;
weprintf("xfer msg %d %x from %d to %d", ntohl(h->msg_type), arg, m->sender, m->receiver);
BRANDT_got_message (ad[m->receiver], m->sender, m->buf, m->buf_len);
free (arg);
}
static uint16_t
cb_start (void *auction_closure)
{
uint16_t *s = (uint16_t *)auction_closure;
if (!s || bidders != *s)
{
weprintf ("start callback called from bidder");
_exit (1);
}
for (uint16_t i = 0; i < bidders; i++)
GNUNET_SCHEDULER_add_now (&bidder_start, &id[i]);
return bidders;
}
static int
cb_broadcast (void *auction_closure,
const void *msg,
size_t msg_len)
{
uint16_t *s = (uint16_t *)auction_closure;
struct msg *m;
for (uint16_t i = 0; i <= bidders; i++)
{
if (i == *s)
continue;
m = GNUNET_new (struct msg);
m->sender = *s;
m->receiver = i;
m->buf = GNUNET_new_array (msg_len, unsigned char);
memcpy (m->buf, msg, msg_len);
m->buf_len = msg_len;
GNUNET_SCHEDULER_add_now (&transfer_message, m);
}
return 0;
}
static int
cb_unicast (void *auction_closure,
const void *msg,
size_t msg_len)
{
}
static void
cb_result (void *auction_closure,
struct BRANDT_Result results[],
uint16_t results_len)
{
}
static void static void
run_new_join (void *arg) run_new_join (void *arg)
{ {
int *ret = arg; int *ret = arg;
const char description[] = "test description for test_new_join"; const char description[] = "test description for test_new_join";
struct BRANDT_Auction *ad_seller;
struct BRANDT_Auction *ad_bidder;
void *desc; void *desc;
size_t desc_len; size_t desc_len;
ad_seller = BRANDT_new (NULL, ad = GNUNET_new_array (bidders + 1, struct BRANDT_Auction *);
NULL,
NULL, ad[bidders] = BRANDT_new (&cb_result,
NULL, &cb_broadcast,
&cb_start,
&id[bidders],
&desc, &desc,
&desc_len, &desc_len,
description, description,
sizeof (description), sizeof (description),
GNUNET_TIME_absolute_get (), GNUNET_TIME_absolute_get (),
GNUNET_TIME_UNIT_MINUTES, GNUNET_TIME_UNIT_MINUTES,
8, prizes, /* amount of possible prizes */
0, 0, /* m */
1); 1);
if (!ad_seller) if (!ad[bidders])
{ {
weprintf ("BRANDT_new() failed."); weprintf ("BRANDT_new() failed.");
*ret = 0; _exit (1);
return;
} }
for (uint16_t i = 0; i < bidders; i++)
ad_bidder = BRANDT_join (NULL, {
NULL, ad[i] = BRANDT_join (&cb_result,
NULL, &cb_broadcast,
NULL, &cb_unicast,
&id[i],
desc, desc,
desc_len, desc_len,
description, description,
sizeof (description)); sizeof (description),
if (!ad_bidder) 3); /* bid */
if (!ad[i])
{ {
weprintf ("BRANDT_join() failed."); weprintf ("BRANDT_join() failed.");
*ret = 0; _exit (1);
return;
} }
if (ad_seller->k != ad_bidder->k || if (ad[bidders]->k != ad[i]->k ||
ad_seller->m != ad_bidder->m || ad[bidders]->m != ad[i]->m ||
ad_seller->outcome_public != ad_bidder->outcome_public || ad[bidders]->outcome_public != ad[i]->outcome_public ||
ad_seller->time_start.abs_value_us ad[bidders]->time_start.abs_value_us
!= ad_bidder->time_start.abs_value_us || != ad[i]->time_start.abs_value_us ||
ad_seller->time_round.rel_value_us ad[bidders]->time_round.rel_value_us
!= ad_bidder->time_round.rel_value_us || != ad[i]->time_round.rel_value_us ||
!ad_seller->seller_mode || !ad[bidders]->seller_mode || /* todo: split out */
ad_bidder->seller_mode) ad[i]->seller_mode)
{ {
weprintf ("error/mismatch in basic auction data"); weprintf ("error/mismatch in basic auction data");
*ret = 0; _exit (1);
return; }
} }
BRANDT_destroy (ad_seller);
BRANDT_destroy (ad_bidder);
*ret = 1; *ret = 1;
} }
@ -103,7 +193,15 @@ test_new_join ()
{ {
int ret = 0; int ret = 0;
id = GNUNET_new_array (bidders + 1, uint16_t);
for (uint16_t i = 0; i <= bidders; i++)
id[i] = i;
GNUNET_SCHEDULER_run (&run_new_join, &ret); GNUNET_SCHEDULER_run (&run_new_join, &ret);
for (uint16_t i = 0; i <= bidders; i++)
BRANDT_destroy (ad[i]);
return ret; return ret;
} }

View File

@ -197,11 +197,17 @@ test_setup_auction_data ()
} }
/* /**
* compute round @a index of the protocol specified by @a type and @a oc
*
* @param[in] type auction type
* @param[in] oc outcome type
* @param[in] index round index
*/ */
#define ROUND(type, oc, index) do { \ #define ROUND(type, oc, index) do { \
for (uint16_t i = 0; i < bidders; i++) \ for (uint16_t i = 0; i < bidders; i++) \
{ \ { \
handler_prep[type][oc][index] (&ad[i]); \
bufs[i] = handler_out[type][oc][index] (&ad[i], &lens[i]); \ bufs[i] = handler_out[type][oc][index] (&ad[i], &lens[i]); \
CHECK (bufs[i], "failed to gen keyshare"); \ CHECK (bufs[i], "failed to gen keyshare"); \
} \ } \
@ -228,63 +234,43 @@ test_setup_auction_data ()
static int static int
test_private_first_price () test_auction (enum auction_type atype, enum outcome_type oc)
{ {
unsigned char *bufs[bidders]; unsigned char *bufs[bidders];
size_t lens[bidders]; size_t lens[bidders];
int32_t winner = -1; int32_t winner = -1;
int32_t price = -1;
ROUND (auction_firstPrice, outcome_private, msg_init); weprintf ("testing auction type %d and outcome format %d...", atype, oc);
ROUND (auction_firstPrice, outcome_private, msg_bid); ROUND (atype, oc, msg_init);
ROUND (auction_firstPrice, outcome_private, msg_outcome); ROUND (atype, oc, msg_bid);
ROUND (auction_firstPrice, outcome_private, msg_decrypt); ROUND (atype, oc, msg_outcome);
ROUND (atype, oc, msg_decrypt);
/* outcome */ /* outcome */
for (uint16_t i = 0; i < ad->n; i++) for (uint16_t i = 0; i < ad->n; i++)
{ {
if (-1 != fp_priv_determine_outcome (&ad[i])) struct BRANDT_Result *res;
{ uint16_t reslen;
CHECK (-1 == winner, "multiple winners detected");
winner = i; res = handler_res[atype][oc] (&ad[i], &reslen);
} if (res && -1 == price && -1 != res->price)
price = res->price;
if (res)
weprintf ("price: %d", res->price);
CHECK (!res || res->price == price, "different prices detected");
if (res && -1 == winner && -1 != res->bidder)
winner = res->bidder;
CHECK (!res || res->bidder == winner, "different winners detected");
} }
CHECK (-1 != winner, "no winner detected"); CHECK (-1 != winner, "no winner detected");
CHECK (-1 != price, "no price detected");
fputs ("good: one winner detected\n", stderr); fputs ("good: one winner detected\n", stderr);
return 1; return 1;
} }
static int
test_public_first_price ()
{
unsigned char *bufs[bidders];
size_t lens[bidders];
int32_t wret = -1;
int32_t pret = -1;
uint16_t winner = -1;
uint16_t price = -1;
ROUND (auction_firstPrice, outcome_public, msg_init);
ROUND (auction_firstPrice, outcome_public, msg_bid);
ROUND (auction_firstPrice, outcome_public, msg_outcome);
ROUND (auction_firstPrice, outcome_public, msg_decrypt);
/* outcome */
for (uint16_t i = 0; i < ad->n; i++)
{
price = fp_pub_determine_outcome (&ad[i], &winner);
if (-1 == pret)
pret = price;
CHECK (price == pret, "different prices detected");
if (-1 == wret)
wret = winner;
CHECK (winner == wret, "different winners detected");
}
fputs ("good: same winner detected\n", stderr);
return 1;
}
static void static void
cleanup_auction_data () cleanup_auction_data ()
{ {
@ -308,6 +294,30 @@ cleanup_auction_data ()
} }
static int
test_all_auctions ()
{
for (size_t atype = 0; atype < auction_last; atype++)
{
if (auction_firstPrice != atype) /* others not yet implemented */
continue;
// for (size_t oc = 0; oc < outcome_last; oc++)
// {
size_t oc = outcome_public;
if (!test_setup_auction_data() || !test_auction (atype, oc))
{
cleanup_auction_data ();
return 0;
}
cleanup_auction_data ();
// }
}
return 1;
}
int int
main (int argc, char *argv[]) main (int argc, char *argv[])
{ {
@ -332,12 +342,7 @@ main (int argc, char *argv[])
RUN (test_smc_zkp_0og); RUN (test_smc_zkp_0og);
} }
RUN (test_setup_auction_data); RUN (test_all_auctions);
RUN (test_private_first_price);
cleanup_auction_data ();
RUN (test_setup_auction_data);
RUN (test_public_first_price);
cleanup_auction_data ();
GNUNET_CRYPTO_ecc_dlog_release (edc); GNUNET_CRYPTO_ecc_dlog_release (edc);
return ret; return ret;