diff --git a/src/bignum.c b/src/bignum.c
index e89bac46eb31aaf992ad6cadb25cd7e4b89afc63..7baecfd2b57cb740e40f1338ecfa8620e0b11cd9 100644
--- a/src/bignum.c
+++ b/src/bignum.c
@@ -12,6 +12,8 @@
 #include "svalue.h"
 #include "pike_error.h"
 
+#include "bignum.h"
+
 #define sp Pike_sp
 
 PMOD_EXPORT struct svalue auto_bignum_program = SVALUE_INIT_FREE;
@@ -125,6 +127,9 @@ PMOD_EXPORT void (*push_ulongest) (unsigned LONGEST) = NULL;
 PMOD_EXPORT int (*ulongest_from_bignum) (unsigned LONGEST *,
 					 struct object *) = NULL;
 
+PMOD_EXPORT MP_INT *(*mpz_from_bignum)(struct object *, int) = NULL;
+PMOD_EXPORT void (*push_bignum)(MP_INT *) = NULL;
+
 PMOD_EXPORT void hook_in_gmp_funcs (
 #ifdef INT64
   void (*push_int64_val)(INT64),
@@ -132,7 +137,9 @@ PMOD_EXPORT void hook_in_gmp_funcs (
   void (*reduce_stack_top_bignum_val) (void),
 #endif
   void (*push_ulongest_val) (unsigned LONGEST),
-  int (*ulongest_from_bignum_val) (unsigned LONGEST *, struct object *))
+  int (*ulongest_from_bignum_val) (unsigned LONGEST *, struct object *),
+  MP_INT *(*mpz_from_bignum_val)(struct object *, int),
+  void (*push_bignum_val)(MP_INT *))
 {
   /* Assigning the pointers above directly from the Gmp module doesn't
    * work in some cases, e.g. NT. */
@@ -143,4 +150,6 @@ PMOD_EXPORT void hook_in_gmp_funcs (
 #endif
   push_ulongest = push_ulongest_val;
   ulongest_from_bignum = ulongest_from_bignum_val;
+  mpz_from_bignum = mpz_from_bignum_val;
+  push_bignum = push_bignum_val;
 }
diff --git a/src/bignum.h b/src/bignum.h
index 30d7b007f5a6f92b138ef9c46da1c09e69f4cd08..55d6f3fe65812d2506c61340ef34549bcf8ec357 100644
--- a/src/bignum.h
+++ b/src/bignum.h
@@ -265,6 +265,13 @@ PMOD_EXPORT extern void (*reduce_stack_top_bignum) (void);
 PMOD_EXPORT extern void (*push_ulongest) (unsigned LONGEST i);
 PMOD_EXPORT extern int (*ulongest_from_bignum) (unsigned LONGEST *i,
 						struct object *bignum);
+#ifndef __MPN
+#define MP_INT void
+#endif
+
+PMOD_EXPORT extern MP_INT *(*mpz_from_bignum)(struct object *, int);
+PMOD_EXPORT extern void (*push_bignum)(MP_INT *);
+
 PMOD_EXPORT void hook_in_gmp_funcs (
 #ifdef INT64
   void (*push_int64_val)(INT64),
@@ -272,7 +279,9 @@ PMOD_EXPORT void hook_in_gmp_funcs (
   void (*reduce_stack_top_bignum_val) (void),
 #endif
   void (*push_ulongest_val) (unsigned LONGEST),
-  int (*ulongest_from_bignum_val) (unsigned LONGEST *, struct object *));
+  int (*ulongest_from_bignum_val) (unsigned LONGEST *, struct object *),
+  MP_INT *(*mpz_from_bignum_val)(struct object *, int),
+  void (*push_bignum_val)(MP_INT *));
 /* Prototypes end here */
 
 /* Less confusing name, considering that push_int64 pushes a 32 bit
diff --git a/src/modules/Gmp/mpf.cmod b/src/modules/Gmp/mpf.cmod
index dd859974ece32aaec4c0f3449bcf0fce43893960..47344b26186acfcb06a579cbab730c2811725a4c 100644
--- a/src/modules/Gmp/mpf.cmod
+++ b/src/modules/Gmp/mpf.cmod
@@ -17,6 +17,8 @@
 
 #if defined(USE_GMP) || defined(USE_GMP2)
 
+#include "my_gmp.h"
+
 #include "interpret.h"
 #include "svalue.h"
 #include "stralloc.h"
@@ -34,8 +36,6 @@
 #include "mapping.h"
 #include "gc.h"
 
-#include "my_gmp.h"
-
 #include <limits.h>
 #include <math.h>
 
diff --git a/src/modules/Gmp/mpq.cmod b/src/modules/Gmp/mpq.cmod
index e936784b115363432a30fa023e845d0020d18820..b6c50515daa80baaa8a3bee0545e371c98df494c 100644
--- a/src/modules/Gmp/mpq.cmod
+++ b/src/modules/Gmp/mpq.cmod
@@ -17,6 +17,8 @@
 
 #if defined(USE_GMP) || defined(USE_GMP2)
 
+#include "my_gmp.h"
+
 #include "interpret.h"
 #include "svalue.h"
 #include "stralloc.h"
@@ -34,8 +36,6 @@
 #include "mapping.h"
 #include "gc.h"
 
-#include "my_gmp.h"
-
 #include <limits.h>
 #include <math.h>
 
diff --git a/src/modules/Gmp/mpz_glue.c b/src/modules/Gmp/mpz_glue.c
index 2b31f6854ba9c37e5872a33d388a1841f5c35cba..c4f7b16c2cb2049fcf2b8ac9f2f71823c60b5962 100644
--- a/src/modules/Gmp/mpz_glue.c
+++ b/src/modules/Gmp/mpz_glue.c
@@ -22,6 +22,8 @@
 
 #if defined(USE_GMP) || defined(USE_GMP2)
 
+#include "my_gmp.h"
+
 #include "interpret.h"
 #include "svalue.h"
 #include "stralloc.h"
@@ -38,8 +40,6 @@
 #include "operators.h"
 #include "gc.h"
 
-#include "my_gmp.h"
-
 #include <limits.h>
 
 #define sp Pike_sp
@@ -65,6 +65,18 @@ struct program *bignum_program = NULL;
 
 static mpz_t mpz_int_type_min;
 
+static MP_INT *gmp_mpz_from_bignum(struct object *o, int inherit)
+{
+  if (!IS_MPZ_OBJ(o)) return NULL;
+  return OBTOMPZ(o);
+}
+
+static void gmp_push_bignum(MP_INT *mpz)
+{
+  push_object(fast_clone_object(bignum_program));
+  mpz_set(OBTOMPZ(Pike_sp[-1].u.object), mpz);
+}
+
 void mpzmod_reduce(struct object *o)
 {
   MP_INT *mpz = OBTOMPZ (o);
@@ -2254,7 +2266,7 @@ PIKE_MODULE_EXIT
 #ifdef INT64
       NULL, NULL, NULL,
 #endif
-      NULL, NULL);
+      NULL, NULL, NULL, NULL);
 #endif
 }
 
@@ -2444,6 +2456,7 @@ PIKE_MODULE_INIT
   MPZ_DEFS();
 
   id=add_program_constant("bignum", bignum_program=end_program(), 0);
+  bignum_program->id = PROG_GMP_BIGNUM_ID;
   bignum_program->flags |=
     PROGRAM_NO_WEAK_FREE |
     PROGRAM_NO_EXPLICIT_DESTRUCT |
@@ -2473,7 +2486,8 @@ PIKE_MODULE_INIT
       gmp_push_int64, gmp_int64_from_bignum,
       gmp_reduce_stack_top_bignum,
 #endif
-      gmp_push_ulongest, gmp_ulongest_from_bignum);
+      gmp_push_ulongest, gmp_ulongest_from_bignum,
+      gmp_mpz_from_bignum, gmp_push_bignum);
 
 #if 0
   /* magic /Hubbe
diff --git a/src/modules/Gmp/my_gmp.h b/src/modules/Gmp/my_gmp.h
index ca3b631670f83234b0404a42b5720680bff72ffd..de9634dd80f8c763f8f7b0c1d6875e611fd585eb 100644
--- a/src/modules/Gmp/my_gmp.h
+++ b/src/modules/Gmp/my_gmp.h
@@ -124,6 +124,7 @@ extern struct program *bignum_program;
 #define OBTOMPF(o) ((MP_FLT *)(o->storage))
 
 #define IS_MPZ_OBJ(O) ((O)->prog == bignum_program || (O)->prog == mpzmod_program)
+#define IS_MPZ_OBJ2(O, INH) ((O->prog) && (((O)->inherits[INH].prog->id & ~1) == PROG_GMP_MPZ_ID))
 
 #ifndef GMP_NUMB_BITS
 #define GMP_NUMB_BITS (SIZEOF_MP_LIMB_T * CHAR_BIT)
diff --git a/src/post_modules/Nettle/hogweed.cmod b/src/post_modules/Nettle/hogweed.cmod
index 887eb1e1a8ea9316d601447a5dc9bd16b47781e3..c926d5a482699763cd869f504c13f74d6c07412a 100644
--- a/src/post_modules/Nettle/hogweed.cmod
+++ b/src/post_modules/Nettle/hogweed.cmod
@@ -5,7 +5,6 @@
 */
 
 #include "global.h"
-#include "bignum.h"
 #include "builtin_functions.h"
 #include "interpret.h"
 #include "module.h"
@@ -21,6 +20,8 @@ DECLARATIONS
 #include <nettle/rsa.h>
 #include <gmp.h>
 
+#include "bignum.h"
+
 void random_func_wrapper(void *f, unsigned int num, uint8_t *out)
 {
   push_int(num);
diff --git a/src/program_id.h b/src/program_id.h
index d277bb0940d9536bfdbff0ae607237903b259824..cf2b2dda6fac660beb7287e41ad521a05ba5bdd1 100644
--- a/src/program_id.h
+++ b/src/program_id.h
@@ -94,6 +94,9 @@
 #define     PROG_GMP_MPZ_ID                                         040
 #define tObjImpl_GMP_MPZ                      "\003\000\000\000\000\040"
 #define   tObjIs_GMP_MPZ                      "\003\001\000\000\000\040"
+#define     PROG_GMP_BIGNUM_ID                                      041
+#define tObjImpl_GMP_BIGNUM                   "\003\000\000\000\000\041"
+#define   tObjIs_GMP_BIGNUM                   "\003\001\000\000\000\041"
 
 /* Classes in builtin.cmod. */
 #define     PROG_SINGLE_STRING_REPLACE_ID			    050