Git Product home page Git Product logo

mcl's Introduction

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

  • mulEach with AVX-512 IFMA is improved slightly and 2.8 times faster than G1::mul on BLS12-381.
  • mulVec (multi scalar multiplication) with AVX-512 IFMA is 1.4 times faster on Xeon w9-3495X
  • a little performance improvement of G1::mulVec of BLS12-381
  • improve performance of Fr::inv on M1 mac
  • add mcl::bn::isValidGT(x) and mclBnGT_isValid(x) to check x in GT for x in Fp12.
  • support BN_P256 (hash-to-curve is not yet standard way.)
  • the performance of {G1,G2}::mulVec(z, xVec, yVec, n) has improved for n >= 256. (about 2x speed up for n = 512).
    • But it changes the type of xVec from const G* to G* because xVec may be normalized when computing.
    • fix mul(G, G, F) for F = Fp at v1.61
  • add set DST functions for hashMapToGi
  • add F::invVec, G::normalizeVec
  • improve SECP256K1 for x64
  • add G1::mulVecMT, G2::mulVecMT (enabled by MCL_USE_OMP=1)
  • improve mulMod of SECP256K1 for wasm
  • fix FpToG1(P, u, v) and Fp2ToG2(P, u, v) when u == v (This bug does not affect mapToG1 and mapToG2).
  • add millerLoopVecMT (enabled if built with MCL_USE_OMP=1)
  • support s390x(systemz)
  • improve M1 mac performance
  • set default MCL_MAX_BIT_SIZE=512 so disable to support NICT_P521.
  • improve performance
  • support M1 mac
  • dst for mapToG1 has changed to BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_POP_.
  • mclBn_eth* functions are removed.
  • mcl::bn::mapToG1(G1& out, const Fp& v) supports BLS12_MAP_FP_TO_G1 in EIP 2537.
  • mcl::bn::hashAndMapToG1(G1& out, const void *msg, size_t msgSize) supports (hash-to-curve-09 BLS12381G1_XMD:SHA-256_SSWU_RO_)
  • MCL_MAP_TO_MODE_HASH_TO_CURVE_07 is added for hash-to-curve-draft-07.

Support architecture

  • x86-64 Windows + Visual Studio 2015 (or later)
  • x86, x86-64 Linux + gcc/clang
  • x86-64, M1 macOS
  • ARM / ARM64 Linux
  • WebAssembly : see mcl-wasm
  • Android : see mcl-android
  • iPhone
  • s390x(systemz)
    • install llvm and clang, and make UPDATE_ASM=1 once.
  • (maybe any platform to be supported by LLVM)

Support curves

  • BN curve ; p(z) = 36z^4 + 36z^3 + 24z^2 + 6z + 1.
    • BN254 ; a BN curve over the 254-bit prime p(z) where z = -(2^62 + 2^55 + 1).
    • BN_SNARK1 ; a BN curve over a 254-bit prime p such that n := p + 1 - t has high 2-adicity.
    • BN381_1 ; a BN curve over the 381-bit prime p(z) where z = -(2^94 + 2^76 + 2^72 + 1).
    • BN462 ; a BN curve over the 462-bit prime p(z) where z = 2^114 + 2^101 - 2^14 - 1.
  • BLS12_381 ; a BLS12-381 curve

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.

  • sudo apt install libgmp-dev on Ubuntu
  • brew install gmp on macOS

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

  • sudo apt install libomp-dev on Ubuntu
  • brew install libomp

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++
  • lib/libmcl.* ; core library
  • lib/libmclbn384_256.* ; library to use C-API of BLS12-381 pairing

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.

  • BIT = 64 (if 64-bit CPU) else 32
  • src/base${BIT}.ll is necessary if MCL_USE_LLVM is defined.
    • This code is used if xbyak is not used.
  • src/bint${BIT}.ll is necessary if MCL_BINT_ASM=1.
    • src/bint-x64-{amd64,win}.asm is used instead if MCL_BINT_ASM_X64=1.
    • It is faster than src/bint64.ll because it uses mulx/adox/adcx.

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 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 on 64-bit Windows with Visual Studio

Python3 is necessary. Open a console window, and

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

# 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


# 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

curveType binary clang-6.0.0 gcc-7.3.0
BN254 bin/bn_test.exe 882Kclk 933Kclk
BLS12-381 bin/bls12_test.exe 2290Kclk 2630Kclk

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

curveType binary clang-6.0.0 gcc-7.3.0
BN254 bin/bn_test.exe 900Kclk 954Kclk
BLS12-381 bin/bls12_test.exe 2340Kclk 2680Kclk
  • now investigating the reason why gcc is slower than clang.

Higher-bit BN curve benchmark

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

paramter x64 Firefox on x64 Safari on iPhone7
BN254 0.25 2.48 4.78
BN381_1 0.95 7.91 11.74
BN462 2.16 14.73 22.77
  • x64 : 'Kaby Lake Core i7-7700(3.6GHz)'.
  • Firefox : 64-bit version 58.
  • iPhone7 : iOS 11.2.1.
  • BN254 is by test/bn_test.cpp.
  • BN381_1 and BN462 are by test/bn512_test.cpp.
  • All the timings are given in ms(milliseconds).

The other benchmark results are bench.txt.

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

  • x64, x86 ; Inte Core i7-6700 3.4GHz(Skylake) upto 4GHz on Ubuntu 16.04.
    • sudo cpufreq-set -g performance
  • arm ; 900MHz quad-core ARM Cortex-A7 on Raspberry Pi2, Linux 4.4.11-v7+
  • arm64 ; 1.2GHz ARM Cortex-A53 HiKey
software x64 x86 arm arm64(msec)
ate-pairing 0.21 - - -
mcl 0.31 1.6 22.6 3.9
TEPLA 1.76 3.7 37 17.9
RELIC PRIME=254 0.30 3.5 36 -
MIRACL ake12bnx 4.2 - 78 -
NEONabe - - 16 -
  • compile option for RELIC
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

  • mclBnGT_inv returns a - b w, a conjugate of x for x = a + b w in Fp12 = Fp6[w]
    • use mclBnGT_invGeneric if x is not in GT
  • mclBn_setETHserialization(true) (de)serialize acoording to ETH2.0 serialization of BLS12-381 when BLS12-381 is used.
  • (Break backward compatibility) libmcl_dy.a is renamed to libmcl.a
    • The option SHARE_BASENAME_SUF is removed
  • 2nd argument of mclBn_init is changed from maxUnitSize to compiledTimeVar, which must be MCLBN_COMPILED_TIME_VAR.
  • break backward compatibility of mapToGi for BLS12. A map-to-function for BN is used. If MCL_USE_OLD_MAPTO_FOR_BLS12 is defined, then the old function is used, but this will be removed in the future.

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

  • 2022/Apr/10 v1.60 improve {G1,G2}::mulVec
  • 2022/Mar/25 v1.59 add set DST functions for hashMapToGi
  • 2022/Mar/24 add F::invVec, G::normalizeVec
  • 2022/Mar/08 v1.58 improve SECP256K1 for x64
  • 2022/Feb/13 v1.57 add mulVecMT
  • 2021/Aug/26 v1.52 improve {G1,G2}::isValidOrder() for BLS12-381
  • 2021/May/04 v1.50 support s390x(systemz)
  • 2021/Apr/21 v1.41 fix inner function of mapToGi for large dst (not affect hashAndMapToGi)
  • 2021/May/24 v1.40 fix sigsegv in valgrind
  • 2021/Jan/28 v1.31 fix : call setOrder in init for isValidOrder
  • 2021/Jan/28 v1.30 a little optimization of Fp operations
  • 2020/Nov/14 v1.28 support M1 mac
  • 2020/Jun/07 v1.22 remove old hash-to-curve functions
  • 2020/Jun/04 v1.21 mapToG1 and hashAndMapToG1 are compatible to irtf/eip-2537
  • 2020/May/13 v1.09 support draft-irtf-cfrg-hash-to-curve-07
  • 2020/Mar/26 v1.07 change DST for hash-to-curve-06
  • 2020/Mar/15 v1.06 support hash-to-curve-06
  • 2020/Jan/31 v1.05 mclBn_ethMsgToFp2 has changed to append zero byte at the end of msg
  • 2020/Jan/25 v1.04 add new hash functions
  • 2019/Dec/05 v1.03 disable to check the order in setStr
  • 2019/Sep/30 v1.00 add some functions to bn.h ; api.md.
  • 2019/Sep/22 v0.99 add mclBnG1_mulVec, etc.
  • 2019/Sep/08 v0.98 bugfix Ec::add(P, Q, R) when P == R
  • 2019/Aug/14 v0.97 add some C api functions
  • 2019/Jul/26 v0.96 improved scalar multiplication
  • 2019/Jun/03 v0.95 fix a parser of 0b10 with base = 16
  • 2019/Apr/29 v0.94 mclBn_setETHserialization supports ETH2.0 serialization of BLS12-381
  • 2019/Apr/24 v0.93 support ios
  • 2019/Mar/22 v0.92 shortcut for Ec::mul(Px, P, x) if P = 0
  • 2019/Mar/21 python binding of she256 for Linux/Mac/Windows
  • 2019/Mar/14 v0.91 modp supports mcl-wasm
  • 2019/Mar/12 v0.90 fix Vint::setArray(x) for x == this
  • 2019/Mar/07 add mclBnFr_setLittleEndianMod, mclBnFp_setLittleEndianMod
  • 2019/Feb/20 LagrangeInterpolation sets out = yVec[0] if k = 1
  • 2019/Jan/31 add mclBnFp_mapToG1, mclBnFp2_mapToG2
  • 2019/Jan/31 fix crash on x64-CPU without AVX (thanks to mortdeus)

Author

MITSUNARI Shigeo([email protected])

Sponsors welcome

GitHub Sponsor

mcl's People

Contributors

0xflotus avatar alexandervdm avatar amin-jabri avatar arybczak avatar earonesty avatar gallmann-ubique avatar herumi avatar ineffectualproperty avatar infinity0 avatar jagerman avatar jrhea avatar mskrzypkows avatar mxaddict avatar osyoyu avatar prprhyt avatar rheitjoh avatar sylvarant avatar undeadrat22 avatar worldofjarcraft 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

mcl's Issues

Segfault at src/fp.cpp:579 maskArray

This program (excluding includes):

int main(int argc, char* argv[]) {
	std::array<uint64_t, bls::local::keySize> key_data{
		0x1000000000000000,
		0x0000000000000000,
		0x0000000000000000,
		0x0000000000000000
	};
	bls::SecretKey secret_key;
	secret_key.set(key_data.data());
}

segfaults for some reason:

Program received signal SIGSEGV, Segmentation fault.
0x0000000000420300 in mcl::fp::maskArray<unsigned long> (bitSize=18446744073709551615, n=0, x=0x7fffffffd080)
    at src/fp.cpp:579
579                             maskArray(y, op.N, op.bitSize - 1);
(gdb) up
#1  mcl::fp::copyAndMask (y=y@entry=0x7fffffffd080, x=x@entry=0x7fffffffd040, xByteSize=0, xByteSize@entry=32, 
    op=..., maskMode=<optimized out>, maskMode@entry=mcl::fp::SmallMask) at src/fp.cpp:579
579                             maskArray(y, op.N, op.bitSize - 1);
(gdb) 
#2  0x000000000040401e in mcl::FpT<mcl::bn::local::FrTag, 256ul>::setArrayMask<char> (n=n@entry=32, 
    x=x@entry=0x7fffffffd040 "\320xi", this=0x7fffffffd080, this@entry=0x7fffffffd030)
    at ./../mcl/src/bn_c_impl.hpp:106
106             cast(x)->setArrayMask((const char *)buf, bufSize);
(gdb) 
#3  mclBnFr_setLittleEndian (x=x@entry=0x7fffffffd080, buf=buf@entry=0x7fffffffd060, bufSize=bufSize@entry=32)
    at ./../mcl/src/bn_c_impl.hpp:106
106             cast(x)->setArrayMask((const char *)buf, bufSize);
(gdb) 
#4  0x000000000040352b in bls::SecretKey::setLittleEndian (bufSize=32, buf=0x7fffffffd060, this=0x7fffffffd080)
    at submodules/bls/include/bls/bls.hpp:202
