modpow with crt; crt; modAdd; modMultiply; phi
This commit is contained in:
parent
7ae82f2c21
commit
e015a51c80
|
@ -1,4 +1,4 @@
|
|||
function n(n){return n>=0?n:-n}function t(n){if("number"==typeof n&&(n=BigInt(n)),1n===n)return 1;let t=1;do{t++;}while((n>>=1n)>1n);return t}function r(n,t){if("number"==typeof n&&(n=BigInt(n)),"number"==typeof t&&(t=BigInt(t)),n<=0n||t<=0n)throw new RangeError("a and b MUST be > 0");let r=0n,e=1n,o=1n,i=0n;for(;0n!==n;){const u=t/n,f=t%n,g=r-o*u,c=e-i*u;t=n,n=f,r=o,e=i,o=g,i=c;}return {g:t,x:r,y:e}}function e(n,t){if("number"==typeof n&&(n=BigInt(n)),"number"==typeof t&&(t=BigInt(t)),t<=0n)throw new RangeError("n must be > 0");const r=n%t;return r<0n?r+t:r}function o(n,t){const o=r(e(n,t),t);if(1n!==o.g)throw new RangeError(`${n.toString()} does not have inverse modulo ${t.toString()}`);return e(o.x,t)}function i(n,t,r){if(n.length!==t.length)throw new RangeError("The remainders and modulos arrays should have the same length");const i=r??t.reduce(((n,t)=>n*t),1n);return t.reduce(((t,r,u)=>{const f=i/r;return e(t+f*o(f,r)%i*n[u]%i,i)}),0n)}function u(t,r){let e="number"==typeof t?BigInt(n(t)):n(t),o="number"==typeof r?BigInt(n(r)):n(r);if(0n===e)return o;if(0n===o)return e;let i=0n;for(;0n===(1n&(e|o));)e>>=1n,o>>=1n,i++;for(;0n===(1n&e);)e>>=1n;do{for(;0n===(1n&o);)o>>=1n;if(e>o){const n=e;e=o,o=n;}o-=e;}while(0n!==o);return e<<i}function f(t,r){return "number"==typeof t&&(t=BigInt(t)),"number"==typeof r&&(r=BigInt(r)),0n===t&&0n===r?BigInt(0):n(t/u(t,r)*r)}function g(n,t){return n>=t?n:t}function c(n,t){return n>=t?t:n}function a(n){return n.map((n=>n[0]**(n[1]-1n)*(n[0]-1n))).reduce(((n,t)=>t*n),1n)}function s(t,r,u,f){if("number"==typeof t&&(t=BigInt(t)),"number"==typeof r&&(r=BigInt(r)),"number"==typeof u&&(u=BigInt(u)),u<=0n)throw new RangeError("n must be > 0");if(1n===u)return 0n;if(t=e(t,u),r<0n)return o(s(t,n(r),u,f),u);if(void 0!==f)return function(n,t,r,e){const o=e.map((n=>n[0]**n[1])),u=e.map((n=>a([n]))),f=u.map(((r,e)=>s(n,t%r,o[e])));return i(f,o,r)}(t,r,u,function(n){const t={};return n.forEach((n=>{if("bigint"==typeof n||"number"==typeof n){const r=String(n);void 0===t[r]?t[r]={p:BigInt(n),k:1n}:t[r].k+=1n;}else {const r=String(n[0]);void 0===t[r]?t[r]={p:BigInt(n[0]),k:BigInt(n[1])}:t[r].k+=BigInt(n[1]);}})),Object.values(t).map((n=>[n.p,n.k]))}(f));let g=1n;for(;r>0;)r%2n===1n&&(g=g*t%u),r/=2n,t=t**2n%u;return g}
|
||||
function n(n){return n>=0?n:-n}function t(n){if("number"==typeof n&&(n=BigInt(n)),1n===n)return 1;let t=1;do{t++;}while((n>>=1n)>1n);return t}function r(n,t){if("number"==typeof n&&(n=BigInt(n)),"number"==typeof t&&(t=BigInt(t)),n<=0n||t<=0n)throw new RangeError("a and b MUST be > 0");let r=0n,e=1n,o=1n,i=0n;for(;0n!==n;){const u=t/n,f=t%n,g=r-o*u,c=e-i*u;t=n,n=f,r=o,e=i,o=g,i=c;}return {g:t,x:r,y:e}}function e(n,t){if("number"==typeof n&&(n=BigInt(n)),"number"==typeof t&&(t=BigInt(t)),t<=0n)throw new RangeError("n must be > 0");const r=n%t;return r<0n?r+t:r}function o(n,t){const o=r(e(n,t),t);if(1n!==o.g)throw new RangeError(`${n.toString()} does not have inverse modulo ${t.toString()}`);return e(o.x,t)}function i(n,t,r){if(n.length!==t.length)throw new RangeError("The remainders and modulos arrays should have the same length");const i=r??t.reduce(((n,t)=>n*t),1n);return t.reduce(((t,r,u)=>{const f=i/r;return e(t+f*o(f,r)%i*n[u]%i,i)}),0n)}function u(t,r){let e="number"==typeof t?BigInt(n(t)):n(t),o="number"==typeof r?BigInt(n(r)):n(r);if(0n===e)return o;if(0n===o)return e;let i=0n;for(;0n===(1n&(e|o));)e>>=1n,o>>=1n,i++;for(;0n===(1n&e);)e>>=1n;do{for(;0n===(1n&o);)o>>=1n;if(e>o){const n=e;e=o,o=n;}o-=e;}while(0n!==o);return e<<i}function f(t,r){return "number"==typeof t&&(t=BigInt(t)),"number"==typeof r&&(r=BigInt(r)),0n===t&&0n===r?BigInt(0):n(t/u(t,r)*r)}function g(n,t){return n>=t?n:t}function c(n,t){return n>=t?t:n}function m(n,t){const r=BigInt(t);return e(n.map((n=>BigInt(n)%r)).reduce(((n,t)=>n+t%r),0n),r)}function p(n,t){const r=BigInt(t);return e(n.map((n=>BigInt(n)%r)).reduce(((n,t)=>n*t%r),1n),r)}function a(n){return n.map((n=>n[0]**(n[1]-1n)*(n[0]-1n))).reduce(((n,t)=>t*n),1n)}function s(t,r,u,f){if("number"==typeof t&&(t=BigInt(t)),"number"==typeof r&&(r=BigInt(r)),"number"==typeof u&&(u=BigInt(u)),u<=0n)throw new RangeError("n must be > 0");if(1n===u)return 0n;if(t=e(t,u),r<0n)return o(s(t,n(r),u,f),u);if(void 0!==f)return function(n,t,r,e){const o=e.map((n=>n[0]**n[1])),u=e.map((n=>a([n]))),f=u.map(((r,e)=>s(n,t%r,o[e])));return i(f,o,r)}(t,r,u,function(n){const t={};return n.forEach((n=>{if("bigint"==typeof n||"number"==typeof n){const r=String(n);void 0===t[r]?t[r]={p:BigInt(n),k:1n}:t[r].k+=1n;}else {const r=String(n[0]);void 0===t[r]?t[r]={p:BigInt(n[0]),k:BigInt(n[1])}:t[r].k+=BigInt(n[1]);}})),Object.values(t).map((n=>[n.p,n.k]))}(f));let g=1n;for(;r>0;)r%2n===1n&&(g=g*t%u),r/=2n,t=t**2n%u;return g}
|
||||
|
||||
function fromBuffer(buf) {
|
||||
let ret = 0n;
|
||||
|
@ -530,4 +530,4 @@ function primeSync(bitLength, iterations = 16) {
|
|||
return rnd;
|
||||
}
|
||||
|
||||
export { n as abs, t as bitLength, r as eGcd, u as gcd, isProbablyPrime, f as lcm, g as max, c as min, o as modInv, s as modPow, prime, primeSync, randBetween, randBits, randBitsSync, randBytes, randBytesSync, e as toZn };
|
||||
export { n as abs, t as bitLength, i as crt, r as eGcd, u as gcd, isProbablyPrime, f as lcm, g as max, c as min, m as modAdd, o as modInv, p as modMultiply, s as modPow, a as phi, prime, primeSync, randBetween, randBits, randBitsSync, randBytes, randBytesSync, e as toZn };
|
||||
|
|
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
|
@ -16,6 +16,20 @@ declare function abs(a: number | bigint): number | bigint;
|
|||
*/
|
||||
declare function bitLength(a: number | bigint): number;
|
||||
|
||||
/**
|
||||
* Chinese remainder theorem states that if one knows the remainders of the Euclidean division of an integer n by several integers, then one can determine uniquely the remainder of the division of n by the product of these integers, under the condition that the divisors are pairwise coprime (no two divisors share a common factor other than 1). Provided that n_i are pairwise coprime, and a_i any integers, this function returns a solution for the following system of equations:
|
||||
x ≡ a_1 mod n_1
|
||||
x ≡ a_2 mod n_2
|
||||
⋮
|
||||
x ≡ a_k mod n_k
|
||||
*
|
||||
* @param remainders the array of remainders a_i. For example [17n, 243n, 344n]
|
||||
* @param modulos the array of modulos n_i. For example [769n, 2017n, 47701n]
|
||||
* @param modulo the product of all modulos. Provided here just to save some operations if it is already known
|
||||
* @returns x
|
||||
*/
|
||||
declare function crt(remainders: bigint[], modulos: bigint[], modulo?: bigint): bigint;
|
||||
|
||||
interface Egcd {
|
||||
g: bigint;
|
||||
x: bigint;
|
||||
|
@ -73,6 +87,14 @@ declare function max(a: number | bigint, b: number | bigint): number | bigint;
|
|||
*/
|
||||
declare function min(a: number | bigint, b: number | bigint): number | bigint;
|
||||
|
||||
/**
|
||||
* Modular addition of (a_1 + ... + a_r) mod n
|
||||
* @param addends an array of the numbers a_i to add. For example [3, 12353251235n, 1243, -12341232545990n]
|
||||
* @param n the modulo
|
||||
* @returns The smallest positive integer that is congruent with (a_1 + ... + a_r) mod n
|
||||
*/
|
||||
declare function modAdd(addends: Array<number | bigint>, n: number | bigint): bigint;
|
||||
|
||||
/**
|
||||
* Modular inverse.
|
||||
*
|
||||
|
@ -85,6 +107,14 @@ declare function min(a: number | bigint, b: number | bigint): number | bigint;
|
|||
*/
|
||||
declare function modInv(a: number | bigint, n: number | bigint): bigint;
|
||||
|
||||
/**
|
||||
* Modular addition of (a_1 * ... * a_r) mod n
|
||||
* @param factors an array of the numbers a_i to multiply. For example [3, 12353251235n, 1243, -12341232545990n]
|
||||
* @param n the modulo
|
||||
* @returns The smallest positive integer that is congruent with (a_1 * ... * a_r) mod n
|
||||
*/
|
||||
declare function modMultiply(factors: Array<number | bigint>, n: number | bigint): bigint;
|
||||
|
||||
type PrimePower = [number | bigint, number | bigint];
|
||||
type PrimeFactor = number | bigint | PrimePower;
|
||||
/**
|
||||
|
@ -101,6 +131,15 @@ type PrimeFactor = number | bigint | PrimePower;
|
|||
*/
|
||||
declare function modPow(b: number | bigint, e: number | bigint, n: number | bigint, primeFactorization?: PrimeFactor[]): bigint;
|
||||
|
||||
type PrimeFactorization = Array<[bigint, bigint]>;
|
||||
/**
|
||||
* A function that computes the Euler's totien function of a number n, whose prime power factorization is known
|
||||
*
|
||||
* @param primeFactorization an array of arrays containing the prime power factorization of a number n. For example, for n = (p1**k1)*(p2**k2)*...*(pr**kr), one should provide [[p1, k1], [p2, k2], ... , [pr, kr]]
|
||||
* @returns phi((p1**k1)*(p2**k2)*...*(pr**kr))
|
||||
*/
|
||||
declare function phi(primeFactorization: PrimeFactorization): bigint;
|
||||
|
||||
/**
|
||||
* Finds the smallest positive element that is congruent to a in modulo n
|
||||
*
|
||||
|
@ -215,4 +254,4 @@ declare function randBytes(byteLength: number, forceLength?: boolean): Promise<U
|
|||
*/
|
||||
declare function randBytesSync(byteLength: number, forceLength?: boolean): Uint8Array | Buffer;
|
||||
|
||||
export { abs, bitLength, eGcd, gcd, isProbablyPrime, lcm, max, min, modInv, modPow, prime, primeSync, randBetween, randBits, randBitsSync, randBytes, randBytesSync, toZn };
|
||||
export { Egcd, PrimeFactor, PrimeFactorization, PrimePower, abs, bitLength, crt, eGcd, gcd, isProbablyPrime, lcm, max, min, modAdd, modInv, modMultiply, modPow, phi, prime, primeSync, randBetween, randBits, randBitsSync, randBytes, randBytesSync, toZn };
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
127
docs/API.md
127
docs/API.md
|
@ -2,18 +2,32 @@
|
|||
|
||||
## Table of contents
|
||||
|
||||
### Interfaces
|
||||
|
||||
- [Egcd](interfaces/Egcd.md)
|
||||
|
||||
### Type Aliases
|
||||
|
||||
- [PrimeFactor](API.md#primefactor)
|
||||
- [PrimeFactorization](API.md#primefactorization)
|
||||
- [PrimePower](API.md#primepower)
|
||||
|
||||
### Functions
|
||||
|
||||
- [abs](API.md#abs)
|
||||
- [bitLength](API.md#bitlength)
|
||||
- [crt](API.md#crt)
|
||||
- [eGcd](API.md#egcd)
|
||||
- [gcd](API.md#gcd)
|
||||
- [isProbablyPrime](API.md#isprobablyprime)
|
||||
- [lcm](API.md#lcm)
|
||||
- [max](API.md#max)
|
||||
- [min](API.md#min)
|
||||
- [modAdd](API.md#modadd)
|
||||
- [modInv](API.md#modinv)
|
||||
- [modMultiply](API.md#modmultiply)
|
||||
- [modPow](API.md#modpow)
|
||||
- [phi](API.md#phi)
|
||||
- [prime](API.md#prime)
|
||||
- [primeSync](API.md#primesync)
|
||||
- [randBetween](API.md#randbetween)
|
||||
|
@ -23,6 +37,24 @@
|
|||
- [randBytesSync](API.md#randbytessync)
|
||||
- [toZn](API.md#tozn)
|
||||
|
||||
## Type Aliases
|
||||
|
||||
### PrimeFactor
|
||||
|
||||
Ƭ **PrimeFactor**: `number` \| `bigint` \| [`PrimePower`](API.md#primepower)
|
||||
|
||||
___
|
||||
|
||||
### PrimeFactorization
|
||||
|
||||
Ƭ **PrimeFactorization**: [`bigint`, `bigint`][]
|
||||
|
||||
___
|
||||
|
||||
### PrimePower
|
||||
|
||||
Ƭ **PrimePower**: [`number` \| `bigint`, `number` \| `bigint`]
|
||||
|
||||
## Functions
|
||||
|
||||
### abs
|
||||
|
@ -65,9 +97,35 @@ The bit length
|
|||
|
||||
___
|
||||
|
||||
### crt
|
||||
|
||||
▸ **crt**(`remainders`, `modulos`, `modulo?`): `bigint`
|
||||
|
||||
Chinese remainder theorem states that if one knows the remainders of the Euclidean division of an integer n by several integers, then one can determine uniquely the remainder of the division of n by the product of these integers, under the condition that the divisors are pairwise coprime (no two divisors share a common factor other than 1). Provided that n_i are pairwise coprime, and a_i any integers, this function returns a solution for the following system of equations:
|
||||
x ≡ a_1 mod n_1
|
||||
x ≡ a_2 mod n_2
|
||||
⋮
|
||||
x ≡ a_k mod n_k
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------ | :------ | :------ |
|
||||
| `remainders` | `bigint`[] | the array of remainders a_i. For example [17n, 243n, 344n] |
|
||||
| `modulos` | `bigint`[] | the array of modulos n_i. For example [769n, 2017n, 47701n] |
|
||||
| `modulo?` | `bigint` | the product of all modulos. Provided here just to save some operations if it is already known |
|
||||
|
||||
#### Returns
|
||||
|
||||
`bigint`
|
||||
|
||||
x
|
||||
|
||||
___
|
||||
|
||||
### eGcd
|
||||
|
||||
▸ **eGcd**(`a`, `b`): `Egcd`
|
||||
▸ **eGcd**(`a`, `b`): [`Egcd`](interfaces/Egcd.md)
|
||||
|
||||
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).
|
||||
|
@ -85,7 +143,7 @@ RangeError if a or b are <= 0
|
|||
|
||||
#### Returns
|
||||
|
||||
`Egcd`
|
||||
[`Egcd`](interfaces/Egcd.md)
|
||||
|
||||
A triple (g, x, y), such that ax + by = g = gcd(a, b).
|
||||
|
||||
|
@ -202,6 +260,27 @@ Minimum of numbers a and b
|
|||
|
||||
___
|
||||
|
||||
### modAdd
|
||||
|
||||
▸ **modAdd**(`addends`, `n`): `bigint`
|
||||
|
||||
Modular addition of (a_1 + ... + a_r) mod n
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------ | :------ | :------ |
|
||||
| `addends` | (`number` \| `bigint`)[] | an array of the numbers a_i to add. For example [3, 12353251235n, 1243, -12341232545990n] |
|
||||
| `n` | `number` \| `bigint` | the modulo |
|
||||
|
||||
#### Returns
|
||||
|
||||
`bigint`
|
||||
|
||||
The smallest positive integer that is congruent with (a_1 + ... + a_r) mod n
|
||||
|
||||
___
|
||||
|
||||
### modInv
|
||||
|
||||
▸ **modInv**(`a`, `n`): `bigint`
|
||||
|
@ -227,6 +306,28 @@ The inverse modulo n
|
|||
|
||||
___
|
||||
|
||||
### modMultiply
|
||||
|
||||
▸ **modMultiply**(`factors`, `n`): `bigint`
|
||||
|
||||
Modular addition of (a_1 * ... * a_r) mod n
|
||||
*
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------ | :------ | :------ |
|
||||
| `factors` | (`number` \| `bigint`)[] | an array of the numbers a_i to multiply. For example [3, 12353251235n, 1243, -12341232545990n] * |
|
||||
| `n` | `number` \| `bigint` | the modulo * |
|
||||
|
||||
#### Returns
|
||||
|
||||
`bigint`
|
||||
|
||||
The smallest positive integer that is congruent with (a_1 * ... * a_r) mod n
|
||||
|
||||
___
|
||||
|
||||
### modPow
|
||||
|
||||
▸ **modPow**(`b`, `e`, `n`, `primeFactorization?`): `bigint`
|
||||
|
@ -244,7 +345,7 @@ RangeError if n <= 0
|
|||
| `b` | `number` \| `bigint` | base |
|
||||
| `e` | `number` \| `bigint` | exponent |
|
||||
| `n` | `number` \| `bigint` | modulo |
|
||||
| `primeFactorization?` | `PrimeFactor`[] | an array of the prime factors, for example [5n, 5n, 13n, 27n], or prime powers as [p, k], for instance [[5, 2], [13, 1], [27, 1]]. If the prime factorization is provided the chinese remainder theorem is used to greatly speed up the exponentiation. |
|
||||
| `primeFactorization?` | [`PrimeFactor`](API.md#primefactor)[] | an array of the prime factors, for example [5n, 5n, 13n, 27n], or prime powers as [p, k], for instance [[5, 2], [13, 1], [27, 1]]. If the prime factorization is provided the chinese remainder theorem is used to greatly speed up the exponentiation. |
|
||||
|
||||
#### Returns
|
||||
|
||||
|
@ -254,6 +355,26 @@ b**e mod n
|
|||
|
||||
___
|
||||
|
||||
### phi
|
||||
|
||||
▸ **phi**(`primeFactorization`): `bigint`
|
||||
|
||||
A function that computes the Euler's totien function of a number n, whose prime power factorization is known
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------ | :------ | :------ |
|
||||
| `primeFactorization` | [`PrimeFactorization`](API.md#primefactorization) | an array of arrays containing the prime power factorization of a number n. For example, for n = (p1**k1)*(p2**k2)*...*(pr**kr), one should provide [[p1, k1], [p2, k2], ... , [pr, kr]] |
|
||||
|
||||
#### Returns
|
||||
|
||||
`bigint`
|
||||
|
||||
phi((p1**k1)*(p2**k2)*...*(pr**kr))
|
||||
|
||||
___
|
||||
|
||||
### prime
|
||||
|
||||
▸ **prime**(`bitLength`, `iterations?`): `Promise`<`bigint`\>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
export { abs, bitLength, eGcd, gcd, lcm, max, min, modInv, modPow, toZn } from 'bigint-mod-arith'
|
||||
export * from 'bigint-mod-arith'
|
||||
|
||||
export { isProbablyPrime } from './isProbablyPrime.js'
|
||||
export { prime, primeSync } from './prime.js'
|
||||
|
|
Loading…
Reference in New Issue