static unsigned int BN_STACK_pop(BN_STACK *st)
{
    return st->indexes[--(st->depth)];
}
['static int ecp_nistz256_points_mul(const EC_GROUP *group,\n                                          EC_POINT *r,\n                                          const BIGNUM *scalar,\n                                          size_t num,\n                                          const EC_POINT *points[],\n                                          const BIGNUM *scalars[], BN_CTX *ctx)\n{\n    int i = 0, ret = 0, no_precomp_for_generator = 0, p_is_infinity = 0;\n    unsigned char p_str[33] = { 0 };\n    const PRECOMP256_ROW *preComputedTable = NULL;\n    const NISTZ256_PRE_COMP *pre_comp = NULL;\n    const EC_POINT *generator = NULL;\n    const BIGNUM **new_scalars = NULL;\n    const EC_POINT **new_points = NULL;\n    unsigned int idx = 0;\n    const unsigned int window_size = 7;\n    const unsigned int mask = (1 << (window_size + 1)) - 1;\n    unsigned int wvalue;\n    ALIGN32 union {\n        P256_POINT p;\n        P256_POINT_AFFINE a;\n    } t, p;\n    BIGNUM *tmp_scalar;\n    if ((num + 1) == 0 || (num + 1) > OPENSSL_MALLOC_MAX_NELEMS(void *)) {\n        ECerr(EC_F_ECP_NISTZ256_POINTS_MUL, ERR_R_MALLOC_FAILURE);\n        return 0;\n    }\n    BN_CTX_start(ctx);\n    if (scalar) {\n        generator = EC_GROUP_get0_generator(group);\n        if (generator == NULL) {\n            ECerr(EC_F_ECP_NISTZ256_POINTS_MUL, EC_R_UNDEFINED_GENERATOR);\n            goto err;\n        }\n        pre_comp = group->pre_comp.nistz256;\n        if (pre_comp) {\n            EC_POINT *pre_comp_generator = EC_POINT_new(group);\n            if (pre_comp_generator == NULL)\n                goto err;\n            ecp_nistz256_gather_w7(&p.a, pre_comp->precomp[0], 1);\n            if (!ecp_nistz256_set_from_affine(pre_comp_generator,\n                                              group, &p.a, ctx)) {\n                EC_POINT_free(pre_comp_generator);\n                goto err;\n            }\n            if (0 == EC_POINT_cmp(group, generator, pre_comp_generator, ctx))\n                preComputedTable = (const PRECOMP256_ROW *)pre_comp->precomp;\n            EC_POINT_free(pre_comp_generator);\n        }\n        if (preComputedTable == NULL && ecp_nistz256_is_affine_G(generator)) {\n            preComputedTable = ecp_nistz256_precomputed;\n        }\n        if (preComputedTable) {\n            if ((BN_num_bits(scalar) > 256)\n                || BN_is_negative(scalar)) {\n                if ((tmp_scalar = BN_CTX_get(ctx)) == NULL)\n                    goto err;\n                if (!BN_nnmod(tmp_scalar, scalar, group->order, ctx)) {\n                    ECerr(EC_F_ECP_NISTZ256_POINTS_MUL, ERR_R_BN_LIB);\n                    goto err;\n                }\n                scalar = tmp_scalar;\n            }\n            for (i = 0; i < bn_get_top(scalar) * BN_BYTES; i += BN_BYTES) {\n                BN_ULONG d = bn_get_words(scalar)[i / BN_BYTES];\n                p_str[i + 0] = (unsigned char)d;\n                p_str[i + 1] = (unsigned char)(d >> 8);\n                p_str[i + 2] = (unsigned char)(d >> 16);\n                p_str[i + 3] = (unsigned char)(d >>= 24);\n                if (BN_BYTES == 8) {\n                    d >>= 8;\n                    p_str[i + 4] = (unsigned char)d;\n                    p_str[i + 5] = (unsigned char)(d >> 8);\n                    p_str[i + 6] = (unsigned char)(d >> 16);\n                    p_str[i + 7] = (unsigned char)(d >> 24);\n                }\n            }\n            for (; i < 33; i++)\n                p_str[i] = 0;\n#if defined(ECP_NISTZ256_AVX2)\n            if (ecp_nistz_avx2_eligible()) {\n                ecp_nistz256_avx2_mul_g(&p.p, p_str, preComputedTable);\n            } else\n#endif\n            {\n                BN_ULONG infty;\n                wvalue = (p_str[0] << 1) & mask;\n                idx += window_size;\n                wvalue = _booth_recode_w7(wvalue);\n                ecp_nistz256_gather_w7(&p.a, preComputedTable[0],\n                                       wvalue >> 1);\n                ecp_nistz256_neg(p.p.Z, p.p.Y);\n                copy_conditional(p.p.Y, p.p.Z, wvalue & 1);\n                infty = (p.p.X[0] | p.p.X[1] | p.p.X[2] | p.p.X[3] |\n                         p.p.Y[0] | p.p.Y[1] | p.p.Y[2] | p.p.Y[3]);\n                if (P256_LIMBS == 8)\n                    infty |= (p.p.X[4] | p.p.X[5] | p.p.X[6] | p.p.X[7] |\n                              p.p.Y[4] | p.p.Y[5] | p.p.Y[6] | p.p.Y[7]);\n                infty = 0 - is_zero(infty);\n                infty = ~infty;\n                p.p.Z[0] = ONE[0] & infty;\n                p.p.Z[1] = ONE[1] & infty;\n                p.p.Z[2] = ONE[2] & infty;\n                p.p.Z[3] = ONE[3] & infty;\n                if (P256_LIMBS == 8) {\n                    p.p.Z[4] = ONE[4] & infty;\n                    p.p.Z[5] = ONE[5] & infty;\n                    p.p.Z[6] = ONE[6] & infty;\n                    p.p.Z[7] = ONE[7] & infty;\n                }\n                for (i = 1; i < 37; i++) {\n                    unsigned int off = (idx - 1) / 8;\n                    wvalue = p_str[off] | p_str[off + 1] << 8;\n                    wvalue = (wvalue >> ((idx - 1) % 8)) & mask;\n                    idx += window_size;\n                    wvalue = _booth_recode_w7(wvalue);\n                    ecp_nistz256_gather_w7(&t.a,\n                                           preComputedTable[i], wvalue >> 1);\n                    ecp_nistz256_neg(t.p.Z, t.a.Y);\n                    copy_conditional(t.a.Y, t.p.Z, wvalue & 1);\n                    ecp_nistz256_point_add_affine(&p.p, &p.p, &t.a);\n                }\n            }\n        } else {\n            p_is_infinity = 1;\n            no_precomp_for_generator = 1;\n        }\n    } else\n        p_is_infinity = 1;\n    if (no_precomp_for_generator) {\n        new_scalars = OPENSSL_malloc((num + 1) * sizeof(BIGNUM *));\n        if (new_scalars == NULL) {\n            ECerr(EC_F_ECP_NISTZ256_POINTS_MUL, ERR_R_MALLOC_FAILURE);\n            goto err;\n        }\n        new_points = OPENSSL_malloc((num + 1) * sizeof(EC_POINT *));\n        if (new_points == NULL) {\n            ECerr(EC_F_ECP_NISTZ256_POINTS_MUL, ERR_R_MALLOC_FAILURE);\n            goto err;\n        }\n        memcpy(new_scalars, scalars, num * sizeof(BIGNUM *));\n        new_scalars[num] = scalar;\n        memcpy(new_points, points, num * sizeof(EC_POINT *));\n        new_points[num] = generator;\n        scalars = new_scalars;\n        points = new_points;\n        num++;\n    }\n    if (num) {\n        P256_POINT *out = &t.p;\n        if (p_is_infinity)\n            out = &p.p;\n        if (!ecp_nistz256_windowed_mul(group, out, scalars, points, num, ctx))\n            goto err;\n        if (!p_is_infinity)\n            ecp_nistz256_point_add(&p.p, &p.p, out);\n    }\n    if (!bn_set_words(r->X, p.p.X, P256_LIMBS) ||\n        !bn_set_words(r->Y, p.p.Y, P256_LIMBS) ||\n        !bn_set_words(r->Z, p.p.Z, P256_LIMBS)) {\n        goto err;\n    }\n    r->Z_is_one = is_one(r->Z) & 1;\n    ret = 1;\nerr:\n    BN_CTX_end(ctx);\n    OPENSSL_free(new_points);\n    OPENSSL_free(new_scalars);\n    return ret;\n}', 'void BN_CTX_start(BN_CTX *ctx)\n{\n    CTXDBG("ENTER 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("LEAVE BN_CTX_start()", ctx);\n}', 'void BN_CTX_end(BN_CTX *ctx)\n{\n    CTXDBG("ENTER 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("LEAVE BN_CTX_end()", ctx);\n}', 'static unsigned int BN_STACK_pop(BN_STACK *st)\n{\n    return st->indexes[--(st->depth)];\n}']