Multi-Party Computation for Java (mpc4j
) is an efficient and easy-to-use Secure Multi-Party Computation (MPC), Homomorphic Encryption (HE), and Differential Privacy (DP) library mainly written in Java.
mpc4j
aims to provide an academic library for researchers to study and develop MPC/HE/DP in a unified manner. As mpc4j
tries to provide state-of-the-art MPC/HE/DP implementations, researchers could leverage the library to have fair and quick comparisons between the new algorithms/protocols they proposed and existing ones.
We note that mpc4j
is mainly focused on research and mpc4j
assumes a very strong system model. Specifically, mpc4j
assumes never-crash nodes with a fully synchronized network. In practice, crash-recovery nodes with a partially synchronized network would be a reasonable system model. Aside from the system model, mpc4j
tries to integrate tools that are suitable to be used in the production environment. We emphasize that additional engineering problems need to be solved if you want to develop your own MPC/DP applications. A reasonable solution would be to implement communication APIs on your own, develop protocols by calling tools in mpc4j
, and referring protocol implementations in mpc4j
as a prototype.
Since version 1.1.3, mpc4j
no longer uses Javallier to support partially homomorphic encryption, and JNA GMP project to support faster BigInteger
exponent operations. The reason is that we did test on MacBook M3 and found unknown bugs when invoking libgmp
on MacBook M3. Since we upgraded JDK to 17, and we can use GraalVM to obtain more efficient operations on JDK with the help of AoT, we can directly use pure JDK implementations for BigInteger
. Therefore, we remove these two modulus in mpc4j
.
Since version 1.1.3, mpc4j
leverages Vector API to speedup performance using Java SIMD. One needs to use JDK 17 (or later) to develop, compile and run mpc4j
. We note that this means you may also need to upgrade the underlying IDE (e.g., Intellij IDEA) to new versions. We further found that Foreign Function and Memory API (FFM) can help us to do conversions between different primitives more efficiently. This requires using JDK 21. However, we need to consider running mpc4j
on Android platforms for specific applications, but current Android platform only supports JDK 17. See Java versions in Android builds for details (access date: Oct. 11, 2024). Therefore, we have not introduced FFM into mpc4j
and force our JDK version as 17.
mpc4j
has the following features:
aarch64
support: mpc4j
can run on both x86_64
and aarch64
. Researchers can develop and test protocols on Macbook M1 (aarch64
) and then run experiments on Linux OS (x86_64
).mpc4j
leverages Bouncy Castle to support SM series algorithms.mpc4j
is mainly developed by Weiran Liu. Feel free to contact me at liuweiran900217@gmail.com.
mpc4j
If your project uses mpc4j
and you do not mind it appearing here, don't hesitate to get in touch with me.
mpc4j
.mpc4j
.mpc4j
for developing their prototypes.If you want to test and evaluate our protocol implementations, compile and run the corresponding jar file with the config file. Since version 1.1.2, if you want to run implementations related to PSU in the package mpc4j-s2pc-pso
, you can first find example config files located in conf/psu
in mpc4j-s2pc-pso
, and then run java -jar mpc4j-s2pc-pso-X.X.X-jar-with-dependencies.jar conf_file_name.txt server
and java -jar mpc4j-s2pc-pso-X.X.X-jar-with-dependencies.jar conf_file_name.txt client
separately on two platforms with direct network connections (using the network channel assigned in config files) or on two terminals in one platform (using local network 127.0.0.1). Note that you need first to run the server and then run the client. The server and the client implicitly synchronize before running the protocol, and the first step is the client to send something like "hello" to the server. If the server is offline at that time, the program will get stuck. Since version 1.1.2, we move all example configuration files in test/resources
for the corresponding modules.
mpc4j-work-femur
contains the implementations of our constructions, both under mpc4j
architecture (see femur-rpc
) and under the standard gRPC architecture (see femur-common
, femur-service-api
, and femur-service
).cppir/ks
in mpc4j-s2pc-pir
contains the implementations of our three constructions shown in the paper and the baseline construction ChamaletPIR. See Artifact Evaluation document in ae
for details.upsu
in mpc4j-s2pc-upso
contains the implementation of this paper.ucpsi
in mpc4j-s2pc-upso
contains the implementation of this paper.mqrpmt
in mpc4j-s2pc-opf
contains the implementation of communicative OPRF.heavyhitter
in mpc4j-dp-service
contains the implementation of this paper.pmid
in mpc4j-s2pc-pso
contains the implementation of this paper.psu
in mpc4j-s2pc-pso
contains the implementation of this paper.mpc4j-sml-opboost
contains the implementation of this paper.mpc4j
contains some implementations of existing works. See PAPERS.md
for more details.
mpc4j
includes some implementation ideas and codes from the following open-source libraries.
Here are some libraries that are included in mpc4j
.
mpc4j
for the dataset management and our privacy-preserving federated GBDT implementation. See packages edu.alibaba.mpc4j.common.data
in mpc4j-common-data
and package edu.alibaba.mpc4j.sml.smile
in mpc4j-sml-opboost
for details. Note that we introduce source codes that are released only under the GNU Lesser General Public License v3.0 (LGPLv3).mpc4j
to support efficient Elliptic Curve Cryptographic (ECC) operations. See package edu.alibaba.mpc4j.common.tool.crypto.ecc.bc
in mpc4j-common-tool
for details.mpc4j
. See package edu.alibaba.mpc4j.common.tool.polynomial
in mpc4j-common-tool
for details. We also provide JdkIntegersZp
to implement operations in $\mathbb{Z}_p$ purely using JDK. See JdkIntegersZp
in mpc4j-common-tool
for details.crypto/blake2
in mpc4j-native-tool
for details.crypto/blake3
in mpc4j-native-tool
for details.bit_matrix_trans
in mpc4j-native-tool
), AES-NI implementations (See crypto/aes.h
in mpc4j-native-tool
), efficient $GF(2^\kappa)$ operations (See gf2k
in mpc4j-native-tool
).mpc4j
for supporting post-quantum secure oblivious transfer. See crypto/kyber
in mpc4j-native-tool
for details.mpc4j
for our privacy-preserving federated XGBoost implementation. See packages ai.h2o.algos.tree
and biz.k11i.xgboost
in mpc4j-sml-opboost
for details.mpc4j
. See package crypto/ecc/cafe
for details.makefile
so that now FourQ can run on MacBook.c9497dfabff240787aa0f5ac7a8f4ad70117ea72
includes pure-Java implementation of PGM-Index. We import its source code and make several changes. Access date: Jul. 28, 2024.Here are some libraries that inspire our implementations.
mpc4j
. See edu.alibaba.mpc4j.common.tool.crypto.prp.JdkBytesLowMcPrp
and edu.alibaba.mpc4j.common.tool.crypto.prp.JdkLongsLowMcPrp
in mpc4j-common-tool
for details. We also introduce its Cuckoo Filter optimizations in mpc4j
.cot
in mpc4j-s2pc-pcg
).mpc4j
, see ecc_openssl
in mpc4j-native-tool
for details.mpc4j
. See package benes_network
in mpc4j-native-tool
for details.mpc4j-dp-cdp
for details.mpc4j
. See package edu.alibaba.mpc4j.dp.cdp.nomial
for details.cot
in mpc4j-s2pc-pcg
).mpc4j
. See package ntl_poly
in mpc4j-native-tool
for details. The PSU implementation is in package psu
of mpc4j-s2pc-pso
.mpc4j
. See package psu
in mpc4j-s2pc-pso
for details.mpc4j
. See package polynomial
in mpc4j-common-tool
for details.mpc4j
. See oprf
in mpc4j-s2pc-pso
for details.mpc4j-native-fhe
and upsi
in mpc-s2pc-pso
for details.crypto/ecc/bc/X25519BcByteMulElligatorEcc
in mpc4j-common-tool
for details.crypto/ecc/bc/X25519BcByteMulElligatorEcc
in mpc4j-common-tool
for details.common/sampler/integral/gaussian
in mpc4j-common-sampler
for details.aarch64
.mpc4j
.okve/okvs
in mpc4j-common-tool
for more details.galoisfield/gf2k
in mpc4j-common-tool
for more details.oprf
in mpc4j-s2pc-pso
for more details.mpc4j
documentation and for mpc4j-native-tool
. These suggestions help us fix many memory leakage problems. Also, the comments help us remove many duplicate codes.This library is licensed under Apache License 2.0.
Most of the codes are in Java, except for very efficient implementations in C/C++. You need OpenSSL, GMP, NTL, libsodium, and FourQ that we rewrite (in mpc4j-native-fourq
) to compile mpc4j-native-tool
and SEAL (version higher than 4.0.0) to compile mpc4j-native-fhe
. Please see README.md in mpc4j-native-fourq
, mpc4j-native-cool
and mpc4j-native-fhe
on how to install C/C++ dependencies.
After successfully installing C/C++ library mpc4j-native-fourq
and obtaining the compiled C/C++ libraries (named libmpc4j-native-tool
and libmpc4j-native-fhe
, respectively), you need to assign the native library location when running mpc4j
using -Djava.library.path
.
mpc4j
has been tested on MAC (x86_64
/ aarch64
), Ubuntu 20.04 (x86_64
/ aarch64
), and CentOS 8 (x86_64
). We welcome developers to do tests on other platforms.
We note that you may need to run test cases in mpc4j-s2pc-pir
separately, especially for test cases in IndexPirTest
and KwPirTest
. The reason is that PIR and related implementations heavily consume the main memory, and direct running all test cases may (automatically) involve frequent fullGC, introducing problems.
We have received a lot of suggestions and some performance reports from users. We thank Dr. Yongha Son for providing performance reports for Private Set Union (PSU) on his development platform (Intel Xeon 3.5GHz) under the Unit Test. The report results are formally shown in their paper "Revisiting Shuffle-based Private Set Unions with Reduced Communication". He reported that:
Well, I tested other protocols, particularly JSZ22 SFC, GMR21, and KRTW19, from unit tests.
JSZ22 takes 4x faster time.
KRTW19 and GMR21 take 1.5x slower.
ZCL22 takes 2.5-3x slower time.
than the reported numbers in ZCL22.
We have a deep discussion about the performance gap. Here are the following reasons:
EccEfficiencyTest
on his platform. The result shows ECC operations on his platform with asm
are much slower (about 5x) than on our Macbook M1 platform without asm
.We have to say that we underestimated the performance gap between different platforms. The performance comparison result also reflects that having fair comparisons for different protocols is very challenging. Aside from that, we still try to provide a unified library for trying to have a relatively fair comparison.
aarch64
When using or developing mpc4j
on aarch64
systems (like MacBook M1), you may get java.lang.UnsatisfiedLinkError
with a description like "no mpc4j-native-tool / mpc4j-native-fhe in java.library.path", even if you correctly compile the native libraries and config the native library paths using -Djava.library.path
. The reason is that some Java Virtual Machines (JVM) with versions less than 17 do not fully support aarch64
. JDK 17 Release Notes stated that (In JEP 391: macOS / Aarch64 Port):
macOS 11.0 now supports the AArch64 architecture. This JEP implements support for the macos-aarch64 platform in the JDK. One of the features added is support for the W^X (write xor execute) memory. It is enabled only for macos-aarch64 and can be extended to other platforms at some point. The JDK can be either cross-compiled on an Intel machine or compiled on an Apple M1-based machine.
We recommend using Java 17 (or higher versions) to run or develop mpc4j
on aarch64
systems. If you still want to use Java with versions less than 17, we test many JVMs and found that Azul Zulu fully supports aarch64
.
When you run make test
for mpc4j-native-fourq
, you possibly meet test failures. The reason is that the original FourQlib have some unknown bugs when running on some platforms (but currently we do not know which platforms you may meet the bug). See Issue #9 in FourQlib and Issue #16 in mpc4j
.
Simply ignoring the error is OK, but many test cases in mpc4j
would fail since mpc4j
uses FourQ EC curve by default. You need to change the default EC curve from FourQ to ED25519 (also see Issue #16 in mpc4j
for more details):
mpc4j-common-tool
, find ByteEccFactory
in package edu.alibaba.mpc4j.common.tool.crypto.ecc
.public static ByteFullEcc createFullInstance(EnvType envType)
.return createFullInstance(ByteEccType.FOUR_Q);
to return createFullInstance(ByteEccType.ED25519_SODIUM);
.mpc4j-dp-service
RAPPOR implementation requires LASSO and Ridge regressions in the server side, for which we uses LASSO and Ridge regressions in smile. We note that smile requires additional configurations to run LASSO and Ridge regressions.
Some algorithms rely on BLAS and LAPACK (e.g. manifold learning, some clustering algorithms, Gaussian Process regression, MLP, etc.). To use these algorithms, you should include OpenBLAS for optimized matrix computation:
libraryDependencies ++= Seq( "org.bytedeco" % "javacpp" % "1.5.8" classifier "macosx-x86_64" classifier "windows-x86_64" classifier "linux-x86_64" classifier "linux-arm64" classifier "linux-ppc64le" classifier "android-arm64" classifier "ios-arm64", "org.bytedeco" % "openblas" % "0.3.21-1.5.8" classifier "macosx-x86_64" classifier "windows-x86_64" classifier "linux-x86_64" classifier "linux-arm64" classifier "linux-ppc64le" classifier "android-arm64" classifier "ios-arm64", "org.bytedeco" % "arpack-ng" % "3.8.0-1.5.8" classifier "macosx-x86_64" classifier "windows-x86_64" classifier "linux-x86_64" classifier "linux-arm64" classifier "linux-ppc64le" )
To sucessfully run RAPPOR, one also needs to add dependencies in pom.xml
of mpc4j-dp-service
.
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>openblas</artifactId>
<version>0.3.21-1.5.8</version>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacpp-platform</artifactId>
<version>1.5.8</version>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>openblas-platform</artifactId>
<version>0.3.21-1.5.8</version>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>arpack-ng-platform</artifactId>
<version>3.8.0-1.5.8</version>
</dependency>
mpc4j
requires PSO to take Set
as inputs. For PSO experiements, mpc4j
uses Set<ByteBuffer>
. However, when running PSO on very large sets, it is possible that Set<ByteBuffer>
does not successfully contain the assigned number of elements, leading to unexpected Exceptions when running experiments. This happens with probability with the size of sets $n$ increases, especially when $n > 2^{20}$.
If you meet problems when running experiments for $n > 2^{20}$, you can simply try deleting files in the path temp
and rerun experiments. We are trying to fix this bug in the next version.
We develop mpc4j
using Intellij IDEA and CLion. Here are some guidelines.
Please change the following Preferences before actual development:
PtoId
in PtoDesc
instances are generated using serialVersionUID. When creating a new instance of PtoDesc
, make it implement Serializable
, follow the warning to generate a serialVersionUID
, paste that ID to be PtoId
, and delete implement Serializable
and corresponding imports.After successfully installing mpc4j-native-fourq
, compiling mpc4j-native-tool
and mpc4j-native-fhe
, you need to configure IDEA with the following procedures so that IDEA can link to these native libraries.
Run->Edit Configurations...
Edit Configuration templates...
JUnit
.VM Options
. Note that do not remove -ea
, which means enabling assert
in unit tests. If so, some test cases (related to input verifications) would fail.-Djava.library.path=/YOUR_MPC4J_ABSOLUTE_PATH/mpc4j-native-tool/cmake-build-release:/YOUR_MPC4J_ABSOLUTE_PATH/mpc4j-native-fhe/cmake-build-release
We thank Qixian Zhou for writing a guideline demonstrating configuring the development environment on macOS (x86_64). We believe this guideline can also be used for other platforms, e.g., macOS (M1), Ubuntu, and CentOS. Here are the steps:
Follow any guidelines to install JDK 17 and IntelliJ IDEA. If you successfully install JDK17, you can obtain similar information in the terminal when executing java -version
.
Clone mpc4j
source code using git clone https://github.com/alibaba-edu/mpc4j.git
.
Follow the documentation in https://github.com/alibaba-edu/mpc4j/tree/main/mpc4j-native-tool to compile mpc4j-native-tool
. If all steps are correct, you will see:
[100%] Linking CXX shared library libmpc4j-native-tool.dylib
[100%] Built target mc4j-native-tool
mpc4j-native-tool
. If all steps are correct, you will see:[100%] Linking CXX shared library libmpc4j-native-fhe.dylib
[100%] Built target mc4j-native-fhe
mpc4j
.Run->Edit Configurations...
.Edit Configuration templates...
.JUnit
, and add the following command into VM Options
(Note that you must replace /YOUR_MPC4J_ABSOLUTE_PATH
with your own absolute path for libmpc4j-native-tool.dylib
and libmpc4j-native-fhe.dylib
.):-Djava.library.path=/YOUR_MPC4J_ABSOLUTE_PATH/mpc4j-native-tool/cmake-build-release:/YOUR_MPC4J_ABSOLUTE_PATH/mpc4j-native-fhe/cmake-build-release