int PiAffp_Sample_and_Commit()

in src/cg21/cg21_rp_pi_affp.c [23:242]


int PiAffp_Sample_and_Commit(csprng *RNG, PAILLIER_private_key *paillier_priv, PAILLIER_public_key *paillier_pub,
                              PEDERSEN_PUB *pedersen_pub, octet *x, octet *y, PiAffp_SECRETS *secrets,
                              PiAffp_COMMITS *commit, PiAffp_COMMITS_OCT *commitsOct, octet *C){

    // ------------ VARIABLE DEFINITION ----------
    BIG_1024_58 n_b[FFLEN_2048];
    BIG_1024_58 n2_b[2 * FFLEN_2048];

    BIG_1024_58 q[HFLEN_2048];          //q:256 bits
    BIG_1024_58 q2[FFLEN_2048];         //q^2
    BIG_1024_58 q3[FFLEN_2048];         //q^3
    BIG_1024_58 q5[FFLEN_2048];         //q^5
    BIG_1024_58 q7[FFLEN_2048];         //q^7

    BIG_512_60 r[FFLEN_4096];
    BIG_1024_58 gamma_mod[2 * FFLEN_2048];
    BIG_1024_58 delta_mod[2 * FFLEN_2048];
    BIG_1024_58 m_mod[2 * FFLEN_2048];
    BIG_1024_58 mu_mod[2 * FFLEN_2048];

    BIG_1024_58 x_[2 * FFLEN_2048];
    BIG_1024_58 y_[2 * FFLEN_2048];

    BIG_512_60 ws1[FFLEN_4096];
    BIG_512_60 ws2[FFLEN_4096];
    BIG_512_60 dws[2 * FFLEN_4096];
    BIG_512_60 alpha[HFLEN_4096];
    BIG_512_60 r_[FFLEN_4096];
    BIG_512_60 beta[FFLEN_4096];
    BIG_1024_58 tws[FFLEN_2048 + HFLEN_2048];

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

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

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

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

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

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

    PAILLIER_public_key PUB;

    // Curve order
    CG21_GET_CURVE_ORDER(q);

    // Calculate N and N^2 parameters based on p and q
    FF_2048_mul(n_b, paillier_priv->p, paillier_priv->q, HFLEN_2048);

    FF_2048_sqr(n2_b, n_b, FFLEN_2048);
    FF_2048_norm(n2_b, 2 * FFLEN_2048);

    if (RNG == NULL)
    {
        return PiAffp_RNG_IS_NULL;
    }
    FF_2048_sqr(q2, q, HFLEN_2048);
    FF_2048_mul(q3, q, q2, HFLEN_2048);
    FF_2048_mul(q5, q3, q2, FFLEN_2048);
    FF_2048_mul(q7, q5, q2, FFLEN_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: 1024-bit random number
    FF_2048_mod(secrets->alpha, q3, HFLEN_2048);            //alpha: 1024-bit reduced to (3*256)-bit number

    // Generate beta in [0, .., q^7]
    FF_2048_zero(secrets->beta, FFLEN_2048);
    FF_2048_random(secrets->beta, RNG, FFLEN_2048);          //beta: 2048-bit random number
    FF_2048_mod(secrets->beta, q7, FFLEN_2048);              //beta: 2048-bit reduced to (7*256)-bit number

    // Generate r in [0, .., N]
    FF_4096_randomnum(r, paillier_pub->n, RNG, HFLEN_4096);   // r: 2048-bit random number
    FF_4096_toOctet(&OCT, r, HFLEN_4096);
    FF_2048_fromOctet(secrets->r, &OCT, FFLEN_2048);

    // Generate rx and ry in [0, .., N]
    FF_2048_randomnum(secrets->rx, n_b, RNG, FFLEN_2048);   // rx: 2048-bit random number
    FF_2048_randomnum(secrets->ry, n_b, RNG, FFLEN_2048);   // ry: 2048-bit random number

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

    // Generate delta in [0, .., Nt * q^3]
    CG21_FF_2048_amul(delta_mod, q3, HFLEN_2048, pedersen_pub->N, FFLEN_2048);   //Nt*q^3
    FF_2048_random(secrets->delta, RNG, FFLEN_2048 + HFLEN_2048);           //delta: (1024+2048)-bit random number

    //delta: (1024+2048)-bit reduced to (3*256+2048)-bit number
    FF_2048_mod(secrets->delta, delta_mod, FFLEN_2048 + HFLEN_2048);

    // Generate m in [0, .., Nt * q]
    CG21_FF_2048_amul(m_mod, q, HFLEN_2048, pedersen_pub->N, FFLEN_2048);
    FF_2048_random(secrets->m, RNG, FFLEN_2048 + HFLEN_2048);            //m: (1024+2048)-bit random number

    //m: (1024+2048)-bit reduced to (256+2048)-bit number
    FF_2048_mod(secrets->m, m_mod, FFLEN_2048 + HFLEN_2048);

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


    // ------------ READING INPUTS ----------
    OCT_copy(&OCT, x);
    OCT_pad(&OCT, HFS_2048);
    FF_2048_zero(x_, FFLEN_2048 + HFLEN_2048);
    FF_2048_fromOctet(x_, &OCT, HFLEN_2048);

    OCT_copy(&OCT, y);
    OCT_pad(&OCT, HFS_4096);
    FF_2048_zero(y_, HFLEN_4096);
    FF_2048_fromOctet(y_, &OCT, FFLEN_2048);

    // ------------ COMMITMENT ----------
    // Compute E: b0^alpha * b1^gamma mod hat{N}
    FF_2048_zero(tws, FFLEN_2048 + HFLEN_2048);
    FF_2048_copy(tws, secrets->alpha, HFLEN_2048);

    // b0 is s and b1 is t from paper's fig.26
    FF_2048_ct_pow_2(commit->E, pedersen_pub->b0, tws, pedersen_pub->b1, secrets->gamma,
                     pedersen_pub->N, FFLEN_2048, FFLEN_2048 + HFLEN_2048);

    // Compute S: b0^x * b1^m mod hat{N}
    FF_2048_ct_pow_2(commit->S, pedersen_pub->b0, x_, pedersen_pub->b1, secrets->m,
                     pedersen_pub->N, FFLEN_2048, FFLEN_2048 + HFLEN_2048);

    // Compute F: b0^beta * b1^delta mod hat{N}
    FF_2048_zero(tws, FFLEN_2048 + HFLEN_2048);
    FF_2048_copy(tws, secrets->beta, FFLEN_2048);
    FF_2048_ct_pow_2(commit->F, pedersen_pub->b0, tws, pedersen_pub->b1, secrets->delta,
                     pedersen_pub->N, FFLEN_2048, FFLEN_2048 + HFLEN_2048);

    // Compute T: b0^y * b1^mu mod hat{N}
    FF_2048_ct_pow_2(commit->T, pedersen_pub->b0, y_, pedersen_pub->b1, secrets->mu,
                     pedersen_pub->N, FFLEN_2048, FFLEN_2048 + HFLEN_2048);

    // Compute A = C^alpha * g^beta * r^N mod n2
    FF_4096_fromOctet(ws2, C, FFLEN_4096);

    FF_2048_toOctet(&alpha_oct, secrets->alpha, HFLEN_2048);
    OCT_pad(&alpha_oct, HFS_4096);
    FF_4096_fromOctet(alpha, &alpha_oct, HFLEN_4096);

    FF_2048_toOctet(&beta_oct, secrets->beta, FFLEN_2048);
    OCT_pad(&beta_oct, HFS_4096);
    FF_4096_fromOctet(beta, &beta_oct, HFLEN_4096);

    FF_2048_toOctet(&OCT, secrets->r, FFLEN_2048);
    OCT_pad(&OCT, FS_4096);
    FF_4096_fromOctet(r_, &OCT, FFLEN_4096);

    // (N0 * beta + 1)
    FF_4096_zero(ws1, FFLEN_4096);
    FF_4096_mul(ws1, paillier_pub->n, beta, HFLEN_4096);
    FF_4096_inc(ws1, 1, FFLEN_4096);
    FF_4096_norm(ws1, FFLEN_4096);

    // C^alpha * r^N0 mod n2
    FF_4096_ct_pow_2(ws2, ws2, alpha, r_, paillier_pub->n, paillier_pub->n2, FFLEN_4096, HFLEN_4096);

    // (N0 * beta + 1) * C^alpha * r^N0 mod N0^2
    FF_4096_zero(dws, 2 * FFLEN_4096);
    FF_4096_mul(dws, ws1, ws2, FFLEN_4096);
    FF_4096_dmod(ws1, dws, paillier_pub->n2, FFLEN_4096);

    FF_4096_toOctet(&OCT, ws1, FFLEN_4096);
    FF_2048_fromOctet(commit->A, &OCT, 2 * FFLEN_2048);

    // Form PAILLIER_public_key using prover's PK
    FF_2048_toOctet(&OCT, n_b, FFLEN_2048);
    OCT_pad(&OCT, HFS_2048);
    FF_4096_zero(PUB.n, FFLEN_4096);
    FF_4096_fromOctet(PUB.n, &OCT, HFLEN_4096);
    FF_4096_sqr(PUB.n2, PUB.n, HFLEN_4096);
    FF_4096_norm(PUB.n2, FFLEN_4096);

    // Computes Bx and By
    FF_2048_toOctet(&rx_oct, secrets->rx, 2*FFLEN_2048);
    OCT_pad(&rx_oct, FS_4096);

    FF_2048_toOctet(&ry_oct, secrets->ry, 2*FFLEN_2048);
    OCT_pad(&ry_oct, FS_4096);

    PAILLIER_ENCRYPT(NULL, &PUB, &alpha_oct, &CT_oct,&rx_oct); // Bx = Enc(alpha; rx)
    FF_2048_fromOctet(commit->Bx, &CT_oct, 2 * FFLEN_2048);

    PAILLIER_ENCRYPT(NULL, &PUB, &beta_oct, &CT_oct,&ry_oct);  // By = Enc(beta; ry)
    FF_2048_fromOctet(commit->By, &CT_oct, 2 * FFLEN_2048);

    PiAffp_Commitment_toOctets_enc(commitsOct, commit);

    // ------------ CLEAN MEMORY ----------
    OCT_clear(&OCT);
    OCT_clear(&rx_oct);
    OCT_clear(&ry_oct);
    OCT_clear(&alpha_oct);
    OCT_clear(&beta_oct);
    OCT_clear(&CT_oct);
    FF_2048_zero(x_, FFLEN_2048 + HFLEN_2048);
    FF_2048_zero(y_, HFLEN_4096);
    FF_2048_zero(tws, FFLEN_2048 + HFLEN_2048);
    FF_4096_zero(r, FFLEN_4096);
    FF_4096_zero(ws1, FFLEN_4096);
    FF_4096_zero(ws2, FFLEN_4096);
    FF_4096_zero(dws, 2*FFLEN_4096);

    return PiAffp_OK;
}