Compare commits

..
31 Commits
Author SHA1 Message Date
Mathias Buus 51f8fbc2d3 0.5.6 2020-03-04 14:52:37 +01:00
Mathias Buus f790621e60 add sodium_malloc 2020-03-04 14:50:09 +01:00
Fedor Indutny 4e42b942a5 crypto_box: fix keypair, implement seal/seal_open
Secret Key is a random nonce, and public key is a point on elliptic
curve.

`crypto_box_seal`/`crypto_box_seal_open` are implemented using existing
primitives and newly exported `core_hsalsa20` in `xsalsa20`
2019-11-14 09:27:36 +01:00
Daniel Regeci 49587c3d7f crypto_box_keypair - rename arguments to pk,sk 2018-03-19 18:07:17 +00:00
Daniel Regeci 92aee452df crypto_box_keypair 2018-03-19 18:07:17 +00:00
Mathias Buus e1ca83f1bd 0.5.5 2018-03-19 19:03:43 +01:00
Peter van Hardenberg c81ef709d1 react-native doesn't want crypto set to an empty module (#14)
React-Native is sort of like a browser, sort of a native environment. On react-native we don't have the browser's crypto implementation, so we need to require react-native-crypto. We can rewrite the module requirement to do that using the extraNodeModules feature in rn-cli.config.js, but the metro packager assumes that if there's a "browser" field in package.json that it's relevant to react-native libraries unless there's also a "react-native" field. Hurray.

