• Stars
    star
    295
  • Rank 140,902 (Top 3 %)
  • Language
    C++
  • License
    Apache License 2.0
  • Created over 6 years ago
  • Updated 2 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

BLS signatures in C++, using the blst library for BLS12-381

BLS Signatures implementation

Build and Test C++, Javascript, and Python PyPI PyPI - Format GitHub

CodeQL

Coverage Status

NOTE: THIS LIBRARY IS NOT YET FORMALLY REVIEWED FOR SECURITY

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

Implements BLS signatures with aggregation using blst library 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

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/src -L./bls-signatures/build/ -l bls yourapp.cpp

Notes on dependencies

We use Libsodium which provides secure memory allocation. To install it, 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. MacOS ARM64 is supported but not automated due to a lack of M1 CI runners. 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 a statically linked libsodium.

Contributing and workflow

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

The main 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 main/release version in preparation for a new chia-blockchain release. Please branch or fork main and then create a pull request to the main branch. Linear merging is enforced on main 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.

BLST license

BLST is used with the Apache 2.0 license

More Repositories

1

chia-blockchain

Chia blockchain python implementation (full node, farmer, harvester, timelord, and wallet)
Python
10,831
star
2

pool-reference

Reference python implementation of Chia pool operations for pool operators
Python
439
star
3

bladebit

A high-performance k32-only, Chia (XCH) plotter supporting in-RAM and disk-based plotting
C
336
star
4

chia-blockchain-gui

Chia blockchain GUI in electron/react
TypeScript
332
star
5

chiapos

Chia Proof of Space library
HTML
267
star
6

chia-docker

Shell
213
star
7

website

Old Corporate web site
HTML
153
star
8

clvm

[Contract Language|Chia Lisp] Virtual Machine
Python
86
star
9

oldvdf-competition

VDF competition instructions, and simple implementation
Python
86
star
10

chia-network.github.io

The Current Chia Network website
HTML
75
star
11

clvm_rs

Rust implementation of clvm
Rust
67
star
12

chialisp-web

A docusaurus Chialisp website
JavaScript
67
star
13

drplotter

64
star
14

chiavdf

Chia VDF utilities
C++
60
star
15

clvm_tools

Tools for clvm development
Python
51
star
16

chia-dev-tools

A utility for developing in the Chia ecosystem: Chialisp functions, object inspection, RPC client and more.
Python
45
star
17

chips

JavaScript
45
star
18

chia-exporter

RPC/Websocket based metrics exporter for Chia
Go
39
star
19

cadt

Climate Action Data Trust
JavaScript
35
star
20

chia-gaming

OCaml
30
star
21

vdf-competition

Python
25
star
22

chia-docs

Chia Docs - documentation on the Chia blockchain, protocol and client
JavaScript
20
star
23

chia_rs

Rust crate & wheel with consensus code
Rust
19
star
24

CAT-admin-tool

Admin tool for issuing CATs
Python
18
star
25

proofofspace

HTML
15
star
26

go-chia-libs

Go
15
star
27

cadt-ui

Climate Action Data Trust User Interface
TypeScript
15
star
28

keybase-live-feed

JavaScript
14
star
29

post-mortem

This repo holds chia public post mortem records.
12
star
30

internal-custody

Smart coins to secure funds with M of N signature thresholds, re-keying, clawbacks, and timelock spends
Python
12
star
31

node-clvm-lib

A browser friendly implementation of clvm in TypeScript.
TypeScript
12
star
32

chia-dev-guides

Chia Dev Guides - tutorials for developers building on the Chia blockchain
JavaScript
12
star
33

clvm_tools_rs

clvm_tools ported to rust based on https://github.com/Chia-Mine/clvm_tools-js/, and chialisp-21 dialect with a new compiler.
Rust
11
star
34

chia-nft-minting-tool

Bulk Minting tool for NFTs
Python
9
star
35

hsms

HSMS: hardware security module software/simulator
Python
8
star
36

offline-signing-demo

Python
8
star
37

vdftrack1results

Track 1 results for Chia's VDF competition
C
8
star
38

node-chia-bls

A browser friendly implementation of bls-signatures in TypeScript.
TypeScript
8
star
39

vscode-chialisp-lsp

A Chialisp LSP client for Visual Studio Code
Rust
7
star
40

carbon-asset-token

carbon asset token project
JavaScript
7
star
41

mozilla-ca

6
star
42

chialinks

HTML
6
star
43

chia-wallet-connect-dapp-test

dApplication for wallet connect testing
TypeScript
6
star
44

node-chia-wallet-lib

Unofficial implementations for standard puzzles and the wallet for Chia
TypeScript
4
star
45

walletconnect-rpcs-dapp

An example dApp for testing Chia WalletConnect commands.
TypeScript
3
star
46

ledger_sim

Python
3
star
47

node-chia-rpc

An implementation of Chia RPC calls in TypeScript.
TypeScript
3
star
48

vdftrack2results

Track 2 results for Chia's VDF competition
C++
3
star
49

Climate-Wallet

Climate Wallet that integrates with the Chia Wallet
JavaScript
3
star
50

chia-simulator-docker

Docker Containers for a One-click Chiaโ„ข Simulator Setup.
Dockerfile
3
star
51

pub-metrics-grafana

Jinja
3
star
52

build-images

Docker images used for the release pipelines
Dockerfile
2
star
53

chia-operator

A Kubernetes operator for Chia
Go
2
star
54

helm-charts

Smarty
2
star
55

dev-community-meetings

2
star
56

actions

TypeScript
2
star
57

terraform-modules

common modules for chia terraform these modules are intended to be inherited by downstream projects
HCL
2
star
58

Climate-Tokenization-Engine

JavaScript
2
star
59

ansible-roles

Jinja
2
star
60

chia-toolbox

Tools
Python
2
star
61

chia-clawback-primitive

A developer primitive for clawbacks on the Chia Blockchain
Python
2
star
62

chiabip158

Chia's implementation of BIP 158 - https://github.com/bitcoin/bips/blob/master/bip-0158.mediawiki
C++
2
star
63

chialisp-crash-course

TypeScript
2
star
64

proofofspaceresults

C++
1
star
65

ecosystem-activity

Go
1
star
66

core-registry-ui

Unified user interface for the carbon Core Registry suite
JavaScript
1
star
67

vdfcontest2results

C++
1
star
68

go-modules

Go
1
star
69

public_bluebox_image

Generate an AWS AMI for public use
HCL
1
star
70

climate-token-driver

Provides three types of functionality for carbon tokenization
Python
1
star
71

chia-healthcheck

A simple healthcheck for Chia components - support being added to new Chia components over time
Go
1
star
72

climate-explorer-ui

User Interface for Climate Explorer
JavaScript
1
star
73

CAT-addresses

Tool that discovers all CAT addresses
Python
1
star
74

coin-tracing-scripts

Python
1
star
75

Climate-Tokenization-Engine-UI

Create tokenized carbon units on the blockchain
JavaScript
1
star
76

mysqlpunch

A small CLI tool for slamming a table in mysql with records to see how it reacts to load
Go
1
star
77

MonsterSprouts

TypeScript
1
star