From 3f571c9dd699695099a88314e89eea6693aec049 Mon Sep 17 00:00:00 2001 From: juanelas Date: Fri, 26 Apr 2019 15:03:53 +0200 Subject: [PATCH] If it is not truly async then is sync --- README.md | 18 +-- dist/bigint-crypto-utils-latest.browser.js | 96 +++++++------- .../bigint-crypto-utils-latest.browser.min.js | 2 +- .../bigint-crypto-utils-latest.browser.mod.js | 96 +++++++------- ...int-crypto-utils-latest.browser.mod.min.js | 2 +- dist/bigint-crypto-utils-latest.node.js | 97 +++++++------- src/main.js | 124 +++++++++--------- 7 files changed, 210 insertions(+), 225 deletions(-) diff --git a/README.md b/README.md index c627f33..9b20dbf 100644 --- a/README.md +++ b/README.md @@ -114,13 +114,13 @@ main process, and it can be much faster (if several cores or cpu are available). The node version can also use worker_threads if they are available (enabled by default with Node 11 and and can be enabled at runtime executing node --experimental-worker with node >=10.5.0).

-
randBetween(max, min)Promise
+
randBetween(max, min)bigint

Returns a cryptographically secure random integer between [min,max]

-
randBits(bitLength, forceLength)Promise
+
randBits(bitLength, forceLength)Buffer | Uint8Array

Secure random bits for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()

-
randBytes(byteLength, forceLength)Promise
+
randBytes(byteLength, forceLength)Buffer | Uint8Array

Secure random bytes for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues()

