diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/scalarproduct/Makefile.am | 4 | ||||
-rw-r--r-- | src/scalarproduct/gnunet-service-scalarproduct-ecc.h | 120 | ||||
-rw-r--r-- | src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c | 474 | ||||
-rw-r--r-- | src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c | 562 |
4 files changed, 363 insertions, 797 deletions
diff --git a/src/scalarproduct/Makefile.am b/src/scalarproduct/Makefile.am index 13e1a00d2..c09e38393 100644 --- a/src/scalarproduct/Makefile.am +++ b/src/scalarproduct/Makefile.am | |||
@@ -60,7 +60,7 @@ gnunet_service_scalarproduct_bob_LDADD = \ | |||
60 | $(GN_LIBINTL) | 60 | $(GN_LIBINTL) |
61 | 61 | ||
62 | gnunet_service_scalarproduct_ecc_alice_SOURCES = \ | 62 | gnunet_service_scalarproduct_ecc_alice_SOURCES = \ |
63 | gnunet-service-scalarproduct.h \ | 63 | gnunet-service-scalarproduct-ecc.h \ |
64 | gnunet-service-scalarproduct-ecc_alice.c | 64 | gnunet-service-scalarproduct-ecc_alice.c |
65 | gnunet_service_scalarproduct_ecc_alice_LDADD = \ | 65 | gnunet_service_scalarproduct_ecc_alice_LDADD = \ |
66 | $(top_builddir)/src/util/libgnunetutil.la \ | 66 | $(top_builddir)/src/util/libgnunetutil.la \ |
@@ -71,7 +71,7 @@ gnunet_service_scalarproduct_ecc_alice_LDADD = \ | |||
71 | $(GN_LIBINTL) | 71 | $(GN_LIBINTL) |
72 | 72 | ||
73 | gnunet_service_scalarproduct_ecc_bob_SOURCES = \ | 73 | gnunet_service_scalarproduct_ecc_bob_SOURCES = \ |
74 | gnunet-service-scalarproduct.h \ | 74 | gnunet-service-scalarproduct-ecc.h \ |
75 | gnunet-service-scalarproduct-ecc_bob.c | 75 | gnunet-service-scalarproduct-ecc_bob.c |
76 | gnunet_service_scalarproduct_ecc_bob_LDADD = \ | 76 | gnunet_service_scalarproduct_ecc_bob_LDADD = \ |
77 | $(top_builddir)/src/util/libgnunetutil.la \ | 77 | $(top_builddir)/src/util/libgnunetutil.la \ |
diff --git a/src/scalarproduct/gnunet-service-scalarproduct-ecc.h b/src/scalarproduct/gnunet-service-scalarproduct-ecc.h new file mode 100644 index 000000000..0a222a208 --- /dev/null +++ b/src/scalarproduct/gnunet-service-scalarproduct-ecc.h | |||
@@ -0,0 +1,120 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2015 Christian Grothoff (and other contributing authors) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @file scalarproduct/gnunet-service-scalarproduct-ecc.h | ||
22 | * @brief scalarproduct service P2P messages | ||
23 | * @author Christian M. Fuchs | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | #ifndef GNUNET_SERVICE_SCALARPRODUCT_ECC_H | ||
27 | #define GNUNET_SERVICE_SCALARPRODUCT_ECC_H | ||
28 | |||
29 | |||
30 | GNUNET_NETWORK_STRUCT_BEGIN | ||
31 | |||
32 | /** | ||
33 | * Message type passed from requesting service Alice to responding | ||
34 | * service Bob to initiate a request and make Bob participate in our | ||
35 | * protocol. Afterwards, Bob is expected to perform the set | ||
36 | * intersection with Alice. Once that has succeeded, Alice will | ||
37 | * send a `struct AliceCryptodataMessage *`. Bob is not expected | ||
38 | * to respond via CADET in the meantime. | ||
39 | */ | ||
40 | struct EccServiceRequestMessage | ||
41 | { | ||
42 | /** | ||
43 | * Type is #GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_SESSION_INITIALIZATION | ||
44 | */ | ||
45 | struct GNUNET_MessageHeader header; | ||
46 | |||
47 | /** | ||
48 | * For alignment. Always zero. | ||
49 | */ | ||
50 | uint32_t reserved; | ||
51 | |||
52 | /** | ||
53 | * The transaction/session key used to identify a session | ||
54 | */ | ||
55 | struct GNUNET_HashCode session_id; | ||
56 | |||
57 | }; | ||
58 | |||
59 | |||
60 | /** | ||
61 | * Vector of ECC-encrypted values sent by Alice to Bob | ||
62 | * (after set intersection). Alice may send messages of this | ||
63 | * type repeatedly to transmit all values. | ||
64 | */ | ||
65 | struct EccAliceCryptodataMessage | ||
66 | { | ||
67 | /** | ||
68 | * Type is #GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_ALICE_CRYPTODATA | ||
69 | */ | ||
70 | struct GNUNET_MessageHeader header; | ||
71 | |||
72 | /** | ||
73 | * How many elements we appended to this message? In NBO. | ||
74 | */ | ||
75 | uint32_t contained_element_count GNUNET_PACKED; | ||
76 | |||
77 | /** | ||
78 | * struct GNUNET_CRYPTO_EccPoint[contained_element_count] | ||
79 | */ | ||
80 | }; | ||
81 | |||
82 | |||
83 | /** | ||
84 | * Message type passed from responding service Bob to responding | ||
85 | * service Alice to complete a request and allow Alice to compute the | ||
86 | * result. If Bob's reply does not fit into this one message, the | ||
87 | * conversation may be continued with `struct BobCryptodataMultipartMessage` | ||
88 | * messages afterwards. | ||
89 | */ | ||
90 | struct EccBobCryptodataMessage | ||
91 | { | ||
92 | /** | ||
93 | * GNUNET message header with type | ||
94 | * #GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_BOB_CRYPTODATA. | ||
95 | */ | ||
96 | struct GNUNET_MessageHeader header; | ||
97 | |||
98 | /** | ||
99 | * How many elements this individual message delivers (in NBO), | ||
100 | * always TWO. | ||
101 | */ | ||
102 | uint32_t contained_element_count GNUNET_PACKED; | ||
103 | |||
104 | /** | ||
105 | * The product of the g_i^{b_i} values. | ||
106 | */ | ||
107 | struct GNUNET_CRYPTO_EccPoint prod_g_i_b_i; | ||
108 | |||
109 | /** | ||
110 | * The product of the h_i^{b_i} values. | ||
111 | */ | ||
112 | struct GNUNET_CRYPTO_EccPoint prod_h_i_b_i; | ||
113 | |||
114 | }; | ||
115 | |||
116 | |||
117 | GNUNET_NETWORK_STRUCT_END | ||
118 | |||
119 | |||
120 | #endif | ||
diff --git a/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c b/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c index 565cc3104..773682234 100644 --- a/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c +++ b/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2013, 2014 Christian Grothoff (and other contributing authors) | 3 | Copyright (C) 2013-2015 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -18,7 +18,7 @@ | |||
18 | Boston, MA 02110-1301, USA. | 18 | Boston, MA 02110-1301, USA. |
19 | */ | 19 | */ |
20 | /** | 20 | /** |
21 | * @file scalarproduct/gnunet-service-scalarproduct_alice.c | 21 | * @file scalarproduct/gnunet-service-scalarproduct-ecc_alice.c |
22 | * @brief scalarproduct service implementation | 22 | * @brief scalarproduct service implementation |
23 | * @author Christian M. Fuchs | 23 | * @author Christian M. Fuchs |
24 | * @author Christian Grothoff | 24 | * @author Christian Grothoff |
@@ -34,11 +34,17 @@ | |||
34 | #include "gnunet_scalarproduct_service.h" | 34 | #include "gnunet_scalarproduct_service.h" |
35 | #include "gnunet_set_service.h" | 35 | #include "gnunet_set_service.h" |
36 | #include "scalarproduct.h" | 36 | #include "scalarproduct.h" |
37 | #include "gnunet-service-scalarproduct.h" | 37 | #include "gnunet-service-scalarproduct-ecc.h" |
38 | 38 | ||
39 | #define LOG(kind,...) GNUNET_log_from (kind, "scalarproduct-alice", __VA_ARGS__) | 39 | #define LOG(kind,...) GNUNET_log_from (kind, "scalarproduct-alice", __VA_ARGS__) |
40 | 40 | ||
41 | /** | 41 | /** |
42 | * Maximum allowed result value for the scalarproduct computation. | ||
43 | * DLOG will fail if the result is bigger. | ||
44 | */ | ||
45 | #define MAX_RESULT (1024 * 1024) | ||
46 | |||
47 | /** | ||
42 | * An encrypted element key-value pair. | 48 | * An encrypted element key-value pair. |
43 | */ | 49 | */ |
44 | struct MpiElement | 50 | struct MpiElement |
@@ -51,9 +57,15 @@ struct MpiElement | |||
51 | const struct GNUNET_HashCode *key; | 57 | const struct GNUNET_HashCode *key; |
52 | 58 | ||
53 | /** | 59 | /** |
54 | * Value represented (a). | 60 | * a_i value, not disclosed to Bob. |
55 | */ | 61 | */ |
56 | gcry_mpi_t value; | 62 | gcry_mpi_t value; |
63 | |||
64 | /** | ||
65 | * r_i value, chosen at random, not disclosed to Bob. | ||
66 | */ | ||
67 | gcry_mpi_t r_i; | ||
68 | |||
57 | }; | 69 | }; |
58 | 70 | ||
59 | 71 | ||
@@ -123,26 +135,6 @@ struct AliceServiceSession | |||
123 | struct MpiElement *sorted_elements; | 135 | struct MpiElement *sorted_elements; |
124 | 136 | ||
125 | /** | 137 | /** |
126 | * Bob's permutation p of R | ||
127 | */ | ||
128 | struct GNUNET_CRYPTO_PaillierCiphertext *r; | ||
129 | |||
130 | /** | ||
131 | * Bob's permutation q of R | ||
132 | */ | ||
133 | struct GNUNET_CRYPTO_PaillierCiphertext *r_prime; | ||
134 | |||
135 | /** | ||
136 | * Bob's "s" | ||
137 | */ | ||
138 | struct GNUNET_CRYPTO_PaillierCiphertext s; | ||
139 | |||
140 | /** | ||
141 | * Bob's "s'" | ||
142 | */ | ||
143 | struct GNUNET_CRYPTO_PaillierCiphertext s_prime; | ||
144 | |||
145 | /** | ||
146 | * The computed scalar | 138 | * The computed scalar |
147 | */ | 139 | */ |
148 | gcry_mpi_t product; | 140 | gcry_mpi_t product; |
@@ -167,12 +159,6 @@ struct AliceServiceSession | |||
167 | uint32_t client_received_element_count; | 159 | uint32_t client_received_element_count; |
168 | 160 | ||
169 | /** | 161 | /** |
170 | * Already transferred elements from Bob to us. | ||
171 | * Less or equal than @e total. | ||
172 | */ | ||
173 | uint32_t cadet_received_element_count; | ||
174 | |||
175 | /** | ||
176 | * State of this session. In | 162 | * State of this session. In |
177 | * #GNUNET_SCALARPRODUCT_STATUS_ACTIVE while operation is | 163 | * #GNUNET_SCALARPRODUCT_STATUS_ACTIVE while operation is |
178 | * ongoing, afterwards in #GNUNET_SCALARPRODUCT_STATUS_SUCCESS or | 164 | * ongoing, afterwards in #GNUNET_SCALARPRODUCT_STATUS_SUCCESS or |
@@ -195,19 +181,19 @@ struct AliceServiceSession | |||
195 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | 181 | static const struct GNUNET_CONFIGURATION_Handle *cfg; |
196 | 182 | ||
197 | /** | 183 | /** |
198 | * Service's own public key | 184 | * Context for DLOG operations on a curve. |
199 | */ | 185 | */ |
200 | static struct GNUNET_CRYPTO_PaillierPublicKey my_pubkey; | 186 | static struct GNUNET_CRYPTO_EccDlogContext *edc; |
201 | 187 | ||
202 | /** | 188 | /** |
203 | * Service's own private key | 189 | * Alice's private key ('a'). |
204 | */ | 190 | */ |
205 | static struct GNUNET_CRYPTO_PaillierPrivateKey my_privkey; | 191 | static gcry_mpi_t my_privkey; |
206 | 192 | ||
207 | /** | 193 | /** |
208 | * Service's offset for values that could possibly be negative but are plaintext for encryption. | 194 | * Inverse of Alice's private key ('a_inv'). |
209 | */ | 195 | */ |
210 | static gcry_mpi_t my_offset; | 196 | static gcry_mpi_t my_privkey_inv; |
211 | 197 | ||
212 | /** | 198 | /** |
213 | * Handle to the CADET service. | 199 | * Handle to the CADET service. |
@@ -300,16 +286,6 @@ destroy_service_session (struct AliceServiceSession *s) | |||
300 | GNUNET_free (s->sorted_elements); | 286 | GNUNET_free (s->sorted_elements); |
301 | s->sorted_elements = NULL; | 287 | s->sorted_elements = NULL; |
302 | } | 288 | } |
303 | if (NULL != s->r) | ||
304 | { | ||
305 | GNUNET_free (s->r); | ||
306 | s->r = NULL; | ||
307 | } | ||
308 | if (NULL != s->r_prime) | ||
309 | { | ||
310 | GNUNET_free (s->r_prime); | ||
311 | s->r_prime = NULL; | ||
312 | } | ||
313 | if (NULL != s->product) | 289 | if (NULL != s->product) |
314 | { | 290 | { |
315 | gcry_mpi_release (s->product); | 291 | gcry_mpi_release (s->product); |
@@ -463,248 +439,41 @@ cb_channel_destruction (void *cls, | |||
463 | 439 | ||
464 | 440 | ||
465 | /** | 441 | /** |
466 | * Computes the square sum over a vector of a given length. | ||
467 | * | ||
468 | * @param vector the vector to compute over | ||
469 | * @param length the length of the vector | ||
470 | * @return an MPI value containing the calculated sum, never NULL | ||
471 | */ | ||
472 | static gcry_mpi_t | ||
473 | compute_square_sum_mpi_elements (const struct MpiElement *vector, | ||
474 | uint32_t length) | ||
475 | { | ||
476 | gcry_mpi_t elem; | ||
477 | gcry_mpi_t sum; | ||
478 | uint32_t i; | ||
479 | |||
480 | GNUNET_assert (NULL != (sum = gcry_mpi_new (0))); | ||
481 | GNUNET_assert (NULL != (elem = gcry_mpi_new (0))); | ||
482 | for (i = 0; i < length; i++) | ||
483 | { | ||
484 | gcry_mpi_mul (elem, vector[i].value, vector[i].value); | ||
485 | gcry_mpi_add (sum, sum, elem); | ||
486 | } | ||
487 | gcry_mpi_release (elem); | ||
488 | return sum; | ||
489 | } | ||
490 | |||
491 | |||
492 | /** | ||
493 | * Computes the square sum over a vector of a given length. | ||
494 | * | ||
495 | * @param vector the vector to compute over | ||
496 | * @param length the length of the vector | ||
497 | * @return an MPI value containing the calculated sum, never NULL | ||
498 | */ | ||
499 | static gcry_mpi_t | ||
500 | compute_square_sum (const gcry_mpi_t *vector, | ||
501 | uint32_t length) | ||
502 | { | ||
503 | gcry_mpi_t elem; | ||
504 | gcry_mpi_t sum; | ||
505 | uint32_t i; | ||
506 | |||
507 | GNUNET_assert (NULL != (sum = gcry_mpi_new (0))); | ||
508 | GNUNET_assert (NULL != (elem = gcry_mpi_new (0))); | ||
509 | for (i = 0; i < length; i++) | ||
510 | { | ||
511 | gcry_mpi_mul (elem, vector[i], vector[i]); | ||
512 | gcry_mpi_add (sum, sum, elem); | ||
513 | } | ||
514 | gcry_mpi_release (elem); | ||
515 | return sum; | ||
516 | } | ||
517 | |||
518 | |||
519 | /** | ||
520 | * Compute our scalar product, done by Alice | 442 | * Compute our scalar product, done by Alice |
521 | * | 443 | * |
522 | * @param session the session associated with this computation | 444 | * @param session the session associated with this computation |
445 | * @param prod_g_i_b_i value from Bob | ||
446 | * @param prod_h_i_b_i value from Bob | ||
523 | * @return product as MPI, never NULL | 447 | * @return product as MPI, never NULL |
524 | */ | 448 | */ |
525 | static gcry_mpi_t | 449 | static gcry_mpi_t |
526 | compute_scalar_product (struct AliceServiceSession *session) | 450 | compute_scalar_product (struct AliceServiceSession *session, |
451 | gcry_mpi_point_t prod_g_i_b_i, | ||
452 | gcry_mpi_point_t prod_h_i_b_i) | ||
527 | { | 453 | { |
528 | uint32_t count; | 454 | gcry_mpi_point_t g_i_b_i_a_inv; |
529 | gcry_mpi_t t; | 455 | gcry_mpi_point_t g_ai_bi; |
530 | gcry_mpi_t u; | 456 | int ai_bi; |
531 | gcry_mpi_t u_prime; | 457 | gcry_mpi_t ret; |
532 | gcry_mpi_t p; | 458 | |
533 | gcry_mpi_t p_prime; | 459 | g_i_b_i_a_inv = GNUNET_CRYPTO_ecc_pmul_mpi (edc, |
534 | gcry_mpi_t tmp; | 460 | prod_g_i_b_i, |
535 | gcry_mpi_t r[session->used_element_count]; | 461 | my_privkey_inv); |
536 | gcry_mpi_t r_prime[session->used_element_count]; | 462 | g_ai_bi = GNUNET_CRYPTO_ecc_add (edc, |
537 | gcry_mpi_t s; | 463 | g_i_b_i_a_inv, |
538 | gcry_mpi_t s_prime; | 464 | prod_h_i_b_i); |
539 | unsigned int i; | 465 | gcry_mpi_point_release (g_i_b_i_a_inv); |
540 | 466 | ai_bi = GNUNET_CRYPTO_ecc_dlog (edc, | |
541 | count = session->used_element_count; | 467 | g_ai_bi); |
542 | // due to the introduced static offset S, we now also have to remove this | 468 | gcry_mpi_point_release (g_ai_bi); |
543 | // from the E(a_pi)(+)E(-b_pi-r_pi) and E(a_qi)(+)E(-r_qi) twice each, | 469 | if (MAX_RESULT == ai_bi) |
544 | // the result is E((S + a_pi) + (S -b_pi-r_pi)) and E(S + a_qi + S - r_qi) | ||
545 | for (i = 0; i < count; i++) | ||
546 | { | 470 | { |
547 | r[i] = gcry_mpi_new (0); | 471 | /* result too big */ |
548 | GNUNET_CRYPTO_paillier_decrypt (&my_privkey, | 472 | return NULL; |
549 | &my_pubkey, | ||
550 | &session->r[i], | ||
551 | r[i]); | ||
552 | gcry_mpi_sub (r[i], | ||
553 | r[i], | ||
554 | my_offset); | ||
555 | gcry_mpi_sub (r[i], | ||
556 | r[i], | ||
557 | my_offset); | ||
558 | r_prime[i] = gcry_mpi_new (0); | ||
559 | GNUNET_CRYPTO_paillier_decrypt (&my_privkey, | ||
560 | &my_pubkey, | ||
561 | &session->r_prime[i], | ||
562 | r_prime[i]); | ||
563 | gcry_mpi_sub (r_prime[i], | ||
564 | r_prime[i], | ||
565 | my_offset); | ||
566 | gcry_mpi_sub (r_prime[i], | ||
567 | r_prime[i], | ||
568 | my_offset); | ||
569 | } | 473 | } |
570 | 474 | ret = gcry_mpi_new (0); | |
571 | // calculate t = sum(ai) | 475 | gcry_mpi_set_ui (ret, ai_bi); |
572 | t = compute_square_sum_mpi_elements (session->sorted_elements, | 476 | return ret; |
573 | count); | ||
574 | // calculate U | ||
575 | u = gcry_mpi_new (0); | ||
576 | tmp = compute_square_sum (r, count); | ||
577 | gcry_mpi_sub (u, u, tmp); | ||
578 | gcry_mpi_release (tmp); | ||
579 | |||
580 | //calculate U' | ||
581 | u_prime = gcry_mpi_new (0); | ||
582 | tmp = compute_square_sum (r_prime, count); | ||
583 | gcry_mpi_sub (u_prime, u_prime, tmp); | ||
584 | |||
585 | GNUNET_assert (p = gcry_mpi_new (0)); | ||
586 | GNUNET_assert (p_prime = gcry_mpi_new (0)); | ||
587 | GNUNET_assert (s = gcry_mpi_new (0)); | ||
588 | GNUNET_assert (s_prime = gcry_mpi_new (0)); | ||
589 | |||
590 | // compute P | ||
591 | GNUNET_CRYPTO_paillier_decrypt (&my_privkey, | ||
592 | &my_pubkey, | ||
593 | &session->s, | ||
594 | s); | ||
595 | GNUNET_CRYPTO_paillier_decrypt (&my_privkey, | ||
596 | &my_pubkey, | ||
597 | &session->s_prime, | ||
598 | s_prime); | ||
599 | |||
600 | // compute P | ||
601 | gcry_mpi_add (p, s, t); | ||
602 | gcry_mpi_add (p, p, u); | ||
603 | |||
604 | // compute P' | ||
605 | gcry_mpi_add (p_prime, s_prime, t); | ||
606 | gcry_mpi_add (p_prime, p_prime, u_prime); | ||
607 | |||
608 | gcry_mpi_release (t); | ||
609 | gcry_mpi_release (u); | ||
610 | gcry_mpi_release (u_prime); | ||
611 | gcry_mpi_release (s); | ||
612 | gcry_mpi_release (s_prime); | ||
613 | |||
614 | // compute product | ||
615 | gcry_mpi_sub (p, p, p_prime); | ||
616 | gcry_mpi_release (p_prime); | ||
617 | tmp = gcry_mpi_set_ui (tmp, 2); | ||
618 | gcry_mpi_div (p, NULL, p, tmp, 0); | ||
619 | |||
620 | gcry_mpi_release (tmp); | ||
621 | for (i = 0; i < count; i++) | ||
622 | { | ||
623 | gcry_mpi_release (session->sorted_elements[i].value); | ||
624 | gcry_mpi_release (r[i]); | ||
625 | gcry_mpi_release (r_prime[i]); | ||
626 | } | ||
627 | GNUNET_free (session->sorted_elements); | ||
628 | session->sorted_elements = NULL; | ||
629 | GNUNET_free (session->r); | ||
630 | session->r = NULL; | ||
631 | GNUNET_free (session->r_prime); | ||
632 | session->r_prime = NULL; | ||
633 | |||
634 | return p; | ||
635 | } | ||
636 | |||
637 | |||
638 | /** | ||
639 | * Handle a multipart chunk of a response we got from another service | ||
640 | * we wanted to calculate a scalarproduct with. | ||
641 | * | ||
642 | * @param cls closure (set from #GNUNET_CADET_connect) | ||
643 | * @param channel connection to the other end | ||
644 | * @param channel_ctx place to store local state associated with the @a channel | ||
645 | * @param message the actual message | ||
646 | * @return #GNUNET_OK to keep the connection open, | ||
647 | * #GNUNET_SYSERR to close it (signal serious error) | ||
648 | */ | ||
649 | static int | ||
650 | handle_bobs_cryptodata_multipart (void *cls, | ||
651 | struct GNUNET_CADET_Channel *channel, | ||
652 | void **channel_ctx, | ||
653 | const struct GNUNET_MessageHeader *message) | ||
654 | { | ||
655 | struct AliceServiceSession *s = *channel_ctx; | ||
656 | const struct BobCryptodataMultipartMessage *msg; | ||
657 | const struct GNUNET_CRYPTO_PaillierCiphertext *payload; | ||
658 | size_t i; | ||
659 | uint32_t contained; | ||
660 | size_t msg_size; | ||
661 | size_t required_size; | ||
662 | |||
663 | if (NULL == s) | ||
664 | { | ||
665 | GNUNET_break_op (0); | ||
666 | return GNUNET_SYSERR; | ||
667 | } | ||
668 | msg_size = ntohs (message->size); | ||
669 | if (sizeof (struct BobCryptodataMultipartMessage) > msg_size) | ||
670 | { | ||
671 | GNUNET_break_op (0); | ||
672 | return GNUNET_SYSERR; | ||
673 | } | ||
674 | msg = (const struct BobCryptodataMultipartMessage *) message; | ||
675 | contained = ntohl (msg->contained_element_count); | ||
676 | required_size = sizeof (struct BobCryptodataMultipartMessage) | ||
677 | + 2 * contained * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext); | ||
678 | if ( (required_size != msg_size) || | ||
679 | (s->cadet_received_element_count + contained > s->used_element_count) ) | ||
680 | { | ||
681 | GNUNET_break (0); | ||
682 | return GNUNET_SYSERR; | ||
683 | } | ||
684 | |||
685 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
686 | "Received %u additional crypto values from Bob\n", | ||
687 | (unsigned int) contained); | ||
688 | |||
689 | payload = (const struct GNUNET_CRYPTO_PaillierCiphertext *) &msg[1]; | ||
690 | /* Convert each k[][perm] to its MPI_value */ | ||
691 | for (i = 0; i < contained; i++) | ||
692 | { | ||
693 | memcpy (&s->r[s->cadet_received_element_count + i], | ||
694 | &payload[2 * i], | ||
695 | sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); | ||
696 | memcpy (&s->r_prime[s->cadet_received_element_count + i], | ||
697 | &payload[2 * i], | ||
698 | sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); | ||
699 | } | ||
700 | s->cadet_received_element_count += contained; | ||
701 | GNUNET_CADET_receive_done (s->channel); | ||
702 | if (s->cadet_received_element_count != s->used_element_count) | ||
703 | return GNUNET_OK; | ||
704 | |||
705 | s->product = compute_scalar_product (s); | ||
706 | transmit_client_response (s); | ||
707 | return GNUNET_OK; | ||
708 | } | 477 | } |
709 | 478 | ||
710 | 479 | ||
@@ -726,12 +495,11 @@ handle_bobs_cryptodata_message (void *cls, | |||
726 | const struct GNUNET_MessageHeader *message) | 495 | const struct GNUNET_MessageHeader *message) |
727 | { | 496 | { |
728 | struct AliceServiceSession *s = *channel_ctx; | 497 | struct AliceServiceSession *s = *channel_ctx; |
729 | const struct BobCryptodataMessage *msg; | 498 | const struct EccBobCryptodataMessage *msg; |
730 | const struct GNUNET_CRYPTO_PaillierCiphertext *payload; | ||
731 | uint32_t i; | ||
732 | uint32_t contained; | 499 | uint32_t contained; |
733 | uint16_t msg_size; | 500 | uint16_t msg_size; |
734 | size_t required_size; | 501 | gcry_mpi_point_t prod_g_i_b_i; |
502 | gcry_mpi_point_t prod_h_i_b_i; | ||
735 | 503 | ||
736 | if (NULL == s) | 504 | if (NULL == s) |
737 | { | 505 | { |
@@ -739,19 +507,14 @@ handle_bobs_cryptodata_message (void *cls, | |||
739 | return GNUNET_SYSERR; | 507 | return GNUNET_SYSERR; |
740 | } | 508 | } |
741 | msg_size = ntohs (message->size); | 509 | msg_size = ntohs (message->size); |
742 | if (sizeof (struct BobCryptodataMessage) > msg_size) | 510 | if (sizeof (struct EccBobCryptodataMessage) > msg_size) |
743 | { | 511 | { |
744 | GNUNET_break_op (0); | 512 | GNUNET_break_op (0); |
745 | return GNUNET_SYSERR; | 513 | return GNUNET_SYSERR; |
746 | } | 514 | } |
747 | msg = (const struct BobCryptodataMessage *) message; | 515 | msg = (const struct EccBobCryptodataMessage *) message; |
748 | contained = ntohl (msg->contained_element_count); | 516 | contained = ntohl (msg->contained_element_count); |
749 | required_size = sizeof (struct BobCryptodataMessage) | 517 | if (2 != contained) |
750 | + 2 * contained * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) | ||
751 | + 2 * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext); | ||
752 | if ( (msg_size != required_size) || | ||
753 | (contained > UINT16_MAX) || | ||
754 | (s->used_element_count < contained) ) | ||
755 | { | 518 | { |
756 | GNUNET_break_op (0); | 519 | GNUNET_break_op (0); |
757 | return GNUNET_SYSERR; | 520 | return GNUNET_SYSERR; |
@@ -771,37 +534,16 @@ handle_bobs_cryptodata_message (void *cls, | |||
771 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 534 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
772 | "Received %u crypto values from Bob\n", | 535 | "Received %u crypto values from Bob\n", |
773 | (unsigned int) contained); | 536 | (unsigned int) contained); |
774 | |||
775 | payload = (const struct GNUNET_CRYPTO_PaillierCiphertext *) &msg[1]; | ||
776 | memcpy (&s->s, | ||
777 | &payload[0], | ||
778 | sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); | ||
779 | memcpy (&s->s_prime, | ||
780 | &payload[1], | ||
781 | sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); | ||
782 | payload = &payload[2]; | ||
783 | |||
784 | s->r = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) * s->used_element_count); | ||
785 | s->r_prime = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) * s->used_element_count); | ||
786 | for (i = 0; i < contained; i++) | ||
787 | { | ||
788 | memcpy (&s->r[i], | ||
789 | &payload[2 * i], | ||
790 | sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); | ||
791 | memcpy (&s->r_prime[i], | ||
792 | &payload[2 * i + 1], | ||
793 | sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); | ||
794 | } | ||
795 | s->cadet_received_element_count = contained; | ||
796 | GNUNET_CADET_receive_done (s->channel); | 537 | GNUNET_CADET_receive_done (s->channel); |
797 | 538 | prod_g_i_b_i = GNUNET_CRYPTO_ecc_bin_to_point (edc, | |
798 | if (s->cadet_received_element_count != s->used_element_count) | 539 | &msg->prod_g_i_b_i); |
799 | { | 540 | prod_h_i_b_i = GNUNET_CRYPTO_ecc_bin_to_point (edc, |
800 | /* More to come */ | 541 | &msg->prod_h_i_b_i); |
801 | return GNUNET_OK; | 542 | s->product = compute_scalar_product (s, |
802 | } | 543 | prod_g_i_b_i, |
803 | 544 | prod_h_i_b_i); | |
804 | s->product = compute_scalar_product (s); | 545 | gcry_mpi_point_release (prod_g_i_b_i); |
546 | gcry_mpi_point_release (prod_h_i_b_i); | ||
805 | transmit_client_response (s); | 547 | transmit_client_response (s); |
806 | return GNUNET_OK; | 548 | return GNUNET_OK; |
807 | } | 549 | } |
@@ -832,6 +574,8 @@ copy_element_cb (void *cls, | |||
832 | else | 574 | else |
833 | gcry_mpi_add_ui (mval, mval, val); | 575 | gcry_mpi_add_ui (mval, mval, val); |
834 | s->sorted_elements [s->used_element_count].value = mval; | 576 | s->sorted_elements [s->used_element_count].value = mval; |
577 | s->sorted_elements [s->used_element_count].r_i | ||
578 | = GNUNET_CRYPTO_ecc_random_mod_n (edc); | ||
835 | s->sorted_elements [s->used_element_count].key = &e->key; | 579 | s->sorted_elements [s->used_element_count].key = &e->key; |
836 | s->used_element_count++; | 580 | s->used_element_count++; |
837 | return GNUNET_OK; | 581 | return GNUNET_OK; |
@@ -861,7 +605,7 @@ element_cmp (const void *a, | |||
861 | * Maximum number of elements we can put into a single cryptodata | 605 | * Maximum number of elements we can put into a single cryptodata |
862 | * message | 606 | * message |
863 | */ | 607 | */ |
864 | #define ELEMENT_CAPACITY ((GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE - 1 - sizeof (struct AliceCryptodataMessage)) / sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)) | 608 | #define ELEMENT_CAPACITY ((GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE - 1 - sizeof (struct EccAliceCryptodataMessage)) / sizeof (struct GNUNET_CRYPTO_EccPoint)) |
865 | 609 | ||
866 | 610 | ||
867 | /** | 611 | /** |
@@ -873,13 +617,16 @@ element_cmp (const void *a, | |||
873 | static void | 617 | static void |
874 | send_alices_cryptodata_message (struct AliceServiceSession *s) | 618 | send_alices_cryptodata_message (struct AliceServiceSession *s) |
875 | { | 619 | { |
876 | struct AliceCryptodataMessage *msg; | 620 | struct EccAliceCryptodataMessage *msg; |
877 | struct GNUNET_MQ_Envelope *e; | 621 | struct GNUNET_MQ_Envelope *e; |
878 | struct GNUNET_CRYPTO_PaillierCiphertext *payload; | 622 | struct GNUNET_CRYPTO_EccPoint *payload; |
623 | gcry_mpi_point_t g_i; | ||
624 | gcry_mpi_point_t h_i; | ||
625 | gcry_mpi_t r_ia; | ||
626 | gcry_mpi_t r_ia_ai; | ||
879 | unsigned int i; | 627 | unsigned int i; |
880 | uint32_t todo_count; | 628 | unsigned int off; |
881 | gcry_mpi_t a; | 629 | unsigned int todo_count; |
882 | uint32_t off; | ||
883 | 630 | ||
884 | s->sorted_elements | 631 | s->sorted_elements |
885 | = GNUNET_malloc (GNUNET_CONTAINER_multihashmap_size (s->intersected_elements) * | 632 | = GNUNET_malloc (GNUNET_CONTAINER_multihashmap_size (s->intersected_elements) * |
@@ -907,23 +654,37 @@ send_alices_cryptodata_message (struct AliceServiceSession *s) | |||
907 | (unsigned int) s->used_element_count); | 654 | (unsigned int) s->used_element_count); |
908 | 655 | ||
909 | e = GNUNET_MQ_msg_extra (msg, | 656 | e = GNUNET_MQ_msg_extra (msg, |
910 | todo_count * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext), | 657 | todo_count * 2 * sizeof (struct GNUNET_CRYPTO_EccPoint), |
911 | GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ALICE_CRYPTODATA); | 658 | GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_ALICE_CRYPTODATA); |
912 | msg->contained_element_count = htonl (todo_count); | 659 | msg->contained_element_count = htonl (todo_count); |
913 | payload = (struct GNUNET_CRYPTO_PaillierCiphertext *) &msg[1]; | 660 | payload = (struct GNUNET_CRYPTO_EccPoint *) &msg[1]; |
914 | a = gcry_mpi_new (0); | 661 | r_ia = gcry_mpi_new (0); |
662 | r_ia_ai = gcry_mpi_new (0); | ||
915 | for (i = off; i < off + todo_count; i++) | 663 | for (i = off; i < off + todo_count; i++) |
916 | { | 664 | { |
917 | gcry_mpi_add (a, | 665 | g_i = GNUNET_CRYPTO_ecc_dexp_mpi (edc, |
666 | s->sorted_elements [i].r_i); | ||
667 | /* r_ia = r_i * a */ | ||
668 | gcry_mpi_mul (s->sorted_elements[i].r_i, | ||
669 | my_privkey, | ||
670 | r_ia); | ||
671 | /* r_ia_ai = r_ia + a_i */ | ||
672 | gcry_mpi_add (r_ia_ai, | ||
918 | s->sorted_elements[i].value, | 673 | s->sorted_elements[i].value, |
919 | my_offset); | 674 | r_ia); |
920 | GNUNET_assert (3 == | 675 | h_i = GNUNET_CRYPTO_ecc_dexp_mpi (edc, |
921 | GNUNET_CRYPTO_paillier_encrypt (&my_pubkey, | 676 | r_ia_ai); |
922 | a, | 677 | GNUNET_CRYPTO_ecc_point_to_bin (edc, |
923 | 3, | 678 | g_i, |
924 | &payload[i - off])); | 679 | &payload[(i - off) * 2]); |
680 | GNUNET_CRYPTO_ecc_point_to_bin (edc, | ||
681 | h_i, | ||
682 | &payload[(i - off) * 2 + 1]); | ||
683 | gcry_mpi_point_release (g_i); | ||
684 | gcry_mpi_point_release (h_i); | ||
925 | } | 685 | } |
926 | gcry_mpi_release (a); | 686 | gcry_mpi_release (r_ia); |
687 | gcry_mpi_release (r_ia_ai); | ||
927 | off += todo_count; | 688 | off += todo_count; |
928 | GNUNET_MQ_send (s->cadet_mq, | 689 | GNUNET_MQ_send (s->cadet_mq, |
929 | e); | 690 | e); |
@@ -1069,7 +830,7 @@ cb_intersection_request_alice (void *cls, | |||
1069 | static void | 830 | static void |
1070 | client_request_complete_alice (struct AliceServiceSession *s) | 831 | client_request_complete_alice (struct AliceServiceSession *s) |
1071 | { | 832 | { |
1072 | struct ServiceRequestMessage *msg; | 833 | struct EccServiceRequestMessage *msg; |
1073 | struct GNUNET_MQ_Envelope *e; | 834 | struct GNUNET_MQ_Envelope *e; |
1074 | 835 | ||
1075 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 836 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -1079,7 +840,7 @@ client_request_complete_alice (struct AliceServiceSession *s) | |||
1079 | = GNUNET_CADET_channel_create (my_cadet, | 840 | = GNUNET_CADET_channel_create (my_cadet, |
1080 | s, | 841 | s, |
1081 | &s->peer, | 842 | &s->peer, |
1082 | GNUNET_APPLICATION_TYPE_SCALARPRODUCT, | 843 | GNUNET_APPLICATION_TYPE_SCALARPRODUCT_ECC, |
1083 | GNUNET_CADET_OPTION_RELIABLE); | 844 | GNUNET_CADET_OPTION_RELIABLE); |
1084 | if (NULL == s->channel) | 845 | if (NULL == s->channel) |
1085 | { | 846 | { |
@@ -1104,9 +865,8 @@ client_request_complete_alice (struct AliceServiceSession *s) | |||
1104 | } | 865 | } |
1105 | 866 | ||
1106 | e = GNUNET_MQ_msg (msg, | 867 | e = GNUNET_MQ_msg (msg, |
1107 | GNUNET_MESSAGE_TYPE_SCALARPRODUCT_SESSION_INITIALIZATION); | 868 | GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_SESSION_INITIALIZATION); |
1108 | msg->session_id = s->session_id; | 869 | msg->session_id = s->session_id; |
1109 | msg->public_key = my_pubkey; | ||
1110 | GNUNET_MQ_send (s->cadet_mq, | 870 | GNUNET_MQ_send (s->cadet_mq, |
1111 | e); | 871 | e); |
1112 | } | 872 | } |
@@ -1327,6 +1087,11 @@ shutdown_task (void *cls, | |||
1327 | GNUNET_CADET_disconnect (my_cadet); | 1087 | GNUNET_CADET_disconnect (my_cadet); |
1328 | my_cadet = NULL; | 1088 | my_cadet = NULL; |
1329 | } | 1089 | } |
1090 | if (NULL != edc) | ||
1091 | { | ||
1092 | GNUNET_CRYPTO_ecc_dlog_release (edc); | ||
1093 | edc = NULL; | ||
1094 | } | ||
1330 | } | 1095 | } |
1331 | 1096 | ||
1332 | 1097 | ||
@@ -1375,10 +1140,7 @@ run (void *cls, | |||
1375 | { | 1140 | { |
1376 | static const struct GNUNET_CADET_MessageHandler cadet_handlers[] = { | 1141 | static const struct GNUNET_CADET_MessageHandler cadet_handlers[] = { |
1377 | { &handle_bobs_cryptodata_message, | 1142 | { &handle_bobs_cryptodata_message, |
1378 | GNUNET_MESSAGE_TYPE_SCALARPRODUCT_BOB_CRYPTODATA, | 1143 | GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_BOB_CRYPTODATA, |
1379 | 0}, | ||
1380 | { &handle_bobs_cryptodata_multipart, | ||
1381 | GNUNET_MESSAGE_TYPE_SCALARPRODUCT_BOB_CRYPTODATA_MULTIPART, | ||
1382 | 0}, | 1144 | 0}, |
1383 | { NULL, 0, 0} | 1145 | { NULL, 0, 0} |
1384 | }; | 1146 | }; |
@@ -1393,16 +1155,12 @@ run (void *cls, | |||
1393 | }; | 1155 | }; |
1394 | 1156 | ||
1395 | cfg = c; | 1157 | cfg = c; |
1396 | /* | 1158 | edc = GNUNET_CRYPTO_ecc_dlog_prepare (MAX_RESULT /* max value */, |
1397 | offset has to be sufficiently small to allow computation of: | 1159 | 1024 /* RAM */); |
1398 | m1+m2 mod n == (S + a) + (S + b) mod n, | 1160 | /* Select a random 'a' value for Alice */ |
1399 | if we have more complex operations, this factor needs to be lowered */ | 1161 | GNUNET_CRYPTO_ecc_rnd_mpi (edc, |
1400 | my_offset = gcry_mpi_new (GNUNET_CRYPTO_PAILLIER_BITS / 3); | 1162 | &my_privkey, |
1401 | gcry_mpi_set_bit (my_offset, | 1163 | &my_privkey_inv); |
1402 | GNUNET_CRYPTO_PAILLIER_BITS / 3); | ||
1403 | |||
1404 | GNUNET_CRYPTO_paillier_create (&my_pubkey, | ||
1405 | &my_privkey); | ||
1406 | GNUNET_SERVER_add_handlers (server, | 1164 | GNUNET_SERVER_add_handlers (server, |
1407 | server_handlers); | 1165 | server_handlers); |
1408 | GNUNET_SERVER_disconnect_notify (server, | 1166 | GNUNET_SERVER_disconnect_notify (server, |
@@ -1445,4 +1203,4 @@ main (int argc, | |||
1445 | &run, NULL)) ? 0 : 1; | 1203 | &run, NULL)) ? 0 : 1; |
1446 | } | 1204 | } |
1447 | 1205 | ||
1448 | /* end of gnunet-service-scalarproduct_alice.c */ | 1206 | /* end of gnunet-service-scalarproduct-ecc_alice.c */ |
diff --git a/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c b/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c index d08f5b858..80a0dc941 100644 --- a/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c +++ b/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2013, 2014 Christian Grothoff (and other contributing authors) | 3 | Copyright (C) 2013-2015 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -18,7 +18,7 @@ | |||
18 | Boston, MA 02110-1301, USA. | 18 | Boston, MA 02110-1301, USA. |
19 | */ | 19 | */ |
20 | /** | 20 | /** |
21 | * @file scalarproduct/gnunet-service-scalarproduct_bob.c | 21 | * @file scalarproduct/gnunet-service-scalarproduct-ecc_bob.c |
22 | * @brief scalarproduct service implementation | 22 | * @brief scalarproduct service implementation |
23 | * @author Christian M. Fuchs | 23 | * @author Christian M. Fuchs |
24 | * @author Christian Grothoff | 24 | * @author Christian Grothoff |
@@ -34,7 +34,7 @@ | |||
34 | #include "gnunet_scalarproduct_service.h" | 34 | #include "gnunet_scalarproduct_service.h" |
35 | #include "gnunet_set_service.h" | 35 | #include "gnunet_set_service.h" |
36 | #include "scalarproduct.h" | 36 | #include "scalarproduct.h" |
37 | #include "gnunet-service-scalarproduct.h" | 37 | #include "gnunet-service-scalarproduct-ecc.h" |
38 | 38 | ||
39 | #define LOG(kind,...) GNUNET_log_from (kind, "scalarproduct-bob", __VA_ARGS__) | 39 | #define LOG(kind,...) GNUNET_log_from (kind, "scalarproduct-bob", __VA_ARGS__) |
40 | 40 | ||
@@ -104,34 +104,19 @@ struct BobServiceSession | |||
104 | struct GNUNET_SET_OperationHandle *intersection_op; | 104 | struct GNUNET_SET_OperationHandle *intersection_op; |
105 | 105 | ||
106 | /** | 106 | /** |
107 | * a(Alice) | 107 | * b(Bob) |
108 | */ | 108 | */ |
109 | struct MpiElement *sorted_elements; | 109 | struct MpiElement *sorted_elements; |
110 | 110 | ||
111 | /** | 111 | /** |
112 | * E(ai)(Bob) after applying the mask | 112 | * Product of the g_i^{b_i} |
113 | */ | 113 | */ |
114 | struct GNUNET_CRYPTO_PaillierCiphertext *e_a; | 114 | gcry_mpi_point_t prod_g_i_b_i; |
115 | 115 | ||
116 | /** | 116 | /** |
117 | * Bob's permutation p of R | 117 | * Product of the h_i^{b_i} |
118 | */ | 118 | */ |
119 | struct GNUNET_CRYPTO_PaillierCiphertext *r; | 119 | gcry_mpi_point_t prod_h_i_b_i; |
120 | |||
121 | /** | ||
122 | * Bob's permutation q of R | ||
123 | */ | ||
124 | struct GNUNET_CRYPTO_PaillierCiphertext *r_prime; | ||
125 | |||
126 | /** | ||
127 | * Bob's "s" | ||
128 | */ | ||
129 | struct GNUNET_CRYPTO_PaillierCiphertext s; | ||
130 | |||
131 | /** | ||
132 | * Bob's "s'" | ||
133 | */ | ||
134 | struct GNUNET_CRYPTO_PaillierCiphertext s_prime; | ||
135 | 120 | ||
136 | /** | 121 | /** |
137 | * Handle for our associated incoming CADET session, or NULL | 122 | * Handle for our associated incoming CADET session, or NULL |
@@ -140,11 +125,6 @@ struct BobServiceSession | |||
140 | struct CadetIncomingSession *cadet; | 125 | struct CadetIncomingSession *cadet; |
141 | 126 | ||
142 | /** | 127 | /** |
143 | * The computed scalar | ||
144 | */ | ||
145 | gcry_mpi_t product; | ||
146 | |||
147 | /** | ||
148 | * How many elements will be supplied in total from the client. | 128 | * How many elements will be supplied in total from the client. |
149 | */ | 129 | */ |
150 | uint32_t total; | 130 | uint32_t total; |
@@ -169,12 +149,6 @@ struct BobServiceSession | |||
169 | uint32_t cadet_received_element_count; | 149 | uint32_t cadet_received_element_count; |
170 | 150 | ||
171 | /** | 151 | /** |
172 | * Counts the number of values transmitted from us to Alice. | ||
173 | * Always less than @e used_element_count. | ||
174 | */ | ||
175 | uint32_t cadet_transmitted_element_count; | ||
176 | |||
177 | /** | ||
178 | * State of this session. In | 152 | * State of this session. In |
179 | * #GNUNET_SCALARPRODUCT_STATUS_ACTIVE while operation is | 153 | * #GNUNET_SCALARPRODUCT_STATUS_ACTIVE while operation is |
180 | * ongoing, afterwards in #GNUNET_SCALARPRODUCT_STATUS_SUCCESS or | 154 | * ongoing, afterwards in #GNUNET_SCALARPRODUCT_STATUS_SUCCESS or |
@@ -217,11 +191,6 @@ struct CadetIncomingSession | |||
217 | struct GNUNET_HashCode session_id; | 191 | struct GNUNET_HashCode session_id; |
218 | 192 | ||
219 | /** | 193 | /** |
220 | * Public key of the remote service. | ||
221 | */ | ||
222 | struct GNUNET_CRYPTO_PaillierPublicKey remote_pubkey; | ||
223 | |||
224 | /** | ||
225 | * The message queue for this channel. | 194 | * The message queue for this channel. |
226 | */ | 195 | */ |
227 | struct GNUNET_MQ_Handle *cadet_mq; | 196 | struct GNUNET_MQ_Handle *cadet_mq; |
@@ -247,21 +216,6 @@ struct CadetIncomingSession | |||
247 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | 216 | static const struct GNUNET_CONFIGURATION_Handle *cfg; |
248 | 217 | ||
249 | /** | 218 | /** |
250 | * Service's own public key | ||
251 | */ | ||
252 | static struct GNUNET_CRYPTO_PaillierPublicKey my_pubkey; | ||
253 | |||
254 | /** | ||
255 | * Service's own private key | ||
256 | */ | ||
257 | static struct GNUNET_CRYPTO_PaillierPrivateKey my_privkey; | ||
258 | |||
259 | /** | ||
260 | * Service's offset for values that could possibly be negative but are plaintext for encryption. | ||
261 | */ | ||
262 | static gcry_mpi_t my_offset; | ||
263 | |||
264 | /** | ||
265 | * Map of `struct BobServiceSession`, by session keys. | 219 | * Map of `struct BobServiceSession`, by session keys. |
266 | */ | 220 | */ |
267 | static struct GNUNET_CONTAINER_MultiHashMap *client_sessions; | 221 | static struct GNUNET_CONTAINER_MultiHashMap *client_sessions; |
@@ -276,6 +230,11 @@ static struct GNUNET_CONTAINER_MultiHashMap *cadet_sessions; | |||
276 | */ | 230 | */ |
277 | static struct GNUNET_CADET_Handle *my_cadet; | 231 | static struct GNUNET_CADET_Handle *my_cadet; |
278 | 232 | ||
233 | /** | ||
234 | * Context for DLOG operations on a curve. | ||
235 | */ | ||
236 | static struct GNUNET_CRYPTO_EccDlogContext *edc; | ||
237 | |||
279 | 238 | ||
280 | 239 | ||
281 | /** | 240 | /** |
@@ -386,11 +345,6 @@ destroy_service_session (struct BobServiceSession *s) | |||
386 | GNUNET_SET_destroy (s->intersection_set); | 345 | GNUNET_SET_destroy (s->intersection_set); |
387 | s->intersection_set = NULL; | 346 | s->intersection_set = NULL; |
388 | } | 347 | } |
389 | if (NULL != s->e_a) | ||
390 | { | ||
391 | GNUNET_free (s->e_a); | ||
392 | s->e_a = NULL; | ||
393 | } | ||
394 | if (NULL != s->sorted_elements) | 348 | if (NULL != s->sorted_elements) |
395 | { | 349 | { |
396 | for (i=0;i<s->used_element_count;i++) | 350 | for (i=0;i<s->used_element_count;i++) |
@@ -398,20 +352,15 @@ destroy_service_session (struct BobServiceSession *s) | |||
398 | GNUNET_free (s->sorted_elements); | 352 | GNUNET_free (s->sorted_elements); |
399 | s->sorted_elements = NULL; | 353 | s->sorted_elements = NULL; |
400 | } | 354 | } |
401 | if (NULL != s->r) | 355 | if (NULL != s->prod_g_i_b_i) |
402 | { | 356 | { |
403 | GNUNET_free (s->r); | 357 | gcry_mpi_point_release (s->prod_g_i_b_i); |
404 | s->r = NULL; | 358 | s->prod_g_i_b_i = NULL; |
405 | } | 359 | } |
406 | if (NULL != s->r_prime) | 360 | if (NULL != s->prod_g_i_b_i) |
407 | { | 361 | { |
408 | GNUNET_free (s->r_prime); | 362 | gcry_mpi_point_release (s->prod_h_i_b_i); |
409 | s->r_prime = NULL; | 363 | s->prod_h_i_b_i = NULL; |
410 | } | ||
411 | if (NULL != s->product) | ||
412 | { | ||
413 | gcry_mpi_release (s->product); | ||
414 | s->product = NULL; | ||
415 | } | 364 | } |
416 | GNUNET_free (s); | 365 | GNUNET_free (s); |
417 | } | 366 | } |
@@ -540,306 +489,34 @@ bob_cadet_done_cb (void *cls) | |||
540 | 489 | ||
541 | 490 | ||
542 | /** | 491 | /** |
543 | * Maximum count of elements we can put into a multipart message | 492 | * Bob generates the response message to be sent to Alice. |
544 | */ | ||
545 | #define ELEMENT_CAPACITY ((GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE - 1 - sizeof (struct BobCryptodataMultipartMessage)) / sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)) | ||
546 | |||
547 | |||
548 | /** | ||
549 | * Send a multipart chunk of a service response from Bob to Alice. | ||
550 | * This element only contains the two permutations of R, R'. | ||
551 | * | ||
552 | * @param s the associated service session | ||
553 | */ | ||
554 | static void | ||
555 | transmit_bobs_cryptodata_message_multipart (struct BobServiceSession *s) | ||
556 | { | ||
557 | struct GNUNET_CRYPTO_PaillierCiphertext *payload; | ||
558 | struct BobCryptodataMultipartMessage *msg; | ||
559 | struct GNUNET_MQ_Envelope *e; | ||
560 | unsigned int i; | ||
561 | unsigned int j; | ||
562 | uint32_t todo_count; | ||
563 | |||
564 | while (s->cadet_transmitted_element_count != s->used_element_count) | ||
565 | { | ||
566 | todo_count = s->used_element_count - s->cadet_transmitted_element_count; | ||
567 | if (todo_count > ELEMENT_CAPACITY / 2) | ||
568 | todo_count = ELEMENT_CAPACITY / 2; | ||
569 | |||
570 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
571 | "Sending %u additional crypto values to Alice\n", | ||
572 | (unsigned int) todo_count); | ||
573 | e = GNUNET_MQ_msg_extra (msg, | ||
574 | todo_count * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) * 2, | ||
575 | GNUNET_MESSAGE_TYPE_SCALARPRODUCT_BOB_CRYPTODATA_MULTIPART); | ||
576 | msg->contained_element_count = htonl (todo_count); | ||
577 | payload = (struct GNUNET_CRYPTO_PaillierCiphertext *) &msg[1]; | ||
578 | for (i = s->cadet_transmitted_element_count, j = 0; i < s->cadet_transmitted_element_count + todo_count; i++) | ||
579 | { | ||
580 | //r[i][p] and r[i][q] | ||
581 | memcpy (&payload[j++], | ||
582 | &s->r[i], | ||
583 | sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); | ||
584 | memcpy (&payload[j++], | ||
585 | &s->r_prime[i], | ||
586 | sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); | ||
587 | } | ||
588 | s->cadet_transmitted_element_count += todo_count; | ||
589 | if (s->cadet_transmitted_element_count == s->used_element_count) | ||
590 | GNUNET_MQ_notify_sent (e, | ||
591 | &bob_cadet_done_cb, | ||
592 | s); | ||
593 | GNUNET_MQ_send (s->cadet->cadet_mq, | ||
594 | e); | ||
595 | } | ||
596 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
597 | "All values queued for Alice, Bob is done\n"); | ||
598 | } | ||
599 | |||
600 | |||
601 | /** | ||
602 | * Bob generates the response message to be sent to Alice after | ||
603 | * computing the values (1), (2), S and S'. | ||
604 | * | ||
605 | * (1)[]: $E_A(a_{pi(i)}) times E_A(- r_{pi(i)} - b_{pi(i)}) &= E_A(a_{pi(i)} - r_{pi(i)} - b_{pi(i)})$ | ||
606 | * (2)[]: $E_A(a_{pi'(i)}) times E_A(- r_{pi'(i)}) &= E_A(a_{pi'(i)} - r_{pi'(i)})$ | ||
607 | * S: $S := E_A(sum (r_i + b_i)^2)$ | ||
608 | * S': $S' := E_A(sum r_i^2)$ | ||
609 | * | 493 | * |
610 | * @param s the associated requesting session with Alice | 494 | * @param s the associated requesting session with Alice |
611 | */ | 495 | */ |
612 | static void | 496 | static void |
613 | transmit_bobs_cryptodata_message (struct BobServiceSession *s) | 497 | transmit_bobs_cryptodata_message (struct BobServiceSession *s) |
614 | { | 498 | { |
615 | struct BobCryptodataMessage *msg; | 499 | struct EccBobCryptodataMessage *msg; |
616 | struct GNUNET_MQ_Envelope *e; | 500 | struct GNUNET_MQ_Envelope *e; |
617 | struct GNUNET_CRYPTO_PaillierCiphertext *payload; | ||
618 | unsigned int i; | ||
619 | |||
620 | s->cadet_transmitted_element_count | ||
621 | = ((GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE - 1 - sizeof (struct BobCryptodataMessage)) | ||
622 | / sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) / 2) - 1; | ||
623 | if (s->cadet_transmitted_element_count > s->used_element_count) | ||
624 | s->cadet_transmitted_element_count = s->used_element_count; | ||
625 | |||
626 | e = GNUNET_MQ_msg_extra (msg, | ||
627 | (2 + s->cadet_transmitted_element_count * 2) | ||
628 | * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext), | ||
629 | GNUNET_MESSAGE_TYPE_SCALARPRODUCT_BOB_CRYPTODATA); | ||
630 | msg->contained_element_count = htonl (s->cadet_transmitted_element_count); | ||
631 | 501 | ||
632 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 502 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
633 | "Sending %u/%u crypto values to Alice\n", | 503 | "Sending response to Alice\n"); |
634 | (unsigned int) s->cadet_transmitted_element_count, | 504 | e = GNUNET_MQ_msg (msg, |
635 | (unsigned int) s->used_element_count); | 505 | GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_BOB_CRYPTODATA); |
636 | 506 | msg->contained_element_count = htonl (2); | |
637 | payload = (struct GNUNET_CRYPTO_PaillierCiphertext *) &msg[1]; | 507 | if (NULL != s->prod_g_i_b_i) |
638 | memcpy (&payload[0], | 508 | GNUNET_CRYPTO_ecc_point_to_bin (edc, |
639 | &s->s, | 509 | s->prod_g_i_b_i, |
640 | sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); | 510 | &msg->prod_g_i_b_i); |
641 | memcpy (&payload[1], | 511 | if (NULL != s->prod_h_i_b_i) |
642 | &s->s_prime, | 512 | GNUNET_CRYPTO_ecc_point_to_bin (edc, |
643 | sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); | 513 | s->prod_h_i_b_i, |
644 | 514 | &msg->prod_h_i_b_i); | |
645 | payload = &payload[2]; | 515 | GNUNET_MQ_notify_sent (e, |
646 | // convert k[][] | 516 | &bob_cadet_done_cb, |
647 | for (i = 0; i < s->cadet_transmitted_element_count; i++) | 517 | s); |
648 | { | ||
649 | //k[i][p] and k[i][q] | ||
650 | memcpy (&payload[i * 2], | ||
651 | &s->r[i], | ||
652 | sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); | ||
653 | memcpy (&payload[i * 2 + 1], | ||
654 | &s->r_prime[i], | ||
655 | sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); | ||
656 | } | ||
657 | if (s->cadet_transmitted_element_count == s->used_element_count) | ||
658 | GNUNET_MQ_notify_sent (e, | ||
659 | &bob_cadet_done_cb, | ||
660 | s); | ||
661 | GNUNET_MQ_send (s->cadet->cadet_mq, | 518 | GNUNET_MQ_send (s->cadet->cadet_mq, |
662 | e); | 519 | e); |
663 | transmit_bobs_cryptodata_message_multipart (s); | ||
664 | } | ||
665 | #undef ELEMENT_CAPACITY | ||
666 | |||
667 | |||
668 | /** | ||
669 | * Computes the square sum over a vector of a given length. | ||
670 | * | ||
671 | * @param vector the vector to compute over | ||
672 | * @param length the length of the vector | ||
673 | * @return an MPI value containing the calculated sum, never NULL | ||
674 | * TODO: code duplication with Alice! | ||
675 | */ | ||
676 | static gcry_mpi_t | ||
677 | compute_square_sum (const gcry_mpi_t *vector, | ||
678 | uint32_t length) | ||
679 | { | ||
680 | gcry_mpi_t elem; | ||
681 | gcry_mpi_t sum; | ||
682 | uint32_t i; | ||
683 | |||
684 | GNUNET_assert (NULL != (sum = gcry_mpi_new (0))); | ||
685 | GNUNET_assert (NULL != (elem = gcry_mpi_new (0))); | ||
686 | for (i = 0; i < length; i++) | ||
687 | { | ||
688 | gcry_mpi_mul (elem, vector[i], vector[i]); | ||
689 | gcry_mpi_add (sum, sum, elem); | ||
690 | } | ||
691 | gcry_mpi_release (elem); | ||
692 | return sum; | ||
693 | } | ||
694 | |||
695 | |||
696 | /** | ||
697 | * Compute the values | ||
698 | * (1)[]: $E_A(a_{pi(i)}) otimes E_A(- r_{pi(i)} - b_{pi(i)}) &= E_A(a_{pi(i)} - r_{pi(i)} - b_{pi(i)})$ | ||
699 | * (2)[]: $E_A(a_{pi'(i)}) otimes E_A(- r_{pi'(i)}) &= E_A(a_{pi'(i)} - r_{pi'(i)})$ | ||
700 | * S: $S := E_A(sum (r_i + b_i)^2)$ | ||
701 | * S': $S' := E_A(sum r_i^2)$ | ||
702 | * | ||
703 | * @param request the requesting session + bob's requesting peer | ||
704 | * @return #GNUNET_OK on success | ||
705 | */ | ||
706 | static int | ||
707 | compute_service_response (struct BobServiceSession *session) | ||
708 | { | ||
709 | uint32_t i; | ||
710 | unsigned int *p; | ||
711 | unsigned int *q; | ||
712 | uint32_t count; | ||
713 | gcry_mpi_t *rand; | ||
714 | gcry_mpi_t tmp; | ||
715 | const struct MpiElement *b; | ||
716 | struct GNUNET_CRYPTO_PaillierCiphertext *a; | ||
717 | struct GNUNET_CRYPTO_PaillierCiphertext *r; | ||
718 | struct GNUNET_CRYPTO_PaillierCiphertext *r_prime; | ||
719 | |||
720 | count = session->used_element_count; | ||
721 | a = session->e_a; | ||
722 | b = session->sorted_elements; | ||
723 | q = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_WEAK, | ||
724 | count); | ||
725 | p = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_WEAK, | ||
726 | count); | ||
727 | rand = GNUNET_malloc (sizeof (gcry_mpi_t) * count); | ||
728 | for (i = 0; i < count; i++) | ||
729 | GNUNET_assert (NULL != (rand[i] = gcry_mpi_new (0))); | ||
730 | r = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) * count); | ||
731 | r_prime = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) * count); | ||
732 | |||
733 | for (i = 0; i < count; i++) | ||
734 | { | ||
735 | int32_t svalue; | ||
736 | |||
737 | svalue = (int32_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, | ||
738 | UINT32_MAX); | ||
739 | // long to gcry_mpi_t | ||
740 | if (svalue < 0) | ||
741 | gcry_mpi_sub_ui (rand[i], | ||
742 | rand[i], | ||
743 | - svalue); | ||
744 | else | ||
745 | rand[i] = gcry_mpi_set_ui (rand[i], svalue); | ||
746 | } | ||
747 | |||
748 | tmp = gcry_mpi_new (0); | ||
749 | // encrypt the element | ||
750 | // for the sake of readability I decided to have dedicated permutation | ||
751 | // vectors, which get rid of all the lookups in p/q. | ||
752 | // however, ap/aq are not absolutely necessary but are just abstraction | ||
753 | // Calculate Kp = E(S + a_pi) (+) E(S - r_pi - b_pi) | ||
754 | for (i = 0; i < count; i++) | ||
755 | { | ||
756 | // E(S - r_pi - b_pi) | ||
757 | gcry_mpi_sub (tmp, my_offset, rand[p[i]]); | ||
758 | gcry_mpi_sub (tmp, tmp, b[p[i]].value); | ||
759 | GNUNET_assert (2 == | ||
760 | GNUNET_CRYPTO_paillier_encrypt (&session->cadet->remote_pubkey, | ||
761 | tmp, | ||
762 | 2, | ||
763 | &r[i])); | ||
764 | |||
765 | // E(S - r_pi - b_pi) * E(S + a_pi) == E(2*S + a - r - b) | ||
766 | if (GNUNET_OK != | ||
767 | GNUNET_CRYPTO_paillier_hom_add (&session->cadet->remote_pubkey, | ||
768 | &r[i], | ||
769 | &a[p[i]], | ||
770 | &r[i])) | ||
771 | { | ||
772 | GNUNET_break_op (0); | ||
773 | goto error_cleanup; | ||
774 | } | ||
775 | } | ||
776 | |||
777 | // Calculate Kq = E(S + a_qi) (+) E(S - r_qi) | ||
778 | for (i = 0; i < count; i++) | ||
779 | { | ||
780 | // E(S - r_qi) | ||
781 | gcry_mpi_sub (tmp, my_offset, rand[q[i]]); | ||
782 | GNUNET_assert (2 == | ||
783 | GNUNET_CRYPTO_paillier_encrypt (&session->cadet->remote_pubkey, | ||
784 | tmp, | ||
785 | 2, | ||
786 | &r_prime[i])); | ||
787 | |||
788 | // E(S - r_qi) * E(S + a_qi) == E(2*S + a_qi - r_qi) | ||
789 | if (GNUNET_OK != | ||
790 | GNUNET_CRYPTO_paillier_hom_add (&session->cadet->remote_pubkey, | ||
791 | &r_prime[i], | ||
792 | &a[q[i]], | ||
793 | &r_prime[i])) | ||
794 | { | ||
795 | GNUNET_break_op (0); | ||
796 | goto error_cleanup; | ||
797 | } | ||
798 | } | ||
799 | gcry_mpi_release (tmp); | ||
800 | |||
801 | // Calculate S' = E(SUM( r_i^2 )) | ||
802 | tmp = compute_square_sum (rand, count); | ||
803 | GNUNET_assert (1 == | ||
804 | GNUNET_CRYPTO_paillier_encrypt (&session->cadet->remote_pubkey, | ||
805 | tmp, | ||
806 | 1, | ||
807 | &session->s_prime)); | ||
808 | gcry_mpi_release (tmp); | ||
809 | |||
810 | // Calculate S = E(SUM( (r_i + b_i)^2 )) | ||
811 | for (i = 0; i < count; i++) | ||
812 | gcry_mpi_add (rand[i], rand[i], b[i].value); | ||
813 | tmp = compute_square_sum (rand, count); | ||
814 | GNUNET_assert (1 == | ||
815 | GNUNET_CRYPTO_paillier_encrypt (&session->cadet->remote_pubkey, | ||
816 | tmp, | ||
817 | 1, | ||
818 | &session->s)); | ||
819 | gcry_mpi_release (tmp); | ||
820 | |||
821 | session->r = r; | ||
822 | session->r_prime = r_prime; | ||
823 | |||
824 | for (i = 0; i < count; i++) | ||
825 | gcry_mpi_release (rand[i]); | ||
826 | GNUNET_free (session->e_a); | ||
827 | session->e_a = NULL; | ||
828 | GNUNET_free (p); | ||
829 | GNUNET_free (q); | ||
830 | GNUNET_free (rand); | ||
831 | return GNUNET_OK; | ||
832 | |||
833 | error_cleanup: | ||
834 | GNUNET_free (r); | ||
835 | GNUNET_free (r_prime); | ||
836 | gcry_mpi_release (tmp); | ||
837 | GNUNET_free (p); | ||
838 | GNUNET_free (q); | ||
839 | for (i = 0; i < count; i++) | ||
840 | gcry_mpi_release (rand[i]); | ||
841 | GNUNET_free (rand); | ||
842 | return GNUNET_SYSERR; | ||
843 | } | 520 | } |
844 | 521 | ||
845 | 522 | ||
@@ -896,44 +573,6 @@ element_cmp (const void *a, | |||
896 | 573 | ||
897 | 574 | ||
898 | /** | 575 | /** |
899 | * Intersection operation and receiving data via CADET from | ||
900 | * Alice are both done, compute and transmit our reply via | ||
901 | * CADET. | ||
902 | * | ||
903 | * @param s session to transmit reply for. | ||
904 | */ | ||
905 | static void | ||
906 | transmit_cryptographic_reply (struct BobServiceSession *s) | ||
907 | { | ||
908 | struct GNUNET_CADET_Channel *channel; | ||
909 | |||
910 | /* TODO: code duplication with Alice! */ | ||
911 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
912 | "Received everything, building reply for Alice\n"); | ||
913 | s->sorted_elements | ||
914 | = GNUNET_malloc (GNUNET_CONTAINER_multihashmap_size (s->intersected_elements) * | ||
915 | sizeof (struct MpiElement)); | ||
916 | s->used_element_count = 0; | ||
917 | GNUNET_CONTAINER_multihashmap_iterate (s->intersected_elements, | ||
918 | ©_element_cb, | ||
919 | s); | ||
920 | qsort (s->sorted_elements, | ||
921 | s->used_element_count, | ||
922 | sizeof (struct MpiElement), | ||
923 | &element_cmp); | ||
924 | if (GNUNET_OK != | ||
925 | compute_service_response (s)) | ||
926 | { | ||
927 | channel = s->cadet->channel; | ||
928 | s->cadet->channel = NULL; | ||
929 | GNUNET_CADET_channel_destroy (channel); | ||
930 | return; | ||
931 | } | ||
932 | transmit_bobs_cryptodata_message (s); | ||
933 | } | ||
934 | |||
935 | |||
936 | /** | ||
937 | * Handle a multipart-chunk of a request from another service to | 576 | * Handle a multipart-chunk of a request from another service to |
938 | * calculate a scalarproduct with us. | 577 | * calculate a scalarproduct with us. |
939 | * | 578 | * |
@@ -952,13 +591,21 @@ handle_alices_cryptodata_message (void *cls, | |||
952 | { | 591 | { |
953 | struct CadetIncomingSession *in = *channel_ctx; | 592 | struct CadetIncomingSession *in = *channel_ctx; |
954 | struct BobServiceSession *s; | 593 | struct BobServiceSession *s; |
955 | const struct AliceCryptodataMessage *msg; | 594 | const struct EccAliceCryptodataMessage *msg; |
956 | const struct GNUNET_CRYPTO_PaillierCiphertext *payload; | 595 | const struct GNUNET_CRYPTO_EccPoint *payload; |
957 | uint32_t contained_elements; | 596 | uint32_t contained_elements; |
958 | size_t msg_length; | 597 | size_t msg_length; |
959 | uint16_t msize; | 598 | uint16_t msize; |
960 | unsigned int max; | 599 | unsigned int max; |
961 | 600 | unsigned int i; | |
601 | const struct MpiElement *b_i; | ||
602 | gcry_mpi_point_t tmp; | ||
603 | gcry_mpi_point_t g_i; | ||
604 | gcry_mpi_point_t h_i; | ||
605 | gcry_mpi_point_t g_i_b_i; | ||
606 | gcry_mpi_point_t h_i_b_i; | ||
607 | |||
608 | /* sanity checks */ | ||
962 | if (NULL == in) | 609 | if (NULL == in) |
963 | { | 610 | { |
964 | GNUNET_break_op (0); | 611 | GNUNET_break_op (0); |
@@ -970,19 +617,36 @@ handle_alices_cryptodata_message (void *cls, | |||
970 | GNUNET_break_op (0); | 617 | GNUNET_break_op (0); |
971 | return GNUNET_SYSERR; | 618 | return GNUNET_SYSERR; |
972 | } | 619 | } |
620 | /* sort our vector for the computation */ | ||
621 | if (NULL == s->sorted_elements) | ||
622 | { | ||
623 | s->sorted_elements | ||
624 | = GNUNET_malloc (GNUNET_CONTAINER_multihashmap_size (s->intersected_elements) * | ||
625 | sizeof (struct MpiElement)); | ||
626 | s->used_element_count = 0; | ||
627 | GNUNET_CONTAINER_multihashmap_iterate (s->intersected_elements, | ||
628 | ©_element_cb, | ||
629 | s); | ||
630 | qsort (s->sorted_elements, | ||
631 | s->used_element_count, | ||
632 | sizeof (struct MpiElement), | ||
633 | &element_cmp); | ||
634 | } | ||
635 | |||
636 | /* parse message */ | ||
973 | msize = ntohs (message->size); | 637 | msize = ntohs (message->size); |
974 | if (msize <= sizeof (struct AliceCryptodataMessage)) | 638 | if (msize <= sizeof (struct EccAliceCryptodataMessage)) |
975 | { | 639 | { |
976 | GNUNET_break_op (0); | 640 | GNUNET_break_op (0); |
977 | return GNUNET_SYSERR; | 641 | return GNUNET_SYSERR; |
978 | } | 642 | } |
979 | msg = (const struct AliceCryptodataMessage *) message; | 643 | msg = (const struct EccAliceCryptodataMessage *) message; |
980 | contained_elements = ntohl (msg->contained_element_count); | 644 | contained_elements = ntohl (msg->contained_element_count); |
981 | /* Our intersection may still be ongoing, but this is nevertheless | 645 | /* Our intersection may still be ongoing, but this is nevertheless |
982 | an upper bound on the required array size */ | 646 | an upper bound on the required array size */ |
983 | max = GNUNET_CONTAINER_multihashmap_size (s->intersected_elements); | 647 | max = GNUNET_CONTAINER_multihashmap_size (s->intersected_elements); |
984 | msg_length = sizeof (struct AliceCryptodataMessage) | 648 | msg_length = sizeof (struct EccAliceCryptodataMessage) |
985 | + contained_elements * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext); | 649 | + contained_elements * sizeof (struct GNUNET_CRYPTO_EccPoint); |
986 | if ( (msize != msg_length) || | 650 | if ( (msize != msg_length) || |
987 | (0 == contained_elements) || | 651 | (0 == contained_elements) || |
988 | (contained_elements > UINT16_MAX) || | 652 | (contained_elements > UINT16_MAX) || |
@@ -994,23 +658,54 @@ handle_alices_cryptodata_message (void *cls, | |||
994 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 658 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
995 | "Received %u crypto values from Alice\n", | 659 | "Received %u crypto values from Alice\n", |
996 | (unsigned int) contained_elements); | 660 | (unsigned int) contained_elements); |
661 | payload = (const struct GNUNET_CRYPTO_EccPoint *) &msg[1]; | ||
997 | 662 | ||
998 | payload = (const struct GNUNET_CRYPTO_PaillierCiphertext *) &msg[1]; | 663 | for (i=0;i<contained_elements;i++) |
999 | if (NULL == s->e_a) | 664 | { |
1000 | s->e_a = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) * | 665 | b_i = &s->sorted_elements[i + s->cadet_received_element_count]; |
1001 | max); | 666 | g_i = GNUNET_CRYPTO_ecc_bin_to_point (edc, |
1002 | memcpy (&s->e_a[s->cadet_received_element_count], | 667 | &payload[i * 2]); |
1003 | payload, | 668 | g_i_b_i = GNUNET_CRYPTO_ecc_pmul_mpi (edc, |
1004 | sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) * contained_elements); | 669 | g_i, |
670 | b_i->value); | ||
671 | gcry_mpi_point_release (g_i); | ||
672 | h_i = GNUNET_CRYPTO_ecc_bin_to_point (edc, | ||
673 | &payload[i * 2 + 1]); | ||
674 | h_i_b_i = GNUNET_CRYPTO_ecc_pmul_mpi (edc, | ||
675 | h_i, | ||
676 | b_i->value); | ||
677 | gcry_mpi_point_release (h_i); | ||
678 | if (0 == i + s->cadet_received_element_count) | ||
679 | { | ||
680 | /* first iteration, nothing to add */ | ||
681 | s->prod_g_i_b_i = g_i_b_i; | ||
682 | s->prod_h_i_b_i = h_i_b_i; | ||
683 | } | ||
684 | else | ||
685 | { | ||
686 | /* further iterations, cummulate resulting value */ | ||
687 | tmp = GNUNET_CRYPTO_ecc_add (edc, | ||
688 | s->prod_g_i_b_i, | ||
689 | g_i_b_i); | ||
690 | gcry_mpi_point_release (s->prod_g_i_b_i); | ||
691 | gcry_mpi_point_release (g_i_b_i); | ||
692 | s->prod_g_i_b_i = tmp; | ||
693 | tmp = GNUNET_CRYPTO_ecc_add (edc, | ||
694 | s->prod_h_i_b_i, | ||
695 | h_i_b_i); | ||
696 | gcry_mpi_point_release (s->prod_h_i_b_i); | ||
697 | gcry_mpi_point_release (h_i_b_i); | ||
698 | s->prod_h_i_b_i = tmp; | ||
699 | } | ||
700 | } | ||
1005 | s->cadet_received_element_count += contained_elements; | 701 | s->cadet_received_element_count += contained_elements; |
1006 | |||
1007 | if ( (s->cadet_received_element_count == max) && | 702 | if ( (s->cadet_received_element_count == max) && |
1008 | (NULL == s->intersection_op) ) | 703 | (NULL == s->intersection_op) ) |
1009 | { | 704 | { |
1010 | /* intersection has finished also on our side, and | 705 | /* intersection has finished also on our side, and |
1011 | we got the full set, so we can proceed with the | 706 | we got the full set, so we can proceed with the |
1012 | CADET response(s) */ | 707 | CADET response(s) */ |
1013 | transmit_cryptographic_reply (s); | 708 | transmit_bobs_cryptodata_message (s); |
1014 | } | 709 | } |
1015 | GNUNET_CADET_receive_done (s->cadet->channel); | 710 | GNUNET_CADET_receive_done (s->cadet->channel); |
1016 | return GNUNET_OK; | 711 | return GNUNET_OK; |
@@ -1062,7 +757,7 @@ cb_intersection_element_removed (void *cls, | |||
1062 | { | 757 | { |
1063 | /* CADET transmission from Alice is also already done, | 758 | /* CADET transmission from Alice is also already done, |
1064 | start with our own reply */ | 759 | start with our own reply */ |
1065 | transmit_cryptographic_reply (s); | 760 | transmit_bobs_cryptodata_message (s); |
1066 | } | 761 | } |
1067 | return; | 762 | return; |
1068 | case GNUNET_SET_STATUS_HALF_DONE: | 763 | case GNUNET_SET_STATUS_HALF_DONE: |
@@ -1142,14 +837,9 @@ handle_alices_computation_request (void *cls, | |||
1142 | { | 837 | { |
1143 | struct CadetIncomingSession *in = *channel_ctx; | 838 | struct CadetIncomingSession *in = *channel_ctx; |
1144 | struct BobServiceSession *s; | 839 | struct BobServiceSession *s; |
1145 | const struct ServiceRequestMessage *msg; | 840 | const struct EccServiceRequestMessage *msg; |
1146 | 841 | ||
1147 | if (ntohs (message->size) != sizeof (struct ServiceRequestMessage)) | 842 | msg = (const struct EccServiceRequestMessage *) message; |
1148 | { | ||
1149 | GNUNET_break_op (0); | ||
1150 | return GNUNET_SYSERR; | ||
1151 | } | ||
1152 | msg = (const struct ServiceRequestMessage *) message; | ||
1153 | if (GNUNET_YES == in->in_map) | 843 | if (GNUNET_YES == in->in_map) |
1154 | { | 844 | { |
1155 | GNUNET_break_op (0); | 845 | GNUNET_break_op (0); |
@@ -1162,7 +852,6 @@ handle_alices_computation_request (void *cls, | |||
1162 | return GNUNET_SYSERR; | 852 | return GNUNET_SYSERR; |
1163 | } | 853 | } |
1164 | in->session_id = msg->session_id; | 854 | in->session_id = msg->session_id; |
1165 | in->remote_pubkey = msg->public_key; | ||
1166 | GNUNET_assert (GNUNET_YES == | 855 | GNUNET_assert (GNUNET_YES == |
1167 | GNUNET_CONTAINER_multihashmap_put (cadet_sessions, | 856 | GNUNET_CONTAINER_multihashmap_put (cadet_sessions, |
1168 | &in->session_id, | 857 | &in->session_id, |
@@ -1462,6 +1151,11 @@ shutdown_task (void *cls, | |||
1462 | GNUNET_CADET_disconnect (my_cadet); | 1151 | GNUNET_CADET_disconnect (my_cadet); |
1463 | my_cadet = NULL; | 1152 | my_cadet = NULL; |
1464 | } | 1153 | } |
1154 | if (NULL != edc) | ||
1155 | { | ||
1156 | GNUNET_CRYPTO_ecc_dlog_release (edc); | ||
1157 | edc = NULL; | ||
1158 | } | ||
1465 | GNUNET_CONTAINER_multihashmap_destroy (client_sessions); | 1159 | GNUNET_CONTAINER_multihashmap_destroy (client_sessions); |
1466 | client_sessions = NULL; | 1160 | client_sessions = NULL; |
1467 | GNUNET_CONTAINER_multihashmap_destroy (cadet_sessions); | 1161 | GNUNET_CONTAINER_multihashmap_destroy (cadet_sessions); |
@@ -1521,29 +1215,23 @@ run (void *cls, | |||
1521 | }; | 1215 | }; |
1522 | static const struct GNUNET_CADET_MessageHandler cadet_handlers[] = { | 1216 | static const struct GNUNET_CADET_MessageHandler cadet_handlers[] = { |
1523 | { &handle_alices_computation_request, | 1217 | { &handle_alices_computation_request, |
1524 | GNUNET_MESSAGE_TYPE_SCALARPRODUCT_SESSION_INITIALIZATION, | 1218 | GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_SESSION_INITIALIZATION, |
1525 | sizeof (struct ServiceRequestMessage) }, | 1219 | sizeof (struct EccServiceRequestMessage) }, |
1526 | { &handle_alices_cryptodata_message, | 1220 | { &handle_alices_cryptodata_message, |
1527 | GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ALICE_CRYPTODATA, | 1221 | GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_ALICE_CRYPTODATA, |
1528 | 0}, | 1222 | 0}, |
1529 | { NULL, 0, 0} | 1223 | { NULL, 0, 0} |
1530 | }; | 1224 | }; |
1531 | static const uint32_t ports[] = { | 1225 | static const uint32_t ports[] = { |
1532 | GNUNET_APPLICATION_TYPE_SCALARPRODUCT, | 1226 | GNUNET_APPLICATION_TYPE_SCALARPRODUCT_ECC, |
1533 | 0 | 1227 | 0 |
1534 | }; | 1228 | }; |
1535 | 1229 | ||
1536 | cfg = c; | 1230 | cfg = c; |
1537 | /* | 1231 | /* We don't really do DLOG, so we can setup with very minimal resources */ |
1538 | offset has to be sufficiently small to allow computation of: | 1232 | edc = GNUNET_CRYPTO_ecc_dlog_prepare (4 /* max value */, |
1539 | m1+m2 mod n == (S + a) + (S + b) mod n, | 1233 | 2 /* RAM */); |
1540 | if we have more complex operations, this factor needs to be lowered */ | 1234 | |
1541 | my_offset = gcry_mpi_new (GNUNET_CRYPTO_PAILLIER_BITS / 3); | ||
1542 | gcry_mpi_set_bit (my_offset, | ||
1543 | GNUNET_CRYPTO_PAILLIER_BITS / 3); | ||
1544 | |||
1545 | GNUNET_CRYPTO_paillier_create (&my_pubkey, | ||
1546 | &my_privkey); | ||
1547 | GNUNET_SERVER_add_handlers (server, | 1235 | GNUNET_SERVER_add_handlers (server, |
1548 | server_handlers); | 1236 | server_handlers); |
1549 | GNUNET_SERVER_disconnect_notify (server, | 1237 | GNUNET_SERVER_disconnect_notify (server, |
@@ -1589,4 +1277,4 @@ main (int argc, | |||
1589 | &run, NULL)) ? 0 : 1; | 1277 | &run, NULL)) ? 0 : 1; |
1590 | } | 1278 | } |
1591 | 1279 | ||
1592 | /* end of gnunet-service-scalarproduct_bob.c */ | 1280 | /* end of gnunet-service-scalarproduct-ecc_bob.c */ |