Compare commits

..
24 Commits
Author SHA1 Message Date
Christophe Diederichs 0fba70b6fa add crypto_auth_hmac methods 2020-09-03 12:49:05 +02:00
Mathias Buus a546f3e51d 0.6.2 2020-08-12 15:40:16 +02:00
Emil BayandMathias Buus a338ae9f9d Missing helpers (#24)
* Detach buffers by sending to an empty message channel

* Move helpers out

* fix import

* export helpers

* Try browser testing

* messagechannel check

* xvfb-run --auto-servernum npm run test-browser fails weirdly on ci, removing

Co-authored-by: Mathias Buus <mathiasbuus@gmail.com>
2020-08-12 15:39:14 +02:00
Christophe Diederichs e4693065fd update dependencies 2020-07-13 14:53:38 +02:00
Christophe Diederichs 44e5985630 change to universal hashes 2020-07-13 14:53:38 +02:00
Emil Bay f11ff5a727 0.6.1 2020-06-24 16:30:16 +02:00
Emil Bay 9c30d3ead8 Nicer message formatting 2020-06-24 16:14:52 +02:00
Emil Bay ddcdae69a1 Upgrade secretbox to sodium-native like api (not exposed there) 2020-06-24 16:12:12 +02:00
Emil Bay 80dd633012 Upgrade onetimeauth to sodium-native api 2020-06-24 16:11:56 +02:00
Emil Bay d8d59d0443 Add note on sodium-universal 2020-06-24 15:06:54 +02:00
Emil Bay ef00ddc878 Fix URLs 2020-06-24 15:06:48 +02:00
Emil Bay cc52e58504 Update package metadata 2020-06-24 15:02:49 +02:00
Emil Bay 7b518f7b2c Fix offset ArrayBuffer views 2020-06-24 15:01:10 +02:00
Emil Bay 74a1067746 Fix filling larger width TypedArrays 2020-06-24 14:55:46 +02:00
Emil Bay 919896d2bb Revert accidental sign API change 2020-06-24 14:49:51 +02:00
Emil Bay f3a80cb6f5 Upgrade deps 2020-06-24 14:49:38 +02:00
Emil Bay 40f9b887f4 Modernise example 2020-06-24 14:49:26 +02:00
Emil Bay 2ca6264f50 Add travis 2020-06-24 14:49:11 +02:00
Emil Bay 9d65d19e86 Standardize readme file 2020-06-24 14:49:05 +02:00
Emil Bay 30c3342156 Make linter happy 2020-06-24 14:08:55 +02:00
Emil Bay 930e77ad32 Move internal primitives 2020-06-24 14:02:00 +02:00
Emil Bay e9ac929b5a Move memory helpers to their own module 2020-06-24 14:01:48 +02:00
Emil Bay e77c70ef71 Bust crypto in browserify 2020-06-24 13:37:16 +02:00
Emil Bay 4bb40aa43d Clean up random bytes 2020-06-24 13:37:07 +02:00
24 changed files with 570 additions and 378 deletions
+18
View File
@@ -0,0 +1,18 @@
language: node_js
node_js:
- lts/*
env:
global:
- MOZ_HEADLESS=1
services:
- xvfb
addons:
firefox: latest
chrome: stable
cache:
npm: false
script:
- npm test
- xvfb-run --auto-servernum npm run test-browser -- --browser chrome
- xvfb-run --auto-servernum npm run test-browser -- --browser firefox
+23 -14
View File
@@ -1,31 +1,29 @@
# sodium-javascript
# `sodium-javascript`
WIP - a pure javascript version of [sodium-native](https://github.com/mafintosh/sodium-native).
[![Build Status](https://travis-ci.org/sodium-friends/sodium-javascript.svg?branch=master)](https://travis-ci.org/sodium-friends/sodium-javascript)
> WIP - a pure javascript version of [sodium-native](https://github.com/sodium-friends/sodium-native).
Based on tweetnacl
```
npm install sodium-javascript
```
## Usage
``` js
var sodium = require('sodium-javascript')
const sodium = require('sodium-javascript')
var key = new Buffer(sodium.crypto_secretbox_KEYBYTES)
var nonce = new Buffer(sodium.crypto_secretbox_NONCEBYTES)
const key = Buffer.alloc(sodium.crypto_secretbox_KEYBYTES)
const nonce = Buffer.alloc(sodium.crypto_secretbox_NONCEBYTES)
sodium.randombytes_buf(key)
sodium.randombytes_buf(nonce)
var message = new Buffer('Hello, World!')
var cipher = new Buffer(message.length + sodium.crypto_secretbox_MACBYTES)
const message = Buffer.from('Hello, World!')
const cipher = Buffer.alloc(message.length + sodium.crypto_secretbox_MACBYTES)
sodium.crypto_secretbox_easy(cipher, message, nonce, key)
console.log('Encrypted:', cipher)
var plainText = new Buffer(cipher.length - sodium.crypto_secretbox_MACBYTES)
const plainText = Buffer.alloc(cipher.length - sodium.crypto_secretbox_MACBYTES)
sodium.crypto_secretbox_open_easy(plainText, cipher, nonce, key)
@@ -34,9 +32,20 @@ console.log('Plaintext:', plainText.toString())
## API
See [sodium-native](https://github.com/mafintosh/sodium-native).
See [sodium-native](https://github.com/sodium-friends/sodium-native).
This is a work in progress so all functions are not implemented yet.
This module is organised into individual submodules which can be required
independently for smaller bundles in the browser. To leverage automatic
switching between `sodium-javascript` and `sodium-native`, see
[`sodium-universal`](https://github.com/sodium-friends/sodium-universal).
## Install
```
npm install sodium-javascript
```
## License
MIT
[MIT](LICENSE)
+2 -1
View File
@@ -1,6 +1,7 @@
/* eslint-disable camelcase */
const { crypto_stream_chacha20_ietf, crypto_stream_chacha20_ietf_xor_ic } = require('./crypto_stream_chacha20')
const { crypto_verify_16 } = require('./crypto_verify')
const Poly1305 = require('./poly1305.js')
const Poly1305 = require('./internal/poly1305')
const assert = require('nanoassert')
const crypto_aead_chacha20poly1305_ietf_KEYBYTES = 32
+72
View File
@@ -0,0 +1,72 @@
/* eslint-disable camelcase */
const { crypto_verify_32, crypto_verify_64 } = require('./crypto_verify')
const Sha256 = require('sha256-universal')
const Sha512 = require('sha512-universal')
const assert = require('nanoassert')
const crypto_auth_hmacsha256_BYTES = 32
const crypto_auth_hmacsha256_KEYBYTES = 32
const crypto_auth_hmacsha512_BYTES = 64
const crypto_auth_hmacsha512_KEYBYTES = 32
const crypto_auth_hmacsha512256_BYTES = 32
const crypto_auth_hmacsha512256_KEYBYTES = 32
function crypto_auth_hmacsha256 (out, input, k) {
assert(out.byteLength === crypto_auth_hmacsha256_BYTES, "out should be 'crypto_auth_hmacsha256_BYTES' in length")
const hmac = Sha256.HMAC(key)
hmac.update(input)
return hmac.digest(out)
}
function crypto_auth_hmacsha256_verify (h, input, k) {
const correct = Sha256.HMAC(k).update(input).digest()
return crypto_verify_32(h, 0, correct, 0) | sodium_memcmp(correct, h, 32)
}
function crypto_auth_hmacsha512 (out, input, k) {
assert(out.byteLength === crypto_auth_hmacsha512_BYTES, "out should be 'crypto_auth_hmacsha512_BYTES' in length")
const hmac = Sha512.HMAC(key)
hmac.update(input)
return hmac.digest(out)
}
function crypto_auth_hmacsha512_verify (h, input, k) {
const correct = Sha512.HMAC(k).update(input).digest()
return crypto_verify_64(h, 0, correct, 0) | sodium_memcmp(correct, h, 64)
}
function crypto_auth_hmacsha512256 (out, input, k) {
assert(out.byteLength === crypto_auth_hmacsha512_BYTES, "out should be 'crypto_auth_hmacsha512256_BYTES' in length")
const out0 = Buffer.alloc(64)
const hmac = Sha512.HMAC(key)
hmac.update(input)
hmac.digest(out)
out.set(out0.subarray(0, 32))
}
function crypto_auth_hmacsha512256_verify (h, input, k) {
const correct = Sha512.HMAC(k).update(input).digest()
return crypto_verify_32(h, 0, correct, 0) | sodium_memcmp(correct, h, 32)
}
module.exports = {
crypto_auth_hmacsha256_BYTES,
crypto_auth_hmacsha256_KEYBYTES,
crypto_auth_hmacsha512_BYTES,
crypto_auth_hmacsha512_KEYBYTES,
crypto_auth_hmacsha512256_BYTES,
crypto_auth_hmacsha512256_KEYBYTES,
crypto_auth_hmacsha256,
crypto_auth_hmacsha256_verify,
crypto_auth_hmacsha512,
crypto_auth_hmacsha512_verify,
crypto_auth_hmacsha512256,
crypto_auth_hmacsha512256_verify
}
+17 -18
View File
@@ -1,3 +1,4 @@
/* eslint-disable camelcase */
const { crypto_hash_sha512 } = require('./crypto_hash')
const { crypto_scalarmult, crypto_scalarmult_base } = require('./crypto_scalarmult')
const { randombytes } = require('./randombytes')
@@ -6,15 +7,14 @@ const { crypto_secretbox_open_easy, crypto_secretbox_easy } = require('./crypto_
const xsalsa20 = require('xsalsa20')
const assert = require('nanoassert')
var crypto_box_PUBLICKEYBYTES = 32,
crypto_box_SECRETKEYBYTES = 32,
crypto_box_BEFORENMBYTES = 32,
crypto_box_NONCEBYTES = 24,
crypto_box_ZEROBYTES = 32,
crypto_box_BOXZEROBYTES = 16,
crypto_box_SEALBYTES = 48,
crypto_box_SEEDBYTES = 32,
crypto_box_BEFORENMBYTES = 32
const crypto_box_PUBLICKEYBYTES = 32
const crypto_box_SECRETKEYBYTES = 32
const crypto_box_NONCEBYTES = 24
const crypto_box_ZEROBYTES = 32
const crypto_box_BOXZEROBYTES = 16
const crypto_box_SEALBYTES = 48
const crypto_box_SEEDBYTES = 32
const crypto_box_BEFORENMBYTES = 32
module.exports = {
crypto_box_keypair,
@@ -23,7 +23,6 @@ module.exports = {
crypto_box_seal_open,
crypto_box_PUBLICKEYBYTES,
crypto_box_SECRETKEYBYTES,
crypto_box_BEFORENMBYTES,
crypto_box_NONCEBYTES,
crypto_box_ZEROBYTES,
crypto_box_BOXZEROBYTES,
@@ -32,14 +31,14 @@ module.exports = {
crypto_box_BEFORENMBYTES
}
function crypto_box_keypair(pk, sk) {
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_seed_keypair(pk, sk, seed) {
function crypto_box_seed_keypair (pk, sk, seed) {
assert(pk.byteLength === crypto_box_PUBLICKEYBYTES, "pk should be 'crypto_box_PUBLICKEYBYTES' bytes")
assert(sk.byteLength === crypto_box_SECRETKEYBYTES, "sk should be 'crypto_box_SECRETKEYBYTES' bytes")
assert(sk.byteLength === crypto_box_SEEDBYTES, "sk should be 'crypto_box_SEEDBYTES' bytes")
@@ -52,7 +51,7 @@ function crypto_box_seed_keypair(pk, sk, seed) {
return crypto_scalarmult_base(pk, sk)
}
function crypto_box_seal(c, m, pk) {
function crypto_box_seal (c, m, pk) {
check(c, crypto_box_SEALBYTES + m.length)
check(pk, crypto_box_PUBLICKEYBYTES)
@@ -61,7 +60,7 @@ function crypto_box_seal(c, m, pk) {
crypto_box_keypair(epk, esk)
var n = new Uint8Array(crypto_box_NONCEBYTES)
crypto_generichash_batch(n, [ epk, pk ])
crypto_generichash_batch(n, [epk, pk])
var s = new Uint8Array(crypto_box_PUBLICKEYBYTES)
crypto_scalarmult(s, esk, pk)
@@ -75,7 +74,7 @@ function crypto_box_seal(c, m, pk) {
cleanup(esk)
}
function crypto_box_seal_open(m, c, pk, sk) {
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)
@@ -84,7 +83,7 @@ function crypto_box_seal_open(m, c, pk, sk) {
var epk = c.subarray(0, crypto_box_PUBLICKEYBYTES)
var n = new Uint8Array(crypto_box_NONCEBYTES)
crypto_generichash_batch(n, [ epk, pk ])
crypto_generichash_batch(n, [epk, pk])
var s = new Uint8Array(crypto_box_PUBLICKEYBYTES)
crypto_scalarmult(s, sk, epk)
@@ -100,6 +99,6 @@ function check (buf, len) {
if (!buf || (len && buf.length < len)) throw new Error('Argument must be a buffer' + (len ? ' of length ' + len : ''))
}
function cleanup(arr) {
for (var i = 0; i < arr.length; i++) arr[i] = 0;
function cleanup (arr) {
for (let i = 0; i < arr.length; i++) arr[i] = 0
}
+1 -1
View File
@@ -31,6 +31,6 @@ module.exports.crypto_generichash_instance = function (key, outlen) {
return blake2b(outlen, key)
}
blake2b.ready(function (err) {
blake2b.ready(function (_) {
module.exports.crypto_generichash_WASM_LOADED = blake2b.WASM_LOADED
})
+4 -3
View File
@@ -1,10 +1,11 @@
const sha512 = require('sha512-wasm')
/* eslint-disable camelcase */
const sha512 = require('sha512-universal')
const assert = require('nanoassert')
if (new Uint16Array([1])[0] !== 1) throw new Error('Big endian architecture is not supported.')
var crypto_hash_sha512_BYTES = 64
var crypto_hash_BYTES = crypto_hash_sha512_BYTES
const crypto_hash_sha512_BYTES = 64
const crypto_hash_BYTES = crypto_hash_sha512_BYTES
function crypto_hash_sha512 (out, m, n) {
assert(out.byteLength === crypto_hash_sha512_BYTES, "out must be 'crypto_hash_sha512_BYTES' bytes long")
+3 -2
View File
@@ -1,9 +1,10 @@
const sha256 = require('sha256-wasm')
/* eslint-disable camelcase */
const sha256 = require('sha256-universal')
const assert = require('nanoassert')
if (new Uint16Array([1])[0] !== 1) throw new Error('Big endian architecture is not supported.')
var crypto_hash_sha256_BYTES = 32
const crypto_hash_sha256_BYTES = 32
function crypto_hash_sha256 (out, m, n) {
assert(out.byteLength === crypto_hash_sha256_BYTES, "out must be 'crypto_hash_sha256_BYTES' bytes long")
+5 -4
View File
@@ -1,6 +1,7 @@
var assert = require('nanoassert')
var randombytes_buf = require('./randombytes').randombytes_buf
var blake2b = require('blake2b')
/* eslint-disable camelcase */
const assert = require('nanoassert')
const randombytes_buf = require('./randombytes').randombytes_buf
const blake2b = require('blake2b')
module.exports.crypto_kdf_PRIMITIVE = 'blake2b'
module.exports.crypto_kdf_BYTES_MIN = 16
@@ -8,7 +9,7 @@ module.exports.crypto_kdf_BYTES_MAX = 64
module.exports.crypto_kdf_CONTEXTBYTES = 8
module.exports.crypto_kdf_KEYBYTES = 32
function STORE64_LE(dest, int) {
function STORE64_LE (dest, int) {
var mul = 1
var i = 0
dest[0] = int & 0xFF
+4 -3
View File
@@ -1,11 +1,12 @@
/* eslint-disable camelcase */
const { crypto_scalarmult_base } = require('./crypto_scalarmult')
const { crypto_generichash } = require('./crypto_generichash')
const { randombytes_buf } = require('./randombytes')
const assert = require('nanoassert')
var crypto_kx_SEEDBYTES = 32
var crypto_kx_PUBLICKEYBYTES = 32
var crypto_kx_SECRETKEYBYTES = 32
const crypto_kx_SEEDBYTES = 32
const crypto_kx_PUBLICKEYBYTES = 32
const crypto_kx_SECRETKEYBYTES = 32
function crypto_kx_keypair (pk, sk) {
assert(pk.byteLength === crypto_kx_PUBLICKEYBYTES, "pk must be 'crypto_kx_PUBLICKEYBYTES' bytes")
+28 -11
View File
@@ -1,20 +1,37 @@
const poly1305 = require('./poly1305')
/* eslint-disable camelcase */
const assert = require('nanoassert')
const Poly1305 = require('./internal/poly1305')
const { crypto_verify_16 } = require('./crypto_verify')
const crypto_onetimeauth_BYTES = 16
const crypto_onetimeauth_KEYBYTES = 32
const crypto_onetimeauth_PRIMITIVE = 'poly1305'
module.exports = {
crypto_onetimeauth,
crypto_onetimeauth_verify
crypto_onetimeauth_verify,
crypto_onetimeauth_BYTES,
crypto_onetimeauth_KEYBYTES,
crypto_onetimeauth_PRIMITIVE
}
function crypto_onetimeauth(out, outpos, m, mpos, n, k) {
var s = new poly1305(k);
s.update(m, mpos, n);
s.finish(out, outpos);
return 0;
function crypto_onetimeauth (mac, msg, key) {
assert(mac.byteLength === crypto_onetimeauth_BYTES, "mac must be 'crypto_onetimeauth_BYTES' bytes")
assert(msg.byteLength != null, 'msg must be buffer')
assert(key.byteLength === crypto_onetimeauth_KEYBYTES, "key must be 'crypto_onetimeauth_KEYBYTES' bytes")
var s = new Poly1305(key)
s.update(msg, 0, msg.byteLength)
s.finish(mac, 0)
return true
}
function crypto_onetimeauth_verify(h, hpos, m, mpos, n, k) {
var x = new Uint8Array(16);
crypto_onetimeauth(x,0,m,mpos,n,k);
return crypto_verify_16(h,hpos,x,0);
function crypto_onetimeauth_verify (mac, msg, key) {
assert(mac.byteLength === crypto_onetimeauth_BYTES, "mac must be 'crypto_onetimeauth_BYTES' bytes")
assert(msg.byteLength != null, 'msg must be buffer')
assert(key.byteLength === crypto_onetimeauth_KEYBYTES, "key must be 'crypto_onetimeauth_KEYBYTES' bytes")
var tmp = new Uint8Array(16)
crypto_onetimeauth(tmp, msg, key)
return crypto_verify_16(mac, 0, tmp, 0) === 0
}
+5 -6
View File
@@ -1,9 +1,8 @@
const { _9, _121665, gf, inv25519, pack25519, unpack25519, sel25519, A, M, Z, S } = require('./ed25519.js')
/* eslint-disable camelcase, one-var */
const { _9, _121665, gf, inv25519, pack25519, unpack25519, sel25519, A, M, Z, S } = require('./internal/ed25519')
var crypto_scalarmult_BYTES = 32
var crypto_scalarmult_SCALARBYTES = 32
var crypto_scalarmult_BYTES = 32
var crypto_scalarmult_SCALARBYTES = 32
const crypto_scalarmult_BYTES = 32
const crypto_scalarmult_SCALARBYTES = 32
module.exports = {
crypto_scalarmult,
@@ -19,7 +18,7 @@ function crypto_scalarmult (q, n, p) {
var z = new Uint8Array(32)
var x = new Float64Array(80), r, i
var a = gf(), b = gf(), c = gf(),
d = gf(), e = gf(), f = gf()
d = gf(), e = gf(), f = gf()
for (i = 0; i < 31; i++) z[i] = n[i]
z[31] = (n[31] & 127) | 64
z[0] &= 248
+87 -67
View File
@@ -1,11 +1,13 @@
var { crypto_stream, crypto_stream_xor } = require('./crypto_stream')
var { crypto_onetimeauth, crypto_onetimeauth_verify } = require('./crypto_onetimeauth')
/* eslint-disable camelcase */
const assert = require('nanoassert')
const { crypto_stream, crypto_stream_xor } = require('./crypto_stream')
const { crypto_onetimeauth, crypto_onetimeauth_verify, crypto_onetimeauth_BYTES, crypto_onetimeauth_KEYBYTES } = require('./crypto_onetimeauth')
var crypto_secretbox_KEYBYTES = 32,
crypto_secretbox_NONCEBYTES = 24,
crypto_secretbox_ZEROBYTES = 32,
crypto_secretbox_BOXZEROBYTES = 16,
crypto_secretbox_MACBYTES = 16
const crypto_secretbox_KEYBYTES = 32
const crypto_secretbox_NONCEBYTES = 24
const crypto_secretbox_ZEROBYTES = 32
const crypto_secretbox_BOXZEROBYTES = 16
const crypto_secretbox_MACBYTES = 16
module.exports = {
crypto_secretbox,
@@ -21,73 +23,91 @@ module.exports = {
crypto_secretbox_MACBYTES
}
function crypto_secretbox (c, m, d, n, k) {
var i
if (d < 32) return -1
function crypto_secretbox (c, m, n, k) {
assert(c.byteLength === m.byteLength, "c must be 'm.byteLength' bytes")
const mlen = m.byteLength
assert(mlen >= crypto_secretbox_ZEROBYTES, "mlen must be at least 'crypto_secretbox_ZEROBYTES'")
assert(n.byteLength === crypto_secretbox_NONCEBYTES, "n must be 'crypto_secretbox_NONCEBYTES' bytes")
assert(k.byteLength === crypto_secretbox_KEYBYTES, "k must be 'crypto_secretbox_KEYBYTES' bytes")
crypto_stream_xor(c, m, n, k)
crypto_onetimeauth(c, 16, c, 32, d - 32, c)
for (i = 0; i < 16; i++) c[i] = 0
crypto_onetimeauth(
c.subarray(crypto_secretbox_BOXZEROBYTES, crypto_secretbox_BOXZEROBYTES + crypto_onetimeauth_BYTES),
c.subarray(crypto_secretbox_BOXZEROBYTES + crypto_onetimeauth_BYTES, c.byteLength),
c.subarray(0, crypto_onetimeauth_KEYBYTES)
)
c.fill(0, 0, crypto_secretbox_BOXZEROBYTES)
return 0
}
function crypto_secretbox_open (m, c, d, n, k) {
var i
var x = new Uint8Array(32)
if (d < 32) return -1
function crypto_secretbox_open (m, c, n, k) {
assert(c.byteLength === m.byteLength, "c must be 'm.byteLength' bytes")
const mlen = m.byteLength
assert(mlen >= crypto_secretbox_ZEROBYTES, "mlen must be at least 'crypto_secretbox_ZEROBYTES'")
assert(n.byteLength === crypto_secretbox_NONCEBYTES, "n must be 'crypto_secretbox_NONCEBYTES' bytes")
assert(k.byteLength === crypto_secretbox_KEYBYTES, "k must be 'crypto_secretbox_KEYBYTES' bytes")
const x = new Uint8Array(crypto_onetimeauth_KEYBYTES)
crypto_stream(x, n, k)
if (crypto_onetimeauth_verify(c, 16, c, 32, d - 32, x) !== 0) return -1
const validMac = crypto_onetimeauth_verify(
c.subarray(crypto_secretbox_BOXZEROBYTES, crypto_secretbox_BOXZEROBYTES + crypto_onetimeauth_BYTES),
c.subarray(crypto_secretbox_BOXZEROBYTES + crypto_onetimeauth_BYTES, c.byteLength),
x
)
if (validMac === false) return false
crypto_stream_xor(m, c, n, k)
for (i = 0; i < 32; i++) m[i] = 0
return 0
}
function crypto_secretbox_detached (o, mac, msg, n, k) {
check(mac, 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_secretbox_open_detached (msg, o, mac, n, k) {
check(mac, 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) {
check(msg, 0)
check(o, msg.length + crypto_secretbox_MACBYTES)
check(n, crypto_secretbox_NONCEBYTES)
check(k, crypto_secretbox_KEYBYTES)
var i
var m = new Uint8Array(crypto_secretbox_ZEROBYTES + msg.length)
var c = new Uint8Array(m.length)
for (i = 0; i < msg.length; i++) m[i + crypto_secretbox_ZEROBYTES] = msg[i]
crypto_secretbox(c, m, m.length, n, k)
for (i = crypto_secretbox_BOXZEROBYTES; i < c.length; i++) o[i - crypto_secretbox_BOXZEROBYTES] = c[i]
}
function crypto_secretbox_open_easy(msg, box, n, k) {
check(box, crypto_secretbox_MACBYTES)
check(msg, box.length - crypto_secretbox_MACBYTES)
check(n, crypto_secretbox_NONCEBYTES)
check(k, crypto_secretbox_KEYBYTES)
var i
var c = new Uint8Array(crypto_secretbox_BOXZEROBYTES + box.length)
var m = new Uint8Array(c.length)
for (i = 0; i < box.length; i++) c[i + crypto_secretbox_BOXZEROBYTES] = box[i]
if (c.length < 32) return false
if (crypto_secretbox_open(m, c, c.length, n, k) !== 0) return false
for (i = crypto_secretbox_ZEROBYTES; i < m.length; i++) msg[i - crypto_secretbox_ZEROBYTES] = m[i]
m.fill(0, 0, 32)
return true
}
function check (buf, len) {
if (!buf || (len && buf.length < len)) throw new Error('Argument must be a buffer' + (len ? ' of length ' + len : ''))
function crypto_secretbox_detached (o, mac, msg, n, k) {
assert(o.byteLength === msg.byteLength, "o must be 'msg.byteLength' bytes")
assert(mac.byteLength === crypto_secretbox_MACBYTES, "mac must be 'crypto_secretbox_MACBYTES' bytes")
assert(n.byteLength === crypto_secretbox_NONCEBYTES, "n must be 'crypto_secretbox_NONCEBYTES' bytes")
assert(k.byteLength === crypto_secretbox_KEYBYTES, "k must be 'crypto_secretbox_KEYBYTES' bytes")
const tmp = new Uint8Array(msg.byteLength + mac.byteLength)
crypto_secretbox_easy(tmp, msg, n, k)
o.set(tmp.subarray(0, msg.byteLength))
mac.set(tmp.subarray(msg.byteLength))
return true
}
function crypto_secretbox_open_detached (msg, o, mac, n, k) {
assert(o.byteLength === msg.byteLength, "o must be 'msg.byteLength' bytes")
assert(mac.byteLength === crypto_secretbox_MACBYTES, "mac must be 'crypto_secretbox_MACBYTES' bytes")
assert(n.byteLength === crypto_secretbox_NONCEBYTES, "n must be 'crypto_secretbox_NONCEBYTES' bytes")
assert(k.byteLength === crypto_secretbox_KEYBYTES, "k must be 'crypto_secretbox_KEYBYTES' bytes")
const tmp = new Uint8Array(o.byteLength + mac.byteLength)
tmp.set(o)
tmp.set(mac, msg.byteLength)
return crypto_secretbox_open_easy(msg, tmp, n, k)
}
function crypto_secretbox_easy (o, msg, n, k) {
assert(o.byteLength === msg.byteLength + crypto_secretbox_MACBYTES, "o must be 'msg.byteLength + crypto_secretbox_MACBYTES' bytes")
assert(n.byteLength === crypto_secretbox_NONCEBYTES, "n must be 'crypto_secretbox_NONCEBYTES' bytes")
assert(k.byteLength === crypto_secretbox_KEYBYTES, "k must be 'crypto_secretbox_KEYBYTES' bytes")
const m = new Uint8Array(crypto_secretbox_ZEROBYTES + msg.byteLength)
const c = new Uint8Array(m.byteLength)
m.set(msg, crypto_secretbox_ZEROBYTES)
if (crypto_secretbox(c, m, n, k) === false) return false
o.set(c.subarray(crypto_secretbox_BOXZEROBYTES))
return true
}
function crypto_secretbox_open_easy (msg, box, n, k) {
assert(box.byteLength === msg.byteLength + crypto_secretbox_MACBYTES, "box must be 'msg.byteLength + crypto_secretbox_MACBYTES' bytes")
assert(n.byteLength === crypto_secretbox_NONCEBYTES, "n must be 'crypto_secretbox_NONCEBYTES' bytes")
assert(k.byteLength === crypto_secretbox_KEYBYTES, "k must be 'crypto_secretbox_KEYBYTES' bytes")
const c = new Uint8Array(crypto_secretbox_BOXZEROBYTES + box.byteLength)
const m = new Uint8Array(c.byteLength)
c.set(box, crypto_secretbox_BOXZEROBYTES)
if (crypto_secretbox_open(m, c, n, k) === false) return false
msg.set(m.subarray(crypto_secretbox_ZEROBYTES))
return true
}
+183 -180
View File
@@ -1,3 +1,4 @@
/* eslint-disable camelcase, one-var */
const { crypto_verify_32 } = require('./crypto_verify')
const { crypto_hash } = require('./crypto_hash')
const {
@@ -5,13 +6,13 @@ const {
X, Y, I, A, Z, M, S,
sel25519, pack25519,
inv25519, unpack25519
} = require('./ed25519')
} = require('./internal/ed25519')
const { randombytes } = require('./randombytes')
const crypto_sign_BYTES = 64,
crypto_sign_PUBLICKEYBYTES = 32,
crypto_sign_SECRETKEYBYTES = 64,
crypto_sign_SEEDBYTES = 32
const crypto_sign_BYTES = 64
const crypto_sign_PUBLICKEYBYTES = 32
const crypto_sign_SECRETKEYBYTES = 64
const crypto_sign_SEEDBYTES = 32
module.exports = {
crypto_sign_keypair,
@@ -26,107 +27,106 @@ module.exports = {
crypto_sign_SEEDBYTES
}
function set25519(r, a) {
var i;
for (i = 0; i < 16; i++) r[i] = a[i]|0;
function set25519 (r, a) {
for (let i = 0; i < 16; i++) r[i] = a[i] | 0
}
function pow2523(o, i) {
var c = gf();
var a;
for (a = 0; a < 16; a++) c[a] = i[a];
function pow2523 (o, i) {
var c = gf()
var a
for (a = 0; a < 16; a++) c[a] = i[a]
for (a = 250; a >= 0; a--) {
S(c, c);
if(a !== 1) M(c, c, i);
S(c, c)
if (a !== 1) M(c, c, i)
}
for (a = 0; a < 16; a++) o[a] = c[a];
for (a = 0; a < 16; a++) o[a] = c[a]
}
function add(p, q) {
function add (p, q) {
var a = gf(), b = gf(), c = gf(),
d = gf(), e = gf(), f = gf(),
g = gf(), h = gf(), t = gf();
d = gf(), e = gf(), f = gf(),
g = gf(), h = gf(), t = gf()
Z(a, p[1], p[0]);
Z(t, q[1], q[0]);
M(a, a, t);
A(b, p[0], p[1]);
A(t, q[0], q[1]);
M(b, b, t);
M(c, p[3], q[3]);
M(c, c, D2);
M(d, p[2], q[2]);
A(d, d, d);
Z(e, b, a);
Z(f, d, c);
A(g, d, c);
A(h, b, a);
Z(a, p[1], p[0])
Z(t, q[1], q[0])
M(a, a, t)
A(b, p[0], p[1])
A(t, q[0], q[1])
M(b, b, t)
M(c, p[3], q[3])
M(c, c, D2)
M(d, p[2], q[2])
A(d, d, d)
Z(e, b, a)
Z(f, d, c)
A(g, d, c)
A(h, b, a)
M(p[0], e, f);
M(p[1], h, g);
M(p[2], g, f);
M(p[3], e, h);
M(p[0], e, f)
M(p[1], h, g)
M(p[2], g, f)
M(p[3], e, h)
}
function cswap(p, q, b) {
var i;
function cswap (p, q, b) {
var i
for (i = 0; i < 4; i++) {
sel25519(p[i], q[i], b);
sel25519(p[i], q[i], b)
}
}
function pack(r, p) {
var tx = gf(), ty = gf(), zi = gf();
inv25519(zi, p[2]);
M(tx, p[0], zi);
M(ty, p[1], zi);
pack25519(r, ty);
r[31] ^= par25519(tx) << 7;
function pack (r, p) {
var tx = gf(), ty = gf(), zi = gf()
inv25519(zi, p[2])
M(tx, p[0], zi)
M(ty, p[1], zi)
pack25519(r, ty)
r[31] ^= par25519(tx) << 7
}
function scalarmult(p, q, s) {
var b, i;
set25519(p[0], gf0);
set25519(p[1], gf1);
set25519(p[2], gf1);
set25519(p[3], gf0);
function scalarmult (p, q, s) {
var b, i
set25519(p[0], gf0)
set25519(p[1], gf1)
set25519(p[2], gf1)
set25519(p[3], gf0)
for (i = 255; i >= 0; --i) {
b = (s[(i/8)|0] >> (i&7)) & 1;
cswap(p, q, b);
add(q, p);
add(p, p);
cswap(p, q, b);
b = (s[(i / 8) | 0] >> (i & 7)) & 1
cswap(p, q, b)
add(q, p)
add(p, p)
cswap(p, q, b)
}
}
function scalarbase(p, s) {
var q = [gf(), gf(), gf(), gf()];
set25519(q[0], X);
set25519(q[1], Y);
set25519(q[2], gf1);
M(q[3], X, Y);
scalarmult(p, q, s);
function scalarbase (p, s) {
var q = [gf(), gf(), gf(), gf()]
set25519(q[0], X)
set25519(q[1], Y)
set25519(q[2], gf1)
M(q[3], X, Y)
scalarmult(p, q, s)
}
function crypto_sign_keypair(pk, sk, seeded) {
function crypto_sign_keypair (pk, sk, seeded) {
check(pk, crypto_sign_PUBLICKEYBYTES)
check(sk, crypto_sign_SECRETKEYBYTES)
var d = new Uint8Array(64);
var p = [gf(), gf(), gf(), gf()];
var i;
var d = new Uint8Array(64)
var p = [gf(), gf(), gf(), gf()]
var i
if (!seeded) randombytes(sk, 32);
crypto_hash(d, sk, 32);
d[0] &= 248;
d[31] &= 127;
d[31] |= 64;
if (!seeded) randombytes(sk, 32)
crypto_hash(d, sk, 32)
d[0] &= 248
d[31] &= 127
d[31] |= 64
scalarbase(p, d);
pack(pk, p);
scalarbase(p, d)
pack(pk, p)
for (i = 0; i < 32; i++) sk[i+32] = pk[i];
return 0;
for (i = 0; i < 32; i++) sk[i + 32] = pk[i]
return 0
}
function crypto_sign_seed_keypair (pk, sk, seed) {
@@ -135,162 +135,165 @@ function crypto_sign_seed_keypair (pk, sk, seed) {
return crypto_sign_keypair(pk, sk, true)
}
var L = new Float64Array([0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10]);
var L = new Float64Array([0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10])
function modL(r, x) {
var carry, i, j, k;
function modL (r, x) {
var carry, i, j, k
for (i = 63; i >= 32; --i) {
carry = 0;
carry = 0
for (j = i - 32, k = i - 12; j < k; ++j) {
x[j] += carry - 16 * x[i] * L[j - (i - 32)];
carry = (x[j] + 128) >> 8;
x[j] -= carry * 256;
x[j] += carry - 16 * x[i] * L[j - (i - 32)]
carry = (x[j] + 128) >> 8
x[j] -= carry * 256
}
x[j] += carry;
x[i] = 0;
x[j] += carry
x[i] = 0
}
carry = 0;
carry = 0
for (j = 0; j < 32; j++) {
x[j] += carry - (x[31] >> 4) * L[j];
carry = x[j] >> 8;
x[j] &= 255;
x[j] += carry - (x[31] >> 4) * L[j]
carry = x[j] >> 8
x[j] &= 255
}
for (j = 0; j < 32; j++) x[j] -= carry * L[j];
for (j = 0; j < 32; j++) x[j] -= carry * L[j]
for (i = 0; i < 32; i++) {
x[i+1] += x[i] >> 8;
r[i] = x[i] & 255;
x[i + 1] += x[i] >> 8
r[i] = x[i] & 255
}
}
function reduce(r) {
var x = new Float64Array(64), i;
for (i = 0; i < 64; i++) x[i] = r[i];
for (i = 0; i < 64; i++) r[i] = 0;
modL(r, x);
function reduce (r) {
var x = new Float64Array(64)
for (let i = 0; i < 64; i++) x[i] = r[i]
for (let i = 0; i < 64; i++) r[i] = 0
modL(r, x)
}
// Note: difference from C - smlen returned, not passed as argument.
function crypto_sign(sm, m, sk) {
function crypto_sign (sm, m, sk) {
check(sm, crypto_sign_BYTES + m.length)
check(m, 0)
check(sk, crypto_sign_SECRETKEYBYTES)
var n = m.length
var d = new Uint8Array(64), h = new Uint8Array(64), r = new Uint8Array(64);
var i, j, x = new Float64Array(64);
var p = [gf(), gf(), gf(), gf()];
var d = new Uint8Array(64), h = new Uint8Array(64), r = new Uint8Array(64)
var i, j, x = new Float64Array(64)
var p = [gf(), gf(), gf(), gf()]
crypto_hash(d, sk, 32);
d[0] &= 248;
d[31] &= 127;
d[31] |= 64;
crypto_hash(d, sk, 32)
d[0] &= 248
d[31] &= 127
d[31] |= 64
var smlen = n + 64;
for (i = 0; i < n; i++) sm[64 + i] = m[i];
for (i = 0; i < 32; i++) sm[32 + i] = d[32 + i];
var smlen = n + 64
for (i = 0; i < n; i++) sm[64 + i] = m[i]
for (i = 0; i < 32; i++) sm[32 + i] = d[32 + i]
crypto_hash(r, sm.subarray(32), n+32);
reduce(r);
scalarbase(p, r);
pack(sm, p);
crypto_hash(r, sm.subarray(32), n + 32)
reduce(r)
scalarbase(p, r)
pack(sm, p)
for (i = 32; i < 64; i++) sm[i] = sk[i];
crypto_hash(h, sm, n + 64);
reduce(h);
for (i = 32; i < 64; i++) sm[i] = sk[i]
crypto_hash(h, sm, n + 64)
reduce(h)
for (i = 0; i < 64; i++) x[i] = 0;
for (i = 0; i < 32; i++) x[i] = r[i];
for (i = 0; i < 64; i++) x[i] = 0
for (i = 0; i < 32; i++) x[i] = r[i]
for (i = 0; i < 32; i++) {
for (j = 0; j < 32; j++) {
x[i+j] += h[i] * d[j];
x[i + j] += h[i] * d[j]
}
}
modL(sm.subarray(32), x);
modL(sm.subarray(32), x)
return smlen
}
function crypto_sign_detached(sig, 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 < crypto_sign_BYTES; i++) sig[i] = sm[i]
for (let i = 0; i < crypto_sign_BYTES; i++) sig[i] = sm[i]
}
function unpackneg(r, p) {
function unpackneg (r, p) {
var t = gf(), chk = gf(), num = gf(),
den = gf(), den2 = gf(), den4 = gf(),
den6 = gf();
den = gf(), den2 = gf(), den4 = gf(),
den6 = gf()
set25519(r[2], gf1);
unpack25519(r[1], p);
S(num, r[1]);
M(den, num, D);
Z(num, num, r[2]);
A(den, r[2], den);
set25519(r[2], gf1)
unpack25519(r[1], p)
S(num, r[1])
M(den, num, D)
Z(num, num, r[2])
A(den, r[2], den)
S(den2, den);
S(den4, den2);
M(den6, den4, den2);
M(t, den6, num);
M(t, t, den);
S(den2, den)
S(den4, den2)
M(den6, den4, den2)
M(t, den6, num)
M(t, t, den)
pow2523(t, t);
M(t, t, num);
M(t, t, den);
M(t, t, den);
M(r[0], t, den);
pow2523(t, t)
M(t, t, num)
M(t, t, den)
M(t, t, den)
M(r[0], t, den)
S(chk, r[0]);
M(chk, chk, den);
if (neq25519(chk, num)) M(r[0], r[0], I);
S(chk, r[0])
M(chk, chk, den)
if (neq25519(chk, num)) M(r[0], r[0], I)
S(chk, r[0]);
M(chk, chk, den);
if (neq25519(chk, num)) return -1;
S(chk, r[0])
M(chk, chk, den)
if (neq25519(chk, num)) return -1
if (par25519(r[0]) === (p[31]>>7)) Z(r[0], gf0, r[0]);
if (par25519(r[0]) === (p[31] >> 7)) Z(r[0], gf0, r[0])
M(r[3], r[0], r[1]);
return 0;
M(r[3], r[0], r[1])
return 0
}
function crypto_sign_open(msg, sm, pk) {
/* eslint-disable no-unused-vars */
function crypto_sign_open (msg, sm, pk) {
check(msg, sm.length - crypto_sign_BYTES)
check(sm, crypto_sign_BYTES)
check(pk, crypto_sign_PUBLICKEYBYTES)
var n = sm.length
var m = new Uint8Array(sm.length)
var i, mlen;
var t = new Uint8Array(32), h = new Uint8Array(64);
var i, mlen
var t = new Uint8Array(32), h = new Uint8Array(64)
var p = [gf(), gf(), gf(), gf()],
q = [gf(), gf(), gf(), gf()];
q = [gf(), gf(), gf(), gf()]
mlen = -1;
if (n < 64) return false;
mlen = -1
if (n < 64) return false
if (unpackneg(q, pk)) return false;
if (unpackneg(q, pk)) return false
for (i = 0; i < n; i++) m[i] = sm[i];
for (i = 0; i < 32; i++) m[i+32] = pk[i];
crypto_hash(h, m, n);
reduce(h);
scalarmult(p, q, h);
for (i = 0; i < n; i++) m[i] = sm[i]
for (i = 0; i < 32; i++) m[i + 32] = pk[i]
crypto_hash(h, m, n)
reduce(h)
scalarmult(p, q, h)
scalarbase(q, sm.subarray(32));
add(p, q);
pack(t, p);
scalarbase(q, sm.subarray(32))
add(p, q)
pack(t, p)
n -= 64;
n -= 64
if (crypto_verify_32(sm, 0, t, 0)) {
for (i = 0; i < n; i++) m[i] = 0;
return false;
for (i = 0; i < n; i++) m[i] = 0
return false
// throw new Error('crypto_sign_open failed')
}
for (i = 0; i < n; i++) msg[i] = sm[i + 64];
mlen = n;
return true;
for (i = 0; i < n; i++) msg[i] = sm[i + 64]
mlen = n
return true
}
/* eslint-enable no-unused-vars */
function crypto_sign_verify_detached (sig, m, pk) {
check(sig, crypto_sign_BYTES)
@@ -301,17 +304,17 @@ function crypto_sign_verify_detached (sig, m, pk) {
return crypto_sign_open(m, sm, pk)
}
function par25519(a) {
var d = new Uint8Array(32);
pack25519(d, a);
return d[0] & 1;
function par25519 (a) {
var d = new Uint8Array(32)
pack25519(d, a)
return d[0] & 1
}
function neq25519(a, b) {
var c = new Uint8Array(32), d = new Uint8Array(32);
pack25519(c, a);
pack25519(d, b);
return crypto_verify_32(c, 0, d, 0);
function neq25519 (a, b) {
var c = new Uint8Array(32), d = new Uint8Array(32)
pack25519(c, a)
pack25519(d, b)
return crypto_verify_32(c, 0, d, 0)
}
function check (buf, len) {
+3 -2
View File
@@ -1,4 +1,5 @@
var xsalsa20 = require('xsalsa20')
/* eslint-disable camelcase */
const xsalsa20 = require('xsalsa20')
if (new Uint16Array([1])[0] !== 1) throw new Error('Big endian architecture is not supported.')
@@ -12,7 +13,7 @@ exports.crypto_stream = function (c, nonce, key) {
}
exports.crypto_stream_xor = function (c, m, nonce, key) {
var xor = xsalsa20(nonce, key)
const xor = xsalsa20(nonce, key)
xor.update(m, c)
xor.final()
+13 -19
View File
@@ -1,34 +1,28 @@
const assert = require('nanoassert')
/* eslint-disable camelcase */
module.exports = {
crypto_verify_16,
crypto_verify_32,
sodium_memcmp,
sodium_is_zero
crypto_verify_32
}
function vn (x, xi, y, yi, n) {
var i, d = 0
for (i = 0; i < n; i++) d |= x[xi + i] ^ y[yi + i]
var d = 0
for (let i = 0; i < n; i++) d |= x[xi + i] ^ y[yi + i]
return (1 & ((d - 1) >>> 8)) - 1
}
function crypto_verify_16(x, xi, y, yi) {
// Make non enumerable as this is an internal function
Object.defineProperty(module.exports, 'vn', {
value: vn
})
function crypto_verify_16 (x, xi, y, yi) {
return vn(x, xi, y, yi, 16)
}
function crypto_verify_32(x, xi, y, yi) {
function crypto_verify_32 (x, xi, y, yi) {
return vn(x, xi, y, yi, 32)
}
function sodium_memcmp (a, b) {
assert(a.byteLength === b.byteLength, 'buffers must be the same size')
return vn(a, 0, b, 0, a.byteLength) === 0
}
function sodium_is_zero (arr) {
var d = 0
for (let i = 0; i < arr.length; i++) d |= arr[i]
return d === 0
function crypto_verify_64 (x, xi, y, yi) {
return vn(x, xi, y, yi, 64)
}
+6 -6
View File
@@ -1,19 +1,19 @@
var sodium = require('./')
const sodium = require('./')
var key = new Buffer(sodium.crypto_secretbox_KEYBYTES)
var nonce = new Buffer(sodium.crypto_secretbox_NONCEBYTES)
const key = Buffer.alloc(sodium.crypto_secretbox_KEYBYTES)
const nonce = Buffer.alloc(sodium.crypto_secretbox_NONCEBYTES)
sodium.randombytes_buf(key)
sodium.randombytes_buf(nonce)
var message = new Buffer('Hello, World!')
var cipher = new Buffer(message.length + sodium.crypto_secretbox_MACBYTES)
const message = Buffer.from('Hello, World!')
const cipher = Buffer.alloc(message.length + sodium.crypto_secretbox_MACBYTES)
sodium.crypto_secretbox_easy(cipher, message, nonce, key)
console.log('Encrypted:', cipher)
var plainText = new Buffer(cipher.length - sodium.crypto_secretbox_MACBYTES)
const plainText = Buffer.alloc(cipher.length - sodium.crypto_secretbox_MACBYTES)
sodium.crypto_secretbox_open_easy(plainText, cipher, nonce, key)
+31
View File
@@ -0,0 +1,31 @@
/* eslint-disable camelcase */
const assert = require('nanoassert')
const { vn } = require('./crypto_verify')
function sodium_increment (n) {
const nlen = n.byteLength
var c = 1
for (var i = 0; i < nlen; i++) {
c += n[i]
n[i] = c
c >>= 8
}
}
function sodium_memcmp (a, b) {
assert(a.byteLength === b.byteLength, 'buffers must be the same size')
return vn(a, 0, b, 0, a.byteLength) === 0
}
function sodium_is_zero (arr) {
var d = 0
for (let i = 0; i < arr.length; i++) d |= arr[i]
return d === 0
}
module.exports = {
sodium_increment,
sodium_memcmp,
sodium_is_zero
}
+5 -14
View File
@@ -2,24 +2,17 @@
// Based on https://github.com/dchest/tweetnacl-js/blob/6dcbcaf5f5cbfd313f2dcfe763db35c828c8ff5b/nacl-fast.js.
var sodium = module.exports
// Ported in 2014 by Dmitry Chestnykh and Devi Mandiri.
// Public domain.
//
// Implementation derived from TweetNaCl version 20140427.
// See for details: http://tweetnacl.cr.yp.to/
// also forwarded at the bottom but randombytes is non-enumerable
sodium.sodium_memzero = function (arr) {
arr.fill(0)
}
sodium.sodium_malloc = function (n) {
return new Uint8Array(n)
}
forward(require('./randombytes'))
forward(require('./memory'))
forward(require('./helpers'))
forward(require('./crypto_verify'))
forward(require('./crypto_auth'))
forward(require('./crypto_box'))
forward(require('./crypto_generichash'))
forward(require('./crypto_hash'))
@@ -34,8 +27,6 @@ forward(require('./crypto_shorthash'))
forward(require('./crypto_sign'))
forward(require('./crypto_stream'))
forward(require('./crypto_stream_chacha20'))
forward(require('./crypto_verify'))
forward(require('./randombytes'))
function forward (submodule) {
Object.keys(submodule).forEach(function (prop) {
View File
+23
View File
@@ -0,0 +1,23 @@
/* eslint-disable camelcase */
var MessageChannel = global.MessageChannel
if (MessageChannel == null) ({ MessageChannel } = require('worker' + '_threads'))
function sodium_malloc (n) {
return new Uint8Array(n)
}
const sink = new MessageChannel()
function sodium_free (n) {
sodium_memzero(n)
sink.port1.postMessage(n.buffer, [n.buffer])
}
function sodium_memzero (arr) {
arr.fill(0)
}
module.exports = {
sodium_malloc,
sodium_free,
sodium_memzero
}
+24 -14
View File
@@ -1,21 +1,27 @@
{
"name": "sodium-javascript",
"version": "0.6.0",
"version": "0.6.2",
"description": "WIP - a pure javascript version of sodium-native",
"main": "index.js",
"dependencies": {
"blake2b": "^2.1.1",
"chacha20-universal": "^1.0.4",
"nanoassert": "^1.0.0",
"sha256-wasm": "^1.3.0",
"sha512-wasm": "^1.2.0",
"nanoassert": "^2.0.0",
"sha256-universal": "^1.1.0",
"sha512-universal": "^1.1.0",
"siphash24": "^1.0.1",
"xsalsa20": "^1.0.0"
},
"devDependencies": {
"browser-run": "^4.0.2",
"browserify": "^14.1.0",
"sodium-test": "^0.9.0"
"browserify": "^16.5.1",
"sodium-test": "^0.9.0",
"standard": "^14.3.4",
"tape-run": "^7.0.0"
},
"standard": {
"ignore": [
"/internal/**/*.js"
]
},
"browser": {
"crypto": false
@@ -24,18 +30,22 @@
"crypto": "crypto"
},
"scripts": {
"browser": "browserify test.js | browser-run",
"browser-manual": "browserify test.js | browser-run -p 1234",
"test": "node test.js"
"pretest": "standard",
"test": "node test.js",
"test-browser": "browserify test.js | tape-run"
},
"repository": {
"type": "git",
"url": "https://github.com/mafintosh/sodium-javascript.git"
"url": "git+https://github.com/sodium-friends/sodium-javascript.git"
},
"author": "Mathias Buus (@mafintosh)",
"contributors": [
"Christophe Diederichs <chm-diederichs@hyperdivision.dk>",
"Emil Bay <github@tixz.dk> (http://bayes.dk)",
"Mathias Buus <mathiasbuus@gmail.com> (https://mafinto.sh)"
],
"license": "MIT",
"bugs": {
"url": "https://github.com/mafintosh/sodium-javascript/issues"
"url": "https://github.com/sodium-friends/sodium-javascript/issues"
},
"homepage": "https://github.com/mafintosh/sodium-javascript"
"homepage": "https://github.com/sodium-friends/sodium-javascript#readme"
}
+13 -13
View File
@@ -1,40 +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
var crypto = global.crypto || global.msCrypto
function browserBytes (out, n) {
for (var i = 0; i < n; i += QUOTA) {
crypto.getRandomValues(out.subarray(i, i + Math.min(n - i, QUOTA)))
for (let i = 0; i < n; i += QUOTA) {
crypto.getRandomValues(new Uint8Array(out.buffer, i + out.byteOffset, Math.min(n - i, QUOTA)))
}
}
function nodeBytes (out, n) {
out.set(crypto.randomBytes(n))
new Uint8Array(out.buffer, out.byteOffset, n).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
}
if (crypto && crypto.getRandomValues) return browserBytes
if (require != null) {
// Node.js. Bust Browserify
crypto = require('cry' + 'pto')
if (crypto && crypto.randomBytes) return nodeBytes
}
return noImpl
})()
// Make non enumerable as this is an internal function
Object.defineProperty(module.exports, 'randombytes', {
value: randombytes
})
module.exports.randombytes_buf = function (out) {
assert(out, 'out must be given')
randombytes(out, out.length)
randombytes(out, out.byteLength)
}