diff --git a/runtime/lib/bigint_patch.dart b/runtime/lib/bigint_patch.dart index 751671273b0..0b0cd0f5351 100644 --- a/runtime/lib/bigint_patch.dart +++ b/runtime/lib/bigint_patch.dart @@ -2628,7 +2628,8 @@ class _BigIntMontgomeryReduction implements _BigIntReduction { } _BigIntImpl _revert(Uint32List xDigits, int xUsed) { - var resultDigits = _newDigits(2 * _normModulusUsed); + // Reserve enough digits for modulus squaring and accumulator carry. + var resultDigits = _newDigits(2 * _normModulusUsed + 2); var i = xUsed + (xUsed & 1); while (--i >= 0) { resultDigits[i] = xDigits[i]; @@ -2640,8 +2641,8 @@ class _BigIntMontgomeryReduction implements _BigIntReduction { // x = x/R mod _modulus. // Returns xUsed. int _reduce(Uint32List xDigits, int xUsed) { - while (xUsed < 2 * _normModulusUsed) { - // Pad x so _mulAdd has enough room later. + while (xUsed < 2 * _normModulusUsed + 2) { + // Pad x so _mulAdd has enough room later for a possible carry. xDigits[xUsed++] = 0; } var i = 0; diff --git a/tests/corelib_2/bigint_test.dart b/tests/corelib_2/bigint_test.dart index e6845d00fbd..290e477ee21 100644 --- a/tests/corelib_2/bigint_test.dart +++ b/tests/corelib_2/bigint_test.dart @@ -484,6 +484,29 @@ testBigintModPow() { e = BigInt.parse("123456789012345678901234567890"); m = BigInt.parse("123456789012345678901234567899"); Expect.equals(BigInt.parse("40128068573873018143207285483"), x.modPow(e, m)); + x = BigInt.parse( + "142223781135477974841804437037182877109549636480215350570761436386728140" + "00321219503871352719175100865184619168128345594681547640115731246638"); + e = BigInt.parse( + "688057170495263083245752731085731160016625265771524738691797062279575950" + "919479651156310413084174304361991240273181430924411258203766946639349880" + "404106504114953688890200429043051936362182997575167191584461538746041795" + "019663740246921124383173799957296515067912829778249931473903780958741032" + "64534184571632120755"); + m = BigInt.parse( + "144173682842817587002196172066264549138375068078359231382946906898412792" + "452632726597279520229873489736777248181678202636100459215718497240474064" + "366927544074501134727745837254834206456400508719134610847814227274992298" + "238973375146473350157304285346424982280927848339601514720098577525635486" + "320547905945936448443"); + Expect.equals( + BigInt.parse( + "41228476947144730491819644448449646627743926889389391986712371102685" + "14984467753960109321610008533258676279344318597060690521027646613453" + "25674994677820913027869835916005689276806408148698486814119894325284" + "18918299321385420296108046942018595594076729397423805685944237555128" + "652606412065971965116137839721723231"), + x.modPow(e, m)); } testBigintModInverse() {