66 lines
1.2 KiB
JavaScript
66 lines
1.2 KiB
JavaScript
/*!
|
|
* 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;
|
|
};
|