123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- /**
- \file djn.h
- \author Daniel Demmler
- \copyright Copyright (C) 2019 ENCRYPTO Group, TU Darmstadt
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published
- by the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- ABY 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 Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- \brief
- libdjn - v0.9
- A library implementing the Damgaard Jurik Nielsen cryptosystem with s=1 (~Paillier).
- based on:
- libpaillier - A library implementing the Paillier cryptosystem.
- (http://hms.isi.jhu.edu/acsc/libpaillier/)
- */
- #ifndef _DJN_H_
- #define _DJN_H_
- #include <gmp.h>
- /*
- 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., djn_keygen and djn_enc) only be run on
- trusted machines. The resulting ciphertexts and public keys,
- however, may of course be handled in an untrusted manner.
- */
- /******
- TYPES
- *******/
- /*
- This represents a public key, which is the modulus n plus a generator h.
- */
- struct djn_pubkey_t {
- int bits; /* e.g., 1024 */
- int rbits; /* e.g., 512 */
- mpz_t n; /* public modulus n = p q */
- mpz_t n_squared; /* cached to avoid recomputing */
- mpz_t h; /* generator h = -x^2 mod n */
- mpz_t h_s; /* h_s = h^n mod n^2 */
- };
- /*
- This represents a Paillier private key; it needs to be used with a
- djn_pubkey_t to be meaningful. It includes the Carmichael
- function (lambda) of the modulus. The other value is kept for
- efficiency and should be considered private.
- */
- struct djn_prvkey_t {
- mpz_t lambda; /* lambda(n), i.e., lcm(p-1,q-1) */
- mpz_t lambda_inverse; /* inverse of lambda (mod n)*/
- mpz_t p; /* cached to avoid recomputing */
- mpz_t q; /* cached to avoid recomputing */
- mpz_t q_inverse; /* inverse of q (mod p) */
- mpz_t q_squared_inverse; /* inverse of q^2 (mod p^2) */
- mpz_t p_minusone; /* cached to avoid recomputing */
- mpz_t q_minusone; /* cached to avoid recomputing */
- mpz_t p_squared; /* cached to avoid recomputing */
- mpz_t q_squared; /* cached to avoid recomputing */
- mpz_t ordpsq; /* p^2-p */
- mpz_t ordqsq; /* q^2-q */
- };
- /*
- This is the type of the callback functions used to obtain the
- randomness needed by the probabilistic algorithms. The functions
- djn_get_rand_devrandom and djn_get_rand_devurandom
- (documented later) may be passed to any library function requiring a
- djn_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 (*djn_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
- djn_pubkey_t and djn_prvkey_t structures. The functions
- djn_get_rand_devrandom and djn_get_rand_devurandom may be
- passed as the final argument.
- */
- void djn_keygen(unsigned int modulusbits, djn_pubkey_t** pub, djn_prvkey_t** prv);
- /*
- 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
- djn_ciphertext_t will be allocated and returned.
- */
- void djn_encrypt(mpz_t res, djn_pubkey_t* pub, mpz_t pt);
- /*
- 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
- djn_ciphertext_t will be allocated and returned.
- */
- void djn_encrypt_crt(mpz_t res, djn_pubkey_t* pub, djn_prvkey_t* prv, mpz_t pt);
- /**
- * fixed base encryption. Requires pre-computed fixed base table.
- */
- void djn_encrypt_fb(mpz_t res, djn_pubkey_t* pub, mpz_t plaintext);
- /*
- 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 djn_plaintext_t will be allocated and returned.
- */
- void djn_decrypt(mpz_t res, djn_pubkey_t* pub, djn_prvkey_t* prv, mpz_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* djn_pubkey_to_hex(djn_pubkey_t* pub);
- char* djn_prvkey_to_hex(djn_prvkey_t* prv);
- djn_pubkey_t* djn_pubkey_from_hex(char* str);
- djn_prvkey_t* djn_prvkey_from_hex(char* str, djn_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 djn_freepubkey(djn_pubkey_t* pub);
- void djn_freeprvkey(djn_prvkey_t* prv);
- /***********
- MISC STUFF
- ***********/
- /*
- 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)
- void djn_pow_mod_n_crt(mpz_t res, const mpz_t b, const mpz_t e, const djn_pubkey_t* pub, const djn_prvkey_t* prv);
- void djn_pow_mod_n_squared_crt(mpz_t res, const mpz_t b, const mpz_t e, const djn_pubkey_t* pub, const djn_prvkey_t* prv);
- /**
- * create full public key given only n and h (e.g., after a key exchange)
- */
- void djn_complete_pubkey(unsigned int modulusbits, djn_pubkey_t** pub, mpz_t n, mpz_t h);
- #endif
|