Current section
Files
Jump to
Current section
Files
c_src/paillier.h
/*
libpaillier - A library implementing the Paillier cryptosystem.
Copyright (C) 2006 SRI International.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
*/
/*
Include gmp.h before including this file.
*/
/*
IMPORTANT SECURITY NOTES:
On paillier_keygen and strong primes:
When selecting a modulus n = p q, we do not bother ensuring that p
and q are strong primes. While this was at one point considered
important (e.g., it is required by ANSI X9.31), modern factoring
algorithms make any advantage of strong primes doubtful [1]. RSA
Laboratories no longer recommends the practice [2].
On memory handling:
At no point is any special effort made to securely "shred" sensitive
memory or prevent it from being paged out to disk. This means that
it is important that functions dealing with private keys and
plaintexts (e.g., paillier_keygen and paillier_enc) only be run on
trusted machines. The resulting ciphertexts and public keys,
however, may of course be handled in an untrusted manner.
[1] Are "strong" primes needed for RSA? Ron Rivest and Robert
Silverman. Cryptology ePrint Archive, Report 2001/007, 2001.
[2] RSA Laboratories' Frequently Asked Questions About Today's
Cryptography, Version 4.1, Section 3.1.4.
*/
/******
TYPES
*******/
/*
This represents a Paillier public key, which is basically just the
modulus n. The other values should be considered private.
*/
typedef struct
{
unsigned int bits; /* e.g., 1024 */
mpz_t n; /* public modulus n = p q */
mpz_t n_squared; /* cached to avoid recomputing */
mpz_t n_plusone; /* cached to avoid recomputing */
} paillier_pubkey_t;
/*
This represents a Paillier private key; it needs to be used with a
paillier_pubkey_t to be meaningful. It only includes the Carmichael
function (lambda) of the modulus. The other value is kept for
efficiency and should be considered private.
*/
typedef struct
{
mpz_t lambda; /* lambda(n), i.e., lcm(p-1,q-1) */
mpz_t x; /* cached to avoid recomputing */
} paillier_prvkey_t;
/*
This is a (semantic rather than structural) type for plaintexts.
These can be converted to and from ASCII strings and byte arrays.
*/
typedef struct
{
mpz_t m;
} paillier_plaintext_t;
/*
This is a (semantic rather than structural) type for ciphertexts.
These can also be converted to or from byte arrays (for example in
order to store them in a file).
*/
typedef struct
{
mpz_t c;
} paillier_ciphertext_t;
/*
This is the type of the callback functions used to obtain the
randomness needed by the probabilistic algorithms. The functions
paillier_get_rand_devrandom and paillier_get_rand_devurandom
(documented later) may be passed to any library function requiring a
paillier_get_rand_t, or you may implement your own. If you implement
your own such function, it should fill in "len" random bytes in the
array "buf".
*/
typedef void (*paillier_get_rand_t) ( void* buf, int len );
/*****************
BASIC OPERATIONS
*****************/
/*
Generate a keypair of length modulusbits using randomness from the
provided get_rand function. Space will be allocated for each of the
keys, and the given pointers will be set to point to the new
paillier_pubkey_t and paillier_prvkey_t structures. The functions
paillier_get_rand_devrandom and paillier_get_rand_devurandom may be
passed as the final argument.
*/
void paillier_keygen( unsigned int modulusbits,
paillier_pubkey_t** pub,
paillier_prvkey_t** prv,
paillier_get_rand_t get_rand );
/*
Encrypt the given plaintext with the given public key using
randomness from get_rand for blinding. If res is not null, its
contents will be overwritten with the result. Otherwise, a new
paillier_ciphertext_t will be allocated and returned.
*/
paillier_ciphertext_t* paillier_enc( paillier_ciphertext_t* res,
paillier_pubkey_t* pub,
paillier_plaintext_t* pt,
paillier_get_rand_t get_rand );
/*
Decrypt the given ciphertext with the given key pair. If res is not
null, its contents will be overwritten with the result. Otherwise, a
new paillier_plaintext_t will be allocated and returned.
*/
paillier_plaintext_t* paillier_dec( paillier_plaintext_t* res,
paillier_pubkey_t* pub,
paillier_prvkey_t* prv,
paillier_ciphertext_t* ct );
/*****************************
USE OF ADDITIVE HOMOMORPHISM
*****************************/
/*
Multiply the two ciphertexts assuming the modulus in the given
public key and store the result in the contents of res, which is
assumed to have already been allocated.
*/
void paillier_mul( paillier_pubkey_t* pub,
paillier_ciphertext_t* res,
paillier_ciphertext_t* ct0,
paillier_ciphertext_t* ct1 );
/*
Raise the given ciphertext to power pt and store the result in res,
which is assumed to be already allocated. If ct is an encryption of
x, then res will become an encryption of x * pt mod n, where n is
the modulus in pub.
*/
void paillier_exp( paillier_pubkey_t* pub,
paillier_ciphertext_t* res,
paillier_ciphertext_t* ct,
paillier_plaintext_t* pt );
/****************************
PLAINTEXT IMPORT AND EXPORT
****************************/
/*
Allocate and initialize a paillier_plaintext_t from an unsigned long
integer, an array of bytes, or a null terminated string.
*/
paillier_plaintext_t* paillier_plaintext_from_ui( unsigned long int x );
paillier_plaintext_t* paillier_plaintext_from_bytes( void* m, unsigned int len );
paillier_plaintext_t* paillier_plaintext_from_str( char* str );
/*
Export a paillier_plaintext_t as a null terminated string or an
array of bytes. In either case the result is allocated for the
caller and the original paillier_plaintext_t is unchanged.
*/
char* paillier_plaintext_to_str( paillier_plaintext_t* pt );
void* paillier_plaintext_to_bytes( unsigned int len, paillier_plaintext_t* pt );
/*****************************
CIPHERTEXT IMPORT AND EXPORT
*****************************/
/*
Import or export a paillier_ciphertext_t from or to an array of
bytes. These behave like the corresponding functions for
paillier_plaintext_t's.
*/
paillier_ciphertext_t* paillier_ciphertext_from_bytes( void* c, unsigned int len );
void* paillier_ciphertext_to_bytes( unsigned int len, paillier_ciphertext_t* ct );
/**********************
KEY IMPORT AND EXPORT
**********************/
/*
Import or export public and private keys from or to hexadecimal,
ASCII strings, which are suitable for I/O. Note that the
corresponding public key is necessary to initialize a private key
from a hex string. In all cases, the returned value is allocated for
the caller and the values passed are unchanged.
*/
char* paillier_pubkey_to_hex( paillier_pubkey_t* pub );
char* paillier_prvkey_to_hex( paillier_prvkey_t* prv );
paillier_pubkey_t* paillier_pubkey_from_hex( char* str );
paillier_prvkey_t* paillier_prvkey_from_hex( char* str,
paillier_pubkey_t* pub );
/********
CLEANUP
********/
/*
These free the structures allocated and returned by various
functions within library and should be used when the structures are
no longer needed.
*/
void paillier_freepubkey( paillier_pubkey_t* pub );
void paillier_freeprvkey( paillier_prvkey_t* prv );
void paillier_freeplaintext( paillier_plaintext_t* pt );
void paillier_freeciphertext( paillier_ciphertext_t* ct );
/***********
MISC STUFF
***********/
/*
These functions may be passed to the paillier_keygen and
paillier_enc functions to provide a source of random numbers. The
first reads bytes from /dev/random. On Linux, this device
exclusively returns entropy gathered from environmental noise and
therefore frequently blocks when not enough is available. The second
returns bytes from /dev/urandom. On Linux, this device also returns
environmental noise, but augments it with a pseudo-random number
generator when not enough is available. The latter is probably the
better choice unless you have a specific reason to believe it is
insufficient.
*/
void paillier_get_rand_devrandom( void* buf, int len );
void paillier_get_rand_devurandom( void* buf, int len );
/*
This function just allocates and returns a paillier_ciphertext_t
which is a valid, _unblinded_ encryption of zero (which may actually
be done without knowledge of a public key). Note that this
encryption is UNBLINDED, so don't use it unless you want anyone who
sees it to know it is an encryption of zero. This function is
sometimes handy to get some homomorphic computations started or
quickly allocate a paillier_ciphertext_t in which to place some
later result.
*/
paillier_ciphertext_t* paillier_create_enc_zero(void);
/*
Just a utility used internally when we need round a number of bits
up the number of bytes necessary to hold them.
*/
#define PAILLIER_BITS_TO_BYTES(n) ((n) % 8 ? (n) / 8 + 1 : (n) / 8)