circom-MP-SPDZ allows parties to perform Multi-Party Computation (MPC) by writing Circom code using the MP-SPDZ framework. Circom code is converted to an arithmetic circuit and then gate by gate translated to the corresponding MP-SPDZ operators.
In the current structure, input files are not limited to MP-SPDZ and can be applied to other MPC frameworks. We can adapt generate_mpspdz_circuit
and generate_mpspdz_inputs_for_party
to support other MPC frameworks.
A computation is defined by two files: circuit.circom
and mpc_settings.json
.
circuit.circom
is an extended circom syntax, which supports more operators than the original circom. The list of supported operators can be found here. For example, it could bempc_settings.json
specifies which inputs a party should supply and which outputs a party can learn. It is an array of entries where the first entry is for party 0, the second entry is for party 1, etc. For example, it could be:This indicates that
alice
a
.a_add_b
and a_mul_c
from the computationbob
b
a_add_b
and a_mul_c
from the computationFor a computation to be successfully carried out, parties must use the same circuit.circom
and mpc_settings.json
in order to generate the same MP-SPDZ circuit.
inputs.json
: each party has an input file, containing all the values of the inputs they should supply according to mpc_settings.json
.For example, in mpc_settings.json
party 0 is assigned to supply a
and party 1 assigned to supply b
.
inputs.json
for party 0 should contain the value of a
inputs.json
for party 1 should contain the value of b
Each party follows the following steps to perform a computation:
circom-2-arithc converts circuit.circom
to circuit.txt
, a bristol fashion circuit with gates sorted in topological order. With this order, all inputs to a gate are available when the gate is executed. We can safely execute gates in this order. For example, circuit.txt
would look like this:
Another file circuit_info.json
is also generated. It tells us how to interpret the wires in the bristol fashion circuit - which wires the inputs and outputs correspond to, and which wires are constants and can be assigned with values directly. For example,
This means that the wire with index 1 is the input a
, the wire with index 0 is the input b
, the wire with index 2 is the constant c
with value 3
, the wire with index 3 is the output a_add_b
, and the wire with index 4 is the output a_mul_c
.
generate_mpspdz_circuit
generates a MP-SPDZ circuit Circuits/circuit.mpc
under the MP-SPDZ project root. It translates each gate to their corresponding MP-SPDZ operator. For example, the above bristol fashion circuit is converted to the following MP-SPDZ circuit:
In the code above,
wires
is a list with 5 elements. According to circuit_info.json
and mpc_settings.json
,
wires[0]
is b
and it should be supplied by party 1wires[1]
is a
and it should be supplied by party 0wires[2]
is c
and it's a constant with value 3
wires[3]
is a_add_b
and it is None
because it should be computed in the following gateswires[4]
is a_mul_c
and it is None
because it should be computed in the following gateswires[3] = wires[1] + wires[0]
is the translation of the AAdd
gate to the +
operator in MP-SPDZ. wires[4] = wires[1] * wires[2]
is the translation of the AMul
gate to the *
operator in MP-SPDZ.print_ln_to(0, 'outputs[0]: a_add_b=%s', wires[3].reveal_to(0))
prints the value of a_add_b
to party 0, as defined in mpc_settings.json
, etc.Each party translates their inputs.json
to the format MP-SPDZ requires by running generate_mpspdz_inputs_for_party
with circuit_info.json
and mpc_settings.json
as inputs. The generated input file is stored in Player-Data/Input-P{party}-0
under the MP-SPDZ project root.
For example, the above inputs.json
for party 0 is converted to Player-Data/Input-P0-0
and the above inputs.json
for party 1 is converted to Player-Data/Input-P1-0
With the generated circuit and inputs for MP-SPDZ, parties can run MP-SPDZ and get the computation result.
For testing, you can run all parties in your local machine. Or, each party can run on different machines and interact with each other through the network.
First, go to the project root of MP-SPDZ.
Run all parties in your local machine with the script
where {mpc_protocol}
is a protocol supported by MP-SPDZ you want to use (e.g., semi
, mascot
, etc). {circuit_name}
is the name of the circuit you want to run. For example, to run circuit.mpc
with semi
protocol:
For each party, run the following commands in the MP-SPDZ project root:
Step 1: Compile the VM for semi
protocol
Step 2: Compile the circuit circuit.mpc
to bytecode
Step 3: Create a file with the IP addresses of all parties. For example, a file hosts
with the following content:
it means party 0 will listen to 18.183.238.119:3000
and party 1 to 43.207.105.60:4000
. Note that all parties must use the same file.
Step 4: Run the party with the VM and bytecode. For example, to run party 0 with circuit.mpc
:
and party 1:
where
-N 2
: there are two parties-p 1
: this is party 0-OF .
: outputs are printed to stdoutOutputs are printed to the console. For example, both party 0 and 1 will see the outputsa_add_b
and a_mul_c
:
due to the settings we have in mpc_settings.json
.