project migrated to typescript
This commit is contained in:
parent
653fbd87fe
commit
8cf28b7587
|
@ -33,49 +33,49 @@ jobs:
|
|||
- name: test
|
||||
run: npm test
|
||||
|
||||
publication:
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
# publication:
|
||||
# needs: build
|
||||
# runs-on: ubuntu-latest
|
||||
# steps:
|
||||
# - uses: actions/checkout@v2
|
||||
|
||||
- uses: EndBug/version-check@v1
|
||||
id: check
|
||||
# - uses: EndBug/version-check@v1
|
||||
# id: check
|
||||
|
||||
- name: check version changes
|
||||
if: steps.check.outputs.changed == 'true'
|
||||
run: 'echo "Version change found! New version: ${{ steps.check.outputs.version }} (${{ steps.check.outputs.type }})"'
|
||||
# - name: check version changes
|
||||
# if: steps.check.outputs.changed == 'true'
|
||||
# run: 'echo "Version change found! New version: ${{ steps.check.outputs.version }} (${{ steps.check.outputs.type }})"'
|
||||
|
||||
- uses: actions/setup-node@v1
|
||||
if: steps.check.outputs.changed == 'true'
|
||||
with:
|
||||
node-version: 12
|
||||
registry-url: https://registry.npmjs.org/
|
||||
# - uses: actions/setup-node@v1
|
||||
# if: steps.check.outputs.changed == 'true'
|
||||
# with:
|
||||
# node-version: 14
|
||||
# registry-url: https://registry.npmjs.org/
|
||||
|
||||
- name: install
|
||||
if: steps.check.outputs.changed == 'true'
|
||||
run: npm ci
|
||||
# - name: install
|
||||
# if: steps.check.outputs.changed == 'true'
|
||||
# run: npm ci
|
||||
|
||||
- name: build
|
||||
if: steps.check.outputs.changed == 'true'
|
||||
run: npm run build
|
||||
# - name: build
|
||||
# if: steps.check.outputs.changed == 'true'
|
||||
# run: npm run build
|
||||
|
||||
- name: test
|
||||
if: steps.check.outputs.changed == 'true'
|
||||
run: npm test
|
||||
# - name: test
|
||||
# if: steps.check.outputs.changed == 'true'
|
||||
# run: npm test
|
||||
|
||||
- name: create code coverage report
|
||||
if: steps.check.outputs.changed == 'true'
|
||||
run: npm run coverage
|
||||
# - name: create code coverage report
|
||||
# if: steps.check.outputs.changed == 'true'
|
||||
# run: npm run coverage
|
||||
|
||||
- name: send report to coveralls.io
|
||||
if: steps.check.outputs.changed == 'true'
|
||||
uses: coverallsapp/github-action@master
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# - name: send report to coveralls.io
|
||||
# if: steps.check.outputs.changed == 'true'
|
||||
# uses: coverallsapp/github-action@master
|
||||
# with:
|
||||
# github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: publish to NPM
|
||||
if: steps.check.outputs.changed == 'true'
|
||||
run: npm publish
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
# - name: publish to NPM
|
||||
# if: steps.check.outputs.changed == 'true'
|
||||
# run: npm publish
|
||||
# env:
|
||||
# NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
@ -4,17 +4,14 @@ logs
|
|||
npm-debug.log*
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
node_modules
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Visual Studio Code
|
||||
.vscode
|
||||
|
||||
# IntelliJ
|
||||
.idea
|
||||
|
||||
# MYC output
|
||||
.nyc_output
|
||||
coverage/*
|
||||
coverage
|
||||
|
||||
# Test temporal files
|
||||
.mocha-ts
|
||||
|
|
28
.npmignore
28
.npmignore
|
@ -1,14 +1,9 @@
|
|||
# Build scripts
|
||||
build/*
|
||||
|
||||
# Source files
|
||||
src/*
|
||||
build
|
||||
|
||||
# Test files
|
||||
test/*
|
||||
|
||||
# Example files
|
||||
examples/*
|
||||
test
|
||||
**/*.spec.ts
|
||||
|
||||
# Logs
|
||||
logs
|
||||
|
@ -26,10 +21,19 @@ npm-debug.log*
|
|||
|
||||
# MYC output
|
||||
.nyc_output
|
||||
coverage/*
|
||||
|
||||
# Travis
|
||||
.travis.yml
|
||||
coverage
|
||||
|
||||
# GitHub
|
||||
.github
|
||||
|
||||
# tsconfig
|
||||
tsconfig.json
|
||||
|
||||
# SRC docs
|
||||
src/docs
|
||||
|
||||
# Test temporal files
|
||||
.mocha-ts
|
||||
|
||||
# Examples
|
||||
examples
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"typescript.tsdk": "node_modules/typescript/lib"
|
||||
}
|
454
README.md
454
README.md
|
@ -1,6 +1,6 @@
|
|||
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
|
||||
[![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)
|
||||
![Node CI](https://github.com/juanelas/bigint-crypto-utils/workflows/Node%20CI/badge.svg)
|
||||
[![Node CI](https://github.com/juanelas/bigint-crypto-utils/workflows/Node%20CI/badge.svg)](https://github.com/juanelas/bigint-crypto-utils/actions?query=workflow%3A%22Node+CI%22)
|
||||
[![Coverage Status](https://coveralls.io/repos/github/juanelas/bigint-crypto-utils/badge.svg?branch=master)](https://coveralls.io/github/juanelas/bigint-crypto-utils?branch=master)
|
||||
|
||||
# bigint-crypto-utils
|
||||
|
@ -13,38 +13,32 @@ Secure random numbers are generated using the native crypto implementation of th
|
|||
|
||||
> 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
|
||||
## Usage
|
||||
|
||||
bigint-crypto-utils can be imported to your project with `npm`:
|
||||
`bigint-crypto-utils` can be imported to your project with `npm`:
|
||||
|
||||
```bash
|
||||
```console
|
||||
npm install bigint-crypto-utils
|
||||
```
|
||||
|
||||
NPM installation defaults to the ES6 module for browsers and the CJS one for Node.js. For web browsers, you can also directly download the [IIFE bundle](https://raw.githubusercontent.com/juanelas/bigint-crypto-utils/master/lib/index.browser.bundle.iife.js) or the [ESM bundle](https://raw.githubusercontent.com/juanelas/bigint-crypto-utils/master/lib/index.browser.bundle.mod.js) from the repository.
|
||||
Then either require (Node.js CJS):
|
||||
|
||||
## Usage examples
|
||||
```javascript
|
||||
const bigintCryptoUtils = require('bigint-crypto-utils')
|
||||
```
|
||||
|
||||
Import your module as :
|
||||
or import (JavaScript ES module):
|
||||
|
||||
- Node.js
|
||||
```javascript
|
||||
import * as bigintCryptoUtils from 'bigint-crypto-utils'
|
||||
```
|
||||
|
||||
```javascript
|
||||
const bigintCryptoUtils = require('bigint-crypto-utils')
|
||||
... // your code here
|
||||
```
|
||||
The appropriate version for browser or node is automatically exported.
|
||||
|
||||
- JavaScript native or TypeScript project (including React and Angular JS)
|
||||
`bigint-crypto-utils` **CANNOT BE POLYFILLED** to suport older JS version (\< ES2020). If you are using webpack/babel to create your production bundles, you should target only the most modern browsers. For instance, for **React** apps created with [`create-react-app`](https://create-react-app.dev/), you should edit your `package.json` and modify the `browserList` so that it only targets the latest browsers (play with the number of versions that do not need polyfilling):
|
||||
|
||||
```javascript
|
||||
import * as bigintCryptoUtils from 'bigint-crypto-utils'
|
||||
... // your code here
|
||||
```
|
||||
|
||||
`bigint-crypto-utils` **CANNOT BE POLYFILLED** to suport older browsers. If you are using webpack/babel to create your production bundles, you should target only the most modern browsers. For instance, for **React** apps created with [`create-react-app`](https://create-react-app.dev/), you should edit your `package.json` and modify the `browserList` so that it only targets the latest browsers (play with the number of versions that do not need polyfilling):
|
||||
|
||||
```json
|
||||
"browserslist": {
|
||||
```json
|
||||
"browserslist": {
|
||||
"production": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
|
@ -55,47 +49,25 @@ Import your module as :
|
|||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
}
|
||||
```
|
||||
}
|
||||
```
|
||||
|
||||
Also, notice that [BigInt implementation is ES2020](https://tc39.es/ecma262/#sec-bigint-objects). In order to use it with TypeScript you will probably need to set `lib`, `target` and/or `module` to `es2020` in your project's `tsconfig.json`.
|
||||
Also, notice that [BigInt implementation is ES2020](https://tc39.es/ecma262/#sec-bigint-objects). In order to use it with TypeScript you need to set `target` to `ES2020` in your project's `tsconfig.json`.
|
||||
|
||||
If you are using Angular, since this library uses node typings, you should also add them to the `angularCompilerOptions` in your `tsconfig.json`:
|
||||
If you are using Angular, since this library uses node typings, you should also add them to the `angularCompilerOptions` in your `tsconfig.json`:
|
||||
|
||||
```json
|
||||
```json
|
||||
"angularCompilerOptions": {
|
||||
"types": ["node"]
|
||||
"types": ["node", ...]
|
||||
...
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
- JavaScript native browser ES module
|
||||
|
||||
```html
|
||||
<script type="module">
|
||||
import * as bigintCryptoUtils from 'index.browser.bundle.mod.js' // Use your actual path to the broser mod bundle that is in the lib directory
|
||||
... // your code here
|
||||
</script>
|
||||
```
|
||||
|
||||
- JavaScript native browser IIFE
|
||||
|
||||
```html
|
||||
<head>
|
||||
...
|
||||
<script src="index.browser.bundle.iife.js"></script> <!-- Use your actual path to the browser iife bundle that is in the lib directory -->
|
||||
</head>
|
||||
<body>
|
||||
...
|
||||
<script>
|
||||
... // your code here
|
||||
</script>
|
||||
</body>
|
||||
```
|
||||
You can also download the [IIFE bundle](https://raw.githubusercontent.com/juanelas/bigint-crypto-utils/master/dist/bundles/bigint-crypto-utils.iife.js), the [ESM bundle](https://raw.githubusercontent.com/juanelas/bigint-crypto-utils/master/dist/bundles/bigint-crypto-utils.esm.js) or the [UMD bundle](https://raw.githubusercontent.com/juanelas/bigint-crypto-utils/master/dist/bundles/bigint-crypto-utils.umd.js) and manually add it to your project, or, if you have already imported `bigint-crypto-utils` to your project, just get the bundles from `node_modules/bigint-crypto-utils/dist/bundles/`.
|
||||
|
||||
An example of usage could be:
|
||||
|
||||
```javascript
|
||||
```typescript
|
||||
/* A BigInt with value 666 can be declared calling the bigint constructor as
|
||||
BigInt('666') or with the shorter 666n.
|
||||
Notice that you can also pass a number to the constructor, e.g. BigInt(666).
|
||||
|
@ -114,14 +86,14 @@ console.log(bigintCryptoUtils.modInv(BigInt('3'), BigInt('5'))) // prints 2
|
|||
|
||||
console.log(bigintCryptoUtils.randBetween(2n ** 256n)) // Prints a cryptographically secure random number between 1 and 2**256 bits.
|
||||
|
||||
async function primeTesting () {
|
||||
async function primeTesting (): void {
|
||||
// Output of a probable prime of 2048 bits
|
||||
console.log(await bigintCryptoUtils.prime(2048))
|
||||
|
||||
// Testing if a number is a probable prime (Miller-Rabin)
|
||||
const number = 27n
|
||||
const isPrime = await bigintCryptoUtils.isProbablyPrime(number)
|
||||
if (isPrime) {
|
||||
if (isPrime === true) {
|
||||
console.log(`${number} is prime`)
|
||||
} else {
|
||||
console.log(`${number} is composite`)
|
||||
|
@ -132,376 +104,6 @@ primeTesting()
|
|||
|
||||
```
|
||||
|
||||
You can find examples in the [examples folder of the repository](https://github.com/juanelas/bigint-crypto-utils/tree/master/examples).
|
||||
|
||||
## API reference documentation
|
||||
|
||||
### Functions
|
||||
|
||||
<dl>
|
||||
<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="#bitLength">bitLength(a)</a> ⇒ <code>number</code></dt>
|
||||
<dd><p>Returns the bitlength of a number</p>
|
||||
</dd>
|
||||
<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, 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(w, [iterations], [disableWorkers])</a> ⇒ <code>Promise.<boolean></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, 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="#max">max(a, b)</a> ⇒ <code>bigint</code></dt>
|
||||
<dd><p>Maximum. max(a,b)==a if a>=b. max(a,b)==b if a<=b</p>
|
||||
</dd>
|
||||
<dt><a href="#min">min(a, b)</a> ⇒ <code>bigint</code></dt>
|
||||
<dd><p>Minimum. min(a,b)==b if a>=b. min(a,b)==a if a<=b</p>
|
||||
</dd>
|
||||
<dt><a href="#modInv">modInv(a, n)</a> ⇒ <code>bigint</code></dt>
|
||||
<dd><p>Modular inverse.</p>
|
||||
</dd>
|
||||
<dt><a href="#modPow">modPow(b, e, n)</a> ⇒ <code>bigint</code></dt>
|
||||
<dd><p>Modular exponentiation b**e mod n. Currently using the right-to-left binary method</p>
|
||||
</dd>
|
||||
<dt><a href="#prime">prime(bitLength, [iterations])</a> ⇒ <code>Promise.<bigint></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).
|
||||
The node version can also use worker_threads if they are available (enabled by default with Node 11 and
|
||||
and can be enabled at runtime executing node --experimental-worker with node >=10.5.0).</p>
|
||||
</dd>
|
||||
<dt><a href="#primeSync">primeSync(bitLength, [iterations])</a> ⇒ <code>bigint</code></dt>
|
||||
<dd><p>A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator.
|
||||
The sync version is NOT RECOMMENDED since it won't use workers and thus it'll be slower and may freeze thw window in browser's javascript. Please consider using prime() instead.</p>
|
||||
</dd>
|
||||
<dt><a href="#randBetween">randBetween(max, [min])</a> ⇒ <code>bigint</code></dt>
|
||||
<dd><p>Returns a cryptographically secure random integer between [min,max]. Both numbers must be >=0</p>
|
||||
</dd>
|
||||
<dt><a href="#randBits">randBits(bitLength, [forceLength])</a> ⇒ <code>Promise.<(Buffer|Uint8Array)></code></dt>
|
||||
<dd><p>Secure random bits for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()</p>
|
||||
</dd>
|
||||
<dt><a href="#randBitsSync">randBitsSync(bitLength, [forceLength])</a> ⇒ <code>Buffer</code> | <code>Uint8Array</code></dt>
|
||||
<dd><p>Secure random bits for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()</p>
|
||||
</dd>
|
||||
<dt><a href="#randBytes">randBytes(byteLength, [forceLength])</a> ⇒ <code>Promise.<(Buffer|Uint8Array)></code></dt>
|
||||
<dd><p>Secure random bytes for both node and browsers. Node version uses crypto.randomBytes() and browser one self.crypto.getRandomValues()</p>
|
||||
</dd>
|
||||
<dt><a href="#randBytesSync">randBytesSync(byteLength, [forceLength])</a> ⇒ <code>Buffer</code> | <code>Uint8Array</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, n)</a> ⇒ <code>bigint</code></dt>
|
||||
<dd><p>Finds the smallest positive element that is congruent to a in modulo n</p>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
### Typedefs
|
||||
|
||||
<dl>
|
||||
<dt><a href="#egcdReturn">egcdReturn</a> : <code>Object</code></dt>
|
||||
<dd><p>A triple (g, x, y), such that ax + by = g = gcd(a, b).</p>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<a name="abs"></a>
|
||||
|
||||
### abs(a) ⇒ <code>bigint</code>
|
||||
Absolute value. abs(a)==a if a>=0. abs(a)==-a if a<0
|
||||
|
||||
**Kind**: global function
|
||||
**Returns**: <code>bigint</code> - the absolute value of a
|
||||
|
||||
| Param | Type |
|
||||
| --- | --- |
|
||||
| a | <code>number</code> \| <code>bigint</code> |
|
||||
|
||||
<a name="bitLength"></a>
|
||||
|
||||
### bitLength(a) ⇒ <code>number</code>
|
||||
Returns the bitlength of a number
|
||||
|
||||
**Kind**: global function
|
||||
**Returns**: <code>number</code> - - the bit length
|
||||
|
||||
| Param | Type |
|
||||
| --- | --- |
|
||||
| a | <code>number</code> \| <code>bigint</code> |
|
||||
|
||||
<a name="eGcd"></a>
|
||||
|
||||
### 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 function
|
||||
**Returns**: [<code>egcdReturn</code>](#egcdReturn) - A triple (g, x, y), such that ax + by = g = gcd(a, b).
|
||||
**Throws**:
|
||||
|
||||
- <code>RangeError</code> a and b MUST be > 0
|
||||
|
||||
|
||||
| Param | Type |
|
||||
| --- | --- |
|
||||
| a | <code>number</code> \| <code>bigint</code> |
|
||||
| b | <code>number</code> \| <code>bigint</code> |
|
||||
|
||||
<a name="egcdReturn"></a>
|
||||
|
||||
### egcdReturn : <code>Object</code>
|
||||
A triple (g, x, y), such that ax + by = g = gcd(a, b).
|
||||
|
||||
**Kind**: global typedef
|
||||
**Properties**
|
||||
|
||||
| Name | Type |
|
||||
| --- | --- |
|
||||
| g | <code>bigint</code> |
|
||||
| x | <code>bigint</code> |
|
||||
| y | <code>bigint</code> |
|
||||
|
||||
<a name="gcd"></a>
|
||||
|
||||
### gcd(a, b) ⇒ <code>bigint</code>
|
||||
Greatest-common divisor of two integers based on the iterative binary algorithm.
|
||||
|
||||
**Kind**: global function
|
||||
**Returns**: <code>bigint</code> - The greatest common divisor of a and b
|
||||
|
||||
| Param | Type |
|
||||
| --- | --- |
|
||||
| a | <code>number</code> \| <code>bigint</code> |
|
||||
| b | <code>number</code> \| <code>bigint</code> |
|
||||
|
||||
<a name="isProbablyPrime"></a>
|
||||
|
||||
### isProbablyPrime(w, [iterations], [disableWorkers]) ⇒ <code>Promise.<boolean></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 function
|
||||
**Returns**: <code>Promise.<boolean></code> - A promise that resolves to a boolean that is either true (a probably prime number) or false (definitely composite)
|
||||
**Throws**:
|
||||
|
||||
- <code>RangeError</code> w MUST be >= 0
|
||||
|
||||
|
||||
| Param | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| w | <code>number</code> \| <code>bigint</code> | | A positive integer to be tested for primality |
|
||||
| [iterations] | <code>number</code> | <code>16</code> | The number of iterations for the primality test. The value shall be consistent with Table C.1, C.2 or C.3 |
|
||||
| [disableWorkers] | <code>boolean</code> | <code>false</code> | Disable the use of workers for the primality test |
|
||||
|
||||
<a name="lcm"></a>
|
||||
|
||||
### lcm(a, b) ⇒ <code>bigint</code>
|
||||
The least common multiple computed as abs(a*b)/gcd(a,b)
|
||||
|
||||
**Kind**: global function
|
||||
**Returns**: <code>bigint</code> - The least common multiple of a and b
|
||||
|
||||
| Param | Type |
|
||||
| --- | --- |
|
||||
| a | <code>number</code> \| <code>bigint</code> |
|
||||
| b | <code>number</code> \| <code>bigint</code> |
|
||||
|
||||
<a name="max"></a>
|
||||
|
||||
### max(a, b) ⇒ <code>bigint</code>
|
||||
Maximum. max(a,b)==a if a>=b. max(a,b)==b if a<=b
|
||||
|
||||
**Kind**: global function
|
||||
**Returns**: <code>bigint</code> - maximum of numbers a and b
|
||||
|
||||
| Param | Type |
|
||||
| --- | --- |
|
||||
| a | <code>number</code> \| <code>bigint</code> |
|
||||
| b | <code>number</code> \| <code>bigint</code> |
|
||||
|
||||
<a name="min"></a>
|
||||
|
||||
### min(a, b) ⇒ <code>bigint</code>
|
||||
Minimum. min(a,b)==b if a>=b. min(a,b)==a if a<=b
|
||||
|
||||
**Kind**: global function
|
||||
**Returns**: <code>bigint</code> - minimum of numbers a and b
|
||||
|
||||
| Param | Type |
|
||||
| --- | --- |
|
||||
| a | <code>number</code> \| <code>bigint</code> |
|
||||
| b | <code>number</code> \| <code>bigint</code> |
|
||||
|
||||
<a name="modInv"></a>
|
||||
|
||||
### modInv(a, n) ⇒ <code>bigint</code>
|
||||
Modular inverse.
|
||||
|
||||
**Kind**: global function
|
||||
**Returns**: <code>bigint</code> - the inverse modulo n
|
||||
**Throws**:
|
||||
|
||||
- <code>RangeError</code> a does not have inverse modulo n
|
||||
|
||||
|
||||
| Param | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| a | <code>number</code> \| <code>bigint</code> | The number to find an inverse for |
|
||||
| n | <code>number</code> \| <code>bigint</code> | The modulo |
|
||||
|
||||
<a name="modPow"></a>
|
||||
|
||||
### modPow(b, e, n) ⇒ <code>bigint</code>
|
||||
Modular exponentiation b**e mod n. Currently using the right-to-left binary method
|
||||
|
||||
**Kind**: global function
|
||||
**Returns**: <code>bigint</code> - b**e mod n
|
||||
|
||||
| Param | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| b | <code>number</code> \| <code>bigint</code> | base |
|
||||
| e | <code>number</code> \| <code>bigint</code> | exponent |
|
||||
| n | <code>number</code> \| <code>bigint</code> | modulo |
|
||||
|
||||
<a name="prime"></a>
|
||||
|
||||
### prime(bitLength, [iterations]) ⇒ <code>Promise.<bigint></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).
|
||||
The node version can also use worker_threads if they are available (enabled by default with Node 11 and
|
||||
and can be enabled at runtime executing node --experimental-worker with node >=10.5.0).
|
||||
|
||||
**Kind**: global function
|
||||
**Returns**: <code>Promise.<bigint></code> - A promise that resolves to a bigint probable prime of bitLength bits.
|
||||
**Throws**:
|
||||
|
||||
- <code>RangeError</code> bitLength MUST be > 0
|
||||
|
||||
|
||||
| Param | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| bitLength | <code>number</code> | | The required bit length for the generated prime |
|
||||
| [iterations] | <code>number</code> | <code>16</code> | The number of iterations for the Miller-Rabin Probabilistic Primality Test |
|
||||
|
||||
<a name="primeSync"></a>
|
||||
|
||||
### primeSync(bitLength, [iterations]) ⇒ <code>bigint</code>
|
||||
A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator.
|
||||
The sync version is NOT RECOMMENDED since it won't use workers and thus it'll be slower and may freeze thw window in browser's javascript. Please consider using prime() instead.
|
||||
|
||||
**Kind**: global function
|
||||
**Returns**: <code>bigint</code> - A bigint probable prime of bitLength bits.
|
||||
**Throws**:
|
||||
|
||||
- <code>RangeError</code> bitLength MUST be > 0
|
||||
|
||||
|
||||
| Param | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| bitLength | <code>number</code> | | The required bit length for the generated prime |
|
||||
| [iterations] | <code>number</code> | <code>16</code> | The number of iterations for the Miller-Rabin Probabilistic Primality Test |
|
||||
|
||||
<a name="randBetween"></a>
|
||||
|
||||
### randBetween(max, [min]) ⇒ <code>bigint</code>
|
||||
Returns a cryptographically secure random integer between [min,max]. Both numbers must be >=0
|
||||
|
||||
**Kind**: global function
|
||||
**Returns**: <code>bigint</code> - A cryptographically secure random bigint between [min,max]
|
||||
**Throws**:
|
||||
|
||||
- <code>RangeError</code> Arguments MUST be: max > 0 && min >=0 && max > min
|
||||
|
||||
|
||||
| Param | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| max | <code>bigint</code> | | Returned value will be <= max |
|
||||
| [min] | <code>bigint</code> | <code>BigInt(1)</code> | Returned value will be >= min |
|
||||
|
||||
<a name="randBits"></a>
|
||||
|
||||
### randBits(bitLength, [forceLength]) ⇒ <code>Promise.<(Buffer\|Uint8Array)></code>
|
||||
Secure random bits for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()
|
||||
|
||||
**Kind**: global function
|
||||
**Returns**: <code>Promise.<(Buffer\|Uint8Array)></code> - A Promise that resolves to a Buffer/UInt8Array (Node.js/Browser) filled with cryptographically secure random bits
|
||||
**Throws**:
|
||||
|
||||
- <code>RangeError</code> bitLength MUST be > 0
|
||||
|
||||
|
||||
| Param | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| bitLength | <code>number</code> | | The desired number of random bits |
|
||||
| [forceLength] | <code>boolean</code> | <code>false</code> | If we want to force the output to have a specific bit length. It basically forces the msb to be 1 |
|
||||
|
||||
<a name="randBitsSync"></a>
|
||||
|
||||
### randBitsSync(bitLength, [forceLength]) ⇒ <code>Buffer</code> \| <code>Uint8Array</code>
|
||||
Secure random bits for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()
|
||||
|
||||
**Kind**: global function
|
||||
**Returns**: <code>Buffer</code> \| <code>Uint8Array</code> - A Buffer/UInt8Array (Node.js/Browser) filled with cryptographically secure random bits
|
||||
**Throws**:
|
||||
|
||||
- <code>RangeError</code> bitLength MUST be > 0
|
||||
|
||||
|
||||
| Param | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| bitLength | <code>number</code> | | The desired number of random bits |
|
||||
| [forceLength] | <code>boolean</code> | <code>false</code> | If we want to force the output to have a specific bit length. It basically forces the msb to be 1 |
|
||||
|
||||
<a name="randBytes"></a>
|
||||
|
||||
### randBytes(byteLength, [forceLength]) ⇒ <code>Promise.<(Buffer\|Uint8Array)></code>
|
||||
Secure random bytes for both node and browsers. Node version uses crypto.randomBytes() and browser one self.crypto.getRandomValues()
|
||||
|
||||
**Kind**: global function
|
||||
**Returns**: <code>Promise.<(Buffer\|Uint8Array)></code> - A promise that resolves to a Buffer/UInt8Array (Node.js/Browser) filled with cryptographically secure random bytes
|
||||
**Throws**:
|
||||
|
||||
- <code>RangeError</code> byteLength MUST be > 0
|
||||
|
||||
|
||||
| Param | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| byteLength | <code>number</code> | | The desired number of random bytes |
|
||||
| [forceLength] | <code>boolean</code> | <code>false</code> | If we want to force the output to have a bit length of 8*byteLength. It basically forces the msb to be 1 |
|
||||
|
||||
<a name="randBytesSync"></a>
|
||||
|
||||
### randBytesSync(byteLength, [forceLength]) ⇒ <code>Buffer</code> \| <code>Uint8Array</code>
|
||||
Secure random bytes for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()
|
||||
|
||||
**Kind**: global function
|
||||
**Returns**: <code>Buffer</code> \| <code>Uint8Array</code> - A Buffer/UInt8Array (Node.js/Browser) filled with cryptographically secure random bytes
|
||||
**Throws**:
|
||||
|
||||
- <code>RangeError</code> byteLength MUST be > 0
|
||||
|
||||
|
||||
| Param | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| byteLength | <code>number</code> | | The desired number of random bytes |
|
||||
| [forceLength] | <code>boolean</code> | <code>false</code> | If we want to force the output to have a bit length of 8*byteLength. It basically forces the msb to be 1 |
|
||||
|
||||
<a name="toZn"></a>
|
||||
|
||||
### toZn(a, n) ⇒ <code>bigint</code>
|
||||
Finds the smallest positive element that is congruent to a in modulo n
|
||||
|
||||
**Kind**: global function
|
||||
**Returns**: <code>bigint</code> - The smallest positive representation of a in modulo n
|
||||
|
||||
| Param | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| a | <code>number</code> \| <code>bigint</code> | An integer |
|
||||
| n | <code>number</code> \| <code>bigint</code> | The modulo |
|
||||
|
||||
[Check the API](./docs/API.md)
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
#! /usr/bin/env node
|
||||
const path = require('path')
|
||||
const childProcess = require('child_process')
|
||||
|
||||
const rootDir = path.join(__dirname, '../..')
|
||||
const mochaTsRelativeDir = '.mocha-ts'
|
||||
const minimatch = require('minimatch')
|
||||
const glob = require('glob')
|
||||
|
||||
// First let us prepare the args to pass to mocha.
|
||||
// ts.files will be replaced by their js-transpiled counterparts
|
||||
// a watch file to our semaphore will be added
|
||||
const processedArgs = processArgs(process.argv.slice(2))
|
||||
|
||||
// Now we can run a script and invoke a callback when complete, e.g.
|
||||
runScript(path.join(rootDir, 'node_modules/.bin/mocha'), processArgs(processedArgs))
|
||||
|
||||
function processArgs (args) {
|
||||
args = process.argv.slice(2).map(arg => {
|
||||
const filenames = glob.sync(arg, { cwd: rootDir, matchBase: true })
|
||||
if (filenames.length > 0) {
|
||||
return filenames.map(file => {
|
||||
const isTsTestFile = minimatch(file, '{test/**/*.ts,src/**/*.spec.ts}', { matchBase: true })
|
||||
if (isTsTestFile) {
|
||||
return `${mochaTsRelativeDir}/${file.slice(0, -3)}.js`
|
||||
}
|
||||
return file
|
||||
})
|
||||
}
|
||||
return arg
|
||||
})
|
||||
|
||||
const processedArgs = []
|
||||
|
||||
let addSemaphore = false
|
||||
let semaphoreAdded = false
|
||||
for (const arg of args) {
|
||||
if (Array.isArray(arg)) {
|
||||
processedArgs.push(...arg)
|
||||
} else {
|
||||
processedArgs.push(arg)
|
||||
if (arg === '--watch' || arg === '-w') {
|
||||
addSemaphore = true
|
||||
} else if (arg === '--watch-files') {
|
||||
processedArgs.push(`${mochaTsRelativeDir}/semaphore`)
|
||||
semaphoreAdded = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if (addSemaphore === true || semaphoreAdded === false) {
|
||||
processedArgs.push('--watch-files')
|
||||
processedArgs.push(`${mochaTsRelativeDir}/semaphore`)
|
||||
}
|
||||
|
||||
return processedArgs
|
||||
}
|
||||
|
||||
function runScript (scriptPath, args) {
|
||||
const mochaCmd = childProcess.fork(path.join(rootDir, 'node_modules/.bin/mocha'), processedArgs, {
|
||||
cwd: rootDir
|
||||
})
|
||||
|
||||
mochaCmd.on('error', (error) => {
|
||||
throw error
|
||||
})
|
||||
|
||||
// execute the callback once the process has finished running
|
||||
mochaCmd.on('exit', function (code) {
|
||||
if (code !== 0) {
|
||||
throw new Error('exit code ' + code)
|
||||
}
|
||||
})
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
'use strict'
|
||||
|
||||
const fs = require('fs')
|
||||
const jsdoc2md = require('jsdoc-to-markdown')
|
||||
const TypeDoc = require('typedoc')
|
||||
const path = require('path')
|
||||
const pkgJson = require('../package.json')
|
||||
|
||||
|
@ -14,6 +14,33 @@ function camelise (str) {
|
|||
})
|
||||
}
|
||||
|
||||
async function typedoc () {
|
||||
const app = new TypeDoc.Application()
|
||||
|
||||
// If you want TypeDoc to load tsconfig.json / typedoc.json files
|
||||
app.options.addReader(new TypeDoc.TSConfigReader())
|
||||
app.options.addReader(new TypeDoc.TypeDocReader())
|
||||
|
||||
app.bootstrap({
|
||||
// typedoc options here
|
||||
entryPoints: ['src/index.ts'],
|
||||
plugin: ['typedoc-plugin-markdown'],
|
||||
includeVersion: true,
|
||||
entryDocument: 'API.md',
|
||||
readme: 'none'
|
||||
})
|
||||
|
||||
const project = app.convert()
|
||||
|
||||
if (project) {
|
||||
// Project may not have converted correctly
|
||||
const output = path.join(rootDir, './docs')
|
||||
|
||||
// Rendered docs
|
||||
await app.generateDocs(project, output)
|
||||
}
|
||||
}
|
||||
|
||||
function getRepositoryData () {
|
||||
if (typeof pkgJson.repository === 'string') {
|
||||
const repodata = pkgJson.repository.split(/[:/]/)
|
||||
|
@ -30,40 +57,45 @@ function getRepositoryData () {
|
|||
|
||||
const { repoProvider, repoUsername, repoName } = getRepositoryData() || { repoProvider: null, repoUsername: null, repoName: null }
|
||||
|
||||
let iifeBundle, esmBundle, workflowBadget, coverallsBadge
|
||||
if (repoProvider && repoProvider === 'github') {
|
||||
iifeBundle = `[IIFE bundle](https://raw.githubusercontent.com/${repoUsername}/${repoName}/master/lib/index.browser.bundle.iife.js)`
|
||||
esmBundle = `[ESM bundle](https://raw.githubusercontent.com/${repoUsername}/${repoName}/master/lib/index.browser.bundle.mod.js)`
|
||||
workflowBadget = `![Node CI](https://github.com/${repoUsername}/${repoName}/workflows/Node%20CI/badge.svg)`
|
||||
const regex = /^(?:(?<scope>@.*?)\/)?(?<name>.*)/ // We are going to take only the package name part if there is a scope, e.g. @my-org/package-name
|
||||
const { name } = pkgJson.name.match(regex).groups
|
||||
const camelCaseName = camelise(name)
|
||||
|
||||
let iifeBundle, esmBundle, umdBundle, workflowBadget, coverallsBadge
|
||||
if (repoProvider) {
|
||||
switch (repoProvider) {
|
||||
case 'github':
|
||||
iifeBundle = `[IIFE bundle](https://raw.githubusercontent.com/${repoUsername}/${repoName}/master/dist/bundles/${name}.iife.js)`
|
||||
esmBundle = `[ESM bundle](https://raw.githubusercontent.com/${repoUsername}/${repoName}/master/dist/bundles/${name}.esm.js)`
|
||||
umdBundle = `[UMD bundle](https://raw.githubusercontent.com/${repoUsername}/${repoName}/master/dist/bundles/${name}.umd.js)`
|
||||
workflowBadget = `[![Node CI](https://github.com/${repoUsername}/${repoName}/workflows/Node%20CI/badge.svg)](https://github.com/${repoUsername}/${repoName}/actions?query=workflow%3A%22Node+CI%22)`
|
||||
coverallsBadge = `[![Coverage Status](https://coveralls.io/repos/github/${repoUsername}/${repoName}/badge.svg?branch=master)](https://coveralls.io/github/${repoUsername}/${repoName}?branch=master)`
|
||||
break
|
||||
|
||||
case 'gitlab':
|
||||
iifeBundle = `[IIFE bundle](https://gitlab.com/${repoUsername}/${repoName}/-/raw/master/dist/bundles/${name}.iife.js?inline=false)`
|
||||
esmBundle = `[ESM bundle](https://gitlab.com/${repoUsername}/${repoName}/-/raw/master/dist/bundles/${name}.esm.js?inline=false)`
|
||||
umdBundle = `[IIFE bundle](https://gitlab.com/${repoUsername}/${repoName}/-/raw/master/dist/bundles/${name}.umd.js?inline=false)`
|
||||
break
|
||||
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
const templateFile = path.join(rootDir, pkgJson.directories.src, 'doc', 'readme-template.md')
|
||||
const templateFile = path.join(rootDir, pkgJson.directories.src, 'docs/index.md')
|
||||
let template = fs.readFileSync(templateFile, { encoding: 'UTF-8' })
|
||||
.replace(/\{\{PKG_NAME\}\}/g, pkgJson.name)
|
||||
.replace(/\{\{PKG_CAMELCASE\}\}/g, camelise(pkgJson.name))
|
||||
.replace(/\{\{PKG_CAMELCASE\}\}/g, camelCaseName)
|
||||
.replace(/\{\{IIFE_BUNDLE\}\}/g, iifeBundle || 'IIFE bundle')
|
||||
.replace(/\{\{ESM_BUNDLE\}\}/g, esmBundle || 'ESM bundle')
|
||||
.replace(/\{\{UMD_BUNDLE\}\}/g, umdBundle || 'UMD bundle')
|
||||
|
||||
if (repoProvider && repoProvider === 'github') {
|
||||
template = template.replace(/\{\{GITHUB_ACTIONS_BADGES\}\}/g, workflowBadget + '\n' + coverallsBadge)
|
||||
}
|
||||
|
||||
const input = path.join(rootDir, pkgJson.browser)
|
||||
// Let us replace bigint literals by standard numbers to avoid issues with bigint
|
||||
const source = fs.readFileSync(input, { encoding: 'UTF-8' }).replace(/([0-9]+)n([,\s\n)])/g, '$1$2')
|
||||
const readmeFile = path.join(rootDir, 'README.md')
|
||||
fs.writeFileSync(readmeFile, template)
|
||||
|
||||
jsdoc2md.clear().then(() => {
|
||||
const data = jsdoc2md.getTemplateDataSync({ source })
|
||||
data.sort((fn1, fn2) => (fn1.id > fn2.id) ? 1 : -1) // sort functions alphabetically
|
||||
const options = {
|
||||
data,
|
||||
template,
|
||||
'heading-depth': 3 // The initial heading depth. For example, with a value of 2 the top-level markdown headings look like "## The heading"
|
||||
// 'global-index-format': 'none' // none, grouped, table, dl.
|
||||
}
|
||||
const readmeContents = jsdoc2md.renderSync(options)
|
||||
|
||||
const readmeFile = path.join(rootDir, 'README.md')
|
||||
fs.writeFileSync(readmeFile, readmeContents)
|
||||
})
|
||||
typedoc()
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
const fs = require('fs')
|
||||
const ts = require('typescript')
|
||||
const path = require('path')
|
||||
const pkgJson = require('../package.json')
|
||||
|
||||
const rootDir = path.join(__dirname, '..')
|
||||
const jsFile = path.join(rootDir, pkgJson.browser)
|
||||
const dtsFile = path.join(rootDir, pkgJson.types)
|
||||
|
||||
const compilerOptions = {
|
||||
declaration: true,
|
||||
noEmit: false,
|
||||
emitDeclarationOnly: true,
|
||||
allowJs: true
|
||||
}
|
||||
|
||||
const host = ts.createCompilerHost(compilerOptions)
|
||||
|
||||
host.writeFile = (fileName, contents) => {
|
||||
fs.writeFileSync(dtsFile, contents)
|
||||
}
|
||||
|
||||
// Prepare and emit the d.ts files
|
||||
const program = ts.createProgram([jsFile], compilerOptions, host)
|
||||
program.emit()
|
|
@ -3,13 +3,16 @@
|
|||
const resolve = require('@rollup/plugin-node-resolve').nodeResolve
|
||||
const replace = require('@rollup/plugin-replace')
|
||||
const { terser } = require('rollup-plugin-terser')
|
||||
const typescriptPlugin = require('@rollup/plugin-typescript')
|
||||
const commonjs = require('@rollup/plugin-commonjs')
|
||||
|
||||
const path = require('path')
|
||||
const fs = require('fs')
|
||||
const pkgJson = require('../package.json')
|
||||
|
||||
const rootDir = path.join(__dirname, '..')
|
||||
const srcDir = path.join(rootDir, pkgJson.directories.src)
|
||||
const dstDir = path.join(rootDir, pkgJson.directories.lib)
|
||||
const dstDir = path.join(rootDir, pkgJson.directories.dist)
|
||||
const srcDir = path.join(rootDir, 'src')
|
||||
|
||||
function camelise (str) {
|
||||
return str.replace(/-([a-z])/g,
|
||||
|
@ -18,61 +21,113 @@ function camelise (str) {
|
|||
})
|
||||
}
|
||||
|
||||
const pkgName = pkgJson.name
|
||||
const pkgCamelisedName = camelise(pkgName)
|
||||
const regex = /^(?:(?<scope>@.*?)\/)?(?<name>.*)/ // We are going to take only the package name part if there is a scope, e.g. @my-org/package-name
|
||||
const { name } = pkgJson.name.match(regex).groups
|
||||
const pkgCamelisedName = camelise(name)
|
||||
|
||||
const input = path.join(srcDir, 'js', 'index.js')
|
||||
const input = path.join(srcDir, 'index.ts')
|
||||
if (fs.existsSync(input) !== true) throw new Error('The entry point should be index.ts')
|
||||
|
||||
const tsBundleOptions = {
|
||||
exclude: ['test/**/*', 'src/**/*.spec.ts', './build/typings/global-this-pkg.d.ts']
|
||||
}
|
||||
|
||||
const external = [...Object.keys(pkgJson.dependencies || {}), ...Object.keys(pkgJson.peerDependencies || {})]
|
||||
|
||||
const sourcemapOutputOptions = {
|
||||
sourcemap: 'inline',
|
||||
sourcemapExcludeSources: true
|
||||
}
|
||||
|
||||
module.exports = [
|
||||
{ // Native JS
|
||||
{ // ESM for browsers
|
||||
input: input,
|
||||
output: [
|
||||
{
|
||||
file: path.join(rootDir, pkgJson.browser),
|
||||
file: path.join(rootDir, pkgJson.exports['.'].default),
|
||||
...sourcemapOutputOptions,
|
||||
format: 'es'
|
||||
}
|
||||
],
|
||||
plugins: [
|
||||
replace({
|
||||
'process.browser': true
|
||||
})
|
||||
]
|
||||
IS_BROWSER: true,
|
||||
preventAssignment: true
|
||||
}),
|
||||
typescriptPlugin(tsBundleOptions)
|
||||
],
|
||||
external
|
||||
},
|
||||
{ // Browser bundles
|
||||
input: input,
|
||||
output: [
|
||||
{
|
||||
file: path.join(dstDir, 'index.browser.bundle.iife.js'),
|
||||
file: path.join(dstDir, `bundles/${name}.iife.js`),
|
||||
format: 'iife',
|
||||
name: pkgCamelisedName
|
||||
},
|
||||
{
|
||||
file: path.join(dstDir, 'index.browser.bundle.mod.js'),
|
||||
file: path.join(dstDir, `bundles/${name}.esm.js`),
|
||||
format: 'es'
|
||||
},
|
||||
{
|
||||
file: path.join(dstDir, `bundles/${name}.umd.js`),
|
||||
format: 'umd',
|
||||
name: pkgCamelisedName
|
||||
}
|
||||
],
|
||||
plugins: [
|
||||
replace({
|
||||
'process.browser': true
|
||||
IS_BROWSER: true,
|
||||
preventAssignment: true
|
||||
}),
|
||||
typescriptPlugin(tsBundleOptions),
|
||||
resolve({
|
||||
browser: true
|
||||
browser: true,
|
||||
exportConditions: ['browser', 'module', 'import', 'default']
|
||||
}),
|
||||
terser()
|
||||
]
|
||||
},
|
||||
{ // Node
|
||||
{ // Node ESM with declaration files
|
||||
input: input,
|
||||
output: {
|
||||
file: path.join(rootDir, pkgJson.main),
|
||||
format: 'cjs',
|
||||
esModule: false,
|
||||
externalLiveBindings: false
|
||||
dir: path.join(rootDir, path.dirname(pkgJson.exports['.'].node.import)),
|
||||
entryFileNames: path.basename(pkgJson.exports['.'].node.import),
|
||||
...sourcemapOutputOptions,
|
||||
format: 'es'
|
||||
},
|
||||
plugins: [
|
||||
replace({
|
||||
'process.browser': false
|
||||
})
|
||||
IS_BROWSER: false,
|
||||
preventAssignment: true
|
||||
}),
|
||||
typescriptPlugin({
|
||||
...tsBundleOptions,
|
||||
declaration: true,
|
||||
outDir: path.join(rootDir, path.dirname(pkgJson.exports['.'].node.import)),
|
||||
declarationDir: path.join(rootDir, path.dirname(pkgJson.exports['.'].node.import), 'types'),
|
||||
declarationMap: true
|
||||
}),
|
||||
commonjs({ extensions: ['.js', '.ts'] }) // the ".ts" extension is required
|
||||
],
|
||||
external
|
||||
},
|
||||
{ // Node CJS
|
||||
input: input,
|
||||
output: {
|
||||
dir: path.join(rootDir, path.dirname(pkgJson.exports['.'].node.require)),
|
||||
entryFileNames: path.basename(pkgJson.exports['.'].node.require),
|
||||
...sourcemapOutputOptions,
|
||||
format: 'cjs'
|
||||
},
|
||||
plugins: [
|
||||
replace({
|
||||
IS_BROWSER: false,
|
||||
preventAssignment: true
|
||||
}),
|
||||
typescriptPlugin(tsBundleOptions),
|
||||
commonjs({ extensions: ['.js', '.ts'] }) // the ".ts" extension is required
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const resolve = require('@rollup/plugin-node-resolve').nodeResolve
|
||||
const replace = require('@rollup/plugin-replace')
|
||||
const commonjs = require('@rollup/plugin-commonjs')
|
||||
const multi = require('@rollup/plugin-multi-entry')
|
||||
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const pkgJson = require('../package.json')
|
||||
const pkgJsonLock = require('../package-lock.json')
|
||||
const mochaVersion = pkgJsonLock.dependencies.mocha.version
|
||||
const chaiVersion = pkgJsonLock.dependencies.chai.version
|
||||
const pkgName = pkgJson.name
|
||||
|
||||
const rootDir = path.join(__dirname, '..')
|
||||
|
||||
// Let's first create the appropriate html file loading mocha, chai and a bundle of the tests
|
||||
const templatePath = path.join(rootDir, pkgJson.directories.src, 'browser', 'tests-template.html')
|
||||
const dstDir = path.join(rootDir, pkgJson.directories.test, 'browser')
|
||||
const dstFileName = path.join(dstDir, 'index.html')
|
||||
|
||||
const template = fs.readFileSync(templatePath, 'utf-8')
|
||||
const bundleFile = path.join(rootDir, pkgJson.directories.lib, 'index.browser.bundle.mod.js')
|
||||
const testsJs = `
|
||||
<script type="module">
|
||||
import * as _pkg from '${path.relative(templatePath, bundleFile)}'
|
||||
window._pkg = _pkg
|
||||
import './tests.js'
|
||||
mocha.run()
|
||||
</script>`
|
||||
|
||||
fs.writeFileSync(dstFileName,
|
||||
template.replace(/{{TESTS}}/g, testsJs).replace(/{{PKG_NAME}}/g, pkgName).replace(/{{MOCHA_VERSION}}/g, mochaVersion).replace(/{{CHAI_VERSION}}/g, chaiVersion)
|
||||
)
|
||||
|
||||
const input = path.join(rootDir, pkgJson.directories.test, '*.js')
|
||||
console.log(input)
|
||||
|
||||
module.exports = [
|
||||
{
|
||||
input: input,
|
||||
plugins: [
|
||||
multi({ exports: false }),
|
||||
replace({
|
||||
'const _pkg = require(\'../lib/index.node\')': '',
|
||||
'const chai = require(\'chai\')': '',
|
||||
delimiters: ['', ''],
|
||||
'process.browser': true
|
||||
}),
|
||||
resolve({
|
||||
browser: true
|
||||
}),
|
||||
commonjs()
|
||||
],
|
||||
output: {
|
||||
file: path.join(rootDir, pkgJson.directories.test, 'browser', 'tests.js'),
|
||||
format: 'esm'
|
||||
},
|
||||
external: [pkgName]
|
||||
}
|
||||
]
|
|
@ -0,0 +1,66 @@
|
|||
const puppeteer = require('puppeteer')
|
||||
|
||||
const browserTests = async ({ logWarnings = false, serverPort = 38000, keepServerRunning = false, puppeteerOptions = {} }) => {
|
||||
const server = require('./server.js').server
|
||||
await server.init()
|
||||
await server.listen(serverPort)
|
||||
const browser = await puppeteer.launch(puppeteerOptions)
|
||||
const page = await browser.newPage()
|
||||
page.on('console', function (message) {
|
||||
let ignore = message.type() === 'warning' && !logWarnings
|
||||
if (message.type() === 'error' && message.location()) {
|
||||
if (message.location().url.includes('favicon.ico')) {
|
||||
ignore = true
|
||||
}
|
||||
}
|
||||
if (ignore) return
|
||||
|
||||
let text = (message.args().length > 0) ? message.args()[0]._remoteObject.value : message.text()
|
||||
const args = []
|
||||
if (message.args() !== undefined && message.args().length > 1) {
|
||||
for (let i = 1; i < message.args().length; i++) {
|
||||
args.push(message.args()[i]._remoteObject.value)
|
||||
}
|
||||
}
|
||||
|
||||
if (message.type() === 'error' && message.location()) {
|
||||
text = `${message.location().url} : ${text}`
|
||||
}
|
||||
let consoleType = 'log'
|
||||
switch (message.type()) {
|
||||
case 'error':
|
||||
consoleType = 'error'
|
||||
break
|
||||
case 'warning':
|
||||
consoleType = 'warn'
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
console[consoleType](text, ...args)
|
||||
})
|
||||
page.on('error', function (err) { page.emit(new Error(err)) })
|
||||
|
||||
await page.goto('http://localhost:38000/')
|
||||
const watchDog = page.waitForFunction('_mocha.state === \'stopped\'')
|
||||
await watchDog
|
||||
|
||||
if (keepServerRunning === false) {
|
||||
await page.close()
|
||||
await browser.close()
|
||||
await server.close()
|
||||
}
|
||||
}
|
||||
|
||||
const opts = {
|
||||
// puppeteer options
|
||||
puppeteerOptions: {
|
||||
headless: true
|
||||
// slowMo: 100,
|
||||
// timeout: 10000
|
||||
},
|
||||
doNotLogWarnings: true,
|
||||
keepServerRunning: false, // keep server running until manually closed with ctrl-c. In combination with puppeteerOptions.headless (or just connecting any browser to the test page) allows debugging in browser
|
||||
serverPort: 38000
|
||||
}
|
||||
browserTests(opts)
|
|
@ -0,0 +1,141 @@
|
|||
'use strict'
|
||||
|
||||
const fs = require('fs')
|
||||
const http = require('http')
|
||||
const path = require('path')
|
||||
const pkgJson = require('../../../package.json')
|
||||
|
||||
const rollup = require('rollup')
|
||||
const resolve = require('@rollup/plugin-node-resolve').nodeResolve
|
||||
const replace = require('@rollup/plugin-replace')
|
||||
const multi = require('@rollup/plugin-multi-entry')
|
||||
const typescript = require('@rollup/plugin-typescript')
|
||||
const commonjs = require('@rollup/plugin-commonjs')
|
||||
|
||||
const rootDir = path.join(__dirname, '..', '..', '..')
|
||||
|
||||
const regex = /^(?:(?<scope>@.*?)\/)?(?<name>.*)/ // We are going to take only the package name part if there is a scope, e.g. @my-org/package-name
|
||||
const { name } = pkgJson.name.match(regex).groups
|
||||
|
||||
const indexHtml = `<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<title>${name}</title>
|
||||
<script src="/mocha.js"></script>
|
||||
<script src="/chai.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
</body>
|
||||
<div id="mocha"></div>
|
||||
<script>
|
||||
mocha.setup({
|
||||
ui: 'bdd',
|
||||
reporter: 'spec',
|
||||
color: 'true',
|
||||
timeout: 90000
|
||||
})
|
||||
</script>
|
||||
<script type="module">
|
||||
import * as _pkg from './${name}.esm.js'
|
||||
self._pkg = _pkg
|
||||
import './tests.js'
|
||||
window._mocha = mocha.run()
|
||||
</script>
|
||||
</html>`
|
||||
|
||||
async function buildTests () {
|
||||
// create a bundle
|
||||
const inputOptions = {
|
||||
input: [path.join(rootDir, pkgJson.directories.test, '**/*.ts'), path.join(rootDir, pkgJson.directories.src, '**/*.spec.ts')],
|
||||
plugins: [
|
||||
multi({ exports: true }),
|
||||
replace({
|
||||
IS_BROWSER: true,
|
||||
preventAssignment: true
|
||||
}),
|
||||
typescript(),
|
||||
resolve({
|
||||
browser: true,
|
||||
exportConditions: ['browser', 'module', 'import', 'default']
|
||||
}),
|
||||
commonjs()
|
||||
]
|
||||
}
|
||||
const bundle = await rollup.rollup(inputOptions)
|
||||
const { output } = await bundle.generate({ format: 'esm' })
|
||||
await bundle.close()
|
||||
return output[0].code
|
||||
}
|
||||
|
||||
class TestServer {
|
||||
constructor () {
|
||||
this.server = http.createServer()
|
||||
}
|
||||
|
||||
async init () {
|
||||
const tests = await buildTests()
|
||||
this.server.on('request', function (req, res) {
|
||||
if (req.url === `/${name}.esm.js`) {
|
||||
fs.readFile(path.join(rootDir, pkgJson.directories.dist, `bundles/${name}.esm.js`), function (err, data) {
|
||||
if (err) {
|
||||
res.writeHead(404)
|
||||
res.end(JSON.stringify(err))
|
||||
return
|
||||
}
|
||||
res.writeHead(200, { 'Content-Type': 'text/javascript' })
|
||||
res.end(data)
|
||||
})
|
||||
} else if (req.url === '/index.html' || req.url === '/') {
|
||||
res.writeHead(200)
|
||||
res.end(indexHtml)
|
||||
} else if (req.url === '/tests.js') {
|
||||
res.writeHead(200, { 'Content-Type': 'text/javascript' })
|
||||
res.end(tests)
|
||||
} else if (req.url === '/mocha.js') {
|
||||
fs.readFile(path.join(rootDir, 'node_modules/mocha/mocha.js'), function (err, data) {
|
||||
if (err) {
|
||||
res.writeHead(404)
|
||||
res.end(JSON.stringify(err))
|
||||
return
|
||||
}
|
||||
res.writeHead(200, { 'Content-Type': 'text/javascript' })
|
||||
res.end(data)
|
||||
})
|
||||
} else if (req.url === '/chai.js' || req.url === '/chai') {
|
||||
fs.readFile(path.join(rootDir, 'node_modules/chai/chai.js'), function (err, data) {
|
||||
if (err) {
|
||||
res.writeHead(404)
|
||||
res.end(JSON.stringify(err))
|
||||
return
|
||||
}
|
||||
res.writeHead(200, { 'Content-Type': 'text/javascript' })
|
||||
res.end(data)
|
||||
})
|
||||
} else {
|
||||
res.writeHead(404)
|
||||
res.end()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
listen (port = 38080) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.server.listen(port, error => {
|
||||
if (error) return reject(error)
|
||||
console.log(`Testing server listenning at http://localhost:${port}`)
|
||||
return resolve()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
close () {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.server.close(error => (error) ? reject(error) : resolve())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
exports.server = new TestServer()
|
|
@ -0,0 +1,59 @@
|
|||
const EventEmitter = require('events')
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
module.exports = class Builder extends EventEmitter {
|
||||
constructor (semaphoreFile, name = 'builder') {
|
||||
super()
|
||||
this.name = name
|
||||
this.firstBuild = true
|
||||
fs.mkdirSync(path.dirname(semaphoreFile), { recursive: true })
|
||||
|
||||
this.semaphoreFile = semaphoreFile
|
||||
this._ready = false
|
||||
|
||||
this.on('message', (...message) => {
|
||||
if (message !== undefined) {
|
||||
console.log(`\x1b[33mℹ [${this.name}]`, ...message, '\x1b[0m')
|
||||
}
|
||||
})
|
||||
|
||||
this.on('error', (...error) => {
|
||||
if (error !== undefined) {
|
||||
console.error(`\x1b[31m❗ [${this.name}]`, ...error, '\x1b[0m')
|
||||
}
|
||||
})
|
||||
|
||||
this.on('ready', () => {
|
||||
if (this.firstBuild === false) {
|
||||
fs.writeFileSync(this.semaphoreFile, '', 'utf-8')
|
||||
} else {
|
||||
this.firstBuild = false
|
||||
}
|
||||
this._ready = true
|
||||
})
|
||||
|
||||
this.on('busy', () => {
|
||||
this._ready = false
|
||||
})
|
||||
}
|
||||
|
||||
ready () {
|
||||
return new Promise(resolve => {
|
||||
if (this._ready === true) return resolve()
|
||||
this.once('ready', () => {
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
async start () {
|
||||
|
||||
}
|
||||
|
||||
async close () {}
|
||||
|
||||
clean () {
|
||||
fs.rmSync(this.semaphoreFile, { force: true })
|
||||
}
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
const EventEmitter = require('events')
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
const rollup = require('rollup')
|
||||
const loadAndParseConfigFile = require('rollup/dist/loadConfigFile')
|
||||
|
||||
const Builder = require('./Builder.js')
|
||||
|
||||
const rootDir = path.join(__dirname, '../../../../')
|
||||
const pkgJson = require(path.join(rootDir, 'package.json'))
|
||||
|
||||
module.exports = class RollupBuilder extends Builder {
|
||||
constructor ({ name = 'rollup', configPath = path.join(rootDir, 'rollup.config.js'), tempDir = path.join(rootDir, '.mocha-ts'), watch = false }) {
|
||||
super(path.join(tempDir, 'semaphore'), name)
|
||||
this.configPath = configPath
|
||||
this.watch = watch
|
||||
}
|
||||
|
||||
async start () {
|
||||
await super.start()
|
||||
|
||||
const { options } = await loadAndParseConfigFile(this.configPath)
|
||||
// Watch only the Node CJS module, that is the one we are going to use with mocha
|
||||
const rollupOptions = options.filter(bundle => {
|
||||
const file = (bundle.output[0].dir !== undefined)
|
||||
? path.join(bundle.output[0].dir, bundle.output[0].entryFileNames)
|
||||
: bundle.output[0].file
|
||||
return file === path.join(rootDir, pkgJson.main)
|
||||
})[0]
|
||||
|
||||
this.builder = new RollupBundler(rollupOptions, this.watch)
|
||||
|
||||
this.builder.on('event', event => {
|
||||
switch (event.code) {
|
||||
case 'START':
|
||||
this.emit('busy')
|
||||
if (this.firstBuild === true) {
|
||||
this.emit('message', 'building your module...')
|
||||
} else {
|
||||
this.emit('message', 'file changes detected. Rebuilding module files...')
|
||||
}
|
||||
break
|
||||
|
||||
case 'BUNDLE_END':
|
||||
if (event.result) event.result.close()
|
||||
break
|
||||
|
||||
case 'END':
|
||||
if (event.result) event.result.close()
|
||||
this.emit('ready')
|
||||
break
|
||||
|
||||
case 'ERROR':
|
||||
if (event.result) event.result.close()
|
||||
this.emit('error', event.error)
|
||||
fs.writeFileSync(path.join(rootDir, pkgJson.main), '', 'utf8')
|
||||
this.emit('ready')
|
||||
break
|
||||
|
||||
default:
|
||||
this.emit('busy')
|
||||
break
|
||||
}
|
||||
})
|
||||
|
||||
this.builder.start()
|
||||
|
||||
return await this.ready()
|
||||
}
|
||||
|
||||
async close () {
|
||||
await super.close()
|
||||
this.builder.close()
|
||||
}
|
||||
}
|
||||
|
||||
class RollupBundler extends EventEmitter {
|
||||
constructor (rollupOptions, watch = false) {
|
||||
super()
|
||||
this.rollupOptions = rollupOptions
|
||||
this.watch = watch
|
||||
}
|
||||
|
||||
async start () {
|
||||
if (this.watch === true) {
|
||||
this.watcher = rollup.watch(this.rollupOptions)
|
||||
|
||||
this.watcher.on('event', event => {
|
||||
this.emit('event', event)
|
||||
})
|
||||
} else {
|
||||
if (fs.existsSync(path.join(rootDir, pkgJson.main)) === false) {
|
||||
await this._bundle()
|
||||
} else {
|
||||
this.emit('event', { code: 'END', noBuild: true })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async _bundle () {
|
||||
this.emit('event', { code: 'START' })
|
||||
for (const optionsObj of [].concat(this.rollupOptions)) {
|
||||
try {
|
||||
const bundle = await rollup.rollup(optionsObj)
|
||||
try {
|
||||
await Promise.all(optionsObj.output.map(bundle.write))
|
||||
this.emit('event', { code: 'BUNDLE_END' })
|
||||
} catch (error) {
|
||||
this.emit('event', { code: 'ERROR', error })
|
||||
}
|
||||
} catch (error) {
|
||||
this.emit('event', { code: 'ERROR', error })
|
||||
}
|
||||
}
|
||||
this.emit('event', { code: 'END' })
|
||||
}
|
||||
|
||||
close () {
|
||||
if (this.watcher !== undefined) this.watcher.close()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
const path = require('path')
|
||||
const fs = require('fs')
|
||||
|
||||
const ts = require('typescript')
|
||||
const JSON5 = require('json5')
|
||||
|
||||
const Builder = require('./Builder.js')
|
||||
|
||||
const rootDir = path.join(__dirname, '../../../../')
|
||||
const mochaTsRelativeDir = '.mocha-ts'
|
||||
const mochaTsDir = path.join(rootDir, mochaTsRelativeDir)
|
||||
|
||||
const formatHost = {
|
||||
getCanonicalFileName: path => path,
|
||||
getCurrentDirectory: ts.sys.getCurrentDirectory,
|
||||
getNewLine: () => ts.sys.newLine
|
||||
}
|
||||
|
||||
module.exports = class TestsBuilder extends Builder {
|
||||
constructor ({ name = 'tsc', configPath = path.join(rootDir, 'tsconfig.json'), tempDir = mochaTsDir }) {
|
||||
super(path.join(tempDir, 'semaphore'), name)
|
||||
|
||||
if (fs.existsSync(configPath) !== true) throw new Error(`Couldn't find a tsconfig file at ${configPath}`)
|
||||
|
||||
this.tempDir = tempDir
|
||||
|
||||
const readFileAndMangle = (path) => { // We need to change the include or file in the original file to only compile the tests
|
||||
const fileStr = fs.readFileSync(path, 'utf8')
|
||||
const config = JSON5.parse(fileStr)
|
||||
if (config.file) delete config.file
|
||||
config.include = ['build/typings/**/*.ts', 'test/**/*.ts', 'src/**/*.spec.ts', 'node_modules/@types/**/*']
|
||||
return JSON.stringify(config)
|
||||
}
|
||||
const configFile = ts.readJsonConfigFile(configPath, readFileAndMangle)
|
||||
|
||||
const parsedTsConfig = ts.parseJsonSourceFileConfigFileContent(configFile, ts.sys, path.dirname(configPath))
|
||||
|
||||
const createProgram = ts.createSemanticDiagnosticsBuilderProgram
|
||||
|
||||
const reportDiagnostic = (diagnostic) => {
|
||||
const filePath = path.relative(rootDir, diagnostic.file.fileName)
|
||||
const tranpiledJsPath = `${path.join(tempDir, filePath).slice(0, -3)}.js`
|
||||
const errorLine = diagnostic.file.text.slice(0, diagnostic.start).split(/\r\n|\r|\n/).length
|
||||
if (fs.existsSync(tranpiledJsPath)) {
|
||||
fs.writeFileSync(tranpiledJsPath, '', 'utf8')
|
||||
}
|
||||
this.emit('error', `[Error ${diagnostic.code}]`, `${filePath}:${errorLine}`, ':', ts.flattenDiagnosticMessageText(diagnostic.messageText, formatHost.getNewLine()))
|
||||
}
|
||||
|
||||
const reportWatchStatusChanged = (diagnostic, newLine, options, errorCount) => {
|
||||
if (errorCount !== undefined) {
|
||||
this.emit('ready')
|
||||
} else {
|
||||
this.emit('busy')
|
||||
if (diagnostic.code === 6031) {
|
||||
this.emit('message', 'transpiling your tests...')
|
||||
} else if (diagnostic.code === 6032) {
|
||||
this.emit('message', 'file changes detected. Transpiling your tests...')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Note that there is another overload for `createWatchCompilerHost` that takes
|
||||
// a set of root files.
|
||||
this.host = ts.createWatchCompilerHost(
|
||||
parsedTsConfig.fileNames,
|
||||
{
|
||||
...parsedTsConfig.options,
|
||||
rootDir,
|
||||
outDir: this.tempDir,
|
||||
module: 'commonjs',
|
||||
noEmit: false,
|
||||
noResolve: true,
|
||||
sourceMap: true
|
||||
},
|
||||
ts.sys,
|
||||
createProgram,
|
||||
reportDiagnostic,
|
||||
reportWatchStatusChanged
|
||||
)
|
||||
}
|
||||
|
||||
async start () {
|
||||
await super.start()
|
||||
// `createWatchProgram` creates an initial program, watches files, and updates
|
||||
// the program over time.
|
||||
this.watcher = ts.createWatchProgram(this.host)
|
||||
return await this.ready()
|
||||
}
|
||||
|
||||
async close () {
|
||||
await super.close()
|
||||
this.watcher.close()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
'use strict'
|
||||
|
||||
const path = require('path')
|
||||
|
||||
const chai = require('chai')
|
||||
const rimraf = require('rimraf')
|
||||
|
||||
const RollupBuilder = require('./builders/RollupBuilder.js')
|
||||
const TestsBuilder = require('./builders/TestsBuilder.js')
|
||||
|
||||
const rootDir = path.join(__dirname, '../../../')
|
||||
|
||||
global.chai = chai
|
||||
|
||||
const watch = process.argv.includes('--watch') || process.argv.includes('-w')
|
||||
|
||||
const tempDir = path.join(rootDir, '.mocha-ts')
|
||||
|
||||
const rollupBuilder = new RollupBuilder({ name: 'rollup', configPath: path.join(rootDir, 'build/rollup.config.js'), tempDir, watch })
|
||||
const testBuilder = new TestsBuilder({ name: 'tsc', tempDir })
|
||||
|
||||
rollupBuilder.start() // This should be in exports.mochaGlobalSetup but mocha fails when not in watch mode (DIRT...)
|
||||
testBuilder.start() // This should be in exports.mochaGlobalSetup but mocha fails when not in watch mode (DIRT...)
|
||||
|
||||
exports.mochaHooks = {
|
||||
beforeAll: [
|
||||
async function () {
|
||||
// Just in case our module had been modified. Reload it when the tests are repeated (for mocha watch mode).
|
||||
delete require.cache[require.resolve(rootDir)]
|
||||
global._pkg = require(rootDir)
|
||||
},
|
||||
async function () {
|
||||
this.timeout('120000')
|
||||
await Promise.all([rollupBuilder.ready(), testBuilder.ready()])
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
// exports.mochaGlobalSetup = async function () {
|
||||
// await rollupBuilder.start()
|
||||
// await testBuilder.start()
|
||||
// }
|
||||
|
||||
exports.mochaGlobalTeardown = async function () {
|
||||
await testBuilder.close()
|
||||
await rollupBuilder.close()
|
||||
|
||||
// I use the sync version of rimraf precisely because it blocks the
|
||||
// main thread and thus the mocha watcher, which otherwise would complain
|
||||
// about files being deleted
|
||||
rimraf.sync(tempDir, { disableGlob: true })
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
import * as _pkgModule from '../..'
|
||||
|
||||
export as namespace _pkg
|
||||
|
||||
export = _pkgModule
|
|
@ -0,0 +1 @@
|
|||
declare const IS_BROWSER: boolean
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,7 @@
|
|||
export { abs, bitLength, eGcd, gcd, lcm, max, min, modInv, modPow, toZn } from 'bigint-mod-arith';
|
||||
export { isProbablyPrime } from './ts/isProbablyPrime';
|
||||
export { prime, primeSync } from './ts/prime';
|
||||
export { randBetween } from './ts/randBetween';
|
||||
export { randBits, randBitsSync } from './ts/randBits';
|
||||
export { randBytes, randBytesSync } from './ts/randBytes';
|
||||
//# sourceMappingURL=index.d.ts.map
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAEjG,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AACtD,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA"}
|
|
@ -0,0 +1,3 @@
|
|||
/// <reference types="node" />
|
||||
export declare function fromBuffer(buf: Uint8Array | Buffer): bigint;
|
||||
//# sourceMappingURL=fromBuffer.d.ts.map
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"fromBuffer.d.ts","sourceRoot":"","sources":["../../../../src/ts/fromBuffer.ts"],"names":[],"mappings":";AAAA,wBAAgB,UAAU,CAAE,GAAG,EAAE,UAAU,GAAC,MAAM,GAAG,MAAM,CAO1D"}
|
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
* 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)
|
||||
*
|
||||
* @param w - A positive integer to be tested for primality
|
||||
* @param iterations - The number of iterations for the primality test. The value shall be consistent with Table C.1, C.2 or C.3
|
||||
* @param disableWorkers - Disable the use of workers for the primality test
|
||||
*
|
||||
* @throws {RangeError}
|
||||
* w MUST be >= 0
|
||||
*
|
||||
* @returns A promise that resolves to a boolean that is either true (a probably prime number) or false (definitely composite)
|
||||
*/
|
||||
export declare function isProbablyPrime(w: number | bigint, iterations?: number, disableWorkers?: boolean): Promise<boolean>;
|
||||
export declare function _isProbablyPrime(w: bigint, iterations?: number): boolean;
|
||||
export declare function _isProbablyPrimeWorkerUrl(): string;
|
||||
//# sourceMappingURL=isProbablyPrime.d.ts.map
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"isProbablyPrime.d.ts","sourceRoot":"","sources":["../../../../src/ts/isProbablyPrime.ts"],"names":[],"mappings":"AAOA;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAE,CAAC,EAAE,MAAM,GAAC,MAAM,EAAE,UAAU,GAAE,MAAW,EAAE,cAAc,GAAE,OAAe,GAAG,OAAO,CAAC,OAAO,CAAC,CAqD7H;AAED,wBAAgB,gBAAgB,CAAE,CAAC,EAAE,MAAM,EAAE,UAAU,GAAE,MAAW,GAAG,OAAO,CA0T7E;AAED,wBAAgB,yBAAyB,IAAK,MAAM,CAkBnD"}
|
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* 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).
|
||||
* The node version can also use worker_threads if they are available (enabled by default with Node 11 and
|
||||
* and can be enabled at runtime executing node --experimental-worker with node >=10.5.0).
|
||||
*
|
||||
* @param bitLength - The required bit length for the generated prime
|
||||
* @param iterations - The number of iterations for the Miller-Rabin Probabilistic Primality Test
|
||||
*
|
||||
* @throws {RangeError}
|
||||
* bitLength MUST be > 0
|
||||
*
|
||||
* @returns A promise that resolves to a bigint probable prime of bitLength bits.
|
||||
*/
|
||||
export declare function prime(bitLength: number, iterations?: number): Promise<bigint>;
|
||||
/**
|
||||
* A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator.
|
||||
* The sync version is NOT RECOMMENDED since it won't use workers and thus it'll be slower and may freeze thw window in browser's javascript. Please consider using prime() instead.
|
||||
*
|
||||
* @param bitLength - The required bit length for the generated prime
|
||||
* @param iterations - The number of iterations for the Miller-Rabin Probabilistic Primality Test
|
||||
*
|
||||
* @throws {RangeError}
|
||||
* bitLength MUST be > 0
|
||||
*
|
||||
* @returns A bigint probable prime of bitLength bits.
|
||||
*/
|
||||
export declare function primeSync(bitLength: number, iterations?: number): bigint;
|
||||
//# sourceMappingURL=prime.d.ts.map
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"prime.d.ts","sourceRoot":"","sources":["../../../../src/ts/prime.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,KAAK,CAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAE,MAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAiElF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAE,MAAW,GAAG,MAAM,CAO7E"}
|
|
@ -0,0 +1,12 @@
|
|||
/**
|
||||
* Returns a cryptographically secure random integer between [min,max]. Both numbers must be >=0
|
||||
* @param max Returned value will be <= max
|
||||
* @param min Returned value will be >= min
|
||||
*
|
||||
* @throws {RangeError}
|
||||
* Arguments MUST be: max > 0 && min >=0 && max > min
|
||||
*
|
||||
* @returns A cryptographically secure random bigint between [min,max]
|
||||
*/
|
||||
export declare function randBetween(max: bigint, min?: bigint): bigint;
|
||||
//# sourceMappingURL=randBetween.d.ts.map
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"randBetween.d.ts","sourceRoot":"","sources":["../../../../src/ts/randBetween.ts"],"names":[],"mappings":"AAIA;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAE,GAAG,EAAE,MAAM,EAAE,GAAG,GAAE,MAAW,GAAG,MAAM,CAUlE"}
|
|
@ -0,0 +1,25 @@
|
|||
/// <reference types="node" />
|
||||
/**
|
||||
* Secure random bits for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()
|
||||
*
|
||||
* @param bitLength - The desired number of random bits
|
||||
* @param forceLength - If we want to force the output to have a specific bit length. It basically forces the msb to be 1
|
||||
*
|
||||
* @throws {RangeError}
|
||||
* bitLength MUST be > 0
|
||||
*
|
||||
* @returns A Promise that resolves to a UInt8Array/Buffer (Browser/Node.js) filled with cryptographically secure random bits
|
||||
*/
|
||||
export declare function randBits(bitLength: number, forceLength?: boolean): Promise<Uint8Array | Buffer>;
|
||||
/**
|
||||
* Secure random bits for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()
|
||||
* @param bitLength - The desired number of random bits
|
||||
* @param forceLength - If we want to force the output to have a specific bit length. It basically forces the msb to be 1
|
||||
*
|
||||
* @throws {RangeError}
|
||||
* bitLength MUST be > 0
|
||||
*
|
||||
* @returns A Uint8Array/Buffer (Browser/Node.js) filled with cryptographically secure random bits
|
||||
*/
|
||||
export declare function randBitsSync(bitLength: number, forceLength?: boolean): Uint8Array | Buffer;
|
||||
//# sourceMappingURL=randBits.d.ts.map
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"randBits.d.ts","sourceRoot":"","sources":["../../../../src/ts/randBits.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;GAUG;AACH,wBAAgB,QAAQ,CAAE,SAAS,EAAE,MAAM,EAAE,WAAW,GAAE,OAAe,GAAG,OAAO,CAAC,UAAU,GAAC,MAAM,CAAC,CAmBrG;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAE,SAAS,EAAE,MAAM,EAAE,WAAW,GAAE,OAAe,GAAG,UAAU,GAAC,MAAM,CAehG"}
|
|
@ -0,0 +1,26 @@
|
|||
/// <reference types="node" />
|
||||
/**
|
||||
* Secure random bytes for both node and browsers. Node version uses crypto.randomBytes() and browser one self.crypto.getRandomValues()
|
||||
*
|
||||
* @param byteLength - The desired number of random bytes
|
||||
* @param forceLength - If we want to force the output to have a bit length of 8*byteLength. It basically forces the msb to be 1
|
||||
*
|
||||
* @throws {RangeError}
|
||||
* byteLength MUST be > 0
|
||||
*
|
||||
* @returns A promise that resolves to a UInt8Array/Buffer (Browser/Node.js) filled with cryptographically secure random bytes
|
||||
*/
|
||||
export declare function randBytes(byteLength: number, forceLength?: boolean): Promise<Uint8Array | Buffer>;
|
||||
/**
|
||||
* Secure random bytes for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()
|
||||
*
|
||||
* @param byteLength - The desired number of random bytes
|
||||
* @param forceLength - If we want to force the output to have a bit length of 8*byteLength. It basically forces the msb to be 1
|
||||
*
|
||||
* @throws {RangeError}
|
||||
* byteLength MUST be > 0
|
||||
*
|
||||
* @returns A UInt8Array/Buffer (Browser/Node.js) filled with cryptographically secure random bytes
|
||||
*/
|
||||
export declare function randBytesSync(byteLength: number, forceLength?: boolean): Uint8Array | Buffer;
|
||||
//# sourceMappingURL=randBytes.d.ts.map
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"randBytes.d.ts","sourceRoot":"","sources":["../../../../src/ts/randBytes.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAE,UAAU,EAAE,MAAM,EAAE,WAAW,UAAQ,GAAG,OAAO,CAAC,UAAU,GAAC,MAAM,CAAC,CAqB9F;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAE,UAAU,EAAE,MAAM,EAAE,WAAW,GAAE,OAAe,GAAG,UAAU,GAAC,MAAM,CAkBlG"}
|
|
@ -0,0 +1,14 @@
|
|||
export declare function _workerUrl(workerCode: string): string;
|
||||
declare let _useWorkers: boolean;
|
||||
export { _useWorkers };
|
||||
export interface WorkerToMainMsg {
|
||||
isPrime: boolean;
|
||||
value: bigint;
|
||||
id: number;
|
||||
}
|
||||
export interface MainToWorkerMsg {
|
||||
rnd: bigint;
|
||||
iterations: number;
|
||||
id: number;
|
||||
}
|
||||
//# sourceMappingURL=workerUtils.d.ts.map
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"workerUtils.d.ts","sourceRoot":"","sources":["../../../../src/ts/workerUtils.ts"],"names":[],"mappings":"AAAA,wBAAgB,UAAU,CAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAItD;AAED,QAAA,IAAI,WAAW,SAAQ,CAAA;AAiBvB,OAAO,EAAE,WAAW,EAAE,CAAA;AAEtB,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,EAAE,EAAE,MAAM,CAAA;CACX;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAA;IACX,UAAU,EAAE,MAAM,CAAA;IAClB,EAAE,EAAE,MAAM,CAAA;CACX"}
|
|
@ -0,0 +1,450 @@
|
|||
bigint-crypto-utils - v3.0.9
|
||||
|
||||
# bigint-crypto-utils - v3.0.9
|
||||
|
||||
## Table of contents
|
||||
|
||||
### Functions
|
||||
|
||||
- [abs](API.md#abs)
|
||||
- [bitLength](API.md#bitlength)
|
||||
- [eGcd](API.md#egcd)
|
||||
- [gcd](API.md#gcd)
|
||||
- [isProbablyPrime](API.md#isprobablyprime)
|
||||
- [lcm](API.md#lcm)
|
||||
- [max](API.md#max)
|
||||
- [min](API.md#min)
|
||||
- [modInv](API.md#modinv)
|
||||
- [modPow](API.md#modpow)
|
||||
- [prime](API.md#prime)
|
||||
- [primeSync](API.md#primesync)
|
||||
- [randBetween](API.md#randbetween)
|
||||
- [randBits](API.md#randbits)
|
||||
- [randBitsSync](API.md#randbitssync)
|
||||
- [randBytes](API.md#randbytes)
|
||||
- [randBytesSync](API.md#randbytessync)
|
||||
- [toZn](API.md#tozn)
|
||||
|
||||
## Functions
|
||||
|
||||
### abs
|
||||
|
||||
▸ **abs**(`a`: *number* \| *bigint*): *number* \| *bigint*
|
||||
|
||||
Absolute value. abs(a)==a if a>=0. abs(a)==-a if a<0
|
||||
|
||||
#### Parameters:
|
||||
|
||||
Name | Type |
|
||||
:------ | :------ |
|
||||
`a` | *number* \| *bigint* |
|
||||
|
||||
**Returns:** *number* \| *bigint*
|
||||
|
||||
The absolute value of a
|
||||
|
||||
Defined in: node_modules/bigint-mod-arith/dist/esm/types/ts/abs.d.ts:8
|
||||
|
||||
___
|
||||
|
||||
### bitLength
|
||||
|
||||
▸ **bitLength**(`a`: *number* \| *bigint*): *number*
|
||||
|
||||
Returns the bitlength of a number
|
||||
|
||||
#### Parameters:
|
||||
|
||||
Name | Type |
|
||||
:------ | :------ |
|
||||
`a` | *number* \| *bigint* |
|
||||
|
||||
**Returns:** *number*
|
||||
|
||||
The bit length
|
||||
|
||||
Defined in: node_modules/bigint-mod-arith/dist/esm/types/ts/bitLength.d.ts:7
|
||||
|
||||
___
|
||||
|
||||
### eGcd
|
||||
|
||||
▸ **eGcd**(`a`: *number* \| *bigint*, `b`: *number* \| *bigint*): Egcd
|
||||
|
||||
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).
|
||||
|
||||
**`throws`** {RangeError}
|
||||
This excepction is thrown if a or b are less than 0
|
||||
|
||||
#### Parameters:
|
||||
|
||||
Name | Type |
|
||||
:------ | :------ |
|
||||
`a` | *number* \| *bigint* |
|
||||
`b` | *number* \| *bigint* |
|
||||
|
||||
**Returns:** Egcd
|
||||
|
||||
A triple (g, x, y), such that ax + by = g = gcd(a, b).
|
||||
|
||||
Defined in: node_modules/bigint-mod-arith/dist/esm/types/ts/egcd.d.ts:18
|
||||
|
||||
___
|
||||
|
||||
### gcd
|
||||
|
||||
▸ **gcd**(`a`: *number* \| *bigint*, `b`: *number* \| *bigint*): *bigint*
|
||||
|
||||
Greatest-common divisor of two integers based on the iterative binary algorithm.
|
||||
|
||||
#### Parameters:
|
||||
|
||||
Name | Type |
|
||||
:------ | :------ |
|
||||
`a` | *number* \| *bigint* |
|
||||
`b` | *number* \| *bigint* |
|
||||
|
||||
**Returns:** *bigint*
|
||||
|
||||
The greatest common divisor of a and b
|
||||
|
||||
Defined in: node_modules/bigint-mod-arith/dist/esm/types/ts/gcd.d.ts:9
|
||||
|
||||
___
|
||||
|
||||
### isProbablyPrime
|
||||
|
||||
▸ **isProbablyPrime**(`w`: *number* \| *bigint*, `iterations?`: *number*, `disableWorkers?`: *boolean*): *Promise*<boolean\>
|
||||
|
||||
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)
|
||||
|
||||
**`throws`** {RangeError}
|
||||
w MUST be >= 0
|
||||
|
||||
#### Parameters:
|
||||
|
||||
Name | Type | Default value | Description |
|
||||
:------ | :------ | :------ | :------ |
|
||||
`w` | *number* \| *bigint* | - | A positive integer to be tested for primality |
|
||||
`iterations` | *number* | 16 | The number of iterations for the primality test. The value shall be consistent with Table C.1, C.2 or C.3 |
|
||||
`disableWorkers` | *boolean* | false | Disable the use of workers for the primality test |
|
||||
|
||||
**Returns:** *Promise*<boolean\>
|
||||
|
||||
A promise that resolves to a boolean that is either true (a probably prime number) or false (definitely composite)
|
||||
|
||||
Defined in: src/ts/isProbablyPrime.ts:21
|
||||
|
||||
___
|
||||
|
||||
### lcm
|
||||
|
||||
▸ **lcm**(`a`: *number* \| *bigint*, `b`: *number* \| *bigint*): *bigint*
|
||||
|
||||
The least common multiple computed as abs(a*b)/gcd(a,b)
|
||||
|
||||
#### Parameters:
|
||||
|
||||
Name | Type |
|
||||
:------ | :------ |
|
||||
`a` | *number* \| *bigint* |
|
||||
`b` | *number* \| *bigint* |
|
||||
|
||||
**Returns:** *bigint*
|
||||
|
||||
The least common multiple of a and b
|
||||
|
||||
Defined in: node_modules/bigint-mod-arith/dist/esm/types/ts/lcm.d.ts:8
|
||||
|
||||
___
|
||||
|
||||
### max
|
||||
|
||||
▸ **max**(`a`: *number* \| *bigint*, `b`: *number* \| *bigint*): *number* \| *bigint*
|
||||
|
||||
Maximum. max(a,b)==a if a>=b. max(a,b)==b if a<=b
|
||||
|
||||
#### Parameters:
|
||||
|
||||
Name | Type |
|
||||
:------ | :------ |
|
||||
`a` | *number* \| *bigint* |
|
||||
`b` | *number* \| *bigint* |
|
||||
|
||||
**Returns:** *number* \| *bigint*
|
||||
|
||||
Maximum of numbers a and b
|
||||
|
||||
Defined in: node_modules/bigint-mod-arith/dist/esm/types/ts/max.d.ts:9
|
||||
|
||||
___
|
||||
|
||||
### min
|
||||
|
||||
▸ **min**(`a`: *number* \| *bigint*, `b`: *number* \| *bigint*): *number* \| *bigint*
|
||||
|
||||
Minimum. min(a,b)==b if a>=b. min(a,b)==a if a<=b
|
||||
|
||||
#### Parameters:
|
||||
|
||||
Name | Type |
|
||||
:------ | :------ |
|
||||
`a` | *number* \| *bigint* |
|
||||
`b` | *number* \| *bigint* |
|
||||
|
||||
**Returns:** *number* \| *bigint*
|
||||
|
||||
Minimum of numbers a and b
|
||||
|
||||
Defined in: node_modules/bigint-mod-arith/dist/esm/types/ts/min.d.ts:9
|
||||
|
||||
___
|
||||
|
||||
### modInv
|
||||
|
||||
▸ **modInv**(`a`: *number* \| *bigint*, `n`: *number* \| *bigint*): *bigint*
|
||||
|
||||
Modular inverse.
|
||||
|
||||
**`throws`** {RangeError}
|
||||
Excpeption thorwn when a does not have inverse modulo n
|
||||
|
||||
#### Parameters:
|
||||
|
||||
Name | Type | Description |
|
||||
:------ | :------ | :------ |
|
||||
`a` | *number* \| *bigint* | The number to find an inverse for |
|
||||
`n` | *number* \| *bigint* | The modulo |
|
||||
|
||||
**Returns:** *bigint*
|
||||
|
||||
The inverse modulo n
|
||||
|
||||
Defined in: node_modules/bigint-mod-arith/dist/esm/types/ts/modInv.d.ts:12
|
||||
|
||||
___
|
||||
|
||||
### modPow
|
||||
|
||||
▸ **modPow**(`b`: *number* \| *bigint*, `e`: *number* \| *bigint*, `n`: *number* \| *bigint*): *bigint*
|
||||
|
||||
Modular exponentiation b**e mod n. Currently using the right-to-left binary method
|
||||
|
||||
**`throws`** {RangeError}
|
||||
Excpeption thrown when n is not > 0
|
||||
|
||||
#### Parameters:
|
||||
|
||||
Name | Type | Description |
|
||||
:------ | :------ | :------ |
|
||||
`b` | *number* \| *bigint* | base |
|
||||
`e` | *number* \| *bigint* | exponent |
|
||||
`n` | *number* \| *bigint* | modulo |
|
||||
|
||||
**Returns:** *bigint*
|
||||
|
||||
b**e mod n
|
||||
|
||||
Defined in: node_modules/bigint-mod-arith/dist/esm/types/ts/modPow.d.ts:13
|
||||
|
||||
___
|
||||
|
||||
### prime
|
||||
|
||||
▸ **prime**(`bitLength`: *number*, `iterations?`: *number*): *Promise*<bigint\>
|
||||
|
||||
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).
|
||||
The node version can also use worker_threads if they are available (enabled by default with Node 11 and
|
||||
and can be enabled at runtime executing node --experimental-worker with node >=10.5.0).
|
||||
|
||||
**`throws`** {RangeError}
|
||||
bitLength MUST be > 0
|
||||
|
||||
#### Parameters:
|
||||
|
||||
Name | Type | Default value | Description |
|
||||
:------ | :------ | :------ | :------ |
|
||||
`bitLength` | *number* | - | The required bit length for the generated prime |
|
||||
`iterations` | *number* | 16 | The number of iterations for the Miller-Rabin Probabilistic Primality Test |
|
||||
|
||||
**Returns:** *Promise*<bigint\>
|
||||
|
||||
A promise that resolves to a bigint probable prime of bitLength bits.
|
||||
|
||||
Defined in: src/ts/prime.ts:21
|
||||
|
||||
___
|
||||
|
||||
### primeSync
|
||||
|
||||
▸ **primeSync**(`bitLength`: *number*, `iterations?`: *number*): *bigint*
|
||||
|
||||
A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator.
|
||||
The sync version is NOT RECOMMENDED since it won't use workers and thus it'll be slower and may freeze thw window in browser's javascript. Please consider using prime() instead.
|
||||
|
||||
**`throws`** {RangeError}
|
||||
bitLength MUST be > 0
|
||||
|
||||
#### Parameters:
|
||||
|
||||
Name | Type | Default value | Description |
|
||||
:------ | :------ | :------ | :------ |
|
||||
`bitLength` | *number* | - | The required bit length for the generated prime |
|
||||
`iterations` | *number* | 16 | The number of iterations for the Miller-Rabin Probabilistic Primality Test |
|
||||
|
||||
**Returns:** *bigint*
|
||||
|
||||
A bigint probable prime of bitLength bits.
|
||||
|
||||
Defined in: src/ts/prime.ts:100
|
||||
|
||||
___
|
||||
|
||||
### randBetween
|
||||
|
||||
▸ **randBetween**(`max`: *bigint*, `min?`: *bigint*): *bigint*
|
||||
|
||||
Returns a cryptographically secure random integer between [min,max]. Both numbers must be >=0
|
||||
|
||||
**`throws`** {RangeError}
|
||||
Arguments MUST be: max > 0 && min >=0 && max > min
|
||||
|
||||
#### Parameters:
|
||||
|
||||
Name | Type | Description |
|
||||
:------ | :------ | :------ |
|
||||
`max` | *bigint* | Returned value will be <= max |
|
||||
`min` | *bigint* | Returned value will be >= min |
|
||||
|
||||
**Returns:** *bigint*
|
||||
|
||||
A cryptographically secure random bigint between [min,max]
|
||||
|
||||
Defined in: src/ts/randBetween.ts:15
|
||||
|
||||
___
|
||||
|
||||
### randBits
|
||||
|
||||
▸ **randBits**(`bitLength`: *number*, `forceLength?`: *boolean*): *Promise*<Uint8Array \| Buffer\>
|
||||
|
||||
Secure random bits for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()
|
||||
|
||||
**`throws`** {RangeError}
|
||||
bitLength MUST be > 0
|
||||
|
||||
#### Parameters:
|
||||
|
||||
Name | Type | Default value | Description |
|
||||
:------ | :------ | :------ | :------ |
|
||||
`bitLength` | *number* | - | The desired number of random bits |
|
||||
`forceLength` | *boolean* | false | If we want to force the output to have a specific bit length. It basically forces the msb to be 1 |
|
||||
|
||||
**Returns:** *Promise*<Uint8Array \| Buffer\>
|
||||
|
||||
A Promise that resolves to a UInt8Array/Buffer (Browser/Node.js) filled with cryptographically secure random bits
|
||||
|
||||
Defined in: src/ts/randBits.ts:14
|
||||
|
||||
___
|
||||
|
||||
### randBitsSync
|
||||
|
||||
▸ **randBitsSync**(`bitLength`: *number*, `forceLength?`: *boolean*): Uint8Array \| Buffer
|
||||
|
||||
Secure random bits for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()
|
||||
|
||||
**`throws`** {RangeError}
|
||||
bitLength MUST be > 0
|
||||
|
||||
#### Parameters:
|
||||
|
||||
Name | Type | Default value | Description |
|
||||
:------ | :------ | :------ | :------ |
|
||||
`bitLength` | *number* | - | The desired number of random bits |
|
||||
`forceLength` | *boolean* | false | If we want to force the output to have a specific bit length. It basically forces the msb to be 1 |
|
||||
|
||||
**Returns:** Uint8Array \| Buffer
|
||||
|
||||
A Uint8Array/Buffer (Browser/Node.js) filled with cryptographically secure random bits
|
||||
|
||||
Defined in: src/ts/randBits.ts:45
|
||||
|
||||
___
|
||||
|
||||
### randBytes
|
||||
|
||||
▸ **randBytes**(`byteLength`: *number*, `forceLength?`: *boolean*): *Promise*<Uint8Array \| Buffer\>
|
||||
|
||||
Secure random bytes for both node and browsers. Node version uses crypto.randomBytes() and browser one self.crypto.getRandomValues()
|
||||
|
||||
**`throws`** {RangeError}
|
||||
byteLength MUST be > 0
|
||||
|
||||
#### Parameters:
|
||||
|
||||
Name | Type | Default value | Description |
|
||||
:------ | :------ | :------ | :------ |
|
||||
`byteLength` | *number* | - | The desired number of random bytes |
|
||||
`forceLength` | *boolean* | false | If we want to force the output to have a bit length of 8*byteLength. It basically forces the msb to be 1 |
|
||||
|
||||
**Returns:** *Promise*<Uint8Array \| Buffer\>
|
||||
|
||||
A promise that resolves to a UInt8Array/Buffer (Browser/Node.js) filled with cryptographically secure random bytes
|
||||
|
||||
Defined in: src/ts/randBytes.ts:12
|
||||
|
||||
___
|
||||
|
||||
### randBytesSync
|
||||
|
||||
▸ **randBytesSync**(`byteLength`: *number*, `forceLength?`: *boolean*): Uint8Array \| Buffer
|
||||
|
||||
Secure random bytes for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()
|
||||
|
||||
**`throws`** {RangeError}
|
||||
byteLength MUST be > 0
|
||||
|
||||
#### Parameters:
|
||||
|
||||
Name | Type | Default value | Description |
|
||||
:------ | :------ | :------ | :------ |
|
||||
`byteLength` | *number* | - | The desired number of random bytes |
|
||||
`forceLength` | *boolean* | false | If we want to force the output to have a bit length of 8*byteLength. It basically forces the msb to be 1 |
|
||||
|
||||
**Returns:** Uint8Array \| Buffer
|
||||
|
||||
A UInt8Array/Buffer (Browser/Node.js) filled with cryptographically secure random bytes
|
||||
|
||||
Defined in: src/ts/randBytes.ts:46
|
||||
|
||||
___
|
||||
|
||||
### toZn
|
||||
|
||||
▸ **toZn**(`a`: *number* \| *bigint*, `n`: *number* \| *bigint*): *bigint*
|
||||
|
||||
Finds the smallest positive element that is congruent to a in modulo n
|
||||
|
||||
**`remarks`**
|
||||
a and b must be the same type, either number or bigint
|
||||
|
||||
**`throws`** {RangeError}
|
||||
Excpeption thrown when n is not > 0
|
||||
|
||||
#### Parameters:
|
||||
|
||||
Name | Type | Description |
|
||||
:------ | :------ | :------ |
|
||||
`a` | *number* \| *bigint* | An integer |
|
||||
`n` | *number* \| *bigint* | The modulo |
|
||||
|
||||
**Returns:** *bigint*
|
||||
|
||||
A bigint with the smallest positive representation of a modulo n
|
||||
|
||||
Defined in: node_modules/bigint-mod-arith/dist/esm/types/ts/toZn.d.ts:15
|
|
@ -10,7 +10,7 @@
|
|||
<div id="status">Still computing in background...</div>
|
||||
<p>Look for the results in the JS console (Developer Tools)</p>
|
||||
<script type="module">
|
||||
import * as bigintCryptoUtils from '../lib/index.browser.bundle.mod.js'
|
||||
import * as bigintCryptoUtils from '../dist/bundles/bigint-crypto-utils.esm.js'
|
||||
/* A BigInt with value 666 can be declared calling the bigint constructor as
|
||||
BigInt('666') or with the shorter 666n.
|
||||
Notice that you can also pass a number to the constructor, e.g. BigInt(666).
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<head>
|
||||
<title>bigint-crypto-utils</title>
|
||||
<meta charset="UTF-8" />
|
||||
<script src="../lib/index.browser.bundle.iife.js"></script>
|
||||
<script src="../dist/bundles/bigint-crypto-utils.iife.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const bigintCryptoUtils = require('../lib/index.node')
|
||||
const bigintCryptoUtils = require('../')
|
||||
// const bigintCryptoUtils = require('bigint-crypto-utils')
|
||||
|
||||
/* A BigInt with value 666 can be declared calling the bigint constructor as
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,837 +0,0 @@
|
|||
/**
|
||||
* Absolute value. abs(a)==a if a>=0. abs(a)==-a if a<0
|
||||
*
|
||||
* @param {number|bigint} a
|
||||
*
|
||||
* @returns {bigint} the absolute value of a
|
||||
*/
|
||||
function abs (a) {
|
||||
a = BigInt(a)
|
||||
return (a >= 0n) ? a : -a
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bitlength of a number
|
||||
*
|
||||
* @param {number|bigint} a
|
||||
* @returns {number} - the bit length
|
||||
*/
|
||||
function bitLength (a) {
|
||||
a = BigInt(a)
|
||||
if (a === 1n) { return 1 }
|
||||
let bits = 1
|
||||
do {
|
||||
bits++
|
||||
} while ((a >>= 1n) > 1n)
|
||||
return bits
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} egcdReturn A triple (g, x, y), such that ax + by = g = gcd(a, b).
|
||||
* @property {bigint} g
|
||||
* @property {bigint} x
|
||||
* @property {bigint} y
|
||||
*/
|
||||
/**
|
||||
* 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).
|
||||
*
|
||||
* @param {number|bigint} a
|
||||
* @param {number|bigint} b
|
||||
*
|
||||
* @throws {RangeError} a and b MUST be > 0
|
||||
*
|
||||
* @returns {egcdReturn} A triple (g, x, y), such that ax + by = g = gcd(a, b).
|
||||
*/
|
||||
function eGcd (a, b) {
|
||||
a = BigInt(a)
|
||||
b = BigInt(b)
|
||||
if (a <= 0n | b <= 0n) throw new RangeError('a and b MUST be > 0') // a and b MUST be positive
|
||||
|
||||
let x = 0n
|
||||
let y = 1n
|
||||
let u = 1n
|
||||
let v = 0n
|
||||
|
||||
while (a !== 0n) {
|
||||
const q = b / a
|
||||
const r = b % a
|
||||
const m = x - (u * q)
|
||||
const n = y - (v * q)
|
||||
b = a
|
||||
a = r
|
||||
x = u
|
||||
y = v
|
||||
u = m
|
||||
v = n
|
||||
}
|
||||
return {
|
||||
g: b,
|
||||
x: x,
|
||||
y: y
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Greatest-common divisor of two integers based on the iterative binary algorithm.
|
||||
*
|
||||
* @param {number|bigint} a
|
||||
* @param {number|bigint} b
|
||||
*
|
||||
* @returns {bigint} The greatest common divisor of a and b
|
||||
*/
|
||||
function gcd (a, b) {
|
||||
a = abs(a)
|
||||
b = abs(b)
|
||||
if (a === 0n) { return b } else if (b === 0n) { return a }
|
||||
|
||||
let shift = 0n
|
||||
while (!((a | b) & 1n)) {
|
||||
a >>= 1n
|
||||
b >>= 1n
|
||||
shift++
|
||||
}
|
||||
while (!(a & 1n)) a >>= 1n
|
||||
do {
|
||||
while (!(b & 1n)) b >>= 1n
|
||||
if (a > b) {
|
||||
const x = a
|
||||
a = b
|
||||
b = x
|
||||
}
|
||||
b -= a
|
||||
} while (b)
|
||||
|
||||
// rescale
|
||||
return a << shift
|
||||
}
|
||||
|
||||
/**
|
||||
* The least common multiple computed as abs(a*b)/gcd(a,b)
|
||||
* @param {number|bigint} a
|
||||
* @param {number|bigint} b
|
||||
*
|
||||
* @returns {bigint} The least common multiple of a and b
|
||||
*/
|
||||
function lcm (a, b) {
|
||||
a = BigInt(a)
|
||||
b = BigInt(b)
|
||||
if (a === 0n && b === 0n) return BigInt(0)
|
||||
return abs(a * b) / gcd(a, b)
|
||||
}
|
||||
|
||||
/**
|
||||
* Maximum. max(a,b)==a if a>=b. max(a,b)==b if a<=b
|
||||
*
|
||||
* @param {number|bigint} a
|
||||
* @param {number|bigint} b
|
||||
*
|
||||
* @returns {bigint} maximum of numbers a and b
|
||||
*/
|
||||
function max (a, b) {
|
||||
a = BigInt(a)
|
||||
b = BigInt(b)
|
||||
return (a >= b) ? a : b
|
||||
}
|
||||
|
||||
/**
|
||||
* Minimum. min(a,b)==b if a>=b. min(a,b)==a if a<=b
|
||||
*
|
||||
* @param {number|bigint} a
|
||||
* @param {number|bigint} b
|
||||
*
|
||||
* @returns {bigint} minimum of numbers a and b
|
||||
*/
|
||||
function min (a, b) {
|
||||
a = BigInt(a)
|
||||
b = BigInt(b)
|
||||
return (a >= b) ? b : a
|
||||
}
|
||||
|
||||
/**
|
||||
* Modular inverse.
|
||||
*
|
||||
* @param {number|bigint} a The number to find an inverse for
|
||||
* @param {number|bigint} n The modulo
|
||||
*
|
||||
* @throws {RangeError} a does not have inverse modulo n
|
||||
*
|
||||
* @returns {bigint} the inverse modulo n
|
||||
*/
|
||||
function modInv (a, n) {
|
||||
const egcd = eGcd(toZn(a, n), n)
|
||||
if (egcd.g !== 1n) {
|
||||
throw new RangeError(`${a.toString()} does not have inverse modulo ${n.toString()}`) // modular inverse does not exist
|
||||
} else {
|
||||
return toZn(egcd.x, n)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Modular exponentiation b**e mod n. Currently using the right-to-left binary method
|
||||
*
|
||||
* @param {number|bigint} b base
|
||||
* @param {number|bigint} e exponent
|
||||
* @param {number|bigint} n modulo
|
||||
*
|
||||
* @returns {bigint} b**e mod n
|
||||
*/
|
||||
function modPow (b, e, n) {
|
||||
n = BigInt(n)
|
||||
if (n === 0n) { throw new RangeError('n must be > 0') } else if (n === 1n) { return BigInt(0) }
|
||||
|
||||
b = toZn(b, n)
|
||||
|
||||
e = BigInt(e)
|
||||
if (e < 0n) {
|
||||
return modInv(modPow(b, abs(e), n), n)
|
||||
}
|
||||
|
||||
let r = 1n
|
||||
while (e > 0) {
|
||||
if ((e % 2n) === 1n) {
|
||||
r = (r * b) % n
|
||||
}
|
||||
e = e / 2n
|
||||
b = b ** 2n % n
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the smallest positive element that is congruent to a in modulo n
|
||||
* @param {number|bigint} a An integer
|
||||
* @param {number|bigint} n The modulo
|
||||
*
|
||||
* @returns {bigint} The smallest positive representation of a in modulo n
|
||||
*/
|
||||
function toZn (a, n) {
|
||||
n = BigInt(n)
|
||||
if (n <= 0) { return NaN }
|
||||
|
||||
a = BigInt(a) % n
|
||||
return (a < 0) ? a + n : a
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
*
|
||||
* @param {number | bigint} w A positive integer to be tested for primality
|
||||
* @param {number} [iterations = 16] The number of iterations for the primality test. The value shall be consistent with Table C.1, C.2 or C.3
|
||||
* @param {boolean} [disableWorkers = false] Disable the use of workers for the primality test
|
||||
*
|
||||
* @throws {RangeError} w MUST be >= 0
|
||||
*
|
||||
* @returns {Promise<boolean>} A promise that resolves to a boolean that is either true (a probably prime number) or false (definitely composite)
|
||||
*/
|
||||
function isProbablyPrime (w, iterations = 16, disableWorkers = false) {
|
||||
if (typeof w === 'number') {
|
||||
w = BigInt(w)
|
||||
}
|
||||
if (w < 0) throw RangeError('w MUST be >= 0')
|
||||
/* eslint-disable no-lone-blocks */
|
||||
{ // browser
|
||||
return new Promise((resolve, reject) => {
|
||||
const worker = new Worker(_isProbablyPrimeWorkerUrl())
|
||||
|
||||
worker.onmessage = (event) => {
|
||||
worker.terminate()
|
||||
resolve(event.data.isPrime)
|
||||
}
|
||||
|
||||
worker.onmessageerror = (event) => {
|
||||
reject(event)
|
||||
}
|
||||
|
||||
worker.postMessage({
|
||||
rnd: w,
|
||||
iterations: iterations,
|
||||
id: 0
|
||||
})
|
||||
})
|
||||
}
|
||||
/* eslint-enable no-lone-blocks */
|
||||
}
|
||||
|
||||
/**
|
||||
* 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).
|
||||
* The node version can also use worker_threads if they are available (enabled by default with Node 11 and
|
||||
* and can be enabled at runtime executing node --experimental-worker with node >=10.5.0).
|
||||
*
|
||||
* @param {number} bitLength The required bit length for the generated prime
|
||||
* @param {number} [iterations = 16] The number of iterations for the Miller-Rabin Probabilistic Primality Test
|
||||
*
|
||||
* @throws {RangeError} bitLength MUST be > 0
|
||||
*
|
||||
* @returns {Promise<bigint>} A promise that resolves to a bigint probable prime of bitLength bits.
|
||||
*/
|
||||
function prime (bitLength, iterations = 16) {
|
||||
if (bitLength < 1) throw new RangeError('bitLength MUST be > 0')
|
||||
|
||||
/* istanbul ignore if */
|
||||
if (!_useWorkers) { // If there is no support for workers
|
||||
let rnd = 0n
|
||||
do {
|
||||
rnd = fromBuffer(randBitsSync(bitLength, true))
|
||||
} while (!_isProbablyPrime(rnd, iterations))
|
||||
return new Promise((resolve) => { resolve(rnd) })
|
||||
}
|
||||
return new Promise((resolve) => {
|
||||
const workerList = []
|
||||
const _onmessage = (msg, newWorker) => {
|
||||
if (msg.isPrime) {
|
||||
// if a prime number has been found, stop all the workers, and return it
|
||||
for (let j = 0; j < workerList.length; j++) {
|
||||
workerList[j].terminate()
|
||||
}
|
||||
while (workerList.length) {
|
||||
workerList.pop()
|
||||
}
|
||||
resolve(msg.value)
|
||||
} else { // if a composite is found, make the worker test another random number
|
||||
const buf = randBitsSync(bitLength, true)
|
||||
const rnd = fromBuffer(buf)
|
||||
try {
|
||||
newWorker.postMessage({
|
||||
rnd: rnd,
|
||||
iterations: iterations,
|
||||
id: msg.id
|
||||
})
|
||||
} catch (error) {
|
||||
// The worker has already terminated. There is nothing to handle here
|
||||
}
|
||||
}
|
||||
}
|
||||
/* eslint-disable no-lone-blocks */
|
||||
{ // browser
|
||||
const workerURL = _isProbablyPrimeWorkerUrl()
|
||||
for (let i = 0; i < self.navigator.hardwareConcurrency - 1; i++) {
|
||||
const newWorker = new Worker(workerURL)
|
||||
newWorker.onmessage = (event) => _onmessage(event.data, newWorker)
|
||||
workerList.push(newWorker)
|
||||
}
|
||||
}
|
||||
/* eslint-enable no-lone-blocks */
|
||||
for (let i = 0; i < workerList.length; i++) {
|
||||
randBits(bitLength, true).then(function (buf) {
|
||||
const rnd = fromBuffer(buf)
|
||||
workerList[i].postMessage({
|
||||
rnd: rnd,
|
||||
iterations: iterations,
|
||||
id: i
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator.
|
||||
* The sync version is NOT RECOMMENDED since it won't use workers and thus it'll be slower and may freeze thw window in browser's javascript. Please consider using prime() instead.
|
||||
*
|
||||
* @param {number} bitLength The required bit length for the generated prime
|
||||
* @param {number} [iterations = 16] The number of iterations for the Miller-Rabin Probabilistic Primality Test
|
||||
*
|
||||
* @throws {RangeError} bitLength MUST be > 0
|
||||
*
|
||||
* @returns {bigint} A bigint probable prime of bitLength bits.
|
||||
*/
|
||||
function primeSync (bitLength, iterations = 16) {
|
||||
if (bitLength < 1) throw new RangeError('bitLength MUST be > 0')
|
||||
let rnd = 0n
|
||||
do {
|
||||
rnd = fromBuffer(randBitsSync(bitLength, true))
|
||||
} while (!_isProbablyPrime(rnd, iterations))
|
||||
return rnd
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a cryptographically secure random integer between [min,max]. Both numbers must be >=0
|
||||
* @param {bigint} max Returned value will be <= max
|
||||
* @param {bigint} [min = BigInt(1)] Returned value will be >= min
|
||||
*
|
||||
* @throws {RangeError} Arguments MUST be: max > 0 && min >=0 && max > min
|
||||
*
|
||||
* @returns {bigint} A cryptographically secure random bigint between [min,max]
|
||||
*/
|
||||
function randBetween (max, min = 1n) {
|
||||
if (max <= 0n || min < 0n || max <= min) throw new RangeError('Arguments MUST be: max > 0 && min >=0 && max > min')
|
||||
const interval = max - min
|
||||
const bitLen = bitLength(interval)
|
||||
let rnd
|
||||
do {
|
||||
const buf = randBitsSync(bitLen)
|
||||
rnd = fromBuffer(buf)
|
||||
} while (rnd > interval)
|
||||
return rnd + min
|
||||
}
|
||||
|
||||
/**
|
||||
* Secure random bits for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()
|
||||
*
|
||||
* @param {number} bitLength The desired number of random bits
|
||||
* @param {boolean} [forceLength = false] If we want to force the output to have a specific bit length. It basically forces the msb to be 1
|
||||
*
|
||||
* @throws {RangeError} bitLength MUST be > 0
|
||||
*
|
||||
* @returns {Promise<Buffer | Uint8Array>} A Promise that resolves to a Buffer/UInt8Array (Node.js/Browser) filled with cryptographically secure random bits
|
||||
*/
|
||||
function randBits (bitLength, forceLength = false) {
|
||||
if (bitLength < 1) throw new RangeError('bitLength MUST be > 0')
|
||||
|
||||
const byteLength = Math.ceil(bitLength / 8)
|
||||
const bitLengthMod8 = bitLength % 8
|
||||
|
||||
return new Promise((resolve) => {
|
||||
randBytes(byteLength, false).then(function (rndBytes) {
|
||||
if (bitLengthMod8) {
|
||||
// Fill with 0's the extra bits
|
||||
rndBytes[0] = rndBytes[0] & (2 ** bitLengthMod8 - 1)
|
||||
}
|
||||
if (forceLength) {
|
||||
const mask = bitLengthMod8 ? 2 ** (bitLengthMod8 - 1) : 128
|
||||
rndBytes[0] = rndBytes[0] | mask
|
||||
}
|
||||
resolve(rndBytes)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Secure random bits for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()
|
||||
* @param {number} bitLength The desired number of random bits
|
||||
* @param {boolean} [forceLength = false] If we want to force the output to have a specific bit length. It basically forces the msb to be 1
|
||||
*
|
||||
* @throws {RangeError} bitLength MUST be > 0
|
||||
*
|
||||
* @returns {Buffer | Uint8Array} A Buffer/UInt8Array (Node.js/Browser) filled with cryptographically secure random bits
|
||||
*/
|
||||
function randBitsSync (bitLength, forceLength = false) {
|
||||
if (bitLength < 1) throw new RangeError('bitLength MUST be > 0')
|
||||
|
||||
const byteLength = Math.ceil(bitLength / 8)
|
||||
const rndBytes = randBytesSync(byteLength, false)
|
||||
const bitLengthMod8 = bitLength % 8
|
||||
if (bitLengthMod8) {
|
||||
// Fill with 0's the extra bits
|
||||
rndBytes[0] = rndBytes[0] & (2 ** bitLengthMod8 - 1)
|
||||
}
|
||||
if (forceLength) {
|
||||
const mask = bitLengthMod8 ? 2 ** (bitLengthMod8 - 1) : 128
|
||||
rndBytes[0] = rndBytes[0] | mask
|
||||
}
|
||||
return rndBytes
|
||||
}
|
||||
|
||||
/**
|
||||
* Secure random bytes for both node and browsers. Node version uses crypto.randomBytes() and browser one self.crypto.getRandomValues()
|
||||
*
|
||||
* @param {number} byteLength The desired number of random bytes
|
||||
* @param {boolean} [forceLength = false] If we want to force the output to have a bit length of 8*byteLength. It basically forces the msb to be 1
|
||||
*
|
||||
* @throws {RangeError} byteLength MUST be > 0
|
||||
*
|
||||
* @returns {Promise<Buffer | Uint8Array>} A promise that resolves to a Buffer/UInt8Array (Node.js/Browser) filled with cryptographically secure random bytes
|
||||
*/
|
||||
function randBytes (byteLength, forceLength = false) {
|
||||
if (byteLength < 1) throw new RangeError('byteLength MUST be > 0')
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
/* eslint-disable no-lone-blocks */
|
||||
{ // browser
|
||||
const buf = new Uint8Array(byteLength)
|
||||
self.crypto.getRandomValues(buf)
|
||||
// If fixed length is required we put the first bit to 1 -> to get the necessary bitLength
|
||||
if (forceLength) buf[0] = buf[0] | 128
|
||||
resolve(buf)
|
||||
}
|
||||
/* eslint-enable no-lone-blocks */
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Secure random bytes for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()
|
||||
*
|
||||
* @param {number} byteLength The desired number of random bytes
|
||||
* @param {boolean} [forceLength = false] If we want to force the output to have a bit length of 8*byteLength. It basically forces the msb to be 1
|
||||
*
|
||||
* @throws {RangeError} byteLength MUST be > 0
|
||||
*
|
||||
* @returns {Buffer | Uint8Array} A Buffer/UInt8Array (Node.js/Browser) filled with cryptographically secure random bytes
|
||||
*/
|
||||
function randBytesSync (byteLength, forceLength = false) {
|
||||
if (byteLength < 1) throw new RangeError('byteLength MUST be > 0')
|
||||
|
||||
/* eslint-disable no-lone-blocks */
|
||||
{ // browser
|
||||
const buf = new Uint8Array(byteLength)
|
||||
self.crypto.getRandomValues(buf)
|
||||
// If fixed length is required we put the first bit to 1 -> to get the necessary bitLength
|
||||
if (forceLength) buf[0] = buf[0] | 128
|
||||
return buf
|
||||
}
|
||||
/* eslint-enable no-lone-blocks */
|
||||
}
|
||||
|
||||
/* HELPER FUNCTIONS */
|
||||
|
||||
function fromBuffer (buf) {
|
||||
let ret = 0n
|
||||
for (const i of buf.values()) {
|
||||
const bi = BigInt(i)
|
||||
ret = (ret << BigInt(8)) + bi
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
function _isProbablyPrimeWorkerUrl () {
|
||||
// Let's us first add all the required functions
|
||||
let workerCode = `'use strict';const ${eGcd.name}=${eGcd.toString()};const ${modInv.name}=${modInv.toString()};const ${modPow.name}=${modPow.toString()};const ${toZn.name}=${toZn.toString()};const ${randBitsSync.name}=${randBitsSync.toString()};const ${randBytesSync.name}=${randBytesSync.toString()};const ${randBetween.name}=${randBetween.toString()};const ${isProbablyPrime.name}=${_isProbablyPrime.toString()};${bitLength.toString()}${fromBuffer.toString()}`
|
||||
|
||||
const onmessage = async function (event) { // Let's start once we are called
|
||||
// event.data = {rnd: <bigint>, iterations: <number>}
|
||||
const isPrime = await isProbablyPrime(event.data.rnd, event.data.iterations)
|
||||
postMessage({
|
||||
isPrime: isPrime,
|
||||
value: event.data.rnd,
|
||||
id: event.data.id
|
||||
})
|
||||
}
|
||||
|
||||
workerCode += `onmessage = ${onmessage.toString()};`
|
||||
|
||||
return _workerUrl(workerCode)
|
||||
}
|
||||
|
||||
function _workerUrl (workerCode) {
|
||||
workerCode = `(() => {${workerCode}})()` // encapsulate IIFE
|
||||
const _blob = new Blob([workerCode], { type: 'text/javascript' })
|
||||
return window.URL.createObjectURL(_blob)
|
||||
}
|
||||
|
||||
function _isProbablyPrime (w, iterations = 16) {
|
||||
/*
|
||||
PREFILTERING. Even values but 2 are not primes, so don't test.
|
||||
1 is not a prime and the M-R algorithm needs w>1.
|
||||
*/
|
||||
if (w === 2n) return true
|
||||
else if ((w & 1n) === 0n || w === 1n) return false
|
||||
|
||||
/*
|
||||
Test if any of the first 250 small primes are a factor of w. 2 is not tested because it was already tested above.
|
||||
*/
|
||||
const firstPrimes = [
|
||||
3n,
|
||||
5n,
|
||||
7n,
|
||||
11n,
|
||||
13n,
|
||||
17n,
|
||||
19n,
|
||||
23n,
|
||||
29n,
|
||||
31n,
|
||||
37n,
|
||||
41n,
|
||||
43n,
|
||||
47n,
|
||||
53n,
|
||||
59n,
|
||||
61n,
|
||||
67n,
|
||||
71n,
|
||||
73n,
|
||||
79n,
|
||||
83n,
|
||||
89n,
|
||||
97n,
|
||||
101n,
|
||||
103n,
|
||||
107n,
|
||||
109n,
|
||||
113n,
|
||||
127n,
|
||||
131n,
|
||||
137n,
|
||||
139n,
|
||||
149n,
|
||||
151n,
|
||||
157n,
|
||||
163n,
|
||||
167n,
|
||||
173n,
|
||||
179n,
|
||||
181n,
|
||||
191n,
|
||||
193n,
|
||||
197n,
|
||||
199n,
|
||||
211n,
|
||||
223n,
|
||||
227n,
|
||||
229n,
|
||||
233n,
|
||||
239n,
|
||||
241n,
|
||||
251n,
|
||||
257n,
|
||||
263n,
|
||||
269n,
|
||||
271n,
|
||||
277n,
|
||||
281n,
|
||||
283n,
|
||||
293n,
|
||||
307n,
|
||||
311n,
|
||||
313n,
|
||||
317n,
|
||||
331n,
|
||||
337n,
|
||||
347n,
|
||||
349n,
|
||||
353n,
|
||||
359n,
|
||||
367n,
|
||||
373n,
|
||||
379n,
|
||||
383n,
|
||||
389n,
|
||||
397n,
|
||||
401n,
|
||||
409n,
|
||||
419n,
|
||||
421n,
|
||||
431n,
|
||||
433n,
|
||||
439n,
|
||||
443n,
|
||||
449n,
|
||||
457n,
|
||||
461n,
|
||||
463n,
|
||||
467n,
|
||||
479n,
|
||||
487n,
|
||||
491n,
|
||||
499n,
|
||||
503n,
|
||||
509n,
|
||||
521n,
|
||||
523n,
|
||||
541n,
|
||||
547n,
|
||||
557n,
|
||||
563n,
|
||||
569n,
|
||||
571n,
|
||||
577n,
|
||||
587n,
|
||||
593n,
|
||||
599n,
|
||||
601n,
|
||||
607n,
|
||||
613n,
|
||||
617n,
|
||||
619n,
|
||||
631n,
|
||||
641n,
|
||||
643n,
|
||||
647n,
|
||||
653n,
|
||||
659n,
|
||||
661n,
|
||||
673n,
|
||||
677n,
|
||||
683n,
|
||||
691n,
|
||||
701n,
|
||||
709n,
|
||||
719n,
|
||||
727n,
|
||||
733n,
|
||||
739n,
|
||||
743n,
|
||||
751n,
|
||||
757n,
|
||||
761n,
|
||||
769n,
|
||||
773n,
|
||||
787n,
|
||||
797n,
|
||||
809n,
|
||||
811n,
|
||||
821n,
|
||||
823n,
|
||||
827n,
|
||||
829n,
|
||||
839n,
|
||||
853n,
|
||||
857n,
|
||||
859n,
|
||||
863n,
|
||||
877n,
|
||||
881n,
|
||||
883n,
|
||||
887n,
|
||||
907n,
|
||||
911n,
|
||||
919n,
|
||||
929n,
|
||||
937n,
|
||||
941n,
|
||||
947n,
|
||||
953n,
|
||||
967n,
|
||||
971n,
|
||||
977n,
|
||||
983n,
|
||||
991n,
|
||||
997n,
|
||||
1009n,
|
||||
1013n,
|
||||
1019n,
|
||||
1021n,
|
||||
1031n,
|
||||
1033n,
|
||||
1039n,
|
||||
1049n,
|
||||
1051n,
|
||||
1061n,
|
||||
1063n,
|
||||
1069n,
|
||||
1087n,
|
||||
1091n,
|
||||
1093n,
|
||||
1097n,
|
||||
1103n,
|
||||
1109n,
|
||||
1117n,
|
||||
1123n,
|
||||
1129n,
|
||||
1151n,
|
||||
1153n,
|
||||
1163n,
|
||||
1171n,
|
||||
1181n,
|
||||
1187n,
|
||||
1193n,
|
||||
1201n,
|
||||
1213n,
|
||||
1217n,
|
||||
1223n,
|
||||
1229n,
|
||||
1231n,
|
||||
1237n,
|
||||
1249n,
|
||||
1259n,
|
||||
1277n,
|
||||
1279n,
|
||||
1283n,
|
||||
1289n,
|
||||
1291n,
|
||||
1297n,
|
||||
1301n,
|
||||
1303n,
|
||||
1307n,
|
||||
1319n,
|
||||
1321n,
|
||||
1327n,
|
||||
1361n,
|
||||
1367n,
|
||||
1373n,
|
||||
1381n,
|
||||
1399n,
|
||||
1409n,
|
||||
1423n,
|
||||
1427n,
|
||||
1429n,
|
||||
1433n,
|
||||
1439n,
|
||||
1447n,
|
||||
1451n,
|
||||
1453n,
|
||||
1459n,
|
||||
1471n,
|
||||
1481n,
|
||||
1483n,
|
||||
1487n,
|
||||
1489n,
|
||||
1493n,
|
||||
1499n,
|
||||
1511n,
|
||||
1523n,
|
||||
1531n,
|
||||
1543n,
|
||||
1549n,
|
||||
1553n,
|
||||
1559n,
|
||||
1567n,
|
||||
1571n,
|
||||
1579n,
|
||||
1583n,
|
||||
1597n
|
||||
]
|
||||
|
||||
for (let i = 0; i < firstPrimes.length && (firstPrimes[i] <= w); i++) {
|
||||
const p = firstPrimes[i]
|
||||
if (w === p) return true
|
||||
else if (w % p === 0n) return false
|
||||
}
|
||||
|
||||
/*
|
||||
1. Let a be the largest integer such that 2**a divides w−1.
|
||||
2. m = (w−1) / 2**a.
|
||||
3. wlen = len (w).
|
||||
4. For i = 1 to iterations do
|
||||
4.1 Obtain a string b of wlen bits from an RBG.
|
||||
Comment: Ensure that 1 < b < w−1.
|
||||
4.2 If ((b ≤ 1) or (b ≥ w−1)), then go to step 4.1.
|
||||
4.3 z = b**m mod w.
|
||||
4.4 If ((z = 1) or (z = w − 1)), then go to step 4.7.
|
||||
4.5 For j = 1 to a − 1 do.
|
||||
4.5.1 z = z**2 mod w.
|
||||
4.5.2 If (z = w−1), then go to step 4.7.
|
||||
4.5.3 If (z = 1), then go to step 4.6.
|
||||
4.6 Return COMPOSITE.
|
||||
4.7 Continue.
|
||||
Comment: Increment i for the do-loop in step 4.
|
||||
5. Return PROBABLY PRIME.
|
||||
*/
|
||||
let a = 0n
|
||||
const d = w - 1n
|
||||
let aux = d
|
||||
while (aux % 2n === 0n) {
|
||||
aux /= 2n
|
||||
++a
|
||||
}
|
||||
|
||||
const m = d / (2n ** a)
|
||||
|
||||
do {
|
||||
const b = randBetween(d, 2n)
|
||||
let z = modPow(b, m, w)
|
||||
if (z === 1n || z === d) continue
|
||||
let j = 1
|
||||
while (j < a) {
|
||||
z = modPow(z, 2n, w)
|
||||
if (z === d) break
|
||||
if (z === 1n) return false
|
||||
j++
|
||||
}
|
||||
if (z !== d) return false
|
||||
} while (--iterations)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
let _useWorkers = false // The following is just to check whether we can use workers
|
||||
/* eslint-disable no-lone-blocks */
|
||||
{ // Native JS
|
||||
if (self.Worker) _useWorkers = true
|
||||
}
|
||||
|
||||
export { abs, bitLength, eGcd, gcd, isProbablyPrime, lcm, max, min, modInv, modPow, prime, primeSync, randBetween, randBits, randBitsSync, randBytes, randBytesSync, toZn }
|
|
@ -1,867 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
/**
|
||||
* Absolute value. abs(a)==a if a>=0. abs(a)==-a if a<0
|
||||
*
|
||||
* @param {number|bigint} a
|
||||
*
|
||||
* @returns {bigint} the absolute value of a
|
||||
*/
|
||||
function abs (a) {
|
||||
a = BigInt(a)
|
||||
return (a >= 0n) ? a : -a
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bitlength of a number
|
||||
*
|
||||
* @param {number|bigint} a
|
||||
* @returns {number} - the bit length
|
||||
*/
|
||||
function bitLength (a) {
|
||||
a = BigInt(a)
|
||||
if (a === 1n) { return 1 }
|
||||
let bits = 1
|
||||
do {
|
||||
bits++
|
||||
} while ((a >>= 1n) > 1n)
|
||||
return bits
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} egcdReturn A triple (g, x, y), such that ax + by = g = gcd(a, b).
|
||||
* @property {bigint} g
|
||||
* @property {bigint} x
|
||||
* @property {bigint} y
|
||||
*/
|
||||
/**
|
||||
* 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).
|
||||
*
|
||||
* @param {number|bigint} a
|
||||
* @param {number|bigint} b
|
||||
*
|
||||
* @throws {RangeError} a and b MUST be > 0
|
||||
*
|
||||
* @returns {egcdReturn} A triple (g, x, y), such that ax + by = g = gcd(a, b).
|
||||
*/
|
||||
function eGcd (a, b) {
|
||||
a = BigInt(a)
|
||||
b = BigInt(b)
|
||||
if (a <= 0n | b <= 0n) throw new RangeError('a and b MUST be > 0') // a and b MUST be positive
|
||||
|
||||
let x = 0n
|
||||
let y = 1n
|
||||
let u = 1n
|
||||
let v = 0n
|
||||
|
||||
while (a !== 0n) {
|
||||
const q = b / a
|
||||
const r = b % a
|
||||
const m = x - (u * q)
|
||||
const n = y - (v * q)
|
||||
b = a
|
||||
a = r
|
||||
x = u
|
||||
y = v
|
||||
u = m
|
||||
v = n
|
||||
}
|
||||
return {
|
||||
g: b,
|
||||
x: x,
|
||||
y: y
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Greatest-common divisor of two integers based on the iterative binary algorithm.
|
||||
*
|
||||
* @param {number|bigint} a
|
||||
* @param {number|bigint} b
|
||||
*
|
||||
* @returns {bigint} The greatest common divisor of a and b
|
||||
*/
|
||||
function gcd (a, b) {
|
||||
a = abs(a)
|
||||
b = abs(b)
|
||||
if (a === 0n) { return b } else if (b === 0n) { return a }
|
||||
|
||||
let shift = 0n
|
||||
while (!((a | b) & 1n)) {
|
||||
a >>= 1n
|
||||
b >>= 1n
|
||||
shift++
|
||||
}
|
||||
while (!(a & 1n)) a >>= 1n
|
||||
do {
|
||||
while (!(b & 1n)) b >>= 1n
|
||||
if (a > b) {
|
||||
const x = a
|
||||
a = b
|
||||
b = x
|
||||
}
|
||||
b -= a
|
||||
} while (b)
|
||||
|
||||
// rescale
|
||||
return a << shift
|
||||
}
|
||||
|
||||
/**
|
||||
* The least common multiple computed as abs(a*b)/gcd(a,b)
|
||||
* @param {number|bigint} a
|
||||
* @param {number|bigint} b
|
||||
*
|
||||
* @returns {bigint} The least common multiple of a and b
|
||||
*/
|
||||
function lcm (a, b) {
|
||||
a = BigInt(a)
|
||||
b = BigInt(b)
|
||||
if (a === 0n && b === 0n) return BigInt(0)
|
||||
return abs(a * b) / gcd(a, b)
|
||||
}
|
||||
|
||||
/**
|
||||
* Maximum. max(a,b)==a if a>=b. max(a,b)==b if a<=b
|
||||
*
|
||||
* @param {number|bigint} a
|
||||
* @param {number|bigint} b
|
||||
*
|
||||
* @returns {bigint} maximum of numbers a and b
|
||||
*/
|
||||
function max (a, b) {
|
||||
a = BigInt(a)
|
||||
b = BigInt(b)
|
||||
return (a >= b) ? a : b
|
||||
}
|
||||
|
||||
/**
|
||||
* Minimum. min(a,b)==b if a>=b. min(a,b)==a if a<=b
|
||||
*
|
||||
* @param {number|bigint} a
|
||||
* @param {number|bigint} b
|
||||
*
|
||||
* @returns {bigint} minimum of numbers a and b
|
||||
*/
|
||||
function min (a, b) {
|
||||
a = BigInt(a)
|
||||
b = BigInt(b)
|
||||
return (a >= b) ? b : a
|
||||
}
|
||||
|
||||
/**
|
||||
* Modular inverse.
|
||||
*
|
||||
* @param {number|bigint} a The number to find an inverse for
|
||||
* @param {number|bigint} n The modulo
|
||||
*
|
||||
* @throws {RangeError} a does not have inverse modulo n
|
||||
*
|
||||
* @returns {bigint} the inverse modulo n
|
||||
*/
|
||||
function modInv (a, n) {
|
||||
const egcd = eGcd(toZn(a, n), n)
|
||||
if (egcd.g !== 1n) {
|
||||
throw new RangeError(`${a.toString()} does not have inverse modulo ${n.toString()}`) // modular inverse does not exist
|
||||
} else {
|
||||
return toZn(egcd.x, n)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Modular exponentiation b**e mod n. Currently using the right-to-left binary method
|
||||
*
|
||||
* @param {number|bigint} b base
|
||||
* @param {number|bigint} e exponent
|
||||
* @param {number|bigint} n modulo
|
||||
*
|
||||
* @returns {bigint} b**e mod n
|
||||
*/
|
||||
function modPow (b, e, n) {
|
||||
n = BigInt(n)
|
||||
if (n === 0n) { throw new RangeError('n must be > 0') } else if (n === 1n) { return BigInt(0) }
|
||||
|
||||
b = toZn(b, n)
|
||||
|
||||
e = BigInt(e)
|
||||
if (e < 0n) {
|
||||
return modInv(modPow(b, abs(e), n), n)
|
||||
}
|
||||
|
||||
let r = 1n
|
||||
while (e > 0) {
|
||||
if ((e % 2n) === 1n) {
|
||||
r = (r * b) % n
|
||||
}
|
||||
e = e / 2n
|
||||
b = b ** 2n % n
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the smallest positive element that is congruent to a in modulo n
|
||||
* @param {number|bigint} a An integer
|
||||
* @param {number|bigint} n The modulo
|
||||
*
|
||||
* @returns {bigint} The smallest positive representation of a in modulo n
|
||||
*/
|
||||
function toZn (a, n) {
|
||||
n = BigInt(n)
|
||||
if (n <= 0) { return NaN }
|
||||
|
||||
a = BigInt(a) % n
|
||||
return (a < 0) ? a + n : a
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
*
|
||||
* @param {number | bigint} w A positive integer to be tested for primality
|
||||
* @param {number} [iterations = 16] The number of iterations for the primality test. The value shall be consistent with Table C.1, C.2 or C.3
|
||||
* @param {boolean} [disableWorkers = false] Disable the use of workers for the primality test
|
||||
*
|
||||
* @throws {RangeError} w MUST be >= 0
|
||||
*
|
||||
* @returns {Promise<boolean>} A promise that resolves to a boolean that is either true (a probably prime number) or false (definitely composite)
|
||||
*/
|
||||
function isProbablyPrime (w, iterations = 16, disableWorkers = false) {
|
||||
if (typeof w === 'number') {
|
||||
w = BigInt(w)
|
||||
}
|
||||
if (w < 0) throw RangeError('w MUST be >= 0')
|
||||
/* eslint-disable no-lone-blocks */
|
||||
{ // Node.js
|
||||
/* istanbul ignore else */
|
||||
if (!disableWorkers && _useWorkers) {
|
||||
const { Worker } = require('worker_threads')
|
||||
return new Promise((resolve, reject) => {
|
||||
const worker = new Worker(__filename)
|
||||
|
||||
worker.on('message', (data) => {
|
||||
worker.terminate()
|
||||
resolve(data.isPrime)
|
||||
})
|
||||
|
||||
worker.on('error', reject)
|
||||
|
||||
worker.postMessage({
|
||||
rnd: w,
|
||||
iterations: iterations,
|
||||
id: 0
|
||||
})
|
||||
})
|
||||
} else {
|
||||
return new Promise((resolve) => {
|
||||
resolve(_isProbablyPrime(w, iterations))
|
||||
})
|
||||
}
|
||||
}
|
||||
/* eslint-enable no-lone-blocks */
|
||||
}
|
||||
|
||||
/**
|
||||
* 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).
|
||||
* The node version can also use worker_threads if they are available (enabled by default with Node 11 and
|
||||
* and can be enabled at runtime executing node --experimental-worker with node >=10.5.0).
|
||||
*
|
||||
* @param {number} bitLength The required bit length for the generated prime
|
||||
* @param {number} [iterations = 16] The number of iterations for the Miller-Rabin Probabilistic Primality Test
|
||||
*
|
||||
* @throws {RangeError} bitLength MUST be > 0
|
||||
*
|
||||
* @returns {Promise<bigint>} A promise that resolves to a bigint probable prime of bitLength bits.
|
||||
*/
|
||||
function prime (bitLength, iterations = 16) {
|
||||
if (bitLength < 1) throw new RangeError('bitLength MUST be > 0')
|
||||
|
||||
/* istanbul ignore if */
|
||||
if (!_useWorkers) { // If there is no support for workers
|
||||
let rnd = 0n
|
||||
do {
|
||||
rnd = fromBuffer(randBitsSync(bitLength, true))
|
||||
} while (!_isProbablyPrime(rnd, iterations))
|
||||
return new Promise((resolve) => { resolve(rnd) })
|
||||
}
|
||||
return new Promise((resolve) => {
|
||||
const workerList = []
|
||||
const _onmessage = (msg, newWorker) => {
|
||||
if (msg.isPrime) {
|
||||
// if a prime number has been found, stop all the workers, and return it
|
||||
for (let j = 0; j < workerList.length; j++) {
|
||||
workerList[j].terminate()
|
||||
}
|
||||
while (workerList.length) {
|
||||
workerList.pop()
|
||||
}
|
||||
resolve(msg.value)
|
||||
} else { // if a composite is found, make the worker test another random number
|
||||
const buf = randBitsSync(bitLength, true)
|
||||
const rnd = fromBuffer(buf)
|
||||
try {
|
||||
newWorker.postMessage({
|
||||
rnd: rnd,
|
||||
iterations: iterations,
|
||||
id: msg.id
|
||||
})
|
||||
} catch (error) {
|
||||
// The worker has already terminated. There is nothing to handle here
|
||||
}
|
||||
}
|
||||
}
|
||||
/* eslint-disable no-lone-blocks */
|
||||
{ // Node.js
|
||||
const { cpus } = require('os')
|
||||
const { Worker } = require('worker_threads')
|
||||
for (let i = 0; i < cpus().length - 1; i++) {
|
||||
const newWorker = new Worker(__filename)
|
||||
newWorker.on('message', (msg) => _onmessage(msg, newWorker))
|
||||
workerList.push(newWorker)
|
||||
}
|
||||
}
|
||||
/* eslint-enable no-lone-blocks */
|
||||
for (let i = 0; i < workerList.length; i++) {
|
||||
randBits(bitLength, true).then(function (buf) {
|
||||
const rnd = fromBuffer(buf)
|
||||
workerList[i].postMessage({
|
||||
rnd: rnd,
|
||||
iterations: iterations,
|
||||
id: i
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator.
|
||||
* The sync version is NOT RECOMMENDED since it won't use workers and thus it'll be slower and may freeze thw window in browser's javascript. Please consider using prime() instead.
|
||||
*
|
||||
* @param {number} bitLength The required bit length for the generated prime
|
||||
* @param {number} [iterations = 16] The number of iterations for the Miller-Rabin Probabilistic Primality Test
|
||||
*
|
||||
* @throws {RangeError} bitLength MUST be > 0
|
||||
*
|
||||
* @returns {bigint} A bigint probable prime of bitLength bits.
|
||||
*/
|
||||
function primeSync (bitLength, iterations = 16) {
|
||||
if (bitLength < 1) throw new RangeError('bitLength MUST be > 0')
|
||||
let rnd = 0n
|
||||
do {
|
||||
rnd = fromBuffer(randBitsSync(bitLength, true))
|
||||
} while (!_isProbablyPrime(rnd, iterations))
|
||||
return rnd
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a cryptographically secure random integer between [min,max]. Both numbers must be >=0
|
||||
* @param {bigint} max Returned value will be <= max
|
||||
* @param {bigint} [min = BigInt(1)] Returned value will be >= min
|
||||
*
|
||||
* @throws {RangeError} Arguments MUST be: max > 0 && min >=0 && max > min
|
||||
*
|
||||
* @returns {bigint} A cryptographically secure random bigint between [min,max]
|
||||
*/
|
||||
function randBetween (max, min = 1n) {
|
||||
if (max <= 0n || min < 0n || max <= min) throw new RangeError('Arguments MUST be: max > 0 && min >=0 && max > min')
|
||||
const interval = max - min
|
||||
const bitLen = bitLength(interval)
|
||||
let rnd
|
||||
do {
|
||||
const buf = randBitsSync(bitLen)
|
||||
rnd = fromBuffer(buf)
|
||||
} while (rnd > interval)
|
||||
return rnd + min
|
||||
}
|
||||
|
||||
/**
|
||||
* Secure random bits for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()
|
||||
*
|
||||
* @param {number} bitLength The desired number of random bits
|
||||
* @param {boolean} [forceLength = false] If we want to force the output to have a specific bit length. It basically forces the msb to be 1
|
||||
*
|
||||
* @throws {RangeError} bitLength MUST be > 0
|
||||
*
|
||||
* @returns {Promise<Buffer | Uint8Array>} A Promise that resolves to a Buffer/UInt8Array (Node.js/Browser) filled with cryptographically secure random bits
|
||||
*/
|
||||
function randBits (bitLength, forceLength = false) {
|
||||
if (bitLength < 1) throw new RangeError('bitLength MUST be > 0')
|
||||
|
||||
const byteLength = Math.ceil(bitLength / 8)
|
||||
const bitLengthMod8 = bitLength % 8
|
||||
|
||||
return new Promise((resolve) => {
|
||||
randBytes(byteLength, false).then(function (rndBytes) {
|
||||
if (bitLengthMod8) {
|
||||
// Fill with 0's the extra bits
|
||||
rndBytes[0] = rndBytes[0] & (2 ** bitLengthMod8 - 1)
|
||||
}
|
||||
if (forceLength) {
|
||||
const mask = bitLengthMod8 ? 2 ** (bitLengthMod8 - 1) : 128
|
||||
rndBytes[0] = rndBytes[0] | mask
|
||||
}
|
||||
resolve(rndBytes)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Secure random bits for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()
|
||||
* @param {number} bitLength The desired number of random bits
|
||||
* @param {boolean} [forceLength = false] If we want to force the output to have a specific bit length. It basically forces the msb to be 1
|
||||
*
|
||||
* @throws {RangeError} bitLength MUST be > 0
|
||||
*
|
||||
* @returns {Buffer | Uint8Array} A Buffer/UInt8Array (Node.js/Browser) filled with cryptographically secure random bits
|
||||
*/
|
||||
function randBitsSync (bitLength, forceLength = false) {
|
||||
if (bitLength < 1) throw new RangeError('bitLength MUST be > 0')
|
||||
|
||||
const byteLength = Math.ceil(bitLength / 8)
|
||||
const rndBytes = randBytesSync(byteLength, false)
|
||||
const bitLengthMod8 = bitLength % 8
|
||||
if (bitLengthMod8) {
|
||||
// Fill with 0's the extra bits
|
||||
rndBytes[0] = rndBytes[0] & (2 ** bitLengthMod8 - 1)
|
||||
}
|
||||
if (forceLength) {
|
||||
const mask = bitLengthMod8 ? 2 ** (bitLengthMod8 - 1) : 128
|
||||
rndBytes[0] = rndBytes[0] | mask
|
||||
}
|
||||
return rndBytes
|
||||
}
|
||||
|
||||
/**
|
||||
* Secure random bytes for both node and browsers. Node version uses crypto.randomBytes() and browser one self.crypto.getRandomValues()
|
||||
*
|
||||
* @param {number} byteLength The desired number of random bytes
|
||||
* @param {boolean} [forceLength = false] If we want to force the output to have a bit length of 8*byteLength. It basically forces the msb to be 1
|
||||
*
|
||||
* @throws {RangeError} byteLength MUST be > 0
|
||||
*
|
||||
* @returns {Promise<Buffer | Uint8Array>} A promise that resolves to a Buffer/UInt8Array (Node.js/Browser) filled with cryptographically secure random bytes
|
||||
*/
|
||||
function randBytes (byteLength, forceLength = false) {
|
||||
if (byteLength < 1) throw new RangeError('byteLength MUST be > 0')
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
/* eslint-disable no-lone-blocks */
|
||||
{
|
||||
const crypto = require('crypto')
|
||||
crypto.randomBytes(byteLength, function (err, buf) {
|
||||
/* istanbul ignore if */
|
||||
if (err) reject(err)
|
||||
// If fixed length is required we put the first bit to 1 -> to get the necessary bitLength
|
||||
if (forceLength) buf[0] = buf[0] | 128
|
||||
resolve(buf)
|
||||
})
|
||||
}
|
||||
/* eslint-enable no-lone-blocks */
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Secure random bytes for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()
|
||||
*
|
||||
* @param {number} byteLength The desired number of random bytes
|
||||
* @param {boolean} [forceLength = false] If we want to force the output to have a bit length of 8*byteLength. It basically forces the msb to be 1
|
||||
*
|
||||
* @throws {RangeError} byteLength MUST be > 0
|
||||
*
|
||||
* @returns {Buffer | Uint8Array} A Buffer/UInt8Array (Node.js/Browser) filled with cryptographically secure random bytes
|
||||
*/
|
||||
function randBytesSync (byteLength, forceLength = false) {
|
||||
if (byteLength < 1) throw new RangeError('byteLength MUST be > 0')
|
||||
|
||||
/* eslint-disable no-lone-blocks */
|
||||
{ // node
|
||||
const crypto = require('crypto')
|
||||
const buf = crypto.randomBytes(byteLength)
|
||||
// If fixed length is required we put the first bit to 1 -> to get the necessary bitLength
|
||||
if (forceLength) buf[0] = buf[0] | 128
|
||||
return buf
|
||||
}
|
||||
/* eslint-enable no-lone-blocks */
|
||||
}
|
||||
|
||||
/* HELPER FUNCTIONS */
|
||||
|
||||
function fromBuffer (buf) {
|
||||
let ret = 0n
|
||||
for (const i of buf.values()) {
|
||||
const bi = BigInt(i)
|
||||
ret = (ret << BigInt(8)) + bi
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
function _isProbablyPrime (w, iterations = 16) {
|
||||
/*
|
||||
PREFILTERING. Even values but 2 are not primes, so don't test.
|
||||
1 is not a prime and the M-R algorithm needs w>1.
|
||||
*/
|
||||
if (w === 2n) return true
|
||||
else if ((w & 1n) === 0n || w === 1n) return false
|
||||
|
||||
/*
|
||||
Test if any of the first 250 small primes are a factor of w. 2 is not tested because it was already tested above.
|
||||
*/
|
||||
const firstPrimes = [
|
||||
3n,
|
||||
5n,
|
||||
7n,
|
||||
11n,
|
||||
13n,
|
||||
17n,
|
||||
19n,
|
||||
23n,
|
||||
29n,
|
||||
31n,
|
||||
37n,
|
||||
41n,
|
||||
43n,
|
||||
47n,
|
||||
53n,
|
||||
59n,
|
||||
61n,
|
||||
67n,
|
||||
71n,
|
||||
73n,
|
||||
79n,
|
||||
83n,
|
||||
89n,
|
||||
97n,
|
||||
101n,
|
||||
103n,
|
||||
107n,
|
||||
109n,
|
||||
113n,
|
||||
127n,
|
||||
131n,
|
||||
137n,
|
||||
139n,
|
||||
149n,
|
||||
151n,
|
||||
157n,
|
||||
163n,
|
||||
167n,
|
||||
173n,
|
||||
179n,
|
||||
181n,
|
||||
191n,
|
||||
193n,
|
||||
197n,
|
||||
199n,
|
||||
211n,
|
||||
223n,
|
||||
227n,
|
||||
229n,
|
||||
233n,
|
||||
239n,
|
||||
241n,
|
||||
251n,
|
||||
257n,
|
||||
263n,
|
||||
269n,
|
||||
271n,
|
||||
277n,
|
||||
281n,
|
||||
283n,
|
||||
293n,
|
||||
307n,
|
||||
311n,
|
||||
313n,
|
||||
317n,
|
||||
331n,
|
||||
337n,
|
||||
347n,
|
||||
349n,
|
||||
353n,
|
||||
359n,
|
||||
367n,
|
||||
373n,
|
||||
379n,
|
||||
383n,
|
||||
389n,
|
||||
397n,
|
||||
401n,
|
||||
409n,
|
||||
419n,
|
||||
421n,
|
||||
431n,
|
||||
433n,
|
||||
439n,
|
||||
443n,
|
||||
449n,
|
||||
457n,
|
||||
461n,
|
||||
463n,
|
||||
467n,
|
||||
479n,
|
||||
487n,
|
||||
491n,
|
||||
499n,
|
||||
503n,
|
||||
509n,
|
||||
521n,
|
||||
523n,
|
||||
541n,
|
||||
547n,
|
||||
557n,
|
||||
563n,
|
||||
569n,
|
||||
571n,
|
||||
577n,
|
||||
587n,
|
||||
593n,
|
||||
599n,
|
||||
601n,
|
||||
607n,
|
||||
613n,
|
||||
617n,
|
||||
619n,
|
||||
631n,
|
||||
641n,
|
||||
643n,
|
||||
647n,
|
||||
653n,
|
||||
659n,
|
||||
661n,
|
||||
673n,
|
||||
677n,
|
||||
683n,
|
||||
691n,
|
||||
701n,
|
||||
709n,
|
||||
719n,
|
||||
727n,
|
||||
733n,
|
||||
739n,
|
||||
743n,
|
||||
751n,
|
||||
757n,
|
||||
761n,
|
||||
769n,
|
||||
773n,
|
||||
787n,
|
||||
797n,
|
||||
809n,
|
||||
811n,
|
||||
821n,
|
||||
823n,
|
||||
827n,
|
||||
829n,
|
||||
839n,
|
||||
853n,
|
||||
857n,
|
||||
859n,
|
||||
863n,
|
||||
877n,
|
||||
881n,
|
||||
883n,
|
||||
887n,
|
||||
907n,
|
||||
911n,
|
||||
919n,
|
||||
929n,
|
||||
937n,
|
||||
941n,
|
||||
947n,
|
||||
953n,
|
||||
967n,
|
||||
971n,
|
||||
977n,
|
||||
983n,
|
||||
991n,
|
||||
997n,
|
||||
1009n,
|
||||
1013n,
|
||||
1019n,
|
||||
1021n,
|
||||
1031n,
|
||||
1033n,
|
||||
1039n,
|
||||
1049n,
|
||||
1051n,
|
||||
1061n,
|
||||
1063n,
|
||||
1069n,
|
||||
1087n,
|
||||
1091n,
|
||||
1093n,
|
||||
1097n,
|
||||
1103n,
|
||||
1109n,
|
||||
1117n,
|
||||
1123n,
|
||||
1129n,
|
||||
1151n,
|
||||
1153n,
|
||||
1163n,
|
||||
1171n,
|
||||
1181n,
|
||||
1187n,
|
||||
1193n,
|
||||
1201n,
|
||||
1213n,
|
||||
1217n,
|
||||
1223n,
|
||||
1229n,
|
||||
1231n,
|
||||
1237n,
|
||||
1249n,
|
||||
1259n,
|
||||
1277n,
|
||||
1279n,
|
||||
1283n,
|
||||
1289n,
|
||||
1291n,
|
||||
1297n,
|
||||
1301n,
|
||||
1303n,
|
||||
1307n,
|
||||
1319n,
|
||||
1321n,
|
||||
1327n,
|
||||
1361n,
|
||||
1367n,
|
||||
1373n,
|
||||
1381n,
|
||||
1399n,
|
||||
1409n,
|
||||
1423n,
|
||||
1427n,
|
||||
1429n,
|
||||
1433n,
|
||||
1439n,
|
||||
1447n,
|
||||
1451n,
|
||||
1453n,
|
||||
1459n,
|
||||
1471n,
|
||||
1481n,
|
||||
1483n,
|
||||
1487n,
|
||||
1489n,
|
||||
1493n,
|
||||
1499n,
|
||||
1511n,
|
||||
1523n,
|
||||
1531n,
|
||||
1543n,
|
||||
1549n,
|
||||
1553n,
|
||||
1559n,
|
||||
1567n,
|
||||
1571n,
|
||||
1579n,
|
||||
1583n,
|
||||
1597n
|
||||
]
|
||||
|
||||
for (let i = 0; i < firstPrimes.length && (firstPrimes[i] <= w); i++) {
|
||||
const p = firstPrimes[i]
|
||||
if (w === p) return true
|
||||
else if (w % p === 0n) return false
|
||||
}
|
||||
|
||||
/*
|
||||
1. Let a be the largest integer such that 2**a divides w−1.
|
||||
2. m = (w−1) / 2**a.
|
||||
3. wlen = len (w).
|
||||
4. For i = 1 to iterations do
|
||||
4.1 Obtain a string b of wlen bits from an RBG.
|
||||
Comment: Ensure that 1 < b < w−1.
|
||||
4.2 If ((b ≤ 1) or (b ≥ w−1)), then go to step 4.1.
|
||||
4.3 z = b**m mod w.
|
||||
4.4 If ((z = 1) or (z = w − 1)), then go to step 4.7.
|
||||
4.5 For j = 1 to a − 1 do.
|
||||
4.5.1 z = z**2 mod w.
|
||||
4.5.2 If (z = w−1), then go to step 4.7.
|
||||
4.5.3 If (z = 1), then go to step 4.6.
|
||||
4.6 Return COMPOSITE.
|
||||
4.7 Continue.
|
||||
Comment: Increment i for the do-loop in step 4.
|
||||
5. Return PROBABLY PRIME.
|
||||
*/
|
||||
let a = 0n
|
||||
const d = w - 1n
|
||||
let aux = d
|
||||
while (aux % 2n === 0n) {
|
||||
aux /= 2n
|
||||
++a
|
||||
}
|
||||
|
||||
const m = d / (2n ** a)
|
||||
|
||||
do {
|
||||
const b = randBetween(d, 2n)
|
||||
let z = modPow(b, m, w)
|
||||
if (z === 1n || z === d) continue
|
||||
let j = 1
|
||||
while (j < a) {
|
||||
z = modPow(z, 2n, w)
|
||||
if (z === d) break
|
||||
if (z === 1n) return false
|
||||
j++
|
||||
}
|
||||
if (z !== d) return false
|
||||
} while (--iterations)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
let _useWorkers = false // The following is just to check whether we can use workers
|
||||
/* eslint-disable no-lone-blocks */
|
||||
{ // Node.js
|
||||
try {
|
||||
require.resolve('worker_threads')
|
||||
_useWorkers = true
|
||||
} catch (e) {
|
||||
/* istanbul ignore next */
|
||||
console.log(`[bigint-crypto-utils] WARNING:
|
||||
This node version doesn't support worker_threads. You should enable them in order to greatly speedup the generation of big prime numbers.
|
||||
· With Node >=11 it is enabled by default (consider upgrading).
|
||||
· With Node 10, starting with 10.5.0, you can enable worker_threads at runtime executing node --experimental-worker `)
|
||||
}
|
||||
}
|
||||
/* eslint-enable no-lone-blocks */
|
||||
|
||||
if (_useWorkers) { // node.js with support for workers
|
||||
const { parentPort, isMainThread } = require('worker_threads')
|
||||
/* istanbul ignore if */
|
||||
if (!isMainThread) { // worker
|
||||
parentPort.on('message', function (data) { // Let's start once we are called
|
||||
// data = {rnd: <bigint>, iterations: <number>}
|
||||
const isPrime = _isProbablyPrime(data.rnd, data.iterations)
|
||||
parentPort.postMessage({
|
||||
isPrime: isPrime,
|
||||
value: data.rnd,
|
||||
id: data.id
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
exports.abs = abs
|
||||
exports.bitLength = bitLength
|
||||
exports.eGcd = eGcd
|
||||
exports.gcd = gcd
|
||||
exports.isProbablyPrime = isProbablyPrime
|
||||
exports.lcm = lcm
|
||||
exports.max = max
|
||||
exports.min = min
|
||||
exports.modInv = modInv
|
||||
exports.modPow = modPow
|
||||
exports.prime = prime
|
||||
exports.primeSync = primeSync
|
||||
exports.randBetween = randBetween
|
||||
exports.randBits = randBits
|
||||
exports.randBitsSync = randBitsSync
|
||||
exports.randBytes = randBytes
|
||||
exports.randBytesSync = randBytesSync
|
||||
exports.toZn = toZn
|
File diff suppressed because it is too large
Load Diff
108
package.json
108
package.json
|
@ -21,64 +21,98 @@
|
|||
"url": "https://github.com/juanelas"
|
||||
},
|
||||
"repository": "github:juanelas/bigint-crypto-utils",
|
||||
"main": "./lib/index.node.js",
|
||||
"browser": "./lib/index.browser.mod.js",
|
||||
"types": "./types/index.d.ts",
|
||||
"directories": {
|
||||
"build": "./build",
|
||||
"lib": "./lib",
|
||||
"src": "./src",
|
||||
"test": "./test",
|
||||
"types": "./types"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.4.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "nyc mocha",
|
||||
"coverage": "nyc report --reporter=lcov",
|
||||
"build:js": "rollup -c build/rollup.config.js",
|
||||
"build:standard": "standard --fix",
|
||||
"build:browserTests": "rollup -c build/rollup.tests.config.js",
|
||||
"build:docs": "node build/build.docs.js",
|
||||
"build:dts": "node build/build.dts.js",
|
||||
"build": "run-s build:**",
|
||||
"preversion": "npm run build && npm run test",
|
||||
"postversion": "git push"
|
||||
"types": "./dist/esm/types/index.d.ts",
|
||||
"main": "./dist/cjs/index.node.cjs",
|
||||
"browser": "./dist/esm/index.browser.js",
|
||||
"module": "./dist/esm/index.node.js",
|
||||
"exports": {
|
||||
".": {
|
||||
"node": {
|
||||
"require": "./dist/cjs/index.node.cjs",
|
||||
"import": "./dist/esm/index.node.js"
|
||||
},
|
||||
"standard": {
|
||||
"default": "./dist/esm/index.browser.js"
|
||||
},
|
||||
"./bundles/": "./dist/bundles/",
|
||||
"./types/": "./dist/esm/types/"
|
||||
},
|
||||
"directories": {
|
||||
"build": "./build",
|
||||
"dist": "./dist",
|
||||
"docs": "./docs",
|
||||
"src": "./src",
|
||||
"test": "./test"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "run-s lint build:js docs test:browser coverage",
|
||||
"build:js": "rollup -c build/rollup.config.js",
|
||||
"clean": "rimraf .nyc_output .mocha-ts coverage dist docs",
|
||||
"coverage": "nyc --check-coverage --exclude build --exclude '{src/**/*.spec.ts,test/**/*.ts}' --reporter=text --reporter=lcov node ./build/bin/mocha-ts.js --require build/testing/mocha/mocha-init.js '{src/**/*.spec.ts,test/**/*.ts}'",
|
||||
"docs": "node build/build.docs.js",
|
||||
"lint": "ts-standard --fix",
|
||||
"mocha": "node ./build/bin/mocha-ts.js --require build/testing/mocha/mocha-init.js ",
|
||||
"preversion": "run-s lint build:js test:browser coverage",
|
||||
"postversion": "npm run docs",
|
||||
"test": "run-s test:browser test:node",
|
||||
"test:browser": "node build/testing/browser/index.js",
|
||||
"test:node": "npm run mocha -- '{src/**/*.spec.ts,test/**/*.ts}'",
|
||||
"watch": "npm run mocha -- --watch '{src/**/*.spec.ts,test/**/*.ts}'"
|
||||
},
|
||||
"ts-standard": {
|
||||
"env": [
|
||||
"mocha"
|
||||
],
|
||||
"globals": [
|
||||
"BigInt",
|
||||
"Blob",
|
||||
"postMessage",
|
||||
"self",
|
||||
"Worker"
|
||||
"Worker",
|
||||
"IS_BROWSER",
|
||||
"browser",
|
||||
"page",
|
||||
"_pkg",
|
||||
"chai"
|
||||
],
|
||||
"project": "./tsconfig.json",
|
||||
"ignore": [
|
||||
"/test/browser/",
|
||||
"/lib/index.browser.bundle.iife.js",
|
||||
"/lib/index.browser.bundle.mod.js"
|
||||
"dist/**/*",
|
||||
"examples/**/*"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-commonjs": "^16.0.0",
|
||||
"@rollup/plugin-commonjs": "^17.0.0",
|
||||
"@rollup/plugin-multi-entry": "^4.0.0",
|
||||
"@rollup/plugin-node-resolve": "^10.0.0",
|
||||
"@rollup/plugin-replace": "^2.3.4",
|
||||
"chai": "^4.2.0",
|
||||
"jsdoc-to-markdown": "^6.0.1",
|
||||
"mocha": "^8.2.1",
|
||||
"@rollup/plugin-node-resolve": "^11.2.0",
|
||||
"@rollup/plugin-replace": "^2.4.1",
|
||||
"@rollup/plugin-typescript": "^8.2.0",
|
||||
"@types/chai": "^4.2.14",
|
||||
"@types/mocha": "^8.2.1",
|
||||
"@types/node": ">=10.4",
|
||||
"chai": "^4.3.3",
|
||||
"glob": "^7.1.6",
|
||||
"json5": "^2.2.0",
|
||||
"minimatch": "^3.0.4",
|
||||
"mocha": "^8.3.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"nyc": "^15.1.0",
|
||||
"rollup": "^2.33.1",
|
||||
"pirates": "^4.0.1",
|
||||
"puppeteer": "^8.0.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"rollup": "^2.40.0",
|
||||
"rollup-plugin-terser": "^7.0.2",
|
||||
"standard": "^16.0.2",
|
||||
"typescript": "^3.9.7"
|
||||
"ts-standard": "^10.0.0",
|
||||
"tslib": "^2.1.0",
|
||||
"typedoc": "^0.20.29",
|
||||
"typedoc-plugin-markdown": "^3.6.0",
|
||||
"typescript": "^4.2.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": ">=10.4"
|
||||
"bigint-mod-arith": "^3.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/node": ">10.4"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>{{PKG_NAME}} - Mocha Tests</title>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/mocha/{{MOCHA_VERSION}}/mocha.min.css">
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/mocha/{{MOCHA_VERSION}}/mocha.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/chai/{{CHAI_VERSION}}/chai.min.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="mocha"></div>
|
||||
<script>mocha.setup('bdd'); mocha.setup({ timeout: 90000 });</script>
|
||||
{{TESTS}}
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -12,38 +12,32 @@ Secure random numbers are generated using the native crypto implementation of th
|
|||
|
||||
> 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
|
||||
## Usage
|
||||
|
||||
{{PKG_NAME}} can be imported to your project with `npm`:
|
||||
`{{PKG_NAME}}` can be imported to your project with `npm`:
|
||||
|
||||
```bash
|
||||
```console
|
||||
npm install {{PKG_NAME}}
|
||||
```
|
||||
|
||||
NPM installation defaults to the ES6 module for browsers and the CJS one for Node.js. For web browsers, you can also directly download the {{IIFE_BUNDLE}} or the {{ESM_BUNDLE}} from the repository.
|
||||
Then either require (Node.js CJS):
|
||||
|
||||
## Usage examples
|
||||
```javascript
|
||||
const {{PKG_CAMELCASE}} = require('{{PKG_NAME}}')
|
||||
```
|
||||
|
||||
Import your module as :
|
||||
or import (JavaScript ES module):
|
||||
|
||||
- Node.js
|
||||
```javascript
|
||||
import * as {{PKG_CAMELCASE}} from '{{PKG_NAME}}'
|
||||
```
|
||||
|
||||
```javascript
|
||||
const bigintCryptoUtils = require('bigint-crypto-utils')
|
||||
... // your code here
|
||||
```
|
||||
The appropriate version for browser or node is automatically exported.
|
||||
|
||||
- JavaScript native or TypeScript project (including React and Angular JS)
|
||||
`{{PKG_NAME}}` **CANNOT BE POLYFILLED** to suport older JS version (\< ES2020). If you are using webpack/babel to create your production bundles, you should target only the most modern browsers. For instance, for **React** apps created with [`create-react-app`](https://create-react-app.dev/), you should edit your `package.json` and modify the `browserList` so that it only targets the latest browsers (play with the number of versions that do not need polyfilling):
|
||||
|
||||
```javascript
|
||||
import * as bigintCryptoUtils from 'bigint-crypto-utils'
|
||||
... // your code here
|
||||
```
|
||||
|
||||
`{{PKG_NAME}}` **CANNOT BE POLYFILLED** to suport older browsers. If you are using webpack/babel to create your production bundles, you should target only the most modern browsers. For instance, for **React** apps created with [`create-react-app`](https://create-react-app.dev/), you should edit your `package.json` and modify the `browserList` so that it only targets the latest browsers (play with the number of versions that do not need polyfilling):
|
||||
|
||||
```json
|
||||
"browserslist": {
|
||||
```json
|
||||
"browserslist": {
|
||||
"production": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
|
@ -54,47 +48,25 @@ Import your module as :
|
|||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
}
|
||||
```
|
||||
}
|
||||
```
|
||||
|
||||
Also, notice that [BigInt implementation is ES2020](https://tc39.es/ecma262/#sec-bigint-objects). In order to use it with TypeScript you will probably need to set `lib`, `target` and/or `module` to `es2020` in your project's `tsconfig.json`.
|
||||
Also, notice that [BigInt implementation is ES2020](https://tc39.es/ecma262/#sec-bigint-objects). In order to use it with TypeScript you need to set `target` to `ES2020` in your project's `tsconfig.json`.
|
||||
|
||||
If you are using Angular, since this library uses node typings, you should also add them to the `angularCompilerOptions` in your `tsconfig.json`:
|
||||
If you are using Angular, since this library uses node typings, you should also add them to the `angularCompilerOptions` in your `tsconfig.json`:
|
||||
|
||||
```json
|
||||
```json
|
||||
"angularCompilerOptions": {
|
||||
"types": ["node"]
|
||||
"types": ["node", ...]
|
||||
...
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
- JavaScript native browser ES module
|
||||
|
||||
```html
|
||||
<script type="module">
|
||||
import * as bigintCryptoUtils from 'index.browser.bundle.mod.js' // Use your actual path to the broser mod bundle that is in the lib directory
|
||||
... // your code here
|
||||
</script>
|
||||
```
|
||||
|
||||
- JavaScript native browser IIFE
|
||||
|
||||
```html
|
||||
<head>
|
||||
...
|
||||
<script src="index.browser.bundle.iife.js"></script> <!-- Use your actual path to the browser iife bundle that is in the lib directory -->
|
||||
</head>
|
||||
<body>
|
||||
...
|
||||
<script>
|
||||
... // your code here
|
||||
</script>
|
||||
</body>
|
||||
```
|
||||
You can also download the {{IIFE_BUNDLE}}, the {{ESM_BUNDLE}} or the {{UMD_BUNDLE}} and manually add it to your project, or, if you have already imported `{{PKG_NAME}}` to your project, just get the bundles from `node_modules/{{PKG_NAME}}/dist/bundles/`.
|
||||
|
||||
An example of usage could be:
|
||||
|
||||
```javascript
|
||||
```typescript
|
||||
/* A BigInt with value 666 can be declared calling the bigint constructor as
|
||||
BigInt('666') or with the shorter 666n.
|
||||
Notice that you can also pass a number to the constructor, e.g. BigInt(666).
|
||||
|
@ -113,14 +85,14 @@ console.log(bigintCryptoUtils.modInv(BigInt('3'), BigInt('5'))) // prints 2
|
|||
|
||||
console.log(bigintCryptoUtils.randBetween(2n ** 256n)) // Prints a cryptographically secure random number between 1 and 2**256 bits.
|
||||
|
||||
async function primeTesting () {
|
||||
async function primeTesting (): void {
|
||||
// Output of a probable prime of 2048 bits
|
||||
console.log(await bigintCryptoUtils.prime(2048))
|
||||
|
||||
// Testing if a number is a probable prime (Miller-Rabin)
|
||||
const number = 27n
|
||||
const isPrime = await bigintCryptoUtils.isProbablyPrime(number)
|
||||
if (isPrime) {
|
||||
if (isPrime === true) {
|
||||
console.log(`${number} is prime`)
|
||||
} else {
|
||||
console.log(`${number} is composite`)
|
||||
|
@ -131,8 +103,6 @@ primeTesting()
|
|||
|
||||
```
|
||||
|
||||
You can find examples in the [examples folder of the repository](https://github.com/juanelas/bigint-crypto-utils/tree/master/examples).
|
||||
|
||||
## API reference documentation
|
||||
|
||||
{{>main}}
|
||||
[Check the API](./docs/API.md)
|
|
@ -0,0 +1,7 @@
|
|||
export { abs, bitLength, eGcd, gcd, lcm, max, min, modInv, modPow, toZn } from 'bigint-mod-arith'
|
||||
|
||||
export { isProbablyPrime } from './ts/isProbablyPrime'
|
||||
export { prime, primeSync } from './ts/prime'
|
||||
export { randBetween } from './ts/randBetween'
|
||||
export { randBits, randBitsSync } from './ts/randBits'
|
||||
export { randBytes, randBytesSync } from './ts/randBytes'
|
|
@ -1,214 +0,0 @@
|
|||
/**
|
||||
* Absolute value. abs(a)==a if a>=0. abs(a)==-a if a<0
|
||||
*
|
||||
* @param {number|bigint} a
|
||||
*
|
||||
* @returns {bigint} the absolute value of a
|
||||
*/
|
||||
export function abs (a) {
|
||||
a = BigInt(a)
|
||||
return (a >= 0n) ? a : -a
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bitlength of a number
|
||||
*
|
||||
* @param {number|bigint} a
|
||||
* @returns {number} - the bit length
|
||||
*/
|
||||
export function bitLength (a) {
|
||||
a = BigInt(a)
|
||||
if (a === 1n) { return 1 }
|
||||
let bits = 1
|
||||
do {
|
||||
bits++
|
||||
} while ((a >>= 1n) > 1n)
|
||||
return bits
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} egcdReturn A triple (g, x, y), such that ax + by = g = gcd(a, b).
|
||||
* @property {bigint} g
|
||||
* @property {bigint} x
|
||||
* @property {bigint} y
|
||||
*/
|
||||
/**
|
||||
* 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).
|
||||
*
|
||||
* @param {number|bigint} a
|
||||
* @param {number|bigint} b
|
||||
*
|
||||
* @throws {RangeError} a and b MUST be > 0
|
||||
*
|
||||
* @returns {egcdReturn} A triple (g, x, y), such that ax + by = g = gcd(a, b).
|
||||
*/
|
||||
export function eGcd (a, b) {
|
||||
a = BigInt(a)
|
||||
b = BigInt(b)
|
||||
if (a <= 0n | b <= 0n) throw new RangeError('a and b MUST be > 0') // a and b MUST be positive
|
||||
|
||||
let x = 0n
|
||||
let y = 1n
|
||||
let u = 1n
|
||||
let v = 0n
|
||||
|
||||
while (a !== 0n) {
|
||||
const q = b / a
|
||||
const r = b % a
|
||||
const m = x - (u * q)
|
||||
const n = y - (v * q)
|
||||
b = a
|
||||
a = r
|
||||
x = u
|
||||
y = v
|
||||
u = m
|
||||
v = n
|
||||
}
|
||||
return {
|
||||
g: b,
|
||||
x: x,
|
||||
y: y
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Greatest-common divisor of two integers based on the iterative binary algorithm.
|
||||
*
|
||||
* @param {number|bigint} a
|
||||
* @param {number|bigint} b
|
||||
*
|
||||
* @returns {bigint} The greatest common divisor of a and b
|
||||
*/
|
||||
export function gcd (a, b) {
|
||||
a = abs(a)
|
||||
b = abs(b)
|
||||
if (a === 0n) { return b } else if (b === 0n) { return a }
|
||||
|
||||
let shift = 0n
|
||||
while (!((a | b) & 1n)) {
|
||||
a >>= 1n
|
||||
b >>= 1n
|
||||
shift++
|
||||
}
|
||||
while (!(a & 1n)) a >>= 1n
|
||||
do {
|
||||
while (!(b & 1n)) b >>= 1n
|
||||
if (a > b) {
|
||||
const x = a
|
||||
a = b
|
||||
b = x
|
||||
}
|
||||
b -= a
|
||||
} while (b)
|
||||
|
||||
// rescale
|
||||
return a << shift
|
||||
}
|
||||
|
||||
/**
|
||||
* The least common multiple computed as abs(a*b)/gcd(a,b)
|
||||
* @param {number|bigint} a
|
||||
* @param {number|bigint} b
|
||||
*
|
||||
* @returns {bigint} The least common multiple of a and b
|
||||
*/
|
||||
export function lcm (a, b) {
|
||||
a = BigInt(a)
|
||||
b = BigInt(b)
|
||||
if (a === 0n && b === 0n) return BigInt(0)
|
||||
return abs(a * b) / gcd(a, b)
|
||||
}
|
||||
|
||||
/**
|
||||
* Maximum. max(a,b)==a if a>=b. max(a,b)==b if a<=b
|
||||
*
|
||||
* @param {number|bigint} a
|
||||
* @param {number|bigint} b
|
||||
*
|
||||
* @returns {bigint} maximum of numbers a and b
|
||||
*/
|
||||
export function max (a, b) {
|
||||
a = BigInt(a)
|
||||
b = BigInt(b)
|
||||
return (a >= b) ? a : b
|
||||
}
|
||||
|
||||
/**
|
||||
* Minimum. min(a,b)==b if a>=b. min(a,b)==a if a<=b
|
||||
*
|
||||
* @param {number|bigint} a
|
||||
* @param {number|bigint} b
|
||||
*
|
||||
* @returns {bigint} minimum of numbers a and b
|
||||
*/
|
||||
export function min (a, b) {
|
||||
a = BigInt(a)
|
||||
b = BigInt(b)
|
||||
return (a >= b) ? b : a
|
||||
}
|
||||
|
||||
/**
|
||||
* Modular inverse.
|
||||
*
|
||||
* @param {number|bigint} a The number to find an inverse for
|
||||
* @param {number|bigint} n The modulo
|
||||
*
|
||||
* @throws {RangeError} a does not have inverse modulo n
|
||||
*
|
||||
* @returns {bigint} the inverse modulo n
|
||||
*/
|
||||
export function modInv (a, n) {
|
||||
const egcd = eGcd(toZn(a, n), n)
|
||||
if (egcd.g !== 1n) {
|
||||
throw new RangeError(`${a.toString()} does not have inverse modulo ${n.toString()}`) // modular inverse does not exist
|
||||
} else {
|
||||
return toZn(egcd.x, n)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Modular exponentiation b**e mod n. Currently using the right-to-left binary method
|
||||
*
|
||||
* @param {number|bigint} b base
|
||||
* @param {number|bigint} e exponent
|
||||
* @param {number|bigint} n modulo
|
||||
*
|
||||
* @returns {bigint} b**e mod n
|
||||
*/
|
||||
export function modPow (b, e, n) {
|
||||
n = BigInt(n)
|
||||
if (n === 0n) { throw new RangeError('n must be > 0') } else if (n === 1n) { return BigInt(0) }
|
||||
|
||||
b = toZn(b, n)
|
||||
|
||||
e = BigInt(e)
|
||||
if (e < 0n) {
|
||||
return modInv(modPow(b, abs(e), n), n)
|
||||
}
|
||||
|
||||
let r = 1n
|
||||
while (e > 0) {
|
||||
if ((e % 2n) === 1n) {
|
||||
r = (r * b) % n
|
||||
}
|
||||
e = e / 2n
|
||||
b = b ** 2n % n
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the smallest positive element that is congruent to a in modulo n
|
||||
* @param {number|bigint} a An integer
|
||||
* @param {number|bigint} n The modulo
|
||||
*
|
||||
* @returns {bigint} The smallest positive representation of a in modulo n
|
||||
*/
|
||||
export function toZn (a, n) {
|
||||
n = BigInt(n)
|
||||
if (n <= 0) { return NaN }
|
||||
|
||||
a = BigInt(a) % n
|
||||
return (a < 0) ? a + n : a
|
||||
}
|
699
src/js/index.js
699
src/js/index.js
|
@ -1,699 +0,0 @@
|
|||
import { bitLength, eGcd, modInv, modPow, toZn } from './bigint-mod-arith'
|
||||
export { abs, bitLength, eGcd, gcd, lcm, max, min, modInv, modPow, toZn } from './bigint-mod-arith'
|
||||
|
||||
/**
|
||||
* 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)
|
||||
*
|
||||
* @param {number | bigint} w A positive integer to be tested for primality
|
||||
* @param {number} [iterations = 16] The number of iterations for the primality test. The value shall be consistent with Table C.1, C.2 or C.3
|
||||
* @param {boolean} [disableWorkers = false] Disable the use of workers for the primality test
|
||||
*
|
||||
* @throws {RangeError} w MUST be >= 0
|
||||
*
|
||||
* @returns {Promise<boolean>} A promise that resolves to a boolean that is either true (a probably prime number) or false (definitely composite)
|
||||
*/
|
||||
export function isProbablyPrime (w, iterations = 16, disableWorkers = false) {
|
||||
if (typeof w === 'number') {
|
||||
w = BigInt(w)
|
||||
}
|
||||
if (w < 0) throw RangeError('w MUST be >= 0')
|
||||
/* eslint-disable no-lone-blocks */
|
||||
if (!process.browser) { // Node.js
|
||||
/* istanbul ignore else */
|
||||
if (!disableWorkers && _useWorkers) {
|
||||
const { Worker } = require('worker_threads')
|
||||
return new Promise((resolve, reject) => {
|
||||
const worker = new Worker(__filename)
|
||||
|
||||
worker.on('message', (data) => {
|
||||
worker.terminate()
|
||||
resolve(data.isPrime)
|
||||
})
|
||||
|
||||
worker.on('error', reject)
|
||||
|
||||
worker.postMessage({
|
||||
rnd: w,
|
||||
iterations: iterations,
|
||||
id: 0
|
||||
})
|
||||
})
|
||||
} else {
|
||||
return new Promise((resolve) => {
|
||||
resolve(_isProbablyPrime(w, iterations))
|
||||
})
|
||||
}
|
||||
} else { // browser
|
||||
return new Promise((resolve, reject) => {
|
||||
const worker = new Worker(_isProbablyPrimeWorkerUrl())
|
||||
|
||||
worker.onmessage = (event) => {
|
||||
worker.terminate()
|
||||
resolve(event.data.isPrime)
|
||||
}
|
||||
|
||||
worker.onmessageerror = (event) => {
|
||||
reject(event)
|
||||
}
|
||||
|
||||
worker.postMessage({
|
||||
rnd: w,
|
||||
iterations: iterations,
|
||||
id: 0
|
||||
})
|
||||
})
|
||||
}
|
||||
/* eslint-enable no-lone-blocks */
|
||||
}
|
||||
|
||||
/**
|
||||
* 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).
|
||||
* The node version can also use worker_threads if they are available (enabled by default with Node 11 and
|
||||
* and can be enabled at runtime executing node --experimental-worker with node >=10.5.0).
|
||||
*
|
||||
* @param {number} bitLength The required bit length for the generated prime
|
||||
* @param {number} [iterations = 16] The number of iterations for the Miller-Rabin Probabilistic Primality Test
|
||||
*
|
||||
* @throws {RangeError} bitLength MUST be > 0
|
||||
*
|
||||
* @returns {Promise<bigint>} A promise that resolves to a bigint probable prime of bitLength bits.
|
||||
*/
|
||||
export function prime (bitLength, iterations = 16) {
|
||||
if (bitLength < 1) throw new RangeError('bitLength MUST be > 0')
|
||||
|
||||
/* istanbul ignore if */
|
||||
if (!_useWorkers) { // If there is no support for workers
|
||||
let rnd = 0n
|
||||
do {
|
||||
rnd = fromBuffer(randBitsSync(bitLength, true))
|
||||
} while (!_isProbablyPrime(rnd, iterations))
|
||||
return new Promise((resolve) => { resolve(rnd) })
|
||||
}
|
||||
return new Promise((resolve) => {
|
||||
const workerList = []
|
||||
const _onmessage = (msg, newWorker) => {
|
||||
if (msg.isPrime) {
|
||||
// if a prime number has been found, stop all the workers, and return it
|
||||
for (let j = 0; j < workerList.length; j++) {
|
||||
workerList[j].terminate()
|
||||
}
|
||||
while (workerList.length) {
|
||||
workerList.pop()
|
||||
}
|
||||
resolve(msg.value)
|
||||
} else { // if a composite is found, make the worker test another random number
|
||||
const buf = randBitsSync(bitLength, true)
|
||||
const rnd = fromBuffer(buf)
|
||||
try {
|
||||
newWorker.postMessage({
|
||||
rnd: rnd,
|
||||
iterations: iterations,
|
||||
id: msg.id
|
||||
})
|
||||
} catch (error) {
|
||||
// The worker has already terminated. There is nothing to handle here
|
||||
}
|
||||
}
|
||||
}
|
||||
/* eslint-disable no-lone-blocks */
|
||||
if (process.browser) { // browser
|
||||
const workerURL = _isProbablyPrimeWorkerUrl()
|
||||
for (let i = 0; i < self.navigator.hardwareConcurrency - 1; i++) {
|
||||
const newWorker = new Worker(workerURL)
|
||||
newWorker.onmessage = (event) => _onmessage(event.data, newWorker)
|
||||
workerList.push(newWorker)
|
||||
}
|
||||
} else { // Node.js
|
||||
const { cpus } = require('os')
|
||||
const { Worker } = require('worker_threads')
|
||||
for (let i = 0; i < cpus().length - 1; i++) {
|
||||
const newWorker = new Worker(__filename)
|
||||
newWorker.on('message', (msg) => _onmessage(msg, newWorker))
|
||||
workerList.push(newWorker)
|
||||
}
|
||||
}
|
||||
/* eslint-enable no-lone-blocks */
|
||||
for (let i = 0; i < workerList.length; i++) {
|
||||
randBits(bitLength, true).then(function (buf) {
|
||||
const rnd = fromBuffer(buf)
|
||||
workerList[i].postMessage({
|
||||
rnd: rnd,
|
||||
iterations: iterations,
|
||||
id: i
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator.
|
||||
* The sync version is NOT RECOMMENDED since it won't use workers and thus it'll be slower and may freeze thw window in browser's javascript. Please consider using prime() instead.
|
||||
*
|
||||
* @param {number} bitLength The required bit length for the generated prime
|
||||
* @param {number} [iterations = 16] The number of iterations for the Miller-Rabin Probabilistic Primality Test
|
||||
*
|
||||
* @throws {RangeError} bitLength MUST be > 0
|
||||
*
|
||||
* @returns {bigint} A bigint probable prime of bitLength bits.
|
||||
*/
|
||||
export function primeSync (bitLength, iterations = 16) {
|
||||
if (bitLength < 1) throw new RangeError('bitLength MUST be > 0')
|
||||
let rnd = 0n
|
||||
do {
|
||||
rnd = fromBuffer(randBitsSync(bitLength, true))
|
||||
} while (!_isProbablyPrime(rnd, iterations))
|
||||
return rnd
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a cryptographically secure random integer between [min,max]. Both numbers must be >=0
|
||||
* @param {bigint} max Returned value will be <= max
|
||||
* @param {bigint} [min = BigInt(1)] Returned value will be >= min
|
||||
*
|
||||
* @throws {RangeError} Arguments MUST be: max > 0 && min >=0 && max > min
|
||||
*
|
||||
* @returns {bigint} A cryptographically secure random bigint between [min,max]
|
||||
*/
|
||||
export function randBetween (max, min = 1n) {
|
||||
if (max <= 0n || min < 0n || max <= min) throw new RangeError('Arguments MUST be: max > 0 && min >=0 && max > min')
|
||||
const interval = max - min
|
||||
const bitLen = bitLength(interval)
|
||||
let rnd
|
||||
do {
|
||||
const buf = randBitsSync(bitLen)
|
||||
rnd = fromBuffer(buf)
|
||||
} while (rnd > interval)
|
||||
return rnd + min
|
||||
}
|
||||
|
||||
/**
|
||||
* Secure random bits for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()
|
||||
*
|
||||
* @param {number} bitLength The desired number of random bits
|
||||
* @param {boolean} [forceLength = false] If we want to force the output to have a specific bit length. It basically forces the msb to be 1
|
||||
*
|
||||
* @throws {RangeError} bitLength MUST be > 0
|
||||
*
|
||||
* @returns {Promise<Buffer | Uint8Array>} A Promise that resolves to a Buffer/UInt8Array (Node.js/Browser) filled with cryptographically secure random bits
|
||||
*/
|
||||
export function randBits (bitLength, forceLength = false) {
|
||||
if (bitLength < 1) throw new RangeError('bitLength MUST be > 0')
|
||||
|
||||
const byteLength = Math.ceil(bitLength / 8)
|
||||
const bitLengthMod8 = bitLength % 8
|
||||
|
||||
return new Promise((resolve) => {
|
||||
randBytes(byteLength, false).then(function (rndBytes) {
|
||||
if (bitLengthMod8) {
|
||||
// Fill with 0's the extra bits
|
||||
rndBytes[0] = rndBytes[0] & (2 ** bitLengthMod8 - 1)
|
||||
}
|
||||
if (forceLength) {
|
||||
const mask = bitLengthMod8 ? 2 ** (bitLengthMod8 - 1) : 128
|
||||
rndBytes[0] = rndBytes[0] | mask
|
||||
}
|
||||
resolve(rndBytes)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Secure random bits for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()
|
||||
* @param {number} bitLength The desired number of random bits
|
||||
* @param {boolean} [forceLength = false] If we want to force the output to have a specific bit length. It basically forces the msb to be 1
|
||||
*
|
||||
* @throws {RangeError} bitLength MUST be > 0
|
||||
*
|
||||
* @returns {Buffer | Uint8Array} A Buffer/UInt8Array (Node.js/Browser) filled with cryptographically secure random bits
|
||||
*/
|
||||
export function randBitsSync (bitLength, forceLength = false) {
|
||||
if (bitLength < 1) throw new RangeError('bitLength MUST be > 0')
|
||||
|
||||
const byteLength = Math.ceil(bitLength / 8)
|
||||
const rndBytes = randBytesSync(byteLength, false)
|
||||
const bitLengthMod8 = bitLength % 8
|
||||
if (bitLengthMod8) {
|
||||
// Fill with 0's the extra bits
|
||||
rndBytes[0] = rndBytes[0] & (2 ** bitLengthMod8 - 1)
|
||||
}
|
||||
if (forceLength) {
|
||||
const mask = bitLengthMod8 ? 2 ** (bitLengthMod8 - 1) : 128
|
||||
rndBytes[0] = rndBytes[0] | mask
|
||||
}
|
||||
return rndBytes
|
||||
}
|
||||
|
||||
/**
|
||||
* Secure random bytes for both node and browsers. Node version uses crypto.randomBytes() and browser one self.crypto.getRandomValues()
|
||||
*
|
||||
* @param {number} byteLength The desired number of random bytes
|
||||
* @param {boolean} [forceLength = false] If we want to force the output to have a bit length of 8*byteLength. It basically forces the msb to be 1
|
||||
*
|
||||
* @throws {RangeError} byteLength MUST be > 0
|
||||
*
|
||||
* @returns {Promise<Buffer | Uint8Array>} A promise that resolves to a Buffer/UInt8Array (Node.js/Browser) filled with cryptographically secure random bytes
|
||||
*/
|
||||
export function randBytes (byteLength, forceLength = false) {
|
||||
if (byteLength < 1) throw new RangeError('byteLength MUST be > 0')
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
/* eslint-disable no-lone-blocks */
|
||||
if (!process.browser) {
|
||||
const crypto = require('crypto')
|
||||
crypto.randomBytes(byteLength, function (err, buf) {
|
||||
/* istanbul ignore if */
|
||||
if (err) reject(err)
|
||||
// If fixed length is required we put the first bit to 1 -> to get the necessary bitLength
|
||||
if (forceLength) buf[0] = buf[0] | 128
|
||||
resolve(buf)
|
||||
})
|
||||
} else { // browser
|
||||
const buf = new Uint8Array(byteLength)
|
||||
self.crypto.getRandomValues(buf)
|
||||
// If fixed length is required we put the first bit to 1 -> to get the necessary bitLength
|
||||
if (forceLength) buf[0] = buf[0] | 128
|
||||
resolve(buf)
|
||||
}
|
||||
/* eslint-enable no-lone-blocks */
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Secure random bytes for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()
|
||||
*
|
||||
* @param {number} byteLength The desired number of random bytes
|
||||
* @param {boolean} [forceLength = false] If we want to force the output to have a bit length of 8*byteLength. It basically forces the msb to be 1
|
||||
*
|
||||
* @throws {RangeError} byteLength MUST be > 0
|
||||
*
|
||||
* @returns {Buffer | Uint8Array} A Buffer/UInt8Array (Node.js/Browser) filled with cryptographically secure random bytes
|
||||
*/
|
||||
export function randBytesSync (byteLength, forceLength = false) {
|
||||
if (byteLength < 1) throw new RangeError('byteLength MUST be > 0')
|
||||
|
||||
/* eslint-disable no-lone-blocks */
|
||||
if (!process.browser) { // node
|
||||
const crypto = require('crypto')
|
||||
const buf = crypto.randomBytes(byteLength)
|
||||
// If fixed length is required we put the first bit to 1 -> to get the necessary bitLength
|
||||
if (forceLength) buf[0] = buf[0] | 128
|
||||
return buf
|
||||
} else { // browser
|
||||
const buf = new Uint8Array(byteLength)
|
||||
self.crypto.getRandomValues(buf)
|
||||
// If fixed length is required we put the first bit to 1 -> to get the necessary bitLength
|
||||
if (forceLength) buf[0] = buf[0] | 128
|
||||
return buf
|
||||
}
|
||||
/* eslint-enable no-lone-blocks */
|
||||
}
|
||||
|
||||
/* HELPER FUNCTIONS */
|
||||
|
||||
function fromBuffer (buf) {
|
||||
let ret = 0n
|
||||
for (const i of buf.values()) {
|
||||
const bi = BigInt(i)
|
||||
ret = (ret << BigInt(8)) + bi
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
function _isProbablyPrimeWorkerUrl () {
|
||||
// Let's us first add all the required functions
|
||||
let workerCode = `'use strict';const ${eGcd.name}=${eGcd.toString()};const ${modInv.name}=${modInv.toString()};const ${modPow.name}=${modPow.toString()};const ${toZn.name}=${toZn.toString()};const ${randBitsSync.name}=${randBitsSync.toString()};const ${randBytesSync.name}=${randBytesSync.toString()};const ${randBetween.name}=${randBetween.toString()};const ${isProbablyPrime.name}=${_isProbablyPrime.toString()};${bitLength.toString()}${fromBuffer.toString()}`
|
||||
|
||||
const onmessage = async function (event) { // Let's start once we are called
|
||||
// event.data = {rnd: <bigint>, iterations: <number>}
|
||||
const isPrime = await isProbablyPrime(event.data.rnd, event.data.iterations)
|
||||
postMessage({
|
||||
isPrime: isPrime,
|
||||
value: event.data.rnd,
|
||||
id: event.data.id
|
||||
})
|
||||
}
|
||||
|
||||
workerCode += `onmessage = ${onmessage.toString()};`
|
||||
|
||||
return _workerUrl(workerCode)
|
||||
}
|
||||
|
||||
function _workerUrl (workerCode) {
|
||||
workerCode = `(() => {${workerCode}})()` // encapsulate IIFE
|
||||
const _blob = new Blob([workerCode], { type: 'text/javascript' })
|
||||
return window.URL.createObjectURL(_blob)
|
||||
}
|
||||
|
||||
function _isProbablyPrime (w, iterations = 16) {
|
||||
/*
|
||||
PREFILTERING. Even values but 2 are not primes, so don't test.
|
||||
1 is not a prime and the M-R algorithm needs w>1.
|
||||
*/
|
||||
if (w === 2n) return true
|
||||
else if ((w & 1n) === 0n || w === 1n) return false
|
||||
|
||||
/*
|
||||
Test if any of the first 250 small primes are a factor of w. 2 is not tested because it was already tested above.
|
||||
*/
|
||||
const firstPrimes = [
|
||||
3n,
|
||||
5n,
|
||||
7n,
|
||||
11n,
|
||||
13n,
|
||||
17n,
|
||||
19n,
|
||||
23n,
|
||||
29n,
|
||||
31n,
|
||||
37n,
|
||||
41n,
|
||||
43n,
|
||||
47n,
|
||||
53n,
|
||||
59n,
|
||||
61n,
|
||||
67n,
|
||||
71n,
|
||||
73n,
|
||||
79n,
|
||||
83n,
|
||||
89n,
|
||||
97n,
|
||||
101n,
|
||||
103n,
|
||||
107n,
|
||||
109n,
|
||||
113n,
|
||||
127n,
|
||||
131n,
|
||||
137n,
|
||||
139n,
|
||||
149n,
|
||||
151n,
|
||||
157n,
|
||||
163n,
|
||||
167n,
|
||||
173n,
|
||||
179n,
|
||||
181n,
|
||||
191n,
|
||||
193n,
|
||||
197n,
|
||||
199n,
|
||||
211n,
|
||||
223n,
|
||||
227n,
|
||||
229n,
|
||||
233n,
|
||||
239n,
|
||||
241n,
|
||||
251n,
|
||||
257n,
|
||||
263n,
|
||||
269n,
|
||||
271n,
|
||||
277n,
|
||||
281n,
|
||||
283n,
|
||||
293n,
|
||||
307n,
|
||||
311n,
|
||||
313n,
|
||||
317n,
|
||||
331n,
|
||||
337n,
|
||||
347n,
|
||||
349n,
|
||||
353n,
|
||||
359n,
|
||||
367n,
|
||||
373n,
|
||||
379n,
|
||||
383n,
|
||||
389n,
|
||||
397n,
|
||||
401n,
|
||||
409n,
|
||||
419n,
|
||||
421n,
|
||||
431n,
|
||||
433n,
|
||||
439n,
|
||||
443n,
|
||||
449n,
|
||||
457n,
|
||||
461n,
|
||||
463n,
|
||||
467n,
|
||||
479n,
|
||||
487n,
|
||||
491n,
|
||||
499n,
|
||||
503n,
|
||||
509n,
|
||||
521n,
|
||||
523n,
|
||||
541n,
|
||||
547n,
|
||||
557n,
|
||||
563n,
|
||||
569n,
|
||||
571n,
|
||||
577n,
|
||||
587n,
|
||||
593n,
|
||||
599n,
|
||||
601n,
|
||||
607n,
|
||||
613n,
|
||||
617n,
|
||||
619n,
|
||||
631n,
|
||||
641n,
|
||||
643n,
|
||||
647n,
|
||||
653n,
|
||||
659n,
|
||||
661n,
|
||||
673n,
|
||||
677n,
|
||||
683n,
|
||||
691n,
|
||||
701n,
|
||||
709n,
|
||||
719n,
|
||||
727n,
|
||||
733n,
|
||||
739n,
|
||||
743n,
|
||||
751n,
|
||||
757n,
|
||||
761n,
|
||||
769n,
|
||||
773n,
|
||||
787n,
|
||||
797n,
|
||||
809n,
|
||||
811n,
|
||||
821n,
|
||||
823n,
|
||||
827n,
|
||||
829n,
|
||||
839n,
|
||||
853n,
|
||||
857n,
|
||||
859n,
|
||||
863n,
|
||||
877n,
|
||||
881n,
|
||||
883n,
|
||||
887n,
|
||||
907n,
|
||||
911n,
|
||||
919n,
|
||||
929n,
|
||||
937n,
|
||||
941n,
|
||||
947n,
|
||||
953n,
|
||||
967n,
|
||||
971n,
|
||||
977n,
|
||||
983n,
|
||||
991n,
|
||||
997n,
|
||||
1009n,
|
||||
1013n,
|
||||
1019n,
|
||||
1021n,
|
||||
1031n,
|
||||
1033n,
|
||||
1039n,
|
||||
1049n,
|
||||
1051n,
|
||||
1061n,
|
||||
1063n,
|
||||
1069n,
|
||||
1087n,
|
||||
1091n,
|
||||
1093n,
|
||||
1097n,
|
||||
1103n,
|
||||
1109n,
|
||||
1117n,
|
||||
1123n,
|
||||
1129n,
|
||||
1151n,
|
||||
1153n,
|
||||
1163n,
|
||||
1171n,
|
||||
1181n,
|
||||
1187n,
|
||||
1193n,
|
||||
1201n,
|
||||
1213n,
|
||||
1217n,
|
||||
1223n,
|
||||
1229n,
|
||||
1231n,
|
||||
1237n,
|
||||
1249n,
|
||||
1259n,
|
||||
1277n,
|
||||
1279n,
|
||||
1283n,
|
||||
1289n,
|
||||
1291n,
|
||||
1297n,
|
||||
1301n,
|
||||
1303n,
|
||||
1307n,
|
||||
1319n,
|
||||
1321n,
|
||||
1327n,
|
||||
1361n,
|
||||
1367n,
|
||||
1373n,
|
||||
1381n,
|
||||
1399n,
|
||||
1409n,
|
||||
1423n,
|
||||
1427n,
|
||||
1429n,
|
||||
1433n,
|
||||
1439n,
|
||||
1447n,
|
||||
1451n,
|
||||
1453n,
|
||||
1459n,
|
||||
1471n,
|
||||
1481n,
|
||||
1483n,
|
||||
1487n,
|
||||
1489n,
|
||||
1493n,
|
||||
1499n,
|
||||
1511n,
|
||||
1523n,
|
||||
1531n,
|
||||
1543n,
|
||||
1549n,
|
||||
1553n,
|
||||
1559n,
|
||||
1567n,
|
||||
1571n,
|
||||
1579n,
|
||||
1583n,
|
||||
1597n
|
||||
]
|
||||
|
||||
for (let i = 0; i < firstPrimes.length && (firstPrimes[i] <= w); i++) {
|
||||
const p = firstPrimes[i]
|
||||
if (w === p) return true
|
||||
else if (w % p === 0n) return false
|
||||
}
|
||||
|
||||
/*
|
||||
1. Let a be the largest integer such that 2**a divides w−1.
|
||||
2. m = (w−1) / 2**a.
|
||||
3. wlen = len (w).
|
||||
4. For i = 1 to iterations do
|
||||
4.1 Obtain a string b of wlen bits from an RBG.
|
||||
Comment: Ensure that 1 < b < w−1.
|
||||
4.2 If ((b ≤ 1) or (b ≥ w−1)), then go to step 4.1.
|
||||
4.3 z = b**m mod w.
|
||||
4.4 If ((z = 1) or (z = w − 1)), then go to step 4.7.
|
||||
4.5 For j = 1 to a − 1 do.
|
||||
4.5.1 z = z**2 mod w.
|
||||
4.5.2 If (z = w−1), then go to step 4.7.
|
||||
4.5.3 If (z = 1), then go to step 4.6.
|
||||
4.6 Return COMPOSITE.
|
||||
4.7 Continue.
|
||||
Comment: Increment i for the do-loop in step 4.
|
||||
5. Return PROBABLY PRIME.
|
||||
*/
|
||||
let a = 0n
|
||||
const d = w - 1n
|
||||
let aux = d
|
||||
while (aux % 2n === 0n) {
|
||||
aux /= 2n
|
||||
++a
|
||||
}
|
||||
|
||||
const m = d / (2n ** a)
|
||||
|
||||
do {
|
||||
const b = randBetween(d, 2n)
|
||||
let z = modPow(b, m, w)
|
||||
if (z === 1n || z === d) continue
|
||||
let j = 1
|
||||
while (j < a) {
|
||||
z = modPow(z, 2n, w)
|
||||
if (z === d) break
|
||||
if (z === 1n) return false
|
||||
j++
|
||||
}
|
||||
if (z !== d) return false
|
||||
} while (--iterations)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
let _useWorkers = false // The following is just to check whether we can use workers
|
||||
/* eslint-disable no-lone-blocks */
|
||||
if (!process.browser) { // Node.js
|
||||
try {
|
||||
require.resolve('worker_threads')
|
||||
_useWorkers = true
|
||||
} catch (e) {
|
||||
/* istanbul ignore next */
|
||||
console.log(`[bigint-crypto-utils] WARNING:
|
||||
This node version doesn't support worker_threads. You should enable them in order to greatly speedup the generation of big prime numbers.
|
||||
· With Node >=11 it is enabled by default (consider upgrading).
|
||||
· With Node 10, starting with 10.5.0, you can enable worker_threads at runtime executing node --experimental-worker `)
|
||||
}
|
||||
} else { // Native JS
|
||||
if (self.Worker) _useWorkers = true
|
||||
}
|
||||
/* eslint-enable no-lone-blocks */
|
||||
|
||||
if (!process.browser && _useWorkers) { // node.js with support for workers
|
||||
const { parentPort, isMainThread } = require('worker_threads')
|
||||
/* istanbul ignore if */
|
||||
if (!isMainThread) { // worker
|
||||
parentPort.on('message', function (data) { // Let's start once we are called
|
||||
// data = {rnd: <bigint>, iterations: <number>}
|
||||
const isPrime = _isProbablyPrime(data.rnd, data.iterations)
|
||||
parentPort.postMessage({
|
||||
isPrime: isPrime,
|
||||
value: data.rnd,
|
||||
id: data.id
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
export function fromBuffer (buf: Uint8Array|Buffer): bigint {
|
||||
let ret = 0n
|
||||
for (const i of buf.values()) {
|
||||
const bi = BigInt(i)
|
||||
ret = (ret << BigInt(8)) + bi
|
||||
}
|
||||
return ret
|
||||
}
|
|
@ -0,0 +1,427 @@
|
|||
import { eGcd, modInv, modPow, toZn, bitLength } from 'bigint-mod-arith'
|
||||
import { fromBuffer } from './fromBuffer'
|
||||
import { randBetween } from './randBetween'
|
||||
import { randBitsSync } from './randBits'
|
||||
import { randBytesSync } from './randBytes'
|
||||
import { _useWorkers, _workerUrl, WorkerToMainMsg, MainToWorkerMsg } from './workerUtils'
|
||||
|
||||
/**
|
||||
* 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)
|
||||
*
|
||||
* @param w - A positive integer to be tested for primality
|
||||
* @param iterations - The number of iterations for the primality test. The value shall be consistent with Table C.1, C.2 or C.3
|
||||
* @param disableWorkers - Disable the use of workers for the primality test
|
||||
*
|
||||
* @throws {RangeError}
|
||||
* w MUST be >= 0
|
||||
*
|
||||
* @returns A promise that resolves to a boolean that is either true (a probably prime number) or false (definitely composite)
|
||||
*/
|
||||
export function isProbablyPrime (w: number|bigint, iterations: number = 16, disableWorkers: boolean = false): Promise<boolean> { // eslint-disable-line
|
||||
if (typeof w === 'number') {
|
||||
w = BigInt(w)
|
||||
}
|
||||
if (w < 0n) throw RangeError('w MUST be >= 0')
|
||||
|
||||
if (!IS_BROWSER) { // Node.js
|
||||
/* istanbul ignore else */
|
||||
if (!disableWorkers && _useWorkers) {
|
||||
const { Worker } = require('worker_threads') // eslint-disable-line
|
||||
return new Promise((resolve, reject) => {
|
||||
const worker = new Worker(__filename)
|
||||
|
||||
worker.on('message', (data: WorkerToMainMsg) => {
|
||||
worker.terminate()
|
||||
resolve(data.isPrime)
|
||||
})
|
||||
|
||||
worker.on('error', reject)
|
||||
|
||||
const msg: MainToWorkerMsg = {
|
||||
rnd: w as bigint,
|
||||
iterations: iterations,
|
||||
id: 0
|
||||
}
|
||||
worker.postMessage(msg)
|
||||
})
|
||||
} else {
|
||||
return new Promise((resolve) => {
|
||||
resolve(_isProbablyPrime(w as bigint, iterations))
|
||||
})
|
||||
}
|
||||
} else { // browser
|
||||
return new Promise((resolve, reject) => {
|
||||
const worker = new Worker(_isProbablyPrimeWorkerUrl())
|
||||
|
||||
worker.onmessage = (event) => {
|
||||
worker.terminate()
|
||||
resolve(event.data.isPrime)
|
||||
}
|
||||
|
||||
worker.onmessageerror = (event) => {
|
||||
reject(event)
|
||||
}
|
||||
|
||||
const msg: MainToWorkerMsg = {
|
||||
rnd: w as bigint,
|
||||
iterations: iterations,
|
||||
id: 0
|
||||
}
|
||||
worker.postMessage(msg)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export function _isProbablyPrime (w: bigint, iterations: number = 16): boolean {
|
||||
/*
|
||||
PREFILTERING. Even values but 2 are not primes, so don't test.
|
||||
1 is not a prime and the M-R algorithm needs w>1.
|
||||
*/
|
||||
if (w === 2n) return true
|
||||
else if ((w & 1n) === 0n || w === 1n) return false
|
||||
|
||||
/*
|
||||
Test if any of the first 250 small primes are a factor of w. 2 is not tested because it was already tested above.
|
||||
*/
|
||||
const firstPrimes = [
|
||||
3n,
|
||||
5n,
|
||||
7n,
|
||||
11n,
|
||||
13n,
|
||||
17n,
|
||||
19n,
|
||||
23n,
|
||||
29n,
|
||||
31n,
|
||||
37n,
|
||||
41n,
|
||||
43n,
|
||||
47n,
|
||||
53n,
|
||||
59n,
|
||||
61n,
|
||||
67n,
|
||||
71n,
|
||||
73n,
|
||||
79n,
|
||||
83n,
|
||||
89n,
|
||||
97n,
|
||||
101n,
|
||||
103n,
|
||||
107n,
|
||||
109n,
|
||||
113n,
|
||||
127n,
|
||||
131n,
|
||||
137n,
|
||||
139n,
|
||||
149n,
|
||||
151n,
|
||||
157n,
|
||||
163n,
|
||||
167n,
|
||||
173n,
|
||||
179n,
|
||||
181n,
|
||||
191n,
|
||||
193n,
|
||||
197n,
|
||||
199n,
|
||||
211n,
|
||||
223n,
|
||||
227n,
|
||||
229n,
|
||||
233n,
|
||||
239n,
|
||||
241n,
|
||||
251n,
|
||||
257n,
|
||||
263n,
|
||||
269n,
|
||||
271n,
|
||||
277n,
|
||||
281n,
|
||||
283n,
|
||||
293n,
|
||||
307n,
|
||||
311n,
|
||||
313n,
|
||||
317n,
|
||||
331n,
|
||||
337n,
|
||||
347n,
|
||||
349n,
|
||||
353n,
|
||||
359n,
|
||||
367n,
|
||||
373n,
|
||||
379n,
|
||||
383n,
|
||||
389n,
|
||||
397n,
|
||||
401n,
|
||||
409n,
|
||||
419n,
|
||||
421n,
|
||||
431n,
|
||||
433n,
|
||||
439n,
|
||||
443n,
|
||||
449n,
|
||||
457n,
|
||||
461n,
|
||||
463n,
|
||||
467n,
|
||||
479n,
|
||||
487n,
|
||||
491n,
|
||||
499n,
|
||||
503n,
|
||||
509n,
|
||||
521n,
|
||||
523n,
|
||||
541n,
|
||||
547n,
|
||||
557n,
|
||||
563n,
|
||||
569n,
|
||||
571n,
|
||||
577n,
|
||||
587n,
|
||||
593n,
|
||||
599n,
|
||||
601n,
|
||||
607n,
|
||||
613n,
|
||||
617n,
|
||||
619n,
|
||||
631n,
|
||||
641n,
|
||||
643n,
|
||||
647n,
|
||||
653n,
|
||||
659n,
|
||||
661n,
|
||||
673n,
|
||||
677n,
|
||||
683n,
|
||||
691n,
|
||||
701n,
|
||||
709n,
|
||||
719n,
|
||||
727n,
|
||||
733n,
|
||||
739n,
|
||||
743n,
|
||||
751n,
|
||||
757n,
|
||||
761n,
|
||||
769n,
|
||||
773n,
|
||||
787n,
|
||||
797n,
|
||||
809n,
|
||||
811n,
|
||||
821n,
|
||||
823n,
|
||||
827n,
|
||||
829n,
|
||||
839n,
|
||||
853n,
|
||||
857n,
|
||||
859n,
|
||||
863n,
|
||||
877n,
|
||||
881n,
|
||||
883n,
|
||||
887n,
|
||||
907n,
|
||||
911n,
|
||||
919n,
|
||||
929n,
|
||||
937n,
|
||||
941n,
|
||||
947n,
|
||||
953n,
|
||||
967n,
|
||||
971n,
|
||||
977n,
|
||||
983n,
|
||||
991n,
|
||||
997n,
|
||||
1009n,
|
||||
1013n,
|
||||
1019n,
|
||||
1021n,
|
||||
1031n,
|
||||
1033n,
|
||||
1039n,
|
||||
1049n,
|
||||
1051n,
|
||||
1061n,
|
||||
1063n,
|
||||
1069n,
|
||||
1087n,
|
||||
1091n,
|
||||
1093n,
|
||||
1097n,
|
||||
1103n,
|
||||
1109n,
|
||||
1117n,
|
||||
1123n,
|
||||
1129n,
|
||||
1151n,
|
||||
1153n,
|
||||
1163n,
|
||||
1171n,
|
||||
1181n,
|
||||
1187n,
|
||||
1193n,
|
||||
1201n,
|
||||
1213n,
|
||||
1217n,
|
||||
1223n,
|
||||
1229n,
|
||||
1231n,
|
||||
1237n,
|
||||
1249n,
|
||||
1259n,
|
||||
1277n,
|
||||
1279n,
|
||||
1283n,
|
||||
1289n,
|
||||
1291n,
|
||||
1297n,
|
||||
1301n,
|
||||
1303n,
|
||||
1307n,
|
||||
1319n,
|
||||
1321n,
|
||||
1327n,
|
||||
1361n,
|
||||
1367n,
|
||||
1373n,
|
||||
1381n,
|
||||
1399n,
|
||||
1409n,
|
||||
1423n,
|
||||
1427n,
|
||||
1429n,
|
||||
1433n,
|
||||
1439n,
|
||||
1447n,
|
||||
1451n,
|
||||
1453n,
|
||||
1459n,
|
||||
1471n,
|
||||
1481n,
|
||||
1483n,
|
||||
1487n,
|
||||
1489n,
|
||||
1493n,
|
||||
1499n,
|
||||
1511n,
|
||||
1523n,
|
||||
1531n,
|
||||
1543n,
|
||||
1549n,
|
||||
1553n,
|
||||
1559n,
|
||||
1567n,
|
||||
1571n,
|
||||
1579n,
|
||||
1583n,
|
||||
1597n
|
||||
]
|
||||
|
||||
for (let i = 0; i < firstPrimes.length && (firstPrimes[i] <= w); i++) {
|
||||
const p = firstPrimes[i]
|
||||
if (w === p) return true
|
||||
else if (w % p === 0n) return false
|
||||
}
|
||||
|
||||
/*
|
||||
1. Let a be the largest integer such that 2**a divides w−1.
|
||||
2. m = (w−1) / 2**a.
|
||||
3. wlen = len (w).
|
||||
4. For i = 1 to iterations do
|
||||
4.1 Obtain a string b of wlen bits from an RBG.
|
||||
Comment: Ensure that 1 < b < w−1.
|
||||
4.2 If ((b ≤ 1) or (b ≥ w−1)), then go to step 4.1.
|
||||
4.3 z = b**m mod w.
|
||||
4.4 If ((z = 1) or (z = w − 1)), then go to step 4.7.
|
||||
4.5 For j = 1 to a − 1 do.
|
||||
4.5.1 z = z**2 mod w.
|
||||
4.5.2 If (z = w−1), then go to step 4.7.
|
||||
4.5.3 If (z = 1), then go to step 4.6.
|
||||
4.6 Return COMPOSITE.
|
||||
4.7 Continue.
|
||||
Comment: Increment i for the do-loop in step 4.
|
||||
5. Return PROBABLY PRIME.
|
||||
*/
|
||||
let a = 0n
|
||||
const d = w - 1n
|
||||
let aux = d
|
||||
while (aux % 2n === 0n) {
|
||||
aux /= 2n
|
||||
++a
|
||||
}
|
||||
|
||||
const m = d / (2n ** a)
|
||||
|
||||
do {
|
||||
const b = randBetween(d, 2n)
|
||||
let z = modPow(b, m, w)
|
||||
if (z === 1n || z === d) continue
|
||||
let j = 1
|
||||
while (j < a) {
|
||||
z = modPow(z, 2n, w)
|
||||
if (z === d) break
|
||||
if (z === 1n) return false
|
||||
j++
|
||||
}
|
||||
if (z !== d) return false
|
||||
} while (--iterations !== 0)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
export function _isProbablyPrimeWorkerUrl (): string {
|
||||
// Let's us first add all the required functions
|
||||
let workerCode = `'use strict';const ${eGcd.name}=${eGcd.toString()};const ${modInv.name}=${modInv.toString()};const ${modPow.name}=${modPow.toString()};const ${toZn.name}=${toZn.toString()};const ${randBitsSync.name}=${randBitsSync.toString()};const ${randBytesSync.name}=${randBytesSync.toString()};const ${randBetween.name}=${randBetween.toString()};const ${isProbablyPrime.name}=${_isProbablyPrime.toString()};${bitLength.toString()};${fromBuffer.toString()};`
|
||||
|
||||
const onmessage = async function (event: {data: MainToWorkerMsg}): Promise<void> { // Let's start once we are called
|
||||
// event.data = {rnd: <bigint>, iterations: <number>}
|
||||
const isPrime = await isProbablyPrime(event.data.rnd, event.data.iterations)
|
||||
const msg: WorkerToMainMsg = {
|
||||
isPrime: isPrime,
|
||||
value: event.data.rnd,
|
||||
id: event.data.id
|
||||
}
|
||||
postMessage(msg)
|
||||
}
|
||||
|
||||
workerCode += `onmessage = ${onmessage.toString()};`
|
||||
|
||||
return _workerUrl(workerCode)
|
||||
}
|
||||
|
||||
if (!IS_BROWSER && _useWorkers) { // node.js with support for workers
|
||||
const { parentPort, isMainThread } = require('worker_threads') // eslint-disable-line
|
||||
const isWorker = !(isMainThread as boolean)
|
||||
/* istanbul ignore if */
|
||||
if (isWorker) { // worker
|
||||
parentPort.on('message', function (data: MainToWorkerMsg) { // Let's start once we are called
|
||||
const isPrime = _isProbablyPrime(data.rnd, data.iterations)
|
||||
const msg: WorkerToMainMsg = {
|
||||
isPrime: isPrime,
|
||||
value: data.rnd,
|
||||
id: data.id
|
||||
}
|
||||
parentPort.postMessage(msg)
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
import { fromBuffer } from './fromBuffer'
|
||||
import { _isProbablyPrime, _isProbablyPrimeWorkerUrl } from './isProbablyPrime'
|
||||
import { randBits, randBitsSync } from './randBits'
|
||||
import { _useWorkers, WorkerToMainMsg, MainToWorkerMsg } from './workerUtils'
|
||||
|
||||
/**
|
||||
* 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).
|
||||
* The node version can also use worker_threads if they are available (enabled by default with Node 11 and
|
||||
* and can be enabled at runtime executing node --experimental-worker with node >=10.5.0).
|
||||
*
|
||||
* @param bitLength - The required bit length for the generated prime
|
||||
* @param iterations - The number of iterations for the Miller-Rabin Probabilistic Primality Test
|
||||
*
|
||||
* @throws {RangeError}
|
||||
* bitLength MUST be > 0
|
||||
*
|
||||
* @returns A promise that resolves to a bigint probable prime of bitLength bits.
|
||||
*/
|
||||
export function prime (bitLength: number, iterations: number = 16): Promise<bigint> { // eslint-disable-line
|
||||
if (bitLength < 1) throw new RangeError('bitLength MUST be > 0')
|
||||
|
||||
/* istanbul ignore if */
|
||||
if (!_useWorkers) { // If there is no support for workers
|
||||
let rnd = 0n
|
||||
do {
|
||||
rnd = fromBuffer(randBitsSync(bitLength, true))
|
||||
} while (!_isProbablyPrime(rnd, iterations))
|
||||
return new Promise((resolve) => { resolve(rnd) })
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
const workerList: Worker[] = []
|
||||
const _onmessage = (msg: WorkerToMainMsg, newWorker: Worker): void => {
|
||||
if (msg.isPrime) {
|
||||
// if a prime number has been found, stop all the workers, and return it
|
||||
for (let j = 0; j < workerList.length; j++) {
|
||||
workerList[j].terminate()
|
||||
}
|
||||
while (workerList.length > 0) {
|
||||
workerList.pop()
|
||||
}
|
||||
resolve(msg.value)
|
||||
} else { // if a composite is found, make the worker test another random number
|
||||
const buf = randBitsSync(bitLength, true)
|
||||
const rnd = fromBuffer(buf)
|
||||
try {
|
||||
const msgToWorker: MainToWorkerMsg = {
|
||||
rnd: rnd,
|
||||
iterations: iterations,
|
||||
id: msg.id
|
||||
}
|
||||
newWorker.postMessage(msgToWorker)
|
||||
} catch (error) {
|
||||
// The worker has already terminated. There is nothing to handle here
|
||||
}
|
||||
}
|
||||
}
|
||||
if (IS_BROWSER) { // browser
|
||||
const workerURL = _isProbablyPrimeWorkerUrl()
|
||||
for (let i = 0; i < self.navigator.hardwareConcurrency - 1; i++) {
|
||||
const newWorker = new Worker(workerURL)
|
||||
newWorker.onmessage = (event) => _onmessage(event.data, newWorker)
|
||||
workerList.push(newWorker)
|
||||
}
|
||||
} else { // Node.js
|
||||
const { cpus } = require('os') // eslint-disable-line
|
||||
const { Worker } = require('worker_threads') // eslint-disable-line
|
||||
for (let i = 0; i < cpus().length - 1; i++) {
|
||||
const newWorker = new Worker(__filename)
|
||||
newWorker.on('message', (msg: WorkerToMainMsg) => _onmessage(msg, newWorker))
|
||||
workerList.push(newWorker)
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < workerList.length; i++) {
|
||||
randBits(bitLength, true).then(function (buf: Uint8Array|Buffer) {
|
||||
const rnd = fromBuffer(buf)
|
||||
workerList[i].postMessage({
|
||||
rnd: rnd,
|
||||
iterations: iterations,
|
||||
id: i
|
||||
})
|
||||
}).catch(reject)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator.
|
||||
* The sync version is NOT RECOMMENDED since it won't use workers and thus it'll be slower and may freeze thw window in browser's javascript. Please consider using prime() instead.
|
||||
*
|
||||
* @param bitLength - The required bit length for the generated prime
|
||||
* @param iterations - The number of iterations for the Miller-Rabin Probabilistic Primality Test
|
||||
*
|
||||
* @throws {RangeError}
|
||||
* bitLength MUST be > 0
|
||||
*
|
||||
* @returns A bigint probable prime of bitLength bits.
|
||||
*/
|
||||
export function primeSync (bitLength: number, iterations: number = 16): bigint {
|
||||
if (bitLength < 1) throw new RangeError('bitLength MUST be > 0')
|
||||
let rnd = 0n
|
||||
do {
|
||||
rnd = fromBuffer(randBitsSync(bitLength, true))
|
||||
} while (!_isProbablyPrime(rnd, iterations))
|
||||
return rnd
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
import { bitLength } from 'bigint-mod-arith'
|
||||
import { fromBuffer } from './fromBuffer'
|
||||
import { randBitsSync } from './randBits'
|
||||
|
||||
/**
|
||||
* Returns a cryptographically secure random integer between [min,max]. Both numbers must be >=0
|
||||
* @param max Returned value will be <= max
|
||||
* @param min Returned value will be >= min
|
||||
*
|
||||
* @throws {RangeError}
|
||||
* Arguments MUST be: max > 0 && min >=0 && max > min
|
||||
*
|
||||
* @returns A cryptographically secure random bigint between [min,max]
|
||||
*/
|
||||
export function randBetween (max: bigint, min: bigint = 1n): bigint {
|
||||
if (max <= 0n || min < 0n || max <= min) throw new RangeError('Arguments MUST be: max > 0 && min >=0 && max > min')
|
||||
const interval = max - min
|
||||
const bitLen = bitLength(interval)
|
||||
let rnd
|
||||
do {
|
||||
const buf = randBitsSync(bitLen)
|
||||
rnd = fromBuffer(buf)
|
||||
} while (rnd > interval)
|
||||
return rnd + min
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
import { randBytes, randBytesSync } from './randBytes'
|
||||
|
||||
/**
|
||||
* Secure random bits for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()
|
||||
*
|
||||
* @param bitLength - The desired number of random bits
|
||||
* @param forceLength - If we want to force the output to have a specific bit length. It basically forces the msb to be 1
|
||||
*
|
||||
* @throws {RangeError}
|
||||
* bitLength MUST be > 0
|
||||
*
|
||||
* @returns A Promise that resolves to a UInt8Array/Buffer (Browser/Node.js) filled with cryptographically secure random bits
|
||||
*/
|
||||
export function randBits (bitLength: number, forceLength: boolean = false): Promise<Uint8Array|Buffer> { // eslint-disable-line
|
||||
if (bitLength < 1) throw new RangeError('bitLength MUST be > 0')
|
||||
|
||||
const byteLength = Math.ceil(bitLength / 8)
|
||||
const bitLengthMod8 = bitLength % 8
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
randBytes(byteLength, false).then(function (rndBytes) { // eslint-disable-line
|
||||
if (bitLengthMod8 !== 0) {
|
||||
// Fill with 0's the extra bits
|
||||
rndBytes[0] = rndBytes[0] & (2 ** bitLengthMod8 - 1)
|
||||
}
|
||||
if (forceLength) {
|
||||
const mask = (bitLengthMod8 !== 0) ? 2 ** (bitLengthMod8 - 1) : 128
|
||||
rndBytes[0] = rndBytes[0] | mask
|
||||
}
|
||||
resolve(rndBytes)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Secure random bits for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()
|
||||
* @param bitLength - The desired number of random bits
|
||||
* @param forceLength - If we want to force the output to have a specific bit length. It basically forces the msb to be 1
|
||||
*
|
||||
* @throws {RangeError}
|
||||
* bitLength MUST be > 0
|
||||
*
|
||||
* @returns A Uint8Array/Buffer (Browser/Node.js) filled with cryptographically secure random bits
|
||||
*/
|
||||
export function randBitsSync (bitLength: number, forceLength: boolean = false): Uint8Array|Buffer {
|
||||
if (bitLength < 1) throw new RangeError('bitLength MUST be > 0')
|
||||
|
||||
const byteLength = Math.ceil(bitLength / 8)
|
||||
const rndBytes = randBytesSync(byteLength, false)
|
||||
const bitLengthMod8 = bitLength % 8
|
||||
if (bitLengthMod8 !== 0) {
|
||||
// Fill with 0's the extra bits
|
||||
rndBytes[0] = rndBytes[0] & (2 ** bitLengthMod8 - 1)
|
||||
}
|
||||
if (forceLength) {
|
||||
const mask = (bitLengthMod8 !== 0) ? 2 ** (bitLengthMod8 - 1) : 128
|
||||
rndBytes[0] = rndBytes[0] | mask
|
||||
}
|
||||
return rndBytes
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/**
|
||||
* Secure random bytes for both node and browsers. Node version uses crypto.randomBytes() and browser one self.crypto.getRandomValues()
|
||||
*
|
||||
* @param byteLength - The desired number of random bytes
|
||||
* @param forceLength - If we want to force the output to have a bit length of 8*byteLength. It basically forces the msb to be 1
|
||||
*
|
||||
* @throws {RangeError}
|
||||
* byteLength MUST be > 0
|
||||
*
|
||||
* @returns A promise that resolves to a UInt8Array/Buffer (Browser/Node.js) filled with cryptographically secure random bytes
|
||||
*/
|
||||
export function randBytes (byteLength: number, forceLength = false): Promise<Uint8Array|Buffer> { // eslint-disable-line
|
||||
if (byteLength < 1) throw new RangeError('byteLength MUST be > 0')
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
if (!IS_BROWSER) {
|
||||
const crypto = require('crypto') // eslint-disable-line
|
||||
crypto.randomBytes(byteLength, function (err: Error, buf: Buffer) {
|
||||
/* istanbul ignore if */
|
||||
if (err !== null) reject(err)
|
||||
// If fixed length is required we put the first bit to 1 -> to get the necessary bitLength
|
||||
if (forceLength) buf[0] = buf[0] | 128
|
||||
resolve(buf)
|
||||
})
|
||||
} else { // browser
|
||||
const buf = new Uint8Array(byteLength)
|
||||
self.crypto.getRandomValues(buf)
|
||||
// If fixed length is required we put the first bit to 1 -> to get the necessary bitLength
|
||||
if (forceLength) buf[0] = buf[0] | 128
|
||||
resolve(buf)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Secure random bytes for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()
|
||||
*
|
||||
* @param byteLength - The desired number of random bytes
|
||||
* @param forceLength - If we want to force the output to have a bit length of 8*byteLength. It basically forces the msb to be 1
|
||||
*
|
||||
* @throws {RangeError}
|
||||
* byteLength MUST be > 0
|
||||
*
|
||||
* @returns A UInt8Array/Buffer (Browser/Node.js) filled with cryptographically secure random bytes
|
||||
*/
|
||||
export function randBytesSync (byteLength: number, forceLength: boolean = false): Uint8Array|Buffer {
|
||||
if (byteLength < 1) throw new RangeError('byteLength MUST be > 0')
|
||||
|
||||
/* eslint-disable no-lone-blocks */
|
||||
if (!IS_BROWSER) { // node
|
||||
const crypto = require('crypto') // eslint-disable-line
|
||||
const buf = crypto.randomBytes(byteLength)
|
||||
// If fixed length is required we put the first bit to 1 -> to get the necessary bitLength
|
||||
if (forceLength) buf[0] = buf[0] | 128
|
||||
return buf
|
||||
} else { // browser
|
||||
const buf = new Uint8Array(byteLength)
|
||||
self.crypto.getRandomValues(buf)
|
||||
// If fixed length is required we put the first bit to 1 -> to get the necessary bitLength
|
||||
if (forceLength) buf[0] = buf[0] | 128
|
||||
return buf
|
||||
}
|
||||
/* eslint-enable no-lone-blocks */
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
export function _workerUrl (workerCode: string): string {
|
||||
workerCode = `(() => {${workerCode}})()` // encapsulate IIFE
|
||||
const _blob = new Blob([workerCode], { type: 'text/javascript' })
|
||||
return window.URL.createObjectURL(_blob)
|
||||
}
|
||||
|
||||
let _useWorkers = false // The following is just to check whether we can use workers
|
||||
/* eslint-disable no-lone-blocks */
|
||||
if (!IS_BROWSER) { // Node.js
|
||||
try {
|
||||
require.resolve('worker_threads')
|
||||
_useWorkers = true
|
||||
} catch (e) {
|
||||
/* istanbul ignore next */
|
||||
console.log(`[bigint-crypto-utils] WARNING:
|
||||
This node version doesn't support worker_threads. You should enable them in order to greatly speedup the generation of big prime numbers.
|
||||
· With Node >=11 it is enabled by default (consider upgrading).
|
||||
· With Node 10, starting with 10.5.0, you can enable worker_threads at runtime executing node --experimental-worker `)
|
||||
}
|
||||
} else { // Native JS
|
||||
if (self.Worker !== undefined) _useWorkers = true
|
||||
}
|
||||
|
||||
export { _useWorkers }
|
||||
|
||||
export interface WorkerToMainMsg {
|
||||
isPrime: boolean
|
||||
value: bigint
|
||||
id: number
|
||||
}
|
||||
|
||||
export interface MainToWorkerMsg {
|
||||
rnd: bigint
|
||||
iterations: number
|
||||
id: number
|
||||
}
|
37
test/abs.js
37
test/abs.js
|
@ -1,37 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
// Every test file (you can create as many as you want) should start like this
|
||||
// Please, do NOT touch. They will be automatically removed for browser tests -->
|
||||
const _pkg = require('../lib/index.node')
|
||||
const chai = require('chai')
|
||||
// <--
|
||||
|
||||
const inputs = [
|
||||
{
|
||||
value: BigInt(1),
|
||||
abs: BigInt(1)
|
||||
},
|
||||
{
|
||||
value: BigInt(-2),
|
||||
abs: BigInt(2)
|
||||
},
|
||||
{
|
||||
value: BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777'),
|
||||
abs: BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777')
|
||||
},
|
||||
{
|
||||
value: BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203'),
|
||||
abs: BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')
|
||||
}
|
||||
]
|
||||
|
||||
describe('abs', function () {
|
||||
for (const input of inputs) {
|
||||
describe(`abs(${input.value})`, function () {
|
||||
it(`should return ${input.abs}`, function () {
|
||||
const ret = _pkg.abs(input.value)
|
||||
chai.expect(ret).to.equal(input.abs)
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
|
@ -1,34 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
// Every test file (you can create as many as you want) should start like this
|
||||
// Please, do NOT touch. They will be automatically removed for browser tests -->
|
||||
const _pkg = require('../lib/index.node')
|
||||
const chai = require('chai')
|
||||
// <--
|
||||
|
||||
const inputs = [
|
||||
{
|
||||
value: BigInt(1),
|
||||
bitLength: 1
|
||||
},
|
||||
{
|
||||
value: BigInt(-2),
|
||||
bitLength: 2
|
||||
},
|
||||
{
|
||||
value: BigInt('11592217955149597331'),
|
||||
abs: BigInt('11592217955149597331'),
|
||||
bitLength: 64
|
||||
}
|
||||
]
|
||||
|
||||
describe('bitLength', function () {
|
||||
for (const input of inputs) {
|
||||
describe(`bitLength(${input.value})`, function () {
|
||||
it(`should return ${input.bitLength}`, function () {
|
||||
const ret = _pkg.bitLength(input.value)
|
||||
chai.expect(ret).to.equal(input.bitLength)
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
|
@ -1,23 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>bigint-crypto-utils - Mocha Tests</title>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/mocha/8.2.1/mocha.min.css">
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/mocha/8.2.1/mocha.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/chai/4.2.0/chai.min.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="mocha"></div>
|
||||
<script>mocha.setup('bdd'); mocha.setup({ timeout: 90000 });</script>
|
||||
|
||||
<script type="module">
|
||||
import * as _pkg from '../../../lib/index.browser.bundle.mod.js'
|
||||
window._pkg = _pkg
|
||||
import './tests.js'
|
||||
mocha.run()
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,888 +0,0 @@
|
|||
// Every test file (you can create as many as you want) should start like this
|
||||
// Please, do NOT touch. They will be automatically removed for browser tests -->
|
||||
|
||||
|
||||
// <--
|
||||
|
||||
const inputs = [
|
||||
{
|
||||
value: BigInt(1),
|
||||
abs: BigInt(1)
|
||||
},
|
||||
{
|
||||
value: BigInt(-2),
|
||||
abs: BigInt(2)
|
||||
},
|
||||
{
|
||||
value: BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777'),
|
||||
abs: BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777')
|
||||
},
|
||||
{
|
||||
value: BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203'),
|
||||
abs: BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')
|
||||
}
|
||||
];
|
||||
|
||||
describe('abs', function () {
|
||||
for (const input of inputs) {
|
||||
describe(`abs(${input.value})`, function () {
|
||||
it(`should return ${input.abs}`, function () {
|
||||
const ret = _pkg.abs(input.value);
|
||||
chai.expect(ret).to.equal(input.abs);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Every test file (you can create as many as you want) should start like this
|
||||
// Please, do NOT touch. They will be automatically removed for browser tests -->
|
||||
|
||||
|
||||
// <--
|
||||
|
||||
const inputs$1 = [
|
||||
{
|
||||
value: BigInt(1),
|
||||
bitLength: 1
|
||||
},
|
||||
{
|
||||
value: BigInt(-2),
|
||||
bitLength: 2
|
||||
},
|
||||
{
|
||||
value: BigInt('11592217955149597331'),
|
||||
abs: BigInt('11592217955149597331'),
|
||||
bitLength: 64
|
||||
}
|
||||
];
|
||||
|
||||
describe('bitLength', function () {
|
||||
for (const input of inputs$1) {
|
||||
describe(`bitLength(${input.value})`, function () {
|
||||
it(`should return ${input.bitLength}`, function () {
|
||||
const ret = _pkg.bitLength(input.value);
|
||||
chai.expect(ret).to.equal(input.bitLength);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Every test file (you can create as many as you want) should start like this
|
||||
// Please, do NOT touch. They will be automatically removed for browser tests -->
|
||||
|
||||
|
||||
// <--
|
||||
|
||||
const inputs$2 = [
|
||||
{
|
||||
a: BigInt(1),
|
||||
b: BigInt(1),
|
||||
gcd: BigInt(1)
|
||||
},
|
||||
{
|
||||
a: BigInt(0),
|
||||
b: BigInt(189),
|
||||
gcd: BigInt(189)
|
||||
},
|
||||
{
|
||||
a: BigInt(189),
|
||||
b: BigInt(0),
|
||||
gcd: BigInt(189)
|
||||
},
|
||||
{
|
||||
a: BigInt(0),
|
||||
b: BigInt(0),
|
||||
gcd: BigInt(0)
|
||||
},
|
||||
{
|
||||
a: BigInt(1),
|
||||
b: BigInt('14546149867129487614601346814'),
|
||||
gcd: BigInt(1)
|
||||
},
|
||||
{
|
||||
a: BigInt(27),
|
||||
b: BigInt(18),
|
||||
gcd: BigInt(9)
|
||||
},
|
||||
{
|
||||
a: BigInt(-27),
|
||||
b: BigInt(18),
|
||||
gcd: BigInt(9)
|
||||
},
|
||||
{
|
||||
a: BigInt(256),
|
||||
b: BigInt(128),
|
||||
gcd: BigInt(128)
|
||||
},
|
||||
{
|
||||
a: BigInt('168694196579467171180863939518634764192343817610869919231900537093664715354591592262546800497540343203057121816378265655992490621138321114570420047522219942818258345349322155251835677199539229050711145144861404607171419723967136221126986330819362088262358855325306938646602003059377699727688477555163239222109'),
|
||||
b: BigInt('168694196579467171180863939518634764192343817610869919231900537093664715354591592262546800497540343203057121816378265655992490621138321114570420047522219942818258345349322155251835677199539229050711145144861404607171419723967136221126986330819362088262358855325306938646602003059377699727688477555163239222109') * BigInt('144678545212641449725111562354371812236197961234111744040227045242578772124779004756249085154188369039159690638725821245974978963371615699005072473649705367893567309027634121825164880046600125480885803891136149601797439273507802533807541605261215613891134865916295914192271736572001975016089773532547481638243'),
|
||||
gcd: BigInt('168694196579467171180863939518634764192343817610869919231900537093664715354591592262546800497540343203057121816378265655992490621138321114570420047522219942818258345349322155251835677199539229050711145144861404607171419723967136221126986330819362088262358855325306938646602003059377699727688477555163239222109')
|
||||
}
|
||||
];
|
||||
|
||||
describe('gcd', function () {
|
||||
for (const input of inputs$2) {
|
||||
describe(`gcd(${input.a}, ${input.b})`, function () {
|
||||
it(`should return ${input.gcd}`, function () {
|
||||
const ret = _pkg.gcd(input.a, input.b);
|
||||
chai.expect(ret).to.equal(input.gcd);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Every test file (you can create as many as you want) should start like this
|
||||
// Please, do NOT touch. They will be automatically removed for browser tests -->
|
||||
|
||||
|
||||
// <--
|
||||
|
||||
const numbers = [
|
||||
{
|
||||
value: BigInt(1),
|
||||
prime: false,
|
||||
iterations: 16,
|
||||
workers: false
|
||||
},
|
||||
{
|
||||
value: BigInt(2),
|
||||
prime: true,
|
||||
iterations: 16,
|
||||
workers: false
|
||||
},
|
||||
{
|
||||
value: 3,
|
||||
prime: true,
|
||||
iterations: 16,
|
||||
workers: false
|
||||
},
|
||||
{
|
||||
value: BigInt(15),
|
||||
prime: false,
|
||||
iterations: 32,
|
||||
workers: false
|
||||
},
|
||||
{
|
||||
value: 29,
|
||||
prime: true,
|
||||
iterations: 16,
|
||||
workers: false
|
||||
},
|
||||
{
|
||||
value: BigInt('669483106578092405936560831017556154622901950048903016651289'),
|
||||
prime: true,
|
||||
iterations: 24,
|
||||
workers: false
|
||||
},
|
||||
{
|
||||
value: BigInt('2074722246773485207821695222107608587480996474721117292752992589912196684750549658310084416732550077'),
|
||||
prime: true,
|
||||
iterations: 16,
|
||||
workers: false
|
||||
},
|
||||
{
|
||||
value: BigInt('2074722246773485207821695222107608587480996474721117292752992589912196684750549658310084416732550079'),
|
||||
prime: false,
|
||||
iterations: 16,
|
||||
workers: false
|
||||
},
|
||||
{
|
||||
value: BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777'),
|
||||
prime: true,
|
||||
iterations: 24,
|
||||
workers: true
|
||||
},
|
||||
{
|
||||
value: BigInt('168694196579467171180863939518634764192343817610869919231900537093664715354591592262546800497540343203057121816378265655992490621138321114570420047522219942818258345349322155251835677199539229050711145144861404607171419723967136221126986330819362088262358855325306938646602003059377699727688477555163239222109') * BigInt('144678545212641449725111562354371812236197961234111744040227045242578772124779004756249085154188369039159690638725821245974978963371615699005072473649705367893567309027634121825164880046600125480885803891136149601797439273507802533807541605261215613891134865916295914192271736572001975016089773532547481638243'),
|
||||
prime: false,
|
||||
iterations: 16,
|
||||
workers: true
|
||||
},
|
||||
{
|
||||
value: BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203'),
|
||||
prime: true,
|
||||
iterations: 16,
|
||||
workers: true
|
||||
},
|
||||
{
|
||||
value: BigInt('940719693126280825126763871881743336375040232953039527942717290104060740215493004508206768342926022549956464101136893240409560470269654765366248516968645294076406953865805712688760371102637642013723011744011617678651884521901163090779813242269935310225049805992299292275574585773507915278612311449919050091057023179541184986547995894821648553256021675133997240195429424258757033557367142630663053464438840832073753440939208165158795269598771598124509831433327480118038278887538430675994497384283550890544882369140852048496460551123626856255619494025370171790720106325655890348475483349150258338517508459674722099347335608814922179633411167540545786247819334838979610017735984374883325689517847175539632896026875016305529321705457954181425405794479825617747354596485074451489940385640535898876551301296003465792117006135339109817937663957519031436646579178503423889430062127572272773511424424297800355292430651838502733756881154935252456036638082486459287411002911323257940893413982671660332662880068976408321968046549017547143836993553556640198884769590214676797037397502067035957959952990027503148987727895561468097917730167320715053689862847457761993196945361244822787209076446259359976421264285658106819879849052247546957718175231'),
|
||||
prime: false,
|
||||
iterations: 16,
|
||||
workers: true
|
||||
}
|
||||
];
|
||||
|
||||
describe('isProbablyPrime', function () {
|
||||
this.timeout(90000);
|
||||
for (const num of numbers) {
|
||||
describe(`isProbablyPrime(${num.value}, ${num.iterations}, ${!num.workers})`, function () {
|
||||
it(`should return ${num.prime}`, async function () {
|
||||
let ret;
|
||||
if (num.iterations === 16 && num.workers) ret = await _pkg.isProbablyPrime(num.value);
|
||||
else ret = await _pkg.isProbablyPrime(num.value, num.iterations, !num.workers);
|
||||
chai.expect(ret).to.equal(num.prime);
|
||||
});
|
||||
});
|
||||
}
|
||||
describe('isProbablyPrime(-1)', function () {
|
||||
it('should throw RangeError', function () {
|
||||
chai.expect(() => _pkg.isProbablyPrime(-1)).to.throw(RangeError);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Every test file (you can create as many as you want) should start like this
|
||||
// Please, do NOT touch. They will be automatically removed for browser tests -->
|
||||
|
||||
|
||||
// <--
|
||||
|
||||
const inputs$3 = [
|
||||
{
|
||||
a: BigInt(0),
|
||||
b: BigInt(0),
|
||||
lcm: BigInt(0)
|
||||
},
|
||||
{
|
||||
a: BigInt(1),
|
||||
b: BigInt(1),
|
||||
lcm: BigInt(1)
|
||||
},
|
||||
{
|
||||
a: BigInt(1),
|
||||
b: BigInt('14546149867129487614601346814'),
|
||||
lcm: BigInt('14546149867129487614601346814')
|
||||
},
|
||||
{
|
||||
a: BigInt(27),
|
||||
b: BigInt(18),
|
||||
lcm: BigInt(27) * BigInt(2)
|
||||
},
|
||||
{
|
||||
a: BigInt(-27),
|
||||
b: BigInt(18),
|
||||
lcm: BigInt(27) * BigInt(2)
|
||||
},
|
||||
{
|
||||
a: BigInt('168694196579467171180863939518634764192343817610869919231900537093664715354591592262546800497540343203057121816378265655992490621138321114570420047522219942818258345349322155251835677199539229050711145144861404607171419723967136221126986330819362088262358855325306938646602003059377699727688477555163239222109'),
|
||||
b: BigInt('168694196579467171180863939518634764192343817610869919231900537093664715354591592262546800497540343203057121816378265655992490621138321114570420047522219942818258345349322155251835677199539229050711145144861404607171419723967136221126986330819362088262358855325306938646602003059377699727688477555163239222109') * BigInt('144678545212641449725111562354371812236197961234111744040227045242578772124779004756249085154188369039159690638725821245974978963371615699005072473649705367893567309027634121825164880046600125480885803891136149601797439273507802533807541605261215613891134865916295914192271736572001975016089773532547481638243'),
|
||||
lcm: BigInt('168694196579467171180863939518634764192343817610869919231900537093664715354591592262546800497540343203057121816378265655992490621138321114570420047522219942818258345349322155251835677199539229050711145144861404607171419723967136221126986330819362088262358855325306938646602003059377699727688477555163239222109') * BigInt('144678545212641449725111562354371812236197961234111744040227045242578772124779004756249085154188369039159690638725821245974978963371615699005072473649705367893567309027634121825164880046600125480885803891136149601797439273507802533807541605261215613891134865916295914192271736572001975016089773532547481638243')
|
||||
}
|
||||
];
|
||||
|
||||
describe('lcm', function () {
|
||||
for (const input of inputs$3) {
|
||||
describe(`lcm(${input.a}, ${input.b})`, function () {
|
||||
it(`should return ${input.lcm}`, function () {
|
||||
const ret = _pkg.lcm(input.a, input.b);
|
||||
chai.expect(ret).to.equal(input.lcm);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Every test file (you can create as many as you want) should start like this
|
||||
// Please, do NOT touch. They will be automatically removed for browser tests -->
|
||||
|
||||
|
||||
// <--
|
||||
|
||||
const inputs$4 = [
|
||||
{
|
||||
value: [BigInt(1), BigInt(2)],
|
||||
max: BigInt(2)
|
||||
},
|
||||
{
|
||||
value: [BigInt(2), BigInt(1)],
|
||||
max: BigInt(2)
|
||||
},
|
||||
{
|
||||
value: [BigInt(2), BigInt(2)],
|
||||
max: BigInt(2)
|
||||
},
|
||||
{
|
||||
value: [BigInt(1), BigInt(-2)],
|
||||
max: BigInt(1)
|
||||
},
|
||||
{
|
||||
value: [BigInt(-2), BigInt(1)],
|
||||
max: BigInt(1)
|
||||
},
|
||||
{
|
||||
value: [BigInt(-2), BigInt(-2)],
|
||||
max: BigInt(-2)
|
||||
},
|
||||
{
|
||||
value: [BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252'), BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777')],
|
||||
max: BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252')
|
||||
},
|
||||
{
|
||||
value: [BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777'), BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252')],
|
||||
max: BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252')
|
||||
},
|
||||
{
|
||||
value: [BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777'), BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777')],
|
||||
max: BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777')
|
||||
},
|
||||
{
|
||||
value: [BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252'), BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777')],
|
||||
max: BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777')
|
||||
},
|
||||
{
|
||||
value: [BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777'), BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252')],
|
||||
max: BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777')
|
||||
},
|
||||
{
|
||||
value: [BigInt('-115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777'), BigInt('-115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777')],
|
||||
max: BigInt('-115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777')
|
||||
},
|
||||
{
|
||||
value: [BigInt('94120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203'), BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')],
|
||||
max: BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')
|
||||
},
|
||||
{
|
||||
value: [BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203'), BigInt('918145974144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')],
|
||||
max: BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')
|
||||
},
|
||||
{
|
||||
value: [BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203'), BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')],
|
||||
max: BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')
|
||||
},
|
||||
{
|
||||
value: [BigInt('94120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203'), BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')],
|
||||
max: BigInt('94120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')
|
||||
},
|
||||
{
|
||||
value: [BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203'), BigInt('918145974144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')],
|
||||
max: BigInt('918145974144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')
|
||||
},
|
||||
{
|
||||
value: [BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203'), BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')],
|
||||
max: BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')
|
||||
}
|
||||
];
|
||||
|
||||
describe('max', function () {
|
||||
for (const input of inputs$4) {
|
||||
describe(`max(${input.value[0]}, ${input.value[1]})`, function () {
|
||||
it(`should return ${input.max}`, function () {
|
||||
const ret = _pkg.max(input.value[0], input.value[1]);
|
||||
chai.expect(ret).to.equal(input.max);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Every test file (you can create as many as you want) should start like this
|
||||
// Please, do NOT touch. They will be automatically removed for browser tests -->
|
||||
|
||||
|
||||
// <--
|
||||
|
||||
const inputs$5 = [
|
||||
{
|
||||
value: [BigInt(1), BigInt(2)],
|
||||
min: BigInt(1)
|
||||
},
|
||||
{
|
||||
value: [BigInt(2), BigInt(1)],
|
||||
min: BigInt(1)
|
||||
},
|
||||
{
|
||||
value: [BigInt(2), BigInt(2)],
|
||||
min: BigInt(2)
|
||||
},
|
||||
{
|
||||
value: [BigInt(1), BigInt(-2)],
|
||||
min: BigInt(-2)
|
||||
},
|
||||
{
|
||||
value: [BigInt(-2), BigInt(1)],
|
||||
min: BigInt(-2)
|
||||
},
|
||||
{
|
||||
value: [BigInt(-2), BigInt(-2)],
|
||||
min: BigInt(-2)
|
||||
},
|
||||
{
|
||||
value: [BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252'), BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777')],
|
||||
min: BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777')
|
||||
},
|
||||
{
|
||||
value: [BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777'), BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252')],
|
||||
min: BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777')
|
||||
},
|
||||
{
|
||||
value: [BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777'), BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777')],
|
||||
min: BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777')
|
||||
},
|
||||
{
|
||||
value: [BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252'), BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777')],
|
||||
min: BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252')
|
||||
},
|
||||
{
|
||||
value: [BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777'), BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252')],
|
||||
min: BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252')
|
||||
},
|
||||
{
|
||||
value: [BigInt('-115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777'), BigInt('-115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777')],
|
||||
min: BigInt('-115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777')
|
||||
},
|
||||
{
|
||||
value: [BigInt('94120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203'), BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')],
|
||||
min: BigInt('94120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')
|
||||
},
|
||||
{
|
||||
value: [BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203'), BigInt('918145974144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')],
|
||||
min: BigInt('918145974144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')
|
||||
},
|
||||
{
|
||||
value: [BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203'), BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')],
|
||||
min: BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')
|
||||
},
|
||||
{
|
||||
value: [BigInt('94120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203'), BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')],
|
||||
min: BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')
|
||||
},
|
||||
{
|
||||
value: [BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203'), BigInt('918145974144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')],
|
||||
min: BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')
|
||||
},
|
||||
{
|
||||
value: [BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203'), BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')],
|
||||
min: BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')
|
||||
}
|
||||
];
|
||||
|
||||
describe('min', function () {
|
||||
for (const input of inputs$5) {
|
||||
describe(`min(${input.value[0]}, ${input.value[1]})`, function () {
|
||||
it(`should return ${input.min}`, function () {
|
||||
const ret = _pkg.min(input.value[0], input.value[1]);
|
||||
chai.expect(ret).to.equal(input.min);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Every test file (you can create as many as you want) should start like this
|
||||
// Please, do NOT touch. They will be automatically removed for browser tests -->
|
||||
|
||||
|
||||
// <--
|
||||
|
||||
const inputs$6 = [
|
||||
{
|
||||
a: BigInt(1),
|
||||
n: BigInt(19),
|
||||
modInv: BigInt(1)
|
||||
},
|
||||
{
|
||||
a: BigInt(2),
|
||||
n: BigInt(5),
|
||||
modInv: BigInt(3)
|
||||
},
|
||||
{
|
||||
a: BigInt(-2),
|
||||
n: BigInt(5),
|
||||
modInv: BigInt(2)
|
||||
}];
|
||||
|
||||
const invalidInputs = [
|
||||
{
|
||||
a: BigInt(2),
|
||||
n: BigInt(4)
|
||||
},
|
||||
{
|
||||
a: BigInt(0),
|
||||
n: BigInt(0)
|
||||
},
|
||||
{
|
||||
a: BigInt(0),
|
||||
n: BigInt(37)
|
||||
}
|
||||
];
|
||||
|
||||
describe('modInv', function () {
|
||||
for (const input of inputs$6) {
|
||||
describe(`modInv(${input.a}, ${input.n})`, function () {
|
||||
it(`should return ${input.modInv}`, function () {
|
||||
const ret = _pkg.modInv(input.a, input.n);
|
||||
// chai.assert( String(ret) === String(input.modInv) );
|
||||
chai.expect(String(ret)).to.be.equal(String(input.modInv));
|
||||
});
|
||||
});
|
||||
}
|
||||
for (const input of invalidInputs) {
|
||||
describe(`modInv(${input.a}, ${input.n})`, function () {
|
||||
it('should throw RangeError', function () {
|
||||
try {
|
||||
_pkg.modInv(input.a, input.n);
|
||||
throw new Error('should have failed')
|
||||
} catch (err) {
|
||||
chai.expect(err).to.be.instanceOf(RangeError);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Every test file (you can create as many as you want) should start like this
|
||||
// Please, do NOT touch. They will be automatically removed for browser tests -->
|
||||
|
||||
|
||||
// <--
|
||||
|
||||
const inputs$7 = [
|
||||
{
|
||||
a: BigInt(4),
|
||||
b: BigInt(-1),
|
||||
n: BigInt(1),
|
||||
modPow: BigInt(0)
|
||||
},
|
||||
{
|
||||
a: BigInt(4),
|
||||
b: BigInt(-1),
|
||||
n: BigInt(19),
|
||||
modPow: BigInt(5)
|
||||
},
|
||||
{
|
||||
a: BigInt(-5),
|
||||
b: BigInt(2),
|
||||
n: BigInt(7),
|
||||
modPow: BigInt(4)
|
||||
},
|
||||
{
|
||||
a: BigInt(2),
|
||||
b: BigInt(255),
|
||||
n: BigInt(64),
|
||||
modPow: BigInt(0)
|
||||
},
|
||||
{
|
||||
a: BigInt(3),
|
||||
b: BigInt(3),
|
||||
n: BigInt(25),
|
||||
modPow: BigInt(2)
|
||||
}];
|
||||
|
||||
const invalidInputs$1 = [
|
||||
{
|
||||
a: BigInt(4),
|
||||
b: BigInt(-1),
|
||||
n: BigInt(0)
|
||||
}
|
||||
];
|
||||
|
||||
describe('modPow', function () {
|
||||
this.timeout(90000);
|
||||
for (const input of inputs$7) {
|
||||
describe(`modPow(${input.a}, ${input.b}, ${input.n})`, function () {
|
||||
it(`should return ${input.modPow}`, function () {
|
||||
const ret = _pkg.modPow(input.a, input.b, input.n);
|
||||
chai.expect(String(ret)).to.equal(String(input.modPow));
|
||||
});
|
||||
});
|
||||
}
|
||||
for (const input of invalidInputs$1) {
|
||||
describe(`modPow(${input.a}, ${input.b}, ${input.n})`, function () {
|
||||
it('should throw RangeError', function () {
|
||||
try {
|
||||
_pkg.modPow(input.a, input.b, input.n);
|
||||
throw new Error('should have failed')
|
||||
} catch (err) {
|
||||
chai.expect(err).to.be.instanceOf(RangeError);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
describe('Time profiling', function () {
|
||||
let iterations = 500;
|
||||
it(`just testing ${iterations} iterations of a big modular exponentiation (1024 bits)`, function () {
|
||||
const p = BigInt('103920301461718841589267304263845359224454055603847417021399996422142529929535423886894599506329362009085557636432288745748144369296043048325513558512136442971686130986388589421125262751724362880217790112013162815676017250234401214198365302142787009943498370856167174244675719638815809347261773472114842038647');
|
||||
const b = BigInt('313632271690673451924314047671460131678794095260951233878123501752357966284491455239133687519908410656818506813151659324961829045286402303082891913186909806785080978448037486178337722667190743610785429936585699831407575170854873682955317589189564880931807976657385223632835801016017549762825562427694700595');
|
||||
const e = BigInt('452149997592306202232720864363485824701879487303880767747217308770351197801836846325633986474037061753983278534192061455638289551714281047915315943771002615269860312318606105460307037327329178890486613832051027105330475852552183444938408408863970975090778239473049899109989825645608770309107015209564444316');
|
||||
while (iterations > 0) {
|
||||
_pkg.modPow(b, e, p);
|
||||
iterations--;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Every test file (you can create as many as you want) should start like this
|
||||
// Please, do NOT touch. They will be automatically removed for browser tests -->
|
||||
|
||||
|
||||
// <--
|
||||
|
||||
const bitLengths = [
|
||||
0,
|
||||
8,
|
||||
255,
|
||||
256,
|
||||
258,
|
||||
512,
|
||||
1024,
|
||||
2048,
|
||||
3072
|
||||
];
|
||||
|
||||
describe('Testing prime generation', function () {
|
||||
this.timeout(120000);
|
||||
for (const bitLength of bitLengths) {
|
||||
describe(`prime(${bitLength})`, function () {
|
||||
if (bitLength > 0) {
|
||||
it(`should return a random ${bitLength}-bits probable prime`, async function () {
|
||||
const prime = await _pkg.prime(bitLength);
|
||||
chai.expect(_pkg.bitLength(prime)).to.equal(bitLength);
|
||||
});
|
||||
} else {
|
||||
it('should throw error', async function () {
|
||||
chai.expect(() => _pkg.prime(bitLength)).to.throw(RangeError);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
describe('Testing sync (NOT-RECOMMENDED) version: primeSync()', function () {
|
||||
it('should return a random 1024-bits probable prime', function () {
|
||||
const prime = _pkg.primeSync(1024, 16);
|
||||
chai.expect(_pkg.bitLength(prime)).to.equal(1024);
|
||||
chai.expect(() => _pkg.primeSync(0)).to.throw(RangeError);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Every test file (you can create as many as you want) should start like this
|
||||
// Please, do NOT touch. They will be automatically removed for browser tests -->
|
||||
|
||||
|
||||
// <--
|
||||
|
||||
const numbers$1 = [
|
||||
{
|
||||
min: BigInt(1),
|
||||
max: BigInt(2) ** BigInt(234),
|
||||
iterations: 100,
|
||||
error: false,
|
||||
errorMax: false
|
||||
},
|
||||
{
|
||||
min: BigInt('122461641436345153'),
|
||||
max: BigInt(2) ** BigInt(234),
|
||||
iterations: 100,
|
||||
error: false,
|
||||
errorMax: false
|
||||
},
|
||||
{
|
||||
min: BigInt(146347),
|
||||
max: BigInt(2),
|
||||
iterations: 1,
|
||||
error: true,
|
||||
errorMax: false
|
||||
},
|
||||
{
|
||||
min: BigInt(2),
|
||||
max: BigInt(2),
|
||||
iterations: 1,
|
||||
error: true,
|
||||
errorMax: false
|
||||
},
|
||||
{
|
||||
min: BigInt(-4),
|
||||
max: BigInt(2),
|
||||
iterations: 1,
|
||||
error: true,
|
||||
errorMax: false
|
||||
},
|
||||
{
|
||||
min: BigInt(1),
|
||||
max: BigInt(-1),
|
||||
iterations: 1,
|
||||
error: true,
|
||||
errorMax: true
|
||||
}
|
||||
];
|
||||
|
||||
describe('randBetween', function () {
|
||||
this.timeout(90000);
|
||||
for (const num of numbers$1) {
|
||||
describe(`randBetween(${num.max}, ${num.min})`, function () {
|
||||
if (!num.error) {
|
||||
it(`[${num.iterations} iterations] should return x such that min < x < max`, function () {
|
||||
let ret = true;
|
||||
for (let i = 0; i < num.iterations; i++) {
|
||||
const x = _pkg.randBetween(num.max, num.min);
|
||||
ret = ret && x > num.min && x < num.max;
|
||||
}
|
||||
chai.expect(ret).to.equal(true);
|
||||
});
|
||||
} else {
|
||||
it('should throw RangeError (max <=0 || min <0 || min>=max)', function () {
|
||||
chai.expect(() => _pkg.randBetween(num.max, num.min)).to.throw(RangeError);
|
||||
});
|
||||
}
|
||||
});
|
||||
describe(`randBetween(${num.max})`, function () {
|
||||
if (!num.errorMax) {
|
||||
it(`[${num.iterations} iterations] should return x such that 1 <= x <= max`, function () {
|
||||
let ret = true;
|
||||
for (let i = 0; i < num.iterations; i++) {
|
||||
const x = _pkg.randBetween(num.max);
|
||||
ret = ret && x >= BigInt(1) && x <= num.max;
|
||||
}
|
||||
chai.expect(ret).to.equal(true);
|
||||
});
|
||||
} else {
|
||||
it('should throw RangeError (max <=0)', function () {
|
||||
chai.expect(() => _pkg.randBetween(num.max)).to.throw(RangeError);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Every test file (you can create as many as you want) should start like this
|
||||
// Please, do NOT touch. They will be automatically removed for browser tests -->
|
||||
|
||||
|
||||
// <--
|
||||
|
||||
const iterations = 10;
|
||||
const bitLengths$1 = [-1, 0, 3, 8, 16, 511, 2048];
|
||||
const byteLengths = [-7, 0, 1, 8, 33, 40];
|
||||
|
||||
describe('testing randBits', async function () {
|
||||
for (const bitLength of bitLengths$1) {
|
||||
describe(`${iterations} iterations of randBitsSync(${bitLength})`, function () {
|
||||
if (bitLength > 0) {
|
||||
it('should return buffers', function () {
|
||||
let ret = true;
|
||||
for (let i = 0; i < iterations; i++) {
|
||||
const randbits = _pkg.randBitsSync(bitLength);
|
||||
// console.log(JSON.stringify(randbits))
|
||||
const randbits2 = _pkg.randBitsSync(bitLength, true);
|
||||
// console.log(JSON.stringify(randbits2))
|
||||
if (!(((randbits instanceof Uint8Array) && (randbits2 instanceof Uint8Array)) ||
|
||||
((randbits instanceof Buffer) && (randbits2 instanceof Buffer)))) {
|
||||
ret = false;
|
||||
break
|
||||
}
|
||||
}
|
||||
chai.expect(ret).to.equal(true);
|
||||
});
|
||||
} else {
|
||||
it('should throw RangeError', function () {
|
||||
chai.expect(() => _pkg.randBitsSync(bitLength)).to.throw(RangeError);
|
||||
});
|
||||
}
|
||||
});
|
||||
describe(`${iterations} iterations of randBits(${bitLength})`, async function () {
|
||||
if (bitLength > 0) {
|
||||
it('should return buffers', async function () {
|
||||
let ret = true;
|
||||
for (let i = 0; i < iterations; i++) {
|
||||
const randbits = await _pkg.randBits(bitLength);
|
||||
// console.log(JSON.stringify(randbits))
|
||||
const randbits2 = await _pkg.randBits(bitLength, true);
|
||||
// console.log(JSON.stringify(randbits2))
|
||||
if (!(((randbits instanceof Uint8Array) && (randbits2 instanceof Uint8Array)) ||
|
||||
((randbits instanceof Buffer) && (randbits2 instanceof Buffer)))) {
|
||||
ret = false;
|
||||
break
|
||||
}
|
||||
}
|
||||
chai.expect(ret).to.equal(true);
|
||||
});
|
||||
} else {
|
||||
it('should throw RangeError', function () {
|
||||
chai.expect(() => _pkg.randBits(bitLength)).to.throw(RangeError);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('testing randBytes', async function () {
|
||||
for (const byteLength of byteLengths) {
|
||||
describe(`${iterations} iterations of randBytesSync(${byteLength})`, function () {
|
||||
if (byteLength > 0) {
|
||||
it('should return buffers', function () {
|
||||
let ret = true;
|
||||
for (let i = 0; i < iterations; i++) {
|
||||
const randbytes = _pkg.randBytesSync(byteLength);
|
||||
// console.log(JSON.stringify(randbits))
|
||||
const randbytes2 = _pkg.randBytesSync(byteLength, true);
|
||||
// console.log(JSON.stringify(randbits2))
|
||||
if (!(((randbytes instanceof Uint8Array) && (randbytes2 instanceof Uint8Array)) ||
|
||||
((randbytes instanceof Buffer) && (randbytes2 instanceof Buffer)))) {
|
||||
ret = false;
|
||||
}
|
||||
}
|
||||
chai.expect(ret).to.equal(true);
|
||||
});
|
||||
} else {
|
||||
it('should throw RangeError', function () {
|
||||
chai.expect(() => _pkg.randBytesSync(byteLength)).to.throw(RangeError);
|
||||
});
|
||||
}
|
||||
});
|
||||
describe(`${iterations} iterations of randBytes(${byteLength})`, async function () {
|
||||
if (byteLength > 0) {
|
||||
it('should return buffers', async function () {
|
||||
let ret = true;
|
||||
for (let i = 0; i < iterations; i++) {
|
||||
const randbytes = await _pkg.randBytes(byteLength);
|
||||
// console.log(JSON.stringify(randbits))
|
||||
const randbytes2 = await _pkg.randBytes(byteLength, true);
|
||||
// console.log(JSON.stringify(randbits2))
|
||||
if (!(((randbytes instanceof Uint8Array) && (randbytes2 instanceof Uint8Array)) ||
|
||||
((randbytes instanceof Buffer) && (randbytes2 instanceof Buffer)))) {
|
||||
ret = false;
|
||||
}
|
||||
}
|
||||
chai.expect(ret).to.equal(true);
|
||||
});
|
||||
} else {
|
||||
it('should throw RangeError', function () {
|
||||
chai.expect(() => _pkg.randBytes(byteLength)).to.throw(RangeError);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Every test file (you can create as many as you want) should start like this
|
||||
// Please, do NOT touch. They will be automatically removed for browser tests -->
|
||||
|
||||
|
||||
// <--
|
||||
|
||||
const inputs$8 = [
|
||||
{
|
||||
a: BigInt(1),
|
||||
n: BigInt(19),
|
||||
toZn: BigInt(1)
|
||||
},
|
||||
{
|
||||
a: BigInt(-25),
|
||||
n: BigInt(9),
|
||||
toZn: BigInt(2)
|
||||
},
|
||||
{
|
||||
a: BigInt('12359782465012847510249'),
|
||||
n: BigInt(5),
|
||||
toZn: BigInt(4)
|
||||
}
|
||||
];
|
||||
|
||||
describe('toZn', function () {
|
||||
for (const input of inputs$8) {
|
||||
describe(`toZn(${input.a}, ${input.n})`, function () {
|
||||
it(`should return ${input.toZn}`, function () {
|
||||
const ret = _pkg.toZn(input.a, input.n);
|
||||
chai.expect(ret).to.equal(input.toZn);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
66
test/gcd.js
66
test/gcd.js
|
@ -1,66 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
// Every test file (you can create as many as you want) should start like this
|
||||
// Please, do NOT touch. They will be automatically removed for browser tests -->
|
||||
const _pkg = require('../lib/index.node')
|
||||
const chai = require('chai')
|
||||
// <--
|
||||
|
||||
const inputs = [
|
||||
{
|
||||
a: BigInt(1),
|
||||
b: BigInt(1),
|
||||
gcd: BigInt(1)
|
||||
},
|
||||
{
|
||||
a: BigInt(0),
|
||||
b: BigInt(189),
|
||||
gcd: BigInt(189)
|
||||
},
|
||||
{
|
||||
a: BigInt(189),
|
||||
b: BigInt(0),
|
||||
gcd: BigInt(189)
|
||||
},
|
||||
{
|
||||
a: BigInt(0),
|
||||
b: BigInt(0),
|
||||
gcd: BigInt(0)
|
||||
},
|
||||
{
|
||||
a: BigInt(1),
|
||||
b: BigInt('14546149867129487614601346814'),
|
||||
gcd: BigInt(1)
|
||||
},
|
||||
{
|
||||
a: BigInt(27),
|
||||
b: BigInt(18),
|
||||
gcd: BigInt(9)
|
||||
},
|
||||
{
|
||||
a: BigInt(-27),
|
||||
b: BigInt(18),
|
||||
gcd: BigInt(9)
|
||||
},
|
||||
{
|
||||
a: BigInt(256),
|
||||
b: BigInt(128),
|
||||
gcd: BigInt(128)
|
||||
},
|
||||
{
|
||||
a: BigInt('168694196579467171180863939518634764192343817610869919231900537093664715354591592262546800497540343203057121816378265655992490621138321114570420047522219942818258345349322155251835677199539229050711145144861404607171419723967136221126986330819362088262358855325306938646602003059377699727688477555163239222109'),
|
||||
b: BigInt('168694196579467171180863939518634764192343817610869919231900537093664715354591592262546800497540343203057121816378265655992490621138321114570420047522219942818258345349322155251835677199539229050711145144861404607171419723967136221126986330819362088262358855325306938646602003059377699727688477555163239222109') * BigInt('144678545212641449725111562354371812236197961234111744040227045242578772124779004756249085154188369039159690638725821245974978963371615699005072473649705367893567309027634121825164880046600125480885803891136149601797439273507802533807541605261215613891134865916295914192271736572001975016089773532547481638243'),
|
||||
gcd: BigInt('168694196579467171180863939518634764192343817610869919231900537093664715354591592262546800497540343203057121816378265655992490621138321114570420047522219942818258345349322155251835677199539229050711145144861404607171419723967136221126986330819362088262358855325306938646602003059377699727688477555163239222109')
|
||||
}
|
||||
]
|
||||
|
||||
describe('gcd', function () {
|
||||
for (const input of inputs) {
|
||||
describe(`gcd(${input.a}, ${input.b})`, function () {
|
||||
it(`should return ${input.gcd}`, function () {
|
||||
const ret = _pkg.gcd(input.a, input.b)
|
||||
chai.expect(ret).to.equal(input.gcd)
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
|
@ -1,101 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
// Every test file (you can create as many as you want) should start like this
|
||||
// Please, do NOT touch. They will be automatically removed for browser tests -->
|
||||
const _pkg = require('../lib/index.node')
|
||||
const chai = require('chai')
|
||||
// <--
|
||||
|
||||
const numbers = [
|
||||
{
|
||||
value: BigInt(1),
|
||||
prime: false,
|
||||
iterations: 16,
|
||||
workers: false
|
||||
},
|
||||
{
|
||||
value: BigInt(2),
|
||||
prime: true,
|
||||
iterations: 16,
|
||||
workers: false
|
||||
},
|
||||
{
|
||||
value: 3,
|
||||
prime: true,
|
||||
iterations: 16,
|
||||
workers: false
|
||||
},
|
||||
{
|
||||
value: BigInt(15),
|
||||
prime: false,
|
||||
iterations: 32,
|
||||
workers: false
|
||||
},
|
||||
{
|
||||
value: 29,
|
||||
prime: true,
|
||||
iterations: 16,
|
||||
workers: false
|
||||
},
|
||||
{
|
||||
value: BigInt('669483106578092405936560831017556154622901950048903016651289'),
|
||||
prime: true,
|
||||
iterations: 24,
|
||||
workers: false
|
||||
},
|
||||
{
|
||||
value: BigInt('2074722246773485207821695222107608587480996474721117292752992589912196684750549658310084416732550077'),
|
||||
prime: true,
|
||||
iterations: 16,
|
||||
workers: false
|
||||
},
|
||||
{
|
||||
value: BigInt('2074722246773485207821695222107608587480996474721117292752992589912196684750549658310084416732550079'),
|
||||
prime: false,
|
||||
iterations: 16,
|
||||
workers: false
|
||||
},
|
||||
{
|
||||
value: BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777'),
|
||||
prime: true,
|
||||
iterations: 24,
|
||||
workers: true
|
||||
},
|
||||
{
|
||||
value: BigInt('168694196579467171180863939518634764192343817610869919231900537093664715354591592262546800497540343203057121816378265655992490621138321114570420047522219942818258345349322155251835677199539229050711145144861404607171419723967136221126986330819362088262358855325306938646602003059377699727688477555163239222109') * BigInt('144678545212641449725111562354371812236197961234111744040227045242578772124779004756249085154188369039159690638725821245974978963371615699005072473649705367893567309027634121825164880046600125480885803891136149601797439273507802533807541605261215613891134865916295914192271736572001975016089773532547481638243'),
|
||||
prime: false,
|
||||
iterations: 16,
|
||||
workers: true
|
||||
},
|
||||
{
|
||||
value: BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203'),
|
||||
prime: true,
|
||||
iterations: 16,
|
||||
workers: true
|
||||
},
|
||||
{
|
||||
value: BigInt('940719693126280825126763871881743336375040232953039527942717290104060740215493004508206768342926022549956464101136893240409560470269654765366248516968645294076406953865805712688760371102637642013723011744011617678651884521901163090779813242269935310225049805992299292275574585773507915278612311449919050091057023179541184986547995894821648553256021675133997240195429424258757033557367142630663053464438840832073753440939208165158795269598771598124509831433327480118038278887538430675994497384283550890544882369140852048496460551123626856255619494025370171790720106325655890348475483349150258338517508459674722099347335608814922179633411167540545786247819334838979610017735984374883325689517847175539632896026875016305529321705457954181425405794479825617747354596485074451489940385640535898876551301296003465792117006135339109817937663957519031436646579178503423889430062127572272773511424424297800355292430651838502733756881154935252456036638082486459287411002911323257940893413982671660332662880068976408321968046549017547143836993553556640198884769590214676797037397502067035957959952990027503148987727895561468097917730167320715053689862847457761993196945361244822787209076446259359976421264285658106819879849052247546957718175231'),
|
||||
prime: false,
|
||||
iterations: 16,
|
||||
workers: true
|
||||
}
|
||||
]
|
||||
|
||||
describe('isProbablyPrime', function () {
|
||||
this.timeout(90000)
|
||||
for (const num of numbers) {
|
||||
describe(`isProbablyPrime(${num.value}, ${num.iterations}, ${!num.workers})`, function () {
|
||||
it(`should return ${num.prime}`, async function () {
|
||||
let ret
|
||||
if (num.iterations === 16 && num.workers) ret = await _pkg.isProbablyPrime(num.value)
|
||||
else ret = await _pkg.isProbablyPrime(num.value, num.iterations, !num.workers)
|
||||
chai.expect(ret).to.equal(num.prime)
|
||||
})
|
||||
})
|
||||
}
|
||||
describe('isProbablyPrime(-1)', function () {
|
||||
it('should throw RangeError', function () {
|
||||
chai.expect(() => _pkg.isProbablyPrime(-1)).to.throw(RangeError)
|
||||
})
|
||||
})
|
||||
})
|
|
@ -0,0 +1,93 @@
|
|||
describe('isProbablyPrime', function () {
|
||||
this.timeout(90000)
|
||||
const numbers = [
|
||||
{
|
||||
value: BigInt(1),
|
||||
prime: false,
|
||||
iterations: 16,
|
||||
workers: false
|
||||
},
|
||||
{
|
||||
value: BigInt(2),
|
||||
prime: true,
|
||||
iterations: 16,
|
||||
workers: false
|
||||
},
|
||||
{
|
||||
value: 3,
|
||||
prime: true,
|
||||
iterations: 16,
|
||||
workers: false
|
||||
},
|
||||
{
|
||||
value: BigInt(15),
|
||||
prime: false,
|
||||
iterations: 32,
|
||||
workers: false
|
||||
},
|
||||
{
|
||||
value: 29,
|
||||
prime: true,
|
||||
iterations: 16,
|
||||
workers: false
|
||||
},
|
||||
{
|
||||
value: BigInt('669483106578092405936560831017556154622901950048903016651289'),
|
||||
prime: true,
|
||||
iterations: 24,
|
||||
workers: false
|
||||
},
|
||||
{
|
||||
value: BigInt('2074722246773485207821695222107608587480996474721117292752992589912196684750549658310084416732550077'),
|
||||
prime: true,
|
||||
iterations: 16,
|
||||
workers: false
|
||||
},
|
||||
{
|
||||
value: BigInt('2074722246773485207821695222107608587480996474721117292752992589912196684750549658310084416732550079'),
|
||||
prime: false,
|
||||
iterations: 16,
|
||||
workers: false
|
||||
},
|
||||
{
|
||||
value: BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777'),
|
||||
prime: true,
|
||||
iterations: 24,
|
||||
workers: true
|
||||
},
|
||||
{
|
||||
value: BigInt('168694196579467171180863939518634764192343817610869919231900537093664715354591592262546800497540343203057121816378265655992490621138321114570420047522219942818258345349322155251835677199539229050711145144861404607171419723967136221126986330819362088262358855325306938646602003059377699727688477555163239222109') * BigInt('144678545212641449725111562354371812236197961234111744040227045242578772124779004756249085154188369039159690638725821245974978963371615699005072473649705367893567309027634121825164880046600125480885803891136149601797439273507802533807541605261215613891134865916295914192271736572001975016089773532547481638243'),
|
||||
prime: false,
|
||||
iterations: 16,
|
||||
workers: true
|
||||
},
|
||||
{
|
||||
value: BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203'),
|
||||
prime: true,
|
||||
iterations: 16,
|
||||
workers: true
|
||||
},
|
||||
{
|
||||
value: BigInt('940719693126280825126763871881743336375040232953039527942717290104060740215493004508206768342926022549956464101136893240409560470269654765366248516968645294076406953865805712688760371102637642013723011744011617678651884521901163090779813242269935310225049805992299292275574585773507915278612311449919050091057023179541184986547995894821648553256021675133997240195429424258757033557367142630663053464438840832073753440939208165158795269598771598124509831433327480118038278887538430675994497384283550890544882369140852048496460551123626856255619494025370171790720106325655890348475483349150258338517508459674722099347335608814922179633411167540545786247819334838979610017735984374883325689517847175539632896026875016305529321705457954181425405794479825617747354596485074451489940385640535898876551301296003465792117006135339109817937663957519031436646579178503423889430062127572272773511424424297800355292430651838502733756881154935252456036638082486459287411002911323257940893413982671660332662880068976408321968046549017547143836993553556640198884769590214676797037397502067035957959952990027503148987727895561468097917730167320715053689862847457761993196945361244822787209076446259359976421264285658106819879849052247546957718175231'),
|
||||
prime: false,
|
||||
iterations: 16,
|
||||
workers: true
|
||||
}
|
||||
]
|
||||
|
||||
for (const num of numbers) {
|
||||
describe(`isProbablyPrime(${num.value}, ${num.iterations}, ${String(!num.workers)})`, function () {
|
||||
it(`should return ${String(num.prime)}`, async function () {
|
||||
let ret
|
||||
if (num.iterations === 16 && num.workers) ret = await _pkg.isProbablyPrime(num.value)
|
||||
else ret = await _pkg.isProbablyPrime(num.value, num.iterations, !num.workers)
|
||||
chai.expect(ret).to.equal(num.prime)
|
||||
})
|
||||
})
|
||||
}
|
||||
describe('isProbablyPrime(-1)', function () {
|
||||
it('should throw RangeError', function () {
|
||||
chai.expect(() => _pkg.isProbablyPrime(-1)).to.throw(RangeError) // eslint-disable-line
|
||||
})
|
||||
})
|
||||
})
|
51
test/lcm.js
51
test/lcm.js
|
@ -1,51 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
// Every test file (you can create as many as you want) should start like this
|
||||
// Please, do NOT touch. They will be automatically removed for browser tests -->
|
||||
const _pkg = require('../lib/index.node')
|
||||
const chai = require('chai')
|
||||
// <--
|
||||
|
||||
const inputs = [
|
||||
{
|
||||
a: BigInt(0),
|
||||
b: BigInt(0),
|
||||
lcm: BigInt(0)
|
||||
},
|
||||
{
|
||||
a: BigInt(1),
|
||||
b: BigInt(1),
|
||||
lcm: BigInt(1)
|
||||
},
|
||||
{
|
||||
a: BigInt(1),
|
||||
b: BigInt('14546149867129487614601346814'),
|
||||
lcm: BigInt('14546149867129487614601346814')
|
||||
},
|
||||
{
|
||||
a: BigInt(27),
|
||||
b: BigInt(18),
|
||||
lcm: BigInt(27) * BigInt(2)
|
||||
},
|
||||
{
|
||||
a: BigInt(-27),
|
||||
b: BigInt(18),
|
||||
lcm: BigInt(27) * BigInt(2)
|
||||
},
|
||||
{
|
||||
a: BigInt('168694196579467171180863939518634764192343817610869919231900537093664715354591592262546800497540343203057121816378265655992490621138321114570420047522219942818258345349322155251835677199539229050711145144861404607171419723967136221126986330819362088262358855325306938646602003059377699727688477555163239222109'),
|
||||
b: BigInt('168694196579467171180863939518634764192343817610869919231900537093664715354591592262546800497540343203057121816378265655992490621138321114570420047522219942818258345349322155251835677199539229050711145144861404607171419723967136221126986330819362088262358855325306938646602003059377699727688477555163239222109') * BigInt('144678545212641449725111562354371812236197961234111744040227045242578772124779004756249085154188369039159690638725821245974978963371615699005072473649705367893567309027634121825164880046600125480885803891136149601797439273507802533807541605261215613891134865916295914192271736572001975016089773532547481638243'),
|
||||
lcm: BigInt('168694196579467171180863939518634764192343817610869919231900537093664715354591592262546800497540343203057121816378265655992490621138321114570420047522219942818258345349322155251835677199539229050711145144861404607171419723967136221126986330819362088262358855325306938646602003059377699727688477555163239222109') * BigInt('144678545212641449725111562354371812236197961234111744040227045242578772124779004756249085154188369039159690638725821245974978963371615699005072473649705367893567309027634121825164880046600125480885803891136149601797439273507802533807541605261215613891134865916295914192271736572001975016089773532547481638243')
|
||||
}
|
||||
]
|
||||
|
||||
describe('lcm', function () {
|
||||
for (const input of inputs) {
|
||||
describe(`lcm(${input.a}, ${input.b})`, function () {
|
||||
it(`should return ${input.lcm}`, function () {
|
||||
const ret = _pkg.lcm(input.a, input.b)
|
||||
chai.expect(ret).to.equal(input.lcm)
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
93
test/max.js
93
test/max.js
|
@ -1,93 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
// Every test file (you can create as many as you want) should start like this
|
||||
// Please, do NOT touch. They will be automatically removed for browser tests -->
|
||||
const _pkg = require('../lib/index.node')
|
||||
const chai = require('chai')
|
||||
// <--
|
||||
|
||||
const inputs = [
|
||||
{
|
||||
value: [BigInt(1), BigInt(2)],
|
||||
max: BigInt(2)
|
||||
},
|
||||
{
|
||||
value: [BigInt(2), BigInt(1)],
|
||||
max: BigInt(2)
|
||||
},
|
||||
{
|
||||
value: [BigInt(2), BigInt(2)],
|
||||
max: BigInt(2)
|
||||
},
|
||||
{
|
||||
value: [BigInt(1), BigInt(-2)],
|
||||
max: BigInt(1)
|
||||
},
|
||||
{
|
||||
value: [BigInt(-2), BigInt(1)],
|
||||
max: BigInt(1)
|
||||
},
|
||||
{
|
||||
value: [BigInt(-2), BigInt(-2)],
|
||||
max: BigInt(-2)
|
||||
},
|
||||
{
|
||||
value: [BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252'), BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777')],
|
||||
max: BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252')
|
||||
},
|
||||
{
|
||||
value: [BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777'), BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252')],
|
||||
max: BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252')
|
||||
},
|
||||
{
|
||||
value: [BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777'), BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777')],
|
||||
max: BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777')
|
||||
},
|
||||
{
|
||||
value: [BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252'), BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777')],
|
||||
max: BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777')
|
||||
},
|
||||
{
|
||||
value: [BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777'), BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252')],
|
||||
max: BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777')
|
||||
},
|
||||
{
|
||||
value: [BigInt('-115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777'), BigInt('-115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777')],
|
||||
max: BigInt('-115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777')
|
||||
},
|
||||
{
|
||||
value: [BigInt('94120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203'), BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')],
|
||||
max: BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')
|
||||
},
|
||||
{
|
||||
value: [BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203'), BigInt('918145974144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')],
|
||||
max: BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')
|
||||
},
|
||||
{
|
||||
value: [BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203'), BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')],
|
||||
max: BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')
|
||||
},
|
||||
{
|
||||
value: [BigInt('94120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203'), BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')],
|
||||
max: BigInt('94120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')
|
||||
},
|
||||
{
|
||||
value: [BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203'), BigInt('918145974144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')],
|
||||
max: BigInt('918145974144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')
|
||||
},
|
||||
{
|
||||
value: [BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203'), BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')],
|
||||
max: BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')
|
||||
}
|
||||
]
|
||||
|
||||
describe('max', function () {
|
||||
for (const input of inputs) {
|
||||
describe(`max(${input.value[0]}, ${input.value[1]})`, function () {
|
||||
it(`should return ${input.max}`, function () {
|
||||
const ret = _pkg.max(input.value[0], input.value[1])
|
||||
chai.expect(ret).to.equal(input.max)
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
93
test/min.js
93
test/min.js
|
@ -1,93 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
// Every test file (you can create as many as you want) should start like this
|
||||
// Please, do NOT touch. They will be automatically removed for browser tests -->
|
||||
const _pkg = require('../lib/index.node')
|
||||
const chai = require('chai')
|
||||
// <--
|
||||
|
||||
const inputs = [
|
||||
{
|
||||
value: [BigInt(1), BigInt(2)],
|
||||
min: BigInt(1)
|
||||
},
|
||||
{
|
||||
value: [BigInt(2), BigInt(1)],
|
||||
min: BigInt(1)
|
||||
},
|
||||
{
|
||||
value: [BigInt(2), BigInt(2)],
|
||||
min: BigInt(2)
|
||||
},
|
||||
{
|
||||
value: [BigInt(1), BigInt(-2)],
|
||||
min: BigInt(-2)
|
||||
},
|
||||
{
|
||||
value: [BigInt(-2), BigInt(1)],
|
||||
min: BigInt(-2)
|
||||
},
|
||||
{
|
||||
value: [BigInt(-2), BigInt(-2)],
|
||||
min: BigInt(-2)
|
||||
},
|
||||
{
|
||||
value: [BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252'), BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777')],
|
||||
min: BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777')
|
||||
},
|
||||
{
|
||||
value: [BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777'), BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252')],
|
||||
min: BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777')
|
||||
},
|
||||
{
|
||||
value: [BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777'), BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777')],
|
||||
min: BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777')
|
||||
},
|
||||
{
|
||||
value: [BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252'), BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777')],
|
||||
min: BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252')
|
||||
},
|
||||
{
|
||||
value: [BigInt('115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777'), BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252')],
|
||||
min: BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252')
|
||||
},
|
||||
{
|
||||
value: [BigInt('-115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777'), BigInt('-115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777')],
|
||||
min: BigInt('-115922179551495973383410176342643722334557255682879605864838806293659619625004303206250384392546855063844106965156287951749387634112551089284595541103692716528774876311641700929986988023197242224581099872580798960693521778607396791006450968430359009613295725905514216842343121690916290236558767890728449777')
|
||||
},
|
||||
{
|
||||
value: [BigInt('94120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203'), BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')],
|
||||
min: BigInt('94120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')
|
||||
},
|
||||
{
|
||||
value: [BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203'), BigInt('918145974144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')],
|
||||
min: BigInt('918145974144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')
|
||||
},
|
||||
{
|
||||
value: [BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203'), BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')],
|
||||
min: BigInt('918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')
|
||||
},
|
||||
{
|
||||
value: [BigInt('94120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203'), BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')],
|
||||
min: BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')
|
||||
},
|
||||
{
|
||||
value: [BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203'), BigInt('918145974144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')],
|
||||
min: BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')
|
||||
},
|
||||
{
|
||||
value: [BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203'), BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')],
|
||||
min: BigInt('-918145944120889203205646923554374144932845997937845799234617798611046542304088105084854788397071323714642587188481158334265864050544813693415594035822877094557870151480865568334936301231664228940480803192289508235412296324312748621874408067955753620604885023289655277704554716080844406284392300643321715285709865081125252390440327650852470312931679380011885102491340191287595160450544053114365852338670819405357496612993587404998677760882578064637552397840566752638770525765833183986360029736508910848408875329873614164495552615086579144675027852136994842529623698055210822311666048300438808691619782893307972452223713060928388502843564836966586109748062827799521852219158489504529458627699284110902303538160168376473182639384638674469114371472053977558648090155686345760457454061117853710619580819749222459422610617170567016772342291486643520567969321969827786373531753524990712622940069883277763528926899970596407140603912036918433859986491820017690762751824769335720368488097262208835708414085501930989486498185503469986946236128468697606998536541209764920494156326791142098506801288127033229779646920082892258428128572765585196779698362187479280520327053508580551167899837393726371144977951402741307021389967382422805567365901203')
|
||||
}
|
||||
]
|
||||
|
||||
describe('min', function () {
|
||||
for (const input of inputs) {
|
||||
describe(`min(${input.value[0]}, ${input.value[1]})`, function () {
|
||||
it(`should return ${input.min}`, function () {
|
||||
const ret = _pkg.min(input.value[0], input.value[1])
|
||||
chai.expect(ret).to.equal(input.min)
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
|
@ -1,63 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
// Every test file (you can create as many as you want) should start like this
|
||||
// Please, do NOT touch. They will be automatically removed for browser tests -->
|
||||
const _pkg = require('../lib/index.node')
|
||||
const chai = require('chai')
|
||||
// <--
|
||||
|
||||
const inputs = [
|
||||
{
|
||||
a: BigInt(1),
|
||||
n: BigInt(19),
|
||||
modInv: BigInt(1)
|
||||
},
|
||||
{
|
||||
a: BigInt(2),
|
||||
n: BigInt(5),
|
||||
modInv: BigInt(3)
|
||||
},
|
||||
{
|
||||
a: BigInt(-2),
|
||||
n: BigInt(5),
|
||||
modInv: BigInt(2)
|
||||
}]
|
||||
|
||||
const invalidInputs = [
|
||||
{
|
||||
a: BigInt(2),
|
||||
n: BigInt(4)
|
||||
},
|
||||
{
|
||||
a: BigInt(0),
|
||||
n: BigInt(0)
|
||||
},
|
||||
{
|
||||
a: BigInt(0),
|
||||
n: BigInt(37)
|
||||
}
|
||||
]
|
||||
|
||||
describe('modInv', function () {
|
||||
for (const input of inputs) {
|
||||
describe(`modInv(${input.a}, ${input.n})`, function () {
|
||||
it(`should return ${input.modInv}`, function () {
|
||||
const ret = _pkg.modInv(input.a, input.n)
|
||||
// chai.assert( String(ret) === String(input.modInv) );
|
||||
chai.expect(String(ret)).to.be.equal(String(input.modInv))
|
||||
})
|
||||
})
|
||||
}
|
||||
for (const input of invalidInputs) {
|
||||
describe(`modInv(${input.a}, ${input.n})`, function () {
|
||||
it('should throw RangeError', function () {
|
||||
try {
|
||||
_pkg.modInv(input.a, input.n)
|
||||
throw new Error('should have failed')
|
||||
} catch (err) {
|
||||
chai.expect(err).to.be.instanceOf(RangeError)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
|
@ -1,83 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
// Every test file (you can create as many as you want) should start like this
|
||||
// Please, do NOT touch. They will be automatically removed for browser tests -->
|
||||
const _pkg = require('../lib/index.node')
|
||||
const chai = require('chai')
|
||||
// <--
|
||||
|
||||
const inputs = [
|
||||
{
|
||||
a: BigInt(4),
|
||||
b: BigInt(-1),
|
||||
n: BigInt(1),
|
||||
modPow: BigInt(0)
|
||||
},
|
||||
{
|
||||
a: BigInt(4),
|
||||
b: BigInt(-1),
|
||||
n: BigInt(19),
|
||||
modPow: BigInt(5)
|
||||
},
|
||||
{
|
||||
a: BigInt(-5),
|
||||
b: BigInt(2),
|
||||
n: BigInt(7),
|
||||
modPow: BigInt(4)
|
||||
},
|
||||
{
|
||||
a: BigInt(2),
|
||||
b: BigInt(255),
|
||||
n: BigInt(64),
|
||||
modPow: BigInt(0)
|
||||
},
|
||||
{
|
||||
a: BigInt(3),
|
||||
b: BigInt(3),
|
||||
n: BigInt(25),
|
||||
modPow: BigInt(2)
|
||||
}]
|
||||
|
||||
const invalidInputs = [
|
||||
{
|
||||
a: BigInt(4),
|
||||
b: BigInt(-1),
|
||||
n: BigInt(0)
|
||||
}
|
||||
]
|
||||
|
||||
describe('modPow', function () {
|
||||
this.timeout(90000)
|
||||
for (const input of inputs) {
|
||||
describe(`modPow(${input.a}, ${input.b}, ${input.n})`, function () {
|
||||
it(`should return ${input.modPow}`, function () {
|
||||
const ret = _pkg.modPow(input.a, input.b, input.n)
|
||||
chai.expect(String(ret)).to.equal(String(input.modPow))
|
||||
})
|
||||
})
|
||||
}
|
||||
for (const input of invalidInputs) {
|
||||
describe(`modPow(${input.a}, ${input.b}, ${input.n})`, function () {
|
||||
it('should throw RangeError', function () {
|
||||
try {
|
||||
_pkg.modPow(input.a, input.b, input.n)
|
||||
throw new Error('should have failed')
|
||||
} catch (err) {
|
||||
chai.expect(err).to.be.instanceOf(RangeError)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
describe('Time profiling', function () {
|
||||
let iterations = 500
|
||||
it(`just testing ${iterations} iterations of a big modular exponentiation (1024 bits)`, function () {
|
||||
const p = BigInt('103920301461718841589267304263845359224454055603847417021399996422142529929535423886894599506329362009085557636432288745748144369296043048325513558512136442971686130986388589421125262751724362880217790112013162815676017250234401214198365302142787009943498370856167174244675719638815809347261773472114842038647')
|
||||
const b = BigInt('313632271690673451924314047671460131678794095260951233878123501752357966284491455239133687519908410656818506813151659324961829045286402303082891913186909806785080978448037486178337722667190743610785429936585699831407575170854873682955317589189564880931807976657385223632835801016017549762825562427694700595')
|
||||
const e = BigInt('452149997592306202232720864363485824701879487303880767747217308770351197801836846325633986474037061753983278534192061455638289551714281047915315943771002615269860312318606105460307037327329178890486613832051027105330475852552183444938408408863970975090778239473049899109989825645608770309107015209564444316')
|
||||
while (iterations > 0) {
|
||||
_pkg.modPow(b, e, p)
|
||||
iterations--
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
|
@ -1,12 +1,5 @@
|
|||
'use strict'
|
||||
|
||||
// Every test file (you can create as many as you want) should start like this
|
||||
// Please, do NOT touch. They will be automatically removed for browser tests -->
|
||||
const _pkg = require('../lib/index.node')
|
||||
const chai = require('chai')
|
||||
// <--
|
||||
|
||||
const bitLengths = [
|
||||
describe('Testing prime generation', function () {
|
||||
const bitLengths = [
|
||||
0,
|
||||
8,
|
||||
255,
|
||||
|
@ -16,9 +9,7 @@ const bitLengths = [
|
|||
1024,
|
||||
2048,
|
||||
3072
|
||||
]
|
||||
|
||||
describe('Testing prime generation', function () {
|
||||
]
|
||||
this.timeout(120000)
|
||||
for (const bitLength of bitLengths) {
|
||||
describe(`prime(${bitLength})`, function () {
|
||||
|
@ -28,8 +19,8 @@ describe('Testing prime generation', function () {
|
|||
chai.expect(_pkg.bitLength(prime)).to.equal(bitLength)
|
||||
})
|
||||
} else {
|
||||
it('should throw error', async function () {
|
||||
chai.expect(() => _pkg.prime(bitLength)).to.throw(RangeError)
|
||||
it('should throw error', function () {
|
||||
chai.expect(() => _pkg.prime(bitLength)).to.throw(RangeError) // eslint-disable-line
|
||||
})
|
||||
}
|
||||
})
|
|
@ -1,12 +1,5 @@
|
|||
'use strict'
|
||||
|
||||
// Every test file (you can create as many as you want) should start like this
|
||||
// Please, do NOT touch. They will be automatically removed for browser tests -->
|
||||
const _pkg = require('../lib/index.node')
|
||||
const chai = require('chai')
|
||||
// <--
|
||||
|
||||
const numbers = [
|
||||
describe('randBetween', function () {
|
||||
const numbers = [
|
||||
{
|
||||
min: BigInt(1),
|
||||
max: BigInt(2) ** BigInt(234),
|
||||
|
@ -49,9 +42,7 @@ const numbers = [
|
|||
error: true,
|
||||
errorMax: true
|
||||
}
|
||||
]
|
||||
|
||||
describe('randBetween', function () {
|
||||
]
|
||||
this.timeout(90000)
|
||||
for (const num of numbers) {
|
||||
describe(`randBetween(${num.max}, ${num.min})`, function () {
|
|
@ -1,16 +1,8 @@
|
|||
'use strict'
|
||||
|
||||
// Every test file (you can create as many as you want) should start like this
|
||||
// Please, do NOT touch. They will be automatically removed for browser tests -->
|
||||
const _pkg = require('../lib/index.node')
|
||||
const chai = require('chai')
|
||||
// <--
|
||||
|
||||
const iterations = 10
|
||||
const bitLengths = [-1, 0, 3, 8, 16, 511, 2048]
|
||||
const byteLengths = [-7, 0, 1, 8, 33, 40]
|
||||
|
||||
describe('testing randBits', async function () {
|
||||
describe('testing randBits', function () {
|
||||
for (const bitLength of bitLengths) {
|
||||
describe(`${iterations} iterations of randBitsSync(${bitLength})`, function () {
|
||||
if (bitLength > 0) {
|
||||
|
@ -35,7 +27,7 @@ describe('testing randBits', async function () {
|
|||
})
|
||||
}
|
||||
})
|
||||
describe(`${iterations} iterations of randBits(${bitLength})`, async function () {
|
||||
describe(`${iterations} iterations of randBits(${bitLength})`, function () {
|
||||
if (bitLength > 0) {
|
||||
it('should return buffers', async function () {
|
||||
let ret = true
|
||||
|
@ -54,14 +46,14 @@ describe('testing randBits', async function () {
|
|||
})
|
||||
} else {
|
||||
it('should throw RangeError', function () {
|
||||
chai.expect(() => _pkg.randBits(bitLength)).to.throw(RangeError)
|
||||
chai.expect(() => _pkg.randBits(bitLength)).to.throw(RangeError) // eslint-disable-line
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
describe('testing randBytes', async function () {
|
||||
describe('testing randBytes', function () {
|
||||
for (const byteLength of byteLengths) {
|
||||
describe(`${iterations} iterations of randBytesSync(${byteLength})`, function () {
|
||||
if (byteLength > 0) {
|
||||
|
@ -85,7 +77,7 @@ describe('testing randBytes', async function () {
|
|||
})
|
||||
}
|
||||
})
|
||||
describe(`${iterations} iterations of randBytes(${byteLength})`, async function () {
|
||||
describe(`${iterations} iterations of randBytes(${byteLength})`, function () {
|
||||
if (byteLength > 0) {
|
||||
it('should return buffers', async function () {
|
||||
let ret = true
|
||||
|
@ -103,7 +95,7 @@ describe('testing randBytes', async function () {
|
|||
})
|
||||
} else {
|
||||
it('should throw RangeError', function () {
|
||||
chai.expect(() => _pkg.randBytes(byteLength)).to.throw(RangeError)
|
||||
chai.expect(() => _pkg.randBytes(byteLength)).to.throw(RangeError) // eslint-disable-line
|
||||
})
|
||||
}
|
||||
})
|
36
test/toZn.js
36
test/toZn.js
|
@ -1,36 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
// Every test file (you can create as many as you want) should start like this
|
||||
// Please, do NOT touch. They will be automatically removed for browser tests -->
|
||||
const _pkg = require('../lib/index.node')
|
||||
const chai = require('chai')
|
||||
// <--
|
||||
|
||||
const inputs = [
|
||||
{
|
||||
a: BigInt(1),
|
||||
n: BigInt(19),
|
||||
toZn: BigInt(1)
|
||||
},
|
||||
{
|
||||
a: BigInt(-25),
|
||||
n: BigInt(9),
|
||||
toZn: BigInt(2)
|
||||
},
|
||||
{
|
||||
a: BigInt('12359782465012847510249'),
|
||||
n: BigInt(5),
|
||||
toZn: BigInt(4)
|
||||
}
|
||||
]
|
||||
|
||||
describe('toZn', function () {
|
||||
for (const input of inputs) {
|
||||
describe(`toZn(${input.a}, ${input.n})`, function () {
|
||||
it(`should return ${input.toZn}`, function () {
|
||||
const ret = _pkg.toZn(input.a, input.n)
|
||||
chai.expect(ret).to.equal(input.toZn)
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"compilerOptions": {
|
||||
"target": "es2020", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
|
||||
"lib": [ "es2020", "DOM" , "WebWorker"], /* Specify library files to be included in the compilation. */
|
||||
"allowJs": true, /* Allow javascript files to be compiled. */
|
||||
"checkJs": true, /* Report errors in .js files. */
|
||||
// "jsx": "preserve", /* Specify JSX code generation: 'react', 'react-jsx', 'react-jsxdev', 'preserve' or 'react-native'. */
|
||||
"strict": true, /* Enable all strict type-checking options. */
|
||||
|
||||
/* Additional Checks */
|
||||
// "noUnusedLocals": true, /* Report errors on unused locals. */
|
||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
||||
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
|
||||
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
|
||||
// "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
|
||||
|
||||
/* Module Resolution Options */
|
||||
"moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
|
||||
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
|
||||
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
|
||||
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
|
||||
"typeRoots": [ "./build/typings", "./node_modules/@types" ], /* List of folders to include type definitions from. */
|
||||
// "types": [], /* Type declaration files to be included in compilation. */
|
||||
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
|
||||
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
|
||||
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
|
||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||
|
||||
/* Experimental Options */
|
||||
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
|
||||
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
|
||||
|
||||
/* Advanced Options */
|
||||
"skipLibCheck": true, /* Skip type checking of declaration files. */
|
||||
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
|
||||
},
|
||||
"include": ["src/**/*", "build/typings/**/*", "test/**/*"]
|
||||
}
|
|
@ -1,198 +0,0 @@
|
|||
/**
|
||||
* A triple (g, x, y), such that ax + by = g = gcd(a, b).
|
||||
*/
|
||||
export type egcdReturn = {
|
||||
g: bigint;
|
||||
x: bigint;
|
||||
y: bigint;
|
||||
};
|
||||
/**
|
||||
* Absolute value. abs(a)==a if a>=0. abs(a)==-a if a<0
|
||||
*
|
||||
* @param {number|bigint} a
|
||||
*
|
||||
* @returns {bigint} the absolute value of a
|
||||
*/
|
||||
export function abs(a: number | bigint): bigint;
|
||||
/**
|
||||
* Returns the bitlength of a number
|
||||
*
|
||||
* @param {number|bigint} a
|
||||
* @returns {number} - the bit length
|
||||
*/
|
||||
export function bitLength(a: number | bigint): number;
|
||||
/**
|
||||
* @typedef {Object} egcdReturn A triple (g, x, y), such that ax + by = g = gcd(a, b).
|
||||
* @property {bigint} g
|
||||
* @property {bigint} x
|
||||
* @property {bigint} y
|
||||
*/
|
||||
/**
|
||||
* 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).
|
||||
*
|
||||
* @param {number|bigint} a
|
||||
* @param {number|bigint} b
|
||||
*
|
||||
* @throws {RangeError} a and b MUST be > 0
|
||||
*
|
||||
* @returns {egcdReturn} A triple (g, x, y), such that ax + by = g = gcd(a, b).
|
||||
*/
|
||||
export function eGcd(a: number | bigint, b: number | bigint): egcdReturn;
|
||||
/**
|
||||
* Greatest-common divisor of two integers based on the iterative binary algorithm.
|
||||
*
|
||||
* @param {number|bigint} a
|
||||
* @param {number|bigint} b
|
||||
*
|
||||
* @returns {bigint} The greatest common divisor of a and b
|
||||
*/
|
||||
export function gcd(a: number | bigint, b: number | bigint): bigint;
|
||||
/**
|
||||
* 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)
|
||||
*
|
||||
* @param {number | bigint} w A positive integer to be tested for primality
|
||||
* @param {number} [iterations = 16] The number of iterations for the primality test. The value shall be consistent with Table C.1, C.2 or C.3
|
||||
* @param {boolean} [disableWorkers = false] Disable the use of workers for the primality test
|
||||
*
|
||||
* @throws {RangeError} w MUST be >= 0
|
||||
*
|
||||
* @returns {Promise<boolean>} A promise that resolves to a boolean that is either true (a probably prime number) or false (definitely composite)
|
||||
*/
|
||||
export function isProbablyPrime(w: number | bigint, iterations?: number, disableWorkers?: boolean): Promise<boolean>;
|
||||
/**
|
||||
* The least common multiple computed as abs(a*b)/gcd(a,b)
|
||||
* @param {number|bigint} a
|
||||
* @param {number|bigint} b
|
||||
*
|
||||
* @returns {bigint} The least common multiple of a and b
|
||||
*/
|
||||
export function lcm(a: number | bigint, b: number | bigint): bigint;
|
||||
/**
|
||||
* Maximum. max(a,b)==a if a>=b. max(a,b)==b if a<=b
|
||||
*
|
||||
* @param {number|bigint} a
|
||||
* @param {number|bigint} b
|
||||
*
|
||||
* @returns {bigint} maximum of numbers a and b
|
||||
*/
|
||||
export function max(a: number | bigint, b: number | bigint): bigint;
|
||||
/**
|
||||
* Minimum. min(a,b)==b if a>=b. min(a,b)==a if a<=b
|
||||
*
|
||||
* @param {number|bigint} a
|
||||
* @param {number|bigint} b
|
||||
*
|
||||
* @returns {bigint} minimum of numbers a and b
|
||||
*/
|
||||
export function min(a: number | bigint, b: number | bigint): bigint;
|
||||
/**
|
||||
* Modular inverse.
|
||||
*
|
||||
* @param {number|bigint} a The number to find an inverse for
|
||||
* @param {number|bigint} n The modulo
|
||||
*
|
||||
* @throws {RangeError} a does not have inverse modulo n
|
||||
*
|
||||
* @returns {bigint} the inverse modulo n
|
||||
*/
|
||||
export function modInv(a: number | bigint, n: number | bigint): bigint;
|
||||
/**
|
||||
* Modular exponentiation b**e mod n. Currently using the right-to-left binary method
|
||||
*
|
||||
* @param {number|bigint} b base
|
||||
* @param {number|bigint} e exponent
|
||||
* @param {number|bigint} n modulo
|
||||
*
|
||||
* @returns {bigint} b**e mod n
|
||||
*/
|
||||
export function modPow(b: number | bigint, e: number | bigint, n: number | bigint): bigint;
|
||||
/**
|
||||
* 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).
|
||||
* The node version can also use worker_threads if they are available (enabled by default with Node 11 and
|
||||
* and can be enabled at runtime executing node --experimental-worker with node >=10.5.0).
|
||||
*
|
||||
* @param {number} bitLength The required bit length for the generated prime
|
||||
* @param {number} [iterations = 16] The number of iterations for the Miller-Rabin Probabilistic Primality Test
|
||||
*
|
||||
* @throws {RangeError} bitLength MUST be > 0
|
||||
*
|
||||
* @returns {Promise<bigint>} A promise that resolves to a bigint probable prime of bitLength bits.
|
||||
*/
|
||||
export function prime(bitLength: number, iterations?: number): Promise<bigint>;
|
||||
/**
|
||||
* A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator.
|
||||
* The sync version is NOT RECOMMENDED since it won't use workers and thus it'll be slower and may freeze thw window in browser's javascript. Please consider using prime() instead.
|
||||
*
|
||||
* @param {number} bitLength The required bit length for the generated prime
|
||||
* @param {number} [iterations = 16] The number of iterations for the Miller-Rabin Probabilistic Primality Test
|
||||
*
|
||||
* @throws {RangeError} bitLength MUST be > 0
|
||||
*
|
||||
* @returns {bigint} A bigint probable prime of bitLength bits.
|
||||
*/
|
||||
export function primeSync(bitLength: number, iterations?: number): bigint;
|
||||
/**
|
||||
* Returns a cryptographically secure random integer between [min,max]. Both numbers must be >=0
|
||||
* @param {bigint} max Returned value will be <= max
|
||||
* @param {bigint} [min = BigInt(1)] Returned value will be >= min
|
||||
*
|
||||
* @throws {RangeError} Arguments MUST be: max > 0 && min >=0 && max > min
|
||||
*
|
||||
* @returns {bigint} A cryptographically secure random bigint between [min,max]
|
||||
*/
|
||||
export function randBetween(max: bigint, min?: bigint): bigint;
|
||||
/**
|
||||
* Secure random bits for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()
|
||||
*
|
||||
* @param {number} bitLength The desired number of random bits
|
||||
* @param {boolean} [forceLength = false] If we want to force the output to have a specific bit length. It basically forces the msb to be 1
|
||||
*
|
||||
* @throws {RangeError} bitLength MUST be > 0
|
||||
*
|
||||
* @returns {Promise<Buffer | Uint8Array>} A Promise that resolves to a Buffer/UInt8Array (Node.js/Browser) filled with cryptographically secure random bits
|
||||
*/
|
||||
export function randBits(bitLength: number, forceLength?: boolean): Promise<Buffer | Uint8Array>;
|
||||
/**
|
||||
* Secure random bits for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()
|
||||
* @param {number} bitLength The desired number of random bits
|
||||
* @param {boolean} [forceLength = false] If we want to force the output to have a specific bit length. It basically forces the msb to be 1
|
||||
*
|
||||
* @throws {RangeError} bitLength MUST be > 0
|
||||
*
|
||||
* @returns {Buffer | Uint8Array} A Buffer/UInt8Array (Node.js/Browser) filled with cryptographically secure random bits
|
||||
*/
|
||||
export function randBitsSync(bitLength: number, forceLength?: boolean): Buffer | Uint8Array;
|
||||
/**
|
||||
* Secure random bytes for both node and browsers. Node version uses crypto.randomBytes() and browser one self.crypto.getRandomValues()
|
||||
*
|
||||
* @param {number} byteLength The desired number of random bytes
|
||||
* @param {boolean} [forceLength = false] If we want to force the output to have a bit length of 8*byteLength. It basically forces the msb to be 1
|
||||
*
|
||||
* @throws {RangeError} byteLength MUST be > 0
|
||||
*
|
||||
* @returns {Promise<Buffer | Uint8Array>} A promise that resolves to a Buffer/UInt8Array (Node.js/Browser) filled with cryptographically secure random bytes
|
||||
*/
|
||||
export function randBytes(byteLength: number, forceLength?: boolean): Promise<Buffer | Uint8Array>;
|
||||
/**
|
||||
* Secure random bytes for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()
|
||||
*
|
||||
* @param {number} byteLength The desired number of random bytes
|
||||
* @param {boolean} [forceLength = false] If we want to force the output to have a bit length of 8*byteLength. It basically forces the msb to be 1
|
||||
*
|
||||
* @throws {RangeError} byteLength MUST be > 0
|
||||
*
|
||||
* @returns {Buffer | Uint8Array} A Buffer/UInt8Array (Node.js/Browser) filled with cryptographically secure random bytes
|
||||
*/
|
||||
export function randBytesSync(byteLength: number, forceLength?: boolean): Buffer | Uint8Array;
|
||||
/**
|
||||
* Finds the smallest positive element that is congruent to a in modulo n
|
||||
* @param {number|bigint} a An integer
|
||||
* @param {number|bigint} n The modulo
|
||||
*
|
||||
* @returns {bigint} The smallest positive representation of a in modulo n
|
||||
*/
|
||||
export function toZn(a: number | bigint, n: number | bigint): bigint;
|
Loading…
Reference in New Issue