bitcore/lib/expmt/cbc.js

102 lines
2.6 KiB
JavaScript
Raw Normal View History

var Random = require('../random');
2014-08-25 20:25:18 -07:00
// Cipher Block Chaining
2014-08-25 16:25:01 -07:00
// http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher-block_chaining_.28CBC.29
var CBC = function CBC(blockcipher, cipherkeybuf, ivbuf) {
2014-08-24 20:51:56 -07:00
if (!(this instanceof CBC))
return new CBC(blockcipher, cipherkeybuf, ivbuf);
2014-08-25 16:25:01 -07:00
this.blockcipher = blockcipher;
this.cipherkeybuf = cipherkeybuf;
2014-08-24 20:51:56 -07:00
this.ivbuf = ivbuf;
};
2014-08-25 16:25:01 -07:00
CBC.buf2blockbufs = function(buf, blocksize) {
var bytesize = blocksize / 8;
var blockbufs = [];
for (var i = 0; i <= buf.length / bytesize; i++) {
var blockbuf = buf.slice(i * bytesize, i * bytesize + bytesize);
if (blockbuf.length < blocksize)
blockbuf = CBC.pkcs7pad(blockbuf, blocksize);
blockbufs.push(blockbuf);
}
return blockbufs;
};
CBC.encrypt = function(messagebuf, ivbuf, blockcipher, cipherkeybuf) {
2014-08-25 16:25:01 -07:00
var blocksize = ivbuf.length * 8;
var blockbufs = CBC.buf2blockbufs(messagebuf, blocksize);
var encbufs = CBC.encryptblocks(blockbufs, ivbuf, blockcipher, cipherkeybuf);
2014-08-25 16:25:01 -07:00
var enc = Buffer.concat(encbufs);
return enc;
};
CBC.encryptblock = function(blockbuf, ivbuf, blockcipher, cipherkeybuf) {
2014-08-25 16:25:01 -07:00
var xorbuf = CBC.xorbufs(blockbuf, ivbuf);
var encbuf = blockcipher.encrypt(xorbuf, cipherkeybuf);
2014-08-25 16:25:01 -07:00
return encbuf;
};
2014-08-25 20:25:18 -07:00
CBC.decryptblock = function(encbuf, ivbuf, blockcipher, cipherkeybuf) {
var xorbuf = blockcipher.decrypt(encbuf, cipherkeybuf);
var blockbuf = CBC.xorbufs(xorbuf, ivbuf);
return blockbuf;
};
CBC.encryptblocks = function(blockbufs, ivbuf, blockcipher, cipherkeybuf) {
2014-08-25 16:25:01 -07:00
var encbufs = [];
for (var i = 0; i < blockbufs.length; i++) {
var blockbuf = blockbufs[i];
var encbuf = CBC.encryptblock(blockbuf, ivbuf, blockcipher, cipherkeybuf);
2014-08-25 16:25:01 -07:00
encbufs.push(encbuf);
ivbuf = encbuf;
}
return encbufs;
};
2014-08-25 20:25:18 -07:00
CBC.decryptblocks = function(encbufs, ivbuf, blockcipher, cipherkeybuf) {
var blockbufs = [];
for (var i = 0; i < encbufs.length; i++) {
var encbuf = encbufs[i];
var blockbuf = CBC.decryptblock(encbuf, ivbuf, blockcipher, cipherkeybuf);
blockbufs.push(blockbuf);
ivbuf = encbuf;
}
return encbufs;
};
CBC.pkcs7pad = function(buf, blocksize) {
var bytesize = blocksize / 8;
var padbytesize = bytesize - buf.length;
var pad = new Buffer(padbytesize);
pad.fill(padbytesize);
return Buffer.concat([buf, pad]);
};
2014-08-24 20:51:56 -07:00
CBC.xorbufs = function(buf1, buf2) {
if (buf1.length !== buf2.length)
throw new Error('bufs must have the same length');
var buf = new Buffer(buf1.length);
for (var i = 0; i < buf1.length; i++) {
buf[i] = buf1[i] ^ buf2[i];
}
return buf;
};
module.exports = CBC;