GNUnet 0.21.1
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
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.
int32_t remaining_ops
Guaranteed minimum number of homomorphic operations with this ciphertext, in network byte order (NBO)...
unsigned char bits[2048 *2/8]
The bits of the ciphertext.

References GNUNET_CRYPTO_PaillierCiphertext::bits, GNUNET_assert, GNUNET_break_op, GNUNET_CRYPTO_mpi_print_unsigned(), GNUNET_CRYPTO_mpi_scan_unsigned(), GNUNET_CRYPTO_PAILLIER_BITS, GNUNET_SYSERR, m, and GNUNET_CRYPTO_PaillierCiphertext::remaining_ops.

Here is the call graph for this function: