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_vrf.c

554 lines
20 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 <openssl/bn.h>
#include <openssl/rsa.h>
#include "../../errors.h"
#include "../../utils.h"
#include "clsig.h"
/**
* Load certificate should always be used by the prover to check certificate validity
* because these functions rebuild the DL representation.
**/
/**
* cryptic_clsig_load_certificate
* @A: Signature value
* @e: RSA exponent
* @v: blind factor
* @quantities: quantities signed
* @nb_quantities: number of quantities
*
* Load a certificate: tuple (A,e,v) and the quantities.
* Compute the DL representation starting using the first base.
*
* Return value: #CRYPTIC_NO_ERROR if successful, an error code otherwise.
*
**/
int
cryptic_clsig_load_certificate(CrypticClsig *clsig,
BIGNUM *A,
BIGNUM *e,
BIGNUM *v,
BIGNUM **quantities,
int nb_quantities,
int sig_checking)
{
int rc = CRYPTIC_ERROR_UNDEFINED;
BIGNUM *tmp = NULL, *two = NULL, *lg = NULL;
BN_CTX *ctx = NULL;
goto_cleanup_if_fail_with_rc_with_warning(clsig->init == 1,
CRYPTIC_CLSIG_NOT_CORRECTLY_INITIALIZED);
goto_cleanup_if_fail_with_rc_with_warning(A != NULL,
CRYPTIC_CLSIG_LOADING_CERTIFICATE_MISSING_ELEMENT);
goto_cleanup_if_fail_with_rc_with_warning(e != NULL,
CRYPTIC_CLSIG_LOADING_CERTIFICATE_MISSING_ELEMENT);
goto_cleanup_if_fail_with_rc_with_warning(v != NULL,
CRYPTIC_CLSIG_LOADING_CERTIFICATE_MISSING_ELEMENT);
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_openssl(tmp = 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(tmp,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,tmp,lg));
goto_cleanup_if_fail_with_rc_with_warning(BN_ucmp(clsig->e,lg) < 0,
CRYPTIC_CLSIG_EXPONENT_BAD_SIZE);
cryptic_check_good_rc(cryptic_clsig_compute_dlrep_bulk_from_offset(clsig, quantities, 0, nb_quantities));
cryptic_release_bn(clsig->A);
cryptic_release_bn(clsig->e);
cryptic_release_bn(clsig->v);
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->A = BN_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(clsig->A,A));
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->e = BN_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(clsig->e,e));
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->v = BN_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(clsig->v,v));
clsig->sigloaded = 1;
if (sig_checking) {
cryptic_check_good_rc(cryptic_clsig_verify_signature_not_randomized(clsig));
}
rc = CRYPTIC_NO_ERROR;
cleanup:
cryptic_release_ctx(ctx);
cryptic_release_bn(two);
cryptic_release_bn(lg);
cryptic_release_bn(tmp);
return rc;
}
/**
* cryptic_clsig_load_certificate_with_index
* @A: Signature value
* @e: RSA exponent
* @v: blind factor
* @quantities: quantities signed
* @nb_quantities: number of quantities
* @index: indicate the bases of representation
*
* Load a certificate: tuple (A,e,v) and the quantities
* Compute the DL representation using the base given by the index.
*
* Return value: #CRYPTIC_NO_ERROR if successful, an error code otherwise.
*
**/
int
cryptic_clsig_load_certificate_with_index(CrypticClsig *clsig,
BIGNUM *A,
BIGNUM *e,
BIGNUM *v,
BIGNUM **quantities,
int nb_quantities,
int* index,
int sig_checking)
{
int rc = CRYPTIC_ERROR_UNDEFINED;
BIGNUM *tmp = NULL, *two = NULL, *lg = NULL;
BN_CTX *ctx = NULL;
goto_cleanup_if_fail_with_rc_with_warning(clsig->init == 1,
CRYPTIC_CLSIG_NOT_CORRECTLY_INITIALIZED);
goto_cleanup_if_fail_with_rc_with_warning(A != NULL,
CRYPTIC_CLSIG_LOADING_CERTIFICATE_MISSING_ELEMENT);
goto_cleanup_if_fail_with_rc_with_warning(e != NULL,
CRYPTIC_CLSIG_LOADING_CERTIFICATE_MISSING_ELEMENT);
goto_cleanup_if_fail_with_rc_with_warning(v != NULL,
CRYPTIC_CLSIG_LOADING_CERTIFICATE_MISSING_ELEMENT);
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_openssl(tmp = 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(tmp,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,tmp,lg));
goto_cleanup_if_fail_with_rc_with_warning(BN_ucmp(clsig->e,lg) < 0,
CRYPTIC_CLSIG_EXPONENT_BAD_SIZE);
cryptic_check_good_rc(cryptic_clsig_compute_dlrep_by_index(clsig, quantities, index, nb_quantities));
cryptic_release_bn(clsig->A);
cryptic_release_bn(clsig->e);
cryptic_release_bn(clsig->v);
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->A = BN_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(clsig->A,A));
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->e = BN_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(clsig->e,e));
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->v = BN_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(clsig->v,v));
clsig->sigloaded = 1;
if (sig_checking) {
cryptic_check_good_rc(cryptic_clsig_verify_signature_not_randomized(clsig));
}
rc = CRYPTIC_NO_ERROR;
cleanup:
cryptic_release_ctx(ctx);
cryptic_release_bn(two);
cryptic_release_bn(lg);
cryptic_release_bn(tmp);
return rc;
}
/**
* cryptic_clsig_load_certificate_with_committed_value
* @A: Signature value
* @e: RSA exponent
* @v: blind factor
* @quantities: quantities signed
* @nb_quantities: number of quantities
* @quantities: quantities committed signed
* @nb_quantities: number of quantities committed
* @vprime: blind factor of the quantities committed
* @commitment: Representation of the quantities committed
*
* Load a certificate: tuple (A,e,v) and the quantities
* The bases for the not commited values are taken in order from the first one.
*
* Return value: #CRYPTIC_NO_ERROR if successful, an error code otherwise.
*
**/
int
cryptic_clsig_load_certificate_with_committed_value(CrypticClsig *clsig,
BIGNUM *A,
BIGNUM *e,
BIGNUM *v,
BIGNUM **quantities, int nb_quantities,
BIGNUM **quantitiesC, int nb_quantitiesC,
BIGNUM *commitment, BIGNUM *vprime)
{
int rc = CRYPTIC_ERROR_UNDEFINED;
int i;
BIGNUM *tmp = NULL;
BN_CTX *ctx = NULL;
goto_cleanup_if_fail_with_rc_with_warning(clsig->init == 1,
CRYPTIC_CLSIG_NOT_CORRECTLY_INITIALIZED);
goto_cleanup_if_fail_with_rc_with_warning(vprime != NULL,
CRYPTIC_CLSIG_MISSING_SIGN_BLIND_RANDOM);
goto_cleanup_if_fail_with_rc_with_warning(commitment != NULL,
CRYPTIC_CLSIG_MISSING_SIGN_BLIND_COMMITMENT);
goto_cleanup_if_fail_with_rc_with_warning(nb_quantitiesC > 0,
CRYPTIC_CLSIG_NO_VALID_QUANTITIES_NUMBER);
goto_cleanup_if_fail_with_rc_with_warning(quantitiesC != NULL,
CRYPTIC_CLSIG_MISSING_QUANTITIES);
for(i=0;i<nb_quantitiesC;i++){
goto_cleanup_if_fail_with_rc_with_warning(quantitiesC[i] != NULL,
CRYPTIC_CLSIG_MISSING_QUANTITIES);
goto_cleanup_if_fail_with_rc_with_warning(BN_num_bits(quantitiesC[i]) <= clsig->lg_quantities,
CRYPTIC_CLSIG_QUANTITY_TOO_LARGE);
}
goto_cleanup_if_fail_with_rc_with_warning_openssl(tmp = BN_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(ctx = BN_CTX_new());
cryptic_check_good_rc(cryptic_clsig_load_certificate(clsig, A, e, v, quantities, nb_quantities, 0));
/* commitment = committed_dlrep * S^vprime */
/* commitment * S^-vprime = committed_dlrep */
/* clsig->dlrep := clsig->dlrep * committed_dlrep */
/* clsig->v := clsig->v + vprime */
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_inverse(tmp,clsig->S,clsig->modulus,ctx));
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp(tmp,tmp,vprime,clsig->modulus,ctx) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(tmp,tmp,commitment,clsig->modulus,ctx) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(clsig->dlrep,clsig->dlrep,tmp,clsig->modulus,ctx) == 1);
clsig->sigloaded = 1;
for(i=0;i<nb_quantitiesC;i++){
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->quantities[clsig->nb_quantities+i] = BN_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(clsig->quantities[clsig->nb_quantities+i],quantitiesC[i]));
}
clsig->nb_quantities = clsig->nb_quantities + nb_quantitiesC;
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_add(clsig->v,clsig->v,vprime));
rc = cryptic_clsig_verify_signature_not_randomized(clsig);
if(rc == 1){
rc = CRYPTIC_NO_ERROR;
}
cleanup:
cryptic_release_ctx(ctx);
cryptic_release_bn(tmp);
return rc;
}
/**
* cryptic_clsig_load_certificate_with_index_with_committed_value
* @A: Signature value
* @e: RSA exponent
* @v: blind factor
* @quantities: quantities signed
* @nb_quantities: number of quantities
* @quantities: quantities committed signed
* @nb_quantities: number of quantities committed
* @vprime: blind factor of the quantities committed
* @commitment: Representation of the quantities committed
* @index: index of the bases used for representation
*
* Load a certificate: tuple (A,e,v) and the quantities
* Compute the DL representation using the base given by the index for the not committed values.
* WARNING: index of the bases used for the not committed to the issuer values
*
* Return value: #CRYPTIC_NO_ERROR if successful, an error code otherwise.
*
**/
int
cryptic_clsig_load_certificate_with_index_with_committed_value(CrypticClsig *clsig,
BIGNUM *A,
BIGNUM *e,
BIGNUM *v,
BIGNUM **quantities, int nb_quantities,
BIGNUM **quantitiesC, int nb_quantitiesC,
BIGNUM *commitment, BIGNUM *vprime,
int *index)
{
int rc = CRYPTIC_ERROR_UNDEFINED;
int i;
BIGNUM *tmp = NULL;
BN_CTX *ctx = NULL;
goto_cleanup_if_fail_with_rc_with_warning(clsig->init == 1,
CRYPTIC_CLSIG_NOT_CORRECTLY_INITIALIZED);
goto_cleanup_if_fail_with_rc_with_warning(vprime != NULL,
CRYPTIC_CLSIG_MISSING_SIGN_BLIND_RANDOM);
goto_cleanup_if_fail_with_rc_with_warning(commitment != NULL,
CRYPTIC_CLSIG_MISSING_SIGN_BLIND_COMMITMENT);
goto_cleanup_if_fail_with_rc_with_warning(nb_quantitiesC > 0,
CRYPTIC_CLSIG_NO_VALID_QUANTITIES_NUMBER);
goto_cleanup_if_fail_with_rc_with_warning(quantitiesC != NULL,
CRYPTIC_CLSIG_MISSING_QUANTITIES);
for(i=0;i<nb_quantitiesC;i++){
goto_cleanup_if_fail_with_rc_with_warning(quantitiesC[i] != NULL,
CRYPTIC_CLSIG_MISSING_QUANTITIES);
goto_cleanup_if_fail_with_rc_with_warning(BN_num_bits(quantitiesC[i]) <= clsig->lg_quantities,
CRYPTIC_CLSIG_QUANTITY_TOO_LARGE);
}
goto_cleanup_if_fail_with_rc_with_warning_openssl(tmp = BN_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(ctx = BN_CTX_new());
cryptic_check_good_rc(cryptic_clsig_load_certificate_with_index(clsig, A, e, v, quantities, nb_quantities, index, 0));
/* commitment = committed_dlrep * S^vprime */
/* commitment * S^-vprime = committed_dlrep */
/* clsig->dlrep := clsig->dlrep * committed_dlrep */
/* clsig->v := clsig->v + vprime */
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_inverse(tmp,clsig->S,clsig->modulus,ctx));
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp(tmp,tmp,vprime,clsig->modulus,ctx) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(tmp,tmp,commitment,clsig->modulus,ctx) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(clsig->dlrep,clsig->dlrep,tmp,clsig->modulus,ctx) == 1);
clsig->sigloaded = 1;
for(i=0;i<nb_quantitiesC;i++){
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->quantities[clsig->nb_quantities+i] = BN_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(clsig->quantities[clsig->nb_quantities+i],quantitiesC[i]));
}
clsig->nb_quantities = clsig->nb_quantities + nb_quantitiesC;
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_add(clsig->v,clsig->v,vprime));
rc = cryptic_clsig_verify_signature_not_randomized(clsig);
if(rc == 1){
rc = CRYPTIC_NO_ERROR;
}
cleanup:
cryptic_release_ctx(ctx);
cryptic_release_bn(tmp);
return rc;
}
/**
* cryptic_clsig_verify_signature_not_randomized
*
* Verify a signature value not randomized.
*
* Return value: 1 if signature valid, 0 if signature invalid, an error code otherwise.
*
**/
int
cryptic_clsig_verify_signature_not_randomized(CrypticClsig *clsig)
{
int rc = CRYPTIC_ERROR_UNDEFINED;
int res;
BIGNUM *tmp1 = NULL, *tmp2 = NULL;
BN_CTX *ctx = NULL;
BN_MONT_CTX *mont = NULL;
goto_cleanup_if_fail_with_rc_with_warning(clsig->init == 1,
CRYPTIC_CLSIG_NOT_CORRECTLY_INITIALIZED);
goto_cleanup_if_fail_with_rc_with_warning(clsig->sigloaded == 1,
CRYPTIC_CLSIG_SIGNATURE_NOT_CORRECTLY_LOADED);
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(ctx = BN_CTX_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(mont=BN_MONT_CTX_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_MONT_CTX_set(mont,clsig->modulus,ctx));
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(tmp1,clsig->S,clsig->v,clsig->modulus,ctx,mont) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(tmp1,tmp1,clsig->dlrep,clsig->modulus,ctx) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(tmp2,clsig->A,clsig->e,clsig->modulus,ctx,mont) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(tmp1,tmp1,tmp2,clsig->modulus,ctx) == 1);
if (BN_ucmp(clsig->Z, tmp1) == 0){
clsig->sigverified = 1;
res = 1;
} else{
res = 0;
}
rc = CRYPTIC_NO_ERROR;
cleanup:
cryptic_release_ctx(ctx);
cryptic_release_mont(mont);
cryptic_release_bn(tmp2);
cryptic_release_bn(tmp1);
if(rc != CRYPTIC_NO_ERROR) return rc;
return res;
}
/**
* cryptic_clsig_verify_signature_not_randomized_prover
*
* Verify a signature value randomized.
*
* Return value: 1 if signature valid, 0 if signature invalid, an error code otherwise.
*
**/
int
cryptic_clsig_verify_signature_randomized(CrypticClsig *clsig)
{
int rc = CRYPTIC_ERROR_UNDEFINED;
int res;
BIGNUM *tmp1 = NULL, *tmp2 = NULL;
BN_CTX *ctx = NULL;
BN_MONT_CTX *mont = NULL;
goto_cleanup_if_fail_with_rc_with_warning(clsig->sigrandomized == 1,
CRYPTIC_CLSIG_SIGNATURE_NOT_RANDOMIZED);
goto_cleanup_if_fail_with_rc_with_warning(clsig->A_rand != NULL,
CRYPTIC_CLSIG_SIGNATURE_NOT_RANDOMIZED);
goto_cleanup_if_fail_with_rc_with_warning(clsig->e_corrected != NULL,
CRYPTIC_CLSIG_SIGNATURE_NOT_RANDOMIZED);
goto_cleanup_if_fail_with_rc_with_warning(clsig->v_rand != NULL,
CRYPTIC_CLSIG_SIGNATURE_NOT_RANDOMIZED);
goto_cleanup_if_fail_with_rc_with_warning(clsig->S != NULL,
CRYPTIC_CLSIG_SIGNATURE_NOT_RANDOMIZED);
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(ctx = BN_CTX_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(mont=BN_MONT_CTX_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_MONT_CTX_set(mont,clsig->modulus,ctx));
if(BN_is_negative(clsig->v_rand)){
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(tmp2,clsig->S));
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_inverse(clsig->S,clsig->S,clsig->modulus,ctx));
}
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(tmp1,clsig->S,clsig->v_rand,clsig->modulus,ctx,mont) == 1);
if(BN_is_negative(clsig->v_rand)) goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(clsig->S,tmp2));
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(tmp2,clsig->A_rand,clsig->e,clsig->modulus,ctx,mont) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(tmp1,tmp1,tmp2,clsig->modulus,ctx) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(tmp1,tmp1,clsig->dlrep,clsig->modulus,ctx) == 1);
if (BN_ucmp(clsig->Z, tmp1) == 0){
res = 1;
} else{
res = 0;
}
rc = CRYPTIC_NO_ERROR;
cleanup:
cryptic_release_ctx(ctx);
cryptic_release_mont(mont);
cryptic_release_bn(tmp2);
cryptic_release_bn(tmp1);
if(rc != CRYPTIC_NO_ERROR) return rc;
return res;
}
/**
* cryptic_clsig_verify_rsa_param
*
* Check validity of a RSA key pair.
*
* Return value: 1 if signature valid, 0 if signature invalid, an error code otherwise.
*
**/
int
cryptic_clsig_verify_rsa_param(CrypticClsig *clsig)
{
int rc = CRYPTIC_ERROR_UNDEFINED;
BIGNUM *tmp1 = NULL, *tmp2 = NULL;
BN_CTX *ctx = NULL;
RSA *key = RSA_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(key->n = BN_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(key->e = BN_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(key->d = BN_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(key->p = BN_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(key->q = BN_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(key->dmp1 = BN_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(key->dmq1 = BN_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(key->iqmp = BN_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(ctx = BN_CTX_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(key->n,clsig->modulus));
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(key->p,cryptic_qrg_get_p(clsig->qrg)));
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(key->q,cryptic_qrg_get_q(clsig->qrg)));
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(key->e,clsig->e));
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(key->d,clsig->d));
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_sub(tmp1,cryptic_qrg_get_p(clsig->qrg),BN_value_one()));
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod(key->dmp1,key->d,tmp1,ctx));
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_sub(tmp1,key->q,BN_value_one()));
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod(key->dmq1,key->d,tmp1,ctx));
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_inverse(key->iqmp,key->q,key->p,ctx));
/*if (r == 1){
printf("RSA key ok\n");
}
else if (r == 0){
printf("RSA key ko\n");
unsigned long err;
while ((err = ERR_peek_error()) != 0 ){
printf("RSA key error: %d\n", ERR_reason_error_string(err));
ERR_get_error();
}
}*/
goto_cleanup_if_fail_with_rc_with_warning(RSA_check_key(key) == 1, CRYPTIC_CLSIG_BAD_RSA_KEY_PAIR);
rc = CRYPTIC_NO_ERROR;
cleanup:
cryptic_release_ctx(ctx);
cryptic_release_bn(tmp2);
cryptic_release_bn(tmp1);
if(key) RSA_free(key);
if(rc == CRYPTIC_NO_ERROR) return 1;
return rc;
}