aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarkus Teich <markus.teich@stusta.mhn.de>2016-10-15 20:33:21 +0200
committerMarkus Teich <markus.teich@stusta.mhn.de>2016-10-15 20:33:21 +0200
commit5ce71329cfa5540aa8bb7091df292fc133bcf8fa (patch)
treeab79ad8748a00a93c15485386b973227b72b9287
parent5d028cc81ef0635a9dbf57584a1ac0dd3bb3cfb2 (diff)
downloadlibbrandt-5ce71329cfa5540aa8bb7091df292fc133bcf8fa.tar.gz
libbrandt-5ce71329cfa5540aa8bb7091df292fc133bcf8fa.zip
add M+1st price private outcome implementation
-rw-r--r--Makefile.am1
-rw-r--r--crypto.h22
-rw-r--r--mp_priv.c216
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
14libbrandt_la_LIBADD = \ 15libbrandt_la_LIBADD = \
diff --git a/crypto.h b/crypto.h
index b4344da..35e98a6 100644
--- a/crypto.h
+++ b/crypto.h
@@ -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
185void mp_priv_prep_outcome (struct BRANDT_Auction *ad);
186
187struct BRANDT_Result *mp_priv_determine_outcome (struct BRANDT_Auction *ad,
188 uint16_t *len);
189
190
185/* --- Round dictionaries --- */ 191/* --- Round dictionaries --- */
186 192
187typedef void 193typedef 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 */
332static const Result handler_res[auction_last][outcome_last] = { 344static 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
32void
33mp_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
153struct BRANDT_Result *
154mp_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
213fail:
214 GNUNET_free (ret);
215 return NULL;
216}