int PiLogstar_Verify()

in src/cg21/cg21_rp_pi_logstar.c [374:507]


int PiLogstar_Verify(PAILLIER_public_key *pub_key, PEDERSEN_PRIV *priv_com, octet *C_oct, octet *g,
                 PiLogstar_COMMITS *commits, octet *X, octet *e_oct, PiLogstar_PROOFS *proofs)
{
    int fail;
    int equal;
    ECP_SECP256K1 G;
    ECP_SECP256K1 P;
    ECP_SECP256K1 Q;


    // ------------ 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);                         // hws1 is now q
    FF_2048_sqr(ws, hws1, HFLEN_2048);             // ws is q^2
    FF_2048_mul(ws, ws, hws1, HFLEN_2048);      // ws is now q^3


    // ------------ CHECK 'z1' IS IN [0, ..., q^3] ------------
    if (FF_2048_comp(proofs->z1, ws, FFLEN_2048) > 0)
    {
        return PiLogstar_INVALID_RANGE;
    }

    // ------------ VALIDATES THE PROOF - PART1 ----------
    // s^z1 * t^z3 =? D * S^e
    // 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->D, priv_com->mod.p, HFLEN_2048);
    FF_2048_dmod(hws2, commits->D, 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
    fail = (FF_2048_comp(hws1, wp_proof, HFLEN_2048) != 0) || (FF_2048_comp(hws2, wq_proof, HFLEN_2048) != 0);

    // ------------ CLEAN MEMORY ----------
    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 PiLogstar_INVALID_PROOF_P1;
    }

    // ------------ VALIDATES THE PROOF - PART2 ----------
    //(1+N)^z1 * z2^N * C_oct^(-e) mod N^2 =? A
    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, C_oct, FFLEN_4096);
    FF_4096_invmodp(ws1_4096, ws1_4096, pub_key->n2, FFLEN_4096);

    // u_proof = (1+N)^z1 * z2^N * C_oct^(-e) mod N^2 ,  (u_proof = ws2_4096 * ws1_4096)
    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 PiLogstar_INVALID_PROOF_P2;
    }

    // ------------ VALIDATES THE PROOF - PART4 ----------
    // z1*G =? Y + e*X

    int rc = ECP_SECP256K1_fromOctet(&G, g);
    if (rc != 1)
    {
        return Pilogstar_Y_FAIL;
    }
    ECP_mul_1024(&G, proofs->z1);

    ECP_SECP256K1_copy(&P,&commits->Y);       // P <- Y
    ECP_SECP256K1_fromOctet(&Q, X);         // Q <- X
    ECP_mul_1024(&Q, e);                      // Q <- e * X

    ECP_SECP256K1_add(&P, &Q);                  // P <- Y + e * X

    equal = ECP_SECP256K1_equals(&P, &G);

    // ------------ CLEAN MEMORY ----------
    ECP_SECP256K1_inf(&G);
    ECP_SECP256K1_inf(&P);
    ECP_SECP256K1_inf(&Q);
    FF_4096_zero(ws1_4096, FFLEN_4096);

    if (equal!=1)
    {
        return PiLogstar_INVALID_PROOF_P3;
    }

    // Note that 'z1' is already checked to be in the range of [0, ..., q^3]

    return PiLogstar_OK;
}