Skip to main content

BLS signatures in c++ (with python bindings)

Project description

BLS Signatures implementation

Build PyPI PyPI - Format GitHub

Total alerts Language grade: JavaScript Language grade: Python Language grade: C/C++

NOTE: THIS LIBRARY IS A DRAFT AND NOT YET REVIEWED FOR SECURITY

NOTE: THIS LIBRARY WAS SHIFTED TO THE IETF BLS SPECIFICATION ON 7/16/20

Implements BLS signatures with aggregation using relic toolkit for cryptographic primitives (pairings, EC, hashing) according to the IETF BLS RFC with these curve parameters for BLS12-381.

Features:

  • Non-interactive signature aggregation following IETF specification
  • Works on Windows, Mac, Linux, BSD
  • Efficient verification using Proof of Posssesion (only one pairing per distinct message)
  • Aggregate public keys and private keys
  • EIP-2333 key derivation (including unhardened BIP-32-like keys)
  • Key and signature serialization
  • Batch verification
  • Python bindings
  • Pure python bls12-381 and signatures
  • JavaScript bindings (currently out of date)

Before you start

This library uses minimum public key sizes (MPL). A G2Element is a signature (96 bytes), and a G1Element is a public key (48 bytes). A private key is a 32 byte integer. There are three schemes: Basic, Augmented, and ProofOfPossession. Augmented should be enough for most use cases, and ProofOfPossession can be used where verification must be fast.

Import the library

#include "bls.hpp"
using namespace bls;

Creating keys and signatures

// Example seed, used to generate private key. Always use
// a secure RNG with sufficient entropy to generate a seed (at least 32 bytes).
vector<uint8_t> seed = {0,  50, 6,  244, 24,  199, 1,  25,  52,  88,  192,
                        19, 18, 12, 89,  6,   220, 18, 102, 58,  209, 82,
                        12, 62, 89, 110, 182, 9,   44, 20,  254, 22};

PrivateKey sk = AugSchemeMPL::KeyGen(seed);
G1Element pk = sk.GetG1Element();

vector<uint8_t> message = {1, 2, 3, 4, 5};  // Message is passed in as a byte vector
G2Element signature = AugSchemeMPL::Sign(sk, message);

// Verify the signature
bool ok = AugSchemeMPL::Verify(pk, message, signature));

Serializing keys and signatures to bytes

vector<uint8_t> skBytes = sk.Serialize();
vector<uint8_t> pkBytes = pk.Serialize();
vector<uint8_t> signatureBytes = signature.Serialize();

cout << Util::HexStr(skBytes) << endl;    // 32 bytes printed in hex
cout << Util::HexStr(pkBytes) << endl;    // 48 bytes printed in hex
cout << Util::HexStr(signatureBytes) << endl;  // 96 bytes printed in hex

Loading keys and signatures from bytes

// Takes vector of 32 bytes
PrivateKey skc = PrivateKey::FromByteVector(skBytes);

// Takes vector of 48 bytes
pk = G1Element::FromByteVector(pkBytes);

// Takes vector of 96 bytes
signature = G2Element::FromByteVector(signatureBytes);

Create aggregate signatures

// Generate some more private keys
seed[0] = 1;
PrivateKey sk1 = AugSchemeMPL::KeyGen(seed);
seed[0] = 2;
PrivateKey sk2 = AugSchemeMPL::KeyGen(seed);
vector<uint8_t> message2 = {1, 2, 3, 4, 5, 6, 7};

// Generate first sig
G1Element pk1 = sk1.GetG1Element();
G2Element sig1 = AugSchemeMPL::Sign(sk1, message);

// Generate second sig
G1Element pk2 = sk2.GetG1Element();
G2Element sig2 = AugSchemeMPL::Sign(sk2, message2);

// Signatures can be non-interactively combined by anyone
G2Element aggSig = AugSchemeMPL::Aggregate({sig1, sig2});

ok = AugSchemeMPL::AggregateVerify({pk1, pk2}, {message, message2}, aggSig);

Arbitrary trees of aggregates

seed[0] = 3;
PrivateKey sk3 = AugSchemeMPL::KeyGen(seed);
G1Element pk3 = sk3.GetG1Element();
vector<uint8_t> message3 = {100, 2, 254, 88, 90, 45, 23};
G2Element sig3 = AugSchemeMPL::Sign(sk3, message3);


G2Element aggSigFinal = AugSchemeMPL::Aggregate({aggSig, sig3});
ok = AugSchemeMPL::AggregateVerify({pk1, pk2, pk3}, {message, message2, message3}, aggSigFinal);

Very fast verification with Proof of Possession scheme

