// Generated by IcedCoffeeScript 1.7.1-f
(function() {
  var AES, Base, Concat, Decryptor, SHA512, Salsa20, TwoFish, V, WordArray, ctr, decrypt, iced, make_esc, salsa20, __iced_k, __iced_k_noop, _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; };

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

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

  salsa20 = require('./salsa20');

  AES = require('./aes').AES;

  TwoFish = require('./twofish').TwoFish;

  ctr = require('./ctr');

  Concat = require('./combine').Concat;

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

  Salsa20 = require('./salsa20').Salsa20;

  _ref = require('./enc'), Base = _ref.Base, V = _ref.V;

  make_esc = require('iced-error').make_esc;

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

    function Decryptor(_arg) {
      var enc, key;
      key = _arg.key, enc = _arg.enc;
      Decryptor.__super__.constructor.call(this, {
        key: key
      });
      if (enc != null) {
        this.key = enc.key;
        this.derived_keys = enc.derived_keys;
      }
    }

    Decryptor.prototype.read_header = function(cb) {
      var err, wa;
      err = (wa = this.ct.unshift(2)) == null ? new Error("Ciphertext underrun in header") : (this.version = V[wa.words[1]]) == null ? new Error("bad header; couldn't find a good version (got " + wa.words[1] + ")") : wa.words[0] !== this.version.header[0] ? new Error("Bad header: unrecognized magic value") : null;
      return cb(err);
    };

    Decryptor.prototype.verify_sig = function(key, cb) {
      var computed, err, received, ___iced_passed_deferral, __iced_deferrals, __iced_k;
      __iced_k = __iced_k_noop;
      ___iced_passed_deferral = iced.findDeferral(arguments);
      (function(_this) {
        return (function(__iced_k) {
          if ((received = _this.ct.unshift(Concat.get_output_size() / 4)) == null) {
            return __iced_k(err = new Error("Ciphertext underrun in signature"));
          } else {
            (function(__iced_k) {
              __iced_deferrals = new iced.Deferrals(__iced_k, {
                parent: ___iced_passed_deferral,
                filename: "/home/max/src/keybase/triplesec/src/dec.iced",
                funcname: "Decryptor.verify_sig"
              });
              _this.sign({
                input: _this.ct,
                key: key,
                salt: _this.salt
              }, __iced_deferrals.defer({
                assign_fn: (function() {
                  return function() {
                    err = arguments[0];
                    return computed = arguments[1];
                  };
                })(),
                lineno: 63
              }));
              __iced_deferrals._fulfill();
            })(function() {
              return __iced_k(err = err != null ? err : received.equal(computed) ? null : new Error('Signature mismatch or bad decryption key'));
            });
          }
        });
      })(this)((function(_this) {
        return function() {
          return cb(err);
        };
      })(this));
    };

    Decryptor.prototype.unshift_iv = function(n_bytes, which, cb) {
      var err, iv;
      err = (iv = this.ct.unshift(n_bytes / 4)) != null ? null : new Error("Ciphertext underrun in " + which);
      return cb(err, iv);
    };

    Decryptor.prototype.read_salt = function(cb) {
      var err;
      err = (this.salt = this.ct.unshift(this.version.salt_size / 4)) == null ? new Error("Ciphertext underrrun in read_salt") : null;
      return cb(err);
    };

    Decryptor.prototype.generate_keys = function(_arg, cb) {
      var err, keys, progress_hook, ___iced_passed_deferral, __iced_deferrals, __iced_k;
      __iced_k = __iced_k_noop;
      ___iced_passed_deferral = iced.findDeferral(arguments);
      progress_hook = _arg.progress_hook;
      (function(_this) {
        return (function(__iced_k) {
          __iced_deferrals = new iced.Deferrals(__iced_k, {
            parent: ___iced_passed_deferral,
            filename: "/home/max/src/keybase/triplesec/src/dec.iced",
            funcname: "Decryptor.generate_keys"
          });
          _this.kdf({
            salt: _this.salt,
            progress_hook: progress_hook
          }, __iced_deferrals.defer({
            assign_fn: (function() {
              return function() {
                err = arguments[0];
                return keys = arguments[1];
              };
            })(),
            lineno: 114
          }));
          __iced_deferrals._fulfill();
        });
      })(this)((function(_this) {
        return function() {
          return cb(err, keys);
        };
      })(this));
    };

    Decryptor.prototype.run = function(_arg, cb) {
      var ct1, ct2, data, esc, iv, progress_hook, pt, ___iced_passed_deferral, __iced_deferrals, __iced_k;
      __iced_k = __iced_k_noop;
      ___iced_passed_deferral = iced.findDeferral(arguments);
      data = _arg.data, progress_hook = _arg.progress_hook;
      esc = make_esc(cb, "Decryptor::run");
      this.ct = WordArray.from_buffer(data);
      (function(_this) {
        return (function(__iced_k) {
          __iced_deferrals = new iced.Deferrals(__iced_k, {
            parent: ___iced_passed_deferral,
            filename: "/home/max/src/keybase/triplesec/src/dec.iced",
            funcname: "Decryptor.run"
          });
          _this.read_header(esc(__iced_deferrals.defer({
            lineno: 141
          })));
          __iced_deferrals._fulfill();
        });
      })(this)((function(_this) {
        return function() {
          (function(__iced_k) {
            __iced_deferrals = new iced.Deferrals(__iced_k, {
              parent: ___iced_passed_deferral,
              filename: "/home/max/src/keybase/triplesec/src/dec.iced",
              funcname: "Decryptor.run"
            });
            _this.read_salt(esc(__iced_deferrals.defer({
              lineno: 142
            })));
            __iced_deferrals._fulfill();
          })(function() {
            (function(__iced_k) {
              __iced_deferrals = new iced.Deferrals(__iced_k, {
                parent: ___iced_passed_deferral,
                filename: "/home/max/src/keybase/triplesec/src/dec.iced",
                funcname: "Decryptor.run"
              });
              _this.generate_keys({
                progress_hook: progress_hook
              }, esc(__iced_deferrals.defer({
                assign_fn: (function(__slot_1) {
                  return function() {
                    return __slot_1.keys = arguments[0];
                  };
                })(_this),
                lineno: 143
              })));
              __iced_deferrals._fulfill();
            })(function() {
              (function(__iced_k) {
                __iced_deferrals = new iced.Deferrals(__iced_k, {
                  parent: ___iced_passed_deferral,
                  filename: "/home/max/src/keybase/triplesec/src/dec.iced",
                  funcname: "Decryptor.run"
                });
                _this.verify_sig(_this.keys.hmac, esc(__iced_deferrals.defer({
                  lineno: 144
                })));
                __iced_deferrals._fulfill();
              })(function() {
                (function(__iced_k) {
                  __iced_deferrals = new iced.Deferrals(__iced_k, {
                    parent: ___iced_passed_deferral,
                    filename: "/home/max/src/keybase/triplesec/src/dec.iced",
                    funcname: "Decryptor.run"
                  });
                  _this.unshift_iv(AES.ivSize, "AES", esc(__iced_deferrals.defer({
                    assign_fn: (function() {
                      return function() {
                        return iv = arguments[0];
                      };
                    })(),
                    lineno: 145
                  })));
                  __iced_deferrals._fulfill();
                })(function() {
                  (function(__iced_k) {
                    __iced_deferrals = new iced.Deferrals(__iced_k, {
                      parent: ___iced_passed_deferral,
                      filename: "/home/max/src/keybase/triplesec/src/dec.iced",
                      funcname: "Decryptor.run"
                    });
                    _this.run_aes({
                      iv: iv,
                      input: _this.ct,
                      key: _this.keys.aes,
                      progress_hook: progress_hook
                    }, esc(__iced_deferrals.defer({
                      assign_fn: (function() {
                        return function() {
                          return ct2 = arguments[0];
                        };
                      })(),
                      lineno: 146
                    })));
                    __iced_deferrals._fulfill();
                  })(function() {
                    (function(__iced_k) {
                      __iced_deferrals = new iced.Deferrals(__iced_k, {
                        parent: ___iced_passed_deferral,
                        filename: "/home/max/src/keybase/triplesec/src/dec.iced",
                        funcname: "Decryptor.run"
                      });
                      _this.unshift_iv(TwoFish.ivSize, "2fish", esc(__iced_deferrals.defer({
                        assign_fn: (function() {
                          return function() {
                            return iv = arguments[0];
                          };
                        })(),
                        lineno: 147
                      })));
                      __iced_deferrals._fulfill();
                    })(function() {
                      (function(__iced_k) {
                        __iced_deferrals = new iced.Deferrals(__iced_k, {
                          parent: ___iced_passed_deferral,
                          filename: "/home/max/src/keybase/triplesec/src/dec.iced",
                          funcname: "Decryptor.run"
                        });
                        _this.run_twofish({
                          iv: iv,
                          input: _this.ct,
                          key: _this.keys.twofish,
                          progress_hook: progress_hook
                        }, esc(__iced_deferrals.defer({
                          assign_fn: (function() {
                            return function() {
                              return ct1 = arguments[0];
                            };
                          })(),
                          lineno: 148
                        })));
                        __iced_deferrals._fulfill();
                      })(function() {
                        (function(__iced_k) {
                          __iced_deferrals = new iced.Deferrals(__iced_k, {
                            parent: ___iced_passed_deferral,
                            filename: "/home/max/src/keybase/triplesec/src/dec.iced",
                            funcname: "Decryptor.run"
                          });
                          _this.unshift_iv(Salsa20.ivSize, "Salsa", esc(__iced_deferrals.defer({
                            assign_fn: (function() {
                              return function() {
                                return iv = arguments[0];
                              };
                            })(),
                            lineno: 149
                          })));
                          __iced_deferrals._fulfill();
                        })(function() {
                          (function(__iced_k) {
                            __iced_deferrals = new iced.Deferrals(__iced_k, {
                              parent: ___iced_passed_deferral,
                              filename: "/home/max/src/keybase/triplesec/src/dec.iced",
                              funcname: "Decryptor.run"
                            });
                            _this.run_salsa20({
                              iv: iv,
                              input: _this.ct,
                              key: _this.keys.salsa20,
                              output_iv: false,
                              progress_hook: progress_hook
                            }, esc(__iced_deferrals.defer({
                              assign_fn: (function() {
                                return function() {
                                  return pt = arguments[0];
                                };
                              })(),
                              lineno: 150
                            })));
                            __iced_deferrals._fulfill();
                          })(function() {
                            return cb(null, pt.to_buffer());
                          });
                        });
                      });
                    });
                  });
                });
              });
            });
          });
        };
      })(this));
    };

    return Decryptor;

  })(Base);

  decrypt = function(_arg, cb) {
    var data, dec, err, key, progress_hook, pt, ___iced_passed_deferral, __iced_deferrals, __iced_k;
    __iced_k = __iced_k_noop;
    ___iced_passed_deferral = iced.findDeferral(arguments);
    key = _arg.key, data = _arg.data, progress_hook = _arg.progress_hook;
    dec = new Decryptor({
      key: key
    });
    (function(_this) {
      return (function(__iced_k) {
        __iced_deferrals = new iced.Deferrals(__iced_k, {
          parent: ___iced_passed_deferral,
          filename: "/home/max/src/keybase/triplesec/src/dec.iced"
        });
        dec.run({
          data: data,
          progress_hook: progress_hook
        }, __iced_deferrals.defer({
          assign_fn: (function() {
            return function() {
              err = arguments[0];
              return pt = arguments[1];
            };
          })(),
          lineno: 168
        }));
        __iced_deferrals._fulfill();
      });
    })(this)((function(_this) {
      return function() {
        dec.scrub();
        return cb(err, pt);
      };
    })(this));
  };

  exports.Decryptor = Decryptor;

  exports.decrypt = decrypt;

}).call(this);
