js-libp2p/src/pnet/crypto.js
Alex Potsides 1e869717ff fix: replace node buffers with uint8arrays (#730)
* fix: replace node buffers with uint8arrays

Upgrades all deps and replaces all use of node Buffers with Uint8Arrays

BREAKING CHANGES:

- All deps used by this module now use Uint8Arrays in place of node Buffers

* chore: browser fixes

* chore: remove .only

* chore: stringify uint8array before parsing

* chore: update interop suite

* chore: remove ts from build command

* chore: update deps

* fix: update records to use uint8array

* chore: fix lint

* chore: update deps

Co-authored-by: Jacob Heun <jacobheun@gmail.com>
2020-08-27 15:38:01 +02:00

81 lines
2.4 KiB
JavaScript

'use strict'
const debug = require('debug')
const Errors = require('./errors')
const xsalsa20 = require('xsalsa20')
const KEY_LENGTH = require('./key-generator').KEY_LENGTH
const uint8ArrayFromString = require('uint8arrays/from-string')
const uint8ArrayToString = require('uint8arrays/to-string')
const log = debug('libp2p:pnet')
log.trace = debug('libp2p:pnet:trace')
log.error = debug('libp2p:pnet:err')
/**
* Creates a stream iterable to encrypt messages in a private network
*
* @param {Uint8Array} nonce The nonce to use in encryption
* @param {Uint8Array} psk The private shared key to use in encryption
* @returns {*} a through iterable
*/
module.exports.createBoxStream = (nonce, psk) => {
const xor = xsalsa20(nonce, psk)
return (source) => (async function * () {
for await (const chunk of source) {
yield Uint8Array.from(xor.update(chunk.slice()))
}
})()
}
/**
* Creates a stream iterable to decrypt messages in a private network
*
* @param {Uint8Array} nonce The nonce of the remote peer
* @param {Uint8Array} psk The private shared key to use in decryption
* @returns {*} a through iterable
*/
module.exports.createUnboxStream = (nonce, psk) => {
return (source) => (async function * () {
const xor = xsalsa20(nonce, psk)
log.trace('Decryption enabled')
for await (const chunk of source) {
yield Uint8Array.from(xor.update(chunk.slice()))
}
})()
}
/**
* Decode the version 1 psk from the given Uint8Array
*
* @param {Uint8Array} pskBuffer
* @throws {INVALID_PSK}
* @returns {Object} The PSK metadata (tag, codecName, psk)
*/
module.exports.decodeV1PSK = (pskBuffer) => {
try {
// This should pull from multibase/multicodec to allow for
// more encoding flexibility. Ideally we'd consume the codecs
// from the buffer line by line to evaluate the next line
// programmatically instead of making assumptions about the
// encodings of each line.
const metadata = uint8ArrayToString(pskBuffer).split(/(?:\r\n|\r|\n)/g)
const pskTag = metadata.shift()
const codec = metadata.shift()
const psk = uint8ArrayFromString(metadata.shift(), 'base16')
if (psk.byteLength !== KEY_LENGTH) {
throw new Error(Errors.INVALID_PSK)
}
return {
tag: pskTag,
codecName: codec,
psk: psk
}
} catch (err) {
log.error(err)
throw new Error(Errors.INVALID_PSK)
}
}