import * as bma from '#pkg' describe('modPow', function () { const inputs = [ { a: BigInt(4), b: BigInt(-1), n: BigInt(1), modPow: BigInt(0) }, { a: BigInt(4), b: -1, n: BigInt(19), modPow: BigInt(5) }, { a: BigInt(-5), b: BigInt(2), n: 7, modPow: BigInt(4) }, { a: 2, b: BigInt(255), n: BigInt(64), modPow: BigInt(0), factorization: [ [2n, 6n] as [bigint, bigint] ] }, { a: BigInt(3), b: BigInt(3), n: BigInt(25), modPow: BigInt(2) }, { a: 1245124521461246134613464612465425n, b: 9861532432154028374523497086414586n, n: 500153323344587826888856848415851710985056973082286918972465210560564286327935715658989361814629267526408365126549790626298674370641919299205366510873756645480988096218726721049169354944272728793562147809267541398194457197043260189n, modPow: 240451691789770161942445790505417018856065097712648273113407316782091824158551945401793333941917448724323499865320019414055693250255681376010258044942735855039307823617978628203426153507803442305305788129411652227222626528677503357n, factorization: [ 218230499735828681265329912048785421189n, 303663914757588658442322995331731552767n, 330074629227155283615948126790169269393n, 318474781297924758545194431666113118619n, 258866136593300047022978927175555617677n, 277352503791024309522752317490262967817n ] }, { a: 14, b: 7, n: 75, modPow: (14n ** 7n) % 75n, factorization: [5, 5, 3] }, { a: 14, b: 7, n: 75, modPow: (14n ** 7n) % 75n, factorization: [ [5, 2], [3, 1] ] as Array<[number, number]> }, { a: 14, b: 7, n: 75, modPow: (14n ** 7n) % 75n, factorization: [ [5, 1], [5, 1], [3, 1] ] as Array<[number, number]> } ] const invalidInputs = [ { a: BigInt(4), b: BigInt(-1), n: BigInt(0) } ] this.timeout(90000) for (const input of inputs) { describe(`modPow(${input.a}, ${input.b}, ${input.n})`, function () { it(`should return ${input.modPow}`, function () { const ret = bma.modPow(input.a, input.b, input.n) chai.expect(String(ret)).to.equal(String(input.modPow)) }) }) if (input.factorization !== undefined) { describe(`modPow(${input.a}, ${input.b}, ${input.n}, ${input.factorization.toString()})`, function () { it(`should return ${input.modPow}`, function () { const ret = bma.modPow(input.a, input.b, input.n, input.factorization) chai.expect(String(ret)).to.equal(String(input.modPow)) }) }) } } for (const input of invalidInputs) { describe(`modPow(${input.a}, ${input.b}, ${input.n})`, function () { it('should throw RangeError', function () { try { bma.modPow(input.a, input.b, input.n) throw new Error('should have failed') } catch (err) { chai.expect(err).to.be.instanceOf(RangeError) } }) }) } describe('Time profiling', function () { let iterations = 200 it(`just testing ${iterations} iterations of a big modular exponentiation (2556 bits) without knowing the factorization`, function () { const b = 14456431150320172221616509514915526986361238106327826551303073486525612767865296230128540157601034246266893020552680362383297675100669325175361571346279322237329539671666972989978592763343703141198972640627941866075477300010699834312750158094259287059018038648351844386887485449450696346016139524199689991349708808322654998848805208669420846568444495238595132694793197702398883664520354286998606227508937724093725751362231924270085297872354786607945787781132474291940577910417557559293025781300297297108502666688221522472289490235815670978276613741134646350434101590756987811531081642032408524942596500338402454466381n const e = 6476828424489334540282736436237684965801863681796103123350476262449294411071194504043425154023126089205310946452545492503146985930350204469300515359582715304152166280054365341048395809786334314857324636363499307693460463510288529968621389225833525926438586030988343742064052508822378379640511991190252363284703683198952353035019752852304188032580325320976126425473699273404534699914473174622613565918567472049036606462965033376292343629368800907251671928637057211397168781968913665986137146419257679003630816671501426427417948524164164352320112674416922816719009895345189205426946805834621054179616261802871233808542n const p = 14042712215688595888153548037889265603500445396639048834534593945467996508131090693365705725532399000992101105698944349047255173597667719370418259169482368508397450171314103850946590710597528264317201250415269575297721977669910571659769606054734401815045082525419212665804298903457270476082779587884970903510490346851467622773314340966549056833592925777140709340896303359906331395892064520612544700229681757412030739888382792194999476266900467607277786534152843408108882693507381781909441777014175765880808549111456404523289456415574592100070259890096499076724913855490255757168221008761519287520710678016476002003203122666993484494111951001896014648841958164118312595430383512299989338389906619375114947097244226374433271798549164684597345168487916487128962249635970759n while (iterations > 0) { bma.modPow(b, e, p) iterations-- } }) let iterations2 = 200 it(`just testing ${iterations2} iterations of a big modular exponentiation (2556 bits) knowing the factorization`, function () { const b = 14456431150320172221616509514915526986361238106327826551303073486525612767865296230128540157601034246266893020552680362383297675100669325175361571346279322237329539671666972989978592763343703141198972640627941866075477300010699834312750158094259287059018038648351844386887485449450696346016139524199689991349708808322654998848805208669420846568444495238595132694793197702398883664520354286998606227508937724093725751362231924270085297872354786607945787781132474291940577910417557559293025781300297297108502666688221522472289490235815670978276613741134646350434101590756987811531081642032408524942596500338402454466381n const e = 6476828424489334540282736436237684965801863681796103123350476262449294411071194504043425154023126089205310946452545492503146985930350204469300515359582715304152166280054365341048395809786334314857324636363499307693460463510288529968621389225833525926438586030988343742064052508822378379640511991190252363284703683198952353035019752852304188032580325320976126425473699273404534699914473174622613565918567472049036606462965033376292343629368800907251671928637057211397168781968913665986137146419257679003630816671501426427417948524164164352320112674416922816719009895345189205426946805834621054179616261802871233808542n const p = 14042712215688595888153548037889265603500445396639048834534593945467996508131090693365705725532399000992101105698944349047255173597667719370418259169482368508397450171314103850946590710597528264317201250415269575297721977669910571659769606054734401815045082525419212665804298903457270476082779587884970903510490346851467622773314340966549056833592925777140709340896303359906331395892064520612544700229681757412030739888382792194999476266900467607277786534152843408108882693507381781909441777014175765880808549111456404523289456415574592100070259890096499076724913855490255757168221008761519287520710678016476002003203122666993484494111951001896014648841958164118312595430383512299989338389906619375114947097244226374433271798549164684597345168487916487128962249635970759n const factorization = [ 64735041287835073339645110378796758902638279101014381826528695387496122442691n, 100608456040189246257906094489725850536673092825529567729728751391736301991369n, 58992718408385655584411200892712190864864350334099743757220725378063820240657n, 96562131825975924912838022675233698320760586729314385931723127363428962983247n, 68620104844493133229164822823175832794894654493599547904820655831878232061531n, 71474468886948151751742173259692288576445414562898468020644046548578552084431n, 96793884673833556249816099345608529931050134280462961194018209385115828684189n, 94085307601549784597508419912586171618182711224796241928810495401174923988119n, 91841918562944515248478087657554520191420619060733607414018266296555587309041n, 92269642318171922312931975258187595106742943586895754768486213552371747180589n ] while (iterations2 > 0) { bma.modPow(b, e, p, factorization) iterations2-- } }) }) })