mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-06-30 19:12:48 -05:00
Replace random_byte() with random_read().
This is in preparation for a PRNG revamp which will want to have a well defined boundary for any given request-for-randomness, so that it can destroy the evidence afterwards. So no more looping round calling random_byte() and then stopping when we feel like it: now you say up front how many random bytes you want, and call random_read() which gives you that many in one go. Most of the call sites that had to be fixed are fairly mechanical, and quite a few ended up more concise afterwards. A few became more cumbersome, such as mp_random_bits, in which the new API doesn't let me load the random bytes directly into the target integer without triggering undefined behaviour, so instead I have to allocate a separate temporary buffer. The _most_ interesting call site was in the PKCS#1 v1.5 padding code in sshrsa.c (used in SSH-1), in which you need a stream of _nonzero_ random bytes. The previous code just looped on random_byte, retrying if it got a zero. Now I'm doing a much more interesting thing with an mpint, essentially scaling a binary fraction repeatedly to extract a number in the range [0,255) and then adding 1 to it.
This commit is contained in:
24
mpint.c
24
mpint.c
@ -2302,21 +2302,20 @@ mp_int *monty_modsqrt(ModsqrtContext *sc, mp_int *x, unsigned *success)
|
||||
return toret;
|
||||
}
|
||||
|
||||
mp_int *mp_random_bits_fn(size_t bits, int (*gen_byte)(void))
|
||||
mp_int *mp_random_bits_fn(size_t bits, random_read_fn_t random_read)
|
||||
{
|
||||
size_t bytes = (bits + 7) / 8;
|
||||
size_t words = (bits + BIGNUM_INT_BITS - 1) / BIGNUM_INT_BITS;
|
||||
mp_int *x = mp_make_sized(words);
|
||||
for (size_t i = 0; i < bytes; i++) {
|
||||
BignumInt byte = gen_byte();
|
||||
unsigned mask = (1 << size_t_min(8, bits-i*8)) - 1;
|
||||
x->w[i / BIGNUM_INT_BYTES] |=
|
||||
(byte & mask) << (8*(i % BIGNUM_INT_BYTES));
|
||||
}
|
||||
return x;
|
||||
uint8_t *randbuf = snewn(bytes, uint8_t);
|
||||
random_read(randbuf, bytes);
|
||||
if (bytes)
|
||||
randbuf[0] &= (2 << ((bits-1) & 7)) - 1;
|
||||
mp_int *toret = mp_from_bytes_be(make_ptrlen(randbuf, bytes));
|
||||
smemclr(randbuf, bytes);
|
||||
sfree(randbuf);
|
||||
return toret;
|
||||
}
|
||||
|
||||
mp_int *mp_random_in_range_fn(mp_int *lo, mp_int *hi, int (*gen_byte)(void))
|
||||
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);
|
||||
|
||||
@ -2329,8 +2328,7 @@ mp_int *mp_random_in_range_fn(mp_int *lo, mp_int *hi, int (*gen_byte)(void))
|
||||
* 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, gen_byte);
|
||||
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_free(unreduced);
|
||||
|
Reference in New Issue
Block a user