update tests ensuring functional correctness of Kyber and its components

Signed-off-by: Anjan Roy <hello@itzmeanjan.in>
This commit is contained in:
Anjan Roy
2023-03-09 18:53:45 +04:00
parent 5e54d6f615
commit 48b2d1b882
5 changed files with 19 additions and 63 deletions

View File

@@ -22,17 +22,20 @@ test_compression()
prng::prng_t prng;
for (size_t i = 0; i < cnt; i++) {
const auto a = ff::ff_t::random(prng);
const auto a = field::zq_t::random(prng);
const auto b = kyber_utils::compress<d>(a);
const auto c = kyber_utils::decompress<d>(b);
const uint16_t br0[]{ static_cast<uint16_t>(ff::Q - c.v), c.v };
const bool flg0 = c.v <= (ff::Q >> 1);
const auto a_canon = a.to_canonical();
const auto c_canon = c.to_canonical();
const uint32_t br0[]{ static_cast<uint16_t>(field::Q - c_canon), c_canon };
const bool flg0 = c_canon <= (field::Q >> 1);
const auto c_prime = static_cast<int32_t>(br0[flg0]);
const uint16_t br1[]{ static_cast<uint16_t>(ff::Q - a.v), a.v };
const bool flg1 = a.v <= (ff::Q >> 1);
const uint32_t br1[]{ static_cast<uint16_t>(field::Q - a_canon), a_canon };
const bool flg1 = a_canon <= (field::Q >> 1);
const auto a_prime = static_cast<int32_t>(br1[flg1]);
const size_t err = static_cast<size_t>(std::abs(c_prime - a_prime));

View File

@@ -5,57 +5,11 @@
// Test functional correctness of Kyber PQC suite implementation
namespace test_kyber {
// Test functional correctness of Kyber prime field operations, by running
// through multiple rounds of execution of field operations on randomly
// sampled field elements
inline void
test_field_ops()
{
constexpr size_t itr_cnt = 1ul << 10;
prng::prng_t prng;
for (size_t i = 0; i < itr_cnt; i++) {
const auto a = ff::ff_t::random(prng);
const auto b = ff::ff_t::random(prng);
// addition, subtraction, negation
const auto c = a - b;
const auto d = -b;
const auto e = a + d;
assert(c == e);
// multiplication, division, inversion
const auto f = a * b;
const auto g = f / b;
if (b == ff::ff_t::zero()) {
assert(g == ff::ff_t::zero());
} else {
assert(g == a);
}
// exponentiation, multiplication
size_t exp = 0;
prng.read(reinterpret_cast<uint8_t*>(&exp), sizeof(exp));
exp >>= 48;
const auto h = a ^ exp;
auto res = ff::ff_t::one();
for (size_t j = 0; j < exp; j++) {
res = res * a;
}
assert(res == h);
}
}
// Test functional correctness of Kyber prime field operations ( using
// Montgomery Arithmetic ), by running through multiple rounds of execution of
// field operations on randomly sampled field elements
inline void
test_mont_field_ops()
test_field_ops()
{
constexpr size_t itr_cnt = 1ul << 10;
prng::prng_t prng;

View File

@@ -16,15 +16,15 @@ namespace test_kyber {
inline void
test_ntt_intt()
{
constexpr size_t poly_len = sizeof(ff::ff_t) * ntt::N;
constexpr size_t poly_len = sizeof(field::zq_t) * ntt::N;
ff::ff_t* poly_a = static_cast<ff::ff_t*>(std::malloc(poly_len));
ff::ff_t* poly_b = static_cast<ff::ff_t*>(std::malloc(poly_len));
field::zq_t* poly_a = static_cast<field::zq_t*>(std::malloc(poly_len));
field::zq_t* poly_b = static_cast<field::zq_t*>(std::malloc(poly_len));
prng::prng_t prng;
for (size_t i = 0; i < ntt::N; i++) {
poly_a[i] = ff::ff_t::random(prng);
poly_a[i] = field::zq_t::random(prng);
}
std::memcpy(poly_b, poly_a, poly_len);

View File

@@ -15,25 +15,25 @@ template<const size_t l>
void
test_serialization()
{
constexpr size_t plen = sizeof(ff::ff_t) * ntt::N;
constexpr size_t plen = sizeof(field::zq_t) * ntt::N;
constexpr size_t blen = 32 * l;
constexpr uint16_t mask = (1u << l) - 1u;
constexpr uint32_t mask = (1u << l) - 1u;
ff::ff_t* src = static_cast<ff::ff_t*>(std::malloc(plen));
field::zq_t* src = static_cast<field::zq_t*>(std::malloc(plen));
uint8_t* arr = static_cast<uint8_t*>(std::malloc(blen));
ff::ff_t* dst = static_cast<ff::ff_t*>(std::malloc(plen));
field::zq_t* dst = static_cast<field::zq_t*>(std::malloc(plen));
prng::prng_t prng;
for (size_t i = 0; i < ntt::N; i++) {
src[i] = ff::ff_t::random(prng);
src[i] = field::zq_t::random(prng);
}
kyber_utils::encode<l>(src, arr);
kyber_utils::decode<l>(arr, dst);
for (size_t i = 0; i < ntt::N; i++) {
assert((src[i].v & mask) == (dst[i].v & mask));
assert((src[i].to_canonical() & mask) == (dst[i].to_canonical() & mask));
}
std::free(src);

View File

@@ -5,7 +5,6 @@ int
main()
{
test_kyber::test_field_ops();
test_kyber::test_mont_field_ops();
std::cout << "[test] Kyber prime field operations" << std::endl;
test_kyber::test_ntt_intt();