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
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "dpf/bit.hpp"
|
||||
#include "dpf/bitstring.hpp"
|
||||
#include "dpf/blob.hpp"
|
||||
#include "dpf/packed_lane_arithmetic.hpp"
|
||||
#include "dpf/wildcard.hpp"
|
||||
#include "dpf/xor_wrapper.hpp"
|
||||
|
|
@ -90,6 +91,83 @@ static constexpr auto subtract_leaf = leaf_arithmetic::subtract_t<OutputT, void>
|
|||
|
||||
static constexpr auto multiply_leaf = leaf_arithmetic::multiply_t<void, void>{};
|
||||
|
||||
/// @brief Scalar add in the leaf output group.
|
||||
/// @details `float`/`double` use XOR of the IEEE bit pattern (same as
|
||||
/// `add_t` on packed leaves), not IEEE floating-point addition.
|
||||
/// \complexity O(1) for a scalar. A packed node walks its bytes once (`add_t` / the lane loops): O(sizeof node) and the carry stays inside a `twobit` or `nyble` lane.
|
||||
template <typename T>
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
HEDLEY_NO_THROW
|
||||
HEDLEY_PURE
|
||||
T leaf_group_add(const T & a, const T & b) noexcept
|
||||
{
|
||||
if constexpr (std::is_same_v<T, float> || std::is_same_v<T, double>)
|
||||
{
|
||||
using bits_t = std::conditional_t<sizeof(T) == 4, psnip_uint32_t, psnip_uint64_t>;
|
||||
bits_t aa{}, bb{};
|
||||
utils::raw_memcpy(&aa, &a, sizeof(T));
|
||||
utils::raw_memcpy(&bb, &b, sizeof(T));
|
||||
bits_t cc = static_cast<bits_t>(aa ^ bb);
|
||||
T out{};
|
||||
utils::raw_memcpy(&out, &cc, sizeof(T));
|
||||
return out;
|
||||
}
|
||||
else
|
||||
{
|
||||
return static_cast<T>(a + b);
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief Scalar multiply in the leaf output group (`float`/`double`: AND of bits).
|
||||
template <typename T>
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
HEDLEY_NO_THROW
|
||||
HEDLEY_PURE
|
||||
T leaf_group_mul(const T & a, const T & b) noexcept
|
||||
{
|
||||
if constexpr (std::is_same_v<T, float> || std::is_same_v<T, double>)
|
||||
{
|
||||
using bits_t = std::conditional_t<sizeof(T) == 4, psnip_uint32_t, psnip_uint64_t>;
|
||||
bits_t aa{}, bb{};
|
||||
utils::raw_memcpy(&aa, &a, sizeof(T));
|
||||
utils::raw_memcpy(&bb, &b, sizeof(T));
|
||||
bits_t cc = static_cast<bits_t>(aa & bb);
|
||||
T out{};
|
||||
utils::raw_memcpy(&out, &cc, sizeof(T));
|
||||
return out;
|
||||
}
|
||||
else
|
||||
{
|
||||
return static_cast<T>(a * b);
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief Multiplicative identity for leaf scaling (all-ones for XOR/AND groups).
|
||||
template <typename T>
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
HEDLEY_NO_THROW
|
||||
HEDLEY_PURE
|
||||
T leaf_group_one() noexcept
|
||||
{
|
||||
if constexpr (std::is_same_v<T, float> || std::is_same_v<T, double>)
|
||||
{
|
||||
using bits_t = std::conditional_t<sizeof(T) == 4, psnip_uint32_t, psnip_uint64_t>;
|
||||
bits_t ones = static_cast<bits_t>(~bits_t{0});
|
||||
T out{};
|
||||
utils::raw_memcpy(&out, &ones, sizeof(T));
|
||||
return out;
|
||||
}
|
||||
else if constexpr (utils::is_xor_wrapper_v<T>)
|
||||
{
|
||||
using u = typename T::value_type;
|
||||
return T{static_cast<u>(~u{0})};
|
||||
}
|
||||
else
|
||||
{
|
||||
return T{1};
|
||||
}
|
||||
}
|
||||
|
||||
namespace leaf_arithmetic
|
||||
{
|
||||
|
||||
|
|
@ -260,10 +338,10 @@ struct add_array_t<OutputT, std::enable_if_t<dpf::utils::has_operators_plus_minu
|
|||
"arithmetic leaf array and output type must be the same size");
|
||||
std::array<T, N> c;
|
||||
output_type a_, b_;
|
||||
std::memcpy(&a_, std::data(a), sizeof(a_));
|
||||
std::memcpy(&b_, std::data(b), sizeof(b_));
|
||||
utils::raw_memcpy(&a_, std::data(a), sizeof(a_));
|
||||
utils::raw_memcpy(&b_, std::data(b), sizeof(b_));
|
||||
output_type c_ = a_ + b_;
|
||||
std::memcpy(std::data(c), &c_, sizeof(c_));
|
||||
utils::raw_memcpy(std::data(c), &c_, sizeof(c_));
|
||||
return c;
|
||||
}
|
||||
};
|
||||
|
|
@ -294,10 +372,10 @@ template <> struct add_t<simde_int128, simde__m128i> final
|
|||
{
|
||||
simde__m128i ret;
|
||||
simde_int128 lhs_, rhs_;
|
||||
std::memcpy(&lhs_, &lhs, sizeof(simde_int128));
|
||||
std::memcpy(&rhs_, &rhs, sizeof(simde_int128));
|
||||
utils::raw_memcpy(&lhs_, &lhs, sizeof(simde_int128));
|
||||
utils::raw_memcpy(&rhs_, &rhs, sizeof(simde_int128));
|
||||
simde_int128 sum = lhs_ + rhs_;
|
||||
std::memcpy(&ret, &sum, sizeof(simde__m128i));
|
||||
utils::raw_memcpy(&ret, &sum, sizeof(simde__m128i));
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
|
@ -307,10 +385,10 @@ template <> struct add_t<simde_uint128, simde__m128i> final
|
|||
{
|
||||
simde__m128i ret;
|
||||
simde_uint128 lhs_, rhs_;
|
||||
std::memcpy(&lhs_, &lhs, sizeof(simde_uint128));
|
||||
std::memcpy(&rhs_, &rhs, sizeof(simde_uint128));
|
||||
utils::raw_memcpy(&lhs_, &lhs, sizeof(simde_uint128));
|
||||
utils::raw_memcpy(&rhs_, &rhs, sizeof(simde_uint128));
|
||||
simde_uint128 sum = lhs_ + rhs_;
|
||||
std::memcpy(&ret, &sum, sizeof(simde__m128i));
|
||||
utils::raw_memcpy(&ret, &sum, sizeof(simde__m128i));
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
|
@ -335,10 +413,10 @@ template <> struct add_t<simde_int128, simde__m256i> final
|
|||
{
|
||||
simde__m256i ret;
|
||||
simde_int128 lhs_[2], rhs_[2];
|
||||
std::memcpy(&lhs_, &lhs, sizeof(simde_int128) * 2);
|
||||
std::memcpy(&rhs_, &rhs, sizeof(simde_int128) * 2);
|
||||
utils::raw_memcpy(&lhs_, &lhs, sizeof(simde_int128) * 2);
|
||||
utils::raw_memcpy(&rhs_, &rhs, sizeof(simde_int128) * 2);
|
||||
simde_int128 sum[2] = { lhs_[0] + rhs_[0], lhs_[1] + rhs_[1] };
|
||||
std::memcpy(&ret, &sum, sizeof(simde__m256i));
|
||||
utils::raw_memcpy(&ret, &sum, sizeof(simde__m256i));
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
|
@ -348,21 +426,28 @@ template <> struct add_t<simde_uint128, simde__m256i> final
|
|||
{
|
||||
simde__m256i ret;
|
||||
simde_uint128 lhs_[2], rhs_[2];
|
||||
std::memcpy(&lhs_, &lhs, sizeof(simde_uint128) * 2);
|
||||
std::memcpy(&rhs_, &rhs, sizeof(simde_uint128) * 2);
|
||||
utils::raw_memcpy(&lhs_, &lhs, sizeof(simde_uint128) * 2);
|
||||
utils::raw_memcpy(&rhs_, &rhs, sizeof(simde_uint128) * 2);
|
||||
simde_uint128 sum[2] = { lhs_[0] + rhs_[0], lhs_[1] + rhs_[1] };
|
||||
std::memcpy(&ret, &sum, sizeof(simde__m256i));
|
||||
utils::raw_memcpy(&ret, &sum, sizeof(simde__m256i));
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename OutputT, typename NodeT, std::size_t N> struct add_t<OutputT, std::array<NodeT, N>> final : public detail::add_array_t<OutputT> {};
|
||||
template <std::size_t Nbits, typename WordT> struct add_t<dpf::bitstring<Nbits, WordT>, void> final : public detail::bitstring_xor_t<Nbits, WordT> {};
|
||||
template <std::size_t N> struct add_t<dpf::blob<N>, void> final : public detail::bitstring_xor_t<N * 8, unsigned char> {};
|
||||
template <std::size_t N, typename NodeT>
|
||||
struct add_t<dpf::blob<N>, NodeT> final : public detail::bitstring_xor_t<N * 8, unsigned char> {};
|
||||
/// @brief Bitwise XOR, not IEEE addition. Float addition does not form an
|
||||
/// exact secret-sharing group; XOR of the representation does.
|
||||
/// @tparam NodeT GGM node type
|
||||
template <typename NodeT> struct add_t<float, NodeT> final : public std::bit_xor<> {};
|
||||
template <typename NodeT> struct add_t<double, NodeT> final : public std::bit_xor<> {};
|
||||
/// @tparam NodeT GGM node type (not `void`; that selects the scalar wrapper)
|
||||
template <typename NodeT>
|
||||
struct add_t<float, NodeT, std::enable_if_t<!std::is_void_v<NodeT>>>
|
||||
final : public std::bit_xor<> {};
|
||||
template <typename NodeT>
|
||||
struct add_t<double, NodeT, std::enable_if_t<!std::is_void_v<NodeT>>>
|
||||
final : public std::bit_xor<> {};
|
||||
template <> struct add_t<dpf::bit, void> final : public std::bit_xor<> {};
|
||||
template <typename NodeT> struct add_t<dpf::bit, NodeT> final : public std::bit_xor<> {};
|
||||
template <typename T> struct add_t<xor_wrapper<T>, void> final : public std::bit_xor<> {};
|
||||
|
|
@ -546,10 +631,10 @@ struct sub_array_t<OutputT, std::enable_if_t<dpf::utils::has_operators_plus_minu
|
|||
"arithmetic leaf array and output type must be the same size");
|
||||
std::array<T, N> c;
|
||||
output_type a_, b_;
|
||||
std::memcpy(&a_, std::data(a), sizeof(a_));
|
||||
std::memcpy(&b_, std::data(b), sizeof(b_));
|
||||
utils::raw_memcpy(&a_, std::data(a), sizeof(a_));
|
||||
utils::raw_memcpy(&b_, std::data(b), sizeof(b_));
|
||||
output_type c_ = a_ - b_;
|
||||
std::memcpy(std::data(c), &c_, sizeof(c_));
|
||||
utils::raw_memcpy(std::data(c), &c_, sizeof(c_));
|
||||
return c;
|
||||
}
|
||||
};
|
||||
|
|
@ -580,10 +665,10 @@ template <> struct subtract_t<simde_int128, simde__m128i> final
|
|||
{
|
||||
simde__m128i ret;
|
||||
simde_int128 lhs_, rhs_;
|
||||
std::memcpy(&lhs_, &lhs, sizeof(simde_int128));
|
||||
std::memcpy(&rhs_, &rhs, sizeof(simde_int128));
|
||||
utils::raw_memcpy(&lhs_, &lhs, sizeof(simde_int128));
|
||||
utils::raw_memcpy(&rhs_, &rhs, sizeof(simde_int128));
|
||||
simde_int128 sum = lhs_ - rhs_;
|
||||
std::memcpy(&ret, &sum, sizeof(simde__m128i));
|
||||
utils::raw_memcpy(&ret, &sum, sizeof(simde__m128i));
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
|
@ -593,10 +678,10 @@ template <> struct subtract_t<simde_uint128, simde__m128i> final
|
|||
{
|
||||
simde__m128i ret;
|
||||
simde_uint128 lhs_, rhs_;
|
||||
std::memcpy(&lhs_, &lhs, sizeof(simde_uint128));
|
||||
std::memcpy(&rhs_, &rhs, sizeof(simde_uint128));
|
||||
utils::raw_memcpy(&lhs_, &lhs, sizeof(simde_uint128));
|
||||
utils::raw_memcpy(&rhs_, &rhs, sizeof(simde_uint128));
|
||||
simde_uint128 sum = lhs_ - rhs_;
|
||||
std::memcpy(&ret, &sum, sizeof(simde__m128i));
|
||||
utils::raw_memcpy(&ret, &sum, sizeof(simde__m128i));
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
|
@ -622,10 +707,10 @@ template <> struct subtract_t<simde_int128, simde__m256i> final
|
|||
{
|
||||
simde__m256i ret;
|
||||
simde_int128 lhs_[2], rhs_[2];
|
||||
std::memcpy(&lhs_, &lhs, sizeof(simde_int128) * 2);
|
||||
std::memcpy(&rhs_, &rhs, sizeof(simde_int128) * 2);
|
||||
utils::raw_memcpy(&lhs_, &lhs, sizeof(simde_int128) * 2);
|
||||
utils::raw_memcpy(&rhs_, &rhs, sizeof(simde_int128) * 2);
|
||||
simde_int128 sum[2] = { lhs_[0] - rhs_[0], lhs_[1] - rhs_[1] };
|
||||
std::memcpy(&ret, &sum, sizeof(simde__m256i));
|
||||
utils::raw_memcpy(&ret, &sum, sizeof(simde__m256i));
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
|
@ -635,20 +720,27 @@ template <> struct subtract_t<simde_uint128, simde__m256i> final
|
|||
{
|
||||
simde__m256i ret;
|
||||
simde_uint128 lhs_[2], rhs_[2];
|
||||
std::memcpy(&lhs_, &lhs, sizeof(simde_uint128) * 2);
|
||||
std::memcpy(&rhs_, &rhs, sizeof(simde_uint128) * 2);
|
||||
utils::raw_memcpy(&lhs_, &lhs, sizeof(simde_uint128) * 2);
|
||||
utils::raw_memcpy(&rhs_, &rhs, sizeof(simde_uint128) * 2);
|
||||
simde_uint128 sum[2] = { lhs_[0] - rhs_[0], lhs_[1] - rhs_[1] };
|
||||
std::memcpy(&ret, &sum, sizeof(simde__m256i));
|
||||
utils::raw_memcpy(&ret, &sum, sizeof(simde__m256i));
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename OutputT, typename NodeT, std::size_t N> struct subtract_t<OutputT, std::array<NodeT, N>> final : public detail::sub_array_t<OutputT> {};
|
||||
template <std::size_t Nbits, typename WordT> struct subtract_t<dpf::bitstring<Nbits, WordT>, void> final : public detail::bitstring_xor_t<Nbits, WordT> {};
|
||||
template <std::size_t N> struct subtract_t<dpf::blob<N>, void> final : public detail::bitstring_xor_t<N * 8, unsigned char> {};
|
||||
template <std::size_t N, typename NodeT>
|
||||
struct subtract_t<dpf::blob<N>, NodeT> final : public detail::bitstring_xor_t<N * 8, unsigned char> {};
|
||||
/// @brief Bitwise XOR, not IEEE subtraction.
|
||||
/// @tparam NodeT GGM node type
|
||||
template <typename NodeT> struct subtract_t<float, NodeT> final : public std::bit_xor<> {};
|
||||
template <typename NodeT> struct subtract_t<double, NodeT> final : public std::bit_xor<> {};
|
||||
template <typename NodeT>
|
||||
struct subtract_t<float, NodeT, std::enable_if_t<!std::is_void_v<NodeT>>>
|
||||
final : public std::bit_xor<> {};
|
||||
template <typename NodeT>
|
||||
struct subtract_t<double, NodeT, std::enable_if_t<!std::is_void_v<NodeT>>>
|
||||
final : public std::bit_xor<> {};
|
||||
template <typename NodeT> struct subtract_t<dpf::bit, NodeT> final : public std::bit_xor<> {};
|
||||
template <> struct subtract_t<dpf::bit, void> final : public std::bit_xor<> {};
|
||||
template <typename T> struct subtract_t<xor_wrapper<T>, void> final : public std::bit_xor<> {};
|
||||
|
|
@ -847,9 +939,9 @@ template <> struct multiply_t<simde_int128, simde__m128i> final
|
|||
{
|
||||
simde_int128 a_;
|
||||
simde__m128i c;
|
||||
std::memcpy(&a_, &a, sizeof(simde_int128));
|
||||
utils::raw_memcpy(&a_, &a, sizeof(simde_int128));
|
||||
simde_int128 c_ = a_ * b;
|
||||
std::memcpy(&c, &c_, sizeof(simde__m128i));
|
||||
utils::raw_memcpy(&c, &c_, sizeof(simde__m128i));
|
||||
return c;
|
||||
}
|
||||
};
|
||||
|
|
@ -860,9 +952,9 @@ template <> struct multiply_t<simde_uint128, simde__m128i> final
|
|||
{
|
||||
simde_uint128 a_;
|
||||
simde__m128i c;
|
||||
std::memcpy(&a_, &a, sizeof(simde_uint128));
|
||||
utils::raw_memcpy(&a_, &a, sizeof(simde_uint128));
|
||||
simde_uint128 c_ = a_ * b;
|
||||
std::memcpy(&c, &c_, sizeof(simde__m128i));
|
||||
utils::raw_memcpy(&c, &c_, sizeof(simde__m128i));
|
||||
return c;
|
||||
}
|
||||
};
|
||||
|
|
@ -908,8 +1000,8 @@ struct multiply_t<xor_wrapper<T>, simde__m128i> final
|
|||
} else {
|
||||
alignas(simde__m128i) unsigned char buf[sizeof(simde__m128i)]{};
|
||||
for (std::size_t off = 0; off + sizeof(val_t) <= sizeof(buf); off += sizeof(val_t))
|
||||
std::memcpy(buf + off, &v, sizeof(val_t));
|
||||
std::memcpy(&bb, buf, sizeof(bb));
|
||||
utils::raw_memcpy(buf + off, &v, sizeof(val_t));
|
||||
utils::raw_memcpy(&bb, buf, sizeof(bb));
|
||||
}
|
||||
return simde_mm_and_si128(a, bb);
|
||||
}
|
||||
|
|
@ -933,8 +1025,8 @@ struct multiply_t<xor_wrapper<T>, simde__m256i> final
|
|||
} else {
|
||||
alignas(simde__m256i) unsigned char buf[sizeof(simde__m256i)]{};
|
||||
for (std::size_t off = 0; off + sizeof(val_t) <= sizeof(buf); off += sizeof(val_t))
|
||||
std::memcpy(buf + off, &v, sizeof(val_t));
|
||||
std::memcpy(&bb, buf, sizeof(bb));
|
||||
utils::raw_memcpy(buf + off, &v, sizeof(val_t));
|
||||
utils::raw_memcpy(&bb, buf, sizeof(bb));
|
||||
}
|
||||
return simde_mm256_and_si256(a, bb);
|
||||
}
|
||||
|
|
@ -986,7 +1078,7 @@ struct multiply_t<float, simde__m128i> final
|
|||
{
|
||||
static_assert(sizeof(float) == 4, "float must be 32 bits");
|
||||
psnip_uint32_t bits = 0;
|
||||
std::memcpy(&bits, &b, sizeof(bits));
|
||||
utils::raw_memcpy(&bits, &b, sizeof(bits));
|
||||
return simde_mm_and_si128(a, simde_mm_set1_epi32(static_cast<int>(bits)));
|
||||
}
|
||||
};
|
||||
|
|
@ -998,7 +1090,7 @@ struct multiply_t<float, simde__m256i> final
|
|||
{
|
||||
static_assert(sizeof(float) == 4, "float must be 32 bits");
|
||||
psnip_uint32_t bits = 0;
|
||||
std::memcpy(&bits, &b, sizeof(bits));
|
||||
utils::raw_memcpy(&bits, &b, sizeof(bits));
|
||||
return simde_mm256_and_si256(a, simde_mm256_set1_epi32(static_cast<int>(bits)));
|
||||
}
|
||||
};
|
||||
|
|
@ -1010,7 +1102,7 @@ struct multiply_t<double, simde__m128i> final
|
|||
{
|
||||
static_assert(sizeof(double) == 8, "double must be 64 bits");
|
||||
psnip_uint64_t bits = 0;
|
||||
std::memcpy(&bits, &b, sizeof(bits));
|
||||
utils::raw_memcpy(&bits, &b, sizeof(bits));
|
||||
return simde_mm_and_si128(a, simde_mm_set1_epi64x(static_cast<long long>(bits)));
|
||||
}
|
||||
};
|
||||
|
|
@ -1022,7 +1114,7 @@ struct multiply_t<double, simde__m256i> final
|
|||
{
|
||||
static_assert(sizeof(double) == 8, "double must be 64 bits");
|
||||
psnip_uint64_t bits = 0;
|
||||
std::memcpy(&bits, &b, sizeof(bits));
|
||||
utils::raw_memcpy(&bits, &b, sizeof(bits));
|
||||
return simde_mm256_and_si256(a, simde_mm256_set1_epi64x(static_cast<long long>(bits)));
|
||||
}
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue