diff --git a/crypto_secretstream.js b/crypto_secretstream.js index 2fb7aa9..138f6e3 100644 --- a/crypto_secretstream.js +++ b/crypto_secretstream.js @@ -27,10 +27,12 @@ const crypto_secretstream_xchacha20poly1305_TAG_MESSAGE = 0 const crypto_secretstream_xchacha20poly1305_TAG_PUSH = 1 const crypto_secretstream_xchacha20poly1305_TAG_REKEY = 2 const crypto_secretstream_xchacha20poly1305_TAG_FINAL = crypto_secretstream_xchacha20poly1305_TAG_PUSH | crypto_secretstream_xchacha20poly1305_TAG_REKEY +const crypto_secretstream_xchacha20poly1305_STATEBYTES = crypto_secretstream_xchacha20poly1305_KEYBYTES + + crypto_secretstream_xchacha20poly1305_INONCEBYTES + crypto_secretstream_xchacha20poly1305_COUNTERBYTES + 8 -// #define STATE_COUNTER(STATE) ((STATE)->nonce) -// #define STATE_INONCE(STATE) ((STATE)->nonce + \ -// crypto_secretstream_xchacha20poly1305_COUNTERBYTES) +const KEY_OFFSET = 0 +const NONCE_OFFSET = crypto_secretstream_xchacha20poly1305_KEYBYTES +const PAD_OFFSET = NONCE_OFFSET + crypto_secretstream_xchacha20poly1305_INONCEBYTES + crypto_secretstream_xchacha20poly1305_COUNTERBYTES const _pad0 = new Uint8Array(16) @@ -44,11 +46,14 @@ function STORE64_LE (dest, int) { } function crypto_secretstream_xchacha20poly1305_counter_reset (state) { - assert(state instanceof Crypto_secretstream_xchacha20poly1305_state, 'state is not an instance of Crypto_secretstream_xchacha20poly1305_state') + assert(state.byteLength === crypto_secretstream_xchacha20poly1305_STATEBYTES, + 'state is should be crypto_secretstream_xchacha20poly1305_STATEBYTES long') + + const nonce = state.subarray(NONCE_OFFSET, PAD_OFFSET) for (let i = 0; i < crypto_secretstream_xchacha20poly1305_COUNTERBYTES; i++) { - state.nonce[i] = 0 + nonce[i] = 0 } - state.nonce[0] = 1 + nonce[0] = 1 } function crypto_secretstream_xchacha20poly1305_keygen (k) { @@ -56,89 +61,105 @@ function crypto_secretstream_xchacha20poly1305_keygen (k) { randombytes_buf(k) } -function crypto_secretstream_xchacha20poly1305_init_push (state, out, k) { - assert(state instanceof Crypto_secretstream_xchacha20poly1305_state, 'state not instance of Crypto_secretstream_xchacha20poly1305_state') +function crypto_secretstream_xchacha20poly1305_init_push (state, out, key) { + assert(state.byteLength === crypto_secretstream_xchacha20poly1305_STATEBYTES, + 'state is should be crypto_secretstream_xchacha20poly1305_STATEBYTES long') assert(out instanceof Uint8Array && out.length === crypto_secretstream_xchacha20poly1305_HEADERBYTES, 'out not byte array of length crypto_secretstream_xchacha20poly1305_HEADERBYTES') - assert(k instanceof Uint8Array && k.length === crypto_secretstream_xchacha20poly1305_KEYBYTES, 'k not byte array of length crypto_secretstream_xchacha20poly1305_KEYBYTES') assert(crypto_secretstream_xchacha20poly1305_HEADERBYTES === crypto_core_hchacha20_INPUTBYTES + crypto_secretstream_xchacha20poly1305_INONCEBYTES) assert(crypto_secretstream_xchacha20poly1305_HEADERBYTES === crypto_aead_xchacha20poly1305_ietf_NPUBBYTES) - assert(state.nonce.length === crypto_secretstream_xchacha20poly1305_INONCEBYTES + crypto_secretstream_xchacha20poly1305_COUNTERBYTES) + assert(key instanceof Uint8Array && key.length === crypto_secretstream_xchacha20poly1305_KEYBYTES, 'key not byte array of length crypto_secretstream_xchacha20poly1305_KEYBYTES') + + const k = state.subarray(KEY_OFFSET, NONCE_OFFSET) + const nonce = state.subarray(NONCE_OFFSET, PAD_OFFSET) + const pad = state.subarray(PAD_OFFSET) randombytes_buf(out, crypto_secretstream_xchacha20poly1305_HEADERBYTES) - crypto_core_hchacha20(state.k, out, k, null) + crypto_core_hchacha20(k, out, key, null) crypto_secretstream_xchacha20poly1305_counter_reset(state) for (let i = 0; i < crypto_secretstream_xchacha20poly1305_INONCEBYTES; i++) { - state.nonce[i + crypto_secretstream_xchacha20poly1305_COUNTERBYTES] = out[i + crypto_core_hchacha20_INPUTBYTES] + nonce[i + crypto_secretstream_xchacha20poly1305_COUNTERBYTES] = out[i + crypto_core_hchacha20_INPUTBYTES] } - state.pad.fill(0) - return 0 + pad.fill(0) } -function crypto_secretstream_xchacha20poly1305_init_pull (state, _in, k) { - assert(state instanceof Crypto_secretstream_xchacha20poly1305_state, - 'state not instance of Crypto_secretstream_xchacha20poly1305_state') +function crypto_secretstream_xchacha20poly1305_init_pull (state, _in, key) { + assert(state.byteLength === crypto_secretstream_xchacha20poly1305_STATEBYTES, + 'state is should be crypto_secretstream_xchacha20poly1305_STATEBYTES long') assert(_in instanceof Uint8Array && _in.length === crypto_secretstream_xchacha20poly1305_HEADERBYTES, '_in not byte array of length crypto_secretstream_xchacha20poly1305_HEADERBYTES') - assert(k instanceof Uint8Array && k.length === crypto_secretstream_xchacha20poly1305_KEYBYTES, - 'k not byte array of length crypto_secretstream_xchacha20poly1305_KEYBYTES') - crypto_core_hchacha20(state.k, _in, k, null) + assert(key instanceof Uint8Array && key.length === crypto_secretstream_xchacha20poly1305_KEYBYTES, + 'key not byte array of length crypto_secretstream_xchacha20poly1305_KEYBYTES') + + const k = state.subarray(KEY_OFFSET, NONCE_OFFSET) + const nonce = state.subarray(NONCE_OFFSET, PAD_OFFSET) + const pad = state.subarray(PAD_OFFSET) + + crypto_core_hchacha20(k, _in, key, null) crypto_secretstream_xchacha20poly1305_counter_reset(state) for (let i = 0; i < crypto_secretstream_xchacha20poly1305_INONCEBYTES; i++) { - state.nonce[i + crypto_secretstream_xchacha20poly1305_COUNTERBYTES] = _in[i + crypto_core_hchacha20_INPUTBYTES] + nonce[i + crypto_secretstream_xchacha20poly1305_COUNTERBYTES] = _in[i + crypto_core_hchacha20_INPUTBYTES] } - state.pad.fill(0) - return 0 + pad.fill(0) } function crypto_secretstream_xchacha20poly1305_rekey (state) { - assert(state instanceof Crypto_secretstream_xchacha20poly1305_state, - 'state not instance of Crypto_secretstream_xchacha20poly1305_state') + assert(state.byteLength === crypto_secretstream_xchacha20poly1305_STATEBYTES, + 'state is should be crypto_secretstream_xchacha20poly1305_STATEBYTES long') + + const k = state.subarray(KEY_OFFSET, NONCE_OFFSET) + const nonce = state.subarray(NONCE_OFFSET, PAD_OFFSET) + const new_key_and_inonce = new Uint8Array( crypto_stream_chacha20_ietf_KEYBYTES + crypto_secretstream_xchacha20poly1305_INONCEBYTES) let i for (i = 0; i < crypto_stream_chacha20_ietf_KEYBYTES; i++) { - new_key_and_inonce[i] = state.k[i] + new_key_and_inonce[i] = k[i] } for (i = 0; i < crypto_secretstream_xchacha20poly1305_INONCEBYTES; i++) { new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + i] = - state.nonce[crypto_secretstream_xchacha20poly1305_COUNTERBYTES + i] + nonce[crypto_secretstream_xchacha20poly1305_COUNTERBYTES + i] } - crypto_stream_chacha20_ietf_xor(new_key_and_inonce, new_key_and_inonce, state.nonce, state.k) + crypto_stream_chacha20_ietf_xor(new_key_and_inonce, new_key_and_inonce, nonce, k) for (i = 0; i < crypto_stream_chacha20_ietf_KEYBYTES; i++) { - state.k[i] = new_key_and_inonce[i] + k[i] = new_key_and_inonce[i] } for (i = 0; i < crypto_secretstream_xchacha20poly1305_INONCEBYTES; i++) { - state.nonce[crypto_secretstream_xchacha20poly1305_COUNTERBYTES + i] = + nonce[crypto_secretstream_xchacha20poly1305_COUNTERBYTES + i] = new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + i] } crypto_secretstream_xchacha20poly1305_counter_reset(state) } function crypto_secretstream_xchacha20poly1305_push (state, out, m, ad, adlen, tag, outputs) { + assert(state.byteLength === crypto_secretstream_xchacha20poly1305_STATEBYTES, + 'state is should be crypto_secretstream_xchacha20poly1305_STATEBYTES long') + if (!ad) ad = new Uint8Array(0) + + const k = state.subarray(KEY_OFFSET, NONCE_OFFSET) + const nonce = state.subarray(NONCE_OFFSET, PAD_OFFSET) + const block = new Uint8Array(64) const slen = new Uint8Array(8) assert(crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX <= crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX) - crypto_stream_chacha20_ietf(block, state.nonce, state.k) + crypto_stream_chacha20_ietf(block, nonce, k) const poly = new Poly1305(block) block.fill(0) - poly.update(ad, 0, adlen) - poly.update(_pad0, 0, (0x10 - adlen) & 0xf) + poly.update(ad, 0, ad.byteLength) + poly.update(_pad0, 0, (0x10 - ad.byteLength) & 0xf) block[0] = tag - crypto_stream_chacha20_ietf_xor_ic(block, block, state.nonce, 1, state.k) + crypto_stream_chacha20_ietf_xor_ic(block, block, nonce, 1, k) poly.update(block, 0, block.byteLength) out[0] = block[0] - // block is 64 bytes. sizeof tag is 1, as it's a byte, so c is the subarray starting at out[1] - // c = out + (sizeof tag); const c = out.subarray(1, out.byteLength) - crypto_stream_chacha20_ietf_xor_ic(c, m, state.nonce, 2, state.k) + crypto_stream_chacha20_ietf_xor_ic(c, m, nonce, 2, k) poly.update(c, 0, m.byteLength) poly.update(_pad0, 0, (0x10 - block.byteLength + m.byteLength) & 0xf) @@ -152,12 +173,12 @@ function crypto_secretstream_xchacha20poly1305_push (state, out, m, ad, adlen, t assert(crypto_onetimeauth_poly1305_BYTES >= crypto_secretstream_xchacha20poly1305_INONCEBYTES) - xor_buf(state.nonce.subarray(crypto_secretstream_xchacha20poly1305_COUNTERBYTES, state.nonce.length), + xor_buf(nonce.subarray(crypto_secretstream_xchacha20poly1305_COUNTERBYTES, nonce.length), mac, crypto_secretstream_xchacha20poly1305_INONCEBYTES) - sodium_increment(state.nonce) + sodium_increment(nonce) if ((tag & crypto_secretstream_xchacha20poly1305_TAG_REKEY) !== 0 || - sodium_is_zero(state.nonce.subarray(0, crypto_secretstream_xchacha20poly1305_COUNTERBYTES))) { + sodium_is_zero(nonce.subarray(0, crypto_secretstream_xchacha20poly1305_COUNTERBYTES))) { crypto_secretstream_xchacha20poly1305_rekey(state) } @@ -166,6 +187,13 @@ function crypto_secretstream_xchacha20poly1305_push (state, out, m, ad, adlen, t } function crypto_secretstream_xchacha20poly1305_pull (state, m, _in, ad, adlen, outputs) { + assert(state.byteLength === crypto_secretstream_xchacha20poly1305_STATEBYTES, + 'state is should be crypto_secretstream_xchacha20poly1305_STATEBYTES long') + if (!ad) ad = new Uint8Array(0) + + const k = state.subarray(KEY_OFFSET, NONCE_OFFSET) + const nonce = state.subarray(NONCE_OFFSET, PAD_OFFSET) + const block = new Uint8Array(64) const slen = new Uint8Array(8) const mac = new Uint8Array(crypto_onetimeauth_poly1305_BYTES) @@ -175,7 +203,7 @@ function crypto_secretstream_xchacha20poly1305_pull (state, m, _in, ad, adlen, o } const mlen = _in.byteLength - crypto_secretstream_xchacha20poly1305_ABYTES - crypto_stream_chacha20_ietf(block, state.nonce, state.k) + crypto_stream_chacha20_ietf(block, nonce, k) const poly = new Poly1305(block) block.fill(0) // sodium_memzero(block, sizeof block); @@ -184,7 +212,7 @@ function crypto_secretstream_xchacha20poly1305_pull (state, m, _in, ad, adlen, o block.fill(0) // memset(block, 0, sizeof block); block[0] = _in[0] - crypto_stream_chacha20_ietf_xor_ic(block, block, state.nonce, 1, state.k) + crypto_stream_chacha20_ietf_xor_ic(block, block, nonce, 1, k) const tag = block[0] block[0] = _in[0] @@ -209,13 +237,13 @@ function crypto_secretstream_xchacha20poly1305_pull (state, m, _in, ad, adlen, o } } - crypto_stream_chacha20_ietf_xor_ic(m, c.subarray(0, m.length), state.nonce, 2, state.k) - xor_buf(state.nonce.subarray(crypto_secretstream_xchacha20poly1305_COUNTERBYTES, state.nonce.length), + crypto_stream_chacha20_ietf_xor_ic(m, c.subarray(0, m.length), nonce, 2, k) + xor_buf(nonce.subarray(crypto_secretstream_xchacha20poly1305_COUNTERBYTES, nonce.length), mac, crypto_secretstream_xchacha20poly1305_INONCEBYTES) - sodium_increment(state.nonce) + sodium_increment(nonce) if ((tag & crypto_secretstream_xchacha20poly1305_TAG_REKEY) !== 0 || - sodium_is_zero(state.nonce.subarray(0, crypto_secretstream_xchacha20poly1305_COUNTERBYTES))) { + sodium_is_zero(nonce.subarray(0, crypto_secretstream_xchacha20poly1305_COUNTERBYTES))) { crypto_secretstream_xchacha20poly1305_rekey(state) } outputs.res_len = mlen @@ -266,7 +294,6 @@ function xor_buf (out, _in, n) { } module.exports = { - Crypto_secretstream_xchacha20poly1305_state, crypto_secretstream_xchacha20poly1305_keygen, crypto_secretstream_xchacha20poly1305_init_push, crypto_secretstream_xchacha20poly1305_init_pull, @@ -283,273 +310,3 @@ module.exports = { crypto_secretstream_xchacha20poly1305_tag_rekey, crypto_secretstream_xchacha20poly1305_tag_final } - -// test - -function memcpy (dest, src, n) { - assert(dest.length >= n && src.length >= n, 'n longer than source or destination') - for (let i = 0; i < n; i++) { - dest[i] = src[i] - } -} - -function getRandomInt (min, max) { - min = Math.ceil(min) - max = Math.floor(max) - return Math.floor(Math.random() * (max - min) + min) // The maximum is exclusive and the minimum is inclusive -} - -function test_secretstream () { - const state = new Crypto_secretstream_xchacha20poly1305_state() - const statesave = new Crypto_secretstream_xchacha20poly1305_state() - const state_copy = new Crypto_secretstream_xchacha20poly1305_state() - const header = new Uint8Array(crypto_secretstream_xchacha20poly1305_HEADERBYTES) - const outputs = { - res_len: null, - tag: null - } - - const ad_len = getRandomInt(0, 100) - const m1_len = getRandomInt(0, 1000) - const m2_len = getRandomInt(0, 1000) - const m3_len = getRandomInt(0, 1000) - - const c1 = new Uint8Array(m1_len + crypto_secretstream_xchacha20poly1305_ABYTES) - const c2 = new Uint8Array(m2_len + crypto_secretstream_xchacha20poly1305_ABYTES) - const c3 = new Uint8Array(m3_len + crypto_secretstream_xchacha20poly1305_ABYTES) - const csave = new Uint8Array((m1_len | m2_len | m3_len) + crypto_secretstream_xchacha20poly1305_ABYTES) - - const ad = new Uint8Array(ad_len) - const m1 = new Uint8Array(m1_len) - const m2 = new Uint8Array(m2_len) - const m3 = new Uint8Array(m3_len) - const m1_ = new Uint8Array(m1_len) - const m2_ = new Uint8Array(m2_len) - const m3_ = new Uint8Array(m3_len) - - randombytes_buf(ad, ad_len) - - randombytes_buf(m1, m1_len) - memcpy(m1_, m1, m1_len) - randombytes_buf(m2, m2_len) - memcpy(m2_, m2, m2_len) - randombytes_buf(m3, m3_len) - memcpy(m3_, m3, m3_len) - - const k = new Uint8Array(crypto_secretstream_xchacha20poly1305_KEYBYTES) - crypto_secretstream_xchacha20poly1305_keygen(k) - - /* push */ - - let ret = crypto_secretstream_xchacha20poly1305_init_push(state, header, k) - assert(ret === 0, 'init_push failed') - - ret = crypto_secretstream_xchacha20poly1305_push(state, c1, m1, 0, 0, 0, outputs) // how can ad be null here? - assert(ret === 0, 'push failed') - assert(outputs.res_len === m1_len + crypto_secretstream_xchacha20poly1305_ABYTES) - - ret = crypto_secretstream_xchacha20poly1305_push(state, c2, m2, ad, 0, 0, outputs) - assert(ret === 0, 'second push failed') - - ret = crypto_secretstream_xchacha20poly1305_push(state, c3, m3, ad, ad_len, crypto_secretstream_xchacha20poly1305_TAG_FINAL, outputs) - assert(ret === 0, 'third push failed') - - /* pull */ - - ret = crypto_secretstream_xchacha20poly1305_init_pull(state, header, k) - assert(ret === 0) - - ret = crypto_secretstream_xchacha20poly1305_pull(state, m1, c1, 0, 0, outputs) - assert(ret === 0, 'first pull failed') - assert(outputs.tag === 0, 'tag pull failed') - assert(sodium_memcmp(m1, m1_), 'failed m1 memcmp') - assert(outputs.res_len === m1_len) - - ret = crypto_secretstream_xchacha20poly1305_pull(state, m2, c2, 0, 0, outputs) - assert(ret === 0, 'second pull failed') - assert(outputs.tag === 0, 'second tag pull failed') - assert(sodium_memcmp(m2, m2_, m2_len), 'failed m2 memcmp') - - if (ad_len > 0) { - ret = crypto_secretstream_xchacha20poly1305_pull(state, m3, c3, 0, 0, outputs) - assert(ret === -1, 'failed third pull') - } - - ret = crypto_secretstream_xchacha20poly1305_pull(state, m3, c3, ad, ad_len, outputs) - assert(ret === 0, 'failed fourth pull') - assert(outputs.tag === crypto_secretstream_xchacha20poly1305_TAG_FINAL, 'failed final tag pull') - assert(sodium_memcmp(m3, m3_, m3_len), 'failed m3 memcmp') - - /* previous with FINAL tag */ - - ret = crypto_secretstream_xchacha20poly1305_pull(state, m3, c3, ad, ad_len, outputs) - assert(ret === -1) - - /* previous without a tag */ - - ret = crypto_secretstream_xchacha20poly1305_pull(state, m2, c2, 0, 0, outputs) - assert(ret === -1) - - /* short ciphertext */ - - ret = crypto_secretstream_xchacha20poly1305_pull(state, m2, - c2.subarray(0, getRandomInt(0, crypto_secretstream_xchacha20poly1305_ABYTES)), 0, 0, outputs) - assert(ret === -1) - ret = crypto_secretstream_xchacha20poly1305_pull(state, m2, c2, 0, 0, outputs) - assert(ret === -1) - - /* empty ciphertext */ - - ret = crypto_secretstream_xchacha20poly1305_pull(state, m2, - c2.subarray(0, crypto_secretstream_xchacha20poly1305_ABYTES), 0, 0, outputs) - assert(ret === -1) - - /* without explicit rekeying */ - - ret = crypto_secretstream_xchacha20poly1305_init_push(state, header, k) - assert(ret === 0) - ret = crypto_secretstream_xchacha20poly1305_push(state, c1, m1, 0, 0, 0, outputs) - assert(ret === 0) - ret = crypto_secretstream_xchacha20poly1305_push(state, c2, m2, 0, 0, 0, outputs) - assert(ret === 0) - - ret = crypto_secretstream_xchacha20poly1305_init_pull(state, header, k) - assert(ret === 0) - ret = crypto_secretstream_xchacha20poly1305_pull(state, m1, c1, 0, 0, outputs) - assert(ret === 0) - ret = crypto_secretstream_xchacha20poly1305_pull(state, m2, c2, 0, 0, outputs) - assert(ret === 0) - - /* with explicit rekeying */ - - ret = crypto_secretstream_xchacha20poly1305_init_push(state, header, k) - assert(ret === 0) - ret = crypto_secretstream_xchacha20poly1305_push(state, c1, m1, 0, 0, 0, outputs) - assert(ret === 0) - - crypto_secretstream_xchacha20poly1305_rekey(state) - - ret = crypto_secretstream_xchacha20poly1305_push(state, c2, m2, 0, 0, 0, outputs) - assert(ret === 0) - - ret = crypto_secretstream_xchacha20poly1305_init_pull(state, header, k) - assert(ret === 0) - ret = crypto_secretstream_xchacha20poly1305_pull(state, m1, c1, 0, 0, outputs) - assert(ret === 0) - - ret = crypto_secretstream_xchacha20poly1305_pull(state, m2, c2, 0, 0, outputs) - assert(ret === -1) - - crypto_secretstream_xchacha20poly1305_rekey(state) - - ret = crypto_secretstream_xchacha20poly1305_pull(state, m2, c2, 0, 0, outputs) - assert(ret === 0) - - /* with explicit rekeying using TAG_REKEY */ - - ret = crypto_secretstream_xchacha20poly1305_init_push(state, header, k) - assert(ret === 0) - - statesave.k = new Uint8Array(state.k) - statesave.nonce = new Uint8Array(state.nonce) - statesave.pad = new Uint8Array(state.pad) - - ret = crypto_secretstream_xchacha20poly1305_push(state, c1, m1, 0, 0, crypto_secretstream_xchacha20poly1305_TAG_REKEY, outputs) - assert(ret === 0) - - ret = crypto_secretstream_xchacha20poly1305_push(state, c2, m2, 0, 0, 0, outputs) - assert(ret === 0) - - memcpy(csave, c2, m2_len + crypto_secretstream_xchacha20poly1305_ABYTES) - - ret = crypto_secretstream_xchacha20poly1305_init_pull(state, header, k) - assert(ret === 0) - ret = crypto_secretstream_xchacha20poly1305_pull(state, m1, c1, 0, 0, outputs) - assert(ret === 0) - assert(outputs.tag === crypto_secretstream_xchacha20poly1305_TAG_REKEY) - - ret = crypto_secretstream_xchacha20poly1305_pull(state, m2, c2, 0, 0, outputs) - assert(ret === 0) - assert(outputs.tag === 0) - - state.k = new Uint8Array(statesave.k) - state.nonce = new Uint8Array(statesave.nonce) - state.pad = new Uint8Array(statesave.pad) - - ret = crypto_secretstream_xchacha20poly1305_push(state, c1, m1, 0, 0, 0, outputs) - assert(ret === 0) - - ret = crypto_secretstream_xchacha20poly1305_push(state, c2, m2, 0, 0, 0, outputs) - assert(ret === 0) - assert(!sodium_memcmp( - csave.subarray(0, m2_len + crypto_secretstream_xchacha20poly1305_ABYTES), - c2.subarray(0, m2_len + crypto_secretstream_xchacha20poly1305_ABYTES) - )) - - /* New stream */ - - ret = crypto_secretstream_xchacha20poly1305_init_push(state, header, k) - assert(ret === 0) - - ret = crypto_secretstream_xchacha20poly1305_push(state, c1, m1, 0, 0, - crypto_secretstream_xchacha20poly1305_TAG_PUSH, outputs) - assert(ret === 0) - assert(outputs.res_len === m1_len + crypto_secretstream_xchacha20poly1305_ABYTES) - - /* Force a counter overflow, check that the key has been updated - * even though the tag was not changed to REKEY */ - - for (let i = 0; i < 4; i++) { - state.nonce[i] = 0xff - } - state_copy.k = new Uint8Array(state.k) - state_copy.nonce = new Uint8Array(state.nonce) - state_copy.pad = new Uint8Array(state.pad) - - ret = crypto_secretstream_xchacha20poly1305_push(state, c2, m2, ad, 0, 0, outputs) - assert(ret === 0) - assert(!sodium_memcmp(state_copy.k, state.k)) - assert(!sodium_memcmp(state_copy.nonce, state.nonce)) - assert(state.nonce[0] === 1) - assert(sodium_is_zero(state.nonce.subarray(1, 4))) - - ret = crypto_secretstream_xchacha20poly1305_init_pull(state, header, k) - assert(ret === 0) - - ret = crypto_secretstream_xchacha20poly1305_pull(state, m1, c1, 0, 0, outputs) - assert(ret === 0) - assert(outputs.tag === crypto_secretstream_xchacha20poly1305_TAG_PUSH) - assert(sodium_memcmp(m1, m1_)) - assert(outputs.res_len === m1_len) - - for (let i = 0; i < 4; i++) { - state.nonce[i] = 0xff - } - - ret = crypto_secretstream_xchacha20poly1305_pull(state, m2, c2, 0, 0, outputs) - assert(ret === 0) - assert(outputs.tag === 0) - assert(sodium_memcmp(m2, m2_)) - - assert(crypto_secretstream_xchacha20poly1305_abytes() === - crypto_secretstream_xchacha20poly1305_ABYTES) - assert(crypto_secretstream_xchacha20poly1305_headerbytes() === - crypto_secretstream_xchacha20poly1305_HEADERBYTES) - assert(crypto_secretstream_xchacha20poly1305_keybytes() === - crypto_secretstream_xchacha20poly1305_KEYBYTES) - assert(crypto_secretstream_xchacha20poly1305_messagebytes_max() === - crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX) - - assert(crypto_secretstream_xchacha20poly1305_tag_message() === - crypto_secretstream_xchacha20poly1305_TAG_MESSAGE) - assert(crypto_secretstream_xchacha20poly1305_tag_push() === - crypto_secretstream_xchacha20poly1305_TAG_PUSH) - assert(crypto_secretstream_xchacha20poly1305_tag_rekey() === - crypto_secretstream_xchacha20poly1305_TAG_REKEY) - assert(crypto_secretstream_xchacha20poly1305_tag_final() === - crypto_secretstream_xchacha20poly1305_TAG_FINAL) - - console.log('secretstream test OK') -} - -test_secretstream() diff --git a/index.js b/index.js index 63579fd..2f5a3f5 100644 --- a/index.js +++ b/index.js @@ -28,7 +28,6 @@ forward(require('./crypto_shorthash')) forward(require('./crypto_sign')) forward(require('./crypto_stream')) forward(require('./crypto_stream_chacha20')) -forward(require('./crypto_core_hchacha20')) function forward (submodule) { Object.keys(submodule).forEach(function (prop) {