in src/cg21/cg21_rp_pi_enc.c [343:441]
int PiEnc_Verify(PAILLIER_public_key *pub_key, PEDERSEN_PRIV *priv_com, octet *K_oct,
PiEnc_COMMITS *commits, octet *e_oct, PiEnc_PROOFS *proofs)
{
// ------------ VARIABLE DEFINITION ----------
BIG_1024_58 ws[FFLEN_2048];
BIG_1024_58 hws1[HFLEN_2048];
BIG_1024_58 hws2[HFLEN_2048];
BIG_1024_58 wp_proof[HFLEN_2048];
BIG_1024_58 wq_proof[HFLEN_2048];
BIG_1024_58 e[HFLEN_2048];
BIG_512_60 e_4096[HFLEN_4096];
BIG_512_60 s1[HFLEN_4096];
BIG_512_60 ws1_4096[FFLEN_4096];
BIG_512_60 ws2_4096[FFLEN_4096];
BIG_512_60 dws_4096[2*FFLEN_4096];
char oct[FS_2048];
octet OCT = {0, sizeof(oct), oct};
// ------------ READ INPUTS ----------
OCT_copy(&OCT, e_oct);
OCT_pad(&OCT, HFS_2048);
FF_2048_fromOctet(e, &OCT, HFLEN_2048);
OCT_pad(&OCT, HFS_4096);
FF_4096_fromOctet(e_4096, &OCT, HFLEN_4096);
OCT_clear(&OCT);
// Read q and compute q^3
CG21_GET_CURVE_ORDER(hws1);
FF_2048_sqr(ws, hws1, HFLEN_2048);
FF_2048_mul(ws, ws, hws1, HFLEN_2048);
// ------------ CHECK 'z1' IS IN [-q^3, ..., q^3] ------------
if (FF_2048_comp(proofs->z1, ws, FFLEN_2048) > 0)
{
return PiEnc_INVALID_RANGE;
}
// ------------ VALIDATES THE PROOF - PART1 ----------
// Split computation of proofs for C using CRT.
CG21_Pedersen_verify(wp_proof, priv_com, proofs->z1, proofs->z3, commits->S, e, priv_com->mod.p,false);
CG21_Pedersen_verify(wq_proof, priv_com, proofs->z1, proofs->z3, commits->S, e, priv_com->mod.q, false);
// Reduce C mod P and Q for comparison
FF_2048_dmod(hws1, commits->C, priv_com->mod.p, HFLEN_2048);
FF_2048_dmod(hws2, commits->C, priv_com->mod.q, HFLEN_2048);
// Compare the results modulo P and Q
// since C == C' mod PQ <==> C == C' mod P & C == C' mod Q
int fail = (FF_2048_comp(hws1, wp_proof, HFLEN_2048) != 0) || (FF_2048_comp(hws2, wq_proof, HFLEN_2048) != 0);
// ------------ CLEAN MEMORY ----------
OCT_clear(&OCT);
FF_2048_zero(hws1, HFLEN_2048);
FF_2048_zero(hws2, HFLEN_2048);
FF_2048_zero(wp_proof, HFLEN_2048);
FF_2048_zero(wq_proof, HFLEN_2048);
if(fail)
{
return PiEnc_INVALID_PROOF_P1;
}
// ------------ VALIDATES THE PROOF - PART2 ----------
FF_2048_toOctet(&OCT, proofs->z1, HFLEN_2048);
OCT_pad(&OCT, HFS_4096);
FF_4096_fromOctet(s1, &OCT, HFLEN_4096);
FF_4096_fromOctet(ws1_4096, K_oct, FFLEN_4096);
FF_4096_invmodp(ws1_4096, ws1_4096, pub_key->n2, FFLEN_4096);
// u_proof = (1+N)^z1 * z2^N * K_oct^(-e) mod N^2
FF_4096_mul(ws2_4096, pub_key->n, s1, HFLEN_4096);
FF_4096_inc(ws2_4096, 1, FFLEN_4096);
FF_4096_norm(ws2_4096, FFLEN_4096);
FF_4096_nt_pow_2(ws1_4096, proofs->z2, pub_key->n, ws1_4096, e_4096, pub_key->n2, FFLEN_4096, HFLEN_4096);
FF_4096_mul(dws_4096, ws1_4096, ws2_4096, FFLEN_4096);
FF_4096_dmod(ws1_4096, dws_4096, pub_key->n2, FFLEN_4096);
// ------------ CLEAN MEMORY ----------
OCT_clear(&OCT);
FF_4096_zero(dws_4096, 2 * FFLEN_4096);
FF_4096_zero(ws2_4096, FFLEN_4096);
FF_4096_zero(s1, HFLEN_4096);
// ------------ OUTPUT ----------
if(FF_4096_comp(ws1_4096, commits->A, FFLEN_4096) != 0)
{
FF_4096_zero(ws1_4096, FFLEN_4096);
return PiEnc_INVALID_PROOF_P2;
}
// ------------ CLEAN MEMORY ----------
FF_4096_zero(ws1_4096, FFLEN_4096);
return PiEnc_OK;
}