From 6bb0b2f78e0ccb25eb6c7072f3d6834db6d093fe Mon Sep 17 00:00:00 2001 From: juanelas Date: Tue, 23 Apr 2019 16:57:06 +0200 Subject: [PATCH] minor improvements in code structure --- dist/bigint-crypto-utils-latest.browser.js | 73 +++++++++-------- .../bigint-crypto-utils-latest.browser.min.js | 2 +- .../bigint-crypto-utils-latest.browser.mod.js | 73 +++++++++-------- ...int-crypto-utils-latest.browser.mod.min.js | 2 +- dist/bigint-crypto-utils-latest.node.js | 80 +++++++++--------- src/main.js | 82 ++++++++++--------- 6 files changed, 167 insertions(+), 145 deletions(-) diff --git a/dist/bigint-crypto-utils-latest.browser.js b/dist/bigint-crypto-utils-latest.browser.js index e8d77d3..6132e52 100644 --- a/dist/bigint-crypto-utils-latest.browser.js +++ b/dist/bigint-crypto-utils-latest.browser.js @@ -10,7 +10,7 @@ var bigintCryptoUtils = (function (exports) { */ function abs(a) { a = BigInt(a); - return (a >= BigInt(0)) ? a : -a; + return (a >= _ZERO) ? a : -a; } /** @@ -31,12 +31,12 @@ var bigintCryptoUtils = (function (exports) { function eGcd(a, b) { a = BigInt(a); b = BigInt(b); - let x = BigInt(0); - let y = BigInt(1); - let u = BigInt(1); - let v = BigInt(0); + let x = _ZERO; + let y = _ONE; + let u = _ONE; + let v = _ZERO; - while (a !== BigInt(0)) { + while (a !== _ZERO) { let q = b / a; let r = b % a; let m = x - (u * q); @@ -66,15 +66,15 @@ var bigintCryptoUtils = (function (exports) { function gcd(a, b) { a = abs(a); b = abs(b); - let shift = BigInt(0); - while (!((a | b) & BigInt(1))) { - a >>= BigInt(1); - b >>= BigInt(1); + let shift = _ZERO; + while (!((a | b) & _ONE)) { + a >>= _ONE; + b >>= _ONE; shift++; } - while (!(a & BigInt(1))) a >>= BigInt(1); + while (!(a & _ONE)) a >>= _ONE; do { - while (!(b & BigInt(1))) b >>= BigInt(1); + while (!(b & _ONE)) b >>= _ONE; if (a > b) { let x = a; a = b; @@ -142,7 +142,7 @@ var bigintCryptoUtils = (function (exports) { */ function modInv(a, n) { let egcd = eGcd(a, n); - if (egcd.b !== BigInt(1)) { + if (egcd.b !== _ONE) { return null; // modular inverse does not exist } else { return toZn(egcd.x, n); @@ -162,15 +162,15 @@ var bigintCryptoUtils = (function (exports) { n = BigInt(n); a = toZn(a, n); b = BigInt(b); - if (b < BigInt(0)) { + if (b < _ZERO) { return modInv(modPow(a, abs(b), n), n); } - let result = BigInt(1); + let result = _ONE; let x = a; while (b > 0) { - var leastSignificantBit = b % BigInt(2); - b = b / BigInt(2); - if (leastSignificantBit == BigInt(1)) { + var leastSignificantBit = b % _TWO; + b = b / _TWO; + if (leastSignificantBit == _ONE) { result = result * x; result = result % n; } @@ -248,7 +248,7 @@ var bigintCryptoUtils = (function (exports) { * * @returns {Promise} A promise that resolves to a cryptographically secure random bigint between [min,max] */ - async function randBetween(max, min = BigInt(1)) { + async function randBetween(max, min = _ONE) { if (max <= min) throw new Error('max must be > min'); const interval = max - min; let bitLen = bitLength(interval); @@ -321,7 +321,7 @@ var bigintCryptoUtils = (function (exports) { /* HELPER FUNCTIONS */ function fromBuffer(buf) { - let ret = BigInt(0); + let ret = _ZERO; for (let i of buf.values()) { let bi = BigInt(i); ret = (ret << BigInt(8)) + bi; @@ -333,13 +333,13 @@ var bigintCryptoUtils = (function (exports) { let bits = 1; do { bits++; - } while ((a >>= BigInt(1)) > BigInt(1)); + } while ((a >>= _ONE) > _ONE); return bits; } function _isProbablyPrimeWorkerURL() { // Let's us first add all the required functions - let workerCode = `'use strict';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()}`; + 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()}`; const _onmessage = async function (event) { // Let's start once we are called // event.data = {rnd: , iterations: } @@ -364,9 +364,9 @@ var bigintCryptoUtils = (function (exports) { 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 === BigInt(2)) + if (w === _TWO) return true; - else if ((w & BigInt(1)) === BigInt(0) || w === BigInt(1)) + else if ((w & _ONE) === _ZERO || w === _ONE) return false; /* @@ -628,7 +628,7 @@ var bigintCryptoUtils = (function (exports) { const p = BigInt(firstPrimes[i]); if (w === p) return true; - else if (w % p === BigInt(0)) + else if (w % p === _ZERO) return false; } @@ -651,25 +651,25 @@ var bigintCryptoUtils = (function (exports) { Comment: Increment i for the do-loop in step 4. 5. Return PROBABLY PRIME. */ - let a = BigInt(0), d = w - BigInt(1); - while (d % BigInt(2) === BigInt(0)) { - d /= BigInt(2); + let a = _ZERO, d = w - _ONE; + while (d % _TWO === _ZERO) { + d /= _TWO; ++a; } - let m = (w - BigInt(1)) / (BigInt(2) ** a); + let m = (w - _ONE) / (_TWO ** a); loop: do { - let b = await randBetween(w - BigInt(1), BigInt(2)); + let b = await randBetween(w - _ONE, _TWO); let z = modPow(b, m, w); - if (z === BigInt(1) || z === w - BigInt(1)) + if (z === _ONE || z === w - _ONE) continue; for (let j = 1; j < a; j++) { - z = modPow(z, BigInt(2), w); - if (z === w - BigInt(1)) + z = modPow(z, _TWO, w); + if (z === w - _ONE) continue loop; - if (z === BigInt(1)) + if (z === _ONE) break; } return false; @@ -678,6 +678,11 @@ var bigintCryptoUtils = (function (exports) { return true; } + /* HELPLER CONSTANTS/VARIABLES*/ + const _ZERO = BigInt(0); + const _ONE = BigInt(1); + const _TWO = BigInt(2); + exports.abs = abs; exports.eGcd = eGcd; exports.gcd = gcd; diff --git a/dist/bigint-crypto-utils-latest.browser.min.js b/dist/bigint-crypto-utils-latest.browser.min.js index 67b8cd7..9a4a0f8 100644 --- a/dist/bigint-crypto-utils-latest.browser.min.js +++ b/dist/bigint-crypto-utils-latest.browser.min.js @@ -1 +1 @@ -var bigintCryptoUtils=function(a){'use strict';function c(b){return b=BigInt(b),b>=BigInt(0)?b:-b}function d(c,d){c=BigInt(c),d=BigInt(d);let e=BigInt(0),f=BigInt(1),g=BigInt(1),h=BigInt(0);for(;c!==BigInt(0);){let a=d/c,b=d%c,i=e-g*a,j=f-h*a;d=c,c=b,e=g,f=h,g=i,h=j}return{b:d,x:e,y:f}}function e(d,e){d=c(d),e=c(e);let f=BigInt(0);for(;!((d|e)&BigInt(1));)d>>=BigInt(1),e>>=BigInt(1),f++;for(;!(d&BigInt(1));)d>>=BigInt(1);do{for(;!(e&BigInt(1));)e>>=BigInt(1);if(d>e){let a=d;d=e,e=a}e-=d}while(e);return d<{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===BigInt(1)?l(c.x,a):null}function h(d,e,f){if(f=BigInt(f),d=l(d,f),e=BigInt(e),e min");const c=a-b;let d,e=n(c);do{let a=await j(e);d=m(a)}while(d>c);return d+b}async function j(a,b=!1){var c=Math.ceil;const d=c(a/8);let e=await 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}async function k(a,b=!1){return new Promise(c=>{let d;d=new Uint8Array(a),self.crypto.getRandomValues(d),b&&(d[0]|=128),c(d)})}function l(b,c){return c=BigInt(c),b=BigInt(b)%c,0>b?b+c:b}function m(a){let b=BigInt(0);for(let c of a.values()){let a=BigInt(c);b=(b<>=BigInt(1))>BigInt(1));return c}function o(){let a=`'use strict';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 = ${p.toString()};${n.toString()}${m.toString()}`;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()};`,a=`(() => {${a}})()`;var b=new Blob([a],{type:"text/javascript"});return window.URL.createObjectURL(b)}async function p(c,b=16){if(c===BigInt(2))return!0;if((c&BigInt(1))===BigInt(0)||c===BigInt(1))return!1;const e=[3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997,1009,1013,1019,1021,1031,1033,1039,1049,1051,1061,1063,1069,1087,1091,1093,1097,1103,1109,1117,1123,1129,1151,1153,1163,1171,1181,1187,1193,1201,1213,1217,1223,1229,1231,1237,1249,1259,1277,1279,1283,1289,1291,1297,1301,1303,1307,1319,1321,1327,1361,1367,1373,1381,1399,1409,1423,1427,1429,1433,1439,1447,1451,1453,1459,1471,1481,1483,1487,1489,1493,1499,1511,1523,1531,1543,1549,1553,1559,1567,1571,1579,1583,1597];for(let a=0;a{let d=[];const e=(e,f)=>{if(e.isPrime){for(let a=0;a{let c=m(a);try{f.postMessage({rnd:c,iterations:b,id:e.id})}catch(a){}})};{let a=o();for(let b,c=0;ce(a.data,b),d.push(b)}for(let e=0;e{let c=m(a);d[e].postMessage({rnd:c,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>=q?b:-b}function d(c,d){c=BigInt(c),d=BigInt(d);let e=q,f=r,g=r,h=q;for(;c!==q;){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=q;for(;!((d|e)&r);)d>>=r,e>>=r,f++;for(;!(d&r);)d>>=r;do{for(;!(e&r);)e>>=r;if(d>e){let a=d;d=e,e=a}e-=d}while(e);return 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===r?l(c.x,a):null}function h(d,e,f){if(f=BigInt(f),d=l(d,f),e=BigInt(e),e min");const c=a-b;let d,e=n(c);do{let a=await j(e);d=m(a)}while(d>c);return d+b}async function j(a,b=!1){var c=Math.ceil;const d=c(a/8);let e=await 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}async function k(a,b=!1){return new Promise(c=>{let d;d=new Uint8Array(a),self.crypto.getRandomValues(d),b&&(d[0]|=128),c(d)})}function l(b,c){return c=BigInt(c),b=BigInt(b)%c,0>b?b+c:b}function m(a){let b=q;for(let c of a.values()){let a=BigInt(c);b=(b<>=r)>r);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 = ${p.toString()};${n.toString()}${m.toString()}`;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()};`,a=`(() => {${a}})()`;var b=new Blob([a],{type:"text/javascript"});return window.URL.createObjectURL(b)}async function p(c,b=16){if(c===s)return!0;if((c&r)===q||c===r)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{let d=[];const e=(e,f)=>{if(e.isPrime){for(let a=0;a{let c=m(a);try{f.postMessage({rnd:c,iterations:b,id:e.id})}catch(a){}})};{let a=o();for(let b,c=0;ce(a.data,b),d.push(b)}for(let e=0;e{let c=m(a);d[e].postMessage({rnd:c,iterations:b,id:e})})})},a.randBetween=i,a.randBits=j,a.randBytes=k,a.toZn=l,a}({}); diff --git a/dist/bigint-crypto-utils-latest.browser.mod.js b/dist/bigint-crypto-utils-latest.browser.mod.js index db939e1..6ca8eb9 100644 --- a/dist/bigint-crypto-utils-latest.browser.mod.js +++ b/dist/bigint-crypto-utils-latest.browser.mod.js @@ -7,7 +7,7 @@ */ function abs(a) { a = BigInt(a); - return (a >= BigInt(0)) ? a : -a; + return (a >= _ZERO) ? a : -a; } /** @@ -28,12 +28,12 @@ function abs(a) { function eGcd(a, b) { a = BigInt(a); b = BigInt(b); - let x = BigInt(0); - let y = BigInt(1); - let u = BigInt(1); - let v = BigInt(0); + let x = _ZERO; + let y = _ONE; + let u = _ONE; + let v = _ZERO; - while (a !== BigInt(0)) { + while (a !== _ZERO) { let q = b / a; let r = b % a; let m = x - (u * q); @@ -63,15 +63,15 @@ function eGcd(a, b) { function gcd(a, b) { a = abs(a); b = abs(b); - let shift = BigInt(0); - while (!((a | b) & BigInt(1))) { - a >>= BigInt(1); - b >>= BigInt(1); + let shift = _ZERO; + while (!((a | b) & _ONE)) { + a >>= _ONE; + b >>= _ONE; shift++; } - while (!(a & BigInt(1))) a >>= BigInt(1); + while (!(a & _ONE)) a >>= _ONE; do { - while (!(b & BigInt(1))) b >>= BigInt(1); + while (!(b & _ONE)) b >>= _ONE; if (a > b) { let x = a; a = b; @@ -139,7 +139,7 @@ function lcm(a, b) { */ function modInv(a, n) { let egcd = eGcd(a, n); - if (egcd.b !== BigInt(1)) { + if (egcd.b !== _ONE) { return null; // modular inverse does not exist } else { return toZn(egcd.x, n); @@ -159,15 +159,15 @@ function modPow(a, b, n) { n = BigInt(n); a = toZn(a, n); b = BigInt(b); - if (b < BigInt(0)) { + if (b < _ZERO) { return modInv(modPow(a, abs(b), n), n); } - let result = BigInt(1); + let result = _ONE; let x = a; while (b > 0) { - var leastSignificantBit = b % BigInt(2); - b = b / BigInt(2); - if (leastSignificantBit == BigInt(1)) { + var leastSignificantBit = b % _TWO; + b = b / _TWO; + if (leastSignificantBit == _ONE) { result = result * x; result = result % n; } @@ -245,7 +245,7 @@ async function prime(bitLength, iterations = 16) { * * @returns {Promise} A promise that resolves to a cryptographically secure random bigint between [min,max] */ -async function randBetween(max, min = BigInt(1)) { +async function randBetween(max, min = _ONE) { if (max <= min) throw new Error('max must be > min'); const interval = max - min; let bitLen = bitLength(interval); @@ -318,7 +318,7 @@ function toZn(a, n) { /* HELPER FUNCTIONS */ function fromBuffer(buf) { - let ret = BigInt(0); + let ret = _ZERO; for (let i of buf.values()) { let bi = BigInt(i); ret = (ret << BigInt(8)) + bi; @@ -330,13 +330,13 @@ function bitLength(a) { let bits = 1; do { bits++; - } while ((a >>= BigInt(1)) > BigInt(1)); + } while ((a >>= _ONE) > _ONE); return bits; } function _isProbablyPrimeWorkerURL() { // Let's us first add all the required functions - let workerCode = `'use strict';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()}`; + 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()}`; const _onmessage = async function (event) { // Let's start once we are called // event.data = {rnd: , iterations: } @@ -361,9 +361,9 @@ async 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 === BigInt(2)) + if (w === _TWO) return true; - else if ((w & BigInt(1)) === BigInt(0) || w === BigInt(1)) + else if ((w & _ONE) === _ZERO || w === _ONE) return false; /* @@ -625,7 +625,7 @@ async function _isProbablyPrime(w, iterations = 16) { const p = BigInt(firstPrimes[i]); if (w === p) return true; - else if (w % p === BigInt(0)) + else if (w % p === _ZERO) return false; } @@ -648,25 +648,25 @@ async function _isProbablyPrime(w, iterations = 16) { Comment: Increment i for the do-loop in step 4. 5. Return PROBABLY PRIME. */ - let a = BigInt(0), d = w - BigInt(1); - while (d % BigInt(2) === BigInt(0)) { - d /= BigInt(2); + let a = _ZERO, d = w - _ONE; + while (d % _TWO === _ZERO) { + d /= _TWO; ++a; } - let m = (w - BigInt(1)) / (BigInt(2) ** a); + let m = (w - _ONE) / (_TWO ** a); loop: do { - let b = await randBetween(w - BigInt(1), BigInt(2)); + let b = await randBetween(w - _ONE, _TWO); let z = modPow(b, m, w); - if (z === BigInt(1) || z === w - BigInt(1)) + if (z === _ONE || z === w - _ONE) continue; for (let j = 1; j < a; j++) { - z = modPow(z, BigInt(2), w); - if (z === w - BigInt(1)) + z = modPow(z, _TWO, w); + if (z === w - _ONE) continue loop; - if (z === BigInt(1)) + if (z === _ONE) break; } return false; @@ -675,4 +675,9 @@ async function _isProbablyPrime(w, iterations = 16) { return true; } +/* HELPLER CONSTANTS/VARIABLES*/ +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 }; diff --git a/dist/bigint-crypto-utils-latest.browser.mod.min.js b/dist/bigint-crypto-utils-latest.browser.mod.min.js index fc9237d..481e672 100644 --- a/dist/bigint-crypto-utils-latest.browser.mod.min.js +++ b/dist/bigint-crypto-utils-latest.browser.mod.min.js @@ -1 +1 @@ -function abs(b){return b=BigInt(b),b>=BigInt(0)?b:-b}function eGcd(c,d){c=BigInt(c),d=BigInt(d);let e=BigInt(0),f=BigInt(1),g=BigInt(1),h=BigInt(0);for(;c!==BigInt(0);){let a=d/c,b=d%c,i=e-g*a,j=f-h*a;d=c,c=b,e=g,f=h,g=i,h=j}return{b:d,x:e,y:f}}function gcd(c,d){c=abs(c),d=abs(d);let e=BigInt(0);for(;!((c|d)&BigInt(1));)c>>=BigInt(1),d>>=BigInt(1),e++;for(;!(c&BigInt(1));)c>>=BigInt(1);do{for(;!(d&BigInt(1));)d>>=BigInt(1);if(c>d){let a=c;c=d,d=a}d-=c}while(d);return c<{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===BigInt(1)?toZn(c.x,a):null}function modPow(c,d,e){if(e=BigInt(e),c=toZn(c,e),d=BigInt(d),d{let d=[];const e=(e,f)=>{if(e.isPrime){for(let a=0;a{let c=fromBuffer(a);try{f.postMessage({rnd:c,iterations:b,id:e.id})}catch(a){}})};{let a=_isProbablyPrimeWorkerURL();for(let b,c=0;ce(a.data,b),d.push(b)}for(let e=0;e{let c=fromBuffer(a);d[e].postMessage({rnd:c,iterations:b,id:e})})})}async function randBetween(a,b=BigInt(1)){if(a<=b)throw new Error("max must be > min");const c=a-b;let d,e=bitLength(c);do{let a=await randBits(e);d=fromBuffer(a)}while(d>c);return d+b}async function randBits(a,b=!1){var c=Math.ceil;const d=c(a/8);let e=await 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}async function randBytes(a,b=!1){return new Promise(c=>{let d;d=new Uint8Array(a),self.crypto.getRandomValues(d),b&&(d[0]|=128),c(d)})}function toZn(b,c){return c=BigInt(c),b=BigInt(b)%c,0>b?b+c:b}function fromBuffer(a){let b=BigInt(0);for(let c of a.values()){let a=BigInt(c);b=(b<>=BigInt(1))>BigInt(1));return c}function _isProbablyPrimeWorkerURL(){let a=`'use strict';const eGcd = ${eGcd.toString()};const modInv = ${modInv.toString()};const modPow = ${modPow.toString()};const toZn = ${toZn.toString()};const randBits = ${randBits.toString()};const randBytes = ${randBytes.toString()};const randBetween = ${randBetween.toString()};const isProbablyPrime = ${_isProbablyPrime.toString()};${bitLength.toString()}${fromBuffer.toString()}`;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()};`,a=`(() => {${a}})()`;var b=new Blob([a],{type:"text/javascript"});return window.URL.createObjectURL(b)}async function _isProbablyPrime(c,b=16){if(c===BigInt(2))return!0;if((c&BigInt(1))===BigInt(0)||c===BigInt(1))return!1;const e=[3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997,1009,1013,1019,1021,1031,1033,1039,1049,1051,1061,1063,1069,1087,1091,1093,1097,1103,1109,1117,1123,1129,1151,1153,1163,1171,1181,1187,1193,1201,1213,1217,1223,1229,1231,1237,1249,1259,1277,1279,1283,1289,1291,1297,1301,1303,1307,1319,1321,1327,1361,1367,1373,1381,1399,1409,1423,1427,1429,1433,1439,1447,1451,1453,1459,1471,1481,1483,1487,1489,1493,1499,1511,1523,1531,1543,1549,1553,1559,1567,1571,1579,1583,1597];for(let a=0;a=_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<{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{let d=[];const e=(e,f)=>{if(e.isPrime){for(let a=0;a{let c=fromBuffer(a);try{f.postMessage({rnd:c,iterations:b,id:e.id})}catch(a){}})};{let a=_isProbablyPrimeWorkerURL();for(let b,c=0;ce(a.data,b),d.push(b)}for(let e=0;e{let c=fromBuffer(a);d[e].postMessage({rnd:c,iterations:b,id:e})})})}async 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=await randBits(e);d=fromBuffer(a)}while(d>c);return d+b}async function randBits(a,b=!1){var c=Math.ceil;const d=c(a/8);let e=await 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}async function randBytes(a,b=!1){return new Promise(c=>{let d;d=new Uint8Array(a),self.crypto.getRandomValues(d),b&&(d[0]|=128),c(d)})}function toZn(b,c){return c=BigInt(c),b=BigInt(b)%c,0>b?b+c:b}function fromBuffer(a){let b=_ZERO;for(let c of a.values()){let a=BigInt(c);b=(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()}`;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()};`,a=`(() => {${a}})()`;var b=new Blob([a],{type:"text/javascript"});return window.URL.createObjectURL(b)}async 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= BigInt(0)) ? a : -a; + return (a >= _ZERO) ? a : -a; } /** @@ -32,12 +32,12 @@ function abs(a) { function eGcd(a, b) { a = BigInt(a); b = BigInt(b); - let x = BigInt(0); - let y = BigInt(1); - let u = BigInt(1); - let v = BigInt(0); + let x = _ZERO; + let y = _ONE; + let u = _ONE; + let v = _ZERO; - while (a !== BigInt(0)) { + while (a !== _ZERO) { let q = b / a; let r = b % a; let m = x - (u * q); @@ -67,15 +67,15 @@ function eGcd(a, b) { function gcd(a, b) { a = abs(a); b = abs(b); - let shift = BigInt(0); - while (!((a | b) & BigInt(1))) { - a >>= BigInt(1); - b >>= BigInt(1); + let shift = _ZERO; + while (!((a | b) & _ONE)) { + a >>= _ONE; + b >>= _ONE; shift++; } - while (!(a & BigInt(1))) a >>= BigInt(1); + while (!(a & _ONE)) a >>= _ONE; do { - while (!(b & BigInt(1))) b >>= BigInt(1); + while (!(b & _ONE)) b >>= _ONE; if (a > b) { let x = a; a = b; @@ -147,7 +147,7 @@ function lcm(a, b) { */ function modInv(a, n) { let egcd = eGcd(a, n); - if (egcd.b !== BigInt(1)) { + if (egcd.b !== _ONE) { return null; // modular inverse does not exist } else { return toZn(egcd.x, n); @@ -167,15 +167,15 @@ function modPow(a, b, n) { n = BigInt(n); a = toZn(a, n); b = BigInt(b); - if (b < BigInt(0)) { + if (b < _ZERO) { return modInv(modPow(a, abs(b), n), n); } - let result = BigInt(1); + let result = _ONE; let x = a; while (b > 0) { - var leastSignificantBit = b % BigInt(2); - b = b / BigInt(2); - if (leastSignificantBit == BigInt(1)) { + var leastSignificantBit = b % _TWO; + b = b / _TWO; + if (leastSignificantBit == _ONE) { result = result * x; result = result % n; } @@ -199,7 +199,7 @@ function modPow(a, b, n) { */ async function prime(bitLength, iterations = 16) { if (!_useWorkers) { - let rnd = BigInt(0); + let rnd = _ZERO; do { rnd = fromBuffer(await randBytes(bitLength / 8, true)); } while (! await _isProbablyPrime(rnd, iterations)); @@ -261,7 +261,7 @@ async function prime(bitLength, iterations = 16) { * * @returns {Promise} A promise that resolves to a cryptographically secure random bigint between [min,max] */ -async function randBetween(max, min = BigInt(1)) { +async function randBetween(max, min = _ONE) { if (max <= min) throw new Error('max must be > min'); const interval = max - min; let bitLen = bitLength(interval); @@ -337,7 +337,7 @@ function toZn(a, n) { /* HELPER FUNCTIONS */ function fromBuffer(buf) { - let ret = BigInt(0); + let ret = _ZERO; for (let i of buf.values()) { let bi = BigInt(i); ret = (ret << BigInt(8)) + bi; @@ -349,7 +349,7 @@ function bitLength(a) { let bits = 1; do { bits++; - } while ((a >>= BigInt(1)) > BigInt(1)); + } while ((a >>= _ONE) > _ONE); return bits; } @@ -358,9 +358,9 @@ async 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 === BigInt(2)) + if (w === _TWO) return true; - else if ((w & BigInt(1)) === BigInt(0) || w === BigInt(1)) + else if ((w & _ONE) === _ZERO || w === _ONE) return false; /* @@ -622,7 +622,7 @@ async function _isProbablyPrime(w, iterations = 16) { const p = BigInt(firstPrimes[i]); if (w === p) return true; - else if (w % p === BigInt(0)) + else if (w % p === _ZERO) return false; } @@ -645,25 +645,25 @@ async function _isProbablyPrime(w, iterations = 16) { Comment: Increment i for the do-loop in step 4. 5. Return PROBABLY PRIME. */ - let a = BigInt(0), d = w - BigInt(1); - while (d % BigInt(2) === BigInt(0)) { - d /= BigInt(2); + let a = _ZERO, d = w - _ONE; + while (d % _TWO === _ZERO) { + d /= _TWO; ++a; } - let m = (w - BigInt(1)) / (BigInt(2) ** a); + let m = (w - _ONE) / (_TWO ** a); loop: do { - let b = await randBetween(w - BigInt(1), BigInt(2)); + let b = await randBetween(w - _ONE, _TWO); let z = modPow(b, m, w); - if (z === BigInt(1) || z === w - BigInt(1)) + if (z === _ONE || z === w - _ONE) continue; for (let j = 1; j < a; j++) { - z = modPow(z, BigInt(2), w); - if (z === w - BigInt(1)) + z = modPow(z, _TWO, w); + if (z === w - _ONE) continue loop; - if (z === BigInt(1)) + if (z === _ONE) break; } return false; @@ -672,9 +672,13 @@ async function _isProbablyPrime(w, iterations = 16) { return true; } -let _useWorkers = true; +/* HELPLER CONSTANTS/VARIABLES*/ +const _ZERO = BigInt(0); +const _ONE = BigInt(1); +const _TWO = BigInt(2); -{ +let _useWorkers = true; // The following is just to check wheter Node.js can use workers +{ // Node.js _useWorkers = (function _workers() { try { require.resolve('worker_threads'); @@ -689,7 +693,9 @@ This node version doesn't support worker_threads. You should enable them in orde })(); } -if (_useWorkers) { // node.js + + +if (_useWorkers) { // node.js with support for workers const { parentPort, isMainThread } = require('worker_threads'); if (!isMainThread) { // worker parentPort.on('message', async function (data) { // Let's start once we are called diff --git a/src/main.js b/src/main.js index 7998f73..fc86544 100644 --- a/src/main.js +++ b/src/main.js @@ -9,7 +9,7 @@ */ export function abs(a) { a = BigInt(a); - return (a >= BigInt(0)) ? a : -a; + return (a >= _ZERO) ? a : -a; } /** @@ -30,12 +30,12 @@ export function abs(a) { export function eGcd(a, b) { a = BigInt(a); b = BigInt(b); - let x = BigInt(0); - let y = BigInt(1); - let u = BigInt(1); - let v = BigInt(0); + let x = _ZERO; + let y = _ONE; + let u = _ONE; + let v = _ZERO; - while (a !== BigInt(0)) { + while (a !== _ZERO) { let q = b / a; let r = b % a; let m = x - (u * q); @@ -65,15 +65,15 @@ export function eGcd(a, b) { export function gcd(a, b) { a = abs(a); b = abs(b); - let shift = BigInt(0); - while (!((a | b) & BigInt(1))) { - a >>= BigInt(1); - b >>= BigInt(1); + let shift = _ZERO; + while (!((a | b) & _ONE)) { + a >>= _ONE; + b >>= _ONE; shift++; } - while (!(a & BigInt(1))) a >>= BigInt(1); + while (!(a & _ONE)) a >>= _ONE; do { - while (!(b & BigInt(1))) b >>= BigInt(1); + while (!(b & _ONE)) b >>= _ONE; if (a > b) { let x = a; a = b; @@ -164,7 +164,7 @@ export function lcm(a, b) { */ export function modInv(a, n) { let egcd = eGcd(a, n); - if (egcd.b !== BigInt(1)) { + if (egcd.b !== _ONE) { return null; // modular inverse does not exist } else { return toZn(egcd.x, n); @@ -184,15 +184,15 @@ export function modPow(a, b, n) { n = BigInt(n); a = toZn(a, n); b = BigInt(b); - if (b < BigInt(0)) { + if (b < _ZERO) { return modInv(modPow(a, abs(b), n), n); } - let result = BigInt(1); + let result = _ONE; let x = a; while (b > 0) { - var leastSignificantBit = b % BigInt(2); - b = b / BigInt(2); - if (leastSignificantBit == BigInt(1)) { + var leastSignificantBit = b % _TWO; + b = b / _TWO; + if (leastSignificantBit == _ONE) { result = result * x; result = result % n; } @@ -216,7 +216,7 @@ export function modPow(a, b, n) { */ export async function prime(bitLength, iterations = 16) { if (!process.browser && !_useWorkers) { - let rnd = BigInt(0); + let rnd = _ZERO; do { rnd = fromBuffer(await randBytes(bitLength / 8, true)); } while (! await _isProbablyPrime(rnd, iterations)); @@ -285,7 +285,7 @@ export async function prime(bitLength, iterations = 16) { * * @returns {Promise} A promise that resolves to a cryptographically secure random bigint between [min,max] */ -export async function randBetween(max, min = BigInt(1)) { +export async function randBetween(max, min = _ONE) { if (max <= min) throw new Error('max must be > min'); const interval = max - min; let bitLen = bitLength(interval); @@ -368,7 +368,7 @@ export function toZn(a, n) { /* HELPER FUNCTIONS */ function fromBuffer(buf) { - let ret = BigInt(0); + let ret = _ZERO; for (let i of buf.values()) { let bi = BigInt(i); ret = (ret << BigInt(8)) + bi; @@ -380,13 +380,13 @@ function bitLength(a) { let bits = 1; do { bits++; - } while ((a >>= BigInt(1)) > BigInt(1)); + } while ((a >>= _ONE) > _ONE); return bits; } function _isProbablyPrimeWorkerURL() { // Let's us first add all the required functions - let workerCode = `'use strict';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()}`; + 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()}`; const _onmessage = async function (event) { // Let's start once we are called // event.data = {rnd: , iterations: } @@ -411,9 +411,9 @@ async 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 === BigInt(2)) + if (w === _TWO) return true; - else if ((w & BigInt(1)) === BigInt(0) || w === BigInt(1)) + else if ((w & _ONE) === _ZERO || w === _ONE) return false; /* @@ -675,7 +675,7 @@ async function _isProbablyPrime(w, iterations = 16) { const p = BigInt(firstPrimes[i]); if (w === p) return true; - else if (w % p === BigInt(0)) + else if (w % p === _ZERO) return false; } @@ -698,25 +698,25 @@ async function _isProbablyPrime(w, iterations = 16) { Comment: Increment i for the do-loop in step 4. 5. Return PROBABLY PRIME. */ - let a = BigInt(0), d = w - BigInt(1); - while (d % BigInt(2) === BigInt(0)) { - d /= BigInt(2); + let a = _ZERO, d = w - _ONE; + while (d % _TWO === _ZERO) { + d /= _TWO; ++a; } - let m = (w - BigInt(1)) / (BigInt(2) ** a); + let m = (w - _ONE) / (_TWO ** a); loop: do { - let b = await randBetween(w - BigInt(1), BigInt(2)); + let b = await randBetween(w - _ONE, _TWO); let z = modPow(b, m, w); - if (z === BigInt(1) || z === w - BigInt(1)) + if (z === _ONE || z === w - _ONE) continue; for (let j = 1; j < a; j++) { - z = modPow(z, BigInt(2), w); - if (z === w - BigInt(1)) + z = modPow(z, _TWO, w); + if (z === w - _ONE) continue loop; - if (z === BigInt(1)) + if (z === _ONE) break; } return false; @@ -725,9 +725,13 @@ async function _isProbablyPrime(w, iterations = 16) { return true; } -let _useWorkers = true; +/* HELPLER CONSTANTS/VARIABLES*/ +const _ZERO = BigInt(0); +const _ONE = BigInt(1); +const _TWO = BigInt(2); -if (!process.browser) { +let _useWorkers = true; // The following is just to check wheter Node.js can use workers +if (!process.browser) { // Node.js _useWorkers = (function _workers() { try { require.resolve('worker_threads'); @@ -742,7 +746,9 @@ This node version doesn't support worker_threads. You should enable them in orde })(); } -if (!process.browser && _useWorkers) { // node.js + + +if (!process.browser && _useWorkers) { // node.js with support for workers const { parentPort, isMainThread } = require('worker_threads'); if (!isMainThread) { // worker parentPort.on('message', async function (data) { // Let's start once we are called