coverage and coveralls. fixed minor bugs. github actions. lsbadges in README
This commit is contained in:
parent
6b1f70b625
commit
153968a5bd
|
@ -4,7 +4,7 @@ logs
|
|||
npm-debug.log*
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
node_modules
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
@ -13,4 +13,8 @@ node_modules/
|
|||
.vscode
|
||||
|
||||
# IntelliJ
|
||||
.idea/
|
||||
.idea
|
||||
|
||||
# MYC output
|
||||
.nyc_output
|
||||
coverage/*
|
||||
|
|
12
.npmignore
12
.npmignore
|
@ -19,4 +19,14 @@ npm-debug.log*
|
|||
.vscode
|
||||
|
||||
# IntelliJ
|
||||
.idea/
|
||||
.idea
|
||||
|
||||
# MYC output
|
||||
.nyc_output
|
||||
coverage/*
|
||||
|
||||
# Travis
|
||||
.travis.yml
|
||||
|
||||
# GitHub
|
||||
.github
|
15
README.md
15
README.md
|
@ -1,4 +1,7 @@
|
|||
[![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-mod-arith/workflows/Node%20CI/badge.svg)
|
||||
[![Coverage Status](https://coveralls.io/repos/github/juanelas/bigint-mod-arith/badge.svg?branch=master)](https://coveralls.io/github/juanelas/bigint-mod-arith?branch=master)
|
||||
|
||||
# bigint-mod-arith
|
||||
|
||||
|
@ -15,9 +18,9 @@ bigint-mod-arith can be imported to your project with `npm`:
|
|||
```bash
|
||||
npm install bigint-mod-arith
|
||||
```
|
||||
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-mod-arith/master/lib/index.browser.bundle.iife.js) or the [ES6 bundle module](https://raw.githubusercontent.com/juanelas/bigint-mod-arith/master/lib/index.browser.bundle.mod.js) from GitHub.
|
||||
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-mod-arith/master/lib/index.browser.bundle.iife.js) or the [ESM bundle](https://raw.githubusercontent.com/juanelas/bigint-mod-arith/master/lib/index.browser.bundle.mod.js) from the repository.
|
||||
|
||||
|
||||
## Usage example
|
||||
|
||||
|
@ -28,7 +31,7 @@ Import your module as :
|
|||
const bigintModArith = require('bigint-mod-arith')
|
||||
... // your code here
|
||||
```
|
||||
- JavaScript native or TypeScript project
|
||||
- JavaScript native or TypeScript project (including Angular and React)
|
||||
```javascript
|
||||
import * as bigintModArith from 'bigint-mod-arith'
|
||||
... // your code here
|
||||
|
@ -86,7 +89,7 @@ Some common functions for modular arithmetic using native JS implementation of B
|
|||
* [~lcm(a, b)](#module_bigint-mod-arith..lcm) ⇒ <code>bigint</code>
|
||||
* [~max(a, b)](#module_bigint-mod-arith..max) ⇒ <code>bigint</code>
|
||||
* [~min(a, b)](#module_bigint-mod-arith..min) ⇒ <code>bigint</code>
|
||||
* [~modInv(a, n)](#module_bigint-mod-arith..modInv) ⇒ <code>bigint</code>
|
||||
* [~modInv(a, n)](#module_bigint-mod-arith..modInv) ⇒ <code>bigint</code> \| <code>NaN</code>
|
||||
* [~modPow(b, e, n)](#module_bigint-mod-arith..modPow) ⇒ <code>bigint</code>
|
||||
* [~toZn(a, n)](#module_bigint-mod-arith..toZn) ⇒ <code>bigint</code>
|
||||
* [~egcdReturn](#module_bigint-mod-arith..egcdReturn) : <code>Object</code>
|
||||
|
@ -183,11 +186,11 @@ Minimum. min(a,b)==b if a>=b. min(a,b)==a if a<=b
|
|||
|
||||
<a name="module_bigint-mod-arith..modInv"></a>
|
||||
|
||||
#### bigint-mod-arith~modInv(a, n) ⇒ <code>bigint</code>
|
||||
#### bigint-mod-arith~modInv(a, n) ⇒ <code>bigint</code> \| <code>NaN</code>
|
||||
Modular inverse.
|
||||
|
||||
**Kind**: inner method of [<code>bigint-mod-arith</code>](#module_bigint-mod-arith)
|
||||
**Returns**: <code>bigint</code> - the inverse modulo n or NaN if it does not exist
|
||||
**Returns**: <code>bigint</code> \| <code>NaN</code> - the inverse modulo n or NaN if it does not exist
|
||||
|
||||
| Param | Type | Description |
|
||||
| --- | --- | --- |
|
||||
|
|
|
@ -14,12 +14,40 @@ function camelise (str) {
|
|||
})
|
||||
}
|
||||
|
||||
function getRepositoryData () {
|
||||
if (typeof pkgJson.repository === 'string') {
|
||||
const repodata = pkgJson.repository.split(/[:/]/)
|
||||
const repoProvider = repodata[0]
|
||||
if (repoProvider === 'github' || repoProvider === 'gitlab' || repoProvider === 'bitbucket') {
|
||||
return {
|
||||
repoProvider,
|
||||
repoUsername: repodata[1],
|
||||
repoName: repodata[2]
|
||||
}
|
||||
} else return null
|
||||
}
|
||||
}
|
||||
|
||||
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)`
|
||||
coverallsBadge = `[![Coverage Status](https://coveralls.io/repos/github/${repoUsername}/${repoName}/badge.svg?branch=master)](https://coveralls.io/github/${repoUsername}/${repoName}?branch=master)`
|
||||
}
|
||||
|
||||
const templateFile = path.join(rootDir, pkgJson.directories.src, 'doc', 'readme-template.md')
|
||||
const template = fs.readFileSync(templateFile, { encoding: 'UTF-8' })
|
||||
let template = fs.readFileSync(templateFile, { encoding: 'UTF-8' })
|
||||
.replace(/\{\{PKG_NAME\}\}/g, pkgJson.name)
|
||||
.replace(/\{\{PKG_CAMELCASE\}\}/g, camelise(pkgJson.name))
|
||||
.replace(/\{\{IIFE_BUNDLE\}\}/g, 'IIFE bundle')
|
||||
.replace(/\{\{ESM_BUNDLE\}\}/g, 'ES6 bundle module')
|
||||
.replace(/\{\{IIFE_BUNDLE\}\}/g, iifeBundle || 'IIFE bundle')
|
||||
.replace(/\{\{ESM_BUNDLE\}\}/g, esmBundle || 'ESM 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
|
||||
|
|
|
@ -1 +1 @@
|
|||
var bigintModArith=function(n){"use strict";function t(n){return(n=BigInt(n))>=0n?n:-n}function r(n,t){if((n=BigInt(n))<=0n|(t=BigInt(t))<=0n)return NaN;let r=0n,i=1n,u=1n,e=0n;for(;0n!==n;){const o=t/n,f=t%n,c=r-u*o,g=i-e*o;t=n,n=f,r=u,i=e,u=c,e=g}return{b:t,x:r,y:i}}function i(n,r){if(n=t(n),r=t(r),0n===n)return r;if(0n===r)return n;let i=0n;for(;!(1n&(n|r));)n>>=1n,r>>=1n,i++;for(;!(1n&n);)n>>=1n;do{for(;!(1n&r);)r>>=1n;if(n>r){const t=n;n=r,r=t}r-=n}while(r);return n<<i}function u(n,t){const i=r(e(n,t),t);return 1n!==i.b?NaN:e(i.x,t)}function e(n,t){return(t=BigInt(t))<=0?NaN:(n=BigInt(n)%t)<0?n+t:n}return n.abs=t,n.bitLength=function(n){if(1n===(n=BigInt(n)))return 1;let t=1;do{t++}while((n>>=1n)>1n);return t},n.eGcd=r,n.gcd=i,n.lcm=function(n,r){return n=BigInt(n),r=BigInt(r),0n===n&&0n===r?0n:t(n*r)/i(n,r)},n.max=function(n,t){return(n=BigInt(n))>=(t=BigInt(t))?n:t},n.min=function(n,t){return(n=BigInt(n))>=(t=BigInt(t))?t:n},n.modInv=u,n.modPow=function n(r,i,o){if(0n===(o=BigInt(o)))return NaN;if(1n===o)return 0n;if(r=e(r,o),(i=BigInt(i))<0n)return u(n(r,t(i),o),o);let f=1n;for(;i>0;)i%2n===1n&&(f=f*r%o),i/=2n,r=r**2n%o;return f},n.toZn=e,n}({});
|
||||
var bigintModArith=function(n){"use strict";function t(n){return(n=BigInt(n))>=0n?n:-n}function r(n,t){if((n=BigInt(n))<=0n|(t=BigInt(t))<=0n)throw new RangeError("a and b MUST be > 0");let r=0n,i=1n,e=1n,u=0n;for(;0n!==n;){const o=t/n,f=t%n,g=r-e*o,c=i-u*o;t=n,n=f,r=e,i=u,e=g,u=c}return{g:t,x:r,y:i}}function i(n,r){if(n=t(n),r=t(r),0n===n)return r;if(0n===r)return n;let i=0n;for(;!(1n&(n|r));)n>>=1n,r>>=1n,i++;for(;!(1n&n);)n>>=1n;do{for(;!(1n&r);)r>>=1n;if(n>r){const t=n;n=r,r=t}r-=n}while(r);return n<<i}function e(n,t){try{const i=r(u(n,t),t);return 1n!==i.g?NaN:u(i.x,t)}catch(n){return NaN}}function u(n,t){return(t=BigInt(t))<=0?NaN:(n=BigInt(n)%t)<0?n+t:n}return n.abs=t,n.bitLength=function(n){if(1n===(n=BigInt(n)))return 1;let t=1;do{t++}while((n>>=1n)>1n);return t},n.eGcd=r,n.gcd=i,n.lcm=function(n,r){return n=BigInt(n),r=BigInt(r),0n===n&&0n===r?BigInt(0):t(n*r)/i(n,r)},n.max=function(n,t){return(n=BigInt(n))>=(t=BigInt(t))?n:t},n.min=function(n,t){return(n=BigInt(n))>=(t=BigInt(t))?t:n},n.modInv=e,n.modPow=function n(r,i,o){if(0n===(o=BigInt(o)))return NaN;if(1n===o)return BigInt(0);if(r=u(r,o),(i=BigInt(i))<0n)return e(n(r,t(i),o),o);let f=1n;for(;i>0;)i%2n===1n&&(f=f*r%o),i/=2n,r=r**2n%o;return f},n.toZn=u,n}({});
|
||||
|
|
|
@ -1 +1 @@
|
|||
function n(n){return(n=BigInt(n))>=0n?n:-n}function t(n){if(1n===(n=BigInt(n)))return 1;let t=1;do{t++}while((n>>=1n)>1n);return t}function r(n,t){if((n=BigInt(n))<=0n|(t=BigInt(t))<=0n)return NaN;let r=0n,i=1n,u=1n,e=0n;for(;0n!==n;){const f=t/n,o=t%n,g=r-u*f,B=i-e*f;t=n,n=o,r=u,i=e,u=g,e=B}return{b:t,x:r,y:i}}function i(t,r){if(t=n(t),r=n(r),0n===t)return r;if(0n===r)return t;let i=0n;for(;!(1n&(t|r));)t>>=1n,r>>=1n,i++;for(;!(1n&t);)t>>=1n;do{for(;!(1n&r);)r>>=1n;if(t>r){const n=t;t=r,r=n}r-=t}while(r);return t<<i}function u(t,r){return t=BigInt(t),r=BigInt(r),0n===t&&0n===r?0n:n(t*r)/i(t,r)}function e(n,t){return(n=BigInt(n))>=(t=BigInt(t))?n:t}function f(n,t){return(n=BigInt(n))>=(t=BigInt(t))?t:n}function o(n,t){const i=r(B(n,t),t);return 1n!==i.b?NaN:B(i.x,t)}function g(t,r,i){if(0n===(i=BigInt(i)))return NaN;if(1n===i)return 0n;if(t=B(t,i),(r=BigInt(r))<0n)return o(g(t,n(r),i),i);let u=1n;for(;r>0;)r%2n===1n&&(u=u*t%i),r/=2n,t=t**2n%i;return u}function B(n,t){return(t=BigInt(t))<=0?NaN:(n=BigInt(n)%t)<0?n+t:n}export{n as abs,t as bitLength,r as eGcd,i as gcd,u as lcm,e as max,f as min,o as modInv,g as modPow,B as toZn};
|
||||
function n(n){return(n=BigInt(n))>=0n?n:-n}function t(n){if(1n===(n=BigInt(n)))return 1;let t=1;do{t++}while((n>>=1n)>1n);return t}function r(n,t){if((n=BigInt(n))<=0n|(t=BigInt(t))<=0n)throw new RangeError("a and b MUST be > 0");let r=0n,i=1n,e=1n,u=0n;for(;0n!==n;){const f=t/n,o=t%n,g=r-e*f,B=i-u*f;t=n,n=o,r=e,i=u,e=g,u=B}return{g:t,x:r,y:i}}function i(t,r){if(t=n(t),r=n(r),0n===t)return r;if(0n===r)return t;let i=0n;for(;!(1n&(t|r));)t>>=1n,r>>=1n,i++;for(;!(1n&t);)t>>=1n;do{for(;!(1n&r);)r>>=1n;if(t>r){const n=t;t=r,r=n}r-=t}while(r);return t<<i}function e(t,r){return t=BigInt(t),r=BigInt(r),0n===t&&0n===r?BigInt(0):n(t*r)/i(t,r)}function u(n,t){return(n=BigInt(n))>=(t=BigInt(t))?n:t}function f(n,t){return(n=BigInt(n))>=(t=BigInt(t))?t:n}function o(n,t){try{const i=r(B(n,t),t);return 1n!==i.g?NaN:B(i.x,t)}catch(n){return NaN}}function g(t,r,i){if(0n===(i=BigInt(i)))return NaN;if(1n===i)return BigInt(0);if(t=B(t,i),(r=BigInt(r))<0n)return o(g(t,n(r),i),i);let e=1n;for(;r>0;)r%2n===1n&&(e=e*t%i),r/=2n,t=t**2n%i;return e}function B(n,t){return(t=BigInt(t))<=0?NaN:(n=BigInt(n)%t)<0?n+t:n}export{n as abs,t as bitLength,r as eGcd,i as gcd,e as lcm,u as max,f as min,o as modInv,g as modPow,B as toZn};
|
||||
|
|
|
@ -49,7 +49,7 @@ function bitLength (a) {
|
|||
function eGcd (a, b) {
|
||||
a = BigInt(a)
|
||||
b = BigInt(b)
|
||||
if (a <= 0n | b <= 0n) { return NaN } // a and b MUST be positive
|
||||
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
|
||||
|
@ -69,7 +69,7 @@ function eGcd (a, b) {
|
|||
v = n
|
||||
}
|
||||
return {
|
||||
b: b,
|
||||
g: b,
|
||||
x: x,
|
||||
y: y
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ function gcd (a, b) {
|
|||
function lcm (a, b) {
|
||||
a = BigInt(a)
|
||||
b = BigInt(b)
|
||||
if (a === 0n && b === 0n) { return 0n }
|
||||
if (a === 0n && b === 0n) return BigInt(0)
|
||||
return abs(a * b) / gcd(a, b)
|
||||
}
|
||||
|
||||
|
@ -157,14 +157,18 @@ function min (a, b) {
|
|||
* @param {number|bigint} a The number to find an inverse for
|
||||
* @param {number|bigint} n The modulo
|
||||
*
|
||||
* @returns {bigint} the inverse modulo n or NaN if it does not exist
|
||||
* @returns {bigint|NaN} the inverse modulo n or NaN if it does not exist
|
||||
*/
|
||||
function modInv (a, n) {
|
||||
const egcd = eGcd(toZn(a, n), n)
|
||||
if (egcd.b !== 1n) {
|
||||
return NaN // modular inverse does not exist
|
||||
} else {
|
||||
return toZn(egcd.x, n)
|
||||
try {
|
||||
const egcd = eGcd(toZn(a, n), n)
|
||||
if (egcd.g !== 1n) {
|
||||
return NaN // modular inverse does not exist
|
||||
} else {
|
||||
return toZn(egcd.x, n)
|
||||
}
|
||||
} catch (error) {
|
||||
return NaN
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -179,7 +183,7 @@ function modInv (a, n) {
|
|||
*/
|
||||
function modPow (b, e, n) {
|
||||
n = BigInt(n)
|
||||
if (n === 0n) { return NaN } else if (n === 1n) { return 0n }
|
||||
if (n === 0n) { return NaN } else if (n === 1n) { return BigInt(0) }
|
||||
|
||||
b = toZn(b, n)
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ function bitLength (a) {
|
|||
function eGcd (a, b) {
|
||||
a = BigInt(a)
|
||||
b = BigInt(b)
|
||||
if (a <= 0n | b <= 0n) { return NaN } // a and b MUST be positive
|
||||
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
|
||||
|
@ -73,7 +73,7 @@ function eGcd (a, b) {
|
|||
v = n
|
||||
}
|
||||
return {
|
||||
b: b,
|
||||
g: b,
|
||||
x: x,
|
||||
y: y
|
||||
}
|
||||
|
@ -123,7 +123,7 @@ function gcd (a, b) {
|
|||
function lcm (a, b) {
|
||||
a = BigInt(a)
|
||||
b = BigInt(b)
|
||||
if (a === 0n && b === 0n) { return 0n }
|
||||
if (a === 0n && b === 0n) return BigInt(0)
|
||||
return abs(a * b) / gcd(a, b)
|
||||
}
|
||||
|
||||
|
@ -161,14 +161,18 @@ function min (a, b) {
|
|||
* @param {number|bigint} a The number to find an inverse for
|
||||
* @param {number|bigint} n The modulo
|
||||
*
|
||||
* @returns {bigint} the inverse modulo n or NaN if it does not exist
|
||||
* @returns {bigint|NaN} the inverse modulo n or NaN if it does not exist
|
||||
*/
|
||||
function modInv (a, n) {
|
||||
const egcd = eGcd(toZn(a, n), n)
|
||||
if (egcd.b !== 1n) {
|
||||
return NaN // modular inverse does not exist
|
||||
} else {
|
||||
return toZn(egcd.x, n)
|
||||
try {
|
||||
const egcd = eGcd(toZn(a, n), n)
|
||||
if (egcd.g !== 1n) {
|
||||
return NaN // modular inverse does not exist
|
||||
} else {
|
||||
return toZn(egcd.x, n)
|
||||
}
|
||||
} catch (error) {
|
||||
return NaN
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -183,7 +187,7 @@ function modInv (a, n) {
|
|||
*/
|
||||
function modPow (b, e, n) {
|
||||
n = BigInt(n)
|
||||
if (n === 0n) { return NaN } else if (n === 1n) { return 0n }
|
||||
if (n === 0n) { return NaN } else if (n === 1n) { return BigInt(0) }
|
||||
|
||||
b = toZn(b, n)
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
15
package.json
15
package.json
|
@ -16,7 +16,7 @@
|
|||
"license": "MIT",
|
||||
"author": {
|
||||
"name": "Juan Hernández Serrano",
|
||||
"email": "jserrano@entel.upc.edu",
|
||||
"email": "j.hernandez@upc.edu",
|
||||
"url": "https://github.com/juanelas"
|
||||
},
|
||||
"repository": "github:juanelas/bigint-mod-arith",
|
||||
|
@ -31,14 +31,16 @@
|
|||
"types": "./types"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha",
|
||||
"test": "nyc --check-coverage 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:**",
|
||||
"prepublishOnly": "npm run build"
|
||||
"preversion": "npm run build && npm run test",
|
||||
"postversion": "git push"
|
||||
},
|
||||
"standard": {
|
||||
"env": [
|
||||
|
@ -54,15 +56,16 @@
|
|||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-commonjs": "^11.0.2",
|
||||
"@rollup/plugin-commonjs": "^11.1.0",
|
||||
"@rollup/plugin-multi-entry": "^3.0.0",
|
||||
"@rollup/plugin-node-resolve": "^7.1.1",
|
||||
"@rollup/plugin-node-resolve": "^7.1.3",
|
||||
"@rollup/plugin-replace": "^2.3.1",
|
||||
"chai": "^4.2.0",
|
||||
"jsdoc-to-markdown": "^5.0.3",
|
||||
"mocha": "^7.1.1",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"rollup": "^2.3.3",
|
||||
"nyc": "^15.0.1",
|
||||
"rollup": "^2.6.1",
|
||||
"rollup-plugin-terser": "^5.3.0",
|
||||
"standard": "^14.3.3",
|
||||
"typescript": "^3.8.3"
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
[![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)
|
||||
{{GITHUB_ACTIONS_BADGES}}
|
||||
|
||||
# bigint-mod-arith
|
||||
# {{PKG_NAME}}
|
||||
|
||||
Some extra functions to work with modular arithmetic using native JS ([ES-2020](https://tc39.es/ecma262/#sec-bigint-objects)) implementation of BigInt. It can be used by any [Web Browser or webview supporting BigInt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#Browser_compatibility) and with Node.js (>=10.4.0).
|
||||
|
||||
|
@ -8,16 +10,16 @@ Some extra functions to work with modular arithmetic using native JS ([ES-2020](
|
|||
|
||||
## Installation
|
||||
|
||||
bigint-mod-arith is distributed for [web browsers and/or webviews supporting BigInt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#Browser_compatibility) as an ES6 module or an IIFE file; and for Node.js (>=10.4.0), as a CJS module.
|
||||
{{PKG_NAME}} is distributed for [web browsers and/or webviews supporting BigInt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#Browser_compatibility) as an ES6 module or an IIFE file; and for Node.js (>=10.4.0), as a CJS module.
|
||||
|
||||
bigint-mod-arith can be imported to your project with `npm`:
|
||||
{{PKG_NAME}} can be imported to your project with `npm`:
|
||||
|
||||
```bash
|
||||
npm install bigint-mod-arith
|
||||
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](https://raw.githubusercontent.com/juanelas/bigint-mod-arith/master/lib/index.browser.bundle.iife.js) or the [ES6 bundle module](https://raw.githubusercontent.com/juanelas/bigint-mod-arith/master/lib/index.browser.bundle.mod.js) from GitHub.
|
||||
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.
|
||||
|
||||
|
||||
## Usage example
|
||||
|
||||
|
@ -28,7 +30,7 @@ Import your module as :
|
|||
const {{PKG_CAMELCASE}} = require('{{PKG_NAME}}')
|
||||
... // your code here
|
||||
```
|
||||
- JavaScript native or TypeScript project
|
||||
- JavaScript native or TypeScript project (including Angular and React)
|
||||
```javascript
|
||||
import * as {{PKG_CAMELCASE}} from '{{PKG_NAME}}'
|
||||
... // your code here
|
||||
|
|
|
@ -49,7 +49,7 @@ export function bitLength (a) {
|
|||
export function eGcd (a, b) {
|
||||
a = BigInt(a)
|
||||
b = BigInt(b)
|
||||
if (a <= 0n | b <= 0n) { return NaN } // a and b MUST be positive
|
||||
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
|
||||
|
@ -69,7 +69,7 @@ export function eGcd (a, b) {
|
|||
v = n
|
||||
}
|
||||
return {
|
||||
b: b,
|
||||
g: b,
|
||||
x: x,
|
||||
y: y
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ export function gcd (a, b) {
|
|||
export function lcm (a, b) {
|
||||
a = BigInt(a)
|
||||
b = BigInt(b)
|
||||
if (a === 0n && b === 0n) { return 0n }
|
||||
if (a === 0n && b === 0n) return BigInt(0)
|
||||
return abs(a * b) / gcd(a, b)
|
||||
}
|
||||
|
||||
|
@ -157,14 +157,18 @@ export function min (a, b) {
|
|||
* @param {number|bigint} a The number to find an inverse for
|
||||
* @param {number|bigint} n The modulo
|
||||
*
|
||||
* @returns {bigint} the inverse modulo n or NaN if it does not exist
|
||||
* @returns {bigint|NaN} the inverse modulo n or NaN if it does not exist
|
||||
*/
|
||||
export function modInv (a, n) {
|
||||
const egcd = eGcd(toZn(a, n), n)
|
||||
if (egcd.b !== 1n) {
|
||||
return NaN // modular inverse does not exist
|
||||
} else {
|
||||
return toZn(egcd.x, n)
|
||||
try {
|
||||
const egcd = eGcd(toZn(a, n), n)
|
||||
if (egcd.g !== 1n) {
|
||||
return NaN // modular inverse does not exist
|
||||
} else {
|
||||
return toZn(egcd.x, n)
|
||||
}
|
||||
} catch (error) {
|
||||
return NaN
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -179,7 +183,7 @@ export function modInv (a, n) {
|
|||
*/
|
||||
export function modPow (b, e, n) {
|
||||
n = BigInt(n)
|
||||
if (n === 0n) { return NaN } else if (n === 1n) { return 0n }
|
||||
if (n === 0n) { return NaN } else if (n === 1n) { return BigInt(0) }
|
||||
|
||||
b = toZn(b, n)
|
||||
|
||||
|
|
|
@ -109,6 +109,11 @@ const inputs$2 = [
|
|||
b: BigInt(18),
|
||||
gcd: BigInt(9)
|
||||
},
|
||||
{
|
||||
a: BigInt(256),
|
||||
b: BigInt(128),
|
||||
gcd: BigInt(128)
|
||||
},
|
||||
{
|
||||
a: BigInt('168694196579467171180863939518634764192343817610869919231900537093664715354591592262546800497540343203057121816378265655992490621138321114570420047522219942818258345349322155251835677199539229050711145144861404607171419723967136221126986330819362088262358855325306938646602003059377699727688477555163239222109'),
|
||||
b: BigInt('168694196579467171180863939518634764192343817610869919231900537093664715354591592262546800497540343203057121816378265655992490621138321114570420047522219942818258345349322155251835677199539229050711145144861404607171419723967136221126986330819362088262358855325306938646602003059377699727688477555163239222109') * BigInt('144678545212641449725111562354371812236197961234111744040227045242578772124779004756249085154188369039159690638725821245974978963371615699005072473649705367893567309027634121825164880046600125480885803891136149601797439273507802533807541605261215613891134865916295914192271736572001975016089773532547481638243'),
|
||||
|
@ -134,6 +139,11 @@ describe('gcd', function () {
|
|||
// <--
|
||||
|
||||
const inputs$3 = [
|
||||
{
|
||||
a: BigInt(0),
|
||||
b: BigInt(0),
|
||||
lcm: BigInt(0)
|
||||
},
|
||||
{
|
||||
a: BigInt(1),
|
||||
b: BigInt(1),
|
||||
|
@ -382,6 +392,16 @@ const inputs$6 = [
|
|||
a: BigInt(2),
|
||||
n: BigInt(4),
|
||||
modInv: NaN
|
||||
},
|
||||
{
|
||||
a: BigInt(0),
|
||||
n: BigInt(0),
|
||||
modInv: NaN
|
||||
},
|
||||
{
|
||||
a: BigInt(0),
|
||||
n: BigInt(37),
|
||||
modInv: NaN
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -404,6 +424,18 @@ describe('modInv', function () {
|
|||
// <--
|
||||
|
||||
const inputs$7 = [
|
||||
{
|
||||
a: BigInt(4),
|
||||
b: BigInt(-1),
|
||||
n: BigInt(0),
|
||||
modPow: NaN
|
||||
},
|
||||
{
|
||||
a: BigInt(4),
|
||||
b: BigInt(-1),
|
||||
n: BigInt(1),
|
||||
modPow: BigInt(0)
|
||||
},
|
||||
{
|
||||
a: BigInt(4),
|
||||
b: BigInt(-1),
|
||||
|
@ -436,7 +468,7 @@ describe('modPow', function () {
|
|||
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(ret).to.equal(input.modPow);
|
||||
chai.expect(String(ret)).to.equal(String(input.modPow));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -42,6 +42,11 @@ const inputs = [
|
|||
b: BigInt(18),
|
||||
gcd: BigInt(9)
|
||||
},
|
||||
{
|
||||
a: BigInt(256),
|
||||
b: BigInt(128),
|
||||
gcd: BigInt(128)
|
||||
},
|
||||
{
|
||||
a: BigInt('168694196579467171180863939518634764192343817610869919231900537093664715354591592262546800497540343203057121816378265655992490621138321114570420047522219942818258345349322155251835677199539229050711145144861404607171419723967136221126986330819362088262358855325306938646602003059377699727688477555163239222109'),
|
||||
b: BigInt('168694196579467171180863939518634764192343817610869919231900537093664715354591592262546800497540343203057121816378265655992490621138321114570420047522219942818258345349322155251835677199539229050711145144861404607171419723967136221126986330819362088262358855325306938646602003059377699727688477555163239222109') * BigInt('144678545212641449725111562354371812236197961234111744040227045242578772124779004756249085154188369039159690638725821245974978963371615699005072473649705367893567309027634121825164880046600125480885803891136149601797439273507802533807541605261215613891134865916295914192271736572001975016089773532547481638243'),
|
||||
|
|
|
@ -7,6 +7,11 @@ const chai = require('chai')
|
|||
// <--
|
||||
|
||||
const inputs = [
|
||||
{
|
||||
a: BigInt(0),
|
||||
b: BigInt(0),
|
||||
lcm: BigInt(0)
|
||||
},
|
||||
{
|
||||
a: BigInt(1),
|
||||
b: BigInt(1),
|
||||
|
|
|
@ -26,6 +26,16 @@ const inputs = [
|
|||
a: BigInt(2),
|
||||
n: BigInt(4),
|
||||
modInv: NaN
|
||||
},
|
||||
{
|
||||
a: BigInt(0),
|
||||
n: BigInt(0),
|
||||
modInv: NaN
|
||||
},
|
||||
{
|
||||
a: BigInt(0),
|
||||
n: BigInt(37),
|
||||
modInv: NaN
|
||||
}
|
||||
]
|
||||
|
||||
|
|
|
@ -7,6 +7,18 @@ const chai = require('chai')
|
|||
// <--
|
||||
|
||||
const inputs = [
|
||||
{
|
||||
a: BigInt(4),
|
||||
b: BigInt(-1),
|
||||
n: BigInt(0),
|
||||
modPow: NaN
|
||||
},
|
||||
{
|
||||
a: BigInt(4),
|
||||
b: BigInt(-1),
|
||||
n: BigInt(1),
|
||||
modPow: BigInt(0)
|
||||
},
|
||||
{
|
||||
a: BigInt(4),
|
||||
b: BigInt(-1),
|
||||
|
@ -39,7 +51,7 @@ describe('modPow', function () {
|
|||
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(ret).to.equal(input.modPow)
|
||||
chai.expect(String(ret)).to.equal(String(input.modPow))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
@ -82,9 +82,9 @@ export function min(a: number | bigint, b: number | bigint): bigint;
|
|||
* @param {number|bigint} a The number to find an inverse for
|
||||
* @param {number|bigint} n The modulo
|
||||
*
|
||||
* @returns {bigint} the inverse modulo n or NaN if it does not exist
|
||||
* @returns {bigint|NaN} the inverse modulo n or NaN if it does not exist
|
||||
*/
|
||||
export function modInv(a: number | bigint, n: number | bigint): bigint;
|
||||
export function modInv(a: number | bigint, n: number | bigint): number | bigint;
|
||||
/**
|
||||
* Modular exponentiation b**e mod n. Currently using the right-to-left binary method
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue