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:
Ryan Henry 2026-09-28 05:59:19 -06:00
parent 695f8e84f7
commit 0d22946a0e
1835 changed files with 170291 additions and 2849 deletions

View file

@ -4,6 +4,8 @@
/// defines `half_tree_tag` (e.g. `prg::aes128_ccr`) opts into the
/// Guo et al. Half-Tree mid-level expand / CW / advance, with a
/// two-tweak last level that keeps BGI-style advice packing.
/// @note Default expand: Boyle, Gilboa, and Ishai, CCS 2016 (full version ePrint 2018/707).
/// @note Best known (same model), selected by `half_tree_tag`: Guo, Yang, Wang, Zhang, Xie, Zhang, and Liu, ePrint 2022/1431. Their dealer point key keeps the CCS 2016 length and the n-hash point evaluation; they state about 2n+2 random-permutation calls to generate a key versus about 4n, and 1.5N calls for a full-domain evaluation versus 2N.
/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors)
/// @license Released under a GNU General Public v2.0 (GPLv2) license;
/// see [LICENSE.md](@ref license) for details.
@ -27,6 +29,15 @@
namespace dpf
{
template <typename P, typename = void>
struct prg_has_indep4 : std::false_type {};
template <typename P>
struct prg_has_indep4<P, std::void_t<decltype(P::eval_indep4(
std::declval<const typename P::block_type *>(),
std::declval<const psnip_uint32_t *>(),
std::declval<typename P::block_type *>()))>> : std::true_type {};
/// @brief Walk policy for interior DPF levels. Specialized when `PRG::half_tree_tag`
/// exists.
/// @tparam PRG pseudorandom generator
@ -145,17 +156,78 @@ struct tree_traits
node cw, psnip_uint8_t advice, bool dir,
bool parent_control, bool /*is_last*/ = false) noexcept
{
(void)parent;
const node packed = pack_cw(cw, advice, dir);
return dpf::xor_if(kids[dir ? 1u : 0u], packed, parent_control);
}
/// @brief One child only: `PRG::eval(cleared, dir)` instead of `eval01`.
/// @details Path walks never need the sibling. Interval/full use
/// `traverse01` / `traverse01_x4` when both children are live.
HEDLEY_NO_THROW
HEDLEY_ALWAYS_INLINE
static node traverse(node parent, node cw_packed, bool dir,
bool /*is_last*/ = false) noexcept
{
auto kids = expand(parent, false);
return dpf::xor_if_lo_bit(kids[dir ? 1u : 0u], cw_packed, parent);
const node child = PRG::eval(dpf::unset_lo_2bits(parent),
static_cast<psnip_uint32_t>(dir ? 1 : 0));
return dpf::xor_if_lo_bit(child, cw_packed, parent);
}
/// @brief Four independent one-child steps. Same result as `traverse`.
/// @details Interleaves the PRG when `PRG::eval_indep4` exists so a
/// strided sequence is not limited by single-block AES latency.
HEDLEY_NO_THROW
HEDLEY_ALWAYS_INLINE
static void traverse4(const node parents[4], const node cws[4],
const bool dirs[4], node out[4]) noexcept
{
if constexpr (prg_has_indep4<PRG>::value)
{
node seeds[4];
psnip_uint32_t pos[4];
for (int i = 0; i < 4; ++i)
{
seeds[i] = dpf::unset_lo_2bits(parents[i]);
pos[i] = dirs[i] ? 1u : 0u;
}
node kids[4];
PRG::eval_indep4(seeds, pos, kids);
for (int i = 0; i < 4; ++i)
out[i] = dpf::xor_if_lo_bit(kids[i], cws[i], parents[i]);
}
else
{
for (int i = 0; i < 4; ++i)
out[i] = traverse(parents[i], cws[i], dirs[i]);
}
}
/// @brief Eight independent one-child steps. Same result as `traverse`.
HEDLEY_NO_THROW
HEDLEY_ALWAYS_INLINE
static void traverse8(const node parents[8], const node cws[8],
const bool dirs[8], node out[8]) noexcept
{
if constexpr (prg_has_indep4<PRG>::value)
{
node seeds[8];
psnip_uint32_t pos[8];
for (int i = 0; i < 8; ++i)
{
seeds[i] = dpf::unset_lo_2bits(parents[i]);
pos[i] = dirs[i] ? 1u : 0u;
}
node kids[8];
PRG::eval_indep8(seeds, pos, kids);
for (int i = 0; i < 8; ++i)
out[i] = dpf::xor_if_lo_bit(kids[i], cws[i], parents[i]);
}
else
{
for (int i = 0; i < 8; ++i)
out[i] = traverse(parents[i], cws[i], dirs[i]);
}
}
HEDLEY_NO_THROW
@ -330,19 +402,32 @@ HEDLEY_PRAGMA(GCC diagnostic pop)
node cw, psnip_uint8_t advice, bool dir, bool parent_control,
bool is_last = false) noexcept
{
(void)parent;
// Mid and last: select child[dir], XOR packed CW if parent control set.
// Mid Half-Tree: child[1]=H⊕s so this is `h ⊕ (dir?s:0) ⊕ (t?cw:0)`.
const node packed = pack_cw(cw, advice, dir, is_last);
return dpf::xor_if(kids[dir ? 1u : 0u], packed, parent_control);
}
/// @brief One child only. Mid: one CCR hash (+ optional ⊕s). Last: one
/// two-tweak hash instead of both.
HEDLEY_NO_THROW
HEDLEY_ALWAYS_INLINE
static node traverse(node parent, node cw_packed, bool dir,
bool is_last = false) noexcept
{
auto kids = expand(parent, is_last);
return dpf::xor_if_lo_bit(kids[dir ? 1u : 0u], cw_packed, parent);
node child;
if (is_last)
{
const node base = dpf::unset_lo_bit(parent);
child = dir ? PRG::hash(dpf::set_lo_bit(base)) : PRG::hash(base);
}
else
{
const node h = PRG::hash(parent);
child = dir ? simde_mm_xor_si128(h, parent) : h;
}
return dpf::xor_if_lo_bit(child, cw_packed, parent);
}
HEDLEY_NO_THROW