diff --git a/.gitignore b/.gitignore index 3d0e5ea..d2719ef 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,6 @@ node_modules/ # Visual Studio Code .vscode + +# IntelliJ +.idea/ diff --git a/dist/bigint-crypto-utils-latest.browser.js b/dist/bigint-crypto-utils-latest.browser.js index 1d1cadf..d522e6e 100644 --- a/dist/bigint-crypto-utils-latest.browser.js +++ b/dist/bigint-crypto-utils-latest.browser.js @@ -360,11 +360,14 @@ var bigintCryptoUtils = (function (exports) { throw new RangeError(`bitLength MUST be > 0 and it is ${bitLength}`); const byteLength = Math.ceil(bitLength / 8); - let rndBytes = randBytesSync(byteLength, false); - // Fill with 0's the extra bits - rndBytes[0] = rndBytes[0] & (2 ** (bitLength % 8) - 1); + const rndBytes = randBytesSync(byteLength, false); + const bitLengthMod8 = bitLength % 8; + if (bitLengthMod8) { + // Fill with 0's the extra bits + rndBytes[0] = rndBytes[0] & (2 ** bitLengthMod8 - 1); + } if (forceLength) { - let mask = (bitLength % 8) ? 2 ** ((bitLength % 8) - 1) : 128; + const mask = bitLengthMod8 ? 2 ** (bitLengthMod8 - 1) : 128; rndBytes[0] = rndBytes[0] | mask; } return rndBytes; diff --git a/dist/bigint-crypto-utils-latest.browser.min.js b/dist/bigint-crypto-utils-latest.browser.min.js index 35a6552..1009745 100644 --- a/dist/bigint-crypto-utils-latest.browser.min.js +++ b/dist/bigint-crypto-utils-latest.browser.min.js @@ -1 +1 @@ -var bigintCryptoUtils=function(exports){"use strict";const _ZERO=BigInt(0),_ONE=BigInt(1),_TWO=BigInt(2);function abs(a){return(a=BigInt(a))>=_ZERO?a:-a}function bitLength(a){if((a=BigInt(a))===_ONE)return 1;let bits=1;do{bits++}while((a>>=_ONE)>_ONE);return bits}function eGcd(a,b){if(a=BigInt(a),b=BigInt(b),a<=_ZERO|b<=_ZERO)return NaN;let x=_ZERO,y=_ONE,u=_ONE,v=_ZERO;for(;a!==_ZERO;){let q=b/a,r=b%a,m=x-u*q,n=y-v*q;b=a,a=r,x=u,y=v,u=m,v=n}return{b:b,x:x,y:y}}function gcd(a,b){if(a=abs(a),b=abs(b),a===_ZERO)return b;if(b===_ZERO)return a;let shift=_ZERO;for(;!((a|b)&_ONE);)a>>=_ONE,b>>=_ONE,shift++;for(;!(a&_ONE);)a>>=_ONE;do{for(;!(b&_ONE);)b>>=_ONE;if(a>b){let x=a;a=b,b=x}b-=a}while(b);return a<{const worker=new Worker(_isProbablyPrimeWorkerUrl());worker.onmessage=event=>{worker.terminate(),resolve(event.data.isPrime)},worker.onmessageerror=event=>{reject(event)},worker.postMessage({rnd:w,iterations:iterations,id:0})})}function modInv(a,n){if(a==_ZERO|n<=_ZERO)return NaN;let egcd=eGcd(toZn(a,n),n);return egcd.b!==_ONE?NaN:toZn(egcd.x,n)}function modPow(b,e,n){if((n=BigInt(n))===_ZERO)return NaN;if(n===_ONE)return _ZERO;if(b=toZn(b,n),(e=BigInt(e))<_ZERO)return modInv(modPow(b,abs(e),n),n);let r=_ONE;for(;e>0;)e%_TWO===_ONE&&(r=r*b%n),e/=_TWO,b=b**_TWO%n;return r}function randBetween(max,min=_ONE){if(max<=min)throw new Error("max must be > min");const interval=max-min;let rnd,bitLen=bitLength(interval);do{rnd=fromBuffer(randBits(bitLen))}while(rnd>interval);return rnd+min}function randBits(bitLength,forceLength=!1){if(bitLength<1)throw new RangeError(`bitLength MUST be > 0 and it is ${bitLength}`);let rndBytes=randBytesSync(Math.ceil(bitLength/8),!1);if(rndBytes[0]=rndBytes[0]&2**(bitLength%8)-1,forceLength){let mask=bitLength%8?2**(bitLength%8-1):128;rndBytes[0]=rndBytes[0]|mask}return rndBytes}function randBytesSync(byteLength,forceLength=!1){if(byteLength<1)throw new RangeError(`byteLength MUST be > 0 and it is ${byteLength}`);let buf;return buf=new Uint8Array(byteLength),self.crypto.getRandomValues(buf),forceLength&&(buf[0]=128|buf[0]),buf}function toZn(a,n){return(n=BigInt(n))<=0?NaN:(a=BigInt(a)%n)<0?a+n:a}function fromBuffer(buf){let ret=_ZERO;for(let i of buf.values()){let bi=BigInt(i);ret=(ret< {${workerCode}})()`;const _blob=new Blob([workerCode],{type:"text/javascript"});return window.URL.createObjectURL(_blob)}(workerCode)}function _isProbablyPrime(w,iterations=16){if(w===_TWO)return!0;if((w&_ONE)===_ZERO||w===_ONE)return!1;const firstPrimes=[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 i=0;i=(b=BigInt(b))?a:b},exports.min=function(a,b){return(a=BigInt(a))>=(b=BigInt(b))?b:a},exports.modInv=modInv,exports.modPow=modPow,exports.prime=function(bitLength,iterations=16){if(bitLength<1)throw new RangeError(`bitLength MUST be > 0 and it is ${bitLength}`);return new Promise(resolve=>{let workerList=[];const _onmessage=(msg,newWorker)=>{if(msg.isPrime){for(let j=0;j_onmessage(event.data,newWorker),workerList.push(newWorker)}}for(let i=0;i 0 and it is ${bitLength}`);let rnd=_ZERO;do{rnd=fromBuffer(randBytesSync(bitLength/8,!0))}while(!_isProbablyPrime(rnd,iterations));return rnd},exports.randBetween=randBetween,exports.randBits=randBits,exports.randBytes=function(byteLength,forceLength=!1){if(byteLength<1)throw new RangeError(`byteLength MUST be > 0 and it is ${byteLength}`);let buf;return new Promise((function(resolve){buf=new Uint8Array(byteLength),self.crypto.getRandomValues(buf),forceLength&&(buf[0]=128|buf[0]),resolve(buf)}))},exports.randBytesSync=randBytesSync,exports.toZn=toZn,exports}({}); +var bigintCryptoUtils=function(exports){"use strict";const _ZERO=BigInt(0),_ONE=BigInt(1),_TWO=BigInt(2);function abs(a){return(a=BigInt(a))>=_ZERO?a:-a}function bitLength(a){if((a=BigInt(a))===_ONE)return 1;let bits=1;do{bits++}while((a>>=_ONE)>_ONE);return bits}function eGcd(a,b){if(a=BigInt(a),b=BigInt(b),a<=_ZERO|b<=_ZERO)return NaN;let x=_ZERO,y=_ONE,u=_ONE,v=_ZERO;for(;a!==_ZERO;){let q=b/a,r=b%a,m=x-u*q,n=y-v*q;b=a,a=r,x=u,y=v,u=m,v=n}return{b:b,x:x,y:y}}function gcd(a,b){if(a=abs(a),b=abs(b),a===_ZERO)return b;if(b===_ZERO)return a;let shift=_ZERO;for(;!((a|b)&_ONE);)a>>=_ONE,b>>=_ONE,shift++;for(;!(a&_ONE);)a>>=_ONE;do{for(;!(b&_ONE);)b>>=_ONE;if(a>b){let x=a;a=b,b=x}b-=a}while(b);return a<{const worker=new Worker(_isProbablyPrimeWorkerUrl());worker.onmessage=event=>{worker.terminate(),resolve(event.data.isPrime)},worker.onmessageerror=event=>{reject(event)},worker.postMessage({rnd:w,iterations:iterations,id:0})})}function modInv(a,n){if(a==_ZERO|n<=_ZERO)return NaN;let egcd=eGcd(toZn(a,n),n);return egcd.b!==_ONE?NaN:toZn(egcd.x,n)}function modPow(b,e,n){if((n=BigInt(n))===_ZERO)return NaN;if(n===_ONE)return _ZERO;if(b=toZn(b,n),(e=BigInt(e))<_ZERO)return modInv(modPow(b,abs(e),n),n);let r=_ONE;for(;e>0;)e%_TWO===_ONE&&(r=r*b%n),e/=_TWO,b=b**_TWO%n;return r}function randBetween(max,min=_ONE){if(max<=min)throw new Error("max must be > min");const interval=max-min;let rnd,bitLen=bitLength(interval);do{rnd=fromBuffer(randBits(bitLen))}while(rnd>interval);return rnd+min}function randBits(bitLength,forceLength=!1){if(bitLength<1)throw new RangeError(`bitLength MUST be > 0 and it is ${bitLength}`);const rndBytes=randBytesSync(Math.ceil(bitLength/8),!1),bitLengthMod8=bitLength%8;if(bitLengthMod8&&(rndBytes[0]=rndBytes[0]&2**bitLengthMod8-1),forceLength){const mask=bitLengthMod8?2**(bitLengthMod8-1):128;rndBytes[0]=rndBytes[0]|mask}return rndBytes}function randBytesSync(byteLength,forceLength=!1){if(byteLength<1)throw new RangeError(`byteLength MUST be > 0 and it is ${byteLength}`);let buf;return buf=new Uint8Array(byteLength),self.crypto.getRandomValues(buf),forceLength&&(buf[0]=128|buf[0]),buf}function toZn(a,n){return(n=BigInt(n))<=0?NaN:(a=BigInt(a)%n)<0?a+n:a}function fromBuffer(buf){let ret=_ZERO;for(let i of buf.values()){let bi=BigInt(i);ret=(ret< {${workerCode}})()`;const _blob=new Blob([workerCode],{type:"text/javascript"});return window.URL.createObjectURL(_blob)}(workerCode)}function _isProbablyPrime(w,iterations=16){if(w===_TWO)return!0;if((w&_ONE)===_ZERO||w===_ONE)return!1;const firstPrimes=[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 i=0;i=(b=BigInt(b))?a:b},exports.min=function(a,b){return(a=BigInt(a))>=(b=BigInt(b))?b:a},exports.modInv=modInv,exports.modPow=modPow,exports.prime=function(bitLength,iterations=16){if(bitLength<1)throw new RangeError(`bitLength MUST be > 0 and it is ${bitLength}`);return new Promise(resolve=>{let workerList=[];const _onmessage=(msg,newWorker)=>{if(msg.isPrime){for(let j=0;j_onmessage(event.data,newWorker),workerList.push(newWorker)}}for(let i=0;i 0 and it is ${bitLength}`);let rnd=_ZERO;do{rnd=fromBuffer(randBytesSync(bitLength/8,!0))}while(!_isProbablyPrime(rnd,iterations));return rnd},exports.randBetween=randBetween,exports.randBits=randBits,exports.randBytes=function(byteLength,forceLength=!1){if(byteLength<1)throw new RangeError(`byteLength MUST be > 0 and it is ${byteLength}`);let buf;return new Promise((function(resolve){buf=new Uint8Array(byteLength),self.crypto.getRandomValues(buf),forceLength&&(buf[0]=128|buf[0]),resolve(buf)}))},exports.randBytesSync=randBytesSync,exports.toZn=toZn,exports}({}); diff --git a/dist/bigint-crypto-utils-latest.browser.mod.js b/dist/bigint-crypto-utils-latest.browser.mod.js index 48ab08d..54d6194 100644 --- a/dist/bigint-crypto-utils-latest.browser.mod.js +++ b/dist/bigint-crypto-utils-latest.browser.mod.js @@ -357,11 +357,14 @@ function randBits(bitLength, forceLength = false) { throw new RangeError(`bitLength MUST be > 0 and it is ${bitLength}`); const byteLength = Math.ceil(bitLength / 8); - let rndBytes = randBytesSync(byteLength, false); - // Fill with 0's the extra bits - rndBytes[0] = rndBytes[0] & (2 ** (bitLength % 8) - 1); + const rndBytes = randBytesSync(byteLength, false); + const bitLengthMod8 = bitLength % 8; + if (bitLengthMod8) { + // Fill with 0's the extra bits + rndBytes[0] = rndBytes[0] & (2 ** bitLengthMod8 - 1); + } if (forceLength) { - let mask = (bitLength % 8) ? 2 ** ((bitLength % 8) - 1) : 128; + const mask = bitLengthMod8 ? 2 ** (bitLengthMod8 - 1) : 128; rndBytes[0] = rndBytes[0] | mask; } return rndBytes; diff --git a/dist/bigint-crypto-utils-latest.browser.mod.min.js b/dist/bigint-crypto-utils-latest.browser.mod.min.js index b8efba4..8a72e4f 100644 --- a/dist/bigint-crypto-utils-latest.browser.mod.min.js +++ b/dist/bigint-crypto-utils-latest.browser.mod.min.js @@ -1 +1 @@ -const _ZERO=BigInt(0),_ONE=BigInt(1),_TWO=BigInt(2);function abs(a){return(a=BigInt(a))>=_ZERO?a:-a}function bitLength(a){if((a=BigInt(a))===_ONE)return 1;let bits=1;do{bits++}while((a>>=_ONE)>_ONE);return bits}function eGcd(a,b){if(a=BigInt(a),b=BigInt(b),a<=_ZERO|b<=_ZERO)return NaN;let x=_ZERO,y=_ONE,u=_ONE,v=_ZERO;for(;a!==_ZERO;){let q=b/a,r=b%a,m=x-u*q,n=y-v*q;b=a,a=r,x=u,y=v,u=m,v=n}return{b:b,x:x,y:y}}function gcd(a,b){if(a=abs(a),b=abs(b),a===_ZERO)return b;if(b===_ZERO)return a;let shift=_ZERO;for(;!((a|b)&_ONE);)a>>=_ONE,b>>=_ONE,shift++;for(;!(a&_ONE);)a>>=_ONE;do{for(;!(b&_ONE);)b>>=_ONE;if(a>b){let x=a;a=b,b=x}b-=a}while(b);return a<{const worker=new Worker(_isProbablyPrimeWorkerUrl());worker.onmessage=event=>{worker.terminate(),resolve(event.data.isPrime)},worker.onmessageerror=event=>{reject(event)},worker.postMessage({rnd:w,iterations:iterations,id:0})})}function lcm(a,b){return a=BigInt(a),b=BigInt(b),a===_ZERO&&b===_ZERO?_ZERO:abs(a*b)/gcd(a,b)}function max(a,b){return(a=BigInt(a))>=(b=BigInt(b))?a:b}function min(a,b){return(a=BigInt(a))>=(b=BigInt(b))?b:a}function modInv(a,n){if(a==_ZERO|n<=_ZERO)return NaN;let egcd=eGcd(toZn(a,n),n);return egcd.b!==_ONE?NaN:toZn(egcd.x,n)}function modPow(b,e,n){if((n=BigInt(n))===_ZERO)return NaN;if(n===_ONE)return _ZERO;if(b=toZn(b,n),(e=BigInt(e))<_ZERO)return modInv(modPow(b,abs(e),n),n);let r=_ONE;for(;e>0;)e%_TWO===_ONE&&(r=r*b%n),e/=_TWO,b=b**_TWO%n;return r}function prime(bitLength,iterations=16){if(bitLength<1)throw new RangeError(`bitLength MUST be > 0 and it is ${bitLength}`);return new Promise(resolve=>{let workerList=[];const _onmessage=(msg,newWorker)=>{if(msg.isPrime){for(let j=0;j_onmessage(event.data,newWorker),workerList.push(newWorker)}}for(let i=0;i 0 and it is ${bitLength}`);let rnd=_ZERO;do{rnd=fromBuffer(randBytesSync(bitLength/8,!0))}while(!_isProbablyPrime(rnd,iterations));return rnd}function randBetween(max,min=_ONE){if(max<=min)throw new Error("max must be > min");const interval=max-min;let rnd,bitLen=bitLength(interval);do{rnd=fromBuffer(randBits(bitLen))}while(rnd>interval);return rnd+min}function randBits(bitLength,forceLength=!1){if(bitLength<1)throw new RangeError(`bitLength MUST be > 0 and it is ${bitLength}`);let rndBytes=randBytesSync(Math.ceil(bitLength/8),!1);if(rndBytes[0]=rndBytes[0]&2**(bitLength%8)-1,forceLength){let mask=bitLength%8?2**(bitLength%8-1):128;rndBytes[0]=rndBytes[0]|mask}return rndBytes}function randBytes(byteLength,forceLength=!1){if(byteLength<1)throw new RangeError(`byteLength MUST be > 0 and it is ${byteLength}`);let buf;return new Promise((function(resolve){buf=new Uint8Array(byteLength),self.crypto.getRandomValues(buf),forceLength&&(buf[0]=128|buf[0]),resolve(buf)}))}function randBytesSync(byteLength,forceLength=!1){if(byteLength<1)throw new RangeError(`byteLength MUST be > 0 and it is ${byteLength}`);let buf;return buf=new Uint8Array(byteLength),self.crypto.getRandomValues(buf),forceLength&&(buf[0]=128|buf[0]),buf}function toZn(a,n){return(n=BigInt(n))<=0?NaN:(a=BigInt(a)%n)<0?a+n:a}function fromBuffer(buf){let ret=_ZERO;for(let i of buf.values()){let bi=BigInt(i);ret=(ret< {${workerCode}})()`;const _blob=new Blob([workerCode],{type:"text/javascript"});return window.URL.createObjectURL(_blob)}(workerCode)}function _isProbablyPrime(w,iterations=16){if(w===_TWO)return!0;if((w&_ONE)===_ZERO||w===_ONE)return!1;const firstPrimes=[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 i=0;i=_ZERO?a:-a}function bitLength(a){if((a=BigInt(a))===_ONE)return 1;let bits=1;do{bits++}while((a>>=_ONE)>_ONE);return bits}function eGcd(a,b){if(a=BigInt(a),b=BigInt(b),a<=_ZERO|b<=_ZERO)return NaN;let x=_ZERO,y=_ONE,u=_ONE,v=_ZERO;for(;a!==_ZERO;){let q=b/a,r=b%a,m=x-u*q,n=y-v*q;b=a,a=r,x=u,y=v,u=m,v=n}return{b:b,x:x,y:y}}function gcd(a,b){if(a=abs(a),b=abs(b),a===_ZERO)return b;if(b===_ZERO)return a;let shift=_ZERO;for(;!((a|b)&_ONE);)a>>=_ONE,b>>=_ONE,shift++;for(;!(a&_ONE);)a>>=_ONE;do{for(;!(b&_ONE);)b>>=_ONE;if(a>b){let x=a;a=b,b=x}b-=a}while(b);return a<{const worker=new Worker(_isProbablyPrimeWorkerUrl());worker.onmessage=event=>{worker.terminate(),resolve(event.data.isPrime)},worker.onmessageerror=event=>{reject(event)},worker.postMessage({rnd:w,iterations:iterations,id:0})})}function lcm(a,b){return a=BigInt(a),b=BigInt(b),a===_ZERO&&b===_ZERO?_ZERO:abs(a*b)/gcd(a,b)}function max(a,b){return(a=BigInt(a))>=(b=BigInt(b))?a:b}function min(a,b){return(a=BigInt(a))>=(b=BigInt(b))?b:a}function modInv(a,n){if(a==_ZERO|n<=_ZERO)return NaN;let egcd=eGcd(toZn(a,n),n);return egcd.b!==_ONE?NaN:toZn(egcd.x,n)}function modPow(b,e,n){if((n=BigInt(n))===_ZERO)return NaN;if(n===_ONE)return _ZERO;if(b=toZn(b,n),(e=BigInt(e))<_ZERO)return modInv(modPow(b,abs(e),n),n);let r=_ONE;for(;e>0;)e%_TWO===_ONE&&(r=r*b%n),e/=_TWO,b=b**_TWO%n;return r}function prime(bitLength,iterations=16){if(bitLength<1)throw new RangeError(`bitLength MUST be > 0 and it is ${bitLength}`);return new Promise(resolve=>{let workerList=[];const _onmessage=(msg,newWorker)=>{if(msg.isPrime){for(let j=0;j_onmessage(event.data,newWorker),workerList.push(newWorker)}}for(let i=0;i 0 and it is ${bitLength}`);let rnd=_ZERO;do{rnd=fromBuffer(randBytesSync(bitLength/8,!0))}while(!_isProbablyPrime(rnd,iterations));return rnd}function randBetween(max,min=_ONE){if(max<=min)throw new Error("max must be > min");const interval=max-min;let rnd,bitLen=bitLength(interval);do{rnd=fromBuffer(randBits(bitLen))}while(rnd>interval);return rnd+min}function randBits(bitLength,forceLength=!1){if(bitLength<1)throw new RangeError(`bitLength MUST be > 0 and it is ${bitLength}`);const rndBytes=randBytesSync(Math.ceil(bitLength/8),!1),bitLengthMod8=bitLength%8;if(bitLengthMod8&&(rndBytes[0]=rndBytes[0]&2**bitLengthMod8-1),forceLength){const mask=bitLengthMod8?2**(bitLengthMod8-1):128;rndBytes[0]=rndBytes[0]|mask}return rndBytes}function randBytes(byteLength,forceLength=!1){if(byteLength<1)throw new RangeError(`byteLength MUST be > 0 and it is ${byteLength}`);let buf;return new Promise((function(resolve){buf=new Uint8Array(byteLength),self.crypto.getRandomValues(buf),forceLength&&(buf[0]=128|buf[0]),resolve(buf)}))}function randBytesSync(byteLength,forceLength=!1){if(byteLength<1)throw new RangeError(`byteLength MUST be > 0 and it is ${byteLength}`);let buf;return buf=new Uint8Array(byteLength),self.crypto.getRandomValues(buf),forceLength&&(buf[0]=128|buf[0]),buf}function toZn(a,n){return(n=BigInt(n))<=0?NaN:(a=BigInt(a)%n)<0?a+n:a}function fromBuffer(buf){let ret=_ZERO;for(let i of buf.values()){let bi=BigInt(i);ret=(ret< {${workerCode}})()`;const _blob=new Blob([workerCode],{type:"text/javascript"});return window.URL.createObjectURL(_blob)}(workerCode)}function _isProbablyPrime(w,iterations=16){if(w===_TWO)return!0;if((w&_ONE)===_ZERO||w===_ONE)return!1;const firstPrimes=[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 i=0;i 0 and it is ${bitLength}`); const byteLength = Math.ceil(bitLength / 8); - let rndBytes = randBytesSync(byteLength, false); - // Fill with 0's the extra bits - rndBytes[0] = rndBytes[0] & (2 ** (bitLength % 8) - 1); + const rndBytes = randBytesSync(byteLength, false); + const bitLengthMod8 = bitLength % 8; + if (bitLengthMod8) { + // Fill with 0's the extra bits + rndBytes[0] = rndBytes[0] & (2 ** bitLengthMod8 - 1); + } if (forceLength) { - let mask = (bitLength % 8) ? 2 ** ((bitLength % 8) - 1) : 128; + const mask = bitLengthMod8 ? 2 ** (bitLengthMod8 - 1) : 128; rndBytes[0] = rndBytes[0] | mask; } return rndBytes; diff --git a/package-lock.json b/package-lock.json index f2a3c6b..3a03dc0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "bigint-crypto-utils", - "version": "2.5.0", + "version": "2.5.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 606d68f..0b8990c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bigint-crypto-utils", - "version": "2.5.0", + "version": "2.5.1", "description": "Utils for working with cryptography using native JS implementation of BigInt. It includes arbitrary precision modular arithmetics, cryptographically secure random numbers and strong probable prime generation/testing.", "keywords": [ "modular arithmetics", diff --git a/src/main.js b/src/main.js index 27a5c71..f3c8656 100644 --- a/src/main.js +++ b/src/main.js @@ -400,11 +400,14 @@ export function randBits(bitLength, forceLength = false) { throw new RangeError(`bitLength MUST be > 0 and it is ${bitLength}`); const byteLength = Math.ceil(bitLength / 8); - let rndBytes = randBytesSync(byteLength, false); - // Fill with 0's the extra bits - rndBytes[0] = rndBytes[0] & (2 ** (bitLength % 8) - 1); + const rndBytes = randBytesSync(byteLength, false); + const bitLengthMod8 = bitLength % 8; + if (bitLengthMod8) { + // Fill with 0's the extra bits + rndBytes[0] = rndBytes[0] & (2 ** bitLengthMod8 - 1); + } if (forceLength) { - let mask = (bitLength % 8) ? 2 ** ((bitLength % 8) - 1) : 128; + const mask = bitLengthMod8 ? 2 ** (bitLengthMod8 - 1) : 128; rndBytes[0] = rndBytes[0] | mask; } return rndBytes;