Turns out we need to patch bigint...
This commit is contained in:
parent
c5f2c88f84
commit
ab934b8573
350
src/bigint.js
350
src/bigint.js
@ -1,17 +1,14 @@
|
|||||||
;(function (root, factory) {
|
;(function (root, factory) {
|
||||||
|
|
||||||
var Salsa20, crypto
|
|
||||||
if (typeof define === 'function' && define.amd) {
|
if (typeof define === 'function' && define.amd) {
|
||||||
define(['salsa20'], factory.bind(root, root.crypto))
|
define([], factory.bind(root, root.crypto || root.msCrypto))
|
||||||
} else if (typeof module !== 'undefined' && module.exports) {
|
} else if (typeof module !== 'undefined' && module.exports) {
|
||||||
Salsa20 = require('./salsa20.js')
|
module.exports = factory(require('crypto'))
|
||||||
crypto = require('crypto')
|
|
||||||
module.exports = factory(crypto, Salsa20)
|
|
||||||
} else {
|
} else {
|
||||||
root.BigInt = factory(root.crypto, root.Salsa20)
|
root.BigInt = factory(root.crypto || root.msCrypto)
|
||||||
}
|
}
|
||||||
|
|
||||||
}(this, function (crypto, Salsa20) {
|
}(this, function (crypto) {
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Big Integer Library v. 5.5
|
// Big Integer Library v. 5.5
|
||||||
@ -151,7 +148,7 @@
|
|||||||
// void linCombShift_(x,y,b,ys) //do x=x+b*(y<<(ys*bpe)) for bigInts x and y, and integers b and ys
|
// void linCombShift_(x,y,b,ys) //do x=x+b*(y<<(ys*bpe)) for bigInts x and y, and integers b and ys
|
||||||
// void mont_(x,y,n,np) //Montgomery multiplication (see comments where the function is defined)
|
// void mont_(x,y,n,np) //Montgomery multiplication (see comments where the function is defined)
|
||||||
// void multInt_(x,n) //do x=x*n where x is a bigInt and n is an integer.
|
// void multInt_(x,n) //do x=x*n where x is a bigInt and n is an integer.
|
||||||
// void rightShift_(x,n) //right shift bigInt x by n bits. 0 <= n < bpe. (This never overflows its array).
|
// void rightShift_(x,n) //right shift bigInt x by n bits. (This never overflows its array).
|
||||||
// void squareMod_(x,n) //do x=x*x mod n for bigInts x,n
|
// void squareMod_(x,n) //do x=x*x mod n for bigInts x,n
|
||||||
// void subShift_(x,y,ys) //do x=x-(y<<(ys*bpe)). Negative answers will be 2s complement.
|
// void subShift_(x,y,ys) //do x=x-(y<<(ys*bpe)). Negative answers will be 2s complement.
|
||||||
//
|
//
|
||||||
@ -195,18 +192,18 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
//globals
|
//globals
|
||||||
var bpe = 0 // bits stored per array element
|
|
||||||
var mask=0; //AND this with an array element to chop it down to bpe bits
|
// The number of significant bits in the fraction of a JavaScript
|
||||||
var radix=mask+1; //equals 2^bpe. A single 1 bit to the left of the last bit of mask.
|
// floating-point number is 52, independent of platform.
|
||||||
|
// See: https://github.com/arlolra/otr/issues/41
|
||||||
|
|
||||||
|
var bpe = 26; // bits stored per array element
|
||||||
|
var radix = 1 << bpe; // equals 2^bpe
|
||||||
|
var mask = radix - 1; // AND this with an array element to chop it down to bpe bits
|
||||||
|
|
||||||
//the digits for converting to different bases
|
//the digits for converting to different bases
|
||||||
var digitsStr='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_=!@#$%^&*()[]{}|;:,.<>/?`~ \\\'\"+-';
|
var digitsStr='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_=!@#$%^&*()[]{}|;:,.<>/?`~ \\\'\"+-';
|
||||||
|
|
||||||
//initialize the global variables
|
|
||||||
for (bpe = 0; (1<<(bpe+1)) > (1<<bpe); bpe++); // bpe = number of bits in the mantissa on this platform
|
|
||||||
bpe>>=1; // bpe = number of bits in one element of the array representing the bigInt
|
|
||||||
mask=(1<<bpe)-1; //AND the mask with an integer to get its bpe least significant bits
|
|
||||||
radix=mask+1; //2^bpe. a single 1 bit to the left of the first bit of mask
|
|
||||||
var one=int2bigInt(1,1,1); //constant used in powMod_()
|
var one=int2bigInt(1,1,1); //constant used in powMod_()
|
||||||
|
|
||||||
//the following global variables are scratchpad memory to
|
//the following global variables are scratchpad memory to
|
||||||
@ -940,11 +937,13 @@
|
|||||||
// q[i-ky]--;
|
// q[i-ky]--;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
y2=(ky>1 ? y[ky-2] : 0)*q[i-ky];
|
y2=(ky>1 ? y[ky-2] : 0)*q[i-ky];
|
||||||
c=y2>>bpe;
|
c=y2;
|
||||||
y2=y2 & mask;
|
y2=y2 & mask;
|
||||||
|
c = (c - y2) / radix;
|
||||||
y1=c+q[i-ky]*y[ky-1];
|
y1=c+q[i-ky]*y[ky-1];
|
||||||
c=y1>>bpe;
|
c=y1;
|
||||||
y1=y1 & mask;
|
y1=y1 & mask;
|
||||||
|
c = (c - y1) / radix;
|
||||||
|
|
||||||
if (c==r[i] ? y1==r[i-1] ? y2>(i>1 ? r[i-2] : 0) : y1>r[i-1] : c>r[i])
|
if (c==r[i] ? y1==r[i-1] ? y2>(i>1 ? r[i-2] : 0) : y1>r[i-1] : c>r[i])
|
||||||
q[i-ky]--;
|
q[i-ky]--;
|
||||||
@ -972,11 +971,12 @@
|
|||||||
c+=x[i];
|
c+=x[i];
|
||||||
b=0;
|
b=0;
|
||||||
if (c<0) {
|
if (c<0) {
|
||||||
b=-(c>>bpe);
|
b = c & mask;
|
||||||
|
b = -((c - b) / radix);
|
||||||
c+=b*radix;
|
c+=b*radix;
|
||||||
}
|
}
|
||||||
x[i]=c & mask;
|
x[i]=c & mask;
|
||||||
c=(c>>bpe)-b;
|
c = ((c - x[i]) / radix) - b;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1169,16 +1169,17 @@
|
|||||||
c+=x[i];
|
c+=x[i];
|
||||||
b=0;
|
b=0;
|
||||||
if (c<0) {
|
if (c<0) {
|
||||||
b=-(c>>bpe);
|
b = c & mask;
|
||||||
|
b = -((c - b) / radix);
|
||||||
c+=b*radix;
|
c+=b*radix;
|
||||||
}
|
}
|
||||||
x[i]=c & mask;
|
x[i]=c & mask;
|
||||||
c=(c>>bpe)-b;
|
c = ((c - x[i]) / radix) - b;
|
||||||
if (!c) return; //stop carrying as soon as the carry is zero
|
if (!c) return; //stop carrying as soon as the carry is zero
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//right shift bigInt x by n bits. 0 <= n < bpe.
|
//right shift bigInt x by n bits.
|
||||||
function rightShift_(x,n) {
|
function rightShift_(x,n) {
|
||||||
var i;
|
var i;
|
||||||
var k=Math.floor(n/bpe);
|
var k=Math.floor(n/bpe);
|
||||||
@ -1235,11 +1236,12 @@
|
|||||||
c+=x[i]*n;
|
c+=x[i]*n;
|
||||||
b=0;
|
b=0;
|
||||||
if (c<0) {
|
if (c<0) {
|
||||||
b=-(c>>bpe);
|
b = c & mask;
|
||||||
|
b = -((c - b) / radix);
|
||||||
c+=b*radix;
|
c+=b*radix;
|
||||||
}
|
}
|
||||||
x[i]=c & mask;
|
x[i]=c & mask;
|
||||||
c=(c>>bpe)-b;
|
c = ((c - x[i]) / radix) - b;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1263,12 +1265,12 @@
|
|||||||
for (c=0,i=0;i<k;i++) {
|
for (c=0,i=0;i<k;i++) {
|
||||||
c+=a*x[i]+b*y[i];
|
c+=a*x[i]+b*y[i];
|
||||||
x[i]=c & mask;
|
x[i]=c & mask;
|
||||||
c>>=bpe;
|
c = (c - x[i]) / radix;
|
||||||
}
|
}
|
||||||
for (i=k;i<kk;i++) {
|
for (i=k;i<kk;i++) {
|
||||||
c+=a*x[i];
|
c+=a*x[i];
|
||||||
x[i]=c & mask;
|
x[i]=c & mask;
|
||||||
c>>=bpe;
|
c = (c - x[i]) / radix;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1281,12 +1283,12 @@
|
|||||||
for (c=0,i=ys;i<k;i++) {
|
for (c=0,i=ys;i<k;i++) {
|
||||||
c+=x[i]+b*y[i-ys];
|
c+=x[i]+b*y[i-ys];
|
||||||
x[i]=c & mask;
|
x[i]=c & mask;
|
||||||
c>>=bpe;
|
c = (c - x[i]) / radix;
|
||||||
}
|
}
|
||||||
for (i=k;c && i<kk;i++) {
|
for (i=k;c && i<kk;i++) {
|
||||||
c+=x[i];
|
c+=x[i];
|
||||||
x[i]=c & mask;
|
x[i]=c & mask;
|
||||||
c>>=bpe;
|
c = (c - x[i]) / radix;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1299,12 +1301,12 @@
|
|||||||
for (c=0,i=ys;i<k;i++) {
|
for (c=0,i=ys;i<k;i++) {
|
||||||
c+=x[i]+y[i-ys];
|
c+=x[i]+y[i-ys];
|
||||||
x[i]=c & mask;
|
x[i]=c & mask;
|
||||||
c>>=bpe;
|
c = (c - x[i]) / radix;
|
||||||
}
|
}
|
||||||
for (i=k;c && i<kk;i++) {
|
for (i=k;c && i<kk;i++) {
|
||||||
c+=x[i];
|
c+=x[i];
|
||||||
x[i]=c & mask;
|
x[i]=c & mask;
|
||||||
c>>=bpe;
|
c = (c - x[i]) / radix;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1317,12 +1319,12 @@
|
|||||||
for (c=0,i=ys;i<k;i++) {
|
for (c=0,i=ys;i<k;i++) {
|
||||||
c+=x[i]-y[i-ys];
|
c+=x[i]-y[i-ys];
|
||||||
x[i]=c & mask;
|
x[i]=c & mask;
|
||||||
c>>=bpe;
|
c = (c - x[i]) / radix;
|
||||||
}
|
}
|
||||||
for (i=k;c && i<kk;i++) {
|
for (i=k;c && i<kk;i++) {
|
||||||
c+=x[i];
|
c+=x[i];
|
||||||
x[i]=c & mask;
|
x[i]=c & mask;
|
||||||
c>>=bpe;
|
c = (c - x[i]) / radix;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1335,12 +1337,12 @@
|
|||||||
for (c=0,i=0;i<k;i++) {
|
for (c=0,i=0;i<k;i++) {
|
||||||
c+=x[i]-y[i];
|
c+=x[i]-y[i];
|
||||||
x[i]=c & mask;
|
x[i]=c & mask;
|
||||||
c>>=bpe;
|
c = (c - x[i]) / radix;
|
||||||
}
|
}
|
||||||
for (i=k;c && i<x.length;i++) {
|
for (i=k;c && i<x.length;i++) {
|
||||||
c+=x[i];
|
c+=x[i];
|
||||||
x[i]=c & mask;
|
x[i]=c & mask;
|
||||||
c>>=bpe;
|
c = (c - x[i]) / radix;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1352,12 +1354,12 @@
|
|||||||
for (c=0,i=0;i<k;i++) {
|
for (c=0,i=0;i<k;i++) {
|
||||||
c+=x[i]+y[i];
|
c+=x[i]+y[i];
|
||||||
x[i]=c & mask;
|
x[i]=c & mask;
|
||||||
c>>=bpe;
|
c = (c - x[i]) / radix;
|
||||||
}
|
}
|
||||||
for (i=k;c && i<x.length;i++) {
|
for (i=k;c && i<x.length;i++) {
|
||||||
c+=x[i];
|
c+=x[i];
|
||||||
x[i]=c & mask;
|
x[i]=c & mask;
|
||||||
c>>=bpe;
|
c = (c - x[i]) / radix;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1409,11 +1411,11 @@
|
|||||||
for (i=0;i<kx;i++) {
|
for (i=0;i<kx;i++) {
|
||||||
c=s0[2*i]+x[i]*x[i];
|
c=s0[2*i]+x[i]*x[i];
|
||||||
s0[2*i]=c & mask;
|
s0[2*i]=c & mask;
|
||||||
c>>=bpe;
|
c = (c - s0[2*i]) / radix;
|
||||||
for (j=i+1;j<kx;j++) {
|
for (j=i+1;j<kx;j++) {
|
||||||
c=s0[i+j]+2*x[i]*x[j]+c;
|
c=s0[i+j]+2*x[i]*x[j]+c;
|
||||||
s0[i+j]=(c & mask);
|
s0[i+j]=(c & mask);
|
||||||
c>>=bpe;
|
c = (c - s0[i+j]) / radix;
|
||||||
}
|
}
|
||||||
s0[i+kx]=c;
|
s0[i+kx]=c;
|
||||||
}
|
}
|
||||||
@ -1497,7 +1499,7 @@
|
|||||||
// n is odd
|
// n is odd
|
||||||
// np = -(n^(-1)) mod radix
|
// np = -(n^(-1)) mod radix
|
||||||
function mont_(x,y,n,np) {
|
function mont_(x,y,n,np) {
|
||||||
var i,j,c,ui,t,ks;
|
var i,j,c,ui,t,t2,ks;
|
||||||
var kn=n.length;
|
var kn=n.length;
|
||||||
var ky=y.length;
|
var ky=y.length;
|
||||||
|
|
||||||
@ -1514,24 +1516,35 @@
|
|||||||
for (i=0; i<kn; i++) {
|
for (i=0; i<kn; i++) {
|
||||||
t=sa[0]+x[i]*y[0];
|
t=sa[0]+x[i]*y[0];
|
||||||
ui=((t & mask) * np) & mask; //the inner "& mask" was needed on Safari (but not MSIE) at one time
|
ui=((t & mask) * np) & mask; //the inner "& mask" was needed on Safari (but not MSIE) at one time
|
||||||
c=(t+ui*n[0]) >> bpe;
|
c=(t+ui*n[0]);
|
||||||
|
c = (c - (c & mask)) / radix;
|
||||||
t=x[i];
|
t=x[i];
|
||||||
|
|
||||||
//do sa=(sa+x[i]*y+ui*n)/b where b=2**bpe. Loop is unrolled 5-fold for speed
|
//do sa=(sa+x[i]*y+ui*n)/b where b=2**bpe. Loop is unrolled 5-fold for speed
|
||||||
j=1;
|
j=1;
|
||||||
for (;j<ky-4;) { c+=sa[j]+ui*n[j]+t*y[j]; sa[j-1]=c & mask; c>>=bpe; j++;
|
for (;j<ky-4;) {
|
||||||
c+=sa[j]+ui*n[j]+t*y[j]; sa[j-1]=c & mask; c>>=bpe; j++;
|
c+=sa[j]+ui*n[j]+t*y[j]; t2=sa[j-1]=c & mask; c=(c-t2)/radix; j++;
|
||||||
c+=sa[j]+ui*n[j]+t*y[j]; sa[j-1]=c & mask; c>>=bpe; j++;
|
c+=sa[j]+ui*n[j]+t*y[j]; t2=sa[j-1]=c & mask; c=(c-t2)/radix; j++;
|
||||||
c+=sa[j]+ui*n[j]+t*y[j]; sa[j-1]=c & mask; c>>=bpe; j++;
|
c+=sa[j]+ui*n[j]+t*y[j]; t2=sa[j-1]=c & mask; c=(c-t2)/radix; j++;
|
||||||
c+=sa[j]+ui*n[j]+t*y[j]; sa[j-1]=c & mask; c>>=bpe; j++; }
|
c+=sa[j]+ui*n[j]+t*y[j]; t2=sa[j-1]=c & mask; c=(c-t2)/radix; j++;
|
||||||
for (;j<ky;) { c+=sa[j]+ui*n[j]+t*y[j]; sa[j-1]=c & mask; c>>=bpe; j++; }
|
c+=sa[j]+ui*n[j]+t*y[j]; t2=sa[j-1]=c & mask; c=(c-t2)/radix; j++;
|
||||||
for (;j<kn-4;) { c+=sa[j]+ui*n[j]; sa[j-1]=c & mask; c>>=bpe; j++;
|
}
|
||||||
c+=sa[j]+ui*n[j]; sa[j-1]=c & mask; c>>=bpe; j++;
|
for (;j<ky;) {
|
||||||
c+=sa[j]+ui*n[j]; sa[j-1]=c & mask; c>>=bpe; j++;
|
c+=sa[j]+ui*n[j]+t*y[j]; t2=sa[j-1]=c & mask; c=(c-t2)/radix; j++;
|
||||||
c+=sa[j]+ui*n[j]; sa[j-1]=c & mask; c>>=bpe; j++;
|
}
|
||||||
c+=sa[j]+ui*n[j]; sa[j-1]=c & mask; c>>=bpe; j++; }
|
for (;j<kn-4;) {
|
||||||
for (;j<kn;) { c+=sa[j]+ui*n[j]; sa[j-1]=c & mask; c>>=bpe; j++; }
|
c+=sa[j]+ui*n[j]; t2=sa[j-1]=c & mask; c=(c-t2)/radix; j++;
|
||||||
for (;j<ks;) { c+=sa[j]; sa[j-1]=c & mask; c>>=bpe; j++; }
|
c+=sa[j]+ui*n[j]; t2=sa[j-1]=c & mask; c=(c-t2)/radix; j++;
|
||||||
|
c+=sa[j]+ui*n[j]; t2=sa[j-1]=c & mask; c=(c-t2)/radix; j++;
|
||||||
|
c+=sa[j]+ui*n[j]; t2=sa[j-1]=c & mask; c=(c-t2)/radix; j++;
|
||||||
|
c+=sa[j]+ui*n[j]; t2=sa[j-1]=c & mask; c=(c-t2)/radix; j++;
|
||||||
|
}
|
||||||
|
for (;j<kn;) {
|
||||||
|
c+=sa[j]+ui*n[j]; t2=sa[j-1]=c & mask; c=(c-t2)/radix; j++;
|
||||||
|
}
|
||||||
|
for (;j<ks;) {
|
||||||
|
c+=sa[j]; t2=sa[j-1]=c & mask; c=(c-t2)/radix; j++;
|
||||||
|
}
|
||||||
sa[j-1]=c & mask;
|
sa[j-1]=c & mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1541,9 +1554,120 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// otr.js stuff
|
// otr.js additions
|
||||||
|
|
||||||
var BigInt = {
|
|
||||||
|
// computes num / den mod n
|
||||||
|
function divMod(num, den, n) {
|
||||||
|
return multMod(num, inverseMod(den, n), n)
|
||||||
|
}
|
||||||
|
|
||||||
|
// computes one - two mod n
|
||||||
|
function subMod(one, two, n) {
|
||||||
|
one = mod(one, n)
|
||||||
|
two = mod(two, n)
|
||||||
|
if (greater(two, one)) one = add(one, n)
|
||||||
|
return sub(one, two)
|
||||||
|
}
|
||||||
|
|
||||||
|
// computes 2^m as a bigInt
|
||||||
|
function twoToThe(m) {
|
||||||
|
var b = Math.floor(m / bpe) + 2
|
||||||
|
var t = new Array(b)
|
||||||
|
for (var i = 0; i < b; i++) t[i] = 0
|
||||||
|
t[b - 2] = 1 << (m % bpe)
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
// cache these results for faster lookup
|
||||||
|
var _num2bin = (function () {
|
||||||
|
var i = 0, _num2bin= {}
|
||||||
|
for (; i < 0x100; ++i) {
|
||||||
|
_num2bin[i] = String.fromCharCode(i) // 0 -> "\00"
|
||||||
|
}
|
||||||
|
return _num2bin
|
||||||
|
}())
|
||||||
|
|
||||||
|
// serialize a bigInt to an ascii string
|
||||||
|
// padded up to pad length
|
||||||
|
function bigInt2bits(bi, pad) {
|
||||||
|
pad || (pad = 0)
|
||||||
|
bi = dup(bi)
|
||||||
|
var ba = ''
|
||||||
|
while (!isZero(bi)) {
|
||||||
|
ba = _num2bin[bi[0] & 0xff] + ba
|
||||||
|
rightShift_(bi, 8)
|
||||||
|
}
|
||||||
|
while (ba.length < pad) {
|
||||||
|
ba = '\x00' + ba
|
||||||
|
}
|
||||||
|
return ba
|
||||||
|
}
|
||||||
|
|
||||||
|
// converts a byte array to a bigInt
|
||||||
|
function ba2bigInt(data) {
|
||||||
|
var mpi = str2bigInt('0', 10, data.length)
|
||||||
|
data.forEach(function (d, i) {
|
||||||
|
if (i) leftShift_(mpi, 8)
|
||||||
|
mpi[0] |= d
|
||||||
|
})
|
||||||
|
return mpi
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns a function that returns an array of n bytes
|
||||||
|
var randomBytes = (function () {
|
||||||
|
|
||||||
|
// in node
|
||||||
|
if ( typeof crypto !== 'undefined' &&
|
||||||
|
typeof crypto.randomBytes === 'function' ) {
|
||||||
|
return function (n) {
|
||||||
|
try {
|
||||||
|
var buf = crypto.randomBytes(n)
|
||||||
|
} catch (e) { throw e }
|
||||||
|
return Array.prototype.slice.call(buf, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// in browser
|
||||||
|
else if ( typeof crypto !== 'undefined' &&
|
||||||
|
typeof crypto.getRandomValues === 'function' ) {
|
||||||
|
return function (n) {
|
||||||
|
var buf = new Uint8Array(n)
|
||||||
|
crypto.getRandomValues(buf)
|
||||||
|
return Array.prototype.slice.call(buf, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// err
|
||||||
|
else {
|
||||||
|
throw new Error('Keys should not be generated without CSPRNG.')
|
||||||
|
}
|
||||||
|
|
||||||
|
}())
|
||||||
|
|
||||||
|
// Salsa 20 in webworker needs a 40 byte seed
|
||||||
|
function getSeed() {
|
||||||
|
return randomBytes(40)
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns a single random byte
|
||||||
|
function randomByte() {
|
||||||
|
return randomBytes(1)[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns a k-bit random integer
|
||||||
|
function randomBitInt(k) {
|
||||||
|
if (k > 31) throw new Error("Too many bits.")
|
||||||
|
var i = 0, r = 0
|
||||||
|
var b = Math.floor(k / 8)
|
||||||
|
var mask = (1 << (k % 8)) - 1
|
||||||
|
if (mask) r = randomByte() & mask
|
||||||
|
for (; i < b; i++)
|
||||||
|
r = (256 * r) + randomByte()
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
str2bigInt : str2bigInt
|
str2bigInt : str2bigInt
|
||||||
, bigInt2str : bigInt2str
|
, bigInt2str : bigInt2str
|
||||||
, int2bigInt : int2bigInt
|
, int2bigInt : int2bigInt
|
||||||
@ -1556,130 +1680,26 @@
|
|||||||
, equalsInt : equalsInt
|
, equalsInt : equalsInt
|
||||||
, sub : sub
|
, sub : sub
|
||||||
, mod : mod
|
, mod : mod
|
||||||
, mod_ : mod_
|
|
||||||
, modInt : modInt
|
, modInt : modInt
|
||||||
, mult : mult
|
, mult : mult
|
||||||
, divInt_ : divInt_
|
, divInt_ : divInt_
|
||||||
, rightShift_ : rightShift_
|
, rightShift_ : rightShift_
|
||||||
, leftShift_ : leftShift_
|
|
||||||
, dup : dup
|
, dup : dup
|
||||||
, greater : greater
|
, greater : greater
|
||||||
, add : add
|
, add : add
|
||||||
, addInt : addInt
|
|
||||||
, addInt_ : addInt_
|
|
||||||
, isZero : isZero
|
, isZero : isZero
|
||||||
, bitSize : bitSize
|
, bitSize : bitSize
|
||||||
, randTruePrime : randTruePrime
|
|
||||||
, millerRabin : millerRabin
|
, millerRabin : millerRabin
|
||||||
, divide_ : divide_
|
, divide_ : divide_
|
||||||
, trim : trim
|
, trim : trim
|
||||||
, expand : expand
|
|
||||||
, bpe : bpe
|
|
||||||
, primes : primes
|
, primes : primes
|
||||||
, findPrimes : findPrimes
|
, findPrimes : findPrimes
|
||||||
, getSeed : getSeed
|
, getSeed : getSeed
|
||||||
|
, divMod : divMod
|
||||||
|
, subMod : subMod
|
||||||
|
, twoToThe : twoToThe
|
||||||
|
, bigInt2bits : bigInt2bits
|
||||||
|
, ba2bigInt : ba2bigInt
|
||||||
}
|
}
|
||||||
|
|
||||||
// from http://davidbau.com/encode/seedrandom.js
|
|
||||||
|
|
||||||
var randomBitInt
|
|
||||||
|
|
||||||
function seedRand(buf) {
|
|
||||||
|
|
||||||
var state = new Salsa20([
|
|
||||||
buf[ 0], buf[ 1], buf[ 2], buf[ 3], buf[ 4], buf[ 5], buf[ 6], buf[ 7],
|
|
||||||
buf[ 8], buf[ 9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15],
|
|
||||||
buf[16], buf[17], buf[18], buf[19], buf[20], buf[21], buf[22], buf[23],
|
|
||||||
buf[24], buf[25], buf[26], buf[27], buf[28], buf[29], buf[30], buf[31]
|
|
||||||
],[
|
|
||||||
buf[32], buf[33], buf[34], buf[35], buf[36], buf[37], buf[38], buf[39]
|
|
||||||
])
|
|
||||||
|
|
||||||
var width = 256
|
|
||||||
, chunks = 6
|
|
||||||
, significance = Math.pow(2, 52)
|
|
||||||
, overflow = significance * 2
|
|
||||||
|
|
||||||
function numerator() {
|
|
||||||
var bytes = state.getBytes(chunks)
|
|
||||||
var i = 0, r = 0
|
|
||||||
for (; i < chunks; i++) {
|
|
||||||
r = r * width + bytes[i]
|
|
||||||
}
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
function randomByte() {
|
|
||||||
return state.getBytes(1)[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
randomBitInt = function (k) {
|
|
||||||
if (k > 31) throw new Error("Too many bits.")
|
|
||||||
var i = 0, r = 0
|
|
||||||
var b = Math.floor(k / 8)
|
|
||||||
var mask = (1 << (k % 8)) - 1
|
|
||||||
if (mask) r = randomByte() & mask
|
|
||||||
for (; i < b; i++)
|
|
||||||
r = (256 * r) + randomByte()
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
// This function returns a random double in [0, 1) that contains
|
|
||||||
// randomness in every bit of the mantissa of the IEEE 754 value.
|
|
||||||
|
|
||||||
return function () { // Closure to return a random double:
|
|
||||||
var n = numerator() // Start with a numerator n < 2 ^ 48
|
|
||||||
, d = Math.pow(width, chunks) // and denominator d = 2 ^ 48.
|
|
||||||
, x = 0 // and no 'extra last byte'.
|
|
||||||
while (n < significance) { // Fill up all significant digits by
|
|
||||||
n = (n + x) * width // shifting numerator and
|
|
||||||
d *= width // denominator and generating a
|
|
||||||
x = randomByte() // new least-significant-byte.
|
|
||||||
}
|
|
||||||
while (n >= overflow) { // To avoid rounding up, before adding
|
|
||||||
n /= 2 // last byte, shift everything
|
|
||||||
d /= 2 // right using integer math until
|
|
||||||
x >>>= 1 // we have exactly the desired bits.
|
|
||||||
}
|
|
||||||
return (n + x) / d // Form the number within [0, 1).
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSeed() {
|
|
||||||
var buf
|
|
||||||
if ( (typeof crypto !== 'undefined') &&
|
|
||||||
(typeof crypto.randomBytes === 'function')
|
|
||||||
) {
|
|
||||||
try {
|
|
||||||
buf = crypto.randomBytes(40)
|
|
||||||
} catch (e) { throw e }
|
|
||||||
} else if ( (typeof crypto !== 'undefined') &&
|
|
||||||
(typeof crypto.getRandomValues === 'function')
|
|
||||||
) {
|
|
||||||
buf = new Uint8Array(40)
|
|
||||||
crypto.getRandomValues(buf)
|
|
||||||
} else {
|
|
||||||
throw new Error('Keys should not be generated without CSPRNG.')
|
|
||||||
}
|
|
||||||
return Array.prototype.slice.call(buf, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
;(function seed() {
|
|
||||||
var HAS_CSPRNG = ((typeof crypto !== 'undefined') &&
|
|
||||||
((typeof crypto.randomBytes === 'function') ||
|
|
||||||
(typeof crypto.getRandomValues === 'function')
|
|
||||||
));
|
|
||||||
if (!HAS_CSPRNG) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Math.random = seedRand(getSeed())
|
|
||||||
|
|
||||||
// reseed every 5 mins (not in ww)
|
|
||||||
if ( typeof setTimeout === 'function' && typeof document !== 'undefined' )
|
|
||||||
setTimeout(seed, 5 * 60 * 1000)
|
|
||||||
|
|
||||||
}())
|
|
||||||
|
|
||||||
return BigInt
|
|
||||||
}))
|
}))
|
||||||
|
Loading…
Reference in New Issue
Block a user