aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--brandt.c82
-rw-r--r--brandt.h50
-rw-r--r--crypto.c280
-rw-r--r--crypto.h87
-rw-r--r--internals.h7
-rw-r--r--test_brandt.c182
-rw-r--r--test_crypto.c101
7 files changed, 550 insertions, 239 deletions
diff --git a/brandt.c b/brandt.c
index 4a4dc49..4f5a3f5 100644
--- a/brandt.c
+++ b/brandt.c
@@ -52,11 +52,35 @@ BRANDT_init (struct GNUNET_CRYPTO_EccDlogContext *dlogctx)
void
BRANDT_bidder_start (struct BRANDT_Auction *auction,
+ uint16_t i,
uint16_t n)
{
- GNUNET_assert (n > 0);
+ GNUNET_assert (auction && n > 0 && i < 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;
+ ad->task = NULL;
+
if (0 == (ad->n = ad->start (ad->closure)))
{
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;
}
}
@@ -201,7 +227,8 @@ BRANDT_join (BRANDT_CbResult result,
const void *auction_desc,
size_t auction_desc_len,
const void *description,
- uint32_t description_len)
+ uint32_t description_len,
+ uint16_t bid)
{
struct BRANDT_Auction *ret = GNUNET_new (struct BRANDT_Auction);
@@ -220,6 +247,7 @@ BRANDT_join (BRANDT_CbResult result,
}
ret->cur_round = msg_init;
ret->round_progress = gcry_mpi_new (256);
+ ret->b = bid;
/* we are the seller */
ret->seller_mode = 0;
@@ -261,8 +289,8 @@ advance_round (struct BRANDT_Auction *ad,
enum auction_type atype,
enum outcome_type outcome)
{
- uint32_t price;
- uint16_t winner = -1;
+ struct BRANDT_Result *res;
+ uint16_t reslen = 0;
unsigned char *buf;
size_t buflen;
@@ -278,21 +306,25 @@ advance_round (struct BRANDT_Auction *ad,
if (msg_last == ++(ad->cur_round))
{
/* done with all rounds, determine outcome here */
- /** \todo: unify …_determine_outcome function signature? */
- if (auction_firstPrice == atype && outcome_private == outcome)
+ if (!handler_res[atype][outcome] ||
+ !(res = handler_res[atype][outcome] (ad, &reslen)))
{
- if (-1 == (price = fp_priv_determine_outcome (ad)))
- ad->result (ad->closure, ad->i, 0, 0);
- else
- ad->result (ad->closure, ad->i, 1, price);
- }
- else if (auction_firstPrice == atype && outcome_public == outcome)
- {
- if (-1 == (price = fp_pub_determine_outcome (ad, &winner)))
- ad->result (ad->closure, ad->i, 0, 0);
- else
- ad->result (ad->closure, winner, 1, price);
+ /** \todo */
+ weprintf ("wow fail result");
+ /** \todo: call result with null pointer here? */
+ return;
}
+
+ 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)
+ {
+ /** \todo: setup round timeout trigger */
return;
}
@@ -306,9 +338,15 @@ advance_round (struct BRANDT_Auction *ad,
/* last message only sent to seller, others are broadcasted */
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
- 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 */
if (ntohl (head->msg_type) != round || ntohl (head->prot_version) != 0)
{
+ weprintf ("%d", auction->i);
weprintf ("got unexpected message, ignoring...");
return;
}
@@ -351,6 +390,7 @@ BRANDT_got_message (struct BRANDT_Auction *auction,
return;
}
gcry_mpi_set_bit (auction->round_progress, sender);
+ DM(auction->round_progress);
/** \todo: seller_mode and new task for round timing */
advance_round (auction, atype, outcome);
diff --git a/brandt.h b/brandt.h
index 569db11..3ed48b6 100644
--- a/brandt.h
+++ b/brandt.h
@@ -28,9 +28,31 @@
#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;
+/**
+ * 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
@@ -86,22 +108,19 @@ typedef int
* Functions of this type are called by libbrandt to report the auction outcome
* 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
* 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] status 1 if the user @a bidder_id has won the auction, 0 if he has
- * lost, negative if erroneous behaviour was detected. Check the result_code
- * enum for more information.
- * @param[in] price The price, the winner has to pay or 0 if the auction result
- * is private and the user did not win.
+ * @param[in] results An array of results for one or more bidders. Each bidder
+ * will only be listed once. Misbehaving bidder results and auction completion
+ * results are not mixed.
+ * @param[in] results_len Amount of items in @a results.
*/
typedef void
-(*BRANDT_CbResult)(void *auction_closure,
- int32_t bidder_id,
- int status,
- uint16_t price);
+(*BRANDT_CbResult)(void *auction_closure,
+ struct BRANDT_Result results[],
+ uint16_t results_len);
void
@@ -159,8 +178,8 @@ BRANDT_join (BRANDT_CbResult result,
const void *auction_desc,
size_t auction_desc_len,
const void *description,
- uint32_t description_len);
-/* \todo: where do I specify my bid? */
+ uint32_t description_len,
+ uint16_t bid);
/* \todo: Distinguish handles for seller/buyers */
@@ -219,10 +238,13 @@ BRANDT_new (BRANDT_CbResult result,
* notification from the seller.
*
* @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).
*/
void
BRANDT_bidder_start (struct BRANDT_Auction *auction,
+ uint16_t i,
uint16_t n);
diff --git a/crypto.c b/crypto.c
index 965f9cc..afa72d4 100644
--- a/crypto.c
+++ b/crypto.c
@@ -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
* public key share
@@ -622,20 +630,15 @@ unsigned char *
smc_gen_keyshare (struct BRANDT_Auction *ad, size_t *buflen)
{
unsigned char *ret;
- struct proof_dl *proof1;
struct msg_head *head;
struct ec_mpi *pubkey_share;
+ struct proof_dl *proof1;
brandt_assert (ad && buflen);
*buflen = (sizeof (*head) +
sizeof (*pubkey_share) +
sizeof (*proof1));
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->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
* 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 *cur;
- struct proof_0og *proof3;
struct msg_head *head;
+ struct proof_0og *proof3;
gcry_mpi_t r_sum;
gcry_mpi_t r_part;
brandt_assert (ad && buflen);
*buflen = (sizeof (*head) + /* msg header */
ad->k * /* k * (alpha, beta, proof3) */
- (sizeof (struct ec_mpi) * 2 + /* alpha, beta */
+ (sizeof (struct ec_mpi) * 2 +
sizeof (*proof3)) +
- sizeof (struct proof_2dle));
+ sizeof (struct proof_2dle)); /* proof2 */
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->prot_version = htonl (0);
head->msg_type = htonl (msg_bid);
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_part = gcry_mpi_new (256);
@@ -822,52 +832,27 @@ quit:
}
-/**
- * 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)
+void
+fp_pub_prep_outcome (struct BRANDT_Auction *ad)
{
- unsigned char *ret;
- unsigned char *cur;
- struct msg_head *head;
gcry_mpi_t coeff = gcry_mpi_copy (GCRYMPI_CONST_ONE);
gcry_mpi_point_t tmp = 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;
- 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->k * (sizeof (*gamma) +
- 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;
- }
+ ad->delta2 = smc_init2 (ad->n, ad->k);
+ brandt_assert (ad->delta2);
- head = (struct msg_head *)ret;
- head->prot_version = htonl (0);
- head->msg_type = htonl (msg_outcome);
- cur = ret + sizeof (*head);
+ ad->tmpa1 = smc_init1 (ad->k);
+ brandt_assert (ad->tmpa1);
+
+ ad->tmpb1 = smc_init1 (ad->k);
+ brandt_assert (ad->tmpb1);
/* create temporary lookup tables with partial sums */
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++)
{
- 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
* have to be recomputed to check the ZK proof_2dle's from other
* 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->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 */
smc_zkp_2dle (ad->gamma2[ad->i][j],
ad->delta2[ad->i][j],
- tlta1[j],
- tltb1[j],
+ tmpa,
+ tmpb,
NULL,
proof2);
@@ -964,10 +997,8 @@ fp_pub_compute_outcome (struct BRANDT_Auction *ad, size_t *buflen)
cur += sizeof (*gamma) + sizeof (*delta) + sizeof (*proof2);
}
- gcry_mpi_release (coeff);
- gcry_mpi_point_release (tmp);
- smc_free1 (tlta1, ad->k);
- smc_free1 (tltb1, ad->k);
+ gcry_mpi_point_release (tmpa);
+ gcry_mpi_point_release (tmpb);
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
* 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 *cur;
- struct msg_head *head;
gcry_mpi_point_t tmp = gcry_mpi_point_new (0);
+ struct msg_head *head;
struct ec_mpi *phi;
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)));
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->prot_version = htonl (0);
@@ -1069,13 +1118,7 @@ fp_pub_decrypt_outcome (struct BRANDT_Auction *ad, size_t *buflen)
phi = (struct ec_mpi *)cur;
proof2 = (struct proof_2dle *)(cur + sizeof (*phi));
- 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);
+ ec_point_copy (tmp, ad->phi2[ad->i][j]);
/* decrypt outcome component and prove the correct key was used */
smc_zkp_2dle (ad->phi2[ad->i][j],
@@ -1138,12 +1181,13 @@ quit:
}
-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)
{
- int32_t ret = -1;
+ struct BRANDT_Result *ret;
+ int32_t price = -1;
+ int32_t winner = -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_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 */
if (ec_point_cmp (sum_gamma, ec_zero))
{
- ret = j;
+ price = j;
break;
}
}
dlogi = GNUNET_CRYPTO_ecc_dlog (ec_dlogctx, sum_gamma);
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++)
{
- if (gcry_mpi_test_bit (dlog, i))
+ /* first set bit determines the winner */
+ if (dlogi & (1 << i))
{
- if (winner)
- *winner = i;
+ winner = i;
break;
}
}
- gcry_mpi_release (dlog);
gcry_mpi_point_release (sum_gamma);
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;
}
@@ -1509,33 +1563,57 @@ quit:
}
-int32_t
-fp_priv_determine_outcome (struct BRANDT_Auction *ad)
+struct BRANDT_Result *fp_priv_determine_outcome (struct BRANDT_Auction *ad,
+ uint16_t *len)
{
- int32_t ret = -1;
- gcry_mpi_point_t sum_gamma = gcry_mpi_point_new (0);
- gcry_mpi_point_t sum_phi = gcry_mpi_point_new (0);
+ 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_phi = gcry_mpi_point_new (0);
brandt_assert (ad);
- for (uint16_t j = 0; j < ad->k; j++)
+ for (uint16_t i = 0; i < ad->n; i++)
{
- smc_sum (sum_gamma, &ad->gamma3[0][ad->i][j], ad->n, ad->n * ad->k);
- smc_sum (sum_phi, &ad->phi3[0][ad->i][j], ad->n, ad->n * ad->k);
- gcry_mpi_ec_sub (sum_gamma, sum_gamma, sum_phi, ec_ctx);
- if (!ec_point_cmp (sum_gamma, ec_zero))
+ if (!ad->seller_mode && i != ad->i)
+ continue;
+
+ for (uint16_t j = 0; j < ad->k; j++)
{
- if (-1 != ret)
+ smc_sum (sum_gamma, &ad->gamma3[0][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);
+ if (!ec_point_cmp (sum_gamma, ec_zero))
{
- weprintf ("multiple winning prices detected");
- return -1;
+ if (-1 != price)
+ {
+ weprintf ("multiple winning prices detected");
+ 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_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;
}
diff --git a/crypto.h b/crypto.h
index 2f40ed3..b3520d0 100644
--- a/crypto.h
+++ b/crypto.h
@@ -116,12 +116,14 @@ int smc_zkp_0og_check (const gcry_mpi_point_t y,
/* --- Protocol implementation --- */
+void smc_prep_keyshare (struct BRANDT_Auction *ad);
unsigned char *smc_gen_keyshare (struct BRANDT_Auction *ad, size_t *buflen);
int smc_recv_keyshare (struct BRANDT_Auction *ad,
const unsigned char *buf,
size_t buflen,
uint16_t sender_index);
+void smc_prep_bid (struct BRANDT_Auction *ad);
unsigned char *smc_encrypt_bid (struct BRANDT_Auction *ad, size_t *buflen);
int smc_recv_encrypted_bid (struct BRANDT_Auction *ad,
const unsigned char *buf,
@@ -142,8 +144,10 @@ int fp_priv_recv_decryption (struct BRANDT_Auction *ad,
size_t buflen,
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,
size_t *buflen);
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,
uint16_t sender);
+void fp_pub_prep_decryption (struct BRANDT_Auction *ad);
unsigned char *fp_pub_decrypt_outcome (struct BRANDT_Auction *ad,
size_t *buflen);
int fp_pub_recv_decryption (struct BRANDT_Auction *ad,
@@ -158,24 +163,71 @@ int fp_pub_recv_decryption (struct BRANDT_Auction *ad,
size_t buflen,
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 --- */
+typedef void
+(*RoundPrep)(struct BRANDT_Auction *ad);
+
typedef int
-(*msg_in)(struct BRANDT_Auction *ad,
+(*MsgIn)(struct BRANDT_Auction *ad,
const unsigned char *buf,
size_t buflen,
uint16_t sender);
typedef unsigned char *
-(*msg_out)(struct BRANDT_Auction *ad,
+(*MsgOut)(struct BRANDT_Auction *ad,
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.
*
* The first index denotes if a first price auction or a M+1st price auction is
@@ -185,7 +237,7 @@ typedef unsigned char *
* 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 msg_in handler_in[auction_last][outcome_last][msg_last] = {
+static const MsgIn handler_in[auction_last][outcome_last][msg_last] = {
[auction_firstPrice] = {
[outcome_private] = {
[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
* 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] = {
[outcome_private] = {
[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 */
diff --git a/internals.h b/internals.h
index 6c8b115..d88e779 100644
--- a/internals.h
+++ b/internals.h
@@ -51,13 +51,6 @@ enum outcome_type {
};
-enum result_code {
- result_loser = 0,
- result_winner = 1,
- result_no_bidders = -2
-};
-
-
GNUNET_NETWORK_STRUCT_BEGIN
struct msg_head {
diff --git a/test_brandt.c b/test_brandt.c
index fa49007..274762d 100644
--- a/test_brandt.c
+++ b/test_brandt.c
@@ -30,70 +30,160 @@
#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
run_new_join (void *arg)
{
int *ret = arg;
const char description[] = "test description for test_new_join";
- struct BRANDT_Auction *ad_seller;
- struct BRANDT_Auction *ad_bidder;
void *desc;
size_t desc_len;
- ad_seller = BRANDT_new (NULL,
- NULL,
- NULL,
- NULL,
+ ad = GNUNET_new_array (bidders + 1, struct BRANDT_Auction *);
+
+ ad[bidders] = BRANDT_new (&cb_result,
+ &cb_broadcast,
+ &cb_start,
+ &id[bidders],
&desc,
&desc_len,
description,
sizeof (description),
GNUNET_TIME_absolute_get (),
GNUNET_TIME_UNIT_MINUTES,
- 8,
- 0,
+ prizes, /* amount of possible prizes */
+ 0, /* m */
1);
- if (!ad_seller)
+ if (!ad[bidders])
{
weprintf ("BRANDT_new() failed.");
- *ret = 0;
- return;
- }
-
-
- ad_bidder = BRANDT_join (NULL,
- NULL,
- NULL,
- NULL,
- desc,
- desc_len,
- description,
- sizeof (description));
- if (!ad_bidder)
- {
- weprintf ("BRANDT_join() failed.");
- *ret = 0;
- return;
+ _exit (1);
}
- if (ad_seller->k != ad_bidder->k ||
- ad_seller->m != ad_bidder->m ||
- ad_seller->outcome_public != ad_bidder->outcome_public ||
- ad_seller->time_start.abs_value_us
- != ad_bidder->time_start.abs_value_us ||
- ad_seller->time_round.rel_value_us
- != ad_bidder->time_round.rel_value_us ||
- !ad_seller->seller_mode ||
- ad_bidder->seller_mode)
+ for (uint16_t i = 0; i < bidders; i++)
{
- weprintf ("error/mismatch in basic auction data");
- *ret = 0;
- return;
+ ad[i] = BRANDT_join (&cb_result,
+ &cb_broadcast,
+ &cb_unicast,
+ &id[i],
+ desc,
+ desc_len,
+ description,
+ sizeof (description),
+ 3); /* bid */
+ if (!ad[i])
+ {
+ weprintf ("BRANDT_join() failed.");
+ _exit (1);
+ }
+
+ if (ad[bidders]->k != ad[i]->k ||
+ ad[bidders]->m != ad[i]->m ||
+ ad[bidders]->outcome_public != ad[i]->outcome_public ||
+ ad[bidders]->time_start.abs_value_us
+ != ad[i]->time_start.abs_value_us ||
+ ad[bidders]->time_round.rel_value_us
+ != ad[i]->time_round.rel_value_us ||
+ !ad[bidders]->seller_mode || /* todo: split out */
+ ad[i]->seller_mode)
+ {
+ weprintf ("error/mismatch in basic auction data");
+ _exit (1);
+ }
}
- BRANDT_destroy (ad_seller);
- BRANDT_destroy (ad_bidder);
-
*ret = 1;
}
@@ -103,7 +193,15 @@ test_new_join ()
{
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);
+
+ for (uint16_t i = 0; i <= bidders; i++)
+ BRANDT_destroy (ad[i]);
+
return ret;
}
diff --git a/test_crypto.c b/test_crypto.c
index 53e06fe..057754a 100644
--- a/test_crypto.c
+++ b/test_crypto.c
@@ -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 { \
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]); \
CHECK (bufs[i], "failed to gen keyshare"); \
} \
@@ -228,63 +234,43 @@ test_setup_auction_data ()
static int
-test_private_first_price ()
+test_auction (enum auction_type atype, enum outcome_type oc)
{
unsigned char *bufs[bidders];
size_t lens[bidders];
int32_t winner = -1;
+ int32_t price = -1;
- ROUND (auction_firstPrice, outcome_private, msg_init);
- ROUND (auction_firstPrice, outcome_private, msg_bid);
- ROUND (auction_firstPrice, outcome_private, msg_outcome);
- ROUND (auction_firstPrice, outcome_private, msg_decrypt);
+ weprintf ("testing auction type %d and outcome format %d...", atype, oc);
+ ROUND (atype, oc, msg_init);
+ ROUND (atype, oc, msg_bid);
+ ROUND (atype, oc, msg_outcome);
+ ROUND (atype, oc, msg_decrypt);
/* outcome */
for (uint16_t i = 0; i < ad->n; i++)
{
- if (-1 != fp_priv_determine_outcome (&ad[i]))
- {
- CHECK (-1 == winner, "multiple winners detected");
- winner = i;
- }
+ struct BRANDT_Result *res;
+ uint16_t reslen;
+
+ 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 != price, "no price detected");
fputs ("good: one winner detected\n", stderr);
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
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
main (int argc, char *argv[])
{
@@ -332,12 +342,7 @@ main (int argc, char *argv[])
RUN (test_smc_zkp_0og);
}
- RUN (test_setup_auction_data);
- RUN (test_private_first_price);
- cleanup_auction_data ();
- RUN (test_setup_auction_data);
- RUN (test_public_first_price);
- cleanup_auction_data ();
+ RUN (test_all_auctions);
GNUNET_CRYPTO_ecc_dlog_release (edc);
return ret;