From b0e8e6c2eb2611060add7b3c566c267f25de2286 Mon Sep 17 00:00:00 2001 From: sowle Date: Fri, 15 Apr 2022 21:29:08 +0200 Subject: [PATCH] crypto: scalar_t: get_bit, set_bit, clear_bit, power_of_2 implemented; crypto_sc_set_bit_clear_bit test added --- src/crypto/crypto-sugar.h | 24 ++++++++++++-- tests/functional_tests/crypto_tests.cpp | 43 ++++++++++++++++++------- 2 files changed, 53 insertions(+), 14 deletions(-) diff --git a/src/crypto/crypto-sugar.h b/src/crypto/crypto-sugar.h index d1928a92..a2681642 100644 --- a/src/crypto/crypto-sugar.h +++ b/src/crypto/crypto-sugar.h @@ -431,13 +431,31 @@ namespace crypto return result; } - bool get_bit(size_t bit_index) const + // Little-endian assumed; TODO: consider Big-endian support + bool get_bit(uint8_t bit_index) const { - if (bit_index > 255) - return false; // TODO: consider performace implications return (m_u64[bit_index >> 6] & (1ull << (bit_index & 63))) != 0; } + // Little-endian assumed; TODO: consider Big-endian support + void set_bit(size_t bit_index) + { + m_u64[bit_index >> 6] |= (1ull << (bit_index & 63)); + } + + // Little-endian assumed; TODO: consider Big-endian support + void clear_bit(size_t bit_index) + { + m_u64[bit_index >> 6] &= ~(1ull << (bit_index & 63)); + } + + static scalar_t power_of_2(uint8_t exponent) + { + scalar_t result = 0; + result.set_bit(exponent); + return result; + } + }; // struct scalar_t // diff --git a/tests/functional_tests/crypto_tests.cpp b/tests/functional_tests/crypto_tests.cpp index c15d3869..e4e0c63e 100644 --- a/tests/functional_tests/crypto_tests.cpp +++ b/tests/functional_tests/crypto_tests.cpp @@ -1812,40 +1812,61 @@ TEST(crypto, sc_get_bit) scalar_t v = 0; // all bits are 0 for (size_t n = 0; n < 256; ++n) { - ASSERT_EQ(v.get_bit(n), false); + ASSERT_EQ(v.get_bit(static_cast(n)), false); } v = c_scalar_256m1; // all bits are 1 for (size_t n = 0; n < 256; ++n) { - ASSERT_EQ(v.get_bit(n), true); + ASSERT_EQ(v.get_bit(static_cast(n)), true); } // bits out of the [0; 255] range supposed to be always 0 for (size_t n = 256; n < 2048; ++n) { - ASSERT_EQ(v.get_bit(n), false); + ASSERT_EQ(v.get_bit(static_cast(n)), false); } // check random value const scalar_t x = scalar_t::random(); for (size_t n = 0; n < 64; ++n) - ASSERT_EQ(x.get_bit(n), ((x.m_u64[0] & (1ull << (n - 0))) != 0)); + ASSERT_EQ(x.get_bit(static_cast(n)), ((x.m_u64[0] & (1ull << (n - 0))) != 0)); for (size_t n = 64; n < 128; ++n) - ASSERT_EQ(x.get_bit(n), ((x.m_u64[1] & (1ull << (n - 64))) != 0)); + ASSERT_EQ(x.get_bit(static_cast(n)), ((x.m_u64[1] & (1ull << (n - 64))) != 0)); for (size_t n = 128; n < 192; ++n) - ASSERT_EQ(x.get_bit(n), ((x.m_u64[2] & (1ull << (n - 128))) != 0)); + ASSERT_EQ(x.get_bit(static_cast(n)), ((x.m_u64[2] & (1ull << (n - 128))) != 0)); for (size_t n = 192; n < 256; ++n) - ASSERT_EQ(x.get_bit(n), ((x.m_u64[3] & (1ull << (n - 192))) != 0)); - - // bits out of the [0; 255] range supposed to be always 0 - for (size_t n = 256; n < 2048; ++n) - ASSERT_EQ(x.get_bit(n), false); + ASSERT_EQ(x.get_bit(static_cast(n)), ((x.m_u64[3] & (1ull << (n - 192))) != 0)); return true; } +TEST(crypto, sc_set_bit_clear_bit) +{ + static_assert(sizeof(scalar_t) * 8 == 256, "size missmatch"); + + // check random value + const scalar_t x = scalar_t::random(); + scalar_t y = scalar_t::random(); + ASSERT_NEQ(x, y); + + uint8_t i = 0; + do + { + if (x.get_bit(i)) + y.set_bit(i); + else + y.clear_bit(i); + } while(++i != 0); + + ASSERT_EQ(x, y); + + return true; +} + + + // // test's runner //