Compare commits

..
1 Commits
Author SHA1 Message Date
Emil Bay 002969f78d Preliminary kx api
Missing dependent apis and tests
2018-02-15 22:31:13 +01:00
26 changed files with 1918 additions and 2298 deletions
-18
View File
@@ -1,18 +0,0 @@
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
+14 -23
View File
@@ -1,29 +1,31 @@
# `sodium-javascript`
# sodium-javascript
[![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).
WIP - a pure javascript version of [sodium-native](https://github.com/mafintosh/sodium-native).
Based on tweetnacl
```
npm install sodium-javascript
```
## Usage
``` js
const sodium = require('sodium-javascript')
var sodium = require('sodium-javascript')
const key = Buffer.alloc(sodium.crypto_secretbox_KEYBYTES)
const nonce = Buffer.alloc(sodium.crypto_secretbox_NONCEBYTES)
var key = new Buffer(sodium.crypto_secretbox_KEYBYTES)
var nonce = new Buffer(sodium.crypto_secretbox_NONCEBYTES)
sodium.randombytes_buf(key)
sodium.randombytes_buf(nonce)
const message = Buffer.from('Hello, World!')
const cipher = Buffer.alloc(message.length + sodium.crypto_secretbox_MACBYTES)
var message = new Buffer('Hello, World!')
var cipher = new Buffer(message.length + sodium.crypto_secretbox_MACBYTES)
sodium.crypto_secretbox_easy(cipher, message, nonce, key)
console.log('Encrypted:', cipher)
const plainText = Buffer.alloc(cipher.length - sodium.crypto_secretbox_MACBYTES)
var plainText = new Buffer(cipher.length - sodium.crypto_secretbox_MACBYTES)
sodium.crypto_secretbox_open_easy(plainText, cipher, nonce, key)
@@ -32,20 +34,9 @@ console.log('Plaintext:', plainText.toString())
## API
See [sodium-native](https://github.com/sodium-friends/sodium-native).
See [sodium-native](https://github.com/mafintosh/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](LICENSE)
MIT
-160
View File
@@ -1,160 +0,0 @@
/* 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('./internal/poly1305')
const assert = require('nanoassert')
const crypto_aead_chacha20poly1305_ietf_KEYBYTES = 32
const crypto_aead_chacha20poly1305_ietf_NSECBYTES = 0
const crypto_aead_chacha20poly1305_ietf_NPUBBYTES = 12
const crypto_aead_chacha20poly1305_ietf_ABYTES = 16
const crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX = Number.MAX_SAFE_INTEGER
const _pad0 = new Uint8Array(16)
function crypto_aead_chacha20poly1305_ietf_encrypt (c, m, ad, nsec, npub, k) {
if (ad === null) return crypto_aead_chacha20poly1305_ietf_encrypt(c, m, new Uint8Array(0), nsec, npub, k)
assert(c.byteLength === m.byteLength + crypto_aead_chacha20poly1305_ietf_ABYTES,
"ciphertext should be 'crypto_aead_chacha20poly1305_ietf_ABYTES' longer than message")
assert(npub.byteLength === crypto_aead_chacha20poly1305_ietf_NPUBBYTES,
"npub should be 'crypto_aead_chacha20poly1305_ietf_NPUBBYTES' long")
assert(k.byteLength === crypto_aead_chacha20poly1305_ietf_KEYBYTES,
"k should be 'crypto_aead_chacha20poly1305_ietf_KEYBYTES' long")
assert(m.byteLength <= crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX, 'message is too large')
const ret = crypto_aead_chacha20poly1305_ietf_encrypt_detached(c.subarray(0, m.byteLength),
c.subarray(m.byteLength), m, ad, nsec, npub, k)
return m.byteLength + ret
}
function crypto_aead_chacha20poly1305_ietf_encrypt_detached (c, mac, m, ad, nsec, npub, k) {
if (ad === null) return crypto_aead_chacha20poly1305_ietf_encrypt_detached(c, mac, m, new Uint8Array(0), nsec, npub, k)
assert(c.byteLength === m.byteLength, 'ciphertext should be same length than message')
assert(npub.byteLength === crypto_aead_chacha20poly1305_ietf_NPUBBYTES,
"npub should be 'crypto_aead_chacha20poly1305_ietf_NPUBBYTES' long")
assert(k.byteLength === crypto_aead_chacha20poly1305_ietf_KEYBYTES,
"k should be 'crypto_aead_chacha20poly1305_ietf_KEYBYTES' long")
assert(m.byteLength <= crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX, 'message is too large')
assert(mac.byteLength <= crypto_aead_chacha20poly1305_ietf_ABYTES,
"mac should be 'crypto_aead_chacha20poly1305_ietf_ABYTES' long")
const block0 = new Uint8Array(64)
var slen = new Uint8Array(8)
crypto_stream_chacha20_ietf(block0, npub, k)
const poly = new Poly1305(block0)
block0.fill(0)
poly.update(ad, 0, ad.byteLength)
poly.update(_pad0, 0, (0x10 - ad.byteLength) & 0xf)
crypto_stream_chacha20_ietf_xor_ic(c, m, npub, 1, k)
poly.update(c, 0, m.byteLength)
poly.update(_pad0, 0, (0x10 - m.byteLength) & 0xf)
write64LE(slen, 0, ad.byteLength)
poly.update(slen, 0, slen.byteLength)
write64LE(slen, 0, m.byteLength)
poly.update(slen, 0, slen.byteLength)
poly.finish(mac, 0)
slen.fill(0)
return crypto_aead_chacha20poly1305_ietf_ABYTES
}
function crypto_aead_chacha20poly1305_ietf_decrypt (m, nsec, c, ad, npub, k) {
if (ad === null) return crypto_aead_chacha20poly1305_ietf_decrypt(m, nsec, c, new Uint8Array(0), npub, k)
assert(m.byteLength === c.byteLength - crypto_aead_chacha20poly1305_ietf_ABYTES,
"message should be 'crypto_aead_chacha20poly1305_ietf_ABYTES' shorter than ciphertext")
assert(npub.byteLength === crypto_aead_chacha20poly1305_ietf_NPUBBYTES,
"npub should be 'crypto_aead_chacha20poly1305_ietf_NPUBBYTES' long")
assert(k.byteLength === crypto_aead_chacha20poly1305_ietf_KEYBYTES,
"k should be 'crypto_aead_chacha20poly1305_ietf_KEYBYTES' long")
assert(m.byteLength <= crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX, 'message is too large')
if (c.byteLength < crypto_aead_chacha20poly1305_ietf_ABYTES) throw new Error('could not verify data')
crypto_aead_chacha20poly1305_ietf_decrypt_detached(
m, nsec,
c.subarray(0, c.byteLength - crypto_aead_chacha20poly1305_ietf_ABYTES),
c.subarray(c.byteLength - crypto_aead_chacha20poly1305_ietf_ABYTES),
ad, npub, k)
return c.byteLength - crypto_aead_chacha20poly1305_ietf_ABYTES
}
function crypto_aead_chacha20poly1305_ietf_decrypt_detached (m, nsec, c, mac, ad, npub, k) {
if (ad === null) return crypto_aead_chacha20poly1305_ietf_decrypt_detached(m, nsec, c, mac, new Uint8Array(0), npub, k)
assert(c.byteLength === m.byteLength, 'message should be same length than ciphertext')
assert(npub.byteLength === crypto_aead_chacha20poly1305_ietf_NPUBBYTES,
"npub should be 'crypto_aead_chacha20poly1305_ietf_NPUBBYTES' long")
assert(k.byteLength === crypto_aead_chacha20poly1305_ietf_KEYBYTES,
"k should be 'crypto_aead_chacha20poly1305_ietf_KEYBYTES' long")
assert(m.byteLength <= crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX, 'message is too large')
assert(mac.byteLength <= crypto_aead_chacha20poly1305_ietf_ABYTES,
"mac should be 'crypto_aead_chacha20poly1305_ietf_ABYTES' long")
const block0 = new Uint8Array(64)
const slen = new Uint8Array(8)
const computed_mac = new Uint8Array(crypto_aead_chacha20poly1305_ietf_ABYTES)
crypto_stream_chacha20_ietf(block0, npub, k)
const poly = new Poly1305(block0)
block0.fill(0)
poly.update(ad, 0, ad.byteLength)
poly.update(_pad0, 0, (0x10 - ad.byteLength) & 0xf)
const mlen = c.byteLength
poly.update(c, 0, mlen)
poly.update(_pad0, 0, (0x10 - mlen) & 0xf)
write64LE(slen, 0, ad.byteLength)
poly.update(slen, 0, slen.byteLength)
write64LE(slen, 0, mlen)
poly.update(slen, 0, slen.byteLength)
poly.finish(computed_mac, 0)
assert(computed_mac.byteLength === 16)
const ret = crypto_verify_16(computed_mac, 0, mac, 0)
computed_mac.fill(0)
slen.fill(0)
if (!ret) {
m.fill(0)
throw new Error('could not verify data')
}
crypto_stream_chacha20_ietf_xor_ic(m, c, npub, 1, k)
}
function write64LE (buf, offset, int) {
buf.fill(0, 0, 8)
const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength)
view.setUint32(offset, int & 0xffffffff, true)
view.setUint32(offset + 4, (int / 2 ** 32) & 0xffffffff, true)
}
module.exports = {
crypto_aead_chacha20poly1305_ietf_encrypt,
crypto_aead_chacha20poly1305_ietf_encrypt_detached,
crypto_aead_chacha20poly1305_ietf_decrypt,
crypto_aead_chacha20poly1305_ietf_decrypt_detached,
crypto_aead_chacha20poly1305_ietf_ABYTES,
crypto_aead_chacha20poly1305_ietf_KEYBYTES,
crypto_aead_chacha20poly1305_ietf_NPUBBYTES,
crypto_aead_chacha20poly1305_ietf_NSECBYTES,
crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX
}
-35
View File
@@ -1,35 +0,0 @@
/* eslint-disable camelcase */
const { crypto_verify_32 } = require('./crypto_verify')
const Sha512 = require('sha512-universal')
const assert = require('nanoassert')
const crypto_auth_BYTES = 32
const crypto_auth_KEYBYTES = 32
function crypto_auth (out, input, k) {
assert(out.byteLength === crypto_auth_BYTES, "out should be 'crypto_auth_BYTES' in length")
assert(k.byteLength === crypto_auth_KEYBYTES, "key should be 'crypto_auth_KEYBYTES' in length")
const out0 = new Uint8Array(64)
const hmac = Sha512.HMAC(k)
hmac.update(input)
hmac.digest(out0)
out.set(out0.subarray(0, 32))
}
function crypto_auth_verify (h, input, k) {
assert(h.byteLength === crypto_auth_BYTES, "h should be 'crypto_auth_BYTES' in length")
assert(k.byteLength === crypto_auth_KEYBYTES, "key should be 'crypto_auth_KEYBYTES' in length")
const correct = Sha512.HMAC(k).update(input).digest()
return crypto_verify_32(h, 0, correct, 0)
}
module.exports = {
crypto_auth_BYTES,
crypto_auth_KEYBYTES,
crypto_auth,
crypto_auth_verify
}
-200
View File
@@ -1,200 +0,0 @@
/* eslint-disable camelcase */
const { crypto_hash_sha512 } = require('./crypto_hash')
const { crypto_scalarmult, crypto_scalarmult_base } = require('./crypto_scalarmult')
const { randombytes } = require('./randombytes')
const { crypto_generichash_batch } = require('./crypto_generichash')
const { crypto_stream_xsalsa20_MESSAGEBYTES_MAX } = require('./crypto_stream')
const {
crypto_secretbox_open_easy,
crypto_secretbox_easy,
crypto_secretbox_detached,
crypto_secretbox_open_detached
} = require('./crypto_secretbox')
const xsalsa20 = require('xsalsa20')
const assert = require('nanoassert')
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
const crypto_box_MACBYTES = 16
const crypto_box_curve25519xsalsa20poly1305_MACBYTES = 16
const crypto_box_MESSAGEBYTES_MAX =
crypto_stream_xsalsa20_MESSAGEBYTES_MAX -
crypto_box_curve25519xsalsa20poly1305_MACBYTES
module.exports = {
crypto_box_easy,
crypto_box_open_easy,
crypto_box_keypair,
crypto_box_seed_keypair,
crypto_box_seal,
crypto_box_seal_open,
crypto_box_PUBLICKEYBYTES,
crypto_box_SECRETKEYBYTES,
crypto_box_NONCEBYTES,
crypto_box_ZEROBYTES,
crypto_box_BOXZEROBYTES,
crypto_box_SEALBYTES,
crypto_box_SEEDBYTES,
crypto_box_BEFORENMBYTES,
crypto_box_MACBYTES
}
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) {
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")
const hash = new Uint8Array(64)
crypto_hash_sha512(hash, seed, 32)
sk.set(hash.subarray(0, 32))
hash.fill(0)
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)
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)
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)
}
function crypto_box_beforenm (k, pk, sk) {
const zero = new Uint8Array(16)
const s = new Uint8Array(32)
assert(crypto_scalarmult(s, sk, pk) === 0)
xsalsa20.core_hsalsa20(k, zero, s, xsalsa20.SIGMA)
return true
}
function crypto_box_detached_afternm (c, mac, m, n, k) {
return crypto_secretbox_detached(c, mac, m, n, k)
}
function crypto_box_detached (c, mac, m, n, pk, sk) {
check(mac, crypto_box_MACBYTES)
check(n, crypto_box_NONCEBYTES)
check(pk, crypto_box_PUBLICKEYBYTES)
check(sk, crypto_box_SECRETKEYBYTES)
const k = new Uint8Array(crypto_box_BEFORENMBYTES)
assert(crypto_box_beforenm(k, pk, sk))
const ret = crypto_box_detached_afternm(c, mac, m, n, k)
cleanup(k)
return ret
}
function crypto_box_easy (c, m, n, pk, sk) {
assert(
c.length >= m.length + crypto_box_MACBYTES,
"c should be at least 'm.length + crypto_box_MACBYTES' bytes"
)
assert(
m.length <= crypto_box_MESSAGEBYTES_MAX,
"m should be at most 'crypto_box_MESSAGEBYTES_MAX' bytes"
)
return crypto_box_detached(
c.subarray(crypto_box_MACBYTES, m.length + crypto_box_MACBYTES),
c.subarray(0, crypto_box_MACBYTES),
m,
n,
pk,
sk
)
}
function crypto_box_open_detached_afternm (m, c, mac, n, k) {
return crypto_secretbox_open_detached(m, c, mac, n, k)
}
function crypto_box_open_detached (m, c, mac, n, pk, sk) {
const k = new Uint8Array(crypto_box_BEFORENMBYTES)
assert(crypto_box_beforenm(k, pk, sk))
const ret = crypto_box_open_detached_afternm(m, c, mac, n, k)
cleanup(k)
return ret
}
function crypto_box_open_easy (m, c, n, pk, sk) {
assert(
c.length >= m.length + crypto_box_MACBYTES,
"c should be at least 'm.length + crypto_box_MACBYTES' bytes"
)
return crypto_box_open_detached(
m,
c.subarray(crypto_box_MACBYTES, m.length + crypto_box_MACBYTES),
c.subarray(0, crypto_box_MACBYTES),
n,
pk,
sk
)
}
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 (let i = 0; i < arr.length; i++) arr[i] = 0
}
+1 -3
View File
@@ -1,7 +1,5 @@
var blake2b = require('blake2b')
if (new Uint16Array([1])[0] !== 1) throw new Error('Big endian architecture is not supported.')
module.exports.crypto_generichash_PRIMITIVE = 'blake2b'
module.exports.crypto_generichash_BYTES_MIN = blake2b.BYTES_MIN
module.exports.crypto_generichash_BYTES_MAX = blake2b.BYTES_MAX
@@ -31,6 +29,6 @@ module.exports.crypto_generichash_instance = function (key, outlen) {
return blake2b(outlen, key)
}
blake2b.ready(function (_) {
blake2b.ready(function (err) {
module.exports.crypto_generichash_WASM_LOADED = blake2b.WASM_LOADED
})
-26
View File
@@ -1,26 +0,0 @@
/* 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.')
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")
sha512().update(m.subarray(0, n)).digest(out)
return 0
}
function crypto_hash (out, m, n) {
return crypto_hash_sha512(out, m, n)
}
module.exports = {
crypto_hash,
crypto_hash_sha512,
crypto_hash_sha512_BYTES,
crypto_hash_BYTES
}
-19
View File
@@ -1,19 +0,0 @@
/* 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.')
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")
sha256().update(m.subarray(0, n)).digest(out)
return 0
}
module.exports = {
crypto_hash_sha256,
crypto_hash_sha256_BYTES
}
+6 -7
View File
@@ -1,15 +1,14 @@
/* eslint-disable camelcase */
const assert = require('nanoassert')
const randombytes_buf = require('./randombytes').randombytes_buf
const blake2b = require('blake2b')
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
module.exports.crypto_kdf_KEYBYTES = 64
function STORE64_LE (dest, int) {
function STORE64_LE(dest, int) {
var mul = 1
var i = 0
dest[0] = int & 0xFF
@@ -30,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.subarray(0, module.exports.crypto_kdf_KEYBYTES), salt, ctx_padded, true)
blake2b(outlen, key, salt, ctx_padded, true)
.final(subkey)
}
+70 -25
View File
@@ -1,34 +1,79 @@
/* 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 assert = require('nanoassert')
var randombytes_buf = require('./randombytes').randombytes_buf
var generichash = require('./crypto_generichash')
var crypto_scalarmult_base = require('./crypto_scalarmult').crypto_scalarmult_base
const crypto_kx_SEEDBYTES = 32
const crypto_kx_PUBLICKEYBYTES = 32
const crypto_kx_SECRETKEYBYTES = 32
exports.crypto_kx_PUBLICKEYBYTES = 32
exports.crypto_kx_SECRETKEYBYTES = 32
exports.crypto_kx_SEEDBYTES = 32
exports.crypto_kx_SESSIONKEYBYTES = 32
exports.crypto_kx_PRIMITIVE = ''
function crypto_kx_keypair (pk, sk) {
assert(pk.byteLength === crypto_kx_PUBLICKEYBYTES, "pk must be 'crypto_kx_PUBLICKEYBYTES' bytes")
assert(sk.byteLength === crypto_kx_SECRETKEYBYTES, "sk must be 'crypto_kx_SECRETKEYBYTES' bytes")
exports.crypto_kx_keypair = function (pk, sk) {
assert(sk.byteLength >= exports.crypto_kx_SECRETKEYBYTES, 'sk must be at least crypto_kx_SECRETKEYBYTES')
assert(pk.byteLength >= exports.crypto_kx_PUBLICKEYBYTES, 'pk must be at least crypto_kx_PUBLICKEYBYTES')
randombytes_buf(sk, crypto_kx_SECRETKEYBYTES)
return crypto_scalarmult_base(pk, sk)
randombytes_buf(sk.subarray(0, exports.crypto_kx_SECRETKEYBYTES))
crypto_scalarmult_base(
pk.subarray(0, exports.crypto_kx_PUBLICKEYBYTES),
sk.subarray(0, exports.crypto_kx_SECRETKEYBYTES)
)
}
function crypto_kx_seed_keypair (pk, sk, seed) {
assert(pk.byteLength === crypto_kx_PUBLICKEYBYTES, "pk must be 'crypto_kx_PUBLICKEYBYTES' bytes")
assert(sk.byteLength === crypto_kx_SECRETKEYBYTES, "sk must be 'crypto_kx_SECRETKEYBYTES' bytes")
assert(seed.byteLength === crypto_kx_SEEDBYTES, "seed must be 'crypto_kx_SEEDBYTES' bytes")
exports.crypto_kx_seed_keypair = function (pk, sk, seed) {
assert(sk.byteLength >= exports.crypto_kx_SECRETKEYBYTES, 'sk must be at least crypto_kx_SECRETKEYBYTES')
assert(pk.byteLength >= exports.crypto_kx_PUBLICKEYBYTES, 'pk must be at least crypto_kx_PUBLICKEYBYTES')
assert(seed.byteLength >= exports.crypto_kx_SEEDBYTES, 'seed must be at least crypto_kx_SEEDBYTES')
crypto_generichash(sk, seed)
return crypto_scalarmult_base(pk, sk)
generichash.crypto_generichash(
sk.subarray(0, exports.crypto_kx_SECRETKEYBYTES),
seed.subarray(0, exports.crypto_kx_SEEDBYTES)
)
crypto_scalarmult_base(
pk.subarray(0, exports.crypto_kx_PUBLICKEYBYTES),
sk.subarray(0, exports.crypto_kx_SECRETKEYBYTES)
)
}
module.exports = {
crypto_kx_keypair,
crypto_kx_seed_keypair,
crypto_kx_SEEDBYTES,
crypto_kx_SECRETKEYBYTES,
crypto_kx_PUBLICKEYBYTES
exports.crypto_kx_client_session_keys = calc.bind(null, false)
exports.crypto_kx_server_session_keys = calc.bind(null, true)
function calc (server, rx, tx, pk, sk, remote_pk) {
if (rx == null) rx = tx
if (tx == null) tx = rx
assert(rx >= exports.crypto_kx_SESSIONKEYBYTES, 'rx must be at least crypto_kx_SESSIONKEYBYTES')
assert(tx >= exports.crypto_kx_SESSIONKEYBYTES, 'tx should be at least crypto_kx_SESSIONKEYBYTES')
assert(sk.byteLength >= exports.crypto_kx_SECRETKEYBYTES, 'sk must be at least crypto_kx_SECRETKEYBYTES')
assert(pk.byteLength >= exports.crypto_kx_PUBLICKEYBYTES, 'pk must be at least crypto_kx_PUBLICKEYBYTES')
assert(remote_pk.byteLength >= exports.crypto_kx_PUBLICKEYBYTES, 'remote_pk must be at least crypto_kx_PUBLICKEYBYTES')
rx = rx.subarray(0, exports.crypto_kx_SESSIONKEYBYTES)
tx = tx.subarray(0, exports.crypto_kx_SESSIONKEYBYTES)
sk = sk.subarray(0, exports.crypto_kx_SECRETKEYBYTES)
pk = pk.subarray(0, exports.crypto_kx_PUBLICKEYBYTES)
remote_pk = remote_pk.subarray(0, exports.crypto_kx_PUBLICKEYBYTES)
var keys = new Uint8Array(2 * exports.crypto_kx_SESSIONKEYBYTES)
var hash = generichash.crypto_generichash_instance(null, keys.byteLength)
var q = new Uint8Array(scalarmult.crypto_scalarmult_BYTES)
scalarmult.crypto_scalamult(q, sk, remote_pk)
hash.update(q)
q.fill(0)
// if server, then remote_pk == client_pk
hash.update(server ? remote_pk : pk)
hash.update(server ? pk : remote_pk)
hash.final(keys)
// TODO clear out hash
rx.set(keys.subarray(0, exports.crypto_kx_SESSIONKEYBYTES))
tx.set(keys.subarray(exports.crypto_kx_SESSIONKEYBYTES))
}
-36
View File
@@ -1,36 +0,0 @@
/* 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_BYTES,
crypto_onetimeauth_KEYBYTES,
crypto_onetimeauth_PRIMITIVE
}
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)
}
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)
}
-76
View File
@@ -1,76 +0,0 @@
/* eslint-disable camelcase, one-var */
const { _9, _121665, gf, inv25519, pack25519, unpack25519, sel25519, A, M, Z, S } = require('./internal/ed25519')
const crypto_scalarmult_BYTES = 32
const crypto_scalarmult_SCALARBYTES = 32
module.exports = {
crypto_scalarmult,
crypto_scalarmult_base,
crypto_scalarmult_BYTES,
crypto_scalarmult_SCALARBYTES
}
function crypto_scalarmult (q, n, p) {
check(q, crypto_scalarmult_BYTES)
check(n, crypto_scalarmult_SCALARBYTES)
check(p, crypto_scalarmult_BYTES)
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()
for (i = 0; i < 31; i++) z[i] = n[i]
z[31] = (n[31] & 127) | 64
z[0] &= 248
unpack25519(x, p)
for (i = 0; i < 16; i++) {
b[i] = x[i]
d[i] = a[i] = c[i] = 0
}
a[0] = d[0] = 1
for (i = 254; i >= 0; --i) {
r = (z[i >>> 3] >>> (i & 7)) & 1
sel25519(a, b, r)
sel25519(c, d, r)
A(e, a, c)
Z(a, a, c)
A(c, b, d)
Z(b, b, d)
S(d, e)
S(f, a)
M(a, c, a)
M(c, b, e)
A(e, a, c)
Z(a, a, c)
S(b, a)
Z(c, d, f)
M(a, c, _121665)
A(a, a, d)
M(c, c, a)
M(a, d, f)
M(d, b, x)
S(b, e)
sel25519(a, b, r)
sel25519(c, d, r)
}
for (i = 0; i < 16; i++) {
x[i + 16] = a[i]
x[i + 32] = c[i]
x[i + 48] = b[i]
x[i + 64] = d[i]
}
var x32 = x.subarray(32)
var x16 = x.subarray(16)
inv25519(x32, x32)
M(x16, x16, x32)
pack25519(q, x16)
return 0
}
function crypto_scalarmult_base (q, n) {
return crypto_scalarmult(q, n, _9)
}
function check (buf, len) {
if (!buf || (len && buf.length < len)) throw new Error('Argument must be a buffer' + (len ? ' of length ' + len : ''))
}
-111
View File
@@ -1,111 +0,0 @@
/* 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')
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,
crypto_secretbox_open,
crypto_secretbox_detached,
crypto_secretbox_open_detached,
crypto_secretbox_easy,
crypto_secretbox_open_easy,
crypto_secretbox_KEYBYTES,
crypto_secretbox_NONCEBYTES,
crypto_secretbox_ZEROBYTES,
crypto_secretbox_BOXZEROBYTES,
crypto_secretbox_MACBYTES
}
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.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)
}
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)
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)
m.fill(0, 0, 32)
return true
}
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)
mac.set(tmp.subarray(0, mac.byteLength))
o.set(tmp.subarray(mac.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(mac)
tmp.set(o, mac.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)
crypto_secretbox(c, m, n, k)
o.set(c.subarray(crypto_secretbox_BOXZEROBYTES))
}
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
}
+5 -2
View File
@@ -1,14 +1,17 @@
var siphash = require('siphash24')
if (new Uint16Array([1])[0] !== 1) throw new Error('Big endian architecture is not supported.')
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_ready = siphash.ready
exports.crypto_shorthash = shorthash
siphash.ready(function () {
exports.crypto_shorthash_WASM_LOADED = siphash.WASM_LOADED
})
function shorthash (out, data, key, noAssert) {
siphash(data, key, out, noAssert)
}
-469
View File
@@ -1,469 +0,0 @@
/* eslint-disable camelcase, one-var */
const { crypto_verify_32 } = require('./crypto_verify')
const { crypto_hash } = require('./crypto_hash')
const {
gf, gf0, gf1, D, D2,
X, Y, I, A, Z, M, S,
sel25519, pack25519,
inv25519, unpack25519
} = require('./internal/ed25519')
const { randombytes } = require('./randombytes')
const { crypto_scalarmult_BYTES } = require('./crypto_scalarmult.js')
const { crypto_hash_sha512_BYTES } = require('./crypto_hash.js')
const assert = require('nanoassert')
const crypto_sign_ed25519_PUBLICKEYBYTES = 32
const crypto_sign_ed25519_SECRETKEYBYTES = 64
const crypto_sign_ed25519_SEEDBYTES = 32
const crypto_sign_ed25519_BYTES = 64
const crypto_sign_BYTES = crypto_sign_ed25519_BYTES
const crypto_sign_PUBLICKEYBYTES = crypto_sign_ed25519_PUBLICKEYBYTES
const crypto_sign_SECRETKEYBYTES = crypto_sign_ed25519_SECRETKEYBYTES
const crypto_sign_SEEDBYTES = crypto_sign_ed25519_SEEDBYTES
module.exports = {
crypto_sign_keypair,
crypto_sign_seed_keypair,
crypto_sign,
crypto_sign_detached,
crypto_sign_open,
crypto_sign_verify_detached,
crypto_sign_BYTES,
crypto_sign_PUBLICKEYBYTES,
crypto_sign_SECRETKEYBYTES,
crypto_sign_SEEDBYTES,
crypto_sign_ed25519_PUBLICKEYBYTES,
crypto_sign_ed25519_SECRETKEYBYTES,
crypto_sign_ed25519_SEEDBYTES,
crypto_sign_ed25519_BYTES,
crypto_sign_ed25519_pk_to_curve25519,
crypto_sign_ed25519_sk_to_curve25519,
crypto_sign_ed25519_sk_to_pk,
unpackneg,
pack
}
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]
for (a = 250; a >= 0; a--) {
S(c, c)
if (a !== 1) M(c, c, i)
}
for (a = 0; a < 16; a++) o[a] = c[a]
}
function add (p, q) {
var a = gf(), b = gf(), c = 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)
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
for (i = 0; i < 4; i++) {
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 scalarmult (p, q, s) {
// don't mutate q
var h = [gf(q[0]), gf(q[1]), gf(q[2]), gf(q[3])]
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, h, b)
add(h, p)
add(p, p)
cswap(p, h, 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 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
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)
for (i = 0; i < 32; i++) sk[i + 32] = pk[i]
}
function crypto_sign_seed_keypair (pk, sk, seed) {
check(seed, crypto_sign_SEEDBYTES)
sk.set(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])
function modL (r, x) {
var carry, i, j, k
for (i = 63; i >= 32; --i) {
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
x[i] = 0
}
carry = 0
for (j = 0; j < 32; j++) {
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 (i = 0; i < 32; i++) {
x[i + 1] += x[i] >> 8
r[i] = x[i] & 255
}
}
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) {
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()]
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]
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 = 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]
}
}
modL(sm.subarray(32), x)
return smlen
}
function crypto_sign_detached (sig, m, sk) {
var sm = new Uint8Array(m.length + crypto_sign_BYTES)
crypto_sign(sm, m, sk)
for (let i = 0; i < crypto_sign_BYTES; i++) sig[i] = sm[i]
}
function unpackneg (r, p) {
var t = gf(), chk = gf(), num = 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)
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)
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 false
if (par25519(r[0]) === (p[31] >> 7)) {
Z(r[0], gf(), r[0])
}
M(r[3], r[0], r[1])
return true
}
/* 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 p = [gf(), gf(), gf(), gf()],
q = [gf(), gf(), gf(), gf()]
mlen = -1
if (n < 64) 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)
scalarbase(q, sm.subarray(32))
add(p, q)
pack(t, p)
n -= 64
if (!crypto_verify_32(sm, 0, t, 0)) {
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
}
/* eslint-enable no-unused-vars */
function crypto_sign_verify_detached (sig, m, pk) {
check(sig, crypto_sign_BYTES)
var sm = new Uint8Array(m.length + crypto_sign_BYTES)
var i = 0
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 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 ed25519_mul_l (p, q) {
scalarmult(p, q, L)
}
function ed25519_is_on_main_subgroup (p) {
var pl = [gf(), gf(), gf(), gf()]
ed25519_mul_l(pl, p)
var zero = 0
for (let i = 0; i < 16; i++) {
zero |= (pl[0][i] & 0xffff)
}
return zero === 0
}
function crypto_sign_ed25519_pk_to_curve25519 (x25519_pk, ed25519_pk) {
check(x25519_pk, crypto_sign_PUBLICKEYBYTES)
check(ed25519_pk, crypto_sign_ed25519_PUBLICKEYBYTES)
var a = [gf(), gf(), gf(), gf()]
var x = gf([1])
var one_minus_y = gf([1])
assert(
isSmallOrder(ed25519_pk) &&
unpackneg(a, ed25519_pk) &&
ed25519_is_on_main_subgroup(a), 'Cannot convert key: bad point')
for (let i = 0; i < a.length; i++) {
pack25519(x25519_pk, a[i])
}
Z(one_minus_y, one_minus_y, a[1])
A(x, x, a[1])
inv25519(one_minus_y, one_minus_y)
M(x, x, one_minus_y)
pack25519(x25519_pk, x)
return 0
}
function isSmallOrder (s) {
Uint8Array.from([])
var bad_points = [
// 0 (order 4)
Uint8Array.from([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]),
// 1 (order 1)
Uint8Array.from([0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]),
// 2707385501144840649318225287225658788936804267575313519463743609750303402022(order 8)
Uint8Array.from([0x26, 0xe8, 0x95, 0x8f, 0xc2, 0xb2, 0x27, 0xb0, 0x45, 0xc3,
0xf4, 0x89, 0xf2, 0xef, 0x98, 0xf0, 0xd5, 0xdf, 0xac, 0x05, 0xd3,
0xc6, 0x33, 0x39, 0xb1, 0x38, 0x02, 0x88, 0x6d, 0x53, 0xfc, 0x05]),
// 55188659117513257062467267217118295137698188065244968500265048394206261417927 (order 8)
Uint8Array.from([0xc7, 0x17, 0x6a, 0x70, 0x3d, 0x4d, 0xd8, 0x4f, 0xba, 0x3c,
0x0b, 0x76, 0x0d, 0x10, 0x67, 0x0f, 0x2a, 0x20, 0x53, 0xfa, 0x2c,
0x39, 0xcc, 0xc6, 0x4e, 0xc7, 0xfd, 0x77, 0x92, 0xac, 0x03, 0x7a]),
// p-1 (order 2)
Uint8Array.from([0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f]),
// p (=0 order 4)
Uint8Array.from([0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f]),
// p + 1 (=1 order 1)
Uint8Array.from([0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f])
]
var c = new Uint8Array(7)
var j
check(bad_points, 7)
for (let i = 0; i < bad_points.length; i++) {
for (j = 0; j < 31; j++) {
c[i] |= s[j] ^ bad_points[i][j]
}
}
for (let i = 0; i < bad_points.length; i++) {
c[i] |= (s[j] & 0x7f) ^ bad_points[i][j]
}
var k = 0
for (let i = 0; i < bad_points.length; i++) {
k |= (c[i] - 1)
}
return ((k >> 8) & 1) === 0
}
function crypto_sign_ed25519_sk_to_pk (pk, sk) {
check(pk, crypto_sign_ed25519_PUBLICKEYBYTES)
pk.set(sk.subarray(crypto_sign_ed25519_SEEDBYTES))
return pk
}
function crypto_sign_ed25519_sk_to_curve25519 (curveSk, edSk) {
assert(curveSk && curveSk.byteLength === crypto_scalarmult_BYTES, "curveSk must be 'crypto_sign_SECRETKEYBYTES' long")
assert(edSk && edSk.byteLength === crypto_sign_ed25519_SECRETKEYBYTES, "edSk must be 'crypto_sign_ed25519_SECRETKEYBYTES' long")
var h = Buffer.alloc(crypto_hash_sha512_BYTES)
crypto_hash(h, edSk, 32)
h[0] &= 248
h[31] &= 127
h[31] |= 64
curveSk.set(h.subarray(0, crypto_scalarmult_BYTES))
h.fill(0)
return curveSk
}
function check (buf, len, arg = 'Argument') {
if (!buf || (len && buf.length < len)) throw new Error(arg + ' must be a buffer' + (len ? ' of length ' + len : ''))
}
+7 -12
View File
@@ -1,22 +1,17 @@
/* eslint-disable camelcase */
const xsalsa20 = require('xsalsa20')
if (new Uint16Array([1])[0] !== 1) throw new Error('Big endian architecture is not supported.')
var xsalsa20 = require('xsalsa20')
exports.crypto_stream_KEYBYTES = 32
exports.crypto_stream_NONCEBYTES = 24
exports.crypto_stream_PRIMITIVE = 'xsalsa20'
exports.crypto_stream_xsalsa20_MESSAGEBYTES_MAX = Number.MAX_SAFE_INTEGER
exports.crypto_stream = function (c, nonce, key) {
c.fill(0)
exports.crypto_stream_xor(c, c, nonce, key)
exports.crypto_stream = function (out, nonce, key) {
out.fill(0)
exports.crypto_stream_xor(out, out, nonce, key)
}
exports.crypto_stream_xor = function (c, m, nonce, key) {
const xor = xsalsa20(nonce, key)
xor.update(m, c)
exports.crypto_stream_xor = function (out, inp, nonce, key) {
var xor = xsalsa20(nonce, key)
xor.update(inp, out)
xor.final()
}
-84
View File
@@ -1,84 +0,0 @@
const assert = require('nanoassert')
const Chacha20 = require('chacha20-universal')
if (new Uint16Array([1])[0] !== 1) throw new Error('Big endian architecture is not supported.')
exports.crypto_stream_chacha20_KEYBYTES = 32
exports.crypto_stream_chacha20_NONCEBYTES = 8
exports.crypto_stream_chacha20_MESSAGEBYTES_MAX = Number.MAX_SAFE_INTEGER
exports.crypto_stream_chacha20_ietf_KEYBYTES = 32
exports.crypto_stream_chacha20_ietf_NONCEBYTES = 12
exports.crypto_stream_chacha20_ietf_MESSAGEBYTES_MAX = 2 ** 32
exports.crypto_stream_chacha20 = function (c, n, k) {
c.fill(0)
exports.crypto_stream_chacha20_xor(c, c, n, k)
}
exports.crypto_stream_chacha20_xor = function (c, m, n, k) {
assert(n.byteLength === exports.crypto_stream_chacha20_NONCEBYTES,
'n should be crypto_stream_chacha20_NONCEBYTES')
assert(k.byteLength === exports.crypto_stream_chacha20_KEYBYTES,
'k should be crypto_stream_chacha20_KEYBYTES')
const xor = new Chacha20(n, k)
xor.update(c, m)
xor.final()
}
exports.crypto_stream_chacha20_xor_ic = function (c, m, n, ic, k) {
assert(n.byteLength === exports.crypto_stream_chacha20_NONCEBYTES,
'n should be crypto_stream_chacha20_NONCEBYTES')
assert(k.byteLength === exports.crypto_stream_chacha20_KEYBYTES,
'k should be crypto_stream_chacha20_KEYBYTES')
const xor = new Chacha20(n, k, ic)
xor.update(c, m)
xor.final()
}
exports.crypto_stream_chacha20_xor_instance = function (n, k) {
assert(n.byteLength === exports.crypto_stream_chacha20_NONCEBYTES,
'n should be crypto_stream_chacha20_NONCEBYTES')
assert(k.byteLength === exports.crypto_stream_chacha20_KEYBYTES,
'k should be crypto_stream_chacha20_KEYBYTES')
return new Chacha20(n, k)
}
exports.crypto_stream_chacha20_ietf = function (c, n, k) {
c.fill(0)
exports.crypto_stream_chacha20_ietf_xor(c, c, n, k)
}
exports.crypto_stream_chacha20_ietf_xor = function (c, m, n, k) {
assert(n.byteLength === exports.crypto_stream_chacha20_ietf_NONCEBYTES,
'n should be crypto_stream_chacha20_ietf_NONCEBYTES')
assert(k.byteLength === exports.crypto_stream_chacha20_ietf_KEYBYTES,
'k should be crypto_stream_chacha20_ietf_KEYBYTES')
const xor = new Chacha20(n, k)
xor.update(c, m)
xor.final()
}
exports.crypto_stream_chacha20_ietf_xor_ic = function (c, m, n, ic, k) {
assert(n.byteLength === exports.crypto_stream_chacha20_ietf_NONCEBYTES,
'n should be crypto_stream_chacha20_ietf_NONCEBYTES')
assert(k.byteLength === exports.crypto_stream_chacha20_ietf_KEYBYTES,
'k should be crypto_stream_chacha20_ietf_KEYBYTES')
const xor = new Chacha20(n, k, ic)
xor.update(c, m)
xor.final()
}
exports.crypto_stream_chacha20_ietf_xor_instance = function (n, k) {
assert(n.byteLength === exports.crypto_stream_chacha20_ietf_NONCEBYTES,
'n should be crypto_stream_chacha20_ietf_NONCEBYTES')
assert(k.byteLength === exports.crypto_stream_chacha20_ietf_KEYBYTES,
'k should be crypto_stream_chacha20_ietf_KEYBYTES')
return new Chacha20(n, k)
}
-29
View File
@@ -1,29 +0,0 @@
/* eslint-disable camelcase */
module.exports = {
crypto_verify_16,
crypto_verify_32,
crypto_verify_64
}
function vn (x, xi, y, yi, n) {
var d = 0
for (let i = 0; i < n; i++) d |= x[xi + i] ^ y[yi + i]
return (1 & ((d - 1) >>> 8)) - 1
}
// 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) === 0
}
function crypto_verify_32 (x, xi, y, yi) {
return vn(x, xi, y, yi, 32) === 0
}
function crypto_verify_64 (x, xi, y, yi) {
return vn(x, xi, y, yi, 64) === 0
}
+6 -6
View File
@@ -1,19 +1,19 @@
const sodium = require('./')
var sodium = require('./')
const key = Buffer.alloc(sodium.crypto_secretbox_KEYBYTES)
const nonce = Buffer.alloc(sodium.crypto_secretbox_NONCEBYTES)
var key = new Buffer(sodium.crypto_secretbox_KEYBYTES)
var nonce = new Buffer(sodium.crypto_secretbox_NONCEBYTES)
sodium.randombytes_buf(key)
sodium.randombytes_buf(nonce)
const message = Buffer.from('Hello, World!')
const cipher = Buffer.alloc(message.length + sodium.crypto_secretbox_MACBYTES)
var message = new Buffer('Hello, World!')
var cipher = new Buffer(message.length + sodium.crypto_secretbox_MACBYTES)
sodium.crypto_secretbox_easy(cipher, message, nonce, key)
console.log('Encrypted:', cipher)
const plainText = Buffer.alloc(cipher.length - sodium.crypto_secretbox_MACBYTES)
var plainText = new Buffer(cipher.length - sodium.crypto_secretbox_MACBYTES)
sodium.crypto_secretbox_open_easy(plainText, cipher, nonce, key)
-31
View File
@@ -1,31 +0,0 @@
/* 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
}
+1784 -16
View File
File diff suppressed because it is too large Load Diff
-483
View File
@@ -1,483 +0,0 @@
if (new Uint16Array([1])[0] !== 1) throw new Error('Big endian architecture is not supported.')
var gf = function(init) {
var i, r = new Float64Array(16);
if (init) for (i = 0; i < init.length; i++) r[i] = init[i];
return r;
}
var _0 = new Uint8Array(16);
var _9 = new Uint8Array(32); _9[0] = 9;
var gf0 = gf(),
gf1 = gf([1]),
_121665 = gf([0xdb41, 1]),
D = gf([0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203]),
D2 = gf([0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406]),
X = gf([0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169]),
Y = gf([0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666]),
I = gf([0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83]);
function A(o, a, b) {
for (var i = 0; i < 16; i++) o[i] = a[i] + b[i];
}
function Z(o, a, b) {
for (var i = 0; i < 16; i++) o[i] = a[i] - b[i];
}
function M(o, a, b) {
var v, c,
t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0,
t8 = 0, t9 = 0, t10 = 0, t11 = 0, t12 = 0, t13 = 0, t14 = 0, t15 = 0,
t16 = 0, t17 = 0, t18 = 0, t19 = 0, t20 = 0, t21 = 0, t22 = 0, t23 = 0,
t24 = 0, t25 = 0, t26 = 0, t27 = 0, t28 = 0, t29 = 0, t30 = 0,
b0 = b[0],
b1 = b[1],
b2 = b[2],
b3 = b[3],
b4 = b[4],
b5 = b[5],
b6 = b[6],
b7 = b[7],
b8 = b[8],
b9 = b[9],
b10 = b[10],
b11 = b[11],
b12 = b[12],
b13 = b[13],
b14 = b[14],
b15 = b[15];
v = a[0];
t0 += v * b0;
t1 += v * b1;
t2 += v * b2;
t3 += v * b3;
t4 += v * b4;
t5 += v * b5;
t6 += v * b6;
t7 += v * b7;
t8 += v * b8;
t9 += v * b9;
t10 += v * b10;
t11 += v * b11;
t12 += v * b12;
t13 += v * b13;
t14 += v * b14;
t15 += v * b15;
v = a[1];
t1 += v * b0;
t2 += v * b1;
t3 += v * b2;
t4 += v * b3;
t5 += v * b4;
t6 += v * b5;
t7 += v * b6;
t8 += v * b7;
t9 += v * b8;
t10 += v * b9;
t11 += v * b10;
t12 += v * b11;
t13 += v * b12;
t14 += v * b13;
t15 += v * b14;
t16 += v * b15;
v = a[2];
t2 += v * b0;
t3 += v * b1;
t4 += v * b2;
t5 += v * b3;
t6 += v * b4;
t7 += v * b5;
t8 += v * b6;
t9 += v * b7;
t10 += v * b8;
t11 += v * b9;
t12 += v * b10;
t13 += v * b11;
t14 += v * b12;
t15 += v * b13;
t16 += v * b14;
t17 += v * b15;
v = a[3];
t3 += v * b0;
t4 += v * b1;
t5 += v * b2;
t6 += v * b3;
t7 += v * b4;
t8 += v * b5;
t9 += v * b6;
t10 += v * b7;
t11 += v * b8;
t12 += v * b9;
t13 += v * b10;
t14 += v * b11;
t15 += v * b12;
t16 += v * b13;
t17 += v * b14;
t18 += v * b15;
v = a[4];
t4 += v * b0;
t5 += v * b1;
t6 += v * b2;
t7 += v * b3;
t8 += v * b4;
t9 += v * b5;
t10 += v * b6;
t11 += v * b7;
t12 += v * b8;
t13 += v * b9;
t14 += v * b10;
t15 += v * b11;
t16 += v * b12;
t17 += v * b13;
t18 += v * b14;
t19 += v * b15;
v = a[5];
t5 += v * b0;
t6 += v * b1;
t7 += v * b2;
t8 += v * b3;
t9 += v * b4;
t10 += v * b5;
t11 += v * b6;
t12 += v * b7;
t13 += v * b8;
t14 += v * b9;
t15 += v * b10;
t16 += v * b11;
t17 += v * b12;
t18 += v * b13;
t19 += v * b14;
t20 += v * b15;
v = a[6];
t6 += v * b0;
t7 += v * b1;
t8 += v * b2;
t9 += v * b3;
t10 += v * b4;
t11 += v * b5;
t12 += v * b6;
t13 += v * b7;
t14 += v * b8;
t15 += v * b9;
t16 += v * b10;
t17 += v * b11;
t18 += v * b12;
t19 += v * b13;
t20 += v * b14;
t21 += v * b15;
v = a[7];
t7 += v * b0;
t8 += v * b1;
t9 += v * b2;
t10 += v * b3;
t11 += v * b4;
t12 += v * b5;
t13 += v * b6;
t14 += v * b7;
t15 += v * b8;
t16 += v * b9;
t17 += v * b10;
t18 += v * b11;
t19 += v * b12;
t20 += v * b13;
t21 += v * b14;
t22 += v * b15;
v = a[8];
t8 += v * b0;
t9 += v * b1;
t10 += v * b2;
t11 += v * b3;
t12 += v * b4;
t13 += v * b5;
t14 += v * b6;
t15 += v * b7;
t16 += v * b8;
t17 += v * b9;
t18 += v * b10;
t19 += v * b11;
t20 += v * b12;
t21 += v * b13;
t22 += v * b14;
t23 += v * b15;
v = a[9];
t9 += v * b0;
t10 += v * b1;
t11 += v * b2;
t12 += v * b3;
t13 += v * b4;
t14 += v * b5;
t15 += v * b6;
t16 += v * b7;
t17 += v * b8;
t18 += v * b9;
t19 += v * b10;
t20 += v * b11;
t21 += v * b12;
t22 += v * b13;
t23 += v * b14;
t24 += v * b15;
v = a[10];
t10 += v * b0;
t11 += v * b1;
t12 += v * b2;
t13 += v * b3;
t14 += v * b4;
t15 += v * b5;
t16 += v * b6;
t17 += v * b7;
t18 += v * b8;
t19 += v * b9;
t20 += v * b10;
t21 += v * b11;
t22 += v * b12;
t23 += v * b13;
t24 += v * b14;
t25 += v * b15;
v = a[11];
t11 += v * b0;
t12 += v * b1;
t13 += v * b2;
t14 += v * b3;
t15 += v * b4;
t16 += v * b5;
t17 += v * b6;
t18 += v * b7;
t19 += v * b8;
t20 += v * b9;
t21 += v * b10;
t22 += v * b11;
t23 += v * b12;
t24 += v * b13;
t25 += v * b14;
t26 += v * b15;
v = a[12];
t12 += v * b0;
t13 += v * b1;
t14 += v * b2;
t15 += v * b3;
t16 += v * b4;
t17 += v * b5;
t18 += v * b6;
t19 += v * b7;
t20 += v * b8;
t21 += v * b9;
t22 += v * b10;
t23 += v * b11;
t24 += v * b12;
t25 += v * b13;
t26 += v * b14;
t27 += v * b15;
v = a[13];
t13 += v * b0;
t14 += v * b1;
t15 += v * b2;
t16 += v * b3;
t17 += v * b4;
t18 += v * b5;
t19 += v * b6;
t20 += v * b7;
t21 += v * b8;
t22 += v * b9;
t23 += v * b10;
t24 += v * b11;
t25 += v * b12;
t26 += v * b13;
t27 += v * b14;
t28 += v * b15;
v = a[14];
t14 += v * b0;
t15 += v * b1;
t16 += v * b2;
t17 += v * b3;
t18 += v * b4;
t19 += v * b5;
t20 += v * b6;
t21 += v * b7;
t22 += v * b8;
t23 += v * b9;
t24 += v * b10;
t25 += v * b11;
t26 += v * b12;
t27 += v * b13;
t28 += v * b14;
t29 += v * b15;
v = a[15];
t15 += v * b0;
t16 += v * b1;
t17 += v * b2;
t18 += v * b3;
t19 += v * b4;
t20 += v * b5;
t21 += v * b6;
t22 += v * b7;
t23 += v * b8;
t24 += v * b9;
t25 += v * b10;
t26 += v * b11;
t27 += v * b12;
t28 += v * b13;
t29 += v * b14;
t30 += v * b15;
t0 += 38 * t16;
t1 += 38 * t17;
t2 += 38 * t18;
t3 += 38 * t19;
t4 += 38 * t20;
t5 += 38 * t21;
t6 += 38 * t22;
t7 += 38 * t23;
t8 += 38 * t24;
t9 += 38 * t25;
t10 += 38 * t26;
t11 += 38 * t27;
t12 += 38 * t28;
t13 += 38 * t29;
t14 += 38 * t30;
// t15 left as is
// first car
c = 1;
v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536;
v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536;
v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536;
v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536;
v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536;
v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536;
v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536;
v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536;
v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536;
v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536;
v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536;
v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536;
v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536;
v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536;
v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536;
v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536;
t0 += c-1 + 37 * (c-1);
// second car
c = 1;
v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536;
v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536;
v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536;
v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536;
v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536;
v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536;
v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536;
v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536;
v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536;
v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536;
v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536;
v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536;
v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536;
v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536;
v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536;
v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536;
t0 += c-1 + 37 * (c-1);
o[ 0] = t0;
o[ 1] = t1;
o[ 2] = t2;
o[ 3] = t3;
o[ 4] = t4;
o[ 5] = t5;
o[ 6] = t6;
o[ 7] = t7;
o[ 8] = t8;
o[ 9] = t9;
o[10] = t10;
o[11] = t11;
o[12] = t12;
o[13] = t13;
o[14] = t14;
o[15] = t15;
}
function S(o, a) {
M(o, a, a);
}
function sel25519(p, q, b) {
var t, c = ~(b-1);
for (var i = 0; i < 16; i++) {
t = c & (p[i] ^ q[i]);
p[i] ^= t;
q[i] ^= t;
}
}
function pack25519(o, n) {
var i, j, b;
var m = gf(), t = gf();
for (i = 0; i < 16; i++) t[i] = n[i];
car25519(t);
car25519(t);
car25519(t);
for (j = 0; j < 2; j++) {
m[0] = t[0] - 0xffed;
for (i = 1; i < 15; i++) {
m[i] = t[i] - 0xffff - ((m[i-1]>>16) & 1);
m[i-1] &= 0xffff;
}
m[15] = t[15] - 0x7fff - ((m[14]>>16) & 1);
b = (m[15]>>16) & 1;
m[14] &= 0xffff;
sel25519(t, m, 1-b);
}
for (i = 0; i < 16; i++) {
o[2*i] = t[i] & 0xff;
o[2*i+1] = t[i]>>8;
}
}
function unpack25519(o, n) {
var i;
for (i = 0; i < 16; i++) o[i] = n[2*i] + (n[2*i+1] << 8);
o[15] &= 0x7fff;
}
function inv25519(o, i) {
var c = gf();
var a;
for (a = 0; a < 16; a++) c[a] = i[a];
for (a = 253; a >= 0; a--) {
S(c, c);
if(a !== 2 && a !== 4) M(c, c, i);
}
for (a = 0; a < 16; a++) o[a] = c[a];
}
function car25519(o) {
var i, v, c = 1;
for (i = 0; i < 16; i++) {
v = o[i] + c + 65535;
c = Math.floor(v / 65536);
o[i] = v - c * 65536;
}
o[0] += c-1 + 37 * (c-1);
}
module.exports = {
gf,
A,
Z,
M,
S,
sel25519,
pack25519,
unpack25519,
inv25519,
gf0,
gf1,
_9,
_121665,
D,
D2,
X,
Y,
I
}
-360
View File
@@ -1,360 +0,0 @@
/*
* Port of Andrew Moon's Poly1305-donna-16. Public domain.
* https://github.com/floodyberry/poly1305-donna
*/
if (new Uint16Array([1])[0] !== 1) throw new Error('Big endian architecture is not supported.')
var poly1305 = function(key) {
this.buffer = new Uint8Array(16);
this.r = new Uint16Array(10);
this.h = new Uint16Array(10);
this.pad = new Uint16Array(8);
this.leftover = 0;
this.fin = 0;
var t0, t1, t2, t3, t4, t5, t6, t7;
t0 = key[ 0] & 0xff | (key[ 1] & 0xff) << 8; this.r[0] = ( t0 ) & 0x1fff;
t1 = key[ 2] & 0xff | (key[ 3] & 0xff) << 8; this.r[1] = ((t0 >>> 13) | (t1 << 3)) & 0x1fff;
t2 = key[ 4] & 0xff | (key[ 5] & 0xff) << 8; this.r[2] = ((t1 >>> 10) | (t2 << 6)) & 0x1f03;
t3 = key[ 6] & 0xff | (key[ 7] & 0xff) << 8; this.r[3] = ((t2 >>> 7) | (t3 << 9)) & 0x1fff;
t4 = key[ 8] & 0xff | (key[ 9] & 0xff) << 8; this.r[4] = ((t3 >>> 4) | (t4 << 12)) & 0x00ff;
this.r[5] = ((t4 >>> 1)) & 0x1ffe;
t5 = key[10] & 0xff | (key[11] & 0xff) << 8; this.r[6] = ((t4 >>> 14) | (t5 << 2)) & 0x1fff;
t6 = key[12] & 0xff | (key[13] & 0xff) << 8; this.r[7] = ((t5 >>> 11) | (t6 << 5)) & 0x1f81;
t7 = key[14] & 0xff | (key[15] & 0xff) << 8; this.r[8] = ((t6 >>> 8) | (t7 << 8)) & 0x1fff;
this.r[9] = ((t7 >>> 5)) & 0x007f;
this.pad[0] = key[16] & 0xff | (key[17] & 0xff) << 8;
this.pad[1] = key[18] & 0xff | (key[19] & 0xff) << 8;
this.pad[2] = key[20] & 0xff | (key[21] & 0xff) << 8;
this.pad[3] = key[22] & 0xff | (key[23] & 0xff) << 8;
this.pad[4] = key[24] & 0xff | (key[25] & 0xff) << 8;
this.pad[5] = key[26] & 0xff | (key[27] & 0xff) << 8;
this.pad[6] = key[28] & 0xff | (key[29] & 0xff) << 8;
this.pad[7] = key[30] & 0xff | (key[31] & 0xff) << 8;
};
poly1305.prototype.blocks = function(m, mpos, bytes) {
var hibit = this.fin ? 0 : (1 << 11);
var t0, t1, t2, t3, t4, t5, t6, t7, c;
var d0, d1, d2, d3, d4, d5, d6, d7, d8, d9;
var h0 = this.h[0],
h1 = this.h[1],
h2 = this.h[2],
h3 = this.h[3],
h4 = this.h[4],
h5 = this.h[5],
h6 = this.h[6],
h7 = this.h[7],
h8 = this.h[8],
h9 = this.h[9];
var r0 = this.r[0],
r1 = this.r[1],
r2 = this.r[2],
r3 = this.r[3],
r4 = this.r[4],
r5 = this.r[5],
r6 = this.r[6],
r7 = this.r[7],
r8 = this.r[8],
r9 = this.r[9];
while (bytes >= 16) {
t0 = m[mpos+ 0] & 0xff | (m[mpos+ 1] & 0xff) << 8; h0 += ( t0 ) & 0x1fff;
t1 = m[mpos+ 2] & 0xff | (m[mpos+ 3] & 0xff) << 8; h1 += ((t0 >>> 13) | (t1 << 3)) & 0x1fff;
t2 = m[mpos+ 4] & 0xff | (m[mpos+ 5] & 0xff) << 8; h2 += ((t1 >>> 10) | (t2 << 6)) & 0x1fff;
t3 = m[mpos+ 6] & 0xff | (m[mpos+ 7] & 0xff) << 8; h3 += ((t2 >>> 7) | (t3 << 9)) & 0x1fff;
t4 = m[mpos+ 8] & 0xff | (m[mpos+ 9] & 0xff) << 8; h4 += ((t3 >>> 4) | (t4 << 12)) & 0x1fff;
h5 += ((t4 >>> 1)) & 0x1fff;
t5 = m[mpos+10] & 0xff | (m[mpos+11] & 0xff) << 8; h6 += ((t4 >>> 14) | (t5 << 2)) & 0x1fff;
t6 = m[mpos+12] & 0xff | (m[mpos+13] & 0xff) << 8; h7 += ((t5 >>> 11) | (t6 << 5)) & 0x1fff;
t7 = m[mpos+14] & 0xff | (m[mpos+15] & 0xff) << 8; h8 += ((t6 >>> 8) | (t7 << 8)) & 0x1fff;
h9 += ((t7 >>> 5)) | hibit;
c = 0;
d0 = c;
d0 += h0 * r0;
d0 += h1 * (5 * r9);
d0 += h2 * (5 * r8);
d0 += h3 * (5 * r7);
d0 += h4 * (5 * r6);
c = (d0 >>> 13); d0 &= 0x1fff;
d0 += h5 * (5 * r5);
d0 += h6 * (5 * r4);
d0 += h7 * (5 * r3);
d0 += h8 * (5 * r2);
d0 += h9 * (5 * r1);
c += (d0 >>> 13); d0 &= 0x1fff;
d1 = c;
d1 += h0 * r1;
d1 += h1 * r0;
d1 += h2 * (5 * r9);
d1 += h3 * (5 * r8);
d1 += h4 * (5 * r7);
c = (d1 >>> 13); d1 &= 0x1fff;
d1 += h5 * (5 * r6);
d1 += h6 * (5 * r5);
d1 += h7 * (5 * r4);
d1 += h8 * (5 * r3);
d1 += h9 * (5 * r2);
c += (d1 >>> 13); d1 &= 0x1fff;
d2 = c;
d2 += h0 * r2;
d2 += h1 * r1;
d2 += h2 * r0;
d2 += h3 * (5 * r9);
d2 += h4 * (5 * r8);
c = (d2 >>> 13); d2 &= 0x1fff;
d2 += h5 * (5 * r7);
d2 += h6 * (5 * r6);
d2 += h7 * (5 * r5);
d2 += h8 * (5 * r4);
d2 += h9 * (5 * r3);
c += (d2 >>> 13); d2 &= 0x1fff;
d3 = c;
d3 += h0 * r3;
d3 += h1 * r2;
d3 += h2 * r1;
d3 += h3 * r0;
d3 += h4 * (5 * r9);
c = (d3 >>> 13); d3 &= 0x1fff;
d3 += h5 * (5 * r8);
d3 += h6 * (5 * r7);
d3 += h7 * (5 * r6);
d3 += h8 * (5 * r5);
d3 += h9 * (5 * r4);
c += (d3 >>> 13); d3 &= 0x1fff;
d4 = c;
d4 += h0 * r4;
d4 += h1 * r3;
d4 += h2 * r2;
d4 += h3 * r1;
d4 += h4 * r0;
c = (d4 >>> 13); d4 &= 0x1fff;
d4 += h5 * (5 * r9);
d4 += h6 * (5 * r8);
d4 += h7 * (5 * r7);
d4 += h8 * (5 * r6);
d4 += h9 * (5 * r5);
c += (d4 >>> 13); d4 &= 0x1fff;
d5 = c;
d5 += h0 * r5;
d5 += h1 * r4;
d5 += h2 * r3;
d5 += h3 * r2;
d5 += h4 * r1;
c = (d5 >>> 13); d5 &= 0x1fff;
d5 += h5 * r0;
d5 += h6 * (5 * r9);
d5 += h7 * (5 * r8);
d5 += h8 * (5 * r7);
d5 += h9 * (5 * r6);
c += (d5 >>> 13); d5 &= 0x1fff;
d6 = c;
d6 += h0 * r6;
d6 += h1 * r5;
d6 += h2 * r4;
d6 += h3 * r3;
d6 += h4 * r2;
c = (d6 >>> 13); d6 &= 0x1fff;
d6 += h5 * r1;
d6 += h6 * r0;
d6 += h7 * (5 * r9);
d6 += h8 * (5 * r8);
d6 += h9 * (5 * r7);
c += (d6 >>> 13); d6 &= 0x1fff;
d7 = c;
d7 += h0 * r7;
d7 += h1 * r6;
d7 += h2 * r5;
d7 += h3 * r4;
d7 += h4 * r3;
c = (d7 >>> 13); d7 &= 0x1fff;
d7 += h5 * r2;
d7 += h6 * r1;
d7 += h7 * r0;
d7 += h8 * (5 * r9);
d7 += h9 * (5 * r8);
c += (d7 >>> 13); d7 &= 0x1fff;
d8 = c;
d8 += h0 * r8;
d8 += h1 * r7;
d8 += h2 * r6;
d8 += h3 * r5;
d8 += h4 * r4;
c = (d8 >>> 13); d8 &= 0x1fff;
d8 += h5 * r3;
d8 += h6 * r2;
d8 += h7 * r1;
d8 += h8 * r0;
d8 += h9 * (5 * r9);
c += (d8 >>> 13); d8 &= 0x1fff;
d9 = c;
d9 += h0 * r9;
d9 += h1 * r8;
d9 += h2 * r7;
d9 += h3 * r6;
d9 += h4 * r5;
c = (d9 >>> 13); d9 &= 0x1fff;
d9 += h5 * r4;
d9 += h6 * r3;
d9 += h7 * r2;
d9 += h8 * r1;
d9 += h9 * r0;
c += (d9 >>> 13); d9 &= 0x1fff;
c = (((c << 2) + c)) | 0;
c = (c + d0) | 0;
d0 = c & 0x1fff;
c = (c >>> 13);
d1 += c;
h0 = d0;
h1 = d1;
h2 = d2;
h3 = d3;
h4 = d4;
h5 = d5;
h6 = d6;
h7 = d7;
h8 = d8;
h9 = d9;
mpos += 16;
bytes -= 16;
}
this.h[0] = h0;
this.h[1] = h1;
this.h[2] = h2;
this.h[3] = h3;
this.h[4] = h4;
this.h[5] = h5;
this.h[6] = h6;
this.h[7] = h7;
this.h[8] = h8;
this.h[9] = h9;
};
poly1305.prototype.finish = function(mac, macpos) {
var g = new Uint16Array(10);
var c, mask, f, i;
if (this.leftover) {
i = this.leftover;
this.buffer[i++] = 1;
for (; i < 16; i++) this.buffer[i] = 0;
this.fin = 1;
this.blocks(this.buffer, 0, 16);
}
c = this.h[1] >>> 13;
this.h[1] &= 0x1fff;
for (i = 2; i < 10; i++) {
this.h[i] += c;
c = this.h[i] >>> 13;
this.h[i] &= 0x1fff;
}
this.h[0] += (c * 5);
c = this.h[0] >>> 13;
this.h[0] &= 0x1fff;
this.h[1] += c;
c = this.h[1] >>> 13;
this.h[1] &= 0x1fff;
this.h[2] += c;
g[0] = this.h[0] + 5;
c = g[0] >>> 13;
g[0] &= 0x1fff;
for (i = 1; i < 10; i++) {
g[i] = this.h[i] + c;
c = g[i] >>> 13;
g[i] &= 0x1fff;
}
g[9] -= (1 << 13);
mask = (c ^ 1) - 1;
for (i = 0; i < 10; i++) g[i] &= mask;
mask = ~mask;
for (i = 0; i < 10; i++) this.h[i] = (this.h[i] & mask) | g[i];
this.h[0] = ((this.h[0] ) | (this.h[1] << 13) ) & 0xffff;
this.h[1] = ((this.h[1] >>> 3) | (this.h[2] << 10) ) & 0xffff;
this.h[2] = ((this.h[2] >>> 6) | (this.h[3] << 7) ) & 0xffff;
this.h[3] = ((this.h[3] >>> 9) | (this.h[4] << 4) ) & 0xffff;
this.h[4] = ((this.h[4] >>> 12) | (this.h[5] << 1) | (this.h[6] << 14)) & 0xffff;
this.h[5] = ((this.h[6] >>> 2) | (this.h[7] << 11) ) & 0xffff;
this.h[6] = ((this.h[7] >>> 5) | (this.h[8] << 8) ) & 0xffff;
this.h[7] = ((this.h[8] >>> 8) | (this.h[9] << 5) ) & 0xffff;
f = this.h[0] + this.pad[0];
this.h[0] = f & 0xffff;
for (i = 1; i < 8; i++) {
f = (((this.h[i] + this.pad[i]) | 0) + (f >>> 16)) | 0;
this.h[i] = f & 0xffff;
}
mac[macpos+ 0] = (this.h[0] >>> 0) & 0xff;
mac[macpos+ 1] = (this.h[0] >>> 8) & 0xff;
mac[macpos+ 2] = (this.h[1] >>> 0) & 0xff;
mac[macpos+ 3] = (this.h[1] >>> 8) & 0xff;
mac[macpos+ 4] = (this.h[2] >>> 0) & 0xff;
mac[macpos+ 5] = (this.h[2] >>> 8) & 0xff;
mac[macpos+ 6] = (this.h[3] >>> 0) & 0xff;
mac[macpos+ 7] = (this.h[3] >>> 8) & 0xff;
mac[macpos+ 8] = (this.h[4] >>> 0) & 0xff;
mac[macpos+ 9] = (this.h[4] >>> 8) & 0xff;
mac[macpos+10] = (this.h[5] >>> 0) & 0xff;
mac[macpos+11] = (this.h[5] >>> 8) & 0xff;
mac[macpos+12] = (this.h[6] >>> 0) & 0xff;
mac[macpos+13] = (this.h[6] >>> 8) & 0xff;
mac[macpos+14] = (this.h[7] >>> 0) & 0xff;
mac[macpos+15] = (this.h[7] >>> 8) & 0xff;
};
poly1305.prototype.update = function(m, mpos, bytes) {
var i, want;
if (this.leftover) {
want = (16 - this.leftover);
if (want > bytes)
want = bytes;
for (i = 0; i < want; i++)
this.buffer[this.leftover + i] = m[mpos+i];
bytes -= want;
mpos += want;
this.leftover += want;
if (this.leftover < 16)
return;
this.blocks(this.buffer, 0, 16);
this.leftover = 0;
}
if (bytes >= 16) {
want = bytes - (bytes % 16);
this.blocks(m, mpos, want);
mpos += want;
bytes -= want;
}
if (bytes) {
for (i = 0; i < bytes; i++)
this.buffer[this.leftover + i] = m[mpos+i];
this.leftover += bytes;
}
};
module.exports = poly1305
-23
View File
@@ -1,23 +0,0 @@
/* 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
}
+12 -31
View File
@@ -1,51 +1,32 @@
{
"name": "sodium-javascript",
"version": "0.7.1",
"version": "0.5.2",
"description": "WIP - a pure javascript version of sodium-native",
"main": "index.js",
"dependencies": {
"blake2b": "^2.1.1",
"chacha20-universal": "^1.0.4",
"nanoassert": "^2.0.0",
"sha256-universal": "^1.1.0",
"sha512-universal": "^1.1.0",
"nanoassert": "^1.0.0",
"siphash24": "^1.0.1",
"xsalsa20": "^1.0.0"
},
"devDependencies": {
"browserify": "^16.5.1",
"sodium-test": "^0.10.0",
"standard": "^14.3.4",
"tape-run": "^7.0.0"
},
"standard": {
"ignore": [
"/internal/**/*.js"
]
},
"browser": {
"crypto": false
},
"react-native": {
"crypto": "crypto"
"browser-run": "^4.0.2",
"browserify": "^14.1.0",
"sodium-test": "^0.7.0"
},
"scripts": {
"pretest": "standard",
"test": "node test.js",
"test-browser": "browserify test.js | tape-run"
"browser": "browserify test.js | browser-run",
"browser-manual": "browserify test.js | browser-run -p 1234",
"test": "node test.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/sodium-friends/sodium-javascript.git"
"url": "https://github.com/mafintosh/sodium-javascript.git"
},
"contributors": [
"Christophe Diederichs <chm-diederichs@hyperdivision.dk>",
"Emil Bay <github@tixz.dk> (http://bayes.dk)",
"Mathias Buus <mathiasbuus@gmail.com> (https://mafinto.sh)"
],
"author": "Mathias Buus (@mafintosh)",
"license": "MIT",
"bugs": {
"url": "https://github.com/sodium-friends/sodium-javascript/issues"
"url": "https://github.com/mafintosh/sodium-javascript/issues"
},
"homepage": "https://github.com/sodium-friends/sodium-javascript#readme"
"homepage": "https://github.com/mafintosh/sodium-javascript"
}
+13 -13
View File
@@ -1,40 +1,40 @@
var assert = require('nanoassert')
var randombytes = (function () {
var QUOTA = 65536 // limit for QuotaExceededException
var crypto = global.crypto || global.msCrypto
var crypto = typeof global !== 'undefined' ? crypto = (global.crypto || global.msCrypto) : null
function browserBytes (out, n) {
for (let i = 0; i < n; i += QUOTA) {
crypto.getRandomValues(new Uint8Array(out.buffer, i + out.byteOffset, Math.min(n - i, QUOTA)))
for (var i = 0; i < n; i += QUOTA) {
crypto.getRandomValues(out.subarray(i, i + Math.min(n - i, QUOTA)))
}
}
function nodeBytes (out, n) {
new Uint8Array(out.buffer, out.byteOffset, n).set(crypto.randomBytes(n))
out.set(crypto.randomBytes(n))
}
function noImpl () {
throw new Error('No secure random number generator available')
}
if (crypto && crypto.getRandomValues) return browserBytes
if (require != null) {
// Node.js. Bust Browserify
crypto = require('cry' + 'pto')
if (crypto && crypto.randomBytes) return nodeBytes
if (crypto && crypto.getRandomValues) {
return browserBytes
} else if (typeof require !== 'undefined') {
// Node.js.
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.byteLength)
randombytes(out, out.length)
}