diff options
author | Florian Dold <florian.dold@gmail.com> | 2014-08-24 02:49:53 +0000 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2014-08-24 02:49:53 +0000 |
commit | 7d91829ad8087a77c6b04fc5547e68684cdbf513 (patch) | |
tree | 351bc03215b1cad029b08343b8cc4e865c98fb62 /src/secretsharing/gnunet-service-secretsharing.c | |
parent | 7675791ceca33a1e0ba0acd6e2d842faa6bc96a2 (diff) | |
download | gnunet-7d91829ad8087a77c6b04fc5547e68684cdbf513.tar.gz gnunet-7d91829ad8087a77c6b04fc5547e68684cdbf513.zip |
full proof of fair encryption
Diffstat (limited to 'src/secretsharing/gnunet-service-secretsharing.c')
-rw-r--r-- | src/secretsharing/gnunet-service-secretsharing.c | 297 |
1 files changed, 244 insertions, 53 deletions
diff --git a/src/secretsharing/gnunet-service-secretsharing.c b/src/secretsharing/gnunet-service-secretsharing.c index 6868195ce..9425a6c7b 100644 --- a/src/secretsharing/gnunet-service-secretsharing.c +++ b/src/secretsharing/gnunet-service-secretsharing.c | |||
@@ -900,17 +900,196 @@ keygen_round2_conclude (void *cls) | |||
900 | } | 900 | } |
901 | 901 | ||
902 | 902 | ||
903 | |||
904 | static void | ||
905 | restore_fair (const struct GNUNET_CRYPTO_PaillierPublicKey *ppub, | ||
906 | const struct GNUNET_SECRETSHARING_FairEncryption *fe, | ||
907 | gcry_mpi_t x, gcry_mpi_t xres) | ||
908 | { | ||
909 | gcry_mpi_t a_1; | ||
910 | gcry_mpi_t a_2; | ||
911 | gcry_mpi_t b_1; | ||
912 | gcry_mpi_t b_2; | ||
913 | gcry_mpi_t big_a; | ||
914 | gcry_mpi_t big_b; | ||
915 | gcry_mpi_t big_t; | ||
916 | gcry_mpi_t n; | ||
917 | gcry_mpi_t t_1; | ||
918 | gcry_mpi_t t_2; | ||
919 | gcry_mpi_t t; | ||
920 | gcry_mpi_t r; | ||
921 | gcry_mpi_t v; | ||
922 | |||
923 | |||
924 | GNUNET_assert (NULL != (n = gcry_mpi_new (0))); | ||
925 | GNUNET_assert (NULL != (t = gcry_mpi_new (0))); | ||
926 | GNUNET_assert (NULL != (t_1 = gcry_mpi_new (0))); | ||
927 | GNUNET_assert (NULL != (t_2 = gcry_mpi_new (0))); | ||
928 | GNUNET_assert (NULL != (r = gcry_mpi_new (0))); | ||
929 | GNUNET_assert (NULL != (big_t = gcry_mpi_new (0))); | ||
930 | GNUNET_assert (NULL != (v = gcry_mpi_new (0))); | ||
931 | GNUNET_assert (NULL != (big_a = gcry_mpi_new (0))); | ||
932 | GNUNET_assert (NULL != (big_b = gcry_mpi_new (0))); | ||
933 | |||
934 | // a = (N,0)^T | ||
935 | GNUNET_CRYPTO_mpi_scan_unsigned (&a_1, ppub, sizeof (struct GNUNET_CRYPTO_PaillierPublicKey)); | ||
936 | GNUNET_assert (NULL != (a_2 = gcry_mpi_new (0))); | ||
937 | gcry_mpi_set_ui (a_2, 0); | ||
938 | // b = (x,1)^T | ||
939 | GNUNET_assert (NULL != (b_1 = gcry_mpi_new (0))); | ||
940 | gcry_mpi_set (b_1, x); | ||
941 | GNUNET_assert (NULL != (b_2 = gcry_mpi_new (0))); | ||
942 | gcry_mpi_set_ui (b_2, 1); | ||
943 | |||
944 | // A = a DOT a | ||
945 | gcry_mpi_mul (t, a_1, a_1); | ||
946 | gcry_mpi_mul (big_a, a_2, a_2); | ||
947 | gcry_mpi_add (big_a, big_a, t); | ||
948 | |||
949 | // B = b DOT b | ||
950 | gcry_mpi_mul (t, b_1, b_1); | ||
951 | gcry_mpi_mul (big_b, b_2, b_2); | ||
952 | gcry_mpi_add (big_b, big_b, t); | ||
953 | |||
954 | while (1) | ||
955 | { | ||
956 | // n = a DOT b | ||
957 | gcry_mpi_mul (t, a_1, b_1); | ||
958 | gcry_mpi_mul (n, a_2, b_2); | ||
959 | gcry_mpi_add (n, n, t); | ||
960 | |||
961 | // r = nearest(n/B) | ||
962 | gcry_mpi_div (r, NULL, n, big_b, 0); | ||
963 | |||
964 | // T := A - 2rn + rrB | ||
965 | gcry_mpi_mul (v, r, n); | ||
966 | gcry_mpi_mul_ui (v, v, 2); | ||
967 | gcry_mpi_sub (big_t, big_a, v); | ||
968 | gcry_mpi_mul (v, r, r); | ||
969 | gcry_mpi_mul (v, v, big_b); | ||
970 | gcry_mpi_add (big_t, big_t, v); | ||
971 | |||
972 | if (gcry_mpi_cmp (big_t, big_b) >= 0) | ||
973 | { | ||
974 | break; | ||
975 | } | ||
976 | |||
977 | // t = a - rb | ||
978 | gcry_mpi_mul (v, r, b_1); | ||
979 | gcry_mpi_sub (t_1, a_1, v); | ||
980 | gcry_mpi_mul (v, r, b_2); | ||
981 | gcry_mpi_sub (t_2, a_2, v); | ||
982 | |||
983 | // a = b | ||
984 | gcry_mpi_set (a_1, b_1); | ||
985 | gcry_mpi_set (a_2, b_2); | ||
986 | // b = t | ||
987 | gcry_mpi_set (b_1, t_1); | ||
988 | gcry_mpi_set (b_2, t_2); | ||
989 | |||
990 | gcry_mpi_set (big_a, big_b); | ||
991 | gcry_mpi_set (big_b, big_t); | ||
992 | } | ||
993 | |||
994 | { | ||
995 | gcry_mpi_t paillier_n; | ||
996 | |||
997 | GNUNET_CRYPTO_mpi_scan_unsigned (&paillier_n, ppub, sizeof (struct GNUNET_CRYPTO_PaillierPublicKey)); | ||
998 | |||
999 | gcry_mpi_set (xres, b_2); | ||
1000 | gcry_mpi_invm (xres, xres, elgamal_q); | ||
1001 | gcry_mpi_mulm (xres, xres, b_1, elgamal_q); | ||
1002 | } | ||
1003 | |||
1004 | // FIXME: cleanup! | ||
1005 | } | ||
1006 | |||
1007 | |||
1008 | static void | ||
1009 | get_fair_encryption_challenge (const struct GNUNET_SECRETSHARING_FairEncryption *fe, gcry_mpi_t e) | ||
1010 | { | ||
1011 | struct { | ||
1012 | struct GNUNET_CRYPTO_PaillierCiphertext c; | ||
1013 | char h[GNUNET_SECRETSHARING_ELGAMAL_BITS / 8]; | ||
1014 | char t1[GNUNET_SECRETSHARING_ELGAMAL_BITS / 8]; | ||
1015 | char t2[GNUNET_CRYPTO_PAILLIER_BITS * 2 / 8]; | ||
1016 | } hash_data; | ||
1017 | struct GNUNET_HashCode e_hash; | ||
1018 | |||
1019 | memcpy (&hash_data.c, &fe->c, sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); | ||
1020 | memcpy (&hash_data.h, &fe->h, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); | ||
1021 | memcpy (&hash_data.t1, &fe->t1, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); | ||
1022 | memcpy (&hash_data.t2, &fe->t2, GNUNET_CRYPTO_PAILLIER_BITS * 2 / 8); | ||
1023 | |||
1024 | GNUNET_CRYPTO_mpi_scan_unsigned (&e, &e_hash, sizeof (struct GNUNET_HashCode)); | ||
1025 | gcry_mpi_mod (e, e, elgamal_q); | ||
1026 | } | ||
1027 | |||
1028 | |||
903 | static int | 1029 | static int |
904 | verify_fair (const struct GNUNET_CRYPTO_Paillier *ppub, const struct GNUNET_SECRETSHARING_FairEncryption *fe) | 1030 | verify_fair (const struct GNUNET_CRYPTO_PaillierPublicKey *ppub, const struct GNUNET_SECRETSHARING_FairEncryption *fe) |
905 | { | 1031 | { |
906 | gcry_mpi_t n; | 1032 | gcry_mpi_t n; |
907 | gcry_mpi_t n_sq; | 1033 | gcry_mpi_t n_sq; |
1034 | gcry_mpi_t z; | ||
1035 | gcry_mpi_t t1; | ||
1036 | gcry_mpi_t t2; | ||
1037 | gcry_mpi_t e; | ||
1038 | gcry_mpi_t w; | ||
1039 | gcry_mpi_t tmp1; | ||
1040 | gcry_mpi_t tmp2; | ||
1041 | gcry_mpi_t y; | ||
1042 | gcry_mpi_t big_y; | ||
908 | 1043 | ||
909 | GNUNET_assert (NULL != (n = gcry_mpi_new (0))); | ||
910 | GNUNET_assert (NULL != (n_sq = gcry_mpi_new (0))); | 1044 | GNUNET_assert (NULL != (n_sq = gcry_mpi_new (0))); |
1045 | GNUNET_assert (NULL != (tmp1 = gcry_mpi_new (0))); | ||
1046 | GNUNET_assert (NULL != (tmp2 = gcry_mpi_new (0))); | ||
1047 | GNUNET_assert (NULL != (e = gcry_mpi_new (0))); | ||
1048 | |||
1049 | get_fair_encryption_challenge (fe, e); | ||
911 | 1050 | ||
912 | GNUNET_CRYPTO_mpi_scan_unsigned (&n, ppub, sizeof (struct GNUNET_CRYPTO_PaillierPublicKey)); | 1051 | GNUNET_CRYPTO_mpi_scan_unsigned (&n, ppub, sizeof (struct GNUNET_CRYPTO_PaillierPublicKey)); |
1052 | GNUNET_CRYPTO_mpi_scan_unsigned (&t1, fe->t1, GNUNET_CRYPTO_PAILLIER_BITS / 8); | ||
1053 | GNUNET_CRYPTO_mpi_scan_unsigned (&z, fe->z, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); | ||
1054 | GNUNET_CRYPTO_mpi_scan_unsigned (&y, fe->h, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); | ||
1055 | GNUNET_CRYPTO_mpi_scan_unsigned (&w, fe->w, GNUNET_CRYPTO_PAILLIER_BITS / 8); | ||
1056 | GNUNET_CRYPTO_mpi_scan_unsigned (&big_y, fe->c.bits, GNUNET_CRYPTO_PAILLIER_BITS * 2 / 8); | ||
1057 | GNUNET_CRYPTO_mpi_scan_unsigned (&t2, fe->t2, GNUNET_CRYPTO_PAILLIER_BITS * 2 / 8); | ||
913 | gcry_mpi_mul (n_sq, n, n); | 1058 | gcry_mpi_mul (n_sq, n, n); |
1059 | |||
1060 | // tmp1 = g^z | ||
1061 | gcry_mpi_powm (tmp1, elgamal_g, z, elgamal_p); | ||
1062 | // tmp2 = y^{-e} | ||
1063 | gcry_mpi_powm (tmp1, y, e, elgamal_p); | ||
1064 | gcry_mpi_invm (tmp1, tmp1, elgamal_p); | ||
1065 | // tmp1 = tmp1 * tmp2 | ||
1066 | gcry_mpi_mulm (tmp1, tmp1, tmp2, elgamal_p); | ||
1067 | |||
1068 | if (0 == gcry_mpi_cmp (t1, tmp1)) | ||
1069 | { | ||
1070 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "fair encryption invalid (t1)\n"); | ||
1071 | return GNUNET_NO; | ||
1072 | } | ||
1073 | |||
1074 | gcry_mpi_powm (big_y, big_y, e, n_sq); | ||
1075 | gcry_mpi_invm (big_y, big_y, n_sq); | ||
1076 | |||
1077 | gcry_mpi_add_ui (tmp1, n, 1); | ||
1078 | gcry_mpi_powm (tmp1, tmp1, z, n_sq); | ||
1079 | |||
1080 | gcry_mpi_powm (tmp2, w, n, n_sq); | ||
1081 | |||
1082 | gcry_mpi_mulm (tmp1, tmp1, tmp2, n_sq); | ||
1083 | gcry_mpi_mulm (tmp1, tmp1, big_y, n_sq); | ||
1084 | |||
1085 | |||
1086 | if (0 == gcry_mpi_cmp (t2, tmp1)) | ||
1087 | { | ||
1088 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "fair encryption invalid (t2)\n"); | ||
1089 | return GNUNET_NO; | ||
1090 | } | ||
1091 | |||
1092 | return GNUNET_YES; | ||
914 | } | 1093 | } |
915 | 1094 | ||
916 | 1095 | ||
@@ -935,6 +1114,7 @@ encrypt_fair (gcry_mpi_t v, const struct GNUNET_CRYPTO_PaillierPublicKey *ppub, | |||
935 | gcry_mpi_t u; | 1114 | gcry_mpi_t u; |
936 | gcry_mpi_t Y; | 1115 | gcry_mpi_t Y; |
937 | gcry_mpi_t G; | 1116 | gcry_mpi_t G; |
1117 | gcry_mpi_t h; | ||
938 | GNUNET_assert (NULL != (r = gcry_mpi_new (0))); | 1118 | GNUNET_assert (NULL != (r = gcry_mpi_new (0))); |
939 | GNUNET_assert (NULL != (s = gcry_mpi_new (0))); | 1119 | GNUNET_assert (NULL != (s = gcry_mpi_new (0))); |
940 | GNUNET_assert (NULL != (t1 = gcry_mpi_new (0))); | 1120 | GNUNET_assert (NULL != (t1 = gcry_mpi_new (0))); |
@@ -946,6 +1126,7 @@ encrypt_fair (gcry_mpi_t v, const struct GNUNET_CRYPTO_PaillierPublicKey *ppub, | |||
946 | GNUNET_assert (NULL != (u = gcry_mpi_new (0))); | 1126 | GNUNET_assert (NULL != (u = gcry_mpi_new (0))); |
947 | GNUNET_assert (NULL != (Y = gcry_mpi_new (0))); | 1127 | GNUNET_assert (NULL != (Y = gcry_mpi_new (0))); |
948 | GNUNET_assert (NULL != (G = gcry_mpi_new (0))); | 1128 | GNUNET_assert (NULL != (G = gcry_mpi_new (0))); |
1129 | GNUNET_assert (NULL != (h = gcry_mpi_new (0))); | ||
949 | 1130 | ||
950 | GNUNET_CRYPTO_mpi_scan_unsigned (&n, ppub, sizeof (struct GNUNET_CRYPTO_PaillierPublicKey)); | 1131 | GNUNET_CRYPTO_mpi_scan_unsigned (&n, ppub, sizeof (struct GNUNET_CRYPTO_PaillierPublicKey)); |
951 | gcry_mpi_mul (n_sq, n, n); | 1132 | gcry_mpi_mul (n_sq, n, n); |
@@ -970,10 +1151,6 @@ encrypt_fair (gcry_mpi_t v, const struct GNUNET_CRYPTO_PaillierPublicKey *ppub, | |||
970 | gcry_mpi_randomize (s, GNUNET_CRYPTO_PAILLIER_BITS, GCRY_WEAK_RANDOM); | 1151 | gcry_mpi_randomize (s, GNUNET_CRYPTO_PAILLIER_BITS, GCRY_WEAK_RANDOM); |
971 | } | 1152 | } |
972 | while (gcry_mpi_cmp (s, n) >= 0); | 1153 | while (gcry_mpi_cmp (s, n) >= 0); |
973 | do { | ||
974 | gcry_mpi_randomize (e, GNUNET_SECRETSHARING_ELGAMAL_BITS - 1, GCRY_WEAK_RANDOM); | ||
975 | } | ||
976 | while (gcry_mpi_cmp (e, elgamal_q) >= 0); | ||
977 | 1154 | ||
978 | // compute t1 | 1155 | // compute t1 |
979 | gcry_mpi_mulm (t1, elgamal_g, r, elgamal_p); | 1156 | gcry_mpi_mulm (t1, elgamal_g, r, elgamal_p); |
@@ -981,12 +1158,13 @@ encrypt_fair (gcry_mpi_t v, const struct GNUNET_CRYPTO_PaillierPublicKey *ppub, | |||
981 | gcry_mpi_powm (z, G, r, n_sq); | 1158 | gcry_mpi_powm (z, G, r, n_sq); |
982 | gcry_mpi_powm (w, s, n, n_sq); | 1159 | gcry_mpi_powm (w, s, n, n_sq); |
983 | gcry_mpi_mulm (t2, z, w, n_sq); | 1160 | gcry_mpi_mulm (t2, z, w, n_sq); |
984 | // compute z | 1161 | |
985 | gcry_mpi_mul (z, e, v); | 1162 | |
986 | gcry_mpi_addm (z, z, r, elgamal_q); | 1163 | gcry_mpi_powm (h, elgamal_g, v, elgamal_p); |
987 | // compute w | 1164 | |
988 | gcry_mpi_powm (w, u, e, n); | 1165 | GNUNET_CRYPTO_mpi_print_unsigned (fe->h, |
989 | gcry_mpi_mulm (w, w, s, n); | 1166 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, |
1167 | h); | ||
990 | 1168 | ||
991 | GNUNET_CRYPTO_mpi_print_unsigned (fe->t1, | 1169 | GNUNET_CRYPTO_mpi_print_unsigned (fe->t1, |
992 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, | 1170 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, |
@@ -996,6 +1174,16 @@ encrypt_fair (gcry_mpi_t v, const struct GNUNET_CRYPTO_PaillierPublicKey *ppub, | |||
996 | GNUNET_CRYPTO_PAILLIER_BITS * 2 / 8, | 1174 | GNUNET_CRYPTO_PAILLIER_BITS * 2 / 8, |
997 | t2); | 1175 | t2); |
998 | 1176 | ||
1177 | |||
1178 | get_fair_encryption_challenge (fe, e); | ||
1179 | |||
1180 | // compute z | ||
1181 | gcry_mpi_mul (z, e, v); | ||
1182 | gcry_mpi_addm (z, z, r, elgamal_q); | ||
1183 | // compute w | ||
1184 | gcry_mpi_powm (w, u, e, n); | ||
1185 | gcry_mpi_mulm (w, w, s, n); | ||
1186 | |||
999 | GNUNET_CRYPTO_mpi_print_unsigned (fe->z, | 1187 | GNUNET_CRYPTO_mpi_print_unsigned (fe->z, |
1000 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, | 1188 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, |
1001 | z); | 1189 | z); |
@@ -1004,9 +1192,6 @@ encrypt_fair (gcry_mpi_t v, const struct GNUNET_CRYPTO_PaillierPublicKey *ppub, | |||
1004 | GNUNET_CRYPTO_PAILLIER_BITS / 8, | 1192 | GNUNET_CRYPTO_PAILLIER_BITS / 8, |
1005 | w); | 1193 | w); |
1006 | 1194 | ||
1007 | GNUNET_CRYPTO_mpi_print_unsigned (fe->e, | ||
1008 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, | ||
1009 | e); | ||
1010 | gcry_mpi_release (n); | 1195 | gcry_mpi_release (n); |
1011 | gcry_mpi_release (r); | 1196 | gcry_mpi_release (r); |
1012 | gcry_mpi_release (s); | 1197 | gcry_mpi_release (s); |
@@ -1019,6 +1204,7 @@ encrypt_fair (gcry_mpi_t v, const struct GNUNET_CRYPTO_PaillierPublicKey *ppub, | |||
1019 | gcry_mpi_release (u); | 1204 | gcry_mpi_release (u); |
1020 | gcry_mpi_release (Y); | 1205 | gcry_mpi_release (Y); |
1021 | gcry_mpi_release (G); | 1206 | gcry_mpi_release (G); |
1207 | gcry_mpi_release (h); | ||
1022 | } | 1208 | } |
1023 | 1209 | ||
1024 | 1210 | ||
@@ -1051,7 +1237,6 @@ insert_round2_element (struct KeygenSession *ks) | |||
1051 | GNUNET_assert (NULL != (idx = gcry_mpi_new (GNUNET_SECRETSHARING_ELGAMAL_BITS))); | 1237 | GNUNET_assert (NULL != (idx = gcry_mpi_new (GNUNET_SECRETSHARING_ELGAMAL_BITS))); |
1052 | 1238 | ||
1053 | element_size = (sizeof (struct GNUNET_SECRETSHARING_KeygenRevealData) + | 1239 | element_size = (sizeof (struct GNUNET_SECRETSHARING_KeygenRevealData) + |
1054 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * ks->num_peers + | ||
1055 | sizeof (struct GNUNET_SECRETSHARING_FairEncryption) * ks->num_peers + | 1240 | sizeof (struct GNUNET_SECRETSHARING_FairEncryption) * ks->num_peers + |
1056 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * ks->threshold); | 1241 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * ks->threshold); |
1057 | 1242 | ||
@@ -1067,20 +1252,6 @@ insert_round2_element (struct KeygenSession *ks) | |||
1067 | pos = (void *) &d[1]; | 1252 | pos = (void *) &d[1]; |
1068 | last_pos = pos + element_size; | 1253 | last_pos = pos + element_size; |
1069 | 1254 | ||
1070 | // exponentiated pre-shares | ||
1071 | for (i = 0; i < ks->num_peers; i++) | ||
1072 | { | ||
1073 | ptrdiff_t remaining = last_pos - pos; | ||
1074 | GNUNET_assert (remaining > 0); | ||
1075 | gcry_mpi_set_ui (idx, i + 1); | ||
1076 | // evaluate the polynomial | ||
1077 | horner_eval (v, ks->presecret_polynomial, ks->threshold, idx, elgamal_q); | ||
1078 | // take g to the result | ||
1079 | gcry_mpi_powm (v, elgamal_g, v, elgamal_p); | ||
1080 | GNUNET_CRYPTO_mpi_print_unsigned (pos, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, v); | ||
1081 | pos += GNUNET_SECRETSHARING_ELGAMAL_BITS / 8; | ||
1082 | } | ||
1083 | |||
1084 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: computed exp preshares\n", | 1255 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: computed exp preshares\n", |
1085 | ks->local_peer_idx); | 1256 | ks->local_peer_idx); |
1086 | 1257 | ||
@@ -1136,23 +1307,6 @@ insert_round2_element (struct KeygenSession *ks) | |||
1136 | 1307 | ||
1137 | 1308 | ||
1138 | static gcry_mpi_t | 1309 | static gcry_mpi_t |
1139 | keygen_reveal_get_exp_preshare (struct KeygenSession *ks, | ||
1140 | const struct GNUNET_SECRETSHARING_KeygenRevealData *d, | ||
1141 | unsigned int idx) | ||
1142 | { | ||
1143 | unsigned char *pos; | ||
1144 | gcry_mpi_t exp_preshare; | ||
1145 | |||
1146 | GNUNET_assert (idx < ks->num_peers); | ||
1147 | |||
1148 | pos = (void *) &d[1]; | ||
1149 | // skip exponentiated pre-shares we don't want | ||
1150 | pos += GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * idx; | ||
1151 | GNUNET_CRYPTO_mpi_scan_unsigned (&exp_preshare, pos, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); | ||
1152 | return exp_preshare; | ||
1153 | } | ||
1154 | |||
1155 | static gcry_mpi_t | ||
1156 | keygen_reveal_get_exp_coeff (struct KeygenSession *ks, | 1310 | keygen_reveal_get_exp_coeff (struct KeygenSession *ks, |
1157 | const struct GNUNET_SECRETSHARING_KeygenRevealData *d, | 1311 | const struct GNUNET_SECRETSHARING_KeygenRevealData *d, |
1158 | unsigned int idx) | 1312 | unsigned int idx) |
@@ -1163,8 +1317,6 @@ keygen_reveal_get_exp_coeff (struct KeygenSession *ks, | |||
1163 | GNUNET_assert (idx < ks->threshold); | 1317 | GNUNET_assert (idx < ks->threshold); |
1164 | 1318 | ||
1165 | pos = (void *) &d[1]; | 1319 | pos = (void *) &d[1]; |
1166 | // skip exponentiated pre-shares | ||
1167 | pos += GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * ks->num_peers; | ||
1168 | // skip encrypted pre-shares | 1320 | // skip encrypted pre-shares |
1169 | pos += sizeof (struct GNUNET_SECRETSHARING_FairEncryption) * ks->num_peers; | 1321 | pos += sizeof (struct GNUNET_SECRETSHARING_FairEncryption) * ks->num_peers; |
1170 | // skip exp. coeffs we are not interested in | 1322 | // skip exp. coeffs we are not interested in |
@@ -1185,14 +1337,31 @@ keygen_reveal_get_enc_preshare (struct KeygenSession *ks, | |||
1185 | GNUNET_assert (idx < ks->num_peers); | 1337 | GNUNET_assert (idx < ks->num_peers); |
1186 | 1338 | ||
1187 | pos = (void *) &d[1]; | 1339 | pos = (void *) &d[1]; |
1188 | // skip exponentiated pre-shares | ||
1189 | pos += GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * ks->num_peers; | ||
1190 | // skip encrypted pre-shares we're not interested in | 1340 | // skip encrypted pre-shares we're not interested in |
1191 | pos += sizeof (struct GNUNET_SECRETSHARING_FairEncryption) * idx; | 1341 | pos += sizeof (struct GNUNET_SECRETSHARING_FairEncryption) * idx; |
1192 | return (struct GNUNET_SECRETSHARING_FairEncryption *) pos; | 1342 | return (struct GNUNET_SECRETSHARING_FairEncryption *) pos; |
1193 | } | 1343 | } |
1194 | 1344 | ||
1195 | 1345 | ||
1346 | static gcry_mpi_t | ||
1347 | keygen_reveal_get_exp_preshare (struct KeygenSession *ks, | ||
1348 | const struct GNUNET_SECRETSHARING_KeygenRevealData *d, | ||
1349 | unsigned int idx) | ||
1350 | { | ||
1351 | unsigned char *pos; | ||
1352 | gcry_mpi_t exp_preshare; | ||
1353 | struct GNUNET_SECRETSHARING_FairEncryption *fe; | ||
1354 | |||
1355 | GNUNET_assert (idx < ks->num_peers); | ||
1356 | |||
1357 | fe = keygen_reveal_get_enc_preshare (ks, d, idx); | ||
1358 | pos += GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * idx; | ||
1359 | GNUNET_CRYPTO_mpi_scan_unsigned (&exp_preshare, fe->h, GNUNET_SECRETSHARING_ELGAMAL_BITS / 8); | ||
1360 | return exp_preshare; | ||
1361 | } | ||
1362 | |||
1363 | |||
1364 | |||
1196 | static void | 1365 | static void |
1197 | keygen_round2_new_element (void *cls, | 1366 | keygen_round2_new_element (void *cls, |
1198 | const struct GNUNET_SET_Element *element) | 1367 | const struct GNUNET_SET_Element *element) |
@@ -1214,7 +1383,6 @@ keygen_round2_new_element (void *cls, | |||
1214 | } | 1383 | } |
1215 | 1384 | ||
1216 | expected_element_size = (sizeof (struct GNUNET_SECRETSHARING_KeygenRevealData) + | 1385 | expected_element_size = (sizeof (struct GNUNET_SECRETSHARING_KeygenRevealData) + |
1217 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * ks->num_peers + | ||
1218 | sizeof (struct GNUNET_SECRETSHARING_FairEncryption) * ks->num_peers + | 1386 | sizeof (struct GNUNET_SECRETSHARING_FairEncryption) * ks->num_peers + |
1219 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * ks->threshold); | 1387 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * ks->threshold); |
1220 | 1388 | ||
@@ -1285,17 +1453,29 @@ keygen_round2_new_element (void *cls, | |||
1285 | 1453 | ||
1286 | { | 1454 | { |
1287 | struct GNUNET_SECRETSHARING_FairEncryption *fe = keygen_reveal_get_enc_preshare (ks, d, ks->local_peer_idx); | 1455 | struct GNUNET_SECRETSHARING_FairEncryption *fe = keygen_reveal_get_enc_preshare (ks, d, ks->local_peer_idx); |
1456 | gcry_mpi_t resx; | ||
1288 | GNUNET_assert (NULL != (preshare = gcry_mpi_new (0))); | 1457 | GNUNET_assert (NULL != (preshare = gcry_mpi_new (0))); |
1289 | GNUNET_CRYPTO_paillier_decrypt (&ks->paillier_private_key, | 1458 | GNUNET_CRYPTO_paillier_decrypt (&ks->paillier_private_key, |
1290 | &ks->info[ks->local_peer_idx].paillier_public_key, | 1459 | &ks->info[ks->local_peer_idx].paillier_public_key, |
1291 | &fe->c, | 1460 | &fe->c, |
1292 | preshare); | 1461 | preshare); |
1462 | |||
1463 | GNUNET_assert (NULL != (resx = gcry_mpi_new (0))); | ||
1464 | |||
1465 | // FIXME: not doing the restoration is less expensive | ||
1466 | |||
1467 | restore_fair (&ks->info[ks->local_peer_idx].paillier_public_key, fe, preshare, preshare); | ||
1468 | |||
1469 | //if (gcry_mpi_cmp (resx, preshare) != 0) | ||
1470 | //{ | ||
1471 | // GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "fair encryption restore failed\n"); | ||
1472 | // return; | ||
1473 | //} | ||
1293 | } | 1474 | } |
1294 | 1475 | ||
1295 | GNUNET_assert (NULL != (tmp = gcry_mpi_new (0))); | 1476 | GNUNET_assert (NULL != (tmp = gcry_mpi_new (0))); |
1296 | gcry_mpi_powm (tmp, elgamal_g, preshare, elgamal_p); | 1477 | gcry_mpi_powm (tmp, elgamal_g, preshare, elgamal_p); |
1297 | 1478 | ||
1298 | // TODO: restore a valid secret from the decryption (the hard part, solving SVP with gauss) | ||
1299 | cmp_result = gcry_mpi_cmp (tmp, info->preshare_commitment); | 1479 | cmp_result = gcry_mpi_cmp (tmp, info->preshare_commitment); |
1300 | gcry_mpi_release (tmp); | 1480 | gcry_mpi_release (tmp); |
1301 | tmp = NULL; | 1481 | tmp = NULL; |
@@ -1362,6 +1542,17 @@ keygen_round2_new_element (void *cls, | |||
1362 | } | 1542 | } |
1363 | 1543 | ||
1364 | // TODO: verify proof of fair encryption (once implemented) | 1544 | // TODO: verify proof of fair encryption (once implemented) |
1545 | for (j = 0; j < ks->num_peers; j++) | ||
1546 | { | ||
1547 | struct GNUNET_SECRETSHARING_FairEncryption *fe = keygen_reveal_get_enc_preshare (ks, d, j); | ||
1548 | if (GNUNET_YES != verify_fair (&ks->info[j].paillier_public_key, fe)) | ||
1549 | { | ||
1550 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "P%u: reveal data from P%u incorrect (fair encryption)\n", | ||
1551 | ks->local_peer_idx, j); | ||
1552 | return; | ||
1553 | } | ||
1554 | |||
1555 | } | ||
1365 | 1556 | ||
1366 | info->round2_valid = GNUNET_YES; | 1557 | info->round2_valid = GNUNET_YES; |
1367 | 1558 | ||