in src/cg21/cg21_rp_pi_affg.c [23:243]
int Piaffg_Sample_and_Commit(csprng *RNG, PAILLIER_private_key *paillier_priv, PAILLIER_public_key *paillier_pub,
PEDERSEN_PUB *pedersen_pub, octet *x, octet *y, Piaffg_SECRETS *secrets,
Piaffg_COMMITS *commit, Piaffg_COMMITS_OCT *commitsOct, octet *C){
// ------------ VARIABLE DEFINITION ----------
ECP_SECP256K1 G;
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, 2^{\ell' + \epsilon}
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};
// 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 PiAffg_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: 2048-bit number
FF_2048_mod(secrets->alpha, q3, HFLEN_2048); //alpha: (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 number
FF_2048_mod(secrets->beta, q7, FFLEN_2048); //beta: (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 ry in [0, .., N]
FF_2048_zero(secrets->ry, 2*FFLEN_2048);
FF_2048_randomnum(secrets->ry, n_b, RNG, FFLEN_2048); // ry: 2048-bit random number
// Generate gamma in [0, .., Nt * q^3]
// See Remark 1 at the top for more information
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: a (1024+2048)-bit 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]
// See Remark 1 at the top for more information
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: a (1024+2048)-bit number
FF_2048_mod(secrets->delta, delta_mod, FFLEN_2048 + HFLEN_2048); //delta: (3*256+2048-bit) number
// Generate m in [0, .., Nt * q]
// See Remark 1 at the top for more information
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: a (1024+2048)-bit number
FF_2048_mod(secrets->m, m_mod, FFLEN_2048 + HFLEN_2048); //m: (256+2048-bit) number
// Generate mu in [0, .., Nt * q]
// See Remark 1 at the top for more information
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: a (1024+2048)-bit number
FF_2048_mod(secrets->mu, mu_mod, FFLEN_2048 + HFLEN_2048); //mu: (256+2048)-bit number
// ------------ READING INPUTS ----------
OCT_copy(&OCT, x);
OCT_pad(&OCT, HFS_2048);
FF_2048_zero(x_, FFLEN_2048 + HFLEN_2048); // Set x_ to zero
FF_2048_fromOctet(x_, &OCT, HFLEN_2048);
OCT_copy(&OCT, y);
OCT_pad(&OCT, HFS_4096);
FF_2048_zero(y_, 2*FFLEN_2048); // Set y_ to zero
FF_2048_fromOctet(y_, &OCT, FFLEN_2048);
// ------------ COMMITMENT ----------
// Compute E
FF_2048_zero(tws, FFLEN_2048 + HFLEN_2048);
FF_2048_copy(tws, secrets->alpha, HFLEN_2048);
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
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
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
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);
PAILLIER_public_key PUB;
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 By
FF_2048_toOctet(&ry_oct, secrets->ry, 2*FFLEN_2048);
OCT_pad(&ry_oct, FS_4096);
PAILLIER_ENCRYPT(NULL, &PUB, &beta_oct, &CT_oct,&ry_oct);
FF_2048_fromOctet(commit->By, &CT_oct, 2 * FFLEN_2048);
// Computes Bx
ECP_SECP256K1_generator(&G);
ECP_mul_1024(&G, secrets->alpha);
ECP_SECP256K1_copy(&commit->Bx,&G);
Piaffg_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);
FF_2048_zero(q2, FFLEN_2048);
FF_2048_zero(q3, FFLEN_2048);
FF_2048_zero(q5, FFLEN_2048);
FF_2048_zero(q7, FFLEN_2048);
return Piaffg_OK;
}