// If the same message is signed, you can use Proof of Posession (PopScheme) for efficiency
// A proof of possession MUST be passed around with the PK to ensure security.

G2Element popSig1 = PopSchemeMPL::Sign(sk1, message);
G2Element popSig2 = PopSchemeMPL::Sign(sk2, message);
G2Element popSig3 = PopSchemeMPL::Sign(sk3, message);
G2Element pop1 = PopSchemeMPL::PopProve(sk1);
G2Element pop2 = PopSchemeMPL::PopProve(sk2);
G2Element pop3 = PopSchemeMPL::PopProve(sk3);

ok = PopSchemeMPL::PopVerify(pk1, pop1);
ok = PopSchemeMPL::PopVerify(pk2, pop2);
ok = PopSchemeMPL::PopVerify(pk3, pop3);
G2Element popSigAgg = PopSchemeMPL::Aggregate({popSig1, popSig2, popSig3});

ok = PopSchemeMPL::FastAggregateVerify({pk1, pk2, pk3}, message, popSigAgg);

// Aggregate public key, indistinguishable from a single public key
G1Element popAggPk = pk1 + pk2 + pk3;
ok = PopSchemeMPL::Verify(popAggPk, message, popSigAgg);

// Aggregate private keys
PrivateKey aggSk = PrivateKey::Aggregate({sk1, sk2, sk3});
ok = (PopSchemeMPL::Sign(aggSk, message) == popSigAgg);

HD keys using EIP-2333

// You can derive 'child' keys from any key, to create arbitrary trees. 4 byte indeces are used.
// Hardened (more secure, but no parent pk -> child pk)
PrivateKey masterSk = AugSchemeMPL::KeyGen(seed);
PrivateKey child = AugSchemeMPL::DeriveChildSk(masterSk, 152);
PrivateKey grandChild = AugSchemeMPL::DeriveChildSk(child, 952)

// Unhardened (less secure, but can go from parent pk -> child pk), BIP32 style
G1Element masterPk = masterSk.GetG1Element();
PrivateKey childU = AugSchemeMPL::DeriveChildSkUnhardened(masterSk, 22);
PrivateKey grandchildU = AugSchemeMPL::DeriveChildSkUnhardened(childU, 0);

G1Element childUPk = AugSchemeMPL::DeriveChildPkUnhardened(masterPk, 22);
G1Element grandchildUPk = AugSchemeMPL::DeriveChildPkUnhardened(childUPk, 0);

