*
* @param public_key Public key to use.
* @param m Plaintext to encrypt.
+ * @param desired_ops How many homomorphic ops the caller intends to use
* @param[out] ciphertext Encrytion of @a plaintext with @a public_key.
* @return guaranteed number of supported homomorphic operations >= 1,
- * -1 if less than one homomorphic operation is possible
+ * or desired_ops, in case that is lower,
+ * or -1 if less than one homomorphic operation is possible
*/
int
GNUNET_CRYPTO_paillier_encrypt (const struct GNUNET_CRYPTO_PaillierPublicKey *public_key,
const gcry_mpi_t m,
+ int desired_ops,
struct GNUNET_CRYPTO_PaillierCiphertext *ciphertext)
{
int possible_opts;
gcry_mpi_t n_square;
gcry_mpi_t r;
- gcry_mpi_t g;
gcry_mpi_t c;
gcry_mpi_t n;
gcry_mpi_t tmp1;
gcry_mpi_release (tmp1);
gcry_mpi_release (tmp2);
- // can we do at least one homomorphic operation with this value?
if (possible_opts < 1)
- // no, don't use paillier please!
- return -1;
- else
- ciphertext->remaining_ops = htonl (possible_opts);
+ possible_opts = 0;
+ //soft-cap by caller
+ possible_opts = (desired_ops < possible_opts)? desired_ops : possible_opts;
+
+ ciphertext->remaining_ops = htonl (possible_opts);
GNUNET_assert (0 != (n_square = gcry_mpi_new (0)));
GNUNET_assert (0 != (r = gcry_mpi_new (0)));
- GNUNET_assert (0 != (g = gcry_mpi_new (0)));
GNUNET_assert (0 != (c = gcry_mpi_new (0)));
GNUNET_CRYPTO_mpi_scan_unsigned (&n, public_key, sizeof (struct GNUNET_CRYPTO_PaillierPublicKey));
c);
gcry_mpi_release (n_square);
+ gcry_mpi_release (n);
gcry_mpi_release (r);
gcry_mpi_release (c);
GNUNET_CRYPTO_mpi_scan_unsigned (&lambda, private_key->lambda, sizeof private_key->lambda);
GNUNET_CRYPTO_mpi_scan_unsigned (&mu, private_key->mu, sizeof private_key->mu);
GNUNET_CRYPTO_mpi_scan_unsigned (&n, public_key, sizeof *public_key);
- GNUNET_CRYPTO_mpi_scan_unsigned (&c, ciphertext, sizeof *ciphertext);
+ GNUNET_CRYPTO_mpi_scan_unsigned (&c, ciphertext->bits, sizeof ciphertext->bits);
gcry_mpi_mul (n_square, n, n);
// m = c^lambda mod n^2