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:
parent
a0211f2b27
commit
b0e8e6c2eb
2 changed files with 53 additions and 14 deletions
|
|
@ -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
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -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
|
||||
//
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue