 +  throw new Error("isPrime_s");
 +}
 +
-+// BigNat -> Int -> Bool
++
 +// fixme: seed
-+function h$ghcjsbn_isPrime_b(b, rounds) {
-+  ASSERTVALID_B(b, "isPrime");
-+  throw new Error("isPrime_b");
++function h$ghcjsbn_random_b(min, max) {
++  if(h$ghcjsbn_cmp_bb(min, max) >= 0) {
++    return min;
++  }
++  var range = h$ghcjsbn_sub_bb(max, min);
++  var size = 4 + Math.ceil(h$ghcjsbn_nbits_b(range) / 16);
++  var r = h$ghcjsbn_zero_b;
++  for(var i=0;i<size;i++) {
++    var rnd = Math.floor(Math.random()*65536);
++    r = h$ghcjsbn_or_bb(h$ghcsbn_shl_b(r, 16), h$ghcjsbn_mkBigNat_w(rnd));
++  }
++  return h$ghcjsbn_add_bb(h$ghcjsbn_rem_bb(r, range), min);
++}
++
++function h$ghcjsbn_testPrime_b(n, rounds) {
++  var r = 0, d = n;
++  var nm1 = h$ghcjsbn_sub_bw(n,1);
++  var two = h$ghcjsbn_mkBigNat_w(2);
++  while(h$ghcjsbn_testBit_b(d, 0)) {
++    d = h$ghcjsbn_shr_b(d, 1);
++    r++;
++  }
++  for(var round = 0; round < rounds; round++) {
++    var a = h$ghcjsbn_random_b(two, nm1);
++    var x = h$ghcjsbn_modPow_bbb(a, d, n);
++    if(h$ghcjsbn_eq_bw(x,1) || h$ghcjsbn_eq_bb(x,nm1)) continue;
++    var found = false;
++    for(var rr=0;rr<r;rr++) {
++      x = h$ghcjsbn_modPow_bbb(x, two, n);
++      if(h$ghcjsbn_eq_bb(x, nm1)) {
++        found = true;
++        break;
++      }
++    }
++    if(!found) return 0;
++  }
++  return 1;
++}
++
++function h$ghcjsbn_testPrime_w(w, rounds) {
++  return h$ghcjsbn_testPrime_b(h$ghcjsbn_mkBigNat_w(w), rounds);
++}
++
++function h$integer_gmp_next_prime1(w) {
++  var r = h$ghcjsbn_nextPrime_b(h$ghcjsbn_mkBigNat_w(w));
++  return h$ghcjsbn_toWord_b(r);
++}
++
++function h$ghcjsbn_nextPrime_b(bn) {
++  var rounds = 64;
++  if(h$ghcjsbn_eq_bw(bn, 2)) {
++    return h$ghcjsbn_mkBigNat_w(3);
++  }
++  var i = bn;
++  do {
++    i = h$ghcjsbn_add_bw(i, 2);
++  } while(!h$ghcjsbn_testPrime_b(i, rounds));
++  return i;
 +}
 +
 +// BigNat -> BigNat -> Bool

+  ASSERTVALID_D(r, "encodeDouble_s result");
+  return r;
+}
diff -X ../utils/updatePatches.excludes -Nru upstream/pkg/integer-gmp/src/GHC/Integer/GMP/Internals.hs boot/pkg/integer-gmp/src/GHC/Integer/GMP/Internals.hs
--- upstream/pkg/integer-gmp/src/GHC/Integer/GMP/Internals.hs	2018-12-24 07:45:51.000000000 +0100
+++ boot/pkg/integer-gmp/src/GHC/Integer/GMP/Internals.hs	2018-12-24 07:45:51.676965858 +0100
@@ -1,4 +1,5 @@
 {-# LANGUAGE BangPatterns #-}
+

+}
+
+// (b ^ s1) % s2 :: BigNat -> BigNat -> BigNat -> BigNat
+function h$ghcjsbn_modPow_bbb(b, e, m) {
+  var r = h$ghcjsbn_one_b, b = h$ghcjsbn_rem_bb(b, m);
+  while(!h$ghcjsbn_eq_bw(e, 0)) {
+    if(h$ghcjsbn_testBit_b(e, 0)) {
+      r = h$ghcjsbn_rem_bb(h$ghcjsbn_mul_bb(r, b), m);
+    }
+    e = h$ghcjsbn_shr_b(e, 1);
+    b = h$ghcjsbn_rem_bb(h$ghcjsbn_mul_bb(b, b), m);
+  }
+  return r;
+}
+
+// (b ^ s1) % s2 :: BigNat -> Int -> Int -> Int
+function h$ghcjsbn_modPow_bss(b, e, m) {
+  return h$ghcjsbn_modPow_sss(h$ghcjsbn_rem_bw(b, m), e, m);
+}
+// (s1 ^ s2) % s3 :: Int -> Int -> Int -> Int
+function h$ghcjsbn_modPow_sss(b, e, m) {
+  return h$integer_gmp_powm_word(b, e, m);
+}
+
+function h$integer_gmp_powm_word(b, e, m) {
+  var r = 1, b = b % m;
+  while(e !== 0) {
+    if(e % 2 === 1) r = (r * b) % m;
+    e = e >>> 1;
+    b = (b * b) % m;
+  }
+  return r;
+}
+
+// r = gcd(b1,b2) BigNat -> BigNat -> BigNat
+function h$ghcjsbn_gcd_bb(b1, b2) {
