void paillier_keygen( int modulusbits, paillier_pubkey_t** pub, paillier_prvkey_t** prv, paillier_get_rand_t get_rand ) { mpz_t p; mpz_t q; gmp_randstate_t rand; /* allocate the new key structures */ *pub = (paillier_pubkey_t*) malloc(sizeof(paillier_pubkey_t)); *prv = (paillier_prvkey_t*) malloc(sizeof(paillier_prvkey_t)); /* initialize our integers */ mpz_init((*pub)->n); mpz_init((*pub)->n_squared); mpz_init((*pub)->n_plusone); mpz_init((*prv)->lambda); mpz_init((*prv)->x); mpz_init(p); mpz_init(q); /* pick random (modulusbits/2)-bit primes p and q */ init_rand(rand, get_rand, modulusbits / 8 + 1); do { do mpz_urandomb(p, rand, modulusbits / 2); while( !mpz_probab_prime_p(p, 10) ); do mpz_urandomb(q, rand, modulusbits / 2); while( !mpz_probab_prime_p(q, 10) ); /* compute the public modulus n = p q */ mpz_mul((*pub)->n, p, q); } while( !mpz_tstbit((*pub)->n, modulusbits - 1) ); complete_pubkey(*pub); (*pub)->bits = modulusbits; /* compute the private key lambda = lcm(p-1,q-1) */ mpz_sub_ui(p, p, 1); mpz_sub_ui(q, q, 1); mpz_lcm((*prv)->lambda, p, q); complete_prvkey(*prv, *pub); /* clear temporary integers and randstate */ mpz_clear(p); mpz_clear(q); gmp_randclear(rand); }
paillier_prvkey_t* paillier_prvkey_from_hex( char* str, paillier_pubkey_t* pub ) { paillier_prvkey_t* prv; prv = (paillier_prvkey_t*) malloc(sizeof(paillier_prvkey_t)); mpz_init_set_str(prv->lambda, str, 16); mpz_init(prv->x); complete_prvkey(prv, pub); return prv; }