Last active
August 29, 2015 14:23
-
-
Save BrendanBenshoof/c8bfbe19cdf93aae02eb to your computer and use it in GitHub Desktop.
Test p2p chat
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html/> | |
<head/> | |
</head> | |
<body/> | |
<h1>UrDHT based simple chatroom</h1> | |
channel: <input type="text" id="channel" value="testnet"/> | |
<br> | |
username: <input type="text" id="uname" value="Username"/> | |
<br> | |
<textarea id="output" readonly width="100%"> | |
</textarea> | |
<br> | |
<input type="text" id="input" value="write something"/><input type="button" id="button" value="say it"/> | |
<script/> | |
/*! | |
* Basic JavaScript BN library - subset useful for RSA encryption. v1.3 | |
* | |
* Copyright (c) 2005 Tom Wu | |
* All Rights Reserved. | |
* BSD License | |
* http://www-cs-students.stanford.edu/~tjw/jsbn/LICENSE | |
* | |
* Copyright Stephan Thomas | |
* Copyright bitaddress.org | |
*/ | |
(function () { | |
// (public) Constructor function of Global BigInteger object | |
var BigInteger = window.BigInteger = function BigInteger(a, b, c) { | |
if (a != null) | |
if ("number" == typeof a) this.fromNumber(a, b, c); | |
else if (b == null && "string" != typeof a) this.fromString(a, 256); | |
else this.fromString(a, b); | |
}; | |
// Bits per digit | |
var dbits; | |
// JavaScript engine analysis | |
var canary = 0xdeadbeefcafe; | |
var j_lm = ((canary & 0xffffff) == 0xefcafe); | |
// return new, unset BigInteger | |
function nbi() { return new BigInteger(null); } | |
// am: Compute w_j += (x*this_i), propagate carries, | |
// c is initial carry, returns final carry. | |
// c < 3*dvalue, x < 2*dvalue, this_i < dvalue | |
// We need to select the fastest one that works in this environment. | |
// am1: use a single mult and divide to get the high bits, | |
// max digit bits should be 26 because | |
// max internal value = 2*dvalue^2-2*dvalue (< 2^53) | |
function am1(i, x, w, j, c, n) { | |
while (--n >= 0) { | |
var v = x * this[i++] + w[j] + c; | |
c = Math.floor(v / 0x4000000); | |
w[j++] = v & 0x3ffffff; | |
} | |
return c; | |
} | |
// am2 avoids a big mult-and-extract completely. | |
// Max digit bits should be <= 30 because we do bitwise ops | |
// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) | |
function am2(i, x, w, j, c, n) { | |
var xl = x & 0x7fff, xh = x >> 15; | |
while (--n >= 0) { | |
var l = this[i] & 0x7fff; | |
var h = this[i++] >> 15; | |
var m = xh * l + h * xl; | |
l = xl * l + ((m & 0x7fff) << 15) + w[j] + (c & 0x3fffffff); | |
c = (l >>> 30) + (m >>> 15) + xh * h + (c >>> 30); | |
w[j++] = l & 0x3fffffff; | |
} | |
return c; | |
} | |
// Alternately, set max digit bits to 28 since some | |
// browsers slow down when dealing with 32-bit numbers. | |
function am3(i, x, w, j, c, n) { | |
var xl = x & 0x3fff, xh = x >> 14; | |
while (--n >= 0) { | |
var l = this[i] & 0x3fff; | |
var h = this[i++] >> 14; | |
var m = xh * l + h * xl; | |
l = xl * l + ((m & 0x3fff) << 14) + w[j] + c; | |
c = (l >> 28) + (m >> 14) + xh * h; | |
w[j++] = l & 0xfffffff; | |
} | |
return c; | |
} | |
if (j_lm && (navigator.appName == "Microsoft Internet Explorer")) { | |
BigInteger.prototype.am = am2; | |
dbits = 30; | |
} | |
else if (j_lm && (navigator.appName != "Netscape")) { | |
BigInteger.prototype.am = am1; | |
dbits = 26; | |
} | |
else { // Mozilla/Netscape seems to prefer am3 | |
BigInteger.prototype.am = am3; | |
dbits = 28; | |
} | |
BigInteger.prototype.DB = dbits; | |
BigInteger.prototype.DM = ((1 << dbits) - 1); | |
BigInteger.prototype.DV = (1 << dbits); | |
var BI_FP = 52; | |
BigInteger.prototype.FV = Math.pow(2, BI_FP); | |
BigInteger.prototype.F1 = BI_FP - dbits; | |
BigInteger.prototype.F2 = 2 * dbits - BI_FP; | |
// Digit conversions | |
var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz"; | |
var BI_RC = new Array(); | |
var rr, vv; | |
rr = "0".charCodeAt(0); | |
for (vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv; | |
rr = "a".charCodeAt(0); | |
for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; | |
rr = "A".charCodeAt(0); | |
for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; | |
function int2char(n) { return BI_RM.charAt(n); } | |
function intAt(s, i) { | |
var c = BI_RC[s.charCodeAt(i)]; | |
return (c == null) ? -1 : c; | |
} | |
// return bigint initialized to value | |
function nbv(i) { var r = nbi(); r.fromInt(i); return r; } | |
// returns bit length of the integer x | |
function nbits(x) { | |
var r = 1, t; | |
if ((t = x >>> 16) != 0) { x = t; r += 16; } | |
if ((t = x >> 8) != 0) { x = t; r += 8; } | |
if ((t = x >> 4) != 0) { x = t; r += 4; } | |
if ((t = x >> 2) != 0) { x = t; r += 2; } | |
if ((t = x >> 1) != 0) { x = t; r += 1; } | |
return r; | |
} | |
// (protected) copy this to r | |
BigInteger.prototype.copyTo = function (r) { | |
for (var i = this.t - 1; i >= 0; --i) r[i] = this[i]; | |
r.t = this.t; | |
r.s = this.s; | |
}; | |
// (protected) set from integer value x, -DV <= x < DV | |
BigInteger.prototype.fromInt = function (x) { | |
this.t = 1; | |
this.s = (x < 0) ? -1 : 0; | |
if (x > 0) this[0] = x; | |
else if (x < -1) this[0] = x + DV; | |
else this.t = 0; | |
}; | |
// (protected) set from string and radix | |
BigInteger.prototype.fromString = function (s, b) { | |
var k; | |
if (b == 16) k = 4; | |
else if (b == 8) k = 3; | |
else if (b == 256) k = 8; // byte array | |
else if (b == 2) k = 1; | |
else if (b == 32) k = 5; | |
else if (b == 4) k = 2; | |
else { this.fromRadix(s, b); return; } | |
this.t = 0; | |
this.s = 0; | |
var i = s.length, mi = false, sh = 0; | |
while (--i >= 0) { | |
var x = (k == 8) ? s[i] & 0xff : intAt(s, i); | |
if (x < 0) { | |
if (s.charAt(i) == "-") mi = true; | |
continue; | |
} | |
mi = false; | |
if (sh == 0) | |
this[this.t++] = x; | |
else if (sh + k > this.DB) { | |
this[this.t - 1] |= (x & ((1 << (this.DB - sh)) - 1)) << sh; | |
this[this.t++] = (x >> (this.DB - sh)); | |
} | |
else | |
this[this.t - 1] |= x << sh; | |
sh += k; | |
if (sh >= this.DB) sh -= this.DB; | |
} | |
if (k == 8 && (s[0] & 0x80) != 0) { | |
this.s = -1; | |
if (sh > 0) this[this.t - 1] |= ((1 << (this.DB - sh)) - 1) << sh; | |
} | |
this.clamp(); | |
if (mi) BigInteger.ZERO.subTo(this, this); | |
}; | |
// (protected) clamp off excess high words | |
BigInteger.prototype.clamp = function () { | |
var c = this.s & this.DM; | |
while (this.t > 0 && this[this.t - 1] == c) --this.t; | |
}; | |
// (protected) r = this << n*DB | |
BigInteger.prototype.dlShiftTo = function (n, r) { | |
var i; | |
for (i = this.t - 1; i >= 0; --i) r[i + n] = this[i]; | |
for (i = n - 1; i >= 0; --i) r[i] = 0; | |
r.t = this.t + n; | |
r.s = this.s; | |
}; | |
// (protected) r = this >> n*DB | |
BigInteger.prototype.drShiftTo = function (n, r) { | |
for (var i = n; i < this.t; ++i) r[i - n] = this[i]; | |
r.t = Math.max(this.t - n, 0); | |
r.s = this.s; | |
}; | |
// (protected) r = this << n | |
BigInteger.prototype.lShiftTo = function (n, r) { | |
var bs = n % this.DB; | |
var cbs = this.DB - bs; | |
var bm = (1 << cbs) - 1; | |
var ds = Math.floor(n / this.DB), c = (this.s << bs) & this.DM, i; | |
for (i = this.t - 1; i >= 0; --i) { | |
r[i + ds + 1] = (this[i] >> cbs) | c; | |
c = (this[i] & bm) << bs; | |
} | |
for (i = ds - 1; i >= 0; --i) r[i] = 0; | |
r[ds] = c; | |
r.t = this.t + ds + 1; | |
r.s = this.s; | |
r.clamp(); | |
}; | |
// (protected) r = this >> n | |
BigInteger.prototype.rShiftTo = function (n, r) { | |
r.s = this.s; | |
var ds = Math.floor(n / this.DB); | |
if (ds >= this.t) { r.t = 0; return; } | |
var bs = n % this.DB; | |
var cbs = this.DB - bs; | |
var bm = (1 << bs) - 1; | |
r[0] = this[ds] >> bs; | |
for (var i = ds + 1; i < this.t; ++i) { | |
r[i - ds - 1] |= (this[i] & bm) << cbs; | |
r[i - ds] = this[i] >> bs; | |
} | |
if (bs > 0) r[this.t - ds - 1] |= (this.s & bm) << cbs; | |
r.t = this.t - ds; | |
r.clamp(); | |
}; | |
// (protected) r = this - a | |
BigInteger.prototype.subTo = function (a, r) { | |
var i = 0, c = 0, m = Math.min(a.t, this.t); | |
while (i < m) { | |
c += this[i] - a[i]; | |
r[i++] = c & this.DM; | |
c >>= this.DB; | |
} | |
if (a.t < this.t) { | |
c -= a.s; | |
while (i < this.t) { | |
c += this[i]; | |
r[i++] = c & this.DM; | |
c >>= this.DB; | |
} | |
c += this.s; | |
} | |
else { | |
c += this.s; | |
while (i < a.t) { | |
c -= a[i]; | |
r[i++] = c & this.DM; | |
c >>= this.DB; | |
} | |
c -= a.s; | |
} | |
r.s = (c < 0) ? -1 : 0; | |
if (c < -1) r[i++] = this.DV + c; | |
else if (c > 0) r[i++] = c; | |
r.t = i; | |
r.clamp(); | |
}; | |
// (protected) r = this * a, r != this,a (HAC 14.12) | |
// "this" should be the larger one if appropriate. | |
BigInteger.prototype.multiplyTo = function (a, r) { | |
var x = this.abs(), y = a.abs(); | |
var i = x.t; | |
r.t = i + y.t; | |
while (--i >= 0) r[i] = 0; | |
for (i = 0; i < y.t; ++i) r[i + x.t] = x.am(0, y[i], r, i, 0, x.t); | |
r.s = 0; | |
r.clamp(); | |
if (this.s != a.s) BigInteger.ZERO.subTo(r, r); | |
}; | |
// (protected) r = this^2, r != this (HAC 14.16) | |
BigInteger.prototype.squareTo = function (r) { | |
var x = this.abs(); | |
var i = r.t = 2 * x.t; | |
while (--i >= 0) r[i] = 0; | |
for (i = 0; i < x.t - 1; ++i) { | |
var c = x.am(i, x[i], r, 2 * i, 0, 1); | |
if ((r[i + x.t] += x.am(i + 1, 2 * x[i], r, 2 * i + 1, c, x.t - i - 1)) >= x.DV) { | |
r[i + x.t] -= x.DV; | |
r[i + x.t + 1] = 1; | |
} | |
} | |
if (r.t > 0) r[r.t - 1] += x.am(i, x[i], r, 2 * i, 0, 1); | |
r.s = 0; | |
r.clamp(); | |
}; | |
// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) | |
// r != q, this != m. q or r may be null. | |
BigInteger.prototype.divRemTo = function (m, q, r) { | |
var pm = m.abs(); | |
if (pm.t <= 0) return; | |
var pt = this.abs(); | |
if (pt.t < pm.t) { | |
if (q != null) q.fromInt(0); | |
if (r != null) this.copyTo(r); | |
return; | |
} | |
if (r == null) r = nbi(); | |
var y = nbi(), ts = this.s, ms = m.s; | |
var nsh = this.DB - nbits(pm[pm.t - 1]); // normalize modulus | |
if (nsh > 0) { pm.lShiftTo(nsh, y); pt.lShiftTo(nsh, r); } | |
else { pm.copyTo(y); pt.copyTo(r); } | |
var ys = y.t; | |
var y0 = y[ys - 1]; | |
if (y0 == 0) return; | |
var yt = y0 * (1 << this.F1) + ((ys > 1) ? y[ys - 2] >> this.F2 : 0); | |
var d1 = this.FV / yt, d2 = (1 << this.F1) / yt, e = 1 << this.F2; | |
var i = r.t, j = i - ys, t = (q == null) ? nbi() : q; | |
y.dlShiftTo(j, t); | |
if (r.compareTo(t) >= 0) { | |
r[r.t++] = 1; | |
r.subTo(t, r); | |
} | |
BigInteger.ONE.dlShiftTo(ys, t); | |
t.subTo(y, y); // "negative" y so we can replace sub with am later | |
while (y.t < ys) y[y.t++] = 0; | |
while (--j >= 0) { | |
// Estimate quotient digit | |
var qd = (r[--i] == y0) ? this.DM : Math.floor(r[i] * d1 + (r[i - 1] + e) * d2); | |
if ((r[i] += y.am(0, qd, r, j, 0, ys)) < qd) { // Try it out | |
y.dlShiftTo(j, t); | |
r.subTo(t, r); | |
while (r[i] < --qd) r.subTo(t, r); | |
} | |
} | |
if (q != null) { | |
r.drShiftTo(ys, q); | |
if (ts != ms) BigInteger.ZERO.subTo(q, q); | |
} | |
r.t = ys; | |
r.clamp(); | |
if (nsh > 0) r.rShiftTo(nsh, r); // Denormalize remainder | |
if (ts < 0) BigInteger.ZERO.subTo(r, r); | |
}; | |
// (protected) return "-1/this % 2^DB"; useful for Mont. reduction | |
// justification: | |
// xy == 1 (mod m) | |
// xy = 1+km | |
// xy(2-xy) = (1+km)(1-km) | |
// x[y(2-xy)] = 1-k^2m^2 | |
// x[y(2-xy)] == 1 (mod m^2) | |
// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 | |
// should reduce x and y(2-xy) by m^2 at each step to keep size bounded. | |
// JS multiply "overflows" differently from C/C++, so care is needed here. | |
BigInteger.prototype.invDigit = function () { | |
if (this.t < 1) return 0; | |
var x = this[0]; | |
if ((x & 1) == 0) return 0; | |
var y = x & 3; // y == 1/x mod 2^2 | |
y = (y * (2 - (x & 0xf) * y)) & 0xf; // y == 1/x mod 2^4 | |
y = (y * (2 - (x & 0xff) * y)) & 0xff; // y == 1/x mod 2^8 | |
y = (y * (2 - (((x & 0xffff) * y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16 | |
// last step - calculate inverse mod DV directly; | |
// assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints | |
y = (y * (2 - x * y % this.DV)) % this.DV; // y == 1/x mod 2^dbits | |
// we really want the negative inverse, and -DV < y < DV | |
return (y > 0) ? this.DV - y : -y; | |
}; | |
// (protected) true iff this is even | |
BigInteger.prototype.isEven = function () { return ((this.t > 0) ? (this[0] & 1) : this.s) == 0; }; | |
// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) | |
BigInteger.prototype.exp = function (e, z) { | |
if (e > 0xffffffff || e < 1) return BigInteger.ONE; | |
var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e) - 1; | |
g.copyTo(r); | |
while (--i >= 0) { | |
z.sqrTo(r, r2); | |
if ((e & (1 << i)) > 0) z.mulTo(r2, g, r); | |
else { var t = r; r = r2; r2 = t; } | |
} | |
return z.revert(r); | |
}; | |
// (public) return string representation in given radix | |
BigInteger.prototype.toString = function (b) { | |
if (this.s < 0) return "-" + this.negate().toString(b); | |
var k; | |
if (b == 16) k = 4; | |
else if (b == 8) k = 3; | |
else if (b == 2) k = 1; | |
else if (b == 32) k = 5; | |
else if (b == 4) k = 2; | |
else return this.toRadix(b); | |
var km = (1 << k) - 1, d, m = false, r = "", i = this.t; | |
var p = this.DB - (i * this.DB) % k; | |
if (i-- > 0) { | |
if (p < this.DB && (d = this[i] >> p) > 0) { m = true; r = int2char(d); } | |
while (i >= 0) { | |
if (p < k) { | |
d = (this[i] & ((1 << p) - 1)) << (k - p); | |
d |= this[--i] >> (p += this.DB - k); | |
} | |
else { | |
d = (this[i] >> (p -= k)) & km; | |
if (p <= 0) { p += this.DB; --i; } | |
} | |
if (d > 0) m = true; | |
if (m) r += int2char(d); | |
} | |
} | |
return m ? r : "0"; | |
}; | |
// (public) -this | |
BigInteger.prototype.negate = function () { var r = nbi(); BigInteger.ZERO.subTo(this, r); return r; }; | |
// (public) |this| | |
BigInteger.prototype.abs = function () { return (this.s < 0) ? this.negate() : this; }; | |
// (public) return + if this > a, - if this < a, 0 if equal | |
BigInteger.prototype.compareTo = function (a) { | |
var r = this.s - a.s; | |
if (r != 0) return r; | |
var i = this.t; | |
r = i - a.t; | |
if (r != 0) return (this.s < 0) ? -r : r; | |
while (--i >= 0) if ((r = this[i] - a[i]) != 0) return r; | |
return 0; | |
} | |
// (public) return the number of bits in "this" | |
BigInteger.prototype.bitLength = function () { | |
if (this.t <= 0) return 0; | |
return this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ (this.s & this.DM)); | |
}; | |
// (public) this mod a | |
BigInteger.prototype.mod = function (a) { | |
var r = nbi(); | |
this.abs().divRemTo(a, null, r); | |
if (this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r, r); | |
return r; | |
} | |
// (public) this^e % m, 0 <= e < 2^32 | |
BigInteger.prototype.modPowInt = function (e, m) { | |
var z; | |
if (e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m); | |
return this.exp(e, z); | |
}; | |
// "constants" | |
BigInteger.ZERO = nbv(0); | |
BigInteger.ONE = nbv(1); | |
// Copyright (c) 2005-2009 Tom Wu | |
// All Rights Reserved. | |
// See "LICENSE" for details. | |
// Extended JavaScript BN functions, required for RSA private ops. | |
// Version 1.1: new BigInteger("0", 10) returns "proper" zero | |
// Version 1.2: square() API, isProbablePrime fix | |
// return index of lowest 1-bit in x, x < 2^31 | |
function lbit(x) { | |
if (x == 0) return -1; | |
var r = 0; | |
if ((x & 0xffff) == 0) { x >>= 16; r += 16; } | |
if ((x & 0xff) == 0) { x >>= 8; r += 8; } | |
if ((x & 0xf) == 0) { x >>= 4; r += 4; } | |
if ((x & 3) == 0) { x >>= 2; r += 2; } | |
if ((x & 1) == 0) ++r; | |
return r; | |
} | |
// return number of 1 bits in x | |
function cbit(x) { | |
var r = 0; | |
while (x != 0) { x &= x - 1; ++r; } | |
return r; | |
} | |
var lowprimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]; | |
var lplim = (1 << 26) / lowprimes[lowprimes.length - 1]; | |
// (protected) return x s.t. r^x < DV | |
BigInteger.prototype.chunkSize = function (r) { return Math.floor(Math.LN2 * this.DB / Math.log(r)); }; | |
// (protected) convert to radix string | |
BigInteger.prototype.toRadix = function (b) { | |
if (b == null) b = 10; | |
if (this.signum() == 0 || b < 2 || b > 36) return "0"; | |
var cs = this.chunkSize(b); | |
var a = Math.pow(b, cs); | |
var d = nbv(a), y = nbi(), z = nbi(), r = ""; | |
this.divRemTo(d, y, z); | |
while (y.signum() > 0) { | |
r = (a + z.intValue()).toString(b).substr(1) + r; | |
y.divRemTo(d, y, z); | |
} | |
return z.intValue().toString(b) + r; | |
}; | |
// (protected) convert from radix string | |
BigInteger.prototype.fromRadix = function (s, b) { | |
this.fromInt(0); | |
if (b == null) b = 10; | |
var cs = this.chunkSize(b); | |
var d = Math.pow(b, cs), mi = false, j = 0, w = 0; | |
for (var i = 0; i < s.length; ++i) { | |
var x = intAt(s, i); | |
if (x < 0) { | |
if (s.charAt(i) == "-" && this.signum() == 0) mi = true; | |
continue; | |
} | |
w = b * w + x; | |
if (++j >= cs) { | |
this.dMultiply(d); | |
this.dAddOffset(w, 0); | |
j = 0; | |
w = 0; | |
} | |
} | |
if (j > 0) { | |
this.dMultiply(Math.pow(b, j)); | |
this.dAddOffset(w, 0); | |
} | |
if (mi) BigInteger.ZERO.subTo(this, this); | |
}; | |
// (protected) alternate constructor | |
BigInteger.prototype.fromNumber = function (a, b, c) { | |
if ("number" == typeof b) { | |
// new BigInteger(int,int,RNG) | |
if (a < 2) this.fromInt(1); | |
else { | |
this.fromNumber(a, c); | |
if (!this.testBit(a - 1)) // force MSB set | |
this.bitwiseTo(BigInteger.ONE.shiftLeft(a - 1), op_or, this); | |
if (this.isEven()) this.dAddOffset(1, 0); // force odd | |
while (!this.isProbablePrime(b)) { | |
this.dAddOffset(2, 0); | |
if (this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a - 1), this); | |
} | |
} | |
} | |
else { | |
// new BigInteger(int,RNG) | |
var x = new Array(), t = a & 7; | |
x.length = (a >> 3) + 1; | |
b.nextBytes(x); | |
if (t > 0) x[0] &= ((1 << t) - 1); else x[0] = 0; | |
this.fromString(x, 256); | |
} | |
}; | |
// (protected) r = this op a (bitwise) | |
BigInteger.prototype.bitwiseTo = function (a, op, r) { | |
var i, f, m = Math.min(a.t, this.t); | |
for (i = 0; i < m; ++i) r[i] = op(this[i], a[i]); | |
if (a.t < this.t) { | |
f = a.s & this.DM; | |
for (i = m; i < this.t; ++i) r[i] = op(this[i], f); | |
r.t = this.t; | |
} | |
else { | |
f = this.s & this.DM; | |
for (i = m; i < a.t; ++i) r[i] = op(f, a[i]); | |
r.t = a.t; | |
} | |
r.s = op(this.s, a.s); | |
r.clamp(); | |
}; | |
// (protected) this op (1<<n) | |
BigInteger.prototype.changeBit = function (n, op) { | |
var r = BigInteger.ONE.shiftLeft(n); | |
this.bitwiseTo(r, op, r); | |
return r; | |
}; | |
// (protected) r = this + a | |
BigInteger.prototype.addTo = function (a, r) { | |
var i = 0, c = 0, m = Math.min(a.t, this.t); | |
while (i < m) { | |
c += this[i] + a[i]; | |
r[i++] = c & this.DM; | |
c >>= this.DB; | |
} | |
if (a.t < this.t) { | |
c += a.s; | |
while (i < this.t) { | |
c += this[i]; | |
r[i++] = c & this.DM; | |
c >>= this.DB; | |
} | |
c += this.s; | |
} | |
else { | |
c += this.s; | |
while (i < a.t) { | |
c += a[i]; | |
r[i++] = c & this.DM; | |
c >>= this.DB; | |
} | |
c += a.s; | |
} | |
r.s = (c < 0) ? -1 : 0; | |
if (c > 0) r[i++] = c; | |
else if (c < -1) r[i++] = this.DV + c; | |
r.t = i; | |
r.clamp(); | |
}; | |
// (protected) this *= n, this >= 0, 1 < n < DV | |
BigInteger.prototype.dMultiply = function (n) { | |
this[this.t] = this.am(0, n - 1, this, 0, 0, this.t); | |
++this.t; | |
this.clamp(); | |
}; | |
// (protected) this += n << w words, this >= 0 | |
BigInteger.prototype.dAddOffset = function (n, w) { | |
if (n == 0) return; | |
while (this.t <= w) this[this.t++] = 0; | |
this[w] += n; | |
while (this[w] >= this.DV) { | |
this[w] -= this.DV; | |
if (++w >= this.t) this[this.t++] = 0; | |
++this[w]; | |
} | |
}; | |
// (protected) r = lower n words of "this * a", a.t <= n | |
// "this" should be the larger one if appropriate. | |
BigInteger.prototype.multiplyLowerTo = function (a, n, r) { | |
var i = Math.min(this.t + a.t, n); | |
r.s = 0; // assumes a,this >= 0 | |
r.t = i; | |
while (i > 0) r[--i] = 0; | |
var j; | |
for (j = r.t - this.t; i < j; ++i) r[i + this.t] = this.am(0, a[i], r, i, 0, this.t); | |
for (j = Math.min(a.t, n); i < j; ++i) this.am(0, a[i], r, i, 0, n - i); | |
r.clamp(); | |
}; | |
// (protected) r = "this * a" without lower n words, n > 0 | |
// "this" should be the larger one if appropriate. | |
BigInteger.prototype.multiplyUpperTo = function (a, n, r) { | |
--n; | |
var i = r.t = this.t + a.t - n; | |
r.s = 0; // assumes a,this >= 0 | |
while (--i >= 0) r[i] = 0; | |
for (i = Math.max(n - this.t, 0); i < a.t; ++i) | |
r[this.t + i - n] = this.am(n - i, a[i], r, 0, 0, this.t + i - n); | |
r.clamp(); | |
r.drShiftTo(1, r); | |
}; | |
// (protected) this % n, n < 2^26 | |
BigInteger.prototype.modInt = function (n) { | |
if (n <= 0) return 0; | |
var d = this.DV % n, r = (this.s < 0) ? n - 1 : 0; | |
if (this.t > 0) | |
if (d == 0) r = this[0] % n; | |
else for (var i = this.t - 1; i >= 0; --i) r = (d * r + this[i]) % n; | |
return r; | |
}; | |
// (protected) true if probably prime (HAC 4.24, Miller-Rabin) | |
BigInteger.prototype.millerRabin = function (t) { | |
var n1 = this.subtract(BigInteger.ONE); | |
var k = n1.getLowestSetBit(); | |
if (k <= 0) return false; | |
var r = n1.shiftRight(k); | |
t = (t + 1) >> 1; | |
if (t > lowprimes.length) t = lowprimes.length; | |
var a = nbi(); | |
for (var i = 0; i < t; ++i) { | |
//Pick bases at random, instead of starting at 2 | |
a.fromInt(lowprimes[Math.floor(Math.random() * lowprimes.length)]); | |
var y = a.modPow(r, this); | |
if (y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { | |
var j = 1; | |
while (j++ < k && y.compareTo(n1) != 0) { | |
y = y.modPowInt(2, this); | |
if (y.compareTo(BigInteger.ONE) == 0) return false; | |
} | |
if (y.compareTo(n1) != 0) return false; | |
} | |
} | |
return true; | |
}; | |
// (public) | |
BigInteger.prototype.clone = function () { var r = nbi(); this.copyTo(r); return r; }; | |
// (public) return value as integer | |
BigInteger.prototype.intValue = function () { | |
if (this.s < 0) { | |
if (this.t == 1) return this[0] - this.DV; | |
else if (this.t == 0) return -1; | |
} | |
else if (this.t == 1) return this[0]; | |
else if (this.t == 0) return 0; | |
// assumes 16 < DB < 32 | |
return ((this[1] & ((1 << (32 - this.DB)) - 1)) << this.DB) | this[0]; | |
}; | |
// (public) return value as byte | |
BigInteger.prototype.byteValue = function () { return (this.t == 0) ? this.s : (this[0] << 24) >> 24; }; | |
// (public) return value as short (assumes DB>=16) | |
BigInteger.prototype.shortValue = function () { return (this.t == 0) ? this.s : (this[0] << 16) >> 16; }; | |
// (public) 0 if this == 0, 1 if this > 0 | |
BigInteger.prototype.signum = function () { | |
if (this.s < 0) return -1; | |
else if (this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0; | |
else return 1; | |
}; | |
// (public) convert to bigendian byte array | |
BigInteger.prototype.toByteArray = function () { | |
var i = this.t, r = new Array(); | |
r[0] = this.s; | |
var p = this.DB - (i * this.DB) % 8, d, k = 0; | |
if (i-- > 0) { | |
if (p < this.DB && (d = this[i] >> p) != (this.s & this.DM) >> p) | |
r[k++] = d | (this.s << (this.DB - p)); | |
while (i >= 0) { | |
if (p < 8) { | |
d = (this[i] & ((1 << p) - 1)) << (8 - p); | |
d |= this[--i] >> (p += this.DB - 8); | |
} | |
else { | |
d = (this[i] >> (p -= 8)) & 0xff; | |
if (p <= 0) { p += this.DB; --i; } | |
} | |
if ((d & 0x80) != 0) d |= -256; | |
if (k == 0 && (this.s & 0x80) != (d & 0x80)) ++k; | |
if (k > 0 || d != this.s) r[k++] = d; | |
} | |
} | |
return r; | |
}; | |
BigInteger.prototype.equals = function (a) { return (this.compareTo(a) == 0); }; | |
BigInteger.prototype.min = function (a) { return (this.compareTo(a) < 0) ? this : a; }; | |
BigInteger.prototype.max = function (a) { return (this.compareTo(a) > 0) ? this : a; }; | |
// (public) this & a | |
function op_and(x, y) { return x & y; } | |
BigInteger.prototype.and = function (a) { var r = nbi(); this.bitwiseTo(a, op_and, r); return r; }; | |
// (public) this | a | |
function op_or(x, y) { return x | y; } | |
BigInteger.prototype.or = function (a) { var r = nbi(); this.bitwiseTo(a, op_or, r); return r; }; | |
// (public) this ^ a | |
function op_xor(x, y) { return x ^ y; } | |
BigInteger.prototype.xor = function (a) { var r = nbi(); this.bitwiseTo(a, op_xor, r); return r; }; | |
// (public) this & ~a | |
function op_andnot(x, y) { return x & ~y; } | |
BigInteger.prototype.andNot = function (a) { var r = nbi(); this.bitwiseTo(a, op_andnot, r); return r; }; | |
// (public) ~this | |
BigInteger.prototype.not = function () { | |
var r = nbi(); | |
for (var i = 0; i < this.t; ++i) r[i] = this.DM & ~this[i]; | |
r.t = this.t; | |
r.s = ~this.s; | |
return r; | |
}; | |
// (public) this << n | |
BigInteger.prototype.shiftLeft = function (n) { | |
var r = nbi(); | |
if (n < 0) this.rShiftTo(-n, r); else this.lShiftTo(n, r); | |
return r; | |
}; | |
// (public) this >> n | |
BigInteger.prototype.shiftRight = function (n) { | |
var r = nbi(); | |
if (n < 0) this.lShiftTo(-n, r); else this.rShiftTo(n, r); | |
return r; | |
}; | |
// (public) returns index of lowest 1-bit (or -1 if none) | |
BigInteger.prototype.getLowestSetBit = function () { | |
for (var i = 0; i < this.t; ++i) | |
if (this[i] != 0) return i * this.DB + lbit(this[i]); | |
if (this.s < 0) return this.t * this.DB; | |
return -1; | |
}; | |
// (public) return number of set bits | |
BigInteger.prototype.bitCount = function () { | |
var r = 0, x = this.s & this.DM; | |
for (var i = 0; i < this.t; ++i) r += cbit(this[i] ^ x); | |
return r; | |
}; | |
// (public) true iff nth bit is set | |
BigInteger.prototype.testBit = function (n) { | |
var j = Math.floor(n / this.DB); | |
if (j >= this.t) return (this.s != 0); | |
return ((this[j] & (1 << (n % this.DB))) != 0); | |
}; | |
// (public) this | (1<<n) | |
BigInteger.prototype.setBit = function (n) { return this.changeBit(n, op_or); }; | |
// (public) this & ~(1<<n) | |
BigInteger.prototype.clearBit = function (n) { return this.changeBit(n, op_andnot); }; | |
// (public) this ^ (1<<n) | |
BigInteger.prototype.flipBit = function (n) { return this.changeBit(n, op_xor); }; | |
// (public) this + a | |
BigInteger.prototype.add = function (a) { var r = nbi(); this.addTo(a, r); return r; }; | |
// (public) this - a | |
BigInteger.prototype.subtract = function (a) { var r = nbi(); this.subTo(a, r); return r; }; | |
// (public) this * a | |
BigInteger.prototype.multiply = function (a) { var r = nbi(); this.multiplyTo(a, r); return r; }; | |
// (public) this / a | |
BigInteger.prototype.divide = function (a) { var r = nbi(); this.divRemTo(a, r, null); return r; }; | |
// (public) this % a | |
BigInteger.prototype.remainder = function (a) { var r = nbi(); this.divRemTo(a, null, r); return r; }; | |
// (public) [this/a,this%a] | |
BigInteger.prototype.divideAndRemainder = function (a) { | |
var q = nbi(), r = nbi(); | |
this.divRemTo(a, q, r); | |
return new Array(q, r); | |
}; | |
// (public) this^e % m (HAC 14.85) | |
BigInteger.prototype.modPow = function (e, m) { | |
var i = e.bitLength(), k, r = nbv(1), z; | |
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; | |
if (i < 8) | |
z = new Classic(m); | |
else if (m.isEven()) | |
z = new Barrett(m); | |
else | |
z = new Montgomery(m); | |
// 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; } | |
} | |
} | |
return z.revert(r); | |
}; | |
// (public) 1/this % m (HAC 14.61) | |
BigInteger.prototype.modInverse = function (m) { | |
var ac = m.isEven(); | |
if ((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO; | |
var u = m.clone(), v = this.clone(); | |
var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1); | |
while (u.signum() != 0) { | |
while (u.isEven()) { | |
u.rShiftTo(1, u); | |
if (ac) { | |
if (!a.isEven() || !b.isEven()) { a.addTo(this, a); b.subTo(m, b); } | |
a.rShiftTo(1, a); | |
} | |
else if (!b.isEven()) b.subTo(m, b); | |
b.rShiftTo(1, b); | |
} | |
while (v.isEven()) { | |
v.rShiftTo(1, v); | |
if (ac) { | |
if (!c.isEven() || !d.isEven()) { c.addTo(this, c); d.subTo(m, d); } | |
c.rShiftTo(1, c); | |
} | |
else if (!d.isEven()) d.subTo(m, d); | |
d.rShiftTo(1, d); | |
} | |
if (u.compareTo(v) >= 0) { | |
u.subTo(v, u); | |
if (ac) a.subTo(c, a); | |
b.subTo(d, b); | |
} | |
else { | |
v.subTo(u, v); | |
if (ac) c.subTo(a, c); | |
d.subTo(b, d); | |
} | |
} | |
if (v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO; | |
if (d.compareTo(m) >= 0) return d.subtract(m); | |
if (d.signum() < 0) d.addTo(m, d); else return d; | |
if (d.signum() < 0) return d.add(m); else return d; | |
}; | |
// (public) this^e | |
BigInteger.prototype.pow = function (e) { return this.exp(e, new NullExp()); }; | |
// (public) gcd(this,a) (HAC 14.54) | |
BigInteger.prototype.gcd = function (a) { | |
var x = (this.s < 0) ? this.negate() : this.clone(); | |
var y = (a.s < 0) ? a.negate() : a.clone(); | |
if (x.compareTo(y) < 0) { var t = x; x = y; y = t; } | |
var i = x.getLowestSetBit(), g = y.getLowestSetBit(); | |
if (g < 0) return x; | |
if (i < g) g = i; | |
if (g > 0) { | |
x.rShiftTo(g, x); | |
y.rShiftTo(g, y); | |
} | |
while (x.signum() > 0) { | |
if ((i = x.getLowestSetBit()) > 0) x.rShiftTo(i, x); | |
if ((i = y.getLowestSetBit()) > 0) y.rShiftTo(i, y); | |
if (x.compareTo(y) >= 0) { | |
x.subTo(y, x); | |
x.rShiftTo(1, x); | |
} | |
else { | |
y.subTo(x, y); | |
y.rShiftTo(1, y); | |
} | |
} | |
if (g > 0) y.lShiftTo(g, y); | |
return y; | |
}; | |
// (public) test primality with certainty >= 1-.5^t | |
BigInteger.prototype.isProbablePrime = function (t) { | |
var i, x = this.abs(); | |
if (x.t == 1 && x[0] <= lowprimes[lowprimes.length - 1]) { | |
for (i = 0; i < lowprimes.length; ++i) | |
if (x[0] == lowprimes[i]) return true; | |
return false; | |
} | |
if (x.isEven()) return false; | |
i = 1; | |
while (i < lowprimes.length) { | |
var m = lowprimes[i], j = i + 1; | |
while (j < lowprimes.length && m < lplim) m *= lowprimes[j++]; | |
m = x.modInt(m); | |
while (i < j) if (m % lowprimes[i++] == 0) return false; | |
} | |
return x.millerRabin(t); | |
}; | |
// JSBN-specific extension | |
// (public) this^2 | |
BigInteger.prototype.square = function () { var r = nbi(); this.squareTo(r); return r; }; | |
// NOTE: BigInteger interfaces not implemented in jsbn: | |
// BigInteger(int signum, byte[] magnitude) | |
// double doubleValue() | |
// float floatValue() | |
// int hashCode() | |
// long longValue() | |
// static BigInteger valueOf(long val) | |
// Copyright Stephan Thomas (start) --- // | |
// https://raw.github.com/bitcoinjs/bitcoinjs-lib/07f9d55ccb6abd962efb6befdd37671f85ea4ff9/src/util.js | |
// BigInteger monkey patching | |
BigInteger.valueOf = nbv; | |
/** | |
* Returns a byte array representation of the big integer. | |
* | |
* This returns the absolute of the contained value in big endian | |
* form. A value of zero results in an empty array. | |
*/ | |
BigInteger.prototype.toByteArrayUnsigned = function () { | |
var ba = this.abs().toByteArray(); | |
if (ba.length) { | |
if (ba[0] == 0) { | |
ba = ba.slice(1); | |
} | |
return ba.map(function (v) { | |
return (v < 0) ? v + 256 : v; | |
}); | |
} else { | |
// Empty array, nothing to do | |
return ba; | |
} | |
}; | |
/** | |
* Turns a byte array into a big integer. | |
* | |
* This function will interpret a byte array as a big integer in big | |
* endian notation and ignore leading zeros. | |
*/ | |
BigInteger.fromByteArrayUnsigned = function (ba) { | |
if (!ba.length) { | |
return ba.valueOf(0); | |
} else if (ba[0] & 0x80) { | |
// Prepend a zero so the BigInteger class doesn't mistake this | |
// for a negative integer. | |
return new BigInteger([0].concat(ba)); | |
} else { | |
return new BigInteger(ba); | |
} | |
}; | |
/** | |
* Converts big integer to signed byte representation. | |
* | |
* The format for this value uses a the most significant bit as a sign | |
* bit. If the most significant bit is already occupied by the | |
* absolute value, an extra byte is prepended and the sign bit is set | |
* there. | |
* | |
* Examples: | |
* | |
* 0 => 0x00 | |
* 1 => 0x01 | |
* -1 => 0x81 | |
* 127 => 0x7f | |
* -127 => 0xff | |
* 128 => 0x0080 | |
* -128 => 0x8080 | |
* 255 => 0x00ff | |
* -255 => 0x80ff | |
* 16300 => 0x3fac | |
* -16300 => 0xbfac | |
* 62300 => 0x00f35c | |
* -62300 => 0x80f35c | |
*/ | |
BigInteger.prototype.toByteArraySigned = function () { | |
var val = this.abs().toByteArrayUnsigned(); | |
var neg = this.compareTo(BigInteger.ZERO) < 0; | |
if (neg) { | |
if (val[0] & 0x80) { | |
val.unshift(0x80); | |
} else { | |
val[0] |= 0x80; | |
} | |
} else { | |
if (val[0] & 0x80) { | |
val.unshift(0x00); | |
} | |
} | |
return val; | |
}; | |
/** | |
* Parse a signed big integer byte representation. | |
* | |
* For details on the format please see BigInteger.toByteArraySigned. | |
*/ | |
BigInteger.fromByteArraySigned = function (ba) { | |
// Check for negative value | |
if (ba[0] & 0x80) { | |
// Remove sign bit | |
ba[0] &= 0x7f; | |
return BigInteger.fromByteArrayUnsigned(ba).negate(); | |
} else { | |
return BigInteger.fromByteArrayUnsigned(ba); | |
} | |
}; | |
// Copyright Stephan Thomas (end) --- // | |
// ****** REDUCTION ******* // | |
// Modular reduction using "classic" algorithm | |
function Classic(m) { this.m = m; } | |
Classic.prototype.convert = function (x) { | |
if (x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); | |
else return x; | |
}; | |
Classic.prototype.revert = function (x) { return x; }; | |
Classic.prototype.reduce = function (x) { x.divRemTo(this.m, null, x); }; | |
Classic.prototype.mulTo = function (x, y, r) { x.multiplyTo(y, r); this.reduce(r); }; | |
Classic.prototype.sqrTo = function (x, r) { x.squareTo(r); this.reduce(r); }; | |
// Montgomery reduction | |
function Montgomery(m) { | |
this.m = m; | |
this.mp = m.invDigit(); | |
this.mpl = this.mp & 0x7fff; | |
this.mph = this.mp >> 15; | |
this.um = (1 << (m.DB - 15)) - 1; | |
this.mt2 = 2 * m.t; | |
} | |
// xR mod m | |
Montgomery.prototype.convert = function (x) { | |
var r = nbi(); | |
x.abs().dlShiftTo(this.m.t, r); | |
r.divRemTo(this.m, null, r); | |
if (x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r, r); | |
return r; | |
} | |
// x/R mod m | |
Montgomery.prototype.revert = function (x) { | |
var r = nbi(); | |
x.copyTo(r); | |
this.reduce(r); | |
return r; | |
}; | |
// x = x/R mod m (HAC 14.32) | |
Montgomery.prototype.reduce = function (x) { | |
while (x.t <= this.mt2) // pad x so am has enough room later | |
x[x.t++] = 0; | |
for (var i = 0; i < this.m.t; ++i) { | |
// faster way of calculating u0 = x[i]*mp mod DV | |
var j = x[i] & 0x7fff; | |
var u0 = (j * this.mpl + (((j * this.mph + (x[i] >> 15) * this.mpl) & this.um) << 15)) & x.DM; | |
// use am to combine the multiply-shift-add into one call | |
j = i + this.m.t; | |
x[j] += this.m.am(0, u0, x, i, 0, this.m.t); | |
// propagate carry | |
while (x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; } | |
} | |
x.clamp(); | |
x.drShiftTo(this.m.t, x); | |
if (x.compareTo(this.m) >= 0) x.subTo(this.m, x); | |
}; | |
// r = "xy/R mod m"; x,y != r | |
Montgomery.prototype.mulTo = function (x, y, r) { x.multiplyTo(y, r); this.reduce(r); }; | |
// r = "x^2/R mod m"; x != r | |
Montgomery.prototype.sqrTo = function (x, r) { x.squareTo(r); this.reduce(r); }; | |
// A "null" reducer | |
function NullExp() { } | |
NullExp.prototype.convert = function (x) { return x; }; | |
NullExp.prototype.revert = function (x) { return x; }; | |
NullExp.prototype.mulTo = function (x, y, r) { x.multiplyTo(y, r); }; | |
NullExp.prototype.sqrTo = function (x, r) { x.squareTo(r); }; | |
// Barrett modular reduction | |
function Barrett(m) { | |
// setup Barrett | |
this.r2 = nbi(); | |
this.q3 = nbi(); | |
BigInteger.ONE.dlShiftTo(2 * m.t, this.r2); | |
this.mu = this.r2.divide(m); | |
this.m = m; | |
} | |
Barrett.prototype.convert = function (x) { | |
if (x.s < 0 || x.t > 2 * this.m.t) return x.mod(this.m); | |
else if (x.compareTo(this.m) < 0) return x; | |
else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; } | |
}; | |
Barrett.prototype.revert = function (x) { return x; }; | |
// x = x mod m (HAC 14.42) | |
Barrett.prototype.reduce = function (x) { | |
x.drShiftTo(this.m.t - 1, this.r2); | |
if (x.t > this.m.t + 1) { x.t = this.m.t + 1; x.clamp(); } | |
this.mu.multiplyUpperTo(this.r2, this.m.t + 1, this.q3); | |
this.m.multiplyLowerTo(this.q3, this.m.t + 1, this.r2); | |
while (x.compareTo(this.r2) < 0) x.dAddOffset(1, this.m.t + 1); | |
x.subTo(this.r2, x); | |
while (x.compareTo(this.m) >= 0) x.subTo(this.m, x); | |
}; | |
// r = x*y mod m; x,y != r | |
Barrett.prototype.mulTo = function (x, y, r) { x.multiplyTo(y, r); this.reduce(r); }; | |
// r = x^2 mod m; x != r | |
Barrett.prototype.sqrTo = function (x, r) { x.squareTo(r); this.reduce(r); }; | |
})(); | |
/* | |
CryptoJS v3.1.2 | |
code.google.com/p/crypto-js | |
(c) 2009-2013 by Jeff Mott. All rights reserved. | |
code.google.com/p/crypto-js/wiki/License | |
*/ | |
var CryptoJS=CryptoJS||function(h,s){var f={},t=f.lib={},g=function(){},j=t.Base={extend:function(a){g.prototype=this;var c=new g;a&&c.mixIn(a);c.hasOwnProperty("init")||(c.init=function(){c.$super.init.apply(this,arguments)});c.init.prototype=c;c.$super=this;return c},create:function(){var a=this.extend();a.init.apply(a,arguments);return a},init:function(){},mixIn:function(a){for(var c in a)a.hasOwnProperty(c)&&(this[c]=a[c]);a.hasOwnProperty("toString")&&(this.toString=a.toString)},clone:function(){return this.init.prototype.extend(this)}}, | |
q=t.WordArray=j.extend({init:function(a,c){a=this.words=a||[];this.sigBytes=c!=s?c:4*a.length},toString:function(a){return(a||u).stringify(this)},concat:function(a){var c=this.words,d=a.words,b=this.sigBytes;a=a.sigBytes;this.clamp();if(b%4)for(var e=0;e<a;e++)c[b+e>>>2]|=(d[e>>>2]>>>24-8*(e%4)&255)<<24-8*((b+e)%4);else if(65535<d.length)for(e=0;e<a;e+=4)c[b+e>>>2]=d[e>>>2];else c.push.apply(c,d);this.sigBytes+=a;return this},clamp:function(){var a=this.words,c=this.sigBytes;a[c>>>2]&=4294967295<< | |
32-8*(c%4);a.length=h.ceil(c/4)},clone:function(){var a=j.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var c=[],d=0;d<a;d+=4)c.push(4294967296*h.random()|0);return new q.init(c,a)}}),v=f.enc={},u=v.Hex={stringify:function(a){var c=a.words;a=a.sigBytes;for(var d=[],b=0;b<a;b++){var e=c[b>>>2]>>>24-8*(b%4)&255;d.push((e>>>4).toString(16));d.push((e&15).toString(16))}return d.join("")},parse:function(a){for(var c=a.length,d=[],b=0;b<c;b+=2)d[b>>>3]|=parseInt(a.substr(b, | |
2),16)<<24-4*(b%8);return new q.init(d,c/2)}},k=v.Latin1={stringify:function(a){var c=a.words;a=a.sigBytes;for(var d=[],b=0;b<a;b++)d.push(String.fromCharCode(c[b>>>2]>>>24-8*(b%4)&255));return d.join("")},parse:function(a){for(var c=a.length,d=[],b=0;b<c;b++)d[b>>>2]|=(a.charCodeAt(b)&255)<<24-8*(b%4);return new q.init(d,c)}},l=v.Utf8={stringify:function(a){try{return decodeURIComponent(escape(k.stringify(a)))}catch(c){throw Error("Malformed UTF-8 data");}},parse:function(a){return k.parse(unescape(encodeURIComponent(a)))}}, | |
x=t.BufferedBlockAlgorithm=j.extend({reset:function(){this._data=new q.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=l.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var c=this._data,d=c.words,b=c.sigBytes,e=this.blockSize,f=b/(4*e),f=a?h.ceil(f):h.max((f|0)-this._minBufferSize,0);a=f*e;b=h.min(4*a,b);if(a){for(var m=0;m<a;m+=e)this._doProcessBlock(d,m);m=d.splice(0,a);c.sigBytes-=b}return new q.init(m,b)},clone:function(){var a=j.clone.call(this); | |
a._data=this._data.clone();return a},_minBufferSize:0});t.Hasher=x.extend({cfg:j.extend(),init:function(a){this.cfg=this.cfg.extend(a);this.reset()},reset:function(){x.reset.call(this);this._doReset()},update:function(a){this._append(a);this._process();return this},finalize:function(a){a&&this._append(a);return this._doFinalize()},blockSize:16,_createHelper:function(a){return function(c,d){return(new a.init(d)).finalize(c)}},_createHmacHelper:function(a){return function(c,d){return(new w.HMAC.init(a, | |
d)).finalize(c)}}});var w=f.algo={};return f}(Math); | |
(function(h){for(var s=CryptoJS,f=s.lib,t=f.WordArray,g=f.Hasher,f=s.algo,j=[],q=[],v=function(a){return 4294967296*(a-(a|0))|0},u=2,k=0;64>k;){var l;a:{l=u;for(var x=h.sqrt(l),w=2;w<=x;w++)if(!(l%w)){l=!1;break a}l=!0}l&&(8>k&&(j[k]=v(h.pow(u,0.5))),q[k]=v(h.pow(u,1/3)),k++);u++}var a=[],f=f.SHA256=g.extend({_doReset:function(){this._hash=new t.init(j.slice(0))},_doProcessBlock:function(c,d){for(var b=this._hash.words,e=b[0],f=b[1],m=b[2],h=b[3],p=b[4],j=b[5],k=b[6],l=b[7],n=0;64>n;n++){if(16>n)a[n]= | |
c[d+n]|0;else{var r=a[n-15],g=a[n-2];a[n]=((r<<25|r>>>7)^(r<<14|r>>>18)^r>>>3)+a[n-7]+((g<<15|g>>>17)^(g<<13|g>>>19)^g>>>10)+a[n-16]}r=l+((p<<26|p>>>6)^(p<<21|p>>>11)^(p<<7|p>>>25))+(p&j^~p&k)+q[n]+a[n];g=((e<<30|e>>>2)^(e<<19|e>>>13)^(e<<10|e>>>22))+(e&f^e&m^f&m);l=k;k=j;j=p;p=h+r|0;h=m;m=f;f=e;e=r+g|0}b[0]=b[0]+e|0;b[1]=b[1]+f|0;b[2]=b[2]+m|0;b[3]=b[3]+h|0;b[4]=b[4]+p|0;b[5]=b[5]+j|0;b[6]=b[6]+k|0;b[7]=b[7]+l|0},_doFinalize:function(){var a=this._data,d=a.words,b=8*this._nDataBytes,e=8*a.sigBytes; | |
d[e>>>5]|=128<<24-e%32;d[(e+64>>>9<<4)+14]=h.floor(b/4294967296);d[(e+64>>>9<<4)+15]=b;a.sigBytes=4*d.length;this._process();return this._hash},clone:function(){var a=g.clone.call(this);a._hash=this._hash.clone();return a}});s.SHA256=g._createHelper(f);s.HmacSHA256=g._createHmacHelper(f)})(Math); | |
function wsDial(target,rawData,callback){ | |
//Opens a websocket, sends rawData and | |
//callbacks with the response | |
//assumes transactional connections: connection is closed before callback | |
//callback should take f(err,data) where err == false indicates ok | |
console.log("dialing: "+target) | |
websocket = new WebSocket(target); | |
websocket.onopen = function(evt) {websocket.send(rawData)}; | |
websocket.onmessage = function(evt) { websocket.close(); typeof callback === 'function' && callback(false,evt.data) }; | |
websocket.onerror = function(evt) { websocket.close(); typeof callback === 'function' && callback(true,evt)}; | |
} | |
function inPeerlist(arr,peer){ | |
for(var i=0; i<arr.length; i++) { | |
if (arr[i]["id"] == peer["id"]) return true; | |
} | |
return false | |
} | |
function UrDHT(bootstraps){ | |
var self = this | |
if (!(this instanceof UrDHT)) return new UrDHT(bootstraps); | |
//above is paranoid magic copied off people who know what they are doing | |
self.peerList = bootstraps | |
self.lookup = function(id, callback){//find the best peer for an address | |
function _lookup(err, raw_newpeer){ | |
newpeer = JSON.parse(raw_newpeer) | |
if(!inPeerlist(self.peerList, newpeer)){ | |
self.peerList.push(newpeer); | |
console.log("discovered: "+raw_newpeer); | |
} | |
if(newpeer["id"] == peer["id"]){ | |
typeof callback === 'function' && callback(newpeer); | |
} | |
else{ | |
peer = newpeer | |
query = { | |
"method":"seek", | |
"id":id | |
} | |
query_raw = JSON.stringify(query) | |
wsDial(peer["wsAddr"],query_raw,_lookup) | |
} | |
}; | |
var peer = self.peerList[Math.floor(Math.random() * self.peerList.length)] | |
query = { | |
"method":"seek", | |
"id":id | |
} | |
query_raw = JSON.stringify(query) | |
wsDial(peer["wsAddr"],query_raw,_lookup) | |
}; | |
self.get = function(id, callback){ | |
function lookup_callback(nodeinfo){ | |
wsAddr = nodeinfo["wsAddr"] | |
query = { | |
"method":"get", | |
"id":id | |
} | |
query_raw = JSON.stringify(query) | |
wsDial(wsAddr, query_raw, callback) | |
} | |
self.lookup(id, lookup_callback) | |
}; | |
self.poll = function(id,t, callback){ | |
function lookup_callback(nodeinfo){ | |
console.log("done lookup, polling") | |
wsAddr = nodeinfo["wsAddr"] | |
query = { | |
"method":"poll", | |
"id":id, | |
"time":t | |
} | |
query_raw = JSON.stringify(query) | |
console.log(query_raw) | |
wsDial(wsAddr, query_raw, callback) | |
} | |
self.lookup(id, lookup_callback) | |
}; | |
self.store = function(id, val, callback){ | |
function lookup_callback(nodeinfo){ | |
wsAddr = nodeinfo["wsAddr"] | |
query = { | |
"method":"store", | |
"id":id, | |
"data":val | |
} | |
query_raw = JSON.stringify(query) | |
wsDial(wsAddr, query_raw, callback) | |
} | |
self.lookup(id, lookup_callback) | |
}; | |
self.post = function(id, val, callback){ | |
function lookup_callback(nodeinfo){ | |
wsAddr = nodeinfo["wsAddr"] | |
query = { | |
"method":"post", | |
"id":id, | |
"data":val | |
} | |
query_raw = JSON.stringify(query) | |
wsDial(wsAddr, query_raw, callback) | |
} | |
self.lookup(id, lookup_callback) | |
}; | |
}; | |
function _B58() | |
{ | |
Base58 = { | |
alphabet: "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz", | |
validRegex: /^[1-9A-HJ-NP-Za-km-z]+$/, | |
base: BigInteger.valueOf(58), | |
/** | |
* Convert a byte array to a base58-encoded string. | |
* | |
* Written by Mike Hearn for BitcoinJ. | |
* Copyright (c) 2011 Google Inc. | |
* | |
* Ported to JavaScript by Stefan Thomas. | |
*/ | |
encode: function (input) { | |
var bi = BigInteger.fromByteArrayUnsigned(input); | |
var chars = []; | |
while (bi.compareTo(B58.base) >= 0) { | |
var mod = bi.mod(B58.base); | |
chars.unshift(B58.alphabet[mod.intValue()]); | |
bi = bi.subtract(mod).divide(B58.base); | |
} | |
chars.unshift(B58.alphabet[bi.intValue()]); | |
// Convert leading zeros too. | |
for (var i = 0; i < input.length; i++) { | |
if (input[i] == 0x00) { | |
chars.unshift(B58.alphabet[0]); | |
} else break; | |
} | |
return chars.join(''); | |
}, | |
/** | |
* Convert a base58-encoded string to a byte array. | |
* | |
* Written by Mike Hearn for BitcoinJ. | |
* Copyright (c) 2011 Google Inc. | |
* | |
* Ported to JavaScript by Stefan Thomas. | |
*/ | |
decode: function (input) { | |
var bi = BigInteger.valueOf(0); | |
var leadingZerosNum = 0; | |
for (var i = input.length - 1; i >= 0; i--) { | |
var alphaIndex = B58.alphabet.indexOf(input[i]); | |
if (alphaIndex < 0) { | |
throw "Invalid character"; | |
} | |
bi = bi.add(BigInteger.valueOf(alphaIndex) | |
.multiply(B58.base.pow(input.length - 1 - i))); | |
// This counts leading zero bytes | |
if (input[i] == "1") leadingZerosNum++; | |
else leadingZerosNum = 0; | |
} | |
var bytes = bi.toByteArrayUnsigned(); | |
// Add leading zeros | |
while (leadingZerosNum-- > 0) bytes.unshift(0); | |
return bytes; | |
} | |
}; | |
return Base58; | |
}; | |
var B58 = _B58() | |
function hash(val){ | |
raw_hex = ""+CryptoJS.SHA256(val); | |
raw_bytes = [0x12,0x20] | |
for (var i = 0; i < raw_hex.length; i += 2) { | |
raw_bytes.push(parseInt("0x" + raw_hex.substr(i, 2),16)); | |
} | |
final_bytes = raw_bytes; | |
console.log(final_bytes) | |
return B58.encode(final_bytes) | |
} | |
</script> | |
<script/> | |
console.log("loaded and running") | |
dht = UrDHT([{"id":"QmdELUa85ULxs5bHNEqHaDjoR9hdw3a2uVJTeBUuV5dxir", "addr":"http://45.79.205.125:8000/", "wsAddr":"ws:/45.79.205.125:8001"} | |
]) | |
function post(){ | |
var timestamp = Math.floor((new Date).getTime()/(1000*60*20)).toString(); //change the room id once every 20 minutes | |
chanid = hash(document.getElementById("channel").value+timestamp) | |
val = document.getElementById("input").value | |
uname = document.getElementById("uname").value | |
dht.post(chanid,uname+": "+val,function(err,data){console.log("post was acked"); document.getElementById("input").value="";}) | |
} | |
document.getElementById ("button").addEventListener ("click", post, false); | |
var lasttime = 0 | |
function poll(){ | |
var timestamp = Math.floor((new Date).getTime()/(1000*60*20)).toString(); //change the room id once every 20 minutes | |
chanid = hash(document.getElementById("channel").value+timestamp) | |
console.log("polling") | |
dht.poll(chanid,lasttime, function(err,data){ | |
console.log(data) | |
objData = JSON.parse(data); | |
for (var i = 0; i < objData.length; i++) { | |
t = objData[i][0] | |
msg = objData[i][1] | |
if(t>lasttime){ | |
lasttime = t; | |
} | |
document.getElementById("output").innerHTML+= "\n"+msg | |
document.getElementById("output").scrollTop = document.getElementById("output").scrollHeight | |
} | |
}) | |
} | |
var intervalID = setInterval(poll, 3000); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment