mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-06-30 19:12:48 -05:00
mpint: add mp_random_upto().
This is a third random-number generation function, with an API in between the too-specific mp_random_bits and the too-general mp_random_in_range. Now you can generate a value between 0 and n without having to either make n a power of 2, or tediously allocate a zero mp_int to be the lower limit for mp_random_in_range. Implementation is done by sawing the existing mp_random_in_range into two pieces and exposing the API between them.
This commit is contained in:
21
mpint.c
21
mpint.c
@ -2423,10 +2423,8 @@ mp_int *mp_random_bits_fn(size_t bits, random_read_fn_t random_read)
|
||||
return toret;
|
||||
}
|
||||
|
||||
mp_int *mp_random_in_range_fn(mp_int *lo, mp_int *hi, random_read_fn_t rf)
|
||||
mp_int *mp_random_upto_fn(mp_int *limit, random_read_fn_t rf)
|
||||
{
|
||||
mp_int *n_outcomes = mp_sub(hi, lo);
|
||||
|
||||
/*
|
||||
* It would be nice to generate our random numbers in such a way
|
||||
* as to make every possible outcome literally equiprobable. But
|
||||
@ -2436,10 +2434,19 @@ mp_int *mp_random_in_range_fn(mp_int *lo, mp_int *hi, random_read_fn_t rf)
|
||||
* is acceptable on the grounds that you'd have to examine so many
|
||||
* outputs to even detect it.
|
||||
*/
|
||||
mp_int *unreduced = mp_random_bits_fn(mp_max_bits(n_outcomes) + 128, rf);
|
||||
mp_int *reduced = mp_mod(unreduced, n_outcomes);
|
||||
mp_add_into(reduced, reduced, lo);
|
||||
mp_int *unreduced = mp_random_bits_fn(mp_max_bits(limit) + 128, rf);
|
||||
mp_int *reduced = mp_mod(unreduced, limit);
|
||||
mp_free(unreduced);
|
||||
mp_free(n_outcomes);
|
||||
return reduced;
|
||||
}
|
||||
|
||||
mp_int *mp_random_in_range_fn(mp_int *lo, mp_int *hi, random_read_fn_t rf)
|
||||
{
|
||||
mp_int *n_outcomes = mp_sub(hi, lo);
|
||||
mp_int *addend = mp_random_upto_fn(n_outcomes, rf);
|
||||
mp_int *result = mp_make_sized(hi->nw);
|
||||
mp_add_into(result, addend, lo);
|
||||
mp_free(addend);
|
||||
mp_free(n_outcomes);
|
||||
return result;
|
||||
}
|
||||
|
Reference in New Issue
Block a user