better README
This commit is contained in:
parent
12a78d9495
commit
de00327fd8
|
@ -2,9 +2,7 @@
|
|||
|
||||
Utils for working with cryptography using native JS (stage 3) implementation of BigInt. It includes some extra functions to work with modular arithmetics along with secure random numbers and a very fast strong probable prime generation/testing (parallelised multi-threaded Miller-Rabin primality test). It can be used with Node.js (>=10.4.0) and [Web Browsers supporting BigInt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#Browser_compatibility).
|
||||
|
||||
_The operations supported on BigInts are not constant time. BigInt can be therefore **[unsuitable for use in cryptography](https://www.chosenplaintext.ca/articles/beginners-guide-constant-time-cryptography.html)**_
|
||||
|
||||
Many platforms provide native support for cryptography, such as [webcrypto](https://w3c.github.io/webcrypto/Overview.html) or [node crypto](https://nodejs.org/dist/latest/docs/api/crypto.html).
|
||||
_The operations supported on BigInts are not constant time. BigInt can be therefore **[unsuitable for use in cryptography](https://www.chosenplaintext.ca/articles/beginners-guide-constant-time-cryptography.html).** Many platforms provide native support for cryptography, such as [Web Cryptography API](https://w3c.github.io/webcrypto/) or [Node.js Crypto](https://nodejs.org/dist/latest/docs/api/crypto.html)._
|
||||
|
||||
## Installation
|
||||
bigint-crypto-utils is distributed for [web browsers supporting BigInt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#Browser_compatibility) as an ES6 module or a IIFE file, and for Node.js (>=10.4.0) as a CJS module.
|
||||
|
@ -15,7 +13,7 @@ npm install bigint-crypto-utils
|
|||
```
|
||||
NPM installation defaults to the ES6 module for browsers and the CJS for Node.js.
|
||||
|
||||
For web browsers, you can also directly download the [IIFE file](https://raw.githubusercontent.com/juanelas/bigint-crypto-utils/master/dist/bigint-crypto-utils-latest.browser.min.js) or the [ES6 module](https://raw.githubusercontent.com/juanelas/bigint-crypto-utils/master/dist/bigint-crypto-utils-latest.browser.mod.min.js) from GitHub.
|
||||
For web browsers, you can also directly download the minimised version of the [IIFE file](https://raw.githubusercontent.com/juanelas/bigint-crypto-utils/master/dist/bigint-crypto-utils-latest.browser.min.js) or the [ES6 module](https://raw.githubusercontent.com/juanelas/bigint-crypto-utils/master/dist/bigint-crypto-utils-latest.browser.mod.min.js) from GitHub.
|
||||
|
||||
## Usage example
|
||||
|
||||
|
|
74
README.md
74
README.md
|
@ -2,9 +2,7 @@
|
|||
|
||||
Utils for working with cryptography using native JS (stage 3) implementation of BigInt. It includes some extra functions to work with modular arithmetics along with secure random numbers and a very fast strong probable prime generation/testing (parallelised multi-threaded Miller-Rabin primality test). It can be used with Node.js (>=10.4.0) and [Web Browsers supporting BigInt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#Browser_compatibility).
|
||||
|
||||
_The operations supported on BigInts are not constant time. BigInt can be therefore **[unsuitable for use in cryptography](https://www.chosenplaintext.ca/articles/beginners-guide-constant-time-cryptography.html)**_
|
||||
|
||||
Many platforms provide native support for cryptography, such as [webcrypto](https://w3c.github.io/webcrypto/Overview.html) or [node crypto](https://nodejs.org/dist/latest/docs/api/crypto.html).
|
||||
_The operations supported on BigInts are not constant time. BigInt can be therefore **[unsuitable for use in cryptography](https://www.chosenplaintext.ca/articles/beginners-guide-constant-time-cryptography.html).** Many platforms provide native support for cryptography, such as [Web Cryptography API](https://w3c.github.io/webcrypto/) or [Node.js Crypto](https://nodejs.org/dist/latest/docs/api/crypto.html)._
|
||||
|
||||
## Installation
|
||||
bigint-crypto-utils is distributed for [web browsers supporting BigInt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#Browser_compatibility) as an ES6 module or a IIFE file, and for Node.js (>=10.4.0) as a CJS module.
|
||||
|
@ -15,7 +13,7 @@ npm install bigint-crypto-utils
|
|||
```
|
||||
NPM installation defaults to the ES6 module for browsers and the CJS for Node.js.
|
||||
|
||||
For web browsers, you can also directly download the [IIFE file](https://raw.githubusercontent.com/juanelas/bigint-crypto-utils/master/dist/bigint-crypto-utils-latest.browser.min.js) or the [ES6 module](https://raw.githubusercontent.com/juanelas/bigint-crypto-utils/master/dist/bigint-crypto-utils-latest.browser.mod.min.js) from GitHub.
|
||||
For web browsers, you can also directly download the minimised version of the [IIFE file](https://raw.githubusercontent.com/juanelas/bigint-crypto-utils/master/dist/bigint-crypto-utils-latest.browser.min.js) or the [ES6 module](https://raw.githubusercontent.com/juanelas/bigint-crypto-utils/master/dist/bigint-crypto-utils-latest.browser.mod.min.js) from GitHub.
|
||||
|
||||
## Usage example
|
||||
|
||||
|
@ -79,43 +77,43 @@ From a browser, you can just load the module in a html page as:
|
|||
|
||||
# bigint-crypto-utils JS Doc
|
||||
|
||||
## Constants
|
||||
## Functions
|
||||
|
||||
<dl>
|
||||
<dt><a href="#abs">abs</a> ⇒ <code>bigint</code></dt>
|
||||
<dt><a href="#abs">abs(a)</a> ⇒ <code>bigint</code></dt>
|
||||
<dd><p>Absolute value. abs(a)==a if a>=0. abs(a)==-a if a<0</p>
|
||||
</dd>
|
||||
<dt><a href="#eGcd">eGcd</a> ⇒ <code><a href="#egcdReturn">egcdReturn</a></code></dt>
|
||||
<dt><a href="#eGcd">eGcd(a, b)</a> ⇒ <code><a href="#egcdReturn">egcdReturn</a></code></dt>
|
||||
<dd><p>An iterative implementation of the extended euclidean algorithm or extended greatest common divisor algorithm.
|
||||
Take positive integers a, b as input, and return a triple (g, x, y), such that ax + by = g = gcd(a, b).</p>
|
||||
</dd>
|
||||
<dt><a href="#gcd">gcd</a> ⇒ <code>bigint</code></dt>
|
||||
<dt><a href="#gcd">gcd(a, b)</a> ⇒ <code>bigint</code></dt>
|
||||
<dd><p>Greatest-common divisor of two integers based on the iterative binary algorithm.</p>
|
||||
</dd>
|
||||
<dt><a href="#isProbablyPrime">isProbablyPrime</a> ⇒ <code>Promise</code></dt>
|
||||
<dt><a href="#isProbablyPrime">isProbablyPrime(w, iterations)</a> ⇒ <code>Promise</code></dt>
|
||||
<dd><p>The test first tries if any of the first 250 small primes are a factor of the input number and then passes several iterations of Miller-Rabin Probabilistic Primality Test (FIPS 186-4 C.3.1)</p>
|
||||
</dd>
|
||||
<dt><a href="#lcm">lcm</a> ⇒ <code>bigint</code></dt>
|
||||
<dt><a href="#lcm">lcm(a, b)</a> ⇒ <code>bigint</code></dt>
|
||||
<dd><p>The least common multiple computed as abs(a*b)/gcd(a,b)</p>
|
||||
</dd>
|
||||
<dt><a href="#modInv">modInv</a> ⇒ <code>bigint</code></dt>
|
||||
<dt><a href="#modInv">modInv(a, n)</a> ⇒ <code>bigint</code></dt>
|
||||
<dd><p>Modular inverse.</p>
|
||||
</dd>
|
||||
<dt><a href="#modPow">modPow</a> ⇒ <code>bigint</code></dt>
|
||||
<dt><a href="#modPow">modPow(a, b, n)</a> ⇒ <code>bigint</code></dt>
|
||||
<dd><p>Modular exponentiation a**b mod n</p>
|
||||
</dd>
|
||||
<dt><a href="#prime">prime</a> ⇒ <code>Promise</code></dt>
|
||||
<dt><a href="#prime">prime(bitLength, iterations)</a> ⇒ <code>Promise</code></dt>
|
||||
<dd><p>A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator.
|
||||
The browser version uses web workers to parallelise prime look up. Therefore, it does not lock the UI
|
||||
main process, and it can be much faster (if several cores or cpu are available).</p>
|
||||
</dd>
|
||||
<dt><a href="#randBetween">randBetween</a> ⇒ <code>Promise</code></dt>
|
||||
<dt><a href="#randBetween">randBetween(max, min)</a> ⇒ <code>Promise</code></dt>
|
||||
<dd><p>Returns a cryptographically secure random integer between [min,max]</p>
|
||||
</dd>
|
||||
<dt><a href="#randBytes">randBytes</a> ⇒ <code>Promise</code></dt>
|
||||
<dt><a href="#randBytes">randBytes(byteLength, forceLength)</a> ⇒ <code>Promise</code></dt>
|
||||
<dd><p>Secure random bytes for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()</p>
|
||||
</dd>
|
||||
<dt><a href="#toZn">toZn</a> ⇒ <code>bigint</code></dt>
|
||||
<dt><a href="#toZn">toZn(a, n)</a> ⇒ <code>bigint</code></dt>
|
||||
<dd><p>Finds the smallest positive element that is congruent to a in modulo n</p>
|
||||
</dd>
|
||||
</dl>
|
||||
|
@ -130,10 +128,10 @@ main process, and it can be much faster (if several cores or cpu are available).
|
|||
|
||||
<a name="abs"></a>
|
||||
|
||||
## abs ⇒ <code>bigint</code>
|
||||
## abs(a) ⇒ <code>bigint</code>
|
||||
Absolute value. abs(a)==a if a>=0. abs(a)==-a if a<0
|
||||
|
||||
**Kind**: global constant
|
||||
**Kind**: global function
|
||||
**Returns**: <code>bigint</code> - the absolute value of a
|
||||
|
||||
| Param | Type |
|
||||
|
@ -142,11 +140,11 @@ Absolute value. abs(a)==a if a>=0. abs(a)==-a if a<0
|
|||
|
||||
<a name="eGcd"></a>
|
||||
|
||||
## eGcd ⇒ [<code>egcdReturn</code>](#egcdReturn)
|
||||
## eGcd(a, b) ⇒ [<code>egcdReturn</code>](#egcdReturn)
|
||||
An iterative implementation of the extended euclidean algorithm or extended greatest common divisor algorithm.
|
||||
Take positive integers a, b as input, and return a triple (g, x, y), such that ax + by = g = gcd(a, b).
|
||||
|
||||
**Kind**: global constant
|
||||
**Kind**: global function
|
||||
|
||||
| Param | Type |
|
||||
| --- | --- |
|
||||
|
@ -155,10 +153,10 @@ Take positive integers a, b as input, and return a triple (g, x, y), such that a
|
|||
|
||||
<a name="gcd"></a>
|
||||
|
||||
## gcd ⇒ <code>bigint</code>
|
||||
## gcd(a, b) ⇒ <code>bigint</code>
|
||||
Greatest-common divisor of two integers based on the iterative binary algorithm.
|
||||
|
||||
**Kind**: global constant
|
||||
**Kind**: global function
|
||||
**Returns**: <code>bigint</code> - The greatest common divisor of a and b
|
||||
|
||||
| Param | Type |
|
||||
|
@ -168,10 +166,10 @@ Greatest-common divisor of two integers based on the iterative binary algorithm.
|
|||
|
||||
<a name="isProbablyPrime"></a>
|
||||
|
||||
## isProbablyPrime ⇒ <code>Promise</code>
|
||||
## isProbablyPrime(w, iterations) ⇒ <code>Promise</code>
|
||||
The test first tries if any of the first 250 small primes are a factor of the input number and then passes several iterations of Miller-Rabin Probabilistic Primality Test (FIPS 186-4 C.3.1)
|
||||
|
||||
**Kind**: global constant
|
||||
**Kind**: global function
|
||||
**Returns**: <code>Promise</code> - A promise that resolve to a boolean that is either true (a probably prime number) or false (definitely composite)
|
||||
|
||||
| Param | Type | Description |
|
||||
|
@ -181,10 +179,10 @@ The test first tries if any of the first 250 small primes are a factor of the in
|
|||
|
||||
<a name="lcm"></a>
|
||||
|
||||
## lcm ⇒ <code>bigint</code>
|
||||
## lcm(a, b) ⇒ <code>bigint</code>
|
||||
The least common multiple computed as abs(a*b)/gcd(a,b)
|
||||
|
||||
**Kind**: global constant
|
||||
**Kind**: global function
|
||||
**Returns**: <code>bigint</code> - The least common multiple of a and b
|
||||
|
||||
| Param | Type |
|
||||
|
@ -194,10 +192,10 @@ The least common multiple computed as abs(a*b)/gcd(a,b)
|
|||
|
||||
<a name="modInv"></a>
|
||||
|
||||
## modInv ⇒ <code>bigint</code>
|
||||
## modInv(a, n) ⇒ <code>bigint</code>
|
||||
Modular inverse.
|
||||
|
||||
**Kind**: global constant
|
||||
**Kind**: global function
|
||||
**Returns**: <code>bigint</code> - the inverse modulo n
|
||||
|
||||
| Param | Type | Description |
|
||||
|
@ -207,10 +205,10 @@ Modular inverse.
|
|||
|
||||
<a name="modPow"></a>
|
||||
|
||||
## modPow ⇒ <code>bigint</code>
|
||||
## modPow(a, b, n) ⇒ <code>bigint</code>
|
||||
Modular exponentiation a**b mod n
|
||||
|
||||
**Kind**: global constant
|
||||
**Kind**: global function
|
||||
**Returns**: <code>bigint</code> - a**b mod n
|
||||
|
||||
| Param | Type | Description |
|
||||
|
@ -221,12 +219,12 @@ Modular exponentiation a**b mod n
|
|||
|
||||
<a name="prime"></a>
|
||||
|
||||
## prime ⇒ <code>Promise</code>
|
||||
## prime(bitLength, iterations) ⇒ <code>Promise</code>
|
||||
A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator.
|
||||
The browser version uses web workers to parallelise prime look up. Therefore, it does not lock the UI
|
||||
main process, and it can be much faster (if several cores or cpu are available).
|
||||
|
||||
**Kind**: global constant
|
||||
**Kind**: global function
|
||||
**Returns**: <code>Promise</code> - A promise that resolves to a bigint probable prime of bitLength bits
|
||||
|
||||
| Param | Type | Description |
|
||||
|
@ -236,10 +234,10 @@ main process, and it can be much faster (if several cores or cpu are available).
|
|||
|
||||
<a name="randBetween"></a>
|
||||
|
||||
## randBetween ⇒ <code>Promise</code>
|
||||
## randBetween(max, min) ⇒ <code>Promise</code>
|
||||
Returns a cryptographically secure random integer between [min,max]
|
||||
|
||||
**Kind**: global constant
|
||||
**Kind**: global function
|
||||
**Returns**: <code>Promise</code> - A promise that resolves to a cryptographically secure random bigint between [min,max]
|
||||
|
||||
| Param | Type | Description |
|
||||
|
@ -249,10 +247,10 @@ Returns a cryptographically secure random integer between [min,max]
|
|||
|
||||
<a name="randBytes"></a>
|
||||
|
||||
## randBytes ⇒ <code>Promise</code>
|
||||
## randBytes(byteLength, forceLength) ⇒ <code>Promise</code>
|
||||
Secure random bytes for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()
|
||||
|
||||
**Kind**: global constant
|
||||
**Kind**: global function
|
||||
**Returns**: <code>Promise</code> - A promise that resolves to a Buffer/UInt8Array filled with cryptographically secure random bytes
|
||||
|
||||
| Param | Type | Description |
|
||||
|
@ -262,10 +260,10 @@ Secure random bytes for both node and browsers. Node version uses crypto.randomF
|
|||
|
||||
<a name="toZn"></a>
|
||||
|
||||
## toZn ⇒ <code>bigint</code>
|
||||
## toZn(a, n) ⇒ <code>bigint</code>
|
||||
Finds the smallest positive element that is congruent to a in modulo n
|
||||
|
||||
**Kind**: global constant
|
||||
**Kind**: global function
|
||||
**Returns**: <code>bigint</code> - The smallest positive representation of a in modulo n
|
||||
|
||||
| Param | Type | Description |
|
||||
|
|
|
@ -8,10 +8,10 @@ var bigintCryptoUtils = (function (exports) {
|
|||
*
|
||||
* @returns {bigint} the absolute value of a
|
||||
*/
|
||||
const abs = function (a) {
|
||||
function abs(a) {
|
||||
a = BigInt(a);
|
||||
return (a >= BigInt(0)) ? a : -a;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} egcdReturn A triple (g, x, y), such that ax + by = g = gcd(a, b).
|
||||
|
@ -28,7 +28,7 @@ var bigintCryptoUtils = (function (exports) {
|
|||
*
|
||||
* @returns {egcdReturn}
|
||||
*/
|
||||
const eGcd = function (a, b) {
|
||||
function eGcd(a, b) {
|
||||
a = BigInt(a);
|
||||
b = BigInt(b);
|
||||
let x = BigInt(0);
|
||||
|
@ -53,7 +53,7 @@ var bigintCryptoUtils = (function (exports) {
|
|||
x: x,
|
||||
y: y
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Greatest-common divisor of two integers based on the iterative binary algorithm.
|
||||
|
@ -63,7 +63,7 @@ var bigintCryptoUtils = (function (exports) {
|
|||
*
|
||||
* @returns {bigint} The greatest common divisor of a and b
|
||||
*/
|
||||
const gcd = function (a, b) {
|
||||
function gcd(a, b) {
|
||||
a = abs(a);
|
||||
b = abs(b);
|
||||
let shift = BigInt(0);
|
||||
|
@ -85,7 +85,7 @@ var bigintCryptoUtils = (function (exports) {
|
|||
|
||||
// rescale
|
||||
return a << shift;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* The test first tries if any of the first 250 small primes are a factor of the input number and then passes several iterations of Miller-Rabin Probabilistic Primality Test (FIPS 186-4 C.3.1)
|
||||
|
@ -95,7 +95,7 @@ var bigintCryptoUtils = (function (exports) {
|
|||
*
|
||||
* @return {Promise} A promise that resolve to a boolean that is either true (a probably prime number) or false (definitely composite)
|
||||
*/
|
||||
const isProbablyPrime = async function (w, iterations = 16) {
|
||||
async function isProbablyPrime(w, iterations = 16) {
|
||||
{
|
||||
return new Promise(resolve => {
|
||||
let worker = new Worker(_isProbablyPrimeWorkerURL());
|
||||
|
@ -111,7 +111,7 @@ var bigintCryptoUtils = (function (exports) {
|
|||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* The least common multiple computed as abs(a*b)/gcd(a,b)
|
||||
|
@ -120,11 +120,11 @@ var bigintCryptoUtils = (function (exports) {
|
|||
*
|
||||
* @returns {bigint} The least common multiple of a and b
|
||||
*/
|
||||
const lcm = function (a, b) {
|
||||
function lcm(a, b) {
|
||||
a = BigInt(a);
|
||||
b = BigInt(b);
|
||||
return abs(a * b) / gcd(a, b);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Modular inverse.
|
||||
|
@ -134,14 +134,14 @@ var bigintCryptoUtils = (function (exports) {
|
|||
*
|
||||
* @returns {bigint} the inverse modulo n
|
||||
*/
|
||||
const modInv = function (a, n) {
|
||||
function modInv(a, n) {
|
||||
let egcd = eGcd(a, n);
|
||||
if (egcd.b !== BigInt(1)) {
|
||||
return null; // modular inverse does not exist
|
||||
} else {
|
||||
return toZn(egcd.x, n);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Modular exponentiation a**b mod n
|
||||
|
@ -151,7 +151,7 @@ var bigintCryptoUtils = (function (exports) {
|
|||
*
|
||||
* @returns {bigint} a**b mod n
|
||||
*/
|
||||
const modPow = function (a, b, n) {
|
||||
function modPow(a, b, n) {
|
||||
// See Knuth, volume 2, section 4.6.3.
|
||||
n = BigInt(n);
|
||||
a = toZn(a, n);
|
||||
|
@ -172,7 +172,7 @@ var bigintCryptoUtils = (function (exports) {
|
|||
x = x % n;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator.
|
||||
|
@ -184,7 +184,7 @@ var bigintCryptoUtils = (function (exports) {
|
|||
*
|
||||
* @returns {Promise} A promise that resolves to a bigint probable prime of bitLength bits
|
||||
*/
|
||||
const prime = async function (bitLength, iterations = 16) {
|
||||
async function prime(bitLength, iterations = 16) {
|
||||
return new Promise(async (resolve) => {
|
||||
{
|
||||
let workerList = [];
|
||||
|
@ -224,7 +224,7 @@ var bigintCryptoUtils = (function (exports) {
|
|||
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a cryptographically secure random integer between [min,max]
|
||||
|
@ -233,7 +233,7 @@ var bigintCryptoUtils = (function (exports) {
|
|||
*
|
||||
* @returns {Promise} A promise that resolves to a cryptographically secure random bigint between [min,max]
|
||||
*/
|
||||
const randBetween = async function (max, min = 1) {
|
||||
async function randBetween(max, min = 1) {
|
||||
let bitLen = bitLength(max);
|
||||
let byteLength = bitLen >> 3;
|
||||
let remaining = bitLen - (byteLength * 8);
|
||||
|
@ -252,7 +252,7 @@ var bigintCryptoUtils = (function (exports) {
|
|||
rnd = fromBuffer(buf);
|
||||
} while (rnd > max || rnd < min);
|
||||
return rnd;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Secure random bytes for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()
|
||||
|
@ -262,7 +262,7 @@ var bigintCryptoUtils = (function (exports) {
|
|||
*
|
||||
* @returns {Promise} A promise that resolves to a Buffer/UInt8Array filled with cryptographically secure random bytes
|
||||
*/
|
||||
const randBytes = async function (byteLength, forceLength = false) {
|
||||
async function randBytes(byteLength, forceLength = false) {
|
||||
return new Promise((resolve) => {
|
||||
let buf;
|
||||
|
||||
|
@ -275,7 +275,7 @@ var bigintCryptoUtils = (function (exports) {
|
|||
resolve(buf);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the smallest positive element that is congruent to a in modulo n
|
||||
|
@ -284,11 +284,11 @@ var bigintCryptoUtils = (function (exports) {
|
|||
*
|
||||
* @returns {bigint} The smallest positive representation of a in modulo n
|
||||
*/
|
||||
const toZn = function (a, n) {
|
||||
function toZn(a, n) {
|
||||
n = BigInt(n);
|
||||
a = BigInt(a) % n;
|
||||
return (a < 0) ? a + n : a;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
var bigintCryptoUtils=function(a){'use strict';function b(a){let b=BigInt(0);for(let c of a.values()){let a=BigInt(c);b=(b<<BigInt(8))+a}return b}function c(b){let c=1;do c++;while((b>>=BigInt(1))>BigInt(1));return c}function d(){let a=`(() => {'use strict';const eGcd = ${g.toString()};const modInv = ${j.toString()};const modPow = ${k.toString()};const toZn = ${o.toString()};const randBytes = ${m.toString()};const randBetween = ${l.toString()};const isProbablyPrime = ${e.toString()};${c.toString()}${b.toString()}onmessage = ${async function(a){const b=await i(a.data.rnd,a.data.iterations);postMessage({isPrime:b,value:a.data.rnd})}.toString()};})()`;var d=new Blob([a],{type:"text/javascript"});return window.URL.createObjectURL(d)}async function e(c,b=16){if(c===BigInt(2))return!0;if((c&BigInt(1))===BigInt(0)||c===BigInt(1))return!1;const e=[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,1009,1013,1019,1021,1031,1033,1039,1049,1051,1061,1063,1069,1087,1091,1093,1097,1103,1109,1117,1123,1129,1151,1153,1163,1171,1181,1187,1193,1201,1213,1217,1223,1229,1231,1237,1249,1259,1277,1279,1283,1289,1291,1297,1301,1303,1307,1319,1321,1327,1361,1367,1373,1381,1399,1409,1423,1427,1429,1433,1439,1447,1451,1453,1459,1471,1481,1483,1487,1489,1493,1499,1511,1523,1531,1543,1549,1553,1559,1567,1571,1579,1583,1597];for(let a=0;a<e.length&&BigInt(e[a])<=c;a++){const b=BigInt(e[a]);if(c===b)return!0;if(c%b===BigInt(0))return!1}let f=BigInt(0),g=c-BigInt(1);for(;g%BigInt(2)===BigInt(0);)g/=BigInt(2),++f;let h=(c-BigInt(1))/BigInt(2)**f;loop:do{let a=await l(c-BigInt(1),2),b=k(a,h,c);if(b===BigInt(1)||b===c-BigInt(1))continue;for(let a=1;a<f;a++){if(b=k(b,BigInt(2),c),b===c-BigInt(1))continue loop;if(b===BigInt(1))break}return!1}while(--b);return!0}const f=function(b){return b=BigInt(b),b>=BigInt(0)?b:-b},g=function(c,d){c=BigInt(c),d=BigInt(d);let e=BigInt(0),f=BigInt(1),g=BigInt(1),h=BigInt(0);for(;c!==BigInt(0);){let a=d/c,b=d%c,i=e-g*a,j=f-h*a;d=c,c=b,e=g,f=h,g=i,h=j}return{b:d,x:e,y:f}},h=function(c,d){c=f(c),d=f(d);let e=BigInt(0);for(;!((c|d)&BigInt(1));)c>>=BigInt(1),d>>=BigInt(1),e++;for(;!(c&BigInt(1));)c>>=BigInt(1);do{for(;!(d&BigInt(1));)d>>=BigInt(1);if(c>d){let a=c;c=d,d=a}d-=c}while(d);return c<<e},i=async function(a,b=16){return new Promise(c=>{let e=new Worker(d());e.onmessage=a=>{e.terminate(),c(a.data.isPrime)},e.postMessage({rnd:a,iterations:b})})},j=function(b,a){let c=g(b,a);return c.b===BigInt(1)?o(c.x,a):null},k=function(c,d,e){if(e=BigInt(e),c=o(c,e),d=BigInt(d),d<BigInt(0))return j(k(c,f(d),e),e);let g=BigInt(1),h=c;for(;0<d;){var i=d%BigInt(2);d/=BigInt(2),i==BigInt(1)&&(g*=h,g%=e),h*=h,h%=e}return g},l=async function(a,d=1){let e,f=c(a),g=f>>3,h=f-8*g;0<h&&(g++,e=2**h-1);let i;do{let a=await m(g);0<h&&(a[0]&=e),i=b(a)}while(i>a||i<d);return i},m=async function(a,b=!1){return new Promise(c=>{let d;d=new Uint8Array(a),self.crypto.getRandomValues(d),b&&(d[0]|=128),c(d)})},o=function(b,c){return c=BigInt(c),b=BigInt(b)%c,0>b?b+c:b};return a.abs=f,a.eGcd=g,a.gcd=h,a.isProbablyPrime=i,a.lcm=function(c,d){return c=BigInt(c),d=BigInt(d),f(c*d)/h(c,d)},a.modInv=j,a.modPow=k,a.prime=async function(a,c=16){return new Promise(async e=>{{let f=[],g=d();for(let d,h=0;h<self.navigator.hardwareConcurrency;h++)d=new Worker(g),d.onmessage=async g=>{if(g.data.isPrime){for(let a=0;a<f.length;a++)f[a].terminate();for(;f.length;)f.pop();e(g.data.value)}else{let e=BigInt(0);e=b((await m(a/8,!0))),d.postMessage({rnd:e,iterations:c})}},f.push(d);for(const d of f){let e=BigInt(0);e=b((await m(a/8,!0))),d.postMessage({rnd:e,iterations:c})}}})},a.randBetween=l,a.randBytes=m,a.toZn=o,a}({});
|
||||
var bigintCryptoUtils=function(a){'use strict';function c(b){return b=BigInt(b),b>=BigInt(0)?b:-b}function d(c,d){c=BigInt(c),d=BigInt(d);let e=BigInt(0),f=BigInt(1),g=BigInt(1),h=BigInt(0);for(;c!==BigInt(0);){let a=d/c,b=d%c,i=e-g*a,j=f-h*a;d=c,c=b,e=g,f=h,g=i,h=j}return{b:d,x:e,y:f}}function e(d,e){d=c(d),e=c(e);let f=BigInt(0);for(;!((d|e)&BigInt(1));)d>>=BigInt(1),e>>=BigInt(1),f++;for(;!(d&BigInt(1));)d>>=BigInt(1);do{for(;!(e&BigInt(1));)e>>=BigInt(1);if(d>e){let a=d;d=e,e=a}e-=d}while(e);return d<<f}async function f(a,b=16){return new Promise(c=>{let d=new Worker(n());d.onmessage=a=>{d.terminate(),c(a.data.isPrime)},d.postMessage({rnd:a,iterations:b})})}function g(b,a){let c=d(b,a);return c.b===BigInt(1)?k(c.x,a):null}function h(d,e,f){if(f=BigInt(f),d=k(d,f),e=BigInt(e),e<BigInt(0))return g(h(d,c(e),f),f);let i=BigInt(1),j=d;for(;0<e;){var l=e%BigInt(2);e/=BigInt(2),l==BigInt(1)&&(i*=j,i%=f),j*=j,j%=f}return i}async function i(a,b=1){let c,d=m(a),e=d>>3,f=d-8*e;0<f&&(e++,c=2**f-1);let g;do{let a=await j(e);0<f&&(a[0]&=c),g=l(a)}while(g>a||g<b);return g}async function j(a,b=!1){return new Promise(c=>{let d;d=new Uint8Array(a),self.crypto.getRandomValues(d),b&&(d[0]|=128),c(d)})}function k(b,c){return c=BigInt(c),b=BigInt(b)%c,0>b?b+c:b}function l(a){let b=BigInt(0);for(let c of a.values()){let a=BigInt(c);b=(b<<BigInt(8))+a}return b}function m(b){let c=1;do c++;while((b>>=BigInt(1))>BigInt(1));return c}function n(){let a=`(() => {'use strict';const eGcd = ${d.toString()};const modInv = ${g.toString()};const modPow = ${h.toString()};const toZn = ${k.toString()};const randBytes = ${j.toString()};const randBetween = ${i.toString()};const isProbablyPrime = ${o.toString()};${m.toString()}${l.toString()}onmessage = ${async function(a){const b=await f(a.data.rnd,a.data.iterations);postMessage({isPrime:b,value:a.data.rnd})}.toString()};})()`;var b=new Blob([a],{type:"text/javascript"});return window.URL.createObjectURL(b)}async function o(c,b=16){if(c===BigInt(2))return!0;if((c&BigInt(1))===BigInt(0)||c===BigInt(1))return!1;const e=[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,1009,1013,1019,1021,1031,1033,1039,1049,1051,1061,1063,1069,1087,1091,1093,1097,1103,1109,1117,1123,1129,1151,1153,1163,1171,1181,1187,1193,1201,1213,1217,1223,1229,1231,1237,1249,1259,1277,1279,1283,1289,1291,1297,1301,1303,1307,1319,1321,1327,1361,1367,1373,1381,1399,1409,1423,1427,1429,1433,1439,1447,1451,1453,1459,1471,1481,1483,1487,1489,1493,1499,1511,1523,1531,1543,1549,1553,1559,1567,1571,1579,1583,1597];for(let a=0;a<e.length&&BigInt(e[a])<=c;a++){const b=BigInt(e[a]);if(c===b)return!0;if(c%b===BigInt(0))return!1}let f=BigInt(0),g=c-BigInt(1);for(;g%BigInt(2)===BigInt(0);)g/=BigInt(2),++f;let j=(c-BigInt(1))/BigInt(2)**f;loop:do{let a=await i(c-BigInt(1),2),b=h(a,j,c);if(b===BigInt(1)||b===c-BigInt(1))continue;for(let a=1;a<f;a++){if(b=h(b,BigInt(2),c),b===c-BigInt(1))continue loop;if(b===BigInt(1))break}return!1}while(--b);return!0}return a.abs=c,a.eGcd=d,a.gcd=e,a.isProbablyPrime=f,a.lcm=function(d,f){return d=BigInt(d),f=BigInt(f),c(d*f)/e(d,f)},a.modInv=g,a.modPow=h,a.prime=async function(a,b=16){return new Promise(async c=>{{let d=[],e=n();for(let f,g=0;g<self.navigator.hardwareConcurrency;g++)f=new Worker(e),f.onmessage=async e=>{if(e.data.isPrime){for(let a=0;a<d.length;a++)d[a].terminate();for(;d.length;)d.pop();c(e.data.value)}else{let c=BigInt(0);c=l((await j(a/8,!0))),f.postMessage({rnd:c,iterations:b})}},d.push(f);for(const c of d){let d=BigInt(0);d=l((await j(a/8,!0))),c.postMessage({rnd:d,iterations:b})}}})},a.randBetween=i,a.randBytes=j,a.toZn=k,a}({});
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
*
|
||||
* @returns {bigint} the absolute value of a
|
||||
*/
|
||||
const abs = function (a) {
|
||||
function abs(a) {
|
||||
a = BigInt(a);
|
||||
return (a >= BigInt(0)) ? a : -a;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} egcdReturn A triple (g, x, y), such that ax + by = g = gcd(a, b).
|
||||
|
@ -25,7 +25,7 @@ const abs = function (a) {
|
|||
*
|
||||
* @returns {egcdReturn}
|
||||
*/
|
||||
const eGcd = function (a, b) {
|
||||
function eGcd(a, b) {
|
||||
a = BigInt(a);
|
||||
b = BigInt(b);
|
||||
let x = BigInt(0);
|
||||
|
@ -50,7 +50,7 @@ const eGcd = function (a, b) {
|
|||
x: x,
|
||||
y: y
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Greatest-common divisor of two integers based on the iterative binary algorithm.
|
||||
|
@ -60,7 +60,7 @@ const eGcd = function (a, b) {
|
|||
*
|
||||
* @returns {bigint} The greatest common divisor of a and b
|
||||
*/
|
||||
const gcd = function (a, b) {
|
||||
function gcd(a, b) {
|
||||
a = abs(a);
|
||||
b = abs(b);
|
||||
let shift = BigInt(0);
|
||||
|
@ -82,7 +82,7 @@ const gcd = function (a, b) {
|
|||
|
||||
// rescale
|
||||
return a << shift;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* The test first tries if any of the first 250 small primes are a factor of the input number and then passes several iterations of Miller-Rabin Probabilistic Primality Test (FIPS 186-4 C.3.1)
|
||||
|
@ -92,7 +92,7 @@ const gcd = function (a, b) {
|
|||
*
|
||||
* @return {Promise} A promise that resolve to a boolean that is either true (a probably prime number) or false (definitely composite)
|
||||
*/
|
||||
const isProbablyPrime = async function (w, iterations = 16) {
|
||||
async function isProbablyPrime(w, iterations = 16) {
|
||||
{
|
||||
return new Promise(resolve => {
|
||||
let worker = new Worker(_isProbablyPrimeWorkerURL());
|
||||
|
@ -108,7 +108,7 @@ const isProbablyPrime = async function (w, iterations = 16) {
|
|||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* The least common multiple computed as abs(a*b)/gcd(a,b)
|
||||
|
@ -117,11 +117,11 @@ const isProbablyPrime = async function (w, iterations = 16) {
|
|||
*
|
||||
* @returns {bigint} The least common multiple of a and b
|
||||
*/
|
||||
const lcm = function (a, b) {
|
||||
function lcm(a, b) {
|
||||
a = BigInt(a);
|
||||
b = BigInt(b);
|
||||
return abs(a * b) / gcd(a, b);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Modular inverse.
|
||||
|
@ -131,14 +131,14 @@ const lcm = function (a, b) {
|
|||
*
|
||||
* @returns {bigint} the inverse modulo n
|
||||
*/
|
||||
const modInv = function (a, n) {
|
||||
function modInv(a, n) {
|
||||
let egcd = eGcd(a, n);
|
||||
if (egcd.b !== BigInt(1)) {
|
||||
return null; // modular inverse does not exist
|
||||
} else {
|
||||
return toZn(egcd.x, n);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Modular exponentiation a**b mod n
|
||||
|
@ -148,7 +148,7 @@ const modInv = function (a, n) {
|
|||
*
|
||||
* @returns {bigint} a**b mod n
|
||||
*/
|
||||
const modPow = function (a, b, n) {
|
||||
function modPow(a, b, n) {
|
||||
// See Knuth, volume 2, section 4.6.3.
|
||||
n = BigInt(n);
|
||||
a = toZn(a, n);
|
||||
|
@ -169,7 +169,7 @@ const modPow = function (a, b, n) {
|
|||
x = x % n;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator.
|
||||
|
@ -181,7 +181,7 @@ const modPow = function (a, b, n) {
|
|||
*
|
||||
* @returns {Promise} A promise that resolves to a bigint probable prime of bitLength bits
|
||||
*/
|
||||
const prime = async function (bitLength, iterations = 16) {
|
||||
async function prime(bitLength, iterations = 16) {
|
||||
return new Promise(async (resolve) => {
|
||||
{
|
||||
let workerList = [];
|
||||
|
@ -221,7 +221,7 @@ const prime = async function (bitLength, iterations = 16) {
|
|||
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a cryptographically secure random integer between [min,max]
|
||||
|
@ -230,7 +230,7 @@ const prime = async function (bitLength, iterations = 16) {
|
|||
*
|
||||
* @returns {Promise} A promise that resolves to a cryptographically secure random bigint between [min,max]
|
||||
*/
|
||||
const randBetween = async function (max, min = 1) {
|
||||
async function randBetween(max, min = 1) {
|
||||
let bitLen = bitLength(max);
|
||||
let byteLength = bitLen >> 3;
|
||||
let remaining = bitLen - (byteLength * 8);
|
||||
|
@ -249,7 +249,7 @@ const randBetween = async function (max, min = 1) {
|
|||
rnd = fromBuffer(buf);
|
||||
} while (rnd > max || rnd < min);
|
||||
return rnd;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Secure random bytes for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()
|
||||
|
@ -259,7 +259,7 @@ const randBetween = async function (max, min = 1) {
|
|||
*
|
||||
* @returns {Promise} A promise that resolves to a Buffer/UInt8Array filled with cryptographically secure random bytes
|
||||
*/
|
||||
const randBytes = async function (byteLength, forceLength = false) {
|
||||
async function randBytes(byteLength, forceLength = false) {
|
||||
return new Promise((resolve) => {
|
||||
let buf;
|
||||
|
||||
|
@ -272,7 +272,7 @@ const randBytes = async function (byteLength, forceLength = false) {
|
|||
resolve(buf);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the smallest positive element that is congruent to a in modulo n
|
||||
|
@ -281,11 +281,11 @@ const randBytes = async function (byteLength, forceLength = false) {
|
|||
*
|
||||
* @returns {bigint} The smallest positive representation of a in modulo n
|
||||
*/
|
||||
const toZn = function (a, n) {
|
||||
function toZn(a, n) {
|
||||
n = BigInt(n);
|
||||
a = BigInt(a) % n;
|
||||
return (a < 0) ? a + n : a;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
const abs=function(b){return b=BigInt(b),b>=BigInt(0)?b:-b},eGcd=function(c,d){c=BigInt(c),d=BigInt(d);let e=BigInt(0),f=BigInt(1),g=BigInt(1),h=BigInt(0);for(;c!==BigInt(0);){let a=d/c,b=d%c,i=e-g*a,j=f-h*a;d=c,c=b,e=g,f=h,g=i,h=j}return{b:d,x:e,y:f}},gcd=function(c,d){c=abs(c),d=abs(d);let e=BigInt(0);for(;!((c|d)&BigInt(1));)c>>=BigInt(1),d>>=BigInt(1),e++;for(;!(c&BigInt(1));)c>>=BigInt(1);do{for(;!(d&BigInt(1));)d>>=BigInt(1);if(c>d){let a=c;c=d,d=a}d-=c}while(d);return c<<e},isProbablyPrime=async function(a,b=16){return new Promise(c=>{let d=new Worker(_isProbablyPrimeWorkerURL());d.onmessage=a=>{d.terminate(),c(a.data.isPrime)},d.postMessage({rnd:a,iterations:b})})},lcm=function(c,d){return c=BigInt(c),d=BigInt(d),abs(c*d)/gcd(c,d)},modInv=function(b,a){let c=eGcd(b,a);return c.b===BigInt(1)?toZn(c.x,a):null},modPow=function(c,d,e){if(e=BigInt(e),c=toZn(c,e),d=BigInt(d),d<BigInt(0))return modInv(modPow(c,abs(d),e),e);let f=BigInt(1),g=c;for(;0<d;){var h=d%BigInt(2);d/=BigInt(2),h==BigInt(1)&&(f*=g,f%=e),g*=g,g%=e}return f},prime=async function(a,b=16){return new Promise(async c=>{{let d=[],e=_isProbablyPrimeWorkerURL();for(let f,g=0;g<self.navigator.hardwareConcurrency;g++)f=new Worker(e),f.onmessage=async e=>{if(e.data.isPrime){for(let a=0;a<d.length;a++)d[a].terminate();for(;d.length;)d.pop();c(e.data.value)}else{let c=BigInt(0);c=fromBuffer((await randBytes(a/8,!0))),f.postMessage({rnd:c,iterations:b})}},d.push(f);for(const c of d){let d=BigInt(0);d=fromBuffer((await randBytes(a/8,!0))),c.postMessage({rnd:d,iterations:b})}}})},randBetween=async function(a,b=1){let c,d=bitLength(a),e=d>>3,f=d-8*e;0<f&&(e++,c=2**f-1);let g;do{let a=await randBytes(e);0<f&&(a[0]&=c),g=fromBuffer(a)}while(g>a||g<b);return g},randBytes=async function(a,b=!1){return new Promise(c=>{let d;d=new Uint8Array(a),self.crypto.getRandomValues(d),b&&(d[0]|=128),c(d)})},toZn=function(b,c){return c=BigInt(c),b=BigInt(b)%c,0>b?b+c:b};function fromBuffer(a){let b=BigInt(0);for(let c of a.values()){let a=BigInt(c);b=(b<<BigInt(8))+a}return b}function bitLength(b){let c=1;do c++;while((b>>=BigInt(1))>BigInt(1));return c}function _isProbablyPrimeWorkerURL(){let a=`(() => {'use strict';const eGcd = ${eGcd.toString()};const modInv = ${modInv.toString()};const modPow = ${modPow.toString()};const toZn = ${toZn.toString()};const randBytes = ${randBytes.toString()};const randBetween = ${randBetween.toString()};const isProbablyPrime = ${_isProbablyPrime.toString()};${bitLength.toString()}${fromBuffer.toString()}onmessage = ${async function(a){const b=await isProbablyPrime(a.data.rnd,a.data.iterations);postMessage({isPrime:b,value:a.data.rnd})}.toString()};})()`;var b=new Blob([a],{type:"text/javascript"});return window.URL.createObjectURL(b)}async function _isProbablyPrime(c,b=16){if(c===BigInt(2))return!0;if((c&BigInt(1))===BigInt(0)||c===BigInt(1))return!1;const e=[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,1009,1013,1019,1021,1031,1033,1039,1049,1051,1061,1063,1069,1087,1091,1093,1097,1103,1109,1117,1123,1129,1151,1153,1163,1171,1181,1187,1193,1201,1213,1217,1223,1229,1231,1237,1249,1259,1277,1279,1283,1289,1291,1297,1301,1303,1307,1319,1321,1327,1361,1367,1373,1381,1399,1409,1423,1427,1429,1433,1439,1447,1451,1453,1459,1471,1481,1483,1487,1489,1493,1499,1511,1523,1531,1543,1549,1553,1559,1567,1571,1579,1583,1597];for(let a=0;a<e.length&&BigInt(e[a])<=c;a++){const b=BigInt(e[a]);if(c===b)return!0;if(c%b===BigInt(0))return!1}let f=BigInt(0),g=c-BigInt(1);for(;g%BigInt(2)===BigInt(0);)g/=BigInt(2),++f;let h=(c-BigInt(1))/BigInt(2)**f;loop:do{let a=await randBetween(c-BigInt(1),2),b=modPow(a,h,c);if(b===BigInt(1)||b===c-BigInt(1))continue;for(let a=1;a<f;a++){if(b=modPow(b,BigInt(2),c),b===c-BigInt(1))continue loop;if(b===BigInt(1))break}return!1}while(--b);return!0}export{abs,eGcd,gcd,isProbablyPrime,lcm,modInv,modPow,prime,randBetween,randBytes,toZn};
|
||||
function abs(b){return b=BigInt(b),b>=BigInt(0)?b:-b}function eGcd(c,d){c=BigInt(c),d=BigInt(d);let e=BigInt(0),f=BigInt(1),g=BigInt(1),h=BigInt(0);for(;c!==BigInt(0);){let a=d/c,b=d%c,i=e-g*a,j=f-h*a;d=c,c=b,e=g,f=h,g=i,h=j}return{b:d,x:e,y:f}}function gcd(c,d){c=abs(c),d=abs(d);let e=BigInt(0);for(;!((c|d)&BigInt(1));)c>>=BigInt(1),d>>=BigInt(1),e++;for(;!(c&BigInt(1));)c>>=BigInt(1);do{for(;!(d&BigInt(1));)d>>=BigInt(1);if(c>d){let a=c;c=d,d=a}d-=c}while(d);return c<<e}async function isProbablyPrime(a,b=16){return new Promise(c=>{let d=new Worker(_isProbablyPrimeWorkerURL());d.onmessage=a=>{d.terminate(),c(a.data.isPrime)},d.postMessage({rnd:a,iterations:b})})}function lcm(c,d){return c=BigInt(c),d=BigInt(d),abs(c*d)/gcd(c,d)}function modInv(b,a){let c=eGcd(b,a);return c.b===BigInt(1)?toZn(c.x,a):null}function modPow(c,d,e){if(e=BigInt(e),c=toZn(c,e),d=BigInt(d),d<BigInt(0))return modInv(modPow(c,abs(d),e),e);let f=BigInt(1),g=c;for(;0<d;){var h=d%BigInt(2);d/=BigInt(2),h==BigInt(1)&&(f*=g,f%=e),g*=g,g%=e}return f}async function prime(a,b=16){return new Promise(async c=>{{let d=[],e=_isProbablyPrimeWorkerURL();for(let f,g=0;g<self.navigator.hardwareConcurrency;g++)f=new Worker(e),f.onmessage=async e=>{if(e.data.isPrime){for(let a=0;a<d.length;a++)d[a].terminate();for(;d.length;)d.pop();c(e.data.value)}else{let c=BigInt(0);c=fromBuffer((await randBytes(a/8,!0))),f.postMessage({rnd:c,iterations:b})}},d.push(f);for(const c of d){let d=BigInt(0);d=fromBuffer((await randBytes(a/8,!0))),c.postMessage({rnd:d,iterations:b})}}})}async function randBetween(a,b=1){let c,d=bitLength(a),e=d>>3,f=d-8*e;0<f&&(e++,c=2**f-1);let g;do{let a=await randBytes(e);0<f&&(a[0]&=c),g=fromBuffer(a)}while(g>a||g<b);return g}async function randBytes(a,b=!1){return new Promise(c=>{let d;d=new Uint8Array(a),self.crypto.getRandomValues(d),b&&(d[0]|=128),c(d)})}function toZn(b,c){return c=BigInt(c),b=BigInt(b)%c,0>b?b+c:b}function fromBuffer(a){let b=BigInt(0);for(let c of a.values()){let a=BigInt(c);b=(b<<BigInt(8))+a}return b}function bitLength(b){let c=1;do c++;while((b>>=BigInt(1))>BigInt(1));return c}function _isProbablyPrimeWorkerURL(){let a=`(() => {'use strict';const eGcd = ${eGcd.toString()};const modInv = ${modInv.toString()};const modPow = ${modPow.toString()};const toZn = ${toZn.toString()};const randBytes = ${randBytes.toString()};const randBetween = ${randBetween.toString()};const isProbablyPrime = ${_isProbablyPrime.toString()};${bitLength.toString()}${fromBuffer.toString()}onmessage = ${async function(a){const b=await isProbablyPrime(a.data.rnd,a.data.iterations);postMessage({isPrime:b,value:a.data.rnd})}.toString()};})()`;var b=new Blob([a],{type:"text/javascript"});return window.URL.createObjectURL(b)}async function _isProbablyPrime(c,b=16){if(c===BigInt(2))return!0;if((c&BigInt(1))===BigInt(0)||c===BigInt(1))return!1;const e=[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,1009,1013,1019,1021,1031,1033,1039,1049,1051,1061,1063,1069,1087,1091,1093,1097,1103,1109,1117,1123,1129,1151,1153,1163,1171,1181,1187,1193,1201,1213,1217,1223,1229,1231,1237,1249,1259,1277,1279,1283,1289,1291,1297,1301,1303,1307,1319,1321,1327,1361,1367,1373,1381,1399,1409,1423,1427,1429,1433,1439,1447,1451,1453,1459,1471,1481,1483,1487,1489,1493,1499,1511,1523,1531,1543,1549,1553,1559,1567,1571,1579,1583,1597];for(let a=0;a<e.length&&BigInt(e[a])<=c;a++){const b=BigInt(e[a]);if(c===b)return!0;if(c%b===BigInt(0))return!1}let f=BigInt(0),g=c-BigInt(1);for(;g%BigInt(2)===BigInt(0);)g/=BigInt(2),++f;let h=(c-BigInt(1))/BigInt(2)**f;loop:do{let a=await randBetween(c-BigInt(1),2),b=modPow(a,h,c);if(b===BigInt(1)||b===c-BigInt(1))continue;for(let a=1;a<f;a++){if(b=modPow(b,BigInt(2),c),b===c-BigInt(1))continue loop;if(b===BigInt(1))break}return!1}while(--b);return!0}export{abs,eGcd,gcd,isProbablyPrime,lcm,modInv,modPow,prime,randBetween,randBytes,toZn};
|
||||
|
|
|
@ -9,10 +9,10 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|||
*
|
||||
* @returns {bigint} the absolute value of a
|
||||
*/
|
||||
const abs = function (a) {
|
||||
function abs(a) {
|
||||
a = BigInt(a);
|
||||
return (a >= BigInt(0)) ? a : -a;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} egcdReturn A triple (g, x, y), such that ax + by = g = gcd(a, b).
|
||||
|
@ -29,7 +29,7 @@ const abs = function (a) {
|
|||
*
|
||||
* @returns {egcdReturn}
|
||||
*/
|
||||
const eGcd = function (a, b) {
|
||||
function eGcd(a, b) {
|
||||
a = BigInt(a);
|
||||
b = BigInt(b);
|
||||
let x = BigInt(0);
|
||||
|
@ -54,7 +54,7 @@ const eGcd = function (a, b) {
|
|||
x: x,
|
||||
y: y
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Greatest-common divisor of two integers based on the iterative binary algorithm.
|
||||
|
@ -64,7 +64,7 @@ const eGcd = function (a, b) {
|
|||
*
|
||||
* @returns {bigint} The greatest common divisor of a and b
|
||||
*/
|
||||
const gcd = function (a, b) {
|
||||
function gcd(a, b) {
|
||||
a = abs(a);
|
||||
b = abs(b);
|
||||
let shift = BigInt(0);
|
||||
|
@ -86,7 +86,7 @@ const gcd = function (a, b) {
|
|||
|
||||
// rescale
|
||||
return a << shift;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* The test first tries if any of the first 250 small primes are a factor of the input number and then passes several iterations of Miller-Rabin Probabilistic Primality Test (FIPS 186-4 C.3.1)
|
||||
|
@ -96,11 +96,11 @@ const gcd = function (a, b) {
|
|||
*
|
||||
* @return {Promise} A promise that resolve to a boolean that is either true (a probably prime number) or false (definitely composite)
|
||||
*/
|
||||
const isProbablyPrime = async function (w, iterations = 16) {
|
||||
async function isProbablyPrime(w, iterations = 16) {
|
||||
{
|
||||
return _isProbablyPrime(w, iterations);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* The least common multiple computed as abs(a*b)/gcd(a,b)
|
||||
|
@ -109,11 +109,11 @@ const isProbablyPrime = async function (w, iterations = 16) {
|
|||
*
|
||||
* @returns {bigint} The least common multiple of a and b
|
||||
*/
|
||||
const lcm = function (a, b) {
|
||||
function lcm(a, b) {
|
||||
a = BigInt(a);
|
||||
b = BigInt(b);
|
||||
return abs(a * b) / gcd(a, b);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Modular inverse.
|
||||
|
@ -123,14 +123,14 @@ const lcm = function (a, b) {
|
|||
*
|
||||
* @returns {bigint} the inverse modulo n
|
||||
*/
|
||||
const modInv = function (a, n) {
|
||||
function modInv(a, n) {
|
||||
let egcd = eGcd(a, n);
|
||||
if (egcd.b !== BigInt(1)) {
|
||||
return null; // modular inverse does not exist
|
||||
} else {
|
||||
return toZn(egcd.x, n);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Modular exponentiation a**b mod n
|
||||
|
@ -140,7 +140,7 @@ const modInv = function (a, n) {
|
|||
*
|
||||
* @returns {bigint} a**b mod n
|
||||
*/
|
||||
const modPow = function (a, b, n) {
|
||||
function modPow(a, b, n) {
|
||||
// See Knuth, volume 2, section 4.6.3.
|
||||
n = BigInt(n);
|
||||
a = toZn(a, n);
|
||||
|
@ -161,7 +161,7 @@ const modPow = function (a, b, n) {
|
|||
x = x % n;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator.
|
||||
|
@ -173,7 +173,7 @@ const modPow = function (a, b, n) {
|
|||
*
|
||||
* @returns {Promise} A promise that resolves to a bigint probable prime of bitLength bits
|
||||
*/
|
||||
const prime = async function (bitLength, iterations = 16) {
|
||||
async function prime(bitLength, iterations = 16) {
|
||||
return new Promise(async (resolve) => {
|
||||
{
|
||||
let rnd = BigInt(0);
|
||||
|
@ -183,7 +183,7 @@ const prime = async function (bitLength, iterations = 16) {
|
|||
resolve(rnd);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a cryptographically secure random integer between [min,max]
|
||||
|
@ -192,7 +192,7 @@ const prime = async function (bitLength, iterations = 16) {
|
|||
*
|
||||
* @returns {Promise} A promise that resolves to a cryptographically secure random bigint between [min,max]
|
||||
*/
|
||||
const randBetween = async function (max, min = 1) {
|
||||
async function randBetween(max, min = 1) {
|
||||
let bitLen = bitLength(max);
|
||||
let byteLength = bitLen >> 3;
|
||||
let remaining = bitLen - (byteLength * 8);
|
||||
|
@ -211,7 +211,7 @@ const randBetween = async function (max, min = 1) {
|
|||
rnd = fromBuffer(buf);
|
||||
} while (rnd > max || rnd < min);
|
||||
return rnd;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Secure random bytes for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()
|
||||
|
@ -221,7 +221,7 @@ const randBetween = async function (max, min = 1) {
|
|||
*
|
||||
* @returns {Promise} A promise that resolves to a Buffer/UInt8Array filled with cryptographically secure random bytes
|
||||
*/
|
||||
const randBytes = async function (byteLength, forceLength = false) {
|
||||
async function randBytes(byteLength, forceLength = false) {
|
||||
return new Promise((resolve) => {
|
||||
let buf;
|
||||
|
||||
|
@ -237,7 +237,7 @@ const randBytes = async function (byteLength, forceLength = false) {
|
|||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the smallest positive element that is congruent to a in modulo n
|
||||
|
@ -246,11 +246,11 @@ const randBytes = async function (byteLength, forceLength = false) {
|
|||
*
|
||||
* @returns {bigint} The smallest positive representation of a in modulo n
|
||||
*/
|
||||
const toZn = function (a, n) {
|
||||
function toZn(a, n) {
|
||||
n = BigInt(n);
|
||||
a = BigInt(a) % n;
|
||||
return (a < 0) ? a + n : a;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
44
src/main.js
44
src/main.js
|
@ -7,10 +7,10 @@
|
|||
*
|
||||
* @returns {bigint} the absolute value of a
|
||||
*/
|
||||
export const abs = function (a) {
|
||||
export function abs(a) {
|
||||
a = BigInt(a);
|
||||
return (a >= BigInt(0)) ? a : -a;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} egcdReturn A triple (g, x, y), such that ax + by = g = gcd(a, b).
|
||||
|
@ -27,7 +27,7 @@ export const abs = function (a) {
|
|||
*
|
||||
* @returns {egcdReturn}
|
||||
*/
|
||||
export const eGcd = function (a, b) {
|
||||
export function eGcd(a, b) {
|
||||
a = BigInt(a);
|
||||
b = BigInt(b);
|
||||
let x = BigInt(0);
|
||||
|
@ -52,7 +52,7 @@ export const eGcd = function (a, b) {
|
|||
x: x,
|
||||
y: y
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Greatest-common divisor of two integers based on the iterative binary algorithm.
|
||||
|
@ -62,7 +62,7 @@ export const eGcd = function (a, b) {
|
|||
*
|
||||
* @returns {bigint} The greatest common divisor of a and b
|
||||
*/
|
||||
export const gcd = function (a, b) {
|
||||
export function gcd(a, b) {
|
||||
a = abs(a);
|
||||
b = abs(b);
|
||||
let shift = BigInt(0);
|
||||
|
@ -84,7 +84,7 @@ export const gcd = function (a, b) {
|
|||
|
||||
// rescale
|
||||
return a << shift;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* The test first tries if any of the first 250 small primes are a factor of the input number and then passes several iterations of Miller-Rabin Probabilistic Primality Test (FIPS 186-4 C.3.1)
|
||||
|
@ -94,7 +94,7 @@ export const gcd = function (a, b) {
|
|||
*
|
||||
* @return {Promise} A promise that resolve to a boolean that is either true (a probably prime number) or false (definitely composite)
|
||||
*/
|
||||
export const isProbablyPrime = async function (w, iterations = 16) {
|
||||
export async function isProbablyPrime(w, iterations = 16) {
|
||||
if (process.browser) {
|
||||
return new Promise(resolve => {
|
||||
let worker = new Worker(_isProbablyPrimeWorkerURL());
|
||||
|
@ -112,7 +112,7 @@ export const isProbablyPrime = async function (w, iterations = 16) {
|
|||
} else {
|
||||
return _isProbablyPrime(w, iterations);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* The least common multiple computed as abs(a*b)/gcd(a,b)
|
||||
|
@ -121,11 +121,11 @@ export const isProbablyPrime = async function (w, iterations = 16) {
|
|||
*
|
||||
* @returns {bigint} The least common multiple of a and b
|
||||
*/
|
||||
export const lcm = function (a, b) {
|
||||
export function lcm(a, b) {
|
||||
a = BigInt(a);
|
||||
b = BigInt(b);
|
||||
return abs(a * b) / gcd(a, b);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Modular inverse.
|
||||
|
@ -135,14 +135,14 @@ export const lcm = function (a, b) {
|
|||
*
|
||||
* @returns {bigint} the inverse modulo n
|
||||
*/
|
||||
export const modInv = function (a, n) {
|
||||
export function modInv(a, n) {
|
||||
let egcd = eGcd(a, n);
|
||||
if (egcd.b !== BigInt(1)) {
|
||||
return null; // modular inverse does not exist
|
||||
} else {
|
||||
return toZn(egcd.x, n);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Modular exponentiation a**b mod n
|
||||
|
@ -152,7 +152,7 @@ export const modInv = function (a, n) {
|
|||
*
|
||||
* @returns {bigint} a**b mod n
|
||||
*/
|
||||
export const modPow = function (a, b, n) {
|
||||
export function modPow(a, b, n) {
|
||||
// See Knuth, volume 2, section 4.6.3.
|
||||
n = BigInt(n);
|
||||
a = toZn(a, n);
|
||||
|
@ -173,7 +173,7 @@ export const modPow = function (a, b, n) {
|
|||
x = x % n;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator.
|
||||
|
@ -185,7 +185,7 @@ export const modPow = function (a, b, n) {
|
|||
*
|
||||
* @returns {Promise} A promise that resolves to a bigint probable prime of bitLength bits
|
||||
*/
|
||||
export const prime = async function (bitLength, iterations = 16) {
|
||||
export async function prime(bitLength, iterations = 16) {
|
||||
return new Promise(async (resolve) => {
|
||||
if (process.browser) {
|
||||
let workerList = [];
|
||||
|
@ -231,7 +231,7 @@ export const prime = async function (bitLength, iterations = 16) {
|
|||
resolve(rnd);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a cryptographically secure random integer between [min,max]
|
||||
|
@ -240,7 +240,7 @@ export const prime = async function (bitLength, iterations = 16) {
|
|||
*
|
||||
* @returns {Promise} A promise that resolves to a cryptographically secure random bigint between [min,max]
|
||||
*/
|
||||
export const randBetween = async function (max, min = 1) {
|
||||
export async function randBetween(max, min = 1) {
|
||||
let bitLen = bitLength(max);
|
||||
let byteLength = bitLen >> 3;
|
||||
let remaining = bitLen - (byteLength * 8);
|
||||
|
@ -259,7 +259,7 @@ export const randBetween = async function (max, min = 1) {
|
|||
rnd = fromBuffer(buf);
|
||||
} while (rnd > max || rnd < min);
|
||||
return rnd;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Secure random bytes for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()
|
||||
|
@ -269,7 +269,7 @@ export const randBetween = async function (max, min = 1) {
|
|||
*
|
||||
* @returns {Promise} A promise that resolves to a Buffer/UInt8Array filled with cryptographically secure random bytes
|
||||
*/
|
||||
export const randBytes = async function (byteLength, forceLength = false) {
|
||||
export async function randBytes(byteLength, forceLength = false) {
|
||||
return new Promise((resolve) => {
|
||||
let buf;
|
||||
|
||||
|
@ -292,7 +292,7 @@ export const randBytes = async function (byteLength, forceLength = false) {
|
|||
resolve(buf);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the smallest positive element that is congruent to a in modulo n
|
||||
|
@ -301,11 +301,11 @@ export const randBytes = async function (byteLength, forceLength = false) {
|
|||
*
|
||||
* @returns {bigint} The smallest positive representation of a in modulo n
|
||||
*/
|
||||
export const toZn = function (a, n) {
|
||||
export function toZn(a, n) {
|
||||
n = BigInt(n);
|
||||
a = BigInt(a) % n;
|
||||
return (a < 0) ? a + n : a;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue