676 lines
23 KiB
C
Executable File
676 lines
23 KiB
C
Executable File
/* Cryptic -- Cryptographic tools and protocols
|
|
* Copyright (C) 2009 Mikaël Ates <mates@entrouvert.com>
|
|
*
|
|
* 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.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include <glib.h>
|
|
#include <glib-object.h>
|
|
#include <openssl/bn.h>
|
|
|
|
#include "../../errors.h"
|
|
#include "../../utils.h"
|
|
|
|
#include "clsig.h"
|
|
#include "maths/quadratic_residues_group.h"
|
|
|
|
/*****************************************************************************/
|
|
/* private methods */
|
|
/*****************************************************************************/
|
|
|
|
static GObjectClass *parent_class = NULL;
|
|
|
|
/*****************************************************************************/
|
|
/* overridden parent class methods */
|
|
/*****************************************************************************/
|
|
|
|
static void
|
|
dispose(GObject *object)
|
|
{
|
|
CrypticClsig *clsig = CRYPTIC_CLSIG(object);
|
|
|
|
int i;
|
|
if(clsig->bases){
|
|
for(i=0;i<clsig->nb_bases;i++){
|
|
cryptic_release_bn(clsig->bases[i]);
|
|
}
|
|
}
|
|
cryptic_release(clsig->bases);
|
|
if(clsig->quantities){
|
|
for(i=0;i<clsig->nb_quantities;i++){
|
|
cryptic_release_bn(clsig->quantities[i]);
|
|
}
|
|
}
|
|
cryptic_release(clsig->quantities);
|
|
cryptic_release_bn(clsig->S);
|
|
cryptic_release_bn(clsig->Z);
|
|
cryptic_release_bn(clsig->modulus);
|
|
cryptic_release_bn(clsig->e);
|
|
cryptic_release_bn(clsig->d);
|
|
cryptic_release_bn(clsig->dlrep);
|
|
cryptic_release_bn(clsig->v);
|
|
cryptic_release_bn(clsig->v_rand);
|
|
cryptic_release_bn(clsig->A);
|
|
cryptic_release_bn(clsig->A_rand);
|
|
cryptic_release_bn(clsig->r);
|
|
|
|
cryptic_release_gobject(clsig->qrg);
|
|
|
|
G_OBJECT_CLASS(parent_class)->dispose(G_OBJECT(clsig));
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* instance and class init functions */
|
|
/*****************************************************************************/
|
|
|
|
static void
|
|
instance_init(CrypticClsig *clsig)
|
|
{
|
|
clsig->bases = NULL;
|
|
clsig->quantities = NULL;
|
|
clsig->S = NULL;
|
|
clsig->Z = NULL;
|
|
clsig->modulus = NULL;
|
|
clsig->e = NULL;
|
|
clsig->d = NULL;
|
|
clsig->dlrep = NULL;
|
|
clsig->v = NULL;
|
|
clsig->v_rand = NULL;
|
|
clsig->A = NULL;
|
|
clsig->A_rand = NULL;
|
|
clsig->r = NULL;
|
|
clsig->qrg = NULL;
|
|
}
|
|
|
|
static void
|
|
class_init(CrypticClsigClass *klass)
|
|
{
|
|
parent_class = g_type_class_peek_parent(klass);
|
|
|
|
G_OBJECT_CLASS(klass)->dispose = dispose;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* public methods */
|
|
/*****************************************************************************/
|
|
|
|
GType
|
|
cryptic_clsig_get_type()
|
|
{
|
|
static GType this_type = 0;
|
|
|
|
if (!this_type) {
|
|
static const GTypeInfo this_info = {
|
|
sizeof (CrypticClsigClass),
|
|
NULL,
|
|
NULL,
|
|
(GClassInitFunc) class_init,
|
|
NULL,
|
|
NULL,
|
|
sizeof(CrypticClsig),
|
|
0,
|
|
(GInstanceInitFunc) instance_init,
|
|
NULL
|
|
};
|
|
|
|
this_type = g_type_register_static(G_TYPE_OBJECT,
|
|
"CrypticClsig", &this_info, 0);
|
|
}
|
|
return this_type;
|
|
}
|
|
/*
|
|
#define CRYPTIC_CLSIG_MODULUS_SIZE 2048 //ln
|
|
#define CRYPTIC_CLSIG_COMMITMENT_GROUP_MODULUS_SIZE 1632 //lRHO
|
|
#define CRYPTIC_CLSIG_COMMITMENT_GROUP_PRIME_ORDER_SIZE 256 //lrho
|
|
#define CRYPTIC_CLSIG_QUANTITIES_SIZE 256 //lm
|
|
#define CRYPTIC_CLSIG_EXPONENT_VALUES 596 //le
|
|
#define CRYPTIC_CLSIG_EXPONENT_INTERVAL 120 //lei
|
|
#define CRYPTIC_CLSIG_BLIND_VALUES 2723 //lv
|
|
#define CRYPTIC_CLSIG_CHALLENGE_SIZE 256 //challenge: lH for non interactive proofs - lc for interactive proofs
|
|
#define CRYPTIC_CLSIG_ZK_SEC_PARAM 80 //l0
|
|
#define CRYPTIC_CLSIG_SEC_PARAM 160 //lk
|
|
#define CRYPTIC_CLSIG_SEC_PARAM_CRED_SYS 80 //lr
|
|
*/
|
|
|
|
/** Constraints
|
|
* 1- le > l0 + lH + max( lm+4 , lei+2 )
|
|
* 2- lv > ln + l0 + lH + max ( lm+lr+3 , l0+2 )
|
|
* 3- lH >= lk
|
|
* 4- lH < le (cf. 1)
|
|
* 5- lei < le - l0 - lH - 3 (computed after checking 1)
|
|
* 6- lm = lH (The larger the better and lm <= lH)
|
|
* 7- lrand = ln + l0
|
|
*/
|
|
|
|
/** Attributes
|
|
* non numerical attributes (string) should be hash
|
|
* numerical attributes should be expresses in a meaningful way to be used in proof
|
|
* ex: DateOfBirth: yyyymmddhhmm allows comparison of dates
|
|
*/
|
|
|
|
/** Mapping
|
|
* le - lg_exponent - CRYPTIC_CLSIG_EXPONENT_VALUES
|
|
* lei - interval_exponent - CRYPTIC_CLSIG_EXPONENT_INTERVAL
|
|
* lH or lc - lg_quantities - CRYPTIC_CLSIG_CHALLENGE_SIZE
|
|
* lv - lg_blind - CRYPTIC_CLSIG_BLIND_VALUES
|
|
* lrand - lg_randomize
|
|
* lm - lg_quantities - CRYPTIC_CLSIG_QUANTITIES_SIZE
|
|
* lk - lg_sec_param - CRYPTIC_CLSIG_SEC_PARAM
|
|
* l0 - lg_zk_sec_param - CRYPTIC_CLSIG_ZK_SEC_PARAM
|
|
* lr - lg_clsig_sec_param - CRYPTIC_CLSIG_SEC_PARAM_CRED_SYS
|
|
*/
|
|
|
|
/* lc is only given to the issuer to compute sizes */
|
|
/* The prover has to take care to not use challenge larger */
|
|
/* For message size, the larger the better */
|
|
/* lm = lc */
|
|
/* lei = le - l0 - lH - 4 */
|
|
|
|
/**
|
|
* cryptic_clsig_new
|
|
* @lg_modulus: bit length of the modulus.
|
|
* @lg_quantities: bit length of the quantities.
|
|
* @lg_exponent: bit length of the RSA exponent.
|
|
* @lg_sec_param: security parameter.
|
|
* @lg_zk_sec_param: security parameter for the zkpk.
|
|
* @lg_clsig_sec_param: security parameter for the clsig system.
|
|
* @nb_bases: nb of bases of represnetation.
|
|
*
|
|
* Creates a new #CrypticClsig.
|
|
*
|
|
* Return value: a newly created #CrypticClsig object; or NULL if an error
|
|
* occured
|
|
**/
|
|
CrypticClsig*
|
|
cryptic_clsig_new(int lg_modulus, int lg_quantities, int lg_exponent, int lg_sec_param, int lg_zk_sec_param, int lg_clsig_sec_param, int nb_bases)
|
|
{
|
|
int rc = CRYPTIC_ERROR_UNDEFINED;
|
|
|
|
CrypticClsig *clsig;
|
|
clsig = g_object_new(CRYPTIC_TYPE_CLSIG, NULL);
|
|
|
|
clsig->qrg = NULL;
|
|
|
|
if(lg_sec_param < CRYPTIC_CLSIG_TEST_SEC_PARAM) { clsig->lg_sec_param = CRYPTIC_CLSIG_TEST_SEC_PARAM;}
|
|
else { clsig->lg_sec_param = lg_sec_param; }
|
|
|
|
if(lg_zk_sec_param < CRYPTIC_CLSIG_TEST_ZK_SEC_PARAM) { clsig->lg_zk_sec_param = CRYPTIC_CLSIG_TEST_ZK_SEC_PARAM;}
|
|
else { clsig->lg_zk_sec_param = lg_zk_sec_param; }
|
|
|
|
if(lg_clsig_sec_param < CRYPTIC_CLSIG_TEST_SEC_PARAM_CRED_SYS) { clsig->lg_clsig_sec_param = CRYPTIC_CLSIG_TEST_SEC_PARAM_CRED_SYS;}
|
|
else { clsig->lg_clsig_sec_param = lg_clsig_sec_param; }
|
|
|
|
if(lg_quantities < clsig->lg_sec_param) { /* lc = lm*/
|
|
cryptic_critical("The challenge size must be larger or equal to the secutiry parameter (%d bits)",clsig->lg_sec_param);
|
|
goto error;
|
|
}
|
|
|
|
clsig->lg_quantities = lg_quantities;
|
|
|
|
if(lg_modulus < CRYPTIC_CLSIG_TEST_MODULUS_SIZE) {
|
|
cryptic_critical("The modulus is too small (min value: %d bits)",CRYPTIC_CLSIG_TEST_MODULUS_SIZE);
|
|
goto error;
|
|
}
|
|
if(lg_modulus%2){
|
|
cryptic_critical("The modulus bit size must be even");
|
|
goto error;
|
|
}
|
|
clsig->lg_modulus = lg_modulus;
|
|
|
|
if(lg_exponent < CRYPTIC_CLSIG_TEST_EXPONENT_VALUES) {
|
|
cryptic_critical("The exponent is too small: %d (min value: %d bits)",lg_exponent,CRYPTIC_CLSIG_TEST_EXPONENT_VALUES);
|
|
goto error;
|
|
}
|
|
if( lg_exponent < (clsig->lg_sec_param + (2*lg_quantities) + 4) ) {
|
|
cryptic_critical("The exponent is too small due to constraints (min value: %d bits)",(clsig->lg_sec_param + (2*lg_quantities) + 4));
|
|
goto error;
|
|
}
|
|
clsig->lg_exponent = lg_exponent;
|
|
|
|
clsig->interval_exponent = clsig->lg_exponent - clsig->lg_zk_sec_param - lg_quantities - 4;
|
|
|
|
if((clsig->lg_quantities + clsig->lg_clsig_sec_param + 3) > (clsig->lg_zk_sec_param + 2)){
|
|
clsig->lg_blind = clsig->lg_modulus + clsig->lg_zk_sec_param + lg_quantities + clsig->lg_quantities + clsig->lg_clsig_sec_param + 3;
|
|
}else{
|
|
clsig->lg_blind = clsig->lg_modulus + clsig->lg_zk_sec_param + lg_quantities + clsig->lg_zk_sec_param + 2;
|
|
}
|
|
|
|
clsig->lg_randomize = clsig->lg_modulus + clsig->lg_zk_sec_param;
|
|
|
|
clsig->nb_bases = nb_bases;
|
|
|
|
clsig->init = 1;
|
|
clsig->sigloaded = 0;
|
|
clsig->sigverified = 0;
|
|
clsig->sigrandomized = 0;
|
|
|
|
return clsig;
|
|
error:
|
|
cryptic_release_gobject(clsig);
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* cryptic_clsig_generate_parameters
|
|
*
|
|
* Generate clsig parameters if the object has been well initialized.
|
|
*
|
|
* Return value: #CRYPTIC_NO_ERROR if successful, an error code otherwise.
|
|
*
|
|
**/
|
|
int
|
|
//cryptic_clsig_generate_parameters(CrypticClsig *clsig, BN_GENCB *cb)
|
|
cryptic_clsig_generate_parameters(CrypticClsig *clsig)
|
|
{
|
|
int rc = CRYPTIC_ERROR_UNDEFINED;
|
|
|
|
BN_GENCB *cb = NULL;
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning(clsig->init == 1,
|
|
CRYPTIC_CLSIG_NOT_CORRECTLY_INITIALIZED);
|
|
|
|
cryptic_release_gobject(clsig->qrg);
|
|
//clsig->qrg = cryptic_qrg_new(clsig->lg_modulus, cb);
|
|
clsig->qrg = cryptic_qrg_new(clsig->lg_modulus);
|
|
goto_cleanup_if_fail_with_rc_with_warning(clsig->qrg != NULL,
|
|
CRYPTIC_CLSIG_UNABLE_TO_CREATE_QRG);
|
|
|
|
cryptic_release_bn(clsig->modulus);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->modulus = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(clsig->modulus,cryptic_qrg_get_n(clsig->qrg)));
|
|
|
|
cryptic_release_bn(clsig->S);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->S = BN_new());
|
|
cryptic_check_good_rc(cryptic_qrg_pick_base(clsig->qrg, clsig->S));
|
|
|
|
cryptic_release_bn(clsig->Z);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->Z = BN_new());
|
|
cryptic_check_good_rc(cryptic_qrg_pick_base(clsig->qrg, clsig->Z));
|
|
|
|
cryptic_release(clsig->bases);
|
|
clsig->bases = g_malloc0(clsig->nb_bases * sizeof (**clsig->bases));
|
|
if(clsig->bases == NULL){
|
|
rc = CRYPTIC_MEMORY_ALLOCATION_FAILURE;
|
|
goto cleanup;
|
|
}
|
|
|
|
int i;
|
|
for(i=0;i<clsig->nb_bases;i++){
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->bases[i] = BN_new());
|
|
}
|
|
cryptic_check_good_rc(cryptic_qrg_pick_k_bases(clsig->qrg,clsig->bases,clsig->nb_bases));
|
|
|
|
//if( (rc = cryptic_clsig_find_rsa_param(clsig, clsig->lg_exponent, cb)) < 0) return rc;
|
|
cryptic_check_good_rc(cryptic_clsig_find_rsa_param(clsig, clsig->lg_exponent));
|
|
|
|
rc = CRYPTIC_NO_ERROR;
|
|
cleanup:
|
|
return rc;
|
|
}
|
|
|
|
/**
|
|
* cryptic_clsig_find_rsa_param
|
|
* @lg_exponent: bit length of the exponent
|
|
*
|
|
* Generate a RSA key pair of length given in parameter.
|
|
* lg_exponent is kept in parameter of this function to make it usable without requiring to call init before.
|
|
* Can be used to update the key pair
|
|
*
|
|
* Return value: #CRYPTIC_NO_ERROR if successful, an error code otherwise.
|
|
*
|
|
**/
|
|
int
|
|
//cryptic_clsig_find_rsa_param(CrypticClsig *clsig, int lg_exponent, BN_GENCB *cb)
|
|
cryptic_clsig_find_rsa_param(CrypticClsig *clsig, int lg_exponent)
|
|
{
|
|
int rc = CRYPTIC_ERROR_UNDEFINED;
|
|
|
|
BN_GENCB *cb = NULL;
|
|
|
|
BIGNUM *tmp1 = NULL,*tmp2 = NULL,*gcd = NULL,*two = NULL,*lg = NULL,*lg2 = NULL;
|
|
BN_CTX *ctx = NULL;
|
|
|
|
cryptic_release_bn(clsig->e);
|
|
cryptic_release_bn(clsig->d);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->e = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->d = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(tmp1 = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(tmp2 = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(gcd = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(lg = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(lg2 = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(two = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_set_word(two,2) == 1);
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(ctx = BN_CTX_new());
|
|
|
|
/**************************************************************************
|
|
* gcd(e,phi(n)) = 1 to be able to find d = 1/e mod(phi(n))
|
|
* if a div b or a div c then a div bc
|
|
* it is then easy to show that if a not div b AND a not div c then a not div bc
|
|
* We need to test that coprime(e,phi(n)=(p-1)(q-1))
|
|
* so we need to test that coprime(e,p-1) and coprime(e,q-1)
|
|
* Both gave the same result but the complexity in space is better with the second test.
|
|
***************************************************************************/
|
|
|
|
/**************************************************************************
|
|
* BN_generate_prime_ex use has a random generator but e not need to be prime
|
|
* Having e prime does not seem to bring benefit except that computing coprimity is faster.
|
|
***************************************************************************/
|
|
|
|
/* TODO: if e is prime and greater than 2, then the less-expensive test (p mod e)!=1 is enough instead of gcd(p-1,e)==1 */
|
|
|
|
/* Take e in [2^le-1, 2^le-1 + 2^lei-1] */
|
|
/* Pick prime of size le-1: e in [2^le-1, 2^le -1] */
|
|
/* Then take e < 2^le-1 + 2^lei-1 */
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_set_word(tmp1,clsig->lg_exponent-1) == 1);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_exp(lg2,two,tmp1, ctx));
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_set_word(lg,clsig->interval_exponent-1) == 1);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_exp(lg,two,lg, ctx));
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_add(lg,lg2,lg));
|
|
|
|
int found=0;
|
|
while(!found){
|
|
cryptic_check_good_rc(cryptic_find_random(tmp1,clsig->interval_exponent-1)); //r_rho
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_add(clsig->e,tmp1,lg2));
|
|
if(BN_ucmp(clsig->e,lg) < 0){
|
|
if(BN_is_prime_ex(clsig->e, BN_prime_checks, ctx, cb)){
|
|
BN_sub(tmp1, cryptic_qrg_get_p(clsig->qrg), BN_value_one());
|
|
BN_gcd(tmp2, tmp1, clsig->e, ctx);
|
|
BN_sub(tmp1, cryptic_qrg_get_q(clsig->qrg), BN_value_one());
|
|
BN_gcd(tmp1, tmp1, clsig->e, ctx);
|
|
if(BN_is_one(tmp1) && BN_is_one(tmp2)){found=1;}
|
|
}
|
|
}
|
|
}
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_inverse(clsig->d,clsig->e,cryptic_qrg_get_phi(clsig->qrg),ctx));
|
|
goto_cleanup_if_fail_with_warning(clsig->d != NULL);
|
|
/* TODO: test that d is big enough (Wiener attack)*/
|
|
|
|
goto_cleanup_if_fail_with_warning(cryptic_clsig_verify_rsa_param(clsig) == 1);
|
|
|
|
clsig->lg_exponent = lg_exponent;
|
|
|
|
rc = CRYPTIC_NO_ERROR;
|
|
cleanup:
|
|
cryptic_release_ctx(ctx);
|
|
cryptic_release_bn(two);
|
|
cryptic_release_bn(lg2);
|
|
cryptic_release_bn(lg);
|
|
cryptic_release_bn(gcd);
|
|
cryptic_release_bn(tmp2);
|
|
cryptic_release_bn(tmp1);
|
|
return(rc);
|
|
}
|
|
|
|
/**
|
|
* cryptic_clsig_find_rsa_param
|
|
* @e: public exponent
|
|
*
|
|
* Compute the private exponent given the public exponent.
|
|
* The order of n only known by the issuer is given in clsig.
|
|
* Can be used to update the key pair
|
|
*
|
|
* Return value: #CRYPTIC_NO_ERROR if successful, an error code otherwise.
|
|
*
|
|
**/
|
|
int
|
|
//cryptic_clsig_find_rsa_param_from_pubexp(CrypticClsig *clsig, BIGNUM *e, BN_GENCB *cb)
|
|
cryptic_clsig_find_rsa_param_from_pubexp(CrypticClsig *clsig, BIGNUM *e)
|
|
{
|
|
/**************************************************************************
|
|
* WARNING: n is computed before choosing e
|
|
* It means that it must be checked before that coprime(e,phi(n))
|
|
* Generally you fix e and then you compute n testing that d is big enough
|
|
* If n does not fit, you compute an other n.
|
|
* You cannot do this here. You have to change e!
|
|
***************************************************************************/
|
|
int rc = CRYPTIC_ERROR_UNDEFINED;
|
|
|
|
BN_GENCB *cb = NULL;
|
|
|
|
BIGNUM *tmp1 = NULL,*tmp2 = NULL,*two = NULL,*lg = NULL;
|
|
BN_CTX *ctx = NULL;
|
|
|
|
cryptic_release_bn(clsig->e);
|
|
cryptic_release_bn(clsig->d);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->e = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->d = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(tmp1 = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(tmp2 = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(lg = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(two = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_set_word(two,2) == 1);
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(ctx = BN_CTX_new());
|
|
|
|
/* Take e in [2^le-1, 2^le-1 + 2^lei-1] */
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_set_word(lg,clsig->lg_exponent-1) == 1);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_exp(tmp1,two,lg, ctx));
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_set_word(lg,clsig->interval_exponent-1) == 1);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_exp(lg,two,lg, ctx));
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_add(lg,tmp1,lg));
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning(BN_num_bits(e) == clsig->lg_exponent,
|
|
CRYPTIC_CLSIG_EXPONENT_BAD_SIZE);
|
|
goto_cleanup_if_fail_with_rc_with_warning(BN_ucmp(e,lg) < 0,
|
|
CRYPTIC_CLSIG_EXPONENT_BAD_SIZE);
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(clsig->e,e));
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_inverse(clsig->d,clsig->e,cryptic_qrg_get_phi(clsig->qrg),ctx));
|
|
goto_cleanup_if_fail_with_warning(clsig->d != NULL);
|
|
|
|
goto_cleanup_if_fail_with_warning(cryptic_clsig_verify_rsa_param(clsig) == 1);
|
|
|
|
clsig->lg_exponent = BN_num_bits(clsig->e);
|
|
|
|
rc = CRYPTIC_NO_ERROR;
|
|
cleanup:
|
|
cryptic_release_ctx(ctx);
|
|
cryptic_release_bn(two);
|
|
cryptic_release_bn(lg);
|
|
cryptic_release_bn(tmp2);
|
|
cryptic_release_bn(tmp1);
|
|
return(rc);
|
|
}
|
|
|
|
/**
|
|
* cryptic_clsig_new_load_parameters_issuer
|
|
* @lg_modulus: bit length of the modulus.
|
|
* @lg_quantities: bit length of the quantities.
|
|
* @lg_exponent: bit length of the RSA exponent.
|
|
* @lg_sec_param: security parameter.
|
|
* @lg_zk_sec_param: security parameter for the zkpk.
|
|
* @lg_clsig_sec_param: security parameter for the clsig system.
|
|
* @nb_bases: nb of bases of represnetation.
|
|
* @bases: representation bases.
|
|
* @S: Blind base
|
|
* @Z: Base to proof a certificate
|
|
* @p: secret prime only known by the certificate issuer
|
|
*
|
|
* Creates a new #CrypticClsig.
|
|
* All parameters of the object are given in parameters
|
|
*
|
|
* Return value: a newly created #CrypticClsig object; or NULL if an error
|
|
* occured
|
|
**/
|
|
CrypticClsig*
|
|
cryptic_clsig_new_load_parameters_issuer(BIGNUM *p,
|
|
BIGNUM *Z,
|
|
BIGNUM *S,
|
|
int nb_bases,
|
|
BIGNUM **bases,
|
|
int lg_quantities,
|
|
int lg_exponent,
|
|
BIGNUM *modulus,
|
|
int lg_sec_param,
|
|
int lg_zk_sec_param,
|
|
int lg_clsig_sec_param)
|
|
// int lg_clsig_sec_param,
|
|
// BN_GENCB *cb)
|
|
{
|
|
int rc = CRYPTIC_ERROR_UNDEFINED;
|
|
|
|
BN_GENCB *cb = NULL;
|
|
|
|
CrypticClsig *clsig;
|
|
|
|
clsig = cryptic_clsig_new_load_public_parameters(Z,S,nb_bases,bases,lg_quantities,lg_exponent,modulus,lg_sec_param, lg_zk_sec_param, lg_clsig_sec_param);
|
|
if(clsig == NULL){
|
|
return NULL;
|
|
}
|
|
|
|
cryptic_release_gobject(clsig->qrg);
|
|
//clsig->qrg = cryptic_qrg_new_load(p,modulus, cb);
|
|
clsig->qrg = cryptic_qrg_new_load(p,modulus,S);
|
|
if(clsig->qrg == NULL){
|
|
cryptic_critical("Unable to load a quadratic residue group");
|
|
return NULL;
|
|
}
|
|
|
|
//if(cryptic_clsig_find_rsa_param(clsig, clsig->lg_exponent, cb) < 0) return NULL;
|
|
cryptic_check_good_rc(cryptic_clsig_find_rsa_param(clsig, clsig->lg_exponent));
|
|
|
|
return clsig;
|
|
cleanup:
|
|
cryptic_release_gobject(clsig);
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* cryptic_clsig_new_load_parameters_issuer
|
|
* @lg_modulus: bit length of the modulus.
|
|
* @lg_quantities: bit length of the quantities.
|
|
* @lg_exponent: bit length of the RSA exponent.
|
|
* @lg_sec_param: security parameter.
|
|
* @lg_zk_sec_param: security parameter for the zkpk.
|
|
* @lg_clsig_sec_param: security parameter for the clsig system.
|
|
* @nb_bases: nb of bases of represnetation.
|
|
* @bases: representation bases.
|
|
* @S: Blind base
|
|
* @Z: Base to proof a certificate
|
|
*
|
|
* Creates a new #CrypticClsig.
|
|
* All public parameters of the object are given in parameters
|
|
*
|
|
* Return value: a newly created #CrypticClsig object; or NULL if an error
|
|
* occured
|
|
**/
|
|
CrypticClsig*
|
|
cryptic_clsig_new_load_public_parameters(BIGNUM *Z,
|
|
BIGNUM *S,
|
|
int nb_bases,
|
|
BIGNUM **bases,
|
|
int lg_quantities,
|
|
int lg_exponent,
|
|
BIGNUM *modulus,
|
|
int lg_sec_param,
|
|
int lg_zk_sec_param,
|
|
int lg_clsig_sec_param)
|
|
{
|
|
int rc = CRYPTIC_ERROR_UNDEFINED;
|
|
|
|
CrypticClsig *clsig = NULL;
|
|
|
|
if(!Z || !S || !bases || !modulus){
|
|
cryptic_critical("Unable to load CLSIG public parameters: element missing");
|
|
return NULL;
|
|
}
|
|
int i;
|
|
for(i=0;i<nb_bases;i++){
|
|
if(!bases[i]){
|
|
cryptic_critical("Unable to load CLSIG public parameters: element missing");
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
clsig = cryptic_clsig_new(BN_num_bits(modulus), lg_quantities, lg_exponent, lg_sec_param, lg_zk_sec_param, lg_clsig_sec_param, nb_bases);
|
|
if(clsig == NULL){
|
|
cryptic_critical("Error creating CrypticClsig object");
|
|
return NULL;
|
|
}
|
|
|
|
cryptic_release_bn(clsig->modulus);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->modulus = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(clsig->modulus, modulus));
|
|
cryptic_release_bn(clsig->S);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->S = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(clsig->S, S));
|
|
cryptic_release_bn(clsig->Z);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->Z = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(clsig->Z, Z));
|
|
|
|
cryptic_release(clsig->bases);
|
|
clsig->bases = g_malloc0(clsig->nb_bases * sizeof (**clsig->bases));
|
|
if(clsig->bases == NULL){
|
|
rc = CRYPTIC_MEMORY_ALLOCATION_FAILURE;
|
|
goto cleanup;
|
|
}
|
|
|
|
for(i=0;i<nb_bases;i++){
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->bases[i] = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(clsig->bases[i], bases[i]));
|
|
}
|
|
|
|
cryptic_release_bn(clsig->e);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->e = BN_new());
|
|
|
|
rc = CRYPTIC_NO_ERROR;
|
|
cleanup:
|
|
if(rc == CRYPTIC_NO_ERROR) return clsig;
|
|
return NULL;
|
|
}
|
|
|
|
int
|
|
cryptic_clsig_add_n_bases(CrypticClsig *clsig, int nb)
|
|
{
|
|
int rc = CRYPTIC_ERROR_UNDEFINED;
|
|
|
|
int i;
|
|
if(clsig->nb_bases == 0) {
|
|
cryptic_release(clsig->bases);
|
|
clsig->bases = g_malloc0(nb * sizeof (**clsig->bases));
|
|
if(clsig->bases == NULL){
|
|
rc = CRYPTIC_MEMORY_ALLOCATION_FAILURE;
|
|
goto cleanup;
|
|
}
|
|
for(i=0;i<nb;i++){
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->bases[i] = BN_new());
|
|
}
|
|
cryptic_check_good_rc(cryptic_qrg_pick_k_bases(clsig->qrg,clsig->bases,clsig->nb_bases));
|
|
clsig->nb_bases = nb;
|
|
}else{
|
|
BIGNUM **tmp = NULL;
|
|
tmp = clsig->bases;
|
|
clsig->bases = g_realloc(clsig->bases,(clsig->nb_bases+nb) * sizeof (**clsig->bases));
|
|
if(clsig->bases == NULL){
|
|
clsig->bases = tmp;
|
|
tmp = NULL;
|
|
rc = CRYPTIC_MEMORY_ALLOCATION_FAILURE;
|
|
goto cleanup;
|
|
}
|
|
for(i=0;i<nb;i++){
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->bases[clsig->nb_bases+i] = BN_new());
|
|
}
|
|
cryptic_check_good_rc(cryptic_qrg_pick_k_bases(clsig->qrg,clsig->bases+clsig->nb_bases,nb));
|
|
clsig->nb_bases = clsig->nb_bases + nb;
|
|
}
|
|
|
|
rc = CRYPTIC_NO_ERROR;
|
|
cleanup:
|
|
return rc;
|
|
}
|