/*! * hkdf.js - hkdf for bcoin * Copyright (c) 2014-2017, Christopher Jeffrey (MIT License). * https://github.com/bcoin-org/bcoin */ 'use strict'; /** * @module crypto/hkdf */ const digest = require('./digest'); /** * Perform hkdf extraction. * @param {Buffer} ikm * @param {Buffer} key * @param {String} alg * @returns {Buffer} */ exports.extract = function extract(ikm, key, alg) { return digest.hmac(alg, ikm, key); }; /** * Perform hkdf expansion. * @param {Buffer} prk * @param {Buffer} info * @param {Number} len * @param {String} alg * @returns {Buffer} */ exports.expand = function expand(prk, info, len, alg) { const size = digest.hash(alg, Buffer.alloc(0)).length; const blocks = Math.ceil(len / size); if (blocks > 255) throw new Error('Too many blocks.'); const okm = Buffer.allocUnsafe(len); if (blocks === 0) return okm; const buf = Buffer.allocUnsafe(size + info.length + 1); // First round: info.copy(buf, size); buf[buf.length - 1] = 1; let out = digest.hmac(alg, buf.slice(size), prk); out.copy(okm, 0); for (let i = 1; i < blocks; i++) { out.copy(buf, 0); buf[buf.length - 1]++; out = digest.hmac(alg, buf, prk); out.copy(okm, i * size); } return okm; };