Beispiel #1
0
/* < 0 means right shift, > 0 means left shift */
void
mpi_shift(const mpi *p, int bits, mpi *q)
{
    if (bits < 0)
        mpi_rshift(p, -bits, q);
    else if (bits > 0)
        mpi_lshift(p, +bits, q);
}
Beispiel #2
0
void
mpi_mul_u64(const mpi *a, uint64_t b, mpi *p)
{
    if (mpi_is_zero(a) || b == 0) {
        mpi_zero(p);
        return;
    } else if (b == 1) {
        if (a != p)
            mpi_set_mpi(p, a);
        return;
    } else if ((b & (b-1)) == 0) {	/* B is a power of 2 */
        mpi_lshift(a, __builtin_ctzll(b), p);
        return;
    } else if (b == (mp_digit)b) {	/* B fits in an mp_digit */
        if (a == p) {
            mp_digit cy = mp_dmuli(p->digits, p->size, (mp_digit)b);
            if (cy) {
                MPI_MIN_ALLOC(p, p->size + 1);
                p->digits[p->size++] = cy;
            }
        } else {
            MPI_MIN_ALLOC(p, a->size);
            mp_digit cy = mp_dmul(a->digits, a->size, (mp_digit)b, p->digits);
            if (cy) {
                MPI_MIN_ALLOC(p, a->size + 1);
                p->digits[a->size] = cy;
                p->size = a->size + 1;
            } else {
                p->size = a->size;
            }
        }
    } else {
        unsigned bits = CHAR_BIT * sizeof(uint64_t) - __builtin_clzll(b);
        mp_size size = (bits + MP_DIGIT_BITS - 1) / MP_DIGIT_BITS;
        mp_digit *bp = MP_TMP_ALLOC(size);
#if MP_DIGIT_BITS >= 64
        bp[0] = b;
#else
        for (mp_size j=0; j<size; j++) {
            bp[j] = (mp_digit)b;
            b >>= MP_DIGIT_BITS;
        }
#endif
        if (a == p) {
            mp_digit *tmp = MP_TMP_ALLOC(p->size + size);
            mp_mul(p->digits, p->size, bp, size, tmp);
            MPI_MIN_ALLOC(p, p->size + size);
            mp_copy(tmp, p->size + size, p->digits);
            p->size = mp_rsize(p->digits, p->size + size);
            MP_TMP_FREE(tmp);
        } else {
            MPI_MIN_ALLOC(p, a->size + size);
            mp_mul(a->digits, a->size, bp, size, p->digits);
            p->size = mp_rsize(p->digits, a->size + size);
        }
        MP_TMP_FREE(bp);
    }
}
Beispiel #3
0
static void
do_lshift (void)
{
  if (stackidx < 1)
    {
      fputs ("stack underflow\n", stderr);
      return;
    }
  mpi_lshift (stack[stackidx - 1], stack[stackidx - 1], 1);
}