Skip to main content

BLS signatures in c++ (python bindings)

This project has been archived.

The maintainers of this project have marked this project as archived. No new releases are expected.

Project description

Build PyPI PyPI - Format GitHub

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

BLS Signatures implementation

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

Implements BLS signatures with aggregation as in Boneh, Drijvers, Neven 2018 , using relic toolkit for cryptographic primitives (pairings, EC, hashing). The BLS12-381 curve is used. The original spec is here. This library now implements IETF BLS RFC.

Features:

  • Non-interactive signature aggregation on identical or distinct messages
  • Aggregate aggregates (trees)
  • Efficient verification (only one pairing per distinct message)
  • Security against rogue public key attack, using aggregation info, or proof of possession
  • Aggregate public keys and private keys
  • M/N threshold keys and signatures using Joint-Feldman scheme
  • HD (BIP32) key derivation
  • Key and signature serialization
  • Batch verification
  • Signature division (divide an aggregate by a previously verified signature)
  • JavaScript bindings
  • Python bindings
  • Pure python bls12-381 and signatures

Import the library

#include "bls.hpp"

Creating keys and signatures

// Example seed, used to generate private key. Always use
// a secure RNG with sufficient entropy to generate a seed.
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};

bls::PrivateKey sk = bls::PrivateKey::FromSeed(seed, sizeof(seed));
bls::PublicKey pk = sk.GetPublicKey();

uint8_t msg[] = {100, 2, 254, 88, 90, 45, 23};

bls::Signature sig = sk.Sign(msg, sizeof(msg));

Serializing keys and signatures to bytes

uint8_t skBytes[bls::PrivateKey::PRIVATE_KEY_SIZE];  // 32 byte array
uint8_t pkBytes[bls::PublicKey::PUBLIC_KEY_SIZE];    // 48 byte array
uint8_t sigBytes[bls::Signature::SIGNATURE_SIZE];    // 96 byte array

sk.Serialize(skBytes);   // 32 bytes
pk.Serialize(pkBytes);   // 48 bytes
sig.Serialize(sigBytes); // 96 bytes

Loading keys and signatures from bytes

// Takes array of 32 bytes
sk = bls::PrivateKey::FromBytes(skBytes);

// Takes array of 48 bytes
pk = bls::PublicKey::FromBytes(pkBytes);

// Takes array of 96 bytes
sig = bls::Signature::FromBytes(sigBytes);

Verifying signatures

// Add information required for verification, to sig object
sig.SetAggregationInfo(bls::AggregationInfo::FromMsg(pk, msg, sizeof(msg)));

bool ok = sig.Verify();

Aggregate signatures for a single message

// Generate some more private keys
seed[0] = 1;
bls::PrivateKey sk1 = bls::PrivateKey::FromSeed(seed, sizeof(seed));
seed[0] = 2;
bls::PrivateKey sk2 = bls::PrivateKey::FromSeed(seed, sizeof(seed));

// Generate first sig
bls::PublicKey pk1 = sk1.GetPublicKey();
bls::Signature sig1 = sk1.Sign(msg, sizeof(msg));

// Generate second sig
bls::PublicKey pk2 = sk2.GetPublicKey();
bls::Signature sig2 = sk2.Sign(msg, sizeof(msg));

// Aggregate signatures together
vector<bls::Signature> sigs = {sig1, sig2};
bls::Signature aggSig = bls::Signature::Aggregate(sigs);

// For same message, public keys can be aggregated into one.
// The signature can be verified the same as a single signature,
// using this public key.
vector<bls::PublicKey> pubKeys = {pk1, pk2};
bls::PublicKey aggPubKey = bls::Signature::Aggregate(pubKeys);

Aggregate signatures for different messages

// Generate one more key and message
seed[0] = 3;
bls::PrivateKey sk3 = bls::PrivateKey::FromSeed(seed, sizeof(seed));
bls::PublicKey pk3 = sk3.GetPublicKey();
uint8_t msg2[] = {100, 2, 254, 88, 90, 45, 23};

