This library is an implementation of BLS threshold signature, which supports the new BLS Signatures specified at Ethereum 2.0 Phase 0.
- 2022/Apr/20 The performance of MulVec got 2x speed for n >= 256, but const attribute of some arguments of MulVec and MultiVerify is removed.
- They may be normalized in processing but the value are not changed.
- 2021/Sep/16 update mcl and improve performance of isValidOrder, which is called from setStr/deserialize.
- 2021/Apr/28 add blsSetGeneratorOfPublicKey to change the generator.
- 2021/Jan/28 check zero public key on BLS_ETH mode
- 2020/Oct/07 add
blsMultiVerify
to process many verification all togather with multi thread.
- Windows Visual Studio / MSYS2(MinGW-w64)
- Linux
- macOS
- Android
- iOS
- WebAssembly
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.
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 | - |
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 asblsSetETHmode
are NOT thread-safe. The other functions are all thread-safe.blsSetETHmode
is available for onlyBLS_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
isn
array of PublicKeymsgVec
isn * msgSize
-byte array, which concatenatesn
-byte messages of lengthmsgSize
.
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 order- every
n
-byte messages of lengthmsgSize
are different from each other
Check 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);
- Prepare k secret keys (msk).
- Make n secret keys from msk by
blsSecretKeyShare
. - Each user makes the public key from the given secret key.
- Each user makes a signature for the same message.
- Any k subset of n signatures can recover the master signature by
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.
static library
mklib eth
dynamic library
mklib dll eth
- 2020/May/13 :
blsSetETHmode()
supportsBLS_ETH_MODE_DRAFT_07
defined at BLS12381G2_XMD:SHA-256_SSWU_RO_. - 2020/Apr/02 : experimental add blsMultiAggregateSignature/blsMultiAggregatePublicKey multiSig
- The hash function is temporary, which may be modified in the future.
- 2020/Mar/26 : DST of hash-to-curve of mcl is changed, so the output has also changed for
BLS_ETH_MODE_DRAFT_06
. - 2020/Mar/15 :
blsSetETHmode()
supportsBLS_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([email protected])