diff options
-rw-r--r-- | rand.c | 92 |
1 files changed, 46 insertions, 46 deletions
@@ -367,52 +367,7 @@ val random(val state, val modulus) cobj_handle(self, state, random_state_cls)); mp_int *m; - if (bignump(modulus) && !mp_isneg(m = mp(modulus))) { - ucnum bits = mp_count_bits(m) - mp_is_pow_two(m); - ucnum rands_needed = (bits + 32 - 1) / 32; - ucnum msb_rand_bits = bits % 32; - rand32_t msb_rand_mask = convert(rand32_t, -1) >> (msb_rand_bits - ? 32 - msb_rand_bits - : 0); - val out = make_bignum(); - mp_int *om = mp(out); - - for (;;) { - ucnum i; - for (i = 0; i < rands_needed; i++) { - rand32_t rnd = rand32(r); - mp_err mpe = MP_OKAY; -#if MP_DIGIT_SIZE >= 4 - if (i > 0) - mpe = mp_mul_2d(om, 32, om); - else - rnd &= msb_rand_mask; - if (mpe == MP_OKAY) - mpe = mp_add_d(om, rnd, om); -#else - if (i > 0) - mpe = mp_mul_2d(om, 16, om); - else - rnd &= msb_rand_mask; - if (mpe == MP_OKAY) - mpe = mp_add_d(om, rnd & 0xFFFF, om); - if (mpe == MP_OKAY) - mpe = mp_mul_2d(om, 16, om); - if (mpe == MP_OKAY) - mp_add_d(om, rnd >> 16, om); -#endif - if (mpe != MP_OKAY) - do_mp_error(self, mpe); - } - if (mp_cmp(om, m) != MP_LT) { - mp_zero(om); - continue; - } - break; - } - - return normalize(out); - } else if (fixnump(modulus)) { + if (fixnump(modulus)) { cnum m = c_num(modulus, self); if (m == 1) { return zero; @@ -583,6 +538,51 @@ val random(val state, val modulus) default: break; } + } else if (bignump(modulus) && !mp_isneg(m = mp(modulus))) { + ucnum bits = mp_count_bits(m) - mp_is_pow_two(m); + ucnum rands_needed = (bits + 32 - 1) / 32; + ucnum msb_rand_bits = bits % 32; + rand32_t msb_rand_mask = convert(rand32_t, -1) >> (msb_rand_bits + ? 32 - msb_rand_bits + : 0); + val out = make_bignum(); + mp_int *om = mp(out); + + for (;;) { + ucnum i; + for (i = 0; i < rands_needed; i++) { + rand32_t rnd = rand32(r); + mp_err mpe = MP_OKAY; +#if MP_DIGIT_SIZE >= 4 + if (i > 0) + mpe = mp_mul_2d(om, 32, om); + else + rnd &= msb_rand_mask; + if (mpe == MP_OKAY) + mpe = mp_add_d(om, rnd, om); +#else + if (i > 0) + mpe = mp_mul_2d(om, 16, om); + else + rnd &= msb_rand_mask; + if (mpe == MP_OKAY) + mpe = mp_add_d(om, rnd & 0xFFFF, om); + if (mpe == MP_OKAY) + mpe = mp_mul_2d(om, 16, om); + if (mpe == MP_OKAY) + mp_add_d(om, rnd >> 16, om); +#endif + if (mpe != MP_OKAY) + do_mp_error(self, mpe); + } + if (mp_cmp(om, m) != MP_LT) { + mp_zero(om); + continue; + } + break; + } + + return normalize(out); } uw_throwf(numeric_error_s, lit("~a: invalid modulus ~s"), |