diff options
-rw-r--r-- | brandt.c | 82 | ||||
-rw-r--r-- | brandt.h | 50 | ||||
-rw-r--r-- | crypto.c | 280 | ||||
-rw-r--r-- | crypto.h | 87 | ||||
-rw-r--r-- | internals.h | 7 | ||||
-rw-r--r-- | test_brandt.c | 182 | ||||
-rw-r--r-- | test_crypto.c | 101 |
7 files changed, 550 insertions, 239 deletions
@@ -52,11 +52,35 @@ BRANDT_init (struct GNUNET_CRYPTO_EccDlogContext *dlogctx) | |||
52 | 52 | ||
53 | void | 53 | void |
54 | BRANDT_bidder_start (struct BRANDT_Auction *auction, | 54 | BRANDT_bidder_start (struct BRANDT_Auction *auction, |
55 | uint16_t i, | ||
55 | uint16_t n) | 56 | uint16_t n) |
56 | { | 57 | { |
57 | GNUNET_assert (n > 0); | 58 | GNUNET_assert (auction && n > 0 && i < n); |
58 | auction->n = n; | 59 | auction->n = n; |
59 | /** \todo: send first message */ | 60 | auction->i = i; |
61 | enum auction_type atype; | ||
62 | enum outcome_type outcome; | ||
63 | unsigned char *buf; | ||
64 | size_t buflen; | ||
65 | |||
66 | atype = auction->m > 0 ? auction_mPlusFirstPrice : auction_firstPrice; | ||
67 | outcome = auction->outcome_public ? outcome_public : outcome_private; | ||
68 | |||
69 | if (handler_prep[atype][outcome][msg_init]) | ||
70 | handler_prep[atype][outcome][msg_init] (auction); | ||
71 | |||
72 | if (!handler_out[atype][outcome][msg_init] || | ||
73 | !(buf = handler_out[atype][outcome][msg_init](auction, &buflen))) | ||
74 | { | ||
75 | /** \todo */ | ||
76 | weprintf ("wow fail out"); | ||
77 | return; | ||
78 | } | ||
79 | |||
80 | weprintf("broadcasting msg_init %p from bidder %d", buf, i); | ||
81 | if (0 == auction->bcast (auction->closure, buf, buflen)) | ||
82 | gcry_mpi_set_bit (auction->round_progress, auction->i); | ||
83 | free (buf); | ||
60 | } | 84 | } |
61 | 85 | ||
62 | 86 | ||
@@ -65,10 +89,12 @@ seller_start (void *arg) | |||
65 | { | 89 | { |
66 | struct BRANDT_Auction *ad = (struct BRANDT_Auction *)arg; | 90 | struct BRANDT_Auction *ad = (struct BRANDT_Auction *)arg; |
67 | 91 | ||
92 | ad->task = NULL; | ||
93 | |||
68 | if (0 == (ad->n = ad->start (ad->closure))) | 94 | if (0 == (ad->n = ad->start (ad->closure))) |
69 | { | 95 | { |
70 | weprintf ("no bidders registered for auction"); | 96 | weprintf ("no bidders registered for auction"); |
71 | ad->result (ad->closure, -1, result_no_bidders, 0); | 97 | /** todo: somehow mark auction as done / ready for cleanup */ |
72 | return; | 98 | return; |
73 | } | 99 | } |
74 | } | 100 | } |
@@ -201,7 +227,8 @@ BRANDT_join (BRANDT_CbResult result, | |||
201 | const void *auction_desc, | 227 | const void *auction_desc, |
202 | size_t auction_desc_len, | 228 | size_t auction_desc_len, |
203 | const void *description, | 229 | const void *description, |
204 | uint32_t description_len) | 230 | uint32_t description_len, |
231 | uint16_t bid) | ||
205 | { | 232 | { |
206 | struct BRANDT_Auction *ret = GNUNET_new (struct BRANDT_Auction); | 233 | struct BRANDT_Auction *ret = GNUNET_new (struct BRANDT_Auction); |
207 | 234 | ||
@@ -220,6 +247,7 @@ BRANDT_join (BRANDT_CbResult result, | |||
220 | } | 247 | } |
221 | ret->cur_round = msg_init; | 248 | ret->cur_round = msg_init; |
222 | ret->round_progress = gcry_mpi_new (256); | 249 | ret->round_progress = gcry_mpi_new (256); |
250 | ret->b = bid; | ||
223 | 251 | ||
224 | /* we are the seller */ | 252 | /* we are the seller */ |
225 | ret->seller_mode = 0; | 253 | ret->seller_mode = 0; |
@@ -261,8 +289,8 @@ advance_round (struct BRANDT_Auction *ad, | |||
261 | enum auction_type atype, | 289 | enum auction_type atype, |
262 | enum outcome_type outcome) | 290 | enum outcome_type outcome) |
263 | { | 291 | { |
264 | uint32_t price; | 292 | struct BRANDT_Result *res; |
265 | uint16_t winner = -1; | 293 | uint16_t reslen = 0; |
266 | unsigned char *buf; | 294 | unsigned char *buf; |
267 | size_t buflen; | 295 | size_t buflen; |
268 | 296 | ||
@@ -278,21 +306,25 @@ advance_round (struct BRANDT_Auction *ad, | |||
278 | if (msg_last == ++(ad->cur_round)) | 306 | if (msg_last == ++(ad->cur_round)) |
279 | { | 307 | { |
280 | /* done with all rounds, determine outcome here */ | 308 | /* done with all rounds, determine outcome here */ |
281 | /** \todo: unify …_determine_outcome function signature? */ | 309 | if (!handler_res[atype][outcome] || |
282 | if (auction_firstPrice == atype && outcome_private == outcome) | 310 | !(res = handler_res[atype][outcome] (ad, &reslen))) |
283 | { | 311 | { |
284 | if (-1 == (price = fp_priv_determine_outcome (ad))) | 312 | /** \todo */ |
285 | ad->result (ad->closure, ad->i, 0, 0); | 313 | weprintf ("wow fail result"); |
286 | else | 314 | /** \todo: call result with null pointer here? */ |
287 | ad->result (ad->closure, ad->i, 1, price); | 315 | return; |
288 | } | ||
289 | else if (auction_firstPrice == atype && outcome_public == outcome) | ||
290 | { | ||
291 | if (-1 == (price = fp_pub_determine_outcome (ad, &winner))) | ||
292 | ad->result (ad->closure, ad->i, 0, 0); | ||
293 | else | ||
294 | ad->result (ad->closure, winner, 1, price); | ||
295 | } | 316 | } |
317 | |||
318 | ad->result (ad->closure, res, reslen); | ||
319 | return; | ||
320 | } | ||
321 | |||
322 | if (handler_prep[atype][outcome][ad->cur_round]) | ||
323 | handler_prep[atype][outcome][ad->cur_round] (ad); | ||
324 | |||
325 | if (ad->seller_mode) | ||
326 | { | ||
327 | /** \todo: setup round timeout trigger */ | ||
296 | return; | 328 | return; |
297 | } | 329 | } |
298 | 330 | ||
@@ -306,9 +338,15 @@ advance_round (struct BRANDT_Auction *ad, | |||
306 | 338 | ||
307 | /* last message only sent to seller, others are broadcasted */ | 339 | /* last message only sent to seller, others are broadcasted */ |
308 | if (msg_decrypt == ad->cur_round) | 340 | if (msg_decrypt == ad->cur_round) |
309 | ad->ucast (ad->closure, buf, buflen); | 341 | { |
342 | if (0 == ad->ucast (ad->closure, buf, buflen)) | ||
343 | gcry_mpi_set_bit (ad->round_progress, ad->i); | ||
344 | } | ||
310 | else | 345 | else |
311 | ad->bcast (ad->closure, buf, buflen); | 346 | { |
347 | if (0 == ad->bcast (ad->closure, buf, buflen)) | ||
348 | gcry_mpi_set_bit (ad->round_progress, ad->i); | ||
349 | } | ||
312 | } | 350 | } |
313 | 351 | ||
314 | 352 | ||
@@ -329,6 +367,7 @@ BRANDT_got_message (struct BRANDT_Auction *auction, | |||
329 | /** \todo: cache out of order messages instead of discarding */ | 367 | /** \todo: cache out of order messages instead of discarding */ |
330 | if (ntohl (head->msg_type) != round || ntohl (head->prot_version) != 0) | 368 | if (ntohl (head->msg_type) != round || ntohl (head->prot_version) != 0) |
331 | { | 369 | { |
370 | weprintf ("%d", auction->i); | ||
332 | weprintf ("got unexpected message, ignoring..."); | 371 | weprintf ("got unexpected message, ignoring..."); |
333 | return; | 372 | return; |
334 | } | 373 | } |
@@ -351,6 +390,7 @@ BRANDT_got_message (struct BRANDT_Auction *auction, | |||
351 | return; | 390 | return; |
352 | } | 391 | } |
353 | gcry_mpi_set_bit (auction->round_progress, sender); | 392 | gcry_mpi_set_bit (auction->round_progress, sender); |
393 | DM(auction->round_progress); | ||
354 | 394 | ||
355 | /** \todo: seller_mode and new task for round timing */ | 395 | /** \todo: seller_mode and new task for round timing */ |
356 | advance_round (auction, atype, outcome); | 396 | advance_round (auction, atype, outcome); |
@@ -28,9 +28,31 @@ | |||
28 | 28 | ||
29 | #include <gnunet/gnunet_util_lib.h> | 29 | #include <gnunet/gnunet_util_lib.h> |
30 | 30 | ||
31 | /** defined in internals.h */ | 31 | /** Enumeration of all possible status reports for a single bidder */ |
32 | enum BRANDT_BidderStatus | ||
33 | { | ||
34 | BRANDT_bidder_won, | ||
35 | }; | ||
36 | |||
37 | /** opaque, defined in internals.h */ | ||
32 | struct BRANDT_Auction; | 38 | struct BRANDT_Auction; |
33 | 39 | ||
40 | /** | ||
41 | * An array of this struct is given to the application by the BRANDT_CbResult() | ||
42 | * callback. One instance represents the status of a single bidder. | ||
43 | */ | ||
44 | struct BRANDT_Result | ||
45 | { | ||
46 | /** Id of the bidder this instance refers to */ | ||
47 | uint16_t bidder; | ||
48 | |||
49 | /** The price the bidder has to pay. This value is only set if the #status | ||
50 | * indicates the bidder has won. */ | ||
51 | uint16_t price; | ||
52 | |||
53 | /** Status of the bidder */ | ||
54 | enum BRANDT_BidderStatus status; | ||
55 | }; | ||
34 | 56 | ||
35 | /** | 57 | /** |
36 | * Functions of this type are called by libbrandt when the auction should be | 58 | * Functions of this type are called by libbrandt when the auction should be |
@@ -86,22 +108,19 @@ typedef int | |||
86 | * Functions of this type are called by libbrandt to report the auction outcome | 108 | * Functions of this type are called by libbrandt to report the auction outcome |
87 | * or malicious/erroneous participants. | 109 | * or malicious/erroneous participants. |
88 | * | 110 | * |
89 | * \todo: export proof of erroneous behaviour / outcome. | 111 | * \todo: export *proof* of erroneous behaviour / outcome. |
90 | * | 112 | * |
91 | * @param[in] auction_closure Closure pointer representing the respective | 113 | * @param[in] auction_closure Closure pointer representing the respective |
92 | * auction. This is the Pointer given to BRANDT_join() / BRANDT_new(). | 114 | * auction. This is the Pointer given to BRANDT_join() / BRANDT_new(). |
93 | * @param[in] bidder_id The numeric Id of the bidder this report refers to. | 115 | * @param[in] results An array of results for one or more bidders. Each bidder |
94 | * @param[in] status 1 if the user @a bidder_id has won the auction, 0 if he has | 116 | * will only be listed once. Misbehaving bidder results and auction completion |
95 | * lost, negative if erroneous behaviour was detected. Check the result_code | 117 | * results are not mixed. |
96 | * enum for more information. | 118 | * @param[in] results_len Amount of items in @a results. |
97 | * @param[in] price The price, the winner has to pay or 0 if the auction result | ||
98 | * is private and the user did not win. | ||
99 | */ | 119 | */ |
100 | typedef void | 120 | typedef void |
101 | (*BRANDT_CbResult)(void *auction_closure, | 121 | (*BRANDT_CbResult)(void *auction_closure, |
102 | int32_t bidder_id, | 122 | struct BRANDT_Result results[], |
103 | int status, | 123 | uint16_t results_len); |
104 | uint16_t price); | ||
105 | 124 | ||
106 | 125 | ||
107 | void | 126 | void |
@@ -159,8 +178,8 @@ BRANDT_join (BRANDT_CbResult result, | |||
159 | const void *auction_desc, | 178 | const void *auction_desc, |
160 | size_t auction_desc_len, | 179 | size_t auction_desc_len, |
161 | const void *description, | 180 | const void *description, |
162 | uint32_t description_len); | 181 | uint32_t description_len, |
163 | /* \todo: where do I specify my bid? */ | 182 | uint16_t bid); |
164 | 183 | ||
165 | 184 | ||
166 | /* \todo: Distinguish handles for seller/buyers */ | 185 | /* \todo: Distinguish handles for seller/buyers */ |
@@ -219,10 +238,13 @@ BRANDT_new (BRANDT_CbResult result, | |||
219 | * notification from the seller. | 238 | * notification from the seller. |
220 | * | 239 | * |
221 | * @param[in] auction The pointer returned by BRANDT_join(). | 240 | * @param[in] auction The pointer returned by BRANDT_join(). |
241 | * @param[in] i The index of this bidder assigned by the seller (from the start | ||
242 | * announcement message). | ||
222 | * @param[in] n The amount of bidders (from the start announcement message). | 243 | * @param[in] n The amount of bidders (from the start announcement message). |
223 | */ | 244 | */ |
224 | void | 245 | void |
225 | BRANDT_bidder_start (struct BRANDT_Auction *auction, | 246 | BRANDT_bidder_start (struct BRANDT_Auction *auction, |
247 | uint16_t i, | ||
226 | uint16_t n); | 248 | uint16_t n); |
227 | 249 | ||
228 | 250 | ||
@@ -609,6 +609,14 @@ smc_sum (gcry_mpi_point_t out, | |||
609 | } | 609 | } |
610 | 610 | ||
611 | 611 | ||
612 | void | ||
613 | smc_prep_keyshare (struct BRANDT_Auction *ad) | ||
614 | { | ||
615 | ad->y = smc_init1 (ad->n); | ||
616 | brandt_assert (ad->y); | ||
617 | } | ||
618 | |||
619 | |||
612 | /** | 620 | /** |
613 | * smc_gen_keyshare creates the private keyshare and computes the | 621 | * smc_gen_keyshare creates the private keyshare and computes the |
614 | * public key share | 622 | * public key share |
@@ -622,20 +630,15 @@ unsigned char * | |||
622 | smc_gen_keyshare (struct BRANDT_Auction *ad, size_t *buflen) | 630 | smc_gen_keyshare (struct BRANDT_Auction *ad, size_t *buflen) |
623 | { | 631 | { |
624 | unsigned char *ret; | 632 | unsigned char *ret; |
625 | struct proof_dl *proof1; | ||
626 | struct msg_head *head; | 633 | struct msg_head *head; |
627 | struct ec_mpi *pubkey_share; | 634 | struct ec_mpi *pubkey_share; |
635 | struct proof_dl *proof1; | ||
628 | 636 | ||
629 | brandt_assert (ad && buflen); | 637 | brandt_assert (ad && buflen); |
630 | *buflen = (sizeof (*head) + | 638 | *buflen = (sizeof (*head) + |
631 | sizeof (*pubkey_share) + | 639 | sizeof (*pubkey_share) + |
632 | sizeof (*proof1)); | 640 | sizeof (*proof1)); |
633 | ret = GNUNET_new_array (*buflen, unsigned char); | 641 | ret = GNUNET_new_array (*buflen, unsigned char); |
634 | if (NULL == (ad->y = smc_init1 (ad->n))) | ||
635 | { | ||
636 | weprintf ("unable to alloc memory for key shares"); | ||
637 | return NULL; | ||
638 | } | ||
639 | 642 | ||
640 | head = (struct msg_head *)ret; | 643 | head = (struct msg_head *)ret; |
641 | head->prot_version = htonl (0); | 644 | head->prot_version = htonl (0); |
@@ -688,6 +691,22 @@ quit: | |||
688 | } | 691 | } |
689 | 692 | ||
690 | 693 | ||
694 | void | ||
695 | smc_prep_bid (struct BRANDT_Auction *ad) | ||
696 | { | ||
697 | ad->alpha = smc_init2 (ad->n, ad->k); | ||
698 | brandt_assert (ad->alpha); | ||
699 | |||
700 | ad->beta = smc_init2 (ad->n, ad->k); | ||
701 | brandt_assert (ad->beta); | ||
702 | |||
703 | ad->Y = gcry_mpi_point_new (0); | ||
704 | brandt_assert (ad->Y); | ||
705 | smc_sum (ad->Y, ad->y, ad->n, 1); | ||
706 | brandt_assert (ad->Y); | ||
707 | } | ||
708 | |||
709 | |||
691 | /** | 710 | /** |
692 | * smc_encrypt_bid encrypts the own bid with the shared public key and packs it | 711 | * smc_encrypt_bid encrypts the own bid with the shared public key and packs it |
693 | * into a message together with proofs of correctnes. | 712 | * into a message together with proofs of correctnes. |
@@ -702,33 +721,24 @@ smc_encrypt_bid (struct BRANDT_Auction *ad, size_t *buflen) | |||
702 | { | 721 | { |
703 | unsigned char *ret; | 722 | unsigned char *ret; |
704 | unsigned char *cur; | 723 | unsigned char *cur; |
705 | struct proof_0og *proof3; | ||
706 | struct msg_head *head; | 724 | struct msg_head *head; |
725 | struct proof_0og *proof3; | ||
707 | gcry_mpi_t r_sum; | 726 | gcry_mpi_t r_sum; |
708 | gcry_mpi_t r_part; | 727 | gcry_mpi_t r_part; |
709 | 728 | ||
710 | brandt_assert (ad && buflen); | 729 | brandt_assert (ad && buflen); |
711 | *buflen = (sizeof (*head) + /* msg header */ | 730 | *buflen = (sizeof (*head) + /* msg header */ |
712 | ad->k * /* k * (alpha, beta, proof3) */ | 731 | ad->k * /* k * (alpha, beta, proof3) */ |
713 | (sizeof (struct ec_mpi) * 2 + /* alpha, beta */ | 732 | (sizeof (struct ec_mpi) * 2 + |
714 | sizeof (*proof3)) + | 733 | sizeof (*proof3)) + |
715 | sizeof (struct proof_2dle)); | 734 | sizeof (struct proof_2dle)); /* proof2 */ |
716 | ret = GNUNET_new_array (*buflen, unsigned char); | 735 | ret = GNUNET_new_array (*buflen, unsigned char); |
717 | if (NULL == (ad->alpha = smc_init2 (ad->n, ad->k)) || | ||
718 | NULL == (ad->beta = smc_init2 (ad->n, ad->k))) | ||
719 | { | ||
720 | weprintf ("unable to alloc memory for encrypted bids"); | ||
721 | return NULL; | ||
722 | } | ||
723 | 736 | ||
724 | head = (struct msg_head *)ret; | 737 | head = (struct msg_head *)ret; |
725 | head->prot_version = htonl (0); | 738 | head->prot_version = htonl (0); |
726 | head->msg_type = htonl (msg_bid); | 739 | head->msg_type = htonl (msg_bid); |
727 | cur = ret + sizeof (*head); | 740 | cur = ret + sizeof (*head); |
728 | 741 | ||
729 | ad->Y = gcry_mpi_point_new (0); | ||
730 | smc_sum (ad->Y, ad->y, ad->n, 1); | ||
731 | |||
732 | r_sum = gcry_mpi_new (256); | 742 | r_sum = gcry_mpi_new (256); |
733 | r_part = gcry_mpi_new (256); | 743 | r_part = gcry_mpi_new (256); |
734 | 744 | ||
@@ -822,52 +832,27 @@ quit: | |||
822 | } | 832 | } |
823 | 833 | ||
824 | 834 | ||
825 | /** | 835 | void |
826 | * fp_pub_compute_outcome computes the outcome for first price auctions with a | 836 | fp_pub_prep_outcome (struct BRANDT_Auction *ad) |
827 | * public outcome and packs it into a message buffer together with proofs of | ||
828 | * correctnes. | ||
829 | * | ||
830 | * @param[in] ad Pointer to the BRANDT_Auction struct to operate on | ||
831 | * @param[out] buflen Size of the returned message buffer in bytes | ||
832 | * @return A buffer containing the encrypted outcome vectors | ||
833 | * which needs to be broadcast | ||
834 | */ | ||
835 | unsigned char * | ||
836 | fp_pub_compute_outcome (struct BRANDT_Auction *ad, size_t *buflen) | ||
837 | { | 837 | { |
838 | unsigned char *ret; | ||
839 | unsigned char *cur; | ||
840 | struct msg_head *head; | ||
841 | gcry_mpi_t coeff = gcry_mpi_copy (GCRYMPI_CONST_ONE); | 838 | gcry_mpi_t coeff = gcry_mpi_copy (GCRYMPI_CONST_ONE); |
842 | gcry_mpi_point_t tmp = gcry_mpi_point_new (0); | 839 | gcry_mpi_point_t tmp = gcry_mpi_point_new (0); |
843 | gcry_mpi_point_t *tlta1; | 840 | gcry_mpi_point_t *tlta1; |
844 | gcry_mpi_point_t *tltb1; | 841 | gcry_mpi_point_t *tltb1; |
845 | gcry_mpi_point_t **tlta2; | 842 | gcry_mpi_point_t **tlta2; |
846 | gcry_mpi_point_t **tltb2; | 843 | gcry_mpi_point_t **tltb2; |
847 | struct ec_mpi *gamma; | ||
848 | struct ec_mpi *delta; | ||
849 | struct proof_2dle *proof2; | ||
850 | 844 | ||
851 | brandt_assert (ad && buflen); | 845 | ad->gamma2 = smc_init2 (ad->n, ad->k); |
846 | brandt_assert (ad->gamma2); | ||
852 | 847 | ||
853 | *buflen = (sizeof (*head) + | 848 | ad->delta2 = smc_init2 (ad->n, ad->k); |
854 | ad->k * (sizeof (*gamma) + | 849 | brandt_assert (ad->delta2); |
855 | sizeof (*delta) + | ||
856 | sizeof (*proof2))); | ||
857 | ret = GNUNET_new_array (*buflen, unsigned char); | ||
858 | if (NULL == (ad->gamma2 = smc_init2 (ad->n, ad->k)) || | ||
859 | NULL == (ad->delta2 = smc_init2 (ad->n, ad->k)) || | ||
860 | NULL == (ad->tmpa1 = smc_init1 (ad->k)) || | ||
861 | NULL == (ad->tmpb1 = smc_init1 (ad->k))) | ||
862 | { | ||
863 | weprintf ("unable to alloc memory for first price outcome computation"); | ||
864 | return NULL; | ||
865 | } | ||
866 | 850 | ||
867 | head = (struct msg_head *)ret; | 851 | ad->tmpa1 = smc_init1 (ad->k); |
868 | head->prot_version = htonl (0); | 852 | brandt_assert (ad->tmpa1); |
869 | head->msg_type = htonl (msg_outcome); | 853 | |
870 | cur = ret + sizeof (*head); | 854 | ad->tmpb1 = smc_init1 (ad->k); |
855 | brandt_assert (ad->tmpb1); | ||
871 | 856 | ||
872 | /* create temporary lookup tables with partial sums */ | 857 | /* create temporary lookup tables with partial sums */ |
873 | tlta1 = smc_init1 (ad->k); | 858 | tlta1 = smc_init1 (ad->k); |
@@ -927,10 +912,6 @@ fp_pub_compute_outcome (struct BRANDT_Auction *ad, size_t *buflen) | |||
927 | 912 | ||
928 | for (uint16_t j = 0; j < ad->k; j++) | 913 | for (uint16_t j = 0; j < ad->k; j++) |
929 | { | 914 | { |
930 | gamma = (struct ec_mpi *)cur; | ||
931 | delta = &((struct ec_mpi *)cur)[1]; | ||
932 | proof2 = (struct proof_2dle *)(cur + 2 * sizeof (struct ec_mpi)); | ||
933 | |||
934 | /* copy unmasked outcome to all other bidder layers so they don't | 915 | /* copy unmasked outcome to all other bidder layers so they don't |
935 | * have to be recomputed to check the ZK proof_2dle's from other | 916 | * have to be recomputed to check the ZK proof_2dle's from other |
936 | * bidders when receiving their outcome messages */ | 917 | * bidders when receiving their outcome messages */ |
@@ -939,12 +920,64 @@ fp_pub_compute_outcome (struct BRANDT_Auction *ad, size_t *buflen) | |||
939 | ec_point_copy (ad->gamma2[a][j], tlta1[j]); | 920 | ec_point_copy (ad->gamma2[a][j], tlta1[j]); |
940 | ec_point_copy (ad->delta2[a][j], tltb1[j]); | 921 | ec_point_copy (ad->delta2[a][j], tltb1[j]); |
941 | } | 922 | } |
923 | } | ||
924 | |||
925 | gcry_mpi_release (coeff); | ||
926 | gcry_mpi_point_release (tmp); | ||
927 | smc_free1 (tlta1, ad->k); | ||
928 | smc_free1 (tltb1, ad->k); | ||
929 | } | ||
930 | |||
931 | |||
932 | /** | ||
933 | * fp_pub_compute_outcome computes the outcome for first price auctions with a | ||
934 | * public outcome and packs it into a message buffer together with proofs of | ||
935 | * correctnes. | ||
936 | * | ||
937 | * @param[in] ad Pointer to the BRANDT_Auction struct to operate on | ||
938 | * @param[out] buflen Size of the returned message buffer in bytes | ||
939 | * @return A buffer containing the encrypted outcome vectors | ||
940 | * which needs to be broadcast | ||
941 | */ | ||
942 | unsigned char * | ||
943 | fp_pub_compute_outcome (struct BRANDT_Auction *ad, size_t *buflen) | ||
944 | { | ||
945 | unsigned char *ret; | ||
946 | unsigned char *cur; | ||
947 | gcry_mpi_point_t tmpa = gcry_mpi_point_new (0); | ||
948 | gcry_mpi_point_t tmpb = gcry_mpi_point_new (0); | ||
949 | struct msg_head *head; | ||
950 | struct ec_mpi *gamma; | ||
951 | struct ec_mpi *delta; | ||
952 | struct proof_2dle *proof2; | ||
953 | |||
954 | brandt_assert (ad && buflen); | ||
955 | |||
956 | *buflen = (sizeof (*head) + | ||
957 | ad->k * (sizeof (*gamma) + | ||
958 | sizeof (*delta) + | ||
959 | sizeof (*proof2))); | ||
960 | ret = GNUNET_new_array (*buflen, unsigned char); | ||
961 | |||
962 | head = (struct msg_head *)ret; | ||
963 | head->prot_version = htonl (0); | ||
964 | head->msg_type = htonl (msg_outcome); | ||
965 | cur = ret + sizeof (*head); | ||
966 | |||
967 | for (uint16_t j = 0; j < ad->k; j++) | ||
968 | { | ||
969 | gamma = (struct ec_mpi *)cur; | ||
970 | delta = &((struct ec_mpi *)cur)[1]; | ||
971 | proof2 = (struct proof_2dle *)(cur + 2 * sizeof (struct ec_mpi)); | ||
972 | |||
973 | ec_point_copy (tmpa, ad->gamma2[ad->i][j]); | ||
974 | ec_point_copy (tmpb, ad->delta2[ad->i][j]); | ||
942 | 975 | ||
943 | /* apply random masking for losing bidders */ | 976 | /* apply random masking for losing bidders */ |
944 | smc_zkp_2dle (ad->gamma2[ad->i][j], | 977 | smc_zkp_2dle (ad->gamma2[ad->i][j], |
945 | ad->delta2[ad->i][j], | 978 | ad->delta2[ad->i][j], |
946 | tlta1[j], | 979 | tmpa, |
947 | tltb1[j], | 980 | tmpb, |
948 | NULL, | 981 | NULL, |
949 | proof2); | 982 | proof2); |
950 | 983 | ||
@@ -964,10 +997,8 @@ fp_pub_compute_outcome (struct BRANDT_Auction *ad, size_t *buflen) | |||
964 | cur += sizeof (*gamma) + sizeof (*delta) + sizeof (*proof2); | 997 | cur += sizeof (*gamma) + sizeof (*delta) + sizeof (*proof2); |
965 | } | 998 | } |
966 | 999 | ||
967 | gcry_mpi_release (coeff); | 1000 | gcry_mpi_point_release (tmpa); |
968 | gcry_mpi_point_release (tmp); | 1001 | gcry_mpi_point_release (tmpb); |
969 | smc_free1 (tlta1, ad->k); | ||
970 | smc_free1 (tltb1, ad->k); | ||
971 | return ret; | 1002 | return ret; |
972 | } | 1003 | } |
973 | 1004 | ||
@@ -1030,6 +1061,29 @@ quit: | |||
1030 | } | 1061 | } |
1031 | 1062 | ||
1032 | 1063 | ||
1064 | void | ||
1065 | fp_pub_prep_decryption (struct BRANDT_Auction *ad) | ||
1066 | { | ||
1067 | gcry_mpi_point_t tmp = gcry_mpi_point_new (0); | ||
1068 | |||
1069 | ad->phi2 = smc_init2 (ad->n, ad->k); | ||
1070 | brandt_assert (ad->phi2); | ||
1071 | |||
1072 | for (uint16_t j = 0; j < ad->k; j++) | ||
1073 | { | ||
1074 | smc_sum (tmp, &ad->delta2[0][j], ad->n, ad->k); | ||
1075 | |||
1076 | /* copy still encrypted outcome to all other bidder layers so they | ||
1077 | * don't have to be recomputed to check the ZK proof_2dle's from | ||
1078 | * other bidders when receiving their outcome decryption messages */ | ||
1079 | for (uint16_t a = 0; a < ad->n; a++) | ||
1080 | ec_point_copy (ad->phi2[a][j], tmp); | ||
1081 | } | ||
1082 | |||
1083 | gcry_mpi_point_release (tmp); | ||
1084 | } | ||
1085 | |||
1086 | |||
1033 | /** | 1087 | /** |
1034 | * fp_pub_decrypt_outcome decrypts part of the outcome and packs it into a | 1088 | * fp_pub_decrypt_outcome decrypts part of the outcome and packs it into a |
1035 | * message buffer together with proofs of correctnes. | 1089 | * message buffer together with proofs of correctnes. |
@@ -1044,8 +1098,8 @@ fp_pub_decrypt_outcome (struct BRANDT_Auction *ad, size_t *buflen) | |||
1044 | { | 1098 | { |
1045 | unsigned char *ret; | 1099 | unsigned char *ret; |
1046 | unsigned char *cur; | 1100 | unsigned char *cur; |
1047 | struct msg_head *head; | ||
1048 | gcry_mpi_point_t tmp = gcry_mpi_point_new (0); | 1101 | gcry_mpi_point_t tmp = gcry_mpi_point_new (0); |
1102 | struct msg_head *head; | ||
1049 | struct ec_mpi *phi; | 1103 | struct ec_mpi *phi; |
1050 | struct proof_2dle *proof2; | 1104 | struct proof_2dle *proof2; |
1051 | 1105 | ||
@@ -1053,11 +1107,6 @@ fp_pub_decrypt_outcome (struct BRANDT_Auction *ad, size_t *buflen) | |||
1053 | 1107 | ||
1054 | *buflen = (sizeof (*head) + ad->k * (sizeof (*phi) + sizeof (*proof2))); | 1108 | *buflen = (sizeof (*head) + ad->k * (sizeof (*phi) + sizeof (*proof2))); |
1055 | ret = GNUNET_new_array (*buflen, unsigned char); | 1109 | ret = GNUNET_new_array (*buflen, unsigned char); |
1056 | if (NULL == (ad->phi2 = smc_init2 (ad->n, ad->k))) | ||
1057 | { | ||
1058 | weprintf ("unable to alloc memory for first price outcome decryption"); | ||
1059 | return NULL; | ||
1060 | } | ||
1061 | 1110 | ||
1062 | head = (struct msg_head *)ret; | 1111 | head = (struct msg_head *)ret; |
1063 | head->prot_version = htonl (0); | 1112 | head->prot_version = htonl (0); |
@@ -1069,13 +1118,7 @@ fp_pub_decrypt_outcome (struct BRANDT_Auction *ad, size_t *buflen) | |||
1069 | phi = (struct ec_mpi *)cur; | 1118 | phi = (struct ec_mpi *)cur; |
1070 | proof2 = (struct proof_2dle *)(cur + sizeof (*phi)); | 1119 | proof2 = (struct proof_2dle *)(cur + sizeof (*phi)); |
1071 | 1120 | ||
1072 | smc_sum (tmp, &ad->delta2[0][j], ad->n, ad->k); | 1121 | ec_point_copy (tmp, ad->phi2[ad->i][j]); |
1073 | |||
1074 | /* copy still encrypted outcome to all other bidder layers so they | ||
1075 | * don't have to be recomputed to check the ZK proof_2dle's from | ||
1076 | * other bidders when receiving their outcome decryption messages */ | ||
1077 | for (uint16_t a = 0; a < ad->n; a++) | ||
1078 | ec_point_copy (ad->phi2[a][j], tmp); | ||
1079 | 1122 | ||
1080 | /* decrypt outcome component and prove the correct key was used */ | 1123 | /* decrypt outcome component and prove the correct key was used */ |
1081 | smc_zkp_2dle (ad->phi2[ad->i][j], | 1124 | smc_zkp_2dle (ad->phi2[ad->i][j], |
@@ -1138,12 +1181,13 @@ quit: | |||
1138 | } | 1181 | } |
1139 | 1182 | ||
1140 | 1183 | ||
1141 | int32_t | 1184 | struct BRANDT_Result *fp_pub_determine_outcome (struct BRANDT_Auction *ad, |
1142 | fp_pub_determine_outcome (struct BRANDT_Auction *ad, uint16_t *winner) | 1185 | uint16_t *len) |
1143 | { | 1186 | { |
1144 | int32_t ret = -1; | 1187 | struct BRANDT_Result *ret; |
1188 | int32_t price = -1; | ||
1189 | int32_t winner = -1; | ||
1145 | int dlogi = -1; | 1190 | int dlogi = -1; |
1146 | gcry_mpi_t dlog = gcry_mpi_new (256); | ||
1147 | gcry_mpi_point_t sum_gamma = gcry_mpi_point_new (0); | 1191 | gcry_mpi_point_t sum_gamma = gcry_mpi_point_new (0); |
1148 | gcry_mpi_point_t sum_phi = gcry_mpi_point_new (0); | 1192 | gcry_mpi_point_t sum_phi = gcry_mpi_point_new (0); |
1149 | 1193 | ||
@@ -1157,28 +1201,38 @@ fp_pub_determine_outcome (struct BRANDT_Auction *ad, uint16_t *winner) | |||
1157 | /* first non-zero component determines the price */ | 1201 | /* first non-zero component determines the price */ |
1158 | if (ec_point_cmp (sum_gamma, ec_zero)) | 1202 | if (ec_point_cmp (sum_gamma, ec_zero)) |
1159 | { | 1203 | { |
1160 | ret = j; | 1204 | price = j; |
1161 | break; | 1205 | break; |
1162 | } | 1206 | } |
1163 | } | 1207 | } |
1164 | 1208 | ||
1165 | dlogi = GNUNET_CRYPTO_ecc_dlog (ec_dlogctx, sum_gamma); | 1209 | dlogi = GNUNET_CRYPTO_ecc_dlog (ec_dlogctx, sum_gamma); |
1166 | brandt_assert (dlogi > 0); | 1210 | brandt_assert (dlogi > 0); |
1167 | gcry_mpi_set_ui (dlog, (unsigned long)dlogi); | ||
1168 | 1211 | ||
1212 | /* can only support up to bits(dlogi) bidders */ | ||
1213 | brandt_assert (sizeof (int) * 8 - 1 >= ad->n); | ||
1169 | for (uint16_t i = 0; i < ad->n; i++) | 1214 | for (uint16_t i = 0; i < ad->n; i++) |
1170 | { | 1215 | { |
1171 | if (gcry_mpi_test_bit (dlog, i)) | 1216 | /* first set bit determines the winner */ |
1217 | if (dlogi & (1 << i)) | ||
1172 | { | 1218 | { |
1173 | if (winner) | 1219 | winner = i; |
1174 | *winner = i; | ||
1175 | break; | 1220 | break; |
1176 | } | 1221 | } |
1177 | } | 1222 | } |
1178 | 1223 | ||
1179 | gcry_mpi_release (dlog); | ||
1180 | gcry_mpi_point_release (sum_gamma); | 1224 | gcry_mpi_point_release (sum_gamma); |
1181 | gcry_mpi_point_release (sum_phi); | 1225 | gcry_mpi_point_release (sum_phi); |
1226 | |||
1227 | if (-1 == winner || -1 == price) | ||
1228 | return NULL; | ||
1229 | |||
1230 | ret = GNUNET_new(struct BRANDT_Result); | ||
1231 | ret->bidder = winner; | ||
1232 | ret->price = price; | ||
1233 | ret->status = BRANDT_bidder_won; | ||
1234 | if (len) | ||
1235 | *len = 1; | ||
1182 | return ret; | 1236 | return ret; |
1183 | } | 1237 | } |
1184 | 1238 | ||
@@ -1509,33 +1563,57 @@ quit: | |||
1509 | } | 1563 | } |
1510 | 1564 | ||
1511 | 1565 | ||
1512 | int32_t | 1566 | struct BRANDT_Result *fp_priv_determine_outcome (struct BRANDT_Auction *ad, |
1513 | fp_priv_determine_outcome (struct BRANDT_Auction *ad) | 1567 | uint16_t *len) |
1514 | { | 1568 | { |
1515 | int32_t ret = -1; | 1569 | struct BRANDT_Result *ret; |
1516 | gcry_mpi_point_t sum_gamma = gcry_mpi_point_new (0); | 1570 | int32_t price = -1; |
1517 | gcry_mpi_point_t sum_phi = gcry_mpi_point_new (0); | 1571 | int32_t winner = -1; |
1572 | gcry_mpi_point_t sum_gamma = gcry_mpi_point_new (0); | ||
1573 | gcry_mpi_point_t sum_phi = gcry_mpi_point_new (0); | ||
1518 | 1574 | ||
1519 | brandt_assert (ad); | 1575 | brandt_assert (ad); |
1520 | 1576 | ||
1521 | for (uint16_t j = 0; j < ad->k; j++) | 1577 | for (uint16_t i = 0; i < ad->n; i++) |
1522 | { | 1578 | { |
1523 | smc_sum (sum_gamma, &ad->gamma3[0][ad->i][j], ad->n, ad->n * ad->k); | 1579 | if (!ad->seller_mode && i != ad->i) |
1524 | smc_sum (sum_phi, &ad->phi3[0][ad->i][j], ad->n, ad->n * ad->k); | 1580 | continue; |
1525 | gcry_mpi_ec_sub (sum_gamma, sum_gamma, sum_phi, ec_ctx); | 1581 | |
1526 | if (!ec_point_cmp (sum_gamma, ec_zero)) | 1582 | for (uint16_t j = 0; j < ad->k; j++) |
1527 | { | 1583 | { |
1528 | if (-1 != ret) | 1584 | smc_sum (sum_gamma, &ad->gamma3[0][i][j], ad->n, ad->n * ad->k); |
1585 | smc_sum (sum_phi, &ad->phi3[0][i][j], ad->n, ad->n * ad->k); | ||
1586 | gcry_mpi_ec_sub (sum_gamma, sum_gamma, sum_phi, ec_ctx); | ||
1587 | if (!ec_point_cmp (sum_gamma, ec_zero)) | ||
1529 | { | 1588 | { |
1530 | weprintf ("multiple winning prices detected"); | 1589 | if (-1 != price) |
1531 | return -1; | 1590 | { |
1591 | weprintf ("multiple winning prices detected"); | ||
1592 | return NULL; | ||
1593 | } | ||
1594 | if (-1 != winner) | ||
1595 | { | ||
1596 | weprintf ("multiple winners detected"); | ||
1597 | return NULL; | ||
1598 | } | ||
1599 | price = j; | ||
1600 | winner = i; | ||
1532 | } | 1601 | } |
1533 | ret = j; | ||
1534 | } | 1602 | } |
1535 | } | 1603 | } |
1536 | 1604 | ||
1537 | gcry_mpi_point_release (sum_gamma); | 1605 | gcry_mpi_point_release (sum_gamma); |
1538 | gcry_mpi_point_release (sum_phi); | 1606 | gcry_mpi_point_release (sum_phi); |
1607 | |||
1608 | if (-1 == winner || -1 == price) | ||
1609 | return NULL; | ||
1610 | |||
1611 | ret = GNUNET_new(struct BRANDT_Result); | ||
1612 | ret->bidder = winner; | ||
1613 | ret->price = price; | ||
1614 | ret->status = BRANDT_bidder_won; | ||
1615 | if (len) | ||
1616 | *len = 1; | ||
1539 | return ret; | 1617 | return ret; |
1540 | } | 1618 | } |
1541 | 1619 | ||
@@ -116,12 +116,14 @@ int smc_zkp_0og_check (const gcry_mpi_point_t y, | |||
116 | 116 | ||
117 | /* --- Protocol implementation --- */ | 117 | /* --- Protocol implementation --- */ |
118 | 118 | ||
119 | void smc_prep_keyshare (struct BRANDT_Auction *ad); | ||
119 | unsigned char *smc_gen_keyshare (struct BRANDT_Auction *ad, size_t *buflen); | 120 | unsigned char *smc_gen_keyshare (struct BRANDT_Auction *ad, size_t *buflen); |
120 | int smc_recv_keyshare (struct BRANDT_Auction *ad, | 121 | int smc_recv_keyshare (struct BRANDT_Auction *ad, |
121 | const unsigned char *buf, | 122 | const unsigned char *buf, |
122 | size_t buflen, | 123 | size_t buflen, |
123 | uint16_t sender_index); | 124 | uint16_t sender_index); |
124 | 125 | ||
126 | void smc_prep_bid (struct BRANDT_Auction *ad); | ||
125 | unsigned char *smc_encrypt_bid (struct BRANDT_Auction *ad, size_t *buflen); | 127 | unsigned char *smc_encrypt_bid (struct BRANDT_Auction *ad, size_t *buflen); |
126 | int smc_recv_encrypted_bid (struct BRANDT_Auction *ad, | 128 | int smc_recv_encrypted_bid (struct BRANDT_Auction *ad, |
127 | const unsigned char *buf, | 129 | const unsigned char *buf, |
@@ -142,8 +144,10 @@ int fp_priv_recv_decryption (struct BRANDT_Auction *ad, | |||
142 | size_t buflen, | 144 | size_t buflen, |
143 | uint16_t sender); | 145 | uint16_t sender); |
144 | 146 | ||
145 | int32_t fp_priv_determine_outcome (struct BRANDT_Auction *ad); | 147 | struct BRANDT_Result *fp_priv_determine_outcome (struct BRANDT_Auction *ad, |
148 | uint16_t *len); | ||
146 | 149 | ||
150 | void fp_pub_prep_outcome (struct BRANDT_Auction *ad); | ||
147 | unsigned char *fp_pub_compute_outcome (struct BRANDT_Auction *ad, | 151 | unsigned char *fp_pub_compute_outcome (struct BRANDT_Auction *ad, |
148 | size_t *buflen); | 152 | size_t *buflen); |
149 | int fp_pub_recv_outcome (struct BRANDT_Auction *ad, | 153 | int fp_pub_recv_outcome (struct BRANDT_Auction *ad, |
@@ -151,6 +155,7 @@ int fp_pub_recv_outcome (struct BRANDT_Auction *ad, | |||
151 | size_t buflen, | 155 | size_t buflen, |
152 | uint16_t sender); | 156 | uint16_t sender); |
153 | 157 | ||
158 | void fp_pub_prep_decryption (struct BRANDT_Auction *ad); | ||
154 | unsigned char *fp_pub_decrypt_outcome (struct BRANDT_Auction *ad, | 159 | unsigned char *fp_pub_decrypt_outcome (struct BRANDT_Auction *ad, |
155 | size_t *buflen); | 160 | size_t *buflen); |
156 | int fp_pub_recv_decryption (struct BRANDT_Auction *ad, | 161 | int fp_pub_recv_decryption (struct BRANDT_Auction *ad, |
@@ -158,24 +163,71 @@ int fp_pub_recv_decryption (struct BRANDT_Auction *ad, | |||
158 | size_t buflen, | 163 | size_t buflen, |
159 | uint16_t sender); | 164 | uint16_t sender); |
160 | 165 | ||
161 | int32_t fp_pub_determine_outcome (struct BRANDT_Auction *ad, uint16_t *winner); | 166 | struct BRANDT_Result *fp_pub_determine_outcome (struct BRANDT_Auction *ad, |
167 | uint16_t *len); | ||
162 | 168 | ||
163 | 169 | ||
164 | /* --- Round dictionaries --- */ | 170 | /* --- Round dictionaries --- */ |
165 | 171 | ||
172 | typedef void | ||
173 | (*RoundPrep)(struct BRANDT_Auction *ad); | ||
174 | |||
166 | typedef int | 175 | typedef int |
167 | (*msg_in)(struct BRANDT_Auction *ad, | 176 | (*MsgIn)(struct BRANDT_Auction *ad, |
168 | const unsigned char *buf, | 177 | const unsigned char *buf, |
169 | size_t buflen, | 178 | size_t buflen, |
170 | uint16_t sender); | 179 | uint16_t sender); |
171 | 180 | ||
172 | 181 | ||
173 | typedef unsigned char * | 182 | typedef unsigned char * |
174 | (*msg_out)(struct BRANDT_Auction *ad, | 183 | (*MsgOut)(struct BRANDT_Auction *ad, |
175 | size_t *buflen); | 184 | size_t *buflen); |
176 | 185 | ||
177 | 186 | ||
178 | /** | 187 | /** |
188 | * Functions of this type determine the outcome of an auction. | ||
189 | * | ||
190 | * \todo: export *proof* of erroneous behaviour / outcome. | ||
191 | * | ||
192 | * @param[in] ad Pointer to the auction data struct. | ||
193 | * @param[out] len Amount of items in @a results. | ||
194 | * @return An array of results for one or more bidders. Each bidder | ||
195 | * will only be listed once. | ||
196 | */ | ||
197 | typedef struct BRANDT_Result * | ||
198 | (*Result)(struct BRANDT_Auction *ad, | ||
199 | uint16_t *len); | ||
200 | |||
201 | |||
202 | static const RoundPrep handler_prep[auction_last][outcome_last][msg_last] = { | ||
203 | [auction_firstPrice] = { | ||
204 | [outcome_private] = { | ||
205 | [msg_init] = &smc_prep_keyshare, | ||
206 | [msg_bid] = &smc_prep_bid, | ||
207 | // [msg_outcome] = &fp_priv_prep_outcome, | ||
208 | // [msg_decrypt] = &fp_priv_prep_decryption, | ||
209 | }, | ||
210 | [outcome_public] = { | ||
211 | [msg_init] = &smc_prep_keyshare, | ||
212 | [msg_bid] = &smc_prep_bid, | ||
213 | [msg_outcome] = &fp_pub_prep_outcome, | ||
214 | [msg_decrypt] = &fp_pub_prep_decryption, | ||
215 | }, | ||
216 | }, | ||
217 | [auction_mPlusFirstPrice] = { | ||
218 | [outcome_private] = { | ||
219 | [msg_init] = &smc_prep_keyshare, | ||
220 | [msg_bid] = &smc_prep_bid, | ||
221 | }, | ||
222 | [outcome_public] = { | ||
223 | [msg_init] = &smc_prep_keyshare, | ||
224 | [msg_bid] = &smc_prep_bid, | ||
225 | }, | ||
226 | }, | ||
227 | }; | ||
228 | |||
229 | |||
230 | /** | ||
179 | * stores the function pointers to receive functions for each state. | 231 | * stores the function pointers to receive functions for each state. |
180 | * | 232 | * |
181 | * The first index denotes if a first price auction or a M+1st price auction is | 233 | * The first index denotes if a first price auction or a M+1st price auction is |
@@ -185,7 +237,7 @@ typedef unsigned char * | |||
185 | * The second index denotes if the outcome should be public or private. A value | 237 | * The second index denotes if the outcome should be public or private. A value |
186 | * of 0 means a private outcome, while a value of 1 means public outcome. | 238 | * of 0 means a private outcome, while a value of 1 means public outcome. |
187 | */ | 239 | */ |
188 | static const msg_in handler_in[auction_last][outcome_last][msg_last] = { | 240 | static const MsgIn handler_in[auction_last][outcome_last][msg_last] = { |
189 | [auction_firstPrice] = { | 241 | [auction_firstPrice] = { |
190 | [outcome_private] = { | 242 | [outcome_private] = { |
191 | [msg_init] = &smc_recv_keyshare, | 243 | [msg_init] = &smc_recv_keyshare, |
@@ -224,7 +276,7 @@ static const msg_in handler_in[auction_last][outcome_last][msg_last] = { | |||
224 | * The second index denotes if the outcome should be public or private. A value | 276 | * The second index denotes if the outcome should be public or private. A value |
225 | * of 0 means a private outcome, while a value of 1 means public outcome. | 277 | * of 0 means a private outcome, while a value of 1 means public outcome. |
226 | */ | 278 | */ |
227 | static const msg_out handler_out[auction_last][outcome_last][msg_last] = { | 279 | static const MsgOut handler_out[auction_last][outcome_last][msg_last] = { |
228 | [auction_firstPrice] = { | 280 | [auction_firstPrice] = { |
229 | [outcome_private] = { | 281 | [outcome_private] = { |
230 | [msg_init] = &smc_gen_keyshare, | 282 | [msg_init] = &smc_gen_keyshare, |
@@ -251,5 +303,28 @@ static const msg_out handler_out[auction_last][outcome_last][msg_last] = { | |||
251 | }, | 303 | }, |
252 | }; | 304 | }; |
253 | 305 | ||
306 | /** | ||
307 | * stores the function pointers to outcome determination functions for each | ||
308 | * auction mode. | ||
309 | * | ||
310 | * The first index denotes if a first price auction or a M+1st price auction is | ||
311 | * used. If it is 0, it is a first price auction, if it is 1, it is a M+1st | ||
312 | * price auction. | ||
313 | * | ||
314 | * The second index denotes if the outcome should be public or private. A value | ||
315 | * of 0 means a private outcome, while a value of 1 means public outcome. | ||
316 | */ | ||
317 | static const Result handler_res[auction_last][outcome_last] = { | ||
318 | [auction_firstPrice] = { | ||
319 | [outcome_private] = &fp_priv_determine_outcome, | ||
320 | [outcome_public] = &fp_pub_determine_outcome, | ||
321 | }, | ||
322 | // [auction_mPlusFirstPrice] = { | ||
323 | // [outcome_private] = , | ||
324 | // [outcome_public] = , | ||
325 | // }, | ||
326 | }; | ||
327 | |||
328 | |||
254 | 329 | ||
255 | #endif /* ifndef _BRANDT_CRYPTO_H */ | 330 | #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 { | |||
51 | }; | 51 | }; |
52 | 52 | ||
53 | 53 | ||
54 | enum result_code { | ||
55 | result_loser = 0, | ||
56 | result_winner = 1, | ||
57 | result_no_bidders = -2 | ||
58 | }; | ||
59 | |||
60 | |||
61 | GNUNET_NETWORK_STRUCT_BEGIN | 54 | GNUNET_NETWORK_STRUCT_BEGIN |
62 | 55 | ||
63 | struct msg_head { | 56 | 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 @@ | |||
30 | #include "util.h" | 30 | #include "util.h" |
31 | 31 | ||
32 | 32 | ||
33 | struct msg | ||
34 | { | ||
35 | uint16_t sender; | ||
36 | uint16_t receiver; | ||
37 | void *buf; | ||
38 | size_t buf_len; | ||
39 | }; | ||
40 | |||
41 | |||
42 | static uint16_t *id; | ||
43 | static struct BRANDT_Auction **ad; | ||
44 | static uint16_t bidders = 3; | ||
45 | static uint16_t prizes = 8; | ||
46 | |||
47 | |||
48 | static void | ||
49 | bidder_start (void *arg) | ||
50 | { | ||
51 | uint16_t i = *(uint16_t *)arg; | ||
52 | |||
53 | weprintf("starting bidder %d", i); | ||
54 | BRANDT_bidder_start (ad[i], i, bidders); | ||
55 | } | ||
56 | |||
57 | |||
58 | static void | ||
59 | transfer_message (void *arg) | ||
60 | { | ||
61 | struct msg *m = (struct msg *)arg; | ||
62 | struct msg_head *h = (struct msg_head *)m->buf; | ||
63 | |||
64 | weprintf("xfer msg %d %x from %d to %d", ntohl(h->msg_type), arg, m->sender, m->receiver); | ||
65 | BRANDT_got_message (ad[m->receiver], m->sender, m->buf, m->buf_len); | ||
66 | free (arg); | ||
67 | } | ||
68 | |||
69 | |||
70 | static uint16_t | ||
71 | cb_start (void *auction_closure) | ||
72 | { | ||
73 | uint16_t *s = (uint16_t *)auction_closure; | ||
74 | if (!s || bidders != *s) | ||
75 | { | ||
76 | weprintf ("start callback called from bidder"); | ||
77 | _exit (1); | ||
78 | } | ||
79 | |||
80 | for (uint16_t i = 0; i < bidders; i++) | ||
81 | GNUNET_SCHEDULER_add_now (&bidder_start, &id[i]); | ||
82 | |||
83 | return bidders; | ||
84 | } | ||
85 | |||
86 | |||
87 | static int | ||
88 | cb_broadcast (void *auction_closure, | ||
89 | const void *msg, | ||
90 | size_t msg_len) | ||
91 | { | ||
92 | uint16_t *s = (uint16_t *)auction_closure; | ||
93 | struct msg *m; | ||
94 | for (uint16_t i = 0; i <= bidders; i++) | ||
95 | { | ||
96 | if (i == *s) | ||
97 | continue; | ||
98 | m = GNUNET_new (struct msg); | ||
99 | m->sender = *s; | ||
100 | m->receiver = i; | ||
101 | m->buf = GNUNET_new_array (msg_len, unsigned char); | ||
102 | memcpy (m->buf, msg, msg_len); | ||
103 | m->buf_len = msg_len; | ||
104 | GNUNET_SCHEDULER_add_now (&transfer_message, m); | ||
105 | } | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | |||
110 | static int | ||
111 | cb_unicast (void *auction_closure, | ||
112 | const void *msg, | ||
113 | size_t msg_len) | ||
114 | { | ||
115 | } | ||
116 | |||
117 | |||
118 | static void | ||
119 | cb_result (void *auction_closure, | ||
120 | struct BRANDT_Result results[], | ||
121 | uint16_t results_len) | ||
122 | { | ||
123 | } | ||
124 | |||
125 | |||
33 | static void | 126 | static void |
34 | run_new_join (void *arg) | 127 | run_new_join (void *arg) |
35 | { | 128 | { |
36 | int *ret = arg; | 129 | int *ret = arg; |
37 | const char description[] = "test description for test_new_join"; | 130 | const char description[] = "test description for test_new_join"; |
38 | struct BRANDT_Auction *ad_seller; | ||
39 | struct BRANDT_Auction *ad_bidder; | ||
40 | void *desc; | 131 | void *desc; |
41 | size_t desc_len; | 132 | size_t desc_len; |
42 | 133 | ||
43 | ad_seller = BRANDT_new (NULL, | 134 | ad = GNUNET_new_array (bidders + 1, struct BRANDT_Auction *); |
44 | NULL, | 135 | |
45 | NULL, | 136 | ad[bidders] = BRANDT_new (&cb_result, |
46 | NULL, | 137 | &cb_broadcast, |
138 | &cb_start, | ||
139 | &id[bidders], | ||
47 | &desc, | 140 | &desc, |
48 | &desc_len, | 141 | &desc_len, |
49 | description, | 142 | description, |
50 | sizeof (description), | 143 | sizeof (description), |
51 | GNUNET_TIME_absolute_get (), | 144 | GNUNET_TIME_absolute_get (), |
52 | GNUNET_TIME_UNIT_MINUTES, | 145 | GNUNET_TIME_UNIT_MINUTES, |
53 | 8, | 146 | prizes, /* amount of possible prizes */ |
54 | 0, | 147 | 0, /* m */ |
55 | 1); | 148 | 1); |
56 | if (!ad_seller) | 149 | if (!ad[bidders]) |
57 | { | 150 | { |
58 | weprintf ("BRANDT_new() failed."); | 151 | weprintf ("BRANDT_new() failed."); |
59 | *ret = 0; | 152 | _exit (1); |
60 | return; | ||
61 | } | ||
62 | |||
63 | |||
64 | ad_bidder = BRANDT_join (NULL, | ||
65 | NULL, | ||
66 | NULL, | ||
67 | NULL, | ||
68 | desc, | ||
69 | desc_len, | ||
70 | description, | ||
71 | sizeof (description)); | ||
72 | if (!ad_bidder) | ||
73 | { | ||
74 | weprintf ("BRANDT_join() failed."); | ||
75 | *ret = 0; | ||
76 | return; | ||
77 | } | 153 | } |
78 | 154 | ||
79 | if (ad_seller->k != ad_bidder->k || | 155 | for (uint16_t i = 0; i < bidders; i++) |
80 | ad_seller->m != ad_bidder->m || | ||
81 | ad_seller->outcome_public != ad_bidder->outcome_public || | ||
82 | ad_seller->time_start.abs_value_us | ||
83 | != ad_bidder->time_start.abs_value_us || | ||
84 | ad_seller->time_round.rel_value_us | ||
85 | != ad_bidder->time_round.rel_value_us || | ||
86 | !ad_seller->seller_mode || | ||
87 | ad_bidder->seller_mode) | ||
88 | { | 156 | { |
89 | weprintf ("error/mismatch in basic auction data"); | 157 | ad[i] = BRANDT_join (&cb_result, |
90 | *ret = 0; | 158 | &cb_broadcast, |
91 | return; | 159 | &cb_unicast, |
160 | &id[i], | ||
161 | desc, | ||
162 | desc_len, | ||
163 | description, | ||
164 | sizeof (description), | ||
165 | 3); /* bid */ | ||
166 | if (!ad[i]) | ||
167 | { | ||
168 | weprintf ("BRANDT_join() failed."); | ||
169 | _exit (1); | ||
170 | } | ||
171 | |||
172 | if (ad[bidders]->k != ad[i]->k || | ||
173 | ad[bidders]->m != ad[i]->m || | ||
174 | ad[bidders]->outcome_public != ad[i]->outcome_public || | ||
175 | ad[bidders]->time_start.abs_value_us | ||
176 | != ad[i]->time_start.abs_value_us || | ||
177 | ad[bidders]->time_round.rel_value_us | ||
178 | != ad[i]->time_round.rel_value_us || | ||
179 | !ad[bidders]->seller_mode || /* todo: split out */ | ||
180 | ad[i]->seller_mode) | ||
181 | { | ||
182 | weprintf ("error/mismatch in basic auction data"); | ||
183 | _exit (1); | ||
184 | } | ||
92 | } | 185 | } |
93 | 186 | ||
94 | BRANDT_destroy (ad_seller); | ||
95 | BRANDT_destroy (ad_bidder); | ||
96 | |||
97 | *ret = 1; | 187 | *ret = 1; |
98 | } | 188 | } |
99 | 189 | ||
@@ -103,7 +193,15 @@ test_new_join () | |||
103 | { | 193 | { |
104 | int ret = 0; | 194 | int ret = 0; |
105 | 195 | ||
196 | id = GNUNET_new_array (bidders + 1, uint16_t); | ||
197 | for (uint16_t i = 0; i <= bidders; i++) | ||
198 | id[i] = i; | ||
199 | |||
106 | GNUNET_SCHEDULER_run (&run_new_join, &ret); | 200 | GNUNET_SCHEDULER_run (&run_new_join, &ret); |
201 | |||
202 | for (uint16_t i = 0; i <= bidders; i++) | ||
203 | BRANDT_destroy (ad[i]); | ||
204 | |||
107 | return ret; | 205 | return ret; |
108 | } | 206 | } |
109 | 207 | ||
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 () | |||
197 | } | 197 | } |
198 | 198 | ||
199 | 199 | ||
200 | /* | 200 | /** |
201 | * compute round @a index of the protocol specified by @a type and @a oc | ||
202 | * | ||
203 | * @param[in] type auction type | ||
204 | * @param[in] oc outcome type | ||
205 | * @param[in] index round index | ||
201 | */ | 206 | */ |
202 | #define ROUND(type, oc, index) do { \ | 207 | #define ROUND(type, oc, index) do { \ |
203 | for (uint16_t i = 0; i < bidders; i++) \ | 208 | for (uint16_t i = 0; i < bidders; i++) \ |
204 | { \ | 209 | { \ |
210 | handler_prep[type][oc][index] (&ad[i]); \ | ||
205 | bufs[i] = handler_out[type][oc][index] (&ad[i], &lens[i]); \ | 211 | bufs[i] = handler_out[type][oc][index] (&ad[i], &lens[i]); \ |
206 | CHECK (bufs[i], "failed to gen keyshare"); \ | 212 | CHECK (bufs[i], "failed to gen keyshare"); \ |
207 | } \ | 213 | } \ |
@@ -228,63 +234,43 @@ test_setup_auction_data () | |||
228 | 234 | ||
229 | 235 | ||
230 | static int | 236 | static int |
231 | test_private_first_price () | 237 | test_auction (enum auction_type atype, enum outcome_type oc) |
232 | { | 238 | { |
233 | unsigned char *bufs[bidders]; | 239 | unsigned char *bufs[bidders]; |
234 | size_t lens[bidders]; | 240 | size_t lens[bidders]; |
235 | int32_t winner = -1; | 241 | int32_t winner = -1; |
242 | int32_t price = -1; | ||
236 | 243 | ||
237 | ROUND (auction_firstPrice, outcome_private, msg_init); | 244 | weprintf ("testing auction type %d and outcome format %d...", atype, oc); |
238 | ROUND (auction_firstPrice, outcome_private, msg_bid); | 245 | ROUND (atype, oc, msg_init); |
239 | ROUND (auction_firstPrice, outcome_private, msg_outcome); | 246 | ROUND (atype, oc, msg_bid); |
240 | ROUND (auction_firstPrice, outcome_private, msg_decrypt); | 247 | ROUND (atype, oc, msg_outcome); |
248 | ROUND (atype, oc, msg_decrypt); | ||
241 | 249 | ||
242 | /* outcome */ | 250 | /* outcome */ |
243 | for (uint16_t i = 0; i < ad->n; i++) | 251 | for (uint16_t i = 0; i < ad->n; i++) |
244 | { | 252 | { |
245 | if (-1 != fp_priv_determine_outcome (&ad[i])) | 253 | struct BRANDT_Result *res; |
246 | { | 254 | uint16_t reslen; |
247 | CHECK (-1 == winner, "multiple winners detected"); | 255 | |
248 | winner = i; | 256 | res = handler_res[atype][oc] (&ad[i], &reslen); |
249 | } | 257 | if (res && -1 == price && -1 != res->price) |
258 | price = res->price; | ||
259 | if (res) | ||
260 | weprintf ("price: %d", res->price); | ||
261 | CHECK (!res || res->price == price, "different prices detected"); | ||
262 | if (res && -1 == winner && -1 != res->bidder) | ||
263 | winner = res->bidder; | ||
264 | CHECK (!res || res->bidder == winner, "different winners detected"); | ||
250 | } | 265 | } |
266 | |||
251 | CHECK (-1 != winner, "no winner detected"); | 267 | CHECK (-1 != winner, "no winner detected"); |
268 | CHECK (-1 != price, "no price detected"); | ||
252 | fputs ("good: one winner detected\n", stderr); | 269 | fputs ("good: one winner detected\n", stderr); |
253 | return 1; | 270 | return 1; |
254 | } | 271 | } |
255 | 272 | ||
256 | 273 | ||
257 | static int | ||
258 | test_public_first_price () | ||
259 | { | ||
260 | unsigned char *bufs[bidders]; | ||
261 | size_t lens[bidders]; | ||
262 | int32_t wret = -1; | ||
263 | int32_t pret = -1; | ||
264 | uint16_t winner = -1; | ||
265 | uint16_t price = -1; | ||
266 | |||
267 | ROUND (auction_firstPrice, outcome_public, msg_init); | ||
268 | ROUND (auction_firstPrice, outcome_public, msg_bid); | ||
269 | ROUND (auction_firstPrice, outcome_public, msg_outcome); | ||
270 | ROUND (auction_firstPrice, outcome_public, msg_decrypt); | ||
271 | |||
272 | /* outcome */ | ||
273 | for (uint16_t i = 0; i < ad->n; i++) | ||
274 | { | ||
275 | price = fp_pub_determine_outcome (&ad[i], &winner); | ||
276 | if (-1 == pret) | ||
277 | pret = price; | ||
278 | CHECK (price == pret, "different prices detected"); | ||
279 | if (-1 == wret) | ||
280 | wret = winner; | ||
281 | CHECK (winner == wret, "different winners detected"); | ||
282 | } | ||
283 | fputs ("good: same winner detected\n", stderr); | ||
284 | return 1; | ||
285 | } | ||
286 | |||
287 | |||
288 | static void | 274 | static void |
289 | cleanup_auction_data () | 275 | cleanup_auction_data () |
290 | { | 276 | { |
@@ -308,6 +294,30 @@ cleanup_auction_data () | |||
308 | } | 294 | } |
309 | 295 | ||
310 | 296 | ||
297 | static int | ||
298 | test_all_auctions () | ||
299 | { | ||
300 | for (size_t atype = 0; atype < auction_last; atype++) | ||
301 | { | ||
302 | if (auction_firstPrice != atype) /* others not yet implemented */ | ||
303 | continue; | ||
304 | |||
305 | // for (size_t oc = 0; oc < outcome_last; oc++) | ||
306 | // { | ||
307 | size_t oc = outcome_public; | ||
308 | if (!test_setup_auction_data() || !test_auction (atype, oc)) | ||
309 | { | ||
310 | cleanup_auction_data (); | ||
311 | return 0; | ||
312 | } | ||
313 | cleanup_auction_data (); | ||
314 | // } | ||
315 | } | ||
316 | |||
317 | return 1; | ||
318 | } | ||
319 | |||
320 | |||
311 | int | 321 | int |
312 | main (int argc, char *argv[]) | 322 | main (int argc, char *argv[]) |
313 | { | 323 | { |
@@ -332,12 +342,7 @@ main (int argc, char *argv[]) | |||
332 | RUN (test_smc_zkp_0og); | 342 | RUN (test_smc_zkp_0og); |
333 | } | 343 | } |
334 | 344 | ||
335 | RUN (test_setup_auction_data); | 345 | RUN (test_all_auctions); |
336 | RUN (test_private_first_price); | ||
337 | cleanup_auction_data (); | ||
338 | RUN (test_setup_auction_data); | ||
339 | RUN (test_public_first_price); | ||
340 | cleanup_auction_data (); | ||
341 | 346 | ||
342 | GNUNET_CRYPTO_ecc_dlog_release (edc); | 347 | GNUNET_CRYPTO_ecc_dlog_release (edc); |
343 | return ret; | 348 | return ret; |