import Benchmark from 'benchmark'; import { readToEnd } from '@openpgp/web-stream-tools'; import * as openpgp from 'openpgp'; const wrapAsync = func => ({ fn: async deferred => { await func().catch(onError); deferred.resolve(); }, defer: true }); const onError = err => { // eslint-disable-next-line no-console console.error('The time benchmark tests failed by throwing the following error:'); // eslint-disable-next-line no-console console.error(err); // eslint-disable-next-line no-process-exit process.exit(1); }; /** * Time benchmark tests. * NB: each test will be run multiple times, so any input must be consumable multiple times. */ (async () => { const suite = new Benchmark.Suite(); const { armoredKey, privateKey, publicKey, armoredEncryptedMessage, armoredSignedMessage } = await getTestData(); function* largeDataGenerator({ chunk, numberOfChunks }) { for (let chunkNumber = 0; chunkNumber < numberOfChunks; chunkNumber++) { yield chunk; } } const streamFromGenerator = it => new ReadableStream({ pull: controller => { const { value, done } = it.next(); if (done) { controller.close(); } else { controller.enqueue(value); } } }); suite.add('openpgp.readKey', wrapAsync(async () => { await openpgp.readKey({ armoredKey }); })); suite.add('openpgp.readMessage', wrapAsync(async () => { await openpgp.readMessage({ armoredMessage: armoredEncryptedMessage }); })); suite.add('openpgp.generateKey', wrapAsync(async () => { await openpgp.generateKey({ userIDs: { email: 'test@test.it' } }); })); suite.add('openpgp.encrypt', wrapAsync(async () => { const message = await openpgp.createMessage({ text: 'plaintext' }); await openpgp.encrypt({ message, encryptionKeys: publicKey }); })); suite.add('openpgp.sign', wrapAsync(async () => { const message = await openpgp.createMessage({ text: 'plaintext' }); await openpgp.sign({ message, signingKeys: privateKey }); })); suite.add('openpgp.sign (stream)', wrapAsync(async () => { const inputStream = streamFromGenerator(largeDataGenerator({ chunk: new Uint8Array(10000), numberOfChunks: 10 })); const message = await openpgp.createMessage({ binary: inputStream }); const signed = await openpgp.sign({ message, signingKeys: privateKey }); await readToEnd(signed); })); suite.add('openpgp.decrypt', wrapAsync(async () => { const message = await openpgp.readMessage({ armoredMessage: armoredEncryptedMessage }); await openpgp.decrypt({ message, decryptionKeys: privateKey }); })); suite.add('openpgp.verify', wrapAsync(async () => { const message = await openpgp.readMessage({ armoredMessage: armoredSignedMessage }); await openpgp.verify({ message, verificationKeys: publicKey, expectSigned: true }); })); suite.on('cycle', event => { // Output benchmark result by converting benchmark result to string // eslint-disable-next-line no-console console.log(String(event.target)); }); suite.run({ 'async': true }); })(); async function getTestData() { const armoredKey = `-----BEGIN PGP PRIVATE KEY BLOCK----- xVgEYS4KIRYJKwYBBAHaRw8BAQdAOl5Ij0p8llEOLqalwRM8+YWKXELm+Zl1 arT2orL/42MAAP9SQBdl+A/i4AtIOr33rn6OKzmXQ2EQH0xoSPJcVxX7BA5U zRR0ZXN0IDx0ZXN0QHRlc3QuY29tPsKMBBAWCgAdBQJhLgohBAsJBwgDFQgK BBYAAgECGQECGwMCHgEAIQkQ2RFo4G/cGHQWIQRL9hTrZduw8+42e1rZEWjg b9wYdEi3AP91NftBKXLfcMRz/g540cQ/0+ax8pvsiqFSb+Sqz87YPwEAkoYK 8I9rVAlVABIhy/g7ZStHu/u0zsPbiquZFKoVLgPHXQRhLgohEgorBgEEAZdV AQUBAQdAqY5VZYX6axscpfVN3EED83T3WO3+Hzxfq31dXJXKrRkDAQgHAAD/ an6zziN/Aw0ruIxuZTjmkYriDW34hys8F2nRR23PO6gPjsJ4BBgWCAAJBQJh LgohAhsMACEJENkRaOBv3Bh0FiEES/YU62XbsPPuNnta2RFo4G/cGHQjlgEA gbOEmauiq2avut4e7pSJ98t50zai2dzNies1OpqTU58BAM1pWI99FxM6thX9 aDa+Qhz0AxhA9P+3eQCXYTZR7CEE =LPl8 -----END PGP PRIVATE KEY BLOCK-----`; const privateKey = await openpgp.readKey({ armoredKey }); const publicKey = privateKey.toPublic(); const plaintextMessage = await openpgp.createMessage({ text: 'plaintext' }); const armoredEncryptedMessage = await openpgp.encrypt({ message: plaintextMessage, encryptionKeys: publicKey }); const armoredSignedMessage = await openpgp.sign({ message: await openpgp.createMessage({ text: 'plaintext' }), signingKeys: privateKey }); return { armoredKey, privateKey, publicKey, armoredEncryptedMessage, armoredSignedMessage }; }