This library is an implementation of BLS threshold signature, which supports the new BLS Signatures specified at Ethereum 2.0 Phase 0.
blsMultiVerify
to process many verification all togather with multi thread.This library supports type-3 pairings such as BN curves and BLS curves. G1, G2, and GT are a cyclic group of prime order r.
e : G1 x G2 -> GT ; pairing
There are two ways for BLS signature.
type | SecretKey | PublicKey | Signature |
---|---|---|---|
default | Fr | G2 | G1 |
ETH2.0 spec (BLS_ETH=1) | Fr | G1 | G2 |
If you need ETH2.0 spec, then use this library with BLS_ETH=1
mode.
If you want to use the same parameters as Ethereum 2.0, just define BLS_ETH
.
If you want to use mcl/bls without BLS_ETH
, then check the following settings.
blsSetETHserialization(1);
to use the same specification as ETH2.0.Serialize()
compresses a point of G1/G2.blsPublicKeySetHexStr
.blsSetMapToMode(MCL_MAP_TO_MODE_HASH_TO_CURVE);
to use the same specification as ETH2.0.mclBnG1_setDst
to set up domain separation.For example, see initForDFINITY for DFINITY compatibility.
language | ETH2.0 spec (PublicKey = G1) | default (PublicKey = G2) |
---|---|---|
Go | bls-eth-go-binary | bls-go-binary |
WebAssembly (Node.js) | bls-eth-wasm | bls-wasm |
Rust | bls-eth-rust | - |
BLS_ETH=1
The compiled static libraries with BLS_ETH=1
mode for {windows, darwin}/amd64, linux/{amd64, arm64} and android/{arm64-v8a, armeabi-v7a}
are provided at bls-eth-go-binary/bls/lib.
#define BLS_ETH
#include <mcl/bn384_256.h>
#include <bls/bls.h>
Remark: BLS_ETH
must always be defined before including bls/bls.h
if you need ETH2.0 spec mode.
// init library at once before calling the other APIs
int err = blsInit(MCL_BLS12_381, MCLBN_COMPILED_TIME_VAR);
if (err != 0) {
printf("blsInit err %d\n", err);
exit(1);
}
// use the latest eth2.0 spec
blsSetETHmode(BLS_ETH_MODE_LATEST);
Remark:
blsInit
and some functions which modify global settings such as blsSetETHmode
are NOT thread-safe.
The other functions are all thread-safe.blsSetETHmode
is available for only BLS_ETH=1
mode.Init a secret key sec
and create a public key pub
.
blsSecretKey sec;
blsPublicKey pub;
// init SecretKey sec by random number
blsSecretKeySetByCSPRNG(&sec);
// get PublicKey pub from SecretKey sec
blsGetPublicKey(&pub, &sec);
Make a signature sig
of a message msg[0..msgSize-1]
by the secret key sec
.
blsSignature sig;
char msg[] = "hello";
const size_t msgSize = strlen(msg);
blsSign(&sig, &sec, msg, msgSize);
msg
may contain \x00
if the correct msgSize
is specified.
Verify the signature sig
of the message msg[0..msgSize-1]
by the public key pub
.
// return 1 if it is valid else 0
int blsVerify(&sig, &pub, msg, msgSize);
Aggregate Signatures sigVec[0]
, ..., sigVec[n-1]
to aggSig
.
aggSig
is cleared if n = 0
.
void blsAggregateSignature(
blsSignature *aggSig,
const blsSignature *sigVec,
mclSize n
);
Verify a signature sig
of a message msg[0..msgSize-1]
by pubVec[0]
, ..., pubVec[n-1]
.
int blsFastAggregateVerify(
const blsSignature *sig,
const blsPublicKey *pubVec,
mclSize n,
const void *msg,
mclSize msgSize
);
pubVec
is n
array of PublicKeymsgVec
is n * msgSize
-byte array, which concatenates n
-byte messages of length msgSize
.Verify Signature sig
of (Message msgVec[msgSize * i..msgSize * (i+1)-1]
and pubVec[i]
) for i = 0
, ..., n-1
.
int blsAggregateVerifyNoCheck(
const blsSignature *sig,
const blsPublicKey *pubVec,
const void *msgVec,
mclSize msgSize,
mclSize n
);
REMARK : blsAggregateVerifyNoCheck
does not check
sig
has the correct ordern
-byte messages of length msgSize
are different from each otherCheck them at the caller if necessary.
bls.h | eth2.0 spec name |
---|---|
blsSign | Sign |
blsVerify | Verify |
blsAggregateSignature | Aggregate |
blsFastAggregateVerify | FastAggregateVerify |
blsAggregateVerifyNoCheck | AggregateVerify |
int blsSecretKeySetLittleEndianMod(blsSecretKey *sec, const void *buf, mclSize bufSize);
Set sec
to (buf[0..bufSize-1]
as little endian) mod r and return 0 if bufSize <= 64
else -1.
mclSize blsSecretKeySerialize(void *buf, mclSize maxBufSize, const blsSecretKey *sec);
mclSize blsPublicKeySerialize(void *buf, mclSize maxBufSize, const blsPublicKey *pub);
mclSize blsSignatureSerialize(void *buf, mclSize maxBufSize, const blsSignature *sig);
Serialize the instance to buf[0..maxBufSize-1]
and return written byte size if success else 0.
mclSize blsSecretKeyDeserialize(blsSecretKey *sec, const void *buf, mclSize bufSize);
mclSize blsPublicKeyDeserialize(blsPublicKey *pub, const void *buf, mclSize bufSize);
mclSize blsSignatureDeserialize(blsSignature *sig, const void *buf, mclSize bufSize);
Deserialize buf[0..bufSize-1]
to the instance and return read byte size if success else 0.
Check whether sig
and pub
have the correct order r
.
// return 1 if it is valid else 0
int blsSignatureIsValidOrder(const blsSignature *sig);
int blsPublicKeyIsValidOrder(const blsPublicKey *pub);
blsSecretKeyShare
.blsSignatureRecover
.See sample/minsample.c for the details.
int blsSecretKeyShare(blsSecretKey *sec, const blsSecretKey *msk, mclSize k, const blsId *id);
Make sec
corresponding to id
from {msk[i] for i = 0, ..., k-1}
.
int blsSignatureRecover(blsSignature *sig, const blsSignature *sigVec, const blsId *idVec, mclSize n);
Recover sig
from {(sigVec[i], idVec[i]) for i = 0, ..., n-1}
.
blsMultiAggregateSignature
and blsMultiAggregatePublicKey
are provided for BLS Multi-Signatures With Public-Key Aggregation.
The hash function is temporary.
See blsMultiAggregateTest.
void blsMultiAggregateSignature(
blsSignature *aggSig,
blsSignature *sigVec,
blsPublicKey *pubVec,
mclSize n
);
Set aggSig = sum_{i=0^n-1} sigVec[i] t_i, where (t_1, ..., t_n) = Hash({pubVec[0..n-1]})
.
void blsMultiAggregatePublicKey(
blsPublicKey *aggPub,
blsPublicKey *pubVec,
mclSize n
);
Set aggPub = sum_{i=0^n-1} pubVec[i] t_i, where (t_1, ..., t_n) = Hash({pubVec[0..n-1]})
.
The following description is for BLS_ETH=1
mode.
Remove it if you need PublicKey as G1.
git clone --recursive https://github.com/herumi/bls
make -C mcl lib/libmcl.a
make BLS_ETH=1 lib/libbls384_256.a
If the option MCL_USE_GMP=0
(resp.MCL_USE_OPENSSL=0
) is used then GMP (resp. OpenSSL) is not used.
Open the x64 Native Tools for Visual Studio and type the following command.
static library
mklib eth
dynamic library
mklib dll eth
Or open bls.sln
and build it.
REMARK CmakeLists.txt is not maintained for Visual Studio.
blsSetETHmode()
supports BLS_ETH_MODE_DRAFT_07
defined at BLS12381G2_XMD:SHA-256_SSWURO.BLS_ETH_MODE_DRAFT_06
.blsSetETHmode()
supports BLS_ETH_MODE_DRAFT_06
defined at draft-irtf-cfrg-hash-to-curve at March 2020. But it has not yet fully tested.modified new BSD License http://opensource.org/licenses/BSD-3-Clause
MITSUNARI Shigeo(herumi@nifty.com)