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
|
|
@ -11,17 +11,19 @@
|
|||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <ostream>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
|
||||
#include "hedley/hedley.h"
|
||||
|
||||
#include "dpf/utils.hpp"
|
||||
#include "dpf/leaf_arithmetic.hpp"
|
||||
#include "dpf/random.hpp"
|
||||
|
||||
namespace dpf
|
||||
{
|
||||
|
||||
/// @brief Modulus \(p = 2^{61}-1\). `p` itself reduces to 0.
|
||||
/// @brief Modulus \f$p = 2^{61}-1\f$. `p` itself reduces to 0.
|
||||
inline constexpr std::uint64_t fp61_mod = (std::uint64_t{1} << 61) - 1;
|
||||
|
||||
/// @brief Additive element of the field of order `2^61 - 1`.
|
||||
|
|
@ -66,7 +68,29 @@ class fp61
|
|||
HEDLEY_NO_THROW
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
HEDLEY_PURE
|
||||
constexpr integral_type raw() const noexcept { return val; }
|
||||
constexpr integral_type raw() const noexcept { return reduce(val); }
|
||||
|
||||
/// @brief Build a field element from PRG bytes (Mersenne reduction).
|
||||
/// @param bytes the PRG output
|
||||
/// @param n the number of bytes available
|
||||
/// @return the field element
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
static fp61 from_seed(const void * bytes, std::size_t n) noexcept
|
||||
{
|
||||
unsigned char buf[16]{};
|
||||
if (n > sizeof(buf))
|
||||
n = sizeof(buf);
|
||||
std::memcpy(buf, bytes, n);
|
||||
std::uint64_t w[2]{};
|
||||
std::memcpy(w, buf, sizeof(w));
|
||||
using u128 = unsigned __int128;
|
||||
const u128 wide = static_cast<u128>(w[0])
|
||||
| (static_cast<u128>(w[1]) << 64);
|
||||
const auto lo = static_cast<integral_type>(wide) & fp61_mod;
|
||||
const auto mid = static_cast<integral_type>(wide >> 61) & fp61_mod;
|
||||
const auto hi = static_cast<integral_type>(wide >> 122);
|
||||
return fp61{lo + mid + hi};
|
||||
}
|
||||
|
||||
/// @brief Same value as `raw()`.
|
||||
/// @return the stored field element
|
||||
|
|
@ -98,7 +122,7 @@ class fp61
|
|||
HEDLEY_CONST
|
||||
friend constexpr fp61 operator+(fp61 a, fp61 b) noexcept
|
||||
{
|
||||
return fp61{a.val + b.val};
|
||||
return fp61{reduce(a.val) + reduce(b.val)};
|
||||
}
|
||||
|
||||
/// @brief Field subtraction.
|
||||
|
|
@ -110,7 +134,7 @@ class fp61
|
|||
HEDLEY_CONST
|
||||
friend constexpr fp61 operator-(fp61 a, fp61 b) noexcept
|
||||
{
|
||||
return fp61{a.val + fp61_mod - b.val};
|
||||
return fp61{reduce(a.val) + fp61_mod - reduce(b.val)};
|
||||
}
|
||||
|
||||
/// @brief Field negation.
|
||||
|
|
@ -121,7 +145,8 @@ class fp61
|
|||
HEDLEY_CONST
|
||||
friend constexpr fp61 operator-(fp61 a) noexcept
|
||||
{
|
||||
return fp61{a.val == 0 ? 0 : fp61_mod - a.val};
|
||||
const auto v = reduce(a.val);
|
||||
return fp61{v == 0 ? 0 : fp61_mod - v};
|
||||
}
|
||||
|
||||
/// @brief Field multiplication.
|
||||
|
|
@ -134,7 +159,7 @@ class fp61
|
|||
friend constexpr fp61 operator*(fp61 a, fp61 b) noexcept
|
||||
{
|
||||
using u128 = unsigned __int128;
|
||||
const u128 p = static_cast<u128>(a.val) * static_cast<u128>(b.val);
|
||||
const u128 p = static_cast<u128>(reduce(a.val)) * static_cast<u128>(reduce(b.val));
|
||||
const auto lo = static_cast<integral_type>(p) & fp61_mod;
|
||||
const auto mid = static_cast<integral_type>(p >> 61) & fp61_mod;
|
||||
const auto hi = static_cast<integral_type>(p >> 122);
|
||||
|
|
@ -150,7 +175,7 @@ class fp61
|
|||
HEDLEY_CONST
|
||||
friend constexpr bool operator==(fp61 a, fp61 b) noexcept
|
||||
{
|
||||
return a.val == b.val;
|
||||
return reduce(a.val) == reduce(b.val);
|
||||
}
|
||||
|
||||
/// @brief Field inequality.
|
||||
|
|
@ -162,7 +187,7 @@ class fp61
|
|||
HEDLEY_CONST
|
||||
friend constexpr bool operator!=(fp61 a, fp61 b) noexcept
|
||||
{
|
||||
return a.val != b.val;
|
||||
return reduce(a.val) != reduce(b.val);
|
||||
}
|
||||
|
||||
/// @brief Write the reduced representative in decimal.
|
||||
|
|
@ -195,6 +220,35 @@ struct has_characteristic_two<fp61> : std::false_type
|
|||
namespace leaf_arithmetic
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <std::size_t Lanes>
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
void fp61_lanes(const void * a, const void * b, void * out,
|
||||
fp61 (*op)(fp61, fp61)) noexcept
|
||||
{
|
||||
std::uint64_t aa[Lanes], bb[Lanes], cc[Lanes];
|
||||
std::memcpy(aa, a, sizeof(aa));
|
||||
std::memcpy(bb, b, sizeof(bb));
|
||||
for (std::size_t i = 0; i < Lanes; ++i)
|
||||
cc[i] = op(fp61{aa[i]}, fp61{bb[i]}).raw();
|
||||
std::memcpy(out, cc, sizeof(cc));
|
||||
}
|
||||
|
||||
template <std::size_t Lanes>
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
void fp61_scale(const void * a, fp61 b, void * out) noexcept
|
||||
{
|
||||
std::uint64_t aa[Lanes], cc[Lanes];
|
||||
std::memcpy(aa, a, sizeof(aa));
|
||||
for (std::size_t i = 0; i < Lanes; ++i)
|
||||
cc[i] = (fp61{aa[i]} * b).raw();
|
||||
std::memcpy(out, cc, sizeof(cc));
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
HEDLEY_PRAGMA(GCC diagnostic push)
|
||||
HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes")
|
||||
template <>
|
||||
|
|
@ -202,7 +256,11 @@ struct add_t<fp61, simde__m128i>
|
|||
{
|
||||
auto operator()(const simde__m128i & a, const simde__m128i & b) const
|
||||
{
|
||||
return add_t<fp61::integral_type, simde__m128i>{}(a, b);
|
||||
simde__m128i out;
|
||||
detail::fp61_lanes<2>(&a, &b, &out, [](fp61 x, fp61 y) {
|
||||
return x + y;
|
||||
});
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -211,7 +269,22 @@ struct subtract_t<fp61, simde__m128i>
|
|||
{
|
||||
auto operator()(const simde__m128i & a, const simde__m128i & b) const
|
||||
{
|
||||
return subtract_t<fp61::integral_type, simde__m128i>{}(a, b);
|
||||
simde__m128i out;
|
||||
detail::fp61_lanes<2>(&a, &b, &out, [](fp61 x, fp61 y) {
|
||||
return x - y;
|
||||
});
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct multiply_t<fp61, simde__m128i>
|
||||
{
|
||||
auto operator()(const simde__m128i & a, fp61 b) const
|
||||
{
|
||||
simde__m128i out;
|
||||
detail::fp61_scale<2>(&a, b, &out);
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -220,7 +293,11 @@ struct add_t<fp61, simde__m256i>
|
|||
{
|
||||
auto operator()(const simde__m256i & a, const simde__m256i & b) const
|
||||
{
|
||||
return add_t<fp61::integral_type, simde__m256i>{}(a, b);
|
||||
simde__m256i out;
|
||||
detail::fp61_lanes<4>(&a, &b, &out, [](fp61 x, fp61 y) {
|
||||
return x + y;
|
||||
});
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -229,13 +306,72 @@ struct subtract_t<fp61, simde__m256i>
|
|||
{
|
||||
auto operator()(const simde__m256i & a, const simde__m256i & b) const
|
||||
{
|
||||
return subtract_t<fp61::integral_type, simde__m256i>{}(a, b);
|
||||
simde__m256i out;
|
||||
detail::fp61_lanes<4>(&a, &b, &out, [](fp61 x, fp61 y) {
|
||||
return x - y;
|
||||
});
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct multiply_t<fp61, simde__m256i>
|
||||
{
|
||||
auto operator()(const simde__m256i & a, fp61 b) const
|
||||
{
|
||||
simde__m256i out;
|
||||
detail::fp61_scale<4>(&a, b, &out);
|
||||
return out;
|
||||
}
|
||||
};
|
||||
HEDLEY_PRAGMA(GCC diagnostic pop)
|
||||
|
||||
} // namespace leaf_arithmetic
|
||||
|
||||
/// @brief Sample a uniformly reduced field element by rejection.
|
||||
/// @return an element of the field
|
||||
template <>
|
||||
HEDLEY_NO_THROW
|
||||
inline auto uniform_sample<fp61>() noexcept
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
const auto v = uniform_sample<std::uint64_t>() & fp61_mod;
|
||||
if (v < fp61_mod)
|
||||
return fp61{v};
|
||||
}
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <>
|
||||
struct shamir_field<fp61> : std::true_type
|
||||
{
|
||||
/// @brief `a^{-1}` by Fermat, `a^{p-2}`.
|
||||
/// @param a a non-zero field element
|
||||
/// @return `a^{-1}`
|
||||
/// @throws std::invalid_argument if `a` is zero
|
||||
static fp61 inv(fp61 a)
|
||||
{
|
||||
if (a.raw() == 0)
|
||||
throw std::invalid_argument("shamir: inverse of zero");
|
||||
fp61 base = a;
|
||||
fp61 out{1};
|
||||
auto e = fp61_mod - 2;
|
||||
while (e != 0)
|
||||
{
|
||||
if (e & 1u)
|
||||
out = out * base;
|
||||
base = base * base;
|
||||
e >>= 1;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace dpf
|
||||
|
||||
#endif // LIBDPF_INCLUDE_DPF_FP61_HPP__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue