// Generated by IcedCoffeeScript 1.7.1-c
(function() {
  var BigInteger, Lock, MRF, MediumRandomFountain, SRF, StrongRandomFountain, WordArray, iced, native_rng, prng, __iced_k, __iced_k_noop, _mrf, _ref, _srf;

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

  BigInteger = require('bn').BigInteger;

  _ref = require('triplesec'), WordArray = _ref.WordArray, prng = _ref.prng;

  native_rng = prng.native_rng;

  Lock = require('./lock').Lock;

  MediumRandomFountain = (function() {
    function MediumRandomFountain() {}

    MediumRandomFountain.prototype.nextBytes = function(v) {
      var b, c, i, _i, _len, _results;
      b = native_rng(v.length);
      _results = [];
      for (i = _i = 0, _len = b.length; _i < _len; i = ++_i) {
        c = b[i];
        _results.push(v[i] = c);
      }
      return _results;
    };

    MediumRandomFountain.prototype.random_word = function() {
      return native_rng(4).readUInt32BE(0);
    };

    MediumRandomFountain.prototype.random_zn = function(n) {
      var i;
      while (true) {
        i = BigInteger.random_nbit(n.bitLength(), this);
        if (i.compareTo(BigInteger.ONE) > 0 && i.compareTo(n) < 0) {
          return i;
        }
      }
    };

    return MediumRandomFountain;

  })();

  _mrf = null;

  MRF = function() {
    if (_mrf == null) {
      _mrf = new MediumRandomFountain();
    }
    return _mrf;
  };

  StrongRandomFountain = (function() {
    function StrongRandomFountain() {
      this.buf = null;
      this.lock = new Lock();
    }

    StrongRandomFountain.prototype.random_word = function(cb) {
      var wa, ___iced_passed_deferral, __iced_deferrals, __iced_k;
      __iced_k = __iced_k_noop;
      ___iced_passed_deferral = iced.findDeferral(arguments);
      (function(_this) {
        return (function(__iced_k) {
          __iced_deferrals = new iced.Deferrals(__iced_k, {
            parent: ___iced_passed_deferral,
            filename: "/home/max/src/keybase/kbpgp/src/rand.iced",
            funcname: "StrongRandomFountain.random_word"
          });
          prng.generate(4, __iced_deferrals.defer({
            assign_fn: (function() {
              return function() {
                return wa = arguments[0];
              };
            })(),
            lineno: 49
          }));
          __iced_deferrals._fulfill();
        });
      })(this)((function(_this) {
        return function() {
          return cb(wa.to_buffer().readUInt32BE(0));
        };
      })(this));
    };

    StrongRandomFountain.prototype.random_double = function(cb) {
      var wa, ___iced_passed_deferral, __iced_deferrals, __iced_k;
      __iced_k = __iced_k_noop;
      ___iced_passed_deferral = iced.findDeferral(arguments);
      (function(_this) {
        return (function(__iced_k) {
          __iced_deferrals = new iced.Deferrals(__iced_k, {
            parent: ___iced_passed_deferral,
            filename: "/home/max/src/keybase/kbpgp/src/rand.iced",
            funcname: "StrongRandomFountain.random_double"
          });
          prng.generate(8, __iced_deferrals.defer({
            assign_fn: (function() {
              return function() {
                return wa = arguments[0];
              };
            })(),
            lineno: 55
          }));
          __iced_deferrals._fulfill();
        });
      })(this)((function(_this) {
        return function() {
          return cb(wa.to_buffer().readDoubleBE(0));
        };
      })(this));
    };

    StrongRandomFountain.prototype.rand_0_1 = function(cb) {
      var ret, w1, w2, ___iced_passed_deferral, __iced_deferrals, __iced_k;
      __iced_k = __iced_k_noop;
      ___iced_passed_deferral = iced.findDeferral(arguments);
      (function(_this) {
        return (function(__iced_k) {
          __iced_deferrals = new iced.Deferrals(__iced_k, {
            parent: ___iced_passed_deferral,
            filename: "/home/max/src/keybase/kbpgp/src/rand.iced",
            funcname: "StrongRandomFountain.rand_0_1"
          });
          _this.random_word(__iced_deferrals.defer({
            assign_fn: (function() {
              return function() {
                return w1 = arguments[0];
              };
            })(),
            lineno: 61
          }));
          __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/kbpgp/src/rand.iced",
              funcname: "StrongRandomFountain.rand_0_1"
            });
            _this.random_word(__iced_deferrals.defer({
              assign_fn: (function() {
                return function() {
                  return w2 = arguments[0];
                };
              })(),
              lineno: 62
            }));
            __iced_deferrals._fulfill();
          })(function() {
            ret = w1 * Math.pow(2, -32) + w2 * Math.pow(2, -64);
            return cb(ret);
          });
        };
      })(this));
    };

    StrongRandomFountain.prototype.random_zn = function(n, cb) {
      var go, ret, ___iced_passed_deferral, __iced_deferrals, __iced_k;
      __iced_k = __iced_k_noop;
      ___iced_passed_deferral = iced.findDeferral(arguments);
      go = true;
      ret = false;
      (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 (!go) {
              return _break();
            } else {
              (function(__iced_k) {
                __iced_deferrals = new iced.Deferrals(__iced_k, {
                  parent: ___iced_passed_deferral,
                  filename: "/home/max/src/keybase/kbpgp/src/rand.iced",
                  funcname: "StrongRandomFountain.random_zn"
                });
                _this.random_nbit(n.bitLength(), __iced_deferrals.defer({
                  assign_fn: (function() {
                    return function() {
                      return ret = arguments[0];
                    };
                  })(),
                  lineno: 72
                }));
                __iced_deferrals._fulfill();
              })(function() {
                return _next(go = (ret.compareTo(BigInteger.ONE) <= 0) || (ret.compareTo(n) >= 0));
              });
            }
          };
          _while(__iced_k);
        });
      })(this)((function(_this) {
        return function() {
          return cb(ret);
        };
      })(this));
    };

    StrongRandomFountain.prototype.nextBytes = function(v) {
      var i, _i, _ref1, _results;
      _results = [];
      for (i = _i = 0, _ref1 = v.length; 0 <= _ref1 ? _i < _ref1 : _i > _ref1; i = 0 <= _ref1 ? ++_i : --_i) {
        _results.push(v[i] = this.buf[i]);
      }
      return _results;
    };

    StrongRandomFountain.prototype.random_word_array = function(nbytes, cb) {
      var b, d, max_pull, n, ret, ___iced_passed_deferral, __iced_deferrals, __iced_k;
      __iced_k = __iced_k_noop;
      ___iced_passed_deferral = iced.findDeferral(arguments);
      ret = new WordArray();
      max_pull = 512;
      (function(_this) {
        return (function(__iced_k) {
          __iced_deferrals = new iced.Deferrals(__iced_k, {
            parent: ___iced_passed_deferral,
            filename: "/home/max/src/keybase/kbpgp/src/rand.iced",
            funcname: "StrongRandomFountain.random_word_array"
          });
          _this.lock.acquire(__iced_deferrals.defer({
            lineno: 88
          }));
          __iced_deferrals._fulfill();
        });
      })(this)((function(_this) {
        return function() {
          (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 (!((d = nbytes - ret.sigBytes) > 0)) {
                return _break();
              } else {
                n = Math.min(max_pull, d);
                (function(__iced_k) {
                  __iced_deferrals = new iced.Deferrals(__iced_k, {
                    parent: ___iced_passed_deferral,
                    filename: "/home/max/src/keybase/kbpgp/src/rand.iced",
                    funcname: "StrongRandomFountain.random_word_array"
                  });
                  prng.generate(n, __iced_deferrals.defer({
                    assign_fn: (function() {
                      return function() {
                        return b = arguments[0];
                      };
                    })(),
                    lineno: 91
                  }));
                  __iced_deferrals._fulfill();
                })(function() {
                  return _next(ret = ret.concat(b));
                });
              }
            };
            _while(__iced_k);
          })(function() {
            _this.lock.release();
            return cb(ret);
          });
        };
      })(this));
    };

    StrongRandomFountain.prototype.random_bytes = function(nbytes, cb) {
      var tmp, ___iced_passed_deferral, __iced_deferrals, __iced_k;
      __iced_k = __iced_k_noop;
      ___iced_passed_deferral = iced.findDeferral(arguments);
      (function(_this) {
        return (function(__iced_k) {
          __iced_deferrals = new iced.Deferrals(__iced_k, {
            parent: ___iced_passed_deferral,
            filename: "/home/max/src/keybase/kbpgp/src/rand.iced",
            funcname: "StrongRandomFountain.random_bytes"
          });
          _this.random_word_array(nbytes, __iced_deferrals.defer({
            assign_fn: (function() {
              return function() {
                return tmp = arguments[0];
              };
            })(),
            lineno: 99
          }));
          __iced_deferrals._fulfill();
        });
      })(this)((function(_this) {
        return function() {
          return cb(tmp.to_buffer());
        };
      })(this));
    };

    StrongRandomFountain.prototype.random_nbit = function(nbits, cb) {
      var nbytes, ret, tmp, ___iced_passed_deferral, __iced_deferrals, __iced_k;
      __iced_k = __iced_k_noop;
      ___iced_passed_deferral = iced.findDeferral(arguments);
      nbytes = (nbits >> 3) + 1;
      (function(_this) {
        return (function(__iced_k) {
          __iced_deferrals = new iced.Deferrals(__iced_k, {
            parent: ___iced_passed_deferral,
            filename: "/home/max/src/keybase/kbpgp/src/rand.iced",
            funcname: "StrongRandomFountain.random_nbit"
          });
          _this.random_bytes(nbytes, __iced_deferrals.defer({
            assign_fn: (function() {
              return function() {
                return tmp = arguments[0];
              };
            })(),
            lineno: 106
          }));
          __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/kbpgp/src/rand.iced",
              funcname: "StrongRandomFountain.random_nbit"
            });
            _this.lock.acquire(__iced_deferrals.defer({
              lineno: 107
            }));
            __iced_deferrals._fulfill();
          })(function() {
            _this.buf = tmp;
            ret = BigInteger.random_nbit(nbits, _this);
            _this.lock.release();
            return cb(ret);
          });
        };
      })(this));
    };

    return StrongRandomFountain;

  })();

  _srf = null;

  SRF = function() {
    if (_srf == null) {
      _srf = new StrongRandomFountain();
    }
    return _srf;
  };

  exports.MRF = MRF;

  exports.SRF = SRF;

}).call(this);