ok = (grandchildUPk == grandchildU.GetG1Element();

Build

Cmake 3.14+, a c++ compiler, and python3 (for bindings) are required for building.

mkdir build
cd build
cmake ../
cmake --build . -- -j 6

Run tests

./build/src/runtest

Run benchmarks

./build/src/runbench

On a 3.5 GHz i7 Mac, verification takes about 1.1ms per signature, and signing takes 1.3ms.

Link the library to use it

g++ -Wl,-no_pie -std=c++11  -Ibls-signatures/build/_deps/relic-src/include -Ibls-signatures/build/_deps/relic-build/include -Ibls-signatures/src -L./bls-signatures/build/ -l bls yourapp.cpp

Notes on dependencies

Libsodium and GMP are optional dependencies: libsodium gives secure memory allocation, and GMP speeds up the library by ~ 3x. To install them, either download them from github and follow the instructions for each repo, or use a package manager like APT or brew. You can follow the recipe used to build python wheels for multiple platforms in .github/workflows/

Discussion

Discussion about this library and other Chia related development is in the #dev channel of Chia's public Keybase channels.

Code style

  • Always use vector<uint8_t> for bytes
  • Use size_t for size variables
  • Uppercase method names
  • Prefer static constructors
  • Avoid using templates
  • Objects allocate and free their own memory
  • Use cpplint with default rules
  • Use SecAlloc and SecFree when handling secrets

ci Building

The primary build process for this repository is to use GitHub Actions to build binary wheels for MacOS, Linux (x64 and aarch64), and Windows and publish them with a source wheel on PyPi. See .github/workflows/build.yml. CMake uses FetchContent to download pybind11 for the Python bindings and relic from a chia relic forked reporitory. Building is then managed by cibuildwheel. Further installation is then available via pip install blspy e.g. The ci builds include GMP and libsoduium.

Contributing and workflow

Contributions are welcome and more details are available in chia-blockchain's CONTRIBUTING.md.

The master branch is usually the currently released latest version on PyPI. Note that at times bls-signatures/blspy will be ahead of the release version that chia-blockchain requires in it's master/release version in preparation for a new chia-blockchain release. Please branch or fork master and then create a pull request to the master branch. Linear merging is enforced on master and merging requires a completed review. PRs will kick off a GitHub actions ci build and analysis of bls-signatures at lgtm.com. Please make sure your build is passing and that it does not increase alerts at lgtm.

Specification and test vectors

The IETF bls draft is followed. Test vectors can also be seen in the python and cpp test files.

Libsodium license

The libsodium static library is licensed under the ISC license which requires the following copyright notice.

ISC License

Copyright (c) 2013-2020 Frank Denis <j at pureftpd dot org>

Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

GMP license

GMP is distributed under the GNU LGPL v3 license

Relic license

Relic is used with the Apache 2.0 license

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

blspy-0.2.4.tar.gz (236.7 kB view details)

Uploaded Source

Built Distributions

blspy-0.2.4-cp38-cp38-win_amd64.whl (2.0 MB view details)

Uploaded CPython 3.8 Windows x86-64

blspy-0.2.4-cp38-cp38-manylinux2014_aarch64.whl (690.0 kB view details)

Uploaded CPython 3.8

blspy-0.2.4-cp38-cp38-manylinux2010_x86_64.whl (791.1 kB view details)

Uploaded CPython 3.8 manylinux: glibc 2.12+ x86-64

blspy-0.2.4-cp38-cp38-macosx_10_14_x86_64.whl (642.4 kB view details)

Uploaded CPython 3.8 macOS 10.14+ x86-64

blspy-0.2.4-cp37-cp37m-win_amd64.whl (2.0 MB view details)

Uploaded CPython 3.7m Windows x86-64

blspy-0.2.4-cp37-cp37m-manylinux2014_aarch64.whl (694.6 kB view details)

Uploaded CPython 3.7m

blspy-0.2.4-cp37-cp37m-manylinux2010_x86_64.whl (791.4 kB view details)

Uploaded CPython 3.7m manylinux: glibc 2.12+ x86-64

blspy-0.2.4-cp37-cp37m-macosx_10_14_x86_64.whl (636.8 kB view details)

Uploaded CPython 3.7m macOS 10.14+ x86-64

File details

Details for the file blspy-0.2.4.tar.gz.

File metadata

  • Download URL: blspy-0.2.4.tar.gz
  • Upload date:
  • Size: 236.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.50.2 CPython/3.7.9

File hashes

Hashes for blspy-0.2.4.tar.gz
Algorithm Hash digest
SHA256 f98f7861b6518f3c9b866854809fa5b872e3566705d95aae2268cb834441f34c
MD5 cf05adbcd0242297b173182b11076ce8
BLAKE2b-256 88b854e06b3b4dc930b5542fff37fd858721d5eace87dfb3d40b3d27e82e32e5

See more details on using hashes here.

File details

Details for the file blspy-0.2.4-cp38-cp38-win_amd64.whl.

File metadata

  • Download URL: blspy-0.2.4-cp38-cp38-win_amd64.whl
  • Upload date:
  • Size: 2.0 MB
  • Tags: CPython 3.8, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.50.2 CPython/3.7.9

File hashes

Hashes for blspy-0.2.4-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 440933815741d9c74fe3fc83f3890fd39a424bf30e2cf983d9762b91e92bee89
MD5 36591cd821a89bafccba5a9ecf8a2ca5
BLAKE2b-256 6b4ae9c7ad696c1b63cbd7a0fa710bc98b949200bb92abc0155ee72599b8602f

See more details on using hashes here.

File details

Details for the file blspy-0.2.4-cp38-cp38-manylinux2014_aarch64.whl.

File metadata

  • Download URL: blspy-0.2.4-cp38-cp38-manylinux2014_aarch64.whl
  • Upload date:
  • Size: 690.0 kB
  • Tags: CPython 3.8
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/44.0.0 requests-toolbelt/0.9.1 tqdm/4.50.2 CPython/3.8.5

File hashes

Hashes for blspy-0.2.4-cp38-cp38-manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 83cb182a2d154ab815aaa14e174c2eae3bc93587aab220bd047baaec59186b53
MD5 bd24a2a7e8606c880b50411f99bdbfa0
BLAKE2b-256 8fb4c33f8f00a7b431f2dd471a19258256d463a5b93bcb64646dd8f980288ba0

See more details on using hashes here.

File details

Details for the file blspy-0.2.4-cp38-cp38-manylinux2010_x86_64.whl.

File metadata

  • Download URL: blspy-0.2.4-cp38-cp38-manylinux2010_x86_64.whl
  • Upload date:
  • Size: 791.1 kB
  • Tags: CPython 3.8, manylinux: glibc 2.12+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.50.2 CPython/3.7.9

File hashes

Hashes for blspy-0.2.4-cp38-cp38-manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 eb592d177370518d700ccbd7691ee5cac0d482f0236041e9704f1c657dc9ef19
MD5 e04a645fb09b7d2d8b1e1a53d3a4cdf0
BLAKE2b-256 8cd7e044a0542f51d1d6494b241d6f1a2df35e513ba4f15234c3d5833063c847

See more details on using hashes here.

File details

Details for the file blspy-0.2.4-cp38-cp38-macosx_10_14_x86_64.whl.

File metadata

  • Download URL: blspy-0.2.4-cp38-cp38-macosx_10_14_x86_64.whl
  • Upload date:
  • Size: 642.4 kB
  • Tags: CPython 3.8, macOS 10.14+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.50.2 CPython/3.7.9

File hashes

Hashes for blspy-0.2.4-cp38-cp38-macosx_10_14_x86_64.whl
Algorithm Hash digest
SHA256 0eb7064a1711369fa51299dbf656e3bf97e8e43a07290689263cc0d728cf7fff
MD5 af26831ba3374aa6f2c13e226ba28241
BLAKE2b-256 bf99da1300a6cbff441d6b8f2eeadb87c0ecf9751cfcf0dc01a7259f2dd576c3

See more details on using hashes here.

File details

Details for the file blspy-0.2.4-cp37-cp37m-win_amd64.whl.

File metadata

  • Download URL: blspy-0.2.4-cp37-cp37m-win_amd64.whl
  • Upload date:
  • Size: 2.0 MB
  • Tags: CPython 3.7m, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.50.2 CPython/3.7.9

File hashes

Hashes for blspy-0.2.4-cp37-cp37m-win_amd64.whl
Algorithm Hash digest
SHA256 f3f5b3f026ad670d79054c6675a695924da7506cc711d5201609b4c74f8cf53e
MD5 d87e0ec22bde903e44a096bae8b52e21
BLAKE2b-256 33a49faa47061c92c2fcef032704d1b630f35942af8fa3a542b3f4ab8c6537e8

See more details on using hashes here.

File details

Details for the file blspy-0.2.4-cp37-cp37m-manylinux2014_aarch64.whl.

File metadata

  • Download URL: blspy-0.2.4-cp37-cp37m-manylinux2014_aarch64.whl
  • Upload date:
  • Size: 694.6 kB
  • Tags: CPython 3.7m
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/44.0.0 requests-toolbelt/0.9.1 tqdm/4.50.2 CPython/3.8.5

File hashes

Hashes for blspy-0.2.4-cp37-cp37m-manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 0af3ce762d0a10ff4698915560704dcdf38922fde40829df3432d974161f0a90
MD5 07c726dc738c9f64091b31da0323fb0a
BLAKE2b-256 232afbb7e30026362097069b753620af5093f5bec807b350b9cd8dbc02abf287

See more details on using hashes here.

File details

Details for the file blspy-0.2.4-cp37-cp37m-manylinux2010_x86_64.whl.

File metadata

  • Download URL: blspy-0.2.4-cp37-cp37m-manylinux2010_x86_64.whl
  • Upload date:
  • Size: 791.4 kB
  • Tags: CPython 3.7m, manylinux: glibc 2.12+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.50.2 CPython/3.7.9

File hashes

Hashes for blspy-0.2.4-cp37-cp37m-manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 85f89f0f29e649a4ac3cb277493149f0013c51007cbe92925a1c41e178d9e569
MD5 393887a04ec9aee0e44ba3cc1f997e02
BLAKE2b-256 7a1a8bda6ff8714dd992b1d51a07c4e5f7cbece52db3f3c025d5fbfb9d9c2b78

See more details on using hashes here.

File details

Details for the file blspy-0.2.4-cp37-cp37m-macosx_10_14_x86_64.whl.

File metadata

  • Download URL: blspy-0.2.4-cp37-cp37m-macosx_10_14_x86_64.whl
  • Upload date:
  • Size: 636.8 kB
  • Tags: CPython 3.7m, macOS 10.14+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.50.2 CPython/3.7.9

File hashes

Hashes for blspy-0.2.4-cp37-cp37m-macosx_10_14_x86_64.whl
Algorithm Hash digest
SHA256 d1a235ad71432ae2808d41d162741a1c0f306f2f9fe596532eb41a56a17e8fae
MD5 c860de78c8109f218877e1e07a735c0b
BLAKE2b-256 c1efef8a18ee4395946e8362160c1fd7233697e2f5637eb4ac897ae8a1cad492

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page