int bn_lshift_fixed_top(BIGNUM *r, const BIGNUM *a, int n)
{
    int i, nw;
    unsigned int lb, rb;
    BN_ULONG *t, *f;
    BN_ULONG l, m, rmask = 0;

    assert(n >= 0);

    bn_check_top(r);
    bn_check_top(a);

    nw = n / BN_BITS2;
    if (bn_wexpand(r, a->top + nw + 1) == NULL)
        return 0;

    if (a->top != 0) {
        lb = (unsigned int)n % BN_BITS2;
        rb = BN_BITS2 - lb;
        rb %= BN_BITS2;            /* say no to undefined behaviour */
        rmask = (BN_ULONG)0 - rb;  /* rmask = 0 - (rb != 0) */
        rmask |= rmask >> 8;
        f = &(a->d[0]);
        t = &(r->d[nw]);
        l = f[a->top - 1];
        t[a->top] = (l >> rb) & rmask;
        for (i = a->top - 1; i > 0; i--) {
            m = l << lb;
            l = f[i - 1];
            t[i] = (m | ((l >> rb) & rmask)) & BN_MASK2;
        }
        t[0] = (l << lb) & BN_MASK2;
    } else {
        /* shouldn't happen, but formally required */
        r->d[nw] = 0;
    }
    if (nw != 0)
        memset(r->d, 0, sizeof(*t) * nw);

    r->neg = a->neg;
    r->top = a->top + nw + 1;
    r->flags |= BN_FLG_FIXED_TOP;

    return 1;
}