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>
86 lines
3.1 KiB
C++
86 lines
3.1 KiB
C++
#include <cstdint>
|
|
#include <cstring>
|
|
#include <iostream>
|
|
#include <vector>
|
|
|
|
#include "dpf/launch.hpp"
|
|
#include "dpf/run_log.hpp"
|
|
|
|
// One party of a two- or three-party run, one process per party.
|
|
//
|
|
// c++ -std=c++17 -march=native -pthread -I include -I thirdparty \
|
|
// -DLIBDPF_GIT_REV="\"$(git describe --always --dirty)\"" \
|
|
// examples/protocol/party_node.cpp -lsctp -lssl -lcrypto -o party_node
|
|
// ./party_node --party=0 --peers=127.0.0.1:9100,127.0.0.1:9101 &
|
|
// ./party_node --party=1 --peers=127.0.0.1:9100,127.0.0.1:9101
|
|
//
|
|
// Any run_config key works as a flag (--transport=parallel --lanes=2 ...).
|
|
// Start order does not matter: connects retry until --connect_ms.
|
|
//
|
|
// Links are TLS 1.3. With no keys they are encrypted but unauthenticated (and
|
|
// the log says so). To authenticate, give each party a key and the others'
|
|
// public keys (dpf_keygen p0.key prints p0's), for example in p0.conf:
|
|
// identity = p0.key
|
|
// peer.1 = <p1's public key>
|
|
// and run ./party_node --config=p0.conf --party=0 --peers=...
|
|
// The run log goes to stderr at info; --log=file:/tmp/p0.log --log_level=debug
|
|
// or DPF_LOG / DPF_LOG_LEVEL redirect it (see dpf/run_log.hpp).
|
|
//
|
|
// With three peers the protocol adds a dealer-delivered mask: party 2 is the
|
|
// dealer, and parties 0 and 1 each open (input + mask share).
|
|
|
|
int main(int argc, char ** argv)
|
|
{
|
|
try
|
|
{
|
|
const auto args = dpf::app::parse_node_args(argc, argv);
|
|
dpf::app::start_logging(args.cfg);
|
|
const unsigned me = args.party;
|
|
const bool dealer = args.peers.size() == 3;
|
|
|
|
dpf::protocol::composer c(me);
|
|
auto x = c.input(dpf::protocol::domain::a, 8);
|
|
dpf::protocol::node opened{};
|
|
dpf::protocol::node mask{};
|
|
if (dealer)
|
|
{
|
|
auto pad = c.input(dpf::protocol::domain::a, 8);
|
|
mask = c.dealer_deliver(pad);
|
|
opened = c.exchange(x);
|
|
(void)pad;
|
|
}
|
|
else
|
|
opened = c.exchange(x);
|
|
auto plan = c.schedule();
|
|
dpf::app::party_values values(plan.nodes().size());
|
|
for (auto & v : values)
|
|
v.assign(8, 0);
|
|
const std::uint64_t mine = me == 0 ? 11 : 31;
|
|
std::memcpy(values[x.id].data(), &mine, 8);
|
|
if (dealer && me == 2)
|
|
{
|
|
const std::uint64_t pad = 7;
|
|
std::memcpy(values[plan.inputs_of(mask.id)[0]].data(), &pad, 8);
|
|
}
|
|
|
|
const auto wire = dpf::app::run_node(args, plan, values);
|
|
std::uint64_t got = 0;
|
|
std::memcpy(&got, values[opened.id].data(), 8);
|
|
std::cout << "party " << me << " open=" << got;
|
|
if (dealer && me < 2)
|
|
{
|
|
std::uint64_t m = 0;
|
|
std::memcpy(&m, values[mask.id].data(), 8);
|
|
std::cout << " mask=" << m;
|
|
}
|
|
std::cout << " wire_out=" << wire.bytes_out << " wire_in=" << wire.bytes_in
|
|
<< "\n";
|
|
return (me == 2 || got == 42) ? 0 : 1;
|
|
}
|
|
catch (const std::exception & e)
|
|
{
|
|
DPF_LOG(error, "node.failed").kv("what", e.what());
|
|
std::cerr << "party_node: " << e.what() << "\n";
|
|
return 1;
|
|
}
|
|
}
|