Skip to content

Commit d6ff738

Browse files
Ensure safety of ctz_debruijn implementation.
Adding U to the magic constants ensures that we are not mixing unsigned and signed value during multiplication, and ensures that the multiplication will not be subject to integer promotion. The (uint32_t)/(uint64_t) casts ensure the values are properly truncated no matter the size of an int. Prior to this commit, if secp256k1_ctz32_var_debruijn were some how managed to be built on a platform with 64-bit ints, (though this function is specifically only intended to be used on 32-bit platforms) it would perform an out-of-bounds array access.
1 parent a01a7d8 commit d6ff738

File tree

1 file changed

+2
-2
lines changed

1 file changed

+2
-2
lines changed

src/util.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ static SECP256K1_INLINE int secp256k1_ctz32_var_debruijn(uint32_t x) {
251251
0x10, 0x07, 0x0C, 0x1A, 0x1F, 0x17, 0x12, 0x05, 0x15, 0x09, 0x0F, 0x0B,
252252
0x1E, 0x11, 0x08, 0x0E, 0x1D, 0x0D, 0x1C, 0x1B
253253
};
254-
return debruijn[((x & -x) * 0x04D7651F) >> 27];
254+
return debruijn[(uint32_t)((x & -x) * 0x04D7651FU) >> 27];
255255
}
256256

257257
/* Determine the number of trailing zero bits in a (non-zero) 64-bit x.
@@ -264,7 +264,7 @@ static SECP256K1_INLINE int secp256k1_ctz64_var_debruijn(uint64_t x) {
264264
63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10,
265265
51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12
266266
};
267-
return debruijn[((x & -x) * 0x022FDD63CC95386D) >> 58];
267+
return debruijn[(uint64_t)((x & -x) * 0x022FDD63CC95386DU) >> 58];
268268
}
269269

270270
/* Determine the number of trailing zero bits in a (non-zero) 32-bit x. */

0 commit comments

Comments
 (0)