Home

Awesome

Build Status

mcl

A portable and fast pairing-based cryptography library.

Abstract

mcl is a library for pairing-based cryptography, which supports the optimal Ate pairing over BN curves and BLS12-381 curves.

News

Support architecture

Support curves

BLS signature

See bls if you want mcl for BLS-signature.

C-API

See api.md and FAQ for serialization and hash-to-curve.

How to build on Linux and macOS

x86-64/ARM/ARM64 Linux, macOS and mingw64 are supported.

GMP is necessary only to build test programs.

OpenMP is optional (make MCL_USE_OMP=1 to use OpenMP for mulVec)

How to build with Makefile

For x86-64 Linux and macOS,

git clone https://github.com/herumi/mcl
cd mcl
make -j4

clang++ is required except for x86-64 on Linux and Windows.

make -j4 CXX=clang++

How to build with CMake

For x86-64 Linux and macOS.

mkdir build
cd build
cmake ..
make

For the other platform (including mingw), clang++ is required.

mkdir build
cd build
cmake .. -DCMAKE_CXX_COMPILER=clang++
make

Use clang++ instead of gcc on mingw.

For Visual Studio, (REMARK : It is not maintained; use the vcxproj file.)

mkdir build
cd build
cmake .. -A x64
msbuild mcl.sln /p:Configuration=Release /m

How to build a static library with Visual Studio

Open mcl.sln and build it. src/proj/lib/lib.vcxproj is to build a static library lib/mcl.lib which is defined MCL_MAX_BIT_SIZE=384.

options

see cmake .. -LA.

tests

make test binaries in ./bin.

cmake .. -DBUILD_TESTING=ON
make -j4

How to make from src/{base,bint}{32,64}.ll

clang (clang-cl on Windows) is necessary to build files with a suffix ll.

These files may be going to be unified in the future.

How to test of BLS12-381 pairing

# C
make bin/bn_c384_256_test.exe && bin/bn_c384_256_test.exe

# C++
make bin/bls12_test.exe && bin/bls12_test.exe

How to make a library for BLS12-381 without Xbyak

On x64 environment, mcl uses JIT code, but if you want to avoid them,

make lib/libmcl.a MCL_STATIC_CODE=1 -j
# test of pairing
make test_static

The generated library supports only BLS12_381 and requires compiler options -DMCL_MAX_BIT_SIZE=384 -DMCL_STATIC_CODE.

How to profile on Linux

Use perf

make MCL_USE_PROF=1 bin/bls12_test.exe
env MCL_PROF=1 bin/bls12_test.exe

Use Intel VTune profiler

Supporse VTune is installed in /opt/intel/vtune_amplifier/.

make MCL_USE_PROF=2 bin/bls12_test.exe
env MCL_PROF=2 bin/bls12_test.exe

How to build on 32-bit x86 Linux

Build GMP for 32-bit mode.

sudo apt install g++-multilib
sudo apt install clang-14
cd <GMP dir>
env ABI=32 ./configure --enable-cxx --prefix=<install dir>
make -j install
cd <mcl dir>
make ARCH=x86 LLVM_VER=-14 GMP_DIR=<install dir>

How to build a library for arm with clang++ on Linux

make -f Makefile.cross BIT=32 TARGET=armv7l
sudo apt install g++-arm-linux-gnueabi
arm-linux-gnueabi-g++ sample/pairing.cpp -O3 -DNDEBUG -I ./include/ lib/libmclbn384_256.a -DMCL_MAX_BIT_SIZE=384
env QEMU_LD_PREFIX=/usr/arm-linux-gnueabi/ qemu-arm ./a.out

The static library libbls384_256.a built by bls/Makefile.onelib in bls contains all mcl functions. So please see the comment of Makefile.onelib if you want to build this library on the other platform such as Mingw64 on Linux.

How to build on 64-bit Windows with Visual Studio

Python3 is necessary. Open a console window, and

git clone https://github.com/herumi/mcl
cd mcl

# static library
mklib
mk -s test\bls12_test.cpp && bin\bls12_test.exe

# dynamic library
mklib dll
mk -d test\bls12_test.cpp && bin\bls12_test.exe

(not maintenanced) Open mcl.sln and build or if you have msbuild.exe

msbuild /p:Configuration=Release

C# test

cd mcl
mklib dll
cd ffi/cs
dotnet build mcl.sln
cd ../../bin
../ffi/cs/test/bin/Debug/netcoreapp3.1/test.exe

How to build for wasm(WebAssembly)

mcl supports emcc (Emscripten) and test/bn_test.cpp runs on browers such as Firefox, Chrome and Edge.

The timing of a pairing on BN254 is 2.8msec on 64-bit Firefox with Skylake 3.4GHz.

Node.js

Benchmark

The latest benchmark(2018/11/7)

Intel Core i7-6700 3.4GHz(Skylake), Ubuntu 18.04.1 LTS

curveTypebinaryclang-6.0.0gcc-7.3.0
BN254bin/bn_test.exe882Kclk933Kclk
BLS12-381bin/bls12_test.exe2290Kclk2630Kclk

Intel Core i7-7700 3.6GHz(Kaby Lake), Ubuntu 18.04.1 LTS on Windows 10 Vmware

curveTypebinaryclang-6.0.0gcc-7.3.0
BN254bin/bn_test.exe900Kclk954Kclk
BLS12-381bin/bls12_test.exe2340Kclk2680Kclk

Higher-bit BN curve benchmark

For JavaScript(WebAssembly), see ID based encryption demo.

paramterx64Firefox on x64Safari on iPhone7
BN2540.252.484.78
BN381_10.957.9111.74
BN4622.1614.7322.77

The other benchmark results are bench.txt.

An old benchmark of a BN curve BN254(2016/12/25).

softwarex64x86armarm64(msec)
ate-pairing0.21---
mcl0.311.622.63.9
TEPLA1.763.73717.9
RELIC PRIME=2540.303.536-
MIRACL ake12bnx4.2-78-
NEONabe--16-
cmake -DARITH=x64-asm-254 -DFP_PRIME=254 -DFPX_METHD="INTEG;INTEG;LAZYR" -DPP_METHD="LAZYR;OATEP"

SELinux

mcl uses Xbyak JIT engine if it is available on x64 architecture, otherwise mcl uses a little slower functions generated by LLVM. The default mode enables SELinux security policy on CentOS, then JIT is disabled.

% sudo setenforce 1
% getenforce
Enforcing
% bin/bn_test.exe
JIT 0
pairing   1.496Mclk
finalExp 581.081Kclk

% sudo setenforce 0
% getenforce
Permissive
% bin/bn_test.exe
JIT 1
pairing   1.394Mclk
finalExp 546.259Kclk

How to make asm files (optional)

The asm files generated by this way are already put in src/asm, then it is not necessary to do this.

Install LLVM.

make MCL_USE_LLVM=1 LLVM_VER=<llvm-version> UPDATE_ASM=1

For example, specify -3.8 for <llvm-version> if opt-3.8 and llc-3.8 are installed.

If you want to use Fp with 1024-bit prime on x86-64, then

make MCL_USE_LLVM=1 LLVM_VER=<llvm-version> UPDATE_ASM=1 MCL_MAX_BIT_SIZE=1024

API for Two level homomorphic encryption

Java API

See java.md

License

modified new BSD License http://opensource.org/licenses/BSD-3-Clause

This library contains some part of the followings software licensed by BSD-3-Clause.

References

compatilibity

FAQ

How do I set the hash value to Fr?

The behavior of setHashOf function may be a little different from what you want.

Please use the following code:

template<class F>
void setHash(F& x, const void *msg, size_t msgSize)
{
    uint8_t md[32];
    mcl::fp::sha256(md, sizeof(md), msg, msgSize);
    x.setBigEndianMod(md, sizeof(md));
    // or x.setLittleEndianMod(md, sizeof(md));
}

History

Author

MITSUNARI Shigeo(herumi@nifty.com)

Sponsors welcome

GitHub Sponsor