// Generate the signatures, assuming we have 3 private keys
sig1 = sk1.Sign(msg, sizeof(msg));
sig2 = sk2.Sign(msg, sizeof(msg));
bls::Signature sig3 = sk3.Sign(msg2, sizeof(msg2));

// They can be noninteractively combined by anyone
// Aggregation below can also be done by the verifier, to
// make batch verification more efficient
vector<bls::Signature> sigsL = {sig1, sig2};
bls::Signature aggSigL = bls::Signature::Aggregate(sigsL);

// Arbitrary trees of aggregates
vector<bls::Signature> sigsFinal = {aggSigL, sig3};
bls::Signature aggSigFinal = bls::Signature::Aggregate(sigsFinal);

// Serialize the final signature
aggSigFinal.Serialize(sigBytes);

Verify aggregate signature for different messages

// Deserialize aggregate signature
aggSigFinal = bls::Signature::FromBytes(sigBytes);

// Create aggregation information (or deserialize it)
bls::AggregationInfo a1 = bls::AggregationInfo::FromMsg(pk1, msg, sizeof(msg));
bls::AggregationInfo a2 = bls::AggregationInfo::FromMsg(pk2, msg, sizeof(msg));
bls::AggregationInfo a3 = bls::AggregationInfo::FromMsg(pk3, msg2, sizeof(msg2));
vector<bls::AggregationInfo> infos = {a1, a2};
bls::AggregationInfo a1a2 = bls::AggregationInfo::MergeInfos(infos);
vector<bls::AggregationInfo> infos2 = {a1a2, a3};
bls::AggregationInfo aFinal = bls::AggregationInfo::MergeInfos(infos2);

// Verify final signature using the aggregation info
aggSigFinal.SetAggregationInfo(aFinal);
ok = aggSigFinal.Verify();

// If you previously verified a signature, you can also divide
// the aggregate signature by the signature you already verified.
ok = aggSigL.Verify();
vector<bls::Signature> cache = {aggSigL};
aggSigFinal = aggSigFinal.DivideBy(cache);

// Final verification is now more efficient
ok = aggSigFinal.Verify();

Aggregate private keys

vector<bls::PrivateKey> privateKeysList = {sk1, sk2};
vector<bls::PublicKey> pubKeysList = {pk1, pk2};

// Create an aggregate private key, that can generate
// aggregate signatures
const bls::PrivateKey aggSk = bls::PrivateKey::Aggregate(
        privateKeys, pubKeys);

bls::Signature aggSig3 = aggSk.Sign(msg, sizeof(msg));

HD keys

// Random seed, used to generate master extended private key
uint8_t seed[] = {1, 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};

bls::ExtendedPrivateKey esk = bls::ExtendedPrivateKey::FromSeed(
        seed, sizeof(seed));

bls::ExtendedPublicKey epk = esk.GetExtendedPublicKey();

// Use i >= 2^31 for hardened keys
bls::ExtendedPrivateKey skChild = esk.PrivateChild(0)
                                .PrivateChild(5);

bls::ExtendedPublicKey pkChild = epk.PublicChild(0)
                               .PublicChild(5);

// Serialize extended keys
uint8_t buffer1[bls::ExtendedPublicKey::EXTENDED_PUBLIC_KEY_SIZE];   // 93 bytes
uint8_t buffer2[bls::ExtendedPrivateKey::EXTENDED_PRIVATE_KEY_SIZE]; // 77 bytes

pkChild.Serialize(buffer1);
skChild.Serialize(buffer2);

Prepend PK method

// Can use proofs of possession to avoid keeping track of metadata
PrependSignature prepend1 = sk1.SignPrepend(msg, sizeof(msg));
PrependSignature prepend2 = sk2.SignPrepend(msg, sizeof(msg));

std::vector<PublicKey> prependPubKeys = {pk1, pk2};
uint8_t messageHash[BLS::MESSAGE_HASH_LEN];
Util::Hash256(messageHash, msg, sizeof(msg));
std::vector<const uint8_t*> hashes = {messageHash, messageHash};

std::vector<PrependSignature> prependSigs = {prepend1, prepend2};
PrependSignature prependAgg = PrependSignature::Aggregate(prependSigs);

