| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 | 
							- 'use strict';
 
- var assert = require('minimalistic-assert');
 
- function Cipher(options) {
 
-   this.options = options;
 
-   this.type = this.options.type;
 
-   this.blockSize = 8;
 
-   this._init();
 
-   this.buffer = new Array(this.blockSize);
 
-   this.bufferOff = 0;
 
-   this.padding = options.padding !== false
 
- }
 
- module.exports = Cipher;
 
- Cipher.prototype._init = function _init() {
 
-   // Might be overrided
 
- };
 
- Cipher.prototype.update = function update(data) {
 
-   if (data.length === 0)
 
-     return [];
 
-   if (this.type === 'decrypt')
 
-     return this._updateDecrypt(data);
 
-   else
 
-     return this._updateEncrypt(data);
 
- };
 
- Cipher.prototype._buffer = function _buffer(data, off) {
 
-   // Append data to buffer
 
-   var min = Math.min(this.buffer.length - this.bufferOff, data.length - off);
 
-   for (var i = 0; i < min; i++)
 
-     this.buffer[this.bufferOff + i] = data[off + i];
 
-   this.bufferOff += min;
 
-   // Shift next
 
-   return min;
 
- };
 
- Cipher.prototype._flushBuffer = function _flushBuffer(out, off) {
 
-   this._update(this.buffer, 0, out, off);
 
-   this.bufferOff = 0;
 
-   return this.blockSize;
 
- };
 
- Cipher.prototype._updateEncrypt = function _updateEncrypt(data) {
 
-   var inputOff = 0;
 
-   var outputOff = 0;
 
-   var count = ((this.bufferOff + data.length) / this.blockSize) | 0;
 
-   var out = new Array(count * this.blockSize);
 
-   if (this.bufferOff !== 0) {
 
-     inputOff += this._buffer(data, inputOff);
 
-     if (this.bufferOff === this.buffer.length)
 
-       outputOff += this._flushBuffer(out, outputOff);
 
-   }
 
-   // Write blocks
 
-   var max = data.length - ((data.length - inputOff) % this.blockSize);
 
-   for (; inputOff < max; inputOff += this.blockSize) {
 
-     this._update(data, inputOff, out, outputOff);
 
-     outputOff += this.blockSize;
 
-   }
 
-   // Queue rest
 
-   for (; inputOff < data.length; inputOff++, this.bufferOff++)
 
-     this.buffer[this.bufferOff] = data[inputOff];
 
-   return out;
 
- };
 
- Cipher.prototype._updateDecrypt = function _updateDecrypt(data) {
 
-   var inputOff = 0;
 
-   var outputOff = 0;
 
-   var count = Math.ceil((this.bufferOff + data.length) / this.blockSize) - 1;
 
-   var out = new Array(count * this.blockSize);
 
-   // TODO(indutny): optimize it, this is far from optimal
 
-   for (; count > 0; count--) {
 
-     inputOff += this._buffer(data, inputOff);
 
-     outputOff += this._flushBuffer(out, outputOff);
 
-   }
 
-   // Buffer rest of the input
 
-   inputOff += this._buffer(data, inputOff);
 
-   return out;
 
- };
 
- Cipher.prototype.final = function final(buffer) {
 
-   var first;
 
-   if (buffer)
 
-     first = this.update(buffer);
 
-   var last;
 
-   if (this.type === 'encrypt')
 
-     last = this._finalEncrypt();
 
-   else
 
-     last = this._finalDecrypt();
 
-   if (first)
 
-     return first.concat(last);
 
-   else
 
-     return last;
 
- };
 
- Cipher.prototype._pad = function _pad(buffer, off) {
 
-   if (off === 0)
 
-     return false;
 
-   while (off < buffer.length)
 
-     buffer[off++] = 0;
 
-   return true;
 
- };
 
- Cipher.prototype._finalEncrypt = function _finalEncrypt() {
 
-   if (!this._pad(this.buffer, this.bufferOff))
 
-     return [];
 
-   var out = new Array(this.blockSize);
 
-   this._update(this.buffer, 0, out, 0);
 
-   return out;
 
- };
 
- Cipher.prototype._unpad = function _unpad(buffer) {
 
-   return buffer;
 
- };
 
- Cipher.prototype._finalDecrypt = function _finalDecrypt() {
 
-   assert.equal(this.bufferOff, this.blockSize, 'Not enough data to decrypt');
 
-   var out = new Array(this.blockSize);
 
-   this._flushBuffer(out, 0);
 
-   return this._unpad(out);
 
- };
 
 
  |