// Generated by IcedCoffeeScript 1.7.1-f
(function() {
  var CombineBase, Concat, HMAC, SHA3, SHA512, WordArray, XOR, bulk_sign, _ref,
    __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; };

  _ref = require('./hmac'), HMAC = _ref.HMAC, bulk_sign = _ref.bulk_sign;

  SHA512 = require('./sha512').SHA512;

  SHA3 = require('./sha3').SHA3;

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

  CombineBase = (function() {
    function CombineBase() {
      this.hasherBlockSize = this.hashers[0].hasherBlockSize;
      this.hasherBlockSizeBytes = this.hasherBlockSize * 4;
      this.reset();
    }

    CombineBase.prototype.reset = function() {
      var h, _i, _len, _ref1;
      _ref1 = this.hashers;
      for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
        h = _ref1[_i];
        h.reset();
      }
      return this;
    };

    CombineBase.prototype.update = function(w) {
      var h, _i, _len, _ref1;
      _ref1 = this.hashers;
      for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
        h = _ref1[_i];
        h.update(w);
      }
      return this;
    };

    CombineBase.prototype.scrub = function() {
      var h, _i, _len, _ref1;
      _ref1 = this.hashers;
      for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
        h = _ref1[_i];
        h.scrub();
      }
      return this;
    };

    CombineBase.prototype.finalize = function(w) {
      var h, hashes, out, _i, _len, _ref1;
      hashes = (function() {
        var _i, _len, _ref1, _results;
        _ref1 = this.hashers;
        _results = [];
        for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
          h = _ref1[_i];
          _results.push(h.finalize(w));
        }
        return _results;
      }).call(this);
      out = hashes[0];
      _ref1 = hashes.slice(1);
      for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
        h = _ref1[_i];
        this._coalesce(out, h);
        h.scrub();
      }
      return out;
    };

    return CombineBase;

  })();

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

    function Concat(key, klasses) {
      var hm, i, klass, subkey, subkeys;
      if (klasses == null) {
        klasses = [SHA512, SHA3];
      }
      subkeys = key.split(klasses.length);
      this.hashers = (function() {
        var _i, _len, _results;
        _results = [];
        for (i = _i = 0, _len = klasses.length; _i < _len; i = ++_i) {
          klass = klasses[i];
          subkey = subkeys[i];
          hm = new HMAC(subkey, klass);
          subkey.scrub();
          _results.push(hm);
        }
        return _results;
      })();
      Concat.__super__.constructor.call(this);
    }

    Concat.get_output_size = function() {
      return SHA512.output_size + SHA3.output_size;
    };

    Concat.prototype._coalesce = function(out, h) {
      return out.concat(h);
    };

    Concat.prototype.get_output_size = function() {
      var h, tot, _i, _len, _ref1;
      tot = 0;
      _ref1 = this.hashers;
      for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
        h = _ref1[_i];
        tot += h.get_output_size();
      }
      return tot;
    };

    Concat.sign = function(_arg) {
      var input, key;
      key = _arg.key, input = _arg.input;
      return (new Concat(key)).finalize(input);
    };

    Concat.bulk_sign = function(args, cb) {
      args.klass = Concat;
      args.what = "HMAC-SHA512-SHA3";
      return bulk_sign(args, cb);
    };

    return Concat;

  })(CombineBase);

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

    function XOR(key, klasses) {
      var klass;
      if (klasses == null) {
        klasses = [SHA512, SHA3];
      }
      this.hashers = (function() {
        var _i, _len, _results;
        _results = [];
        for (_i = 0, _len = klasses.length; _i < _len; _i++) {
          klass = klasses[_i];
          _results.push(new HMAC(key, klass));
        }
        return _results;
      })();
      XOR.__super__.constructor.call(this);
    }

    XOR.prototype.reset = function() {
      var h, i, _i, _len, _ref1;
      XOR.__super__.reset.call(this);
      _ref1 = this.hashers;
      for (i = _i = 0, _len = _ref1.length; _i < _len; i = ++_i) {
        h = _ref1[i];
        h.update(new WordArray([i]));
      }
      return this;
    };

    XOR.get_output_size = function() {
      return Math.max(SHA512.output_size, SHA3.output_size);
    };

    XOR.prototype._coalesce = function(out, h) {
      return out.xor(h, {});
    };

    XOR.prototype.get_output_size = function() {
      var h;
      return Math.max.apply(Math, (function() {
        var _i, _len, _ref1, _results;
        _ref1 = this.hashers;
        _results = [];
        for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
          h = _ref1[_i];
          _results.push(h.get_output_size());
        }
        return _results;
      }).call(this));
    };

    XOR.sign = function(_arg) {
      var input, key;
      key = _arg.key, input = _arg.input;
      return (new XOR(key)).finalize(input);
    };

    XOR.bulk_sign = function(arg, cb) {
      arg.klass = XOR;
      arg.what = "HMAC-SHA512-XOR-SHA3";
      return bulk_sign(arg, cb);
    };

    return XOR;

  })(CombineBase);

  exports.Concat = Concat;

  exports.XOR = XOR;

}).call(this);
