mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 09:27:59 +00:00
mp_divmod_into: don't confuse uint64_t with BignumInt.
A major advantage of the new testcrypt system _not_ being written as a native-code Python module in the usual way is that it makes it very easy to recompile testcrypt in a non-default way, such as with -m32, and still run the same tests via the same Python module. But I hadn't actually _done_ that until now, and now that I do, the test suite has picked up a couple of bugs. When computing the initial reciprocal approximation in mp_divmod_into, I did a lot of work on explicit uint64_t, but did it in a way that used BIGNUM_INT_BITS as the number's bit size instead of the constant 64, and cast several things absentmindedly to BignumInt. And because I'd only tested on a platform where those are the same type anyway, I didn't spot it.
This commit is contained in:
parent
8e399f9aa7
commit
8024b55ea6
22
mpint.c
22
mpint.c
@ -270,6 +270,12 @@ static inline unsigned normalise_to_1(BignumInt n)
|
||||
n = (-n) >> (BIGNUM_INT_BITS - 1); /* normalise to 0 or 1 */
|
||||
return n;
|
||||
}
|
||||
static inline unsigned normalise_to_1_u64(uint64_t n)
|
||||
{
|
||||
n = (n >> 1) | (n & 1); /* ensure top bit is clear */
|
||||
n = (-n) >> 63; /* normalise to 0 or 1 */
|
||||
return n;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the highest nonzero word in a number. Returns the index of the
|
||||
@ -1822,10 +1828,10 @@ void mp_divmod_into(mp_int *n, mp_int *d, mp_int *q_out, mp_int *r_out)
|
||||
size_t shift_up = 0;
|
||||
for (size_t i = BIGNUM_INT_BITS_BITS; i-- > 0;) {
|
||||
size_t sl = 1 << i; /* left shift count */
|
||||
size_t sr = BIGNUM_INT_BITS - sl; /* complementary right-shift count */
|
||||
size_t sr = 64 - sl; /* complementary right-shift count */
|
||||
|
||||
/* Should we shift up? */
|
||||
unsigned indicator = 1 ^ normalise_to_1(hibits >> sr);
|
||||
unsigned indicator = 1 ^ normalise_to_1_u64(hibits >> sr);
|
||||
|
||||
/* If we do, what will we get? */
|
||||
uint64_t new_hibits = (hibits << sl) | (lobits >> sr);
|
||||
@ -1833,9 +1839,9 @@ void mp_divmod_into(mp_int *n, mp_int *d, mp_int *q_out, mp_int *r_out)
|
||||
size_t new_shift_up = shift_up + sl;
|
||||
|
||||
/* Conditionally swap those values in. */
|
||||
hibits ^= (hibits ^ new_hibits ) & -(BignumInt)indicator;
|
||||
lobits ^= (lobits ^ new_lobits ) & -(BignumInt)indicator;
|
||||
shift_up ^= (shift_up ^ new_shift_up ) & -(size_t) indicator;
|
||||
hibits ^= (hibits ^ new_hibits ) & -(uint64_t)indicator;
|
||||
lobits ^= (lobits ^ new_lobits ) & -(uint64_t)indicator;
|
||||
shift_up ^= (shift_up ^ new_shift_up ) & -(size_t) indicator;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1860,7 +1866,7 @@ void mp_divmod_into(mp_int *n, mp_int *d, mp_int *q_out, mp_int *r_out)
|
||||
*/
|
||||
for (size_t i = BIGNUM_INT_BITS_BITS; i-- > 0;) {
|
||||
size_t sl = 1 << i; /* left shift count */
|
||||
size_t sr = BIGNUM_INT_BITS - sl; /* complementary right-shift count */
|
||||
size_t sr = 64 - sl; /* complementary right-shift count */
|
||||
|
||||
/* Should we shift up? */
|
||||
unsigned indicator = 1 & (shift_up >> i);
|
||||
@ -1870,8 +1876,8 @@ void mp_divmod_into(mp_int *n, mp_int *d, mp_int *q_out, mp_int *r_out)
|
||||
uint64_t new_lobits = lobits << sl;
|
||||
|
||||
/* Conditionally swap those values in. */
|
||||
hibits ^= (hibits ^ new_hibits ) & -(BignumInt)indicator;
|
||||
lobits ^= (lobits ^ new_lobits ) & -(BignumInt)indicator;
|
||||
hibits ^= (hibits ^ new_hibits ) & -(uint64_t)indicator;
|
||||
lobits ^= (lobits ^ new_lobits ) & -(uint64_t)indicator;
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user