Deprecate sodium-test (#68)

* deprecate sodium-test ahrness

* prune dependencies
This commit is contained in:
Christophe Diederichs 2023-05-23 16:16:13 +01:00 committed by GitHub
parent ae2df3305e
commit f19e6c8172
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 7760 additions and 9 deletions

View File

@ -13,15 +13,18 @@
"xsalsa20": "^1.0.0" "xsalsa20": "^1.0.0"
}, },
"devDependencies": { "devDependencies": {
"brittle": "^3.2.1",
"browserify": "^16.5.1", "browserify": "^16.5.1",
"sodium-test": "^0.10.0", "standard": "^15.0.1"
"standard": "^15.0.1",
"tape-run": "^7.0.0"
}, },
"standard": { "standard": {
"ignore": [ "ignore": [
"/internal/**/*.js" "/internal/**/*.js",
] "/test/fixtures/*.js"
],
"rules": {
"camelcase": "off"
}
}, },
"browser": { "browser": {
"crypto": false, "crypto": false,
@ -29,7 +32,7 @@
}, },
"scripts": { "scripts": {
"pretest": "standard", "pretest": "standard",
"test": "node test.js", "test": "brittle test/*.js",
"test-browser": "browserify test.js | tape-run" "test-browser": "browserify test.js | tape-run"
}, },
"repository": { "repository": {

View File

@ -1,3 +0,0 @@
require('sodium-test')(require('.'))
if ((typeof window !== 'undefined') && window.close) window.close()

View File

@ -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
*/

219
test/crypto_auth.js Normal file
View File

@ -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
}

305
test/crypto_box.js Normal file
View File

@ -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()
})

133
test/crypto_generichash.js Normal file
View File

@ -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')
})

17
test/crypto_hash.js Normal file
View File

@ -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')
})

View File

@ -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')
})

View File

@ -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')
})

71
test/crypto_kdf.js Normal file
View File

@ -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()
})

265
test/crypto_kx.js Normal file
View File

@ -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)
})

View File

@ -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')
})

39
test/crypto_scalarmult.js Normal file
View File

@ -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
}
}

72
test/crypto_secretbox.js Normal file
View File

@ -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')
})

148
test/crypto_secretstream.js Normal file
View File

@ -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)
})

214
test/crypto_shorthash.js Normal file
View File

@ -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()
}

334
test/crypto_sign.js Normal file
View File

@ -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))
}
}

213
test/crypto_stream.js Normal file
View File

@ -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')()
}

View File

@ -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')()
}

View File

@ -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')()
}

78
test/fixtures/crypto_kdf.json vendored Normal file
View File

@ -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}
]

2050
test/fixtures/crypto_sign.json vendored Normal file

File diff suppressed because it is too large Load Diff

1025
test/fixtures/crypto_tweak_ed25519_sign.js vendored Normal file

File diff suppressed because it is too large Load Diff

6
test/fixtures/mprotect_noaccess.js vendored Normal file
View File

@ -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')

8
test/fixtures/mprotect_readonly.js vendored Normal file
View File

@ -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')

11
test/fixtures/mprotect_readwrite.js vendored Normal file
View File

@ -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
test/helpers.js Normal file
View File

@ -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
test/memory.js Normal file
View File

@ -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')
})

111
test/randombytes.js Normal file
View File

@ -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
test/vectors.js Normal file

File diff suppressed because it is too large Load Diff