From: jsing Date: Tue, 14 Feb 2023 18:06:06 +0000 (+0000) Subject: Reimplement BN_num_bits_word(). X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=553747b429101252f4601d165bea0319b2586a33;p=openbsd Reimplement BN_num_bits_word(). Provide a simpler and more readable bn_word_clz() function that returns the number of leading zeros for a given BN_ULONG, then implement BN_num_bits_word() using bn_word_clz(). This is a hot path and bn_word_clz() can now be replaced with architecture specific versions where possible. ok tb@ --- diff --git a/lib/libcrypto/bn/bn_lib.c b/lib/libcrypto/bn/bn_lib.c index 32ac7ae606e..b792250fbcd 100644 --- a/lib/libcrypto/bn/bn_lib.c +++ b/lib/libcrypto/bn/bn_lib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bn_lib.c,v 1.74 2023/02/14 18:01:15 jsing Exp $ */ +/* $OpenBSD: bn_lib.c,v 1.75 2023/02/14 18:06:06 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -220,26 +220,31 @@ BN_value_one(void) return (&const_one); } +#ifndef HAVE_BN_WORD_CLZ int -BN_num_bits_word(BN_ULONG l) -{ - BN_ULONG x, mask; - int bits; - unsigned int shift; - - /* Constant time calculation of floor(log2(l)) + 1. */ - bits = (l != 0); - shift = BN_BITS4; /* On _LP64 this is 32, otherwise 16. */ - do { - x = l >> shift; - /* If x is 0, set mask to 0, otherwise set it to all 1s. */ - mask = ((~x & (x - 1)) >> (BN_BITS2 - 1)) - 1; - bits += shift & mask; - /* If x is 0, leave l alone, otherwise set l = x. */ - l ^= (x ^ l) & mask; - } while ((shift /= 2) != 0); - - return bits; +bn_word_clz(BN_ULONG w) +{ + BN_ULONG bits, mask, shift; + + bits = shift = BN_BITS2; + mask = 0; + + while ((shift >>= 1) != 0) { + bits += (shift & mask) - (shift & ~mask); + mask = bn_ct_ne_zero_mask(w >> bits); + } + bits += 1 & mask; + + bits -= bn_ct_eq_zero(w); + + return BN_BITS2 - bits; +} +#endif + +int +BN_num_bits_word(BN_ULONG w) +{ + return BN_BITS2 - bn_word_clz(w); } int