Skip to content

Instantly share code, notes, and snippets.

@panva

panva/README.md Secret

Last active April 9, 2020 08:52
Show Gist options
  • Save panva/09902dde1c737bc551397761d4e9ed42 to your computer and use it in GitHub Desktop.
Save panva/09902dde1c737bc551397761d4e9ed42 to your computer and use it in GitHub Desktop.
Proposal crypto's KeyObject interaction with worker_threads.

Proposal

crypto's KeyObject interaction with worker_threads

  • (required) when KeyObject instances are part of the message (it would be okay if they also had to be put in transferList) they get transmitted as KeyObject instances
  • (optional) the KeyObject instance remains the same object in the worker thread when passed again

sendMessage

const { Worker, isMainThread, parentPort } = require('worker_threads')
const crypto = require('crypto')
const { promisify } = require('util')
const { strict: assert } = require('assert')
const generateKeyPair = promisify(crypto.generateKeyPair)
if (isMainThread) {
const tasks = new Map()
let worker
let taskId = 0
const spawn = () => {
worker = new Worker(__filename)
worker.on('message', function ({ id, signature }) {
const task = tasks.get(id)
tasks.delete(id)
if (tasks.size === 0) worker.unref()
task(signature)
})
}
const sign = (algorithm, data, key) => new Promise((resolve) => {
const id = taskId++
tasks.set(id, resolve)
if (worker === undefined) spawn()
worker.ref()
worker.postMessage({ id, algorithm, data, key })
})
;(async () => {
const { privateKey } = await generateKeyPair('ec', { namedCurve: 'secp256k1' })
const algorithm = 'sha256'
console.log(await sign(algorithm, Buffer.from('foo'), privateKey))
console.log(await sign(algorithm, Buffer.from('bar'), privateKey))
})().catch((err) => {
process.exitCode = 1
if (worker) worker.unref()
console.error(err)
})
} else {
const { sign, KeyObject } = crypto
let inst
parentPort.on('message', ({ id, algorithm, data, key }) => {
// required
assert.ok(key instanceof KeyObject, 'expect key to be an instance of KeyObject')
// optional
{
if (!inst) {
inst = key
}
assert.equal(inst, key) // this will pass on task id 0 but fail on task id 1
}
parentPort.postMessage({ id, signature: sign(algorithm, data, key) })
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment