in src/cg21/cg21_pi_mod.c [186:266]
static void CG21_PI_MOD_GEN_Zi(CG21_PIMOD_PROOF *pimodProof, CG21_PAILLIER_KEYS paillierKeys){
BIG_1024_58 Mp[HFLEN_2048];
BIG_1024_58 Mq[HFLEN_2048];
BIG_1024_58 Xp[HFLEN_2048];
BIG_1024_58 Xq[HFLEN_2048];
BIG_1024_58 ws[FFLEN_2048];
BIG_1024_58 n_2048[FFLEN_2048];
char oct[2*FS_2048];
octet OCT = {0, sizeof(oct), oct};
/* Compute Mp, Mq s.t.
*
* T ← PQ^(-1) mod (P-1)(Q-1)
* zi ← yi^T mod PQ, for i ∈ [1 ... m]
*
* i.e.
* Mp = Q^(-1) mod P-1
* Mq = P^(-1) mod Q-1
*/
// Compute Mp
// Since P is odd P>>1 = (P-1)/2
FF_2048_copy(ws, paillierKeys.paillier_sk.p, HFLEN_2048);
FF_2048_shr(ws, HFLEN_2048);
// Compute inverse mod (P-1)/2
FF_2048_invmodp(Mp, paillierKeys.paillier_sk.q, ws, HFLEN_2048);
// Apply correction to obtain inverse mod P-1
if (!FF_2048_parity(Mp))
{
FF_2048_add(Mp, ws, Mp, HFLEN_2048);
FF_2048_norm(Mp, HFLEN_2048);
}
// Compute Mq
// Since Q is odd Q>>1 = (Q-1)/2
FF_2048_copy(ws, paillierKeys.paillier_sk.q, HFLEN_2048);
FF_2048_shr(ws, HFLEN_2048);
// Compute inverse mod (Q-1)/2
FF_2048_invmodp(Mq, paillierKeys.paillier_sk.p, ws, HFLEN_2048);
// Apply correction to obtain inverse mod Q-1
if (!FF_2048_parity(Mq))
{
FF_2048_add(Mq, ws, Mq, HFLEN_2048);
FF_2048_norm(Mq, HFLEN_2048);
}
// convert paillier_pk.n from BIG_512_60[HFLEN_4096] to BIG_1024_58[FFLEN_2048]
FF_4096_toOctet(&OCT, paillierKeys.paillier_pk.n, HFLEN_4096);
FF_2048_fromOctet(n_2048, &OCT, FFLEN_2048);
for (int i=0; i<CG21_PAILLIER_PROOF_ITERS;i++){
// Xp = yi % p
FF_2048_dmod(Xp, pimodProof->yi[i], paillierKeys.paillier_sk.p, HFLEN_2048);
// Xq = yi % q
FF_2048_dmod(Xq, pimodProof->yi[i], paillierKeys.paillier_sk.q, HFLEN_2048);
// Compute zi^M using Mp, Mq and CRT
FF_2048_ct_pow(Xp, Xp, Mp, paillierKeys.paillier_sk.p, HFLEN_2048, HFLEN_2048);
FF_2048_ct_pow(Xq, Xq, Mq, paillierKeys.paillier_sk.q, HFLEN_2048, HFLEN_2048);
// zi ← yi^T mod PQ, for i ∈ [1 ... m]
FF_2048_crt(pimodProof->zi[i], Xp, Xq, paillierKeys.paillier_sk.p, paillierKeys.paillier_sk.invpq, n_2048, HFLEN_2048);
}
// clean up
FF_2048_zero(Mp,HFLEN_2048);
FF_2048_zero(Mq,HFLEN_2048);
FF_2048_zero(Xp,HFLEN_2048);
FF_2048_zero(Xq,FFLEN_2048);
FF_2048_zero(ws,FFLEN_2048);
}