This commit is contained in:
Theron 2020-11-23 22:54:22 -06:00
parent 9c2e01c678
commit 0cfb053ef5

View File

@ -4,27 +4,18 @@ const { randombytes_buf } = require('./randombytes')
const { crypto_stream_chacha20_ietf, crypto_stream_chacha20_ietf_xor, crypto_stream_chacha20_ietf_xor_ic, crypto_stream_chacha20_ietf_KEYBYTES, crypto_stream_chacha20_ietf_NONCEBYTES } = require('./crypto_stream_chacha20')
const { crypto_core_hchacha20, crypto_core_hchacha20_INPUTBYTES } = require('./crypto_core_hchacha20')
const Poly1305 = require('./internal/poly1305')
const { STORE64_LE } = require('./crypto_kdf')
const { sodium_increment } = require('./helpers')
const crypto_onetimeauth_poly1305_BYTES = 16
const crypto_secretstream_xchacha20poly1305_COUNTERBYTES = 4
const crypto_secretstream_xchacha20poly1305_INONCEBYTES = 8
const crypto_aead_xchacha20poly1305_ietf_KEYBYTES = 32
const crypto_secretstream_xchacha20poly1305_KEYBYTES = crypto_aead_xchacha20poly1305_ietf_KEYBYTES
// #define crypto_secretstream_xchacha20poly1305_HEADERBYTES \
// crypto_aead_xchacha20poly1305_ietf_NPUBBYTES
const crypto_aead_xchacha20poly1305_ietf_NPUBBYTES = 24
const crypto_secretstream_xchacha20poly1305_HEADERBYTES = crypto_aead_xchacha20poly1305_ietf_NPUBBYTES
// #define crypto_aead_xchacha20poly1305_ietf_ABYTES 16U
const crypto_aead_xchacha20poly1305_ietf_ABYTES = 16
// #define crypto_secretstream_xchacha20poly1305_ABYTES \
// (1U + crypto_aead_xchacha20poly1305_ietf_ABYTES)
const crypto_secretstream_xchacha20poly1305_ABYTES = 1 + crypto_aead_xchacha20poly1305_ietf_ABYTES
// #define crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX \
// SODIUM_MIN(SODIUM_SIZE_MAX - crypto_secretstream_xchacha20poly1305_ABYTES, \
// (64ULL * ((1ULL << 32) - 2ULL)))
const crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX = Number.MAX_SAFE_INTEGER
const crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX = Number.MAX_SAFE_INTEGER
@ -53,9 +44,9 @@ class crypto_secretstream_xchacha20poly1305_state {
function _crypto_secretstream_xchacha20poly1305_counter_reset (state) {
assert(state instanceof crypto_secretstream_xchacha20poly1305_state, 'state is not an instance of crypto_secretstream_xchacha20poly1305_state')
for (let i = 0; i < crypto_secretstream_xchacha20poly1305_COUNTERBYTES; i++) {
state[i] = 0
state.nonce[i] = 0
}
state[0] = 1
state.nonce[0] = 1
}
// void
@ -263,6 +254,7 @@ function crypto_secretstream_xchacha20poly1305_rekey (state) {
// }
function crypto_secretstream_xchacha20poly1305_push (state, out, m, ad, tag) {
const block = new Uint8Array(64)
const slen = new Uint8Array(8)
assert(crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX <=
crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX)
@ -278,13 +270,33 @@ function crypto_secretstream_xchacha20poly1305_push (state, out, m, ad, tag) {
crypto_stream_chacha20_ietf_xor_ic(block, state.nonce, 1, state.k)
poly.update(block, 0, block.byteLength)
out[0] = block[0];
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);
let c = out.subarray(1, out.byteLength)
const c = out.subarray(1, out.byteLength)
crypto_stream_chacha20_ietf_xor_ic(c, m, state.nonce, 2, state.key)
poly.update(c, 0, m.byteLength)
poly.update(_pad0, (0x10 - block.byteLength + m.byteLength) & 0xf)
STORE64_LE(slen, ad.byteLength)
poly.update(slen, slen.byteLength)
STORE64_LE(slen, block.byteLength + m.byteLength)
poly.update(slen, slen.byteLength)
const mac = out.subarray(1 + m.byteLength, out.byteLength)
poly.finish(mac, 0)
assert(crypto_onetimeauth_poly1305_BYTES >=
crypto_secretstream_xchacha20poly1305_INONCEBYTES)
xor_buf(state.nonce.subarray(crypto_secretstream_xchacha20poly1305_COUNTERBYTES, state.nonce.length),
mac, crypto_secretstream_xchacha20poly1305_INONCEBYTES)
sodium_increment(state.nonce)
if ((tag & crypto_secretstream_xchacha20poly1305_TAG_REKEY) != 0 ||
sodium_is_zero(STATE_COUNTER(state), crypto_secretstream_xchacha20poly1305_COUNTERBYTES)) {
crypto_secretstream_xchacha20poly1305_rekey(state)
}
}
// int
@ -425,6 +437,12 @@ function crypto_secretstream_xchacha20poly1305_push (state, out, m, ad, tag) {
// return crypto_secretstream_xchacha20poly1305_TAG_FINAL;
// }
function xor_buf (out, _in, n) {
for (let i = 0; i < n; i++) {
out[i] ^= _in[i]
}
}
module.exports = {
crypto_aead_xchacha20poly1305_ietf_ABYTES,
crypto_secretstream_xchacha20poly1305_ABYTES,