aboutsummaryrefslogtreecommitdiff
path: root/src/util/crypto_paillier.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2014-12-07 23:50:19 +0000
committerChristian Grothoff <christian@grothoff.org>2014-12-07 23:50:19 +0000
commitb65c2c27f8284fde36536cc9b4ff2307b20a1717 (patch)
treed3c354c3e562ce60e0da69a8f0375b5ebbc15dc5 /src/util/crypto_paillier.c
parent00ba6aa6e5b4271ed3af3fb98426ff9f74451f31 (diff)
downloadgnunet-b65c2c27f8284fde36536cc9b4ff2307b20a1717.tar.gz
gnunet-b65c2c27f8284fde36536cc9b4ff2307b20a1717.zip
ensure that a bogus public key cannot send us into an infinite loop
Diffstat (limited to 'src/util/crypto_paillier.c')
-rw-r--r--src/util/crypto_paillier.c47
1 files changed, 30 insertions, 17 deletions
diff --git a/src/util/crypto_paillier.c b/src/util/crypto_paillier.c
index 80ad25f1f..c16706dcb 100644
--- a/src/util/crypto_paillier.c
+++ b/src/util/crypto_paillier.c
@@ -60,13 +60,15 @@ GNUNET_CRYPTO_paillier_create (struct GNUNET_CRYPTO_PaillierPublicKey *public_ke
60 gcry_mpi_release (q); 60 gcry_mpi_release (q);
61 // generate rsa modulus 61 // generate rsa modulus
62 GNUNET_assert (0 == gcry_prime_generate (&p, GNUNET_CRYPTO_PAILLIER_BITS / 2, 0, NULL, NULL, NULL, 62 GNUNET_assert (0 == gcry_prime_generate (&p, GNUNET_CRYPTO_PAILLIER_BITS / 2, 0, NULL, NULL, NULL,
63 GCRY_WEAK_RANDOM, 0)); 63 GCRY_STRONG_RANDOM, 0));
64 GNUNET_assert (0 == gcry_prime_generate (&q, GNUNET_CRYPTO_PAILLIER_BITS / 2, 0, NULL, NULL, NULL, 64 GNUNET_assert (0 == gcry_prime_generate (&q, GNUNET_CRYPTO_PAILLIER_BITS / 2, 0, NULL, NULL, NULL,
65 GCRY_WEAK_RANDOM, 0)); 65 GCRY_STRONG_RANDOM, 0));
66 } 66 }
67 while (0 == gcry_mpi_cmp (p, q)); 67 while (0 == gcry_mpi_cmp (p, q));
68 gcry_mpi_mul (n, p, q); 68 gcry_mpi_mul (n, p, q);
69 GNUNET_CRYPTO_mpi_print_unsigned (public_key, sizeof (struct GNUNET_CRYPTO_PaillierPublicKey), n); 69 GNUNET_CRYPTO_mpi_print_unsigned (public_key,
70 sizeof (struct GNUNET_CRYPTO_PaillierPublicKey),
71 n);
70 72
71 // compute phi(n) = (p-1)(q-1) 73 // compute phi(n) = (p-1)(q-1)
72 gcry_mpi_sub_ui (p, p, 1); 74 gcry_mpi_sub_ui (p, p, 1);
@@ -94,7 +96,7 @@ GNUNET_CRYPTO_paillier_create (struct GNUNET_CRYPTO_PaillierPublicKey *public_ke
94 * @param m Plaintext to encrypt. 96 * @param m Plaintext to encrypt.
95 * @param desired_ops How many homomorphic ops the caller intends to use 97 * @param desired_ops How many homomorphic ops the caller intends to use
96 * @param[out] ciphertext Encrytion of @a plaintext with @a public_key. 98 * @param[out] ciphertext Encrytion of @a plaintext with @a public_key.
97 * @return guaranteed number of supported homomorphic operations >= 1, 99 * @return guaranteed number of supported homomorphic operations >= 1,
98 * or desired_ops, in case that is lower, 100 * or desired_ops, in case that is lower,
99 * or -1 if less than one homomorphic operation is possible 101 * or -1 if less than one homomorphic operation is possible
100 */ 102 */
@@ -111,41 +113,52 @@ GNUNET_CRYPTO_paillier_encrypt (const struct GNUNET_CRYPTO_PaillierPublicKey *pu
111 gcry_mpi_t n; 113 gcry_mpi_t n;
112 gcry_mpi_t tmp1; 114 gcry_mpi_t tmp1;
113 gcry_mpi_t tmp2; 115 gcry_mpi_t tmp2;
116 unsigned int highbit;
114 117
115 // determine how many operations we could allow, if the other number 118 // determine how many operations we could allow, if the other number
116 // has the same length. 119 // has the same length.
117 GNUNET_assert (NULL != (tmp1 = gcry_mpi_set_ui (NULL, 1))); 120 GNUNET_assert (NULL != (tmp1 = gcry_mpi_set_ui (NULL, 1)));
118 GNUNET_assert (NULL != (tmp2 = gcry_mpi_set_ui (NULL, 2))); 121 GNUNET_assert (NULL != (tmp2 = gcry_mpi_set_ui (NULL, 2)));
119 gcry_mpi_mul_2exp (tmp1, tmp1, GNUNET_CRYPTO_PAILLIER_BITS); 122 gcry_mpi_mul_2exp (tmp1, tmp1, GNUNET_CRYPTO_PAILLIER_BITS);
120 123
121 // count number of possible operations 124 // count number of possible operations
122 // this would be nicer with gcry_mpi_get_nbits, however it does not return 125 // this would be nicer with gcry_mpi_get_nbits, however it does not return
123 // the BITLENGTH of the given MPI's value, but the bits required 126 // the BITLENGTH of the given MPI's value, but the bits required
124 // to represent the number as MPI. 127 // to represent the number as MPI.
125 for (possible_opts = -2; gcry_mpi_cmp (tmp1, m) > 0; possible_opts++) { 128 for (possible_opts = -2; gcry_mpi_cmp (tmp1, m) > 0; possible_opts++)
126 gcry_mpi_div (tmp1, NULL, tmp1, tmp2, 0); 129 gcry_mpi_div (tmp1, NULL, tmp1, tmp2, 0);
127 }
128 gcry_mpi_release (tmp1); 130 gcry_mpi_release (tmp1);
129 gcry_mpi_release (tmp2); 131 gcry_mpi_release (tmp2);
130 132
131 if (possible_opts < 1) 133 if (possible_opts < 1)
132 possible_opts = 0; 134 possible_opts = 0;
133 //soft-cap by caller 135 //soft-cap by caller
134 possible_opts = (desired_ops < possible_opts)? desired_ops : possible_opts; 136 possible_opts = (desired_ops < possible_opts)? desired_ops : possible_opts;
135 137
136 ciphertext->remaining_ops = htonl (possible_opts); 138 ciphertext->remaining_ops = htonl (possible_opts);
137 139
140 GNUNET_CRYPTO_mpi_scan_unsigned (&n,
141 public_key,
142 sizeof (struct GNUNET_CRYPTO_PaillierPublicKey));
143 highbit = GNUNET_CRYPTO_PAILLIER_BITS - 1;
144 while ( (! gcry_mpi_test_bit (n, highbit)) &&
145 (0 != highbit) )
146 highbit--;
147 if (0 == highbit)
148 {
149 /* invalid public key */
150 GNUNET_break_op (0);
151 gcry_mpi_release (n);
152 return GNUNET_SYSERR;
153 }
138 GNUNET_assert (0 != (n_square = gcry_mpi_new (0))); 154 GNUNET_assert (0 != (n_square = gcry_mpi_new (0)));
139 GNUNET_assert (0 != (r = gcry_mpi_new (0))); 155 GNUNET_assert (0 != (r = gcry_mpi_new (0)));
140 GNUNET_assert (0 != (c = gcry_mpi_new (0))); 156 GNUNET_assert (0 != (c = gcry_mpi_new (0)));
141
142 GNUNET_CRYPTO_mpi_scan_unsigned (&n, public_key, sizeof (struct GNUNET_CRYPTO_PaillierPublicKey));
143
144 gcry_mpi_mul (n_square, n, n); 157 gcry_mpi_mul (n_square, n, n);
145 158
146 // generate r < n 159 // generate r < n (without bias)
147 do { 160 do {
148 gcry_mpi_randomize (r, GNUNET_CRYPTO_PAILLIER_BITS, GCRY_WEAK_RANDOM); 161 gcry_mpi_randomize (r, highbit + 1, GCRY_STRONG_RANDOM);
149 } 162 }
150 while (gcry_mpi_cmp (r, n) >= 0); 163 while (gcry_mpi_cmp (r, n) >= 0);
151 164
@@ -266,7 +279,7 @@ GNUNET_CRYPTO_paillier_hom_add (const struct GNUNET_CRYPTO_PaillierPublicKey *pu
266 279
267 280
268/** 281/**
269 * Get the number of remaining supported homomorphic operations. 282 * Get the number of remaining supported homomorphic operations.
270 * 283 *
271 * @param c Paillier cipher text. 284 * @param c Paillier cipher text.
272 * @return the number of remaining homomorphic operations 285 * @return the number of remaining homomorphic operations