2021-11-15 11:00:37 +00:00
/ * *
* Absolute value . abs ( a ) == a if a >= 0. abs ( a ) == - a if a < 0
*
* @ param a
*
* @ returns The absolute value of a
* /
function abs ( a ) {
return ( a >= 0 ) ? a : - a ;
}
/ * *
* Returns the bitlength of a number
*
* @ param a
* @ returns The bit length
* /
function bitLength ( a ) {
if ( typeof a === 'number' )
a = BigInt ( a ) ;
if ( a === 1 n ) {
return 1 ;
}
let bits = 1 ;
do {
bits ++ ;
} while ( ( a >>= 1 n ) > 1 n ) ;
return bits ;
}
/ * *
* An iterative implementation of the extended euclidean algorithm or extended greatest common divisor algorithm .
* Take positive integers a , b as input , and return a triple ( g , x , y ) , such that ax + by = g = gcd ( a , b ) .
*
* @ param a
* @ param b
*
* @ throws { RangeError }
* This excepction is thrown if a or b are less than 0
*
* @ returns A triple ( g , x , y ) , such that ax + by = g = gcd ( a , b ) .
* /
function eGcd ( a , b ) {
if ( typeof a === 'number' )
a = BigInt ( a ) ;
if ( typeof b === 'number' )
b = BigInt ( b ) ;
if ( a <= 0 n || b <= 0 n )
throw new RangeError ( 'a and b MUST be > 0' ) ; // a and b MUST be positive
let x = 0 n ;
let y = 1 n ;
let u = 1 n ;
let v = 0 n ;
while ( a !== 0 n ) {
const q = b / a ;
const r = b % a ;
const m = x - ( u * q ) ;
const n = y - ( v * q ) ;
b = a ;
a = r ;
x = u ;
y = v ;
u = m ;
v = n ;
}
return {
g : b ,
x : x ,
y : y
} ;
}
/ * *
* Greatest - common divisor of two integers based on the iterative binary algorithm .
*
* @ param a
* @ param b
*
* @ returns The greatest common divisor of a and b
* /
function gcd ( a , b ) {
let aAbs = ( typeof a === 'number' ) ? BigInt ( abs ( a ) ) : abs ( a ) ;
let bAbs = ( typeof b === 'number' ) ? BigInt ( abs ( b ) ) : abs ( b ) ;
if ( aAbs === 0 n ) {
return bAbs ;
}
else if ( bAbs === 0 n ) {
return aAbs ;
}
let shift = 0 n ;
while ( ( ( aAbs | bAbs ) & 1 n ) === 0 n ) {
aAbs >>= 1 n ;
bAbs >>= 1 n ;
shift ++ ;
}
while ( ( aAbs & 1 n ) === 0 n )
aAbs >>= 1 n ;
do {
while ( ( bAbs & 1 n ) === 0 n )
bAbs >>= 1 n ;
if ( aAbs > bAbs ) {
const x = aAbs ;
aAbs = bAbs ;
bAbs = x ;
}
bAbs -= aAbs ;
} while ( bAbs !== 0 n ) ;
// rescale
return aAbs << shift ;
}
/ * *
* The least common multiple computed as abs ( a * b ) / gcd ( a , b )
* @ param a
* @ param b
*
* @ returns The least common multiple of a and b
* /
function lcm ( a , b ) {
if ( typeof a === 'number' )
a = BigInt ( a ) ;
if ( typeof b === 'number' )
b = BigInt ( b ) ;
if ( a === 0 n && b === 0 n )
return BigInt ( 0 ) ;
2022-01-17 10:25:42 +00:00
// return abs(a * b) as bigint / gcd(a, b)
return abs ( ( a / gcd ( a , b ) ) * b ) ;
2021-11-15 11:00:37 +00:00
}
/ * *
* Maximum . max ( a , b ) == a if a >= b . max ( a , b ) == b if a <= b
*
* @ param a
* @ param b
*
* @ returns Maximum of numbers a and b
* /
function max ( a , b ) {
return ( a >= b ) ? a : b ;
}
/ * *
* Minimum . min ( a , b ) == b if a >= b . min ( a , b ) == a if a <= b
*
* @ param a
* @ param b
*
* @ returns Minimum of numbers a and b
* /
function min ( a , b ) {
return ( a >= b ) ? b : a ;
}
/ * *
* Finds the smallest positive element that is congruent to a in modulo n
*
* @ remarks
* a and b must be the same type , either number or bigint
*
* @ param a - An integer
* @ param n - The modulo
*
* @ throws { RangeError }
* Excpeption thrown when n is not > 0
*
* @ returns A bigint with the smallest positive representation of a modulo n
* /
function toZn ( a , n ) {
if ( typeof a === 'number' )
a = BigInt ( a ) ;
if ( typeof n === 'number' )
n = BigInt ( n ) ;
if ( n <= 0 n ) {
throw new RangeError ( 'n must be > 0' ) ;
}
const aZn = a % n ;
return ( aZn < 0 n ) ? aZn + n : aZn ;
}
/ * *
* Modular inverse .
*
* @ param a The number to find an inverse for
* @ param n The modulo
*
* @ throws { RangeError }
* Excpeption thorwn when a does not have inverse modulo n
*
* @ returns The inverse modulo n
* /
function modInv ( a , n ) {
const egcd = eGcd ( toZn ( a , n ) , n ) ;
if ( egcd . g !== 1 n ) {
throw new RangeError ( ` ${ a . toString ( ) } does not have inverse modulo ${ n . toString ( ) } ` ) ; // modular inverse does not exist
}
else {
return toZn ( egcd . x , n ) ;
}
}
/ * *
* Modular exponentiation b * * e mod n . Currently using the right - to - left binary method
*
* @ param b base
* @ param e exponent
* @ param n modulo
*
* @ throws { RangeError }
* Excpeption thrown when n is not > 0
*
* @ returns b * * e mod n
* /
function modPow ( b , e , n ) {
if ( typeof b === 'number' )
b = BigInt ( b ) ;
if ( typeof e === 'number' )
e = BigInt ( e ) ;
if ( typeof n === 'number' )
n = BigInt ( n ) ;
if ( n <= 0 n ) {
throw new RangeError ( 'n must be > 0' ) ;
}
else if ( n === 1 n ) {
return 0 n ;
}
b = toZn ( b , n ) ;
if ( e < 0 n ) {
return modInv ( modPow ( b , abs ( e ) , n ) , n ) ;
}
let r = 1 n ;
while ( e > 0 ) {
if ( ( e % 2 n ) === 1 n ) {
r = r * b % n ;
}
e = e / 2 n ;
b = b * * 2 n % n ;
}
return r ;
}
2021-03-25 12:40:04 +00:00
function fromBuffer ( buf ) {
let ret = 0 n ;
for ( const i of buf . values ( ) ) {
const bi = BigInt ( i ) ;
2021-04-21 09:14:04 +00:00
ret = ( ret << 8 n ) + bi ;
2021-03-25 12:40:04 +00:00
}
return ret ;
}
2022-08-01 02:19:48 +00:00
var crypto = await import ( 'crypto' ) ; // eslint-disable-line no-var
2021-03-25 12:40:04 +00:00
/ * *
* Secure random bytes for both node and browsers . Node version uses crypto . randomBytes ( ) and browser one self . crypto . getRandomValues ( )
*
* @ param byteLength - The desired number of random bytes
* @ param forceLength - If we want to force the output to have a bit length of 8 * byteLength . It basically forces the msb to be 1
*
* @ throws { RangeError }
* byteLength MUST be > 0
*
* @ returns A promise that resolves to a UInt8Array / Buffer ( Browser / Node . js ) filled with cryptographically secure random bytes
* /
function randBytes ( byteLength , forceLength = false ) {
if ( byteLength < 1 )
throw new RangeError ( 'byteLength MUST be > 0' ) ;
return new Promise ( function ( resolve , reject ) {
{
crypto . randomBytes ( byteLength , function ( err , buf ) {
if ( err !== null )
reject ( err ) ;
// 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 ) ;
} ) ;
}
} ) ;
}
/ * *
* Secure random bytes for both node and browsers . Node version uses crypto . randomFill ( ) and browser one self . crypto . getRandomValues ( )
*
* @ param byteLength - The desired number of random bytes
* @ param forceLength - If we want to force the output to have a bit length of 8 * byteLength . It basically forces the msb to be 1
*
* @ throws { RangeError }
* byteLength MUST be > 0
*
* @ returns A UInt8Array / Buffer ( Browser / Node . js ) filled with cryptographically secure random bytes
* /
function randBytesSync ( byteLength , forceLength = false ) {
if ( byteLength < 1 )
throw new RangeError ( 'byteLength MUST be > 0' ) ;
/* eslint-disable no-lone-blocks */
{ // node
const buf = crypto . randomBytes ( byteLength ) ;
// 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 ;
}
/* eslint-enable no-lone-blocks */
}
/ * *
* Secure random bits for both node and browsers . Node version uses crypto . randomFill ( ) and browser one self . crypto . getRandomValues ( )
*
* @ param bitLength - The desired number of random bits
* @ param forceLength - If we want to force the output to have a specific bit length . It basically forces the msb to be 1
*
* @ throws { RangeError }
* bitLength MUST be > 0
*
* @ returns A Promise that resolves to a UInt8Array / Buffer ( Browser / Node . js ) filled with cryptographically secure random bits
* /
function randBits ( bitLength , forceLength = false ) {
if ( bitLength < 1 )
throw new RangeError ( 'bitLength MUST be > 0' ) ;
const byteLength = Math . ceil ( bitLength / 8 ) ;
const bitLengthMod8 = bitLength % 8 ;
return new Promise ( ( resolve , reject ) => {
randBytes ( byteLength , false ) . then ( function ( rndBytes ) {
if ( bitLengthMod8 !== 0 ) {
// Fill with 0's the extra bits
rndBytes [ 0 ] = rndBytes [ 0 ] & ( 2 * * bitLengthMod8 - 1 ) ;
}
if ( forceLength ) {
const mask = ( bitLengthMod8 !== 0 ) ? 2 * * ( bitLengthMod8 - 1 ) : 128 ;
rndBytes [ 0 ] = rndBytes [ 0 ] | mask ;
}
resolve ( rndBytes ) ;
} ) ;
} ) ;
}
/ * *
* Secure random bits for both node and browsers . Node version uses crypto . randomFill ( ) and browser one self . crypto . getRandomValues ( )
* @ param bitLength - The desired number of random bits
* @ param forceLength - If we want to force the output to have a specific bit length . It basically forces the msb to be 1
*
* @ throws { RangeError }
* bitLength MUST be > 0
*
* @ returns A Uint8Array / Buffer ( Browser / Node . js ) filled with cryptographically secure random bits
* /
function randBitsSync ( bitLength , forceLength = false ) {
if ( bitLength < 1 )
throw new RangeError ( 'bitLength MUST be > 0' ) ;
const byteLength = Math . ceil ( bitLength / 8 ) ;
const rndBytes = randBytesSync ( byteLength , false ) ;
const bitLengthMod8 = bitLength % 8 ;
if ( bitLengthMod8 !== 0 ) {
// Fill with 0's the extra bits
rndBytes [ 0 ] = rndBytes [ 0 ] & ( 2 * * bitLengthMod8 - 1 ) ;
}
if ( forceLength ) {
const mask = ( bitLengthMod8 !== 0 ) ? 2 * * ( bitLengthMod8 - 1 ) : 128 ;
rndBytes [ 0 ] = rndBytes [ 0 ] | mask ;
}
return rndBytes ;
}
/ * *
2022-01-17 11:30:59 +00:00
* Returns a cryptographically secure random integer between [ min , max ] .
2021-03-25 12:40:04 +00:00
* @ param max Returned value will be <= max
* @ param min Returned value will be >= min
*
* @ throws { RangeError }
2022-01-17 11:30:59 +00:00
* Arguments MUST be : max > min
2021-03-25 12:40:04 +00:00
*
* @ returns A cryptographically secure random bigint between [ min , max ]
* /
function randBetween ( max , min = 1 n ) {
2022-01-17 11:30:59 +00:00
if ( max <= min )
throw new RangeError ( 'Arguments MUST be: max > min' ) ;
2021-03-25 12:40:04 +00:00
const interval = max - min ;
2022-08-01 02:19:48 +00:00
const bitLen = bitLength ( interval ) ;
2021-03-25 12:40:04 +00:00
let rnd ;
do {
const buf = randBitsSync ( bitLen ) ;
rnd = fromBuffer ( buf ) ;
} while ( rnd > interval ) ;
return rnd + min ;
}
let _useWorkers = false ; // The following is just to check whether we can use workers
/* eslint-disable no-lone-blocks */
{ // Node.js
try {
2022-08-01 02:19:48 +00:00
await import ( 'worker_threads' ) ;
2021-03-25 12:40:04 +00:00
_useWorkers = true ;
2022-08-01 17:10:00 +00:00
} /* c8 ignore start */
2021-03-25 12:40:04 +00:00
catch ( e ) {
console . log ( ` [bigint-crypto-utils] WARNING:
This node version doesn ' t support worker _threads . You should enable them in order to greatly speedup the generation of big prime numbers .
· With Node >= 11 it is enabled by default ( consider upgrading ) .
· With Node 10 , starting with 10.5 . 0 , you can enable worker _threads at runtime executing node -- experimental - worker ` );
}
2022-08-01 17:10:00 +00:00
/* c8 ignore stop */
2021-03-25 12:40:04 +00:00
}
/ * *
* The test first tries if any of the first 250 small primes are a factor of the input number and then passes several
* iterations of Miller - Rabin Probabilistic Primality Test ( FIPS 186 - 4 C . 3.1 )
*
* @ param w - A positive integer to be tested for primality
* @ param iterations - The number of iterations for the primality test . The value shall be consistent with Table C . 1 , C . 2 or C . 3
* @ param disableWorkers - Disable the use of workers for the primality test
*
* @ throws { RangeError }
* w MUST be >= 0
*
* @ returns A promise that resolves to a boolean that is either true ( a probably prime number ) or false ( definitely composite )
* /
function isProbablyPrime ( w , iterations = 16 , disableWorkers = false ) {
if ( typeof w === 'number' ) {
w = BigInt ( w ) ;
}
if ( w < 0 n )
throw RangeError ( 'w MUST be >= 0' ) ;
{ // Node.js
if ( ! disableWorkers && _useWorkers ) {
return new Promise ( ( resolve , reject ) => {
2022-08-01 20:21:29 +00:00
const worker = new workerThreads$1 . Worker ( './dist/esm/index.node.js' ) ;
2021-03-25 12:40:04 +00:00
worker . on ( 'message' , ( data ) => {
2022-08-01 02:19:48 +00:00
worker . terminate ( ) . catch ( reject ) ;
2021-03-25 12:40:04 +00:00
resolve ( data . isPrime ) ;
} ) ;
worker . on ( 'error' , reject ) ;
const msg = {
rnd : w ,
iterations : iterations ,
id : 0
} ;
worker . postMessage ( msg ) ;
} ) ;
}
else {
return new Promise ( ( resolve ) => {
resolve ( _isProbablyPrime ( w , iterations ) ) ;
} ) ;
}
}
}
2021-04-21 09:14:04 +00:00
function _isProbablyPrime ( w , iterations ) {
2021-03-25 12:40:04 +00:00
/ *
PREFILTERING . Even values but 2 are not primes , so don ' t test .
1 is not a prime and the M - R algorithm needs w > 1.
* /
if ( w === 2 n )
return true ;
else if ( ( w & 1 n ) === 0 n || w === 1 n )
return false ;
/ *
Test if any of the first 250 small primes are a factor of w . 2 is not tested because it was already tested above .
* /
const firstPrimes = [
3 n ,
5 n ,
7 n ,
11 n ,
13 n ,
17 n ,
19 n ,
23 n ,
29 n ,
31 n ,
37 n ,
41 n ,
43 n ,
47 n ,
53 n ,
59 n ,
61 n ,
67 n ,
71 n ,
73 n ,
79 n ,
83 n ,
89 n ,
97 n ,
101 n ,
103 n ,
107 n ,
109 n ,
113 n ,
127 n ,
131 n ,
137 n ,
139 n ,
149 n ,
151 n ,
157 n ,
163 n ,
167 n ,
173 n ,
179 n ,
181 n ,
191 n ,
193 n ,
197 n ,
199 n ,
211 n ,
223 n ,
227 n ,
229 n ,
233 n ,
239 n ,
241 n ,
251 n ,
257 n ,
263 n ,
269 n ,
271 n ,
277 n ,
281 n ,
283 n ,
293 n ,
307 n ,
311 n ,
313 n ,
317 n ,
331 n ,
337 n ,
347 n ,
349 n ,
353 n ,
359 n ,
367 n ,
373 n ,
379 n ,
383 n ,
389 n ,
397 n ,
401 n ,
409 n ,
419 n ,
421 n ,
431 n ,
433 n ,
439 n ,
443 n ,
449 n ,
457 n ,
461 n ,
463 n ,
467 n ,
479 n ,
487 n ,
491 n ,
499 n ,
503 n ,
509 n ,
521 n ,
523 n ,
541 n ,
547 n ,
557 n ,
563 n ,
569 n ,
571 n ,
577 n ,
587 n ,
593 n ,
599 n ,
601 n ,
607 n ,
613 n ,
617 n ,
619 n ,
631 n ,
641 n ,
643 n ,
647 n ,
653 n ,
659 n ,
661 n ,
673 n ,
677 n ,
683 n ,
691 n ,
701 n ,
709 n ,
719 n ,
727 n ,
733 n ,
739 n ,
743 n ,
751 n ,
757 n ,
761 n ,
769 n ,
773 n ,
787 n ,
797 n ,
809 n ,
811 n ,
821 n ,
823 n ,
827 n ,
829 n ,
839 n ,
853 n ,
857 n ,
859 n ,
863 n ,
877 n ,
881 n ,
883 n ,
887 n ,
907 n ,
911 n ,
919 n ,
929 n ,
937 n ,
941 n ,
947 n ,
953 n ,
967 n ,
971 n ,
977 n ,
983 n ,
991 n ,
997 n ,
1009 n ,
1013 n ,
1019 n ,
1021 n ,
1031 n ,
1033 n ,
1039 n ,
1049 n ,
1051 n ,
1061 n ,
1063 n ,
1069 n ,
1087 n ,
1091 n ,
1093 n ,
1097 n ,
1103 n ,
1109 n ,
1117 n ,
1123 n ,
1129 n ,
1151 n ,
1153 n ,
1163 n ,
1171 n ,
1181 n ,
1187 n ,
1193 n ,
1201 n ,
1213 n ,
1217 n ,
1223 n ,
1229 n ,
1231 n ,
1237 n ,
1249 n ,
1259 n ,
1277 n ,
1279 n ,
1283 n ,
1289 n ,
1291 n ,
1297 n ,
1301 n ,
1303 n ,
1307 n ,
1319 n ,
1321 n ,
1327 n ,
1361 n ,
1367 n ,
1373 n ,
1381 n ,
1399 n ,
1409 n ,
1423 n ,
1427 n ,
1429 n ,
1433 n ,
1439 n ,
1447 n ,
1451 n ,
1453 n ,
1459 n ,
1471 n ,
1481 n ,
1483 n ,
1487 n ,
1489 n ,
1493 n ,
1499 n ,
1511 n ,
1523 n ,
1531 n ,
1543 n ,
1549 n ,
1553 n ,
1559 n ,
1567 n ,
1571 n ,
1579 n ,
1583 n ,
1597 n
] ;
for ( let i = 0 ; i < firstPrimes . length && ( firstPrimes [ i ] <= w ) ; i ++ ) {
const p = firstPrimes [ i ] ;
if ( w === p )
return true ;
else if ( w % p === 0 n )
return false ;
}
/ *
1. Let a be the largest integer such that 2 * * a divides w − 1.
2. m = ( w − 1 ) / 2 * * a .
3. wlen = len ( w ) .
4. For i = 1 to iterations do
4.1 Obtain a string b of wlen bits from an RBG .
Comment : Ensure that 1 < b < w − 1.
4.2 If ( ( b ≤ 1 ) or ( b ≥ w − 1 ) ) , then go to step 4.1 .
4.3 z = b * * m mod w .
4.4 If ( ( z = 1 ) or ( z = w − 1 ) ) , then go to step 4.7 .
4.5 For j = 1 to a − 1 do .
4.5 . 1 z = z * * 2 mod w .
4.5 . 2 If ( z = w − 1 ) , then go to step 4.7 .
4.5 . 3 If ( z = 1 ) , then go to step 4.6 .
4.6 Return COMPOSITE .
4.7 Continue .
Comment : Increment i for the do - loop in step 4.
5. Return PROBABLY PRIME .
* /
let a = 0 n ;
const d = w - 1 n ;
let aux = d ;
while ( aux % 2 n === 0 n ) {
aux /= 2 n ;
++ a ;
}
const m = d / ( 2 n * * a ) ;
do {
const b = randBetween ( d , 2 n ) ;
2022-08-01 02:19:48 +00:00
let z = modPow ( b , m , w ) ;
2021-03-25 12:40:04 +00:00
if ( z === 1 n || z === d )
continue ;
let j = 1 ;
while ( j < a ) {
2022-08-01 02:19:48 +00:00
z = modPow ( z , 2 n , w ) ;
2021-03-25 12:40:04 +00:00
if ( z === d )
break ;
if ( z === 1 n )
return false ;
j ++ ;
}
if ( z !== d )
return false ;
} while ( -- iterations !== 0 ) ;
return true ;
}
2022-08-01 19:53:46 +00:00
if ( _useWorkers ) { // node.js with support for workers
try {
var workerThreads$1 = await import ( 'worker_threads' ) ; // eslint-disable-line no-var
2022-08-01 18:34:24 +00:00
const isWorker = ! ( workerThreads$1 . isMainThread ) ;
if ( isWorker && workerThreads$1 . parentPort !== null ) { // worker
const parentPort = workerThreads$1 . parentPort ;
parentPort . on ( 'message' , function ( data ) {
const isPrime = _isProbablyPrime ( data . rnd , data . iterations ) ;
const msg = {
isPrime : isPrime ,
value : data . rnd ,
id : data . id
} ;
parentPort . postMessage ( msg ) ;
} ) ;
}
2021-03-25 12:40:04 +00:00
}
2022-08-01 19:53:46 +00:00
catch ( error ) { }
2021-03-25 12:40:04 +00:00
}
2022-08-01 02:19:48 +00:00
var os = await import ( 'os' ) ; // eslint-disable-line no-var
2022-08-01 18:34:24 +00:00
{
try {
var workerThreads = await import ( 'worker_threads' ) ; // eslint-disable-line no-var
}
catch { }
}
2021-03-25 12:40:04 +00:00
/ * *
* A probably - prime ( Miller - Rabin ) , cryptographically - secure , random - number generator .
* The browser version uses web workers to parallelise prime look up . Therefore , it does not lock the UI
* 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 ) .
*
* @ param bitLength - The required bit length for the generated prime
* @ param iterations - The number of iterations for the Miller - Rabin Probabilistic Primality Test
*
* @ throws { RangeError }
* bitLength MUST be > 0
*
* @ returns A promise that resolves to a bigint probable prime of bitLength bits .
* /
function prime ( bitLength , iterations = 16 ) {
if ( bitLength < 1 )
throw new RangeError ( 'bitLength MUST be > 0' ) ;
2022-08-01 17:10:00 +00:00
/* c8 ignore start */
2021-03-25 12:40:04 +00:00
if ( ! _useWorkers ) { // If there is no support for workers
let rnd = 0 n ;
do {
rnd = fromBuffer ( randBitsSync ( bitLength , true ) ) ;
} while ( ! _isProbablyPrime ( rnd , iterations ) ) ;
return new Promise ( ( resolve ) => { resolve ( rnd ) ; } ) ;
}
2022-08-01 17:10:00 +00:00
/* c8 ignore stop */
2021-03-25 12:40:04 +00:00
return new Promise ( ( resolve , reject ) => {
const workerList = [ ] ;
const _onmessage = ( msg , newWorker ) => {
if ( msg . isPrime ) {
// if a prime number has been found, stop all the workers, and return it
for ( let j = 0 ; j < workerList . length ; j ++ ) {
2022-08-01 02:19:48 +00:00
workerList [ j ] . terminate ( ) ; // eslint-disable-line @typescript-eslint/no-floating-promises
2021-03-25 12:40:04 +00:00
}
while ( workerList . length > 0 ) {
workerList . pop ( ) ;
}
resolve ( msg . value ) ;
}
else { // if a composite is found, make the worker test another random number
const buf = randBitsSync ( bitLength , true ) ;
const rnd = fromBuffer ( buf ) ;
try {
const msgToWorker = {
rnd : rnd ,
iterations : iterations ,
id : msg . id
} ;
newWorker . postMessage ( msgToWorker ) ;
}
catch ( error ) {
// The worker has already terminated. There is nothing to handle here
}
}
} ;
{ // Node.js
2022-08-01 02:19:48 +00:00
for ( let i = 0 ; i < os . cpus ( ) . length - 1 ; i ++ ) {
2022-08-01 20:21:29 +00:00
const newWorker = new workerThreads . Worker ( './dist/esm/index.node.js' ) ;
2021-03-25 12:40:04 +00:00
newWorker . on ( 'message' , ( msg ) => _onmessage ( msg , newWorker ) ) ;
workerList . push ( newWorker ) ;
}
}
for ( let i = 0 ; i < workerList . length ; i ++ ) {
randBits ( bitLength , true ) . then ( function ( buf ) {
const rnd = fromBuffer ( buf ) ;
workerList [ i ] . postMessage ( {
rnd : rnd ,
iterations : iterations ,
id : i
} ) ;
} ) . catch ( reject ) ;
}
} ) ;
}
/ * *
* 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 bitLength - The required bit length for the generated prime
* @ param iterations - The number of iterations for the Miller - Rabin Probabilistic Primality Test
*
* @ throws { RangeError }
* bitLength MUST be > 0
*
* @ returns A bigint probable prime of bitLength bits .
* /
function primeSync ( bitLength , iterations = 16 ) {
if ( bitLength < 1 )
throw new RangeError ( 'bitLength MUST be > 0' ) ;
let rnd = 0 n ;
do {
rnd = fromBuffer ( randBitsSync ( bitLength , true ) ) ;
} while ( ! _isProbablyPrime ( rnd , iterations ) ) ;
return rnd ;
}
2022-08-01 02:19:48 +00:00
export { abs , bitLength , eGcd , gcd , isProbablyPrime , lcm , max , min , modInv , modPow , prime , primeSync , randBetween , randBits , randBitsSync , randBytes , randBytesSync , toZn } ;
2022-08-01 20:21:29 +00:00
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXgubm9kZS5qcyIsInNvdXJjZXMiOlsiLi4vLi4vbm9kZV9tb2R1bGVzL2JpZ2ludC1tb2QtYXJpdGgvZGlzdC9lc20vaW5kZXgubm9kZS5qcyIsIi4uLy4uL3NyYy90cy9mcm9tQnVmZmVyLnRzIiwiLi4vLi4vc3JjL3RzL3JhbmRCeXRlcy50cyIsIi4uLy4uL3NyYy90cy9yYW5kQml0cy50cyIsIi4uLy4uL3NyYy90cy9yYW5kQmV0d2Vlbi50cyIsIi4uLy4uL3NyYy90cy93b3JrZXJVdGlscy50cyIsIi4uLy4uL3NyYy90cy9pc1Byb2JhYmx5UHJpbWUudHMiLCIuLi8uLi9zcmMvdHMvcHJpbWUudHMiXSwic291cmNlc0NvbnRlbnQiOm51bGwsIm5hbWVzIjpbIndvcmtlclRocmVhZHMiXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUyxHQUFHLENBQUMsQ0FBQyxFQUFFO0FBQ2hCLElBQUksT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQzdCLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVMsU0FBUyxDQUFDLENBQUMsRUFBRTtBQUN0QixJQUFJLElBQUksT0FBTyxDQUFDLEtBQUssUUFBUTtBQUM3QixRQUFRLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdEIsSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFLEVBQUU7QUFDbEIsUUFBUSxPQUFPLENBQUMsQ0FBQztBQUNqQixLQUFLO0FBQ0wsSUFBSSxJQUFJLElBQUksR0FBRyxDQUFDLENBQUM7QUFDakIsSUFBSSxHQUFHO0FBQ1AsUUFBUSxJQUFJLEVBQUUsQ0FBQztBQUNmLEtBQUssUUFBUSxDQUFDLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxFQUFFO0FBQzlCLElBQUksT0FBTyxJQUFJLENBQUM7QUFDaEIsQ0FBQztBQUNE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