Git Product home page Git Product logo

data61 / mp-spdz Goto Github PK

View Code? Open in Web Editor NEW

This project forked from bristolcrypto/spdz-2

895.0 21.0 277.0 19.12 MB

Versatile framework for multi-party computation

License: Other

C++ 64.26% Python 33.30% C 1.37% Makefile 0.34% Shell 0.51% Dockerfile 0.21%
mpc privacy-enhancing-technologies multi-party-computation multiparty-computation secret-sharing garbled-circuits secure-computation threshold-cryptography secure-multiparty-computation confidential-computing secure-multi-party-computation smpc

mp-spdz's Introduction

Multi-Protocol SPDZ Documentation Status Build Status Gitter

This is a software to benchmark various secure multi-party computation (MPC) protocols in a variety of security models such as honest and dishonest majority, semi-honest/passive and malicious/active corruption. The underlying technologies span secret sharing, homomorphic encryption, and garbled circuits.

Contact

Filing an issue on GitHub is the preferred way of contacting us, but you can also write an email to [email protected] (archive). Before reporting a problem, please check against the list of known issues and possible solutions.

Filing Issues

Please file complete code examples because it's usually not possible to reproduce problems from incomplete code, and please include which protocol you have used (if applicable) because there are considerable differences between the various protocols.

Frequently Asked Questions

The documentation contains section on a number of frequently asked topics as well as information on how to solve common issues.

TL;DR (Binary Distribution on Linux or Source Distribution on macOS)

This requires either a Linux distribution originally released 2018 or later (glibc 2.18) or macOS High Sierra or later as well as Python 3 and basic command-line utilities.

Download and unpack the distribution, then execute the following from the top folder:

Scripts/tldr.sh
echo 1 2 3 4 > Player-Data/Input-P0-0
echo 1 2 3 4 > Player-Data/Input-P1-0
Scripts/compile-run.py -E mascot tutorial

This runs the tutorial with two parties and malicious security.

TL;DR (Source Distribution)

On Linux, this requires a working toolchain and all requirements. On Ubuntu, the following might suffice:

sudo apt-get install automake build-essential clang cmake git libboost-dev libboost-iostreams-dev libboost-thread-dev libgmp-dev libntl-dev libsodium-dev libssl-dev libtool python3

On MacOS, this requires brew to be installed, which will be used for all dependencies. It will execute the tutorial with two parties and malicious security.

make setup
echo 1 2 3 4 > Player-Data/Input-P0-0
echo 1 2 3 4 > Player-Data/Input-P1-0
Scripts/compile-run.py mascot tutorial

On strong enough hardware setups (several cores and GB of RAM), you can speed up the last step by running make -j8 mascot-party.x beforehand.

TL;DR (Docker)

Build a docker image for mascot-party.x:

docker build --tag mpspdz:mascot-party --build-arg machine=mascot-party.x .

Run the the tutorial:

docker run --rm -it mpspdz:mascot-party ./Scripts/compile-run.py mascot tutorial

See the Dockerfile for examples of how it can be used.

Preface

The primary aim of this software is to run the same computation in various protocols in order to compare the performance. All protocols in the matrix below are fully implemented. However, this does not mean that the software has undergone a security review as should be done with critical production code.

Protocols

The following table lists all protocols that are fully supported.

Security model Mod prime / GF(2^n) Mod 2^k Bin. SS Garbling
Malicious, dishonest majority MASCOT / LowGear / HighGear SPDZ2k Tiny / Tinier BMR
Covert, dishonest majority CowGear / ChaiGear N/A N/A N/A
Semi-honest, dishonest majority Semi / Hemi / Temi / Soho Semi2k SemiBin Yao's GC / BMR
Malicious, honest majority Shamir / Rep3 / PS / SY Brain / Rep3 / PS / SY Rep3 / CCD / PS BMR
Semi-honest, honest majority Shamir / ATLAS / Rep3 Rep3 Rep3 / CCD BMR
Malicious, honest supermajority Rep4 Rep4 Rep4 N/A
Semi-honest, dealer Dealer Dealer Dealer N/A

Modulo prime and modulo 2^k are the two settings that allow integer-like computation. For k = 64, the latter corresponds to the computation available on the widely used 64-bit processors. GF(2^n) denotes Galois extension fields of order 2^n, which are different to computation modulo 2^n. In particular, every element has an inverse, which is not the case modulo 2^n. See this article for an introduction. Modulo prime and GF(2^n) are lumped together because the protocols are very similar due to the mathematical properties.

Bin. SS stands for binary secret sharing, that is secret sharing modulo two. In some settings, this requires specific protocols as some protocols require the domain size to be larger than two. In other settings, the protocol is the same mathematically speaking, but a specific implementation allows for optimizations such as using the inherent parallelism of bit-wise operations on machine words.

A security model specifies how many parties are "allowed" to misbehave in what sense. Malicious means that not following the protocol will at least be detected while semi-honest means that even corrupted parties are assumed to follow the protocol. See this paper for an explanation of the various security models and a high-level introduction to multi-party computation.

Finding the most efficient protocol

Lower security requirements generally allow for more efficient protocols. Within the same security model (line in the table above), there are a few things to consider:

  • Computation domain: Arithmetic protocols (modulo prime or power of two) are preferable for many applications because they offer integer addition and multiplication at low cost. However, binary circuits might be a better option if there is very little integer computation. See below to find the most efficient mixed-circuit variant. Furthermore, local computation modulo a power of two is cheaper, but MP-SPDZ does not offer this domain with homomorphic encryption.

  • Secret sharing vs garbled circuits: Computation using secret sharing requires a number of communication rounds that grows depending on the computation, which is not the case for garbled circuits. However, the cost of integer computation as a binary circuit often offset this. MP-SPDZ only offers garbled circuit with binary computation.

  • Underlying technology for dishonest majority: While secret sharing alone suffice honest-majority computation, dishonest majority requires either homomorphic encryption (HE) or oblivious transfer (OT). The two options offer a computation-communication trade-off: While OT is easier to compute, HE requires less communication. Furthermore, the latter requires a certain of batching to be efficient, which makes OT preferable for smaller tasks.

  • Malicious, honest-majority three-party computation: A number of protocols are available for this setting, but SY/SPDZ-wise is the most efficient one for a number of reasons: It requires the lowest communication, and it is the only one offering constant-communication dot products.

  • Fixed-point multiplication: Three- and four-party replicated secret sharing as well semi-honest full-threshold protocols allow a special probabilistic truncation protocol (see Dalskov et al. and Dalskov et al.). You can activate it by adding program.use_trunc_pr = True at the beginning of your high-level program.

  • Larger number of parties: ATLAS scales better than the plain Shamir protocol, and Temi scale better than Hemi or Semi.

  • Minor variants: Some command-line options change aspects of the protocols such as:

    • --bucket-size: In some malicious binary computation and malicious edaBit generation, a smaller bucket size allows preprocessing in smaller batches at a higher asymptotic cost.
    • --batch-size: Preprocessing in smaller batches avoids generating too much but larger batches save communication rounds.
    • --direct: In protocols with any number of parties, direct communication instead of star-shaped saves communication rounds at the expense of a quadratic amount. This might be beneficial with a small number of parties.
    • --bits-from-squares: In some protocols computing modulo a prime (Shamir, Rep3, SPDZ-wise), this switches from generating random bits via XOR of parties' inputs to generation using the root of a random square.

Paper and Citation

The design of MP-SPDZ is described in this paper. If you use it for an academic project, please cite:

