diff options
author | Florian Dold <florian.dold@gmail.com> | 2014-08-20 19:41:50 +0000 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2014-08-20 19:41:50 +0000 |
commit | 6ad171117374cbe13b1feb6ee97d7a9535ed0d4e (patch) | |
tree | 7a5e335bdf20b6fae0dcbb4365ff10ee5739deb8 /src/secretsharing/gnunet-service-secretsharing.c | |
parent | 4a93e6dd3ad7dc996830922ce39def67869b61d5 (diff) | |
download | gnunet-6ad171117374cbe13b1feb6ee97d7a9535ed0d4e.tar.gz gnunet-6ad171117374cbe13b1feb6ee97d7a9535ed0d4e.zip |
generate proof of fair encryption
Diffstat (limited to 'src/secretsharing/gnunet-service-secretsharing.c')
-rw-r--r-- | src/secretsharing/gnunet-service-secretsharing.c | 178 |
1 files changed, 153 insertions, 25 deletions
diff --git a/src/secretsharing/gnunet-service-secretsharing.c b/src/secretsharing/gnunet-service-secretsharing.c index 1e19df5ff..6868195ce 100644 --- a/src/secretsharing/gnunet-service-secretsharing.c +++ b/src/secretsharing/gnunet-service-secretsharing.c | |||
@@ -900,6 +900,128 @@ keygen_round2_conclude (void *cls) | |||
900 | } | 900 | } |
901 | 901 | ||
902 | 902 | ||
903 | static int | ||
904 | verify_fair (const struct GNUNET_CRYPTO_Paillier *ppub, const struct GNUNET_SECRETSHARING_FairEncryption *fe) | ||
905 | { | ||
906 | gcry_mpi_t n; | ||
907 | gcry_mpi_t n_sq; | ||
908 | |||
909 | GNUNET_assert (NULL != (n = gcry_mpi_new (0))); | ||
910 | GNUNET_assert (NULL != (n_sq = gcry_mpi_new (0))); | ||
911 | |||
912 | GNUNET_CRYPTO_mpi_scan_unsigned (&n, ppub, sizeof (struct GNUNET_CRYPTO_PaillierPublicKey)); | ||
913 | gcry_mpi_mul (n_sq, n, n); | ||
914 | } | ||
915 | |||
916 | |||
917 | /** | ||
918 | * Create a fair Paillier encryption of then given ciphertext. | ||
919 | * | ||
920 | * @param v the ciphertext | ||
921 | * @param[out] fe the fair encryption | ||
922 | */ | ||
923 | static void | ||
924 | encrypt_fair (gcry_mpi_t v, const struct GNUNET_CRYPTO_PaillierPublicKey *ppub, struct GNUNET_SECRETSHARING_FairEncryption *fe) | ||
925 | { | ||
926 | gcry_mpi_t r; | ||
927 | gcry_mpi_t s; | ||
928 | gcry_mpi_t t1; | ||
929 | gcry_mpi_t t2; | ||
930 | gcry_mpi_t z; | ||
931 | gcry_mpi_t w; | ||
932 | gcry_mpi_t n; | ||
933 | gcry_mpi_t e; | ||
934 | gcry_mpi_t n_sq; | ||
935 | gcry_mpi_t u; | ||
936 | gcry_mpi_t Y; | ||
937 | gcry_mpi_t G; | ||
938 | GNUNET_assert (NULL != (r = gcry_mpi_new (0))); | ||
939 | GNUNET_assert (NULL != (s = gcry_mpi_new (0))); | ||
940 | GNUNET_assert (NULL != (t1 = gcry_mpi_new (0))); | ||
941 | GNUNET_assert (NULL != (t2 = gcry_mpi_new (0))); | ||
942 | GNUNET_assert (NULL != (z = gcry_mpi_new (0))); | ||
943 | GNUNET_assert (NULL != (w = gcry_mpi_new (0))); | ||
944 | GNUNET_assert (NULL != (n_sq = gcry_mpi_new (0))); | ||
945 | GNUNET_assert (NULL != (e = gcry_mpi_new (0))); | ||
946 | GNUNET_assert (NULL != (u = gcry_mpi_new (0))); | ||
947 | GNUNET_assert (NULL != (Y = gcry_mpi_new (0))); | ||
948 | GNUNET_assert (NULL != (G = gcry_mpi_new (0))); | ||
949 | |||
950 | GNUNET_CRYPTO_mpi_scan_unsigned (&n, ppub, sizeof (struct GNUNET_CRYPTO_PaillierPublicKey)); | ||
951 | gcry_mpi_mul (n_sq, n, n); | ||
952 | gcry_mpi_add_ui (G, n, 1); | ||
953 | |||
954 | do { | ||
955 | gcry_mpi_randomize (u, GNUNET_CRYPTO_PAILLIER_BITS, GCRY_WEAK_RANDOM); | ||
956 | } | ||
957 | while (gcry_mpi_cmp (u, n) >= 0); | ||
958 | |||
959 | gcry_mpi_powm (t1, G, v, n_sq); | ||
960 | gcry_mpi_powm (t2, u, n, n_sq); | ||
961 | gcry_mpi_mulm (Y, t1, t2, n_sq); | ||
962 | |||
963 | GNUNET_CRYPTO_mpi_print_unsigned (fe->c.bits, | ||
964 | sizeof fe->c.bits, | ||
965 | Y); | ||
966 | |||
967 | |||
968 | gcry_mpi_randomize (r, 2048, GCRY_WEAK_RANDOM); | ||
969 | do { | ||
970 | gcry_mpi_randomize (s, GNUNET_CRYPTO_PAILLIER_BITS, GCRY_WEAK_RANDOM); | ||
971 | } | ||
972 | 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 | |||
978 | // compute t1 | ||
979 | gcry_mpi_mulm (t1, elgamal_g, r, elgamal_p); | ||
980 | // compute t2 (use z and w as temp) | ||
981 | gcry_mpi_powm (z, G, r, n_sq); | ||
982 | gcry_mpi_powm (w, s, n, n_sq); | ||
983 | gcry_mpi_mulm (t2, z, w, n_sq); | ||
984 | // compute z | ||
985 | gcry_mpi_mul (z, e, v); | ||
986 | gcry_mpi_addm (z, z, r, elgamal_q); | ||
987 | // compute w | ||
988 | gcry_mpi_powm (w, u, e, n); | ||
989 | gcry_mpi_mulm (w, w, s, n); | ||
990 | |||
991 | GNUNET_CRYPTO_mpi_print_unsigned (fe->t1, | ||
992 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, | ||
993 | t1); | ||
994 | |||
995 | GNUNET_CRYPTO_mpi_print_unsigned (fe->t2, | ||
996 | GNUNET_CRYPTO_PAILLIER_BITS * 2 / 8, | ||
997 | t2); | ||
998 | |||
999 | GNUNET_CRYPTO_mpi_print_unsigned (fe->z, | ||
1000 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, | ||
1001 | z); | ||
1002 | |||
1003 | GNUNET_CRYPTO_mpi_print_unsigned (fe->w, | ||
1004 | GNUNET_CRYPTO_PAILLIER_BITS / 8, | ||
1005 | w); | ||
1006 | |||
1007 | GNUNET_CRYPTO_mpi_print_unsigned (fe->e, | ||
1008 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, | ||
1009 | e); | ||
1010 | gcry_mpi_release (n); | ||
1011 | gcry_mpi_release (r); | ||
1012 | gcry_mpi_release (s); | ||
1013 | gcry_mpi_release (t1); | ||
1014 | gcry_mpi_release (t2); | ||
1015 | gcry_mpi_release (z); | ||
1016 | gcry_mpi_release (w); | ||
1017 | gcry_mpi_release (e); | ||
1018 | gcry_mpi_release (n_sq); | ||
1019 | gcry_mpi_release (u); | ||
1020 | gcry_mpi_release (Y); | ||
1021 | gcry_mpi_release (G); | ||
1022 | } | ||
1023 | |||
1024 | |||
903 | /** | 1025 | /** |
904 | * Insert round 2 element in the consensus, consisting of | 1026 | * Insert round 2 element in the consensus, consisting of |
905 | * (1) The exponentiated pre-share polynomial coefficients A_{i,l}=g^{a_{i,l}} | 1027 | * (1) The exponentiated pre-share polynomial coefficients A_{i,l}=g^{a_{i,l}} |
@@ -930,7 +1052,7 @@ insert_round2_element (struct KeygenSession *ks) | |||
930 | 1052 | ||
931 | element_size = (sizeof (struct GNUNET_SECRETSHARING_KeygenRevealData) + | 1053 | element_size = (sizeof (struct GNUNET_SECRETSHARING_KeygenRevealData) + |
932 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * ks->num_peers + | 1054 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * ks->num_peers + |
933 | sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) * ks->num_peers + | 1055 | sizeof (struct GNUNET_SECRETSHARING_FairEncryption) * ks->num_peers + |
934 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * ks->threshold); | 1056 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * ks->threshold); |
935 | 1057 | ||
936 | element = GNUNET_malloc (sizeof (struct GNUNET_SET_Element) + element_size); | 1058 | element = GNUNET_malloc (sizeof (struct GNUNET_SET_Element) + element_size); |
@@ -963,23 +1085,25 @@ insert_round2_element (struct KeygenSession *ks) | |||
963 | ks->local_peer_idx); | 1085 | ks->local_peer_idx); |
964 | 1086 | ||
965 | // encrypted pre-shares | 1087 | // encrypted pre-shares |
966 | for (i = 0; i < ks->num_peers; i++) | 1088 | // and fair encryption proof |
967 | { | 1089 | { |
968 | ptrdiff_t remaining = last_pos - pos; | 1090 | for (i = 0; i < ks->num_peers; i++) |
969 | struct GNUNET_CRYPTO_PaillierCiphertext *ciphertext; | ||
970 | |||
971 | GNUNET_assert (remaining > 0); | ||
972 | ciphertext = (void *) pos; | ||
973 | memset (ciphertext, 0, sizeof *ciphertext); | ||
974 | if (GNUNET_YES == ks->info[i].round1_valid) | ||
975 | { | 1091 | { |
976 | gcry_mpi_set_ui (idx, i + 1); | 1092 | ptrdiff_t remaining = last_pos - pos; |
977 | // evaluate the polynomial | 1093 | struct GNUNET_SECRETSHARING_FairEncryption *fe = (void *) pos; |
978 | horner_eval (v, ks->presecret_polynomial, ks->threshold, idx, elgamal_q); | 1094 | |
979 | // encrypt the result | 1095 | GNUNET_assert (remaining > 0); |
980 | GNUNET_CRYPTO_paillier_encrypt (&ks->info[i].paillier_public_key, v, 0, ciphertext); | 1096 | memset (fe, 0, sizeof *fe); |
1097 | if (GNUNET_YES == ks->info[i].round1_valid) | ||
1098 | { | ||
1099 | gcry_mpi_set_ui (idx, i + 1); | ||
1100 | // evaluate the polynomial | ||
1101 | horner_eval (v, ks->presecret_polynomial, ks->threshold, idx, elgamal_q); | ||
1102 | // encrypt the result | ||
1103 | encrypt_fair (v, &ks->info[i].paillier_public_key, fe); | ||
1104 | } | ||
1105 | pos += sizeof *fe; | ||
981 | } | 1106 | } |
982 | pos += sizeof *ciphertext; | ||
983 | } | 1107 | } |
984 | 1108 | ||
985 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: computed enc preshares\n", | 1109 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: computed enc preshares\n", |
@@ -998,6 +1122,7 @@ insert_round2_element (struct KeygenSession *ks) | |||
998 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: computed exp coefficients\n", | 1122 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: computed exp coefficients\n", |
999 | ks->local_peer_idx); | 1123 | ks->local_peer_idx); |
1000 | 1124 | ||
1125 | |||
1001 | d->purpose.size = htonl (element_size - offsetof (struct GNUNET_SECRETSHARING_KeygenRevealData, purpose)); | 1126 | d->purpose.size = htonl (element_size - offsetof (struct GNUNET_SECRETSHARING_KeygenRevealData, purpose)); |
1002 | d->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_SECRETSHARING_DKG2); | 1127 | d->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_SECRETSHARING_DKG2); |
1003 | GNUNET_CRYPTO_eddsa_sign (my_peer_private_key, &d->purpose, &d->signature); | 1128 | GNUNET_CRYPTO_eddsa_sign (my_peer_private_key, &d->purpose, &d->signature); |
@@ -1041,7 +1166,7 @@ keygen_reveal_get_exp_coeff (struct KeygenSession *ks, | |||
1041 | // skip exponentiated pre-shares | 1166 | // skip exponentiated pre-shares |
1042 | pos += GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * ks->num_peers; | 1167 | pos += GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * ks->num_peers; |
1043 | // skip encrypted pre-shares | 1168 | // skip encrypted pre-shares |
1044 | pos += sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) * ks->num_peers; | 1169 | pos += sizeof (struct GNUNET_SECRETSHARING_FairEncryption) * ks->num_peers; |
1045 | // skip exp. coeffs we are not interested in | 1170 | // skip exp. coeffs we are not interested in |
1046 | pos += GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * idx; | 1171 | pos += GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * idx; |
1047 | // the first exponentiated coefficient is the public key share | 1172 | // the first exponentiated coefficient is the public key share |
@@ -1050,7 +1175,7 @@ keygen_reveal_get_exp_coeff (struct KeygenSession *ks, | |||
1050 | } | 1175 | } |
1051 | 1176 | ||
1052 | 1177 | ||
1053 | static struct GNUNET_CRYPTO_PaillierCiphertext * | 1178 | static struct GNUNET_SECRETSHARING_FairEncryption * |
1054 | keygen_reveal_get_enc_preshare (struct KeygenSession *ks, | 1179 | keygen_reveal_get_enc_preshare (struct KeygenSession *ks, |
1055 | const struct GNUNET_SECRETSHARING_KeygenRevealData *d, | 1180 | const struct GNUNET_SECRETSHARING_KeygenRevealData *d, |
1056 | unsigned int idx) | 1181 | unsigned int idx) |
@@ -1063,8 +1188,8 @@ keygen_reveal_get_enc_preshare (struct KeygenSession *ks, | |||
1063 | // skip exponentiated pre-shares | 1188 | // skip exponentiated pre-shares |
1064 | pos += GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * ks->num_peers; | 1189 | pos += GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * ks->num_peers; |
1065 | // skip encrypted pre-shares we're not interested in | 1190 | // skip encrypted pre-shares we're not interested in |
1066 | pos += sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) * idx; | 1191 | pos += sizeof (struct GNUNET_SECRETSHARING_FairEncryption) * idx; |
1067 | return (struct GNUNET_CRYPTO_PaillierCiphertext *) pos; | 1192 | return (struct GNUNET_SECRETSHARING_FairEncryption *) pos; |
1068 | } | 1193 | } |
1069 | 1194 | ||
1070 | 1195 | ||
@@ -1090,7 +1215,7 @@ keygen_round2_new_element (void *cls, | |||
1090 | 1215 | ||
1091 | expected_element_size = (sizeof (struct GNUNET_SECRETSHARING_KeygenRevealData) + | 1216 | expected_element_size = (sizeof (struct GNUNET_SECRETSHARING_KeygenRevealData) + |
1092 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * ks->num_peers + | 1217 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * ks->num_peers + |
1093 | sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) * ks->num_peers + | 1218 | sizeof (struct GNUNET_SECRETSHARING_FairEncryption) * ks->num_peers + |
1094 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * ks->threshold); | 1219 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * ks->threshold); |
1095 | 1220 | ||
1096 | if (element->size != expected_element_size) | 1221 | if (element->size != expected_element_size) |
@@ -1158,11 +1283,14 @@ keygen_round2_new_element (void *cls, | |||
1158 | gcry_mpi_release (public_key_share); | 1283 | gcry_mpi_release (public_key_share); |
1159 | public_key_share = NULL; | 1284 | public_key_share = NULL; |
1160 | 1285 | ||
1161 | GNUNET_assert (NULL != (preshare = gcry_mpi_new (0))); | 1286 | { |
1162 | GNUNET_CRYPTO_paillier_decrypt (&ks->paillier_private_key, | 1287 | struct GNUNET_SECRETSHARING_FairEncryption *fe = keygen_reveal_get_enc_preshare (ks, d, ks->local_peer_idx); |
1163 | &ks->info[ks->local_peer_idx].paillier_public_key, | 1288 | GNUNET_assert (NULL != (preshare = gcry_mpi_new (0))); |
1164 | keygen_reveal_get_enc_preshare (ks, d, ks->local_peer_idx), | 1289 | GNUNET_CRYPTO_paillier_decrypt (&ks->paillier_private_key, |
1165 | preshare); | 1290 | &ks->info[ks->local_peer_idx].paillier_public_key, |
1291 | &fe->c, | ||
1292 | preshare); | ||
1293 | } | ||
1166 | 1294 | ||
1167 | GNUNET_assert (NULL != (tmp = gcry_mpi_new (0))); | 1295 | GNUNET_assert (NULL != (tmp = gcry_mpi_new (0))); |
1168 | gcry_mpi_powm (tmp, elgamal_g, preshare, elgamal_p); | 1296 | gcry_mpi_powm (tmp, elgamal_g, preshare, elgamal_p); |