From b02cd11c969cde15a7de88657fa3c63830e1b5c1 Mon Sep 17 00:00:00 2001 From: dapplion Date: Mon, 30 Nov 2020 22:05:19 +0000 Subject: [PATCH 1/3] Benchmark noble-bls12-381 f --- test/benchmark/index.ts | 166 +++++++++++++++++++-------------------- test/benchmark/noble.ts | 78 ++++++++++++++++++ test/benchmark/runner.ts | 14 ++-- test/util.ts | 6 ++ 4 files changed, 171 insertions(+), 93 deletions(-) create mode 100644 test/benchmark/noble.ts diff --git a/test/benchmark/index.ts b/test/benchmark/index.ts index f316e4e..5939180 100644 --- a/test/benchmark/index.ts +++ b/test/benchmark/index.ts @@ -1,100 +1,92 @@ import {runBenchmark} from "./runner"; import {runForAllImplementations} from "../switch"; import {IPublicKey, ISignature} from "../../src/interface"; -import {randomBytes} from "../../src/helpers"; +import {range, randomMessage} from "../util"; -runForAllImplementations((bls, implementation) => { - const aggCount = 30; +const aggCount = 30; - // verify +(async function () { + await runForAllImplementations(async (bls, implementation) => { + // verify - runBenchmark<{pk: IPublicKey; msg: Uint8Array; sig: ISignature}, boolean>({ - id: `${implementation} verify`, + await runBenchmark<{pk: IPublicKey; msg: Uint8Array; sig: ISignature}, boolean>({ + id: `${implementation} verify`, - prepareTest: () => { - const msg = randomMsg(); - const sk = bls.SecretKey.fromKeygen(); - const pk = sk.toPublicKey(); - const sig = sk.sign(msg); - return { - input: {pk, msg, sig}, - resultCheck: (valid) => valid === true, - }; - }, - testRunner: ({pk, msg, sig}) => { - return sig.verify(pk, msg); - }, - }); - - // Fast aggregate - - runBenchmark<{pks: IPublicKey[]; msg: Uint8Array; sig: ISignature}, boolean>({ - id: `${implementation} verifyAggregate`, - - prepareTest: () => { - const msg = randomMsg(); - const dataArr = range(aggCount).map(() => { + prepareTest: () => { + const msg = randomMessage(); const sk = bls.SecretKey.fromKeygen(); const pk = sk.toPublicKey(); const sig = sk.sign(msg); - return {pk, sig}; - }); + return { + input: {pk, msg, sig}, + resultCheck: (valid) => valid === true, + }; + }, + testRunner: ({pk, msg, sig}) => { + return sig.verify(pk, msg); + }, + }); - const pks = dataArr.map((data) => data.pk); - const sig = bls.Signature.aggregate(dataArr.map((data) => data.sig)); + // Fast aggregate - return { - input: {pks, msg, sig}, - resultCheck: (valid) => valid === true, - }; - }, - testRunner: ({pks, msg, sig}) => { - return sig.verifyAggregate(pks, msg); - }, + await runBenchmark<{pks: IPublicKey[]; msg: Uint8Array; sig: ISignature}, boolean>({ + id: `${implementation} verifyAggregate`, + + prepareTest: () => { + const msg = randomMessage(); + const dataArr = range(aggCount).map(() => { + const sk = bls.SecretKey.fromKeygen(); + const pk = sk.toPublicKey(); + const sig = sk.sign(msg); + return {pk, sig}; + }); + + const pks = dataArr.map((data) => data.pk); + const sig = bls.Signature.aggregate(dataArr.map((data) => data.sig)); + + return { + input: {pks, msg, sig}, + resultCheck: (valid) => valid === true, + }; + }, + testRunner: ({pks, msg, sig}) => { + return sig.verifyAggregate(pks, msg); + }, + }); + + // Aggregate pubkeys + + await runBenchmark({ + id: `${implementation} aggregate pubkeys (${aggCount})`, + + prepareTest: () => { + return { + input: range(aggCount).map(() => bls.SecretKey.fromKeygen().toPublicKey()), + }; + }, + testRunner: (pks) => { + bls.PublicKey.aggregate(pks); + }, + }); + + // Aggregate sigs + + await runBenchmark({ + id: `${implementation} aggregate signatures (${aggCount})`, + + prepareTest: () => { + const msg = randomMessage(); + const sigs = range(aggCount).map(() => { + const sk = bls.SecretKey.fromKeygen(); + return sk.sign(msg); + }); + return { + input: sigs, + }; + }, + testRunner: (sigs) => { + bls.Signature.aggregate(sigs); + }, + }); }); - - // Aggregate pubkeys - - runBenchmark({ - id: `${implementation} aggregate pubkeys (${aggCount})`, - - prepareTest: () => { - return { - input: range(aggCount).map(() => bls.SecretKey.fromKeygen().toPublicKey()), - }; - }, - testRunner: (pks) => { - bls.PublicKey.aggregate(pks); - }, - }); - - // Aggregate sigs - - runBenchmark({ - id: `${implementation} aggregate signatures (${aggCount})`, - - prepareTest: () => { - const msg = randomMsg(); - const sigs = range(aggCount).map(() => { - const sk = bls.SecretKey.fromKeygen(); - return sk.sign(msg); - }); - return { - input: sigs, - }; - }, - testRunner: (sigs) => { - bls.Signature.aggregate(sigs); - }, - }); -}); - -function range(n: number): number[] { - const nums: number[] = []; - for (let i = 0; i < n; i++) nums.push(i); - return nums; -} - -function randomMsg(): Uint8Array { - return randomBytes(32); -} +})(); diff --git a/test/benchmark/noble.ts b/test/benchmark/noble.ts new file mode 100644 index 0000000..9d78d25 --- /dev/null +++ b/test/benchmark/noble.ts @@ -0,0 +1,78 @@ +import {runBenchmark} from "./runner"; +import {range, randomMessage} from "../util"; +import {generateRandomSecretKey} from "@chainsafe/bls-keygen"; +import * as noble from "noble-bls12-381"; + +const aggCount = 30; +const nobleRuns = 10; + +(async function () { + // verify + + await runBenchmark<{pk: Uint8Array; msg: Uint8Array; sig: Uint8Array}, boolean>({ + id: `noble verify`, + + prepareTest: async () => { + const priv = generateRandomSecretKey(); + const msg = randomMessage(); + const sig = await noble.sign(msg, priv); + const pk = noble.getPublicKey(priv); + + return { + input: {pk, msg, sig}, + resultCheck: (valid: boolean) => valid === true, + }; + }, + testRunner: async ({pk, msg, sig}) => { + return await noble.verify(sig, msg, pk); + }, + runs: nobleRuns, + }); + + // Fast aggregate + + await runBenchmark<{pks: Uint8Array[]; msg: Uint8Array; sig: Uint8Array}, boolean>({ + id: `noble verifyAggregate`, + + prepareTest: async () => { + const msg = randomMessage(); + const dataArr = await Promise.all( + range(aggCount).map(async () => { + const sk = generateRandomSecretKey(); + const pk = noble.getPublicKey(sk); + const sig = await noble.sign(msg, sk); + return {pk, sig}; + }) + ); + + const pks = dataArr.map((data) => data.pk); + const sig = noble.aggregateSignatures(dataArr.map((data) => data.sig)); + + return { + input: {pks, msg, sig}, + resultCheck: (valid: boolean) => valid === true, + }; + }, + testRunner: async ({pks, msg, sig}) => { + const pk = noble.aggregatePublicKeys(pks); + return await noble.verify(sig, msg, pk); + }, + runs: nobleRuns, + }); + + // Aggregate pubkeys + + await runBenchmark({ + id: `noble aggregate pubkeys (${aggCount})`, + + prepareTest: () => { + return { + input: range(aggCount).map(() => noble.getPublicKey(generateRandomSecretKey())), + }; + }, + testRunner: async (pks) => { + noble.aggregatePublicKeys(pks); + }, + runs: nobleRuns, + }); +})(); diff --git a/test/benchmark/runner.ts b/test/benchmark/runner.ts index b7c32bc..90bdaeb 100644 --- a/test/benchmark/runner.ts +++ b/test/benchmark/runner.ts @@ -1,21 +1,23 @@ -export function runBenchmark({ +type PromiseOptional = T | Promise; + +export async function runBenchmark({ prepareTest, testRunner, runs = 100, id, }: { - prepareTest: (i: number) => {input: T; resultCheck?: (result: R) => boolean}; - testRunner: (input: T) => R; + prepareTest: (i: number) => PromiseOptional<{input: T; resultCheck?: (result: R) => boolean}>; + testRunner: (input: T) => PromiseOptional; runs?: number; id: string; -}): void { +}): Promise { const diffsNanoSec: bigint[] = []; for (let i = 0; i < runs; i++) { - const {input, resultCheck} = prepareTest(i); + const {input, resultCheck} = await prepareTest(i); const start = process.hrtime.bigint(); - const result = testRunner(input); + const result = await testRunner(input); const end = process.hrtime.bigint(); if (resultCheck && !resultCheck(result)) throw Error("Result fails check test"); diff --git a/test/util.ts b/test/util.ts index b929188..37e835a 100644 --- a/test/util.ts +++ b/test/util.ts @@ -7,3 +7,9 @@ export function randomMessage(): Uint8Array { export function getN(n: number, getter: () => T): T[] { return Array.from({length: n}, () => getter()); } + +export function range(n: number): number[] { + const nums: number[] = []; + for (let i = 0; i < n; i++) nums.push(i); + return nums; +} From 138c8e99fa4403c5ee6d79aa6583dca700667b2f Mon Sep 17 00:00:00 2001 From: dapplion Date: Mon, 30 Nov 2020 22:05:37 +0000 Subject: [PATCH 2/3] Install libs to benchmark in benchmark project --- test/benchmark/package.json | 12 ++++++++++++ test/benchmark/yarn.lock | 8 ++++++++ 2 files changed, 20 insertions(+) create mode 100644 test/benchmark/package.json create mode 100644 test/benchmark/yarn.lock diff --git a/test/benchmark/package.json b/test/benchmark/package.json new file mode 100644 index 0000000..b9b267b --- /dev/null +++ b/test/benchmark/package.json @@ -0,0 +1,12 @@ +{ + "name": "bls-libs-benchmark", + "version": "1.0.0", + "main": "index.js", + "license": "MIT", + "scripts": { + "benchmark": "ts-node index && ts-node noble" + }, + "dependencies": { + "noble-bls12-381": "^0.6.1" + } +} diff --git a/test/benchmark/yarn.lock b/test/benchmark/yarn.lock new file mode 100644 index 0000000..25594ae --- /dev/null +++ b/test/benchmark/yarn.lock @@ -0,0 +1,8 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +noble-bls12-381@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/noble-bls12-381/-/noble-bls12-381-0.6.1.tgz#b44bb5443b4b5c409723f19a8288155f0b3ad126" + integrity sha512-Dt0lq24ez75HqOqNIsxxbzfY7YOuwArtE3H6Clp1XbwnY4Ga1OjFbTaXq5aDBE3+ab1wLK11s0b3yR3+RiWWqw== From 46e26a621cfb9bf4c72cda50a3a1a4a3ef621417 Mon Sep 17 00:00:00 2001 From: dapplion Date: Mon, 30 Nov 2020 22:07:26 +0000 Subject: [PATCH 3/3] Expose benchmark:all script --- .github/workflows/test.yml | 2 +- package.json | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2bfdb7b..999f802 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -29,4 +29,4 @@ jobs: run: yarn test:web - name: Benchmark - run: yarn benchmark + run: yarn benchmark:all diff --git a/package.json b/package.json index 7c46110..9c40fd5 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,8 @@ "test:spec": "mocha --colors -r ts-node/register 'test/spec/**/*.test.ts'", "test": "yarn run test:unit && yarn run test:spec", "coverage": "codecov -F bls", - "benchmark": "ts-node test/benchmark" + "benchmark": "ts-node test/benchmark", + "benchmark:all": "cd test/benchmark && yarn install && yarn benchmark" }, "dependencies": { "@chainsafe/bls-keygen": "^0.3.0",