bigint-crypto-utils
Advanced tools
Comparing version 2.2.1 to 2.3.1
@@ -260,4 +260,5 @@ var bigintCryptoUtils = (function (exports) { | ||
* @param {number} iterations The number of iterations for the Miller-Rabin Probabilistic Primality Test | ||
* @param {boolean} sync NOT RECOMMENDED. Invoke the function synchronously. It won't use workers so it'll be slower and may freeze thw window in browser's javascript. | ||
* | ||
* @returns {Promise} A promise that resolves to a bigint probable prime of bitLength bits | ||
* @returns {Promise} A promise that resolves to a bigint probable prime of bitLength bits. | ||
*/ | ||
@@ -314,2 +315,21 @@ function prime(bitLength, iterations = 16) { | ||
/** | ||
* A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator. | ||
* The sync version is NOT RECOMMENDED since it won't use workers and thus it'll be slower and may freeze thw window in browser's javascript. Please consider using prime() instead. | ||
* | ||
* @param {number} bitLength The required bit length for the generated prime | ||
* @param {number} iterations The number of iterations for the Miller-Rabin Probabilistic Primality Test | ||
* | ||
* @returns {bigint} A bigint probable prime of bitLength bits. | ||
*/ | ||
function primeSync(bitLength, iterations = 16) { | ||
if (bitLength < 1) | ||
throw new RangeError(`bitLength MUST be > 0 and it is ${bitLength}`); | ||
let rnd = _ZERO; | ||
do { | ||
rnd = fromBuffer(randBytesSync(bitLength / 8, true)); | ||
} while (!_isProbablyPrime(rnd, iterations)); | ||
return rnd; | ||
} | ||
/** | ||
* Returns a cryptographically secure random integer between [min,max] | ||
@@ -788,2 +808,3 @@ * @param {bigint} max Returned value will be <= max | ||
exports.prime = prime; | ||
exports.primeSync = primeSync; | ||
exports.randBetween = randBetween; | ||
@@ -790,0 +811,0 @@ exports.randBits = randBits; |
@@ -1,1 +0,1 @@ | ||
var bigintCryptoUtils=function(a){'use strict';function c(b){return b=BigInt(b),b>=s?b:-b}function d(b){if(b=BigInt(b),b===t)return 1;let c=1;do c++;while((b>>=t)>t);return c}function e(c,d){if(c=BigInt(c),d=BigInt(d),c<=s|d<=s)return NaN;let e=s,f=t,g=t,h=s;for(;c!==s;){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){if(d=c(d),e=c(e),d===s)return e;if(e===s)return d;let f=s;for(;!((d|e)&t);)d>>=t,e>>=t,f++;for(;!(d&t);)d>>=t;do{for(;!(e&t);)e>>=t;if(d>e){let a=d;d=e,e=a}e-=d}while(e);return d<<f}async function g(a,b=16){return"number"==typeof a&&(a=BigInt(a)),new Promise((c,d)=>{const 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){if(b==s|a<=s)return NaN;let c=e(m(b,a),a);return c.b===t?m(c.x,a):NaN}function i(a,d,f){if(f=BigInt(f),f===s)return NaN;if(f===t)return s;if(a=m(a,f),d=BigInt(d),d<s)return h(i(a,c(d),f),f);let g=t;for(;0<d;)d%u===t&&(g=g*a%f),d/=u,a=a**u%f;return g}function j(a,b=t){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;if(1>a)throw new RangeError(`bitLength MUST be > 0 and it is ${a}`);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){if(1>a)throw new RangeError(`byteLength MUST be > 0 and it is ${a}`);let c;return c=new Uint8Array(a),self.crypto.getRandomValues(c),b&&(c[0]|=128),c}function m(b,c){return(c=BigInt(c),0>=c)?NaN:(b=BigInt(b)%c,0>b?b+c:b)}function n(a){let b=s;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 randBytesSync = ${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}})()`;const b=new Blob([a],{type:"text/javascript"});return window.URL.createObjectURL(b)}function q(c,b=16){if(c===u)return!0;if((c&t)===s||c===t)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===s)return!1}let f=s,g=c-t;for(;g%u===s;)g/=u,++f;let h=(c-t)/u**f;loop:do{let a=j(c-t,u),b=i(a,h,c);if(b===t||b===c-t)continue;for(let a=1;a<f;a++){if(b=i(b,u,c),b===c-t)continue loop;if(b===t)break}return!1}while(--b);return!0}const s=BigInt(0),t=BigInt(1),u=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),d===s&&e===s?s:c(d*e)/f(d,e)},a.max=function(c,d){return c=BigInt(c),d=BigInt(d),c>=d?c:d},a.min=function(c,d){return c=BigInt(c),d=BigInt(d),c>=d?d:c},a.modInv=h,a.modPow=i,a.prime=function(a,b=16){if(1>a)throw new RangeError(`bitLength MUST be > 0 and it is ${a}`);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=function(a,b=!1){if(1>a)throw new RangeError(`byteLength MUST be > 0 and it is ${a}`);let c;return new Promise(function(d){c=new Uint8Array(a),self.crypto.getRandomValues(c),b&&(c[0]|=128),d(c)})},a.randBytesSync=l,a.toZn=m,a}({}); | ||
var bigintCryptoUtils=function(a){'use strict';function c(b){return b=BigInt(b),b>=s?b:-b}function d(b){if(b=BigInt(b),b===t)return 1;let c=1;do c++;while((b>>=t)>t);return c}function e(c,d){if(c=BigInt(c),d=BigInt(d),c<=s|d<=s)return NaN;let e=s,f=t,g=t,h=s;for(;c!==s;){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){if(d=c(d),e=c(e),d===s)return e;if(e===s)return d;let f=s;for(;!((d|e)&t);)d>>=t,e>>=t,f++;for(;!(d&t);)d>>=t;do{for(;!(e&t);)e>>=t;if(d>e){let a=d;d=e,e=a}e-=d}while(e);return d<<f}async function g(a,b=16){return"number"==typeof a&&(a=BigInt(a)),new Promise((c,d)=>{const 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){if(b==s|a<=s)return NaN;let c=e(m(b,a),a);return c.b===t?m(c.x,a):NaN}function i(a,d,f){if(f=BigInt(f),f===s)return NaN;if(f===t)return s;if(a=m(a,f),d=BigInt(d),d<s)return h(i(a,c(d),f),f);let g=t;for(;0<d;)d%u===t&&(g=g*a%f),d/=u,a=a**u%f;return g}function j(a,b=t){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;if(1>a)throw new RangeError(`bitLength MUST be > 0 and it is ${a}`);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){if(1>a)throw new RangeError(`byteLength MUST be > 0 and it is ${a}`);let c;return c=new Uint8Array(a),self.crypto.getRandomValues(c),b&&(c[0]|=128),c}function m(b,c){return(c=BigInt(c),0>=c)?NaN:(b=BigInt(b)%c,0>b?b+c:b)}function n(a){let b=s;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 randBytesSync = ${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}})()`;const b=new Blob([a],{type:"text/javascript"});return window.URL.createObjectURL(b)}function q(c,b=16){if(c===u)return!0;if((c&t)===s||c===t)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===s)return!1}let f=s,g=c-t;for(;g%u===s;)g/=u,++f;let h=(c-t)/u**f;loop:do{let a=j(c-t,u),b=i(a,h,c);if(b===t||b===c-t)continue;for(let a=1;a<f;a++){if(b=i(b,u,c),b===c-t)continue loop;if(b===t)break}return!1}while(--b);return!0}const s=BigInt(0),t=BigInt(1),u=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),d===s&&e===s?s:c(d*e)/f(d,e)},a.max=function(c,d){return c=BigInt(c),d=BigInt(d),c>=d?c:d},a.min=function(c,d){return c=BigInt(c),d=BigInt(d),c>=d?d:c},a.modInv=h,a.modPow=i,a.prime=function(a,b=16){if(1>a)throw new RangeError(`bitLength MUST be > 0 and it is ${a}`);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.primeSync=function(a,b=16){if(1>a)throw new RangeError(`bitLength MUST be > 0 and it is ${a}`);let c=s;do c=n(l(a/8,!0));while(!q(c,b));return c},a.randBetween=j,a.randBits=k,a.randBytes=function(a,b=!1){if(1>a)throw new RangeError(`byteLength MUST be > 0 and it is ${a}`);let c;return new Promise(function(d){c=new Uint8Array(a),self.crypto.getRandomValues(c),b&&(c[0]|=128),d(c)})},a.randBytesSync=l,a.toZn=m,a}({}); |
@@ -257,4 +257,5 @@ const _ZERO = BigInt(0); | ||
* @param {number} iterations The number of iterations for the Miller-Rabin Probabilistic Primality Test | ||
* @param {boolean} sync NOT RECOMMENDED. Invoke the function synchronously. It won't use workers so it'll be slower and may freeze thw window in browser's javascript. | ||
* | ||
* @returns {Promise} A promise that resolves to a bigint probable prime of bitLength bits | ||
* @returns {Promise} A promise that resolves to a bigint probable prime of bitLength bits. | ||
*/ | ||
@@ -311,2 +312,21 @@ function prime(bitLength, iterations = 16) { | ||
/** | ||
* A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator. | ||
* The sync version is NOT RECOMMENDED since it won't use workers and thus it'll be slower and may freeze thw window in browser's javascript. Please consider using prime() instead. | ||
* | ||
* @param {number} bitLength The required bit length for the generated prime | ||
* @param {number} iterations The number of iterations for the Miller-Rabin Probabilistic Primality Test | ||
* | ||
* @returns {bigint} A bigint probable prime of bitLength bits. | ||
*/ | ||
function primeSync(bitLength, iterations = 16) { | ||
if (bitLength < 1) | ||
throw new RangeError(`bitLength MUST be > 0 and it is ${bitLength}`); | ||
let rnd = _ZERO; | ||
do { | ||
rnd = fromBuffer(randBytesSync(bitLength / 8, true)); | ||
} while (!_isProbablyPrime(rnd, iterations)); | ||
return rnd; | ||
} | ||
/** | ||
* Returns a cryptographically secure random integer between [min,max] | ||
@@ -774,2 +794,2 @@ * @param {bigint} max Returned value will be <= max | ||
export { abs, bitLength, eGcd, gcd, isProbablyPrime, lcm, max, min, modInv, modPow, prime, randBetween, randBits, randBytes, randBytesSync, toZn }; | ||
export { abs, bitLength, eGcd, gcd, isProbablyPrime, lcm, max, min, modInv, modPow, prime, primeSync, randBetween, randBits, randBytes, randBytesSync, toZn }; |
@@ -1,1 +0,1 @@ | ||
const _ZERO=BigInt(0),_ONE=BigInt(1),_TWO=BigInt(2);function abs(b){return b=BigInt(b),b>=_ZERO?b:-b}function bitLength(b){if(b=BigInt(b),b===_ONE)return 1;let c=1;do c++;while((b>>=_ONE)>_ONE);return c}function eGcd(c,d){if(c=BigInt(c),d=BigInt(d),c<=_ZERO|d<=_ZERO)return NaN;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){if(c=abs(c),d=abs(d),c===_ZERO)return d;if(d===_ZERO)return c;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"number"==typeof a&&(a=BigInt(a)),new Promise((c,d)=>{const 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),c===_ZERO&&d===_ZERO?_ZERO:abs(c*d)/gcd(c,d)}function max(c,d){return c=BigInt(c),d=BigInt(d),c>=d?c:d}function min(c,d){return c=BigInt(c),d=BigInt(d),c>=d?d:c}function modInv(b,a){if(b==_ZERO|a<=_ZERO)return NaN;let c=eGcd(toZn(b,a),a);return c.b===_ONE?toZn(c.x,a):NaN}function modPow(a,c,d){if(d=BigInt(d),d===_ZERO)return NaN;if(d===_ONE)return _ZERO;if(a=toZn(a,d),c=BigInt(c),c<_ZERO)return modInv(modPow(a,abs(c),d),d);let f=_ONE;for(;0<c;)c%_TWO===_ONE&&(f=f*a%d),c/=_TWO,a=a**_TWO%d;return f}function prime(a,b=16){if(1>a)throw new RangeError(`bitLength MUST be > 0 and it is ${a}`);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;if(1>a)throw new RangeError(`bitLength MUST be > 0 and it is ${a}`);const d=c(a/8);let e=randBytesSync(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){if(1>a)throw new RangeError(`byteLength MUST be > 0 and it is ${a}`);let c;return new Promise(function(d){c=new Uint8Array(a),self.crypto.getRandomValues(c),b&&(c[0]|=128),d(c)})}function randBytesSync(a,b=!1){if(1>a)throw new RangeError(`byteLength MUST be > 0 and it is ${a}`);let c;return c=new Uint8Array(a),self.crypto.getRandomValues(c),b&&(c[0]|=128),c}function toZn(b,c){return(c=BigInt(c),0>=c)?NaN:(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 randBytesSync = ${randBytesSync.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}})()`;const 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}export{abs,bitLength,eGcd,gcd,isProbablyPrime,lcm,max,min,modInv,modPow,prime,randBetween,randBits,randBytes,randBytesSync,toZn}; | ||
const _ZERO=BigInt(0),_ONE=BigInt(1),_TWO=BigInt(2);function abs(b){return b=BigInt(b),b>=_ZERO?b:-b}function bitLength(b){if(b=BigInt(b),b===_ONE)return 1;let c=1;do c++;while((b>>=_ONE)>_ONE);return c}function eGcd(c,d){if(c=BigInt(c),d=BigInt(d),c<=_ZERO|d<=_ZERO)return NaN;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){if(c=abs(c),d=abs(d),c===_ZERO)return d;if(d===_ZERO)return c;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"number"==typeof a&&(a=BigInt(a)),new Promise((c,d)=>{const 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),c===_ZERO&&d===_ZERO?_ZERO:abs(c*d)/gcd(c,d)}function max(c,d){return c=BigInt(c),d=BigInt(d),c>=d?c:d}function min(c,d){return c=BigInt(c),d=BigInt(d),c>=d?d:c}function modInv(b,a){if(b==_ZERO|a<=_ZERO)return NaN;let c=eGcd(toZn(b,a),a);return c.b===_ONE?toZn(c.x,a):NaN}function modPow(a,c,d){if(d=BigInt(d),d===_ZERO)return NaN;if(d===_ONE)return _ZERO;if(a=toZn(a,d),c=BigInt(c),c<_ZERO)return modInv(modPow(a,abs(c),d),d);let f=_ONE;for(;0<c;)c%_TWO===_ONE&&(f=f*a%d),c/=_TWO,a=a**_TWO%d;return f}function prime(a,b=16){if(1>a)throw new RangeError(`bitLength MUST be > 0 and it is ${a}`);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 primeSync(a,b=16){if(1>a)throw new RangeError(`bitLength MUST be > 0 and it is ${a}`);let c=_ZERO;do c=fromBuffer(randBytesSync(a/8,!0));while(!_isProbablyPrime(c,b));return c}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;if(1>a)throw new RangeError(`bitLength MUST be > 0 and it is ${a}`);const d=c(a/8);let e=randBytesSync(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){if(1>a)throw new RangeError(`byteLength MUST be > 0 and it is ${a}`);let c;return new Promise(function(d){c=new Uint8Array(a),self.crypto.getRandomValues(c),b&&(c[0]|=128),d(c)})}function randBytesSync(a,b=!1){if(1>a)throw new RangeError(`byteLength MUST be > 0 and it is ${a}`);let c;return c=new Uint8Array(a),self.crypto.getRandomValues(c),b&&(c[0]|=128),c}function toZn(b,c){return(c=BigInt(c),0>=c)?NaN:(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 randBytesSync = ${randBytesSync.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}})()`;const 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}export{abs,bitLength,eGcd,gcd,isProbablyPrime,lcm,max,min,modInv,modPow,prime,primeSync,randBetween,randBits,randBytes,randBytesSync,toZn}; |
@@ -267,4 +267,5 @@ 'use strict'; | ||
* @param {number} iterations The number of iterations for the Miller-Rabin Probabilistic Primality Test | ||
* @param {boolean} sync NOT RECOMMENDED. Invoke the function synchronously. It won't use workers so it'll be slower and may freeze thw window in browser's javascript. | ||
* | ||
* @returns {Promise} A promise that resolves to a bigint probable prime of bitLength bits | ||
* @returns {Promise} A promise that resolves to a bigint probable prime of bitLength bits. | ||
*/ | ||
@@ -330,2 +331,21 @@ function prime(bitLength, iterations = 16) { | ||
/** | ||
* A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator. | ||
* The sync version is NOT RECOMMENDED since it won't use workers and thus it'll be slower and may freeze thw window in browser's javascript. Please consider using prime() instead. | ||
* | ||
* @param {number} bitLength The required bit length for the generated prime | ||
* @param {number} iterations The number of iterations for the Miller-Rabin Probabilistic Primality Test | ||
* | ||
* @returns {bigint} A bigint probable prime of bitLength bits. | ||
*/ | ||
function primeSync(bitLength, iterations = 16) { | ||
if (bitLength < 1) | ||
throw new RangeError(`bitLength MUST be > 0 and it is ${bitLength}`); | ||
let rnd = _ZERO; | ||
do { | ||
rnd = fromBuffer(randBytesSync(bitLength / 8, true)); | ||
} while (!_isProbablyPrime(rnd, iterations)); | ||
return rnd; | ||
} | ||
/** | ||
* Returns a cryptographically secure random integer between [min,max] | ||
@@ -814,2 +834,3 @@ * @param {bigint} max Returned value will be <= max | ||
exports.prime = prime; | ||
exports.primeSync = primeSync; | ||
exports.randBetween = randBetween; | ||
@@ -816,0 +837,0 @@ exports.randBits = randBits; |
{ | ||
"name": "bigint-crypto-utils", | ||
"version": "2.2.1", | ||
"version": "2.3.1", | ||
"description": "Utils for working with cryptography using native JS (stage 3) implementation of BigInt. It includes arbitrary precision modular arithmetics, cryptographically secure random numbers and strong probable prime generation/testing.", | ||
@@ -40,8 +40,8 @@ "keywords": [ | ||
"chai": ">=4.2.0", | ||
"eslint": ">=6.0.1", | ||
"jsdoc-to-markdown": ">=5.0.0", | ||
"mocha": ">=6.2.0", | ||
"rollup": ">=1.17.0", | ||
"rollup-plugin-babel-minify": ">=9.0.0", | ||
"rollup-plugin-commonjs": ">=10.0.1", | ||
"eslint": "^6.5.1", | ||
"jsdoc-to-markdown": "^5.0.1", | ||
"mocha": "^6.2.1", | ||
"rollup": "^1.23.1", | ||
"rollup-plugin-babel-minify": "^9.1.0", | ||
"rollup-plugin-commonjs": "^10.1.0", | ||
"rollup-plugin-multi-entry": ">=2.1.0", | ||
@@ -48,0 +48,0 @@ "rollup-plugin-node-resolve": ">=5.2.0", |
@@ -119,3 +119,3 @@ # bigint-crypto-utils | ||
</dd> | ||
<dt><a href="#prime">prime(bitLength, iterations)</a> ⇒ <code>Promise</code></dt> | ||
<dt><a href="#prime">prime(bitLength, iterations, sync)</a> ⇒ <code>Promise</code></dt> | ||
<dd><p>A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator. | ||
@@ -127,2 +127,6 @@ The browser version uses web workers to parallelise prime look up. Therefore, it does not lock the UI | ||
</dd> | ||
<dt><a href="#primeSync">primeSync(bitLength, iterations)</a> ⇒ <code>bigint</code></dt> | ||
<dd><p>A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator. | ||
The sync version is NOT RECOMMENDED since it won't use workers and thus it'll be slower and may freeze thw window in browser's javascript. Please consider using prime() instead.</p> | ||
</dd> | ||
<dt><a href="#randBetween">randBetween(max, min)</a> ⇒ <code>bigint</code></dt> | ||
@@ -286,3 +290,3 @@ <dd><p>Returns a cryptographically secure random integer between [min,max]</p> | ||
## prime(bitLength, iterations) ⇒ <code>Promise</code> | ||
## prime(bitLength, iterations, sync) ⇒ <code>Promise</code> | ||
A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator. | ||
@@ -295,3 +299,3 @@ The browser version uses web workers to parallelise prime look up. Therefore, it does not lock the UI | ||
**Kind**: global function | ||
**Returns**: <code>Promise</code> - A promise that resolves to a bigint probable prime of bitLength bits | ||
**Returns**: <code>Promise</code> - A promise that resolves to a bigint probable prime of bitLength bits. | ||
@@ -302,3 +306,18 @@ | Param | Type | Description | | ||
| iterations | <code>number</code> | The number of iterations for the Miller-Rabin Probabilistic Primality Test | | ||
| sync | <code>boolean</code> | NOT RECOMMENDED. Invoke the function synchronously. It won't use workers so it'll be slower and may freeze thw window in browser's javascript. | | ||
<a name="primeSync"></a> | ||
## primeSync(bitLength, iterations) ⇒ <code>bigint</code> | ||
A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator. | ||
The sync version is NOT RECOMMENDED since it won't use workers and thus it'll be slower and may freeze thw window in browser's javascript. Please consider using prime() instead. | ||
**Kind**: global function | ||
**Returns**: <code>bigint</code> - A bigint probable prime of bitLength bits. | ||
| Param | Type | Description | | ||
| --- | --- | --- | | ||
| bitLength | <code>number</code> | The required bit length for the generated prime | | ||
| iterations | <code>number</code> | The number of iterations for the Miller-Rabin Probabilistic Primality Test | | ||
<a name="randBetween"></a> | ||
@@ -305,0 +324,0 @@ |
@@ -284,4 +284,5 @@ 'use strict'; | ||
* @param {number} iterations The number of iterations for the Miller-Rabin Probabilistic Primality Test | ||
* @param {boolean} sync NOT RECOMMENDED. Invoke the function synchronously. It won't use workers so it'll be slower and may freeze thw window in browser's javascript. | ||
* | ||
* @returns {Promise} A promise that resolves to a bigint probable prime of bitLength bits | ||
* @returns {Promise} A promise that resolves to a bigint probable prime of bitLength bits. | ||
*/ | ||
@@ -354,2 +355,21 @@ export function prime(bitLength, iterations = 16) { | ||
/** | ||
* A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator. | ||
* The sync version is NOT RECOMMENDED since it won't use workers and thus it'll be slower and may freeze thw window in browser's javascript. Please consider using prime() instead. | ||
* | ||
* @param {number} bitLength The required bit length for the generated prime | ||
* @param {number} iterations The number of iterations for the Miller-Rabin Probabilistic Primality Test | ||
* | ||
* @returns {bigint} A bigint probable prime of bitLength bits. | ||
*/ | ||
export function primeSync(bitLength, iterations = 16) { | ||
if (bitLength < 1) | ||
throw new RangeError(`bitLength MUST be > 0 and it is ${bitLength}`); | ||
let rnd = _ZERO; | ||
do { | ||
rnd = fromBuffer(randBytesSync(bitLength / 8, true)); | ||
} while (!_isProbablyPrime(rnd, iterations)); | ||
return rnd; | ||
} | ||
/** | ||
* Returns a cryptographically secure random integer between [min,max] | ||
@@ -356,0 +376,0 @@ * @param {bigint} max Returned value will be <= max |
@@ -27,2 +27,9 @@ 'use strict'; | ||
} | ||
describe('Testing sync (NOT-RECOMMENDED) version: primeSync()', function() { | ||
it('should return a random 1024-bits probable prime', function () { | ||
const prime = bigintCryptoUtils.primeSync(1024, 16); | ||
const primeBitLength = bigintCryptoUtils.bitLength(prime); | ||
chai.expect(primeBitLength).to.equal(1024); | ||
}); | ||
}); | ||
}); |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
408071
4901
398