Document the new DPF surfaces in one command set, and test the field, half-tree, and multipoint edges.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
0d8a5a8131
commit
0dff6df8ed
250 changed files with 12199 additions and 1981 deletions
|
|
@ -3,6 +3,7 @@
|
|||
#include "dpf.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <initializer_list>
|
||||
#include <random>
|
||||
#include <vector>
|
||||
|
||||
|
|
@ -40,6 +41,39 @@ void expect_domain(Input r, Input p, Input q, Beta if_true, Beta if_false,
|
|||
}
|
||||
}
|
||||
|
||||
struct IcPad
|
||||
{
|
||||
simde__m128i block() { return dpf::uniform_sample<simde__m128i>(); }
|
||||
uint8_t bit() { return static_cast<uint8_t>(dpf::uniform_sample<uint8_t>() & 1u); }
|
||||
};
|
||||
|
||||
using IcRng = dpf::ds_randomness<decltype(&dpf::uniform_sample<simde__m128i>), IcPad>;
|
||||
|
||||
IcRng ic_rng()
|
||||
{
|
||||
return {&dpf::uniform_sample<simde__m128i>, {}};
|
||||
}
|
||||
|
||||
template <typename Input>
|
||||
void expect_samples(Input r, Input p, Input q, uint32_t if_true, uint32_t if_false,
|
||||
std::initializer_list<Input> xs)
|
||||
{
|
||||
auto keys = dpf::make_dpf(r, dpf::ic(p, q, if_true, if_false));
|
||||
const uint64_t nmask = keys.first.input_mask;
|
||||
const uint64_t rb = static_cast<uint64_t>(r);
|
||||
const uint64_t pb = static_cast<uint64_t>(p);
|
||||
const uint64_t qb = static_cast<uint64_t>(q);
|
||||
for (Input x : xs)
|
||||
{
|
||||
const uint64_t got = static_cast<uint64_t>(dpf::reconstruct(
|
||||
dpf::eval_point(dpf::ic, keys.first, x),
|
||||
dpf::eval_point(dpf::ic, keys.second, x))) & 0xffffffffu;
|
||||
const uint64_t want = oracle(static_cast<uint64_t>(x), rb, pb, qb, nmask,
|
||||
if_true, if_false, 0xffffffffu);
|
||||
EXPECT_EQ(got, want) << "r=" << rb << " x=" << static_cast<uint64_t>(x);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(Ic, Uint8FullDomainCorners)
|
||||
|
|
@ -222,3 +256,92 @@ TEST(Ic, BitPayload)
|
|||
EXPECT_EQ(static_cast<bool>(y), w >= 1 && w <= 3) << x;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Ic, Uint16FullDomain)
|
||||
{
|
||||
expect_domain<uint16_t>(uint16_t{0x0100}, uint16_t{20}, uint16_t{400},
|
||||
uint32_t{9}, uint32_t{3}, 0xffffffffu);
|
||||
expect_domain<uint16_t>(uint16_t{0xFF00}, uint16_t{0}, uint16_t{1},
|
||||
uint32_t{1}, uint32_t{0}, 0xffffffffu);
|
||||
}
|
||||
|
||||
TEST(Ic, WideMasksSampleTheWrap)
|
||||
{
|
||||
const uint32_t p32 = 10, q32 = 1000;
|
||||
const uint32_t r32 = 0xFFFFFFF0u;
|
||||
expect_samples<uint32_t>(r32, p32, q32, 7u, 2u, {
|
||||
0u, 1u, p32, q32, q32 + 1u, r32, r32 - 1u, r32 + 1u,
|
||||
0x80000000u, 0xffffffffu
|
||||
});
|
||||
|
||||
const uint64_t p64 = 1, q64 = 3;
|
||||
const uint64_t r64 = ~uint64_t{0};
|
||||
expect_samples<uint64_t>(r64, p64, q64, 5u, 4u, {
|
||||
0ull, 1ull, 2ull, 3ull, 4ull, r64, r64 - 1ull,
|
||||
uint64_t{1} << 63
|
||||
});
|
||||
auto keys = dpf::make_dpf(r64, dpf::ic(p64, q64, uint32_t{5}, uint32_t{4}));
|
||||
EXPECT_EQ(keys.first.input_mask, ~uint64_t{0});
|
||||
}
|
||||
|
||||
TEST(Ic, AdditiveDoernerShelatMatchesDealer)
|
||||
{
|
||||
auto check = [](uint8_t r0, uint8_t r1, uint8_t p, uint8_t q,
|
||||
uint32_t beta, uint32_t fals) {
|
||||
const uint8_t r = static_cast<uint8_t>(r0 + r1);
|
||||
auto dealer = dpf::make_dpf(r, dpf::ic(p, q, beta, fals));
|
||||
auto ds = dpf::make_dpf_doerner_shelat(dpf::arith_input, r0, r1, ic_rng(),
|
||||
dpf::ic(p, q, beta, fals));
|
||||
for (int x = 0; x < 256; ++x)
|
||||
{
|
||||
const auto dealer_y = dpf::reconstruct(
|
||||
dpf::eval_point(dpf::ic, dealer.first, static_cast<uint8_t>(x)),
|
||||
dpf::eval_point(dpf::ic, dealer.second, static_cast<uint8_t>(x)));
|
||||
const auto ds_y = dpf::reconstruct(
|
||||
dpf::eval_point(dpf::ic, ds.first, static_cast<uint8_t>(x)),
|
||||
dpf::eval_point(dpf::ic, ds.second, static_cast<uint8_t>(x)));
|
||||
EXPECT_EQ(dealer_y, ds_y) << "r0=" << int(r0) << " r1=" << int(r1)
|
||||
<< " x=" << x;
|
||||
}
|
||||
};
|
||||
check(9, 100, 3, 50, 4, 0);
|
||||
check(200, 100, 0, 255, 8, 1);
|
||||
check(200, 200, 10, 20, 6, 2);
|
||||
check(0, 0, 1, 1, 1, 0);
|
||||
check(1, 0, 0, 0, 3, 9);
|
||||
}
|
||||
|
||||
TEST(Ic, AdditiveGeneval)
|
||||
{
|
||||
const uint8_t r0 = 250, r1 = 20, p = 4, q = 8;
|
||||
const uint32_t beta = 11, fals = 2;
|
||||
const uint8_t r = static_cast<uint8_t>(r0 + r1);
|
||||
const uint8_t queries[] = {0, 1, 4, 8, 9, 255};
|
||||
auto opened = dpf::geneval_ic(dpf::arith_input, r0, r1,
|
||||
std::begin(queries), std::end(queries), ic_rng(),
|
||||
dpf::ic(p, q, beta, fals));
|
||||
ASSERT_EQ(opened.party0.size(), 6u);
|
||||
for (std::size_t i = 0; i < 6; ++i)
|
||||
{
|
||||
const uint64_t got = (opened.party0[i] + opened.party1[i]) & 0xffffffffu;
|
||||
const uint64_t w = static_cast<uint64_t>(static_cast<uint8_t>(queries[i] - r));
|
||||
const uint64_t want = (w >= p && w <= q) ? beta : fals;
|
||||
EXPECT_EQ(got, want) << i;
|
||||
}
|
||||
|
||||
const uint8_t none[] = {0};
|
||||
auto empty = dpf::geneval_ic(dpf::arith_input, r0, r1,
|
||||
std::begin(none), std::begin(none), ic_rng(), dpf::ic(p, q, beta));
|
||||
EXPECT_TRUE(empty.party0.empty());
|
||||
EXPECT_EQ(empty.live_levels, 0u);
|
||||
}
|
||||
|
||||
TEST(Ic, IntervalRejectsDescendingEndpoints)
|
||||
{
|
||||
auto keys = dpf::make_dpf(uint8_t{4}, dpf::ic(uint8_t{1}, uint8_t{6}, uint32_t{1}));
|
||||
auto buf = dpf::make_output_buffer(dpf::ic, keys.first, 1);
|
||||
EXPECT_THROW(dpf::eval_interval(dpf::ic, keys.first, uint8_t{9}, uint8_t{2}, buf),
|
||||
std::invalid_argument);
|
||||
EXPECT_THROW(dpf::make_output_buffer(dpf::ic, keys.first, uint8_t{9}, uint8_t{2}),
|
||||
std::invalid_argument);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue