function bnModPow()

in public/amazon-cognito-identity.js [4029:4105]


function bnModPow(e, m, callback) {
	var i = e.bitLength(),
	    k,
	    r = nbv(1),
	    z = new Montgomery(m);
	if (i <= 0) return r;else if (i < 18) k = 1;else if (i < 48) k = 3;else if (i < 144) k = 4;else if (i < 768) k = 5;else k = 6;

	// precomputation
	var g = new Array(),
	    n = 3,
	    k1 = k - 1,
	    km = (1 << k) - 1;
	g[1] = z.convert(this);
	if (k > 1) {
		var g2 = nbi();
		z.sqrTo(g[1], g2);
		while (n <= km) {
			g[n] = nbi();
			z.mulTo(g2, g[n - 2], g[n]);
			n += 2;
		}
	}

	var j = e.t - 1,
	    w,
	    is1 = true,
	    r2 = nbi(),
	    t;
	i = nbits(e[j]) - 1;
	while (j >= 0) {
		if (i >= k1) w = e[j] >> i - k1 & km;else {
			w = (e[j] & (1 << i + 1) - 1) << k1 - i;
			if (j > 0) w |= e[j - 1] >> this.DB + i - k1;
		}

		n = k;
		while ((w & 1) == 0) {
			w >>= 1;
			--n;
		}
		if ((i -= n) < 0) {
			i += this.DB;
			--j;
		}
		if (is1) {
			// ret == 1, don't bother squaring or multiplying it
			g[w].copyTo(r);
			is1 = false;
		} else {
			while (n > 1) {
				z.sqrTo(r, r2);
				z.sqrTo(r2, r);
				n -= 2;
			}
			if (n > 0) z.sqrTo(r, r2);else {
				t = r;
				r = r2;
				r2 = t;
			}
			z.mulTo(r2, g[w], r);
		}

		while (j >= 0 && (e[j] & 1 << i) == 0) {
			z.sqrTo(r, r2);
			t = r;
			r = r2;
			r2 = t;
			if (--i < 0) {
				i = this.DB - 1;
				--j;
			}
		}
	}
	var result = z.revert(r);
	callback(null, result);
	return result;
}