diff --git a/src/scalar_4x64_impl.h b/src/scalar_4x64_impl.h index a5bf18feb9..b914136d5e 100644 --- a/src/scalar_4x64_impl.h +++ b/src/scalar_4x64_impl.h @@ -41,7 +41,8 @@ SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsig SECP256K1_INLINE static uint32_t secp256k1_scalar_get_bits_limb32(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { SECP256K1_SCALAR_VERIFY(a); VERIFY_CHECK(count > 0 && count <= 32); - VERIFY_CHECK((offset + count - 1) >> 6 == offset >> 6); + VERIFY_CHECK(offset <= 256 - count); + VERIFY_CHECK((offset + count - 1) >> 5 == offset >> 5); return (a->d[offset >> 6] >> (offset & 0x3F)) & (0xFFFFFFFF >> (32 - count)); } @@ -49,12 +50,13 @@ SECP256K1_INLINE static uint32_t secp256k1_scalar_get_bits_limb32(const secp256k SECP256K1_INLINE static uint32_t secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { SECP256K1_SCALAR_VERIFY(a); VERIFY_CHECK(count > 0 && count <= 32); - VERIFY_CHECK(offset + count <= 256); + VERIFY_CHECK(offset <= 256 - count); if ((offset + count - 1) >> 6 == offset >> 6) { - return secp256k1_scalar_get_bits_limb32(a, offset, count); + return (a->d[offset >> 6] >> (offset & 0x3F)) & (0xFFFFFFFF >> (32 - count)); } else { VERIFY_CHECK((offset >> 6) + 1 < 4); + VERIFY_CHECK((offset & 0x3F) > 0); return ((a->d[offset >> 6] >> (offset & 0x3F)) | (a->d[(offset >> 6) + 1] << (64 - (offset & 0x3F)))) & (0xFFFFFFFF >> (32 - count)); } } diff --git a/src/scalar_8x32_impl.h b/src/scalar_8x32_impl.h index aa87b1d3d1..055918ca37 100644 --- a/src/scalar_8x32_impl.h +++ b/src/scalar_8x32_impl.h @@ -54,6 +54,7 @@ SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsig SECP256K1_INLINE static uint32_t secp256k1_scalar_get_bits_limb32(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { SECP256K1_SCALAR_VERIFY(a); VERIFY_CHECK(count > 0 && count <= 32); + VERIFY_CHECK(offset <= 256 - count); VERIFY_CHECK((offset + count - 1) >> 5 == offset >> 5); return (a->d[offset >> 5] >> (offset & 0x1F)) & (0xFFFFFFFF >> (32 - count)); @@ -62,7 +63,7 @@ SECP256K1_INLINE static uint32_t secp256k1_scalar_get_bits_limb32(const secp256k SECP256K1_INLINE static uint32_t secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { SECP256K1_SCALAR_VERIFY(a); VERIFY_CHECK(count > 0 && count <= 32); - VERIFY_CHECK(offset + count <= 256); + VERIFY_CHECK(offset <= 256 - count); if ((offset + count - 1) >> 5 == offset >> 5) { return secp256k1_scalar_get_bits_limb32(a, offset, count); diff --git a/src/scalar_low_impl.h b/src/scalar_low_impl.h index 628bfd33e8..164cda447b 100644 --- a/src/scalar_low_impl.h +++ b/src/scalar_low_impl.h @@ -27,8 +27,10 @@ SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsig SECP256K1_INLINE static uint32_t secp256k1_scalar_get_bits_limb32(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { SECP256K1_SCALAR_VERIFY(a); - VERIFY_CHECK(count > 0 && count <= 32); + VERIFY_CHECK(offset <= 256 - count); + VERIFY_CHECK((offset + count - 1) >> 5 == offset >> 5); + if (offset < 32) { return (*a >> offset) & (0xFFFFFFFF >> (32 - count)); } else { @@ -38,8 +40,14 @@ SECP256K1_INLINE static uint32_t secp256k1_scalar_get_bits_limb32(const secp256k SECP256K1_INLINE static uint32_t secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { SECP256K1_SCALAR_VERIFY(a); + VERIFY_CHECK(count > 0 && count <= 32); + VERIFY_CHECK(offset <= 256 - count); - return secp256k1_scalar_get_bits_limb32(a, offset, count); + if (offset < 32) { + return (*a >> offset) & (0xFFFFFFFF >> (32 - count)); + } else { + return 0; + } } SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scalar *a) { return *a >= EXHAUSTIVE_TEST_ORDER; }