in src/cg21/cg21_sign.c [175:254]
int CG21_SIGN_VALIDATE(const octet *msg,
CG21_SIGN_ROUND2_OUTPUT *out,
octet *PK){
BIG_256_56 q;
BIG_256_56 a;
BIG_256_56 r;
BIG_256_56 s;
BIG_256_56 b;
BIG_256_56 x;
BIG_256_56 y;
ECP_SECP256K1 G;
ECP_SECP256K1 c;
int valid;
char hm[SHA256_HASH_SIZE];
octet HM = {0,sizeof(hm),hm};
// hash message and store it in HM
ehashit(HASH_TYPE_SECP256K1, msg, -1, NULL, &HM, MODBYTES_256_56);
// Curve order
BIG_256_56_rcopy(q,CURVE_Order_SECP256K1);
ECP_SECP256K1_generator(&G);
// Load values
OCT_shl(out->r,out->r->len-MODBYTES_256_56);
OCT_shl(out->sigma,out->sigma->len-MODBYTES_256_56);
BIG_256_56_fromBytes(r,out->r->val);
BIG_256_56_fromBytes(s,out->sigma->val);
BIG_256_56_fromBytes(a,HM.val);
if (BIG_256_56_iszilch(r) || BIG_256_56_comp(r,q)>=0 || BIG_256_56_iszilch(s) || BIG_256_56_comp(s,q)>=0)
{
return CG21_SIGN_SIGNATURE_IS_INVALID;
}
/* ---------STEP 1: generate sigma ----------
* compute a = ms^{-1} mod q
* compute b = rs^{-1} mod q
* compute c = a*G + b*PK
* check c_x == r
*/
// s = s^-1 mod q
BIG_256_56_invmodp(s,s,q);
// a = ms^{-1} mod q
BIG_256_56_modmul(a,a,s,q);
// b = rs^{-1} mod q
BIG_256_56_modmul(b,r,s,q);
valid=ECP_SECP256K1_fromOctet(&c,PK);
if (!valid)
{
return CG21_INVALID_ECP;
}
// c = a*G + b*PK
ECP_SECP256K1_mul2(&c,&G,b,a);
if (ECP_SECP256K1_isinf(&c))
{
return CG21_INVALID_ECP;
}
// get x component of point c
ECP_SECP256K1_get(x,y,&c);
BIG_256_56_mod(x,q);
//check c_x == r
if (BIG_256_56_comp(x,r)!=0)
{
return CG21_SIGN_SIGNATURE_IS_INVALID;
}
return CG21_OK;
}