793 lines
24 KiB
C
Executable File
793 lines
24 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"
|
|
#include "../../maths/quadratic_residues_group.h"
|
|
#include "../pok_schnorr/schnorr_zkpk.h"
|
|
#include "commit_data_store.h"
|
|
|
|
/**
|
|
* cryptic_clsig_compute_dlrep_with_random_quantities:
|
|
* @nb_quantities: Number of quantities to generate
|
|
*
|
|
* Mainly a test function, generate random quantities.
|
|
*
|
|
* Return value: #CRYPTIC_NO_ERROR if successful, an error code otherwise.
|
|
*
|
|
**/
|
|
int
|
|
cryptic_clsig_compute_dlrep_with_random_quantities(CrypticClsig *clsig, int nb_quantities)
|
|
{
|
|
int rc = CRYPTIC_ERROR_UNDEFINED;
|
|
|
|
BIGNUM *tmp = NULL;
|
|
BN_CTX *ctx = NULL;
|
|
BN_MONT_CTX *mont = NULL;
|
|
|
|
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());
|
|
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(clsig->init == 1,
|
|
CRYPTIC_CLSIG_NOT_CORRECTLY_INITIALIZED);
|
|
goto_cleanup_if_fail_with_rc_with_warning(nb_quantities <= clsig->nb_bases,
|
|
CRYPTIC_CLSIG_TOO_MUCH_QUANTITIES);
|
|
|
|
clsig->nb_quantities = nb_quantities;
|
|
|
|
cryptic_release(clsig->quantities);
|
|
clsig->quantities = g_malloc0(clsig->nb_quantities * sizeof (**clsig->quantities));
|
|
if(clsig->quantities == NULL){
|
|
rc = CRYPTIC_MEMORY_ALLOCATION_FAILURE;
|
|
goto cleanup;
|
|
}
|
|
|
|
/* Random mesages */
|
|
int i;
|
|
for(i=0;i<clsig->nb_quantities;i++){
|
|
clsig->quantities[i] = NULL;
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->quantities[i] = BN_new());
|
|
cryptic_check_good_rc(cryptic_find_random(clsig->quantities[i],clsig->lg_quantities));
|
|
}
|
|
|
|
cryptic_release_bn(clsig->dlrep);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->dlrep = BN_new());
|
|
BN_copy(clsig->dlrep,BN_value_one());
|
|
|
|
for(i=0;i<clsig->nb_quantities;i++){
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(tmp,clsig->bases[i],clsig->quantities[i],clsig->modulus,ctx,mont) == 1);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(clsig->dlrep,clsig->dlrep,tmp,clsig->modulus,ctx) == 1);
|
|
}
|
|
|
|
cleanup:
|
|
cryptic_release_ctx(ctx);
|
|
cryptic_release_mont(mont);
|
|
cryptic_release_bn(tmp);
|
|
return(CRYPTIC_NO_ERROR);
|
|
}
|
|
|
|
/**
|
|
* cryptic_clsig_compute_dlrep_with_random_quantities:
|
|
* @quantities: Quantities to represent
|
|
* @nb_quantities: Number of quantities to represent
|
|
* @index: Index of the base of representation
|
|
*
|
|
* Helper function to represent quantities.
|
|
* The quantities given are represented with the bases indicated by the index.
|
|
*
|
|
* Return value: #CRYPTIC_NO_ERROR if successful, an error code otherwise.
|
|
*
|
|
**/
|
|
int
|
|
cryptic_clsig_compute_dlrep_by_index(CrypticClsig *clsig, BIGNUM **quantities, int *index, int nb_quantities)
|
|
{
|
|
int rc = CRYPTIC_ERROR_UNDEFINED;
|
|
|
|
int i;
|
|
BIGNUM *tmp = NULL;
|
|
BN_CTX *ctx = NULL;
|
|
BN_MONT_CTX *mont = NULL;
|
|
|
|
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());
|
|
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(clsig->init == 1,
|
|
CRYPTIC_CLSIG_NOT_CORRECTLY_INITIALIZED);
|
|
goto_cleanup_if_fail_with_rc_with_warning(nb_quantities <= clsig->nb_bases,
|
|
CRYPTIC_CLSIG_TOO_MUCH_QUANTITIES);
|
|
|
|
clsig->nb_quantities = nb_quantities;
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning(quantities != NULL,
|
|
CRYPTIC_CLSIG_MISSING_QUANTITIES);
|
|
for(i=0;i<clsig->nb_quantities;i++){
|
|
goto_cleanup_if_fail_with_rc_with_warning(quantities[i] != NULL,
|
|
CRYPTIC_CLSIG_MISSING_QUANTITIES);
|
|
goto_cleanup_if_fail_with_rc_with_warning(BN_num_bits(quantities[i]) <= clsig->lg_quantities,
|
|
CRYPTIC_CLSIG_QUANTITY_TOO_LARGE);
|
|
}
|
|
|
|
cryptic_release(clsig->quantities);
|
|
clsig->quantities = g_malloc0(clsig->nb_quantities * sizeof (**clsig->quantities));
|
|
if(clsig->quantities == NULL){
|
|
rc = CRYPTIC_MEMORY_ALLOCATION_FAILURE;
|
|
goto cleanup;
|
|
}
|
|
|
|
cryptic_release_bn(clsig->dlrep);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->dlrep = BN_new());
|
|
BN_copy(clsig->dlrep,BN_value_one());
|
|
|
|
for(i=0;i<clsig->nb_quantities;i++){
|
|
clsig->quantities[i] = NULL;
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->quantities[i] = BN_new());
|
|
BN_copy(clsig->quantities[i],quantities[i]);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(tmp,clsig->bases[index[i]],quantities[i],clsig->modulus,ctx,mont) == 1);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(clsig->dlrep,clsig->dlrep,tmp,clsig->modulus,ctx) == 1);
|
|
}
|
|
|
|
rc = CRYPTIC_NO_ERROR;
|
|
cleanup:
|
|
cryptic_release_ctx(ctx);
|
|
cryptic_release_mont(mont);
|
|
cryptic_release_bn(tmp);
|
|
return rc;
|
|
}
|
|
|
|
/**
|
|
* cryptic_clsig_compute_dlrep_with_random_quantities:
|
|
* @quantities: Quantities to represent
|
|
* @nb_quantities: Number of quantities to represent
|
|
* @index: position of the first base.
|
|
*
|
|
* Helper function to represent quantities.
|
|
* The quantities given are represented with the bases ordered from the position given by the offset.
|
|
*
|
|
* Return value: #CRYPTIC_NO_ERROR if successful, an error code otherwise.
|
|
*
|
|
**/
|
|
int
|
|
cryptic_clsig_compute_dlrep_bulk_from_offset(CrypticClsig *clsig, BIGNUM **quantities, int offset, int nb_quantities)
|
|
{
|
|
int rc = CRYPTIC_ERROR_UNDEFINED;
|
|
|
|
int i;
|
|
BIGNUM *tmp = NULL;
|
|
BN_CTX *ctx = NULL;
|
|
BN_MONT_CTX *mont = NULL;
|
|
|
|
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());
|
|
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(clsig->init == 1,
|
|
CRYPTIC_CLSIG_NOT_CORRECTLY_INITIALIZED);
|
|
goto_cleanup_if_fail_with_rc_with_warning(nb_quantities <= clsig->nb_bases,
|
|
CRYPTIC_CLSIG_TOO_MUCH_QUANTITIES);
|
|
|
|
clsig->nb_quantities = nb_quantities;
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning(quantities != NULL,
|
|
CRYPTIC_CLSIG_MISSING_QUANTITIES);
|
|
for(i=0;i<clsig->nb_quantities;i++){
|
|
goto_cleanup_if_fail_with_rc_with_warning(quantities[i] != NULL,
|
|
CRYPTIC_CLSIG_MISSING_QUANTITIES);
|
|
goto_cleanup_if_fail_with_rc_with_warning(BN_num_bits(quantities[i]) <= clsig->lg_quantities,
|
|
CRYPTIC_CLSIG_QUANTITY_TOO_LARGE);
|
|
}
|
|
|
|
cryptic_release(clsig->quantities);
|
|
clsig->quantities = g_malloc0(clsig->nb_quantities * sizeof (**clsig->quantities));
|
|
if(clsig->quantities == NULL){
|
|
rc = CRYPTIC_MEMORY_ALLOCATION_FAILURE;
|
|
goto cleanup;
|
|
}
|
|
|
|
cryptic_release_bn(clsig->dlrep);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->dlrep = BN_new());
|
|
BN_copy(clsig->dlrep,BN_value_one());
|
|
|
|
for(i=0;i<clsig->nb_quantities;i++){
|
|
clsig->quantities[i] = NULL;
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->quantities[i] = BN_new());
|
|
BN_copy(clsig->quantities[i],quantities[i]);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(tmp,clsig->bases[i+offset],quantities[i],clsig->modulus,ctx,mont) == 1);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(clsig->dlrep,clsig->dlrep,tmp,clsig->modulus,ctx) == 1);
|
|
}
|
|
|
|
rc = CRYPTIC_NO_ERROR;
|
|
cleanup:
|
|
cryptic_release_ctx(ctx);
|
|
cryptic_release_mont(mont);
|
|
cryptic_release_bn(tmp);
|
|
return rc;
|
|
}
|
|
|
|
/**
|
|
* cryptic_clsig_compute_committed_value:
|
|
* @quantities: Quantities to represent
|
|
* @nb_quantities: Number of quantities to represent
|
|
* @bases: bases of representation
|
|
* @vprime: blind factor randomly generated
|
|
* @dlrep: the resulting representation
|
|
*
|
|
* Compute the representation of quantities to commit.
|
|
*
|
|
* Return value: #CRYPTIC_NO_ERROR if successful, an error code otherwise.
|
|
*
|
|
**/
|
|
int
|
|
cryptic_clsig_compute_committed_value(CrypticClsig *clsig, CrypticCommitDataStore *pdc, BIGNUM** bases, BIGNUM** quantities, int nb_quantities)
|
|
{
|
|
int rc = CRYPTIC_ERROR_UNDEFINED;
|
|
|
|
int i;
|
|
BIGNUM *tmp = NULL;
|
|
BN_CTX *ctx = NULL;
|
|
BN_MONT_CTX *mont = NULL;
|
|
|
|
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());
|
|
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(clsig->init == 1,
|
|
CRYPTIC_CLSIG_NOT_CORRECTLY_INITIALIZED);
|
|
goto_cleanup_if_fail_with_rc_with_warning(pdc != NULL,
|
|
CRYPTIC_ERROR_FUNCTION_PARAMETER_NOT_ALLOCATED);
|
|
goto_cleanup_if_fail_with_rc_with_warning(nb_quantities > 0,
|
|
CRYPTIC_CLSIG_NO_VALID_QUANTITIES_NUMBER);
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning(quantities != NULL,
|
|
CRYPTIC_CLSIG_MISSING_QUANTITIES);
|
|
for(i=0;i<nb_quantities;i++){
|
|
goto_cleanup_if_fail_with_rc_with_warning(quantities[i] != NULL,
|
|
CRYPTIC_CLSIG_MISSING_QUANTITIES);
|
|
goto_cleanup_if_fail_with_rc_with_warning(BN_num_bits(quantities[i]) <= clsig->lg_quantities,
|
|
CRYPTIC_CLSIG_QUANTITY_TOO_LARGE);
|
|
}
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning(bases != NULL,
|
|
CRYPTIC_CLSIG_MISSING_BASES);
|
|
for(i=0;i<nb_quantities;i++){
|
|
goto_cleanup_if_fail_with_rc_with_warning(bases[i] != NULL,
|
|
CRYPTIC_CLSIG_MISSING_BASES);
|
|
}
|
|
|
|
cryptic_release_bn(pdc->dlrep);
|
|
cryptic_release_bn(pdc->vprime);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(pdc->dlrep = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(pdc->vprime = BN_new());
|
|
|
|
cryptic_check_good_rc(cryptic_find_random(pdc->vprime, clsig->lg_modulus + clsig->lg_zk_sec_param));
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(pdc->dlrep,clsig->S,pdc->vprime,clsig->modulus,ctx,mont) == 1);
|
|
for(i=0;i<nb_quantities;i++){
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(tmp,bases[i],quantities[i],clsig->modulus,ctx,mont) == 1);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(pdc->dlrep,pdc->dlrep,tmp,clsig->modulus,ctx) == 1);
|
|
}
|
|
|
|
rc = CRYPTIC_NO_ERROR;
|
|
cleanup:
|
|
cryptic_release_ctx(ctx);
|
|
cryptic_release_mont(mont);
|
|
cryptic_release_bn(tmp);
|
|
return rc;
|
|
}
|
|
|
|
/**
|
|
* cryptic_clsig_compute_committed_value_with_index:
|
|
* @quantities: Quantities to represent
|
|
* @nb_quantities: Number of quantities to represent
|
|
* @index: index of the bases of representation
|
|
* @vprime: blind factor randomly generated
|
|
* @dlrep: the resulting representation
|
|
*
|
|
* Compute the representation of quantities to commit.
|
|
*
|
|
* Return value: #CRYPTIC_NO_ERROR if successful, an error code otherwise.
|
|
*
|
|
**/
|
|
int
|
|
cryptic_clsig_compute_committed_value_with_index(CrypticClsig *clsig, CrypticCommitDataStore *pdc, int *index, BIGNUM** quantities, int nb_quantities)
|
|
{
|
|
int rc = CRYPTIC_ERROR_UNDEFINED;
|
|
|
|
int i;
|
|
BIGNUM *tmp = NULL;
|
|
BN_CTX *ctx = NULL;
|
|
BN_MONT_CTX *mont = NULL;
|
|
|
|
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());
|
|
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(clsig->init == 1,
|
|
CRYPTIC_CLSIG_NOT_CORRECTLY_INITIALIZED);
|
|
goto_cleanup_if_fail_with_rc_with_warning(pdc != NULL,
|
|
CRYPTIC_ERROR_FUNCTION_PARAMETER_NOT_ALLOCATED);
|
|
goto_cleanup_if_fail_with_rc_with_warning(nb_quantities > 0,
|
|
CRYPTIC_CLSIG_NO_VALID_QUANTITIES_NUMBER);
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning(quantities != NULL,
|
|
CRYPTIC_CLSIG_MISSING_QUANTITIES);
|
|
for(i=0;i<nb_quantities;i++){
|
|
goto_cleanup_if_fail_with_rc_with_warning(quantities[i] != NULL,
|
|
CRYPTIC_CLSIG_MISSING_QUANTITIES);
|
|
goto_cleanup_if_fail_with_rc_with_warning(BN_num_bits(quantities[i]) <= clsig->lg_quantities,
|
|
CRYPTIC_CLSIG_QUANTITY_TOO_LARGE);
|
|
}
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning(clsig->bases != NULL,
|
|
CRYPTIC_CLSIG_MISSING_BASES);
|
|
for(i=0;i<nb_quantities;i++){
|
|
goto_cleanup_if_fail_with_rc_with_warning(clsig->bases[i] != NULL,
|
|
CRYPTIC_CLSIG_MISSING_BASES);
|
|
}
|
|
|
|
cryptic_release_bn(pdc->dlrep);
|
|
cryptic_release_bn(pdc->vprime);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(pdc->dlrep = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(pdc->vprime = BN_new());
|
|
|
|
cryptic_check_good_rc(cryptic_find_random(pdc->vprime, clsig->lg_modulus + clsig->lg_zk_sec_param));
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(pdc->dlrep,clsig->S,pdc->vprime,clsig->modulus,ctx,mont) == 1);
|
|
for(i=0;i<nb_quantities;i++){
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(tmp,clsig->bases[index[i]],quantities[i],clsig->modulus,ctx,mont) == 1);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(pdc->dlrep,pdc->dlrep,tmp,clsig->modulus,ctx) == 1);
|
|
}
|
|
|
|
rc = CRYPTIC_NO_ERROR;
|
|
cleanup:
|
|
cryptic_release_ctx(ctx);
|
|
cryptic_release_mont(mont);
|
|
cryptic_release_bn(tmp);
|
|
return rc;
|
|
}
|
|
|
|
/* Z. Ri^mi * A_rand^-(2le-1) = A_rand^e_corrected . S^v_rand . Rj^mj */
|
|
|
|
BIGNUM*
|
|
cryptic_clsig_correct_dlrep_before_proving(CrypticClsig *clsig, BIGNUM* dlrep)
|
|
{
|
|
int rc = CRYPTIC_ERROR_UNDEFINED;
|
|
|
|
BIGNUM *two = NULL, *lg = NULL, *tmp = NULL;
|
|
BN_CTX *ctx = NULL;
|
|
|
|
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());
|
|
|
|
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)); /* 2le-1 */
|
|
BN_copy(tmp,clsig->A_rand);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_inverse(tmp,tmp,clsig->modulus,ctx)); /* A_rand^-*/
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp(tmp,tmp,lg,clsig->modulus,ctx) == 1); /* A_rand^-(2le-1) */
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(tmp,dlrep,tmp,clsig->modulus,ctx) == 1); /* * A_rand^-(2le-1) */
|
|
|
|
rc = CRYPTIC_NO_ERROR;
|
|
cleanup:
|
|
cryptic_release_ctx(ctx);
|
|
cryptic_release_bn(two);
|
|
cryptic_release_bn(lg);
|
|
cryptic_release_bn(tmp);
|
|
return tmp;
|
|
}
|
|
|
|
BIGNUM*
|
|
cryptic_clsig_build_dlrep_before_proving(CrypticClsig *clsig, int* index_quantities, int* index_bases, int nb_quantities)
|
|
{
|
|
int rc = CRYPTIC_ERROR_UNDEFINED;
|
|
|
|
int i;
|
|
BIGNUM *two = NULL, *lg = NULL, *tmp1 = NULL, *tmp2 = NULL;
|
|
BN_CTX *ctx = NULL;
|
|
|
|
if(!nb_quantities || nb_quantities == 0) goto cleanup;
|
|
|
|
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());
|
|
|
|
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(lg,two,tmp1,ctx)); /* 2le-1 */
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(tmp1,clsig->A_rand));
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_inverse(tmp1,tmp1,clsig->modulus,ctx)); /* A_rand^-*/
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp(tmp1,tmp1,lg,clsig->modulus,ctx) == 1); /* A_rand^-(2le-1) */
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(tmp1,clsig->Z,tmp1,clsig->modulus,ctx) == 1); /* Z * A_rand^-(2le-1) */
|
|
|
|
for(i=0;i<nb_quantities;i++){
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_inverse(tmp2,clsig->bases[index_bases[i]],clsig->modulus,ctx));
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp(tmp2,tmp2,clsig->quantities[index_quantities[i]],clsig->modulus,ctx) == 1);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(tmp1,tmp1,tmp2,clsig->modulus,ctx) == 1);
|
|
}
|
|
|
|
rc = CRYPTIC_NO_ERROR;
|
|
cleanup:
|
|
cryptic_release_ctx(ctx);
|
|
cryptic_release_bn(two);
|
|
cryptic_release_bn(lg);
|
|
cryptic_release_bn(tmp2);
|
|
if(rc != CRYPTIC_NO_ERROR){
|
|
cryptic_release_bn(tmp1);
|
|
return NULL;
|
|
}
|
|
return tmp1;
|
|
|
|
}
|
|
|
|
/**
|
|
* cryptic_clsig_run_zkpk_schnorr_round1:
|
|
* @shn: CrypticZkpkSchnorr object
|
|
*
|
|
* Run the first round of a schnorr zkpk to choose randoms of good size.
|
|
*
|
|
* Return value: #CRYPTIC_NO_ERROR if successful, an error code otherwise.
|
|
*
|
|
**/
|
|
/* IBM: RZ3730 (#99740) 03/19/2009 */
|
|
/* re : lei + l0 + lH */ /* lH = lc = lm*/
|
|
/* rv' : lv + l0 + lH */
|
|
/* rmi : lm + l0 + lH */
|
|
/* Else, in cryptic_zkpk_schnorr_round1() random size is the modulus size. */
|
|
/* This does not match these requirements on random size since lv > ln + l0 + lH + max ( lm+lr+3 , l0+2 ) */
|
|
int
|
|
cryptic_clsig_run_zkpk_schnorr_round1(CrypticClsig *clsig, CrypticZkpkSchnorr *shn)
|
|
{
|
|
int rc = CRYPTIC_ERROR_UNDEFINED;
|
|
|
|
int i;
|
|
BIGNUM *randoms[shn->nb_quantities];
|
|
for(i=0;i<shn->nb_quantities;i++){
|
|
randoms[i] = NULL;
|
|
}
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(randoms[0] = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(randoms[1] = BN_new());
|
|
int fixed_add_size = clsig->lg_zk_sec_param + clsig->lg_quantities;
|
|
cryptic_find_random(randoms[0],clsig->interval_exponent + fixed_add_size);
|
|
cryptic_find_random(randoms[1],clsig->lg_blind + fixed_add_size);
|
|
for(i=2;i<shn->nb_quantities;i++){
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(randoms[i] = BN_new());
|
|
cryptic_find_random(randoms[i],clsig->lg_quantities + fixed_add_size);
|
|
}
|
|
|
|
cryptic_check_good_rc(cryptic_zkpk_schnorr_round1_randoms_chosen(shn,randoms));
|
|
|
|
rc = CRYPTIC_NO_ERROR;
|
|
cleanup:
|
|
for(i=0;i<shn->nb_quantities;i++){
|
|
cryptic_release_bn(randoms[i]);
|
|
}
|
|
return rc;
|
|
}
|
|
|
|
/* Helper functions to extract parameters */
|
|
int
|
|
cryptic_clsig_copy_generators_in_tab(BIGNUM **ret, CrypticClsig *clsig)
|
|
{
|
|
int rc = CRYPTIC_ERROR_UNDEFINED;
|
|
|
|
int i;
|
|
for(i=0; i<clsig->nb_bases; i++){
|
|
ret[i] = NULL;
|
|
}
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(ret[0] = BN_new());
|
|
BN_copy(ret[0],clsig->A_rand);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(ret[1] = BN_new());
|
|
BN_copy(ret[1],clsig->S);
|
|
for(i=0; i<clsig->nb_bases; i++){
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(ret[i+2] = BN_new());
|
|
BN_copy(ret[i+2],clsig->bases[i]);
|
|
}
|
|
|
|
rc = CRYPTIC_NO_ERROR;
|
|
cleanup:
|
|
return rc;
|
|
}
|
|
|
|
int
|
|
cryptic_clsig_copy_generators_by_index_in_tab(BIGNUM **ret, CrypticClsig *clsig,int *index,int nb_gen)
|
|
{
|
|
int rc = CRYPTIC_ERROR_UNDEFINED;
|
|
|
|
int i;
|
|
for(i=0; i<nb_gen; i++){
|
|
ret[i] = NULL;
|
|
}
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(ret[0] = BN_new());
|
|
BN_copy(ret[0],clsig->A_rand);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(ret[1] = BN_new());
|
|
BN_copy(ret[1],clsig->S);
|
|
for(i=0; i<nb_gen; i++){
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(ret[i+2] = BN_new());
|
|
BN_copy(ret[i+2],clsig->bases[index[i]]);
|
|
}
|
|
|
|
rc = CRYPTIC_NO_ERROR;
|
|
cleanup:
|
|
return rc;
|
|
}
|
|
|
|
int
|
|
cryptic_clsig_copy_generators_bulk_from_offset_in_tab(BIGNUM **ret, CrypticClsig *clsig, int offset,int nb_gen)
|
|
{
|
|
int rc = CRYPTIC_ERROR_UNDEFINED;
|
|
|
|
int i;
|
|
for(i=0; i<nb_gen; i++){
|
|
ret[i] = NULL;
|
|
}
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(ret[0] = BN_new());
|
|
BN_copy(ret[0],clsig->A_rand);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(ret[1] = BN_new());
|
|
BN_copy(ret[1],clsig->S);
|
|
for(i=0; i<nb_gen; i++){
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(ret[i+2] = BN_new());
|
|
BN_copy(ret[i+2],clsig->bases[i+offset]);
|
|
}
|
|
|
|
rc = CRYPTIC_NO_ERROR;
|
|
cleanup:
|
|
return rc;
|
|
}
|
|
|
|
int
|
|
cryptic_clsig_copy_quantities_in_tab(BIGNUM **ret, CrypticClsig *clsig)
|
|
{
|
|
int rc = CRYPTIC_ERROR_UNDEFINED;
|
|
|
|
int i;
|
|
for(i=0; i<clsig->nb_quantities; i++){
|
|
ret[i] = NULL;
|
|
}
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(ret[0] = BN_new());
|
|
BN_copy(ret[0],clsig->e);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(ret[1] = BN_new());
|
|
BN_copy(ret[1],clsig->v_rand);
|
|
for(i=0; i<clsig->nb_quantities; i++){
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(ret[i+2] = BN_new());
|
|
BN_copy(ret[i+2],clsig->quantities[i]);
|
|
}
|
|
|
|
rc = CRYPTIC_NO_ERROR;
|
|
cleanup:
|
|
return rc;
|
|
}
|
|
|
|
/* Getters */
|
|
BIGNUM*
|
|
cryptic_clsig_get_private_composite(CrypticClsig *clsig)
|
|
{
|
|
cryptic_return_null_if_fail(clsig->qrg);
|
|
return cryptic_qrg_get_p(clsig->qrg);
|
|
}
|
|
|
|
BIGNUM*
|
|
cryptic_clsig_get_order(CrypticClsig *clsig)
|
|
{
|
|
cryptic_return_null_if_fail(clsig->qrg);
|
|
return cryptic_qrg_get_order(clsig->qrg);
|
|
}
|
|
|
|
BIGNUM*
|
|
cryptic_clsig_get_modulus(CrypticClsig *clsig)
|
|
{
|
|
cryptic_return_null_if_fail(clsig->modulus);
|
|
return clsig->modulus;
|
|
}
|
|
|
|
BIGNUM*
|
|
cryptic_clsig_get_exponent(CrypticClsig *clsig)
|
|
{
|
|
cryptic_return_null_if_fail(clsig->e);
|
|
return clsig->e;
|
|
}
|
|
|
|
BIGNUM*
|
|
cryptic_clsig_get_exponent_corrected(CrypticClsig *clsig)
|
|
{
|
|
cryptic_return_null_if_fail(clsig->e_corrected);
|
|
return clsig->e_corrected;
|
|
}
|
|
|
|
BIGNUM*
|
|
cryptic_clsig_get_private_exponent(CrypticClsig *clsig)
|
|
{
|
|
cryptic_return_null_if_fail(clsig->d);
|
|
return clsig->d;
|
|
}
|
|
|
|
BIGNUM*
|
|
cryptic_clsig_get_signature(CrypticClsig *clsig)
|
|
{
|
|
cryptic_return_null_if_fail(clsig->A);
|
|
return clsig->A;
|
|
}
|
|
|
|
BIGNUM*
|
|
cryptic_clsig_get_randomized_signature(CrypticClsig *clsig)
|
|
{
|
|
cryptic_return_null_if_fail(clsig->A_rand);
|
|
return clsig->A_rand;
|
|
}
|
|
|
|
BIGNUM*
|
|
cryptic_clsig_get_random_for_randomized_signature(CrypticClsig *clsig)
|
|
{
|
|
cryptic_return_null_if_fail(clsig->r);
|
|
return clsig->r;
|
|
}
|
|
|
|
BIGNUM*
|
|
cryptic_clsig_get_DL_representation(CrypticClsig *clsig)
|
|
{
|
|
cryptic_return_null_if_fail(clsig->dlrep);
|
|
return clsig->dlrep;
|
|
}
|
|
|
|
BIGNUM*
|
|
cryptic_clsig_get_blind(CrypticClsig *clsig)
|
|
{
|
|
cryptic_return_null_if_fail(clsig->v);
|
|
return clsig->v;
|
|
}
|
|
|
|
BIGNUM*
|
|
cryptic_clsig_get_random_blind(CrypticClsig *clsig)
|
|
{
|
|
cryptic_return_null_if_fail(clsig->v_rand);
|
|
return clsig->v_rand;
|
|
}
|
|
|
|
BIGNUM*
|
|
cryptic_clsig_get_S(CrypticClsig *clsig)
|
|
{
|
|
cryptic_return_null_if_fail(clsig->S);
|
|
return clsig->S;
|
|
}
|
|
|
|
BIGNUM*
|
|
cryptic_clsig_get_Z(CrypticClsig *clsig)
|
|
{
|
|
cryptic_return_null_if_fail(clsig->Z);
|
|
return clsig->Z;
|
|
}
|
|
|
|
BIGNUM**
|
|
cryptic_clsig_get_bases(CrypticClsig *clsig)
|
|
{
|
|
cryptic_return_null_if_fail(clsig->bases);
|
|
return clsig->bases;
|
|
}
|
|
|
|
BIGNUM**
|
|
cryptic_clsig_get_quantities(CrypticClsig *clsig)
|
|
{
|
|
cryptic_return_null_if_fail(clsig->quantities);
|
|
return clsig->quantities;
|
|
}
|
|
|
|
BIGNUM*
|
|
cryptic_clsig_get_i_base(CrypticClsig *clsig, int i)
|
|
{
|
|
cryptic_return_null_if_fail(clsig->bases[i]);
|
|
return clsig->bases[i];
|
|
}
|
|
|
|
BIGNUM*
|
|
cryptic_clsig_get_i_quantity(CrypticClsig *clsig, int i)
|
|
{
|
|
cryptic_return_null_if_fail(clsig->quantities[i]);
|
|
return clsig->quantities[i];
|
|
}
|
|
|
|
int
|
|
cryptic_clsig_get_nb_quantities(CrypticClsig *clsig)
|
|
{
|
|
return clsig->nb_quantities;
|
|
}
|
|
|
|
int
|
|
cryptic_clsig_get_nb_bases(CrypticClsig *clsig)
|
|
{
|
|
return clsig->nb_bases;
|
|
}
|
|
|
|
int
|
|
cryptic_clsig_get_lg_quantities(CrypticClsig *clsig)
|
|
{
|
|
return clsig->lg_quantities;
|
|
}
|
|
|
|
int
|
|
cryptic_clsig_get_lg_modulus(CrypticClsig *clsig)
|
|
{
|
|
return clsig->lg_modulus;
|
|
}
|
|
|
|
int
|
|
cryptic_clsig_get_lg_blind(CrypticClsig *clsig)
|
|
{
|
|
return clsig->lg_blind;
|
|
}
|
|
|
|
int
|
|
cryptic_clsig_get_lg_randomize(CrypticClsig *clsig)
|
|
{
|
|
return clsig->lg_randomize;
|
|
}
|
|
|
|
int
|
|
cryptic_clsig_get_lg_exponent(CrypticClsig *clsig)
|
|
{
|
|
return clsig->lg_exponent;
|
|
}
|
|
|
|
int
|
|
cryptic_clsig_get_interval_exponent(CrypticClsig *clsig)
|
|
{
|
|
return clsig->interval_exponent;
|
|
}
|
|
|
|
int
|
|
cryptic_clsig_get_lg_sec_param(CrypticClsig *clsig)
|
|
{
|
|
return clsig->lg_sec_param;
|
|
}
|
|
|
|
int
|
|
cryptic_clsig_get_lg_zk_sec_param(CrypticClsig *clsig)
|
|
{
|
|
return clsig->lg_zk_sec_param;
|
|
}
|
|
|
|
int
|
|
cryptic_clsig_get_lg_clsig_sec_param(CrypticClsig *clsig)
|
|
{
|
|
return clsig->lg_clsig_sec_param;
|
|
}
|