diff options
author | Markus Teich <markus.teich@stusta.mhn.de> | 2016-10-15 20:33:21 +0200 |
---|---|---|
committer | Markus Teich <markus.teich@stusta.mhn.de> | 2016-10-15 20:33:21 +0200 |
commit | 5ce71329cfa5540aa8bb7091df292fc133bcf8fa (patch) | |
tree | ab79ad8748a00a93c15485386b973227b72b9287 | |
parent | 5d028cc81ef0635a9dbf57584a1ac0dd3bb3cfb2 (diff) | |
download | libbrandt-5ce71329cfa5540aa8bb7091df292fc133bcf8fa.tar.gz libbrandt-5ce71329cfa5540aa8bb7091df292fc133bcf8fa.zip |
add M+1st price private outcome implementation
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | crypto.h | 22 | ||||
-rw-r--r-- | mp_priv.c | 216 |
3 files changed, 234 insertions, 5 deletions
diff --git a/Makefile.am b/Makefile.am index 92674e6..e0b6356 100644 --- a/Makefile.am +++ b/Makefile.am | |||
@@ -9,6 +9,7 @@ libbrandt_la_SOURCES = \ | |||
9 | crypto.c \ | 9 | crypto.c \ |
10 | fp_priv.c \ | 10 | fp_priv.c \ |
11 | fp_pub.c \ | 11 | fp_pub.c \ |
12 | mp_priv.c \ | ||
12 | util.c | 13 | util.c |
13 | 14 | ||
14 | libbrandt_la_LIBADD = \ | 15 | libbrandt_la_LIBADD = \ |
@@ -182,6 +182,12 @@ struct BRANDT_Result *fp_pub_determine_outcome (struct BRANDT_Auction *ad, | |||
182 | uint16_t *len); | 182 | uint16_t *len); |
183 | 183 | ||
184 | 184 | ||
185 | void mp_priv_prep_outcome (struct BRANDT_Auction *ad); | ||
186 | |||
187 | struct BRANDT_Result *mp_priv_determine_outcome (struct BRANDT_Auction *ad, | ||
188 | uint16_t *len); | ||
189 | |||
190 | |||
185 | /* --- Round dictionaries --- */ | 191 | /* --- Round dictionaries --- */ |
186 | 192 | ||
187 | typedef void | 193 | typedef void |
@@ -233,6 +239,8 @@ static const RoundPrep handler_prep[auction_last][outcome_last][msg_last] = { | |||
233 | [outcome_private] = { | 239 | [outcome_private] = { |
234 | [msg_init] = &smc_prep_keyshare, | 240 | [msg_init] = &smc_prep_keyshare, |
235 | [msg_bid] = &smc_prep_bid, | 241 | [msg_bid] = &smc_prep_bid, |
242 | [msg_outcome] = &mp_priv_prep_outcome, | ||
243 | [msg_decrypt] = &fp_priv_prep_decryption, | ||
236 | }, | 244 | }, |
237 | [outcome_public] = { | 245 | [outcome_public] = { |
238 | [msg_init] = &smc_prep_keyshare, | 246 | [msg_init] = &smc_prep_keyshare, |
@@ -271,6 +279,8 @@ static const MsgIn handler_in[auction_last][outcome_last][msg_last] = { | |||
271 | [outcome_private] = { | 279 | [outcome_private] = { |
272 | [msg_init] = &smc_recv_keyshare, | 280 | [msg_init] = &smc_recv_keyshare, |
273 | [msg_bid] = &smc_recv_encrypted_bid, | 281 | [msg_bid] = &smc_recv_encrypted_bid, |
282 | [msg_outcome] = &fp_priv_recv_outcome, | ||
283 | [msg_decrypt] = &fp_priv_recv_decryption, | ||
274 | }, | 284 | }, |
275 | [outcome_public] = { | 285 | [outcome_public] = { |
276 | [msg_init] = &smc_recv_keyshare, | 286 | [msg_init] = &smc_recv_keyshare, |
@@ -310,6 +320,8 @@ static const MsgOut handler_out[auction_last][outcome_last][msg_last] = { | |||
310 | [outcome_private] = { | 320 | [outcome_private] = { |
311 | [msg_init] = &smc_gen_keyshare, | 321 | [msg_init] = &smc_gen_keyshare, |
312 | [msg_bid] = &smc_encrypt_bid, | 322 | [msg_bid] = &smc_encrypt_bid, |
323 | [msg_outcome] = &fp_priv_compute_outcome, | ||
324 | [msg_decrypt] = &fp_priv_decrypt_outcome, | ||
313 | }, | 325 | }, |
314 | [outcome_public] = { | 326 | [outcome_public] = { |
315 | [msg_init] = &smc_gen_keyshare, | 327 | [msg_init] = &smc_gen_keyshare, |
@@ -330,14 +342,14 @@ static const MsgOut handler_out[auction_last][outcome_last][msg_last] = { | |||
330 | * of 0 means a private outcome, while a value of 1 means public outcome. | 342 | * of 0 means a private outcome, while a value of 1 means public outcome. |
331 | */ | 343 | */ |
332 | static const Result handler_res[auction_last][outcome_last] = { | 344 | static const Result handler_res[auction_last][outcome_last] = { |
333 | [auction_firstPrice] = { | 345 | [auction_firstPrice] = { |
334 | [outcome_private] = &fp_priv_determine_outcome, | 346 | [outcome_private] = &fp_priv_determine_outcome, |
335 | [outcome_public] = &fp_pub_determine_outcome, | 347 | [outcome_public] = &fp_pub_determine_outcome, |
336 | }, | 348 | }, |
337 | // [auction_mPlusFirstPrice] = { | 349 | [auction_mPlusFirstPrice] = { |
338 | // [outcome_private] = , | 350 | [outcome_private] = &mp_priv_determine_outcome, |
339 | // [outcome_public] = , | 351 | // [outcome_public] = , |
340 | // }, | 352 | }, |
341 | }; | 353 | }; |
342 | 354 | ||
343 | 355 | ||
diff --git a/mp_priv.c b/mp_priv.c new file mode 100644 index 0000000..0d45a06 --- /dev/null +++ b/mp_priv.c | |||
@@ -0,0 +1,216 @@ | |||
1 | /* This file is part of libbrandt. | ||
2 | * Copyright (C) 2016 GNUnet e.V. | ||
3 | * | ||
4 | * libbrandt is free software: you can redistribute it and/or modify it under | ||
5 | * the terms of the GNU General Public License as published by the Free Software | ||
6 | * Foundation, either version 3 of the License, or (at your option) any later | ||
7 | * version. | ||
8 | * | ||
9 | * libbrandt is distributed in the hope that it will be useful, but WITHOUT ANY | ||
10 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
11 | * A PARTICULAR PURPOSE. See the GNU General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License along with | ||
14 | * libbrandt. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | /** | ||
18 | * @file mp_priv.c | ||
19 | * @brief Implementation of the m+1st price private outcome algorithm. | ||
20 | * @author Markus Teich | ||
21 | */ | ||
22 | |||
23 | #include "platform.h" | ||
24 | |||
25 | #include <gcrypt.h> | ||
26 | |||
27 | #include "crypto.h" | ||
28 | #include "internals.h" | ||
29 | #include "util.h" | ||
30 | |||
31 | |||
32 | void | ||
33 | mp_priv_prep_outcome (struct BRANDT_Auction *ad) | ||
34 | { | ||
35 | gcry_mpi_t factor = gcry_mpi_new (256); | ||
36 | gcry_mpi_point_t subtr = gcry_mpi_point_new (0); | ||
37 | gcry_mpi_point_t tmpa = gcry_mpi_point_new (0); | ||
38 | gcry_mpi_point_t tmpb = gcry_mpi_point_new (0); | ||
39 | gcry_mpi_point_t *tlta1; | ||
40 | gcry_mpi_point_t *tltb1; | ||
41 | gcry_mpi_point_t **tlta2; | ||
42 | gcry_mpi_point_t **tltb2; | ||
43 | gcry_mpi_point_t **tlta3; | ||
44 | gcry_mpi_point_t **tltb3; | ||
45 | |||
46 | ad->gamma3 = smc_init3 (ad->n, ad->n, ad->k); | ||
47 | brandt_assert (ad->gamma3); | ||
48 | |||
49 | ad->delta3 = smc_init3 (ad->n, ad->n, ad->k); | ||
50 | brandt_assert (ad->delta3); | ||
51 | |||
52 | /* create temporary lookup tables with partial sums */ | ||
53 | tlta1 = smc_init1 (ad->k); | ||
54 | tltb1 = smc_init1 (ad->k); | ||
55 | tlta2 = smc_init2 (ad->n, ad->k); | ||
56 | tltb2 = smc_init2 (ad->n, ad->k); | ||
57 | tlta3 = smc_init2 (ad->n, ad->k); | ||
58 | tltb3 = smc_init2 (ad->n, ad->k); | ||
59 | |||
60 | /* temporary lookup table for first summand (building ladder of bids) */ | ||
61 | for (uint16_t i = 0; i < ad->n; i++) | ||
62 | { | ||
63 | smc_sums_partial (tlta3[i], ad->alpha[i], ad->k, 1, 1); | ||
64 | smc_sums_partial (tltb3[i], ad->beta[i], ad->k, 1, 1); | ||
65 | for (uint16_t j = 0; j < ad->k; j++) | ||
66 | { | ||
67 | gcry_mpi_ec_sub (tlta2[i][j], | ||
68 | tlta3[i][ad->k - 1], | ||
69 | tlta3[i][j], | ||
70 | ec_ctx); | ||
71 | gcry_mpi_ec_sub (tltb2[i][j], | ||
72 | tltb3[i][ad->k - 1], | ||
73 | tltb3[i][j], | ||
74 | ec_ctx); | ||
75 | } | ||
76 | brandt_assert (!ec_point_cmp (ec_zero, tlta2[i][ad->k - 1])); | ||
77 | brandt_assert (!ec_point_cmp (ec_zero, tltb2[i][ad->k - 1])); | ||
78 | } | ||
79 | for (uint16_t j = 0; j < ad->k; j++) | ||
80 | { | ||
81 | /* 2L - 2I */ | ||
82 | smc_sum (tmpa, &tlta2[0][j], ad->n, ad->k); | ||
83 | smc_sum (tmpb, &tltb2[0][j], ad->n, ad->k); | ||
84 | gcry_mpi_ec_mul (tlta1[j], GCRYMPI_CONST_TWO, tmpa, ec_ctx); | ||
85 | gcry_mpi_ec_mul (tltb1[j], GCRYMPI_CONST_TWO, tmpb, ec_ctx); | ||
86 | |||
87 | /* I */ | ||
88 | smc_sum (tmpa, &ad->alpha[0][j], ad->n, ad->k); | ||
89 | smc_sum (tmpb, &ad->beta[0][j], ad->n, ad->k); | ||
90 | |||
91 | /* 2L - 2I + I = 2L - I */ | ||
92 | gcry_mpi_ec_add (tlta1[j], tlta1[j], tmpa, ec_ctx); | ||
93 | gcry_mpi_ec_add (tltb1[j], tltb1[j], tmpb, ec_ctx); | ||
94 | } | ||
95 | /* This check only works directly after the loop when tmpa/tmpb are still | ||
96 | * the sum of the last row */ | ||
97 | brandt_assert (!ec_point_cmp (tmpa, tlta1[ad->k - 1])); | ||
98 | brandt_assert (!ec_point_cmp (tmpb, tltb1[ad->k - 1])); | ||
99 | |||
100 | /* temporary lookup table for second summand (hide outcome from losers) */ | ||
101 | gcry_mpi_set_ui (factor, ad->m); | ||
102 | gcry_mpi_lshift (factor, factor, 1); | ||
103 | gcry_mpi_add_ui (factor, factor, 2); | ||
104 | for (uint16_t i = 0; i < ad->n; i++) | ||
105 | { | ||
106 | for (uint16_t j = 0; j < ad->k; j++) | ||
107 | { | ||
108 | gcry_mpi_ec_mul (tlta2[i][j], factor, tlta3[i][j], ec_ctx); | ||
109 | gcry_mpi_ec_mul (tltb2[i][j], factor, tltb3[i][j], ec_ctx); | ||
110 | } | ||
111 | } | ||
112 | |||
113 | /* temporary lookup table for subtrahend (getting M+1st highest bid) */ | ||
114 | gcry_mpi_sub_ui (factor, factor, 1); | ||
115 | gcry_mpi_ec_mul (subtr, factor, ec_gen, ec_ctx); | ||
116 | |||
117 | /* compute gamma and delta */ | ||
118 | for (uint16_t i = 0; i < ad->n; i++) | ||
119 | { | ||
120 | for (uint16_t j = 0; j < ad->k; j++) | ||
121 | { | ||
122 | /* compute inner gamma */ | ||
123 | gcry_mpi_ec_add (tmpa, tlta1[j], tlta2[i][j], ec_ctx); | ||
124 | gcry_mpi_ec_sub (tmpa, tmpa, subtr, ec_ctx); | ||
125 | |||
126 | /* compute inner delta */ | ||
127 | gcry_mpi_ec_add (tmpb, tltb1[j], tltb2[i][j], ec_ctx); | ||
128 | |||
129 | /* copy unmasked outcome to all other bidder layers so they don't | ||
130 | * have to be recomputed to check the ZK proof_2dle's from other | ||
131 | * bidders when receiving their outcome messages */ | ||
132 | for (uint16_t a = 0; a < ad->n; a++) | ||
133 | { | ||
134 | ec_point_copy (ad->gamma3[a][i][j], tmpa); | ||
135 | ec_point_copy (ad->delta3[a][i][j], tmpb); | ||
136 | } | ||
137 | } | ||
138 | } | ||
139 | |||
140 | gcry_mpi_release (factor); | ||
141 | gcry_mpi_point_release (subtr); | ||
142 | gcry_mpi_point_release (tmpa); | ||
143 | gcry_mpi_point_release (tmpb); | ||
144 | smc_free1 (tlta1, ad->k); | ||
145 | smc_free1 (tltb1, ad->k); | ||
146 | smc_free2 (tlta2, ad->n, ad->k); | ||
147 | smc_free2 (tltb2, ad->n, ad->k); | ||
148 | smc_free2 (tlta3, ad->n, ad->k); | ||
149 | smc_free2 (tltb3, ad->n, ad->k); | ||
150 | } | ||
151 | |||
152 | |||
153 | struct BRANDT_Result * | ||
154 | mp_priv_determine_outcome (struct BRANDT_Auction *ad, | ||
155 | uint16_t *len) | ||
156 | { | ||
157 | struct BRANDT_Result *ret; | ||
158 | int32_t price = -1; | ||
159 | uint16_t winners = 0; | ||
160 | uint16_t max_winners; | ||
161 | gcry_mpi_point_t sum_gamma = gcry_mpi_point_new (0); | ||
162 | gcry_mpi_point_t sum_phi = gcry_mpi_point_new (0); | ||
163 | |||
164 | brandt_assert (ad); | ||
165 | |||
166 | max_winners = ad->seller_mode ? ad->m : 1; | ||
167 | ret = GNUNET_new_array (max_winners, struct BRANDT_Result); | ||
168 | for (uint16_t i = 0; i < ad->n; i++) | ||
169 | { | ||
170 | if (!ad->seller_mode && i != ad->i) | ||
171 | continue; | ||
172 | |||
173 | for (uint16_t j = 0; j < ad->k; j++) | ||
174 | { | ||
175 | smc_sum (sum_gamma, &ad->gamma3[0][i][j], ad->n, ad->n * ad->k); | ||
176 | smc_sum (sum_phi, &ad->phi3[0][i][j], ad->n, ad->n * ad->k); | ||
177 | gcry_mpi_ec_sub (sum_gamma, sum_gamma, sum_phi, ec_ctx); | ||
178 | if (!ec_point_cmp (sum_gamma, ec_zero)) | ||
179 | { | ||
180 | weprintf ("lol"); | ||
181 | if (winners >= max_winners) | ||
182 | { | ||
183 | weprintf ("too many winners detected"); | ||
184 | goto fail; | ||
185 | } | ||
186 | if (-1 != price && j != price) | ||
187 | { | ||
188 | weprintf ("multiple winning prices detected"); | ||
189 | goto fail; | ||
190 | } | ||
191 | price = j; | ||
192 | |||
193 | ret[winners].bidder = i; | ||
194 | ret[winners].price = j / ad->n; | ||
195 | ret[winners].status = BRANDT_bidder_won; | ||
196 | winners++; | ||
197 | } | ||
198 | } | ||
199 | } | ||
200 | |||
201 | gcry_mpi_point_release (sum_gamma); | ||
202 | gcry_mpi_point_release (sum_phi); | ||
203 | |||
204 | if (ad->m <= ad->n && winners < max_winners && -1 != price) | ||
205 | weprintf ("too few winners detected"); | ||
206 | if (0 == winners) | ||
207 | goto fail; | ||
208 | |||
209 | if (len) | ||
210 | *len = winners; | ||
211 | return ret; | ||
212 | |||
213 | fail: | ||
214 | GNUNET_free (ret); | ||
215 | return NULL; | ||
216 | } | ||