All Projects → paulmillr → Noble Bls12 381

paulmillr / Noble Bls12 381

Licence: mit
Fastest implementation of BLS12-381 in a scripting language. High-security, auditable, 0-dependency aggregated signatures / zk-snarks over pairing-friendly curve

Programming Languages

typescript
32286 projects

Projects that are alternatives of or similar to Noble Bls12 381

Cryptocurrency Dashboard
Crypto Currency Dashboard Using Twitter 🐦 And Coinmarketcap 🚀 API
Stars: ✭ 54 (-26.03%)
Mutual labels:  crypto
Core Geth
A highly configurable Go implementation of the Ethereum protocol.
Stars: ✭ 66 (-9.59%)
Mutual labels:  crypto
Random Bytes Readable Stream
Creates a readable stream producing cryptographically strong pseudo-random data using `crypto.randomBytes()`
Stars: ✭ 71 (-2.74%)
Mutual labels:  crypto
Crypto Trading Bot
Cryptocurrency trading bot in javascript for Bitfinex, Bitmex, Binance, FTX, Bybit ... (public edition)
Stars: ✭ 1,089 (+1391.78%)
Mutual labels:  crypto
Curve Fit
Curve-Fit is an Android library for drawing curves on Google Maps
Stars: ✭ 63 (-13.7%)
Mutual labels:  curve
Covenantsql
A decentralized, trusted, high performance, SQL database with blockchain features
Stars: ✭ 1,148 (+1472.6%)
Mutual labels:  crypto
Cryptex
Gemini, GDAX, Bitfinex, Poloniex, Binance, Kraken, Cryptopia, Koinex, BitGrail and CoinMarketCap cryptocurrency exchange API clients in Swift / iOS SDK. Check prices and account balances using Sample iOS app.
Stars: ✭ 51 (-30.14%)
Mutual labels:  crypto
I2p.i2p
I2P is an anonymizing network, offering a simple layer that identity-sensitive applications can use to securely communicate. All data is wrapped with several layers of encryption, and the network is both distributed and dynamic, with no trusted parties.
Stars: ✭ 1,186 (+1524.66%)
Mutual labels:  crypto
Fhe Toolkit Linux
IBM Fully Homomorphic Encryption Toolkit For Linux. This toolkit is a Linux based Docker container that demonstrates computing on encrypted data without decrypting it! The toolkit ships with two demos including a fully encrypted Machine Learning inference with a Neural Network and a Privacy-Preserving key-value search.
Stars: ✭ 1,123 (+1438.36%)
Mutual labels:  crypto
Crycompare
Python wrapper for CryptoCompare public API
Stars: ✭ 70 (-4.11%)
Mutual labels:  crypto
Minisign
A dead simple tool to sign files and verify digital signatures.
Stars: ✭ 1,105 (+1413.7%)
Mutual labels:  crypto
The Journal Of Blockchain
区块链自媒体、专注区块链技术学习和实践、IPFS/Filecoin、Bitcoin、Ethereum、EOS、Cosmos、区块链、白皮书、Coinmarketcap、Coindesk、Safe Network、Telegram、Docker、社会治理、经济激励
Stars: ✭ 63 (-13.7%)
Mutual labels:  crypto
Crypto Bench
Benchmarks for crypto libraries (in Rust, or with Rust bindings)
Stars: ✭ 67 (-8.22%)
Mutual labels:  crypto
Cryptohelper
Standalone password hasher for ASP.NET Core using a PBKDF2 implementation.
Stars: ✭ 58 (-20.55%)
Mutual labels:  crypto
Cava
ConsenSys core libraries for Java & Kotlin
Stars: ✭ 71 (-2.74%)
Mutual labels:  crypto
Jesse
An advanced crypto trading bot written in Python
Stars: ✭ 1,038 (+1321.92%)
Mutual labels:  crypto
Crypto Es
A cryptography algorithms library
Stars: ✭ 65 (-10.96%)
Mutual labels:  crypto
Zbox
Zero-details, privacy-focused in-app file system.
Stars: ✭ 1,185 (+1523.29%)
Mutual labels:  crypto
Tweetnacl Js
Port of TweetNaCl cryptographic library to JavaScript
Stars: ✭ 1,176 (+1510.96%)
Mutual labels:  crypto
Encryptlab
A Free and Comprehensive Encrypt and Decrypt Tools Website with example code in Node.js, Website is looking for a new server.
Stars: ✭ 69 (-5.48%)
Mutual labels:  crypto

noble-bls12-381 Node CI code style: prettier

Fastest implementation of BLS12-381 in a scripting language. The pairing-friendly Barreto-Lynn-Scott elliptic curve construction allows to:

  • Construct zk-SNARKs at the 128-bit security
  • Use threshold signatures, which allows a user to sign lots of messages with one signature and verify them swiftly in a batch, using Boneh-Lynn-Shacham signature scheme.

Matches specs pairing-curves-09, bls-sigs-04, hash-to-curve-10. To learn more about internals, check out BLS12-381 for the rest of us & key concepts of pairings. To try it live, see the online demo & threshold sigs demo.

This library belongs to noble crypto

noble-crypto — high-security, easily auditable set of contained cryptographic libraries and tools.

  • Just two files
  • No dependencies
  • Easily auditable TypeScript/JS code
  • Supported in all major browsers and stable node.js versions
  • All releases are signed with PGP keys
  • Check out all libraries: secp256k1, ed25519, bls12-381, ripemd160

Usage

Node.js and browser:

npm install noble-bls12-381

const bls = require('noble-bls12-381');

// You can use Uint8Array, or hex string for readability
const privateKey = '67d53f170b908cabb9eb326c3c337762d59289a8fec79f7bc9254b584b73265c';
const privateKeys = [
  '18f020b98eb798752a50ed0563b079c125b0db5dd0b1060d1c1b47d4a193e1e4',
  'ed69a8c50cf8c9836be3b67c7eeff416612d45ba39a5c099d48fa668bf558c9c',
  '16ae669f3be7a2121e17d0c68c05a8f3d6bef21ec0f2315f1d7aec12484e4cf5'
];
const message = '64726e3da8';
const messages = ['d2', '0d98', '05caf3'];

(async () => {
  const publicKey = bls.getPublicKey(privateKey);
  const publicKeys = privateKeys.map(bls.getPublicKey);

  const signature = await bls.sign(message, privateKey);
  const isCorrect = await bls.verify(signature, message, publicKey);
  console.log('key', publicKey);
  console.log('signature', signature);
  console.log('is correct:', isCorrect);

  // Sign 1 msg with 3 keys
  const signatures2 = await Promise.all(privateKeys.map(p => bls.sign(message, p)));
  const aggPubKey2 = bls.aggregatePublicKeys(publicKeys);
  const aggSignature2 = bls.aggregateSignatures(signatures2);
  const isCorrect2 = await bls.verify(aggSignature2, message, aggPubKey2);
  console.log();
  console.log('signatures are', signatures2);
  console.log('merged to one signature', aggSignature2);
  console.log('is correct:', isCorrect2);

  // Sign 3 msgs with 3 keys
  const signatures3 = await Promise.all(privateKeys.map((p, i) => bls.sign(messages[i], p)));
  const aggSignature3 = bls.aggregateSignatures(signatures3);
  const isCorrect3 = await bls.verifyBatch(aggSignature3, messages, publicKeys);
  console.log();
  console.log('keys', publicKeys);
  console.log('signatures', signatures3);
  console.log('merged to one signature', aggSignature3);
  console.log('is correct:', isCorrect3);
})();

API

getPublicKey(privateKey)
function getPublicKey(privateKey: Uint8Array | bigint): Uint8Array;
function getPublicKey(privateKey: string): string;
  • privateKey: Uint8Array | string | bigint will be used to generate public key. Public key is generated by executing scalar multiplication of a base Point(x, y) by a fixed integer. The result is another Point(x, y) which we will by default encode to hex Uint8Array.
  • Returns Uint8Array: encoded publicKey for signature verification

Note: if you need spec-based KeyGen, use paulmillr/bls12-381-keygen. It should work properly with ETH2 and FIL keys.

sign(message, privateKey)
function sign(
  message: Uint8Array,
  privateKey: Uint8Array
): Promise<Uint8Array>;
function sign(
  message: string,
  privateKey: string
): Promise<string>;
function sign(
  message: PointG2,
  privateKey: Uint8Array | string | bigint
): Promise<PointG2>;
  • message: Uint8Array | string - message which would be hashed & signed
  • privateKey: Uint8Array | string | bigint - private key which will sign the hash
  • Returns Uint8Array | string | PointG2: encoded signature

Default domain (DST) is BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_, use bls.DST to change it.

verify(signature, message, publicKey)
function verify(
  signature: Uint8Array | string | PointG2,
  message: Uint8Array | string | PointG2,
  publicKey: Uint8Array | string | PointG1
): Promise<boolean>
  • signature: Uint8Array | string - object returned by the sign or aggregateSignatures function
  • message: Uint8Array | string - message hash that needs to be verified
  • publicKey: Uint8Array | string - e.g. that was generated from privateKey by getPublicKey
  • Returns Promise<boolean>: true / false whether the signature matches hash
aggregatePublicKeys(publicKeys)
function aggregatePublicKeys(publicKeys: Uint8Array[]): Uint8Array;
function aggregatePublicKeys(publicKeys: string[]): string;
function aggregatePublicKeys(publicKeys: PointG1[]): PointG1;
  • publicKeys: (Uint8Array | string | PointG1)[] - e.g. that have been generated from privateKey by getPublicKey
  • Returns Uint8Array | PointG1: one aggregated public key which calculated from public keys
aggregateSignatures(signatures)
function aggregateSignatures(signatures: Uint8Array[]): Uint8Array;
function aggregateSignatures(signatures: string[]): string;
function aggregateSignatures(signatures: PointG2[]): PointG2;
  • signatures: (Uint8Array | string | PointG2)[] - e.g. that have been generated by sign
  • Returns Uint8Array | PointG2: one aggregated signature which calculated from signatures
verifyBatch(signature, messages, publicKeys)
function verifyBatch(
  signature: Uint8Array | string | PointG2,
  messages: (Uint8Array | string | PointG2)[],
  publicKeys: (Uint8Array | string | PointG1)[]
): Promise<boolean>
  • signature: Uint8Array | string | PointG2 - object returned by the aggregateSignatures function
  • messages: (Uint8Array | string | PointG2)[] - messages hashes that needs to be verified
  • publicKeys: (Uint8Array | string | PointG1)[] - e.g. that were generated from privateKeys by getPublicKey
  • Returns Promise<boolean>: true / false whether the signature matches hashes
pairing(G1Point, G2Point)
function pairing(
  g1Point: PointG1,
  g2Point: PointG2,
  withFinalExponent: boolean = true
): Fq12
  • g1Point: PointG1 - simple point, x, y are bigints
  • g2Point: PointG2 - point over curve with imaginary numbers ((x, x_1), (y, y_1))
  • withFinalExponent: boolean - should the result be powered by curve order. Very slow.
  • Returns Fq12: paired point over 12-degree extension field.
Helpers
// 𝔽p
bls.CURVE.P // 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaabn

// Prime order
bls.CURVE.r // 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001n

// Hash base point (x, y)
bls.CURVE.Gx // 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001n
// x = 3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507
// y = 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569

// Signature base point ((x_1, x_2), (y_1, y_2))
bls.CURVE.Gy
// x = 3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758, 352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160
// y = 927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582, 1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905

// Classes
bls.Fq
bls.Fq2
bls.Fq12
bls.G1Point
bls.G2Point

Internals

The library uses G1 for public keys and G2 for signatures. Adding support for G1 signatures is planned.

  • BLS Relies on Bilinear Pairing (expensive)
  • Private Keys: 32 bytes
  • Public Keys: 48 bytes: 381 bit affine x coordinate, encoded into 48 big-endian bytes.
  • Signatures: 96 bytes: two 381 bit integers (affine x coordinate), encoded into two 48 big-endian byte arrays.
    • The signature is a point on the G2 subgroup, which is defined over a finite field with elements twice as big as the G1 curve (G2 is over Fq2 rather than Fq. Fq2 is analogous to the complex numbers).
  • The 12 stands for the Embedding degree.

Formulas:

  • P = pk x G - public keys
  • S = pk x H(m) - signing
  • e(P, H(m)) == e(G,S) - verification using pairings
  • e(G, S) = e(G, SUM(n)(Si)) = MUL(n)(e(G, Si)) - signature aggregation

The BLS parameters for the library are:

  • PK_IN G1
  • HASH_OR_ENCODE true
  • DST BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_
  • RAND_BITS 64

Speed

To achieve the best speed out of all JS / Python implementations, the library employs optimizations:

  • cyclotomic exponentation
  • frobenius coefficients
  • endomorphism for clearing cofactor

Benchmarks measured with Apple M1:

getPublicKey x 1639 ops/sec @ 609μs/op
sign x 20 ops/sec @ 48ms/op
verify x 32 ops/sec @ 30ms/op
pairing x 75 ops/sec @ 13ms/op
aggregatePublicKeys/8 x 396 ops/sec @ 2ms/op
aggregateSignatures/8 x 74 ops/sec @ 13ms/op

with compression / decompression disabled:
sign/nc x 26 ops/sec @ 37ms/op
verify/nc x 55 ops/sec @ 17ms/op
aggregatePublicKeys/32 x 5402 ops/sec @ 185μs/op
aggregatePublicKeys/128 x 1305 ops/sec @ 766μs/op
aggregatePublicKeys/512 x 332 ops/sec @ 3ms/op
aggregatePublicKeys/2048 x 81 ops/sec @ 12ms/op
aggregateSignatures/32 x 1424 ops/sec @ 701μs/op
aggregateSignatures/128 x 347 ops/sec @ 2ms/op
aggregateSignatures/512 x 85 ops/sec @ 11ms/op
aggregateSignatures/2048 x 21 ops/sec @ 46ms/op

Security

Noble is production-ready. Our goal is to have it audited by a good security expert.

We're using built-in JS BigInt, which is "unsuitable for use in cryptography" as per official spec. This means that the lib is potentially vulnerable to timing attacks. But:

  1. JIT-compiler and Garbage Collector make "constant time" extremely hard to achieve in a scripting language.
  2. Which means any other JS library doesn't use constant-time bigints. Including bn.js or anything else. Even statically typed Rust, a language without GC, makes it harder to achieve constant-time for some cases.
  3. If your goal is absolute security, don't use any JS lib — including bindings to native ones. Use low-level libraries & languages.
  4. We however consider infrastructure attacks like rogue NPM modules very important; that's why it's crucial to minimize the amount of 3rd-party dependencies & native bindings. If your app uses 500 dependencies, any dep could get hacked and you'll be downloading rootkits with every npm install. Our goal is to minimize this attack vector.

Contributing

  1. Clone the repository.
  2. npm install to install build dependencies like TypeScript
  3. npm run build to compile TypeScript code
  4. npm run test to run jest on test/index.ts

Special thanks to Roman Koblov, who have helped to improve pairing speed.

License

MIT (c) Paul Miller (https://paulmillr.com), see LICENSE file.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].