bitLength() is also exported (it could be useful)
This commit is contained in:
parent
e572e9dba8
commit
42a0aba89a
15
README.md
15
README.md
|
@ -87,6 +87,9 @@ From a browser, you can just load the module in a html page as:
|
|||
<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>
|
||||
|
@ -148,6 +151,18 @@ Absolute value. abs(a)==a if a>=0. abs(a)==-a if a<0
|
|||
| --- | --- |
|
||||
| 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>bigint</code> |
|
||||
|
||||
<a name="eGcd"></a>
|
||||
|
||||
## eGcd(a, b) ⇒ [<code>egcdReturn</code>](#egcdReturn)
|
||||
|
|
|
@ -13,6 +13,20 @@ var bigintCryptoUtils = (function (exports) {
|
|||
return (a >= _ZERO) ? a : -a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bitlength of a number
|
||||
*
|
||||
* @param {bigint} a
|
||||
* @returns {number} - the bit length
|
||||
*/
|
||||
function bitLength(a) {
|
||||
let bits = 1;
|
||||
do {
|
||||
bits++;
|
||||
} while ((a >>= _ONE) > _ONE);
|
||||
return bits;
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} egcdReturn A triple (g, x, y), such that ax + by = g = gcd(a, b).
|
||||
* @property {bigint} g
|
||||
|
@ -324,14 +338,6 @@ var bigintCryptoUtils = (function (exports) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
function bitLength(a) {
|
||||
let bits = 1;
|
||||
do {
|
||||
bits++;
|
||||
} while ((a >>= _ONE) > _ONE);
|
||||
return bits;
|
||||
}
|
||||
|
||||
function _isProbablyPrimeWorkerUrl() {
|
||||
// Let's us first add all the required functions
|
||||
let workerCode = `'use strict';const _ZERO = BigInt(0);const _ONE = BigInt(1);const _TWO = BigInt(2);const eGcd = ${eGcd.toString()};const modInv = ${modInv.toString()};const modPow = ${modPow.toString()};const toZn = ${toZn.toString()};const randBits = ${randBits.toString()};const randBytes = ${randBytes.toString()};const randBetween = ${randBetween.toString()};const isProbablyPrime = ${_isProbablyPrime.toString()};${bitLength.toString()}${fromBuffer.toString()}`;
|
||||
|
@ -682,6 +688,7 @@ var bigintCryptoUtils = (function (exports) {
|
|||
const _TWO = BigInt(2);
|
||||
|
||||
exports.abs = abs;
|
||||
exports.bitLength = bitLength;
|
||||
exports.eGcd = eGcd;
|
||||
exports.gcd = gcd;
|
||||
exports.isProbablyPrime = isProbablyPrime;
|
||||
|
|
|
@ -1 +1 @@
|
|||
var bigintCryptoUtils=function(a){'use strict';function c(b){return b=BigInt(b),b>=r?b:-b}function d(c,d){c=BigInt(c),d=BigInt(d);let e=r,f=s,g=s,h=r;for(;c!==r;){let a=d/c,b=d%c,i=e-g*a,j=f-h*a;d=c,c=b,e=g,f=h,g=i,h=j}return{b:d,x:e,y:f}}function e(d,e){d=c(d),e=c(e);let f=r;for(;!((d|e)&s);)d>>=s,e>>=s,f++;for(;!(d&s);)d>>=s;do{for(;!(e&s);)e>>=s;if(d>e){let a=d;d=e,e=a}e-=d}while(e);return d<<f}async function f(a,b=16){return new Promise((c,d)=>{let e=new Worker(o());e.onmessage=a=>{e.terminate(),c(a.data.isPrime)},e.onmessageerror=a=>{d(a)},e.postMessage({rnd:a,iterations:b,id:0})})}function g(b,a){let c=d(b,a);return c.b===s?l(c.x,a):null}function h(d,e,f){if(f=BigInt(f),d=l(d,f),e=BigInt(e),e<r)return g(h(d,c(e),f),f);let i=s,j=d;for(;0<e;){var k=e%t;e/=t,k==s&&(i*=j,i%=f),j*=j,j%=f}return i}function i(a,b=s){if(a<=b)throw new Error("max must be > min");const c=a-b;let d,e=n(c);do{let a=j(e);d=m(a)}while(d>c);return d+b}function j(a,b=!1){var c=Math.ceil;const d=c(a/8);let e=k(d,!1);if(e[0]&=2**(a%8)-1,b){let b=a%8?2**(a%8-1):128;e[0]|=b}return e}function k(a,b=!1){let c;return c=new Uint8Array(a),self.crypto.getRandomValues(c),b&&(c[0]|=128),c}function l(b,c){return c=BigInt(c),b=BigInt(b)%c,0>b?b+c:b}function m(a){let b=r;for(let c of a.values()){let a=BigInt(c);b=(b<<BigInt(8))+a}return b}function n(b){let c=1;do c++;while((b>>=s)>s);return c}function o(){let a=`'use strict';const _ZERO = BigInt(0);const _ONE = BigInt(1);const _TWO = BigInt(2);const eGcd = ${d.toString()};const modInv = ${g.toString()};const modPow = ${h.toString()};const toZn = ${l.toString()};const randBits = ${j.toString()};const randBytes = ${k.toString()};const randBetween = ${i.toString()};const isProbablyPrime = ${q.toString()};${n.toString()}${m.toString()}`;return a+=`onmessage = ${async function(a){const b=await f(a.data.rnd,a.data.iterations);postMessage({isPrime:b,value:a.data.rnd,id:a.data.id})}.toString()};`,p(a)}function p(a){a=`(() => {${a}})()`;var b=new Blob([a],{type:"text/javascript"});return window.URL.createObjectURL(b)}function q(c,b=16){if(c===t)return!0;if((c&s)===r||c===s)return!1;const e=[3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997,1009,1013,1019,1021,1031,1033,1039,1049,1051,1061,1063,1069,1087,1091,1093,1097,1103,1109,1117,1123,1129,1151,1153,1163,1171,1181,1187,1193,1201,1213,1217,1223,1229,1231,1237,1249,1259,1277,1279,1283,1289,1291,1297,1301,1303,1307,1319,1321,1327,1361,1367,1373,1381,1399,1409,1423,1427,1429,1433,1439,1447,1451,1453,1459,1471,1481,1483,1487,1489,1493,1499,1511,1523,1531,1543,1549,1553,1559,1567,1571,1579,1583,1597];for(let a=0;a<e.length&&BigInt(e[a])<=c;a++){const b=BigInt(e[a]);if(c===b)return!0;if(c%b===r)return!1}let f=r,g=c-s;for(;g%t===r;)g/=t,++f;let j=(c-s)/t**f;loop:do{let a=i(c-s,t),b=h(a,j,c);if(b===s||b===c-s)continue;for(let a=1;a<f;a++){if(b=h(b,t,c),b===c-s)continue loop;if(b===s)break}return!1}while(--b);return!0}const r=BigInt(0),s=BigInt(1),t=BigInt(2);return a.abs=c,a.eGcd=d,a.gcd=e,a.isProbablyPrime=f,a.lcm=function(d,f){return d=BigInt(d),f=BigInt(f),c(d*f)/e(d,f)},a.modInv=g,a.modPow=h,a.prime=function(a,b=16){return new Promise(c=>{let d=[];const e=(e,f)=>{if(e.isPrime){for(let a=0;a<d.length;a++)d[a].terminate();for(;d.length;)d.pop();c(e.value)}else{let c=j(a,!0),d=m(c);try{f.postMessage({rnd:d,iterations:b,id:e.id})}catch(a){}}};{let a=o();for(let b,c=0;c<self.navigator.hardwareConcurrency;c++)b=new Worker(a),b.onmessage=a=>e(a.data,b),d.push(b)}for(let e=0;e<d.length;e++){let c=j(a,!0),f=m(c);d[e].postMessage({rnd:f,iterations:b,id:e})}})},a.randBetween=i,a.randBits=j,a.randBytes=k,a.toZn=l,a}({});
|
||||
var bigintCryptoUtils=function(a){'use strict';function c(b){return b=BigInt(b),b>=r?b:-b}function d(b){let c=1;do c++;while((b>>=s)>s);return c}function e(c,d){c=BigInt(c),d=BigInt(d);let e=r,f=s,g=s,h=r;for(;c!==r;){let a=d/c,b=d%c,i=e-g*a,j=f-h*a;d=c,c=b,e=g,f=h,g=i,h=j}return{b:d,x:e,y:f}}function f(d,e){d=c(d),e=c(e);let f=r;for(;!((d|e)&s);)d>>=s,e>>=s,f++;for(;!(d&s);)d>>=s;do{for(;!(e&s);)e>>=s;if(d>e){let a=d;d=e,e=a}e-=d}while(e);return d<<f}async function g(a,b=16){return new Promise((c,d)=>{let e=new Worker(o());e.onmessage=a=>{e.terminate(),c(a.data.isPrime)},e.onmessageerror=a=>{d(a)},e.postMessage({rnd:a,iterations:b,id:0})})}function h(b,a){let c=e(b,a);return c.b===s?m(c.x,a):null}function i(d,e,f){if(f=BigInt(f),d=m(d,f),e=BigInt(e),e<r)return h(i(d,c(e),f),f);let g=s,j=d;for(;0<e;){var k=e%t;e/=t,k==s&&(g*=j,g%=f),j*=j,j%=f}return g}function j(a,b=s){if(a<=b)throw new Error("max must be > min");const c=a-b;let e,f=d(c);do{let a=k(f);e=n(a)}while(e>c);return e+b}function k(a,b=!1){var c=Math.ceil;const d=c(a/8);let e=l(d,!1);if(e[0]&=2**(a%8)-1,b){let b=a%8?2**(a%8-1):128;e[0]|=b}return e}function l(a,b=!1){let c;return c=new Uint8Array(a),self.crypto.getRandomValues(c),b&&(c[0]|=128),c}function m(b,c){return c=BigInt(c),b=BigInt(b)%c,0>b?b+c:b}function n(a){let b=r;for(let c of a.values()){let a=BigInt(c);b=(b<<BigInt(8))+a}return b}function o(){let a=`'use strict';const _ZERO = BigInt(0);const _ONE = BigInt(1);const _TWO = BigInt(2);const eGcd = ${e.toString()};const modInv = ${h.toString()};const modPow = ${i.toString()};const toZn = ${m.toString()};const randBits = ${k.toString()};const randBytes = ${l.toString()};const randBetween = ${j.toString()};const isProbablyPrime = ${q.toString()};${d.toString()}${n.toString()}`;return a+=`onmessage = ${async function(a){const b=await g(a.data.rnd,a.data.iterations);postMessage({isPrime:b,value:a.data.rnd,id:a.data.id})}.toString()};`,p(a)}function p(a){a=`(() => {${a}})()`;var b=new Blob([a],{type:"text/javascript"});return window.URL.createObjectURL(b)}function q(c,b=16){if(c===t)return!0;if((c&s)===r||c===s)return!1;const e=[3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997,1009,1013,1019,1021,1031,1033,1039,1049,1051,1061,1063,1069,1087,1091,1093,1097,1103,1109,1117,1123,1129,1151,1153,1163,1171,1181,1187,1193,1201,1213,1217,1223,1229,1231,1237,1249,1259,1277,1279,1283,1289,1291,1297,1301,1303,1307,1319,1321,1327,1361,1367,1373,1381,1399,1409,1423,1427,1429,1433,1439,1447,1451,1453,1459,1471,1481,1483,1487,1489,1493,1499,1511,1523,1531,1543,1549,1553,1559,1567,1571,1579,1583,1597];for(let a=0;a<e.length&&BigInt(e[a])<=c;a++){const b=BigInt(e[a]);if(c===b)return!0;if(c%b===r)return!1}let f=r,g=c-s;for(;g%t===r;)g/=t,++f;let h=(c-s)/t**f;loop:do{let a=j(c-s,t),b=i(a,h,c);if(b===s||b===c-s)continue;for(let a=1;a<f;a++){if(b=i(b,t,c),b===c-s)continue loop;if(b===s)break}return!1}while(--b);return!0}const r=BigInt(0),s=BigInt(1),t=BigInt(2);return a.abs=c,a.bitLength=d,a.eGcd=e,a.gcd=f,a.isProbablyPrime=g,a.lcm=function(d,e){return d=BigInt(d),e=BigInt(e),c(d*e)/f(d,e)},a.modInv=h,a.modPow=i,a.prime=function(a,b=16){return new Promise(c=>{let d=[];const e=(e,f)=>{if(e.isPrime){for(let a=0;a<d.length;a++)d[a].terminate();for(;d.length;)d.pop();c(e.value)}else{let c=k(a,!0),d=n(c);try{f.postMessage({rnd:d,iterations:b,id:e.id})}catch(a){}}};{let a=o();for(let b,c=0;c<self.navigator.hardwareConcurrency;c++)b=new Worker(a),b.onmessage=a=>e(a.data,b),d.push(b)}for(let e=0;e<d.length;e++){let c=k(a,!0),f=n(c);d[e].postMessage({rnd:f,iterations:b,id:e})}})},a.randBetween=j,a.randBits=k,a.randBytes=l,a.toZn=m,a}({});
|
||||
|
|
|
@ -10,6 +10,20 @@ function abs(a) {
|
|||
return (a >= _ZERO) ? a : -a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bitlength of a number
|
||||
*
|
||||
* @param {bigint} a
|
||||
* @returns {number} - the bit length
|
||||
*/
|
||||
function bitLength(a) {
|
||||
let bits = 1;
|
||||
do {
|
||||
bits++;
|
||||
} while ((a >>= _ONE) > _ONE);
|
||||
return bits;
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} egcdReturn A triple (g, x, y), such that ax + by = g = gcd(a, b).
|
||||
* @property {bigint} g
|
||||
|
@ -321,14 +335,6 @@ function fromBuffer(buf) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
function bitLength(a) {
|
||||
let bits = 1;
|
||||
do {
|
||||
bits++;
|
||||
} while ((a >>= _ONE) > _ONE);
|
||||
return bits;
|
||||
}
|
||||
|
||||
function _isProbablyPrimeWorkerUrl() {
|
||||
// Let's us first add all the required functions
|
||||
let workerCode = `'use strict';const _ZERO = BigInt(0);const _ONE = BigInt(1);const _TWO = BigInt(2);const eGcd = ${eGcd.toString()};const modInv = ${modInv.toString()};const modPow = ${modPow.toString()};const toZn = ${toZn.toString()};const randBits = ${randBits.toString()};const randBytes = ${randBytes.toString()};const randBetween = ${randBetween.toString()};const isProbablyPrime = ${_isProbablyPrime.toString()};${bitLength.toString()}${fromBuffer.toString()}`;
|
||||
|
@ -678,4 +684,4 @@ const _ZERO = BigInt(0);
|
|||
const _ONE = BigInt(1);
|
||||
const _TWO = BigInt(2);
|
||||
|
||||
export { abs, eGcd, gcd, isProbablyPrime, lcm, modInv, modPow, prime, randBetween, randBits, randBytes, toZn };
|
||||
export { abs, bitLength, eGcd, gcd, isProbablyPrime, lcm, modInv, modPow, prime, randBetween, randBits, randBytes, toZn };
|
||||
|
|
|
@ -1 +1 @@
|
|||
function abs(b){return b=BigInt(b),b>=_ZERO?b:-b}function eGcd(c,d){c=BigInt(c),d=BigInt(d);let e=_ZERO,f=_ONE,g=_ONE,h=_ZERO;for(;c!==_ZERO;){let a=d/c,b=d%c,i=e-g*a,j=f-h*a;d=c,c=b,e=g,f=h,g=i,h=j}return{b:d,x:e,y:f}}function gcd(c,d){c=abs(c),d=abs(d);let e=_ZERO;for(;!((c|d)&_ONE);)c>>=_ONE,d>>=_ONE,e++;for(;!(c&_ONE);)c>>=_ONE;do{for(;!(d&_ONE);)d>>=_ONE;if(c>d){let a=c;c=d,d=a}d-=c}while(d);return c<<e}async function isProbablyPrime(a,b=16){return new Promise((c,d)=>{let e=new Worker(_isProbablyPrimeWorkerUrl());e.onmessage=a=>{e.terminate(),c(a.data.isPrime)},e.onmessageerror=a=>{d(a)},e.postMessage({rnd:a,iterations:b,id:0})})}function lcm(c,d){return c=BigInt(c),d=BigInt(d),abs(c*d)/gcd(c,d)}function modInv(b,a){let c=eGcd(b,a);return c.b===_ONE?toZn(c.x,a):null}function modPow(c,d,e){if(e=BigInt(e),c=toZn(c,e),d=BigInt(d),d<_ZERO)return modInv(modPow(c,abs(d),e),e);let f=_ONE,g=c;for(;0<d;){var h=d%_TWO;d/=_TWO,h==_ONE&&(f*=g,f%=e),g*=g,g%=e}return f}function prime(a,b=16){return new Promise(c=>{let d=[];const e=(e,f)=>{if(e.isPrime){for(let a=0;a<d.length;a++)d[a].terminate();for(;d.length;)d.pop();c(e.value)}else{let c=randBits(a,!0),d=fromBuffer(c);try{f.postMessage({rnd:d,iterations:b,id:e.id})}catch(a){}}};{let a=_isProbablyPrimeWorkerUrl();for(let b,c=0;c<self.navigator.hardwareConcurrency;c++)b=new Worker(a),b.onmessage=a=>e(a.data,b),d.push(b)}for(let e=0;e<d.length;e++){let c=randBits(a,!0),f=fromBuffer(c);d[e].postMessage({rnd:f,iterations:b,id:e})}})}function randBetween(a,b=_ONE){if(a<=b)throw new Error("max must be > min");const c=a-b;let d,e=bitLength(c);do{let a=randBits(e);d=fromBuffer(a)}while(d>c);return d+b}function randBits(a,b=!1){var c=Math.ceil;const d=c(a/8);let e=randBytes(d,!1);if(e[0]&=2**(a%8)-1,b){let b=a%8?2**(a%8-1):128;e[0]|=b}return e}function randBytes(a,b=!1){let c;return c=new Uint8Array(a),self.crypto.getRandomValues(c),b&&(c[0]|=128),c}function toZn(b,c){return c=BigInt(c),b=BigInt(b)%c,0>b?b+c:b}function fromBuffer(a){let b=_ZERO;for(let c of a.values()){let a=BigInt(c);b=(b<<BigInt(8))+a}return b}function bitLength(b){let c=1;do c++;while((b>>=_ONE)>_ONE);return c}function _isProbablyPrimeWorkerUrl(){let a=`'use strict';const _ZERO = BigInt(0);const _ONE = BigInt(1);const _TWO = BigInt(2);const eGcd = ${eGcd.toString()};const modInv = ${modInv.toString()};const modPow = ${modPow.toString()};const toZn = ${toZn.toString()};const randBits = ${randBits.toString()};const randBytes = ${randBytes.toString()};const randBetween = ${randBetween.toString()};const isProbablyPrime = ${_isProbablyPrime.toString()};${bitLength.toString()}${fromBuffer.toString()}`;return a+=`onmessage = ${async function(a){const b=await isProbablyPrime(a.data.rnd,a.data.iterations);postMessage({isPrime:b,value:a.data.rnd,id:a.data.id})}.toString()};`,_workerUrl(a)}function _workerUrl(a){a=`(() => {${a}})()`;var b=new Blob([a],{type:"text/javascript"});return window.URL.createObjectURL(b)}function _isProbablyPrime(c,b=16){if(c===_TWO)return!0;if((c&_ONE)===_ZERO||c===_ONE)return!1;const e=[3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997,1009,1013,1019,1021,1031,1033,1039,1049,1051,1061,1063,1069,1087,1091,1093,1097,1103,1109,1117,1123,1129,1151,1153,1163,1171,1181,1187,1193,1201,1213,1217,1223,1229,1231,1237,1249,1259,1277,1279,1283,1289,1291,1297,1301,1303,1307,1319,1321,1327,1361,1367,1373,1381,1399,1409,1423,1427,1429,1433,1439,1447,1451,1453,1459,1471,1481,1483,1487,1489,1493,1499,1511,1523,1531,1543,1549,1553,1559,1567,1571,1579,1583,1597];for(let a=0;a<e.length&&BigInt(e[a])<=c;a++){const b=BigInt(e[a]);if(c===b)return!0;if(c%b===_ZERO)return!1}let f=_ZERO,g=c-_ONE;for(;g%_TWO===_ZERO;)g/=_TWO,++f;let h=(c-_ONE)/_TWO**f;loop:do{let a=randBetween(c-_ONE,_TWO),b=modPow(a,h,c);if(b===_ONE||b===c-_ONE)continue;for(let a=1;a<f;a++){if(b=modPow(b,_TWO,c),b===c-_ONE)continue loop;if(b===_ONE)break}return!1}while(--b);return!0}const _ZERO=BigInt(0),_ONE=BigInt(1),_TWO=BigInt(2);export{abs,eGcd,gcd,isProbablyPrime,lcm,modInv,modPow,prime,randBetween,randBits,randBytes,toZn};
|
||||
function abs(b){return b=BigInt(b),b>=_ZERO?b:-b}function bitLength(b){let c=1;do c++;while((b>>=_ONE)>_ONE);return c}function eGcd(c,d){c=BigInt(c),d=BigInt(d);let e=_ZERO,f=_ONE,g=_ONE,h=_ZERO;for(;c!==_ZERO;){let a=d/c,b=d%c,i=e-g*a,j=f-h*a;d=c,c=b,e=g,f=h,g=i,h=j}return{b:d,x:e,y:f}}function gcd(c,d){c=abs(c),d=abs(d);let e=_ZERO;for(;!((c|d)&_ONE);)c>>=_ONE,d>>=_ONE,e++;for(;!(c&_ONE);)c>>=_ONE;do{for(;!(d&_ONE);)d>>=_ONE;if(c>d){let a=c;c=d,d=a}d-=c}while(d);return c<<e}async function isProbablyPrime(a,b=16){return new Promise((c,d)=>{let e=new Worker(_isProbablyPrimeWorkerUrl());e.onmessage=a=>{e.terminate(),c(a.data.isPrime)},e.onmessageerror=a=>{d(a)},e.postMessage({rnd:a,iterations:b,id:0})})}function lcm(c,d){return c=BigInt(c),d=BigInt(d),abs(c*d)/gcd(c,d)}function modInv(b,a){let c=eGcd(b,a);return c.b===_ONE?toZn(c.x,a):null}function modPow(c,d,e){if(e=BigInt(e),c=toZn(c,e),d=BigInt(d),d<_ZERO)return modInv(modPow(c,abs(d),e),e);let f=_ONE,g=c;for(;0<d;){var h=d%_TWO;d/=_TWO,h==_ONE&&(f*=g,f%=e),g*=g,g%=e}return f}function prime(a,b=16){return new Promise(c=>{let d=[];const e=(e,f)=>{if(e.isPrime){for(let a=0;a<d.length;a++)d[a].terminate();for(;d.length;)d.pop();c(e.value)}else{let c=randBits(a,!0),d=fromBuffer(c);try{f.postMessage({rnd:d,iterations:b,id:e.id})}catch(a){}}};{let a=_isProbablyPrimeWorkerUrl();for(let b,c=0;c<self.navigator.hardwareConcurrency;c++)b=new Worker(a),b.onmessage=a=>e(a.data,b),d.push(b)}for(let e=0;e<d.length;e++){let c=randBits(a,!0),f=fromBuffer(c);d[e].postMessage({rnd:f,iterations:b,id:e})}})}function randBetween(a,b=_ONE){if(a<=b)throw new Error("max must be > min");const c=a-b;let d,e=bitLength(c);do{let a=randBits(e);d=fromBuffer(a)}while(d>c);return d+b}function randBits(a,b=!1){var c=Math.ceil;const d=c(a/8);let e=randBytes(d,!1);if(e[0]&=2**(a%8)-1,b){let b=a%8?2**(a%8-1):128;e[0]|=b}return e}function randBytes(a,b=!1){let c;return c=new Uint8Array(a),self.crypto.getRandomValues(c),b&&(c[0]|=128),c}function toZn(b,c){return c=BigInt(c),b=BigInt(b)%c,0>b?b+c:b}function fromBuffer(a){let b=_ZERO;for(let c of a.values()){let a=BigInt(c);b=(b<<BigInt(8))+a}return b}function _isProbablyPrimeWorkerUrl(){let a=`'use strict';const _ZERO = BigInt(0);const _ONE = BigInt(1);const _TWO = BigInt(2);const eGcd = ${eGcd.toString()};const modInv = ${modInv.toString()};const modPow = ${modPow.toString()};const toZn = ${toZn.toString()};const randBits = ${randBits.toString()};const randBytes = ${randBytes.toString()};const randBetween = ${randBetween.toString()};const isProbablyPrime = ${_isProbablyPrime.toString()};${bitLength.toString()}${fromBuffer.toString()}`;return a+=`onmessage = ${async function(a){const b=await isProbablyPrime(a.data.rnd,a.data.iterations);postMessage({isPrime:b,value:a.data.rnd,id:a.data.id})}.toString()};`,_workerUrl(a)}function _workerUrl(a){a=`(() => {${a}})()`;var b=new Blob([a],{type:"text/javascript"});return window.URL.createObjectURL(b)}function _isProbablyPrime(c,b=16){if(c===_TWO)return!0;if((c&_ONE)===_ZERO||c===_ONE)return!1;const e=[3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997,1009,1013,1019,1021,1031,1033,1039,1049,1051,1061,1063,1069,1087,1091,1093,1097,1103,1109,1117,1123,1129,1151,1153,1163,1171,1181,1187,1193,1201,1213,1217,1223,1229,1231,1237,1249,1259,1277,1279,1283,1289,1291,1297,1301,1303,1307,1319,1321,1327,1361,1367,1373,1381,1399,1409,1423,1427,1429,1433,1439,1447,1451,1453,1459,1471,1481,1483,1487,1489,1493,1499,1511,1523,1531,1543,1549,1553,1559,1567,1571,1579,1583,1597];for(let a=0;a<e.length&&BigInt(e[a])<=c;a++){const b=BigInt(e[a]);if(c===b)return!0;if(c%b===_ZERO)return!1}let f=_ZERO,g=c-_ONE;for(;g%_TWO===_ZERO;)g/=_TWO,++f;let h=(c-_ONE)/_TWO**f;loop:do{let a=randBetween(c-_ONE,_TWO),b=modPow(a,h,c);if(b===_ONE||b===c-_ONE)continue;for(let a=1;a<f;a++){if(b=modPow(b,_TWO,c),b===c-_ONE)continue loop;if(b===_ONE)break}return!1}while(--b);return!0}const _ZERO=BigInt(0),_ONE=BigInt(1),_TWO=BigInt(2);export{abs,bitLength,eGcd,gcd,isProbablyPrime,lcm,modInv,modPow,prime,randBetween,randBits,randBytes,toZn};
|
||||
|
|
|
@ -14,6 +14,20 @@ function abs(a) {
|
|||
return (a >= _ZERO) ? a : -a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bitlength of a number
|
||||
*
|
||||
* @param {bigint} a
|
||||
* @returns {number} - the bit length
|
||||
*/
|
||||
function bitLength(a) {
|
||||
let bits = 1;
|
||||
do {
|
||||
bits++;
|
||||
} while ((a >>= _ONE) > _ONE);
|
||||
return bits;
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} egcdReturn A triple (g, x, y), such that ax + by = g = gcd(a, b).
|
||||
* @property {bigint} g
|
||||
|
@ -340,14 +354,6 @@ function fromBuffer(buf) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
function bitLength(a) {
|
||||
let bits = 1;
|
||||
do {
|
||||
bits++;
|
||||
} while ((a >>= _ONE) > _ONE);
|
||||
return bits;
|
||||
}
|
||||
|
||||
function _isProbablyPrime(w, iterations = 16) {
|
||||
/*
|
||||
PREFILTERING. Even values but 2 are not primes, so don't test.
|
||||
|
@ -706,6 +712,7 @@ if (_useWorkers) { // node.js with support for workers
|
|||
}
|
||||
|
||||
exports.abs = abs;
|
||||
exports.bitLength = bitLength;
|
||||
exports.eGcd = eGcd;
|
||||
exports.gcd = gcd;
|
||||
exports.isProbablyPrime = isProbablyPrime;
|
||||
|
|
22
src/main.js
22
src/main.js
|
@ -12,6 +12,20 @@ export function abs(a) {
|
|||
return (a >= _ZERO) ? a : -a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bitlength of a number
|
||||
*
|
||||
* @param {bigint} a
|
||||
* @returns {number} - the bit length
|
||||
*/
|
||||
export function bitLength(a) {
|
||||
let bits = 1;
|
||||
do {
|
||||
bits++;
|
||||
} while ((a >>= _ONE) > _ONE);
|
||||
return bits;
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} egcdReturn A triple (g, x, y), such that ax + by = g = gcd(a, b).
|
||||
* @property {bigint} g
|
||||
|
@ -367,14 +381,6 @@ function fromBuffer(buf) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
function bitLength(a) {
|
||||
let bits = 1;
|
||||
do {
|
||||
bits++;
|
||||
} while ((a >>= _ONE) > _ONE);
|
||||
return bits;
|
||||
}
|
||||
|
||||
function _isProbablyPrimeWorkerUrl() {
|
||||
// Let's us first add all the required functions
|
||||
let workerCode = `'use strict';const _ZERO = BigInt(0);const _ONE = BigInt(1);const _TWO = BigInt(2);const eGcd = ${eGcd.toString()};const modInv = ${modInv.toString()};const modPow = ${modPow.toString()};const toZn = ${toZn.toString()};const randBits = ${randBits.toString()};const randBytes = ${randBytes.toString()};const randBetween = ${randBetween.toString()};const isProbablyPrime = ${_isProbablyPrime.toString()};${bitLength.toString()}${fromBuffer.toString()}`;
|
||||
|
|
Loading…
Reference in New Issue