Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0227f45c6b | ||
|
|
ca32540960 | ||
|
|
51093efbc5 | ||
|
|
f79aed4eee | ||
|
|
3eb1d64460 | ||
|
|
7febc97986 | ||
|
|
66494ec3b5 | ||
|
|
35f38a6c10 | ||
|
|
125384f26a | ||
|
|
d432fe295d | ||
|
|
97200f90da | ||
|
|
656d6d251e | ||
|
|
61b6e6916a | ||
|
|
ab004d8022 | ||
|
|
ce5ac41ecd | ||
|
|
a82160d51b | ||
|
|
a546f3e51d | ||
|
|
a338ae9f9d | ||
|
|
e4693065fd | ||
|
|
44e5985630 | ||
|
|
f11ff5a727 | ||
|
|
9c30d3ead8 | ||
|
|
ddcdae69a1 | ||
|
|
80dd633012 | ||
|
|
d8d59d0443 | ||
|
|
ef00ddc878 | ||
|
|
cc52e58504 | ||
|
|
7b518f7b2c | ||
|
|
74a1067746 | ||
|
|
919896d2bb | ||
|
|
f3a80cb6f5 | ||
|
|
40f9b887f4 | ||
|
|
2ca6264f50 | ||
|
|
9d65d19e86 | ||
|
|
30c3342156 | ||
|
|
930e77ad32 | ||
|
|
e9ac929b5a | ||
|
|
e77c70ef71 | ||
|
|
4bb40aa43d | ||
|
|
fc90cbedba | ||
|
|
63fb70028e | ||
|
|
f033af88bd | ||
|
|
b44f83f0a8 | ||
|
|
51f8fbc2d3 | ||
|
|
f790621e60 | ||
|
|
4e42b942a5 | ||
|
|
49587c3d7f | ||
|
|
92aee452df | ||
|
|
e1ca83f1bd | ||
|
|
c81ef709d1 | ||
|
|
4e1c69ba13 | ||
|
|
5159d68fa9 | ||
|
|
5ccdcdee17 | ||
|
|
48081c6896 | ||
|
|
b1741bfdae | ||
|
|
f7de366eec | ||
|
|
51e11143e5 | ||
|
|
b883b2a8df | ||
|
|
f336097b6a | ||
|
|
5511bafdba | ||
|
|
212550db1b | ||
|
|
384ec2f636 | ||
|
|
07e1bc4ed6 | ||
|
|
6561ff99f1 | ||
|
|
0f249a7e8f | ||
|
|
fa6f2a836c | ||
|
|
2bae0d19af | ||
|
|
75bad77847 | ||
|
|
49feb73134 | ||
|
|
642a68c2a1 | ||
|
|
abedfa6362 | ||
|
|
de8639f558 | ||
|
|
33befeb87a | ||
|
|
a22454f86f | ||
|
|
d546f63e11 | ||
|
|
78f7c7111c | ||
|
|
51875f2288 | ||
|
|
95732bdd4f | ||
|
|
1967024766 | ||
|
|
776ffea91c |
+18
@@ -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
|
||||
@@ -1,31 +1,29 @@
|
||||
# sodium-javascript
|
||||
# `sodium-javascript`
|
||||
|
||||
WIP - a pure javascript version of [sodium-native](https://github.com/mafintosh/sodium-native).
|
||||
[](https://travis-ci.org/sodium-friends/sodium-javascript)
|
||||
|
||||
> WIP - a pure javascript version of [sodium-native](https://github.com/sodium-friends/sodium-native).
|
||||
Based on tweetnacl
|
||||
|
||||
```
|
||||
npm install sodium-javascript
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
``` js
|
||||
var sodium = require('sodium-javascript')
|
||||
const sodium = require('sodium-javascript')
|
||||
|
||||
var key = new Buffer(sodium.crypto_secretbox_KEYBYTES)
|
||||
var nonce = new Buffer(sodium.crypto_secretbox_NONCEBYTES)
|
||||
const key = Buffer.alloc(sodium.crypto_secretbox_KEYBYTES)
|
||||
const nonce = Buffer.alloc(sodium.crypto_secretbox_NONCEBYTES)
|
||||
|
||||
sodium.randombytes_buf(key)
|
||||
sodium.randombytes_buf(nonce)
|
||||
|
||||
var message = new Buffer('Hello, World!')
|
||||
var cipher = new Buffer(message.length + sodium.crypto_secretbox_MACBYTES)
|
||||
const message = Buffer.from('Hello, World!')
|
||||
const cipher = Buffer.alloc(message.length + sodium.crypto_secretbox_MACBYTES)
|
||||
|
||||
sodium.crypto_secretbox_easy(cipher, message, nonce, key)
|
||||
|
||||
console.log('Encrypted:', cipher)
|
||||
|
||||
var plainText = new Buffer(cipher.length - sodium.crypto_secretbox_MACBYTES)
|
||||
const plainText = Buffer.alloc(cipher.length - sodium.crypto_secretbox_MACBYTES)
|
||||
|
||||
sodium.crypto_secretbox_open_easy(plainText, cipher, nonce, key)
|
||||
|
||||
@@ -34,9 +32,20 @@ console.log('Plaintext:', plainText.toString())
|
||||
|
||||
## API
|
||||
|
||||
See [sodium-native](https://github.com/mafintosh/sodium-native).
|
||||
This is a work in progress so all functions are not implemented yet.
|
||||
See [sodium-native](https://github.com/sodium-friends/sodium-native).
|
||||
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
|
||||
|
||||
MIT
|
||||
[MIT](LICENSE)
|
||||
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
/* 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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
+200
@@ -0,0 +1,200 @@
|
||||
/* 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
|
||||
}
|
||||
+13
-4
@@ -1,6 +1,7 @@
|
||||
var assert = require('assert')
|
||||
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
|
||||
@@ -8,13 +9,17 @@ module.exports.crypto_generichash_BYTES = blake2b.BYTES
|
||||
module.exports.crypto_generichash_KEYBYTES_MIN = blake2b.KEYBYTES_MIN
|
||||
module.exports.crypto_generichash_KEYBYTES_MAX = blake2b.KEYBYTES_MAX
|
||||
module.exports.crypto_generichash_KEYBYTES = blake2b.KEYBYTES
|
||||
module.exports.crypto_generichash_WASM_SUPPORTED = blake2b.WASM_SUPPORTED
|
||||
module.exports.crypto_generichash_WASM_LOADED = false
|
||||
|
||||
module.exports.crypto_generichash = function (output, input, key) {
|
||||
blake2b(output, input, key)
|
||||
blake2b(output.length, key).update(input).final(output)
|
||||
}
|
||||
|
||||
module.exports.crypto_generichash_ready = blake2b.ready
|
||||
|
||||
module.exports.crypto_generichash_batch = function (output, inputArray, key) {
|
||||
var ctx = blake2b.instance(output.length, key)
|
||||
var ctx = blake2b(output.length, key)
|
||||
for (var i = 0; i < inputArray.length; i++) {
|
||||
ctx.update(inputArray[i])
|
||||
}
|
||||
@@ -23,5 +28,9 @@ module.exports.crypto_generichash_batch = function (output, inputArray, key) {
|
||||
|
||||
module.exports.crypto_generichash_instance = function (key, outlen) {
|
||||
if (outlen == null) outlen = module.exports.crypto_generichash_BYTES
|
||||
return blake2b.instance(outlen, key)
|
||||
return blake2b(outlen, key)
|
||||
}
|
||||
|
||||
blake2b.ready(function (_) {
|
||||
module.exports.crypto_generichash_WASM_LOADED = blake2b.WASM_LOADED
|
||||
})
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/* 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
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/* 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
|
||||
}
|
||||
+14
-11
@@ -1,14 +1,15 @@
|
||||
var assert = require('assert')
|
||||
var randombytes_buf = require('.').randombytes_buf
|
||||
var blake2b = require('blake2b')
|
||||
/* eslint-disable camelcase */
|
||||
const assert = require('nanoassert')
|
||||
const randombytes_buf = require('./randombytes').randombytes_buf
|
||||
const blake2b = require('blake2b')
|
||||
|
||||
module.exports.crypto_kdf_PRIMITIVE = 'blake2b'
|
||||
module.exports.crypto_kdf_BYTES_MIN = 16
|
||||
module.exports.crypto_kdf_BYTES_MAX = 64
|
||||
module.exports.crypto_kdf_CONTEXTBYTES = 8
|
||||
module.exports.crypto_kdf_KEYBYTES = 64
|
||||
module.exports.crypto_kdf_KEYBYTES = 32
|
||||
|
||||
function STORE64_LE(dest, int) {
|
||||
function STORE64_LE (dest, int) {
|
||||
var mul = 1
|
||||
var i = 0
|
||||
dest[0] = int & 0xFF
|
||||
@@ -18,20 +19,22 @@ function STORE64_LE(dest, int) {
|
||||
}
|
||||
|
||||
module.exports.crypto_kdf_derive_from_key = function crypto_kdf_derive_from_key (subkey, subkey_id, ctx, key) {
|
||||
assert(subkey.length >= module.exports.crypto_kdf_BYTES_MIN, 'subkey must be')
|
||||
assert(ctx.length >= module.exports.crypto_kdf_CONTEXTBYTES, 'context must be')
|
||||
assert(subkey.length >= module.exports.crypto_kdf_BYTES_MIN, 'subkey must be at least crypto_kdf_BYTES_MIN')
|
||||
assert(subkey_id >= 0 && subkey_id <= 0x1fffffffffffff, 'subkey_id must be safe integer')
|
||||
assert(ctx.length >= module.exports.crypto_kdf_CONTEXTBYTES, 'context must be at least crypto_kdf_CONTEXTBYTES')
|
||||
|
||||
var ctx_padded = new Uint8Array(blake2b.PERSONALBYTES)
|
||||
var salt = new Uint8Array(blake2b.SALTBYTES)
|
||||
|
||||
ctx_padded.set(ctx, 0, module.exports.crypto_kdf_CONTEXTBYTES)
|
||||
|
||||
STORE64_LE(salt, subkey_id)
|
||||
|
||||
blake2b(subkey.slice(0, Math.min(subkey.length, module.exports.crypto_kdf_BYTES_MAX)), [], key, salt, ctx_padded, true)
|
||||
var outlen = Math.min(subkey.length, module.exports.crypto_kdf_BYTES_MAX)
|
||||
blake2b(outlen, key.subarray(0, module.exports.crypto_kdf_KEYBYTES), salt, ctx_padded, true)
|
||||
.final(subkey)
|
||||
}
|
||||
|
||||
module.exports.crypto_kdf_keygen = function crypto_kdf_keygen (out) {
|
||||
assert(out.length >= module.exports.crypto_kdf_KEYBYTES)
|
||||
randombytes_buf(out, module.exports.crypto_kdf_KEYBYTES)
|
||||
assert(out.length >= module.exports.crypto_kdf_KEYBYTES, 'out.length must be crypto_kdf_KEYBYTES')
|
||||
randombytes_buf(out.subarray(0, module.exports.crypto_kdf_KEYBYTES))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/* 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')
|
||||
|
||||
const crypto_kx_SEEDBYTES = 32
|
||||
const crypto_kx_PUBLICKEYBYTES = 32
|
||||
const crypto_kx_SECRETKEYBYTES = 32
|
||||
|
||||
function crypto_kx_keypair (pk, sk) {
|
||||
assert(pk.byteLength === crypto_kx_PUBLICKEYBYTES, "pk must be 'crypto_kx_PUBLICKEYBYTES' bytes")
|
||||
assert(sk.byteLength === crypto_kx_SECRETKEYBYTES, "sk must be 'crypto_kx_SECRETKEYBYTES' bytes")
|
||||
|
||||
randombytes_buf(sk, crypto_kx_SECRETKEYBYTES)
|
||||
return crypto_scalarmult_base(pk, sk)
|
||||
}
|
||||
|
||||
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")
|
||||
|
||||
crypto_generichash(sk, seed)
|
||||
return crypto_scalarmult_base(pk, sk)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
crypto_kx_keypair,
|
||||
crypto_kx_seed_keypair,
|
||||
crypto_kx_SEEDBYTES,
|
||||
crypto_kx_SECRETKEYBYTES,
|
||||
crypto_kx_PUBLICKEYBYTES
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/* 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)
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/* 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 : ''))
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/* 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
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
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 = shorthash
|
||||
|
||||
function shorthash (out, data, key, noAssert) {
|
||||
siphash(data, key, out, noAssert)
|
||||
}
|
||||
+469
@@ -0,0 +1,469 @@
|
||||
/* 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 : ''))
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/* eslint-disable camelcase */
|
||||
const xsalsa20 = require('xsalsa20')
|
||||
|
||||
if (new Uint16Array([1])[0] !== 1) throw new Error('Big endian architecture is not supported.')
|
||||
|
||||
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_xor = function (c, m, nonce, key) {
|
||||
const xor = xsalsa20(nonce, key)
|
||||
|
||||
xor.update(m, c)
|
||||
xor.final()
|
||||
}
|
||||
|
||||
exports.crypto_stream_xor_instance = function (nonce, key) {
|
||||
return new XOR(nonce, key)
|
||||
}
|
||||
|
||||
function XOR (nonce, key) {
|
||||
this._instance = xsalsa20(nonce, key)
|
||||
}
|
||||
|
||||
XOR.prototype.update = function (out, inp) {
|
||||
this._instance.update(inp, out)
|
||||
}
|
||||
|
||||
XOR.prototype.final = function () {
|
||||
this._instance.finalize()
|
||||
this._instance = null
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
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)
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/* 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
|
||||
}
|
||||
+8
-6
@@ -1,20 +1,22 @@
|
||||
var sodium = require('./')
|
||||
const sodium = require('./')
|
||||
|
||||
var key = new Buffer(sodium.crypto_secretbox_KEYBYTES)
|
||||
var nonce = new Buffer(sodium.crypto_secretbox_NONCEBYTES)
|
||||
const key = Buffer.alloc(sodium.crypto_secretbox_KEYBYTES)
|
||||
const nonce = Buffer.alloc(sodium.crypto_secretbox_NONCEBYTES)
|
||||
|
||||
sodium.randombytes_buf(key)
|
||||
sodium.randombytes_buf(nonce)
|
||||
|
||||
var message = new Buffer('Hello, World!')
|
||||
var cipher = new Buffer(message.length + sodium.crypto_secretbox_MACBYTES)
|
||||
const message = Buffer.from('Hello, World!')
|
||||
const cipher = Buffer.alloc(message.length + sodium.crypto_secretbox_MACBYTES)
|
||||
|
||||
sodium.crypto_secretbox_easy(cipher, message, nonce, key)
|
||||
|
||||
console.log('Encrypted:', cipher)
|
||||
|
||||
var plainText = new Buffer(cipher.length - sodium.crypto_secretbox_MACBYTES)
|
||||
const plainText = Buffer.alloc(cipher.length - sodium.crypto_secretbox_MACBYTES)
|
||||
|
||||
sodium.crypto_secretbox_open_easy(plainText, cipher, nonce, key)
|
||||
|
||||
console.log('Plaintext:', plainText.toString())
|
||||
|
||||
if (typeof window !== 'undefined') window.close()
|
||||
|
||||
+31
@@ -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
|
||||
}
|
||||
@@ -0,0 +1,483 @@
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,360 @@
|
||||
/*
|
||||
* 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
|
||||
@@ -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 = global.MessageChannel
|
||||
if (MessageChannel == null) ({ MessageChannel } = require('worker' + '_threads'))
|
||||
sink = new MessageChannel()
|
||||
return sink
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
sodium_malloc,
|
||||
sodium_free,
|
||||
sodium_memzero
|
||||
}
|
||||
+37
-7
@@ -1,22 +1,52 @@
|
||||
{
|
||||
"name": "sodium-javascript",
|
||||
"version": "0.2.0",
|
||||
"version": "0.7.3",
|
||||
"description": "WIP - a pure javascript version of sodium-native",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"blake2b": "^1.2.0"
|
||||
"blake2b": "^2.1.1",
|
||||
"chacha20-universal": "^1.0.4",
|
||||
"nanoassert": "^2.0.0",
|
||||
"sha256-universal": "^1.1.0",
|
||||
"sha512-universal": "^1.1.0",
|
||||
"siphash24": "^1.0.1",
|
||||
"xsalsa20": "^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"sodium-test": "^0.3.0"
|
||||
"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,
|
||||
"worker_threads": false
|
||||
},
|
||||
"react-native": {
|
||||
"crypto": "crypto"
|
||||
},
|
||||
"scripts": {
|
||||
"pretest": "standard",
|
||||
"test": "node test.js",
|
||||
"test-browser": "browserify test.js | tape-run"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/mafintosh/sodium-javascript.git"
|
||||
"url": "git+https://github.com/sodium-friends/sodium-javascript.git"
|
||||
},
|
||||
"author": "Mathias Buus (@mafintosh)",
|
||||
"contributors": [
|
||||
"Christophe Diederichs <chm-diederichs@hyperdivision.dk>",
|
||||
"Emil Bay <github@tixz.dk> (http://bayes.dk)",
|
||||
"Mathias Buus <mathiasbuus@gmail.com> (https://mafinto.sh)"
|
||||
],
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/mafintosh/sodium-javascript/issues"
|
||||
"url": "https://github.com/sodium-friends/sodium-javascript/issues"
|
||||
},
|
||||
"homepage": "https://github.com/mafintosh/sodium-javascript"
|
||||
"homepage": "https://github.com/sodium-friends/sodium-javascript#readme"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
var assert = require('nanoassert')
|
||||
|
||||
var randombytes = (function () {
|
||||
var QUOTA = 65536 // limit for QuotaExceededException
|
||||
var crypto = global.crypto || global.msCrypto
|
||||
|
||||
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)))
|
||||
}
|
||||
}
|
||||
|
||||
function nodeBytes (out, n) {
|
||||
new Uint8Array(out.buffer, out.byteOffset, n).set(crypto.randomBytes(n))
|
||||
}
|
||||
|
||||
function noImpl () {
|
||||
throw new Error('No secure random number generator available')
|
||||
}
|
||||
|
||||
if (crypto && crypto.getRandomValues) return browserBytes
|
||||
|
||||
if (require != null) {
|
||||
// Node.js. Bust Browserify
|
||||
crypto = require('cry' + 'pto')
|
||||
if (crypto && crypto.randomBytes) return nodeBytes
|
||||
}
|
||||
|
||||
return noImpl
|
||||
})()
|
||||
|
||||
// Make non enumerable as this is an internal function
|
||||
Object.defineProperty(module.exports, 'randombytes', {
|
||||
value: randombytes
|
||||
})
|
||||
|
||||
module.exports.randombytes_buf = function (out) {
|
||||
assert(out, 'out must be given')
|
||||
randombytes(out, out.byteLength)
|
||||
}
|
||||
Reference in New Issue
Block a user