mirror of
https://github.com/itzmeanjan/ml-kem.git
synced 2026-01-09 23:57:56 -05:00
update tests ensuring functional correctness of Kyber and its components
Signed-off-by: Anjan Roy <hello@itzmeanjan.in>
This commit is contained in:
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user