node-ebics-client/lib/MGF1.js

68 lines
1.3 KiB
JavaScript
Raw Permalink Normal View History

'use strict'
const crypto = require("crypto");
const BN = require('bn.js');
module.exports = class MGF1 {
constructor() {
this._len = 32;
}
/**
*
* @param {Buffer} seed
* @param {Number} masklen
*
* @returns Buffer
*/
static generate(seed, masklen) {
const mgf1 = new MGF1();
if ( masklen > 4294967296 * this._len) {
throw new Error('Mask too long');
}
const b = [];
for (let i = 0; i < mgf1._divceil(masklen, mgf1._len); i++) {
b[i] = crypto.createHash('sha256').update(Buffer.concat([seed, mgf1._i2osp(i, 4)])).digest();
}
return (Buffer.concat(b)).slice(0, masklen);
}
static 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];
}
return a;
}
_divceil(a, b) {
return ~~((a + b - 1) / b);
}
_i2osp(x, len) {
if ( x >= 256 ** len ) {
throw new Error('Integer too large');
}
return Buffer.from(this._rjust( (Buffer.from((new BN(x)).toArray('be', 4)).toString()).replace(/\x00/gi, ''), len, "\x00" ));
}
_rjust( string, width, padding ) {
padding = padding || " ";
padding = padding.substr( 0, 1 );
if ( string.length < width )
return padding.repeat( width - string.length ) + string;
else
return string;
}
}