Anyway, this silly little patch tells metro not to replace crypto with an empty module but actually to use whatever you currently have crypto set to (which is not solved here, so you'll still have to do that.)
2018-03-19 18:58:24 +01:00
Jim Pick 4e1c69ba13 Change crypto_kdf_KEYBYTES to be 32 and use subarray instead of slice
Thanks to Emil Bayes for the advice.
2018-03-03 17:24:12 +00:00
Jim Pick 5159d68fa9 In kdf, truncate key before passing to blake to match sodium-native behaviour
Currently, sodium-native and sodium-javascript are returning different
hashes. The code in hyperdrive passes a 64 byte secret key to the kdf,
but only 32 bytes are used by the native version, but all 64 bytes are
used in the javascript version. As a result, hyperdrive secret keys
can't be imported/exported across the two sodium implementations.

https://gist.github.com/jimpick/3e869522eddaad77ac1bc9e64f36e1a7
2018-03-03 17:24:12 +00:00
Mathias Buus 5ccdcdee17 0.5.4 2017-11-19 13:16:51 +01:00
Mathias Buus 48081c6896 ignore crypto in the browser 2017-11-19 13:16:35 +01:00
Mathias Buus b1741bfdae 0.5.3 2017-11-17 12:09:34 +01:00
Mathias Buus f7de366eec fix shorthash_ready being deprecated 2017-11-17 12:07:52 +01:00
Mathias Buus 51e11143e5 fix siphash24 not having ready 2017-11-17 10:43:01 +01:00
Emil Bay b883b2a8df 0.5.2 2017-11-03 08:19:11 +01:00
Emil Bay f336097b6a Fix bug with undefined window in web workers
Fixes #8
2017-11-03 08:19:06 +01:00
Mathias Buus 5511bafdba 0.5.1 2017-07-13 16:52:43 +02:00
Mathias Buus 212550db1b bump sodium-test and minor tweak 2017-07-13 16:52:30 +02:00
Luke Burns 384ec2f636 fixed detached sign/verify 2017-07-13 16:47:23 +02:00
Mathias Buus 07e1bc4ed6 0.5.0 2017-06-28 11:17:18 +02:00
Mathias Buus 6561ff99f1 use xsalsa20 and support crypto_stream_instance 2017-06-28 11:14:00 +02:00
Emil Bay 0f249a7e8f Run tests with browser-run 2017-06-19 22:39:11 +02:00
Emil Bay fa6f2a836c 0.4.0 2017-06-19 22:36:13 +02:00
Emil Bay 2bae0d19af Use independent randombytes_buf 2017-06-19 22:34:38 +02:00
Emil Bay 75bad77847 Upgrade sodium-test 2017-06-19 22:34:37 +02:00
Emil Bay 49feb73134 Move out randombytes_buf 2017-06-19 22:34:12 +02:00
Julian Gruber 642a68c2a1 Add browser support (#1)
* add browser test target
* add browser-manual target
2017-06-19 21:44:32 +02:00
Mathias Buus abedfa6362 0.3.1 2017-06-12 11:01:30 +02:00
Mathias Buus de8639f558 use siphash24 2017-06-12 11:01:21 +02:00
Mathias Buus 33befeb87a cleanup newlines 2017-06-12 10:31:43 +02:00
Mathias Buus a22454f86f simply wasm loaded logic 2017-06-12 10:29:16 +02:00
11 changed files with 202 additions and 1016 deletions
+1 -2
View File
@@ -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)
}
@@ -31,5 +30,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
})
+3 -3
View File
@@ -1,12 +1,12 @@
var assert = require('nanoassert')
var randombytes_buf = require('.').randombytes_buf
var randombytes_buf = require('./randombytes').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
module.exports.crypto_kdf_KEYBYTES = 32
function STORE64_LE(dest, int) {
var mul = 1
@@ -29,7 +29,7 @@ module.exports.crypto_kdf_derive_from_key = function crypto_kdf_derive_from_key
STORE64_LE(salt, subkey_id)
var outlen = Math.min(subkey.length, module.exports.crypto_kdf_BYTES_MAX)
blake2b(outlen, key, salt, ctx_padded, true)
blake2b(outlen, key.subarray(0, module.exports.crypto_kdf_KEYBYTES), salt, ctx_padded, true)
.final(subkey)
}
+6 -163
View File
@@ -1,169 +1,12 @@
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 = 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
siphash(data, key, out, noAssert)
}
+33
View File
@@ -0,0 +1,33 @@
var xsalsa20 = require('xsalsa20')
exports.crypto_stream_KEYBYTES = 32
exports.crypto_stream_NONCEBYTES = 24
exports.crypto_stream_PRIMITIVE = 'xsalsa20'
exports.crypto_stream = function (out, nonce, key) {
out.fill(0)
exports.crypto_stream_xor(out, out, nonce, key)
}
exports.crypto_stream_xor = function (out, inp, nonce, key) {
var xor = xsalsa20(nonce, key)
xor.update(inp, out)
xor.final()
}
exports.crypto_stream_xor_instance = function (nonce, key) {
return new XOR(nonce, key)
}
function XOR (nonce, key) {
this._instance = xsalsa20(nonce, key)
}
XOR.prototype.update = function (out, inp) {
this._instance.update(inp, out)
}
XOR.prototype.final = function () {
this._instance.finalize()
this._instance = null
}
+2
View File
@@ -18,3 +18,5 @@ var plainText = new Buffer(cipher.length - sodium.crypto_secretbox_MACBYTES)
sodium.crypto_secretbox_open_easy(plainText, cipher, nonce, key)
console.log('Plaintext:', plainText.toString())
if (typeof window !== 'undefined') window.close()
+99 -489
View File
@@ -1,8 +1,11 @@
'use strict';
var xsalsa20 = require('xsalsa20')
// Based on https://github.com/dchest/tweetnacl-js/blob/6dcbcaf5f5cbfd313f2dcfe763db35c828c8ff5b/nacl-fast.js.
var sodium = module.exports
var cs = require('./crypto_stream')
// Ported in 2014 by Dmitry Chestnykh and Devi Mandiri.
// Public domain.
@@ -16,8 +19,8 @@ var gf = function(init) {
return r;
};
// Pluggable, initialized in high-level API below.
var randombytes = function(/* x, n */) { throw new Error('no PRNG'); };
// also forwarded at the bottom but randombytes is non-enumerable
var randombytes = require('./randombytes').randombytes
var _0 = new Uint8Array(16);
var _9 = new Uint8Array(32); _9[0] = 9;
@@ -56,412 +59,6 @@ function crypto_verify_32(x, xi, y, yi) {
return vn(x,xi,y,yi,32);
}
function core_salsa20(o, p, k, c) {
var j0 = c[ 0] & 0xff | (c[ 1] & 0xff)<<8 | (c[ 2] & 0xff)<<16 | (c[ 3] & 0xff)<<24,
j1 = k[ 0] & 0xff | (k[ 1] & 0xff)<<8 | (k[ 2] & 0xff)<<16 | (k[ 3] & 0xff)<<24,
j2 = k[ 4] & 0xff | (k[ 5] & 0xff)<<8 | (k[ 6] & 0xff)<<16 | (k[ 7] & 0xff)<<24,
j3 = k[ 8] & 0xff | (k[ 9] & 0xff)<<8 | (k[10] & 0xff)<<16 | (k[11] & 0xff)<<24,
j4 = k[12] & 0xff | (k[13] & 0xff)<<8 | (k[14] & 0xff)<<16 | (k[15] & 0xff)<<24,
j5 = c[ 4] & 0xff | (c[ 5] & 0xff)<<8 | (c[ 6] & 0xff)<<16 | (c[ 7] & 0xff)<<24,
j6 = p[ 0] & 0xff | (p[ 1] & 0xff)<<8 | (p[ 2] & 0xff)<<16 | (p[ 3] & 0xff)<<24,
j7 = p[ 4] & 0xff | (p[ 5] & 0xff)<<8 | (p[ 6] & 0xff)<<16 | (p[ 7] & 0xff)<<24,
j8 = p[ 8] & 0xff | (p[ 9] & 0xff)<<8 | (p[10] & 0xff)<<16 | (p[11] & 0xff)<<24,
j9 = p[12] & 0xff | (p[13] & 0xff)<<8 | (p[14] & 0xff)<<16 | (p[15] & 0xff)<<24,
j10 = c[ 8] & 0xff | (c[ 9] & 0xff)<<8 | (c[10] & 0xff)<<16 | (c[11] & 0xff)<<24,
j11 = k[16] & 0xff | (k[17] & 0xff)<<8 | (k[18] & 0xff)<<16 | (k[19] & 0xff)<<24,
j12 = k[20] & 0xff | (k[21] & 0xff)<<8 | (k[22] & 0xff)<<16 | (k[23] & 0xff)<<24,
j13 = k[24] & 0xff | (k[25] & 0xff)<<8 | (k[26] & 0xff)<<16 | (k[27] & 0xff)<<24,
j14 = k[28] & 0xff | (k[29] & 0xff)<<8 | (k[30] & 0xff)<<16 | (k[31] & 0xff)<<24,
j15 = c[12] & 0xff | (c[13] & 0xff)<<8 | (c[14] & 0xff)<<16 | (c[15] & 0xff)<<24;
var x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7,
x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14,
x15 = j15, u;
for (var i = 0; i < 20; i += 2) {
u = x0 + x12 | 0;
x4 ^= u<<7 | u>>>(32-7);
u = x4 + x0 | 0;
x8 ^= u<<9 | u>>>(32-9);
u = x8 + x4 | 0;
x12 ^= u<<13 | u>>>(32-13);
u = x12 + x8 | 0;
x0 ^= u<<18 | u>>>(32-18);
u = x5 + x1 | 0;
x9 ^= u<<7 | u>>>(32-7);
u = x9 + x5 | 0;
x13 ^= u<<9 | u>>>(32-9);
u = x13 + x9 | 0;
x1 ^= u<<13 | u>>>(32-13);
u = x1 + x13 | 0;
x5 ^= u<<18 | u>>>(32-18);
u = x10 + x6 | 0;
x14 ^= u<<7 | u>>>(32-7);
u = x14 + x10 | 0;
x2 ^= u<<9 | u>>>(32-9);
u = x2 + x14 | 0;
x6 ^= u<<13 | u>>>(32-13);
u = x6 + x2 | 0;
x10 ^= u<<18 | u>>>(32-18);
u = x15 + x11 | 0;
x3 ^= u<<7 | u>>>(32-7);
u = x3 + x15 | 0;
x7 ^= u<<9 | u>>>(32-9);
u = x7 + x3 | 0;
x11 ^= u<<13 | u>>>(32-13);
u = x11 + x7 | 0;
x15 ^= u<<18 | u>>>(32-18);
u = x0 + x3 | 0;
x1 ^= u<<7 | u>>>(32-7);
u = x1 + x0 | 0;
x2 ^= u<<9 | u>>>(32-9);
u = x2 + x1 | 0;
x3 ^= u<<13 | u>>>(32-13);
u = x3 + x2 | 0;
x0 ^= u<<18 | u>>>(32-18);
u = x5 + x4 | 0;
x6 ^= u<<7 | u>>>(32-7);
u = x6 + x5 | 0;
x7 ^= u<<9 | u>>>(32-9);
u = x7 + x6 | 0;
x4 ^= u<<13 | u>>>(32-13);
u = x4 + x7 | 0;
x5 ^= u<<18 | u>>>(32-18);
u = x10 + x9 | 0;
x11 ^= u<<7 | u>>>(32-7);
u = x11 + x10 | 0;
x8 ^= u<<9 | u>>>(32-9);
u = x8 + x11 | 0;
x9 ^= u<<13 | u>>>(32-13);
u = x9 + x8 | 0;
x10 ^= u<<18 | u>>>(32-18);
u = x15 + x14 | 0;
x12 ^= u<<7 | u>>>(32-7);
u = x12 + x15 | 0;
x13 ^= u<<9 | u>>>(32-9);
u = x13 + x12 | 0;
x14 ^= u<<13 | u>>>(32-13);
u = x14 + x13 | 0;
x15 ^= u<<18 | u>>>(32-18);
}
x0 = x0 + j0 | 0;
x1 = x1 + j1 | 0;
x2 = x2 + j2 | 0;
x3 = x3 + j3 | 0;
x4 = x4 + j4 | 0;
x5 = x5 + j5 | 0;
x6 = x6 + j6 | 0;
x7 = x7 + j7 | 0;
x8 = x8 + j8 | 0;
x9 = x9 + j9 | 0;
x10 = x10 + j10 | 0;
x11 = x11 + j11 | 0;
x12 = x12 + j12 | 0;
x13 = x13 + j13 | 0;
x14 = x14 + j14 | 0;
x15 = x15 + j15 | 0;
o[ 0] = x0 >>> 0 & 0xff;
o[ 1] = x0 >>> 8 & 0xff;
o[ 2] = x0 >>> 16 & 0xff;
o[ 3] = x0 >>> 24 & 0xff;
o[ 4] = x1 >>> 0 & 0xff;
o[ 5] = x1 >>> 8 & 0xff;
o[ 6] = x1 >>> 16 & 0xff;
o[ 7] = x1 >>> 24 & 0xff;
o[ 8] = x2 >>> 0 & 0xff;
o[ 9] = x2 >>> 8 & 0xff;
o[10] = x2 >>> 16 & 0xff;
o[11] = x2 >>> 24 & 0xff;
o[12] = x3 >>> 0 & 0xff;
o[13] = x3 >>> 8 & 0xff;
o[14] = x3 >>> 16 & 0xff;
o[15] = x3 >>> 24 & 0xff;
o[16] = x4 >>> 0 & 0xff;
o[17] = x4 >>> 8 & 0xff;
o[18] = x4 >>> 16 & 0xff;
o[19] = x4 >>> 24 & 0xff;
o[20] = x5 >>> 0 & 0xff;
o[21] = x5 >>> 8 & 0xff;
o[22] = x5 >>> 16 & 0xff;
o[23] = x5 >>> 24 & 0xff;
o[24] = x6 >>> 0 & 0xff;
o[25] = x6 >>> 8 & 0xff;
o[26] = x6 >>> 16 & 0xff;
o[27] = x6 >>> 24 & 0xff;
o[28] = x7 >>> 0 & 0xff;
o[29] = x7 >>> 8 & 0xff;
o[30] = x7 >>> 16 & 0xff;
o[31] = x7 >>> 24 & 0xff;
o[32] = x8 >>> 0 & 0xff;
o[33] = x8 >>> 8 & 0xff;
o[34] = x8 >>> 16 & 0xff;
o[35] = x8 >>> 24 & 0xff;
o[36] = x9 >>> 0 & 0xff;
o[37] = x9 >>> 8 & 0xff;
o[38] = x9 >>> 16 & 0xff;
o[39] = x9 >>> 24 & 0xff;
o[40] = x10 >>> 0 & 0xff;
o[41] = x10 >>> 8 & 0xff;
o[42] = x10 >>> 16 & 0xff;
o[43] = x10 >>> 24 & 0xff;
o[44] = x11 >>> 0 & 0xff;
o[45] = x11 >>> 8 & 0xff;
o[46] = x11 >>> 16 & 0xff;
o[47] = x11 >>> 24 & 0xff;
o[48] = x12 >>> 0 & 0xff;
o[49] = x12 >>> 8 & 0xff;
o[50] = x12 >>> 16 & 0xff;
o[51] = x12 >>> 24 & 0xff;
o[52] = x13 >>> 0 & 0xff;
o[53] = x13 >>> 8 & 0xff;
o[54] = x13 >>> 16 & 0xff;
o[55] = x13 >>> 24 & 0xff;
o[56] = x14 >>> 0 & 0xff;
o[57] = x14 >>> 8 & 0xff;
o[58] = x14 >>> 16 & 0xff;
o[59] = x14 >>> 24 & 0xff;
o[60] = x15 >>> 0 & 0xff;
o[61] = x15 >>> 8 & 0xff;
o[62] = x15 >>> 16 & 0xff;
o[63] = x15 >>> 24 & 0xff;
}
function core_hsalsa20(o,p,k,c) {
var j0 = c[ 0] & 0xff | (c[ 1] & 0xff)<<8 | (c[ 2] & 0xff)<<16 | (c[ 3] & 0xff)<<24,
j1 = k[ 0] & 0xff | (k[ 1] & 0xff)<<8 | (k[ 2] & 0xff)<<16 | (k[ 3] & 0xff)<<24,
j2 = k[ 4] & 0xff | (k[ 5] & 0xff)<<8 | (k[ 6] & 0xff)<<16 | (k[ 7] & 0xff)<<24,
j3 = k[ 8] & 0xff | (k[ 9] & 0xff)<<8 | (k[10] & 0xff)<<16 | (k[11] & 0xff)<<24,
j4 = k[12] & 0xff | (k[13] & 0xff)<<8 | (k[14] & 0xff)<<16 | (k[15] & 0xff)<<24,
j5 = c[ 4] & 0xff | (c[ 5] & 0xff)<<8 | (c[ 6] & 0xff)<<16 | (c[ 7] & 0xff)<<24,
j6 = p[ 0] & 0xff | (p[ 1] & 0xff)<<8 | (p[ 2] & 0xff)<<16 | (p[ 3] & 0xff)<<24,
j7 = p[ 4] & 0xff | (p[ 5] & 0xff)<<8 | (p[ 6] & 0xff)<<16 | (p[ 7] & 0xff)<<24,
j8 = p[ 8] & 0xff | (p[ 9] & 0xff)<<8 | (p[10] & 0xff)<<16 | (p[11] & 0xff)<<24,
j9 = p[12] & 0xff | (p[13] & 0xff)<<8 | (p[14] & 0xff)<<16 | (p[15] & 0xff)<<24,
j10 = c[ 8] & 0xff | (c[ 9] & 0xff)<<8 | (c[10] & 0xff)<<16 | (c[11] & 0xff)<<24,
j11 = k[16] & 0xff | (k[17] & 0xff)<<8 | (k[18] & 0xff)<<16 | (k[19] & 0xff)<<24,
j12 = k[20] & 0xff | (k[21] & 0xff)<<8 | (k[22] & 0xff)<<16 | (k[23] & 0xff)<<24,
j13 = k[24] & 0xff | (k[25] & 0xff)<<8 | (k[26] & 0xff)<<16 | (k[27] & 0xff)<<24,
j14 = k[28] & 0xff | (k[29] & 0xff)<<8 | (k[30] & 0xff)<<16 | (k[31] & 0xff)<<24,
j15 = c[12] & 0xff | (c[13] & 0xff)<<8 | (c[14] & 0xff)<<16 | (c[15] & 0xff)<<24;
var x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7,
x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14,
x15 = j15, u;
for (var i = 0; i < 20; i += 2) {
u = x0 + x12 | 0;
x4 ^= u<<7 | u>>>(32-7);
u = x4 + x0 | 0;
x8 ^= u<<9 | u>>>(32-9);
u = x8 + x4 | 0;
x12 ^= u<<13 | u>>>(32-13);
u = x12 + x8 | 0;
x0 ^= u<<18 | u>>>(32-18);
u = x5 + x1 | 0;
x9 ^= u<<7 | u>>>(32-7);
u = x9 + x5 | 0;
x13 ^= u<<9 | u>>>(32-9);
u = x13 + x9 | 0;
x1 ^= u<<13 | u>>>(32-13);
u = x1 + x13 | 0;
x5 ^= u<<18 | u>>>(32-18);
u = x10 + x6 | 0;
x14 ^= u<<7 | u>>>(32-7);
u = x14 + x10 | 0;
x2 ^= u<<9 | u>>>(32-9);
u = x2 + x14 | 0;
x6 ^= u<<13 | u>>>(32-13);
u = x6 + x2 | 0;
x10 ^= u<<18 | u>>>(32-18);
u = x15 + x11 | 0;
x3 ^= u<<7 | u>>>(32-7);
u = x3 + x15 | 0;
x7 ^= u<<9 | u>>>(32-9);
u = x7 + x3 | 0;
x11 ^= u<<13 | u>>>(32-13);
u = x11 + x7 | 0;
x15 ^= u<<18 | u>>>(32-18);
u = x0 + x3 | 0;
x1 ^= u<<7 | u>>>(32-7);
u = x1 + x0 | 0;
x2 ^= u<<9 | u>>>(32-9);
u = x2 + x1 | 0;
x3 ^= u<<13 | u>>>(32-13);
u = x3 + x2 | 0;
x0 ^= u<<18 | u>>>(32-18);
u = x5 + x4 | 0;
x6 ^= u<<7 | u>>>(32-7);
u = x6 + x5 | 0;
x7 ^= u<<9 | u>>>(32-9);
u = x7 + x6 | 0;
x4 ^= u<<13 | u>>>(32-13);
u = x4 + x7 | 0;
x5 ^= u<<18 | u>>>(32-18);
u = x10 + x9 | 0;
x11 ^= u<<7 | u>>>(32-7);
u = x11 + x10 | 0;
x8 ^= u<<9 | u>>>(32-9);
u = x8 + x11 | 0;
x9 ^= u<<13 | u>>>(32-13);
u = x9 + x8 | 0;
x10 ^= u<<18 | u>>>(32-18);
u = x15 + x14 | 0;
x12 ^= u<<7 | u>>>(32-7);
u = x12 + x15 | 0;
x13 ^= u<<9 | u>>>(32-9);
u = x13 + x12 | 0;
x14 ^= u<<13 | u>>>(32-13);
u = x14 + x13 | 0;
x15 ^= u<<18 | u>>>(32-18);
}
o[ 0] = x0 >>> 0 & 0xff;
o[ 1] = x0 >>> 8 & 0xff;
o[ 2] = x0 >>> 16 & 0xff;
o[ 3] = x0 >>> 24 & 0xff;
o[ 4] = x5 >>> 0 & 0xff;
o[ 5] = x5 >>> 8 & 0xff;
o[ 6] = x5 >>> 16 & 0xff;
o[ 7] = x5 >>> 24 & 0xff;
o[ 8] = x10 >>> 0 & 0xff;
o[ 9] = x10 >>> 8 & 0xff;
o[10] = x10 >>> 16 & 0xff;
o[11] = x10 >>> 24 & 0xff;
o[12] = x15 >>> 0 & 0xff;
o[13] = x15 >>> 8 & 0xff;
o[14] = x15 >>> 16 & 0xff;
o[15] = x15 >>> 24 & 0xff;
o[16] = x6 >>> 0 & 0xff;
o[17] = x6 >>> 8 & 0xff;
o[18] = x6 >>> 16 & 0xff;
o[19] = x6 >>> 24 & 0xff;
o[20] = x7 >>> 0 & 0xff;
o[21] = x7 >>> 8 & 0xff;
o[22] = x7 >>> 16 & 0xff;
o[23] = x7 >>> 24 & 0xff;
o[24] = x8 >>> 0 & 0xff;
o[25] = x8 >>> 8 & 0xff;
o[26] = x8 >>> 16 & 0xff;
o[27] = x8 >>> 24 & 0xff;
o[28] = x9 >>> 0 & 0xff;
o[29] = x9 >>> 8 & 0xff;
o[30] = x9 >>> 16 & 0xff;
o[31] = x9 >>> 24 & 0xff;
}
function crypto_core_salsa20(out,inp,k,c) {
core_salsa20(out,inp,k,c);
}
function crypto_core_hsalsa20(out,inp,k,c) {
core_hsalsa20(out,inp,k,c);
}
var sigma = new Uint8Array([101, 120, 112, 97, 110, 100, 32, 51, 50, 45, 98, 121, 116, 101, 32, 107]);
// "expand 32-byte k"
function crypto_stream_salsa20_xor(c,cpos,m,mpos,b,n,k) {
var z = new Uint8Array(16), x = new Uint8Array(64);
var u, i;
for (i = 0; i < 16; i++) z[i] = 0;
for (i = 0; i < 8; i++) z[i] = n[i];
while (b >= 64) {
crypto_core_salsa20(x,z,k,sigma);
for (i = 0; i < 64; i++) c[cpos+i] = m[mpos+i] ^ x[i];
u = 1;
for (i = 8; i < 16; i++) {
u = u + (z[i] & 0xff) | 0;
z[i] = u & 0xff;
u >>>= 8;
}
b -= 64;
cpos += 64;
mpos += 64;
}
if (b > 0) {
crypto_core_salsa20(x,z,k,sigma);
for (i = 0; i < b; i++) c[cpos+i] = m[mpos+i] ^ x[i];
}
return 0;
}
function crypto_stream_salsa20(c,cpos,b,n,k) {
var z = new Uint8Array(16), x = new Uint8Array(64);
var u, i;
for (i = 0; i < 16; i++) z[i] = 0;
for (i = 0; i < 8; i++) z[i] = n[i];
while (b >= 64) {
crypto_core_salsa20(x,z,k,sigma);
for (i = 0; i < 64; i++) c[cpos+i] = x[i];
u = 1;
for (i = 8; i < 16; i++) {
u = u + (z[i] & 0xff) | 0;
z[i] = u & 0xff;
u >>>= 8;
}
b -= 64;
cpos += 64;
}
if (b > 0) {
crypto_core_salsa20(x,z,k,sigma);
for (i = 0; i < b; i++) c[cpos+i] = x[i];
}
return 0;
}
function crypto_stream(c,cpos,d,n,k) {
var s = new Uint8Array(32);
crypto_core_hsalsa20(s,n,k,sigma);
var sn = new Uint8Array(8);
for (var i = 0; i < 8; i++) sn[i] = n[i+16];
return crypto_stream_salsa20(c,cpos,d,sn,s);
}
function crypto_stream_xor(c,cpos,m,mpos,d,n,k) {
var s = new Uint8Array(32);
crypto_core_hsalsa20(s,n,k,sigma);
var sn = new Uint8Array(8);
for (var i = 0; i < 8; i++) sn[i] = n[i+16];
return crypto_stream_salsa20_xor(c,cpos,m,mpos,d,sn,s);
}
/*
* Port of Andrew Moon's Poly1305-donna-16. Public domain.
* https://github.com/floodyberry/poly1305-donna
@@ -819,6 +416,14 @@ poly1305.prototype.update = function(m, mpos, bytes) {
}
};
function crypto_stream_xor (c, cpos, m, mpos, clen, n, k) {
cs.crypto_stream_xor(c, m, n, k)
}
function crypto_stream (c, cpos, clen, n, k) {
cs.crypto_stream(c, n, k)
}
function crypto_onetimeauth(out, outpos, m, mpos, n, k) {
var s = new poly1305(k);
s.update(m, mpos, n);
@@ -1384,32 +989,6 @@ function crypto_scalarmult_base(q, n) {
return crypto_scalarmult(q, n, _9);
}
function crypto_box_keypair(y, x) {
randombytes(x, 32);
return crypto_scalarmult_base(y, x);
}
function crypto_box_beforenm(k, y, x) {
var s = new Uint8Array(32);
crypto_scalarmult(s, x, y);
return crypto_core_hsalsa20(k, _0, s, sigma);
}
var crypto_box_afternm = crypto_secretbox;
var crypto_box_open_afternm = crypto_secretbox_open;
function crypto_box(c, m, d, n, y, x) {
var k = new Uint8Array(32);
crypto_box_beforenm(k, y, x);
return crypto_box_afternm(c, m, d, n, k);
}
function crypto_box_open(m, c, d, n, y, x) {
var k = new Uint8Array(32);
crypto_box_beforenm(k, y, x);
return crypto_box_open_afternm(m, c, d, n, k);
}
var K = [
0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd,
0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc,
@@ -2024,7 +1603,7 @@ function crypto_sign(sm, m, sk) {
function crypto_sign_detached(sig, m, sk) {
var sm = new Uint8Array(m.length + crypto_sign_BYTES)
crypto_sign(sm, m, sk)
for (var i = 0; i < 32; i++) sig[i] = sm[i]
for (var i = 0; i < crypto_sign_BYTES; i++) sig[i] = sm[i]
}
function unpackneg(r, p) {
@@ -2105,30 +1684,27 @@ function crypto_sign_open(msg, sm, pk) {
function crypto_sign_verify_detached (sig, m, pk) {
check(sig, crypto_sign_BYTES)
var sm = new Uint8Array(m.length + sig.length)
var sm = new Uint8Array(m.length + crypto_sign_BYTES)
var i = 0
for (i = 0; i < 64; i++) sm[i] = m[i]
for (i = 0; i < m.length; i++) sm[i + 64] = m[i]
return crypto_sign_open(sm, m, pk)
for (i = 0; i < crypto_sign_BYTES; i++) sm[i] = sig[i]
for (i = 0; i < m.length; i++) sm[i + crypto_sign_BYTES] = m[i]
return crypto_sign_open(m, sm, pk)
}
function randombytes_buf (n) {
randombytes(n, n.length)
function crypto_secretbox_detached (o, mac, msg, n, k) {
check(mac, sodium.crypto_secretbox_MACBYTES)
var tmp = new Uint8Array(msg.length + mac.length)
crypto_secretbox_easy(tmp, msg, n, k)
o.set(tmp.subarray(0, msg.length))
mac.set(tmp.subarray(msg.length))
}
function crypto_stream_wrap(c, n, k) {
check(c, 0)
check(n, sodium.crypto_stream_NONCEBYTES)
check(k, sodium.crypto_stream_KEYBYTES)
crypto_stream(c, 0, c.length, n, k)
}
function crypto_stream_xor_wrap(c, m, n, k) {
check(m, 0)
check(c, m.length)
check(n, sodium.crypto_stream_NONCEBYTES)
check(k, sodium.crypto_stream_KEYBYTES)
crypto_stream_xor(c, 0, m, 0, m.length, n, k)
function crypto_secretbox_open_detached (msg, o, mac, n, k) {
check(mac, sodium.crypto_secretbox_MACBYTES)
var tmp = new Uint8Array(o.length + mac.length)
tmp.set(o)
tmp.set(mac, msg.length)
return crypto_secretbox_open_easy(msg, tmp, n, k)
}
function crypto_secretbox_easy(o, msg, n, k) {
@@ -2162,6 +1738,57 @@ function crypto_secretbox_open_easy(msg, box, n, k) {
return true
}
function crypto_box_keypair(pk, sk) {
check(pk, crypto_box_PUBLICKEYBYTES)
check(sk, crypto_box_SECRETKEYBYTES)
randombytes(sk, 32)
return crypto_scalarmult_base(pk, sk)
}
function crypto_box_seal(c, m, pk) {
check(c, crypto_box_SEALBYTES + m.length)
check(pk, crypto_box_PUBLICKEYBYTES)
var epk = c.subarray(0, crypto_box_PUBLICKEYBYTES)
var esk = new Uint8Array(crypto_box_SECRETKEYBYTES)
crypto_box_keypair(epk, esk)
var n = new Uint8Array(crypto_box_NONCEBYTES)
sodium.crypto_generichash_batch(n, [ epk, pk ])
var s = new Uint8Array(crypto_box_PUBLICKEYBYTES)
crypto_scalarmult(s, esk, pk)
var k = new Uint8Array(crypto_box_BEFORENMBYTES)
var zero = new Uint8Array(16)
xsalsa20.core_hsalsa20(k, zero, s, xsalsa20.SIGMA)
crypto_secretbox_easy(c.subarray(epk.length), m, n, k)
cleanup(esk)
}
function crypto_box_seal_open(m, c, pk, sk) {
check(c, crypto_box_SEALBYTES)
check(m, c.length - crypto_box_SEALBYTES)
check(pk, crypto_box_PUBLICKEYBYTES)
check(sk, crypto_box_SECRETKEYBYTES)
var epk = c.subarray(0, crypto_box_PUBLICKEYBYTES)
var n = new Uint8Array(crypto_box_NONCEBYTES)
sodium.crypto_generichash_batch(n, [ epk, pk ])
var s = new Uint8Array(crypto_box_PUBLICKEYBYTES)
crypto_scalarmult(s, sk, epk)
var k = new Uint8Array(crypto_box_BEFORENMBYTES)
var zero = new Uint8Array(16)
xsalsa20.core_hsalsa20(k, zero, s, xsalsa20.SIGMA)
return crypto_secretbox_open_easy(m, c.subarray(epk.length), n, k)
}
var crypto_secretbox_KEYBYTES = 32,
crypto_secretbox_NONCEBYTES = 24,
crypto_secretbox_ZEROBYTES = 32,
@@ -2174,6 +1801,8 @@ var crypto_secretbox_KEYBYTES = 32,
crypto_box_NONCEBYTES = crypto_secretbox_NONCEBYTES,
crypto_box_ZEROBYTES = crypto_secretbox_ZEROBYTES,
crypto_box_BOXZEROBYTES = crypto_secretbox_BOXZEROBYTES,
crypto_box_SEALBYTES = 48,
crypto_box_BEFORENMBYTES = 32,
crypto_sign_BYTES = 64,
crypto_sign_PUBLICKEYBYTES = 32,
crypto_sign_SECRETKEYBYTES = 64,
@@ -2184,8 +1813,6 @@ 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
sodium.crypto_sign_PUBLICKEYBYTES = crypto_sign_PUBLICKEYBYTES
sodium.crypto_sign_SECRETKEYBYTES = crypto_sign_SECRETKEYBYTES
@@ -2200,11 +1827,8 @@ 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
sodium.crypto_stream = crypto_stream_wrap
sodium.crypto_stream_xor = crypto_stream_xor_wrap
forward(require('./randombytes'))
forward(require('./crypto_stream'))
sodium.crypto_scalarmult_BYTES = crypto_scalarmult_BYTES
sodium.crypto_scalarmult_SCALARBYTES = crypto_scalarmult_SCALARBYTES
@@ -2216,6 +1840,20 @@ sodium.crypto_secretbox_NONCEBYTES = crypto_secretbox_NONCEBYTES,
sodium.crypto_secretbox_MACBYTES = 16
sodium.crypto_secretbox_easy = crypto_secretbox_easy
sodium.crypto_secretbox_open_easy = crypto_secretbox_open_easy
sodium.crypto_secretbox_detached = crypto_secretbox_detached
sodium.crypto_secretbox_open_detached = crypto_secretbox_open_detached
sodium.crypto_box_PUBLICKEYBYTES = crypto_box_PUBLICKEYBYTES
sodium.crypto_box_SECRETKEYBYTES = crypto_box_SECRETKEYBYTES
sodium.crypto_box_SEALBYTES = crypto_box_SEALBYTES
sodium.crypto_box_BEFORENMBYTES = crypto_box_BEFORENMBYTES
sodium.crypto_box_keypair = crypto_box_keypair
sodium.crypto_box_seal = crypto_box_seal
sodium.crypto_box_seal_open = crypto_box_seal_open
sodium.sodium_malloc = function (n) {
return new Uint8Array(n)
}
function cleanup(arr) {
for (var i = 0; i < arr.length; i++) arr[i] = 0;
@@ -2230,31 +1868,3 @@ function forward (submodule) {
module.exports[prop] = submodule[prop]
})
}
(function() {
// Initialize PRNG if environment provides CSPRNG.
// If not, methods calling randombytes will throw.
var crypto = typeof self !== 'undefined' ? (self.crypto || self.msCrypto) : null;
if (crypto && crypto.getRandomValues) {
// Browsers.
var QUOTA = 65536;
randombytes = function(x, n) {
var i, v = new Uint8Array(n);
for (i = 0; i < n; i += QUOTA) {
crypto.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA)));
}
for (i = 0; i < n; i++) x[i] = v[i];
cleanup(v);
};
} else if (typeof require !== 'undefined') {
// Node.js.
crypto = require('cry' + 'pto');
if (crypto && crypto.randomBytes) {
randombytes = function(x, n) {
var i, v = crypto.randomBytes(n);
for (i = 0; i < n; i++) x[i] = v[i];
cleanup(v);
};
}
}
})();
+16 -11
View File
@@ -1,24 +1,29 @@
{
"name": "sodium-javascript",
"version": "0.3.0",
"version": "0.5.6",
"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",
"xsalsa20": "^1.0.0"
},
"devDependencies": {
"sodium-test": "^0.4.0"
"browser-run": "^4.0.2",
"browserify": "^14.1.0",
"sodium-test": "^0.7.0"
},
"browser": {
"crypto": false
},
"react-native": {
"crypto": "crypto"
},
"scripts": {
"test": " node test.js"
},
"browserify": {
"transform": [
"brfs"
]
"browser": "browserify test.js | browser-run",
"browser-manual": "browserify test.js | browser-run -p 1234",
"test": "node test.js"
},
"repository": {
"type": "git",
+40
View File
@@ -0,0 +1,40 @@
var assert = require('nanoassert')
var randombytes = (function () {
var QUOTA = 65536 // limit for QuotaExceededException
var crypto = typeof global !== 'undefined' ? crypto = (global.crypto || global.msCrypto) : null
function browserBytes (out, n) {
for (var i = 0; i < n; i += QUOTA) {
crypto.getRandomValues(out.subarray(i, i + Math.min(n - i, QUOTA)))
}
}
function nodeBytes (out, n) {
out.set(crypto.randomBytes(n))
}
function noImpl () {
throw new Error('No secure random number generator available')
}
if (crypto && crypto.getRandomValues) {
return browserBytes
} else if (typeof require !== 'undefined') {
// Node.js.
crypto = require('crypto')
if (crypto && crypto.randomBytes) {
return nodeBytes
}
}
return noImpl
})()
Object.defineProperty(module.exports, 'randombytes', {
value: randombytes
})
module.exports.randombytes_buf = function (out) {
assert(out, 'out must be given')
randombytes(out, out.length)
}
+2
View File
@@ -1 +1,3 @@
require('sodium-test')(require('.'))
if (typeof window !== 'undefined') window.close()
BIN
View File
Binary file not shown.
-348
View File
@@ -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)))))
)
)