aboutsummaryrefslogtreecommitdiff
path: root/src/secretsharing/secretsharing_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/secretsharing/secretsharing_api.c')
-rw-r--r--src/secretsharing/secretsharing_api.c181
1 files changed, 177 insertions, 4 deletions
diff --git a/src/secretsharing/secretsharing_api.c b/src/secretsharing/secretsharing_api.c
index d2b53acc7..1489a5c45 100644
--- a/src/secretsharing/secretsharing_api.c
+++ b/src/secretsharing/secretsharing_api.c
@@ -27,6 +27,7 @@
27#include "gnunet_util_lib.h" 27#include "gnunet_util_lib.h"
28#include "gnunet_secretsharing_service.h" 28#include "gnunet_secretsharing_service.h"
29#include "secretsharing.h" 29#include "secretsharing.h"
30#include <gcrypt.h>
30 31
31 32
32#define LOG(kind,...) GNUNET_log_from (kind, "secretsharing-api",__VA_ARGS__) 33#define LOG(kind,...) GNUNET_log_from (kind, "secretsharing-api",__VA_ARGS__)
@@ -83,6 +84,40 @@ struct GNUNET_SECRETSHARING_DecryptionHandle
83}; 84};
84 85
85 86
87/**
88 * The ElGamal prime field order as libgcrypt mpi.
89 * Initialized in #init_crypto_constants.
90 */
91static gcry_mpi_t elgamal_q;
92
93/**
94 * Modulus of the prime field used for ElGamal.
95 * Initialized in #init_crypto_constants.
96 */
97static gcry_mpi_t elgamal_p;
98
99/**
100 * Generator for prime field of order 'elgamal_q'.
101 * Initialized in #init_crypto_constants.
102 */
103static gcry_mpi_t elgamal_g;
104
105
106static void
107ensure_elgamal_initialized (void)
108{
109 if (NULL != elgamal_q)
110 return; /* looks like crypto is already initialized */
111
112 GNUNET_assert (0 == gcry_mpi_scan (&elgamal_q, GCRYMPI_FMT_HEX,
113 GNUNET_SECRETSHARING_ELGAMAL_Q_HEX, 0, NULL));
114 GNUNET_assert (0 == gcry_mpi_scan (&elgamal_p, GCRYMPI_FMT_HEX,
115 GNUNET_SECRETSHARING_ELGAMAL_P_HEX, 0, NULL));
116 GNUNET_assert (0 == gcry_mpi_scan (&elgamal_g, GCRYMPI_FMT_HEX,
117 GNUNET_SECRETSHARING_ELGAMAL_G_HEX, 0, NULL));
118}
119
120
86static void 121static void
87handle_session_client_error (void *cls, enum GNUNET_MQ_Error error) 122handle_session_client_error (void *cls, enum GNUNET_MQ_Error error)
88{ 123{
@@ -95,9 +130,12 @@ handle_session_client_error (void *cls, enum GNUNET_MQ_Error error)
95static void 130static void
96handle_decrypt_client_error (void *cls, enum GNUNET_MQ_Error error) 131handle_decrypt_client_error (void *cls, enum GNUNET_MQ_Error error)
97{ 132{
98 GNUNET_assert (0); 133 struct GNUNET_SECRETSHARING_DecryptionHandle *dh = cls;
134
135 dh->decrypt_cb (dh->decrypt_cls, NULL);
99} 136}
100 137
138
101static void 139static void
102handle_secret_ready (void *cls, const struct GNUNET_MessageHeader *msg) 140handle_secret_ready (void *cls, const struct GNUNET_MessageHeader *msg)
103{ 141{
@@ -116,6 +154,18 @@ handle_secret_ready (void *cls, const struct GNUNET_MessageHeader *msg)
116 share->num_peers, 154 share->num_peers,
117 (struct GNUNET_PeerIdentity *) &m[1]); 155 (struct GNUNET_PeerIdentity *) &m[1]);
118 156
157 GNUNET_SECRETSHARING_session_destroy (session);
158}
159
160
161void
162GNUNET_SECRETSHARING_session_destroy (struct GNUNET_SECRETSHARING_Session *session)
163{
164 GNUNET_MQ_destroy (session->mq);
165 session->mq = NULL;
166 GNUNET_CLIENT_disconnect (session->client);
167 session->client = NULL;
168 GNUNET_free (session);
119} 169}
120 170
121 171
@@ -169,7 +219,20 @@ GNUNET_SECRETSHARING_create_session (const struct GNUNET_CONFIGURATION_Handle *c
169static void 219static void
170handle_decrypt_done (void *cls, const struct GNUNET_MessageHeader *msg) 220handle_decrypt_done (void *cls, const struct GNUNET_MessageHeader *msg)
171{ 221{
172 GNUNET_assert (0); 222 struct GNUNET_SECRETSHARING_DecryptionHandle *dh = cls;
223 const struct GNUNET_SECRETSHARING_DecryptResponseMessage *m =
224 (const void *) msg;
225
226 const struct GNUNET_SECRETSHARING_Plaintext *plaintext;
227
228 if (m->success == 0)
229 plaintext = NULL;
230 else
231 plaintext = (void *) &m->plaintext;
232
233 dh->decrypt_cb (dh->decrypt_cls, plaintext);
234
235 GNUNET_SECRETSHARING_decrypt_cancel (dh);
173} 236}
174 237
175 238
@@ -187,9 +250,9 @@ handle_decrypt_done (void *cls, const struct GNUNET_MessageHeader *msg)
187 * @return handle to cancel the operation 250 * @return handle to cancel the operation
188 */ 251 */
189struct GNUNET_SECRETSHARING_DecryptionHandle * 252struct GNUNET_SECRETSHARING_DecryptionHandle *
190GNUNET_SECRETSHARING_decrypt (struct GNUNET_CONFIGURATION_Handle *cfg, 253GNUNET_SECRETSHARING_decrypt (const struct GNUNET_CONFIGURATION_Handle *cfg,
191 struct GNUNET_SECRETSHARING_Share *share, 254 struct GNUNET_SECRETSHARING_Share *share,
192 struct GNUNET_SECRETSHARING_Ciphertext *ciphertext, 255 const struct GNUNET_SECRETSHARING_Ciphertext *ciphertext,
193 struct GNUNET_TIME_Absolute deadline, 256 struct GNUNET_TIME_Absolute deadline,
194 GNUNET_SECRETSHARING_DecryptCallback decrypt_cb, 257 GNUNET_SECRETSHARING_DecryptCallback decrypt_cb,
195 void *decrypt_cb_cls) 258 void *decrypt_cb_cls)
@@ -223,6 +286,7 @@ GNUNET_SECRETSHARING_decrypt (struct GNUNET_CONFIGURATION_Handle *cfg,
223 GNUNET_assert (GNUNET_OK == GNUNET_SECRETSHARING_share_write (share, &msg[1], share_size, NULL)); 286 GNUNET_assert (GNUNET_OK == GNUNET_SECRETSHARING_share_write (share, &msg[1], share_size, NULL));
224 287
225 msg->deadline = GNUNET_TIME_absolute_hton (deadline); 288 msg->deadline = GNUNET_TIME_absolute_hton (deadline);
289 msg->ciphertext = *ciphertext;
226 290
227 GNUNET_MQ_send (s->mq, ev); 291 GNUNET_MQ_send (s->mq, ev);
228 292
@@ -231,3 +295,112 @@ GNUNET_SECRETSHARING_decrypt (struct GNUNET_CONFIGURATION_Handle *cfg,
231} 295}
232 296
233 297
298int
299GNUNET_SECRETSHARING_plaintext_generate_i (struct GNUNET_SECRETSHARING_Plaintext *plaintext,
300 int64_t exponent)
301{
302 int negative;
303 gcry_mpi_t x;
304
305 ensure_elgamal_initialized ();
306
307 GNUNET_assert (NULL != (x = gcry_mpi_new (0)));
308
309 negative = GNUNET_NO;
310 if (exponent < 0)
311 {
312 negative = GNUNET_YES;
313 exponent = -exponent;
314 }
315
316 gcry_mpi_set_ui (x, exponent);
317
318 gcry_mpi_powm (x, elgamal_g, x, elgamal_p);
319
320 if (GNUNET_YES == negative)
321 {
322 int res;
323 res = gcry_mpi_invm (x, x, elgamal_p);
324 if (0 == res)
325 return GNUNET_SYSERR;
326 }
327
328 GNUNET_CRYPTO_mpi_print_unsigned (plaintext, sizeof (struct GNUNET_SECRETSHARING_Plaintext), x);
329
330 return GNUNET_OK;
331}
332
333
334/**
335 * Encrypt a value. This operation is executed locally, no communication is
336 * necessary.
337 *
338 * This is a helper function, encryption can be done soley with a session's public key
339 * and the crypto system parameters.
340 *
341 * @param public_key public key to use for decryption
342 * @param message message to encrypt
343 * @param message_size number of bytes in @a message
344 * @param result_ciphertext pointer to store the resulting ciphertext
345 * @return #GNUNET_YES on succes, #GNUNET_SYSERR if the message is invalid (invalid range)
346 */
347int
348GNUNET_SECRETSHARING_encrypt (const struct GNUNET_SECRETSHARING_PublicKey *public_key,
349 const struct GNUNET_SECRETSHARING_Plaintext *plaintext,
350 struct GNUNET_SECRETSHARING_Ciphertext *result_ciphertext)
351{
352 /* pubkey */
353 gcry_mpi_t h;
354 /* nonce */
355 gcry_mpi_t y;
356 /* plaintext message */
357 gcry_mpi_t m;
358 /* temp value */
359 gcry_mpi_t tmp;
360
361 ensure_elgamal_initialized ();
362
363 GNUNET_assert (NULL != (h = gcry_mpi_new (0)));
364 GNUNET_assert (NULL != (y = gcry_mpi_new (0)));
365 GNUNET_assert (NULL != (tmp = gcry_mpi_new (0)));
366
367 GNUNET_CRYPTO_mpi_scan_unsigned (&h, public_key, sizeof *public_key);
368 GNUNET_CRYPTO_mpi_scan_unsigned (&m, plaintext, sizeof *plaintext);
369
370 // Randomize y such that 0 < y < elgamal_q.
371 // The '- 1' is necessary as bitlength(q) = bitlength(p) - 1.
372 do
373 {
374 gcry_mpi_randomize (y, GNUNET_SECRETSHARING_ELGAMAL_BITS - 1, GCRY_WEAK_RANDOM);
375 } while ((gcry_mpi_cmp_ui (y, 0) == 0) || (gcry_mpi_cmp (y, elgamal_q) >= 0));
376
377 // tmp <- g^y
378 gcry_mpi_powm (tmp, elgamal_g, y, elgamal_p);
379 // write tmp to c1
380 GNUNET_CRYPTO_mpi_print_unsigned (&result_ciphertext->c1_bits,
381 GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, tmp);
382
383 // tmp <- h^y
384 gcry_mpi_powm (tmp, h, y, elgamal_p);
385 // tmp <- tmp * m
386 gcry_mpi_mulm (tmp, tmp, m, elgamal_p);
387 // write tmp to c2
388 GNUNET_CRYPTO_mpi_print_unsigned (&result_ciphertext->c2_bits,
389 GNUNET_SECRETSHARING_ELGAMAL_BITS / 8, tmp);
390
391 return GNUNET_OK;
392}
393
394
395void
396GNUNET_SECRETSHARING_decrypt_cancel (struct GNUNET_SECRETSHARING_DecryptionHandle *h)
397{
398 GNUNET_MQ_destroy (h->mq);
399 h->mq = NULL;
400 GNUNET_CLIENT_disconnect (h->client);
401 h->client = NULL;
402 GNUNET_free (h);
403}
404
405
406