GNUnet  0.20.0
crypto_paillier.c File Reference

implementation of the paillier crypto system with libgcrypt More...

#include "platform.h"
#include <gcrypt.h>
#include "gnunet_util_lib.h"
Include dependency graph for crypto_paillier.c:

Go to the source code of this file.

Functions

void GNUNET_CRYPTO_paillier_create (struct GNUNET_CRYPTO_PaillierPublicKey *public_key, struct GNUNET_CRYPTO_PaillierPrivateKey *private_key)
 Create a freshly generated paillier public key. More...
 
int GNUNET_CRYPTO_paillier_encrypt1 (const struct GNUNET_CRYPTO_PaillierPublicKey *public_key, const gcry_mpi_t m, int desired_ops, struct GNUNET_CRYPTO_PaillierCiphertext *ciphertext)
 Encrypt a plaintext with a paillier public key. More...
 
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)
 Encrypt a plaintext with a paillier public key. More...
 
void GNUNET_CRYPTO_paillier_decrypt (const struct GNUNET_CRYPTO_PaillierPrivateKey *private_key, const struct GNUNET_CRYPTO_PaillierPublicKey *public_key, const struct GNUNET_CRYPTO_PaillierCiphertext *ciphertext, gcry_mpi_t m)
 Decrypt a paillier ciphertext with a private key. More...
 
int GNUNET_CRYPTO_paillier_hom_add (const struct GNUNET_CRYPTO_PaillierPublicKey *public_key, const struct GNUNET_CRYPTO_PaillierCiphertext *c1, const struct GNUNET_CRYPTO_PaillierCiphertext *c2, struct GNUNET_CRYPTO_PaillierCiphertext *result)
 Compute a ciphertext that represents the sum of the plaintext in c1 and c2. More...
 
int GNUNET_CRYPTO_paillier_hom_get_remaining (const struct GNUNET_CRYPTO_PaillierCiphertext *c)
 Get the number of remaining supported homomorphic operations. More...
 

Detailed Description

implementation of the paillier crypto system with libgcrypt

Author
Florian Dold
Christian Fuchs

Definition in file crypto_paillier.c.

Function Documentation

◆ GNUNET_CRYPTO_paillier_encrypt1()

int GNUNET_CRYPTO_paillier_encrypt1 ( const struct GNUNET_CRYPTO_PaillierPublicKey public_key,
const gcry_mpi_t  m,
int  desired_ops,
struct GNUNET_CRYPTO_PaillierCiphertext ciphertext 
)

Encrypt a plaintext with a paillier public key.

Parameters
public_keyPublic key to use.
mPlaintext to encrypt.
desired_opsHow many homomorphic ops the caller intends to use
[out]ciphertextEncryption of plaintext with public_key.
Returns
guaranteed number of supported homomorphic operations >= 1, or desired_ops, in case that is lower, or -1 if less than one homomorphic operation is possible

Definition at line 121 of file crypto_paillier.c.

127 {
128  int possible_opts;
129  gcry_mpi_t n_square;
130  gcry_mpi_t r;
131  gcry_mpi_t c;
132  gcry_mpi_t n;
133  gcry_mpi_t tmp1;
134  gcry_mpi_t tmp2;
135  unsigned int highbit;
136 
137  /* determine how many operations we could allow, if the other number
138  has the same length. */
139  GNUNET_assert (NULL != (tmp1 = gcry_mpi_set_ui (NULL, 1)));
140  GNUNET_assert (NULL != (tmp2 = gcry_mpi_set_ui (NULL, 2)));
141  gcry_mpi_mul_2exp (tmp1, tmp1, GNUNET_CRYPTO_PAILLIER_BITS);
142 
143  /* count number of possible operations
144  this would be nicer with gcry_mpi_get_nbits, however it does not return
145  the BITLENGTH of the given MPI's value, but the bits required
146  to represent the number as MPI. */
147  for (possible_opts = -2; gcry_mpi_cmp (tmp1, m) > 0; possible_opts++)
148  gcry_mpi_div (tmp1, NULL, tmp1, tmp2, 0);
149  gcry_mpi_release (tmp1);
150  gcry_mpi_release (tmp2);
151 
152  if (possible_opts < 1)
153  possible_opts = 0;
154  /* soft-cap by caller */
155  possible_opts = (desired_ops < possible_opts) ? desired_ops : possible_opts;
156 
157  ciphertext->remaining_ops = htonl (possible_opts);
158 
160  public_key,
161  sizeof(struct
163  highbit = GNUNET_CRYPTO_PAILLIER_BITS - 1;
164  while ((! gcry_mpi_test_bit (n, highbit)) &&
165  (0 != highbit))
166  highbit--;
167  if (0 == highbit)
168  {
169  /* invalid public key */
170  GNUNET_break_op (0);
171  gcry_mpi_release (n);
172  return GNUNET_SYSERR;
173  }
174  GNUNET_assert (0 != (n_square = gcry_mpi_new (0)));
175  GNUNET_assert (0 != (r = gcry_mpi_new (0)));
176  GNUNET_assert (0 != (c = gcry_mpi_new (0)));
177  gcry_mpi_mul (n_square, n, n);
178 
179  /* generate r < n (without bias) */
180  do
181  {
182  gcry_mpi_randomize (r, highbit + 1, GCRY_STRONG_RANDOM);
183  }
184  while (gcry_mpi_cmp (r, n) >= 0);
185 
186  /* c = (n+1)^m mod n^2 */
187  /* c = n + 1 */
188  gcry_mpi_add_ui (c, n, 1);
189  /* c = (n+1)^m mod n^2 */
190  gcry_mpi_powm (c, c, m, n_square);
191  /* r <- r^n mod n^2 */
192  gcry_mpi_powm (r, r, n, n_square);
193  /* c <- r*c mod n^2 */
194  gcry_mpi_mulm (c, r, c, n_square);
195 
197  sizeof ciphertext->bits,
198  c);
199 
200  gcry_mpi_release (n_square);
201  gcry_mpi_release (n);
202  gcry_mpi_release (r);
203  gcry_mpi_release (c);
204 
205  return possible_opts;
206 }
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition: gnunet-arm.c:104
static struct GNUNET_SECRETSHARING_Ciphertext ciphertext
void GNUNET_CRYPTO_mpi_scan_unsigned(gcry_mpi_t *result, const void *data, size_t size)
Convert data buffer into MPI value.
Definition: crypto_mpi.c:132
#define GNUNET_CRYPTO_PAILLIER_BITS
Size of paillier plain texts and public keys.
void GNUNET_CRYPTO_mpi_print_unsigned(void *buf, size_t size, gcry_mpi_t val)
Output the given MPI value to the given buffer in network byte order.
Definition: crypto_mpi.c:79
@ GNUNET_SYSERR
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.

References ciphertext, GNUNET_assert, GNUNET_break_op, GNUNET_CRYPTO_mpi_print_unsigned(), GNUNET_CRYPTO_mpi_scan_unsigned(), GNUNET_CRYPTO_PAILLIER_BITS, GNUNET_SYSERR, and m.

Here is the call graph for this function: