diff options
Diffstat (limited to 'brandt.c')
-rw-r--r-- | brandt.c | 860 |
1 files changed, 430 insertions, 430 deletions
@@ -30,499 +30,499 @@ void BRANDT_init () { - gcry_error_t err = 0; - - if (!gcry_check_version ("1.7.0")) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, - "libbrandt", - "libgcrypt version mismatch\n"); - GNUNET_abort_ (); - } - - /* SECMEM cannot be resized dynamically. We do not know how much we need */ - if ((err = gcry_control (GCRYCTL_DISABLE_SECMEM, 0))) - GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, - "libbrandt", - "failed to set libgcrypt option DISABLE_SECMEM: %s\n", - gcry_strerror (err)); - - /* ecc is slow otherwise and we don't create long term keys anyway. */ - if ((err = gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0))) - GNUNET_log_from ( - GNUNET_ERROR_TYPE_WARNING, - "libbrandt", - "failed to set libgcrypt option ENABLE_QUICK_RANDOM: %s\n", - gcry_strerror (err)); - - gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); - brandt_crypto_init (); + gcry_error_t err = 0; + + if (! gcry_check_version ("1.7.0")) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, + "libbrandt", + "libgcrypt version mismatch\n"); + GNUNET_abort_ (); + } + + /* SECMEM cannot be resized dynamically. We do not know how much we need */ + if ((err = gcry_control (GCRYCTL_DISABLE_SECMEM, 0))) + GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, + "libbrandt", + "failed to set libgcrypt option DISABLE_SECMEM: %s\n", + gcry_strerror (err)); + + /* ecc is slow otherwise and we don't create long term keys anyway. */ + if ((err = gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0))) + GNUNET_log_from ( + GNUNET_ERROR_TYPE_WARNING, + "libbrandt", + "failed to set libgcrypt option ENABLE_QUICK_RANDOM: %s\n", + gcry_strerror (err)); + + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + brandt_crypto_init (); } void BRANDT_bidder_start (struct BRANDT_Auction *auction, - uint16_t i, - uint16_t n) + uint16_t i, + uint16_t n) { - enum auction_type atype; - enum outcome_type outcome; - unsigned char *buf; - size_t buflen; - - GNUNET_assert (auction && n > 0 && i < n); - auction->n = n; - auction->i = i; - - atype = auction->m > 0 ? auction_mPlusFirstPrice : auction_firstPrice; - outcome = auction->outcome_public ? outcome_public : outcome_private; - - if (auction_mPlusFirstPrice == atype && n <= auction->m) - { /* fewer bidders than items to sell. every bidder won with lowest price */ - struct BRANDT_Result *res; - if (auction->outcome_public) - { - res = GNUNET_new_array (n, struct BRANDT_Result); - for (uint16_t h = 0; h < n; h++) - { - res[h].bidder = h; - res[h].price = 0; - res[h].status = BRANDT_bidder_won; - } - auction->result (auction->closure, res, n); - } - else - { - res = GNUNET_new (struct BRANDT_Result); - res->bidder = i; - res->price = 0; - res->status = BRANDT_bidder_won; - auction->result (auction->closure, res, 1); - } - return; - } - - /* On M+1st price auctions we multiply the amount of prizes by the amount of - * bidders and resctrict each bidder to his own distinct subset of the - * prices. This is done for tie breaking. An additional proof is used in the - * encrypt_bid round to show that the bidder has chosen a valid bid and the - * outcome callback will remap the result to the original k price values. */ - if (auction_mPlusFirstPrice == atype) - { - auction->k *= n; - auction->b = auction->b * n + n - i - 1; - } - - 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 */ - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, - "libbrandt", - "wow fail out\n"); - return; - } - - auction->bcast (auction->closure, buf, buflen); - gcry_mpi_set_bit (auction->round_progress, auction->i); - free (buf); + enum auction_type atype; + enum outcome_type outcome; + unsigned char *buf; + size_t buflen; + + GNUNET_assert (auction && n > 0 && i < n); + auction->n = n; + auction->i = i; + + atype = auction->m > 0 ? auction_mPlusFirstPrice : auction_firstPrice; + outcome = auction->outcome_public ? outcome_public : outcome_private; + + if (auction_mPlusFirstPrice == atype && n <= auction->m) + { /* fewer bidders than items to sell. every bidder won with lowest price */ + struct BRANDT_Result *res; + if (auction->outcome_public) + { + res = GNUNET_new_array (n, struct BRANDT_Result); + for (uint16_t h = 0; h < n; h++) + { + res[h].bidder = h; + res[h].price = 0; + res[h].status = BRANDT_bidder_won; + } + auction->result (auction->closure, res, n); + } + else + { + res = GNUNET_new (struct BRANDT_Result); + res->bidder = i; + res->price = 0; + res->status = BRANDT_bidder_won; + auction->result (auction->closure, res, 1); + } + return; + } + + /* On M+1st price auctions we multiply the amount of prizes by the amount of + * bidders and resctrict each bidder to his own distinct subset of the + * prices. This is done for tie breaking. An additional proof is used in the + * encrypt_bid round to show that the bidder has chosen a valid bid and the + * outcome callback will remap the result to the original k price values. */ + if (auction_mPlusFirstPrice == atype) + { + auction->k *= n; + auction->b = auction->b * n + n - i - 1; + } + + 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 */ + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, + "libbrandt", + "wow fail out\n"); + return; + } + + auction->bcast (auction->closure, buf, buflen); + gcry_mpi_set_bit (auction->round_progress, auction->i); + free (buf); } static void seller_start (void *arg) { - struct BRANDT_Auction *ad = (struct BRANDT_Auction *)arg; - enum auction_type atype; - enum outcome_type outcome; - - ad->task = NULL; - - ad->n = ad->start (ad->closure); - if (0 == ad->n) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, - "libbrandt", - "no bidders registered for auction\n"); - ad->result (ad->closure, NULL, 0); - return; - } - else if (ad->n <= ad->m) - { - struct BRANDT_Result *res = GNUNET_new_array (ad->n, - struct BRANDT_Result); - - GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, - "libbrandt", - "less bidders than needed, selling for lowest price\n"); - for (uint16_t i = 0; i < ad->n; i++) - { - res[i].bidder = i; - res[i].price = 0; - res[i].status = BRANDT_bidder_won; - } - ad->result (ad->closure, res, ad->n); - } - - atype = ad->m > 0 ? auction_mPlusFirstPrice : auction_firstPrice; - outcome = ad->outcome_public ? outcome_public : outcome_private; - - /* On M+1st price auctions we multiply the amount of prizes by the amount of - * bidders and resctrict each bidder to his own distinct subset of the - * prices. This is done for tie breaking. An additional proof is used in the - * encrypt_bid round to show that the bidder has chosen a valid bid and the - * outcome callback will remap the result to the original k price values. */ - if (auction_mPlusFirstPrice == atype) - ad->k *= ad->n; - - if (handler_prep[atype][outcome][msg_init]) - handler_prep[atype][outcome][msg_init] (ad); + struct BRANDT_Auction *ad = (struct BRANDT_Auction *) arg; + enum auction_type atype; + enum outcome_type outcome; + + ad->task = NULL; + + ad->n = ad->start (ad->closure); + if (0 == ad->n) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, + "libbrandt", + "no bidders registered for auction\n"); + ad->result (ad->closure, NULL, 0); + return; + } + else if (ad->n <= ad->m) + { + struct BRANDT_Result *res = GNUNET_new_array (ad->n, + struct BRANDT_Result); + + GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, + "libbrandt", + "less bidders than needed, selling for lowest price\n"); + for (uint16_t i = 0; i < ad->n; i++) + { + res[i].bidder = i; + res[i].price = 0; + res[i].status = BRANDT_bidder_won; + } + ad->result (ad->closure, res, ad->n); + } + + atype = ad->m > 0 ? auction_mPlusFirstPrice : auction_firstPrice; + outcome = ad->outcome_public ? outcome_public : outcome_private; + + /* On M+1st price auctions we multiply the amount of prizes by the amount of + * bidders and resctrict each bidder to his own distinct subset of the + * prices. This is done for tie breaking. An additional proof is used in the + * encrypt_bid round to show that the bidder has chosen a valid bid and the + * outcome callback will remap the result to the original k price values. */ + if (auction_mPlusFirstPrice == atype) + ad->k *= ad->n; + + if (handler_prep[atype][outcome][msg_init]) + handler_prep[atype][outcome][msg_init] (ad); } struct BRANDT_Auction * -BRANDT_new (BRANDT_CbResult result, - BRANDT_CbDeliver broadcast, - BRANDT_CbStart start, +BRANDT_new (BRANDT_CbResult result, + BRANDT_CbDeliver broadcast, + BRANDT_CbStart start, void *auction_closure, void **auction_desc, size_t *auction_desc_len, - struct GNUNET_TIME_Absolute time_start, - struct GNUNET_TIME_Relative time_round, - uint16_t num_prices, - uint16_t m, - int outcome_public, + struct GNUNET_TIME_Absolute time_start, + struct GNUNET_TIME_Relative time_round, + uint16_t num_prices, + uint16_t m, + int outcome_public, struct GNUNET_CRYPTO_EccDlogContext *dlogctx) { - struct BRANDT_Auction *ret; - struct BRANDT_DescrP *desc; - struct GNUNET_TIME_Relative until_start; - - if (!(0 < num_prices)) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, - "libbrandt", - "num_prices must be > 0\n"); - return NULL; - } - - if (1 == outcome_public && NULL == dlogctx) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, - "libbrandt", - "need dlogctx for public outcome auctions\n"); - return NULL; - } - - desc = GNUNET_new (struct BRANDT_DescrP); - desc->time_start = GNUNET_TIME_absolute_hton (time_start); - desc->time_round = GNUNET_TIME_relative_hton (time_round); - desc->k = htons (num_prices); - desc->m = htons (m); - desc->outcome_public = htons (outcome_public); - - ret = GNUNET_new (struct BRANDT_Auction); - ret->time_start = time_start; - ret->time_round = time_round; - ret->k = num_prices; - ret->m = m; - ret->outcome_public = outcome_public; - ret->cur_round = msg_init; - ret->round_progress = gcry_mpi_new (256); - ret->dlogctx = dlogctx; - - /* we are the seller */ - ret->seller_mode = 1; - - /* callback interface with application */ - ret->closure = auction_closure; - ret->bcast = broadcast; - ret->result = result; - ret->start = start; - - until_start = GNUNET_TIME_absolute_get_remaining (time_start); - ret->task = GNUNET_SCHEDULER_add_delayed (until_start, - &seller_start, - ret); - - *auction_desc_len = sizeof (struct BRANDT_DescrP); - *auction_desc = desc; - return ret; + struct BRANDT_Auction *ret; + struct BRANDT_DescrP *desc; + struct GNUNET_TIME_Relative until_start; + + if (! (0 < num_prices)) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, + "libbrandt", + "num_prices must be > 0\n"); + return NULL; + } + + if (1 == outcome_public && NULL == dlogctx) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, + "libbrandt", + "need dlogctx for public outcome auctions\n"); + return NULL; + } + + desc = GNUNET_new (struct BRANDT_DescrP); + desc->time_start = GNUNET_TIME_absolute_hton (time_start); + desc->time_round = GNUNET_TIME_relative_hton (time_round); + desc->k = htons (num_prices); + desc->m = htons (m); + desc->outcome_public = htons (outcome_public); + + ret = GNUNET_new (struct BRANDT_Auction); + ret->time_start = time_start; + ret->time_round = time_round; + ret->k = num_prices; + ret->m = m; + ret->outcome_public = outcome_public; + ret->cur_round = msg_init; + ret->round_progress = gcry_mpi_new (256); + ret->dlogctx = dlogctx; + + /* we are the seller */ + ret->seller_mode = 1; + + /* callback interface with application */ + ret->closure = auction_closure; + ret->bcast = broadcast; + ret->result = result; + ret->start = start; + + until_start = GNUNET_TIME_absolute_get_remaining (time_start); + ret->task = GNUNET_SCHEDULER_add_delayed (until_start, + &seller_start, + ret); + + *auction_desc_len = sizeof (struct BRANDT_DescrP); + *auction_desc = desc; + return ret; } int BRANDT_parse_desc (const void *auction_desc, - size_t auction_desc_len, + size_t auction_desc_len, struct GNUNET_TIME_Absolute *time_start, struct GNUNET_TIME_Relative *time_round, uint16_t *num_prices, uint16_t *m, uint16_t *outcome_public) { - const struct BRANDT_DescrP *desc = auction_desc; - const uint32_t zero = 0; - - if (sizeof (struct BRANDT_DescrP) != auction_desc_len) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, - "libbrandt", - "auction desc struct size mismatch\n"); - return -1; - } - - if (0 != memcmp (&desc->reserved, &zero, sizeof (desc->reserved))) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, - "libbrandt", - "reserved field in auction description must be zero\n"); - return -1; - } - - if (time_start) - *time_start = GNUNET_TIME_absolute_ntoh (desc->time_start); - if (time_round) - *time_round = GNUNET_TIME_relative_ntoh (desc->time_round); - if (num_prices) - *num_prices = ntohs (desc->k); - if (m) - *m = ntohs (desc->m); - if (outcome_public) - *outcome_public = ntohs (desc->outcome_public); - - return 0; + const struct BRANDT_DescrP *desc = auction_desc; + const uint32_t zero = 0; + + if (sizeof (struct BRANDT_DescrP) != auction_desc_len) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, + "libbrandt", + "auction desc struct size mismatch\n"); + return -1; + } + + if (0 != memcmp (&desc->reserved, &zero, sizeof (desc->reserved))) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, + "libbrandt", + "reserved field in auction description must be zero\n"); + return -1; + } + + if (time_start) + *time_start = GNUNET_TIME_absolute_ntoh (desc->time_start); + if (time_round) + *time_round = GNUNET_TIME_relative_ntoh (desc->time_round); + if (num_prices) + *num_prices = ntohs (desc->k); + if (m) + *m = ntohs (desc->m); + if (outcome_public) + *outcome_public = ntohs (desc->outcome_public); + + return 0; } struct BRANDT_Auction * -BRANDT_join (BRANDT_CbResult result, - BRANDT_CbDeliver broadcast, - BRANDT_CbDeliver unicast, +BRANDT_join (BRANDT_CbResult result, + BRANDT_CbDeliver broadcast, + BRANDT_CbDeliver unicast, void *auction_closure, const void *auction_desc, - size_t auction_desc_len, - uint16_t bid, + size_t auction_desc_len, + uint16_t bid, struct GNUNET_CRYPTO_EccDlogContext *dlogctx) { - struct BRANDT_Auction *ret = GNUNET_new (struct BRANDT_Auction); - - if (0 != BRANDT_parse_desc (auction_desc, - auction_desc_len, - &ret->time_start, - &ret->time_round, - &ret->k, - &ret->m, - &ret->outcome_public)) - { - GNUNET_free (ret); - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, - "libbrandt", - "failed to parse auction description blob\n"); - return NULL; - } - - if (1 == ret->outcome_public && NULL == dlogctx) - { - GNUNET_free (ret); - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, - "libbrandt", - "need dlogctx for public outcome auctions\n"); - return NULL; - } - - ret->cur_round = msg_init; - ret->round_progress = gcry_mpi_new (256); - ret->b = bid; - ret->dlogctx = dlogctx; - - /* we are the seller */ - ret->seller_mode = 0; - - /* callback interface with application */ - ret->closure = auction_closure; - ret->bcast = broadcast; - ret->ucast = unicast; - ret->result = result; - - return ret; + struct BRANDT_Auction *ret = GNUNET_new (struct BRANDT_Auction); + + if (0 != BRANDT_parse_desc (auction_desc, + auction_desc_len, + &ret->time_start, + &ret->time_round, + &ret->k, + &ret->m, + &ret->outcome_public)) + { + GNUNET_free (ret); + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, + "libbrandt", + "failed to parse auction description blob\n"); + return NULL; + } + + if (1 == ret->outcome_public && NULL == dlogctx) + { + GNUNET_free (ret); + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, + "libbrandt", + "need dlogctx for public outcome auctions\n"); + return NULL; + } + + ret->cur_round = msg_init; + ret->round_progress = gcry_mpi_new (256); + ret->b = bid; + ret->dlogctx = dlogctx; + + /* we are the seller */ + ret->seller_mode = 0; + + /* callback interface with application */ + ret->closure = auction_closure; + ret->bcast = broadcast; + ret->ucast = unicast; + ret->result = result; + + return ret; } void BRANDT_destroy (struct BRANDT_Auction *auction) { - if (auction->task) - GNUNET_SCHEDULER_cancel (auction->task); - gcry_mpi_release (auction->round_progress); - gcry_mpi_release (auction->x); - smc_free1 (auction->y, auction->n); - gcry_mpi_point_release (auction->Y); - smc_free2 (auction->alpha, auction->n, auction->k); - smc_free2 (auction->beta, auction->n, auction->k); - smc_free2 (auction->gamma2, auction->n, auction->k); - smc_free2 (auction->delta2, auction->n, auction->k); - smc_free2 (auction->phi2, auction->n, auction->k); - free (auction->phiproofs3); - smc_free1 (auction->tmpa1, auction->k); - smc_free1 (auction->tmpb1, auction->k); - if (auction->m > 0 && auction->outcome_public) - { - smc_free3 (auction->gamma3, auction->n, 2, auction->k); - smc_free3 (auction->delta3, auction->n, 2, auction->k); - smc_free3 (auction->phi3, auction->n, 2, auction->k); - } - else - { - smc_free3 (auction->gamma3, auction->n, auction->n, auction->k); - smc_free3 (auction->delta3, auction->n, auction->n, auction->k); - smc_free3 (auction->phi3, auction->n, auction->n, auction->k); - } + if (auction->task) + GNUNET_SCHEDULER_cancel (auction->task); + gcry_mpi_release (auction->round_progress); + gcry_mpi_release (auction->x); + smc_free1 (auction->y, auction->n); + gcry_mpi_point_release (auction->Y); + smc_free2 (auction->alpha, auction->n, auction->k); + smc_free2 (auction->beta, auction->n, auction->k); + smc_free2 (auction->gamma2, auction->n, auction->k); + smc_free2 (auction->delta2, auction->n, auction->k); + smc_free2 (auction->phi2, auction->n, auction->k); + free (auction->phiproofs3); + smc_free1 (auction->tmpa1, auction->k); + smc_free1 (auction->tmpb1, auction->k); + if (auction->m > 0 && auction->outcome_public) + { + smc_free3 (auction->gamma3, auction->n, 2, auction->k); + smc_free3 (auction->delta3, auction->n, 2, auction->k); + smc_free3 (auction->phi3, auction->n, 2, auction->k); + } + else + { + smc_free3 (auction->gamma3, auction->n, auction->n, auction->k); + smc_free3 (auction->delta3, auction->n, auction->n, auction->k); + smc_free3 (auction->phi3, auction->n, auction->n, auction->k); + } } static void report_outcome (struct BRANDT_Auction *ad, - enum auction_type atype, - enum outcome_type outcome) + enum auction_type atype, + enum outcome_type outcome) { - struct BRANDT_Result *res; - uint16_t reslen = 0; - - if (!handler_res[atype][outcome] || - !(res = handler_res[atype][outcome] (ad, &reslen))) - ad->result (ad->closure, NULL, 0); - else - ad->result (ad->closure, res, reslen); + struct BRANDT_Result *res; + uint16_t reslen = 0; + + if (! handler_res[atype][outcome] || + ! (res = handler_res[atype][outcome] (ad, &reslen))) + ad->result (ad->closure, NULL, 0); + else + ad->result (ad->closure, res, reslen); } static void advance_round (struct BRANDT_Auction *ad, - enum auction_type atype, - enum outcome_type outcome) + enum auction_type atype, + enum outcome_type outcome) { - unsigned char *buf; - size_t buflen; - - if (!ad->seller_mode && msg_decrypt == ad->cur_round && !outcome) - { - /* we are a bidder on a private outcome auction and - * successfully parsed the msg_decrypt from the seller - * => we can determine the auction result */ - report_outcome (ad, atype, outcome); - return; - } - - /* only continue if the round is complete */ - for (uint16_t i = 0; i < ad->n; i++) - if (!gcry_mpi_test_bit (ad->round_progress, i)) - return; - - if (ad->seller_mode && msg_decrypt == ad->cur_round && !ad->outcome_public) - { - /* all bidders msg_decrypt received, broadcast combined msg_decrypt */ - if (!handler_out[atype][outcome][ad->cur_round] || - !(buf = handler_out[atype][outcome][ad->cur_round](ad, &buflen))) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, - "libbrandt", - "failed to create msg %d buffer as seller\n", - ad->cur_round); - return; - } - ad->bcast (ad->closure, buf, buflen); - } - - if (msg_decrypt == ad->cur_round) - { - report_outcome (ad, atype, outcome); - return; - } - - /* round complete, advance to next one */ - gcry_mpi_clear_highbit (ad->round_progress, 0); - ad->cur_round++; - - /* prepare next round. */ - 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 */ - /* seller does not send regular messages */ - return; - } - - /* create next message buffer */ - if (!handler_out[atype][outcome][ad->cur_round] || - !(buf = handler_out[atype][outcome][ad->cur_round](ad, &buflen))) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, - "libbrandt", - "failed to create msg %d buffer as bidder\n", - ad->cur_round); - return; - } - - /* msg_decrypt unicast to seller if private outcome mode. - * All other messages are broadcasted */ - if (msg_decrypt == ad->cur_round && !outcome) - ad->ucast (ad->closure, buf, buflen); - else - ad->bcast (ad->closure, buf, buflen); - gcry_mpi_set_bit (ad->round_progress, ad->i); + unsigned char *buf; + size_t buflen; + + if (! ad->seller_mode && msg_decrypt == ad->cur_round && ! outcome) + { + /* we are a bidder on a private outcome auction and + * successfully parsed the msg_decrypt from the seller + * => we can determine the auction result */ + report_outcome (ad, atype, outcome); + return; + } + + /* only continue if the round is complete */ + for (uint16_t i = 0; i < ad->n; i++) + if (! gcry_mpi_test_bit (ad->round_progress, i)) + return; + + if (ad->seller_mode && msg_decrypt == ad->cur_round && ! ad->outcome_public) + { + /* all bidders msg_decrypt received, broadcast combined msg_decrypt */ + if (! handler_out[atype][outcome][ad->cur_round] || + ! (buf = handler_out[atype][outcome][ad->cur_round](ad, &buflen))) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, + "libbrandt", + "failed to create msg %d buffer as seller\n", + ad->cur_round); + return; + } + ad->bcast (ad->closure, buf, buflen); + } + + if (msg_decrypt == ad->cur_round) + { + report_outcome (ad, atype, outcome); + return; + } + + /* round complete, advance to next one */ + gcry_mpi_clear_highbit (ad->round_progress, 0); + ad->cur_round++; + + /* prepare next round. */ + 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 */ + /* seller does not send regular messages */ + return; + } + + /* create next message buffer */ + if (! handler_out[atype][outcome][ad->cur_round] || + ! (buf = handler_out[atype][outcome][ad->cur_round](ad, &buflen))) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, + "libbrandt", + "failed to create msg %d buffer as bidder\n", + ad->cur_round); + return; + } + + /* msg_decrypt unicast to seller if private outcome mode. + * All other messages are broadcasted */ + if (msg_decrypt == ad->cur_round && ! outcome) + ad->ucast (ad->closure, buf, buflen); + else + ad->bcast (ad->closure, buf, buflen); + gcry_mpi_set_bit (ad->round_progress, ad->i); } void BRANDT_got_message (struct BRANDT_Auction *auction, - uint16_t sender, + uint16_t sender, const unsigned char *msg, - size_t msg_len) + size_t msg_len) { - struct msg_head *head = (struct msg_head *)msg; - enum auction_type atype; - enum outcome_type outcome; - enum rounds round = auction->cur_round; - - atype = auction->m > 0 ? auction_mPlusFirstPrice : auction_firstPrice; - outcome = auction->outcome_public ? outcome_public : outcome_private; - - /** \todo: cache out of order messages instead of discarding */ - if (ntohl (head->msg_type) != round || ntohl (head->prot_version) != 0) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, - "libbrandt", - "got unexpected message, ignoring...\n"); - return; - } - - /* check if we already got that round message from the same user */ - if (gcry_mpi_test_bit (auction->round_progress, sender)) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, - "libbrandt", - "got a duplicate message from user %d\n", sender); - return; - } - - if (!handler_in[atype][outcome][round] || - !handler_in[atype][outcome][round](auction, - msg + sizeof (*head), - msg_len - sizeof (*head), - sender)) - { - /** \todo */ - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, - "libbrandt", - "wow fail in\n"); - return; - } - gcry_mpi_set_bit (auction->round_progress, sender); - - advance_round (auction, atype, outcome); + struct msg_head *head = (struct msg_head *) msg; + enum auction_type atype; + enum outcome_type outcome; + enum rounds round = auction->cur_round; + + atype = auction->m > 0 ? auction_mPlusFirstPrice : auction_firstPrice; + outcome = auction->outcome_public ? outcome_public : outcome_private; + + /** \todo: cache out of order messages instead of discarding */ + if (ntohl (head->msg_type) != round || ntohl (head->prot_version) != 0) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, + "libbrandt", + "got unexpected message, ignoring...\n"); + return; + } + + /* check if we already got that round message from the same user */ + if (gcry_mpi_test_bit (auction->round_progress, sender)) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, + "libbrandt", + "got a duplicate message from user %d\n", sender); + return; + } + + if (! handler_in[atype][outcome][round] || + ! handler_in[atype][outcome][round](auction, + msg + sizeof (*head), + msg_len - sizeof (*head), + sender)) + { + /** \todo */ + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, + "libbrandt", + "wow fail in\n"); + return; + } + gcry_mpi_set_bit (auction->round_progress, sender); + + advance_round (auction, atype, outcome); } |