Simplify log_2_byte & add test (#109)

This commit is contained in:
Justin Traglia 2023-02-01 18:16:20 +01:00 committed by GitHub
parent 1e7353c435
commit e5fa8c7ee1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 36 additions and 14 deletions

View File

@ -220,20 +220,18 @@ static C_KZG_RET new_fr_array(fr_t **x, size_t n) {
/**
* Fast log base 2 of a byte.
*
* Corresponds to the index of the highest bit set in the byte. Adapted from
* https://graphics.stanford.edu/~seander/bithacks.html#IntegerLog.
*
* @param[in] b A non-zero byte
* @return The index of the highest set bit
*/
STATIC int log_2_byte(byte b) {
int r, shift;
r = (b > 0xF) << 2;
b >>= r;
shift = (b > 0x3) << 1;
b >>= (shift + 1);
r |= shift | b;
return r;
if (b < 2) return 0;
if (b < 4) return 1;
if (b < 8) return 2;
if (b < 16) return 3;
if (b < 32) return 4;
if (b < 64) return 5;
if (b < 128) return 6;
return 7;
}
/**
@ -242,8 +240,6 @@ STATIC int log_2_byte(byte b) {
* @param p The field element to be checked
* @retval true The element is one
* @retval false The element is not one
*
* @todo See if there is a more efficient way to check for one in the finite field.
*/
static bool fr_is_one(const fr_t *p) {
uint64_t a[4];
@ -535,8 +531,6 @@ static bool is_power_of_two(uint64_t n) {
*
* @param a A byte
* @return A byte that is bit-reversed with respect to @p a
*
* @todo Benchmark some of the other bit-reversal options in the list. Maybe.
*/
#define rev_byte(a) ((((a)&0xff) * 0x0202020202ULL & 0x010884422010ULL) % 1023)

View File

@ -136,6 +136,7 @@ C_KZG_RET evaluate_polynomial_in_evaluation_form(fr_t *out, const Polynomial *p,
C_KZG_RET blob_to_polynomial(Polynomial *p, const Blob *blob);
C_KZG_RET bytes_to_bls_field(fr_t *out, const Bytes32 *b);
uint32_t reverse_bits(uint32_t a);
int log_2_byte(byte b);
#endif

View File

@ -412,6 +412,32 @@ static void test_reverse_bits__all_bits_are_one(void) {
ASSERT_EQUALS(reverse_bits(original), reversed);
}
///////////////////////////////////////////////////////////////////////////////
// Tests for log_2_byte
///////////////////////////////////////////////////////////////////////////////
static void test_log_2_byte__expected_values(void) {
byte i = 0;
while (true) {
/*
* Corresponds to the index of the highest bit set in the byte.
* Adapted from https://graphics.stanford.edu/~seander/bithacks.html#IntegerLog.
*/
byte b = i;
int r, shift;
r = (b > 0xF) << 2;
b >>= r;
shift = (b > 0x3) << 1;
b >>= (shift + 1);
r |= shift | b;
ASSERT_EQUALS(r, log_2_byte(i));
if (i == 255) break;
i += 1;
}
}
///////////////////////////////////////////////////////////////////////////////
// Tests for compute_kzg_proof
///////////////////////////////////////////////////////////////////////////////
@ -505,6 +531,7 @@ int main(void) {
RUN(test_reverse_bits__all_bits_are_zero);
RUN(test_reverse_bits__some_bits_are_one);
RUN(test_reverse_bits__all_bits_are_one);
RUN(test_log_2_byte__expected_values);
RUN(test_compute_and_verify_kzg_proof);
teardown();