int CG21_SIGN_VALIDATE()

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