Checkpoint the party/runtime stack before share-program and malicious-mode work.
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>
This commit is contained in:
parent
695f8e84f7
commit
0d22946a0e
1835 changed files with 170291 additions and 2849 deletions
|
|
@ -57,6 +57,13 @@ template <typename T>
|
|||
struct is_vec_tag<T, std::void_t<decltype(T::dpf_vec)>>
|
||||
: std::bool_constant<T::dpf_vec> {};
|
||||
|
||||
template <typename T, typename = void>
|
||||
struct has_from_seed : std::false_type {};
|
||||
template <typename T>
|
||||
struct has_from_seed<T, std::void_t<decltype(
|
||||
T::from_seed(static_cast<const void *>(nullptr), std::size_t{0}))>>
|
||||
: std::true_type {};
|
||||
|
||||
template <typename T, typename = void>
|
||||
struct has_integral_representation : std::false_type {};
|
||||
template <typename T>
|
||||
|
|
@ -542,6 +549,221 @@ group_elem group_final_cw(const typename PRG::block_type & s0,
|
|||
group_add(group_add(group_add(c1, group_neg(c0)), group_neg(Va)), on_path));
|
||||
}
|
||||
|
||||
/// @brief Type-erased group for a comparison payload that supplies `from_seed`,
|
||||
/// `operator+`, and unary `operator-`. The element is at most 256 bytes.
|
||||
struct payload_ops
|
||||
{
|
||||
static constexpr std::size_t cap = 256;
|
||||
std::size_t size = 0;
|
||||
void (*add)(unsigned char *, const unsigned char *, const unsigned char *) = nullptr;
|
||||
void (*neg)(unsigned char *, const unsigned char *) = nullptr;
|
||||
void (*from_node)(unsigned char *, const void *, std::size_t) = nullptr;
|
||||
void (*scale)(unsigned char *, const unsigned char *, std::int64_t) = nullptr;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void payload_add(unsigned char * dst, const unsigned char * a, const unsigned char * b)
|
||||
{
|
||||
T x{}, y{};
|
||||
std::memcpy(&x, a, sizeof(T));
|
||||
std::memcpy(&y, b, sizeof(T));
|
||||
const T z = x + y;
|
||||
std::memset(dst, 0, payload_ops::cap);
|
||||
std::memcpy(dst, &z, sizeof(T));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void payload_neg(unsigned char * dst, const unsigned char * a)
|
||||
{
|
||||
T x{};
|
||||
std::memcpy(&x, a, sizeof(T));
|
||||
const T z = -x;
|
||||
std::memset(dst, 0, payload_ops::cap);
|
||||
std::memcpy(dst, &z, sizeof(T));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void payload_from_node(unsigned char * dst, const void * node, std::size_t n)
|
||||
{
|
||||
const T z = T::from_seed(node, n);
|
||||
std::memset(dst, 0, payload_ops::cap);
|
||||
std::memcpy(dst, &z, sizeof(T));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void payload_scale(unsigned char * dst, const unsigned char * a, std::int64_t k)
|
||||
{
|
||||
T g{};
|
||||
std::memcpy(&g, a, sizeof(T));
|
||||
T r{};
|
||||
if (k < 0)
|
||||
{
|
||||
g = -g;
|
||||
k = -k;
|
||||
}
|
||||
auto m = static_cast<std::uint64_t>(k);
|
||||
while (m != 0)
|
||||
{
|
||||
if ((m & 1u) != 0)
|
||||
r = r + g;
|
||||
m >>= 1;
|
||||
if (m != 0)
|
||||
g = g + g;
|
||||
}
|
||||
std::memset(dst, 0, payload_ops::cap);
|
||||
std::memcpy(dst, &r, sizeof(T));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
payload_ops make_payload_ops()
|
||||
{
|
||||
static_assert(sizeof(T) <= payload_ops::cap,
|
||||
"comparison payload exceeds 256 bytes");
|
||||
static_assert(has_from_seed<T>::value,
|
||||
"comparison payload needs from_seed");
|
||||
payload_ops ops;
|
||||
ops.size = sizeof(T);
|
||||
ops.add = &payload_add<T>;
|
||||
ops.neg = &payload_neg<T>;
|
||||
ops.from_node = &payload_from_node<T>;
|
||||
ops.scale = &payload_scale<T>;
|
||||
return ops;
|
||||
}
|
||||
|
||||
inline void payload_copy(unsigned char * dst, const unsigned char * src, std::size_t n)
|
||||
{
|
||||
std::memset(dst, 0, payload_ops::cap);
|
||||
if (n != 0)
|
||||
std::memcpy(dst, src, n);
|
||||
}
|
||||
|
||||
inline void payload_sgn(const payload_ops & ops, unsigned char * dst,
|
||||
const unsigned char * src, bool neg)
|
||||
{
|
||||
if (!neg)
|
||||
payload_copy(dst, src, ops.size);
|
||||
else
|
||||
ops.neg(dst, src);
|
||||
}
|
||||
|
||||
/// @brief One comparison-level correction in `ops`'s group.
|
||||
/// @details Mirrors `group_value_cw`. When `beta` is null the correction is split
|
||||
/// into a group element independent of δ and an integer coefficient of δ.
|
||||
inline void payload_value_cw(const payload_ops & ops,
|
||||
const void * n0l, const void * n0r, const void * n1l, const void * n1r,
|
||||
std::size_t node_len, std::uint8_t t1, int ai,
|
||||
unsigned char * va, std::int64_t & va_c,
|
||||
const unsigned char * beta, unsigned char * vcw, std::int64_t * coeff)
|
||||
{
|
||||
unsigned char v0l[payload_ops::cap]{}, v0r[payload_ops::cap]{};
|
||||
unsigned char v1l[payload_ops::cap]{}, v1r[payload_ops::cap]{};
|
||||
ops.from_node(v0l, n0l, node_len);
|
||||
ops.from_node(v0r, n0r, node_len);
|
||||
ops.from_node(v1l, n1l, node_len);
|
||||
ops.from_node(v1r, n1r, node_len);
|
||||
const unsigned char * v0k = ai == 0 ? v0l : v0r;
|
||||
const unsigned char * v1k = ai == 0 ? v1l : v1r;
|
||||
const unsigned char * v0lo = ai == 0 ? v0r : v0l;
|
||||
const unsigned char * v1lo = ai == 0 ? v1r : v1l;
|
||||
unsigned char neg_v0[payload_ops::cap]{}, neg_va[payload_ops::cap]{};
|
||||
ops.neg(neg_v0, v0lo);
|
||||
ops.neg(neg_va, va);
|
||||
unsigned char sum[payload_ops::cap]{}, inner[payload_ops::cap]{};
|
||||
ops.add(sum, v1lo, neg_v0);
|
||||
ops.add(inner, sum, neg_va);
|
||||
std::int64_t inner_c = -va_c;
|
||||
if (ai == 1)
|
||||
{
|
||||
if (beta != nullptr)
|
||||
ops.add(inner, inner, beta);
|
||||
else
|
||||
inner_c += 1;
|
||||
}
|
||||
payload_sgn(ops, vcw, inner, t1 != 0);
|
||||
const std::int64_t vcw_c = (t1 != 0) ? -inner_c : inner_c;
|
||||
unsigned char sgn_vcw[payload_ops::cap]{};
|
||||
payload_sgn(ops, sgn_vcw, vcw, t1 != 0);
|
||||
unsigned char neg_v1k[payload_ops::cap]{}, acc[payload_ops::cap]{};
|
||||
ops.neg(neg_v1k, v1k);
|
||||
ops.add(acc, va, neg_v1k);
|
||||
ops.add(acc, acc, v0k);
|
||||
ops.add(va, acc, sgn_vcw);
|
||||
va_c += (t1 != 0) ? -vcw_c : vcw_c;
|
||||
if (coeff != nullptr)
|
||||
*coeff = vcw_c;
|
||||
if (beta != nullptr && vcw_c != 0)
|
||||
{
|
||||
unsigned char extra[payload_ops::cap]{};
|
||||
ops.scale(extra, beta, vcw_c);
|
||||
ops.add(vcw, vcw, extra);
|
||||
}
|
||||
}
|
||||
|
||||
inline void payload_final_cw(const payload_ops & ops,
|
||||
const void * s0, const void * s1, std::size_t node_len, std::uint8_t t1,
|
||||
const unsigned char * va, std::int64_t va_c,
|
||||
const unsigned char * on_path, int on_c,
|
||||
unsigned char * out, std::int64_t * coeff)
|
||||
{
|
||||
unsigned char c0[payload_ops::cap]{}, c1[payload_ops::cap]{};
|
||||
ops.from_node(c0, s0, node_len);
|
||||
ops.from_node(c1, s1, node_len);
|
||||
unsigned char neg_c0[payload_ops::cap]{}, neg_va[payload_ops::cap]{};
|
||||
ops.neg(neg_c0, c0);
|
||||
ops.neg(neg_va, va);
|
||||
unsigned char sum[payload_ops::cap]{}, inner[payload_ops::cap]{};
|
||||
ops.add(sum, c1, neg_c0);
|
||||
ops.add(inner, sum, neg_va);
|
||||
if (on_path != nullptr)
|
||||
ops.add(inner, inner, on_path);
|
||||
std::int64_t inner_c = -va_c + on_c;
|
||||
payload_sgn(ops, out, inner, t1 != 0);
|
||||
const std::int64_t out_c = (t1 != 0) ? -inner_c : inner_c;
|
||||
if (coeff != nullptr)
|
||||
*coeff = out_c;
|
||||
}
|
||||
|
||||
template <typename Word>
|
||||
Word payload_to_word(const unsigned char * bytes, std::size_t n)
|
||||
{
|
||||
Word w{};
|
||||
std::memcpy(&w, bytes, n < sizeof(Word) ? n : sizeof(Word));
|
||||
return w;
|
||||
}
|
||||
|
||||
template <typename T, typename = void>
|
||||
struct payload_has_canonicalize : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct payload_has_canonicalize<T,
|
||||
std::void_t<decltype(T::canonicalize(T{}))>> : std::true_type {};
|
||||
|
||||
template <typename T, typename Word>
|
||||
T payload_from_word(const Word & w)
|
||||
{
|
||||
T t{};
|
||||
utils::raw_memcpy(&t, &w, sizeof(T) < sizeof(Word) ? sizeof(T) : sizeof(Word));
|
||||
if constexpr (payload_has_canonicalize<T>::value)
|
||||
return T::canonicalize(t);
|
||||
return t;
|
||||
}
|
||||
|
||||
template <typename Word>
|
||||
std::int64_t payload_coeff_of(const Word & w)
|
||||
{
|
||||
std::int64_t k = 0;
|
||||
std::memcpy(&k, &w, sizeof(k) < sizeof(Word) ? sizeof(k) : sizeof(Word));
|
||||
return k;
|
||||
}
|
||||
|
||||
template <typename Word>
|
||||
Word payload_coeff_word(std::int64_t k)
|
||||
{
|
||||
Word w{};
|
||||
std::memcpy(&w, &k, sizeof(k) < sizeof(Word) ? sizeof(k) : sizeof(Word));
|
||||
return w;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace dpf
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue