diff --git a/src/ssh/comp/none.c b/src/ssh/comp/none.c
index 7d040934e6031bcebfe02842f081421ded767dfd..912b89609648126a2b8add4457aecb8468df3162 100644
--- a/src/ssh/comp/none.c
+++ b/src/ssh/comp/none.c
@@ -1,4 +1,4 @@
-#include "ssh-trans.h"
+#include "deucessh.h"
 
 static int
 compress(uint8_t *buf, uint8_t *bufsz, deuce_ssh_session_t sess)
diff --git a/src/ssh/deucessh.h b/src/ssh/deucessh.h
index eb1985c2f26020ce887c4138923231b54564d86c..ad6db796feb13ca52252476c7168a1ef51cd0ebc 100644
--- a/src/ssh/deucessh.h
+++ b/src/ssh/deucessh.h
@@ -14,16 +14,17 @@ _Static_assert(0, "threads.h support required");
 #include <stdbool.h>
 #include <threads.h>
 
-#define DEUCE_SSH_ERROR_NONE          0
-#define DEUCE_SSH_ERROR_PARSE        -1
-#define DEUCE_SSH_ERROR_INVALID      -2
-#define DEUCE_SSH_ERROR_ALLOC        -3
-#define DEUCE_SSH_ERROR_INIT         -4
-#define DEUCE_SSH_ERROR_TERMINATED   -5
-#define DEUCE_SSH_ERROR_TOOLATE      -6
-#define DEUCE_SSH_ERROR_TOOMANY      -7
-#define DEUCE_SSH_ERROR_TOOLONG      -8
-#define DEUCE_SSH_ERROR_MUST_BE_NULL -9
+#define DEUCE_SSH_ERROR_NONE           0
+#define DEUCE_SSH_ERROR_PARSE         -1
+#define DEUCE_SSH_ERROR_INVALID       -2
+#define DEUCE_SSH_ERROR_ALLOC         -3
+#define DEUCE_SSH_ERROR_INIT          -4
+#define DEUCE_SSH_ERROR_TERMINATED    -5
+#define DEUCE_SSH_ERROR_TOOLATE       -6
+#define DEUCE_SSH_ERROR_TOOMANY       -7
+#define DEUCE_SSH_ERROR_TOOLONG       -8
+#define DEUCE_SSH_ERROR_MUST_BE_NULL  -9
+#define DEUCE_SSH_ERROR_NOMORE       -10
 
 typedef struct deuce_ssh_transport_state *deuce_ssh_transport_state_t;
 typedef int (*deuce_ssh_transport_io_cb_t)(uint8_t *buf, size_t bufsz, atomic_bool *terminate, void *cbdata);
diff --git a/src/ssh/enc/none.c b/src/ssh/enc/none.c
index d4dad104397b0943be44f64437bfa07134ad4aa7..7d5ec2611eaa622b634da0ce9be22063cd1cd6ee 100644
--- a/src/ssh/enc/none.c
+++ b/src/ssh/enc/none.c
@@ -1,4 +1,4 @@
-#include "ssh-trans.h"
+#include "deucessh.h"
 
 static int
 encrypt(uint8_t *buf, uint8_t *bufsz, deuce_ssh_session_t sess)
diff --git a/src/ssh/mac/none.c b/src/ssh/mac/none.c
index 914573292a868d7ce890ed7defca8175675f830d..5ae2c18e402ac60c6b6c770d2c21de3ae3e5cdcc 100644
--- a/src/ssh/mac/none.c
+++ b/src/ssh/mac/none.c
@@ -1,4 +1,4 @@
-#include "ssh-trans.h"
+#include "deucessh.h"
 
 static int
 generate(uint8_t *key, uint8_t *buf, size_t bufsz, uint8_t *outbuf, deuce_ssh_session_t sess)
diff --git a/src/ssh/ssh-arch.c b/src/ssh/ssh-arch.c
index 8dc7e1d5a785dd1a4ac3b422a11e8f03a63a39f9..8c2a34c8cc2fa788ba4fc41f221e314bdba2ac8c 100644
--- a/src/ssh/ssh-arch.c
+++ b/src/ssh/ssh-arch.c
@@ -40,8 +40,10 @@ deuce_ssh_parse_boolean(uint8_t * buf, size_t bufsz, deuce_ssh_boolean_t *val)
 	assert(bufsz >= 1);
 	if (bufsz < 1)
 		return DEUCE_SSH_ERROR_PARSE;
+#ifdef PARANOID_WRONG
 	if (buf[0] != 0 && buf[0] != 1)
 		return DEUCE_SSH_ERROR_INVALID;
+#endif
 	*val = buf[0];
 	return 1;
 }
@@ -119,7 +121,7 @@ deuce_ssh_serialize_uint64(deuce_ssh_uint64_t val, uint8_t *buf, MAYBE_UNUSED si
 }
 
 ssize_t
-deuce_ssh_parse_string(uint8_t * buf, size_t bufsz, deuce_ssh_string_t *val)
+deuce_ssh_parse_string(uint8_t * buf, size_t bufsz, deuce_ssh_string_t val)
 {
 	ssize_t ret;
 	uint32_t len;
@@ -127,7 +129,6 @@ deuce_ssh_parse_string(uint8_t * buf, size_t bufsz, deuce_ssh_string_t *val)
 	size_t pos = 0;
 
 	assert(bufsz >= 4);
-	assert(*val == NULL);
 	if (bufsz < 4)
 		return DEUCE_SSH_ERROR_PARSE;
 	ret = deuce_ssh_parse_uint32(buf, bufsz, &len);
@@ -138,13 +139,8 @@ deuce_ssh_parse_string(uint8_t * buf, size_t bufsz, deuce_ssh_string_t *val)
 	assert(bufsz >= sz);
 	if (bufsz < sz)
 		return DEUCE_SSH_ERROR_PARSE;
-	*val = malloc(sz);
-	if (*val == NULL)
-		return DEUCE_SSH_ERROR_ALLOC;
-	(*val)->length = len;
-	deuce_ssh_serialize_uint32(len, (uint8_t *)*val, sz, &pos);
-	assert(pos == 4);
-	memcpy(&(*val)->value, &buf[pos], len);
+	val->length = len;
+	memcpy(&val->value, &buf[ret], len);
 	return sz;
 }
 
@@ -164,129 +160,83 @@ deuce_ssh_serialize_string(deuce_ssh_string_t val, uint8_t *buf, MAYBE_UNUSED si
 }
 
 ssize_t
-deuce_ssh_parse_mpint(uint8_t * buf, size_t bufsz, deuce_ssh_mpint_t *val)
+deuce_ssh_parse_mpint(uint8_t * buf, size_t bufsz, deuce_ssh_mpint_t val)
 {
-	size_t ret;
-	uint32_t len;
-	size_t sz;
-	size_t pos = 0;
-
-	assert(bufsz >= 4);
-	assert(*val == NULL);
-	if (bufsz < 4)
-		return DEUCE_SSH_ERROR_PARSE;
-	ret = deuce_ssh_parse_uint32(buf, bufsz, &len);
-	if (ret < 4)
-		return ret;
-	assert(ret == 4);
-	sz = ret + len;
-	assert(bufsz >= sz);
-	if (bufsz < sz)
-		return DEUCE_SSH_ERROR_PARSE;
-	*val = BN_mpi2bn(buf, sz, NULL);
-	return sz;
+	ssize_t ret = deuce_ssh_parse_string(buf, bufsz, val);
+	if (val->value[0] == val->value[1])
+		return DEUCE_SSH_ERROR_INVALID;
+	if ((val->value[0] == 0) && ((val->value[0] & 0x80) == 0))
+		return DEUCE_SSH_ERROR_INVALID;
+	if ((val->value[0] == 255) && (val->value[0] & 0x80))
+		return DEUCE_SSH_ERROR_INVALID;
+	return ret;
 }
 
 size_t
 deuce_ssh_serialized_mpint_length(deuce_ssh_mpint_t val)
 {
-	int ret = BN_bn2mpi(val, NULL);
-	assert(ret >= 4);
-	return ret;
+	return val->length + 4;
 }
 
 void
 deuce_ssh_serialize_mpint(deuce_ssh_mpint_t val, uint8_t *buf, MAYBE_UNUSED size_t bufsz, size_t *pos)
 {
-	assert(*pos + 4 <= bufsz);
-	*pos += BN_bn2mpi(val, &buf[*pos]);
+	deuce_ssh_serialize_string(val, buf, bufsz, pos);
 }
 
 ssize_t
-deuce_ssh_parse_namelist(uint8_t * buf, size_t bufsz, deuce_ssh_namelist_t *val)
+deuce_ssh_parse_namelist(uint8_t * buf, size_t bufsz, deuce_ssh_namelist_t val)
 {
-	deuce_ssh_string_t str = NULL;
-	size_t names = 0;
+	struct deuce_ssh_string str;
 
-	assert(*val == NULL);
 	ssize_t ret = deuce_ssh_parse_string(buf, bufsz, &str);
 	if (ret < 4)
 		return ret;
-	if (str->length > 0) {
-		names++;
-		for (size_t i = 0; i < str->length; i++) {
-			if (str->value[i] == ',') {
-				if (i == 0 || str->value[i - 1] == ',') {
-					free(str);
+	if (str.length > 0) {
+		for (uint32_t i = 0; i < str.length; i++) {
+			if (str.value[i] == ',') {
+				if (i == 0 || str.value[i - 1] == ',')
 					return DEUCE_SSH_ERROR_PARSE;
-				}
-				names++;
 			}
-			if (str->value[i] < ' ') {
-				free(str);
+			if (str.value[i] < ' ')
 				return DEUCE_SSH_ERROR_PARSE;
-			}
-			if (str->value[i] > '~') {
-				free(str);
+			if (str.value[i] > '~')
 				return DEUCE_SSH_ERROR_PARSE;
-			}
-		}
-	}
-	size_t lsz = sizeof(uint8_t *) * names;
-	*val = malloc(offsetof(struct deuce_ssh_namelist, name) + lsz + str->length + (names == 0 ? 0 : 1));
-	if (*val == NULL) {
-		free(str);
-		return DEUCE_SSH_ERROR_ALLOC;
-	}
-	(*val)->names = names;
-	if (names > 0) {
-		uint8_t *data = (uint8_t *)&(*val)->name[names];
-		memcpy(data, str->value, str->length);
-		data[str->length] = ',';
-		uint8_t *end = data;
-		size_t remain = str->length + 1;
-		for (size_t i = 0; i < names; i++) {
-			(*val)->name[i] = end;
-			end = memchr(end, ',', remain);
-			assert(end);
-			assert(*end == ',');
-			*end = 0;
-			end++;
-			remain = (str->length + 1) - (end - data);
 		}
 	}
+	val->value = str.value;
+	val->length = str.length;
+	val->next = 0;
 	return ret;
 }
 
 size_t
 deuce_ssh_serialized_namelist_length(deuce_ssh_namelist_t val)
 {
-	size_t ret = 4;
-	for (size_t i = 0; i < val->names; i++) {
-		ret += strlen((char *)val->name[i]);
-		if (i < (val->names - 1))
-			ret += 1;
-	}
-	return ret;
+	return val->length + 4;
 }
 
 void
 deuce_ssh_serialize_namelist(deuce_ssh_namelist_t val, uint8_t *buf, MAYBE_UNUSED size_t bufsz, size_t *pos)
 {
-	assert(bufsz >= 4);
+	struct deuce_ssh_string str = {
+		.value = val->value,
+		.length = val->length,
+	};
+	deuce_ssh_serialize_string(&str, buf, bufsz, pos);
+}
 
-	uint8_t *lbuf = buf;
-	size_t lpos = *pos;
-	*pos += 4;
-	uint8_t *data = (uint8_t *)&val->name[0];
-	size_t names = 0;
-	for (size_t i = 0;; i++) {
-		if (data[i] == 0) {
-			names++;
-			if (names == val->names)
-				break;
+ssize_t
+deuce_ssh_parse_namelist_next(deuce_ssh_string_t val, deuce_ssh_namelist_t nl)
+{
+	if (nl->next >= nl->length)
+		return DEUCE_SSH_ERROR_NOMORE;
+	val->value = &(nl->value[nl->next]);
+	for (val->length = 0; nl->next < nl->length; nl->next++, val->length++) {
+		if (nl->value[nl->next] == ',') {
+			nl->next++;
+			break;
 		}
-		buf[(*pos)++] = data[i];
 	}
-	deuce_ssh_serialize_uint32(*pos - lpos - 4, lbuf, 4, &lpos);
+	return val->length + 4;
 }
diff --git a/src/ssh/ssh-arch.h b/src/ssh/ssh-arch.h
index ca844688dd2dcb2044150d846e8fecbc18e9da38..17b1cc46e4913ae447896c4f9f1b8d22fbeea837 100644
--- a/src/ssh/ssh-arch.h
+++ b/src/ssh/ssh-arch.h
@@ -20,13 +20,14 @@ typedef bool deuce_ssh_boolean_t;
 typedef uint32_t deuce_ssh_uint32_t;
 typedef uint64_t deuce_ssh_uint64_t;
 typedef struct deuce_ssh_string {
+	deuce_ssh_byte_t *value;
 	deuce_ssh_uint32_t length;
-	deuce_ssh_byte_t value[];
 } *deuce_ssh_string_t;
-typedef BIGNUM *deuce_ssh_mpint_t;
+typedef struct deuce_ssh_string *deuce_ssh_mpint_t;
 typedef struct deuce_ssh_namelist {
-	size_t   names;
-	uint8_t *name[];
+	deuce_ssh_byte_t *value;
+	deuce_ssh_uint32_t length;
+	deuce_ssh_uint32_t next;
 } *deuce_ssh_namelist_t;
 
 #define deuce_ssh_parse(buf, bufsz, val) _Generic(val,                \
@@ -72,16 +73,17 @@ ssize_t deuce_ssh_parse_uint64(uint8_t * buf, size_t bufsz, deuce_ssh_uint64_t *
 size_t deuce_ssh_serialized_uint64_length(deuce_ssh_uint64_t val);
 void deuce_ssh_serialize_uint64(deuce_ssh_uint64_t val, uint8_t *buf, MAYBE_UNUSED size_t bufsz, size_t *pos);
 
-ssize_t deuce_ssh_parse_string(uint8_t * buf, size_t bufsz, deuce_ssh_string_t *val);
+ssize_t deuce_ssh_parse_string(uint8_t * buf, size_t bufsz, deuce_ssh_string_t val);
 size_t deuce_ssh_serialized_string_length(deuce_ssh_string_t val);
 void deuce_ssh_serialize_string(deuce_ssh_string_t val, uint8_t *buf, MAYBE_UNUSED size_t bufsz, size_t *pos);
 
-ssize_t deuce_ssh_parse_mpint(uint8_t * buf, size_t bufsz, deuce_ssh_mpint_t *val);
+ssize_t deuce_ssh_parse_mpint(uint8_t * buf, size_t bufsz, deuce_ssh_mpint_t val);
 size_t deuce_ssh_serialized_mpint_length(deuce_ssh_mpint_t val);
 void deuce_ssh_serialize_mpint(deuce_ssh_mpint_t val, uint8_t *buf, MAYBE_UNUSED size_t bufsz, size_t *pos);
 
-ssize_t deuce_ssh_parse_namelist(uint8_t * buf, size_t bufsz, deuce_ssh_namelist_t *val);
+ssize_t deuce_ssh_parse_namelist(uint8_t * buf, size_t bufsz, deuce_ssh_namelist_t val);
 size_t deuce_ssh_serialized_namelist_length(deuce_ssh_namelist_t val);
 void deuce_ssh_serialize_namelist(deuce_ssh_namelist_t val, uint8_t *buf, MAYBE_UNUSED size_t bufsz, size_t *pos);
+ssize_t deuce_ssh_parse_namelist_next(deuce_ssh_string_t val, deuce_ssh_namelist_t nl);
 
 #endif