diff --git a/src/modules/bulletproofs/bulletproofs_util.h b/src/modules/bulletproofs/bulletproofs_util.h index 20d1c748..2bdae23f 100644 --- a/src/modules/bulletproofs/bulletproofs_util.h +++ b/src/modules/bulletproofs/bulletproofs_util.h @@ -39,4 +39,17 @@ static void secp256k1_bulletproofs_le64(unsigned char *output, const uint64_t n) output[7] = n >> 56; } +/* Check if n is power of two*/ +static int secp256k1_is_power_of_two(size_t n) { + return n > 0 && (n & (n - 1)) == 0; +} + +/* Compute the log2 of n. If n is not a power of two, it returns the largest + * `k` such that 2^k <= n. Assumes n < 2^64. In Bulletproofs, this is bounded + * by len of input vectors which can be safely assumed to be less than 2^64. +*/ +static size_t secp256k1_bulletproofs_pp_log2(size_t n) { + return 64 - 1 - secp256k1_clz64_var((uint64_t)n); +} + #endif diff --git a/src/modules/bulletproofs/tests_impl.h b/src/modules/bulletproofs/tests_impl.h index 930b35af..bec7c84f 100644 --- a/src/modules/bulletproofs/tests_impl.h +++ b/src/modules/bulletproofs/tests_impl.h @@ -7,6 +7,10 @@ #ifndef _SECP256K1_MODULE_BULLETPROOFS_TEST_ #define _SECP256K1_MODULE_BULLETPROOFS_TEST_ +#include + +#include "include/secp256k1_bulletproofs.h" +#include "bulletproofs_util.h" #include "bulletproofs_pp_transcript_impl.h" static void test_bulletproofs_generators_api(void) { @@ -130,7 +134,23 @@ static void test_bulletproofs_pp_tagged_hash(void) { CHECK(secp256k1_memcmp_var(output, output_cached, 32) == 0); } +void test_log_exp(void) { + CHECK(secp256k1_is_power_of_two(0) == 0); + CHECK(secp256k1_is_power_of_two(1) == 1); + CHECK(secp256k1_is_power_of_two(2) == 1); + CHECK(secp256k1_is_power_of_two(64) == 1); + CHECK(secp256k1_is_power_of_two(63) == 0); + CHECK(secp256k1_is_power_of_two(256) == 1); + + CHECK(secp256k1_bulletproofs_pp_log2(1) == 0); + CHECK(secp256k1_bulletproofs_pp_log2(2) == 1); + CHECK(secp256k1_bulletproofs_pp_log2(255) == 7); + CHECK(secp256k1_bulletproofs_pp_log2(256) == 8); + CHECK(secp256k1_bulletproofs_pp_log2(257) == 8); +} + void run_bulletproofs_tests(void) { + test_log_exp(); test_bulletproofs_generators_api(); test_bulletproofs_generators_fixed(); test_bulletproofs_pp_tagged_hash();