#include #include #include #include "dpf.hpp" // Extractable full-domain expansion must match point eval share-for-share, // including both lanes of the packed leaf that holds the programmed point. TEST(ExtractableFull, Fp61SharesMatchPointEval) { constexpr std::uint8_t alpha = 9; const dpf::fp61 message{42}; auto [k0, k1] = dpf::make_dpf(alpha, message, dpf::extractable{}); auto [buf0, it0] = dpf::eval_full(k0); auto [buf1, it1] = dpf::eval_full(k1); auto a0 = std::begin(it0); auto a1 = std::begin(it1); for (unsigned i = 0; i < 256; ++i, ++a0, ++a1) { const auto x = static_cast(i); const auto p0 = (*dpf::eval_point(k0, x)).raw(); const auto p1 = (*dpf::eval_point(k1, x)).raw(); EXPECT_EQ((*a0).raw().raw(), p0.raw()) << "party0 at " << i; EXPECT_EQ((*a1).raw().raw(), p1.raw()) << "party1 at " << i; } EXPECT_EQ(a0, std::end(it0)); EXPECT_EQ(a1, std::end(it1)); EXPECT_EQ(dpf::reconstruct(*a0 = *std::begin(it0), *std::begin(it1)), dpf::fp61{0}); // silence unused if reconstruct needs the type (void)buf0; (void)buf1; } TEST(ExtractableFull, Fp61OpenedMailbox) { constexpr std::uint8_t alpha = 9; const dpf::fp61 message{42}; auto [k0, k1] = dpf::make_dpf(alpha, message, dpf::extractable{}); auto [buf0, it0] = dpf::eval_full(k0); auto [buf1, it1] = dpf::eval_full(k1); std::vector y0, y1; for (auto it = std::begin(it0); it != std::end(it0); ++it) y0.push_back((*it).raw()); for (auto it = std::begin(it1); it != std::end(it1); ++it) y1.push_back((*it).raw()); EXPECT_EQ(y0[alpha] - y1[alpha], message); EXPECT_EQ((y0[0] - y1[0]).raw(), 0u); EXPECT_EQ((y0[8] - y1[8]).raw(), 0u); EXPECT_EQ((y0[10] - y1[10]).raw(), 0u); std::vector challenge(256); for (std::size_t i = 0; i < challenge.size(); ++i) challenge[i] = dpf::fp61{static_cast(i + 1)}; EXPECT_TRUE(dpf::sketch_verify(dpf::sketch_fold(y0, challenge), dpf::sketch_fold(y1, challenge))); }