int PiEnc_Verify()

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