UNPKG

ara-crypto

Version:

Cryptographic functions used in Ara modules

196 lines (163 loc) 5.15 kB
const isBuffer = require('is-buffer') const { randomBytes } = require('./random-bytes') /* eslint-disable camelcase */ const { crypto_kx_SESSIONKEYBYTES, crypto_kx_PUBLICKEYBYTES, crypto_kx_SECRETKEYBYTES, crypto_kx_SEEDBYTES, crypto_kx_client_session_keys, crypto_kx_server_session_keys, crypto_kx_seed_keypair, } = require('./sodium') /** * Generates a key exchange key pair. * * @public * @param {?(Buffer)} [seed] * @returns {Object} * @throws TypeError */ function keyPair(seed) { const publicKey = Buffer.allocUnsafe(crypto_kx_PUBLICKEYBYTES) const secretKey = Buffer.allocUnsafe(crypto_kx_SECRETKEYBYTES) if (seed && false === isBuffer(seed)) { throw new TypeError('kx.keyPair: Expecting seed to be a buffer.') } if (undefined === seed) { /* eslint-disable-next-line no-param-reassign */ seed = randomBytes(crypto_kx_SEEDBYTES) } if (crypto_kx_SEEDBYTES !== seed.length) { throw new TypeError(`kx.keyPair: Invalid seed length: ${seed.length}`) } crypto_kx_seed_keypair(publicKey, secretKey, seed) return { publicKey, secretKey } } /** * Compute sender (tx) and receiver (rx) session keys for a client * based on a server's public key. * * @public * @param {Object} opts * @param {Buffer} opts.publicKey * @param {Buffer} opts.secretKey * @param {Object} opts.server * @param {Buffer} opts.server.publicKey * @return {Object} * @throws TypeError */ function client(opts) { if (!opts || 'object' !== typeof opts) { throw new TypeError('kx.client: Expecting object.') } if (!opts.publicKey || false === isBuffer(opts.publicKey)) { throw new TypeError('kx.client: Expecting buffer for public key.') } if (!opts.secretKey || false === isBuffer(opts.secretKey)) { throw new TypeError('kx.client: Expecting buffer for secret key.') } if (!opts.server || 'object' !== typeof opts.server) { throw new TypeError('kx.client: Expecting server object.') } if (!opts.server.publicKey || false === isBuffer(opts.server.publicKey)) { throw new TypeError('kx.client: Expecting buffer for server public key.') } if (crypto_kx_PUBLICKEYBYTES !== opts.publicKey.length) { const len = opts.publicKey.length throw new TypeError(`kx.client: Invalid public key length: ${len}`) } if (crypto_kx_SECRETKEYBYTES !== opts.secretKey.length) { const len = opts.secretKey.length throw new TypeError(`kx.client: Invalid secret key length: ${len}`) } if (crypto_kx_PUBLICKEYBYTES !== opts.server.publicKey.length) { const len = opts.server.publicKey.length throw new TypeError(`kx.client: Invalid server public key length: ${len}`) } // reader/receiver const receiver = Buffer.allocUnsafe(crypto_kx_SESSIONKEYBYTES) // writer/sender const sender = Buffer.allocUnsafe(crypto_kx_SESSIONKEYBYTES) // compute rx and tx session keys crypto_kx_client_session_keys( receiver, sender, opts.publicKey, opts.secretKey, opts.server.publicKey ) return { receiver, sender, // short hand rx: receiver, tx: sender, } } /** * Compute sender (tx) and receiver (rx) session keys for a server * based on a client's public key. * * @public * @param {Object} opts * @param {Buffer} opts.publicKey * @param {Buffer} opts.secretKey * @param {Object} opts.client * @param {Buffer} opts.client.publicKey * @return {Object} * @throws TypeError */ function server(opts) { if (!opts || 'object' !== typeof opts) { throw new TypeError('kx.server: Expecting object.') } if (!opts.publicKey || false === isBuffer(opts.publicKey)) { throw new TypeError('kx.server: Expecting buffer for public key.') } if (!opts.secretKey || false === isBuffer(opts.secretKey)) { throw new TypeError('kx.server: Expecting buffer for secret key.') } if (!opts.client || 'object' !== typeof opts.client) { throw new TypeError('kx.server: Expecting client object.') } if (!opts.client.publicKey || false === isBuffer(opts.client.publicKey)) { throw new TypeError('kx.server: Expecting buffer for client public key.') } if (crypto_kx_PUBLICKEYBYTES !== opts.publicKey.length) { const len = opts.publicKey.length throw new TypeError(`kx.server: Invalid public key length: ${len}`) } if (crypto_kx_SECRETKEYBYTES !== opts.secretKey.length) { const len = opts.secretKey.length throw new TypeError(`kx.server: Invalid secret key length: ${len}`) } if (crypto_kx_PUBLICKEYBYTES !== opts.client.publicKey.length) { const len = opts.client.publicKey.length throw new TypeError(`kx.server: Invalid client public key length: ${len}`) } // reader/receiver const receiver = Buffer.allocUnsafe(crypto_kx_SESSIONKEYBYTES) // writer/sender const sender = Buffer.allocUnsafe(crypto_kx_SESSIONKEYBYTES) // compute rx and tx session keys crypto_kx_server_session_keys( receiver, sender, opts.publicKey, opts.secretKey, opts.client.publicKey ) return { receiver, sender, // short hand rx: receiver, tx: sender, } } module.exports = { keyPair, client, server, }