node-ebics-client/lib/crypto/MGF1.js

49 lines
1.2 KiB
JavaScript
Raw Normal View History

2018-06-01 13:16:43 +00:00
'use strict';
const crypto = require('crypto');
2019-11-06 15:16:56 +00:00
2019-11-07 08:27:08 +00:00
const BigNumber = require('./BigNumber.js');
2018-06-01 13:16:43 +00:00
const MFG_LEN = 32;
const divceil = (a, b) => ~~(((a + b) - 1) / b); // eslint-disable-line no-bitwise
2019-11-06 15:16:56 +00:00
const rjust = (string, width, padding = ' ') => {
2018-06-01 13:16:43 +00:00
padding = padding.substr(0, 1);
if (string.length < width)
return padding.repeat(width - string.length) + string;
return string;
};
const xor = (a, b) => {
if (a.length !== b.length)
throw new Error('Different length for a and b');
for (let i = 0; i < a.length; i++)
a[i] ^= b[i]; // eslint-disable-line no-bitwise
return a;
};
const i2osp = (x, len) => {
if (x >= 256 ** len)
throw new Error('Integer too large');
2019-11-06 15:16:56 +00:00
return Buffer.from(rjust(new BigNumber(x).toBEBuffer(4).toString().replace(/\x00/gi, ''), len, '\x00')); // eslint-disable-line no-control-regex
2018-06-01 13:16:43 +00:00
};
module.exports = {
generate(seed, masklen) {
if (masklen > 4294967296 * MFG_LEN)
throw new Error('Mask too long');
2018-06-01 13:16:43 +00:00
const b = [];
2018-06-01 13:16:43 +00:00
for (let i = 0; i < divceil(masklen, MFG_LEN); i++)
b[i] = crypto.createHash('sha256').update(Buffer.concat([seed, i2osp(i, 4)])).digest();
2018-06-01 13:16:43 +00:00
return (Buffer.concat(b)).slice(0, masklen);
},
xor,
rjust,
};