[VM bigint] Fix padding length in Montgomery Reduction (fixes #32626).
Add regression test to existing bigint test.

Change-Id: I9e470c4002c25493285ce6bb908375ff913a4e17
Reviewed-on: https://dart-review.googlesource.com/54070
Reviewed-by: Alexander Markov <alexmarkov@google.com>
diff --git a/runtime/lib/bigint_patch.dart b/runtime/lib/bigint_patch.dart
index 7516712..0b0cd0f 100644
--- a/runtime/lib/bigint_patch.dart
+++ b/runtime/lib/bigint_patch.dart
@@ -2628,7 +2628,8 @@
   }
 
   _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 @@
   // 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 e6845d0..290e477 100644
--- a/tests/corelib_2/bigint_test.dart
+++ b/tests/corelib_2/bigint_test.dart
@@ -484,6 +484,29 @@
   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() {