toZn(a, n)bigint
@@ -247,11 +247,11 @@ and can be enabled at runtime executing node --experimental-worker with node >=1 -## randBetween(max, min) ⇒ Promise +## randBetween(max, min) ⇒ bigint Returns a cryptographically secure random integer between [min,max] **Kind**: global function -**Returns**: Promise - A promise that resolves to a cryptographically secure random bigint between [min,max] +**Returns**: bigint - A cryptographically secure random bigint between [min,max] | Param | Type | Description | | --- | --- | --- | @@ -260,11 +260,11 @@ Returns a cryptographically secure random integer between [min,max] -## randBits(bitLength, forceLength) ⇒ Promise +## randBits(bitLength, forceLength) ⇒ Buffer \| Uint8Array Secure random bits for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues() **Kind**: global function -**Returns**: Promise - A promise that resolves to a Buffer/UInt8Array filled with cryptographically secure random bits +**Returns**: Buffer \| Uint8Array - A Buffer/UInt8Array filled with cryptographically secure random bits | Param | Type | Description | | --- | --- | --- | @@ -273,11 +273,11 @@ Secure random bits for both node and browsers. Node version uses crypto.randomFi -## randBytes(byteLength, forceLength) ⇒ Promise +## randBytes(byteLength, forceLength) ⇒ Buffer \| Uint8Array Secure random bytes for both node and browsers. Node version uses crypto.randomFill() and browser one self.crypto.getRandomValues() **Kind**: global function -**Returns**: Promise - A promise that resolves to a Buffer/UInt8Array filled with cryptographically secure random bytes +**Returns**: Buffer \| Uint8Array - A Buffer/UInt8Array filled with cryptographically secure random bytes | Param | Type | Description | | --- | --- | --- | diff --git a/dist/bigint-crypto-utils-latest.browser.js b/dist/bigint-crypto-utils-latest.browser.js index 6132e52..79e51fa 100644 --- a/dist/bigint-crypto-utils-latest.browser.js +++ b/dist/bigint-crypto-utils-latest.browser.js @@ -99,7 +99,7 @@ var bigintCryptoUtils = (function (exports) { async function isProbablyPrime(w, iterations = 16) { { // browser return new Promise((resolve, reject) => { - let worker = new Worker(_isProbablyPrimeWorkerURL()); + let worker = new Worker(_isProbablyPrimeWorkerUrl()); worker.onmessage = (event) => { worker.terminate(); @@ -192,7 +192,7 @@ var bigintCryptoUtils = (function (exports) { * * @returns {Promise} A promise that resolves to a bigint probable prime of bitLength bits */ - async function prime(bitLength, iterations = 16) { + function prime(bitLength, iterations = 16) { return new Promise((resolve) => { let workerList = []; const _onmessage = (msg, newWorker) => { @@ -206,22 +206,21 @@ var bigintCryptoUtils = (function (exports) { } resolve(msg.value); } else { // if a composite is found, make the worker test another random number - randBits(bitLength, true).then((buf) => { - let rnd = fromBuffer(buf); - try { - newWorker.postMessage({ - 'rnd': rnd, - 'iterations': iterations, - 'id': msg.id - }); - } catch (error) { - // The worker has already terminated. There is nothing to handle here - } - }); + let buf = randBits(bitLength, true); + let rnd = fromBuffer(buf); + try { + newWorker.postMessage({ + 'rnd': rnd, + 'iterations': iterations, + 'id': msg.id + }); + } catch (error) { + // The worker has already terminated. There is nothing to handle here + } } }; { //browser - let workerURL = _isProbablyPrimeWorkerURL(); + let workerURL = _isProbablyPrimeWorkerUrl(); for (let i = 0; i < self.navigator.hardwareConcurrency; i++) { let newWorker = new Worker(workerURL); newWorker.onmessage = (event) => _onmessage(event.data, newWorker); @@ -229,13 +228,12 @@ var bigintCryptoUtils = (function (exports) { } } for (let i = 0; i < workerList.length; i++) { - randBits(bitLength, true).then((buf) => { - let rnd = fromBuffer(buf); - workerList[i].postMessage({ - 'rnd': rnd, - 'iterations': iterations, - 'id': i - }); + let buf = randBits(bitLength, true); + let rnd = fromBuffer(buf); + workerList[i].postMessage({ + 'rnd': rnd, + 'iterations': iterations, + 'id': i }); } }); @@ -246,15 +244,15 @@ var bigintCryptoUtils = (function (exports) { * @param {bigint} max Returned value will be <= max * @param {bigint} min Returned value will be >= min * - * @returns {Promise} A promise that resolves to a cryptographically secure random bigint between [min,max] + * @returns {bigint} A cryptographically secure random bigint between [min,max] */ - async function randBetween(max, min = _ONE) { + function randBetween(max, min = _ONE) { if (max <= min) throw new Error('max must be > min'); const interval = max - min; let bitLen = bitLength(interval); let rnd; do { - let buf = await randBits(bitLen); + let buf = randBits(bitLen); rnd = fromBuffer(buf); } while (rnd > interval); return rnd + min; @@ -266,11 +264,11 @@ var bigintCryptoUtils = (function (exports) { * @param {number} bitLength The desired number of random bits * @param {boolean} forceLength If we want to force the output to have a specific bit length. It basically forces the msb to be 1 * - * @returns {Promise} A promise that resolves to a Buffer/UInt8Array filled with cryptographically secure random bits + * @returns {Buffer|Uint8Array} A Buffer/UInt8Array filled with cryptographically secure random bits */ - async function randBits(bitLength, forceLength = false) { + function randBits(bitLength, forceLength = false) { const byteLength = Math.ceil(bitLength / 8); - let rndBytes = await randBytes(byteLength, false); + let rndBytes = randBytes(byteLength, false); // Fill with 0's the extra birs rndBytes[0] = rndBytes[0] & (2 ** (bitLength % 8) - 1); if (forceLength) { @@ -286,21 +284,18 @@ var bigintCryptoUtils = (function (exports) { * @param {number} byteLength The desired number of random bytes * @param {boolean} forceLength If we want to force the output to have a bit length of 8*byteLength. It basically forces the msb to be 1 * - * @returns {Promise} A promise that resolves to a Buffer/UInt8Array filled with cryptographically secure random bytes + * @returns {Buffer|Uint8Array} A Buffer/UInt8Array filled with cryptographically secure random bytes */ - async function randBytes(byteLength, forceLength = false) { - return new Promise((resolve) => { - let buf; - - { // browser - buf = new Uint8Array(byteLength); - self.crypto.getRandomValues(buf); - // If fixed length is required we put the first bit to 1 -> to get the necessary bitLength - if (forceLength) - buf[0] = buf[0] | 128; - resolve(buf); - } - }); + function randBytes(byteLength, forceLength = false) { + let buf; + { // browser + buf = new Uint8Array(byteLength); + self.crypto.getRandomValues(buf); + } + // If fixed length is required we put the first bit to 1 -> to get the necessary bitLength + if (forceLength) + buf[0] = buf[0] | 128; + return buf; } /** @@ -337,11 +332,11 @@ var bigintCryptoUtils = (function (exports) { return bits; } - function _isProbablyPrimeWorkerURL() { + 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()}`; - const _onmessage = async function (event) { // Let's start once we are called + const onmessage = async function (event) { // Let's start once we are called // event.data = {rnd: , iterations: } const isPrime = await isProbablyPrime(event.data.rnd, event.data.iterations); postMessage({ @@ -350,16 +345,19 @@ var bigintCryptoUtils = (function (exports) { 'id': event.data.id }); }; - workerCode += `onmessage = ${_onmessage.toString()};`; + + workerCode += `onmessage = ${onmessage.toString()};`; + return _workerUrl(workerCode); + } + + function _workerUrl(workerCode) { workerCode = `(() => {${workerCode}})()`; // encapsulate IIFE - var _blob = new Blob([workerCode], { type: 'text/javascript' }); - return window.URL.createObjectURL(_blob); } - async function _isProbablyPrime(w, iterations = 16) { + 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. @@ -660,7 +658,7 @@ var bigintCryptoUtils = (function (exports) { let m = (w - _ONE) / (_TWO ** a); loop: do { - let b = await randBetween(w - _ONE, _TWO); + let b = randBetween(w - _ONE, _TWO); let z = modPow(b, m, w); if (z === _ONE || z === w - _ONE) continue; diff --git a/dist/bigint-crypto-utils-latest.browser.min.js b/dist/bigint-crypto-utils-latest.browser.min.js index 9a4a0f8..5083289 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>=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}({}); +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<{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 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<>=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{let d=[];const e=(e,f)=>{if(e.isPrime){for(let a=0;ae(a.data,b),d.push(b)}for(let e=0;e { - let worker = new Worker(_isProbablyPrimeWorkerURL()); + let worker = new Worker(_isProbablyPrimeWorkerUrl()); worker.onmessage = (event) => { worker.terminate(); @@ -189,7 +189,7 @@ function modPow(a, b, n) { * * @returns {Promise} A promise that resolves to a bigint probable prime of bitLength bits */ -async function prime(bitLength, iterations = 16) { +function prime(bitLength, iterations = 16) { return new Promise((resolve) => { let workerList = []; const _onmessage = (msg, newWorker) => { @@ -203,22 +203,21 @@ async function prime(bitLength, iterations = 16) { } resolve(msg.value); } else { // if a composite is found, make the worker test another random number - randBits(bitLength, true).then((buf) => { - let rnd = fromBuffer(buf); - try { - newWorker.postMessage({ - 'rnd': rnd, - 'iterations': iterations, - 'id': msg.id - }); - } catch (error) { - // The worker has already terminated. There is nothing to handle here - } - }); + let buf = randBits(bitLength, true); + let rnd = fromBuffer(buf); + try { + newWorker.postMessage({ + 'rnd': rnd, + 'iterations': iterations, + 'id': msg.id + }); + } catch (error) { + // The worker has already terminated. There is nothing to handle here + } } }; { //browser - let workerURL = _isProbablyPrimeWorkerURL(); + let workerURL = _isProbablyPrimeWorkerUrl(); for (let i = 0; i < self.navigator.hardwareConcurrency; i++) { let newWorker = new Worker(workerURL); newWorker.onmessage = (event) => _onmessage(event.data, newWorker); @@ -226,13 +225,12 @@ async function prime(bitLength, iterations = 16) { } } for (let i = 0; i < workerList.length; i++) { - randBits(bitLength, true).then((buf) => { - let rnd = fromBuffer(buf); - workerList[i].postMessage({ - 'rnd': rnd, - 'iterations': iterations, - 'id': i - }); + let buf = randBits(bitLength, true); + let rnd = fromBuffer(buf); + workerList[i].postMessage({ + 'rnd': rnd, + 'iterations': iterations, + 'id': i }); } }); @@ -243,15 +241,15 @@ async function prime(bitLength, iterations = 16) { * @param {bigint} max Returned value will be <= max * @param {bigint} min Returned value will be >= min * - * @returns {Promise} A promise that resolves to a cryptographically secure random bigint between [min,max] + * @returns {bigint} A cryptographically secure random bigint between [min,max] */ -async function randBetween(max, min = _ONE) { +function randBetween(max, min = _ONE) { if (max <= min) throw new Error('max must be > min'); const interval = max - min; let bitLen = bitLength(interval); let rnd; do { - let buf = await randBits(bitLen); + let buf = randBits(bitLen); rnd = fromBuffer(buf); } while (rnd > interval); return rnd + min; @@ -263,11 +261,11 @@ async function randBetween(max, min = _ONE) { * @param {number} bitLength The desired number of random bits * @param {boolean} forceLength If we want to force the output to have a specific bit length. It basically forces the msb to be 1 * - * @returns {Promise} A promise that resolves to a Buffer/UInt8Array filled with cryptographically secure random bits + * @returns {Buffer|Uint8Array} A Buffer/UInt8Array filled with cryptographically secure random bits */ -async function randBits(bitLength, forceLength = false) { +function randBits(bitLength, forceLength = false) { const byteLength = Math.ceil(bitLength / 8); - let rndBytes = await randBytes(byteLength, false); + let rndBytes = randBytes(byteLength, false); // Fill with 0's the extra birs rndBytes[0] = rndBytes[0] & (2 ** (bitLength % 8) - 1); if (forceLength) { @@ -283,21 +281,18 @@ async function randBits(bitLength, forceLength = false) { * @param {number} byteLength The desired number of random bytes * @param {boolean} forceLength If we want to force the output to have a bit length of 8*byteLength. It basically forces the msb to be 1 * - * @returns {Promise} A promise that resolves to a Buffer/UInt8Array filled with cryptographically secure random bytes + * @returns {Buffer|Uint8Array} A Buffer/UInt8Array filled with cryptographically secure random bytes */ -async function randBytes(byteLength, forceLength = false) { - return new Promise((resolve) => { - let buf; - - { // browser - buf = new Uint8Array(byteLength); - self.crypto.getRandomValues(buf); - // If fixed length is required we put the first bit to 1 -> to get the necessary bitLength - if (forceLength) - buf[0] = buf[0] | 128; - resolve(buf); - } - }); +function randBytes(byteLength, forceLength = false) { + let buf; + { // browser + buf = new Uint8Array(byteLength); + self.crypto.getRandomValues(buf); + } + // If fixed length is required we put the first bit to 1 -> to get the necessary bitLength + if (forceLength) + buf[0] = buf[0] | 128; + return buf; } /** @@ -334,11 +329,11 @@ function bitLength(a) { return bits; } -function _isProbablyPrimeWorkerURL() { +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()}`; - const _onmessage = async function (event) { // Let's start once we are called + const onmessage = async function (event) { // Let's start once we are called // event.data = {rnd: , iterations: } const isPrime = await isProbablyPrime(event.data.rnd, event.data.iterations); postMessage({ @@ -347,16 +342,19 @@ function _isProbablyPrimeWorkerURL() { 'id': event.data.id }); }; - workerCode += `onmessage = ${_onmessage.toString()};`; + + workerCode += `onmessage = ${onmessage.toString()};`; + return _workerUrl(workerCode); +} + +function _workerUrl(workerCode) { workerCode = `(() => {${workerCode}})()`; // encapsulate IIFE - var _blob = new Blob([workerCode], { type: 'text/javascript' }); - return window.URL.createObjectURL(_blob); } -async function _isProbablyPrime(w, iterations = 16) { +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. @@ -657,7 +655,7 @@ async function _isProbablyPrime(w, iterations = 16) { let m = (w - _ONE) / (_TWO ** a); loop: do { - let b = await randBetween(w - _ONE, _TWO); + let b = randBetween(w - _ONE, _TWO); let z = modPow(b, m, w); if (z === _ONE || z === w - _ONE) continue; diff --git a/dist/bigint-crypto-utils-latest.browser.mod.min.js b/dist/bigint-crypto-utils-latest.browser.mod.min.js index 481e672..cbef25c 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>=_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=_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;ae(a.data,b),d.push(b)}for(let e=0;e 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<>=_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 { + resolve(_isProbablyPrime(w, iterations)); + }); } } } @@ -197,13 +199,13 @@ function modPow(a, b, n) { * * @returns {Promise} A promise that resolves to a bigint probable prime of bitLength bits */ -async function prime(bitLength, iterations = 16) { +function prime(bitLength, iterations = 16) { if (!_useWorkers) { let rnd = _ZERO; do { - rnd = fromBuffer(await randBytes(bitLength / 8, true)); - } while (! await _isProbablyPrime(rnd, iterations)); - return rnd; + rnd = fromBuffer(randBytes(bitLength / 8, true)); + } while (!_isProbablyPrime(rnd, iterations)); + return new Promise((resolve) => { resolve(rnd); }); } return new Promise((resolve) => { let workerList = []; @@ -218,18 +220,17 @@ async function prime(bitLength, iterations = 16) { } resolve(msg.value); } else { // if a composite is found, make the worker test another random number - randBits(bitLength, true).then((buf) => { - let rnd = fromBuffer(buf); - try { - newWorker.postMessage({ - 'rnd': rnd, - 'iterations': iterations, - 'id': msg.id - }); - } catch (error) { - // The worker has already terminated. There is nothing to handle here - } - }); + let buf = randBits(bitLength, true); + let rnd = fromBuffer(buf); + try { + newWorker.postMessage({ + 'rnd': rnd, + 'iterations': iterations, + 'id': msg.id + }); + } catch (error) { + // The worker has already terminated. There is nothing to handle here + } } }; { // Node.js @@ -242,13 +243,12 @@ async function prime(bitLength, iterations = 16) { } } for (let i = 0; i < workerList.length; i++) { - randBits(bitLength, true).then((buf) => { - let rnd = fromBuffer(buf); - workerList[i].postMessage({ - 'rnd': rnd, - 'iterations': iterations, - 'id': i - }); + let buf = randBits(bitLength, true); + let rnd = fromBuffer(buf); + workerList[i].postMessage({ + 'rnd': rnd, + 'iterations': iterations, + 'id': i }); } }); @@ -259,15 +259,15 @@ async function prime(bitLength, iterations = 16) { * @param {bigint} max Returned value will be <= max * @param {bigint} min Returned value will be >= min * - * @returns {Promise} A promise that resolves to a cryptographically secure random bigint between [min,max] + * @returns {bigint} A cryptographically secure random bigint between [min,max] */ -async function randBetween(max, min = _ONE) { +function randBetween(max, min = _ONE) { if (max <= min) throw new Error('max must be > min'); const interval = max - min; let bitLen = bitLength(interval); let rnd; do { - let buf = await randBits(bitLen); + let buf = randBits(bitLen); rnd = fromBuffer(buf); } while (rnd > interval); return rnd + min; @@ -279,11 +279,11 @@ async function randBetween(max, min = _ONE) { * @param {number} bitLength The desired number of random bits * @param {boolean} forceLength If we want to force the output to have a specific bit length. It basically forces the msb to be 1 * - * @returns {Promise} A promise that resolves to a Buffer/UInt8Array filled with cryptographically secure random bits + * @returns {Buffer|Uint8Array} A Buffer/UInt8Array filled with cryptographically secure random bits */ -async function randBits(bitLength, forceLength = false) { +function randBits(bitLength, forceLength = false) { const byteLength = Math.ceil(bitLength / 8); - let rndBytes = await randBytes(byteLength, false); + let rndBytes = randBytes(byteLength, false); // Fill with 0's the extra birs rndBytes[0] = rndBytes[0] & (2 ** (bitLength % 8) - 1); if (forceLength) { @@ -299,24 +299,19 @@ async function randBits(bitLength, forceLength = false) { * @param {number} byteLength The desired number of random bytes * @param {boolean} forceLength If we want to force the output to have a bit length of 8*byteLength. It basically forces the msb to be 1 * - * @returns {Promise} A promise that resolves to a Buffer/UInt8Array filled with cryptographically secure random bytes + * @returns {Buffer|Uint8Array} A Buffer/UInt8Array filled with cryptographically secure random bytes */ -async function randBytes(byteLength, forceLength = false) { - return new Promise((resolve) => { - let buf; - - { // node - const crypto = require('crypto'); - buf = Buffer.alloc(byteLength); - crypto.randomFill(buf, (err, buf) => { - // If fixed length is required we put the first bit to 1 -> to get the necessary bitLength - if (forceLength) - buf[0] = buf[0] | 128; - - resolve(buf); - }); - } - }); +function randBytes(byteLength, forceLength = false) { + let buf; + { // node + const crypto = require('crypto'); + buf = Buffer.alloc(byteLength); + crypto.randomFillSync(buf); + } + // If fixed length is required we put the first bit to 1 -> to get the necessary bitLength + if (forceLength) + buf[0] = buf[0] | 128; + return buf; } /** @@ -353,7 +348,7 @@ function bitLength(a) { return bits; } -async function _isProbablyPrime(w, iterations = 16) { +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. @@ -654,7 +649,7 @@ async function _isProbablyPrime(w, iterations = 16) { let m = (w - _ONE) / (_TWO ** a); loop: do { - let b = await randBetween(w - _ONE, _TWO); + let b = randBetween(w - _ONE, _TWO); let z = modPow(b, m, w); if (z === _ONE || z === w - _ONE) continue; @@ -698,9 +693,9 @@ This node version doesn't support worker_threads. You should enable them in orde 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 + parentPort.on('message', function (data) { // Let's start once we are called // data = {rnd: , iterations: } - const isPrime = await _isProbablyPrime(data.rnd, data.iterations); + const isPrime = _isProbablyPrime(data.rnd, data.iterations); parentPort.postMessage({ 'isPrime': isPrime, 'value': data.rnd, diff --git a/src/main.js b/src/main.js index e16084f..b60a6d2 100644 --- a/src/main.js +++ b/src/main.js @@ -117,11 +117,13 @@ export async function isProbablyPrime(w, iterations = 16) { }); }); } else { - return _isProbablyPrime(w, iterations); + return new Promise((resolve) => { + resolve(_isProbablyPrime(w, iterations)); + }); } } else { // browser return new Promise((resolve, reject) => { - let worker = new Worker(_isProbablyPrimeWorkerURL()); + let worker = new Worker(_isProbablyPrimeWorkerUrl()); worker.onmessage = (event) => { worker.terminate(); @@ -214,13 +216,13 @@ export function modPow(a, b, n) { * * @returns {Promise} A promise that resolves to a bigint probable prime of bitLength bits */ -export async function prime(bitLength, iterations = 16) { +export function prime(bitLength, iterations = 16) { if (!process.browser && !_useWorkers) { let rnd = _ZERO; do { - rnd = fromBuffer(await randBytes(bitLength / 8, true)); - } while (! await _isProbablyPrime(rnd, iterations)); - return rnd; + rnd = fromBuffer(randBytes(bitLength / 8, true)); + } while (!_isProbablyPrime(rnd, iterations)); + return new Promise((resolve) => { resolve(rnd); }); } return new Promise((resolve) => { let workerList = []; @@ -235,22 +237,21 @@ export async function prime(bitLength, iterations = 16) { } resolve(msg.value); } else { // if a composite is found, make the worker test another random number - randBits(bitLength, true).then((buf) => { - let rnd = fromBuffer(buf); - try { - newWorker.postMessage({ - 'rnd': rnd, - 'iterations': iterations, - 'id': msg.id - }); - } catch (error) { - // The worker has already terminated. There is nothing to handle here - } - }); + let buf = randBits(bitLength, true); + let rnd = fromBuffer(buf); + try { + newWorker.postMessage({ + 'rnd': rnd, + 'iterations': iterations, + 'id': msg.id + }); + } catch (error) { + // The worker has already terminated. There is nothing to handle here + } } }; if (process.browser) { //browser - let workerURL = _isProbablyPrimeWorkerURL(); + let workerURL = _isProbablyPrimeWorkerUrl(); for (let i = 0; i < self.navigator.hardwareConcurrency; i++) { let newWorker = new Worker(workerURL); newWorker.onmessage = (event) => _onmessage(event.data, newWorker); @@ -266,13 +267,12 @@ export async function prime(bitLength, iterations = 16) { } } for (let i = 0; i < workerList.length; i++) { - randBits(bitLength, true).then((buf) => { - let rnd = fromBuffer(buf); - workerList[i].postMessage({ - 'rnd': rnd, - 'iterations': iterations, - 'id': i - }); + let buf = randBits(bitLength, true); + let rnd = fromBuffer(buf); + workerList[i].postMessage({ + 'rnd': rnd, + 'iterations': iterations, + 'id': i }); } }); @@ -283,15 +283,15 @@ export async function prime(bitLength, iterations = 16) { * @param {bigint} max Returned value will be <= max * @param {bigint} min Returned value will be >= min * - * @returns {Promise} A promise that resolves to a cryptographically secure random bigint between [min,max] + * @returns {bigint} A cryptographically secure random bigint between [min,max] */ -export async function randBetween(max, min = _ONE) { +export function randBetween(max, min = _ONE) { if (max <= min) throw new Error('max must be > min'); const interval = max - min; let bitLen = bitLength(interval); let rnd; do { - let buf = await randBits(bitLen); + let buf = randBits(bitLen); rnd = fromBuffer(buf); } while (rnd > interval); return rnd + min; @@ -303,11 +303,11 @@ export async function randBetween(max, min = _ONE) { * @param {number} bitLength The desired number of random bits * @param {boolean} forceLength If we want to force the output to have a specific bit length. It basically forces the msb to be 1 * - * @returns {Promise} A promise that resolves to a Buffer/UInt8Array filled with cryptographically secure random bits + * @returns {Buffer|Uint8Array} A Buffer/UInt8Array filled with cryptographically secure random bits */ -export async function randBits(bitLength, forceLength = false) { +export function randBits(bitLength, forceLength = false) { const byteLength = Math.ceil(bitLength / 8); - let rndBytes = await randBytes(byteLength, false); + let rndBytes = randBytes(byteLength, false); // Fill with 0's the extra birs rndBytes[0] = rndBytes[0] & (2 ** (bitLength % 8) - 1); if (forceLength) { @@ -323,31 +323,22 @@ export async function randBits(bitLength, forceLength = false) { * @param {number} byteLength The desired number of random bytes * @param {boolean} forceLength If we want to force the output to have a bit length of 8*byteLength. It basically forces the msb to be 1 * - * @returns {Promise} A promise that resolves to a Buffer/UInt8Array filled with cryptographically secure random bytes + * @returns {Buffer|Uint8Array} A Buffer/UInt8Array filled with cryptographically secure random bytes */ -export async function randBytes(byteLength, forceLength = false) { - return new Promise((resolve) => { - let buf; - - if (!process.browser) { // node - const crypto = require('crypto'); - buf = Buffer.alloc(byteLength); - crypto.randomFill(buf, (err, buf) => { - // If fixed length is required we put the first bit to 1 -> to get the necessary bitLength - if (forceLength) - buf[0] = buf[0] | 128; - - resolve(buf); - }); - } else { // browser - buf = new Uint8Array(byteLength); - self.crypto.getRandomValues(buf); - // If fixed length is required we put the first bit to 1 -> to get the necessary bitLength - if (forceLength) - buf[0] = buf[0] | 128; - resolve(buf); - } - }); +export function randBytes(byteLength, forceLength = false) { + let buf; + if (!process.browser) { // node + const crypto = require('crypto'); + buf = Buffer.alloc(byteLength); + crypto.randomFillSync(buf); + } else { // browser + buf = new Uint8Array(byteLength); + self.crypto.getRandomValues(buf); + } + // If fixed length is required we put the first bit to 1 -> to get the necessary bitLength + if (forceLength) + buf[0] = buf[0] | 128; + return buf; } /** @@ -384,11 +375,11 @@ function bitLength(a) { return bits; } -function _isProbablyPrimeWorkerURL() { +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()}`; - const _onmessage = async function (event) { // Let's start once we are called + const onmessage = async function (event) { // Let's start once we are called // event.data = {rnd: , iterations: } const isPrime = await isProbablyPrime(event.data.rnd, event.data.iterations); postMessage({ @@ -397,16 +388,19 @@ function _isProbablyPrimeWorkerURL() { 'id': event.data.id }); }; - workerCode += `onmessage = ${_onmessage.toString()};`; + + workerCode += `onmessage = ${onmessage.toString()};`; + return _workerUrl(workerCode); +} + +function _workerUrl(workerCode) { workerCode = `(() => {${workerCode}})()`; // encapsulate IIFE - var _blob = new Blob([workerCode], { type: 'text/javascript' }); - return window.URL.createObjectURL(_blob); } -async function _isProbablyPrime(w, iterations = 16) { +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. @@ -707,7 +701,7 @@ async function _isProbablyPrime(w, iterations = 16) { let m = (w - _ONE) / (_TWO ** a); loop: do { - let b = await randBetween(w - _ONE, _TWO); + let b = randBetween(w - _ONE, _TWO); let z = modPow(b, m, w); if (z === _ONE || z === w - _ONE) continue; @@ -751,9 +745,9 @@ This node version doesn't support worker_threads. You should enable them in orde 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 + parentPort.on('message', function (data) { // Let's start once we are called // data = {rnd: , iterations: } - const isPrime = await _isProbablyPrime(data.rnd, data.iterations); + const isPrime = _isProbablyPrime(data.rnd, data.iterations); parentPort.postMessage({ 'isPrime': isPrime, 'value': data.rnd,