From b9ccb10287dd21433ece375ced5b4f3d910a9f50 Mon Sep 17 00:00:00 2001 From: sowle Date: Sat, 9 Apr 2022 21:12:44 +0200 Subject: [PATCH] crypto: scalar_t::git_bit + test crypto_sc_get_bit; hash_helper_t extended with hp variants --- src/crypto/crypto-sugar.h | 22 ++++++++++++++ tests/functional_tests/crypto_tests.cpp | 40 +++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/src/crypto/crypto-sugar.h b/src/crypto/crypto-sugar.h index 5542b9fb..e5ce7b9b 100644 --- a/src/crypto/crypto-sugar.h +++ b/src/crypto/crypto-sugar.h @@ -431,6 +431,13 @@ namespace crypto return result; } + bool get_bit(size_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; + } + }; // struct scalar_t // @@ -1063,6 +1070,21 @@ namespace crypto ge_bytes_hash_to_ec_32(&result.m_p3, (const unsigned char*)&p); return result; } + + static point_t hp(const scalar_t& s) + { + point_t result; + ge_bytes_hash_to_ec_32(&result.m_p3, s.data()); + return result; + } + + static point_t hp(const void* data, size_t size) + { + point_t result; + ge_bytes_hash_to_ec(&result.m_p3, data, size); + return result; + } + }; // hash_helper_t struct diff --git a/tests/functional_tests/crypto_tests.cpp b/tests/functional_tests/crypto_tests.cpp index 83c94b8b..19c922e2 100644 --- a/tests/functional_tests/crypto_tests.cpp +++ b/tests/functional_tests/crypto_tests.cpp @@ -1803,6 +1803,46 @@ TEST(crypto, point_is_zero) } +TEST(crypto, sc_get_bit) +{ + static_assert(sizeof(scalar_t) * 8 == 256, "size missmatch"); + + scalar_t v = 0; // all bits are 0 + for (size_t n = 0; n < 256; ++n) + { + ASSERT_EQ(v.get_bit(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); + } + + // 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); + } + + // 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)); + for (size_t n = 64; n < 128; ++n) + ASSERT_EQ(x.get_bit(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)); + 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); + + return true; +} + // // test's runner //