void BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords)
{
    BN_ULONG t;
    int i;
    bn_wcheck_size(a, nwords);
    bn_wcheck_size(b, nwords);
    assert(a != b);
    assert((condition & (condition - 1)) == 0);
    assert(sizeof(BN_ULONG) >= sizeof(int));
    condition = ((condition - 1) >> (BN_BITS2 - 1)) - 1;
    t = (a->top ^ b->top) & condition;
    a->top ^= t;
    b->top ^= t;
    t = (a->neg ^ b->neg) & condition;
    a->neg ^= t;
    b->neg ^= t;
    t = ((a->flags ^ b->flags) & BN_FLG_CONSTTIME) & condition;
    a->flags ^= t;
    b->flags ^= t;
#define BN_CONSTTIME_SWAP(ind) \
        do { \
                t = (a->d[ind] ^ b->d[ind]) & condition; \
                a->d[ind] ^= t; \
                b->d[ind] ^= t; \
        } while (0)
    switch (nwords) {
    default:
        for (i = 10; i < nwords; i++)
            BN_CONSTTIME_SWAP(i);
    case 10:
        BN_CONSTTIME_SWAP(9);
    case 9:
        BN_CONSTTIME_SWAP(8);
    case 8:
        BN_CONSTTIME_SWAP(7);
    case 7:
        BN_CONSTTIME_SWAP(6);
    case 6:
        BN_CONSTTIME_SWAP(5);
    case 5:
        BN_CONSTTIME_SWAP(4);
    case 4:
        BN_CONSTTIME_SWAP(3);
    case 3:
        BN_CONSTTIME_SWAP(2);
    case 2:
        BN_CONSTTIME_SWAP(1);
    case 1:
        BN_CONSTTIME_SWAP(0);
    }
#undef BN_CONSTTIME_SWAP
}
['static\nint ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,\n                         const BIGNUM *scalar, const EC_POINT *point,\n                         BN_CTX *ctx)\n{\n    int i, cardinality_bits, group_top, kbit, pbit, Z_is_one;\n    EC_POINT *p = NULL;\n    EC_POINT *s = NULL;\n    BIGNUM *k = NULL;\n    BIGNUM *lambda = NULL;\n    BIGNUM *cardinality = NULL;\n    BN_CTX *new_ctx = NULL;\n    int ret = 0;\n    if (point != NULL && EC_POINT_is_at_infinity(group, point))\n        return EC_POINT_set_to_infinity(group, r);\n    if (ctx == NULL && (ctx = new_ctx = BN_CTX_secure_new()) == NULL)\n        return 0;\n    BN_CTX_start(ctx);\n    if (((p = EC_POINT_new(group)) == NULL)\n        || ((s = EC_POINT_new(group)) == NULL)) {\n        ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_MALLOC_FAILURE);\n        goto err;\n    }\n    if (point == NULL) {\n        if (!EC_POINT_copy(p, group->generator)) {\n            ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_EC_LIB);\n            goto err;\n        }\n    } else {\n        if (!EC_POINT_copy(p, point)) {\n            ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_EC_LIB);\n            goto err;\n        }\n    }\n    EC_POINT_BN_set_flags(p, BN_FLG_CONSTTIME);\n    EC_POINT_BN_set_flags(r, BN_FLG_CONSTTIME);\n    EC_POINT_BN_set_flags(s, BN_FLG_CONSTTIME);\n    cardinality = BN_CTX_get(ctx);\n    lambda = BN_CTX_get(ctx);\n    k = BN_CTX_get(ctx);\n    if (k == NULL) {\n        ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_MALLOC_FAILURE);\n        goto err;\n    }\n    if (!BN_mul(cardinality, group->order, group->cofactor, ctx)) {\n        ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);\n        goto err;\n    }\n    cardinality_bits = BN_num_bits(cardinality);\n    group_top = bn_get_top(cardinality);\n    if ((bn_wexpand(k, group_top + 1) == NULL)\n        || (bn_wexpand(lambda, group_top + 1) == NULL)) {\n        ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);\n        goto err;\n    }\n    if (!BN_copy(k, scalar)) {\n        ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);\n        goto err;\n    }\n    BN_set_flags(k, BN_FLG_CONSTTIME);\n    if ((BN_num_bits(k) > cardinality_bits) || (BN_is_negative(k))) {\n        if (!BN_nnmod(k, k, cardinality, ctx)) {\n            ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);\n            goto err;\n        }\n    }\n    if (!BN_add(lambda, k, cardinality)) {\n        ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);\n        goto err;\n    }\n    BN_set_flags(lambda, BN_FLG_CONSTTIME);\n    if (!BN_add(k, lambda, cardinality)) {\n        ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);\n        goto err;\n    }\n    kbit = BN_is_bit_set(lambda, cardinality_bits);\n    BN_consttime_swap(kbit, k, lambda, group_top + 1);\n    group_top = bn_get_top(group->field);\n    if ((bn_wexpand(s->X, group_top) == NULL)\n        || (bn_wexpand(s->Y, group_top) == NULL)\n        || (bn_wexpand(s->Z, group_top) == NULL)\n        || (bn_wexpand(r->X, group_top) == NULL)\n        || (bn_wexpand(r->Y, group_top) == NULL)\n        || (bn_wexpand(r->Z, group_top) == NULL)\n        || (bn_wexpand(p->X, group_top) == NULL)\n        || (bn_wexpand(p->Y, group_top) == NULL)\n        || (bn_wexpand(p->Z, group_top) == NULL)) {\n        ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);\n        goto err;\n    }\n    if (!ec_point_blind_coordinates(group, p, ctx)) {\n        ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_POINT_COORDINATES_BLIND_FAILURE);\n        goto err;\n    }\n    if (!ec_point_ladder_pre(group, r, s, p, ctx)) {\n        ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_LADDER_PRE_FAILURE);\n        goto err;\n    }\n    pbit = 1;\n#define EC_POINT_CSWAP(c, a, b, w, t) do {         \\\n        BN_consttime_swap(c, (a)->X, (b)->X, w);   \\\n        BN_consttime_swap(c, (a)->Y, (b)->Y, w);   \\\n        BN_consttime_swap(c, (a)->Z, (b)->Z, w);   \\\n        t = ((a)->Z_is_one ^ (b)->Z_is_one) & (c); \\\n        (a)->Z_is_one ^= (t);                      \\\n        (b)->Z_is_one ^= (t);                      \\\n} while(0)\n    for (i = cardinality_bits - 1; i >= 0; i--) {\n        kbit = BN_is_bit_set(k, i) ^ pbit;\n        EC_POINT_CSWAP(kbit, r, s, group_top, Z_is_one);\n        if (!ec_point_ladder_step(group, r, s, p, ctx)) {\n            ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_LADDER_STEP_FAILURE);\n            goto err;\n        }\n        pbit ^= kbit;\n    }\n    EC_POINT_CSWAP(pbit, r, s, group_top, Z_is_one);\n#undef EC_POINT_CSWAP\n    if (!ec_point_ladder_post(group, r, s, p, ctx)) {\n        ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_LADDER_POST_FAILURE);\n        goto err;\n    }\n    ret = 1;\n err:\n    EC_POINT_free(p);\n    EC_POINT_free(s);\n    BN_CTX_end(ctx);\n    BN_CTX_free(new_ctx);\n    return ret;\n}', 'int BN_is_bit_set(const BIGNUM *a, int n)\n{\n    int i, j;\n    bn_check_top(a);\n    if (n < 0)\n        return 0;\n    i = n / BN_BITS2;\n    j = n % BN_BITS2;\n    if (a->top <= i)\n        return 0;\n    return (int)(((a->d[i]) >> j) & ((BN_ULONG)1));\n}', 'void BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords)\n{\n    BN_ULONG t;\n    int i;\n    bn_wcheck_size(a, nwords);\n    bn_wcheck_size(b, nwords);\n    assert(a != b);\n    assert((condition & (condition - 1)) == 0);\n    assert(sizeof(BN_ULONG) >= sizeof(int));\n    condition = ((condition - 1) >> (BN_BITS2 - 1)) - 1;\n    t = (a->top ^ b->top) & condition;\n    a->top ^= t;\n    b->top ^= t;\n    t = (a->neg ^ b->neg) & condition;\n    a->neg ^= t;\n    b->neg ^= t;\n    t = ((a->flags ^ b->flags) & BN_FLG_CONSTTIME) & condition;\n    a->flags ^= t;\n    b->flags ^= t;\n#define BN_CONSTTIME_SWAP(ind) \\\n        do { \\\n                t = (a->d[ind] ^ b->d[ind]) & condition; \\\n                a->d[ind] ^= t; \\\n                b->d[ind] ^= t; \\\n        } while (0)\n    switch (nwords) {\n    default:\n        for (i = 10; i < nwords; i++)\n            BN_CONSTTIME_SWAP(i);\n    case 10:\n        BN_CONSTTIME_SWAP(9);\n    case 9:\n        BN_CONSTTIME_SWAP(8);\n    case 8:\n        BN_CONSTTIME_SWAP(7);\n    case 7:\n        BN_CONSTTIME_SWAP(6);\n    case 6:\n        BN_CONSTTIME_SWAP(5);\n    case 5:\n        BN_CONSTTIME_SWAP(4);\n    case 4:\n        BN_CONSTTIME_SWAP(3);\n    case 3:\n        BN_CONSTTIME_SWAP(2);\n    case 2:\n        BN_CONSTTIME_SWAP(1);\n    case 1:\n        BN_CONSTTIME_SWAP(0);\n    }\n#undef BN_CONSTTIME_SWAP\n}']