-
-
Notifications
You must be signed in to change notification settings - Fork 80
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Is there a way to make it non-blocking? #96
Comments
I resolved this using custom service worker with WASM. First, you need webpack or other bundler to bundle everything into single js file in service worker. Then install argon2-browser and use this code: import argon2 from 'argon2-browser'
const crypto_pwhash_SALTBYTES = 16
const crypto_pwhash_MEMLIMIT_MODERATE = 268435456
const crypto_pwhash_OPSLIMIT_MODERATE = 3
const crypto_aead_xchacha20poly1305_ietf_KEYBYTES = 32
const channel = new BroadcastChannel('sw-messages')
self.addEventListener('message', async event => {
if(typeof event.data === 'object') {
if (event.data.type === 'hash' && 'plain' in event.data) {
const OLD_ENC_SALT = new Uint8Array(crypto_pwhash_SALTBYTES)
const result = await argon2.hash({
pass: event.data.plain,
salt: OLD_ENC_SALT,
time: crypto_pwhash_OPSLIMIT_MODERATE,
mem: crypto_pwhash_MEMLIMIT_MODERATE / 1024,
hashLen: crypto_aead_xchacha20poly1305_ietf_KEYBYTES,
parallelism: 1,
type: argon2.ArgonType.Argon2id
})
channel.postMessage({ type: 'hash_result', result, plain: event.data.plain })
}
}
}) Then build it into single file, import with service worker and you can use it like this on your website: const hashChannel = new BroadcastChannel('sw-messages')
const plain = 'what you want to hash goes here'
const sw = navigator.serviceWorker.controller
if (!sw) return console.error('Service Worker not ready')
sw.postMessage({ type: 'hash', plain })
const subscription = (event: MessageEvent<{ type: 'hash_result', result: import('argon2-browser').Argon2BrowserHashResult, plain: string }>) => {
if (
typeof event.data === 'object'
&& event.data.type === 'hash_result'
&& 'result' in event.data
&& event.data.plain === plain
) {
hashChannel.removeEventListener('message', subscription)
resolve(event.data.result.hash)
}
}
hashChannel.addEventListener('message', subscription) |
Oh and this is the config I used for webpack to correctly bundle wasm: /* eslint-disable @typescript-eslint/no-var-requires */
const path = require('path')
const { IgnorePlugin } = require('webpack')
/** @type {import('webpack').Configuration} */
const config = {
mode: 'production',
entry: __dirname + '/index.ts',
output: {
path: path.resolve(__dirname, '../public'),
filename: 'custom-worker.js'
},
module: {
rules: [
{
test: /\.wasm$/,
type: 'javascript/auto',
use: [{
loader: 'base64-loader'
}]
}
],
noParse: /\.wasm$/
},
plugins: [
new IgnorePlugin({ resourceRegExp: /\/__tests__\// })
],
resolve: {
fallback: {
path: require.resolve('path-browserify'),
fs: false
}
}
}
module.exports = config |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
When using crypto_pwhash_MEMLIMIT_MODERATE/1024 memory (256 MiB), 3 iterations, it takes more than a second to hash and while it hashing, render loop is blocked and page is frozen
I'm using service worker anyway, maybe use that here?
The text was updated successfully, but these errors were encountered: