diff --git a/mpint.c b/mpint.c index 8ac7a50e..6113d179 100644 --- a/mpint.c +++ b/mpint.c @@ -869,11 +869,12 @@ unsigned mp_cmp_hs(mp_int *a, mp_int *b) unsigned mp_hs_integer(mp_int *x, uintmax_t n) { BignumInt carry = 1; - for (size_t i = 0; i < x->nw; i++) { + size_t nwords = sizeof(n)/BIGNUM_INT_BYTES; + for (size_t i = 0, e = size_t_max(x->nw, nwords); i < e; i++) { BignumInt nword = n; n = shift_right_by_one_word(n); BignumInt dummy_out; - BignumADC(dummy_out, carry, x->w[i], ~nword, carry); + BignumADC(dummy_out, carry, mp_word(x, i), ~nword, carry); (void)dummy_out; } return carry; @@ -895,10 +896,11 @@ unsigned mp_cmp_eq(mp_int *a, mp_int *b) unsigned mp_eq_integer(mp_int *x, uintmax_t n) { BignumInt diff = 0; - for (size_t i = 0; i < x->nw; i++) { + size_t nwords = sizeof(n)/BIGNUM_INT_BYTES; + for (size_t i = 0, e = size_t_max(x->nw, nwords); i < e; i++) { BignumInt nword = n; n = shift_right_by_one_word(n); - diff |= x->w[i] ^ nword; + diff |= mp_word(x, i) ^ nword; } return 1 ^ normalise_to_1(diff); /* return 1 if diff _is_ zero */ } diff --git a/test/cryptsuite.py b/test/cryptsuite.py index 995110b0..5564c11f 100755 --- a/test/cryptsuite.py +++ b/test/cryptsuite.py @@ -252,6 +252,19 @@ class mpint(MyTestBase): mp_max_into(am_big, am, bm) self.assertEqual(int(am_big), max(ai, bi)) + # Test mp_{eq,hs}_integer in the case where the integer is as + # large as possible and the bignum contains very few words. In + # modes where BIGNUM_INT_BITS < 64, this used to go wrong. + mp10 = mp_new(4) + mp_add_integer_into(mp10, mp10, 10) + highbit = 1 << 63 + self.assertEqual(mp_hs_integer(mp10, highbit | 9), 0) + self.assertEqual(mp_hs_integer(mp10, highbit | 10), 0) + self.assertEqual(mp_hs_integer(mp10, highbit | 11), 0) + self.assertEqual(mp_eq_integer(mp10, highbit | 9), 0) + self.assertEqual(mp_eq_integer(mp10, highbit | 10), 0) + self.assertEqual(mp_eq_integer(mp10, highbit | 11), 0) + def testConditionals(self): testnumbers = [(mp_copy(n),n) for n in fibonacci_scattered()] for am, ai in testnumbers: