TypeScript icon, indicating that this package has built-in type declarations

    6.0.2 • Public • Published


    codecov ETH2.0_Spec_Version 1.0.0 ES Version Node Version

    Javascript library for BLS (Boneh-Lynn-Shacham) signatures and signature aggregation, tailored for use in Eth2.


    yarn add @chainsafe/bls

    To use native bindings you must install peer dependency @chainsafe/blst

    yarn add @chainsafe/bls @chainsafe/blst

    You must initialize the library once in your application before using it. The result is cached and use across all your imports

    import {init, SecretKey, secretKeyToPublicKey, sign, verify} from "@chainsafe/bls";
    (async () => {
      await init("herumi");
      // class-based interface
      const secretKey = SecretKey.fromKeygen();
      const publicKey = secretKey.toPublicKey();
      const message = new Uint8Array(32);
      const signature = secretKey.sign(message);
      console.log("Is valid: ", signature.verify(publicKey, message));
      // functional interface
      const sk = secretKey.toBytes();
      const pk = secretKeyToPublicKey(sk);
      const sig = sign(sk, message);
      console.log("Is valid: ", verify(pk, message, sig));


    If you are in the browser, import from /browser to import directly the WASM version

    import bls from "@chainsafe/bls/browser";

    Native bindings only

    If you are in NodeJS, import from /node to skip browser specific code. Also install peer dependency @chainsafe/blst which has the native bindings

    yarn add @chainsafe/bls @chainsafe/blst
    import bls from "@chainsafe/bls/node";

    Native bindings + WASM fallback

    If you want to offer a fallback in NodeJS, first try to load native bindings and then fallback to WASM. Also install peer dependency @chainsafe/blst which has the native bindings

    yarn add @chainsafe/bls @chainsafe/blst
    import {init} from "@chainsafe/bls";
    try {
      await init("blst-native");
    } catch (e) {
      await init("herumi");
      console.warn("Using WASM");

    The API is identical for all implementations.


    Results are in ops/sec (x times slower), where x times slower = times slower than fastest implementation (blst).

    Function - ops/sec blst herumi noble
    verify 326.38 47.674 (x7) 17.906 (x18)
    verifyAggregate (30) 453.29 51.151 (x9) 18.372 (x25)
    verifyMultiple (30) 34.497 3.5233 (x10) 2.0286 (x17)
    verifyMultipleSignatures (30) 26.381 3.1633 (x8) -
    aggregate (pubkeys, 30) 15686 2898.9 (x5) 1875.0 (x8)
    aggregate (sigs, 30) 6373.4 1033.0 (x6) 526.25 (x12)
    sign 925.49 108.81 (x9) 10.246 (x90)

    * blst and herumi performed 100 runs each, noble 10 runs.

    Results from CI run https://github.com/ChainSafe/bls/runs/1513710175?check_suite_focus=true#step:12:13

    Spec versioning

    Version Bls spec hash-to-curve version
    5.x.x draft #9
    2.x.x draft #7
    1.x.x draft #6
    0.3.x initial version


    test vectors




    npm i @chainsafe/bls

    DownloadsWeekly Downloads






    Unpacked Size

    64 kB

    Total Files


    Last publish


    • gregthegreek
    • priom
    • dapplion
    • wemeetagain
    • mpetrunic