Compare commits

...
43 Commits
Author SHA1 Message Date
Christophe Diederichs 426ca77d47 0.7.4 2021-11-05 09:32:51 +00:00
Kasper Isager Dalsgarð 25c97802f4 crypto_sign: replace Buffer.alloc() with new Uint8Array() (#62) 2021-11-04 17:17:13 +00:00
Kasper Isager Dalsgarð 87ff2a56bd Use globalThis instead of global (#61)
* Use `globalThis` instead of `global`

* Update `standard`
2021-11-02 16:36:15 +01:00
RangerMauve 7ef6e52870 Remove "react-native" field
This field isn't adding anything at the moment, and it actually breaks things by pointing at an unresolvable module.
2020-12-01 11:29:33 +01:00
Mathias Buus 0227f45c6b 0.7.3 2020-11-13 16:46:11 +01:00
Mathias Buus ca32540960 load the sink just in time 2020-11-13 16:46:06 +01:00
Mathias Buus 51093efbc5 0.7.2 2020-11-12 14:46:28 +01:00
Christophe Diederichs f79aed4eee turn off worker_threads in browser (#52) 2020-11-12 14:04:40 +01:00
Kyle Mathews 3eb1d64460 Small copy change to README (#54) 2020-11-12 08:39:33 +01:00
RangerMauve 7febc97986 Detect window.close is defined (#49) 2020-10-09 13:35:11 +02:00
Christophe Diederichs 66494ec3b5 0.7.1 2020-09-22 15:56:40 +02:00
Christophe Diederichs 35f38a6c10 missing export: crypto_sign_ed25519_sk_to_pk 2020-09-22 15:50:00 +02:00
Christophe Diederichs 125384f26a remove lockfile 2020-09-22 15:34:54 +02:00
Christophe Diederichs d432fe295d crypto_aead: correctly hadle ad passed as null 2020-09-22 15:30:31 +02:00
Christophe Diederichs 97200f90da 0.7.0 2020-09-22 14:56:20 +02:00
Christian Bundy 656d6d251e Add crypto_auth (#32)
* add crypto_auth_hmac methods
2020-09-22 14:49:40 +02:00
Christian Bundy 61b6e6916a Add crypto_box_easy (#29)
* Fix backward crypto_secretbox_detached bug

* Add crypto_box_easy
2020-09-22 14:47:36 +02:00
Christophe Diederichs ab004d8022 Add ed25519 conversion operations (#46)
* add ed25519 methods and constants
2020-09-22 14:46:45 +02:00
Christophe Diederichs ce5ac41ecd 0.6.3 2020-09-15 17:39:54 +02:00
Christophe Diederichs a82160d51b crypto_verify return booleans & add crypto_verify_64 (#33)
* crypto_verify return booleans

* can now return crypto_verify result directly

* remove redundant return values

* unpackneg check returns boolean
2020-09-15 17:27:39 +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
26 changed files with 799 additions and 396 deletions
+1
View File
@@ -1 +1,2 @@
node_modules node_modules
package-lock.json
+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
+24 -15
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 Based on tweetnacl
```
npm install sodium-javascript
```
## Usage ## Usage
``` js ``` js
var sodium = require('sodium-javascript') const sodium = require('sodium-javascript')
var key = new Buffer(sodium.crypto_secretbox_KEYBYTES) const key = Buffer.alloc(sodium.crypto_secretbox_KEYBYTES)
var nonce = new Buffer(sodium.crypto_secretbox_NONCEBYTES) const nonce = Buffer.alloc(sodium.crypto_secretbox_NONCEBYTES)
sodium.randombytes_buf(key) sodium.randombytes_buf(key)
sodium.randombytes_buf(nonce) sodium.randombytes_buf(nonce)
var message = new Buffer('Hello, World!') const message = Buffer.from('Hello, World!')
var cipher = new Buffer(message.length + sodium.crypto_secretbox_MACBYTES) const cipher = Buffer.alloc(message.length + sodium.crypto_secretbox_MACBYTES)
sodium.crypto_secretbox_easy(cipher, message, nonce, key) sodium.crypto_secretbox_easy(cipher, message, nonce, key)
console.log('Encrypted:', cipher) 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) sodium.crypto_secretbox_open_easy(plainText, cipher, nonce, key)
@@ -34,9 +32,20 @@ console.log('Plaintext:', plainText.toString())
## API ## 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 is a work in progress so not all functions are 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 ## License
MIT [MIT](LICENSE)
+5 -4
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_stream_chacha20_ietf, crypto_stream_chacha20_ietf_xor_ic } = require('./crypto_stream_chacha20')
const { crypto_verify_16 } = require('./crypto_verify') const { crypto_verify_16 } = require('./crypto_verify')
const Poly1305 = require('./poly1305.js') const Poly1305 = require('./internal/poly1305')
const assert = require('nanoassert') const assert = require('nanoassert')
const crypto_aead_chacha20poly1305_ietf_KEYBYTES = 32 const crypto_aead_chacha20poly1305_ietf_KEYBYTES = 32
@@ -29,7 +30,7 @@ function crypto_aead_chacha20poly1305_ietf_encrypt (c, m, ad, nsec, npub, k) {
} }
function crypto_aead_chacha20poly1305_ietf_encrypt_detached (c, mac, m, ad, nsec, npub, k) { function crypto_aead_chacha20poly1305_ietf_encrypt_detached (c, mac, m, ad, nsec, npub, k) {
if (ad === null) return crypto_aead_chacha20poly1305_ietf_encrypt(c, mac, m, new Uint8Array(0), 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(c.byteLength === m.byteLength, 'ciphertext should be same length than message')
assert(npub.byteLength === crypto_aead_chacha20poly1305_ietf_NPUBBYTES, assert(npub.byteLength === crypto_aead_chacha20poly1305_ietf_NPUBBYTES,
@@ -90,7 +91,7 @@ function crypto_aead_chacha20poly1305_ietf_decrypt (m, nsec, c, ad, npub, k) {
} }
function crypto_aead_chacha20poly1305_ietf_decrypt_detached (m, nsec, c, mac, ad, npub, k) { function crypto_aead_chacha20poly1305_ietf_decrypt_detached (m, nsec, c, mac, ad, npub, k) {
if (ad === null) return crypto_aead_chacha20poly1305_ietf_decrypt(m, nsec, c, mac, new Uint8Array(0), 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(c.byteLength === m.byteLength, 'message should be same length than ciphertext')
assert(npub.byteLength === crypto_aead_chacha20poly1305_ietf_NPUBBYTES, assert(npub.byteLength === crypto_aead_chacha20poly1305_ietf_NPUBBYTES,
@@ -130,7 +131,7 @@ function crypto_aead_chacha20poly1305_ietf_decrypt_detached (m, nsec, c, mac, ad
computed_mac.fill(0) computed_mac.fill(0)
slen.fill(0) slen.fill(0)
if (ret !== 0) { if (!ret) {
m.fill(0) m.fill(0)
throw new Error('could not verify data') throw new Error('could not verify data')
} }
+35
View File
@@ -0,0 +1,35 @@
/* 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
}
+116 -21
View File
@@ -1,45 +1,59 @@
/* eslint-disable camelcase */
const { crypto_hash_sha512 } = require('./crypto_hash') const { crypto_hash_sha512 } = require('./crypto_hash')
const { crypto_scalarmult, crypto_scalarmult_base } = require('./crypto_scalarmult') const { crypto_scalarmult, crypto_scalarmult_base } = require('./crypto_scalarmult')
const { randombytes } = require('./randombytes') const { randombytes } = require('./randombytes')
const { crypto_generichash_batch } = require('./crypto_generichash') const { crypto_generichash_batch } = require('./crypto_generichash')
const { crypto_secretbox_open_easy, crypto_secretbox_easy } = require('./crypto_secretbox') 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 xsalsa20 = require('xsalsa20')
const assert = require('nanoassert') const assert = require('nanoassert')
var crypto_box_PUBLICKEYBYTES = 32, const crypto_box_PUBLICKEYBYTES = 32
crypto_box_SECRETKEYBYTES = 32, const crypto_box_SECRETKEYBYTES = 32
crypto_box_BEFORENMBYTES = 32, const crypto_box_NONCEBYTES = 24
crypto_box_NONCEBYTES = 24, const crypto_box_ZEROBYTES = 32
crypto_box_ZEROBYTES = 32, const crypto_box_BOXZEROBYTES = 16
crypto_box_BOXZEROBYTES = 16, const crypto_box_SEALBYTES = 48
crypto_box_SEALBYTES = 48, const crypto_box_SEEDBYTES = 32
crypto_box_SEEDBYTES = 32, const crypto_box_BEFORENMBYTES = 32
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 = { module.exports = {
crypto_box_easy,
crypto_box_open_easy,
crypto_box_keypair, crypto_box_keypair,
crypto_box_seed_keypair, crypto_box_seed_keypair,
crypto_box_seal, crypto_box_seal,
crypto_box_seal_open, crypto_box_seal_open,
crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES,
crypto_box_SECRETKEYBYTES, crypto_box_SECRETKEYBYTES,
crypto_box_BEFORENMBYTES,
crypto_box_NONCEBYTES, crypto_box_NONCEBYTES,
crypto_box_ZEROBYTES, crypto_box_ZEROBYTES,
crypto_box_BOXZEROBYTES, crypto_box_BOXZEROBYTES,
crypto_box_SEALBYTES, crypto_box_SEALBYTES,
crypto_box_SEEDBYTES, crypto_box_SEEDBYTES,
crypto_box_BEFORENMBYTES crypto_box_BEFORENMBYTES,
crypto_box_MACBYTES
} }
function crypto_box_keypair(pk, sk) { function crypto_box_keypair (pk, sk) {
check(pk, crypto_box_PUBLICKEYBYTES) check(pk, crypto_box_PUBLICKEYBYTES)
check(sk, crypto_box_SECRETKEYBYTES) check(sk, crypto_box_SECRETKEYBYTES)
randombytes(sk, 32) randombytes(sk, 32)
return crypto_scalarmult_base(pk, sk) 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(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_SECRETKEYBYTES, "sk should be 'crypto_box_SECRETKEYBYTES' bytes")
assert(sk.byteLength === crypto_box_SEEDBYTES, "sk should be 'crypto_box_SEEDBYTES' bytes") assert(sk.byteLength === crypto_box_SEEDBYTES, "sk should be 'crypto_box_SEEDBYTES' bytes")
@@ -52,7 +66,7 @@ function crypto_box_seed_keypair(pk, sk, seed) {
return crypto_scalarmult_base(pk, sk) 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(c, crypto_box_SEALBYTES + m.length)
check(pk, crypto_box_PUBLICKEYBYTES) check(pk, crypto_box_PUBLICKEYBYTES)
@@ -61,7 +75,7 @@ function crypto_box_seal(c, m, pk) {
crypto_box_keypair(epk, esk) crypto_box_keypair(epk, esk)
var n = new Uint8Array(crypto_box_NONCEBYTES) 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) var s = new Uint8Array(crypto_box_PUBLICKEYBYTES)
crypto_scalarmult(s, esk, pk) crypto_scalarmult(s, esk, pk)
@@ -75,7 +89,7 @@ function crypto_box_seal(c, m, pk) {
cleanup(esk) 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(c, crypto_box_SEALBYTES)
check(m, c.length - crypto_box_SEALBYTES) check(m, c.length - crypto_box_SEALBYTES)
check(pk, crypto_box_PUBLICKEYBYTES) check(pk, crypto_box_PUBLICKEYBYTES)
@@ -84,7 +98,7 @@ function crypto_box_seal_open(m, c, pk, sk) {
var epk = c.subarray(0, crypto_box_PUBLICKEYBYTES) var epk = c.subarray(0, crypto_box_PUBLICKEYBYTES)
var n = new Uint8Array(crypto_box_NONCEBYTES) 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) var s = new Uint8Array(crypto_box_PUBLICKEYBYTES)
crypto_scalarmult(s, sk, epk) crypto_scalarmult(s, sk, epk)
@@ -96,10 +110,91 @@ function crypto_box_seal_open(m, c, pk, sk) {
return crypto_secretbox_open_easy(m, c.subarray(epk.length), n, k) 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) { function check (buf, len) {
if (!buf || (len && buf.length < len)) throw new Error('Argument must be a buffer' + (len ? ' of length ' + len : '')) if (!buf || (len && buf.length < len)) throw new Error('Argument must be a buffer' + (len ? ' of length ' + len : ''))
} }
function cleanup(arr) { function cleanup (arr) {
for (var i = 0; i < arr.length; i++) arr[i] = 0; 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) return blake2b(outlen, key)
} }
blake2b.ready(function (err) { blake2b.ready(function (_) {
module.exports.crypto_generichash_WASM_LOADED = blake2b.WASM_LOADED 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') const assert = require('nanoassert')
if (new Uint16Array([1])[0] !== 1) throw new Error('Big endian architecture is not supported.') if (new Uint16Array([1])[0] !== 1) throw new Error('Big endian architecture is not supported.')
var crypto_hash_sha512_BYTES = 64 const crypto_hash_sha512_BYTES = 64
var crypto_hash_BYTES = crypto_hash_sha512_BYTES const crypto_hash_BYTES = crypto_hash_sha512_BYTES
function crypto_hash_sha512 (out, m, n) { function crypto_hash_sha512 (out, m, n) {
assert(out.byteLength === crypto_hash_sha512_BYTES, "out must be 'crypto_hash_sha512_BYTES' bytes long") 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') const assert = require('nanoassert')
if (new Uint16Array([1])[0] !== 1) throw new Error('Big endian architecture is not supported.') 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) { function crypto_hash_sha256 (out, m, n) {
assert(out.byteLength === crypto_hash_sha256_BYTES, "out must be 'crypto_hash_sha256_BYTES' bytes long") 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') /* eslint-disable camelcase */
var randombytes_buf = require('./randombytes').randombytes_buf const assert = require('nanoassert')
var blake2b = require('blake2b') const randombytes_buf = require('./randombytes').randombytes_buf
const blake2b = require('blake2b')
module.exports.crypto_kdf_PRIMITIVE = 'blake2b' module.exports.crypto_kdf_PRIMITIVE = 'blake2b'
module.exports.crypto_kdf_BYTES_MIN = 16 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_CONTEXTBYTES = 8
module.exports.crypto_kdf_KEYBYTES = 32 module.exports.crypto_kdf_KEYBYTES = 32
function STORE64_LE(dest, int) { function STORE64_LE (dest, int) {
var mul = 1 var mul = 1
var i = 0 var i = 0
dest[0] = int & 0xFF dest[0] = int & 0xFF
+4 -3
View File
@@ -1,11 +1,12 @@
/* eslint-disable camelcase */
const { crypto_scalarmult_base } = require('./crypto_scalarmult') const { crypto_scalarmult_base } = require('./crypto_scalarmult')
const { crypto_generichash } = require('./crypto_generichash') const { crypto_generichash } = require('./crypto_generichash')
const { randombytes_buf } = require('./randombytes') const { randombytes_buf } = require('./randombytes')
const assert = require('nanoassert') const assert = require('nanoassert')
var crypto_kx_SEEDBYTES = 32 const crypto_kx_SEEDBYTES = 32
var crypto_kx_PUBLICKEYBYTES = 32 const crypto_kx_PUBLICKEYBYTES = 32
var crypto_kx_SECRETKEYBYTES = 32 const crypto_kx_SECRETKEYBYTES = 32
function crypto_kx_keypair (pk, sk) { function crypto_kx_keypair (pk, sk) {
assert(pk.byteLength === crypto_kx_PUBLICKEYBYTES, "pk must be 'crypto_kx_PUBLICKEYBYTES' bytes") assert(pk.byteLength === crypto_kx_PUBLICKEYBYTES, "pk must be 'crypto_kx_PUBLICKEYBYTES' bytes")
+27 -11
View File
@@ -1,20 +1,36 @@
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_verify_16 } = require('./crypto_verify')
const crypto_onetimeauth_BYTES = 16
const crypto_onetimeauth_KEYBYTES = 32
const crypto_onetimeauth_PRIMITIVE = 'poly1305'
module.exports = { module.exports = {
crypto_onetimeauth, 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) { function crypto_onetimeauth (mac, msg, key) {
var s = new poly1305(k); assert(mac.byteLength === crypto_onetimeauth_BYTES, "mac must be 'crypto_onetimeauth_BYTES' bytes")
s.update(m, mpos, n); assert(msg.byteLength != null, 'msg must be buffer')
s.finish(out, outpos); assert(key.byteLength === crypto_onetimeauth_KEYBYTES, "key must be 'crypto_onetimeauth_KEYBYTES' bytes")
return 0;
var s = new Poly1305(key)
s.update(msg, 0, msg.byteLength)
s.finish(mac, 0)
} }
function crypto_onetimeauth_verify(h, hpos, m, mpos, n, k) { function crypto_onetimeauth_verify (mac, msg, key) {
var x = new Uint8Array(16); assert(mac.byteLength === crypto_onetimeauth_BYTES, "mac must be 'crypto_onetimeauth_BYTES' bytes")
crypto_onetimeauth(x,0,m,mpos,n,k); assert(msg.byteLength != null, 'msg must be buffer')
return crypto_verify_16(h,hpos,x,0); 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)
} }
+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 const crypto_scalarmult_BYTES = 32
var crypto_scalarmult_SCALARBYTES = 32 const crypto_scalarmult_SCALARBYTES = 32
var crypto_scalarmult_BYTES = 32
var crypto_scalarmult_SCALARBYTES = 32
module.exports = { module.exports = {
crypto_scalarmult, crypto_scalarmult,
@@ -19,7 +18,7 @@ function crypto_scalarmult (q, n, p) {
var z = new Uint8Array(32) var z = new Uint8Array(32)
var x = new Float64Array(80), r, i var x = new Float64Array(80), r, i
var a = gf(), b = gf(), c = gf(), 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] for (i = 0; i < 31; i++) z[i] = n[i]
z[31] = (n[31] & 127) | 64 z[31] = (n[31] & 127) | 64
z[0] &= 248 z[0] &= 248
+86 -68
View File
@@ -1,11 +1,13 @@
var { crypto_stream, crypto_stream_xor } = require('./crypto_stream') /* eslint-disable camelcase */
var { crypto_onetimeauth, crypto_onetimeauth_verify } = require('./crypto_onetimeauth') 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, const crypto_secretbox_KEYBYTES = 32
crypto_secretbox_NONCEBYTES = 24, const crypto_secretbox_NONCEBYTES = 24
crypto_secretbox_ZEROBYTES = 32, const crypto_secretbox_ZEROBYTES = 32
crypto_secretbox_BOXZEROBYTES = 16, const crypto_secretbox_BOXZEROBYTES = 16
crypto_secretbox_MACBYTES = 16 const crypto_secretbox_MACBYTES = 16
module.exports = { module.exports = {
crypto_secretbox, crypto_secretbox,
@@ -21,73 +23,89 @@ module.exports = {
crypto_secretbox_MACBYTES crypto_secretbox_MACBYTES
} }
function crypto_secretbox (c, m, d, n, k) { function crypto_secretbox (c, m, n, k) {
var i assert(c.byteLength === m.byteLength, "c must be 'm.byteLength' bytes")
if (d < 32) return -1 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_stream_xor(c, m, n, k)
crypto_onetimeauth(c, 16, c, 32, d - 32, c) crypto_onetimeauth(
for (i = 0; i < 16; i++) c[i] = 0 c.subarray(crypto_secretbox_BOXZEROBYTES, crypto_secretbox_BOXZEROBYTES + crypto_onetimeauth_BYTES),
return 0 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, d, n, k) { function crypto_secretbox_open (m, c, n, k) {
var i assert(c.byteLength === m.byteLength, "c must be 'm.byteLength' bytes")
var x = new Uint8Array(32) const mlen = m.byteLength
if (d < 32) return -1 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) 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) crypto_stream_xor(m, c, n, k)
for (i = 0; i < 32; i++) m[i] = 0 m.fill(0, 0, 32)
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]
return true return true
} }
function check (buf, len) { function crypto_secretbox_detached (o, mac, msg, n, k) {
if (!buf || (len && buf.length < len)) throw new Error('Argument must be a buffer' + (len ? ' of length ' + len : '')) 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
} }
+334 -184
View File
@@ -1,3 +1,4 @@
/* eslint-disable camelcase, one-var */
const { crypto_verify_32 } = require('./crypto_verify') const { crypto_verify_32 } = require('./crypto_verify')
const { crypto_hash } = require('./crypto_hash') const { crypto_hash } = require('./crypto_hash')
const { const {
@@ -5,13 +6,21 @@ const {
X, Y, I, A, Z, M, S, X, Y, I, A, Z, M, S,
sel25519, pack25519, sel25519, pack25519,
inv25519, unpack25519 inv25519, unpack25519
} = require('./ed25519') } = require('./internal/ed25519')
const { randombytes } = require('./randombytes') 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_BYTES = 64, const crypto_sign_ed25519_PUBLICKEYBYTES = 32
crypto_sign_PUBLICKEYBYTES = 32, const crypto_sign_ed25519_SECRETKEYBYTES = 64
crypto_sign_SECRETKEYBYTES = 64, const crypto_sign_ed25519_SEEDBYTES = 32
crypto_sign_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 = { module.exports = {
crypto_sign_keypair, crypto_sign_keypair,
@@ -23,110 +32,119 @@ module.exports = {
crypto_sign_BYTES, crypto_sign_BYTES,
crypto_sign_PUBLICKEYBYTES, crypto_sign_PUBLICKEYBYTES,
crypto_sign_SECRETKEYBYTES, crypto_sign_SECRETKEYBYTES,
crypto_sign_SEEDBYTES 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) { function set25519 (r, a) {
var i; for (let i = 0; i < 16; i++) r[i] = a[i] | 0
for (i = 0; i < 16; i++) r[i] = a[i]|0;
} }
function pow2523(o, i) { function pow2523 (o, i) {
var c = gf(); var c = gf()
var a; var a
for (a = 0; a < 16; a++) c[a] = i[a]; for (a = 0; a < 16; a++) c[a] = i[a]
for (a = 250; a >= 0; a--) { for (a = 250; a >= 0; a--) {
S(c, c); S(c, c)
if(a !== 1) M(c, c, i); 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(), var a = gf(), b = gf(), c = gf(),
d = gf(), e = gf(), f = gf(), d = gf(), e = gf(), f = gf(),
g = gf(), h = gf(), t = gf(); g = gf(), h = gf(), t = gf()
Z(a, p[1], p[0]); Z(a, p[1], p[0])
Z(t, q[1], q[0]); Z(t, q[1], q[0])
M(a, a, t); M(a, a, t)
A(b, p[0], p[1]); A(b, p[0], p[1])
A(t, q[0], q[1]); A(t, q[0], q[1])
M(b, b, t); M(b, b, t)
M(c, p[3], q[3]); M(c, p[3], q[3])
M(c, c, D2); M(c, c, D2)
M(d, p[2], q[2]); M(d, p[2], q[2])
A(d, d, d); A(d, d, d)
Z(e, b, a); Z(e, b, a)
Z(f, d, c); Z(f, d, c)
A(g, d, c); A(g, d, c)
A(h, b, a); A(h, b, a)
M(p[0], e, f); M(p[0], e, f)
M(p[1], h, g); M(p[1], h, g)
M(p[2], g, f); M(p[2], g, f)
M(p[3], e, h); M(p[3], e, h)
} }
function cswap(p, q, b) { function cswap (p, q, b) {
var i; var i
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
sel25519(p[i], q[i], b); sel25519(p[i], q[i], b)
} }
} }
function pack(r, p) { function pack (r, p) {
var tx = gf(), ty = gf(), zi = gf(); var tx = gf(), ty = gf(), zi = gf()
inv25519(zi, p[2]); inv25519(zi, p[2])
M(tx, p[0], zi); M(tx, p[0], zi)
M(ty, p[1], zi); M(ty, p[1], zi)
pack25519(r, ty); pack25519(r, ty)
r[31] ^= par25519(tx) << 7; r[31] ^= par25519(tx) << 7
} }
function scalarmult(p, q, s) { function scalarmult (p, q, s) {
var b, i; // don't mutate q
set25519(p[0], gf0); var h = [gf(q[0]), gf(q[1]), gf(q[2]), gf(q[3])]
set25519(p[1], gf1); var b, i
set25519(p[2], gf1); set25519(p[0], gf0)
set25519(p[3], gf0); set25519(p[1], gf1)
set25519(p[2], gf1)
set25519(p[3], gf0)
for (i = 255; i >= 0; --i) { for (i = 255; i >= 0; --i) {
b = (s[(i/8)|0] >> (i&7)) & 1; b = (s[(i / 8) | 0] >> (i & 7)) & 1
cswap(p, q, b); cswap(p, h, b)
add(q, p); add(h, p)
add(p, p); add(p, p)
cswap(p, q, b); cswap(p, h, b)
} }
} }
function scalarbase(p, s) { function scalarbase (p, s) {
var q = [gf(), gf(), gf(), gf()]; var q = [gf(), gf(), gf(), gf()]
set25519(q[0], X); set25519(q[0], X)
set25519(q[1], Y); set25519(q[1], Y)
set25519(q[2], gf1); set25519(q[2], gf1)
M(q[3], X, Y); M(q[3], X, Y)
scalarmult(p, q, s); scalarmult(p, q, s)
} }
function crypto_sign_keypair(pk, sk, seeded) { function crypto_sign_keypair (pk, sk, seeded) {
check(pk, crypto_sign_PUBLICKEYBYTES) check(pk, crypto_sign_PUBLICKEYBYTES)
check(sk, crypto_sign_SECRETKEYBYTES) check(sk, crypto_sign_SECRETKEYBYTES)
var d = new Uint8Array(64); var d = new Uint8Array(64)
var p = [gf(), gf(), gf(), gf()]; var p = [gf(), gf(), gf(), gf()]
var i; var i
if (!seeded) randombytes(sk, 32); if (!seeded) randombytes(sk, 32)
crypto_hash(d, sk, 32); crypto_hash(d, sk, 32)
d[0] &= 248; d[0] &= 248
d[31] &= 127; d[31] &= 127
d[31] |= 64; d[31] |= 64
scalarbase(p, d); scalarbase(p, d)
pack(pk, p); pack(pk, p)
for (i = 0; i < 32; i++) sk[i+32] = pk[i]; for (i = 0; i < 32; i++) sk[i + 32] = pk[i]
return 0;
} }
function crypto_sign_seed_keypair (pk, sk, seed) { function crypto_sign_seed_keypair (pk, sk, seed) {
@@ -135,162 +153,167 @@ function crypto_sign_seed_keypair (pk, sk, seed) {
return crypto_sign_keypair(pk, sk, true) 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) { function modL (r, x) {
var carry, i, j, k; var carry, i, j, k
for (i = 63; i >= 32; --i) { for (i = 63; i >= 32; --i) {
carry = 0; carry = 0
for (j = i - 32, k = i - 12; j < k; ++j) { for (j = i - 32, k = i - 12; j < k; ++j) {
x[j] += carry - 16 * x[i] * L[j - (i - 32)]; x[j] += carry - 16 * x[i] * L[j - (i - 32)]
carry = (x[j] + 128) >> 8; carry = (x[j] + 128) >> 8
x[j] -= carry * 256; x[j] -= carry * 256
} }
x[j] += carry; x[j] += carry
x[i] = 0; x[i] = 0
} }
carry = 0; carry = 0
for (j = 0; j < 32; j++) { for (j = 0; j < 32; j++) {
x[j] += carry - (x[31] >> 4) * L[j]; x[j] += carry - (x[31] >> 4) * L[j]
carry = x[j] >> 8; carry = x[j] >> 8
x[j] &= 255; 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++) { for (i = 0; i < 32; i++) {
x[i+1] += x[i] >> 8; x[i + 1] += x[i] >> 8
r[i] = x[i] & 255; r[i] = x[i] & 255
} }
} }
function reduce(r) { function reduce (r) {
var x = new Float64Array(64), i; var x = new Float64Array(64)
for (i = 0; i < 64; i++) x[i] = r[i]; for (let i = 0; i < 64; i++) x[i] = r[i]
for (i = 0; i < 64; i++) r[i] = 0; for (let i = 0; i < 64; i++) r[i] = 0
modL(r, x); modL(r, x)
} }
// Note: difference from C - smlen returned, not passed as argument. // 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(sm, crypto_sign_BYTES + m.length)
check(m, 0) check(m, 0)
check(sk, crypto_sign_SECRETKEYBYTES) check(sk, crypto_sign_SECRETKEYBYTES)
var n = m.length var n = m.length
var d = new Uint8Array(64), h = new Uint8Array(64), r = new Uint8Array(64); var d = new Uint8Array(64), h = new Uint8Array(64), r = new Uint8Array(64)
var i, j, x = new Float64Array(64); var i, j, x = new Float64Array(64)
var p = [gf(), gf(), gf(), gf()]; var p = [gf(), gf(), gf(), gf()]
crypto_hash(d, sk, 32); crypto_hash(d, sk, 32)
d[0] &= 248; d[0] &= 248
d[31] &= 127; d[31] &= 127
d[31] |= 64; d[31] |= 64
var smlen = n + 64; var smlen = n + 64
for (i = 0; i < n; i++) sm[64 + i] = m[i]; for (i = 0; i < n; i++) sm[64 + i] = m[i]
for (i = 0; i < 32; i++) sm[32 + i] = d[32 + i]; for (i = 0; i < 32; i++) sm[32 + i] = d[32 + i]
crypto_hash(r, sm.subarray(32), n+32); crypto_hash(r, sm.subarray(32), n + 32)
reduce(r); reduce(r)
scalarbase(p, r); scalarbase(p, r)
pack(sm, p); pack(sm, p)
for (i = 32; i < 64; i++) sm[i] = sk[i]; for (i = 32; i < 64; i++) sm[i] = sk[i]
crypto_hash(h, sm, n + 64); crypto_hash(h, sm, n + 64)
reduce(h); reduce(h)
for (i = 0; i < 64; i++) x[i] = 0; 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++) x[i] = r[i]
for (i = 0; i < 32; i++) { for (i = 0; i < 32; i++) {
for (j = 0; j < 32; j++) { 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 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) var sm = new Uint8Array(m.length + crypto_sign_BYTES)
crypto_sign(sm, m, sk) 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(), var t = gf(), chk = gf(), num = gf(),
den = gf(), den2 = gf(), den4 = gf(), den = gf(), den2 = gf(), den4 = gf(),
den6 = gf(); den6 = gf()
set25519(r[2], gf1); set25519(r[2], gf1)
unpack25519(r[1], p); unpack25519(r[1], p)
S(num, r[1]); S(num, r[1])
M(den, num, D); M(den, num, D)
Z(num, num, r[2]); Z(num, num, r[2])
A(den, r[2], den); A(den, r[2], den)
S(den2, den); S(den2, den)
S(den4, den2); S(den4, den2)
M(den6, den4, den2); M(den6, den4, den2)
M(t, den6, num); M(t, den6, num)
M(t, t, den); M(t, t, den)
pow2523(t, t); pow2523(t, t)
M(t, t, num); M(t, t, num)
M(t, t, den); M(t, t, den)
M(t, t, den); M(t, t, den)
M(r[0], t, den); M(r[0], t, den)
S(chk, r[0]); S(chk, r[0])
M(chk, chk, den); M(chk, chk, den)
if (neq25519(chk, num)) M(r[0], r[0], I); if (!neq25519(chk, num)) M(r[0], r[0], I)
S(chk, r[0]); S(chk, r[0])
M(chk, chk, den); M(chk, chk, den)
if (neq25519(chk, num)) return -1; if (!neq25519(chk, num)) return false
if (par25519(r[0]) === (p[31]>>7)) Z(r[0], gf0, r[0]); if (par25519(r[0]) === (p[31] >> 7)) {
Z(r[0], gf(), r[0])
}
M(r[3], r[0], r[1]); M(r[3], r[0], r[1])
return 0; return true
} }
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(msg, sm.length - crypto_sign_BYTES)
check(sm, crypto_sign_BYTES) check(sm, crypto_sign_BYTES)
check(pk, crypto_sign_PUBLICKEYBYTES) check(pk, crypto_sign_PUBLICKEYBYTES)
var n = sm.length var n = sm.length
var m = new Uint8Array(sm.length) var m = new Uint8Array(sm.length)
var i, mlen; var i, mlen
var t = new Uint8Array(32), h = new Uint8Array(64); var t = new Uint8Array(32), h = new Uint8Array(64)
var p = [gf(), gf(), gf(), gf()], var p = [gf(), gf(), gf(), gf()],
q = [gf(), gf(), gf(), gf()]; q = [gf(), gf(), gf(), gf()]
mlen = -1; mlen = -1
if (n < 64) return false; 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 < n; i++) m[i] = sm[i]
for (i = 0; i < 32; i++) m[i+32] = pk[i]; for (i = 0; i < 32; i++) m[i + 32] = pk[i]
crypto_hash(h, m, n); crypto_hash(h, m, n)
reduce(h); reduce(h)
scalarmult(p, q, h); scalarmult(p, q, h)
scalarbase(q, sm.subarray(32)); scalarbase(q, sm.subarray(32))
add(p, q); add(p, q)
pack(t, p); pack(t, p)
n -= 64; n -= 64
if (crypto_verify_32(sm, 0, t, 0)) { if (!crypto_verify_32(sm, 0, t, 0)) {
for (i = 0; i < n; i++) m[i] = 0; for (i = 0; i < n; i++) m[i] = 0
return false; return false
// throw new Error('crypto_sign_open failed')
} }
for (i = 0; i < n; i++) msg[i] = sm[i + 64]; for (i = 0; i < n; i++) msg[i] = sm[i + 64]
mlen = n; mlen = n
return true; return true
} }
/* eslint-enable no-unused-vars */
function crypto_sign_verify_detached (sig, m, pk) { function crypto_sign_verify_detached (sig, m, pk) {
check(sig, crypto_sign_BYTES) check(sig, crypto_sign_BYTES)
@@ -301,19 +324,146 @@ function crypto_sign_verify_detached (sig, m, pk) {
return crypto_sign_open(m, sm, pk) return crypto_sign_open(m, sm, pk)
} }
function par25519(a) { function par25519 (a) {
var d = new Uint8Array(32); var d = new Uint8Array(32)
pack25519(d, a); pack25519(d, a)
return d[0] & 1; return d[0] & 1
} }
function neq25519(a, b) { function neq25519 (a, b) {
var c = new Uint8Array(32), d = new Uint8Array(32); var c = new Uint8Array(32), d = new Uint8Array(32)
pack25519(c, a); pack25519(c, a)
pack25519(d, b); pack25519(d, b)
return crypto_verify_32(c, 0, d, 0); return crypto_verify_32(c, 0, d, 0)
} }
function check (buf, len) { function ed25519_mul_l (p, q) {
if (!buf || (len && buf.length < len)) throw new Error('Argument must be a buffer' + (len ? ' of length ' + len : '')) 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 = new Uint8Array(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 : ''))
} }
+4 -2
View File
@@ -1,10 +1,12 @@
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.') if (new Uint16Array([1])[0] !== 1) throw new Error('Big endian architecture is not supported.')
exports.crypto_stream_KEYBYTES = 32 exports.crypto_stream_KEYBYTES = 32
exports.crypto_stream_NONCEBYTES = 24 exports.crypto_stream_NONCEBYTES = 24
exports.crypto_stream_PRIMITIVE = 'xsalsa20' exports.crypto_stream_PRIMITIVE = 'xsalsa20'
exports.crypto_stream_xsalsa20_MESSAGEBYTES_MAX = Number.MAX_SAFE_INTEGER
exports.crypto_stream = function (c, nonce, key) { exports.crypto_stream = function (c, nonce, key) {
c.fill(0) c.fill(0)
@@ -12,7 +14,7 @@ exports.crypto_stream = function (c, nonce, key) {
} }
exports.crypto_stream_xor = function (c, m, 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.update(m, c)
xor.final() xor.final()
+15 -20
View File
@@ -1,34 +1,29 @@
const assert = require('nanoassert') /* eslint-disable camelcase */
module.exports = { module.exports = {
crypto_verify_16, crypto_verify_16,
crypto_verify_32, crypto_verify_32,
sodium_memcmp, crypto_verify_64
sodium_is_zero
} }
function vn (x, xi, y, yi, n) { function vn (x, xi, y, yi, n) {
var i, d = 0 var d = 0
for (i = 0; i < n; i++) d |= x[xi + i] ^ y[yi + i] for (let i = 0; i < n; i++) d |= x[xi + i] ^ y[yi + i]
return (1 & ((d - 1) >>> 8)) - 1 return (1 & ((d - 1) >>> 8)) - 1
} }
function crypto_verify_16(x, xi, y, yi) { // Make non enumerable as this is an internal function
return vn(x, xi, y, yi, 16) 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) { function crypto_verify_32 (x, xi, y, yi) {
return vn(x, xi, y, yi, 32) return vn(x, xi, y, yi, 32) === 0
} }
function sodium_memcmp (a, b) { function crypto_verify_64 (x, xi, y, yi) {
assert(a.byteLength === b.byteLength, 'buffers must be the same size') return vn(x, xi, y, yi, 64) === 0
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
} }
+6 -6
View File
@@ -1,19 +1,19 @@
var sodium = require('./') const sodium = require('./')
var key = new Buffer(sodium.crypto_secretbox_KEYBYTES) const key = Buffer.alloc(sodium.crypto_secretbox_KEYBYTES)
var nonce = new Buffer(sodium.crypto_secretbox_NONCEBYTES) const nonce = Buffer.alloc(sodium.crypto_secretbox_NONCEBYTES)
sodium.randombytes_buf(key) sodium.randombytes_buf(key)
sodium.randombytes_buf(nonce) sodium.randombytes_buf(nonce)
var message = new Buffer('Hello, World!') const message = Buffer.from('Hello, World!')
var cipher = new Buffer(message.length + sodium.crypto_secretbox_MACBYTES) const cipher = Buffer.alloc(message.length + sodium.crypto_secretbox_MACBYTES)
sodium.crypto_secretbox_easy(cipher, message, nonce, key) sodium.crypto_secretbox_easy(cipher, message, nonce, key)
console.log('Encrypted:', cipher) 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) 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. // 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. // Ported in 2014 by Dmitry Chestnykh and Devi Mandiri.
// Public domain. // Public domain.
// //
// Implementation derived from TweetNaCl version 20140427. // Implementation derived from TweetNaCl version 20140427.
// See for details: http://tweetnacl.cr.yp.to/ // See for details: http://tweetnacl.cr.yp.to/
// also forwarded at the bottom but randombytes is non-enumerable forward(require('./randombytes'))
forward(require('./memory'))
sodium.sodium_memzero = function (arr) { forward(require('./helpers'))
arr.fill(0) forward(require('./crypto_verify'))
} forward(require('./crypto_auth'))
sodium.sodium_malloc = function (n) {
return new Uint8Array(n)
}
forward(require('./crypto_box')) forward(require('./crypto_box'))
forward(require('./crypto_generichash')) forward(require('./crypto_generichash'))
forward(require('./crypto_hash')) forward(require('./crypto_hash'))
@@ -34,8 +27,6 @@ forward(require('./crypto_shorthash'))
forward(require('./crypto_sign')) forward(require('./crypto_sign'))
forward(require('./crypto_stream')) forward(require('./crypto_stream'))
forward(require('./crypto_stream_chacha20')) forward(require('./crypto_stream_chacha20'))
forward(require('./crypto_verify'))
forward(require('./randombytes'))
function forward (submodule) { function forward (submodule) {
Object.keys(submodule).forEach(function (prop) { Object.keys(submodule).forEach(function (prop) {
View File
+30
View File
@@ -0,0 +1,30 @@
/* eslint-disable camelcase */
function sodium_malloc (n) {
return new Uint8Array(n)
}
function sodium_free (n) {
sodium_memzero(n)
loadSink().port1.postMessage(n.buffer, [n.buffer])
}
function sodium_memzero (arr) {
arr.fill(0)
}
var sink
function loadSink () {
if (sink) return sink
var MessageChannel = globalThis.MessageChannel
if (MessageChannel == null) ({ MessageChannel } = require('worker' + '_threads'))
sink = new MessageChannel()
return sink
}
module.exports = {
sodium_malloc,
sodium_free,
sodium_memzero
}
+26 -18
View File
@@ -1,41 +1,49 @@
{ {
"name": "sodium-javascript", "name": "sodium-javascript",
"version": "0.6.0", "version": "0.7.4",
"description": "WIP - a pure javascript version of sodium-native", "description": "WIP - a pure javascript version of sodium-native",
"main": "index.js", "main": "index.js",
"dependencies": { "dependencies": {
"blake2b": "^2.1.1", "blake2b": "^2.1.1",
"chacha20-universal": "^1.0.4", "chacha20-universal": "^1.0.4",
"nanoassert": "^1.0.0", "nanoassert": "^2.0.0",
"sha256-wasm": "^1.3.0", "sha256-universal": "^1.1.0",
"sha512-wasm": "^1.2.0", "sha512-universal": "^1.1.0",
"siphash24": "^1.0.1", "siphash24": "^1.0.1",
"xsalsa20": "^1.0.0" "xsalsa20": "^1.0.0"
}, },
"devDependencies": { "devDependencies": {
"browser-run": "^4.0.2", "browserify": "^16.5.1",
"browserify": "^14.1.0", "sodium-test": "^0.10.0",
"sodium-test": "^0.9.0" "standard": "^15.0.1",
"tape-run": "^7.0.0"
},
"standard": {
"ignore": [
"/internal/**/*.js"
]
}, },
"browser": { "browser": {
"crypto": false "crypto": false,
}, "worker_threads": false
"react-native": {
"crypto": "crypto"
}, },
"scripts": { "scripts": {
"browser": "browserify test.js | browser-run", "pretest": "standard",
"browser-manual": "browserify test.js | browser-run -p 1234", "test": "node test.js",
"test": "node test.js" "test-browser": "browserify test.js | tape-run"
}, },
"repository": { "repository": {
"type": "git", "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", "license": "MIT",
"bugs": { "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 assert = require('nanoassert')
var randombytes = (function () { var randombytes = (function () {
var QUOTA = 65536 // limit for QuotaExceededException var QUOTA = 65536 // limit for QuotaExceededException
var crypto = typeof global !== 'undefined' ? crypto = (global.crypto || global.msCrypto) : null var crypto = globalThis.crypto || globalThis.msCrypto
function browserBytes (out, n) { function browserBytes (out, n) {
for (var i = 0; i < n; i += QUOTA) { for (let i = 0; i < n; i += QUOTA) {
crypto.getRandomValues(out.subarray(i, i + Math.min(n - i, QUOTA))) crypto.getRandomValues(new Uint8Array(out.buffer, i + out.byteOffset, Math.min(n - i, QUOTA)))
} }
} }
function nodeBytes (out, n) { function nodeBytes (out, n) {
out.set(crypto.randomBytes(n)) new Uint8Array(out.buffer, out.byteOffset, n).set(crypto.randomBytes(n))
} }
function noImpl () { function noImpl () {
throw new Error('No secure random number generator available') throw new Error('No secure random number generator available')
} }
if (crypto && crypto.getRandomValues) { if (crypto && crypto.getRandomValues) return browserBytes
return browserBytes
} else if (typeof require !== 'undefined') { if (require != null) {
// Node.js. // Node.js. Bust Browserify
crypto = require('crypto') crypto = require('cry' + 'pto')
if (crypto && crypto.randomBytes) { if (crypto && crypto.randomBytes) return nodeBytes
return nodeBytes
}
} }
return noImpl return noImpl
})() })()
// Make non enumerable as this is an internal function
Object.defineProperty(module.exports, 'randombytes', { Object.defineProperty(module.exports, 'randombytes', {
value: randombytes value: randombytes
}) })
module.exports.randombytes_buf = function (out) { module.exports.randombytes_buf = function (out) {
assert(out, 'out must be given') assert(out, 'out must be given')
randombytes(out, out.length) randombytes(out, out.byteLength)
} }
+1 -1
View File
@@ -1,3 +1,3 @@
require('sodium-test')(require('.')) require('sodium-test')(require('.'))
if (typeof window !== 'undefined') window.close() if ((typeof window !== 'undefined') && window.close) window.close()