#include #include #include #include #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 = // 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; } }