int PiEnc_Sample_randoms_and_commit()

in src/cg21/cg21_rp_pi_enc.c [23:167]


int PiEnc_Sample_randoms_and_commit(csprng *RNG, PAILLIER_private_key *priv_key, PEDERSEN_PUB *pub_com,
                                    octet *k, PiEnc_SECRETS *secrets, PiEnc_COMMITS *commits, PiEnc_COMMITS_OCT *commitsOct)
{

    /*
     * ---------STEP 1: choosing randoms -----------
     * alpha:       random from [0, q^3]
     * mu_mod:      q + \hat{N} bits
     * r:           Z_{N_0}
     * gamma_mod:   q^3 + \hat{N} bits
     */

     /* ---------STEP 2: commitment --------------
     * S = s^k x t^mu_mod pub_com \hat{N}
     * A = (1 + N0)^alpha x r^N0 pub_com N0^2
     * C = s^alpha x t^gamma_mod pub_com \hat{N}
     */


    // ------------ CHECKING INPUTS -------------
    if (RNG == NULL){
        return PiEnc_RNG_IS_NULL;
    }
    if (priv_key == NULL){
        return PiEnc_PAILLIER_SK_IS_NULL;
    }
    if (pub_com == NULL){
        return PiEnc_COM_PUB_IS_NULL;
    }
    if (k == NULL){
        return PiEnc_INPUT_IS_NULL;
    }

    // ------------ VARIABLE DEFINITION ----------
    BIG_1024_58 q[HFLEN_2048];
    BIG_1024_58 q2[FFLEN_2048];
    BIG_1024_58 q3[FFLEN_2048];

    BIG_1024_58 n[FFLEN_2048];
    BIG_1024_58 invp2q2[FFLEN_2048];
    BIG_1024_58 n2[2 * FFLEN_2048];
    BIG_1024_58 ws3[FFLEN_2048];
    BIG_1024_58 gamma_mod[FFLEN_2048 + HFLEN_2048];
    BIG_1024_58 mu_mod[2 * FFLEN_2048];
    BIG_1024_58 dws2[2 * FFLEN_2048];
    BIG_1024_58 t[2 * FFLEN_2048];

    char oct[2 * FS_2048];
    octet OCT = {0, sizeof(oct), oct};


    // Curve order
    CG21_GET_CURVE_ORDER(q);

    FF_2048_mul(n, priv_key->p, priv_key->q, HFLEN_2048);
    FF_2048_sqr(n2, n, FFLEN_2048);
    FF_2048_norm(n2, 2 * FFLEN_2048);
    FF_2048_invmodp(invp2q2, priv_key->p2, priv_key->q2, FFLEN_2048);


    FF_2048_sqr(q2, q, HFLEN_2048);
    FF_2048_mul(q3, q, q2, HFLEN_2048);

    // ------------ RANDOM GENERATION ----------
    // Generate alpha in [0, .., q^3]
    FF_2048_zero(secrets->alpha, FFLEN_2048);
    FF_2048_random(secrets->alpha, RNG, HFLEN_2048);        //alpha: a 1024-bit number
    FF_2048_mod(secrets->alpha, q3, HFLEN_2048);            //alpha: in  [0, .., q^3]

    // Generate r in [0, .., N]
    FF_2048_randomnum(secrets->r, n, RNG, FFLEN_2048);   // r: 1024-bit random number

    // Generate gamma in [0, .., Nt * q^3]
    CG21_FF_2048_amul(gamma_mod, q3, HFLEN_2048, pub_com->N, FFLEN_2048);   //Nt*q^3
    FF_2048_random(secrets->gamma, RNG, FFLEN_2048 + HFLEN_2048);           //gamma_mod: a (1024+2048)-bit number
    FF_2048_mod(secrets->gamma, gamma_mod, FFLEN_2048 + HFLEN_2048);            //gamma_mod: in [0, .., 3*256+2048]

    // Generate mu in [0, .., Nt * q]
    CG21_FF_2048_amul(mu_mod, q, HFLEN_2048, pub_com->N, FFLEN_2048);
    FF_2048_random(secrets->mu, RNG, FFLEN_2048 + HFLEN_2048);         //mu_mod: a (1024+2048)-bit number
    FF_2048_mod(secrets->mu, mu_mod, FFLEN_2048 + HFLEN_2048);             //mu_mod: in [0, .., 256+2048]


    // ------------ READING INPUTS ----------
    OCT_copy(&OCT, k);
    OCT_pad(&OCT, HFS_2048);
    FF_2048_zero(t, 2*FFLEN_2048);       // Set t to zero
    FF_2048_fromOctet(t, &OCT, HFLEN_2048);

    // ------------ COMMITMENT ----------
    // Compute S and C
    FF_2048_ct_pow_2(commits->S, pub_com->b0, t, pub_com->b1, secrets->mu, pub_com->N, FFLEN_2048, FFLEN_2048 + HFLEN_2048);

    FF_2048_copy(t, secrets->alpha, HFLEN_2048);
    FF_2048_ct_pow_2(commits->C, pub_com->b0, t, pub_com->b1, secrets->gamma, pub_com->N, FFLEN_2048, FFLEN_2048 + HFLEN_2048);

    // Compute A using CRT and Paillier PK trick
    // Compute 1 + n * alpha
    // Defer the increment after the modular reduction so it can
    // be performed without conversion to FF_4096
    FF_2048_zero(dws2, 2 * FFLEN_2048);
    CG21_FF_2048_amul(dws2, secrets->alpha, HFLEN_2048, n, FFLEN_2048);

    // Compute pub_com P^2
    FF_2048_dmod(ws3, dws2, priv_key->p2, FFLEN_2048);
    FF_2048_inc(ws3, 1, FFLEN_2048);
    FF_2048_norm(ws3, FFLEN_2048);

    FF_2048_ct_pow(q2, secrets->r, n, priv_key->p2, FFLEN_2048, FFLEN_2048);

    FF_2048_mul(t, q2, ws3, FFLEN_2048);
    FF_2048_dmod(q2, t, priv_key->p2, FFLEN_2048);

    // Compute pub_com Q^2
    FF_2048_dmod(ws3, dws2, priv_key->q2, FFLEN_2048);
    FF_2048_inc(ws3, 1, FFLEN_2048);
    FF_2048_norm(ws3, FFLEN_2048);

    FF_2048_ct_pow(q3, secrets->r, n, priv_key->q2, FFLEN_2048, FFLEN_2048);

    FF_2048_mul(t, q3, ws3, FFLEN_2048);
    FF_2048_dmod(q3, t, priv_key->q2, FFLEN_2048);

    // Combine results
    FF_2048_crt(t, q2, q3, priv_key->p2, invp2q2, n2, FFLEN_2048);

    // Convert A to FF_4096 since it is only used as such
    FF_2048_toOctet(&OCT, t, 2 * FFLEN_2048);
    FF_4096_fromOctet(commits->A, &OCT, FFLEN_4096);

    // the commitment to octets for transmission
    PiEnc_Commitment_toOctets_enc(commitsOct, commits);

    // ------------ CLEAN MEMORY ----------
    OCT_clear(&OCT);
    FF_2048_zero(dws2, 2 * FFLEN_2048);
    FF_2048_zero(ws3, FFLEN_2048);
    FF_2048_zero(q2, FFLEN_2048);
    FF_2048_zero(q3, FFLEN_2048);
    FF_2048_zero(t, 2 * FFLEN_2048);
    FF_2048_zero(invp2q2, FFLEN_2048);
    FF_2048_zero(ws3, HFLEN_2048);

    return PiEnc_OK;
}