better README

This commit is contained in:
Juan Hernández Serrano 2019-04-19 16:40:11 +02:00
parent 12a78d9495
commit de00327fd8
8 changed files with 128 additions and 132 deletions

View File

@ -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). 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)**_ _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)._
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).
## Installation ## 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. 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. 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 ## Usage example

View File

@ -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). 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)**_ _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)._
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).
## Installation ## 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. 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. 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 ## 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 # bigint-crypto-utils JS Doc
## Constants ## Functions
<dl> <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&gt;=0. abs(a)==-a if a&lt;0</p> <dd><p>Absolute value. abs(a)==a if a&gt;=0. abs(a)==-a if a&lt;0</p>
</dd> </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. <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> Take positive integers a, b as input, and return a triple (g, x, y), such that ax + by = g = gcd(a, b).</p>
</dd> </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><p>Greatest-common divisor of two integers based on the iterative binary algorithm.</p>
</dd> </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><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> </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><p>The least common multiple computed as abs(a*b)/gcd(a,b)</p>
</dd> </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><p>Modular inverse.</p>
</dd> </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><p>Modular exponentiation a**b mod n</p>
</dd> </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. <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 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> main process, and it can be much faster (if several cores or cpu are available).</p>
</dd> </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><p>Returns a cryptographically secure random integer between [min,max]</p>
</dd> </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><p>Secure random bytes for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()</p>
</dd> </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><p>Finds the smallest positive element that is congruent to a in modulo n</p>
</dd> </dd>
</dl> </dl>
@ -130,10 +128,10 @@ main process, and it can be much faster (if several cores or cpu are available).
<a name="abs"></a> <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 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 **Returns**: <code>bigint</code> - the absolute value of a
| Param | Type | | Param | Type |
@ -142,11 +140,11 @@ Absolute value. abs(a)==a if a>=0. abs(a)==-a if a<0
<a name="eGcd"></a> <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. 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). 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 | | 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> <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. 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 **Returns**: <code>bigint</code> - The greatest common divisor of a and b
| Param | Type | | Param | Type |
@ -168,10 +166,10 @@ Greatest-common divisor of two integers based on the iterative binary algorithm.
<a name="isProbablyPrime"></a> <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) 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) **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 | | 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> <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) 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 **Returns**: <code>bigint</code> - The least common multiple of a and b
| Param | Type | | Param | Type |
@ -194,10 +192,10 @@ The least common multiple computed as abs(a*b)/gcd(a,b)
<a name="modInv"></a> <a name="modInv"></a>
## modInv ⇒ <code>bigint</code> ## modInv(a, n)<code>bigint</code>
Modular inverse. Modular inverse.
**Kind**: global constant **Kind**: global function
**Returns**: <code>bigint</code> - the inverse modulo n **Returns**: <code>bigint</code> - the inverse modulo n
| Param | Type | Description | | Param | Type | Description |
@ -207,10 +205,10 @@ Modular inverse.
<a name="modPow"></a> <a name="modPow"></a>
## modPow ⇒ <code>bigint</code> ## modPow(a, b, n)<code>bigint</code>
Modular exponentiation a**b mod n Modular exponentiation a**b mod n
**Kind**: global constant **Kind**: global function
**Returns**: <code>bigint</code> - a**b mod n **Returns**: <code>bigint</code> - a**b mod n
| Param | Type | Description | | Param | Type | Description |
@ -221,12 +219,12 @@ Modular exponentiation a**b mod n
<a name="prime"></a> <a name="prime"></a>
## prime ⇒ <code>Promise</code> ## prime(bitLength, iterations)<code>Promise</code>
A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator. 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 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). 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 **Returns**: <code>Promise</code> - A promise that resolves to a bigint probable prime of bitLength bits
| Param | Type | Description | | 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> <a name="randBetween"></a>
## randBetween ⇒ <code>Promise</code> ## randBetween(max, min)<code>Promise</code>
Returns a cryptographically secure random integer between [min,max] 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] **Returns**: <code>Promise</code> - A promise that resolves to a cryptographically secure random bigint between [min,max]
| Param | Type | Description | | Param | Type | Description |
@ -249,10 +247,10 @@ Returns a cryptographically secure random integer between [min,max]
<a name="randBytes"></a> <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() 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 **Returns**: <code>Promise</code> - A promise that resolves to a Buffer/UInt8Array filled with cryptographically secure random bytes
| Param | Type | Description | | Param | Type | Description |
@ -262,10 +260,10 @@ Secure random bytes for both node and browsers. Node version uses crypto.randomF
<a name="toZn"></a> <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 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 **Returns**: <code>bigint</code> - The smallest positive representation of a in modulo n
| Param | Type | Description | | Param | Type | Description |

View File

@ -8,10 +8,10 @@ var bigintCryptoUtils = (function (exports) {
* *
* @returns {bigint} the absolute value of a * @returns {bigint} the absolute value of a
*/ */
const abs = function (a) { function abs(a) {
a = BigInt(a); a = BigInt(a);
return (a >= BigInt(0)) ? a : -a; return (a >= BigInt(0)) ? a : -a;
}; }
/** /**
* @typedef {Object} egcdReturn A triple (g, x, y), such that ax + by = g = gcd(a, b). * @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} * @returns {egcdReturn}
*/ */
const eGcd = function (a, b) { function eGcd(a, b) {
a = BigInt(a); a = BigInt(a);
b = BigInt(b); b = BigInt(b);
let x = BigInt(0); let x = BigInt(0);
@ -53,7 +53,7 @@ var bigintCryptoUtils = (function (exports) {
x: x, x: x,
y: y y: y
}; };
}; }
/** /**
* Greatest-common divisor of two integers based on the iterative binary algorithm. * 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 * @returns {bigint} The greatest common divisor of a and b
*/ */
const gcd = function (a, b) { function gcd(a, b) {
a = abs(a); a = abs(a);
b = abs(b); b = abs(b);
let shift = BigInt(0); let shift = BigInt(0);
@ -85,7 +85,7 @@ var bigintCryptoUtils = (function (exports) {
// rescale // rescale
return a << shift; 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) * 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) * @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 => { return new Promise(resolve => {
let worker = new Worker(_isProbablyPrimeWorkerURL()); 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) * 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 * @returns {bigint} The least common multiple of a and b
*/ */
const lcm = function (a, b) { function lcm(a, b) {
a = BigInt(a); a = BigInt(a);
b = BigInt(b); b = BigInt(b);
return abs(a * b) / gcd(a, b); return abs(a * b) / gcd(a, b);
}; }
/** /**
* Modular inverse. * Modular inverse.
@ -134,14 +134,14 @@ var bigintCryptoUtils = (function (exports) {
* *
* @returns {bigint} the inverse modulo n * @returns {bigint} the inverse modulo n
*/ */
const modInv = function (a, n) { function modInv(a, n) {
let egcd = eGcd(a, n); let egcd = eGcd(a, n);
if (egcd.b !== BigInt(1)) { if (egcd.b !== BigInt(1)) {
return null; // modular inverse does not exist return null; // modular inverse does not exist
} else { } else {
return toZn(egcd.x, n); return toZn(egcd.x, n);
} }
}; }
/** /**
* Modular exponentiation a**b mod n * Modular exponentiation a**b mod n
@ -151,7 +151,7 @@ var bigintCryptoUtils = (function (exports) {
* *
* @returns {bigint} a**b mod 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. // See Knuth, volume 2, section 4.6.3.
n = BigInt(n); n = BigInt(n);
a = toZn(a, n); a = toZn(a, n);
@ -172,7 +172,7 @@ var bigintCryptoUtils = (function (exports) {
x = x % n; x = x % n;
} }
return result; return result;
}; }
/** /**
* A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator. * 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 * @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) => { return new Promise(async (resolve) => {
{ {
let workerList = []; let workerList = [];
@ -224,7 +224,7 @@ var bigintCryptoUtils = (function (exports) {
} }
}); });
}; }
/** /**
* Returns a cryptographically secure random integer between [min,max] * 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] * @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 bitLen = bitLength(max);
let byteLength = bitLen >> 3; let byteLength = bitLen >> 3;
let remaining = bitLen - (byteLength * 8); let remaining = bitLen - (byteLength * 8);
@ -252,7 +252,7 @@ var bigintCryptoUtils = (function (exports) {
rnd = fromBuffer(buf); rnd = fromBuffer(buf);
} while (rnd > max || rnd < min); } while (rnd > max || rnd < min);
return rnd; return rnd;
}; }
/** /**
* Secure random bytes for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues() * 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 * @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) => { return new Promise((resolve) => {
let buf; let buf;
@ -275,7 +275,7 @@ var bigintCryptoUtils = (function (exports) {
resolve(buf); resolve(buf);
} }
}); });
}; }
/** /**
* Finds the smallest positive element that is congruent to a in modulo n * 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 * @returns {bigint} The smallest positive representation of a in modulo n
*/ */
const toZn = function (a, n) { function toZn(a, n) {
n = BigInt(n); n = BigInt(n);
a = BigInt(a) % n; a = BigInt(a) % n;
return (a < 0) ? a + n : a; return (a < 0) ? a + n : a;
}; }

View File

@ -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}({});

View File

@ -5,10 +5,10 @@
* *
* @returns {bigint} the absolute value of a * @returns {bigint} the absolute value of a
*/ */
const abs = function (a) { function abs(a) {
a = BigInt(a); a = BigInt(a);
return (a >= BigInt(0)) ? a : -a; return (a >= BigInt(0)) ? a : -a;
}; }
/** /**
* @typedef {Object} egcdReturn A triple (g, x, y), such that ax + by = g = gcd(a, b). * @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} * @returns {egcdReturn}
*/ */
const eGcd = function (a, b) { function eGcd(a, b) {
a = BigInt(a); a = BigInt(a);
b = BigInt(b); b = BigInt(b);
let x = BigInt(0); let x = BigInt(0);
@ -50,7 +50,7 @@ const eGcd = function (a, b) {
x: x, x: x,
y: y y: y
}; };
}; }
/** /**
* Greatest-common divisor of two integers based on the iterative binary algorithm. * 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 * @returns {bigint} The greatest common divisor of a and b
*/ */
const gcd = function (a, b) { function gcd(a, b) {
a = abs(a); a = abs(a);
b = abs(b); b = abs(b);
let shift = BigInt(0); let shift = BigInt(0);
@ -82,7 +82,7 @@ const gcd = function (a, b) {
// rescale // rescale
return a << shift; 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) * 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) * @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 => { return new Promise(resolve => {
let worker = new Worker(_isProbablyPrimeWorkerURL()); 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) * 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 * @returns {bigint} The least common multiple of a and b
*/ */
const lcm = function (a, b) { function lcm(a, b) {
a = BigInt(a); a = BigInt(a);
b = BigInt(b); b = BigInt(b);
return abs(a * b) / gcd(a, b); return abs(a * b) / gcd(a, b);
}; }
/** /**
* Modular inverse. * Modular inverse.
@ -131,14 +131,14 @@ const lcm = function (a, b) {
* *
* @returns {bigint} the inverse modulo n * @returns {bigint} the inverse modulo n
*/ */
const modInv = function (a, n) { function modInv(a, n) {
let egcd = eGcd(a, n); let egcd = eGcd(a, n);
if (egcd.b !== BigInt(1)) { if (egcd.b !== BigInt(1)) {
return null; // modular inverse does not exist return null; // modular inverse does not exist
} else { } else {
return toZn(egcd.x, n); return toZn(egcd.x, n);
} }
}; }
/** /**
* Modular exponentiation a**b mod n * Modular exponentiation a**b mod n
@ -148,7 +148,7 @@ const modInv = function (a, n) {
* *
* @returns {bigint} a**b mod 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. // See Knuth, volume 2, section 4.6.3.
n = BigInt(n); n = BigInt(n);
a = toZn(a, n); a = toZn(a, n);
@ -169,7 +169,7 @@ const modPow = function (a, b, n) {
x = x % n; x = x % n;
} }
return result; return result;
}; }
/** /**
* A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator. * 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 * @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) => { return new Promise(async (resolve) => {
{ {
let workerList = []; let workerList = [];
@ -221,7 +221,7 @@ const prime = async function (bitLength, iterations = 16) {
} }
}); });
}; }
/** /**
* Returns a cryptographically secure random integer between [min,max] * 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] * @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 bitLen = bitLength(max);
let byteLength = bitLen >> 3; let byteLength = bitLen >> 3;
let remaining = bitLen - (byteLength * 8); let remaining = bitLen - (byteLength * 8);
@ -249,7 +249,7 @@ const randBetween = async function (max, min = 1) {
rnd = fromBuffer(buf); rnd = fromBuffer(buf);
} while (rnd > max || rnd < min); } while (rnd > max || rnd < min);
return rnd; return rnd;
}; }
/** /**
* Secure random bytes for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues() * 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 * @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) => { return new Promise((resolve) => {
let buf; let buf;
@ -272,7 +272,7 @@ const randBytes = async function (byteLength, forceLength = false) {
resolve(buf); resolve(buf);
} }
}); });
}; }
/** /**
* Finds the smallest positive element that is congruent to a in modulo n * 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 * @returns {bigint} The smallest positive representation of a in modulo n
*/ */
const toZn = function (a, n) { function toZn(a, n) {
n = BigInt(n); n = BigInt(n);
a = BigInt(a) % n; a = BigInt(a) % n;
return (a < 0) ? a + n : a; return (a < 0) ? a + n : a;
}; }

View File

@ -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};

View File

@ -9,10 +9,10 @@ Object.defineProperty(exports, '__esModule', { value: true });
* *
* @returns {bigint} the absolute value of a * @returns {bigint} the absolute value of a
*/ */
const abs = function (a) { function abs(a) {
a = BigInt(a); a = BigInt(a);
return (a >= BigInt(0)) ? a : -a; return (a >= BigInt(0)) ? a : -a;
}; }
/** /**
* @typedef {Object} egcdReturn A triple (g, x, y), such that ax + by = g = gcd(a, b). * @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} * @returns {egcdReturn}
*/ */
const eGcd = function (a, b) { function eGcd(a, b) {
a = BigInt(a); a = BigInt(a);
b = BigInt(b); b = BigInt(b);
let x = BigInt(0); let x = BigInt(0);
@ -54,7 +54,7 @@ const eGcd = function (a, b) {
x: x, x: x,
y: y y: y
}; };
}; }
/** /**
* Greatest-common divisor of two integers based on the iterative binary algorithm. * 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 * @returns {bigint} The greatest common divisor of a and b
*/ */
const gcd = function (a, b) { function gcd(a, b) {
a = abs(a); a = abs(a);
b = abs(b); b = abs(b);
let shift = BigInt(0); let shift = BigInt(0);
@ -86,7 +86,7 @@ const gcd = function (a, b) {
// rescale // rescale
return a << shift; 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) * 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) * @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); return _isProbablyPrime(w, iterations);
} }
}; }
/** /**
* The least common multiple computed as abs(a*b)/gcd(a,b) * 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 * @returns {bigint} The least common multiple of a and b
*/ */
const lcm = function (a, b) { function lcm(a, b) {
a = BigInt(a); a = BigInt(a);
b = BigInt(b); b = BigInt(b);
return abs(a * b) / gcd(a, b); return abs(a * b) / gcd(a, b);
}; }
/** /**
* Modular inverse. * Modular inverse.
@ -123,14 +123,14 @@ const lcm = function (a, b) {
* *
* @returns {bigint} the inverse modulo n * @returns {bigint} the inverse modulo n
*/ */
const modInv = function (a, n) { function modInv(a, n) {
let egcd = eGcd(a, n); let egcd = eGcd(a, n);
if (egcd.b !== BigInt(1)) { if (egcd.b !== BigInt(1)) {
return null; // modular inverse does not exist return null; // modular inverse does not exist
} else { } else {
return toZn(egcd.x, n); return toZn(egcd.x, n);
} }
}; }
/** /**
* Modular exponentiation a**b mod n * Modular exponentiation a**b mod n
@ -140,7 +140,7 @@ const modInv = function (a, n) {
* *
* @returns {bigint} a**b mod 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. // See Knuth, volume 2, section 4.6.3.
n = BigInt(n); n = BigInt(n);
a = toZn(a, n); a = toZn(a, n);
@ -161,7 +161,7 @@ const modPow = function (a, b, n) {
x = x % n; x = x % n;
} }
return result; return result;
}; }
/** /**
* A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator. * 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 * @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) => { return new Promise(async (resolve) => {
{ {
let rnd = BigInt(0); let rnd = BigInt(0);
@ -183,7 +183,7 @@ const prime = async function (bitLength, iterations = 16) {
resolve(rnd); resolve(rnd);
} }
}); });
}; }
/** /**
* Returns a cryptographically secure random integer between [min,max] * 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] * @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 bitLen = bitLength(max);
let byteLength = bitLen >> 3; let byteLength = bitLen >> 3;
let remaining = bitLen - (byteLength * 8); let remaining = bitLen - (byteLength * 8);
@ -211,7 +211,7 @@ const randBetween = async function (max, min = 1) {
rnd = fromBuffer(buf); rnd = fromBuffer(buf);
} while (rnd > max || rnd < min); } while (rnd > max || rnd < min);
return rnd; return rnd;
}; }
/** /**
* Secure random bytes for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues() * 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 * @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) => { return new Promise((resolve) => {
let buf; 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 * 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 * @returns {bigint} The smallest positive representation of a in modulo n
*/ */
const toZn = function (a, n) { function toZn(a, n) {
n = BigInt(n); n = BigInt(n);
a = BigInt(a) % n; a = BigInt(a) % n;
return (a < 0) ? a + n : a; return (a < 0) ? a + n : a;
}; }

View File

@ -7,10 +7,10 @@
* *
* @returns {bigint} the absolute value of a * @returns {bigint} the absolute value of a
*/ */
export const abs = function (a) { export function abs(a) {
a = BigInt(a); a = BigInt(a);
return (a >= BigInt(0)) ? a : -a; return (a >= BigInt(0)) ? a : -a;
}; }
/** /**
* @typedef {Object} egcdReturn A triple (g, x, y), such that ax + by = g = gcd(a, b). * @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} * @returns {egcdReturn}
*/ */
export const eGcd = function (a, b) { export function eGcd(a, b) {
a = BigInt(a); a = BigInt(a);
b = BigInt(b); b = BigInt(b);
let x = BigInt(0); let x = BigInt(0);
@ -52,7 +52,7 @@ export const eGcd = function (a, b) {
x: x, x: x,
y: y y: y
}; };
}; }
/** /**
* Greatest-common divisor of two integers based on the iterative binary algorithm. * 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 * @returns {bigint} The greatest common divisor of a and b
*/ */
export const gcd = function (a, b) { export function gcd(a, b) {
a = abs(a); a = abs(a);
b = abs(b); b = abs(b);
let shift = BigInt(0); let shift = BigInt(0);
@ -84,7 +84,7 @@ export const gcd = function (a, b) {
// rescale // rescale
return a << shift; 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) * 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) * @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) { if (process.browser) {
return new Promise(resolve => { return new Promise(resolve => {
let worker = new Worker(_isProbablyPrimeWorkerURL()); let worker = new Worker(_isProbablyPrimeWorkerURL());
@ -112,7 +112,7 @@ export const isProbablyPrime = async function (w, iterations = 16) {
} else { } else {
return _isProbablyPrime(w, iterations); return _isProbablyPrime(w, iterations);
} }
}; }
/** /**
* The least common multiple computed as abs(a*b)/gcd(a,b) * 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 * @returns {bigint} The least common multiple of a and b
*/ */
export const lcm = function (a, b) { export function lcm(a, b) {
a = BigInt(a); a = BigInt(a);
b = BigInt(b); b = BigInt(b);
return abs(a * b) / gcd(a, b); return abs(a * b) / gcd(a, b);
}; }
/** /**
* Modular inverse. * Modular inverse.
@ -135,14 +135,14 @@ export const lcm = function (a, b) {
* *
* @returns {bigint} the inverse modulo n * @returns {bigint} the inverse modulo n
*/ */
export const modInv = function (a, n) { export function modInv(a, n) {
let egcd = eGcd(a, n); let egcd = eGcd(a, n);
if (egcd.b !== BigInt(1)) { if (egcd.b !== BigInt(1)) {
return null; // modular inverse does not exist return null; // modular inverse does not exist
} else { } else {
return toZn(egcd.x, n); return toZn(egcd.x, n);
} }
}; }
/** /**
* Modular exponentiation a**b mod n * Modular exponentiation a**b mod n
@ -152,7 +152,7 @@ export const modInv = function (a, n) {
* *
* @returns {bigint} a**b mod 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. // See Knuth, volume 2, section 4.6.3.
n = BigInt(n); n = BigInt(n);
a = toZn(a, n); a = toZn(a, n);
@ -173,7 +173,7 @@ export const modPow = function (a, b, n) {
x = x % n; x = x % n;
} }
return result; return result;
}; }
/** /**
* A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator. * 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 * @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) => { return new Promise(async (resolve) => {
if (process.browser) { if (process.browser) {
let workerList = []; let workerList = [];
@ -231,7 +231,7 @@ export const prime = async function (bitLength, iterations = 16) {
resolve(rnd); resolve(rnd);
} }
}); });
}; }
/** /**
* Returns a cryptographically secure random integer between [min,max] * 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] * @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 bitLen = bitLength(max);
let byteLength = bitLen >> 3; let byteLength = bitLen >> 3;
let remaining = bitLen - (byteLength * 8); let remaining = bitLen - (byteLength * 8);
@ -259,7 +259,7 @@ export const randBetween = async function (max, min = 1) {
rnd = fromBuffer(buf); rnd = fromBuffer(buf);
} while (rnd > max || rnd < min); } while (rnd > max || rnd < min);
return rnd; return rnd;
}; }
/** /**
* Secure random bytes for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues() * 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 * @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) => { return new Promise((resolve) => {
let buf; let buf;
@ -292,7 +292,7 @@ export const randBytes = async function (byteLength, forceLength = false) {
resolve(buf); resolve(buf);
} }
}); });
}; }
/** /**
* Finds the smallest positive element that is congruent to a in modulo n * 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 * @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); n = BigInt(n);
a = BigInt(a) % n; a = BigInt(a) % n;
return (a < 0) ? a + n : a; return (a < 0) ? a + n : a;
}; }