// Generated by IcedCoffeeScript 1.7.1-c
(function() {
  var C, SHA512, SRF, bufeq_secure, buffer_to_ui8a, eme_random, emsa_pkcs1_decode, emsa_pkcs1_encode, hash_headers, iced, nbs, __iced_k, __iced_k_noop, _ref;

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

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

  C = require('./const').openpgp;

  nbs = require('./bn').nbs;

  _ref = require('./util'), buffer_to_ui8a = _ref.buffer_to_ui8a, bufeq_secure = _ref.bufeq_secure;

  SRF = require('./rand').SRF;

  hash_headers = {
    MD5: [0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10],
    SHA1: [0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14],
    SHA224: [0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1C],
    SHA256: [0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20],
    SHA384: [0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30],
    SHA512: [0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40]
  };

  exports.emsa_pkcs1_encode = emsa_pkcs1_encode = function(hashed_data, len, opts) {
    var buf, hasher, headers, i, n;
    if (opts == null) {
      opts = {};
    }
    hasher = opts.hasher || SHA512;
    headers = hash_headers[hasher.algname];
    n = len - headers.length - 3 - hasher.output_length;
    buf = Buffer.concat([
      new Buffer([0x00, 0x01]), new Buffer((function() {
        var _i, _results;
        _results = [];
        for (i = _i = 0; 0 <= n ? _i < n : _i > n; i = 0 <= n ? ++_i : --_i) {
          _results.push(0xff);
        }
        return _results;
      })()), new Buffer([0x00]), new Buffer(headers), hashed_data
    ]);
    return nbs(buffer_to_ui8a(buf), 256);
  };

  exports.emsa_pkcs1_decode = emsa_pkcs1_decode = function(v, hasher) {
    var err, h, header, i, ret;
    err = ret = null;
    i = 0;
    if (v.length < 2) {
      err = new Error("signature was way too short: < 2 bytes");
    } else {
      if (v.readUInt16BE(0) !== 0x0001) {
        err = new Error("Sig verify error: Didn't get two-byte header 0x00 0x01");
      } else {
        i = 2;
        while (i < v.length && (v.readUInt8(i) === 0xff)) {
          i++;
        }
        if (i >= v.length || v.readUInt8(i) !== 0) {
          err = new Error("Sig verify error: Missed the 0x0 separator");
        } else {
          i++;
          header = hash_headers[hasher.algname];
          if (!bufeq_secure(new Buffer(header), v.slice(i, header.length + i))) {
            err = new Error("Sig verify error: missing ASN header for " + hasher.algname);
          } else {
            i += header.length;
            h = v.slice(i);
            if (h.length !== hasher.output_length) {
              err = new Error("Sig verify error: trailing garbage in signature");
            } else {
              ret = h;
            }
          }
        }
      }
    }
    return [err, ret];
  };

  eme_random = function(n, cb) {
    var b, bytes, c, diff, i, ___iced_passed_deferral, __iced_deferrals, __iced_k;
    __iced_k = __iced_k_noop;
    ___iced_passed_deferral = iced.findDeferral(arguments);
    bytes = [];
    (function(_this) {
      return (function(__iced_k) {
        var _results, _while;
        _results = [];
        _while = function(__iced_k) {
          var _break, _continue, _next;
          _break = function() {
            return __iced_k(_results);
          };
          _continue = function() {
            return iced.trampoline(function() {
              return _while(__iced_k);
            });
          };
          _next = function(__iced_next_arg) {
            _results.push(__iced_next_arg);
            return _continue();
          };
          if (!(bytes.length < n)) {
            return _break();
          } else {
            diff = n - bytes.length;
            (function(__iced_k) {
              __iced_deferrals = new iced.Deferrals(__iced_k, {
                parent: ___iced_passed_deferral,
                filename: "/home/max/src/keybase/kbpgp/src/pad.iced"
              });
              SRF().random_bytes(diff, __iced_deferrals.defer({
                assign_fn: (function() {
                  return function() {
                    return b = arguments[0];
                  };
                })(),
                lineno: 77
              }));
              __iced_deferrals._fulfill();
            })(function() {
              var _i;
              for (i = _i = 0; 0 <= diff ? _i < diff : _i > diff; i = 0 <= diff ? ++_i : --_i) {
                c = b.readUInt8(i);
                if (c !== 0) {
                  bytes.push(c);
                }
              }
              return _next();
            });
          }
        };
        _while(__iced_k);
      });
    })(this)((function(_this) {
      return function() {
        return cb(new Buffer(bytes));
      };
    })(this));
  };

  exports.eme_pkcs1_encode = function(v, len, cb) {
    var PS, buf, err, n_randos, ret, ___iced_passed_deferral, __iced_deferrals, __iced_k;
    __iced_k = __iced_k_noop;
    ___iced_passed_deferral = iced.findDeferral(arguments);
    ret = err = null;
    (function(_this) {
      return (function(__iced_k) {
        if (v.length > len - 11) {
          return __iced_k(err = new Error("cannot encrypt message -- it's too long!"));
        } else {
          n_randos = len - 3 - v.length;
          (function(__iced_k) {
            __iced_deferrals = new iced.Deferrals(__iced_k, {
              parent: ___iced_passed_deferral,
              filename: "/home/max/src/keybase/kbpgp/src/pad.iced",
              funcname: "eme_pkcs1_encode"
            });
            eme_random(n_randos, __iced_deferrals.defer({
              assign_fn: (function() {
                return function() {
                  return PS = arguments[0];
                };
              })(),
              lineno: 93
            }));
            __iced_deferrals._fulfill();
          })(function() {
            buf = Buffer.concat([new Buffer([0x00, 0x02]), PS, new Buffer([0x00]), v]);
            return __iced_k(ret = nbs(buffer_to_ui8a(buf), 256));
          });
        }
      });
    })(this)((function(_this) {
      return function() {
        return cb(err, ret);
      };
    })(this));
  };

  exports.eme_pkcs1_decode = function(v) {
    var err, i, ret;
    err = ret = null;
    if (v.length < 12) {
      err = new Error("Ciphertext too short, needs to be >= 12 bytes");
    } else if (v.readUInt16BE(0) !== 0x0002) {
      err = new Error("Failed to find expected header: 0x00 0x02");
    } else {
      i = 2;
      while (i < v.length && (v.readUInt8(i) !== 0x0)) {
        i++;
      }
      if (i >= v.length) {
        err = new Error("didn't get 0x00 seperator octet");
      } else {
        i++;
        ret = v.slice(i);
      }
    }
    return [err, ret];
  };

  exports.ecc_pkcs5_pad_data = function(d) {
    var err, pad_len, ret, v;
    err = ret = null;
    pad_len = 40 - d.length;
    if (pad_len < 0) {
      err = new Error("Pad underrun");
    } else {
      v = (function() {
        var _i, _results;
        _results = [];
        for (_i = 0; 0 <= pad_len ? _i < pad_len : _i > pad_len; 0 <= pad_len ? _i++ : _i--) {
          _results.push(pad_len);
        }
        return _results;
      })();
      ret = Buffer.concat([d, new Buffer(v)]);
    }
    return [err, ret];
  };

  exports.ecc_pkcs5_unpad_data = function(buf, data_len) {
    var c, err, i, pad_len, _i, _ref1;
    err = null;
    pad_len = buf.length - data_len;
    if (pad_len < 0) {
      err = new Error("Pad length was < 0; pad underrun");
    } else if ((buf.length % 8) !== 0) {
      err = new Error("Padded data must be a multiple of 8 bytes long");
    } else {
      for (i = _i = data_len, _ref1 = buf.length; data_len <= _ref1 ? _i < _ref1 : _i > _ref1; i = data_len <= _ref1 ? ++_i : --_i) {
        if ((c = buf.readUInt8(i)) !== pad_len) {
          err = new Error("Got bad PKCS#5 pad character " + c + " at position " + i + "; wanted " + pad_len);
          break;
        }
      }
    }
    return err;
  };

}).call(this);
