From 92bea299c6dfe6b757ba27325b1f90bbaa217aba Mon Sep 17 00:00:00 2001 From: Emil Bay Date: Tue, 11 Apr 2017 22:19:34 +0200 Subject: [PATCH 01/17] Add sodium-test script --- package.json | 4 +++- test.js | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 test.js diff --git a/package.json b/package.json index 8910f28..15fa6a4 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,9 @@ "dependencies": { "blakejs": "^1.0.1" }, - "devDependencies": {}, + "devDependencies": { + "sodium-test": "^0.1.0" + }, "repository": { "type": "git", "url": "https://github.com/mafintosh/sodium-javascript.git" diff --git a/test.js b/test.js new file mode 100644 index 0000000..2a1cdcd --- /dev/null +++ b/test.js @@ -0,0 +1 @@ +require('sodium-test')('.') From f639c1ce6f56fff6903154b7257b10e58c405f2f Mon Sep 17 00:00:00 2001 From: Emil Bay Date: Thu, 13 Apr 2017 17:59:36 +0200 Subject: [PATCH 02/17] Fix sodium-test require --- test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test.js b/test.js index 2a1cdcd..f40a397 100644 --- a/test.js +++ b/test.js @@ -1 +1 @@ -require('sodium-test')('.') +require('sodium-test')(require('.')) From 5397910bbb31c34193a56ba50830d945edfe1362 Mon Sep 17 00:00:00 2001 From: Emil Bay Date: Tue, 6 Jun 2017 21:04:36 +0200 Subject: [PATCH 03/17] Add blake2b for generichash --- crypto_generichash.js | 27 +++++++++++++++++++++++++++ index.js | 32 ++++++++------------------------ package.json | 4 ++-- 3 files changed, 37 insertions(+), 26 deletions(-) create mode 100644 crypto_generichash.js diff --git a/crypto_generichash.js b/crypto_generichash.js new file mode 100644 index 0000000..2c3bf89 --- /dev/null +++ b/crypto_generichash.js @@ -0,0 +1,27 @@ +var assert = require('assert') +var blake2b = require('blake2b') + +module.exports.crypto_generichash_PRIMITIVE = 'blake2b' +module.exports.crypto_generichash_BYTES_MIN = blake2b.BYTES_MIN +module.exports.crypto_generichash_BYTES_MAX = blake2b.BYTES_MAX +module.exports.crypto_generichash_BYTES = blake2b.BYTES +module.exports.crypto_generichash_KEYBYTES_MIN = blake2b.KEYBYTES_MIN +module.exports.crypto_generichash_KEYBYTES_MAX = blake2b.KEYBYTES_MAX +module.exports.crypto_generichash_KEYBYTES = blake2b.KEYBYTES + +module.exports.crypto_generichash = function (output, input, key) { + blake2b(output, input, key) +} + +module.exports.crypto_generichash_batch = function (output, inputArray, key) { + var ctx = blake2b.instance(output.length, key) + for (var i = 0; i < inputArray.length; i++) { + ctx.update(inputArray[i]) + } + ctx.final(output) +} + +module.exports.crypto_generichash_instance = function (key, outlen) { + if (outlen == null) outlen = module.exports.crypto_generichash_BYTES + return blake2b.instance(outlen, key) +} diff --git a/index.js b/index.js index 8cc07dc..c9189fe 100644 --- a/index.js +++ b/index.js @@ -2162,21 +2162,6 @@ function crypto_secretbox_open_easy(msg, box, n, k) { return true } -var blake2b = require('blakejs/blake2b') - -function crypto_generichash (out, data, key) { - var tmp = blake2b.blake2b(data, key, out.length) - for (var i = 0; i < tmp.length; i++) out[i] = tmp[i] -} - -function crypto_generichash_batch (out, batch, key) { - var i = 0 - var ctx = blake2b.blake2bInit(out.length, key) - for (i = 0; i < batch.length; i++) blake2b.blake2bUpdate(ctx, batch[i]) - var tmp = blake2b.blake2bFinal(ctx) - for (var i = 0; i < tmp.length; i++) out[i] = tmp[i] -} - var crypto_secretbox_KEYBYTES = 32, crypto_secretbox_NONCEBYTES = 24, crypto_secretbox_ZEROBYTES = 32, @@ -2208,6 +2193,8 @@ sodium.crypto_sign_open = crypto_sign_open sodium.crypto_sign_detached = crypto_sign_detached sodium.crypto_sign_verify_detached = crypto_sign_verify_detached +forward(require('./crypto_generichash')) + sodium.crypto_stream_KEYBYTES = 32 sodium.crypto_stream_NONCEBYTES = 24 sodium.crypto_stream = crypto_stream_wrap @@ -2224,15 +2211,6 @@ sodium.crypto_secretbox_MACBYTES = 16 sodium.crypto_secretbox_easy = crypto_secretbox_easy sodium.crypto_secretbox_open_easy = crypto_secretbox_open_easy -sodium.crypto_generichash_BYTES_MIN = 16 -sodium.crypto_generichash_BYTES_MAX = 64 -sodium.crypto_generichash_BYTES = 32 -sodium.crypto_generichash_KEYBYTES_MIN = 16 -sodium.crypto_generichash_KEYBYTES_MAX = 64 -sodium.crypto_generichash_KEYBYTES = 32 -sodium.crypto_generichash = crypto_generichash -sodium.crypto_generichash_batch = crypto_generichash_batch - function cleanup(arr) { for (var i = 0; i < arr.length; i++) arr[i] = 0; } @@ -2241,6 +2219,12 @@ function check (buf, len) { if (!buf || (len && buf.length < len)) throw new Error('Argument must be a buffer' + (len ? ' of length ' + len : '')) } +function forward (submodule) { + Object.keys(submodule).forEach(function (prop) { + module.exports[prop] = submodule[prop] + }) +} + (function() { // Initialize PRNG if environment provides CSPRNG. // If not, methods calling randombytes will throw. diff --git a/package.json b/package.json index 15fa6a4..e90ef6e 100644 --- a/package.json +++ b/package.json @@ -4,10 +4,10 @@ "description": "WIP - a pure javascript version of sodium-native", "main": "index.js", "dependencies": { - "blakejs": "^1.0.1" + "blake2b": "^1.2.0" }, "devDependencies": { - "sodium-test": "^0.1.0" + "sodium-test": "^0.2.0" }, "repository": { "type": "git", From 226ecd8778d51d92a9181b0469fbbda39d79fbd2 Mon Sep 17 00:00:00 2001 From: Emil Bay Date: Tue, 6 Jun 2017 21:04:50 +0200 Subject: [PATCH 04/17] Add memzero --- index.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/index.js b/index.js index c9189fe..9e7624c 100644 --- a/index.js +++ b/index.js @@ -2180,6 +2180,10 @@ var crypto_secretbox_KEYBYTES = 32, crypto_sign_SEEDBYTES = 32, crypto_hash_BYTES = 64; +sodium.memzero = function (len, offset) { + for (var i = offset; i < len; i++) arr[i] = 0; +} + sodium.randombytes_buf = randombytes_buf sodium.crypto_sign_BYTES = crypto_sign_BYTES From afa3b5fc0479f462cbf45847bcf2ef7adde074d4 Mon Sep 17 00:00:00 2001 From: Emil Bay Date: Tue, 6 Jun 2017 21:05:48 +0200 Subject: [PATCH 05/17] 0.1.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e90ef6e..dfb00de 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sodium-javascript", - "version": "0.0.1", + "version": "0.1.0", "description": "WIP - a pure javascript version of sodium-native", "main": "index.js", "dependencies": { From 94e3891f674c5ec3d6462ddabf91f176af0cbb7f Mon Sep 17 00:00:00 2001 From: Emil Bay Date: Wed, 7 Jun 2017 22:38:40 +0200 Subject: [PATCH 06/17] Added crypto_kdf --- crypto_kdf.js | 37 +++++++++++++++++++++++++++++++++++++ index.js | 1 + package.json | 2 +- 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 crypto_kdf.js diff --git a/crypto_kdf.js b/crypto_kdf.js new file mode 100644 index 0000000..1536250 --- /dev/null +++ b/crypto_kdf.js @@ -0,0 +1,37 @@ +var assert = require('assert') +var randombytes_buf = require('.').randombytes_buf +var blake2b = require('blake2b') + +module.exports.crypto_kdf_PRIMITIVE = 'blake2b' +module.exports.crypto_kdf_BYTES_MIN = 16 +module.exports.crypto_kdf_BYTES_MAX = 64 +module.exports.crypto_kdf_CONTEXTBYTES = 8 +module.exports.crypto_kdf_KEYBYTES = 64 + +function STORE64_LE(dest, int) { + var mul = 1 + var i = 0 + dest[0] = int & 0xFF + while (++i < 8 && (mul *= 0x100)) { + dest[i] = (int / mul) & 0xFF + } +} + +module.exports.crypto_kdf_derive_from_key = function crypto_kdf_derive_from_key (subkey, subkey_id, ctx, key) { + assert(subkey.length >= module.exports.crypto_kdf_BYTES_MIN, 'subkey must be') + assert(ctx.length >= module.exports.crypto_kdf_CONTEXTBYTES, 'context must be') + + var ctx_padded = new Uint8Array(blake2b.PERSONALBYTES) + var salt = new Uint8Array(blake2b.SALTBYTES) + + ctx_padded.set(ctx, 0, module.exports.crypto_kdf_CONTEXTBYTES) + + STORE64_LE(salt, subkey_id) + + blake2b(subkey.slice(0, Math.min(subkey.length, module.exports.crypto_kdf_BYTES_MAX)), [], key, salt, ctx_padded, true) +} + +module.exports.crypto_kdf_keygen = function crypto_kdf_keygen (out) { + assert(out.length >= module.exports.crypto_kdf_KEYBYTES) + randombytes_buf(out, module.exports.crypto_kdf_KEYBYTES) +} diff --git a/index.js b/index.js index 9e7624c..98b818f 100644 --- a/index.js +++ b/index.js @@ -2198,6 +2198,7 @@ sodium.crypto_sign_detached = crypto_sign_detached sodium.crypto_sign_verify_detached = crypto_sign_verify_detached forward(require('./crypto_generichash')) +forward(require('./crypto_kdf')) sodium.crypto_stream_KEYBYTES = 32 sodium.crypto_stream_NONCEBYTES = 24 diff --git a/package.json b/package.json index dfb00de..27b279a 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "blake2b": "^1.2.0" }, "devDependencies": { - "sodium-test": "^0.2.0" + "sodium-test": "^0.3.0" }, "repository": { "type": "git", From 56913733b9a13271ff11973b76b095fb7a5d350d Mon Sep 17 00:00:00 2001 From: Emil Bay Date: Wed, 7 Jun 2017 22:39:24 +0200 Subject: [PATCH 07/17] 0.2.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 27b279a..647277f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sodium-javascript", - "version": "0.1.0", + "version": "0.2.0", "description": "WIP - a pure javascript version of sodium-native", "main": "index.js", "dependencies": { From 776ffea91c3a3e58dd4162c208e373fa2605e853 Mon Sep 17 00:00:00 2001 From: Emil Bay Date: Sun, 11 Jun 2017 10:44:02 +0200 Subject: [PATCH 08/17] Fix keygen overflow bug --- crypto_kdf.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto_kdf.js b/crypto_kdf.js index 1536250..1fef3ea 100644 --- a/crypto_kdf.js +++ b/crypto_kdf.js @@ -33,5 +33,5 @@ module.exports.crypto_kdf_derive_from_key = function crypto_kdf_derive_from_key module.exports.crypto_kdf_keygen = function crypto_kdf_keygen (out) { assert(out.length >= module.exports.crypto_kdf_KEYBYTES) - randombytes_buf(out, module.exports.crypto_kdf_KEYBYTES) + randombytes_buf(out.subarray(0, module.exports.crypto_kdf_KEYBYTES)) } From 196702476682bd04e2979868f766a85f2714d7da Mon Sep 17 00:00:00 2001 From: Emil Bay Date: Sun, 11 Jun 2017 20:23:06 +0200 Subject: [PATCH 09/17] Update to new blake2b --- crypto_generichash.js | 6 +++--- crypto_kdf.js | 14 ++++++++------ package.json | 6 +++++- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/crypto_generichash.js b/crypto_generichash.js index 2c3bf89..ed699a2 100644 --- a/crypto_generichash.js +++ b/crypto_generichash.js @@ -10,11 +10,11 @@ module.exports.crypto_generichash_KEYBYTES_MAX = blake2b.KEYBYTES_MAX module.exports.crypto_generichash_KEYBYTES = blake2b.KEYBYTES module.exports.crypto_generichash = function (output, input, key) { - blake2b(output, input, key) + blake2b(output.length, key).update(input).final(output) } module.exports.crypto_generichash_batch = function (output, inputArray, key) { - var ctx = blake2b.instance(output.length, key) + var ctx = blake2b(output.length, key) for (var i = 0; i < inputArray.length; i++) { ctx.update(inputArray[i]) } @@ -23,5 +23,5 @@ module.exports.crypto_generichash_batch = function (output, inputArray, key) { module.exports.crypto_generichash_instance = function (key, outlen) { if (outlen == null) outlen = module.exports.crypto_generichash_BYTES - return blake2b.instance(outlen, key) + return blake2b(outlen, key) } diff --git a/crypto_kdf.js b/crypto_kdf.js index 1fef3ea..4aa945b 100644 --- a/crypto_kdf.js +++ b/crypto_kdf.js @@ -1,4 +1,4 @@ -var assert = require('assert') +var assert = require('nanoassert') var randombytes_buf = require('.').randombytes_buf var blake2b = require('blake2b') @@ -18,20 +18,22 @@ function STORE64_LE(dest, int) { } module.exports.crypto_kdf_derive_from_key = function crypto_kdf_derive_from_key (subkey, subkey_id, ctx, key) { - assert(subkey.length >= module.exports.crypto_kdf_BYTES_MIN, 'subkey must be') - assert(ctx.length >= module.exports.crypto_kdf_CONTEXTBYTES, 'context must be') + assert(subkey.length >= module.exports.crypto_kdf_BYTES_MIN, 'subkey must be at least crypto_kdf_BYTES_MIN') + assert(subkey_id >= 0 && subkey_id <= 0x1fffffffffffff, 'subkey_id must be safe integer') + assert(ctx.length >= module.exports.crypto_kdf_CONTEXTBYTES, 'context must be at least crypto_kdf_CONTEXTBYTES') var ctx_padded = new Uint8Array(blake2b.PERSONALBYTES) var salt = new Uint8Array(blake2b.SALTBYTES) ctx_padded.set(ctx, 0, module.exports.crypto_kdf_CONTEXTBYTES) - STORE64_LE(salt, subkey_id) - blake2b(subkey.slice(0, Math.min(subkey.length, module.exports.crypto_kdf_BYTES_MAX)), [], key, salt, ctx_padded, true) + var outlen = Math.min(subkey.length, module.exports.crypto_kdf_BYTES_MAX) + blake2b(outlen, key, salt, ctx_padded, true) + .final(subkey) } module.exports.crypto_kdf_keygen = function crypto_kdf_keygen (out) { - assert(out.length >= module.exports.crypto_kdf_KEYBYTES) + assert(out.length >= module.exports.crypto_kdf_KEYBYTES, 'out.length must be crypto_kdf_KEYBYTES') randombytes_buf(out.subarray(0, module.exports.crypto_kdf_KEYBYTES)) } diff --git a/package.json b/package.json index 647277f..a286be0 100644 --- a/package.json +++ b/package.json @@ -4,11 +4,15 @@ "description": "WIP - a pure javascript version of sodium-native", "main": "index.js", "dependencies": { - "blake2b": "^1.2.0" + "blake2b": "^2.1.1", + "nanoassert": "^1.0.0" }, "devDependencies": { "sodium-test": "^0.3.0" }, + "scripts": { + "test": " node test.js" + }, "repository": { "type": "git", "url": "https://github.com/mafintosh/sodium-javascript.git" From 95732bdd4f5662b3d577a07ed515fa6553653e6f Mon Sep 17 00:00:00 2001 From: Mathias Buus Date: Mon, 12 Jun 2017 10:05:49 +0200 Subject: [PATCH 10/17] add crypto_shorthash (#4) --- crypto_shorthash.js | 169 +++++++++++++++++++++ index.js | 1 + package.json | 9 +- wasm/siphash.wasm | Bin 0 -> 1194 bytes wasm/siphash.wat | 348 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 526 insertions(+), 1 deletion(-) create mode 100644 crypto_shorthash.js create mode 100644 wasm/siphash.wasm create mode 100644 wasm/siphash.wat diff --git a/crypto_shorthash.js b/crypto_shorthash.js new file mode 100644 index 0000000..6699605 --- /dev/null +++ b/crypto_shorthash.js @@ -0,0 +1,169 @@ +var fs = require('fs') +var toUint8Array = require('base64-to-uint8array') +var assert = require('nanoassert') + +var WASM = toUint8Array(fs.readFileSync(__dirname + '/wasm/siphash.wasm', 'base64')) +var mod +var mem +var rdy + +var BYTES = exports.crypto_shorthash_BYTES = 8 +var KEYBYTES = exports.crypto_shorthash_KEYBYTES = 16 +exports.crypto_shorthash_PRIMITIVE = 'siphash24' +exports.crypto_shorthash_WASM_SUPPORTED = typeof WebAssembly !== 'undefined' +exports.crypto_shorthash_WASM_LOADED = false +exports.crypto_shorthash_ready = ready +exports.crypto_shorthash = shorthash + +ready(function (err) { + if (!err) exports.crypto_shorthash_WASM_LOADED = true +}) + +function ready (cb) { + if (!cb) cb = noop + if (!exports.crypto_shorthash_WASM_SUPPORTED) return cb(new Error('WebAssembly not supported')) + if (!rdy) rdy = WebAssembly.instantiate(WASM).then(setup) + return rdy.then(cb).catch(cb) +} + +function shorthash (out, data, key, noAssert) { + if (noAssert !== true) { + assert(out.length >= BYTES, 'output must be at least crypto_shorthash_BYTES') + assert(key.length >= KEYBYTES, 'output must be at least crypto_shorthash_KEYBYTES') + } + + if (mod) { + mem.set(key, 8) + mem.set(data, 24) + mod.siphash(24, data.length) + out.set(mem.subarray(0, 8)) + } else { + fallback(out, data, key) + } +} + +function noop () {} + +function setup (w) { + mod = w.instance.exports + mem = new Uint8Array(w.instance.exports.siphash_memory.buffer) +} + +function _add(a, b) { + var rl = a.l + b.l + var a2 = { + h: a.h + b.h + (rl / 2 >>> 31) >>> 0, + l: rl >>> 0 + } + a.h = a2.h + a.l = a2.l +} + +function _xor(a, b) { + a.h ^= b.h + a.h >>>= 0 + a.l ^= b.l + a.l >>>= 0 +} + +function _rotl(a, n) { + var a2 = { + h: a.h << n | a.l >>> (32 - n), + l: a.l << n | a.h >>> (32 - n) + } + a.h = a2.h + a.l = a2.l +} + +function _rotl32(a) { + var al = a.l + a.l = a.h + a.h = al +} + +function _compress(v0, v1, v2, v3) { + _add(v0, v1) + _add(v2, v3) + _rotl(v1, 13) + _rotl(v3, 16) + _xor(v1, v0) + _xor(v3, v2) + _rotl32(v0) + _add(v2, v1) + _add(v0, v3) + _rotl(v1, 17) + _rotl(v3, 21) + _xor(v1, v2) + _xor(v3, v0) + _rotl32(v2) +} + +function _get_int(a, offset) { + return (a[offset + 3] << 24) | (a[offset + 2] << 16) | (a[offset + 1] << 8) | a[offset] +} + +function fallback (out, m, key) { // modified from https://github.com/jedisct1/siphash-js to use uint8arrays + var k0 = {h: _get_int(key, 4), l: _get_int(key, 0)} + var k1 = {h: _get_int(key, 12), l: _get_int(key, 8)} + var v0 = {h: k0.h, l: k0.l} + var v2 = k0 + var v1 = {h: k1.h, l: k1.l} + var v3 = k1 + var mi + var mp = 0 + var ml = m.length + var ml7 = ml - 7 + var buf = new Uint8Array(new ArrayBuffer(8)) + + _xor(v0, {h: 0x736f6d65, l: 0x70736575}) + _xor(v1, {h: 0x646f7261, l: 0x6e646f6d}) + _xor(v2, {h: 0x6c796765, l: 0x6e657261}) + _xor(v3, {h: 0x74656462, l: 0x79746573}) + + while (mp < ml7) { + mi = {h: _get_int(m, mp + 4), l: _get_int(m, mp)} + _xor(v3, mi) + _compress(v0, v1, v2, v3) + _compress(v0, v1, v2, v3) + _xor(v0, mi) + mp += 8 + } + + buf[7] = ml + var ic = 0 + while (mp < ml) { + buf[ic++] = m[mp++] + } + while (ic < 7) { + buf[ic++] = 0 + } + + mi = { + h: buf[7] << 24 | buf[6] << 16 | buf[5] << 8 | buf[4], + l: buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0] + } + + _xor(v3, mi) + _compress(v0, v1, v2, v3) + _compress(v0, v1, v2, v3) + _xor(v0, mi) + _xor(v2, { h: 0, l: 0xff }) + _compress(v0, v1, v2, v3) + _compress(v0, v1, v2, v3) + _compress(v0, v1, v2, v3) + _compress(v0, v1, v2, v3) + + var h = v0 + _xor(h, v1) + _xor(h, v2) + _xor(h, v3) + + out[0] = h.l & 0xff + out[1] = (h.l >> 8) & 0xff + out[2] = (h.l >> 16) & 0xff + out[3] = (h.l >> 24) & 0xff + out[4] = h.h & 0xff + out[5] = (h.h >> 8) & 0xff + out[6] = (h.h >> 16) & 0xff + out[7] = (h.h >> 24) & 0xff +} diff --git a/index.js b/index.js index 98b818f..c4b8ce1 100644 --- a/index.js +++ b/index.js @@ -2199,6 +2199,7 @@ sodium.crypto_sign_verify_detached = crypto_sign_verify_detached forward(require('./crypto_generichash')) forward(require('./crypto_kdf')) +forward(require('./crypto_shorthash')) sodium.crypto_stream_KEYBYTES = 32 sodium.crypto_stream_NONCEBYTES = 24 diff --git a/package.json b/package.json index a286be0..8525996 100644 --- a/package.json +++ b/package.json @@ -4,15 +4,22 @@ "description": "WIP - a pure javascript version of sodium-native", "main": "index.js", "dependencies": { + "base64-to-uint8array": "^1.0.0", "blake2b": "^2.1.1", + "brfs": "^1.4.3", "nanoassert": "^1.0.0" }, "devDependencies": { - "sodium-test": "^0.3.0" + "sodium-test": "^0.4.0" }, "scripts": { "test": " node test.js" }, + "browserify": { + "transform": [ + "brfs" + ] + }, "repository": { "type": "git", "url": "https://github.com/mafintosh/sodium-javascript.git" diff --git a/wasm/siphash.wasm b/wasm/siphash.wasm new file mode 100644 index 0000000000000000000000000000000000000000..c1c0cdeaa8030fe7b70e9c181773ebb335a0bb6f GIT binary patch literal 1194 zcmds$y-EW?5XWb~?lyNO#6qyJnC-OFO3U09zJ{g{VkG#HN(iRV3j}N|^c8Hhu}PCB zh+5bvK@o(M5sTAWXYa(r7Z3~!yUdUO{D;|{g=(|G0DyUHowwT{I0Gda3j%+RmztY9 zwQ94r*4Sul@9lH&zX3q-rrB6?eZbrHV{m);aPinnz;OHee3G2qJoQFkgnb#ECimlE ze+)+2WN>$VemuN-2csgrAi(%h*&Q0$rCsS54_V~znh*h59m6dXph6uRg%bVPNE9v- z$X&#FMN~)`tQHx9vni0e;M5#N%g|$3`@T6Dd`?8M30nSeF?xWc8-jf0hNOJ z9LN-44nzuObHGzj&H+n-{sB}X^;hUk&Q((@G#U1jxgnd3>G}6RAOiOi?!U%yyeuI6 E0%0Y{-~a#s literal 0 HcmV?d00001 diff --git a/wasm/siphash.wat b/wasm/siphash.wat new file mode 100644 index 0000000..fb9b322 --- /dev/null +++ b/wasm/siphash.wat @@ -0,0 +1,348 @@ +(module + (memory (export "siphash_memory") 10 10) + + (func (export "siphash") (param $ptr i32) (param $ptr_len i32) + (local $v0 i64) + (local $v1 i64) + (local $v2 i64) + (local $v3 i64) + (local $b i64) + (local $k0 i64) + (local $k1 i64) + (local $m i64) + (local $end i32) + (local $left i32) + + (set_local $v0 (i64.const 0x736f6d6570736575)) + (set_local $v1 (i64.const 0x646f72616e646f6d)) + (set_local $v2 (i64.const 0x6c7967656e657261)) + (set_local $v3 (i64.const 0x7465646279746573)) + + (set_local $k0 (i64.load (i32.const 8))) + (set_local $k1 (i64.load (i32.const 16))) + + ;; b = ((uint64_t) inlen) << 56; + (set_local $b (i64.shl (i64.extend_u/i32 (get_local $ptr_len)) (i64.const 56))) + + ;; left = inlen & 7; + (set_local $left (i32.and (get_local $ptr_len) (i32.const 7))) + + ;; end = in + inlen - left; + (set_local $end (i32.sub (i32.add (get_local $ptr) (get_local $ptr_len)) (get_local $left))) + + ;; v3 ^= k1; + (set_local $v3 (i64.xor (get_local $v3) (get_local $k1))) + + ;; v2 ^= k0; + (set_local $v2 (i64.xor (get_local $v2) (get_local $k0))) + + ;; v1 ^= k1; + (set_local $v1 (i64.xor (get_local $v1) (get_local $k1))) + + ;; v0 ^= k0; + (set_local $v0 (i64.xor (get_local $v0) (get_local $k0))) + + (block $end_loop + (loop $start_loop + (br_if $end_loop (i32.eq (get_local $ptr) (get_local $end))) + + ;; m = LOAD64_LE(in); + (set_local $m (i64.load (get_local $ptr))) + + ;; v3 ^= m + (set_local $v3 (i64.xor (get_local $v3) (get_local $m))) + + ;; SIPROUND + ;; v0 += v1; + (set_local $v0 (i64.add (get_local $v0) (get_local $v1))) + ;; v1 = ROTL64(v1, 13); + (set_local $v1 (i64.rotl (get_local $v1) (i64.const 13))) + ;; v1 ^= v0; + (set_local $v1 (i64.xor (get_local $v1) (get_local $v0))) + ;; v0 = ROTL64(v0, 32) + (set_local $v0 (i64.rotl (get_local $v0) (i64.const 32))) + ;; v2 += v3; + (set_local $v2 (i64.add (get_local $v2) (get_local $v3))) + ;; v3 = ROTL64(v3, 16); + (set_local $v3 (i64.rotl (get_local $v3) (i64.const 16))) + ;; v3 ^= v2; + (set_local $v3 (i64.xor (get_local $v3) (get_local $v2))) + ;; v0 += v3; + (set_local $v0 (i64.add (get_local $v0) (get_local $v3))) + ;; v3 = ROTL64(v3, 21); + (set_local $v3 (i64.rotl (get_local $v3) (i64.const 21))) + ;; v3 ^= v0; + (set_local $v3 (i64.xor (get_local $v3) (get_local $v0))) + ;; v2 += v1; + (set_local $v2 (i64.add (get_local $v2) (get_local $v1))) + ;; v1 = ROTL64(v1, 17); + (set_local $v1 (i64.rotl (get_local $v1) (i64.const 17))) + ;; v1 ^= v2; + (set_local $v1 (i64.xor (get_local $v1) (get_local $v2))) + ;; v2 = ROTL64(v2, 32); + (set_local $v2 (i64.rotl (get_local $v2) (i64.const 32))) + + ;; SIPROUND + ;; v0 += v1; + (set_local $v0 (i64.add (get_local $v0) (get_local $v1))) + ;; v1 = ROTL64(v1, 13); + (set_local $v1 (i64.rotl (get_local $v1) (i64.const 13))) + ;; v1 ^= v0; + (set_local $v1 (i64.xor (get_local $v1) (get_local $v0))) + ;; v0 = ROTL64(v0, 32) + (set_local $v0 (i64.rotl (get_local $v0) (i64.const 32))) + ;; v2 += v3; + (set_local $v2 (i64.add (get_local $v2) (get_local $v3))) + ;; v3 = ROTL64(v3, 16); + (set_local $v3 (i64.rotl (get_local $v3) (i64.const 16))) + ;; v3 ^= v2; + (set_local $v3 (i64.xor (get_local $v3) (get_local $v2))) + ;; v0 += v3; + (set_local $v0 (i64.add (get_local $v0) (get_local $v3))) + ;; v3 = ROTL64(v3, 21); + (set_local $v3 (i64.rotl (get_local $v3) (i64.const 21))) + ;; v3 ^= v0; + (set_local $v3 (i64.xor (get_local $v3) (get_local $v0))) + ;; v2 += v1; + (set_local $v2 (i64.add (get_local $v2) (get_local $v1))) + ;; v1 = ROTL64(v1, 17); + (set_local $v1 (i64.rotl (get_local $v1) (i64.const 17))) + ;; v1 ^= v2; + (set_local $v1 (i64.xor (get_local $v1) (get_local $v2))) + ;; v2 = ROTL64(v2, 32); + (set_local $v2 (i64.rotl (get_local $v2) (i64.const 32))) + + ;; v0 ^= m; + (set_local $v0 (i64.xor (get_local $v0) (get_local $m))) + + ;; ptr += 8 + (set_local $ptr (i32.add (get_local $ptr) (i32.const 8))) + (br $start_loop) + ) + ) + + (block $0 + (block $1 + (block $2 + (block $3 + (block $4 + (block $5 + (block $6 + (block $7 + (br_table $0 $1 $2 $3 $4 $5 $6 $7 (get_local $left)) + ) + ;; b |= ((uint64_t) in[6]) << 48; + (set_local $b (i64.or (get_local $b) (i64.shl (i64.load8_u (i32.add (get_local $ptr) (i32.const 6))) (i64.const 48)))) + ) + ;; b |= ((uint64_t) in[5]) << 40; + (set_local $b (i64.or (get_local $b) (i64.shl (i64.load8_u (i32.add (get_local $ptr) (i32.const 5))) (i64.const 40)))) + ) + ;; b |= ((uint64_t) in[4]) << 32; + (set_local $b (i64.or (get_local $b) (i64.shl (i64.load8_u (i32.add (get_local $ptr) (i32.const 4))) (i64.const 32)))) + ) + ;; b |= ((uint64_t) in[3]) << 24; + (set_local $b (i64.or (get_local $b) (i64.shl (i64.load8_u (i32.add (get_local $ptr) (i32.const 3))) (i64.const 24)))) + ) + ;; b |= ((uint64_t) in[2]) << 16; + (set_local $b (i64.or (get_local $b) (i64.shl (i64.load8_u (i32.add (get_local $ptr) (i32.const 2))) (i64.const 16)))) + ) + ;; b |= ((uint64_t) in[1]) << 8; + (set_local $b (i64.or (get_local $b) (i64.shl (i64.load8_u (i32.add (get_local $ptr) (i32.const 1))) (i64.const 8)))) + ) + ;; b |= ((uint64_t) in[0]); + (set_local $b (i64.or (get_local $b) (i64.load8_u (get_local $ptr)))) + ) + + ;; v3 ^= b; + (set_local $v3 (i64.xor (get_local $v3) (get_local $b))) + + ;; SIPROUND + ;; v0 += v1; + (set_local $v0 (i64.add (get_local $v0) (get_local $v1))) + ;; v1 = ROTL64(v1, 13); + (set_local $v1 (i64.rotl (get_local $v1) (i64.const 13))) + ;; v1 ^= v0; + (set_local $v1 (i64.xor (get_local $v1) (get_local $v0))) + ;; v0 = ROTL64(v0, 32) + (set_local $v0 (i64.rotl (get_local $v0) (i64.const 32))) + ;; v2 += v3; + (set_local $v2 (i64.add (get_local $v2) (get_local $v3))) + ;; v3 = ROTL64(v3, 16); + (set_local $v3 (i64.rotl (get_local $v3) (i64.const 16))) + ;; v3 ^= v2; + (set_local $v3 (i64.xor (get_local $v3) (get_local $v2))) + ;; v0 += v3; + (set_local $v0 (i64.add (get_local $v0) (get_local $v3))) + ;; v3 = ROTL64(v3, 21); + (set_local $v3 (i64.rotl (get_local $v3) (i64.const 21))) + ;; v3 ^= v0; + (set_local $v3 (i64.xor (get_local $v3) (get_local $v0))) + ;; v2 += v1; + (set_local $v2 (i64.add (get_local $v2) (get_local $v1))) + ;; v1 = ROTL64(v1, 17); + (set_local $v1 (i64.rotl (get_local $v1) (i64.const 17))) + ;; v1 ^= v2; + (set_local $v1 (i64.xor (get_local $v1) (get_local $v2))) + ;; v2 = ROTL64(v2, 32); + (set_local $v2 (i64.rotl (get_local $v2) (i64.const 32))) + + ;; SIPROUND + ;; v0 += v1; + (set_local $v0 (i64.add (get_local $v0) (get_local $v1))) + ;; v1 = ROTL64(v1, 13); + (set_local $v1 (i64.rotl (get_local $v1) (i64.const 13))) + ;; v1 ^= v0; + (set_local $v1 (i64.xor (get_local $v1) (get_local $v0))) + ;; v0 = ROTL64(v0, 32) + (set_local $v0 (i64.rotl (get_local $v0) (i64.const 32))) + ;; v2 += v3; + (set_local $v2 (i64.add (get_local $v2) (get_local $v3))) + ;; v3 = ROTL64(v3, 16); + (set_local $v3 (i64.rotl (get_local $v3) (i64.const 16))) + ;; v3 ^= v2; + (set_local $v3 (i64.xor (get_local $v3) (get_local $v2))) + ;; v0 += v3; + (set_local $v0 (i64.add (get_local $v0) (get_local $v3))) + ;; v3 = ROTL64(v3, 21); + (set_local $v3 (i64.rotl (get_local $v3) (i64.const 21))) + ;; v3 ^= v0; + (set_local $v3 (i64.xor (get_local $v3) (get_local $v0))) + ;; v2 += v1; + (set_local $v2 (i64.add (get_local $v2) (get_local $v1))) + ;; v1 = ROTL64(v1, 17); + (set_local $v1 (i64.rotl (get_local $v1) (i64.const 17))) + ;; v1 ^= v2; + (set_local $v1 (i64.xor (get_local $v1) (get_local $v2))) + ;; v2 = ROTL64(v2, 32); + (set_local $v2 (i64.rotl (get_local $v2) (i64.const 32))) + + ;; v0 ^= b; + (set_local $v0 (i64.xor (get_local $v0) (get_local $b))) + + ;; v2 ^= 0xff; + (set_local $v2 (i64.xor (get_local $v2) (i64.const 0xff))) + + ;; SIPROUND + ;; v0 += v1; + (set_local $v0 (i64.add (get_local $v0) (get_local $v1))) + ;; v1 = ROTL64(v1, 13); + (set_local $v1 (i64.rotl (get_local $v1) (i64.const 13))) + ;; v1 ^= v0; + (set_local $v1 (i64.xor (get_local $v1) (get_local $v0))) + ;; v0 = ROTL64(v0, 32) + (set_local $v0 (i64.rotl (get_local $v0) (i64.const 32))) + ;; v2 += v3; + (set_local $v2 (i64.add (get_local $v2) (get_local $v3))) + ;; v3 = ROTL64(v3, 16); + (set_local $v3 (i64.rotl (get_local $v3) (i64.const 16))) + ;; v3 ^= v2; + (set_local $v3 (i64.xor (get_local $v3) (get_local $v2))) + ;; v0 += v3; + (set_local $v0 (i64.add (get_local $v0) (get_local $v3))) + ;; v3 = ROTL64(v3, 21); + (set_local $v3 (i64.rotl (get_local $v3) (i64.const 21))) + ;; v3 ^= v0; + (set_local $v3 (i64.xor (get_local $v3) (get_local $v0))) + ;; v2 += v1; + (set_local $v2 (i64.add (get_local $v2) (get_local $v1))) + ;; v1 = ROTL64(v1, 17); + (set_local $v1 (i64.rotl (get_local $v1) (i64.const 17))) + ;; v1 ^= v2; + (set_local $v1 (i64.xor (get_local $v1) (get_local $v2))) + ;; v2 = ROTL64(v2, 32); + (set_local $v2 (i64.rotl (get_local $v2) (i64.const 32))) + + ;; SIPROUND + ;; v0 += v1; + (set_local $v0 (i64.add (get_local $v0) (get_local $v1))) + ;; v1 = ROTL64(v1, 13); + (set_local $v1 (i64.rotl (get_local $v1) (i64.const 13))) + ;; v1 ^= v0; + (set_local $v1 (i64.xor (get_local $v1) (get_local $v0))) + ;; v0 = ROTL64(v0, 32) + (set_local $v0 (i64.rotl (get_local $v0) (i64.const 32))) + ;; v2 += v3; + (set_local $v2 (i64.add (get_local $v2) (get_local $v3))) + ;; v3 = ROTL64(v3, 16); + (set_local $v3 (i64.rotl (get_local $v3) (i64.const 16))) + ;; v3 ^= v2; + (set_local $v3 (i64.xor (get_local $v3) (get_local $v2))) + ;; v0 += v3; + (set_local $v0 (i64.add (get_local $v0) (get_local $v3))) + ;; v3 = ROTL64(v3, 21); + (set_local $v3 (i64.rotl (get_local $v3) (i64.const 21))) + ;; v3 ^= v0; + (set_local $v3 (i64.xor (get_local $v3) (get_local $v0))) + ;; v2 += v1; + (set_local $v2 (i64.add (get_local $v2) (get_local $v1))) + ;; v1 = ROTL64(v1, 17); + (set_local $v1 (i64.rotl (get_local $v1) (i64.const 17))) + ;; v1 ^= v2; + (set_local $v1 (i64.xor (get_local $v1) (get_local $v2))) + ;; v2 = ROTL64(v2, 32); + (set_local $v2 (i64.rotl (get_local $v2) (i64.const 32))) + + ;; SIPROUND + ;; v0 += v1; + (set_local $v0 (i64.add (get_local $v0) (get_local $v1))) + ;; v1 = ROTL64(v1, 13); + (set_local $v1 (i64.rotl (get_local $v1) (i64.const 13))) + ;; v1 ^= v0; + (set_local $v1 (i64.xor (get_local $v1) (get_local $v0))) + ;; v0 = ROTL64(v0, 32) + (set_local $v0 (i64.rotl (get_local $v0) (i64.const 32))) + ;; v2 += v3; + (set_local $v2 (i64.add (get_local $v2) (get_local $v3))) + ;; v3 = ROTL64(v3, 16); + (set_local $v3 (i64.rotl (get_local $v3) (i64.const 16))) + ;; v3 ^= v2; + (set_local $v3 (i64.xor (get_local $v3) (get_local $v2))) + ;; v0 += v3; + (set_local $v0 (i64.add (get_local $v0) (get_local $v3))) + ;; v3 = ROTL64(v3, 21); + (set_local $v3 (i64.rotl (get_local $v3) (i64.const 21))) + ;; v3 ^= v0; + (set_local $v3 (i64.xor (get_local $v3) (get_local $v0))) + ;; v2 += v1; + (set_local $v2 (i64.add (get_local $v2) (get_local $v1))) + ;; v1 = ROTL64(v1, 17); + (set_local $v1 (i64.rotl (get_local $v1) (i64.const 17))) + ;; v1 ^= v2; + (set_local $v1 (i64.xor (get_local $v1) (get_local $v2))) + ;; v2 = ROTL64(v2, 32); + (set_local $v2 (i64.rotl (get_local $v2) (i64.const 32))) + + ;; SIPROUND + ;; v0 += v1; + (set_local $v0 (i64.add (get_local $v0) (get_local $v1))) + ;; v1 = ROTL64(v1, 13); + (set_local $v1 (i64.rotl (get_local $v1) (i64.const 13))) + ;; v1 ^= v0; + (set_local $v1 (i64.xor (get_local $v1) (get_local $v0))) + ;; v0 = ROTL64(v0, 32) + (set_local $v0 (i64.rotl (get_local $v0) (i64.const 32))) + ;; v2 += v3; + (set_local $v2 (i64.add (get_local $v2) (get_local $v3))) + ;; v3 = ROTL64(v3, 16); + (set_local $v3 (i64.rotl (get_local $v3) (i64.const 16))) + ;; v3 ^= v2; + (set_local $v3 (i64.xor (get_local $v3) (get_local $v2))) + ;; v0 += v3; + (set_local $v0 (i64.add (get_local $v0) (get_local $v3))) + ;; v3 = ROTL64(v3, 21); + (set_local $v3 (i64.rotl (get_local $v3) (i64.const 21))) + ;; v3 ^= v0; + (set_local $v3 (i64.xor (get_local $v3) (get_local $v0))) + ;; v2 += v1; + (set_local $v2 (i64.add (get_local $v2) (get_local $v1))) + ;; v1 = ROTL64(v1, 17); + (set_local $v1 (i64.rotl (get_local $v1) (i64.const 17))) + ;; v1 ^= v2; + (set_local $v1 (i64.xor (get_local $v1) (get_local $v2))) + ;; v2 = ROTL64(v2, 32); + (set_local $v2 (i64.rotl (get_local $v2) (i64.const 32))) + + ;; b = v0 ^ v1 ^ v2 ^ v3; + (i64.store (i32.const 0) (i64.xor (get_local $v0) (i64.xor (get_local $v1) (i64.xor (get_local $v2) (get_local $v3))))) + ) +) From 51875f2288a6afa08472027575bfc1163ec078d6 Mon Sep 17 00:00:00 2001 From: Mathias Buus Date: Mon, 12 Jun 2017 10:08:46 +0200 Subject: [PATCH 11/17] remove unused assert --- crypto_generichash.js | 1 - 1 file changed, 1 deletion(-) diff --git a/crypto_generichash.js b/crypto_generichash.js index ed699a2..b347aff 100644 --- a/crypto_generichash.js +++ b/crypto_generichash.js @@ -1,4 +1,3 @@ -var assert = require('assert') var blake2b = require('blake2b') module.exports.crypto_generichash_PRIMITIVE = 'blake2b' From 78f7c7111c5c1bb4ddc51f915be0611fb36e5418 Mon Sep 17 00:00:00 2001 From: Mathias Buus Date: Mon, 12 Jun 2017 10:15:52 +0200 Subject: [PATCH 12/17] add wasm info --- crypto_generichash.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/crypto_generichash.js b/crypto_generichash.js index b347aff..cf7694a 100644 --- a/crypto_generichash.js +++ b/crypto_generichash.js @@ -7,11 +7,16 @@ module.exports.crypto_generichash_BYTES = blake2b.BYTES module.exports.crypto_generichash_KEYBYTES_MIN = blake2b.KEYBYTES_MIN module.exports.crypto_generichash_KEYBYTES_MAX = blake2b.KEYBYTES_MAX module.exports.crypto_generichash_KEYBYTES = blake2b.KEYBYTES +module.exports.crypto_generichash_WASM_SUPPORTED = blake2b.WASM_SUPPORTED +module.exports.crypto_generichash_WASM_LOADED = false + module.exports.crypto_generichash = function (output, input, key) { blake2b(output.length, key).update(input).final(output) } +module.exports.crypto_generichash_ready = blake2b.ready + module.exports.crypto_generichash_batch = function (output, inputArray, key) { var ctx = blake2b(output.length, key) for (var i = 0; i < inputArray.length; i++) { @@ -24,3 +29,7 @@ module.exports.crypto_generichash_instance = function (key, outlen) { if (outlen == null) outlen = module.exports.crypto_generichash_BYTES return blake2b(outlen, key) } + +blake2b.ready(function (err) { + if (blake2b.WASM_SUPPORTED) module.exports.crypto_generichash_WASM_LOADED = !err +}) From d546f63e1196c288675b3d5d92c38ba649cc664b Mon Sep 17 00:00:00 2001 From: Mathias Buus Date: Mon, 12 Jun 2017 10:19:02 +0200 Subject: [PATCH 13/17] 0.3.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8525996..35781c6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sodium-javascript", - "version": "0.2.0", + "version": "0.3.0", "description": "WIP - a pure javascript version of sodium-native", "main": "index.js", "dependencies": { From a22454f86fd314d10f075f0880b3d8468ffdd083 Mon Sep 17 00:00:00 2001 From: Mathias Buus Date: Mon, 12 Jun 2017 10:29:16 +0200 Subject: [PATCH 14/17] simply wasm loaded logic --- crypto_generichash.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto_generichash.js b/crypto_generichash.js index cf7694a..fd02502 100644 --- a/crypto_generichash.js +++ b/crypto_generichash.js @@ -31,5 +31,5 @@ module.exports.crypto_generichash_instance = function (key, outlen) { } blake2b.ready(function (err) { - if (blake2b.WASM_SUPPORTED) module.exports.crypto_generichash_WASM_LOADED = !err + module.exports.crypto_generichash_WASM_LOADED = blake2b.WASM_LOADED }) From 33befeb87a10a5854129de6e0bb377aaf6f9154c Mon Sep 17 00:00:00 2001 From: Mathias Buus Date: Mon, 12 Jun 2017 10:31:43 +0200 Subject: [PATCH 15/17] cleanup newlines --- crypto_generichash.js | 1 - 1 file changed, 1 deletion(-) diff --git a/crypto_generichash.js b/crypto_generichash.js index fd02502..36b9111 100644 --- a/crypto_generichash.js +++ b/crypto_generichash.js @@ -10,7 +10,6 @@ module.exports.crypto_generichash_KEYBYTES = blake2b.KEYBYTES module.exports.crypto_generichash_WASM_SUPPORTED = blake2b.WASM_SUPPORTED module.exports.crypto_generichash_WASM_LOADED = false - module.exports.crypto_generichash = function (output, input, key) { blake2b(output.length, key).update(input).final(output) } From de8639f558b47d1d96609c03af8be8d14d420f07 Mon Sep 17 00:00:00 2001 From: Mathias Buus Date: Mon, 12 Jun 2017 11:01:21 +0200 Subject: [PATCH 16/17] use siphash24 --- crypto_shorthash.js | 170 ++-------------------- package.json | 5 +- wasm/siphash.wasm | Bin 1194 -> 0 bytes wasm/siphash.wat | 348 -------------------------------------------- 4 files changed, 11 insertions(+), 512 deletions(-) delete mode 100644 wasm/siphash.wasm delete mode 100644 wasm/siphash.wat diff --git a/crypto_shorthash.js b/crypto_shorthash.js index 6699605..5563f89 100644 --- a/crypto_shorthash.js +++ b/crypto_shorthash.js @@ -1,169 +1,17 @@ -var fs = require('fs') -var toUint8Array = require('base64-to-uint8array') -var assert = require('nanoassert') +var siphash = require('siphash24') -var WASM = toUint8Array(fs.readFileSync(__dirname + '/wasm/siphash.wasm', 'base64')) -var mod -var mem -var rdy - -var BYTES = exports.crypto_shorthash_BYTES = 8 -var KEYBYTES = exports.crypto_shorthash_KEYBYTES = 16 exports.crypto_shorthash_PRIMITIVE = 'siphash24' -exports.crypto_shorthash_WASM_SUPPORTED = typeof WebAssembly !== 'undefined' -exports.crypto_shorthash_WASM_LOADED = false -exports.crypto_shorthash_ready = ready +exports.crypto_shorthash_BYTES = siphash.BYTES +exports.crypto_shorthash_KEYBYTES = siphash.KEYBYTES +exports.crypto_shorthash_WASM_SUPPORTED = siphash.WASM_SUPPORTED +exports.crypto_shorthash_WASM_LOADED = siphash.WASM_LOADED +exports.crypto_shorthash_ready = siphash.ready exports.crypto_shorthash = shorthash -ready(function (err) { - if (!err) exports.crypto_shorthash_WASM_LOADED = true +siphash.ready(function () { + exports.crypto_shorthash_WASM_LOADED = siphash.WASM_LOADED }) -function ready (cb) { - if (!cb) cb = noop - if (!exports.crypto_shorthash_WASM_SUPPORTED) return cb(new Error('WebAssembly not supported')) - if (!rdy) rdy = WebAssembly.instantiate(WASM).then(setup) - return rdy.then(cb).catch(cb) -} - function shorthash (out, data, key, noAssert) { - if (noAssert !== true) { - assert(out.length >= BYTES, 'output must be at least crypto_shorthash_BYTES') - assert(key.length >= KEYBYTES, 'output must be at least crypto_shorthash_KEYBYTES') - } - - if (mod) { - mem.set(key, 8) - mem.set(data, 24) - mod.siphash(24, data.length) - out.set(mem.subarray(0, 8)) - } else { - fallback(out, data, key) - } -} - -function noop () {} - -function setup (w) { - mod = w.instance.exports - mem = new Uint8Array(w.instance.exports.siphash_memory.buffer) -} - -function _add(a, b) { - var rl = a.l + b.l - var a2 = { - h: a.h + b.h + (rl / 2 >>> 31) >>> 0, - l: rl >>> 0 - } - a.h = a2.h - a.l = a2.l -} - -function _xor(a, b) { - a.h ^= b.h - a.h >>>= 0 - a.l ^= b.l - a.l >>>= 0 -} - -function _rotl(a, n) { - var a2 = { - h: a.h << n | a.l >>> (32 - n), - l: a.l << n | a.h >>> (32 - n) - } - a.h = a2.h - a.l = a2.l -} - -function _rotl32(a) { - var al = a.l - a.l = a.h - a.h = al -} - -function _compress(v0, v1, v2, v3) { - _add(v0, v1) - _add(v2, v3) - _rotl(v1, 13) - _rotl(v3, 16) - _xor(v1, v0) - _xor(v3, v2) - _rotl32(v0) - _add(v2, v1) - _add(v0, v3) - _rotl(v1, 17) - _rotl(v3, 21) - _xor(v1, v2) - _xor(v3, v0) - _rotl32(v2) -} - -function _get_int(a, offset) { - return (a[offset + 3] << 24) | (a[offset + 2] << 16) | (a[offset + 1] << 8) | a[offset] -} - -function fallback (out, m, key) { // modified from https://github.com/jedisct1/siphash-js to use uint8arrays - var k0 = {h: _get_int(key, 4), l: _get_int(key, 0)} - var k1 = {h: _get_int(key, 12), l: _get_int(key, 8)} - var v0 = {h: k0.h, l: k0.l} - var v2 = k0 - var v1 = {h: k1.h, l: k1.l} - var v3 = k1 - var mi - var mp = 0 - var ml = m.length - var ml7 = ml - 7 - var buf = new Uint8Array(new ArrayBuffer(8)) - - _xor(v0, {h: 0x736f6d65, l: 0x70736575}) - _xor(v1, {h: 0x646f7261, l: 0x6e646f6d}) - _xor(v2, {h: 0x6c796765, l: 0x6e657261}) - _xor(v3, {h: 0x74656462, l: 0x79746573}) - - while (mp < ml7) { - mi = {h: _get_int(m, mp + 4), l: _get_int(m, mp)} - _xor(v3, mi) - _compress(v0, v1, v2, v3) - _compress(v0, v1, v2, v3) - _xor(v0, mi) - mp += 8 - } - - buf[7] = ml - var ic = 0 - while (mp < ml) { - buf[ic++] = m[mp++] - } - while (ic < 7) { - buf[ic++] = 0 - } - - mi = { - h: buf[7] << 24 | buf[6] << 16 | buf[5] << 8 | buf[4], - l: buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0] - } - - _xor(v3, mi) - _compress(v0, v1, v2, v3) - _compress(v0, v1, v2, v3) - _xor(v0, mi) - _xor(v2, { h: 0, l: 0xff }) - _compress(v0, v1, v2, v3) - _compress(v0, v1, v2, v3) - _compress(v0, v1, v2, v3) - _compress(v0, v1, v2, v3) - - var h = v0 - _xor(h, v1) - _xor(h, v2) - _xor(h, v3) - - out[0] = h.l & 0xff - out[1] = (h.l >> 8) & 0xff - out[2] = (h.l >> 16) & 0xff - out[3] = (h.l >> 24) & 0xff - out[4] = h.h & 0xff - out[5] = (h.h >> 8) & 0xff - out[6] = (h.h >> 16) & 0xff - out[7] = (h.h >> 24) & 0xff + siphash(data, key, out, noAssert) } diff --git a/package.json b/package.json index 35781c6..da65c6d 100644 --- a/package.json +++ b/package.json @@ -4,10 +4,9 @@ "description": "WIP - a pure javascript version of sodium-native", "main": "index.js", "dependencies": { - "base64-to-uint8array": "^1.0.0", "blake2b": "^2.1.1", - "brfs": "^1.4.3", - "nanoassert": "^1.0.0" + "nanoassert": "^1.0.0", + "siphash24": "^1.0.1" }, "devDependencies": { "sodium-test": "^0.4.0" diff --git a/wasm/siphash.wasm b/wasm/siphash.wasm deleted file mode 100644 index c1c0cdeaa8030fe7b70e9c181773ebb335a0bb6f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1194 zcmds$y-EW?5XWb~?lyNO#6qyJnC-OFO3U09zJ{g{VkG#HN(iRV3j}N|^c8Hhu}PCB zh+5bvK@o(M5sTAWXYa(r7Z3~!yUdUO{D;|{g=(|G0DyUHowwT{I0Gda3j%+RmztY9 zwQ94r*4Sul@9lH&zX3q-rrB6?eZbrHV{m);aPinnz;OHee3G2qJoQFkgnb#ECimlE ze+)+2WN>$VemuN-2csgrAi(%h*&Q0$rCsS54_V~znh*h59m6dXph6uRg%bVPNE9v- z$X&#FMN~)`tQHx9vni0e;M5#N%g|$3`@T6Dd`?8M30nSeF?xWc8-jf0hNOJ z9LN-44nzuObHGzj&H+n-{sB}X^;hUk&Q((@G#U1jxgnd3>G}6RAOiOi?!U%yyeuI6 E0%0Y{-~a#s diff --git a/wasm/siphash.wat b/wasm/siphash.wat deleted file mode 100644 index fb9b322..0000000 --- a/wasm/siphash.wat +++ /dev/null @@ -1,348 +0,0 @@ -(module - (memory (export "siphash_memory") 10 10) - - (func (export "siphash") (param $ptr i32) (param $ptr_len i32) - (local $v0 i64) - (local $v1 i64) - (local $v2 i64) - (local $v3 i64) - (local $b i64) - (local $k0 i64) - (local $k1 i64) - (local $m i64) - (local $end i32) - (local $left i32) - - (set_local $v0 (i64.const 0x736f6d6570736575)) - (set_local $v1 (i64.const 0x646f72616e646f6d)) - (set_local $v2 (i64.const 0x6c7967656e657261)) - (set_local $v3 (i64.const 0x7465646279746573)) - - (set_local $k0 (i64.load (i32.const 8))) - (set_local $k1 (i64.load (i32.const 16))) - - ;; b = ((uint64_t) inlen) << 56; - (set_local $b (i64.shl (i64.extend_u/i32 (get_local $ptr_len)) (i64.const 56))) - - ;; left = inlen & 7; - (set_local $left (i32.and (get_local $ptr_len) (i32.const 7))) - - ;; end = in + inlen - left; - (set_local $end (i32.sub (i32.add (get_local $ptr) (get_local $ptr_len)) (get_local $left))) - - ;; v3 ^= k1; - (set_local $v3 (i64.xor (get_local $v3) (get_local $k1))) - - ;; v2 ^= k0; - (set_local $v2 (i64.xor (get_local $v2) (get_local $k0))) - - ;; v1 ^= k1; - (set_local $v1 (i64.xor (get_local $v1) (get_local $k1))) - - ;; v0 ^= k0; - (set_local $v0 (i64.xor (get_local $v0) (get_local $k0))) - - (block $end_loop - (loop $start_loop - (br_if $end_loop (i32.eq (get_local $ptr) (get_local $end))) - - ;; m = LOAD64_LE(in); - (set_local $m (i64.load (get_local $ptr))) - - ;; v3 ^= m - (set_local $v3 (i64.xor (get_local $v3) (get_local $m))) - - ;; SIPROUND - ;; v0 += v1; - (set_local $v0 (i64.add (get_local $v0) (get_local $v1))) - ;; v1 = ROTL64(v1, 13); - (set_local $v1 (i64.rotl (get_local $v1) (i64.const 13))) - ;; v1 ^= v0; - (set_local $v1 (i64.xor (get_local $v1) (get_local $v0))) - ;; v0 = ROTL64(v0, 32) - (set_local $v0 (i64.rotl (get_local $v0) (i64.const 32))) - ;; v2 += v3; - (set_local $v2 (i64.add (get_local $v2) (get_local $v3))) - ;; v3 = ROTL64(v3, 16); - (set_local $v3 (i64.rotl (get_local $v3) (i64.const 16))) - ;; v3 ^= v2; - (set_local $v3 (i64.xor (get_local $v3) (get_local $v2))) - ;; v0 += v3; - (set_local $v0 (i64.add (get_local $v0) (get_local $v3))) - ;; v3 = ROTL64(v3, 21); - (set_local $v3 (i64.rotl (get_local $v3) (i64.const 21))) - ;; v3 ^= v0; - (set_local $v3 (i64.xor (get_local $v3) (get_local $v0))) - ;; v2 += v1; - (set_local $v2 (i64.add (get_local $v2) (get_local $v1))) - ;; v1 = ROTL64(v1, 17); - (set_local $v1 (i64.rotl (get_local $v1) (i64.const 17))) - ;; v1 ^= v2; - (set_local $v1 (i64.xor (get_local $v1) (get_local $v2))) - ;; v2 = ROTL64(v2, 32); - (set_local $v2 (i64.rotl (get_local $v2) (i64.const 32))) - - ;; SIPROUND - ;; v0 += v1; - (set_local $v0 (i64.add (get_local $v0) (get_local $v1))) - ;; v1 = ROTL64(v1, 13); - (set_local $v1 (i64.rotl (get_local $v1) (i64.const 13))) - ;; v1 ^= v0; - (set_local $v1 (i64.xor (get_local $v1) (get_local $v0))) - ;; v0 = ROTL64(v0, 32) - (set_local $v0 (i64.rotl (get_local $v0) (i64.const 32))) - ;; v2 += v3; - (set_local $v2 (i64.add (get_local $v2) (get_local $v3))) - ;; v3 = ROTL64(v3, 16); - (set_local $v3 (i64.rotl (get_local $v3) (i64.const 16))) - ;; v3 ^= v2; - (set_local $v3 (i64.xor (get_local $v3) (get_local $v2))) - ;; v0 += v3; - (set_local $v0 (i64.add (get_local $v0) (get_local $v3))) - ;; v3 = ROTL64(v3, 21); - (set_local $v3 (i64.rotl (get_local $v3) (i64.const 21))) - ;; v3 ^= v0; - (set_local $v3 (i64.xor (get_local $v3) (get_local $v0))) - ;; v2 += v1; - (set_local $v2 (i64.add (get_local $v2) (get_local $v1))) - ;; v1 = ROTL64(v1, 17); - (set_local $v1 (i64.rotl (get_local $v1) (i64.const 17))) - ;; v1 ^= v2; - (set_local $v1 (i64.xor (get_local $v1) (get_local $v2))) - ;; v2 = ROTL64(v2, 32); - (set_local $v2 (i64.rotl (get_local $v2) (i64.const 32))) - - ;; v0 ^= m; - (set_local $v0 (i64.xor (get_local $v0) (get_local $m))) - - ;; ptr += 8 - (set_local $ptr (i32.add (get_local $ptr) (i32.const 8))) - (br $start_loop) - ) - ) - - (block $0 - (block $1 - (block $2 - (block $3 - (block $4 - (block $5 - (block $6 - (block $7 - (br_table $0 $1 $2 $3 $4 $5 $6 $7 (get_local $left)) - ) - ;; b |= ((uint64_t) in[6]) << 48; - (set_local $b (i64.or (get_local $b) (i64.shl (i64.load8_u (i32.add (get_local $ptr) (i32.const 6))) (i64.const 48)))) - ) - ;; b |= ((uint64_t) in[5]) << 40; - (set_local $b (i64.or (get_local $b) (i64.shl (i64.load8_u (i32.add (get_local $ptr) (i32.const 5))) (i64.const 40)))) - ) - ;; b |= ((uint64_t) in[4]) << 32; - (set_local $b (i64.or (get_local $b) (i64.shl (i64.load8_u (i32.add (get_local $ptr) (i32.const 4))) (i64.const 32)))) - ) - ;; b |= ((uint64_t) in[3]) << 24; - (set_local $b (i64.or (get_local $b) (i64.shl (i64.load8_u (i32.add (get_local $ptr) (i32.const 3))) (i64.const 24)))) - ) - ;; b |= ((uint64_t) in[2]) << 16; - (set_local $b (i64.or (get_local $b) (i64.shl (i64.load8_u (i32.add (get_local $ptr) (i32.const 2))) (i64.const 16)))) - ) - ;; b |= ((uint64_t) in[1]) << 8; - (set_local $b (i64.or (get_local $b) (i64.shl (i64.load8_u (i32.add (get_local $ptr) (i32.const 1))) (i64.const 8)))) - ) - ;; b |= ((uint64_t) in[0]); - (set_local $b (i64.or (get_local $b) (i64.load8_u (get_local $ptr)))) - ) - - ;; v3 ^= b; - (set_local $v3 (i64.xor (get_local $v3) (get_local $b))) - - ;; SIPROUND - ;; v0 += v1; - (set_local $v0 (i64.add (get_local $v0) (get_local $v1))) - ;; v1 = ROTL64(v1, 13); - (set_local $v1 (i64.rotl (get_local $v1) (i64.const 13))) - ;; v1 ^= v0; - (set_local $v1 (i64.xor (get_local $v1) (get_local $v0))) - ;; v0 = ROTL64(v0, 32) - (set_local $v0 (i64.rotl (get_local $v0) (i64.const 32))) - ;; v2 += v3; - (set_local $v2 (i64.add (get_local $v2) (get_local $v3))) - ;; v3 = ROTL64(v3, 16); - (set_local $v3 (i64.rotl (get_local $v3) (i64.const 16))) - ;; v3 ^= v2; - (set_local $v3 (i64.xor (get_local $v3) (get_local $v2))) - ;; v0 += v3; - (set_local $v0 (i64.add (get_local $v0) (get_local $v3))) - ;; v3 = ROTL64(v3, 21); - (set_local $v3 (i64.rotl (get_local $v3) (i64.const 21))) - ;; v3 ^= v0; - (set_local $v3 (i64.xor (get_local $v3) (get_local $v0))) - ;; v2 += v1; - (set_local $v2 (i64.add (get_local $v2) (get_local $v1))) - ;; v1 = ROTL64(v1, 17); - (set_local $v1 (i64.rotl (get_local $v1) (i64.const 17))) - ;; v1 ^= v2; - (set_local $v1 (i64.xor (get_local $v1) (get_local $v2))) - ;; v2 = ROTL64(v2, 32); - (set_local $v2 (i64.rotl (get_local $v2) (i64.const 32))) - - ;; SIPROUND - ;; v0 += v1; - (set_local $v0 (i64.add (get_local $v0) (get_local $v1))) - ;; v1 = ROTL64(v1, 13); - (set_local $v1 (i64.rotl (get_local $v1) (i64.const 13))) - ;; v1 ^= v0; - (set_local $v1 (i64.xor (get_local $v1) (get_local $v0))) - ;; v0 = ROTL64(v0, 32) - (set_local $v0 (i64.rotl (get_local $v0) (i64.const 32))) - ;; v2 += v3; - (set_local $v2 (i64.add (get_local $v2) (get_local $v3))) - ;; v3 = ROTL64(v3, 16); - (set_local $v3 (i64.rotl (get_local $v3) (i64.const 16))) - ;; v3 ^= v2; - (set_local $v3 (i64.xor (get_local $v3) (get_local $v2))) - ;; v0 += v3; - (set_local $v0 (i64.add (get_local $v0) (get_local $v3))) - ;; v3 = ROTL64(v3, 21); - (set_local $v3 (i64.rotl (get_local $v3) (i64.const 21))) - ;; v3 ^= v0; - (set_local $v3 (i64.xor (get_local $v3) (get_local $v0))) - ;; v2 += v1; - (set_local $v2 (i64.add (get_local $v2) (get_local $v1))) - ;; v1 = ROTL64(v1, 17); - (set_local $v1 (i64.rotl (get_local $v1) (i64.const 17))) - ;; v1 ^= v2; - (set_local $v1 (i64.xor (get_local $v1) (get_local $v2))) - ;; v2 = ROTL64(v2, 32); - (set_local $v2 (i64.rotl (get_local $v2) (i64.const 32))) - - ;; v0 ^= b; - (set_local $v0 (i64.xor (get_local $v0) (get_local $b))) - - ;; v2 ^= 0xff; - (set_local $v2 (i64.xor (get_local $v2) (i64.const 0xff))) - - ;; SIPROUND - ;; v0 += v1; - (set_local $v0 (i64.add (get_local $v0) (get_local $v1))) - ;; v1 = ROTL64(v1, 13); - (set_local $v1 (i64.rotl (get_local $v1) (i64.const 13))) - ;; v1 ^= v0; - (set_local $v1 (i64.xor (get_local $v1) (get_local $v0))) - ;; v0 = ROTL64(v0, 32) - (set_local $v0 (i64.rotl (get_local $v0) (i64.const 32))) - ;; v2 += v3; - (set_local $v2 (i64.add (get_local $v2) (get_local $v3))) - ;; v3 = ROTL64(v3, 16); - (set_local $v3 (i64.rotl (get_local $v3) (i64.const 16))) - ;; v3 ^= v2; - (set_local $v3 (i64.xor (get_local $v3) (get_local $v2))) - ;; v0 += v3; - (set_local $v0 (i64.add (get_local $v0) (get_local $v3))) - ;; v3 = ROTL64(v3, 21); - (set_local $v3 (i64.rotl (get_local $v3) (i64.const 21))) - ;; v3 ^= v0; - (set_local $v3 (i64.xor (get_local $v3) (get_local $v0))) - ;; v2 += v1; - (set_local $v2 (i64.add (get_local $v2) (get_local $v1))) - ;; v1 = ROTL64(v1, 17); - (set_local $v1 (i64.rotl (get_local $v1) (i64.const 17))) - ;; v1 ^= v2; - (set_local $v1 (i64.xor (get_local $v1) (get_local $v2))) - ;; v2 = ROTL64(v2, 32); - (set_local $v2 (i64.rotl (get_local $v2) (i64.const 32))) - - ;; SIPROUND - ;; v0 += v1; - (set_local $v0 (i64.add (get_local $v0) (get_local $v1))) - ;; v1 = ROTL64(v1, 13); - (set_local $v1 (i64.rotl (get_local $v1) (i64.const 13))) - ;; v1 ^= v0; - (set_local $v1 (i64.xor (get_local $v1) (get_local $v0))) - ;; v0 = ROTL64(v0, 32) - (set_local $v0 (i64.rotl (get_local $v0) (i64.const 32))) - ;; v2 += v3; - (set_local $v2 (i64.add (get_local $v2) (get_local $v3))) - ;; v3 = ROTL64(v3, 16); - (set_local $v3 (i64.rotl (get_local $v3) (i64.const 16))) - ;; v3 ^= v2; - (set_local $v3 (i64.xor (get_local $v3) (get_local $v2))) - ;; v0 += v3; - (set_local $v0 (i64.add (get_local $v0) (get_local $v3))) - ;; v3 = ROTL64(v3, 21); - (set_local $v3 (i64.rotl (get_local $v3) (i64.const 21))) - ;; v3 ^= v0; - (set_local $v3 (i64.xor (get_local $v3) (get_local $v0))) - ;; v2 += v1; - (set_local $v2 (i64.add (get_local $v2) (get_local $v1))) - ;; v1 = ROTL64(v1, 17); - (set_local $v1 (i64.rotl (get_local $v1) (i64.const 17))) - ;; v1 ^= v2; - (set_local $v1 (i64.xor (get_local $v1) (get_local $v2))) - ;; v2 = ROTL64(v2, 32); - (set_local $v2 (i64.rotl (get_local $v2) (i64.const 32))) - - ;; SIPROUND - ;; v0 += v1; - (set_local $v0 (i64.add (get_local $v0) (get_local $v1))) - ;; v1 = ROTL64(v1, 13); - (set_local $v1 (i64.rotl (get_local $v1) (i64.const 13))) - ;; v1 ^= v0; - (set_local $v1 (i64.xor (get_local $v1) (get_local $v0))) - ;; v0 = ROTL64(v0, 32) - (set_local $v0 (i64.rotl (get_local $v0) (i64.const 32))) - ;; v2 += v3; - (set_local $v2 (i64.add (get_local $v2) (get_local $v3))) - ;; v3 = ROTL64(v3, 16); - (set_local $v3 (i64.rotl (get_local $v3) (i64.const 16))) - ;; v3 ^= v2; - (set_local $v3 (i64.xor (get_local $v3) (get_local $v2))) - ;; v0 += v3; - (set_local $v0 (i64.add (get_local $v0) (get_local $v3))) - ;; v3 = ROTL64(v3, 21); - (set_local $v3 (i64.rotl (get_local $v3) (i64.const 21))) - ;; v3 ^= v0; - (set_local $v3 (i64.xor (get_local $v3) (get_local $v0))) - ;; v2 += v1; - (set_local $v2 (i64.add (get_local $v2) (get_local $v1))) - ;; v1 = ROTL64(v1, 17); - (set_local $v1 (i64.rotl (get_local $v1) (i64.const 17))) - ;; v1 ^= v2; - (set_local $v1 (i64.xor (get_local $v1) (get_local $v2))) - ;; v2 = ROTL64(v2, 32); - (set_local $v2 (i64.rotl (get_local $v2) (i64.const 32))) - - ;; SIPROUND - ;; v0 += v1; - (set_local $v0 (i64.add (get_local $v0) (get_local $v1))) - ;; v1 = ROTL64(v1, 13); - (set_local $v1 (i64.rotl (get_local $v1) (i64.const 13))) - ;; v1 ^= v0; - (set_local $v1 (i64.xor (get_local $v1) (get_local $v0))) - ;; v0 = ROTL64(v0, 32) - (set_local $v0 (i64.rotl (get_local $v0) (i64.const 32))) - ;; v2 += v3; - (set_local $v2 (i64.add (get_local $v2) (get_local $v3))) - ;; v3 = ROTL64(v3, 16); - (set_local $v3 (i64.rotl (get_local $v3) (i64.const 16))) - ;; v3 ^= v2; - (set_local $v3 (i64.xor (get_local $v3) (get_local $v2))) - ;; v0 += v3; - (set_local $v0 (i64.add (get_local $v0) (get_local $v3))) - ;; v3 = ROTL64(v3, 21); - (set_local $v3 (i64.rotl (get_local $v3) (i64.const 21))) - ;; v3 ^= v0; - (set_local $v3 (i64.xor (get_local $v3) (get_local $v0))) - ;; v2 += v1; - (set_local $v2 (i64.add (get_local $v2) (get_local $v1))) - ;; v1 = ROTL64(v1, 17); - (set_local $v1 (i64.rotl (get_local $v1) (i64.const 17))) - ;; v1 ^= v2; - (set_local $v1 (i64.xor (get_local $v1) (get_local $v2))) - ;; v2 = ROTL64(v2, 32); - (set_local $v2 (i64.rotl (get_local $v2) (i64.const 32))) - - ;; b = v0 ^ v1 ^ v2 ^ v3; - (i64.store (i32.const 0) (i64.xor (get_local $v0) (i64.xor (get_local $v1) (i64.xor (get_local $v2) (get_local $v3))))) - ) -) From abedfa6362fdfbc5e3ee93c6a89f52de45a60824 Mon Sep 17 00:00:00 2001 From: Mathias Buus Date: Mon, 12 Jun 2017 11:01:30 +0200 Subject: [PATCH 17/17] 0.3.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index da65c6d..125dda8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sodium-javascript", - "version": "0.3.0", + "version": "0.3.1", "description": "WIP - a pure javascript version of sodium-native", "main": "index.js", "dependencies": {