prependAgg.Verify(hashes, prependPubKeys);

Build

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

git submodule update --init --recursive

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

Run tests

./build/src/runtest

Run benchmarks

./build/src/runbench

Link the library to use it

g++ -Wl,-no_pie  -Ibls-signatures/contrib/relic/include -Ibls-signatures/build/contrib/relic/incl
ude -Ibls-signatures/src/  -L./bls-signatures/build/ -l bls  yourfile.cpp

Notes on dependencies

Changes performed to relic: Added config files for Chia, and added gmp include in relic.h, new ep_map and ep2_map, new ep_pck and ep2_pck. Custom inversion function. Note: relic is used with the Apache 2.0 license.

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.

Discussion

Discussion about this library and other Chia related development is on Keybase. Install Keybase, and run the following to join the Chia public channels:

keybase team request-access chia_network.public

Code style

  • Always use 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

There are three types of signatures: InsecureSignatures (simple signatures which are not secure by themselves, due to rogue public keys), Signatures (secure signatures that require AggregationInfo to aggregate), and PrependSignatures, which prepend public keys to messages, making them secure.

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. 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 specification and test vectors can be found here. Test vectors can also be seen in the python or cpp test files.

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.2b14.tar.gz (240.2 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

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

Uploaded CPython 3.8Windows x86-64

blspy-0.2b14-cp38-cp38-manylinux2014_aarch64.whl (367.5 kB view details)

Uploaded CPython 3.8

blspy-0.2b14-cp38-cp38-manylinux2010_x86_64.whl (382.0 kB view details)

Uploaded CPython 3.8manylinux: glibc 2.12+ x86-64

blspy-0.2b14-cp38-cp38-macosx_10_14_x86_64.whl (534.1 kB view details)

Uploaded CPython 3.8macOS 10.14+ x86-64

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

Uploaded CPython 3.7mWindows x86-64

blspy-0.2b14-cp37-cp37m-manylinux2010_x86_64.whl (382.7 kB view details)

Uploaded CPython 3.7mmanylinux: glibc 2.12+ x86-64

blspy-0.2b14-cp37-cp37m-macosx_10_14_x86_64.whl (529.3 kB view details)

Uploaded CPython 3.7mmacOS 10.14+ x86-64

File details

Details for the file blspy-0.2b14.tar.gz.

File metadata

  • Download URL: blspy-0.2b14.tar.gz
  • Upload date:
  • Size: 240.2 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.47.0 CPython/3.7.8

File hashes

Hashes for blspy-0.2b14.tar.gz
Algorithm Hash digest
SHA256 8d89b5bdaf7769093c9c8633dc38d44740d47f6c554af2479570cc1cdeee4eb7
MD5 1e7ba965f5f2916b379b41e6fa5051b1
BLAKE2b-256 793f54822958c3d62df84a33511c8ed6f833ca8a02b983907916482ba82c3caf

See more details on using hashes here.

File details

Details for the file blspy-0.2b14-cp38-cp38-win_amd64.whl.

File metadata

  • Download URL: blspy-0.2b14-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.47.0 CPython/3.7.8

File hashes

Hashes for blspy-0.2b14-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 151db644c6f1574799ebceae3ea3cb6445f4a5a3343f6d44a1595a8c5a51c20c
MD5 0d9926d3935aa27901e894314fc3b284
BLAKE2b-256 2b30c2ecac184d42352b701608819163dece7609d2fd2441903ec2144b94ac3c

See more details on using hashes here.

File details

Details for the file blspy-0.2b14-cp38-cp38-manylinux2014_aarch64.whl.

File metadata

  • Download URL: blspy-0.2b14-cp38-cp38-manylinux2014_aarch64.whl
  • Upload date:
  • Size: 367.5 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.47.0 CPython/3.8.2

File hashes

Hashes for blspy-0.2b14-cp38-cp38-manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 dcb5dbdd7b6c47b9e93e137058d6528350b9757c7079899bfb237e5f741a8467
MD5 d0c3b1c746b22d2dfff71b032e7c69fb
BLAKE2b-256 a4dffd904a09c1fe41fe9bcfb456961335f56d1cc5ef16593b290f5eb3ab64a8

See more details on using hashes here.

File details

Details for the file blspy-0.2b14-cp38-cp38-manylinux2010_x86_64.whl.

File metadata

  • Download URL: blspy-0.2b14-cp38-cp38-manylinux2010_x86_64.whl
  • Upload date:
  • Size: 382.0 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/41.2.0 requests-toolbelt/0.9.1 tqdm/4.47.0 CPython/3.7.7

File hashes

Hashes for blspy-0.2b14-cp38-cp38-manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 bd5f289b7cf58c973f648fe3e93a168cbfdccfa0dce0fb7535d43473d8801fc9
MD5 588cd17777cb8a3ad9e19bb44867f3a2
BLAKE2b-256 066859028c8268528f2f5008e4c13d58620ffb89a709f00ae086e424e588b0a4

See more details on using hashes here.

File details

Details for the file blspy-0.2b14-cp38-cp38-macosx_10_14_x86_64.whl.

File metadata

  • Download URL: blspy-0.2b14-cp38-cp38-macosx_10_14_x86_64.whl
  • Upload date:
  • Size: 534.1 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.47.0 CPython/3.7.8

File hashes

Hashes for blspy-0.2b14-cp38-cp38-macosx_10_14_x86_64.whl
Algorithm Hash digest
SHA256 bbd780b61693515ec79e699fe5f344c005352ba2cf8394bc6f3f2fd2bd3b4c6b
MD5 e2148ceb2b463f6b301b30c65ed4f55f
BLAKE2b-256 43d9a89534d34355f1959d3e9e091543617c66a8657838584b57e02c09839306

See more details on using hashes here.

File details

Details for the file blspy-0.2b14-cp37-cp37m-win_amd64.whl.

File metadata

  • Download URL: blspy-0.2b14-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.47.0 CPython/3.7.8

File hashes

Hashes for blspy-0.2b14-cp37-cp37m-win_amd64.whl
Algorithm Hash digest
SHA256 a85619dc895a94127a7bfd6871cf15ae2876dad15f994a1b60b9d946d1f103e2
MD5 456f703b51e60c65defc49cfa1e38e10
BLAKE2b-256 774f0e6ea81ed36a80bb3b5552d23689cb8e92a668212da4f72eae4386a52a85

See more details on using hashes here.

File details

Details for the file blspy-0.2b14-cp37-cp37m-manylinux2010_x86_64.whl.

File metadata

  • Download URL: blspy-0.2b14-cp37-cp37m-manylinux2010_x86_64.whl
  • Upload date:
  • Size: 382.7 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/41.2.0 requests-toolbelt/0.9.1 tqdm/4.47.0 CPython/3.7.7

File hashes

Hashes for blspy-0.2b14-cp37-cp37m-manylinux2010_x86_64.whl
Algorithm Hash digest
SHA256 5baee9cd02a19e4b2c4e0270767a99a4ef1fba40a9d1687043a3eed09253411b
MD5 d6584007fe5174f60f7b66ab101374f0
BLAKE2b-256 fc19f87373bd5cc12a17262438aab3e8903c1271c99a726edee85323d15c42f3

See more details on using hashes here.

File details

Details for the file blspy-0.2b14-cp37-cp37m-macosx_10_14_x86_64.whl.

File metadata

  • Download URL: blspy-0.2b14-cp37-cp37m-macosx_10_14_x86_64.whl
  • Upload date:
  • Size: 529.3 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.47.0 CPython/3.7.8

File hashes

Hashes for blspy-0.2b14-cp37-cp37m-macosx_10_14_x86_64.whl
Algorithm Hash digest
SHA256 fe46e849ee15fe4b3fe877fcffcf870965f3f1cb3c11f46fb3cadb05876ec9ad
MD5 c1c9018069c875eb4c8a18a9e1a84bde
BLAKE2b-256 ba0eabd3e5abb3dc816f3ab221a6878ad4cb846ba1b2de6a54fd771e4c931ec3

See more details on using hashes here.

Supported by

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