mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 17:38:00 +00:00
mpint_rshift_safe: stop using variable bit shifts.
I've decided not to trust register-controlled shift operations to be time-constant after all. They're surely fine on nice fast machines where everything simple takes one cycle, but stranger machines, perhaps not. In which case, I should avoid using them in the mpint shift operation that's supposed not to reveal the shift count.
This commit is contained in:
parent
ced0f19118
commit
c9f673ac12
30
mpint.c
30
mpint.c
@ -1112,19 +1112,14 @@ mp_int *mp_rshift_safe(mp_int *x, size_t bits)
|
||||
/*
|
||||
* That's done the shifting by words; now we do the shifting by
|
||||
* bits.
|
||||
*
|
||||
* I assume here that register-controlled right shifts are
|
||||
* time-constant. If they're not, I could replace this with
|
||||
* another loop over bit positions.
|
||||
*/
|
||||
size_t upshift = BIGNUM_INT_BITS - bitshift;
|
||||
size_t no_shift = (upshift >> BIGNUM_INT_BITS_BITS);
|
||||
upshift &= ~-(size_t)no_shift;
|
||||
BignumInt upshifted_mask = ~-(BignumInt)no_shift;
|
||||
|
||||
for (size_t i = 0; i < r->nw; i++) {
|
||||
r->w[i] = (r->w[i] >> bitshift) |
|
||||
((mp_word(r, i+1) << upshift) & upshifted_mask);
|
||||
for (unsigned bit = 0; bit < BIGNUM_INT_BITS_BITS; bit++) {
|
||||
unsigned shift = 1 << bit, upshift = BIGNUM_INT_BITS - shift;
|
||||
BignumInt mask = -(BignumInt)((bitshift >> bit) & 1);
|
||||
for (size_t i = 0; i < r->nw; i++) {
|
||||
BignumInt w = ((r->w[i] >> shift) | (mp_word(r, i+1) << upshift));
|
||||
r->w[i] ^= (r->w[i] ^ w) & mask;
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
@ -1863,12 +1858,11 @@ void mp_divmod_into(mp_int *n, mp_int *d, mp_int *q_out, mp_int *r_out)
|
||||
* actual input will be close to a fixed power of two regardless
|
||||
* of where the MSB was.
|
||||
*
|
||||
* I do this in another log n individual passes, not so much
|
||||
* because I'm worried about the time-invariance of the CPU's
|
||||
* register-controlled shift operation, but in case the compiler
|
||||
* code-generates uint64_t shifts out of a variable number of
|
||||
* smaller-word shift instructions, e.g. by splitting up into
|
||||
* cases.
|
||||
* I do this in another log n individual passes, partly in case
|
||||
* the CPU's register-controlled shift operation isn't
|
||||
* time-constant, and also in case the compiler code-generates
|
||||
* uint64_t shifts out of a variable number of smaller-word shift
|
||||
* instructions, e.g. by splitting up into cases.
|
||||
*/
|
||||
for (size_t i = BIGNUM_INT_BITS_BITS; i-- > 0;) {
|
||||
size_t sl = 1 << i; /* left shift count */
|
||||
|
Loading…
Reference in New Issue
Block a user