Which version do I want?
- Existing projects pinned to a published release: stay on
0.3.0— branchv0.3.x. Bug fixes and security patches will be backported tov0.3.x.- New projects, or able to track a moving API: use the development branch (this branch,
main). It will become1.0.0-alphaafter a polish pass and then1.0.0. Builds against emp-tool / emp-ot ≥ 1.0 (unifiedBackendexecution layer, de-templated IO and OT) — but the API is not yet frozen and headers may move between alphas. Requires emp-tool ≥ 1.0.0-alpha and emp-ot ≥ 1.0.0-alpha.
Header-only semi-honest 2PC built on top of emp-tool and emp-ot: garbled-circuit evaluation (half-gates) for Bit / Integer / Float over a NetIO channel, with batched IKNP COT for input wires.
The public handle is one session, SH2PCSession: it owns the IO channel and all
protocol state, and sess.ctx() is the gate context your values are built over.
#include <emp-sh2pc/emp-sh2pc.h>
using namespace emp;
int party = parse_party(argv); // argv[1]; port/IP come from $EMP_PORT / $EMP_PEER_IP
NetIO io(party == ALICE ? nullptr : peer_ip(), peer_port());
SH2PCSession sess(&io, party);
using Ctx = SH2PCSession::ctx_t; // the gate context values are built over
using UInt32 = UInt_T<Ctx, 32>;
auto a = sess.input<UInt32>(ALICE, av); // each party owns its input
auto b = sess.input<UInt32>(BOB, bv);
auto c = a + b; // eager half-gate over sess.ctx()
uint32_t out = sess.reveal(c, PUBLIC).value(); // open the result to both partiesreveal returns std::optional<clear_t>: the value on a party that learns it —
every party for PUBLIC, the named recipient for reveal(v, ALICE) / reveal(v, BOB),
both parties (each its own secret-share) for reveal(v, XOR) — and std::nullopt
on a party that does not. The session names no value family — circuit values are
emp-tool's context-bound types (UInt_T<Ctx,N>, Int_T<Ctx,N>, Float_T<Ctx,W>,
BitVec_T<Ctx,N>, Bit_T<Ctx>), and input/reveal are generic over any WireValue.
Public constants use UInt32::constant(sess.ctx(), 1). A reusable circuit is
compiled once with the emp-tool frontend and replayed over the session's context with
frontend::run(sess.ctx(), circuit, args...). There is no global backend — the
session is explicit.
- CMake ≥ 3.21
- A C++20 compiler (Clang ≥ 14, GCC ≥ 10, AppleClang 14+)
- emp-tool ≥ 1.0
- emp-ot ≥ 1.0
- pthreads
emp-sh2pc is header-only; the build produces test executables only.
emp-sh2pc consumes emp-tool and emp-ot through their installed CMake packages. Install both first, then build emp-sh2pc the same way:
# emp-tool
git clone https://github.com/emp-toolkit/emp-tool.git
cmake -S emp-tool -B emp-tool/build -DCMAKE_BUILD_TYPE=Release
cmake --build emp-tool/build -j
cmake --install emp-tool/build # respects CMAKE_INSTALL_PREFIX
# emp-ot
git clone https://github.com/emp-toolkit/emp-ot.git
cmake -S emp-ot -B emp-ot/build -DCMAKE_BUILD_TYPE=Release
cmake --build emp-ot/build -j
cmake --install emp-ot/build
# emp-sh2pc
git clone https://github.com/emp-toolkit/emp-sh2pc.git
cmake -S emp-sh2pc -B emp-sh2pc/build -DCMAKE_BUILD_TYPE=Release
cmake --build emp-sh2pc/build -j
cmake --install emp-sh2pc/buildIf you don't want to install the dependencies, point emp-sh2pc directly at sibling build trees:
cmake -S emp-sh2pc -B emp-sh2pc/build \
-DCMAKE_BUILD_TYPE=Release \
-Demp-tool_DIR=$PWD/emp-tool/build \
-Demp-ot_DIR=$PWD/emp-ot/build
cmake --build emp-sh2pc/build -jTests live under test/ and ship as executables in build/. Both
parties run on localhost for local testing, joined by the ./run
wrapper script.
-
Local machine, both parties on
localhost:./run ./build/[binary] [more opts]e.g.
./run ./build/test_bitor./run ./build/test_example 123. -
Two machines: the shared port is
$EMP_PORT(default 12345) and party 2 dials$EMP_PEER_IP; only the party id is a positional arg:./build/[binary] 1 [more opts]on one machine andEMP_PEER_IP=<party-1-ip> ./build/[binary] 2 [more opts]on the other. -
test_exampletakes a per-party integer; the two parties must use different numbers:./build/test_example 1 123 & EMP_PEER_IP=<party-1-ip> ./build/test_example 2 124
ctest --test-dir build --output-on-failure runs the entire suite.
Downstream CMake projects link against the emp-sh2pc::emp-sh2pc
INTERFACE target, which transitively brings in
emp-ot::emp-ot and emp-tool::emp-tool:
find_package(emp-sh2pc 1.0 REQUIRED)
target_link_libraries(my-app PRIVATE emp-sh2pc::emp-sh2pc)Please send email to wangxiao@cs.northwestern.edu
This work was supported in part by the National Science Foundation under Awards #1111599 and #1563722.
Licensed under the Apache License, Version 2.0 — see LICENSE.
