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
|
|
@ -10,10 +10,11 @@
|
|||
|
||||
#include <bsd/stdlib.h>
|
||||
|
||||
#include <array>
|
||||
#include <cerrno>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <exception>
|
||||
#include <fcntl.h>
|
||||
#include <mutex>
|
||||
|
|
@ -31,11 +32,19 @@ namespace dpf
|
|||
namespace detail
|
||||
{
|
||||
|
||||
/// @brief Thread-local count of bytes delivered by `uniform_fill`.
|
||||
inline thread_local std::uint64_t random_bytes_tls = 0;
|
||||
|
||||
/// @brief When set, `uniform_fill` copies from this hook and does not read the
|
||||
/// system RNG. Used to feed the same beaver coins to dealer `make_dpf` and
|
||||
/// Doerner–Shelat gen. Null in normal use.
|
||||
inline thread_local void (*uniform_bytes_hook)(void *, std::size_t) = nullptr;
|
||||
|
||||
/// @brief State for `uniform_bytes_hook`, set and read by the hook's owner
|
||||
/// (`experiment` keeps itself here). Travels with the hook when another thread
|
||||
/// adopts this one's draws (`dpf/thread_work.hpp`).
|
||||
inline thread_local void * uniform_bytes_ctx = nullptr;
|
||||
|
||||
template <typename T>
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
HEDLEY_NO_THROW
|
||||
|
|
@ -170,6 +179,20 @@ inline entropy_source & entropy()
|
|||
|
||||
} // namespace detail
|
||||
|
||||
/// @brief Zero the thread-local random-byte counter.
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
void reset_random_bytes_count() noexcept
|
||||
{
|
||||
detail::random_bytes_tls = 0;
|
||||
}
|
||||
|
||||
/// @brief Bytes filled by `uniform_fill` since the last reset on this thread.
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
std::uint64_t random_bytes_count() noexcept
|
||||
{
|
||||
return detail::random_bytes_tls;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
HEDLEY_NO_THROW
|
||||
auto & uniform_fill(T & buf) noexcept // NOLINT(runtime/references)
|
||||
|
|
@ -186,12 +209,17 @@ auto & uniform_fill(T & buf) noexcept // NOLINT(runtime/references)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (detail::fill_from_hook(buf)) return buf;
|
||||
if (detail::fill_from_hook(buf))
|
||||
{
|
||||
detail::random_bytes_tls += sizeof(buf);
|
||||
return buf;
|
||||
}
|
||||
#if defined(LIBDPF_USE_ARC4RANDOM)
|
||||
arc4random_buf(&buf, sizeof(buf));
|
||||
#else
|
||||
detail::entropy().read(&buf, sizeof(buf));
|
||||
#endif
|
||||
detail::random_bytes_tls += sizeof(buf);
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
|
@ -214,24 +242,82 @@ auto additively_share(T secret) noexcept
|
|||
{
|
||||
using T_ = std::remove_cv_t<std::remove_reference_t<T>>;
|
||||
T_ tmp = uniform_sample<T_>();
|
||||
// Signed subtraction overflows for extreme shares. Subtract in the
|
||||
// unsigned width and copy the bits back so the group is mod 2^n.
|
||||
T_ other;
|
||||
if constexpr (std::is_integral_v<T_> && std::is_signed_v<T_>)
|
||||
{
|
||||
using U = std::make_unsigned_t<T_>;
|
||||
U diff = static_cast<U>(static_cast<T_>(secret)) - static_cast<U>(tmp);
|
||||
std::memcpy(&other, &diff, sizeof(other));
|
||||
}
|
||||
else
|
||||
{
|
||||
other = static_cast<T_>(static_cast<T_>(secret) - tmp);
|
||||
}
|
||||
T_ other = detail::group_sub(static_cast<T_>(secret), tmp);
|
||||
return std::make_pair(
|
||||
additive_share<T_, 0>::from_raw(tmp),
|
||||
additive_share<T_, 1>::from_raw(other));
|
||||
}
|
||||
|
||||
/// @brief Uniform (3,3)-additive sharing of `secret`.
|
||||
/// @details Two components are uniform. The third is `secret` minus those
|
||||
/// two in the share group, so the three shares sum to `secret`.
|
||||
/// @tparam T value type
|
||||
/// @param secret the cleartext secret
|
||||
/// @return shares for parties 0, 1, and 2
|
||||
template <typename T>
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
HEDLEY_NO_THROW
|
||||
auto additively_share3(T secret) noexcept
|
||||
{
|
||||
using T_ = std::remove_cv_t<std::remove_reference_t<T>>;
|
||||
const T_ a = uniform_sample<T_>();
|
||||
const T_ b = uniform_sample<T_>();
|
||||
const T_ c = detail::group_sub(
|
||||
detail::group_sub(static_cast<T_>(secret), a), b);
|
||||
return std::make_tuple(
|
||||
additive3_share<T_, 0>::from_raw(a),
|
||||
additive3_share<T_, 1>::from_raw(b),
|
||||
additive3_share<T_, 2>::from_raw(c));
|
||||
}
|
||||
|
||||
/// @brief Uniform (2,3)-replicated sharing of `secret`.
|
||||
/// @details The underlying (3,3) components are a uniform additive split.
|
||||
/// Each party receives its component and the next party's.
|
||||
/// @tparam T value type
|
||||
/// @param secret the cleartext secret
|
||||
/// @return shares for parties 0, 1, and 2
|
||||
template <typename T>
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
HEDLEY_NO_THROW
|
||||
auto share_replicated(T secret) noexcept
|
||||
{
|
||||
using T_ = std::remove_cv_t<std::remove_reference_t<T>>;
|
||||
const T_ x0 = uniform_sample<T_>();
|
||||
const T_ x1 = uniform_sample<T_>();
|
||||
const T_ x2 = detail::group_sub(
|
||||
detail::group_sub(static_cast<T_>(secret), x0), x1);
|
||||
return make_replicated_shares(x0, x1, x2);
|
||||
}
|
||||
|
||||
namespace shamir
|
||||
{
|
||||
|
||||
/// @brief Uniform `(K,N)` Shamir sharing of `secret`.
|
||||
/// @details Coefficients of `x, ..., x^{K-1}` are `uniform_sample<T>`. The
|
||||
/// shares are `deal<T, K, N>`. Threshold 1 draws nothing: every share
|
||||
/// equals `secret`. `shamir3::share_secret` is the `(2,3)` case on
|
||||
/// `fp61`, reindexed to points `1`, `2`, and `3`.
|
||||
/// @tparam K shares required to reconstruct
|
||||
/// @tparam N shareholders
|
||||
/// @tparam T field type. Opening needs `detail::shamir_field<T>`
|
||||
/// @param secret the cleartext secret
|
||||
/// @return one share per party `0 .. N-1`
|
||||
/// \complexity O(NK) field operations, plus `K-1` field samples. No messages.
|
||||
template <typename T, std::size_t K, std::size_t N>
|
||||
HEDLEY_WARN_UNUSED_RESULT
|
||||
HEDLEY_NO_THROW
|
||||
auto share_secret(T secret) noexcept
|
||||
{
|
||||
using T_ = std::remove_cv_t<std::remove_reference_t<T>>;
|
||||
constexpr std::size_t degree = access<K, N>::degree;
|
||||
std::array<T_, degree> coeff{};
|
||||
for (std::size_t i = 0; i < degree; ++i)
|
||||
coeff[i] = uniform_sample<T_>();
|
||||
return deal<T_, K, N>(static_cast<T_>(secret), coeff);
|
||||
}
|
||||
|
||||
} // namespace shamir
|
||||
|
||||
} // namespace dpf
|
||||
|
||||
#endif // LIBDPF_INCLUDE_DPF_RANDOM_HPP__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue