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

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