aboutsummaryrefslogtreecommitdiff
path: root/src/secretsharing
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2014-08-20 19:41:50 +0000
committerFlorian Dold <florian.dold@gmail.com>2014-08-20 19:41:50 +0000
commit6ad171117374cbe13b1feb6ee97d7a9535ed0d4e (patch)
tree7a5e335bdf20b6fae0dcbb4365ff10ee5739deb8 /src/secretsharing
parent4a93e6dd3ad7dc996830922ce39def67869b61d5 (diff)
downloadgnunet-6ad171117374cbe13b1feb6ee97d7a9535ed0d4e.tar.gz
gnunet-6ad171117374cbe13b1feb6ee97d7a9535ed0d4e.zip
generate proof of fair encryption
Diffstat (limited to 'src/secretsharing')
-rw-r--r--src/secretsharing/gnunet-service-secretsharing.c178
-rw-r--r--src/secretsharing/secretsharing_protocol.h11
2 files changed, 164 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
903static int
904verify_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 */
923static void
924encrypt_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
1053static struct GNUNET_CRYPTO_PaillierCiphertext * 1178static struct GNUNET_SECRETSHARING_FairEncryption *
1054keygen_reveal_get_enc_preshare (struct KeygenSession *ks, 1179keygen_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);
diff --git a/src/secretsharing/secretsharing_protocol.h b/src/secretsharing/secretsharing_protocol.h
index 3930c1231..90f021215 100644
--- a/src/secretsharing/secretsharing_protocol.h
+++ b/src/secretsharing/secretsharing_protocol.h
@@ -128,6 +128,17 @@ struct GNUNET_SECRETSHARING_DecryptData
128 struct GNUNET_SECRETSHARING_FieldElement nizk_response; 128 struct GNUNET_SECRETSHARING_FieldElement nizk_response;
129}; 129};
130 130
131
132struct GNUNET_SECRETSHARING_FairEncryption
133{
134 struct GNUNET_CRYPTO_PaillierCiphertext c;
135 char t1[GNUNET_SECRETSHARING_ELGAMAL_BITS / 8];
136 char t2[GNUNET_CRYPTO_PAILLIER_BITS * 2 / 8];
137 char e[GNUNET_SECRETSHARING_ELGAMAL_BITS / 8];
138 char z[GNUNET_SECRETSHARING_ELGAMAL_BITS / 8];
139 char w[GNUNET_CRYPTO_PAILLIER_BITS / 8];
140};
141
131GNUNET_NETWORK_STRUCT_END 142GNUNET_NETWORK_STRUCT_END
132 143
133#endif 144#endif