int PiLogstar_Sample_and_commit()

in src/cg21/cg21_rp_pi_logstar.c [24:184]


int PiLogstar_Sample_and_commit(csprng *RNG, PAILLIER_private_key *priv_key, PEDERSEN_PUB *pub_com,
                                octet *x, octet *g, PiLogstar_SECRETS *secrets, PiLogstar_COMMITS *commits,
                                PiLogstar_COMMITS_OCT *commitsOct)
{
    /*
     * ---------STEP 1: choosing randoms -----------
     * alpha:       random from [0, q^3]
     * mu_mod:      |q| + |\hat{N}| bits
     * r:           random from Z_{N_0}
     * gamma_mod:   |q^3| + |\hat{N}| bits
     *
     * ---------STEP 2: commitment --------------
     * S = s^x * t^mu mod \hat{N}
     * A = (1 + N0)^alpha * r^N0 mod N0^2
     * D = s^alpha * t^gamma mod \hat{N}
     * Y = alpha*G
     */


    // ------------ CHECKING INPUTS -------------
    if (RNG == NULL){
        return PiLogstar_RNG_IS_NULL;
    }
    if (priv_key == NULL){
        return PiLogstar_PAILLIER_SK_IS_NULL;
    }
    if (pub_com == NULL){
        return PiLogstar_COM_PUB_IS_NULL;
    }
    if (x == NULL){
        return PiLogstar_INPUT_IS_NULL;
    }
    if (g == NULL){
        return PiLogstar_INPUT_IS_NULL;
    }

    // ------------ VARIABLE DEFINITION ----------
    ECP_SECP256K1 G;

    BIG_1024_58 q[HFLEN_2048];          // q
    BIG_1024_58 q2[FFLEN_2048];         // q^2
    BIG_1024_58 q3[FFLEN_2048];         // q^3

    BIG_1024_58 n[FFLEN_2048];
    BIG_1024_58 invp2q2[FFLEN_2048];
    BIG_1024_58 n2[2 * FFLEN_2048];     // n^2
    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, HFLEN_2048);
    FF_2048_random(secrets->alpha, RNG, HFLEN_2048);        // alpha: a 1024-bit number
    FF_2048_mod(secrets->alpha, q3, HFLEN_2048);            // random of size |q^3| bits needs to be reduced mod q^3

    // Generate r in [0, .., N]
    FF_2048_randomnum(secrets->r, n, RNG, FFLEN_2048);   // |N| bit sized r needs to be reduced mod N

    // Generate mu_mod 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_mod 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, x);                      // x is 32 bytes long
    OCT_pad(&OCT, HFS_2048);                // pad to ensure that all 1024 bits are initialized
    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);

    // recall: b0 is s and b1 is t from the eprint fig.25
    FF_2048_ct_pow_2(commits->D, 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_zero(ws3, FFLEN_2048);
    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_zero(ws3, FFLEN_2048);
    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);

    // Compute Y
    int rc = ECP_SECP256K1_fromOctet(&G, g);
    if (rc != 1)
    {
        return Pilogstar_Y_FAIL;
    }
    ECP_mul_1024(&G, secrets->alpha);
    ECP_SECP256K1_copy(&commits->Y,&G);

    // the commitment to octets for transmission
    PiLogstar_Commitment_toOctets_logstar(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);

    return PiLogstar_OK;
}