aboutsummaryrefslogtreecommitdiff
path: root/crypto.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 /crypto.c
parent656aa465530452eed934bc430b5ecbaa72a90a10 (diff)
downloadlibbrandt-8ea21d9732c1615961006e16d05330fd5d955006.tar.gz
libbrandt-8ea21d9732c1615961006e16d05330fd5d955006.zip
split different auction format algorithms into separate files
Diffstat (limited to 'crypto.c')
-rw-r--r--crypto.c978
1 files changed, 7 insertions, 971 deletions
diff --git a/crypto.c b/crypto.c
index b9f55db..3b5205a 100644
--- a/crypto.c
+++ b/crypto.c
@@ -58,11 +58,11 @@ struct zkp_challenge_0og {
58}; 58};
59 59
60 60
61static gcry_ctx_t ec_ctx; 61gcry_ctx_t ec_ctx = NULL;
62static gcry_mpi_point_t ec_gen; 62gcry_mpi_point_t ec_gen = NULL;
63static gcry_mpi_point_t ec_zero; 63gcry_mpi_point_t ec_zero = NULL;
64static gcry_mpi_t ec_n; 64gcry_mpi_t ec_n = NULL;
65static struct GNUNET_CRYPTO_EccDlogContext *ec_dlogctx; 65struct GNUNET_CRYPTO_EccDlogContext *ec_dlogctx = NULL;
66 66
67 67
68/** 68/**
@@ -553,7 +553,7 @@ smc_init3 (uint16_t size1, uint16_t size2, uint16_t size3)
553 * @param[in] stepo The amount of items to advance in @a out each step. Can be 553 * @param[in] stepo The amount of items to advance in @a out each step. Can be
554 * used to store the sum in multi-dimensional arrays. 554 * used to store the sum in multi-dimensional arrays.
555 */ 555 */
556static void 556void
557smc_sums_partial (gcry_mpi_point_t out[], 557smc_sums_partial (gcry_mpi_point_t out[],
558 gcry_mpi_point_t in[], 558 gcry_mpi_point_t in[],
559 uint16_t len, 559 uint16_t len,
@@ -577,7 +577,7 @@ smc_sums_partial (gcry_mpi_point_t out[],
577 * @param[in] step The amount of items to advance in @a in each step. Can be 577 * @param[in] step The amount of items to advance in @a in each step. Can be
578 * used to sum over multi-dimensional arrays. 578 * used to sum over multi-dimensional arrays.
579 */ 579 */
580static void 580void
581smc_sum (gcry_mpi_point_t out, 581smc_sum (gcry_mpi_point_t out,
582 gcry_mpi_point_t in[], 582 gcry_mpi_point_t in[],
583 uint16_t len, 583 uint16_t len,
@@ -813,970 +813,6 @@ quit:
813} 813}
814 814
815 815
816void
817fp_pub_prep_outcome (struct BRANDT_Auction *ad)
818{
819 gcry_mpi_t coeff = gcry_mpi_copy (GCRYMPI_CONST_ONE);
820 gcry_mpi_point_t tmp = gcry_mpi_point_new (0);
821 gcry_mpi_point_t *tlta1;
822 gcry_mpi_point_t *tltb1;
823 gcry_mpi_point_t **tlta2;
824 gcry_mpi_point_t **tltb2;
825
826 ad->gamma2 = smc_init2 (ad->n, ad->k);
827 brandt_assert (ad->gamma2);
828
829 ad->delta2 = smc_init2 (ad->n, ad->k);
830 brandt_assert (ad->delta2);
831
832 ad->tmpa1 = smc_init1 (ad->k);
833 brandt_assert (ad->tmpa1);
834
835 ad->tmpb1 = smc_init1 (ad->k);
836 brandt_assert (ad->tmpb1);
837
838 /* create temporary lookup tables with partial sums */
839 tlta1 = smc_init1 (ad->k);
840 tltb1 = smc_init1 (ad->k);
841 tlta2 = smc_init2 (ad->n, ad->k);
842 tltb2 = smc_init2 (ad->n, ad->k);
843
844 /* temporary lookup table for sum of bid vectors */
845 for (uint16_t i = 0; i < ad->n; i++)
846 {
847 smc_sums_partial (tlta2[i], ad->alpha[i], ad->k, 1, 1);
848 smc_sums_partial (tltb2[i], ad->beta[i], ad->k, 1, 1);
849 for (uint16_t j = 0; j < ad->k; j++)
850 {
851 gcry_mpi_ec_sub (tlta2[i][j],
852 tlta2[i][ad->k - 1],
853 tlta2[i][j],
854 ec_ctx);
855 gcry_mpi_ec_sub (tltb2[i][j],
856 tltb2[i][ad->k - 1],
857 tltb2[i][j],
858 ec_ctx);
859 }
860 brandt_assert (!ec_point_cmp (ec_zero, tlta2[i][ad->k - 1]));
861 brandt_assert (!ec_point_cmp (ec_zero, tltb2[i][ad->k - 1]));
862 }
863 for (uint16_t j = 0; j < ad->k; j++)
864 {
865 smc_sum (tlta1[j], &tlta2[0][j], ad->n, ad->k);
866 smc_sum (tltb1[j], &tltb2[0][j], ad->n, ad->k);
867 }
868 smc_free2 (tlta2, ad->n, ad->k);
869 smc_free2 (tltb2, ad->n, ad->k);
870 brandt_assert (!ec_point_cmp (ec_zero, tlta1[ad->k - 1]));
871 brandt_assert (!ec_point_cmp (ec_zero, tltb1[ad->k - 1]));
872
873 /* initialize tmp array with zeroes, since we are calculating a sum */
874 for (uint16_t j = 0; j < ad->k; j++)
875 {
876 ec_point_copy (ad->tmpa1[j], ec_zero);
877 ec_point_copy (ad->tmpb1[j], ec_zero);
878 }
879 /* store the \sum_{i=1}^n2^{i-1}b_i in tmp1 until outcome determination,
880 * since it is needed each time a gamma,delta pair is received from another
881 * bidder */
882 for (uint16_t i = 0; i < ad->n; i++)
883 {
884 for (uint16_t j = 0; j < ad->k; j++)
885 {
886 gcry_mpi_ec_mul (tmp, coeff, ad->alpha[i][j], ec_ctx);
887 gcry_mpi_ec_add (ad->tmpa1[j], ad->tmpa1[j], tmp, ec_ctx);
888 gcry_mpi_ec_mul (tmp, coeff, ad->beta[i][j], ec_ctx);
889 gcry_mpi_ec_add (ad->tmpb1[j], ad->tmpb1[j], tmp, ec_ctx);
890 }
891 gcry_mpi_lshift (coeff, coeff, 1);
892 }
893
894 for (uint16_t j = 0; j < ad->k; j++)
895 {
896 /* copy unmasked outcome to all other bidder layers so they don't
897 * have to be recomputed to check the ZK proof_2dle's from other
898 * bidders when receiving their outcome messages */
899 for (uint16_t a = 0; a < ad->n; a++)
900 {
901 ec_point_copy (ad->gamma2[a][j], tlta1[j]);
902 ec_point_copy (ad->delta2[a][j], tltb1[j]);
903 }
904 }
905
906 gcry_mpi_release (coeff);
907 gcry_mpi_point_release (tmp);
908 smc_free1 (tlta1, ad->k);
909 smc_free1 (tltb1, ad->k);
910}
911
912
913/**
914 * fp_pub_compute_outcome computes the outcome for first price auctions with a
915 * public outcome and packs it into a message buffer together with proofs of
916 * correctnes.
917 *
918 * @param[in] ad Pointer to the BRANDT_Auction struct to operate on
919 * @param[out] buflen Size of the returned message buffer in bytes
920 * @return A buffer containing the encrypted outcome vectors
921 * which needs to be broadcast
922 */
923unsigned char *
924fp_pub_compute_outcome (struct BRANDT_Auction *ad, size_t *buflen)
925{
926 unsigned char *ret;
927 unsigned char *cur;
928 gcry_mpi_point_t tmpa = gcry_mpi_point_new (0);
929 gcry_mpi_point_t tmpb = gcry_mpi_point_new (0);
930 struct msg_head *head;
931 struct ec_mpi *gamma;
932 struct ec_mpi *delta;
933 struct proof_2dle *proof2;
934
935 brandt_assert (ad && buflen);
936
937 *buflen = (sizeof (*head) +
938 ad->k * (sizeof (*gamma) +
939 sizeof (*delta) +
940 sizeof (*proof2)));
941 ret = GNUNET_new_array (*buflen, unsigned char);
942
943 head = (struct msg_head *)ret;
944 head->prot_version = htonl (0);
945 head->msg_type = htonl (msg_outcome);
946 cur = ret + sizeof (*head);
947
948 for (uint16_t j = 0; j < ad->k; j++)
949 {
950 gamma = (struct ec_mpi *)cur;
951 delta = &((struct ec_mpi *)cur)[1];
952 proof2 = (struct proof_2dle *)(cur + 2 * sizeof (struct ec_mpi));
953
954 ec_point_copy (tmpa, ad->gamma2[ad->i][j]);
955 ec_point_copy (tmpb, ad->delta2[ad->i][j]);
956
957 /* apply random masking for losing bidders */
958 smc_zkp_2dle (ad->gamma2[ad->i][j],
959 ad->delta2[ad->i][j],
960 tmpa,
961 tmpb,
962 NULL,
963 proof2);
964
965 ec_point_serialize (gamma, ad->gamma2[ad->i][j]);
966 ec_point_serialize (delta, ad->delta2[ad->i][j]);
967
968 /* add winner determination for own gamma,delta */
969 gcry_mpi_ec_add (ad->gamma2[ad->i][j],
970 ad->gamma2[ad->i][j],
971 ad->tmpa1[j],
972 ec_ctx);
973 gcry_mpi_ec_add (ad->delta2[ad->i][j],
974 ad->delta2[ad->i][j],
975 ad->tmpb1[j],
976 ec_ctx);
977
978 cur += sizeof (*gamma) + sizeof (*delta) + sizeof (*proof2);
979 }
980
981 gcry_mpi_point_release (tmpa);
982 gcry_mpi_point_release (tmpb);
983 return ret;
984}
985
986
987int
988fp_pub_recv_outcome (struct BRANDT_Auction *ad,
989 const unsigned char *buf,
990 size_t buflen,
991 uint16_t sender)
992{
993 int ret = 0;
994 const unsigned char *cur = buf;
995 struct proof_2dle *proof2;
996 gcry_mpi_point_t gamma = gcry_mpi_point_new (0);
997 gcry_mpi_point_t delta = gcry_mpi_point_new (0);
998
999 brandt_assert (ad && buf);
1000
1001 if (buflen != (ad->k * (2 * sizeof (struct ec_mpi) + sizeof (*proof2))))
1002 {
1003 weprintf ("wrong size of received outcome");
1004 goto quit;
1005 }
1006
1007 for (uint16_t j = 0; j < ad->k; j++)
1008 {
1009 ec_point_parse (gamma, (struct ec_mpi *)cur);
1010 ec_point_parse (delta, &((struct ec_mpi *)cur)[1]);
1011 proof2 = (struct proof_2dle *)(cur + 2 * sizeof (struct ec_mpi));
1012 if (smc_zkp_2dle_check (gamma,
1013 delta,
1014 ad->gamma2[sender][j],
1015 ad->delta2[sender][j],
1016 proof2))
1017 {
1018 weprintf ("wrong zkp2 for gamma, delta received");
1019 goto quit;
1020 }
1021 ec_point_copy (ad->gamma2[sender][j], gamma);
1022 ec_point_copy (ad->delta2[sender][j], delta);
1023
1024 /* add winner determination summand */
1025 gcry_mpi_ec_add (ad->gamma2[sender][j],
1026 ad->gamma2[sender][j],
1027 ad->tmpa1[j],
1028 ec_ctx);
1029 gcry_mpi_ec_add (ad->delta2[sender][j],
1030 ad->delta2[sender][j],
1031 ad->tmpb1[j],
1032 ec_ctx);
1033
1034 cur += 2 * sizeof (struct ec_mpi) + sizeof (*proof2);
1035 }
1036
1037 ret = 1;
1038quit:
1039 gcry_mpi_point_release (gamma);
1040 gcry_mpi_point_release (delta);
1041 return ret;
1042}
1043
1044
1045void
1046fp_pub_prep_decryption (struct BRANDT_Auction *ad)
1047{
1048 gcry_mpi_point_t tmp = gcry_mpi_point_new (0);
1049
1050 ad->phi2 = smc_init2 (ad->n, ad->k);
1051 brandt_assert (ad->phi2);
1052
1053 for (uint16_t j = 0; j < ad->k; j++)
1054 {
1055 smc_sum (tmp, &ad->delta2[0][j], ad->n, ad->k);
1056
1057 /* copy still encrypted outcome to all other bidder layers so they
1058 * don't have to be recomputed to check the ZK proof_2dle's from
1059 * other bidders when receiving their outcome decryption messages */
1060 for (uint16_t a = 0; a < ad->n; a++)
1061 ec_point_copy (ad->phi2[a][j], tmp);
1062 }
1063
1064 gcry_mpi_point_release (tmp);
1065}
1066
1067
1068/**
1069 * fp_pub_decrypt_outcome decrypts part of the outcome and packs it into a
1070 * message buffer together with proofs of correctnes.
1071 *
1072 * @param[in] ad Pointer to the BRANDT_Auction struct to operate on
1073 * @param[out] buflen Size of the returned message buffer in bytes
1074 * @return A buffer containing the own share of the decrypted outcome
1075 * which needs to be broadcast
1076 */
1077unsigned char *
1078fp_pub_decrypt_outcome (struct BRANDT_Auction *ad, size_t *buflen)
1079{
1080 unsigned char *ret;
1081 unsigned char *cur;
1082 gcry_mpi_point_t tmp = gcry_mpi_point_new (0);
1083 struct msg_head *head;
1084 struct ec_mpi *phi;
1085 struct proof_2dle *proof2;
1086
1087 brandt_assert (ad && buflen);
1088
1089 *buflen = (sizeof (*head) + ad->k * (sizeof (*phi) + sizeof (*proof2)));
1090 ret = GNUNET_new_array (*buflen, unsigned char);
1091
1092 head = (struct msg_head *)ret;
1093 head->prot_version = htonl (0);
1094 head->msg_type = htonl (msg_decrypt);
1095 cur = ret + sizeof (*head);
1096
1097 for (uint16_t j = 0; j < ad->k; j++)
1098 {
1099 phi = (struct ec_mpi *)cur;
1100 proof2 = (struct proof_2dle *)(cur + sizeof (*phi));
1101
1102 ec_point_copy (tmp, ad->phi2[ad->i][j]);
1103
1104 /* decrypt outcome component and prove the correct key was used */
1105 smc_zkp_2dle (ad->phi2[ad->i][j],
1106 NULL,
1107 tmp,
1108 ec_gen,
1109 ad->x,
1110 proof2);
1111
1112 ec_point_serialize (phi, ad->phi2[ad->i][j]);
1113
1114 cur += sizeof (*phi) + sizeof (*proof2);
1115 }
1116
1117 gcry_mpi_point_release (tmp);
1118 return ret;
1119}
1120
1121
1122int
1123fp_pub_recv_decryption (struct BRANDT_Auction *ad,
1124 const unsigned char *buf,
1125 size_t buflen,
1126 uint16_t sender)
1127{
1128 int ret = 0;
1129 const unsigned char *cur = buf;
1130 struct proof_2dle *proof2;
1131 gcry_mpi_point_t phi = gcry_mpi_point_new (0);
1132
1133 brandt_assert (ad && buf);
1134
1135 if (buflen != (ad->k * (sizeof (struct ec_mpi) + sizeof (*proof2))))
1136 {
1137 weprintf ("wrong size of received outcome decryption");
1138 goto quit;
1139 }
1140
1141 for (uint16_t j = 0; j < ad->k; j++)
1142 {
1143 ec_point_parse (phi, (struct ec_mpi *)cur);
1144 proof2 = (struct proof_2dle *)(cur + sizeof (struct ec_mpi));
1145 if (smc_zkp_2dle_check (phi,
1146 ad->y[sender],
1147 ad->phi2[sender][j],
1148 ec_gen,
1149 proof2))
1150 {
1151 weprintf ("wrong zkp2 for phi, y received");
1152 goto quit;
1153 }
1154 ec_point_copy (ad->phi2[sender][j], phi);
1155 cur += sizeof (struct ec_mpi) + sizeof (*proof2);
1156 }
1157
1158 ret = 1;
1159quit:
1160 gcry_mpi_point_release (phi);
1161 return ret;
1162}
1163
1164
1165struct BRANDT_Result *
1166fp_pub_determine_outcome (struct BRANDT_Auction *ad,
1167 uint16_t *len)
1168{
1169 struct BRANDT_Result *ret;
1170 int32_t price = -1;
1171 int32_t winner = -1;
1172 int dlogi = -1;
1173 gcry_mpi_point_t sum_gamma = gcry_mpi_point_new (0);
1174 gcry_mpi_point_t sum_phi = gcry_mpi_point_new (0);
1175
1176 brandt_assert (ad);
1177
1178 for (uint16_t j = ad->k - 1; j >= 0; j--)
1179 {
1180 smc_sum (sum_gamma, &ad->gamma2[0][j], ad->n, ad->k);
1181 smc_sum (sum_phi, &ad->phi2[0][j], ad->n, ad->k);
1182 gcry_mpi_ec_sub (sum_gamma, sum_gamma, sum_phi, ec_ctx);
1183 /* first non-zero component determines the price */
1184 if (ec_point_cmp (sum_gamma, ec_zero))
1185 {
1186 price = j;
1187 break;
1188 }
1189 }
1190
1191 dlogi = GNUNET_CRYPTO_ecc_dlog (ec_dlogctx, sum_gamma);
1192 brandt_assert (dlogi > 0);
1193
1194 /* all bidders participated with a multiplicative share */
1195 dlogi /= ad->n;
1196
1197 /* can only support up to bits(dlogi) bidders */
1198 brandt_assert (sizeof (int) * 8 - 1 >= ad->n);
1199 for (uint16_t i = 0; i < ad->n; i++)
1200 {
1201 /* first set bit determines the winner */
1202 if (dlogi & (1 << i))
1203 {
1204 winner = i;
1205 break;
1206 }
1207 }
1208
1209 gcry_mpi_point_release (sum_gamma);
1210 gcry_mpi_point_release (sum_phi);
1211
1212 if (-1 == winner || -1 == price)
1213 return NULL;
1214
1215 ret = GNUNET_new (struct BRANDT_Result);
1216 ret->bidder = winner;
1217 ret->price = price;
1218 ret->status = BRANDT_bidder_won;
1219 if (len)
1220 *len = 1;
1221 return ret;
1222}
1223
1224
1225void
1226fp_priv_prep_outcome (struct BRANDT_Auction *ad)
1227{
1228 gcry_mpi_point_t tmpa = gcry_mpi_point_new (0);
1229 gcry_mpi_point_t tmpb = gcry_mpi_point_new (0);
1230 gcry_mpi_point_t *tlta1;
1231 gcry_mpi_point_t *tltb1;
1232 gcry_mpi_point_t **tlta2;
1233 gcry_mpi_point_t **tltb2;
1234 gcry_mpi_point_t **tlta3;
1235 gcry_mpi_point_t **tltb3;
1236
1237 ad->gamma3 = smc_init3 (ad->n, ad->n, ad->k);
1238 brandt_assert (ad->gamma3);
1239
1240 ad->delta3 = smc_init3 (ad->n, ad->n, ad->k);
1241 brandt_assert (ad->delta3);
1242
1243 /* create temporary lookup tables with partial sums */
1244 tlta1 = smc_init1 (ad->k);
1245 tltb1 = smc_init1 (ad->k);
1246 tlta2 = smc_init2 (ad->n, ad->k);
1247 tltb2 = smc_init2 (ad->n, ad->k);
1248 tlta3 = smc_init2 (ad->n, ad->k);
1249 tltb3 = smc_init2 (ad->n, ad->k);
1250
1251 /* temporary lookup table for first summand (no one has a higher bid) */
1252 for (uint16_t i = 0; i < ad->n; i++)
1253 {
1254 smc_sums_partial (tlta2[i], ad->alpha[i], ad->k, 1, 1);
1255 smc_sums_partial (tltb2[i], ad->beta[i], ad->k, 1, 1);
1256 for (uint16_t j = 0; j < ad->k; j++)
1257 {
1258 gcry_mpi_ec_sub (tlta3[i][j],
1259 tlta2[i][ad->k - 1],
1260 tlta2[i][j],
1261 ec_ctx);
1262 gcry_mpi_ec_sub (tltb3[i][j],
1263 tltb2[i][ad->k - 1],
1264 tltb2[i][j],
1265 ec_ctx);
1266 }
1267 brandt_assert (!ec_point_cmp (ec_zero, tlta3[i][ad->k - 1]));
1268 brandt_assert (!ec_point_cmp (ec_zero, tltb3[i][ad->k - 1]));
1269 }
1270 for (uint16_t j = 0; j < ad->k; j++)
1271 {
1272 smc_sum (tlta1[j], &tlta3[0][j], ad->n, ad->k);
1273 smc_sum (tltb1[j], &tltb3[0][j], ad->n, ad->k);
1274 }
1275 brandt_assert (!ec_point_cmp (ec_zero, tlta1[ad->k - 1]));
1276 brandt_assert (!ec_point_cmp (ec_zero, tltb1[ad->k - 1]));
1277 /* \todo: merge into one nested i,j loop and one nested j,i loop? */
1278
1279 /* temporary lookup table for second summand (my bid is not lower) */
1280 for (uint16_t i = 0; i < ad->n; i++)
1281 {
1282 for (uint16_t j = 0; j < ad->k; j++)
1283 {
1284 gcry_mpi_ec_sub (tlta2[i][j], tlta2[i][j], ad->alpha[i][j], ec_ctx);
1285 gcry_mpi_ec_sub (tltb2[i][j], tltb2[i][j], ad->beta[i][j], ec_ctx);
1286 }
1287 brandt_assert (!ec_point_cmp (ec_zero, tlta2[i][0]));
1288 brandt_assert (!ec_point_cmp (ec_zero, tltb2[i][0]));
1289 }
1290
1291 /* temporary lookup table for third summand (no one with a lower index has
1292 * the same bid) */
1293 for (uint16_t j = 0; j < ad->k; j++)
1294 {
1295 smc_sums_partial (&tlta3[0][j], &ad->alpha[0][j], ad->n, ad->k, ad->k);
1296 smc_sums_partial (&tltb3[0][j], &ad->beta[0][j], ad->n, ad->k, ad->k);
1297 for (uint16_t i = 0; i < ad->n; i++)
1298 {
1299 gcry_mpi_ec_sub (tlta3[i][j], tlta3[i][j], ad->alpha[i][j], ec_ctx);
1300 gcry_mpi_ec_sub (tltb3[i][j], tltb3[i][j], ad->beta[i][j], ec_ctx);
1301 }
1302 brandt_assert (!ec_point_cmp (ec_zero, tlta3[0][j]));
1303 brandt_assert (!ec_point_cmp (ec_zero, tltb3[0][j]));
1304 }
1305
1306 for (uint16_t i = 0; i < ad->n; i++)
1307 {
1308 for (uint16_t j = 0; j < ad->k; j++)
1309 {
1310 /* compute inner gamma */
1311 gcry_mpi_ec_add (tmpa, tlta1[j], tlta2[i][j], ec_ctx);
1312 gcry_mpi_ec_add (tmpa, tmpa, tlta3[i][j], ec_ctx);
1313
1314 /* compute inner delta */
1315 gcry_mpi_ec_add (tmpb, tltb1[j], tltb2[i][j], ec_ctx);
1316 gcry_mpi_ec_add (tmpb, tmpb, tltb3[i][j], ec_ctx);
1317
1318 /* copy unmasked outcome to all other bidder layers so they don't
1319 * have to be recomputed to check the ZK proof_2dle's from other
1320 * bidders when receiving their outcome messages */
1321 for (uint16_t a = 0; a < ad->n; a++)
1322 {
1323 ec_point_copy (ad->gamma3[a][i][j], tmpa);
1324 ec_point_copy (ad->delta3[a][i][j], tmpb);
1325 }
1326 }
1327 }
1328
1329 gcry_mpi_point_release (tmpa);
1330 gcry_mpi_point_release (tmpb);
1331 smc_free1 (tlta1, ad->k);
1332 smc_free1 (tltb1, ad->k);
1333 smc_free2 (tlta2, ad->n, ad->k);
1334 smc_free2 (tltb2, ad->n, ad->k);
1335 smc_free2 (tlta3, ad->n, ad->k);
1336 smc_free2 (tltb3, ad->n, ad->k);
1337}
1338
1339
1340/**
1341 * fp_priv_compute_outcome computes encrypted outcome shares and packs them into
1342 * a message buffer together with proofs of correctnes.
1343 *
1344 * @param[in] ad Pointer to the BRANDT_Auction struct to operate on
1345 * @param[out] buflen Size of the returned message buffer in bytes
1346 * @return A buffer containing the encrypted outcome vectors
1347 * which needs to be broadcast
1348 */
1349unsigned char *
1350fp_priv_compute_outcome (struct BRANDT_Auction *ad, size_t *buflen)
1351{
1352 unsigned char *ret;
1353 unsigned char *cur;
1354 struct msg_head *head;
1355 gcry_mpi_point_t tmpa = gcry_mpi_point_new (0);
1356 gcry_mpi_point_t tmpb = gcry_mpi_point_new (0);
1357 struct ec_mpi *gamma;
1358 struct ec_mpi *delta;
1359 struct proof_2dle *proof2;
1360
1361 brandt_assert (ad && buflen);
1362
1363 *buflen = (sizeof (*head) + /* msg header */
1364 ad->n * ad->k * /* nk * (gamma, delta, proof2) */
1365 (sizeof (*gamma) + sizeof (*delta) + sizeof (*proof2)));
1366 ret = GNUNET_new_array (*buflen, unsigned char);
1367
1368 head = (struct msg_head *)ret;
1369 head->prot_version = htonl (0);
1370 head->msg_type = htonl (msg_outcome);
1371 cur = ret + sizeof (*head);
1372
1373 for (uint16_t i = 0; i < ad->n; i++)
1374 {
1375 for (uint16_t j = 0; j < ad->k; j++)
1376 {
1377 gamma = (struct ec_mpi *)cur;
1378 delta = &((struct ec_mpi *)cur)[1];
1379 proof2 = (struct proof_2dle *)(cur + 2 * sizeof (struct ec_mpi));
1380
1381 ec_point_copy (tmpa, ad->gamma3[ad->i][i][j]);
1382 ec_point_copy (tmpb, ad->delta3[ad->i][i][j]);
1383
1384 /* apply random masking for losing bidders */
1385 smc_zkp_2dle (ad->gamma3[ad->i][i][j],
1386 ad->delta3[ad->i][i][j],
1387 tmpa,
1388 tmpb,
1389 NULL,
1390 proof2);
1391
1392 ec_point_serialize (gamma, ad->gamma3[ad->i][i][j]);
1393 ec_point_serialize (delta, ad->delta3[ad->i][i][j]);
1394
1395 cur += sizeof (*gamma) + sizeof (*delta) + sizeof (*proof2);
1396 }
1397 }
1398
1399 gcry_mpi_point_release (tmpa);
1400 gcry_mpi_point_release (tmpb);
1401 return ret;
1402}
1403
1404
1405int
1406fp_priv_recv_outcome (struct BRANDT_Auction *ad,
1407 const unsigned char *buf,
1408 size_t buflen,
1409 uint16_t sender)
1410{
1411 int ret = 0;
1412 const unsigned char *cur = buf;
1413 struct proof_2dle *proof2;
1414 gcry_mpi_point_t gamma = gcry_mpi_point_new (0);
1415 gcry_mpi_point_t delta = gcry_mpi_point_new (0);
1416
1417 brandt_assert (ad && buf);
1418
1419 if (buflen != (ad->n * ad->k *
1420 (2 * sizeof (struct ec_mpi) + sizeof (*proof2))))
1421 {
1422 weprintf ("wrong size of received outcome");
1423 goto quit;
1424 }
1425
1426 for (uint16_t i = 0; i < ad->n; i++)
1427 {
1428 for (uint16_t j = 0; j < ad->k; j++)
1429 {
1430 ec_point_parse (gamma, (struct ec_mpi *)cur);
1431 ec_point_parse (delta, &((struct ec_mpi *)cur)[1]);
1432 proof2 = (struct proof_2dle *)(cur + 2 * sizeof (struct ec_mpi));
1433 if (smc_zkp_2dle_check (gamma,
1434 delta,
1435 ad->gamma3[sender][i][j],
1436 ad->delta3[sender][i][j],
1437 proof2))
1438 {
1439 weprintf ("wrong zkp2 for gamma, delta received");
1440 goto quit;
1441 }
1442 ec_point_copy (ad->gamma3[sender][i][j], gamma);
1443 ec_point_copy (ad->delta3[sender][i][j], delta);
1444 cur += 2 * sizeof (struct ec_mpi) + sizeof (*proof2);
1445 }
1446 }
1447
1448 ret = 1;
1449quit:
1450 gcry_mpi_point_release (gamma);
1451 gcry_mpi_point_release (delta);
1452 return ret;
1453}
1454
1455
1456void
1457fp_priv_prep_decryption (struct BRANDT_Auction *ad)
1458{
1459 gcry_mpi_point_t tmp = gcry_mpi_point_new (0);
1460
1461 ad->phi3 = smc_init3 (ad->n, ad->n, ad->k);
1462 brandt_assert (ad->phi3);
1463
1464 ad->phiproofs3 = GNUNET_new_array_3d (ad->n,
1465 ad->n,
1466 ad->k,
1467 struct proof_2dle);
1468 brandt_assert (ad->phiproofs3);
1469
1470 for (uint16_t i = 0; i < ad->n; i++)
1471 {
1472 for (uint16_t j = 0; j < ad->k; j++)
1473 {
1474 smc_sum (tmp, &ad->delta3[0][i][j], ad->n, ad->n * ad->k);
1475
1476 /* copy still encrypted outcome to all other bidder layers so they
1477 * don't have to be recomputed to check the ZK proof_2dle's from
1478 * other bidders when receiving their outcome decryption messages */
1479 for (uint16_t a = 0; a < ad->n; a++)
1480 ec_point_copy (ad->phi3[a][i][j], tmp);
1481 }
1482 }
1483
1484 gcry_mpi_point_release (tmp);
1485}
1486
1487
1488static unsigned char *
1489fp_priv_decrypt_outcome_seller (struct BRANDT_Auction *ad, size_t *buflen)
1490{
1491 unsigned char *ret;
1492 unsigned char *cur;
1493 struct msg_head *head;
1494 gcry_mpi_point_t tmp = gcry_mpi_point_new (0);
1495 struct ec_mpi *phi;
1496 struct proof_2dle *proof2;
1497
1498 *buflen = (sizeof (*head) +
1499 (ad->n - 1) * ad->n * ad->k * (sizeof (*phi) +
1500 sizeof (*proof2)));
1501 ret = GNUNET_new_array (*buflen, unsigned char);
1502
1503 head = (struct msg_head *)ret;
1504 head->prot_version = htonl (0);
1505 head->msg_type = htonl (msg_decrypt);
1506 cur = ret + sizeof (*head);
1507
1508 for (uint16_t h = 0; h < ad->n; h++)
1509 {
1510 for (uint16_t i = 0; i < ad->n; i++)
1511 {
1512 /* don't reveal outcome to losing bidders */
1513 if (h == i)
1514 continue;
1515
1516 for (uint16_t j = 0; j < ad->k; j++)
1517 {
1518 phi = (struct ec_mpi *)cur;
1519 proof2 = (struct proof_2dle *)(cur + sizeof (*phi));
1520
1521 ec_point_serialize (phi, ad->phi3[h][i][j]);
1522 memcpy (proof2, &ad->phiproofs3[h][i][j], sizeof (*proof2));
1523
1524 cur += sizeof (*phi) + sizeof (*proof2);
1525 }
1526 }
1527 }
1528
1529 gcry_mpi_point_release (tmp);
1530 return ret;
1531}
1532
1533
1534static unsigned char *
1535fp_priv_decrypt_outcome_bidder (struct BRANDT_Auction *ad, size_t *buflen)
1536{
1537 unsigned char *ret;
1538 unsigned char *cur;
1539 struct msg_head *head;
1540 gcry_mpi_point_t tmp = gcry_mpi_point_new (0);
1541 struct ec_mpi *phi;
1542 struct proof_2dle *proof2;
1543
1544 *buflen = (sizeof (*head) +
1545 ad->n * ad->k * (sizeof (*phi) + sizeof (*proof2)));
1546 ret = GNUNET_new_array (*buflen, unsigned char);
1547
1548 head = (struct msg_head *)ret;
1549 head->prot_version = htonl (0);
1550 head->msg_type = htonl (msg_decrypt);
1551 cur = ret + sizeof (*head);
1552
1553 for (uint16_t i = 0; i < ad->n; i++)
1554 {
1555 for (uint16_t j = 0; j < ad->k; j++)
1556 {
1557 phi = (struct ec_mpi *)cur;
1558 proof2 = (struct proof_2dle *)(cur + sizeof (*phi));
1559
1560 ec_point_copy (tmp, ad->phi3[ad->i][i][j]);
1561
1562 /* decrypt outcome component and prove the correct key was used */
1563 smc_zkp_2dle (ad->phi3[ad->i][i][j],
1564 NULL,
1565 tmp,
1566 ec_gen,
1567 ad->x,
1568 proof2);
1569
1570 ec_point_serialize (phi, ad->phi3[ad->i][i][j]);
1571
1572 cur += sizeof (*phi) + sizeof (*proof2);
1573 }
1574 }
1575
1576 gcry_mpi_point_release (tmp);
1577 return ret;
1578}
1579
1580
1581/**
1582 * fp_priv_decrypt_outcome decrypts the own shares of the outcome and packs them
1583 * into a message buffer together with proofs of correctnes. When this is called
1584 * as the seller it will not decrypt anything, but just create the message
1585 * buffer from all received decryption shares to broadcast back to all bidders.
1586 *
1587 * @param[in] ad Pointer to the BRANDT_Auction struct to operate on
1588 * @param[out] buflen Size of the returned message buffer in bytes
1589 * @return A buffer containing the share of the decrypted outcome
1590 * which needs to be broadcast
1591 */
1592unsigned char *
1593fp_priv_decrypt_outcome (struct BRANDT_Auction *ad, size_t *buflen)
1594{
1595 brandt_assert (ad && buflen);
1596 if (ad->seller_mode)
1597 return fp_priv_decrypt_outcome_seller (ad, buflen);
1598 else
1599 return fp_priv_decrypt_outcome_bidder (ad, buflen);
1600}
1601
1602
1603static int
1604fp_priv_recv_decryption_seller (struct BRANDT_Auction *ad,
1605 const unsigned char *buf,
1606 size_t buflen,
1607 uint16_t sender)
1608{
1609 int ret = 0;
1610 const unsigned char *cur = buf;
1611 struct proof_2dle *proof2;
1612 gcry_mpi_point_t phi = gcry_mpi_point_new (0);
1613
1614 if (buflen != (ad->n * ad->k * (sizeof (struct ec_mpi) + sizeof (*proof2))))
1615 {
1616 weprintf ("wrong size of received outcome decryption from bidder");
1617 goto quit;
1618 }
1619
1620 for (uint16_t i = 0; i < ad->n; i++)
1621 {
1622 for (uint16_t j = 0; j < ad->k; j++)
1623 {
1624 ec_point_parse (phi, (struct ec_mpi *)cur);
1625 proof2 = (struct proof_2dle *)(cur + sizeof (struct ec_mpi));
1626 if (smc_zkp_2dle_check (phi,
1627 ad->y[sender],
1628 ad->phi3[sender][i][j],
1629 ec_gen,
1630 proof2))
1631 {
1632 weprintf ("wrong zkp2 for phi, y received from bidder");
1633 goto quit;
1634 }
1635
1636 /* store proof. we need to rebroadcast it to the other bidders */
1637 memcpy (&ad->phiproofs3[sender][i][j], proof2, sizeof (*proof2));
1638
1639 ec_point_copy (ad->phi3[sender][i][j], phi);
1640 cur += sizeof (struct ec_mpi) + sizeof (*proof2);
1641 }
1642 }
1643
1644 ret = 1;
1645quit:
1646 gcry_mpi_point_release (phi);
1647 return ret;
1648}
1649
1650
1651static int
1652fp_priv_recv_decryption_bidder (struct BRANDT_Auction *ad,
1653 const unsigned char *buf,
1654 size_t buflen,
1655 uint16_t sender)
1656{
1657 int ret = 0;
1658 const unsigned char *cur = buf;
1659 struct proof_2dle *proof2;
1660 gcry_mpi_point_t phi = gcry_mpi_point_new (0);
1661
1662 if (buflen != ((ad->n - 1) * ad->n * ad->k * (sizeof (struct ec_mpi) +
1663 sizeof (*proof2))))
1664 {
1665 weprintf ("wrong size of received outcome decryption from seller");
1666 goto quit;
1667 }
1668
1669 for (uint16_t h = 0; h < ad->n; h++)
1670 {
1671 for (uint16_t i = 0; i < ad->n; i++)
1672 {
1673 /* those combinations are not sent by the seller */
1674 if (h == i)
1675 continue;
1676
1677 /* we already have our own phi values */
1678 if (h == ad->i)
1679 {
1680 cur += ad->k * (sizeof (struct ec_mpi) + sizeof (*proof2));
1681 continue;
1682 }
1683
1684 for (uint16_t j = 0; j < ad->k; j++)
1685 {
1686 ec_point_parse (phi, (struct ec_mpi *)cur);
1687 proof2 = (struct proof_2dle *)(cur + sizeof (struct ec_mpi));
1688 if (smc_zkp_2dle_check (phi,
1689 ad->y[h],
1690 ad->phi3[h][i][j],
1691 ec_gen,
1692 proof2))
1693 {
1694 weprintf ("wrong zkp2 for phi, y received from seller");
1695 goto quit;
1696 }
1697 ec_point_copy (ad->phi3[h][i][j], phi);
1698 cur += sizeof (struct ec_mpi) + sizeof (*proof2);
1699 }
1700 }
1701 }
1702
1703 ret = 1;
1704quit:
1705 gcry_mpi_point_release (phi);
1706 return ret;
1707}
1708
1709
1710int
1711fp_priv_recv_decryption (struct BRANDT_Auction *ad,
1712 const unsigned char *buf,
1713 size_t buflen,
1714 uint16_t sender)
1715{
1716 brandt_assert (ad && buf);
1717 if (ad->seller_mode)
1718 return fp_priv_recv_decryption_seller (ad, buf, buflen, sender);
1719 else
1720 return fp_priv_recv_decryption_bidder (ad, buf, buflen, sender);
1721}
1722
1723
1724struct BRANDT_Result *
1725fp_priv_determine_outcome (struct BRANDT_Auction *ad,
1726 uint16_t *len)
1727{
1728 struct BRANDT_Result *ret;
1729 int32_t price = -1;
1730 int32_t winner = -1;
1731 gcry_mpi_point_t sum_gamma = gcry_mpi_point_new (0);
1732 gcry_mpi_point_t sum_phi = gcry_mpi_point_new (0);
1733
1734 brandt_assert (ad);
1735
1736 for (uint16_t i = 0; i < ad->n; i++)
1737 {
1738 if (!ad->seller_mode && i != ad->i)
1739 continue;
1740
1741 for (uint16_t j = 0; j < ad->k; j++)
1742 {
1743 smc_sum (sum_gamma, &ad->gamma3[0][i][j], ad->n, ad->n * ad->k);
1744 smc_sum (sum_phi, &ad->phi3[0][i][j], ad->n, ad->n * ad->k);
1745 gcry_mpi_ec_sub (sum_gamma, sum_gamma, sum_phi, ec_ctx);
1746 if (!ec_point_cmp (sum_gamma, ec_zero))
1747 {
1748 if (-1 != price)
1749 {
1750 weprintf ("multiple winning prices detected");
1751 return NULL;
1752 }
1753 if (-1 != winner)
1754 {
1755 weprintf ("multiple winners detected");
1756 return NULL;
1757 }
1758 price = j;
1759 winner = i;
1760 }
1761 }
1762 }
1763
1764 gcry_mpi_point_release (sum_gamma);
1765 gcry_mpi_point_release (sum_phi);
1766
1767 if (-1 == winner || -1 == price)
1768 return NULL;
1769
1770 ret = GNUNET_new (struct BRANDT_Result);
1771 ret->bidder = winner;
1772 ret->price = price;
1773 ret->status = BRANDT_bidder_won;
1774 if (len)
1775 *len = 1;
1776 return ret;
1777}
1778
1779
1780/** 816/**
1781 * smc_zkp_dl creates a proof of knowledge of @a x with \f$v = xg\f$ where 817 * smc_zkp_dl creates a proof of knowledge of @a x with \f$v = xg\f$ where
1782 * \f$g\f$ is the base point on Ed25519. 818 * \f$g\f$ is the base point on Ed25519.