static unsigned int BN_STACK_pop(BN_STACK *st)
{
    return st->indexes[--(st->depth)];
}
['int test_gf2m_mod_inv(BIO *bp, BN_CTX *ctx)\n{\n    BIGNUM *a, *b[2], *c, *d;\n    int i, j, ret = 0;\n    int p0[] = { 163, 7, 6, 3, 0, -1 };\n    int p1[] = { 193, 15, 0, -1 };\n    a = BN_new();\n    b[0] = BN_new();\n    b[1] = BN_new();\n    c = BN_new();\n    d = BN_new();\n    BN_GF2m_arr2poly(p0, b[0]);\n    BN_GF2m_arr2poly(p1, b[1]);\n    for (i = 0; i < num0; i++) {\n        BN_bntest_rand(a, 512, 0, 0);\n        for (j = 0; j < 2; j++) {\n            BN_GF2m_mod_inv(c, a, b[j], ctx);\n            BN_GF2m_mod_mul(d, a, c, b[j], ctx);\n            if (!BN_is_one(d)) {\n                fprintf(stderr, "GF(2^m) modular inversion test failed!\\n");\n                goto err;\n            }\n        }\n    }\n    ret = 1;\n err:\n    BN_free(a);\n    BN_free(b[0]);\n    BN_free(b[1]);\n    BN_free(c);\n    BN_free(d);\n    return ret;\n}', 'int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)\n{\n    BIGNUM *b, *c = NULL, *u = NULL, *v = NULL, *tmp;\n    int ret = 0;\n    bn_check_top(a);\n    bn_check_top(p);\n    BN_CTX_start(ctx);\n    if ((b = BN_CTX_get(ctx)) == NULL)\n        goto err;\n    if ((c = BN_CTX_get(ctx)) == NULL)\n        goto err;\n    if ((u = BN_CTX_get(ctx)) == NULL)\n        goto err;\n    if ((v = BN_CTX_get(ctx)) == NULL)\n        goto err;\n    if (!BN_GF2m_mod(u, a, p))\n        goto err;\n    if (BN_is_zero(u))\n        goto err;\n    if (!BN_copy(v, p))\n        goto err;\n# if 0\n    if (!BN_one(b))\n        goto err;\n    while (1) {\n        while (!BN_is_odd(u)) {\n            if (BN_is_zero(u))\n                goto err;\n            if (!BN_rshift1(u, u))\n                goto err;\n            if (BN_is_odd(b)) {\n                if (!BN_GF2m_add(b, b, p))\n                    goto err;\n            }\n            if (!BN_rshift1(b, b))\n                goto err;\n        }\n        if (BN_abs_is_word(u, 1))\n            break;\n        if (BN_num_bits(u) < BN_num_bits(v)) {\n            tmp = u;\n            u = v;\n            v = tmp;\n            tmp = b;\n            b = c;\n            c = tmp;\n        }\n        if (!BN_GF2m_add(u, u, v))\n            goto err;\n        if (!BN_GF2m_add(b, b, c))\n            goto err;\n    }\n# else\n    {\n        int i;\n        int ubits = BN_num_bits(u);\n        int vbits = BN_num_bits(v);\n        int top = p->top;\n        BN_ULONG *udp, *bdp, *vdp, *cdp;\n        if (!bn_wexpand(u, top))\n            goto err;\n        udp = u->d;\n        for (i = u->top; i < top; i++)\n            udp[i] = 0;\n        u->top = top;\n        if (!bn_wexpand(b, top))\n          goto err;\n        bdp = b->d;\n        bdp[0] = 1;\n        for (i = 1; i < top; i++)\n            bdp[i] = 0;\n        b->top = top;\n        if (!bn_wexpand(c, top))\n          goto err;\n        cdp = c->d;\n        for (i = 0; i < top; i++)\n            cdp[i] = 0;\n        c->top = top;\n        vdp = v->d;\n        while (1) {\n            while (ubits && !(udp[0] & 1)) {\n                BN_ULONG u0, u1, b0, b1, mask;\n                u0 = udp[0];\n                b0 = bdp[0];\n                mask = (BN_ULONG)0 - (b0 & 1);\n                b0 ^= p->d[0] & mask;\n                for (i = 0; i < top - 1; i++) {\n                    u1 = udp[i + 1];\n                    udp[i] = ((u0 >> 1) | (u1 << (BN_BITS2 - 1))) & BN_MASK2;\n                    u0 = u1;\n                    b1 = bdp[i + 1] ^ (p->d[i + 1] & mask);\n                    bdp[i] = ((b0 >> 1) | (b1 << (BN_BITS2 - 1))) & BN_MASK2;\n                    b0 = b1;\n                }\n                udp[i] = u0 >> 1;\n                bdp[i] = b0 >> 1;\n                ubits--;\n            }\n            if (ubits <= BN_BITS2) {\n                if (udp[0] == 0)\n                    goto err;\n                if (udp[0] == 1)\n                    break;\n            }\n            if (ubits < vbits) {\n                i = ubits;\n                ubits = vbits;\n                vbits = i;\n                tmp = u;\n                u = v;\n                v = tmp;\n                tmp = b;\n                b = c;\n                c = tmp;\n                udp = vdp;\n                vdp = v->d;\n                bdp = cdp;\n                cdp = c->d;\n            }\n            for (i = 0; i < top; i++) {\n                udp[i] ^= vdp[i];\n                bdp[i] ^= cdp[i];\n            }\n            if (ubits == vbits) {\n                BN_ULONG ul;\n                int utop = (ubits - 1) / BN_BITS2;\n                while ((ul = udp[utop]) == 0 && utop)\n                    utop--;\n                ubits = utop * BN_BITS2 + BN_num_bits_word(ul);\n            }\n        }\n        bn_correct_top(b);\n    }\n# endif\n    if (!BN_copy(r, b))\n        goto err;\n    bn_check_top(r);\n    ret = 1;\n err:\n# ifdef BN_DEBUG\n    bn_correct_top(c);\n    bn_correct_top(u);\n    bn_correct_top(v);\n# endif\n    BN_CTX_end(ctx);\n    return ret;\n}', 'void BN_CTX_start(BN_CTX *ctx)\n{\n    CTXDBG_ENTRY("BN_CTX_start", ctx);\n    if (ctx->err_stack || ctx->too_many)\n        ctx->err_stack++;\n    else if (!BN_STACK_push(&ctx->stack, ctx->used)) {\n        BNerr(BN_F_BN_CTX_START, BN_R_TOO_MANY_TEMPORARY_VARIABLES);\n        ctx->err_stack++;\n    }\n    CTXDBG_EXIT(ctx);\n}', 'void BN_CTX_end(BN_CTX *ctx)\n{\n    CTXDBG_ENTRY("BN_CTX_end", ctx);\n    if (ctx->err_stack)\n        ctx->err_stack--;\n    else {\n        unsigned int fp = BN_STACK_pop(&ctx->stack);\n        if (fp < ctx->used)\n            BN_POOL_release(&ctx->pool, ctx->used - fp);\n        ctx->used = fp;\n        ctx->too_many = 0;\n    }\n    CTXDBG_EXIT(ctx);\n}', 'static unsigned int BN_STACK_pop(BN_STACK *st)\n{\n    return st->indexes[--(st->depth)];\n}']