2023-06-28 17:38:17 +00:00
function n ( n ) { return n >= 0 ? n : - n } function t ( n ) { if ( "number" == typeof n && ( n = BigInt ( n ) ) , 1 n === n ) return 1 ; let t = 1 ; do { t ++ ; } while ( ( n >>= 1 n ) > 1 n ) ; return t } function r ( n , t ) { if ( "number" == typeof n && ( n = BigInt ( n ) ) , "number" == typeof t && ( t = BigInt ( t ) ) , n <= 0 n || t <= 0 n ) throw new RangeError ( "a and b MUST be > 0" ) ; let r = 0 n , e = 1 n , o = 1 n , i = 0 n ; for ( ; 0 n !== n ; ) { const u = t / n , f = t % n , g = r - o * u , c = e - i * u ; t = n , n = f , r = o , e = i , o = g , i = c ; } return { g : t , x : r , y : e } } function e ( n , t ) { if ( "number" == typeof n && ( n = BigInt ( n ) ) , "number" == typeof t && ( t = BigInt ( t ) ) , t <= 0 n ) throw new RangeError ( "n must be > 0" ) ; const r = n % t ; return r < 0 n ? r + t : r } function o ( n , t ) { const o = r ( e ( n , t ) , t ) ; if ( 1 n !== o . g ) throw new RangeError ( ` ${ n . toString ( ) } does not have inverse modulo ${ t . toString ( ) } ` ) ; return e ( o . x , t ) } function i ( n , t , r ) { if ( n . length !== t . length ) throw new RangeError ( "The remainders and modulos arrays should have the same length" ) ; const i = r ? ? t . reduce ( ( ( n , t ) => n * t ) , 1 n ) ; return t . reduce ( ( ( t , r , u ) => { const f = i / r ; return e ( t + f * o ( f , r ) % i * n [ u ] % i , i ) } ) , 0 n ) } function u ( t , r ) { let e = "number" == typeof t ? BigInt ( n ( t ) ) : n ( t ) , o = "number" == typeof r ? BigInt ( n ( r ) ) : n ( r ) ; if ( 0 n === e ) return o ; if ( 0 n === o ) return e ; let i = 0 n ; for ( ; 0 n === ( 1 n & ( e | o ) ) ; ) e >>= 1 n , o >>= 1 n , i ++ ; for ( ; 0 n === ( 1 n & e ) ; ) e >>= 1 n ; do { for ( ; 0 n === ( 1 n & o ) ; ) o >>= 1 n ; if ( e > o ) { const n = e ; e = o , o = n ; } o -= e ; } while ( 0 n !== o ) ; return e << i } function f ( t , r ) { return "number" == typeof t && ( t = BigInt ( t ) ) , "number" == typeof r && ( r = BigInt ( r ) ) , 0 n === t && 0 n === r ? BigInt ( 0 ) : n ( t / u ( t , r ) * r ) } function g ( n , t ) { return n >= t ? n : t } function c ( n , t ) { return n >= t ? t : n } function m ( n , t ) { const r = BigInt ( t ) ; return e ( n . map ( ( n => BigInt ( n ) % r ) ) . reduce ( ( ( n , t ) => n + t % r ) , 0 n ) , r ) } function p ( n , t ) { const r = BigInt ( t ) ; return e ( n . map ( ( n => BigInt ( n ) % r ) ) . reduce ( ( ( n , t ) => n * t % r ) , 1 n ) , r ) } function a ( n ) { return n . map ( ( n => n [ 0 ] * * ( n [ 1 ] - 1 n ) * ( n [ 0 ] - 1 n ) ) ) . reduce ( ( ( n , t ) => t * n ) , 1 n ) } function s ( t , r , u , f ) { if ( "number" == typeof t && ( t = BigInt ( t ) ) , "number" == typeof r && ( r = BigInt ( r ) ) , "number" == typeof u && ( u = BigInt ( u ) ) , u <= 0 n ) throw new RangeError ( "n must be > 0" ) ; if ( 1 n === u ) return 0 n ; if ( t = e ( t , u ) , r < 0 n ) return o ( s ( t , n ( r ) , u , f ) , u ) ; if ( void 0 !== f ) return function ( n , t , r , e ) { const o = e . map ( ( n => n [ 0 ] * * n [ 1 ] ) ) , u = e . map ( ( n => a ( [ n ] ) ) ) , f = u . map ( ( ( r , e ) => s ( n , t % r , o [ e ] ) ) ) ; return i ( f , o , r ) } ( t , r , u , function ( n ) { const t = { } ; return n . forEach ( ( n => { if ( "bigint" == typeof n || "number" == typeof n ) { const r = String ( n ) ; void 0 === t [ r ] ? t [ r ] = { p : BigInt ( n ) , k : 1 n } : t [ r ] . k += 1 n ; } else { const r = String ( n [ 0 ] ) ; void 0 === t [ r ] ? t [ r ] = { p : BigInt ( n [ 0 ] ) , k : BigInt ( n [ 1 ] ) } : t [ r ] . k += BigInt ( n [ 1 ] ) ; } } ) ) , Object . values ( t ) . map ( ( n => [ n . p , n . k ] ) ) } ( f ) ) ; let g = 1 n ; for ( ; r > 0 ; ) r % 2 n === 1 n && ( g = g * t % u ) , r /= 2 n , t = t * * 2 n % u ; return g }
2022-08-01 02:40:02 +00:00
function fromBuffer ( buf ) {
let ret = 0 n ;
for ( const i of buf . values ( ) ) {
const bi = BigInt ( i ) ;
ret = ( ret << 8 n ) + bi ;
}
return ret ;
}
function randBytes ( byteLength , forceLength = false ) {
if ( byteLength < 1 )
throw new RangeError ( 'byteLength MUST be > 0' ) ;
return new Promise ( function ( resolve , reject ) {
2023-04-11 09:01:32 +00:00
{
2022-08-01 02:40:02 +00:00
const buf = new Uint8Array ( byteLength ) ;
2022-12-20 22:51:18 +00:00
if ( byteLength <= 65536 ) {
self . crypto . getRandomValues ( buf ) ;
}
else {
for ( let i = 0 ; i < Math . ceil ( byteLength / 65536 ) ; i ++ ) {
const begin = i * 65536 ;
const end = ( ( begin + 65535 ) < byteLength ) ? begin + 65535 : byteLength - 1 ;
self . crypto . getRandomValues ( buf . subarray ( begin , end ) ) ;
}
}
2022-08-01 02:40:02 +00:00
if ( forceLength )
buf [ 0 ] = buf [ 0 ] | 128 ;
resolve ( buf ) ;
}
} ) ;
}
function randBytesSync ( byteLength , forceLength = false ) {
if ( byteLength < 1 )
throw new RangeError ( 'byteLength MUST be > 0' ) ;
2023-04-11 09:01:32 +00:00
{
2022-08-01 02:40:02 +00:00
const buf = new Uint8Array ( byteLength ) ;
2022-12-20 22:51:18 +00:00
if ( byteLength <= 65536 ) {
self . crypto . getRandomValues ( buf ) ;
}
else {
for ( let i = 0 ; i < Math . ceil ( byteLength / 65536 ) ; i ++ ) {
const begin = i * 65536 ;
const end = ( ( begin + 65535 ) < byteLength ) ? begin + 65535 : byteLength - 1 ;
self . crypto . getRandomValues ( buf . subarray ( begin , end ) ) ;
}
}
2022-08-01 02:40:02 +00:00
if ( forceLength )
buf [ 0 ] = buf [ 0 ] | 128 ;
return buf ;
}
}
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 ) {
rndBytes [ 0 ] = rndBytes [ 0 ] & ( 2 * * bitLengthMod8 - 1 ) ;
}
if ( forceLength ) {
const mask = ( bitLengthMod8 !== 0 ) ? 2 * * ( bitLengthMod8 - 1 ) : 128 ;
rndBytes [ 0 ] = rndBytes [ 0 ] | mask ;
}
resolve ( rndBytes ) ;
} ) ;
} ) ;
}
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 ) {
rndBytes [ 0 ] = rndBytes [ 0 ] & ( 2 * * bitLengthMod8 - 1 ) ;
}
if ( forceLength ) {
const mask = ( bitLengthMod8 !== 0 ) ? 2 * * ( bitLengthMod8 - 1 ) : 128 ;
rndBytes [ 0 ] = rndBytes [ 0 ] | mask ;
}
return rndBytes ;
}
function randBetween ( max , min = 1 n ) {
if ( max <= min )
throw new RangeError ( 'Arguments MUST be: max > min' ) ;
const interval = max - min ;
2023-04-13 17:33:52 +00:00
const bitLen = t ( interval ) ;
2022-08-01 02:40:02 +00:00
let rnd ;
do {
const buf = randBitsSync ( bitLen ) ;
rnd = fromBuffer ( buf ) ;
} while ( rnd > interval ) ;
return rnd + min ;
}
function _workerUrl ( workerCode ) {
2023-04-11 09:01:32 +00:00
workerCode = ` (() => { ${ workerCode } })() ` ;
2022-08-01 02:40:02 +00:00
const _blob = new Blob ( [ workerCode ] , { type : 'text/javascript' } ) ;
return window . URL . createObjectURL ( _blob ) ;
}
2023-04-11 09:01:32 +00:00
let _useWorkers = false ;
{
2022-08-01 02:40:02 +00:00
if ( self . Worker !== undefined )
_useWorkers = true ;
}
function isProbablyPrime ( w , iterations = 16 , disableWorkers = false ) {
if ( typeof w === 'number' ) {
w = BigInt ( w ) ;
}
if ( w < 0 n )
throw RangeError ( 'w MUST be >= 0' ) ;
2023-04-11 09:01:32 +00:00
{
2022-08-01 02:40:02 +00:00
return new Promise ( ( resolve , reject ) => {
const worker = new Worker ( _isProbablyPrimeWorkerUrl ( ) ) ;
worker . onmessage = ( event ) => {
2022-09-08 11:56:49 +00:00
if ( event ? . data ? . _bcu ? . isPrime !== undefined ) {
worker . terminate ( ) ;
resolve ( event . data . _bcu . isPrime ) ;
}
2022-08-01 02:40:02 +00:00
} ;
worker . onmessageerror = ( event ) => {
reject ( event ) ;
} ;
const msg = {
2022-09-08 11:56:49 +00:00
_bcu : {
rnd : w ,
2023-04-11 09:01:32 +00:00
iterations ,
2022-09-08 11:56:49 +00:00
id : 0
}
2022-08-01 02:40:02 +00:00
} ;
worker . postMessage ( msg ) ;
} ) ;
}
}
function _isProbablyPrime ( w , iterations ) {
if ( w === 2 n )
return true ;
else if ( ( w & 1 n ) === 0 n || w === 1 n )
return false ;
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 ;
}
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 {
2023-06-28 17:35:42 +00:00
const b = randBetween ( d , 2 n ) ;
let z = s ( b , m , w ) ;
2022-08-01 02:40:02 +00:00
if ( z === 1 n || z === d )
continue ;
let j = 1 ;
while ( j < a ) {
2023-06-28 17:35:42 +00:00
z = s ( z , 2 n , w ) ;
2022-08-01 02:40:02 +00:00
if ( z === d )
break ;
if ( z === 1 n )
return false ;
j ++ ;
}
if ( z !== d )
return false ;
} while ( -- iterations !== 0 ) ;
return true ;
}
function _isProbablyPrimeWorkerUrl ( ) {
2022-09-08 11:56:49 +00:00
let workerCode = `
'use strict' ;
2023-04-13 17:33:52 +00:00
const $ { r . name } = $ { r . toString ( ) } ;
2023-06-28 17:35:42 +00:00
const $ { o . name } = $ { o . toString ( ) } ;
const $ { s . name } = $ { s . toString ( ) } ;
const $ { e . name } = $ { e . toString ( ) } ;
2022-09-08 11:56:49 +00:00
const $ { randBitsSync . name } = $ { randBitsSync . toString ( ) } ;
const $ { randBytesSync . name } = $ { randBytesSync . toString ( ) } ;
const $ { randBetween . name } = $ { randBetween . toString ( ) } ;
const $ { isProbablyPrime . name } = $ { _isProbablyPrime . toString ( ) } ;
2023-04-13 17:33:52 +00:00
$ { t . toString ( ) } ;
2022-09-08 11:56:49 +00:00
$ { fromBuffer . toString ( ) } ; ` ;
workerCode += `
onmessage = async function ( msg ) {
if ( msg !== undefined && msg . data !== undefined && msg . data . _bcu !== undefined && msg . data . _bcu . id !== undefined && msg . data . _bcu . iterations !== undefined && msg . data . _bcu . rnd !== undefined ) {
const msgToParent = {
_bcu : {
isPrime : await $ { isProbablyPrime . name } ( msg . data . _bcu . rnd , msg . data . _bcu . iterations ) ,
value : msg . data . _bcu . rnd ,
id : msg . data . _bcu . id
}
} ;
postMessage ( msgToParent ) ;
}
} ` ;
2022-08-01 02:40:02 +00:00
return _workerUrl ( workerCode ) ;
}
function prime ( bitLength , iterations = 16 ) {
if ( bitLength < 1 )
throw new RangeError ( 'bitLength MUST be > 0' ) ;
2023-04-11 09:01:32 +00:00
if ( ! _useWorkers ) {
2022-08-01 02:40:02 +00:00
let rnd = 0 n ;
do {
rnd = fromBuffer ( randBitsSync ( bitLength , true ) ) ;
} while ( ! _isProbablyPrime ( rnd , iterations ) ) ;
return new Promise ( ( resolve ) => { resolve ( rnd ) ; } ) ;
}
return new Promise ( ( resolve , reject ) => {
const workerList = [ ] ;
const _onmessage = ( msg , newWorker ) => {
2022-09-08 11:56:49 +00:00
if ( msg . _bcu . isPrime ) {
2022-08-01 02:40:02 +00:00
for ( let j = 0 ; j < workerList . length ; j ++ ) {
2023-04-11 09:01:32 +00:00
workerList [ j ] . terminate ( ) ;
2022-08-01 02:40:02 +00:00
}
while ( workerList . length > 0 ) {
workerList . pop ( ) ;
}
2022-09-08 11:56:49 +00:00
resolve ( msg . _bcu . value ) ;
2022-08-01 02:40:02 +00:00
}
2023-04-11 09:01:32 +00:00
else {
2022-08-01 02:40:02 +00:00
const buf = randBitsSync ( bitLength , true ) ;
const rnd = fromBuffer ( buf ) ;
try {
const msgToWorker = {
2022-09-08 11:56:49 +00:00
_bcu : {
2023-04-11 09:01:32 +00:00
rnd ,
iterations ,
2022-09-08 11:56:49 +00:00
id : msg . _bcu . id
}
2022-08-01 02:40:02 +00:00
} ;
newWorker . postMessage ( msgToWorker ) ;
}
catch ( error ) {
}
}
} ;
2023-04-11 09:01:32 +00:00
{
2022-08-01 02:40:02 +00:00
const workerURL = _isProbablyPrimeWorkerUrl ( ) ;
for ( let i = 0 ; i < self . navigator . hardwareConcurrency - 1 ; i ++ ) {
const newWorker = new Worker ( workerURL ) ;
newWorker . onmessage = ( event ) => _onmessage ( event . data , 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 ( {
2022-09-08 11:56:49 +00:00
_bcu : {
2023-04-11 09:01:32 +00:00
rnd ,
iterations ,
2022-09-08 11:56:49 +00:00
id : i
}
2022-08-01 02:40:02 +00:00
} ) ;
} ) . catch ( reject ) ;
}
} ) ;
}
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 ;
}
2023-06-28 17:38:17 +00:00
export { n as abs , t as bitLength , i as crt , r as eGcd , u as gcd , isProbablyPrime , f as lcm , g as max , c as min , m as modAdd , o as modInv , p as modMultiply , s as modPow , a as phi , prime , primeSync , randBetween , randBits , randBitsSync , randBytes , randBytesSync , e as toZn } ;