Ship the TLS mesh, composer, Beaver/Yao/leaf MPC, prep/online paths, apps, and docs so the tree is pushable before elevating share_expr, security_mode, and prep resume. Co-authored-by: Cursor <cursoragent@cursor.com>
109 lines
3.2 KiB
C++
109 lines
3.2 KiB
C++
#include <gtest/gtest.h>
|
|
|
|
#include <array>
|
|
#include <cstdint>
|
|
#include <cstring>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
#include "dpf.hpp"
|
|
|
|
namespace
|
|
{
|
|
|
|
template <std::size_t N>
|
|
dpf::blob<N> make_blob_pattern(unsigned char seed)
|
|
{
|
|
dpf::blob<N> b{};
|
|
for (std::size_t i = 0; i < N; ++i)
|
|
b.bytes[i] = static_cast<unsigned char>(seed + static_cast<unsigned char>(i));
|
|
return b;
|
|
}
|
|
|
|
template <std::size_t N, typename InputT>
|
|
void expect_point_opens(InputT alpha, const dpf::blob<N> & beta)
|
|
{
|
|
auto [k0, k1] = dpf::make_dpf(alpha, beta);
|
|
auto open = [&](InputT x) {
|
|
return dpf::reconstruct(*dpf::eval_point(k0, x),
|
|
*dpf::eval_point(k1, x));
|
|
};
|
|
|
|
const auto s0 = *dpf::eval_point(k0, alpha);
|
|
const auto s1 = *dpf::eval_point(k1, alpha);
|
|
EXPECT_EQ(dpf::reconstruct(s0, s1), beta);
|
|
EXPECT_EQ(open(alpha), beta);
|
|
|
|
const dpf::blob<N> zero{};
|
|
const std::vector<InputT> offs = {
|
|
InputT{0},
|
|
InputT{1},
|
|
static_cast<InputT>(alpha + 1),
|
|
static_cast<InputT>(alpha ^ InputT{1}),
|
|
};
|
|
for (InputT x : offs)
|
|
{
|
|
if (x == alpha)
|
|
continue;
|
|
EXPECT_EQ(open(x), zero) << "off-point";
|
|
}
|
|
}
|
|
|
|
} // namespace
|
|
|
|
TEST(BlobLeaf, PointEvalUint32VariousN)
|
|
{
|
|
const std::uint32_t alpha = 0x00ab12cdu;
|
|
expect_point_opens<1>(alpha, make_blob_pattern<1>(0x11));
|
|
expect_point_opens<16>(alpha, make_blob_pattern<16>(0x22));
|
|
expect_point_opens<100>(alpha, make_blob_pattern<100>(0x33));
|
|
expect_point_opens<1000>(alpha, make_blob_pattern<1000>(0x44));
|
|
}
|
|
|
|
TEST(BlobLeaf, PointEvalUint128)
|
|
{
|
|
using input_t = simde_uint128;
|
|
const input_t alpha = (input_t{1} << 100) | input_t{0x55aau};
|
|
expect_point_opens<16>(alpha, make_blob_pattern<16>(0x7a));
|
|
expect_point_opens<100>(alpha, make_blob_pattern<100>(0x8b));
|
|
}
|
|
|
|
TEST(BlobLeaf, FullDomainMatchesPointShareForShare)
|
|
{
|
|
using input_t = std::uint8_t;
|
|
using blob_t = dpf::blob<100>;
|
|
const input_t alpha = 17;
|
|
const blob_t beta = make_blob_pattern<100>(0x9c);
|
|
|
|
auto [k0, k1] = dpf::make_dpf(alpha, beta);
|
|
auto full0 = dpf::eval_full(k0);
|
|
auto full1 = dpf::eval_full(k1);
|
|
auto & it0 = full0.second;
|
|
auto & it1 = full1.second;
|
|
|
|
auto a = std::begin(it0);
|
|
auto b = std::begin(it1);
|
|
for (std::size_t i = 0; a != std::end(it0) && b != std::end(it1);
|
|
++a, ++b, ++i)
|
|
{
|
|
const auto p0 = *dpf::eval_point(k0, static_cast<input_t>(i));
|
|
const auto p1 = *dpf::eval_point(k1, static_cast<input_t>(i));
|
|
EXPECT_EQ(dpf::reconstruct(*a, *b), dpf::reconstruct(p0, p1)) << i;
|
|
EXPECT_EQ(dpf::detail_walk::group_value(*a),
|
|
dpf::detail_walk::group_value(p0)) << "party0 @" << i;
|
|
EXPECT_EQ(dpf::detail_walk::group_value(*b),
|
|
dpf::detail_walk::group_value(p1)) << "party1 @" << i;
|
|
}
|
|
EXPECT_EQ(std::size_t(std::distance(std::begin(it0), std::end(it0))), 256u);
|
|
}
|
|
|
|
TEST(BlobLeaf, Domain128FullEvalThrows)
|
|
{
|
|
using input_t = simde_uint128;
|
|
using blob_t = dpf::blob<16>;
|
|
const input_t alpha = input_t{1} << 90;
|
|
const blob_t beta = make_blob_pattern<16>(1);
|
|
auto [k0, k1] = dpf::make_dpf(alpha, beta);
|
|
(void)k1;
|
|
EXPECT_THROW((void)dpf::eval_full(k0), std::exception);
|
|
}
|