@inproceedings{mp-spdz,
    author = {Marcel Keller},
    title = {{MP-SPDZ}: A Versatile Framework for Multi-Party Computation},
    booktitle = {Proceedings of the 2020 ACM SIGSAC Conference on
    Computer and Communications Security},
    year = {2020},
    doi = {10.1145/3372297.3417872},
    url = {https://doi.org/10.1145/3372297.3417872},
}

History

The software started out as an implementation of the improved SPDZ protocol. The name SPDZ is derived from the authors of the original protocol.

This repository combines the functionality previously published in the following repositories:

Overview

For the actual computation, the software implements a virtual machine that executes programs in a specific bytecode. Such code can be generated from high-level Python code using a compiler that optimizes the computation with a particular focus on minimizing the number of communication rounds (for protocols based on secret sharing) or on AES-NI pipelining (for garbled circuits).

The software uses two different bytecode sets, one for arithmetic circuits and one for boolean circuits. The high-level code differs between the two variants. Most computation functionality is available in both, but binary circuits are lacking some input-output functionality.

In the section on computation we will explain how to compile a high-level program for the various computation domains and then how to run it with different protocols.

The section on offline phases will explain how to benchmark the offline phases required for the SPDZ protocol. Running the online phase outputs the amount of offline material required, which allows to compute the preprocessing time for a particular computation.

Requirements

  • GCC 7 or later (tested with up to 11) or LLVM/clang 6 or later (tested with up to 19). The default is to use clang because it performs better. clang 9 doesn't support libOTe, so you need to deactivate its use for these compilers (see the next section).
  • For protocols using oblivious transfer, libOTe with the necessary patches but without SimplestOT. The easiest way is to run make libote, which will install it as needed in a subdirectory. libOTe requires CMake of version at least 3.15, which is not available by default on older systems such as Ubuntu 18.04. You can run make cmake to install it locally. libOTe also requires boost of version at least 1.75, which is not available by default on relatively recent systems such as Ubuntu 22.04. You can install it locally by running make boost.
  • GMP library, compiled with C++ support (use flag --enable-cxx when running configure). Tested against 6.2.1 as supplied by Ubuntu.
  • libsodium library, tested against 1.0.18
  • OpenSSL, tested against 3.0.2
  • Boost.Asio with SSL support (libboost-dev on Ubuntu), tested against 1.81
  • Boost.Thread for BMR (libboost-thread-dev on Ubuntu), tested against 1.81
  • x86 or ARM 64-bit CPU (the latter tested with AWS Gravitron and Apple Silicon)
  • Python 3.5 or later
  • NTL library for homomorphic encryption (optional; tested with NTL 11.5.1)
  • If using macOS, Sierra or later
  • Windows/VirtualBox: see this issue for a discussion

Compilation

  1. Edit CONFIG or CONFIG.mine to your needs:

    • On x86, the binaries are optimized for the CPU you are compiling on. For all optimizations on x86, a CPU supporting AES-NI, PCLMUL, AVX2, BMI2, ADX is required. This includes mainstream processors released 2014 or later. If you intend to run on a different CPU than compiling, you might need to change the ARCH variable in CONFIG or CONFIG.mine to -march=<cpu>. See the GCC documentation for the possible options. To run on CPUs without AVX2 (CPUs from before 2014), you should also add AVX_OT = 0 to CONFIG.mine.
    • For optimal results on Linux on ARM, add ARCH = -march=armv8.2-a+crypto to CONFIG.mine. This enables the hardware support for AES. See the GCC documentation on available options.
    • To benchmark online-only protocols or Overdrive offline phases, add the following line at the top: MY_CFLAGS = -DINSECURE
    • PREP_DIR should point to a local, unversioned directory to store preprocessing data (the default is Player-Data in the current directory).
    • SSL_DIR should point to a local, unversioned directory to store ssl keys (the default is Player-Data in the current directory).
    • For homomorphic encryption with GF(2^40), set USE_NTL = 1.
    • To use KOS instead of SoftSpokenOT, add USE_KOS = 1 and SECURE = -DINSECURE to CONFIG.mine.
    • On macOS, there have been issues with non-system compilers. Add CXX = /usr/bin/g++ to fix them.
  2. Run make to compile all the software (use the flag -j for faster compilation using multiple threads). See below on how to compile specific parts only. Remember to run make clean first after changing CONFIG or CONFIG.mine.

Running Computation

See Programs/Source/ for some example MPC programs, in particular tutorial.mpc. Furthermore, Read the Docs hosts a more detailed reference of all aspects of MP-SPDZ.

There are three ways of running computation:

  1. Separate compilation and execution. This is the default in the further documentation. It allows to run the same program several times while only compiling once, for example:

    ./compile.py <program> <argument>
    Scripts/mascot.sh <program>-<argument> [<runtime-arg>...]
    Scripts/mascot.sh <program>-<argument> [<runtime-arg>...]
    
  2. One-command local execution. This compiles the program and the virtual machine if necessary before executing it locally with the given protocol. The name of the protocols correspond to the script names below (without the .sh). Furthermore, some protocol-specific optimization options are automatically used as well as required options.

    Scripts/compile-run.py -E mascot <program> <argument> -- [<runtime-arg>...]
    
  3. One-command remote execution. This compiles the program and the virtual machine if necessary before uploading them together with all necessary input and certificate files via SSH.

    Scripts/compile-run.py -H HOSTS -E mascot <program> <argument> -- [<runtime-arg>...]
    

    HOSTS has to be a text file in the following format:

    [<user>@]<host0>[/<path>]
    [<user>@]<host1>[/<path>]
    ...
    

    If does not start with / (only one / after the hostname), the path will be relative to the home directory of the user. Otherwise (// after the hostname it will be relative to the root directory.

    It is assumed that the SSH login is possible without password.

    Adding the compiler option -t (--tidy_output) groups the output prints by party; however, it delays the outputs until the execution is finished.

Even with the integrated execution it is important to keep in mind that there are two different phases, the compilation and the run-time phase. Any secret data is only available in the second phase, when the Python compilation has concluded. Therefore, the types like sint and sfix are mere placeholders for data to be used later, and they don't contain any shares. See also the documentation for what this means when using Python data structures and Python language features.

Compiling high-level programs

There are three computation domains, and the high-level programs have to be compiled accordingly.

Arithmetic modulo a prime

./compile.py [-F <integer bit length>] [-P <prime>] <program>

The integer bit length defaults to 64, and the prime defaults to none given. If a prime is given, it has to be at least two bits longer than the integer length. Note that -P is optional, and it involves algorithms that are more expensive while allowing for a wider range of integer lengths.

The command-line options primarily affects non-linear computation such as comparisons. See the documentation on non-linear computation for more details and pointers to relevant papers.

Note that in this context integers do not wrap around according to the integer bit length but the length is used for non-linear computations such as comparison. Overflow in secret integers might have security implications if no concrete prime is given.

The parameters given together with the computation mandate some restriction on the prime modulus, either an exact value or a minimum length. The latter is roughly the integer length plus 40 (default security parameter). The restrictions are communicated to the virtual machines, which will use an appropriate prime if they have been compiled accordingly. By default, they are compiled for prime bit lengths up to 256. For larger primes, you will have to compile with MOD = -DGFP_MOD_SZ=<number of limbs> in CONFIG.mine where the number of limbs is the the prime length divided by 64 rounded up.

The precision for fixed- and floating-point computation are not affected by the integer bit length but can be set in the code directly. For fixed-point computation this is done via sfix.set_precision().

Arithmetic modulo 2^k

./compile.py -R <integer bit length> <program>

The length is communicated to the virtual machines and automatically used if supported. By default, they support bit lengths 64, 72, and 128 (the latter except for SPDZ2k). If another length is required, use MOD = -DRING_SIZE=<bit length> in CONFIG.mine.

Binary circuits

./compile.py -B <integer bit length> <program>

The integer length can be any number up to a maximum depending on the protocol. All protocols support at least 64-bit integers.

Fixed-point numbers (sfix) always use 16/16-bit precision by default in binary circuits. This can be changed with sfix.set_precision. See the tutorial.

If you would like to use integers of various precisions, you can use sbitint.get_type(n) to get a type for n-bit arithmetic.

Mixed circuits

MP-SPDZ allows to mix computation between arithmetic and binary secret sharing in the same security model. In the compiler, this is used to switch from arithmetic to binary computation for certain non-linear functions such as comparison, bit decomposition, truncation, and modulo power of two, which are use for fixed- and floating-point operations. There are several ways of achieving this as described below.

Classic daBits

You can activate this by adding -X when compiling arithmetic circuits, that is ./compile.py -X [-F <integer bit length>] <program> for computation modulo a prime and ./compile.py -X -R <integer bit length> <program> for computation modulo 2^k.

Internally, this uses daBits described by Rotaru and Wood, that is secret random bits shared in different domains. Some security models allow direct conversion of random bits from arithmetic to binary while others require inputs from several parties followed by computing XOR and checking for malicious security as described by Rotaru and Wood in Section 4.1.

Extended daBits

Extended daBits were introduced by Escudero et al.. You can activate them by using -Y instead of -X. Note that this also activates classic daBits when useful.

Local share conversion

This technique has been used by Mohassel and Rindal as well as Araki et al. for three parties and Demmler et al. for two parties. It involves locally converting an arithmetic share to a set of binary shares, from which the binary equivalent to the arithmetic share is reconstructed using a binary adder. This requires additive secret sharing over a ring without any MACs. You can activate it by using -Z <n> with the compiler where n is the number of parties for the standard variant and 2 for the special variant by Mohassel and Rindal (available in Rep3 only).

Finding the most efficient variant

Where available, local share conversion is likely the most efficient variant. Otherwise, edaBits likely offer an asymptotic benefit. When using edaBits with malicious protocols, there is a trade-off between cost per item and batch size. The lowest cost per item requires large batches of edaBits (more than one million at once), which is only worthwhile for accordingly large computation. This setting can be selected by running the virtual machine with -B 3. For smaller computation, try -B 4 or -B 5, which set the batch size to ~10,000 and ~1,000, respectively, at a higher asymptotic cost. -B 4 is the default.

Bristol Fashion circuits

Bristol Fashion is the name of a description format of binary circuits used by SCALE-MAMBA. You can access such circuits from the high-level language if they are present in Programs/Circuits. To run the AES-128 circuit provided with SCALE-MAMBA, you can run the following:

make Programs/Circuits
./compile.py aes_circuit
Scripts/semi.sh aes_circuit

This downloads the circuit, compiles it to MP-SPDZ bytecode, and runs it as semi-honest two-party computation 1000 times in parallel. It should then output the AES test vector 0x3ad77bb40d7a3660a89ecaf32466ef97. You can run it with any other protocol as well.

See the documentation for further examples.

Compiling programs directly in Python

You may prefer to not have an entirely static .mpc file to compile, and may want to compile based on dynamic inputs. For example, you may want to be able to compile with different sizes of input data without making a code change to the .mpc file. To handle this, the compiler an also be directly imported, and a function can be compiled with the following interface:

# hello_world.mpc
from Compiler.library import print_ln
from Compiler.compilerLib import Compiler

compiler = Compiler()

@compiler.register_function('helloworld')
def hello_world():
    print_ln('hello world')

if __name__ == "__main__":
    compiler.compile_func()

You could then run this with the same args as used with compile.py:

python hello_world.mpc <compile args>

This is particularly useful if want to add new command line arguments specifically for your .mpc file. See test_args.mpc for more details on this use case.

Note that when using this approach, all objects provided in the high level interface (e.g. sint, print_ln) need to be imported, because the .mpc file is interpreted directly by Python (instead of being read by compile.py.)

Compiling and running programs from external directories

Programs can also be edited, compiled and run from any directory with the above basic structure. So for a source file in ./Programs/Source/, all MP-SPDZ scripts must be run from ./. Any setup scripts such as setup-ssl.sh script must also be run from ./ to create the relevant data. For example:

MP-SPDZ$ cd ../
$ mkdir myprogs
$ cd myprogs
$ mkdir -p Programs/Source
$ vi Programs/Source/test.mpc
$ ../MP-SPDZ/compile.py test.mpc
$ ls Programs/
Bytecode  Public-Input  Schedules  Source
$ ../MP-SPDZ/Scripts/setup-ssl.sh
$ ls
Player-Data Programs
$ ../MP-SPDZ/Scripts/rep-field.sh test

TensorFlow inference

Note: All networks mentioned below are now supported by the PyTorch interface, which is better integrated and thus easier to use. This section is merely kept to document the approach used for an earlier paper, but it is recommended to use the PyTorch interface.

MP-SPDZ supports inference with selected TensorFlow graphs, in particular DenseNet, ResNet, and SqueezeNet as used in CrypTFlow. For example, you can run SqueezeNet inference for ImageNet as follows:

git clone https://github.com/mkskeller/EzPC
cd EzPC/Athos/Networks/SqueezeNetImgNet
axel -a -n 5 -c --output ./PreTrainedModel https://github.com/avoroshilov/tf-squeezenet/raw/master/sqz_full.mat
pip3 install numpy scipy pillow>=9.1 tensorflow
python3 squeezenet_main.py --in ./SampleImages/n02109961_36.JPEG --saveTFMetadata True
python3 squeezenet_main.py --in ./SampleImages/n02109961_36.JPEG --scalingFac 12 --saveImgAndWtData True
cd ../../../..
cp EzPC/Athos/Networks/SqueezeNetImgNet/SqNetImgNet_img_input.inp Player-Data/Input-Binary-P0-0
./compile.py -R 64 tf EzPC/Athos/Networks/SqueezeNetImgNet/graphDef.bin 1 trunc_pr split
Scripts/ring.sh tf-EzPC_Athos_Networks_SqueezeNetImgNet_graphDef.bin-1-trunc_pr-split

This requires TensorFlow and the axel command-line utility to be installed. It runs inference with three-party semi-honest computation, similar to CrypTFlow's Porthos. Replace 1 by the desired number of thread in the last two lines. If you run with some other protocols, you will need to remove trunc_pr and/or split. Also note that you will need to use a CrypTFlow repository that includes the patches in https://github.com/mkskeller/EzPC.

The reference contains further documentation on available layers.

Emulation

For arithmetic circuits modulo a power of two and binary circuits, you can emulate the computation as follows:

./emulate.x <program>

This runs the compiled bytecode in cleartext computation, that is, no multi-party computation is performed.

Dishonest majority

Some full implementations require oblivious transfer, which is implemented as OT extension based on https://github.com/mkskeller/SimpleOT or https://github.com/mkskeller/SimplestOT_C, depending on whether AVX is available.

Secret sharing

The following table shows all programs for dishonest-majority computation using secret sharing:

Program Protocol Domain Security Script
mascot-party.x MASCOT Mod prime Malicious mascot.sh
mama-party.x MASCOT* Mod prime Malicious mama.sh
spdz2k-party.x SPDZ2k Mod 2^k Malicious spdz2k.sh
semi-party.x OT-based Mod prime Semi-honest semi.sh
semi2k-party.x OT-based Mod 2^k Semi-honest semi2k.sh
lowgear-party.x LowGear Mod prime Malicious lowgear.sh
highgear-party.x HighGear Mod prime Malicious highgear.sh
cowgear-party.x Adapted LowGear Mod prime Covert cowgear.sh
chaigear-party.x Adapted HighGear Mod prime Covert chaigear.sh
hemi-party.x Semi-homomorphic encryption Mod prime Semi-honest hemi.sh
temi-party.x Adapted CDN01 Mod prime Semi-honest temi.sh
soho-party.x Somewhat homomorphic encryption Mod prime Semi-honest soho.sh
semi-bin-party.x OT-based Binary Semi-honest semi-bin.sh
tiny-party.x Adapted SPDZ2k Binary Malicious tiny.sh
tinier-party.x FKOS15 Binary Malicious tinier.sh

Mama denotes MASCOT with several MACs to increase the security parameter to a multiple of the prime length.

Semi and Semi2k denote the result of stripping MASCOT/SPDZ2k of all steps required for malicious security, namely amplifying, sacrificing, MAC generation, and OT correlation checks. What remains is the generation of additively shared Beaver triples using OT.

Similarly, SemiBin denotes a protocol that generates bit-wise multiplication triples using OT without any element of malicious security.

Tiny denotes the adaption of SPDZ2k to the binary setting. In particular, the SPDZ2k sacrifice does not work for bits, so we replace it by cut-and-choose according to Furukawa et al. Tinier on the other hand denotes the protocol by Frederiksen et al. also using the cut-and-choose sacrifice by Furukawa et al.

The virtual machines for LowGear and HighGear run a key generation similar to the one by Rotaru et al.. The main difference is using daBits to generate maBits. CowGear and ChaiGear denote covertly secure versions of LowGear and HighGear. In all relevant programs, option -T activates TopGear zero-knowledge proofs in both.

Hemi and Soho denote the stripped version of LowGear and HighGear, respectively, for semi-honest security similar to Semi, that is, generating additively shared Beaver triples using semi-homomorphic encryption. Temi in turn denotes the adaption of Cramer et al. to LWE-based semi-homomorphic encryption as described in Appendix B of this work. Both Hemi and Temi use the diagonal packing by Halevi and Shoup for matrix multiplication.

We will use MASCOT to demonstrate the use, but the other protocols work similarly.

First compile the virtual machine:

make -j8 mascot-party.x

and a high-level program, for example the tutorial (use -R 64 for SPDZ2k and Semi2k and -B <precision> for SemiBin):

./compile.py -F 64 tutorial

To run the tutorial with two parties on one machine, run:

./mascot-party.x -N 2 -I -p 0 tutorial

./mascot-party.x -N 2 -I -p 1 tutorial (in a separate terminal)

Using -I activates interactive mode, which means that inputs are solicited from standard input, and outputs are given to any party. Omitting -I leads to inputs being read from Player-Data/Input-P<party number>-0 in text format.

Or, you can use a script to do run two parties in non-interactive mode automatically:

Scripts/mascot.sh tutorial

To run a program on two different machines, mascot-party.x needs to be passed the machine where the first party is running, e.g. if this machine is name diffie on the local network:

./mascot-party.x -N 2 -h diffie 0 tutorial

./mascot-party.x -N 2 -h diffie 1 tutorial

The software uses TCP ports around 5000 by default, use the -pn argument to change that.

Yao's garbled circuits

We use half-gate garbling as described by Zahur et al. and Guo et al.. Alternatively, you can activate the implementation optimized by Bellare et al. by adding MY_CFLAGS += -DFULL_GATES to CONFIG.mine.

Compile the virtual machine:

make -j 8 yao

and the high-level program:

./compile.py -G -B <integer bit length> <program>

Then run as follows:

  • Garbler: ./yao-party.x [-I] -p 0 <program>
  • Evaluator: ./yao-party.x [-I] -p 1 -h <garbler host> <program>

When running locally, you can omit the host argument. As above, -I activates interactive input, otherwise inputs are read from Player-Data/Input-P<playerno>-0.

By default, the circuit is garbled in chunks that are evaluated whenever received.You can activate garbling all at once by adding -O to the command line on both sides.

Honest majority

The following table shows all programs for honest-majority computation:

Program Sharing Domain Malicious # parties Script
replicated-ring-party.x Replicated Mod 2^k N 3 ring.sh
brain-party.x Replicated Mod 2^k Y 3 brain.sh
ps-rep-ring-party.x Replicated Mod 2^k Y 3 ps-rep-ring.sh
malicious-rep-ring-party.x Replicated Mod 2^k Y 3 mal-rep-ring.sh
sy-rep-ring-party.x SPDZ-wise replicated Mod 2^k Y 3 sy-rep-ring.sh
rep4-ring-party.x Replicated Mod 2^k Y 4 rep4-ring.sh
replicated-bin-party.x Replicated Binary N 3 replicated.sh
malicious-rep-bin-party.x Replicated Binary Y 3 mal-rep-bin.sh
ps-rep-bin-party.x Replicated Binary Y 3 ps-rep-bin.sh
replicated-field-party.x Replicated Mod prime N 3 rep-field.sh
ps-rep-field-party.x Replicated Mod prime Y 3 ps-rep-field.sh
sy-rep-field-party.x SPDZ-wise replicated Mod prime Y 3 sy-rep-field.sh
malicious-rep-field-party.x Replicated Mod prime Y 3 mal-rep-field.sh
atlas-party.x ATLAS Mod prime N 3 or more atlas.sh
shamir-party.x Shamir Mod prime N 3 or more shamir.sh
malicious-shamir-party.x Shamir Mod prime Y 3 or more mal-shamir.sh
sy-shamir-party.x SPDZ-wise Shamir Mod prime Y 3 or more sy-shamir.sh
ccd-party.x CCD/Shamir Binary N 3 or more ccd.sh
malicious-cdd-party.x CCD/Shamir Binary Y 3 or more mal-ccd.sh

We use the "generate random triple optimistically/sacrifice/Beaver" methodology described by Lindell and Nof to achieve malicious security with plain arithmetic replicated secret sharing, except for the "PS" (post-sacrifice) protocols where the actual multiplication is executed optimistically and checked later as also described by Lindell and Nof. The implementations used by brain-party.x, malicious-rep-ring-party.x -S, malicious-rep-ring-party.x, and ps-rep-ring-party.x correspond to the protocols called DOS18 preprocessing (single), ABF+17 preprocessing, CDE+18 preprocessing, and postprocessing, respectively, by Eerikson et al. We use resharing by Cramer et al. for Shamir's secret sharing and the optimized approach by Araki et al. for replicated secret sharing. The CCD protocols are named after the historic paper by Chaum, Crépeau, and Damgård, which introduced binary computation using Shamir secret sharing over extension fields of characteristic two. SY/SPDZ-wise refers to the line of work started by Chida et al. for computation modulo a prime and furthered by Abspoel et al. for computation modulo a power of two. It involves sharing both a secret value and information-theoretic tag similar to SPDZ but not with additive secret sharing, hence the name. Rep4 refers to the four-party protocol by Dalskov et al. malicious-rep-bin-party.x is based on cut-and-choose triple generation by Furukawa et al. but using Beaver multiplication instead of their post-sacrifice approach. ps-rep-bin-party.x is based on the post-sacrifice approach by Araki et al. but without using their cache optimization.

All protocols in this section require encrypted channels because the information received by the honest majority suffices the reconstruct all secrets. Therefore, an eavesdropper on the network could learn all information.

MP-SPDZ uses OpenSSL for secure channels. You can generate the necessary certificates and keys as follows:

Scripts/setup-ssl.sh [<number of parties> <ssl_dir>]

The programs expect the keys and certificates to be in SSL_DIR/P<i>.key and SSL_DIR/P<i>.pem, respectively, and the certificates to have the common name P<i> for player <i>. Furthermore, the relevant root certificates have to be in SSL_DIR such that OpenSSL can find them (run c_rehash <ssl_dir>). The script above takes care of all this by generating self-signed certificates. Therefore, if you are running the programs on different hosts you will need to copy the certificate files. Note that <ssl_dir> must match SSL_DIR set in CONFIG or CONFIG.mine. Just like SSL_DIR, <ssl_dir> defaults to Player-Data.

In the following, we will walk through running the tutorial modulo 2^k with three parties. The other programs work similarly.

First, compile the virtual machine:

make -j 8 replicated-ring-party.x

In order to compile a high-level program, use ./compile.py -R 64:

./compile.py -R 64 tutorial

If using another computation domain, use -F or -B as described in the relevant section above.

Finally, run the three parties as follows:

./replicated-ring-party.x -I 0 tutorial

./replicated-ring-party.x -I 1 tutorial (in a separate terminal)

./replicated-ring-party.x -I 2 tutorial (in a separate terminal)

or

Scripts/ring.sh tutorial

The -I argument enables interactive inputs, and in the tutorial party 0 and 1 will be asked to provide three numbers. Otherwise, and when using the script, the inputs are read from Player-Data/Input-P<playerno>-0.

When using programs based on Shamir's secret sharing, you can specify the number of parties with -N and the maximum number of corrupted parties with -T. The latter can be at most half the number of parties.

Dealer model

This security model defines a special party that generates correlated randomness such as multiplication triples, which is then used by all other parties. MP-SPDZ implements the canonical protocol where the other parties run the online phase of the semi-honest protocol in Semi(2k/Bin) and the dealer provides all preprocessing. The security assumption is that dealer doesn't collude with any other party, but all but one of the other parties are allowed to collude. In our implementation, the dealer is the party with the highest number, so with three parties overall, Party 0 and 1 run the online phase.

Program Sharing Domain Malicious # parties Script
dealer-ring-party.x Additive Mod 2^k N 3+ dealer-ring.sh

BMR

BMR (Beaver-Micali-Rogaway) is a method of generating a garbled circuit using another secure computation protocol. We have implemented BMR based on all available implementations using GF(2^128) because the nature of this field particularly suits the Free-XOR optimization for garbled circuits. Our implementation is based on the SPDZ-BMR-ORAM construction. The following table lists the available schemes.

Program Protocol Dishonest Maj. Malicious # parties Script
real-bmr-party.x MASCOT Y Y 2 or more real-bmr.sh
semi-bmr-party.x Semi Y N 2 or more semi-bmr.sh
shamir-bmr-party.x Shamir N N 3 or more shamir-bmr.sh
mal-shamir-bmr-party.x Shamir N Y 3 or more mal-shamir-bmr.sh
rep-bmr-party.x Replicated N N 3 rep-bmr.sh
mal-rep-bmr-party.x Replicated N Y 3 mal-rep-bmr.sh

In the following, we will walk through running the tutorial with BMR based on MASCOT and two parties. The other programs work similarly.

First, compile the virtual machine. In order to run with more than three parties, change the definition of MAX_N_PARTIES in BMR/config.h accordingly.

make -j 8 real-bmr-party.x

In order to compile a high-level program, use ./compile.py -B:

./compile.py -G -B 32 tutorial

Finally, run the two parties as follows:

./real-bmr-party.x -I 0 tutorial

./real-bmr-party.x -I 1 tutorial (in a separate terminal)

or

Scripts/real-bmr.sh tutorial

The -I enable interactive inputs, and in the tutorial party 0 and 1 will be asked to provide three numbers. Otherwise, and when using the script, the inputs are read from Player-Data/Input-P<playerno>-0.

Online-only benchmarking

In this section we show how to benchmark purely the data-dependent (often called online) phase of some protocols. This requires to generate the output of a previous phase. There are two options to do that:

  1. For select protocols, you can run preprocessing as required.
  2. You can run insecure preprocessing. For this, you will have to (re)compile the software after adding MY_CFLAGS = -DINSECURE to CONFIG.mine in order to run this insecure generation. Make sure to run make clean before recompiling any binaries. Then, you need to run make Fake-Offline.x <protocol>-party.x.

Note that you can as well run the full protocol with option -v to see the cost split by preprocessing and online phase.

SPDZ

The SPDZ protocol uses preprocessing, that is, in a first (sometimes called offline) phase correlated randomness is generated independent of the actual inputs of the computation. Only the second ("online") phase combines this randomness with the actual inputs in order to produce the desired results. The preprocessed data can only be used once, thus more computation requires more preprocessing. MASCOT and Overdrive are the names for two alternative preprocessing phases to go with the SPDZ online phase.

All programs required in this section can be compiled with the target online:

make -j 8 online

To setup for benchmarking the online phase

This requires the INSECURE flag to be set before compilation as explained above. For a secure offline phase, see the section on SPDZ-2 below.

Run the command below. If you haven't added MY_CFLAGS = -DINSECURE to CONFIG.mine before compiling, it will fail.

Scripts/setup-online.sh

This sets up parameters for the online phase for 2 parties with a 128-bit prime field and 128-bit binary field, and creates fake offline data (multiplication triples etc.) for these parameters.

Parameters can be customised by running

Scripts/setup-online.sh <nparties> <nbitsp> [<nbits2>]

To compile a program

To compile for example the program in ./Programs/Source/tutorial.mpc, run:

./compile.py tutorial

This creates the bytecode and schedule files in Programs/Bytecode/ and Programs/Schedules/

To run a program

To run the above program with two parties on one machine, run:

./mascot-party.x -F -N 2 0 tutorial

./mascot-party.x -F -N 2 1 tutorial (in a separate terminal)

Or, you can use a script to do the above automatically:

Scripts/mascot.sh -F tutorial

MASCOT is one of the protocols that use SPDZ for the online phase, and -F causes the programs to read preprocessing material from files.

To run a program on two different machines, firstly the preprocessing data must be copied across to the second machine (or shared using sshfs), and secondly, mascot-party.x needs to be passed the machine where the first party is running. E.g., if this machine is named diffie on the local network:

./mascot-party.x -F -N 2 -h diffie 0 test_all

./mascot-party.x -F -N 2 -h diffie 1 test_all

The software uses TCP ports around 5000 by default, use the -pn argument to change that.

SPDZ2k

Creating fake offline data for SPDZ2k requires to call Fake-Offline.x directly instead of via setup-online.sh:

./Fake-Offline.x <nparties> -Z <bit length k for SPDZ2k> -S <security parameter>

You will need to run spdz2k-party.x -F in order to use the data from storage.

Other protocols

Preprocessing data for the default parameters of most other protocols can be produced as follows:

./Fake-Offline.x <nparties> -e <edaBit length,...>

The -e command-line parameters accepts a list of integers separated by commas.

You can then run the protocol with argument -F. Note that when running on several hosts, you will need to distribute the data in Player-Data. The preprocessing files contain -P<party number> indicating which party will access it.

BMR

This part has been developed to benchmark ORAM for the Eurocrypt 2018 paper by Marcel Keller and Avishay Yanay. It only allows to benchmark the data-dependent phase. The data-independent and function-independent phases are emulated insecurely.

By default, the implementations is optimized for two parties. You can change this by defining N_PARTIES accordingly in BMR/config.h. If you entirely delete the definition, it will be able to run for any number of parties albeit slower.

Compile the virtual machine:

make -j 8 bmr

After compiling the mpc file:

  • Run everything locally: Scripts/bmr-program-run.sh <program> <number of parties>.
  • Run on different hosts: Scripts/bmr-program-run-remote.sh <program> <host1> <host2> [...]

Oblivious RAM

You can benchmark the ORAM implementation as follows:

  1. Edit Program/Source/gc_oram.mpc to change size and to choose Circuit ORAM or linear scan without ORAM.
  2. Run ./compile.py -G -D gc_oram. The -D argument instructs the compiler to remove dead code. This is useful for more complex programs such as this one.
  3. Run gc_oram in the virtual machines as explained above.

Preprocessing as required

For select protocols, you can run all required preprocessing but not the actual computation. First, compile the binary:

make <protocol>-offline.x

At the time of writing the supported protocols are mascot, cowgear, mal-shamir, semi, semi2k, and hemi.

If you have not done so already, then compile your high-level program:

./compile.py <program>

Finally, run the parties as follows:

./<protocol>-offline.x -p 0 & ./<protocol>-offline.x -p 1 & ...

The options for the network setup are the same as for the complete computation above.

If you run the preprocessing on different hosts, make sure to use the same player number in the preprocessing and the online phase.

Benchmarking offline phases

SPDZ-2 offline phase

This implementation is suitable to generate the preprocessed data used in the online phase. You need to compile with USE_NTL = 1 in CONFIG.mine to run this.

For quick run on one machine, you can call the following:

./spdz2-offline.x -p 0 & ./spdz2-offline.x -p 1

More generally, run the following on every machine:

./spdz2-offline.x -p <number of party> -N <total number of parties> -h <hostname of party 0> -c <covert security parameter>

The number of parties are counted from 0. As seen in the quick example, you can omit the total number of parties if it is 2 and the hostname if all parties run on the same machine. Invoke ./spdz2-offline.x for more explanation on the options.

./spdz2-offline.x provides covert security according to some parameter c (at least 2). A malicious adversary will get caught with probability 1-1/c. There is a linear correlation between c and the running time, that is, running with 2c takes twice as long as running with c. The default for c is 10.

The program will generate every kind of randomness required by the online phase except input tuples until you stop it. You can shut it down gracefully pressing Ctrl-c (or sending the interrupt signal SIGINT), but only after an initial phase, the end of which is marked by the output Starting to produce gf2n. Note that the initial phase has been reported to take up to an hour. Furthermore, 3 GB of RAM are required per party.

Benchmarking the MASCOT or SPDZ2k offline phase

These implementations are not suitable to generate the preprocessed data for the online phase because they can only generate either multiplication triples or bits.

MASCOT can be run as follows:

host1:$ ./ot-offline.x -p 0 -c

host2:$ ./ot-offline.x -p 1 -c

For SPDZ2k, use -Z <k> to set the computation domain to Z_{2^k}, and -S to set the security parameter. The latter defaults to k. At the time of writing, the following combinations are available: 32/32, 64/64, 64/48, and 66/48.

Running ./ot-offline.x without parameters give the full menu of options such as how many items to generate in how many threads and loops.

Benchmarking Overdrive offline phases

We have implemented several protocols to measure the maximal throughput for the Overdrive paper. As for MASCOT, these implementations are not suited to generate data for the online phase because they only generate one type at a time.

Binary Protocol
simple-offline.x SPDZ-1 and High Gear (with command-line argument -g)
pairwise-offline.x Low Gear
cnc-offline.x SPDZ-2 with malicious security (covert security with command-line argument -c)

These programs can be run similarly to spdz2-offline.x, for example:

host1:$ ./simple-offline.x -p 0 -h host1

host2:$ ./simple-offline.x -p 1 -h host1

Running any program without arguments describes all command-line arguments.

Memory usage

Lattice-based ciphertexts are relatively large (in the order of megabytes), and the zero-knowledge proofs we use require storing some hundred of them. You must therefore expect to use at least some hundred megabytes of memory per thread. The memory usage is linear in MAX_MOD_SZ (determining the maximum integer size for computations in steps of 64 bits), so you can try to reduce it (see the compilation section for how set it). For some choices of parameters, 4 is enough while others require up to 8. The programs above indicate the minimum MAX_MOD_SZ required, and they fail during the parameter generation if it is too low.

mp-spdz's People

Contributors

abspoel avatar avishayyanay avatar chriszgh avatar dar9586 avatar eriktaubeneck avatar hdvanegasm avatar henri2h avatar hiddely avatar jonas-eppard avatar jvmncs avatar lance6716 avatar mariandietz avatar martin2384798 avatar mkskeller avatar ocalex86 avatar parallelogrampal avatar pascholl avatar prayforwind avatar quitlox avatar rdeviti avatar rdragos avatar rhg101997 avatar rtaiello avatar sbellem avatar strieflin avatar tskovlund avatar vinc0682 avatar vincent-ehrmanntraut avatar vomvas avatar weizheng92 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mp-spdz's Issues

some problems about offline data

Hi, mkskeller,
As for offline data, I have met some problems. (1) I run ./Fake-Offline.x 3 -inv 170 -bit 1500,10000 -btrip 600 to produce offline data for online phase, then I run Scripts/shamir.sh aes -F , I can run the aes.mpc successfully. But when I compile aes.mpc, the compilation output including offline data requirements are as follows, obviously, the produced offline data do not meet the needs, but it can be run successfully.

Compile offline data requirements...
Tape requires 53 rounds in all, 16 inputs in gf2n from player 2, 1200 triples in gf2n, 1712 invs in all, 3584 bits in gf2n, 16 inputs in gf2n from player 1, 16 inputs in gf2n from player 0
Program requires: {('all', 'round'): 53, ('gf2n', 'input', 1): 16, ('gf2n', 'bit'): 3584, ('gf2n', 'input', 0): 16, ('gf2n', 'input', 2): 16, ('gf2n', 'triple'): 1200, ('all', 'inv'): 1712}

(2) I wonder know how to read the triples from the file when they are used for online phase, I saw you define DataPositions pos to keep record of used offline data, I want to output the starting position of each read to work out how it works, but failed, I do not know how to achieve that, because I do n’t understand the whole process, and I have difficulty in understanding the entire project, is there any recommended editor to understand the entire project, by the way, I use vscode.
I am eager to understand this project, I am sorry to trouble you again and again, you are nice to give me guidance patiently.Thanks your kind help !

Problem when running AES

Hi
I run AES as the follwing steps, I have installed MPIR (Download from MPIR: Multiple Precision Integers and Rationals
echo 'USE_GF2N_LONG = 0' >> CONFIG.mine
make clean
make -j8 shamir-party.x malicious-shamir-party.x replicated-field-party.x malicious-rep-field-party.x

echo 16 6b c1 be e2 2e 40 9f 96 e9 3d 7e 11 73 93 17 2a > gf2n_vals.in
./gen_input_f2n.x
mv gf2n_vals.out Player-Data/Private-Input-1

echo 16 2b 7e 15 16 28 ae d2 a6 ab f7 15 88 09 cf 4f 3c > gf2n_vals.in
./gen_input_f2n.x
mv gf2n_vals.out Player-Data/Private-Input-0

./compile.py aes

Then I run AES in three terminals ,But it occurs the problem as follows(the same as running Scripts/shamir.sh aes). could you please give me some guidance.
3
2
1

Scripts/shamir.sh aes

Initialize GF2N in external application problem

Hi,

I use the external application to talk to MP-SPDZ based on the bonus example and I've got two problems.

(1) when initializing fields in the external application by reading the Param-Data file that is set up in spdz, I received the following error:

terminate called after throwing an instance of 'std::runtime_error'
what(): need to compile with USE_GF2N_LONG = 1; remember to make clean
Aborted (core dumped)

(2) The communications between external apps and spdz parties are unstable. I used the similar sockets as in the bonus example (actually, if I write the application inside the spdz project, it also runs correctly), however, sometimes the external apps in the send_private_inputs function cannot receive triplets from the spdz party, where the apps are stuck at the following position, such that no triple received. But sometimes the external apps can run smoothly to obtain the final result by interacting with spdz.

   // Receive num_inputs triples from SPDZ
    for (int j = 0; j < n_parties; j++)
    {
        os.reset_write_head();
        logger(stdout, "stuck at here \n");
        os.Receive(sockets[j]);
    }

Any help would be highly appreciated.

Thanks and best regards,
Yuncheng

the result overflows when using sint.get_raw_input_from()

I create a file named "add.mpc", my code is as follows. If I use get_input_from() to get the inputs, the correct result comes out.

a = sint.get_input_from(0)   
b = sint.get_input_from(1)
c = sint.get_input_from(2)
d= (a+b)*c 
print_ln('Result is %s', d.reveal())

But If I use get_raw_input_from() to get the inputs as the following code segment, The result is wrong as shown in the following picture .

a = sint.get_raw_input_from(0)
b = sint.get_raw_input_from(1)
c = sint.get_raw_input_from(2)
d = (a+b)*c
print_ln('Result is %s', d.reveal())

5ZWXMQ}%~Y}YG`Z$HC2}(KE
I complete the following steps to run it.

echo 10 2 > gf2n_vals.in
./gen_input_f2n.x
mv gf2n_vals.out Player-Data/Private-Input-0

echo 10 3 > gf2n_vals.in
./gen_input_f2n.x
mv gf2n_vals.out Player-Data/Private-Input-1

echo 10 4 > gf2n_vals.in
./gen_input_f2n.x
mv gf2n_vals.out Player-Data/Private-Input-2

./compile.py add
./mascot-party.x num add  -pn 8000 -h localhost -N 3    
#run in three terminals,where num belongs to {0,1,2}

Benchmark the program cost

Hi MP-SPDZ team,

I am trying to benchmark the online and offline phases using semi-honest protocols, but unclear with the following aspects:

  1. I was informed to use -F parameter with semi-party.x to specify semi-honest additive secret sharing protocol in the online phase. A question is how to benchmark the computational cost of the offline phase using the same protocol?

  2. Is there an easy way to benchmark the communication cost of the protocols? I noticed that in scale-mamba, it gives the information of the number of communication round, triples used, etc. So I wonder if mp-spdz can also measure these information.

  3. Does the online phase support parallelism to accelerate the computation?

Any suggestions would be highly appreciated.

Best regards,
Yuncheng

Compiling issue on MacOS Mojave

OS: MacOS Mojave 10.14.4
g++ : homebrew gcc 8.3.0

When I compile with "Scripts/tldr.sh"

Errors

/usr/local/bin/g++ -march=native -I/usr/local/opt/openssl/include -I/usr/local/opt/openssl/include -I/usr/local/opt/openssl/include -I/usr/local/opt/libsodium/include -I/usr/local/opt/openssl/include -I/usr/local/opt/libsodium/include -I/usr/local/opt/boost/include -I/usr/local/opt/openssl/include -I/usr/local/opt/libsodium/include -I/usr/local/opt/boost/include -I/usr/local/opt/openssl/include -I/usr/local/opt/libsodium/include -I/usr/local/opt/boost/include -I/usr/local/opt/mpir/include -I/usr/local/opt/openssl/include -I/usr/local/opt/libsodium/include -I/usr/local/opt/boost/include -I/usr/local/opt/mpir/include -I/usr/local/opt/openssl/include -I/usr/local/opt/libsodium/include -I/usr/local/opt/boost/include -I/usr/local/opt/mpir/include -IMath/ -I/usr/local/opt/openssl/include -I/usr/local/opt/libsodium/include -I/usr/local/opt/boost/include -I/usr/local/opt/mpir/include -IMath/ -I/usr/local/opt/openssl/include -I/usr/local/opt/libsodium/include -I/usr/local/opt/boost/include -I/usr/local/opt/mpir/include -IMath/ -I/usr/local/opt/openssl/include -I/usr/local/opt/libsodium/include -I/usr/local/opt/boost/include -I/usr/local/opt/mpir/include -IMath/ -I/usr/local/opt/openssl/include -I/usr/local/opt/libsodium/include -I/usr/local/opt/boost/include -I/usr/local/opt/mpir/include -IMath/ -g -Wextra -Wall -O3 -I. -pthread -DDEBUG -DUSE_GF2N_LONG '-DPREP_DIR="Player-Data/"' -std=c++11 -Werror -o Player-Online.x Player-Online.cpp Machines/SPDZ.o Math/BitVec.o Math/Integer.o Math/Setup.o Math/Share.o Math/Subroutines.o Math/Z2k.o Math/Zp_Data.o Math/bigint.o Math/gf2n.o Math/gf2nlong.o Math/gfp.o Math/modp.o Tools/Buffer.o Tools/Commit.o Tools/Config.o Tools/FlexBuffer.o Tools/Lock.o Tools/MMO.o Tools/OfflineMachineBase.o Tools/Signal.o Tools/aes-ni.o Tools/aes.o Tools/mkpath.o Tools/names.o Tools/octetStream.o Tools/random.o Tools/sha1.o Tools/time-func.o Networking/CryptoPlayer.o Networking/Player.o Networking/Receiver.o Networking/STS.o Networking/Sender.o Networking/Server.o Networking/ServerSocket.o Networking/sockets.o Auth/Subroutines.o Auth/Summer.o Processor/BaseMachine.o Processor/DataPositions.o Processor/ExternalClients.o Processor/OnlineOptions.o Processor/PrivateOutput.o Processor/ProcessorBase.o Processor/Program.o OT/BaseOT.o OT/BitMatrix.o OT/BitVector.o OT/NPartyTripleGenerator.o OT/OTExtension.o OT/OTExtensionWithMatrix.o OT/OTMachine.o OT/OTMultiplier.o OT/OTTripleSetup.o OT/Tools.o OT/TripleMachine.o SimpleOT/libsimpleot.a -lmpirxx -lmpir -lsodium -L/usr/local/opt/openssl/lib -L/usr/local/opt/openssl/lib -L/usr/local/opt/openssl/lib -L/usr/local/opt/libsodium/lib -L/usr/local/opt/openssl/lib -L/usr/local/opt/libsodium/lib -L/usr/local/opt/boost/lib -L/usr/local/opt/openssl/lib -L/usr/local/opt/libsodium/lib -L/usr/local/opt/boost/lib -L/usr/local/opt/openssl/lib -L/usr/local/opt/libsodium/lib -L/usr/local/opt/boost/lib -L/usr/local/opt/mpir/lib -L/usr/local/opt/openssl/lib -L/usr/local/opt/libsodium/lib -L/usr/local/opt/boost/lib -L/usr/local/opt/mpir/lib -L/usr/local/opt/openssl/lib -L/usr/local/opt/libsodium/lib -L/usr/local/opt/boost/lib -L/usr/local/opt/mpir/lib -L/usr/local/opt/openssl/lib -L/usr/local/opt/libsodium/lib -L/usr/local/opt/boost/lib -L/usr/local/opt/mpir/lib -L/usr/local/opt/openssl/lib -L/usr/local/opt/libsodium/lib -L/usr/local/opt/boost/lib -L/usr/local/opt/mpir/lib -L/usr/local/opt/openssl/lib -L/usr/local/opt/libsodium/lib -L/usr/local/opt/boost/lib -L/usr/local/opt/mpir/lib -L/usr/local/opt/openssl/lib -L/usr/local/opt/libsodium/lib -L/usr/local/opt/boost/lib -L/usr/local/opt/mpir/lib -lboost_system -lssl -lcrypto Undefined symbols for architecture x86_64: "operator<<(std::basic_ostream<char, std::char_traits<char> >&, __mpf_struct const*)", referenced from: void Program::execute<Share<gfp_<0> >, Share<gf2n_long> >(Processor<Share<gfp_<0> >, Share<gf2n_long> >&) const in SPDZ.o void Program::execute<Spdz2kShare<64, 64>, Share<gf2n_long> >(Processor<Spdz2kShare<64, 64>, Share<gf2n_long> >&) const in SPDZ.o void Program::execute<Spdz2kShare<64, 48>, Share<gf2n_long> >(Processor<Spdz2kShare<64, 48>, Share<gf2n_long> >&) const in SPDZ.o "operator<<(std::basic_ostream<char, std::char_traits<char> >&, __mpz_struct const*)", referenced from: write_online_setup(std::basic_ofstream<char, std::char_traits<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bigint const&, int) in Setup.o Z2<32>::output(std::basic_ostream<char, std::char_traits<char> >&, bool) const in Z2k.o Z2<64>::output(std::basic_ostream<char, std::char_traits<char> >&, bool) const in Z2k.o Z2<96>::output(std::basic_ostream<char, std::char_traits<char> >&, bool) const in Z2k.o Z2<128>::output(std::basic_ostream<char, std::char_traits<char> >&, bool) const in Z2k.o Z2<160>::output(std::basic_ostream<char, std::char_traits<char> >&, bool) const in Z2k.o Z2<192>::output(std::basic_ostream<char, std::char_traits<char> >&, bool) const in Z2k.o ... "operator>>(std::basic_istream<char, std::char_traits<char> >&, __mpz_struct*)", referenced from: read_setup(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) in Setup.o Z2<32>::input(std::basic_istream<char, std::char_traits<char> >&, bool) in Z2k.o Z2<64>::input(std::basic_istream<char, std::char_traits<char> >&, bool) in Z2k.o Z2<96>::input(std::basic_istream<char, std::char_traits<char> >&, bool) in Z2k.o Z2<128>::input(std::basic_istream<char, std::char_traits<char> >&, bool) in Z2k.o Z2<160>::input(std::basic_istream<char, std::char_traits<char> >&, bool) in Z2k.o Z2<192>::input(std::basic_istream<char, std::char_traits<char> >&, bool) in Z2k.o ... ld: symbol(s) not found for architecture x86_64 collect2: error: ld returned 1 exit status make[1]: *** [Player-Online.x] Error 1 make: *** [tldr] Error 2

I added some MY_CFLAGS path.

brew is /usr/local/bin/brew Now making tldr brew install openssl boost libsodium mpir yasm Warning: openssl 1.0.2r is already installed and up-to-date To reinstall 1.0.2r, run brew reinstall opensslWarning: boost 1.69.0_2 is already installed and up-to-date To reinstall 1.69.0_2, runbrew reinstall boostWarning: libsodium 1.0.17 is already installed and up-to-date To reinstall 1.0.17, runbrew reinstall libsodiumWarning: mpir 3.0.0 is already installed and up-to-date To reinstall 3.0.0, runbrew reinstall mpirWarning: yasm 1.3.0_2 is already installed and up-to-date To reinstall 1.3.0_2, runbrew reinstall yasm echo MY_CFLAGS += -I/usr/local/opt/openssl/include >> CONFIG.mine echo MY_LDLIBS += -L/usr/local/opt/openssl/lib >> CONFIG.mine echo MY_CFLAGS += -I/usr/local/opt/libsodium/include >> CONFIG.mine echo MY_LDLIBS += -L/usr/local/opt/libsodium/lib >> CONFIG.mine echo MY_CFLAGS += -I/usr/local/opt/boost/include >> CONFIG.mine echo MY_LDLIBS += -L/usr/local/opt/boost/lib >> CONFIG.mine echo MY_CFLAGS += -I/usr/local/opt/mpir/include >> CONFIG.mine echo MY_LDLIBS += -L/usr/local/opt/mpir/lib >> CONFIG.mine echo MY_CFLAGS += -IMath/ >> CONFIG.mine echo ARCH = -march=native >> CONFIG.mine

It seems the "operators" missed?

List indices must be integers, not regint

Hi MP-SPDZ team,

I am trying the ExternalIO part based on the bankers_bonus.mpc program, which is to receive values from client and convert them into sfix type. I got the "TypeError: list indices must be integers, not regint". The code is as follows where I try to receive "size" values, and the problem occurs by "client_inputs[i]".

client_inputs = sint.receive_from_client(size, client_socket_id)
# process the sint values, convert to sfix values for computations
client_inputs_sfix = Array(size, sfix)
@for_range(size)
def _(i):
client_inputs_sfix[i].v = client_inputs[i]
client_inputs_sfix[i].f = FIXED_F

Any help would be highly appreciated.

Thanks and best regards,
Yuncheng

Generate secure preprocessed data for semi-honest protocol

Hello MP-SPDZ team,

I just start to study MPC, I am trying to use the semi-honest MASCOT protocol to benchmark online phase (semi-party.x). And I prefer to generate the preprocessed data in a secure and suitable way, so I do not want to use the setup-online or Fake-Offline.x. But when I use spdz2-offline.x,

./spdz2-offline.x -m -p 0 -h host
./spdz2-offline.x -m -p 1 -h host

./compile.py -F 64 TEST

./semi-party.x -F -h host -N 2 0 TEST
./semi-party.x -F -h host -N 2 1 TEST

It throws a file_error:

Purging preprocessed data because something is wrong
Removing Player-Data/2-128-40/Triples-Dp-P0
Removing Player-Data/2-128-40/Squares-Dp-P0
Removing Player-Data/2-128-40/Bits-Dp-P0
Removing Player-Data/2-128-40/Inverses-Dp-P0
Removing Player-Data/2-128-40/Inputs-Dp-P0-0
Removing Player-Data/2-128-40/Inputs-Dp-P0-1
Removing Player-Data/2-128-40/Triples-D2-P0
Removing Player-Data/2-128-40/Squares-D2-P0
Removing Player-Data/2-128-40/Bits-D2-P0
Removing Player-Data/2-128-40/Inverses-D2-P0
Removing Player-Data/2-128-40/BitTriples-D2-P0
Removing Player-Data/2-128-40/BitGF2NTriples-D2-P0
Removing Player-Data/2-128-40/Inputs-D2-P0-0
Removing Player-Data/2-128-40/Inputs-D2-P0-1
terminate called after throwing an instance of 'file_error'
what(): File Error : IO problem when buffering gfp Triples from Player-Data/2-128-40/Triples-Dp-P0

So what should I do to solve this?
I appreciate any help.

Sincerely, Li

Online-only SPDZ-2k

In the README, I found enough documentation on how to benchmark just the online phase for SPDZ. However, I couldn't find any for SPDZ-2k. I looked into the scripts for the same, but could not find anything for a fake offline phase for rings.
I want to run just the online phase of the protocol to quickly evaluate the changes I am making to the application built on top of SPDZ-2k.
Is there some script that I could use for the same? If not, I would really appreciate some pointers towards writing one.

Error encountered in run-common.sh

While following the instructions given in tutorial.md, I tried running the command sh Scripts/run-online.sh addition for the first example with cint. I encounter the following error-

Scripts/run-online.sh: 21: /home/user/mp-spdz-0.1.0/Scripts/run-common.sh: Syntax error: "(" unexpected (expecting "then")

Writing and reading memory

Is it possible to persist the secret shares produced by one application, to later load them from another app?

In particular, I have an application that computes a Matrix of sints, and another application that needs that matrix for further computation. I've played around with store_in_mem but I've been unable to load the stored results from my second application; they don't seem to be written to disk at any point. I also found write_shares_to_socket; is there an equivalent function for writing to a file?

Thanks!

How to use the statement of “if” in SPDZ

Hi,
I have some problem about "if statement" in SPDZ,such as the following code:

l1=Array(3,sint)
l2=Array(3,sint)
l1=[0,1,2]
l2=[1,2,3]
match = l1[0]<l2[0]
mid = match.reveal()
if_then(mid)
del l1[0]
else_then()
del l2[0]
end_if()

Why did it ignore my "else_then", and execute "del l2[0]" again after execute "del l1[0]"?
How should I use the "if statement" in SPDZ (data on "cint" and "sint" types)?
I appreciate your time ,and thank you very much.

get started with simple arithmetic circuits

Hi, I want to build a simple arithmetic circuit in GF(2^n), E.g., n=128. I want to run it in SPDZ with preferably MOSCOT preprocessing. Could you provide some instructions as to:

  • What type to use in Python-like .asm to represent GF elements?
  • What parameters to use in ./compile.py?
  • Is there a way to test the Program before running it through SPDZ/MASCOT?
  • Do I need to change CONFIG?

Thanks a lot!

Data sent in v0.1.0

Hi,
after updating MP-SPDZ to version 0.1.0 from the previous one 0.0.9, I noticed that the "data sent" outputted on stdout by mascot-party.x is quite different for the same program.
In 0.0.9 my program had 3.7 MB of data sent, now it is 0.05 MB.
What is changed? By my theoretical computations the volume of data should be the previous (considering preprocessing and online phase).
I'm using MASCOT with 2 party.

Thanks,
Giuseppe

Show public result in `Public-Output-0-0` (for example) files

Hi,

I'm just new to this library, probably a stupid question: How to get the public results printed in files such as Public-Output-1-0?

Let's say in "millionaire's game", there's a private input '1' from party 0 and '0' from part 1, and then how to print the public result "0" (because apparently party 0 wins) into Public-Output-0-0 and Public-Output-1-0?

Thanks

Is there a way to use precomputed input shares?

I am a beginner doing SPDZ related research.
Thanks to bristol crypto's MP-SPDZ project, I can study many MPCs and benchmarks.

While studying this project, I had the following questions.

  1. When P1 and P2 perform a MPC protocol, is it possible to use the input shares previously calculated by P1 and is there security problems?
  2. If so, how should the code be written for MP-SPDZ (.mpc file)?

Let me explain with a concrete example.
(Preprocessing phase)

  1. P1 and P2 produce random input pairs <r1>, <r2_1>,...,<r2_n>.
  2. They produce the Beaver's triples and so on, to compute circuit f(u, v) n times at the "online phase 2".

(Online phase 1)

  1. P1 produces the input share <x> with P2 using P1's input x and preprocessed input pair r1, <r1>.
  2. P1 and P2 don't remove <x> for later use.
  3. P1 and P2 don't have <r1> anymore. That is, they remove <r1>. (Is this possible?)

(Online phase 2)

  1. P1 produces the input share <y_i> with P2 using P1's input y_i and preprocessed input pair r2_i, <r2_i>.
  2. P1 and P2 perform some secure computation of f (x, y_i) using MPC protocol (such as SPDZ).
  3. They repeats the same and the secure circuit f with the other P1's input y_i for all i.

Is this possible without compromising security?
In other words, can P1 or P2 reveal the secret value x after the online phase 2 or later?

So how can this be implemented in MP-SPDZ?

Please help.....

Compilation Time of Source Programs

I observed that the compile.py script is only utilising a single thread. Can multi CPU cores be exploited for compilation of source programs (.mpc files)?
Is there something I should keep in mind while writing these source programs so as to get a better compilation time (for SPDZ2k)?

Compiling on ARM platform

Hi,
some parts of the library rely on intrinsic functions specific for x86 platforms.
This means that it is not possible to compile the lib for other platforms, and in particular for ARM.
Is there any plan to include that possibility in the future? or any effort in that direction anyone is aware of?

Merging open instructions leads to incorrect computation

Hey, an application I'm working on produces incorrect results unless I compile with the --nomerge flag, in which case I do consistently see the expected results.

To make things more interesting, the application is fairly complex and for the time being in a private repo. So far I haven't been able to come up with a simplified example that reproduces the issue.

Do you have any general tips as to how to debug this, i.e., is there a common, easy-to-spot issue that might be causing this?

Thanks, and sorry for not having anything more concrete! I'll keep working on a simplified example/debug this further in the meantime, just figured I'd ask in parallel.

Handshake with other party failed

I don't know why it occurs this error, I have run it on three machines successfully before. Each party's pem is in directory Player-Data/, and I re-run setup-ssl.sh and setup-online.sh, but it failed again.
3DV6KN7OJ9_}PDE3J@N94FL
JQF}$JX89{YH$4ZRA$ZA99
RDD_BJJNJP0MJQQ9{NA7UTV

Modifying SecureNN Benchmarks

Is there a straightforward way to add ReLU layer and 64-bit integer quantization to the example file MP-SPDZ/Programs/Source/benchmark_secureNN.mpc?

In this file, the 4 SecureNN neural networks are written, but I don't see a ReLU activation between different layers. Is ReLU being simulated in some way?

I observed that the file runs 8-bit quantized networks. It is written in these lines:

p1 = squant_params(sfloat(.001), sint(1), 8)
p2 = squant_params(sfloat(.002), sint(2), 8)
p3 = squant_params(sfloat(.003), sint(3), 8)

If I change the last argument to 64, does it make the quantization 64-bit?

Probem about extracting the code for communication

Hi,
I want to Extract the code for the communication from MP-SPDZ, which can implement many-to-many communications and broadcast, but I don’t need to use OpenSSL for secure channels. But after I did it for a while, I found it difficult to do that. so does SPDZ-2,which do not use OpenSSL. Could you please give me some suggestions?

Batched Communication and Private Output

The Cowgear paper talks about conducting parallel multiplications such that communication gets merged in a single round. Is this something that can be achieved by using get_vector() command and multiplying the resulting vector?

Also, the framework provides reveal() function in order to reveal a secret value to all parties. What can be done in order to reveal secret-values to a particular party?

justification for noise formula

The formula below does not seem to agree with the usual FHE noise analysis -- could you provide justification?

B_KS = p * phi_m * sigma
* (pow(n, 2.5) * (1.49 * sqrt(h * phi_m) + 2.11 * h)
+ 2.77 * n * n * sqrt(h)
+ pow(n, 1.5) * (1.96 * sqrt(phi_m) * 2.77 * sqrt(h))
+ 4.62 * n);

Data sent discrepency between release v0.1.1 and v0.1.0

Hi,
I have observed that the Data sent value reported when I run pre-included benchmarks varies a lot when I run the same benchmark with v0.1.1 and v0.1.0.
The communication numbers reported by latest version i.e., v0.1.1 is actually an order or sometimes 2 orders of magnitudes more than the communication numbers reported by v0.1.0.

I was running the following backends:

  1. Mascot 2-party
  2. SPDZ2k 2-party

I wanted to know which of the above 2 versions is reporting the wrong numbers.

make MP-SPDZ with out of the bounds error

while i'm making the project, i encounter the following error :

g++ -no-pie -mtune=native -mavx -g -Wextra -Wall -O3 -I. -pthread -DUSE_GF2N_LONG '-DPREP_DIR="Player-Data/"' -maes -mpclmul -msse4.1 -mavx -mavx2 -mbmi2 --std=c++11 -Werror -MMD -c -o Tools/random.o Tools/random.cpp
In member function 'void PRNG::SetSeed(PRNG&)':
cc1plus: error: 'void* __builtin_memcpy(void*, const void*, long unsigned int)' forming offset [17, 32] is out of the bounds [0, 16] of object 'tmp' with type 'octet [16]' {aka 'unsigned char [16]'} [-Werror=array-bounds]
Tools/random.cpp:34:9: note: 'tmp' declared here
octet tmp[SEED_SIZE];
^~~
cc1plus: all warnings being treated as errors

how do i fixed it, thank you

Are URLs supported in the list of players

When running the online phase the service discovery is done by the Server.x which hands out a list of ip addresses received from the registered clients. One could also bypass this mechanism by specifying the list of IPs by providing the --ip-file-name parameter when running Player-Online.x.
Would it be also possible to specify a list of URLs instead of the real IPs to support players from different networks?
I was not able to find it in the code, I'm a bit new to the topic so maybe I'm just missing something obvious.
Thank you in advance.

Memory error

We modified aes.mpc to test the encryption time of 10,000 times, I put 10000 keys in Player-Data/Private-Input-0, and 10,000 plaintexts in Player-Data/Private-Input-1 , then compile aes.mpc, after compiling for a while, it occurs an error as follows, I wonder know if there exits a solution to fix it. our virtual machine's memory is 128G, and the disk space is 500G.
IMG_20191122_203930

Problems of semi-honest protocol

Hi MP-SPDZ team,

I am a new to MP-SPDZ and I am trying to use semi-honest shamir-party protocol. The first step is to setup the certificates. However, I received the following error.

Setting up SSL for 3 parties
openssl: relocation error: openssl: symbol EVP_mdc2 version OPENSSL_1_1_0 not defined in file libcrypto.so.1.1 with link time reference
openssl: relocation error: openssl: symbol EVP_mdc2 version OPENSSL_1_1_0 not defined in file libcrypto.so.1.1 with link time reference
openssl: relocation error: openssl: symbol EVP_mdc2 version OPENSSL_1_1_0 not defined in file libcrypto.so.1.1 with link time reference
Doing Player-Data

By the way, I have another two questions. The first is that does MP-SPDZ support semi-honest additive secret sharing? The second is that, is it possible that I have an external application that calls MP-SPDZ as a library iteratively, i.e., sends input to the mpc program and receives the output in each iteration? This can be achieved using scale-mamba library, but it only supports malicious protocols. So I would be better if I can use MP-SPDZ to solve the problem.

Any help would be highly appreciated.

Thanks and best regards,
Yuncheng

Sporadic increase in the player-online execution time

When running a game with the following command ./Player-Online.x 0 test -N 2 --ip-file-name ipfile.
The following CONFIG.mine is used:

USE_NTL = 0
USE_GF2N_LONG = 0
MOD = -DMAX_MOD_SZ=6
ARCH = -march=native
MY_CFLAGS = -DINSECURE -DVERBOSE -DDEBUG_THREADS -DTIME_ROUNDS

Periodically I see games with a relatively long execution time, e.g. in the range of 6-12s. When typical games are finished in the range of milliseconds.

Here is the log output of Player1:

Reading MAC keys from Player-Data/2-128-40//Player-MAC-Keys-p-P0
Cost of first tape:
Waiting for thread 0 to be ready
	I am in thread 0
Using single-threaded receiving
	Set up player in thread 0
Using indirect communication.
Exchange time: 5.91052 seconds and 10343936 iterations to receive 0.016 KB
Exchange time: 3.7e-06 seconds and 2 iterations to receive 0.036 KB
Locking for sync of thread 0
Start listening on thread 140120489457408
Party 0 is listening on port 10000 for external client connections.
Thread 140120489457408 found server.
Party 0 received external client connection from client id: 0
Result is 222
Exchange time: 0.00387421 seconds and 6455 iterations to receive 0.016 KB
Exchange time: 3.8e-06 seconds and 2 iterations to receive 0.036 KB
Exchange time: 0.00649372 seconds and 11380 iterations to receive 0.02 KB
Compiler: ./compile.py mpc-program
Waiting for all clients to finish
	Thread 0 terminating
Opened 1 elements in 1 rounds
0 : MAC Checking
	MC2.number=0
	MCp.number=1
Thread 0 timer: 0.0127693
Thread 0 wait timer: 5.2401e-05
Broadcasting 0.000124 MB in 5 rounds, taking 6.74147 seconds
Sending directly 1.6e-05 MB in 1 rounds, taking 9.0001e-05 seconds
Receiving took 3.1e-06 seconds
Join timer: 0 0.0634782
Finish timer: 0.00380891
Process timer: 0.0133595
Time = 0.0674831 seconds
Data sent = 0.00014 MB
Summed all shares at once
Full broadcast
Actual cost of program:
End of prog

The log output of Player2:

Reading MAC keys from Player-Data/2-128-40//Player-MAC-Keys-p-P1
Cost of first tape:
Waiting for thread 0 to be ready
	I am in thread 0
Using single-threaded receiving
	Set up player in thread 0
Using indirect communication.
Exchange time: 5e-06 seconds and 2 iterations to receive 0.016 KB
Exchange time: 0.00468721 seconds and 6583 iterations to receive 0.036 KB
Locking for sync of thread 0
Start listening on thread 140551348758272
Party 1 is listening on port 10001 for external client connections.
Thread 140551348758272 found server.
Party 1 received external client connection from client id: 0
Exchange time: 3.1e-06 seconds and 2 iterations to receive 0.016 KB
Exchange time: 0.00673002 seconds and 10726 iterations to receive 0.036 KB
Exchange time: 3.9e-06 seconds and 2 iterations to receive 0.02 KB
Compiler: ./compile.py mpc-program
Waiting for all clients to finish
	Thread 0 terminating
Opened 1 elements in 1 rounds
0 : MAC Checking
	MC2.number=0
	MCp.number=1
Thread 0 timer: 0.0080866
Thread 0 wait timer: 0.000149701
Broadcasting 0.000124 MB in 5 rounds, taking 0.0137277 seconds
Sending directly 1.6e-05 MB in 1 rounds, taking 3.3601e-05 seconds
Receiving took 0.00619302 seconds
Join timer: 0 0.0594035
Finish timer: 0.0105991
Process timer: 0.00873885
Time = 0.0704512 seconds
Data sent = 0.00014 MB
Summed all shares at once
Full broadcast
Actual cost of program:
End of prog

The interesting lines from the first player are:

Exchange time: 5.91052 seconds and 10343936 iterations to receive 0.016 KB
Broadcasting 0.000124 MB in 5 rounds, taking 6.74147 seconds

So it took ~6s to read a tiny chunk of data.

Can you think of a scenario which could cause such a delay?

Broken round counter when using loopy_chunkier sort

When compiling the one-line file

loopy_chunkier_odd_even_merge_sort(Array(32, sint))

compile.py cannot output the number of rounds. Towards the end of the output it prints:

Going to unknown from inf rounds in all, inf invs in all
Tape requires inf rounds in all, inf invs in all
Program requires: {('all', 'round'): inf, ('all', 'inv'): inf, ('modp', 'bit'): 12224, ('modp', 'triple'): 22920}
Cost: nan

problem of aes.mpc

I have run aes.mpc, but I didn't run the offline phase for generating some triples, I saw in your paper that it required a large number of triples to be generated for online phase. I wonder if the aes.mpc in this project requires triples or offline phase.

fixed point multiplication throws core dumped error

mpc file :

sfix.set_precision(32, 64)
cfix.set_precision(32, 64)

a = sfix(1.1)
b = sfix(2.1)

prod = a * b
print_ln('prod = %s', prod.reveal());

the error msg:
Tape requires prime of bit length 169
terminate called after throwing an instance of 'invalid_params'
what(): Invalid Params
Aborted (core dumped)

And if I change the precision setting to (16, 32), it works well.

for_range loops and regint

I am trying to get public input from a file by importing the io python library through the following function:

import io

def read_public_matrix(filename, matrix):
    with io.open(filename) as f:
        lines = f.readlines()
        f.seek(0)
        @for_range(len(lines))
        def _(i):
            line = f.readline().split()
            @for_range(len(line))
            def _(j):
                token = line.pop(0)
                matrix[i][j] = cfix(cint(int(token)))

I have written it this way to avoid using separate python integers (other than i, j) to maintain the iteration number and use them to index lists, since regint is not compatible with python lists.
When I run this function, I end up with the same value (i.e. matrix[0][0]) in all the positions of the matrix.
In this regard, I have the following questions:

  • It seems that the loop body is not being performed sequentially according to the iteration number. Could you please explain how the for_range decorator executes the loop body?
  • I am using for_range decorator to improve the compile time of my program. Is there any other construct I can use to achieve the desired effect?
  • Can I convert regint to a python int so as to make it compatible with other python types?
  • Is there a better way to input public data?

How to run AES?

Can you provide documentation on how to compile and run the aes circuit? I tried Yao’s Player but didn’t work. Which protocol should I use?

Player-Online exits if the tcp connection was closed

In some cases it might be required to connect to a player without sending any data and starting the actual computation, and then disconnect. For example in order to verify the player has come up online.
Currently it is possible to connect, but the attempt to close the tcp connection causes the crash of the player.

How to reproduce.

  1. Start a player:
./Player-Online.x 1 mpc-test -N 2 --ip-file-name ./ip-file
  1. Use telnet to connect:
telnet localhost 5001
  1. Close the TCP connection
  2. See the crash of the player:
terminate called after throwing an instance of 'std::runtime_error'
  what():  connection closed down
Aborted

Do you think we must fix this behaviour?

sfix Matrix value reveal error

I want to read data from 3 party and do some computation, here is my code

ROW = 1
COL = 10
PARTY = 3

value = Matrix(ROW * PARTY, COL, sfix)
weight = Matrix(ROW * PARTY, COL, sint)

value.assign_all(0)
weight.assign_all(0)

for i in range(ROW):
  for k in range(PARTY):
    for j in range(COL):
      t = sfix.from_sint(sint.get_input_from(k))
      value[PARTY * i + k][j] = t
      print_ln('read value: %s', value[PARTY * i + k][j].reveal()) # right
    for j in range(COL):
      weight[PARTY * i + k][j] = sint.get_input_from(k)

print_ln('value[0][1] %s', value[0][1].reveal()) # weird
print_ln('weight[0][1] %s', weight[0][1].reveal())

and input file is(same for 3 parties)

0 11 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0

now the code could output the right value at the moment it finish assignment, but the second last print_ln will output 9.53674e-07. And there's a segfault at last. Full output is

ServerSocket is bound on port 4999
Waiting for player 0
Sent Connected to player 0
Waiting for player 1
0 to 127.0.0.1:4999
Connected to player 1
Waiting for player 2
Connected to player 2
Player 0 started.
My Name = 127.0.0.1
My number = 0
Player 0 sent (IP for info only) 127.0.0.1:5000
Client IP address: 127.0.0.1
Player 1 started.
Player 1 sent (IP for info only) 127.0.0.1:5001
Client IP address: 127.0.0.1
Player 2 started.
Player 2 sent (IP for info only) 127.0.0.1:5002
Client IP address: 127.0.0.1
3 players
Player 0 is running on machine 127.0.0.1                            
Player 1 is running on machine 127.0.0.1
Player 2 is running on machine 127.0.0.1
ServerSocket is bound on port 5000
loading params from: Player-Data/3-128-128/Params-Data
Using GF(2^128)
MAC Key p = -49706636798366209764019861759806023269
MAC Key 2 = 88c9aa6193cb7f39114f97927c35c634
Opening file Programs/Schedules/cotton1.sch
Number of threads I will run in parallel = 1
Number of program sequences I need to load = 1
Loading program 0 from Programs/Bytecode/cotton1-0.bc
cotton1-0 needs more secret gf2n_long memory, resizing to 8192
cotton1-0 needs more clear gf2n_long memory, resizing to 8192
cotton1-0 needs more secret gfp memory, resizing to 8222
cotton1-0 needs more clear gfp memory, resizing to 8192
cotton1-0 needs more clear integer memory, resizing to 8194
Cost of first tape:
Waiting for thread 0 to be ready
        I am in thread 0
Using single-threaded receiving
Setting up send to self socket to 127.0.0.1:5000 with id 0x0
Setting up client to 127.0.0.1:5001 with id 0x0
Setting up client to 127.0.0.1:5002 with id 0x0
As a server, waiting for client with id 0x0 to connect.              
        Set up player in thread 0
Setting up Data_Files in: Player-Data/3-128-128/
done
Setting up Data_Files in: Player-Data/3-128-128/
done
Using indirect communication.
Opening file Programs/Public-Input/cotton1
Opening file Player-Data/Private-Input-0
Opening file Player-Data/Public-Output-0
Opening file Player-Data/Private-Output-0
opening Player-Data/Input-P0-0
Locking for sync of thread 0
read value: 0
read value: 11
read value: 0
read value: 0
read value: 0
read value: 0
read value: 0
read value: 0
read value: 0
read value: 0
read value: 0
read value: 11                                                     
read value: 0
read value: 0
read value: 0
read value: 0
read value: 0
read value: 0
read value: 0
read value: 0
read value: 0
read value: 11
read value: 0
read value: 0
read value: 0
read value: 0
read value: 0
read value: 0
read value: 0
read value: 0
value[0][1] 9.53674e-07
weight[0][1] 1
Compiler: ./compile.py Programs/Source/cotton1.mpc
[1]    117720 segmentation fault  ./Player-Online.x -N 3 -h 127.0.0.1 0 cotton1

Calls to reveal_to() does not work

Hi, I modified aes.mpc to output the ciphertext to player 1 and player 2, I run aes.mpc in three machines, but the player 1 and player 2 do not obtain ciphertext, moreover the player 0 output the ciphertext three times as follows. The changed code is as follows. Finally, I wonder if there exits a latest documentation about MP-SPDZ like SCALE-MAMBA .
`CC6S@U} O~R1KKIJZO26Y5
4%ED(BOR3{_ 6_JDL789QVO
JANF9YU(_SUHSYELS)7_SR7
WNWH0SY~(ETC{UX(7H W)V6

Conflict between MPIR and GMP

I want to use SPDZ as a third party dependency in my project. However, my project uses some other libraries which include the gmp.h. And mpir.h and gmp.h will cause the conflict.
Do you have any solution to solve this conflict?

problem about prepared share

Hi, mkskeller
If I use the high-level functionality to implement a new function named test.mpc to compare two number x and y, then I run it using semi-honest Shamir secret sharing scheme with shamir-party.x , I may define x=sint(1), y=sint(2) in test.mpc, then running the .mpc will compare x and y securely.
But if I(carol) precompute the share x1,x2 of x, the share y1,y2 of y, then I distribute x1 and y1 to Alice. distribute x2 and y2 to Bob. Moreover, Alice and Bob don't know x either y. Then Alice and Bob run a 2PC to compare x and y. is it feasible to use shamir-party.x in MP-SPDZ to achieve that ? if so, how should I do?
In my understanding of MP-SPDZ, If I use shamir-party.x to run a .mpc like the given example, it may split Alice's x and Bob's y into shares, then compare them securely, but know I have prepared share of x and y mentioned in above. Can I use MP-SPDZ to implement that, Could you please give me some suggestions?

`

Multiplication and division by a public value

I have been trying to perform multiplication and division of a secret intermediate value (sfix type) with a public constant. However, it ends up taking the same time it would've taken to multiply / divide by a secret value. I would imagine that SPDZ compiler isn't automatically doing local multiplications in this case. Is there a way to force the compiler to do that?

Online-only Benchmarking

I wish to setup for the online-only benchmarking of cowgear-party.x, how can I run Fake-Offline.x to do so?
Moreover, can you please specify which paper is the protocol being emulated by ./Player-Online.x based on?

Error when running oblivious shuffle

Following code produces a compile time error:

from Compiler.types import sint, Array
from permutation import shuffle, config_shuffle

src = Array(4, sint)
src[0] = sint(0)
src[1] = sint(1)
src[2] = sint(2)
src[3] = sint(3)

config = config_shuffle(len(src), value_type=sint)
shuffle(src, config, value_type=sint)

The error is NameError: global name 'inwards' is not defined. Looking at the code of iter_waksman in permutation.py, inwards is indeed undefined.

Do I have to set it externally?

Follow up

Setting inwards to 1 allows the program to compile and run, however, the permutation does not seem to be applied correctly.

In the code below, I've modified config_shuffle to take a hard-coded permutation. The result of applying that permutation to the input does not look right:

# Modified to accept permutation
def config_shuffle_with_perm(perm, value_type):
    """Compute config for oblivious shuffling.

    Take mod 2 for active sec. """
    n = len(perm)
    if n & (n - 1) != 0:
        # pad permutation to power of 2
        m = 2 ** int(math.ceil(math.log(n, 2)))
        perm += range(n, m)
    config_bits = configure_waksman(perm)
    # 2-D array
    config = Array(len(config_bits) * len(perm), value_type.reg_type)
    for i, c in enumerate(config_bits):
        for j, b in enumerate(c):
            config[i * len(perm) + j] = b
    return config

src = Array(4, sint)
src[0] = sint(0)
src[1] = sint(1)
src[2] = sint(2)
src[3] = sint(3)
my_perm = [1, 0, 2, 3]
config = config_shuffle_with_perm(my_perm, value_type=sint)
iter_waksman(src, config)
# This prints 0 1 2 3, but should be 1 0 2 3
for el in src:
    print_str("%s ", el.reveal())
print_ln()

The first two elements above should be swapped, according to the permutation.

When I try other permutations, the elements do get re-arranged but not always consistently with the chosen permutation.

Invalid Instruction in Zp_data

Dear MP-SPDZ team,

after testing mps-spdz in virtual box (worked fine) I decided to install on native debian linux.
Running the tutorial (or any other mpc), I get an 'Invalid Instruction', which gets thrown from Math/Zp_data.cpp, l.20:
mask=(1LL<<((mpz_sizeinbase(pr.get_mpz_t(),2)-1)%(8*sizeof(mp_limb_t))))-1;

I followed the same installation procedure in vbox and 2 different native linux boxes, with the native linux boxes both showing the same behavior.

Are there any know mistakes I might have done / any known issues?

Chris

P.S.: the gh readme states it's preferred to ask questions here (not in the google group) -> is it ok to ask some question regarding understanding the protocols / code here? Or elsewhere, because this should only be related to software 'issues'?

Python3 Syntax Warnings in Compiler

When running ./compile.py for the first time, I get the following warnings:

/path/to/MP-SPDZ/Compiler/util.py:155: SyntaxWarning: "is" with a literal. Did you mean "=="?
  return int(x) is 0
/path/to/MP-SPDZ/Compiler/types.py:131: SyntaxWarning: "is" with a literal. Did you mean "=="?
  if other is 0:
/path/to/MP-SPDZ/Compiler/types.py:137: SyntaxWarning: "is" with a literal. Did you mean "=="?
  if other is 0:
/path/to/MP-SPDZ/Compiler/types.py:139: SyntaxWarning: "is" with a literal. Did you mean "=="?
  elif other is 1:
/path/to/MP-SPDZ/Compiler/types.py:1490: SyntaxWarning: "is" with a literal. Did you mean "=="?
  if other is 0:
/path/to/MP-SPDZ/Compiler/types.py:1591: SyntaxWarning: "is" with a literal. Did you mean "=="?
  if ai is 0 or bi is 0:
/path/to/MP-SPDZ/Compiler/types.py:1591: SyntaxWarning: "is" with a literal. Did you mean "=="?
  if ai is 0 or bi is 0:
/path/to/MP-SPDZ/Compiler/types.py:2593: SyntaxWarning: "is" with a literal. Did you mean "=="?
  if other is 0:
/path/to/MP-SPDZ/Compiler/types.py:2725: SyntaxWarning: "is" with a literal. Did you mean "=="?
  if other is 0:
/path/to/MP-SPDZ/Compiler/types.py:3343: SyntaxWarning: "is" with a literal. Did you mean "=="?
  if other is 0:
/path/to/MP-SPDZ/Compiler/types.py:3454: SyntaxWarning: "is" with a literal. Did you mean "=="?
  if other is 0:
/path/to/MP-SPDZ/Compiler/library.py:837: SyntaxWarning: "is" with a literal. Did you mean "=="?
  n_parallel = 1 if n_parallel is 0 else n_parallel
/path/to/MP-SPDZ/Compiler/GC/types.py:422: SyntaxWarning: "is" with a literal. Did you mean "=="?
  while res[-1] is 0:
/path/to/MP-SPDZ/Compiler/GC/types.py:625: SyntaxWarning: "is" with a literal. Did you mean "=="?
  if other is 0:

This might relevant: https://bugs.python.org/issue34850

For some reasons the warnings disappear after the first call to ./compile.py.

No idea if this is really a problem, but maybe that should be investigated.
I'm running Python 3.8.1.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.