static
int SM2_sig_verify(const EC_KEY *key, const ECDSA_SIG *sig, const BIGNUM *e)
{
    int ret = 0;
    const EC_GROUP *group = EC_KEY_get0_group(key);
    const BIGNUM *order = EC_GROUP_get0_order(group);
    BN_CTX *ctx = NULL;
    EC_POINT *pt = NULL;
    BIGNUM *t = NULL;
    BIGNUM *x1 = NULL;
    const BIGNUM *r = NULL;
    const BIGNUM *s = NULL;
    ctx = BN_CTX_new();
    if (ctx == NULL)
        goto done;
    pt = EC_POINT_new(group);
    if (pt == NULL)
        goto done;
    BN_CTX_start(ctx);
    t = BN_CTX_get(ctx);
    x1 = BN_CTX_get(ctx);
    if (x1 == NULL)
        goto done;
    ECDSA_SIG_get0(sig, &r, &s);
    if (BN_cmp(r, BN_value_one()) < 0)
        goto done;
    if (BN_cmp(s, BN_value_one()) < 0)
        goto done;
    if (BN_cmp(order, r) <= 0)
        goto done;
    if (BN_cmp(order, s) <= 0)
        goto done;
    if (BN_mod_add(t, r, s, order, ctx) == 0)
        goto done;
    if (BN_is_zero(t) == 1)
        goto done;
    if (EC_POINT_mul(group, pt, s, EC_KEY_get0_public_key(key), t, ctx) == 0)
        goto done;
    if (EC_POINT_get_affine_coordinates_GFp(group, pt, x1, NULL, ctx) == 0)
        goto done;
    if (BN_mod_add(t, e, x1, order, ctx) == 0)
        goto done;
    if (BN_cmp(r, t) == 0)
        ret = 1;
 done:
    EC_POINT_free(pt);
    BN_CTX_free(ctx);
    return ret;
}
['static\nint SM2_sig_verify(const EC_KEY *key, const ECDSA_SIG *sig, const BIGNUM *e)\n{\n    int ret = 0;\n    const EC_GROUP *group = EC_KEY_get0_group(key);\n    const BIGNUM *order = EC_GROUP_get0_order(group);\n    BN_CTX *ctx = NULL;\n    EC_POINT *pt = NULL;\n    BIGNUM *t = NULL;\n    BIGNUM *x1 = NULL;\n    const BIGNUM *r = NULL;\n    const BIGNUM *s = NULL;\n    ctx = BN_CTX_new();\n    if (ctx == NULL)\n        goto done;\n    pt = EC_POINT_new(group);\n    if (pt == NULL)\n        goto done;\n    BN_CTX_start(ctx);\n    t = BN_CTX_get(ctx);\n    x1 = BN_CTX_get(ctx);\n    if (x1 == NULL)\n        goto done;\n    ECDSA_SIG_get0(sig, &r, &s);\n    if (BN_cmp(r, BN_value_one()) < 0)\n        goto done;\n    if (BN_cmp(s, BN_value_one()) < 0)\n        goto done;\n    if (BN_cmp(order, r) <= 0)\n        goto done;\n    if (BN_cmp(order, s) <= 0)\n        goto done;\n    if (BN_mod_add(t, r, s, order, ctx) == 0)\n        goto done;\n    if (BN_is_zero(t) == 1)\n        goto done;\n    if (EC_POINT_mul(group, pt, s, EC_KEY_get0_public_key(key), t, ctx) == 0)\n        goto done;\n    if (EC_POINT_get_affine_coordinates_GFp(group, pt, x1, NULL, ctx) == 0)\n        goto done;\n    if (BN_mod_add(t, e, x1, order, ctx) == 0)\n        goto done;\n    if (BN_cmp(r, t) == 0)\n        ret = 1;\n done:\n    EC_POINT_free(pt);\n    BN_CTX_free(ctx);\n    return ret;\n}', 'const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key)\n{\n    return key->group;\n}', 'const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group)\n{\n    return group->order;\n}', 'void EC_POINT_free(EC_POINT *point)\n{\n    if (!point)\n        return;\n    if (point->meth->point_finish != 0)\n        point->meth->point_finish(point);\n    OPENSSL_free(point);\n}', 'void BN_CTX_free(BN_CTX *ctx)\n{\n#ifdef BN_CTX_DEBUG\n    {\n        BN_POOL_ITEM *pool = ctx->pool.head;\n        fprintf(stderr, "BN_CTX_free, stack-size=%d, pool-bignums=%d\\n",\n                ctx->stack.size, ctx->pool.size);\n        fprintf(stderr, "dmaxs: ");\n        while (pool) {\n            unsigned loop = 0;\n            while (loop < BN_CTX_POOL_SIZE)\n                fprintf(stderr, "%02x ", pool->vals[loop++].dmax);\n            pool = pool->next;\n        }\n        fprintf(stderr, "\\n");\n    }\n#endif\n    BN_STACK_finish(&ctx->stack);\n    BN_POOL_finish(&ctx->pool);\n    OPENSSL_free(ctx);\n}', 'static void BN_STACK_finish(BN_STACK *st)\n{\n    OPENSSL_free(st->indexes);\n    st->indexes = NULL;\n}', 'void CRYPTO_free(void *str, const char *file, int line)\n{\n    INCREMENT(free_count);\n    if (free_impl != NULL && free_impl != &CRYPTO_free) {\n        free_impl(str, file, line);\n        return;\n    }\n#ifndef OPENSSL_NO_CRYPTO_MDEBUG\n    if (call_malloc_debug) {\n        CRYPTO_mem_debug_free(str, 0, file, line);\n        free(str);\n        CRYPTO_mem_debug_free(str, 1, file, line);\n    } else {\n        free(str);\n    }\n#else\n    free(str);\n#endif\n}', 'static void BN_POOL_finish(BN_POOL *p)\n{\n    unsigned int loop;\n    BIGNUM *bn;\n    while (p->head) {\n        for (loop = 0, bn = p->head->vals; loop++ < BN_CTX_POOL_SIZE; bn++)\n            if (bn->d)\n                BN_clear_free(bn);\n        p->current = p->head->next;\n        OPENSSL_free(p->head);\n        p->head = p->current;\n    }\n}']