// Generated by IcedCoffeeScript 1.7.1-f
(function() {
  var HMAC, HMAC_SHA256, SHA256, SHA512, bulk_sign, iced, sign, util, __iced_k, __iced_k_noop,
    __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; };

  iced = require('iced-runtime');
  __iced_k = __iced_k_noop = function() {};

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

  SHA256 = require('./sha256').SHA256;

  util = require('./util');

  HMAC = (function() {
    HMAC.outputSize = 512 / 8;

    HMAC.prototype.outputSize = HMAC.outputSize;

    function HMAC(key, klass) {
      var i, _i, _ref;
      if (klass == null) {
        klass = SHA512;
      }
      this.key = key.clone();
      this.hasher = new klass();
      this.hasherBlockSize = this.hasher.blockSize;
      this.hasherBlockSizeBytes = this.hasherBlockSize * 4;
      if (this.key.sigBytes > this.hasherBlockSizeBytes) {
        this.key = this.hasher.finalize(this.key);
      }
      this.key.clamp();
      this._oKey = this.key.clone();
      this._iKey = this.key.clone();
      for (i = _i = 0, _ref = this.hasherBlockSize; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
        this._oKey.words[i] ^= 0x5c5c5c5c;
        this._iKey.words[i] ^= 0x36363636;
      }
      this._oKey.sigBytes = this._iKey.sigBytes = this.hasherBlockSizeBytes;
      this.reset();
    }

    HMAC.prototype.get_output_size = function() {
      return this.hasher.output_size;
    };

    HMAC.prototype.reset = function() {
      return this.hasher.reset().update(this._iKey);
    };

    HMAC.prototype.update = function(wa) {
      this.hasher.update(wa);
      return this;
    };

    HMAC.prototype.finalize = function(wa) {
      var innerHash, innerHash2, out;
      innerHash = this.hasher.finalize(wa);
      this.hasher.reset();
      innerHash2 = this._oKey.clone().concat(innerHash);
      out = this.hasher.finalize(innerHash2);
      innerHash.scrub();
      innerHash2.scrub();
      return out;
    };

    HMAC.prototype.scrub = function() {
      this.key.scrub();
      this._iKey.scrub();
      return this._oKey.scrub();
    };

    return HMAC;

  })();

  sign = function(_arg) {
    var eng, hash_class, input, key, out;
    key = _arg.key, input = _arg.input, hash_class = _arg.hash_class;
    eng = new HMAC(key, hash_class);
    out = eng.finalize(input.clamp());
    eng.scrub();
    return out;
  };

  bulk_sign = function(_arg, cb) {
    var eng, input, key, klass, progress_hook, res, slice_args, what, ___iced_passed_deferral, __iced_deferrals, __iced_k;
    __iced_k = __iced_k_noop;
    ___iced_passed_deferral = iced.findDeferral(arguments);
    key = _arg.key, input = _arg.input, progress_hook = _arg.progress_hook, klass = _arg.klass, what = _arg.what;
    klass || (klass = HMAC);
    what || (what = "hmac_sha512");
    eng = new klass(key);
    input.clamp();
    slice_args = {
      update: function(lo, hi) {
        return eng.update(input.slice(lo, hi));
      },
      finalize: function() {
        return eng.finalize();
      },
      default_n: eng.hasherBlockSize * 1000
    };
    (function(_this) {
      return (function(__iced_k) {
        __iced_deferrals = new iced.Deferrals(__iced_k, {
          parent: ___iced_passed_deferral,
          filename: "/home/max/src/keybase/triplesec/src/hmac.iced"
        });
        util.bulk(input.sigBytes, slice_args, {
          what: what,
          progress_hook: progress_hook,
          cb: __iced_deferrals.defer({
            assign_fn: (function() {
              return function() {
                return res = arguments[0];
              };
            })(),
            lineno: 137
          })
        });
        __iced_deferrals._fulfill();
      });
    })(this)((function(_this) {
      return function() {
        eng.scrub();
        return cb(res);
      };
    })(this));
  };

  exports.HMAC_SHA256 = HMAC_SHA256 = (function(_super) {
    __extends(HMAC_SHA256, _super);

    function HMAC_SHA256(key) {
      HMAC_SHA256.__super__.constructor.call(this, key, SHA256);
    }

    return HMAC_SHA256;

  })(HMAC);

  exports.HMAC = HMAC;

  exports.sign = sign;

  exports.bulk_sign = bulk_sign;

}).call(this);
