sodium-secretstream
Version:
Wraps libsodiums secretstream in a higher level abstraction
71 lines (57 loc) • 2.26 kB
JavaScript
const sodium = require('sodium-universal')
const b4a = require('b4a')
const ABYTES = sodium.crypto_secretstream_xchacha20poly1305_ABYTES
const TAG_MESSAGE = sodium.crypto_secretstream_xchacha20poly1305_TAG_MESSAGE
const TAG_FINAL = sodium.crypto_secretstream_xchacha20poly1305_TAG_FINAL
const STATEBYTES = sodium.crypto_secretstream_xchacha20poly1305_STATEBYTES
const HEADERBYTES = sodium.crypto_secretstream_xchacha20poly1305_HEADERBYTES
const KEYBYTES = sodium.crypto_secretstream_xchacha20poly1305_KEYBYTES
const TAG_FINAL_BYTE = b4a.isBuffer(TAG_FINAL) ? TAG_FINAL[0] : TAG_FINAL
const EMPTY = b4a.alloc(0)
const TAG = b4a.alloc(1)
class Push {
constructor (key, state = b4a.allocUnsafeSlow(STATEBYTES), header = b4a.allocUnsafeSlow(HEADERBYTES)) {
if (!TAG_FINAL) throw new Error('JavaScript sodium version needs to support crypto_secretstream_xchacha20poly')
this.key = key
this.state = state
this.header = header
sodium.crypto_secretstream_xchacha20poly1305_init_push(this.state, this.header, this.key)
}
next (message, cipher = b4a.allocUnsafe(message.byteLength + ABYTES)) {
sodium.crypto_secretstream_xchacha20poly1305_push(this.state, cipher, message, null, TAG_MESSAGE)
return cipher
}
final (message = EMPTY, cipher = b4a.allocUnsafe(ABYTES)) {
sodium.crypto_secretstream_xchacha20poly1305_push(this.state, cipher, message, null, TAG_FINAL)
return cipher
}
}
class Pull {
constructor (key, state = b4a.allocUnsafeSlow(STATEBYTES)) {
if (!TAG_FINAL) throw new Error('JavaScript sodium version needs to support crypto_secretstream_xchacha20poly')
this.key = key
this.state = state
this.final = false
}
init (header) {
sodium.crypto_secretstream_xchacha20poly1305_init_pull(this.state, header, this.key)
}
next (cipher, message = b4a.allocUnsafe(cipher.byteLength - ABYTES)) {
sodium.crypto_secretstream_xchacha20poly1305_pull(this.state, message, TAG, cipher, null)
this.final = TAG[0] === TAG_FINAL_BYTE
return message
}
}
function keygen (buf = b4a.alloc(KEYBYTES)) {
sodium.crypto_secretstream_xchacha20poly1305_keygen(buf)
return buf
}
module.exports = {
keygen,
KEYBYTES,
ABYTES,
STATEBYTES,
HEADERBYTES,
Push,
Pull
}