diff options
author | Markus Teich <markus.teich@stusta.mhn.de> | 2016-09-29 18:22:21 +0200 |
---|---|---|
committer | Markus Teich <markus.teich@stusta.mhn.de> | 2016-09-29 18:22:21 +0200 |
commit | 8ea21d9732c1615961006e16d05330fd5d955006 (patch) | |
tree | ed33d63e0d72874d3955bbe70d0f63e5807b93bf /fp_pub.c | |
parent | 656aa465530452eed934bc430b5ecbaa72a90a10 (diff) | |
download | libbrandt-8ea21d9732c1615961006e16d05330fd5d955006.tar.gz libbrandt-8ea21d9732c1615961006e16d05330fd5d955006.zip |
split different auction format algorithms into separate files
Diffstat (limited to 'fp_pub.c')
-rw-r--r-- | fp_pub.c | 438 |
1 files changed, 438 insertions, 0 deletions
diff --git a/fp_pub.c b/fp_pub.c new file mode 100644 index 0000000..eb0cfe1 --- /dev/null +++ b/fp_pub.c | |||
@@ -0,0 +1,438 @@ | |||
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 fp_pub.c | ||
19 | * @brief Implementation of the first price public 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 | fp_pub_prep_outcome (struct BRANDT_Auction *ad) | ||
34 | { | ||
35 | gcry_mpi_t coeff = gcry_mpi_copy (GCRYMPI_CONST_ONE); | ||
36 | gcry_mpi_point_t tmp = gcry_mpi_point_new (0); | ||
37 | gcry_mpi_point_t *tlta1; | ||
38 | gcry_mpi_point_t *tltb1; | ||
39 | gcry_mpi_point_t **tlta2; | ||
40 | gcry_mpi_point_t **tltb2; | ||
41 | |||
42 | ad->gamma2 = smc_init2 (ad->n, ad->k); | ||
43 | brandt_assert (ad->gamma2); | ||
44 | |||
45 | ad->delta2 = smc_init2 (ad->n, ad->k); | ||
46 | brandt_assert (ad->delta2); | ||
47 | |||
48 | ad->tmpa1 = smc_init1 (ad->k); | ||
49 | brandt_assert (ad->tmpa1); | ||
50 | |||
51 | ad->tmpb1 = smc_init1 (ad->k); | ||
52 | brandt_assert (ad->tmpb1); | ||
53 | |||
54 | /* create temporary lookup tables with partial sums */ | ||
55 | tlta1 = smc_init1 (ad->k); | ||
56 | tltb1 = smc_init1 (ad->k); | ||
57 | tlta2 = smc_init2 (ad->n, ad->k); | ||
58 | tltb2 = smc_init2 (ad->n, ad->k); | ||
59 | |||
60 | /* temporary lookup table for sum of bid vectors */ | ||
61 | for (uint16_t i = 0; i < ad->n; i++) | ||
62 | { | ||
63 | smc_sums_partial (tlta2[i], ad->alpha[i], ad->k, 1, 1); | ||
64 | smc_sums_partial (tltb2[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 | tlta2[i][ad->k - 1], | ||
69 | tlta2[i][j], | ||
70 | ec_ctx); | ||
71 | gcry_mpi_ec_sub (tltb2[i][j], | ||
72 | tltb2[i][ad->k - 1], | ||
73 | tltb2[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 | smc_sum (tlta1[j], &tlta2[0][j], ad->n, ad->k); | ||
82 | smc_sum (tltb1[j], &tltb2[0][j], ad->n, ad->k); | ||
83 | } | ||
84 | smc_free2 (tlta2, ad->n, ad->k); | ||
85 | smc_free2 (tltb2, ad->n, ad->k); | ||
86 | brandt_assert (!ec_point_cmp (ec_zero, tlta1[ad->k - 1])); | ||
87 | brandt_assert (!ec_point_cmp (ec_zero, tltb1[ad->k - 1])); | ||
88 | |||
89 | /* initialize tmp array with zeroes, since we are calculating a sum */ | ||
90 | for (uint16_t j = 0; j < ad->k; j++) | ||
91 | { | ||
92 | ec_point_copy (ad->tmpa1[j], ec_zero); | ||
93 | ec_point_copy (ad->tmpb1[j], ec_zero); | ||
94 | } | ||
95 | /* store the \sum_{i=1}^n2^{i-1}b_i in tmp1 until outcome determination, | ||
96 | * since it is needed each time a gamma,delta pair is received from another | ||
97 | * bidder */ | ||
98 | for (uint16_t i = 0; i < ad->n; i++) | ||
99 | { | ||
100 | for (uint16_t j = 0; j < ad->k; j++) | ||
101 | { | ||
102 | gcry_mpi_ec_mul (tmp, coeff, ad->alpha[i][j], ec_ctx); | ||
103 | gcry_mpi_ec_add (ad->tmpa1[j], ad->tmpa1[j], tmp, ec_ctx); | ||
104 | gcry_mpi_ec_mul (tmp, coeff, ad->beta[i][j], ec_ctx); | ||
105 | gcry_mpi_ec_add (ad->tmpb1[j], ad->tmpb1[j], tmp, ec_ctx); | ||
106 | } | ||
107 | gcry_mpi_lshift (coeff, coeff, 1); | ||
108 | } | ||
109 | |||
110 | for (uint16_t j = 0; j < ad->k; j++) | ||
111 | { | ||
112 | /* copy unmasked outcome to all other bidder layers so they don't | ||
113 | * have to be recomputed to check the ZK proof_2dle's from other | ||
114 | * bidders when receiving their outcome messages */ | ||
115 | for (uint16_t a = 0; a < ad->n; a++) | ||
116 | { | ||
117 | ec_point_copy (ad->gamma2[a][j], tlta1[j]); | ||
118 | ec_point_copy (ad->delta2[a][j], tltb1[j]); | ||
119 | } | ||
120 | } | ||
121 | |||
122 | gcry_mpi_release (coeff); | ||
123 | gcry_mpi_point_release (tmp); | ||
124 | smc_free1 (tlta1, ad->k); | ||
125 | smc_free1 (tltb1, ad->k); | ||
126 | } | ||
127 | |||
128 | |||
129 | /** | ||
130 | * fp_pub_compute_outcome computes the outcome for first price auctions with a | ||
131 | * public outcome and packs it into a message buffer together with proofs of | ||
132 | * correctnes. | ||
133 | * | ||
134 | * @param[in] ad Pointer to the BRANDT_Auction struct to operate on | ||
135 | * @param[out] buflen Size of the returned message buffer in bytes | ||
136 | * @return A buffer containing the encrypted outcome vectors | ||
137 | * which needs to be broadcast | ||
138 | */ | ||
139 | unsigned char * | ||
140 | fp_pub_compute_outcome (struct BRANDT_Auction *ad, size_t *buflen) | ||
141 | { | ||
142 | unsigned char *ret; | ||
143 | unsigned char *cur; | ||
144 | gcry_mpi_point_t tmpa = gcry_mpi_point_new (0); | ||
145 | gcry_mpi_point_t tmpb = gcry_mpi_point_new (0); | ||
146 | struct msg_head *head; | ||
147 | struct ec_mpi *gamma; | ||
148 | struct ec_mpi *delta; | ||
149 | struct proof_2dle *proof2; | ||
150 | |||
151 | brandt_assert (ad && buflen); | ||
152 | |||
153 | *buflen = (sizeof (*head) + | ||
154 | ad->k * (sizeof (*gamma) + | ||
155 | sizeof (*delta) + | ||
156 | sizeof (*proof2))); | ||
157 | ret = GNUNET_new_array (*buflen, unsigned char); | ||
158 | |||
159 | head = (struct msg_head *)ret; | ||
160 | head->prot_version = htonl (0); | ||
161 | head->msg_type = htonl (msg_outcome); | ||
162 | cur = ret + sizeof (*head); | ||
163 | |||
164 | for (uint16_t j = 0; j < ad->k; j++) | ||
165 | { | ||
166 | gamma = (struct ec_mpi *)cur; | ||
167 | delta = &((struct ec_mpi *)cur)[1]; | ||
168 | proof2 = (struct proof_2dle *)(cur + 2 * sizeof (struct ec_mpi)); | ||
169 | |||
170 | ec_point_copy (tmpa, ad->gamma2[ad->i][j]); | ||
171 | ec_point_copy (tmpb, ad->delta2[ad->i][j]); | ||
172 | |||
173 | /* apply random masking for losing bidders */ | ||
174 | smc_zkp_2dle (ad->gamma2[ad->i][j], | ||
175 | ad->delta2[ad->i][j], | ||
176 | tmpa, | ||
177 | tmpb, | ||
178 | NULL, | ||
179 | proof2); | ||
180 | |||
181 | ec_point_serialize (gamma, ad->gamma2[ad->i][j]); | ||
182 | ec_point_serialize (delta, ad->delta2[ad->i][j]); | ||
183 | |||
184 | /* add winner determination for own gamma,delta */ | ||
185 | gcry_mpi_ec_add (ad->gamma2[ad->i][j], | ||
186 | ad->gamma2[ad->i][j], | ||
187 | ad->tmpa1[j], | ||
188 | ec_ctx); | ||
189 | gcry_mpi_ec_add (ad->delta2[ad->i][j], | ||
190 | ad->delta2[ad->i][j], | ||
191 | ad->tmpb1[j], | ||
192 | ec_ctx); | ||
193 | |||
194 | cur += sizeof (*gamma) + sizeof (*delta) + sizeof (*proof2); | ||
195 | } | ||
196 | |||
197 | gcry_mpi_point_release (tmpa); | ||
198 | gcry_mpi_point_release (tmpb); | ||
199 | return ret; | ||
200 | } | ||
201 | |||
202 | |||
203 | int | ||
204 | fp_pub_recv_outcome (struct BRANDT_Auction *ad, | ||
205 | const unsigned char *buf, | ||
206 | size_t buflen, | ||
207 | uint16_t sender) | ||
208 | { | ||
209 | int ret = 0; | ||
210 | const unsigned char *cur = buf; | ||
211 | struct proof_2dle *proof2; | ||
212 | gcry_mpi_point_t gamma = gcry_mpi_point_new (0); | ||
213 | gcry_mpi_point_t delta = gcry_mpi_point_new (0); | ||
214 | |||
215 | brandt_assert (ad && buf); | ||
216 | |||
217 | if (buflen != (ad->k * (2 * sizeof (struct ec_mpi) + sizeof (*proof2)))) | ||
218 | { | ||
219 | weprintf ("wrong size of received outcome"); | ||
220 | goto quit; | ||
221 | } | ||
222 | |||
223 | for (uint16_t j = 0; j < ad->k; j++) | ||
224 | { | ||
225 | ec_point_parse (gamma, (struct ec_mpi *)cur); | ||
226 | ec_point_parse (delta, &((struct ec_mpi *)cur)[1]); | ||
227 | proof2 = (struct proof_2dle *)(cur + 2 * sizeof (struct ec_mpi)); | ||
228 | if (smc_zkp_2dle_check (gamma, | ||
229 | delta, | ||
230 | ad->gamma2[sender][j], | ||
231 | ad->delta2[sender][j], | ||
232 | proof2)) | ||
233 | { | ||
234 | weprintf ("wrong zkp2 for gamma, delta received"); | ||
235 | goto quit; | ||
236 | } | ||
237 | ec_point_copy (ad->gamma2[sender][j], gamma); | ||
238 | ec_point_copy (ad->delta2[sender][j], delta); | ||
239 | |||
240 | /* add winner determination summand */ | ||
241 | gcry_mpi_ec_add (ad->gamma2[sender][j], | ||
242 | ad->gamma2[sender][j], | ||
243 | ad->tmpa1[j], | ||
244 | ec_ctx); | ||
245 | gcry_mpi_ec_add (ad->delta2[sender][j], | ||
246 | ad->delta2[sender][j], | ||
247 | ad->tmpb1[j], | ||
248 | ec_ctx); | ||
249 | |||
250 | cur += 2 * sizeof (struct ec_mpi) + sizeof (*proof2); | ||
251 | } | ||
252 | |||
253 | ret = 1; | ||
254 | quit: | ||
255 | gcry_mpi_point_release (gamma); | ||
256 | gcry_mpi_point_release (delta); | ||
257 | return ret; | ||
258 | } | ||
259 | |||
260 | |||
261 | void | ||
262 | fp_pub_prep_decryption (struct BRANDT_Auction *ad) | ||
263 | { | ||
264 | gcry_mpi_point_t tmp = gcry_mpi_point_new (0); | ||
265 | |||
266 | ad->phi2 = smc_init2 (ad->n, ad->k); | ||
267 | brandt_assert (ad->phi2); | ||
268 | |||
269 | for (uint16_t j = 0; j < ad->k; j++) | ||
270 | { | ||
271 | smc_sum (tmp, &ad->delta2[0][j], ad->n, ad->k); | ||
272 | |||
273 | /* copy still encrypted outcome to all other bidder layers so they | ||
274 | * don't have to be recomputed to check the ZK proof_2dle's from | ||
275 | * other bidders when receiving their outcome decryption messages */ | ||
276 | for (uint16_t a = 0; a < ad->n; a++) | ||
277 | ec_point_copy (ad->phi2[a][j], tmp); | ||
278 | } | ||
279 | |||
280 | gcry_mpi_point_release (tmp); | ||
281 | } | ||
282 | |||
283 | |||
284 | /** | ||
285 | * fp_pub_decrypt_outcome decrypts part of the outcome and packs it into a | ||
286 | * message buffer together with proofs of correctnes. | ||
287 | * | ||
288 | * @param[in] ad Pointer to the BRANDT_Auction struct to operate on | ||
289 | * @param[out] buflen Size of the returned message buffer in bytes | ||
290 | * @return A buffer containing the own share of the decrypted outcome | ||
291 | * which needs to be broadcast | ||
292 | */ | ||
293 | unsigned char * | ||
294 | fp_pub_decrypt_outcome (struct BRANDT_Auction *ad, size_t *buflen) | ||
295 | { | ||
296 | unsigned char *ret; | ||
297 | unsigned char *cur; | ||
298 | gcry_mpi_point_t tmp = gcry_mpi_point_new (0); | ||
299 | struct msg_head *head; | ||
300 | struct ec_mpi *phi; | ||
301 | struct proof_2dle *proof2; | ||
302 | |||
303 | brandt_assert (ad && buflen); | ||
304 | |||
305 | *buflen = (sizeof (*head) + ad->k * (sizeof (*phi) + sizeof (*proof2))); | ||
306 | ret = GNUNET_new_array (*buflen, unsigned char); | ||
307 | |||
308 | head = (struct msg_head *)ret; | ||
309 | head->prot_version = htonl (0); | ||
310 | head->msg_type = htonl (msg_decrypt); | ||
311 | cur = ret + sizeof (*head); | ||
312 | |||
313 | for (uint16_t j = 0; j < ad->k; j++) | ||
314 | { | ||
315 | phi = (struct ec_mpi *)cur; | ||
316 | proof2 = (struct proof_2dle *)(cur + sizeof (*phi)); | ||
317 | |||
318 | ec_point_copy (tmp, ad->phi2[ad->i][j]); | ||
319 | |||
320 | /* decrypt outcome component and prove the correct key was used */ | ||
321 | smc_zkp_2dle (ad->phi2[ad->i][j], | ||
322 | NULL, | ||
323 | tmp, | ||
324 | ec_gen, | ||
325 | ad->x, | ||
326 | proof2); | ||
327 | |||
328 | ec_point_serialize (phi, ad->phi2[ad->i][j]); | ||
329 | |||
330 | cur += sizeof (*phi) + sizeof (*proof2); | ||
331 | } | ||
332 | |||
333 | gcry_mpi_point_release (tmp); | ||
334 | return ret; | ||
335 | } | ||
336 | |||
337 | |||
338 | int | ||
339 | fp_pub_recv_decryption (struct BRANDT_Auction *ad, | ||
340 | const unsigned char *buf, | ||
341 | size_t buflen, | ||
342 | uint16_t sender) | ||
343 | { | ||
344 | int ret = 0; | ||
345 | const unsigned char *cur = buf; | ||
346 | struct proof_2dle *proof2; | ||
347 | gcry_mpi_point_t phi = gcry_mpi_point_new (0); | ||
348 | |||
349 | brandt_assert (ad && buf); | ||
350 | |||
351 | if (buflen != (ad->k * (sizeof (struct ec_mpi) + sizeof (*proof2)))) | ||
352 | { | ||
353 | weprintf ("wrong size of received outcome decryption"); | ||
354 | goto quit; | ||
355 | } | ||
356 | |||
357 | for (uint16_t j = 0; j < ad->k; j++) | ||
358 | { | ||
359 | ec_point_parse (phi, (struct ec_mpi *)cur); | ||
360 | proof2 = (struct proof_2dle *)(cur + sizeof (struct ec_mpi)); | ||
361 | if (smc_zkp_2dle_check (phi, | ||
362 | ad->y[sender], | ||
363 | ad->phi2[sender][j], | ||
364 | ec_gen, | ||
365 | proof2)) | ||
366 | { | ||
367 | weprintf ("wrong zkp2 for phi, y received"); | ||
368 | goto quit; | ||
369 | } | ||
370 | ec_point_copy (ad->phi2[sender][j], phi); | ||
371 | cur += sizeof (struct ec_mpi) + sizeof (*proof2); | ||
372 | } | ||
373 | |||
374 | ret = 1; | ||
375 | quit: | ||
376 | gcry_mpi_point_release (phi); | ||
377 | return ret; | ||
378 | } | ||
379 | |||
380 | |||
381 | struct BRANDT_Result * | ||
382 | fp_pub_determine_outcome (struct BRANDT_Auction *ad, | ||
383 | uint16_t *len) | ||
384 | { | ||
385 | struct BRANDT_Result *ret; | ||
386 | int32_t price = -1; | ||
387 | int32_t winner = -1; | ||
388 | int dlogi = -1; | ||
389 | gcry_mpi_point_t sum_gamma = gcry_mpi_point_new (0); | ||
390 | gcry_mpi_point_t sum_phi = gcry_mpi_point_new (0); | ||
391 | |||
392 | brandt_assert (ad); | ||
393 | |||
394 | for (uint16_t j = ad->k - 1; j >= 0; j--) | ||
395 | { | ||
396 | smc_sum (sum_gamma, &ad->gamma2[0][j], ad->n, ad->k); | ||
397 | smc_sum (sum_phi, &ad->phi2[0][j], ad->n, ad->k); | ||
398 | gcry_mpi_ec_sub (sum_gamma, sum_gamma, sum_phi, ec_ctx); | ||
399 | /* first non-zero component determines the price */ | ||
400 | if (ec_point_cmp (sum_gamma, ec_zero)) | ||
401 | { | ||
402 | price = j; | ||
403 | break; | ||
404 | } | ||
405 | } | ||
406 | |||
407 | dlogi = GNUNET_CRYPTO_ecc_dlog (ec_dlogctx, sum_gamma); | ||
408 | brandt_assert (dlogi > 0); | ||
409 | |||
410 | /* all bidders participated with a multiplicative share */ | ||
411 | dlogi /= ad->n; | ||
412 | |||
413 | /* can only support up to bits(dlogi) bidders */ | ||
414 | brandt_assert (sizeof (int) * 8 - 1 >= ad->n); | ||
415 | for (uint16_t i = 0; i < ad->n; i++) | ||
416 | { | ||
417 | /* first set bit determines the winner */ | ||
418 | if (dlogi & (1 << i)) | ||
419 | { | ||
420 | winner = i; | ||
421 | break; | ||
422 | } | ||
423 | } | ||
424 | |||
425 | gcry_mpi_point_release (sum_gamma); | ||
426 | gcry_mpi_point_release (sum_phi); | ||
427 | |||
428 | if (-1 == winner || -1 == price) | ||
429 | return NULL; | ||
430 | |||
431 | ret = GNUNET_new (struct BRANDT_Result); | ||
432 | ret->bidder = winner; | ||
433 | ret->price = price; | ||
434 | ret->status = BRANDT_bidder_won; | ||
435 | if (len) | ||
436 | *len = 1; | ||
437 | return ret; | ||
438 | } | ||