// Generated by IcedCoffeeScript 1.7.1-f
(function() {
  var BlockCipher, BufferedBlockAlgorithm, Hasher, StreamCipher, WordArray, util,
    __hasProp = {}.hasOwnProperty,
    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };

  WordArray = require('./wordarray').WordArray;

  util = require('./util');

  BufferedBlockAlgorithm = (function() {
    BufferedBlockAlgorithm.prototype._minBufferSize = 0;

    function BufferedBlockAlgorithm() {
      this.reset();
    }

    BufferedBlockAlgorithm.prototype.reset = function() {
      this._data = new WordArray();
      return this._nDataBytes = 0;
    };

    BufferedBlockAlgorithm.prototype._append = function(data) {
      this._data.concat(data);
      return this._nDataBytes += data.sigBytes;
    };

    BufferedBlockAlgorithm.prototype._process = function(doFlush) {
      var blockSizeBytes, data, dataSigBytes, dataWords, nBlocksReady, nBytesReady, nWordsReady, offset, processedWords, _i, _ref;
      data = this._data;
      dataWords = data.words;
      dataSigBytes = data.sigBytes;
      blockSizeBytes = this.blockSize * 4;
      nBlocksReady = dataSigBytes / blockSizeBytes;
      if (doFlush) {
        nBlocksReady = Math.ceil(nBlocksReady);
      } else {
        nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0);
      }
      nWordsReady = nBlocksReady * this.blockSize;
      nBytesReady = Math.min(nWordsReady * 4, dataSigBytes);
      if (nWordsReady) {
        for (offset = _i = 0, _ref = this.blockSize; _ref > 0 ? _i < nWordsReady : _i > nWordsReady; offset = _i += _ref) {
          this._doProcessBlock(dataWords, offset);
        }
        processedWords = dataWords.splice(0, nWordsReady);
        data.sigBytes -= nBytesReady;
      }
      return new WordArray(processedWords, nBytesReady);
    };

    BufferedBlockAlgorithm.prototype.copy_to = function(out) {
      out._data = this._data.clone();
      return out._nDataBytes = this._nDataBytes;
    };

    BufferedBlockAlgorithm.prototype.clone = function() {
      var obj;
      obj = new BufferedBlockAlgorithm();
      this.copy_to(obj);
      return obj;
    };

    return BufferedBlockAlgorithm;

  })();

  Hasher = (function(_super) {
    __extends(Hasher, _super);

    function Hasher() {
      Hasher.__super__.constructor.call(this);
    }

    Hasher.prototype.reset = function() {
      Hasher.__super__.reset.call(this);
      this._doReset();
      return this;
    };

    Hasher.prototype.update = function(messageUpdate) {
      this._append(messageUpdate);
      this._process();
      return this;
    };

    Hasher.prototype.finalize = function(messageUpdate) {
      if (messageUpdate) {
        this._append(messageUpdate);
      }
      return this._doFinalize();
    };

    Hasher.prototype.bufhash = function(input) {
      var out, wa_in, wa_out;
      wa_in = WordArray.from_buffer(input);
      wa_out = this.finalize(wa_in);
      out = wa_out.to_buffer();
      wa_in.scrub();
      wa_out.scrub();
      return out;
    };

    return Hasher;

  })(BufferedBlockAlgorithm);

  exports.BlockCipher = BlockCipher = (function() {
    function BlockCipher(key) {}

    BlockCipher.prototype.encryptBlock = function(M, offset) {};

    return BlockCipher;

  })();

  StreamCipher = (function() {
    function StreamCipher() {}

    StreamCipher.prototype.encryptBlock = function(word_array, dst_offset) {
      var n_words, pad;
      if (dst_offset == null) {
        dst_offset = 0;
      }
      pad = this.get_pad();
      n_words = Math.min(word_array.words.length - dst_offset, this.bsiw);
      word_array.xor(pad, {
        dst_offset: dst_offset,
        n_words: n_words
      });
      pad.scrub();
      return this.bsiw;
    };

    StreamCipher.prototype.encrypt = function(word_array) {
      var i, _i, _ref, _ref1;
      for (i = _i = 0, _ref = word_array.words.length, _ref1 = this.bsiw; _ref1 > 0 ? _i < _ref : _i > _ref; i = _i += _ref1) {
        this.encryptBlock(word_array, i);
      }
      return word_array;
    };

    StreamCipher.prototype.bulk_encrypt = function(_arg, cb) {
      var async_args, input, progress_hook, slice_args, what;
      input = _arg.input, progress_hook = _arg.progress_hook, what = _arg.what;
      slice_args = {
        update: (function(_this) {
          return function(lo, hi) {
            var i, _i, _ref, _results;
            _results = [];
            for (i = _i = lo, _ref = _this.bsiw; _ref > 0 ? _i < hi : _i > hi; i = _i += _ref) {
              _results.push(_this.encryptBlock(input, i));
            }
            return _results;
          };
        })(this),
        finalize: function() {
          return input;
        },
        default_n: this.bsiw * 1024
      };
      async_args = {
        progress_hook: progress_hook,
        cb: cb,
        what: what
      };
      return util.bulk(input.sigBytes, slice_args, async_args);
    };

    return StreamCipher;

  })();

  exports.BlockCipher = BlockCipher;

  exports.Hasher = Hasher;

  exports.BufferedBlockAlgorithm = BufferedBlockAlgorithm;

  exports.StreamCipher = StreamCipher;

}).call(this);
