216 lines
8.0 KiB
C
Executable File
216 lines
8.0 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 "../../errors.h"
|
|
#include "../../utils.h"
|
|
|
|
#include "clsig.h"
|
|
|
|
/**
|
|
* cryptic_clsig_sign
|
|
*
|
|
* Produce a signature value for a DL representation.
|
|
* In other words, makes a certificate and signed it.
|
|
* tuple (A,e,v)
|
|
*
|
|
* Return value: #CRYPTIC_NO_ERROR if successful, an error code otherwise.
|
|
*
|
|
**/
|
|
int
|
|
cryptic_clsig_sign(CrypticClsig *clsig)
|
|
{
|
|
int rc = CRYPTIC_ERROR_UNDEFINED;
|
|
|
|
BIGNUM *tmp1 = NULL,*tmp2 = NULL,*gcd = NULL, *two = 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_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(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());
|
|
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));
|
|
|
|
cryptic_release_bn(clsig->v);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->v = BN_new());
|
|
cryptic_check_good_rc(cryptic_find_random(clsig->v,clsig->lg_blind));
|
|
|
|
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_gcd(gcd, tmp1, clsig->modulus, ctx) == 1);
|
|
goto_cleanup_if_fail_with_rc_with_warning(BN_ucmp(gcd, BN_value_one()) == 0,
|
|
CRYPTIC_CLSIG_EXPONENTIATION_S_NOT_INVERSIBLE);
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_inverse(tmp2,tmp1,clsig->modulus,ctx));
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(tmp1,clsig->Z,tmp2,clsig->modulus,ctx) == 1);
|
|
|
|
/******************************************************
|
|
* TODO: computation of the signature
|
|
* using the Chinese Remainder Theorem (CRT)
|
|
* we need dmp = d mod p, dmq = d mod q and iqmp = 1/q mod p AND p>q
|
|
* m1 = c^dmp mod p
|
|
* m2 = c^dmq mod q
|
|
* h = iqmp(m1 - m2) mod p
|
|
* signed_value = m2 + q*h
|
|
* The complexity in time is four time better:
|
|
* lq env = lp env = ln/2 and the complexity in time is squared
|
|
*******************************************************/
|
|
/* New RSA key pair for each certificate */
|
|
cryptic_check_good_rc(cryptic_clsig_find_rsa_param(clsig, clsig->lg_exponent));
|
|
|
|
cryptic_release_bn(clsig->A);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->A = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(clsig->A,tmp1,clsig->d,clsig->modulus,ctx,mont) == 1);
|
|
|
|
clsig->sigloaded = 1;
|
|
clsig->sigverified = 0;
|
|
clsig->sigrandomized = 0;
|
|
|
|
rc = CRYPTIC_NO_ERROR;
|
|
cleanup:
|
|
cryptic_release_ctx(ctx);
|
|
cryptic_release_mont(mont);
|
|
cryptic_release_bn(two);
|
|
cryptic_release_bn(gcd);
|
|
cryptic_release_bn(tmp2);
|
|
cryptic_release_bn(tmp1);
|
|
return rc;
|
|
}
|
|
|
|
/**
|
|
* cryptic_clsig_sign_with_committed_value
|
|
*
|
|
* Produce a signature value for a DL representation
|
|
* with a commited value given in parameter.
|
|
* In other words, makes a certificate and signed it.
|
|
* tuple (A,e,v)
|
|
*
|
|
* Return value: #CRYPTIC_NO_ERROR if successful, an error code otherwise.
|
|
*
|
|
**/
|
|
int
|
|
cryptic_clsig_sign_with_committed_value(CrypticClsig *clsig, BIGNUM *commitment)
|
|
{
|
|
int rc = CRYPTIC_ERROR_UNDEFINED;
|
|
|
|
BN_CTX *ctx = NULL;
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(ctx = BN_CTX_new());
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning(clsig->init == 1,
|
|
CRYPTIC_CLSIG_NOT_CORRECTLY_INITIALIZED);
|
|
goto_cleanup_if_fail_with_rc_with_warning(commitment != NULL,
|
|
CRYPTIC_CLSIG_SIGNATURE_WITH_COMMIT_MISSING_ELEMENT);
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(clsig->dlrep,clsig->dlrep,commitment,clsig->modulus,ctx) == 1);
|
|
|
|
cryptic_check_good_rc(cryptic_clsig_sign(clsig));
|
|
|
|
rc = CRYPTIC_NO_ERROR;
|
|
cleanup:
|
|
cryptic_release_ctx(ctx);
|
|
return rc;
|
|
}
|
|
|
|
/**
|
|
* cryptic_clsig_randomize_signature
|
|
*
|
|
* Randomize a signature.
|
|
* tuple (A_rand,e_corrected,v_rand)
|
|
*
|
|
* Return value: #CRYPTIC_NO_ERROR if successful, an error code otherwise.
|
|
*
|
|
**/
|
|
int
|
|
cryptic_clsig_randomize_signature(CrypticClsig *clsig)
|
|
{
|
|
int rc = CRYPTIC_ERROR_UNDEFINED;
|
|
|
|
BIGNUM *tmp = NULL,*gcd = NULL,*two = NULL,*lg = NULL;
|
|
BN_CTX *ctx = NULL;
|
|
BN_MONT_CTX *mont = NULL;
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning(clsig->sigverified == 1,
|
|
CRYPTIC_CLSIG_SIGNATURE_NOT_VALIDATED_TO_RANDOMIZE);
|
|
goto_cleanup_if_fail_with_rc_with_warning(clsig->A != NULL,
|
|
CRYPTIC_CLSIG_SIGNATURE_NOT_VALIDATED_TO_RANDOMIZE);
|
|
goto_cleanup_if_fail_with_rc_with_warning(clsig->e != NULL,
|
|
CRYPTIC_CLSIG_SIGNATURE_NOT_VALIDATED_TO_RANDOMIZE);
|
|
goto_cleanup_if_fail_with_rc_with_warning(clsig->v != NULL,
|
|
CRYPTIC_CLSIG_SIGNATURE_NOT_VALIDATED_TO_RANDOMIZE);
|
|
goto_cleanup_if_fail_with_rc_with_warning(clsig->S != NULL,
|
|
CRYPTIC_CLSIG_SIGNATURE_NOT_VALIDATED_TO_RANDOMIZE);
|
|
|
|
cryptic_release_bn(clsig->r);
|
|
cryptic_release_bn(clsig->A_rand);
|
|
cryptic_release_bn(clsig->v_rand);
|
|
cryptic_release_bn(clsig->e_corrected);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->r = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->A_rand = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->v_rand = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->e_corrected = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(tmp = 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(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());
|
|
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));
|
|
|
|
/* ln + l0 */
|
|
cryptic_check_good_rc(cryptic_find_random(clsig->r,clsig->lg_modulus + clsig->lg_zk_sec_param)); //r_rho
|
|
|
|
/* A_rand = A.S^r */
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(tmp,clsig->S,clsig->r,clsig->modulus,ctx,mont) == 1);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(clsig->A_rand,clsig->A,tmp,clsig->modulus,ctx) == 1);
|
|
|
|
/* v_rand = v -e.r */
|
|
/* in Z -> no modulo to randomize v_rand */
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mul(tmp,clsig->e,clsig->r,ctx) == 1);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_sub(clsig->v_rand,clsig->v,tmp) == 1);
|
|
|
|
/* e_corrected = e - 2^le-1*/
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_set_word(tmp,clsig->lg_exponent-1) == 1);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_exp(lg,two,tmp,ctx));
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_sub(clsig->e_corrected,clsig->e,lg) == 1);
|
|
|
|
clsig->sigrandomized = 1;
|
|
|
|
rc = CRYPTIC_NO_ERROR;
|
|
|
|
cleanup:
|
|
cryptic_release_ctx(ctx);
|
|
cryptic_release_mont(mont);
|
|
cryptic_release_bn(two);
|
|
cryptic_release_bn(lg);
|
|
cryptic_release_bn(gcd);
|
|
cryptic_release_bn(tmp);
|
|
return rc;
|
|
}
|
|
|