aboutsummaryrefslogtreecommitdiff
path: root/fp_pub.c
diff options
context:
space:
mode:
authorMarkus Teich <markus.teich@stusta.mhn.de>2016-09-29 18:22:21 +0200
committerMarkus Teich <markus.teich@stusta.mhn.de>2016-09-29 18:22:21 +0200
commit8ea21d9732c1615961006e16d05330fd5d955006 (patch)
treeed33d63e0d72874d3955bbe70d0f63e5807b93bf /fp_pub.c
parent656aa465530452eed934bc430b5ecbaa72a90a10 (diff)
downloadlibbrandt-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.c438
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
32void
33fp_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 */
139unsigned char *
140fp_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
203int
204fp_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;
254quit:
255 gcry_mpi_point_release (gamma);
256 gcry_mpi_point_release (delta);
257 return ret;
258}
259
260
261void
262fp_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 */
293unsigned char *
294fp_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
338int
339fp_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;
375quit:
376 gcry_mpi_point_release (phi);
377 return ret;
378}
379
380
381struct BRANDT_Result *
382fp_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}