in src/cg21/cg21_pi_factor.c [534:751]
int CG21_PI_FACTOR_VERIFY(const CG21_PiFACTOR_COMMIT *r1pub, const CG21_PiFACTOR_PROOF *proof, octet *N_oct,
PEDERSEN_PRIV *priv_com, const CG21_SSID *ssid, int n){
char oct[3*FS_2048];
octet OCT = {0, sizeof(oct), oct};
char te[MODBYTES_256_56];
octet e = {0, sizeof(te), te};
BIG_1024_58 q[HFLEN_2048];
BIG_1024_58 q2[FFLEN_2048];
BIG_1024_58 q3[FFLEN_2048];
BIG_1024_58 q4[FFLEN_2048];
BIG_1024_58 q7[FFLEN_2048];
BIG_1024_58 e_[HFLEN_2048];
BIG_1024_58 z1[FFLEN_2048 + HFLEN_2048];
BIG_1024_58 z2[FFLEN_2048 + HFLEN_2048];
BIG_1024_58 w1[FFLEN_2048 + HFLEN_2048];
BIG_1024_58 w2[FFLEN_2048 + HFLEN_2048];
BIG_1024_58 v[2*FFLEN_2048 + HFLEN_2048];
BIG_1024_58 P[FFLEN_2048];
BIG_1024_58 Q[FFLEN_2048];
BIG_1024_58 A[FFLEN_2048];
BIG_1024_58 B[FFLEN_2048];
BIG_1024_58 T[FFLEN_2048];
BIG_1024_58 p_verify[FFLEN_2048];
BIG_1024_58 q_verify[FFLEN_2048];
BIG_1024_58 p_gt[FFLEN_2048];
BIG_1024_58 q_gt[FFLEN_2048];
BIG_1024_58 t[FFLEN_2048 + HFLEN_2048];
BIG_1024_58 R[FFLEN_2048];
BIG_1024_58 t2[2*FFLEN_2048 + HFLEN_2048];
BIG_1024_58 t3[2*FFLEN_2048 + HFLEN_2048];
BIG_1024_58 N[FFLEN_2048];
PEDERSEN_PUB Pedersen_pub;
FF_2048_fromOctet(N, N_oct, FFLEN_2048);
// Curve order
CG21_GET_CURVE_ORDER(q);
FF_2048_sqr(q2, q, HFLEN_2048);
FF_2048_mul(q3, q, q2, HFLEN_2048);
FF_2048_mul(q4, q, q3, HFLEN_2048);
FF_2048_mul(q7, q4, q3, HFLEN_2048);
FF_2048_zero(t, FFLEN_2048 + HFLEN_2048);
FF_2048_copy(t, q7, FFLEN_2048); // t = q7
// get Pedersen public parameters
Pedersen_get_public_param(&Pedersen_pub, priv_com);
/* Check both z1 and z2 are in the valid range */
// load z1
OCT_clear(&OCT);
OCT_copy(&OCT, proof->z1);
OCT_pad(&OCT, FS_2048+ HFS_2048);
FF_2048_fromOctet(z1, &OCT, FFLEN_2048 + HFLEN_2048);
// ------------ CHECK 'z1' IS IN [0, ..., t=q^7] ------------
if (FF_2048_comp(z1, t, FFLEN_2048 + HFLEN_2048) > 0)
{
return CG21_PI_FACTOR_INVALID_RANGE;
}
// load z2
OCT_clear(&OCT);
OCT_copy(&OCT, proof->z2);
OCT_pad(&OCT, FS_2048+ HFS_2048);
FF_2048_fromOctet(z2, &OCT, FFLEN_2048 + HFLEN_2048);
// ------------ CHECK 'z2' IS IN [0, ..., t=q^7] ------------
if (FF_2048_comp(z2, t, FFLEN_2048 + HFLEN_2048) > 0)
{
return CG21_PI_FACTOR_INVALID_RANGE;
}
// load w1
OCT_clear(&OCT);
OCT_copy(&OCT, proof->w1);
OCT_pad(&OCT, FS_2048 + HFS_2048);
FF_2048_fromOctet(w1, &OCT, FFLEN_2048 + HFLEN_2048);
// load w2
OCT_clear(&OCT);
OCT_copy(&OCT, proof->w2);
OCT_pad(&OCT, FS_2048 + HFS_2048);
FF_2048_fromOctet(w2, &OCT, FFLEN_2048 + HFLEN_2048);
// load v
OCT_clear(&OCT);
OCT_copy(&OCT, proof->v);
OCT_pad(&OCT, 2*FS_2048 + HFS_2048);
FF_2048_fromOctet(v, &OCT, 2*FFLEN_2048 + HFLEN_2048);
// load A
OCT_clear(&OCT);
OCT_copy(&OCT, r1pub->A);
OCT_pad(&OCT, FS_2048);
FF_2048_fromOctet(A, &OCT, FFLEN_2048);
// load B
OCT_clear(&OCT);
OCT_copy(&OCT, r1pub->B);
OCT_pad(&OCT, FS_2048);
FF_2048_fromOctet(B, &OCT, FFLEN_2048);
// load P
OCT_clear(&OCT);
OCT_copy(&OCT, r1pub->P);
OCT_pad(&OCT, FS_2048);
FF_2048_fromOctet(P, &OCT, FFLEN_2048);
// load Q
OCT_clear(&OCT);
OCT_copy(&OCT, r1pub->Q);
OCT_pad(&OCT, FS_2048);
FF_2048_fromOctet(Q, &OCT, FFLEN_2048);
// load T
OCT_clear(&OCT);
OCT_copy(&OCT, r1pub->T);
OCT_pad(&OCT, FS_2048);
FF_2048_fromOctet(T, &OCT, FFLEN_2048);
// generate challenge e
CG21_PI_FACTOR_CHALLENGE(ssid, Pedersen_pub.N, N, &e, n);
// load octet e as HFLEN_2048 in e_
OCT_copy(&OCT, &e);
OCT_pad(&OCT, HFS_2048);
FF_2048_fromOctet(e_, &OCT, HFLEN_2048);
/* Split check s^z1 * t^w1 * P^(-e) == A mod PQ using CRT */
CG21_PI_FACTOR_PED_verify(p_verify, priv_com->b0, priv_com->b1, z1, w1,
P, e_, priv_com->mod.p, FFLEN_2048 + HFLEN_2048, FFLEN_2048 + HFLEN_2048);
CG21_PI_FACTOR_PED_verify(q_verify, priv_com->b0, priv_com->b1, z1, w1,
P, e_, priv_com->mod.q, FFLEN_2048 + HFLEN_2048, FFLEN_2048 + HFLEN_2048);
FF_2048_dmod(p_gt, A, priv_com->mod.p, HFLEN_2048);
FF_2048_dmod(q_gt, A, priv_com->mod.q, HFLEN_2048);
int fail = (FF_2048_comp(p_gt, p_verify, HFLEN_2048) != 0) || (FF_2048_comp(q_gt, q_verify, HFLEN_2048) != 0);
if (fail)
{
// Clean memory
FF_2048_zero(p_gt, HFLEN_2048);
FF_2048_zero(q_gt, HFLEN_2048);
FF_2048_zero(p_verify, HFLEN_2048);
FF_2048_zero(q_verify, HFLEN_2048);
return CG21_PI_FACTOR_INVALID_PROOF;
}
/* Split check s^z2 * t^w2 * Q^(-e) == B mod PQ using CRT */
CG21_PI_FACTOR_PED_verify(p_verify, priv_com->b0, priv_com->b1, z2, w2,
Q, e_, priv_com->mod.p, FFLEN_2048 + HFLEN_2048, FFLEN_2048 + HFLEN_2048);
CG21_PI_FACTOR_PED_verify(q_verify, priv_com->b0, priv_com->b1, z2, w2,
Q, e_, priv_com->mod.q, FFLEN_2048 + HFLEN_2048, FFLEN_2048 + HFLEN_2048);
FF_2048_dmod(p_gt, B, priv_com->mod.p, HFLEN_2048);
FF_2048_dmod(q_gt, B, priv_com->mod.q, HFLEN_2048);
fail = (FF_2048_comp(p_gt, p_verify, HFLEN_2048) != 0) || (FF_2048_comp(q_gt, q_verify, HFLEN_2048) != 0);
if (fail)
{
// Clean memory
FF_2048_zero(p_gt, HFLEN_2048);
FF_2048_zero(q_gt, HFLEN_2048);
FF_2048_zero(p_verify, HFLEN_2048);
FF_2048_zero(q_verify, HFLEN_2048);
return CG21_PI_FACTOR_INVALID_PROOF;
}
/* Compute R = s^{pa_N}t^{sigma}*/
// load sigma
OCT_clear(&OCT);
OCT_copy(&OCT, r1pub->sigma);
OCT_pad(&OCT, 2*FS_2048+HFS_2048);
FF_2048_fromOctet(t2, &OCT, 2*FFLEN_2048 + HFLEN_2048); // t2 = sigma
// load Paillier N as 2*FFLEN_2048 + HFLEN_2048
OCT_clear(&OCT);
FF_2048_toOctet(&OCT, N, FFLEN_2048);
OCT_pad(&OCT, 2*FS_2048+HFS_2048);
FF_2048_fromOctet(t3, &OCT, 2*FFLEN_2048 + HFLEN_2048); // t3 = Paillier N
// R = s^{pa_N}t^{sigma} mod hat{N}
FF_2048_ct_pow_2(R, Pedersen_pub.b0, t3, Pedersen_pub.b1, t2,Pedersen_pub.N,
FFLEN_2048, 2*FFLEN_2048 + HFLEN_2048);
/* Q^z1 * t^v * R^(-e) == T mod PQ using CRT */
CG21_PI_FACTOR_PED_verify(p_verify, Q, priv_com->b1, z1, v,
R, e_, priv_com->mod.p, FFLEN_2048 + HFLEN_2048, 2 * FFLEN_2048 + HFLEN_2048);
CG21_PI_FACTOR_PED_verify(q_verify, Q, priv_com->b1, z1, v,
R, e_, priv_com->mod.q, FFLEN_2048 + HFLEN_2048, 2 * FFLEN_2048 + HFLEN_2048);
FF_2048_dmod(p_gt, T, priv_com->mod.p, HFLEN_2048);
FF_2048_dmod(q_gt, T, priv_com->mod.q, HFLEN_2048);
fail = (FF_2048_comp(p_gt, p_verify, HFLEN_2048) != 0) || (FF_2048_comp(q_gt, q_verify, HFLEN_2048) != 0);
if (fail)
{
// Clean memory
FF_2048_zero(p_gt, HFLEN_2048);
FF_2048_zero(q_gt, HFLEN_2048);
FF_2048_zero(p_verify, HFLEN_2048);
FF_2048_zero(q_verify, HFLEN_2048);
return CG21_PI_FACTOR_INVALID_PROOF;
}
return CG21_OK;
}