202                     mclBnFr_setLittleEndian(&self_.v, buf, bufSize);
(gdb) 
#5  bls::SecretKey::set (p=0x7fffffffd060, this=0x7fffffffd080) at submodules/bls/include/bls/bls.hpp:197
197                     setLittleEndian(p, local::keySize * sizeof(uint64_t));

at secret_key.set(key_data.data());. What is weird is that identical code works in another larger program. Compiling with GCC 8.1.1 and -O3.

An error happened in C sharp project.

Hi, all.
When I run the C sharp solution in Visual stuido 2017, an error happens in 'bn256.cs' file.

public static void init()
		{
			const int curveFp254BNb = 0;
			const int maxUnitSize = 4;
			if (mclBn_init(curveFp254BNb, maxUnitSize) != 0) { // the value is -4404.
				throw new InvalidOperationException("mclBn_init");
			}
		}

Is any BUGs in the current version ?

Stabilise the API and track ABI compatibility using SOVERSION

See #21 and dfinity-side-projects/bn#14 for some previous discussion. This would be needed for inclusion into standard FOSS distributions like Debian and Fedora.

@@ -106,6 +105,16 @@ include_directories(
 add_library(mcl STATIC ${SRCS})
 if(NOT MSVC)
 add_library(mcl_dy SHARED ${SRCS})
+set_target_properties(mcl_dy PROPERTIES OUTPUT_NAME mcl VERSION 1.0.0 SOVERSION 1)
+# SOVERSION must match VERSION's major number and be bumped whenever non-backwards-ABI-compatible changes
+# are made. The other numbers in VERSION should be bumped for other changes as you wish; one common standard
+# is libtool's scheme: https://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html
+#
+# For semantics of ABI compatibility including when you must bump SOVERSION, see:
+# https://community.kde.org/Policies/Binary_Compatibility_Issues_With_C%2B%2B#The_Do.27s_and_Don.27ts
+#
+# Since ABI compatibility is a strict requirement that is only necessary for shared-library systems,
+# these library version numbers do not necessarily need to match the release version of the overall package.
 endif()
 
 file(GLOB MCL_HEADERS include/mcl/*.hpp include/mcl/*.h)

Go binding: maybe `SetHashOf` should compare with 0 not 1

Thanks for the great library!

Maybe

mcl/ffi/go/mcl/mcl.go

Lines 148 to 151 in d798881

func (x *Fr) SetHashOf(buf []byte) bool {
// #nosec
return C.mclBnFr_setHashOf(x.getPointer(), unsafe.Pointer(&buf[0]), C.size_t(len(buf))) == 1
}

Should compare with 0, not 1? E.g.,

func (x *Fr) SetHashOf(buf []byte) bool {
	// #nosec
	return C.mclBnFr_setHashOf(x.getPointer(), unsafe.Pointer(&buf[0]), C.size_t(len(buf))) == 0
}

Since the success value seems to be 0, and the failure value seems to be -1:

return 0;

Use cmake for the build system

Current situation with hand-written makefiles is less than ideal, because:

  1. There is no make install.
  2. A lot of things are hardcoded (e.g. -O* always overrides compilation flags you can set from the command line, you can't compile with -flto because ar command is hardcoded, linking of 32bit libmcl_dy.so on 64bit system fails because no -m32 is passed to linker)
  3. Windows and Linux need separate makefiles.

Want to use static library in a golang project.

I want to use the library in a golang project use cgo, first, I use "sudo make install" and the libraries install in "/usr/local", but "/usr/local/lib" has only "libmcl.a" and "libmcl.so", and I move "libmclbn384.a" and "libmclbn384.so" from "mcl/lib" to "/usr/local/lib" and the go code works well.

1752504875

but if I want to use pure static library(copy the *.a and *.h to golang project), How should I do? I think I should change all the header file about path, and specify the link path where the static library locate. I try to do that, but don't work. Is there some idea to do that? I'm not familiar with C++.

/*
#cgo  CFLAGS:-DMCLBN_FP_UNIT_SIZE=6
#cgo LDFLAGS:-L ./lib -lmclbn384 -lmcl
#include "./include/bn.h"
*/
import "C"
import "fmt"
import "unsafe"

how encrypt an "byte series"

as the title:
i have a byte array:
char a[64]={};
how can i encrypt a to EncG1 or EncG2?
i need encryt every byte using many encryption loops?

compare with ate-pairing

In https://github.com/herumi/libsnark, you said: ""mcl_bn128": an alternative to "bn128", using the new MCL elliptic curve library. Somewhat slower on x86-64 but supported and optimized for different architectures."

I just added mcl_bn128 to libsnark (latest version) base on your fork(just need to change some include path and function name). But I'm curious the percent of slow, that is for x64 CPU, should I use mcl_bn128 to replace the bn128?

Mapping to G1/G2

I've looked at the "Indifferentiable hashing to Barreto Naehrig curves" paper and for Fp254BNb the assumption that g(1) = 1 + b is a nonzero quare in Fp does not hold, which I assume is the reason why mapping fails for sqrt(-3) and -sqrt(-3). I didn't study these proofs closely to see whether the broken assumption leads to other values that will not be mappable. Do you know of any? Also, what about G2?

As a side note, page 3 of the paper has an interesting remark:

like Icart’s encoding and many others, this encoding f will not yield a gener-
ically secure hash function construction if we simply compose it with a ran-
dom oracle to the base field (e.g. it is easy to distinguish such a hash function
from a random oracle to the curve since its image has a simple algebraic de-
scription and only contains a constant fraction of all points). However, we
show (in Section 5) that it is well-distributed in the sense of Farashahi et al.
[17]. This implies
 that if h1 , h2 are random oracles to the base field, then
m -> f(h1(m)) + f(h2(m)) is a good, generically secure hash function to the
BN curve (it is indifferentiable from a random oracle);

However, it seems this is what BN256_G1_hashAndMapTo (and G2 variant) do, i.e. they just hash a message to a value in Fp and then map this value to get a point on the curve.

Getting the base point in golang

Hi, I need to generate points deterministically in order to make comparisons with alternative implementations.

What I have so far is the following:

	var f Fr
	f.SetInt64(x)

	var g1, gout G1
	// TODO set g1 to the base point
	G1Mul(&gout, &g1, &f)

but obviously gout is zero because g1 is zero.

How can I set g1 to the base point? I didn't see an API to do it.

big endian save&load

Any (easy) way to change littlte endian to big endian when doing serialization.

Link fp.o in libmclbn512 (probably others)

I ran make, copied the lib files to my /usr/local/lib/
I tried to import the built libmclbn512, got an error
Error opening shared object "libmclbn512.so": /usr/local/lib/libmclbn512.so: undefined symbol: _ZN3mcl2fp2Op18destroyFpGeneratorEPNS0_11FpGeneratorE

Edited Makefile to include $(LIB_OBJ) next to $(BN512_OBJ) on L169.
Recompiled, imported with no error.

improve NASM binding

  • hashAndMapToG1 is very slow, it should be at least 10 times faster.
  • implement portable SHA-2 instead of SHA-1.
  • try to import evm2wasm for 256-bit arithmetic operations.
  • try to use clang wasm backend.

Where is the "mclBn256.dll" file?

Hi,all.
I wanna complie the C sharp solution to test the results, but there is a error msg "ERR=System.DllNotFoundException: couldn't load 'mclBn256.dll'" in my Visual studio 2017.

How to deal with this problem?

Thank you all!

Question about constant time exponentiation/multiplication

Constant time version of these seems to be constant in a sense that it doesn't reveal information about particular bits of the input, but it does reveal information about the bitlength of input, i.e. multiplying a point from bn256::G1 by 42 is much faster than multiplying it by a "proper" 254bit scalar. I wonder if that can be a problem?

compiling shared library with ndk

Hi, how could I compile a shared library with the full code using ndk? Thanks.

** Why I ask
I need to use MCL with my project. So the following code is used first, it succeeds to generate libmcl.so.

include $(CLEAR_VARS)
LOCAL_SHARED_LIBRARIES := gmp gmpxx crypto
LOCAL_MODULE := mcl
LOCAL_ARM_NEON := true
LOCAL_SRC_FILES := ./src/fp.cpp \
	./src/bn_c384.cpp
LOCAL_CFLAGS += -I$(LOCAL_PATH)/include/
LOCAL_CFLAGS += -Wall
LOCAL_CPPFLAGS += -fexceptions
include $(BUILD_SHARED_LIBRARY)

But there are some error when using libmcl.so to compile my project.

/home/luopeng/my_sec_data/jni/include/mcl/fp.hpp:530: error: undefined reference to 'mcl::fp::detectIoMode(int, std::__ndk1::ios_base const&)'
/home/luopeng/my_sec_data/jni/include/mcl/fp_tower.hpp:474: error: undefined reference to 'mcl::fp::detectIoMode(int, std::__ndk1::ios_base const&)'

Then I notice that detectIoMode is under a macro. So I add the following compile option.

LOCAL_CPPFLAGS += -DCYBOZU_DONT_USE_STRING

But it fails to generate the libmcl.so.

/home/luopeng/mcl/mcl/jni/include/mcl/gmp_util.hpp:714:45: error: too few arguments to function call, expected at least 3, have 2
printf("\"%s\",\n", mcl::gmp::getStr(p, 16).c_str());
~~~~~~~~~~~~~~~~      ^                    

So, do you have any advice? thanks.

question about serialize performance

I am using the curve bn254.
I found the performance of the mcl::EcT<Fp2>::load() is weird slow.

In my computer, load 1M(1024768) G2 from a data file using 450 seconds (single thread).
It seems that the main cost is the function getYfromX() which need to compute the Square Root of the Y.

Since the data file is generated by myself, how can I save the G2 with the Y? I know, in this case, the data file size will *2. Maybe I should not use the mcl::IoMode::IoSerialize, which flag should I use? I do not understand all those flags.

My code looks like:

typedef mcl::EcT<Fp2> G2;
struct imembuf : public std::streambuf {
  imembuf(char const* array, size_t len) {
    char* p(const_cast<char*>(array));
		this->setg(p, p, p + len);
  }
};

struct imemstream : virtual imembuf, std::istream {
  imemstream(char* array, size_t len)
      : imembuf(array, len), std::istream(static_cast<std::streambuf*>(this)) {}
};

bool BinToG2(uint8_t const* buf, G2* g) {
  bool ret;
  imemstream in((char*)buf, 64);
  g->load(&ret, in, mcl::IoMode::IoSerialize);
  return ret;
}


performance and fewer bits curve

In some scenario, for example, proofs of data possession, proofs of data retrievability, we do not need that safe, it's not the transaction.
I just implement the paper https://hovav.net/ucsd/dist/verstore.pdf . In paper 3.3, it requires to calculate 10000 times ui^fi for a 320KB file, which ui is a group point and fi is a field number (BN128). Now it needs several seconds (one core).
I hope I can improve the speed 10 times, and I am seeking a fewer bits curve.
Is it possible?
Could you please provide a curve which just use 80 bits or 64 bits?

performance of bls12-381

I just tested the bls12-381.
To my surprise, the bls12-381 is much slower than bn254.
I tested 1000 times ecc_mul, bn254 use 90ms, and bls12-381 use 900ms.
Why? Maybe I made some mistakes(some optimize compile flags)?

Where is the JNI documentation?

The main README.md says that the JNI interface is described in /java/java.md but that file doesn't exist. (never mind - I found it in ffi/java/java.md)

Also, I was trying to do 'make test_java' on MacOS with Java 8 and had to add two -I statements in order to find jni.h and jni_md.h:
-I/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/include
-I/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/include/darwin

When make arrives at compiling ElgamalTest.java, it gets the following error

javac ElgamalTest.java
ElgamalTest.java:2: error: package com.herumi.mcl does not exist
import com.herumi.mcl.*;

I found com.herumi.mcl.* in mcladt. What is the relationship between mcl and mcladt?

I would like to run MCL with Java, but not on Android. Is there a way to do that?

Thanks again for your nice library.

Questions regarding backend implementation

Hi @herumi

I am interested in contributing to the repo to attempt to provide faster signature verification. For this, I wanted to understand the underlying implementation of the miller_loop and finalexp functions. As far as I understand, these functions are implemented in the llvm IR. I am having some trouble understanding what is going on. Do you have more high-level code on the miller_loop and finalexp implementation?

Kind regards

static variables init order

I init the mcl with code like:

static struct LibInit {
    LibInit()
    {
        mcl::bn256::initPairing(mcl::bn::CurveSNARK1); // init mcl library
    }
} s_libInit;

And I got an exception in xbyak.h RegExp::RegExp(...).
The caller function is MixPack::init and the code is
this->m = Xbyak::util::rsp + rspPos;

The static const Xbyak::util::rsp is not initialized yet.
I print the rsp, looks like:

(gdb) print Xbyak::util::rsp
$5 = {<Xbyak::Reg32e> = {<Xbyak::Reg> = {<Xbyak::Operand> = {static EXT8BIT = 32 ' ', idx_ = 0, kind_ = 0, bit_ = 0, zero_ = 0, mask_ = 0,
        rounding_ = 0}, <No data fields>}, <No data fields>}, <No data fields>}

I understand that the c++ static variables init order is somehow like magic. So it seems that I should not init the mcl by a static variable's constructor.
But I need to define some global variables looks like:

std::vector<size_t> mcl_bn128_G1::wnaf_window_table;
std::vector<size_t> mcl_bn128_G1::fixed_base_exp_window_table;
mcl_bn128_G1 mcl_bn128_G1::G1_zero;
mcl_bn128_G1 mcl_bn128_G1::G1_one;

So, what should I do? Any suggestion? Thanks.

Elgamal Plaintext Range ?

  1. What is the plaintxt range of the Elgamal ? If the mcl::ecparam::secp160k1 is used, shoud the plaintext domain be 160-bits (i.e., 2^160) ?
  2. Should we need to cache all the elements in the plaintext range (the setCache method in the private key class), if we want to use Elgamal to do arithmetic computation ?

how to accelerate g*f by precompute?

The speed of g*f (BN curve) in mcl is very fast, much faster than normal wNAF algorithm.

In my scenario, the g is hardcoded, so I think I can accelerate the speed of g*f by precompute and cache some data, for example, 2g, 4g, 8g,16g ... , then I can convert theg*fto test_bit&add. But to my surprise, I found the test_bit&add version only slightly faster (20%~30%) than mcl version.

So, what should I do? How can I accelerate the speed for 100% or more by precompute/cache? Could you please give some suggestions (or some URLs)?

Build to golang

Hello. When I import ffi/go/mcl.go to own project and then build, I have that error

# github.com/herumi/mcl/ffi/go/mcl
In file included from vendor/src/github.com/herumi/mcl/ffi/go/mcl/mcl.go:10:
/usr/local/include/mcl/bn.h:13:3: error: #error "define MCLBN_FP_UNIT_SIZE 4(, 6 or 8)"
  #error "define MCLBN_FP_UNIT_SIZE 4(, 6 or 8)"
   ^~~~~

Compilation finished with exit code 2

How correct build mcl to using in golang?
Thanks!!!

how to get G1::zero() and G1::one()?

I think it's a stupid question...

How can I get the zero and one element in G?
Should I use G1 zero(Fp(0), Fp(0))?
And, as my understanding, the one is the generator of the G, but how to get it?

Question about BN-381-1 and BN-381-2

Hi,
You support two 381 bits BN curve : N-381-1 and BN-381-2. The first one is a A Family of Implementation-Friendly BN Elliptic Curves, the second one is used in relic-toolkit. Then , are they both security? And , is there other difference except their params. And which one is more faster?

tests fail with segfault on x86-64 and Ubuntu

I am having an issue with xbyak that is causing some of the tests (most importantly bn_test.exe) to crash. I have investigated the issue and concluded that the problem has something to do with xbyak because the problem goes away whenever xbyak is not enabled.

However having xbyak disabled leads to further breakage when trying to compile bls with the xbyak disabled mcl library. (that error is related to an undefined reference to a fp::Op related function that is #ifdef'd out in the mcl code whenever MCL_USE_XBYAK=1 is set)

Clarify how to init() in JavaScript

mcl.init(mcl.BLS12_381).then(() => {
	console.log("mcl initialized to BLS12-381.");
	console.log("G1 = " + mcl.getBasePointG1().getStr(16));
});

G1 prints as 0, so it is apparently not initialized. I can't tell from reading mcl.js how to properly initialize G1 and G2. I would like to use the same G1 and G2 points as zksnark.

I see your note on initialization but I don't see similar initialization functions in the JavaScript API. Can you please clarify how to initialize G1 and G2 in JavaScript?

Also, there is no function mcl.getBasePointG2() that we can use to verify that G2 is properly initialized.

mcl-wasm: Clarification or possible error in deserializeHexStrToFp

Is Fp supposed to be a number in the range [0..p] where p defines the modular field of the elliptic curve? In BLS12-381, p is 381 bits long so Fp should also be 381 bits long. However, deserializeHexStrToFp limits the number to 256 bits.

Unable to deserialize 'eca3a7bd15e08e0f6771805cbc4b8905654e9d356d5398a2aa4cbc71a55017c'
test.js:23975 Error: fromHexStr:length must be even 63
    at Object.exports.fromHexStr (test.js:22820)
    at exports.Fp.deserializeHexStr (test.js:22950)
    at Object.exports.deserializeHexStrToFp (test.js:23113)

What I actually want to generate is a random number in [0..p). Does mcl-wasm provide a function to do that?

BN462

How can I use the BN462 curve?

deserializeHexStrToFr problem in mcl-wasm

I am unable to deserialize some hex strings in mcl-wasm in the browser.
The first test string is 63 hex characters so it fails due to not being an even number of characters. If I put "0" on the front to make it 64 characters, there is an error in the C code. Adding a leading space to the short string also generates an error.

How do I create an Fr number that is smaller than 32 bytes? For example, I would like mcl.deserializeHexStrToFr("07") to work. Is there an alternative method?

As a side issue, the error message is confusing. "Error: fromHexStr:length must be even 63" would be more understandable if it was "fromHexStr:length must be even; length is 63".

Code:

  	let t1str = null;
    	let t1 = null;
    	try {
    		t1str = "eca3a7bd15e08e0f6771805cbc4b8905654e9d356d5398a2aa4cbc71a55017c";
    		t1 = mcl.deserializeHexStrToFr(t1str);
    	} catch (ex) {
    		console.log("Unable to deserialize '" + t1str + "'");
    		console.log(ex);
    	}
    	
       	try {
    		t1str = "0eca3a7bd15e08e0f6771805cbc4b8905654e9d356d5398a2aa4cbc71a55017c";
    		t1 = mcl.deserializeHexStrToFr(t1str);
    	} catch (ex) {
    		console.log("Unable to deserialize '" + t1str + "'");
    		console.log(ex);
    	}

Output:

mcl initialized to BLS12-381.

test.js:23974 Unable to deserialize 'eca3a7bd15e08e0f6771805cbc4b8905654e9d356d5398a2aa4cbc71a55017c'
test.js:23975 Error: fromHexStr:length must be even 63
    at Object.exports.fromHexStr (test.js:22820)
    at exports.Fr.deserializeHexStr (test.js:22950)
    at Object.exports.deserializeHexStrToFr (test.js:23070)
    at <anonymous>:1:1

test.js:23982 Unable to deserialize '0eca3a7bd15e08e0f6771805cbc4b8905654e9d356d5398a2aa4cbc71a55017c'
test.js:23983 Error: err _wrapDeserialize
    at test.js:22856
    at exports.Fr._setter (test.js:22983)
    at exports.Fr.deserialize (test.js:23033)
    at exports.Fr.deserializeHexStr (test.js:22950)
    at Object.exports.deserializeHexStrToFr (test.js:23070)
    at <anonymous>:1:1

MCL uses a old version CYBOZULIB_TAG release2018050

  1. current MCL uses (CYBOZULIB_TAG release2018050) which the following error pops out.
error: ‘uintToDec’ is not a member of ‘cybozu::itoa_local’
size_t len = cybozu::itoa_local::uintToDec(buf, bufSize - pos, r);                           
  1. the uintToDec is in this commit but not in release2018050.

New release?

I'm one of the contributors of Homebrew, a community-driven package manager for macOS.

Homebrew has a package for your creation mcl.

Homebrew needs stable releases to update package.
Since there is no release after 2014, homebrew's mcl remains old.

Are you planning any release on your homepage or Github?

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.