This repository has been archived on 2023-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
cryptic/cryptic/protocols/clsig/clsig_gen.c

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;
}