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/proof_range/proof_range_in_qrg.c

935 lines
41 KiB
C

/* Cryptic -- Cryptographic tools and protocols
* Copyright (C) 2010 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 <stdio.h>
#include <glib.h>
#include <glib-object.h>
#include <openssl/bn.h>
#include <openssl/bio.h>
#include "../../errors.h"
#include "../../utils.h"
#include "../pok_schnorr/schnorr_zkpk.h"
#include "../proof_range/proof_range_in_qrg.h"
/*****************************************************************************/
/* private methods */
/*****************************************************************************/
static GObjectClass *parent_class = NULL;
/*****************************************************************************/
/* overridden parent class methods */
/*****************************************************************************/
static void
dispose(GObject *object)
{
CrypticProofrangeQrg *pr = CRYPTIC_PROOFRANGEQRG(object);
int i;
cryptic_release_bn(pr->modulus);
cryptic_release_bn(pr->m);
cryptic_release_bn(pr->b);
cryptic_release_bn(pr->delta);
cryptic_release_bn(pr->randDLRepDelta);
cryptic_release_bn(pr->randQ);
cryptic_release_bn(pr->Q);
cryptic_release_bn(pr->challenge);
if(pr->tabBases){
for(i=0;i<2;i++){
cryptic_release_bn(pr->tabBases[i]);
}
}
if(pr->tabRandDLRepSqrRoot){
for(i=0;i<4;i++){
cryptic_release_bn(pr->tabRandDLRepSqrRoot[i]);
}
}
if(pr->dlreps){
for(i=0;i<5;i++){
cryptic_release_bn(pr->dlreps[i]);
}
}
if(pr->commitments){
for(i=0;i<6;i++){
cryptic_release_bn(pr->commitments[i]);
}
}
if(pr->responses){
for(i=0;i<11;i++){
cryptic_release_bn(pr->responses[i]);
}
}
cryptic_release(pr->tabBases);
cryptic_release(pr->tabRandDLRepSqrRoot);
cryptic_release(pr->dlreps);
cryptic_release(pr->commitments);
cryptic_release(pr->responses);
cryptic_release_gobject(pr->pokSqrRoot1);
cryptic_release_gobject(pr->pokSqrRoot2);
cryptic_release_gobject(pr->pokSqrRoot3);
cryptic_release_gobject(pr->pokSqrRoot4);
cryptic_release_gobject(pr->pokDelta);
cryptic_release_gobject(pr->di);
G_OBJECT_CLASS(parent_class)->dispose(G_OBJECT(pr));
}
/*****************************************************************************/
/* instance and class init functions */
/*****************************************************************************/
static void
instance_init(CrypticProofrangeQrg *pr)
{
pr->modulus = NULL;
pr->m = NULL;
pr->b = NULL;
pr->delta = NULL;
pr->randDLRepDelta = NULL;
pr->randQ = NULL;
pr->Q = NULL;
pr->challenge = NULL;
pr->tabBases = NULL;
pr->tabRandDLRepSqrRoot = NULL;
pr->dlreps = NULL;
pr->commitments = NULL;
pr->responses = NULL;
pr->pokSqrRoot1 = NULL;
pr->pokSqrRoot2 = NULL;
pr->pokSqrRoot3 = NULL;
pr->pokSqrRoot4 = NULL;
pr->pokDelta = NULL;
pr->di = NULL;
}
static void
class_init(CrypticProofrangeQrgClass *klass)
{
parent_class = g_type_class_peek_parent(klass);
G_OBJECT_CLASS(klass)->dispose = dispose;
}
/*****************************************************************************/
/* public methods */
/*****************************************************************************/
GType
cryptic_proofrange_qrg_get_type()
{
static GType this_type = 0;
if (!this_type) {
static const GTypeInfo this_info = {
sizeof (CrypticProofrangeQrgClass),
NULL,
NULL,
(GClassInitFunc) class_init,
NULL,
NULL,
sizeof(CrypticProofrangeQrg),
0,
(GInstanceInitFunc) instance_init,
NULL
};
this_type = g_type_register_static(G_TYPE_OBJECT,
"CrypticProofrangeQrg", &this_info, 0);
}
return this_type;
}
/**
* cryptic_proofrange_qrg_new:
* @base1: First base used for the DL representation.
* @base2: Second base used for the DL representation.
* @modulus: Modulus of the group.
*
* Creates a new #CrypticProofrangeQrg.
*
* Return value: a newly created #CrypticProofrangeQrg object; or NULL if an error
* occured
**/
CrypticProofrangeQrg*
cryptic_proofrange_qrg_new(BIGNUM *base1, BIGNUM *base2, BIGNUM *modulus)
{
int rc = CRYPTIC_ERROR_UNDEFINED;
CrypticProofrangeQrg *pr;
pr = g_object_new(CRYPTIC_TYPE_PROOFRANGEQRG, NULL);
int i;
cryptic_release(pr->tabBases);
pr->tabBases = g_malloc0(2 * sizeof (**pr->tabBases));
for(i=0; i<2; i++){
pr->tabBases[i] = NULL;
}
cryptic_release(pr->tabRandDLRepSqrRoot);
pr->tabRandDLRepSqrRoot = g_malloc0(4 * sizeof (**pr->tabRandDLRepSqrRoot));
for(i=0; i<4; i++){
pr->tabRandDLRepSqrRoot[i] = NULL;
}
cryptic_release(pr->dlreps);
pr->dlreps = g_malloc0(5 * sizeof (**pr->dlreps));
for(i=0; i<5; i++){
pr->dlreps[i] = NULL;
}
cryptic_release(pr->commitments);
pr->commitments = g_malloc0(6 * sizeof (**pr->commitments));
for(i=0; i<6; i++){
pr->commitments[i] = NULL;
}
cryptic_release(pr->responses);
pr->responses = g_malloc0(11 * sizeof (**pr->responses));
for(i=0; i<11; i++){
pr->responses[i] = NULL;
}
goto_cleanup_if_fail_with_rc_with_warning_openssl(pr->tabBases[0] = BN_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(pr->tabBases[0],base1));
goto_cleanup_if_fail_with_rc_with_warning_openssl(pr->tabBases[1] = BN_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(pr->tabBases[1],base2));
cryptic_release_bn(pr->modulus);
goto_cleanup_if_fail_with_rc_with_warning_openssl(pr->modulus = BN_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(pr->modulus, modulus));
return pr;
cleanup:
cryptic_release_gobject(pr);
return NULL;
}
/**
* cryptic_proofrange_qrg_round1:
* @rel: inequality to prove.
* @m: quantity on which the range proof is led.
* @b: quantity of comparison.
* @random_m: Random for m.
* @rand1: size of the random for proof of the first square.
* @rand2: size of the random for proof of the second square.
* @rand3: size of the random for proof of the third square.
* @rand4: size of the random for proof of the forth square.
*
* Lead a range proof relying on the interactive Schnorr ZKPK. Round1 for committing.
*
* Return value: #CRYPTIC_NO_ERROR if successful, an error code otherwise.
*/
int
cryptic_proofrange_qrg_round1(CrypticProofrangeQrg *pr, int rel, BIGNUM *m, BIGNUM *b, BIGNUM *random_m, int lg_sec_param, int lg_zk_sec_param, int lg_challenge)
{
int rc = CRYPTIC_ERROR_UNDEFINED;
int i;
int neg = 0;
BIGNUM *tmp = NULL;
BIGNUM *tab_rand[2];
tab_rand[0] = NULL;
tab_rand[1] = NULL;
BN_CTX *ctx = NULL;
BN_MONT_CTX *mont = NULL;
goto_cleanup_if_fail_with_rc_with_warning(pr->modulus != NULL,
CRYPTIC_PROOF_RANGE_STRUCTURE_NOT_INIT);
goto_cleanup_if_fail_with_rc_with_warning(m != NULL,
CRYPTIC_PROOF_RANGE_STRUCTURE_NOT_INIT);
goto_cleanup_if_fail_with_rc_with_warning(b != NULL,
CRYPTIC_PROOF_RANGE_NO_BOUND);
if(lg_sec_param<CRYPTIC_PROOF_RANGE_TEST_SEC_PARAM){
lg_sec_param = CRYPTIC_PROOF_RANGE_TEST_SEC_PARAM;
}
if(lg_zk_sec_param<CRYPTIC_PROOF_RANGE_TEST_ZK_SEC_PARAM){
lg_zk_sec_param = CRYPTIC_PROOF_RANGE_TEST_ZK_SEC_PARAM;
}
goto_cleanup_if_fail_with_rc_with_warning(lg_challenge >= CRYPTIC_PROOF_RANGE_TEST_CHALLENGE_MIN_SIZE,
CRYPTIC_PROOF_GENERIC_CHALLENGE_SIZE_NOT_VALID);
goto_cleanup_if_fail_with_rc_with_warning_openssl(tmp = BN_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(tab_rand[0] = BN_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(tab_rand[1] = 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,pr->modulus,ctx));
/*****************************
* Compute delta
******************************/
goto_cleanup_if_fail_with_rc_with_warning_openssl(pr->delta = BN_new());
switch (rel) {
case CRYPTIC_PROOF_RANGE_LTE:
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_sub(pr->delta,b,m) == 1); // b-m
neg = 1;
break;
case CRYPTIC_PROOF_RANGE_LT:
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_sub(pr->delta,b,m) == 1); // b-m-1
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_sub(pr->delta,pr->delta,BN_value_one()) == 1);
neg = 1;
break;
case CRYPTIC_PROOF_RANGE_GTE:
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_sub(pr->delta,m,b) == 1); // m-b
break;
case CRYPTIC_PROOF_RANGE_GT:
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_sub(pr->delta,m,b) == 1); // m-b-1
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_sub(pr->delta,pr->delta,BN_value_one()) == 1);
break;
default:
rc = CRYPTIC_PROOF_RANGE_RELATION_UNKNOWN;
goto cleanup;
}
goto_cleanup_if_fail_with_rc_with_warning(!BN_is_negative(pr->delta),
CRYPTIC_PROOF_RANGE_DELTA_NEGATIVE);
/*****************************
* Decomposition
******************************/
cryptic_release_bn(pr->m);
goto_cleanup_if_fail_with_rc_with_warning_openssl(pr->m = BN_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(pr->m,m));
cryptic_release_bn(pr->b);
goto_cleanup_if_fail_with_rc_with_warning_openssl(pr->b = BN_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(pr->b,b));
pr->di = cryptic_decompose_integer_new(pr->delta);
goto_cleanup_if_fail_with_rc_with_warning(pr->di >= 0 && cryptic_decompose_integer_verify_decomposition(pr->di,pr->delta) == 1,
CRYPTIC_PROOF_RANGE_DECOMPOSITION_FAILED);
/* IBM: RZ3730 (#99740) 03/19/2009 */
/* rdelta, ri : rand1 = ln + l_zk_sec_param */
/* qi : rand2 = lm + l_challenge + l_zk_sec_param */
/* zdelta, zi : rand3 = lm + l_challenge + 2*l_zk_sec_param */
/* rrho : rand4 = ln + lm + 2*l_sec_param + 2*l_zk_sec_param + 3 */
int lg_modulus = BN_num_bits(pr->modulus);
int lg_quantity = lg_challenge;
int rand1 = lg_modulus + lg_zk_sec_param;
int rand2 = lg_quantity + lg_challenge + lg_zk_sec_param;
int rand3 = lg_quantity + lg_challenge + 2*lg_zk_sec_param;
int rand4 = lg_modulus + lg_quantity + 2*lg_sec_param + 2*lg_zk_sec_param + 3;
/*****************************
* Build dlrep
******************************/
for(i=0;i<4;i++){
cryptic_release_bn(pr->tabRandDLRepSqrRoot[i]);
cryptic_release_bn(pr->dlreps[i]);
goto_cleanup_if_fail_with_rc_with_warning_openssl(pr->tabRandDLRepSqrRoot[i] = BN_new()); //random to dlrep the square roots of Delta
goto_cleanup_if_fail_with_rc_with_warning_openssl(pr->dlreps[i] = BN_new()); //dlrep of the square roots of Delta (Ti)
goto_cleanup_if_fail_with_rc_with_warning_openssl(cryptic_find_random(pr->tabRandDLRepSqrRoot[i],rand1) == 0);
switch (i){
case 0: goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(pr->dlreps[i],pr->tabBases[0],cryptic_getSqrRoot1(pr->di),pr->modulus,ctx,mont) == 1); break;
case 1: goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(pr->dlreps[i],pr->tabBases[0],cryptic_getSqrRoot2(pr->di),pr->modulus,ctx,mont) == 1); break;
case 2: goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(pr->dlreps[i],pr->tabBases[0],cryptic_getSqrRoot3(pr->di),pr->modulus,ctx,mont) == 1); break;
case 3: goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(pr->dlreps[i],pr->tabBases[0],cryptic_getSqrRoot4(pr->di),pr->modulus,ctx,mont) == 1); break;
}
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(tmp,pr->tabBases[1],pr->tabRandDLRepSqrRoot[i],pr->modulus,ctx,mont) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(pr->dlreps[i],pr->dlreps[i],tmp,pr->modulus,ctx) == 1);
}
cryptic_release_bn(pr->randDLRepDelta);
cryptic_release_bn(pr->dlreps[4]);
goto_cleanup_if_fail_with_rc_with_warning_openssl(pr->randDLRepDelta = BN_new()); //random to dlrep Delta
goto_cleanup_if_fail_with_rc_with_warning_openssl(pr->dlreps[4] = BN_new()); //dlrep Delta (Td)
goto_cleanup_if_fail_with_rc_with_warning_openssl(cryptic_find_random(pr->randDLRepDelta,rand1) == 0);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(pr->dlreps[4],pr->tabBases[0],pr->delta,pr->modulus,ctx,mont) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(tmp,pr->tabBases[1],pr->randDLRepDelta,pr->modulus,ctx,mont) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(pr->dlreps[4],pr->dlreps[4],tmp,pr->modulus,ctx) == 1);
/*****************************
* Compute commitments
******************************/
pr->pokSqrRoot1 = cryptic_zkpk_schnorr_new(pr->tabBases, 2, pr->modulus);
goto_cleanup_if_fail_with_rc_with_warning_openssl(cryptic_find_random(tab_rand[0],rand2) == 0);
goto_cleanup_if_fail_with_rc_with_warning_openssl(cryptic_find_random(tab_rand[1],rand3) == 0);
goto_cleanup_if_fail_with_rc_with_warning_openssl(cryptic_zkpk_schnorr_round1_randoms_chosen(pr->pokSqrRoot1,tab_rand) == 0);
pr->pokSqrRoot2 = cryptic_zkpk_schnorr_new(pr->tabBases, 2, pr->modulus);
goto_cleanup_if_fail_with_rc_with_warning_openssl(cryptic_find_random(tab_rand[0],rand2) == 0);
goto_cleanup_if_fail_with_rc_with_warning_openssl(cryptic_find_random(tab_rand[1],rand3) == 0);
goto_cleanup_if_fail_with_rc_with_warning_openssl(cryptic_zkpk_schnorr_round1_randoms_chosen(pr->pokSqrRoot2,tab_rand) == 0);
pr->pokSqrRoot3 = cryptic_zkpk_schnorr_new(pr->tabBases, 2, pr->modulus);
goto_cleanup_if_fail_with_rc_with_warning_openssl(cryptic_find_random(tab_rand[0],rand2) == 0);
goto_cleanup_if_fail_with_rc_with_warning_openssl(cryptic_find_random(tab_rand[1],rand3) == 0);
goto_cleanup_if_fail_with_rc_with_warning_openssl(cryptic_zkpk_schnorr_round1_randoms_chosen(pr->pokSqrRoot3,tab_rand) == 0);
pr->pokSqrRoot4 = cryptic_zkpk_schnorr_new(pr->tabBases, 2, pr->modulus);
goto_cleanup_if_fail_with_rc_with_warning_openssl(cryptic_find_random(tab_rand[0],rand2) == 0);
goto_cleanup_if_fail_with_rc_with_warning_openssl(cryptic_find_random(tab_rand[1],rand3) == 0);
goto_cleanup_if_fail_with_rc_with_warning_openssl(cryptic_zkpk_schnorr_round1_randoms_chosen(pr->pokSqrRoot4,tab_rand) == 0);
if(neg){
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(tmp,pr->tabBases[1]));
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_inverse(pr->tabBases[1],pr->tabBases[1],pr->modulus,ctx));
}
pr->pokDelta = cryptic_zkpk_schnorr_new(pr->tabBases, 2, pr->modulus);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(tab_rand[0],random_m)); //r_m
goto_cleanup_if_fail_with_rc_with_warning_openssl(cryptic_find_random(tab_rand[1],rand3) == 0); //z_delta
goto_cleanup_if_fail_with_rc_with_warning_openssl(cryptic_zkpk_schnorr_round1_randoms_chosen(pr->pokDelta,tab_rand) == 0);
if(neg) goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(pr->tabBases[1],tmp));
/*****************************
* Compute Q
******************************/
cryptic_release_bn(pr->randQ);
goto_cleanup_if_fail_with_rc_with_warning_openssl(pr->randQ = BN_new());
cryptic_check_good_rc(cryptic_find_random(pr->randQ,rand4)); //r_rho
goto_cleanup_if_fail_with_rc_with_warning_openssl(pr->Q = BN_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(pr->Q,pr->dlreps[0],cryptic_zkpk_schnorr_get_i_random(pr->pokSqrRoot1, 0),pr->modulus,ctx,mont) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(tmp,pr->dlreps[1],cryptic_zkpk_schnorr_get_i_random(pr->pokSqrRoot2, 0),pr->modulus,ctx,mont) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(pr->Q,pr->Q,tmp,pr->modulus,ctx) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(tmp,pr->dlreps[2],cryptic_zkpk_schnorr_get_i_random(pr->pokSqrRoot3, 0),pr->modulus,ctx,mont) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(pr->Q,pr->Q,tmp,pr->modulus,ctx) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(tmp,pr->dlreps[3],cryptic_zkpk_schnorr_get_i_random(pr->pokSqrRoot4, 0),pr->modulus,ctx,mont) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(pr->Q,pr->Q,tmp,pr->modulus,ctx) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(tmp,pr->tabBases[1],pr->randQ,pr->modulus,ctx,mont) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(pr->Q,pr->Q,tmp,pr->modulus,ctx) == 1);
rc = CRYPTIC_NO_ERROR;
cleanup:
cryptic_release_ctx(ctx);
cryptic_release_mont(mont);
cryptic_release_bn(tab_rand[1]);
cryptic_release_bn(tab_rand[0]);
cryptic_release_bn(tmp);
return rc;
}
/**
* cryptic_proofrange_qrg_round1:
* @challenge: challenge for interactive, hash for non interactive proofs.
*
* Round2 for response.
*
* Return value: #CRYPTIC_NO_ERROR if successful, an error code otherwise.
*/
int
cryptic_proofrange_qrg_round2(CrypticProofrangeQrg *pr, BIGNUM *challenge)
{
int rc = CRYPTIC_ERROR_UNDEFINED;
BIGNUM *tmp = NULL;
BIGNUM *tab_qty[2];
tab_qty[0] = NULL;
tab_qty[1] = NULL;
BN_CTX *ctx = NULL;
goto_cleanup_if_fail_with_rc_with_warning(pr->modulus != NULL,
CRYPTIC_PROOF_RANGE_STRUCTURE_NOT_INIT);
goto_cleanup_if_fail_with_rc_with_warning(pr->Q != NULL,
CRYPTIC_PROOF_RANGE_INTERACTIVE_ROUND_1_UNCOMPLETE);
goto_cleanup_if_fail_with_rc_with_warning(challenge != NULL,
CRYPTIC_PROOF_RANGE_INTERACTIVE_ROUND_2_NO_CHALLENGE);
goto_cleanup_if_fail_with_rc_with_warning_openssl(pr->challenge = BN_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(pr->challenge,challenge));
goto_cleanup_if_fail_with_rc_with_warning_openssl(tmp = BN_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(tab_qty[0] = BN_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(tab_qty[1] = BN_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(ctx = BN_CTX_new());
/*****************************
* Compute responses
******************************/
/* S_u_1 = pr->pokSqrRoot1->random[0] + c.u_1 */
/* S_r_1 = pr->pokSqrRoot1->random[1] + c.r_1 */
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(tab_qty[0],cryptic_getSqrRoot1(pr->di)));
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(tab_qty[1],pr->tabRandDLRepSqrRoot[0]));
goto_cleanup_if_fail_with_rc_with_warning_openssl(cryptic_zkpk_schnorr_round2_without_order(pr->pokSqrRoot1,pr->challenge,tab_qty) == 0);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(tab_qty[0],cryptic_getSqrRoot2(pr->di)));
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(tab_qty[1],pr->tabRandDLRepSqrRoot[1]));
goto_cleanup_if_fail_with_rc_with_warning_openssl(cryptic_zkpk_schnorr_round2_without_order(pr->pokSqrRoot2,pr->challenge,tab_qty) == 0);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(tab_qty[0],cryptic_getSqrRoot3(pr->di)));
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(tab_qty[1],pr->tabRandDLRepSqrRoot[2]));
goto_cleanup_if_fail_with_rc_with_warning_openssl(cryptic_zkpk_schnorr_round2_without_order(pr->pokSqrRoot3,pr->challenge,tab_qty) == 0);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(tab_qty[0],cryptic_getSqrRoot4(pr->di)));
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(tab_qty[1],pr->tabRandDLRepSqrRoot[3]));
goto_cleanup_if_fail_with_rc_with_warning_openssl(cryptic_zkpk_schnorr_round2_without_order(pr->pokSqrRoot4,pr->challenge,tab_qty) == 0);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(tab_qty[0],pr->m));
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(tab_qty[1],pr->randDLRepDelta));
goto_cleanup_if_fail_with_rc_with_warning_openssl(cryptic_zkpk_schnorr_round2_without_order(pr->pokDelta,pr->challenge,tab_qty) == 0);
cryptic_release_bn(pr->responserho);
goto_cleanup_if_fail_with_rc_with_warning_openssl(pr->responserho = BN_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mul(tmp,cryptic_getSqrRoot1(pr->di),pr->tabRandDLRepSqrRoot[0],ctx) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mul(pr->responserho,cryptic_getSqrRoot2(pr->di),pr->tabRandDLRepSqrRoot[1],ctx) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_add(pr->responserho,tmp,pr->responserho) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mul(tmp,cryptic_getSqrRoot3(pr->di),pr->tabRandDLRepSqrRoot[2],ctx) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_add(pr->responserho,tmp,pr->responserho) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mul(tmp,cryptic_getSqrRoot4(pr->di),pr->tabRandDLRepSqrRoot[3],ctx) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_add(pr->responserho,tmp,pr->responserho) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_sub(pr->responserho,pr->randDLRepDelta,pr->responserho) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mul(pr->responserho,pr->responserho,pr->challenge,ctx) == 1);
/* s = r - cx */
//goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_sub(pr->responserho,pr->randQ,pr->responserho) == 1);
/* s = r + cx */
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_add(pr->responserho,pr->randQ,pr->responserho) == 1);
int i;
for(i=0;i<11;i++){
cryptic_release_bn(pr->responses[i]);
goto_cleanup_if_fail_with_rc_with_warning_openssl(pr->responses[i] = BN_new());
}
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(pr->responses[0],cryptic_zkpk_schnorr_get_i_response(pr->pokSqrRoot1,0)));
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(pr->responses[1],cryptic_zkpk_schnorr_get_i_response(pr->pokSqrRoot1,1)));
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(pr->responses[2],cryptic_zkpk_schnorr_get_i_response(pr->pokSqrRoot2,0)));
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(pr->responses[3],cryptic_zkpk_schnorr_get_i_response(pr->pokSqrRoot2,1)));
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(pr->responses[4],cryptic_zkpk_schnorr_get_i_response(pr->pokSqrRoot3,0)));
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(pr->responses[5],cryptic_zkpk_schnorr_get_i_response(pr->pokSqrRoot3,1)));
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(pr->responses[6],cryptic_zkpk_schnorr_get_i_response(pr->pokSqrRoot4,0)));
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(pr->responses[7],cryptic_zkpk_schnorr_get_i_response(pr->pokSqrRoot4,1)));
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(pr->responses[8],cryptic_zkpk_schnorr_get_i_response(pr->pokDelta,0)));
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(pr->responses[9],cryptic_zkpk_schnorr_get_i_response(pr->pokDelta,1)));
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(pr->responses[10],pr->responserho));
rc = CRYPTIC_NO_ERROR;
cleanup:
cryptic_release_ctx(ctx);
cryptic_release_bn(tmp);
if(tab_qty){
int i;
for(i=0;i<2;i++){
cryptic_release_bn(tab_qty[i]);
}
}
return rc;
}
/**
* cryptic_proofrange_qrg_verify_interactive_proof:
* @rel: inequality to prove.
* @b: quantity of comparison.
* @dlreps: Representation proved.
* @commitments: Commitments.
* @challenge: Challenge.
* @responses: Responses of the proof.
*
* Verify a range proof relying on the interactive Schnorr ZKPK.
*
* Return value: 1 if proof is successful, an error code otherwise.
*/
int
cryptic_proofrange_qrg_verify_interactive_proof(CrypticProofrangeQrg *pr,
int rel,
BIGNUM *b,
BIGNUM **dlreps, //T1, T2, T3, T4, T5, Tdelta
BIGNUM **commitments, //t1, t2, t3, t4, t5, tdelta, tQ
BIGNUM *challenge, //c
BIGNUM **responses) //su1, zu1, su2, zu2, su3, zu3, su4, zu4, srho
{
int rc = CRYPTIC_ERROR_UNDEFINED;
int i;
int neg = 0;
BIGNUM *tmp = NULL;
BN_CTX *ctx = NULL;
BN_MONT_CTX *mont = NULL;
goto_cleanup_if_fail_with_rc_with_warning(pr->modulus != NULL,
CRYPTIC_PROOF_RANGE_STRUCTURE_NOT_INIT);
goto_cleanup_if_fail_with_rc_with_warning(b != NULL,
CRYPTIC_PROOF_RANGE_NO_BOUND);
cryptic_release_bn(pr->delta);
goto_cleanup_if_fail_with_rc_with_warning_openssl(pr->delta = BN_new());
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,pr->modulus,ctx));
/*****************************
* Compute delta
******************************/
switch (rel) {
case CRYPTIC_PROOF_RANGE_LTE:
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(pr->delta,b));
neg = 1;
break;
case CRYPTIC_PROOF_RANGE_LT:
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(pr->delta,b));
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_sub(pr->delta,pr->delta,BN_value_one()) == 1);
neg = 1;
break;
case CRYPTIC_PROOF_RANGE_GTE:
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(pr->delta,b));
break;
case CRYPTIC_PROOF_RANGE_GT:
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(pr->delta,b));
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_add(pr->delta,pr->delta,BN_value_one()) == 1);
break;
default:
rc = CRYPTIC_PROOF_RANGE_RELATION_UNKNOWN;
goto cleanup;
}
goto_cleanup_if_fail_with_rc_with_warning(!BN_is_negative(pr->delta),
CRYPTIC_PROOF_RANGE_DELTA_NEGATIVE);
goto_cleanup_if_fail_with_rc_with_warning(dlreps != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_TAB_DLREPS_EMPTY);
goto_cleanup_if_fail_with_rc_with_warning(dlreps[0] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_DLREP_FIRST_SQRROOT_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(dlreps[1] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_DLREP_SECOND_SQRROOT_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(dlreps[2] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_DLREP_THIRD_SQRROOT_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(dlreps[3] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_DLREP_FORTH_SQRROOT_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(dlreps[4] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_DLREP_DELTA_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(commitments != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_TAB_COMMITMENTS_EMPTY);
goto_cleanup_if_fail_with_rc_with_warning(commitments[0] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_COMMIT_FIRST_SQRROOT_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(commitments[1] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_COMMIT_SECOND_SQRROOT_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(commitments[2] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_COMMIT_THIRD_SQRROOT_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(commitments[3] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_COMMIT_FORTH_SQRROOT_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(commitments[4] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_COMMIT_DELTA_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(commitments[5] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_COMMIT_Q_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(challenge != NULL,
CRYPTIC_PROOF_GENERIC_CHALLENGE_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(responses != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_TAB_RESPONSES_EMPTY);
goto_cleanup_if_fail_with_rc_with_warning(responses[0] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_RESPONSES_FIRST_SQRROOT_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(responses[1] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_RESPONSES_FIRST_SQRROOT_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(responses[2] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_RESPONSES_SECOND_SQRROOT_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(responses[3] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_RESPONSES_SECOND_SQRROOT_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(responses[4] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_RESPONSES_THIRD_SQRROOT_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(responses[5] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_RESPONSES_THIRD_SQRROOT_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(responses[6] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_RESPONSES_FORTH_SQRROOT_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(responses[7] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_RESPONSES_FORTH_SQRROOT_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(responses[8] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_RESPONSES_DELTA_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(responses[9] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_RESPONSES_DELTA_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(responses[10] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_RESPONSES_RHO_MISSING);
pr->pokSqrRoot1 = cryptic_zkpk_schnorr_new(pr->tabBases, 2, pr->modulus);
goto_cleanup_if_fail_with_rc_with_warning(
cryptic_zkpk_schnorr_verify_interactive_proof(pr->pokSqrRoot1, dlreps[0], commitments[0], challenge, responses) == 1,
CRYPTIC_PROOF_RANGE_VERIFICATION_FAILURE);
pr->pokSqrRoot2 = cryptic_zkpk_schnorr_new(pr->tabBases, 2, pr->modulus);
goto_cleanup_if_fail_with_rc_with_warning(
cryptic_zkpk_schnorr_verify_interactive_proof(pr->pokSqrRoot2, dlreps[1], commitments[1], challenge, responses+2) == 1,
CRYPTIC_PROOF_RANGE_VERIFICATION_FAILURE);
pr->pokSqrRoot3 = cryptic_zkpk_schnorr_new(pr->tabBases, 2, pr->modulus);
goto_cleanup_if_fail_with_rc_with_warning(
cryptic_zkpk_schnorr_verify_interactive_proof(pr->pokSqrRoot3, dlreps[2], commitments[2], challenge, responses+4) == 1,
CRYPTIC_PROOF_RANGE_VERIFICATION_FAILURE);
pr->pokSqrRoot4 = cryptic_zkpk_schnorr_new(pr->tabBases, 2,pr->modulus);
goto_cleanup_if_fail_with_rc_with_warning(
cryptic_zkpk_schnorr_verify_interactive_proof(pr->pokSqrRoot4, dlreps[3], commitments[3], challenge, responses+6) == 1,
CRYPTIC_PROOF_RANGE_VERIFICATION_FAILURE);
cryptic_release_bn(pr->dlreps[4]);
goto_cleanup_if_fail_with_rc_with_warning_openssl(pr->dlreps[4] = BN_new());
if(neg){
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_inverse(pr->dlreps[4],dlreps[4],pr->modulus,ctx));
}else{
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(pr->dlreps[4],dlreps[4]));
}
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(tmp,pr->tabBases[0],pr->delta,pr->modulus,ctx,mont) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(pr->dlreps[4],pr->dlreps[4],tmp,pr->modulus,ctx) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(tmp,pr->dlreps[4],challenge,pr->modulus,ctx,mont) == 1);
if(neg){
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(tmp,pr->tabBases[1]));
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_inverse(pr->tabBases[1],pr->tabBases[1],pr->modulus,ctx));
}
pr->pokDelta = cryptic_zkpk_schnorr_new(pr->tabBases, 2, pr->modulus);
goto_cleanup_if_fail_with_rc_with_warning(
cryptic_zkpk_schnorr_verify_interactive_proof(pr->pokDelta,pr->dlreps[4], commitments[4],challenge,responses+8) == 1,
CRYPTIC_PROOF_RANGE_VERIFICATION_FAILURE);
if(neg) goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(pr->tabBases[1],tmp));
cryptic_release_bn(pr->Q);
goto_cleanup_if_fail_with_rc_with_warning_openssl(pr->Q = BN_new());
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_inverse(tmp,dlreps[4],pr->modulus,ctx)); /* Comment for s = r - cx */
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(pr->Q,tmp,challenge,pr->modulus,ctx,mont) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(tmp,dlreps[0],responses[0],pr->modulus,ctx,mont) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(pr->Q,pr->Q,tmp,pr->modulus,ctx) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(tmp,dlreps[1],responses[2],pr->modulus,ctx,mont) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(pr->Q,pr->Q,tmp,pr->modulus,ctx) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(tmp,dlreps[2],responses[4],pr->modulus,ctx,mont) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(pr->Q,pr->Q,tmp,pr->modulus,ctx) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(tmp,dlreps[3],responses[6],pr->modulus,ctx,mont) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(pr->Q,pr->Q,tmp,pr->modulus,ctx) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(tmp,pr->tabBases[1],responses[10],pr->modulus,ctx,mont) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(pr->Q,pr->Q,tmp,pr->modulus,ctx) == 1);
goto_cleanup_if_fail_with_rc_with_warning(BN_ucmp(pr->Q,commitments[5]) == 0,
CRYPTIC_PROOF_RANGE_VERIFICATION_FAILURE);
rc = CRYPTIC_NO_ERROR;
cleanup:
cryptic_release_ctx(ctx);
cryptic_release_mont(mont);
cryptic_release_bn(tmp);
if(rc == CRYPTIC_NO_ERROR) return 1;
return rc;
}
/**
* cryptic_proofrange_qrg_verify_noninteractive_proof:
* @rel: inequality to prove.
* @b: quantity of comparison.
* @dlreps: Representation proved.
* @hash: hash.
* @responses: Responses of the proof.
*
* Verify a range proof relying on the interactive Schnorr ZKPK.
*
* Return value: 1 if proof is successful, an error code otherwise.
*/
int
cryptic_proofrange_qrg_verify_noninteractive_proof(CrypticProofrangeQrg *pr,
int rel,
BIGNUM *b,
BIGNUM **dlreps, //T1, T2, T3, T4, T5, Tdelta
BIGNUM *hash, //hash
BIGNUM **responses) //su1, zu1, su2, zu2, su3, zu3, su4, zu4, srho
{
int rc = CRYPTIC_ERROR_UNDEFINED;
int i;
int neg = 0;
BIGNUM *tmp = NULL;
BN_CTX *ctx = NULL;
BN_MONT_CTX *mont = NULL;
goto_cleanup_if_fail_with_rc_with_warning(pr->modulus != NULL,
CRYPTIC_PROOF_RANGE_STRUCTURE_NOT_INIT);
goto_cleanup_if_fail_with_rc_with_warning(b != NULL,
CRYPTIC_PROOF_RANGE_NO_BOUND);
cryptic_release_bn(pr->delta);
goto_cleanup_if_fail_with_rc_with_warning_openssl(pr->delta = BN_new());
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,pr->modulus,ctx));
/*****************************
* Compute delta
******************************/
switch (rel) {
case CRYPTIC_PROOF_RANGE_LTE:
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(pr->delta,b));
neg = 1;
break;
case CRYPTIC_PROOF_RANGE_LT:
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(pr->delta,b));
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_sub(pr->delta,pr->delta,BN_value_one()) == 1);
neg = 1;
break;
case CRYPTIC_PROOF_RANGE_GTE:
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(pr->delta,b));
break;
case CRYPTIC_PROOF_RANGE_GT:
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(pr->delta,b));
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_add(pr->delta,pr->delta,BN_value_one()) == 1);
break;
default:
rc = CRYPTIC_PROOF_RANGE_RELATION_UNKNOWN;
goto cleanup;
}
goto_cleanup_if_fail_with_rc_with_warning(!BN_is_negative(pr->delta),
CRYPTIC_PROOF_RANGE_DELTA_NEGATIVE);
goto_cleanup_if_fail_with_rc_with_warning(dlreps != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_TAB_DLREPS_EMPTY);
goto_cleanup_if_fail_with_rc_with_warning(dlreps[0] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_DLREP_FIRST_SQRROOT_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(dlreps[1] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_DLREP_SECOND_SQRROOT_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(dlreps[2] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_DLREP_THIRD_SQRROOT_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(dlreps[3] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_DLREP_FORTH_SQRROOT_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(dlreps[4] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_DLREP_DELTA_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(hash != NULL,
CRYPTIC_PROOF_GENERIC_CHALLENGE_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(responses != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_TAB_RESPONSES_EMPTY);
goto_cleanup_if_fail_with_rc_with_warning(responses[0] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_RESPONSES_FIRST_SQRROOT_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(responses[1] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_RESPONSES_FIRST_SQRROOT_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(responses[2] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_RESPONSES_SECOND_SQRROOT_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(responses[3] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_RESPONSES_SECOND_SQRROOT_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(responses[4] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_RESPONSES_THIRD_SQRROOT_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(responses[5] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_RESPONSES_THIRD_SQRROOT_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(responses[6] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_RESPONSES_FORTH_SQRROOT_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(responses[7] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_RESPONSES_FORTH_SQRROOT_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(responses[8] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_RESPONSES_DELTA_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(responses[9] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_RESPONSES_DELTA_MISSING);
goto_cleanup_if_fail_with_rc_with_warning(responses[10] != NULL,
CRYPTIC_PROOF_RANGE_VERIFY_RESPONSES_RHO_MISSING);
pr->pokSqrRoot1 = cryptic_zkpk_schnorr_new(pr->tabBases, 2, pr->modulus);
cryptic_check_good_rc(cryptic_zkpk_schnorr_verify_noninteractive_proof(pr->pokSqrRoot1,dlreps[0],hash,responses));
pr->pokSqrRoot2 = cryptic_zkpk_schnorr_new(pr->tabBases, 2, pr->modulus);
cryptic_check_good_rc(cryptic_zkpk_schnorr_verify_noninteractive_proof(pr->pokSqrRoot2,dlreps[1],hash,responses+2));
pr->pokSqrRoot3 = cryptic_zkpk_schnorr_new(pr->tabBases, 2, pr->modulus);
cryptic_check_good_rc(cryptic_zkpk_schnorr_verify_noninteractive_proof(pr->pokSqrRoot3,dlreps[2],hash,responses+4));
pr->pokSqrRoot4 = cryptic_zkpk_schnorr_new(pr->tabBases, 2, pr->modulus);
cryptic_check_good_rc(cryptic_zkpk_schnorr_verify_noninteractive_proof(pr->pokSqrRoot4,dlreps[3],hash,responses+6));
cryptic_release_bn(pr->dlreps[4]);
goto_cleanup_if_fail_with_rc_with_warning_openssl(pr->dlreps[4] = BN_new());
if(neg){
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_inverse(pr->dlreps[4],dlreps[4],pr->modulus,ctx));
}else{
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(pr->dlreps[4],dlreps[4]));
}
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(tmp,pr->tabBases[0],pr->delta,pr->modulus,ctx,mont) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(pr->dlreps[4],pr->dlreps[4],tmp,pr->modulus,ctx) == 1);
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(tmp,pr->dlreps[4],hash,pr->modulus,ctx,mont) == 1);
if(neg){
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(tmp,pr->tabBases[1]));
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_inverse(pr->tabBases[1],pr->tabBases[1],pr->modulus,ctx));
}
pr->pokDelta = cryptic_zkpk_schnorr_new(pr->tabBases, 2, pr->modulus);
goto_cleanup_if_fail(cryptic_zkpk_schnorr_verify_noninteractive_proof(pr->pokDelta,pr->dlreps[4],hash,responses+8) == 0);
if(neg) goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(pr->tabBases[1],tmp));
rc = CRYPTIC_NO_ERROR;
cleanup:
cryptic_release_ctx(ctx);
cryptic_release_mont(mont);
cryptic_release_bn(tmp);
return rc;
}
/* Getters */
BIGNUM*
cryptic_proofrange_qrg_get_modulus(CrypticProofrangeQrg *pr)
{
if(pr->modulus) {return(pr->modulus);}
else {return(NULL);}
}
BIGNUM**
cryptic_proofrange_qrg_get_dlreps(CrypticProofrangeQrg *pr)
{
if(pr->dlreps){
//concat avec delta
return(pr->dlreps);
}
else{
return(NULL);
}
}
BIGNUM**
cryptic_proofrange_qrg_get_commitments(CrypticProofrangeQrg *pr)
{
if(pr->pokSqrRoot1 && pr->pokSqrRoot2 && pr->pokSqrRoot3 && pr->pokSqrRoot4 && pr->pokDelta){
int i;
for(i=0;i<6;i++){
if(!(pr->commitments[i] = BN_new())) return NULL;
}
if(!BN_copy(pr->commitments[0],cryptic_zkpk_schnorr_get_commitment(pr->pokSqrRoot1))) return NULL;
if(!BN_copy(pr->commitments[1],cryptic_zkpk_schnorr_get_commitment(pr->pokSqrRoot2))) return NULL;
if(!BN_copy(pr->commitments[2],cryptic_zkpk_schnorr_get_commitment(pr->pokSqrRoot3))) return NULL;
if(!BN_copy(pr->commitments[3],cryptic_zkpk_schnorr_get_commitment(pr->pokSqrRoot4))) return NULL;
if(!BN_copy(pr->commitments[4],cryptic_zkpk_schnorr_get_commitment(pr->pokDelta))) return NULL;
if(!BN_copy(pr->commitments[5],pr->Q)) return NULL;
return(pr->commitments);
}
else {
return(NULL);
}
}
BIGNUM**
cryptic_proofrange_qrg_get_responses(CrypticProofrangeQrg *pr)
{
if(pr->pokSqrRoot1 && pr->pokSqrRoot2 && pr->pokSqrRoot3 && pr->pokSqrRoot4 && pr->pokDelta){
return(pr->responses);
}
else {
return(NULL);
}
}
BIGNUM**
cryptic_proofrange_qrg_get_tabRandDLRepSqrRoot(CrypticProofrangeQrg *pr)
{
if(pr->tabRandDLRepSqrRoot){
//concat avec delta
return(pr->tabRandDLRepSqrRoot);
}
else{
return(NULL);
}
}