Compare commits
151
Commits
v0.5.3
...
crypto_pwhash
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
38a0d034d4 | ||
|
|
2b515e6b71 | ||
|
|
4465a532c4 | ||
|
|
64089d1fca | ||
|
|
c428394bb6 | ||
|
|
713becb400 | ||
|
|
5dfe656dc5 | ||
|
|
081ca46654 | ||
|
|
f19e6c8172 | ||
|
|
facf602fdc | ||
|
|
ee481d0096 | ||
|
|
4a97dfeebe | ||
|
|
dbc8196148 | ||
|
|
056b13362b | ||
|
|
f62c993d48 | ||
|
|
2f4480f2f1 | ||
|
|
d6869faa13 | ||
|
|
b619401719 | ||
|
|
52d5899c54 | ||
|
|
919353ba53 | ||
|
|
7cad891d0e | ||
|
|
bfa677d67f | ||
|
|
37c8f2db79 | ||
|
|
c42c442eab | ||
|
|
58947e04ce | ||
|
|
ae2df3305e | ||
|
|
6c584231e6 | ||
|
|
c54ff9636e | ||
|
|
426ca77d47 | ||
|
|
25c97802f4 | ||
|
|
87ff2a56bd | ||
|
|
7ef6e52870 | ||
|
|
0227f45c6b | ||
|
|
ca32540960 | ||
|
|
51093efbc5 | ||
|
|
f79aed4eee | ||
|
|
3eb1d64460 | ||
|
|
88862d3669 | ||
|
|
bafe8f8fac | ||
|
|
a02899bfe2 | ||
|
|
40bced0da1 | ||
|
|
7febc97986 | ||
|
|
66494ec3b5 | ||
|
|
35f38a6c10 | ||
|
|
125384f26a | ||
|
|
d432fe295d | ||
|
|
97200f90da | ||
|
|
656d6d251e | ||
|
|
61b6e6916a | ||
|
|
ab004d8022 | ||
|
|
ce5ac41ecd | ||
|
|
a82160d51b | ||
|
|
3c2f81c3f3 | ||
|
|
3753006318 | ||
|
|
a546f3e51d | ||
|
|
a338ae9f9d | ||
|
|
e4693065fd | ||
|
|
44e5985630 | ||
|
|
65639e537e | ||
|
|
3dfe6daec0 | ||
|
|
885541ad1f | ||
|
|
e5dff8b785 | ||
|
|
8c23d7a3af | ||
|
|
3ecb669b6f | ||
|
|
f1537df1e0 | ||
|
|
f11ff5a727 | ||
|
|
9c30d3ead8 | ||
|
|
ddcdae69a1 | ||
|
|
80dd633012 | ||
|
|
d8d59d0443 | ||
|
|
ef00ddc878 | ||
|
|
cc52e58504 | ||
|
|
7b518f7b2c | ||
|
|
74a1067746 | ||
|
|
919896d2bb | ||
|
|
f3a80cb6f5 | ||
|
|
40f9b887f4 | ||
|
|
2ca6264f50 | ||
|
|
9d65d19e86 | ||
|
|
30c3342156 | ||
|
|
930e77ad32 | ||
|
|
e9ac929b5a | ||
|
|
e77c70ef71 | ||
|
|
4bb40aa43d | ||
|
|
fc90cbedba | ||
|
|
63fb70028e | ||
|
|
f033af88bd | ||
|
|
b44f83f0a8 | ||
|
|
596f8c8f18 | ||
|
|
21051f3392 | ||
|
|
759cec5b5a | ||
|
|
aa0305154f | ||
|
|
cb1fe07efe | ||
|
|
b6201cc0f1 | ||
|
|
9d29d467e4 | ||
|
|
5473cafdfe | ||
|
|
d2d84df55e | ||
|
|
fdfc09a157 | ||
|
|
d626fb2ca5 | ||
|
|
b6b39638cf | ||
|
|
56416de1d5 | ||
|
|
e35adc6823 | ||
|
|
ec9cac17d0 | ||
|
|
b7a0d1f2e5 | ||
|
|
9b78e675e4 | ||
|
|
2214a59711 | ||
|
|
0b37ca03ec | ||
|
|
6a0e8e7236 | ||
|
|
68bd4b4a68 | ||
|
|
272ac68f6b | ||
|
|
e423d00ebc | ||
|
|
caa8390691 | ||
|
|
04bebb09c9 | ||
|
|
e69a73279a | ||
|
|
79273d499e | ||
|
|
e589c6a5d6 | ||
|
|
96266128af | ||
|
|
84bf4229e4 | ||
|
|
7d7249ddc2 | ||
|
|
f969d1f707 | ||
|
|
67a4ba77cb | ||
|
|
8aae7efea2 | ||
|
|
d57736bf8b | ||
|
|
7141f00ff0 | ||
|
|
7e5ea3b5ed | ||
|
|
30b8e83417 | ||
|
|
311905883a | ||
|
|
895d4312af | ||
|
|
d1aaacd3a7 | ||
|
|
6a9696c86f | ||
|
|
5dd22a0957 | ||
|
|
a4cab9dfd4 | ||
|
|
00d47225ff | ||
|
|
1e447c23d6 | ||
|
|
6428fb8222 | ||
|
|
b30cf7348e | ||
|
|
ff28f5a888 | ||
|
|
03fb607709 | ||
|
|
d7ca21cbf1 | ||
|
|
942c2a6db0 | ||
|
|
51f8fbc2d3 | ||
|
|
f790621e60 | ||
|
|
4e42b942a5 | ||
|
|
49587c3d7f | ||
|
|
92aee452df | ||
|
|
e1ca83f1bd | ||
|
|
c81ef709d1 | ||
|
|
4e1c69ba13 | ||
|
|
5159d68fa9 | ||
|
|
5ccdcdee17 | ||
|
|
48081c6896 |
@@ -1 +1,2 @@
|
||||
node_modules
|
||||
package-lock.json
|
||||
|
||||
+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
|
||||
}
|
||||
+202
@@ -0,0 +1,202 @@
|
||||
/* eslint-disable camelcase */
|
||||
const { crypto_hash_sha512 } = require('./crypto_hash')
|
||||
const { crypto_scalarmult, crypto_scalarmult_base } = require('./crypto_scalarmult')
|
||||
const { randombytes_buf } = 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_detached,
|
||||
crypto_box_open_detached,
|
||||
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_buf(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
|
||||
}
|
||||
+269
@@ -0,0 +1,269 @@
|
||||
const b4a = require('b4a')
|
||||
const assert = require('nanoassert')
|
||||
|
||||
const {
|
||||
ge25519_p3,
|
||||
ge25519_p1p1,
|
||||
ge25519_cached,
|
||||
ge25519_frombytes,
|
||||
ge25519_p3_tobytes,
|
||||
ge25519_p1p1_to_p3,
|
||||
ge25519_p3_to_cached,
|
||||
ge25519_is_on_curve,
|
||||
ge25519_is_canonical,
|
||||
ge25519_is_on_main_subgroup,
|
||||
ge25519_has_small_order,
|
||||
ge25519_add_cached,
|
||||
ge25519_sub_cached,
|
||||
ge25519_from_uniform,
|
||||
sc25519_reduce,
|
||||
sc25519_mul,
|
||||
sc25519_invert,
|
||||
sc25519_is_canonical
|
||||
} = require('./fe25519_25.js')
|
||||
|
||||
const { randombytes_buf } = require('./randombytes')
|
||||
|
||||
const {
|
||||
sodium_add,
|
||||
sodium_sub,
|
||||
sodium_is_zero,
|
||||
sodium_memzero
|
||||
} = require('./utils')
|
||||
|
||||
function crypto_core_ed25519_is_valid_point (p) {
|
||||
const p_p3 = ge25519_p3()
|
||||
|
||||
if (ge25519_is_canonical(p) == 0 ||
|
||||
ge25519_has_small_order(p) != 0 ||
|
||||
ge25519_frombytes(p_p3, p) != 0 ||
|
||||
ge25519_is_on_curve(p_p3) == 0 ||
|
||||
ge25519_is_on_main_subgroup(p_p3) == 0) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
function crypto_core_ed25519_add (r, p, q) {
|
||||
const p_p3 = ge25519_p3()
|
||||
const q_p3 = ge25519_p3()
|
||||
const r_p3 = ge25519_p3()
|
||||
|
||||
const r_p1p1 = ge25519_p1p1()
|
||||
const q_cached = ge25519_cached()
|
||||
|
||||
if (ge25519_frombytes(p_p3, p) != 0 || ge25519_is_on_curve(p_p3) == 0 ||
|
||||
ge25519_frombytes(q_p3, q) != 0 || ge25519_is_on_curve(q_p3) == 0) {
|
||||
throw new Error('Operands must be valid points.')
|
||||
}
|
||||
|
||||
ge25519_p3_to_cached(q_cached, q_p3)
|
||||
ge25519_add_cached(r_p1p1, p_p3, q_cached)
|
||||
ge25519_p1p1_to_p3(r_p3, r_p1p1)
|
||||
ge25519_p3_tobytes(r, r_p3)
|
||||
}
|
||||
|
||||
function crypto_core_ed25519_sub (r, p, q) {
|
||||
const p_p3 = ge25519_p3()
|
||||
const q_p3 = ge25519_p3()
|
||||
const r_p3 = ge25519_p3()
|
||||
|
||||
const r_p1p1 = ge25519_p1p1()
|
||||
const q_cached = ge25519_cached()
|
||||
|
||||
if (ge25519_frombytes(p_p3, p) != 0 || ge25519_is_on_curve(p_p3) == 0 ||
|
||||
ge25519_frombytes(q_p3, q) != 0 || ge25519_is_on_curve(q_p3) == 0) {
|
||||
throw new Error('Operands must be valid points.')
|
||||
}
|
||||
ge25519_p3_to_cached(q_cached, q_p3)
|
||||
ge25519_sub_cached(r_p1p1, p_p3, q_cached)
|
||||
ge25519_p1p1_to_p3(r_p3, r_p1p1)
|
||||
ge25519_p3_tobytes(r, r_p3)
|
||||
}
|
||||
|
||||
function crypto_core_ed25519_from_uniform (p, r) {
|
||||
ge25519_from_uniform(p, r)
|
||||
}
|
||||
|
||||
// const HASH_GE_L = 48
|
||||
|
||||
// function _string_to_points (px, n, ctx, msg, msg_len, hash_alg) {
|
||||
// const h = b4a.alloc(crypto_core_ed25519_HASHBYTES)
|
||||
// const h_be = b4a.alloc(2 * HASH_GE_L)
|
||||
|
||||
// let i
|
||||
// let j
|
||||
|
||||
// if (n > 2) {
|
||||
// // abort(); /* LCOV_EXCL_LINE */
|
||||
// throw new Error('abort')
|
||||
// }
|
||||
// if (core_h2c_string_to_hash(h_be, n * HASH_GE_L, ctx, msg, msg_len,
|
||||
// hash_alg) != 0) {
|
||||
// return -1;
|
||||
// }
|
||||
// COMPILER_ASSERT(sizeof h >= HASH_GE_L);
|
||||
// for (i = 0U; i < n; i++) {
|
||||
// for (j = 0U; j < HASH_GE_L; j++) {
|
||||
// h[j] = h_be[i * HASH_GE_L + HASH_GE_L - 1U - j];
|
||||
// }
|
||||
// memset(&h[j], 0, (sizeof h) - j);
|
||||
// ge25519_from_hash(&px[i * crypto_core_ed25519_BYTES], h);
|
||||
// }
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// int
|
||||
// crypto_core_ed25519_from_string(unsigned char p[crypto_core_ed25519_BYTES],
|
||||
// const char *ctx, msg,
|
||||
// size_t msg_len, int hash_alg)
|
||||
// {
|
||||
// return _string_to_points(p, 1, ctx, msg, msg_len, hash_alg);
|
||||
// }
|
||||
|
||||
// int
|
||||
// crypto_core_ed25519_from_string_ro(unsigned char p[crypto_core_ed25519_BYTES],
|
||||
// const char *ctx, msg,
|
||||
// size_t msg_len, int hash_alg)
|
||||
// {
|
||||
// unsigned char px[2 * crypto_core_ed25519_BYTES];
|
||||
|
||||
// if (_string_to_points(px, 2, ctx, msg, msg_len, hash_alg) != 0) {
|
||||
// return -1;
|
||||
// }
|
||||
// return crypto_core_ed25519_add(p, &px[0], &px[crypto_core_ed25519_BYTES]);
|
||||
// }
|
||||
|
||||
function crypto_core_ed25519_random (p) {
|
||||
const h = b4a.alloc(crypto_core_ed25519_UNIFORMBYTES)
|
||||
|
||||
randombytes_buf(h)
|
||||
crypto_core_ed25519_from_uniform(p, h)
|
||||
}
|
||||
|
||||
function crypto_core_ed25519_scalar_random (r) {
|
||||
do {
|
||||
randombytes_buf(r, crypto_core_ed25519_SCALARBYTES)
|
||||
r[crypto_core_ed25519_SCALARBYTES - 1] &= 0x1f
|
||||
} while (sc25519_is_canonical(r) == 0 ||
|
||||
sodium_is_zero(r, crypto_core_ed25519_SCALARBYTES))
|
||||
}
|
||||
|
||||
function crypto_core_ed25519_scalar_invert (recip, s) {
|
||||
sc25519_invert(recip, s)
|
||||
|
||||
if (sodium_is_zero(s, crypto_core_ed25519_SCALARBYTES)) {
|
||||
throw new Error('Zero point')
|
||||
}
|
||||
}
|
||||
|
||||
/* 2^252+27742317777372353535851937790883648493 */
|
||||
const L = b4a.from([
|
||||
0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7,
|
||||
0xa2, 0xde, 0xf9, 0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10
|
||||
])
|
||||
|
||||
function crypto_core_ed25519_scalar_negate (neg, s) {
|
||||
const t_ = b4a.alloc(crypto_core_ed25519_NONREDUCEDSCALARBYTES)
|
||||
const s_ = b4a.alloc(crypto_core_ed25519_NONREDUCEDSCALARBYTES)
|
||||
|
||||
assert(crypto_core_ed25519_NONREDUCEDSCALARBYTES >=
|
||||
2 * crypto_core_ed25519_SCALARBYTES)
|
||||
|
||||
t_.fill(0)
|
||||
s_.fill(0)
|
||||
|
||||
t_.set(L.subarray(0, crypto_core_ed25519_SCALARBYTES), crypto_core_ed25519_SCALARBYTES)
|
||||
s_.set(s.subarray(0, crypto_core_ed25519_SCALARBYTES))
|
||||
|
||||
sodium_sub(t_, s_, crypto_core_ed25519_NONREDUCEDSCALARBYTES)
|
||||
sc25519_reduce(t_)
|
||||
|
||||
neg.set(t_.subarray(0, crypto_core_ed25519_SCALARBYTES))
|
||||
}
|
||||
|
||||
function crypto_core_ed25519_scalar_complement (comp, s) {
|
||||
const t_ = b4a.alloc(crypto_core_ed25519_NONREDUCEDSCALARBYTES)
|
||||
const s_ = b4a.alloc(crypto_core_ed25519_NONREDUCEDSCALARBYTES)
|
||||
|
||||
assert(crypto_core_ed25519_NONREDUCEDSCALARBYTES >=
|
||||
2 * crypto_core_ed25519_SCALARBYTES)
|
||||
|
||||
t_.fill(0)
|
||||
s_.fill(0)
|
||||
t_[0]++
|
||||
|
||||
t_.set(L.subarray(0, crypto_core_ed25519_SCALARBYTES), crypto_core_ed25519_SCALARBYTES)
|
||||
s_.set(s.subarray(0, crypto_core_ed25519_SCALARBYTES))
|
||||
|
||||
sodium_sub(t_, s_, crypto_core_ed25519_NONREDUCEDSCALARBYTES)
|
||||
sc25519_reduce(t_)
|
||||
|
||||
comp.set(t_.subarray(0, crypto_core_ed25519_SCALARBYTES))
|
||||
}
|
||||
|
||||
function crypto_core_ed25519_scalar_add (z, x, y) {
|
||||
const x_ = b4a.alloc(crypto_core_ed25519_NONREDUCEDSCALARBYTES)
|
||||
const y_ = b4a.alloc(crypto_core_ed25519_NONREDUCEDSCALARBYTES)
|
||||
|
||||
x_.fill(0)
|
||||
y_.fill(0)
|
||||
|
||||
x_.set(x.subarray(0, crypto_core_ed25519_SCALARBYTES))
|
||||
y_.set(y.subarray(0, crypto_core_ed25519_SCALARBYTES))
|
||||
|
||||
sodium_add(x_, y_, crypto_core_ed25519_SCALARBYTES)
|
||||
crypto_core_ed25519_scalar_reduce(z, x_)
|
||||
}
|
||||
|
||||
function crypto_core_ed25519_scalar_sub (z, x, y) {
|
||||
const yn = b4a.alloc(crypto_core_ed25519_SCALARBYTES)
|
||||
|
||||
crypto_core_ed25519_scalar_negate(yn, y)
|
||||
crypto_core_ed25519_scalar_add(z, x, yn)
|
||||
}
|
||||
|
||||
function crypto_core_ed25519_scalar_mul (z, x, y) {
|
||||
sc25519_mul(z, x, y)
|
||||
}
|
||||
|
||||
function crypto_core_ed25519_scalar_reduce (r, s) {
|
||||
const t = b4a.alloc(crypto_core_ed25519_NONREDUCEDSCALARBYTES)
|
||||
|
||||
t.set(s)
|
||||
|
||||
sc25519_reduce(t)
|
||||
r.set(t.subarray(0, crypto_core_ed25519_SCALARBYTES))
|
||||
sodium_memzero(t)
|
||||
}
|
||||
|
||||
function crypto_core_ed25519_scalar_is_canonical (s) {
|
||||
return sc25519_is_canonical(s)
|
||||
}
|
||||
|
||||
const crypto_core_ed25519_BYTES = 32
|
||||
const crypto_core_ed25519_UNIFORMBYTES = 32
|
||||
const crypto_core_ed25519_SCALARBYTES = 32
|
||||
const crypto_core_ed25519_NONREDUCEDSCALARBYTES = 64
|
||||
|
||||
module.exports = {
|
||||
crypto_core_ed25519_is_valid_point,
|
||||
crypto_core_ed25519_add,
|
||||
crypto_core_ed25519_sub,
|
||||
crypto_core_ed25519_from_uniform,
|
||||
crypto_core_ed25519_random,
|
||||
crypto_core_ed25519_scalar_random,
|
||||
crypto_core_ed25519_scalar_invert,
|
||||
crypto_core_ed25519_scalar_negate,
|
||||
crypto_core_ed25519_scalar_complement,
|
||||
crypto_core_ed25519_scalar_add,
|
||||
crypto_core_ed25519_scalar_sub,
|
||||
crypto_core_ed25519_scalar_mul,
|
||||
crypto_core_ed25519_scalar_reduce,
|
||||
crypto_core_ed25519_scalar_is_canonical,
|
||||
crypto_core_ed25519_BYTES,
|
||||
crypto_core_ed25519_UNIFORMBYTES,
|
||||
crypto_core_ed25519_SCALARBYTES,
|
||||
crypto_core_ed25519_NONREDUCEDSCALARBYTES
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
const b4a = require('b4a')
|
||||
|
||||
const { randombytes_buf } = require('./randombytes')
|
||||
const {
|
||||
ge25519_p3,
|
||||
ge25519_p1p1,
|
||||
ge25519_cached,
|
||||
ge25519_p3_to_cached,
|
||||
ge25519_add_cached,
|
||||
ge25519_p1p1_to_p3,
|
||||
ge25519_sub_cached,
|
||||
ristretto255_frombytes,
|
||||
ristretto255_p3_tobytes,
|
||||
ristretto255_from_hash,
|
||||
sc25519_mul,
|
||||
sc25519_is_canonical
|
||||
} = require('./fe25519_25')
|
||||
|
||||
const {
|
||||
crypto_core_ed25519_scalar_random,
|
||||
crypto_core_ed25519_scalar_invert,
|
||||
crypto_core_ed25519_scalar_negate,
|
||||
crypto_core_ed25519_scalar_complement,
|
||||
crypto_core_ed25519_scalar_add,
|
||||
crypto_core_ed25519_scalar_sub,
|
||||
crypto_core_ed25519_scalar_reduce
|
||||
} = require('./crypto_core')
|
||||
|
||||
const crypto_core_ristretto255_BYTES = 32
|
||||
const crypto_core_ristretto255_NONREDUCEDSCALARBYTES = 64
|
||||
const crypto_core_ristretto255_HASHBYTES = 64
|
||||
const crypto_core_ristretto255_SCALARBYTES = 32
|
||||
|
||||
module.exports = {
|
||||
crypto_core_ristretto255_BYTES,
|
||||
crypto_core_ristretto255_NONREDUCEDSCALARBYTES,
|
||||
crypto_core_ristretto255_HASHBYTES,
|
||||
crypto_core_ristretto255_SCALARBYTES,
|
||||
crypto_core_ristretto255_is_valid_point,
|
||||
crypto_core_ristretto255_add,
|
||||
crypto_core_ristretto255_sub,
|
||||
crypto_core_ristretto255_from_hash,
|
||||
crypto_core_ristretto255_random,
|
||||
crypto_core_ristretto255_scalar_random,
|
||||
crypto_core_ristretto255_scalar_invert,
|
||||
crypto_core_ristretto255_scalar_negate,
|
||||
crypto_core_ristretto255_scalar_complement,
|
||||
crypto_core_ristretto255_scalar_add,
|
||||
crypto_core_ristretto255_scalar_sub,
|
||||
crypto_core_ristretto255_scalar_mul,
|
||||
crypto_core_ristretto255_scalar_reduce,
|
||||
crypto_core_ristretto255_scalar_is_canonical
|
||||
}
|
||||
|
||||
function crypto_core_ristretto255_is_valid_point (p) {
|
||||
const p_p3 = ge25519_p3()
|
||||
|
||||
if (ristretto255_frombytes(p_p3, p) != 0) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
function crypto_core_ristretto255_add (r, p, q) {
|
||||
const p_p3 = ge25519_p3()
|
||||
const q_p3 = ge25519_p3()
|
||||
const r_p3 = ge25519_p3()
|
||||
const r_p1p1 = ge25519_p1p1()
|
||||
const q_cached = ge25519_cached()
|
||||
|
||||
if (ristretto255_frombytes(p_p3, p) != 0 ||
|
||||
ristretto255_frombytes(q_p3, q) != 0) {
|
||||
return -1
|
||||
}
|
||||
ge25519_p3_to_cached(q_cached, q_p3)
|
||||
ge25519_add_cached(r_p1p1, p_p3, q_cached)
|
||||
ge25519_p1p1_to_p3(r_p3, r_p1p1)
|
||||
ristretto255_p3_tobytes(r, r_p3)
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
function crypto_core_ristretto255_sub (r, p, q) {
|
||||
const p_p3 = ge25519_p3()
|
||||
const q_p3 = ge25519_p3()
|
||||
const r_p3 = ge25519_p3()
|
||||
const r_p1p1 = ge25519_p1p1()
|
||||
const q_cached = ge25519_cached()
|
||||
|
||||
if (ristretto255_frombytes(p_p3, p) != 0 ||
|
||||
ristretto255_frombytes(q_p3, q) != 0) {
|
||||
return -1
|
||||
}
|
||||
ge25519_p3_to_cached(q_cached, q_p3)
|
||||
ge25519_sub_cached(r_p1p1, p_p3, q_cached)
|
||||
ge25519_p1p1_to_p3(r_p3, r_p1p1)
|
||||
ristretto255_p3_tobytes(r, r_p3)
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
function crypto_core_ristretto255_from_hash (p, r) {
|
||||
ristretto255_from_hash(p, r)
|
||||
return 0
|
||||
}
|
||||
|
||||
function crypto_core_ristretto255_random (p) {
|
||||
const h = b4a.alloc(crypto_core_ristretto255_HASHBYTES)
|
||||
randombytes_buf(h)
|
||||
crypto_core_ristretto255_from_hash(p, h)
|
||||
}
|
||||
|
||||
function crypto_core_ristretto255_scalar_random (r) {
|
||||
crypto_core_ed25519_scalar_random(r)
|
||||
}
|
||||
|
||||
function crypto_core_ristretto255_scalar_invert (recip, s) {
|
||||
return crypto_core_ed25519_scalar_invert(recip, s)
|
||||
}
|
||||
|
||||
function crypto_core_ristretto255_scalar_negate (neg, s) {
|
||||
crypto_core_ed25519_scalar_negate(neg, s)
|
||||
}
|
||||
|
||||
function crypto_core_ristretto255_scalar_complement (comp, s) {
|
||||
crypto_core_ed25519_scalar_complement(comp, s)
|
||||
}
|
||||
|
||||
function crypto_core_ristretto255_scalar_add (z, x, y) {
|
||||
crypto_core_ed25519_scalar_add(z, x, y)
|
||||
}
|
||||
|
||||
function crypto_core_ristretto255_scalar_sub (z, x, y) {
|
||||
crypto_core_ed25519_scalar_sub(z, x, y)
|
||||
}
|
||||
|
||||
function crypto_core_ristretto255_scalar_mul (z, x, y) {
|
||||
sc25519_mul(z, x, y)
|
||||
}
|
||||
|
||||
function crypto_core_ristretto255_scalar_reduce (r, s) {
|
||||
crypto_core_ed25519_scalar_reduce(r, s)
|
||||
}
|
||||
|
||||
function crypto_core_ristretto255_scalar_is_canonical (s) {
|
||||
return sc25519_is_canonical(s)
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
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
|
||||
@@ -29,6 +31,6 @@ module.exports.crypto_generichash_instance = function (key, outlen) {
|
||||
return blake2b(outlen, key)
|
||||
}
|
||||
|
||||
blake2b.ready(function (err) {
|
||||
blake2b.ready(function (_) {
|
||||
module.exports.crypto_generichash_WASM_LOADED = blake2b.WASM_LOADED
|
||||
})
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/* 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_sha512_state () {
|
||||
return sha512()
|
||||
}
|
||||
|
||||
function crypto_hash_sha512_update (state, m, n) {
|
||||
if (n === undefined) n = m.byteLength
|
||||
state.update(m.subarray(0, n))
|
||||
return 0
|
||||
}
|
||||
|
||||
function crypto_hash_sha512_final (state, out) {
|
||||
assert(out.byteLength === crypto_hash_sha512_BYTES, "out must be 'crypto_hash_sha512_BYTES' bytes long")
|
||||
|
||||
state.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_state,
|
||||
crypto_hash_sha512_update,
|
||||
crypto_hash_sha512_final,
|
||||
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
|
||||
}
|
||||
+7
-6
@@ -1,14 +1,15 @@
|
||||
var assert = require('nanoassert')
|
||||
var randombytes_buf = require('./randombytes').randombytes_buf
|
||||
var blake2b = require('blake2b')
|
||||
/* eslint-disable camelcase */
|
||||
const assert = require('nanoassert')
|
||||
const randombytes_buf = require('./randombytes').randombytes_buf
|
||||
const blake2b = require('blake2b')
|
||||
|
||||
module.exports.crypto_kdf_PRIMITIVE = 'blake2b'
|
||||
module.exports.crypto_kdf_BYTES_MIN = 16
|
||||
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
|
||||
@@ -29,7 +30,7 @@ module.exports.crypto_kdf_derive_from_key = function crypto_kdf_derive_from_key
|
||||
STORE64_LE(salt, subkey_id)
|
||||
|
||||
var outlen = Math.min(subkey.length, module.exports.crypto_kdf_BYTES_MAX)
|
||||
blake2b(outlen, key, salt, ctx_padded, true)
|
||||
blake2b(outlen, key.subarray(0, module.exports.crypto_kdf_KEYBYTES), salt, ctx_padded, true)
|
||||
.final(subkey)
|
||||
}
|
||||
|
||||
|
||||
@@ -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,264 @@
|
||||
/* eslint-disable camelcase */
|
||||
const b4a = require('b4a')
|
||||
const argon2 = require('argon2hash-wasm')
|
||||
const { randombytes_buf } = require('./randombytes')
|
||||
|
||||
const crypto_pwhash_argon2i_ALG_ARGON2I13 = 1
|
||||
const crypto_pwhash_argon2i_BYTES_MIN = 16
|
||||
const crypto_pwhash_argon2i_BYTES_MAX = 4294967295
|
||||
const crypto_pwhash_argon2i_PASSWD_MIN = 0
|
||||
const crypto_pwhash_argon2i_PASSWD_MAX = 4294967295
|
||||
const crypto_pwhash_argon2i_SALTBYTES = 16
|
||||
const crypto_pwhash_argon2i_STRBYTES = 128
|
||||
const crypto_pwhash_argon2i_STRPREFIX = '$argon2i$'
|
||||
const crypto_pwhash_argon2i_OPSLIMIT_MIN = 3
|
||||
const crypto_pwhash_argon2i_OPSLIMIT_MAX = 4294967295
|
||||
const crypto_pwhash_argon2i_MEMLIMIT_MIN = 8192
|
||||
const crypto_pwhash_argon2i_MEMLIMIT_MAX = 2147483648
|
||||
const crypto_pwhash_argon2i_OPSLIMIT_INTERACTIVE = 4
|
||||
const crypto_pwhash_argon2i_MEMLIMIT_INTERACTIVE = 33554432
|
||||
const crypto_pwhash_argon2i_OPSLIMIT_MODERATE = 6
|
||||
const crypto_pwhash_argon2i_MEMLIMIT_MODERATE = 134217728
|
||||
const crypto_pwhash_argon2i_OPSLIMIT_SENSITIVE = 8
|
||||
const crypto_pwhash_argon2i_MEMLIMIT_SENSITIVE = 536870912
|
||||
|
||||
const crypto_pwhash_argon2id_ALG_ARGON2ID13 = 2
|
||||
const crypto_pwhash_argon2id_BYTES_MIN = 16
|
||||
const crypto_pwhash_argon2id_BYTES_MAX = 4294967295
|
||||
const crypto_pwhash_argon2id_PASSWD_MIN = 0
|
||||
const crypto_pwhash_argon2id_PASSWD_MAX = 4294967295
|
||||
const crypto_pwhash_argon2id_SALTBYTES = 16
|
||||
const crypto_pwhash_argon2id_STRBYTES = 128
|
||||
const crypto_pwhash_argon2id_STRPREFIX = '$argon2id$'
|
||||
const crypto_pwhash_argon2id_OPSLIMIT_MIN = 1
|
||||
const crypto_pwhash_argon2id_OPSLIMIT_MAX = 4294967295
|
||||
const crypto_pwhash_argon2id_MEMLIMIT_MIN = 8192
|
||||
const crypto_pwhash_argon2id_MEMLIMIT_MAX = 2147483648
|
||||
const crypto_pwhash_argon2id_OPSLIMIT_INTERACTIVE = 2
|
||||
const crypto_pwhash_argon2id_MEMLIMIT_INTERACTIVE = 67108864
|
||||
const crypto_pwhash_argon2id_OPSLIMIT_MODERATE = 3
|
||||
const crypto_pwhash_argon2id_MEMLIMIT_MODERATE = 268435456
|
||||
const crypto_pwhash_argon2id_OPSLIMIT_SENSITIVE = 4
|
||||
const crypto_pwhash_argon2id_MEMLIMIT_SENSITIVE = 1073741824
|
||||
|
||||
const crypto_pwhash_ALG_ARGON2I13 = crypto_pwhash_argon2i_ALG_ARGON2I13
|
||||
const crypto_pwhash_ALG_ARGON2ID13 = crypto_pwhash_argon2id_ALG_ARGON2ID13
|
||||
const crypto_pwhash_ALG_DEFAULT = crypto_pwhash_ALG_ARGON2ID13
|
||||
const crypto_pwhash_BYTES_MIN = crypto_pwhash_argon2id_BYTES_MIN
|
||||
const crypto_pwhash_BYTES_MAX = crypto_pwhash_argon2id_BYTES_MAX
|
||||
const crypto_pwhash_PASSWD_MIN = crypto_pwhash_argon2id_PASSWD_MIN
|
||||
const crypto_pwhash_PASSWD_MAX = crypto_pwhash_argon2id_PASSWD_MAX
|
||||
const crypto_pwhash_SALTBYTES = crypto_pwhash_argon2id_SALTBYTES
|
||||
const crypto_pwhash_STRBYTES = crypto_pwhash_argon2id_STRBYTES
|
||||
const crypto_pwhash_STRPREFIX = crypto_pwhash_argon2id_STRPREFIX
|
||||
const crypto_pwhash_OPSLIMIT_MIN = crypto_pwhash_argon2id_OPSLIMIT_MIN
|
||||
const crypto_pwhash_OPSLIMIT_MAX = crypto_pwhash_argon2id_OPSLIMIT_MAX
|
||||
const crypto_pwhash_MEMLIMIT_MIN = crypto_pwhash_argon2id_MEMLIMIT_MIN
|
||||
const crypto_pwhash_MEMLIMIT_MAX = crypto_pwhash_argon2id_MEMLIMIT_MAX
|
||||
const crypto_pwhash_OPSLIMIT_INTERACTIVE = crypto_pwhash_argon2id_OPSLIMIT_INTERACTIVE
|
||||
const crypto_pwhash_MEMLIMIT_INTERACTIVE = crypto_pwhash_argon2id_MEMLIMIT_INTERACTIVE
|
||||
const crypto_pwhash_OPSLIMIT_MODERATE = crypto_pwhash_argon2id_OPSLIMIT_MODERATE
|
||||
const crypto_pwhash_MEMLIMIT_MODERATE = crypto_pwhash_argon2id_MEMLIMIT_MODERATE
|
||||
const crypto_pwhash_OPSLIMIT_SENSITIVE = crypto_pwhash_argon2id_OPSLIMIT_SENSITIVE
|
||||
const crypto_pwhash_MEMLIMIT_SENSITIVE = crypto_pwhash_argon2id_MEMLIMIT_SENSITIVE
|
||||
|
||||
module.exports = {
|
||||
crypto_pwhash_ALG_ARGON2I13,
|
||||
crypto_pwhash_ALG_ARGON2ID13,
|
||||
crypto_pwhash_ALG_DEFAULT,
|
||||
crypto_pwhash_BYTES_MIN,
|
||||
crypto_pwhash_BYTES_MAX,
|
||||
crypto_pwhash_PASSWD_MIN,
|
||||
crypto_pwhash_PASSWD_MAX,
|
||||
crypto_pwhash_SALTBYTES,
|
||||
crypto_pwhash_STRBYTES,
|
||||
crypto_pwhash_STRPREFIX,
|
||||
crypto_pwhash_OPSLIMIT_MIN,
|
||||
crypto_pwhash_OPSLIMIT_MAX,
|
||||
crypto_pwhash_MEMLIMIT_MIN,
|
||||
crypto_pwhash_MEMLIMIT_MAX,
|
||||
crypto_pwhash_OPSLIMIT_INTERACTIVE,
|
||||
crypto_pwhash_MEMLIMIT_INTERACTIVE,
|
||||
crypto_pwhash_OPSLIMIT_MODERATE,
|
||||
crypto_pwhash_MEMLIMIT_MODERATE,
|
||||
crypto_pwhash_OPSLIMIT_SENSITIVE,
|
||||
crypto_pwhash_MEMLIMIT_SENSITIVE,
|
||||
crypto_pwhash_argon2i,
|
||||
crypto_pwhash_argon2id,
|
||||
crypto_pwhash_argon2i_str,
|
||||
crypto_pwhash_argon2id_str,
|
||||
crypto_pwhash,
|
||||
crypto_pwhash_str,
|
||||
crypto_pwhash_str_verify,
|
||||
crypto_pwhash_str_needs_rehash
|
||||
}
|
||||
|
||||
function crypto_pwhash_argon2i (out, passwd, salt, passes, memory, alg) {
|
||||
const outlen = out.byteLength
|
||||
const passwdlen = passwd.byteLength
|
||||
out.fill(0)
|
||||
|
||||
if (outlen > crypto_pwhash_argon2i_BYTES_MAX) {
|
||||
throw new Error('Too large')
|
||||
}
|
||||
|
||||
if (outlen < crypto_pwhash_argon2i_BYTES_MIN) {
|
||||
throw new Error('Invalid opts')
|
||||
}
|
||||
|
||||
if (passwdlen > crypto_pwhash_argon2i_PASSWD_MAX ||
|
||||
passes > crypto_pwhash_argon2i_OPSLIMIT_MAX ||
|
||||
memory > crypto_pwhash_argon2i_MEMLIMIT_MAX) {
|
||||
throw new Error('Too large')
|
||||
}
|
||||
|
||||
if (passwdlen < crypto_pwhash_argon2i_PASSWD_MIN ||
|
||||
(passes && passes < crypto_pwhash_argon2i_OPSLIMIT_MIN) ||
|
||||
(memory && memory < crypto_pwhash_argon2i_MEMLIMIT_MIN)) {
|
||||
throw new Error('Invalid opts')
|
||||
}
|
||||
|
||||
switch (alg) {
|
||||
case crypto_pwhash_argon2i_ALG_ARGON2I13: {
|
||||
const buf = argon2(passwd, salt, null, null, 'binary', { memory: memory >> 10, passes, outlen, type: argon2.ARGON2I })
|
||||
out.set(buf)
|
||||
return 0
|
||||
}
|
||||
|
||||
default:
|
||||
throw new Error('Invalid input')
|
||||
}
|
||||
}
|
||||
|
||||
function crypto_pwhash_argon2id (out, passwd, salt, passes, memory, alg) {
|
||||
const outlen = out.byteLength
|
||||
const passwdlen = passwd.byteLength
|
||||
out.fill(0)
|
||||
|
||||
if (outlen > crypto_pwhash_argon2id_BYTES_MAX) {
|
||||
throw new Error('Too large')
|
||||
}
|
||||
|
||||
if (outlen < crypto_pwhash_argon2id_BYTES_MIN) {
|
||||
throw new Error('Invalid opts')
|
||||
}
|
||||
|
||||
if (passwdlen > crypto_pwhash_argon2id_PASSWD_MAX ||
|
||||
passes > crypto_pwhash_argon2id_OPSLIMIT_MAX ||
|
||||
memory > crypto_pwhash_argon2id_MEMLIMIT_MAX) {
|
||||
throw new Error('Too large')
|
||||
}
|
||||
|
||||
if (passwdlen < crypto_pwhash_argon2id_PASSWD_MIN ||
|
||||
(passes && passes < crypto_pwhash_argon2id_OPSLIMIT_MIN) ||
|
||||
(memory && memory < crypto_pwhash_argon2id_MEMLIMIT_MIN)) {
|
||||
throw new Error('Invalid opts')
|
||||
}
|
||||
|
||||
switch (alg) {
|
||||
case crypto_pwhash_argon2id_ALG_ARGON2ID13: {
|
||||
const buf = argon2(passwd, salt, null, null, 'binary', { memory: memory >> 10, passes, outlen, type: argon2.ARGON2ID })
|
||||
out.set(buf)
|
||||
return 0
|
||||
}
|
||||
|
||||
default:
|
||||
throw new Error('Invalid input')
|
||||
}
|
||||
}
|
||||
|
||||
function crypto_pwhash_argon2i_str (out, passwd, salt, passes, memory, alg) {
|
||||
const outlen = 32
|
||||
const passwdlen = passwd.byteLength
|
||||
|
||||
if (passwdlen > crypto_pwhash_argon2i_PASSWD_MAX ||
|
||||
passes > crypto_pwhash_argon2i_OPSLIMIT_MAX ||
|
||||
memory > crypto_pwhash_argon2i_MEMLIMIT_MAX) {
|
||||
throw new Error('Too large')
|
||||
}
|
||||
|
||||
if (passwdlen < crypto_pwhash_argon2i_PASSWD_MIN ||
|
||||
(passes && passes < crypto_pwhash_argon2i_OPSLIMIT_MIN) ||
|
||||
(memory && memory < crypto_pwhash_argon2i_MEMLIMIT_MIN)) {
|
||||
throw new Error('Invalid opts')
|
||||
}
|
||||
|
||||
switch (alg) {
|
||||
case crypto_pwhash_argon2i_ALG_ARGON2I13:
|
||||
return argon2(passwd, salt, null, null, { memory: memory >> 10, passes, outlen, type: argon2.ARGON2I })
|
||||
|
||||
default:
|
||||
throw new Error('Invalid input')
|
||||
}
|
||||
}
|
||||
|
||||
function crypto_pwhash_argon2id_str (out, passwd, salt, passes, memory, alg) {
|
||||
const outlen = 32
|
||||
const passwdlen = passwd.byteLength
|
||||
|
||||
if (passwdlen > crypto_pwhash_argon2id_PASSWD_MAX ||
|
||||
passes > crypto_pwhash_argon2id_OPSLIMIT_MAX ||
|
||||
memory > crypto_pwhash_argon2id_MEMLIMIT_MAX) {
|
||||
throw new Error('Too large')
|
||||
}
|
||||
|
||||
if (passwdlen < crypto_pwhash_argon2id_PASSWD_MIN ||
|
||||
(passes && passes < crypto_pwhash_argon2id_OPSLIMIT_MIN) ||
|
||||
(memory && memory < crypto_pwhash_argon2id_MEMLIMIT_MIN)) {
|
||||
throw new Error('Invalid opts')
|
||||
}
|
||||
|
||||
switch (alg) {
|
||||
case crypto_pwhash_argon2id_ALG_ARGON2ID13:
|
||||
out.write(argon2(passwd, salt, null, null, { memory: memory >> 10, passes, outlen, type: argon2.ARGON2ID }))
|
||||
return
|
||||
|
||||
default:
|
||||
throw new Error('Invalid input')
|
||||
}
|
||||
}
|
||||
|
||||
function crypto_pwhash (out, passwd, salt, opslimit, memlimit, alg) {
|
||||
switch (alg) {
|
||||
case crypto_pwhash_argon2i_ALG_ARGON2I13:
|
||||
return crypto_pwhash_argon2i(out, passwd, salt, opslimit, memlimit, alg)
|
||||
|
||||
case crypto_pwhash_argon2id_ALG_ARGON2ID13:
|
||||
return crypto_pwhash_argon2id(out, passwd, salt, opslimit, memlimit, alg)
|
||||
}
|
||||
}
|
||||
|
||||
function crypto_pwhash_str (out, passwd, opslimit, memlimit) {
|
||||
const salt = b4a.alloc(crypto_pwhash_SALTBYTES)
|
||||
randombytes_buf(salt)
|
||||
|
||||
return crypto_pwhash_argon2id_str(out, passwd, salt, opslimit, memlimit, crypto_pwhash_ALG_DEFAULT)
|
||||
}
|
||||
|
||||
function crypto_pwhash_str_verify (str, passwd) {
|
||||
if (b4a.isBuffer(str)) return crypto_pwhash_str_verify(str.toString(), passwd)
|
||||
|
||||
if (str.slice(0, crypto_pwhash_argon2id_STRPREFIX.length) === crypto_pwhash_argon2id_STRPREFIX) {
|
||||
return argon2.verify(str, passwd, null)
|
||||
}
|
||||
|
||||
if (str.slice(0, crypto_pwhash_argon2i_STRPREFIX.length) === crypto_pwhash_argon2i_STRPREFIX) {
|
||||
return argon2.verify(str, passwd, null)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
function crypto_pwhash_str_needs_rehash (str, opslimit, memlimit, type) {
|
||||
memlimit >>= 10
|
||||
|
||||
if ((opslimit | memlimit) > 0xffffffff || (str.byteLength > crypto_pwhash_STRBYTES)) {
|
||||
throw new Error('Invalid opts.')
|
||||
}
|
||||
|
||||
try {
|
||||
return argon2.needsRehash(str, opslimit, memlimit, type)
|
||||
} catch {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -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,398 @@
|
||||
const assert = require('nanoassert')
|
||||
const ec = require('./fe25519_25')
|
||||
|
||||
const crypto_scalarmult_ed25519_BYTES = 32
|
||||
const crypto_scalarmult_ed25519_SCALARBYTES = 32
|
||||
|
||||
module.exports = {
|
||||
crypto_scalarmult_ed25519,
|
||||
crypto_scalarmult_ed25519_noclamp,
|
||||
crypto_scalarmult_ed25519_base,
|
||||
crypto_scalarmult: crypto_scalarmult_curve25519,
|
||||
crypto_scalarmult_base: crypto_scalarmult_curve25519_base,
|
||||
crypto_scalarmult_ed25519_base_noclamp,
|
||||
crypto_scalarmult_curve25519,
|
||||
crypto_scalarmult_curve25519_1,
|
||||
crypto_scalarmult_curve25519_base,
|
||||
crypto_scalarmult_ristretto255,
|
||||
crypto_scalarmult_ristretto255_base,
|
||||
crypto_scalarmult_BYTES: crypto_scalarmult_ed25519_BYTES,
|
||||
crypto_scalarmult_SCALARBYTES: crypto_scalarmult_ed25519_SCALARBYTES,
|
||||
crypto_scalarmult_ed25519_BYTES,
|
||||
crypto_scalarmult_ed25519_SCALARBYTES,
|
||||
crypto_scalarmult_curve25519_BYTES: 32,
|
||||
crypto_scalarmult_curve25519_SCALARBYTES: 32
|
||||
}
|
||||
|
||||
const _121666buf = Buffer.alloc(32)
|
||||
_121666buf.writeUInt32LE(121666)
|
||||
|
||||
const _121666 = ec.fe25519()
|
||||
ec.fe25519_frombytes(_121666, _121666buf)
|
||||
|
||||
function _crypto_scalarmult_ed25519_is_inf (s) {
|
||||
var c
|
||||
var i
|
||||
|
||||
c = s[0] ^ 0x01
|
||||
for (i = 1; i < 31; i++) {
|
||||
c |= s[i]
|
||||
}
|
||||
c |= s[31] & 0x7f
|
||||
|
||||
return ((c - 1) >> 8) & 1
|
||||
}
|
||||
|
||||
function _crypto_scalarmult_ed25519_clamp (k) {
|
||||
k[0] &= 248
|
||||
k[31] |= 64
|
||||
}
|
||||
|
||||
function _crypto_scalarmult_ed25519 (q, n, p, clamp) {
|
||||
var Q = ec.ge3()
|
||||
var P = ec.ge3()
|
||||
var t = q.slice()
|
||||
var i
|
||||
|
||||
if (ec.ge25519_is_canonical(p) == 0 || ec.ge25519_has_small_order(p) != 0 ||
|
||||
ec.ge25519_frombytes(P, p) != 0 || ec.ge25519_is_on_main_subgroup(P) == 0) {
|
||||
throw new Error('Invalid base point')
|
||||
}
|
||||
|
||||
for (i = 0; i < 32; ++i) {
|
||||
t[i] = n[i]
|
||||
}
|
||||
|
||||
if (clamp !== 0) {
|
||||
_crypto_scalarmult_ed25519_clamp(t)
|
||||
}
|
||||
|
||||
t[31] &= 127
|
||||
|
||||
ec.ge25519_scalarmult(Q, t, P)
|
||||
ec.ge25519_p3_tobytes(q, Q)
|
||||
|
||||
if (_crypto_scalarmult_ed25519_is_inf(q) != 0 || sodium_is_zero(n, 32)) {
|
||||
throw new Error('Point multiplication failed')
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
function crypto_scalarmult_ed25519 (q, n, p) {
|
||||
assert(q instanceof Uint8Array && q.byteLength === 32)
|
||||
assert(n instanceof Uint8Array && n.byteLength === 32)
|
||||
assert(p instanceof Uint8Array && p.byteLength === 32)
|
||||
|
||||
return _crypto_scalarmult_ed25519(q, n, p, 1)
|
||||
}
|
||||
|
||||
function crypto_scalarmult_ed25519_noclamp (q, n, p) {
|
||||
assert(q instanceof Uint8Array && q.byteLength === 32)
|
||||
assert(n instanceof Uint8Array && n.byteLength === 32)
|
||||
assert(p instanceof Uint8Array && p.byteLength === 32)
|
||||
|
||||
return _crypto_scalarmult_ed25519(q, n, p, 0)
|
||||
}
|
||||
|
||||
function _crypto_scalarmult_ed25519_base (q, n, clamp) {
|
||||
var t = q.slice()
|
||||
var Q = ec.ge3()
|
||||
var i
|
||||
|
||||
for (i = 0; i < 32; ++i) {
|
||||
t[i] = n[i]
|
||||
}
|
||||
|
||||
if (clamp !== 0) {
|
||||
_crypto_scalarmult_ed25519_clamp(t)
|
||||
}
|
||||
|
||||
t[31] &= 127
|
||||
|
||||
ec.ge25519_scalarmult_base(Q, t)
|
||||
ec.ge25519_p3_tobytes(q, Q)
|
||||
if (_crypto_scalarmult_ed25519_is_inf(q) !== 0 || sodium_is_zero(n, 32)) {
|
||||
return -1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
function crypto_scalarmult_ed25519_base(q, n) {
|
||||
assert(q instanceof Uint8Array && q.byteLength === 32)
|
||||
assert(n instanceof Uint8Array && n.byteLength === 32)
|
||||
|
||||
return _crypto_scalarmult_ed25519_base(q, n, 1)
|
||||
}
|
||||
|
||||
function crypto_scalarmult_ed25519_base_noclamp (q, n) {
|
||||
return _crypto_scalarmult_ed25519_base(q, n, 0)
|
||||
}
|
||||
|
||||
function crypto_scalarmult_ed25519_bytes () {
|
||||
return crypto_scalarmult_ed25519_BYTES
|
||||
}
|
||||
|
||||
function crypto_scalarmult_ed25519_scalarbytes () {
|
||||
return crypto_scalarmult_ed25519_SCALARBYTES
|
||||
}
|
||||
|
||||
function crypto_scalarmult_ristretto255 (q, n, p) {
|
||||
assert(q instanceof Uint8Array && q.byteLength === 32)
|
||||
assert(n instanceof Uint8Array && n.byteLength === 32)
|
||||
assert(p instanceof Uint8Array && p.byteLength === 32)
|
||||
|
||||
var t = q.slice()
|
||||
var Q = ec.ge3()
|
||||
var P = ec.ge3()
|
||||
var i
|
||||
|
||||
if (ec.ristretto255_frombytes(P, p) != 0) {
|
||||
return -1
|
||||
}
|
||||
for (i = 0; i < 32; ++i) {
|
||||
t[i] = n[i]
|
||||
}
|
||||
t[31] &= 127
|
||||
ec.ge25519_scalarmult(Q, t, P)
|
||||
ec.ristretto255_p3_tobytes(q, Q)
|
||||
if (sodium_is_zero(q, 32)) {
|
||||
return -1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
function crypto_scalarmult_ristretto255_base (q, n) {
|
||||
var t = q.slice
|
||||
var Q = ec.ge3()
|
||||
var i
|
||||
|
||||
for (i = 0; i < 32; ++i) {
|
||||
t[i] = n[i]
|
||||
}
|
||||
|
||||
t[31] &= 127
|
||||
|
||||
ec.ge25519_scalarmult_base(Q, t)
|
||||
ec.ristretto255_p3_tobytes(q, Q)
|
||||
if (sodium_is_zero(q, 32)) {
|
||||
return -1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
function crypto_scalarmult_ristretto255_bytes () {
|
||||
return crypto_scalarmult_ristretto255_BYTES
|
||||
}
|
||||
|
||||
function crypto_scalarmult_ristretto255_scalarbytes () {
|
||||
return crypto_scalarmult_ristretto255_SCALARBYTES
|
||||
}
|
||||
|
||||
function has_small_order (s) {
|
||||
assert(s instanceof Uint8Array && s.byteLength === 32)
|
||||
|
||||
const blacklist = [
|
||||
/* 0 (order 4) */
|
||||
[ 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) */
|
||||
[ 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 ],
|
||||
/* 325606250916557431795983626356110631294008115727848805560023387167927233504
|
||||
(order 8) */
|
||||
[ 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3,
|
||||
0xfa, 0xf1, 0x9f, 0xc4, 0x6a, 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32,
|
||||
0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00 ],
|
||||
/* 39382357235489614581723060781553021112529911719440698176882885853963445705823
|
||||
(order 8) */
|
||||
[ 0x5f, 0x9c, 0x95, 0xbc, 0xa3, 0x50, 0x8c, 0x24, 0xb1, 0xd0, 0xb1,
|
||||
0x55, 0x9c, 0x83, 0xef, 0x5b, 0x04, 0x44, 0x5c, 0xc4, 0x58, 0x1c,
|
||||
0x8e, 0x86, 0xd8, 0x22, 0x4e, 0xdd, 0xd0, 0x9f, 0x11, 0x57 ],
|
||||
/* p-1 (order 2) */
|
||||
[ 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) */
|
||||
[ 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) */
|
||||
[ 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 ]
|
||||
]
|
||||
|
||||
const c = Buffer.alloc(7)
|
||||
|
||||
var k
|
||||
var i, j
|
||||
|
||||
assert(blacklist.length === 7)
|
||||
for (j = 0; j < 31; j++) {
|
||||
for (i = 0; i < 7; i++) {
|
||||
c[i] |= s[j] ^ blacklist[i][j]
|
||||
}
|
||||
}
|
||||
for (i = 0; i < 7; i++) {
|
||||
c[i] |= (s[j] & 0x7f) ^ blacklist[i][j]
|
||||
}
|
||||
k = 0
|
||||
for (i = 0; i < 7; i++) {
|
||||
k |= (c[i] - 1)
|
||||
}
|
||||
return ((k >> 8) & 1)
|
||||
}
|
||||
|
||||
function crypto_scalarmult_curve25519 (q, n, p) {
|
||||
var t = q.slice()
|
||||
var i
|
||||
var x1 = ec.fe25519()
|
||||
var x2 = ec.fe25519()
|
||||
var z2 = ec.fe25519()
|
||||
var x3 = ec.fe25519()
|
||||
var z3 = ec.fe25519()
|
||||
var tmp0 = ec.fe25519()
|
||||
var tmp1 = ec.fe25519()
|
||||
var pos
|
||||
var swap
|
||||
var b
|
||||
|
||||
if (has_small_order(p)) {
|
||||
return -1;
|
||||
}
|
||||
for (i = 0; i < 32; i++) {
|
||||
t[i] = n[i]
|
||||
}
|
||||
t[0] &= 248
|
||||
t[31] &= 127
|
||||
t[31] |= 64
|
||||
ec.fe25519_frombytes(x1, p)
|
||||
ec.fe25519_1(x2)
|
||||
ec.fe25519_0(z2)
|
||||
ec.fe25519_copy(x3, x1)
|
||||
ec.fe25519_1(z3)
|
||||
|
||||
for (pos = 254; pos >= 0; --pos) {
|
||||
b = t[Math.floor(pos / 8)] >> (pos & 7)
|
||||
b &= 1
|
||||
swap ^= b
|
||||
|
||||
ec.fe25519_cswap(x2, x3, swap)
|
||||
ec.fe25519_cswap(z2, z3, swap)
|
||||
swap = b
|
||||
ec.fe25519_sub(tmp0, x3, z3)
|
||||
|
||||
ec.fe25519_sub(tmp1, x2, z2)
|
||||
ec.fe25519_add(x2, x2, z2)
|
||||
ec.fe25519_add(z2, x3, z3)
|
||||
ec.fe25519_mul(z3, tmp0, x2)
|
||||
ec.fe25519_mul(z2, z2, tmp1)
|
||||
ec.fe25519_sq(tmp0, tmp1)
|
||||
ec.fe25519_sq(tmp1, x2)
|
||||
ec.fe25519_add(x3, z3, z2)
|
||||
ec.fe25519_sub(z2, z3, z2)
|
||||
ec.fe25519_mul(x2, tmp1, tmp0)
|
||||
ec.fe25519_sub(tmp1, tmp1, tmp0)
|
||||
ec.fe25519_sq(z2, z2)
|
||||
// TODO
|
||||
// ec.fe25519_mul32(z3, tmp1, 121666)
|
||||
ec.fe25519_mul(z3, tmp1, _121666)
|
||||
ec.fe25519_sq(x3, x3)
|
||||
ec.fe25519_add(tmp0, tmp0, z3)
|
||||
ec.fe25519_mul(z3, x1, z2)
|
||||
ec.fe25519_mul(z2, tmp1, tmp0)
|
||||
}
|
||||
|
||||
ec.fe25519_cswap(x2, x3, swap)
|
||||
ec.fe25519_cswap(z2, z3, swap)
|
||||
|
||||
ec.fe25519_invert(z2, z2)
|
||||
ec.fe25519_mul(x2, x2, z2)
|
||||
ec.fe25519_tobytes(q, x2)
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
function crypto_scalarmult_curve25519_1 (q, n, p) {
|
||||
var t = q.slice()
|
||||
var i
|
||||
var x1 = ec.fe25519()
|
||||
var x2 = ec.fe25519()
|
||||
var z2 = ec.fe25519()
|
||||
var x3 = ec.fe25519()
|
||||
var z3 = ec.fe25519()
|
||||
var pos
|
||||
var swap
|
||||
var b
|
||||
var _q = Buffer.alloc(32)
|
||||
|
||||
if (has_small_order(p)) {
|
||||
return -1;
|
||||
}
|
||||
t.set(n)
|
||||
t[0] &= 248
|
||||
t[31] &= 127
|
||||
t[31] |= 64
|
||||
|
||||
ec.fe25519_frombytes(x1, p)
|
||||
swap = ec.scalarmult_curve25519_inner_loop(x1, x2, t)
|
||||
|
||||
ec.fe25519_tobytes(q, x2)
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
function edwards_to_montgomery(montgomeryX, edwardsY, edwardsZ) {
|
||||
var tempX = ec.fe25519()
|
||||
var tempZ = ec.fe25519()
|
||||
|
||||
ec.fe25519_add(tempX, edwardsZ, edwardsY)
|
||||
ec.fe25519_sub(tempZ, edwardsZ, edwardsY)
|
||||
ec.fe25519_invert(tempZ, tempZ)
|
||||
ec.fe25519_mul(montgomeryX, tempX, tempZ)
|
||||
}
|
||||
|
||||
function crypto_scalarmult_curve25519_base (q, n) {
|
||||
var t = q.slice()
|
||||
var Q = ec.ge3()
|
||||
const pk = ec.fe25519()
|
||||
|
||||
var i
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
t[i] = n[i]
|
||||
}
|
||||
|
||||
t[0] &= 248
|
||||
t[31] |= 64
|
||||
t[31] &= 127
|
||||
|
||||
ec.ge25519_scalarmult_base(Q, t)
|
||||
edwards_to_montgomery(pk, Q[1], Q[2]);
|
||||
ec.fe25519_tobytes(q, pk)
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
function print32 (num) {
|
||||
if (num < 0) return print32(0x100000000 + num)
|
||||
console.log(num.toString(16).padStart(16, '0'))
|
||||
}
|
||||
|
||||
function printfe (fe) {
|
||||
for (let i of fe) print32(i)
|
||||
}
|
||||
|
||||
function sodium_is_zero (n) {
|
||||
let i
|
||||
let d = 0
|
||||
|
||||
for (let i = 0; i < n.length; i++) {
|
||||
d |= n[i]
|
||||
}
|
||||
|
||||
return 1 & ((d - 1) >> 8)
|
||||
}
|
||||
@@ -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,271 @@
|
||||
/* eslint-disable camelcase */
|
||||
const assert = require('nanoassert')
|
||||
const { randombytes_buf } = require('./randombytes')
|
||||
const {
|
||||
crypto_stream_chacha20_ietf,
|
||||
crypto_stream_chacha20_ietf_xor,
|
||||
crypto_stream_chacha20_ietf_xor_ic,
|
||||
crypto_stream_chacha20_ietf_KEYBYTES
|
||||
} = require('./crypto_stream_chacha20')
|
||||
const { crypto_core_hchacha20, crypto_core_hchacha20_INPUTBYTES } = require('./internal/hchacha20')
|
||||
const Poly1305 = require('./internal/poly1305')
|
||||
const { sodium_increment, sodium_is_zero, sodium_memcmp } = require('./helpers')
|
||||
|
||||
const crypto_onetimeauth_poly1305_BYTES = 16
|
||||
const crypto_secretstream_xchacha20poly1305_COUNTERBYTES = 4
|
||||
const crypto_secretstream_xchacha20poly1305_INONCEBYTES = 8
|
||||
const crypto_aead_xchacha20poly1305_ietf_KEYBYTES = 32
|
||||
const crypto_secretstream_xchacha20poly1305_KEYBYTES = crypto_aead_xchacha20poly1305_ietf_KEYBYTES
|
||||
const crypto_aead_xchacha20poly1305_ietf_NPUBBYTES = 24
|
||||
const crypto_secretstream_xchacha20poly1305_HEADERBYTES = crypto_aead_xchacha20poly1305_ietf_NPUBBYTES
|
||||
const crypto_aead_xchacha20poly1305_ietf_ABYTES = 16
|
||||
const crypto_secretstream_xchacha20poly1305_ABYTES = 1 + crypto_aead_xchacha20poly1305_ietf_ABYTES
|
||||
const crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX = Number.MAX_SAFE_INTEGER
|
||||
const crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX = Number.MAX_SAFE_INTEGER
|
||||
const crypto_secretstream_xchacha20poly1305_TAGBYTES = 1
|
||||
const crypto_secretstream_xchacha20poly1305_TAG_MESSAGE = new Uint8Array([0])
|
||||
const crypto_secretstream_xchacha20poly1305_TAG_PUSH = new Uint8Array([1])
|
||||
const crypto_secretstream_xchacha20poly1305_TAG_REKEY = new Uint8Array([2])
|
||||
const crypto_secretstream_xchacha20poly1305_TAG_FINAL = new Uint8Array([crypto_secretstream_xchacha20poly1305_TAG_PUSH | crypto_secretstream_xchacha20poly1305_TAG_REKEY])
|
||||
const crypto_secretstream_xchacha20poly1305_STATEBYTES = crypto_secretstream_xchacha20poly1305_KEYBYTES +
|
||||
crypto_secretstream_xchacha20poly1305_INONCEBYTES + crypto_secretstream_xchacha20poly1305_COUNTERBYTES + 8
|
||||
|
||||
const KEY_OFFSET = 0
|
||||
const NONCE_OFFSET = crypto_secretstream_xchacha20poly1305_KEYBYTES
|
||||
const PAD_OFFSET = NONCE_OFFSET + crypto_secretstream_xchacha20poly1305_INONCEBYTES + crypto_secretstream_xchacha20poly1305_COUNTERBYTES
|
||||
|
||||
const _pad0 = new Uint8Array(16)
|
||||
|
||||
function STORE64_LE (dest, int) {
|
||||
let mul = 1
|
||||
let i = 0
|
||||
dest[0] = int & 0xFF
|
||||
while (++i < 8 && (mul *= 0x100)) {
|
||||
dest[i] = (int / mul) & 0xFF
|
||||
}
|
||||
}
|
||||
|
||||
function crypto_secretstream_xchacha20poly1305_counter_reset (state) {
|
||||
assert(state.byteLength === crypto_secretstream_xchacha20poly1305_STATEBYTES,
|
||||
'state is should be crypto_secretstream_xchacha20poly1305_STATEBYTES long')
|
||||
|
||||
const nonce = state.subarray(NONCE_OFFSET, PAD_OFFSET)
|
||||
for (let i = 0; i < crypto_secretstream_xchacha20poly1305_COUNTERBYTES; i++) {
|
||||
nonce[i] = 0
|
||||
}
|
||||
nonce[0] = 1
|
||||
}
|
||||
|
||||
function crypto_secretstream_xchacha20poly1305_keygen (k) {
|
||||
assert(k.length === crypto_secretstream_xchacha20poly1305_KEYBYTES)
|
||||
randombytes_buf(k)
|
||||
}
|
||||
|
||||
function crypto_secretstream_xchacha20poly1305_init_push (state, out, key) {
|
||||
assert(state.byteLength === crypto_secretstream_xchacha20poly1305_STATEBYTES,
|
||||
'state is should be crypto_secretstream_xchacha20poly1305_STATEBYTES long')
|
||||
assert(out instanceof Uint8Array && out.length === crypto_secretstream_xchacha20poly1305_HEADERBYTES, 'out not byte array of length crypto_secretstream_xchacha20poly1305_HEADERBYTES')
|
||||
assert(key instanceof Uint8Array && key.length === crypto_secretstream_xchacha20poly1305_KEYBYTES, 'key not byte array of length crypto_secretstream_xchacha20poly1305_KEYBYTES')
|
||||
|
||||
const k = state.subarray(KEY_OFFSET, NONCE_OFFSET)
|
||||
const nonce = state.subarray(NONCE_OFFSET, PAD_OFFSET)
|
||||
const pad = state.subarray(PAD_OFFSET)
|
||||
|
||||
randombytes_buf(out, crypto_secretstream_xchacha20poly1305_HEADERBYTES)
|
||||
crypto_core_hchacha20(k, out, key, null)
|
||||
crypto_secretstream_xchacha20poly1305_counter_reset(state)
|
||||
for (let i = 0; i < crypto_secretstream_xchacha20poly1305_INONCEBYTES; i++) {
|
||||
nonce[i + crypto_secretstream_xchacha20poly1305_COUNTERBYTES] = out[i + crypto_core_hchacha20_INPUTBYTES]
|
||||
}
|
||||
pad.fill(0)
|
||||
}
|
||||
|
||||
function crypto_secretstream_xchacha20poly1305_init_pull (state, _in, key) {
|
||||
assert(state.byteLength === crypto_secretstream_xchacha20poly1305_STATEBYTES,
|
||||
'state is should be crypto_secretstream_xchacha20poly1305_STATEBYTES long')
|
||||
assert(_in instanceof Uint8Array && _in.length === crypto_secretstream_xchacha20poly1305_HEADERBYTES,
|
||||
'_in not byte array of length crypto_secretstream_xchacha20poly1305_HEADERBYTES')
|
||||
assert(key instanceof Uint8Array && key.length === crypto_secretstream_xchacha20poly1305_KEYBYTES,
|
||||
'key not byte array of length crypto_secretstream_xchacha20poly1305_KEYBYTES')
|
||||
|
||||
const k = state.subarray(KEY_OFFSET, NONCE_OFFSET)
|
||||
const nonce = state.subarray(NONCE_OFFSET, PAD_OFFSET)
|
||||
const pad = state.subarray(PAD_OFFSET)
|
||||
|
||||
crypto_core_hchacha20(k, _in, key, null)
|
||||
crypto_secretstream_xchacha20poly1305_counter_reset(state)
|
||||
|
||||
for (let i = 0; i < crypto_secretstream_xchacha20poly1305_INONCEBYTES; i++) {
|
||||
nonce[i + crypto_secretstream_xchacha20poly1305_COUNTERBYTES] = _in[i + crypto_core_hchacha20_INPUTBYTES]
|
||||
}
|
||||
pad.fill(0)
|
||||
}
|
||||
|
||||
function crypto_secretstream_xchacha20poly1305_rekey (state) {
|
||||
assert(state.byteLength === crypto_secretstream_xchacha20poly1305_STATEBYTES,
|
||||
'state is should be crypto_secretstream_xchacha20poly1305_STATEBYTES long')
|
||||
|
||||
const k = state.subarray(KEY_OFFSET, NONCE_OFFSET)
|
||||
const nonce = state.subarray(NONCE_OFFSET, PAD_OFFSET)
|
||||
|
||||
const new_key_and_inonce = new Uint8Array(
|
||||
crypto_stream_chacha20_ietf_KEYBYTES + crypto_secretstream_xchacha20poly1305_INONCEBYTES)
|
||||
let i
|
||||
for (i = 0; i < crypto_stream_chacha20_ietf_KEYBYTES; i++) {
|
||||
new_key_and_inonce[i] = k[i]
|
||||
}
|
||||
for (i = 0; i < crypto_secretstream_xchacha20poly1305_INONCEBYTES; i++) {
|
||||
new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + i] =
|
||||
nonce[crypto_secretstream_xchacha20poly1305_COUNTERBYTES + i]
|
||||
}
|
||||
crypto_stream_chacha20_ietf_xor(new_key_and_inonce, new_key_and_inonce, nonce, k)
|
||||
for (i = 0; i < crypto_stream_chacha20_ietf_KEYBYTES; i++) {
|
||||
k[i] = new_key_and_inonce[i]
|
||||
}
|
||||
for (i = 0; i < crypto_secretstream_xchacha20poly1305_INONCEBYTES; i++) {
|
||||
nonce[crypto_secretstream_xchacha20poly1305_COUNTERBYTES + i] =
|
||||
new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + i]
|
||||
}
|
||||
crypto_secretstream_xchacha20poly1305_counter_reset(state)
|
||||
}
|
||||
|
||||
function crypto_secretstream_xchacha20poly1305_push (state, out, m, ad, tag) {
|
||||
assert(state.byteLength === crypto_secretstream_xchacha20poly1305_STATEBYTES,
|
||||
'state is should be crypto_secretstream_xchacha20poly1305_STATEBYTES long')
|
||||
if (!ad) ad = new Uint8Array(0)
|
||||
|
||||
const k = state.subarray(KEY_OFFSET, NONCE_OFFSET)
|
||||
const nonce = state.subarray(NONCE_OFFSET, PAD_OFFSET)
|
||||
|
||||
const block = new Uint8Array(64)
|
||||
const slen = new Uint8Array(8)
|
||||
|
||||
assert(crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX <=
|
||||
crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX)
|
||||
|
||||
crypto_stream_chacha20_ietf(block, nonce, k)
|
||||
const poly = new Poly1305(block)
|
||||
block.fill(0)
|
||||
|
||||
poly.update(ad, 0, ad.byteLength)
|
||||
poly.update(_pad0, 0, (0x10 - ad.byteLength) & 0xf)
|
||||
|
||||
block[0] = tag[0]
|
||||
crypto_stream_chacha20_ietf_xor_ic(block, block, nonce, 1, k)
|
||||
|
||||
poly.update(block, 0, block.byteLength)
|
||||
out[0] = block[0]
|
||||
|
||||
const c = out.subarray(1, out.byteLength)
|
||||
crypto_stream_chacha20_ietf_xor_ic(c, m, nonce, 2, k)
|
||||
poly.update(c, 0, m.byteLength)
|
||||
poly.update(_pad0, 0, (0x10 - block.byteLength + m.byteLength) & 0xf)
|
||||
|
||||
STORE64_LE(slen, ad.byteLength)
|
||||
poly.update(slen, 0, slen.byteLength)
|
||||
STORE64_LE(slen, block.byteLength + m.byteLength)
|
||||
poly.update(slen, 0, slen.byteLength)
|
||||
|
||||
const mac = out.subarray(1 + m.byteLength, out.byteLength)
|
||||
poly.finish(mac, 0)
|
||||
|
||||
assert(crypto_onetimeauth_poly1305_BYTES >=
|
||||
crypto_secretstream_xchacha20poly1305_INONCEBYTES)
|
||||
xor_buf(nonce.subarray(crypto_secretstream_xchacha20poly1305_COUNTERBYTES, nonce.length),
|
||||
mac, crypto_secretstream_xchacha20poly1305_INONCEBYTES)
|
||||
sodium_increment(nonce)
|
||||
|
||||
if ((tag[0] & crypto_secretstream_xchacha20poly1305_TAG_REKEY) !== 0 ||
|
||||
sodium_is_zero(nonce.subarray(0, crypto_secretstream_xchacha20poly1305_COUNTERBYTES))) {
|
||||
crypto_secretstream_xchacha20poly1305_rekey(state)
|
||||
}
|
||||
|
||||
return crypto_secretstream_xchacha20poly1305_ABYTES + m.byteLength
|
||||
}
|
||||
|
||||
function crypto_secretstream_xchacha20poly1305_pull (state, m, tag, _in, ad) {
|
||||
assert(state.byteLength === crypto_secretstream_xchacha20poly1305_STATEBYTES,
|
||||
'state is should be crypto_secretstream_xchacha20poly1305_STATEBYTES long')
|
||||
if (!ad) ad = new Uint8Array(0)
|
||||
|
||||
const k = state.subarray(KEY_OFFSET, NONCE_OFFSET)
|
||||
const nonce = state.subarray(NONCE_OFFSET, PAD_OFFSET)
|
||||
|
||||
const block = new Uint8Array(64)
|
||||
const slen = new Uint8Array(8)
|
||||
const mac = new Uint8Array(crypto_onetimeauth_poly1305_BYTES)
|
||||
|
||||
assert(_in.byteLength >= crypto_secretstream_xchacha20poly1305_ABYTES,
|
||||
'ciphertext is too short.')
|
||||
|
||||
const mlen = _in.byteLength - crypto_secretstream_xchacha20poly1305_ABYTES
|
||||
crypto_stream_chacha20_ietf(block, nonce, k)
|
||||
const poly = new Poly1305(block)
|
||||
block.fill(0) // sodium_memzero(block, sizeof block);
|
||||
|
||||
poly.update(ad, 0, ad.byteLength)
|
||||
poly.update(_pad0, 0, (0x10 - ad.byteLength) & 0xf)
|
||||
|
||||
block.fill(0) // memset(block, 0, sizeof block);
|
||||
block[0] = _in[0]
|
||||
crypto_stream_chacha20_ietf_xor_ic(block, block, nonce, 1, k)
|
||||
|
||||
tag[0] = block[0]
|
||||
block[0] = _in[0]
|
||||
poly.update(block, 0, block.byteLength)
|
||||
|
||||
const c = _in.subarray(1, _in.length)
|
||||
poly.update(c, 0, mlen)
|
||||
|
||||
poly.update(_pad0, 0, (0x10 - block.byteLength + mlen) & 0xf)
|
||||
|
||||
STORE64_LE(slen, ad.byteLength)
|
||||
poly.update(slen, 0, slen.byteLength)
|
||||
STORE64_LE(slen, block.byteLength + m.byteLength)
|
||||
poly.update(slen, 0, slen.byteLength)
|
||||
|
||||
poly.finish(mac, 0)
|
||||
const stored_mac = _in.subarray(1 + mlen, _in.length)
|
||||
|
||||
if (!sodium_memcmp(mac, stored_mac)) {
|
||||
mac.fill(0)
|
||||
throw new Error('MAC could not be verified.')
|
||||
}
|
||||
|
||||
crypto_stream_chacha20_ietf_xor_ic(m, c.subarray(0, m.length), nonce, 2, k)
|
||||
xor_buf(nonce.subarray(crypto_secretstream_xchacha20poly1305_COUNTERBYTES, nonce.length),
|
||||
mac, crypto_secretstream_xchacha20poly1305_INONCEBYTES)
|
||||
sodium_increment(nonce)
|
||||
|
||||
if ((tag & crypto_secretstream_xchacha20poly1305_TAG_REKEY) !== 0 ||
|
||||
sodium_is_zero(nonce.subarray(0, crypto_secretstream_xchacha20poly1305_COUNTERBYTES))) {
|
||||
crypto_secretstream_xchacha20poly1305_rekey(state)
|
||||
}
|
||||
|
||||
return mlen
|
||||
}
|
||||
|
||||
function xor_buf (out, _in, n) {
|
||||
for (let i = 0; i < n; i++) {
|
||||
out[i] ^= _in[i]
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
crypto_secretstream_xchacha20poly1305_keygen,
|
||||
crypto_secretstream_xchacha20poly1305_init_push,
|
||||
crypto_secretstream_xchacha20poly1305_init_pull,
|
||||
crypto_secretstream_xchacha20poly1305_rekey,
|
||||
crypto_secretstream_xchacha20poly1305_push,
|
||||
crypto_secretstream_xchacha20poly1305_pull,
|
||||
crypto_secretstream_xchacha20poly1305_STATEBYTES,
|
||||
crypto_secretstream_xchacha20poly1305_ABYTES,
|
||||
crypto_secretstream_xchacha20poly1305_HEADERBYTES,
|
||||
crypto_secretstream_xchacha20poly1305_KEYBYTES,
|
||||
crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX,
|
||||
crypto_secretstream_xchacha20poly1305_TAGBYTES,
|
||||
crypto_secretstream_xchacha20poly1305_TAG_MESSAGE,
|
||||
crypto_secretstream_xchacha20poly1305_TAG_PUSH,
|
||||
crypto_secretstream_xchacha20poly1305_TAG_REKEY,
|
||||
crypto_secretstream_xchacha20poly1305_TAG_FINAL
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
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
|
||||
|
||||
+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 = new Uint8Array(crypto_hash_sha512_BYTES)
|
||||
crypto_hash(h, edSk, 32)
|
||||
|
||||
h[0] &= 248
|
||||
h[31] &= 127
|
||||
h[31] |= 64
|
||||
|
||||
curveSk.set(h.subarray(0, crypto_scalarmult_BYTES))
|
||||
h.fill(0)
|
||||
return curveSk
|
||||
}
|
||||
|
||||
function check (buf, len, arg = 'Argument') {
|
||||
if (!buf || (len && buf.length < len)) throw new Error(arg + ' must be a buffer' + (len ? ' of length ' + len : ''))
|
||||
}
|
||||
+2050
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,377 @@
|
||||
const { sodium_memzero } = require('./utils')
|
||||
const { randombytes_buf } = require('./randombytes')
|
||||
const ec = require('./fe25519_25')
|
||||
const {
|
||||
crypto_hash_sha512,
|
||||
crypto_hash_sha512_update,
|
||||
crypto_hash_sha512_state,
|
||||
crypto_hash_sha512_final,
|
||||
crypto_hash_sha512_BYTES
|
||||
} = require('./crypto_hash.js')
|
||||
const { crypto_verify_32 } = require('./crypto_verify')
|
||||
const {
|
||||
crypto_scalarmult_base,
|
||||
crypto_scalarmult_curve25519_BYTES
|
||||
} = require('./crypto_scalarmult_ed25519')
|
||||
|
||||
var crypto_sign_ed25519_BYTES = 64
|
||||
var crypto_sign_ed25519_SEEDBYTES = 32
|
||||
var crypto_sign_ed25519_PUBLICKEYBYTES = 32
|
||||
var crypto_sign_ed25519_SECRETKEYBYTES = 64
|
||||
var crypto_sign_ed25519_MESSAGEBYTES_MAX = Number.MAX_SAFE_INTEGER
|
||||
|
||||
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
|
||||
|
||||
|
||||
function crypto_sign_seed_keypair (pk, sk, seed) {
|
||||
const A = ec.ge25519_p3()
|
||||
|
||||
crypto_hash_sha512(sk, seed, 32)
|
||||
sk[0] &= 248
|
||||
sk[31] &= 127
|
||||
sk[31] |= 64
|
||||
|
||||
ec.ge25519_scalarmult_base(A, sk)
|
||||
ec.ge25519_p3_tobytes(pk, A)
|
||||
|
||||
sk.set(seed)
|
||||
sk.set(pk, 32)
|
||||
}
|
||||
|
||||
function crypto_sign_keypair (pk, sk) {
|
||||
const seed = Buffer.alloc(32)
|
||||
|
||||
randombytes_buf(seed)
|
||||
crypto_sign_seed_keypair(pk, sk, seed)
|
||||
sodium_memzero(seed)
|
||||
}
|
||||
|
||||
function crypto_sign_ed25519_pk_to_curve25519 (curve25519_pk, ed25519_pk) {
|
||||
const A = ec.ge25519_p3()
|
||||
const x = ec.fe25519()
|
||||
const one_minus_y = ec.fe25519()
|
||||
|
||||
if (ec.ge25519_has_small_order(ed25519_pk) != 0 ||
|
||||
ec.ge25519_frombytes_negate_vartime(A, ed25519_pk) != 0 ||
|
||||
ec.ge25519_is_on_main_subgroup(A) == 0) {
|
||||
throw new Error('Invalid public key')
|
||||
}
|
||||
|
||||
ec.fe25519_1(one_minus_y)
|
||||
ec.fe25519_sub(one_minus_y, one_minus_y, A[1])
|
||||
ec.fe25519_1(x)
|
||||
ec.fe25519_add(x, x, A[1])
|
||||
ec.fe25519_invert(one_minus_y, one_minus_y)
|
||||
ec.fe25519_mul(x, x, one_minus_y)
|
||||
ec.fe25519_tobytes(curve25519_pk, x)
|
||||
}
|
||||
|
||||
function crypto_sign_ed25519_sk_to_curve25519 (curve25519_sk, ed25519_sk) {
|
||||
const h = Buffer.alloc(crypto_hash_sha512_BYTES)
|
||||
|
||||
crypto_hash_sha512(h, ed25519_sk, 32)
|
||||
h[0] &= 248
|
||||
h[31] &= 127
|
||||
h[31] |= 64
|
||||
curve25519_sk.set(h.subarray(0, crypto_scalarmult_curve25519_BYTES))
|
||||
|
||||
sodium_memzero(h)
|
||||
}
|
||||
|
||||
function _crypto_sign_ed25519_ref10_hinit (hs, prehashed) {
|
||||
const DOM2PREFIX = Buffer.from('SigEd25519 no Ed25519 collisions ')
|
||||
DOM2PREFIX[30] = 1
|
||||
DOM2PREFIX[31] = 0
|
||||
|
||||
if (prehashed) {
|
||||
crypto_hash_sha512_update(hs, DOM2PREFIX, DOM2PREFIX.byteLength)
|
||||
}
|
||||
}
|
||||
|
||||
function _crypto_sign_ed25519_clamp (k) {
|
||||
k[0] &= 248
|
||||
k[31] &= 127
|
||||
k[31] |= 64
|
||||
}
|
||||
|
||||
function _crypto_sign_ed25519_detached (sig, m, sk, prehashed) {
|
||||
var state = crypto_hash_sha512_state()
|
||||
var az = Buffer.alloc(64)
|
||||
var nonce = Buffer.alloc(64)
|
||||
var hram = Buffer.alloc(64)
|
||||
var R = ec.ge3()
|
||||
|
||||
_crypto_sign_ed25519_ref10_hinit(state, prehashed)
|
||||
|
||||
crypto_hash_sha512(az, sk, 32)
|
||||
crypto_hash_sha512_update(state, az.subarray(32), 32)
|
||||
crypto_hash_sha512_update(state, m)
|
||||
crypto_hash_sha512_final(state, nonce)
|
||||
|
||||
sig.set(sk.subarray(32, 64), 32)
|
||||
|
||||
ec.sc25519_reduce(nonce)
|
||||
ec.ge25519_scalarmult_base(R, nonce)
|
||||
ec.ge25519_p3_tobytes(sig, R)
|
||||
|
||||
state = crypto_hash_sha512_state()
|
||||
_crypto_sign_ed25519_ref10_hinit(state, prehashed)
|
||||
crypto_hash_sha512_update(state, sig, 64)
|
||||
crypto_hash_sha512_update(state, m)
|
||||
crypto_hash_sha512_final(state, hram)
|
||||
|
||||
ec.sc25519_reduce(hram)
|
||||
_crypto_sign_ed25519_clamp(az)
|
||||
ec.sc25519_muladd(sig.subarray(32), hram, az, nonce)
|
||||
|
||||
sodium_memzero(az)
|
||||
sodium_memzero(nonce)
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
function crypto_sign_ed25519_detached (sig, m, sk) {
|
||||
return _crypto_sign_ed25519_detached(sig, m, sk, 0)
|
||||
}
|
||||
|
||||
function crypto_sign_detached (sig, m, sk) {
|
||||
return _crypto_sign_ed25519_detached(sig, m, sk, 0)
|
||||
}
|
||||
|
||||
function crypto_sign_ed25519 (sm, m, sk) {
|
||||
sm.set(m, crypto_sign_ed25519_BYTES)
|
||||
|
||||
/* LCOV_EXCL_START */
|
||||
if (crypto_sign_detached(sm, sm.subarray(crypto_sign_ed25519_BYTES), sk) !== 0) {
|
||||
sm.fill(0, m.byteLength + crypto_sign_ed25519_BYTES)
|
||||
return -1
|
||||
}
|
||||
/* LCOV_EXCL_STOP */
|
||||
return m.byteLength + 64
|
||||
}
|
||||
|
||||
function crypto_sign (sm, m, sk) {
|
||||
return crypto_sign_ed25519(sm, m, sk)
|
||||
}
|
||||
|
||||
function _crypto_sign_ed25519_verify_detached(sig, m, pk, prehashed) {
|
||||
var hs = crypto_hash_sha512_state()
|
||||
var h = Buffer.alloc(64)
|
||||
var rcheck = Buffer.alloc(32)
|
||||
var A = ec.ge3()
|
||||
var R = ec.ge2()
|
||||
|
||||
if ((sig[63] & 240) &&
|
||||
ec.sc25519_is_canonical(sig + 32) == 0) {
|
||||
return false
|
||||
}
|
||||
if (ec.ge25519_has_small_order(sig.subarray(0, 32)) != 0) {
|
||||
return false
|
||||
}
|
||||
if (ec.ge25519_is_canonical(pk) == 0 ||
|
||||
ec.ge25519_has_small_order(pk) != 0) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (ec.ge25519_frombytes_negate_vartime(A, pk) !== 0) {
|
||||
}
|
||||
ec.ge25519_tobytes(rcheck, A)
|
||||
|
||||
_crypto_sign_ed25519_ref10_hinit(hs, prehashed)
|
||||
crypto_hash_sha512_update(hs, sig, 32)
|
||||
crypto_hash_sha512_update(hs, pk, 32)
|
||||
crypto_hash_sha512_update(hs, m)
|
||||
crypto_hash_sha512_final(hs, h)
|
||||
ec.sc25519_reduce(h)
|
||||
|
||||
ec.ge25519_double_scalarmult_vartime(R, h, A, sig.subarray(32))
|
||||
ec.ge25519_tobytes(rcheck, R)
|
||||
|
||||
return crypto_verify_32(rcheck, 0, sig, 0)
|
||||
}
|
||||
|
||||
function crypto_sign_ed25519_verify_detached (sig, m, pk) {
|
||||
return _crypto_sign_ed25519_verify_detached(sig, m, pk, 0);
|
||||
}
|
||||
|
||||
function crypto_sign_ed25519_open (m, sm, pk) {
|
||||
if (sm.byteLength < 64 || sm.byteLength - 64 > crypto_sign_ed25519_MESSAGEBYTES_MAX) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (!crypto_sign_ed25519_verify_detached(sm, sm.subarray(64), pk)) {
|
||||
if (m.byteLength) m.fill(0)
|
||||
return false
|
||||
}
|
||||
|
||||
if (m.byteLength) {
|
||||
m.set(sm.subarray(64))
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
function crypto_sign_ed25519_sk_to_pk (pk, sk) {
|
||||
pk.set(sk.subarray(crypto_sign_ed25519_SEEDBYTES))
|
||||
}
|
||||
|
||||
function crypto_sign_open (m, sm, pk) {
|
||||
return crypto_sign_ed25519_open(m, sm, pk)
|
||||
}
|
||||
|
||||
function crypto_sign_verify_detached (m, sm, pk) {
|
||||
return crypto_sign_ed25519_verify_detached(m, sm, pk)
|
||||
}
|
||||
|
||||
function _crypto_sign_ristretto25519_detached (sig, m, sk, prehashed) {
|
||||
var state = crypto_hash_sha512_state()
|
||||
var az = Buffer.alloc(64)
|
||||
var nonce = Buffer.alloc(64)
|
||||
var hram = Buffer.alloc(64)
|
||||
var R = ec.ge3()
|
||||
|
||||
_crypto_sign_ed25519_ref10_hinit(state, prehashed)
|
||||
|
||||
crypto_hash_sha512(az, sk, 32)
|
||||
crypto_hash_sha512_update(state, az.subarray(32), 32)
|
||||
crypto_hash_sha512_update(state, m)
|
||||
crypto_hash_sha512_final(state, nonce)
|
||||
|
||||
sig.set(sk.subarray(32, 64), 32)
|
||||
|
||||
ec.sc25519_reduce(nonce)
|
||||
ec.ge25519_scalarmult_base(R, nonce)
|
||||
ec.ristretto255_p3_tobytes(sig, R)
|
||||
|
||||
state = crypto_hash_sha512_state()
|
||||
_crypto_sign_ed25519_ref10_hinit(state, prehashed)
|
||||
crypto_hash_sha512_update(state, sig, 64)
|
||||
crypto_hash_sha512_update(state, m)
|
||||
crypto_hash_sha512_final(state, hram)
|
||||
|
||||
ec.sc25519_reduce(hram)
|
||||
az[31] &= 127
|
||||
// az[0] &= 248
|
||||
// az[0] |= 1
|
||||
// console.log(az[31] & 128)
|
||||
// console.log(nonce[31] & 128)
|
||||
// console.log(hram[31] & 128)
|
||||
ec.sc25519_muladd(sig.subarray(32), hram, az, nonce)
|
||||
|
||||
sodium_memzero(az)
|
||||
sodium_memzero(nonce)
|
||||
|
||||
return 0
|
||||
|
||||
var rcheck = Buffer.alloc(32)
|
||||
var A = ec.ge3()
|
||||
var _A = ec.ge3()
|
||||
var h = Buffer.alloc(64)
|
||||
var hs = crypto_hash_sha512_state()
|
||||
var pk = sk.subarray(32).slice()
|
||||
// pk[31] &= 127
|
||||
ec.ristretto255_frombytes(A, pk, true)
|
||||
ec.ge25519_scalarmult_base(_A, az)
|
||||
ec.ge25519_p3_add(_A, _A, A)
|
||||
ec.ge25519_p3_tobytes(rcheck, _A)
|
||||
// console.log(rcheck.toString('hex'))
|
||||
|
||||
_crypto_sign_ed25519_ref10_hinit(hs, prehashed)
|
||||
crypto_hash_sha512_update(hs, sig, 32)
|
||||
crypto_hash_sha512_update(hs, pk, 32)
|
||||
crypto_hash_sha512_update(hs, m)
|
||||
crypto_hash_sha512_final(hs, h)
|
||||
ec.sc25519_reduce(h)
|
||||
|
||||
ec.ge25519_double_scalarmult_vartime(R, h, A, sig.subarray(32))
|
||||
ec.ristretto255_p3_tobytes(rcheck, R)
|
||||
|
||||
}
|
||||
|
||||
function _crypto_sign_ristretto25519_verify_detached(sig, m, pk, prehashed) {
|
||||
var hs = crypto_hash_sha512_state()
|
||||
var h = Buffer.alloc(64)
|
||||
var rcheck = Buffer.alloc(32)
|
||||
var A = ec.ge3()
|
||||
var R = ec.ge3()
|
||||
|
||||
// #ifdef ED25519_COMPAT
|
||||
// if (sig[63] & 224) {
|
||||
// return -1
|
||||
// }
|
||||
// #else
|
||||
if ((sig[63] & 240) &&
|
||||
ec.sc25519_is_canonical(sig + 32) == 0) {
|
||||
return false
|
||||
}
|
||||
if (ec.ge25519_has_small_order(sig) != 0) {
|
||||
return false
|
||||
}
|
||||
if (ec.ge25519_is_canonical(pk) == 0 ||
|
||||
ec.ge25519_has_small_order(pk) != 0) {
|
||||
return false
|
||||
}
|
||||
// #endif
|
||||
if (ec.ristretto255_frombytes(A, pk, true) !== 0) {
|
||||
return false
|
||||
}
|
||||
|
||||
_crypto_sign_ed25519_ref10_hinit(hs, prehashed)
|
||||
crypto_hash_sha512_update(hs, sig, 32)
|
||||
crypto_hash_sha512_update(hs, pk, 32)
|
||||
crypto_hash_sha512_update(hs, m)
|
||||
crypto_hash_sha512_final(hs, h)
|
||||
ec.sc25519_reduce(h)
|
||||
|
||||
ec.ge25519_double_scalarmult_vartime(R, h, A, sig.subarray(32))
|
||||
ec.ristretto255_p3_tobytes(rcheck, R)
|
||||
|
||||
return crypto_verify_32(rcheck, 0, sig, 0)// | sodium_memcmp(sig.subarray(0, 32), rcheck.subarray(0, 32))
|
||||
}
|
||||
|
||||
function crypto_sign_ristretto25519_detached (sig, m, sk) {
|
||||
return _crypto_sign_ristretto25519_detached(sig, m, sk)
|
||||
}
|
||||
|
||||
function crypto_sign_ristretto25519_verify_detached (sig, m, pk) {
|
||||
return _crypto_sign_ristretto25519_verify_detached(sig, m, pk, 0)
|
||||
}
|
||||
|
||||
function crypto_sign_ristretto25519 (sm, m, sk) {
|
||||
var siglen
|
||||
|
||||
sm.set(m.subarray(0, mlen), crypto_sign_ristretto25519_BYTES)
|
||||
|
||||
/* LCOV_EXCL_START */
|
||||
if (crypto_sign_ristretto25519_detached(sm, sm.subarray(crypto_sign_ristretto25519_BYTES), mlen, sk) !== 0) {
|
||||
sm.fill(0, mlen + crypto_sign_ristretto25519_BYTES)
|
||||
return -1
|
||||
}
|
||||
/* LCOV_EXCL_STOP */
|
||||
return m.byteLength + 64
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
crypto_sign_keypair,
|
||||
crypto_sign_seed_keypair,
|
||||
crypto_sign_ed25519_pk_to_curve25519,
|
||||
crypto_sign_ed25519_sk_to_curve25519,
|
||||
crypto_sign_ed25519_sk_to_pk,
|
||||
crypto_sign,
|
||||
crypto_sign_open,
|
||||
crypto_sign_ed25519_detached,
|
||||
crypto_sign_detached,
|
||||
crypto_sign_ristretto25519_detached,
|
||||
crypto_sign_ristretto25519_verify_detached,
|
||||
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
|
||||
}
|
||||
+14
-7
@@ -1,17 +1,24 @@
|
||||
var xsalsa20 = require('xsalsa20')
|
||||
/* eslint-disable camelcase */
|
||||
const xsalsa20 = require('xsalsa20')
|
||||
|
||||
if (new Uint16Array([1])[0] !== 1) throw new Error('Big endian architecture is not supported.')
|
||||
|
||||
if (new Uint16Array([1])[0] !== 1) throw new Error('Big endian architecture is not supported.')
|
||||
|
||||
exports.crypto_stream_KEYBYTES = 32
|
||||
exports.crypto_stream_NONCEBYTES = 24
|
||||
exports.crypto_stream_PRIMITIVE = 'xsalsa20'
|
||||
exports.crypto_stream_xsalsa20_MESSAGEBYTES_MAX = Number.MAX_SAFE_INTEGER
|
||||
|
||||
exports.crypto_stream = function (out, nonce, key) {
|
||||
out.fill(0)
|
||||
exports.crypto_stream_xor(out, out, nonce, key)
|
||||
exports.crypto_stream = function (c, nonce, key) {
|
||||
c.fill(0)
|
||||
exports.crypto_stream_xor(c, c, nonce, key)
|
||||
}
|
||||
|
||||
exports.crypto_stream_xor = function (out, inp, nonce, key) {
|
||||
var xor = xsalsa20(nonce, key)
|
||||
xor.update(inp, out)
|
||||
exports.crypto_stream_xor = function (c, m, nonce, key) {
|
||||
const xor = xsalsa20(nonce, key)
|
||||
|
||||
xor.update(m, c)
|
||||
xor.final()
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
+216
@@ -0,0 +1,216 @@
|
||||
const b4a = require('b4a')
|
||||
|
||||
const {
|
||||
crypto_scalarmult_ed25519,
|
||||
crypto_scalarmult_ed25519_noclamp,
|
||||
crypto_scalarmult_ed25519_base,
|
||||
crypto_scalarmult_ed25519_base_noclamp,
|
||||
crypto_scalarmult_ed25519_SCALARBYTES
|
||||
} = require('./crypto_scalarmult_ed25519')
|
||||
|
||||
const {
|
||||
crypto_sign_keypair_seed,
|
||||
crypto_sign_ed25519_PUBLICKEYBYTES
|
||||
} = require('./crypto_sign_ed25519')
|
||||
|
||||
const {
|
||||
crypto_hash_sha512_state,
|
||||
crypto_hash_sha512_update,
|
||||
crypto_hash_sha512_final,
|
||||
crypto_hash
|
||||
} = require('./crypto_hash')
|
||||
|
||||
const {
|
||||
crypto_core_ed25519_is_valid_point,
|
||||
crypto_core_ed25519_scalar_reduce,
|
||||
crypto_core_ed25519_scalar_add,
|
||||
crypto_core_ed25519_scalar_mul,
|
||||
crypto_core_ed25519_add
|
||||
} = require('./crypto_core')
|
||||
|
||||
const { curve25519_h: COFACTOR } = require('./fe25519_25')
|
||||
|
||||
const { sodium_memzero } = require('./utils')
|
||||
|
||||
/*
|
||||
*EXPERIMENTAL API*
|
||||
|
||||
This module is an experimental implementation of a key tweaking protocol
|
||||
over ed25519 keys. The signature algorithm has been reimplemented from
|
||||
libsodium, but the nonce generation algorithm is *non-standard*.
|
||||
|
||||
Use at your own risk
|
||||
*/
|
||||
|
||||
const crypto_tweak_ed25519_BYTES = crypto_sign_ed25519_PUBLICKEYBYTES
|
||||
const crypto_tweak_ed25519_SCALARBYTES = crypto_scalarmult_ed25519_SCALARBYTES
|
||||
|
||||
function _crypto_tweak_nonce (nonce, n, m, mlen) {
|
||||
// dom2(x, y) with x = 0 (not prehashed) and y = "crypto_tweak_ed25519"
|
||||
const prefix = b4a.alloc(54)
|
||||
|
||||
prefix.write('SigEd25519 no Ed25519 collisions\x00\x14crypto_tweak_ed25519')
|
||||
|
||||
const hs = crypto_hash_sha512_state()
|
||||
|
||||
crypto_hash_sha512_update(hs, prefix)
|
||||
crypto_hash_sha512_update(hs, n, 32)
|
||||
crypto_hash_sha512_update(hs, m, m.byteLength)
|
||||
crypto_hash_sha512_final(hs, nonce)
|
||||
}
|
||||
|
||||
function _crypto_sign_ed25519_clamp (k) {
|
||||
k[0] &= 248
|
||||
k[31] &= 127
|
||||
k[31] |= 64
|
||||
}
|
||||
|
||||
function _crypto_tweak_ed25519(q, n, ns) {
|
||||
sodium_memzero(q)
|
||||
|
||||
crypto_hash(n, ns)
|
||||
n[31] &= 127 // clear highest bit
|
||||
|
||||
crypto_scalarmult_ed25519_base_noclamp(q, n)
|
||||
|
||||
// hash tweak until we get a valid tweaked q
|
||||
while (crypto_core_ed25519_is_valid_point(q) != 1) {
|
||||
crypto_hash(n, n, 32)
|
||||
n[31] &= 127 // clear highest bit
|
||||
|
||||
crypto_scalarmult_ed25519_base_noclamp(q, n)
|
||||
}
|
||||
}
|
||||
|
||||
function crypto_tweak_ed25519_base (n, q, ns) {
|
||||
sodium_memzero(q)
|
||||
|
||||
const n64 = b4a.alloc(64)
|
||||
_crypto_tweak_ed25519(q, n64, ns)
|
||||
|
||||
n.set(n64.subarray(0, 32))
|
||||
}
|
||||
|
||||
// TODO: check pk is correct if we pass it
|
||||
function crypto_tweak_ed25519_sign_detached (sig, m, n, pk = null) {
|
||||
const hs = crypto_hash_sha512_state()
|
||||
|
||||
const nonce = b4a.alloc(64)
|
||||
const R = b4a.alloc(32)
|
||||
const hram = b4a.alloc(64)
|
||||
const _pk = b4a.alloc(32)
|
||||
|
||||
// check if pk was passed
|
||||
if (pk === null) {
|
||||
pk = _pk
|
||||
|
||||
// derive pk from scalar
|
||||
crypto_scalarmult_ed25519_base_noclamp(pk, n)
|
||||
}
|
||||
|
||||
_crypto_tweak_nonce(nonce, n, m)
|
||||
crypto_core_ed25519_scalar_reduce(nonce, nonce)
|
||||
|
||||
// R = G ^ nonce : curve point from nonce
|
||||
crypto_scalarmult_ed25519_base_noclamp(R, nonce)
|
||||
|
||||
// generate challenge as h(ram) = hash(R, pk, message)
|
||||
crypto_hash_sha512_update(hs, R, 32)
|
||||
crypto_hash_sha512_update(hs, pk, 32)
|
||||
crypto_hash_sha512_update(hs, m, m.byteLength)
|
||||
|
||||
crypto_hash_sha512_final(hs, hram)
|
||||
|
||||
crypto_core_ed25519_scalar_reduce(hram, hram)
|
||||
|
||||
// sig = nonce + n * h(ram)
|
||||
crypto_core_ed25519_scalar_mul(sig.subarray(0, 32), hram.subarray(0, 32), n)
|
||||
crypto_core_ed25519_scalar_add(sig.subarray(32, 64), nonce.subarray(0, 32), sig)
|
||||
|
||||
sig.set(R)
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
// get scalar from secret key
|
||||
function crypto_tweak_ed25519_sk_to_scalar (n, sk) {
|
||||
const n64 = b4a.alloc(64)
|
||||
|
||||
// get sk scalar from seed, cf. crypto_sign_keypair_seed
|
||||
crypto_hash(n64, sk, 32)
|
||||
_crypto_sign_ed25519_clamp(n64)
|
||||
|
||||
n.set(n64.subarray(0, 32))
|
||||
}
|
||||
|
||||
// tweak a secret key
|
||||
function crypto_tweak_ed25519_scalar (scalar_out, scalar, ns) {
|
||||
const q = b4a.alloc(32)
|
||||
const n = b4a.alloc(64)
|
||||
|
||||
const n32 = n.subarray(0, 32)
|
||||
|
||||
_crypto_tweak_ed25519(q, n, ns)
|
||||
crypto_tweak_ed25519_scalar_add(scalar_out, n32, scalar)
|
||||
}
|
||||
|
||||
// tweak a public key
|
||||
function crypto_tweak_ed25519_pk (tpk, pk, ns) {
|
||||
const n = b4a.alloc(64)
|
||||
const q = b4a.alloc(32)
|
||||
|
||||
_crypto_tweak_ed25519(q, n, ns)
|
||||
return crypto_core_ed25519_add(tpk, q, pk)
|
||||
}
|
||||
|
||||
function crypto_tweak_ed25519_keypair (pk, scalar_out, scalar, ns) {
|
||||
const n64 = b4a.alloc(64)
|
||||
|
||||
crypto_hash(n64, ns)
|
||||
n64[31] &= 127 // clear highest bit
|
||||
|
||||
crypto_tweak_ed25519_scalar_add(scalar_out, scalar, n64)
|
||||
crypto_scalarmult_ed25519_base_noclamp(pk, scalar_out)
|
||||
|
||||
// hash tweak until we get a valid tweaked point
|
||||
while (crypto_core_ed25519_is_valid_point(pk) != 1) {
|
||||
crypto_hash(n64, n64, 32)
|
||||
n64[31] &= 127 // clear highest bit
|
||||
|
||||
crypto_tweak_ed25519_scalar_add(scalar_out, scalar, n64)
|
||||
crypto_scalarmult_ed25519_base_noclamp(pk, scalar_out)
|
||||
}
|
||||
}
|
||||
|
||||
// add tweak to scalar
|
||||
function crypto_tweak_ed25519_scalar_add (scalar_out, scalar, n) {
|
||||
crypto_core_ed25519_scalar_add(scalar_out, scalar, n)
|
||||
}
|
||||
|
||||
// add tweak point to public key
|
||||
function crypto_tweak_ed25519_pk_add (tpk, pk, q) {
|
||||
crypto_core_ed25519_add(tpk, pk, q)
|
||||
}
|
||||
|
||||
// add tweak to scalar
|
||||
function crypto_tweak_ed25519_scalar_mul (scalar_out, scalar, n) {
|
||||
crypto_core_ed25519_scalar_mul(scalar_out, scalar, n)
|
||||
}
|
||||
|
||||
// add tweak point to public key
|
||||
function crypto_tweak_ed25519_publickey_mul (tpk, pk, n) {
|
||||
crypto_scalarmult_ed25519_noclamp(tpk, n, pk)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
crypto_tweak_ed25519_base,
|
||||
crypto_tweak_ed25519_sign_detached,
|
||||
crypto_tweak_ed25519_sk_to_scalar,
|
||||
crypto_tweak_ed25519_scalar,
|
||||
crypto_tweak_ed25519_pk,
|
||||
crypto_tweak_ed25519_keypair,
|
||||
crypto_tweak_ed25519_scalar_add,
|
||||
crypto_tweak_ed25519_pk_add,
|
||||
crypto_tweak_ed25519_BYTES,
|
||||
crypto_tweak_ed25519_SCALARBYTES
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
+236
@@ -0,0 +1,236 @@
|
||||
const sodium = require('./')
|
||||
const native = require('sodium-native')
|
||||
const { crypto_scalarmult_ed25519, crypto_scalarmult_ed25519_base, crypto_scalarmult_curve25519, crypto_scalarmult_curve25519_1, crypto_scalarmult_curve25519_base } = require('./crypto_scalarmult_ed25519')
|
||||
const { crypto_sign, crypto_sign_open, crypto_sign_verify_detached } = require('./crypto_sign_ed25519')
|
||||
const sign = require('./crypto_sign')
|
||||
const ed = require('./ed25519')
|
||||
const ec = require('./fe25519_25')
|
||||
const { crypto_tweak_ed25519 } = require('./crypto_tweak')
|
||||
|
||||
console.log(crypto_scalarmult_ed25519)
|
||||
let sm = Buffer.alloc(1024 + sodium.crypto_sign_BYTES)
|
||||
let sm1 = Buffer.alloc(1024 + sodium.crypto_sign_BYTES)
|
||||
let skpk = Buffer.alloc(sodium.crypto_sign_SECRETKEYBYTES)
|
||||
let pk = Buffer.alloc(sodium.crypto_sign_PUBLICKEYBYTES)
|
||||
let sk = Buffer.alloc(sodium.crypto_sign_SECRETKEYBYTES)
|
||||
let smlen
|
||||
let smlen1
|
||||
let i
|
||||
let test
|
||||
|
||||
// sig.fill(0)
|
||||
|
||||
var an = Buffer.from([
|
||||
0x77, 0x07, 0x6d, 0x0a, 0x73, 0x18, 0xa5, 0x7d, 0x3c, 0x16, 0xc1,
|
||||
0x72, 0x51, 0xb2, 0x66, 0x45, 0xdf, 0x4c, 0x2f, 0x87, 0xeb, 0xc0,
|
||||
0x99, 0x2a, 0xb1, 0x77, 0xfb, 0xa5, 0x1d, 0xb9, 0x2c, 0x2a
|
||||
])
|
||||
|
||||
var bn = Buffer.from([
|
||||
0x5d, 0xab, 0x08, 0x7e, 0x62, 0x4a, 0x8a, 0x4b, 0x79, 0xe1, 0x7f,
|
||||
0x8b, 0x83, 0x80, 0x0e, 0xe6, 0x6f, 0x3b, 0xb1, 0x29, 0x26, 0x18,
|
||||
0xb6, 0xfd, 0x1c, 0x2f, 0x8b, 0x27, 0xff, 0x88, 0xe0, 0xeb
|
||||
])
|
||||
|
||||
var bobpk = Buffer.from('de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f', 'hex')
|
||||
|
||||
var cn = Buffer.from([
|
||||
190, 24, 150, 125, 14, 254, 19, 44,
|
||||
55, 112, 156, 5, 141, 230, 91, 84,
|
||||
110, 130, 213, 39, 249, 107, 145, 140,
|
||||
226, 38, 16, 80, 186, 183, 134, 239
|
||||
])
|
||||
|
||||
const res = Buffer.alloc(32)
|
||||
|
||||
var fixtures = require('./crypto_sign.json').map(a => parseTest(a))
|
||||
var pass = true
|
||||
|
||||
// test = parseTest(fixture)
|
||||
|
||||
// console.time('hello')
|
||||
// for (let test of fixtures) {
|
||||
// skpk.set(test.sk)
|
||||
// skpk.set(test.pk, sodium.crypto_sign_SEEDBYTES)
|
||||
// smlen = sodium.crypto_sign(sm, test.m, skpk)
|
||||
// sodium.crypto_sign_open(test.m, sm.subarray(0, smlen), test.pk)
|
||||
// }
|
||||
// console.timeEnd('hello')
|
||||
|
||||
// console.time('ed')
|
||||
// for (let test of fixtures) {
|
||||
// skpk.set(test.sk)
|
||||
// skpk.set(test.pk, sodium.crypto_sign_SEEDBYTES)
|
||||
// smlen = crypto_sign(sm, test.m, skpk)
|
||||
// crypto_sign_open(test.m, sm.subarray(0, smlen), test.pk)
|
||||
// }
|
||||
// console.timeEnd('ed')
|
||||
|
||||
// for (let i = 0; i < fixtures.length; i++) {
|
||||
// let pass = true
|
||||
|
||||
// sm.fill(0)
|
||||
// sm1.fill(0)
|
||||
// test = fixtures[i]
|
||||
// skpk.set(test.sk)
|
||||
// skpk.set(test.pk, sodium.crypto_sign_SEEDBYTES)
|
||||
// smlen = sodium.crypto_sign(sm, test.m, skpk)
|
||||
// smlen1 = crypto_sign(sm1, test.m, skpk)
|
||||
|
||||
// pass &= sodium.crypto_sign_open(test.m, sm1.subarray(0, smlen1), test.pk)
|
||||
// pass &= crypto_sign_open(test.m, sm.subarray(0, smlen), test.pk)
|
||||
|
||||
// if (Buffer.compare(sm, sm1) !== 0 || !pass) console.log('test fails at fixture #' + i)
|
||||
// }
|
||||
|
||||
// //////////////////////////////
|
||||
// sodium.crypto_scalarmult(res, an, bn)
|
||||
// console.log(res.toString('hex'))
|
||||
|
||||
function main () {
|
||||
const b = 3;
|
||||
const pos = 21;
|
||||
const p = ec.ge2();
|
||||
const res = Buffer.alloc(32)
|
||||
// static char hex[32];
|
||||
|
||||
// printf("hello\n");
|
||||
ec.ge25519_cmov8_base(p, pos, b);
|
||||
// printf("hello\n");
|
||||
ec.ge25519_tobytes(res, p);
|
||||
|
||||
console.log(res.toString('hex'))
|
||||
}
|
||||
console.log('====================')
|
||||
main()
|
||||
console.log('====================')
|
||||
|
||||
/////////////////////////////////////////
|
||||
|
||||
res.fill(0)
|
||||
crypto_scalarmult_curve25519(res, an, bobpk)
|
||||
console.log(res.toString('hex'))
|
||||
|
||||
// console.time('whole')
|
||||
crypto_scalarmult_curve25519_1(res, an, bobpk)
|
||||
// console.timeEnd('whole')
|
||||
console.log('scmult wasm', res.toString('hex'))
|
||||
|
||||
native.crypto_scalarmult(res, an, bobpk)
|
||||
console.log('scmult nati', res.toString('hex'))
|
||||
|
||||
sodium.crypto_scalarmult(res, an, bobpk)
|
||||
console.log('scmult js ', res.toString('hex'))
|
||||
|
||||
sodium.crypto_scalarmult_base(res, an)
|
||||
console.log('scmultb js', res.toString('hex'))
|
||||
|
||||
// const basepoint = Buffer.alloc(32)
|
||||
// res.fill(0)
|
||||
// native.crypto_scalarmult_base(basepoint, res)
|
||||
// console.log('---------------', basepoint.toString('hex'))
|
||||
|
||||
native.crypto_scalarmult_base(res, an)
|
||||
console.log('scmultb nat', res.toString('hex'))
|
||||
|
||||
// res.fill(0)
|
||||
// const p = ec.ge3()
|
||||
// ec.ge25519_scalarmult_base(p, an)
|
||||
// ec.ge25519_tobytes(res, p)
|
||||
crypto_scalarmult_curve25519_base(res, an)
|
||||
console.log('scmultb was', res.toString('hex'))
|
||||
|
||||
native.crypto_scalarmult(res, fixtures[1].sk, fixtures[1].pk)
|
||||
console.log(res.toString('hex'))
|
||||
|
||||
crypto_scalarmult_curve25519(res, fixtures[1].sk, fixtures[1].pk)
|
||||
console.log('wasm naive', res.toString('hex'))
|
||||
|
||||
crypto_scalarmult_curve25519_1(res, fixtures[1].sk, fixtures[1].pk)
|
||||
console.log('wasm inner loop', res.toString('hex'))
|
||||
|
||||
native.crypto_scalarmult(res, fixtures[1].sk, fixtures[1].pk)
|
||||
console.log('native', res.toString('hex'))
|
||||
|
||||
crypto_scalarmult_ed25519(res, fixtures[1].sk, fixtures[1].pk)
|
||||
console.log(res.toString('hex'))
|
||||
|
||||
const tweak = Buffer.alloc(32)
|
||||
const ns = Buffer.alloc(32)
|
||||
|
||||
native.crypto_generichash(ns, Buffer.from('namespace'))
|
||||
crypto_tweak_ed25519(tweak, fixtures[1].pk, ns)
|
||||
console.log('js', tweak.toString('hex'))
|
||||
|
||||
native.experimental_crypto_tweak_ed25519(tweak, fixtures[1].pk, ns)
|
||||
console.log('native', tweak.toString('hex'))
|
||||
|
||||
// const a = Buffer.alloc(32)
|
||||
// a[i] = 9
|
||||
// crypto_scalarmult_curve25519_base(res, an)
|
||||
// console.log(res.toString('hex'))
|
||||
|
||||
|
||||
// console.time('hello')
|
||||
// for (let test of fixtures) {
|
||||
// sodium.crypto_scalarmult(res, test.sk, test.pk)
|
||||
// }
|
||||
// console.timeEnd('hello')
|
||||
// console.log(res.toString('hex'))
|
||||
|
||||
// const res1 = Buffer.from(res)
|
||||
// console.time('ed')
|
||||
// for (let test of fixtures) {
|
||||
// crypto_scalarmult_curve25519(res, test.sk, test.pk)
|
||||
// }
|
||||
// console.timeEnd('ed')
|
||||
|
||||
// console.time('wasm')
|
||||
// for (let test of fixtures) {
|
||||
// crypto_scalarmult_curve25519_1(res1, test.sk, test.pk)
|
||||
// }
|
||||
// console.timeEnd('wasm')
|
||||
|
||||
// console.time('native')
|
||||
// for (let test of fixtures) {
|
||||
// native.crypto_scalarmult(res1, test.sk, test.pk)
|
||||
// }
|
||||
// console.timeEnd('native')
|
||||
// console.log(res.toString('hex'))
|
||||
// console.log(res1.toString('hex'))
|
||||
|
||||
/////////////////////////////////////////
|
||||
|
||||
// console.log(sm.toString('hex'))
|
||||
|
||||
native.crypto_sign_keypair(pk, sk)
|
||||
|
||||
let sig = Buffer.alloc(sodium.crypto_sign_BYTES + 32)
|
||||
const m = Buffer.alloc(32)
|
||||
const m2 = Buffer.alloc(32)
|
||||
for (let i = 0; i < 32; i++) m[i] = i
|
||||
|
||||
crypto_sign(sig, m, sk)
|
||||
// pass &= smlen === sodium.crypto_sign_BYTES + test.m.byteLength
|
||||
// pass &= Buffer.compare(test.sig, sm.subarray(0, 64)) === 0
|
||||
// pass &= sodium.crypto_sign_open(test.m, sm.subarray(0, smlen), test.pk)
|
||||
console.log('sig', sig.toString('hex'))
|
||||
|
||||
console.log(sodium.crypto_sign_open(m2, sig, pk))
|
||||
console.log(crypto_sign_open(m2, sig, pk))
|
||||
console.log(m2.toString('hex'))
|
||||
|
||||
// // pass &= sig.byteLength !== 0 && sig.byteLength <= sodium.crypto_sign_BYTES
|
||||
// // pass &= Buffer.compare(test.sig, sig) === 0
|
||||
// pass &= sodium.crypto_sign_verify_detached(sig, test.m.subarray(0, i), test.pk)
|
||||
|
||||
function parseTest (t) {
|
||||
return {
|
||||
sk: Buffer.from(t[0]),
|
||||
pk: Buffer.from(t[1]),
|
||||
sig: Buffer.from(t[2]),
|
||||
m: Buffer.from(t[3])
|
||||
}
|
||||
}
|
||||
|
||||
// 92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00720
|
||||
+483
@@ -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
|
||||
}
|
||||
+6
-6
@@ -1,19 +1,19 @@
|
||||
var sodium = require('./')
|
||||
const sodium = require('./')
|
||||
|
||||
var key = new Buffer(sodium.crypto_secretbox_KEYBYTES)
|
||||
var nonce = new Buffer(sodium.crypto_secretbox_NONCEBYTES)
|
||||
const key = Buffer.alloc(sodium.crypto_secretbox_KEYBYTES)
|
||||
const nonce = Buffer.alloc(sodium.crypto_secretbox_NONCEBYTES)
|
||||
|
||||
sodium.randombytes_buf(key)
|
||||
sodium.randombytes_buf(nonce)
|
||||
|
||||
var message = new Buffer('Hello, World!')
|
||||
var cipher = new Buffer(message.length + sodium.crypto_secretbox_MACBYTES)
|
||||
const message = Buffer.from('Hello, World!')
|
||||
const cipher = Buffer.alloc(message.length + sodium.crypto_secretbox_MACBYTES)
|
||||
|
||||
sodium.crypto_secretbox_easy(cipher, message, nonce, key)
|
||||
|
||||
console.log('Encrypted:', cipher)
|
||||
|
||||
var plainText = new Buffer(cipher.length - sodium.crypto_secretbox_MACBYTES)
|
||||
const plainText = Buffer.alloc(cipher.length - sodium.crypto_secretbox_MACBYTES)
|
||||
|
||||
sodium.crypto_secretbox_open_easy(plainText, cipher, nonce, key)
|
||||
|
||||
|
||||
+333
@@ -0,0 +1,333 @@
|
||||
const ec = require('./fe25519_25.js')
|
||||
const sodium = require('./')
|
||||
const invert = require('./fe25519_25/fe25519_invert')({
|
||||
imports: {
|
||||
debug: {
|
||||
log (...args) {
|
||||
console.log(...args.map(int => (int >>> 0).toString(16).padStart(8, '0')))
|
||||
},
|
||||
log_tee (arg) {
|
||||
console.log((arg >>> 0).toString(16).padStart(8, '0'))
|
||||
return arg
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
const pow = require('./fe25519_25/fe25519_pow22523')({
|
||||
imports: {
|
||||
debug: {
|
||||
log (...args) {
|
||||
console.log(...args.map(int => (int >>> 0).toString(16).padStart(8, '0')))
|
||||
},
|
||||
log_tee (arg) {
|
||||
console.log((arg >>> 0).toString(16).padStart(8, '0'))
|
||||
return arg
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// const crypto = require('crypto')
|
||||
|
||||
var f = new Int32Array(10)
|
||||
var g = new Int32Array(10)
|
||||
var h = new Int32Array(10)
|
||||
|
||||
var a = ec.ge3()
|
||||
var r = ec.ge3()
|
||||
|
||||
function wasm_inv (h, f) {
|
||||
var buf = Buffer.from(f.buffer)
|
||||
|
||||
invert.memory.set(buf)
|
||||
invert.exports.fe25519_invert(40, 0)
|
||||
|
||||
buf = Buffer.from(invert.memory.slice(40, 80))
|
||||
for (let i = 0; i < 10; i++) {
|
||||
h[i] = buf.readUInt32LE(4 * i)
|
||||
}
|
||||
}
|
||||
|
||||
function wasm_pow (h, f) {
|
||||
var buf = Buffer.from(f.buffer)
|
||||
|
||||
pow.memory.set(buf)
|
||||
pow.exports.fe25519_pow22523(40, 0)
|
||||
|
||||
buf = Buffer.from(pow.memory.slice(40, 80))
|
||||
for (let i = 0; i < 10; i++) {
|
||||
h[i] = buf.readUInt32LE(4 * i)
|
||||
}
|
||||
}
|
||||
|
||||
f[0] = 23983080
|
||||
a[2][0] = 1
|
||||
|
||||
// ec.fe25519_neg(g, f)
|
||||
// ec.fe25519_reduce(g, g)
|
||||
// ec.fe25519_add(h, f, g)
|
||||
// ec.fe25519_reduce(h, h)
|
||||
|
||||
// ec.fe25519_sub(h, f, g)
|
||||
// ec.fe25519_reduce(h, h)
|
||||
// console.log(h)
|
||||
|
||||
// ec.fe25519_add(h, f, f)
|
||||
// ec.fe25519_reduce(h, h)
|
||||
// console.log(h)
|
||||
|
||||
// g[0] = 2
|
||||
// for (let i = 1; i < 10; i++) g[i] = 0
|
||||
// ec.fe25519_mul(h, f, g)
|
||||
// console.log(h)
|
||||
// ec.fe25519_reduce(h, h)
|
||||
// console.log(h)
|
||||
|
||||
var an = Buffer.from([
|
||||
171, 69, 129, 47, 90, 82, 223, 134,
|
||||
6, 147, 54, 76, 55, 148, 252, 37,
|
||||
234, 216, 113, 62, 223, 49, 33, 36,
|
||||
172, 246, 18, 226, 50, 249, 198, 231
|
||||
])
|
||||
|
||||
var bn = Buffer.from([
|
||||
226, 38, 16, 80, 186, 183, 134, 239,
|
||||
190, 24, 150, 125, 14, 254, 19, 44,
|
||||
55, 112, 156, 5, 141, 230, 91, 84,
|
||||
110, 130, 213, 39, 249, 107, 145, 140
|
||||
])
|
||||
|
||||
var cn = Buffer.from([
|
||||
190, 24, 150, 125, 14, 254, 19, 44,
|
||||
55, 112, 156, 5, 141, 230, 91, 84,
|
||||
110, 130, 213, 39, 249, 107, 145, 140,
|
||||
226, 38, 16, 80, 186, 183, 134, 239
|
||||
])
|
||||
|
||||
var s = Buffer.from([
|
||||
190, 24, 150, 125, 14, 254, 19, 44,
|
||||
55, 112, 156, 5, 141, 230, 91, 84,
|
||||
110, 130, 213, 39, 249, 107, 145, 140,
|
||||
226, 38, 16, 80, 186, 183, 134, 239,
|
||||
190, 24, 150, 125, 14, 254, 19, 44,
|
||||
55, 112, 156, 5, 141, 230, 91, 84,
|
||||
110, 130, 213, 39, 249, 107, 145, 140,
|
||||
226, 38, 16, 80, 186, 183, 134, 239
|
||||
])
|
||||
|
||||
const p = Buffer.from([
|
||||
0x38, 0xf4, 0x69, 0x6f, 0xcf, 0x62, 0xa0, 0xfd,
|
||||
0x5a, 0xb7, 0x6e, 0x9f, 0xcb, 0xcd, 0x95, 0x3f,
|
||||
0xed, 0xba, 0x30, 0xb2, 0x64, 0x42, 0xa4, 0x52,
|
||||
0x27, 0xa6, 0x3e, 0xd2, 0xc8, 0xac, 0xa4, 0xed
|
||||
])
|
||||
|
||||
const pk_test = Buffer.from('d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a', 'hex')
|
||||
|
||||
function signedInt (i) {
|
||||
return i < 0 ? 2 ** 32 + i : i
|
||||
}
|
||||
|
||||
// console.log(Uint8Array.from(an))
|
||||
// console.log(Uint8Array.from(bn))
|
||||
|
||||
// console.log(an.toString('hex'))
|
||||
// console.log(bn.toString('hex'))
|
||||
|
||||
// for (let i = 0; i < 25; i++) an[i] = bn[i] = i
|
||||
// var correct = true
|
||||
|
||||
// var dn = Buffer.alloc(32)
|
||||
|
||||
const mod = 2n ** 252n + 27742317777372353535851937790883648493n
|
||||
const res = Buffer.alloc(32)
|
||||
const res1 = Buffer.alloc(32)
|
||||
|
||||
var a = new Int32Array(10)
|
||||
var b = new Int32Array(10)
|
||||
var c = new Int32Array(10)
|
||||
var g = new Int32Array(10)
|
||||
const ge = ec.ge3()
|
||||
const gf = ec.ge3()
|
||||
|
||||
///////////////////////////////////////////
|
||||
ec.fe25519_frombytes(a, an)
|
||||
ec.fe25519_frombytes(b, bn)
|
||||
|
||||
ec.fe25519_mul(c, b, a)
|
||||
// // console.log('\na __________')
|
||||
// // for (let i = 0; i < 10; i++) console.log(`a${i}:`, signedInt(a[i]).toString(16).padStart(8, '0'))
|
||||
// // console.log('\nb __________')
|
||||
// // for (let i = 0; i < 10; i++) console.log(`b${i}:`, signedInt(b[i]).toString(16).padStart(8, '0'))
|
||||
// ec.fe25519_frombytes(c, bn)
|
||||
ec.fe25519_tobytes(res, c)
|
||||
console.log('tess :', res.toString('hex'))
|
||||
|
||||
|
||||
console.time('standard')
|
||||
for (let i = 0; i < 10000; i++) ec.fe25519_invert(b, a)
|
||||
console.timeEnd('standard')
|
||||
|
||||
ec.fe25519_tobytes(res, b)
|
||||
console.log('tess :', res.toString('hex'))
|
||||
|
||||
console.time('pure invert')
|
||||
for (let i = 0; i < 10000; i++) ec.fe25519_invert_1(b, a)
|
||||
console.timeEnd('pure invert')
|
||||
ec.fe25519_tobytes(res, b)
|
||||
console.log('tess :', res.toString('hex'))
|
||||
|
||||
ec.fe25519_pow22523(a, a)
|
||||
ec.fe25519_tobytes(res, a)
|
||||
console.log('fe_p25:', res.toString('hex'))
|
||||
|
||||
ec.fe25519_cneg(a, a, 1)
|
||||
ec.fe25519_tobytes(res, a)
|
||||
console.log('fe_cng:', res.toString('hex'))
|
||||
|
||||
ec.sc25519_mul(res, an, bn)
|
||||
console.log('sc_mul:', res.toString('hex'))
|
||||
|
||||
ec.sc25519_muladd(res, an, bn, cn)
|
||||
console.log('sc_mad:', res.toString('hex'))
|
||||
|
||||
ec.sc25519_reduce(s)
|
||||
console.log('sc_red:', s.subarray(0, 32).toString('hex'))
|
||||
|
||||
ec.sc25519_invert(res, cn)
|
||||
console.log('sc_inv:', res.toString('hex'))
|
||||
|
||||
ec.ge25519_mont_to_ed(g, c, a, b)
|
||||
ec.fe25519_tobytes(res, g)
|
||||
console.log('g_m2ex:', res.toString('hex'))
|
||||
ec.fe25519_tobytes(res, c)
|
||||
console.log('g_m2ey:', res.toString('hex'))
|
||||
|
||||
ec.ge25519_frombytes(ge, p)
|
||||
ec.ge25519_p3_tobytes(res, ge)
|
||||
console.log("p :", res.toString('hex'))
|
||||
|
||||
ec.ge25519_mul_l(gf, ge)
|
||||
ec.ge25519_p3_tobytes(res, gf)
|
||||
console.log("mul_l :", res.toString('hex'))
|
||||
|
||||
ec.ge25519_scalarmult_base(gf, cn)
|
||||
ec.ge25519_p3_tobytes(res, gf)
|
||||
console.log("smultb:", res.toString('hex'))
|
||||
|
||||
ec.ge25519_scalarmult(ge, bn, gf)
|
||||
ec.ge25519_p3_tobytes(res, ge)
|
||||
console.log("smult :", res.toString('hex'))
|
||||
|
||||
ec.ge25519_double_scalarmult_vartime(gf, an, ge, bn)
|
||||
ec.ge25519_p3_tobytes(res, gf)
|
||||
console.log("smdbl :", res.toString('hex'))
|
||||
|
||||
ec.ge25519_frombytes_negate_vartime(gf, pk_test)
|
||||
ec.ge25519_p3_tobytes(res, gf)
|
||||
console.log("smdbl :", res.toString('hex'))
|
||||
|
||||
console.log('canon :', ec.sc25519_is_canonical(bn))
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
// console.log(((BigInt(ahex) * BigInt(ahex)) % mod).toString(16))
|
||||
// console.log(res1.toString('hex'))
|
||||
|
||||
// const b = new Float64Array(16)
|
||||
// const bi = new Float64Array(16)
|
||||
// sodium.unpack25519(b, an)
|
||||
// console.log(b)
|
||||
// sodium.inv25519(bi, b)
|
||||
// console.log(b)
|
||||
// sodium.pack(res1, bi)
|
||||
|
||||
|
||||
// console.log(res.toString('hex'))
|
||||
// console.log(res1.toString('hex'))
|
||||
|
||||
|
||||
// for (let j = 0; j < 10000; j++) {
|
||||
// var an = crypto.randomBytes(32)
|
||||
// var bn = crypto.randomBytes(32)
|
||||
// var cn = crypto.randomBytes(32)
|
||||
// dn.fill(0)
|
||||
|
||||
// ec.fe25519_invert(dn, an, bn, cn)
|
||||
// var res = reverseEndian(dn)
|
||||
|
||||
// var bi = (((BigInt('0x' + reverseEndian(an)) * BigInt('0x' + reverseEndian(bn))) + BigInt('0x' + reverseEndian(cn))) % mod).toString(16).padStart(res.length, '0')
|
||||
|
||||
// correct &= res === bi
|
||||
// }
|
||||
|
||||
// console.log(correct === 1)
|
||||
|
||||
// function reverseEndian (buf) {
|
||||
// var str = ''
|
||||
// let i = buf.length - 1
|
||||
|
||||
// while (buf[i] === 0) i--
|
||||
// if (i === -1) return '0'
|
||||
|
||||
// for (; i >= 0; i--) {
|
||||
// str += buf[i].toString(16).padStart(2, '0')
|
||||
// }
|
||||
|
||||
// return str
|
||||
// }
|
||||
|
||||
// const a237 = new Array(
|
||||
// 0x0003e6b1n,
|
||||
// 0x001d0353n,
|
||||
// 0x00033a5dn,
|
||||
// 0x000fcd68n,
|
||||
// 0x000cd8c5n,
|
||||
// 0x00172cd9n,
|
||||
// 0x000dcf66n,
|
||||
// 0x0014afffn,
|
||||
// 0x0009f453n,
|
||||
// 0x0006399cn,
|
||||
// 0x000e9672n,
|
||||
// 0x000ee4een
|
||||
// )
|
||||
// var a237 = []
|
||||
// a237 = Array.from(a237).map(BigInt)
|
||||
|
||||
// var s = Buffer.alloc(32)
|
||||
|
||||
// s[0] = Number(a237[0] >> 0n)
|
||||
// s[1] = Number(a237[0] >> 8n)
|
||||
// s[2] = Number((a237[0] >> 16n) | (a237[1] * (1n << 5n)))
|
||||
// s[3] = Number(a237[1] >> 3n)
|
||||
// s[4] = Number(a237[1] >> 11n)
|
||||
// s[5] = Number((a237[1] >> 19n) | (a237[2] * (1n << 2n)))
|
||||
// s[6] = Number(a237[2] >> 6n)
|
||||
// s[7] = Number((a237[2] >> 14n) | (a237[3] * (1n << 7n)))
|
||||
// s[8] = Number(a237[3] >> 1n)
|
||||
// s[9] = Number(a237[3] >> 9n)
|
||||
// s[10] = Number((a237[3] >> 17n) | (a237[4] * (1n << 4n)))
|
||||
// s[11] = Number(a237[4] >> 4n)
|
||||
// s[12] = Number(a237[4] >> 12n)
|
||||
// s[13] = Number((a237[4] >> 20n) | (a237[5] * (1n << 1n)))
|
||||
// s[14] = Number(a237[5] >> 7n)
|
||||
// s[15] = Number((a237[5] >> 15n) | (a237[6] * (1n << 6n)))
|
||||
// s[16] = Number(a237[6] >> 2n)
|
||||
// s[17] = Number(a237[6] >> 10n)
|
||||
// s[18] = Number((a237[6] >> 18n) | (a237[7] * (1n << 3n)))
|
||||
// s[19] = Number(a237[7] >> 5n)
|
||||
// s[20] = Number(a237[7] >> 13n)
|
||||
// s[21] = Number(a237[8] >> 0n)
|
||||
// s[22] = Number(a237[8] >> 8n)
|
||||
// s[23] = Number((a237[8] >> 16n) | (a237[9] * (1n << 5n)))
|
||||
// s[24] = Number(a237[9] >> 3n)
|
||||
// s[25] = Number(a237[9] >> 11n)
|
||||
// s[26] = Number((a237[9] >> 19n) | (a237[10] * (1n << 2n)))
|
||||
// s[27] = Number(a237[10] >> 6n)
|
||||
// s[28] = Number((a237[10] >> 14n) | (a237[11] * (1n << 7n)))
|
||||
// s[29] = Number(a237[11] >> 1n)
|
||||
// s[30] = Number(a237[11] >> 9n)
|
||||
// s[31] = Number(a237[11] >> 17n)
|
||||
|
||||
// console.log(reverseEndian(s))
|
||||
// // console.log(a237.reduce((acc, a, i) => acc + a * 1n << (20n * BigInt(i))).toString(16))
|
||||
+2962
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,61 @@
|
||||
|
||||
module.exports = loadWebAssembly
|
||||
|
||||
loadWebAssembly.supported = typeof WebAssembly !== 'undefined'
|
||||
|
||||
function loadWebAssembly (opts) {
|
||||
if (!loadWebAssembly.supported) return null
|
||||
|
||||
var imp = opts && opts.imports
|
||||
var wasm = toUint8Array('AGFzbQEAAAABHwJgFX5+fn5+fn5+fn5+fn5+fn5+fn5+fwBgA39/fwACGAICanMFdGFibGUBcAAEAmpzA21lbQIAAQMDAgABBw8BC2ZlMjU1MTlfbXVsAAEJBwEAQQELAQAK/hACkBABhgF+IACnrCEAIAGnrCEBIAKnrCECIAOnrCEDIASnrCEEIAWnrCEFIAanrCEGIAenrCEHIAinrCEIIAmnrCEJIAqnrCEKIAunrCELIAynrCEMIA2nrCENIA6nrCEOIA+nrCEPIBCnrCEQIBGnrCERIBKnrCESIBOnrCETQhMgC34gC0KAgICACINCAYZCE359ISlCEyAMfiAMQoCAgIAIg0IBhkITfn0hKkITIA1+IA1CgICAgAiDQgGGQhN+fSErQhMgDn4gDkKAgICACINCAYZCE359ISxCEyAPfiAPQoCAgIAIg0IBhkITfn0hLUITIBB+IBBCgICAgAiDQgGGQhN+fSEuQhMgEX4gEUKAgICACINCAYZCE359IS9CEyASfiASQoCAgIAIg0IBhkITfn0hMEITIBN+IBNCgICAgAiDQgGGQhN+fSExQgIgAX4gAUKAgICACINCAYZCAn59ITJCAiADfiADQoCAgIAIg0IBhkICfn0hM0ICIAV+IAVCgICAgAiDQgGGQgJ+fSE0QgIgB34gB0KAgICACINCAYZCAn59ITVCAiAJfiAJQoCAgIAIg0IBhkICfn0hNiApp6whKSAqp6whKiArp6whKyAsp6whLCAtp6whLSAup6whLiAvp6whLyAwp6whMCAxp6whMSAyp6whMiAzp6whMyA0p6whNCA1p6whNSA2p6whNiAAIAp+ITcgACALfiE4IAAgDH4hOSAAIA1+ITogACAOfiE7IAAgD34hPCAAIBB+IT0gACARfiE+IAAgEn4hPyAAIBN+IUAgASAKfiFBIDIgC34hQiABIAx+IUMgMiANfiFEIAEgDn4hRSAyIA9+IUYgASAQfiFHIDIgEX4hSCABIBJ+IUkgMiAxfiFKIAIgCn4hSyACIAt+IUwgAiAMfiFNIAIgDX4hTiACIA5+IU8gAiAPfiFQIAIgEH4hUSACIBF+IVIgAiAwfiFTIAIgMX4hVCADIAp+IVUgMyALfiFWIAMgDH4hVyAzIA1+IVggAyAOfiFZIDMgD34hWiADIBB+IVsgMyAvfiFcIAMgMH4hXSAzIDF+IV4gBCAKfiFfIAQgC34hYCAEIAx+IWEgBCANfiFiIAQgDn4hYyAEIA9+IWQgBCAufiFlIAQgL34hZiAEIDB+IWcgBCAxfiFoIAUgCn4haSA0IAt+IWogBSAMfiFrIDQgDX4hbCAFIA5+IW0gNCAtfiFuIAUgLn4hbyA0IC9+IXAgBSAwfiFxIDQgMX4hciAGIAp+IXMgBiALfiF0IAYgDH4hdSAGIA1+IXYgBiAsfiF3IAYgLX4heCAGIC5+IXkgBiAvfiF6IAYgMH4heyAGIDF+IXwgByAKfiF9IDUgC34hfiAHIAx+IX8gNSArfiGAASAHICx+IYEBIDUgLX4hggEgByAufiGDASA1IC9+IYQBIAcgMH4hhQEgNSAxfiGGASAIIAp+IYcBIAggC34hiAEgCCAqfiGJASAIICt+IYoBIAggLH4hiwEgCCAtfiGMASAIIC5+IY0BIAggL34hjgEgCCAwfiGPASAIIDF+IZABIAkgCn4hkQEgNiApfiGSASAJICp+IZMBIDYgK34hlAEgCSAsfiGVASA2IC1+IZYBIAkgLn4hlwEgNiAvfiGYASAJIDB+IZkBIDYgMX4hmgEgNyBKIFMgXCBlIG4gdyCAASCJASCSAXx8fHx8fHx8fCEVIDggQSBUIF0gZiBvIHgggQEgigEgkwF8fHx8fHx8fHwhFiA5IEIgSyBeIGcgcCB5IIIBIIsBIJQBfHx8fHx8fHx8IRcgOiBDIEwgVSBoIHEgeiCDASCMASCVAXx8fHx8fHx8fCEYIDsgRCBNIFYgXyByIHsghAEgjQEglgF8fHx8fHx8fHwhGSA8IEUgTiBXIGAgaSB8IIUBII4BIJcBfHx8fHx8fHx8IRogPSBGIE8gWCBhIGogcyCGASCPASCYAXx8fHx8fHx8fCEbID4gRyBQIFkgYiBrIHQgfSCQASCZAXx8fHx8fHx8fCEcID8gSCBRIFogYyBsIHUgfiCHASCaAXx8fHx8fHx8fCEdIEAgSSBSIFsgZCBtIHYgfyCIASCRAXx8fHx8fHx8fCEeIBVCAUIZhnxCGochHyAWIB98IRYgFSAfQgFCGoZ+fSEVIBlCAUIZhnxCGochIyAaICN8IRogGSAjQgFCGoZ+fSEZIBZCAUIYhnxCGYchICAXICB8IRcgFiAgQgFCGYZ+fSEWIBpCAUIYhnxCGYchJCAbICR8IRsgGiAkQgFCGYZ+fSEaIBdCAUIZhnxCGochISAYICF8IRggFyAhQgFCGoZ+fSEXIBtCAUIZhnxCGochJSAcICV8IRwgGyAlQgFCGoZ+fSEbIBhCAUIYhnxCGYchIiAZICJ8IRkgGCAiQgFCGYZ+fSEYIBxCAUIYhnxCGYchJiAdICZ8IR0gHCAmQgFCGYZ+fSEcIBlCAUIZhnxCGochIyAaICN8IRogGSAjQgFCGoZ+fSEZIB1CAUIZhnxCGochJyAeICd8IR4gHSAnQgFCGoZ+fSEdIB5CAUIYhnxCGYchKCAVIChCE358IRUgHiAoQgFCGYZ+fSEeIBVCAUIZhnxCGochHyAWIB98IRYgFSAfQgFCGoZ+fSEVIBQgFT4CACAUIBY+AgQgFCAXPgIIIBQgGD4CDCAUIBk+AhAgFCAaPgIUIBQgGz4CGCAUIBw+AhwgFCAdPgIgIBQgHj4CJAtqACABNQIAIAE1AgQgATUCCCABNQIMIAE1AhAgATUCFCABNQIYIAE1AhwgATUCICABNQIkIAI1AgAgAjUCBCACNQIIIAI1AgwgAjUCECACNQIUIAI1AhggAjUCHCACNQIgIAI1AiQgABAACw==')
|
||||
var ready = null
|
||||
|
||||
var mod = {
|
||||
buffer: wasm,
|
||||
memory: null,
|
||||
exports: null,
|
||||
realloc: realloc,
|
||||
onload: onload
|
||||
}
|
||||
|
||||
onload(function () {})
|
||||
|
||||
return mod
|
||||
|
||||
function realloc (size) {
|
||||
mod.exports.memory.grow(Math.max(0, Math.ceil(Math.abs(size - mod.memory.length) / 65536)))
|
||||
mod.memory = new Uint8Array(mod.exports.memory.buffer)
|
||||
}
|
||||
|
||||
function onload (cb) {
|
||||
if (mod.exports) return cb()
|
||||
|
||||
if (ready) {
|
||||
ready.then(cb.bind(null, null)).catch(cb)
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
if (opts && opts.async) throw new Error('async')
|
||||
setup({instance: new WebAssembly.Instance(new WebAssembly.Module(wasm), imp)})
|
||||
} catch (err) {
|
||||
ready = WebAssembly.instantiate(wasm, imp).then(setup)
|
||||
}
|
||||
|
||||
onload(cb)
|
||||
}
|
||||
|
||||
function setup (w) {
|
||||
mod.exports = w.instance.exports
|
||||
mod.memory = mod.exports.memory && mod.exports.memory.buffer && new Uint8Array(mod.exports.memory.buffer)
|
||||
}
|
||||
}
|
||||
|
||||
function toUint8Array (s) {
|
||||
if (typeof atob === 'function') return new Uint8Array(atob(s).split('').map(charCodeAt))
|
||||
return (require('buf' + 'fer').Buffer).from(s, 'base64')
|
||||
}
|
||||
|
||||
function charCodeAt (c) {
|
||||
return c.charCodeAt(0)
|
||||
}
|
||||
@@ -0,0 +1,440 @@
|
||||
(module
|
||||
(import "js" "table" (table 4 anyfunc))
|
||||
(import "js" "mem" (memory 1))
|
||||
|
||||
(elem (i32.const 1) $fe_mul)
|
||||
|
||||
;; (func $i32.log (import "debug" "log") (param i32))
|
||||
;; (func $i32.log_tee (import "debug" "log_tee") (param i32) (result i32))
|
||||
;; ;; No i64 interop with JS yet - but maybe coming with WebAssembly BigInt
|
||||
;; ;; So we can instead fake this by splitting the i64 into two i32 limbs,
|
||||
;; ;; however these are WASM functions using i32x2.log:
|
||||
;; (func $i32x2.log (import "debug" "log") (param i32) (param i32))
|
||||
;; (func $f32.log (import "debug" "log") (param f32))
|
||||
;; (func $f32.log_tee (import "debug" "log_tee") (param f32) (result f32))
|
||||
;; (func $f64.log (import "debug" "log") (param f64))
|
||||
;; (func $f64.log_tee (import "debug" "log_tee") (param f64) (result f64))
|
||||
|
||||
;; ;; i64 logging by splitting into two i32 limbs
|
||||
;; (func $i64.log
|
||||
;; (param $0 i64)
|
||||
;; (call $i32x2.log
|
||||
;; ;; Upper limb
|
||||
;; (i32.wrap/i64
|
||||
;; (i64.shr_s (get_local $0)
|
||||
;; (i64.const 32)))
|
||||
;; ;; Lower limb
|
||||
;; (i32.wrap/i64 (get_local $0))))
|
||||
|
||||
;; (func $i64.log_tee
|
||||
;; (param $0 i64)
|
||||
;; (result i64)
|
||||
;; (call $i64.log (get_local $0))
|
||||
;; (return (get_local $0)))
|
||||
|
||||
(func $fe_mul
|
||||
(param $f0 i64)
|
||||
(param $f1 i64)
|
||||
(param $f2 i64)
|
||||
(param $f3 i64)
|
||||
(param $f4 i64)
|
||||
(param $f5 i64)
|
||||
(param $f6 i64)
|
||||
(param $f7 i64)
|
||||
(param $f8 i64)
|
||||
(param $f9 i64)
|
||||
|
||||
(param $g0 i64)
|
||||
(param $g1 i64)
|
||||
(param $g2 i64)
|
||||
(param $g3 i64)
|
||||
(param $g4 i64)
|
||||
(param $g5 i64)
|
||||
(param $g6 i64)
|
||||
(param $g7 i64)
|
||||
(param $g8 i64)
|
||||
(param $g9 i64)
|
||||
|
||||
(param $h i32)
|
||||
|
||||
(local $h0 i64)
|
||||
(local $h1 i64)
|
||||
(local $h2 i64)
|
||||
(local $h3 i64)
|
||||
(local $h4 i64)
|
||||
(local $h5 i64)
|
||||
(local $h6 i64)
|
||||
(local $h7 i64)
|
||||
(local $h8 i64)
|
||||
(local $h9 i64)
|
||||
|
||||
(local $carry0 i64)
|
||||
(local $carry1 i64)
|
||||
(local $carry2 i64)
|
||||
(local $carry3 i64)
|
||||
(local $carry4 i64)
|
||||
(local $carry5 i64)
|
||||
(local $carry6 i64)
|
||||
(local $carry7 i64)
|
||||
(local $carry8 i64)
|
||||
(local $carry9 i64)
|
||||
|
||||
(local $g1_19 i64)
|
||||
(local $g2_19 i64)
|
||||
(local $g3_19 i64)
|
||||
(local $g4_19 i64)
|
||||
(local $g5_19 i64)
|
||||
(local $g6_19 i64)
|
||||
(local $g7_19 i64)
|
||||
(local $g8_19 i64)
|
||||
(local $g9_19 i64)
|
||||
(local $f1_2 i64)
|
||||
(local $f3_2 i64)
|
||||
(local $f5_2 i64)
|
||||
(local $f7_2 i64)
|
||||
(local $f9_2 i64)
|
||||
|
||||
(local $f0g0 i64)
|
||||
(local $f0g1 i64)
|
||||
(local $f0g2 i64)
|
||||
(local $f0g3 i64)
|
||||
(local $f0g4 i64)
|
||||
(local $f0g5 i64)
|
||||
(local $f0g6 i64)
|
||||
(local $f0g7 i64)
|
||||
(local $f0g8 i64)
|
||||
(local $f0g9 i64)
|
||||
(local $f1g0 i64)
|
||||
(local $f1g1_2 i64)
|
||||
(local $f1g2 i64)
|
||||
(local $f1g3_2 i64)
|
||||
(local $f1g4 i64)
|
||||
(local $f1g5_2 i64)
|
||||
(local $f1g6 i64)
|
||||
(local $f1g7_2 i64)
|
||||
(local $f1g8 i64)
|
||||
(local $f1g9_38 i64)
|
||||
(local $f2g0 i64)
|
||||
(local $f2g1 i64)
|
||||
(local $f2g2 i64)
|
||||
(local $f2g3 i64)
|
||||
(local $f2g4 i64)
|
||||
(local $f2g5 i64)
|
||||
(local $f2g6 i64)
|
||||
(local $f2g7 i64)
|
||||
(local $f2g8_19 i64)
|
||||
(local $f2g9_19 i64)
|
||||
(local $f3g0 i64)
|
||||
(local $f3g1_2 i64)
|
||||
(local $f3g2 i64)
|
||||
(local $f3g3_2 i64)
|
||||
(local $f3g4 i64)
|
||||
(local $f3g5_2 i64)
|
||||
(local $f3g6 i64)
|
||||
(local $f3g7_38 i64)
|
||||
(local $f3g8_19 i64)
|
||||
(local $f3g9_38 i64)
|
||||
(local $f4g0 i64)
|
||||
(local $f4g1 i64)
|
||||
(local $f4g2 i64)
|
||||
(local $f4g3 i64)
|
||||
(local $f4g4 i64)
|
||||
(local $f4g5 i64)
|
||||
(local $f4g6_19 i64)
|
||||
(local $f4g7_19 i64)
|
||||
(local $f4g8_19 i64)
|
||||
(local $f4g9_19 i64)
|
||||
(local $f5g0 i64)
|
||||
(local $f5g1_2 i64)
|
||||
(local $f5g2 i64)
|
||||
(local $f5g3_2 i64)
|
||||
(local $f5g4 i64)
|
||||
(local $f5g5_38 i64)
|
||||
(local $f5g6_19 i64)
|
||||
(local $f5g7_38 i64)
|
||||
(local $f5g8_19 i64)
|
||||
(local $f5g9_38 i64)
|
||||
(local $f6g0 i64)
|
||||
(local $f6g1 i64)
|
||||
(local $f6g2 i64)
|
||||
(local $f6g3 i64)
|
||||
(local $f6g4_19 i64)
|
||||
(local $f6g5_19 i64)
|
||||
(local $f6g6_19 i64)
|
||||
(local $f6g7_19 i64)
|
||||
(local $f6g8_19 i64)
|
||||
(local $f6g9_19 i64)
|
||||
(local $f7g0 i64)
|
||||
(local $f7g1_2 i64)
|
||||
(local $f7g2 i64)
|
||||
(local $f7g3_38 i64)
|
||||
(local $f7g4_19 i64)
|
||||
(local $f7g5_38 i64)
|
||||
(local $f7g6_19 i64)
|
||||
(local $f7g7_38 i64)
|
||||
(local $f7g8_19 i64)
|
||||
(local $f7g9_38 i64)
|
||||
(local $f8g0 i64)
|
||||
(local $f8g1 i64)
|
||||
(local $f8g2_19 i64)
|
||||
(local $f8g3_19 i64)
|
||||
(local $f8g4_19 i64)
|
||||
(local $f8g5_19 i64)
|
||||
(local $f8g6_19 i64)
|
||||
(local $f8g7_19 i64)
|
||||
(local $f8g8_19 i64)
|
||||
(local $f8g9_19 i64)
|
||||
(local $f9g0 i64)
|
||||
(local $f9g1_38 i64)
|
||||
(local $f9g2_19 i64)
|
||||
(local $f9g3_38 i64)
|
||||
(local $f9g4_19 i64)
|
||||
(local $f9g5_38 i64)
|
||||
(local $f9g6_19 i64)
|
||||
(local $f9g7_38 i64)
|
||||
(local $f9g8_19 i64)
|
||||
(local $f9g9_38 i64)
|
||||
|
||||
(set_local $f0 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f0))))
|
||||
(set_local $f1 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f1))))
|
||||
(set_local $f2 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f2))))
|
||||
(set_local $f3 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f3))))
|
||||
(set_local $f4 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f4))))
|
||||
(set_local $f5 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f5))))
|
||||
(set_local $f6 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f6))))
|
||||
(set_local $f7 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f7))))
|
||||
(set_local $f8 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f8))))
|
||||
(set_local $f9 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f9))))
|
||||
|
||||
(set_local $g0 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g0))))
|
||||
(set_local $g1 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g1))))
|
||||
(set_local $g2 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g2))))
|
||||
(set_local $g3 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g3))))
|
||||
(set_local $g4 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g4))))
|
||||
(set_local $g5 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g5))))
|
||||
(set_local $g6 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g6))))
|
||||
(set_local $g7 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g7))))
|
||||
(set_local $g8 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g8))))
|
||||
(set_local $g9 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g9))))
|
||||
|
||||
(set_local $g1_19 (i64.sub (i64.mul (i64.const 19) (get_local $g1)) (i64.mul (i64.shl (i64.and (get_local $g1) (i64.const 0x80000000)) (i64.const 1)) (i64.const 19))))
|
||||
(set_local $g2_19 (i64.sub (i64.mul (i64.const 19) (get_local $g2)) (i64.mul (i64.shl (i64.and (get_local $g2) (i64.const 0x80000000)) (i64.const 1)) (i64.const 19))))
|
||||
(set_local $g3_19 (i64.sub (i64.mul (i64.const 19) (get_local $g3)) (i64.mul (i64.shl (i64.and (get_local $g3) (i64.const 0x80000000)) (i64.const 1)) (i64.const 19))))
|
||||
(set_local $g4_19 (i64.sub (i64.mul (i64.const 19) (get_local $g4)) (i64.mul (i64.shl (i64.and (get_local $g4) (i64.const 0x80000000)) (i64.const 1)) (i64.const 19))))
|
||||
(set_local $g5_19 (i64.sub (i64.mul (i64.const 19) (get_local $g5)) (i64.mul (i64.shl (i64.and (get_local $g5) (i64.const 0x80000000)) (i64.const 1)) (i64.const 19))))
|
||||
(set_local $g6_19 (i64.sub (i64.mul (i64.const 19) (get_local $g6)) (i64.mul (i64.shl (i64.and (get_local $g6) (i64.const 0x80000000)) (i64.const 1)) (i64.const 19))))
|
||||
(set_local $g7_19 (i64.sub (i64.mul (i64.const 19) (get_local $g7)) (i64.mul (i64.shl (i64.and (get_local $g7) (i64.const 0x80000000)) (i64.const 1)) (i64.const 19))))
|
||||
(set_local $g8_19 (i64.sub (i64.mul (i64.const 19) (get_local $g8)) (i64.mul (i64.shl (i64.and (get_local $g8) (i64.const 0x80000000)) (i64.const 1)) (i64.const 19))))
|
||||
(set_local $g9_19 (i64.sub (i64.mul (i64.const 19) (get_local $g9)) (i64.mul (i64.shl (i64.and (get_local $g9) (i64.const 0x80000000)) (i64.const 1)) (i64.const 19))))
|
||||
|
||||
(set_local $f1_2 (i64.sub (i64.mul (i64.const 2) (get_local $f1)) (i64.mul (i64.shl (i64.and (get_local $f1) (i64.const 0x80000000)) (i64.const 1)) (i64.const 2))))
|
||||
(set_local $f3_2 (i64.sub (i64.mul (i64.const 2) (get_local $f3)) (i64.mul (i64.shl (i64.and (get_local $f3) (i64.const 0x80000000)) (i64.const 1)) (i64.const 2))))
|
||||
(set_local $f5_2 (i64.sub (i64.mul (i64.const 2) (get_local $f5)) (i64.mul (i64.shl (i64.and (get_local $f5) (i64.const 0x80000000)) (i64.const 1)) (i64.const 2))))
|
||||
(set_local $f7_2 (i64.sub (i64.mul (i64.const 2) (get_local $f7)) (i64.mul (i64.shl (i64.and (get_local $f7) (i64.const 0x80000000)) (i64.const 1)) (i64.const 2))))
|
||||
(set_local $f9_2 (i64.sub (i64.mul (i64.const 2) (get_local $f9)) (i64.mul (i64.shl (i64.and (get_local $f9) (i64.const 0x80000000)) (i64.const 1)) (i64.const 2))))
|
||||
|
||||
(set_local $g1_19 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g1_19))))
|
||||
(set_local $g2_19 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g2_19))))
|
||||
(set_local $g3_19 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g3_19))))
|
||||
(set_local $g4_19 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g4_19))))
|
||||
(set_local $g5_19 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g5_19))))
|
||||
(set_local $g6_19 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g6_19))))
|
||||
(set_local $g7_19 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g7_19))))
|
||||
(set_local $g8_19 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g8_19))))
|
||||
(set_local $g9_19 (i64.extend_s/i32 (i32.wrap/i64 (get_local $g9_19))))
|
||||
|
||||
(set_local $f1_2 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f1_2))))
|
||||
(set_local $f3_2 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f3_2))))
|
||||
(set_local $f5_2 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f5_2))))
|
||||
(set_local $f7_2 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f7_2))))
|
||||
(set_local $f9_2 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f9_2))))
|
||||
|
||||
(set_local $f0g0 (i64.mul (get_local $f0 ) (get_local $g0)))
|
||||
(set_local $f0g1 (i64.mul (get_local $f0 ) (get_local $g1)))
|
||||
(set_local $f0g2 (i64.mul (get_local $f0 ) (get_local $g2)))
|
||||
(set_local $f0g3 (i64.mul (get_local $f0 ) (get_local $g3)))
|
||||
(set_local $f0g4 (i64.mul (get_local $f0 ) (get_local $g4)))
|
||||
(set_local $f0g5 (i64.mul (get_local $f0 ) (get_local $g5)))
|
||||
(set_local $f0g6 (i64.mul (get_local $f0 ) (get_local $g6)))
|
||||
(set_local $f0g7 (i64.mul (get_local $f0 ) (get_local $g7)))
|
||||
(set_local $f0g8 (i64.mul (get_local $f0 ) (get_local $g8)))
|
||||
(set_local $f0g9 (i64.mul (get_local $f0 ) (get_local $g9)))
|
||||
(set_local $f1g0 (i64.mul (get_local $f1 ) (get_local $g0)))
|
||||
(set_local $f1g1_2 (i64.mul (get_local $f1_2) (get_local $g1)))
|
||||
(set_local $f1g2 (i64.mul (get_local $f1 ) (get_local $g2)))
|
||||
(set_local $f1g3_2 (i64.mul (get_local $f1_2) (get_local $g3)))
|
||||
(set_local $f1g4 (i64.mul (get_local $f1 ) (get_local $g4)))
|
||||
(set_local $f1g5_2 (i64.mul (get_local $f1_2) (get_local $g5)))
|
||||
(set_local $f1g6 (i64.mul (get_local $f1 ) (get_local $g6)))
|
||||
(set_local $f1g7_2 (i64.mul (get_local $f1_2) (get_local $g7)))
|
||||
(set_local $f1g8 (i64.mul (get_local $f1 ) (get_local $g8)))
|
||||
(set_local $f1g9_38 (i64.mul (get_local $f1_2) (get_local $g9_19)))
|
||||
(set_local $f2g0 (i64.mul (get_local $f2 ) (get_local $g0)))
|
||||
(set_local $f2g1 (i64.mul (get_local $f2 ) (get_local $g1)))
|
||||
(set_local $f2g2 (i64.mul (get_local $f2 ) (get_local $g2)))
|
||||
(set_local $f2g3 (i64.mul (get_local $f2 ) (get_local $g3)))
|
||||
(set_local $f2g4 (i64.mul (get_local $f2 ) (get_local $g4)))
|
||||
(set_local $f2g5 (i64.mul (get_local $f2 ) (get_local $g5)))
|
||||
(set_local $f2g6 (i64.mul (get_local $f2 ) (get_local $g6)))
|
||||
(set_local $f2g7 (i64.mul (get_local $f2 ) (get_local $g7)))
|
||||
(set_local $f2g8_19 (i64.mul (get_local $f2 ) (get_local $g8_19)))
|
||||
(set_local $f2g9_19 (i64.mul (get_local $f2 ) (get_local $g9_19)))
|
||||
(set_local $f3g0 (i64.mul (get_local $f3 ) (get_local $g0)))
|
||||
(set_local $f3g1_2 (i64.mul (get_local $f3_2) (get_local $g1)))
|
||||
(set_local $f3g2 (i64.mul (get_local $f3 ) (get_local $g2)))
|
||||
(set_local $f3g3_2 (i64.mul (get_local $f3_2) (get_local $g3)))
|
||||
(set_local $f3g4 (i64.mul (get_local $f3 ) (get_local $g4)))
|
||||
(set_local $f3g5_2 (i64.mul (get_local $f3_2) (get_local $g5)))
|
||||
(set_local $f3g6 (i64.mul (get_local $f3 ) (get_local $g6)))
|
||||
(set_local $f3g7_38 (i64.mul (get_local $f3_2) (get_local $g7_19)))
|
||||
(set_local $f3g8_19 (i64.mul (get_local $f3 ) (get_local $g8_19)))
|
||||
(set_local $f3g9_38 (i64.mul (get_local $f3_2) (get_local $g9_19)))
|
||||
(set_local $f4g0 (i64.mul (get_local $f4) (get_local $g0)))
|
||||
(set_local $f4g1 (i64.mul (get_local $f4) (get_local $g1)))
|
||||
(set_local $f4g2 (i64.mul (get_local $f4) (get_local $g2)))
|
||||
(set_local $f4g3 (i64.mul (get_local $f4) (get_local $g3)))
|
||||
(set_local $f4g4 (i64.mul (get_local $f4) (get_local $g4)))
|
||||
(set_local $f4g5 (i64.mul (get_local $f4) (get_local $g5)))
|
||||
(set_local $f4g6_19 (i64.mul (get_local $f4) (get_local $g6_19)))
|
||||
(set_local $f4g7_19 (i64.mul (get_local $f4) (get_local $g7_19)))
|
||||
(set_local $f4g8_19 (i64.mul (get_local $f4) (get_local $g8_19)))
|
||||
(set_local $f4g9_19 (i64.mul (get_local $f4) (get_local $g9_19)))
|
||||
(set_local $f5g0 (i64.mul (get_local $f5) (get_local $g0)))
|
||||
(set_local $f5g1_2 (i64.mul (get_local $f5_2) (get_local $g1)))
|
||||
(set_local $f5g2 (i64.mul (get_local $f5) (get_local $g2)))
|
||||
(set_local $f5g3_2 (i64.mul (get_local $f5_2) (get_local $g3)))
|
||||
(set_local $f5g4 (i64.mul (get_local $f5) (get_local $g4)))
|
||||
(set_local $f5g5_38 (i64.mul (get_local $f5_2) (get_local $g5_19)))
|
||||
(set_local $f5g6_19 (i64.mul (get_local $f5) (get_local $g6_19)))
|
||||
(set_local $f5g7_38 (i64.mul (get_local $f5_2) (get_local $g7_19)))
|
||||
(set_local $f5g8_19 (i64.mul (get_local $f5) (get_local $g8_19)))
|
||||
(set_local $f5g9_38 (i64.mul (get_local $f5_2) (get_local $g9_19)))
|
||||
(set_local $f6g0 (i64.mul (get_local $f6) (get_local $g0)))
|
||||
(set_local $f6g1 (i64.mul (get_local $f6) (get_local $g1)))
|
||||
(set_local $f6g2 (i64.mul (get_local $f6) (get_local $g2)))
|
||||
(set_local $f6g3 (i64.mul (get_local $f6) (get_local $g3)))
|
||||
(set_local $f6g4_19 (i64.mul (get_local $f6) (get_local $g4_19)))
|
||||
(set_local $f6g5_19 (i64.mul (get_local $f6) (get_local $g5_19)))
|
||||
(set_local $f6g6_19 (i64.mul (get_local $f6) (get_local $g6_19)))
|
||||
(set_local $f6g7_19 (i64.mul (get_local $f6) (get_local $g7_19)))
|
||||
(set_local $f6g8_19 (i64.mul (get_local $f6) (get_local $g8_19)))
|
||||
(set_local $f6g9_19 (i64.mul (get_local $f6) (get_local $g9_19)))
|
||||
(set_local $f7g0 (i64.mul (get_local $f7) (get_local $g0)))
|
||||
(set_local $f7g1_2 (i64.mul (get_local $f7_2) (get_local $g1)))
|
||||
(set_local $f7g2 (i64.mul (get_local $f7) (get_local $g2)))
|
||||
(set_local $f7g3_38 (i64.mul (get_local $f7_2) (get_local $g3_19)))
|
||||
(set_local $f7g4_19 (i64.mul (get_local $f7) (get_local $g4_19)))
|
||||
(set_local $f7g5_38 (i64.mul (get_local $f7_2) (get_local $g5_19)))
|
||||
(set_local $f7g6_19 (i64.mul (get_local $f7) (get_local $g6_19)))
|
||||
(set_local $f7g7_38 (i64.mul (get_local $f7_2) (get_local $g7_19)))
|
||||
(set_local $f7g8_19 (i64.mul (get_local $f7) (get_local $g8_19)))
|
||||
(set_local $f7g9_38 (i64.mul (get_local $f7_2) (get_local $g9_19)))
|
||||
(set_local $f8g0 (i64.mul (get_local $f8) (get_local $g0)))
|
||||
(set_local $f8g1 (i64.mul (get_local $f8) (get_local $g1)))
|
||||
(set_local $f8g2_19 (i64.mul (get_local $f8) (get_local $g2_19)))
|
||||
(set_local $f8g3_19 (i64.mul (get_local $f8) (get_local $g3_19)))
|
||||
(set_local $f8g4_19 (i64.mul (get_local $f8) (get_local $g4_19)))
|
||||
(set_local $f8g5_19 (i64.mul (get_local $f8) (get_local $g5_19)))
|
||||
(set_local $f8g6_19 (i64.mul (get_local $f8) (get_local $g6_19)))
|
||||
(set_local $f8g7_19 (i64.mul (get_local $f8) (get_local $g7_19)))
|
||||
(set_local $f8g8_19 (i64.mul (get_local $f8) (get_local $g8_19)))
|
||||
(set_local $f8g9_19 (i64.mul (get_local $f8) (get_local $g9_19)))
|
||||
(set_local $f9g0 (i64.mul (get_local $f9) (get_local $g0)))
|
||||
(set_local $f9g1_38 (i64.mul (get_local $f9_2) (get_local $g1_19)))
|
||||
(set_local $f9g2_19 (i64.mul (get_local $f9) (get_local $g2_19)))
|
||||
(set_local $f9g3_38 (i64.mul (get_local $f9_2) (get_local $g3_19)))
|
||||
(set_local $f9g4_19 (i64.mul (get_local $f9) (get_local $g4_19)))
|
||||
(set_local $f9g5_38 (i64.mul (get_local $f9_2) (get_local $g5_19)))
|
||||
(set_local $f9g6_19 (i64.mul (get_local $f9) (get_local $g6_19)))
|
||||
(set_local $f9g7_38 (i64.mul (get_local $f9_2) (get_local $g7_19)))
|
||||
(set_local $f9g8_19 (i64.mul (get_local $f9) (get_local $g8_19)))
|
||||
(set_local $f9g9_38 (i64.mul (get_local $f9_2) (get_local $g9_19)))
|
||||
|
||||
(set_local $h0 (i64.add (get_local $f0g0) (i64.add (get_local $f1g9_38) (i64.add (get_local $f2g8_19) (i64.add (get_local $f3g7_38) (i64.add (get_local $f4g6_19) (i64.add (get_local $f5g5_38) (i64.add (get_local $f6g4_19) (i64.add (get_local $f7g3_38) (i64.add (get_local $f8g2_19) (get_local $f9g1_38)))))))))))
|
||||
(set_local $h1 (i64.add (get_local $f0g1) (i64.add (get_local $f1g0) (i64.add (get_local $f2g9_19) (i64.add (get_local $f3g8_19) (i64.add (get_local $f4g7_19) (i64.add (get_local $f5g6_19) (i64.add (get_local $f6g5_19) (i64.add (get_local $f7g4_19) (i64.add (get_local $f8g3_19) (get_local $f9g2_19)))))))))))
|
||||
(set_local $h2 (i64.add (get_local $f0g2) (i64.add (get_local $f1g1_2) (i64.add (get_local $f2g0) (i64.add (get_local $f3g9_38) (i64.add (get_local $f4g8_19) (i64.add (get_local $f5g7_38) (i64.add (get_local $f6g6_19) (i64.add (get_local $f7g5_38) (i64.add (get_local $f8g4_19) (get_local $f9g3_38)))))))))))
|
||||
(set_local $h3 (i64.add (get_local $f0g3) (i64.add (get_local $f1g2) (i64.add (get_local $f2g1) (i64.add (get_local $f3g0) (i64.add (get_local $f4g9_19) (i64.add (get_local $f5g8_19) (i64.add (get_local $f6g7_19) (i64.add (get_local $f7g6_19) (i64.add (get_local $f8g5_19) (get_local $f9g4_19)))))))))))
|
||||
(set_local $h4 (i64.add (get_local $f0g4) (i64.add (get_local $f1g3_2) (i64.add (get_local $f2g2) (i64.add (get_local $f3g1_2) (i64.add (get_local $f4g0) (i64.add (get_local $f5g9_38) (i64.add (get_local $f6g8_19) (i64.add (get_local $f7g7_38) (i64.add (get_local $f8g6_19) (get_local $f9g5_38)))))))))))
|
||||
(set_local $h5 (i64.add (get_local $f0g5) (i64.add (get_local $f1g4) (i64.add (get_local $f2g3) (i64.add (get_local $f3g2) (i64.add (get_local $f4g1) (i64.add (get_local $f5g0) (i64.add (get_local $f6g9_19) (i64.add (get_local $f7g8_19) (i64.add (get_local $f8g7_19) (get_local $f9g6_19)))))))))))
|
||||
(set_local $h6 (i64.add (get_local $f0g6) (i64.add (get_local $f1g5_2) (i64.add (get_local $f2g4) (i64.add (get_local $f3g3_2) (i64.add (get_local $f4g2) (i64.add (get_local $f5g1_2) (i64.add (get_local $f6g0) (i64.add (get_local $f7g9_38) (i64.add (get_local $f8g8_19) (get_local $f9g7_38)))))))))))
|
||||
(set_local $h7 (i64.add (get_local $f0g7) (i64.add (get_local $f1g6) (i64.add (get_local $f2g5) (i64.add (get_local $f3g4) (i64.add (get_local $f4g3) (i64.add (get_local $f5g2) (i64.add (get_local $f6g1) (i64.add (get_local $f7g0) (i64.add (get_local $f8g9_19) (get_local $f9g8_19)))))))))))
|
||||
(set_local $h8 (i64.add (get_local $f0g8) (i64.add (get_local $f1g7_2) (i64.add (get_local $f2g6) (i64.add (get_local $f3g5_2) (i64.add (get_local $f4g4) (i64.add (get_local $f5g3_2) (i64.add (get_local $f6g2) (i64.add (get_local $f7g1_2) (i64.add (get_local $f8g0) (get_local $f9g9_38)))))))))))
|
||||
(set_local $h9 (i64.add (get_local $f0g9) (i64.add (get_local $f1g8) (i64.add (get_local $f2g7) (i64.add (get_local $f3g6) (i64.add (get_local $f4g5) (i64.add (get_local $f5g4) (i64.add (get_local $f6g3) (i64.add (get_local $f7g2) (i64.add (get_local $f8g1) (get_local $f9g0)))))))))))
|
||||
|
||||
(set_local $carry0 (i64.shr_s (i64.add (get_local $h0) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
|
||||
(set_local $h1 (i64.add (get_local $h1) (get_local $carry0)))
|
||||
(set_local $h0 (i64.sub (get_local $h0) (i64.mul (get_local $carry0) (i64.shl (i64.const 1) (i64.const 26)))))
|
||||
(set_local $carry4 (i64.shr_s (i64.add (get_local $h4) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
|
||||
(set_local $h5 (i64.add (get_local $h5) (get_local $carry4)))
|
||||
(set_local $h4 (i64.sub (get_local $h4) (i64.mul (get_local $carry4) (i64.shl (i64.const 1) (i64.const 26)))))
|
||||
|
||||
(set_local $carry1 (i64.shr_s (i64.add (get_local $h1) (i64.shl (i64.const 1) (i64.const 24))) (i64.const 25)))
|
||||
(set_local $h2 (i64.add (get_local $h2) (get_local $carry1)))
|
||||
(set_local $h1 (i64.sub (get_local $h1) (i64.mul (get_local $carry1) (i64.shl (i64.const 1) (i64.const 25)))))
|
||||
(set_local $carry5 (i64.shr_s (i64.add (get_local $h5) (i64.shl (i64.const 1) (i64.const 24))) (i64.const 25)))
|
||||
(set_local $h6 (i64.add (get_local $h6) (get_local $carry5)))
|
||||
(set_local $h5 (i64.sub (get_local $h5) (i64.mul (get_local $carry5) (i64.shl (i64.const 1) (i64.const 25)))))
|
||||
|
||||
(set_local $carry2 (i64.shr_s (i64.add (get_local $h2) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
|
||||
(set_local $h3 (i64.add (get_local $h3) (get_local $carry2)))
|
||||
(set_local $h2 (i64.sub (get_local $h2) (i64.mul (get_local $carry2) (i64.shl (i64.const 1) (i64.const 26)))))
|
||||
(set_local $carry6 (i64.shr_s (i64.add (get_local $h6) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
|
||||
(set_local $h7 (i64.add (get_local $h7) (get_local $carry6)))
|
||||
(set_local $h6 (i64.sub (get_local $h6) (i64.mul (get_local $carry6) (i64.shl (i64.const 1) (i64.const 26)))))
|
||||
|
||||
(set_local $carry3 (i64.shr_s (i64.add (get_local $h3) (i64.shl (i64.const 1) (i64.const 24))) (i64.const 25)))
|
||||
(set_local $h4 (i64.add (get_local $h4) (get_local $carry3)))
|
||||
(set_local $h3 (i64.sub (get_local $h3) (i64.mul (get_local $carry3) (i64.shl (i64.const 1) (i64.const 25)))))
|
||||
(set_local $carry7 (i64.shr_s (i64.add (get_local $h7) (i64.shl (i64.const 1) (i64.const 24))) (i64.const 25)))
|
||||
(set_local $h8 (i64.add (get_local $h8) (get_local $carry7)))
|
||||
(set_local $h7 (i64.sub (get_local $h7) (i64.mul (get_local $carry7) (i64.shl (i64.const 1) (i64.const 25)))))
|
||||
|
||||
(set_local $carry4 (i64.shr_s (i64.add (get_local $h4) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
|
||||
(set_local $h5 (i64.add (get_local $h5) (get_local $carry4)))
|
||||
(set_local $h4 (i64.sub (get_local $h4) (i64.mul (get_local $carry4) (i64.shl (i64.const 1) (i64.const 26)))))
|
||||
(set_local $carry8 (i64.shr_s (i64.add (get_local $h8) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
|
||||
(set_local $h9 (i64.add (get_local $h9) (get_local $carry8)))
|
||||
(set_local $h8 (i64.sub (get_local $h8) (i64.mul (get_local $carry8) (i64.shl (i64.const 1) (i64.const 26)))))
|
||||
|
||||
(set_local $carry9 (i64.shr_s (i64.add (get_local $h9) (i64.shl (i64.const 1) (i64.const 24))) (i64.const 25)))
|
||||
(set_local $h0 (i64.add (get_local $h0) (i64.mul (get_local $carry9) (i64.const 19))))
|
||||
(set_local $h9 (i64.sub (get_local $h9) (i64.mul (get_local $carry9) (i64.shl (i64.const 1) (i64.const 25)))))
|
||||
|
||||
(set_local $carry0 (i64.shr_s (i64.add (get_local $h0) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
|
||||
(set_local $h1 (i64.add (get_local $h1) (get_local $carry0)))
|
||||
(set_local $h0 (i64.sub (get_local $h0) (i64.mul (get_local $carry0) (i64.shl (i64.const 1) (i64.const 26)))))
|
||||
|
||||
(i64.store32 offset=0 (get_local $h) (get_local $h0))
|
||||
(i64.store32 offset=4 (get_local $h) (get_local $h1))
|
||||
(i64.store32 offset=8 (get_local $h) (get_local $h2))
|
||||
(i64.store32 offset=12 (get_local $h) (get_local $h3))
|
||||
(i64.store32 offset=16 (get_local $h) (get_local $h4))
|
||||
(i64.store32 offset=20 (get_local $h) (get_local $h5))
|
||||
(i64.store32 offset=24 (get_local $h) (get_local $h6))
|
||||
(i64.store32 offset=28 (get_local $h) (get_local $h7))
|
||||
(i64.store32 offset=32 (get_local $h) (get_local $h8))
|
||||
(i64.store32 offset=36 (get_local $h) (get_local $h9)))
|
||||
|
||||
(func $fe25519_mul (export "fe25519_mul") (param $h i32) (param $f i32) (param $g i32)
|
||||
(i64.load32_u offset=0 (get_local $f))
|
||||
(i64.load32_u offset=4 (get_local $f))
|
||||
(i64.load32_u offset=8 (get_local $f))
|
||||
(i64.load32_u offset=12 (get_local $f))
|
||||
(i64.load32_u offset=16 (get_local $f))
|
||||
(i64.load32_u offset=20 (get_local $f))
|
||||
(i64.load32_u offset=24 (get_local $f))
|
||||
(i64.load32_u offset=28 (get_local $f))
|
||||
(i64.load32_u offset=32 (get_local $f))
|
||||
(i64.load32_u offset=36 (get_local $f))
|
||||
(i64.load32_u offset=0 (get_local $g))
|
||||
(i64.load32_u offset=4 (get_local $g))
|
||||
(i64.load32_u offset=8 (get_local $g))
|
||||
(i64.load32_u offset=12 (get_local $g))
|
||||
(i64.load32_u offset=16 (get_local $g))
|
||||
(i64.load32_u offset=20 (get_local $g))
|
||||
(i64.load32_u offset=24 (get_local $g))
|
||||
(i64.load32_u offset=28 (get_local $g))
|
||||
(i64.load32_u offset=32 (get_local $g))
|
||||
(i64.load32_u offset=36 (get_local $g))
|
||||
(get_local $h)
|
||||
(call $fe_mul)))
|
||||
@@ -0,0 +1,61 @@
|
||||
|
||||
module.exports = loadWebAssembly
|
||||
|
||||
loadWebAssembly.supported = typeof WebAssembly !== 'undefined'
|
||||
|
||||
function loadWebAssembly (opts) {
|
||||
if (!loadWebAssembly.supported) return null
|
||||
|
||||
var imp = opts && opts.imports
|
||||
var wasm = toUint8Array('AGFzbQEAAAABFgJgDH5+fn5+fn5+fn5/fwBgA39/fwADAwIAAQUDAQABBxoCBm1lbW9yeQIADWZlMjU1MTlfbXVsMzIAAQrcBAKeBAEVfiAKrCEMIACnrCEAIAGnrCEBIAKnrCECIAOnrCEDIASnrCEEIAWnrCEFIAanrCEGIAenrCEHIAinrCEIIAmnrCEJIAAgDH4hDSABIAx+IQ4gAiAMfiEPIAMgDH4hECAEIAx+IREgBSAMfiESIAYgDH4hEyAHIAx+IRQgCCAMfiEVIAkgDH4hFiAWQgFCGIZ8QhmHISAgDSAgQhN+fCENIBYgIEIBQhmGfn0hFiAOQgFCGIZ8QhmHIRggDyAYfCEPIA4gGEIBQhmGfn0hDiAQQgFCGIZ8QhmHIRogESAafCERIBAgGkIBQhmGfn0hECASQgFCGIZ8QhmHIRwgEyAcfCETIBIgHEIBQhmGfn0hEiAUQgFCGIZ8QhmHIR4gFSAefCEVIBQgHkIBQhmGfn0hFCANQgFCGYZ8QhqHIRcgDiAXfCEOIA0gF0IBQhqGfn0hDSAPQgFCGYZ8QhqHIRkgECAZfCEQIA8gGUIBQhqGfn0hDyARQgFCGYZ8QhqHIRsgEiAbfCESIBEgG0IBQhqGfn0hESATQgFCGYZ8QhqHIR0gFCAdfCEUIBMgHUIBQhqGfn0hEyAVQgFCGYZ8QhqHIR8gFiAffCEWIBUgH0IBQhqGfn0hFSALIA0+AgAgCyAOPgIEIAsgDz4CCCALIBA+AgwgCyARPgIQIAsgEj4CFCALIBM+AhggCyAUPgIcIAsgFT4CICALIBY+AiQLOgAgATUCACABNQIEIAE1AgggATUCDCABNQIQIAE1AhQgATUCGCABNQIcIAE1AiAgATUCJCACIAAQAAs=')
|
||||
var ready = null
|
||||
|
||||
var mod = {
|
||||
buffer: wasm,
|
||||
memory: null,
|
||||
exports: null,
|
||||
realloc: realloc,
|
||||
onload: onload
|
||||
}
|
||||
|
||||
onload(function () {})
|
||||
|
||||
return mod
|
||||
|
||||
function realloc (size) {
|
||||
mod.exports.memory.grow(Math.max(0, Math.ceil(Math.abs(size - mod.memory.length) / 65536)))
|
||||
mod.memory = new Uint8Array(mod.exports.memory.buffer)
|
||||
}
|
||||
|
||||
function onload (cb) {
|
||||
if (mod.exports) return cb()
|
||||
|
||||
if (ready) {
|
||||
ready.then(cb.bind(null, null)).catch(cb)
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
if (opts && opts.async) throw new Error('async')
|
||||
setup({instance: new WebAssembly.Instance(new WebAssembly.Module(wasm), imp)})
|
||||
} catch (err) {
|
||||
ready = WebAssembly.instantiate(wasm, imp).then(setup)
|
||||
}
|
||||
|
||||
onload(cb)
|
||||
}
|
||||
|
||||
function setup (w) {
|
||||
mod.exports = w.instance.exports
|
||||
mod.memory = mod.exports.memory && mod.exports.memory.buffer && new Uint8Array(mod.exports.memory.buffer)
|
||||
}
|
||||
}
|
||||
|
||||
function toUint8Array (s) {
|
||||
if (typeof atob === 'function') return new Uint8Array(atob(s).split('').map(charCodeAt))
|
||||
return (require('buf' + 'fer').Buffer).from(s, 'base64')
|
||||
}
|
||||
|
||||
function charCodeAt (c) {
|
||||
return c.charCodeAt(0)
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
(module
|
||||
(memory $0 1)
|
||||
(export "memory" (memory $0))
|
||||
|
||||
;; (func $i32.log (import "debug" "log") (param i32))
|
||||
;; (func $i32.log_tee (import "debug" "log_tee") (param i32) (result i32))
|
||||
;; ;; No i64 interop with JS yet - but maybe coming with WebAssembly BigInt
|
||||
;; ;; So we can instead fake this by splitting the i64 into two i32 limbs,
|
||||
;; ;; however these are WASM functions using i32x2.log:
|
||||
;; (func $i32x2.log (import "debug" "log") (param i32) (param i32))
|
||||
;; (func $f32.log (import "debug" "log") (param f32))
|
||||
;; (func $f32.log_tee (import "debug" "log_tee") (param f32) (result f32))
|
||||
;; (func $f64.log (import "debug" "log") (param f64))
|
||||
;; (func $f64.log_tee (import "debug" "log_tee") (param f64) (result f64))
|
||||
|
||||
;; ;; i64 logging by splitting into two i32 limbs
|
||||
;; (func $i64.log
|
||||
;; (param $0 i64)
|
||||
;; (call $i32x2.log
|
||||
;; ;; Upper limb
|
||||
;; (i32.wrap/i64
|
||||
;; (i64.shr_s (get_local $0)
|
||||
;; (i64.const 32)))
|
||||
;; ;; Lower limb
|
||||
;; (i32.wrap/i64 (get_local $0))))
|
||||
|
||||
;; (func $i64.log_tee
|
||||
;; (param $0 i64)
|
||||
;; (result i64)
|
||||
;; (call $i64.log (get_local $0))
|
||||
;; (return (get_local $0)))
|
||||
|
||||
(func $fe_mul32
|
||||
(param $f0 i64)
|
||||
(param $f1 i64)
|
||||
(param $f2 i64)
|
||||
(param $f3 i64)
|
||||
(param $f4 i64)
|
||||
(param $f5 i64)
|
||||
(param $f6 i64)
|
||||
(param $f7 i64)
|
||||
(param $f8 i64)
|
||||
(param $f9 i64)
|
||||
|
||||
(param $n i32)
|
||||
|
||||
(param $h i32)
|
||||
|
||||
(local $sn i64)
|
||||
|
||||
(local $h0 i64)
|
||||
(local $h1 i64)
|
||||
(local $h2 i64)
|
||||
(local $h3 i64)
|
||||
(local $h4 i64)
|
||||
(local $h5 i64)
|
||||
(local $h6 i64)
|
||||
(local $h7 i64)
|
||||
(local $h8 i64)
|
||||
(local $h9 i64)
|
||||
|
||||
(local $carry0 i64)
|
||||
(local $carry1 i64)
|
||||
(local $carry2 i64)
|
||||
(local $carry3 i64)
|
||||
(local $carry4 i64)
|
||||
(local $carry5 i64)
|
||||
(local $carry6 i64)
|
||||
(local $carry7 i64)
|
||||
(local $carry8 i64)
|
||||
(local $carry9 i64)
|
||||
|
||||
(set_local $sn (i64.extend_s/i32 (get_local $n)))
|
||||
|
||||
(set_local $f0 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f0))))
|
||||
(set_local $f1 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f1))))
|
||||
(set_local $f2 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f2))))
|
||||
(set_local $f3 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f3))))
|
||||
(set_local $f4 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f4))))
|
||||
(set_local $f5 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f5))))
|
||||
(set_local $f6 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f6))))
|
||||
(set_local $f7 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f7))))
|
||||
(set_local $f8 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f8))))
|
||||
(set_local $f9 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f9))))
|
||||
|
||||
(set_local $h0 (i64.mul (get_local $f0) (get_local $sn)))
|
||||
(set_local $h1 (i64.mul (get_local $f1) (get_local $sn)))
|
||||
(set_local $h2 (i64.mul (get_local $f2) (get_local $sn)))
|
||||
(set_local $h3 (i64.mul (get_local $f3) (get_local $sn)))
|
||||
(set_local $h4 (i64.mul (get_local $f4) (get_local $sn)))
|
||||
(set_local $h5 (i64.mul (get_local $f5) (get_local $sn)))
|
||||
(set_local $h6 (i64.mul (get_local $f6) (get_local $sn)))
|
||||
(set_local $h7 (i64.mul (get_local $f7) (get_local $sn)))
|
||||
(set_local $h8 (i64.mul (get_local $f8) (get_local $sn)))
|
||||
(set_local $h9 (i64.mul (get_local $f9) (get_local $sn)))
|
||||
|
||||
(set_local $carry9 (i64.shr_s (i64.add (get_local $h9) (i64.shl (i64.const 1) (i64.const 24))) (i64.const 25)))
|
||||
(set_local $h0 (i64.add (get_local $h0) (i64.mul (get_local $carry9) (i64.const 19))))
|
||||
(set_local $h9 (i64.sub (get_local $h9) (i64.mul (get_local $carry9) (i64.shl (i64.const 1) (i64.const 25)))))
|
||||
|
||||
(set_local $carry1 (i64.shr_s (i64.add (get_local $h1) (i64.shl (i64.const 1) (i64.const 24))) (i64.const 25)))
|
||||
(set_local $h2 (i64.add (get_local $h2) (get_local $carry1)))
|
||||
(set_local $h1 (i64.sub (get_local $h1) (i64.mul (get_local $carry1) (i64.shl (i64.const 1) (i64.const 25)))))
|
||||
|
||||
(set_local $carry3 (i64.shr_s (i64.add (get_local $h3) (i64.shl (i64.const 1) (i64.const 24))) (i64.const 25)))
|
||||
(set_local $h4 (i64.add (get_local $h4) (get_local $carry3)))
|
||||
(set_local $h3 (i64.sub (get_local $h3) (i64.mul (get_local $carry3) (i64.shl (i64.const 1) (i64.const 25)))))
|
||||
|
||||
(set_local $carry5 (i64.shr_s (i64.add (get_local $h5) (i64.shl (i64.const 1) (i64.const 24))) (i64.const 25)))
|
||||
(set_local $h6 (i64.add (get_local $h6) (get_local $carry5)))
|
||||
(set_local $h5 (i64.sub (get_local $h5) (i64.mul (get_local $carry5) (i64.shl (i64.const 1) (i64.const 25)))))
|
||||
|
||||
(set_local $carry7 (i64.shr_s (i64.add (get_local $h7) (i64.shl (i64.const 1) (i64.const 24))) (i64.const 25)))
|
||||
(set_local $h8 (i64.add (get_local $h8) (get_local $carry7)))
|
||||
(set_local $h7 (i64.sub (get_local $h7) (i64.mul (get_local $carry7) (i64.shl (i64.const 1) (i64.const 25)))))
|
||||
|
||||
(set_local $carry0 (i64.shr_s (i64.add (get_local $h0) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
|
||||
(set_local $h1 (i64.add (get_local $h1) (get_local $carry0)))
|
||||
(set_local $h0 (i64.sub (get_local $h0) (i64.mul (get_local $carry0) (i64.shl (i64.const 1) (i64.const 26)))))
|
||||
|
||||
(set_local $carry2 (i64.shr_s (i64.add (get_local $h2) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
|
||||
(set_local $h3 (i64.add (get_local $h3) (get_local $carry2)))
|
||||
(set_local $h2 (i64.sub (get_local $h2) (i64.mul (get_local $carry2) (i64.shl (i64.const 1) (i64.const 26)))))
|
||||
|
||||
(set_local $carry4 (i64.shr_s (i64.add (get_local $h4) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
|
||||
(set_local $h5 (i64.add (get_local $h5) (get_local $carry4)))
|
||||
(set_local $h4 (i64.sub (get_local $h4) (i64.mul (get_local $carry4) (i64.shl (i64.const 1) (i64.const 26)))))
|
||||
|
||||
(set_local $carry6 (i64.shr_s (i64.add (get_local $h6) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
|
||||
(set_local $h7 (i64.add (get_local $h7) (get_local $carry6)))
|
||||
(set_local $h6 (i64.sub (get_local $h6) (i64.mul (get_local $carry6) (i64.shl (i64.const 1) (i64.const 26)))))
|
||||
|
||||
(set_local $carry8 (i64.shr_s (i64.add (get_local $h8) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
|
||||
(set_local $h9 (i64.add (get_local $h9) (get_local $carry8)))
|
||||
(set_local $h8 (i64.sub (get_local $h8) (i64.mul (get_local $carry8) (i64.shl (i64.const 1) (i64.const 26)))))
|
||||
|
||||
(i64.store32 offset=0 (get_local $h) (get_local $h0))
|
||||
(i64.store32 offset=4 (get_local $h) (get_local $h1))
|
||||
(i64.store32 offset=8 (get_local $h) (get_local $h2))
|
||||
(i64.store32 offset=12 (get_local $h) (get_local $h3))
|
||||
(i64.store32 offset=16 (get_local $h) (get_local $h4))
|
||||
(i64.store32 offset=20 (get_local $h) (get_local $h5))
|
||||
(i64.store32 offset=24 (get_local $h) (get_local $h6))
|
||||
(i64.store32 offset=28 (get_local $h) (get_local $h7))
|
||||
(i64.store32 offset=32 (get_local $h) (get_local $h8))
|
||||
(i64.store32 offset=36 (get_local $h) (get_local $h9)))
|
||||
|
||||
(func $fe25519_mul32 (export "fe25519_mul32") (param $h i32) (param $f i32) (param $n i32)
|
||||
(i64.load32_u offset=0 (get_local $f))
|
||||
(i64.load32_u offset=4 (get_local $f))
|
||||
(i64.load32_u offset=8 (get_local $f))
|
||||
(i64.load32_u offset=12 (get_local $f))
|
||||
(i64.load32_u offset=16 (get_local $f))
|
||||
(i64.load32_u offset=20 (get_local $f))
|
||||
(i64.load32_u offset=24 (get_local $f))
|
||||
(i64.load32_u offset=28 (get_local $f))
|
||||
(i64.load32_u offset=32 (get_local $f))
|
||||
(i64.load32_u offset=36 (get_local $f))
|
||||
(get_local $n)
|
||||
(get_local $h)
|
||||
(call $fe_mul32)))
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,61 @@
|
||||
|
||||
module.exports = loadWebAssembly
|
||||
|
||||
loadWebAssembly.supported = typeof WebAssembly !== 'undefined'
|
||||
|
||||
function loadWebAssembly (opts) {
|
||||
if (!loadWebAssembly.supported) return null
|
||||
|
||||
var imp = opts && opts.imports
|
||||
var wasm = toUint8Array('AGFzbQEAAAABQQtgAX8AYAF/AX9gAn9/AGABfQBgAX0BfWABfABgAXwBfGABfgBgAX4BfmANfn5+fn5+fn5+fn9/fwBgBH9/f38AAngJAmpzBXRhYmxlAXAAAQJqcwNtZW0CAAEFZGVidWcDbG9nAAAFZGVidWcHbG9nX3RlZQABBWRlYnVnA2xvZwACBWRlYnVnA2xvZwADBWRlYnVnB2xvZ190ZWUABAVkZWJ1ZwNsb2cABQVkZWJ1Zwdsb2dfdGVlAAYDBQQHCAkKBwYBAnNxAAoJBwEAQQILAQkK3goEDQAgAEIgh6cgAKcQAgsJACAAEAcgAA8LhgoCAX9ZfgJAA0AgAKesIQAgAaesIQEgAqesIQIgA6esIQMgBKesIQQgBaesIQUgBqesIQYgB6esIQcgCKesIQggCaesIQkgAEICfiEjIAFCAn4hJCACQgJ+ISUgA0ICfiEmIARCAn4hJyAFQgJ+ISggBkICfiEpIAdCAn4hKiAFQiZ+ISsgBkITfiEsIAdCJn4hLSAIQhN+IS4gCUImfiEvIAAgAH4hMCAjIAF+ITEgIyACfiEyICMgA34hMyAjIAR+ITQgIyAFfiE1ICMgBn4hNiAjIAd+ITcgIyAIfiE4ICMgCX4hOSAkIAF+ITogJCACfiE7ICQgJn4hPCAkIAR+IT0gJCAofiE+ICQgBn4hPyAkICp+IUAgJCAIfiFBICQgL34hQiACIAJ+IUMgJSADfiFEICUgBH4hRSAlIAV+IUYgJSAGfiFHICUgB34hSCAlIC5+IUkgAiAvfiFKICYgA34hSyAmIAR+IUwgJiAofiFNICYgBn4hTiAmIC1+IU8gJiAufiFQICYgL34hUSAEIAR+IVIgJyAFfiFTICcgLH4hVCAEIC1+IVUgJyAufiFWIAQgL34hVyAFICt+IVggKCAsfiFZICggLX4hWiAoIC5+IVsgKCAvfiFcIAYgLH4hXSAGIC1+IV4gKSAufiFfIAYgL34hYCAHIC1+IWEgKiAufiFiICogL34hYyAIIC5+IWQgCCAvfiFlIAkgL34hZiAwIEIgSSBPIFQgWHx8fHx8IQ8gMSBKIFAgVSBZfHx8fCEQIDIgOiBRIFYgWiBdfHx8fHwhESAzIDsgVyBbIF58fHx8IRIgNCA8IEMgXCBfIGF8fHx8fCETIDUgPSBEIGAgYnx8fHwhFCA2ID4gRSBLIGMgZHx8fHx8IRUgNyA/IEYgTCBlfHx8fCEWIDggQCBHIE0gUiBmfHx8fHwhFyA5IEEgSCBOIFN8fHx8IRggDSALRg0BIA1BAWohDQwACwsgCkEBRgRAIA8gD3whDyAQIBB8IRAgESARfCERIBIgEnwhEiATIBN8IRMgFCAUfCEUIBUgFXwhFSAWIBZ8IRYgFyAXfCEXIBggGHwhGAsgD0IBQhmGfEIahyEZIBAgGXwhECAPIBlCAUIahn59IQ8gE0IBQhmGfEIahyEdIBQgHXwhFCATIB1CAUIahn59IRMgEEIBQhiGfEIZhyEaIBEgGnwhESAQIBpCAUIZhn59IRAgFEIBQhiGfEIZhyEeIBUgHnwhFSAUIB5CAUIZhn59IRQgEUIBQhmGfEIahyEbIBIgG3whEiARIBtCAUIahn59IREgFUIBQhmGfEIahyEfIBYgH3whFiAVIB9CAUIahn59IRUgEkIBQhiGfEIZhyEcIBMgHHwhEyASIBxCAUIZhn59IRIgFkIBQhiGfEIZhyEgIBcgIHwhFyAWICBCAUIZhn59IRYgE0IBQhmGfEIahyEdIBQgHXwhFCATIB1CAUIahn59IRMgF0IBQhmGfEIahyEhIBggIXwhGCAXICFCAUIahn59IRcgGEIBQhiGfEIZhyEiIA8gIkITfnwhDyAYICJCAUIZhn59IRggD0IBQhmGfEIahyEZIBAgGXwhECAPIBlCAUIahn59IQ8gDCAPPgIAIAwgED4CBCAMIBE+AgggDCASPgIMIAwgEz4CECAMIBQ+AhQgDCAVPgIYIAwgFj4CHCAMIBc+AiAgDCAYPgIkCzwAIAE1AgAgATUCBCABNQIIIAE1AgwgATUCECABNQIUIAE1AhggATUCHCABNQIgIAE1AiQgAiADIAAQCQs=')
|
||||
var ready = null
|
||||
|
||||
var mod = {
|
||||
buffer: wasm,
|
||||
memory: null,
|
||||
exports: null,
|
||||
realloc: realloc,
|
||||
onload: onload
|
||||
}
|
||||
|
||||
onload(function () {})
|
||||
|
||||
return mod
|
||||
|
||||
function realloc (size) {
|
||||
mod.exports.memory.grow(Math.max(0, Math.ceil(Math.abs(size - mod.memory.length) / 65536)))
|
||||
mod.memory = new Uint8Array(mod.exports.memory.buffer)
|
||||
}
|
||||
|
||||
function onload (cb) {
|
||||
if (mod.exports) return cb()
|
||||
|
||||
if (ready) {
|
||||
ready.then(cb.bind(null, null)).catch(cb)
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
if (opts && opts.async) throw new Error('async')
|
||||
setup({instance: new WebAssembly.Instance(new WebAssembly.Module(wasm), imp)})
|
||||
} catch (err) {
|
||||
ready = WebAssembly.instantiate(wasm, imp).then(setup)
|
||||
}
|
||||
|
||||
onload(cb)
|
||||
}
|
||||
|
||||
function setup (w) {
|
||||
mod.exports = w.instance.exports
|
||||
mod.memory = mod.exports.memory && mod.exports.memory.buffer && new Uint8Array(mod.exports.memory.buffer)
|
||||
}
|
||||
}
|
||||
|
||||
function toUint8Array (s) {
|
||||
if (typeof atob === 'function') return new Uint8Array(atob(s).split('').map(charCodeAt))
|
||||
return (require('buf' + 'fer').Buffer).from(s, 'base64')
|
||||
}
|
||||
|
||||
function charCodeAt (c) {
|
||||
return c.charCodeAt(0)
|
||||
}
|
||||
@@ -0,0 +1,328 @@
|
||||
(module
|
||||
(import "js" "table" (table 1 anyfunc))
|
||||
(import "js" "mem" (memory 1))
|
||||
|
||||
(elem (i32.const 2) $fe_sq)
|
||||
|
||||
(func $i32.log (import "debug" "log") (param i32))
|
||||
(func $i32.log_tee (import "debug" "log_tee") (param i32) (result i32))
|
||||
;; No i64 interop with JS yet - but maybe coming with WebAssembly BigInt
|
||||
;; So we can instead fake this by splitting the i64 into two i32 limbs,
|
||||
;; however these are WASM functions using i32x2.log:
|
||||
(func $i32x2.log (import "debug" "log") (param i32) (param i32))
|
||||
(func $f32.log (import "debug" "log") (param f32))
|
||||
(func $f32.log_tee (import "debug" "log_tee") (param f32) (result f32))
|
||||
(func $f64.log (import "debug" "log") (param f64))
|
||||
(func $f64.log_tee (import "debug" "log_tee") (param f64) (result f64))
|
||||
|
||||
;; i64 logging by splitting into two i32 limbs
|
||||
(func $i64.log
|
||||
(param $0 i64)
|
||||
(call $i32x2.log
|
||||
;; Upper limb
|
||||
(i32.wrap/i64
|
||||
(i64.shr_s (get_local $0)
|
||||
(i64.const 32)))
|
||||
;; Lower limb
|
||||
(i32.wrap/i64 (get_local $0))))
|
||||
|
||||
(func $i64.log_tee
|
||||
(param $0 i64)
|
||||
(result i64)
|
||||
(call $i64.log (get_local $0))
|
||||
(return (get_local $0)))
|
||||
|
||||
(func $fe_sq
|
||||
(param $f0 i64)
|
||||
(param $f1 i64)
|
||||
(param $f2 i64)
|
||||
(param $f3 i64)
|
||||
(param $f4 i64)
|
||||
(param $f5 i64)
|
||||
(param $f6 i64)
|
||||
(param $f7 i64)
|
||||
(param $f8 i64)
|
||||
(param $f9 i64)
|
||||
|
||||
(param $double i32)
|
||||
(param $repeat i32)
|
||||
|
||||
(param $h i32)
|
||||
|
||||
(local $count i32)
|
||||
(local $tmp i64)
|
||||
|
||||
(local $h0 i64)
|
||||
(local $h1 i64)
|
||||
(local $h2 i64)
|
||||
(local $h3 i64)
|
||||
(local $h4 i64)
|
||||
(local $h5 i64)
|
||||
(local $h6 i64)
|
||||
(local $h7 i64)
|
||||
(local $h8 i64)
|
||||
(local $h9 i64)
|
||||
|
||||
(local $carry0 i64)
|
||||
(local $carry1 i64)
|
||||
(local $carry2 i64)
|
||||
(local $carry3 i64)
|
||||
(local $carry4 i64)
|
||||
(local $carry5 i64)
|
||||
(local $carry6 i64)
|
||||
(local $carry7 i64)
|
||||
(local $carry8 i64)
|
||||
(local $carry9 i64)
|
||||
|
||||
(local $f0_2 i64)
|
||||
(local $f1_2 i64)
|
||||
(local $f2_2 i64)
|
||||
(local $f3_2 i64)
|
||||
(local $f4_2 i64)
|
||||
(local $f5_2 i64)
|
||||
(local $f6_2 i64)
|
||||
(local $f7_2 i64)
|
||||
|
||||
(local $f5_38 i64)
|
||||
(local $f6_19 i64)
|
||||
(local $f7_38 i64)
|
||||
(local $f8_19 i64)
|
||||
(local $f9_38 i64)
|
||||
|
||||
(local $f0f0 i64)
|
||||
(local $f0f1_2 i64)
|
||||
(local $f0f2_2 i64)
|
||||
(local $f0f3_2 i64)
|
||||
(local $f0f4_2 i64)
|
||||
(local $f0f5_2 i64)
|
||||
(local $f0f6_2 i64)
|
||||
(local $f0f7_2 i64)
|
||||
(local $f0f8_2 i64)
|
||||
(local $f0f9_2 i64)
|
||||
(local $f1f1_2 i64)
|
||||
(local $f1f2_2 i64)
|
||||
(local $f1f3_4 i64)
|
||||
(local $f1f4_2 i64)
|
||||
(local $f1f5_4 i64)
|
||||
(local $f1f6_2 i64)
|
||||
(local $f1f7_4 i64)
|
||||
(local $f1f8_2 i64)
|
||||
(local $f1f9_76 i64)
|
||||
(local $f2f2 i64)
|
||||
(local $f2f3_2 i64)
|
||||
(local $f2f4_2 i64)
|
||||
(local $f2f5_2 i64)
|
||||
(local $f2f6_2 i64)
|
||||
(local $f2f7_2 i64)
|
||||
(local $f2f8_38 i64)
|
||||
(local $f2f9_38 i64)
|
||||
(local $f3f3_2 i64)
|
||||
(local $f3f4_2 i64)
|
||||
(local $f3f5_4 i64)
|
||||
(local $f3f6_2 i64)
|
||||
(local $f3f7_76 i64)
|
||||
(local $f3f8_38 i64)
|
||||
(local $f3f9_76 i64)
|
||||
(local $f4f4 i64)
|
||||
(local $f4f5_2 i64)
|
||||
(local $f4f6_38 i64)
|
||||
(local $f4f7_38 i64)
|
||||
(local $f4f8_38 i64)
|
||||
(local $f4f9_38 i64)
|
||||
(local $f5f5_38 i64)
|
||||
(local $f5f6_38 i64)
|
||||
(local $f5f7_76 i64)
|
||||
(local $f5f8_38 i64)
|
||||
(local $f5f9_76 i64)
|
||||
(local $f6f6_19 i64)
|
||||
(local $f6f7_38 i64)
|
||||
(local $f6f8_38 i64)
|
||||
(local $f6f9_38 i64)
|
||||
(local $f7f7_38 i64)
|
||||
(local $f7f8_38 i64)
|
||||
(local $f7f9_76 i64)
|
||||
(local $f8f8_19 i64)
|
||||
(local $f8f9_38 i64)
|
||||
(local $f9f9_38 i64)
|
||||
|
||||
(block $end
|
||||
(loop $again
|
||||
(set_local $f0 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f0))))
|
||||
(set_local $f1 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f1))))
|
||||
(set_local $f2 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f2))))
|
||||
(set_local $f3 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f3))))
|
||||
(set_local $f4 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f4))))
|
||||
(set_local $f5 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f5))))
|
||||
(set_local $f6 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f6))))
|
||||
(set_local $f7 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f7))))
|
||||
(set_local $f8 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f8))))
|
||||
(set_local $f9 (i64.extend_s/i32 (i32.wrap/i64 (get_local $f9))))
|
||||
|
||||
(set_local $f0_2 (i64.mul (i64.const 2 (get_local $f0))))
|
||||
(set_local $f1_2 (i64.mul (i64.const 2 (get_local $f1))))
|
||||
(set_local $f2_2 (i64.mul (i64.const 2 (get_local $f2))))
|
||||
(set_local $f3_2 (i64.mul (i64.const 2 (get_local $f3))))
|
||||
(set_local $f4_2 (i64.mul (i64.const 2 (get_local $f4))))
|
||||
(set_local $f5_2 (i64.mul (i64.const 2 (get_local $f5))))
|
||||
(set_local $f6_2 (i64.mul (i64.const 2 (get_local $f6))))
|
||||
(set_local $f7_2 (i64.mul (i64.const 2 (get_local $f7))))
|
||||
|
||||
(set_local $f5_38 (i64.mul (i64.const 38 (get_local $f5))))
|
||||
(set_local $f6_19 (i64.mul (i64.const 19 (get_local $f6))))
|
||||
(set_local $f7_38 (i64.mul (i64.const 38 (get_local $f7))))
|
||||
(set_local $f8_19 (i64.mul (i64.const 19 (get_local $f8))))
|
||||
(set_local $f9_38 (i64.mul (i64.const 38 (get_local $f9))))
|
||||
|
||||
(set_local $f0f0 (i64.mul (get_local $f0) (get_local $f0)))
|
||||
(set_local $f0f1_2 (i64.mul (get_local $f0_2) (get_local $f1)))
|
||||
(set_local $f0f2_2 (i64.mul (get_local $f0_2) (get_local $f2)))
|
||||
(set_local $f0f3_2 (i64.mul (get_local $f0_2) (get_local $f3)))
|
||||
(set_local $f0f4_2 (i64.mul (get_local $f0_2) (get_local $f4)))
|
||||
(set_local $f0f5_2 (i64.mul (get_local $f0_2) (get_local $f5)))
|
||||
(set_local $f0f6_2 (i64.mul (get_local $f0_2) (get_local $f6)))
|
||||
(set_local $f0f7_2 (i64.mul (get_local $f0_2) (get_local $f7)))
|
||||
(set_local $f0f8_2 (i64.mul (get_local $f0_2) (get_local $f8)))
|
||||
(set_local $f0f9_2 (i64.mul (get_local $f0_2) (get_local $f9)))
|
||||
(set_local $f1f1_2 (i64.mul (get_local $f1_2) (get_local $f1)))
|
||||
(set_local $f1f2_2 (i64.mul (get_local $f1_2) (get_local $f2)))
|
||||
(set_local $f1f3_4 (i64.mul (get_local $f1_2) (get_local $f3_2)))
|
||||
(set_local $f1f4_2 (i64.mul (get_local $f1_2) (get_local $f4)))
|
||||
(set_local $f1f5_4 (i64.mul (get_local $f1_2) (get_local $f5_2)))
|
||||
(set_local $f1f6_2 (i64.mul (get_local $f1_2) (get_local $f6)))
|
||||
(set_local $f1f7_4 (i64.mul (get_local $f1_2) (get_local $f7_2)))
|
||||
(set_local $f1f8_2 (i64.mul (get_local $f1_2) (get_local $f8)))
|
||||
(set_local $f1f9_76 (i64.mul (get_local $f1_2) (get_local $f9_38)))
|
||||
(set_local $f2f2 (i64.mul (get_local $f2) (get_local $f2)))
|
||||
(set_local $f2f3_2 (i64.mul (get_local $f2_2) (get_local $f3)))
|
||||
(set_local $f2f4_2 (i64.mul (get_local $f2_2) (get_local $f4)))
|
||||
(set_local $f2f5_2 (i64.mul (get_local $f2_2) (get_local $f5)))
|
||||
(set_local $f2f6_2 (i64.mul (get_local $f2_2) (get_local $f6)))
|
||||
(set_local $f2f7_2 (i64.mul (get_local $f2_2) (get_local $f7)))
|
||||
(set_local $f2f8_38 (i64.mul (get_local $f2_2) (get_local $f8_19)))
|
||||
(set_local $f2f9_38 (i64.mul (get_local $f2) (get_local $f9_38)))
|
||||
(set_local $f3f3_2 (i64.mul (get_local $f3_2) (get_local $f3)))
|
||||
(set_local $f3f4_2 (i64.mul (get_local $f3_2) (get_local $f4)))
|
||||
(set_local $f3f5_4 (i64.mul (get_local $f3_2) (get_local $f5_2)))
|
||||
(set_local $f3f6_2 (i64.mul (get_local $f3_2) (get_local $f6)))
|
||||
(set_local $f3f7_76 (i64.mul (get_local $f3_2) (get_local $f7_38)))
|
||||
(set_local $f3f8_38 (i64.mul (get_local $f3_2) (get_local $f8_19)))
|
||||
(set_local $f3f9_76 (i64.mul (get_local $f3_2) (get_local $f9_38)))
|
||||
(set_local $f4f4 (i64.mul (get_local $f4) (get_local $f4)))
|
||||
(set_local $f4f5_2 (i64.mul (get_local $f4_2) (get_local $f5)))
|
||||
(set_local $f4f6_38 (i64.mul (get_local $f4_2) (get_local $f6_19)))
|
||||
(set_local $f4f7_38 (i64.mul (get_local $f4) (get_local $f7_38)))
|
||||
(set_local $f4f8_38 (i64.mul (get_local $f4_2) (get_local $f8_19)))
|
||||
(set_local $f4f9_38 (i64.mul (get_local $f4) (get_local $f9_38)))
|
||||
(set_local $f5f5_38 (i64.mul (get_local $f5) (get_local $f5_38)))
|
||||
(set_local $f5f6_38 (i64.mul (get_local $f5_2) (get_local $f6_19)))
|
||||
(set_local $f5f7_76 (i64.mul (get_local $f5_2) (get_local $f7_38)))
|
||||
(set_local $f5f8_38 (i64.mul (get_local $f5_2) (get_local $f8_19)))
|
||||
(set_local $f5f9_76 (i64.mul (get_local $f5_2) (get_local $f9_38)))
|
||||
(set_local $f6f6_19 (i64.mul (get_local $f6) (get_local $f6_19)))
|
||||
(set_local $f6f7_38 (i64.mul (get_local $f6) (get_local $f7_38)))
|
||||
(set_local $f6f8_38 (i64.mul (get_local $f6_2) (get_local $f8_19)))
|
||||
(set_local $f6f9_38 (i64.mul (get_local $f6) (get_local $f9_38)))
|
||||
(set_local $f7f7_38 (i64.mul (get_local $f7) (get_local $f7_38)))
|
||||
(set_local $f7f8_38 (i64.mul (get_local $f7_2) (get_local $f8_19)))
|
||||
(set_local $f7f9_76 (i64.mul (get_local $f7_2) (get_local $f9_38)))
|
||||
(set_local $f8f8_19 (i64.mul (get_local $f8) (get_local $f8_19)))
|
||||
(set_local $f8f9_38 (i64.mul (get_local $f8) (get_local $f9_38)))
|
||||
(set_local $f9f9_38 (i64.mul (get_local $f9) (get_local $f9_38)))
|
||||
|
||||
(set_local $h0 (i64.add (get_local $f0f0) (i64.add (get_local $f1f9_76) (i64.add (get_local $f2f8_38) (i64.add (get_local $f3f7_76) (i64.add (get_local $f4f6_38) (get_local $f5f5_38)))))))
|
||||
(set_local $h1 (i64.add (get_local $f0f1_2) (i64.add (get_local $f2f9_38) (i64.add (get_local $f3f8_38) (i64.add (get_local $f4f7_38) (get_local $f5f6_38))))))
|
||||
(set_local $h2 (i64.add (get_local $f0f2_2) (i64.add (get_local $f1f1_2) (i64.add (get_local $f3f9_76) (i64.add (get_local $f4f8_38) (i64.add (get_local $f5f7_76) (get_local $f6f6_19)))))))
|
||||
(set_local $h3 (i64.add (get_local $f0f3_2) (i64.add (get_local $f1f2_2) (i64.add (get_local $f4f9_38) (i64.add (get_local $f5f8_38) (get_local $f6f7_38))))))
|
||||
(set_local $h4 (i64.add (get_local $f0f4_2) (i64.add (get_local $f1f3_4) (i64.add (get_local $f2f2) (i64.add (get_local $f5f9_76) (i64.add (get_local $f6f8_38) (get_local $f7f7_38)))))))
|
||||
(set_local $h5 (i64.add (get_local $f0f5_2) (i64.add (get_local $f1f4_2) (i64.add (get_local $f2f3_2) (i64.add (get_local $f6f9_38) (get_local $f7f8_38))))))
|
||||
(set_local $h6 (i64.add (get_local $f0f6_2) (i64.add (get_local $f1f5_4) (i64.add (get_local $f2f4_2) (i64.add (get_local $f3f3_2) (i64.add (get_local $f7f9_76) (get_local $f8f8_19)))))))
|
||||
(set_local $h7 (i64.add (get_local $f0f7_2) (i64.add (get_local $f1f6_2) (i64.add (get_local $f2f5_2) (i64.add (get_local $f3f4_2) (get_local $f8f9_38))))))
|
||||
(set_local $h8 (i64.add (get_local $f0f8_2) (i64.add (get_local $f1f7_4) (i64.add (get_local $f2f6_2) (i64.add (get_local $f3f5_4) (i64.add (get_local $f4f4) (get_local $f9f9_38)))))))
|
||||
(set_local $h9 (i64.add (get_local $f0f9_2) (i64.add (get_local $f1f8_2) (i64.add (get_local $f2f7_2) (i64.add (get_local $f3f6_2) (get_local $f4f5_2 ))))))
|
||||
|
||||
(br_if $end (i32.eq (get_local $count) (get_local $repeat)))
|
||||
(set_local $count (i32.add (get_local $count) (i32.const 1)))
|
||||
(br $again)))
|
||||
|
||||
(if (i32.eq (get_local $double) (i32.const 1))
|
||||
(then
|
||||
(set_local $h0 (i64.add (get_local $h0) (get_local $h0)))
|
||||
(set_local $h1 (i64.add (get_local $h1) (get_local $h1)))
|
||||
(set_local $h2 (i64.add (get_local $h2) (get_local $h2)))
|
||||
(set_local $h3 (i64.add (get_local $h3) (get_local $h3)))
|
||||
(set_local $h4 (i64.add (get_local $h4) (get_local $h4)))
|
||||
(set_local $h5 (i64.add (get_local $h5) (get_local $h5)))
|
||||
(set_local $h6 (i64.add (get_local $h6) (get_local $h6)))
|
||||
(set_local $h7 (i64.add (get_local $h7) (get_local $h7)))
|
||||
(set_local $h8 (i64.add (get_local $h8) (get_local $h8)))
|
||||
(set_local $h9 (i64.add (get_local $h9) (get_local $h9)))))
|
||||
|
||||
(set_local $carry0 (i64.shr_s (i64.add (get_local $h0) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
|
||||
(set_local $h1 (i64.add (get_local $h1) (get_local $carry0)))
|
||||
(set_local $h0 (i64.sub (get_local $h0) (i64.mul (get_local $carry0) (i64.shl (i64.const 1) (i64.const 26)))))
|
||||
(set_local $carry4 (i64.shr_s (i64.add (get_local $h4) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
|
||||
(set_local $h5 (i64.add (get_local $h5) (get_local $carry4)))
|
||||
(set_local $h4 (i64.sub (get_local $h4) (i64.mul (get_local $carry4) (i64.shl (i64.const 1) (i64.const 26)))))
|
||||
|
||||
(set_local $carry1 (i64.shr_s (i64.add (get_local $h1) (i64.shl (i64.const 1) (i64.const 24))) (i64.const 25)))
|
||||
(set_local $h2 (i64.add (get_local $h2) (get_local $carry1)))
|
||||
(set_local $h1 (i64.sub (get_local $h1) (i64.mul (get_local $carry1) (i64.shl (i64.const 1) (i64.const 25)))))
|
||||
(set_local $carry5 (i64.shr_s (i64.add (get_local $h5) (i64.shl (i64.const 1) (i64.const 24))) (i64.const 25)))
|
||||
(set_local $h6 (i64.add (get_local $h6) (get_local $carry5)))
|
||||
(set_local $h5 (i64.sub (get_local $h5) (i64.mul (get_local $carry5) (i64.shl (i64.const 1) (i64.const 25)))))
|
||||
|
||||
(set_local $carry2 (i64.shr_s (i64.add (get_local $h2) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
|
||||
(set_local $h3 (i64.add (get_local $h3) (get_local $carry2)))
|
||||
(set_local $h2 (i64.sub (get_local $h2) (i64.mul (get_local $carry2) (i64.shl (i64.const 1) (i64.const 26)))))
|
||||
(set_local $carry6 (i64.shr_s (i64.add (get_local $h6) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
|
||||
(set_local $h7 (i64.add (get_local $h7) (get_local $carry6)))
|
||||
(set_local $h6 (i64.sub (get_local $h6) (i64.mul (get_local $carry6) (i64.shl (i64.const 1) (i64.const 26)))))
|
||||
|
||||
(set_local $carry3 (i64.shr_s (i64.add (get_local $h3) (i64.shl (i64.const 1) (i64.const 24))) (i64.const 25)))
|
||||
(set_local $h4 (i64.add (get_local $h4) (get_local $carry3)))
|
||||
(set_local $h3 (i64.sub (get_local $h3) (i64.mul (get_local $carry3) (i64.shl (i64.const 1) (i64.const 25)))))
|
||||
(set_local $carry7 (i64.shr_s (i64.add (get_local $h7) (i64.shl (i64.const 1) (i64.const 24))) (i64.const 25)))
|
||||
(set_local $h8 (i64.add (get_local $h8) (get_local $carry7)))
|
||||
(set_local $h7 (i64.sub (get_local $h7) (i64.mul (get_local $carry7) (i64.shl (i64.const 1) (i64.const 25)))))
|
||||
|
||||
(set_local $carry4 (i64.shr_s (i64.add (get_local $h4) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
|
||||
(set_local $h5 (i64.add (get_local $h5) (get_local $carry4)))
|
||||
(set_local $h4 (i64.sub (get_local $h4) (i64.mul (get_local $carry4) (i64.shl (i64.const 1) (i64.const 26)))))
|
||||
(set_local $carry8 (i64.shr_s (i64.add (get_local $h8) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
|
||||
(set_local $h9 (i64.add (get_local $h9) (get_local $carry8)))
|
||||
(set_local $h8 (i64.sub (get_local $h8) (i64.mul (get_local $carry8) (i64.shl (i64.const 1) (i64.const 26)))))
|
||||
|
||||
(set_local $carry9 (i64.shr_s (i64.add (get_local $h9) (i64.shl (i64.const 1) (i64.const 24))) (i64.const 25)))
|
||||
(set_local $h0 (i64.add (get_local $h0) (i64.mul (get_local $carry9) (i64.const 19))))
|
||||
(set_local $h9 (i64.sub (get_local $h9) (i64.mul (get_local $carry9) (i64.shl (i64.const 1) (i64.const 25)))))
|
||||
|
||||
(set_local $carry0 (i64.shr_s (i64.add (get_local $h0) (i64.shl (i64.const 1) (i64.const 25))) (i64.const 26)))
|
||||
(set_local $h1 (i64.add (get_local $h1) (get_local $carry0)))
|
||||
(set_local $h0 (i64.sub (get_local $h0) (i64.mul (get_local $carry0) (i64.shl (i64.const 1) (i64.const 26)))))
|
||||
|
||||
(i64.store32 offset=0 (get_local $h) (get_local $h0))
|
||||
(i64.store32 offset=4 (get_local $h) (get_local $h1))
|
||||
(i64.store32 offset=8 (get_local $h) (get_local $h2))
|
||||
(i64.store32 offset=12 (get_local $h) (get_local $h3))
|
||||
(i64.store32 offset=16 (get_local $h) (get_local $h4))
|
||||
(i64.store32 offset=20 (get_local $h) (get_local $h5))
|
||||
(i64.store32 offset=24 (get_local $h) (get_local $h6))
|
||||
(i64.store32 offset=28 (get_local $h) (get_local $h7))
|
||||
(i64.store32 offset=32 (get_local $h) (get_local $h8))
|
||||
(i64.store32 offset=36 (get_local $h) (get_local $h9)))
|
||||
|
||||
(func $sq (export "sq") (param $h i32) (param $f i32) (param $double i32) (param $repeat i32)
|
||||
(i64.load32_u offset=0 (get_local $f))
|
||||
(i64.load32_u offset=4 (get_local $f))
|
||||
(i64.load32_u offset=8 (get_local $f))
|
||||
(i64.load32_u offset=12 (get_local $f))
|
||||
(i64.load32_u offset=16 (get_local $f))
|
||||
(i64.load32_u offset=20 (get_local $f))
|
||||
(i64.load32_u offset=24 (get_local $f))
|
||||
(i64.load32_u offset=28 (get_local $f))
|
||||
(i64.load32_u offset=32 (get_local $f))
|
||||
(i64.load32_u offset=36 (get_local $f))
|
||||
(get_local $double)
|
||||
(get_local $repeat)
|
||||
(get_local $h)
|
||||
(call $fe_sq)))
|
||||
@@ -0,0 +1,61 @@
|
||||
|
||||
module.exports = loadWebAssembly
|
||||
|
||||
loadWebAssembly.supported = typeof WebAssembly !== 'undefined'
|
||||
|
||||
function loadWebAssembly (opts) {
|
||||
if (!loadWebAssembly.supported) return null
|
||||
|
||||
var imp = opts && opts.imports
|
||||
var wasm = toUint8Array('AGFzbQEAAAABIwJgGX9+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn4AYAN/f38AAg4BAmpzBXRhYmxlAXAAAQMCAQEFAwEAAQcYAgZtZW1vcnkCAAtzYzI1NTE5X211bAAACugPAeUPAUh+IAE1AgAhBCABNQIEIQUgATUCCCEGIAE1AgwhByABNQIQIQggATUCFCEJIAE1AhghCiABNQIcIQsgATUCICEMIAE1AiQhDSABNQIoIQ4gATUCLCEPIAI1AgAhECACNQIEIREgAjUCCCESIAI1AgwhEyACNQIQIRQgAjUCFCEVIAI1AhghFiACNQIcIRcgAjUCICEYIAI1AiQhGSACNQIoIRogAjUCLCEbIASnrCEEIAWnrCEFIAanrCEGIAenrCEHIAinrCEIIAmnrCEJIAqnrCEKIAunrCELIAynrCEMIA2nrCENIA6nrCEOIA+nrCEPIBCnrCEQIBGnrCERIBKnrCESIBOnrCETIBSnrCEUIBWnrCEVIBanrCEWIBenrCEXIBinrCEYIBmnrCEZIBqnrCEaIBunrCEbIAQgEH4hHCAEIBF+IAUgEH58IR0gBCASfiAFIBF+IAYgEH58fCEeIAQgE34gBSASfiAGIBF+IAcgEH58fHwhHyAEIBR+IAUgE34gBiASfiAHIBF+IAggEH58fHx8ISAgBCAVfiAFIBR+IAYgE34gByASfiAIIBF+IAkgEH58fHx8fCEhIAQgFn4gBSAVfiAGIBR+IAcgE34gCCASfiAJIBF+IAogEH58fHx8fHwhIiAEIBd+IAUgFn4gBiAVfiAHIBR+IAggE34gCSASfiAKIBF+IAsgEH58fHx8fHx8ISMgBCAYfiAFIBd+IAYgFn4gByAVfiAIIBR+IAkgE34gCiASfiALIBF+IAwgEH58fHx8fHx8fCEkIAQgGX4gBSAYfiAGIBd+IAcgFn4gCCAVfiAJIBR+IAogE34gCyASfiAMIBF+IA0gEH58fHx8fHx8fHwhJSAEIBp+IAUgGX4gBiAYfiAHIBd+IAggFn4gCSAVfiAKIBR+IAsgE34gDCASfiANIBF+IA4gEH58fHx8fHx8fHx8ISYgBCAbfiAFIBp+IAYgGX4gByAYfiAIIBd+IAkgFn4gCiAVfiALIBR+IAwgE34gDSASfiAOIBF+IA8gEH58fHx8fHx8fHx8fCEnIAUgG34gBiAafiAHIBl+IAggGH4gCSAXfiAKIBZ+IAsgFX4gDCAUfiANIBN+IA4gEn4gDyARfnx8fHx8fHx8fHwhKCAGIBt+IAcgGn4gCCAZfiAJIBh+IAogF34gCyAWfiAMIBV+IA0gFH4gDiATfiAPIBJ+fHx8fHx8fHx8ISkgByAbfiAIIBp+IAkgGX4gCiAYfiALIBd+IAwgFn4gDSAVfiAOIBR+IA8gE358fHx8fHx8fCEqIAggG34gCSAafiAKIBl+IAsgGH4gDCAXfiANIBZ+IA4gFX4gDyAUfnx8fHx8fHwhKyAJIBt+IAogGn4gCyAZfiAMIBh+IA0gF34gDiAWfiAPIBV+fHx8fHx8ISwgCiAbfiALIBp+IAwgGX4gDSAYfiAOIBd+IA8gFn58fHx8fCEtIAsgG34gDCAafiANIBl+IA4gGH4gDyAXfnx8fHwhLiAMIBt+IA0gGn4gDiAZfiAPIBh+fHx8IS8gDSAbfiAOIBp+IA8gGX58fCEwIA4gG34gDyAafnwhMSAPIBt+ITJCACEzIBxCAUIUhnxCFYchNCAdIDR8IR0gHCA0QgFCFYZ+fSEcIB5CAUIUhnxCFYchNiAfIDZ8IR8gHiA2QgFCFYZ+fSEeICBCAUIUhnxCFYchOCAhIDh8ISEgICA4QgFCFYZ+fSEgICJCAUIUhnxCFYchOiAjIDp8ISMgIiA6QgFCFYZ+fSEiICRCAUIUhnxCFYchPCAlIDx8ISUgJCA8QgFCFYZ+fSEkICZCAUIUhnxCFYchPiAnID58IScgJiA+QgFCFYZ+fSEmIChCAUIUhnxCFYchQCApIEB8ISkgKCBAQgFCFYZ+fSEoICpCAUIUhnxCFYchQiArIEJ8ISsgKiBCQgFCFYZ+fSEqICxCAUIUhnxCFYchRCAtIER8IS0gLCBEQgFCFYZ+fSEsIC5CAUIUhnxCFYchRiAvIEZ8IS8gLiBGQgFCFYZ+fSEuIDBCAUIUhnxCFYchSCAxIEh8ITEgMCBIQgFCFYZ+fSEwIDJCAUIUhnxCFYchSiAzIEp8ITMgMiBKQgFCFYZ+fSEyIB1CAUIUhnxCFYchNSAeIDV8IR4gHSA1QgFCFYZ+fSEdIB9CAUIUhnxCFYchNyAgIDd8ISAgHyA3QgFCFYZ+fSEfICFCAUIUhnxCFYchOSAiIDl8ISIgISA5QgFCFYZ+fSEhICNCAUIUhnxCFYchOyAkIDt8ISQgIyA7QgFCFYZ+fSEjICVCAUIUhnxCFYchPSAmID18ISYgJSA9QgFCFYZ+fSElICdCAUIUhnxCFYchPyAoID98ISggJyA/QgFCFYZ+fSEnIClCAUIUhnxCFYchQSAqIEF8ISogKSBBQgFCFYZ+fSEpICtCAUIUhnxCFYchQyAsIEN8ISwgKyBDQgFCFYZ+fSErIC1CAUIUhnxCFYchRSAuIEV8IS4gLSBFQgFCFYZ+fSEtIC9CAUIUhnxCFYchRyAwIEd8ITAgLyBHQgFCFYZ+fSEvIDFCAUIUhnxCFYchSSAyIEl8ITIgMSBJQgFCFYZ+fSExIAAgHCAdIB4gHyAgICEgIiAjICQgJSAmICcgKCApICogKyAsIC0gLiAvIDAgMSAyIDNBABEAAAs=')
|
||||
var ready = null
|
||||
|
||||
var mod = {
|
||||
buffer: wasm,
|
||||
memory: null,
|
||||
exports: null,
|
||||
realloc: realloc,
|
||||
onload: onload
|
||||
}
|
||||
|
||||
onload(function () {})
|
||||
|
||||
return mod
|
||||
|
||||
function realloc (size) {
|
||||
mod.exports.memory.grow(Math.max(0, Math.ceil(Math.abs(size - mod.memory.length) / 65536)))
|
||||
mod.memory = new Uint8Array(mod.exports.memory.buffer)
|
||||
}
|
||||
|
||||
function onload (cb) {
|
||||
if (mod.exports) return cb()
|
||||
|
||||
if (ready) {
|
||||
ready.then(cb.bind(null, null)).catch(cb)
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
if (opts && opts.async) throw new Error('async')
|
||||
setup({instance: new WebAssembly.Instance(new WebAssembly.Module(wasm), imp)})
|
||||
} catch (err) {
|
||||
ready = WebAssembly.instantiate(wasm, imp).then(setup)
|
||||
}
|
||||
|
||||
onload(cb)
|
||||
}
|
||||
|
||||
function setup (w) {
|
||||
mod.exports = w.instance.exports
|
||||
mod.memory = mod.exports.memory && mod.exports.memory.buffer && new Uint8Array(mod.exports.memory.buffer)
|
||||
}
|
||||
}
|
||||
|
||||
function toUint8Array (s) {
|
||||
if (typeof atob === 'function') return new Uint8Array(atob(s).split('').map(charCodeAt))
|
||||
return (require('buf' + 'fer').Buffer).from(s, 'base64')
|
||||
}
|
||||
|
||||
function charCodeAt (c) {
|
||||
return c.charCodeAt(0)
|
||||
}
|
||||
@@ -0,0 +1,308 @@
|
||||
(module
|
||||
(import "js" "table" (table 1 anyfunc))
|
||||
(type $to_void (func
|
||||
(param $s i32)
|
||||
(param $s0 i64)
|
||||
(param $s1 i64)
|
||||
(param $s2 i64)
|
||||
(param $s3 i64)
|
||||
(param $s4 i64)
|
||||
(param $s5 i64)
|
||||
(param $s6 i64)
|
||||
(param $s7 i64)
|
||||
(param $s8 i64)
|
||||
(param $s9 i64)
|
||||
(param $s10 i64)
|
||||
(param $s11 i64)
|
||||
(param $s12 i64)
|
||||
(param $s13 i64)
|
||||
(param $s14 i64)
|
||||
(param $s15 i64)
|
||||
(param $s16 i64)
|
||||
(param $s17 i64)
|
||||
(param $s18 i64)
|
||||
(param $s19 i64)
|
||||
(param $s20 i64)
|
||||
(param $s21 i64)
|
||||
(param $s22 i64)
|
||||
(param $s23 i64)))
|
||||
|
||||
(memory $0 1)
|
||||
(export "memory" (memory $0))
|
||||
|
||||
(func $sc25519_mul (export "sc25519_mul") (param $s i32) (param $a i32) (param $b i32)
|
||||
(local $tmp i64)
|
||||
|
||||
(local $a0 i64)
|
||||
(local $a1 i64)
|
||||
(local $a2 i64)
|
||||
(local $a3 i64)
|
||||
(local $a4 i64)
|
||||
(local $a5 i64)
|
||||
(local $a6 i64)
|
||||
(local $a7 i64)
|
||||
(local $a8 i64)
|
||||
(local $a9 i64)
|
||||
(local $a10 i64)
|
||||
(local $a11 i64)
|
||||
|
||||
(local $b0 i64)
|
||||
(local $b1 i64)
|
||||
(local $b2 i64)
|
||||
(local $b3 i64)
|
||||
(local $b4 i64)
|
||||
(local $b5 i64)
|
||||
(local $b6 i64)
|
||||
(local $b7 i64)
|
||||
(local $b8 i64)
|
||||
(local $b9 i64)
|
||||
(local $b10 i64)
|
||||
(local $b11 i64)
|
||||
|
||||
(local $s0 i64)
|
||||
(local $s1 i64)
|
||||
(local $s2 i64)
|
||||
(local $s3 i64)
|
||||
(local $s4 i64)
|
||||
(local $s5 i64)
|
||||
(local $s6 i64)
|
||||
(local $s7 i64)
|
||||
(local $s8 i64)
|
||||
(local $s9 i64)
|
||||
(local $s10 i64)
|
||||
(local $s11 i64)
|
||||
(local $s12 i64)
|
||||
(local $s13 i64)
|
||||
(local $s14 i64)
|
||||
(local $s15 i64)
|
||||
(local $s16 i64)
|
||||
(local $s17 i64)
|
||||
(local $s18 i64)
|
||||
(local $s19 i64)
|
||||
(local $s20 i64)
|
||||
(local $s21 i64)
|
||||
(local $s22 i64)
|
||||
(local $s23 i64)
|
||||
|
||||
(local $carry0 i64)
|
||||
(local $carry1 i64)
|
||||
(local $carry2 i64)
|
||||
(local $carry3 i64)
|
||||
(local $carry4 i64)
|
||||
(local $carry5 i64)
|
||||
(local $carry6 i64)
|
||||
(local $carry7 i64)
|
||||
(local $carry8 i64)
|
||||
(local $carry9 i64)
|
||||
(local $carry10 i64)
|
||||
(local $carry11 i64)
|
||||
(local $carry12 i64)
|
||||
(local $carry13 i64)
|
||||
(local $carry14 i64)
|
||||
(local $carry15 i64)
|
||||
(local $carry16 i64)
|
||||
(local $carry17 i64)
|
||||
(local $carry18 i64)
|
||||
(local $carry19 i64)
|
||||
(local $carry20 i64)
|
||||
(local $carry21 i64)
|
||||
(local $carry22 i64)
|
||||
|
||||
(set_local $a0 (i64.load32_u offset=0 (get_local $a)))
|
||||
(set_local $a1 (i64.load32_u offset=4 (get_local $a)))
|
||||
(set_local $a2 (i64.load32_u offset=8 (get_local $a)))
|
||||
(set_local $a3 (i64.load32_u offset=12 (get_local $a)))
|
||||
(set_local $a4 (i64.load32_u offset=16 (get_local $a)))
|
||||
(set_local $a5 (i64.load32_u offset=20 (get_local $a)))
|
||||
(set_local $a6 (i64.load32_u offset=24 (get_local $a)))
|
||||
(set_local $a7 (i64.load32_u offset=28 (get_local $a)))
|
||||
(set_local $a8 (i64.load32_u offset=32 (get_local $a)))
|
||||
(set_local $a9 (i64.load32_u offset=36 (get_local $a)))
|
||||
(set_local $a10 (i64.load32_u offset=40 (get_local $a)))
|
||||
(set_local $a11 (i64.load32_u offset=44 (get_local $a)))
|
||||
|
||||
(set_local $b0 (i64.load32_u offset=0 (get_local $b)))
|
||||
(set_local $b1 (i64.load32_u offset=4 (get_local $b)))
|
||||
(set_local $b2 (i64.load32_u offset=8 (get_local $b)))
|
||||
(set_local $b3 (i64.load32_u offset=12 (get_local $b)))
|
||||
(set_local $b4 (i64.load32_u offset=16 (get_local $b)))
|
||||
(set_local $b5 (i64.load32_u offset=20 (get_local $b)))
|
||||
(set_local $b6 (i64.load32_u offset=24 (get_local $b)))
|
||||
(set_local $b7 (i64.load32_u offset=28 (get_local $b)))
|
||||
(set_local $b8 (i64.load32_u offset=32 (get_local $b)))
|
||||
(set_local $b9 (i64.load32_u offset=36 (get_local $b)))
|
||||
(set_local $b10 (i64.load32_u offset=40 (get_local $b)))
|
||||
(set_local $b11 (i64.load32_u offset=44 (get_local $b)))
|
||||
|
||||
(set_local $a0 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a0))))
|
||||
(set_local $a1 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a1))))
|
||||
(set_local $a2 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a2))))
|
||||
(set_local $a3 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a3))))
|
||||
(set_local $a4 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a4))))
|
||||
(set_local $a5 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a5))))
|
||||
(set_local $a6 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a6))))
|
||||
(set_local $a7 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a7))))
|
||||
(set_local $a8 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a8))))
|
||||
(set_local $a9 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a9))))
|
||||
(set_local $a10 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a10))))
|
||||
(set_local $a11 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a11))))
|
||||
|
||||
(set_local $b0 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b0))))
|
||||
(set_local $b1 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b1))))
|
||||
(set_local $b2 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b2))))
|
||||
(set_local $b3 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b3))))
|
||||
(set_local $b4 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b4))))
|
||||
(set_local $b5 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b5))))
|
||||
(set_local $b6 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b6))))
|
||||
(set_local $b7 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b7))))
|
||||
(set_local $b8 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b8))))
|
||||
(set_local $b9 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b9))))
|
||||
(set_local $b10 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b10))))
|
||||
(set_local $b11 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b11))))
|
||||
|
||||
(set_local $s0 (i64.mul (get_local $a0) (get_local $b0)))
|
||||
(set_local $s1 (i64.add (i64.mul (get_local $a0) (get_local $b1 )) (i64.mul (get_local $a1) (get_local $b0))))
|
||||
(set_local $s2 (i64.add (i64.mul (get_local $a0) (get_local $b2 )) (i64.add (i64.mul (get_local $a1) (get_local $b1 )) (i64.mul (get_local $a2) (get_local $b0)))))
|
||||
(set_local $s3 (i64.add (i64.mul (get_local $a0) (get_local $b3 )) (i64.add (i64.mul (get_local $a1) (get_local $b2 )) (i64.add (i64.mul (get_local $a2) (get_local $b1)) (i64.mul (get_local $a3) (get_local $b0))))))
|
||||
(set_local $s4 (i64.add (i64.mul (get_local $a0) (get_local $b4 )) (i64.add (i64.mul (get_local $a1) (get_local $b3 )) (i64.add (i64.mul (get_local $a2) (get_local $b2)) (i64.add (i64.mul (get_local $a3) (get_local $b1)) (i64.mul (get_local $a4) (get_local $b0)))))))
|
||||
(set_local $s5 (i64.add (i64.mul (get_local $a0) (get_local $b5 )) (i64.add (i64.mul (get_local $a1) (get_local $b4 )) (i64.add (i64.mul (get_local $a2) (get_local $b3)) (i64.add (i64.mul (get_local $a3) (get_local $b2)) (i64.add (i64.mul (get_local $a4) (get_local $b1)) (i64.mul (get_local $a5) (get_local $b0))))))))
|
||||
(set_local $s6 (i64.add (i64.mul (get_local $a0) (get_local $b6 )) (i64.add (i64.mul (get_local $a1) (get_local $b5 )) (i64.add (i64.mul (get_local $a2) (get_local $b4)) (i64.add (i64.mul (get_local $a3) (get_local $b3)) (i64.add (i64.mul (get_local $a4) (get_local $b2)) (i64.add (i64.mul (get_local $a5) (get_local $b1)) (i64.mul (get_local $a6) (get_local $b0)))))))))
|
||||
(set_local $s7 (i64.add (i64.mul (get_local $a0) (get_local $b7 )) (i64.add (i64.mul (get_local $a1) (get_local $b6 )) (i64.add (i64.mul (get_local $a2) (get_local $b5)) (i64.add (i64.mul (get_local $a3) (get_local $b4)) (i64.add (i64.mul (get_local $a4) (get_local $b3)) (i64.add (i64.mul (get_local $a5) (get_local $b2)) (i64.add (i64.mul (get_local $a6) (get_local $b1)) (i64.mul (get_local $a7) (get_local $b0))))))))))
|
||||
(set_local $s8 (i64.add (i64.mul (get_local $a0) (get_local $b8 )) (i64.add (i64.mul (get_local $a1) (get_local $b7 )) (i64.add (i64.mul (get_local $a2) (get_local $b6)) (i64.add (i64.mul (get_local $a3) (get_local $b5)) (i64.add (i64.mul (get_local $a4) (get_local $b4)) (i64.add (i64.mul (get_local $a5) (get_local $b3)) (i64.add (i64.mul (get_local $a6) (get_local $b2)) (i64.add (i64.mul (get_local $a7) (get_local $b1)) (i64.mul (get_local $a8) (get_local $b0)))))))))))
|
||||
(set_local $s9 (i64.add (i64.mul (get_local $a0) (get_local $b9 )) (i64.add (i64.mul (get_local $a1) (get_local $b8 )) (i64.add (i64.mul (get_local $a2) (get_local $b7)) (i64.add (i64.mul (get_local $a3) (get_local $b6)) (i64.add (i64.mul (get_local $a4) (get_local $b5)) (i64.add (i64.mul (get_local $a5) (get_local $b4)) (i64.add (i64.mul (get_local $a6) (get_local $b3)) (i64.add (i64.mul (get_local $a7) (get_local $b2)) (i64.add (i64.mul (get_local $a8) (get_local $b1)) (i64.mul (get_local $a9) (get_local $b0))))))))))))
|
||||
(set_local $s10 (i64.add (i64.mul (get_local $a0) (get_local $b10)) (i64.add (i64.mul (get_local $a1) (get_local $b9 )) (i64.add (i64.mul (get_local $a2) (get_local $b8)) (i64.add (i64.mul (get_local $a3) (get_local $b7)) (i64.add (i64.mul (get_local $a4) (get_local $b6)) (i64.add (i64.mul (get_local $a5) (get_local $b5)) (i64.add (i64.mul (get_local $a6) (get_local $b4)) (i64.add (i64.mul (get_local $a7) (get_local $b3)) (i64.add (i64.mul (get_local $a8) (get_local $b2)) (i64.add (i64.mul (get_local $a9) (get_local $b1)) (i64.mul (get_local $a10) (get_local $b0)))))))))))))
|
||||
(set_local $s11 (i64.add (i64.mul (get_local $a0) (get_local $b11)) (i64.add (i64.mul (get_local $a1) (get_local $b10)) (i64.add (i64.mul (get_local $a2) (get_local $b9)) (i64.add (i64.mul (get_local $a3) (get_local $b8)) (i64.add (i64.mul (get_local $a4) (get_local $b7)) (i64.add (i64.mul (get_local $a5) (get_local $b6)) (i64.add (i64.mul (get_local $a6) (get_local $b5)) (i64.add (i64.mul (get_local $a7) (get_local $b4)) (i64.add (i64.mul (get_local $a8) (get_local $b3)) (i64.add (i64.mul (get_local $a9) (get_local $b2)) (i64.add (i64.mul (get_local $a10) (get_local $b1)) (i64.mul (get_local $a11) (get_local $b0))))))))))))))
|
||||
(set_local $s12 (i64.add (i64.mul (get_local $a1) (get_local $b11)) (i64.add (i64.mul (get_local $a2) (get_local $b10)) (i64.add (i64.mul (get_local $a3) (get_local $b9)) (i64.add (i64.mul (get_local $a4) (get_local $b8)) (i64.add (i64.mul (get_local $a5) (get_local $b7)) (i64.add (i64.mul (get_local $a6) (get_local $b6)) (i64.add (i64.mul (get_local $a7) (get_local $b5)) (i64.add (i64.mul (get_local $a8) (get_local $b4)) (i64.add (i64.mul (get_local $a9) (get_local $b3)) (i64.add (i64.mul (get_local $a10) (get_local $b2)) (i64.mul (get_local $a11) (get_local $b1)))))))))))))
|
||||
(set_local $s13 (i64.add (i64.mul (get_local $a2) (get_local $b11)) (i64.add (i64.mul (get_local $a3) (get_local $b10)) (i64.add (i64.mul (get_local $a4) (get_local $b9)) (i64.add (i64.mul (get_local $a5) (get_local $b8)) (i64.add (i64.mul (get_local $a6) (get_local $b7)) (i64.add (i64.mul (get_local $a7) (get_local $b6)) (i64.add (i64.mul (get_local $a8) (get_local $b5)) (i64.add (i64.mul (get_local $a9) (get_local $b4)) (i64.add (i64.mul (get_local $a10) (get_local $b3)) (i64.mul (get_local $a11) (get_local $b2))))))))))))
|
||||
(set_local $s14 (i64.add (i64.mul (get_local $a3) (get_local $b11)) (i64.add (i64.mul (get_local $a4) (get_local $b10)) (i64.add (i64.mul (get_local $a5) (get_local $b9)) (i64.add (i64.mul (get_local $a6) (get_local $b8)) (i64.add (i64.mul (get_local $a7) (get_local $b7)) (i64.add (i64.mul (get_local $a8) (get_local $b6)) (i64.add (i64.mul (get_local $a9) (get_local $b5)) (i64.add (i64.mul (get_local $a10) (get_local $b4)) (i64.mul (get_local $a11) (get_local $b3)))))))))))
|
||||
(set_local $s15 (i64.add (i64.mul (get_local $a4) (get_local $b11)) (i64.add (i64.mul (get_local $a5) (get_local $b10)) (i64.add (i64.mul (get_local $a6) (get_local $b9)) (i64.add (i64.mul (get_local $a7) (get_local $b8)) (i64.add (i64.mul (get_local $a8) (get_local $b7)) (i64.add (i64.mul (get_local $a9) (get_local $b6)) (i64.add (i64.mul (get_local $a10) (get_local $b5)) (i64.mul (get_local $a11) (get_local $b4))))))))))
|
||||
(set_local $s16 (i64.add (i64.mul (get_local $a5) (get_local $b11)) (i64.add (i64.mul (get_local $a6) (get_local $b10)) (i64.add (i64.mul (get_local $a7) (get_local $b9)) (i64.add (i64.mul (get_local $a8) (get_local $b8)) (i64.add (i64.mul (get_local $a9) (get_local $b7)) (i64.add (i64.mul (get_local $a10) (get_local $b6)) (i64.mul (get_local $a11) (get_local $b5)))))))))
|
||||
(set_local $s17 (i64.add (i64.mul (get_local $a6) (get_local $b11)) (i64.add (i64.mul (get_local $a7) (get_local $b10)) (i64.add (i64.mul (get_local $a8) (get_local $b9)) (i64.add (i64.mul (get_local $a9) (get_local $b8)) (i64.add (i64.mul (get_local $a10) (get_local $b7)) (i64.mul (get_local $a11) (get_local $b6))))))))
|
||||
(set_local $s18 (i64.add (i64.mul (get_local $a7) (get_local $b11)) (i64.add (i64.mul (get_local $a8) (get_local $b10)) (i64.add (i64.mul (get_local $a9) (get_local $b9)) (i64.add (i64.mul (get_local $a10) (get_local $b8)) (i64.mul (get_local $a11) (get_local $b7)))))))
|
||||
(set_local $s19 (i64.add (i64.mul (get_local $a8) (get_local $b11)) (i64.add (i64.mul (get_local $a9) (get_local $b10)) (i64.add (i64.mul (get_local $a10) (get_local $b9)) (i64.mul (get_local $a11) (get_local $b8))))))
|
||||
(set_local $s20 (i64.add (i64.mul (get_local $a9) (get_local $b11)) (i64.add (i64.mul (get_local $a10) (get_local $b10)) (i64.mul (get_local $a11) (get_local $b9)))))
|
||||
(set_local $s21 (i64.add (i64.mul (get_local $a10) (get_local $b11)) (i64.mul (get_local $a11) (get_local $b10))))
|
||||
(set_local $s22 (i64.mul (get_local $a11) (get_local $b11)))
|
||||
(set_local $s23 (i64.const 0))
|
||||
|
||||
(set_local $carry0 (i64.shr_s (i64.add (get_local $s0) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s1 (i64.add (get_local $s1) (get_local $carry0)))
|
||||
(set_local $s0 (i64.sub (get_local $s0) (i64.mul (get_local $carry0) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry2 (i64.shr_s (i64.add (get_local $s2) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s3 (i64.add (get_local $s3) (get_local $carry2)))
|
||||
(set_local $s2 (i64.sub (get_local $s2) (i64.mul (get_local $carry2) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry4 (i64.shr_s (i64.add (get_local $s4) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s5 (i64.add (get_local $s5) (get_local $carry4)))
|
||||
(set_local $s4 (i64.sub (get_local $s4) (i64.mul (get_local $carry4) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry6 (i64.shr_s (i64.add (get_local $s6) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s7 (i64.add (get_local $s7) (get_local $carry6)))
|
||||
(set_local $s6 (i64.sub (get_local $s6) (i64.mul (get_local $carry6) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry8 (i64.shr_s (i64.add (get_local $s8) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s9 (i64.add (get_local $s9) (get_local $carry8)))
|
||||
(set_local $s8 (i64.sub (get_local $s8) (i64.mul (get_local $carry8) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry10 (i64.shr_s (i64.add (get_local $s10) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s11 (i64.add (get_local $s11) (get_local $carry10)))
|
||||
(set_local $s10 (i64.sub (get_local $s10) (i64.mul (get_local $carry10) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry12 (i64.shr_s (i64.add (get_local $s12) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s13 (i64.add (get_local $s13) (get_local $carry12)))
|
||||
(set_local $s12 (i64.sub (get_local $s12) (i64.mul (get_local $carry12) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry14 (i64.shr_s (i64.add (get_local $s14) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s15 (i64.add (get_local $s15) (get_local $carry14)))
|
||||
(set_local $s14 (i64.sub (get_local $s14) (i64.mul (get_local $carry14) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry16 (i64.shr_s (i64.add (get_local $s16) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s17 (i64.add (get_local $s17) (get_local $carry16)))
|
||||
(set_local $s16 (i64.sub (get_local $s16) (i64.mul (get_local $carry16) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry18 (i64.shr_s (i64.add (get_local $s18) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s19 (i64.add (get_local $s19) (get_local $carry18)))
|
||||
(set_local $s18 (i64.sub (get_local $s18) (i64.mul (get_local $carry18) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry20 (i64.shr_s (i64.add (get_local $s20) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s21 (i64.add (get_local $s21) (get_local $carry20)))
|
||||
(set_local $s20 (i64.sub (get_local $s20) (i64.mul (get_local $carry20) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry22 (i64.shr_s (i64.add (get_local $s22) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s23 (i64.add (get_local $s23) (get_local $carry22)))
|
||||
(set_local $s22 (i64.sub (get_local $s22) (i64.mul (get_local $carry22) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry1 (i64.shr_s (i64.add (get_local $s1) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s2 (i64.add (get_local $s2) (get_local $carry1)))
|
||||
(set_local $s1 (i64.sub (get_local $s1) (i64.mul (get_local $carry1) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry3 (i64.shr_s (i64.add (get_local $s3) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s4 (i64.add (get_local $s4) (get_local $carry3)))
|
||||
(set_local $s3 (i64.sub (get_local $s3) (i64.mul (get_local $carry3) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry5 (i64.shr_s (i64.add (get_local $s5) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s6 (i64.add (get_local $s6) (get_local $carry5)))
|
||||
(set_local $s5 (i64.sub (get_local $s5) (i64.mul (get_local $carry5) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry7 (i64.shr_s (i64.add (get_local $s7) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s8 (i64.add (get_local $s8) (get_local $carry7)))
|
||||
(set_local $s7 (i64.sub (get_local $s7) (i64.mul (get_local $carry7) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry9 (i64.shr_s (i64.add (get_local $s9) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s10 (i64.add (get_local $s10) (get_local $carry9)))
|
||||
(set_local $s9 (i64.sub (get_local $s9) (i64.mul (get_local $carry9) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry11 (i64.shr_s (i64.add (get_local $s11) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s12 (i64.add (get_local $s12) (get_local $carry11)))
|
||||
(set_local $s11 (i64.sub (get_local $s11) (i64.mul (get_local $carry11) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry13 (i64.shr_s (i64.add (get_local $s13) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s14 (i64.add (get_local $s14) (get_local $carry13)))
|
||||
(set_local $s13 (i64.sub (get_local $s13) (i64.mul (get_local $carry13) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry15 (i64.shr_s (i64.add (get_local $s15) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s16 (i64.add (get_local $s16) (get_local $carry15)))
|
||||
(set_local $s15 (i64.sub (get_local $s15) (i64.mul (get_local $carry15) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry17 (i64.shr_s (i64.add (get_local $s17) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s18 (i64.add (get_local $s18) (get_local $carry17)))
|
||||
(set_local $s17 (i64.sub (get_local $s17) (i64.mul (get_local $carry17) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry19 (i64.shr_s (i64.add (get_local $s19) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s20 (i64.add (get_local $s20) (get_local $carry19)))
|
||||
(set_local $s19 (i64.sub (get_local $s19) (i64.mul (get_local $carry19) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry21 (i64.shr_s (i64.add (get_local $s21) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s22 (i64.add (get_local $s22) (get_local $carry21)))
|
||||
(set_local $s21 (i64.sub (get_local $s21) (i64.mul (get_local $carry21) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(get_local $s)
|
||||
(get_local $s0)
|
||||
(get_local $s1)
|
||||
(get_local $s2)
|
||||
(get_local $s3)
|
||||
(get_local $s4)
|
||||
(get_local $s5)
|
||||
(get_local $s6)
|
||||
(get_local $s7)
|
||||
(get_local $s8)
|
||||
(get_local $s9)
|
||||
(get_local $s10)
|
||||
(get_local $s11)
|
||||
(get_local $s12)
|
||||
(get_local $s13)
|
||||
(get_local $s14)
|
||||
(get_local $s15)
|
||||
(get_local $s16)
|
||||
(get_local $s17)
|
||||
(get_local $s18)
|
||||
(get_local $s19)
|
||||
(get_local $s20)
|
||||
(get_local $s21)
|
||||
(get_local $s22)
|
||||
(get_local $s23)
|
||||
(i32.const 0)
|
||||
(call_indirect (type $to_void))))
|
||||
|
||||
;; TODO: export muladd and call in reduce
|
||||
@@ -0,0 +1,61 @@
|
||||
|
||||
module.exports = loadWebAssembly
|
||||
|
||||
loadWebAssembly.supported = typeof WebAssembly !== 'undefined'
|
||||
|
||||
function loadWebAssembly (opts) {
|
||||
if (!loadWebAssembly.supported) return null
|
||||
|
||||
var imp = opts && opts.imports
|
||||
var wasm = toUint8Array('AGFzbQEAAAABTQtgGX9+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn4AYAF/AGABfwF/YAJ/fwBgAX0AYAF9AX1gAXwAYAF8AXxgAX4AYAF+AX5gBH9/f38AAm4IAmpzBXRhYmxlAXAAAQVkZWJ1ZwNsb2cAAQVkZWJ1Zwdsb2dfdGVlAAIFZGVidWcDbG9nAAMFZGVidWcDbG9nAAQFZGVidWcHbG9nX3RlZQAFBWRlYnVnA2xvZwAGBWRlYnVnB2xvZ190ZWUABwMEAwgJCgUDAQABBxsCBm1lbW9yeQIADnNjMjU1MTlfbXVsYWRkAAkKwBEDDQAgAEIgh6cgAKcQAgsJACAAEAcgAA8LpREBVH4gATUCACEFIAE1AgQhBiABNQIIIQcgATUCDCEIIAE1AhAhCSABNQIUIQogATUCGCELIAE1AhwhDCABNQIgIQ0gATUCJCEOIAE1AighDyABNQIsIRAgAjUCACERIAI1AgQhEiACNQIIIRMgAjUCDCEUIAI1AhAhFSACNQIUIRYgAjUCGCEXIAI1AhwhGCACNQIgIRkgAjUCJCEaIAI1AighGyACNQIsIRwgAzUCACEdIAM1AgQhHiADNQIIIR8gAzUCDCEgIAM1AhAhISADNQIUISIgAzUCGCEjIAM1AhwhJCADNQIgISUgAzUCJCEmIAM1AighJyADNQIsISggBaesIQUgBqesIQYgB6esIQcgCKesIQggCaesIQkgCqesIQogC6esIQsgDKesIQwgDaesIQ0gDqesIQ4gD6esIQ8gEKesIRAgEaesIREgEqesIRIgE6esIRMgFKesIRQgFaesIRUgFqesIRYgF6esIRcgGKesIRggGaesIRkgGqesIRogG6esIRsgHKesIRwgHaesIR0gHqesIR4gH6esIR8gIKesISAgIaesISEgIqesISIgI6esISMgJKesISQgJaesISUgJqesISYgJ6esIScgKKesISggHSAFIBF+fCEpIB4gBSASfiAGIBF+fHwhKiAfIAUgE34gBiASfiAHIBF+fHx8ISsgICAFIBR+IAYgE34gByASfiAIIBF+fHx8fCEsICEgBSAVfiAGIBR+IAcgE34gCCASfiAJIBF+fHx8fHwhLSAiIAUgFn4gBiAVfiAHIBR+IAggE34gCSASfiAKIBF+fHx8fHx8IS4gIyAFIBd+IAYgFn4gByAVfiAIIBR+IAkgE34gCiASfiALIBF+fHx8fHx8fCEvICQgBSAYfiAGIBd+IAcgFn4gCCAVfiAJIBR+IAogE34gCyASfiAMIBF+fHx8fHx8fHwhMCAlIAUgGX4gBiAYfiAHIBd+IAggFn4gCSAVfiAKIBR+IAsgE34gDCASfiANIBF+fHx8fHx8fHx8ITEgJiAFIBp+IAYgGX4gByAYfiAIIBd+IAkgFn4gCiAVfiALIBR+IAwgE34gDSASfiAOIBF+fHx8fHx8fHx8fCEyICcgBSAbfiAGIBp+IAcgGX4gCCAYfiAJIBd+IAogFn4gCyAVfiAMIBR+IA0gE34gDiASfiAPIBF+fHx8fHx8fHx8fHwhMyAoIAUgHH4gBiAbfiAHIBp+IAggGX4gCSAYfiAKIBd+IAsgFn4gDCAVfiANIBR+IA4gE34gDyASfiAQIBF+fHx8fHx8fHx8fHx8ITQgBiAcfiAHIBt+IAggGn4gCSAZfiAKIBh+IAsgF34gDCAWfiANIBV+IA4gFH4gDyATfiAQIBJ+fHx8fHx8fHx8fCE1IAcgHH4gCCAbfiAJIBp+IAogGX4gCyAYfiAMIBd+IA0gFn4gDiAVfiAPIBR+IBAgE358fHx8fHx8fHwhNiAIIBx+IAkgG34gCiAafiALIBl+IAwgGH4gDSAXfiAOIBZ+IA8gFX4gECAUfnx8fHx8fHx8ITcgCSAcfiAKIBt+IAsgGn4gDCAZfiANIBh+IA4gF34gDyAWfiAQIBV+fHx8fHx8fCE4IAogHH4gCyAbfiAMIBp+IA0gGX4gDiAYfiAPIBd+IBAgFn58fHx8fHwhOSALIBx+IAwgG34gDSAafiAOIBl+IA8gGH4gECAXfnx8fHx8ITogDCAcfiANIBt+IA4gGn4gDyAZfiAQIBh+fHx8fCE7IA0gHH4gDiAbfiAPIBp+IBAgGX58fHwhPCAOIBx+IA8gG34gECAafnx8IT0gDyAcfiAQIBt+fCE+IBAgHH4hP0IAIUAgKUIBQhSGfEIVhyFBICogQXwhKiApIEFCAUIVhn59ISkgK0IBQhSGfEIVhyFDICwgQ3whLCArIENCAUIVhn59ISsgLUIBQhSGfEIVhyFFIC4gRXwhLiAtIEVCAUIVhn59IS0gL0IBQhSGfEIVhyFHIDAgR3whMCAvIEdCAUIVhn59IS8gMUIBQhSGfEIVhyFJIDIgSXwhMiAxIElCAUIVhn59ITEgM0IBQhSGfEIVhyFLIDQgS3whNCAzIEtCAUIVhn59ITMgNUIBQhSGfEIVhyFNIDYgTXwhNiA1IE1CAUIVhn59ITUgN0IBQhSGfEIVhyFPIDggT3whOCA3IE9CAUIVhn59ITcgOUIBQhSGfEIVhyFRIDogUXwhOiA5IFFCAUIVhn59ITkgO0IBQhSGfEIVhyFTIDwgU3whPCA7IFNCAUIVhn59ITsgPUIBQhSGfEIVhyFVID4gVXwhPiA9IFVCAUIVhn59IT0gP0IBQhSGfEIVhyFXIEAgV3whQCA/IFdCAUIVhn59IT8gKkIBQhSGfEIVhyFCICsgQnwhKyAqIEJCAUIVhn59ISogLEIBQhSGfEIVhyFEIC0gRHwhLSAsIERCAUIVhn59ISwgLkIBQhSGfEIVhyFGIC8gRnwhLyAuIEZCAUIVhn59IS4gMEIBQhSGfEIVhyFIIDEgSHwhMSAwIEhCAUIVhn59ITAgMkIBQhSGfEIVhyFKIDMgSnwhMyAyIEpCAUIVhn59ITIgNEIBQhSGfEIVhyFMIDUgTHwhNSA0IExCAUIVhn59ITQgNkIBQhSGfEIVhyFOIDcgTnwhNyA2IE5CAUIVhn59ITYgOEIBQhSGfEIVhyFQIDkgUHwhOSA4IFBCAUIVhn59ITggOkIBQhSGfEIVhyFSIDsgUnwhOyA6IFJCAUIVhn59ITogPEIBQhSGfEIVhyFUID0gVHwhPSA8IFRCAUIVhn59ITwgPkIBQhSGfEIVhyFWID8gVnwhPyA+IFZCAUIVhn59IT4gACApICogKyAsIC0gLiAvIDAgMSAyIDMgNCA1IDYgNyA4IDkgOiA7IDwgPSA+ID8gQEEAEQAACw==')
|
||||
var ready = null
|
||||
|
||||
var mod = {
|
||||
buffer: wasm,
|
||||
memory: null,
|
||||
exports: null,
|
||||
realloc: realloc,
|
||||
onload: onload
|
||||
}
|
||||
|
||||
onload(function () {})
|
||||
|
||||
return mod
|
||||
|
||||
function realloc (size) {
|
||||
mod.exports.memory.grow(Math.max(0, Math.ceil(Math.abs(size - mod.memory.length) / 65536)))
|
||||
mod.memory = new Uint8Array(mod.exports.memory.buffer)
|
||||
}
|
||||
|
||||
function onload (cb) {
|
||||
if (mod.exports) return cb()
|
||||
|
||||
if (ready) {
|
||||
ready.then(cb.bind(null, null)).catch(cb)
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
if (opts && opts.async) throw new Error('async')
|
||||
setup({instance: new WebAssembly.Instance(new WebAssembly.Module(wasm), imp)})
|
||||
} catch (err) {
|
||||
ready = WebAssembly.instantiate(wasm, imp).then(setup)
|
||||
}
|
||||
|
||||
onload(cb)
|
||||
}
|
||||
|
||||
function setup (w) {
|
||||
mod.exports = w.instance.exports
|
||||
mod.memory = mod.exports.memory && mod.exports.memory.buffer && new Uint8Array(mod.exports.memory.buffer)
|
||||
}
|
||||
}
|
||||
|
||||
function toUint8Array (s) {
|
||||
if (typeof atob === 'function') return new Uint8Array(atob(s).split('').map(charCodeAt))
|
||||
return (require('buf' + 'fer').Buffer).from(s, 'base64')
|
||||
}
|
||||
|
||||
function charCodeAt (c) {
|
||||
return c.charCodeAt(0)
|
||||
}
|
||||
@@ -0,0 +1,373 @@
|
||||
(module
|
||||
(import "js" "table" (table 1 anyfunc))
|
||||
(type $to_void (func
|
||||
(param $s i32)
|
||||
(param $s0 i64)
|
||||
(param $s1 i64)
|
||||
(param $s2 i64)
|
||||
(param $s3 i64)
|
||||
(param $s4 i64)
|
||||
(param $s5 i64)
|
||||
(param $s6 i64)
|
||||
(param $s7 i64)
|
||||
(param $s8 i64)
|
||||
(param $s9 i64)
|
||||
(param $s10 i64)
|
||||
(param $s11 i64)
|
||||
(param $s12 i64)
|
||||
(param $s13 i64)
|
||||
(param $s14 i64)
|
||||
(param $s15 i64)
|
||||
(param $s16 i64)
|
||||
(param $s17 i64)
|
||||
(param $s18 i64)
|
||||
(param $s19 i64)
|
||||
(param $s20 i64)
|
||||
(param $s21 i64)
|
||||
(param $s22 i64)
|
||||
(param $s23 i64)))
|
||||
|
||||
(func $i32.log (import "debug" "log") (param i32))
|
||||
(func $i32.log_tee (import "debug" "log_tee") (param i32) (result i32))
|
||||
;; No i64 interop with JS yet - but maybe coming with WebAssembly BigInt
|
||||
;; So we can instead fake this by splitting the i64 into two i32 limbs,
|
||||
;; however these are WASM functions using i32x2.log:
|
||||
(func $i32x2.log (import "debug" "log") (param i32) (param i32))
|
||||
(func $f32.log (import "debug" "log") (param f32))
|
||||
(func $f32.log_tee (import "debug" "log_tee") (param f32) (result f32))
|
||||
(func $f64.log (import "debug" "log") (param f64))
|
||||
(func $f64.log_tee (import "debug" "log_tee") (param f64) (result f64))
|
||||
|
||||
;; i64 logging by splitting into two i32 limbs
|
||||
(func $i64.log
|
||||
(param $0 i64)
|
||||
(call $i32x2.log
|
||||
;; Upper limb
|
||||
(i32.wrap/i64
|
||||
(i64.shr_s (get_local $0)
|
||||
(i64.const 32)))
|
||||
;; Lower limb
|
||||
(i32.wrap/i64 (get_local $0))))
|
||||
|
||||
(func $i64.log_tee
|
||||
(param $0 i64)
|
||||
(result i64)
|
||||
(call $i64.log (get_local $0))
|
||||
(return (get_local $0)))
|
||||
|
||||
(memory $0 1)
|
||||
(export "memory" (memory $0))
|
||||
|
||||
(func $sc25519_muladd (export "sc25519_muladd") (param $s i32) (param $a i32) (param $b i32) (param $c i32)
|
||||
(local $tmp i64)
|
||||
|
||||
(local $a0 i64)
|
||||
(local $a1 i64)
|
||||
(local $a2 i64)
|
||||
(local $a3 i64)
|
||||
(local $a4 i64)
|
||||
(local $a5 i64)
|
||||
(local $a6 i64)
|
||||
(local $a7 i64)
|
||||
(local $a8 i64)
|
||||
(local $a9 i64)
|
||||
(local $a10 i64)
|
||||
(local $a11 i64)
|
||||
|
||||
(local $b0 i64)
|
||||
(local $b1 i64)
|
||||
(local $b2 i64)
|
||||
(local $b3 i64)
|
||||
(local $b4 i64)
|
||||
(local $b5 i64)
|
||||
(local $b6 i64)
|
||||
(local $b7 i64)
|
||||
(local $b8 i64)
|
||||
(local $b9 i64)
|
||||
(local $b10 i64)
|
||||
(local $b11 i64)
|
||||
|
||||
(local $c0 i64)
|
||||
(local $c1 i64)
|
||||
(local $c2 i64)
|
||||
(local $c3 i64)
|
||||
(local $c4 i64)
|
||||
(local $c5 i64)
|
||||
(local $c6 i64)
|
||||
(local $c7 i64)
|
||||
(local $c8 i64)
|
||||
(local $c9 i64)
|
||||
(local $c10 i64)
|
||||
(local $c11 i64)
|
||||
|
||||
(local $s0 i64)
|
||||
(local $s1 i64)
|
||||
(local $s2 i64)
|
||||
(local $s3 i64)
|
||||
(local $s4 i64)
|
||||
(local $s5 i64)
|
||||
(local $s6 i64)
|
||||
(local $s7 i64)
|
||||
(local $s8 i64)
|
||||
(local $s9 i64)
|
||||
(local $s10 i64)
|
||||
(local $s11 i64)
|
||||
(local $s12 i64)
|
||||
(local $s13 i64)
|
||||
(local $s14 i64)
|
||||
(local $s15 i64)
|
||||
(local $s16 i64)
|
||||
(local $s17 i64)
|
||||
(local $s18 i64)
|
||||
(local $s19 i64)
|
||||
(local $s20 i64)
|
||||
(local $s21 i64)
|
||||
(local $s22 i64)
|
||||
(local $s23 i64)
|
||||
|
||||
(local $carry0 i64)
|
||||
(local $carry1 i64)
|
||||
(local $carry2 i64)
|
||||
(local $carry3 i64)
|
||||
(local $carry4 i64)
|
||||
(local $carry5 i64)
|
||||
(local $carry6 i64)
|
||||
(local $carry7 i64)
|
||||
(local $carry8 i64)
|
||||
(local $carry9 i64)
|
||||
(local $carry10 i64)
|
||||
(local $carry11 i64)
|
||||
(local $carry12 i64)
|
||||
(local $carry13 i64)
|
||||
(local $carry14 i64)
|
||||
(local $carry15 i64)
|
||||
(local $carry16 i64)
|
||||
(local $carry17 i64)
|
||||
(local $carry18 i64)
|
||||
(local $carry19 i64)
|
||||
(local $carry20 i64)
|
||||
(local $carry21 i64)
|
||||
(local $carry22 i64)
|
||||
|
||||
(set_local $a0 (i64.load32_u offset=0 (get_local $a)))
|
||||
(set_local $a1 (i64.load32_u offset=4 (get_local $a)))
|
||||
(set_local $a2 (i64.load32_u offset=8 (get_local $a)))
|
||||
(set_local $a3 (i64.load32_u offset=12 (get_local $a)))
|
||||
(set_local $a4 (i64.load32_u offset=16 (get_local $a)))
|
||||
(set_local $a5 (i64.load32_u offset=20 (get_local $a)))
|
||||
(set_local $a6 (i64.load32_u offset=24 (get_local $a)))
|
||||
(set_local $a7 (i64.load32_u offset=28 (get_local $a)))
|
||||
(set_local $a8 (i64.load32_u offset=32 (get_local $a)))
|
||||
(set_local $a9 (i64.load32_u offset=36 (get_local $a)))
|
||||
(set_local $a10 (i64.load32_u offset=40 (get_local $a)))
|
||||
(set_local $a11 (i64.load32_u offset=44 (get_local $a)))
|
||||
|
||||
(set_local $b0 (i64.load32_u offset=0 (get_local $b)))
|
||||
(set_local $b1 (i64.load32_u offset=4 (get_local $b)))
|
||||
(set_local $b2 (i64.load32_u offset=8 (get_local $b)))
|
||||
(set_local $b3 (i64.load32_u offset=12 (get_local $b)))
|
||||
(set_local $b4 (i64.load32_u offset=16 (get_local $b)))
|
||||
(set_local $b5 (i64.load32_u offset=20 (get_local $b)))
|
||||
(set_local $b6 (i64.load32_u offset=24 (get_local $b)))
|
||||
(set_local $b7 (i64.load32_u offset=28 (get_local $b)))
|
||||
(set_local $b8 (i64.load32_u offset=32 (get_local $b)))
|
||||
(set_local $b9 (i64.load32_u offset=36 (get_local $b)))
|
||||
(set_local $b10 (i64.load32_u offset=40 (get_local $b)))
|
||||
(set_local $b11 (i64.load32_u offset=44 (get_local $b)))
|
||||
|
||||
(set_local $c0 (i64.load32_u offset=0 (get_local $c)))
|
||||
(set_local $c1 (i64.load32_u offset=4 (get_local $c)))
|
||||
(set_local $c2 (i64.load32_u offset=8 (get_local $c)))
|
||||
(set_local $c3 (i64.load32_u offset=12 (get_local $c)))
|
||||
(set_local $c4 (i64.load32_u offset=16 (get_local $c)))
|
||||
(set_local $c5 (i64.load32_u offset=20 (get_local $c)))
|
||||
(set_local $c6 (i64.load32_u offset=24 (get_local $c)))
|
||||
(set_local $c7 (i64.load32_u offset=28 (get_local $c)))
|
||||
(set_local $c8 (i64.load32_u offset=32 (get_local $c)))
|
||||
(set_local $c9 (i64.load32_u offset=36 (get_local $c)))
|
||||
(set_local $c10 (i64.load32_u offset=40 (get_local $c)))
|
||||
(set_local $c11 (i64.load32_u offset=44 (get_local $c)))
|
||||
|
||||
(set_local $a0 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a0))))
|
||||
(set_local $a1 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a1))))
|
||||
(set_local $a2 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a2))))
|
||||
(set_local $a3 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a3))))
|
||||
(set_local $a4 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a4))))
|
||||
(set_local $a5 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a5))))
|
||||
(set_local $a6 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a6))))
|
||||
(set_local $a7 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a7))))
|
||||
(set_local $a8 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a8))))
|
||||
(set_local $a9 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a9))))
|
||||
(set_local $a10 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a10))))
|
||||
(set_local $a11 (i64.extend_s/i32 (i32.wrap/i64 (get_local $a11))))
|
||||
|
||||
(set_local $b0 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b0))))
|
||||
(set_local $b1 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b1))))
|
||||
(set_local $b2 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b2))))
|
||||
(set_local $b3 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b3))))
|
||||
(set_local $b4 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b4))))
|
||||
(set_local $b5 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b5))))
|
||||
(set_local $b6 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b6))))
|
||||
(set_local $b7 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b7))))
|
||||
(set_local $b8 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b8))))
|
||||
(set_local $b9 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b9))))
|
||||
(set_local $b10 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b10))))
|
||||
(set_local $b11 (i64.extend_s/i32 (i32.wrap/i64 (get_local $b11))))
|
||||
|
||||
(set_local $c0 (i64.extend_s/i32 (i32.wrap/i64 (get_local $c0))))
|
||||
(set_local $c1 (i64.extend_s/i32 (i32.wrap/i64 (get_local $c1))))
|
||||
(set_local $c2 (i64.extend_s/i32 (i32.wrap/i64 (get_local $c2))))
|
||||
(set_local $c3 (i64.extend_s/i32 (i32.wrap/i64 (get_local $c3))))
|
||||
(set_local $c4 (i64.extend_s/i32 (i32.wrap/i64 (get_local $c4))))
|
||||
(set_local $c5 (i64.extend_s/i32 (i32.wrap/i64 (get_local $c5))))
|
||||
(set_local $c6 (i64.extend_s/i32 (i32.wrap/i64 (get_local $c6))))
|
||||
(set_local $c7 (i64.extend_s/i32 (i32.wrap/i64 (get_local $c7))))
|
||||
(set_local $c8 (i64.extend_s/i32 (i32.wrap/i64 (get_local $c8))))
|
||||
(set_local $c9 (i64.extend_s/i32 (i32.wrap/i64 (get_local $c9))))
|
||||
(set_local $c10 (i64.extend_s/i32 (i32.wrap/i64 (get_local $c10))))
|
||||
(set_local $c11 (i64.extend_s/i32 (i32.wrap/i64 (get_local $c11))))
|
||||
|
||||
(set_local $s0 (i64.add (get_local $c0 ) (i64.mul (get_local $a0) (get_local $b0))))
|
||||
(set_local $s1 (i64.add (get_local $c1 ) (i64.add (i64.mul (get_local $a0) (get_local $b1 )) (i64.mul (get_local $a1) (get_local $b0)))))
|
||||
(set_local $s2 (i64.add (get_local $c2 ) (i64.add (i64.mul (get_local $a0) (get_local $b2 )) (i64.add (i64.mul (get_local $a1) (get_local $b1 )) (i64.mul (get_local $a2) (get_local $b0))))))
|
||||
(set_local $s3 (i64.add (get_local $c3 ) (i64.add (i64.mul (get_local $a0) (get_local $b3 )) (i64.add (i64.mul (get_local $a1) (get_local $b2 )) (i64.add (i64.mul (get_local $a2) (get_local $b1)) (i64.mul (get_local $a3) (get_local $b0)))))))
|
||||
(set_local $s4 (i64.add (get_local $c4 ) (i64.add (i64.mul (get_local $a0) (get_local $b4 )) (i64.add (i64.mul (get_local $a1) (get_local $b3 )) (i64.add (i64.mul (get_local $a2) (get_local $b2)) (i64.add (i64.mul (get_local $a3) (get_local $b1)) (i64.mul (get_local $a4) (get_local $b0))))))))
|
||||
(set_local $s5 (i64.add (get_local $c5 ) (i64.add (i64.mul (get_local $a0) (get_local $b5 )) (i64.add (i64.mul (get_local $a1) (get_local $b4 )) (i64.add (i64.mul (get_local $a2) (get_local $b3)) (i64.add (i64.mul (get_local $a3) (get_local $b2)) (i64.add (i64.mul (get_local $a4) (get_local $b1)) (i64.mul (get_local $a5) (get_local $b0)))))))))
|
||||
(set_local $s6 (i64.add (get_local $c6 ) (i64.add (i64.mul (get_local $a0) (get_local $b6 )) (i64.add (i64.mul (get_local $a1) (get_local $b5 )) (i64.add (i64.mul (get_local $a2) (get_local $b4)) (i64.add (i64.mul (get_local $a3) (get_local $b3)) (i64.add (i64.mul (get_local $a4) (get_local $b2)) (i64.add (i64.mul (get_local $a5) (get_local $b1)) (i64.mul (get_local $a6) (get_local $b0))))))))))
|
||||
(set_local $s7 (i64.add (get_local $c7 ) (i64.add (i64.mul (get_local $a0) (get_local $b7 )) (i64.add (i64.mul (get_local $a1) (get_local $b6 )) (i64.add (i64.mul (get_local $a2) (get_local $b5)) (i64.add (i64.mul (get_local $a3) (get_local $b4)) (i64.add (i64.mul (get_local $a4) (get_local $b3)) (i64.add (i64.mul (get_local $a5) (get_local $b2)) (i64.add (i64.mul (get_local $a6) (get_local $b1)) (i64.mul (get_local $a7) (get_local $b0)))))))))))
|
||||
(set_local $s8 (i64.add (get_local $c8 ) (i64.add (i64.mul (get_local $a0) (get_local $b8 )) (i64.add (i64.mul (get_local $a1) (get_local $b7 )) (i64.add (i64.mul (get_local $a2) (get_local $b6)) (i64.add (i64.mul (get_local $a3) (get_local $b5)) (i64.add (i64.mul (get_local $a4) (get_local $b4)) (i64.add (i64.mul (get_local $a5) (get_local $b3)) (i64.add (i64.mul (get_local $a6) (get_local $b2)) (i64.add (i64.mul (get_local $a7) (get_local $b1)) (i64.mul (get_local $a8) (get_local $b0))))))))))))
|
||||
(set_local $s9 (i64.add (get_local $c9 ) (i64.add (i64.mul (get_local $a0) (get_local $b9 )) (i64.add (i64.mul (get_local $a1) (get_local $b8 )) (i64.add (i64.mul (get_local $a2) (get_local $b7)) (i64.add (i64.mul (get_local $a3) (get_local $b6)) (i64.add (i64.mul (get_local $a4) (get_local $b5)) (i64.add (i64.mul (get_local $a5) (get_local $b4)) (i64.add (i64.mul (get_local $a6) (get_local $b3)) (i64.add (i64.mul (get_local $a7) (get_local $b2)) (i64.add (i64.mul (get_local $a8) (get_local $b1)) (i64.mul (get_local $a9) (get_local $b0)))))))))))))
|
||||
(set_local $s10 (i64.add (get_local $c10) (i64.add (i64.mul (get_local $a0) (get_local $b10)) (i64.add (i64.mul (get_local $a1) (get_local $b9 )) (i64.add (i64.mul (get_local $a2) (get_local $b8)) (i64.add (i64.mul (get_local $a3) (get_local $b7)) (i64.add (i64.mul (get_local $a4) (get_local $b6)) (i64.add (i64.mul (get_local $a5) (get_local $b5)) (i64.add (i64.mul (get_local $a6) (get_local $b4)) (i64.add (i64.mul (get_local $a7) (get_local $b3)) (i64.add (i64.mul (get_local $a8) (get_local $b2)) (i64.add (i64.mul (get_local $a9) (get_local $b1)) (i64.mul (get_local $a10) (get_local $b0))))))))))))))
|
||||
(set_local $s11 (i64.add (get_local $c11) (i64.add (i64.mul (get_local $a0) (get_local $b11)) (i64.add (i64.mul (get_local $a1) (get_local $b10)) (i64.add (i64.mul (get_local $a2) (get_local $b9)) (i64.add (i64.mul (get_local $a3) (get_local $b8)) (i64.add (i64.mul (get_local $a4) (get_local $b7)) (i64.add (i64.mul (get_local $a5) (get_local $b6)) (i64.add (i64.mul (get_local $a6) (get_local $b5)) (i64.add (i64.mul (get_local $a7) (get_local $b4)) (i64.add (i64.mul (get_local $a8) (get_local $b3)) (i64.add (i64.mul (get_local $a9) (get_local $b2)) (i64.add (i64.mul (get_local $a10) (get_local $b1)) (i64.mul (get_local $a11) (get_local $b0)))))))))))))))
|
||||
(set_local $s12 (i64.add (i64.mul (get_local $a1) (get_local $b11)) (i64.add (i64.mul (get_local $a2) (get_local $b10)) (i64.add (i64.mul (get_local $a3) (get_local $b9)) (i64.add (i64.mul (get_local $a4) (get_local $b8)) (i64.add (i64.mul (get_local $a5) (get_local $b7)) (i64.add (i64.mul (get_local $a6) (get_local $b6)) (i64.add (i64.mul (get_local $a7) (get_local $b5)) (i64.add (i64.mul (get_local $a8) (get_local $b4)) (i64.add (i64.mul (get_local $a9) (get_local $b3)) (i64.add (i64.mul (get_local $a10) (get_local $b2)) (i64.mul (get_local $a11) (get_local $b1)))))))))))))
|
||||
(set_local $s13 (i64.add (i64.mul (get_local $a2) (get_local $b11)) (i64.add (i64.mul (get_local $a3) (get_local $b10)) (i64.add (i64.mul (get_local $a4) (get_local $b9)) (i64.add (i64.mul (get_local $a5) (get_local $b8)) (i64.add (i64.mul (get_local $a6) (get_local $b7)) (i64.add (i64.mul (get_local $a7) (get_local $b6)) (i64.add (i64.mul (get_local $a8) (get_local $b5)) (i64.add (i64.mul (get_local $a9) (get_local $b4)) (i64.add (i64.mul (get_local $a10) (get_local $b3)) (i64.mul (get_local $a11) (get_local $b2))))))))))))
|
||||
(set_local $s14 (i64.add (i64.mul (get_local $a3) (get_local $b11)) (i64.add (i64.mul (get_local $a4) (get_local $b10)) (i64.add (i64.mul (get_local $a5) (get_local $b9)) (i64.add (i64.mul (get_local $a6) (get_local $b8)) (i64.add (i64.mul (get_local $a7) (get_local $b7)) (i64.add (i64.mul (get_local $a8) (get_local $b6)) (i64.add (i64.mul (get_local $a9) (get_local $b5)) (i64.add (i64.mul (get_local $a10) (get_local $b4)) (i64.mul (get_local $a11) (get_local $b3)))))))))))
|
||||
(set_local $s15 (i64.add (i64.mul (get_local $a4) (get_local $b11)) (i64.add (i64.mul (get_local $a5) (get_local $b10)) (i64.add (i64.mul (get_local $a6) (get_local $b9)) (i64.add (i64.mul (get_local $a7) (get_local $b8)) (i64.add (i64.mul (get_local $a8) (get_local $b7)) (i64.add (i64.mul (get_local $a9) (get_local $b6)) (i64.add (i64.mul (get_local $a10) (get_local $b5)) (i64.mul (get_local $a11) (get_local $b4))))))))))
|
||||
(set_local $s16 (i64.add (i64.mul (get_local $a5) (get_local $b11)) (i64.add (i64.mul (get_local $a6) (get_local $b10)) (i64.add (i64.mul (get_local $a7) (get_local $b9)) (i64.add (i64.mul (get_local $a8) (get_local $b8)) (i64.add (i64.mul (get_local $a9) (get_local $b7)) (i64.add (i64.mul (get_local $a10) (get_local $b6)) (i64.mul (get_local $a11) (get_local $b5)))))))))
|
||||
(set_local $s17 (i64.add (i64.mul (get_local $a6) (get_local $b11)) (i64.add (i64.mul (get_local $a7) (get_local $b10)) (i64.add (i64.mul (get_local $a8) (get_local $b9)) (i64.add (i64.mul (get_local $a9) (get_local $b8)) (i64.add (i64.mul (get_local $a10) (get_local $b7)) (i64.mul (get_local $a11) (get_local $b6))))))))
|
||||
(set_local $s18 (i64.add (i64.mul (get_local $a7) (get_local $b11)) (i64.add (i64.mul (get_local $a8) (get_local $b10)) (i64.add (i64.mul (get_local $a9) (get_local $b9)) (i64.add (i64.mul (get_local $a10) (get_local $b8)) (i64.mul (get_local $a11) (get_local $b7)))))))
|
||||
(set_local $s19 (i64.add (i64.mul (get_local $a8) (get_local $b11)) (i64.add (i64.mul (get_local $a9) (get_local $b10)) (i64.add (i64.mul (get_local $a10) (get_local $b9)) (i64.mul (get_local $a11) (get_local $b8))))))
|
||||
(set_local $s20 (i64.add (i64.mul (get_local $a9) (get_local $b11)) (i64.add (i64.mul (get_local $a10) (get_local $b10)) (i64.mul (get_local $a11) (get_local $b9)))))
|
||||
(set_local $s21 (i64.add (i64.mul (get_local $a10) (get_local $b11)) (i64.mul (get_local $a11) (get_local $b10))))
|
||||
(set_local $s22 (i64.mul (get_local $a11) (get_local $b11)))
|
||||
(set_local $s23 (i64.const 0))
|
||||
|
||||
(set_local $carry0 (i64.shr_s (i64.add (get_local $s0) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s1 (i64.add (get_local $s1) (get_local $carry0)))
|
||||
(set_local $s0 (i64.sub (get_local $s0) (i64.mul (get_local $carry0) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry2 (i64.shr_s (i64.add (get_local $s2) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s3 (i64.add (get_local $s3) (get_local $carry2)))
|
||||
(set_local $s2 (i64.sub (get_local $s2) (i64.mul (get_local $carry2) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry4 (i64.shr_s (i64.add (get_local $s4) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s5 (i64.add (get_local $s5) (get_local $carry4)))
|
||||
(set_local $s4 (i64.sub (get_local $s4) (i64.mul (get_local $carry4) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry6 (i64.shr_s (i64.add (get_local $s6) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s7 (i64.add (get_local $s7) (get_local $carry6)))
|
||||
(set_local $s6 (i64.sub (get_local $s6) (i64.mul (get_local $carry6) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry8 (i64.shr_s (i64.add (get_local $s8) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s9 (i64.add (get_local $s9) (get_local $carry8)))
|
||||
(set_local $s8 (i64.sub (get_local $s8) (i64.mul (get_local $carry8) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry10 (i64.shr_s (i64.add (get_local $s10) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s11 (i64.add (get_local $s11) (get_local $carry10)))
|
||||
(set_local $s10 (i64.sub (get_local $s10) (i64.mul (get_local $carry10) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry12 (i64.shr_s (i64.add (get_local $s12) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s13 (i64.add (get_local $s13) (get_local $carry12)))
|
||||
(set_local $s12 (i64.sub (get_local $s12) (i64.mul (get_local $carry12) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry14 (i64.shr_s (i64.add (get_local $s14) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s15 (i64.add (get_local $s15) (get_local $carry14)))
|
||||
(set_local $s14 (i64.sub (get_local $s14) (i64.mul (get_local $carry14) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry16 (i64.shr_s (i64.add (get_local $s16) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s17 (i64.add (get_local $s17) (get_local $carry16)))
|
||||
(set_local $s16 (i64.sub (get_local $s16) (i64.mul (get_local $carry16) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry18 (i64.shr_s (i64.add (get_local $s18) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s19 (i64.add (get_local $s19) (get_local $carry18)))
|
||||
(set_local $s18 (i64.sub (get_local $s18) (i64.mul (get_local $carry18) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry20 (i64.shr_s (i64.add (get_local $s20) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s21 (i64.add (get_local $s21) (get_local $carry20)))
|
||||
(set_local $s20 (i64.sub (get_local $s20) (i64.mul (get_local $carry20) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry22 (i64.shr_s (i64.add (get_local $s22) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s23 (i64.add (get_local $s23) (get_local $carry22)))
|
||||
(set_local $s22 (i64.sub (get_local $s22) (i64.mul (get_local $carry22) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry1 (i64.shr_s (i64.add (get_local $s1) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s2 (i64.add (get_local $s2) (get_local $carry1)))
|
||||
(set_local $s1 (i64.sub (get_local $s1) (i64.mul (get_local $carry1) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry3 (i64.shr_s (i64.add (get_local $s3) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s4 (i64.add (get_local $s4) (get_local $carry3)))
|
||||
(set_local $s3 (i64.sub (get_local $s3) (i64.mul (get_local $carry3) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry5 (i64.shr_s (i64.add (get_local $s5) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s6 (i64.add (get_local $s6) (get_local $carry5)))
|
||||
(set_local $s5 (i64.sub (get_local $s5) (i64.mul (get_local $carry5) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry7 (i64.shr_s (i64.add (get_local $s7) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s8 (i64.add (get_local $s8) (get_local $carry7)))
|
||||
(set_local $s7 (i64.sub (get_local $s7) (i64.mul (get_local $carry7) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry9 (i64.shr_s (i64.add (get_local $s9) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s10 (i64.add (get_local $s10) (get_local $carry9)))
|
||||
(set_local $s9 (i64.sub (get_local $s9) (i64.mul (get_local $carry9) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry11 (i64.shr_s (i64.add (get_local $s11) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s12 (i64.add (get_local $s12) (get_local $carry11)))
|
||||
(set_local $s11 (i64.sub (get_local $s11) (i64.mul (get_local $carry11) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry13 (i64.shr_s (i64.add (get_local $s13) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s14 (i64.add (get_local $s14) (get_local $carry13)))
|
||||
(set_local $s13 (i64.sub (get_local $s13) (i64.mul (get_local $carry13) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry15 (i64.shr_s (i64.add (get_local $s15) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s16 (i64.add (get_local $s16) (get_local $carry15)))
|
||||
(set_local $s15 (i64.sub (get_local $s15) (i64.mul (get_local $carry15) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry17 (i64.shr_s (i64.add (get_local $s17) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s18 (i64.add (get_local $s18) (get_local $carry17)))
|
||||
(set_local $s17 (i64.sub (get_local $s17) (i64.mul (get_local $carry17) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry19 (i64.shr_s (i64.add (get_local $s19) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s20 (i64.add (get_local $s20) (get_local $carry19)))
|
||||
(set_local $s19 (i64.sub (get_local $s19) (i64.mul (get_local $carry19) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry21 (i64.shr_s (i64.add (get_local $s21) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s22 (i64.add (get_local $s22) (get_local $carry21)))
|
||||
(set_local $s21 (i64.sub (get_local $s21) (i64.mul (get_local $carry21) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(get_local $s)
|
||||
(get_local $s0)
|
||||
(get_local $s1)
|
||||
(get_local $s2)
|
||||
(get_local $s3)
|
||||
(get_local $s4)
|
||||
(get_local $s5)
|
||||
(get_local $s6)
|
||||
(get_local $s7)
|
||||
(get_local $s8)
|
||||
(get_local $s9)
|
||||
(get_local $s10)
|
||||
(get_local $s11)
|
||||
(get_local $s12)
|
||||
(get_local $s13)
|
||||
(get_local $s14)
|
||||
(get_local $s15)
|
||||
(get_local $s16)
|
||||
(get_local $s17)
|
||||
(get_local $s18)
|
||||
(get_local $s19)
|
||||
(get_local $s20)
|
||||
(get_local $s21)
|
||||
(get_local $s22)
|
||||
(get_local $s23)
|
||||
(i32.const 0)
|
||||
(call_indirect (type $to_void))))
|
||||
@@ -0,0 +1,61 @@
|
||||
|
||||
module.exports = loadWebAssembly
|
||||
|
||||
loadWebAssembly.supported = typeof WebAssembly !== 'undefined'
|
||||
|
||||
function loadWebAssembly (opts) {
|
||||
if (!loadWebAssembly.supported) return null
|
||||
|
||||
var imp = opts && opts.imports
|
||||
var wasm = toUint8Array('AGFzbQEAAAABRgpgAX8AYAF/AX9gAn9/AGABfQBgAX0BfWABfABgAXwBfGABfgBgAX4BfmAZf35+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fgACbggCanMFdGFibGUBcAABBWRlYnVnA2xvZwAABWRlYnVnB2xvZ190ZWUAAQVkZWJ1ZwNsb2cAAgVkZWJ1ZwNsb2cAAwVkZWJ1Zwdsb2dfdGVlAAQFZGVidWcDbG9nAAUFZGVidWcHbG9nX3RlZQAGAwUEBwgJAAUDAQABBycDBm1lbW9yeQIACXNjX3JlZHVjZQAJDnNjMjU1MTlfcmVkdWNlAAoJBwEAQQALAQkKkhgEDQAgAEIgh6cgAKcQAgsJACAAEAcgAA8L+BYBEX4gDCAYQpPYKH58IQwgDSAYQpjaHH58IQ0gDiAYQuf2J358IQ4gDyAYQq3zPH59IQ8gECAYQtGrCH58IRAgESAYQv3eKX59IREgCyAXQpPYKH58IQsgDCAXQpjaHH58IQwgDSAXQuf2J358IQ0gDiAXQq3zPH59IQ4gDyAXQtGrCH58IQ8gECAXQv3eKX59IRAgCiAWQpPYKH58IQogCyAWQpjaHH58IQsgDCAWQuf2J358IQwgDSAWQq3zPH59IQ0gDiAWQtGrCH58IQ4gDyAWQv3eKX59IQ8gCSAVQpPYKH58IQkgCiAVQpjaHH58IQogCyAVQuf2J358IQsgDCAVQq3zPH59IQwgDSAVQtGrCH58IQ0gDiAVQv3eKX59IQ4gCCAUQpPYKH58IQggCSAUQpjaHH58IQkgCiAUQuf2J358IQogCyAUQq3zPH59IQsgDCAUQtGrCH58IQwgDSAUQv3eKX59IQ0gByATQpPYKH58IQcgCCATQpjaHH58IQggCSATQuf2J358IQkgCiATQq3zPH59IQogCyATQtGrCH58IQsgDCATQv3eKX59IQwgB0IBQhSGfEIVhyEfIAggH3whCCAHIB9CAUIVhn59IQcgCUIBQhSGfEIVhyEhIAogIXwhCiAJICFCAUIVhn59IQkgC0IBQhSGfEIVhyEjIAwgI3whDCALICNCAUIVhn59IQsgDUIBQhSGfEIVhyElIA4gJXwhDiANICVCAUIVhn59IQ0gD0IBQhSGfEIVhyEnIBAgJ3whECAPICdCAUIVhn59IQ8gEUIBQhSGfEIVhyEpIBIgKXwhEiARIClCAUIVhn59IREgCEIBQhSGfEIVhyEgIAkgIHwhCSAIICBCAUIVhn59IQggCkIBQhSGfEIVhyEiIAsgInwhCyAKICJCAUIVhn59IQogDEIBQhSGfEIVhyEkIA0gJHwhDSAMICRCAUIVhn59IQwgDkIBQhSGfEIVhyEmIA8gJnwhDyAOICZCAUIVhn59IQ4gEEIBQhSGfEIVhyEoIBEgKHwhESAQIChCAUIVhn59IRAgBiASQpPYKH58IQYgByASQpjaHH58IQcgCCASQuf2J358IQggCSASQq3zPH59IQkgCiASQtGrCH58IQogCyASQv3eKX59IQsgBSARQpPYKH58IQUgBiARQpjaHH58IQYgByARQuf2J358IQcgCCARQq3zPH59IQggCSARQtGrCH58IQkgCiARQv3eKX59IQogBCAQQpPYKH58IQQgBSAQQpjaHH58IQUgBiAQQuf2J358IQYgByAQQq3zPH59IQcgCCAQQtGrCH58IQggCSAQQv3eKX59IQkgAyAPQpPYKH58IQMgBCAPQpjaHH58IQQgBSAPQuf2J358IQUgBiAPQq3zPH59IQYgByAPQtGrCH58IQcgCCAPQv3eKX59IQggAiAOQpPYKH58IQIgAyAOQpjaHH58IQMgBCAOQuf2J358IQQgBSAOQq3zPH59IQUgBiAOQtGrCH58IQYgByAOQv3eKX59IQcgASANQpPYKH58IQEgAiANQpjaHH58IQIgAyANQuf2J358IQMgBCANQq3zPH59IQQgBSANQtGrCH58IQUgBiANQv3eKX59IQZCACENIAFCAUIUhnxCFYchGSACIBl8IQIgASAZQgFCFYZ+fSEBIANCAUIUhnxCFYchGyAEIBt8IQQgAyAbQgFCFYZ+fSEDIAVCAUIUhnxCFYchHSAGIB18IQYgBSAdQgFCFYZ+fSEFIAdCAUIUhnxCFYchHyAIIB98IQggByAfQgFCFYZ+fSEHIAlCAUIUhnxCFYchISAKICF8IQogCSAhQgFCFYZ+fSEJIAtCAUIUhnxCFYchIyAMICN8IQwgCyAjQgFCFYZ+fSELIAJCAUIUhnxCFYchGiADIBp8IQMgAiAaQgFCFYZ+fSECIARCAUIUhnxCFYchHCAFIBx8IQUgBCAcQgFCFYZ+fSEEIAZCAUIUhnxCFYchHiAHIB58IQcgBiAeQgFCFYZ+fSEGIAhCAUIUhnxCFYchICAJICB8IQkgCCAgQgFCFYZ+fSEIIApCAUIUhnxCFYchIiALICJ8IQsgCiAiQgFCFYZ+fSEKIAxCAUIUhnxCFYchJCANICR8IQ0gDCAkQgFCFYZ+fSEMIAEgDUKT2Ch+fCEBIAIgDUKY2hx+fCECIAMgDULn9id+fCEDIAQgDUKt8zx+fSEEIAUgDULRqwh+fCEFIAYgDUL93il+fSEGQgAhDSABQhWHIRkgAiAZfCECIAEgGUIBQhWGfn0hASACQhWHIRogAyAafCEDIAIgGkIBQhWGfn0hAiADQhWHIRsgBCAbfCEEIAMgG0IBQhWGfn0hAyAEQhWHIRwgBSAcfCEFIAQgHEIBQhWGfn0hBCAFQhWHIR0gBiAdfCEGIAUgHUIBQhWGfn0hBSAGQhWHIR4gByAefCEHIAYgHkIBQhWGfn0hBiAHQhWHIR8gCCAffCEIIAcgH0IBQhWGfn0hByAIQhWHISAgCSAgfCEJIAggIEIBQhWGfn0hCCAJQhWHISEgCiAhfCEKIAkgIUIBQhWGfn0hCSAKQhWHISIgCyAifCELIAogIkIBQhWGfn0hCiALQhWHISMgDCAjfCEMIAsgI0IBQhWGfn0hCyAMQhWHISQgDSAkfCENIAwgJEIBQhWGfn0hDCABIA1Ck9gofnwhASACIA1CmNocfnwhAiADIA1C5/YnfnwhAyAEIA1CrfM8fn0hBCAFIA1C0asIfnwhBSAGIA1C/d4pfn0hBiABQhWHIRkgAiAZfCECIAEgGUIBQhWGfn0hASACQhWHIRogAyAafCEDIAIgGkIBQhWGfn0hAiADQhWHIRsgBCAbfCEEIAMgG0IBQhWGfn0hAyAEQhWHIRwgBSAcfCEFIAQgHEIBQhWGfn0hBCAFQhWHIR0gBiAdfCEGIAUgHUIBQhWGfn0hBSAGQhWHIR4gByAefCEHIAYgHkIBQhWGfn0hBiAHQhWHIR8gCCAffCEIIAcgH0IBQhWGfn0hByAIQhWHISAgCSAgfCEJIAggIEIBQhWGfn0hCCAJQhWHISEgCiAhfCEKIAkgIUIBQhWGfn0hCSAKQhWHISIgCyAifCELIAogIkIBQhWGfn0hCiALQhWHISMgDCAjfCEMIAsgI0IBQhWGfn0hCyAAIAFC/wGDIAFCgP4Dg4QgASACQiB+QhCGhEKAgPwHg4QgAkIVhkKAgID4D4OEIAJCFYZCgICAgPAfg4QgAkIVhiADQgR+QiiGhEKAgICAgOA/g4QgA0IqhkKAgICAgIDA/wCDhCADQiqGIARCgAF+QjiGhEKAgICAgICAgH+DhDcDACAAIARCAYdC/wGDIARCAYdCgP4Dg4QgBEIBhyAFQhB+QhCGhEKAgPwHg4QgBUIUhkKAgID4D4OEIAVCFIZCgICAgPAfg4QgBUIUhiAGQgJ+QiiGhEKAgICAgOA/g4QgBkIphkKAgICAgIDA/wCDhCAGQimGIAdCwAB+QjiGhEKAgICAgICAgH+DhDcDCCAAIAdCAodC/wGDIAdCAodCgP4Dg4QgB0IChyAIQgh+QhCGhEKAgPwHg4QgCEIThkKAgID4D4OEIAhCE4ZCgICAgPAfg4QgCUIohkKAgICAgOA/g4QgCUIohkKAgICAgIDA/wCDhCAJQiiGIApCIH5COIaEQoCAgICAgICAf4OENwMQIAAgCkIDh0L/AYMgCkIDh0KA/gODhCAKQgOHIAtCBH5CEIaEQoCA/AeDhCALQhKGQoCAgPgPg4QgC0IShiAMQoABfkIghoRCgICAgPAfg4QgDEInhkKAgICAgOA/g4QgDEInhkKAgICAgIDA/wCDhCAMQieGQoCAgICAgICAf4OENwMYC34AIAAgADUCACAANQIEIAA1AgggADUCDCAANQIQIAA1AhQgADUCGCAANQIcIAA1AiAgADUCJCAANQIoIAA1AiwgADUCMCAANQI0IAA1AjggADUCPCAANQJAIAA1AkQgADUCSCAANQJMIAA1AlAgADUCVCAANQJYIAA1AlwQCQs=')
|
||||
var ready = null
|
||||
|
||||
var mod = {
|
||||
buffer: wasm,
|
||||
memory: null,
|
||||
exports: null,
|
||||
realloc: realloc,
|
||||
onload: onload
|
||||
}
|
||||
|
||||
onload(function () {})
|
||||
|
||||
return mod
|
||||
|
||||
function realloc (size) {
|
||||
mod.exports.memory.grow(Math.max(0, Math.ceil(Math.abs(size - mod.memory.length) / 65536)))
|
||||
mod.memory = new Uint8Array(mod.exports.memory.buffer)
|
||||
}
|
||||
|
||||
function onload (cb) {
|
||||
if (mod.exports) return cb()
|
||||
|
||||
if (ready) {
|
||||
ready.then(cb.bind(null, null)).catch(cb)
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
if (opts && opts.async) throw new Error('async')
|
||||
setup({instance: new WebAssembly.Instance(new WebAssembly.Module(wasm), imp)})
|
||||
} catch (err) {
|
||||
ready = WebAssembly.instantiate(wasm, imp).then(setup)
|
||||
}
|
||||
|
||||
onload(cb)
|
||||
}
|
||||
|
||||
function setup (w) {
|
||||
mod.exports = w.instance.exports
|
||||
mod.memory = mod.exports.memory && mod.exports.memory.buffer && new Uint8Array(mod.exports.memory.buffer)
|
||||
}
|
||||
}
|
||||
|
||||
function toUint8Array (s) {
|
||||
if (typeof atob === 'function') return new Uint8Array(atob(s).split('').map(charCodeAt))
|
||||
return (require('buf' + 'fer').Buffer).from(s, 'base64')
|
||||
}
|
||||
|
||||
function charCodeAt (c) {
|
||||
return c.charCodeAt(0)
|
||||
}
|
||||
@@ -0,0 +1,542 @@
|
||||
(module
|
||||
(import "js" "table" (table 1 anyfunc))
|
||||
(elem (i32.const 0) $sc_reduce)
|
||||
|
||||
(func $i32.log (import "debug" "log") (param i32))
|
||||
(func $i32.log_tee (import "debug" "log_tee") (param i32) (result i32))
|
||||
;; No i64 interop with JS yet - but maybe coming with WebAssembly BigInt
|
||||
;; So we can instead fake this by splitting the i64 into two i32 limbs,
|
||||
;; however these are WASM functions using i32x2.log:
|
||||
(func $i32x2.log (import "debug" "log") (param i32) (param i32))
|
||||
(func $f32.log (import "debug" "log") (param f32))
|
||||
(func $f32.log_tee (import "debug" "log_tee") (param f32) (result f32))
|
||||
(func $f64.log (import "debug" "log") (param f64))
|
||||
(func $f64.log_tee (import "debug" "log_tee") (param f64) (result f64))
|
||||
|
||||
;; i64 logging by splitting into two i32 limbs
|
||||
(func $i64.log
|
||||
(param $0 i64)
|
||||
(call $i32x2.log
|
||||
;; Upper limb
|
||||
(i32.wrap/i64
|
||||
(i64.shr_s (get_local $0)
|
||||
(i64.const 32)))
|
||||
;; Lower limb
|
||||
(i32.wrap/i64 (get_local $0))))
|
||||
|
||||
(func $i64.log_tee
|
||||
(param $0 i64)
|
||||
(result i64)
|
||||
(call $i64.log (get_local $0))
|
||||
(return (get_local $0)))
|
||||
|
||||
(memory $0 1)
|
||||
(export "memory" (memory $0))
|
||||
|
||||
(func $sc_reduce (export "sc_reduce")
|
||||
(param $s i32)
|
||||
|
||||
(param $s0 i64)
|
||||
(param $s1 i64)
|
||||
(param $s2 i64)
|
||||
(param $s3 i64)
|
||||
(param $s4 i64)
|
||||
(param $s5 i64)
|
||||
(param $s6 i64)
|
||||
(param $s7 i64)
|
||||
(param $s8 i64)
|
||||
(param $s9 i64)
|
||||
(param $s10 i64)
|
||||
(param $s11 i64)
|
||||
(param $s12 i64)
|
||||
(param $s13 i64)
|
||||
(param $s14 i64)
|
||||
(param $s15 i64)
|
||||
(param $s16 i64)
|
||||
(param $s17 i64)
|
||||
(param $s18 i64)
|
||||
(param $s19 i64)
|
||||
(param $s20 i64)
|
||||
(param $s21 i64)
|
||||
(param $s22 i64)
|
||||
(param $s23 i64)
|
||||
|
||||
(local $carry0 i64)
|
||||
(local $carry1 i64)
|
||||
(local $carry2 i64)
|
||||
(local $carry3 i64)
|
||||
(local $carry4 i64)
|
||||
(local $carry5 i64)
|
||||
(local $carry6 i64)
|
||||
(local $carry7 i64)
|
||||
(local $carry8 i64)
|
||||
(local $carry9 i64)
|
||||
(local $carry10 i64)
|
||||
(local $carry11 i64)
|
||||
(local $carry12 i64)
|
||||
(local $carry13 i64)
|
||||
(local $carry14 i64)
|
||||
(local $carry15 i64)
|
||||
(local $carry16 i64)
|
||||
|
||||
(set_local $s11 (i64.add (get_local $s11) (i64.mul (get_local $s23) (i64.const 666643))))
|
||||
(set_local $s12 (i64.add (get_local $s12) (i64.mul (get_local $s23) (i64.const 470296))))
|
||||
(set_local $s13 (i64.add (get_local $s13) (i64.mul (get_local $s23) (i64.const 654183))))
|
||||
(set_local $s14 (i64.sub (get_local $s14) (i64.mul (get_local $s23) (i64.const 997805))))
|
||||
(set_local $s15 (i64.add (get_local $s15) (i64.mul (get_local $s23) (i64.const 136657))))
|
||||
(set_local $s16 (i64.sub (get_local $s16) (i64.mul (get_local $s23) (i64.const 683901))))
|
||||
|
||||
(set_local $s10 (i64.add (get_local $s10) (i64.mul (get_local $s22) (i64.const 666643))))
|
||||
(set_local $s11 (i64.add (get_local $s11) (i64.mul (get_local $s22) (i64.const 470296))))
|
||||
(set_local $s12 (i64.add (get_local $s12) (i64.mul (get_local $s22) (i64.const 654183))))
|
||||
(set_local $s13 (i64.sub (get_local $s13) (i64.mul (get_local $s22) (i64.const 997805))))
|
||||
(set_local $s14 (i64.add (get_local $s14) (i64.mul (get_local $s22) (i64.const 136657))))
|
||||
(set_local $s15 (i64.sub (get_local $s15) (i64.mul (get_local $s22) (i64.const 683901))))
|
||||
|
||||
(set_local $s9 (i64.add (get_local $s9 ) (i64.mul (get_local $s21) (i64.const 666643))))
|
||||
(set_local $s10 (i64.add (get_local $s10) (i64.mul (get_local $s21) (i64.const 470296))))
|
||||
(set_local $s11 (i64.add (get_local $s11) (i64.mul (get_local $s21) (i64.const 654183))))
|
||||
(set_local $s12 (i64.sub (get_local $s12) (i64.mul (get_local $s21) (i64.const 997805))))
|
||||
(set_local $s13 (i64.add (get_local $s13) (i64.mul (get_local $s21) (i64.const 136657))))
|
||||
(set_local $s14 (i64.sub (get_local $s14) (i64.mul (get_local $s21) (i64.const 683901))))
|
||||
|
||||
(set_local $s8 (i64.add (get_local $s8 ) (i64.mul (get_local $s20) (i64.const 666643))))
|
||||
(set_local $s9 (i64.add (get_local $s9 ) (i64.mul (get_local $s20) (i64.const 470296))))
|
||||
(set_local $s10 (i64.add (get_local $s10) (i64.mul (get_local $s20) (i64.const 654183))))
|
||||
(set_local $s11 (i64.sub (get_local $s11) (i64.mul (get_local $s20) (i64.const 997805))))
|
||||
(set_local $s12 (i64.add (get_local $s12) (i64.mul (get_local $s20) (i64.const 136657))))
|
||||
(set_local $s13 (i64.sub (get_local $s13) (i64.mul (get_local $s20) (i64.const 683901))))
|
||||
|
||||
(set_local $s7 (i64.add (get_local $s7 ) (i64.mul (get_local $s19) (i64.const 666643))))
|
||||
(set_local $s8 (i64.add (get_local $s8 ) (i64.mul (get_local $s19) (i64.const 470296))))
|
||||
(set_local $s9 (i64.add (get_local $s9 ) (i64.mul (get_local $s19) (i64.const 654183))))
|
||||
(set_local $s10 (i64.sub (get_local $s10) (i64.mul (get_local $s19) (i64.const 997805))))
|
||||
(set_local $s11 (i64.add (get_local $s11) (i64.mul (get_local $s19) (i64.const 136657))))
|
||||
(set_local $s12 (i64.sub (get_local $s12) (i64.mul (get_local $s19) (i64.const 683901))))
|
||||
|
||||
(set_local $s6 (i64.add (get_local $s6 ) (i64.mul (get_local $s18) (i64.const 666643))))
|
||||
(set_local $s7 (i64.add (get_local $s7 ) (i64.mul (get_local $s18) (i64.const 470296))))
|
||||
(set_local $s8 (i64.add (get_local $s8 ) (i64.mul (get_local $s18) (i64.const 654183))))
|
||||
(set_local $s9 (i64.sub (get_local $s9 ) (i64.mul (get_local $s18) (i64.const 997805))))
|
||||
(set_local $s10 (i64.add (get_local $s10) (i64.mul (get_local $s18) (i64.const 136657))))
|
||||
(set_local $s11 (i64.sub (get_local $s11) (i64.mul (get_local $s18) (i64.const 683901))))
|
||||
|
||||
(set_local $carry6 (i64.shr_s (i64.add (get_local $s6) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s7 (i64.add (get_local $s7) (get_local $carry6)))
|
||||
(set_local $s6 (i64.sub (get_local $s6) (i64.mul (get_local $carry6) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry8 (i64.shr_s (i64.add (get_local $s8) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s9 (i64.add (get_local $s9) (get_local $carry8)))
|
||||
(set_local $s8 (i64.sub (get_local $s8) (i64.mul (get_local $carry8) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry10 (i64.shr_s (i64.add (get_local $s10) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s11 (i64.add (get_local $s11) (get_local $carry10)))
|
||||
(set_local $s10 (i64.sub (get_local $s10) (i64.mul (get_local $carry10) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry12 (i64.shr_s (i64.add (get_local $s12) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s13 (i64.add (get_local $s13) (get_local $carry12)))
|
||||
(set_local $s12 (i64.sub (get_local $s12) (i64.mul (get_local $carry12) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry14 (i64.shr_s (i64.add (get_local $s14) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s15 (i64.add (get_local $s15) (get_local $carry14)))
|
||||
(set_local $s14 (i64.sub (get_local $s14) (i64.mul (get_local $carry14) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry16 (i64.shr_s (i64.add (get_local $s16) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s17 (i64.add (get_local $s17) (get_local $carry16)))
|
||||
(set_local $s16 (i64.sub (get_local $s16) (i64.mul (get_local $carry16) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry7 (i64.shr_s (i64.add (get_local $s7) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s8 (i64.add (get_local $s8) (get_local $carry7)))
|
||||
(set_local $s7 (i64.sub (get_local $s7) (i64.mul (get_local $carry7) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry9 (i64.shr_s (i64.add (get_local $s9) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s10 (i64.add (get_local $s10) (get_local $carry9)))
|
||||
(set_local $s9 (i64.sub (get_local $s9) (i64.mul (get_local $carry9) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry11 (i64.shr_s (i64.add (get_local $s11) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s12 (i64.add (get_local $s12) (get_local $carry11)))
|
||||
(set_local $s11 (i64.sub (get_local $s11) (i64.mul (get_local $carry11) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry13 (i64.shr_s (i64.add (get_local $s13) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s14 (i64.add (get_local $s14) (get_local $carry13)))
|
||||
(set_local $s13 (i64.sub (get_local $s13) (i64.mul (get_local $carry13) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry15 (i64.shr_s (i64.add (get_local $s15) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s16 (i64.add (get_local $s16) (get_local $carry15)))
|
||||
(set_local $s15 (i64.sub (get_local $s15) (i64.mul (get_local $carry15) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $s5 (i64.add (get_local $s5 ) (i64.mul (get_local $s17) (i64.const 666643))))
|
||||
(set_local $s6 (i64.add (get_local $s6 ) (i64.mul (get_local $s17) (i64.const 470296))))
|
||||
(set_local $s7 (i64.add (get_local $s7 ) (i64.mul (get_local $s17) (i64.const 654183))))
|
||||
(set_local $s8 (i64.sub (get_local $s8 ) (i64.mul (get_local $s17) (i64.const 997805))))
|
||||
(set_local $s9 (i64.add (get_local $s9 ) (i64.mul (get_local $s17) (i64.const 136657))))
|
||||
(set_local $s10 (i64.sub (get_local $s10) (i64.mul (get_local $s17) (i64.const 683901))))
|
||||
|
||||
(set_local $s4 (i64.add (get_local $s4) (i64.mul (get_local $s16) (i64.const 666643))))
|
||||
(set_local $s5 (i64.add (get_local $s5) (i64.mul (get_local $s16) (i64.const 470296))))
|
||||
(set_local $s6 (i64.add (get_local $s6) (i64.mul (get_local $s16) (i64.const 654183))))
|
||||
(set_local $s7 (i64.sub (get_local $s7) (i64.mul (get_local $s16) (i64.const 997805))))
|
||||
(set_local $s8 (i64.add (get_local $s8) (i64.mul (get_local $s16) (i64.const 136657))))
|
||||
(set_local $s9 (i64.sub (get_local $s9) (i64.mul (get_local $s16) (i64.const 683901))))
|
||||
|
||||
(set_local $s3 (i64.add (get_local $s3) (i64.mul (get_local $s15) (i64.const 666643))))
|
||||
(set_local $s4 (i64.add (get_local $s4) (i64.mul (get_local $s15) (i64.const 470296))))
|
||||
(set_local $s5 (i64.add (get_local $s5) (i64.mul (get_local $s15) (i64.const 654183))))
|
||||
(set_local $s6 (i64.sub (get_local $s6) (i64.mul (get_local $s15) (i64.const 997805))))
|
||||
(set_local $s7 (i64.add (get_local $s7) (i64.mul (get_local $s15) (i64.const 136657))))
|
||||
(set_local $s8 (i64.sub (get_local $s8) (i64.mul (get_local $s15) (i64.const 683901))))
|
||||
|
||||
(set_local $s2 (i64.add (get_local $s2) (i64.mul (get_local $s14) (i64.const 666643))))
|
||||
(set_local $s3 (i64.add (get_local $s3) (i64.mul (get_local $s14) (i64.const 470296))))
|
||||
(set_local $s4 (i64.add (get_local $s4) (i64.mul (get_local $s14) (i64.const 654183))))
|
||||
(set_local $s5 (i64.sub (get_local $s5) (i64.mul (get_local $s14) (i64.const 997805))))
|
||||
(set_local $s6 (i64.add (get_local $s6) (i64.mul (get_local $s14) (i64.const 136657))))
|
||||
(set_local $s7 (i64.sub (get_local $s7) (i64.mul (get_local $s14) (i64.const 683901))))
|
||||
|
||||
(set_local $s1 (i64.add (get_local $s1) (i64.mul (get_local $s13) (i64.const 666643))))
|
||||
(set_local $s2 (i64.add (get_local $s2) (i64.mul (get_local $s13) (i64.const 470296))))
|
||||
(set_local $s3 (i64.add (get_local $s3) (i64.mul (get_local $s13) (i64.const 654183))))
|
||||
(set_local $s4 (i64.sub (get_local $s4) (i64.mul (get_local $s13) (i64.const 997805))))
|
||||
(set_local $s5 (i64.add (get_local $s5) (i64.mul (get_local $s13) (i64.const 136657))))
|
||||
(set_local $s6 (i64.sub (get_local $s6) (i64.mul (get_local $s13) (i64.const 683901))))
|
||||
|
||||
(set_local $s0 (i64.add (get_local $s0) (i64.mul (get_local $s12) (i64.const 666643))))
|
||||
(set_local $s1 (i64.add (get_local $s1) (i64.mul (get_local $s12) (i64.const 470296))))
|
||||
(set_local $s2 (i64.add (get_local $s2) (i64.mul (get_local $s12) (i64.const 654183))))
|
||||
(set_local $s3 (i64.sub (get_local $s3) (i64.mul (get_local $s12) (i64.const 997805))))
|
||||
(set_local $s4 (i64.add (get_local $s4) (i64.mul (get_local $s12) (i64.const 136657))))
|
||||
(set_local $s5 (i64.sub (get_local $s5) (i64.mul (get_local $s12) (i64.const 683901))))
|
||||
(set_local $s12 (i64.const 0))
|
||||
|
||||
(set_local $carry0 (i64.shr_s (i64.add (get_local $s0) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s1 (i64.add (get_local $s1) (get_local $carry0)))
|
||||
(set_local $s0 (i64.sub (get_local $s0) (i64.mul (get_local $carry0) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry2 (i64.shr_s (i64.add (get_local $s2) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s3 (i64.add (get_local $s3) (get_local $carry2)))
|
||||
(set_local $s2 (i64.sub (get_local $s2) (i64.mul (get_local $carry2) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry4 (i64.shr_s (i64.add (get_local $s4) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s5 (i64.add (get_local $s5) (get_local $carry4)))
|
||||
(set_local $s4 (i64.sub (get_local $s4) (i64.mul (get_local $carry4) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry6 (i64.shr_s (i64.add (get_local $s6) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s7 (i64.add (get_local $s7) (get_local $carry6)))
|
||||
(set_local $s6 (i64.sub (get_local $s6) (i64.mul (get_local $carry6) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry8 (i64.shr_s (i64.add (get_local $s8) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s9 (i64.add (get_local $s9) (get_local $carry8)))
|
||||
(set_local $s8 (i64.sub (get_local $s8) (i64.mul (get_local $carry8) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry10 (i64.shr_s (i64.add (get_local $s10) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s11 (i64.add (get_local $s11) (get_local $carry10)))
|
||||
(set_local $s10 (i64.sub (get_local $s10) (i64.mul (get_local $carry10) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry1 (i64.shr_s (i64.add (get_local $s1) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s2 (i64.add (get_local $s2) (get_local $carry1)))
|
||||
(set_local $s1 (i64.sub (get_local $s1) (i64.mul (get_local $carry1) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry3 (i64.shr_s (i64.add (get_local $s3) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s4 (i64.add (get_local $s4) (get_local $carry3)))
|
||||
(set_local $s3 (i64.sub (get_local $s3) (i64.mul (get_local $carry3) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry5 (i64.shr_s (i64.add (get_local $s5) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s6 (i64.add (get_local $s6) (get_local $carry5)))
|
||||
(set_local $s5 (i64.sub (get_local $s5) (i64.mul (get_local $carry5) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry7 (i64.shr_s (i64.add (get_local $s7) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s8 (i64.add (get_local $s8) (get_local $carry7)))
|
||||
(set_local $s7 (i64.sub (get_local $s7) (i64.mul (get_local $carry7) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry9 (i64.shr_s (i64.add (get_local $s9) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s10 (i64.add (get_local $s10) (get_local $carry9)))
|
||||
(set_local $s9 (i64.sub (get_local $s9) (i64.mul (get_local $carry9) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry11 (i64.shr_s (i64.add (get_local $s11) (i64.shl (i64.const 1) (i64.const 20))) (i64.const 21)))
|
||||
(set_local $s12 (i64.add (get_local $s12) (get_local $carry11)))
|
||||
(set_local $s11 (i64.sub (get_local $s11) (i64.mul (get_local $carry11) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $s0 (i64.add (get_local $s0) (i64.mul (get_local $s12) (i64.const 666643))))
|
||||
(set_local $s1 (i64.add (get_local $s1) (i64.mul (get_local $s12) (i64.const 470296))))
|
||||
(set_local $s2 (i64.add (get_local $s2) (i64.mul (get_local $s12) (i64.const 654183))))
|
||||
(set_local $s3 (i64.sub (get_local $s3) (i64.mul (get_local $s12) (i64.const 997805))))
|
||||
(set_local $s4 (i64.add (get_local $s4) (i64.mul (get_local $s12) (i64.const 136657))))
|
||||
(set_local $s5 (i64.sub (get_local $s5) (i64.mul (get_local $s12) (i64.const 683901))))
|
||||
(set_local $s12 (i64.const 0))
|
||||
|
||||
(set_local $carry0 (i64.shr_s (get_local $s0) (i64.const 21)))
|
||||
(set_local $s1 (i64.add (get_local $s1) (get_local $carry0)))
|
||||
(set_local $s0 (i64.sub (get_local $s0) (i64.mul (get_local $carry0) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry1 (i64.shr_s (get_local $s1) (i64.const 21)))
|
||||
(set_local $s2 (i64.add (get_local $s2) (get_local $carry1)))
|
||||
(set_local $s1 (i64.sub (get_local $s1) (i64.mul (get_local $carry1) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry2 (i64.shr_s (get_local $s2) (i64.const 21)))
|
||||
(set_local $s3 (i64.add (get_local $s3) (get_local $carry2)))
|
||||
(set_local $s2 (i64.sub (get_local $s2) (i64.mul (get_local $carry2) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry3 (i64.shr_s (get_local $s3) (i64.const 21)))
|
||||
(set_local $s4 (i64.add (get_local $s4) (get_local $carry3)))
|
||||
(set_local $s3 (i64.sub (get_local $s3) (i64.mul (get_local $carry3) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry4 (i64.shr_s (get_local $s4) (i64.const 21)))
|
||||
(set_local $s5 (i64.add (get_local $s5) (get_local $carry4)))
|
||||
(set_local $s4 (i64.sub (get_local $s4) (i64.mul (get_local $carry4) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry5 (i64.shr_s (get_local $s5) (i64.const 21)))
|
||||
(set_local $s6 (i64.add (get_local $s6) (get_local $carry5)))
|
||||
(set_local $s5 (i64.sub (get_local $s5) (i64.mul (get_local $carry5) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry6 (i64.shr_s (get_local $s6) (i64.const 21)))
|
||||
(set_local $s7 (i64.add (get_local $s7) (get_local $carry6)))
|
||||
(set_local $s6 (i64.sub (get_local $s6) (i64.mul (get_local $carry6) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry7 (i64.shr_s (get_local $s7) (i64.const 21)))
|
||||
(set_local $s8 (i64.add (get_local $s8) (get_local $carry7)))
|
||||
(set_local $s7 (i64.sub (get_local $s7) (i64.mul (get_local $carry7) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry8 (i64.shr_s (get_local $s8) (i64.const 21)))
|
||||
(set_local $s9 (i64.add (get_local $s9) (get_local $carry8)))
|
||||
(set_local $s8 (i64.sub (get_local $s8) (i64.mul (get_local $carry8) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry9 (i64.shr_s (get_local $s9) (i64.const 21)))
|
||||
(set_local $s10 (i64.add (get_local $s10) (get_local $carry9)))
|
||||
(set_local $s9 (i64.sub (get_local $s9) (i64.mul (get_local $carry9) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry10 (i64.shr_s (get_local $s10) (i64.const 21)))
|
||||
(set_local $s11 (i64.add (get_local $s11) (get_local $carry10)))
|
||||
(set_local $s10 (i64.sub (get_local $s10) (i64.mul (get_local $carry10) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry11 (i64.shr_s (get_local $s11) (i64.const 21)))
|
||||
(set_local $s12 (i64.add (get_local $s12) (get_local $carry11)))
|
||||
(set_local $s11 (i64.sub (get_local $s11) (i64.mul (get_local $carry11) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $s0 (i64.add (get_local $s0) (i64.mul (get_local $s12) (i64.const 666643))))
|
||||
(set_local $s1 (i64.add (get_local $s1) (i64.mul (get_local $s12) (i64.const 470296))))
|
||||
(set_local $s2 (i64.add (get_local $s2) (i64.mul (get_local $s12) (i64.const 654183))))
|
||||
(set_local $s3 (i64.sub (get_local $s3) (i64.mul (get_local $s12) (i64.const 997805))))
|
||||
(set_local $s4 (i64.add (get_local $s4) (i64.mul (get_local $s12) (i64.const 136657))))
|
||||
(set_local $s5 (i64.sub (get_local $s5) (i64.mul (get_local $s12) (i64.const 683901))))
|
||||
|
||||
(set_local $carry0 (i64.shr_s (get_local $s0) (i64.const 21)))
|
||||
(set_local $s1 (i64.add (get_local $s1) (get_local $carry0)))
|
||||
(set_local $s0 (i64.sub (get_local $s0) (i64.mul (get_local $carry0) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry1 (i64.shr_s (get_local $s1) (i64.const 21)))
|
||||
(set_local $s2 (i64.add (get_local $s2) (get_local $carry1)))
|
||||
(set_local $s1 (i64.sub (get_local $s1) (i64.mul (get_local $carry1) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry2 (i64.shr_s (get_local $s2) (i64.const 21)))
|
||||
(set_local $s3 (i64.add (get_local $s3) (get_local $carry2)))
|
||||
(set_local $s2 (i64.sub (get_local $s2) (i64.mul (get_local $carry2) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry3 (i64.shr_s (get_local $s3) (i64.const 21)))
|
||||
(set_local $s4 (i64.add (get_local $s4) (get_local $carry3)))
|
||||
(set_local $s3 (i64.sub (get_local $s3) (i64.mul (get_local $carry3) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry4 (i64.shr_s (get_local $s4) (i64.const 21)))
|
||||
(set_local $s5 (i64.add (get_local $s5) (get_local $carry4)))
|
||||
(set_local $s4 (i64.sub (get_local $s4) (i64.mul (get_local $carry4) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry5 (i64.shr_s (get_local $s5) (i64.const 21)))
|
||||
(set_local $s6 (i64.add (get_local $s6) (get_local $carry5)))
|
||||
(set_local $s5 (i64.sub (get_local $s5) (i64.mul (get_local $carry5) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry6 (i64.shr_s (get_local $s6) (i64.const 21)))
|
||||
(set_local $s7 (i64.add (get_local $s7) (get_local $carry6)))
|
||||
(set_local $s6 (i64.sub (get_local $s6) (i64.mul (get_local $carry6) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry7 (i64.shr_s (get_local $s7) (i64.const 21)))
|
||||
(set_local $s8 (i64.add (get_local $s8) (get_local $carry7)))
|
||||
(set_local $s7 (i64.sub (get_local $s7) (i64.mul (get_local $carry7) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry8 (i64.shr_s (get_local $s8) (i64.const 21)))
|
||||
(set_local $s9 (i64.add (get_local $s9) (get_local $carry8)))
|
||||
(set_local $s8 (i64.sub (get_local $s8) (i64.mul (get_local $carry8) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry9 (i64.shr_s (get_local $s9) (i64.const 21)))
|
||||
(set_local $s10 (i64.add (get_local $s10) (get_local $carry9)))
|
||||
(set_local $s9 (i64.sub (get_local $s9) (i64.mul (get_local $carry9) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(set_local $carry10 (i64.shr_s (get_local $s10) (i64.const 21)))
|
||||
(set_local $s11 (i64.add (get_local $s11) (get_local $carry10)))
|
||||
(set_local $s10 (i64.sub (get_local $s10) (i64.mul (get_local $carry10) (i64.shl (i64.const 1) (i64.const 21)))))
|
||||
|
||||
(get_local $s)
|
||||
|
||||
(i64.and (get_local $s0) (i64.const 0xff))
|
||||
(i64.and (get_local $s0) (i64.const 0xff00))
|
||||
(i64.or)
|
||||
(get_local $s0)
|
||||
(i64.shl (i64.mul (get_local $s1) (i64.const 32)) (i64.const 16))
|
||||
(i64.or)
|
||||
(i64.const 0xff0000)
|
||||
(i64.and)
|
||||
(i64.or)
|
||||
(i64.shl (get_local $s1) (i64.const 21))
|
||||
(i64.const 0xff000000)
|
||||
(i64.and)
|
||||
(i64.or)
|
||||
(i64.shl (get_local $s1) (i64.const 21))
|
||||
(i64.const 0xff00000000)
|
||||
(i64.and)
|
||||
(i64.or)
|
||||
(i64.shl (get_local $s1) (i64.const 21))
|
||||
(i64.shl (i64.mul (get_local $s2) (i64.const 4)) (i64.const 40))
|
||||
(i64.or)
|
||||
(i64.const 0xff0000000000)
|
||||
(i64.and)
|
||||
(i64.or)
|
||||
(i64.shl (get_local $s2) (i64.const 42))
|
||||
(i64.const 0xff000000000000)
|
||||
(i64.and)
|
||||
(i64.or)
|
||||
(i64.shl (get_local $s2) (i64.const 42))
|
||||
(i64.shl (i64.mul (get_local $s3) (i64.const 128)) (i64.const 56))
|
||||
(i64.or)
|
||||
(i64.const 0xff00000000000000)
|
||||
(i64.and)
|
||||
(i64.or)
|
||||
|
||||
(i64.store offset=0)
|
||||
|
||||
(get_local $s)
|
||||
|
||||
(i64.and (i64.shr_s (get_local $s3) (i64.const 1)) (i64.const 0xff))
|
||||
(i64.and (i64.shr_s (get_local $s3) (i64.const 1)) (i64.const 0xff00))
|
||||
(i64.or)
|
||||
(i64.shr_s (get_local $s3) (i64.const 1))
|
||||
(i64.shl (i64.mul (get_local $s4) (i64.const 16)) (i64.const 16))
|
||||
(i64.or)
|
||||
(i64.const 0xff0000)
|
||||
(i64.and)
|
||||
(i64.or)
|
||||
(i64.shl (get_local $s4) (i64.const 20))
|
||||
(i64.const 0xff000000)
|
||||
(i64.and)
|
||||
(i64.or)
|
||||
(i64.shl (get_local $s4) (i64.const 20))
|
||||
(i64.const 0xff00000000)
|
||||
(i64.and)
|
||||
(i64.or)
|
||||
(i64.shl (get_local $s4) (i64.const 20))
|
||||
(i64.shl (i64.mul (get_local $s5) (i64.const 2)) (i64.const 40))
|
||||
(i64.or)
|
||||
(i64.const 0xff0000000000)
|
||||
(i64.and)
|
||||
(i64.or)
|
||||
(i64.shl (get_local $s5) (i64.const 41))
|
||||
(i64.const 0xff000000000000)
|
||||
(i64.and)
|
||||
(i64.or)
|
||||
(i64.shl (get_local $s5) (i64.const 41))
|
||||
(i64.shl (i64.mul (get_local $s6) (i64.const 64)) (i64.const 56))
|
||||
(i64.or)
|
||||
(i64.const 0xff00000000000000)
|
||||
(i64.and)
|
||||
(i64.or)
|
||||
|
||||
(i64.store offset=8)
|
||||
|
||||
(get_local $s)
|
||||
|
||||
(i64.and (i64.shr_s (get_local $s6) (i64.const 2)) (i64.const 0xff))
|
||||
(i64.and (i64.shr_s (get_local $s6) (i64.const 2)) (i64.const 0xff00))
|
||||
(i64.or)
|
||||
(i64.shr_s (get_local $s6) (i64.const 2))
|
||||
(i64.shl (i64.mul (get_local $s7) (i64.const 8)) (i64.const 16))
|
||||
(i64.or)
|
||||
(i64.const 0xff0000)
|
||||
(i64.and)
|
||||
(i64.or)
|
||||
(i64.shl (get_local $s7) (i64.const 19))
|
||||
(i64.const 0xff000000)
|
||||
(i64.and)
|
||||
(i64.or)
|
||||
(i64.shl (get_local $s7) (i64.const 19))
|
||||
(i64.const 0xff00000000)
|
||||
(i64.and)
|
||||
(i64.or)
|
||||
(i64.shl (get_local $s8) (i64.const 40))
|
||||
(i64.const 0xff0000000000)
|
||||
(i64.and)
|
||||
(i64.or)
|
||||
(i64.shl (get_local $s8) (i64.const 40))
|
||||
(i64.const 0xff000000000000)
|
||||
(i64.and)
|
||||
(i64.or)
|
||||
(i64.shl (get_local $s8) (i64.const 40))
|
||||
(i64.shl (i64.mul (get_local $s9) (i64.const 32)) (i64.const 56))
|
||||
(i64.or)
|
||||
(i64.const 0xff00000000000000)
|
||||
(i64.and)
|
||||
(i64.or)
|
||||
|
||||
(i64.store offset=16)
|
||||
|
||||
(get_local $s)
|
||||
|
||||
(i64.and (i64.shr_s (get_local $s9) (i64.const 3)) (i64.const 0xff))
|
||||
(i64.and (i64.shr_s (get_local $s9) (i64.const 3)) (i64.const 0xff00))
|
||||
(i64.or)
|
||||
(i64.shr_s (get_local $s9) (i64.const 3))
|
||||
(i64.shl (i64.mul (get_local $s10) (i64.const 4)) (i64.const 16))
|
||||
(i64.or)
|
||||
(i64.const 0xff0000)
|
||||
(i64.and)
|
||||
(i64.or)
|
||||
(i64.shl (get_local $s10) (i64.const 18))
|
||||
(i64.const 0xff000000)
|
||||
(i64.and)
|
||||
(i64.or)
|
||||
(i64.shl (get_local $s10) (i64.const 18))
|
||||
(i64.shl (i64.mul (get_local $s11) (i64.const 128)) (i64.const 32))
|
||||
(i64.or)
|
||||
(i64.const 0xff00000000)
|
||||
(i64.and)
|
||||
(i64.or)
|
||||
(i64.shl (get_local $s11) (i64.const 39))
|
||||
(i64.const 0xff0000000000)
|
||||
(i64.and)
|
||||
(i64.or)
|
||||
(i64.shl (get_local $s11) (i64.const 39))
|
||||
(i64.const 0xff000000000000)
|
||||
(i64.and)
|
||||
(i64.or)
|
||||
(i64.shl (get_local $s11) (i64.const 39))
|
||||
(i64.const 0xff00000000000000)
|
||||
(i64.and)
|
||||
(i64.or)
|
||||
|
||||
(i64.store offset=24))
|
||||
|
||||
(func $sc25519_reduce (export "sc25519_reduce") (param $s i32)
|
||||
(get_local $s)
|
||||
(i64.load32_u offset=0 (get_local $s))
|
||||
(i64.load32_u offset=4 (get_local $s))
|
||||
(i64.load32_u offset=8 (get_local $s))
|
||||
(i64.load32_u offset=12 (get_local $s))
|
||||
(i64.load32_u offset=16 (get_local $s))
|
||||
(i64.load32_u offset=20 (get_local $s))
|
||||
(i64.load32_u offset=24 (get_local $s))
|
||||
(i64.load32_u offset=28 (get_local $s))
|
||||
(i64.load32_u offset=32 (get_local $s))
|
||||
(i64.load32_u offset=36 (get_local $s))
|
||||
(i64.load32_u offset=40 (get_local $s))
|
||||
(i64.load32_u offset=44 (get_local $s))
|
||||
(i64.load32_u offset=48 (get_local $s))
|
||||
(i64.load32_u offset=52 (get_local $s))
|
||||
(i64.load32_u offset=56 (get_local $s))
|
||||
(i64.load32_u offset=60 (get_local $s))
|
||||
(i64.load32_u offset=64 (get_local $s))
|
||||
(i64.load32_u offset=68 (get_local $s))
|
||||
(i64.load32_u offset=72 (get_local $s))
|
||||
(i64.load32_u offset=76 (get_local $s))
|
||||
(i64.load32_u offset=80 (get_local $s))
|
||||
(i64.load32_u offset=84 (get_local $s))
|
||||
(i64.load32_u offset=88 (get_local $s))
|
||||
(i64.load32_u offset=92 (get_local $s))
|
||||
(call $sc_reduce)))
|
||||
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
|
||||
module.exports = loadWebAssembly
|
||||
|
||||
loadWebAssembly.supported = typeof WebAssembly !== 'undefined'
|
||||
|
||||
function loadWebAssembly (opts) {
|
||||
if (!loadWebAssembly.supported) return null
|
||||
|
||||
var imp = opts && opts.imports
|
||||
var wasm = toUint8Array('AGFzbQEAAAABZg1gFX5+fn5+fn5+fn5+fn5+fn5+fn5+fwBgDX5+fn5+fn5+fn5/f38AYAt+fn5+fn5+fn5+fwBgAX8AYAF/AX9gAn9/AGABfQBgAX0BfWABfABgAXwBfGABfgBgAX4BfmADf39/AAJ4CQJqcwV0YWJsZQFwAAMCanMDbWVtAgABBWRlYnVnA2xvZwADBWRlYnVnB2xvZ190ZWUABAVkZWJ1ZwNsb2cABQVkZWJ1ZwNsb2cABgVkZWJ1Zwdsb2dfdGVlAAcFZGVidWcDbG9nAAgFZGVidWcHbG9nX3RlZQAJAwQDCgsMBw4BCnNjYWxhcm11bHQACQqLGQMNACAAQiCHpyAApxACCwkAIAAQByAADwvwGAIHf0x+QZADIQZBuAMhB0HgAyEIQYgEIQkgAikDACEMIAIpAwghDSACKQMQIQ4gAikDGCEPIAE1AgAhECABNQIEIREgATUCCCESIAE1AgwhEyABNQIQIRQgATUCFCEVIAE1AhghFiABNQIcIRcgATUCICEYIAE1AiQhGUIBIRpCACEbQgAhHEIAIR1CACEeQgAhH0IAISBCACEhQgAhIkIAISMgATUCACEuIAE1AgQhLyABNQIIITAgATUCDCExIAE1AhAhMiABNQIUITMgATUCGCE0IAE1AhwhNSABNQIgITYgATUCJCE3QgAhJEIAISVCACEmQgAhJ0IAIShCACEpQgAhKkIAIStCACEsQgAhLUIBIThCACE5QgAhOkIAITtCACE8QgAhPUIAIT5CACE/QgAhQEIAIUFB/gEhBQJAA0AgBUEASA0BAkACQAJAAkACQAJAIAVBwABuDgMEAwIBCwsgDyELDAMLIA4hCwwCCyANIQsMAQsgDCELCyALIAVBCG5BCHBBCGytiEL/AYMgBUEHca2IQgGDpyEEIAMgBHMhA0EAIANrrSEKIBogLoUgCoMhQiAbIC+FIAqDIUMgHCAwhSAKgyFEIB0gMYUgCoMhRSAeIDKFIAqDIUYgHyAzhSAKgyFHICAgNIUgCoMhSCAhIDWFIAqDIUkgIiA2hSAKgyFKICMgN4UgCoMhSyAaIEKFIRogGyBDhSEbIBwgRIUhHCAdIEWFIR0gHiBGhSEeIB8gR4UhHyAgIEiFISAgISBJhSEhICIgSoUhIiAjIEuFISMgLiBChSEuIC8gQ4UhLyAwIESFITAgMSBFhSExIDIgRoUhMiAzIEeFITMgNCBIhSE0IDUgSYUhNSA2IEqFITYgNyBLhSE3IDggJIUgCoMhQiA5ICWFIAqDIUMgOiAmhSAKgyFEIDsgJ4UgCoMhRSA8ICiFIAqDIUYgPSAphSAKgyFHID4gKoUgCoMhSCA/ICuFIAqDIUkgQCAshSAKgyFKIEEgLYUgCoMhSyAkIEKFISQgJSBDhSElICYgRIUhJiAnIEWFIScgKCBGhSEoICkgR4UhKSAqIEiFISogKyBJhSErICwgSoUhLCAtIEuFIS0gOCBChSE4IDkgQ4UhOSA6IESFITogOyBFhSE7IDwgRoUhPCA9IEeFIT0gPiBIhSE+ID8gSYUhPyBAIEqFIUAgQSBLhSFBIAQhAyAuIDh9IUIgLyA5fSFDIDAgOn0hRCAxIDt9IUUgMiA8fSFGIDMgPX0hRyA0ID59IUggNSA/fSFJIDYgQH0hSiA3IEF9IUsgGiAkfSFMIBsgJX0hTSAcICZ9IU4gHSAnfSFPIB4gKH0hUCAfICl9IVEgICAqfSFSICEgK30hUyAiICx9IVQgIyAtfSFVIBogJHwhGiAbICV8IRsgHCAmfCEcIB0gJ3whHSAeICh8IR4gHyApfCEfICAgKnwhICAhICt8ISEgIiAsfCEiICMgLXwhIyAuIDh8ISQgLyA5fCElIDAgOnwhJiAxIDt8IScgMiA8fCEoIDMgPXwhKSA0ID58ISogNSA/fCErIDYgQHwhLCA3IEF8IS0gGiAbIBwgHSAeIB8gICAhICIgIyBCIEMgRCBFIEYgRyBIIEkgSiBLIAZBAREAACBMIE0gTiBPIFAgUSBSIFMgVCBVICQgJSAmICcgKCApICogKyAsIC0gB0EBEQAAIEwgTSBOIE8gUCBRIFIgUyBUIFVBAEEAIAhBAhEBACAaIBsgHCAdIB4gHyAgICEgIiAjQQBBACAJQQIRAQAgBjUCACE4IAY1AgQhOSAGNQIIITogBjUCDCE7IAY1AhAhPCAGNQIUIT0gBjUCGCE+IAY1AhwhPyAGNQIgIUAgBjUCJCFBIAc1AgAhJCAHNQIEISUgBzUCCCEmIAc1AgwhJyAHNQIQISggBzUCFCEpIAc1AhghKiAHNQIcISsgBzUCICEsIAc1AiQhLSAINQIAIUIgCDUCBCFDIAg1AgghRCAINQIMIUUgCDUCECFGIAg1AhQhRyAINQIYIUggCDUCHCFJIAg1AiAhSiAINQIkIUsgCTUCACFMIAk1AgQhTSAJNQIIIU4gCTUCDCFPIAk1AhAhUCAJNQIUIVEgCTUCGCFSIAk1AhwhUyAJNQIgIVQgCTUCJCFVIDggJHwhLiA5ICV8IS8gOiAmfCEwIDsgJ3whMSA8ICh8ITIgPSApfCEzID4gKnwhNCA/ICt8ITUgQCAsfCE2IEEgLXwhNyA4ICR9ISQgOSAlfSElIDogJn0hJiA7ICd9IScgPCAofSEoID0gKX0hKSA+ICp9ISogPyArfSErIEAgLH0hLCBBIC19IS0gTCBNIE4gTyBQIFEgUiBTIFQgVSBCIEMgRCBFIEYgRyBIIEkgSiBLIAZBAREAACBMIEJ9IUwgTSBDfSFNIE4gRH0hTiBPIEV9IU8gUCBGfSFQIFEgR30hUSBSIEh9IVIgUyBJfSFTIFQgSn0hVCBVIEt9IVUgJCAlICYgJyAoICkgKiArICwgLUEAQQAgB0ECEQEAQsK2B0IAQgBCAEIAQgBCAEIAQgBCACBMIE0gTiBPIFAgUSBSIFMgVCBVIAhBAREAACAuIC8gMCAxIDIgMyA0IDUgNiA3QQBBACAJQQIRAQAgBjUCACEaIAY1AgQhGyAGNQIIIRwgBjUCDCEdIAY1AhAhHiAGNQIUIR8gBjUCGCEgIAY1AhwhISAGNQIgISIgBjUCJCEjIAc1AgAhJCAHNQIEISUgBzUCCCEmIAc1AgwhJyAHNQIQISggBzUCFCEpIAc1AhghKiAHNQIcISsgBzUCICEsIAc1AiQhLSAINQIAITggCDUCBCE5IAg1AgghOiAINQIMITsgCDUCECE8IAg1AhQhPSAINQIYIT4gCDUCHCE/IAg1AiAhQCAINQIkIUEgCTUCACEuIAk1AgQhLyAJNQIIITAgCTUCDCExIAk1AhAhMiAJNQIUITMgCTUCGCE0IAk1AhwhNSAJNQIgITYgCTUCJCE3IEIgOHwhQiBDIDl8IUMgRCA6fCFEIEUgO3whRSBGIDx8IUYgRyA9fCFHIEggPnwhSCBJID98IUkgSiBAfCFKIEsgQXwhSyAQIBEgEiATIBQgFSAWIBcgGCAZICQgJSAmICcgKCApICogKyAsIC0gB0EBEQAAIEIgQyBEIEUgRiBHIEggSSBKIEsgTCBNIE4gTyBQIFEgUiBTIFQgVSAGQQERAAAgBjUCACEkIAY1AgQhJSAGNQIIISYgBjUCDCEnIAY1AhAhKCAGNQIUISkgBjUCGCEqIAY1AhwhKyAGNQIgISwgBjUCJCEtIAc1AgAhOCAHNQIEITkgBzUCCCE6IAc1AgwhOyAHNQIQITwgBzUCFCE9IAc1AhghPiAHNQIcIT8gBzUCICFAIAc1AiQhQSAFQQFrIQUMAAsLQQAgA2utIQogGiAuhSAKgyFCIBsgL4UgCoMhQyAcIDCFIAqDIUQgHSAxhSAKgyFFIB4gMoUgCoMhRiAfIDOFIAqDIUcgICA0hSAKgyFIICEgNYUgCoMhSSAiIDaFIAqDIUogIyA3hSAKgyFLIBogQoUhGiAbIEOFIRsgHCBEhSEcIB0gRYUhHSAeIEaFIR4gHyBHhSEfICAgSIUhICAhIEmFISEgIiBKhSEiICMgS4UhIyAuIEKFIS4gLyBDhSEvIDAgRIUhMCAxIEWFITEgMiBGhSEyIDMgR4UhMyA0IEiFITQgNSBJhSE1IDYgSoUhNiA3IEuFITcgJCA4hSAKgyFCICUgOYUgCoMhQyAmIDqFIAqDIUQgJyA7hSAKgyFFICggPIUgCoMhRiApID2FIAqDIUcgKiA+hSAKgyFIICsgP4UgCoMhSSAsIECFIAqDIUogLSBBhSAKgyFLICQgQoUhJCAlIEOFISUgJiBEhSEmICcgRYUhJyAoIEaFISggKSBHhSEpICogSIUhKiArIEmFISsgLCBKhSEsIC0gS4UhLSA4IEKFITggOSBDhSE5IDogRIUhOiA7IEWFITsgPCBGhSE8ID0gR4UhPSA+IEiFIT4gPyBJhSE/IEAgSoUhQCBBIEuFIUEgJCAlICYgJyAoICkgKiArICwgLSAGQQMRAgAgBjUCACAGNQIEIAY1AgggBjUCDCAGNQIQIAY1AhQgBjUCGCAGNQIcIAY1AiAgBjUCJCAaIBsgHCAdIB4gHyAgICEgIiAjIABBAREAAAs=')
|
||||
var ready = null
|
||||
|
||||
var mod = {
|
||||
buffer: wasm,
|
||||
memory: null,
|
||||
exports: null,
|
||||
realloc: realloc,
|
||||
onload: onload
|
||||
}
|
||||
|
||||
onload(function () {})
|
||||
|
||||
return mod
|
||||
|
||||
function realloc (size) {
|
||||
mod.exports.memory.grow(Math.max(0, Math.ceil(Math.abs(size - mod.memory.length) / 65536)))
|
||||
mod.memory = new Uint8Array(mod.exports.memory.buffer)
|
||||
}
|
||||
|
||||
function onload (cb) {
|
||||
if (mod.exports) return cb()
|
||||
|
||||
if (ready) {
|
||||
ready.then(cb.bind(null, null)).catch(cb)
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
if (opts && opts.async) throw new Error('async')
|
||||
setup({instance: new WebAssembly.Instance(new WebAssembly.Module(wasm), imp)})
|
||||
} catch (err) {
|
||||
ready = WebAssembly.instantiate(wasm, imp).then(setup)
|
||||
}
|
||||
|
||||
onload(cb)
|
||||
}
|
||||
|
||||
function setup (w) {
|
||||
mod.exports = w.instance.exports
|
||||
mod.memory = mod.exports.memory && mod.exports.memory.buffer && new Uint8Array(mod.exports.memory.buffer)
|
||||
}
|
||||
}
|
||||
|
||||
function toUint8Array (s) {
|
||||
if (typeof atob === 'function') return new Uint8Array(atob(s).split('').map(charCodeAt))
|
||||
return (require('buf' + 'fer').Buffer).from(s, 'base64')
|
||||
}
|
||||
|
||||
function charCodeAt (c) {
|
||||
return c.charCodeAt(0)
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
+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,128 @@
|
||||
/* eslint-disable camelcase */
|
||||
const { sodium_malloc } = require('../memory')
|
||||
const assert = require('nanoassert')
|
||||
|
||||
if (new Uint16Array([1])[0] !== 1) throw new Error('Big endian architecture is not supported.')
|
||||
|
||||
const crypto_core_hchacha20_OUTPUTBYTES = 32
|
||||
const crypto_core_hchacha20_INPUTBYTES = 16
|
||||
const crypto_core_hchacha20_KEYBYTES = 32
|
||||
const crypto_core_hchacha20_CONSTBYTES = 16
|
||||
|
||||
function ROTL32 (x, b) {
|
||||
x &= 0xFFFFFFFF
|
||||
b &= 0xFFFFFFFF
|
||||
return (x << b) | (x >>> (32 - b))
|
||||
}
|
||||
|
||||
function LOAD32_LE (src, offset) {
|
||||
assert(src instanceof Uint8Array, 'src not byte array')
|
||||
let w = src[offset]
|
||||
w |= src[offset + 1] << 8
|
||||
w |= src[offset + 2] << 16
|
||||
w |= src[offset + 3] << 24
|
||||
return w
|
||||
}
|
||||
|
||||
function STORE32_LE (dest, int, offset) {
|
||||
assert(dest instanceof Uint8Array, 'dest not byte array')
|
||||
var mul = 1
|
||||
var i = 0
|
||||
dest[offset] = int & 0xFF // grab bottom byte
|
||||
while (++i < 4 && (mul *= 0x100)) {
|
||||
dest[offset + i] = (int / mul) & 0xFF
|
||||
}
|
||||
}
|
||||
|
||||
function QUARTERROUND (l, A, B, C, D) {
|
||||
l[A] += l[B]
|
||||
l[D] = ROTL32(l[D] ^ l[A], 16)
|
||||
l[C] += l[D]
|
||||
l[B] = ROTL32(l[B] ^ l[C], 12)
|
||||
l[A] += l[B]
|
||||
l[D] = ROTL32(l[D] ^ l[A], 8)
|
||||
l[C] += l[D]
|
||||
l[B] = ROTL32(l[B] ^ l[C], 7)
|
||||
}
|
||||
|
||||
function crypto_core_hchacha20 (out, _in, k, c) {
|
||||
assert(out instanceof Uint8Array && out.length === 32, 'out is not an array of 32 bytes')
|
||||
assert(k instanceof Uint8Array && k.length === 32, 'k is not an array of 32 bytes')
|
||||
assert(c === null || (c instanceof Uint8Array && c.length === 16), 'c is not null or an array of 16 bytes')
|
||||
|
||||
let i = 0
|
||||
const x = new Uint32Array(16)
|
||||
if (!c) {
|
||||
x[0] = 0x61707865
|
||||
x[1] = 0x3320646E
|
||||
x[2] = 0x79622D32
|
||||
x[3] = 0x6B206574
|
||||
} else {
|
||||
x[0] = LOAD32_LE(c, 0)
|
||||
x[1] = LOAD32_LE(c, 4)
|
||||
x[2] = LOAD32_LE(c, 8)
|
||||
x[3] = LOAD32_LE(c, 12)
|
||||
}
|
||||
x[4] = LOAD32_LE(k, 0)
|
||||
x[5] = LOAD32_LE(k, 4)
|
||||
x[6] = LOAD32_LE(k, 8)
|
||||
x[7] = LOAD32_LE(k, 12)
|
||||
x[8] = LOAD32_LE(k, 16)
|
||||
x[9] = LOAD32_LE(k, 20)
|
||||
x[10] = LOAD32_LE(k, 24)
|
||||
x[11] = LOAD32_LE(k, 28)
|
||||
x[12] = LOAD32_LE(_in, 0)
|
||||
x[13] = LOAD32_LE(_in, 4)
|
||||
x[14] = LOAD32_LE(_in, 8)
|
||||
x[15] = LOAD32_LE(_in, 12)
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
QUARTERROUND(x, 0, 4, 8, 12)
|
||||
QUARTERROUND(x, 1, 5, 9, 13)
|
||||
QUARTERROUND(x, 2, 6, 10, 14)
|
||||
QUARTERROUND(x, 3, 7, 11, 15)
|
||||
QUARTERROUND(x, 0, 5, 10, 15)
|
||||
QUARTERROUND(x, 1, 6, 11, 12)
|
||||
QUARTERROUND(x, 2, 7, 8, 13)
|
||||
QUARTERROUND(x, 3, 4, 9, 14)
|
||||
}
|
||||
|
||||
STORE32_LE(out, x[0], 0)
|
||||
STORE32_LE(out, x[1], 4)
|
||||
STORE32_LE(out, x[2], 8)
|
||||
STORE32_LE(out, x[3], 12)
|
||||
STORE32_LE(out, x[12], 16)
|
||||
STORE32_LE(out, x[13], 20)
|
||||
STORE32_LE(out, x[14], 24)
|
||||
STORE32_LE(out, x[15], 28)
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
function crypto_core_hchacha20_outputbytes () {
|
||||
return crypto_core_hchacha20_OUTPUTBYTES
|
||||
}
|
||||
|
||||
function crypto_core_hchacha20_inputbytes () {
|
||||
return crypto_core_hchacha20_INPUTBYTES
|
||||
}
|
||||
|
||||
function crypto_core_hchacha20_keybytes () {
|
||||
return crypto_core_hchacha20_KEYBYTES
|
||||
}
|
||||
|
||||
function crypto_core_hchacha20_constbytes () {
|
||||
return crypto_core_hchacha20_CONSTBYTES
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
crypto_core_hchacha20_INPUTBYTES,
|
||||
LOAD32_LE,
|
||||
STORE32_LE,
|
||||
QUARTERROUND,
|
||||
crypto_core_hchacha20,
|
||||
crypto_core_hchacha20_outputbytes,
|
||||
crypto_core_hchacha20_inputbytes,
|
||||
crypto_core_hchacha20_keybytes,
|
||||
crypto_core_hchacha20_constbytes
|
||||
}
|
||||
@@ -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 = globalThis.MessageChannel
|
||||
if (MessageChannel == null) ({ MessageChannel } = require('worker' + '_threads'))
|
||||
sink = new MessageChannel()
|
||||
return sink
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
sodium_malloc,
|
||||
sodium_free,
|
||||
sodium_memzero
|
||||
}
|
||||
+31
-11
@@ -1,32 +1,52 @@
|
||||
{
|
||||
"name": "sodium-javascript",
|
||||
"version": "0.5.3",
|
||||
"version": "0.8.0",
|
||||
"description": "WIP - a pure javascript version of sodium-native",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"argon2hash-wasm": "^1.0.0",
|
||||
"blake2b": "^2.1.1",
|
||||
"nanoassert": "^1.0.0",
|
||||
"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": {
|
||||
"brittle": "^3.2.1",
|
||||
"browser-run": "^4.0.2",
|
||||
"browserify": "^14.1.0",
|
||||
"sodium-test": "^0.7.0"
|
||||
"browserify": "^16.5.1",
|
||||
"sodium-native": "^3.4.1",
|
||||
"standard": "^15.0.1"
|
||||
},
|
||||
"standard": {
|
||||
"ignore": [
|
||||
"/internal/**/*.js",
|
||||
"/test/fixtures/*.js"
|
||||
]
|
||||
},
|
||||
"browser": {
|
||||
"crypto": false,
|
||||
"worker_threads": false
|
||||
},
|
||||
"scripts": {
|
||||
"browser": "browserify test.js | browser-run",
|
||||
"browser-manual": "browserify test.js | browser-run -p 1234",
|
||||
"test": "node test.js"
|
||||
"pretest": "standard",
|
||||
"test": "brittle 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"
|
||||
}
|
||||
|
||||
+360
@@ -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
|
||||
+36
-14
@@ -1,40 +1,62 @@
|
||||
var assert = require('nanoassert')
|
||||
|
||||
const {
|
||||
crypto_stream_chacha20_ietf,
|
||||
crypto_stream_chacha20_ietf_KEYBYTES,
|
||||
crypto_stream_chacha20_ietf_NONCEBYTES
|
||||
} = require('./crypto_stream_chacha20')
|
||||
|
||||
const randombytes_SEEDBYTES = 32
|
||||
|
||||
var randombytes = (function () {
|
||||
var QUOTA = 65536 // limit for QuotaExceededException
|
||||
var crypto = typeof global !== 'undefined' ? crypto = (global.crypto || global.msCrypto) : null
|
||||
var crypto = globalThis.crypto || globalThis.msCrypto
|
||||
|
||||
function browserBytes (out, n) {
|
||||
for (var i = 0; i < n; i += QUOTA) {
|
||||
crypto.getRandomValues(out.subarray(i, i + Math.min(n - i, QUOTA)))
|
||||
for (let i = 0; i < n; i += QUOTA) {
|
||||
crypto.getRandomValues(new Uint8Array(out.buffer, i + out.byteOffset, Math.min(n - i, QUOTA)))
|
||||
}
|
||||
}
|
||||
|
||||
function nodeBytes (out, n) {
|
||||
out.set(crypto.randomBytes(n))
|
||||
new Uint8Array(out.buffer, out.byteOffset, n).set(crypto.randomBytes(n))
|
||||
}
|
||||
|
||||
function noImpl () {
|
||||
throw new Error('No secure random number generator available')
|
||||
}
|
||||
|
||||
if (crypto && crypto.getRandomValues) {
|
||||
return browserBytes
|
||||
} else if (typeof require !== 'undefined') {
|
||||
// Node.js.
|
||||
crypto = require('cry' + 'pto');
|
||||
if (crypto && crypto.randomBytes) {
|
||||
return nodeBytes
|
||||
}
|
||||
if (crypto && crypto.getRandomValues) return browserBytes
|
||||
|
||||
if (require != null) {
|
||||
// Node.js. Bust Browserify
|
||||
crypto = require('cry' + 'pto')
|
||||
if (crypto && crypto.randomBytes) return nodeBytes
|
||||
}
|
||||
|
||||
return noImpl
|
||||
})()
|
||||
|
||||
// Make non enumerable as this is an internal function
|
||||
Object.defineProperty(module.exports, 'randombytes', {
|
||||
value: randombytes
|
||||
})
|
||||
|
||||
module.exports.randombytes_buf = function (out) {
|
||||
function randombytes_buf (out) {
|
||||
assert(out, 'out must be given')
|
||||
randombytes(out, out.length)
|
||||
randombytes(out, out.byteLength)
|
||||
}
|
||||
|
||||
function randombytes_buf_deterministic (buf, seed) {
|
||||
const nonce = Buffer.alloc(crypto_stream_chacha20_ietf_NONCEBYTES)
|
||||
nonce.write('LibsodiumDRG')
|
||||
|
||||
assert(randombytes_SEEDBYTES === crypto_stream_chacha20_ietf_KEYBYTES)
|
||||
crypto_stream_chacha20_ietf(buf, nonce, seed)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
randombytes_buf,
|
||||
randombytes_buf_deterministic,
|
||||
randombytes_SEEDBYTES
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
require('sodium-test')(require('.'))
|
||||
|
||||
if (typeof window !== 'undefined') window.close()
|
||||
@@ -0,0 +1,285 @@
|
||||
/* eslint-disable camelcase */
|
||||
const test = require('brittle')
|
||||
const b4a = require('b4a')
|
||||
const sodium = require('..')
|
||||
|
||||
test('constants', function (t) {
|
||||
t.is(typeof sodium.crypto_aead_chacha20poly1305_ietf_ABYTES, 'number')
|
||||
t.is(typeof sodium.crypto_aead_chacha20poly1305_ietf_KEYBYTES, 'number')
|
||||
t.is(typeof sodium.crypto_aead_chacha20poly1305_ietf_NPUBBYTES, 'number')
|
||||
t.is(typeof sodium.crypto_aead_chacha20poly1305_ietf_NSECBYTES, 'number')
|
||||
t.is(sodium.crypto_aead_chacha20poly1305_ietf_NSECBYTES, 0)
|
||||
t.is(typeof sodium.crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX, 'number')
|
||||
t.is(sodium.crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX, Number.MAX_SAFE_INTEGER) // to make sure, see note in binding.cc
|
||||
})
|
||||
|
||||
test('ported from libsodium', function (t) {
|
||||
const mlen = 114
|
||||
const adlen = 12
|
||||
const clen = mlen + sodium.crypto_aead_chacha20poly1305_ietf_ABYTES
|
||||
|
||||
const firstkey = b4a.from([
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
|
||||
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
|
||||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
|
||||
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f
|
||||
])
|
||||
|
||||
const message = b4a.from('Ladies and Gentlemen of the class of \'99: If I could offer you only one tip for the future, sunscreen would be it.')
|
||||
|
||||
const m = sodium.sodium_malloc(mlen)
|
||||
const nonce = b4a.from([
|
||||
0x07, 0x00, 0x00, 0x00, 0x40, 0x41, 0x42, 0x43,
|
||||
0x44, 0x45, 0x46, 0x47
|
||||
])
|
||||
t.is(nonce.length, sodium.crypto_aead_chacha20poly1305_ietf_NPUBBYTES)
|
||||
|
||||
const ad = b4a.from([
|
||||
0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3,
|
||||
0xc4, 0xc5, 0xc6, 0xc7
|
||||
])
|
||||
t.is(ad.length, adlen)
|
||||
|
||||
const c = sodium.sodium_malloc(clen)
|
||||
const detachedc = sodium.sodium_malloc(mlen)
|
||||
|
||||
const mac = sodium.sodium_malloc(sodium.crypto_aead_chacha20poly1305_ietf_ABYTES)
|
||||
|
||||
const m2 = sodium.sodium_malloc(mlen)
|
||||
|
||||
let foundclen = 0
|
||||
let foundmaclen = 0
|
||||
let m2len = 0
|
||||
|
||||
let i = 0
|
||||
|
||||
t.is(message.length, mlen)
|
||||
b4a.copy(message, m)
|
||||
|
||||
foundclen = sodium.crypto_aead_chacha20poly1305_ietf_encrypt(c, m, ad, null, nonce, firstkey)
|
||||
t.is(foundclen, mlen + sodium.crypto_aead_chacha20poly1305_ietf_ABYTES)
|
||||
|
||||
const exp1 = new Uint8Array([
|
||||
0xd3, 0x1a, 0x8d, 0x34, 0x64, 0x8e, 0x60, 0xdb, 0x7b, 0x86, 0xaf, 0xbc,
|
||||
0x53, 0xef, 0x7e, 0xc2, 0xa4, 0xad, 0xed, 0x51, 0x29, 0x6e, 0x08, 0xfe,
|
||||
0xa9, 0xe2, 0xb5, 0xa7, 0x36, 0xee, 0x62, 0xd6, 0x3d, 0xbe, 0xa4, 0x5e,
|
||||
0x8c, 0xa9, 0x67, 0x12, 0x82, 0xfa, 0xfb, 0x69, 0xda, 0x92, 0x72, 0x8b,
|
||||
0x1a, 0x71, 0xde, 0x0a, 0x9e, 0x06, 0x0b, 0x29, 0x05, 0xd6, 0xa5, 0xb6,
|
||||
0x7e, 0xcd, 0x3b, 0x36, 0x92, 0xdd, 0xbd, 0x7f, 0x2d, 0x77, 0x8b, 0x8c,
|
||||
0x98, 0x03, 0xae, 0xe3, 0x28, 0x09, 0x1b, 0x58, 0xfa, 0xb3, 0x24, 0xe4,
|
||||
0xfa, 0xd6, 0x75, 0x94, 0x55, 0x85, 0x80, 0x8b, 0x48, 0x31, 0xd7, 0xbc,
|
||||
0x3f, 0xf4, 0xde, 0xf0, 0x8e, 0x4b, 0x7a, 0x9d, 0xe5, 0x76, 0xd2, 0x65,
|
||||
0x86, 0xce, 0xc6, 0x4b, 0x61, 0x16, 0x1a, 0xe1, 0x0b, 0x59, 0x4f, 0x09,
|
||||
0xe2, 0x6a, 0x7e, 0x90, 0x2e, 0xcb, 0xd0, 0x60, 0x06, 0x91
|
||||
])
|
||||
|
||||
t.alike(c, exp1)
|
||||
|
||||
foundmaclen = sodium.crypto_aead_chacha20poly1305_ietf_encrypt_detached(detachedc, mac, m, ad, null, nonce, firstkey)
|
||||
|
||||
t.is(foundmaclen, sodium.crypto_aead_chacha20poly1305_ietf_ABYTES)
|
||||
const exp0 = c.slice(0, mlen)
|
||||
|
||||
t.alike(detachedc, exp0)
|
||||
|
||||
m2len = sodium.crypto_aead_chacha20poly1305_ietf_decrypt(m2, null, c, ad, nonce, firstkey)
|
||||
t.is(m2len, mlen)
|
||||
|
||||
t.alike(m, m2)
|
||||
|
||||
m2.fill(0)
|
||||
sodium.crypto_aead_chacha20poly1305_ietf_decrypt_detached(m2, null, c.slice(0, mlen), mac, ad, nonce, firstkey)
|
||||
|
||||
t.alike(m, m2)
|
||||
|
||||
for (i = 0; i < clen; i++) {
|
||||
c[i] ^= (i + 1)
|
||||
t.exception.all(_ => sodium.crypto_aead_chacha20poly1305_ietf_decrypt(m2, null, c, ad, nonce, firstkey))
|
||||
if (b4a.equals(m, m2)) t.fail()
|
||||
c[i] ^= (i + 1)
|
||||
}
|
||||
|
||||
foundclen = sodium.crypto_aead_chacha20poly1305_ietf_encrypt(c, m, null, null, nonce, firstkey)
|
||||
t.is(foundclen, clen)
|
||||
|
||||
const exp2 = new Uint8Array([
|
||||
0xd3, 0x1a, 0x8d, 0x34, 0x64, 0x8e, 0x60, 0xdb, 0x7b, 0x86, 0xaf, 0xbc,
|
||||
0x53, 0xef, 0x7e, 0xc2, 0xa4, 0xad, 0xed, 0x51, 0x29, 0x6e, 0x08, 0xfe,
|
||||
0xa9, 0xe2, 0xb5, 0xa7, 0x36, 0xee, 0x62, 0xd6, 0x3d, 0xbe, 0xa4, 0x5e,
|
||||
0x8c, 0xa9, 0x67, 0x12, 0x82, 0xfa, 0xfb, 0x69, 0xda, 0x92, 0x72, 0x8b,
|
||||
0x1a, 0x71, 0xde, 0x0a, 0x9e, 0x06, 0x0b, 0x29, 0x05, 0xd6, 0xa5, 0xb6,
|
||||
0x7e, 0xcd, 0x3b, 0x36, 0x92, 0xdd, 0xbd, 0x7f, 0x2d, 0x77, 0x8b, 0x8c,
|
||||
0x98, 0x03, 0xae, 0xe3, 0x28, 0x09, 0x1b, 0x58, 0xfa, 0xb3, 0x24, 0xe4,
|
||||
0xfa, 0xd6, 0x75, 0x94, 0x55, 0x85, 0x80, 0x8b, 0x48, 0x31, 0xd7, 0xbc,
|
||||
0x3f, 0xf4, 0xde, 0xf0, 0x8e, 0x4b, 0x7a, 0x9d, 0xe5, 0x76, 0xd2, 0x65,
|
||||
0x86, 0xce, 0xc6, 0x4b, 0x61, 0x16, 0x6a, 0x23, 0xa4, 0x68, 0x1f, 0xd5,
|
||||
0x94, 0x56, 0xae, 0xa1, 0xd2, 0x9f, 0x82, 0x47, 0x72, 0x16
|
||||
])
|
||||
|
||||
t.alike(c, exp2)
|
||||
|
||||
m2len = sodium.crypto_aead_chacha20poly1305_ietf_decrypt(m2, null, c, null, nonce, firstkey)
|
||||
t.is(m2len, mlen)
|
||||
|
||||
t.alike(m2, m)
|
||||
|
||||
b4a.copy(m, c)
|
||||
|
||||
foundclen = sodium.crypto_aead_chacha20poly1305_ietf_encrypt(c, c.slice(0, mlen), null, null, nonce, firstkey)
|
||||
|
||||
t.is(foundclen, clen, 'clen is properly set (adlen=0)')
|
||||
|
||||
const exp3 = new Uint8Array([
|
||||
0xd3, 0x1a, 0x8d, 0x34, 0x64, 0x8e, 0x60, 0xdb, 0x7b, 0x86, 0xaf, 0xbc,
|
||||
0x53, 0xef, 0x7e, 0xc2, 0xa4, 0xad, 0xed, 0x51, 0x29, 0x6e, 0x08, 0xfe,
|
||||
0xa9, 0xe2, 0xb5, 0xa7, 0x36, 0xee, 0x62, 0xd6, 0x3d, 0xbe, 0xa4, 0x5e,
|
||||
0x8c, 0xa9, 0x67, 0x12, 0x82, 0xfa, 0xfb, 0x69, 0xda, 0x92, 0x72, 0x8b,
|
||||
0x1a, 0x71, 0xde, 0x0a, 0x9e, 0x06, 0x0b, 0x29, 0x05, 0xd6, 0xa5, 0xb6,
|
||||
0x7e, 0xcd, 0x3b, 0x36, 0x92, 0xdd, 0xbd, 0x7f, 0x2d, 0x77, 0x8b, 0x8c,
|
||||
0x98, 0x03, 0xae, 0xe3, 0x28, 0x09, 0x1b, 0x58, 0xfa, 0xb3, 0x24, 0xe4,
|
||||
0xfa, 0xd6, 0x75, 0x94, 0x55, 0x85, 0x80, 0x8b, 0x48, 0x31, 0xd7, 0xbc,
|
||||
0x3f, 0xf4, 0xde, 0xf0, 0x8e, 0x4b, 0x7a, 0x9d, 0xe5, 0x76, 0xd2, 0x65,
|
||||
0x86, 0xce, 0xc6, 0x4b, 0x61, 0x16, 0x6a, 0x23, 0xa4, 0x68, 0x1f, 0xd5,
|
||||
0x94, 0x56, 0xae, 0xa1, 0xd2, 0x9f, 0x82, 0x47, 0x72, 0x16
|
||||
])
|
||||
|
||||
t.alike(c, exp3)
|
||||
|
||||
const decrypted = sodium.sodium_malloc(c.byteLength - sodium.crypto_aead_chacha20poly1305_ietf_ABYTES)
|
||||
m2len = sodium.crypto_aead_chacha20poly1305_ietf_decrypt(decrypted, null, c, null, nonce, firstkey)
|
||||
t.is(m2len, mlen, 'm2len is properly set (adlen=0)')
|
||||
|
||||
t.alike(m, decrypted, 'm == c (adlen=0)')
|
||||
})
|
||||
|
||||
test.skip('keygen', function (t) {
|
||||
const key1 = sodium.sodium_malloc(sodium.crypto_aead_chacha20poly1305_ietf_KEYBYTES)
|
||||
const key2 = sodium.sodium_malloc(sodium.crypto_aead_chacha20poly1305_ietf_KEYBYTES)
|
||||
|
||||
sodium.crypto_aead_chacha20poly1305_ietf_keygen(key1)
|
||||
sodium.crypto_aead_chacha20poly1305_ietf_keygen(key2)
|
||||
|
||||
t.unlike(key1, key2)
|
||||
})
|
||||
|
||||
test.skip('different keys', function (t) {
|
||||
const m = b4a.from('Ladies and Gentlemen of the class of \'99: If I could offer you only one tip for the future, sunscreen would be it.')
|
||||
|
||||
const key1 = sodium.sodium_malloc(sodium.crypto_aead_chacha20poly1305_ietf_KEYBYTES)
|
||||
const key2 = sodium.sodium_malloc(sodium.crypto_aead_chacha20poly1305_ietf_KEYBYTES)
|
||||
sodium.crypto_aead_chacha20poly1305_ietf_keygen(key1)
|
||||
sodium.crypto_aead_chacha20poly1305_ietf_keygen(key2)
|
||||
|
||||
const nonce = sodium.sodium_malloc(sodium.crypto_aead_chacha20poly1305_ietf_NPUBBYTES)
|
||||
sodium.randombytes_buf(nonce)
|
||||
|
||||
const clen = m.byteLength + sodium.crypto_aead_chacha20poly1305_ietf_ABYTES
|
||||
const c1 = sodium.sodium_malloc(clen)
|
||||
const c2 = sodium.sodium_malloc(clen)
|
||||
|
||||
const m1 = sodium.sodium_malloc(m.byteLength)
|
||||
const m2 = sodium.sodium_malloc(m.byteLength)
|
||||
|
||||
t.is(sodium.crypto_aead_chacha20poly1305_ietf_encrypt(c1, m, null, null, nonce, key1), clen)
|
||||
t.absent(c1.equals(c2))
|
||||
t.absent(c1.equals(m))
|
||||
t.is(sodium.crypto_aead_chacha20poly1305_ietf_encrypt(c2, m, null, null, nonce, key2), clen)
|
||||
t.absent(c1.equals(c2))
|
||||
t.absent(c2.equals(m))
|
||||
|
||||
t.exception.all(_ => sodium.crypto_aead_chacha20poly1305_ietf_decrypt(m1, null, c1, null, nonce, key2))
|
||||
t.exception.all(_ => sodium.crypto_aead_chacha20poly1305_ietf_decrypt(m2, null, c2, null, nonce, key1))
|
||||
|
||||
t.is(sodium.crypto_aead_chacha20poly1305_ietf_decrypt(m1, null, c1, null, nonce, key1), m.byteLength)
|
||||
t.ok(m.equals(m1))
|
||||
t.is(sodium.crypto_aead_chacha20poly1305_ietf_decrypt(m2, null, c2, null, nonce, key2), m.byteLength)
|
||||
t.ok(m.equals(m2))
|
||||
})
|
||||
|
||||
test.skip('different nonce', function (t) {
|
||||
const m = b4a.from('Ladies and Gentlemen of the class of \'99: If I could offer you only one tip for the future, sunscreen would be it.')
|
||||
|
||||
const key = sodium.sodium_malloc(sodium.crypto_aead_chacha20poly1305_ietf_KEYBYTES)
|
||||
sodium.crypto_aead_chacha20poly1305_ietf_keygen(key)
|
||||
|
||||
const n1 = sodium.sodium_malloc(sodium.crypto_aead_chacha20poly1305_ietf_NPUBBYTES)
|
||||
const n2 = sodium.sodium_malloc(sodium.crypto_aead_chacha20poly1305_ietf_NPUBBYTES)
|
||||
sodium.randombytes_buf(n1)
|
||||
sodium.randombytes_buf(n2)
|
||||
|
||||
const clen = m.byteLength + sodium.crypto_aead_chacha20poly1305_ietf_ABYTES
|
||||
const c1 = sodium.sodium_malloc(clen)
|
||||
const c2 = sodium.sodium_malloc(clen)
|
||||
|
||||
const m1 = sodium.sodium_malloc(m.byteLength)
|
||||
const m2 = sodium.sodium_malloc(m.byteLength)
|
||||
|
||||
t.is(sodium.crypto_aead_chacha20poly1305_ietf_encrypt(c1, m, null, null, n1, key), clen)
|
||||
t.absent(c1.equals(c2))
|
||||
t.absent(c1.equals(m))
|
||||
t.is(sodium.crypto_aead_chacha20poly1305_ietf_encrypt(c2, m, null, null, n2, key), clen)
|
||||
t.absent(c1.equals(c2))
|
||||
t.absent(c2.equals(m))
|
||||
|
||||
t.exception.all(_ => sodium.crypto_aead_chacha20poly1305_ietf_decrypt(m1, null, c1, null, n2, key))
|
||||
t.exception.all(_ => sodium.crypto_aead_chacha20poly1305_ietf_decrypt(m2, null, c2, null, n1, key))
|
||||
|
||||
t.is(sodium.crypto_aead_chacha20poly1305_ietf_decrypt(m1, null, c1, null, n1, key), m.byteLength)
|
||||
t.ok(m.equals(m1))
|
||||
t.is(sodium.crypto_aead_chacha20poly1305_ietf_decrypt(m2, null, c2, null, n2, key), m.byteLength)
|
||||
t.ok(m.equals(m2))
|
||||
})
|
||||
|
||||
test.skip('detached -> non-detached', function (t) {
|
||||
const m = b4a.from('Ladies and Gentlemen of the class of \'99: If I could offer you only one tip for the future, sunscreen would be it.')
|
||||
m.secure = true
|
||||
|
||||
const key = sodium.sodium_malloc(sodium.crypto_aead_chacha20poly1305_ietf_KEYBYTES)
|
||||
sodium.crypto_aead_chacha20poly1305_ietf_keygen(key)
|
||||
|
||||
const nonce = sodium.sodium_malloc(sodium.crypto_aead_chacha20poly1305_ietf_NPUBBYTES)
|
||||
sodium.randombytes_buf(nonce)
|
||||
|
||||
const mac = sodium.sodium_malloc(sodium.crypto_aead_chacha20poly1305_ietf_ABYTES)
|
||||
const clen = m.byteLength
|
||||
const c = sodium.sodium_malloc(clen)
|
||||
|
||||
t.is(sodium.crypto_aead_chacha20poly1305_ietf_encrypt_detached(c, mac, m, null, null, nonce, key), mac.byteLength)
|
||||
|
||||
const m1 = sodium.sodium_malloc(m.byteLength)
|
||||
t.is(sodium.crypto_aead_chacha20poly1305_ietf_decrypt(m1, null, b4a.concat([c, mac]), null, nonce, key), m.byteLength)
|
||||
|
||||
t.alike(m, m1)
|
||||
})
|
||||
|
||||
test.skip('non-detached -> detached', function (t) {
|
||||
const m = b4a.from('Ladies and Gentlemen of the class of \'99: If I could offer you only one tip for the future, sunscreen would be it.')
|
||||
m.secure = true
|
||||
|
||||
const key = sodium.sodium_malloc(sodium.crypto_aead_chacha20poly1305_ietf_KEYBYTES)
|
||||
sodium.crypto_aead_chacha20poly1305_ietf_keygen(key)
|
||||
|
||||
const nonce = sodium.sodium_malloc(sodium.crypto_aead_chacha20poly1305_ietf_NPUBBYTES)
|
||||
sodium.randombytes_buf(nonce)
|
||||
|
||||
const clen = m.byteLength + sodium.crypto_aead_chacha20poly1305_ietf_ABYTES
|
||||
const c = sodium.sodium_malloc(clen)
|
||||
|
||||
t.is(sodium.crypto_aead_chacha20poly1305_ietf_encrypt(c, m, null, null, nonce, key), c.byteLength)
|
||||
|
||||
const m1 = sodium.sodium_malloc(m.byteLength)
|
||||
const csub = c.subarray(0, clen - sodium.crypto_aead_chacha20poly1305_ietf_ABYTES)
|
||||
const macsub = c.subarray(csub.byteLength)
|
||||
sodium.crypto_aead_chacha20poly1305_ietf_decrypt_detached(m1, null, csub, macsub, null, nonce, key)
|
||||
|
||||
t.alike(m, m1)
|
||||
})
|
||||
|
||||
/**
|
||||
* Need to test in-place encryption
|
||||
* detach can talk to non detach
|
||||
* encrypt - decrypt
|
||||
* different nonce
|
||||
* different key
|
||||
* return values
|
||||
*/
|
||||
@@ -0,0 +1,219 @@
|
||||
/* eslint-disable camelcase */
|
||||
const test = require('brittle')
|
||||
const sodium = require('..')
|
||||
|
||||
test('crypto_auth', function (t) {
|
||||
const key = Buffer.alloc(sodium.crypto_auth_KEYBYTES)
|
||||
sodium.randombytes_buf(key)
|
||||
|
||||
const mac = Buffer.alloc(sodium.crypto_auth_BYTES)
|
||||
const value = Buffer.from('Hej, Verden')
|
||||
|
||||
sodium.crypto_auth(mac, value, key)
|
||||
|
||||
t.not(mac, Buffer.alloc(mac.length), 'mac not blank')
|
||||
t.absent(sodium.crypto_auth_verify(Buffer.alloc(mac.length), value, key), 'does not verify')
|
||||
t.ok(sodium.crypto_auth_verify(mac, value, key), 'verifies')
|
||||
})
|
||||
|
||||
test('crypto_auth #1', t => {
|
||||
// "Test Case 2" from RFC 4231
|
||||
const key = stringToArray('Jefe', 32)
|
||||
const c = stringToArray('what do ya want for nothing?')
|
||||
const c1 = stringToArray('wwhat do ya want for nothing')
|
||||
|
||||
const a = new Uint8Array(sodium.crypto_auth_BYTES)
|
||||
|
||||
const exp = [
|
||||
new Uint8Array([
|
||||
0x16, 0x4b, 0x7a, 0x7b, 0xfc, 0xf8, 0x19, 0xe2,
|
||||
0xe3, 0x95, 0xfb, 0xe7, 0x3b, 0x56, 0xe0, 0xa3,
|
||||
0x87, 0xbd, 0x64, 0x22, 0x2e, 0x83, 0x1f, 0xd6,
|
||||
0x10, 0x27, 0x0c, 0xd7, 0xea, 0x25, 0x05, 0x54
|
||||
]),
|
||||
new Uint8Array([
|
||||
0x7b, 0x9d, 0x83, 0x38, 0xeb, 0x1e, 0x3d, 0xdd,
|
||||
0xba, 0x8a, 0x9a, 0x35, 0x08, 0xd0, 0x34, 0xa1,
|
||||
0xec, 0xbe, 0x75, 0x11, 0x37, 0xfa, 0x1b, 0xcb,
|
||||
0xa0, 0xf9, 0x2a, 0x3e, 0x6d, 0xfc, 0x79, 0x80
|
||||
]),
|
||||
new Uint8Array([
|
||||
0xb9, 0xd1, 0x4c, 0x51, 0xa6, 0xd4, 0xdd, 0x41,
|
||||
0x60, 0x4e, 0xb0, 0x6c, 0x9c, 0x24, 0x0f, 0x1f,
|
||||
0x64, 0xf1, 0x43, 0xb5, 0xcf, 0xde, 0xa3, 0x71,
|
||||
0x29, 0xb2, 0x8b, 0xb7, 0x5d, 0x13, 0x71, 0xd3
|
||||
])
|
||||
]
|
||||
|
||||
sodium.crypto_auth(a, c, key)
|
||||
t.alike(a, exp[0])
|
||||
t.ok(sodium.crypto_auth_verify(exp[0], c, key))
|
||||
|
||||
a.fill(0)
|
||||
sodium.crypto_auth(a, c1, key)
|
||||
t.alike(a, exp[1])
|
||||
t.ok(sodium.crypto_auth_verify(exp[1], c1, key))
|
||||
|
||||
// Empty message tests
|
||||
a.fill(0)
|
||||
sodium.crypto_auth(a, new Uint8Array(0), key)
|
||||
t.alike(a, exp[2])
|
||||
t.ok(sodium.crypto_auth_verify(exp[2], new Uint8Array(0), key))
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('crypto_auth', function (t) {
|
||||
const key = stringToArray('Jefe', 32)
|
||||
const c = stringToArray('what do ya want for nothing?')
|
||||
const a = new Uint8Array(sodium.crypto_auth_BYTES)
|
||||
const expected = new Uint8Array([
|
||||
0x16, 0x4b, 0x7a, 0x7b, 0xfc, 0xf8, 0x19, 0xe2, 0xe3, 0x95, 0xfb, 0xe7,
|
||||
0x3b, 0x56, 0xe0, 0xa3, 0x87, 0xbd, 0x64, 0x22, 0x2e, 0x83, 0x1f, 0xd6,
|
||||
0x10, 0x27, 0x0c, 0xd7, 0xea, 0x25, 0x05, 0x54
|
||||
])
|
||||
|
||||
sodium.crypto_auth(a, c, key)
|
||||
|
||||
t.alike(a, expected)
|
||||
t.ok(sodium.crypto_auth_verify(a, c, key))
|
||||
|
||||
c[Math.floor(Math.random() * c.length)] += 1
|
||||
t.absent(sodium.crypto_auth_verify(a, c, key))
|
||||
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('wrong keylength', t => {
|
||||
const a = new Uint8Array(32)
|
||||
const c = new Uint8Array(0)
|
||||
|
||||
for (let i = 0; i < 128; i++) {
|
||||
if (i === 32) continue
|
||||
const k = new Uint8Array(i)
|
||||
try {
|
||||
sodium.crypto_auth(a, c, k)
|
||||
t.fail('failed on test #' + i)
|
||||
} catch (e) {
|
||||
try {
|
||||
sodium.crypto_auth_verify(a, c, k)
|
||||
t.fail('failed on test #' + i)
|
||||
} catch (e) {
|
||||
try {
|
||||
sodium.crypto_auth_verify(k, c, a)
|
||||
t.fail('failed on test #' + i)
|
||||
} catch {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
t.pass('should not accept bad input length')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('crypto_auth constants', t => {
|
||||
t.is(sodium.crypto_auth_BYTES, 32)
|
||||
t.is(sodium.crypto_auth_KEYBYTES, 32)
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('rfc4231 test case #6', t => {
|
||||
const keys = [
|
||||
new Uint8Array([
|
||||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
|
||||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
|
||||
0x0b, 0x0b, 0x0b, 0x0b, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
]),
|
||||
new Uint8Array([
|
||||
0x4a, 0x65, 0x66, 0x65, 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
|
||||
]),
|
||||
new Uint8Array([
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
]),
|
||||
new Uint8Array([
|
||||
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
||||
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
|
||||
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
|
||||
0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
])
|
||||
]
|
||||
|
||||
const data = [
|
||||
new Uint8Array([
|
||||
0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65
|
||||
]),
|
||||
new Uint8Array([
|
||||
0x77, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x20,
|
||||
0x79, 0x61, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20,
|
||||
0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x68,
|
||||
0x69, 0x6e, 0x67, 0x3f
|
||||
]),
|
||||
new Uint8Array([
|
||||
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
|
||||
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
|
||||
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
|
||||
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
|
||||
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
|
||||
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
|
||||
0xdd, 0xdd
|
||||
]),
|
||||
new Uint8Array([
|
||||
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
|
||||
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
|
||||
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
|
||||
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
|
||||
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
|
||||
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
|
||||
0xcd, 0xcd
|
||||
])
|
||||
]
|
||||
|
||||
const exp = [
|
||||
new Uint8Array([
|
||||
0x87, 0xaa, 0x7c, 0xde, 0xa5, 0xef, 0x61, 0x9d,
|
||||
0x4f, 0xf0, 0xb4, 0x24, 0x1a, 0x1d, 0x6c, 0xb0,
|
||||
0x23, 0x79, 0xf4, 0xe2, 0xce, 0x4e, 0xc2, 0x78,
|
||||
0x7a, 0xd0, 0xb3, 0x05, 0x45, 0xe1, 0x7c, 0xde
|
||||
]),
|
||||
new Uint8Array([
|
||||
0x16, 0x4b, 0x7a, 0x7b, 0xfc, 0xf8, 0x19, 0xe2,
|
||||
0xe3, 0x95, 0xfb, 0xe7, 0x3b, 0x56, 0xe0, 0xa3,
|
||||
0x87, 0xbd, 0x64, 0x22, 0x2e, 0x83, 0x1f, 0xd6,
|
||||
0x10, 0x27, 0x0c, 0xd7, 0xea, 0x25, 0x05, 0x54
|
||||
]),
|
||||
new Uint8Array([
|
||||
0xfa, 0x73, 0xb0, 0x08, 0x9d, 0x56, 0xa2, 0x84,
|
||||
0xef, 0xb0, 0xf0, 0x75, 0x6c, 0x89, 0x0b, 0xe9,
|
||||
0xb1, 0xb5, 0xdb, 0xdd, 0x8e, 0xe8, 0x1a, 0x36,
|
||||
0x55, 0xf8, 0x3e, 0x33, 0xb2, 0x27, 0x9d, 0x39
|
||||
]),
|
||||
new Uint8Array([
|
||||
0xb0, 0xba, 0x46, 0x56, 0x37, 0x45, 0x8c, 0x69,
|
||||
0x90, 0xe5, 0xa8, 0xc5, 0xf6, 0x1d, 0x4a, 0xf7,
|
||||
0xe5, 0x76, 0xd9, 0x7f, 0xf9, 0x4b, 0x87, 0x2d,
|
||||
0xe7, 0x6f, 0x80, 0x50, 0x36, 0x1e, 0xe3, 0xdb
|
||||
])
|
||||
]
|
||||
|
||||
const a = new Uint8Array(sodium.crypto_auth_BYTES)
|
||||
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
sodium.crypto_auth(a, data[i], keys[i])
|
||||
t.alike(a, exp[i])
|
||||
t.ok(sodium.crypto_auth_verify(exp[i], data[i], keys[i]))
|
||||
}
|
||||
|
||||
t.end()
|
||||
})
|
||||
|
||||
function stringToArray (s, size = s.length) {
|
||||
const array = new Uint8Array(size)
|
||||
array.set(s.split('').map((c) => c.charCodeAt(0)))
|
||||
return array
|
||||
}
|
||||
@@ -0,0 +1,305 @@
|
||||
/* eslint-disable camelcase */
|
||||
const test = require('brittle')
|
||||
const sodium = require('..')
|
||||
|
||||
test('crypto_box_seed_keypair', function (t) {
|
||||
const pk = Buffer.alloc(sodium.crypto_box_PUBLICKEYBYTES)
|
||||
const sk = Buffer.alloc(sodium.crypto_box_SECRETKEYBYTES)
|
||||
const seed = Buffer.alloc(sodium.crypto_box_SEEDBYTES, 'lo')
|
||||
|
||||
t.exception.all(function () {
|
||||
sodium.crypto_box_seed_keypair()
|
||||
}, 'should validate input')
|
||||
|
||||
t.exception.all(function () {
|
||||
sodium.crypto_box_seed_keypair(Buffer.alloc(0), Buffer.alloc(0), Buffer.alloc(0))
|
||||
}, 'should validate input length')
|
||||
|
||||
sodium.crypto_box_seed_keypair(pk, sk, seed)
|
||||
|
||||
const eSk = '8661a95d21b134adc02881022ad86d37f32a230d537b525b997bce27aa745afc'
|
||||
const ePk = '425c5ba523e70411c77300bb48dd846562e6c1fcf0142d81d2567d650ce76c3b'
|
||||
|
||||
t.alike(pk.toString('hex'), ePk, 'seeded public key')
|
||||
t.alike(sk.toString('hex'), eSk, 'seeded secret key')
|
||||
})
|
||||
|
||||
test('crypto_box_keypair', function (t) {
|
||||
const pk = Buffer.alloc(sodium.crypto_box_PUBLICKEYBYTES)
|
||||
const sk = Buffer.alloc(sodium.crypto_box_SECRETKEYBYTES)
|
||||
|
||||
sodium.crypto_box_keypair(pk, sk)
|
||||
|
||||
t.not(pk, Buffer.alloc(pk.length), 'made public key')
|
||||
t.not(sk, Buffer.alloc(sk.length), 'made secret key')
|
||||
|
||||
t.exception.all(function () {
|
||||
sodium.crypto_box_keypair()
|
||||
}, 'should validate input')
|
||||
|
||||
t.exception.all(function () {
|
||||
sodium.crypto_box_keypair(Buffer.alloc(0), Buffer.alloc(0))
|
||||
}, 'should validate input length')
|
||||
})
|
||||
|
||||
test('crypto_box_detached', function (t) {
|
||||
const pk = Buffer.alloc(sodium.crypto_box_PUBLICKEYBYTES)
|
||||
const sk = Buffer.alloc(sodium.crypto_box_SECRETKEYBYTES)
|
||||
const nonce = Buffer.alloc(sodium.crypto_box_NONCEBYTES)
|
||||
|
||||
sodium.crypto_box_keypair(pk, sk)
|
||||
|
||||
const message = Buffer.from('Hello, World!')
|
||||
const mac = Buffer.alloc(sodium.crypto_box_MACBYTES)
|
||||
const cipher = Buffer.alloc(message.length)
|
||||
|
||||
sodium.crypto_box_detached(cipher, mac, message, nonce, pk, sk)
|
||||
|
||||
t.not(cipher, Buffer.alloc(cipher.length), 'not blank')
|
||||
|
||||
const plain = Buffer.alloc(cipher.length)
|
||||
t.absent(sodium.crypto_box_open_detached(plain, cipher, Buffer.alloc(mac.length), nonce, pk, sk), 'does not decrypt')
|
||||
t.ok(sodium.crypto_box_open_detached(plain, cipher, mac, nonce, pk, sk), 'decrypts')
|
||||
t.alike(plain, message, 'same message')
|
||||
})
|
||||
|
||||
test('crypto_box_easy', function (t) {
|
||||
const pk = Buffer.alloc(sodium.crypto_box_PUBLICKEYBYTES)
|
||||
const sk = Buffer.alloc(sodium.crypto_box_SECRETKEYBYTES)
|
||||
const nonce = Buffer.alloc(sodium.crypto_box_NONCEBYTES)
|
||||
|
||||
sodium.crypto_box_keypair(pk, sk)
|
||||
|
||||
const message = Buffer.from('Hello, World!')
|
||||
const cipher = Buffer.alloc(message.length + sodium.crypto_box_MACBYTES)
|
||||
|
||||
sodium.crypto_box_easy(cipher, message, nonce, pk, sk)
|
||||
|
||||
t.not(cipher, Buffer.alloc(cipher.length), 'not blank')
|
||||
|
||||
const plain = Buffer.alloc(cipher.length - sodium.crypto_box_MACBYTES)
|
||||
t.absent(sodium.crypto_box_open_easy(plain, Buffer.alloc(cipher.length), nonce, pk, sk), 'does not decrypt')
|
||||
t.ok(sodium.crypto_box_open_easy(plain, cipher, nonce, pk, sk), 'decrypts')
|
||||
t.alike(plain, message, 'same message')
|
||||
})
|
||||
|
||||
test('crypto_box_seal', function (t) {
|
||||
const pk = Buffer.alloc(sodium.crypto_box_PUBLICKEYBYTES)
|
||||
const sk = Buffer.alloc(sodium.crypto_box_SECRETKEYBYTES)
|
||||
|
||||
sodium.crypto_box_keypair(pk, sk)
|
||||
|
||||
const pk2 = Buffer.alloc(sodium.crypto_box_PUBLICKEYBYTES)
|
||||
const sk2 = Buffer.alloc(sodium.crypto_box_SECRETKEYBYTES)
|
||||
|
||||
sodium.crypto_box_keypair(pk2, sk2)
|
||||
|
||||
const message = Buffer.from('Hello, sealed World!')
|
||||
const cipher = Buffer.alloc(message.length + sodium.crypto_box_SEALBYTES)
|
||||
|
||||
sodium.crypto_box_seal(cipher, message, pk)
|
||||
t.not(cipher, message, 'did not encrypt!')
|
||||
|
||||
t.not(cipher, Buffer.alloc(cipher.length), 'not blank')
|
||||
|
||||
const plain = Buffer.alloc(cipher.length - sodium.crypto_box_SEALBYTES)
|
||||
t.absent(sodium.crypto_box_seal_open(plain, cipher, pk2, sk2), 'does not decrypt')
|
||||
t.ok(sodium.crypto_box_seal_open(plain, cipher, pk, sk), 'decrypts')
|
||||
t.alike(plain, message, 'same message')
|
||||
})
|
||||
|
||||
test('crypto_box_seal/crypto_box_seal_open self-decrypt', function (t) {
|
||||
const pubKey = Buffer.alloc(sodium.crypto_box_PUBLICKEYBYTES)
|
||||
const secret = Buffer.alloc(sodium.crypto_box_SECRETKEYBYTES)
|
||||
|
||||
sodium.crypto_box_keypair(pubKey, secret)
|
||||
|
||||
const msg = Buffer.from('hello world')
|
||||
const cipher = Buffer.alloc(sodium.crypto_box_SEALBYTES + msg.length)
|
||||
sodium.crypto_box_seal(cipher, msg, pubKey)
|
||||
|
||||
const out = Buffer.alloc(cipher.length - sodium.crypto_box_SEALBYTES)
|
||||
sodium.crypto_box_seal_open(out, cipher, pubKey, secret)
|
||||
t.alike(out.toString(), msg.toString())
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('crypto_box_seal_open cross-decrypt', function (t) {
|
||||
const pubKey = Buffer.from(
|
||||
'e0bb844ae3f48bb04323c8dfe7c34cf86608db2e2112f927953060c80506287f', 'hex')
|
||||
const secret = Buffer.from(
|
||||
'036a9de1ecc9d152cf39fed1b3e15bf761ae39a299031adc011cc9809041abfa', 'hex')
|
||||
const cipher = Buffer.from(
|
||||
'249912e916ad8bcf96a3f9b750da2703' +
|
||||
'2eccdf83b5cff0d6a59a8bbe0bcd5823' +
|
||||
'5de9fbca55bd5416c754e5e0e0fe2f0c' +
|
||||
'4e50df0cb302f1c4378f80', 'hex')
|
||||
|
||||
const out = Buffer.alloc(cipher.length - sodium.crypto_box_SEALBYTES)
|
||||
sodium.crypto_box_seal_open(out, cipher, pubKey, secret)
|
||||
t.alike(out.toString(), 'hello world')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('crypto_box_seed_keypair', function (t) {
|
||||
const seed = Buffer.from([
|
||||
0x77, 0x07, 0x6d, 0x0a, 0x73, 0x18, 0xa5,
|
||||
0x7d, 0x3c, 0x16, 0xc1, 0x72, 0x51, 0xb2,
|
||||
0x66, 0x45, 0xdf, 0x4c, 0x2f, 0x87, 0xeb,
|
||||
0xc0, 0x99, 0x2a, 0xb1, 0x77, 0xfb, 0xa5,
|
||||
0x1d, 0xb9, 0x2c, 0x2a
|
||||
])
|
||||
|
||||
const expPk = Buffer.from([
|
||||
0xed, 0x77, 0x49, 0xb4, 0xd9, 0x89, 0xf6, 0x95,
|
||||
0x7f, 0x3b, 0xfd, 0xe6, 0xc5, 0x67, 0x67, 0xe9,
|
||||
0x88, 0xe2, 0x1c, 0x9f, 0x87, 0x84, 0xd9, 0x1d,
|
||||
0x61, 0x00, 0x11, 0xcd, 0x55, 0x3f, 0x9b, 0x06
|
||||
])
|
||||
|
||||
const expSk = Buffer.from([
|
||||
0xac, 0xcd, 0x44, 0xeb, 0x8e, 0x93, 0x31, 0x9c,
|
||||
0x05, 0x70, 0xbc, 0x11, 0x00, 0x5c, 0x0e, 0x01,
|
||||
0x89, 0xd3, 0x4f, 0xf0, 0x2f, 0x6c, 0x17, 0x77,
|
||||
0x34, 0x11, 0xad, 0x19, 0x12, 0x93, 0xc9, 0x8f
|
||||
])
|
||||
|
||||
const sk = Buffer.alloc(32)
|
||||
const pk = Buffer.alloc(32)
|
||||
|
||||
sodium.crypto_box_seed_keypair(pk, sk, seed)
|
||||
|
||||
t.alike(pk, expPk)
|
||||
t.alike(sk, expSk)
|
||||
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('crypto_box_easy', (t) => {
|
||||
const alicesk = new Uint8Array([
|
||||
0x77, 0x07, 0x6d, 0x0a, 0x73, 0x18, 0xa5, 0x7d, 0x3c, 0x16, 0xc1, 0x72,
|
||||
0x51, 0xb2, 0x66, 0x45, 0xdf, 0x4c, 0x2f, 0x87, 0xeb, 0xc0, 0x99, 0x2a,
|
||||
0xb1, 0x77, 0xfb, 0xa5, 0x1d, 0xb9, 0x2c, 0x2a
|
||||
])
|
||||
const bobpk = new Uint8Array([
|
||||
0xde, 0x9e, 0xdb, 0x7d, 0x7b, 0x7d, 0xc1, 0xb4, 0xd3, 0x5b, 0x61, 0xc2,
|
||||
0xec, 0xe4, 0x35, 0x37, 0x3f, 0x83, 0x43, 0xc8, 0x5b, 0x78, 0x67, 0x4d,
|
||||
0xad, 0xfc, 0x7e, 0x14, 0x6f, 0x88, 0x2b, 0x4f
|
||||
])
|
||||
const nonce = new Uint8Array([
|
||||
0x69, 0x69, 0x6e, 0xe9, 0x55, 0xb6, 0x2b, 0x73, 0xcd, 0x62, 0xbd, 0xa8,
|
||||
0x75, 0xfc, 0x73, 0xd6, 0x82, 0x19, 0xe0, 0x03, 0x6b, 0x7a, 0x0b, 0x37
|
||||
])
|
||||
const m = new Uint8Array([
|
||||
0xbe, 0x07, 0x5f, 0xc5, 0x3c, 0x81, 0xf2, 0xd5, 0xcf, 0x14, 0x13, 0x16,
|
||||
0xeb, 0xeb, 0x0c, 0x7b, 0x52, 0x28, 0xc5, 0x2a, 0x4c, 0x62, 0xcb, 0xd4,
|
||||
0x4b, 0x66, 0x84, 0x9b, 0x64, 0x24, 0x4f, 0xfc, 0xe5, 0xec, 0xba, 0xaf,
|
||||
0x33, 0xbd, 0x75, 0x1a, 0x1a, 0xc7, 0x28, 0xd4, 0x5e, 0x6c, 0x61, 0x29,
|
||||
0x6c, 0xdc, 0x3c, 0x01, 0x23, 0x35, 0x61, 0xf4, 0x1d, 0xb6, 0x6c, 0xce,
|
||||
0x31, 0x4a, 0xdb, 0x31, 0x0e, 0x3b, 0xe8, 0x25, 0x0c, 0x46, 0xf0, 0x6d,
|
||||
0xce, 0xea, 0x3a, 0x7f, 0xa1, 0x34, 0x80, 0x57, 0xe2, 0xf6, 0x55, 0x6a,
|
||||
0xd6, 0xb1, 0x31, 0x8a, 0x02, 0x4a, 0x83, 0x8f, 0x21, 0xaf, 0x1f, 0xde,
|
||||
0x04, 0x89, 0x77, 0xeb, 0x48, 0xf5, 0x9f, 0xfd, 0x49, 0x24, 0xca, 0x1c,
|
||||
0x60, 0x90, 0x2e, 0x52, 0xf0, 0xa0, 0x89, 0xbc, 0x76, 0x89, 0x70, 0x40,
|
||||
0xe0, 0x82, 0xf9, 0x37, 0x76, 0x38, 0x48, 0x64, 0x5e, 0x07, 0x05
|
||||
])
|
||||
|
||||
const c = new Uint8Array(147)
|
||||
sodium.crypto_box_easy(c, m, nonce, bobpk, alicesk)
|
||||
|
||||
const expected1 = new Uint8Array([
|
||||
0xf3, 0xff, 0xc7, 0x70, 0x3f, 0x94, 0x00, 0xe5, 0x2a, 0x7d, 0xfb, 0x4b,
|
||||
0x3d, 0x33, 0x05, 0xd9, 0x8e, 0x99, 0x3b, 0x9f, 0x48, 0x68, 0x12, 0x73,
|
||||
0xc2, 0x96, 0x50, 0xba, 0x32, 0xfc, 0x76, 0xce, 0x48, 0x33, 0x2e, 0xa7,
|
||||
0x16, 0x4d, 0x96, 0xa4, 0x47, 0x6f, 0xb8, 0xc5, 0x31, 0xa1, 0x18, 0x6a,
|
||||
0xc0, 0xdf, 0xc1, 0x7c, 0x98, 0xdc, 0xe8, 0x7b, 0x4d, 0xa7, 0xf0, 0x11,
|
||||
0xec, 0x48, 0xc9, 0x72, 0x71, 0xd2, 0xc2, 0x0f, 0x9b, 0x92, 0x8f, 0xe2,
|
||||
0x27, 0x0d, 0x6f, 0xb8, 0x63, 0xd5, 0x17, 0x38, 0xb4, 0x8e, 0xee, 0xe3,
|
||||
0x14, 0xa7, 0xcc, 0x8a, 0xb9, 0x32, 0x16, 0x45, 0x48, 0xe5, 0x26, 0xae,
|
||||
0x90, 0x22, 0x43, 0x68, 0x51, 0x7a, 0xcf, 0xea, 0xbd, 0x6b, 0xb3, 0x73,
|
||||
0x2b, 0xc0, 0xe9, 0xda, 0x99, 0x83, 0x2b, 0x61, 0xca, 0x01, 0xb6, 0xde,
|
||||
0x56, 0x24, 0x4a, 0x9e, 0x88, 0xd5, 0xf9, 0xb3, 0x79, 0x73, 0xf6, 0x22,
|
||||
0xa4, 0x3d, 0x14, 0xa6, 0x59, 0x9b, 0x1f, 0x65, 0x4c, 0xb4, 0x5a, 0x74,
|
||||
0xe3, 0x55, 0xa5
|
||||
])
|
||||
|
||||
t.alike(c, expected1, 'encrypts correctly')
|
||||
|
||||
// This test isn't found upstream, but it seems necessary to have at least
|
||||
// one crypto_box_open_easy() working since the next test diverges.
|
||||
const o = new Uint8Array(131)
|
||||
t.ok(sodium.crypto_box_open_easy(o, expected1, nonce, bobpk, alicesk))
|
||||
t.alike(o, m, 'decrypts correctly')
|
||||
|
||||
const guardPage = new Uint8Array(0)
|
||||
|
||||
t.execution(() => sodium.crypto_box_easy(
|
||||
c.subarray(0, sodium.crypto_box_MACBYTES),
|
||||
guardPage,
|
||||
nonce,
|
||||
bobpk,
|
||||
alicesk
|
||||
))
|
||||
|
||||
const expected2 = new Uint8Array([
|
||||
0x25, 0x39, 0x12, 0x1d, 0x8e, 0x23, 0x4e, 0x65, 0x2d, 0x65, 0x1f, 0xa4,
|
||||
0xc8, 0xcf, 0xf8, 0x80, 0x8e
|
||||
])
|
||||
|
||||
t.alike(c.subarray(0, expected2.length), expected2)
|
||||
|
||||
t.ok(sodium.crypto_box_open_easy(
|
||||
new Uint8Array(0),
|
||||
c.subarray(0, sodium.crypto_box_MACBYTES),
|
||||
nonce,
|
||||
bobpk,
|
||||
alicesk
|
||||
))
|
||||
|
||||
c[Math.floor(Math.random() * sodium.crypto_box_MACBYTES)] += 1
|
||||
|
||||
t.absent(sodium.crypto_box_open_easy(new Uint8Array(0), c.subarray(0, sodium.crypto_box_MACBYTES), nonce, bobpk, alicesk))
|
||||
|
||||
t.end()
|
||||
})
|
||||
|
||||
/* eslint-disable camelcase */
|
||||
test('crypto_box_easy2', t => {
|
||||
const alicepk = new Uint8Array(sodium.crypto_box_PUBLICKEYBYTES)
|
||||
const alicesk = new Uint8Array(sodium.crypto_box_SECRETKEYBYTES)
|
||||
const bobpk = new Uint8Array(sodium.crypto_box_PUBLICKEYBYTES)
|
||||
const bobsk = new Uint8Array(sodium.crypto_box_SECRETKEYBYTES)
|
||||
const nonce = new Uint8Array(sodium.crypto_box_NONCEBYTES)
|
||||
const m_size = 7 + Math.floor(Math.random() * 1000)
|
||||
const m = new Uint8Array(m_size)
|
||||
const m2 = new Uint8Array(m_size)
|
||||
const c = new Uint8Array(sodium.crypto_box_MACBYTES + m_size)
|
||||
|
||||
sodium.crypto_box_keypair(alicepk, alicesk)
|
||||
sodium.crypto_box_keypair(bobpk, bobsk)
|
||||
|
||||
const mlen = Math.floor(Math.random() * m_size) + 1
|
||||
sodium.randombytes_buf(m.subarray(0, mlen))
|
||||
sodium.randombytes_buf(nonce.subarray(0, sodium.crypto_box_NONCEBYTES))
|
||||
|
||||
t.execution(() => sodium.crypto_box_easy(c.subarray(0, mlen + sodium.crypto_box_MACBYTES), m.subarray(0, mlen), nonce, bobpk, alicesk))
|
||||
|
||||
t.ok(sodium.crypto_box_open_easy(m2.subarray(0, mlen), c.subarray(0, mlen + sodium.crypto_box_MACBYTES), nonce, alicepk, bobsk))
|
||||
t.alike(m.subarray(0, mlen), m2.subarray(0, mlen))
|
||||
|
||||
for (let i = sodium.crypto_box_MACBYTES; i < mlen + sodium.crypto_box_MACBYTES - 1; i++) {
|
||||
if (sodium.crypto_box_open_easy(m2.subarray(0, i - sodium.crypto_box_MACBYTES), c.subarray(0, i), nonce, alicepk, bobsk)) {
|
||||
t.fail('short open() should fail.')
|
||||
}
|
||||
}
|
||||
|
||||
c.set(m.subarray(0, mlen))
|
||||
t.execution(() => sodium.crypto_box_easy(c.subarray(0, mlen + sodium.crypto_box_MACBYTES), c.subarray(0, mlen), nonce, bobpk, alicesk))
|
||||
|
||||
t.unlike(m.subarray(0, mlen), c.subarray(0, mlen))
|
||||
t.unlike(m.subarray(0, mlen), c.subarray(sodium.crypto_box_MACBYTES, sodium.crypto_box_MACBYTES + mlen))
|
||||
|
||||
t.ok(sodium.crypto_box_open_easy(c.subarray(0, mlen), c.subarray(0, mlen + sodium.crypto_box_MACBYTES), nonce, alicepk, bobsk))
|
||||
|
||||
t.end()
|
||||
})
|
||||
@@ -0,0 +1,133 @@
|
||||
/* eslint-disable camelcase */
|
||||
const test = require('brittle')
|
||||
const sodium = require('..')
|
||||
|
||||
test('crypto_generichash', function (t) {
|
||||
const buf = Buffer.from('Hello, World!')
|
||||
|
||||
const out = Buffer.alloc(sodium.crypto_generichash_BYTES)
|
||||
sodium.crypto_generichash(out, buf)
|
||||
|
||||
t.alike(out.toString('hex'), '511bc81dde11180838c562c82bb35f3223f46061ebde4a955c27b3f489cf1e03', 'hashed buffer')
|
||||
|
||||
const min = Buffer.alloc(sodium.crypto_generichash_BYTES_MIN)
|
||||
sodium.crypto_generichash(min, buf)
|
||||
|
||||
t.alike(min.toString('hex'), '3895c59e4aeb0903396b5be3fbec69fe', 'hashed buffer min')
|
||||
|
||||
const max = Buffer.alloc(sodium.crypto_generichash_BYTES_MAX)
|
||||
sodium.crypto_generichash(max, buf)
|
||||
|
||||
const res = '7dfdb888af71eae0e6a6b751e8e3413d767ef4fa52a7993daa9ef097f7aa3d949199c113caa37c94f80cf3b22f7d9d6e4f5def4ff927830cffe4857c34be3d89'
|
||||
t.alike(max.toString('hex'), res, 'hashed buffer max')
|
||||
})
|
||||
|
||||
test('crypto_generichash with key', function (t) {
|
||||
const buf = Buffer.from('Hello, World!')
|
||||
const key = Buffer.alloc(sodium.crypto_generichash_KEYBYTES)
|
||||
|
||||
key.fill('lo')
|
||||
|
||||
const out = Buffer.alloc(sodium.crypto_generichash_BYTES)
|
||||
sodium.crypto_generichash(out, buf, key)
|
||||
|
||||
t.alike(out.toString('hex'), 'f4113fe33d43c24c54627d40efa1a78838d4a6d689fd6e83c213848904fffa8c', 'hashed buffer')
|
||||
|
||||
const min = Buffer.alloc(sodium.crypto_generichash_BYTES_MIN)
|
||||
sodium.crypto_generichash(min, buf, key)
|
||||
|
||||
t.alike(min.toString('hex'), 'c8226257b0d1c3dcf4bbc3ef79574689', 'hashed buffer min')
|
||||
|
||||
const max = Buffer.alloc(sodium.crypto_generichash_BYTES_MAX)
|
||||
sodium.crypto_generichash(max, buf, key)
|
||||
|
||||
const res = '763eda46f4c6c61abb4310eb8a488950e9e0667b2fca03c463dc7489e94f065b7af6063fe86b0441c3eb9052800121d55730412abb2cbe0761b1d66f9b047c1c'
|
||||
t.alike(max.toString('hex'), res, 'hashed buffer max')
|
||||
})
|
||||
|
||||
test.skip('crypto_generichash_state', function (t) {
|
||||
const state = Buffer.alloc(sodium.crypto_generichash_STATEBYTES)
|
||||
sodium.crypto_generichash_init(state, null, sodium.crypto_generichash_BYTES)
|
||||
|
||||
const buf = Buffer.from('Hej, Verden')
|
||||
|
||||
for (let i = 0; i < 10; i++) sodium.crypto_generichash_update(state, buf)
|
||||
|
||||
const out = Buffer.alloc(sodium.crypto_generichash_BYTES)
|
||||
sodium.crypto_generichash_final(state, out)
|
||||
|
||||
t.alike(out.toString('hex'), 'cbc20f347f5dfe37dc13231cbf7eaa4ec48e585ec055a96839b213f62bd8ce00', 'streaming hash')
|
||||
})
|
||||
|
||||
test.skip('crypto_generichash state with key', function (t) {
|
||||
const key = Buffer.alloc(sodium.crypto_generichash_KEYBYTES)
|
||||
key.fill('lo')
|
||||
|
||||
const state = Buffer.alloc(sodium.crypto_generichash_STATEBYTES)
|
||||
sodium.crypto_generichash_init(state, key, sodium.crypto_generichash_BYTES)
|
||||
|
||||
const buf = Buffer.from('Hej, Verden')
|
||||
|
||||
for (let i = 0; i < 10; i++) sodium.crypto_generichash_update(state, buf)
|
||||
|
||||
const out = Buffer.alloc(sodium.crypto_generichash_BYTES)
|
||||
sodium.crypto_generichash_final(state, out)
|
||||
|
||||
t.alike(out.toString('hex'), '405f14acbeeb30396b8030f78e6a84bab0acf08cb1376aa200a500f669f675dc', 'streaming keyed hash')
|
||||
})
|
||||
|
||||
test.skip('crypto_generichash state with hash length', function (t) {
|
||||
const state = Buffer.alloc(sodium.crypto_generichash_STATEBYTES)
|
||||
sodium.crypto_generichash_init(state, null, sodium.crypto_generichash_BYTES_MIN)
|
||||
|
||||
const buf = Buffer.from('Hej, Verden')
|
||||
|
||||
for (let i = 0; i < 10; i++) sodium.crypto_generichash_update(state, buf)
|
||||
|
||||
const out = Buffer.alloc(sodium.crypto_generichash_BYTES_MIN)
|
||||
sodium.crypto_generichash_final(state, out)
|
||||
|
||||
t.alike(out.toString('hex'), 'decacdcc3c61948c79d9f8dee5b6aa99', 'streaming short hash')
|
||||
})
|
||||
|
||||
test.skip('crypto_generichash state with key and hash length', function (t) {
|
||||
const key = Buffer.alloc(sodium.crypto_generichash_KEYBYTES)
|
||||
key.fill('lo')
|
||||
|
||||
const state = Buffer.alloc(sodium.crypto_generichash_STATEBYTES)
|
||||
sodium.crypto_generichash_init(state, key, sodium.crypto_generichash_BYTES_MIN)
|
||||
|
||||
const buf = Buffer.from('Hej, Verden')
|
||||
|
||||
for (let i = 0; i < 10; i++) sodium.crypto_generichash_update(state, buf)
|
||||
|
||||
const out = Buffer.alloc(sodium.crypto_generichash_BYTES_MIN)
|
||||
sodium.crypto_generichash_final(state, out)
|
||||
|
||||
t.alike(out.toString('hex'), 'fb43f0ab6872cbfd39ec4f8a1bc6fb37', 'streaming short keyed hash')
|
||||
})
|
||||
|
||||
test('crypto_generichash_batch', function (t) {
|
||||
const buf = Buffer.from('Hej, Verden')
|
||||
const batch = []
|
||||
for (let i = 0; i < 10; i++) batch.push(buf)
|
||||
|
||||
const out = Buffer.alloc(sodium.crypto_generichash_BYTES)
|
||||
sodium.crypto_generichash_batch(out, batch)
|
||||
|
||||
t.alike(out.toString('hex'), 'cbc20f347f5dfe37dc13231cbf7eaa4ec48e585ec055a96839b213f62bd8ce00', 'batch hash')
|
||||
})
|
||||
|
||||
test('crypto_generichash_batch with key', function (t) {
|
||||
const key = Buffer.alloc(sodium.crypto_generichash_KEYBYTES)
|
||||
key.fill('lo')
|
||||
|
||||
const buf = Buffer.from('Hej, Verden')
|
||||
const batch = []
|
||||
for (let i = 0; i < 10; i++) batch.push(buf)
|
||||
|
||||
const out = Buffer.alloc(sodium.crypto_generichash_BYTES)
|
||||
sodium.crypto_generichash_batch(out, batch, key)
|
||||
|
||||
t.alike(out.toString('hex'), '405f14acbeeb30396b8030f78e6a84bab0acf08cb1376aa200a500f669f675dc', 'batch keyed hash')
|
||||
})
|
||||
@@ -0,0 +1,17 @@
|
||||
/* eslint-disable camelcase */
|
||||
const test = require('brittle')
|
||||
const sodium = require('..')
|
||||
|
||||
test('crypto_hash', function (t) {
|
||||
const out = Buffer.alloc(sodium.crypto_hash_BYTES)
|
||||
const inp = Buffer.from('Hej, Verden!')
|
||||
|
||||
t.exception.all(function () {
|
||||
sodium.crypto_hash(Buffer.alloc(0), inp)
|
||||
}, 'throws on bad input')
|
||||
|
||||
sodium.crypto_hash(out, inp)
|
||||
|
||||
const result = 'bcf8e6d11dec2da6e93abb99a73c8e9c387886a5f84fbca5e25af85af26ee39161b7e0c9f9cf547f2aef40523f1aab80e26ec3c630db43ce78adc8c058dc5d16'
|
||||
t.alike(out.toString('hex'), result, 'hashed the string')
|
||||
})
|
||||
@@ -0,0 +1,32 @@
|
||||
/* eslint-disable camelcase */
|
||||
const test = require('brittle')
|
||||
const sodium = require('..')
|
||||
|
||||
test('crypto_hash_sha256', function (t) {
|
||||
const out = Buffer.alloc(sodium.crypto_hash_sha256_BYTES)
|
||||
const inp = Buffer.from('Hej, Verden!')
|
||||
|
||||
t.exception.all(function () {
|
||||
sodium.crypto_hash(Buffer.alloc(0), inp)
|
||||
}, 'throws on bad input')
|
||||
|
||||
sodium.crypto_hash_sha256(out, inp)
|
||||
|
||||
const result = 'f0704b1e832b05d01223952fb2512181af4f843ce7bb6b443afd5ea028010e6c'
|
||||
t.alike(out.toString('hex'), result, 'hashed the string')
|
||||
})
|
||||
|
||||
test.skip('crypto_hash_sha256_state', function (t) {
|
||||
const state = Buffer.alloc(sodium.crypto_hash_sha256_STATEBYTES)
|
||||
sodium.crypto_hash_sha256_init(state)
|
||||
|
||||
const buf = Buffer.from('Hej, Verden!')
|
||||
|
||||
for (let i = 0; i < 10; i++) sodium.crypto_hash_sha256_update(state, buf)
|
||||
|
||||
const out = Buffer.alloc(sodium.crypto_hash_sha256_BYTES)
|
||||
sodium.crypto_hash_sha256_final(state, out)
|
||||
|
||||
const result = '14207db33c6ac7d39ca5fe0e74432fa7a2ed15caf7f6ab5ef68d24017a899974'
|
||||
t.alike(out.toString('hex'), result, 'hashed the string')
|
||||
})
|
||||
@@ -0,0 +1,32 @@
|
||||
/* eslint-disable camelcase */
|
||||
const test = require('brittle')
|
||||
const sodium = require('..')
|
||||
|
||||
test('crypto_hash_sha512', function (t) {
|
||||
const out = Buffer.alloc(sodium.crypto_hash_sha512_BYTES)
|
||||
const inp = Buffer.from('Hej, Verden!')
|
||||
|
||||
t.exception.all(function () {
|
||||
sodium.crypto_hash(Buffer.alloc(0), inp)
|
||||
}, 'throws on bad input')
|
||||
|
||||
sodium.crypto_hash_sha512(out, inp)
|
||||
|
||||
const result = 'bcf8e6d11dec2da6e93abb99a73c8e9c387886a5f84fbca5e25af85af26ee39161b7e0c9f9cf547f2aef40523f1aab80e26ec3c630db43ce78adc8c058dc5d16'
|
||||
t.alike(out.toString('hex'), result, 'hashed the string')
|
||||
})
|
||||
|
||||
test.skip('crypto_hash_sha512_state', function (t) {
|
||||
const state = Buffer.alloc(sodium.crypto_hash_sha512_STATEBYTES)
|
||||
sodium.crypto_hash_sha512_init(state)
|
||||
|
||||
const buf = Buffer.from('Hej, Verden!')
|
||||
|
||||
for (let i = 0; i < 10; i++) sodium.crypto_hash_sha512_update(state, buf)
|
||||
|
||||
const out = Buffer.alloc(sodium.crypto_hash_sha512_BYTES)
|
||||
sodium.crypto_hash_sha512_final(state, out)
|
||||
|
||||
const result = 'a0a9b965c23be41fa8c344f483da39bedcf88b7f25cdc0bc9ea335fa264dc3db51f08c1d0f5f6f0ffb08a1d8643e2a1cd0ea8f03408ca03711c751d61787a229'
|
||||
t.alike(out.toString('hex'), result, 'hashed the string')
|
||||
})
|
||||
@@ -0,0 +1,71 @@
|
||||
/* eslint-disable camelcase */
|
||||
const test = require('brittle')
|
||||
const sodium = require('..')
|
||||
|
||||
test('crypto_kdf_keygen', function (t) {
|
||||
const key = Buffer.alloc(sodium.crypto_kdf_KEYBYTES)
|
||||
|
||||
t.exception.all(function () {
|
||||
sodium.crypto_kdf_keygen(Buffer.alloc(1))
|
||||
})
|
||||
|
||||
sodium.crypto_kdf_keygen(key)
|
||||
|
||||
t.not(key, Buffer.alloc(key.length))
|
||||
})
|
||||
|
||||
test('crypto_kdf_derive_from_key', function (t) {
|
||||
const key = Buffer.alloc(sodium.crypto_kdf_KEYBYTES)
|
||||
|
||||
sodium.crypto_kdf_keygen(key)
|
||||
|
||||
const subkey = Buffer.alloc(sodium.crypto_kdf_BYTES_MIN)
|
||||
|
||||
sodium.crypto_kdf_derive_from_key(subkey, 0, Buffer.from('context_'), key)
|
||||
t.not(subkey, Buffer.alloc(subkey.length))
|
||||
|
||||
const subkey2 = Buffer.alloc(sodium.crypto_kdf_BYTES_MIN)
|
||||
|
||||
sodium.crypto_kdf_derive_from_key(subkey2, 1, Buffer.from('context_'), key)
|
||||
t.not(subkey, subkey2)
|
||||
|
||||
sodium.crypto_kdf_derive_from_key(subkey2, 0, Buffer.from('context_'), key)
|
||||
t.alike(subkey, subkey2)
|
||||
})
|
||||
|
||||
test('test vectors', function (assert) {
|
||||
const fixtures = require('./fixtures/crypto_kdf.json')
|
||||
|
||||
for (let i = 0; i < fixtures.length; i++) {
|
||||
const key = Buffer.from(fixtures[i].key, 'hex')
|
||||
const subkeyLen = fixtures[i].subkey_len
|
||||
const id = fixtures[i].id
|
||||
const context = Buffer.from(fixtures[i].context, 'hex')
|
||||
|
||||
const shouldError = fixtures[i].error
|
||||
|
||||
const actual = Buffer.alloc(subkeyLen)
|
||||
|
||||
try {
|
||||
sodium.crypto_kdf_derive_from_key(actual, id, context, key)
|
||||
const expected = Buffer.from(fixtures[i].subkey, 'hex')
|
||||
if (Buffer.compare(actual, expected) !== 0) {
|
||||
assert.fail('Failed on fixture #' + i)
|
||||
}
|
||||
} catch (ex) {
|
||||
if (shouldError === false) assert.fail('Failed on fixture #' + i)
|
||||
}
|
||||
}
|
||||
|
||||
assert.pass('Passed all fixtures')
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test('constants', function (t) {
|
||||
t.ok(sodium.crypto_kdf_PRIMITIVE)
|
||||
t.ok(sodium.crypto_kdf_BYTES_MAX > 0)
|
||||
t.ok(sodium.crypto_kdf_BYTES_MIN <= sodium.crypto_kdf_BYTES_MAX)
|
||||
t.ok(sodium.crypto_kdf_CONTEXTBYTES > 0)
|
||||
t.ok(sodium.crypto_kdf_KEYBYTES >= 16)
|
||||
t.end()
|
||||
})
|
||||
@@ -0,0 +1,265 @@
|
||||
/* eslint-disable camelcase */
|
||||
const test = require('brittle')
|
||||
const sodium = require('..')
|
||||
|
||||
test('crypto_kx_seed_keypair', function (t) {
|
||||
const pk = Buffer.alloc(sodium.crypto_kx_PUBLICKEYBYTES)
|
||||
const sk = Buffer.alloc(sodium.crypto_kx_SECRETKEYBYTES)
|
||||
const seed = Buffer.alloc(sodium.crypto_kx_SEEDBYTES, 'lo')
|
||||
|
||||
t.exception.all(function () {
|
||||
sodium.crypto_kx_seed_keypair()
|
||||
}, 'should validate input')
|
||||
|
||||
t.exception.all(function () {
|
||||
sodium.crypto_kx_seed_keypair(Buffer.alloc(0), Buffer.alloc(0), Buffer.alloc(0))
|
||||
}, 'should validate input length')
|
||||
|
||||
sodium.crypto_kx_seed_keypair(pk, sk, seed)
|
||||
|
||||
const eSk = '768475983073421d5b1676c4aabb24fdf17c3a5f19e6e9e9cdefbfeb45ceb153'
|
||||
const ePk = '0cd703bbd6b1d46dc431a1fc4f1f7724c64b1d4c471e8c17de4966c9e15bf85e'
|
||||
|
||||
t.alike(pk.toString('hex'), ePk, 'seeded public key')
|
||||
t.alike(sk.toString('hex'), eSk, 'seeded secret key')
|
||||
})
|
||||
|
||||
test('crypto_kx_keypair', function (t) {
|
||||
const pk = Buffer.alloc(sodium.crypto_kx_PUBLICKEYBYTES)
|
||||
const sk = Buffer.alloc(sodium.crypto_kx_SECRETKEYBYTES)
|
||||
|
||||
sodium.crypto_kx_keypair(pk, sk)
|
||||
|
||||
t.not(pk, Buffer.alloc(pk.length), 'made public key')
|
||||
t.not(sk, Buffer.alloc(sk.length), 'made secret key')
|
||||
|
||||
t.exception.all(function () {
|
||||
sodium.crypto_kx_keypair()
|
||||
}, 'should validate input')
|
||||
|
||||
t.exception.all(function () {
|
||||
sodium.crypto_kx_keypair(Buffer.alloc(0), Buffer.alloc(0))
|
||||
}, 'should validate input length')
|
||||
})
|
||||
|
||||
test.skip('crypto_kx_client_session_keys', function (t) {
|
||||
const clientPk = Buffer.alloc(sodium.crypto_kx_PUBLICKEYBYTES)
|
||||
const clientSk = Buffer.alloc(sodium.crypto_kx_SECRETKEYBYTES)
|
||||
const serverPk = Buffer.alloc(sodium.crypto_kx_PUBLICKEYBYTES)
|
||||
const serverSk = Buffer.alloc(sodium.crypto_kx_SECRETKEYBYTES)
|
||||
|
||||
const serverRx = Buffer.alloc(sodium.crypto_kx_SESSIONKEYBYTES)
|
||||
const serverTx = Buffer.alloc(sodium.crypto_kx_SESSIONKEYBYTES)
|
||||
|
||||
const clientRx = Buffer.alloc(sodium.crypto_kx_SESSIONKEYBYTES)
|
||||
const clientTx = Buffer.alloc(sodium.crypto_kx_SESSIONKEYBYTES)
|
||||
|
||||
sodium.crypto_kx_keypair(serverPk, serverSk)
|
||||
sodium.crypto_kx_keypair(clientPk, clientSk)
|
||||
|
||||
t.exception.all(function () {
|
||||
sodium.crypto_kx_client_session_keys()
|
||||
}, 'should validate')
|
||||
|
||||
t.exception.all(function () {
|
||||
sodium.crypto_kx_server_session_keys()
|
||||
}, 'should validate')
|
||||
|
||||
sodium.crypto_kx_client_session_keys(clientRx, clientTx, clientPk, clientSk, serverPk)
|
||||
sodium.crypto_kx_server_session_keys(serverRx, serverTx, serverPk, serverSk, clientPk)
|
||||
|
||||
t.alike(clientRx, serverTx)
|
||||
t.alike(clientTx, serverRx)
|
||||
})
|
||||
|
||||
test.skip('crypto_kx_client_session_keys one NULL', function (t) {
|
||||
const clientPk = Buffer.alloc(sodium.crypto_kx_PUBLICKEYBYTES)
|
||||
const clientSk = Buffer.alloc(sodium.crypto_kx_SECRETKEYBYTES)
|
||||
const serverPk = Buffer.alloc(sodium.crypto_kx_PUBLICKEYBYTES)
|
||||
const serverSk = Buffer.alloc(sodium.crypto_kx_SECRETKEYBYTES)
|
||||
|
||||
const serverRx = Buffer.alloc(sodium.crypto_kx_SESSIONKEYBYTES)
|
||||
const serverTx = Buffer.alloc(sodium.crypto_kx_SESSIONKEYBYTES)
|
||||
|
||||
const clientRx = Buffer.alloc(sodium.crypto_kx_SESSIONKEYBYTES)
|
||||
const clientTx = Buffer.alloc(sodium.crypto_kx_SESSIONKEYBYTES)
|
||||
|
||||
sodium.crypto_kx_keypair(serverPk, serverSk)
|
||||
sodium.crypto_kx_keypair(clientPk, clientSk)
|
||||
|
||||
t.exception.all(function () {
|
||||
sodium.crypto_kx_client_session_keys()
|
||||
}, 'should validate')
|
||||
|
||||
t.exception.all(function () {
|
||||
sodium.crypto_kx_server_session_keys()
|
||||
}, 'should validate')
|
||||
|
||||
t.exception(function () {
|
||||
sodium.crypto_kx_server_session_keys(null, null, clientPk, clientSk, serverPk)
|
||||
}, 'should validate')
|
||||
|
||||
t.exception(function () {
|
||||
sodium.crypto_kx_client_session_keys(null, null, clientPk, clientSk, serverPk)
|
||||
}, 'should validate')
|
||||
|
||||
sodium.crypto_kx_client_session_keys(clientRx, null, clientPk, clientSk, serverPk)
|
||||
sodium.crypto_kx_server_session_keys(null, serverTx, serverPk, serverSk, clientPk)
|
||||
|
||||
t.alike(clientRx, serverTx)
|
||||
|
||||
sodium.crypto_kx_client_session_keys(null, clientTx, clientPk, clientSk, serverPk)
|
||||
sodium.crypto_kx_server_session_keys(serverRx, null, serverPk, serverSk, clientPk)
|
||||
t.alike(clientTx, serverRx)
|
||||
})
|
||||
|
||||
test('crypto_kx constants', function (t) {
|
||||
t.alike(typeof sodium.crypto_kx_SESSIONKEYBYTES, 'number')
|
||||
t.alike(typeof sodium.crypto_kx_PUBLICKEYBYTES, 'number')
|
||||
t.alike(typeof sodium.crypto_kx_SECRETKEYBYTES, 'number')
|
||||
t.alike(typeof sodium.crypto_kx_SEEDBYTES, 'number')
|
||||
t.alike(typeof sodium.crypto_kx_PRIMITIVE, 'string')
|
||||
|
||||
t.is(sodium.crypto_kx_SEEDBYTES, 32)
|
||||
t.is(sodium.crypto_kx_PUBLICKEYBYTES, 32)
|
||||
t.is(sodium.crypto_kx_SESSIONKEYBYTES, 32)
|
||||
t.is(sodium.crypto_kx_SECRETKEYBYTES, 32)
|
||||
|
||||
t.end()
|
||||
})
|
||||
|
||||
/* eslint-disable camelcase */
|
||||
test.skip('libsodium', function (t) {
|
||||
const small_order_p = new Uint8Array([
|
||||
0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3,
|
||||
0xfa, 0xf1, 0x9f, 0xc4, 0x6a, 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32,
|
||||
0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00
|
||||
])
|
||||
|
||||
const seed = new Uint8Array(sodium.crypto_kx_SEEDBYTES)
|
||||
const client_pk = new Uint8Array(sodium.crypto_kx_PUBLICKEYBYTES)
|
||||
const client_sk = new Uint8Array(sodium.crypto_kx_SECRETKEYBYTES)
|
||||
const client_rx = new Uint8Array(sodium.crypto_kx_SESSIONKEYBYTES)
|
||||
const client_tx = new Uint8Array(sodium.crypto_kx_SESSIONKEYBYTES)
|
||||
const server_pk = new Uint8Array(sodium.crypto_kx_PUBLICKEYBYTES)
|
||||
const server_sk = new Uint8Array(sodium.crypto_kx_SECRETKEYBYTES)
|
||||
const server_rx = new Uint8Array(sodium.crypto_kx_SESSIONKEYBYTES)
|
||||
const server_tx = new Uint8Array(sodium.crypto_kx_SESSIONKEYBYTES)
|
||||
|
||||
for (let i = 0; i < sodium.crypto_kx_SEEDBYTES; i++) {
|
||||
seed[i] = i
|
||||
}
|
||||
|
||||
sodium.crypto_kx_seed_keypair(client_pk, client_sk, seed)
|
||||
|
||||
const exp1 = new Uint8Array([
|
||||
0x0e, 0x02, 0x16, 0x22, 0x3f, 0x14, 0x71, 0x43, 0xd3, 0x26, 0x15,
|
||||
0xa9, 0x11, 0x89, 0xc2, 0x88, 0xc1, 0x72, 0x8c, 0xba, 0x3c, 0xc5,
|
||||
0xf9, 0xf6, 0x21, 0xb1, 0x02, 0x6e, 0x03, 0xd8, 0x31, 0x29
|
||||
])
|
||||
|
||||
const exp2 = new Uint8Array([
|
||||
0xcb, 0x2f, 0x51, 0x60, 0xfc, 0x1f, 0x7e, 0x05, 0xa5, 0x5e, 0xf4,
|
||||
0x9d, 0x34, 0x0b, 0x48, 0xda, 0x2e, 0x5a, 0x78, 0x09, 0x9d, 0x53,
|
||||
0x39, 0x33, 0x51, 0xcd, 0x57, 0x9d, 0xd4, 0x25, 0x03, 0xd6
|
||||
])
|
||||
|
||||
t.alike(client_pk, exp1, 'client_pk')
|
||||
t.alike(client_sk, exp2, 'client_pk')
|
||||
|
||||
sodium.crypto_kx_keypair(server_pk, server_sk)
|
||||
|
||||
t.exception(() => {
|
||||
sodium.crypto_kx_client_session_keys(client_rx, client_tx, client_pk, client_sk, small_order_p)
|
||||
})
|
||||
|
||||
t.execution(() => {
|
||||
sodium.crypto_kx_client_session_keys(client_rx, client_tx, client_pk, client_sk, server_pk)
|
||||
})
|
||||
|
||||
t.exception(() => sodium.crypto_kx_server_session_keys(server_rx, server_tx, server_pk, server_sk, small_order_p))
|
||||
t.execution(() => {
|
||||
sodium.crypto_kx_server_session_keys(server_rx, server_tx, server_pk, server_sk, client_pk)
|
||||
})
|
||||
|
||||
t.alike(server_rx, client_tx)
|
||||
t.alike(server_tx, client_rx)
|
||||
|
||||
sodium.sodium_increment(client_pk)
|
||||
|
||||
t.execution(() => {
|
||||
sodium.crypto_kx_server_session_keys(server_rx, server_tx, server_pk, server_sk, client_pk)
|
||||
})
|
||||
|
||||
t.unlike(server_rx, client_tx)
|
||||
t.unlike(server_tx, client_rx)
|
||||
|
||||
sodium.crypto_kx_keypair(client_pk, client_sk)
|
||||
|
||||
t.execution(() => {
|
||||
sodium.crypto_kx_server_session_keys(server_rx, server_tx, server_pk, server_sk, client_pk)
|
||||
})
|
||||
|
||||
t.unlike(server_rx, client_tx)
|
||||
t.unlike(server_tx, client_rx)
|
||||
|
||||
sodium.crypto_kx_seed_keypair(client_pk, client_sk, seed)
|
||||
sodium.sodium_increment(seed)
|
||||
|
||||
sodium.crypto_kx_seed_keypair(server_pk, server_sk, seed)
|
||||
t.execution(() => {
|
||||
sodium.crypto_kx_server_session_keys(server_rx, server_tx, server_pk, server_sk, client_pk)
|
||||
})
|
||||
|
||||
const exp3 = new Uint8Array([
|
||||
0x62, 0xc8, 0xf4, 0xfa, 0x81, 0x80, 0x0a, 0xbd, 0x05, 0x77, 0xd9,
|
||||
0x99, 0x18, 0xd1, 0x29, 0xb6, 0x5d, 0xeb, 0x78, 0x9a, 0xf8, 0xc8,
|
||||
0x35, 0x1f, 0x39, 0x1f, 0xeb, 0x0c, 0xbf, 0x23, 0x86, 0x04
|
||||
])
|
||||
|
||||
const exp4 = new Uint8Array([
|
||||
0x74, 0x95, 0x19, 0xc6, 0x80, 0x59, 0xbc, 0xe6, 0x9f, 0x7c, 0xfc,
|
||||
0xc7, 0xb3, 0x87, 0xa3, 0xde, 0x1a, 0x1e, 0x82, 0x37, 0xd1, 0x10,
|
||||
0x99, 0x13, 0x23, 0xbf, 0x62, 0x87, 0x01, 0x15, 0x73, 0x1a
|
||||
])
|
||||
|
||||
t.alike(server_rx, exp3)
|
||||
t.alike(server_tx, exp4)
|
||||
|
||||
t.execution(() => {
|
||||
sodium.crypto_kx_client_session_keys(client_rx, client_tx, client_pk, client_sk, server_pk)
|
||||
})
|
||||
|
||||
const exp5 = new Uint8Array([
|
||||
0x74, 0x95, 0x19, 0xc6, 0x80, 0x59, 0xbc, 0xe6, 0x9f, 0x7c, 0xfc,
|
||||
0xc7, 0xb3, 0x87, 0xa3, 0xde, 0x1a, 0x1e, 0x82, 0x37, 0xd1, 0x10,
|
||||
0x99, 0x13, 0x23, 0xbf, 0x62, 0x87, 0x01, 0x15, 0x73, 0x1a
|
||||
])
|
||||
|
||||
const exp6 = new Uint8Array([
|
||||
0x62, 0xc8, 0xf4, 0xfa, 0x81, 0x80, 0x0a, 0xbd, 0x05, 0x77, 0xd9,
|
||||
0x99, 0x18, 0xd1, 0x29, 0xb6, 0x5d, 0xeb, 0x78, 0x9a, 0xf8, 0xc8,
|
||||
0x35, 0x1f, 0x39, 0x1f, 0xeb, 0x0c, 0xbf, 0x23, 0x86, 0x04
|
||||
])
|
||||
|
||||
t.alike(client_rx, exp5)
|
||||
t.alike(client_tx, exp6)
|
||||
|
||||
sodium.randombytes_buf(client_rx)
|
||||
sodium.randombytes_buf(client_tx)
|
||||
sodium.randombytes_buf(server_rx)
|
||||
sodium.randombytes_buf(server_tx)
|
||||
|
||||
t.execution(() => sodium.crypto_kx_client_session_keys(client_rx, null,
|
||||
client_pk, client_sk, server_pk))
|
||||
t.execution(() => sodium.crypto_kx_client_session_keys(null, client_tx,
|
||||
client_pk, client_sk, server_pk))
|
||||
t.execution(() => sodium.crypto_kx_server_session_keys(server_rx, null,
|
||||
server_pk, server_sk, client_pk))
|
||||
t.execution(() => sodium.crypto_kx_server_session_keys(null, server_tx,
|
||||
server_pk, server_sk, client_pk))
|
||||
|
||||
t.alike(client_rx, client_tx)
|
||||
t.alike(client_tx, server_rx)
|
||||
t.alike(server_rx, server_tx)
|
||||
})
|
||||
@@ -0,0 +1,37 @@
|
||||
/* eslint-disable camelcase */
|
||||
const test = require('brittle')
|
||||
const sodium = require('..')
|
||||
|
||||
test('crypto_onetimeauth', function (t) {
|
||||
const key = Buffer.alloc(sodium.crypto_onetimeauth_KEYBYTES)
|
||||
const mac = Buffer.alloc(sodium.crypto_onetimeauth_BYTES)
|
||||
const value = Buffer.from('Hello, World!')
|
||||
|
||||
sodium.randombytes_buf(key)
|
||||
sodium.crypto_onetimeauth(mac, value, key)
|
||||
|
||||
t.not(mac, Buffer.alloc(mac.length), 'not blank')
|
||||
t.absent(sodium.crypto_onetimeauth_verify(Buffer.alloc(mac.length), value, key), 'does not verify')
|
||||
t.ok(sodium.crypto_onetimeauth_verify(mac, value, key), 'verifies')
|
||||
})
|
||||
|
||||
test.skip('crypto_onetimeauth_state', function (t) {
|
||||
const key = Buffer.alloc(sodium.crypto_onetimeauth_KEYBYTES, 'lo')
|
||||
const state = Buffer.alloc(sodium.crypto_onetimeauth_STATEBYTES)
|
||||
|
||||
t.exception.all(function () {
|
||||
sodium.crypto_onetimeauth_init(state)
|
||||
}, 'key required')
|
||||
|
||||
key[0] = 42
|
||||
|
||||
sodium.crypto_onetimeauth_init(state, key)
|
||||
const value = Buffer.from('Hello, World!')
|
||||
|
||||
for (let i = 0; i < 10; i++) sodium.crypto_onetimeauth_update(state, value)
|
||||
|
||||
const mac = Buffer.alloc(sodium.crypto_onetimeauth_BYTES)
|
||||
sodium.crypto_onetimeauth_final(state, mac)
|
||||
|
||||
t.alike(mac.toString('hex'), 'ac35df70e6b95051e015de11a6cbf4ab', 'streaming mac')
|
||||
})
|
||||
@@ -0,0 +1,226 @@
|
||||
const test = require('brittle')
|
||||
const sodium = require('..')
|
||||
|
||||
test('constants', function (t) {
|
||||
t.ok(sodium.crypto_pwhash_ALG_ARGON2I13 != null, 'crypto_pwhash_ALG_ARGON2I13 is defined')
|
||||
t.ok(sodium.crypto_pwhash_ALG_ARGON2ID13 != null, 'crypto_pwhash_ALG_ARGON2ID13 is defined')
|
||||
t.ok(sodium.crypto_pwhash_ALG_DEFAULT === sodium.crypto_pwhash_ALG_ARGON2ID13, 'crypto_pwhash_ALG_DEFAULT is crypto_pwhash_ALG_ARGON2ID13')
|
||||
t.ok(sodium.crypto_pwhash_BYTES_MIN != null, 'crypto_pwhash_BYTES_MIN is defined')
|
||||
t.ok(sodium.crypto_pwhash_BYTES_MAX != null, 'crypto_pwhash_BYTES_MAX is defined')
|
||||
t.ok(sodium.crypto_pwhash_PASSWD_MIN != null, 'crypto_pwhash_PASSWD_MIN is defined')
|
||||
t.ok(sodium.crypto_pwhash_PASSWD_MAX != null, 'crypto_pwhash_PASSWD_MAX is defined')
|
||||
t.ok(sodium.crypto_pwhash_SALTBYTES != null, 'crypto_pwhash_SALTBYTES is defined')
|
||||
t.ok(sodium.crypto_pwhash_STRBYTES != null, 'crypto_pwhash_STRBYTES is defined')
|
||||
|
||||
t.ok(sodium.crypto_pwhash_OPSLIMIT_MIN != null, 'crypto_pwhash_OPSLIMIT_MIN is defined')
|
||||
t.ok(sodium.crypto_pwhash_OPSLIMIT_MAX != null, 'crypto_pwhash_OPSLIMIT_MAX is defined')
|
||||
t.ok(sodium.crypto_pwhash_MEMLIMIT_MIN != null, 'crypto_pwhash_MEMLIMIT_MIN is defined')
|
||||
t.ok(sodium.crypto_pwhash_MEMLIMIT_MAX != null, 'crypto_pwhash_MEMLIMIT_MAX is defined')
|
||||
t.ok(sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE != null, 'crypto_pwhash_OPSLIMIT_INTERACTIVE is defined')
|
||||
t.ok(sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE != null, 'crypto_pwhash_MEMLIMIT_INTERACTIVE is defined')
|
||||
t.ok(sodium.crypto_pwhash_OPSLIMIT_MODERATE != null, 'crypto_pwhash_OPSLIMIT_MODERATE is defined')
|
||||
t.ok(sodium.crypto_pwhash_MEMLIMIT_MODERATE != null, 'crypto_pwhash_MEMLIMIT_MODERATE is defined')
|
||||
t.ok(sodium.crypto_pwhash_OPSLIMIT_SENSITIVE != null, 'crypto_pwhash_OPSLIMIT_SENSITIVE is defined')
|
||||
t.ok(sodium.crypto_pwhash_MEMLIMIT_SENSITIVE != null, 'crypto_pwhash_MEMLIMIT_SENSITIVE is defined')
|
||||
})
|
||||
|
||||
test('crypto_pwhash', function (t) {
|
||||
const output = Buffer.alloc(32) // can be any size
|
||||
const passwd = Buffer.from('Hej, Verden!')
|
||||
const salt = Buffer.alloc(sodium.crypto_pwhash_SALTBYTES, 'lo')
|
||||
const opslimit = sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE
|
||||
const memlimit = sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE
|
||||
const algo = sodium.crypto_pwhash_ALG_DEFAULT
|
||||
|
||||
sodium.crypto_pwhash(output, passwd, salt, opslimit, memlimit, algo)
|
||||
|
||||
t.alike(output.toString('hex'), 'f0236e17ec70050fc989f19d8ce640301e8f912154b4f0afc1552cdf246e659f', 'hashes password')
|
||||
|
||||
salt[0] = 0
|
||||
sodium.crypto_pwhash(output, passwd, salt, opslimit, memlimit, algo)
|
||||
|
||||
t.alike(output.toString('hex'), 'df73f15d217196311d4b1aa6fba339905ffe581dee4bd3a95ec2bb7c52991d65', 'diff salt -> diff hash')
|
||||
})
|
||||
|
||||
test('crypto_pwhash_str', function (t) {
|
||||
const output = Buffer.alloc(sodium.crypto_pwhash_STRBYTES)
|
||||
const passwd = Buffer.from('Hej, Verden!')
|
||||
const opslimit = sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE
|
||||
const memlimit = sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE
|
||||
|
||||
t.exception.all(function () {
|
||||
sodium.crypto_pwhash_str(output, passwd)
|
||||
}, 'should throw on missing args')
|
||||
|
||||
sodium.crypto_pwhash_str(output, passwd, opslimit, memlimit)
|
||||
|
||||
t.not(output, Buffer.alloc(output.length), 'not blank')
|
||||
t.absent(sodium.crypto_pwhash_str_verify(Buffer.alloc(output.length), passwd), 'does not verify')
|
||||
t.ok(sodium.crypto_pwhash_str_verify(output, passwd), 'verifies')
|
||||
})
|
||||
|
||||
test('crypto_pwhash_str_needs_rehash', function (t) {
|
||||
const passwd = Buffer.from('secret')
|
||||
const weakMem = Buffer.alloc(sodium.crypto_pwhash_STRBYTES)
|
||||
const weakOps = Buffer.alloc(sodium.crypto_pwhash_STRBYTES)
|
||||
const malformed = Buffer.alloc(sodium.crypto_pwhash_STRBYTES)
|
||||
const good = Buffer.alloc(sodium.crypto_pwhash_STRBYTES)
|
||||
const weakAlg = Buffer.alloc(sodium.crypto_pwhash_STRBYTES)
|
||||
weakAlg.set(Buffer.from('$argon2id$v=19$m=8,t=1,p=1$DF4Tce8BK5di0gKeMBb2Fw$uNE4oyvyA0z68RPUom2NXu/KyGvpFppyUoN6pwFBtRU'))
|
||||
|
||||
sodium.crypto_pwhash_str(weakMem, passwd, sodium.crypto_pwhash_OPSLIMIT_MODERATE, sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE)
|
||||
sodium.crypto_pwhash_str(weakOps, passwd, sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE, sodium.crypto_pwhash_MEMLIMIT_MODERATE)
|
||||
sodium.crypto_pwhash_str(malformed, passwd, sodium.crypto_pwhash_OPSLIMIT_MODERATE, sodium.crypto_pwhash_MEMLIMIT_MODERATE)
|
||||
sodium.crypto_pwhash_str(good, passwd, sodium.crypto_pwhash_OPSLIMIT_MODERATE, sodium.crypto_pwhash_MEMLIMIT_MODERATE)
|
||||
|
||||
const first$ = malformed.indexOf('$')
|
||||
const second$ = malformed.indexOf('$', first$ + 1)
|
||||
malformed.fill('p=,m=,', first$, second$, 'ascii')
|
||||
|
||||
t.ok(sodium.crypto_pwhash_str_needs_rehash(weakMem, sodium.crypto_pwhash_OPSLIMIT_MODERATE, sodium.crypto_pwhash_MEMLIMIT_MODERATE))
|
||||
t.ok(sodium.crypto_pwhash_str_needs_rehash(weakOps, sodium.crypto_pwhash_OPSLIMIT_MODERATE, sodium.crypto_pwhash_MEMLIMIT_MODERATE))
|
||||
t.ok(sodium.crypto_pwhash_str_needs_rehash(weakAlg, sodium.crypto_pwhash_OPSLIMIT_MODERATE, sodium.crypto_pwhash_MEMLIMIT_MODERATE))
|
||||
t.absent(sodium.crypto_pwhash_str_needs_rehash(good, sodium.crypto_pwhash_OPSLIMIT_MODERATE, sodium.crypto_pwhash_MEMLIMIT_MODERATE))
|
||||
t.ok(sodium.crypto_pwhash_str_needs_rehash(
|
||||
, sodium.crypto_pwhash_OPSLIMIT_MODERATE, sodium.crypto_pwhash_MEMLIMIT_MODERATE))
|
||||
})
|
||||
|
||||
test('crypto_pwhash_async', function (t) {
|
||||
t.plan(4)
|
||||
|
||||
const output = Buffer.alloc(32) // can be any size
|
||||
const passwd = Buffer.from('Hej, Verden!')
|
||||
const salt = Buffer.alloc(sodium.crypto_pwhash_SALTBYTES, 'lo')
|
||||
const opslimit = sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE
|
||||
const memlimit = sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE
|
||||
const algo = sodium.crypto_pwhash_ALG_DEFAULT
|
||||
|
||||
sodium.crypto_pwhash_async(output, passwd, salt, opslimit, memlimit, algo, function (err) {
|
||||
t.absent(err)
|
||||
t.alike(output.toString('hex'), 'f0236e17ec70050fc989f19d8ce640301e8f912154b4f0afc1552cdf246e659f', 'hashes password')
|
||||
|
||||
salt[0] = 0
|
||||
|
||||
sodium.crypto_pwhash_async(output, passwd, salt, opslimit, memlimit, algo, function (err) {
|
||||
t.absent(err)
|
||||
t.alike(output.toString('hex'), 'df73f15d217196311d4b1aa6fba339905ffe581dee4bd3a95ec2bb7c52991d65', 'diff salt -> diff hash')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('crypto_pwhash_str_async', function (t) {
|
||||
t.plan(7)
|
||||
|
||||
const output = Buffer.alloc(sodium.crypto_pwhash_STRBYTES)
|
||||
const passwd = Buffer.from('Hej, Verden!')
|
||||
const opslimit = sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE
|
||||
const memlimit = sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE
|
||||
|
||||
t.exception.all(function () {
|
||||
sodium.crypto_pwhash_str_async(output, passwd)
|
||||
}, 'should throw on missing args')
|
||||
|
||||
sodium.crypto_pwhash_str_async(output, passwd, opslimit, memlimit, function (err) {
|
||||
t.absent(err)
|
||||
t.not(output, Buffer.alloc(output.length), 'not blank')
|
||||
|
||||
sodium.crypto_pwhash_str_verify_async(Buffer.alloc(output.length), passwd, function (err, bool) {
|
||||
t.absent(err)
|
||||
t.ok(bool === false, 'does not verify')
|
||||
|
||||
sodium.crypto_pwhash_str_verify_async(output, passwd, function (err, bool) {
|
||||
t.absent(err)
|
||||
t.ok(bool === true, 'verifies')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('crypto_pwhash limits', function (t) {
|
||||
const output = Buffer.alloc(sodium.crypto_pwhash_STRBYTES)
|
||||
const passwd = Buffer.from('Hej, Verden!')
|
||||
const opslimit = Number.MAX_SAFE_INTEGER
|
||||
const memlimit = Number.MAX_SAFE_INTEGER
|
||||
|
||||
t.exception.all(function () {
|
||||
sodium.crypto_pwhash_str(output, passwd, opslimit, memlimit)
|
||||
}, 'should throw on large limits')
|
||||
t.exception.all(function () {
|
||||
sodium.crypto_pwhash_str(output, passwd, -1, -1)
|
||||
}, 'should throw on negative limits')
|
||||
})
|
||||
|
||||
test('crypto_pwhash_async uncaughtException', function (t) {
|
||||
t.plan(1)
|
||||
|
||||
const output = Buffer.alloc(32) // can be any size
|
||||
const passwd = Buffer.from('Hej, Verden!')
|
||||
const salt = Buffer.alloc(sodium.crypto_pwhash_SALTBYTES, 'lo')
|
||||
const opslimit = sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE
|
||||
const memlimit = sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE
|
||||
const algo = sodium.crypto_pwhash_ALG_DEFAULT
|
||||
|
||||
process.once('uncaughtException', listener)
|
||||
|
||||
sodium.crypto_pwhash_async(output, passwd, salt, opslimit, memlimit, algo, exception)
|
||||
|
||||
function exception () {
|
||||
throw new Error('caught')
|
||||
}
|
||||
|
||||
function listener (err) {
|
||||
if (err.message !== 'caught') {
|
||||
t.fail()
|
||||
} else {
|
||||
t.pass()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
test('crypto_pwhash_str_async uncaughtException', function (t) {
|
||||
t.plan(1)
|
||||
|
||||
const output = Buffer.alloc(sodium.crypto_pwhash_STRBYTES) // can be any size
|
||||
const passwd = Buffer.from('Hej, Verden!')
|
||||
const opslimit = sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE
|
||||
const memlimit = sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE
|
||||
|
||||
process.once('uncaughtException', listener)
|
||||
|
||||
sodium.crypto_pwhash_str_async(output, passwd, opslimit, memlimit, exception)
|
||||
|
||||
function exception () {
|
||||
throw new Error('caught')
|
||||
}
|
||||
|
||||
function listener (err) {
|
||||
if (err.message === 'caught') {
|
||||
t.pass()
|
||||
} else {
|
||||
t.fail()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
test('crypto_pwhash_str_verify_async uncaughtException', function (t) {
|
||||
t.plan(1)
|
||||
|
||||
const output = Buffer.alloc(sodium.crypto_pwhash_STRBYTES) // can be any size
|
||||
const passwd = Buffer.from('Hej, Verden!')
|
||||
|
||||
process.once('uncaughtException', listener)
|
||||
|
||||
sodium.crypto_pwhash_str_verify_async(output, passwd, exception)
|
||||
|
||||
function exception () {
|
||||
throw new Error('caught')
|
||||
}
|
||||
|
||||
function listener (err) {
|
||||
if (err.message === 'caught') {
|
||||
t.pass()
|
||||
} else {
|
||||
t.fail()
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,39 @@
|
||||
/* eslint-disable camelcase */
|
||||
const test = require('brittle')
|
||||
const sodium = require('..')
|
||||
|
||||
test('crypto_scalarmult_base', function (t) {
|
||||
const keys = keyPair()
|
||||
|
||||
t.not(keys.secretKey, Buffer.alloc(keys.secretKey.length), 'secret key not blank')
|
||||
t.not(keys.publicKey, Buffer.alloc(keys.publicKey.length), 'public key not blank')
|
||||
})
|
||||
|
||||
test('crypto_scalarmult', function (t) {
|
||||
const peer1 = keyPair()
|
||||
const peer2 = keyPair()
|
||||
|
||||
t.not(peer1.secretKey, peer2.secretKey, 'diff secret keys')
|
||||
t.not(peer1.publicKey, peer2.publicKey, 'diff public keys')
|
||||
|
||||
const shared1 = Buffer.alloc(sodium.crypto_scalarmult_BYTES)
|
||||
const shared2 = Buffer.alloc(sodium.crypto_scalarmult_BYTES)
|
||||
|
||||
sodium.crypto_scalarmult(shared1, peer1.secretKey, peer2.publicKey)
|
||||
sodium.crypto_scalarmult(shared2, peer2.secretKey, peer1.publicKey)
|
||||
|
||||
t.alike(shared1, shared2, 'same shared secret')
|
||||
})
|
||||
|
||||
function keyPair () {
|
||||
const secretKey = Buffer.alloc(sodium.crypto_scalarmult_SCALARBYTES)
|
||||
sodium.randombytes_buf(secretKey)
|
||||
|
||||
const publicKey = Buffer.alloc(sodium.crypto_scalarmult_BYTES)
|
||||
sodium.crypto_scalarmult_base(publicKey, secretKey)
|
||||
|
||||
return {
|
||||
publicKey,
|
||||
secretKey
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/* eslint-disable camelcase */
|
||||
const test = require('brittle')
|
||||
const sodium = require('..')
|
||||
|
||||
test('crypto_secretbox_easy', function (t) {
|
||||
const message = Buffer.from('Hej, Verden!')
|
||||
const output = Buffer.alloc(message.length + sodium.crypto_secretbox_MACBYTES)
|
||||
|
||||
const key = Buffer.alloc(sodium.crypto_secretbox_KEYBYTES)
|
||||
sodium.randombytes_buf(key)
|
||||
|
||||
const nonce = Buffer.alloc(sodium.crypto_secretbox_NONCEBYTES)
|
||||
sodium.randombytes_buf(nonce)
|
||||
|
||||
t.exception.all(function () {
|
||||
sodium.crypto_secretbox_easy(Buffer.alloc(0), message, nonce, key)
|
||||
}, 'throws if output is too small')
|
||||
|
||||
t.exception.all(function () {
|
||||
sodium.crypto_secretbox_easy(Buffer.alloc(message.length), message, nonce, key)
|
||||
}, 'throws if output is too small')
|
||||
|
||||
sodium.crypto_secretbox_easy(output, message, nonce, key)
|
||||
t.not(output, Buffer.alloc(output.length))
|
||||
|
||||
const result = Buffer.alloc(output.length - sodium.crypto_secretbox_MACBYTES)
|
||||
t.absent(sodium.crypto_secretbox_open_easy(result, output, Buffer.alloc(sodium.crypto_secretbox_NONCEBYTES), key), 'could not decrypt')
|
||||
t.ok(sodium.crypto_secretbox_open_easy(result, output, nonce, key), 'could decrypt')
|
||||
|
||||
t.alike(result, message, 'decrypted message is correct')
|
||||
})
|
||||
|
||||
test('crypto_secretbox_easy overwrite buffer', function (t) {
|
||||
const output = Buffer.alloc(Buffer.byteLength('Hej, Verden!') + sodium.crypto_secretbox_MACBYTES)
|
||||
output.write('Hej, Verden!', sodium.crypto_secretbox_MACBYTES)
|
||||
|
||||
const key = Buffer.alloc(sodium.crypto_secretbox_KEYBYTES)
|
||||
sodium.randombytes_buf(key)
|
||||
|
||||
const nonce = Buffer.alloc(sodium.crypto_secretbox_NONCEBYTES)
|
||||
sodium.randombytes_buf(nonce)
|
||||
|
||||
sodium.crypto_secretbox_easy(output, output.slice(sodium.crypto_secretbox_MACBYTES), nonce, key)
|
||||
t.not(output, Buffer.alloc(output.length))
|
||||
|
||||
t.ok(sodium.crypto_secretbox_open_easy(output.slice(sodium.crypto_secretbox_MACBYTES), output, nonce, key), 'could decrypt')
|
||||
t.alike(output.slice(sodium.crypto_secretbox_MACBYTES), Buffer.from('Hej, Verden!'), 'decrypted message is correct')
|
||||
})
|
||||
|
||||
test('crypto_secretbox_detached', function (t) {
|
||||
const message = Buffer.from('Hej, Verden!')
|
||||
const output = Buffer.alloc(message.length)
|
||||
const mac = Buffer.alloc(sodium.crypto_secretbox_MACBYTES)
|
||||
|
||||
const key = Buffer.alloc(sodium.crypto_secretbox_KEYBYTES)
|
||||
sodium.randombytes_buf(key)
|
||||
|
||||
const nonce = Buffer.alloc(sodium.crypto_secretbox_NONCEBYTES)
|
||||
sodium.randombytes_buf(nonce)
|
||||
|
||||
sodium.crypto_secretbox_detached(output, mac, message, nonce, key)
|
||||
|
||||
t.not(mac, Buffer.alloc(mac.length), 'mac not blank')
|
||||
t.not(output, Buffer.alloc(output.length), 'output not blank')
|
||||
|
||||
const result = Buffer.alloc(output.length)
|
||||
|
||||
t.absent(sodium.crypto_secretbox_open_detached(result, output, mac, nonce, Buffer.alloc(key.length)), 'could not decrypt')
|
||||
t.ok(sodium.crypto_secretbox_open_detached(result, output, mac, nonce, key), 'could decrypt')
|
||||
|
||||
t.alike(result, message, 'decrypted message is correct')
|
||||
})
|
||||
@@ -0,0 +1,148 @@
|
||||
/* eslint-disable camelcase */
|
||||
const test = require('brittle')
|
||||
const sodium = require('..')
|
||||
|
||||
test('constants', function (t) {
|
||||
t.alike(typeof sodium.crypto_secretstream_xchacha20poly1305_ABYTES, 'number', 'crypto_secretstream_xchacha20poly1305_ABYTES is number')
|
||||
t.alike(typeof sodium.crypto_secretstream_xchacha20poly1305_HEADERBYTES, 'number', 'crypto_secretstream_xchacha20poly1305_HEADERBYTES is number')
|
||||
t.alike(typeof sodium.crypto_secretstream_xchacha20poly1305_KEYBYTES, 'number', 'crypto_secretstream_xchacha20poly1305_KEYBYTES is number')
|
||||
t.alike(typeof sodium.crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX, 'bigint', 'crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX is number')
|
||||
|
||||
t.ok(typeof sodium.crypto_secretstream_xchacha20poly1305_TAG_MESSAGE === 'number', 'crypto_secretstream_xchacha20poly1305_TAG_MESSAGE is Buffer')
|
||||
t.ok(typeof sodium.crypto_secretstream_xchacha20poly1305_TAG_PUSH === 'number', 'crypto_secretstream_xchacha20poly1305_TAG_PUSH is Buffer')
|
||||
t.ok(typeof sodium.crypto_secretstream_xchacha20poly1305_TAG_REKEY === 'number', 'crypto_secretstream_xchacha20poly1305_TAG_REKEY is Buffer')
|
||||
t.ok(typeof sodium.crypto_secretstream_xchacha20poly1305_TAG_FINAL === 'number', 'crypto_secretstream_xchacha20poly1305_TAG_FINAL is Buffer')
|
||||
})
|
||||
|
||||
test.skip('crypto_secretstream', function (t) {
|
||||
const state = Buffer.alloc(sodium.crypto_secretstream_xchacha20poly1305_STATEBYTES)
|
||||
|
||||
const header = Buffer.alloc(sodium.crypto_secretstream_xchacha20poly1305_HEADERBYTES)
|
||||
const ad = Buffer.alloc(Math.floor(Math.random() * 100))
|
||||
sodium.randombytes_buf(ad)
|
||||
|
||||
const m1 = Buffer.alloc(Math.floor(Math.random() * 1000))
|
||||
sodium.randombytes_buf(m1)
|
||||
|
||||
const m2 = Buffer.alloc(Math.floor(Math.random() * 1000))
|
||||
sodium.randombytes_buf(m2)
|
||||
|
||||
const m3 = Buffer.alloc(Math.floor(Math.random() * 1000))
|
||||
sodium.randombytes_buf(m3)
|
||||
|
||||
const m4 = Buffer.alloc(Math.floor(Math.random() * 1000))
|
||||
sodium.randombytes_buf(m4)
|
||||
|
||||
const m1_ = Buffer.from(m1)
|
||||
const m2_ = Buffer.from(m2)
|
||||
const m3_ = Buffer.from(m3)
|
||||
const m4_ = Buffer.from(m4)
|
||||
|
||||
const c1 = Buffer.alloc(m1.length + sodium.crypto_secretstream_xchacha20poly1305_ABYTES)
|
||||
const c2 = Buffer.alloc(m2.length + sodium.crypto_secretstream_xchacha20poly1305_ABYTES)
|
||||
const c3 = Buffer.alloc(m3.length + sodium.crypto_secretstream_xchacha20poly1305_ABYTES)
|
||||
const c4 = Buffer.alloc(m4.length + sodium.crypto_secretstream_xchacha20poly1305_ABYTES)
|
||||
|
||||
const key = Buffer.alloc(sodium.crypto_secretstream_xchacha20poly1305_KEYBYTES)
|
||||
let ret
|
||||
const tag = Buffer.alloc(sodium.crypto_secretstream_xchacha20poly1305_TAGBYTES, 0xdb)
|
||||
|
||||
sodium.crypto_secretstream_xchacha20poly1305_keygen(key)
|
||||
|
||||
sodium.crypto_secretstream_xchacha20poly1305_init_push(state, header, key)
|
||||
t.unlike(header.toString('hex'), '000000000000000000000000000000000000000000000000')
|
||||
ret = sodium.crypto_secretstream_xchacha20poly1305_push(state, c1, m1, null, sodium.crypto_secretstream_xchacha20poly1305_TAG_MESSAGE)
|
||||
t.alike(ret, m1.length + sodium.crypto_secretstream_xchacha20poly1305_ABYTES)
|
||||
ret = sodium.crypto_secretstream_xchacha20poly1305_push(state, c2, m2, ad.slice(0, 0), sodium.crypto_secretstream_xchacha20poly1305_TAG_MESSAGE)
|
||||
t.alike(ret, m2.length + sodium.crypto_secretstream_xchacha20poly1305_ABYTES)
|
||||
ret = sodium.crypto_secretstream_xchacha20poly1305_push(state, c3, m3, ad, sodium.crypto_secretstream_xchacha20poly1305_TAG_MESSAGE)
|
||||
t.alike(ret, m3.length + sodium.crypto_secretstream_xchacha20poly1305_ABYTES)
|
||||
ret = sodium.crypto_secretstream_xchacha20poly1305_push(state, c4, m4, null, sodium.crypto_secretstream_xchacha20poly1305_TAG_FINAL)
|
||||
t.alike(ret, m4.length + sodium.crypto_secretstream_xchacha20poly1305_ABYTES)
|
||||
|
||||
sodium.crypto_secretstream_xchacha20poly1305_init_pull(state, header, key)
|
||||
m1.fill(0)
|
||||
tag.fill(0xdb)
|
||||
ret = sodium.crypto_secretstream_xchacha20poly1305_pull(state, m1, tag, c1, null)
|
||||
t.alike(ret, c1.length - sodium.crypto_secretstream_xchacha20poly1305_ABYTES)
|
||||
t.alike(tag[0], sodium.crypto_secretstream_xchacha20poly1305_TAG_MESSAGE)
|
||||
t.ok(m1.equals(m1_))
|
||||
|
||||
m2.fill(0)
|
||||
tag.fill(0xdb)
|
||||
ret = sodium.crypto_secretstream_xchacha20poly1305_pull(state, m2, tag, c2, null)
|
||||
t.alike(ret, c2.length - sodium.crypto_secretstream_xchacha20poly1305_ABYTES)
|
||||
t.alike(tag[0], sodium.crypto_secretstream_xchacha20poly1305_TAG_MESSAGE)
|
||||
t.ok(m2.equals(m2_))
|
||||
|
||||
if (ad.length > 0) {
|
||||
t.exception.all(function () {
|
||||
sodium.crypto_secretstream_xchacha20poly1305_pull(state, m3, tag, c3, null)
|
||||
})
|
||||
}
|
||||
|
||||
m3.fill(0)
|
||||
tag.fill(0xdb)
|
||||
ret = sodium.crypto_secretstream_xchacha20poly1305_pull(state, m3, tag, c3, ad)
|
||||
t.alike(ret, c3.length - sodium.crypto_secretstream_xchacha20poly1305_ABYTES)
|
||||
t.alike(tag[0], sodium.crypto_secretstream_xchacha20poly1305_TAG_MESSAGE)
|
||||
t.ok(m3.equals(m3_))
|
||||
|
||||
m4.fill(0)
|
||||
tag.fill(0xdb)
|
||||
ret = sodium.crypto_secretstream_xchacha20poly1305_pull(state, m4, tag, c4, null)
|
||||
t.alike(ret, c4.length - sodium.crypto_secretstream_xchacha20poly1305_ABYTES)
|
||||
t.alike(tag[0], sodium.crypto_secretstream_xchacha20poly1305_TAG_FINAL)
|
||||
t.ok(m4.equals(m4_))
|
||||
|
||||
t.exception.all(function () {
|
||||
sodium.crypto_secretstream_xchacha20poly1305_pull(state, m4, tag, c4, null)
|
||||
}, 'previous with FINAL tag')
|
||||
|
||||
t.exception.all(function () {
|
||||
sodium.crypto_secretstream_xchacha20poly1305_pull(state, m2, tag, c2, null)
|
||||
}, 'previous with without tag')
|
||||
|
||||
t.exception.all(function () {
|
||||
sodium.crypto_secretstream_xchacha20poly1305_pull(state, m2, tag, c2.slice(0, Math.random() * sodium.crypto_secretstream_xchacha20poly1305_ABYTES | 0), null) // fixme
|
||||
}, 'short ciphertext')
|
||||
|
||||
t.exception.all(function () {
|
||||
sodium.crypto_secretstream_xchacha20poly1305_pull(state, m2, tag, c2.slice(0, sodium.crypto_secretstream_xchacha20poly1305_ABYTES), null)
|
||||
}, 'empty ciphertext')
|
||||
|
||||
/* without explicit rekeying */
|
||||
|
||||
sodium.crypto_secretstream_xchacha20poly1305_init_push(state, header, key)
|
||||
sodium.crypto_secretstream_xchacha20poly1305_push(state, c1, m1, null, sodium.crypto_secretstream_xchacha20poly1305_TAG_REKEY)
|
||||
sodium.crypto_secretstream_xchacha20poly1305_push(state, c2, m2, null, sodium.crypto_secretstream_xchacha20poly1305_TAG_MESSAGE)
|
||||
|
||||
sodium.crypto_secretstream_xchacha20poly1305_init_pull(state, header, key)
|
||||
tag.fill(0xdb)
|
||||
sodium.crypto_secretstream_xchacha20poly1305_pull(state, m1, tag, c1, null)
|
||||
t.alike(tag[0], sodium.crypto_secretstream_xchacha20poly1305_TAG_REKEY)
|
||||
tag.fill(0xdb)
|
||||
sodium.crypto_secretstream_xchacha20poly1305_pull(state, m2, tag, c2, null)
|
||||
t.alike(tag[0], sodium.crypto_secretstream_xchacha20poly1305_TAG_MESSAGE)
|
||||
|
||||
/* with explicit rekeying */
|
||||
|
||||
sodium.crypto_secretstream_xchacha20poly1305_init_push(state, header, key)
|
||||
sodium.crypto_secretstream_xchacha20poly1305_push(state, c1, m1, null, sodium.crypto_secretstream_xchacha20poly1305_TAG_MESSAGE)
|
||||
sodium.crypto_secretstream_xchacha20poly1305_rekey(state)
|
||||
sodium.crypto_secretstream_xchacha20poly1305_push(state, c2, m2, null, sodium.crypto_secretstream_xchacha20poly1305_TAG_MESSAGE)
|
||||
|
||||
sodium.crypto_secretstream_xchacha20poly1305_init_pull(state, header, key)
|
||||
tag.fill(0xdb)
|
||||
sodium.crypto_secretstream_xchacha20poly1305_pull(state, m1, tag, c1, null)
|
||||
t.alike(tag[0], sodium.crypto_secretstream_xchacha20poly1305_TAG_MESSAGE)
|
||||
|
||||
t.exception.all(function () {
|
||||
sodium.crypto_secretstream_xchacha20poly1305_pull(state, m2, tag, c2, null)
|
||||
})
|
||||
|
||||
sodium.crypto_secretstream_xchacha20poly1305_rekey(state)
|
||||
tag.fill(0xdb)
|
||||
sodium.crypto_secretstream_xchacha20poly1305_pull(state, m2, tag, c2, null)
|
||||
t.alike(tag[0], sodium.crypto_secretstream_xchacha20poly1305_TAG_MESSAGE)
|
||||
})
|
||||
@@ -0,0 +1,214 @@
|
||||
/* eslint-disable camelcase */
|
||||
const test = require('brittle')
|
||||
const sodium = require('..')
|
||||
|
||||
const vectors = [ // generated from https://github.com/jedisct1/siphash-js/blob/master/test/index.js
|
||||
['aON1dHrq90SbG8Hx', 'v7LyiwuCrB7EgAibPve6Yg2gLmggxE6j7ocR37EudrH_P9XX2rQK', [147, 73, 50, 63, 71, 98, 203, 42]],
|
||||
['YOT4AG5F7ONRW5na', '4Ks1pPO_2wGYR-gfJShqUO-FirA9c5cF4oKwvStp2Ix5hHUg2klPofVJ8TZoBdFfgTh8', [138, 27, 129, 27, 185, 163, 160, 153]],
|
||||
['63UlqXfSckA3Dv8S', 'bMQudI8yVdDx5ScGQCMQy4K_QXYCq1w1eC', [6, 78, 44, 167, 186, 29, 113, 244]],
|
||||
['P3hpmZEuwfDO_uZ-', 'Wh8yRitk__n4MsETCTRFrB4bjWRtPjUZVLPnywlvv5nTMA2C71', [241, 171, 151, 44, 166, 163, 156, 234]],
|
||||
['d9oTrpd-a_Na4b6w', 'f-NT', [182, 147, 203, 88, 65, 57, 119, 203]],
|
||||
['fe88HBnyyEiuIJ8G', 'KSWP9sFkhSdGsha0Fmd5raCf_eA5gnV1', [218, 10, 3, 10, 16, 50, 241, 229]],
|
||||
['o6LxtnACG0RGQ3z-', 'k8zMl', [16, 158, 19, 145, 214, 142, 177, 55]],
|
||||
['AHGkoQQ6xdf90MD9', 'HC9bz8XUYkan0jxYSaj0vP-cs324Y4PrnAXutwKBgIko5oOOOViJSjLD2m8WenV8HdF78J', [157, 186, 255, 238, 165, 21, 187, 163]],
|
||||
['TlVmpfbZMFkeuENo', '5is', [166, 36, 114, 58, 101, 106, 79, 30]],
|
||||
['iBLscVfsPM1xrSFJ', 'J-aH-', [14, 91, 64, 158, 190, 247, 72, 26]],
|
||||
['hUehErdKolgd0erH', 'DhS94w_07-vaAXo_msv8Fk57slIHnuxy3iv4Yymh5k', [45, 207, 192, 24, 158, 243, 93, 68]],
|
||||
['B-aq-09jmO0z_PUD', '1p2IMG4A1NMyWsfUS02VK8fOEhn', [161, 224, 65, 80, 91, 44, 131, 177]],
|
||||
['fyNYE8SMJvYrDgao', 'HWCtQs19BHZcH', [122, 114, 254, 14, 124, 226, 23, 173]],
|
||||
['5vQHK_yJlJez45N5', '8YJwfpxwbH9h-N27i-uTUUK2Vt', [142, 216, 87, 77, 16, 17, 8, 199]],
|
||||
['q7Oo0g9DDjLJ_pyV', 'jQFAHtrTUDaCaSIcis5h2j4fyOJpJGfdZBMTO5GOAAB4AwZtutDenNZ', [230, 111, 182, 25, 233, 231, 14, 141]],
|
||||
['IUle6P8g2uyX_8ms', 'hOKGFGrsAux60CQmbOjQd-EzQBKUjLbDUhhtsKt3ZY4', [64, 247, 102, 236, 211, 145, 4, 152]],
|
||||
['-bZa23onpInwqNWG', 'DNbtZuulH9', [247, 2, 142, 172, 208, 100, 60, 127]],
|
||||
['1xjmLXTmVJwse8M-', 'j1_Hh', [197, 81, 6, 184, 57, 173, 83, 126]],
|
||||
['Ey7hygEVd8RxZdtX', 'GNRDNJDu00L', [137, 196, 184, 4, 146, 27, 188, 191]],
|
||||
['weTzikz4EGUbhSgC', 'g1SXT7b4Zz6q2tQykV1tZS', [105, 39, 69, 220, 198, 210, 96, 240]],
|
||||
['OjSaplYVoQPDXG7S', 'QCk4v3D9s6R471p0xa--Vv00vzIaMpJ1S48Qnz6uzhmtke99HmWcY9vapyjdWVS', [183, 208, 142, 194, 95, 247, 239, 122]],
|
||||
['4g2ZB-SA-HlqJT7D', 'N5Ht5QIk6KziyTE4-q5eNkqGdQgg8fxkr4w-ARqRgdaZd3XpbePGGb4jPFo3', [127, 245, 152, 248, 155, 148, 212, 127]],
|
||||
['CXOF2EKm5CDPYpNC', 'xkY0T8bPF4JFq6Mu0K5YtFp7KfOni', [124, 172, 24, 66, 198, 236, 234, 226]],
|
||||
['ID4UzFBiztXW--b0', 'qyICNMPaivgDmX', [46, 95, 156, 18, 186, 88, 188, 122]],
|
||||
['TaGesMDe_0UNGzcp', 'nlNv', [103, 245, 211, 70, 87, 104, 0, 17]],
|
||||
['lMDS8Vcs-8aCV9hJ', 'KW44Qk', [69, 47, 130, 50, 196, 101, 206, 62]],
|
||||
['BmQCaB-c777zvFsc', 'o-tr2zQVbtrmkH4rCCAXoXFt8KwAWo4YFpK', [123, 168, 235, 94, 113, 233, 190, 213]],
|
||||
['OQlCpJOLmsouyme1', 'aRk9nyHhXlad-TpIemD2VTRiHVlzSysY7uKof9ApR5DejFjT-Bmdzl_z', [89, 201, 222, 238, 50, 99, 249, 215]],
|
||||
['t6Wl3FKDhr9FAMzz', 'BLu17bk_iQtpGv1N4A', [80, 7, 121, 129, 115, 84, 153, 140]],
|
||||
['XU5km7La0ujNVvlV', 'OUEAH4yu6SXQ4I8zjn07NuB_AudmoewXc39HqgN8rc', [220, 180, 100, 142, 210, 176, 72, 108]],
|
||||
['zDKBNpM2cdf0HwkK', 'dEqgpqTRc', [221, 42, 57, 242, 197, 147, 27, 81]],
|
||||
['yZGrKEShM0z7Vvns', 'sgUtgxRQpMl_o6iuZqomKhJxaSBCD_NBHa2lqX3cWfq8byu', [211, 179, 114, 59, 129, 223, 168, 65]],
|
||||
['4-wM8GXg1a7hyerE', 'djJ3-b2', [157, 165, 254, 119, 109, 239, 114, 115]],
|
||||
['jD3Y4PgdExHU2JaY', 'uQC59dKTf3unOGu-Lg9IgmC8MTSg-BcH-', [249, 179, 174, 181, 118, 232, 40, 255]],
|
||||
['dZhRW8ubIZovieQg', 'GCbxph1HICSKgHLafk_8TRjGdZa7jnJOu', [73, 24, 76, 226, 201, 86, 43, 223]],
|
||||
['P9hudzT3H87QzC9E', 'Vfeo26fUa3sLk6BNM', [31, 150, 174, 223, 224, 214, 127, 107]],
|
||||
['ocfdt04Np8Bs5hn9', 'dQiaUqksbXOWmBPt2kBn0ARiVkr3r4mBwypQq', [203, 253, 155, 6, 148, 92, 81, 212]],
|
||||
['UuQ68x330IdojsLI', 'pb6-OdmVdQ1gLP8E1szvlf0T6aOQp-EQHPW-tAKQ8Xj', [23, 158, 11, 26, 216, 251, 17, 229]],
|
||||
['T4ec6Q68QKiuIARL', 'BeLjFIoODtDg5vLMLBN1Sae', [250, 103, 43, 65, 80, 229, 66, 116]],
|
||||
['xmZBUpwjJwnXZAp6', 'WS2F3Nzg2s7TqVIygm8W1tQyNc6DFy', [186, 206, 177, 250, 182, 139, 138, 19]],
|
||||
['4qB6m0d_ryzb3w6q', '2Nr1sd1phWDB9gnuYOLUsjvX9jxntScWyRlX3Nj_xs8MV10LGgSgfRBKVGnO', [97, 101, 207, 79, 55, 205, 142, 253]],
|
||||
['SmVONU3BEODnkbdM', 'G4WIU3UrBqbN6_nccFrIyx_TdXx-W80YzWw', [33, 147, 134, 20, 73, 169, 2, 107]],
|
||||
['zseM9_-0y7B9URxM', 'us8B1DmHxOF10ue3jm2VfoJ250h364zRd2U8VIm2Lbkf3OWprSUpLF4ePjdj5aS', [80, 47, 98, 151, 139, 175, 78, 166]],
|
||||
['WY_sEWLFAybHSwX4', 'vLJyXNkHCYGHWsvhXcU2sWYzgFYlWF7A_ZjFg8kJ4wwuJ', [132, 67, 168, 204, 90, 10, 169, 235]],
|
||||
['maWrEov1bBjSq2Zn', 'sCP9zPakZ_wZ8hcQu-G6nN', [136, 204, 107, 221, 66, 198, 31, 201]],
|
||||
['tXInZHO-x4AWxKTp', 'JQUM_O-E4-YI6dhxo', [36, 245, 166, 183, 31, 222, 192, 96]],
|
||||
['OqaQt_b1hvU-atC3', 'X7Ou8cKo17xHlq_5gwM56GZrCSJBReeA60pDj2hUer6', [169, 107, 175, 79, 116, 24, 153, 93]],
|
||||
['nHdnXHGmGknC8FfC', 'cRupnAESNmU', [18, 200, 205, 81, 7, 32, 8, 213]],
|
||||
['59n9lAJdrxIz3joe', 'WBPr', [75, 153, 152, 122, 242, 233, 165, 255]],
|
||||
['q-PAAgkE9z2xed85', 'AFOQD_H7MO3q3cxLa7TOUd89kpH03SpjpqmzY6AX16-uZFYcZZBb8D', [45, 4, 101, 133, 174, 99, 42, 4]],
|
||||
['tBzStZxn2ZqlQfBf', 'nZdIaI7-bdqqh6aU7w4HfDCByX-x4_3q9Jf', [253, 49, 199, 224, 50, 253, 75, 144]],
|
||||
['rH8Nn75LyYC0hjVG', 'IrDPpL-dkoh6VTy7pOtKKdAD9dLwUnE-', [76, 2, 97, 127, 190, 74, 74, 5]],
|
||||
['F-pI7AhpS1V-48eT', 'Ao7hV41P08Zq4C1szyOVN7K1iWW8z', [121, 76, 85, 13, 162, 105, 174, 114]],
|
||||
['Khje_RmXXmJ3CAb1', 'TvMx3ISTfIQ', [237, 102, 92, 182, 242, 45, 27, 178]],
|
||||
['G1KRzk-KMqCk-kbD', 'imHZWdBz01lGR3m1zuO74berNn68uFZR3kcoWEaMhVjJ1g', [165, 3, 34, 126, 199, 101, 203, 184]],
|
||||
['wJhnTtBLcy_1rZay', 'qbZ6oK0a4eWf2ud1sEnKLeguOmYsbG4aOTdlMdrf', [226, 169, 14, 147, 180, 88, 90, 132]],
|
||||
['vVl9fhjkwASu2WXe', '8-CjQylw18IKWgAL2mMxo', [30, 193, 202, 34, 74, 172, 72, 42]],
|
||||
['m2Qx2Dtbvwv3qjNJ', 'WrIqIIsHqbgm3Qfg03QvaVG9G6fz2zxjnfNZUVuX8XUtjz4LQuj3VZNh', [237, 163, 64, 58, 187, 234, 117, 106]],
|
||||
['5R1maUgHiPQ0ZoaD', 'SZJ6uMXnMuLll2xOfHcy_DE', [209, 26, 182, 131, 19, 180, 5, 55]],
|
||||
['dDBufcmObAK1dKYw', 'ayjd0F5mqWsVF0MtUNJYo8S8GhuCsMCnEU6k3H9z0f8', [126, 244, 206, 245, 56, 4, 39, 63]],
|
||||
['o_YPVOjQ7Xw0G9OD', 'UPF-HW1hJukwdVvhCl7IZJzy7a', [30, 211, 48, 214, 88, 189, 59, 33]],
|
||||
['oule-vFYlFJfsXU3', '8ORL7DUv28-yVfUw_cJ3imWP-iXrQRmzZRp0jtspwW_qm-rXmc1aBsbvbAut8', [66, 62, 243, 87, 153, 23, 230, 113]],
|
||||
['kEPlQxhC27GQcJeb', 'wL-dAWvwZapITZZvgW46', [153, 83, 52, 252, 33, 23, 48, 216]],
|
||||
['GFilE6NpBPWE25uB', 'RzoQCcd5NVeDbd2cx', [144, 101, 221, 104, 142, 244, 87, 216]],
|
||||
['sENqlFHs0NvkY28u', 'Gm2ojB-BJBdL', [75, 226, 42, 7, 94, 14, 215, 52]],
|
||||
['mxiOr15qouOEhzHS', 'SChjLg6SXpEb9', [174, 64, 56, 79, 211, 158, 21, 229]],
|
||||
['pFL_Sbx5RW0fuPHO', 'hdb8HqaxEN99N4V1STTpnR4kr9F-lONwKp2TcOCopBFnDrjITz3jHPM4WKIYyw59US', [108, 66, 228, 165, 111, 142, 78, 201]],
|
||||
['sMgAXpCtVqeFm14R', 'dNPnh6shnGYEZuN0id', [101, 147, 101, 20, 126, 33, 84, 255]],
|
||||
['nTu9mRGqYc1SOPk7', 'ogL8VEqgoMkh6YNgTzvF4f87wHvmRhzncGPunN2ZJ5p3qUqZeJ3', [253, 16, 23, 144, 34, 207, 28, 82]],
|
||||
['d5jDH8Ppk82zj_vd', '5sfq9Q_0P0H', [197, 245, 4, 89, 247, 26, 240, 77]],
|
||||
['bEEUPVwdHlYwYL6o', 'AGoiVTE9foWm2MZqsn3dfS1XQiQW0QJwLXi6oXR2L9nMnPCPG_oF', [186, 203, 217, 87, 4, 177, 20, 242]],
|
||||
['JbKhWuTfRMWb4hFD', 'NTNhYIahQ769TsCDwFyfOYZ8x6np58jg9hMAHFH-BMv7hBwESi596D4aDuyPabFGbqcG', [60, 79, 166, 97, 146, 213, 223, 59]],
|
||||
['hvCtw1q_GJUBFW_X', 'uL5zgFM9WUTyO25dzVCmSVOxbpV70ZPurKK-CPUAmP', [127, 4, 233, 105, 7, 183, 123, 61]],
|
||||
['hWxh0P6EXlm4yYKA', 'NUgrOoTOfqaB6JDZj', [96, 255, 249, 149, 117, 178, 189, 183]],
|
||||
['TLHDMak8qeH3ABaV', 'HW-7PPunyMCinXt8QjQUuJUzZZQs1-T9ADR-6y', [46, 167, 85, 216, 34, 240, 131, 74]],
|
||||
['uE4OfzzqHVDH8lbd', '8KCUyGtkcG-T8gA3lpplC13LsnFZ', [18, 9, 33, 96, 47, 132, 243, 76]],
|
||||
['ocjA0Quge9vdCDbH', 'tLlU03I9CDBbP1Pnl6KM3MW34TNzuuZYv0u-uU-l7RtFF0OmGoySyg_yc7vWswGkz', [124, 174, 227, 126, 197, 91, 232, 11]],
|
||||
['TDVmxGeyDULfxyrz', 'A57Y0_L6K4TTzQx1-Yr1E6fVAZi31RyipeK0Q4uqwXXfRLo4tz2a5PSqN3-bdQ4f2', [53, 212, 137, 227, 12, 85, 50, 251]],
|
||||
['8OhqW3sA7s1vqEDr', 'jlFquRWvL07TyLjW9ZNk81gxkvs4u1WLkNhOQVLOjFjw3iecMjun5Yk0xcruo', [147, 130, 134, 67, 235, 29, 115, 34]],
|
||||
['9kPcY6rfhPzSzEGn', 'nS1kAxpsghzJJXiCzhNycDk2_EJ_yIT97fV2kxXTtfZ9p0', [178, 109, 176, 237, 184, 79, 209, 89]],
|
||||
['AJJ_yoEL8WyEtA1U', 'vFNErhfCk1TZiTFMA6J8D', [26, 63, 142, 247, 30, 50, 167, 102]],
|
||||
['PBr4drRAJTaWv5Um', '5quc8Vd2rHVNk2NoDxk3TL', [150, 113, 209, 153, 101, 74, 42, 2]],
|
||||
['MnODoRJI2FgZrvLs', 'gqJ_7HnrfiqYkenyvhe53SB1vTBgMiMB3kxF5', [205, 11, 216, 157, 130, 39, 60, 161]],
|
||||
['iSxQPJpp_s0ws-4b', 'K-J', [46, 78, 209, 241, 112, 90, 91, 181]],
|
||||
['ZMm2tCGDJ04A3I_6', 'gw-wcFYO1G2KEqJagWAic2l2d1FoTVXVT', [22, 60, 166, 216, 76, 146, 36, 22]],
|
||||
['Hxf6qsSIV6blPdB1', 'GTWOerCQdUMkL6it6hEEPKBcOe_9f_B618ivjeM3BKfjzRQ8rvcGjUUJnsljerca6', [122, 74, 100, 36, 79, 173, 4, 91]],
|
||||
['U5gXdMrRYUdxuDjK', 'siy9CxY2BbhazTqBWwFrtBLh', [79, 92, 248, 231, 189, 215, 27, 51]],
|
||||
['YJiK_B-TENJsVnd_', 'Ohyz8XU06XWewcgTX-PffLVdatU3UFl6CYe', [22, 147, 91, 237, 188, 184, 70, 223]],
|
||||
['J7wVNfLdkCCtndH5', '1Vw163YqXwP8cPXIy5dSkcIoClBep7gWb0qGJzHM8h_hzk2GFtZyLKk', [123, 221, 220, 145, 75, 144, 103, 74]],
|
||||
['elId3b7ZyOg6HVif', 'N89kQR7VMUgF4DyWhpTo_ZW2lERbNqFa1RdXjaUctO1FdevDAZaA', [39, 244, 17, 57, 240, 193, 34, 112]],
|
||||
['ydBueYO29jaUsEVU', 'HMcnfvYjjz8Uf8bUhxXlAYHcyO7x5NHE_gc3bcWSMWJD2JdryrUBBdYj1', [252, 15, 32, 244, 143, 126, 130, 34]],
|
||||
['fVprx-PzTSx6CUcX', 'Q', [253, 22, 240, 135, 62, 55, 219, 1]],
|
||||
['9ORMwecQjlob9aTT', '2cpq2XTWPk5sVLlN4OR5y6X_rTRFNUURgrwnWDg76u927cYud6PS-17UTgd3TO9g3K4', [15, 124, 108, 136, 56, 254, 85, 250]],
|
||||
['-V3BEGXuTWtFOMv4', '8l6qcZXfG9iSywi1IgwJ_PkZh0Bg2iR1cbGps_sWPdKXbIvDDX-3IeTTg', [111, 8, 18, 99, 6, 72, 56, 232]],
|
||||
['Cbvx4_KdboiNHs6P', 'nzUo0UnqKn05adw5g0jtBN703bUgb8UxywfC93I7KN', [85, 17, 95, 157, 77, 25, 206, 45]],
|
||||
['SDPzfgeqkvmi62JH', 'Z6kJuDD-8FSz1VwOuPeoSJ6X-4hpib563UjYxtFcB4SvhQr-Hstg5OhMi4iZZ', [153, 35, 172, 58, 141, 180, 95, 97]],
|
||||
['mBJlhP6D3M2raEjD', 'ogtg66jr2KLCFO2RvodOXw0mt4XS6BOnLhBI_gDV0', [85, 231, 198, 97, 240, 108, 230, 150]],
|
||||
['Sz-mxKc7KGM7SDaf', 'ecQ-7-3VddOdMSeKUbZE1t6Aa67pYGXjQeOckq1l50GkvfomFr', [18, 241, 24, 133, 142, 74, 218, 178]],
|
||||
['_5ck5scojT4oyJEq', '43oLkeixGHShTMUhtI', [35, 190, 107, 33, 2, 165, 11, 34]],
|
||||
['48ulC82W4qv49InN', '8HQyT55TtmGahy6w', [2, 70, 28, 124, 164, 101, 100, 185]],
|
||||
['-exgd5coAHqBu3ga', 'vRfqYthbUNh', [48, 188, 141, 96, 138, 114, 132, 143]],
|
||||
['hJEBugObOX06pplH', 'oYYZ-v', [153, 112, 89, 5, 46, 138, 209, 254]],
|
||||
['eSDsC63oTtVfi_F7', 'BVmyPas409CmRHiRRiTPjJL87KgJefuDK6lEh5isghLl7l3a4Xmxa', [21, 198, 30, 251, 173, 36, 165, 82]],
|
||||
['KZtUPWMUr469RWL8', 'F9K6TUd6j7Dm25rAS7cqOKDtSnnxj0hYKVTMFQ6CfA5218gPeZo', [203, 233, 183, 39, 57, 54, 60, 173]],
|
||||
['0TeBxGk-V7RPSZML', 'kmL1fKqHwAoxI1b_ap8I9fGZMmcx3gIMiglxLLPFWOoDNUGe', [193, 7, 13, 148, 71, 231, 166, 135]],
|
||||
['PWYY82PNqwshPHiv', 'Ya4LyHqxIxK8GaND9FIzqugleh-QELha_ntbRJixl6hZI5m3RfdrcntjiPJ', [27, 177, 64, 55, 129, 165, 132, 108]],
|
||||
['PtCub86vGwNj1tcv', 'qR08eqAeNrrUYDl18C-wttqMDk', [66, 134, 247, 100, 38, 3, 7, 125]],
|
||||
['3eqQxzhNdv2kJqy5', '0wxAd9NT-Z8xFzomFwgMqMVbaUg', [36, 191, 165, 105, 211, 159, 155, 13]],
|
||||
['MgEjpTNPFFwes6Sm', '7SCVGNJYZhtnbiLZAE5TrsL5K1X', [208, 79, 201, 49, 48, 3, 227, 199]],
|
||||
['vSofRAYxXUU1qjhl', 'HATE-YsASxySRkK5aJR4yV0mxx1YAuEgM5tUqyJDc7cLL', [61, 205, 183, 24, 68, 135, 7, 74]],
|
||||
['kIUe96sZ6LV464T_', 'rjwrCOQAzLFbIM_3M7KfDQ1A6r3nkebk-dgqORG0Uy-n89_apYNLVTbdr3yuzXKOTfkRh', [83, 214, 143, 126, 145, 218, 225, 186]],
|
||||
['8wao85IcCu1mC-Rc', 'AdVncBX6wkLXqMQPol3tNDPd5HJ', [161, 223, 243, 36, 219, 75, 215, 63]],
|
||||
['NRVNeO5wysG3DRuU', 'Mr8vhiVPo5GpI6sho4R09k8D-vFgcghF3-kF', [246, 119, 57, 225, 254, 189, 182, 180]],
|
||||
['VHJZOECxfyxVyufk', 'TMB3UMDEIs-vj_9aDBNDzT6HkHcwQQhr4EnG6A1AD9JkHENVAAQnS7s', [117, 85, 69, 116, 56, 27, 123, 62]],
|
||||
['TUfnTd3pmaJzSdD4', 'VoRGCJgaGEhPSGRl0EPKWIzN7CRpD49CiyjC7y_4xRpppMNlR4v', [3, 116, 140, 4, 113, 208, 78, 186]],
|
||||
['-I1YgwmWxehyB6kv', 'IplQLxea3JGywQn3XMNWrqVbE', [137, 251, 109, 201, 11, 101, 132, 97]],
|
||||
['4ic5nM5lbfMOXDRR', 'TfVtpOoAQt1IxL0qJtAQoCJJThyxncIagOvKSpxjD7RDmh7YQBHWPkuv5lpSzpN', [192, 203, 84, 99, 85, 184, 122, 44]],
|
||||
['NYOq6hIu2C-aZPhE', 'QQa0EWIHXqbrkq3nBeXt6yEj12z', [40, 199, 197, 21, 82, 53, 100, 58]],
|
||||
['nC93tajnfzk6bMtM', 'p9gbEB4nMHXDqmOC413rI4Z', [200, 140, 102, 143, 89, 170, 219, 32]],
|
||||
['ZCCkYIbGOzXa5GRO', '2f9VGQeb4AtW6SwPjAGxxjyHNw3-MZj2BfxttNLxM0Tv_rpXO8TUH4YASb', [0, 174, 100, 194, 149, 35, 81, 12]],
|
||||
['oapO2W6hces4Pfkc', 'oEyf5eqpM-N7LBp3C5vejvO7M87OzT4MHdwJz', [140, 195, 199, 20, 207, 60, 104, 240]],
|
||||
['__daPiDXrnPpS7eO', '1_tnhApr6nZbWIEPja0jAJ6LbTvD6oAEvPyrLYQ', [255, 244, 76, 119, 124, 124, 146, 214]],
|
||||
['5iIExqPt5W-ZpudD', 'jNbLiDmQdN5X7HEOfgnAi5A7s1pGXwP41hX1Z', [149, 68, 125, 203, 174, 150, 66, 31]],
|
||||
['gD_J-R8tOb977BtL', 'f7A81Qbh8gQhfRpOmtz5-ZJqBxiQJ6myBhGfqK7BVaGBL_W2MvfB', [106, 38, 140, 196, 141, 190, 232, 110]],
|
||||
['ZxHO4JJ8p45jTUXU', 'fs4Oy8mPZS6919SZ7gDyKIILDkXnPt8SsXkfBd-Mnm4wO6alw-veQD9', [209, 53, 104, 100, 102, 136, 84, 134]],
|
||||
['2bVzT0moojGNQgIX', 'nuyb-AgYY-rsmhtdav3LC7meSPy1dCosjSw0YAvgP', [1, 201, 247, 25, 104, 147, 148, 252]],
|
||||
['FicyyNT0BRua05i9', 'TG4leSS_mcrZ_L68GKFdxc4-McFCCtdG7QpbPu_MolD5luE6n3dKlPzb9MvfvkiZKi', [136, 150, 66, 224, 178, 235, 114, 238]],
|
||||
['g5Qaf7mQAIxuHR0O', 'A6u5gtb1yMSiGlWVt3exYsRS', [169, 20, 115, 32, 43, 71, 21, 193]],
|
||||
['aOACI6GP6u4WFyxp', '1eEx55L3E9MZga7l1WzpnKfI', [177, 26, 15, 27, 217, 101, 69, 195]],
|
||||
['Rr2jLg-asIQrlaRJ', 'rgALEbs', [163, 103, 250, 90, 4, 46, 69, 32]],
|
||||
['p8qW0oYzj5zi55s5', 'V1ZCoK73ifwcnzPjQEN7Q79MtZCskcpqiE3gfbqYPYRmy-q0lPxopkZZp2lNWKkpL_q5z', [29, 121, 240, 174, 51, 38, 238, 123]],
|
||||
['wA0cNUJOhIMpiopE', 'U2RE2L2zZysyOTcsj5_JosVDaMRtUxkRWVCeBH0AeodMvYGBcHizhxc2QM89', [40, 230, 148, 164, 7, 168, 3, 46]],
|
||||
['zBCN1w4ypWCEfpwC', 'VRcTwONsyRQIy2ymVniMmry', [184, 177, 56, 54, 152, 189, 120, 222]],
|
||||
['i8cumEDwOxSXT0gL', 'ifKav', [53, 190, 193, 228, 179, 41, 246, 171]],
|
||||
['g3EswbaCSNMsegzm', 'rTFnEuEDlwBB0Dw_q3-FUSaTCEjWe0pOPZDIWD35Us08Qa-nulc57YjDoGphUfBamq', [157, 64, 119, 179, 60, 147, 48, 17]],
|
||||
['iYsckWoQTk5ap8YO', 'wIyTqa43-_GiZlHJ8UXcD_tnqKikH5DZUWxdQ1xjYMyzCr2JvKKRBm8BbcDl_Q8p', [96, 237, 170, 183, 48, 45, 116, 106]],
|
||||
['Iyk5MoAjoWq4n8bG', 'IV2N5MC6kvk95ykEzb3jj0A7Sv0jjif45SR1avc0bRWot2aW', [99, 23, 149, 225, 242, 204, 47, 7]],
|
||||
['NfzdRXCegRRsHHYj', '5uLBPbyFQqiv', [136, 45, 110, 192, 36, 204, 171, 218]],
|
||||
['YiJTXegVwaNDtlpl', 'DbwKoF3CI5kd2JRKwfyuLpeGd6sFhqI0t43C2ph', [188, 126, 147, 191, 9, 114, 107, 60]],
|
||||
['ZuUlFM-yEzZ9XHKj', 'errecd71', [158, 231, 84, 47, 149, 227, 92, 111]],
|
||||
['EtEXELa6V_NSjvEh', 'yrTjrRuW8mJc3utw2JUH7iIW-J5vF3t9GC1-ZvRmO8UXNsG8-I3Iqgtinzoabqqbs1yvR', [186, 52, 144, 215, 104, 246, 174, 71]],
|
||||
['q2uA_VwMnaBtAgTx', 'uJOymuDgBBS9Ec56JRGmKYsMHoGLCKA5wzwhtYf-g8-IT7UsAX1JHFGSV0EF', [176, 65, 188, 134, 212, 6, 97, 186]],
|
||||
['4RmqR10QiIZDDKNO', 'oWY0Aj2CDCWuEFhdNHq2RFcGJD0sSRxK5K', [114, 28, 238, 228, 122, 40, 82, 13]],
|
||||
['a9DfUPCLyQ_yrNIa', '5G-6AVe7CBJl-NuuUN_7TN', [95, 206, 124, 185, 194, 207, 227, 111]],
|
||||
['8oB5yG87C2v5j0_4', '1S-aiUNRJ2c', [123, 42, 242, 79, 90, 36, 208, 81]],
|
||||
['ZA2ZT22NXwD_UvTM', 'UpV3pLYniWPm-PnWUAbBNeO4V-zuuw6IZQ1ZprLsC_LjGdSJP7rZCnoPz', [189, 209, 102, 128, 246, 141, 212, 109]],
|
||||
['ycz6aiuQFGKxZVsM', 'fBuJp4_A_hiq--4uBhxjXfT3nRaYEJ8azW2_FKooXdSVRv2Y03VoWzPzG', [241, 127, 162, 199, 73, 10, 75, 24]],
|
||||
['eAmt0pClMyL8Sk69', 'JFzXjfJhEMUCYEDrBKRM9OFFK0PSX', [176, 167, 43, 60, 16, 69, 194, 2]],
|
||||
['CTFnU2nwy9s1_kBj', 'hEHqR0idFTzbvG193aLYj6y2DFPi2UKQut_A--43PdN1XF', [6, 84, 156, 248, 125, 55, 230, 121]],
|
||||
['CAhom0f872WEDXP6', 'dmX', [203, 98, 175, 172, 19, 3, 244, 177]],
|
||||
['aON1dHrq90SbG8Hx', 'v7LyiwuCrB7EgAibPve6Yg2gLmggxE6j7ocR37EudrH_P9XX2rQK', [147, 73, 50, 63, 71, 98, 203, 42]]
|
||||
]
|
||||
|
||||
test('crypto_shorthash', function (t) {
|
||||
const out = Buffer.alloc(sodium.crypto_shorthash_BYTES)
|
||||
const inp = Buffer.from('Hej, Verden!')
|
||||
const key = Buffer.alloc(sodium.crypto_shorthash_KEYBYTES)
|
||||
|
||||
t.exception.all(function () {
|
||||
sodium.crypto_shorthash(Buffer.alloc(0), inp)
|
||||
}, 'throws on bad input')
|
||||
|
||||
sodium.crypto_shorthash(out, inp, key)
|
||||
|
||||
const result = '6a29984f782e684e'
|
||||
t.alike(out.toString('hex'), result, 'hashed the string')
|
||||
})
|
||||
|
||||
test('constants', function (assert) {
|
||||
assert.ok(sodium.crypto_shorthash_PRIMITIVE)
|
||||
assert.ok(sodium.crypto_shorthash_KEYBYTES > 0)
|
||||
assert.ok(sodium.crypto_shorthash_BYTES > 0)
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test('crypto_shorthash fixtures', function (assert) {
|
||||
run(assert)
|
||||
})
|
||||
|
||||
test('crypto_shorthash fixtures (wasm)', function (assert) {
|
||||
if (!sodium.crypto_shorthash_WASM_SUPPORTED) {
|
||||
assert.pass('wasm not supported')
|
||||
assert.end()
|
||||
return
|
||||
}
|
||||
|
||||
assert.ok(sodium.crypto_shorthash_WASM_LOADED)
|
||||
run(assert)
|
||||
})
|
||||
|
||||
function run (assert) {
|
||||
for (let i = 0; i < vectors.length; i++) {
|
||||
const v = vectors[i]
|
||||
const key = Buffer.from(v[0])
|
||||
const message = Buffer.from(v[1])
|
||||
const expected = Buffer.from(v[2])
|
||||
const out = Buffer.alloc(sodium.crypto_shorthash_BYTES)
|
||||
|
||||
sodium.crypto_shorthash(out, message, key)
|
||||
if (Buffer.compare(out, expected) !== 0) {
|
||||
assert.fail('Failed on fixture #' + i)
|
||||
assert.end()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
assert.pass('Passed all fixtures')
|
||||
assert.end()
|
||||
}
|
||||
@@ -0,0 +1,334 @@
|
||||
/* eslint-disable camelcase */
|
||||
const test = require('brittle')
|
||||
const sodium = require('..')
|
||||
const fixtures = require('./fixtures/crypto_sign.json')
|
||||
|
||||
test('crypto_sign_ed25519_sk_to_pk', function (t) {
|
||||
const pk = Buffer.alloc(sodium.crypto_sign_PUBLICKEYBYTES)
|
||||
const pke = Buffer.alloc(sodium.crypto_sign_PUBLICKEYBYTES)
|
||||
const sk = Buffer.alloc(sodium.crypto_sign_SECRETKEYBYTES)
|
||||
|
||||
sodium.crypto_sign_keypair(pk, sk)
|
||||
sodium.crypto_sign_ed25519_sk_to_pk(pke, sk)
|
||||
|
||||
t.ok(pk.equals(pke))
|
||||
})
|
||||
|
||||
test('crypto_sign_seed_keypair', function (t) {
|
||||
const pk = Buffer.alloc(sodium.crypto_sign_PUBLICKEYBYTES)
|
||||
const sk = Buffer.alloc(sodium.crypto_sign_SECRETKEYBYTES)
|
||||
const seed = Buffer.alloc(sodium.crypto_sign_SEEDBYTES, 'lo')
|
||||
|
||||
t.exception.all(function () {
|
||||
sodium.crypto_sign_seed_keypair()
|
||||
}, 'should validate input')
|
||||
|
||||
t.exception.all(function () {
|
||||
sodium.crypto_sign_seed_keypair(Buffer.alloc(0), Buffer.alloc(0), Buffer.alloc(0))
|
||||
}, 'should validate input length')
|
||||
|
||||
sodium.crypto_sign_seed_keypair(pk, sk, seed)
|
||||
|
||||
const eSk = '6c6f6c6f6c6f6c6f6c6f6c6f6c6f6c6f6c6f6c6f6c6f6c6f6c6f6c6f6c6f6c6f41eb5b4dba29b19e391d9a4d1a4a879b27958ff3734e10cfbf1f46d68f4d3038'
|
||||
const ePk = '41eb5b4dba29b19e391d9a4d1a4a879b27958ff3734e10cfbf1f46d68f4d3038'
|
||||
|
||||
t.alike(pk.toString('hex'), ePk, 'seeded public key')
|
||||
t.alike(sk.toString('hex'), eSk, 'seeded secret key')
|
||||
})
|
||||
|
||||
test('crypto_sign_keypair', function (t) {
|
||||
const pk = Buffer.alloc(sodium.crypto_sign_PUBLICKEYBYTES)
|
||||
const sk = Buffer.alloc(sodium.crypto_sign_SECRETKEYBYTES)
|
||||
|
||||
sodium.crypto_sign_keypair(pk, sk)
|
||||
|
||||
t.not(pk, Buffer.alloc(pk.length), 'made public key')
|
||||
t.not(sk, Buffer.alloc(sk.length), 'made secret key')
|
||||
|
||||
t.exception.all(function () {
|
||||
sodium.crypto_sign_keypair()
|
||||
}, 'should validate input')
|
||||
|
||||
t.exception.all(function () {
|
||||
sodium.crypto_sign_keypair(Buffer.alloc(0), Buffer.alloc(0))
|
||||
}, 'should validate input length')
|
||||
})
|
||||
|
||||
test('crypto_sign', function (t) {
|
||||
const pk = Buffer.alloc(sodium.crypto_sign_PUBLICKEYBYTES)
|
||||
const sk = Buffer.alloc(sodium.crypto_sign_SECRETKEYBYTES)
|
||||
|
||||
sodium.crypto_sign_keypair(pk, sk)
|
||||
|
||||
const message = Buffer.from('Hello, World!')
|
||||
const signedMessage = Buffer.alloc(message.length + sodium.crypto_sign_BYTES)
|
||||
|
||||
sodium.crypto_sign(signedMessage, message, sk)
|
||||
|
||||
t.alike(signedMessage.slice(-message.length), message, 'contains message')
|
||||
|
||||
const output = Buffer.alloc(message.length)
|
||||
|
||||
t.absent(sodium.crypto_sign_open(output, Buffer.alloc(signedMessage.length), pk), 'was not signed')
|
||||
t.ok(sodium.crypto_sign_open(output, signedMessage, pk), 'was signed')
|
||||
|
||||
t.alike(output, message, 'same message')
|
||||
})
|
||||
|
||||
test('crypto_sign_detached', function (t) {
|
||||
const pk = Buffer.alloc(sodium.crypto_sign_PUBLICKEYBYTES)
|
||||
const sk = Buffer.alloc(sodium.crypto_sign_SECRETKEYBYTES)
|
||||
|
||||
sodium.crypto_sign_keypair(pk, sk)
|
||||
|
||||
const message = Buffer.from('Hello, World!')
|
||||
const signature = Buffer.alloc(sodium.crypto_sign_BYTES)
|
||||
|
||||
sodium.crypto_sign_detached(signature, message, sk)
|
||||
|
||||
t.absent(sodium.crypto_sign_verify_detached(Buffer.concat([Buffer.alloc(1), signature]), message, pk), 'was not signed')
|
||||
t.ok(sodium.crypto_sign_verify_detached(signature, message, pk), 'was signed')
|
||||
})
|
||||
|
||||
test('crypto_sign_open fixtures', function (t) {
|
||||
for (let i = 0; i < fixtures.length; i++) {
|
||||
const publicKey = new Uint8Array(fixtures[i][1])
|
||||
const message = new Uint8Array(fixtures[i][3])
|
||||
const signed = new Uint8Array([].concat(fixtures[i][2], fixtures[i][3]))
|
||||
|
||||
if (!sodium.crypto_sign_open(message, signed, publicKey)) {
|
||||
t.fail('Failed on fixture #' + i)
|
||||
t.end()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
t.pass('Passed all fixtures')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('crypto_sign fixtures', function (t) {
|
||||
const fixtures = require('./fixtures/crypto_sign.json')
|
||||
|
||||
for (let i = 0; i < fixtures.length; i++) {
|
||||
const secretKey = new Uint8Array([].concat(fixtures[i][0], fixtures[i][1]))
|
||||
const message = new Uint8Array(fixtures[i][3])
|
||||
|
||||
const expected = new Uint8Array([].concat(fixtures[i][2], fixtures[i][3]))
|
||||
const actual = new Uint8Array(sodium.crypto_sign_BYTES + message.length)
|
||||
|
||||
sodium.crypto_sign(actual, message, secretKey)
|
||||
|
||||
if (Buffer.compare(actual, expected) !== 0) {
|
||||
t.fail('Failed on fixture #' + i)
|
||||
t.end()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
t.pass('Passed all fixtures')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('crypto_sign_verify_detached fixtures', function (t) {
|
||||
const fixtures = require('./fixtures/crypto_sign.json')
|
||||
|
||||
for (let i = 0; i < fixtures.length; i++) {
|
||||
const publicKey = new Uint8Array(fixtures[i][1])
|
||||
const message = new Uint8Array(fixtures[i][3])
|
||||
const signature = new Uint8Array(fixtures[i][2])
|
||||
|
||||
if (!sodium.crypto_sign_verify_detached(signature, message, publicKey)) {
|
||||
t.fail('Failed on fixture #' + i)
|
||||
t.end()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
t.pass('Passed all fixtures')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('crypto_sign_detached fixtures', function (t) {
|
||||
const fixtures = require('./fixtures/crypto_sign.json')
|
||||
|
||||
for (let i = 0; i < fixtures.length; i++) {
|
||||
const secretKey = new Uint8Array([].concat(fixtures[i][0], fixtures[i][1]))
|
||||
const message = new Uint8Array(fixtures[i][3])
|
||||
|
||||
const expected = new Uint8Array(fixtures[i][2])
|
||||
const actual = new Uint8Array(sodium.crypto_sign_BYTES)
|
||||
|
||||
sodium.crypto_sign_detached(actual, message, secretKey)
|
||||
|
||||
if (Buffer.compare(actual, expected) !== 0) {
|
||||
t.fail('Failed on fixture #' + i)
|
||||
t.end()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
t.pass('Passed all fixtures')
|
||||
t.end()
|
||||
})
|
||||
|
||||
/* eslint-disable camelcase */
|
||||
test('libsodium', function (t) {
|
||||
const sig = new Uint8Array(sodium.crypto_sign_BYTES)
|
||||
const sm = new Uint8Array(1024 + sodium.crypto_sign_BYTES)
|
||||
const skpk = new Uint8Array(sodium.crypto_sign_SECRETKEYBYTES)
|
||||
const pk = new Uint8Array(sodium.crypto_sign_PUBLICKEYBYTES)
|
||||
const sk = new Uint8Array(sodium.crypto_sign_SECRETKEYBYTES)
|
||||
|
||||
let smlen
|
||||
let i
|
||||
let test
|
||||
|
||||
sig.fill(0)
|
||||
|
||||
let pass = true
|
||||
for (i = 0; i < fixtures.length; i++) {
|
||||
test = parseTest(fixtures[i])
|
||||
|
||||
skpk.set(test.sk)
|
||||
skpk.set(test.pk, sodium.crypto_sign_SEEDBYTES)
|
||||
|
||||
smlen = sodium.crypto_sign_BYTES + test.m.byteLength
|
||||
|
||||
sodium.crypto_sign(sm.subarray(0, test.m.byteLength + sodium.crypto_sign_BYTES), test.m, skpk)
|
||||
pass &= Buffer.compare(test.sig, sm.subarray(0, 64)) === 0
|
||||
pass &= sodium.crypto_sign_open(test.m, sm.subarray(0, smlen), test.pk)
|
||||
|
||||
sodium.crypto_sign_detached(sig, test.m, skpk)
|
||||
|
||||
pass &= sig.byteLength !== 0 && sig.byteLength <= sodium.crypto_sign_BYTES
|
||||
pass &= Buffer.compare(test.sig, sig) === 0
|
||||
pass &= sodium.crypto_sign_verify_detached(sig, test.m.subarray(0, i), test.pk)
|
||||
|
||||
if (!pass) t.fail('failed on fixture #' + i)
|
||||
}
|
||||
t.pass('passed all fixtures')
|
||||
|
||||
for (let j = 1; j < 8; j++) {
|
||||
sig[63] ^= (j << 5)
|
||||
|
||||
t.absent(sodium.crypto_sign_verify_detached(sig, test.m.subarray(0, i), test.pk))
|
||||
|
||||
sig[63] ^= (j << 5)
|
||||
}
|
||||
|
||||
pk.fill(0)
|
||||
t.absent(sodium.crypto_sign_verify_detached(sig, test.m.subarray(0, i), pk))
|
||||
|
||||
sig.subarray(0, 32).fill(0xff)
|
||||
sig[0] = 0xdb
|
||||
|
||||
t.absent(sodium.crypto_sign_verify_detached(sig, test.m.subarray(0, i), pk))
|
||||
sodium.crypto_sign_detached(sig, test.m.subarray(0, i), skpk)
|
||||
|
||||
hex2bin(pk, '3eee494fb9eac773144e34b0c755affaf33ea782c0722e5ea8b150e61209ab36')
|
||||
t.absent(sodium.crypto_sign_verify_detached(sig, test.m.subarray(0, i), pk))
|
||||
|
||||
hex2bin(pk, '0200000000000000000000000000000000000000000000000000000000000000')
|
||||
t.absent(sodium.crypto_sign_verify_detached(sig, test.m.subarray(0, i), pk))
|
||||
|
||||
hex2bin(pk, '0500000000000000000000000000000000000000000000000000000000000000')
|
||||
t.absent(sodium.crypto_sign_verify_detached(sig, test.m.subarray(0, i), pk))
|
||||
|
||||
const keypair_seed = new Uint8Array([
|
||||
0x42, 0x11, 0x51, 0xa4, 0x59, 0xfa, 0xea, 0xde, 0x3d, 0x24, 0x71,
|
||||
0x15, 0xf9, 0x4a, 0xed, 0xae, 0x42, 0x31, 0x81, 0x24, 0x09, 0x5a,
|
||||
0xfa, 0xbe, 0x4d, 0x14, 0x51, 0xa5, 0x59, 0xfa, 0xed, 0xee
|
||||
])
|
||||
|
||||
t.execution(() => sodium.crypto_sign_seed_keypair(pk, sk, keypair_seed))
|
||||
t.execution(() => sodium.crypto_sign_keypair(pk, sk))
|
||||
|
||||
t.ok(sodium.crypto_sign_BYTES > 0)
|
||||
t.ok(sodium.crypto_sign_SEEDBYTES > 0)
|
||||
t.ok(sodium.crypto_sign_PUBLICKEYBYTES > 0)
|
||||
t.ok(sodium.crypto_sign_SECRETKEYBYTES > 0)
|
||||
t.is(sodium.crypto_sign_BYTES, 64)
|
||||
t.is(sodium.crypto_sign_SEEDBYTES, 32)
|
||||
t.is(sodium.crypto_sign_PUBLICKEYBYTES, 32)
|
||||
t.is(sodium.crypto_sign_SECRETKEYBYTES, 64)
|
||||
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('ed25519 convert', function (t) {
|
||||
const keypair_seed = new Uint8Array([
|
||||
0x42, 0x11, 0x51, 0xa4, 0x59, 0xfa, 0xea, 0xde, 0x3d, 0x24, 0x71,
|
||||
0x15, 0xf9, 0x4a, 0xed, 0xae, 0x42, 0x31, 0x81, 0x24, 0x09, 0x5a,
|
||||
0xfa, 0xbe, 0x4d, 0x14, 0x51, 0xa5, 0x59, 0xfa, 0xed, 0xee
|
||||
])
|
||||
|
||||
const ed25519_pk = new Uint8Array(sodium.crypto_sign_PUBLICKEYBYTES)
|
||||
const ed25519_skpk = new Uint8Array(sodium.crypto_sign_SECRETKEYBYTES)
|
||||
const curve25519_pk = new Uint8Array(sodium.crypto_scalarmult_BYTES)
|
||||
const curve25519_pk2 = new Uint8Array(sodium.crypto_scalarmult_BYTES)
|
||||
const curve25519_sk = new Uint8Array(sodium.crypto_scalarmult_BYTES)
|
||||
|
||||
t.ok(sodium.crypto_sign_SEEDBYTES <= sodium.crypto_hash_sha512_BYTES)
|
||||
|
||||
sodium.crypto_sign_seed_keypair(ed25519_pk, ed25519_skpk, keypair_seed)
|
||||
sodium.crypto_sign_ed25519_pk_to_curve25519(curve25519_pk, ed25519_pk)
|
||||
sodium.crypto_sign_ed25519_sk_to_curve25519(curve25519_sk, ed25519_skpk)
|
||||
|
||||
const expected_pk = new Uint8Array([
|
||||
0xf1, 0x81, 0x4f, 0x0e, 0x8f, 0xf1, 0x04, 0x3d, 0x8a, 0x44, 0xd2, 0x5b,
|
||||
0xab, 0xff, 0x3c, 0xed, 0xca, 0xe6, 0xc2, 0x2c, 0x3e, 0xda, 0xa4, 0x8f,
|
||||
0x85, 0x7a, 0xe7, 0x0d, 0xe2, 0xba, 0xae, 0x50
|
||||
])
|
||||
|
||||
const expected_sk = new Uint8Array([
|
||||
0x80, 0x52, 0x03, 0x03, 0x76, 0xd4, 0x71, 0x12, 0xbe, 0x7f, 0x73, 0xed,
|
||||
0x7a, 0x01, 0x92, 0x93, 0xdd, 0x12, 0xad, 0x91, 0x0b, 0x65, 0x44, 0x55,
|
||||
0x79, 0x8b, 0x46, 0x67, 0xd7, 0x3d, 0xe1, 0x66
|
||||
])
|
||||
|
||||
t.alike(curve25519_pk, expected_pk)
|
||||
t.alike(curve25519_sk, expected_sk)
|
||||
|
||||
for (let i = 0; i < 500; i++) {
|
||||
sodium.crypto_sign_keypair(ed25519_pk, ed25519_skpk)
|
||||
sodium.crypto_sign_ed25519_pk_to_curve25519(curve25519_pk, ed25519_pk)
|
||||
|
||||
sodium.crypto_sign_ed25519_sk_to_curve25519(curve25519_sk, ed25519_skpk)
|
||||
sodium.crypto_scalarmult_base(curve25519_pk2, curve25519_sk)
|
||||
if (Buffer.compare(curve25519_pk, curve25519_pk2) !== 0) t.fail()
|
||||
}
|
||||
t.pass('passed all cases')
|
||||
|
||||
ed25519_pk.fill(0)
|
||||
t.exception(() => {
|
||||
sodium.crypto_sign_ed25519_pk_to_curve25519(curve25519_pk, ed25519_pk)
|
||||
})
|
||||
|
||||
t.exception(() => {
|
||||
ed25519_pk[0] = 2
|
||||
sodium.crypto_sign_ed25519_pk_to_curve25519(curve25519_pk, ed25519_pk)
|
||||
})
|
||||
|
||||
t.exception(() => {
|
||||
ed25519_pk[0] = 5
|
||||
sodium.crypto_sign_ed25519_pk_to_curve25519(curve25519_pk, ed25519_pk)
|
||||
})
|
||||
|
||||
t.end()
|
||||
})
|
||||
|
||||
function parseTest (t) {
|
||||
return {
|
||||
sk: new Uint8Array(t[0]),
|
||||
pk: new Uint8Array(t[1]),
|
||||
sig: new Uint8Array(t[2]),
|
||||
m: new Uint8Array(t[3])
|
||||
}
|
||||
}
|
||||
|
||||
function hex2bin (buf, hex) {
|
||||
for (let i = 0; i < hex.length / 2; i++) {
|
||||
buf[i] = Number('0x' + hex.slice(2 * i, 2 * i + 1))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
/* eslint-disable camelcase */
|
||||
const test = require('brittle')
|
||||
const sodium = require('..')
|
||||
|
||||
test('crypto_stream', function (t) {
|
||||
const buf = Buffer.alloc(50)
|
||||
const nonce = random(sodium.crypto_stream_NONCEBYTES)
|
||||
const key = random(sodium.crypto_stream_KEYBYTES)
|
||||
|
||||
sodium.crypto_stream(buf, nonce, key)
|
||||
|
||||
t.not(buf, Buffer.alloc(50), 'contains noise now')
|
||||
const copy = Buffer.from(buf.toString('hex'), 'hex')
|
||||
|
||||
sodium.crypto_stream(buf, nonce, key)
|
||||
t.alike(buf, copy, 'predictable from nonce, key')
|
||||
})
|
||||
|
||||
test('crypto_stream_xor', function (t) {
|
||||
const message = Buffer.from('Hello, World!')
|
||||
const nonce = random(sodium.crypto_stream_NONCEBYTES)
|
||||
const key = random(sodium.crypto_stream_KEYBYTES)
|
||||
|
||||
sodium.crypto_stream_xor(message, message, nonce, key)
|
||||
|
||||
t.not(message, Buffer.from('Hello, World!'), 'encrypted')
|
||||
|
||||
sodium.crypto_stream_xor(message, message, nonce, key)
|
||||
|
||||
t.alike(message, Buffer.from('Hello, World!'), 'decrypted')
|
||||
})
|
||||
|
||||
test.skip('crypto_stream_xor state', function (t) {
|
||||
const message = Buffer.from('Hello, world!')
|
||||
const nonce = random(sodium.crypto_stream_NONCEBYTES)
|
||||
const key = random(sodium.crypto_stream_KEYBYTES)
|
||||
|
||||
const out = Buffer.alloc(message.length)
|
||||
|
||||
const state = Buffer.alloc(sodium.crypto_stream_xor_STATEBYTES)
|
||||
sodium.crypto_stream_xor_init(state, nonce, key)
|
||||
|
||||
for (let i = 0; i < message.length; i++) {
|
||||
sodium.crypto_stream_xor_update(state, out.slice(i, i + 1), message.slice(i, i + 1))
|
||||
}
|
||||
|
||||
sodium.crypto_stream_xor_final(state)
|
||||
sodium.crypto_stream_xor(out, out, nonce, key)
|
||||
t.alike(out, message, 'decrypted')
|
||||
})
|
||||
|
||||
test.skip('crypto_stream_xor state with empty buffers', function (t) {
|
||||
const message = Buffer.from('Hello, world!')
|
||||
const nonce = random(sodium.crypto_stream_NONCEBYTES)
|
||||
const key = random(sodium.crypto_stream_KEYBYTES)
|
||||
|
||||
const out = Buffer.alloc(message.length)
|
||||
|
||||
const state = Buffer.alloc(sodium.crypto_stream_xor_STATEBYTES)
|
||||
sodium.crypto_stream_xor_init(state, nonce, key)
|
||||
|
||||
sodium.crypto_stream_xor_update(state, Buffer.alloc(0), Buffer.alloc(0))
|
||||
|
||||
for (let i = 0; i < message.length; i++) {
|
||||
sodium.crypto_stream_xor_update(state, out.slice(i, i + 1), message.slice(i, i + 1))
|
||||
sodium.crypto_stream_xor_update(state, Buffer.alloc(0), Buffer.alloc(0))
|
||||
}
|
||||
|
||||
sodium.crypto_stream_xor_final(state)
|
||||
sodium.crypto_stream_xor(out, out, nonce, key)
|
||||
t.alike(out, message, 'decrypted')
|
||||
})
|
||||
|
||||
test.skip('crypto_stream_xor state long stream', function (t) {
|
||||
const nonce = random(sodium.crypto_stream_NONCEBYTES)
|
||||
const key = random(sodium.crypto_stream_KEYBYTES)
|
||||
|
||||
const encState = Buffer.alloc(sodium.crypto_stream_xor_STATEBYTES)
|
||||
const decState = Buffer.alloc(sodium.crypto_stream_xor_STATEBYTES)
|
||||
|
||||
sodium.crypto_stream_xor_init(encState, nonce, key)
|
||||
sodium.crypto_stream_xor_init(decState, nonce, key)
|
||||
const plain = []
|
||||
const encrypted = []
|
||||
const decrypted = []
|
||||
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
const next = random(61)
|
||||
plain.push(next)
|
||||
|
||||
const enc = Buffer.alloc(61)
|
||||
sodium.crypto_stream_xor_update(encState, enc, next)
|
||||
encrypted.push(enc)
|
||||
|
||||
const dec = Buffer.alloc(61)
|
||||
sodium.crypto_stream_xor_update(decState, dec, enc)
|
||||
decrypted.push(dec)
|
||||
}
|
||||
|
||||
const enc2 = Buffer.alloc(1000 * 61)
|
||||
sodium.crypto_stream_xor(enc2, Buffer.concat(plain), nonce, key)
|
||||
|
||||
t.alike(Buffer.concat(encrypted), enc2, 'same as encrypting all at once')
|
||||
t.alike(Buffer.concat(decrypted), Buffer.concat(plain), 'decrypts')
|
||||
})
|
||||
|
||||
test.skip('crypto_stream_xor state long stream (random chunks)', function (t) {
|
||||
const nonce = random(sodium.crypto_stream_NONCEBYTES)
|
||||
const key = random(sodium.crypto_stream_KEYBYTES)
|
||||
|
||||
const encState = Buffer.alloc(sodium.crypto_stream_xor_STATEBYTES)
|
||||
const decState = Buffer.alloc(sodium.crypto_stream_xor_STATEBYTES)
|
||||
|
||||
sodium.crypto_stream_xor_init(encState, nonce, key)
|
||||
sodium.crypto_stream_xor_init(decState, nonce, key)
|
||||
const plain = []
|
||||
const encrypted = []
|
||||
const decrypted = []
|
||||
|
||||
for (let i = 0; i < 10000; i++) {
|
||||
const len = Math.floor(Math.random() * 256)
|
||||
const next = random(len)
|
||||
plain.push(next)
|
||||
|
||||
const enc = Buffer.alloc(len)
|
||||
sodium.crypto_stream_xor_update(encState, enc, next)
|
||||
encrypted.push(enc)
|
||||
|
||||
const dec = Buffer.alloc(len)
|
||||
sodium.crypto_stream_xor_update(decState, dec, enc)
|
||||
decrypted.push(dec)
|
||||
}
|
||||
|
||||
const enc2 = Buffer.alloc(Buffer.concat(plain).length)
|
||||
sodium.crypto_stream_xor(enc2, Buffer.concat(plain), nonce, key)
|
||||
|
||||
t.alike(Buffer.concat(encrypted), enc2, 'same as encrypting all at once')
|
||||
t.alike(Buffer.concat(decrypted), Buffer.concat(plain), 'decrypts')
|
||||
})
|
||||
|
||||
test.skip('crypto_stream_xor state long stream (random chunks) with empty buffers', function (t) {
|
||||
const nonce = random(sodium.crypto_stream_NONCEBYTES)
|
||||
const key = random(sodium.crypto_stream_KEYBYTES)
|
||||
|
||||
const encState = Buffer.alloc(sodium.crypto_stream_xor_STATEBYTES)
|
||||
const decState = Buffer.alloc(sodium.crypto_stream_xor_STATEBYTES)
|
||||
|
||||
sodium.crypto_stream_xor_init(encState, nonce, key)
|
||||
sodium.crypto_stream_xor_init(decState, nonce, key)
|
||||
const plain = []
|
||||
const encrypted = []
|
||||
const decrypted = []
|
||||
|
||||
for (let i = 0; i < 10000; i++) {
|
||||
const len = Math.floor(Math.random() * 256)
|
||||
const next = random(len)
|
||||
plain.push(next)
|
||||
|
||||
sodium.crypto_stream_xor_update(encState, Buffer.alloc(0), Buffer.alloc(0))
|
||||
|
||||
const enc = Buffer.alloc(len)
|
||||
sodium.crypto_stream_xor_update(encState, enc, next)
|
||||
encrypted.push(enc)
|
||||
|
||||
const dec = Buffer.alloc(len)
|
||||
sodium.crypto_stream_xor_update(decState, dec, enc)
|
||||
decrypted.push(dec)
|
||||
sodium.crypto_stream_xor_update(decState, Buffer.alloc(0), Buffer.alloc(0))
|
||||
}
|
||||
|
||||
const enc2 = Buffer.alloc(Buffer.concat(plain).length)
|
||||
sodium.crypto_stream_xor(enc2, Buffer.concat(plain), nonce, key)
|
||||
|
||||
t.alike(Buffer.concat(encrypted), enc2, 'same as encrypting all at once')
|
||||
t.alike(Buffer.concat(decrypted), Buffer.concat(plain), 'decrypts')
|
||||
})
|
||||
|
||||
test.skip('crypto_stream_xor state after GC', function (t) {
|
||||
const message = Buffer.from('Hello, world!')
|
||||
let nonce = random(sodium.crypto_stream_NONCEBYTES)
|
||||
let key = random(sodium.crypto_stream_KEYBYTES)
|
||||
|
||||
const out = Buffer.alloc(message.length)
|
||||
|
||||
const state = Buffer.alloc(sodium.crypto_stream_xor_STATEBYTES)
|
||||
sodium.crypto_stream_xor_init(state, nonce, key)
|
||||
|
||||
const nonceCopy = Buffer.from(nonce.toString('hex'), 'hex')
|
||||
const keyCopy = Buffer.from(key.toString('hex'), 'hex')
|
||||
nonce = null
|
||||
key = null
|
||||
|
||||
forceGC()
|
||||
|
||||
for (let i = 0; i < message.length; i++) {
|
||||
sodium.crypto_stream_xor_update(state, out.slice(i, i + 1), message.slice(i, i + 1))
|
||||
}
|
||||
|
||||
sodium.crypto_stream_xor_final(state)
|
||||
sodium.crypto_stream_xor(out, out, nonceCopy, keyCopy)
|
||||
t.alike(out, message, 'decrypted')
|
||||
})
|
||||
|
||||
function random (n) {
|
||||
const buf = Buffer.alloc(n)
|
||||
sodium.randombytes_buf(buf)
|
||||
return buf
|
||||
}
|
||||
|
||||
function forceGC () {
|
||||
require('v8').setFlagsFromString('--expose-gc')
|
||||
require('vm').runInNewContext('gc')()
|
||||
}
|
||||
@@ -0,0 +1,284 @@
|
||||
/* eslint-disable camelcase */
|
||||
const test = require('brittle')
|
||||
const sodium = require('..')
|
||||
|
||||
const tests = [
|
||||
['0000000000000000000000000000000000000000000000000000000000000000', '0000000000000000', '76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7da41597c5157488d7724e03fb8d84a376a43b8f41518a11cc387b669b2ee65869f07e7be5551387a98ba977c732d080dcb0f29a048e3656912c6533e32ee7aed29b721769ce64e43d57133b074d839d531ed1f28510afb45ace10a1f4b794d6f2d09a0e663266ce1ae7ed1081968a0758e718e997bd362c6b0c34634a9a0b35d'],
|
||||
['0000000000000000000000000000000000000000000000000000000000000001', '0000000000000000', '4540f05a9f1fb296d7736e7b208e3c96eb4fe1834688d2604f450952ed432d41bbe2a0b6ea7566d2a5d1e7e20d42af2c53d792b1c43fea817e9ad275ae5469633aeb5224ecf849929b9d828db1ced4dd832025e8018b8160b82284f3c949aa5a8eca00bbb4a73bdad192b5c42f73f2fd4e273644c8b36125a64addeb006c13a096d68b9ff7b57e7090f880392effd5b297a83bbaf2fbe8cf5d4618965e3dc776'],
|
||||
['0000000000000000000000000000000000000000000000000000000000000000', '0000000000000001', 'de9cba7bf3d69ef5e786dc63973f653a0b49e015adbff7134fcb7df137821031e85a050278a7084527214f73efc7fa5b5277062eb7a0433e445f41e31afab757283547e3d3d30ee0371c1e6025ff4c91b794a291cf7568d48ff84b37329e2730b12738a072a2b2c7169e326fe4893a7b2421bb910b79599a7ce4fbaee86be427c5ee0e8225eb6f48231fd504939d59eac8bd106cc138779b893c54da8758f62a'],
|
||||
['0000000000000000000000000000000000000000000000000000000000000000', '0100000000000000', 'ef3fdfd6c61578fbf5cf35bd3dd33b8009631634d21e42ac33960bd138e50d32111e4caf237ee53ca8ad6426194a88545ddc497a0b466e7d6bbdb0041b2f586b5305e5e44aff19b235936144675efbe4409eb7e8e5f1430f5f5836aeb49bb5328b017c4b9dc11f8a03863fa803dc71d5726b2b6b31aa32708afe5af1d6b690584d58792b271e5fdb92c486051c48b79a4d48a109bb2d0477956e74c25e93c3c2'],
|
||||
['000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f', '0001020304050607', 'f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59ea1c53f15916155c2be8241a38008b9a26bc35941e2444177c8ade6689de95264986d95889fb60e84629c9bd9a5acb1cc118be563eb9b3a4a472f82e09a7e778492b562ef7130e88dfe031c79db9d4f7c7a899151b9a475032b63fc385245fe054e3dd5a97a5f576fe064025']
|
||||
]
|
||||
|
||||
const vectors = [
|
||||
'f7010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101',
|
||||
'f798a189040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404',
|
||||
'f798a189f195e6070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707',
|
||||
'f798a189f195e66982100a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a',
|
||||
'f798a189f195e66982105ffb640d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d',
|
||||
'f798a189f195e66982105ffb640bb775101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010',
|
||||
'f798a189f195e66982105ffb640bb7757f579d131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313',
|
||||
'f798a189f195e66982105ffb640bb7757f579da31602161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616',
|
||||
'f798a189f195e66982105ffb640bb7757f579da31602fc93ec191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919',
|
||||
'f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac561c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c',
|
||||
'f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac31f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f',
|
||||
'f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222',
|
||||
'f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b73252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525',
|
||||
'f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b4641282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828',
|
||||
'f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c92b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b',
|
||||
'f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c94400492e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e',
|
||||
'f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131',
|
||||
'f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434',
|
||||
'f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59ea1c53373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737',
|
||||
'f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59ea1c53f159163a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a',
|
||||
'f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59ea1c53f15916155c2b3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d',
|
||||
'f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59ea1c53f15916155c2be8241a404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040'
|
||||
]
|
||||
|
||||
test('constants', function (t) {
|
||||
t.ok(sodium.crypto_stream_chacha20_KEYBYTES > 0)
|
||||
t.ok(sodium.crypto_stream_chacha20_NONCEBYTES > 0)
|
||||
t.ok(sodium.crypto_stream_chacha20_MESSAGEBYTES_MAX > 0)
|
||||
})
|
||||
|
||||
test('libsodium crypto_stream_chacha20', function (t) {
|
||||
const key = Buffer.alloc(sodium.crypto_stream_chacha20_KEYBYTES)
|
||||
const nonce = Buffer.alloc(sodium.crypto_stream_chacha20_NONCEBYTES)
|
||||
|
||||
const out = Buffer.alloc(160)
|
||||
|
||||
for (let i = 0; i < tests.length; i++) {
|
||||
key.write(tests[i][0], 0, key.byteLength, 'hex')
|
||||
nonce.write(tests[i][1], 0, nonce.byteLength, 'hex')
|
||||
sodium.crypto_stream_chacha20(out, nonce, key)
|
||||
t.alike(out, Buffer.from(tests[i][2], 'hex'))
|
||||
for (let plen = 0; plen < out.byteLength; plen++) {
|
||||
const part = Buffer.alloc(plen)
|
||||
sodium.crypto_stream_chacha20_xor(part, out.subarray(0, plen), nonce, key)
|
||||
if (part.every(b => b === 0) === false) return t.fail()
|
||||
}
|
||||
}
|
||||
|
||||
for (let plen = 1, i = 0; plen < 66; plen += 3, i++) {
|
||||
out.fill(plen & 0xff)
|
||||
sodium.crypto_stream_chacha20(out.subarray(0, plen), nonce, key)
|
||||
if (out.equals(Buffer.from(vectors[i], 'hex')) === false) return t.fail()
|
||||
}
|
||||
|
||||
sodium.randombytes_buf(out)
|
||||
sodium.crypto_stream_chacha20(out, nonce, key)
|
||||
t.alike(out, Buffer.from('f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59ea1c53f15916155c2be8241a38008b9a26bc35941e2444177c8ade6689de95264986d95889fb60e84629c9bd9a5acb1cc118be563eb9b3a4a472f82e09a7e778492b562ef7130e88dfe031c79db9d4f7c7a899151b9a475032b63fc385245fe054e3dd5a97a5f576fe064025', 'hex'))
|
||||
|
||||
t.execution(() => sodium.crypto_stream_chacha20(out.subarray(0, 0), nonce, key))
|
||||
t.execution(() => sodium.crypto_stream_chacha20_xor(out.subarray(0, 0), Buffer.alloc(0), nonce, key))
|
||||
t.execution(() => sodium.crypto_stream_chacha20_xor(out.subarray(0, 0), Buffer.alloc(0), nonce, key))
|
||||
t.execution(() => sodium.crypto_stream_chacha20_xor_ic(out.subarray(0, 0), Buffer.alloc(0), nonce, 1, key))
|
||||
|
||||
out.fill(0x42)
|
||||
sodium.crypto_stream_chacha20_xor(out, out, nonce, key)
|
||||
t.alike(out, Buffer.from('b5dae3cbb3d7a42bc0521db92649f5373d15dfe15440bed1ae43ee14ba18818376e616393179040372008b06420b552b4791fc1ba85e11b31b54571e69aa66587a42c9d864fe77d65c6606553ec89c24cb9cd7640bc49b1acbb922aa046b8bffd818895e835afc147cfbf1e6e630ba6c4be5a53a0b69146cb5514cca9da27385dffb96b585eadb5759d8051270f47d81c7661da216a19f18d5e7b734bc440267', 'hex'))
|
||||
|
||||
sodium.crypto_stream_chacha20_xor_ic(out, out, nonce, 0, key)
|
||||
t.alike(out, Buffer.from('42424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242', 'hex'))
|
||||
|
||||
sodium.crypto_stream_chacha20_xor_ic(out, out, nonce, 1, key)
|
||||
t.alike(out, Buffer.from('7a42c9d864fe77d65c6606553ec89c24cb9cd7640bc49b1acbb922aa046b8bffd818895e835afc147cfbf1e6e630ba6c4be5a53a0b69146cb5514cca9da27385dffb96b585eadb5759d8051270f47d81c7661da216a19f18d5e7b734bc440267918c466e1428f08745f37a99c77c7f2b1b244bd4162e8b86e4a8bf85358202954ced04b52fef7b3ba787744e715554285ecb0ed6e133c528d69d346abc0ce8b0', 'hex'))
|
||||
})
|
||||
|
||||
test('crypto_stream_chacha20', function (t) {
|
||||
const buf = Buffer.alloc(50)
|
||||
const nonce = random(sodium.crypto_stream_chacha20_NONCEBYTES)
|
||||
const key = random(sodium.crypto_stream_chacha20_KEYBYTES)
|
||||
|
||||
sodium.crypto_stream_chacha20(buf, nonce, key)
|
||||
|
||||
t.unlike(buf, Buffer.alloc(50), 'contains noise now')
|
||||
const copy = Buffer.from(buf.toString('hex'), 'hex')
|
||||
|
||||
sodium.crypto_stream_chacha20(buf, nonce, key)
|
||||
t.alike(buf, copy, 'predictable from nonce, key')
|
||||
|
||||
t.end()
|
||||
})
|
||||
|
||||
test.skip('crypto_stream_chacha20_xor state', function (t) {
|
||||
const message = Buffer.from('Hello, world!')
|
||||
const nonce = random(sodium.crypto_stream_chacha20_NONCEBYTES)
|
||||
const key = random(sodium.crypto_stream_chacha20_KEYBYTES)
|
||||
|
||||
const out = Buffer.alloc(message.length)
|
||||
|
||||
const state = Buffer.alloc(sodium.crypto_stream_chacha20_xor_STATEBYTES)
|
||||
sodium.crypto_stream_chacha20_xor_init(state, nonce, key)
|
||||
|
||||
for (let i = 0; i < message.length; i++) {
|
||||
sodium.crypto_stream_chacha20_xor_update(state, out.slice(i, i + 1), message.slice(i, i + 1))
|
||||
}
|
||||
|
||||
sodium.crypto_stream_chacha20_xor_final(state)
|
||||
sodium.crypto_stream_chacha20_xor(out, out, nonce, key)
|
||||
t.alike(out, message, 'decrypted')
|
||||
})
|
||||
|
||||
test.skip('crypto_stream_chacha20_xor state with empty buffers', function (t) {
|
||||
const message = Buffer.from('Hello, world!')
|
||||
const nonce = random(sodium.crypto_stream_chacha20_NONCEBYTES)
|
||||
const key = random(sodium.crypto_stream_chacha20_KEYBYTES)
|
||||
|
||||
const out = Buffer.alloc(message.length)
|
||||
|
||||
const state = Buffer.alloc(sodium.crypto_stream_chacha20_xor_STATEBYTES)
|
||||
sodium.crypto_stream_chacha20_xor_init(state, nonce, key)
|
||||
|
||||
sodium.crypto_stream_chacha20_xor_update(state, Buffer.alloc(0), Buffer.alloc(0))
|
||||
|
||||
for (let i = 0; i < message.length; i++) {
|
||||
sodium.crypto_stream_chacha20_xor_update(state, out.slice(i, i + 1), message.slice(i, i + 1))
|
||||
sodium.crypto_stream_chacha20_xor_update(state, Buffer.alloc(0), Buffer.alloc(0))
|
||||
}
|
||||
|
||||
sodium.crypto_stream_chacha20_xor_final(state)
|
||||
sodium.crypto_stream_chacha20_xor(out, out, nonce, key)
|
||||
t.alike(out, message, 'decrypted')
|
||||
})
|
||||
|
||||
test.skip('crypto_stream_chacha20_xor state long stream', function (t) {
|
||||
const nonce = random(sodium.crypto_stream_chacha20_NONCEBYTES)
|
||||
const key = random(sodium.crypto_stream_chacha20_KEYBYTES)
|
||||
|
||||
const encState = Buffer.alloc(sodium.crypto_stream_chacha20_xor_STATEBYTES)
|
||||
const decState = Buffer.alloc(sodium.crypto_stream_chacha20_xor_STATEBYTES)
|
||||
|
||||
sodium.crypto_stream_chacha20_xor_init(encState, nonce, key)
|
||||
sodium.crypto_stream_chacha20_xor_init(decState, nonce, key)
|
||||
const plain = []
|
||||
const encrypted = []
|
||||
const decrypted = []
|
||||
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
const next = random(61)
|
||||
plain.push(next)
|
||||
|
||||
const enc = Buffer.alloc(61)
|
||||
sodium.crypto_stream_chacha20_xor_update(encState, enc, next)
|
||||
encrypted.push(enc)
|
||||
|
||||
const dec = Buffer.alloc(61)
|
||||
sodium.crypto_stream_chacha20_xor_update(decState, dec, enc)
|
||||
decrypted.push(dec)
|
||||
}
|
||||
|
||||
const enc2 = Buffer.alloc(1000 * 61)
|
||||
sodium.crypto_stream_chacha20_xor(enc2, Buffer.concat(plain), nonce, key)
|
||||
|
||||
t.alike(Buffer.concat(encrypted), enc2, 'same as encrypting all at once')
|
||||
t.alike(Buffer.concat(decrypted), Buffer.concat(plain), 'decrypts')
|
||||
})
|
||||
|
||||
test.skip('crypto_stream_chacha20_xor state long stream (random chunks)', function (t) {
|
||||
const nonce = random(sodium.crypto_stream_chacha20_NONCEBYTES)
|
||||
const key = random(sodium.crypto_stream_chacha20_KEYBYTES)
|
||||
|
||||
const encState = Buffer.alloc(sodium.crypto_stream_chacha20_xor_STATEBYTES)
|
||||
const decState = Buffer.alloc(sodium.crypto_stream_chacha20_xor_STATEBYTES)
|
||||
|
||||
sodium.crypto_stream_chacha20_xor_init(encState, nonce, key)
|
||||
sodium.crypto_stream_chacha20_xor_init(decState, nonce, key)
|
||||
const plain = []
|
||||
const encrypted = []
|
||||
const decrypted = []
|
||||
|
||||
for (let i = 0; i < 10000; i++) {
|
||||
const len = Math.floor(Math.random() * 256)
|
||||
const next = random(len)
|
||||
plain.push(next)
|
||||
|
||||
const enc = Buffer.alloc(len)
|
||||
sodium.crypto_stream_chacha20_xor_update(encState, enc, next)
|
||||
encrypted.push(enc)
|
||||
|
||||
const dec = Buffer.alloc(len)
|
||||
sodium.crypto_stream_chacha20_xor_update(decState, dec, enc)
|
||||
decrypted.push(dec)
|
||||
}
|
||||
|
||||
const enc2 = Buffer.alloc(Buffer.concat(plain).length)
|
||||
sodium.crypto_stream_chacha20_xor(enc2, Buffer.concat(plain), nonce, key)
|
||||
|
||||
t.alike(Buffer.concat(encrypted), enc2, 'same as encrypting all at once')
|
||||
t.alike(Buffer.concat(decrypted), Buffer.concat(plain), 'decrypts')
|
||||
})
|
||||
|
||||
test.skip('crypto_stream_chacha20_xor state long stream (random chunks) with empty buffers', function (t) {
|
||||
const nonce = random(sodium.crypto_stream_chacha20_NONCEBYTES)
|
||||
const key = random(sodium.crypto_stream_chacha20_KEYBYTES)
|
||||
|
||||
const encState = Buffer.alloc(sodium.crypto_stream_chacha20_xor_STATEBYTES)
|
||||
const decState = Buffer.alloc(sodium.crypto_stream_chacha20_xor_STATEBYTES)
|
||||
|
||||
sodium.crypto_stream_chacha20_xor_init(encState, nonce, key)
|
||||
sodium.crypto_stream_chacha20_xor_init(decState, nonce, key)
|
||||
const plain = []
|
||||
const encrypted = []
|
||||
const decrypted = []
|
||||
|
||||
for (let i = 0; i < 10000; i++) {
|
||||
const len = Math.floor(Math.random() * 256)
|
||||
const next = random(len)
|
||||
plain.push(next)
|
||||
|
||||
sodium.crypto_stream_chacha20_xor_update(encState, Buffer.alloc(0), Buffer.alloc(0))
|
||||
|
||||
const enc = Buffer.alloc(len)
|
||||
sodium.crypto_stream_chacha20_xor_update(encState, enc, next)
|
||||
encrypted.push(enc)
|
||||
|
||||
const dec = Buffer.alloc(len)
|
||||
sodium.crypto_stream_chacha20_xor_update(decState, dec, enc)
|
||||
decrypted.push(dec)
|
||||
sodium.crypto_stream_chacha20_xor_update(decState, Buffer.alloc(0), Buffer.alloc(0))
|
||||
}
|
||||
|
||||
const enc2 = Buffer.alloc(Buffer.concat(plain).length)
|
||||
sodium.crypto_stream_chacha20_xor(enc2, Buffer.concat(plain), nonce, key)
|
||||
|
||||
t.alike(Buffer.concat(encrypted), enc2, 'same as encrypting all at once')
|
||||
t.alike(Buffer.concat(decrypted), Buffer.concat(plain), 'decrypts')
|
||||
})
|
||||
|
||||
test.skip('crypto_stream_chacha20_xor state after GC', function (t) {
|
||||
const message = Buffer.from('Hello, world!')
|
||||
let nonce = random(sodium.crypto_stream_chacha20_NONCEBYTES)
|
||||
let key = random(sodium.crypto_stream_chacha20_KEYBYTES)
|
||||
|
||||
const out = Buffer.alloc(message.length)
|
||||
|
||||
const state = Buffer.alloc(sodium.crypto_stream_chacha20_xor_STATEBYTES)
|
||||
sodium.crypto_stream_chacha20_xor_init(state, nonce, key)
|
||||
|
||||
const nonceCopy = Buffer.from(nonce.toString('hex'), 'hex')
|
||||
const keyCopy = Buffer.from(key.toString('hex'), 'hex')
|
||||
nonce = null
|
||||
key = null
|
||||
|
||||
forceGC()
|
||||
|
||||
for (let i = 0; i < message.length; i++) {
|
||||
sodium.crypto_stream_chacha20_xor_update(state, out.slice(i, i + 1), message.slice(i, i + 1))
|
||||
}
|
||||
|
||||
sodium.crypto_stream_chacha20_xor_final(state)
|
||||
sodium.crypto_stream_chacha20_xor(out, out, nonceCopy, keyCopy)
|
||||
t.alike(out, message, 'decrypted')
|
||||
})
|
||||
|
||||
function random (n) {
|
||||
const buf = Buffer.alloc(n)
|
||||
sodium.randombytes_buf(buf)
|
||||
return buf
|
||||
}
|
||||
|
||||
function forceGC () {
|
||||
require('v8').setFlagsFromString('--expose-gc')
|
||||
require('vm').runInNewContext('gc')()
|
||||
}
|
||||
@@ -0,0 +1,303 @@
|
||||
/* eslint-disable camelcase */
|
||||
const test = require('brittle')
|
||||
const sodium = require('..')
|
||||
|
||||
const tests = [
|
||||
['0000000000000000000000000000000000000000000000000000000000000000', '000000000000000000000000', 0, '76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7da41597c5157488d7724e03fb8d84a376a43b8f41518a11cc387b669b2ee65869f07e7be5551387a98ba977c732d080dcb0f29a048e3656912c6533e32ee7aed29b721769ce64e43d57133b074d839d531ed1f28510afb45ace10a1f4b794d6f2d09a0e663266ce1ae7ed1081968a0758e718e997bd362c6b0c34634a9a0b35d'],
|
||||
['0000000000000000000000000000000000000000000000000000000000000000', '000000000000000000000000', 1, '9f07e7be5551387a98ba977c732d080dcb0f29a048e3656912c6533e32ee7aed29b721769ce64e43d57133b074d839d531ed1f28510afb45ace10a1f4b794d6f2d09a0e663266ce1ae7ed1081968a0758e718e997bd362c6b0c34634a9a0b35d012737681f7b5d0f281e3afde458bc1e73d2d313c9cf94c05ff3716240a248f21320a058d7b3566bd520daaa3ed2bf0ac5b8b120fb852773c3639734b45c91a4'],
|
||||
['0000000000000000000000000000000000000000000000000000000000000001', '000000000000000000000000', 1, '3aeb5224ecf849929b9d828db1ced4dd832025e8018b8160b82284f3c949aa5a8eca00bbb4a73bdad192b5c42f73f2fd4e273644c8b36125a64addeb006c13a096d68b9ff7b57e7090f880392effd5b297a83bbaf2fbe8cf5d4618965e3dc776cd430d9b4e7eda8a767fb0e860319aadb5fd96a855de1fbfc92cb0489190cfdd87da6dbf1f736a2d499941ca097e5170bd685578611323120cebf296181ed4f5'],
|
||||
['00ff000000000000000000000000000000000000000000000000000000000000', '000000000000000000000000', 2, '72d54dfbf12ec44b362692df94137f328fea8da73990265ec1bbbea1ae9af0ca13b25aa26cb4a648cb9b9d1be65b2c0924a66c54d545ec1b7374f4872e99f096bf74dbd52cc4fc95ceb6097fe5e65358c9dbc0a5ecbf7894a132a9a54ae3e951f2e9f209aa9c3d9a877ac9dab62433d2961a17d103e455dfb7337c90f6857aad233065955a212b5c7a8eab4dc8a629e5b6b8ba914afd06de7177054b33d21c96'],
|
||||
['0000000000000000000000000000000000000000000000000000000000000000', '000000000000000000000002', 0, 'c2c64d378cd536374ae204b9ef933fcd1a8b2288b3dfa49672ab765b54ee27c78a970e0e955c14f3a88e741b97c286f75f8fc299e8148362fa198a39531bed6d1a91288c874ec254f322c2a197340c55bb3e9b3998f7de2309486a0bb494abd20c9c5ef99c1370d61e77f408ac5514f49202bcc6828d45409d2d1416f8ae106b06ebd2541256264fa415bd54cb12e1d4449ed85299a1b7a249b75ff6c89b2e3f'],
|
||||
['000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f', '000000090000004a00000000', 1, '10f1e7e4d13b5915500fdd1fa32071c4c7d1f4c733c068030422aa9ac3d46c4ed2826446079faa0914c2d705d98b02a2b5129cd1de164eb9cbd083e8a2503c4e0a88837739d7bf4ef8ccacb0ea2bb9d69d56c394aa351dfda5bf459f0a2e9fe8e721f89255f9c486bf21679c683d4f9c5cf2fa27865526005b06ca374c86af3bdcbfbdcb83be65862ed5c20eae5a43241d6a92da6dca9a156be25297f51c2718'],
|
||||
['000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f', '000000090000004a00000000', 0xfeffffff, '75924bad7831b25662dbac54b46827990b6168ae990e7bd7e1fd2ad282bf23ef052c7d1a0a6c1ef862070943a0d4da24705fbc006dfb85e2af18c0a264d772a44c70fbedac9d6a6867ff6be0a32826507f2c784101583211c9e2453d4cc8b283d5e86682bd4bf511271b91dbd351415f5a009d1f78b64085a9a4341be7d42e2679d57e2747097f0129950e2c9e9ca1356022d45da252af71ac37f351a2e77911']
|
||||
]
|
||||
|
||||
const vectors = [
|
||||
'8a010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101',
|
||||
'8adc91fd040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404',
|
||||
'8adc91fd9ff4f0070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707',
|
||||
'8adc91fd9ff4f0f51b0f0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a',
|
||||
'8adc91fd9ff4f0f51b0fad50ff0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d',
|
||||
'8adc91fd9ff4f0f51b0fad50ff15d637101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010',
|
||||
'8adc91fd9ff4f0f51b0fad50ff15d637e40efd131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313',
|
||||
'8adc91fd9ff4f0f51b0fad50ff15d637e40efda206cc161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616',
|
||||
'8adc91fd9ff4f0f51b0fad50ff15d637e40efda206cc52c783191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919',
|
||||
'8adc91fd9ff4f0f51b0fad50ff15d637e40efda206cc52c783a742001c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c',
|
||||
'8adc91fd9ff4f0f51b0fad50ff15d637e40efda206cc52c783a74200503c151f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f',
|
||||
'8adc91fd9ff4f0f51b0fad50ff15d637e40efda206cc52c783a74200503c1582cd98222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222',
|
||||
'8adc91fd9ff4f0f51b0fad50ff15d637e40efda206cc52c783a74200503c1582cd9833367d252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525',
|
||||
'8adc91fd9ff4f0f51b0fad50ff15d637e40efda206cc52c783a74200503c1582cd9833367d0a54d5282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828',
|
||||
'8adc91fd9ff4f0f51b0fad50ff15d637e40efda206cc52c783a74200503c1582cd9833367d0a54d57d3c9e2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b',
|
||||
'8adc91fd9ff4f0f51b0fad50ff15d637e40efda206cc52c783a74200503c1582cd9833367d0a54d57d3c9e998f492e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e',
|
||||
'8adc91fd9ff4f0f51b0fad50ff15d637e40efda206cc52c783a74200503c1582cd9833367d0a54d57d3c9e998f490ee69c313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131',
|
||||
'8adc91fd9ff4f0f51b0fad50ff15d637e40efda206cc52c783a74200503c1582cd9833367d0a54d57d3c9e998f490ee69ca34c1f343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434',
|
||||
'8adc91fd9ff4f0f51b0fad50ff15d637e40efda206cc52c783a74200503c1582cd9833367d0a54d57d3c9e998f490ee69ca34c1ff9e939373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737',
|
||||
'8adc91fd9ff4f0f51b0fad50ff15d637e40efda206cc52c783a74200503c1582cd9833367d0a54d57d3c9e998f490ee69ca34c1ff9e939a755843a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a',
|
||||
'8adc91fd9ff4f0f51b0fad50ff15d637e40efda206cc52c783a74200503c1582cd9833367d0a54d57d3c9e998f490ee69ca34c1ff9e939a75584c52d693d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d',
|
||||
'8adc91fd9ff4f0f51b0fad50ff15d637e40efda206cc52c783a74200503c1582cd9833367d0a54d57d3c9e998f490ee69ca34c1ff9e939a75584c52d690a35d4404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040'
|
||||
]
|
||||
|
||||
test('constants', function (t) {
|
||||
t.ok(sodium.crypto_stream_chacha20_ietf_KEYBYTES > 0)
|
||||
t.ok(sodium.crypto_stream_chacha20_ietf_NONCEBYTES > 0)
|
||||
t.ok(sodium.crypto_stream_chacha20_ietf_MESSAGEBYTES_MAX > 0)
|
||||
})
|
||||
|
||||
test('libsodium crypto_stream_chacha20_ietf', function (t) {
|
||||
const key = Buffer.alloc(sodium.crypto_stream_chacha20_ietf_KEYBYTES)
|
||||
const nonce = Buffer.alloc(sodium.crypto_stream_chacha20_ietf_NONCEBYTES)
|
||||
|
||||
const out = Buffer.alloc(160)
|
||||
|
||||
for (let i = 0; i < tests.length; i++) {
|
||||
key.write(tests[i][0], 0, key.byteLength, 'hex')
|
||||
nonce.write(tests[i][1], 0, nonce.byteLength, 'hex')
|
||||
out.fill(0)
|
||||
sodium.crypto_stream_chacha20_ietf_xor_ic(out, out, nonce, tests[i][2], key)
|
||||
t.alike(out, Buffer.from(tests[i][3], 'hex'), 'crypto_stream_chacha20_ietf_xor_ic vector ' + i)
|
||||
for (let plen = 0; plen < out.byteLength; plen++) {
|
||||
const part = Buffer.alloc(plen)
|
||||
sodium.crypto_stream_chacha20_ietf_xor_ic(part, out.subarray(0, plen), nonce, tests[i][2], key)
|
||||
if (part.every(b => b === 0) === false) return t.fail()
|
||||
}
|
||||
}
|
||||
|
||||
for (let plen = 1, i = 0; plen < 66; plen += 3, i++) {
|
||||
out.fill(plen & 0xff)
|
||||
sodium.crypto_stream_chacha20_ietf(out.subarray(0, plen), nonce, key)
|
||||
if (out.equals(Buffer.from(vectors[i], 'hex')) === false) return t.fail()
|
||||
}
|
||||
|
||||
sodium.randombytes_buf(out)
|
||||
sodium.crypto_stream_chacha20_ietf(out, nonce, key)
|
||||
t.alike(out, Buffer.from('8adc91fd9ff4f0f51b0fad50ff15d637e40efda206cc52c783a74200503c1582cd9833367d0a54d57d3c9e998f490ee69ca34c1ff9e939a75584c52d690a35d410f1e7e4d13b5915500fdd1fa32071c4c7d1f4c733c068030422aa9ac3d46c4ed2826446079faa0914c2d705d98b02a2b5129cd1de164eb9cbd083e8a2503c4e0a88837739d7bf4ef8ccacb0ea2bb9d69d56c394aa351dfda5bf459f0a2e9fe8', 'hex'))
|
||||
|
||||
t.execution(() => sodium.crypto_stream_chacha20_ietf(out.subarray(0, 0), nonce, key))
|
||||
t.execution(() => sodium.crypto_stream_chacha20_ietf_xor(out.subarray(0, 0), Buffer.alloc(0), nonce, key))
|
||||
t.execution(() => sodium.crypto_stream_chacha20_ietf_xor(out.subarray(0, 0), Buffer.alloc(0), nonce, key))
|
||||
t.execution(() => sodium.crypto_stream_chacha20_ietf_xor_ic(out.subarray(0, 0), Buffer.alloc(0), nonce, 1, key))
|
||||
|
||||
out.fill(0x42)
|
||||
sodium.crypto_stream_chacha20_ietf_xor(out, out, nonce, key)
|
||||
t.alike(out, Buffer.from('c89ed3bfddb6b2b7594def12bd579475a64cbfe0448e1085c1e50042127e57c08fda71743f4816973f7edcdbcd0b4ca4dee10e5dbbab7be517c6876f2b48779652b3a5a693791b57124d9f5de16233868593b68571822a414660e8d881962e0c90c0260445dde84b568095479bc940e0f750de939c540cfb8992c1aae0127e0c48cac1357b95fd0cba8eeef2a869fb94df1481d6e8775fbfe7fd07dd486cddaa', 'hex'))
|
||||
|
||||
sodium.crypto_stream_chacha20_ietf_xor_ic(out, out, nonce, 0, key)
|
||||
t.alike(out, Buffer.from('42424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242', 'hex'))
|
||||
|
||||
sodium.crypto_stream_chacha20_ietf_xor_ic(out, out, nonce, 1, key)
|
||||
t.alike(out, Buffer.from('52b3a5a693791b57124d9f5de16233868593b68571822a414660e8d881962e0c90c0260445dde84b568095479bc940e0f750de939c540cfb8992c1aae0127e0c48cac1357b95fd0cba8eeef2a869fb94df1481d6e8775fbfe7fd07dd486cddaaa563bad017bb86c4fd6325de2a7f0dde1eb0b865c4176442194488750ec4ed799efdff89c1fc27c46c97804cec1801665f28d0982f88d85729a010d5b75e655a', 'hex'))
|
||||
})
|
||||
|
||||
test('crypto_stream_chacha20_ietf', function (t) {
|
||||
const buf = Buffer.alloc(50)
|
||||
const nonce = random(sodium.crypto_stream_chacha20_ietf_NONCEBYTES)
|
||||
const key = random(sodium.crypto_stream_chacha20_ietf_KEYBYTES)
|
||||
|
||||
sodium.crypto_stream_chacha20_ietf(buf, nonce, key)
|
||||
|
||||
t.unlike(buf, Buffer.alloc(50), 'contains noise now')
|
||||
const copy = Buffer.from(buf.toString('hex'), 'hex')
|
||||
|
||||
sodium.crypto_stream_chacha20_ietf(buf, nonce, key)
|
||||
t.alike(buf, copy, 'predictable from nonce, key')
|
||||
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('crypto_stream_chacha20_ietf_xor', function (t) {
|
||||
const message = Buffer.from('Hello, World!')
|
||||
const nonce = random(sodium.crypto_stream_chacha20_ietf_NONCEBYTES)
|
||||
const key = random(sodium.crypto_stream_chacha20_ietf_KEYBYTES)
|
||||
|
||||
sodium.crypto_stream_chacha20_ietf_xor(message, message, nonce, key)
|
||||
|
||||
t.unlike(message, Buffer.from('Hello, World!'), 'encrypted')
|
||||
|
||||
sodium.crypto_stream_chacha20_ietf_xor(message, message, nonce, key)
|
||||
|
||||
t.alike(message, Buffer.from('Hello, World!'), 'decrypted')
|
||||
|
||||
t.end()
|
||||
})
|
||||
|
||||
test.skip('crypto_stream_chacha20_ietf_xor state', function (t) {
|
||||
const message = Buffer.from('Hello, world!')
|
||||
const nonce = random(sodium.crypto_stream_chacha20_ietf_NONCEBYTES)
|
||||
const key = random(sodium.crypto_stream_chacha20_ietf_KEYBYTES)
|
||||
|
||||
const out = Buffer.alloc(message.length)
|
||||
|
||||
const state = Buffer.alloc(sodium.crypto_stream_chacha20_ietf_xor_STATEBYTES)
|
||||
sodium.crypto_stream_chacha20_ietf_xor_init(state, nonce, key)
|
||||
|
||||
for (let i = 0; i < message.length; i++) {
|
||||
sodium.crypto_stream_chacha20_ietf_xor_update(state, out.slice(i, i + 1), message.slice(i, i + 1))
|
||||
}
|
||||
|
||||
sodium.crypto_stream_chacha20_ietf_xor_final(state)
|
||||
sodium.crypto_stream_chacha20_ietf_xor(out, out, nonce, key)
|
||||
t.alike(out, message, 'decrypted')
|
||||
})
|
||||
|
||||
test.skip('crypto_stream_chacha20_ietf_xor state with empty buffers', function (t) {
|
||||
const message = Buffer.from('Hello, world!')
|
||||
const nonce = random(sodium.crypto_stream_chacha20_ietf_NONCEBYTES)
|
||||
const key = random(sodium.crypto_stream_chacha20_ietf_KEYBYTES)
|
||||
|
||||
const out = Buffer.alloc(message.length)
|
||||
|
||||
const state = Buffer.alloc(sodium.crypto_stream_chacha20_ietf_xor_STATEBYTES)
|
||||
sodium.crypto_stream_chacha20_ietf_xor_init(state, nonce, key)
|
||||
|
||||
sodium.crypto_stream_chacha20_ietf_xor_update(state, Buffer.alloc(0), Buffer.alloc(0))
|
||||
|
||||
for (let i = 0; i < message.length; i++) {
|
||||
sodium.crypto_stream_chacha20_ietf_xor_update(state, out.slice(i, i + 1), message.slice(i, i + 1))
|
||||
sodium.crypto_stream_chacha20_ietf_xor_update(state, Buffer.alloc(0), Buffer.alloc(0))
|
||||
}
|
||||
|
||||
sodium.crypto_stream_chacha20_ietf_xor_final(state)
|
||||
sodium.crypto_stream_chacha20_ietf_xor(out, out, nonce, key)
|
||||
t.alike(out, message, 'decrypted')
|
||||
})
|
||||
|
||||
test.skip('crypto_stream_chacha20_ietf_xor state long stream', function (t) {
|
||||
const nonce = random(sodium.crypto_stream_chacha20_ietf_NONCEBYTES)
|
||||
const key = random(sodium.crypto_stream_chacha20_ietf_KEYBYTES)
|
||||
|
||||
const encState = Buffer.alloc(sodium.crypto_stream_chacha20_ietf_xor_STATEBYTES)
|
||||
const decState = Buffer.alloc(sodium.crypto_stream_chacha20_ietf_xor_STATEBYTES)
|
||||
|
||||
sodium.crypto_stream_chacha20_ietf_xor_init(encState, nonce, key)
|
||||
sodium.crypto_stream_chacha20_ietf_xor_init(decState, nonce, key)
|
||||
const plain = []
|
||||
const encrypted = []
|
||||
const decrypted = []
|
||||
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
const next = random(61)
|
||||
plain.push(next)
|
||||
|
||||
const enc = Buffer.alloc(61)
|
||||
sodium.crypto_stream_chacha20_ietf_xor_update(encState, enc, next)
|
||||
encrypted.push(enc)
|
||||
|
||||
const dec = Buffer.alloc(61)
|
||||
sodium.crypto_stream_chacha20_ietf_xor_update(decState, dec, enc)
|
||||
decrypted.push(dec)
|
||||
}
|
||||
|
||||
const enc2 = Buffer.alloc(1000 * 61)
|
||||
sodium.crypto_stream_chacha20_ietf_xor(enc2, Buffer.concat(plain), nonce, key)
|
||||
|
||||
t.alike(Buffer.concat(encrypted), enc2, 'same as encrypting all at once')
|
||||
t.alike(Buffer.concat(decrypted), Buffer.concat(plain), 'decrypts')
|
||||
})
|
||||
|
||||
test.skip('crypto_stream_chacha20_ietf_xor state long stream (random chunks)', function (t) {
|
||||
const nonce = random(sodium.crypto_stream_chacha20_ietf_NONCEBYTES)
|
||||
const key = random(sodium.crypto_stream_chacha20_ietf_KEYBYTES)
|
||||
|
||||
const encState = Buffer.alloc(sodium.crypto_stream_chacha20_ietf_xor_STATEBYTES)
|
||||
const decState = Buffer.alloc(sodium.crypto_stream_chacha20_ietf_xor_STATEBYTES)
|
||||
|
||||
sodium.crypto_stream_chacha20_ietf_xor_init(encState, nonce, key)
|
||||
sodium.crypto_stream_chacha20_ietf_xor_init(decState, nonce, key)
|
||||
const plain = []
|
||||
const encrypted = []
|
||||
const decrypted = []
|
||||
|
||||
for (let i = 0; i < 10000; i++) {
|
||||
const len = Math.floor(Math.random() * 256)
|
||||
const next = random(len)
|
||||
plain.push(next)
|
||||
|
||||
const enc = Buffer.alloc(len)
|
||||
sodium.crypto_stream_chacha20_ietf_xor_update(encState, enc, next)
|
||||
encrypted.push(enc)
|
||||
|
||||
const dec = Buffer.alloc(len)
|
||||
sodium.crypto_stream_chacha20_ietf_xor_update(decState, dec, enc)
|
||||
decrypted.push(dec)
|
||||
}
|
||||
|
||||
const enc2 = Buffer.alloc(Buffer.concat(plain).length)
|
||||
sodium.crypto_stream_chacha20_ietf_xor(enc2, Buffer.concat(plain), nonce, key)
|
||||
|
||||
t.alike(Buffer.concat(encrypted), enc2, 'same as encrypting all at once')
|
||||
t.alike(Buffer.concat(decrypted), Buffer.concat(plain), 'decrypts')
|
||||
})
|
||||
|
||||
test.skip('crypto_stream_chacha20_ietf_xor state long stream (random chunks) with empty buffers', function (t) {
|
||||
const nonce = random(sodium.crypto_stream_chacha20_ietf_NONCEBYTES)
|
||||
const key = random(sodium.crypto_stream_chacha20_ietf_KEYBYTES)
|
||||
|
||||
const encState = Buffer.alloc(sodium.crypto_stream_chacha20_ietf_xor_STATEBYTES)
|
||||
const decState = Buffer.alloc(sodium.crypto_stream_chacha20_ietf_xor_STATEBYTES)
|
||||
|
||||
sodium.crypto_stream_chacha20_ietf_xor_init(encState, nonce, key)
|
||||
sodium.crypto_stream_chacha20_ietf_xor_init(decState, nonce, key)
|
||||
const plain = []
|
||||
const encrypted = []
|
||||
const decrypted = []
|
||||
|
||||
for (let i = 0; i < 10000; i++) {
|
||||
const len = Math.floor(Math.random() * 256)
|
||||
const next = random(len)
|
||||
plain.push(next)
|
||||
|
||||
sodium.crypto_stream_chacha20_ietf_xor_update(encState, Buffer.alloc(0), Buffer.alloc(0))
|
||||
|
||||
const enc = Buffer.alloc(len)
|
||||
sodium.crypto_stream_chacha20_ietf_xor_update(encState, enc, next)
|
||||
encrypted.push(enc)
|
||||
|
||||
const dec = Buffer.alloc(len)
|
||||
sodium.crypto_stream_chacha20_ietf_xor_update(decState, dec, enc)
|
||||
decrypted.push(dec)
|
||||
sodium.crypto_stream_chacha20_ietf_xor_update(decState, Buffer.alloc(0), Buffer.alloc(0))
|
||||
}
|
||||
|
||||
const enc2 = Buffer.alloc(Buffer.concat(plain).length)
|
||||
sodium.crypto_stream_chacha20_ietf_xor(enc2, Buffer.concat(plain), nonce, key)
|
||||
|
||||
t.alike(Buffer.concat(encrypted), enc2, 'same as encrypting all at once')
|
||||
t.alike(Buffer.concat(decrypted), Buffer.concat(plain), 'decrypts')
|
||||
})
|
||||
|
||||
test.skip('crypto_stream_chacha20_xor state after GC', function (t) {
|
||||
const message = Buffer.from('Hello, world!')
|
||||
let nonce = random(sodium.crypto_stream_chacha20_ietf_NONCEBYTES)
|
||||
let key = random(sodium.crypto_stream_chacha20_ietf_KEYBYTES)
|
||||
|
||||
const out = Buffer.alloc(message.length)
|
||||
|
||||
const state = Buffer.alloc(sodium.crypto_stream_chacha20_ietf_xor_STATEBYTES)
|
||||
sodium.crypto_stream_chacha20_ietf_xor_init(state, nonce, key)
|
||||
|
||||
const nonceCopy = Buffer.from(nonce.toString('hex'), 'hex')
|
||||
const keyCopy = Buffer.from(key.toString('hex'), 'hex')
|
||||
nonce = null
|
||||
key = null
|
||||
|
||||
forceGC()
|
||||
|
||||
for (let i = 0; i < message.length; i++) {
|
||||
sodium.crypto_stream_chacha20_ietf_xor_update(state, out.slice(i, i + 1), message.slice(i, i + 1))
|
||||
}
|
||||
|
||||
sodium.crypto_stream_chacha20_ietf_xor_final(state)
|
||||
sodium.crypto_stream_chacha20_ietf_xor(out, out, nonceCopy, keyCopy)
|
||||
t.alike(out, message, 'decrypted')
|
||||
})
|
||||
|
||||
function random (n) {
|
||||
const buf = Buffer.alloc(n)
|
||||
sodium.randombytes_buf(buf)
|
||||
return buf
|
||||
}
|
||||
|
||||
function forceGC () {
|
||||
require('v8').setFlagsFromString('--expose-gc')
|
||||
require('vm').runInNewContext('gc')()
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
const test = require('brittle')
|
||||
const sodium = require('..')
|
||||
const fixtures = require('./fixtures/crypto_tweak_ed25519_sign.js')
|
||||
|
||||
test('crypto_tweak', function (t) {
|
||||
const pk = Buffer.alloc(sodium.crypto_sign_PUBLICKEYBYTES)
|
||||
const sk = Buffer.alloc(sodium.crypto_sign_SECRETKEYBYTES)
|
||||
|
||||
sodium.crypto_sign_keypair(pk, sk)
|
||||
|
||||
const tpk = Buffer.alloc(sodium.crypto_tweak_ed25519_BYTES)
|
||||
const tsk = Buffer.alloc(sodium.crypto_tweak_ed25519_SCALARBYTES)
|
||||
|
||||
const tkpk = Buffer.alloc(sodium.crypto_tweak_ed25519_BYTES)
|
||||
const tksk = Buffer.alloc(sodium.crypto_tweak_ed25519_SCALARBYTES)
|
||||
|
||||
const point = Buffer.alloc(sodium.crypto_tweak_ed25519_BYTES)
|
||||
const tweak = Buffer.alloc(sodium.crypto_tweak_ed25519_SCALARBYTES)
|
||||
|
||||
const ns = Buffer.alloc(32)
|
||||
sodium.crypto_generichash(ns, Buffer.from('namespace'))
|
||||
|
||||
t.exception.all(function () {
|
||||
sodium.crypto_tweak_ed25519_base()
|
||||
}, 'should validate input')
|
||||
|
||||
t.exception.all(function () {
|
||||
sodium.crypto_tweak_ed25519_base(Buffer.alloc(0), Buffer.alloc(0), ns)
|
||||
}, 'should validate input length')
|
||||
|
||||
sodium.crypto_tweak_ed25519_base(tweak, point, ns)
|
||||
|
||||
const _sk = sk.subarray(0, 32)
|
||||
sodium.crypto_tweak_ed25519_sk_to_scalar(_sk, sk)
|
||||
|
||||
sodium.crypto_tweak_ed25519_pk(tpk, pk, ns)
|
||||
sodium.crypto_tweak_ed25519_scalar(tsk, _sk, ns)
|
||||
|
||||
sodium.crypto_tweak_ed25519_keypair(tkpk, tksk, _sk, ns)
|
||||
|
||||
sodium.crypto_tweak_ed25519_pk_add(pk, pk, point)
|
||||
sodium.crypto_tweak_ed25519_scalar_add(_sk, _sk, tweak)
|
||||
|
||||
t.alike(pk, tpk, 'tweak public key')
|
||||
t.alike(_sk, tsk, 'tweak secret key')
|
||||
t.alike(pk, tkpk, 'tweak keypair public key')
|
||||
t.alike(_sk, tksk, 'tweak keypair secret key')
|
||||
})
|
||||
|
||||
test('crypto_tweak_sign', function (t) {
|
||||
const pk = Buffer.alloc(sodium.crypto_sign_PUBLICKEYBYTES)
|
||||
const sk = Buffer.alloc(sodium.crypto_sign_SECRETKEYBYTES)
|
||||
|
||||
sodium.crypto_sign_keypair(pk, sk)
|
||||
|
||||
const tpk = Buffer.alloc(sodium.crypto_tweak_ed25519_BYTES)
|
||||
const tsk = Buffer.alloc(sodium.crypto_tweak_ed25519_SCALARBYTES)
|
||||
|
||||
const point = Buffer.alloc(sodium.crypto_tweak_ed25519_BYTES)
|
||||
const tweak = Buffer.alloc(sodium.crypto_tweak_ed25519_SCALARBYTES)
|
||||
|
||||
const ns = Buffer.alloc(32)
|
||||
sodium.crypto_generichash(ns, Buffer.from('namespace'))
|
||||
|
||||
sodium.crypto_tweak_ed25519_base(tweak, point, ns)
|
||||
|
||||
sodium.crypto_tweak_ed25519_pk(tpk, pk, ns)
|
||||
sodium.crypto_tweak_ed25519_sk_to_scalar(tsk, sk)
|
||||
sodium.crypto_tweak_ed25519_scalar(tsk, tsk, ns)
|
||||
|
||||
sodium.crypto_tweak_ed25519_pk_add(pk, pk, point)
|
||||
|
||||
const _sk = sk.subarray(0, 32)
|
||||
sodium.crypto_tweak_ed25519_sk_to_scalar(_sk, sk)
|
||||
sodium.crypto_tweak_ed25519_scalar_add(_sk, _sk, tweak)
|
||||
|
||||
const m = Buffer.from('test message')
|
||||
const sig = Buffer.alloc(sodium.crypto_sign_BYTES)
|
||||
|
||||
sodium.crypto_tweak_ed25519_sign_detached(sig, m, _sk)
|
||||
t.ok(sodium.crypto_sign_verify_detached(sig, m, pk))
|
||||
t.ok(sodium.crypto_sign_verify_detached(sig, m, tpk))
|
||||
|
||||
sodium.crypto_tweak_ed25519_sign_detached(sig, m, tsk)
|
||||
t.ok(sodium.crypto_sign_verify_detached(sig, m, pk))
|
||||
t.ok(sodium.crypto_sign_verify_detached(sig, m, tpk))
|
||||
})
|
||||
|
||||
test('crypto_tweak sign fixtures', t => {
|
||||
for (const f of fixtures) {
|
||||
const [sk, n, m, sig, tweak, tpk, tn] = f.map(Buffer.from)
|
||||
|
||||
const signature = Buffer.alloc(64)
|
||||
const scalar = Buffer.alloc(32)
|
||||
const pk = Buffer.alloc(32)
|
||||
|
||||
sodium.crypto_tweak_ed25519_sk_to_scalar(scalar, sk)
|
||||
t.alike(scalar, n)
|
||||
|
||||
sodium.crypto_tweak_ed25519_sign_detached(signature, m, n)
|
||||
t.alike(signature, sig)
|
||||
|
||||
sodium.randombytes_buf(signature)
|
||||
sodium.crypto_sign_ed25519_sk_to_pk(pk, sk)
|
||||
|
||||
sodium.crypto_tweak_ed25519_sign_detached(signature, m, n, pk)
|
||||
t.alike(signature, sig)
|
||||
|
||||
sodium.crypto_tweak_ed25519_keypair(pk, scalar, n, tweak)
|
||||
t.alike(pk, tpk)
|
||||
t.alike(scalar, tn)
|
||||
}
|
||||
})
|
||||
Vendored
+78
@@ -0,0 +1,78 @@
|
||||
[
|
||||
{"error": false, "id":0, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":64, "subkey":"a0c724404728c8bb95e5433eb6a9716171144d61efb23e74b873fcbeda51d8071b5d70aae12066dfc94ce943f145aa176c055040c3dd73b0a15e36254d450614"},
|
||||
{"error": false, "id":1, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":64, "subkey":"02507f144fa9bf19010bf7c70b235b4c2663cc00e074f929602a5e2c10a780757d2a3993d06debc378a90efdac196dd841817b977d67b786804f6d3cd585bab5"},
|
||||
{"error": false, "id":2, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":64, "subkey":"1944da61ff18dc2028c3578ac85be904931b83860896598f62468f1cb5471c6a344c945dbc62c9aaf70feb62472d17775ea5db6ed5494c68b7a9a59761f39614"},
|
||||
{"error": false, "id":3, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":64, "subkey":"131c0ca1633ed074986215b264f6e0474f362c52b029effc7b0f75977ee89cc95d85c3db87f7e399197a25411592beeeb7e5128a74646a460ecd6deb4994b71e"},
|
||||
{"error": false, "id":4, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":64, "subkey":"a7023a0bf9be245d078aed26bcde0465ff0cc0961196a5482a0ff4ff8b4015971e13611f50529cb408f5776b14a90e7c3dd9160a22211db64ff4b5c0b9953680"},
|
||||
{"error": false, "id":5, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":64, "subkey":"50f49313f3a05b2e565c13feedb44daa675cafd42c2b2cf9edbce9c949fbfc3f175dcb738671509ae2ea66fb85e552394d479afa7fa3affe8791744796b94176"},
|
||||
{"error": false, "id":6, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":64, "subkey":"13b58d6d69780089293862cd59a1a8a4ef79bb850e3f3ba41fb22446a7dd1dc4da4667d37b33bf1225dcf8173c4c349a5d911c5bd2db9c5905ed70c11e809e3b"},
|
||||
{"error": false, "id":7, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":64, "subkey":"15d44b4b44ffa006eeceeb508c98a970aaa573d65905687b9e15854dec6d49c612757e149f78268f727660dedf9abce22a9691feb20a01b0525f4b47a3cf19db"},
|
||||
{"error": false, "id":8, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":64, "subkey":"9aebba11c5428ae8225716369e30a48943be39159a899f804e9963ef78822e186c21fe95bb0b85e60ef03a6f58d0b9d06e91f79d0ab998450b8810c73ca935b4"},
|
||||
{"error": false, "id":9, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":64, "subkey":"70f9b83e463fb441e7a4c43275125cd5b19d8e2e4a5d179a39f5db10bbce745a199104563d308cf8d4c6b27bbb759ded232f5bdb7c367dd632a9677320dfe416"},
|
||||
{"error": true, "id":0, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":0, "subkey":null},
|
||||
{"error": true, "id":1, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":1, "subkey":null},
|
||||
{"error": true, "id":2, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":2, "subkey":null},
|
||||
{"error": true, "id":3, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":3, "subkey":null},
|
||||
{"error": true, "id":4, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":4, "subkey":null},
|
||||
{"error": true, "id":5, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":5, "subkey":null},
|
||||
{"error": true, "id":6, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":6, "subkey":null},
|
||||
{"error": true, "id":7, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":7, "subkey":null},
|
||||
{"error": true, "id":8, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":8, "subkey":null},
|
||||
{"error": true, "id":9, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":9, "subkey":null},
|
||||
{"error": true, "id":10, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":10, "subkey":null},
|
||||
{"error": true, "id":11, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":11, "subkey":null},
|
||||
{"error": true, "id":12, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":12, "subkey":null},
|
||||
{"error": true, "id":13, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":13, "subkey":null},
|
||||
{"error": true, "id":14, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":14, "subkey":null},
|
||||
{"error": true, "id":15, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":15, "subkey":null},
|
||||
{"error": false, "id":16, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":16, "subkey":"a529216624ef9161e4cf117272aafff2"},
|
||||
{"error": false, "id":17, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":17, "subkey":"068bd6940b80c6cc2530a68c31d9f4e323"},
|
||||
{"error": false, "id":18, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":18, "subkey":"0acf4f6c74a590c8a1c0997ec9a1a3f48b2a"},
|
||||
{"error": false, "id":19, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":19, "subkey":"ac17a37ce74c0efece75f9337de20795dbadcc"},
|
||||
{"error": false, "id":20, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":20, "subkey":"268214dc9477a2e3c1022829f934ab992a5a3d84"},
|
||||
{"error": false, "id":21, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":21, "subkey":"33b76197b4531665e494760909eda1cc570e7da9bb"},
|
||||
{"error": false, "id":22, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":22, "subkey":"3d4efbc569ca7f858ad4f49c56b820986a406e6eebbc"},
|
||||
{"error": false, "id":23, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":23, "subkey":"983fea27520f507c40231f9557908f07c095bdf4a4ce5d"},
|
||||
{"error": false, "id":24, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":24, "subkey":"94d678717625e011995c7355f2092267dee47bf0722dd380"},
|
||||
{"error": false, "id":25, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":25, "subkey":"198901896c4f51e74ffa8b2805415c6eaba5accfc85a6e6b34"},
|
||||
{"error": false, "id":26, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":26, "subkey":"4ffabb81d49021f85ef5d2a713ab02ae86bc2e7d1522f5e077fe"},
|
||||
{"error": false, "id":27, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":27, "subkey":"eebc3d55b3f4fc8b64d2474063254da7db98e7398dfdd510e28075"},
|
||||
{"error": false, "id":28, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":28, "subkey":"22c134b9d664e1bdb14dc309a936bf1512b19e4f5175642efb1a0df7"},
|
||||
{"error": false, "id":29, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":29, "subkey":"4b179762bfc8e27a9e575113faa76247b9c046d6f22d5a02e2910a299b"},
|
||||
{"error": false, "id":30, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":30, "subkey":"abc45eb2b031307b8822c7e59a43f4108850c34a7445936bc848422251c4"},
|
||||
{"error": false, "id":31, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":31, "subkey":"d6565bd3265b6373f4f6a6b6458e981006da5e9d532ce94ca4737e188995e9"},
|
||||
{"error": false, "id":32, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":32, "subkey":"154b291f11196737f8b7f491e4ca11764e0227d34f94295408a869f007aa8618"},
|
||||
{"error": false, "id":33, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":33, "subkey":"e9dd395570e09ebb523ffc6ba098a38b17bc4944f14bd3725bdd7edbd8bcff54fb"},
|
||||
{"error": false, "id":34, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":34, "subkey":"7248294d37159e85bacde68c7762a673794c91b811e05f4e3b9e3ecc82bfcf63a2cd"},
|
||||
{"error": false, "id":35, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":35, "subkey":"d060ee4d93f8de6d9ae60fca9596413455183a1f83c7a2381227cec8f7a217e4072f85"},
|
||||
{"error": false, "id":36, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":36, "subkey":"20790290347b9b0f413a954f40e52e270b3b45417e96c8733161672188701c08dd76cc3d"},
|
||||
{"error": false, "id":37, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":37, "subkey":"7674188112a1ab8d3926d468be8e51d788ce4144bb20ff842034e4d1ddab3929a4f1a13a74"},
|
||||
{"error": false, "id":38, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":38, "subkey":"a2ab1f980a47472d8a539f20410cc9bf143d941331ab2259ea73684c0608939c5b23e9cbcb3d"},
|
||||
{"error": false, "id":39, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":39, "subkey":"f4cfbe3050f15ebbaf8d2f3bf3a678c01fc21ee1f4be07d0744c7fbf4835ea9d9472a3d785c24c"},
|
||||
{"error": false, "id":40, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":40, "subkey":"66efa5dfe3efd4cc8ca25f2d622c97a20a192d7add965f26b002b7eb81aae4203c0e5f07fd945845"},
|
||||
{"error": false, "id":41, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":41, "subkey":"ad5d8031055c96dc9db10285206d7edc38d3af85736df8a3b5fdd30a318e80c28d9b26c95a60fa3e68"},
|
||||
{"error": false, "id":42, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":42, "subkey":"9107c8a57a2c9ca40158f33ca0bfb64c095d2f21ca98bb7138477599330a36cdfc2ae5751e370d0e024e"},
|
||||
{"error": false, "id":43, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":43, "subkey":"b0c190177358b955ebebc5e0b86ec91dde3b6f1982ea4d68ec5ec3bdd6527c362e5275600b263601c98452"},
|
||||
{"error": false, "id":44, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":44, "subkey":"31bfaaad4adde0f87d87372e398c42cb7befe065ab2957ebb91ef9dc534b410783899b2e1e84221286f3bab4"},
|
||||
{"error": false, "id":45, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":45, "subkey":"2258dd1f3e516cb8e3d1f6c45808573c365192f073698939721af8961a02a8bdd002a31fd239b9498663a01f27"},
|
||||
{"error": false, "id":46, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":46, "subkey":"7c7a88016610493bb44a9432a88b50f97e2e94383972ff95da826692d96c52d82f86899b3561ec9c95a8b1bf3213"},
|
||||
{"error": false, "id":47, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":47, "subkey":"3929dc7473be4c633be9e08801a8abd284dc0c6154c5c81a4c18259699dd86753c5e14fbd723be46ebb04f4ab3058c"},
|
||||
{"error": false, "id":48, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":48, "subkey":"30b720220015fa60daa69c83f9754d772b1b2dd12ab6baaa2f4edab458d4d251c1cddb8c4a554f3eb13969316b890fbd"},
|
||||
{"error": false, "id":49, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":49, "subkey":"33fa2412a5c3294d49e964419e96d043a2099a72b3351e3bed0f07e12255c95b509ea9bf2963a4c0fe9cc2314dbc44f673"},
|
||||
{"error": false, "id":50, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":50, "subkey":"ca891d2c82a6a8f833dc1a05f190bab6de221307eab1dd2c88341d4d2537a2fc0056b0d04d8104fd3fe89e1ea20877893e81"},
|
||||
{"error": false, "id":51, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":51, "subkey":"fd78ac89a64d03672ad99d663f2613d15277cda1636e334a1706b7211ff1f3a3b3d2e671e391c75e3d242c482ce7e1b8b427ed"},
|
||||
{"error": false, "id":52, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":52, "subkey":"36a6072743d3aafd3ee89344b9ef92cb58a2853ae92b20283520439fcb55afffd3d4b5e4e8c92a85d3cf74497bdcf68bbf1fcf93"},
|
||||
{"error": false, "id":53, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":53, "subkey":"a90afcfaffec1105ad05fdaa9473fb5daf1bf8fb376b7326db46ef4c120c553188c69131933371d409eb56d66d5adca618e1dac65b"},
|
||||
{"error": false, "id":54, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":54, "subkey":"9b990d1fcddbdb5e5c7a48a6a2a666e02e7d4d4a814ece40660d99e1c02d5f023c56ae82526fc6dc8c933d0add92fc376efcddd55a42"},
|
||||
{"error": false, "id":55, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":55, "subkey":"ec545dcf456d1b0907c07418a42bf2b3d668b4797ba6874bf0d563f5f429a820f02177dd4d05e639a06807c9619fee54ffe07712493543"},
|
||||
{"error": false, "id":56, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":56, "subkey":"b0106957626894586682a275f69ed4533e2f94334cc0430394b68d82679aca00dd579e712bdd2d7f5bbce9a050269739bd8427b75b06027f"},
|
||||
{"error": false, "id":57, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":57, "subkey":"05751bfeebb480c9bca0d25d8197e2673845f405d7fb9793e29169ac19956c525f6e637f3d5ea50597b04342afed4ca16f988b4f21a34f1902"},
|
||||
{"error": false, "id":58, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":58, "subkey":"7b4e4294d3f64085b5c09be73548f1f5cb5c6f04e57ce6cdd3077e2fb37640bf1ca0c6393b87d48a6b7e3e42628bd30fca132ded03ce51f71d9d"},
|
||||
{"error": false, "id":59, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":59, "subkey":"082d248862cbfd71a634769a4b1cf52a4af47ace5b9ea4d583ca52207efc7234a6d321788130cbdec122579ad03afe00bc68c9fb3f68dd0532a96f"},
|
||||
{"error": false, "id":60, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":60, "subkey":"a2b39b4428d981013e8a9c0e41b3eed504983fc18dc4b60332b1ab28b9705228147bdb95cc17889d5f0f9cfb7fd16f9d414b1a829346a8922e945b40"},
|
||||
{"error": false, "id":61, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":61, "subkey":"efbf0f8bda1b9ef24fe389f1cf0c0c8a08bca03fc95badabb79a487d8ce1351683f59183aa6229f880d69ad60114ac128f69b2be250109972ab1f3fc3b"},
|
||||
{"error": false, "id":62, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":62, "subkey":"dfe0ba2a6de25fa06b47375e9d9cf6c6fa1493a8a2a81c28d6e09bc161057b445659db76e92e349ff44f34a2a9e3bcaa6b84b21bae56f1499c170ab81af0"},
|
||||
{"error": false, "id":63, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":63, "subkey":"02f9cbdb10759314515b01379c474ad74a1b575137bd3949776dbcfc3e18060cb13ee1f6dcf86035768fc7be63e01de321cacbfade209900dd94273fd8e176"},
|
||||
{"error": false, "id":64, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":64, "subkey":"06ae14308eeeda62a00cb6d5edf18d1707029515db98f472bbf0617419301b1d4f4f2ab65849446be46f87e1d31c6c74283897b9976f70d8a16253ac927e0d9f"},
|
||||
{"error": true, "id":65, "context":"4b44462074657374", "key":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "subkey_len":65, "subkey":null}
|
||||
]
|
||||
Vendored
+2050
File diff suppressed because it is too large
Load Diff
+1025
File diff suppressed because it is too large
Load Diff
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
/* eslint-disable */
|
||||
const sodium = require('../..')
|
||||
const buf = sodium.sodium_malloc(1)
|
||||
sodium.sodium_mprotect_noaccess(buf)
|
||||
buf[0]
|
||||
process.send('read')
|
||||
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
/* eslint-disable */
|
||||
const sodium = require('../..')
|
||||
const buf = sodium.sodium_malloc(1)
|
||||
sodium.sodium_mprotect_readonly(buf)
|
||||
buf[0]
|
||||
process.send('read')
|
||||
buf[0] = 1
|
||||
process.send('write')
|
||||
Vendored
+11
@@ -0,0 +1,11 @@
|
||||
/* eslint-disable */
|
||||
const sodium = require('../..')
|
||||
const buf = sodium.sodium_malloc(1)
|
||||
sodium.sodium_mprotect_noaccess(buf)
|
||||
sodium.sodium_mprotect_readwrite(buf)
|
||||
buf[0]
|
||||
process.send('read')
|
||||
buf[0] = 1
|
||||
process.send('write')
|
||||
sodium.sodium_mprotect_readonly(buf)
|
||||
process.send(buf[0] === 1 ? 'did_write' : 'did_not_write')
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
/* eslint-disable camelcase */
|
||||
const test = require('brittle')
|
||||
const sodium = require('..')
|
||||
|
||||
test('sodium_memcmp', function (t) {
|
||||
const b1 = Buffer.from([0, 1, 2, 3])
|
||||
const b2 = Buffer.from([3, 2, 1, 0])
|
||||
|
||||
t.exception.all(_ => sodium.sodium_memcmp(), 'no args')
|
||||
t.exception.all(_ => sodium.sodium_memcmp(b1), 'arg mismatch')
|
||||
t.exception.all(_ => sodium.sodium_memcmp(b1, b2.slice(1)), 'length mismatch')
|
||||
t.ok(sodium.sodium_memcmp(Buffer.alloc(0), Buffer.alloc(0)))
|
||||
t.ok(sodium.sodium_memcmp(Buffer.alloc(5), Buffer.alloc(5)))
|
||||
t.ok(sodium.sodium_memcmp(b1, b1))
|
||||
t.absent(sodium.sodium_memcmp(b2, b1))
|
||||
t.absent(sodium.sodium_memcmp(b1, b2))
|
||||
})
|
||||
|
||||
test.skip('sodium_compare', function (t) {
|
||||
const one = Buffer.from([1])
|
||||
const two = Buffer.from([2])
|
||||
const three = Buffer.from([3])
|
||||
|
||||
t.is(sodium.sodium_compare(Buffer.alloc(0), Buffer.alloc(0)), 0)
|
||||
t.is(sodium.sodium_compare(one, one), 0)
|
||||
t.is(sodium.sodium_compare(two, two), 0)
|
||||
t.is(sodium.sodium_compare(three, three), 0)
|
||||
|
||||
t.is(sodium.sodium_compare(one, two), -1)
|
||||
t.is(sodium.sodium_compare(one, three), -1)
|
||||
t.is(sodium.sodium_compare(two, one), 1)
|
||||
t.is(sodium.sodium_compare(three, one), 1)
|
||||
|
||||
t.is(sodium.sodium_compare(two, three), -1)
|
||||
t.is(sodium.sodium_compare(three, two), 1)
|
||||
})
|
||||
|
||||
test.skip('sodium_add', function (t) {
|
||||
const large = Buffer.alloc(32)
|
||||
large[23] = 0b00000011
|
||||
const largeLessOne = Buffer.alloc(32)
|
||||
largeLessOne[23] = 0b00000001
|
||||
|
||||
const c = Buffer.from(large)
|
||||
|
||||
sodium.sodium_add(c, largeLessOne)
|
||||
t.ok(large[23], 4)
|
||||
|
||||
const overflow = Buffer.alloc(56, 0xff)
|
||||
const one = Buffer.alloc(56)
|
||||
one[0] = 1
|
||||
sodium.sodium_add(overflow, one)
|
||||
|
||||
t.ok(sodium.sodium_is_zero(overflow))
|
||||
})
|
||||
|
||||
test.skip('sub', function (t) {
|
||||
const large = Buffer.alloc(32)
|
||||
large[23] = 0b00000011
|
||||
const largeLessOne = Buffer.alloc(32)
|
||||
largeLessOne[23] = 0b00000001
|
||||
|
||||
const c = Buffer.from(large)
|
||||
|
||||
sodium.sodium_sub(c, largeLessOne)
|
||||
t.ok(large[23], 2)
|
||||
|
||||
const overflow = Buffer.alloc(56, 0x00)
|
||||
const one = Buffer.alloc(56)
|
||||
one[0] = 1
|
||||
sodium.sodium_sub(overflow, one)
|
||||
|
||||
t.ok(sodium.sodium_memcmp(overflow, Buffer.alloc(56, 0xff)))
|
||||
})
|
||||
|
||||
test('sodium_increment', function (t) {
|
||||
const zero = Buffer.alloc(4)
|
||||
sodium.sodium_increment(zero)
|
||||
|
||||
t.ok(zero[0], 1)
|
||||
|
||||
const overflow = Buffer.alloc(56, 0xff)
|
||||
sodium.sodium_increment(overflow)
|
||||
|
||||
t.ok(sodium.sodium_is_zero(overflow))
|
||||
})
|
||||
|
||||
test('sodium_is_zero', function (t) {
|
||||
const buf = Buffer.from([0, 0, 0, 1])
|
||||
|
||||
t.exception.all(_ => sodium.sodium_is_zero(), 'no args')
|
||||
t.exception.all(_ => sodium.sodium_is_zero(null), 'missing buf')
|
||||
|
||||
t.ok(sodium.sodium_is_zero(Buffer.alloc(0)), 'empty buffer')
|
||||
t.ok(sodium.sodium_is_zero(buf.subarray(0, 0)), 'zero bytes')
|
||||
t.ok(sodium.sodium_is_zero(buf.subarray(0, 1)), 'one byte')
|
||||
t.ok(sodium.sodium_is_zero(buf.subarray(0, 2)), 'two bytes')
|
||||
t.ok(sodium.sodium_is_zero(buf.subarray(0, 3)), '3 bytes')
|
||||
t.absent(sodium.sodium_is_zero(buf), 'first non-zero byte')
|
||||
t.ok(sodium.sodium_is_zero(buf.subarray(1, 2)), 'view')
|
||||
t.ok(sodium.sodium_is_zero(buf.subarray(1, 2)), 'view')
|
||||
t.absent(sodium.sodium_is_zero(buf.subarray(3)), 'view')
|
||||
})
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
/* eslint-disable camelcase */
|
||||
const test = require('brittle')
|
||||
const sodium = require('..')
|
||||
const fork = require('child_process').fork
|
||||
|
||||
test.skip('sodium_mprotect_noaccess', function (t) {
|
||||
t.plan(1)
|
||||
const p = fork(require.resolve('./fixtures/mprotect_noaccess'))
|
||||
|
||||
p.on('message', function () {
|
||||
t.fail()
|
||||
})
|
||||
p.on('exit', function (code, signal) {
|
||||
t.ok(p.signalCode !== null || p.exitCode > 0)
|
||||
})
|
||||
})
|
||||
|
||||
test.skip('sodium_mprotect_readonly', function (t) {
|
||||
t.plan(2)
|
||||
const p = fork(require.resolve('./fixtures/mprotect_readonly'))
|
||||
|
||||
p.on('message', function (msg) {
|
||||
t.ok(msg === 'read')
|
||||
})
|
||||
p.on('exit', function (code, signal) {
|
||||
t.ok(p.signalCode !== null || p.exitCode > 0)
|
||||
})
|
||||
})
|
||||
|
||||
test.skip('sodium_mprotect_readwrite', function (t) {
|
||||
t.plan(4)
|
||||
const p = fork(require.resolve('./fixtures/mprotect_readwrite'))
|
||||
|
||||
p.on('message', function (msg) {
|
||||
switch (msg) {
|
||||
case 'read': t.pass()
|
||||
break
|
||||
case 'write': t.pass()
|
||||
break
|
||||
case 'did_write': t.pass()
|
||||
break
|
||||
case 'did_not_write': t.fail()
|
||||
break
|
||||
default: t.fail()
|
||||
break
|
||||
}
|
||||
})
|
||||
p.on('exit', function (code, signal) {
|
||||
t.ok(p.signalCode === null || p.exitCode === 0)
|
||||
})
|
||||
})
|
||||
|
||||
test('sodium_memzero', function (t) {
|
||||
const buf = Buffer.alloc(10, 0xab)
|
||||
const exp = Buffer.alloc(10, 0xab)
|
||||
const zero = Buffer.alloc(10)
|
||||
|
||||
t.alike(buf, exp, 'buffers start out with same content')
|
||||
t.unlike(buf, zero, 'buffer is not zero')
|
||||
|
||||
sodium.sodium_memzero(buf)
|
||||
t.unlike(buf, exp, 'buffers are not longer the same')
|
||||
t.alike(buf, zero, 'buffer is now zeroed')
|
||||
})
|
||||
|
||||
test.skip('sodium_mlock / sodium_munlock', function (t) {
|
||||
const buf = Buffer.alloc(10, 0x18)
|
||||
const exp = Buffer.alloc(10, 0x18)
|
||||
|
||||
sodium.sodium_mlock(buf)
|
||||
t.absent(buf.secure)
|
||||
t.alike(buf, exp, 'mlock did not corrupt data')
|
||||
sodium.sodium_munlock(buf)
|
||||
t.absent(buf.secure)
|
||||
t.alike(buf, Buffer.alloc(10), 'munlock did zero data')
|
||||
})
|
||||
|
||||
test('sodium_malloc', function (t) {
|
||||
const empty = sodium.sodium_malloc(0)
|
||||
const small = sodium.sodium_malloc(1)
|
||||
const large = sodium.sodium_malloc(1e8)
|
||||
|
||||
// sodium-javascript does not set secure prop
|
||||
|
||||
// t.ok(empty.secure)
|
||||
// t.ok(small.secure)
|
||||
// t.ok(large.secure)
|
||||
|
||||
t.ok(empty.length === 0, 'has correct size')
|
||||
t.ok(small.length === 1, 'has correct size')
|
||||
t.ok(large.length === 1e8, 'has correct size')
|
||||
|
||||
// const expected = Buffer.from([0xdb])
|
||||
// expected.secure = true
|
||||
// t.alike(small, expected, 'has canary content')
|
||||
|
||||
// test gc
|
||||
for (let i = 0; i < 1e3; i++) {
|
||||
if (sodium.sodium_malloc(256).length !== 256) {
|
||||
t.fail('allocated incorrect size')
|
||||
}
|
||||
}
|
||||
t.ok(empty.length === 0, 'retained correct size')
|
||||
t.ok(small.length === 1, 'retained correct size')
|
||||
t.ok(large.length === 1e8, 'retained correct size')
|
||||
})
|
||||
|
||||
test('sodium_free', function (t) {
|
||||
if (process.version.startsWith('v10')) {
|
||||
t.comment('Skipping free test on v10')
|
||||
return
|
||||
}
|
||||
const buf = sodium.sodium_malloc(1)
|
||||
t.ok(buf.byteLength === 1)
|
||||
sodium.sodium_free(buf)
|
||||
t.ok(buf.byteLength === 0)
|
||||
})
|
||||
|
||||
test.skip('sodium_malloc bounds', function (t) {
|
||||
t.throws(function () {
|
||||
sodium.sodium_malloc(-1)
|
||||
}, 'too small')
|
||||
t.throws(function () {
|
||||
sodium.sodium_malloc(Number.MAX_SAFE_INTEGER)
|
||||
}, 'too large')
|
||||
})
|
||||
@@ -0,0 +1,111 @@
|
||||
/* eslint-disable camelcase */
|
||||
const test = require('brittle')
|
||||
const sodium = require('..')
|
||||
|
||||
test.skip('constants', function (t) {
|
||||
t.alike(typeof sodium.randombytes_SEEDBYTES, 'number', 'randombytes_SEEDBYTES is number')
|
||||
})
|
||||
|
||||
test.skip('randombytes_random', function (t) {
|
||||
for (let i = 0; i < 1e6; i++) {
|
||||
const n = sodium.randombytes_random()
|
||||
if (n > 0xffffffff || n < 0) t.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test.skip('randombytes_uniform', function (t) {
|
||||
const p = 5381
|
||||
for (let i = 0; i < 1e6; i++) {
|
||||
const n = sodium.randombytes_uniform(5381)
|
||||
if (n >= p || n < 0) t.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('randombytes_buf', function (t) {
|
||||
let buf = null
|
||||
|
||||
buf = Buffer.alloc(10)
|
||||
sodium.randombytes_buf(buf)
|
||||
t.not(buf, Buffer.alloc(10), 'not blank')
|
||||
|
||||
buf = Buffer.alloc(1024)
|
||||
sodium.randombytes_buf(buf)
|
||||
t.not(buf, Buffer.alloc(1024), 'large not blank')
|
||||
})
|
||||
|
||||
test.skip('randombytes_deterministic', function (t) {
|
||||
const seed1 = Buffer.allocUnsafe(sodium.randombytes_SEEDBYTES)
|
||||
const seed2 = Buffer.allocUnsafe(sodium.randombytes_SEEDBYTES)
|
||||
const buf1 = Buffer.alloc(10)
|
||||
const buf2 = Buffer.alloc(10)
|
||||
|
||||
for (let i = 0; i < 1e6; i++) {
|
||||
sodium.randombytes_buf(seed1)
|
||||
sodium.randombytes_buf(seed2)
|
||||
|
||||
sodium.randombytes_buf_deterministic(buf1, seed1)
|
||||
sodium.randombytes_buf_deterministic(buf2, seed1)
|
||||
if (!buf1.equals(buf2)) t.fail('should equal')
|
||||
|
||||
sodium.randombytes_buf_deterministic(buf1, seed1)
|
||||
sodium.randombytes_buf_deterministic(buf2, seed2)
|
||||
if (buf1.equals(buf2)) t.fail('should not equal')
|
||||
|
||||
sodium.randombytes_buf_deterministic(buf1, seed2)
|
||||
sodium.randombytes_buf_deterministic(buf2, seed1)
|
||||
if (buf1.equals(buf2)) t.fail('should not equal')
|
||||
|
||||
sodium.randombytes_buf_deterministic(buf1, seed2)
|
||||
sodium.randombytes_buf_deterministic(buf2, seed2)
|
||||
if (!buf1.equals(buf2)) t.fail('should equal')
|
||||
}
|
||||
})
|
||||
|
||||
test.skip('Various test cases', function (t) {
|
||||
sodium.randombytes_buf(Buffer.alloc(0))
|
||||
sodium.randombytes_buf(new Uint8Array(16))
|
||||
|
||||
t.throws(function () {
|
||||
sodium.randombytes_buf([])
|
||||
})
|
||||
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('Generates random bytes', function (t) {
|
||||
const bufConst = Buffer.alloc(64)
|
||||
sodium.randombytes_buf(bufConst)
|
||||
|
||||
const buf1 = Buffer.alloc(64)
|
||||
for (let i = 0; i < 1e4; i++) {
|
||||
sodium.randombytes_buf(buf1)
|
||||
if (Buffer.compare(buf1, bufConst) === 0) {
|
||||
t.fail('Constant buffer should not be equal')
|
||||
t.end()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
t.pass('Generated unique buffers')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('Exceed quota', function (t) {
|
||||
const buf = Buffer.alloc(1 << 17)
|
||||
sodium.randombytes_buf(buf)
|
||||
|
||||
const scores = new Array(256)
|
||||
scores.fill(0)
|
||||
|
||||
for (const b of buf) {
|
||||
scores[b]++
|
||||
}
|
||||
|
||||
scores
|
||||
.map(cnt => cnt / 256)
|
||||
.forEach(cnt => {
|
||||
if (cnt < 1 && cnt > 3) t.fail('Statistically unreasonable')
|
||||
})
|
||||
|
||||
t.end()
|
||||
})
|
||||
+1230
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user