changeset 640:76097ec1a29a dropbear-tfm

- Bring in original tomsfastmath patch against 0.52 from Peter Turczak in 2008
author Matt Johnston <matt@ucc.asn.au>
date Mon, 21 Nov 2011 19:19:57 +0800
parents ce104c8b0be1
children 2b1bb792cd4d
files bignum.c bignum.h buffer.c buffer.h cli-kex.c common-kex.c configure.in dbutil.h dropbearkey.c dss.c dss.h gendss.c genrsa.c includes.h kex.h keyimport.c options.h random.c random.h rsa.c rsa.h session.h svr-kex.c
diffstat 23 files changed, 460 insertions(+), 475 deletions(-) [+]
line wrap: on
line diff
--- a/bignum.c	Wed Nov 12 13:13:00 2008 +0000
+++ b/bignum.c	Mon Nov 21 19:19:57 2011 +0800
@@ -22,52 +22,61 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE. */
 
-/* Contains helper functions for mp_int handling */
+/* Contains helper functions for fp_int handling */
 
 #include "includes.h"
 #include "dbutil.h"
 
-/* wrapper for mp_init, failing fatally on errors (memory allocation) */
-void m_mp_init(mp_int *mp) {
+/* wrapper for fp_init, failing fatally on errors (memory allocation) */
+void m_fp_init(fp_int *fp) {
 
-	if (mp_init(mp) != MP_OKAY) {
-		dropbear_exit("mem alloc error");
-	}
+	fp_init(fp);
 }
 
-/* simplified duplication of bn_mp_multi's mp_init_multi, but die fatally
+/* simplified duplication of bn_fp_multi's fp_init_multi, but die fatally
  * on error */
-void m_mp_init_multi(mp_int *mp, ...) 
+void m_fp_init_multi(fp_int *fp, ...) 
 {
-    mp_int* cur_arg = mp;
+    fp_int* cur_arg = fp;
     va_list args;
 
-    va_start(args, mp);        /* init args to next argument from caller */
+    va_start(args, fp);        /* init args to next argument from caller */
     while (cur_arg != NULL) {
-        if (mp_init(cur_arg) != MP_OKAY) {
-			dropbear_exit("mem alloc error");
-        }
-        cur_arg = va_arg(args, mp_int*);
+        fp_init(cur_arg);
+        cur_arg = va_arg(args, fp_int*);
     }
     va_end(args);
 }
 
-void bytes_to_mp(mp_int *mp, const unsigned char* bytes, unsigned int len) {
+/* simplified duplication of bn_fp_multi's fp_init_multi, but die fatally
+ * on error */
+void m_fp_zero_multi(fp_int *fp, ...) 
+{
+    fp_int* cur_arg = fp;
+    va_list args;
 
-	if (mp_read_unsigned_bin(mp, (unsigned char*)bytes, len) != MP_OKAY) {
-		dropbear_exit("mem alloc error");
-	}
+    va_start(args, fp);        /* init args to next argument from caller */
+    while (cur_arg != NULL) {
+        fp_zero(cur_arg);
+        cur_arg = va_arg(args, fp_int*);
+    }
+    va_end(args);
 }
 
-/* hash the ssh representation of the mp_int mp */
-void sha1_process_mp(hash_state *hs, mp_int *mp) {
+void bytes_to_fp(fp_int *fp, const unsigned char* bytes, unsigned int len) {
+
+	fp_read_unsigned_bin(fp, (unsigned char*)bytes, len);
+}
+
+/* hash the ssh representation of the fp_int fp */
+void sha1_process_fp(hash_state *hs, fp_int *fp) {
 
 	int i;
 	buffer * buf;
 
 	buf = buf_new(512 + 20); /* max buffer is a 4096 bit key, 
 								plus header + some leeway*/
-	buf_putmpint(buf, mp);
+	buf_putfpint(buf, fp);
 	i = buf->pos;
 	buf_setpos(buf, 0);
 	sha1_process(hs, buf_getptr(buf, i), i);
--- a/bignum.h	Wed Nov 12 13:13:00 2008 +0000
+++ b/bignum.h	Mon Nov 21 19:19:57 2011 +0800
@@ -27,9 +27,10 @@
 
 #include "includes.h"
 
-void m_mp_init(mp_int *mp);
-void m_mp_init_multi(mp_int *mp, ...);
-void bytes_to_mp(mp_int *mp, const unsigned char* bytes, unsigned int len);
-void sha1_process_mp(hash_state *hs, mp_int *mp);
+void m_fp_init(fp_int *fp);
+void m_fp_init_multi(fp_int *fp, ...);
+void m_fp_zero_multi(fp_int *fp, ...);
+void bytes_to_fp(fp_int *fp, const unsigned char* bytes, unsigned int len);
+void sha1_process_fp(hash_state *hs, fp_int *fp);
 
 #endif /* _BIGNUM_H_ */
--- a/buffer.c	Wed Nov 12 13:13:00 2008 +0000
+++ b/buffer.c	Mon Nov 21 19:19:57 2011 +0800
@@ -37,6 +37,8 @@
 /* avoid excessively large numbers, > ~8192 bits */
 #define BUF_MAX_MPINT (8240 / 8)
 
+#define BUF_MAX_FPINT (FP_MAX_SIZE / 8)
+
 /* Create (malloc) a new buffer of size */
 buffer* buf_new(unsigned int size) {
 
@@ -265,24 +267,24 @@
 
 /* for our purposes we only need positive (or 0) numbers, so will
  * fail if we get negative numbers */
-void buf_putmpint(buffer* buf, mp_int * mp) {
+void buf_putfpint(buffer* buf, fp_int * fp) {
 
 	unsigned int len, pad = 0;
-	TRACE(("enter buf_putmpint"))
+	TRACE(("enter buf_putfpint"))
 
-	dropbear_assert(mp != NULL);
+	dropbear_assert(fp != NULL);
 
-	if (SIGN(mp) == MP_NEG) {
+	if (SIGN(fp) == FP_NEG) {
 		dropbear_exit("negative bignum");
 	}
 
 	/* zero check */
-	if (USED(mp) == 1 && DIGIT(mp, 0) == 0) {
+	if (USED(fp) == 1 && DIGIT(fp, 0) == 0) {
 		len = 0;
 	} else {
-		/* SSH spec requires padding for mpints with the MSB set, this code
-		 * implements it */
-		len = mp_count_bits(mp);
+		/* SSH spec requires padding for fpints with the MSB set, this code
+		 * ifplements it */
+		len = fp_count_bits(fp);
 		/* if the top bit of MSB is set, we need to pad */
 		pad = (len%8 == 0) ? 1 : 0;
 		len = len / 8 + 1; /* don't worry about rounding, we need it for
@@ -298,29 +300,29 @@
 		if (pad) {
 			buf_putbyte(buf, 0x00);
 		}
-		if (mp_to_unsigned_bin(mp, buf_getwriteptr(buf, len-pad)) != MP_OKAY) {
-			dropbear_exit("mpint error");
-		}
+ 		/* Should always succseed */ 
+		fp_to_unsigned_bin(fp, buf_getwriteptr(buf, len-pad)) ;
+
 		buf_incrwritepos(buf, len-pad);
 	}
 
-	TRACE(("leave buf_putmpint"))
+	TRACE(("leave buf_putfpint"))
 }
 
-/* Retrieve an mp_int from the buffer.
+/* Retrieve an fp_int from the buffer.
  * Will fail for -ve since they shouldn't be required here.
  * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
-int buf_getmpint(buffer* buf, mp_int* mp) {
+int buf_getfpint(buffer* buf, fp_int* fp) {
 
 	unsigned int len;
 	len = buf_getint(buf);
 	
 	if (len == 0) {
-		mp_zero(mp);
+		fp_zero(fp);
 		return DROPBEAR_SUCCESS;
 	}
 
-	if (len > BUF_MAX_MPINT) {
+	if (len > BUF_MAX_FPINT) {
 		return DROPBEAR_FAILURE;
 	}
 
@@ -329,9 +331,8 @@
 		return DROPBEAR_FAILURE;
 	}
 
-	if (mp_read_unsigned_bin(mp, buf_getptr(buf, len), len) != MP_OKAY) {
-		return DROPBEAR_FAILURE;
-	}
+	/** Should always succseed */
+	fp_read_unsigned_bin(fp, buf_getptr(buf, len), len);
 
 	buf_incrpos(buf, len);
 	return DROPBEAR_SUCCESS;
--- a/buffer.h	Wed Nov 12 13:13:00 2008 +0000
+++ b/buffer.h	Mon Nov 21 19:19:57 2011 +0800
@@ -59,8 +59,8 @@
 void buf_putint(buffer* buf, unsigned int val);
 void buf_putstring(buffer* buf, const unsigned char* str, unsigned int len);
 void buf_putbytes(buffer *buf, const unsigned char *bytes, unsigned int len);
-void buf_putmpint(buffer* buf, mp_int * mp);
-int buf_getmpint(buffer* buf, mp_int* mp);
+void buf_putfpint(buffer* buf, fp_int * fp);
+int buf_getfpint(buffer* buf, fp_int* fp);
 unsigned int buf_getint(buffer* buf);
 
 #endif /* _BUFFER_H_ */
--- a/cli-kex.c	Wed Nov 12 13:13:00 2008 +0000
+++ b/cli-kex.c	Mon Nov 21 19:19:57 2011 +0800
@@ -43,15 +43,15 @@
 
 void send_msg_kexdh_init() {
 
-	cli_ses.dh_e = (mp_int*)m_malloc(sizeof(mp_int));
-	cli_ses.dh_x = (mp_int*)m_malloc(sizeof(mp_int));
-	m_mp_init_multi(cli_ses.dh_e, cli_ses.dh_x, NULL);
+	cli_ses.dh_e = (fp_int*)m_malloc(sizeof(fp_int));
+	cli_ses.dh_x = (fp_int*)m_malloc(sizeof(fp_int));
+	m_fp_init_multi(cli_ses.dh_e, cli_ses.dh_x, NULL);
 
 	gen_kexdh_vals(cli_ses.dh_e, cli_ses.dh_x);
 
 	CHECKCLEARTOWRITE();
 	buf_putbyte(ses.writepayload, SSH_MSG_KEXDH_INIT);
-	buf_putmpint(ses.writepayload, cli_ses.dh_e);
+	buf_putfpint(ses.writepayload, cli_ses.dh_e);
 	encrypt_packet();
 	ses.requirenext = SSH_MSG_KEXDH_REPLY;
 }
@@ -59,7 +59,7 @@
 /* Handle a diffie-hellman key exchange reply. */
 void recv_msg_kexdh_reply() {
 
-	DEF_MP_INT(dh_f);
+	DEF_FP_INT(dh_f);
 	sign_key *hostkey = NULL;
 	unsigned int type, keybloblen;
 	unsigned char* keyblob = NULL;
@@ -70,7 +70,7 @@
 	if (cli_ses.kex_state != KEXDH_INIT_SENT) {
 		dropbear_exit("Received out-of-order kexdhreply");
 	}
-	m_mp_init(&dh_f);
+	m_fp_init(&dh_f);
 	type = ses.newkeys->algo_hostkey;
 	TRACE(("type is %d", type))
 
@@ -88,14 +88,15 @@
 		dropbear_exit("Bad KEX packet");
 	}
 
-	if (buf_getmpint(ses.payload, &dh_f) != DROPBEAR_SUCCESS) {
-		TRACE(("failed getting mpint"))
+	if (buf_getfpint(ses.payload, &dh_f) != DROPBEAR_SUCCESS) {
+		TRACE(("failed getting fpint"))
 		dropbear_exit("Bad KEX packet");
 	}
 
 	kexdh_comb_key(cli_ses.dh_e, cli_ses.dh_x, &dh_f, hostkey);
-	mp_clear(&dh_f);
-	mp_clear_multi(cli_ses.dh_e, cli_ses.dh_x, NULL);
+	fp_zero(&dh_f);
+	fp_zero(cli_ses.dh_e);
+	fp_zero(cli_ses.dh_x);
 	m_free(cli_ses.dh_e);
 	m_free(cli_ses.dh_x);
 
--- a/common-kex.c	Wed Nov 12 13:13:00 2008 +0000
+++ b/common-kex.c	Mon Nov 21 19:19:57 2011 +0800
@@ -261,8 +261,8 @@
 	/* the dh_K and hash are the start of all hashes, we make use of that */
 
 	sha1_init(&hs);
-	sha1_process_mp(&hs, ses.dh_K);
-	mp_clear(ses.dh_K);
+	sha1_process_fp(&hs, ses.dh_K);
+	fp_zero(ses.dh_K);
 	m_free(ses.dh_K);
 	sha1_process(&hs, ses.hash, SHA1_HASH_SIZE);
 	m_burn(ses.hash, SHA1_HASH_SIZE);
@@ -482,72 +482,67 @@
 /* Initialises and generate one side of the diffie-hellman key exchange values.
  * See the ietf-secsh-transport draft, section 6, for details */
 /* dh_pub and dh_priv MUST be already initialised */
-void gen_kexdh_vals(mp_int *dh_pub, mp_int *dh_priv) {
+void gen_kexdh_vals(fp_int *dh_pub, fp_int *dh_priv) {
 
-	DEF_MP_INT(dh_p);
-	DEF_MP_INT(dh_q);
-	DEF_MP_INT(dh_g);
+	DEF_FP_INT(dh_p);
+	DEF_FP_INT(dh_q);
+	DEF_FP_INT(dh_g);
 
 	TRACE(("enter send_msg_kexdh_reply"))
 	
-	m_mp_init_multi(&dh_g, &dh_p, &dh_q, NULL);
+	m_fp_init_multi(&dh_g, &dh_p, &dh_q, NULL);
 
 	/* read the prime and generator*/
-	bytes_to_mp(&dh_p, (unsigned char*)dh_p_val, DH_P_LEN);
+	bytes_to_fp(&dh_p, (unsigned char*)dh_p_val, DH_P_LEN);
 	
-	if (mp_set_int(&dh_g, DH_G_VAL) != MP_OKAY) {
-		dropbear_exit("Diffie-Hellman error");
-	}
+	fp_set(&dh_g, DH_G_VAL);
 
 	/* calculate q = (p-1)/2 */
 	/* dh_priv is just a temp var here */
-	if (mp_sub_d(&dh_p, 1, dh_priv) != MP_OKAY) { 
-		dropbear_exit("Diffie-Hellman error");
-	}
-	if (mp_div_2(dh_priv, &dh_q) != MP_OKAY) {
-		dropbear_exit("Diffie-Hellman error");
-	}
+	fp_sub_d(&dh_p, 1, dh_priv);
+
+	fp_div_2(dh_priv, &dh_q);
 
 	/* Generate a private portion 0 < dh_priv < dh_q */
-	gen_random_mpint(&dh_q, dh_priv);
+	gen_random_fpint(&dh_q, dh_priv);
 
 	/* f = g^y mod p */
-	if (mp_exptmod(&dh_g, dh_priv, &dh_p, dh_pub) != MP_OKAY) {
+	if (fp_exptmod(&dh_g, dh_priv, &dh_p, dh_pub) != FP_OKAY) {
 		dropbear_exit("Diffie-Hellman error");
 	}
-	mp_clear_multi(&dh_g, &dh_p, &dh_q, NULL);
+	m_fp_zero_multi(&dh_g, &dh_p, &dh_q, NULL);
 }
 
 /* This function is fairly common between client/server, with some substitution
  * of dh_e/dh_f etc. Hence these arguments:
  * dh_pub_us is 'e' for the client, 'f' for the server. dh_pub_them is 
  * vice-versa. dh_priv is the x/y value corresponding to dh_pub_us */
-void kexdh_comb_key(mp_int *dh_pub_us, mp_int *dh_priv, mp_int *dh_pub_them,
+void kexdh_comb_key(fp_int *dh_pub_us, fp_int *dh_priv, fp_int *dh_pub_them,
 		sign_key *hostkey) {
 
-	mp_int dh_p;
-	mp_int *dh_e = NULL, *dh_f = NULL;
+	fp_int dh_p;
+	fp_int *dh_e = NULL, *dh_f = NULL;
 	hash_state hs;
 
 	/* read the prime and generator*/
-	m_mp_init(&dh_p);
-	bytes_to_mp(&dh_p, dh_p_val, DH_P_LEN);
+	m_fp_init(&dh_p);
+	bytes_to_fp(&dh_p, dh_p_val, DH_P_LEN);
 
 	/* Check that dh_pub_them (dh_e or dh_f) is in the range [1, p-1] */
-	if (mp_cmp(dh_pub_them, &dh_p) != MP_LT 
-			|| mp_cmp_d(dh_pub_them, 0) != MP_GT) {
+	if (fp_cmp(dh_pub_them, &dh_p) != FP_LT 
+			|| fp_cmp_d(dh_pub_them, 0) != FP_GT) {
 		dropbear_exit("Diffie-Hellman error");
 	}
 	
 	/* K = e^y mod p = f^x mod p */
-	ses.dh_K = (mp_int*)m_malloc(sizeof(mp_int));
-	m_mp_init(ses.dh_K);
-	if (mp_exptmod(dh_pub_them, dh_priv, &dh_p, ses.dh_K) != MP_OKAY) {
+	ses.dh_K = (fp_int*)m_malloc(sizeof(fp_int));
+	m_fp_init(ses.dh_K);
+	if (fp_exptmod(dh_pub_them, dh_priv, &dh_p, ses.dh_K) != FP_OKAY) {
 		dropbear_exit("Diffie-Hellman error");
 	}
 
 	/* clear no longer needed vars */
-	mp_clear_multi(&dh_p, NULL);
+	m_fp_zero_multi(&dh_p, NULL);
 
 	/* From here on, the code needs to work with the _same_ vars on each side,
 	 * not vice-versaing for client/server */
@@ -563,11 +558,11 @@
 	/* K_S, the host key */
 	buf_put_pub_key(ses.kexhashbuf, hostkey, ses.newkeys->algo_hostkey);
 	/* e, exchange value sent by the client */
-	buf_putmpint(ses.kexhashbuf, dh_e);
+	buf_putfpint(ses.kexhashbuf, dh_e);
 	/* f, exchange value sent by the server */
-	buf_putmpint(ses.kexhashbuf, dh_f);
+	buf_putfpint(ses.kexhashbuf, dh_f);
 	/* K, the shared secret */
-	buf_putmpint(ses.kexhashbuf, ses.dh_K);
+	buf_putfpint(ses.kexhashbuf, ses.dh_K);
 
 	/* calculate the hash H to sign */
 	sha1_init(&hs);
@@ -597,8 +592,8 @@
 	algo_type * s2c_hash_algo = NULL;
 	algo_type * c2s_cipher_algo = NULL;
 	algo_type * s2c_cipher_algo = NULL;
-	algo_type * c2s_comp_algo = NULL;
-	algo_type * s2c_comp_algo = NULL;
+	algo_type * c2s_cofp_algo = NULL;
+	algo_type * s2c_cofp_algo = NULL;
 	/* the generic one */
 	algo_type * algo = NULL;
 
@@ -666,20 +661,20 @@
 	TRACE(("hash s2c is  %s", s2c_hash_algo->name))
 
 	/* compression_algorithms_client_to_server */
-	c2s_comp_algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess);
-	if (c2s_comp_algo == NULL) {
+	c2s_cofp_algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess);
+	if (c2s_cofp_algo == NULL) {
 		erralgo = "comp c->s";
 		goto error;
 	}
-	TRACE(("hash c2s is  %s", c2s_comp_algo->name))
+	TRACE(("hash c2s is  %s", c2s_cofp_algo->name))
 
 	/* compression_algorithms_server_to_client */
-	s2c_comp_algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess);
-	if (s2c_comp_algo == NULL) {
+	s2c_cofp_algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess);
+	if (s2c_cofp_algo == NULL) {
 		erralgo = "comp s->c";
 		goto error;
 	}
-	TRACE(("hash s2c is  %s", s2c_comp_algo->name))
+	TRACE(("hash s2c is  %s", s2c_cofp_algo->name))
 
 	/* languages_client_to_server */
 	buf_eatstring(ses.payload);
@@ -710,8 +705,8 @@
 			(struct dropbear_hash*)s2c_hash_algo->data;
 		ses.newkeys->trans_algo_mac = 
 			(struct dropbear_hash*)c2s_hash_algo->data;
-		ses.newkeys->recv_algo_comp = s2c_comp_algo->val;
-		ses.newkeys->trans_algo_comp = c2s_comp_algo->val;
+		ses.newkeys->recv_algo_comp = s2c_cofp_algo->val;
+		ses.newkeys->trans_algo_comp = c2s_cofp_algo->val;
 	} else {
 		/* SERVER */
 		ses.newkeys->recv_algo_crypt = 
@@ -726,8 +721,8 @@
 			(struct dropbear_hash*)c2s_hash_algo->data;
 		ses.newkeys->trans_algo_mac = 
 			(struct dropbear_hash*)s2c_hash_algo->data;
-		ses.newkeys->recv_algo_comp = c2s_comp_algo->val;
-		ses.newkeys->trans_algo_comp = s2c_comp_algo->val;
+		ses.newkeys->recv_algo_comp = c2s_cofp_algo->val;
+		ses.newkeys->trans_algo_comp = s2c_cofp_algo->val;
 	}
 
 	/* reserved for future extensions */
--- a/configure.in	Wed Nov 12 13:13:00 2008 +0000
+++ b/configure.in	Mon Nov 21 19:19:57 2011 +0800
@@ -668,6 +668,6 @@
 AC_CONFIG_HEADER(config.h)
 AC_OUTPUT(Makefile)
 AC_OUTPUT(libtomcrypt/Makefile)
-AC_OUTPUT(libtommath/Makefile)
+#AC_OUTPUT(libtommath/Makefile)
 AC_MSG_NOTICE()
 AC_MSG_NOTICE(Now edit options.h to choose features.)
--- a/dbutil.h	Wed Nov 12 13:13:00 2008 +0000
+++ b/dbutil.h	Mon Nov 21 19:19:57 2011 +0800
@@ -69,8 +69,8 @@
 void disallow_core();
 int m_str_to_uint(const char* str, unsigned int *val);
 
-/* Used to force mp_ints to be initialised */
-#define DEF_MP_INT(X) mp_int X = {0, 0, 0, NULL}
+/* Used to force fp_ints to be initialised */
+#define DEF_FP_INT(X) fp_int X = {{},0, 0}
 
 /* Dropbear assertion */
 #define dropbear_assert(X) do { if (!(X)) { fail_assert(#X, __FILE__, __LINE__); } } while (0)
--- a/dropbearkey.c	Wed Nov 12 13:13:00 2008 +0000
+++ b/dropbearkey.c	Mon Nov 21 19:19:57 2011 +0800
@@ -24,24 +24,24 @@
 
 /* The format of the keyfiles is basically a raw dump of the buffer. Data types
  * are specified in the transport draft - string is a 32-bit len then the
- * non-null-terminated string, mp_int is a 32-bit len then the bignum data.
+ * non-null-terminated string, fp_int is a 32-bit len then the bignum data.
  * The actual functions are buf_put_rsa_priv_key() and buf_put_dss_priv_key()
 
  * RSA:
  * string	"ssh-rsa"
- * mp_int	e
- * mp_int	n
- * mp_int	d
- * mp_int	p (newer versions only)
- * mp_int	q (newer versions only) 
+ * fp_int	e
+ * fp_int	n
+ * fp_int	d
+ * fp_int	p (newer versions only)
+ * fp_int	q (newer versions only) 
  *
  * DSS:
  * string	"ssh-dss"
- * mp_int	p
- * mp_int	q
- * mp_int	g
- * mp_int	y
- * mp_int	x
+ * fp_int	p
+ * fp_int	q
+ * fp_int	g
+ * fp_int	y
+ * fp_int	x
  *
  */
 #include "includes.h"
--- a/dss.c	Wed Nov 12 13:13:00 2008 +0000
+++ b/dss.c	Mon Nov 21 19:19:57 2011 +0800
@@ -47,23 +47,26 @@
 
 	TRACE(("enter buf_get_dss_pub_key"))
 	dropbear_assert(key != NULL);
-	key->p = m_malloc(sizeof(mp_int));
-	key->q = m_malloc(sizeof(mp_int));
-	key->g = m_malloc(sizeof(mp_int));
-	key->y = m_malloc(sizeof(mp_int));
-	m_mp_init_multi(key->p, key->q, key->g, key->y, NULL);
+	key->p = m_malloc(sizeof(fp_int));
+	key->q = m_malloc(sizeof(fp_int));
+	key->g = m_malloc(sizeof(fp_int));
+	key->y = m_malloc(sizeof(fp_int));
+	fp_init(key->p);
+	fp_init(key->q);
+	fp_init(key->g);
+	fp_init(key->y);
 	key->x = NULL;
 
 	buf_incrpos(buf, 4+SSH_SIGNKEY_DSS_LEN); /* int + "ssh-dss" */
-	if (buf_getmpint(buf, key->p) == DROPBEAR_FAILURE
-	 || buf_getmpint(buf, key->q) == DROPBEAR_FAILURE
-	 || buf_getmpint(buf, key->g) == DROPBEAR_FAILURE
-	 || buf_getmpint(buf, key->y) == DROPBEAR_FAILURE) {
-		TRACE(("leave buf_get_dss_pub_key: failed reading mpints"))
+	if (buf_getfpint(buf, key->p) == DROPBEAR_FAILURE
+	 || buf_getfpint(buf, key->q) == DROPBEAR_FAILURE
+	 || buf_getfpint(buf, key->g) == DROPBEAR_FAILURE
+	 || buf_getfpint(buf, key->y) == DROPBEAR_FAILURE) {
+		TRACE(("leave buf_get_dss_pub_key: failed reading fpints"))
 		return DROPBEAR_FAILURE;
 	}
 
-	if (mp_count_bits(key->p) < MIN_DSS_KEYLEN) {
+	if (fp_count_bits(key->p) < MIN_DSS_KEYLEN) {
 		dropbear_log(LOG_WARNING, "DSS key too short");
 		TRACE(("leave buf_get_dss_pub_key: short key"))
 		return DROPBEAR_FAILURE;
@@ -87,9 +90,9 @@
 		return DROPBEAR_FAILURE;
 	}
 
-	key->x = m_malloc(sizeof(mp_int));
-	m_mp_init(key->x);
-	ret = buf_getmpint(buf, key->x);
+	key->x = m_malloc(sizeof(fp_int));
+	m_fp_init(key->x);
+	ret = buf_getfpint(buf, key->x);
 	if (ret == DROPBEAR_FAILURE) {
 		m_free(key->x);
 	}
@@ -107,23 +110,23 @@
 		return;
 	}
 	if (key->p) {
-		mp_clear(key->p);
+		fp_zero(key->p);
 		m_free(key->p);
 	}
 	if (key->q) {
-		mp_clear(key->q);
+		fp_zero(key->q);
 		m_free(key->q);
 	}
 	if (key->g) {
-		mp_clear(key->g);
+		fp_zero(key->g);
 		m_free(key->g);
 	}
 	if (key->y) {
-		mp_clear(key->y);
+		fp_zero(key->y);
 		m_free(key->y);
 	}
 	if (key->x) {
-		mp_clear(key->x);
+		fp_zero(key->x);
 		m_free(key->x);
 	}
 	m_free(key);
@@ -133,19 +136,19 @@
 /* put the dss public key into the buffer in the required format:
  *
  * string	"ssh-dss"
- * mpint	p
- * mpint	q
- * mpint	g
- * mpint	y
+ * fpint	p
+ * fpint	q
+ * fpint	g
+ * fpint	y
  */
 void buf_put_dss_pub_key(buffer* buf, dss_key *key) {
 
 	dropbear_assert(key != NULL);
 	buf_putstring(buf, SSH_SIGNKEY_DSS, SSH_SIGNKEY_DSS_LEN);
-	buf_putmpint(buf, key->p);
-	buf_putmpint(buf, key->q);
-	buf_putmpint(buf, key->g);
-	buf_putmpint(buf, key->y);
+	buf_putfpint(buf, key->p);
+	buf_putfpint(buf, key->q);
+	buf_putfpint(buf, key->g);
+	buf_putfpint(buf, key->y);
 
 }
 
@@ -154,7 +157,7 @@
 
 	dropbear_assert(key != NULL);
 	buf_put_dss_pub_key(buf, key);
-	buf_putmpint(buf, key->x);
+	buf_putfpint(buf, key->x);
 
 }
 
@@ -167,17 +170,20 @@
 	unsigned char msghash[SHA1_HASH_SIZE];
 	hash_state hs;
 	int ret = DROPBEAR_FAILURE;
-	DEF_MP_INT(val1);
-	DEF_MP_INT(val2);
-	DEF_MP_INT(val3);
-	DEF_MP_INT(val4);
+	DEF_FP_INT(val1);
+	DEF_FP_INT(val2);
+	DEF_FP_INT(val3);
+	DEF_FP_INT(val4);
 	char * string = NULL;
 	int stringlen;
 
 	TRACE(("enter buf_dss_verify"))
 	dropbear_assert(key != NULL);
 
-	m_mp_init_multi(&val1, &val2, &val3, &val4, NULL);
+	fp_init(&val1);
+	fp_init(&val2);
+	fp_init(&val3);
+	fp_init(&val4);
 
 	/* get blob, check length */
 	string = buf_getstring(buf, &stringlen);
@@ -193,64 +199,64 @@
 	/* create the signature - s' and r' are the received signatures in buf */
 	/* w = (s')-1 mod q */
 	/* let val1 = s' */
-	bytes_to_mp(&val1, &string[SHA1_HASH_SIZE], SHA1_HASH_SIZE);
+	bytes_to_fp(&val1, &string[SHA1_HASH_SIZE], SHA1_HASH_SIZE);
 
-	if (mp_cmp(&val1, key->q) != MP_LT) {
+	if (fp_cmp(&val1, key->q) != FP_LT) {
 		TRACE(("verify failed, s' >= q"))
 		goto out;
 	}
 	/* let val2 = w = (s')^-1 mod q*/
-	if (mp_invmod(&val1, key->q, &val2) != MP_OKAY) {
+	if (fp_invmod(&val1, key->q, &val2) != FP_OKAY) {
 		goto out;
 	}
 
 	/* u1 = ((SHA(M')w) mod q */
 	/* let val1 = SHA(M') = msghash */
-	bytes_to_mp(&val1, msghash, SHA1_HASH_SIZE);
+	bytes_to_fp(&val1, msghash, SHA1_HASH_SIZE);
 
 	/* let val3 = u1 = ((SHA(M')w) mod q */
-	if (mp_mulmod(&val1, &val2, key->q, &val3) != MP_OKAY) {
+	if (fp_mulmod(&val1, &val2, key->q, &val3) != FP_OKAY) {
 		goto out;
 	}
 
 	/* u2 = ((r')w) mod q */
 	/* let val1 = r' */
-	bytes_to_mp(&val1, &string[0], SHA1_HASH_SIZE);
-	if (mp_cmp(&val1, key->q) != MP_LT) {
+	bytes_to_fp(&val1, &string[0], SHA1_HASH_SIZE);
+	if (fp_cmp(&val1, key->q) != FP_LT) {
 		TRACE(("verify failed, r' >= q"))
 		goto out;
 	}
 	/* let val4 = u2 = ((r')w) mod q */
-	if (mp_mulmod(&val1, &val2, key->q, &val4) != MP_OKAY) {
+	if (fp_mulmod(&val1, &val2, key->q, &val4) != FP_OKAY) {
 		goto out;
 	}
 
 	/* v = (((g)^u1 (y)^u2) mod p) mod q */
 	/* val2 = g^u1 mod p */
-	if (mp_exptmod(key->g, &val3, key->p, &val2) != MP_OKAY) {
+	if (fp_exptmod(key->g, &val3, key->p, &val2) != FP_OKAY) {
 		goto out;
 	}
 	/* val3 = y^u2 mod p */
-	if (mp_exptmod(key->y, &val4, key->p, &val3) != MP_OKAY) {
+	if (fp_exptmod(key->y, &val4, key->p, &val3) != FP_OKAY) {
 		goto out;
 	}
 	/* val4 = ((g)^u1 (y)^u2) mod p */
-	if (mp_mulmod(&val2, &val3, key->p, &val4) != MP_OKAY) {
+	if (fp_mulmod(&val2, &val3, key->p, &val4) != FP_OKAY) {
 		goto out;
 	}
 	/* val2 = v = (((g)^u1 (y)^u2) mod p) mod q */
-	if (mp_mod(&val4, key->q, &val2) != MP_OKAY) {
+	if (fp_mod(&val4, key->q, &val2) != FP_OKAY) {
 		goto out;
 	}
 	
 	/* check whether signatures verify */
-	if (mp_cmp(&val2, &val1) == MP_EQ) {
+	if (fp_cmp(&val2, &val1) == FP_EQ) {
 		/* good sig */
 		ret = DROPBEAR_SUCCESS;
 	}
 
 out:
-	mp_clear_multi(&val1, &val2, &val3, &val4, NULL);
+	m_fp_zero_multi(&val1, &val2, &val3, &val4, NULL);
 	m_free(string);
 
 	return ret;
@@ -262,16 +268,14 @@
 /* convert an unsigned mp into an array of bytes, malloced.
  * This array must be freed after use, len contains the length of the array,
  * if len != NULL */
-static unsigned char* mptobytes(mp_int *mp, int *len) {
+static unsigned char* fptobytes(fp_int *mp, int *len) {
 	
 	unsigned char* ret;
 	int size;
 
-	size = mp_unsigned_bin_size(mp);
+	size = fp_unsigned_bin_size(mp);
 	ret = m_malloc(size);
-	if (mp_to_unsigned_bin(mp, ret) != MP_OKAY) {
-		dropbear_exit("mem alloc error");
-	}
+	fp_to_unsigned_bin(mp, ret);
 	if (len != NULL) {
 		*len = size;
 	}
@@ -302,14 +306,14 @@
 	unsigned char privkeyhash[SHA512_HASH_SIZE];
 	unsigned char *privkeytmp;
 	unsigned char proto_k[SHA512_HASH_SIZE];
-	DEF_MP_INT(dss_protok);
+	DEF_FP_INT(dss_protok);
 #endif
-	DEF_MP_INT(dss_k);
-	DEF_MP_INT(dss_m);
-	DEF_MP_INT(dss_temp1);
-	DEF_MP_INT(dss_temp2);
-	DEF_MP_INT(dss_r);
-	DEF_MP_INT(dss_s);
+	DEF_FP_INT(dss_k);
+	DEF_FP_INT(dss_m);
+	DEF_FP_INT(dss_temp1);
+	DEF_FP_INT(dss_temp2);
+	DEF_FP_INT(dss_r);
+	DEF_FP_INT(dss_s);
 	hash_state hs;
 	
 	TRACE(("enter buf_put_dss_sign"))
@@ -320,11 +324,11 @@
 	sha1_process(&hs, data, len);
 	sha1_done(&hs, msghash);
 
-	m_mp_init_multi(&dss_k, &dss_temp1, &dss_temp2, &dss_r, &dss_s,
+	m_fp_init_multi(&dss_k, &dss_temp1, &dss_temp2, &dss_r, &dss_s,
 			&dss_m, NULL);
 #ifdef DSS_PROTOK	
 	/* hash the privkey */
-	privkeytmp = mptobytes(key->x, &i);
+	privkeytmp = fptobytes(key->x, &i);
 	sha512_init(&hs);
 	sha512_process(&hs, "the quick brown fox jumped over the lazy dog", 44);
 	sha512_process(&hs, privkeytmp, i);
@@ -339,78 +343,72 @@
 	sha512_done(&hs, proto_k);
 
 	/* generate k */
-	m_mp_init(&dss_protok);
-	bytes_to_mp(&dss_protok, proto_k, SHA512_HASH_SIZE);
-	if (mp_mod(&dss_protok, key->q, &dss_k) != MP_OKAY) {
+	m_fp_init(&dss_protok);
+	bytes_to_fp(&dss_protok, proto_k, SHA512_HASH_SIZE);
+	if (fp_mod(&dss_protok, key->q, &dss_k) != FP_OKAY) {
 		dropbear_exit("dss error");
 	}
-	mp_clear(&dss_protok);
+	m_fp_zero(&dss_protok);
 	m_burn(proto_k, SHA512_HASH_SIZE);
 #else /* DSS_PROTOK not defined*/
-	gen_random_mpint(key->q, &dss_k);
+	gen_random_fpint(key->q, &dss_k);
 #endif
 
 	/* now generate the actual signature */
-	bytes_to_mp(&dss_m, msghash, SHA1_HASH_SIZE);
+	bytes_to_fp(&dss_m, msghash, SHA1_HASH_SIZE);
 
 	/* g^k mod p */
-	if (mp_exptmod(key->g, &dss_k, key->p, &dss_temp1) !=  MP_OKAY) {
+	if (fp_exptmod(key->g, &dss_k, key->p, &dss_temp1) !=  FP_OKAY) {
 		dropbear_exit("dss error");
 	}
 	/* r = (g^k mod p) mod q */
-	if (mp_mod(&dss_temp1, key->q, &dss_r) != MP_OKAY) {
+	if (fp_mod(&dss_temp1, key->q, &dss_r) != FP_OKAY) {
 		dropbear_exit("dss error");
 	}
 
 	/* x*r mod q */
-	if (mp_mulmod(&dss_r, key->x, key->q, &dss_temp1) != MP_OKAY) {
+	if (fp_mulmod(&dss_r, key->x, key->q, &dss_temp1) != FP_OKAY) {
 		dropbear_exit("dss error");
 	}
 	/* (SHA1(M) + xr) mod q) */
-	if (mp_addmod(&dss_m, &dss_temp1, key->q, &dss_temp2) != MP_OKAY) {
+	if (fp_addmod(&dss_m, &dss_temp1, key->q, &dss_temp2) != FP_OKAY) {
 		dropbear_exit("dss error");
 	}
 	
 	/* (k^-1) mod q */
-	if (mp_invmod(&dss_k, key->q, &dss_temp1) != MP_OKAY) {
+	if (fp_invmod(&dss_k, key->q, &dss_temp1) != FP_OKAY) {
 		dropbear_exit("dss error");
 	}
 
 	/* s = (k^-1(SHA1(M) + xr)) mod q */
-	if (mp_mulmod(&dss_temp1, &dss_temp2, key->q, &dss_s) != MP_OKAY) {
+	if (fp_mulmod(&dss_temp1, &dss_temp2, key->q, &dss_s) != FP_OKAY) {
 		dropbear_exit("dss error");
 	}
 
 	buf_putstring(buf, SSH_SIGNKEY_DSS, SSH_SIGNKEY_DSS_LEN);
 	buf_putint(buf, 2*SHA1_HASH_SIZE);
 
-	writelen = mp_unsigned_bin_size(&dss_r);
+	writelen = fp_unsigned_bin_size(&dss_r);
 	dropbear_assert(writelen <= SHA1_HASH_SIZE);
 	/* need to pad to 160 bits with leading zeros */
 	for (i = 0; i < SHA1_HASH_SIZE - writelen; i++) {
 		buf_putbyte(buf, 0);
 	}
-	if (mp_to_unsigned_bin(&dss_r, buf_getwriteptr(buf, writelen)) 
-			!= MP_OKAY) {
-		dropbear_exit("dss error");
-	}
-	mp_clear(&dss_r);
+	fp_to_unsigned_bin(&dss_r, buf_getwriteptr(buf, writelen));
+	fp_zero(&dss_r);
 	buf_incrwritepos(buf, writelen);
 
-	writelen = mp_unsigned_bin_size(&dss_s);
+	writelen = fp_unsigned_bin_size(&dss_s);
 	dropbear_assert(writelen <= SHA1_HASH_SIZE);
 	/* need to pad to 160 bits with leading zeros */
 	for (i = 0; i < SHA1_HASH_SIZE - writelen; i++) {
 		buf_putbyte(buf, 0);
 	}
-	if (mp_to_unsigned_bin(&dss_s, buf_getwriteptr(buf, writelen)) 
-			!= MP_OKAY) {
-		dropbear_exit("dss error");
-	}
-	mp_clear(&dss_s);
+	fp_to_unsigned_bin(&dss_s, buf_getwriteptr(buf, writelen));
+	fp_zero(&dss_s);
 	buf_incrwritepos(buf, writelen);
 
-	mp_clear_multi(&dss_k, &dss_temp1, &dss_temp2, &dss_r, &dss_s,
+	m_fp_zero_multi(&dss_k, &dss_temp1, &dss_temp2, &dss_r, &dss_s,
 			&dss_m, NULL);
 	
 	/* create the signature to return */
--- a/dss.h	Wed Nov 12 13:13:00 2008 +0000
+++ b/dss.h	Mon Nov 21 19:19:57 2011 +0800
@@ -34,11 +34,11 @@
 
 struct DSS_key {
 
-	mp_int* p;
-	mp_int* q;
-	mp_int* g;
-	mp_int* y;
-	mp_int* x;
+	fp_int* p;
+	fp_int* q;
+	fp_int* g;
+	fp_int* y;
+	fp_int* x;
 
 };
 
--- a/gendss.c	Wed Nov 12 13:13:00 2008 +0000
+++ b/gendss.c	Mon Nov 21 19:19:57 2011 +0800
@@ -49,12 +49,12 @@
 
 	key = (dss_key*)m_malloc(sizeof(dss_key));
 
-	key->p = (mp_int*)m_malloc(sizeof(mp_int));
-	key->q = (mp_int*)m_malloc(sizeof(mp_int));
-	key->g = (mp_int*)m_malloc(sizeof(mp_int));
-	key->y = (mp_int*)m_malloc(sizeof(mp_int));
-	key->x = (mp_int*)m_malloc(sizeof(mp_int));
-	m_mp_init_multi(key->p, key->q, key->g, key->y, key->x, NULL);
+	key->p = (fp_int*)m_malloc(sizeof(fp_int));
+	key->q = (fp_int*)m_malloc(sizeof(fp_int));
+	key->g = (fp_int*)m_malloc(sizeof(fp_int));
+	key->y = (fp_int*)m_malloc(sizeof(fp_int));
+	key->x = (fp_int*)m_malloc(sizeof(fp_int));
+	m_fp_init_multi(key->p, key->q, key->g, key->y, key->x, NULL);
 	
 	seedrandom();
 	
@@ -77,10 +77,10 @@
 	buf[0] |= 0x80; /* top bit high */
 	buf[QSIZE-1] |= 0x01; /* bottom bit high */
 
-	bytes_to_mp(key->q, buf, QSIZE);
+	bytes_to_fp(key->q, buf, QSIZE);
 
 	/* 18 rounds are required according to HAC */
-	if (mp_prime_next_prime(key->q, 18, 0) != MP_OKAY) {
+	if (fp_prime_next_prime(key->q, 18, 0) != FP_OKAY) {
 		fprintf(stderr, "dss key generation failed\n");
 		exit(1);
 	}
@@ -88,21 +88,18 @@
 
 static void getp(dss_key *key, unsigned int size) {
 
-	DEF_MP_INT(tempX);
-	DEF_MP_INT(tempC);
-	DEF_MP_INT(tempP);
-	DEF_MP_INT(temp2q);
+	DEF_FP_INT(tempX);
+	DEF_FP_INT(tempC);
+	DEF_FP_INT(tempP);
+	DEF_FP_INT(temp2q);
 	int result;
 	unsigned char *buf;
 
-	m_mp_init_multi(&tempX, &tempC, &tempP, &temp2q, NULL);
+	m_fp_init_multi(&tempX, &tempC, &tempP, &temp2q, NULL);
 
 
 	/* 2*q */
-	if (mp_mul_d(key->q, 2, &temp2q) != MP_OKAY) {
-		fprintf(stderr, "dss key generation failed\n");
-		exit(1);
-	}
+	fp_mul_d(key->q, 2, &temp2q);
 	
 	buf = (unsigned char*)m_malloc(size);
 
@@ -112,84 +109,74 @@
 		genrandom(buf, size);
 		buf[0] |= 0x80; /* set the top bit high */
 
-		/* X is a random mp_int */
-		bytes_to_mp(&tempX, buf, size);
+		/* X is a random fp_int */
+		bytes_to_fp(&tempX, buf, size);
 
 		/* C = X mod 2q */
-		if (mp_mod(&tempX, &temp2q, &tempC) != MP_OKAY) {
+		if (fp_mod(&tempX, &temp2q, &tempC) != FP_OKAY) {
 			fprintf(stderr, "dss key generation failed\n");
 			exit(1);
 		}
 
 		/* P = X - (C - 1) = X - C + 1*/
-		if (mp_sub(&tempX, &tempC, &tempP) != MP_OKAY) {
-			fprintf(stderr, "dss key generation failed\n");
-			exit(1);
-		}
+		fp_sub(&tempX, &tempC, &tempP);
 		
-		if (mp_add_d(&tempP, 1, key->p) != MP_OKAY) {
-			fprintf(stderr, "dss key generation failed\n");
-			exit(1);
-		}
+		fp_add_d(&tempP, 1, key->p);
 
 		/* now check for prime, 5 rounds is enough according to HAC */
 		/* result == 1  =>  p is prime */
-		if (mp_prime_is_prime(key->p, 5, &result) != MP_OKAY) {
+		if (fp_prime_is_prime(key->p, 5, &result) != FP_OKAY) {
 			fprintf(stderr, "dss key generation failed\n");
 			exit(1);
 		}
 	} while (!result);
 
-	mp_clear_multi(&tempX, &tempC, &tempP, &temp2q, NULL);
+	fp_zero(&tempX);
+	fp_zero(&tempC);
+        fp_zero(&tempP);
+        fp_zero(&temp2q);
 	m_burn(buf, size);
 	m_free(buf);
 }
 
 static void getg(dss_key * key) {
 
-	DEF_MP_INT(div);
-	DEF_MP_INT(h);
-	DEF_MP_INT(val);
+	DEF_FP_INT(div);
+	DEF_FP_INT(h);
+	DEF_FP_INT(val);
 
-	m_mp_init_multi(&div, &h, &val, NULL);
+	m_fp_init_multi(&div, &h, &val, NULL);
 
 	/* get div=(p-1)/q */
-	if (mp_sub_d(key->p, 1, &val) != MP_OKAY) {
-		fprintf(stderr, "dss key generation failed\n");
-		exit(1);
-	}
-	if (mp_div(&val, key->q, &div, NULL) != MP_OKAY) {
-		fprintf(stderr, "dss key generation failed\n");
-		exit(1);
-	}
+	fp_sub_d(key->p, 1, &val);
+	fp_div(&val, key->q, &div, NULL);
 
 	/* initialise h=1 */
-	mp_set(&h, 1);
+	fp_set(&h, 1);
 	do {
 		/* now keep going with g=h^div mod p, until g > 1 */
-		if (mp_exptmod(&h, &div, key->p, key->g) != MP_OKAY) {
+		if (fp_exptmod(&h, &div, key->p, key->g) != FP_OKAY) {
 			fprintf(stderr, "dss key generation failed\n");
 			exit(1);
 		}
 
-		if (mp_add_d(&h, 1, &h) != MP_OKAY) {
-			fprintf(stderr, "dss key generation failed\n");
-			exit(1);
-		}
+		fp_add_d(&h, 1, &h);
 	
-	} while (mp_cmp_d(key->g, 1) != MP_GT);
+	} while (fp_cmp_d(key->g, 1) != FP_GT);
 
-	mp_clear_multi(&div, &h, &val, NULL);
+	fp_zero(&div);
+	fp_zero(&h);
+	fp_zero(&val);
 }
 
 static void getx(dss_key *key) {
 
-	gen_random_mpint(key->q, key->x);
+	gen_random_fpint(key->q, key->x);
 }
 
 static void gety(dss_key *key) {
 
-	if (mp_exptmod(key->g, key->x, key->p, key->y) != MP_OKAY) {
+	if (fp_exptmod(key->g, key->x, key->p, key->y) != FP_OKAY) {
 		fprintf(stderr, "dss key generation failed\n");
 		exit(1);
 	}
--- a/genrsa.c	Wed Nov 12 13:13:00 2008 +0000
+++ b/genrsa.c	Mon Nov 21 19:19:57 2011 +0800
@@ -33,99 +33,85 @@
 
 #ifdef DROPBEAR_RSA
 
-static void getrsaprime(mp_int* prime, mp_int *primeminus, 
-		mp_int* rsa_e, unsigned int size);
+static void getrsaprime(fp_int* prime, fp_int *primeminus, 
+		fp_int* rsa_e, unsigned int size);
 
 /* mostly taken from libtomcrypt's rsa key generation routine */
 rsa_key * gen_rsa_priv_key(unsigned int size) {
 
 	rsa_key * key;
-	DEF_MP_INT(pminus);
-	DEF_MP_INT(qminus);
-	DEF_MP_INT(lcm);
+	DEF_FP_INT(pminus);
+	DEF_FP_INT(qminus);
+	DEF_FP_INT(lcm);
 
 	key = (rsa_key*)m_malloc(sizeof(rsa_key));
 
-	key->e = (mp_int*)m_malloc(sizeof(mp_int));
-	key->n = (mp_int*)m_malloc(sizeof(mp_int));
-	key->d = (mp_int*)m_malloc(sizeof(mp_int));
-	key->p = (mp_int*)m_malloc(sizeof(mp_int));
-	key->q = (mp_int*)m_malloc(sizeof(mp_int));
+	key->e = (fp_int*)m_malloc(sizeof(fp_int));
+	key->n = (fp_int*)m_malloc(sizeof(fp_int));
+	key->d = (fp_int*)m_malloc(sizeof(fp_int));
+	key->p = (fp_int*)m_malloc(sizeof(fp_int));
+	key->q = (fp_int*)m_malloc(sizeof(fp_int));
 
-	m_mp_init_multi(key->e, key->n, key->d, key->p, key->q,
+	m_fp_init_multi(key->e, key->n, key->d, key->p, key->q,
 			&pminus, &lcm, &qminus, NULL);
 
 	seedrandom();
 
-	if (mp_set_int(key->e, RSA_E) != MP_OKAY) {
+	fp_set(key->e, RSA_E);
+
+	getrsaprime(key->p, &pminus, key->e, size/2);
+	getrsaprime(key->q, &qminus, key->e, size/2);
+
+	fp_mul(key->p, key->q, key->n);
+
+	/* lcm(p-1, q-1) */
+	fp_lcm(&pminus, &qminus, &lcm);
+
+	/* de = 1 mod lcm(p-1,q-1) */
+	/* therefore d = (e^-1) mod lcm(p-1,q-1) */
+	if (fp_invmod(key->e, &lcm, key->d) != FP_OKAY) {
 		fprintf(stderr, "rsa generation failed\n");
 		exit(1);
 	}
 
-	getrsaprime(key->p, &pminus, key->e, size/2);
-	getrsaprime(key->q, &qminus, key->e, size/2);
-
-	if (mp_mul(key->p, key->q, key->n) != MP_OKAY) {
-		fprintf(stderr, "rsa generation failed\n");
-		exit(1);
-	}
-
-	/* lcm(p-1, q-1) */
-	if (mp_lcm(&pminus, &qminus, &lcm) != MP_OKAY) {
-		fprintf(stderr, "rsa generation failed\n");
-		exit(1);
-	}
-
-	/* de = 1 mod lcm(p-1,q-1) */
-	/* therefore d = (e^-1) mod lcm(p-1,q-1) */
-	if (mp_invmod(key->e, &lcm, key->d) != MP_OKAY) {
-		fprintf(stderr, "rsa generation failed\n");
-		exit(1);
-	}
-
-	mp_clear_multi(&pminus, &qminus, &lcm, NULL);
+	m_fp_zero_multi(&pminus, &qminus, &lcm, NULL);
 
 	return key;
 }	
 
 /* return a prime suitable for p or q */
-static void getrsaprime(mp_int* prime, mp_int *primeminus, 
-		mp_int* rsa_e, unsigned int size) {
+static void getrsaprime(fp_int* prime, fp_int *primeminus, 
+		fp_int* rsa_e, unsigned int size) {
 
 	unsigned char *buf;
-	DEF_MP_INT(temp_gcd);
+	DEF_FP_INT(temp_gcd);
 
 	buf = (unsigned char*)m_malloc(size+1);
 
-	m_mp_init(&temp_gcd);
+	m_fp_init(&temp_gcd);
 	do {
 		/* generate a random odd number with MSB set, then find the
 		   the next prime above it */
 		genrandom(buf, size+1);
 		buf[0] |= 0x80; /* MSB set */
 
-		bytes_to_mp(prime, buf, size+1);
+		bytes_to_fp(prime, buf, size+1);
 
 		/* find the next integer which is prime, 8 round of miller-rabin */
-		if (mp_prime_next_prime(prime, 8, 0) != MP_OKAY) {
+		if (fp_prime_next_prime(prime, 8, 0) != FP_OKAY) {
 			fprintf(stderr, "rsa generation failed\n");
 			exit(1);
 		}
 
 		/* subtract one to get p-1 */
-		if (mp_sub_d(prime, 1, primeminus) != MP_OKAY) {
-			fprintf(stderr, "rsa generation failed\n");
-			exit(1);
-		}
+		fp_sub_d(prime, 1, primeminus);
+
 		/* check relative primality to e */
-		if (mp_gcd(primeminus, rsa_e, &temp_gcd) != MP_OKAY) {
-			fprintf(stderr, "rsa generation failed\n");
-			exit(1);
-		}
-	} while (mp_cmp_d(&temp_gcd, 1) != MP_EQ); /* while gcd(p-1, e) != 1 */
+		fp_gcd(primeminus, rsa_e, &temp_gcd);
+	} while (fp_cmp_d(&temp_gcd, 1) != FP_EQ); /* while gcd(p-1, e) != 1 */
 
 	/* now we have a good value for result */
-	mp_clear(&temp_gcd);
+	fp_zero(&temp_gcd);
 	m_burn(buf, size+1);
 	m_free(buf);
 }
--- a/includes.h	Wed Nov 12 13:13:00 2008 +0000
+++ b/includes.h	Mon Nov 21 19:19:57 2011 +0800
@@ -121,7 +121,9 @@
 #endif
 
 #include "libtomcrypt/src/headers/tomcrypt.h"
-#include "libtommath/tommath.h"
+//#include "libtommath/tommath.h"
+#include "libtomsfastmath/tfm.h"
+
 
 #include "compat.h"
 #include "fake-rfc2553.h"
--- a/kex.h	Wed Nov 12 13:13:00 2008 +0000
+++ b/kex.h	Mon Nov 21 19:19:57 2011 +0800
@@ -33,8 +33,8 @@
 void send_msg_newkeys();
 void recv_msg_newkeys();
 void kexfirstinitialise();
-void gen_kexdh_vals(mp_int *dh_pub, mp_int *dh_priv);
-void kexdh_comb_key(mp_int *dh_pub_us, mp_int *dh_priv, mp_int *dh_pub_them,
+void gen_kexdh_vals(fp_int *dh_pub, fp_int *dh_priv);
+void kexdh_comb_key(fp_int *dh_pub_us, fp_int *dh_priv, fp_int *dh_pub_them,
 		sign_key *hostkey);
 
 #ifndef DISABLE_ZLIB
--- a/keyimport.c	Wed Nov 12 13:13:00 2008 +0000
+++ b/keyimport.c	Mon Nov 21 19:19:57 2011 +0800
@@ -343,7 +343,7 @@
 
 
 /* Simple structure to point to an mp-int within a blob. */
-struct mpint_pos { void *start; int bytes; };
+struct fpint_pos { void *start; int bytes; };
 
 /* ----------------------------------------------------------------------
  * Code to read and write OpenSSH private keys.
@@ -697,7 +697,7 @@
 	buffer * extrablob = NULL; /* used for calculated values to write */
 	unsigned char *outblob = NULL;
 	int outlen = -9999;
-	struct mpint_pos numbers[9];
+	struct fpint_pos numbers[9];
 	int nnumbers = -1, pos, len, seqlen, i;
 	char *header = NULL, *footer = NULL;
 	char zero[1];
@@ -706,7 +706,7 @@
 	int keytype = -1;
 
 #ifdef DROPBEAR_RSA
-	mp_int dmp1, dmq1, iqmp, tmpval; /* for rsa */
+	fp_int dmp1, dmq1, iqmp, tmpval; /* for rsa */
 
 	if (key->rsakey != NULL) {
 		keytype = DROPBEAR_SIGNKEY_RSA;
@@ -770,46 +770,42 @@
 		buf_incrpos(keyblob, numbers[5].bytes);
 
 		/* now calculate some extra parameters: */
-		m_mp_init(&tmpval);
-		m_mp_init(&dmp1);
-		m_mp_init(&dmq1);
-		m_mp_init(&iqmp);
+		m_fp_init(&tmpval);
+		m_fp_init(&dmp1);
+		m_fp_init(&dmq1);
+		m_fp_init(&iqmp);
 
 		/* dmp1 = d mod (p-1) */
-		if (mp_sub_d(key->rsakey->p, 1, &tmpval) != MP_OKAY) {
-			fprintf(stderr, "Bignum error for p-1\n");
-			goto error;
-		}
-		if (mp_mod(key->rsakey->d, &tmpval, &dmp1) != MP_OKAY) {
+		fp_sub_d(key->rsakey->p, 1, &tmpval);
+
+		if (fp_mod(key->rsakey->d, &tmpval, &dmp1) != FP_OKAY) {
 			fprintf(stderr, "Bignum error for dmp1\n");
 			goto error;
 		}
 
 		/* dmq1 = d mod (q-1) */
-		if (mp_sub_d(key->rsakey->q, 1, &tmpval) != MP_OKAY) {
-			fprintf(stderr, "Bignum error for q-1\n");
-			goto error;
-		}
-		if (mp_mod(key->rsakey->d, &tmpval, &dmq1) != MP_OKAY) {
+		fp_sub_d(key->rsakey->q, 1, &tmpval);
+
+		if (fp_mod(key->rsakey->d, &tmpval, &dmq1) != FP_OKAY) {
 			fprintf(stderr, "Bignum error for dmq1\n");
 			goto error;
 		}
 
 		/* iqmp = (q^-1) mod p */
-		if (mp_invmod(key->rsakey->q, key->rsakey->p, &iqmp) != MP_OKAY) {
+		if (fp_invmod(key->rsakey->q, key->rsakey->p, &iqmp) != FP_OKAY) {
 			fprintf(stderr, "Bignum error for iqmp\n");
 			goto error;
 		}
 
 		extrablob = buf_new(2000);
-		buf_putmpint(extrablob, &dmp1);
-		buf_putmpint(extrablob, &dmq1);
-		buf_putmpint(extrablob, &iqmp);
+		buf_putfpint(extrablob, &dmp1);
+		buf_putfpint(extrablob, &dmq1);
+		buf_putfpint(extrablob, &iqmp);
 		buf_setpos(extrablob, 0);
-		mp_clear(&dmp1);
-		mp_clear(&dmq1);
-		mp_clear(&iqmp);
-		mp_clear(&tmpval);
+		fp_zero(&dmp1);
+		fp_zero(&dmq1);
+		fp_zero(&iqmp);
+		fp_zero(&tmpval);
 		
 		/* dmp1 */
 		numbers[6].bytes = buf_getint(extrablob);
@@ -974,8 +970,8 @@
 
 /*
  * The format of the base64 blob is largely ssh2-packet-formatted,
- * except that mpints are a bit different: they're more like the
- * old ssh1 mpint. You have a 32-bit bit count N, followed by
+ * except that fpints are a bit different: they're more like the
+ * old ssh1 fpint. You have a 32-bit bit count N, followed by
  * (N+7)/8 bytes of data.
  * 
  * So. The blob contains:
@@ -998,20 +994,20 @@
  * decryption check.)
  * 
  * The payload blob, for an RSA key, contains:
- *  - mpint e
- *  - mpint d
- *  - mpint n  (yes, the public and private stuff is intermixed)
- *  - mpint u  (presumably inverse of p mod q)
- *  - mpint p  (p is the smaller prime)
- *  - mpint q  (q is the larger)
+ *  - fpint e
+ *  - fpint d
+ *  - fpint n  (yes, the public and private stuff is intermixed)
+ *  - fpint u  (presumably inverse of p mod q)
+ *  - fpint p  (p is the smaller prime)
+ *  - fpint q  (q is the larger)
  * 
  * For a DSA key, the payload blob contains:
  *  - uint32 0
- *  - mpint p
- *  - mpint g
- *  - mpint q
- *  - mpint y
- *  - mpint x
+ *  - fpint p
+ *  - fpint g
+ *  - fpint q
+ *  - fpint y
+ *  - fpint x
  * 
  * Alternatively, if the parameters are `predefined', that
  * (0,p,g,q) sequence can be replaced by a uint32 1 and a string
@@ -1209,7 +1205,7 @@
 	return answer;
 }
 
-static int sshcom_read_mpint(void *data, int len, struct mpint_pos *ret)
+static int sshcom_read_fpint(void *data, int len, struct fpint_pos *ret)
 {
 	int bits;
 	int bytes;
@@ -1233,7 +1229,7 @@
 	return len;						/* ensure further calls fail as well */
 }
 
-static int sshcom_put_mpint(void *target, void *data, int len)
+static int sshcom_put_fpint(void *target, void *data, int len)
 {
 	unsigned char *d = (unsigned char *)target;
 	unsigned char *i = (unsigned char *)data;
@@ -1402,14 +1398,14 @@
 	blob = snewn(blobsize, unsigned char);
 	privlen = 0;
 	if (type == RSA) {
-		struct mpint_pos n, e, d, u, p, q;
+		struct fpint_pos n, e, d, u, p, q;
 		int pos = 0;
-		pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &e);
-		pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &d);
-		pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &n);
-		pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &u);
-		pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &p);
-		pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &q);
+		pos += sshcom_read_fpint(ciphertext+pos, cipherlen-pos, &e);
+		pos += sshcom_read_fpint(ciphertext+pos, cipherlen-pos, &d);
+		pos += sshcom_read_fpint(ciphertext+pos, cipherlen-pos, &n);
+		pos += sshcom_read_fpint(ciphertext+pos, cipherlen-pos, &u);
+		pos += sshcom_read_fpint(ciphertext+pos, cipherlen-pos, &p);
+		pos += sshcom_read_fpint(ciphertext+pos, cipherlen-pos, &q);
 		if (!q.start) {
 			errmsg = "key data did not contain six integers";
 			goto error;
@@ -1427,17 +1423,17 @@
 		pos += put_mp(blob+pos, u.start, u.bytes);
 		privlen = pos - publen;
 	} else if (type == DSA) {
-		struct mpint_pos p, q, g, x, y;
+		struct fpint_pos p, q, g, x, y;
 		int pos = 4;
 		if (GET_32BIT(ciphertext) != 0) {
 			errmsg = "predefined DSA parameters not supported";
 			goto error;
 		}
-		pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &p);
-		pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &g);
-		pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &q);
-		pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &y);
-		pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &x);
+		pos += sshcom_read_fpint(ciphertext+pos, cipherlen-pos, &p);
+		pos += sshcom_read_fpint(ciphertext+pos, cipherlen-pos, &g);
+		pos += sshcom_read_fpint(ciphertext+pos, cipherlen-pos, &q);
+		pos += sshcom_read_fpint(ciphertext+pos, cipherlen-pos, &y);
+		pos += sshcom_read_fpint(ciphertext+pos, cipherlen-pos, &x);
 		if (!x.start) {
 			errmsg = "key data did not contain five integers";
 			goto error;
@@ -1489,7 +1485,7 @@
 	int publen, privlen;
 	unsigned char *outblob;
 	int outlen;
-	struct mpint_pos numbers[6];
+	struct fpint_pos numbers[6];
 	int nnumbers, initial_zero, pos, lenpos, i;
 	char *type;
 	char *ciphertext;
@@ -1510,16 +1506,16 @@
 	 */
 	if (key->alg == &ssh_rsa) {
 		int pos;
-		struct mpint_pos n, e, d, p, q, iqmp;
+		struct fpint_pos n, e, d, p, q, iqmp;
 
 		pos = 4 + GET_32BIT(pubblob);
-		pos += ssh2_read_mpint(pubblob+pos, publen-pos, &e);
-		pos += ssh2_read_mpint(pubblob+pos, publen-pos, &n);
+		pos += ssh2_read_fpint(pubblob+pos, publen-pos, &e);
+		pos += ssh2_read_fpint(pubblob+pos, publen-pos, &n);
 		pos = 0;
-		pos += ssh2_read_mpint(privblob+pos, privlen-pos, &d);
-		pos += ssh2_read_mpint(privblob+pos, privlen-pos, &p);
-		pos += ssh2_read_mpint(privblob+pos, privlen-pos, &q);
-		pos += ssh2_read_mpint(privblob+pos, privlen-pos, &iqmp);
+		pos += ssh2_read_fpint(privblob+pos, privlen-pos, &d);
+		pos += ssh2_read_fpint(privblob+pos, privlen-pos, &p);
+		pos += ssh2_read_fpint(privblob+pos, privlen-pos, &q);
+		pos += ssh2_read_fpint(privblob+pos, privlen-pos, &iqmp);
 
 		dropbear_assert(e.start && iqmp.start); /* can't go wrong */
 
@@ -1535,15 +1531,15 @@
 		type = "if-modn{sign{rsa-pkcs1-sha1},encrypt{rsa-pkcs1v2-oaep}}";
 	} else if (key->alg == &ssh_dss) {
 		int pos;
-		struct mpint_pos p, q, g, y, x;
+		struct fpint_pos p, q, g, y, x;
 
 		pos = 4 + GET_32BIT(pubblob);
-		pos += ssh2_read_mpint(pubblob+pos, publen-pos, &p);
-		pos += ssh2_read_mpint(pubblob+pos, publen-pos, &q);
-		pos += ssh2_read_mpint(pubblob+pos, publen-pos, &g);
-		pos += ssh2_read_mpint(pubblob+pos, publen-pos, &y);
+		pos += ssh2_read_fpint(pubblob+pos, publen-pos, &p);
+		pos += ssh2_read_fpint(pubblob+pos, publen-pos, &q);
+		pos += ssh2_read_fpint(pubblob+pos, publen-pos, &g);
+		pos += ssh2_read_fpint(pubblob+pos, publen-pos, &y);
 		pos = 0;
-		pos += ssh2_read_mpint(privblob+pos, privlen-pos, &x);
+		pos += ssh2_read_fpint(privblob+pos, privlen-pos, &x);
 
 		dropbear_assert(y.start && x.start); /* can't go wrong */
 
@@ -1589,7 +1585,7 @@
 		pos += 4;
 	}
 	for (i = 0; i < nnumbers; i++)
-		pos += sshcom_put_mpint(outblob+pos,
+		pos += sshcom_put_fpint(outblob+pos,
 								numbers[i].start, numbers[i].bytes);
 	/* Now wrap up the encrypted payload. */
 	PUT_32BIT(outblob+lenpos+4, pos - (lenpos+8));
--- a/options.h	Wed Nov 12 13:13:00 2008 +0000
+++ b/options.h	Mon Nov 21 19:19:57 2011 +0800
@@ -51,7 +51,7 @@
 #define DROPBEAR_SMALL_CODE
 
 /* Enable X11 Forwarding - server only */
-#define ENABLE_X11FWD
+/* #define ENABLE_X11FWD */
 
 /* Enable TCP Fowarding */
 /* 'Local' is "-L" style (client listening port forwarded via server)
--- a/random.c	Wed Nov 12 13:13:00 2008 +0000
+++ b/random.c	Mon Nov 21 19:19:57 2011 +0800
@@ -205,18 +205,18 @@
 	m_burn(hash, sizeof(hash));
 }
 
-/* Generates a random mp_int. 
- * max is a *mp_int specifying an upper bound.
- * rand must be an initialised *mp_int for the result.
+/* Generates a random fp_int. 
+ * max is a *fp_int specifying an upper bound.
+ * rand must be an initialised *fp_int for the result.
  * the result rand satisfies:  0 < rand < max 
  * */
-void gen_random_mpint(mp_int *max, mp_int *rand) {
+void gen_random_fpint(fp_int *max, fp_int *rand) {
 
 	unsigned char *randbuf = NULL;
 	unsigned int len = 0;
 	const unsigned char masks[] = {0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f};
 
-	const int size_bits = mp_count_bits(max);
+	const int size_bits = fp_count_bits(max);
 
 	len = size_bits / 8;
 	if ((size_bits % 8) != 0) {
@@ -226,15 +226,15 @@
 	randbuf = (unsigned char*)m_malloc(len);
 	do {
 		genrandom(randbuf, len);
-		/* Mask out the unrequired bits - mp_read_unsigned_bin expects
+		/* Mask out the unrequired bits - fp_read_unsigned_bin expects
 		 * MSB first.*/
 		randbuf[0] &= masks[size_bits % 8];
 
-		bytes_to_mp(rand, randbuf, len);
+		bytes_to_fp(rand, randbuf, len);
 
 		/* keep regenerating until we get one satisfying
 		 * 0 < rand < max    */
-	} while (mp_cmp(rand, max) != MP_LT);
+	} while (fp_cmp(rand, max) != FP_LT);
 	m_burn(randbuf, len);
 	m_free(randbuf);
 }
--- a/random.h	Wed Nov 12 13:13:00 2008 +0000
+++ b/random.h	Mon Nov 21 19:19:57 2011 +0800
@@ -25,12 +25,12 @@
 #ifndef _RANDOM_H_
 #define _RANDOM_H_
 
-struct mp_int;
+struct fp_int;
 
 void seedrandom();
 void reseedrandom();
 void genrandom(unsigned char* buf, int len);
 void addrandom(unsigned char* buf, int len);
-void gen_random_mpint(mp_int *max, mp_int *rand);
+void gen_random_mpint(fp_int *max, fp_int *rand);
 
 #endif /* _RANDOM_H_ */
--- a/rsa.c	Wed Nov 12 13:13:00 2008 +0000
+++ b/rsa.c	Mon Nov 21 19:19:57 2011 +0800
@@ -40,7 +40,8 @@
 
 static void rsa_pad_em(rsa_key * key,
 		const unsigned char * data, unsigned int len,
-		mp_int * rsa_em);
+		fp_int * rsa_em);
+
 
 /* Load a public rsa key from a buffer, initialising the values.
  * The key will have the same format as buf_put_rsa_key.
@@ -51,22 +52,23 @@
     int ret = DROPBEAR_FAILURE;
 	TRACE(("enter buf_get_rsa_pub_key"))
 	dropbear_assert(key != NULL);
-	key->e = m_malloc(sizeof(mp_int));
-	key->n = m_malloc(sizeof(mp_int));
-	m_mp_init_multi(key->e, key->n, NULL);
+	key->e = m_malloc(sizeof(fp_int));
+	key->n = m_malloc(sizeof(fp_int));
+	fp_init(key->e);
+	fp_init(key->n);
 	key->d = NULL;
 	key->p = NULL;
 	key->q = NULL;
 
 	buf_incrpos(buf, 4+SSH_SIGNKEY_RSA_LEN); /* int + "ssh-rsa" */
 
-	if (buf_getmpint(buf, key->e) == DROPBEAR_FAILURE
-	 || buf_getmpint(buf, key->n) == DROPBEAR_FAILURE) {
+	if (buf_getfpint(buf, key->e) == DROPBEAR_FAILURE
+	 || buf_getfpint(buf, key->n) == DROPBEAR_FAILURE) {
 		TRACE(("leave buf_get_rsa_pub_key: failure"))
 	    goto out;
 	}
 
-	if (mp_count_bits(key->n) < MIN_RSA_KEYLEN) {
+	if (fp_count_bits(key->n) < MIN_RSA_KEYLEN) {
 		dropbear_log(LOG_WARNING, "rsa key too short");
 	    goto out;
 	}
@@ -99,9 +101,9 @@
 	key->p = NULL;
 	key->q = NULL;
 
-	key->d = m_malloc(sizeof(mp_int));
-	m_mp_init(key->d);
-	if (buf_getmpint(buf, key->d) == DROPBEAR_FAILURE) {
+	key->d = m_malloc(sizeof(fp_int));
+	fp_init(key->d);
+	if (buf_getfpint(buf, key->d) == DROPBEAR_FAILURE) {
 		TRACE(("leave buf_get_rsa_priv_key: d: ret == DROPBEAR_FAILURE"))
 	    goto out;
 	}
@@ -109,16 +111,17 @@
 	if (buf->pos == buf->len) {
     	/* old Dropbear private keys didn't keep p and q, so we will ignore them*/
 	} else {
-		key->p = m_malloc(sizeof(mp_int));
-		key->q = m_malloc(sizeof(mp_int));
-		m_mp_init_multi(key->p, key->q, NULL);
+		key->p = m_malloc(sizeof(fp_int));
+		key->q = m_malloc(sizeof(fp_int));
+		fp_init(key->p);
+		fp_init(key->q);
 
-		if (buf_getmpint(buf, key->p) == DROPBEAR_FAILURE) {
+		if (buf_getfpint(buf, key->p) == DROPBEAR_FAILURE) {
 			TRACE(("leave buf_get_rsa_priv_key: p: ret == DROPBEAR_FAILURE"))
 		    goto out;
 		}
 
-		if (buf_getmpint(buf, key->q) == DROPBEAR_FAILURE) {
+		if (buf_getfpint(buf, key->q) == DROPBEAR_FAILURE) {
 			TRACE(("leave buf_get_rsa_priv_key: q: ret == DROPBEAR_FAILURE"))
 		    goto out;
 		}
@@ -146,23 +149,23 @@
 		return;
 	}
 	if (key->d) {
-		mp_clear(key->d);
+		fp_zero(key->d);
 		m_free(key->d);
 	}
 	if (key->e) {
-		mp_clear(key->e);
+		fp_zero(key->e);
 		m_free(key->e);
 	}
 	if (key->n) {
-		 mp_clear(key->n);
+		 fp_zero(key->n);
 		 m_free(key->n);
 	}
 	if (key->p) {
-		mp_clear(key->p);
+		fp_zero(key->p);
 		m_free(key->p);
 	}
 	if (key->q) {
-		mp_clear(key->q);
+		fp_zero(key->q);
 		m_free(key->q);
 	}
 	m_free(key);
@@ -172,8 +175,8 @@
 /* Put the public rsa key into the buffer in the required format:
  *
  * string	"ssh-rsa"
- * mp_int	e
- * mp_int	n
+ * fp_int	e
+ * fp_int	n
  */
 void buf_put_rsa_pub_key(buffer* buf, rsa_key *key) {
 
@@ -181,8 +184,8 @@
 	dropbear_assert(key != NULL);
 
 	buf_putstring(buf, SSH_SIGNKEY_RSA, SSH_SIGNKEY_RSA_LEN);
-	buf_putmpint(buf, key->e);
-	buf_putmpint(buf, key->n);
+	buf_putfpint(buf, key->e);
+	buf_putfpint(buf, key->n);
 
 	TRACE(("leave buf_put_rsa_pub_key"))
 
@@ -195,14 +198,14 @@
 
 	dropbear_assert(key != NULL);
 	buf_put_rsa_pub_key(buf, key);
-	buf_putmpint(buf, key->d);
+	buf_putfpint(buf, key->d);
 
 	/* new versions have p and q, old versions don't */
 	if (key->p) {
-		buf_putmpint(buf, key->p);
+		buf_putfpint(buf, key->p);
 	}
 	if (key->q) {
-		buf_putmpint(buf, key->q);
+		buf_putfpint(buf, key->q);
 	}
 
 
@@ -217,31 +220,30 @@
 		unsigned int len) {
 
 	unsigned int slen;
-	DEF_MP_INT(rsa_s);
-	DEF_MP_INT(rsa_mdash);
-	DEF_MP_INT(rsa_em);
+	DEF_FP_INT(rsa_s);
+	DEF_FP_INT(rsa_mdash);
+	DEF_FP_INT(rsa_em);
 	int ret = DROPBEAR_FAILURE;
 
 	TRACE(("enter buf_rsa_verify"))
 
 	dropbear_assert(key != NULL);
 
-	m_mp_init_multi(&rsa_mdash, &rsa_s, &rsa_em, NULL);
+	fp_init(&rsa_mdash);
+	fp_init(&rsa_s);
+	fp_init(&rsa_em);
 
 	slen = buf_getint(buf);
-	if (slen != (unsigned int)mp_unsigned_bin_size(key->n)) {
+	if (slen != (unsigned int)fp_unsigned_bin_size(key->n)) {
 		TRACE(("bad size"))
 		goto out;
 	}
 
-	if (mp_read_unsigned_bin(&rsa_s, buf_getptr(buf, buf->len - buf->pos),
-				buf->len - buf->pos) != MP_OKAY) {
-		TRACE(("failed reading rsa_s"))
-		goto out;
-	}
+	fp_read_unsigned_bin(&rsa_s, buf_getptr(buf, buf->len - buf->pos),
+				buf->len - buf->pos);
 
 	/* check that s <= n-1 */
-	if (mp_cmp(&rsa_s, key->n) != MP_LT) {
+	if (fp_cmp(&rsa_s, key->n) != FP_LT) {
 		TRACE(("s > n-1"))
 		goto out;
 	}
@@ -249,19 +251,22 @@
 	/* create the magic PKCS padded value */
 	rsa_pad_em(key, data, len, &rsa_em);
 
-	if (mp_exptmod(&rsa_s, key->e, key->n, &rsa_mdash) != MP_OKAY) {
+	if (fp_exptmod(&rsa_s, key->e, key->n, &rsa_mdash) != FP_OKAY) {
 		TRACE(("failed exptmod rsa_s"))
 		goto out;
 	}
 
-	if (mp_cmp(&rsa_em, &rsa_mdash) == MP_EQ) {
+	if (fp_cmp(&rsa_em, &rsa_mdash) == FP_EQ) {
 		/* signature is valid */
 		TRACE(("success!"))
 		ret = DROPBEAR_SUCCESS;
 	}
 
 out:
-	mp_clear_multi(&rsa_mdash, &rsa_s, &rsa_em, NULL);
+	fp_zero(&rsa_mdash);
+	fp_zero(&rsa_s);
+	fp_zero(&rsa_em);
+
 	TRACE(("leave buf_rsa_verify: ret %d", ret))
 	return ret;
 }
@@ -275,15 +280,18 @@
 
 	unsigned int nsize, ssize;
 	unsigned int i;
-	DEF_MP_INT(rsa_s);
-	DEF_MP_INT(rsa_tmp1);
-	DEF_MP_INT(rsa_tmp2);
-	DEF_MP_INT(rsa_tmp3);
+	DEF_FP_INT(rsa_s);
+	DEF_FP_INT(rsa_tmp1);
+	DEF_FP_INT(rsa_tmp2);
+	DEF_FP_INT(rsa_tmp3);
 	
 	TRACE(("enter buf_put_rsa_sign"))
 	dropbear_assert(key != NULL);
 
-	m_mp_init_multi(&rsa_s, &rsa_tmp1, &rsa_tmp2, &rsa_tmp3, NULL);
+	fp_init(&rsa_s);
+	fp_init(&rsa_tmp1);
+	fp_init(&rsa_tmp2);
+	fp_init(&rsa_tmp3);
 
 	rsa_pad_em(key, data, len, &rsa_tmp1);
 
@@ -295,32 +303,32 @@
 
 	/* generate the r blinding value */
 	/* rsa_tmp2 is r */
-	gen_random_mpint(key->n, &rsa_tmp2);
+	gen_random_fpint(key->n, &rsa_tmp2);
 
 	/* rsa_tmp1 is em */
 	/* em' = em * r^e mod n */
 
 	/* rsa_s used as a temp var*/
-	if (mp_exptmod(&rsa_tmp2, key->e, key->n, &rsa_s) != MP_OKAY) {
+	if (fp_exptmod(&rsa_tmp2, key->e, key->n, &rsa_s) != FP_OKAY) {
 		dropbear_exit("rsa error");
 	}
-	if (mp_invmod(&rsa_tmp2, key->n, &rsa_tmp3) != MP_OKAY) {
+	if (fp_invmod(&rsa_tmp2, key->n, &rsa_tmp3) != FP_OKAY) {
 		dropbear_exit("rsa error");
 	}
-	if (mp_mulmod(&rsa_tmp1, &rsa_s, key->n, &rsa_tmp2) != MP_OKAY) {
+	if (fp_mulmod(&rsa_tmp1, &rsa_s, key->n, &rsa_tmp2) != FP_OKAY) {
 		dropbear_exit("rsa error");
 	}
 
 	/* rsa_tmp2 is em' */
 	/* s' = (em')^d mod n */
-	if (mp_exptmod(&rsa_tmp2, key->d, key->n, &rsa_tmp1) != MP_OKAY) {
+	if (fp_exptmod(&rsa_tmp2, key->d, key->n, &rsa_tmp1) != FP_OKAY) {
 		dropbear_exit("rsa error");
 	}
 
 	/* rsa_tmp1 is s' */
 	/* rsa_tmp3 is r^(-1) mod n */
 	/* s = (s')r^(-1) mod n */
-	if (mp_mulmod(&rsa_tmp1, &rsa_tmp3, key->n, &rsa_s) != MP_OKAY) {
+	if (fp_mulmod(&rsa_tmp1, &rsa_tmp3, key->n, &rsa_s) != FP_OKAY) {
 		dropbear_exit("rsa error");
 	}
 
@@ -328,33 +336,34 @@
 
 	/* s = em^d mod n */
 	/* rsa_tmp1 is em */
-	if (mp_exptmod(&rsa_tmp1, key->d, key->n, &rsa_s) != MP_OKAY) {
+	if (fp_exptmod(&rsa_tmp1, key->d, key->n, &rsa_s) != FP_OKAY) {
 		dropbear_exit("rsa error");
 	}
 
 #endif /* RSA_BLINDING */
 
-	mp_clear_multi(&rsa_tmp1, &rsa_tmp2, &rsa_tmp3, NULL);
+	fp_zero(&rsa_tmp1);
+	fp_zero(&rsa_tmp2);
+	fp_zero(&rsa_tmp3);
 	
 	/* create the signature to return */
 	buf_putstring(buf, SSH_SIGNKEY_RSA, SSH_SIGNKEY_RSA_LEN);
 
-	nsize = mp_unsigned_bin_size(key->n);
+	nsize = fp_unsigned_bin_size(key->n);
 
 	/* string rsa_signature_blob length */
 	buf_putint(buf, nsize);
 	/* pad out s to same length as n */
-	ssize = mp_unsigned_bin_size(&rsa_s);
+	ssize = fp_unsigned_bin_size(&rsa_s);
 	dropbear_assert(ssize <= nsize);
 	for (i = 0; i < nsize-ssize; i++) {
 		buf_putbyte(buf, 0x00);
 	}
 
-	if (mp_to_unsigned_bin(&rsa_s, buf_getwriteptr(buf, ssize)) != MP_OKAY) {
-		dropbear_exit("rsa error");
-	}
+	fp_to_unsigned_bin(&rsa_s, buf_getwriteptr(buf, ssize));
+
 	buf_incrwritepos(buf, ssize);
-	mp_clear(&rsa_s);
+	fp_zero(&rsa_s);
 
 #if defined(DEBUG_RSA) && defined(DEBUG_TRACE)
 	printhex("RSA sig", buf->data, buf->len);
@@ -374,11 +383,11 @@
  * prefix is the ASN1 designator prefix,
  * hex 30 21 30 09 06 05 2B 0E 03 02 1A 05 00 04 14
  *
- * rsa_em must be a pointer to an initialised mp_int.
+ * rsa_em must be a pointer to an initialised fp_int.
  */
 static void rsa_pad_em(rsa_key * key,
 		const unsigned char * data, unsigned int len, 
-		mp_int * rsa_em) {
+		fp_int * rsa_em) {
 
 	/* ASN1 designator (including the 0x00 preceding) */
 	const unsigned char rsa_asn1_magic[] = 
@@ -392,7 +401,7 @@
 	
 	dropbear_assert(key != NULL);
 	dropbear_assert(data != NULL);
-	nsize = mp_unsigned_bin_size(key->n);
+	nsize = fp_unsigned_bin_size(key->n);
 
 	rsa_EM = buf_new(nsize-1);
 	/* type byte */
@@ -414,9 +423,9 @@
 
 	dropbear_assert(rsa_EM->pos == rsa_EM->size);
 
-	/* Create the mp_int from the encoded bytes */
+	/* Create the fp_int from the encoded bytes */
 	buf_setpos(rsa_EM, 0);
-	bytes_to_mp(rsa_em, buf_getptr(rsa_EM, rsa_EM->size),
+	bytes_to_fp(rsa_em, buf_getptr(rsa_EM, rsa_EM->size),
 			rsa_EM->size);
 	buf_free(rsa_EM);
 }
--- a/rsa.h	Wed Nov 12 13:13:00 2008 +0000
+++ b/rsa.h	Mon Nov 21 19:19:57 2011 +0800
@@ -34,11 +34,11 @@
 
 struct RSA_key {
 
-	mp_int* n;
-	mp_int* e;
-	mp_int* d;
-	mp_int* p;
-	mp_int* q;
+	fp_int* n;
+	fp_int* e;
+	fp_int* d;
+	fp_int* p;
+	fp_int* q;
 
 };
 
--- a/session.h	Wed Nov 12 13:13:00 2008 +0000
+++ b/session.h	Mon Nov 21 19:19:57 2011 +0800
@@ -164,7 +164,7 @@
 	struct key_context *newkeys;
 	unsigned char *session_id; /* this is the hash from the first kex */
 	/* The below are used temorarily during kex, are freed after use */
-	mp_int * dh_K; /* SSH_MSG_KEXDH_REPLY and sending SSH_MSH_NEWKEYS */
+	fp_int * dh_K; /* SSH_MSG_KEXDH_REPLY and sending SSH_MSH_NEWKEYS */
 	unsigned char hash[SHA1_HASH_SIZE]; /* the hash*/
 	buffer* kexhashbuf; /* session hash buffer calculated from various packets*/
 	buffer* transkexinit; /* the kexinit packet we send should be kept so we
@@ -243,7 +243,7 @@
 
 struct clientsession {
 
-	mp_int *dh_e, *dh_x; /* Used during KEX */
+	fp_int *dh_e, *dh_x; /* Used during KEX */
 	cli_kex_state kex_state; /* Used for progressing KEX */
 	cli_state state; /* Used to progress auth/channelsession etc */
 	unsigned donefirstkex : 1; /* Set when we set sentnewkeys, never reset */
--- a/svr-kex.c	Wed Nov 12 13:13:00 2008 +0000
+++ b/svr-kex.c	Mon Nov 21 19:19:57 2011 +0800
@@ -36,7 +36,7 @@
 #include "runopts.h"
 
 
-static void send_msg_kexdh_reply(mp_int *dh_e);
+static void send_msg_kexdh_reply(fp_int *dh_e);
 
 /* Handle a diffie-hellman key exchange initialisation. This involves
  * calculating a session key reply value, and corresponding hash. These
@@ -44,21 +44,21 @@
  * that function, then brings the new keys into use */
 void recv_msg_kexdh_init() {
 
-	DEF_MP_INT(dh_e);
+	DEF_FP_INT(dh_e);
 
 	TRACE(("enter recv_msg_kexdh_init"))
 	if (!ses.kexstate.recvkexinit) {
 		dropbear_exit("Premature kexdh_init message received");
 	}
 
-	m_mp_init(&dh_e);
-	if (buf_getmpint(ses.payload, &dh_e) != DROPBEAR_SUCCESS) {
+	m_fp_init(&dh_e);
+	if (buf_getfpint(ses.payload, &dh_e) != DROPBEAR_SUCCESS) {
 		dropbear_exit("Failed to get kex value");
 	}
 
 	send_msg_kexdh_reply(&dh_e);
 
-	mp_clear(&dh_e);
+	fp_zero(&dh_e);
 
 	send_msg_newkeys();
 	ses.requirenext = SSH_MSG_NEWKEYS;
@@ -71,18 +71,18 @@
  * result is sent to the client. 
  *
  * See the ietf-secsh-transport draft, section 6, for details */
-static void send_msg_kexdh_reply(mp_int *dh_e) {
+static void send_msg_kexdh_reply(fp_int *dh_e) {
 
-	DEF_MP_INT(dh_y);
-	DEF_MP_INT(dh_f);
+	DEF_FP_INT(dh_y);
+	DEF_FP_INT(dh_f);
 
 	TRACE(("enter send_msg_kexdh_reply"))
-	m_mp_init_multi(&dh_y, &dh_f, NULL);
+	m_fp_init_multi(&dh_y, &dh_f, NULL);
 	
 	gen_kexdh_vals(&dh_f, &dh_y);
 
 	kexdh_comb_key(&dh_f, &dh_y, dh_e, svr_opts.hostkey);
-	mp_clear(&dh_y);
+	fp_zero(&dh_y);
 
 	/* we can start creating the kexdh_reply packet */
 	CHECKCLEARTOWRITE();
@@ -91,8 +91,8 @@
 			ses.newkeys->algo_hostkey);
 
 	/* put f */
-	buf_putmpint(ses.writepayload, &dh_f);
-	mp_clear(&dh_f);
+	buf_putfpint(ses.writepayload, &dh_f);
+	fp_zero(&dh_f);
 
 	/* calc the signature */
 	buf_put_sign(ses.writepayload, svr_opts.hostkey,