Compare commits

...
39 Commits
Author SHA1 Message Date
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
Mathias Buus d546f63e11 0.3.0 2017-06-12 10:19:02 +02:00
Mathias Buus 78f7c7111c add wasm info 2017-06-12 10:15:52 +02:00
Mathias Buus 51875f2288 remove unused assert 2017-06-12 10:10:01 +02:00
Mathias Buus 95732bdd4f add crypto_shorthash (#4) 2017-06-12 10:05:49 +02:00
Emil Bay 1967024766 Update to new blake2b 2017-06-11 20:23:06 +02:00
Emil Bay 776ffea91c Fix keygen overflow bug 2017-06-11 10:44:02 +02:00
Emil Bay 56913733b9 0.2.0 2017-06-07 22:39:24 +02:00
Emil Bay 94e3891f67 Added crypto_kdf 2017-06-07 22:38:40 +02:00
Emil Bay afa3b5fc04 0.1.0 2017-06-06 21:05:48 +02:00
Emil Bay 226ecd8778 Add memzero 2017-06-06 21:04:50 +02:00
Emil Bay 5397910bbb Add blake2b for generichash 2017-06-06 21:04:36 +02:00
Emil Bay f639c1ce6f Fix sodium-test require 2017-04-13 17:59:36 +02:00
Emil Bay 92bea299c6 Add sodium-test script 2017-04-11 22:19:34 +02:00
9 changed files with 227 additions and 513 deletions
+34
View File
@@ -0,0 +1,34 @@
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_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++) {
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(outlen, key)
}
blake2b.ready(function (err) {
module.exports.crypto_generichash_WASM_LOADED = blake2b.WASM_LOADED
})
+39
View File
@@ -0,0 +1,39 @@
var assert = require('nanoassert')
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 = 32
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 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)
var outlen = Math.min(subkey.length, module.exports.crypto_kdf_BYTES_MAX)
blake2b(outlen, key.subarray(0, module.exports.crypto_kdf_KEYBYTES), salt, ctx_padded, true)
.final(subkey)
}
module.exports.crypto_kdf_keygen = function crypto_kdf_keygen (out) {
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))
}
+12
View File
@@ -0,0 +1,12 @@
var siphash = require('siphash24')
exports.crypto_shorthash_PRIMITIVE = 'siphash24'
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
function shorthash (out, data, key, noAssert) {
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()
+43 -510
View File
@@ -3,6 +3,7 @@
// 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 +17,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 +57,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 +414,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 +987,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 +1601,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 +1682,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,21 +1736,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,
@@ -2195,7 +1754,9 @@ var crypto_secretbox_KEYBYTES = 32,
crypto_sign_SEEDBYTES = 32,
crypto_hash_BYTES = 64;
sodium.randombytes_buf = randombytes_buf
sodium.memzero = function (len, offset) {
for (var i = offset; i < len; i++) arr[i] = 0;
}
sodium.crypto_sign_BYTES = crypto_sign_BYTES
sodium.crypto_sign_PUBLICKEYBYTES = crypto_sign_PUBLICKEYBYTES
@@ -2208,10 +1769,11 @@ sodium.crypto_sign_open = crypto_sign_open
sodium.crypto_sign_detached = crypto_sign_detached
sodium.crypto_sign_verify_detached = crypto_sign_verify_detached
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('./crypto_generichash'))
forward(require('./crypto_kdf'))
forward(require('./crypto_shorthash'))
forward(require('./randombytes'))
forward(require('./crypto_stream'))
sodium.crypto_scalarmult_BYTES = crypto_scalarmult_BYTES
sodium.crypto_scalarmult_SCALARBYTES = crypto_scalarmult_SCALARBYTES
@@ -2223,15 +1785,8 @@ 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_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
sodium.crypto_secretbox_detached = crypto_secretbox_detached
sodium.crypto_secretbox_open_detached = crypto_secretbox_open_detached
function cleanup(arr) {
for (var i = 0; i < arr.length; i++) arr[i] = 0;
@@ -2241,30 +1796,8 @@ function check (buf, len) {
if (!buf || (len && buf.length < len)) throw new Error('Argument must be a buffer' + (len ? ' of length ' + len : ''))
}
(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);
};
}
}
})();
function forward (submodule) {
Object.keys(submodule).forEach(function (prop) {
module.exports[prop] = submodule[prop]
})
}
+21 -3
View File
@@ -1,12 +1,30 @@
{
"name": "sodium-javascript",
"version": "0.0.1",
"version": "0.5.5",
"description": "WIP - a pure javascript version of sodium-native",
"main": "index.js",
"dependencies": {
"blakejs": "^1.0.1"
"blake2b": "^2.1.1",
"nanoassert": "^1.0.0",
"siphash24": "^1.0.1",
"xsalsa20": "^1.0.0"
},
"devDependencies": {
"browser-run": "^4.0.2",
"browserify": "^14.1.0",
"sodium-test": "^0.7.0"
},
"browser": {
"crypto": false
},
"react-native": {
"crypto": "crypto"
},
"scripts": {
"browser": "browserify test.js | browser-run",
"browser-manual": "browserify test.js | browser-run -p 1234",
"test": "node test.js"
},
"devDependencies": {},
"repository": {
"type": "git",
"url": "https://github.com/mafintosh/sodium-javascript.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)
}
+3
View File
@@ -0,0 +1,3 @@
require('sodium-test')(require('.'))
if (typeof window !== 'undefined') window.close()