a portable and fast pairing-based cryptography library
C++
531
4,189 commits
updated Oct 9, 2026
A portable and fast pairing-based cryptography library.
mcl is a library for pairing-based cryptography, which supports the optimal Ate pairing over BN curves and BLS12-381 curves.
mcl.{a,lib} supports up to 384 bits for the field Fp over which the elliptic curve is defined,
and up to 256 bits for the order field Fr of the elliptic curve (MCL_FP_BIT=384, MCL_FR_BIT=256).
MCL_FP_BIT and MCL_FR_BIT must be at most 384 (MCL_BINT_MAX_BIT in include/mcl/config.hpp; the generated low-level functions support up to 384-bit multiplication),
so the initialization of a curve over a larger prime such as BN462 fails.
To enlarge the limit (up to 576 for the x64 assembly), set MCL_BINT_MAX_BIT in include/mcl/config.hpp and BINT_MUL_N (= MCL_BINT_MAX_BIT / 64) in Makefile to the same size,
and regenerate the low-level functions by make update_all_asm (requires LLVM) and make header.mclbn***.{a,lib} has been merged into mcl.{a,lib} and removed.make UPDATE_ASM=1 once.See bls if you want mcl for BLS-signature.
See api.md and FAQ for serialization and hash-to-curve.
x86-64/ARM/ARM64 Linux, macOS and mingw64 are supported.
GMP is necessary only to build test programs.
sudo apt install libgmp-dev on Ubuntubrew install gmp on macOSOpenMP is optional (make MCL_USE_OMP=1 to use OpenMP for mulVec)
sudo apt install libomp-dev on Ubuntubrew install libompFor 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 (MinGW).
make -j4 CXX=clang++
lib/libmcl.a: static librarylib/libmcl.so: shared libraryFor x86-64 Linux and macOS.
mkdir build
cd build
cmake ..
make
For other platforms (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
Open mcl.sln and build it.
src/proj/mcllib/mcllib.vcxproj is to build a static library lib/mcl.lib, which is built with MCL_FP_BIT=384.
see cmake .. -LA.
Build test binaries in ./bin.
cmake .. -DMCL_BUILD_TESTING=ON
make -j4
clang (clang-cl on Windows) is necessary to build files with the suffix .ll.
src/base${BIT}.ll is necessary if MCL_USE_LLVM is defined.
src/bint${BIT}.ll is necessary if MCL_BINT_ASM=1.
src/asm/bint-x64-amd64.S (src/asm/bint-x64-mingw.S on MinGW, src/asm/bint-x64-win.asm on Windows) is used instead if MCL_BINT_ASM_X64=1.src/bint64.ll because it uses mulx/adox/adcx.These files may be unified in the future.
# C
make bin/bn_c384_256_test.exe && bin/bn_c384_256_test.exe
# C++
make bin/bls12_test.exe && bin/bls12_test.exe
On x64 environments, mcl uses JIT code, but if you want to avoid it,
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_FP_BIT=384 -DMCL_STATIC_CODE.
make MCL_USE_PROF=1 bin/bls12_test.exe
env MCL_PROF=1 bin/bls12_test.exe
Suppose 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
Build GMP for 32-bit mode.
sudo apt install g++-multilib
sudo apt install clang-21
cd <GMP dir>
env ABI=32 ./configure --enable-cxx --prefix=<install dir>
make -j install
cd <mcl dir>
make ARCH=x86 LLVM_VER=-21 GMP_DIR=<install dir>
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/libmcl.a -DMCL_FP_BIT=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.
Install clang++ and
sudo apt install g++-14-riscv64-linux-gnu binutils-riscv64-unknown-elf
make -f Makefile.cross test TARGET=riscv64-linux-gnu LD_PREFIX=riscv64-linux-gnu
mklib.bat builds the library and mk.bat builds a test or sample with it.
mklib [dll] [clang=(0|1|2)]
mk (-s|-d) <source file>
dll: build bin\mcl.dll (and bin\mcl.lib for import) instead of the static library lib\mcl.lib.clang=1 (default): build src\base64.ll with clang++ (MCL_USE_LLVM=1). clang++ (installed by the LLVM component of Visual Studio) is required.clang=0: build without clang++ (src\base64.ll is not used).clang=2: also build src\fp.cpp and src\msm_avx.cpp with clang-cl instead of cl, with the same optimization options as Makefile on x64 (CLANG_CFLAGS in setvar.bat). Some functions such as Fr::mulUnit become faster.
mklib leaves USE_CLANG=2 in the environment, and then mk also uses clang-cl.
A program that links the library built with clang=2 requires clang_rt.builtins-x86_64.lib (CLANG_RT_LIB in setvar.bat, found via clang -print-resource-dir); mk adds it if USE_CLANG=2.mk -s links lib\mcl.lib and mk -d links bin\mcl.lib with /DMCL_DLL. The executable is put in bin\.Open a console window, and
git clone https://github.com/herumi/mcl
cd mcl
# static library (support both C/C++ API)
mklib
mk -s test\bls12_test.cpp && bin\bls12_test.exe
# dynamic library (support both C/C++ API)
mklib dll
mk -d test\bn_c384_256_test.cpp && bin\bn_c384_256_test.exe
mk -d test\bls12_test.cpp && bin\bls12_test.exe
A C++ client of mcl.dll must be compiled with /DMCL_DLL (mk -d does it); the static data of Fp, Fr, G1, and G2 then refers to the instances in the DLL.
(not maintained)
Open mcl.sln and build or if you have msbuild.exe
msbuild /p:Configuration=Release
Install Clang for Visual Studio.
Open command prompt and run
cd mcl
setvar_arm64.bat
"%VS_PATH%"\vc\auxiliary\build\vcvarsamd64_arm64.bat
# static library
mklib_arm64
mk_arm64 -s test\bls12_test.cpp
# dynamic library
mklib_arm64 dll
mk_arm64 -d test\bn_c384_256_test.cpp
lib/mcl.lib: static librarybin/{mcl.lib,mcl.dll}: dynamic librarycd mcl
cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=cmake/arm64-windows-toolchain.cmake
cmake --build build --config Release
build/lib/mcl.lib: static librarybuild/bin/{mcl.lib,mcl.dll}: dynamic librarycd mcl
cmake -S . -B build -A arm64
cmake --build build --config Release
cd mcl
mklib dll
cd ffi/cs
dotnet build mcl.sln
cd ../../bin
../ffi/cs/test/bin/Debug/net8.0/test.exe
mcl supports emcc (Emscripten) and test/bn_test.cpp runs on browsers such as Firefox, Chrome and Edge.
The timing of a pairing on BN254 is 2.8msec on 64-bit Firefox with Skylake 3.4GHz.
Build mcl.wasm without Emscripten using clang's wasm target directly.
make -f Makefile.wasm LLVM_VER=-21
This generates lib/mcl.wasm and lib/mcl_c.js (wasm binary embedded as base64 in JS).
Set LLVM_VER to match your installed LLVM version suffix (e.g., -21 for clang-21).
See java.md
modified new BSD License http://opensource.org/licenses/BSD-3-Clause
This library contains parts of the following software, licensed under the BSD-3-Clause license.
mclBn_init is changed from maxUnitSize to compiledTimeVar, which must be MCLBN_COMPILED_TIME_VAR.MCL_USE_OLD_MAPTO_FOR_BLS12, has been removed.)The behavior of the 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));
}
MITSUNARI Shigeo(herumi@nifty.com)
796 followers · starred Sep 2021
1,052 followers · starred May 2026
400 followers · starred Sep 2018
211 followers · starred Dec 2025
a portable and fast pairing-based cryptography library
C++
531
4,189 commits
updated Oct 9, 2026
A portable and fast pairing-based cryptography library.
mcl is a library for pairing-based cryptography, which supports the optimal Ate pairing over BN curves and BLS12-381 curves.
mcl.{a,lib} supports up to 384 bits for the field Fp over which the elliptic curve is defined,
and up to 256 bits for the order field Fr of the elliptic curve (MCL_FP_BIT=384, MCL_FR_BIT=256).
MCL_FP_BIT and MCL_FR_BIT must be at most 384 (MCL_BINT_MAX_BIT in include/mcl/config.hpp; the generated low-level functions support up to 384-bit multiplication),
so the initialization of a curve over a larger prime such as BN462 fails.
To enlarge the limit (up to 576 for the x64 assembly), set MCL_BINT_MAX_BIT in include/mcl/config.hpp and BINT_MUL_N (= MCL_BINT_MAX_BIT / 64) in Makefile to the same size,
and regenerate the low-level functions by make update_all_asm (requires LLVM) and make header.mclbn***.{a,lib} has been merged into mcl.{a,lib} and removed.make UPDATE_ASM=1 once.See bls if you want mcl for BLS-signature.
See api.md and FAQ for serialization and hash-to-curve.
x86-64/ARM/ARM64 Linux, macOS and mingw64 are supported.
GMP is necessary only to build test programs.
sudo apt install libgmp-dev on Ubuntubrew install gmp on macOSOpenMP is optional (make MCL_USE_OMP=1 to use OpenMP for mulVec)
sudo apt install libomp-dev on Ubuntubrew install libompFor 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 (MinGW).
make -j4 CXX=clang++
lib/libmcl.a: static librarylib/libmcl.so: shared libraryFor x86-64 Linux and macOS.
mkdir build
cd build
cmake ..
make
For other platforms (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
Open mcl.sln and build it.
src/proj/mcllib/mcllib.vcxproj is to build a static library lib/mcl.lib, which is built with MCL_FP_BIT=384.
see cmake .. -LA.
Build test binaries in ./bin.
cmake .. -DMCL_BUILD_TESTING=ON
make -j4
clang (clang-cl on Windows) is necessary to build files with the suffix .ll.
src/base${BIT}.ll is necessary if MCL_USE_LLVM is defined.
src/bint${BIT}.ll is necessary if MCL_BINT_ASM=1.
src/asm/bint-x64-amd64.S (src/asm/bint-x64-mingw.S on MinGW, src/asm/bint-x64-win.asm on Windows) is used instead if MCL_BINT_ASM_X64=1.src/bint64.ll because it uses mulx/adox/adcx.These files may be unified in the future.
# C
make bin/bn_c384_256_test.exe && bin/bn_c384_256_test.exe
# C++
make bin/bls12_test.exe && bin/bls12_test.exe
On x64 environments, mcl uses JIT code, but if you want to avoid it,
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_FP_BIT=384 -DMCL_STATIC_CODE.
make MCL_USE_PROF=1 bin/bls12_test.exe
env MCL_PROF=1 bin/bls12_test.exe
Suppose 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
Build GMP for 32-bit mode.
sudo apt install g++-multilib
sudo apt install clang-21
cd <GMP dir>
env ABI=32 ./configure --enable-cxx --prefix=<install dir>
make -j install
cd <mcl dir>
make ARCH=x86 LLVM_VER=-21 GMP_DIR=<install dir>
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/libmcl.a -DMCL_FP_BIT=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.
Install clang++ and
sudo apt install g++-14-riscv64-linux-gnu binutils-riscv64-unknown-elf
make -f Makefile.cross test TARGET=riscv64-linux-gnu LD_PREFIX=riscv64-linux-gnu
mklib.bat builds the library and mk.bat builds a test or sample with it.
mklib [dll] [clang=(0|1|2)]
mk (-s|-d) <source file>
dll: build bin\mcl.dll (and bin\mcl.lib for import) instead of the static library lib\mcl.lib.clang=1 (default): build src\base64.ll with clang++ (MCL_USE_LLVM=1). clang++ (installed by the LLVM component of Visual Studio) is required.clang=0: build without clang++ (src\base64.ll is not used).clang=2: also build src\fp.cpp and src\msm_avx.cpp with clang-cl instead of cl, with the same optimization options as Makefile on x64 (CLANG_CFLAGS in setvar.bat). Some functions such as Fr::mulUnit become faster.
mklib leaves USE_CLANG=2 in the environment, and then mk also uses clang-cl.
A program that links the library built with clang=2 requires clang_rt.builtins-x86_64.lib (CLANG_RT_LIB in setvar.bat, found via clang -print-resource-dir); mk adds it if USE_CLANG=2.mk -s links lib\mcl.lib and mk -d links bin\mcl.lib with /DMCL_DLL. The executable is put in bin\.Open a console window, and
git clone https://github.com/herumi/mcl
cd mcl
# static library (support both C/C++ API)
mklib
mk -s test\bls12_test.cpp && bin\bls12_test.exe
# dynamic library (support both C/C++ API)
mklib dll
mk -d test\bn_c384_256_test.cpp && bin\bn_c384_256_test.exe
mk -d test\bls12_test.cpp && bin\bls12_test.exe
A C++ client of mcl.dll must be compiled with /DMCL_DLL (mk -d does it); the static data of Fp, Fr, G1, and G2 then refers to the instances in the DLL.
(not maintained)
Open mcl.sln and build or if you have msbuild.exe
msbuild /p:Configuration=Release
Install Clang for Visual Studio.
Open command prompt and run
cd mcl
setvar_arm64.bat
"%VS_PATH%"\vc\auxiliary\build\vcvarsamd64_arm64.bat
# static library
mklib_arm64
mk_arm64 -s test\bls12_test.cpp
# dynamic library
mklib_arm64 dll
mk_arm64 -d test\bn_c384_256_test.cpp
lib/mcl.lib: static librarybin/{mcl.lib,mcl.dll}: dynamic librarycd mcl
cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=cmake/arm64-windows-toolchain.cmake
cmake --build build --config Release
build/lib/mcl.lib: static librarybuild/bin/{mcl.lib,mcl.dll}: dynamic librarycd mcl
cmake -S . -B build -A arm64
cmake --build build --config Release
cd mcl
mklib dll
cd ffi/cs
dotnet build mcl.sln
cd ../../bin
../ffi/cs/test/bin/Debug/net8.0/test.exe
mcl supports emcc (Emscripten) and test/bn_test.cpp runs on browsers such as Firefox, Chrome and Edge.
The timing of a pairing on BN254 is 2.8msec on 64-bit Firefox with Skylake 3.4GHz.
Build mcl.wasm without Emscripten using clang's wasm target directly.
make -f Makefile.wasm LLVM_VER=-21
This generates lib/mcl.wasm and lib/mcl_c.js (wasm binary embedded as base64 in JS).
Set LLVM_VER to match your installed LLVM version suffix (e.g., -21 for clang-21).
See java.md
modified new BSD License http://opensource.org/licenses/BSD-3-Clause
This library contains parts of the following software, licensed under the BSD-3-Clause license.
mclBn_init is changed from maxUnitSize to compiledTimeVar, which must be MCLBN_COMPILED_TIME_VAR.MCL_USE_OLD_MAPTO_FOR_BLS12, has been removed.)The behavior of the 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));
}
MITSUNARI Shigeo(herumi@nifty.com)
796 followers · starred Sep 2021
1,052 followers · starred May 2026
400 followers · starred Sep 2018
211 followers · starred Dec 2025