bls-sign
v0.13.10
Published
BLS threshold signatures creation and verification
Maintainers
Readme
bls-sign
npm: bls-sign
This package is still being downloaded ~10 times a week after 6 years! I decided to publish some small updates using new AI features.
Boneh–Lynn–Shacham signature scheme
The Boneh–Lynn–Shacham (BLS) signature scheme allows a user to verify that a signer is authentic. The scheme uses a bilinear pairing for verification, and signatures are elements of an elliptic curve group. Working in an elliptic curve group provides some defense against index calculus attacks, allowing shorter signatures than FDH signatures for a similar level of security. Signatures produced by the BLS signature scheme are often referred to as short signatures, BLS short signatures, or simply BLS signatures. The signature scheme is provably secure (it is existentially unforgeable under adaptive chosen-message attacks), assuming both the existence of random oracles and the intractability of the computational Diffie–Hellman problem in a gap Diffie–Hellman group.
Usage
npm install bls-signconst { BLSSigner, BLSSecretKey, BLSPublicKey } = require('bls-sign')
const signer = new BLSSigner(256)
// Q is a fixed global generator on G1; H is the message hashed onto G2
const Q = signer.G.multiply(4n)
const H = signer.getRandomPointOnEt()
const secretKey = new BLSSecretKey()
const publicKey = new BLSPublicKey(secretKey, Q)
const signature = secretKey.sign(H)
signer.verify(Q, H, publicKey, signature) // trueThreshold signatures
A secret key can be split into n shares, any k of which are enough to reconstruct it (Shamir's Secret Sharing):
// split secretKey into 5 shares, any 3 of which reconstruct it
const shares = secretKey.share(5, 3)
const recovered = new BLSSecretKey()
recovered.recover(shares.slice(0, 3))
recovered.s === secretKey.s // trueAPI
BLSSigner
Holds the curve's fixed generator points and provides the top-level sign/verify helpers.
new BLSSigner(bitLength)— createsG(a generator point on G1) andG2(a generator point on G2).bitLengthis currently unused..G,.G2— the fixed generator points..getRandomPointOnE()— a random scalar multiple ofG(a random point on G1)..getRandomPointOnEt()— a random scalar multiple ofG2(a random point on G2); typically used as the "message" pointH..sign(H, s)— low-level signing: returnsH.multiply(s), a raw point (not aBLSSignature). For normal use preferBLSSecretKey.sign(H)below..verify(Q, H, sQ, sH)— checkse(sQ, H) === e(Q, sH).sQmust be aBLSPublicKey,sHaBLSSignature..getPairing(),.getParameters()— currently always returnundefined; unimplemented.
BLSSecretKey
new BLSSecretKey(s)— wraps a secret scalar. Ifsis omitted, generates a random one-byte secret (0-255)..toString().getPublicKey(Q)— derives this key'sBLSPublicKeyfor generatorQ..sign(H)— signs pointH, returning aBLSSignature..getMasterSecretKey(k)— builds thekcoefficients of a degreek-1sharing polynomial withthisas the constant term (the secret). Throws ifk <= 1..share(n, k)— Shamir's Secret Sharing: splits the secret intonshares (ids1..n) drawn from a degreek-1polynomial; anykof the returned shares can reconstruct the secret..recover(vec)— reconstructs the secret from an array of shares via Lagrange interpolation and setsthis.s(this.idbecomes0). Passing fewer thankshares does not throw — it silently produces a different, wrong secret, so callers are responsible for gathering enough shares.
BLSPublicKey
new BLSPublicKey(secretKey, Q)— computessQ = Q.multiply(secretKey.s)..toString()
BLSSignature
.toString().recover(signVec)— combines an array of partial signatures (each produced by a key share's.sign()) into one valid signature via Lagrange interpolation, without ever reconstructing the underlying secret key. Same "fewer thankshares silently gives a wrong result" caveat asBLSSecretKey.recover.
BLSSignature instances are normally produced by BLSSecretKey.sign() / BLSSignature.recover(), not constructed directly.
BLSPolynomial
Internal helper backing the threshold-sharing methods above:
.eval(msk, x)— evaluates the sharing polynomial (coefficientsmsk, each with an.s) atx..calcDelta(ids)— computes the Lagrange basis coefficients atx = 0for an array of share ids. Throws if fewer than 2 ids are given, or if two ids are equal..lagrange(vec)— reconstructs either a secret scalar (if entries have.s) or an aggregated signature point (if entries have.sH) via Lagrange interpolation atx = 0.
Parameters
Re-exported from alg-field: the curve's field parameters — Parameters.p (the base field prime) and Parameters.n (the curve/group order).
The Scheme
e : G1 x G2 -> Fp12 ; ate pairing over BN curve
Q in G1 ; fixed global parameter
H : {str} -> G2
s in Fr: secret key
sQ in G1; public key
s H(m) in G2; signature of m
verify ; e(sQ, H(m)) = e(Q, s H(m))Shamir Secret Sharing and Lagrange Interpolation
Shamir's Secret Sharing is an algorithm in cryptography created by Adi Shamir. It is a form of secret sharing where a secret is divided into parts, giving each participant its own unique part. Some or all of the parts are needed in order to reconstruct the secret.
Counting on all participants to combine the secret might be impractical, so the threshold scheme is sometimes used instead, where any k of the parts is sufficient to reconstruct the original secret.

Build
npm run buildRun tests
npm run testCurves are compatible with Ethereum.
