1
0
Fork 0
forked from lthn/blockchain

crypto: scalar_t: get_bit, set_bit, clear_bit, power_of_2 implemented; crypto_sc_set_bit_clear_bit test added

This commit is contained in:
sowle 2022-04-15 21:29:08 +02:00
parent a0211f2b27
commit b0e8e6c2eb
No known key found for this signature in database
GPG key ID: C07A24B2D89D49FC
2 changed files with 53 additions and 14 deletions

View file

@ -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
//

View file

@ -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<uint8_t>(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<uint8_t>(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<uint8_t>(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<uint8_t>(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<uint8_t>(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<uint8_t>(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<uint8_t>(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
//