libdpf/test/tests/prg_lowmc_test.cpp

130 lines
3.6 KiB
C++
Raw Permalink Normal View History

#include <gtest/gtest.h>
#include <cstdint>
#include <cstring>
#include "dpf.hpp"
#include "simde/simde/x86/avx2.h"
namespace
{
bool blocks_equal(simde__m128i a, simde__m128i b)
{
return simde_mm_movemask_epi8(simde_mm_cmpeq_epi8(a, b)) == 0xFFFF;
}
simde__m128i block_from_lanes(std::uint64_t lo, std::uint64_t hi)
{
simde__m128i x;
std::uint64_t lane[2] = {lo, hi};
std::memcpy(&x, lane, sizeof(x));
return x;
}
} // namespace
TEST(LowmcPrg, EncryptDecryptRoundtrip)
{
lowmc::LowMC cipher;
lowmc::block plain = 0;
plain[0] = 1;
plain[127] = 1;
plain[64] = 1;
lowmc::block ciphered = cipher.encrypt(plain);
EXPECT_TRUE(cipher.decrypt(ciphered) == plain);
EXPECT_TRUE(ciphered != plain);
}
TEST(LowmcPrg, EvalAgreesWithBulk)
{
using prg = dpf::prg::lowmc128;
simde__m128i seed = block_from_lanes(0x0123456789abcdefull, 0xfedcba9876543210ull);
auto kids = prg::eval01(seed);
EXPECT_TRUE(blocks_equal(kids[0], prg::eval(seed, 0)));
EXPECT_TRUE(blocks_equal(kids[1], prg::eval(seed, 1)));
EXPECT_FALSE(blocks_equal(kids[0], kids[1]));
EXPECT_FALSE(blocks_equal(kids[0], seed));
alignas(16) simde__m128i bulk[4];
prg::eval(seed, bulk, 4, 0);
EXPECT_TRUE(blocks_equal(bulk[0], kids[0]));
EXPECT_TRUE(blocks_equal(bulk[1], kids[1]));
EXPECT_TRUE(blocks_equal(bulk[2], prg::eval(seed, 2)));
EXPECT_TRUE(blocks_equal(bulk[3], prg::eval(seed, 3)));
alignas(16) simde__m128i seeds[8];
alignas(16) simde__m128i out4[4];
alignas(16) simde__m128i out8[8];
alignas(16) simde__m128i left[4];
alignas(16) simde__m128i right[4];
for (int i = 0; i < 8; ++i)
{
seeds[i] = block_from_lanes(0x1000u + static_cast<unsigned>(i), 0x2000u);
}
prg::eval_x4(seeds, out4, 3);
prg::eval_x8(seeds, out8, 5);
prg::eval01_x4(seeds, left, right);
for (int i = 0; i < 4; ++i)
{
EXPECT_TRUE(blocks_equal(out4[i], prg::eval(seeds[i], 3)));
EXPECT_TRUE(blocks_equal(left[i], prg::eval(seeds[i], 0)));
EXPECT_TRUE(blocks_equal(right[i], prg::eval(seeds[i], 1)));
}
for (int i = 0; i < 8; ++i)
{
EXPECT_TRUE(blocks_equal(out8[i], prg::eval(seeds[i], 5)));
}
}
TEST(LowmcPrg, DpfPoint)
{
using prg = dpf::prg::lowmc128;
const std::uint8_t x = 0x2a;
const std::uint32_t y = 0x01020304;
auto [k0, k1] = dpf::make_dpf<prg>(x, y);
for (int i = 0; i < 256; ++i)
{
auto y0 = *dpf::eval_point(k0, static_cast<std::uint8_t>(i));
auto y1 = *dpf::eval_point(k1, static_cast<std::uint8_t>(i));
auto sum = dpf::reconstruct(y0, y1);
if (static_cast<std::uint8_t>(i) == x)
{
EXPECT_EQ(sum, y);
}
else
{
EXPECT_EQ(sum, 0u);
}
}
}
TEST(LowmcPrg, CounterWrapperCountsEval01)
{
using prg = dpf::prg::counter_wrapper<dpf::prg::lowmc128>;
const auto before = prg::count();
simde__m128i seed = block_from_lanes(0x1111ull, 0x2222ull);
auto kids = prg::eval01(seed);
EXPECT_FALSE(blocks_equal(kids[0], kids[1]));
EXPECT_EQ(prg::count(), before + 2u);
alignas(16) simde__m128i bulk[4];
prg::eval(seed, bulk, 4, 0);
EXPECT_EQ(prg::count(), before + 2u + 4u);
}
TEST(LowmcPrg, CounterWrapperDpfGenAndPoint)
{
using prg = dpf::prg::counter_wrapper<dpf::prg::lowmc128>;
const auto before = prg::count();
const std::uint8_t x = 0x91;
const std::uint32_t y = 0xdeadbeef;
auto [k0, k1] = dpf::make_dpf<prg>(x, y);
EXPECT_GT(prg::count(), before);
auto y0 = *dpf::eval_point(k0, x);
auto y1 = *dpf::eval_point(k1, x);
EXPECT_EQ(dpf::reconstruct(y0, y1), y);
}