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
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);

View File

@ -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);

280
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
* 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;
}

View File

@ -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,23 +163,70 @@ 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.
*
@ -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 */

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
struct msg_head {

View File

@ -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;
_exit (1);
}
ad_bidder = BRANDT_join (NULL,
NULL,
NULL,
NULL,
desc,
desc_len,
description,
sizeof (description));
if (!ad_bidder)
for (uint16_t i = 0; i < bidders; i++)
{
weprintf ("BRANDT_join() failed.");
*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_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)
{
weprintf ("error/mismatch in basic auction data");
*ret = 0;
return;
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;
}

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 { \
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;