Compare commits
65
Commits
v0.2.0
...
crypto_auth
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0fba70b6fa | ||
|
|
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
|
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 all functions are not implemented yet.
|
||||||
|
|
||||||
|
This module is organised into individual submodules which can be required
|
||||||
|
independently for smaller bundles in the browser. To leverage automatic
|
||||||
|
switching between `sodium-javascript` and `sodium-native`, see
|
||||||
|
[`sodium-universal`](https://github.com/sodium-friends/sodium-universal).
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
```
|
||||||
|
npm install sodium-javascript
|
||||||
|
```
|
||||||
|
|
||||||
## License
|
## 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(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(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 !== 0) {
|
||||||
|
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,72 @@
|
|||||||
|
/* eslint-disable camelcase */
|
||||||
|
const { crypto_verify_32, crypto_verify_64 } = require('./crypto_verify')
|
||||||
|
const Sha256 = require('sha256-universal')
|
||||||
|
const Sha512 = require('sha512-universal')
|
||||||
|
const assert = require('nanoassert')
|
||||||
|
|
||||||
|
const crypto_auth_hmacsha256_BYTES = 32
|
||||||
|
const crypto_auth_hmacsha256_KEYBYTES = 32
|
||||||
|
const crypto_auth_hmacsha512_BYTES = 64
|
||||||
|
const crypto_auth_hmacsha512_KEYBYTES = 32
|
||||||
|
const crypto_auth_hmacsha512256_BYTES = 32
|
||||||
|
const crypto_auth_hmacsha512256_KEYBYTES = 32
|
||||||
|
|
||||||
|
function crypto_auth_hmacsha256 (out, input, k) {
|
||||||
|
assert(out.byteLength === crypto_auth_hmacsha256_BYTES, "out should be 'crypto_auth_hmacsha256_BYTES' in length")
|
||||||
|
|
||||||
|
const hmac = Sha256.HMAC(key)
|
||||||
|
hmac.update(input)
|
||||||
|
return hmac.digest(out)
|
||||||
|
}
|
||||||
|
|
||||||
|
function crypto_auth_hmacsha256_verify (h, input, k) {
|
||||||
|
const correct = Sha256.HMAC(k).update(input).digest()
|
||||||
|
|
||||||
|
return crypto_verify_32(h, 0, correct, 0) | sodium_memcmp(correct, h, 32)
|
||||||
|
}
|
||||||
|
|
||||||
|
function crypto_auth_hmacsha512 (out, input, k) {
|
||||||
|
assert(out.byteLength === crypto_auth_hmacsha512_BYTES, "out should be 'crypto_auth_hmacsha512_BYTES' in length")
|
||||||
|
|
||||||
|
const hmac = Sha512.HMAC(key)
|
||||||
|
hmac.update(input)
|
||||||
|
return hmac.digest(out)
|
||||||
|
}
|
||||||
|
|
||||||
|
function crypto_auth_hmacsha512_verify (h, input, k) {
|
||||||
|
const correct = Sha512.HMAC(k).update(input).digest()
|
||||||
|
|
||||||
|
return crypto_verify_64(h, 0, correct, 0) | sodium_memcmp(correct, h, 64)
|
||||||
|
}
|
||||||
|
|
||||||
|
function crypto_auth_hmacsha512256 (out, input, k) {
|
||||||
|
assert(out.byteLength === crypto_auth_hmacsha512_BYTES, "out should be 'crypto_auth_hmacsha512256_BYTES' in length")
|
||||||
|
|
||||||
|
const out0 = Buffer.alloc(64)
|
||||||
|
const hmac = Sha512.HMAC(key)
|
||||||
|
hmac.update(input)
|
||||||
|
hmac.digest(out)
|
||||||
|
|
||||||
|
out.set(out0.subarray(0, 32))
|
||||||
|
}
|
||||||
|
|
||||||
|
function crypto_auth_hmacsha512256_verify (h, input, k) {
|
||||||
|
const correct = Sha512.HMAC(k).update(input).digest()
|
||||||
|
|
||||||
|
return crypto_verify_32(h, 0, correct, 0) | sodium_memcmp(correct, h, 32)
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
crypto_auth_hmacsha256_BYTES,
|
||||||
|
crypto_auth_hmacsha256_KEYBYTES,
|
||||||
|
crypto_auth_hmacsha512_BYTES,
|
||||||
|
crypto_auth_hmacsha512_KEYBYTES,
|
||||||
|
crypto_auth_hmacsha512256_BYTES,
|
||||||
|
crypto_auth_hmacsha512256_KEYBYTES,
|
||||||
|
crypto_auth_hmacsha256,
|
||||||
|
crypto_auth_hmacsha256_verify,
|
||||||
|
crypto_auth_hmacsha512,
|
||||||
|
crypto_auth_hmacsha512_verify,
|
||||||
|
crypto_auth_hmacsha512256,
|
||||||
|
crypto_auth_hmacsha512256_verify
|
||||||
|
}
|
||||||
+104
@@ -0,0 +1,104 @@
|
|||||||
|
/* 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_secretbox_open_easy, crypto_secretbox_easy } = 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
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
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 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')
|
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_PRIMITIVE = 'blake2b'
|
||||||
module.exports.crypto_generichash_BYTES_MIN = blake2b.BYTES_MIN
|
module.exports.crypto_generichash_BYTES_MIN = blake2b.BYTES_MIN
|
||||||
module.exports.crypto_generichash_BYTES_MAX = blake2b.BYTES_MAX
|
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_MIN = blake2b.KEYBYTES_MIN
|
||||||
module.exports.crypto_generichash_KEYBYTES_MAX = blake2b.KEYBYTES_MAX
|
module.exports.crypto_generichash_KEYBYTES_MAX = blake2b.KEYBYTES_MAX
|
||||||
module.exports.crypto_generichash_KEYBYTES = blake2b.KEYBYTES
|
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) {
|
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) {
|
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++) {
|
for (var i = 0; i < inputArray.length; i++) {
|
||||||
ctx.update(inputArray[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) {
|
module.exports.crypto_generichash_instance = function (key, outlen) {
|
||||||
if (outlen == null) outlen = module.exports.crypto_generichash_BYTES
|
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')
|
/* eslint-disable camelcase */
|
||||||
var randombytes_buf = require('.').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
|
||||||
module.exports.crypto_kdf_BYTES_MAX = 64
|
module.exports.crypto_kdf_BYTES_MAX = 64
|
||||||
module.exports.crypto_kdf_CONTEXTBYTES = 8
|
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 mul = 1
|
||||||
var i = 0
|
var i = 0
|
||||||
dest[0] = int & 0xFF
|
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) {
|
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(subkey.length >= module.exports.crypto_kdf_BYTES_MIN, 'subkey must be at least crypto_kdf_BYTES_MIN')
|
||||||
assert(ctx.length >= module.exports.crypto_kdf_CONTEXTBYTES, 'context must be')
|
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 ctx_padded = new Uint8Array(blake2b.PERSONALBYTES)
|
||||||
var salt = new Uint8Array(blake2b.SALTBYTES)
|
var salt = new Uint8Array(blake2b.SALTBYTES)
|
||||||
|
|
||||||
ctx_padded.set(ctx, 0, module.exports.crypto_kdf_CONTEXTBYTES)
|
ctx_padded.set(ctx, 0, module.exports.crypto_kdf_CONTEXTBYTES)
|
||||||
|
|
||||||
STORE64_LE(salt, subkey_id)
|
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) {
|
module.exports.crypto_kdf_keygen = function crypto_kdf_keygen (out) {
|
||||||
assert(out.length >= module.exports.crypto_kdf_KEYBYTES)
|
assert(out.length >= module.exports.crypto_kdf_KEYBYTES, 'out.length must be crypto_kdf_KEYBYTES')
|
||||||
randombytes_buf(out, module.exports.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,37 @@
|
|||||||
|
/* 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)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
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,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,113 @@
|
|||||||
|
/* 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)
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
o.set(tmp.subarray(0, msg.byteLength))
|
||||||
|
mac.set(tmp.subarray(msg.byteLength))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
function crypto_secretbox_open_detached (msg, o, mac, n, k) {
|
||||||
|
assert(o.byteLength === msg.byteLength, "o must be 'msg.byteLength' bytes")
|
||||||
|
assert(mac.byteLength === crypto_secretbox_MACBYTES, "mac must be 'crypto_secretbox_MACBYTES' bytes")
|
||||||
|
assert(n.byteLength === crypto_secretbox_NONCEBYTES, "n must be 'crypto_secretbox_NONCEBYTES' bytes")
|
||||||
|
assert(k.byteLength === crypto_secretbox_KEYBYTES, "k must be 'crypto_secretbox_KEYBYTES' bytes")
|
||||||
|
|
||||||
|
const tmp = new Uint8Array(o.byteLength + mac.byteLength)
|
||||||
|
tmp.set(o)
|
||||||
|
tmp.set(mac, msg.byteLength)
|
||||||
|
return crypto_secretbox_open_easy(msg, tmp, n, k)
|
||||||
|
}
|
||||||
|
|
||||||
|
function crypto_secretbox_easy (o, msg, n, k) {
|
||||||
|
assert(o.byteLength === msg.byteLength + crypto_secretbox_MACBYTES, "o must be 'msg.byteLength + crypto_secretbox_MACBYTES' bytes")
|
||||||
|
assert(n.byteLength === crypto_secretbox_NONCEBYTES, "n must be 'crypto_secretbox_NONCEBYTES' bytes")
|
||||||
|
assert(k.byteLength === crypto_secretbox_KEYBYTES, "k must be 'crypto_secretbox_KEYBYTES' bytes")
|
||||||
|
|
||||||
|
const m = new Uint8Array(crypto_secretbox_ZEROBYTES + msg.byteLength)
|
||||||
|
const c = new Uint8Array(m.byteLength)
|
||||||
|
m.set(msg, crypto_secretbox_ZEROBYTES)
|
||||||
|
if (crypto_secretbox(c, m, n, k) === false) return false
|
||||||
|
o.set(c.subarray(crypto_secretbox_BOXZEROBYTES))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
function crypto_secretbox_open_easy (msg, box, n, k) {
|
||||||
|
assert(box.byteLength === msg.byteLength + crypto_secretbox_MACBYTES, "box must be 'msg.byteLength + crypto_secretbox_MACBYTES' bytes")
|
||||||
|
assert(n.byteLength === crypto_secretbox_NONCEBYTES, "n must be 'crypto_secretbox_NONCEBYTES' bytes")
|
||||||
|
assert(k.byteLength === crypto_secretbox_KEYBYTES, "k must be 'crypto_secretbox_KEYBYTES' bytes")
|
||||||
|
|
||||||
|
const c = new Uint8Array(crypto_secretbox_BOXZEROBYTES + box.byteLength)
|
||||||
|
const m = new Uint8Array(c.byteLength)
|
||||||
|
c.set(box, crypto_secretbox_BOXZEROBYTES)
|
||||||
|
if (crypto_secretbox_open(m, c, n, k) === false) return false
|
||||||
|
msg.set(m.subarray(crypto_secretbox_ZEROBYTES))
|
||||||
|
return true
|
||||||
|
}
|
||||||
@@ -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)
|
||||||
|
}
|
||||||
+322
@@ -0,0 +1,322 @@
|
|||||||
|
/* 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_sign_BYTES = 64
|
||||||
|
const crypto_sign_PUBLICKEYBYTES = 32
|
||||||
|
const crypto_sign_SECRETKEYBYTES = 64
|
||||||
|
const crypto_sign_SEEDBYTES = 32
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
var b, i
|
||||||
|
set25519(p[0], gf0)
|
||||||
|
set25519(p[1], gf1)
|
||||||
|
set25519(p[2], gf1)
|
||||||
|
set25519(p[3], gf0)
|
||||||
|
for (i = 255; i >= 0; --i) {
|
||||||
|
b = (s[(i / 8) | 0] >> (i & 7)) & 1
|
||||||
|
cswap(p, q, b)
|
||||||
|
add(q, p)
|
||||||
|
add(p, p)
|
||||||
|
cswap(p, q, b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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]
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
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 -1
|
||||||
|
|
||||||
|
if (par25519(r[0]) === (p[31] >> 7)) Z(r[0], gf0, r[0])
|
||||||
|
|
||||||
|
M(r[3], r[0], r[1])
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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 check (buf, len) {
|
||||||
|
if (!buf || (len && buf.length < len)) throw new Error('Argument must be a buffer' + (len ? ' of length ' + len : ''))
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/* 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 = 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,28 @@
|
|||||||
|
/* eslint-disable camelcase */
|
||||||
|
module.exports = {
|
||||||
|
crypto_verify_16,
|
||||||
|
crypto_verify_32
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
function crypto_verify_32 (x, xi, y, yi) {
|
||||||
|
return vn(x, xi, y, yi, 32)
|
||||||
|
}
|
||||||
|
|
||||||
|
function crypto_verify_64 (x, xi, y, yi) {
|
||||||
|
return vn(x, xi, y, yi, 64)
|
||||||
|
}
|
||||||
+8
-6
@@ -1,20 +1,22 @@
|
|||||||
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)
|
||||||
|
|
||||||
console.log('Plaintext:', plainText.toString())
|
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,23 @@
|
|||||||
|
/* eslint-disable camelcase */
|
||||||
|
var MessageChannel = global.MessageChannel
|
||||||
|
if (MessageChannel == null) ({ MessageChannel } = require('worker' + '_threads'))
|
||||||
|
|
||||||
|
function sodium_malloc (n) {
|
||||||
|
return new Uint8Array(n)
|
||||||
|
}
|
||||||
|
|
||||||
|
const sink = new MessageChannel()
|
||||||
|
function sodium_free (n) {
|
||||||
|
sodium_memzero(n)
|
||||||
|
sink.port1.postMessage(n.buffer, [n.buffer])
|
||||||
|
}
|
||||||
|
|
||||||
|
function sodium_memzero (arr) {
|
||||||
|
arr.fill(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
sodium_malloc,
|
||||||
|
sodium_free,
|
||||||
|
sodium_memzero
|
||||||
|
}
|
||||||
+36
-7
@@ -1,22 +1,51 @@
|
|||||||
{
|
{
|
||||||
"name": "sodium-javascript",
|
"name": "sodium-javascript",
|
||||||
"version": "0.2.0",
|
"version": "0.6.2",
|
||||||
"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": "^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": {
|
"devDependencies": {
|
||||||
"sodium-test": "^0.3.0"
|
"browserify": "^16.5.1",
|
||||||
|
"sodium-test": "^0.9.0",
|
||||||
|
"standard": "^14.3.4",
|
||||||
|
"tape-run": "^7.0.0"
|
||||||
|
},
|
||||||
|
"standard": {
|
||||||
|
"ignore": [
|
||||||
|
"/internal/**/*.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"browser": {
|
||||||
|
"crypto": false
|
||||||
|
},
|
||||||
|
"react-native": {
|
||||||
|
"crypto": "crypto"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"pretest": "standard",
|
||||||
|
"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"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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