// Generated by IcedCoffeeScript 1.7.1-f
(function() {
  var WordArray, X64Word, X64WordArray, buffer_to_ui8a, endian_reverse, ui8a_to_buffer, util;

  util = require('./util');

  buffer_to_ui8a = function(b) {
    var i, ret, _i, _ref;
    ret = new Uint8Array(b.length);
    for (i = _i = 0, _ref = b.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
      ret[i] = b.readUInt8(i);
    }
    return ret;
  };

  ui8a_to_buffer = function(v) {
    var i, ret, _i, _ref;
    ret = new Buffer(v.length);
    for (i = _i = 0, _ref = v.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
      ret.writeUInt8(v[i], i);
    }
    return ret;
  };

  endian_reverse = function(x) {
    return ((x >>> 24) & 0xff) | (((x >>> 16) & 0xff) << 8) | (((x >>> 8) & 0xff) << 16) | ((x & 0xff) << 24);
  };

  exports.WordArray = WordArray = (function() {
    function WordArray(words, sigBytes) {
      this.words = words || [];
      this.sigBytes = sigBytes != null ? sigBytes : this.words.length * 4;
    }

    WordArray.prototype.concat = function(wordArray) {
      var i, thatByte, thatSigBytes, thatWords, _i;
      thatWords = wordArray.words;
      thatSigBytes = wordArray.sigBytes;
      this.clamp();
      if (this.sigBytes % 4) {
        for (i = _i = 0; 0 <= thatSigBytes ? _i < thatSigBytes : _i > thatSigBytes; i = 0 <= thatSigBytes ? ++_i : --_i) {
          thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
          this.words[(this.sigBytes + i) >>> 2] |= thatByte << (24 - ((this.sigBytes + i) % 4) * 8);
        }
      } else {
        this.words = this.words.concat(thatWords);
      }
      this.sigBytes += thatSigBytes;
      return this;
    };

    WordArray.prototype.clamp = function() {
      this.words[this.sigBytes >>> 2] &= 0xffffffff << (32 - (this.sigBytes % 4) * 8);
      this.words.length = Math.ceil(this.sigBytes / 4);
      return this;
    };

    WordArray.prototype.clone = function() {
      return new WordArray(this.words.slice(0), this.sigBytes);
    };

    WordArray.prototype.to_buffer = function() {
      var ch, out, p, w, _i, _len, _ref;
      out = new Buffer(this.sigBytes);
      p = 0;
      _ref = this.words;
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        w = _ref[_i];
        if (!((this.sigBytes - p) >= 4)) {
          continue;
        }
        w = util.fixup_uint32(w);
        out.writeUInt32BE(w, p);
        p += 4;
      }
      while (p < this.sigBytes) {
        ch = (this.words[p >>> 2] >>> (24 - (p % 4) * 8)) & 0xff;
        out.writeUInt8(ch, p);
        p++;
      }
      return out;
    };

    WordArray.prototype.endian_reverse = function() {
      var i, w, _i, _len, _ref;
      _ref = this.words;
      for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
        w = _ref[i];
        this.words[i] = endian_reverse(w);
      }
      return this;
    };

    WordArray.prototype.split = function(n) {
      var i, out, sz;
      if (!(((this.sigBytes % 4) === 0) && ((this.words.length % n) === 0))) {
        throw new Error("bad key alignment");
      }
      sz = this.words.length / n;
      out = (function() {
        var _i, _ref, _results;
        _results = [];
        for (i = _i = 0, _ref = this.words.length; sz > 0 ? _i < _ref : _i > _ref; i = _i += sz) {
          _results.push(new WordArray(this.words.slice(i, i + sz)));
        }
        return _results;
      }).call(this);
      return out;
    };

    WordArray.prototype.to_utf8 = function() {
      return this.to_buffer().toString('utf8');
    };

    WordArray.prototype.to_hex = function() {
      return this.to_buffer().toString('hex');
    };

    WordArray.prototype.to_ui8a = function() {
      return buffer_to_ui8a(this.to_buffer());
    };

    WordArray.alloc = function(b) {
      if (Buffer.isBuffer(b)) {
        return WordArray.from_buffer(b);
      } else if ((typeof b === 'object') && (b instanceof WordArray)) {
        return b;
      } else if (typeof b === 'string') {
        return WordArray.from_hex(b);
      } else {
        return null;
      }
    };

    WordArray.from_buffer = function(b) {
      var ch, last, p, words;
      words = [];
      p = 0;
      while ((b.length - p) >= 4) {
        words.push(b.readUInt32BE(p));
        p += 4;
      }
      if (p < b.length) {
        last = 0;
        while (p < b.length) {
          ch = b.readUInt8(p);
          last |= ch << (24 - (p % 4) * 8);
          p++;
        }
        last = util.fixup_uint32(last);
        words.push(last);
      }
      return new WordArray(words, b.length);
    };

    WordArray.from_buffer_le = function(b) {
      var ch, last, p, words;
      words = [];
      p = 0;
      while ((b.length - p) >= 4) {
        words.push(b.readUInt32LE(p));
        p += 4;
      }
      if (p < b.length) {
        last = 0;
        while (p < b.length) {
          ch = b.readUInt8(p);
          last |= ch << ((p % 4) * 8);
          p++;
        }
        last = util.fixup_uint32(last);
        words.push(last);
      }
      return new WordArray(words, b.length);
    };

    WordArray.from_utf8 = function(s) {
      return WordArray.from_buffer(new Buffer(s, 'utf8'));
    };

    WordArray.from_utf8_le = function(s) {
      return WordArray.from_buffer_le(new Buffer(s, 'utf8'));
    };

    WordArray.from_hex = function(s) {
      return WordArray.from_buffer(new Buffer(s, 'hex'));
    };

    WordArray.from_hex_le = function(s) {
      return WordArray.from_buffer_le(new Buffer(s, 'hex'));
    };

    WordArray.from_ui8a = function(v) {
      return WordArray.from_buffer(ui8a_to_buffer(v));
    };

    WordArray.from_i32a = function(v) {
      return new WordArray(Array.apply([], v));
    };

    WordArray.prototype.equal = function(wa) {
      var i, ret, w, _i, _len, _ref;
      ret = true;
      if (wa.sigBytes !== this.sigBytes) {
        ret = false;
      } else {
        _ref = this.words;
        for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
          w = _ref[i];
          if (util.fixup_uint32(w) !== util.fixup_uint32(wa.words[i])) {
            ret = false;
          }
        }
      }
      return ret;
    };

    WordArray.prototype.xor = function(wa2, _arg) {
      var dst_offset, i, n_words, src_offset, tmp, _i;
      dst_offset = _arg.dst_offset, src_offset = _arg.src_offset, n_words = _arg.n_words;
      if (!dst_offset) {
        dst_offset = 0;
      }
      if (!src_offset) {
        src_offset = 0;
      }
      if (n_words == null) {
        n_words = wa2.words.length - src_offset;
      }
      if (this.words.length < dst_offset + n_words) {
        throw new Error("dest range exceeded (" + this.words.length + " < " + (dst_offset + n_words) + ")");
      }
      if (wa2.words.length < src_offset + n_words) {
        throw new Error("source range exceeded");
      }
      for (i = _i = 0; 0 <= n_words ? _i < n_words : _i > n_words; i = 0 <= n_words ? ++_i : --_i) {
        tmp = this.words[dst_offset + i] ^ wa2.words[src_offset + i];
        this.words[dst_offset + i] = util.fixup_uint32(tmp);
      }
      return this;
    };

    WordArray.prototype.truncate = function(n_bytes) {
      var n_words;
      if (!(n_bytes <= this.sigBytes)) {
        throw new Error("Cannot truncate: " + n_bytes + " > " + this.sigBytes);
      }
      n_words = Math.ceil(n_bytes / 4);
      return new WordArray(this.words.slice(0, n_words), n_bytes);
    };

    WordArray.prototype.unshift = function(n_words) {
      var ret;
      if (this.words.length >= n_words) {
        ret = this.words.splice(0, n_words);
        this.sigBytes -= n_words * 4;
        return new WordArray(ret);
      } else {
        return null;
      }
    };

    WordArray.prototype.is_scrubbed = function() {
      var w, _i, _len, _ref;
      _ref = this.words;
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        w = _ref[_i];
        if (w !== 0) {
          return false;
        }
      }
      return true;
    };

    WordArray.prototype.scrub = function() {
      return util.scrub_vec(this.words);
    };

    WordArray.prototype.cmp_ule = function(wa2) {
      return util.buffer_cmp_ule(this.to_buffer(), wa2.to_buffer());
    };

    WordArray.prototype.slice = function(low, hi) {
      var n, sb;
      n = this.words.length;
      if (!((low < hi) && (hi <= n))) {
        throw new Error("Bad WordArray slice [" + low + "," + hi + ")] when only " + n + " avail");
      }
      sb = (hi - low) * 4;
      if (hi === n) {
        sb -= n * 4 - this.sigBytes;
      }
      return new WordArray(this.words.slice(low, hi), sb);
    };

    return WordArray;

  })();

  exports.X64Word = X64Word = (function() {
    function X64Word(high, low) {
      this.high = high;
      this.low = low;
    }

    X64Word.prototype.clone = function() {
      return new X64Word(this.high, this.low);
    };

    return X64Word;

  })();

  exports.X64WordArray = X64WordArray = (function() {
    function X64WordArray(words, sigBytes) {
      this.sigBytes = sigBytes;
      this.words = words || [];
      if (!this.sigBytes) {
        this.sigBytes = this.words.length * 8;
      }
    }

    X64WordArray.prototype.toX32 = function() {
      var v, w, _i, _len, _ref;
      v = [];
      _ref = this.words;
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        w = _ref[_i];
        v.push(w.high);
        v.push(w.low);
      }
      return new WordArray(v, this.sigBytes);
    };

    X64WordArray.prototype.clone = function() {
      var w;
      return new X64WordArray((function() {
        var _i, _len, _ref, _results;
        _ref = this.words;
        _results = [];
        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
          w = _ref[_i];
          _results.push(w.clone());
        }
        return _results;
      }).call(this), this.sigBytes);
    };

    return X64WordArray;

  })();

  exports.buffer_to_ui8a = buffer_to_ui8a;

  exports.ui8a_to_buffer = ui8a_to_buffer;

  exports.endian_reverse = endian_reverse;

}).call(this);
