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;
}