aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--brandt.c82
-rw-r--r--brandt.h50
-rw-r--r--crypto.c280
-rw-r--r--crypto.h87
-rw-r--r--internals.h7
-rw-r--r--test_brandt.c182
-rw-r--r--test_crypto.c101
7 files changed, 550 insertions, 239 deletions
diff --git a/brandt.c b/brandt.c
index 4a4dc49..4f5a3f5 100644
--- a/brandt.c
+++ b/brandt.c
@@ -52,11 +52,35 @@ BRANDT_init (struct GNUNET_CRYPTO_EccDlogContext *dlogctx)
52 52
53void 53void
54BRANDT_bidder_start (struct BRANDT_Auction *auction, 54BRANDT_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);
diff --git a/brandt.h b/brandt.h
index 569db11..3ed48b6 100644
--- a/brandt.h
+++ b/brandt.h
@@ -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 */
32enum BRANDT_BidderStatus
33{
34 BRANDT_bidder_won,
35};
36
37/** opaque, defined in internals.h */
32struct BRANDT_Auction; 38struct 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 */
44struct 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 */
100typedef void 120typedef 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
107void 126void
@@ -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 */
224void 245void
225BRANDT_bidder_start (struct BRANDT_Auction *auction, 246BRANDT_bidder_start (struct BRANDT_Auction *auction,
247 uint16_t i,
226 uint16_t n); 248 uint16_t n);
227 249
228 250
diff --git a/crypto.c b/crypto.c
index 965f9cc..afa72d4 100644
--- a/crypto.c
+++ b/crypto.c
@@ -609,6 +609,14 @@ smc_sum (gcry_mpi_point_t out,
609} 609}
610 610
611 611
612void
613smc_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 *
622smc_gen_keyshare (struct BRANDT_Auction *ad, size_t *buflen) 630smc_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
694void
695smc_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/** 835void
826 * fp_pub_compute_outcome computes the outcome for first price auctions with a 836fp_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 */
835unsigned char *
836fp_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 */
942unsigned char *
943fp_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
1064void
1065fp_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
1141int32_t 1184struct BRANDT_Result *fp_pub_determine_outcome (struct BRANDT_Auction *ad,
1142fp_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
1512int32_t 1566struct BRANDT_Result *fp_priv_determine_outcome (struct BRANDT_Auction *ad,
1513fp_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
diff --git a/crypto.h b/crypto.h
index 2f40ed3..b3520d0 100644
--- a/crypto.h
+++ b/crypto.h
@@ -116,12 +116,14 @@ int smc_zkp_0og_check (const gcry_mpi_point_t y,
116 116
117/* --- Protocol implementation --- */ 117/* --- Protocol implementation --- */
118 118
119void smc_prep_keyshare (struct BRANDT_Auction *ad);
119unsigned char *smc_gen_keyshare (struct BRANDT_Auction *ad, size_t *buflen); 120unsigned char *smc_gen_keyshare (struct BRANDT_Auction *ad, size_t *buflen);
120int smc_recv_keyshare (struct BRANDT_Auction *ad, 121int 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
126void smc_prep_bid (struct BRANDT_Auction *ad);
125unsigned char *smc_encrypt_bid (struct BRANDT_Auction *ad, size_t *buflen); 127unsigned char *smc_encrypt_bid (struct BRANDT_Auction *ad, size_t *buflen);
126int smc_recv_encrypted_bid (struct BRANDT_Auction *ad, 128int 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
145int32_t fp_priv_determine_outcome (struct BRANDT_Auction *ad); 147struct BRANDT_Result *fp_priv_determine_outcome (struct BRANDT_Auction *ad,
148 uint16_t *len);
146 149
150void fp_pub_prep_outcome (struct BRANDT_Auction *ad);
147unsigned char *fp_pub_compute_outcome (struct BRANDT_Auction *ad, 151unsigned char *fp_pub_compute_outcome (struct BRANDT_Auction *ad,
148 size_t *buflen); 152 size_t *buflen);
149int fp_pub_recv_outcome (struct BRANDT_Auction *ad, 153int 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
158void fp_pub_prep_decryption (struct BRANDT_Auction *ad);
154unsigned char *fp_pub_decrypt_outcome (struct BRANDT_Auction *ad, 159unsigned char *fp_pub_decrypt_outcome (struct BRANDT_Auction *ad,
155 size_t *buflen); 160 size_t *buflen);
156int fp_pub_recv_decryption (struct BRANDT_Auction *ad, 161int 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
161int32_t fp_pub_determine_outcome (struct BRANDT_Auction *ad, uint16_t *winner); 166struct 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
172typedef void
173(*RoundPrep)(struct BRANDT_Auction *ad);
174
166typedef int 175typedef 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
173typedef unsigned char * 182typedef 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 */
197typedef struct BRANDT_Result *
198(*Result)(struct BRANDT_Auction *ad,
199 uint16_t *len);
200
201
202static 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 */
188static const msg_in handler_in[auction_last][outcome_last][msg_last] = { 240static 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 */
227static const msg_out handler_out[auction_last][outcome_last][msg_last] = { 279static 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 */
317static 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
54enum result_code {
55 result_loser = 0,
56 result_winner = 1,
57 result_no_bidders = -2
58};
59
60
61GNUNET_NETWORK_STRUCT_BEGIN 54GNUNET_NETWORK_STRUCT_BEGIN
62 55
63struct msg_head { 56struct 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
33struct msg
34{
35 uint16_t sender;
36 uint16_t receiver;
37 void *buf;
38 size_t buf_len;
39};
40
41
42static uint16_t *id;
43static struct BRANDT_Auction **ad;
44static uint16_t bidders = 3;
45static uint16_t prizes = 8;
46
47
48static void
49bidder_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
58static void
59transfer_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
70static uint16_t
71cb_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
87static int
88cb_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
110static int
111cb_unicast (void *auction_closure,
112 const void *msg,
113 size_t msg_len)
114{
115}
116
117
118static void
119cb_result (void *auction_closure,
120 struct BRANDT_Result results[],
121 uint16_t results_len)
122{
123}
124
125
33static void 126static void
34run_new_join (void *arg) 127run_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
230static int 236static int
231test_private_first_price () 237test_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
257static int
258test_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
288static void 274static void
289cleanup_auction_data () 275cleanup_auction_data ()
290{ 276{
@@ -308,6 +294,30 @@ cleanup_auction_data ()
308} 294}
309 295
310 296
297static int
298test_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
311int 321int
312main (int argc, char *argv[]) 322main (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;