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
131
examples/mwe/chooser.html
Normal file
131
examples/mwe/chooser.html
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
<div class="chooser">
|
||||
<p class="q">Who knows the secret index?</p>
|
||||
<input type="radio" name="holder" id="h-dealer">
|
||||
<label class="choice" for="h-dealer"><strong>A dealer</strong><span>knows alpha and beta, and hands each party a key</span></label>
|
||||
<input type="radio" name="holder" id="h-share">
|
||||
<label class="choice" for="h-share"><strong>The two parties</strong><span>already share alpha. They want a key they can reuse</span></label>
|
||||
<input type="radio" name="holder" id="h-answer">
|
||||
<label class="choice" for="h-answer"><strong>The two parties</strong><span>already share alpha. They want the answer, not a key</span></label>
|
||||
<input type="radio" name="holder" id="h-three">
|
||||
<label class="choice" for="h-three"><strong>Three evaluators</strong><span>any two of them can open the value</span></label>
|
||||
<div class="branch branch-dealer">
|
||||
<p class="q">What should be nonzero?</p>
|
||||
<input type="radio" name="dealer-what" id="d-point">
|
||||
<label class="choice" for="d-point"><strong>One point</strong><span>beta at alpha, zero elsewhere</span></label>
|
||||
<input type="radio" name="dealer-what" id="d-cmp">
|
||||
<label class="choice" for="d-cmp"><strong>A comparison</strong><span>1 where x is above alpha</span></label>
|
||||
<input type="radio" name="dealer-what" id="d-ic">
|
||||
<label class="choice" for="d-ic"><strong>A public interval</strong><span>beta on a span of the unmasked input</span></label>
|
||||
<div class="result result-point">
|
||||
<h3>dpf::make_dpf</h3>
|
||||
<p>Dealer point key. Leaf shares are subtractive, so reconstruct subtracts them. This prints <code>7 0</code>.</p>
|
||||
<p><a href="incremental_8hpp.html">dpf/incremental.hpp</a></p>
|
||||
<button type="button" class="mwe-copy">Copy</button>
|
||||
<pre class="mwe"><code>#include <cstdint>
|
||||
#include <iostream>
|
||||
#include "dpf.hpp"
|
||||
int main()
|
||||
{
|
||||
const std::uint8_t alpha = 42;
|
||||
const std::uint64_t beta = 7;
|
||||
auto [k0, k1] = dpf::make_dpf(alpha, beta);
|
||||
const std::uint64_t at = dpf::reconstruct(
|
||||
*dpf::eval_point(k0, alpha),
|
||||
*dpf::eval_point(k1, alpha));
|
||||
const std::uint64_t off = dpf::reconstruct(
|
||||
*dpf::eval_point(k0, std::uint8_t{0}),
|
||||
*dpf::eval_point(k1, std::uint8_t{0}));
|
||||
std::cout << at << " " << off << "\n";
|
||||
return (at == beta && off == 0) ? 0 : 1;
|
||||
}</code></pre>
|
||||
<p class="mwe-cmd"><code>c++ -std=c++17 -march=native -I include -I thirdparty examples/mwe/point.cpp</code></p>
|
||||
</div>
|
||||
<div class="result result-cmp">
|
||||
<h3>dpf::gt</h3>
|
||||
<p>One comparison on the same key. Comparison shares are additive, so reconstruct adds them. This prints <code>1 0</code>.</p>
|
||||
<p><a href="dcf_8hpp.html">dpf/dcf.hpp</a></p>
|
||||
<button type="button" class="mwe-copy">Copy</button>
|
||||
<pre class="mwe"><code>#include <cstdint>
|
||||
#include <iostream>
|
||||
#include "dpf.hpp"
|
||||
int main()
|
||||
{
|
||||
const std::uint8_t alpha = 40;
|
||||
auto [k0, k1] = dpf::make_dpf(alpha, dpf::gt(std::uint64_t{1}));
|
||||
const auto above = dpf::reconstruct(
|
||||
dpf::eval_point(dpf::cmp, k0, std::uint8_t{50}),
|
||||
dpf::eval_point(dpf::cmp, k1, std::uint8_t{50}));
|
||||
const auto below = dpf::reconstruct(
|
||||
dpf::eval_point(dpf::cmp, k0, std::uint8_t{10}),
|
||||
dpf::eval_point(dpf::cmp, k1, std::uint8_t{10}));
|
||||
std::cout << above << " " << below << "\n";
|
||||
return (above == 1 && below == 0) ? 0 : 1;
|
||||
}</code></pre>
|
||||
<p class="mwe-cmd"><code>c++ -std=c++17 -march=native -I include -I thirdparty examples/mwe/compare.cpp</code></p>
|
||||
</div>
|
||||
<div class="result result-ic">
|
||||
<h3>dpf::ic</h3>
|
||||
<p>The secret is a mask. The public interval is on <code>x - r</code>. This prints <code>9 0</code>: 14 - 10 = 4, which sits in [3, 5].</p>
|
||||
<p><a href="interval_8hpp.html">dpf/interval.hpp</a></p>
|
||||
<button type="button" class="mwe-copy">Copy</button>
|
||||
<pre class="mwe"><code>#include <cstdint>
|
||||
#include <iostream>
|
||||
#include "dpf.hpp"
|
||||
int main()
|
||||
{
|
||||
const std::uint8_t r = 10;
|
||||
const std::uint64_t beta = 9;
|
||||
auto [k0, k1] = dpf::make_dpf(r, dpf::ic(std::uint8_t{3}, std::uint8_t{5}, beta));
|
||||
const auto inside = dpf::reconstruct(
|
||||
dpf::eval_point(dpf::ic, k0, std::uint8_t{14}),
|
||||
dpf::eval_point(dpf::ic, k1, std::uint8_t{14}));
|
||||
const auto outside = dpf::reconstruct(
|
||||
dpf::eval_point(dpf::ic, k0, std::uint8_t{0}),
|
||||
dpf::eval_point(dpf::ic, k1, std::uint8_t{0}));
|
||||
std::cout << inside << " " << outside << "\n";
|
||||
return (inside == beta && outside == 0) ? 0 : 1;
|
||||
}</code></pre>
|
||||
<p class="mwe-cmd"><code>c++ -std=c++17 -march=native -I include -I thirdparty examples/mwe/interval.cpp</code></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="branch branch-share">
|
||||
<h3>dpf::make_dpf_doerner_shelat</h3>
|
||||
<p>Each party holds an XOR share of alpha. A pad dealer supplies the tape and does not learn alpha. The key is reusable. This prints <code>7</code>.</p>
|
||||
<p><a href="doerner__shelat_8hpp.html">dpf/doerner_shelat.hpp</a></p>
|
||||
<button type="button" class="mwe-copy">Copy</button>
|
||||
<pre class="mwe"><code>#include <cstdint>
|
||||
#include <iostream>
|
||||
#include "dpf.hpp"
|
||||
int main()
|
||||
{
|
||||
const std::uint8_t alpha = 42;
|
||||
const std::uint64_t beta = 7;
|
||||
const std::uint8_t x0 = 7;
|
||||
const std::uint8_t x1 = static_cast<std::uint8_t>(alpha ^ x0);
|
||||
auto root = []() { return dpf::uniform_sample<simde__m128i>(); };
|
||||
struct pad {
|
||||
simde__m128i block() { return dpf::uniform_sample<simde__m128i>(); }
|
||||
std::uint8_t bit() {
|
||||
return static_cast<std::uint8_t>(dpf::uniform_sample<unsigned>() & 1u);
|
||||
}
|
||||
};
|
||||
dpf::ds_randomness<decltype(root), pad> rng{root, {}};
|
||||
auto keys = dpf::make_dpf_doerner_shelat(x0, x1, rng, beta);
|
||||
const std::uint64_t opened = dpf::reconstruct(
|
||||
*dpf::eval_point(keys.first, alpha),
|
||||
*dpf::eval_point(keys.second, alpha));
|
||||
std::cout << opened << "\n";
|
||||
return opened == beta ? 0 : 1;
|
||||
}</code></pre>
|
||||
<p class="mwe-cmd"><code>c++ -std=c++17 -march=native -I include -I thirdparty examples/mwe/shared_index.cpp</code></p>
|
||||
</div>
|
||||
<div class="branch branch-answer">
|
||||
<h3>dpf::geneval_point</h3>
|
||||
<p>Same share convention as the reusable key, and the parties open the value along the query. The call does not hand back a key you can evaluate again. The openings are on <a href="geneval_8hpp.html">dpf/geneval.hpp</a>: <code>geneval_point</code>, <code>geneval_interval</code>, <code>geneval_sequence</code>, <code>geneval_full</code>, and <code>geneval_cmp</code>.</p>
|
||||
</div>
|
||||
<div class="branch branch-three">
|
||||
<h3>dpf::make_dpf3</h3>
|
||||
<p>Three evaluators, any two open. Spines are Shamir shares in <code>fp61</code>. The dealerless form is <code>make_dpf3_doerner_shelat</code>. Comparisons for that setting are <code>make_dpf3_cmp</code> and <code>make_dpf3_ic</code>.</p>
|
||||
<p><a href="dpf3_8hpp.html">dpf/dpf3.hpp</a> · <a href="dpf3__cmp_8hpp.html">dpf/dpf3_cmp.hpp</a></p>
|
||||
</div>
|
||||
</div>
|
||||
24
examples/mwe/compare.cpp
Normal file
24
examples/mwe/compare.cpp
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#include <cstdint>
|
||||
#include <iostream>
|
||||
|
||||
#include "dpf.hpp"
|
||||
|
||||
// Complete program. Comparison shares are additive: reconstruct is share0 + share1.
|
||||
// gt(1) is 1 where x > alpha and 0 elsewhere.
|
||||
//
|
||||
// c++ -std=c++17 -march=native -I include -I thirdparty examples/mwe/compare.cpp
|
||||
int main()
|
||||
{
|
||||
const std::uint8_t alpha = 40;
|
||||
auto [k0, k1] = dpf::make_dpf(alpha, dpf::gt(std::uint64_t{1}));
|
||||
|
||||
const auto above = dpf::reconstruct(
|
||||
dpf::eval_point(dpf::cmp, k0, std::uint8_t{50}),
|
||||
dpf::eval_point(dpf::cmp, k1, std::uint8_t{50}));
|
||||
const auto below = dpf::reconstruct(
|
||||
dpf::eval_point(dpf::cmp, k0, std::uint8_t{10}),
|
||||
dpf::eval_point(dpf::cmp, k1, std::uint8_t{10}));
|
||||
|
||||
std::cout << above << " " << below << "\n";
|
||||
return (above == 1 && below == 0) ? 0 : 1;
|
||||
}
|
||||
28
examples/mwe/interval.cpp
Normal file
28
examples/mwe/interval.cpp
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#include <cstdint>
|
||||
#include <iostream>
|
||||
|
||||
#include "dpf.hpp"
|
||||
|
||||
// Complete program. The secret is a mask r. The public interval is [p, q]
|
||||
// on the unmasked input x - r. ic returns `beta` inside that interval.
|
||||
//
|
||||
// c++ -std=c++17 -march=native -I include -I thirdparty examples/mwe/interval.cpp
|
||||
int main()
|
||||
{
|
||||
const std::uint8_t r = 10;
|
||||
const std::uint8_t p = 3;
|
||||
const std::uint8_t q = 5;
|
||||
const std::uint64_t beta = 9;
|
||||
auto [k0, k1] = dpf::make_dpf(r, dpf::ic(p, q, beta));
|
||||
|
||||
// x = 14 means x - r = 4, which is inside [3, 5].
|
||||
const auto inside = dpf::reconstruct(
|
||||
dpf::eval_point(dpf::ic, k0, std::uint8_t{14}),
|
||||
dpf::eval_point(dpf::ic, k1, std::uint8_t{14}));
|
||||
const auto outside = dpf::reconstruct(
|
||||
dpf::eval_point(dpf::ic, k0, std::uint8_t{0}),
|
||||
dpf::eval_point(dpf::ic, k1, std::uint8_t{0}));
|
||||
|
||||
std::cout << inside << " " << outside << "\n";
|
||||
return (inside == beta && outside == 0) ? 0 : 1;
|
||||
}
|
||||
24
examples/mwe/point.cpp
Normal file
24
examples/mwe/point.cpp
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#include <cstdint>
|
||||
#include <iostream>
|
||||
|
||||
#include "dpf.hpp"
|
||||
|
||||
// Complete program. Leaf shares are subtractive: reconstruct is share0 - share1.
|
||||
//
|
||||
// c++ -std=c++17 -march=native -I include -I thirdparty examples/mwe/point.cpp
|
||||
int main()
|
||||
{
|
||||
const std::uint8_t alpha = 42;
|
||||
const std::uint64_t beta = 7;
|
||||
auto [k0, k1] = dpf::make_dpf(alpha, beta);
|
||||
|
||||
const std::uint64_t at = dpf::reconstruct(
|
||||
*dpf::eval_point(k0, alpha),
|
||||
*dpf::eval_point(k1, alpha));
|
||||
const std::uint64_t off = dpf::reconstruct(
|
||||
*dpf::eval_point(k0, std::uint8_t{0}),
|
||||
*dpf::eval_point(k1, std::uint8_t{0}));
|
||||
|
||||
std::cout << at << " " << off << "\n";
|
||||
return (at == beta && off == 0) ? 0 : 1;
|
||||
}
|
||||
43
examples/mwe/shamir.cpp
Normal file
43
examples/mwe/shamir.cpp
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
|
||||
#include "dpf.hpp"
|
||||
|
||||
// (K,N) Shamir. The secret is the constant term of a degree K-1 polynomial.
|
||||
// Party i holds that polynomial at x = i+1. Any K shares open it. (2,3) is
|
||||
// shamir_share: make_shamir_shares(secret, slope) is deal<T, 2, 3>.
|
||||
// fp61 and gf2n both open. For gf2n, N must be less than 2^k.
|
||||
//
|
||||
// c++ -std=c++17 -march=native -I include -I thirdparty examples/mwe/shamir.cpp
|
||||
|
||||
int main()
|
||||
{
|
||||
using F = dpf::fp61;
|
||||
const F secret{10};
|
||||
// p(x) = 10 + 2x + 3x^2. Parties 0, 2, and 4 are enough.
|
||||
const std::array<F, 2> coeff{{F{2}, F{3}}};
|
||||
auto shares = dpf::make_shamir_shares<3, 5>(secret, coeff);
|
||||
const F opened = dpf::shamir::reconstruct(
|
||||
std::get<0>(shares), std::get<2>(shares), std::get<4>(shares));
|
||||
|
||||
const F slope{3};
|
||||
auto [s0, s1, s2] = dpf::make_shamir_shares(secret, slope);
|
||||
static_assert(std::is_same_v<decltype(s0), dpf::shamir::share<F, 0, 2, 3>>);
|
||||
const F opened23 = dpf::reconstruct(s1, s2);
|
||||
const bool on_line = s0.raw() == secret + slope * F{1}
|
||||
&& s2.raw() == secret + slope * F{3};
|
||||
|
||||
using G = dpf::gf28;
|
||||
auto [g0, g1, g2] = dpf::make_shamir_shares(G{0x1b}, G{0x5a});
|
||||
const G gopen = dpf::reconstruct(g0, g2);
|
||||
const G gopen13 = dpf::reconstruct(g1, g2);
|
||||
|
||||
std::cout << opened.raw() << " " << opened23.raw() << " "
|
||||
<< static_cast<unsigned>(gopen.raw()) << "\n";
|
||||
return (opened == secret && opened23 == secret && on_line
|
||||
&& gopen == G{0x1b} && gopen13 == G{0x1b})
|
||||
? 0 : 1;
|
||||
}
|
||||
36
examples/mwe/shared_index.cpp
Normal file
36
examples/mwe/shared_index.cpp
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#include <cstdint>
|
||||
#include <iostream>
|
||||
|
||||
#include "dpf.hpp"
|
||||
|
||||
// Complete program. The parties already hold XOR shares of alpha.
|
||||
// The pad stream is local here; a real protocol would draw it from a dealer
|
||||
// who never sees alpha.
|
||||
//
|
||||
// c++ -std=c++17 -march=native -I include -I thirdparty examples/mwe/shared_index.cpp
|
||||
int main()
|
||||
{
|
||||
const std::uint8_t alpha = 42;
|
||||
const std::uint64_t beta = 7;
|
||||
const std::uint8_t x0 = 7;
|
||||
const std::uint8_t x1 = static_cast<std::uint8_t>(alpha ^ x0);
|
||||
|
||||
auto root = []() { return dpf::uniform_sample<simde__m128i>(); };
|
||||
struct pad
|
||||
{
|
||||
simde__m128i block() { return dpf::uniform_sample<simde__m128i>(); }
|
||||
std::uint8_t bit()
|
||||
{
|
||||
return static_cast<std::uint8_t>(dpf::uniform_sample<unsigned>() & 1u);
|
||||
}
|
||||
};
|
||||
dpf::ds_randomness<decltype(root), pad> rng{root, {}};
|
||||
|
||||
auto keys = dpf::make_dpf_doerner_shelat(x0, x1, rng, beta);
|
||||
const std::uint64_t opened = dpf::reconstruct(
|
||||
*dpf::eval_point(keys.first, alpha),
|
||||
*dpf::eval_point(keys.second, alpha));
|
||||
|
||||
std::cout << opened << "\n";
|
||||
return opened == beta ? 0 : 1;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue