diff --git a/benchmark/_shared.js b/benchmark/_shared.js new file mode 100644 index 0000000..bb8192d --- /dev/null +++ b/benchmark/_shared.js @@ -0,0 +1,7 @@ +export function generateData(curve) { + const priv = curve.utils.randomPrivateKey(); + const pub = curve.getPublicKey(priv); + const msg = curve.utils.randomPrivateKey(); + const sig = curve.sign(msg, priv); + return { priv, pub, msg, sig }; +} diff --git a/benchmark/bls.js b/benchmark/bls.js new file mode 100644 index 0000000..fde97c2 --- /dev/null +++ b/benchmark/bls.js @@ -0,0 +1,52 @@ +import { readFileSync } from 'fs'; +import { mark, run } from 'micro-bmark'; +import { bls12_381 as bls } from '../lib/bls12-381.js'; + +const G2_VECTORS = readFileSync('../test/bls12-381/bls12-381-g2-test-vectors.txt', 'utf-8') + .trim() + .split('\n') + .map((l) => l.split(':')); + +run(async () => { + console.log(`\x1b[36mbls12-381\x1b[0m`); + let p1, p2, sig; + await mark('init', 1, () => { + p1 = + bls.G1.ProjectivePoint.BASE.multiply( + 0x28b90deaf189015d3a325908c5e0e4bf00f84f7e639b056ff82d7e70b6eede4cn + ); + p2 = + bls.G2.ProjectivePoint.BASE.multiply( + 0x28b90deaf189015d3a325908c5e0e4bf00f84f7e639b056ff82d7e70b6eede4dn + ); + bls.pairing(p1, p2); + }); + const priv = '28b90deaf189015d3a325908c5e0e4bf00f84f7e639b056ff82d7e70b6eede4c'; + sig = bls.sign('09', priv); + const pubs = G2_VECTORS.map((v) => bls.getPublicKey(v[0])); + const sigs = G2_VECTORS.map((v) => v[2]); + const pub = bls.getPublicKey(priv); + const pub512 = pubs.slice(0, 512); // .map(bls.PointG1.fromHex) + const pub32 = pub512.slice(0, 32); + const pub128 = pub512.slice(0, 128); + const pub2048 = pub512.concat(pub512, pub512, pub512); + const sig512 = sigs.slice(0, 512); // .map(bls.PointG2.fromSignature); + const sig32 = sig512.slice(0, 32); + const sig128 = sig512.slice(0, 128); + const sig2048 = sig512.concat(sig512, sig512, sig512); + await mark('getPublicKey 1-bit', 1000, () => bls.getPublicKey('2'.padStart(64, '0'))); + await mark('getPublicKey', 1000, () => bls.getPublicKey(priv)); + await mark('sign', 50, () => bls.sign('09', priv)); + await mark('verify', 50, () => bls.verify(sig, '09', pub)); + await mark('pairing', 100, () => bls.pairing(p1, p2)); + await mark('aggregatePublicKeys/8', 100, () => bls.aggregatePublicKeys(pubs.slice(0, 8))); + await mark('aggregatePublicKeys/32', 50, () => bls.aggregatePublicKeys(pub32)); + await mark('aggregatePublicKeys/128', 20, () => bls.aggregatePublicKeys(pub128)); + await mark('aggregatePublicKeys/512', 10, () => bls.aggregatePublicKeys(pub512)); + await mark('aggregatePublicKeys/2048', 5, () => bls.aggregatePublicKeys(pub2048)); + await mark('aggregateSignatures/8', 100, () => bls.aggregateSignatures(sigs.slice(0, 8))); + await mark('aggregateSignatures/32', 50, () => bls.aggregateSignatures(sig32)); + await mark('aggregateSignatures/128', 20, () => bls.aggregateSignatures(sig128)); + await mark('aggregateSignatures/512', 10, () => bls.aggregateSignatures(sig512)); + await mark('aggregateSignatures/2048', 5, () => bls.aggregateSignatures(sig2048)); +}); diff --git a/benchmark/curves.js b/benchmark/curves.js new file mode 100644 index 0000000..c49b1a1 --- /dev/null +++ b/benchmark/curves.js @@ -0,0 +1,23 @@ +import { run, mark, utils } from 'micro-bmark'; +import { generateData } from './_shared.js'; +import { P256 } from '../lib/p256.js'; +import { P384 } from '../lib/p384.js'; +import { P521 } from '../lib/p521.js'; +import { ed25519 } from '../lib/ed25519.js'; +import { ed448 } from '../lib/ed448.js'; + +run(async () => { + const RAM = false + for (let kv of Object.entries({ P256, P384, P521, ed25519, ed448 })) { + const [name, curve] = kv; + console.log(); + console.log(`\x1b[36m${name}\x1b[0m`); + if (RAM) utils.logMem(); + await mark('init', 1, () => curve.utils.precompute(8)); + const d = generateData(curve); + await mark('getPublicKey', 5000, () => curve.getPublicKey(d.priv)); + await mark('sign', 5000, () => curve.sign(d.msg, d.priv)); + await mark('verify', 500, () => curve.verify(d.sig, d.msg, d.pub)); + if (RAM) utils.logMem(); + } +}); diff --git a/benchmark/index.js b/benchmark/index.js deleted file mode 100644 index 5f8b5a3..0000000 --- a/benchmark/index.js +++ /dev/null @@ -1,424 +0,0 @@ -import * as bench from 'micro-bmark'; -const { run, mark } = bench; // or bench.mark -import { readFileSync } from 'fs'; - -// Curves -import { secp256k1 } from '../lib/secp256k1.js'; -import { P256 } from '../lib/p256.js'; -import { P384 } from '../lib/p384.js'; -import { P521 } from '../lib/p521.js'; -import { ed25519 } from '../lib/ed25519.js'; -import { ed448 } from '../lib/ed448.js'; -import { bls12_381 as bls } from '../lib/bls12-381.js'; - -// Others -import { hmac } from '@noble/hashes/hmac'; -import { sha256 } from '@noble/hashes/sha256'; -import { sha512 } from '@noble/hashes/sha512'; - -import * as old_secp from '@noble/secp256k1'; -import * as old_bls from '@noble/bls12-381'; -import { concatBytes, hexToBytes } from '@noble/hashes/utils'; - -import * as starkwareCrypto from '@starkware-industries/starkware-crypto-utils'; -import * as stark from '../lib/stark.js'; - -old_secp.utils.sha256Sync = (...msgs) => - sha256 - .create() - .update(concatBytes(...msgs)) - .digest(); -old_secp.utils.hmacSha256Sync = (key, ...msgs) => - hmac - .create(sha256, key) - .update(concatBytes(...msgs)) - .digest(); -import * as noble_ed25519 from '@noble/ed25519'; -noble_ed25519.utils.sha512Sync = (...m) => sha512(concatBytes(...m)); - -// BLS -const G2_VECTORS = readFileSync('../test/bls12-381/bls12-381-g2-test-vectors.txt', 'utf-8') - .trim() - .split('\n') - .map((l) => l.split(':')); -let p1, p2, oldp1, oldp2; -// /BLS - -for (let item of [secp256k1, ed25519, ed448, P256, P384, P521]) item.utils.precompute(8); -for (let item of [old_secp, noble_ed25519]) item.utils.precompute(8); - -const ONLY_NOBLE = process.argv[2] === 'noble'; - -function generateData(namespace) { - const priv = namespace.utils.randomPrivateKey(); - const pub = namespace.getPublicKey(priv); - const msg = namespace.utils.randomPrivateKey(); - const sig = namespace.sign(msg, priv); - return { priv, pub, msg, sig }; -} - -export const CURVES = { - secp256k1: { - data: () => { - return generateData(secp256k1); - }, - getPublicKey1: { - samples: 10000, - secp256k1_old: () => old_secp.getPublicKey(3n), - secp256k1: () => secp256k1.getPublicKey(3n), - }, - getPublicKey255: { - samples: 10000, - secp256k1_old: () => old_secp.getPublicKey(2n ** 255n - 1n), - secp256k1: () => secp256k1.getPublicKey(2n ** 255n - 1n), - }, - sign: { - samples: 5000, - secp256k1_old: ({ msg, priv }) => old_secp.signSync(msg, priv), - secp256k1: ({ msg, priv }) => secp256k1.sign(msg, priv).toCompactRawBytes(), - }, - verify: { - samples: 1000, - secp256k1_old: ({ sig, msg, pub }) => { - return old_secp.verify(new old_secp.Signature(sig.r, sig.s), msg, pub); - }, - secp256k1: ({ sig, msg, pub }) => secp256k1.verify(sig, msg, pub), - }, - getSharedSecret: { - samples: 1000, - secp256k1_old: ({ pub, priv }) => old_secp.getSharedSecret(priv, pub), - secp256k1: ({ pub, priv }) => secp256k1.getSharedSecret(priv, pub), - }, - recoverPublicKey: { - samples: 1000, - secp256k1_old: ({ sig, msg }) => - old_secp.recoverPublicKey(msg, new old_secp.Signature(sig.r, sig.s), sig.recovery), - secp256k1: ({ sig, msg }) => sig.recoverPublicKey(msg), - }, - // hashToCurve: { - // samples: 500, - // noble: () => secp256k1.Point.hashToCurve('abcd'), - // }, - }, - ed25519: { - data: () => { - function to32Bytes(numOrStr) { - const hex = typeof numOrStr === 'string' ? numOrStr : numOrStr.toString(16); - return hexToBytes(hex.padStart(64, '0')); - } - const priv = to32Bytes(0x9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60n); - const pub = noble_ed25519.sync.getPublicKey(priv); - const msg = to32Bytes('deadbeefdeadbeefdeadbeefdeadbeefdeadbeef'); - const sig = noble_ed25519.sync.sign(msg, priv); - return { pub, priv, msg, sig }; - }, - getPublicKey: { - samples: 10000, - old: () => noble_ed25519.sync.getPublicKey(noble_ed25519.utils.randomPrivateKey()), - noble: () => ed25519.getPublicKey(ed25519.utils.randomPrivateKey()), - }, - sign: { - samples: 5000, - old: ({ msg, priv }) => noble_ed25519.sync.sign(msg, priv), - noble: ({ msg, priv }) => ed25519.sign(msg, priv), - }, - verify: { - samples: 1000, - old: ({ sig, msg, pub }) => noble_ed25519.sync.verify(sig, msg, pub), - noble: ({ sig, msg, pub }) => ed25519.verify(sig, msg, pub), - }, - // hashToCurve: { - // samples: 500, - // noble: () => ed25519.Point.hashToCurve('abcd'), - // }, - }, - ed448: { - data: () => { - const priv = ed448.utils.randomPrivateKey(); - const pub = ed448.getPublicKey(priv); - const msg = ed448.utils.randomPrivateKey(); - const sig = ed448.sign(msg, priv); - return { priv, pub, msg, sig }; - }, - getPublicKey: { - samples: 5000, - noble: () => ed448.getPublicKey(ed448.utils.randomPrivateKey()), - }, - sign: { - samples: 2500, - noble: ({ msg, priv }) => ed448.sign(msg, priv), - }, - verify: { - samples: 500, - noble: ({ sig, msg, pub }) => ed448.verify(sig, msg, pub), - }, - // hashToCurve: { - // samples: 500, - // noble: () => ed448.Point.hashToCurve('abcd'), - // }, - }, - nist: { - data: () => { - return { p256: generateData(P256), p384: generateData(P384), p521: generateData(P521) }; - }, - getPublicKey: { - samples: 2500, - P256: () => P256.getPublicKey(P256.utils.randomPrivateKey()), - P384: () => P384.getPublicKey(P384.utils.randomPrivateKey()), - P521: () => P521.getPublicKey(P521.utils.randomPrivateKey()), - }, - sign: { - samples: 1000, - P256: ({ p256: { msg, priv } }) => P256.sign(msg, priv), - P384: ({ p384: { msg, priv } }) => P384.sign(msg, priv), - P521: ({ p521: { msg, priv } }) => P521.sign(msg, priv), - }, - verify: { - samples: 250, - P256: ({ p256: { sig, msg, pub } }) => P256.verify(sig, msg, pub), - P384: ({ p384: { sig, msg, pub } }) => P384.verify(sig, msg, pub), - P521: ({ p521: { sig, msg, pub } }) => P521.verify(sig, msg, pub), - }, - // hashToCurve: { - // samples: 500, - // P256: () => P256.Point.hashToCurve('abcd'), - // P384: () => P384.Point.hashToCurve('abcd'), - // P521: () => P521.Point.hashToCurve('abcd'), - // }, - }, - stark: { - data: () => { - const priv = '2dccce1da22003777062ee0870e9881b460a8b7eca276870f57c601f182136c'; - const msg = 'c465dd6b1bbffdb05442eb17f5ca38ad1aa78a6f56bf4415bdee219114a47'; - const pub = stark.getPublicKey(priv); - const sig = stark.sign(msg, priv); - - const privateKey = '2dccce1da22003777062ee0870e9881b460a8b7eca276870f57c601f182136c'; - const msgHash = 'c465dd6b1bbffdb05442eb17f5ca38ad1aa78a6f56bf4415bdee219114a47'; - const keyPair = starkwareCrypto.default.ec.keyFromPrivate(privateKey, 'hex'); - const publicKeyStark = starkwareCrypto.default.ec.keyFromPublic( - keyPair.getPublic(true, 'hex'), - 'hex' - ); - - return { priv, sig, msg, pub, publicKeyStark, msgHash, keyPair }; - }, - pedersen: { - samples: 500, - old: () => { - return starkwareCrypto.default.pedersen([ - '3d937c035c878245caf64531a5756109c53068da139362728feb561405371cb', - '208a0a10250e382e1e4bbe2880906c2791bf6275695e02fbbc6aeff9cd8b31a', - ]); - }, - noble: () => { - return stark.pedersen( - '3d937c035c878245caf64531a5756109c53068da139362728feb561405371cb', - '208a0a10250e382e1e4bbe2880906c2791bf6275695e02fbbc6aeff9cd8b31a' - ); - }, - }, - poseidon: { - samples: 2000, - noble: () => { - return stark.poseidonHash( - 0x3d937c035c878245caf64531a5756109c53068da139362728feb561405371cbn, - 0x208a0a10250e382e1e4bbe2880906c2791bf6275695e02fbbc6aeff9cd8b31an - ); - }, - }, - verify: { - samples: 500, - old: ({ publicKeyStark, msgHash, keyPair }) => { - return starkwareCrypto.default.verify( - publicKeyStark, - msgHash, - starkwareCrypto.default.sign(keyPair, msgHash) - ); - }, - noble: ({ priv, msg, pub }) => { - return stark.verify(stark.sign(msg, priv), msg, pub); - }, - }, - }, - 'bls12-381': { - data: async () => { - const priv = '28b90deaf189015d3a325908c5e0e4bf00f84f7e639b056ff82d7e70b6eede4c'; - const pubs = G2_VECTORS.map((v) => bls.getPublicKey(v[0])); - const sigs = G2_VECTORS.map((v) => v[2]); - const pub = bls.getPublicKey(priv); - const pub512 = pubs.slice(0, 512); // .map(bls.PointG1.fromHex) - const pub32 = pub512.slice(0, 32); - const pub128 = pub512.slice(0, 128); - const pub2048 = pub512.concat(pub512, pub512, pub512); - const sig512 = sigs.slice(0, 512); // .map(bls.PointG2.fromSignature); - const sig32 = sig512.slice(0, 32); - const sig128 = sig512.slice(0, 128); - const sig2048 = sig512.concat(sig512, sig512, sig512); - return { - priv, - pubs, - sigs, - pub, - pub512, - pub32, - pub128, - pub2048, - sig32, - sig128, - sig512, - sig2048, - }; - }, - init: { - samples: 1, - old: () => { - oldp1 = - old_bls.PointG1.BASE.multiply( - 0x28b90deaf189015d3a325908c5e0e4bf00f84f7e639b056ff82d7e70b6eede4cn - ); - oldp2 = - old_bls.PointG2.BASE.multiply( - 0x28b90deaf189015d3a325908c5e0e4bf00f84f7e639b056ff82d7e70b6eede4dn - ); - old_bls.pairing(oldp1, oldp2); - }, - noble: () => { - p1 = - bls.G1.ProjectivePoint.BASE.multiply( - 0x28b90deaf189015d3a325908c5e0e4bf00f84f7e639b056ff82d7e70b6eede4cn - ); - p2 = - bls.G2.ProjectivePoint.BASE.multiply( - 0x28b90deaf189015d3a325908c5e0e4bf00f84f7e639b056ff82d7e70b6eede4dn - ); - bls.pairing(p1, p2); - }, - }, - 'getPublicKey (1-bit)': { - samples: 1000, - old: () => old_bls.getPublicKey('2'.padStart(64, '0')), - noble: () => bls.getPublicKey('2'.padStart(64, '0')), - }, - getPublicKey: { - samples: 1000, - old: ({ priv }) => old_bls.getPublicKey(priv), - noble: ({ priv }) => bls.getPublicKey(priv), - }, - sign: { - samples: 50, - old: ({ priv }) => old_bls.sign('09', priv), - noble: ({ priv }) => bls.sign('09', priv), - }, - verify: { - samples: 50, - old: ({ pub }) => - old_bls.verify( - '8647aa9680cd0cdf065b94e818ff2bb948cc97838bcee987b9bc1b76d0a0a6e0d85db4e9d75aaedfc79d4ea2733a21ae0579014de7636dd2943d45b87c82b1c66a289006b0b9767921bb8edd3f6c5c5dec0d54cd65f61513113c50cc977849e5', - '09', - pub - ), - noble: ({ pub }) => - bls.verify( - '8647aa9680cd0cdf065b94e818ff2bb948cc97838bcee987b9bc1b76d0a0a6e0d85db4e9d75aaedfc79d4ea2733a21ae0579014de7636dd2943d45b87c82b1c66a289006b0b9767921bb8edd3f6c5c5dec0d54cd65f61513113c50cc977849e5', - '09', - pub - ), - }, - pairing: { - samples: 100, - old: () => old_bls.pairing(oldp1, oldp2), - noble: () => bls.pairing(p1, p2), - }, - // 'hashToCurve/G1': { - // samples: 500, - // old: () => old_bls.PointG1.hashToCurve('abcd'), - // noble: () => bls.hashToCurve.G1.hashToCurve('abcd'), - // }, - // 'hashToCurve/G2': { - // samples: 200, - // old: () => old_bls.PointG2.hashToCurve('abcd'), - // noble: () => bls.hashToCurve.G2.hashToCurve('abcd'), - // }, - // SLOW PART - // Requires points which we cannot init before (data fn same for all) - // await mark('sign/nc', 30, () => bls.sign(msgp, priv)); - // await mark('verify/nc', 30, () => bls.verify(sigp, msgp, pubp)); - 'aggregatePublicKeys/8': { - samples: 100, - old: ({ pubs }) => old_bls.aggregatePublicKeys(pubs.slice(0, 8)), - noble: ({ pubs }) => bls.aggregatePublicKeys(pubs.slice(0, 8)), - }, - 'aggregatePublicKeys/32': { - samples: 50, - old: ({ pub32 }) => old_bls.aggregatePublicKeys(pub32.map(old_bls.PointG1.fromHex)), - noble: ({ pub32 }) => bls.aggregatePublicKeys(pub32.map(bls.G1.ProjectivePoint.fromHex)), - }, - 'aggregatePublicKeys/128': { - samples: 20, - old: ({ pub128 }) => old_bls.aggregatePublicKeys(pub128.map(old_bls.PointG1.fromHex)), - noble: ({ pub128 }) => bls.aggregatePublicKeys(pub128.map(bls.G1.ProjectivePoint.fromHex)), - }, - 'aggregatePublicKeys/512': { - samples: 10, - old: ({ pub512 }) => old_bls.aggregatePublicKeys(pub512.map(old_bls.PointG1.fromHex)), - noble: ({ pub512 }) => bls.aggregatePublicKeys(pub512.map(bls.G1.ProjectivePoint.fromHex)), - }, - 'aggregatePublicKeys/2048': { - samples: 5, - old: ({ pub2048 }) => old_bls.aggregatePublicKeys(pub2048.map(old_bls.PointG1.fromHex)), - noble: ({ pub2048 }) => bls.aggregatePublicKeys(pub2048.map(bls.G1.ProjectivePoint.fromHex)), - }, - 'aggregateSignatures/8': { - samples: 50, - old: ({ sigs }) => old_bls.aggregateSignatures(sigs.slice(0, 8)), - noble: ({ sigs }) => bls.aggregateSignatures(sigs.slice(0, 8)), - }, - 'aggregateSignatures/32': { - samples: 10, - old: ({ sig32 }) => old_bls.aggregateSignatures(sig32.map(old_bls.PointG2.fromSignature)), - noble: ({ sig32 }) => bls.aggregateSignatures(sig32.map(bls.Signature.decode)), - }, - 'aggregateSignatures/128': { - samples: 5, - old: ({ sig128 }) => old_bls.aggregateSignatures(sig128.map(old_bls.PointG2.fromSignature)), - noble: ({ sig128 }) => bls.aggregateSignatures(sig128.map(bls.Signature.decode)), - }, - 'aggregateSignatures/512': { - samples: 3, - old: ({ sig512 }) => old_bls.aggregateSignatures(sig512.map(old_bls.PointG2.fromSignature)), - noble: ({ sig512 }) => bls.aggregateSignatures(sig512.map(bls.Signature.decode)), - }, - 'aggregateSignatures/2048': { - samples: 2, - old: ({ sig2048 }) => old_bls.aggregateSignatures(sig2048.map(old_bls.PointG2.fromSignature)), - noble: ({ sig2048 }) => bls.aggregateSignatures(sig2048.map(bls.Signature.decode)), - }, - }, -}; - -const main = () => - run(async () => { - for (const [name, curve] of Object.entries(CURVES)) { - console.log(`==== ${name} ====`); - const data = await curve.data(); - for (const [fnName, libs] of Object.entries(curve)) { - if (fnName === 'data') continue; - const samples = libs.samples; - console.log(` - ${fnName} (samples: ${samples})`); - for (const [lib, fn] of Object.entries(libs)) { - if (lib === 'samples') continue; - if (ONLY_NOBLE && lib !== 'noble') continue; - await mark(` ${lib}`, samples, () => fn(data)); - } - } - } - // Log current RAM - bench.logMem(); - }); - -// ESM is broken. -import url from 'url'; -if (import.meta.url === url.pathToFileURL(process.argv[1]).href) { - main(); -} diff --git a/benchmark/package.json b/benchmark/package.json index ecc0127..3d9a6f8 100644 --- a/benchmark/package.json +++ b/benchmark/package.json @@ -1,26 +1,22 @@ { - "name": "benchmark", - "private": true, - "version": "0.1.0", - "description": "benchmarks", - "main": "index.js", - "type": "module", - "scripts": { - "bench": "node index.js" - }, - "keywords": [], - "author": "", - "license": "MIT", - "devDependencies": { - "micro-bmark": "0.2.1" - }, - "dependencies": { - "@noble/bls12-381": "^1.4.0", - "@noble/ed25519": "^1.7.1", - "@noble/hashes": "^1.1.5", - "@noble/secp256k1": "^1.7.0", - "@starkware-industries/starkware-crypto-utils": "^0.0.2", - "calculate-correlation": "^1.2.3", - "elliptic": "^6.5.4" - } + "name": "benchmark", + "private": true, + "version": "0.1.0", + "description": "benchmarks", + "main": "index.js", + "type": "module", + "scripts": { + "bench": "node index.js" + }, + "keywords": [], + "author": "", + "license": "MIT", + "devDependencies": { + "micro-bmark": "0.3.0" + }, + "dependencies": { + "@noble/hashes": "^1.1.5", + "@starkware-industries/starkware-crypto-utils": "^0.0.2", + "elliptic": "^6.5.4" + } } diff --git a/benchmark/secp256k1.js b/benchmark/secp256k1.js new file mode 100644 index 0000000..ca232fc --- /dev/null +++ b/benchmark/secp256k1.js @@ -0,0 +1,22 @@ +import { run, mark, utils } from 'micro-bmark'; +import { secp256k1, schnorr } from '../lib/secp256k1.js'; +import { generateData } from './_shared.js'; + +run(async () => { + const RAM = false; + if (RAM) utils.logMem(); + console.log(`\x1b[36msecp256k1\x1b[0m`); + await mark('init', 1, () => secp256k1.utils.precompute(8)); + const d = generateData(secp256k1); + await mark('getPublicKey', 10000, () => secp256k1.getPublicKey(d.priv)); + await mark('sign', 10000, () => secp256k1.sign(d.msg, d.priv)); + await mark('verify', 1000, () => secp256k1.verify(d.sig, d.msg, d.pub)); + const pub2 = secp256k1.getPublicKey(secp256k1.utils.randomPrivateKey()); + await mark('getSharedSecret', 1000, () => secp256k1.getSharedSecret(d.priv, pub2)); + await mark('recoverPublicKey', 1000, () => d.sig.recoverPublicKey(d.msg)); + const s = schnorr.sign(d.msg, d.priv); + const spub = schnorr.getPublicKey(d.priv); + await mark('schnorr.sign', 1000, () => schnorr.sign(d.msg, d.priv)); + await mark('schnorr.verify', 1000, () => schnorr.verify(s, d.msg, spub)); + if (RAM) utils.logMem(); +}); diff --git a/benchmark/stark.js b/benchmark/stark.js new file mode 100644 index 0000000..e97faf9 --- /dev/null +++ b/benchmark/stark.js @@ -0,0 +1,56 @@ +import { run, mark, compare, utils } from 'micro-bmark'; +import * as starkwareCrypto from '@starkware-industries/starkware-crypto-utils'; +import * as stark from '../lib/stark.js'; + +run(async () => { + const RAM = false; + if (RAM) utils.logMem(); + console.log(`\x1b[36msecp256k1\x1b[0m`); + await mark('init', 1, () => stark.utils.precompute(8)); + const d = (() => { + const priv = '2dccce1da22003777062ee0870e9881b460a8b7eca276870f57c601f182136c'; + const msg = 'c465dd6b1bbffdb05442eb17f5ca38ad1aa78a6f56bf4415bdee219114a47'; + const pub = stark.getPublicKey(priv); + const sig = stark.sign(msg, priv); + + const privateKey = '2dccce1da22003777062ee0870e9881b460a8b7eca276870f57c601f182136c'; + const msgHash = 'c465dd6b1bbffdb05442eb17f5ca38ad1aa78a6f56bf4415bdee219114a47'; + const keyPair = starkwareCrypto.default.ec.keyFromPrivate(privateKey, 'hex'); + const publicKeyStark = starkwareCrypto.default.ec.keyFromPublic( + keyPair.getPublic(true, 'hex'), + 'hex' + ); + return { priv, sig, msg, pub, publicKeyStark, msgHash, keyPair }; + })(); + await compare('pedersen', 500, { + old: () => { + return starkwareCrypto.default.pedersen([ + '3d937c035c878245caf64531a5756109c53068da139362728feb561405371cb', + '208a0a10250e382e1e4bbe2880906c2791bf6275695e02fbbc6aeff9cd8b31a', + ]); + }, + noble: () => { + return stark.pedersen( + '3d937c035c878245caf64531a5756109c53068da139362728feb561405371cb', + '208a0a10250e382e1e4bbe2880906c2791bf6275695e02fbbc6aeff9cd8b31a' + ); + }, + }); + await mark('poseidon', 10000, () => stark.poseidonHash( + 0x3d937c035c878245caf64531a5756109c53068da139362728feb561405371cbn, + 0x208a0a10250e382e1e4bbe2880906c2791bf6275695e02fbbc6aeff9cd8b31an + )); + await compare('verify', 500, { + old: () => { + return starkwareCrypto.default.verify( + d.publicKeyStark, + d.msgHash, + starkwareCrypto.default.sign(d.keyPair, d.msgHash) + ); + }, + noble: () => { + return stark.verify(stark.sign(d.msg, d.priv), d.msg, d.pub); + }, + }); + if (RAM) utils.logMem(); +}); diff --git a/package.json b/package.json index c696690..e04053d 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "lib" ], "scripts": { - "bench": "cd benchmark; node index.js", + "bench": "cd benchmark; node secp256k1.js; node curves.js; node stark.js; node bls.js", "build": "tsc && tsc -p tsconfig.esm.json", "build:release": "rollup -c rollup.config.js", "lint": "prettier --check 'src/**/*.{js,ts}' 'test/*.js'", @@ -30,7 +30,7 @@ "@scure/bip39": "~1.1.0", "@types/node": "18.11.3", "fast-check": "3.0.0", - "micro-bmark": "0.2.0", + "micro-bmark": "0.3.0", "micro-should": "0.4.0", "prettier": "2.8.3", "rollup": "2.75.5", diff --git a/src/stark.ts b/src/stark.ts index cd15290..b4be59f 100644 --- a/src/stark.ts +++ b/src/stark.ts @@ -97,7 +97,7 @@ function ensureBytes0x(hex: Hex): Uint8Array { function normalizePrivateKey(privKey: Hex) { return cutils.bytesToHex(ensureBytes0x(privKey)).padStart(64, '0'); } -function getPublicKey0x(privKey: Hex, isCompressed?: boolean) { +function getPublicKey0x(privKey: Hex, isCompressed = false) { return starkCurve.getPublicKey(normalizePrivateKey(privKey), isCompressed); } function getSharedSecret0x(privKeyA: Hex, pubKeyB: Hex) {