--- openssl-0.9.8g/engines/e_gmp.c.ORIG	2008-04-01 15:33:06.000000000 +0200
+++ openssl-0.9.8g/engines/e_gmp.c	2008-04-02 13:27:21.000000000 +0200
@@ -249,31 +249,65 @@
 		}
 
 	return to_return;
 	}
 
-/* HACK - use text I/O functions in openssl and GMP to handle conversions. This
- * is vile. */
+
+/* Most often limb sizes will be the same. If not, we use hex conversion
+ * which is neat, but extremely inefficient. */
 static int bn2gmp(const BIGNUM *bn, mpz_t g)
 	{
-	int toret;
-	char *tmpchar = BN_bn2hex(bn);
-	if(!tmpchar) return 0;
-	toret = (mpz_set_str(g, tmpchar, 16) == 0 ? 1 : 0);
-	OPENSSL_free(tmpchar);
-	return toret;
+	if(sizeof(bn->d[0]) * 8 == GMP_NUMB_BITS && BN_BITS2 == GMP_NUMB_BITS)  /* The common case */
+		{
+		int i;
+		if(!_mpz_realloc (g, bn->top))
+			return 0;
+		for (i = 0; i < bn->top; i++)
+			g->_mp_d[i] = bn->d[i];
+		g->_mp_size = g->_mp_alloc = bn->top;
+		if(bn->neg)
+			g->_mp_size = -g->_mp_size;
+		return 1;
+		}
+	else
+		{
+		int toret;
+		char *tmpchar = BN_bn2hex(bn);
+		if(!tmpchar) return 0;
+		toret = (mpz_set_str(g, tmpchar, 16) == 0 ? 1 : 0);
+		OPENSSL_free(tmpchar);
+		return toret;
+		}
 	}
 
 static int gmp2bn(mpz_t g, BIGNUM *bn)
 	{
-	int toret;
-	char *tmpchar = OPENSSL_malloc(mpz_sizeinbase(g, 16) + 10);
-	if(!tmpchar) return 0;
-	mpz_get_str(tmpchar, 16, g);
-	toret = BN_hex2bn(&bn, tmpchar);
-	OPENSSL_free(tmpchar);
-	return toret;
+	int i, s;
+	if(sizeof(bn->d[0]) * 8 == GMP_NUMB_BITS && BN_BITS2 == GMP_NUMB_BITS)  /* The common case */
+		{
+		s = g->_mp_size >= 0 ? g->_mp_size : -g->_mp_size;
+		BN_zero(bn);
+		if(bn_expand2 (bn, s) == NULL)
+			return 0;
+		bn->top = s;
+		for(i = 0; i < s; i++)
+			bn->d[i] = g->_mp_d[i];
+		bn_correct_top(bn);
+		bn_check_top(bn);
+		bn->neg = g->_mp_size >= 0 ? 0 : 1;
+		return 1;
+		}
+	else
+		{
+		int toret;
+		char *tmpchar = OPENSSL_malloc(mpz_sizeinbase(g, 16) + 10);
+		if(!tmpchar) return 0;
+		mpz_get_str(tmpchar, 16, g);
+		toret = BN_hex2bn(&bn, tmpchar);
+		OPENSSL_free(tmpchar);
+		return toret;
+		}
 	}
 
 #ifndef OPENSSL_NO_RSA 
 typedef struct st_e_gmp_rsa_ctx
 	{
