/**
\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 .
\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
/*
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