diff --git a/CMakeLists.txt b/CMakeLists.txt
index c7d4c52de638045ca973e776bfeafb93458b49a6..e7e2819410c0abcb2aaf8b877031adb2e6449bab 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -605,7 +605,9 @@ set(HDR_PRIVATE
 
 set(HDR_PUBLIC
 	"${PROJECT_SOURCE_DIR}/lib/libwebsockets.h"
-	"${PROJECT_BINARY_DIR}/lws_config.h")
+	"${PROJECT_BINARY_DIR}/lws_config.h"
+	"${PROJECT_SOURCE_DIR}/plugins/ssh-base/include/lws-plugin-ssh.h"
+	)
 
 set(SOURCES
 	lib/base64-decode.c
@@ -1153,6 +1155,8 @@ set(CMAKE_REQUIRED_LIBRARIES ${LIB_LIST})
 CHECK_FUNCTION_EXISTS(SSL_CTX_set1_param LWS_HAVE_SSL_CTX_set1_param)
 CHECK_FUNCTION_EXISTS(SSL_set_info_callback LWS_HAVE_SSL_SET_INFO_CALLBACK)
 CHECK_FUNCTION_EXISTS(X509_VERIFY_PARAM_set1_host LWS_HAVE_X509_VERIFY_PARAM_set1_host)
+CHECK_FUNCTION_EXISTS(RSA_set0_key LWS_HAVE_RSA_SET0_KEY)
+
 if (LWS_USE_MBEDTLS)
 	set(LWS_HAVE_TLS_CLIENT_METHOD 1)
 	if (NOT LWS_WITH_ESP32)
@@ -1363,6 +1367,18 @@ if (NOT LWS_WITHOUT_TESTAPPS)
 				""
 				""
 				"")
+
+			if (LWS_WITH_CGI)
+			create_test_app(test-sshd "test-apps/test-sshd.c"
+				""
+				""
+				""
+				""
+				"")
+			target_include_directories(test-sshd PRIVATE "${PROJECT_SOURCE_DIR}/plugins/ssh-base/include")
+
+			endif()
+
 			if (UNIX)
 				create_test_app(test-fuzxy "test-apps/fuzxy.c"
 					""
@@ -1508,7 +1524,7 @@ if (NOT LWS_WITHOUT_TESTAPPS)
 	
 	
 	if (LWS_WITH_PLUGINS AND LWS_WITH_SHARED)
-		macro(create_plugin PLUGIN_NAME MAIN_SRC S2 S3)
+		macro(create_plugin PLUGIN_NAME PLUGIN_INCLUDE MAIN_SRC S2 S3)
 
 		set(PLUGIN_SRCS ${MAIN_SRC})
 
@@ -1540,6 +1556,7 @@ if (NOT LWS_WITHOUT_TESTAPPS)
 		
 		target_link_libraries(${PLUGIN_NAME} websockets_shared)
 		add_dependencies(${PLUGIN_NAME} websockets_shared)
+		include_directories(${PLUGIN_INCLUDE})
 
 		# Set test app specific defines.
 		set_property(TARGET ${PLUGIN_NAME}
@@ -1556,35 +1573,42 @@ if (NOT LWS_WITHOUT_TESTAPPS)
 		endmacro()
 		
 
-		create_plugin(protocol_lws_meta
+		create_plugin(protocol_lws_meta ""
 			      "plugins/protocol_lws_meta.c" "" "")
-		create_plugin(protocol_dumb_increment
+		create_plugin(protocol_dumb_increment ""
 			      "plugins/protocol_dumb_increment.c" "" "")
-		create_plugin(protocol_lws_mirror
+		create_plugin(protocol_lws_mirror ""
 			      "plugins/protocol_lws_mirror.c" "" "")
-		create_plugin(protocol_lws_status
+		create_plugin(protocol_lws_status ""
 			      "plugins/protocol_lws_status.c" "" "")
-		create_plugin(protocol_post_demo
+		create_plugin(protocol_post_demo ""
 			      "plugins/protocol_post_demo.c" "" "")
-		create_plugin(protocol_lws_table_dirlisting
+		create_plugin(protocol_lws_table_dirlisting ""
 			      "plugins/generic-table/protocol_table_dirlisting.c" "" "")
+		create_plugin(protocol_lws_ssh_base "plugins/ssh-base/include"
+			      "plugins/ssh-base/sshd.c;plugins/ssh-base/telnet.c;plugins/ssh-base/kex-25519.c" "plugins/ssh-base/crypto/chacha.c;plugins/ssh-base/crypto/ed25519.c;plugins/ssh-base/crypto/fe25519.c;plugins/ssh-base/crypto/ge25519.c;plugins/ssh-base/crypto/poly1305.c;plugins/ssh-base/crypto/sc25519.c;plugins/ssh-base/crypto/smult_curve25519_ref.c" "")
+		create_plugin(protocol_lws_sshd_demo "plugins/ssh-base/include" "plugins/protocol_lws_sshd_demo.c" "" "")
+
+
+		include_directories("${PROJECT_SOURCE_DIR}/plugins/ssh-base/include")
+
 		if (NOT WIN32)
-      		      create_plugin(protocol_lws_raw_test
+			create_plugin(protocol_lws_raw_test ""
 			      "plugins/protocol_lws_raw_test.c" "" "")
 		endif()
 
 if (LWS_WITH_SERVER_STATUS)
-		create_plugin(protocol_lws_server_status
+		create_plugin(protocol_lws_server_status ""
 			      "plugins/protocol_lws_server_status.c" "" "")
 endif()
 
 if (NOT LWS_WITHOUT_CLIENT)
-		create_plugin(protocol_client_loopback_test
+		create_plugin(protocol_client_loopback_test ""
                               "plugins/protocol_client_loopback_test.c" "" "")
 endif(NOT LWS_WITHOUT_CLIENT)
 
 if (LWS_WITH_GENERIC_SESSIONS)
-	create_plugin(protocol_generic_sessions
+	create_plugin(protocol_generic_sessions ""
                       "plugins/generic-sessions/protocol_generic_sessions.c"
 		      "plugins/generic-sessions/utils.c"
 		      "plugins/generic-sessions/handlers.c")
@@ -1595,7 +1619,7 @@ if (LWS_WITH_GENERIC_SESSIONS)
 		target_link_libraries(protocol_generic_sessions sqlite3 )
 	endif(WIN32)
 
-		create_plugin(protocol_lws_messageboard
+		create_plugin(protocol_lws_messageboard ""
 			      "plugins/generic-sessions/protocol_lws_messageboard.c" "" "")
 	if (WIN32)
 		target_link_libraries(protocol_lws_messageboard ${LWS_SQLITE3_LIBRARIES})
@@ -1802,6 +1826,10 @@ if (LWS_WITH_CGI)
 	endif()
 endif()
 
+install(FILES test-apps/lws-ssh-test-keys;test-apps/lws-ssh-test-keys.pub
+	DESTINATION share/libwebsockets-test-server
+	COMPONENT examples)
+
 # plugins
 
 if (LWS_WITH_PLUGINS)
@@ -1907,6 +1935,7 @@ message(" LWS_MAX_SMP = ${LWS_MAX_SMP}")
 message(" LWS_WITH_CGI = ${LWS_WITH_CGI}")
 message(" LWS_HAVE_OPENSSL_ECDH_H = ${LWS_HAVE_OPENSSL_ECDH_H}")
 message(" LWS_HAVE_SSL_CTX_set1_param = ${LWS_HAVE_SSL_CTX_set1_param}")
+message(" LWS_HAVE_RSA_SET0_KEY = ${LWS_HAVE_RSA_SET0_KEY}")
 message(" LWS_WITH_HTTP_PROXY = ${LWS_WITH_HTTP_PROXY}")
 message(" LIBHUBBUB_LIBRARIES = ${LIBHUBBUB_LIBRARIES}")
 message(" PLUGINS = ${PLUGINS_LIST}")
diff --git a/READMEs/README-plugin-sshd-base.md b/READMEs/README-plugin-sshd-base.md
new file mode 100644
index 0000000000000000000000000000000000000000..65d67f827341f1efd5cbd7aa75a4a3a896ff03b3
--- /dev/null
+++ b/READMEs/README-plugin-sshd-base.md
@@ -0,0 +1,250 @@
+ssh-base Plugin
+================
+
+## Introduction
+
+lws-ssh-base is a protcol plugin for libwebsockets that implements a
+generic, abstract, ssh server.
+
+ - very small footprint in code and memory, takes up small part of ESP32
+ 
+ - written with security in mind: valgrind and Coverity -clean
+ 
+ - binds to one or more vhosts, that controls listen port(s)
+ 
+ - all IO and settings abstracted through a single "ops" struct from user code
+ 
+ - each instance on a vhost has its own "ops" struct, defining server keys,
+   auth method and functions to implement IO and other operations
+
+ - The plugin has no built-in behaviours like check ~/.ssh/authorized_keys,
+   treat auth usernames as system usernames, or spawn the user's shell.
+   Everything potentially dangerous is left to the user ops code to decide
+   how to handle.  It's NOT like sshd where running it implies it will accept
+   existing keys for any system user, will spawn a shell, etc, unless you
+   implement those parts in the ops callbacks.
+   
+ - The plugin requires extra code around it in the form of the ops struct
+   handlers.  So it's role is something like an abstract base class for an ssh
+   server.  All the crypto, protocol sequencing and state machine are inside,
+   but all the IO except the network connection is outside.
+   
+ - Built as part of libwebsockets, like all plugins may be dynamically loaded
+   at runtime or built statically.  Test app `libwebsockets-test-sshd` provided
+   
+ - Uses hash and RSA functions from either mbedTLS or OpenSSL automatically,
+   according to which library libwebsockets was built for
+
+To maintain its small size, it implements a single "best of breed" crypto for
+the following functions:
+
+|Function|Crypto|
+|---|---|
+|KEX|curve25519-sha256@libssh.org|
+|Server host key|ssh-rsa (4096b)|
+|Encryption|chacha20-poly1305@openssh.com|
+|Compression|None|
+
+## License
+
+lws-ssh-base is Free Software, available under libwebsocket's LGPLv2 +
+static linking exception license.
+
+The crypto parts are available elsewhere under a BSD license.  But for
+simplicity the whole plugin is under LGPLv2.
+
+## Generating your own keys
+
+```
+ $ ssh-keygen -t rsa -b 4096 -f mykeys
+```
+
+will ask for a passphrase and generate the private key in `mykeys` and the
+public key in `mykeys.pub`.  If you already have a suitable RSA key you use
+with ssh, you can just use that directly.
+
+lws installs a test keypair in /usr[/local]/share/libwebsockets-test-server
+that the test apps will accept.
+
+## Example code
+
+1) There's a working example app `libwebsockets-test-sshd` included that
+spawns a bash shell when an ssh client authenticates.  The username used on
+the remote ssh has no meaning, it spawns the shell under the credentials of
+"lws-test-sshd" was run under.  It accepts the lws ssh test key which is
+installed into /usr[/local]/share/libwebsockets-test-server.
+
+Start the server like this (it wants root only because the server key is stored
+in /etc)
+
+```
+ $ sudo libwebsockets-test-sshd
+```
+
+Connect to it using the test private key like this
+
+```
+ $ ssh -p 2200 -i /usr/local/share/libwebsockets-test-server/lws-ssh-test-keys anyuser@127.0.0.1
+```
+
+2) There's also a working example plugin `lws-sshd-demo` that "subclasses" the
+abstract `lws-ssh-base` plugin to make a protocol which can be used from,
+eg, lwsws.  For an lwsws vhost that listens on port 2222 and responds with
+the lws-sshd-demo ssh server, the related config is:
+
+```
+        {
+                "name": "sshd",
+                "port": "2222",
+                "onlyraw": "1",
+                "ws-protocols": [{
+                        "lws-ssh-base": {
+                                "status": "ok",
+                                "ops-from": "lws-sshd-demo"
+                        },
+                        "lws-sshd-demo": {
+                                "status": "ok",
+                                "raw": "1"
+                        }
+                }]
+        }
+```
+
+
+
+## Integration to other apps
+
+### Step 0: Build and install libwebsockets
+
+For the `libwebsockets-test-sshd` example, you will need CMake options
+`LWS_WITH_CGI`, since it uses lws helpers to spawn a shell.
+
+lws-ssh-base itself doesn't require CGI support in libwebsockets.
+
+### Step 1: make the code available in your app
+
+Include `lws-plugin-ssh-base` in your app, either as a runtime plugin or by using
+the lws static include scheme.
+
+To bring in the whole of the ssh-base plugin
+into your app in one step, statically, just include
+`plugins/ssh-base/include/lws-plugin-sshd-static-build-includes.h`, you can see
+an example of this in `./test-apps/test-sshd.c`.
+
+### Step 2: define your `struct lws_ssh_ops`
+
+`plugins/ssh-base/include/lws-plugin-ssh.h` defines
+`struct lws_ssh_ops` which is used for all customization and integration
+of the plugin per vhost.  Eg,
+
+```
+static const struct lws_ssh_ops ssh_ops = {
+	.channel_create			= ssh_ops_channel_create,
+	.channel_destroy		= ssh_ops_channel_destroy,
+	.tx_waiting			= ssh_ops_tx_waiting,
+	.tx				= ssh_ops_tx,
+	.rx				= ssh_ops_rx,
+	.get_server_key			= ssh_ops_get_server_key,
+	.set_server_key			= ssh_ops_set_server_key,
+	.set_env			= ssh_ops_set_env,
+	.pty_req			= ssh_ops_pty_req,
+	.child_process_io		= ssh_ops_child_process_io,
+	.child_process_terminated	= ssh_ops_child_process_terminated,
+	.exec				= ssh_ops_exec,
+	.shell				= ssh_ops_shell,
+	.is_pubkey_authorized		= ssh_ops_is_pubkey_authorized,
+	.banner				= ssh_ops_banner,
+	.disconnect_reason		= ssh_ops_disconnect_reason,
+	.server_string			= "SSH-2.0-Libwebsockets",
+	.api_version			= 1,
+};
+```
+The `ssh_ops_...()` functions are your implementations for the operations
+needed by the plugin for your purposes.
+
+### Step 3: enable `lws-ssh-base` protocol to a vhost and configure using pvo
+
+A pointer to your struct lws_ssh_ops is passed into the vhost instance of the
+protocol using per-vhost options
+
+```
+static const struct lws_protocol_vhost_options pvo_ssh_ops = {
+	NULL,
+	NULL,
+	"ops",
+	(void *)&ssh_ops
+};
+
+static const struct lws_protocol_vhost_options pvo_ssh = {
+	NULL,
+	&pvo_ssh_ops,
+	"lws-sshd-base",
+	"" /* ignored, just matches the protocol name above */
+};
+
+...
+	info.port = 22;
+	info.options = LWS_SERVER_OPTION_ONLY_RAW;
+	info.vhost_name = "sshd";
+	info.protocols = protocols_sshd;
+	info.pvo = &pvo_ssh;
+
+	vh_sshd = lws_create_vhost(context, &info);
+```
+
+There are two possible pvos supported, "ops", shown above, directly passes the
+ops structure in using the value on the "ops" pvo.
+
+To support other protocols that want to provide ops to lws-ssh-base themselves
+for a particular vhost, you can also provide a pvo `"ops-from"` whose value is
+the name of the protocol also enabled on this vhost, whose protocol ".user"
+pointer points to the ops struct lws-ssh-base should use.
+
+## Integration to other plugins
+
+A worked example of using the abstract `lws-ssh-base` plugin from another
+plugin that provides the ops struct is in `./plugins/protocol_lws_sshd_demo`.
+
+The key points to note
+
+ - the plugin sets the ops struct for the vhost instantiation of `lws-ssh-base`
+ by passing a pointer to the ops struct in its `lws_protocols` struct `user`
+ member.
+ 
+ - the config for the vhost tells `lws-ssh-base` to pick up the ops struct
+ pointer using an "ops-from" pvo that indicates the protocol name.
+ 
+```
+ 			"lws-ssh-base": {
+                                "status": "ok",
+                                "ops-from": "lws-sshd-demo"
+                        },
+```
+
+ - the config for the vhost tells lws this vhost only serves RAW (ie, no http)
+ 
+```
+         {
+                "name": "sshd",
+                "port": "2222",
+                "onlyraw": "1",
+                ...
+```
+
+ - the config for the vhost marks the protocol that uses `lws-ssh-base`, not
+ `lws-ssh-base` itself, as the protocol to be served for raw connections
+
+```
+                        "lws-sshd-demo": {
+                                "status": "ok",
+                                "raw": "1"
+                         ...
+```
+
+## Notes
+
+You can have the vhost it binds to listen on a nonstandard port.  The ssh
+commandline app cane be told to connect to a non-22 port with
+`ssh -p portnum user@hostname`
+
+
diff --git a/READMEs/README.lwsws.md b/READMEs/README.lwsws.md
index df0a8788ac47e81f750d202b672fd2c75b09929c..33f7f721d44b1526fd420ecf18cee2e1bba03864 100644
--- a/READMEs/README.lwsws.md
+++ b/READMEs/README.lwsws.md
@@ -196,6 +196,18 @@ by the client, you can use "default": "1"
 	     }]
 ```
 
+Similarly, if your vhost is serving a raw protocol, you can mark the protocol
+to be selected using "raw": "1"
+```
+	     "ws-protocols": [{
+	       "warmcat-timezoom": {
+	         "status": "ok",
+	         "raw": "1"
+	       }
+	     }]
+```
+
+See also "rawonly" below.
 
 @section lwswsovo Lwsws Other vhost options
 
@@ -257,6 +269,8 @@ recommended vhost headers for good client security are
 
 ```
 
+ - "`rawonly`": "on"  This vhost only serves a raw protocol, disable HTTP on it
+
 @section lwswsm Lwsws Mounts
 
 Where mounts are given in the vhost definition, then directory contents may
@@ -590,7 +604,7 @@ this will give nice backtraces in lwsws itself and in plugins, if they were buil
 
 @section lwswsvgd Running lwsws under valgrind
 
-You can just run lwsws under galgrind as usual and get valid results.  However the results / analysis part of valgrind runs
+You can just run lwsws under valgrind as usual and get valid results.  However the results / analysis part of valgrind runs
 after the plugins have removed themselves, this means valgrind backtraces into plugin code is opaque, without
 source-level info because the dynamic library is gone.
 
diff --git a/cmake/lws_config.h.in b/cmake/lws_config.h.in
index 3f2488abc3a8c3f8285cd31d2ead4cc65b29443a..851bc388945d1e73ddd62085e90f4f133187f72b 100644
--- a/cmake/lws_config.h.in
+++ b/cmake/lws_config.h.in
@@ -92,6 +92,7 @@
 #cmakedefine LWS_SSL_SERVER_WITH_ECDH_CERT
 #cmakedefine LWS_HAVE_SSL_CTX_set1_param
 #cmakedefine LWS_HAVE_X509_VERIFY_PARAM_set1_host
+#cmakedefine LWS_HAVE_RSA_SET0_KEY
 
 #cmakedefine LWS_HAVE_UV_VERSION_H
 
diff --git a/lib/context.c b/lib/context.c
index 9c0073a1dcc1cbad99ade71a29a6b72d39e388e1..419567699cdbeb249ed5b27b0a82897e39694409 100644
--- a/lib/context.c
+++ b/lib/context.c
@@ -482,6 +482,9 @@ lws_create_vhost(struct lws_context *context,
 	else
 		vh->name = info->vhost_name;
 
+	if (info->options & LWS_SERVER_OPTION_ONLY_RAW)
+		lwsl_info("%s set to only support RAW\n", vh->name);
+
 	vh->iface = info->iface;
 #if !defined(LWS_WITH_ESP8266) && !defined(LWS_WITH_ESP32) && !defined(OPTEE_TA) && !defined(WIN32)
 	vh->bind_iface = info->bind_iface;
diff --git a/lib/lejp-conf.c b/lib/lejp-conf.c
index 3a1586deed99a633c932fbade44cf9f3c01b3ab6..185e663b340ff56c24e017ed72d690ee358d55f9 100644
--- a/lib/lejp-conf.c
+++ b/lib/lejp-conf.c
@@ -99,6 +99,7 @@ static const char * const paths_vhosts[] = {
 	"vhosts[].client-ssl-cert",
 	"vhosts[].client-ssl-ca",
 	"vhosts[].client-ssl-ciphers",
+	"vhosts[].onlyraw",
 };
 
 enum lejp_vhost_paths {
@@ -145,6 +146,7 @@ enum lejp_vhost_paths {
 	LEJPVP_CLIENT_SSL_CERT,
 	LEJPVP_CLIENT_SSL_CA,
 	LEJPVP_CLIENT_CIPHERS,
+	LEJPVP_FLAG_ONLYRAW,
 };
 
 static const char * const parser_errs[] = {
@@ -356,7 +358,7 @@ lejp_vhosts_cb(struct lejp_ctx *ctx, char reason)
 		a->info->keepalive_timeout = 5;
 		a->info->log_filepath = NULL;
 		a->info->options &= ~(LWS_SERVER_OPTION_UNIX_SOCK |
-				      LWS_SERVER_OPTION_STS);
+				      LWS_SERVER_OPTION_STS | LWS_SERVER_OPTION_ONLY_RAW);
 		a->enable_client_ssl = 0;
 	}
 
@@ -666,6 +668,13 @@ lejp_vhosts_cb(struct lejp_ctx *ctx, char reason)
 			a->info->options &= ~(LWS_SERVER_OPTION_DISABLE_IPV6);
 		return 0;
 
+	case LEJPVP_FLAG_ONLYRAW:
+		if (arg_to_bool(ctx->buf))
+			a->info->options |= LWS_SERVER_OPTION_ONLY_RAW;
+		else
+			a->info->options &= ~(LWS_SERVER_OPTION_ONLY_RAW);
+		return 0;
+
 	case LEJPVP_IPV6ONLY:
 		a->info->options |= LWS_SERVER_OPTION_IPV6_V6ONLY_MODIFY;
 		if (arg_to_bool(ctx->buf))
diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c
index 7c7b3aaddfa158b2e31b6d9e68181e637ff43404..60d0bbc0f27a6d08bbdfbe5fc5c8d8bfa63b2aa3 100755
--- a/lib/libwebsockets.c
+++ b/lib/libwebsockets.c
@@ -90,6 +90,9 @@ lws_free_wsi(struct lws *wsi)
 	lws_header_table_force_to_detachable_state(wsi);
 	lws_header_table_detach(wsi, 0);
 
+	if (wsi->vhost->lserv_wsi == wsi)
+		wsi->vhost->lserv_wsi = NULL;
+
 	lws_pt_lock(pt);
 	for (n = 0; n < wsi->context->max_http_header_pool; n++) {
 		if (pt->ah_pool[n].in_use &&
@@ -1520,8 +1523,6 @@ lws_get_reserved_bits(struct lws *wsi)
 int
 lws_ensure_user_space(struct lws *wsi)
 {
-	lwsl_debug("%s: %p protocol %p\n", __func__, wsi, wsi->protocol);
-
 	if (!wsi->protocol)
 		return 1;
 
@@ -1540,6 +1541,18 @@ lws_ensure_user_space(struct lws *wsi)
 	return 0;
 }
 
+LWS_VISIBLE void *
+lws_adjust_protocol_psds(struct lws *wsi, size_t new_size)
+{
+	((struct lws_protocols *)lws_get_protocol(wsi))->per_session_data_size =
+		new_size;
+
+	if (lws_ensure_user_space(wsi))
+			return NULL;
+
+	return wsi->user_space;
+}
+
 LWS_VISIBLE int
 lwsl_timestamp(int level, char *p, int len)
 {
@@ -3975,7 +3988,6 @@ lws_ring_consume(struct lws_ring *ring, uint32_t *tail, void *dest,
 
 		return n / ring->element_len;
 	}
-
 	if (*tail + n > ring->buflen) {
 
 		/*
@@ -4003,6 +4015,18 @@ lws_ring_consume(struct lws_ring *ring, uint32_t *tail, void *dest,
 	return (((uint8_t *)dest + n) - odest) / ring->element_len;
 }
 
+LWS_VISIBLE LWS_EXTERN const void *
+lws_ring_get_element(struct lws_ring *ring, uint32_t *tail)
+{
+	if (!tail)
+		tail = &ring->oldest_tail;
+
+	if (*tail == ring->head)
+		return NULL;
+
+	return ((uint8_t *)ring->buf) + *tail;
+}
+
 LWS_VISIBLE LWS_EXTERN void
 lws_ring_update_oldest_tail(struct lws_ring *ring, uint32_t tail)
 {
diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h
index 0d01418207fe41f8f3ad48b5943341723e81e7f1..6efa7457f0e937d16286ec15d627e724df2aa76b 100644
--- a/lib/libwebsockets.h
+++ b/lib/libwebsockets.h
@@ -1845,6 +1845,23 @@ lws_protocol_vh_priv_zalloc(struct lws_vhost *vhost, const struct lws_protocols
 LWS_VISIBLE LWS_EXTERN void *
 lws_protocol_vh_priv_get(struct lws_vhost *vhost, const struct lws_protocols *prot);
 
+/**
+ * lws_adjust_protocol_psds - change a vhost protocol's per session data size
+ *
+ * \param wsi: a connection with the protocol to change
+ * \param new_size: the new size of the per session data size for the protocol
+ *
+ * Returns user_space for the wsi, after allocating
+ *
+ * This should not be used except to initalize a vhost protocol's per session
+ * data size one time, before any connections are accepted.
+ *
+ * Sometimes the protocol wraps another protocol and needs to discover and set
+ * its per session data size at runtime.
+ */
+LWS_VISIBLE LWS_EXTERN void *
+lws_adjust_protocol_psds(struct lws *wsi, size_t new_size);
+
 /**
  * lws_finalize_startup() - drop initial process privileges
  *
@@ -4743,18 +4760,44 @@ lws_ring_insert(struct lws_ring *ring, const void *src, size_t max_count);
  *
  * \param ring: the struct lws_ring to report on
  * \param tail: a pointer to the tail struct to use, or NULL for single tail
- * \param dest: the array of elements to be inserted
+ * \param dest: the array of elements to be inserted. or NULL for no copy
  * \param max_count: the number of available elements at src
  *
  * Attempts to copy out as many waiting elements as possible into dest, from
- * the perspective of the given tail, up to max_count.
+ * the perspective of the given tail, up to max_count.  If dest is NULL, the
+ * copying out is not done but the elements are logically consumed as usual.
+ * NULL dest is useful in combination with lws_ring_get_element(), where you
+ * can use the element direct from the ringbuffer and then call this with NULL
+ * dest to logically consume it.
+ *
+ * Increments the tail position according to how many elements could be
+ * consumed.
  *
- * Returns the number of elements copied out.
+ * Returns the number of elements consumed.
  */
 LWS_VISIBLE LWS_EXTERN size_t
 lws_ring_consume(struct lws_ring *ring, uint32_t *tail, void *dest,
 		 size_t max_count);
 
+/**
+ * lws_ring_get_element():  get a pointer to the next waiting element for tail
+ *
+ * \param ring: the struct lws_ring to report on
+ * \param tail: a pointer to the tail struct to use, or NULL for single tail
+ *
+ * Points to the next element that tail would consume, directly in the
+ * ringbuffer.  This lets you write() or otherwise use the element without
+ * having to copy it out somewhere first.
+ *
+ * After calling this, you must call lws_ring_consume(ring, &tail, NULL, 1)
+ * which will logically consume the element you used up and increment your
+ * tail (tail may also be NULL there if you use a single tail).
+ *
+ * Returns NULL if no waiting element, or a const void * pointing to it.
+ */
+LWS_VISIBLE LWS_EXTERN const void *
+lws_ring_get_element(struct lws_ring *ring, uint32_t *tail);
+
 /**
  * lws_ring_update_oldest_tail():  free up elements older than tail for reuse
  *
diff --git a/lib/server.c b/lib/server.c
index 256574ac9b3f099143f0062a8bdd6af8ff627d29..9a0fbb5fef25673f0d150431416323d0fed6cc50 100644
--- a/lib/server.c
+++ b/lib/server.c
@@ -2817,6 +2817,8 @@ try_pollout:
 
 			if (!(wsi->vhost->options & LWS_SERVER_OPTION_ONLY_RAW))
 				opts |= LWS_ADOPT_HTTP;
+			else
+				opts = LWS_ADOPT_SOCKET;
 
 			fd.sockfd = accept_fd;
 			if (!lws_adopt_descriptor_vhost(wsi->vhost, opts, fd,
diff --git a/lib/ssl-client.c b/lib/ssl-client.c
index 0b7f24d2f9226edf8346d51f2c48c30682302826..be96a0e5dcbd36a0980c7bf57b33f26f56a967dc 100644
--- a/lib/ssl-client.c
+++ b/lib/ssl-client.c
@@ -443,6 +443,9 @@ int lws_context_init_client_ssl(struct lws_context_creation_info *info,
 	const char *cert_filepath = info->ssl_cert_filepath;
 	int n;
 
+	if (vhost->options & LWS_SERVER_OPTION_ONLY_RAW)
+		return 0;
+
 	/*
 	 *  for backwards-compatibility default to using ssl_... members, but
 	 * if the newer client-specific ones are given, use those
diff --git a/plugins/protocol_lws_sshd_demo.c b/plugins/protocol_lws_sshd_demo.c
new file mode 100644
index 0000000000000000000000000000000000000000..db8164ac8516521370a9a71b3605810d95af8e74
--- /dev/null
+++ b/plugins/protocol_lws_sshd_demo.c
@@ -0,0 +1,473 @@
+/*
+ * ws protocol handler plugin for sshd demo
+ *
+ * Copyright (C) 2010-2017 Andy Green <andy@warmcat.com>
+ *
+ * This file is made available under the Creative Commons CC0 1.0
+ * Universal Public Domain Dedication.
+ *
+ * The person who associated a work with this deed has dedicated
+ * the work to the public domain by waiving all of his or her rights
+ * to the work worldwide under copyright law, including all related
+ * and neighboring rights, to the extent allowed by law. You can copy,
+ * modify, distribute and perform the work, even for commercial purposes,
+ * all without asking permission.
+ *
+ * These test plugins are intended to be adapted for use in your code, which
+ * may be proprietary.  So unlike the library itself, they are licensed
+ * Public Domain.
+ */
+
+#if !defined (LWS_PLUGIN_STATIC)
+#define LWS_DLL
+#define LWS_INTERNAL
+#include "../lib/libwebsockets.h"
+#endif
+
+#include <lws-ssh.h>
+
+#include <string.h>
+
+#define TEST_SERVER_KEY_PATH "/etc/lws-test-sshd-server-key"
+
+struct per_vhost_data__lws_sshd_demo {
+	const struct lws_protocols *ssh_base_protocol;
+	int privileged_fd;
+};
+
+/*
+ *  This is a copy of the lws ssh test public key, you can find it in
+ *  /usr[/local]/share/libwebsockets-test-server/lws-ssh-test-keys.pub
+ *  and the matching private key there too in .../lws-ssh-test-keys
+ *
+ *  If the vhost with this protocol is using localhost:2222, you can test with
+ *  the matching private key like this:
+ *
+ *  ssh -p 2222 -i /usr/local/share/libwebsockets-test-server/lws-ssh-test-keys anyuser@127.0.0.1
+ *
+ *  These keys are distributed for testing!  Don't use them on a real system
+ *  unless you want anyone with a copy of lws to access it.
+ */
+static const char *authorized_key =
+	"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCnWiP+c+kSD6Lk+C6NA9KruApa45sbt"
+	"94/dxT0bCITlAA/+PBk6mR1lwWgXYozOMdrHrqx34piqDyXnc4HabqCaOm/FrYhkCPL8z"
+	"a26PMYqteSosuwKv//5iT6ZWhNnsMwExBwtV6MIq0MxAeWqxRnYNWpNM8iN6sFzkdG/YF"
+	"dyHrIBTgwzM77NLCMl6GEkJErRCFppC2SwYxGa3BRrgUwX3LkV8HpMIaYHFo1Qgj7Scqm"
+	"HwS2R75SOqi2aOWDpKjznARg9JgzDWSQi4seBMV2oL0BTwJANSDf+p0sQLsaKGJhpVpBQ"
+	"yS2wUeyuGyytupWzEluQrajMZq52iotcogv5BfeulfTTFbJP4kuHOsSP0lsQ2lpMDQANS"
+	"HEvXxzHJLDLXM9gXJzwJ+ZiRt6R+bfmP1nfN3MiWtxcIbBanWwQK6xTCKBe4wPaKta5EU"
+	"6wsLPeakOIVzoeaOu/HsbtPZlwX0Mu/oUFcfKyKAhlkU15MOAIEfUPo8Yh52bWMlIlpZa"
+	"4xWbLMGw3GrsrPPdcsAauyqvY4/NjjWQbWhP1SuUfvv5709PIiOUjVKK2HUwmR1ouch6X"
+	"MQGXfMR1h1Wjvc+bkNs17gCIrQnFilAZLC3Sm3Opiz/4LO99Hw448G0RM2vQn0mJE46w"
+	"Eu/B10U6Jf4Efojhh1dk85BD1LTIb+N3Q== ssh-test-key@lws";
+
+enum states {
+	SSH_TEST_GREET,
+	SSH_TEST_PRESSED,
+	SSH_TEST_DONE,
+};
+
+static const char * const strings[] =
+	{
+		/* SSH_TEST_GREET */
+		"Thanks for logging to lws sshd server demo.\n\r"
+		"\n\r"
+		"This demo is very simple, it waits for you to press\n\r"
+		"a key, and acknowledges it.  Then press another key\n\r"
+		"and it will exit.  But actually that demos the basic\n\r"
+		"sshd functions underneath.  You can use the ops struct\n\r"
+		"members to add a pty / shell or whatever you want.\n\r"
+		"\n\r"
+		"Press a key...\n\r",
+
+		/* SSH_TEST_PRESSED */
+		"Thanks for pressing a key.  Press another to exit.\n\r",
+
+		/* SSH_TEST_DONE */
+		"Bye!\n\r"
+	};
+
+struct sshd_instance_priv {
+	struct lws *wsi;
+	enum states state;
+	const char *ptr;
+	int pos;
+	int len;
+};
+
+static void
+enter_state(struct sshd_instance_priv *priv, enum states state)
+{
+	priv->state = state;
+	priv->ptr = strings[state];
+	priv->pos = 0;
+	priv->len = strlen(priv->ptr);
+
+	lws_callback_on_writable(priv->wsi);
+}
+
+/* ops: channel lifecycle */
+
+static int
+ssh_ops_channel_create(struct lws *wsi, void **_priv)
+{
+	struct sshd_instance_priv *priv;
+
+	priv = malloc(sizeof(struct sshd_instance_priv));
+	*_priv = priv;
+	if (!priv)
+		return 1;
+
+	memset(priv, 0, sizeof(*priv));
+	priv->wsi = wsi;
+
+	return 0;
+}
+
+static int
+ssh_ops_channel_destroy(void *_priv)
+{
+	struct sshd_instance_priv *priv = _priv;
+
+	free(priv);
+
+	return 0;
+}
+
+/* ops: IO */
+
+static int
+ssh_ops_tx_waiting(void *_priv)
+{
+	struct sshd_instance_priv *priv = _priv;
+
+	if (priv->state == SSH_TEST_DONE &&
+	    priv->pos == priv->len)
+		return -1; /* exit */
+
+	if (priv->pos != priv->len)
+		return LWS_STDOUT;
+
+	return 0;
+}
+
+static size_t
+ssh_ops_tx(void *_priv, int stdch, uint8_t *buf, size_t len)
+{
+	struct sshd_instance_priv *priv = _priv;
+	size_t chunk = len;
+
+	if (stdch != LWS_STDOUT)
+		return 0;
+
+	if (priv->len - priv->pos < chunk)
+		chunk = priv->len - priv->pos;
+
+	if (!chunk)
+		return 0;
+
+	memcpy(buf, priv->ptr + priv->pos, chunk);
+	priv->pos += chunk;
+
+	if (priv->state == SSH_TEST_DONE && priv->pos == priv->len) {
+		/*
+		 * we are sending the last thing we want to send
+		 * before exiting.  Make it ask again at ssh_ops_tx_waiting()
+		 * and we will exit then, after this has been sent
+		 */
+		lws_callback_on_writable(priv->wsi);
+	}
+
+	return chunk;
+}
+
+
+static int
+ssh_ops_rx(void *_priv, struct lws *wsi, const uint8_t *buf, uint32_t len)
+{
+	struct sshd_instance_priv *priv = _priv;
+
+	if (priv->state < SSH_TEST_DONE)
+		enter_state(priv, priv->state + 1);
+	else
+		return -1;
+
+	return 0;
+}
+
+/* ops: storage for the (autogenerated) persistent server key */
+
+static size_t
+ssh_ops_get_server_key(struct lws *wsi, uint8_t *buf, size_t len)
+{
+	struct per_vhost_data__lws_sshd_demo *vhd =
+			(struct per_vhost_data__lws_sshd_demo *)
+			lws_protocol_vh_priv_get(lws_get_vhost(wsi),
+						 lws_get_protocol(wsi));
+	int n;
+
+	lseek(vhd->privileged_fd, 0, SEEK_SET);
+	n = read(vhd->privileged_fd, buf, len);
+	if (n < 0) {
+		lwsl_err("%s: read failed: %d\n", __func__, n);
+		n = 0;
+	}
+
+	return n;
+}
+
+static size_t
+ssh_ops_set_server_key(struct lws *wsi, uint8_t *buf, size_t len)
+{
+	struct per_vhost_data__lws_sshd_demo *vhd =
+			(struct per_vhost_data__lws_sshd_demo *)
+			lws_protocol_vh_priv_get(lws_get_vhost(wsi),
+						 lws_get_protocol(wsi));
+	int n;
+
+	n = write(vhd->privileged_fd, buf, len);
+	if (n < 0) {
+		lwsl_err("%s: read failed: %d\n", __func__, errno);
+		n = 0;
+	}
+
+	return n;
+}
+
+/* ops: auth */
+
+static int
+ssh_ops_is_pubkey_authorized(const char *username, const char *type,
+				 const uint8_t *peer, int peer_len)
+{
+	char *aps = NULL, *p, *ps;
+	int n = strlen(type), alen = 2048, ret = 2, len;
+	size_t s = 0;
+
+	lwsl_info("%s: checking pubkey for %s\n", __func__, username);
+
+	s = strlen(authorized_key) + 1;
+
+	aps = malloc(s);
+	if (!aps) {
+		lwsl_notice("OOM 1\n");
+		goto bail_p1;
+	}
+	memcpy(aps, authorized_key, s);
+
+	/* we only understand RSA */
+	if (strcmp(type, "ssh-rsa")) {
+		lwsl_notice("type is not ssh-rsa\n");
+		goto bail_p1;
+	}
+	p = aps;
+
+	if (strncmp(p, type, n)) {
+		lwsl_notice("lead-in string  does not match %s\n", type);
+		goto bail_p1;
+	}
+
+	p += n;
+	if (*p != ' ') {
+		lwsl_notice("missing space at end of lead-in\n");
+		goto bail_p1;
+	}
+
+	p++;
+	ps = malloc(alen);
+	if (!ps) {
+		lwsl_notice("OOM 2\n");
+		free(aps);
+		goto bail;
+	}
+	len = lws_b64_decode_string(p, ps, alen);
+	free(aps);
+	if (len < 0) {
+		lwsl_notice("key too big\n");
+		goto bail;
+	}
+
+	if (peer_len > len) {
+		lwsl_notice("peer_len %d bigger than decoded len %d\n",
+				peer_len, len);
+		goto bail;
+	}
+
+	/*
+	 * once we are past that, it's the same <len32>name
+	 * <len32>E<len32>N that the peer sends us
+	 */
+	if (memcmp(peer, ps, peer_len)) {
+		lwsl_info("factors mismatch\n");
+		goto bail;
+	}
+
+	lwsl_info("pubkey authorized\n");
+
+	ret = 0;
+bail:
+	free(ps);
+
+	return ret;
+
+bail_p1:
+	if (aps)
+		free(aps);
+
+	return 1;
+}
+
+static int
+ssh_ops_shell(void *_priv, struct lws *wsi)
+{
+	struct sshd_instance_priv *priv = _priv;
+
+	/* for this demo, we don't open a real shell */
+
+	enter_state(priv, SSH_TEST_GREET);
+
+	return 0;
+}
+
+/* ops: banner */
+
+static size_t
+ssh_ops_banner(char *buf, size_t max_len, char *lang, size_t max_lang_len)
+{
+	int n = snprintf(buf, max_len, "\n"
+		      " |\\---/|  lws-ssh Test Server\n"
+		      " | o_o |  SSH Terminal Server\n"
+		      "  \\_^_/   Copyright (C) 2017 Crash Barrier Ltd\n\n");
+
+	snprintf(lang, max_lang_len, "en/US");
+
+	return n;
+}
+
+static void
+ssh_ops_disconnect_reason(uint32_t reason, const char *desc,
+			  const char *desc_lang)
+{
+	lwsl_notice("DISCONNECT reason 0x%X, %s (lang %s)\n", reason, desc,
+		    desc_lang);
+}
+
+
+static const struct lws_ssh_ops ssh_ops = {
+	.channel_create			= ssh_ops_channel_create,
+	.channel_destroy		= ssh_ops_channel_destroy,
+	.tx_waiting			= ssh_ops_tx_waiting,
+	.tx				= ssh_ops_tx,
+	.rx				= ssh_ops_rx,
+	.get_server_key			= ssh_ops_get_server_key,
+	.set_server_key			= ssh_ops_set_server_key,
+	.set_env			= NULL,
+	.pty_req			= NULL,
+	.child_process_io		= NULL,
+	.child_process_terminated	= NULL,
+	.exec				= NULL,
+	.shell				= ssh_ops_shell,
+	.is_pubkey_authorized		= ssh_ops_is_pubkey_authorized,
+	.banner				= ssh_ops_banner,
+	.disconnect_reason		= ssh_ops_disconnect_reason,
+	.server_string			= "SSH-2.0-Libwebsockets",
+	.api_version			= 1,
+};
+
+static int
+callback_lws_sshd_demo(struct lws *wsi, enum lws_callback_reasons reason,
+		       void *user, void *in, size_t len)
+{
+	struct per_vhost_data__lws_sshd_demo *vhd =
+			(struct per_vhost_data__lws_sshd_demo *)
+			lws_protocol_vh_priv_get(lws_get_vhost(wsi),
+						 lws_get_protocol(wsi));
+
+	switch (reason) {
+	case LWS_CALLBACK_PROTOCOL_INIT:
+		vhd = lws_protocol_vh_priv_zalloc(lws_get_vhost(wsi),
+						  lws_get_protocol(wsi),
+				sizeof(struct per_vhost_data__lws_sshd_demo));
+		/*
+		 * During this we still have the privs / caps we were started
+		 * with.  So open an fd on the server key, either just for read
+		 * or for creat / trunc if doesn't exist.  This allows us to
+		 * deal with it down /etc/.. when just after this we will lose
+		 * the privileges needed to read / write /etc/...
+		 */
+		vhd->privileged_fd = open(TEST_SERVER_KEY_PATH, O_RDONLY);
+		if (vhd->privileged_fd == -1)
+			vhd->privileged_fd = open(TEST_SERVER_KEY_PATH,
+					O_CREAT | O_TRUNC | O_RDWR, 0600);
+		if (vhd->privileged_fd == -1) {
+			lwsl_err("%s: Can't open %s\n", __func__,
+				 TEST_SERVER_KEY_PATH);
+			return -1;
+		}
+		break;
+
+	case LWS_CALLBACK_PROTOCOL_DESTROY:
+		close(vhd->privileged_fd);
+		break;
+
+	default:
+		if (!vhd->ssh_base_protocol) {
+			vhd->ssh_base_protocol = lws_vhost_name_to_protocol(
+							lws_get_vhost(wsi),
+							"lws-ssh-base");
+			if (vhd->ssh_base_protocol)
+				user = lws_adjust_protocol_psds(wsi,
+				vhd->ssh_base_protocol->per_session_data_size);
+		}
+
+		if (vhd->ssh_base_protocol)
+			return vhd->ssh_base_protocol->callback(wsi, reason,
+								user, in, len);
+		else
+			lwsl_notice("can't find lws-ssh-base\n");
+		break;
+	}
+
+	return 0;
+}
+
+#define LWS_PLUGIN_PROTOCOL_LWS_SSHD_DEMO \
+	{ \
+		"lws-sshd-demo", \
+		callback_lws_sshd_demo, \
+		0, \
+		1024, /* rx buf size must be >= permessage-deflate rx size */ \
+		0, (void *)&ssh_ops, 0 \
+	}
+
+#if !defined (LWS_PLUGIN_STATIC)
+		
+static const struct lws_protocols protocols[] = {
+		LWS_PLUGIN_PROTOCOL_LWS_SSHD_DEMO
+};
+
+LWS_EXTERN LWS_VISIBLE int
+init_protocol_lws_sshd_demo(struct lws_context *context,
+			     struct lws_plugin_capability *c)
+{
+	if (c->api_magic != LWS_PLUGIN_API_MAGIC) {
+		lwsl_err("Plugin API %d, library API %d", LWS_PLUGIN_API_MAGIC,
+			 c->api_magic);
+		return 1;
+	}
+
+	c->protocols = protocols;
+	c->count_protocols = ARRAY_SIZE(protocols);
+	c->extensions = NULL;
+	c->count_extensions = 0;
+
+	return 0;
+}
+
+LWS_EXTERN LWS_VISIBLE int
+destroy_protocol_lws_sshd_demo(struct lws_context *context)
+{
+	return 0;
+}
+
+#endif
diff --git a/plugins/ssh-base/crypto/chacha.c b/plugins/ssh-base/crypto/chacha.c
new file mode 100644
index 0000000000000000000000000000000000000000..46d46cb818210ef1b9461f010feb55bf1e1c4418
--- /dev/null
+++ b/plugins/ssh-base/crypto/chacha.c
@@ -0,0 +1,367 @@
+/*
+chacha-merged.c version 20080118
+D. J. Bernstein
+Public domain.
+*/
+
+#include <libwebsockets.h>
+#include "lws-ssh.h"
+
+#include <string.h>
+
+struct chacha_ctx {
+	u_int input[16];
+};
+
+#define CHACHA_MINKEYLEN 	16
+#define CHACHA_NONCELEN		8
+#define CHACHA_CTRLEN		8
+#define CHACHA_STATELEN		(CHACHA_NONCELEN+CHACHA_CTRLEN)
+#define CHACHA_BLOCKLEN		64
+
+typedef unsigned char u8;
+typedef unsigned int u32;
+
+typedef struct chacha_ctx chacha_ctx;
+
+#define U8C(v) (v##U)
+#define U32C(v) (v##U)
+
+#define U8V(v) ((u8)(v) & U8C(0xFF))
+#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF))
+
+#define ROTL32(v, n) \
+  (U32V((v) << (n)) | ((v) >> (32 - (n))))
+
+#define U8TO32_LITTLE(p) \
+  (((u32)((p)[0])      ) | \
+   ((u32)((p)[1]) <<  8) | \
+   ((u32)((p)[2]) << 16) | \
+   ((u32)((p)[3]) << 24))
+
+#define U32TO8_LITTLE(p, v) \
+  do { \
+    (p)[0] = U8V((v)      ); \
+    (p)[1] = U8V((v) >>  8); \
+    (p)[2] = U8V((v) >> 16); \
+    (p)[3] = U8V((v) >> 24); \
+  } while (0)
+
+#define ROTATE(v,c) (ROTL32(v,c))
+#define XOR(v,w) ((v) ^ (w))
+#define PLUS(v,w) (U32V((v) + (w)))
+#define PLUSONE(v) (PLUS((v),1))
+
+#define QUARTERROUND(a,b,c,d) \
+  a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \
+  c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \
+  a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \
+  c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
+
+static const char sigma[16] = "expand 32-byte k";
+static const char tau[16] = "expand 16-byte k";
+
+void
+chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits)
+{
+  const char *constants;
+
+  x->input[4] = U8TO32_LITTLE(k + 0);
+  x->input[5] = U8TO32_LITTLE(k + 4);
+  x->input[6] = U8TO32_LITTLE(k + 8);
+  x->input[7] = U8TO32_LITTLE(k + 12);
+  if (kbits == 256) { /* recommended */
+    k += 16;
+    constants = sigma;
+  } else { /* kbits == 128 */
+    constants = tau;
+  }
+  x->input[8] = U8TO32_LITTLE(k + 0);
+  x->input[9] = U8TO32_LITTLE(k + 4);
+  x->input[10] = U8TO32_LITTLE(k + 8);
+  x->input[11] = U8TO32_LITTLE(k + 12);
+  x->input[0] = U8TO32_LITTLE(constants + 0);
+  x->input[1] = U8TO32_LITTLE(constants + 4);
+  x->input[2] = U8TO32_LITTLE(constants + 8);
+  x->input[3] = U8TO32_LITTLE(constants + 12);
+}
+
+void
+chacha_ivsetup(chacha_ctx *x, const u8 *iv, const u8 *counter)
+{
+  x->input[12] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 0);
+  x->input[13] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 4);
+  x->input[14] = U8TO32_LITTLE(iv + 0);
+  x->input[15] = U8TO32_LITTLE(iv + 4);
+}
+
+void
+chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes)
+{
+  u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
+  u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
+  u8 *ctarget = NULL;
+  u8 tmp[64];
+  u_int i;
+
+  if (!bytes) return;
+
+  j0 = x->input[0];
+  j1 = x->input[1];
+  j2 = x->input[2];
+  j3 = x->input[3];
+  j4 = x->input[4];
+  j5 = x->input[5];
+  j6 = x->input[6];
+  j7 = x->input[7];
+  j8 = x->input[8];
+  j9 = x->input[9];
+  j10 = x->input[10];
+  j11 = x->input[11];
+  j12 = x->input[12];
+  j13 = x->input[13];
+  j14 = x->input[14];
+  j15 = x->input[15];
+
+  for (;;) {
+    if (bytes < 64) {
+      for (i = 0;i < bytes;++i) tmp[i] = m[i];
+      m = tmp;
+      ctarget = c;
+      c = tmp;
+    }
+    x0 = j0;
+    x1 = j1;
+    x2 = j2;
+    x3 = j3;
+    x4 = j4;
+    x5 = j5;
+    x6 = j6;
+    x7 = j7;
+    x8 = j8;
+    x9 = j9;
+    x10 = j10;
+    x11 = j11;
+    x12 = j12;
+    x13 = j13;
+    x14 = j14;
+    x15 = j15;
+    for (i = 20;i > 0;i -= 2) {
+      QUARTERROUND( x0, x4, x8,x12)
+      QUARTERROUND( x1, x5, x9,x13)
+      QUARTERROUND( x2, x6,x10,x14)
+      QUARTERROUND( x3, x7,x11,x15)
+      QUARTERROUND( x0, x5,x10,x15)
+      QUARTERROUND( x1, x6,x11,x12)
+      QUARTERROUND( x2, x7, x8,x13)
+      QUARTERROUND( x3, x4, x9,x14)
+    }
+    x0 = PLUS(x0,j0);
+    x1 = PLUS(x1,j1);
+    x2 = PLUS(x2,j2);
+    x3 = PLUS(x3,j3);
+    x4 = PLUS(x4,j4);
+    x5 = PLUS(x5,j5);
+    x6 = PLUS(x6,j6);
+    x7 = PLUS(x7,j7);
+    x8 = PLUS(x8,j8);
+    x9 = PLUS(x9,j9);
+    x10 = PLUS(x10,j10);
+    x11 = PLUS(x11,j11);
+    x12 = PLUS(x12,j12);
+    x13 = PLUS(x13,j13);
+    x14 = PLUS(x14,j14);
+    x15 = PLUS(x15,j15);
+
+    x0 = XOR(x0,U8TO32_LITTLE(m + 0));
+    x1 = XOR(x1,U8TO32_LITTLE(m + 4));
+    x2 = XOR(x2,U8TO32_LITTLE(m + 8));
+    x3 = XOR(x3,U8TO32_LITTLE(m + 12));
+    x4 = XOR(x4,U8TO32_LITTLE(m + 16));
+    x5 = XOR(x5,U8TO32_LITTLE(m + 20));
+    x6 = XOR(x6,U8TO32_LITTLE(m + 24));
+    x7 = XOR(x7,U8TO32_LITTLE(m + 28));
+    x8 = XOR(x8,U8TO32_LITTLE(m + 32));
+    x9 = XOR(x9,U8TO32_LITTLE(m + 36));
+    x10 = XOR(x10,U8TO32_LITTLE(m + 40));
+    x11 = XOR(x11,U8TO32_LITTLE(m + 44));
+    x12 = XOR(x12,U8TO32_LITTLE(m + 48));
+    x13 = XOR(x13,U8TO32_LITTLE(m + 52));
+    x14 = XOR(x14,U8TO32_LITTLE(m + 56));
+    x15 = XOR(x15,U8TO32_LITTLE(m + 60));
+
+    j12 = PLUSONE(j12);
+    if (!j12)
+      j13 = PLUSONE(j13);
+      /* stopping at 2^70 bytes per nonce is user's responsibility */
+
+    U32TO8_LITTLE(c + 0,x0);
+    U32TO8_LITTLE(c + 4,x1);
+    U32TO8_LITTLE(c + 8,x2);
+    U32TO8_LITTLE(c + 12,x3);
+    U32TO8_LITTLE(c + 16,x4);
+    U32TO8_LITTLE(c + 20,x5);
+    U32TO8_LITTLE(c + 24,x6);
+    U32TO8_LITTLE(c + 28,x7);
+    U32TO8_LITTLE(c + 32,x8);
+    U32TO8_LITTLE(c + 36,x9);
+    U32TO8_LITTLE(c + 40,x10);
+    U32TO8_LITTLE(c + 44,x11);
+    U32TO8_LITTLE(c + 48,x12);
+    U32TO8_LITTLE(c + 52,x13);
+    U32TO8_LITTLE(c + 56,x14);
+    U32TO8_LITTLE(c + 60,x15);
+
+    if (bytes <= 64) {
+      if (bytes < 64) {
+        for (i = 0;i < bytes;++i) ctarget[i] = c[i];
+      }
+      x->input[12] = j12;
+      x->input[13] = j13;
+      return;
+    }
+    bytes -= 64;
+    c += 64;
+    m += 64;
+  }
+}
+
+struct lws_cipher_chacha {
+	struct chacha_ctx ccctx[2];
+};
+
+#define K_1(_keys) &((struct lws_cipher_chacha *)_keys->cipher)->ccctx[0]
+#define K_2(_keys) &((struct lws_cipher_chacha *)_keys->cipher)->ccctx[1]
+
+int
+lws_chacha_activate(struct lws_ssh_keys *keys)
+{
+	if (keys->cipher) {
+		free(keys->cipher);
+		keys->cipher = NULL;
+	}
+
+	keys->cipher = malloc(sizeof(struct lws_cipher_chacha));
+	if (!keys->cipher)
+		return 1;
+
+	memset(keys->cipher, 0, sizeof(struct lws_cipher_chacha));
+
+	/* uses 2 x 256-bit keys, so 512 bits (64 bytes) needed */
+	chacha_keysetup(K_2(keys), keys->key[SSH_KEYIDX_ENC], 256);
+	chacha_keysetup(K_1(keys), &keys->key[SSH_KEYIDX_ENC][32], 256);
+
+	keys->valid = 1;
+	keys->full_length = 1;
+	keys->padding_alignment = 8; // CHACHA_BLOCKLEN;
+	keys->MAC_length = POLY1305_TAGLEN;
+
+	return 0;
+}
+
+void
+lws_chacha_destroy(struct lws_ssh_keys *keys)
+{
+	if (keys->cipher) {
+		free(keys->cipher);
+		keys->cipher = NULL;
+	}
+}
+
+uint32_t
+lws_chachapoly_get_length(struct lws_ssh_keys *keys, uint32_t seq,
+			  const uint8_t *in4)
+{
+        uint8_t buf[4], seqbuf[8];
+
+	/*
+	 * When receiving a packet, the length must be decrypted first.  When 4
+	 * bytes of ciphertext length have been received, they may be decrypted
+	 * using the K_1 key, a nonce consisting of the packet sequence number
+	 * encoded as a uint64 under the usual SSH wire encoding and a zero
+	 * block counter to obtain the plaintext length.
+	 */
+        POKE_U64(seqbuf, seq);
+	chacha_ivsetup(K_1(keys), seqbuf, NULL);
+        chacha_encrypt_bytes(K_1(keys), in4, buf, 4);
+
+	return PEEK_U32(buf);
+}
+
+/*
+ * chachapoly_crypt() operates as following:
+ * En/decrypt with header key 'aadlen' bytes from 'src', storing result
+ * to 'dest'. The ciphertext here is treated as additional authenticated
+ * data for MAC calculation.
+ * En/decrypt 'len' bytes at offset 'aadlen' from 'src' to 'dest'. Use
+ * POLY1305_TAGLEN bytes at offset 'len'+'aadlen' as the authentication
+ * tag. This tag is written on encryption and verified on decryption.
+ */
+int
+chachapoly_crypt(struct lws_ssh_keys *keys, u_int seqnr, u_char *dest,
+    const u_char *src, u_int len, u_int aadlen, u_int authlen, int do_encrypt)
+{
+        u_char seqbuf[8];
+        const u_char one[8] = { 1, 0, 0, 0, 0, 0, 0, 0 }; /* NB little-endian */
+        u_char expected_tag[POLY1305_TAGLEN], poly_key[POLY1305_KEYLEN];
+        int r = 1;
+
+        /*
+         * Run ChaCha20 once to generate the Poly1305 key. The IV is the
+         * packet sequence number.
+         */
+        memset(poly_key, 0, sizeof(poly_key));
+        POKE_U64(seqbuf, seqnr);
+        chacha_ivsetup(K_2(keys), seqbuf, NULL);
+        chacha_encrypt_bytes(K_2(keys),
+            poly_key, poly_key, sizeof(poly_key));
+
+        /* If decrypting, check tag before anything else */
+        if (!do_encrypt) {
+                const u_char *tag = src + aadlen + len;
+
+                poly1305_auth(expected_tag, src, aadlen + len, poly_key);
+                if (timingsafe_bcmp(expected_tag, tag, POLY1305_TAGLEN) != 0) {
+                        r = 2;
+                        goto out;
+                }
+        }
+
+        /* Crypt additional data */
+        if (aadlen) {
+                chacha_ivsetup(K_1(keys), seqbuf, NULL);
+                chacha_encrypt_bytes(K_1(keys), src, dest, aadlen);
+        }
+
+        /* Set Chacha's block counter to 1 */
+        chacha_ivsetup(K_2(keys), seqbuf, one);
+        chacha_encrypt_bytes(K_2(keys), src + aadlen, dest + aadlen, len);
+
+        /* If encrypting, calculate and append tag */
+        if (do_encrypt) {
+                poly1305_auth(dest + aadlen + len, dest, aadlen + len,
+                    poly_key);
+        }
+        r = 0;
+ out:
+        explicit_bzero(expected_tag, sizeof(expected_tag));
+        explicit_bzero(seqbuf, sizeof(seqbuf));
+        explicit_bzero(poly_key, sizeof(poly_key));
+        return r;
+}
+
+int
+lws_chacha_decrypt(struct lws_ssh_keys *keys, uint32_t seq,
+		   const uint8_t *ct, uint32_t len, uint8_t *pt)
+{
+	return chachapoly_crypt(keys, seq, pt, ct, len - POLY1305_TAGLEN - 4, 4,
+			 POLY1305_TAGLEN, 0);
+}
+
+int
+lws_chacha_encrypt(struct lws_ssh_keys *keys, uint32_t seq,
+		   const uint8_t *ct, uint32_t len, uint8_t *pt)
+{
+	return chachapoly_crypt(keys, seq, pt, ct, len - 4, 4, 0, 1);
+}
+
diff --git a/plugins/ssh-base/crypto/ed25519.c b/plugins/ssh-base/crypto/ed25519.c
new file mode 100644
index 0000000000000000000000000000000000000000..72b3ae7c52f851baaa5d4d790923feedad07a061
--- /dev/null
+++ b/plugins/ssh-base/crypto/ed25519.c
@@ -0,0 +1,221 @@
+/* $OpenBSD: ed25519.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */
+
+/*
+ * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
+ * Peter Schwabe, Bo-Yin Yang.
+ * Copied from supercop-20130419/crypto_sign/ed25519/ref/ed25519.c
+ *
+ * Modified to use lws genhash by Andy Green <andy@warmcat.com>
+ */
+
+#include <libwebsockets.h>
+#include <lws-ssh.h>
+#include "ge25519.h"
+
+int
+crypto_hash_sha512(uint8_t *hash64, const uint8_t *data, size_t len)
+{
+	struct lws_genhash_ctx ctx;
+	int ret;
+
+	if (lws_genhash_init(&ctx, LWS_GENHASH_TYPE_SHA512)) {
+		lwsl_notice("Failed to init SHA512\n");
+		return 0;
+	}
+
+	ret = lws_genhash_update(&ctx, data, len);
+
+	if (lws_genhash_destroy(&ctx, hash64))
+		lwsl_notice("genhash destroy failed\n");
+
+	return ret ? 0 : 64;
+}
+
+
+static void
+get_hram(unsigned char *hram, const unsigned char *sm,
+	 const unsigned char *pk, unsigned char *playground,
+	 size_t smlen)
+{
+	unsigned long long i;
+
+	for (i =  0; i < 32; ++i)
+		playground[i] = sm[i];
+	for (i = 32; i < 64; ++i)
+		playground[i] = pk[i-32];
+	for (i = 64; i < smlen; ++i)
+		playground[i] = sm[i];
+
+	crypto_hash_sha512(hram, playground, smlen);
+}
+
+
+int crypto_sign_ed25519_keypair(
+    struct lws_context *context,
+    unsigned char *pk,
+    unsigned char *sk
+    )
+{
+  sc25519 scsk;
+  ge25519 gepk;
+  unsigned char extsk[64];
+  int i;
+
+  lws_get_random(context, sk, 32);
+  crypto_hash_sha512(extsk, sk, 32);
+  extsk[0] &= 248;
+  extsk[31] &= 127;
+  extsk[31] |= 64;
+
+  sc25519_from32bytes(&scsk,extsk);
+  
+  ge25519_scalarmult_base(&gepk, &scsk);
+  ge25519_pack(pk, &gepk);
+  for(i=0;i<32;i++)
+    sk[32 + i] = pk[i];
+  return 0;
+}
+
+int crypto_sign_ed25519(
+    unsigned char *sm,
+    unsigned long long *smlen,
+    const unsigned char *m, size_t mlen,
+    const unsigned char *sk
+    )
+{
+  sc25519 sck, scs, scsk;
+  ge25519 ger;
+  unsigned char r[32];
+  unsigned char s[32];
+  unsigned char extsk[64];
+  unsigned long long i;
+  unsigned char hmg[crypto_hash_sha512_BYTES];
+  unsigned char hram[crypto_hash_sha512_BYTES];
+
+  crypto_hash_sha512(extsk, sk, 32);
+  extsk[0] &= 248;
+  extsk[31] &= 127;
+  extsk[31] |= 64;
+
+  *smlen = mlen+64;
+  for(i=0;i<mlen;i++)
+    sm[64 + i] = m[i];
+  for(i=0;i<32;i++)
+    sm[32 + i] = extsk[32+i];
+
+  crypto_hash_sha512(hmg, sm+32, mlen+32);
+  /* Generate k as h(extsk[32],...,extsk[63],m) */
+
+  /* Computation of R */
+  sc25519_from64bytes(&sck, hmg);
+  ge25519_scalarmult_base(&ger, &sck);
+  ge25519_pack(r, &ger);
+  
+  /* Computation of s */
+  for (i = 0; i < 32; i++)
+    sm[i] = r[i];
+
+  get_hram(hram, sm, sk + 32, sm, (size_t)mlen + 64);
+
+  sc25519_from64bytes(&scs, hram);
+  sc25519_from32bytes(&scsk, extsk);
+  sc25519_mul(&scs, &scs, &scsk);
+  
+  sc25519_add(&scs, &scs, &sck);
+
+  sc25519_to32bytes(s,&scs); /* cat s */
+  for (i = 0; i < 32; i++)
+    sm[32 + i] = s[i]; 
+
+  return 0;
+}
+
+int crypto_verify_32(const unsigned char *x,const unsigned char *y)
+{
+  unsigned int differentbits = 0;
+#define F(i) differentbits |= x[i] ^ y[i];
+  F(0)
+  F(1)
+  F(2)
+  F(3)
+  F(4)
+  F(5)
+  F(6)
+  F(7)
+  F(8)
+  F(9)
+  F(10)
+  F(11)
+  F(12)
+  F(13)
+  F(14)
+  F(15)
+  F(16)
+  F(17)
+  F(18)
+  F(19)
+  F(20)
+  F(21)
+  F(22)
+  F(23)
+  F(24)
+  F(25)
+  F(26)
+  F(27)
+  F(28)
+  F(29)
+  F(30)
+  F(31)
+  return (1 & ((differentbits - 1) >> 8)) - 1;
+}
+
+int crypto_sign_ed25519_open(
+    unsigned char *m,unsigned long long *mlen,
+    const unsigned char *sm,unsigned long long smlen,
+    const unsigned char *pk
+    )
+{
+  unsigned int i;
+  int ret;
+  unsigned char t2[32];
+  ge25519 get1, get2;
+  sc25519 schram, scs;
+  unsigned char hram[crypto_hash_sha512_BYTES];
+
+  *mlen = (unsigned long long) -1;
+  if (smlen < 64) {
+	  lwsl_notice("a\n");
+
+	  return -1;
+  }
+
+  if (ge25519_unpackneg_vartime(&get1, pk)) {
+	  lwsl_notice("b\n");
+	  return -1;
+  }
+
+  get_hram(hram,sm,pk,m, (size_t)smlen);
+
+  sc25519_from64bytes(&schram, hram);
+
+  sc25519_from32bytes(&scs, sm+32);
+
+  ge25519_double_scalarmult_vartime(&get2, &get1, &schram, &ge25519_base, &scs);
+  ge25519_pack(t2, &get2);
+
+  ret = crypto_verify_32(sm, t2);
+  lwsl_notice("vf says %d\n", ret);
+
+  if (!ret)
+  {
+    for(i=0;i<smlen-64;i++)
+      m[i] = sm[i + 64];
+    *mlen = smlen-64;
+  }
+  else
+  {
+    for(i=0;i<smlen-64;i++)
+      m[i] = 0;
+  }
+  return ret;
+}
diff --git a/plugins/ssh-base/crypto/fe25519.c b/plugins/ssh-base/crypto/fe25519.c
new file mode 100644
index 0000000000000000000000000000000000000000..fdc2e2a7cabf781f6133399a12b02f3d5fa7bfe3
--- /dev/null
+++ b/plugins/ssh-base/crypto/fe25519.c
@@ -0,0 +1,338 @@
+/* $OpenBSD: fe25519.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */
+
+/*
+ * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
+ * Peter Schwabe, Bo-Yin Yang.
+ * Copied from supercop-20130419/crypto_sign/ed25519/ref/fe25519.c
+ */
+
+#include "libwebsockets.h"
+
+#define WINDOWSIZE 1 /* Should be 1,2, or 4 */
+#define WINDOWMASK ((1<<WINDOWSIZE)-1)
+
+#include "fe25519.h"
+
+static uint32_t fe_equal(uint32_t a,uint32_t b) /* 16-bit inputs */
+{
+  uint32_t x = a ^ b; /* 0: yes; 1..65535: no */
+  x -= 1; /* 4294967295: yes; 0..65534: no */
+  x >>= 31; /* 1: yes; 0: no */
+  return x;
+}
+
+static uint32_t ge(uint32_t a,uint32_t b) /* 16-bit inputs */
+{
+  unsigned int x = a;
+  x -= (unsigned int) b; /* 0..65535: yes; 4294901761..4294967295: no */
+  x >>= 31; /* 0: yes; 1: no */
+  x ^= 1; /* 1: yes; 0: no */
+  return x;
+}
+
+static uint32_t times19(uint32_t a)
+{
+  return (a << 4) + (a << 1) + a;
+}
+
+static uint32_t times38(uint32_t a)
+{
+  return (a << 5) + (a << 2) + (a << 1);
+}
+
+static void fe_reduce_add_sub(fe25519 *r)
+{
+  uint32_t t;
+  int i,rep;
+
+  for(rep=0;rep<4;rep++)
+  {
+    t = r->v[31] >> 7;
+    r->v[31] &= 127;
+    t = times19(t);
+    r->v[0] += t;
+    for(i=0;i<31;i++)
+    {
+      t = r->v[i] >> 8;
+      r->v[i+1] += t;
+      r->v[i] &= 255;
+    }
+  }
+}
+
+static void reduce_mul(fe25519 *r)
+{
+  uint32_t t;
+  int i,rep;
+
+  for(rep=0;rep<2;rep++)
+  {
+    t = r->v[31] >> 7;
+    r->v[31] &= 127;
+    t = times19(t);
+    r->v[0] += t;
+    for(i=0;i<31;i++)
+    {
+      t = r->v[i] >> 8;
+      r->v[i+1] += t;
+      r->v[i] &= 255;
+    }
+  }
+}
+
+/* reduction modulo 2^255-19 */
+void fe25519_freeze(fe25519 *r) 
+{
+  int i;
+  uint32_t m = fe_equal(r->v[31],127);
+
+  for(i=30;i>0;i--)
+    m &= fe_equal(r->v[i],255);
+  m &= ge(r->v[0],237);
+
+  m = -(int32_t)m;
+
+  r->v[31] -= m&127;
+  for(i=30;i>0;i--)
+    r->v[i] -= m&255;
+  r->v[0] -= m&237;
+}
+
+void fe25519_unpack(fe25519 *r, const unsigned char x[32])
+{
+  int i;
+  for(i=0;i<32;i++) r->v[i] = x[i];
+  r->v[31] &= 127;
+}
+
+/* Assumes input x being reduced below 2^255 */
+void fe25519_pack(unsigned char r[32], const fe25519 *x)
+{
+  int i;
+  fe25519 y = *x;
+  fe25519_freeze(&y);
+  for(i=0;i<32;i++) 
+    r[i] = y.v[i];
+}
+
+int fe25519_iszero(const fe25519 *x)
+{
+  int i;
+  int r;
+  fe25519 t = *x;
+  fe25519_freeze(&t);
+  r = fe_equal(t.v[0],0);
+  for(i=1;i<32;i++) 
+    r &= fe_equal(t.v[i],0);
+  return r;
+}
+
+int fe25519_iseq_vartime(const fe25519 *x, const fe25519 *y)
+{
+  int i;
+  fe25519 t1 = *x;
+  fe25519 t2 = *y;
+  fe25519_freeze(&t1);
+  fe25519_freeze(&t2);
+  for(i=0;i<32;i++)
+    if(t1.v[i] != t2.v[i]) return 0;
+  return 1;
+}
+
+void fe25519_cmov(fe25519 *r, const fe25519 *x, unsigned char b)
+{
+  int i;
+  uint32_t mask = b;
+  mask = -(int32_t)mask;
+  for(i=0;i<32;i++) r->v[i] ^= mask & (x->v[i] ^ r->v[i]);
+}
+
+unsigned char fe25519_getparity(const fe25519 *x)
+{
+  fe25519 t = *x;
+  fe25519_freeze(&t);
+  return (unsigned char)(t.v[0] & 1);
+}
+
+void fe25519_setone(fe25519 *r)
+{
+  int i;
+  r->v[0] = 1;
+  for(i=1;i<32;i++) r->v[i]=0;
+}
+
+void fe25519_setzero(fe25519 *r)
+{
+  int i;
+  for(i=0;i<32;i++) r->v[i]=0;
+}
+
+void fe25519_neg(fe25519 *r, const fe25519 *x)
+{
+  fe25519 t;
+  int i;
+  for(i=0;i<32;i++) t.v[i]=x->v[i];
+  fe25519_setzero(r);
+  fe25519_sub(r, r, &t);
+}
+
+void fe25519_add(fe25519 *r, const fe25519 *x, const fe25519 *y)
+{
+  int i;
+  for(i=0;i<32;i++) r->v[i] = x->v[i] + y->v[i];
+  fe_reduce_add_sub(r);
+}
+
+void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y)
+{
+  int i;
+  uint32_t t[32];
+  t[0] = x->v[0] + 0x1da;
+  t[31] = x->v[31] + 0xfe;
+  for(i=1;i<31;i++) t[i] = x->v[i] + 0x1fe;
+  for(i=0;i<32;i++) r->v[i] = t[i] - y->v[i];
+  fe_reduce_add_sub(r);
+}
+
+void fe25519_mul(fe25519 *r, const fe25519 *x, const fe25519 *y)
+{
+  int i,j;
+  uint32_t t[63];
+  for(i=0;i<63;i++)t[i] = 0;
+
+  for(i=0;i<32;i++)
+    for(j=0;j<32;j++)
+      t[i+j] += x->v[i] * y->v[j];
+
+  for(i=32;i<63;i++)
+    r->v[i-32] = t[i-32] + times38(t[i]); 
+  r->v[31] = t[31]; /* result now in r[0]...r[31] */
+
+  reduce_mul(r);
+}
+
+void fe25519_square(fe25519 *r, const fe25519 *x)
+{
+  fe25519_mul(r, x, x);
+}
+
+void fe25519_invert(fe25519 *r, const fe25519 *x)
+{
+	fe25519 z2;
+	fe25519 z9;
+	fe25519 z11;
+	fe25519 z2_5_0;
+	fe25519 z2_10_0;
+	fe25519 z2_20_0;
+	fe25519 z2_50_0;
+	fe25519 z2_100_0;
+	fe25519 t0;
+	fe25519 t1;
+	int i;
+	
+	/* 2 */ fe25519_square(&z2,x);
+	/* 4 */ fe25519_square(&t1,&z2);
+	/* 8 */ fe25519_square(&t0,&t1);
+	/* 9 */ fe25519_mul(&z9,&t0,x);
+	/* 11 */ fe25519_mul(&z11,&z9,&z2);
+	/* 22 */ fe25519_square(&t0,&z11);
+	/* 2^5 - 2^0 = 31 */ fe25519_mul(&z2_5_0,&t0,&z9);
+
+	/* 2^6 - 2^1 */ fe25519_square(&t0,&z2_5_0);
+	/* 2^7 - 2^2 */ fe25519_square(&t1,&t0);
+	/* 2^8 - 2^3 */ fe25519_square(&t0,&t1);
+	/* 2^9 - 2^4 */ fe25519_square(&t1,&t0);
+	/* 2^10 - 2^5 */ fe25519_square(&t0,&t1);
+	/* 2^10 - 2^0 */ fe25519_mul(&z2_10_0,&t0,&z2_5_0);
+
+	/* 2^11 - 2^1 */ fe25519_square(&t0,&z2_10_0);
+	/* 2^12 - 2^2 */ fe25519_square(&t1,&t0);
+	/* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); }
+	/* 2^20 - 2^0 */ fe25519_mul(&z2_20_0,&t1,&z2_10_0);
+
+	/* 2^21 - 2^1 */ fe25519_square(&t0,&z2_20_0);
+	/* 2^22 - 2^2 */ fe25519_square(&t1,&t0);
+	/* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); }
+	/* 2^40 - 2^0 */ fe25519_mul(&t0,&t1,&z2_20_0);
+
+	/* 2^41 - 2^1 */ fe25519_square(&t1,&t0);
+	/* 2^42 - 2^2 */ fe25519_square(&t0,&t1);
+	/* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) { fe25519_square(&t1,&t0); fe25519_square(&t0,&t1); }
+	/* 2^50 - 2^0 */ fe25519_mul(&z2_50_0,&t0,&z2_10_0);
+
+	/* 2^51 - 2^1 */ fe25519_square(&t0,&z2_50_0);
+	/* 2^52 - 2^2 */ fe25519_square(&t1,&t0);
+	/* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); }
+	/* 2^100 - 2^0 */ fe25519_mul(&z2_100_0,&t1,&z2_50_0);
+
+	/* 2^101 - 2^1 */ fe25519_square(&t1,&z2_100_0);
+	/* 2^102 - 2^2 */ fe25519_square(&t0,&t1);
+	/* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) { fe25519_square(&t1,&t0); fe25519_square(&t0,&t1); }
+	/* 2^200 - 2^0 */ fe25519_mul(&t1,&t0,&z2_100_0);
+
+	/* 2^201 - 2^1 */ fe25519_square(&t0,&t1);
+	/* 2^202 - 2^2 */ fe25519_square(&t1,&t0);
+	/* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); }
+	/* 2^250 - 2^0 */ fe25519_mul(&t0,&t1,&z2_50_0);
+
+	/* 2^251 - 2^1 */ fe25519_square(&t1,&t0);
+	/* 2^252 - 2^2 */ fe25519_square(&t0,&t1);
+	/* 2^253 - 2^3 */ fe25519_square(&t1,&t0);
+	/* 2^254 - 2^4 */ fe25519_square(&t0,&t1);
+	/* 2^255 - 2^5 */ fe25519_square(&t1,&t0);
+	/* 2^255 - 21 */ fe25519_mul(r,&t1,&z11);
+}
+
+void fe25519_pow2523(fe25519 *r, const fe25519 *x)
+{
+	fe25519 z2;
+	fe25519 z9;
+	fe25519 z11;
+	fe25519 z2_5_0;
+	fe25519 z2_10_0;
+	fe25519 z2_20_0;
+	fe25519 z2_50_0;
+	fe25519 z2_100_0;
+	fe25519 t;
+	int i;
+		
+	/* 2 */ fe25519_square(&z2,x);
+	/* 4 */ fe25519_square(&t,&z2);
+	/* 8 */ fe25519_square(&t,&t);
+	/* 9 */ fe25519_mul(&z9,&t,x);
+	/* 11 */ fe25519_mul(&z11,&z9,&z2);
+	/* 22 */ fe25519_square(&t,&z11);
+	/* 2^5 - 2^0 = 31 */ fe25519_mul(&z2_5_0,&t,&z9);
+
+	/* 2^6 - 2^1 */ fe25519_square(&t,&z2_5_0);
+	/* 2^10 - 2^5 */ for (i = 1;i < 5;i++) { fe25519_square(&t,&t); }
+	/* 2^10 - 2^0 */ fe25519_mul(&z2_10_0,&t,&z2_5_0);
+
+	/* 2^11 - 2^1 */ fe25519_square(&t,&z2_10_0);
+	/* 2^20 - 2^10 */ for (i = 1;i < 10;i++) { fe25519_square(&t,&t); }
+	/* 2^20 - 2^0 */ fe25519_mul(&z2_20_0,&t,&z2_10_0);
+
+	/* 2^21 - 2^1 */ fe25519_square(&t,&z2_20_0);
+	/* 2^40 - 2^20 */ for (i = 1;i < 20;i++) { fe25519_square(&t,&t); }
+	/* 2^40 - 2^0 */ fe25519_mul(&t,&t,&z2_20_0);
+
+	/* 2^41 - 2^1 */ fe25519_square(&t,&t);
+	/* 2^50 - 2^10 */ for (i = 1;i < 10;i++) { fe25519_square(&t,&t); }
+	/* 2^50 - 2^0 */ fe25519_mul(&z2_50_0,&t,&z2_10_0);
+
+	/* 2^51 - 2^1 */ fe25519_square(&t,&z2_50_0);
+	/* 2^100 - 2^50 */ for (i = 1;i < 50;i++) { fe25519_square(&t,&t); }
+	/* 2^100 - 2^0 */ fe25519_mul(&z2_100_0,&t,&z2_50_0);
+
+	/* 2^101 - 2^1 */ fe25519_square(&t,&z2_100_0);
+	/* 2^200 - 2^100 */ for (i = 1;i < 100;i++) { fe25519_square(&t,&t); }
+	/* 2^200 - 2^0 */ fe25519_mul(&t,&t,&z2_100_0);
+
+	/* 2^201 - 2^1 */ fe25519_square(&t,&t);
+	/* 2^250 - 2^50 */ for (i = 1;i < 50;i++) { fe25519_square(&t,&t); }
+	/* 2^250 - 2^0 */ fe25519_mul(&t,&t,&z2_50_0);
+
+	/* 2^251 - 2^1 */ fe25519_square(&t,&t);
+	/* 2^252 - 2^2 */ fe25519_square(&t,&t);
+	/* 2^252 - 3 */ fe25519_mul(r,&t,x);
+}
diff --git a/plugins/ssh-base/crypto/fe25519.h b/plugins/ssh-base/crypto/fe25519.h
new file mode 100644
index 0000000000000000000000000000000000000000..c1f5bf55c97cca9f4f360d76cb63ee2082617079
--- /dev/null
+++ b/plugins/ssh-base/crypto/fe25519.h
@@ -0,0 +1,68 @@
+/* $OpenBSD: fe25519.h,v 1.3 2013/12/09 11:03:45 markus Exp $ */
+
+/*
+ * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
+ * Peter Schwabe, Bo-Yin Yang.
+ * Copied from supercop-20130419/crypto_sign/ed25519/ref/fe25519.h
+ */
+
+#ifndef FE25519_H
+#define FE25519_H
+
+#define fe25519              crypto_sign_ed25519_ref_fe25519
+#define fe25519_freeze       crypto_sign_ed25519_ref_fe25519_freeze
+#define fe25519_unpack       crypto_sign_ed25519_ref_fe25519_unpack
+#define fe25519_pack         crypto_sign_ed25519_ref_fe25519_pack
+#define fe25519_iszero       crypto_sign_ed25519_ref_fe25519_iszero
+#define fe25519_iseq_vartime crypto_sign_ed25519_ref_fe25519_iseq_vartime
+#define fe25519_cmov         crypto_sign_ed25519_ref_fe25519_cmov
+#define fe25519_setone       crypto_sign_ed25519_ref_fe25519_setone
+#define fe25519_setzero      crypto_sign_ed25519_ref_fe25519_setzero
+#define fe25519_neg          crypto_sign_ed25519_ref_fe25519_neg
+#define fe25519_getparity    crypto_sign_ed25519_ref_fe25519_getparity
+#define fe25519_add          crypto_sign_ed25519_ref_fe25519_add
+#define fe25519_sub          crypto_sign_ed25519_ref_fe25519_sub
+#define fe25519_mul          crypto_sign_ed25519_ref_fe25519_mul
+#define fe25519_square       crypto_sign_ed25519_ref_fe25519_square
+#define fe25519_invert       crypto_sign_ed25519_ref_fe25519_invert
+#define fe25519_pow2523      crypto_sign_ed25519_ref_fe25519_pow2523
+
+typedef struct 
+{
+	uint32_t v[32];
+}
+fe25519;
+
+void fe25519_freeze(fe25519 *r);
+
+void fe25519_unpack(fe25519 *r, const unsigned char x[32]);
+
+void fe25519_pack(unsigned char r[32], const fe25519 *x);
+
+int fe25519_iszero(const fe25519 *x);
+
+int fe25519_iseq_vartime(const fe25519 *x, const fe25519 *y);
+
+void fe25519_cmov(fe25519 *r, const fe25519 *x, unsigned char b);
+
+void fe25519_setone(fe25519 *r);
+
+void fe25519_setzero(fe25519 *r);
+
+void fe25519_neg(fe25519 *r, const fe25519 *x);
+
+unsigned char fe25519_getparity(const fe25519 *x);
+
+void fe25519_add(fe25519 *r, const fe25519 *x, const fe25519 *y);
+
+void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y);
+
+void fe25519_mul(fe25519 *r, const fe25519 *x, const fe25519 *y);
+
+void fe25519_square(fe25519 *r, const fe25519 *x);
+
+void fe25519_invert(fe25519 *r, const fe25519 *x);
+
+void fe25519_pow2523(fe25519 *r, const fe25519 *x);
+
+#endif
diff --git a/plugins/ssh-base/crypto/ge25519.c b/plugins/ssh-base/crypto/ge25519.c
new file mode 100644
index 0000000000000000000000000000000000000000..0c6273bbc5871dfb88d4469d33010c9ed62f7dcc
--- /dev/null
+++ b/plugins/ssh-base/crypto/ge25519.c
@@ -0,0 +1,321 @@
+/* $OpenBSD: ge25519.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */
+
+/*
+ * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
+ * Peter Schwabe, Bo-Yin Yang.
+ * Copied from supercop-20130419/crypto_sign/ed25519/ref/ge25519.c
+ */
+
+#include <libwebsockets.h>
+
+#include "fe25519.h"
+#include "sc25519.h"
+#include "ge25519.h"
+
+/* 
+ * Arithmetic on the twisted Edwards curve -x^2 + y^2 = 1 + dx^2y^2 
+ * with d = -(121665/121666) = 37095705934669439343138083508754565189542113879843219016388785533085940283555
+ * Base point: (15112221349535400772501151409588531511454012693041857206046113283949847762202,46316835694926478169428394003475163141307993866256225615783033603165251855960);
+ */
+
+/* d */
+static const fe25519 ge25519_ecd = {{0xA3, 0x78, 0x59, 0x13, 0xCA, 0x4D, 0xEB, 0x75, 0xAB, 0xD8, 0x41, 0x41, 0x4D, 0x0A, 0x70, 0x00, 
+                      0x98, 0xE8, 0x79, 0x77, 0x79, 0x40, 0xC7, 0x8C, 0x73, 0xFE, 0x6F, 0x2B, 0xEE, 0x6C, 0x03, 0x52}};
+/* 2*d */
+static const fe25519 ge25519_ec2d = {{0x59, 0xF1, 0xB2, 0x26, 0x94, 0x9B, 0xD6, 0xEB, 0x56, 0xB1, 0x83, 0x82, 0x9A, 0x14, 0xE0, 0x00, 
+                       0x30, 0xD1, 0xF3, 0xEE, 0xF2, 0x80, 0x8E, 0x19, 0xE7, 0xFC, 0xDF, 0x56, 0xDC, 0xD9, 0x06, 0x24}};
+/* sqrt(-1) */
+static const fe25519 ge25519_sqrtm1 = {{0xB0, 0xA0, 0x0E, 0x4A, 0x27, 0x1B, 0xEE, 0xC4, 0x78, 0xE4, 0x2F, 0xAD, 0x06, 0x18, 0x43, 0x2F, 
+                         0xA7, 0xD7, 0xFB, 0x3D, 0x99, 0x00, 0x4D, 0x2B, 0x0B, 0xDF, 0xC1, 0x4F, 0x80, 0x24, 0x83, 0x2B}};
+
+#define ge25519_p3 ge25519
+
+typedef struct
+{
+  fe25519 x;
+  fe25519 z;
+  fe25519 y;
+  fe25519 t;
+} ge25519_p1p1;
+
+typedef struct
+{
+  fe25519 x;
+  fe25519 y;
+  fe25519 z;
+} ge25519_p2;
+
+typedef struct
+{
+  fe25519 x;
+  fe25519 y;
+} ge25519_aff;
+
+
+/* Packed coordinates of the base point */
+const ge25519 ge25519_base = {{{0x1A, 0xD5, 0x25, 0x8F, 0x60, 0x2D, 0x56, 0xC9, 0xB2, 0xA7, 0x25, 0x95, 0x60, 0xC7, 0x2C, 0x69, 
+                                0x5C, 0xDC, 0xD6, 0xFD, 0x31, 0xE2, 0xA4, 0xC0, 0xFE, 0x53, 0x6E, 0xCD, 0xD3, 0x36, 0x69, 0x21}},
+                              {{0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 
+                                0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66}},
+                              {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+                              {{0xA3, 0xDD, 0xB7, 0xA5, 0xB3, 0x8A, 0xDE, 0x6D, 0xF5, 0x52, 0x51, 0x77, 0x80, 0x9F, 0xF0, 0x20, 
+                                0x7D, 0xE3, 0xAB, 0x64, 0x8E, 0x4E, 0xEA, 0x66, 0x65, 0x76, 0x8B, 0xD7, 0x0F, 0x5F, 0x87, 0x67}}};
+
+/* Multiples of the base point in affine representation */
+static const ge25519_aff ge25519_base_multiples_affine[425] = {
+#include "ge25519_base.data"
+};
+
+static void p1p1_to_p2(ge25519_p2 *r, const ge25519_p1p1 *p)
+{
+  fe25519_mul(&r->x, &p->x, &p->t);
+  fe25519_mul(&r->y, &p->y, &p->z);
+  fe25519_mul(&r->z, &p->z, &p->t);
+}
+
+static void p1p1_to_p3(ge25519_p3 *r, const ge25519_p1p1 *p)
+{
+  p1p1_to_p2((ge25519_p2 *)r, p);
+  fe25519_mul(&r->t, &p->x, &p->y);
+}
+
+static void ge25519_mixadd2(ge25519_p3 *r, const ge25519_aff *q)
+{
+  fe25519 a,b,t1,t2,c,d,e,f,g,h,qt;
+  fe25519_mul(&qt, &q->x, &q->y);
+  fe25519_sub(&a, &r->y, &r->x); /* A = (Y1-X1)*(Y2-X2) */
+  fe25519_add(&b, &r->y, &r->x); /* B = (Y1+X1)*(Y2+X2) */
+  fe25519_sub(&t1, &q->y, &q->x);
+  fe25519_add(&t2, &q->y, &q->x);
+  fe25519_mul(&a, &a, &t1);
+  fe25519_mul(&b, &b, &t2);
+  fe25519_sub(&e, &b, &a); /* E = B-A */
+  fe25519_add(&h, &b, &a); /* H = B+A */
+  fe25519_mul(&c, &r->t, &qt); /* C = T1*k*T2 */
+  fe25519_mul(&c, &c, &ge25519_ec2d);
+  fe25519_add(&d, &r->z, &r->z); /* D = Z1*2 */
+  fe25519_sub(&f, &d, &c); /* F = D-C */
+  fe25519_add(&g, &d, &c); /* G = D+C */
+  fe25519_mul(&r->x, &e, &f);
+  fe25519_mul(&r->y, &h, &g);
+  fe25519_mul(&r->z, &g, &f);
+  fe25519_mul(&r->t, &e, &h);
+}
+
+static void add_p1p1(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_p3 *q)
+{
+  fe25519 a, b, c, d, t;
+  
+  fe25519_sub(&a, &p->y, &p->x); /* A = (Y1-X1)*(Y2-X2) */
+  fe25519_sub(&t, &q->y, &q->x);
+  fe25519_mul(&a, &a, &t);
+  fe25519_add(&b, &p->x, &p->y); /* B = (Y1+X1)*(Y2+X2) */
+  fe25519_add(&t, &q->x, &q->y);
+  fe25519_mul(&b, &b, &t);
+  fe25519_mul(&c, &p->t, &q->t); /* C = T1*k*T2 */
+  fe25519_mul(&c, &c, &ge25519_ec2d);
+  fe25519_mul(&d, &p->z, &q->z); /* D = Z1*2*Z2 */
+  fe25519_add(&d, &d, &d);
+  fe25519_sub(&r->x, &b, &a); /* E = B-A */
+  fe25519_sub(&r->t, &d, &c); /* F = D-C */
+  fe25519_add(&r->z, &d, &c); /* G = D+C */
+  fe25519_add(&r->y, &b, &a); /* H = B+A */
+}
+
+/* See http://www.hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html#doubling-dbl-2008-hwcd */
+static void dbl_p1p1(ge25519_p1p1 *r, const ge25519_p2 *p)
+{
+  fe25519 a,b,c,d;
+  fe25519_square(&a, &p->x);
+  fe25519_square(&b, &p->y);
+  fe25519_square(&c, &p->z);
+  fe25519_add(&c, &c, &c);
+  fe25519_neg(&d, &a);
+
+  fe25519_add(&r->x, &p->x, &p->y);
+  fe25519_square(&r->x, &r->x);
+  fe25519_sub(&r->x, &r->x, &a);
+  fe25519_sub(&r->x, &r->x, &b);
+  fe25519_add(&r->z, &d, &b);
+  fe25519_sub(&r->t, &r->z, &c);
+  fe25519_sub(&r->y, &d, &b);
+}
+
+/* Constant-time version of: if(b) r = p */
+static void cmov_aff(ge25519_aff *r, const ge25519_aff *p, unsigned char b)
+{
+  fe25519_cmov(&r->x, &p->x, b);
+  fe25519_cmov(&r->y, &p->y, b);
+}
+
+static unsigned char ge_equal(signed char b,signed char c)
+{
+  unsigned char ub = b;
+  unsigned char uc = c;
+  unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */
+  uint32_t y = x; /* 0: yes; 1..255: no */
+  y -= 1; /* 4294967295: yes; 0..254: no */
+  y >>= 31; /* 1: yes; 0: no */
+  return y;
+}
+
+static unsigned char negative(signed char b)
+{
+  unsigned long long x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */
+  x >>= 63; /* 1: yes; 0: no */
+  return (unsigned char)x;
+}
+
+static void choose_t(ge25519_aff *t, unsigned long long pos, signed char b)
+{
+  /* constant time */
+  fe25519 v;
+  *t = ge25519_base_multiples_affine[5*pos+0];
+  cmov_aff(t, &ge25519_base_multiples_affine[5*pos+1],ge_equal(b,1) | ge_equal(b,-1));
+  cmov_aff(t, &ge25519_base_multiples_affine[5*pos+2],ge_equal(b,2) | ge_equal(b,-2));
+  cmov_aff(t, &ge25519_base_multiples_affine[5*pos+3],ge_equal(b,3) | ge_equal(b,-3));
+  cmov_aff(t, &ge25519_base_multiples_affine[5*pos+4],ge_equal(b,-4));
+  fe25519_neg(&v, &t->x);
+  fe25519_cmov(&t->x, &v, negative(b));
+}
+
+static void setneutral(ge25519 *r)
+{
+  fe25519_setzero(&r->x);
+  fe25519_setone(&r->y);
+  fe25519_setone(&r->z);
+  fe25519_setzero(&r->t);
+}
+
+/* ********************************************************************
+ *                    EXPORTED FUNCTIONS
+ ******************************************************************** */
+
+/* return 0 on success, -1 otherwise */
+int ge25519_unpackneg_vartime(ge25519_p3 *r, const unsigned char p[32])
+{
+  unsigned char par;
+  fe25519 t, chk, num, den, den2, den4, den6;
+  fe25519_setone(&r->z);
+  par = p[31] >> 7;
+  fe25519_unpack(&r->y, p); 
+  fe25519_square(&num, &r->y); /* x = y^2 */
+  fe25519_mul(&den, &num, &ge25519_ecd); /* den = dy^2 */
+  fe25519_sub(&num, &num, &r->z); /* x = y^2-1 */
+  fe25519_add(&den, &r->z, &den); /* den = dy^2+1 */
+
+  /* Computation of sqrt(num/den) */
+  /* 1.: computation of num^((p-5)/8)*den^((7p-35)/8) = (num*den^7)^((p-5)/8) */
+  fe25519_square(&den2, &den);
+  fe25519_square(&den4, &den2);
+  fe25519_mul(&den6, &den4, &den2);
+  fe25519_mul(&t, &den6, &num);
+  fe25519_mul(&t, &t, &den);
+
+  fe25519_pow2523(&t, &t);
+  /* 2. computation of r->x = t * num * den^3 */
+  fe25519_mul(&t, &t, &num);
+  fe25519_mul(&t, &t, &den);
+  fe25519_mul(&t, &t, &den);
+  fe25519_mul(&r->x, &t, &den);
+
+  /* 3. Check whether sqrt computation gave correct result, multiply by sqrt(-1) if not: */
+  fe25519_square(&chk, &r->x);
+  fe25519_mul(&chk, &chk, &den);
+  if (!fe25519_iseq_vartime(&chk, &num))
+    fe25519_mul(&r->x, &r->x, &ge25519_sqrtm1);
+
+  /* 4. Now we have one of the two square roots, except if input was not a square */
+  fe25519_square(&chk, &r->x);
+  fe25519_mul(&chk, &chk, &den);
+  if (!fe25519_iseq_vartime(&chk, &num))
+    return -1;
+
+  /* 5. Choose the desired square root according to parity: */
+  if(fe25519_getparity(&r->x) != (1-par))
+    fe25519_neg(&r->x, &r->x);
+
+  fe25519_mul(&r->t, &r->x, &r->y);
+  return 0;
+}
+
+void ge25519_pack(unsigned char r[32], const ge25519_p3 *p)
+{
+  fe25519 tx, ty, zi;
+  fe25519_invert(&zi, &p->z); 
+  fe25519_mul(&tx, &p->x, &zi);
+  fe25519_mul(&ty, &p->y, &zi);
+  fe25519_pack(r, &ty);
+  r[31] ^= fe25519_getparity(&tx) << 7;
+}
+
+int ge25519_isneutral_vartime(const ge25519_p3 *p)
+{
+  int ret = 1;
+  if(!fe25519_iszero(&p->x)) ret = 0;
+  if(!fe25519_iseq_vartime(&p->y, &p->z)) ret = 0;
+  return ret;
+}
+
+/* computes [s1]p1 + [s2]p2 */
+void ge25519_double_scalarmult_vartime(ge25519_p3 *r, const ge25519_p3 *p1, const sc25519 *s1, const ge25519_p3 *p2, const sc25519 *s2)
+{
+  ge25519_p1p1 tp1p1;
+  ge25519_p3 pre[16];
+  unsigned char b[127];
+  int i;
+
+  /* precomputation                                                        s2 s1 */
+  setneutral(pre);                                                      /* 00 00 */
+  pre[1] = *p1;                                                         /* 00 01 */
+  dbl_p1p1(&tp1p1,(ge25519_p2 *)p1);      p1p1_to_p3( &pre[2], &tp1p1); /* 00 10 */
+  add_p1p1(&tp1p1,&pre[1], &pre[2]);      p1p1_to_p3( &pre[3], &tp1p1); /* 00 11 */
+  pre[4] = *p2;                                                         /* 01 00 */
+  add_p1p1(&tp1p1,&pre[1], &pre[4]);      p1p1_to_p3( &pre[5], &tp1p1); /* 01 01 */
+  add_p1p1(&tp1p1,&pre[2], &pre[4]);      p1p1_to_p3( &pre[6], &tp1p1); /* 01 10 */
+  add_p1p1(&tp1p1,&pre[3], &pre[4]);      p1p1_to_p3( &pre[7], &tp1p1); /* 01 11 */
+  dbl_p1p1(&tp1p1,(ge25519_p2 *)p2);      p1p1_to_p3( &pre[8], &tp1p1); /* 10 00 */
+  add_p1p1(&tp1p1,&pre[1], &pre[8]);      p1p1_to_p3( &pre[9], &tp1p1); /* 10 01 */
+  dbl_p1p1(&tp1p1,(ge25519_p2 *)&pre[5]); p1p1_to_p3(&pre[10], &tp1p1); /* 10 10 */
+  add_p1p1(&tp1p1,&pre[3], &pre[8]);      p1p1_to_p3(&pre[11], &tp1p1); /* 10 11 */
+  add_p1p1(&tp1p1,&pre[4], &pre[8]);      p1p1_to_p3(&pre[12], &tp1p1); /* 11 00 */
+  add_p1p1(&tp1p1,&pre[1],&pre[12]);      p1p1_to_p3(&pre[13], &tp1p1); /* 11 01 */
+  add_p1p1(&tp1p1,&pre[2],&pre[12]);      p1p1_to_p3(&pre[14], &tp1p1); /* 11 10 */
+  add_p1p1(&tp1p1,&pre[3],&pre[12]);      p1p1_to_p3(&pre[15], &tp1p1); /* 11 11 */
+
+  sc25519_2interleave2(b,s1,s2);
+
+  /* scalar multiplication */
+  *r = pre[b[126]];
+  for(i=125;i>=0;i--)
+  {
+    dbl_p1p1(&tp1p1, (ge25519_p2 *)r);
+    p1p1_to_p2((ge25519_p2 *) r, &tp1p1);
+    dbl_p1p1(&tp1p1, (ge25519_p2 *)r);
+    if(b[i]!=0)
+    {
+      p1p1_to_p3(r, &tp1p1);
+      add_p1p1(&tp1p1, r, &pre[b[i]]);
+    }
+    if(i != 0) p1p1_to_p2((ge25519_p2 *)r, &tp1p1);
+    else p1p1_to_p3(r, &tp1p1);
+  }
+}
+
+void ge25519_scalarmult_base(ge25519_p3 *r, const sc25519 *s)
+{
+  signed char b[85];
+  int i;
+  ge25519_aff t;
+  sc25519_window3(b,s);
+
+  choose_t((ge25519_aff *)r, 0, b[0]);
+  fe25519_setone(&r->z);
+  fe25519_mul(&r->t, &r->x, &r->y);
+  for(i=1;i<85;i++)
+  {
+    choose_t(&t, (unsigned long long) i, b[i]);
+    ge25519_mixadd2(r, &t);
+  }
+}
diff --git a/plugins/ssh-base/crypto/ge25519.h b/plugins/ssh-base/crypto/ge25519.h
new file mode 100644
index 0000000000000000000000000000000000000000..a097637609317f2fc273ec4bf8f8cecce9fe0744
--- /dev/null
+++ b/plugins/ssh-base/crypto/ge25519.h
@@ -0,0 +1,43 @@
+/* $OpenBSD: ge25519.h,v 1.4 2015/02/16 18:26:26 miod Exp $ */
+
+/*
+ * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
+ * Peter Schwabe, Bo-Yin Yang.
+ * Copied from supercop-20130419/crypto_sign/ed25519/ref/ge25519.h
+ */
+
+#ifndef GE25519_H
+#define GE25519_H
+
+#include "fe25519.h"
+#include "sc25519.h"
+
+#define ge25519                           crypto_sign_ed25519_ref_ge25519
+#define ge25519_base                      crypto_sign_ed25519_ref_ge25519_base
+#define ge25519_unpackneg_vartime         crypto_sign_ed25519_ref_unpackneg_vartime
+#define ge25519_pack                      crypto_sign_ed25519_ref_pack
+#define ge25519_isneutral_vartime         crypto_sign_ed25519_ref_isneutral_vartime
+#define ge25519_double_scalarmult_vartime crypto_sign_ed25519_ref_double_scalarmult_vartime
+#define ge25519_scalarmult_base           crypto_sign_ed25519_ref_scalarmult_base
+
+typedef struct
+{
+  fe25519 x;
+  fe25519 y;
+  fe25519 z;
+  fe25519 t;
+} ge25519;
+
+extern const ge25519 ge25519_base;
+
+int ge25519_unpackneg_vartime(ge25519 *r, const unsigned char p[32]);
+
+void ge25519_pack(unsigned char r[32], const ge25519 *p);
+
+int ge25519_isneutral_vartime(const ge25519 *p);
+
+void ge25519_double_scalarmult_vartime(ge25519 *r, const ge25519 *p1, const sc25519 *s1, const ge25519 *p2, const sc25519 *s2);
+
+void ge25519_scalarmult_base(ge25519 *r, const sc25519 *s);
+
+#endif
diff --git a/plugins/ssh-base/crypto/ge25519_base.data b/plugins/ssh-base/crypto/ge25519_base.data
new file mode 100644
index 0000000000000000000000000000000000000000..66fb1b61c67d2d30cec2781564903d90c9086a38
--- /dev/null
+++ b/plugins/ssh-base/crypto/ge25519_base.data
@@ -0,0 +1,858 @@
+/* $OpenBSD: ge25519_base.data,v 1.3 2013/12/09 11:03:45 markus Exp $ */
+
+/*
+ * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
+ * Peter Schwabe, Bo-Yin Yang.
+ * Copied from supercop-20130419/crypto_sign/ed25519/ref/ge25519_base.data
+ */
+
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95, 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0, 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21}} ,
+ {{0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66}}},
+{{{0x0e, 0xce, 0x43, 0x28, 0x4e, 0xa1, 0xc5, 0x83, 0x5f, 0xa4, 0xd7, 0x15, 0x45, 0x8e, 0x0d, 0x08, 0xac, 0xe7, 0x33, 0x18, 0x7d, 0x3b, 0x04, 0x3d, 0x6c, 0x04, 0x5a, 0x9f, 0x4c, 0x38, 0xab, 0x36}} ,
+ {{0xc9, 0xa3, 0xf8, 0x6a, 0xae, 0x46, 0x5f, 0x0e, 0x56, 0x51, 0x38, 0x64, 0x51, 0x0f, 0x39, 0x97, 0x56, 0x1f, 0xa2, 0xc9, 0xe8, 0x5e, 0xa2, 0x1d, 0xc2, 0x29, 0x23, 0x09, 0xf3, 0xcd, 0x60, 0x22}}},
+{{{0x5c, 0xe2, 0xf8, 0xd3, 0x5f, 0x48, 0x62, 0xac, 0x86, 0x48, 0x62, 0x81, 0x19, 0x98, 0x43, 0x63, 0x3a, 0xc8, 0xda, 0x3e, 0x74, 0xae, 0xf4, 0x1f, 0x49, 0x8f, 0x92, 0x22, 0x4a, 0x9c, 0xae, 0x67}} ,
+ {{0xd4, 0xb4, 0xf5, 0x78, 0x48, 0x68, 0xc3, 0x02, 0x04, 0x03, 0x24, 0x67, 0x17, 0xec, 0x16, 0x9f, 0xf7, 0x9e, 0x26, 0x60, 0x8e, 0xa1, 0x26, 0xa1, 0xab, 0x69, 0xee, 0x77, 0xd1, 0xb1, 0x67, 0x12}}},
+{{{0x70, 0xf8, 0xc9, 0xc4, 0x57, 0xa6, 0x3a, 0x49, 0x47, 0x15, 0xce, 0x93, 0xc1, 0x9e, 0x73, 0x1a, 0xf9, 0x20, 0x35, 0x7a, 0xb8, 0xd4, 0x25, 0x83, 0x46, 0xf1, 0xcf, 0x56, 0xdb, 0xa8, 0x3d, 0x20}} ,
+ {{0x2f, 0x11, 0x32, 0xca, 0x61, 0xab, 0x38, 0xdf, 0xf0, 0x0f, 0x2f, 0xea, 0x32, 0x28, 0xf2, 0x4c, 0x6c, 0x71, 0xd5, 0x80, 0x85, 0xb8, 0x0e, 0x47, 0xe1, 0x95, 0x15, 0xcb, 0x27, 0xe8, 0xd0, 0x47}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xc8, 0x84, 0xa5, 0x08, 0xbc, 0xfd, 0x87, 0x3b, 0x99, 0x8b, 0x69, 0x80, 0x7b, 0xc6, 0x3a, 0xeb, 0x93, 0xcf, 0x4e, 0xf8, 0x5c, 0x2d, 0x86, 0x42, 0xb6, 0x71, 0xd7, 0x97, 0x5f, 0xe1, 0x42, 0x67}} ,
+ {{0xb4, 0xb9, 0x37, 0xfc, 0xa9, 0x5b, 0x2f, 0x1e, 0x93, 0xe4, 0x1e, 0x62, 0xfc, 0x3c, 0x78, 0x81, 0x8f, 0xf3, 0x8a, 0x66, 0x09, 0x6f, 0xad, 0x6e, 0x79, 0x73, 0xe5, 0xc9, 0x00, 0x06, 0xd3, 0x21}}},
+{{{0xf8, 0xf9, 0x28, 0x6c, 0x6d, 0x59, 0xb2, 0x59, 0x74, 0x23, 0xbf, 0xe7, 0x33, 0x8d, 0x57, 0x09, 0x91, 0x9c, 0x24, 0x08, 0x15, 0x2b, 0xe2, 0xb8, 0xee, 0x3a, 0xe5, 0x27, 0x06, 0x86, 0xa4, 0x23}} ,
+ {{0xeb, 0x27, 0x67, 0xc1, 0x37, 0xab, 0x7a, 0xd8, 0x27, 0x9c, 0x07, 0x8e, 0xff, 0x11, 0x6a, 0xb0, 0x78, 0x6e, 0xad, 0x3a, 0x2e, 0x0f, 0x98, 0x9f, 0x72, 0xc3, 0x7f, 0x82, 0xf2, 0x96, 0x96, 0x70}}},
+{{{0x81, 0x6b, 0x88, 0xe8, 0x1e, 0xc7, 0x77, 0x96, 0x0e, 0xa1, 0xa9, 0x52, 0xe0, 0xd8, 0x0e, 0x61, 0x9e, 0x79, 0x2d, 0x95, 0x9c, 0x8d, 0x96, 0xe0, 0x06, 0x40, 0x5d, 0x87, 0x28, 0x5f, 0x98, 0x70}} ,
+ {{0xf1, 0x79, 0x7b, 0xed, 0x4f, 0x44, 0xb2, 0xe7, 0x08, 0x0d, 0xc2, 0x08, 0x12, 0xd2, 0x9f, 0xdf, 0xcd, 0x93, 0x20, 0x8a, 0xcf, 0x33, 0xca, 0x6d, 0x89, 0xb9, 0x77, 0xc8, 0x93, 0x1b, 0x4e, 0x60}}},
+{{{0x26, 0x4f, 0x7e, 0x97, 0xf6, 0x40, 0xdd, 0x4f, 0xfc, 0x52, 0x78, 0xf9, 0x90, 0x31, 0x03, 0xe6, 0x7d, 0x56, 0x39, 0x0b, 0x1d, 0x56, 0x82, 0x85, 0xf9, 0x1a, 0x42, 0x17, 0x69, 0x6c, 0xcf, 0x39}} ,
+ {{0x69, 0xd2, 0x06, 0x3a, 0x4f, 0x39, 0x2d, 0xf9, 0x38, 0x40, 0x8c, 0x4c, 0xe7, 0x05, 0x12, 0xb4, 0x78, 0x8b, 0xf8, 0xc0, 0xec, 0x93, 0xde, 0x7a, 0x6b, 0xce, 0x2c, 0xe1, 0x0e, 0xa9, 0x34, 0x44}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x0b, 0xa4, 0x3c, 0xb0, 0x0f, 0x7a, 0x51, 0xf1, 0x78, 0xd6, 0xd9, 0x6a, 0xfd, 0x46, 0xe8, 0xb8, 0xa8, 0x79, 0x1d, 0x87, 0xf9, 0x90, 0xf2, 0x9c, 0x13, 0x29, 0xf8, 0x0b, 0x20, 0x64, 0xfa, 0x05}} ,
+ {{0x26, 0x09, 0xda, 0x17, 0xaf, 0x95, 0xd6, 0xfb, 0x6a, 0x19, 0x0d, 0x6e, 0x5e, 0x12, 0xf1, 0x99, 0x4c, 0xaa, 0xa8, 0x6f, 0x79, 0x86, 0xf4, 0x72, 0x28, 0x00, 0x26, 0xf9, 0xea, 0x9e, 0x19, 0x3d}}},
+{{{0x87, 0xdd, 0xcf, 0xf0, 0x5b, 0x49, 0xa2, 0x5d, 0x40, 0x7a, 0x23, 0x26, 0xa4, 0x7a, 0x83, 0x8a, 0xb7, 0x8b, 0xd2, 0x1a, 0xbf, 0xea, 0x02, 0x24, 0x08, 0x5f, 0x7b, 0xa9, 0xb1, 0xbe, 0x9d, 0x37}} ,
+ {{0xfc, 0x86, 0x4b, 0x08, 0xee, 0xe7, 0xa0, 0xfd, 0x21, 0x45, 0x09, 0x34, 0xc1, 0x61, 0x32, 0x23, 0xfc, 0x9b, 0x55, 0x48, 0x53, 0x99, 0xf7, 0x63, 0xd0, 0x99, 0xce, 0x01, 0xe0, 0x9f, 0xeb, 0x28}}},
+{{{0x47, 0xfc, 0xab, 0x5a, 0x17, 0xf0, 0x85, 0x56, 0x3a, 0x30, 0x86, 0x20, 0x28, 0x4b, 0x8e, 0x44, 0x74, 0x3a, 0x6e, 0x02, 0xf1, 0x32, 0x8f, 0x9f, 0x3f, 0x08, 0x35, 0xe9, 0xca, 0x16, 0x5f, 0x6e}} ,
+ {{0x1c, 0x59, 0x1c, 0x65, 0x5d, 0x34, 0xa4, 0x09, 0xcd, 0x13, 0x9c, 0x70, 0x7d, 0xb1, 0x2a, 0xc5, 0x88, 0xaf, 0x0b, 0x60, 0xc7, 0x9f, 0x34, 0x8d, 0xd6, 0xb7, 0x7f, 0xea, 0x78, 0x65, 0x8d, 0x77}}},
+{{{0x56, 0xa5, 0xc2, 0x0c, 0xdd, 0xbc, 0xb8, 0x20, 0x6d, 0x57, 0x61, 0xb5, 0xfb, 0x78, 0xb5, 0xd4, 0x49, 0x54, 0x90, 0x26, 0xc1, 0xcb, 0xe9, 0xe6, 0xbf, 0xec, 0x1d, 0x4e, 0xed, 0x07, 0x7e, 0x5e}} ,
+ {{0xc7, 0xf6, 0x6c, 0x56, 0x31, 0x20, 0x14, 0x0e, 0xa8, 0xd9, 0x27, 0xc1, 0x9a, 0x3d, 0x1b, 0x7d, 0x0e, 0x26, 0xd3, 0x81, 0xaa, 0xeb, 0xf5, 0x6b, 0x79, 0x02, 0xf1, 0x51, 0x5c, 0x75, 0x55, 0x0f}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x0a, 0x34, 0xcd, 0x82, 0x3c, 0x33, 0x09, 0x54, 0xd2, 0x61, 0x39, 0x30, 0x9b, 0xfd, 0xef, 0x21, 0x26, 0xd4, 0x70, 0xfa, 0xee, 0xf9, 0x31, 0x33, 0x73, 0x84, 0xd0, 0xb3, 0x81, 0xbf, 0xec, 0x2e}} ,
+ {{0xe8, 0x93, 0x8b, 0x00, 0x64, 0xf7, 0x9c, 0xb8, 0x74, 0xe0, 0xe6, 0x49, 0x48, 0x4d, 0x4d, 0x48, 0xb6, 0x19, 0xa1, 0x40, 0xb7, 0xd9, 0x32, 0x41, 0x7c, 0x82, 0x37, 0xa1, 0x2d, 0xdc, 0xd2, 0x54}}},
+{{{0x68, 0x2b, 0x4a, 0x5b, 0xd5, 0xc7, 0x51, 0x91, 0x1d, 0xe1, 0x2a, 0x4b, 0xc4, 0x47, 0xf1, 0xbc, 0x7a, 0xb3, 0xcb, 0xc8, 0xb6, 0x7c, 0xac, 0x90, 0x05, 0xfd, 0xf3, 0xf9, 0x52, 0x3a, 0x11, 0x6b}} ,
+ {{0x3d, 0xc1, 0x27, 0xf3, 0x59, 0x43, 0x95, 0x90, 0xc5, 0x96, 0x79, 0xf5, 0xf4, 0x95, 0x65, 0x29, 0x06, 0x9c, 0x51, 0x05, 0x18, 0xda, 0xb8, 0x2e, 0x79, 0x7e, 0x69, 0x59, 0x71, 0x01, 0xeb, 0x1a}}},
+{{{0x15, 0x06, 0x49, 0xb6, 0x8a, 0x3c, 0xea, 0x2f, 0x34, 0x20, 0x14, 0xc3, 0xaa, 0xd6, 0xaf, 0x2c, 0x3e, 0xbd, 0x65, 0x20, 0xe2, 0x4d, 0x4b, 0x3b, 0xeb, 0x9f, 0x4a, 0xc3, 0xad, 0xa4, 0x3b, 0x60}} ,
+ {{0xbc, 0x58, 0xe6, 0xc0, 0x95, 0x2a, 0x2a, 0x81, 0x9a, 0x7a, 0xf3, 0xd2, 0x06, 0xbe, 0x48, 0xbc, 0x0c, 0xc5, 0x46, 0xe0, 0x6a, 0xd4, 0xac, 0x0f, 0xd9, 0xcc, 0x82, 0x34, 0x2c, 0xaf, 0xdb, 0x1f}}},
+{{{0xf7, 0x17, 0x13, 0xbd, 0xfb, 0xbc, 0xd2, 0xec, 0x45, 0xb3, 0x15, 0x31, 0xe9, 0xaf, 0x82, 0x84, 0x3d, 0x28, 0xc6, 0xfc, 0x11, 0xf5, 0x41, 0xb5, 0x8b, 0xd3, 0x12, 0x76, 0x52, 0xe7, 0x1a, 0x3c}} ,
+ {{0x4e, 0x36, 0x11, 0x07, 0xa2, 0x15, 0x20, 0x51, 0xc4, 0x2a, 0xc3, 0x62, 0x8b, 0x5e, 0x7f, 0xa6, 0x0f, 0xf9, 0x45, 0x85, 0x6c, 0x11, 0x86, 0xb7, 0x7e, 0xe5, 0xd7, 0xf9, 0xc3, 0x91, 0x1c, 0x05}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xea, 0xd6, 0xde, 0x29, 0x3a, 0x00, 0xb9, 0x02, 0x59, 0xcb, 0x26, 0xc4, 0xba, 0x99, 0xb1, 0x97, 0x2f, 0x8e, 0x00, 0x92, 0x26, 0x4f, 0x52, 0xeb, 0x47, 0x1b, 0x89, 0x8b, 0x24, 0xc0, 0x13, 0x7d}} ,
+ {{0xd5, 0x20, 0x5b, 0x80, 0xa6, 0x80, 0x20, 0x95, 0xc3, 0xe9, 0x9f, 0x8e, 0x87, 0x9e, 0x1e, 0x9e, 0x7a, 0xc7, 0xcc, 0x75, 0x6c, 0xa5, 0xf1, 0x91, 0x1a, 0xa8, 0x01, 0x2c, 0xab, 0x76, 0xa9, 0x59}}},
+{{{0xde, 0xc9, 0xb1, 0x31, 0x10, 0x16, 0xaa, 0x35, 0x14, 0x6a, 0xd4, 0xb5, 0x34, 0x82, 0x71, 0xd2, 0x4a, 0x5d, 0x9a, 0x1f, 0x53, 0x26, 0x3c, 0xe5, 0x8e, 0x8d, 0x33, 0x7f, 0xff, 0xa9, 0xd5, 0x17}} ,
+ {{0x89, 0xaf, 0xf6, 0xa4, 0x64, 0xd5, 0x10, 0xe0, 0x1d, 0xad, 0xef, 0x44, 0xbd, 0xda, 0x83, 0xac, 0x7a, 0xa8, 0xf0, 0x1c, 0x07, 0xf9, 0xc3, 0x43, 0x6c, 0x3f, 0xb7, 0xd3, 0x87, 0x22, 0x02, 0x73}}},
+{{{0x64, 0x1d, 0x49, 0x13, 0x2f, 0x71, 0xec, 0x69, 0x87, 0xd0, 0x42, 0xee, 0x13, 0xec, 0xe3, 0xed, 0x56, 0x7b, 0xbf, 0xbd, 0x8c, 0x2f, 0x7d, 0x7b, 0x9d, 0x28, 0xec, 0x8e, 0x76, 0x2f, 0x6f, 0x08}} ,
+ {{0x22, 0xf5, 0x5f, 0x4d, 0x15, 0xef, 0xfc, 0x4e, 0x57, 0x03, 0x36, 0x89, 0xf0, 0xeb, 0x5b, 0x91, 0xd6, 0xe2, 0xca, 0x01, 0xa5, 0xee, 0x52, 0xec, 0xa0, 0x3c, 0x8f, 0x33, 0x90, 0x5a, 0x94, 0x72}}},
+{{{0x8a, 0x4b, 0xe7, 0x38, 0xbc, 0xda, 0xc2, 0xb0, 0x85, 0xe1, 0x4a, 0xfe, 0x2d, 0x44, 0x84, 0xcb, 0x20, 0x6b, 0x2d, 0xbf, 0x11, 0x9c, 0xd7, 0xbe, 0xd3, 0x3e, 0x5f, 0xbf, 0x68, 0xbc, 0xa8, 0x07}} ,
+ {{0x01, 0x89, 0x28, 0x22, 0x6a, 0x78, 0xaa, 0x29, 0x03, 0xc8, 0x74, 0x95, 0x03, 0x3e, 0xdc, 0xbd, 0x07, 0x13, 0xa8, 0xa2, 0x20, 0x2d, 0xb3, 0x18, 0x70, 0x42, 0xfd, 0x7a, 0xc4, 0xd7, 0x49, 0x72}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x02, 0xff, 0x32, 0x2b, 0x5c, 0x93, 0x54, 0x32, 0xe8, 0x57, 0x54, 0x1a, 0x8b, 0x33, 0x60, 0x65, 0xd3, 0x67, 0xa4, 0xc1, 0x26, 0xc4, 0xa4, 0x34, 0x1f, 0x9b, 0xa7, 0xa9, 0xf4, 0xd9, 0x4f, 0x5b}} ,
+ {{0x46, 0x8d, 0xb0, 0x33, 0x54, 0x26, 0x5b, 0x68, 0xdf, 0xbb, 0xc5, 0xec, 0xc2, 0xf9, 0x3c, 0x5a, 0x37, 0xc1, 0x8e, 0x27, 0x47, 0xaa, 0x49, 0x5a, 0xf8, 0xfb, 0x68, 0x04, 0x23, 0xd1, 0xeb, 0x40}}},
+{{{0x65, 0xa5, 0x11, 0x84, 0x8a, 0x67, 0x9d, 0x9e, 0xd1, 0x44, 0x68, 0x7a, 0x34, 0xe1, 0x9f, 0xa3, 0x54, 0xcd, 0x07, 0xca, 0x79, 0x1f, 0x54, 0x2f, 0x13, 0x70, 0x4e, 0xee, 0xa2, 0xfa, 0xe7, 0x5d}} ,
+ {{0x36, 0xec, 0x54, 0xf8, 0xce, 0xe4, 0x85, 0xdf, 0xf6, 0x6f, 0x1d, 0x90, 0x08, 0xbc, 0xe8, 0xc0, 0x92, 0x2d, 0x43, 0x6b, 0x92, 0xa9, 0x8e, 0xab, 0x0a, 0x2e, 0x1c, 0x1e, 0x64, 0x23, 0x9f, 0x2c}}},
+{{{0xa7, 0xd6, 0x2e, 0xd5, 0xcc, 0xd4, 0xcb, 0x5a, 0x3b, 0xa7, 0xf9, 0x46, 0x03, 0x1d, 0xad, 0x2b, 0x34, 0x31, 0x90, 0x00, 0x46, 0x08, 0x82, 0x14, 0xc4, 0xe0, 0x9c, 0xf0, 0xe3, 0x55, 0x43, 0x31}} ,
+ {{0x60, 0xd6, 0xdd, 0x78, 0xe6, 0xd4, 0x22, 0x42, 0x1f, 0x00, 0xf9, 0xb1, 0x6a, 0x63, 0xe2, 0x92, 0x59, 0xd1, 0x1a, 0xb7, 0x00, 0x54, 0x29, 0xc9, 0xc1, 0xf6, 0x6f, 0x7a, 0xc5, 0x3c, 0x5f, 0x65}}},
+{{{0x27, 0x4f, 0xd0, 0x72, 0xb1, 0x11, 0x14, 0x27, 0x15, 0x94, 0x48, 0x81, 0x7e, 0x74, 0xd8, 0x32, 0xd5, 0xd1, 0x11, 0x28, 0x60, 0x63, 0x36, 0x32, 0x37, 0xb5, 0x13, 0x1c, 0xa0, 0x37, 0xe3, 0x74}} ,
+ {{0xf1, 0x25, 0x4e, 0x11, 0x96, 0x67, 0xe6, 0x1c, 0xc2, 0xb2, 0x53, 0xe2, 0xda, 0x85, 0xee, 0xb2, 0x9f, 0x59, 0xf3, 0xba, 0xbd, 0xfa, 0xcf, 0x6e, 0xf9, 0xda, 0xa4, 0xb3, 0x02, 0x8f, 0x64, 0x08}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x34, 0x94, 0xf2, 0x64, 0x54, 0x47, 0x37, 0x07, 0x40, 0x8a, 0x20, 0xba, 0x4a, 0x55, 0xd7, 0x3f, 0x47, 0xba, 0x25, 0x23, 0x14, 0xb0, 0x2c, 0xe8, 0x55, 0xa8, 0xa6, 0xef, 0x51, 0xbd, 0x6f, 0x6a}} ,
+ {{0x71, 0xd6, 0x16, 0x76, 0xb2, 0x06, 0xea, 0x79, 0xf5, 0xc4, 0xc3, 0x52, 0x7e, 0x61, 0xd1, 0xe1, 0xad, 0x70, 0x78, 0x1d, 0x16, 0x11, 0xf8, 0x7c, 0x2b, 0xfc, 0x55, 0x9f, 0x52, 0xf8, 0xf5, 0x16}}},
+{{{0x34, 0x96, 0x9a, 0xf6, 0xc5, 0xe0, 0x14, 0x03, 0x24, 0x0e, 0x4c, 0xad, 0x9e, 0x9a, 0x70, 0x23, 0x96, 0xb2, 0xf1, 0x2e, 0x9d, 0xc3, 0x32, 0x9b, 0x54, 0xa5, 0x73, 0xde, 0x88, 0xb1, 0x3e, 0x24}} ,
+ {{0xf6, 0xe2, 0x4c, 0x1f, 0x5b, 0xb2, 0xaf, 0x82, 0xa5, 0xcf, 0x81, 0x10, 0x04, 0xef, 0xdb, 0xa2, 0xcc, 0x24, 0xb2, 0x7e, 0x0b, 0x7a, 0xeb, 0x01, 0xd8, 0x52, 0xf4, 0x51, 0x89, 0x29, 0x79, 0x37}}},
+{{{0x74, 0xde, 0x12, 0xf3, 0x68, 0xb7, 0x66, 0xc3, 0xee, 0x68, 0xdc, 0x81, 0xb5, 0x55, 0x99, 0xab, 0xd9, 0x28, 0x63, 0x6d, 0x8b, 0x40, 0x69, 0x75, 0x6c, 0xcd, 0x5c, 0x2a, 0x7e, 0x32, 0x7b, 0x29}} ,
+ {{0x02, 0xcc, 0x22, 0x74, 0x4d, 0x19, 0x07, 0xc0, 0xda, 0xb5, 0x76, 0x51, 0x2a, 0xaa, 0xa6, 0x0a, 0x5f, 0x26, 0xd4, 0xbc, 0xaf, 0x48, 0x88, 0x7f, 0x02, 0xbc, 0xf2, 0xe1, 0xcf, 0xe9, 0xdd, 0x15}}},
+{{{0xed, 0xb5, 0x9a, 0x8c, 0x9a, 0xdd, 0x27, 0xf4, 0x7f, 0x47, 0xd9, 0x52, 0xa7, 0xcd, 0x65, 0xa5, 0x31, 0x22, 0xed, 0xa6, 0x63, 0x5b, 0x80, 0x4a, 0xad, 0x4d, 0xed, 0xbf, 0xee, 0x49, 0xb3, 0x06}} ,
+ {{0xf8, 0x64, 0x8b, 0x60, 0x90, 0xe9, 0xde, 0x44, 0x77, 0xb9, 0x07, 0x36, 0x32, 0xc2, 0x50, 0xf5, 0x65, 0xdf, 0x48, 0x4c, 0x37, 0xaa, 0x68, 0xab, 0x9a, 0x1f, 0x3e, 0xff, 0x89, 0x92, 0xa0, 0x07}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x7d, 0x4f, 0x9c, 0x19, 0xc0, 0x4a, 0x31, 0xec, 0xf9, 0xaa, 0xeb, 0xb2, 0x16, 0x9c, 0xa3, 0x66, 0x5f, 0xd1, 0xd4, 0xed, 0xb8, 0x92, 0x1c, 0xab, 0xda, 0xea, 0xd9, 0x57, 0xdf, 0x4c, 0x2a, 0x48}} ,
+ {{0x4b, 0xb0, 0x4e, 0x6e, 0x11, 0x3b, 0x51, 0xbd, 0x6a, 0xfd, 0xe4, 0x25, 0xa5, 0x5f, 0x11, 0x3f, 0x98, 0x92, 0x51, 0x14, 0xc6, 0x5f, 0x3c, 0x0b, 0xa8, 0xf7, 0xc2, 0x81, 0x43, 0xde, 0x91, 0x73}}},
+{{{0x3c, 0x8f, 0x9f, 0x33, 0x2a, 0x1f, 0x43, 0x33, 0x8f, 0x68, 0xff, 0x1f, 0x3d, 0x73, 0x6b, 0xbf, 0x68, 0xcc, 0x7d, 0x13, 0x6c, 0x24, 0x4b, 0xcc, 0x4d, 0x24, 0x0d, 0xfe, 0xde, 0x86, 0xad, 0x3b}} ,
+ {{0x79, 0x51, 0x81, 0x01, 0xdc, 0x73, 0x53, 0xe0, 0x6e, 0x9b, 0xea, 0x68, 0x3f, 0x5c, 0x14, 0x84, 0x53, 0x8d, 0x4b, 0xc0, 0x9f, 0x9f, 0x89, 0x2b, 0x8c, 0xba, 0x86, 0xfa, 0xf2, 0xcd, 0xe3, 0x2d}}},
+{{{0x06, 0xf9, 0x29, 0x5a, 0xdb, 0x3d, 0x84, 0x52, 0xab, 0xcc, 0x6b, 0x60, 0x9d, 0xb7, 0x4a, 0x0e, 0x36, 0x63, 0x91, 0xad, 0xa0, 0x95, 0xb0, 0x97, 0x89, 0x4e, 0xcf, 0x7d, 0x3c, 0xe5, 0x7c, 0x28}} ,
+ {{0x2e, 0x69, 0x98, 0xfd, 0xc6, 0xbd, 0xcc, 0xca, 0xdf, 0x9a, 0x44, 0x7e, 0x9d, 0xca, 0x89, 0x6d, 0xbf, 0x27, 0xc2, 0xf8, 0xcd, 0x46, 0x00, 0x2b, 0xb5, 0x58, 0x4e, 0xb7, 0x89, 0x09, 0xe9, 0x2d}}},
+{{{0x54, 0xbe, 0x75, 0xcb, 0x05, 0xb0, 0x54, 0xb7, 0xe7, 0x26, 0x86, 0x4a, 0xfc, 0x19, 0xcf, 0x27, 0x46, 0xd4, 0x22, 0x96, 0x5a, 0x11, 0xe8, 0xd5, 0x1b, 0xed, 0x71, 0xc5, 0x5d, 0xc8, 0xaf, 0x45}} ,
+ {{0x40, 0x7b, 0x77, 0x57, 0x49, 0x9e, 0x80, 0x39, 0x23, 0xee, 0x81, 0x0b, 0x22, 0xcf, 0xdb, 0x7a, 0x2f, 0x14, 0xb8, 0x57, 0x8f, 0xa1, 0x39, 0x1e, 0x77, 0xfc, 0x0b, 0xa6, 0xbf, 0x8a, 0x0c, 0x6c}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x77, 0x3a, 0xd4, 0xd8, 0x27, 0xcf, 0xe8, 0xa1, 0x72, 0x9d, 0xca, 0xdd, 0x0d, 0x96, 0xda, 0x79, 0xed, 0x56, 0x42, 0x15, 0x60, 0xc7, 0x1c, 0x6b, 0x26, 0x30, 0xf6, 0x6a, 0x95, 0x67, 0xf3, 0x0a}} ,
+ {{0xc5, 0x08, 0xa4, 0x2b, 0x2f, 0xbd, 0x31, 0x81, 0x2a, 0xa6, 0xb6, 0xe4, 0x00, 0x91, 0xda, 0x3d, 0xb2, 0xb0, 0x96, 0xce, 0x8a, 0xd2, 0x8d, 0x70, 0xb3, 0xd3, 0x34, 0x01, 0x90, 0x8d, 0x10, 0x21}}},
+{{{0x33, 0x0d, 0xe7, 0xba, 0x4f, 0x07, 0xdf, 0x8d, 0xea, 0x7d, 0xa0, 0xc5, 0xd6, 0xb1, 0xb0, 0xe5, 0x57, 0x1b, 0x5b, 0xf5, 0x45, 0x13, 0x14, 0x64, 0x5a, 0xeb, 0x5c, 0xfc, 0x54, 0x01, 0x76, 0x2b}} ,
+ {{0x02, 0x0c, 0xc2, 0xaf, 0x96, 0x36, 0xfe, 0x4a, 0xe2, 0x54, 0x20, 0x6a, 0xeb, 0xb2, 0x9f, 0x62, 0xd7, 0xce, 0xa2, 0x3f, 0x20, 0x11, 0x34, 0x37, 0xe0, 0x42, 0xed, 0x6f, 0xf9, 0x1a, 0xc8, 0x7d}}},
+{{{0xd8, 0xb9, 0x11, 0xe8, 0x36, 0x3f, 0x42, 0xc1, 0xca, 0xdc, 0xd3, 0xf1, 0xc8, 0x23, 0x3d, 0x4f, 0x51, 0x7b, 0x9d, 0x8d, 0xd8, 0xe4, 0xa0, 0xaa, 0xf3, 0x04, 0xd6, 0x11, 0x93, 0xc8, 0x35, 0x45}} ,
+ {{0x61, 0x36, 0xd6, 0x08, 0x90, 0xbf, 0xa7, 0x7a, 0x97, 0x6c, 0x0f, 0x84, 0xd5, 0x33, 0x2d, 0x37, 0xc9, 0x6a, 0x80, 0x90, 0x3d, 0x0a, 0xa2, 0xaa, 0xe1, 0xb8, 0x84, 0xba, 0x61, 0x36, 0xdd, 0x69}}},
+{{{0x6b, 0xdb, 0x5b, 0x9c, 0xc6, 0x92, 0xbc, 0x23, 0xaf, 0xc5, 0xb8, 0x75, 0xf8, 0x42, 0xfa, 0xd6, 0xb6, 0x84, 0x94, 0x63, 0x98, 0x93, 0x48, 0x78, 0x38, 0xcd, 0xbb, 0x18, 0x34, 0xc3, 0xdb, 0x67}} ,
+ {{0x96, 0xf3, 0x3a, 0x09, 0x56, 0xb0, 0x6f, 0x7c, 0x51, 0x1e, 0x1b, 0x39, 0x48, 0xea, 0xc9, 0x0c, 0x25, 0xa2, 0x7a, 0xca, 0xe7, 0x92, 0xfc, 0x59, 0x30, 0xa3, 0x89, 0x85, 0xdf, 0x6f, 0x43, 0x38}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x79, 0x84, 0x44, 0x19, 0xbd, 0xe9, 0x54, 0xc4, 0xc0, 0x6e, 0x2a, 0xa8, 0xa8, 0x9b, 0x43, 0xd5, 0x71, 0x22, 0x5f, 0xdc, 0x01, 0xfa, 0xdf, 0xb3, 0xb8, 0x47, 0x4b, 0x0a, 0xa5, 0x44, 0xea, 0x29}} ,
+ {{0x05, 0x90, 0x50, 0xaf, 0x63, 0x5f, 0x9d, 0x9e, 0xe1, 0x9d, 0x38, 0x97, 0x1f, 0x6c, 0xac, 0x30, 0x46, 0xb2, 0x6a, 0x19, 0xd1, 0x4b, 0xdb, 0xbb, 0x8c, 0xda, 0x2e, 0xab, 0xc8, 0x5a, 0x77, 0x6c}}},
+{{{0x2b, 0xbe, 0xaf, 0xa1, 0x6d, 0x2f, 0x0b, 0xb1, 0x8f, 0xe3, 0xe0, 0x38, 0xcd, 0x0b, 0x41, 0x1b, 0x4a, 0x15, 0x07, 0xf3, 0x6f, 0xdc, 0xb8, 0xe9, 0xde, 0xb2, 0xa3, 0x40, 0x01, 0xa6, 0x45, 0x1e}} ,
+ {{0x76, 0x0a, 0xda, 0x8d, 0x2c, 0x07, 0x3f, 0x89, 0x7d, 0x04, 0xad, 0x43, 0x50, 0x6e, 0xd2, 0x47, 0xcb, 0x8a, 0xe6, 0x85, 0x1a, 0x24, 0xf3, 0xd2, 0x60, 0xfd, 0xdf, 0x73, 0xa4, 0x0d, 0x73, 0x0e}}},
+{{{0xfd, 0x67, 0x6b, 0x71, 0x9b, 0x81, 0x53, 0x39, 0x39, 0xf4, 0xb8, 0xd5, 0xc3, 0x30, 0x9b, 0x3b, 0x7c, 0xa3, 0xf0, 0xd0, 0x84, 0x21, 0xd6, 0xbf, 0xb7, 0x4c, 0x87, 0x13, 0x45, 0x2d, 0xa7, 0x55}} ,
+ {{0x5d, 0x04, 0xb3, 0x40, 0x28, 0x95, 0x2d, 0x30, 0x83, 0xec, 0x5e, 0xe4, 0xff, 0x75, 0xfe, 0x79, 0x26, 0x9d, 0x1d, 0x36, 0xcd, 0x0a, 0x15, 0xd2, 0x24, 0x14, 0x77, 0x71, 0xd7, 0x8a, 0x1b, 0x04}}},
+{{{0x5d, 0x93, 0xc9, 0xbe, 0xaa, 0x90, 0xcd, 0x9b, 0xfb, 0x73, 0x7e, 0xb0, 0x64, 0x98, 0x57, 0x44, 0x42, 0x41, 0xb1, 0xaf, 0xea, 0xc1, 0xc3, 0x22, 0xff, 0x60, 0x46, 0xcb, 0x61, 0x81, 0x70, 0x61}} ,
+ {{0x0d, 0x82, 0xb9, 0xfe, 0x21, 0xcd, 0xc4, 0xf5, 0x98, 0x0c, 0x4e, 0x72, 0xee, 0x87, 0x49, 0xf8, 0xa1, 0x95, 0xdf, 0x8f, 0x2d, 0xbd, 0x21, 0x06, 0x7c, 0x15, 0xe8, 0x12, 0x6d, 0x93, 0xd6, 0x38}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x91, 0xf7, 0x51, 0xd9, 0xef, 0x7d, 0x42, 0x01, 0x13, 0xe9, 0xb8, 0x7f, 0xa6, 0x49, 0x17, 0x64, 0x21, 0x80, 0x83, 0x2c, 0x63, 0x4c, 0x60, 0x09, 0x59, 0x91, 0x92, 0x77, 0x39, 0x51, 0xf4, 0x48}} ,
+ {{0x60, 0xd5, 0x22, 0x83, 0x08, 0x2f, 0xff, 0x99, 0x3e, 0x69, 0x6d, 0x88, 0xda, 0xe7, 0x5b, 0x52, 0x26, 0x31, 0x2a, 0xe5, 0x89, 0xde, 0x68, 0x90, 0xb6, 0x22, 0x5a, 0xbd, 0xd3, 0x85, 0x53, 0x31}}},
+{{{0xd8, 0xce, 0xdc, 0xf9, 0x3c, 0x4b, 0xa2, 0x1d, 0x2c, 0x2f, 0x36, 0xbe, 0x7a, 0xfc, 0xcd, 0xbc, 0xdc, 0xf9, 0x30, 0xbd, 0xff, 0x05, 0xc7, 0xe4, 0x8e, 0x17, 0x62, 0xf8, 0x4d, 0xa0, 0x56, 0x79}} ,
+ {{0x82, 0xe7, 0xf6, 0xba, 0x53, 0x84, 0x0a, 0xa3, 0x34, 0xff, 0x3c, 0xa3, 0x6a, 0xa1, 0x37, 0xea, 0xdd, 0xb6, 0x95, 0xb3, 0x78, 0x19, 0x76, 0x1e, 0x55, 0x2f, 0x77, 0x2e, 0x7f, 0xc1, 0xea, 0x5e}}},
+{{{0x83, 0xe1, 0x6e, 0xa9, 0x07, 0x33, 0x3e, 0x83, 0xff, 0xcb, 0x1c, 0x9f, 0xb1, 0xa3, 0xb4, 0xc9, 0xe1, 0x07, 0x97, 0xff, 0xf8, 0x23, 0x8f, 0xce, 0x40, 0xfd, 0x2e, 0x5e, 0xdb, 0x16, 0x43, 0x2d}} ,
+ {{0xba, 0x38, 0x02, 0xf7, 0x81, 0x43, 0x83, 0xa3, 0x20, 0x4f, 0x01, 0x3b, 0x8a, 0x04, 0x38, 0x31, 0xc6, 0x0f, 0xc8, 0xdf, 0xd7, 0xfa, 0x2f, 0x88, 0x3f, 0xfc, 0x0c, 0x76, 0xc4, 0xa6, 0x45, 0x72}}},
+{{{0xbb, 0x0c, 0xbc, 0x6a, 0xa4, 0x97, 0x17, 0x93, 0x2d, 0x6f, 0xde, 0x72, 0x10, 0x1c, 0x08, 0x2c, 0x0f, 0x80, 0x32, 0x68, 0x27, 0xd4, 0xab, 0xdd, 0xc5, 0x58, 0x61, 0x13, 0x6d, 0x11, 0x1e, 0x4d}} ,
+ {{0x1a, 0xb9, 0xc9, 0x10, 0xfb, 0x1e, 0x4e, 0xf4, 0x84, 0x4b, 0x8a, 0x5e, 0x7b, 0x4b, 0xe8, 0x43, 0x8c, 0x8f, 0x00, 0xb5, 0x54, 0x13, 0xc5, 0x5c, 0xb6, 0x35, 0x4e, 0x9d, 0xe4, 0x5b, 0x41, 0x6d}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x15, 0x7d, 0x12, 0x48, 0x82, 0x14, 0x42, 0xcd, 0x32, 0xd4, 0x4b, 0xc1, 0x72, 0x61, 0x2a, 0x8c, 0xec, 0xe2, 0xf8, 0x24, 0x45, 0x94, 0xe3, 0xbe, 0xdd, 0x67, 0xa8, 0x77, 0x5a, 0xae, 0x5b, 0x4b}} ,
+ {{0xcb, 0x77, 0x9a, 0x20, 0xde, 0xb8, 0x23, 0xd9, 0xa0, 0x0f, 0x8c, 0x7b, 0xa5, 0xcb, 0xae, 0xb6, 0xec, 0x42, 0x67, 0x0e, 0x58, 0xa4, 0x75, 0x98, 0x21, 0x71, 0x84, 0xb3, 0xe0, 0x76, 0x94, 0x73}}},
+{{{0xdf, 0xfc, 0x69, 0x28, 0x23, 0x3f, 0x5b, 0xf8, 0x3b, 0x24, 0x37, 0xf3, 0x1d, 0xd5, 0x22, 0x6b, 0xd0, 0x98, 0xa8, 0x6c, 0xcf, 0xff, 0x06, 0xe1, 0x13, 0xdf, 0xb9, 0xc1, 0x0c, 0xa9, 0xbf, 0x33}} ,
+ {{0xd9, 0x81, 0xda, 0xb2, 0x4f, 0x82, 0x9d, 0x43, 0x81, 0x09, 0xf1, 0xd2, 0x01, 0xef, 0xac, 0xf4, 0x2d, 0x7d, 0x01, 0x09, 0xf1, 0xff, 0xa5, 0x9f, 0xe5, 0xca, 0x27, 0x63, 0xdb, 0x20, 0xb1, 0x53}}},
+{{{0x67, 0x02, 0xe8, 0xad, 0xa9, 0x34, 0xd4, 0xf0, 0x15, 0x81, 0xaa, 0xc7, 0x4d, 0x87, 0x94, 0xea, 0x75, 0xe7, 0x4c, 0x94, 0x04, 0x0e, 0x69, 0x87, 0xe7, 0x51, 0x91, 0x10, 0x03, 0xc7, 0xbe, 0x56}} ,
+ {{0x32, 0xfb, 0x86, 0xec, 0x33, 0x6b, 0x2e, 0x51, 0x2b, 0xc8, 0xfa, 0x6c, 0x70, 0x47, 0x7e, 0xce, 0x05, 0x0c, 0x71, 0xf3, 0xb4, 0x56, 0xa6, 0xdc, 0xcc, 0x78, 0x07, 0x75, 0xd0, 0xdd, 0xb2, 0x6a}}},
+{{{0xc6, 0xef, 0xb9, 0xc0, 0x2b, 0x22, 0x08, 0x1e, 0x71, 0x70, 0xb3, 0x35, 0x9c, 0x7a, 0x01, 0x92, 0x44, 0x9a, 0xf6, 0xb0, 0x58, 0x95, 0xc1, 0x9b, 0x02, 0xed, 0x2d, 0x7c, 0x34, 0x29, 0x49, 0x44}} ,
+ {{0x45, 0x62, 0x1d, 0x2e, 0xff, 0x2a, 0x1c, 0x21, 0xa4, 0x25, 0x7b, 0x0d, 0x8c, 0x15, 0x39, 0xfc, 0x8f, 0x7c, 0xa5, 0x7d, 0x1e, 0x25, 0xa3, 0x45, 0xd6, 0xab, 0xbd, 0xcb, 0xc5, 0x5e, 0x78, 0x77}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xd0, 0xd3, 0x42, 0xed, 0x1d, 0x00, 0x3c, 0x15, 0x2c, 0x9c, 0x77, 0x81, 0xd2, 0x73, 0xd1, 0x06, 0xd5, 0xc4, 0x7f, 0x94, 0xbb, 0x92, 0x2d, 0x2c, 0x4b, 0x45, 0x4b, 0xe9, 0x2a, 0x89, 0x6b, 0x2b}} ,
+ {{0xd2, 0x0c, 0x88, 0xc5, 0x48, 0x4d, 0xea, 0x0d, 0x4a, 0xc9, 0x52, 0x6a, 0x61, 0x79, 0xe9, 0x76, 0xf3, 0x85, 0x52, 0x5c, 0x1b, 0x2c, 0xe1, 0xd6, 0xc4, 0x0f, 0x18, 0x0e, 0x4e, 0xf6, 0x1c, 0x7f}}},
+{{{0xb4, 0x04, 0x2e, 0x42, 0xcb, 0x1f, 0x2b, 0x11, 0x51, 0x7b, 0x08, 0xac, 0xaa, 0x3e, 0x9e, 0x52, 0x60, 0xb7, 0xc2, 0x61, 0x57, 0x8c, 0x84, 0xd5, 0x18, 0xa6, 0x19, 0xfc, 0xb7, 0x75, 0x91, 0x1b}} ,
+ {{0xe8, 0x68, 0xca, 0x44, 0xc8, 0x38, 0x38, 0xcc, 0x53, 0x0a, 0x32, 0x35, 0xcc, 0x52, 0xcb, 0x0e, 0xf7, 0xc5, 0xe7, 0xec, 0x3d, 0x85, 0xcc, 0x58, 0xe2, 0x17, 0x47, 0xff, 0x9f, 0xa5, 0x30, 0x17}}},
+{{{0xe3, 0xae, 0xc8, 0xc1, 0x71, 0x75, 0x31, 0x00, 0x37, 0x41, 0x5c, 0x0e, 0x39, 0xda, 0x73, 0xa0, 0xc7, 0x97, 0x36, 0x6c, 0x5b, 0xf2, 0xee, 0x64, 0x0a, 0x3d, 0x89, 0x1e, 0x1d, 0x49, 0x8c, 0x37}} ,
+ {{0x4c, 0xe6, 0xb0, 0xc1, 0xa5, 0x2a, 0x82, 0x09, 0x08, 0xad, 0x79, 0x9c, 0x56, 0xf6, 0xf9, 0xc1, 0xd7, 0x7c, 0x39, 0x7f, 0x93, 0xca, 0x11, 0x55, 0xbf, 0x07, 0x1b, 0x82, 0x29, 0x69, 0x95, 0x5c}}},
+{{{0x87, 0xee, 0xa6, 0x56, 0x9e, 0xc2, 0x9a, 0x56, 0x24, 0x42, 0x85, 0x4d, 0x98, 0x31, 0x1e, 0x60, 0x4d, 0x87, 0x85, 0x04, 0xae, 0x46, 0x12, 0xf9, 0x8e, 0x7f, 0xe4, 0x7f, 0xf6, 0x1c, 0x37, 0x01}} ,
+ {{0x73, 0x4c, 0xb6, 0xc5, 0xc4, 0xe9, 0x6c, 0x85, 0x48, 0x4a, 0x5a, 0xac, 0xd9, 0x1f, 0x43, 0xf8, 0x62, 0x5b, 0xee, 0x98, 0x2a, 0x33, 0x8e, 0x79, 0xce, 0x61, 0x06, 0x35, 0xd8, 0xd7, 0xca, 0x71}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x72, 0xd3, 0xae, 0xa6, 0xca, 0x8f, 0xcd, 0xcc, 0x78, 0x8e, 0x19, 0x4d, 0xa7, 0xd2, 0x27, 0xe9, 0xa4, 0x3c, 0x16, 0x5b, 0x84, 0x80, 0xf9, 0xd0, 0xcc, 0x6a, 0x1e, 0xca, 0x1e, 0x67, 0xbd, 0x63}} ,
+ {{0x7b, 0x6e, 0x2a, 0xd2, 0x87, 0x48, 0xff, 0xa1, 0xca, 0xe9, 0x15, 0x85, 0xdc, 0xdb, 0x2c, 0x39, 0x12, 0x91, 0xa9, 0x20, 0xaa, 0x4f, 0x29, 0xf4, 0x15, 0x7a, 0xd2, 0xf5, 0x32, 0xcc, 0x60, 0x04}}},
+{{{0xe5, 0x10, 0x47, 0x3b, 0xfa, 0x90, 0xfc, 0x30, 0xb5, 0xea, 0x6f, 0x56, 0x8f, 0xfb, 0x0e, 0xa7, 0x3b, 0xc8, 0xb2, 0xff, 0x02, 0x7a, 0x33, 0x94, 0x93, 0x2a, 0x03, 0xe0, 0x96, 0x3a, 0x6c, 0x0f}} ,
+ {{0x5a, 0x63, 0x67, 0xe1, 0x9b, 0x47, 0x78, 0x9f, 0x38, 0x79, 0xac, 0x97, 0x66, 0x1d, 0x5e, 0x51, 0xee, 0x24, 0x42, 0xe8, 0x58, 0x4b, 0x8a, 0x03, 0x75, 0x86, 0x37, 0x86, 0xe2, 0x97, 0x4e, 0x3d}}},
+{{{0x3f, 0x75, 0x8e, 0xb4, 0xff, 0xd8, 0xdd, 0xd6, 0x37, 0x57, 0x9d, 0x6d, 0x3b, 0xbd, 0xd5, 0x60, 0x88, 0x65, 0x9a, 0xb9, 0x4a, 0x68, 0x84, 0xa2, 0x67, 0xdd, 0x17, 0x25, 0x97, 0x04, 0x8b, 0x5e}} ,
+ {{0xbb, 0x40, 0x5e, 0xbc, 0x16, 0x92, 0x05, 0xc4, 0xc0, 0x4e, 0x72, 0x90, 0x0e, 0xab, 0xcf, 0x8a, 0xed, 0xef, 0xb9, 0x2d, 0x3b, 0xf8, 0x43, 0x5b, 0xba, 0x2d, 0xeb, 0x2f, 0x52, 0xd2, 0xd1, 0x5a}}},
+{{{0x40, 0xb4, 0xab, 0xe6, 0xad, 0x9f, 0x46, 0x69, 0x4a, 0xb3, 0x8e, 0xaa, 0xea, 0x9c, 0x8a, 0x20, 0x16, 0x5d, 0x8c, 0x13, 0xbd, 0xf6, 0x1d, 0xc5, 0x24, 0xbd, 0x90, 0x2a, 0x1c, 0xc7, 0x13, 0x3b}} ,
+ {{0x54, 0xdc, 0x16, 0x0d, 0x18, 0xbe, 0x35, 0x64, 0x61, 0x52, 0x02, 0x80, 0xaf, 0x05, 0xf7, 0xa6, 0x42, 0xd3, 0x8f, 0x2e, 0x79, 0x26, 0xa8, 0xbb, 0xb2, 0x17, 0x48, 0xb2, 0x7a, 0x0a, 0x89, 0x14}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x20, 0xa8, 0x88, 0xe3, 0x91, 0xc0, 0x6e, 0xbb, 0x8a, 0x27, 0x82, 0x51, 0x83, 0xb2, 0x28, 0xa9, 0x83, 0xeb, 0xa6, 0xa9, 0x4d, 0x17, 0x59, 0x22, 0x54, 0x00, 0x50, 0x45, 0xcb, 0x48, 0x4b, 0x18}} ,
+ {{0x33, 0x7c, 0xe7, 0x26, 0xba, 0x4d, 0x32, 0xfe, 0x53, 0xf4, 0xfa, 0x83, 0xe3, 0xa5, 0x79, 0x66, 0x73, 0xef, 0x80, 0x23, 0x68, 0xc2, 0x60, 0xdd, 0xa9, 0x33, 0xdc, 0x03, 0x7a, 0xe0, 0xe0, 0x3e}}},
+{{{0x34, 0x5c, 0x13, 0xfb, 0xc0, 0xe3, 0x78, 0x2b, 0x54, 0x58, 0x22, 0x9b, 0x76, 0x81, 0x7f, 0x93, 0x9c, 0x25, 0x3c, 0xd2, 0xe9, 0x96, 0x21, 0x26, 0x08, 0xf5, 0xed, 0x95, 0x11, 0xae, 0x04, 0x5a}} ,
+ {{0xb9, 0xe8, 0xc5, 0x12, 0x97, 0x1f, 0x83, 0xfe, 0x3e, 0x94, 0x99, 0xd4, 0x2d, 0xf9, 0x52, 0x59, 0x5c, 0x82, 0xa6, 0xf0, 0x75, 0x7e, 0xe8, 0xec, 0xcc, 0xac, 0x18, 0x21, 0x09, 0x67, 0x66, 0x67}}},
+{{{0xb3, 0x40, 0x29, 0xd1, 0xcb, 0x1b, 0x08, 0x9e, 0x9c, 0xb7, 0x53, 0xb9, 0x3b, 0x71, 0x08, 0x95, 0x12, 0x1a, 0x58, 0xaf, 0x7e, 0x82, 0x52, 0x43, 0x4f, 0x11, 0x39, 0xf4, 0x93, 0x1a, 0x26, 0x05}} ,
+ {{0x6e, 0x44, 0xa3, 0xf9, 0x64, 0xaf, 0xe7, 0x6d, 0x7d, 0xdf, 0x1e, 0xac, 0x04, 0xea, 0x3b, 0x5f, 0x9b, 0xe8, 0x24, 0x9d, 0x0e, 0xe5, 0x2e, 0x3e, 0xdf, 0xa9, 0xf7, 0xd4, 0x50, 0x71, 0xf0, 0x78}}},
+{{{0x3e, 0xa8, 0x38, 0xc2, 0x57, 0x56, 0x42, 0x9a, 0xb1, 0xe2, 0xf8, 0x45, 0xaa, 0x11, 0x48, 0x5f, 0x17, 0xc4, 0x54, 0x27, 0xdc, 0x5d, 0xaa, 0xdd, 0x41, 0xbc, 0xdf, 0x81, 0xb9, 0x53, 0xee, 0x52}} ,
+ {{0xc3, 0xf1, 0xa7, 0x6d, 0xb3, 0x5f, 0x92, 0x6f, 0xcc, 0x91, 0xb8, 0x95, 0x05, 0xdf, 0x3c, 0x64, 0x57, 0x39, 0x61, 0x51, 0xad, 0x8c, 0x38, 0x7b, 0xc8, 0xde, 0x00, 0x34, 0xbe, 0xa1, 0xb0, 0x7e}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x25, 0x24, 0x1d, 0x8a, 0x67, 0x20, 0xee, 0x42, 0xeb, 0x38, 0xed, 0x0b, 0x8b, 0xcd, 0x46, 0x9d, 0x5e, 0x6b, 0x1e, 0x24, 0x9d, 0x12, 0x05, 0x1a, 0xcc, 0x05, 0x4e, 0x92, 0x38, 0xe1, 0x1f, 0x50}} ,
+ {{0x4e, 0xee, 0x1c, 0x91, 0xe6, 0x11, 0xbd, 0x8e, 0x55, 0x1a, 0x18, 0x75, 0x66, 0xaf, 0x4d, 0x7b, 0x0f, 0xae, 0x6d, 0x85, 0xca, 0x82, 0x58, 0x21, 0x9c, 0x18, 0xe0, 0xed, 0xec, 0x22, 0x80, 0x2f}}},
+{{{0x68, 0x3b, 0x0a, 0x39, 0x1d, 0x6a, 0x15, 0x57, 0xfc, 0xf0, 0x63, 0x54, 0xdb, 0x39, 0xdb, 0xe8, 0x5c, 0x64, 0xff, 0xa0, 0x09, 0x4f, 0x3b, 0xb7, 0x32, 0x60, 0x99, 0x94, 0xfd, 0x94, 0x82, 0x2d}} ,
+ {{0x24, 0xf6, 0x5a, 0x44, 0xf1, 0x55, 0x2c, 0xdb, 0xea, 0x7c, 0x84, 0x7c, 0x01, 0xac, 0xe3, 0xfd, 0xc9, 0x27, 0xc1, 0x5a, 0xb9, 0xde, 0x4f, 0x5a, 0x90, 0xdd, 0xc6, 0x67, 0xaa, 0x6f, 0x8a, 0x3a}}},
+{{{0x78, 0x52, 0x87, 0xc9, 0x97, 0x63, 0xb1, 0xdd, 0x54, 0x5f, 0xc1, 0xf8, 0xf1, 0x06, 0xa6, 0xa8, 0xa3, 0x88, 0x82, 0xd4, 0xcb, 0xa6, 0x19, 0xdd, 0xd1, 0x11, 0x87, 0x08, 0x17, 0x4c, 0x37, 0x2a}} ,
+ {{0xa1, 0x0c, 0xf3, 0x08, 0x43, 0xd9, 0x24, 0x1e, 0x83, 0xa7, 0xdf, 0x91, 0xca, 0xbd, 0x69, 0x47, 0x8d, 0x1b, 0xe2, 0xb9, 0x4e, 0xb5, 0xe1, 0x76, 0xb3, 0x1c, 0x93, 0x03, 0xce, 0x5f, 0xb3, 0x5a}}},
+{{{0x1d, 0xda, 0xe4, 0x61, 0x03, 0x50, 0xa9, 0x8b, 0x68, 0x18, 0xef, 0xb2, 0x1c, 0x84, 0x3b, 0xa2, 0x44, 0x95, 0xa3, 0x04, 0x3b, 0xd6, 0x99, 0x00, 0xaf, 0x76, 0x42, 0x67, 0x02, 0x7d, 0x85, 0x56}} ,
+ {{0xce, 0x72, 0x0e, 0x29, 0x84, 0xb2, 0x7d, 0xd2, 0x45, 0xbe, 0x57, 0x06, 0xed, 0x7f, 0xcf, 0xed, 0xcd, 0xef, 0x19, 0xd6, 0xbc, 0x15, 0x79, 0x64, 0xd2, 0x18, 0xe3, 0x20, 0x67, 0x3a, 0x54, 0x0b}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x52, 0xfd, 0x04, 0xc5, 0xfb, 0x99, 0xe7, 0xe8, 0xfb, 0x8c, 0xe1, 0x42, 0x03, 0xef, 0x9d, 0xd9, 0x9e, 0x4d, 0xf7, 0x80, 0xcf, 0x2e, 0xcc, 0x9b, 0x45, 0xc9, 0x7b, 0x7a, 0xbc, 0x37, 0xa8, 0x52}} ,
+ {{0x96, 0x11, 0x41, 0x8a, 0x47, 0x91, 0xfe, 0xb6, 0xda, 0x7a, 0x54, 0x63, 0xd1, 0x14, 0x35, 0x05, 0x86, 0x8c, 0xa9, 0x36, 0x3f, 0xf2, 0x85, 0x54, 0x4e, 0x92, 0xd8, 0x85, 0x01, 0x46, 0xd6, 0x50}}},
+{{{0x53, 0xcd, 0xf3, 0x86, 0x40, 0xe6, 0x39, 0x42, 0x95, 0xd6, 0xcb, 0x45, 0x1a, 0x20, 0xc8, 0x45, 0x4b, 0x32, 0x69, 0x04, 0xb1, 0xaf, 0x20, 0x46, 0xc7, 0x6b, 0x23, 0x5b, 0x69, 0xee, 0x30, 0x3f}} ,
+ {{0x70, 0x83, 0x47, 0xc0, 0xdb, 0x55, 0x08, 0xa8, 0x7b, 0x18, 0x6d, 0xf5, 0x04, 0x5a, 0x20, 0x0c, 0x4a, 0x8c, 0x60, 0xae, 0xae, 0x0f, 0x64, 0x55, 0x55, 0x2e, 0xd5, 0x1d, 0x53, 0x31, 0x42, 0x41}}},
+{{{0xca, 0xfc, 0x88, 0x6b, 0x96, 0x78, 0x0a, 0x8b, 0x83, 0xdc, 0xbc, 0xaf, 0x40, 0xb6, 0x8d, 0x7f, 0xef, 0xb4, 0xd1, 0x3f, 0xcc, 0xa2, 0x74, 0xc9, 0xc2, 0x92, 0x55, 0x00, 0xab, 0xdb, 0xbf, 0x4f}} ,
+ {{0x93, 0x1c, 0x06, 0x2d, 0x66, 0x65, 0x02, 0xa4, 0x97, 0x18, 0xfd, 0x00, 0xe7, 0xab, 0x03, 0xec, 0xce, 0xc1, 0xbf, 0x37, 0xf8, 0x13, 0x53, 0xa5, 0xe5, 0x0c, 0x3a, 0xa8, 0x55, 0xb9, 0xff, 0x68}}},
+{{{0xe4, 0xe6, 0x6d, 0x30, 0x7d, 0x30, 0x35, 0xc2, 0x78, 0x87, 0xf9, 0xfc, 0x6b, 0x5a, 0xc3, 0xb7, 0x65, 0xd8, 0x2e, 0xc7, 0xa5, 0x0c, 0xc6, 0xdc, 0x12, 0xaa, 0xd6, 0x4f, 0xc5, 0x38, 0xbc, 0x0e}} ,
+ {{0xe2, 0x3c, 0x76, 0x86, 0x38, 0xf2, 0x7b, 0x2c, 0x16, 0x78, 0x8d, 0xf5, 0xa4, 0x15, 0xda, 0xdb, 0x26, 0x85, 0xa0, 0x56, 0xdd, 0x1d, 0xe3, 0xb3, 0xfd, 0x40, 0xef, 0xf2, 0xd9, 0xa1, 0xb3, 0x04}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xdb, 0x49, 0x0e, 0xe6, 0x58, 0x10, 0x7a, 0x52, 0xda, 0xb5, 0x7d, 0x37, 0x6a, 0x3e, 0xa1, 0x78, 0xce, 0xc7, 0x1c, 0x24, 0x23, 0xdb, 0x7d, 0xfb, 0x8c, 0x8d, 0xdc, 0x30, 0x67, 0x69, 0x75, 0x3b}} ,
+ {{0xa9, 0xea, 0x6d, 0x16, 0x16, 0x60, 0xf4, 0x60, 0x87, 0x19, 0x44, 0x8c, 0x4a, 0x8b, 0x3e, 0xfb, 0x16, 0x00, 0x00, 0x54, 0xa6, 0x9e, 0x9f, 0xef, 0xcf, 0xd9, 0xd2, 0x4c, 0x74, 0x31, 0xd0, 0x34}}},
+{{{0xa4, 0xeb, 0x04, 0xa4, 0x8c, 0x8f, 0x71, 0x27, 0x95, 0x85, 0x5d, 0x55, 0x4b, 0xb1, 0x26, 0x26, 0xc8, 0xae, 0x6a, 0x7d, 0xa2, 0x21, 0xca, 0xce, 0x38, 0xab, 0x0f, 0xd0, 0xd5, 0x2b, 0x6b, 0x00}} ,
+ {{0xe5, 0x67, 0x0c, 0xf1, 0x3a, 0x9a, 0xea, 0x09, 0x39, 0xef, 0xd1, 0x30, 0xbc, 0x33, 0xba, 0xb1, 0x6a, 0xc5, 0x27, 0x08, 0x7f, 0x54, 0x80, 0x3d, 0xab, 0xf6, 0x15, 0x7a, 0xc2, 0x40, 0x73, 0x72}}},
+{{{0x84, 0x56, 0x82, 0xb6, 0x12, 0x70, 0x7f, 0xf7, 0xf0, 0xbd, 0x5b, 0xa9, 0xd5, 0xc5, 0x5f, 0x59, 0xbf, 0x7f, 0xb3, 0x55, 0x22, 0x02, 0xc9, 0x44, 0x55, 0x87, 0x8f, 0x96, 0x98, 0x64, 0x6d, 0x15}} ,
+ {{0xb0, 0x8b, 0xaa, 0x1e, 0xec, 0xc7, 0xa5, 0x8f, 0x1f, 0x92, 0x04, 0xc6, 0x05, 0xf6, 0xdf, 0xa1, 0xcc, 0x1f, 0x81, 0xf5, 0x0e, 0x9c, 0x57, 0xdc, 0xe3, 0xbb, 0x06, 0x87, 0x1e, 0xfe, 0x23, 0x6c}}},
+{{{0xd8, 0x2b, 0x5b, 0x16, 0xea, 0x20, 0xf1, 0xd3, 0x68, 0x8f, 0xae, 0x5b, 0xd0, 0xa9, 0x1a, 0x19, 0xa8, 0x36, 0xfb, 0x2b, 0x57, 0x88, 0x7d, 0x90, 0xd5, 0xa6, 0xf3, 0xdc, 0x38, 0x89, 0x4e, 0x1f}} ,
+ {{0xcc, 0x19, 0xda, 0x9b, 0x3b, 0x43, 0x48, 0x21, 0x2e, 0x23, 0x4d, 0x3d, 0xae, 0xf8, 0x8c, 0xfc, 0xdd, 0xa6, 0x74, 0x37, 0x65, 0xca, 0xee, 0x1a, 0x19, 0x8e, 0x9f, 0x64, 0x6f, 0x0c, 0x8b, 0x5a}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x25, 0xb9, 0xc2, 0xf0, 0x72, 0xb8, 0x15, 0x16, 0xcc, 0x8d, 0x3c, 0x6f, 0x25, 0xed, 0xf4, 0x46, 0x2e, 0x0c, 0x60, 0x0f, 0xe2, 0x84, 0x34, 0x55, 0x89, 0x59, 0x34, 0x1b, 0xf5, 0x8d, 0xfe, 0x08}} ,
+ {{0xf8, 0xab, 0x93, 0xbc, 0x44, 0xba, 0x1b, 0x75, 0x4b, 0x49, 0x6f, 0xd0, 0x54, 0x2e, 0x63, 0xba, 0xb5, 0xea, 0xed, 0x32, 0x14, 0xc9, 0x94, 0xd8, 0xc5, 0xce, 0xf4, 0x10, 0x68, 0xe0, 0x38, 0x27}}},
+{{{0x74, 0x1c, 0x14, 0x9b, 0xd4, 0x64, 0x61, 0x71, 0x5a, 0xb6, 0x21, 0x33, 0x4f, 0xf7, 0x8e, 0xba, 0xa5, 0x48, 0x9a, 0xc7, 0xfa, 0x9a, 0xf0, 0xb4, 0x62, 0xad, 0xf2, 0x5e, 0xcc, 0x03, 0x24, 0x1a}} ,
+ {{0xf5, 0x76, 0xfd, 0xe4, 0xaf, 0xb9, 0x03, 0x59, 0xce, 0x63, 0xd2, 0x3b, 0x1f, 0xcd, 0x21, 0x0c, 0xad, 0x44, 0xa5, 0x97, 0xac, 0x80, 0x11, 0x02, 0x9b, 0x0c, 0xe5, 0x8b, 0xcd, 0xfb, 0x79, 0x77}}},
+{{{0x15, 0xbe, 0x9a, 0x0d, 0xba, 0x38, 0x72, 0x20, 0x8a, 0xf5, 0xbe, 0x59, 0x93, 0x79, 0xb7, 0xf6, 0x6a, 0x0c, 0x38, 0x27, 0x1a, 0x60, 0xf4, 0x86, 0x3b, 0xab, 0x5a, 0x00, 0xa0, 0xce, 0x21, 0x7d}} ,
+ {{0x6c, 0xba, 0x14, 0xc5, 0xea, 0x12, 0x9e, 0x2e, 0x82, 0x63, 0xce, 0x9b, 0x4a, 0xe7, 0x1d, 0xec, 0xf1, 0x2e, 0x51, 0x1c, 0xf4, 0xd0, 0x69, 0x15, 0x42, 0x9d, 0xa3, 0x3f, 0x0e, 0xbf, 0xe9, 0x5c}}},
+{{{0xe4, 0x0d, 0xf4, 0xbd, 0xee, 0x31, 0x10, 0xed, 0xcb, 0x12, 0x86, 0xad, 0xd4, 0x2f, 0x90, 0x37, 0x32, 0xc3, 0x0b, 0x73, 0xec, 0x97, 0x85, 0xa4, 0x01, 0x1c, 0x76, 0x35, 0xfe, 0x75, 0xdd, 0x71}} ,
+ {{0x11, 0xa4, 0x88, 0x9f, 0x3e, 0x53, 0x69, 0x3b, 0x1b, 0xe0, 0xf7, 0xba, 0x9b, 0xad, 0x4e, 0x81, 0x5f, 0xb5, 0x5c, 0xae, 0xbe, 0x67, 0x86, 0x37, 0x34, 0x8e, 0x07, 0x32, 0x45, 0x4a, 0x67, 0x39}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x90, 0x70, 0x58, 0x20, 0x03, 0x1e, 0x67, 0xb2, 0xc8, 0x9b, 0x58, 0xc5, 0xb1, 0xeb, 0x2d, 0x4a, 0xde, 0x82, 0x8c, 0xf2, 0xd2, 0x14, 0xb8, 0x70, 0x61, 0x4e, 0x73, 0xd6, 0x0b, 0x6b, 0x0d, 0x30}} ,
+ {{0x81, 0xfc, 0x55, 0x5c, 0xbf, 0xa7, 0xc4, 0xbd, 0xe2, 0xf0, 0x4b, 0x8f, 0xe9, 0x7d, 0x99, 0xfa, 0xd3, 0xab, 0xbc, 0xc7, 0x83, 0x2b, 0x04, 0x7f, 0x0c, 0x19, 0x43, 0x03, 0x3d, 0x07, 0xca, 0x40}}},
+{{{0xf9, 0xc8, 0xbe, 0x8c, 0x16, 0x81, 0x39, 0x96, 0xf6, 0x17, 0x58, 0xc8, 0x30, 0x58, 0xfb, 0xc2, 0x03, 0x45, 0xd2, 0x52, 0x76, 0xe0, 0x6a, 0x26, 0x28, 0x5c, 0x88, 0x59, 0x6a, 0x5a, 0x54, 0x42}} ,
+ {{0x07, 0xb5, 0x2e, 0x2c, 0x67, 0x15, 0x9b, 0xfb, 0x83, 0x69, 0x1e, 0x0f, 0xda, 0xd6, 0x29, 0xb1, 0x60, 0xe0, 0xb2, 0xba, 0x69, 0xa2, 0x9e, 0xbd, 0xbd, 0xe0, 0x1c, 0xbd, 0xcd, 0x06, 0x64, 0x70}}},
+{{{0x41, 0xfa, 0x8c, 0xe1, 0x89, 0x8f, 0x27, 0xc8, 0x25, 0x8f, 0x6f, 0x5f, 0x55, 0xf8, 0xde, 0x95, 0x6d, 0x2f, 0x75, 0x16, 0x2b, 0x4e, 0x44, 0xfd, 0x86, 0x6e, 0xe9, 0x70, 0x39, 0x76, 0x97, 0x7e}} ,
+ {{0x17, 0x62, 0x6b, 0x14, 0xa1, 0x7c, 0xd0, 0x79, 0x6e, 0xd8, 0x8a, 0xa5, 0x6d, 0x8c, 0x93, 0xd2, 0x3f, 0xec, 0x44, 0x8d, 0x6e, 0x91, 0x01, 0x8c, 0x8f, 0xee, 0x01, 0x8f, 0xc0, 0xb4, 0x85, 0x0e}}},
+{{{0x02, 0x3a, 0x70, 0x41, 0xe4, 0x11, 0x57, 0x23, 0xac, 0xe6, 0xfc, 0x54, 0x7e, 0xcd, 0xd7, 0x22, 0xcb, 0x76, 0x9f, 0x20, 0xce, 0xa0, 0x73, 0x76, 0x51, 0x3b, 0xa4, 0xf8, 0xe3, 0x62, 0x12, 0x6c}} ,
+ {{0x7f, 0x00, 0x9c, 0x26, 0x0d, 0x6f, 0x48, 0x7f, 0x3a, 0x01, 0xed, 0xc5, 0x96, 0xb0, 0x1f, 0x4f, 0xa8, 0x02, 0x62, 0x27, 0x8a, 0x50, 0x8d, 0x9a, 0x8b, 0x52, 0x0f, 0x1e, 0xcf, 0x41, 0x38, 0x19}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xf5, 0x6c, 0xd4, 0x2f, 0x0f, 0x69, 0x0f, 0x87, 0x3f, 0x61, 0x65, 0x1e, 0x35, 0x34, 0x85, 0xba, 0x02, 0x30, 0xac, 0x25, 0x3d, 0xe2, 0x62, 0xf1, 0xcc, 0xe9, 0x1b, 0xc2, 0xef, 0x6a, 0x42, 0x57}} ,
+ {{0x34, 0x1f, 0x2e, 0xac, 0xd1, 0xc7, 0x04, 0x52, 0x32, 0x66, 0xb2, 0x33, 0x73, 0x21, 0x34, 0x54, 0xf7, 0x71, 0xed, 0x06, 0xb0, 0xff, 0xa6, 0x59, 0x6f, 0x8a, 0x4e, 0xfb, 0x02, 0xb0, 0x45, 0x6b}}},
+{{{0xf5, 0x48, 0x0b, 0x03, 0xc5, 0x22, 0x7d, 0x80, 0x08, 0x53, 0xfe, 0x32, 0xb1, 0xa1, 0x8a, 0x74, 0x6f, 0xbd, 0x3f, 0x85, 0xf4, 0xcf, 0xf5, 0x60, 0xaf, 0x41, 0x7e, 0x3e, 0x46, 0xa3, 0x5a, 0x20}} ,
+ {{0xaa, 0x35, 0x87, 0x44, 0x63, 0x66, 0x97, 0xf8, 0x6e, 0x55, 0x0c, 0x04, 0x3e, 0x35, 0x50, 0xbf, 0x93, 0x69, 0xd2, 0x8b, 0x05, 0x55, 0x99, 0xbe, 0xe2, 0x53, 0x61, 0xec, 0xe8, 0x08, 0x0b, 0x32}}},
+{{{0xb3, 0x10, 0x45, 0x02, 0x69, 0x59, 0x2e, 0x97, 0xd9, 0x64, 0xf8, 0xdb, 0x25, 0x80, 0xdc, 0xc4, 0xd5, 0x62, 0x3c, 0xed, 0x65, 0x91, 0xad, 0xd1, 0x57, 0x81, 0x94, 0xaa, 0xa1, 0x29, 0xfc, 0x68}} ,
+ {{0xdd, 0xb5, 0x7d, 0xab, 0x5a, 0x21, 0x41, 0x53, 0xbb, 0x17, 0x79, 0x0d, 0xd1, 0xa8, 0x0c, 0x0c, 0x20, 0x88, 0x09, 0xe9, 0x84, 0xe8, 0x25, 0x11, 0x67, 0x7a, 0x8b, 0x1a, 0xe4, 0x5d, 0xe1, 0x5d}}},
+{{{0x37, 0xea, 0xfe, 0x65, 0x3b, 0x25, 0xe8, 0xe1, 0xc2, 0xc5, 0x02, 0xa4, 0xbe, 0x98, 0x0a, 0x2b, 0x61, 0xc1, 0x9b, 0xe2, 0xd5, 0x92, 0xe6, 0x9e, 0x7d, 0x1f, 0xca, 0x43, 0x88, 0x8b, 0x2c, 0x59}} ,
+ {{0xe0, 0xb5, 0x00, 0x1d, 0x2a, 0x6f, 0xaf, 0x79, 0x86, 0x2f, 0xa6, 0x5a, 0x93, 0xd1, 0xfe, 0xae, 0x3a, 0xee, 0xdb, 0x7c, 0x61, 0xbe, 0x7c, 0x01, 0xf9, 0xfe, 0x52, 0xdc, 0xd8, 0x52, 0xa3, 0x42}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x22, 0xaf, 0x13, 0x37, 0xbd, 0x37, 0x71, 0xac, 0x04, 0x46, 0x63, 0xac, 0xa4, 0x77, 0xed, 0x25, 0x38, 0xe0, 0x15, 0xa8, 0x64, 0x00, 0x0d, 0xce, 0x51, 0x01, 0xa9, 0xbc, 0x0f, 0x03, 0x1c, 0x04}} ,
+ {{0x89, 0xf9, 0x80, 0x07, 0xcf, 0x3f, 0xb3, 0xe9, 0xe7, 0x45, 0x44, 0x3d, 0x2a, 0x7c, 0xe9, 0xe4, 0x16, 0x5c, 0x5e, 0x65, 0x1c, 0xc7, 0x7d, 0xc6, 0x7a, 0xfb, 0x43, 0xee, 0x25, 0x76, 0x46, 0x72}}},
+{{{0x02, 0xa2, 0xed, 0xf4, 0x8f, 0x6b, 0x0b, 0x3e, 0xeb, 0x35, 0x1a, 0xd5, 0x7e, 0xdb, 0x78, 0x00, 0x96, 0x8a, 0xa0, 0xb4, 0xcf, 0x60, 0x4b, 0xd4, 0xd5, 0xf9, 0x2d, 0xbf, 0x88, 0xbd, 0x22, 0x62}} ,
+ {{0x13, 0x53, 0xe4, 0x82, 0x57, 0xfa, 0x1e, 0x8f, 0x06, 0x2b, 0x90, 0xba, 0x08, 0xb6, 0x10, 0x54, 0x4f, 0x7c, 0x1b, 0x26, 0xed, 0xda, 0x6b, 0xdd, 0x25, 0xd0, 0x4e, 0xea, 0x42, 0xbb, 0x25, 0x03}}},
+{{{0x51, 0x16, 0x50, 0x7c, 0xd5, 0x5d, 0xf6, 0x99, 0xe8, 0x77, 0x72, 0x4e, 0xfa, 0x62, 0xcb, 0x76, 0x75, 0x0c, 0xe2, 0x71, 0x98, 0x92, 0xd5, 0xfa, 0x45, 0xdf, 0x5c, 0x6f, 0x1e, 0x9e, 0x28, 0x69}} ,
+ {{0x0d, 0xac, 0x66, 0x6d, 0xc3, 0x8b, 0xba, 0x16, 0xb5, 0xe2, 0xa0, 0x0d, 0x0c, 0xbd, 0xa4, 0x8e, 0x18, 0x6c, 0xf2, 0xdc, 0xf9, 0xdc, 0x4a, 0x86, 0x25, 0x95, 0x14, 0xcb, 0xd8, 0x1a, 0x04, 0x0f}}},
+{{{0x97, 0xa5, 0xdb, 0x8b, 0x2d, 0xaa, 0x42, 0x11, 0x09, 0xf2, 0x93, 0xbb, 0xd9, 0x06, 0x84, 0x4e, 0x11, 0xa8, 0xa0, 0x25, 0x2b, 0xa6, 0x5f, 0xae, 0xc4, 0xb4, 0x4c, 0xc8, 0xab, 0xc7, 0x3b, 0x02}} ,
+ {{0xee, 0xc9, 0x29, 0x0f, 0xdf, 0x11, 0x85, 0xed, 0xce, 0x0d, 0x62, 0x2c, 0x8f, 0x4b, 0xf9, 0x04, 0xe9, 0x06, 0x72, 0x1d, 0x37, 0x20, 0x50, 0xc9, 0x14, 0xeb, 0xec, 0x39, 0xa7, 0x97, 0x2b, 0x4d}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x69, 0xd1, 0x39, 0xbd, 0xfb, 0x33, 0xbe, 0xc4, 0xf0, 0x5c, 0xef, 0xf0, 0x56, 0x68, 0xfc, 0x97, 0x47, 0xc8, 0x72, 0xb6, 0x53, 0xa4, 0x0a, 0x98, 0xa5, 0xb4, 0x37, 0x71, 0xcf, 0x66, 0x50, 0x6d}} ,
+ {{0x17, 0xa4, 0x19, 0x52, 0x11, 0x47, 0xb3, 0x5c, 0x5b, 0xa9, 0x2e, 0x22, 0xb4, 0x00, 0x52, 0xf9, 0x57, 0x18, 0xb8, 0xbe, 0x5a, 0xe3, 0xab, 0x83, 0xc8, 0x87, 0x0a, 0x2a, 0xd8, 0x8c, 0xbb, 0x54}}},
+{{{0xa9, 0x62, 0x93, 0x85, 0xbe, 0xe8, 0x73, 0x4a, 0x0e, 0xb0, 0xb5, 0x2d, 0x94, 0x50, 0xaa, 0xd3, 0xb2, 0xea, 0x9d, 0x62, 0x76, 0x3b, 0x07, 0x34, 0x4e, 0x2d, 0x70, 0xc8, 0x9a, 0x15, 0x66, 0x6b}} ,
+ {{0xc5, 0x96, 0xca, 0xc8, 0x22, 0x1a, 0xee, 0x5f, 0xe7, 0x31, 0x60, 0x22, 0x83, 0x08, 0x63, 0xce, 0xb9, 0x32, 0x44, 0x58, 0x5d, 0x3a, 0x9b, 0xe4, 0x04, 0xd5, 0xef, 0x38, 0xef, 0x4b, 0xdd, 0x19}}},
+{{{0x4d, 0xc2, 0x17, 0x75, 0xa1, 0x68, 0xcd, 0xc3, 0xc6, 0x03, 0x44, 0xe3, 0x78, 0x09, 0x91, 0x47, 0x3f, 0x0f, 0xe4, 0x92, 0x58, 0xfa, 0x7d, 0x1f, 0x20, 0x94, 0x58, 0x5e, 0xbc, 0x19, 0x02, 0x6f}} ,
+ {{0x20, 0xd6, 0xd8, 0x91, 0x54, 0xa7, 0xf3, 0x20, 0x4b, 0x34, 0x06, 0xfa, 0x30, 0xc8, 0x6f, 0x14, 0x10, 0x65, 0x74, 0x13, 0x4e, 0xf0, 0x69, 0x26, 0xce, 0xcf, 0x90, 0xf4, 0xd0, 0xc5, 0xc8, 0x64}}},
+{{{0x26, 0xa2, 0x50, 0x02, 0x24, 0x72, 0xf1, 0xf0, 0x4e, 0x2d, 0x93, 0xd5, 0x08, 0xe7, 0xae, 0x38, 0xf7, 0x18, 0xa5, 0x32, 0x34, 0xc2, 0xf0, 0xa6, 0xec, 0xb9, 0x61, 0x7b, 0x64, 0x99, 0xac, 0x71}} ,
+ {{0x25, 0xcf, 0x74, 0x55, 0x1b, 0xaa, 0xa9, 0x38, 0x41, 0x40, 0xd5, 0x95, 0x95, 0xab, 0x1c, 0x5e, 0xbc, 0x41, 0x7e, 0x14, 0x30, 0xbe, 0x13, 0x89, 0xf4, 0xe5, 0xeb, 0x28, 0xc0, 0xc2, 0x96, 0x3a}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x2b, 0x77, 0x45, 0xec, 0x67, 0x76, 0x32, 0x4c, 0xb9, 0xdf, 0x25, 0x32, 0x6b, 0xcb, 0xe7, 0x14, 0x61, 0x43, 0xee, 0xba, 0x9b, 0x71, 0xef, 0xd2, 0x48, 0x65, 0xbb, 0x1b, 0x8a, 0x13, 0x1b, 0x22}} ,
+ {{0x84, 0xad, 0x0c, 0x18, 0x38, 0x5a, 0xba, 0xd0, 0x98, 0x59, 0xbf, 0x37, 0xb0, 0x4f, 0x97, 0x60, 0x20, 0xb3, 0x9b, 0x97, 0xf6, 0x08, 0x6c, 0xa4, 0xff, 0xfb, 0xb7, 0xfa, 0x95, 0xb2, 0x51, 0x79}}},
+{{{0x28, 0x5c, 0x3f, 0xdb, 0x6b, 0x18, 0x3b, 0x5c, 0xd1, 0x04, 0x28, 0xde, 0x85, 0x52, 0x31, 0xb5, 0xbb, 0xf6, 0xa9, 0xed, 0xbe, 0x28, 0x4f, 0xb3, 0x7e, 0x05, 0x6a, 0xdb, 0x95, 0x0d, 0x1b, 0x1c}} ,
+ {{0xd5, 0xc5, 0xc3, 0x9a, 0x0a, 0xd0, 0x31, 0x3e, 0x07, 0x36, 0x8e, 0xc0, 0x8a, 0x62, 0xb1, 0xca, 0xd6, 0x0e, 0x1e, 0x9d, 0xef, 0xab, 0x98, 0x4d, 0xbb, 0x6c, 0x05, 0xe0, 0xe4, 0x5d, 0xbd, 0x57}}},
+{{{0xcc, 0x21, 0x27, 0xce, 0xfd, 0xa9, 0x94, 0x8e, 0xe1, 0xab, 0x49, 0xe0, 0x46, 0x26, 0xa1, 0xa8, 0x8c, 0xa1, 0x99, 0x1d, 0xb4, 0x27, 0x6d, 0x2d, 0xc8, 0x39, 0x30, 0x5e, 0x37, 0x52, 0xc4, 0x6e}} ,
+ {{0xa9, 0x85, 0xf4, 0xe7, 0xb0, 0x15, 0x33, 0x84, 0x1b, 0x14, 0x1a, 0x02, 0xd9, 0x3b, 0xad, 0x0f, 0x43, 0x6c, 0xea, 0x3e, 0x0f, 0x7e, 0xda, 0xdd, 0x6b, 0x4c, 0x7f, 0x6e, 0xd4, 0x6b, 0xbf, 0x0f}}},
+{{{0x47, 0x9f, 0x7c, 0x56, 0x7c, 0x43, 0x91, 0x1c, 0xbb, 0x4e, 0x72, 0x3e, 0x64, 0xab, 0xa0, 0xa0, 0xdf, 0xb4, 0xd8, 0x87, 0x3a, 0xbd, 0xa8, 0x48, 0xc9, 0xb8, 0xef, 0x2e, 0xad, 0x6f, 0x84, 0x4f}} ,
+ {{0x2d, 0x2d, 0xf0, 0x1b, 0x7e, 0x2a, 0x6c, 0xf8, 0xa9, 0x6a, 0xe1, 0xf0, 0x99, 0xa1, 0x67, 0x9a, 0xd4, 0x13, 0xca, 0xca, 0xba, 0x27, 0x92, 0xaa, 0xa1, 0x5d, 0x50, 0xde, 0xcc, 0x40, 0x26, 0x0a}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x9f, 0x3e, 0xf2, 0xb2, 0x90, 0xce, 0xdb, 0x64, 0x3e, 0x03, 0xdd, 0x37, 0x36, 0x54, 0x70, 0x76, 0x24, 0xb5, 0x69, 0x03, 0xfc, 0xa0, 0x2b, 0x74, 0xb2, 0x05, 0x0e, 0xcc, 0xd8, 0x1f, 0x6a, 0x1f}} ,
+ {{0x19, 0x5e, 0x60, 0x69, 0x58, 0x86, 0xa0, 0x31, 0xbd, 0x32, 0xe9, 0x2c, 0x5c, 0xd2, 0x85, 0xba, 0x40, 0x64, 0xa8, 0x74, 0xf8, 0x0e, 0x1c, 0xb3, 0xa9, 0x69, 0xe8, 0x1e, 0x40, 0x64, 0x99, 0x77}}},
+{{{0x6c, 0x32, 0x4f, 0xfd, 0xbb, 0x5c, 0xbb, 0x8d, 0x64, 0x66, 0x4a, 0x71, 0x1f, 0x79, 0xa3, 0xad, 0x8d, 0xf9, 0xd4, 0xec, 0xcf, 0x67, 0x70, 0xfa, 0x05, 0x4a, 0x0f, 0x6e, 0xaf, 0x87, 0x0a, 0x6f}} ,
+ {{0xc6, 0x36, 0x6e, 0x6c, 0x8c, 0x24, 0x09, 0x60, 0xbe, 0x26, 0xd2, 0x4c, 0x5e, 0x17, 0xca, 0x5f, 0x1d, 0xcc, 0x87, 0xe8, 0x42, 0x6a, 0xcb, 0xcb, 0x7d, 0x92, 0x05, 0x35, 0x81, 0x13, 0x60, 0x6b}}},
+{{{0xf4, 0x15, 0xcd, 0x0f, 0x0a, 0xaf, 0x4e, 0x6b, 0x51, 0xfd, 0x14, 0xc4, 0x2e, 0x13, 0x86, 0x74, 0x44, 0xcb, 0x66, 0x6b, 0xb6, 0x9d, 0x74, 0x56, 0x32, 0xac, 0x8d, 0x8e, 0x8c, 0x8c, 0x8c, 0x39}} ,
+ {{0xca, 0x59, 0x74, 0x1a, 0x11, 0xef, 0x6d, 0xf7, 0x39, 0x5c, 0x3b, 0x1f, 0xfa, 0xe3, 0x40, 0x41, 0x23, 0x9e, 0xf6, 0xd1, 0x21, 0xa2, 0xbf, 0xad, 0x65, 0x42, 0x6b, 0x59, 0x8a, 0xe8, 0xc5, 0x7f}}},
+{{{0x64, 0x05, 0x7a, 0x84, 0x4a, 0x13, 0xc3, 0xf6, 0xb0, 0x6e, 0x9a, 0x6b, 0x53, 0x6b, 0x32, 0xda, 0xd9, 0x74, 0x75, 0xc4, 0xba, 0x64, 0x3d, 0x3b, 0x08, 0xdd, 0x10, 0x46, 0xef, 0xc7, 0x90, 0x1f}} ,
+ {{0x7b, 0x2f, 0x3a, 0xce, 0xc8, 0xa1, 0x79, 0x3c, 0x30, 0x12, 0x44, 0x28, 0xf6, 0xbc, 0xff, 0xfd, 0xf4, 0xc0, 0x97, 0xb0, 0xcc, 0xc3, 0x13, 0x7a, 0xb9, 0x9a, 0x16, 0xe4, 0xcb, 0x4c, 0x34, 0x63}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x07, 0x4e, 0xd3, 0x2d, 0x09, 0x33, 0x0e, 0xd2, 0x0d, 0xbe, 0x3e, 0xe7, 0xe4, 0xaa, 0xb7, 0x00, 0x8b, 0xe8, 0xad, 0xaa, 0x7a, 0x8d, 0x34, 0x28, 0xa9, 0x81, 0x94, 0xc5, 0xe7, 0x42, 0xac, 0x47}} ,
+ {{0x24, 0x89, 0x7a, 0x8f, 0xb5, 0x9b, 0xf0, 0xc2, 0x03, 0x64, 0xd0, 0x1e, 0xf5, 0xa4, 0xb2, 0xf3, 0x74, 0xe9, 0x1a, 0x16, 0xfd, 0xcb, 0x15, 0xea, 0xeb, 0x10, 0x6c, 0x35, 0xd1, 0xc1, 0xa6, 0x28}}},
+{{{0xcc, 0xd5, 0x39, 0xfc, 0xa5, 0xa4, 0xad, 0x32, 0x15, 0xce, 0x19, 0xe8, 0x34, 0x2b, 0x1c, 0x60, 0x91, 0xfc, 0x05, 0xa9, 0xb3, 0xdc, 0x80, 0x29, 0xc4, 0x20, 0x79, 0x06, 0x39, 0xc0, 0xe2, 0x22}} ,
+ {{0xbb, 0xa8, 0xe1, 0x89, 0x70, 0x57, 0x18, 0x54, 0x3c, 0xf6, 0x0d, 0x82, 0x12, 0x05, 0x87, 0x96, 0x06, 0x39, 0xe3, 0xf8, 0xb3, 0x95, 0xe5, 0xd7, 0x26, 0xbf, 0x09, 0x5a, 0x94, 0xf9, 0x1c, 0x63}}},
+{{{0x2b, 0x8c, 0x2d, 0x9a, 0x8b, 0x84, 0xf2, 0x56, 0xfb, 0xad, 0x2e, 0x7f, 0xb7, 0xfc, 0x30, 0xe1, 0x35, 0x89, 0xba, 0x4d, 0xa8, 0x6d, 0xce, 0x8c, 0x8b, 0x30, 0xe0, 0xda, 0x29, 0x18, 0x11, 0x17}} ,
+ {{0x19, 0xa6, 0x5a, 0x65, 0x93, 0xc3, 0xb5, 0x31, 0x22, 0x4f, 0xf3, 0xf6, 0x0f, 0xeb, 0x28, 0xc3, 0x7c, 0xeb, 0xce, 0x86, 0xec, 0x67, 0x76, 0x6e, 0x35, 0x45, 0x7b, 0xd8, 0x6b, 0x92, 0x01, 0x65}}},
+{{{0x3d, 0xd5, 0x9a, 0x64, 0x73, 0x36, 0xb1, 0xd6, 0x86, 0x98, 0x42, 0x3f, 0x8a, 0xf1, 0xc7, 0xf5, 0x42, 0xa8, 0x9c, 0x52, 0xa8, 0xdc, 0xf9, 0x24, 0x3f, 0x4a, 0xa1, 0xa4, 0x5b, 0xe8, 0x62, 0x1a}} ,
+ {{0xc5, 0xbd, 0xc8, 0x14, 0xd5, 0x0d, 0xeb, 0xe1, 0xa5, 0xe6, 0x83, 0x11, 0x09, 0x00, 0x1d, 0x55, 0x83, 0x51, 0x7e, 0x75, 0x00, 0x81, 0xb9, 0xcb, 0xd8, 0xc5, 0xe5, 0xa1, 0xd9, 0x17, 0x6d, 0x1f}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xea, 0xf9, 0xe4, 0xe9, 0xe1, 0x52, 0x3f, 0x51, 0x19, 0x0d, 0xdd, 0xd9, 0x9d, 0x93, 0x31, 0x87, 0x23, 0x09, 0xd5, 0x83, 0xeb, 0x92, 0x09, 0x76, 0x6e, 0xe3, 0xf8, 0xc0, 0xa2, 0x66, 0xb5, 0x36}} ,
+ {{0x3a, 0xbb, 0x39, 0xed, 0x32, 0x02, 0xe7, 0x43, 0x7a, 0x38, 0x14, 0x84, 0xe3, 0x44, 0xd2, 0x5e, 0x94, 0xdd, 0x78, 0x89, 0x55, 0x4c, 0x73, 0x9e, 0xe1, 0xe4, 0x3e, 0x43, 0xd0, 0x4a, 0xde, 0x1b}}},
+{{{0xb2, 0xe7, 0x8f, 0xe3, 0xa3, 0xc5, 0xcb, 0x72, 0xee, 0x79, 0x41, 0xf8, 0xdf, 0xee, 0x65, 0xc5, 0x45, 0x77, 0x27, 0x3c, 0xbd, 0x58, 0xd3, 0x75, 0xe2, 0x04, 0x4b, 0xbb, 0x65, 0xf3, 0xc8, 0x0f}} ,
+ {{0x24, 0x7b, 0x93, 0x34, 0xb5, 0xe2, 0x74, 0x48, 0xcd, 0xa0, 0x0b, 0x92, 0x97, 0x66, 0x39, 0xf4, 0xb0, 0xe2, 0x5d, 0x39, 0x6a, 0x5b, 0x45, 0x17, 0x78, 0x1e, 0xdb, 0x91, 0x81, 0x1c, 0xf9, 0x16}}},
+{{{0x16, 0xdf, 0xd1, 0x5a, 0xd5, 0xe9, 0x4e, 0x58, 0x95, 0x93, 0x5f, 0x51, 0x09, 0xc3, 0x2a, 0xc9, 0xd4, 0x55, 0x48, 0x79, 0xa4, 0xa3, 0xb2, 0xc3, 0x62, 0xaa, 0x8c, 0xe8, 0xad, 0x47, 0x39, 0x1b}} ,
+ {{0x46, 0xda, 0x9e, 0x51, 0x3a, 0xe6, 0xd1, 0xa6, 0xbb, 0x4d, 0x7b, 0x08, 0xbe, 0x8c, 0xd5, 0xf3, 0x3f, 0xfd, 0xf7, 0x44, 0x80, 0x2d, 0x53, 0x4b, 0xd0, 0x87, 0x68, 0xc1, 0xb5, 0xd8, 0xf7, 0x07}}},
+{{{0xf4, 0x10, 0x46, 0xbe, 0xb7, 0xd2, 0xd1, 0xce, 0x5e, 0x76, 0xa2, 0xd7, 0x03, 0xdc, 0xe4, 0x81, 0x5a, 0xf6, 0x3c, 0xde, 0xae, 0x7a, 0x9d, 0x21, 0x34, 0xa5, 0xf6, 0xa9, 0x73, 0xe2, 0x8d, 0x60}} ,
+ {{0xfa, 0x44, 0x71, 0xf6, 0x41, 0xd8, 0xc6, 0x58, 0x13, 0x37, 0xeb, 0x84, 0x0f, 0x96, 0xc7, 0xdc, 0xc8, 0xa9, 0x7a, 0x83, 0xb2, 0x2f, 0x31, 0xb1, 0x1a, 0xd8, 0x98, 0x3f, 0x11, 0xd0, 0x31, 0x3b}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x81, 0xd5, 0x34, 0x16, 0x01, 0xa3, 0x93, 0xea, 0x52, 0x94, 0xec, 0x93, 0xb7, 0x81, 0x11, 0x2d, 0x58, 0xf9, 0xb5, 0x0a, 0xaa, 0x4f, 0xf6, 0x2e, 0x3f, 0x36, 0xbf, 0x33, 0x5a, 0xe7, 0xd1, 0x08}} ,
+ {{0x1a, 0xcf, 0x42, 0xae, 0xcc, 0xb5, 0x77, 0x39, 0xc4, 0x5b, 0x5b, 0xd0, 0x26, 0x59, 0x27, 0xd0, 0x55, 0x71, 0x12, 0x9d, 0x88, 0x3d, 0x9c, 0xea, 0x41, 0x6a, 0xf0, 0x50, 0x93, 0x93, 0xdd, 0x47}}},
+{{{0x6f, 0xc9, 0x51, 0x6d, 0x1c, 0xaa, 0xf5, 0xa5, 0x90, 0x3f, 0x14, 0xe2, 0x6e, 0x8e, 0x64, 0xfd, 0xac, 0xe0, 0x4e, 0x22, 0xe5, 0xc1, 0xbc, 0x29, 0x0a, 0x6a, 0x9e, 0xa1, 0x60, 0xcb, 0x2f, 0x0b}} ,
+ {{0xdc, 0x39, 0x32, 0xf3, 0xa1, 0x44, 0xe9, 0xc5, 0xc3, 0x78, 0xfb, 0x95, 0x47, 0x34, 0x35, 0x34, 0xe8, 0x25, 0xde, 0x93, 0xc6, 0xb4, 0x76, 0x6d, 0x86, 0x13, 0xc6, 0xe9, 0x68, 0xb5, 0x01, 0x63}}},
+{{{0x1f, 0x9a, 0x52, 0x64, 0x97, 0xd9, 0x1c, 0x08, 0x51, 0x6f, 0x26, 0x9d, 0xaa, 0x93, 0x33, 0x43, 0xfa, 0x77, 0xe9, 0x62, 0x9b, 0x5d, 0x18, 0x75, 0xeb, 0x78, 0xf7, 0x87, 0x8f, 0x41, 0xb4, 0x4d}} ,
+ {{0x13, 0xa8, 0x82, 0x3e, 0xe9, 0x13, 0xad, 0xeb, 0x01, 0xca, 0xcf, 0xda, 0xcd, 0xf7, 0x6c, 0xc7, 0x7a, 0xdc, 0x1e, 0x6e, 0xc8, 0x4e, 0x55, 0x62, 0x80, 0xea, 0x78, 0x0c, 0x86, 0xb9, 0x40, 0x51}}},
+{{{0x27, 0xae, 0xd3, 0x0d, 0x4c, 0x8f, 0x34, 0xea, 0x7d, 0x3c, 0xe5, 0x8a, 0xcf, 0x5b, 0x92, 0xd8, 0x30, 0x16, 0xb4, 0xa3, 0x75, 0xff, 0xeb, 0x27, 0xc8, 0x5c, 0x6c, 0xc2, 0xee, 0x6c, 0x21, 0x0b}} ,
+ {{0xc3, 0xba, 0x12, 0x53, 0x2a, 0xaa, 0x77, 0xad, 0x19, 0x78, 0x55, 0x8a, 0x2e, 0x60, 0x87, 0xc2, 0x6e, 0x91, 0x38, 0x91, 0x3f, 0x7a, 0xc5, 0x24, 0x8f, 0x51, 0xc5, 0xde, 0xb0, 0x53, 0x30, 0x56}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x02, 0xfe, 0x54, 0x12, 0x18, 0xca, 0x7d, 0xa5, 0x68, 0x43, 0xa3, 0x6d, 0x14, 0x2a, 0x6a, 0xa5, 0x8e, 0x32, 0xe7, 0x63, 0x4f, 0xe3, 0xc6, 0x44, 0x3e, 0xab, 0x63, 0xca, 0x17, 0x86, 0x74, 0x3f}} ,
+ {{0x1e, 0x64, 0xc1, 0x7d, 0x52, 0xdc, 0x13, 0x5a, 0xa1, 0x9c, 0x4e, 0xee, 0x99, 0x28, 0xbb, 0x4c, 0xee, 0xac, 0xa9, 0x1b, 0x89, 0xa2, 0x38, 0x39, 0x7b, 0xc4, 0x0f, 0x42, 0xe6, 0x89, 0xed, 0x0f}}},
+{{{0xf3, 0x3c, 0x8c, 0x80, 0x83, 0x10, 0x8a, 0x37, 0x50, 0x9c, 0xb4, 0xdf, 0x3f, 0x8c, 0xf7, 0x23, 0x07, 0xd6, 0xff, 0xa0, 0x82, 0x6c, 0x75, 0x3b, 0xe4, 0xb5, 0xbb, 0xe4, 0xe6, 0x50, 0xf0, 0x08}} ,
+ {{0x62, 0xee, 0x75, 0x48, 0x92, 0x33, 0xf2, 0xf4, 0xad, 0x15, 0x7a, 0xa1, 0x01, 0x46, 0xa9, 0x32, 0x06, 0x88, 0xb6, 0x36, 0x47, 0x35, 0xb9, 0xb4, 0x42, 0x85, 0x76, 0xf0, 0x48, 0x00, 0x90, 0x38}}},
+{{{0x51, 0x15, 0x9d, 0xc3, 0x95, 0xd1, 0x39, 0xbb, 0x64, 0x9d, 0x15, 0x81, 0xc1, 0x68, 0xd0, 0xb6, 0xa4, 0x2c, 0x7d, 0x5e, 0x02, 0x39, 0x00, 0xe0, 0x3b, 0xa4, 0xcc, 0xca, 0x1d, 0x81, 0x24, 0x10}} ,
+ {{0xe7, 0x29, 0xf9, 0x37, 0xd9, 0x46, 0x5a, 0xcd, 0x70, 0xfe, 0x4d, 0x5b, 0xbf, 0xa5, 0xcf, 0x91, 0xf4, 0xef, 0xee, 0x8a, 0x29, 0xd0, 0xe7, 0xc4, 0x25, 0x92, 0x8a, 0xff, 0x36, 0xfc, 0xe4, 0x49}}},
+{{{0xbd, 0x00, 0xb9, 0x04, 0x7d, 0x35, 0xfc, 0xeb, 0xd0, 0x0b, 0x05, 0x32, 0x52, 0x7a, 0x89, 0x24, 0x75, 0x50, 0xe1, 0x63, 0x02, 0x82, 0x8e, 0xe7, 0x85, 0x0c, 0xf2, 0x56, 0x44, 0x37, 0x83, 0x25}} ,
+ {{0x8f, 0xa1, 0xce, 0xcb, 0x60, 0xda, 0x12, 0x02, 0x1e, 0x29, 0x39, 0x2a, 0x03, 0xb7, 0xeb, 0x77, 0x40, 0xea, 0xc9, 0x2b, 0x2c, 0xd5, 0x7d, 0x7e, 0x2c, 0xc7, 0x5a, 0xfd, 0xff, 0xc4, 0xd1, 0x62}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x1d, 0x88, 0x98, 0x5b, 0x4e, 0xfc, 0x41, 0x24, 0x05, 0xe6, 0x50, 0x2b, 0xae, 0x96, 0x51, 0xd9, 0x6b, 0x72, 0xb2, 0x33, 0x42, 0x98, 0x68, 0xbb, 0x10, 0x5a, 0x7a, 0x8c, 0x9d, 0x07, 0xb4, 0x05}} ,
+ {{0x2f, 0x61, 0x9f, 0xd7, 0xa8, 0x3f, 0x83, 0x8c, 0x10, 0x69, 0x90, 0xe6, 0xcf, 0xd2, 0x63, 0xa3, 0xe4, 0x54, 0x7e, 0xe5, 0x69, 0x13, 0x1c, 0x90, 0x57, 0xaa, 0xe9, 0x53, 0x22, 0x43, 0x29, 0x23}}},
+{{{0xe5, 0x1c, 0xf8, 0x0a, 0xfd, 0x2d, 0x7e, 0xf5, 0xf5, 0x70, 0x7d, 0x41, 0x6b, 0x11, 0xfe, 0xbe, 0x99, 0xd1, 0x55, 0x29, 0x31, 0xbf, 0xc0, 0x97, 0x6c, 0xd5, 0x35, 0xcc, 0x5e, 0x8b, 0xd9, 0x69}} ,
+ {{0x8e, 0x4e, 0x9f, 0x25, 0xf8, 0x81, 0x54, 0x2d, 0x0e, 0xd5, 0x54, 0x81, 0x9b, 0xa6, 0x92, 0xce, 0x4b, 0xe9, 0x8f, 0x24, 0x3b, 0xca, 0xe0, 0x44, 0xab, 0x36, 0xfe, 0xfb, 0x87, 0xd4, 0x26, 0x3e}}},
+{{{0x0f, 0x93, 0x9c, 0x11, 0xe7, 0xdb, 0xf1, 0xf0, 0x85, 0x43, 0x28, 0x15, 0x37, 0xdd, 0xde, 0x27, 0xdf, 0xad, 0x3e, 0x49, 0x4f, 0xe0, 0x5b, 0xf6, 0x80, 0x59, 0x15, 0x3c, 0x85, 0xb7, 0x3e, 0x12}} ,
+ {{0xf5, 0xff, 0xcc, 0xf0, 0xb4, 0x12, 0x03, 0x5f, 0xc9, 0x84, 0xcb, 0x1d, 0x17, 0xe0, 0xbc, 0xcc, 0x03, 0x62, 0xa9, 0x8b, 0x94, 0xa6, 0xaa, 0x18, 0xcb, 0x27, 0x8d, 0x49, 0xa6, 0x17, 0x15, 0x07}}},
+{{{0xd9, 0xb6, 0xd4, 0x9d, 0xd4, 0x6a, 0xaf, 0x70, 0x07, 0x2c, 0x10, 0x9e, 0xbd, 0x11, 0xad, 0xe4, 0x26, 0x33, 0x70, 0x92, 0x78, 0x1c, 0x74, 0x9f, 0x75, 0x60, 0x56, 0xf4, 0x39, 0xa8, 0xa8, 0x62}} ,
+ {{0x3b, 0xbf, 0x55, 0x35, 0x61, 0x8b, 0x44, 0x97, 0xe8, 0x3a, 0x55, 0xc1, 0xc8, 0x3b, 0xfd, 0x95, 0x29, 0x11, 0x60, 0x96, 0x1e, 0xcb, 0x11, 0x9d, 0xc2, 0x03, 0x8a, 0x1b, 0xc6, 0xd6, 0x45, 0x3d}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x7e, 0x0e, 0x50, 0xb2, 0xcc, 0x0d, 0x6b, 0xa6, 0x71, 0x5b, 0x42, 0xed, 0xbd, 0xaf, 0xac, 0xf0, 0xfc, 0x12, 0xa2, 0x3f, 0x4e, 0xda, 0xe8, 0x11, 0xf3, 0x23, 0xe1, 0x04, 0x62, 0x03, 0x1c, 0x4e}} ,
+ {{0xc8, 0xb1, 0x1b, 0x6f, 0x73, 0x61, 0x3d, 0x27, 0x0d, 0x7d, 0x7a, 0x25, 0x5f, 0x73, 0x0e, 0x2f, 0x93, 0xf6, 0x24, 0xd8, 0x4f, 0x90, 0xac, 0xa2, 0x62, 0x0a, 0xf0, 0x61, 0xd9, 0x08, 0x59, 0x6a}}},
+{{{0x6f, 0x2d, 0x55, 0xf8, 0x2f, 0x8e, 0xf0, 0x18, 0x3b, 0xea, 0xdd, 0x26, 0x72, 0xd1, 0xf5, 0xfe, 0xe5, 0xb8, 0xe6, 0xd3, 0x10, 0x48, 0x46, 0x49, 0x3a, 0x9f, 0x5e, 0x45, 0x6b, 0x90, 0xe8, 0x7f}} ,
+ {{0xd3, 0x76, 0x69, 0x33, 0x7b, 0xb9, 0x40, 0x70, 0xee, 0xa6, 0x29, 0x6b, 0xdd, 0xd0, 0x5d, 0x8d, 0xc1, 0x3e, 0x4a, 0xea, 0x37, 0xb1, 0x03, 0x02, 0x03, 0x35, 0xf1, 0x28, 0x9d, 0xff, 0x00, 0x13}}},
+{{{0x7a, 0xdb, 0x12, 0xd2, 0x8a, 0x82, 0x03, 0x1b, 0x1e, 0xaf, 0xf9, 0x4b, 0x9c, 0xbe, 0xae, 0x7c, 0xe4, 0x94, 0x2a, 0x23, 0xb3, 0x62, 0x86, 0xe7, 0xfd, 0x23, 0xaa, 0x99, 0xbd, 0x2b, 0x11, 0x6c}} ,
+ {{0x8d, 0xa6, 0xd5, 0xac, 0x9d, 0xcc, 0x68, 0x75, 0x7f, 0xc3, 0x4d, 0x4b, 0xdd, 0x6c, 0xbb, 0x11, 0x5a, 0x60, 0xe5, 0xbd, 0x7d, 0x27, 0x8b, 0xda, 0xb4, 0x95, 0xf6, 0x03, 0x27, 0xa4, 0x92, 0x3f}}},
+{{{0x22, 0xd6, 0xb5, 0x17, 0x84, 0xbf, 0x12, 0xcc, 0x23, 0x14, 0x4a, 0xdf, 0x14, 0x31, 0xbc, 0xa1, 0xac, 0x6e, 0xab, 0xfa, 0x57, 0x11, 0x53, 0xb3, 0x27, 0xe6, 0xf9, 0x47, 0x33, 0x44, 0x34, 0x1e}} ,
+ {{0x79, 0xfc, 0xa6, 0xb4, 0x0b, 0x35, 0x20, 0xc9, 0x4d, 0x22, 0x84, 0xc4, 0xa9, 0x20, 0xec, 0x89, 0x94, 0xba, 0x66, 0x56, 0x48, 0xb9, 0x87, 0x7f, 0xca, 0x1e, 0x06, 0xed, 0xa5, 0x55, 0x59, 0x29}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x56, 0xe1, 0xf5, 0xf1, 0xd5, 0xab, 0xa8, 0x2b, 0xae, 0x89, 0xf3, 0xcf, 0x56, 0x9f, 0xf2, 0x4b, 0x31, 0xbc, 0x18, 0xa9, 0x06, 0x5b, 0xbe, 0xb4, 0x61, 0xf8, 0xb2, 0x06, 0x9c, 0x81, 0xab, 0x4c}} ,
+ {{0x1f, 0x68, 0x76, 0x01, 0x16, 0x38, 0x2b, 0x0f, 0x77, 0x97, 0x92, 0x67, 0x4e, 0x86, 0x6a, 0x8b, 0xe5, 0xe8, 0x0c, 0xf7, 0x36, 0x39, 0xb5, 0x33, 0xe6, 0xcf, 0x5e, 0xbd, 0x18, 0xfb, 0x10, 0x1f}}},
+{{{0x83, 0xf0, 0x0d, 0x63, 0xef, 0x53, 0x6b, 0xb5, 0x6b, 0xf9, 0x83, 0xcf, 0xde, 0x04, 0x22, 0x9b, 0x2c, 0x0a, 0xe0, 0xa5, 0xd8, 0xc7, 0x9c, 0xa5, 0xa3, 0xf6, 0x6f, 0xcf, 0x90, 0x6b, 0x68, 0x7c}} ,
+ {{0x33, 0x15, 0xd7, 0x7f, 0x1a, 0xd5, 0x21, 0x58, 0xc4, 0x18, 0xa5, 0xf0, 0xcc, 0x73, 0xa8, 0xfd, 0xfa, 0x18, 0xd1, 0x03, 0x91, 0x8d, 0x52, 0xd2, 0xa3, 0xa4, 0xd3, 0xb1, 0xea, 0x1d, 0x0f, 0x00}}},
+{{{0xcc, 0x48, 0x83, 0x90, 0xe5, 0xfd, 0x3f, 0x84, 0xaa, 0xf9, 0x8b, 0x82, 0x59, 0x24, 0x34, 0x68, 0x4f, 0x1c, 0x23, 0xd9, 0xcc, 0x71, 0xe1, 0x7f, 0x8c, 0xaf, 0xf1, 0xee, 0x00, 0xb6, 0xa0, 0x77}} ,
+ {{0xf5, 0x1a, 0x61, 0xf7, 0x37, 0x9d, 0x00, 0xf4, 0xf2, 0x69, 0x6f, 0x4b, 0x01, 0x85, 0x19, 0x45, 0x4d, 0x7f, 0x02, 0x7c, 0x6a, 0x05, 0x47, 0x6c, 0x1f, 0x81, 0x20, 0xd4, 0xe8, 0x50, 0x27, 0x72}}},
+{{{0x2c, 0x3a, 0xe5, 0xad, 0xf4, 0xdd, 0x2d, 0xf7, 0x5c, 0x44, 0xb5, 0x5b, 0x21, 0xa3, 0x89, 0x5f, 0x96, 0x45, 0xca, 0x4d, 0xa4, 0x21, 0x99, 0x70, 0xda, 0xc4, 0xc4, 0xa0, 0xe5, 0xf4, 0xec, 0x0a}} ,
+ {{0x07, 0x68, 0x21, 0x65, 0xe9, 0x08, 0xa0, 0x0b, 0x6a, 0x4a, 0xba, 0xb5, 0x80, 0xaf, 0xd0, 0x1b, 0xc5, 0xf5, 0x4b, 0x73, 0x50, 0x60, 0x2d, 0x71, 0x69, 0x61, 0x0e, 0xc0, 0x20, 0x40, 0x30, 0x19}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xd0, 0x75, 0x57, 0x3b, 0xeb, 0x5c, 0x14, 0x56, 0x50, 0xc9, 0x4f, 0xb8, 0xb8, 0x1e, 0xa3, 0xf4, 0xab, 0xf5, 0xa9, 0x20, 0x15, 0x94, 0x82, 0xda, 0x96, 0x1c, 0x9b, 0x59, 0x8c, 0xff, 0xf4, 0x51}} ,
+ {{0xc1, 0x3a, 0x86, 0xd7, 0xb0, 0x06, 0x84, 0x7f, 0x1b, 0xbd, 0xd4, 0x07, 0x78, 0x80, 0x2e, 0xb1, 0xb4, 0xee, 0x52, 0x38, 0xee, 0x9a, 0xf9, 0xf6, 0xf3, 0x41, 0x6e, 0xd4, 0x88, 0x95, 0xac, 0x35}}},
+{{{0x41, 0x97, 0xbf, 0x71, 0x6a, 0x9b, 0x72, 0xec, 0xf3, 0xf8, 0x6b, 0xe6, 0x0e, 0x6c, 0x69, 0xa5, 0x2f, 0x68, 0x52, 0xd8, 0x61, 0x81, 0xc0, 0x63, 0x3f, 0xa6, 0x3c, 0x13, 0x90, 0xe6, 0x8d, 0x56}} ,
+ {{0xe8, 0x39, 0x30, 0x77, 0x23, 0xb1, 0xfd, 0x1b, 0x3d, 0x3e, 0x74, 0x4d, 0x7f, 0xae, 0x5b, 0x3a, 0xb4, 0x65, 0x0e, 0x3a, 0x43, 0xdc, 0xdc, 0x41, 0x47, 0xe6, 0xe8, 0x92, 0x09, 0x22, 0x48, 0x4c}}},
+{{{0x85, 0x57, 0x9f, 0xb5, 0xc8, 0x06, 0xb2, 0x9f, 0x47, 0x3f, 0xf0, 0xfa, 0xe6, 0xa9, 0xb1, 0x9b, 0x6f, 0x96, 0x7d, 0xf9, 0xa4, 0x65, 0x09, 0x75, 0x32, 0xa6, 0x6c, 0x7f, 0x47, 0x4b, 0x2f, 0x4f}} ,
+ {{0x34, 0xe9, 0x59, 0x93, 0x9d, 0x26, 0x80, 0x54, 0xf2, 0xcc, 0x3c, 0xc2, 0x25, 0x85, 0xe3, 0x6a, 0xc1, 0x62, 0x04, 0xa7, 0x08, 0x32, 0x6d, 0xa1, 0x39, 0x84, 0x8a, 0x3b, 0x87, 0x5f, 0x11, 0x13}}},
+{{{0xda, 0x03, 0x34, 0x66, 0xc4, 0x0c, 0x73, 0x6e, 0xbc, 0x24, 0xb5, 0xf9, 0x70, 0x81, 0x52, 0xe9, 0xf4, 0x7c, 0x23, 0xdd, 0x9f, 0xb8, 0x46, 0xef, 0x1d, 0x22, 0x55, 0x7d, 0x71, 0xc4, 0x42, 0x33}} ,
+ {{0xc5, 0x37, 0x69, 0x5b, 0xa8, 0xc6, 0x9d, 0xa4, 0xfc, 0x61, 0x6e, 0x68, 0x46, 0xea, 0xd7, 0x1c, 0x67, 0xd2, 0x7d, 0xfa, 0xf1, 0xcc, 0x54, 0x8d, 0x36, 0x35, 0xc9, 0x00, 0xdf, 0x6c, 0x67, 0x50}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x9a, 0x4d, 0x42, 0x29, 0x5d, 0xa4, 0x6b, 0x6f, 0xa8, 0x8a, 0x4d, 0x91, 0x7b, 0xd2, 0xdf, 0x36, 0xef, 0x01, 0x22, 0xc5, 0xcc, 0x8d, 0xeb, 0x58, 0x3d, 0xb3, 0x50, 0xfc, 0x8b, 0x97, 0x96, 0x33}} ,
+ {{0x93, 0x33, 0x07, 0xc8, 0x4a, 0xca, 0xd0, 0xb1, 0xab, 0xbd, 0xdd, 0xa7, 0x7c, 0xac, 0x3e, 0x45, 0xcb, 0xcc, 0x07, 0x91, 0xbf, 0x35, 0x9d, 0xcb, 0x7d, 0x12, 0x3c, 0x11, 0x59, 0x13, 0xcf, 0x5c}}},
+{{{0x45, 0xb8, 0x41, 0xd7, 0xab, 0x07, 0x15, 0x00, 0x8e, 0xce, 0xdf, 0xb2, 0x43, 0x5c, 0x01, 0xdc, 0xf4, 0x01, 0x51, 0x95, 0x10, 0x5a, 0xf6, 0x24, 0x24, 0xa0, 0x19, 0x3a, 0x09, 0x2a, 0xaa, 0x3f}} ,
+ {{0xdc, 0x8e, 0xeb, 0xc6, 0xbf, 0xdd, 0x11, 0x7b, 0xe7, 0x47, 0xe6, 0xce, 0xe7, 0xb6, 0xc5, 0xe8, 0x8a, 0xdc, 0x4b, 0x57, 0x15, 0x3b, 0x66, 0xca, 0x89, 0xa3, 0xfd, 0xac, 0x0d, 0xe1, 0x1d, 0x7a}}},
+{{{0x89, 0xef, 0xbf, 0x03, 0x75, 0xd0, 0x29, 0x50, 0xcb, 0x7d, 0xd6, 0xbe, 0xad, 0x5f, 0x7b, 0x00, 0x32, 0xaa, 0x98, 0xed, 0x3f, 0x8f, 0x92, 0xcb, 0x81, 0x56, 0x01, 0x63, 0x64, 0xa3, 0x38, 0x39}} ,
+ {{0x8b, 0xa4, 0xd6, 0x50, 0xb4, 0xaa, 0x5d, 0x64, 0x64, 0x76, 0x2e, 0xa1, 0xa6, 0xb3, 0xb8, 0x7c, 0x7a, 0x56, 0xf5, 0x5c, 0x4e, 0x84, 0x5c, 0xfb, 0xdd, 0xca, 0x48, 0x8b, 0x48, 0xb9, 0xba, 0x34}}},
+{{{0xc5, 0xe3, 0xe8, 0xae, 0x17, 0x27, 0xe3, 0x64, 0x60, 0x71, 0x47, 0x29, 0x02, 0x0f, 0x92, 0x5d, 0x10, 0x93, 0xc8, 0x0e, 0xa1, 0xed, 0xba, 0xa9, 0x96, 0x1c, 0xc5, 0x76, 0x30, 0xcd, 0xf9, 0x30}} ,
+ {{0x95, 0xb0, 0xbd, 0x8c, 0xbc, 0xa7, 0x4f, 0x7e, 0xfd, 0x4e, 0x3a, 0xbf, 0x5f, 0x04, 0x79, 0x80, 0x2b, 0x5a, 0x9f, 0x4f, 0x68, 0x21, 0x19, 0x71, 0xc6, 0x20, 0x01, 0x42, 0xaa, 0xdf, 0xae, 0x2c}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x90, 0x6e, 0x7e, 0x4b, 0x71, 0x93, 0xc0, 0x72, 0xed, 0xeb, 0x71, 0x24, 0x97, 0x26, 0x9c, 0xfe, 0xcb, 0x3e, 0x59, 0x19, 0xa8, 0x0f, 0x75, 0x7d, 0xbe, 0x18, 0xe6, 0x96, 0x1e, 0x95, 0x70, 0x60}} ,
+ {{0x89, 0x66, 0x3e, 0x1d, 0x4c, 0x5f, 0xfe, 0xc0, 0x04, 0x43, 0xd6, 0x44, 0x19, 0xb5, 0xad, 0xc7, 0x22, 0xdc, 0x71, 0x28, 0x64, 0xde, 0x41, 0x38, 0x27, 0x8f, 0x2c, 0x6b, 0x08, 0xb8, 0xb8, 0x7b}}},
+{{{0x3d, 0x70, 0x27, 0x9d, 0xd9, 0xaf, 0xb1, 0x27, 0xaf, 0xe3, 0x5d, 0x1e, 0x3a, 0x30, 0x54, 0x61, 0x60, 0xe8, 0xc3, 0x26, 0x3a, 0xbc, 0x7e, 0xf5, 0x81, 0xdd, 0x64, 0x01, 0x04, 0xeb, 0xc0, 0x1e}} ,
+ {{0xda, 0x2c, 0xa4, 0xd1, 0xa1, 0xc3, 0x5c, 0x6e, 0x32, 0x07, 0x1f, 0xb8, 0x0e, 0x19, 0x9e, 0x99, 0x29, 0x33, 0x9a, 0xae, 0x7a, 0xed, 0x68, 0x42, 0x69, 0x7c, 0x07, 0xb3, 0x38, 0x2c, 0xf6, 0x3d}}},
+{{{0x64, 0xaa, 0xb5, 0x88, 0x79, 0x65, 0x38, 0x8c, 0x94, 0xd6, 0x62, 0x37, 0x7d, 0x64, 0xcd, 0x3a, 0xeb, 0xff, 0xe8, 0x81, 0x09, 0xc7, 0x6a, 0x50, 0x09, 0x0d, 0x28, 0x03, 0x0d, 0x9a, 0x93, 0x0a}} ,
+ {{0x42, 0xa3, 0xf1, 0xc5, 0xb4, 0x0f, 0xd8, 0xc8, 0x8d, 0x15, 0x31, 0xbd, 0xf8, 0x07, 0x8b, 0xcd, 0x08, 0x8a, 0xfb, 0x18, 0x07, 0xfe, 0x8e, 0x52, 0x86, 0xef, 0xbe, 0xec, 0x49, 0x52, 0x99, 0x08}}},
+{{{0x0f, 0xa9, 0xd5, 0x01, 0xaa, 0x48, 0x4f, 0x28, 0x66, 0x32, 0x1a, 0xba, 0x7c, 0xea, 0x11, 0x80, 0x17, 0x18, 0x9b, 0x56, 0x88, 0x25, 0x06, 0x69, 0x12, 0x2c, 0xea, 0x56, 0x69, 0x41, 0x24, 0x19}} ,
+ {{0xde, 0x21, 0xf0, 0xda, 0x8a, 0xfb, 0xb1, 0xb8, 0xcd, 0xc8, 0x6a, 0x82, 0x19, 0x73, 0xdb, 0xc7, 0xcf, 0x88, 0xeb, 0x96, 0xee, 0x6f, 0xfb, 0x06, 0xd2, 0xcd, 0x7d, 0x7b, 0x12, 0x28, 0x8e, 0x0c}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x93, 0x44, 0x97, 0xce, 0x28, 0xff, 0x3a, 0x40, 0xc4, 0xf5, 0xf6, 0x9b, 0xf4, 0x6b, 0x07, 0x84, 0xfb, 0x98, 0xd8, 0xec, 0x8c, 0x03, 0x57, 0xec, 0x49, 0xed, 0x63, 0xb6, 0xaa, 0xff, 0x98, 0x28}} ,
+ {{0x3d, 0x16, 0x35, 0xf3, 0x46, 0xbc, 0xb3, 0xf4, 0xc6, 0xb6, 0x4f, 0xfa, 0xf4, 0xa0, 0x13, 0xe6, 0x57, 0x45, 0x93, 0xb9, 0xbc, 0xd6, 0x59, 0xe7, 0x77, 0x94, 0x6c, 0xab, 0x96, 0x3b, 0x4f, 0x09}}},
+{{{0x5a, 0xf7, 0x6b, 0x01, 0x12, 0x4f, 0x51, 0xc1, 0x70, 0x84, 0x94, 0x47, 0xb2, 0x01, 0x6c, 0x71, 0xd7, 0xcc, 0x17, 0x66, 0x0f, 0x59, 0x5d, 0x5d, 0x10, 0x01, 0x57, 0x11, 0xf5, 0xdd, 0xe2, 0x34}} ,
+ {{0x26, 0xd9, 0x1f, 0x5c, 0x58, 0xac, 0x8b, 0x03, 0xd2, 0xc3, 0x85, 0x0f, 0x3a, 0xc3, 0x7f, 0x6d, 0x8e, 0x86, 0xcd, 0x52, 0x74, 0x8f, 0x55, 0x77, 0x17, 0xb7, 0x8e, 0xb7, 0x88, 0xea, 0xda, 0x1b}}},
+{{{0xb6, 0xea, 0x0e, 0x40, 0x93, 0x20, 0x79, 0x35, 0x6a, 0x61, 0x84, 0x5a, 0x07, 0x6d, 0xf9, 0x77, 0x6f, 0xed, 0x69, 0x1c, 0x0d, 0x25, 0x76, 0xcc, 0xf0, 0xdb, 0xbb, 0xc5, 0xad, 0xe2, 0x26, 0x57}} ,
+ {{0xcf, 0xe8, 0x0e, 0x6b, 0x96, 0x7d, 0xed, 0x27, 0xd1, 0x3c, 0xa9, 0xd9, 0x50, 0xa9, 0x98, 0x84, 0x5e, 0x86, 0xef, 0xd6, 0xf0, 0xf8, 0x0e, 0x89, 0x05, 0x2f, 0xd9, 0x5f, 0x15, 0x5f, 0x73, 0x79}}},
+{{{0xc8, 0x5c, 0x16, 0xfe, 0xed, 0x9f, 0x26, 0x56, 0xf6, 0x4b, 0x9f, 0xa7, 0x0a, 0x85, 0xfe, 0xa5, 0x8c, 0x87, 0xdd, 0x98, 0xce, 0x4e, 0xc3, 0x58, 0x55, 0xb2, 0x7b, 0x3d, 0xd8, 0x6b, 0xb5, 0x4c}} ,
+ {{0x65, 0x38, 0xa0, 0x15, 0xfa, 0xa7, 0xb4, 0x8f, 0xeb, 0xc4, 0x86, 0x9b, 0x30, 0xa5, 0x5e, 0x4d, 0xea, 0x8a, 0x9a, 0x9f, 0x1a, 0xd8, 0x5b, 0x53, 0x14, 0x19, 0x25, 0x63, 0xb4, 0x6f, 0x1f, 0x5d}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xac, 0x8f, 0xbc, 0x1e, 0x7d, 0x8b, 0x5a, 0x0b, 0x8d, 0xaf, 0x76, 0x2e, 0x71, 0xe3, 0x3b, 0x6f, 0x53, 0x2f, 0x3e, 0x90, 0x95, 0xd4, 0x35, 0x14, 0x4f, 0x8c, 0x3c, 0xce, 0x57, 0x1c, 0x76, 0x49}} ,
+ {{0xa8, 0x50, 0xe1, 0x61, 0x6b, 0x57, 0x35, 0xeb, 0x44, 0x0b, 0x0c, 0x6e, 0xf9, 0x25, 0x80, 0x74, 0xf2, 0x8f, 0x6f, 0x7a, 0x3e, 0x7f, 0x2d, 0xf3, 0x4e, 0x09, 0x65, 0x10, 0x5e, 0x03, 0x25, 0x32}}},
+{{{0xa9, 0x60, 0xdc, 0x0f, 0x64, 0xe5, 0x1d, 0xe2, 0x8d, 0x4f, 0x79, 0x2f, 0x0e, 0x24, 0x02, 0x00, 0x05, 0x77, 0x43, 0x25, 0x3d, 0x6a, 0xc7, 0xb7, 0xbf, 0x04, 0x08, 0x65, 0xf4, 0x39, 0x4b, 0x65}} ,
+ {{0x96, 0x19, 0x12, 0x6b, 0x6a, 0xb7, 0xe3, 0xdc, 0x45, 0x9b, 0xdb, 0xb4, 0xa8, 0xae, 0xdc, 0xa8, 0x14, 0x44, 0x65, 0x62, 0xce, 0x34, 0x9a, 0x84, 0x18, 0x12, 0x01, 0xf1, 0xe2, 0x7b, 0xce, 0x50}}},
+{{{0x41, 0x21, 0x30, 0x53, 0x1b, 0x47, 0x01, 0xb7, 0x18, 0xd8, 0x82, 0x57, 0xbd, 0xa3, 0x60, 0xf0, 0x32, 0xf6, 0x5b, 0xf0, 0x30, 0x88, 0x91, 0x59, 0xfd, 0x90, 0xa2, 0xb9, 0x55, 0x93, 0x21, 0x34}} ,
+ {{0x97, 0x67, 0x9e, 0xeb, 0x6a, 0xf9, 0x6e, 0xd6, 0x73, 0xe8, 0x6b, 0x29, 0xec, 0x63, 0x82, 0x00, 0xa8, 0x99, 0x1c, 0x1d, 0x30, 0xc8, 0x90, 0x52, 0x90, 0xb6, 0x6a, 0x80, 0x4e, 0xff, 0x4b, 0x51}}},
+{{{0x0f, 0x7d, 0x63, 0x8c, 0x6e, 0x5c, 0xde, 0x30, 0xdf, 0x65, 0xfa, 0x2e, 0xb0, 0xa3, 0x25, 0x05, 0x54, 0xbd, 0x25, 0xba, 0x06, 0xae, 0xdf, 0x8b, 0xd9, 0x1b, 0xea, 0x38, 0xb3, 0x05, 0x16, 0x09}} ,
+ {{0xc7, 0x8c, 0xbf, 0x64, 0x28, 0xad, 0xf8, 0xa5, 0x5a, 0x6f, 0xc9, 0xba, 0xd5, 0x7f, 0xd5, 0xd6, 0xbd, 0x66, 0x2f, 0x3d, 0xaa, 0x54, 0xf6, 0xba, 0x32, 0x22, 0x9a, 0x1e, 0x52, 0x05, 0xf4, 0x1d}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xaa, 0x1f, 0xbb, 0xeb, 0xfe, 0xe4, 0x87, 0xfc, 0xb1, 0x2c, 0xb7, 0x88, 0xf4, 0xc6, 0xb9, 0xf5, 0x24, 0x46, 0xf2, 0xa5, 0x9f, 0x8f, 0x8a, 0x93, 0x70, 0x69, 0xd4, 0x56, 0xec, 0xfd, 0x06, 0x46}} ,
+ {{0x4e, 0x66, 0xcf, 0x4e, 0x34, 0xce, 0x0c, 0xd9, 0xa6, 0x50, 0xd6, 0x5e, 0x95, 0xaf, 0xe9, 0x58, 0xfa, 0xee, 0x9b, 0xb8, 0xa5, 0x0f, 0x35, 0xe0, 0x43, 0x82, 0x6d, 0x65, 0xe6, 0xd9, 0x00, 0x0f}}},
+{{{0x7b, 0x75, 0x3a, 0xfc, 0x64, 0xd3, 0x29, 0x7e, 0xdd, 0x49, 0x9a, 0x59, 0x53, 0xbf, 0xb4, 0xa7, 0x52, 0xb3, 0x05, 0xab, 0xc3, 0xaf, 0x16, 0x1a, 0x85, 0x42, 0x32, 0xa2, 0x86, 0xfa, 0x39, 0x43}} ,
+ {{0x0e, 0x4b, 0xa3, 0x63, 0x8a, 0xfe, 0xa5, 0x58, 0xf1, 0x13, 0xbd, 0x9d, 0xaa, 0x7f, 0x76, 0x40, 0x70, 0x81, 0x10, 0x75, 0x99, 0xbb, 0xbe, 0x0b, 0x16, 0xe9, 0xba, 0x62, 0x34, 0xcc, 0x07, 0x6d}}},
+{{{0xc3, 0xf1, 0xc6, 0x93, 0x65, 0xee, 0x0b, 0xbc, 0xea, 0x14, 0xf0, 0xc1, 0xf8, 0x84, 0x89, 0xc2, 0xc9, 0xd7, 0xea, 0x34, 0xca, 0xa7, 0xc4, 0x99, 0xd5, 0x50, 0x69, 0xcb, 0xd6, 0x21, 0x63, 0x7c}} ,
+ {{0x99, 0xeb, 0x7c, 0x31, 0x73, 0x64, 0x67, 0x7f, 0x0c, 0x66, 0xaa, 0x8c, 0x69, 0x91, 0xe2, 0x26, 0xd3, 0x23, 0xe2, 0x76, 0x5d, 0x32, 0x52, 0xdf, 0x5d, 0xc5, 0x8f, 0xb7, 0x7c, 0x84, 0xb3, 0x70}}},
+{{{0xeb, 0x01, 0xc7, 0x36, 0x97, 0x4e, 0xb6, 0xab, 0x5f, 0x0d, 0x2c, 0xba, 0x67, 0x64, 0x55, 0xde, 0xbc, 0xff, 0xa6, 0xec, 0x04, 0xd3, 0x8d, 0x39, 0x56, 0x5e, 0xee, 0xf8, 0xe4, 0x2e, 0x33, 0x62}} ,
+ {{0x65, 0xef, 0xb8, 0x9f, 0xc8, 0x4b, 0xa7, 0xfd, 0x21, 0x49, 0x9b, 0x92, 0x35, 0x82, 0xd6, 0x0a, 0x9b, 0xf2, 0x79, 0xf1, 0x47, 0x2f, 0x6a, 0x7e, 0x9f, 0xcf, 0x18, 0x02, 0x3c, 0xfb, 0x1b, 0x3e}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x2f, 0x8b, 0xc8, 0x40, 0x51, 0xd1, 0xac, 0x1a, 0x0b, 0xe4, 0xa9, 0xa2, 0x42, 0x21, 0x19, 0x2f, 0x7b, 0x97, 0xbf, 0xf7, 0x57, 0x6d, 0x3f, 0x3d, 0x4f, 0x0f, 0xe2, 0xb2, 0x81, 0x00, 0x9e, 0x7b}} ,
+ {{0x8c, 0x85, 0x2b, 0xc4, 0xfc, 0xf1, 0xab, 0xe8, 0x79, 0x22, 0xc4, 0x84, 0x17, 0x3a, 0xfa, 0x86, 0xa6, 0x7d, 0xf9, 0xf3, 0x6f, 0x03, 0x57, 0x20, 0x4d, 0x79, 0xf9, 0x6e, 0x71, 0x54, 0x38, 0x09}}},
+{{{0x40, 0x29, 0x74, 0xa8, 0x2f, 0x5e, 0xf9, 0x79, 0xa4, 0xf3, 0x3e, 0xb9, 0xfd, 0x33, 0x31, 0xac, 0x9a, 0x69, 0x88, 0x1e, 0x77, 0x21, 0x2d, 0xf3, 0x91, 0x52, 0x26, 0x15, 0xb2, 0xa6, 0xcf, 0x7e}} ,
+ {{0xc6, 0x20, 0x47, 0x6c, 0xa4, 0x7d, 0xcb, 0x63, 0xea, 0x5b, 0x03, 0xdf, 0x3e, 0x88, 0x81, 0x6d, 0xce, 0x07, 0x42, 0x18, 0x60, 0x7e, 0x7b, 0x55, 0xfe, 0x6a, 0xf3, 0xda, 0x5c, 0x8b, 0x95, 0x10}}},
+{{{0x62, 0xe4, 0x0d, 0x03, 0xb4, 0xd7, 0xcd, 0xfa, 0xbd, 0x46, 0xdf, 0x93, 0x71, 0x10, 0x2c, 0xa8, 0x3b, 0xb6, 0x09, 0x05, 0x70, 0x84, 0x43, 0x29, 0xa8, 0x59, 0xf5, 0x8e, 0x10, 0xe4, 0xd7, 0x20}} ,
+ {{0x57, 0x82, 0x1c, 0xab, 0xbf, 0x62, 0x70, 0xe8, 0xc4, 0xcf, 0xf0, 0x28, 0x6e, 0x16, 0x3c, 0x08, 0x78, 0x89, 0x85, 0x46, 0x0f, 0xf6, 0x7f, 0xcf, 0xcb, 0x7e, 0xb8, 0x25, 0xe9, 0x5a, 0xfa, 0x03}}},
+{{{0xfb, 0x95, 0x92, 0x63, 0x50, 0xfc, 0x62, 0xf0, 0xa4, 0x5e, 0x8c, 0x18, 0xc2, 0x17, 0x24, 0xb7, 0x78, 0xc2, 0xa9, 0xe7, 0x6a, 0x32, 0xd6, 0x29, 0x85, 0xaf, 0xcb, 0x8d, 0x91, 0x13, 0xda, 0x6b}} ,
+ {{0x36, 0x0a, 0xc2, 0xb6, 0x4b, 0xa5, 0x5d, 0x07, 0x17, 0x41, 0x31, 0x5f, 0x62, 0x46, 0xf8, 0x92, 0xf9, 0x66, 0x48, 0x73, 0xa6, 0x97, 0x0d, 0x7d, 0x88, 0xee, 0x62, 0xb1, 0x03, 0xa8, 0x3f, 0x2c}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x4a, 0xb1, 0x70, 0x8a, 0xa9, 0xe8, 0x63, 0x79, 0x00, 0xe2, 0x25, 0x16, 0xca, 0x4b, 0x0f, 0xa4, 0x66, 0xad, 0x19, 0x9f, 0x88, 0x67, 0x0c, 0x8b, 0xc2, 0x4a, 0x5b, 0x2b, 0x6d, 0x95, 0xaf, 0x19}} ,
+ {{0x8b, 0x9d, 0xb6, 0xcc, 0x60, 0xb4, 0x72, 0x4f, 0x17, 0x69, 0x5a, 0x4a, 0x68, 0x34, 0xab, 0xa1, 0x45, 0x32, 0x3c, 0x83, 0x87, 0x72, 0x30, 0x54, 0x77, 0x68, 0xae, 0xfb, 0xb5, 0x8b, 0x22, 0x5e}}},
+{{{0xf1, 0xb9, 0x87, 0x35, 0xc5, 0xbb, 0xb9, 0xcf, 0xf5, 0xd6, 0xcd, 0xd5, 0x0c, 0x7c, 0x0e, 0xe6, 0x90, 0x34, 0xfb, 0x51, 0x42, 0x1e, 0x6d, 0xac, 0x9a, 0x46, 0xc4, 0x97, 0x29, 0x32, 0xbf, 0x45}} ,
+ {{0x66, 0x9e, 0xc6, 0x24, 0xc0, 0xed, 0xa5, 0x5d, 0x88, 0xd4, 0xf0, 0x73, 0x97, 0x7b, 0xea, 0x7f, 0x42, 0xff, 0x21, 0xa0, 0x9b, 0x2f, 0x9a, 0xfd, 0x53, 0x57, 0x07, 0x84, 0x48, 0x88, 0x9d, 0x52}}},
+{{{0xc6, 0x96, 0x48, 0x34, 0x2a, 0x06, 0xaf, 0x94, 0x3d, 0xf4, 0x1a, 0xcf, 0xf2, 0xc0, 0x21, 0xc2, 0x42, 0x5e, 0xc8, 0x2f, 0x35, 0xa2, 0x3e, 0x29, 0xfa, 0x0c, 0x84, 0xe5, 0x89, 0x72, 0x7c, 0x06}} ,
+ {{0x32, 0x65, 0x03, 0xe5, 0x89, 0xa6, 0x6e, 0xb3, 0x5b, 0x8e, 0xca, 0xeb, 0xfe, 0x22, 0x56, 0x8b, 0x5d, 0x14, 0x4b, 0x4d, 0xf9, 0xbe, 0xb5, 0xf5, 0xe6, 0x5c, 0x7b, 0x8b, 0xf4, 0x13, 0x11, 0x34}}},
+{{{0x07, 0xc6, 0x22, 0x15, 0xe2, 0x9c, 0x60, 0xa2, 0x19, 0xd9, 0x27, 0xae, 0x37, 0x4e, 0xa6, 0xc9, 0x80, 0xa6, 0x91, 0x8f, 0x12, 0x49, 0xe5, 0x00, 0x18, 0x47, 0xd1, 0xd7, 0x28, 0x22, 0x63, 0x39}} ,
+ {{0xe8, 0xe2, 0x00, 0x7e, 0xf2, 0x9e, 0x1e, 0x99, 0x39, 0x95, 0x04, 0xbd, 0x1e, 0x67, 0x7b, 0xb2, 0x26, 0xac, 0xe6, 0xaa, 0xe2, 0x46, 0xd5, 0xe4, 0xe8, 0x86, 0xbd, 0xab, 0x7c, 0x55, 0x59, 0x6f}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x24, 0x64, 0x6e, 0x9b, 0x35, 0x71, 0x78, 0xce, 0x33, 0x03, 0x21, 0x33, 0x36, 0xf1, 0x73, 0x9b, 0xb9, 0x15, 0x8b, 0x2c, 0x69, 0xcf, 0x4d, 0xed, 0x4f, 0x4d, 0x57, 0x14, 0x13, 0x82, 0xa4, 0x4d}} ,
+ {{0x65, 0x6e, 0x0a, 0xa4, 0x59, 0x07, 0x17, 0xf2, 0x6b, 0x4a, 0x1f, 0x6e, 0xf6, 0xb5, 0xbc, 0x62, 0xe4, 0xb6, 0xda, 0xa2, 0x93, 0xbc, 0x29, 0x05, 0xd2, 0xd2, 0x73, 0x46, 0x03, 0x16, 0x40, 0x31}}},
+{{{0x4c, 0x73, 0x6d, 0x15, 0xbd, 0xa1, 0x4d, 0x5c, 0x13, 0x0b, 0x24, 0x06, 0x98, 0x78, 0x1c, 0x5b, 0xeb, 0x1f, 0x18, 0x54, 0x43, 0xd9, 0x55, 0x66, 0xda, 0x29, 0x21, 0xe8, 0xb8, 0x3c, 0x42, 0x22}} ,
+ {{0xb4, 0xcd, 0x08, 0x6f, 0x15, 0x23, 0x1a, 0x0b, 0x22, 0xed, 0xd1, 0xf1, 0xa7, 0xc7, 0x73, 0x45, 0xf3, 0x9e, 0xce, 0x76, 0xb7, 0xf6, 0x39, 0xb6, 0x8e, 0x79, 0xbe, 0xe9, 0x9b, 0xcf, 0x7d, 0x62}}},
+{{{0x92, 0x5b, 0xfc, 0x72, 0xfd, 0xba, 0xf1, 0xfd, 0xa6, 0x7c, 0x95, 0xe3, 0x61, 0x3f, 0xe9, 0x03, 0xd4, 0x2b, 0xd4, 0x20, 0xd9, 0xdb, 0x4d, 0x32, 0x3e, 0xf5, 0x11, 0x64, 0xe3, 0xb4, 0xbe, 0x32}} ,
+ {{0x86, 0x17, 0x90, 0xe7, 0xc9, 0x1f, 0x10, 0xa5, 0x6a, 0x2d, 0x39, 0xd0, 0x3b, 0xc4, 0xa6, 0xe9, 0x59, 0x13, 0xda, 0x1a, 0xe6, 0xa0, 0xb9, 0x3c, 0x50, 0xb8, 0x40, 0x7c, 0x15, 0x36, 0x5a, 0x42}}},
+{{{0xb4, 0x0b, 0x32, 0xab, 0xdc, 0x04, 0x51, 0x55, 0x21, 0x1e, 0x0b, 0x75, 0x99, 0x89, 0x73, 0x35, 0x3a, 0x91, 0x2b, 0xfe, 0xe7, 0x49, 0xea, 0x76, 0xc1, 0xf9, 0x46, 0xb9, 0x53, 0x02, 0x23, 0x04}} ,
+ {{0xfc, 0x5a, 0x1e, 0x1d, 0x74, 0x58, 0x95, 0xa6, 0x8f, 0x7b, 0x97, 0x3e, 0x17, 0x3b, 0x79, 0x2d, 0xa6, 0x57, 0xef, 0x45, 0x02, 0x0b, 0x4d, 0x6e, 0x9e, 0x93, 0x8d, 0x2f, 0xd9, 0x9d, 0xdb, 0x04}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xc0, 0xd7, 0x56, 0x97, 0x58, 0x91, 0xde, 0x09, 0x4f, 0x9f, 0xbe, 0x63, 0xb0, 0x83, 0x86, 0x43, 0x5d, 0xbc, 0xe0, 0xf3, 0xc0, 0x75, 0xbf, 0x8b, 0x8e, 0xaa, 0xf7, 0x8b, 0x64, 0x6e, 0xb0, 0x63}} ,
+ {{0x16, 0xae, 0x8b, 0xe0, 0x9b, 0x24, 0x68, 0x5c, 0x44, 0xc2, 0xd0, 0x08, 0xb7, 0x7b, 0x62, 0xfd, 0x7f, 0xd8, 0xd4, 0xb7, 0x50, 0xfd, 0x2c, 0x1b, 0xbf, 0x41, 0x95, 0xd9, 0x8e, 0xd8, 0x17, 0x1b}}},
+{{{0x86, 0x55, 0x37, 0x8e, 0xc3, 0x38, 0x48, 0x14, 0xb5, 0x97, 0xd2, 0xa7, 0x54, 0x45, 0xf1, 0x35, 0x44, 0x38, 0x9e, 0xf1, 0x1b, 0xb6, 0x34, 0x00, 0x3c, 0x96, 0xee, 0x29, 0x00, 0xea, 0x2c, 0x0b}} ,
+ {{0xea, 0xda, 0x99, 0x9e, 0x19, 0x83, 0x66, 0x6d, 0xe9, 0x76, 0x87, 0x50, 0xd1, 0xfd, 0x3c, 0x60, 0x87, 0xc6, 0x41, 0xd9, 0x8e, 0xdb, 0x5e, 0xde, 0xaa, 0x9a, 0xd3, 0x28, 0xda, 0x95, 0xea, 0x47}}},
+{{{0xd0, 0x80, 0xba, 0x19, 0xae, 0x1d, 0xa9, 0x79, 0xf6, 0x3f, 0xac, 0x5d, 0x6f, 0x96, 0x1f, 0x2a, 0xce, 0x29, 0xb2, 0xff, 0x37, 0xf1, 0x94, 0x8f, 0x0c, 0xb5, 0x28, 0xba, 0x9a, 0x21, 0xf6, 0x66}} ,
+ {{0x02, 0xfb, 0x54, 0xb8, 0x05, 0xf3, 0x81, 0x52, 0x69, 0x34, 0x46, 0x9d, 0x86, 0x76, 0x8f, 0xd7, 0xf8, 0x6a, 0x66, 0xff, 0xe6, 0xa7, 0x90, 0xf7, 0x5e, 0xcd, 0x6a, 0x9b, 0x55, 0xfc, 0x9d, 0x48}}},
+{{{0xbd, 0xaa, 0x13, 0xe6, 0xcd, 0x45, 0x4a, 0xa4, 0x59, 0x0a, 0x64, 0xb1, 0x98, 0xd6, 0x34, 0x13, 0x04, 0xe6, 0x97, 0x94, 0x06, 0xcb, 0xd4, 0x4e, 0xbb, 0x96, 0xcd, 0xd1, 0x57, 0xd1, 0xe3, 0x06}} ,
+ {{0x7a, 0x6c, 0x45, 0x27, 0xc4, 0x93, 0x7f, 0x7d, 0x7c, 0x62, 0x50, 0x38, 0x3a, 0x6b, 0xb5, 0x88, 0xc6, 0xd9, 0xf1, 0x78, 0x19, 0xb9, 0x39, 0x93, 0x3d, 0xc9, 0xe0, 0x9c, 0x3c, 0xce, 0xf5, 0x72}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x24, 0xea, 0x23, 0x7d, 0x56, 0x2c, 0xe2, 0x59, 0x0e, 0x85, 0x60, 0x04, 0x88, 0x5a, 0x74, 0x1e, 0x4b, 0xef, 0x13, 0xda, 0x4c, 0xff, 0x83, 0x45, 0x85, 0x3f, 0x08, 0x95, 0x2c, 0x20, 0x13, 0x1f}} ,
+ {{0x48, 0x5f, 0x27, 0x90, 0x5c, 0x02, 0x42, 0xad, 0x78, 0x47, 0x5c, 0xb5, 0x7e, 0x08, 0x85, 0x00, 0xfa, 0x7f, 0xfd, 0xfd, 0xe7, 0x09, 0x11, 0xf2, 0x7e, 0x1b, 0x38, 0x6c, 0x35, 0x6d, 0x33, 0x66}}},
+{{{0x93, 0x03, 0x36, 0x81, 0xac, 0xe4, 0x20, 0x09, 0x35, 0x4c, 0x45, 0xb2, 0x1e, 0x4c, 0x14, 0x21, 0xe6, 0xe9, 0x8a, 0x7b, 0x8d, 0xfe, 0x1e, 0xc6, 0x3e, 0xc1, 0x35, 0xfa, 0xe7, 0x70, 0x4e, 0x1d}} ,
+ {{0x61, 0x2e, 0xc2, 0xdd, 0x95, 0x57, 0xd1, 0xab, 0x80, 0xe8, 0x63, 0x17, 0xb5, 0x48, 0xe4, 0x8a, 0x11, 0x9e, 0x72, 0xbe, 0x85, 0x8d, 0x51, 0x0a, 0xf2, 0x9f, 0xe0, 0x1c, 0xa9, 0x07, 0x28, 0x7b}}},
+{{{0xbb, 0x71, 0x14, 0x5e, 0x26, 0x8c, 0x3d, 0xc8, 0xe9, 0x7c, 0xd3, 0xd6, 0xd1, 0x2f, 0x07, 0x6d, 0xe6, 0xdf, 0xfb, 0x79, 0xd6, 0x99, 0x59, 0x96, 0x48, 0x40, 0x0f, 0x3a, 0x7b, 0xb2, 0xa0, 0x72}} ,
+ {{0x4e, 0x3b, 0x69, 0xc8, 0x43, 0x75, 0x51, 0x6c, 0x79, 0x56, 0xe4, 0xcb, 0xf7, 0xa6, 0x51, 0xc2, 0x2c, 0x42, 0x0b, 0xd4, 0x82, 0x20, 0x1c, 0x01, 0x08, 0x66, 0xd7, 0xbf, 0x04, 0x56, 0xfc, 0x02}}},
+{{{0x24, 0xe8, 0xb7, 0x60, 0xae, 0x47, 0x80, 0xfc, 0xe5, 0x23, 0xe7, 0xc2, 0xc9, 0x85, 0xe6, 0x98, 0xa0, 0x29, 0x4e, 0xe1, 0x84, 0x39, 0x2d, 0x95, 0x2c, 0xf3, 0x45, 0x3c, 0xff, 0xaf, 0x27, 0x4c}} ,
+ {{0x6b, 0xa6, 0xf5, 0x4b, 0x11, 0xbd, 0xba, 0x5b, 0x9e, 0xc4, 0xa4, 0x51, 0x1e, 0xbe, 0xd0, 0x90, 0x3a, 0x9c, 0xc2, 0x26, 0xb6, 0x1e, 0xf1, 0x95, 0x7d, 0xc8, 0x6d, 0x52, 0xe6, 0x99, 0x2c, 0x5f}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x85, 0xe0, 0x24, 0x32, 0xb4, 0xd1, 0xef, 0xfc, 0x69, 0xa2, 0xbf, 0x8f, 0x72, 0x2c, 0x95, 0xf6, 0xe4, 0x6e, 0x7d, 0x90, 0xf7, 0x57, 0x81, 0xa0, 0xf7, 0xda, 0xef, 0x33, 0x07, 0xe3, 0x6b, 0x78}} ,
+ {{0x36, 0x27, 0x3e, 0xc6, 0x12, 0x07, 0xab, 0x4e, 0xbe, 0x69, 0x9d, 0xb3, 0xbe, 0x08, 0x7c, 0x2a, 0x47, 0x08, 0xfd, 0xd4, 0xcd, 0x0e, 0x27, 0x34, 0x5b, 0x98, 0x34, 0x2f, 0x77, 0x5f, 0x3a, 0x65}}},
+{{{0x13, 0xaa, 0x2e, 0x4c, 0xf0, 0x22, 0xb8, 0x6c, 0xb3, 0x19, 0x4d, 0xeb, 0x6b, 0xd0, 0xa4, 0xc6, 0x9c, 0xdd, 0xc8, 0x5b, 0x81, 0x57, 0x89, 0xdf, 0x33, 0xa9, 0x68, 0x49, 0x80, 0xe4, 0xfe, 0x21}} ,
+ {{0x00, 0x17, 0x90, 0x30, 0xe9, 0xd3, 0x60, 0x30, 0x31, 0xc2, 0x72, 0x89, 0x7a, 0x36, 0xa5, 0xbd, 0x39, 0x83, 0x85, 0x50, 0xa1, 0x5d, 0x6c, 0x41, 0x1d, 0xb5, 0x2c, 0x07, 0x40, 0x77, 0x0b, 0x50}}},
+{{{0x64, 0x34, 0xec, 0xc0, 0x9e, 0x44, 0x41, 0xaf, 0xa0, 0x36, 0x05, 0x6d, 0xea, 0x30, 0x25, 0x46, 0x35, 0x24, 0x9d, 0x86, 0xbd, 0x95, 0xf1, 0x6a, 0x46, 0xd7, 0x94, 0x54, 0xf9, 0x3b, 0xbd, 0x5d}} ,
+ {{0x77, 0x5b, 0xe2, 0x37, 0xc7, 0xe1, 0x7c, 0x13, 0x8c, 0x9f, 0x7b, 0x7b, 0x2a, 0xce, 0x42, 0xa3, 0xb9, 0x2a, 0x99, 0xa8, 0xc0, 0xd8, 0x3c, 0x86, 0xb0, 0xfb, 0xe9, 0x76, 0x77, 0xf7, 0xf5, 0x56}}},
+{{{0xdf, 0xb3, 0x46, 0x11, 0x6e, 0x13, 0xb7, 0x28, 0x4e, 0x56, 0xdd, 0xf1, 0xac, 0xad, 0x58, 0xc3, 0xf8, 0x88, 0x94, 0x5e, 0x06, 0x98, 0xa1, 0xe4, 0x6a, 0xfb, 0x0a, 0x49, 0x5d, 0x8a, 0xfe, 0x77}} ,
+ {{0x46, 0x02, 0xf5, 0xa5, 0xaf, 0xc5, 0x75, 0x6d, 0xba, 0x45, 0x35, 0x0a, 0xfe, 0xc9, 0xac, 0x22, 0x91, 0x8d, 0x21, 0x95, 0x33, 0x03, 0xc0, 0x8a, 0x16, 0xf3, 0x39, 0xe0, 0x01, 0x0f, 0x53, 0x3c}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x34, 0x75, 0x37, 0x1f, 0x34, 0x4e, 0xa9, 0x1d, 0x68, 0x67, 0xf8, 0x49, 0x98, 0x96, 0xfc, 0x4c, 0x65, 0x97, 0xf7, 0x02, 0x4a, 0x52, 0x6c, 0x01, 0xbd, 0x48, 0xbb, 0x1b, 0xed, 0xa4, 0xe2, 0x53}} ,
+ {{0x59, 0xd5, 0x9b, 0x5a, 0xa2, 0x90, 0xd3, 0xb8, 0x37, 0x4c, 0x55, 0x82, 0x28, 0x08, 0x0f, 0x7f, 0xaa, 0x81, 0x65, 0xe0, 0x0c, 0x52, 0xc9, 0xa3, 0x32, 0x27, 0x64, 0xda, 0xfd, 0x34, 0x23, 0x5a}}},
+{{{0xb5, 0xb0, 0x0c, 0x4d, 0xb3, 0x7b, 0x23, 0xc8, 0x1f, 0x8a, 0x39, 0x66, 0xe6, 0xba, 0x4c, 0x10, 0x37, 0xca, 0x9c, 0x7c, 0x05, 0x9e, 0xff, 0xc0, 0xf8, 0x8e, 0xb1, 0x8f, 0x6f, 0x67, 0x18, 0x26}} ,
+ {{0x4b, 0x41, 0x13, 0x54, 0x23, 0x1a, 0xa4, 0x4e, 0xa9, 0x8b, 0x1e, 0x4b, 0xfc, 0x15, 0x24, 0xbb, 0x7e, 0xcb, 0xb6, 0x1e, 0x1b, 0xf5, 0xf2, 0xc8, 0x56, 0xec, 0x32, 0xa2, 0x60, 0x5b, 0xa0, 0x2a}}},
+{{{0xa4, 0x29, 0x47, 0x86, 0x2e, 0x92, 0x4f, 0x11, 0x4f, 0xf3, 0xb2, 0x5c, 0xd5, 0x3e, 0xa6, 0xb9, 0xc8, 0xe2, 0x33, 0x11, 0x1f, 0x01, 0x8f, 0xb0, 0x9b, 0xc7, 0xa5, 0xff, 0x83, 0x0f, 0x1e, 0x28}} ,
+ {{0x1d, 0x29, 0x7a, 0xa1, 0xec, 0x8e, 0xb5, 0xad, 0xea, 0x02, 0x68, 0x60, 0x74, 0x29, 0x1c, 0xa5, 0xcf, 0xc8, 0x3b, 0x7d, 0x8b, 0x2b, 0x7c, 0xad, 0xa4, 0x40, 0x17, 0x51, 0x59, 0x7c, 0x2e, 0x5d}}},
+{{{0x0a, 0x6c, 0x4f, 0xbc, 0x3e, 0x32, 0xe7, 0x4a, 0x1a, 0x13, 0xc1, 0x49, 0x38, 0xbf, 0xf7, 0xc2, 0xd3, 0x8f, 0x6b, 0xad, 0x52, 0xf7, 0xcf, 0xbc, 0x27, 0xcb, 0x40, 0x67, 0x76, 0xcd, 0x6d, 0x56}} ,
+ {{0xe5, 0xb0, 0x27, 0xad, 0xbe, 0x9b, 0xf2, 0xb5, 0x63, 0xde, 0x3a, 0x23, 0x95, 0xb7, 0x0a, 0x7e, 0xf3, 0x9e, 0x45, 0x6f, 0x19, 0x39, 0x75, 0x8f, 0x39, 0x3d, 0x0f, 0xc0, 0x9f, 0xf1, 0xe9, 0x51}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x88, 0xaa, 0x14, 0x24, 0x86, 0x94, 0x11, 0x12, 0x3e, 0x1a, 0xb5, 0xcc, 0xbb, 0xe0, 0x9c, 0xd5, 0x9c, 0x6d, 0xba, 0x58, 0x72, 0x8d, 0xfb, 0x22, 0x7b, 0x9f, 0x7c, 0x94, 0x30, 0xb3, 0x51, 0x21}} ,
+ {{0xf6, 0x74, 0x3d, 0xf2, 0xaf, 0xd0, 0x1e, 0x03, 0x7c, 0x23, 0x6b, 0xc9, 0xfc, 0x25, 0x70, 0x90, 0xdc, 0x9a, 0xa4, 0xfb, 0x49, 0xfc, 0x3d, 0x0a, 0x35, 0x38, 0x6f, 0xe4, 0x7e, 0x50, 0x01, 0x2a}}},
+{{{0xd6, 0xe3, 0x96, 0x61, 0x3a, 0xfd, 0xef, 0x9b, 0x1f, 0x90, 0xa4, 0x24, 0x14, 0x5b, 0xc8, 0xde, 0x50, 0xb1, 0x1d, 0xaf, 0xe8, 0x55, 0x8a, 0x87, 0x0d, 0xfe, 0xaa, 0x3b, 0x82, 0x2c, 0x8d, 0x7b}} ,
+ {{0x85, 0x0c, 0xaf, 0xf8, 0x83, 0x44, 0x49, 0xd9, 0x45, 0xcf, 0xf7, 0x48, 0xd9, 0x53, 0xb4, 0xf1, 0x65, 0xa0, 0xe1, 0xc3, 0xb3, 0x15, 0xed, 0x89, 0x9b, 0x4f, 0x62, 0xb3, 0x57, 0xa5, 0x45, 0x1c}}},
+{{{0x8f, 0x12, 0xea, 0xaf, 0xd1, 0x1f, 0x79, 0x10, 0x0b, 0xf6, 0xa3, 0x7b, 0xea, 0xac, 0x8b, 0x57, 0x32, 0x62, 0xe7, 0x06, 0x12, 0x51, 0xa0, 0x3b, 0x43, 0x5e, 0xa4, 0x20, 0x78, 0x31, 0xce, 0x0d}} ,
+ {{0x84, 0x7c, 0xc2, 0xa6, 0x91, 0x23, 0xce, 0xbd, 0xdc, 0xf9, 0xce, 0xd5, 0x75, 0x30, 0x22, 0xe6, 0xf9, 0x43, 0x62, 0x0d, 0xf7, 0x75, 0x9d, 0x7f, 0x8c, 0xff, 0x7d, 0xe4, 0x72, 0xac, 0x9f, 0x1c}}},
+{{{0x88, 0xc1, 0x99, 0xd0, 0x3c, 0x1c, 0x5d, 0xb4, 0xef, 0x13, 0x0f, 0x90, 0xb9, 0x36, 0x2f, 0x95, 0x95, 0xc6, 0xdc, 0xde, 0x0a, 0x51, 0xe2, 0x8d, 0xf3, 0xbc, 0x51, 0xec, 0xdf, 0xb1, 0xa2, 0x5f}} ,
+ {{0x2e, 0x68, 0xa1, 0x23, 0x7d, 0x9b, 0x40, 0x69, 0x85, 0x7b, 0x42, 0xbf, 0x90, 0x4b, 0xd6, 0x40, 0x2f, 0xd7, 0x52, 0x52, 0xb2, 0x21, 0xde, 0x64, 0xbd, 0x88, 0xc3, 0x6d, 0xa5, 0xfa, 0x81, 0x3f}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xfb, 0xfd, 0x47, 0x7b, 0x8a, 0x66, 0x9e, 0x79, 0x2e, 0x64, 0x82, 0xef, 0xf7, 0x21, 0xec, 0xf6, 0xd8, 0x86, 0x09, 0x31, 0x7c, 0xdd, 0x03, 0x6a, 0x58, 0xa0, 0x77, 0xb7, 0x9b, 0x8c, 0x87, 0x1f}} ,
+ {{0x55, 0x47, 0xe4, 0xa8, 0x3d, 0x55, 0x21, 0x34, 0xab, 0x1d, 0xae, 0xe0, 0xf4, 0xea, 0xdb, 0xc5, 0xb9, 0x58, 0xbf, 0xc4, 0x2a, 0x89, 0x31, 0x1a, 0xf4, 0x2d, 0xe1, 0xca, 0x37, 0x99, 0x47, 0x59}}},
+{{{0xc7, 0xca, 0x63, 0xc1, 0x49, 0xa9, 0x35, 0x45, 0x55, 0x7e, 0xda, 0x64, 0x32, 0x07, 0x50, 0xf7, 0x32, 0xac, 0xde, 0x75, 0x58, 0x9b, 0x11, 0xb2, 0x3a, 0x1f, 0xf5, 0xf7, 0x79, 0x04, 0xe6, 0x08}} ,
+ {{0x46, 0xfa, 0x22, 0x4b, 0xfa, 0xe1, 0xfe, 0x96, 0xfc, 0x67, 0xba, 0x67, 0x97, 0xc4, 0xe7, 0x1b, 0x86, 0x90, 0x5f, 0xee, 0xf4, 0x5b, 0x11, 0xb2, 0xcd, 0xad, 0xee, 0xc2, 0x48, 0x6c, 0x2b, 0x1b}}},
+{{{0xe3, 0x39, 0x62, 0xb4, 0x4f, 0x31, 0x04, 0xc9, 0xda, 0xd5, 0x73, 0x51, 0x57, 0xc5, 0xb8, 0xf3, 0xa3, 0x43, 0x70, 0xe4, 0x61, 0x81, 0x84, 0xe2, 0xbb, 0xbf, 0x4f, 0x9e, 0xa4, 0x5e, 0x74, 0x06}} ,
+ {{0x29, 0xac, 0xff, 0x27, 0xe0, 0x59, 0xbe, 0x39, 0x9c, 0x0d, 0x83, 0xd7, 0x10, 0x0b, 0x15, 0xb7, 0xe1, 0xc2, 0x2c, 0x30, 0x73, 0x80, 0x3a, 0x7d, 0x5d, 0xab, 0x58, 0x6b, 0xc1, 0xf0, 0xf4, 0x22}}},
+{{{0xfe, 0x7f, 0xfb, 0x35, 0x7d, 0xc6, 0x01, 0x23, 0x28, 0xc4, 0x02, 0xac, 0x1f, 0x42, 0xb4, 0x9d, 0xfc, 0x00, 0x94, 0xa5, 0xee, 0xca, 0xda, 0x97, 0x09, 0x41, 0x77, 0x87, 0x5d, 0x7b, 0x87, 0x78}} ,
+ {{0xf5, 0xfb, 0x90, 0x2d, 0x81, 0x19, 0x9e, 0x2f, 0x6d, 0x85, 0x88, 0x8c, 0x40, 0x5c, 0x77, 0x41, 0x4d, 0x01, 0x19, 0x76, 0x60, 0xe8, 0x4c, 0x48, 0xe4, 0x33, 0x83, 0x32, 0x6c, 0xb4, 0x41, 0x03}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xff, 0x10, 0xc2, 0x09, 0x4f, 0x6e, 0xf4, 0xd2, 0xdf, 0x7e, 0xca, 0x7b, 0x1c, 0x1d, 0xba, 0xa3, 0xb6, 0xda, 0x67, 0x33, 0xd4, 0x87, 0x36, 0x4b, 0x11, 0x20, 0x05, 0xa6, 0x29, 0xc1, 0x87, 0x17}} ,
+ {{0xf6, 0x96, 0xca, 0x2f, 0xda, 0x38, 0xa7, 0x1b, 0xfc, 0xca, 0x7d, 0xfe, 0x08, 0x89, 0xe2, 0x47, 0x2b, 0x6a, 0x5d, 0x4b, 0xfa, 0xa1, 0xb4, 0xde, 0xb6, 0xc2, 0x31, 0x51, 0xf5, 0xe0, 0xa4, 0x0b}}},
+{{{0x5c, 0xe5, 0xc6, 0x04, 0x8e, 0x2b, 0x57, 0xbe, 0x38, 0x85, 0x23, 0xcb, 0xb7, 0xbe, 0x4f, 0xa9, 0xd3, 0x6e, 0x12, 0xaa, 0xd5, 0xb2, 0x2e, 0x93, 0x29, 0x9a, 0x4a, 0x88, 0x18, 0x43, 0xf5, 0x01}} ,
+ {{0x50, 0xfc, 0xdb, 0xa2, 0x59, 0x21, 0x8d, 0xbd, 0x7e, 0x33, 0xae, 0x2f, 0x87, 0x1a, 0xd0, 0x97, 0xc7, 0x0d, 0x4d, 0x63, 0x01, 0xef, 0x05, 0x84, 0xec, 0x40, 0xdd, 0xa8, 0x0a, 0x4f, 0x70, 0x0b}}},
+{{{0x41, 0x69, 0x01, 0x67, 0x5c, 0xd3, 0x8a, 0xc5, 0xcf, 0x3f, 0xd1, 0x57, 0xd1, 0x67, 0x3e, 0x01, 0x39, 0xb5, 0xcb, 0x81, 0x56, 0x96, 0x26, 0xb6, 0xc2, 0xe7, 0x5c, 0xfb, 0x63, 0x97, 0x58, 0x06}} ,
+ {{0x0c, 0x0e, 0xf3, 0xba, 0xf0, 0xe5, 0xba, 0xb2, 0x57, 0x77, 0xc6, 0x20, 0x9b, 0x89, 0x24, 0xbe, 0xf2, 0x9c, 0x8a, 0xba, 0x69, 0xc1, 0xf1, 0xb0, 0x4f, 0x2a, 0x05, 0x9a, 0xee, 0x10, 0x7e, 0x36}}},
+{{{0x3f, 0x26, 0xe9, 0x40, 0xe9, 0x03, 0xad, 0x06, 0x69, 0x91, 0xe0, 0xd1, 0x89, 0x60, 0x84, 0x79, 0xde, 0x27, 0x6d, 0xe6, 0x76, 0xbd, 0xea, 0xe6, 0xae, 0x48, 0xc3, 0x67, 0xc0, 0x57, 0xcd, 0x2f}} ,
+ {{0x7f, 0xc1, 0xdc, 0xb9, 0xc7, 0xbc, 0x86, 0x3d, 0x55, 0x4b, 0x28, 0x7a, 0xfb, 0x4d, 0xc7, 0xf8, 0xbc, 0x67, 0x2a, 0x60, 0x4d, 0x8f, 0x07, 0x0b, 0x1a, 0x17, 0xbf, 0xfa, 0xac, 0xa7, 0x3d, 0x1a}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x91, 0x3f, 0xed, 0x5e, 0x18, 0x78, 0x3f, 0x23, 0x2c, 0x0d, 0x8c, 0x44, 0x00, 0xe8, 0xfb, 0xe9, 0x8e, 0xd6, 0xd1, 0x36, 0x58, 0x57, 0x9e, 0xae, 0x4b, 0x5c, 0x0b, 0x07, 0xbc, 0x6b, 0x55, 0x2b}} ,
+ {{0x6f, 0x4d, 0x17, 0xd7, 0xe1, 0x84, 0xd9, 0x78, 0xb1, 0x90, 0xfd, 0x2e, 0xb3, 0xb5, 0x19, 0x3f, 0x1b, 0xfa, 0xc0, 0x68, 0xb3, 0xdd, 0x00, 0x2e, 0x89, 0xbd, 0x7e, 0x80, 0x32, 0x13, 0xa0, 0x7b}}},
+{{{0x1a, 0x6f, 0x40, 0xaf, 0x44, 0x44, 0xb0, 0x43, 0x8f, 0x0d, 0xd0, 0x1e, 0xc4, 0x0b, 0x19, 0x5d, 0x8e, 0xfe, 0xc1, 0xf3, 0xc5, 0x5c, 0x91, 0xf8, 0x04, 0x4e, 0xbe, 0x90, 0xb4, 0x47, 0x5c, 0x3f}} ,
+ {{0xb0, 0x3b, 0x2c, 0xf3, 0xfe, 0x32, 0x71, 0x07, 0x3f, 0xaa, 0xba, 0x45, 0x60, 0xa8, 0x8d, 0xea, 0x54, 0xcb, 0x39, 0x10, 0xb4, 0xf2, 0x8b, 0xd2, 0x14, 0x82, 0x42, 0x07, 0x8e, 0xe9, 0x7c, 0x53}}},
+{{{0xb0, 0xae, 0xc1, 0x8d, 0xc9, 0x8f, 0xb9, 0x7a, 0x77, 0xef, 0xba, 0x79, 0xa0, 0x3c, 0xa8, 0xf5, 0x6a, 0xe2, 0x3f, 0x5d, 0x00, 0xe3, 0x4b, 0x45, 0x24, 0x7b, 0x43, 0x78, 0x55, 0x1d, 0x2b, 0x1e}} ,
+ {{0x01, 0xb8, 0xd6, 0x16, 0x67, 0xa0, 0x15, 0xb9, 0xe1, 0x58, 0xa4, 0xa7, 0x31, 0x37, 0x77, 0x2f, 0x8b, 0x12, 0x9f, 0xf4, 0x3f, 0xc7, 0x36, 0x66, 0xd2, 0xa8, 0x56, 0xf7, 0x7f, 0x74, 0xc6, 0x41}}},
+{{{0x5d, 0xf8, 0xb4, 0xa8, 0x30, 0xdd, 0xcc, 0x38, 0xa5, 0xd3, 0xca, 0xd8, 0xd1, 0xf8, 0xb2, 0x31, 0x91, 0xd4, 0x72, 0x05, 0x57, 0x4a, 0x3b, 0x82, 0x4a, 0xc6, 0x68, 0x20, 0xe2, 0x18, 0x41, 0x61}} ,
+ {{0x19, 0xd4, 0x8d, 0x47, 0x29, 0x12, 0x65, 0xb0, 0x11, 0x78, 0x47, 0xb5, 0xcb, 0xa3, 0xa5, 0xfa, 0x05, 0x85, 0x54, 0xa9, 0x33, 0x97, 0x8d, 0x2b, 0xc2, 0xfe, 0x99, 0x35, 0x28, 0xe5, 0xeb, 0x63}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xb1, 0x3f, 0x3f, 0xef, 0xd8, 0xf4, 0xfc, 0xb3, 0xa0, 0x60, 0x50, 0x06, 0x2b, 0x29, 0x52, 0x70, 0x15, 0x0b, 0x24, 0x24, 0xf8, 0x5f, 0x79, 0x18, 0xcc, 0xff, 0x89, 0x99, 0x84, 0xa1, 0xae, 0x13}} ,
+ {{0x44, 0x1f, 0xb8, 0xc2, 0x01, 0xc1, 0x30, 0x19, 0x55, 0x05, 0x60, 0x10, 0xa4, 0x6c, 0x2d, 0x67, 0x70, 0xe5, 0x25, 0x1b, 0xf2, 0xbf, 0xdd, 0xfb, 0x70, 0x2b, 0xa1, 0x8c, 0x9c, 0x94, 0x84, 0x08}}},
+{{{0xe7, 0xc4, 0x43, 0x4d, 0xc9, 0x2b, 0x69, 0x5d, 0x1d, 0x3c, 0xaf, 0xbb, 0x43, 0x38, 0x4e, 0x98, 0x3d, 0xed, 0x0d, 0x21, 0x03, 0xfd, 0xf0, 0x99, 0x47, 0x04, 0xb0, 0x98, 0x69, 0x55, 0x72, 0x0f}} ,
+ {{0x5e, 0xdf, 0x15, 0x53, 0x3b, 0x86, 0x80, 0xb0, 0xf1, 0x70, 0x68, 0x8f, 0x66, 0x7c, 0x0e, 0x49, 0x1a, 0xd8, 0x6b, 0xfe, 0x4e, 0xef, 0xca, 0x47, 0xd4, 0x03, 0xc1, 0x37, 0x50, 0x9c, 0xc1, 0x16}}},
+{{{0xcd, 0x24, 0xc6, 0x3e, 0x0c, 0x82, 0x9b, 0x91, 0x2b, 0x61, 0x4a, 0xb2, 0x0f, 0x88, 0x55, 0x5f, 0x5a, 0x57, 0xff, 0xe5, 0x74, 0x0b, 0x13, 0x43, 0x00, 0xd8, 0x6b, 0xcf, 0xd2, 0x15, 0x03, 0x2c}} ,
+ {{0xdc, 0xff, 0x15, 0x61, 0x2f, 0x4a, 0x2f, 0x62, 0xf2, 0x04, 0x2f, 0xb5, 0x0c, 0xb7, 0x1e, 0x3f, 0x74, 0x1a, 0x0f, 0xd7, 0xea, 0xcd, 0xd9, 0x7d, 0xf6, 0x12, 0x0e, 0x2f, 0xdb, 0x5a, 0x3b, 0x16}}},
+{{{0x1b, 0x37, 0x47, 0xe3, 0xf5, 0x9e, 0xea, 0x2c, 0x2a, 0xe7, 0x82, 0x36, 0xf4, 0x1f, 0x81, 0x47, 0x92, 0x4b, 0x69, 0x0e, 0x11, 0x8c, 0x5d, 0x53, 0x5b, 0x81, 0x27, 0x08, 0xbc, 0xa0, 0xae, 0x25}} ,
+ {{0x69, 0x32, 0xa1, 0x05, 0x11, 0x42, 0x00, 0xd2, 0x59, 0xac, 0x4d, 0x62, 0x8b, 0x13, 0xe2, 0x50, 0x5d, 0xa0, 0x9d, 0x9b, 0xfd, 0xbb, 0x12, 0x41, 0x75, 0x41, 0x9e, 0xcc, 0xdc, 0xc7, 0xdc, 0x5d}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xd9, 0xe3, 0x38, 0x06, 0x46, 0x70, 0x82, 0x5e, 0x28, 0x49, 0x79, 0xff, 0x25, 0xd2, 0x4e, 0x29, 0x8d, 0x06, 0xb0, 0x23, 0xae, 0x9b, 0x66, 0xe4, 0x7d, 0xc0, 0x70, 0x91, 0xa3, 0xfc, 0xec, 0x4e}} ,
+ {{0x62, 0x12, 0x37, 0x6a, 0x30, 0xf6, 0x1e, 0xfb, 0x14, 0x5c, 0x0d, 0x0e, 0xb7, 0x81, 0x6a, 0xe7, 0x08, 0x05, 0xac, 0xaa, 0x38, 0x46, 0xe2, 0x73, 0xea, 0x4b, 0x07, 0x81, 0x43, 0x7c, 0x9e, 0x5e}}},
+{{{0xfc, 0xf9, 0x21, 0x4f, 0x2e, 0x76, 0x9b, 0x1f, 0x28, 0x60, 0x77, 0x43, 0x32, 0x9d, 0xbe, 0x17, 0x30, 0x2a, 0xc6, 0x18, 0x92, 0x66, 0x62, 0x30, 0x98, 0x40, 0x11, 0xa6, 0x7f, 0x18, 0x84, 0x28}} ,
+ {{0x3f, 0xab, 0xd3, 0xf4, 0x8a, 0x76, 0xa1, 0x3c, 0xca, 0x2d, 0x49, 0xc3, 0xea, 0x08, 0x0b, 0x85, 0x17, 0x2a, 0xc3, 0x6c, 0x08, 0xfd, 0x57, 0x9f, 0x3d, 0x5f, 0xdf, 0x67, 0x68, 0x42, 0x00, 0x32}}},
+{{{0x51, 0x60, 0x1b, 0x06, 0x4f, 0x8a, 0x21, 0xba, 0x38, 0xa8, 0xba, 0xd6, 0x40, 0xf6, 0xe9, 0x9b, 0x76, 0x4d, 0x56, 0x21, 0x5b, 0x0a, 0x9b, 0x2e, 0x4f, 0x3d, 0x81, 0x32, 0x08, 0x9f, 0x97, 0x5b}} ,
+ {{0xe5, 0x44, 0xec, 0x06, 0x9d, 0x90, 0x79, 0x9f, 0xd3, 0xe0, 0x79, 0xaf, 0x8f, 0x10, 0xfd, 0xdd, 0x04, 0xae, 0x27, 0x97, 0x46, 0x33, 0x79, 0xea, 0xb8, 0x4e, 0xca, 0x5a, 0x59, 0x57, 0xe1, 0x0e}}},
+{{{0x1a, 0xda, 0xf3, 0xa5, 0x41, 0x43, 0x28, 0xfc, 0x7e, 0xe7, 0x71, 0xea, 0xc6, 0x3b, 0x59, 0xcc, 0x2e, 0xd3, 0x40, 0xec, 0xb3, 0x13, 0x6f, 0x44, 0xcd, 0x13, 0xb2, 0x37, 0xf2, 0x6e, 0xd9, 0x1c}} ,
+ {{0xe3, 0xdb, 0x60, 0xcd, 0x5c, 0x4a, 0x18, 0x0f, 0xef, 0x73, 0x36, 0x71, 0x8c, 0xf6, 0x11, 0xb4, 0xd8, 0xce, 0x17, 0x5e, 0x4f, 0x26, 0x77, 0x97, 0x5f, 0xcb, 0xef, 0x91, 0xeb, 0x6a, 0x62, 0x7a}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x18, 0x4a, 0xa2, 0x97, 0x08, 0x81, 0x2d, 0x83, 0xc4, 0xcc, 0xf0, 0x83, 0x7e, 0xec, 0x0d, 0x95, 0x4c, 0x5b, 0xfb, 0xfa, 0x98, 0x80, 0x4a, 0x66, 0x56, 0x0c, 0x51, 0xb3, 0xf2, 0x04, 0x5d, 0x27}} ,
+ {{0x3b, 0xb9, 0xb8, 0x06, 0x5a, 0x2e, 0xfe, 0xc3, 0x82, 0x37, 0x9c, 0xa3, 0x11, 0x1f, 0x9c, 0xa6, 0xda, 0x63, 0x48, 0x9b, 0xad, 0xde, 0x2d, 0xa6, 0xbc, 0x6e, 0x32, 0xda, 0x27, 0x65, 0xdd, 0x57}}},
+{{{0x84, 0x4f, 0x37, 0x31, 0x7d, 0x2e, 0xbc, 0xad, 0x87, 0x07, 0x2a, 0x6b, 0x37, 0xfc, 0x5f, 0xeb, 0x4e, 0x75, 0x35, 0xa6, 0xde, 0xab, 0x0a, 0x19, 0x3a, 0xb7, 0xb1, 0xef, 0x92, 0x6a, 0x3b, 0x3c}} ,
+ {{0x3b, 0xb2, 0x94, 0x6d, 0x39, 0x60, 0xac, 0xee, 0xe7, 0x81, 0x1a, 0x3b, 0x76, 0x87, 0x5c, 0x05, 0x94, 0x2a, 0x45, 0xb9, 0x80, 0xe9, 0x22, 0xb1, 0x07, 0xcb, 0x40, 0x9e, 0x70, 0x49, 0x6d, 0x12}}},
+{{{0xfd, 0x18, 0x78, 0x84, 0xa8, 0x4c, 0x7d, 0x6e, 0x59, 0xa6, 0xe5, 0x74, 0xf1, 0x19, 0xa6, 0x84, 0x2e, 0x51, 0xc1, 0x29, 0x13, 0xf2, 0x14, 0x6b, 0x5d, 0x53, 0x51, 0xf7, 0xef, 0xbf, 0x01, 0x22}} ,
+ {{0xa4, 0x4b, 0x62, 0x4c, 0xe6, 0xfd, 0x72, 0x07, 0xf2, 0x81, 0xfc, 0xf2, 0xbd, 0x12, 0x7c, 0x68, 0x76, 0x2a, 0xba, 0xf5, 0x65, 0xb1, 0x1f, 0x17, 0x0a, 0x38, 0xb0, 0xbf, 0xc0, 0xf8, 0xf4, 0x2a}}},
+{{{0x55, 0x60, 0x55, 0x5b, 0xe4, 0x1d, 0x71, 0x4c, 0x9d, 0x5b, 0x9f, 0x70, 0xa6, 0x85, 0x9a, 0x2c, 0xa0, 0xe2, 0x32, 0x48, 0xce, 0x9e, 0x2a, 0xa5, 0x07, 0x3b, 0xc7, 0x6c, 0x86, 0x77, 0xde, 0x3c}} ,
+ {{0xf7, 0x18, 0x7a, 0x96, 0x7e, 0x43, 0x57, 0xa9, 0x55, 0xfc, 0x4e, 0xb6, 0x72, 0x00, 0xf2, 0xe4, 0xd7, 0x52, 0xd3, 0xd3, 0xb6, 0x85, 0xf6, 0x71, 0xc7, 0x44, 0x3f, 0x7f, 0xd7, 0xb3, 0xf2, 0x79}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x46, 0xca, 0xa7, 0x55, 0x7b, 0x79, 0xf3, 0xca, 0x5a, 0x65, 0xf6, 0xed, 0x50, 0x14, 0x7b, 0xe4, 0xc4, 0x2a, 0x65, 0x9e, 0xe2, 0xf9, 0xca, 0xa7, 0x22, 0x26, 0x53, 0xcb, 0x21, 0x5b, 0xa7, 0x31}} ,
+ {{0x90, 0xd7, 0xc5, 0x26, 0x08, 0xbd, 0xb0, 0x53, 0x63, 0x58, 0xc3, 0x31, 0x5e, 0x75, 0x46, 0x15, 0x91, 0xa6, 0xf8, 0x2f, 0x1a, 0x08, 0x65, 0x88, 0x2f, 0x98, 0x04, 0xf1, 0x7c, 0x6e, 0x00, 0x77}}},
+{{{0x81, 0x21, 0x61, 0x09, 0xf6, 0x4e, 0xf1, 0x92, 0xee, 0x63, 0x61, 0x73, 0x87, 0xc7, 0x54, 0x0e, 0x42, 0x4b, 0xc9, 0x47, 0xd1, 0xb8, 0x7e, 0x91, 0x75, 0x37, 0x99, 0x28, 0xb8, 0xdd, 0x7f, 0x50}} ,
+ {{0x89, 0x8f, 0xc0, 0xbe, 0x5d, 0xd6, 0x9f, 0xa0, 0xf0, 0x9d, 0x81, 0xce, 0x3a, 0x7b, 0x98, 0x58, 0xbb, 0xd7, 0x78, 0xc8, 0x3f, 0x13, 0xf1, 0x74, 0x19, 0xdf, 0xf8, 0x98, 0x89, 0x5d, 0xfa, 0x5f}}},
+{{{0x9e, 0x35, 0x85, 0x94, 0x47, 0x1f, 0x90, 0x15, 0x26, 0xd0, 0x84, 0xed, 0x8a, 0x80, 0xf7, 0x63, 0x42, 0x86, 0x27, 0xd7, 0xf4, 0x75, 0x58, 0xdc, 0x9c, 0xc0, 0x22, 0x7e, 0x20, 0x35, 0xfd, 0x1f}} ,
+ {{0x68, 0x0e, 0x6f, 0x97, 0xba, 0x70, 0xbb, 0xa3, 0x0e, 0xe5, 0x0b, 0x12, 0xf4, 0xa2, 0xdc, 0x47, 0xf8, 0xe6, 0xd0, 0x23, 0x6c, 0x33, 0xa8, 0x99, 0x46, 0x6e, 0x0f, 0x44, 0xba, 0x76, 0x48, 0x0f}}},
+{{{0xa3, 0x2a, 0x61, 0x37, 0xe2, 0x59, 0x12, 0x0e, 0x27, 0xba, 0x64, 0x43, 0xae, 0xc0, 0x42, 0x69, 0x79, 0xa4, 0x1e, 0x29, 0x8b, 0x15, 0xeb, 0xf8, 0xaf, 0xd4, 0xa2, 0x68, 0x33, 0xb5, 0x7a, 0x24}} ,
+ {{0x2c, 0x19, 0x33, 0xdd, 0x1b, 0xab, 0xec, 0x01, 0xb0, 0x23, 0xf8, 0x42, 0x2b, 0x06, 0x88, 0xea, 0x3d, 0x2d, 0x00, 0x2a, 0x78, 0x45, 0x4d, 0x38, 0xed, 0x2e, 0x2e, 0x44, 0x49, 0xed, 0xcb, 0x33}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xa0, 0x68, 0xe8, 0x41, 0x8f, 0x91, 0xf8, 0x11, 0x13, 0x90, 0x2e, 0xa7, 0xab, 0x30, 0xef, 0xad, 0xa0, 0x61, 0x00, 0x88, 0xef, 0xdb, 0xce, 0x5b, 0x5c, 0xbb, 0x62, 0xc8, 0x56, 0xf9, 0x00, 0x73}} ,
+ {{0x3f, 0x60, 0xc1, 0x82, 0x2d, 0xa3, 0x28, 0x58, 0x24, 0x9e, 0x9f, 0xe3, 0x70, 0xcc, 0x09, 0x4e, 0x1a, 0x3f, 0x11, 0x11, 0x15, 0x07, 0x3c, 0xa4, 0x41, 0xe0, 0x65, 0xa3, 0x0a, 0x41, 0x6d, 0x11}}},
+{{{0x31, 0x40, 0x01, 0x52, 0x56, 0x94, 0x5b, 0x28, 0x8a, 0xaa, 0x52, 0xee, 0xd8, 0x0a, 0x05, 0x8d, 0xcd, 0xb5, 0xaa, 0x2e, 0x38, 0xaa, 0xb7, 0x87, 0xf7, 0x2b, 0xfb, 0x04, 0xcb, 0x84, 0x3d, 0x54}} ,
+ {{0x20, 0xef, 0x59, 0xde, 0xa4, 0x2b, 0x93, 0x6e, 0x2e, 0xec, 0x42, 0x9a, 0xd4, 0x2d, 0xf4, 0x46, 0x58, 0x27, 0x2b, 0x18, 0x8f, 0x83, 0x3d, 0x69, 0x9e, 0xd4, 0x3e, 0xb6, 0xc5, 0xfd, 0x58, 0x03}}},
+{{{0x33, 0x89, 0xc9, 0x63, 0x62, 0x1c, 0x17, 0xb4, 0x60, 0xc4, 0x26, 0x68, 0x09, 0xc3, 0x2e, 0x37, 0x0f, 0x7b, 0xb4, 0x9c, 0xb6, 0xf9, 0xfb, 0xd4, 0x51, 0x78, 0xc8, 0x63, 0xea, 0x77, 0x47, 0x07}} ,
+ {{0x32, 0xb4, 0x18, 0x47, 0x79, 0xcb, 0xd4, 0x5a, 0x07, 0x14, 0x0f, 0xa0, 0xd5, 0xac, 0xd0, 0x41, 0x40, 0xab, 0x61, 0x23, 0xe5, 0x2a, 0x2a, 0x6f, 0xf7, 0xa8, 0xd4, 0x76, 0xef, 0xe7, 0x45, 0x6c}}},
+{{{0xa1, 0x5e, 0x60, 0x4f, 0xfb, 0xe1, 0x70, 0x6a, 0x1f, 0x55, 0x4f, 0x09, 0xb4, 0x95, 0x33, 0x36, 0xc6, 0x81, 0x01, 0x18, 0x06, 0x25, 0x27, 0xa4, 0xb4, 0x24, 0xa4, 0x86, 0x03, 0x4c, 0xac, 0x02}} ,
+ {{0x77, 0x38, 0xde, 0xd7, 0x60, 0x48, 0x07, 0xf0, 0x74, 0xa8, 0xff, 0x54, 0xe5, 0x30, 0x43, 0xff, 0x77, 0xfb, 0x21, 0x07, 0xff, 0xb2, 0x07, 0x6b, 0xe4, 0xe5, 0x30, 0xfc, 0x19, 0x6c, 0xa3, 0x01}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x13, 0xc5, 0x2c, 0xac, 0xd3, 0x83, 0x82, 0x7c, 0x29, 0xf7, 0x05, 0xa5, 0x00, 0xb6, 0x1f, 0x86, 0x55, 0xf4, 0xd6, 0x2f, 0x0c, 0x99, 0xd0, 0x65, 0x9b, 0x6b, 0x46, 0x0d, 0x43, 0xf8, 0x16, 0x28}} ,
+ {{0x1e, 0x7f, 0xb4, 0x74, 0x7e, 0xb1, 0x89, 0x4f, 0x18, 0x5a, 0xab, 0x64, 0x06, 0xdf, 0x45, 0x87, 0xe0, 0x6a, 0xc6, 0xf0, 0x0e, 0xc9, 0x24, 0x35, 0x38, 0xea, 0x30, 0x54, 0xb4, 0xc4, 0x52, 0x54}}},
+{{{0xe9, 0x9f, 0xdc, 0x3f, 0xc1, 0x89, 0x44, 0x74, 0x27, 0xe4, 0xc1, 0x90, 0xff, 0x4a, 0xa7, 0x3c, 0xee, 0xcd, 0xf4, 0x1d, 0x25, 0x94, 0x7f, 0x63, 0x16, 0x48, 0xbc, 0x64, 0xfe, 0x95, 0xc4, 0x0c}} ,
+ {{0x8b, 0x19, 0x75, 0x6e, 0x03, 0x06, 0x5e, 0x6a, 0x6f, 0x1a, 0x8c, 0xe3, 0xd3, 0x28, 0xf2, 0xe0, 0xb9, 0x7a, 0x43, 0x69, 0xe6, 0xd3, 0xc0, 0xfe, 0x7e, 0x97, 0xab, 0x6c, 0x7b, 0x8e, 0x13, 0x42}}},
+{{{0xd4, 0xca, 0x70, 0x3d, 0xab, 0xfb, 0x5f, 0x5e, 0x00, 0x0c, 0xcc, 0x77, 0x22, 0xf8, 0x78, 0x55, 0xae, 0x62, 0x35, 0xfb, 0x9a, 0xc6, 0x03, 0xe4, 0x0c, 0xee, 0xab, 0xc7, 0xc0, 0x89, 0x87, 0x54}} ,
+ {{0x32, 0xad, 0xae, 0x85, 0x58, 0x43, 0xb8, 0xb1, 0xe6, 0x3e, 0x00, 0x9c, 0x78, 0x88, 0x56, 0xdb, 0x9c, 0xfc, 0x79, 0xf6, 0xf9, 0x41, 0x5f, 0xb7, 0xbc, 0x11, 0xf9, 0x20, 0x36, 0x1c, 0x53, 0x2b}}},
+{{{0x5a, 0x20, 0x5b, 0xa1, 0xa5, 0x44, 0x91, 0x24, 0x02, 0x63, 0x12, 0x64, 0xb8, 0x55, 0xf6, 0xde, 0x2c, 0xdb, 0x47, 0xb8, 0xc6, 0x0a, 0xc3, 0x00, 0x78, 0x93, 0xd8, 0xf5, 0xf5, 0x18, 0x28, 0x0a}} ,
+ {{0xd6, 0x1b, 0x9a, 0x6c, 0xe5, 0x46, 0xea, 0x70, 0x96, 0x8d, 0x4e, 0x2a, 0x52, 0x21, 0x26, 0x4b, 0xb1, 0xbb, 0x0f, 0x7c, 0xa9, 0x9b, 0x04, 0xbb, 0x51, 0x08, 0xf1, 0x9a, 0xa4, 0x76, 0x7c, 0x18}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xfa, 0x94, 0xf7, 0x40, 0xd0, 0xd7, 0xeb, 0xa9, 0x82, 0x36, 0xd5, 0x15, 0xb9, 0x33, 0x7a, 0xbf, 0x8a, 0xf2, 0x63, 0xaa, 0x37, 0xf5, 0x59, 0xac, 0xbd, 0xbb, 0x32, 0x36, 0xbe, 0x73, 0x99, 0x38}} ,
+ {{0x2c, 0xb3, 0xda, 0x7a, 0xd8, 0x3d, 0x99, 0xca, 0xd2, 0xf4, 0xda, 0x99, 0x8e, 0x4f, 0x98, 0xb7, 0xf4, 0xae, 0x3e, 0x9f, 0x8e, 0x35, 0x60, 0xa4, 0x33, 0x75, 0xa4, 0x04, 0x93, 0xb1, 0x6b, 0x4d}}},
+{{{0x97, 0x9d, 0xa8, 0xcd, 0x97, 0x7b, 0x9d, 0xb9, 0xe7, 0xa5, 0xef, 0xfd, 0xa8, 0x42, 0x6b, 0xc3, 0x62, 0x64, 0x7d, 0xa5, 0x1b, 0xc9, 0x9e, 0xd2, 0x45, 0xb9, 0xee, 0x03, 0xb0, 0xbf, 0xc0, 0x68}} ,
+ {{0xed, 0xb7, 0x84, 0x2c, 0xf6, 0xd3, 0xa1, 0x6b, 0x24, 0x6d, 0x87, 0x56, 0x97, 0x59, 0x79, 0x62, 0x9f, 0xac, 0xed, 0xf3, 0xc9, 0x89, 0x21, 0x2e, 0x04, 0xb3, 0xcc, 0x2f, 0xbe, 0xd6, 0x0a, 0x4b}}},
+{{{0x39, 0x61, 0x05, 0xed, 0x25, 0x89, 0x8b, 0x5d, 0x1b, 0xcb, 0x0c, 0x55, 0xf4, 0x6a, 0x00, 0x8a, 0x46, 0xe8, 0x1e, 0xc6, 0x83, 0xc8, 0x5a, 0x76, 0xdb, 0xcc, 0x19, 0x7a, 0xcc, 0x67, 0x46, 0x0b}} ,
+ {{0x53, 0xcf, 0xc2, 0xa1, 0xad, 0x6a, 0xf3, 0xcd, 0x8f, 0xc9, 0xde, 0x1c, 0xf8, 0x6c, 0x8f, 0xf8, 0x76, 0x42, 0xe7, 0xfe, 0xb2, 0x72, 0x21, 0x0a, 0x66, 0x74, 0x8f, 0xb7, 0xeb, 0xe4, 0x6f, 0x01}}},
+{{{0x22, 0x8c, 0x6b, 0xbe, 0xfc, 0x4d, 0x70, 0x62, 0x6e, 0x52, 0x77, 0x99, 0x88, 0x7e, 0x7b, 0x57, 0x7a, 0x0d, 0xfe, 0xdc, 0x72, 0x92, 0xf1, 0x68, 0x1d, 0x97, 0xd7, 0x7c, 0x8d, 0x53, 0x10, 0x37}} ,
+ {{0x53, 0x88, 0x77, 0x02, 0xca, 0x27, 0xa8, 0xe5, 0x45, 0xe2, 0xa8, 0x48, 0x2a, 0xab, 0x18, 0xca, 0xea, 0x2d, 0x2a, 0x54, 0x17, 0x37, 0x32, 0x09, 0xdc, 0xe0, 0x4a, 0xb7, 0x7d, 0x82, 0x10, 0x7d}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x8a, 0x64, 0x1e, 0x14, 0x0a, 0x57, 0xd4, 0xda, 0x5c, 0x96, 0x9b, 0x01, 0x4c, 0x67, 0xbf, 0x8b, 0x30, 0xfe, 0x08, 0xdb, 0x0d, 0xd5, 0xa8, 0xd7, 0x09, 0x11, 0x85, 0xa2, 0xd3, 0x45, 0xfb, 0x7e}} ,
+ {{0xda, 0x8c, 0xc2, 0xd0, 0xac, 0x18, 0xe8, 0x52, 0x36, 0xd4, 0x21, 0xa3, 0xdd, 0x57, 0x22, 0x79, 0xb7, 0xf8, 0x71, 0x9d, 0xc6, 0x91, 0x70, 0x86, 0x56, 0xbf, 0xa1, 0x11, 0x8b, 0x19, 0xe1, 0x0f}}},
+{{{0x18, 0x32, 0x98, 0x2c, 0x8f, 0x91, 0xae, 0x12, 0xf0, 0x8c, 0xea, 0xf3, 0x3c, 0xb9, 0x5d, 0xe4, 0x69, 0xed, 0xb2, 0x47, 0x18, 0xbd, 0xce, 0x16, 0x52, 0x5c, 0x23, 0xe2, 0xa5, 0x25, 0x52, 0x5d}} ,
+ {{0xb9, 0xb1, 0xe7, 0x5d, 0x4e, 0xbc, 0xee, 0xbb, 0x40, 0x81, 0x77, 0x82, 0x19, 0xab, 0xb5, 0xc6, 0xee, 0xab, 0x5b, 0x6b, 0x63, 0x92, 0x8a, 0x34, 0x8d, 0xcd, 0xee, 0x4f, 0x49, 0xe5, 0xc9, 0x7e}}},
+{{{0x21, 0xac, 0x8b, 0x22, 0xcd, 0xc3, 0x9a, 0xe9, 0x5e, 0x78, 0xbd, 0xde, 0xba, 0xad, 0xab, 0xbf, 0x75, 0x41, 0x09, 0xc5, 0x58, 0xa4, 0x7d, 0x92, 0xb0, 0x7f, 0xf2, 0xa1, 0xd1, 0xc0, 0xb3, 0x6d}} ,
+ {{0x62, 0x4f, 0xd0, 0x75, 0x77, 0xba, 0x76, 0x77, 0xd7, 0xb8, 0xd8, 0x92, 0x6f, 0x98, 0x34, 0x3d, 0xd6, 0x4e, 0x1c, 0x0f, 0xf0, 0x8f, 0x2e, 0xf1, 0xb3, 0xbd, 0xb1, 0xb9, 0xec, 0x99, 0xb4, 0x07}}},
+{{{0x60, 0x57, 0x2e, 0x9a, 0x72, 0x1d, 0x6b, 0x6e, 0x58, 0x33, 0x24, 0x8c, 0x48, 0x39, 0x46, 0x8e, 0x89, 0x6a, 0x88, 0x51, 0x23, 0x62, 0xb5, 0x32, 0x09, 0x36, 0xe3, 0x57, 0xf5, 0x98, 0xde, 0x6f}} ,
+ {{0x8b, 0x2c, 0x00, 0x48, 0x4a, 0xf9, 0x5b, 0x87, 0x69, 0x52, 0xe5, 0x5b, 0xd1, 0xb1, 0xe5, 0x25, 0x25, 0xe0, 0x9c, 0xc2, 0x13, 0x44, 0xe8, 0xb9, 0x0a, 0x70, 0xad, 0xbd, 0x0f, 0x51, 0x94, 0x69}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xa2, 0xdc, 0xab, 0xa9, 0x25, 0x2d, 0xac, 0x5f, 0x03, 0x33, 0x08, 0xe7, 0x7e, 0xfe, 0x95, 0x36, 0x3c, 0x5b, 0x3a, 0xd3, 0x05, 0x82, 0x1c, 0x95, 0x2d, 0xd8, 0x77, 0x7e, 0x02, 0xd9, 0x5b, 0x70}} ,
+ {{0xc2, 0xfe, 0x1b, 0x0c, 0x67, 0xcd, 0xd6, 0xe0, 0x51, 0x8e, 0x2c, 0xe0, 0x79, 0x88, 0xf0, 0xcf, 0x41, 0x4a, 0xad, 0x23, 0xd4, 0x46, 0xca, 0x94, 0xa1, 0xc3, 0xeb, 0x28, 0x06, 0xfa, 0x17, 0x14}}},
+{{{0x7b, 0xaa, 0x70, 0x0a, 0x4b, 0xfb, 0xf5, 0xbf, 0x80, 0xc5, 0xcf, 0x08, 0x7a, 0xdd, 0xa1, 0xf4, 0x9d, 0x54, 0x50, 0x53, 0x23, 0x77, 0x23, 0xf5, 0x34, 0xa5, 0x22, 0xd1, 0x0d, 0x96, 0x2e, 0x47}} ,
+ {{0xcc, 0xb7, 0x32, 0x89, 0x57, 0xd0, 0x98, 0x75, 0xe4, 0x37, 0x99, 0xa9, 0xe8, 0xba, 0xed, 0xba, 0xeb, 0xc7, 0x4f, 0x15, 0x76, 0x07, 0x0c, 0x4c, 0xef, 0x9f, 0x52, 0xfc, 0x04, 0x5d, 0x58, 0x10}}},
+{{{0xce, 0x82, 0xf0, 0x8f, 0x79, 0x02, 0xa8, 0xd1, 0xda, 0x14, 0x09, 0x48, 0xee, 0x8a, 0x40, 0x98, 0x76, 0x60, 0x54, 0x5a, 0xde, 0x03, 0x24, 0xf5, 0xe6, 0x2f, 0xe1, 0x03, 0xbf, 0x68, 0x82, 0x7f}} ,
+ {{0x64, 0xe9, 0x28, 0xc7, 0xa4, 0xcf, 0x2a, 0xf9, 0x90, 0x64, 0x72, 0x2c, 0x8b, 0xeb, 0xec, 0xa0, 0xf2, 0x7d, 0x35, 0xb5, 0x90, 0x4d, 0x7f, 0x5b, 0x4a, 0x49, 0xe4, 0xb8, 0x3b, 0xc8, 0xa1, 0x2f}}},
+{{{0x8b, 0xc5, 0xcc, 0x3d, 0x69, 0xa6, 0xa1, 0x18, 0x44, 0xbc, 0x4d, 0x77, 0x37, 0xc7, 0x86, 0xec, 0x0c, 0xc9, 0xd6, 0x44, 0xa9, 0x23, 0x27, 0xb9, 0x03, 0x34, 0xa7, 0x0a, 0xd5, 0xc7, 0x34, 0x37}} ,
+ {{0xf9, 0x7e, 0x3e, 0x66, 0xee, 0xf9, 0x99, 0x28, 0xff, 0xad, 0x11, 0xd8, 0xe2, 0x66, 0xc5, 0xcd, 0x0f, 0x0d, 0x0b, 0x6a, 0xfc, 0x7c, 0x24, 0xa8, 0x4f, 0xa8, 0x5e, 0x80, 0x45, 0x8b, 0x6c, 0x41}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xef, 0x1e, 0xec, 0xf7, 0x8d, 0x77, 0xf2, 0xea, 0xdb, 0x60, 0x03, 0x21, 0xc0, 0xff, 0x5e, 0x67, 0xc3, 0x71, 0x0b, 0x21, 0xb4, 0x41, 0xa0, 0x68, 0x38, 0xc6, 0x01, 0xa3, 0xd3, 0x51, 0x3c, 0x3c}} ,
+ {{0x92, 0xf8, 0xd6, 0x4b, 0xef, 0x42, 0x13, 0xb2, 0x4a, 0xc4, 0x2e, 0x72, 0x3f, 0xc9, 0x11, 0xbd, 0x74, 0x02, 0x0e, 0xf5, 0x13, 0x9d, 0x83, 0x1a, 0x1b, 0xd5, 0x54, 0xde, 0xc4, 0x1e, 0x16, 0x6c}}},
+{{{0x27, 0x52, 0xe4, 0x63, 0xaa, 0x94, 0xe6, 0xc3, 0x28, 0x9c, 0xc6, 0x56, 0xac, 0xfa, 0xb6, 0xbd, 0xe2, 0xcc, 0x76, 0xc6, 0x27, 0x27, 0xa2, 0x8e, 0x78, 0x2b, 0x84, 0x72, 0x10, 0xbd, 0x4e, 0x2a}} ,
+ {{0xea, 0xa7, 0x23, 0xef, 0x04, 0x61, 0x80, 0x50, 0xc9, 0x6e, 0xa5, 0x96, 0xd1, 0xd1, 0xc8, 0xc3, 0x18, 0xd7, 0x2d, 0xfd, 0x26, 0xbd, 0xcb, 0x7b, 0x92, 0x51, 0x0e, 0x4a, 0x65, 0x57, 0xb8, 0x49}}},
+{{{0xab, 0x55, 0x36, 0xc3, 0xec, 0x63, 0x55, 0x11, 0x55, 0xf6, 0xa5, 0xc7, 0x01, 0x5f, 0xfe, 0x79, 0xd8, 0x0a, 0xf7, 0x03, 0xd8, 0x98, 0x99, 0xf5, 0xd0, 0x00, 0x54, 0x6b, 0x66, 0x28, 0xf5, 0x25}} ,
+ {{0x7a, 0x8d, 0xa1, 0x5d, 0x70, 0x5d, 0x51, 0x27, 0xee, 0x30, 0x65, 0x56, 0x95, 0x46, 0xde, 0xbd, 0x03, 0x75, 0xb4, 0x57, 0x59, 0x89, 0xeb, 0x02, 0x9e, 0xcc, 0x89, 0x19, 0xa7, 0xcb, 0x17, 0x67}}},
+{{{0x6a, 0xeb, 0xfc, 0x9a, 0x9a, 0x10, 0xce, 0xdb, 0x3a, 0x1c, 0x3c, 0x6a, 0x9d, 0xea, 0x46, 0xbc, 0x45, 0x49, 0xac, 0xe3, 0x41, 0x12, 0x7c, 0xf0, 0xf7, 0x4f, 0xf9, 0xf7, 0xff, 0x2c, 0x89, 0x04}} ,
+ {{0x30, 0x31, 0x54, 0x1a, 0x46, 0xca, 0xe6, 0xc6, 0xcb, 0xe2, 0xc3, 0xc1, 0x8b, 0x75, 0x81, 0xbe, 0xee, 0xf8, 0xa3, 0x11, 0x1c, 0x25, 0xa3, 0xa7, 0x35, 0x51, 0x55, 0xe2, 0x25, 0xaa, 0xe2, 0x3a}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xb4, 0x48, 0x10, 0x9f, 0x8a, 0x09, 0x76, 0xfa, 0xf0, 0x7a, 0xb0, 0x70, 0xf7, 0x83, 0x80, 0x52, 0x84, 0x2b, 0x26, 0xa2, 0xc4, 0x5d, 0x4f, 0xba, 0xb1, 0xc8, 0x40, 0x0d, 0x78, 0x97, 0xc4, 0x60}} ,
+ {{0xd4, 0xb1, 0x6c, 0x08, 0xc7, 0x40, 0x38, 0x73, 0x5f, 0x0b, 0xf3, 0x76, 0x5d, 0xb2, 0xa5, 0x2f, 0x57, 0x57, 0x07, 0xed, 0x08, 0xa2, 0x6c, 0x4f, 0x08, 0x02, 0xb5, 0x0e, 0xee, 0x44, 0xfa, 0x22}}},
+{{{0x0f, 0x00, 0x3f, 0xa6, 0x04, 0x19, 0x56, 0x65, 0x31, 0x7f, 0x8b, 0xeb, 0x0d, 0xe1, 0x47, 0x89, 0x97, 0x16, 0x53, 0xfa, 0x81, 0xa7, 0xaa, 0xb2, 0xbf, 0x67, 0xeb, 0x72, 0x60, 0x81, 0x0d, 0x48}} ,
+ {{0x7e, 0x13, 0x33, 0xcd, 0xa8, 0x84, 0x56, 0x1e, 0x67, 0xaf, 0x6b, 0x43, 0xac, 0x17, 0xaf, 0x16, 0xc0, 0x52, 0x99, 0x49, 0x5b, 0x87, 0x73, 0x7e, 0xb5, 0x43, 0xda, 0x6b, 0x1d, 0x0f, 0x2d, 0x55}}},
+{{{0xe9, 0x58, 0x1f, 0xff, 0x84, 0x3f, 0x93, 0x1c, 0xcb, 0xe1, 0x30, 0x69, 0xa5, 0x75, 0x19, 0x7e, 0x14, 0x5f, 0xf8, 0xfc, 0x09, 0xdd, 0xa8, 0x78, 0x9d, 0xca, 0x59, 0x8b, 0xd1, 0x30, 0x01, 0x13}} ,
+ {{0xff, 0x76, 0x03, 0xc5, 0x4b, 0x89, 0x99, 0x70, 0x00, 0x59, 0x70, 0x9c, 0xd5, 0xd9, 0x11, 0x89, 0x5a, 0x46, 0xfe, 0xef, 0xdc, 0xd9, 0x55, 0x2b, 0x45, 0xa7, 0xb0, 0x2d, 0xfb, 0x24, 0xc2, 0x29}}},
+{{{0x38, 0x06, 0xf8, 0x0b, 0xac, 0x82, 0xc4, 0x97, 0x2b, 0x90, 0xe0, 0xf7, 0xa8, 0xab, 0x6c, 0x08, 0x80, 0x66, 0x90, 0x46, 0xf7, 0x26, 0x2d, 0xf8, 0xf1, 0xc4, 0x6b, 0x4a, 0x82, 0x98, 0x8e, 0x37}} ,
+ {{0x8e, 0xb4, 0xee, 0xb8, 0xd4, 0x3f, 0xb2, 0x1b, 0xe0, 0x0a, 0x3d, 0x75, 0x34, 0x28, 0xa2, 0x8e, 0xc4, 0x92, 0x7b, 0xfe, 0x60, 0x6e, 0x6d, 0xb8, 0x31, 0x1d, 0x62, 0x0d, 0x78, 0x14, 0x42, 0x11}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x5e, 0xa8, 0xd8, 0x04, 0x9b, 0x73, 0xc9, 0xc9, 0xdc, 0x0d, 0x73, 0xbf, 0x0a, 0x0a, 0x73, 0xff, 0x18, 0x1f, 0x9c, 0x51, 0xaa, 0xc6, 0xf1, 0x83, 0x25, 0xfd, 0xab, 0xa3, 0x11, 0xd3, 0x01, 0x24}} ,
+ {{0x4d, 0xe3, 0x7e, 0x38, 0x62, 0x5e, 0x64, 0xbb, 0x2b, 0x53, 0xb5, 0x03, 0x68, 0xc4, 0xf2, 0x2b, 0x5a, 0x03, 0x32, 0x99, 0x4a, 0x41, 0x9a, 0xe1, 0x1a, 0xae, 0x8c, 0x48, 0xf3, 0x24, 0x32, 0x65}}},
+{{{0xe8, 0xdd, 0xad, 0x3a, 0x8c, 0xea, 0xf4, 0xb3, 0xb2, 0xe5, 0x73, 0xf2, 0xed, 0x8b, 0xbf, 0xed, 0xb1, 0x0c, 0x0c, 0xfb, 0x2b, 0xf1, 0x01, 0x48, 0xe8, 0x26, 0x03, 0x8e, 0x27, 0x4d, 0x96, 0x72}} ,
+ {{0xc8, 0x09, 0x3b, 0x60, 0xc9, 0x26, 0x4d, 0x7c, 0xf2, 0x9c, 0xd4, 0xa1, 0x3b, 0x26, 0xc2, 0x04, 0x33, 0x44, 0x76, 0x3c, 0x02, 0xbb, 0x11, 0x42, 0x0c, 0x22, 0xb7, 0xc6, 0xe1, 0xac, 0xb4, 0x0e}}},
+{{{0x6f, 0x85, 0xe7, 0xef, 0xde, 0x67, 0x30, 0xfc, 0xbf, 0x5a, 0xe0, 0x7b, 0x7a, 0x2a, 0x54, 0x6b, 0x5d, 0x62, 0x85, 0xa1, 0xf8, 0x16, 0x88, 0xec, 0x61, 0xb9, 0x96, 0xb5, 0xef, 0x2d, 0x43, 0x4d}} ,
+ {{0x7c, 0x31, 0x33, 0xcc, 0xe4, 0xcf, 0x6c, 0xff, 0x80, 0x47, 0x77, 0xd1, 0xd8, 0xe9, 0x69, 0x97, 0x98, 0x7f, 0x20, 0x57, 0x1d, 0x1d, 0x4f, 0x08, 0x27, 0xc8, 0x35, 0x57, 0x40, 0xc6, 0x21, 0x0c}}},
+{{{0xd2, 0x8e, 0x9b, 0xfa, 0x42, 0x8e, 0xdf, 0x8f, 0xc7, 0x86, 0xf9, 0xa4, 0xca, 0x70, 0x00, 0x9d, 0x21, 0xbf, 0xec, 0x57, 0x62, 0x30, 0x58, 0x8c, 0x0d, 0x35, 0xdb, 0x5d, 0x8b, 0x6a, 0xa0, 0x5a}} ,
+ {{0xc1, 0x58, 0x7c, 0x0d, 0x20, 0xdd, 0x11, 0x26, 0x5f, 0x89, 0x3b, 0x97, 0x58, 0xf8, 0x8b, 0xe3, 0xdf, 0x32, 0xe2, 0xfc, 0xd8, 0x67, 0xf2, 0xa5, 0x37, 0x1e, 0x6d, 0xec, 0x7c, 0x27, 0x20, 0x79}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xd0, 0xe9, 0xc0, 0xfa, 0x95, 0x45, 0x23, 0x96, 0xf1, 0x2c, 0x79, 0x25, 0x14, 0xce, 0x40, 0x14, 0x44, 0x2c, 0x36, 0x50, 0xd9, 0x63, 0x56, 0xb7, 0x56, 0x3b, 0x9e, 0xa7, 0xef, 0x89, 0xbb, 0x0e}} ,
+ {{0xce, 0x7f, 0xdc, 0x0a, 0xcc, 0x82, 0x1c, 0x0a, 0x78, 0x71, 0xe8, 0x74, 0x8d, 0x01, 0x30, 0x0f, 0xa7, 0x11, 0x4c, 0xdf, 0x38, 0xd7, 0xa7, 0x0d, 0xf8, 0x48, 0x52, 0x00, 0x80, 0x7b, 0x5f, 0x0e}}},
+{{{0x25, 0x83, 0xe6, 0x94, 0x7b, 0x81, 0xb2, 0x91, 0xae, 0x0e, 0x05, 0xc9, 0xa3, 0x68, 0x2d, 0xd9, 0x88, 0x25, 0x19, 0x2a, 0x61, 0x61, 0x21, 0x97, 0x15, 0xa1, 0x35, 0xa5, 0x46, 0xc8, 0xa2, 0x0e}} ,
+ {{0x1b, 0x03, 0x0d, 0x8b, 0x5a, 0x1b, 0x97, 0x4b, 0xf2, 0x16, 0x31, 0x3d, 0x1f, 0x33, 0xa0, 0x50, 0x3a, 0x18, 0xbe, 0x13, 0xa1, 0x76, 0xc1, 0xba, 0x1b, 0xf1, 0x05, 0x7b, 0x33, 0xa8, 0x82, 0x3b}}},
+{{{0xba, 0x36, 0x7b, 0x6d, 0xa9, 0xea, 0x14, 0x12, 0xc5, 0xfa, 0x91, 0x00, 0xba, 0x9b, 0x99, 0xcc, 0x56, 0x02, 0xe9, 0xa0, 0x26, 0x40, 0x66, 0x8c, 0xc4, 0xf8, 0x85, 0x33, 0x68, 0xe7, 0x03, 0x20}} ,
+ {{0x50, 0x5b, 0xff, 0xa9, 0xb2, 0xf1, 0xf1, 0x78, 0xcf, 0x14, 0xa4, 0xa9, 0xfc, 0x09, 0x46, 0x94, 0x54, 0x65, 0x0d, 0x9c, 0x5f, 0x72, 0x21, 0xe2, 0x97, 0xa5, 0x2d, 0x81, 0xce, 0x4a, 0x5f, 0x79}}},
+{{{0x3d, 0x5f, 0x5c, 0xd2, 0xbc, 0x7d, 0x77, 0x0e, 0x2a, 0x6d, 0x22, 0x45, 0x84, 0x06, 0xc4, 0xdd, 0xc6, 0xa6, 0xc6, 0xd7, 0x49, 0xad, 0x6d, 0x87, 0x91, 0x0e, 0x3a, 0x67, 0x1d, 0x2c, 0x1d, 0x56}} ,
+ {{0xfe, 0x7a, 0x74, 0xcf, 0xd4, 0xd2, 0xe5, 0x19, 0xde, 0xd0, 0xdb, 0x70, 0x23, 0x69, 0xe6, 0x6d, 0xec, 0xec, 0xcc, 0x09, 0x33, 0x6a, 0x77, 0xdc, 0x6b, 0x22, 0x76, 0x5d, 0x92, 0x09, 0xac, 0x2d}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x23, 0x15, 0x17, 0xeb, 0xd3, 0xdb, 0x12, 0x5e, 0x01, 0xf0, 0x91, 0xab, 0x2c, 0x41, 0xce, 0xac, 0xed, 0x1b, 0x4b, 0x2d, 0xbc, 0xdb, 0x17, 0x66, 0x89, 0x46, 0xad, 0x4b, 0x1e, 0x6f, 0x0b, 0x14}} ,
+ {{0x11, 0xce, 0xbf, 0xb6, 0x77, 0x2d, 0x48, 0x22, 0x18, 0x4f, 0xa3, 0x5d, 0x4a, 0xb0, 0x70, 0x12, 0x3e, 0x54, 0xd7, 0xd8, 0x0e, 0x2b, 0x27, 0xdc, 0x53, 0xff, 0xca, 0x8c, 0x59, 0xb3, 0x4e, 0x44}}},
+{{{0x07, 0x76, 0x61, 0x0f, 0x66, 0xb2, 0x21, 0x39, 0x7e, 0xc0, 0xec, 0x45, 0x28, 0x82, 0xa1, 0x29, 0x32, 0x44, 0x35, 0x13, 0x5e, 0x61, 0x5e, 0x54, 0xcb, 0x7c, 0xef, 0xf6, 0x41, 0xcf, 0x9f, 0x0a}} ,
+ {{0xdd, 0xf9, 0xda, 0x84, 0xc3, 0xe6, 0x8a, 0x9f, 0x24, 0xd2, 0x96, 0x5d, 0x39, 0x6f, 0x58, 0x8c, 0xc1, 0x56, 0x93, 0xab, 0xb5, 0x79, 0x3b, 0xd2, 0xa8, 0x73, 0x16, 0xed, 0xfa, 0xb4, 0x2f, 0x73}}},
+{{{0x8b, 0xb1, 0x95, 0xe5, 0x92, 0x50, 0x35, 0x11, 0x76, 0xac, 0xf4, 0x4d, 0x24, 0xc3, 0x32, 0xe6, 0xeb, 0xfe, 0x2c, 0x87, 0xc4, 0xf1, 0x56, 0xc4, 0x75, 0x24, 0x7a, 0x56, 0x85, 0x5a, 0x3a, 0x13}} ,
+ {{0x0d, 0x16, 0xac, 0x3c, 0x4a, 0x58, 0x86, 0x3a, 0x46, 0x7f, 0x6c, 0xa3, 0x52, 0x6e, 0x37, 0xe4, 0x96, 0x9c, 0xe9, 0x5c, 0x66, 0x41, 0x67, 0xe4, 0xfb, 0x79, 0x0c, 0x05, 0xf6, 0x64, 0xd5, 0x7c}}},
+{{{0x28, 0xc1, 0xe1, 0x54, 0x73, 0xf2, 0xbf, 0x76, 0x74, 0x19, 0x19, 0x1b, 0xe4, 0xb9, 0xa8, 0x46, 0x65, 0x73, 0xf3, 0x77, 0x9b, 0x29, 0x74, 0x5b, 0xc6, 0x89, 0x6c, 0x2c, 0x7c, 0xf8, 0xb3, 0x0f}} ,
+ {{0xf7, 0xd5, 0xe9, 0x74, 0x5d, 0xb8, 0x25, 0x16, 0xb5, 0x30, 0xbc, 0x84, 0xc5, 0xf0, 0xad, 0xca, 0x12, 0x28, 0xbc, 0x9d, 0xd4, 0xfa, 0x82, 0xe6, 0xe3, 0xbf, 0xa2, 0x15, 0x2c, 0xd4, 0x34, 0x10}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x61, 0xb1, 0x46, 0xba, 0x0e, 0x31, 0xa5, 0x67, 0x6c, 0x7f, 0xd6, 0xd9, 0x27, 0x85, 0x0f, 0x79, 0x14, 0xc8, 0x6c, 0x2f, 0x5f, 0x5b, 0x9c, 0x35, 0x3d, 0x38, 0x86, 0x77, 0x65, 0x55, 0x6a, 0x7b}} ,
+ {{0xd3, 0xb0, 0x3a, 0x66, 0x60, 0x1b, 0x43, 0xf1, 0x26, 0x58, 0x99, 0x09, 0x8f, 0x2d, 0xa3, 0x14, 0x71, 0x85, 0xdb, 0xed, 0xf6, 0x26, 0xd5, 0x61, 0x9a, 0x73, 0xac, 0x0e, 0xea, 0xac, 0xb7, 0x0c}}},
+{{{0x5e, 0xf4, 0xe5, 0x17, 0x0e, 0x10, 0x9f, 0xe7, 0x43, 0x5f, 0x67, 0x5c, 0xac, 0x4b, 0xe5, 0x14, 0x41, 0xd2, 0xbf, 0x48, 0xf5, 0x14, 0xb0, 0x71, 0xc6, 0x61, 0xc1, 0xb2, 0x70, 0x58, 0xd2, 0x5a}} ,
+ {{0x2d, 0xba, 0x16, 0x07, 0x92, 0x94, 0xdc, 0xbd, 0x50, 0x2b, 0xc9, 0x7f, 0x42, 0x00, 0xba, 0x61, 0xed, 0xf8, 0x43, 0xed, 0xf5, 0xf9, 0x40, 0x60, 0xb2, 0xb0, 0x82, 0xcb, 0xed, 0x75, 0xc7, 0x65}}},
+{{{0x80, 0xba, 0x0d, 0x09, 0x40, 0xa7, 0x39, 0xa6, 0x67, 0x34, 0x7e, 0x66, 0xbe, 0x56, 0xfb, 0x53, 0x78, 0xc4, 0x46, 0xe8, 0xed, 0x68, 0x6c, 0x7f, 0xce, 0xe8, 0x9f, 0xce, 0xa2, 0x64, 0x58, 0x53}} ,
+ {{0xe8, 0xc1, 0xa9, 0xc2, 0x7b, 0x59, 0x21, 0x33, 0xe2, 0x43, 0x73, 0x2b, 0xac, 0x2d, 0xc1, 0x89, 0x3b, 0x15, 0xe2, 0xd5, 0xc0, 0x97, 0x8a, 0xfd, 0x6f, 0x36, 0x33, 0xb7, 0xb9, 0xc3, 0x88, 0x09}}},
+{{{0xd0, 0xb6, 0x56, 0x30, 0x5c, 0xae, 0xb3, 0x75, 0x44, 0xa4, 0x83, 0x51, 0x6e, 0x01, 0x65, 0xef, 0x45, 0x76, 0xe6, 0xf5, 0xa2, 0x0d, 0xd4, 0x16, 0x3b, 0x58, 0x2f, 0xf2, 0x2f, 0x36, 0x18, 0x3f}} ,
+ {{0xfd, 0x2f, 0xe0, 0x9b, 0x1e, 0x8c, 0xc5, 0x18, 0xa9, 0xca, 0xd4, 0x2b, 0x35, 0xb6, 0x95, 0x0a, 0x9f, 0x7e, 0xfb, 0xc4, 0xef, 0x88, 0x7b, 0x23, 0x43, 0xec, 0x2f, 0x0d, 0x0f, 0x7a, 0xfc, 0x5c}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x8d, 0xd2, 0xda, 0xc7, 0x44, 0xd6, 0x7a, 0xdb, 0x26, 0x7d, 0x1d, 0xb8, 0xe1, 0xde, 0x9d, 0x7a, 0x7d, 0x17, 0x7e, 0x1c, 0x37, 0x04, 0x8d, 0x2d, 0x7c, 0x5e, 0x18, 0x38, 0x1e, 0xaf, 0xc7, 0x1b}} ,
+ {{0x33, 0x48, 0x31, 0x00, 0x59, 0xf6, 0xf2, 0xca, 0x0f, 0x27, 0x1b, 0x63, 0x12, 0x7e, 0x02, 0x1d, 0x49, 0xc0, 0x5d, 0x79, 0x87, 0xef, 0x5e, 0x7a, 0x2f, 0x1f, 0x66, 0x55, 0xd8, 0x09, 0xd9, 0x61}}},
+{{{0x54, 0x83, 0x02, 0x18, 0x82, 0x93, 0x99, 0x07, 0xd0, 0xa7, 0xda, 0xd8, 0x75, 0x89, 0xfa, 0xf2, 0xd9, 0xa3, 0xb8, 0x6b, 0x5a, 0x35, 0x28, 0xd2, 0x6b, 0x59, 0xc2, 0xf8, 0x45, 0xe2, 0xbc, 0x06}} ,
+ {{0x65, 0xc0, 0xa3, 0x88, 0x51, 0x95, 0xfc, 0x96, 0x94, 0x78, 0xe8, 0x0d, 0x8b, 0x41, 0xc9, 0xc2, 0x58, 0x48, 0x75, 0x10, 0x2f, 0xcd, 0x2a, 0xc9, 0xa0, 0x6d, 0x0f, 0xdd, 0x9c, 0x98, 0x26, 0x3d}}},
+{{{0x2f, 0x66, 0x29, 0x1b, 0x04, 0x89, 0xbd, 0x7e, 0xee, 0x6e, 0xdd, 0xb7, 0x0e, 0xef, 0xb0, 0x0c, 0xb4, 0xfc, 0x7f, 0xc2, 0xc9, 0x3a, 0x3c, 0x64, 0xef, 0x45, 0x44, 0xaf, 0x8a, 0x90, 0x65, 0x76}} ,
+ {{0xa1, 0x4c, 0x70, 0x4b, 0x0e, 0xa0, 0x83, 0x70, 0x13, 0xa4, 0xaf, 0xb8, 0x38, 0x19, 0x22, 0x65, 0x09, 0xb4, 0x02, 0x4f, 0x06, 0xf8, 0x17, 0xce, 0x46, 0x45, 0xda, 0x50, 0x7c, 0x8a, 0xd1, 0x4e}}},
+{{{0xf7, 0xd4, 0x16, 0x6c, 0x4e, 0x95, 0x9d, 0x5d, 0x0f, 0x91, 0x2b, 0x52, 0xfe, 0x5c, 0x34, 0xe5, 0x30, 0xe6, 0xa4, 0x3b, 0xf3, 0xf3, 0x34, 0x08, 0xa9, 0x4a, 0xa0, 0xb5, 0x6e, 0xb3, 0x09, 0x0a}} ,
+ {{0x26, 0xd9, 0x5e, 0xa3, 0x0f, 0xeb, 0xa2, 0xf3, 0x20, 0x3b, 0x37, 0xd4, 0xe4, 0x9e, 0xce, 0x06, 0x3d, 0x53, 0xed, 0xae, 0x2b, 0xeb, 0xb6, 0x24, 0x0a, 0x11, 0xa3, 0x0f, 0xd6, 0x7f, 0xa4, 0x3a}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xdb, 0x9f, 0x2c, 0xfc, 0xd6, 0xb2, 0x1e, 0x2e, 0x52, 0x7a, 0x06, 0x87, 0x2d, 0x86, 0x72, 0x2b, 0x6d, 0x90, 0x77, 0x46, 0x43, 0xb5, 0x7a, 0xf8, 0x60, 0x7d, 0x91, 0x60, 0x5b, 0x9d, 0x9e, 0x07}} ,
+ {{0x97, 0x87, 0xc7, 0x04, 0x1c, 0x38, 0x01, 0x39, 0x58, 0xc7, 0x85, 0xa3, 0xfc, 0x64, 0x00, 0x64, 0x25, 0xa2, 0xbf, 0x50, 0x94, 0xca, 0x26, 0x31, 0x45, 0x0a, 0x24, 0xd2, 0x51, 0x29, 0x51, 0x16}}},
+{{{0x4d, 0x4a, 0xd7, 0x98, 0x71, 0x57, 0xac, 0x7d, 0x8b, 0x37, 0xbd, 0x63, 0xff, 0x87, 0xb1, 0x49, 0x95, 0x20, 0x7c, 0xcf, 0x7c, 0x59, 0xc4, 0x91, 0x9c, 0xef, 0xd0, 0xdb, 0x60, 0x09, 0x9d, 0x46}} ,
+ {{0xcb, 0x78, 0x94, 0x90, 0xe4, 0x45, 0xb3, 0xf6, 0xd9, 0xf6, 0x57, 0x74, 0xd5, 0xf8, 0x83, 0x4f, 0x39, 0xc9, 0xbd, 0x88, 0xc2, 0x57, 0x21, 0x1f, 0x24, 0x32, 0x68, 0xf8, 0xc7, 0x21, 0x5f, 0x0b}}},
+{{{0x2a, 0x36, 0x68, 0xfc, 0x5f, 0xb6, 0x4f, 0xa5, 0xe3, 0x9d, 0x24, 0x2f, 0xc0, 0x93, 0x61, 0xcf, 0xf8, 0x0a, 0xed, 0xe1, 0xdb, 0x27, 0xec, 0x0e, 0x14, 0x32, 0x5f, 0x8e, 0xa1, 0x62, 0x41, 0x16}} ,
+ {{0x95, 0x21, 0x01, 0xce, 0x95, 0x5b, 0x0e, 0x57, 0xc7, 0xb9, 0x62, 0xb5, 0x28, 0xca, 0x11, 0xec, 0xb4, 0x46, 0x06, 0x73, 0x26, 0xff, 0xfb, 0x66, 0x7d, 0xee, 0x5f, 0xb2, 0x56, 0xfd, 0x2a, 0x08}}},
+{{{0x92, 0x67, 0x77, 0x56, 0xa1, 0xff, 0xc4, 0xc5, 0x95, 0xf0, 0xe3, 0x3a, 0x0a, 0xca, 0x94, 0x4d, 0x9e, 0x7e, 0x3d, 0xb9, 0x6e, 0xb6, 0xb0, 0xce, 0xa4, 0x30, 0x89, 0x99, 0xe9, 0xad, 0x11, 0x59}} ,
+ {{0xf6, 0x48, 0x95, 0xa1, 0x6f, 0x5f, 0xb7, 0xa5, 0xbb, 0x30, 0x00, 0x1c, 0xd2, 0x8a, 0xd6, 0x25, 0x26, 0x1b, 0xb2, 0x0d, 0x37, 0x6a, 0x05, 0xf4, 0x9d, 0x3e, 0x17, 0x2a, 0x43, 0xd2, 0x3a, 0x06}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x32, 0x99, 0x93, 0xd1, 0x9a, 0x72, 0xf3, 0xa9, 0x16, 0xbd, 0xb4, 0x4c, 0xdd, 0xf9, 0xd4, 0xb2, 0x64, 0x9a, 0xd3, 0x05, 0xe4, 0xa3, 0x73, 0x1c, 0xcb, 0x7e, 0x57, 0x67, 0xff, 0x04, 0xb3, 0x10}} ,
+ {{0xb9, 0x4b, 0xa4, 0xad, 0xd0, 0x6d, 0x61, 0x23, 0xb4, 0xaf, 0x34, 0xa9, 0xaa, 0x65, 0xec, 0xd9, 0x69, 0xe3, 0x85, 0xcd, 0xcc, 0xe7, 0xb0, 0x9b, 0x41, 0xc1, 0x1c, 0xf9, 0xa0, 0xfa, 0xb7, 0x13}}},
+{{{0x04, 0xfd, 0x88, 0x3c, 0x0c, 0xd0, 0x09, 0x52, 0x51, 0x4f, 0x06, 0x19, 0xcc, 0xc3, 0xbb, 0xde, 0x80, 0xc5, 0x33, 0xbc, 0xf9, 0xf3, 0x17, 0x36, 0xdd, 0xc6, 0xde, 0xe8, 0x9b, 0x5d, 0x79, 0x1b}} ,
+ {{0x65, 0x0a, 0xbe, 0x51, 0x57, 0xad, 0x50, 0x79, 0x08, 0x71, 0x9b, 0x07, 0x95, 0x8f, 0xfb, 0xae, 0x4b, 0x38, 0xba, 0xcf, 0x53, 0x2a, 0x86, 0x1e, 0xc0, 0x50, 0x5c, 0x67, 0x1b, 0xf6, 0x87, 0x6c}}},
+{{{0x4f, 0x00, 0xb2, 0x66, 0x55, 0xed, 0x4a, 0xed, 0x8d, 0xe1, 0x66, 0x18, 0xb2, 0x14, 0x74, 0x8d, 0xfd, 0x1a, 0x36, 0x0f, 0x26, 0x5c, 0x8b, 0x89, 0xf3, 0xab, 0xf2, 0xf3, 0x24, 0x67, 0xfd, 0x70}} ,
+ {{0xfd, 0x4e, 0x2a, 0xc1, 0x3a, 0xca, 0x8f, 0x00, 0xd8, 0xec, 0x74, 0x67, 0xef, 0x61, 0xe0, 0x28, 0xd0, 0x96, 0xf4, 0x48, 0xde, 0x81, 0xe3, 0xef, 0xdc, 0xaa, 0x7d, 0xf3, 0xb6, 0x55, 0xa6, 0x65}}},
+{{{0xeb, 0xcb, 0xc5, 0x70, 0x91, 0x31, 0x10, 0x93, 0x0d, 0xc8, 0xd0, 0xef, 0x62, 0xe8, 0x6f, 0x82, 0xe3, 0x69, 0x3d, 0x91, 0x7f, 0x31, 0xe1, 0x26, 0x35, 0x3c, 0x4a, 0x2f, 0xab, 0xc4, 0x9a, 0x5e}} ,
+ {{0xab, 0x1b, 0xb5, 0xe5, 0x2b, 0xc3, 0x0e, 0x29, 0xb0, 0xd0, 0x73, 0xe6, 0x4f, 0x64, 0xf2, 0xbc, 0xe4, 0xe4, 0xe1, 0x9a, 0x52, 0x33, 0x2f, 0xbd, 0xcc, 0x03, 0xee, 0x8a, 0xfa, 0x00, 0x5f, 0x50}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xf6, 0xdb, 0x0d, 0x22, 0x3d, 0xb5, 0x14, 0x75, 0x31, 0xf0, 0x81, 0xe2, 0xb9, 0x37, 0xa2, 0xa9, 0x84, 0x11, 0x9a, 0x07, 0xb5, 0x53, 0x89, 0x78, 0xa9, 0x30, 0x27, 0xa1, 0xf1, 0x4e, 0x5c, 0x2e}} ,
+ {{0x8b, 0x00, 0x54, 0xfb, 0x4d, 0xdc, 0xcb, 0x17, 0x35, 0x40, 0xff, 0xb7, 0x8c, 0xfe, 0x4a, 0xe4, 0x4e, 0x99, 0x4e, 0xa8, 0x74, 0x54, 0x5d, 0x5c, 0x96, 0xa3, 0x12, 0x55, 0x36, 0x31, 0x17, 0x5c}}},
+{{{0xce, 0x24, 0xef, 0x7b, 0x86, 0xf2, 0x0f, 0x77, 0xe8, 0x5c, 0x7d, 0x87, 0x38, 0x2d, 0xef, 0xaf, 0xf2, 0x8c, 0x72, 0x2e, 0xeb, 0xb6, 0x55, 0x4b, 0x6e, 0xf1, 0x4e, 0x8a, 0x0e, 0x9a, 0x6c, 0x4c}} ,
+ {{0x25, 0xea, 0x86, 0xc2, 0xd1, 0x4f, 0xb7, 0x3e, 0xa8, 0x5c, 0x8d, 0x66, 0x81, 0x25, 0xed, 0xc5, 0x4c, 0x05, 0xb9, 0xd8, 0xd6, 0x70, 0xbe, 0x73, 0x82, 0xe8, 0xa1, 0xe5, 0x1e, 0x71, 0xd5, 0x26}}},
+{{{0x4e, 0x6d, 0xc3, 0xa7, 0x4f, 0x22, 0x45, 0x26, 0xa2, 0x7e, 0x16, 0xf7, 0xf7, 0x63, 0xdc, 0x86, 0x01, 0x2a, 0x71, 0x38, 0x5c, 0x33, 0xc3, 0xce, 0x30, 0xff, 0xf9, 0x2c, 0x91, 0x71, 0x8a, 0x72}} ,
+ {{0x8c, 0x44, 0x09, 0x28, 0xd5, 0x23, 0xc9, 0x8f, 0xf3, 0x84, 0x45, 0xc6, 0x9a, 0x5e, 0xff, 0xd2, 0xc7, 0x57, 0x93, 0xa3, 0xc1, 0x69, 0xdd, 0x62, 0x0f, 0xda, 0x5c, 0x30, 0x59, 0x5d, 0xe9, 0x4c}}},
+{{{0x92, 0x7e, 0x50, 0x27, 0x72, 0xd7, 0x0c, 0xd6, 0x69, 0x96, 0x81, 0x35, 0x84, 0x94, 0x35, 0x8b, 0x6c, 0xaa, 0x62, 0x86, 0x6e, 0x1c, 0x15, 0xf3, 0x6c, 0xb3, 0xff, 0x65, 0x1b, 0xa2, 0x9b, 0x59}} ,
+ {{0xe2, 0xa9, 0x65, 0x88, 0xc4, 0x50, 0xfa, 0xbb, 0x3b, 0x6e, 0x5f, 0x44, 0x01, 0xca, 0x97, 0xd4, 0xdd, 0xf6, 0xcd, 0x3f, 0x3f, 0xe5, 0x97, 0x67, 0x2b, 0x8c, 0x66, 0x0f, 0x35, 0x9b, 0xf5, 0x07}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xf1, 0x59, 0x27, 0xd8, 0xdb, 0x5a, 0x11, 0x5e, 0x82, 0xf3, 0x38, 0xff, 0x1c, 0xed, 0xfe, 0x3f, 0x64, 0x54, 0x3f, 0x7f, 0xd1, 0x81, 0xed, 0xef, 0x65, 0xc5, 0xcb, 0xfd, 0xe1, 0x80, 0xcd, 0x11}} ,
+ {{0xe0, 0xdb, 0x22, 0x28, 0xe6, 0xff, 0x61, 0x9d, 0x41, 0x14, 0x2d, 0x3b, 0x26, 0x22, 0xdf, 0xf1, 0x34, 0x81, 0xe9, 0x45, 0xee, 0x0f, 0x98, 0x8b, 0xa6, 0x3f, 0xef, 0xf7, 0x43, 0x19, 0xf1, 0x43}}},
+{{{0xee, 0xf3, 0x00, 0xa1, 0x50, 0xde, 0xc0, 0xb6, 0x01, 0xe3, 0x8c, 0x3c, 0x4d, 0x31, 0xd2, 0xb0, 0x58, 0xcd, 0xed, 0x10, 0x4a, 0x7a, 0xef, 0x80, 0xa9, 0x19, 0x32, 0xf3, 0xd8, 0x33, 0x8c, 0x06}} ,
+ {{0xcb, 0x7d, 0x4f, 0xff, 0x30, 0xd8, 0x12, 0x3b, 0x39, 0x1c, 0x06, 0xf9, 0x4c, 0x34, 0x35, 0x71, 0xb5, 0x16, 0x94, 0x67, 0xdf, 0xee, 0x11, 0xde, 0xa4, 0x1d, 0x88, 0x93, 0x35, 0xa9, 0x32, 0x10}}},
+{{{0xe9, 0xc3, 0xbc, 0x7b, 0x5c, 0xfc, 0xb2, 0xf9, 0xc9, 0x2f, 0xe5, 0xba, 0x3a, 0x0b, 0xab, 0x64, 0x38, 0x6f, 0x5b, 0x4b, 0x93, 0xda, 0x64, 0xec, 0x4d, 0x3d, 0xa0, 0xf5, 0xbb, 0xba, 0x47, 0x48}} ,
+ {{0x60, 0xbc, 0x45, 0x1f, 0x23, 0xa2, 0x3b, 0x70, 0x76, 0xe6, 0x97, 0x99, 0x4f, 0x77, 0x54, 0x67, 0x30, 0x9a, 0xe7, 0x66, 0xd6, 0xcd, 0x2e, 0x51, 0x24, 0x2c, 0x42, 0x4a, 0x11, 0xfe, 0x6f, 0x7e}}},
+{{{0x87, 0xc0, 0xb1, 0xf0, 0xa3, 0x6f, 0x0c, 0x93, 0xa9, 0x0a, 0x72, 0xef, 0x5c, 0xbe, 0x65, 0x35, 0xa7, 0x6a, 0x4e, 0x2c, 0xbf, 0x21, 0x23, 0xe8, 0x2f, 0x97, 0xc7, 0x3e, 0xc8, 0x17, 0xac, 0x1e}} ,
+ {{0x7b, 0xef, 0x21, 0xe5, 0x40, 0xcc, 0x1e, 0xdc, 0xd6, 0xbd, 0x97, 0x7a, 0x7c, 0x75, 0x86, 0x7a, 0x25, 0x5a, 0x6e, 0x7c, 0xe5, 0x51, 0x3c, 0x1b, 0x5b, 0x82, 0x9a, 0x07, 0x60, 0xa1, 0x19, 0x04}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x96, 0x88, 0xa6, 0xab, 0x8f, 0xe3, 0x3a, 0x49, 0xf8, 0xfe, 0x34, 0xe7, 0x6a, 0xb2, 0xfe, 0x40, 0x26, 0x74, 0x57, 0x4c, 0xf6, 0xd4, 0x99, 0xce, 0x5d, 0x7b, 0x2f, 0x67, 0xd6, 0x5a, 0xe4, 0x4e}} ,
+ {{0x5c, 0x82, 0xb3, 0xbd, 0x55, 0x25, 0xf6, 0x6a, 0x93, 0xa4, 0x02, 0xc6, 0x7d, 0x5c, 0xb1, 0x2b, 0x5b, 0xff, 0xfb, 0x56, 0xf8, 0x01, 0x41, 0x90, 0xc6, 0xb6, 0xac, 0x4f, 0xfe, 0xa7, 0x41, 0x70}}},
+{{{0xdb, 0xfa, 0x9b, 0x2c, 0xd4, 0x23, 0x67, 0x2c, 0x8a, 0x63, 0x6c, 0x07, 0x26, 0x48, 0x4f, 0xc2, 0x03, 0xd2, 0x53, 0x20, 0x28, 0xed, 0x65, 0x71, 0x47, 0xa9, 0x16, 0x16, 0x12, 0xbc, 0x28, 0x33}} ,
+ {{0x39, 0xc0, 0xfa, 0xfa, 0xcd, 0x33, 0x43, 0xc7, 0x97, 0x76, 0x9b, 0x93, 0x91, 0x72, 0xeb, 0xc5, 0x18, 0x67, 0x4c, 0x11, 0xf0, 0xf4, 0xe5, 0x73, 0xb2, 0x5c, 0x1b, 0xc2, 0x26, 0x3f, 0xbf, 0x2b}}},
+{{{0x86, 0xe6, 0x8c, 0x1d, 0xdf, 0xca, 0xfc, 0xd5, 0xf8, 0x3a, 0xc3, 0x44, 0x72, 0xe6, 0x78, 0x9d, 0x2b, 0x97, 0xf8, 0x28, 0x45, 0xb4, 0x20, 0xc9, 0x2a, 0x8c, 0x67, 0xaa, 0x11, 0xc5, 0x5b, 0x2f}} ,
+ {{0x17, 0x0f, 0x86, 0x52, 0xd7, 0x9d, 0xc3, 0x44, 0x51, 0x76, 0x32, 0x65, 0xb4, 0x37, 0x81, 0x99, 0x46, 0x37, 0x62, 0xed, 0xcf, 0x64, 0x9d, 0x72, 0x40, 0x7a, 0x4c, 0x0b, 0x76, 0x2a, 0xfb, 0x56}}},
+{{{0x33, 0xa7, 0x90, 0x7c, 0xc3, 0x6f, 0x17, 0xa5, 0xa0, 0x67, 0x72, 0x17, 0xea, 0x7e, 0x63, 0x14, 0x83, 0xde, 0xc1, 0x71, 0x2d, 0x41, 0x32, 0x7a, 0xf3, 0xd1, 0x2b, 0xd8, 0x2a, 0xa6, 0x46, 0x36}} ,
+ {{0xac, 0xcc, 0x6b, 0x7c, 0xf9, 0xb8, 0x8b, 0x08, 0x5c, 0xd0, 0x7d, 0x8f, 0x73, 0xea, 0x20, 0xda, 0x86, 0xca, 0x00, 0xc7, 0xad, 0x73, 0x4d, 0xe9, 0xe8, 0xa9, 0xda, 0x1f, 0x03, 0x06, 0xdd, 0x24}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x9c, 0xb2, 0x61, 0x0a, 0x98, 0x2a, 0xa5, 0xd7, 0xee, 0xa9, 0xac, 0x65, 0xcb, 0x0a, 0x1e, 0xe2, 0xbe, 0xdc, 0x85, 0x59, 0x0f, 0x9c, 0xa6, 0x57, 0x34, 0xa5, 0x87, 0xeb, 0x7b, 0x1e, 0x0c, 0x3c}} ,
+ {{0x2f, 0xbd, 0x84, 0x63, 0x0d, 0xb5, 0xa0, 0xf0, 0x4b, 0x9e, 0x93, 0xc6, 0x34, 0x9a, 0x34, 0xff, 0x73, 0x19, 0x2f, 0x6e, 0x54, 0x45, 0x2c, 0x92, 0x31, 0x76, 0x34, 0xf1, 0xb2, 0x26, 0xe8, 0x74}}},
+{{{0x0a, 0x67, 0x90, 0x6d, 0x0c, 0x4c, 0xcc, 0xc0, 0xe6, 0xbd, 0xa7, 0x5e, 0x55, 0x8c, 0xcd, 0x58, 0x9b, 0x11, 0xa2, 0xbb, 0x4b, 0xb1, 0x43, 0x04, 0x3c, 0x55, 0xed, 0x23, 0xfe, 0xcd, 0xb1, 0x53}} ,
+ {{0x05, 0xfb, 0x75, 0xf5, 0x01, 0xaf, 0x38, 0x72, 0x58, 0xfc, 0x04, 0x29, 0x34, 0x7a, 0x67, 0xa2, 0x08, 0x50, 0x6e, 0xd0, 0x2b, 0x73, 0xd5, 0xb8, 0xe4, 0x30, 0x96, 0xad, 0x45, 0xdf, 0xa6, 0x5c}}},
+{{{0x0d, 0x88, 0x1a, 0x90, 0x7e, 0xdc, 0xd8, 0xfe, 0xc1, 0x2f, 0x5d, 0x67, 0xee, 0x67, 0x2f, 0xed, 0x6f, 0x55, 0x43, 0x5f, 0x87, 0x14, 0x35, 0x42, 0xd3, 0x75, 0xae, 0xd5, 0xd3, 0x85, 0x1a, 0x76}} ,
+ {{0x87, 0xc8, 0xa0, 0x6e, 0xe1, 0xb0, 0xad, 0x6a, 0x4a, 0x34, 0x71, 0xed, 0x7c, 0xd6, 0x44, 0x03, 0x65, 0x4a, 0x5c, 0x5c, 0x04, 0xf5, 0x24, 0x3f, 0xb0, 0x16, 0x5e, 0x8c, 0xb2, 0xd2, 0xc5, 0x20}}},
+{{{0x98, 0x83, 0xc2, 0x37, 0xa0, 0x41, 0xa8, 0x48, 0x5c, 0x5f, 0xbf, 0xc8, 0xfa, 0x24, 0xe0, 0x59, 0x2c, 0xbd, 0xf6, 0x81, 0x7e, 0x88, 0xe6, 0xca, 0x04, 0xd8, 0x5d, 0x60, 0xbb, 0x74, 0xa7, 0x0b}} ,
+ {{0x21, 0x13, 0x91, 0xbf, 0x77, 0x7a, 0x33, 0xbc, 0xe9, 0x07, 0x39, 0x0a, 0xdd, 0x7d, 0x06, 0x10, 0x9a, 0xee, 0x47, 0x73, 0x1b, 0x15, 0x5a, 0xfb, 0xcd, 0x4d, 0xd0, 0xd2, 0x3a, 0x01, 0xba, 0x54}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x48, 0xd5, 0x39, 0x4a, 0x0b, 0x20, 0x6a, 0x43, 0xa0, 0x07, 0x82, 0x5e, 0x49, 0x7c, 0xc9, 0x47, 0xf1, 0x7c, 0x37, 0xb9, 0x23, 0xef, 0x6b, 0x46, 0x45, 0x8c, 0x45, 0x76, 0xdf, 0x14, 0x6b, 0x6e}} ,
+ {{0x42, 0xc9, 0xca, 0x29, 0x4c, 0x76, 0x37, 0xda, 0x8a, 0x2d, 0x7c, 0x3a, 0x58, 0xf2, 0x03, 0xb4, 0xb5, 0xb9, 0x1a, 0x13, 0x2d, 0xde, 0x5f, 0x6b, 0x9d, 0xba, 0x52, 0xc9, 0x5d, 0xb3, 0xf3, 0x30}}},
+{{{0x4c, 0x6f, 0xfe, 0x6b, 0x0c, 0x62, 0xd7, 0x48, 0x71, 0xef, 0xb1, 0x85, 0x79, 0xc0, 0xed, 0x24, 0xb1, 0x08, 0x93, 0x76, 0x8e, 0xf7, 0x38, 0x8e, 0xeb, 0xfe, 0x80, 0x40, 0xaf, 0x90, 0x64, 0x49}} ,
+ {{0x4a, 0x88, 0xda, 0xc1, 0x98, 0x44, 0x3c, 0x53, 0x4e, 0xdb, 0x4b, 0xb9, 0x12, 0x5f, 0xcd, 0x08, 0x04, 0xef, 0x75, 0xe7, 0xb1, 0x3a, 0xe5, 0x07, 0xfa, 0xca, 0x65, 0x7b, 0x72, 0x10, 0x64, 0x7f}}},
+{{{0x3d, 0x81, 0xf0, 0xeb, 0x16, 0xfd, 0x58, 0x33, 0x8d, 0x7c, 0x1a, 0xfb, 0x20, 0x2c, 0x8a, 0xee, 0x90, 0xbb, 0x33, 0x6d, 0x45, 0xe9, 0x8e, 0x99, 0x85, 0xe1, 0x08, 0x1f, 0xc5, 0xf1, 0xb5, 0x46}} ,
+ {{0xe4, 0xe7, 0x43, 0x4b, 0xa0, 0x3f, 0x2b, 0x06, 0xba, 0x17, 0xae, 0x3d, 0xe6, 0xce, 0xbd, 0xb8, 0xed, 0x74, 0x11, 0x35, 0xec, 0x96, 0xfe, 0x31, 0xe3, 0x0e, 0x7a, 0x4e, 0xc9, 0x1d, 0xcb, 0x20}}},
+{{{0xe0, 0x67, 0xe9, 0x7b, 0xdb, 0x96, 0x5c, 0xb0, 0x32, 0xd0, 0x59, 0x31, 0x90, 0xdc, 0x92, 0x97, 0xac, 0x09, 0x38, 0x31, 0x0f, 0x7e, 0xd6, 0x5d, 0xd0, 0x06, 0xb6, 0x1f, 0xea, 0xf0, 0x5b, 0x07}} ,
+ {{0x81, 0x9f, 0xc7, 0xde, 0x6b, 0x41, 0x22, 0x35, 0x14, 0x67, 0x77, 0x3e, 0x90, 0x81, 0xb0, 0xd9, 0x85, 0x4c, 0xca, 0x9b, 0x3f, 0x04, 0x59, 0xd6, 0xaa, 0x17, 0xc3, 0x88, 0x34, 0x37, 0xba, 0x43}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x4c, 0xb6, 0x69, 0xc8, 0x81, 0x95, 0x94, 0x33, 0x92, 0x34, 0xe9, 0x3c, 0x84, 0x0d, 0x3d, 0x5a, 0x37, 0x9c, 0x22, 0xa0, 0xaa, 0x65, 0xce, 0xb4, 0xc2, 0x2d, 0x66, 0x67, 0x02, 0xff, 0x74, 0x10}} ,
+ {{0x22, 0xb0, 0xd5, 0xe6, 0xc7, 0xef, 0xb1, 0xa7, 0x13, 0xda, 0x60, 0xb4, 0x80, 0xc1, 0x42, 0x7d, 0x10, 0x70, 0x97, 0x04, 0x4d, 0xda, 0x23, 0x89, 0xc2, 0x0e, 0x68, 0xcb, 0xde, 0xe0, 0x9b, 0x29}}},
+{{{0x33, 0xfe, 0x42, 0x2a, 0x36, 0x2b, 0x2e, 0x36, 0x64, 0x5c, 0x8b, 0xcc, 0x81, 0x6a, 0x15, 0x08, 0xa1, 0x27, 0xe8, 0x57, 0xe5, 0x78, 0x8e, 0xf2, 0x58, 0x19, 0x12, 0x42, 0xae, 0xc4, 0x63, 0x3e}} ,
+ {{0x78, 0x96, 0x9c, 0xa7, 0xca, 0x80, 0xae, 0x02, 0x85, 0xb1, 0x7c, 0x04, 0x5c, 0xc1, 0x5b, 0x26, 0xc1, 0xba, 0xed, 0xa5, 0x59, 0x70, 0x85, 0x8c, 0x8c, 0xe8, 0x87, 0xac, 0x6a, 0x28, 0x99, 0x35}}},
+{{{0x9f, 0x04, 0x08, 0x28, 0xbe, 0x87, 0xda, 0x80, 0x28, 0x38, 0xde, 0x9f, 0xcd, 0xe4, 0xe3, 0x62, 0xfb, 0x2e, 0x46, 0x8d, 0x01, 0xb3, 0x06, 0x51, 0xd4, 0x19, 0x3b, 0x11, 0xfa, 0xe2, 0xad, 0x1e}} ,
+ {{0xa0, 0x20, 0x99, 0x69, 0x0a, 0xae, 0xa3, 0x70, 0x4e, 0x64, 0x80, 0xb7, 0x85, 0x9c, 0x87, 0x54, 0x43, 0x43, 0x55, 0x80, 0x6d, 0x8d, 0x7c, 0xa9, 0x64, 0xca, 0x6c, 0x2e, 0x21, 0xd8, 0xc8, 0x6c}}},
+{{{0x91, 0x4a, 0x07, 0xad, 0x08, 0x75, 0xc1, 0x4f, 0xa4, 0xb2, 0xc3, 0x6f, 0x46, 0x3e, 0xb1, 0xce, 0x52, 0xab, 0x67, 0x09, 0x54, 0x48, 0x6b, 0x6c, 0xd7, 0x1d, 0x71, 0x76, 0xcb, 0xff, 0xdd, 0x31}} ,
+ {{0x36, 0x88, 0xfa, 0xfd, 0xf0, 0x36, 0x6f, 0x07, 0x74, 0x88, 0x50, 0xd0, 0x95, 0x38, 0x4a, 0x48, 0x2e, 0x07, 0x64, 0x97, 0x11, 0x76, 0x01, 0x1a, 0x27, 0x4d, 0x8e, 0x25, 0x9a, 0x9b, 0x1c, 0x22}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xbe, 0x57, 0xbd, 0x0e, 0x0f, 0xac, 0x5e, 0x76, 0xa3, 0x71, 0xad, 0x2b, 0x10, 0x45, 0x02, 0xec, 0x59, 0xd5, 0x5d, 0xa9, 0x44, 0xcc, 0x25, 0x4c, 0xb3, 0x3c, 0x5b, 0x69, 0x07, 0x55, 0x26, 0x6b}} ,
+ {{0x30, 0x6b, 0xd4, 0xa7, 0x51, 0x29, 0xe3, 0xf9, 0x7a, 0x75, 0x2a, 0x82, 0x2f, 0xd6, 0x1d, 0x99, 0x2b, 0x80, 0xd5, 0x67, 0x1e, 0x15, 0x9d, 0xca, 0xfd, 0xeb, 0xac, 0x97, 0x35, 0x09, 0x7f, 0x3f}}},
+{{{0x35, 0x0d, 0x34, 0x0a, 0xb8, 0x67, 0x56, 0x29, 0x20, 0xf3, 0x19, 0x5f, 0xe2, 0x83, 0x42, 0x73, 0x53, 0xa8, 0xc5, 0x02, 0x19, 0x33, 0xb4, 0x64, 0xbd, 0xc3, 0x87, 0x8c, 0xd7, 0x76, 0xed, 0x25}} ,
+ {{0x47, 0x39, 0x37, 0x76, 0x0d, 0x1d, 0x0c, 0xf5, 0x5a, 0x6d, 0x43, 0x88, 0x99, 0x15, 0xb4, 0x52, 0x0f, 0x2a, 0xb3, 0xb0, 0x3f, 0xa6, 0xb3, 0x26, 0xb3, 0xc7, 0x45, 0xf5, 0x92, 0x5f, 0x9b, 0x17}}},
+{{{0x9d, 0x23, 0xbd, 0x15, 0xfe, 0x52, 0x52, 0x15, 0x26, 0x79, 0x86, 0xba, 0x06, 0x56, 0x66, 0xbb, 0x8c, 0x2e, 0x10, 0x11, 0xd5, 0x4a, 0x18, 0x52, 0xda, 0x84, 0x44, 0xf0, 0x3e, 0xe9, 0x8c, 0x35}} ,
+ {{0xad, 0xa0, 0x41, 0xec, 0xc8, 0x4d, 0xb9, 0xd2, 0x6e, 0x96, 0x4e, 0x5b, 0xc5, 0xc2, 0xa0, 0x1b, 0xcf, 0x0c, 0xbf, 0x17, 0x66, 0x57, 0xc1, 0x17, 0x90, 0x45, 0x71, 0xc2, 0xe1, 0x24, 0xeb, 0x27}}},
+{{{0x2c, 0xb9, 0x42, 0xa4, 0xaf, 0x3b, 0x42, 0x0e, 0xc2, 0x0f, 0xf2, 0xea, 0x83, 0xaf, 0x9a, 0x13, 0x17, 0xb0, 0xbd, 0x89, 0x17, 0xe3, 0x72, 0xcb, 0x0e, 0x76, 0x7e, 0x41, 0x63, 0x04, 0x88, 0x71}} ,
+ {{0x75, 0x78, 0x38, 0x86, 0x57, 0xdd, 0x9f, 0xee, 0x54, 0x70, 0x65, 0xbf, 0xf1, 0x2c, 0xe0, 0x39, 0x0d, 0xe3, 0x89, 0xfd, 0x8e, 0x93, 0x4f, 0x43, 0xdc, 0xd5, 0x5b, 0xde, 0xf9, 0x98, 0xe5, 0x7b}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xe7, 0x3b, 0x65, 0x11, 0xdf, 0xb2, 0xf2, 0x63, 0x94, 0x12, 0x6f, 0x5c, 0x9e, 0x77, 0xc1, 0xb6, 0xd8, 0xab, 0x58, 0x7a, 0x1d, 0x95, 0x73, 0xdd, 0xe7, 0xe3, 0x6f, 0xf2, 0x03, 0x1d, 0xdb, 0x76}} ,
+ {{0xae, 0x06, 0x4e, 0x2c, 0x52, 0x1b, 0xbc, 0x5a, 0x5a, 0xa5, 0xbe, 0x27, 0xbd, 0xeb, 0xe1, 0x14, 0x17, 0x68, 0x26, 0x07, 0x03, 0xd1, 0x18, 0x0b, 0xdf, 0xf1, 0x06, 0x5c, 0xa6, 0x1b, 0xb9, 0x24}}},
+{{{0xc5, 0x66, 0x80, 0x13, 0x0e, 0x48, 0x8c, 0x87, 0x31, 0x84, 0xb4, 0x60, 0xed, 0xc5, 0xec, 0xb6, 0xc5, 0x05, 0x33, 0x5f, 0x2f, 0x7d, 0x40, 0xb6, 0x32, 0x1d, 0x38, 0x74, 0x1b, 0xf1, 0x09, 0x3d}} ,
+ {{0xd4, 0x69, 0x82, 0xbc, 0x8d, 0xf8, 0x34, 0x36, 0x75, 0x55, 0x18, 0x55, 0x58, 0x3c, 0x79, 0xaf, 0x26, 0x80, 0xab, 0x9b, 0x95, 0x00, 0xf1, 0xcb, 0xda, 0xc1, 0x9f, 0xf6, 0x2f, 0xa2, 0xf4, 0x45}}},
+{{{0x17, 0xbe, 0xeb, 0x85, 0xed, 0x9e, 0xcd, 0x56, 0xf5, 0x17, 0x45, 0x42, 0xb4, 0x1f, 0x44, 0x4c, 0x05, 0x74, 0x15, 0x47, 0x00, 0xc6, 0x6a, 0x3d, 0x24, 0x09, 0x0d, 0x58, 0xb1, 0x42, 0xd7, 0x04}} ,
+ {{0x8d, 0xbd, 0xa3, 0xc4, 0x06, 0x9b, 0x1f, 0x90, 0x58, 0x60, 0x74, 0xb2, 0x00, 0x3b, 0x3c, 0xd2, 0xda, 0x82, 0xbb, 0x10, 0x90, 0x69, 0x92, 0xa9, 0xb4, 0x30, 0x81, 0xe3, 0x7c, 0xa8, 0x89, 0x45}}},
+{{{0x3f, 0xdc, 0x05, 0xcb, 0x41, 0x3c, 0xc8, 0x23, 0x04, 0x2c, 0x38, 0x99, 0xe3, 0x68, 0x55, 0xf9, 0xd3, 0x32, 0xc7, 0xbf, 0xfa, 0xd4, 0x1b, 0x5d, 0xde, 0xdc, 0x10, 0x42, 0xc0, 0x42, 0xd9, 0x75}} ,
+ {{0x2d, 0xab, 0x35, 0x4e, 0x87, 0xc4, 0x65, 0x97, 0x67, 0x24, 0xa4, 0x47, 0xad, 0x3f, 0x8e, 0xf3, 0xcb, 0x31, 0x17, 0x77, 0xc5, 0xe2, 0xd7, 0x8f, 0x3c, 0xc1, 0xcd, 0x56, 0x48, 0xc1, 0x6c, 0x69}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x14, 0xae, 0x5f, 0x88, 0x7b, 0xa5, 0x90, 0xdf, 0x10, 0xb2, 0x8b, 0x5e, 0x24, 0x17, 0xc3, 0xa3, 0xd4, 0x0f, 0x92, 0x61, 0x1a, 0x19, 0x5a, 0xad, 0x76, 0xbd, 0xd8, 0x1c, 0xdd, 0xe0, 0x12, 0x6d}} ,
+ {{0x8e, 0xbd, 0x70, 0x8f, 0x02, 0xa3, 0x24, 0x4d, 0x5a, 0x67, 0xc4, 0xda, 0xf7, 0x20, 0x0f, 0x81, 0x5b, 0x7a, 0x05, 0x24, 0x67, 0x83, 0x0b, 0x2a, 0x80, 0xe7, 0xfd, 0x74, 0x4b, 0x9e, 0x5c, 0x0d}}},
+{{{0x94, 0xd5, 0x5f, 0x1f, 0xa2, 0xfb, 0xeb, 0xe1, 0x07, 0x34, 0xf8, 0x20, 0xad, 0x81, 0x30, 0x06, 0x2d, 0xa1, 0x81, 0x95, 0x36, 0xcf, 0x11, 0x0b, 0xaf, 0xc1, 0x2b, 0x9a, 0x6c, 0x55, 0xc1, 0x16}} ,
+ {{0x36, 0x4f, 0xf1, 0x5e, 0x74, 0x35, 0x13, 0x28, 0xd7, 0x11, 0xcf, 0xb8, 0xde, 0x93, 0xb3, 0x05, 0xb8, 0xb5, 0x73, 0xe9, 0xeb, 0xad, 0x19, 0x1e, 0x89, 0x0f, 0x8b, 0x15, 0xd5, 0x8c, 0xe3, 0x23}}},
+{{{0x33, 0x79, 0xe7, 0x18, 0xe6, 0x0f, 0x57, 0x93, 0x15, 0xa0, 0xa7, 0xaa, 0xc4, 0xbf, 0x4f, 0x30, 0x74, 0x95, 0x5e, 0x69, 0x4a, 0x5b, 0x45, 0xe4, 0x00, 0xeb, 0x23, 0x74, 0x4c, 0xdf, 0x6b, 0x45}} ,
+ {{0x97, 0x29, 0x6c, 0xc4, 0x42, 0x0b, 0xdd, 0xc0, 0x29, 0x5c, 0x9b, 0x34, 0x97, 0xd0, 0xc7, 0x79, 0x80, 0x63, 0x74, 0xe4, 0x8e, 0x37, 0xb0, 0x2b, 0x7c, 0xe8, 0x68, 0x6c, 0xc3, 0x82, 0x97, 0x57}}},
+{{{0x22, 0xbe, 0x83, 0xb6, 0x4b, 0x80, 0x6b, 0x43, 0x24, 0x5e, 0xef, 0x99, 0x9b, 0xa8, 0xfc, 0x25, 0x8d, 0x3b, 0x03, 0x94, 0x2b, 0x3e, 0xe7, 0x95, 0x76, 0x9b, 0xcc, 0x15, 0xdb, 0x32, 0xe6, 0x66}} ,
+ {{0x84, 0xf0, 0x4a, 0x13, 0xa6, 0xd6, 0xfa, 0x93, 0x46, 0x07, 0xf6, 0x7e, 0x5c, 0x6d, 0x5e, 0xf6, 0xa6, 0xe7, 0x48, 0xf0, 0x06, 0xea, 0xff, 0x90, 0xc1, 0xcc, 0x4c, 0x19, 0x9c, 0x3c, 0x4e, 0x53}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x2a, 0x50, 0xe3, 0x07, 0x15, 0x59, 0xf2, 0x8b, 0x81, 0xf2, 0xf3, 0xd3, 0x6c, 0x99, 0x8c, 0x70, 0x67, 0xec, 0xcc, 0xee, 0x9e, 0x59, 0x45, 0x59, 0x7d, 0x47, 0x75, 0x69, 0xf5, 0x24, 0x93, 0x5d}} ,
+ {{0x6a, 0x4f, 0x1b, 0xbe, 0x6b, 0x30, 0xcf, 0x75, 0x46, 0xe3, 0x7b, 0x9d, 0xfc, 0xcd, 0xd8, 0x5c, 0x1f, 0xb4, 0xc8, 0xe2, 0x24, 0xec, 0x1a, 0x28, 0x05, 0x32, 0x57, 0xfd, 0x3c, 0x5a, 0x98, 0x10}}},
+{{{0xa3, 0xdb, 0xf7, 0x30, 0xd8, 0xc2, 0x9a, 0xe1, 0xd3, 0xce, 0x22, 0xe5, 0x80, 0x1e, 0xd9, 0xe4, 0x1f, 0xab, 0xc0, 0x71, 0x1a, 0x86, 0x0e, 0x27, 0x99, 0x5b, 0xfa, 0x76, 0x99, 0xb0, 0x08, 0x3c}} ,
+ {{0x2a, 0x93, 0xd2, 0x85, 0x1b, 0x6a, 0x5d, 0xa6, 0xee, 0xd1, 0xd1, 0x33, 0xbd, 0x6a, 0x36, 0x73, 0x37, 0x3a, 0x44, 0xb4, 0xec, 0xa9, 0x7a, 0xde, 0x83, 0x40, 0xd7, 0xdf, 0x28, 0xba, 0xa2, 0x30}}},
+{{{0xd3, 0xb5, 0x6d, 0x05, 0x3f, 0x9f, 0xf3, 0x15, 0x8d, 0x7c, 0xca, 0xc9, 0xfc, 0x8a, 0x7c, 0x94, 0xb0, 0x63, 0x36, 0x9b, 0x78, 0xd1, 0x91, 0x1f, 0x93, 0xd8, 0x57, 0x43, 0xde, 0x76, 0xa3, 0x43}} ,
+ {{0x9b, 0x35, 0xe2, 0xa9, 0x3d, 0x32, 0x1e, 0xbb, 0x16, 0x28, 0x70, 0xe9, 0x45, 0x2f, 0x8f, 0x70, 0x7f, 0x08, 0x7e, 0x53, 0xc4, 0x7a, 0xbf, 0xf7, 0xe1, 0xa4, 0x6a, 0xd8, 0xac, 0x64, 0x1b, 0x11}}},
+{{{0xb2, 0xeb, 0x47, 0x46, 0x18, 0x3e, 0x1f, 0x99, 0x0c, 0xcc, 0xf1, 0x2c, 0xe0, 0xe7, 0x8f, 0xe0, 0x01, 0x7e, 0x65, 0xb8, 0x0c, 0xd0, 0xfb, 0xc8, 0xb9, 0x90, 0x98, 0x33, 0x61, 0x3b, 0xd8, 0x27}} ,
+ {{0xa0, 0xbe, 0x72, 0x3a, 0x50, 0x4b, 0x74, 0xab, 0x01, 0xc8, 0x93, 0xc5, 0xe4, 0xc7, 0x08, 0x6c, 0xb4, 0xca, 0xee, 0xeb, 0x8e, 0xd7, 0x4e, 0x26, 0xc6, 0x1d, 0xe2, 0x71, 0xaf, 0x89, 0xa0, 0x2a}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x98, 0x0b, 0xe4, 0xde, 0xdb, 0xa8, 0xfa, 0x82, 0x74, 0x06, 0x52, 0x6d, 0x08, 0x52, 0x8a, 0xff, 0x62, 0xc5, 0x6a, 0x44, 0x0f, 0x51, 0x8c, 0x1f, 0x6e, 0xb6, 0xc6, 0x2c, 0x81, 0xd3, 0x76, 0x46}} ,
+ {{0xf4, 0x29, 0x74, 0x2e, 0x80, 0xa7, 0x1a, 0x8f, 0xf6, 0xbd, 0xd6, 0x8e, 0xbf, 0xc1, 0x95, 0x2a, 0xeb, 0xa0, 0x7f, 0x45, 0xa0, 0x50, 0x14, 0x05, 0xb1, 0x57, 0x4c, 0x74, 0xb7, 0xe2, 0x89, 0x7d}}},
+{{{0x07, 0xee, 0xa7, 0xad, 0xb7, 0x09, 0x0b, 0x49, 0x4e, 0xbf, 0xca, 0xe5, 0x21, 0xe6, 0xe6, 0xaf, 0xd5, 0x67, 0xf3, 0xce, 0x7e, 0x7c, 0x93, 0x7b, 0x5a, 0x10, 0x12, 0x0e, 0x6c, 0x06, 0x11, 0x75}} ,
+ {{0xd5, 0xfc, 0x86, 0xa3, 0x3b, 0xa3, 0x3e, 0x0a, 0xfb, 0x0b, 0xf7, 0x36, 0xb1, 0x5b, 0xda, 0x70, 0xb7, 0x00, 0xa7, 0xda, 0x88, 0x8f, 0x84, 0xa8, 0xbc, 0x1c, 0x39, 0xb8, 0x65, 0xf3, 0x4d, 0x60}}},
+{{{0x96, 0x9d, 0x31, 0xf4, 0xa2, 0xbe, 0x81, 0xb9, 0xa5, 0x59, 0x9e, 0xba, 0x07, 0xbe, 0x74, 0x58, 0xd8, 0xeb, 0xc5, 0x9f, 0x3d, 0xd1, 0xf4, 0xae, 0xce, 0x53, 0xdf, 0x4f, 0xc7, 0x2a, 0x89, 0x4d}} ,
+ {{0x29, 0xd8, 0xf2, 0xaa, 0xe9, 0x0e, 0xf7, 0x2e, 0x5f, 0x9d, 0x8a, 0x5b, 0x09, 0xed, 0xc9, 0x24, 0x22, 0xf4, 0x0f, 0x25, 0x8f, 0x1c, 0x84, 0x6e, 0x34, 0x14, 0x6c, 0xea, 0xb3, 0x86, 0x5d, 0x04}}},
+{{{0x07, 0x98, 0x61, 0xe8, 0x6a, 0xd2, 0x81, 0x49, 0x25, 0xd5, 0x5b, 0x18, 0xc7, 0x35, 0x52, 0x51, 0xa4, 0x46, 0xad, 0x18, 0x0d, 0xc9, 0x5f, 0x18, 0x91, 0x3b, 0xb4, 0xc0, 0x60, 0x59, 0x8d, 0x66}} ,
+ {{0x03, 0x1b, 0x79, 0x53, 0x6e, 0x24, 0xae, 0x57, 0xd9, 0x58, 0x09, 0x85, 0x48, 0xa2, 0xd3, 0xb5, 0xe2, 0x4d, 0x11, 0x82, 0xe6, 0x86, 0x3c, 0xe9, 0xb1, 0x00, 0x19, 0xc2, 0x57, 0xf7, 0x66, 0x7a}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x0f, 0xe3, 0x89, 0x03, 0xd7, 0x22, 0x95, 0x9f, 0xca, 0xb4, 0x8d, 0x9e, 0x6d, 0x97, 0xff, 0x8d, 0x21, 0x59, 0x07, 0xef, 0x03, 0x2d, 0x5e, 0xf8, 0x44, 0x46, 0xe7, 0x85, 0x80, 0xc5, 0x89, 0x50}} ,
+ {{0x8b, 0xd8, 0x53, 0x86, 0x24, 0x86, 0x29, 0x52, 0x01, 0xfa, 0x20, 0xc3, 0x4e, 0x95, 0xcb, 0xad, 0x7b, 0x34, 0x94, 0x30, 0xb7, 0x7a, 0xfa, 0x96, 0x41, 0x60, 0x2b, 0xcb, 0x59, 0xb9, 0xca, 0x50}}},
+{{{0xc2, 0x5b, 0x9b, 0x78, 0x23, 0x1b, 0x3a, 0x88, 0x94, 0x5f, 0x0a, 0x9b, 0x98, 0x2b, 0x6e, 0x53, 0x11, 0xf6, 0xff, 0xc6, 0x7d, 0x42, 0xcc, 0x02, 0x80, 0x40, 0x0d, 0x1e, 0xfb, 0xaf, 0x61, 0x07}} ,
+ {{0xb0, 0xe6, 0x2f, 0x81, 0x70, 0xa1, 0x2e, 0x39, 0x04, 0x7c, 0xc4, 0x2c, 0x87, 0x45, 0x4a, 0x5b, 0x69, 0x97, 0xac, 0x6d, 0x2c, 0x10, 0x42, 0x7c, 0x3b, 0x15, 0x70, 0x60, 0x0e, 0x11, 0x6d, 0x3a}}},
+{{{0x9b, 0x18, 0x80, 0x5e, 0xdb, 0x05, 0xbd, 0xc6, 0xb7, 0x3c, 0xc2, 0x40, 0x4d, 0x5d, 0xce, 0x97, 0x8a, 0x34, 0x15, 0xab, 0x28, 0x5d, 0x10, 0xf0, 0x37, 0x0c, 0xcc, 0x16, 0xfa, 0x1f, 0x33, 0x0d}} ,
+ {{0x19, 0xf9, 0x35, 0xaa, 0x59, 0x1a, 0x0c, 0x5c, 0x06, 0xfc, 0x6a, 0x0b, 0x97, 0x53, 0x36, 0xfc, 0x2a, 0xa5, 0x5a, 0x9b, 0x30, 0xef, 0x23, 0xaf, 0x39, 0x5d, 0x9a, 0x6b, 0x75, 0x57, 0x48, 0x0b}}},
+{{{0x26, 0xdc, 0x76, 0x3b, 0xfc, 0xf9, 0x9c, 0x3f, 0x89, 0x0b, 0x62, 0x53, 0xaf, 0x83, 0x01, 0x2e, 0xbc, 0x6a, 0xc6, 0x03, 0x0d, 0x75, 0x2a, 0x0d, 0xe6, 0x94, 0x54, 0xcf, 0xb3, 0xe5, 0x96, 0x25}} ,
+ {{0xfe, 0x82, 0xb1, 0x74, 0x31, 0x8a, 0xa7, 0x6f, 0x56, 0xbd, 0x8d, 0xf4, 0xe0, 0x94, 0x51, 0x59, 0xde, 0x2c, 0x5a, 0xf4, 0x84, 0x6b, 0x4a, 0x88, 0x93, 0xc0, 0x0c, 0x9a, 0xac, 0xa7, 0xa0, 0x68}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x25, 0x0d, 0xd6, 0xc7, 0x23, 0x47, 0x10, 0xad, 0xc7, 0x08, 0x5c, 0x87, 0x87, 0x93, 0x98, 0x18, 0xb8, 0xd3, 0x9c, 0xac, 0x5a, 0x3d, 0xc5, 0x75, 0xf8, 0x49, 0x32, 0x14, 0xcc, 0x51, 0x96, 0x24}} ,
+ {{0x65, 0x9c, 0x5d, 0xf0, 0x37, 0x04, 0xf0, 0x34, 0x69, 0x2a, 0xf0, 0xa5, 0x64, 0xca, 0xde, 0x2b, 0x5b, 0x15, 0x10, 0xd2, 0xab, 0x06, 0xdd, 0xc4, 0xb0, 0xb6, 0x5b, 0xc1, 0x17, 0xdf, 0x8f, 0x02}}},
+{{{0xbd, 0x59, 0x3d, 0xbf, 0x5c, 0x31, 0x44, 0x2c, 0x32, 0x94, 0x04, 0x60, 0x84, 0x0f, 0xad, 0x00, 0xb6, 0x8f, 0xc9, 0x1d, 0xcc, 0x5c, 0xa2, 0x49, 0x0e, 0x50, 0x91, 0x08, 0x9a, 0x43, 0x55, 0x05}} ,
+ {{0x5d, 0x93, 0x55, 0xdf, 0x9b, 0x12, 0x19, 0xec, 0x93, 0x85, 0x42, 0x9e, 0x66, 0x0f, 0x9d, 0xaf, 0x99, 0xaf, 0x26, 0x89, 0xbc, 0x61, 0xfd, 0xff, 0xce, 0x4b, 0xf4, 0x33, 0x95, 0xc9, 0x35, 0x58}}},
+{{{0x12, 0x55, 0xf9, 0xda, 0xcb, 0x44, 0xa7, 0xdc, 0x57, 0xe2, 0xf9, 0x9a, 0xe6, 0x07, 0x23, 0x60, 0x54, 0xa7, 0x39, 0xa5, 0x9b, 0x84, 0x56, 0x6e, 0xaa, 0x8b, 0x8f, 0xb0, 0x2c, 0x87, 0xaf, 0x67}} ,
+ {{0x00, 0xa9, 0x4c, 0xb2, 0x12, 0xf8, 0x32, 0xa8, 0x7a, 0x00, 0x4b, 0x49, 0x32, 0xba, 0x1f, 0x5d, 0x44, 0x8e, 0x44, 0x7a, 0xdc, 0x11, 0xfb, 0x39, 0x08, 0x57, 0x87, 0xa5, 0x12, 0x42, 0x93, 0x0e}}},
+{{{0x17, 0xb4, 0xae, 0x72, 0x59, 0xd0, 0xaa, 0xa8, 0x16, 0x8b, 0x63, 0x11, 0xb3, 0x43, 0x04, 0xda, 0x0c, 0xa8, 0xb7, 0x68, 0xdd, 0x4e, 0x54, 0xe7, 0xaf, 0x5d, 0x5d, 0x05, 0x76, 0x36, 0xec, 0x0d}} ,
+ {{0x6d, 0x7c, 0x82, 0x32, 0x38, 0x55, 0x57, 0x74, 0x5b, 0x7d, 0xc3, 0xc4, 0xfb, 0x06, 0x29, 0xf0, 0x13, 0x55, 0x54, 0xc6, 0xa7, 0xdc, 0x4c, 0x9f, 0x98, 0x49, 0x20, 0xa8, 0xc3, 0x8d, 0xfa, 0x48}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x87, 0x47, 0x9d, 0xe9, 0x25, 0xd5, 0xe3, 0x47, 0x78, 0xdf, 0x85, 0xa7, 0x85, 0x5e, 0x7a, 0x4c, 0x5f, 0x79, 0x1a, 0xf3, 0xa2, 0xb2, 0x28, 0xa0, 0x9c, 0xdd, 0x30, 0x40, 0xd4, 0x38, 0xbd, 0x28}} ,
+ {{0xfc, 0xbb, 0xd5, 0x78, 0x6d, 0x1d, 0xd4, 0x99, 0xb4, 0xaa, 0x44, 0x44, 0x7a, 0x1b, 0xd8, 0xfe, 0xb4, 0x99, 0xb9, 0xcc, 0xe7, 0xc4, 0xd3, 0x3a, 0x73, 0x83, 0x41, 0x5c, 0x40, 0xd7, 0x2d, 0x55}}},
+{{{0x26, 0xe1, 0x7b, 0x5f, 0xe5, 0xdc, 0x3f, 0x7d, 0xa1, 0xa7, 0x26, 0x44, 0x22, 0x23, 0xc0, 0x8f, 0x7d, 0xf1, 0xb5, 0x11, 0x47, 0x7b, 0x19, 0xd4, 0x75, 0x6f, 0x1e, 0xa5, 0x27, 0xfe, 0xc8, 0x0e}} ,
+ {{0xd3, 0x11, 0x3d, 0xab, 0xef, 0x2c, 0xed, 0xb1, 0x3d, 0x7c, 0x32, 0x81, 0x6b, 0xfe, 0xf8, 0x1c, 0x3c, 0x7b, 0xc0, 0x61, 0xdf, 0xb8, 0x75, 0x76, 0x7f, 0xaa, 0xd8, 0x93, 0xaf, 0x3d, 0xe8, 0x3d}}},
+{{{0xfd, 0x5b, 0x4e, 0x8d, 0xb6, 0x7e, 0x82, 0x9b, 0xef, 0xce, 0x04, 0x69, 0x51, 0x52, 0xff, 0xef, 0xa0, 0x52, 0xb5, 0x79, 0x17, 0x5e, 0x2f, 0xde, 0xd6, 0x3c, 0x2d, 0xa0, 0x43, 0xb4, 0x0b, 0x19}} ,
+ {{0xc0, 0x61, 0x48, 0x48, 0x17, 0xf4, 0x9e, 0x18, 0x51, 0x2d, 0xea, 0x2f, 0xf2, 0xf2, 0xe0, 0xa3, 0x14, 0xb7, 0x8b, 0x3a, 0x30, 0xf5, 0x81, 0xc1, 0x5d, 0x71, 0x39, 0x62, 0x55, 0x1f, 0x60, 0x5a}}},
+{{{0xe5, 0x89, 0x8a, 0x76, 0x6c, 0xdb, 0x4d, 0x0a, 0x5b, 0x72, 0x9d, 0x59, 0x6e, 0x63, 0x63, 0x18, 0x7c, 0xe3, 0xfa, 0xe2, 0xdb, 0xa1, 0x8d, 0xf4, 0xa5, 0xd7, 0x16, 0xb2, 0xd0, 0xb3, 0x3f, 0x39}} ,
+ {{0xce, 0x60, 0x09, 0x6c, 0xf5, 0x76, 0x17, 0x24, 0x80, 0x3a, 0x96, 0xc7, 0x94, 0x2e, 0xf7, 0x6b, 0xef, 0xb5, 0x05, 0x96, 0xef, 0xd3, 0x7b, 0x51, 0xda, 0x05, 0x44, 0x67, 0xbc, 0x07, 0x21, 0x4e}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xe9, 0x73, 0x6f, 0x21, 0xb9, 0xde, 0x22, 0x7d, 0xeb, 0x97, 0x31, 0x10, 0xa3, 0xea, 0xe1, 0xc6, 0x37, 0xeb, 0x8f, 0x43, 0x58, 0xde, 0x41, 0x64, 0x0e, 0x3e, 0x07, 0x99, 0x3d, 0xf1, 0xdf, 0x1e}} ,
+ {{0xf8, 0xad, 0x43, 0xc2, 0x17, 0x06, 0xe2, 0xe4, 0xa9, 0x86, 0xcd, 0x18, 0xd7, 0x78, 0xc8, 0x74, 0x66, 0xd2, 0x09, 0x18, 0xa5, 0xf1, 0xca, 0xa6, 0x62, 0x92, 0xc1, 0xcb, 0x00, 0xeb, 0x42, 0x2e}}},
+{{{0x7b, 0x34, 0x24, 0x4c, 0xcf, 0x38, 0xe5, 0x6c, 0x0a, 0x01, 0x2c, 0x22, 0x0b, 0x24, 0x38, 0xad, 0x24, 0x7e, 0x19, 0xf0, 0x6c, 0xf9, 0x31, 0xf4, 0x35, 0x11, 0xf6, 0x46, 0x33, 0x3a, 0x23, 0x59}} ,
+ {{0x20, 0x0b, 0xa1, 0x08, 0x19, 0xad, 0x39, 0x54, 0xea, 0x3e, 0x23, 0x09, 0xb6, 0xe2, 0xd2, 0xbc, 0x4d, 0xfc, 0x9c, 0xf0, 0x13, 0x16, 0x22, 0x3f, 0xb9, 0xd2, 0x11, 0x86, 0x90, 0x55, 0xce, 0x3c}}},
+{{{0xc4, 0x0b, 0x4b, 0x62, 0x99, 0x37, 0x84, 0x3f, 0x74, 0xa2, 0xf9, 0xce, 0xe2, 0x0b, 0x0f, 0x2a, 0x3d, 0xa3, 0xe3, 0xdb, 0x5a, 0x9d, 0x93, 0xcc, 0xa5, 0xef, 0x82, 0x91, 0x1d, 0xe6, 0x6c, 0x68}} ,
+ {{0xa3, 0x64, 0x17, 0x9b, 0x8b, 0xc8, 0x3a, 0x61, 0xe6, 0x9d, 0xc6, 0xed, 0x7b, 0x03, 0x52, 0x26, 0x9d, 0x3a, 0xb3, 0x13, 0xcc, 0x8a, 0xfd, 0x2c, 0x1a, 0x1d, 0xed, 0x13, 0xd0, 0x55, 0x57, 0x0e}}},
+{{{0x1a, 0xea, 0xbf, 0xfd, 0x4a, 0x3c, 0x8e, 0xec, 0x29, 0x7e, 0x77, 0x77, 0x12, 0x99, 0xd7, 0x84, 0xf9, 0x55, 0x7f, 0xf1, 0x8b, 0xb4, 0xd2, 0x95, 0xa3, 0x8d, 0xf0, 0x8a, 0xa7, 0xeb, 0x82, 0x4b}} ,
+ {{0x2c, 0x28, 0xf4, 0x3a, 0xf6, 0xde, 0x0a, 0xe0, 0x41, 0x44, 0x23, 0xf8, 0x3f, 0x03, 0x64, 0x9f, 0xc3, 0x55, 0x4c, 0xc6, 0xc1, 0x94, 0x1c, 0x24, 0x5d, 0x5f, 0x92, 0x45, 0x96, 0x57, 0x37, 0x14}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xc1, 0xcd, 0x90, 0x66, 0xb9, 0x76, 0xa0, 0x5b, 0xa5, 0x85, 0x75, 0x23, 0xf9, 0x89, 0xa5, 0x82, 0xb2, 0x6f, 0xb1, 0xeb, 0xc4, 0x69, 0x6f, 0x18, 0x5a, 0xed, 0x94, 0x3d, 0x9d, 0xd9, 0x2c, 0x1a}} ,
+ {{0x35, 0xb0, 0xe6, 0x73, 0x06, 0xb7, 0x37, 0xe0, 0xf8, 0xb0, 0x22, 0xe8, 0xd2, 0xed, 0x0b, 0xef, 0xe6, 0xc6, 0x5a, 0x99, 0x9e, 0x1a, 0x9f, 0x04, 0x97, 0xe4, 0x4d, 0x0b, 0xbe, 0xba, 0x44, 0x40}}},
+{{{0xc1, 0x56, 0x96, 0x91, 0x5f, 0x1f, 0xbb, 0x54, 0x6f, 0x88, 0x89, 0x0a, 0xb2, 0xd6, 0x41, 0x42, 0x6a, 0x82, 0xee, 0x14, 0xaa, 0x76, 0x30, 0x65, 0x0f, 0x67, 0x39, 0xa6, 0x51, 0x7c, 0x49, 0x24}} ,
+ {{0x35, 0xa3, 0x78, 0xd1, 0x11, 0x0f, 0x75, 0xd3, 0x70, 0x46, 0xdb, 0x20, 0x51, 0xcb, 0x92, 0x80, 0x54, 0x10, 0x74, 0x36, 0x86, 0xa9, 0xd7, 0xa3, 0x08, 0x78, 0xf1, 0x01, 0x29, 0xf8, 0x80, 0x3b}}},
+{{{0xdb, 0xa7, 0x9d, 0x9d, 0xbf, 0xa0, 0xcc, 0xed, 0x53, 0xa2, 0xa2, 0x19, 0x39, 0x48, 0x83, 0x19, 0x37, 0x58, 0xd1, 0x04, 0x28, 0x40, 0xf7, 0x8a, 0xc2, 0x08, 0xb7, 0xa5, 0x42, 0xcf, 0x53, 0x4c}} ,
+ {{0xa7, 0xbb, 0xf6, 0x8e, 0xad, 0xdd, 0xf7, 0x90, 0xdd, 0x5f, 0x93, 0x89, 0xae, 0x04, 0x37, 0xe6, 0x9a, 0xb7, 0xe8, 0xc0, 0xdf, 0x16, 0x2a, 0xbf, 0xc4, 0x3a, 0x3c, 0x41, 0xd5, 0x89, 0x72, 0x5a}}},
+{{{0x1f, 0x96, 0xff, 0x34, 0x2c, 0x13, 0x21, 0xcb, 0x0a, 0x89, 0x85, 0xbe, 0xb3, 0x70, 0x9e, 0x1e, 0xde, 0x97, 0xaf, 0x96, 0x30, 0xf7, 0x48, 0x89, 0x40, 0x8d, 0x07, 0xf1, 0x25, 0xf0, 0x30, 0x58}} ,
+ {{0x1e, 0xd4, 0x93, 0x57, 0xe2, 0x17, 0xe7, 0x9d, 0xab, 0x3c, 0x55, 0x03, 0x82, 0x2f, 0x2b, 0xdb, 0x56, 0x1e, 0x30, 0x2e, 0x24, 0x47, 0x6e, 0xe6, 0xff, 0x33, 0x24, 0x2c, 0x75, 0x51, 0xd4, 0x67}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x2b, 0x06, 0xd9, 0xa1, 0x5d, 0xe1, 0xf4, 0xd1, 0x1e, 0x3c, 0x9a, 0xc6, 0x29, 0x2b, 0x13, 0x13, 0x78, 0xc0, 0xd8, 0x16, 0x17, 0x2d, 0x9e, 0xa9, 0xc9, 0x79, 0x57, 0xab, 0x24, 0x91, 0x92, 0x19}} ,
+ {{0x69, 0xfb, 0xa1, 0x9c, 0xa6, 0x75, 0x49, 0x7d, 0x60, 0x73, 0x40, 0x42, 0xc4, 0x13, 0x0a, 0x95, 0x79, 0x1e, 0x04, 0x83, 0x94, 0x99, 0x9b, 0x1e, 0x0c, 0xe8, 0x1f, 0x54, 0xef, 0xcb, 0xc0, 0x52}}},
+{{{0x14, 0x89, 0x73, 0xa1, 0x37, 0x87, 0x6a, 0x7a, 0xcf, 0x1d, 0xd9, 0x2e, 0x1a, 0x67, 0xed, 0x74, 0xc0, 0xf0, 0x9c, 0x33, 0xdd, 0xdf, 0x08, 0xbf, 0x7b, 0xd1, 0x66, 0xda, 0xe6, 0xc9, 0x49, 0x08}} ,
+ {{0xe9, 0xdd, 0x5e, 0x55, 0xb0, 0x0a, 0xde, 0x21, 0x4c, 0x5a, 0x2e, 0xd4, 0x80, 0x3a, 0x57, 0x92, 0x7a, 0xf1, 0xc4, 0x2c, 0x40, 0xaf, 0x2f, 0xc9, 0x92, 0x03, 0xe5, 0x5a, 0xbc, 0xdc, 0xf4, 0x09}}},
+{{{0xf3, 0xe1, 0x2b, 0x7c, 0x05, 0x86, 0x80, 0x93, 0x4a, 0xad, 0xb4, 0x8f, 0x7e, 0x99, 0x0c, 0xfd, 0xcd, 0xef, 0xd1, 0xff, 0x2c, 0x69, 0x34, 0x13, 0x41, 0x64, 0xcf, 0x3b, 0xd0, 0x90, 0x09, 0x1e}} ,
+ {{0x9d, 0x45, 0xd6, 0x80, 0xe6, 0x45, 0xaa, 0xf4, 0x15, 0xaa, 0x5c, 0x34, 0x87, 0x99, 0xa2, 0x8c, 0x26, 0x84, 0x62, 0x7d, 0xb6, 0x29, 0xc0, 0x52, 0xea, 0xf5, 0x81, 0x18, 0x0f, 0x35, 0xa9, 0x0e}}},
+{{{0xe7, 0x20, 0x72, 0x7c, 0x6d, 0x94, 0x5f, 0x52, 0x44, 0x54, 0xe3, 0xf1, 0xb2, 0xb0, 0x36, 0x46, 0x0f, 0xae, 0x92, 0xe8, 0x70, 0x9d, 0x6e, 0x79, 0xb1, 0xad, 0x37, 0xa9, 0x5f, 0xc0, 0xde, 0x03}} ,
+ {{0x15, 0x55, 0x37, 0xc6, 0x1c, 0x27, 0x1c, 0x6d, 0x14, 0x4f, 0xca, 0xa4, 0xc4, 0x88, 0x25, 0x46, 0x39, 0xfc, 0x5a, 0xe5, 0xfe, 0x29, 0x11, 0x69, 0xf5, 0x72, 0x84, 0x4d, 0x78, 0x9f, 0x94, 0x15}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xec, 0xd3, 0xff, 0x57, 0x0b, 0xb0, 0xb2, 0xdc, 0xf8, 0x4f, 0xe2, 0x12, 0xd5, 0x36, 0xbe, 0x6b, 0x09, 0x43, 0x6d, 0xa3, 0x4d, 0x90, 0x2d, 0xb8, 0x74, 0xe8, 0x71, 0x45, 0x19, 0x8b, 0x0c, 0x6a}} ,
+ {{0xb8, 0x42, 0x1c, 0x03, 0xad, 0x2c, 0x03, 0x8e, 0xac, 0xd7, 0x98, 0x29, 0x13, 0xc6, 0x02, 0x29, 0xb5, 0xd4, 0xe7, 0xcf, 0xcc, 0x8b, 0x83, 0xec, 0x35, 0xc7, 0x9c, 0x74, 0xb7, 0xad, 0x85, 0x5f}}},
+{{{0x78, 0x84, 0xe1, 0x56, 0x45, 0x69, 0x68, 0x5a, 0x4f, 0xb8, 0xb1, 0x29, 0xff, 0x33, 0x03, 0x31, 0xb7, 0xcb, 0x96, 0x25, 0xe6, 0xe6, 0x41, 0x98, 0x1a, 0xbb, 0x03, 0x56, 0xf2, 0xb2, 0x91, 0x34}} ,
+ {{0x2c, 0x6c, 0xf7, 0x66, 0xa4, 0x62, 0x6b, 0x39, 0xb3, 0xba, 0x65, 0xd3, 0x1c, 0xf8, 0x11, 0xaa, 0xbe, 0xdc, 0x80, 0x59, 0x87, 0xf5, 0x7b, 0xe5, 0xe3, 0xb3, 0x3e, 0x39, 0xda, 0xbe, 0x88, 0x09}}},
+{{{0x8b, 0xf1, 0xa0, 0xf5, 0xdc, 0x29, 0xb4, 0xe2, 0x07, 0xc6, 0x7a, 0x00, 0xd0, 0x89, 0x17, 0x51, 0xd4, 0xbb, 0xd4, 0x22, 0xea, 0x7e, 0x7d, 0x7c, 0x24, 0xea, 0xf2, 0xe8, 0x22, 0x12, 0x95, 0x06}} ,
+ {{0xda, 0x7c, 0xa4, 0x0c, 0xf4, 0xba, 0x6e, 0xe1, 0x89, 0xb5, 0x59, 0xca, 0xf1, 0xc0, 0x29, 0x36, 0x09, 0x44, 0xe2, 0x7f, 0xd1, 0x63, 0x15, 0x99, 0xea, 0x25, 0xcf, 0x0c, 0x9d, 0xc0, 0x44, 0x6f}}},
+{{{0x1d, 0x86, 0x4e, 0xcf, 0xf7, 0x37, 0x10, 0x25, 0x8f, 0x12, 0xfb, 0x19, 0xfb, 0xe0, 0xed, 0x10, 0xc8, 0xe2, 0xf5, 0x75, 0xb1, 0x33, 0xc0, 0x96, 0x0d, 0xfb, 0x15, 0x6c, 0x0d, 0x07, 0x5f, 0x05}} ,
+ {{0x69, 0x3e, 0x47, 0x97, 0x2c, 0xaf, 0x52, 0x7c, 0x78, 0x83, 0xad, 0x1b, 0x39, 0x82, 0x2f, 0x02, 0x6f, 0x47, 0xdb, 0x2a, 0xb0, 0xe1, 0x91, 0x99, 0x55, 0xb8, 0x99, 0x3a, 0xa0, 0x44, 0x11, 0x51}}}
diff --git a/plugins/ssh-base/crypto/poly1305.c b/plugins/ssh-base/crypto/poly1305.c
new file mode 100644
index 0000000000000000000000000000000000000000..65426673cb15cb5f2578b926fff07c10abe6187d
--- /dev/null
+++ b/plugins/ssh-base/crypto/poly1305.c
@@ -0,0 +1,172 @@
+/* 
+ * Public Domain poly1305 from Andrew Moon
+ * poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna
+ */
+
+/* $OpenBSD: poly1305.c,v 1.3 2013/12/19 22:57:13 djm Exp $ */
+
+#include <libwebsockets.h>
+#include "lws-ssh.h"
+
+#define mul32x32_64(a,b) ((uint64_t)(a) * (b))
+
+#define U8TO32_LE(p) \
+	(((uint32_t)((p)[0])) | \
+	 ((uint32_t)((p)[1]) <<  8) | \
+	 ((uint32_t)((p)[2]) << 16) | \
+	 ((uint32_t)((p)[3]) << 24))
+
+#define U32TO8_LE(p, v) \
+	do { \
+		(p)[0] = (uint8_t)((v)); \
+		(p)[1] = (uint8_t)((v) >>  8); \
+		(p)[2] = (uint8_t)((v) >> 16); \
+		(p)[3] = (uint8_t)((v) >> 24); \
+	} while (0)
+
+void
+poly1305_auth(unsigned char out[POLY1305_TAGLEN],
+	      const unsigned char *m, size_t inlen,
+	      const unsigned char key[POLY1305_KEYLEN])
+{
+	uint32_t t0,t1,t2,t3;
+	uint32_t h0,h1,h2,h3,h4;
+	uint32_t r0,r1,r2,r3,r4;
+	uint32_t s1,s2,s3,s4;
+	uint32_t b, nb;
+	size_t j;
+	uint64_t t[5];
+	uint64_t f0,f1,f2,f3;
+	uint32_t g0,g1,g2,g3,g4;
+	uint64_t c;
+	unsigned char mp[16];
+
+	/* clamp key */
+	t0 = U8TO32_LE(key + 0);
+	t1 = U8TO32_LE(key + 4);
+	t2 = U8TO32_LE(key + 8);
+	t3 = U8TO32_LE(key + 12);
+
+	/* precompute multipliers */
+	r0 = t0 & 0x3ffffff; t0 >>= 26; t0 |= t1 << 6;
+	r1 = t0 & 0x3ffff03; t1 >>= 20; t1 |= t2 << 12;
+	r2 = t1 & 0x3ffc0ff; t2 >>= 14; t2 |= t3 << 18;
+	r3 = t2 & 0x3f03fff; t3 >>= 8;
+	r4 = t3 & 0x00fffff;
+
+	s1 = r1 * 5;
+	s2 = r2 * 5;
+	s3 = r3 * 5;
+	s4 = r4 * 5;
+
+	/* init state */
+	h0 = 0;
+	h1 = 0;
+	h2 = 0;
+	h3 = 0;
+	h4 = 0;
+
+	/* full blocks */
+	if (inlen < 16)
+		goto poly1305_donna_atmost15bytes;
+
+poly1305_donna_16bytes:
+	m += 16;
+	inlen -= 16;
+
+	t0 = U8TO32_LE(m - 16);
+	t1 = U8TO32_LE(m - 12);
+	t2 = U8TO32_LE(m - 8);
+	t3 = U8TO32_LE(m - 4);
+
+	h0 += t0 & 0x3ffffff;
+	h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff;
+	h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff;
+	h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff;
+	h4 += (t3 >> 8) | (1 << 24);
+
+poly1305_donna_mul:
+	t[0]  = mul32x32_64(h0,r0) + mul32x32_64(h1,s4) +
+		mul32x32_64(h2,s3) + mul32x32_64(h3,s2) +
+		mul32x32_64(h4,s1);
+	t[1]  = mul32x32_64(h0,r1) + mul32x32_64(h1,r0) +
+		mul32x32_64(h2,s4) + mul32x32_64(h3,s3) +
+		mul32x32_64(h4,s2);
+	t[2]  = mul32x32_64(h0,r2) + mul32x32_64(h1,r1) +
+		mul32x32_64(h2,r0) + mul32x32_64(h3,s4) +
+		mul32x32_64(h4,s3);
+	t[3]  = mul32x32_64(h0,r3) + mul32x32_64(h1,r2) +
+		mul32x32_64(h2,r1) + mul32x32_64(h3,r0) +
+		mul32x32_64(h4,s4);
+	t[4]  = mul32x32_64(h0,r4) + mul32x32_64(h1,r3) +
+		mul32x32_64(h2,r2) + mul32x32_64(h3,r1) +
+		mul32x32_64(h4,r0);
+
+		    h0 = (uint32_t)t[0] & 0x3ffffff; c =           (t[0] >> 26);
+	t[1] += c;  h1 = (uint32_t)t[1] & 0x3ffffff; b = (uint32_t)(t[1] >> 26);
+	t[2] += b;  h2 = (uint32_t)t[2] & 0x3ffffff; b = (uint32_t)(t[2] >> 26);
+	t[3] += b;  h3 = (uint32_t)t[3] & 0x3ffffff; b = (uint32_t)(t[3] >> 26);
+	t[4] += b;  h4 = (uint32_t)t[4] & 0x3ffffff; b = (uint32_t)(t[4] >> 26);
+	h0 += b * 5;
+
+	if (inlen >= 16)
+		goto poly1305_donna_16bytes;
+
+	/* final bytes */
+poly1305_donna_atmost15bytes:
+	if (!inlen)
+		goto poly1305_donna_finish;
+
+	for (j = 0; j < inlen; j++)
+		mp[j] = m[j];
+	mp[j++] = 1;
+	for (; j < 16; j++)
+		mp[j] = 0;
+	inlen = 0;
+
+	t0 = U8TO32_LE(mp + 0);
+	t1 = U8TO32_LE(mp + 4);
+	t2 = U8TO32_LE(mp + 8);
+	t3 = U8TO32_LE(mp + 12);
+
+	h0 += t0 & 0x3ffffff;
+	h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff;
+	h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff;
+	h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff;
+	h4 += (t3 >> 8);
+
+	goto poly1305_donna_mul;
+
+poly1305_donna_finish:
+	             b = h0 >> 26; h0 = h0 & 0x3ffffff;
+	h1 +=     b; b = h1 >> 26; h1 = h1 & 0x3ffffff;
+	h2 +=     b; b = h2 >> 26; h2 = h2 & 0x3ffffff;
+	h3 +=     b; b = h3 >> 26; h3 = h3 & 0x3ffffff;
+	h4 +=     b; b = h4 >> 26; h4 = h4 & 0x3ffffff;
+	h0 += b * 5; b = h0 >> 26; h0 = h0 & 0x3ffffff;
+	h1 +=     b;
+
+	g0 = h0 + 5; b = g0 >> 26; g0 &= 0x3ffffff;
+	g1 = h1 + b; b = g1 >> 26; g1 &= 0x3ffffff;
+	g2 = h2 + b; b = g2 >> 26; g2 &= 0x3ffffff;
+	g3 = h3 + b; b = g3 >> 26; g3 &= 0x3ffffff;
+	g4 = h4 + b - (1 << 26);
+
+	b = (g4 >> 31) - 1;
+	nb = ~b;
+	h0 = (h0 & nb) | (g0 & b);
+	h1 = (h1 & nb) | (g1 & b);
+	h2 = (h2 & nb) | (g2 & b);
+	h3 = (h3 & nb) | (g3 & b);
+	h4 = (h4 & nb) | (g4 & b);
+
+	f0 = ((h0      ) | (h1 << 26)) + (uint64_t)U8TO32_LE(&key[16]);
+	f1 = ((h1 >>  6) | (h2 << 20)) + (uint64_t)U8TO32_LE(&key[20]);
+	f2 = ((h2 >> 12) | (h3 << 14)) + (uint64_t)U8TO32_LE(&key[24]);
+	f3 = ((h3 >> 18) | (h4 <<  8)) + (uint64_t)U8TO32_LE(&key[28]);
+
+	U32TO8_LE(&out[ 0], f0); f1 += (f0 >> 32);
+	U32TO8_LE(&out[ 4], f1); f2 += (f1 >> 32);
+	U32TO8_LE(&out[ 8], f2); f3 += (f2 >> 32);
+	U32TO8_LE(&out[12], f3);
+}
diff --git a/plugins/ssh-base/crypto/sc25519.c b/plugins/ssh-base/crypto/sc25519.c
new file mode 100644
index 0000000000000000000000000000000000000000..072fff3c6922a94ea30e80f120ac5a9de0f171e2
--- /dev/null
+++ b/plugins/ssh-base/crypto/sc25519.c
@@ -0,0 +1,308 @@
+/* $OpenBSD: sc25519.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */
+
+/*
+ * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
+ * Peter Schwabe, Bo-Yin Yang.
+ * Copied from supercop-20130419/crypto_sign/ed25519/ref/sc25519.c
+ */
+
+#include <libwebsockets.h>
+
+#include "sc25519.h"
+
+/*Arithmetic modulo the group order m = 2^252 +  27742317777372353535851937790883648493 = 7237005577332262213973186563042994240857116359379907606001950938285454250989 */
+
+static const uint32_t m[32] = {0xED, 0xD3, 0xF5, 0x5C, 0x1A, 0x63, 0x12, 0x58, 0xD6, 0x9C, 0xF7, 0xA2, 0xDE, 0xF9, 0xDE, 0x14,
+                                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
+
+static const uint32_t mu[33] = {0x1B, 0x13, 0x2C, 0x0A, 0xA3, 0xE5, 0x9C, 0xED, 0xA7, 0x29, 0x63, 0x08, 0x5D, 0x21, 0x06, 0x21,
+                                     0xEB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F};
+
+static uint32_t lt(uint32_t a,uint32_t b) /* 16-bit inputs */
+{
+  unsigned int x = a;
+  x -= (unsigned int) b; /* 0..65535: no; 4294901761..4294967295: yes */
+  x >>= 31; /* 0: no; 1: yes */
+  return x;
+}
+
+/* Reduce coefficients of r before calling sc_reduce_add_sub */
+static void sc_reduce_add_sub(sc25519 *r)
+{
+  uint32_t pb = 0;
+  uint32_t b;
+  uint32_t mask;
+  int i;
+  unsigned char t[32];
+
+  for(i=0;i<32;i++) 
+  {
+    pb += m[i];
+    b = lt(r->v[i],pb);
+    t[i] = r->v[i]-pb+(b<<8);
+    pb = b;
+  }
+  mask = b - 1;
+  for(i=0;i<32;i++) 
+    r->v[i] ^= mask & (r->v[i] ^ t[i]);
+}
+
+/* Reduce coefficients of x before calling barrett_reduce */
+static void barrett_reduce(sc25519 *r, const uint32_t x[64])
+{
+  /* See HAC, Alg. 14.42 */
+  int i,j;
+  uint32_t q2[66];
+  uint32_t *q3 = q2 + 33;
+  uint32_t r1[33];
+  uint32_t r2[33];
+  uint32_t carry;
+  uint32_t pb = 0;
+  uint32_t b;
+
+  for (i = 0;i < 66;++i) q2[i] = 0;
+  for (i = 0;i < 33;++i) r2[i] = 0;
+
+  for(i=0;i<33;i++)
+    for(j=0;j<33;j++)
+      if(i+j >= 31) q2[i+j] += mu[i]*x[j+31];
+  carry = q2[31] >> 8;
+  q2[32] += carry;
+  carry = q2[32] >> 8;
+  q2[33] += carry;
+
+  for(i=0;i<33;i++)r1[i] = x[i];
+  for(i=0;i<32;i++)
+    for(j=0;j<33;j++)
+      if(i+j < 33) r2[i+j] += m[i]*q3[j];
+
+  for(i=0;i<32;i++)
+  {
+    carry = r2[i] >> 8;
+    r2[i+1] += carry;
+    r2[i] &= 0xff;
+  }
+
+  for(i=0;i<32;i++) 
+  {
+    pb += r2[i];
+    b = lt(r1[i],pb);
+    r->v[i] = r1[i]-pb+(b<<8);
+    pb = b;
+  }
+
+  /* XXX: Can it really happen that r<0?, See HAC, Alg 14.42, Step 3 
+   * If so: Handle  it here!
+   */
+
+  sc_reduce_add_sub(r);
+  sc_reduce_add_sub(r);
+}
+
+void sc25519_from32bytes(sc25519 *r, const unsigned char x[32])
+{
+  int i;
+  uint32_t t[64];
+  for(i=0;i<32;i++) t[i] = x[i];
+  for(i=32;i<64;++i) t[i] = 0;
+  barrett_reduce(r, t);
+}
+
+void shortsc25519_from16bytes(shortsc25519 *r, const unsigned char x[16])
+{
+  int i;
+  for(i=0;i<16;i++) r->v[i] = x[i];
+}
+
+void sc25519_from64bytes(sc25519 *r, const unsigned char x[64])
+{
+  int i;
+  uint32_t t[64];
+  for(i=0;i<64;i++) t[i] = x[i];
+  barrett_reduce(r, t);
+}
+
+void sc25519_from_shortsc(sc25519 *r, const shortsc25519 *x)
+{
+  int i;
+  for(i=0;i<16;i++)
+    r->v[i] = x->v[i];
+  for(i=0;i<16;i++)
+    r->v[16+i] = 0;
+}
+
+void sc25519_to32bytes(unsigned char r[32], const sc25519 *x)
+{
+  int i;
+  for(i=0;i<32;i++) r[i] = x->v[i];
+}
+
+int sc25519_iszero_vartime(const sc25519 *x)
+{
+  int i;
+  for(i=0;i<32;i++)
+    if(x->v[i] != 0) return 0;
+  return 1;
+}
+
+int sc25519_isshort_vartime(const sc25519 *x)
+{
+  int i;
+  for(i=31;i>15;i--)
+    if(x->v[i] != 0) return 0;
+  return 1;
+}
+
+int sc25519_lt_vartime(const sc25519 *x, const sc25519 *y)
+{
+  int i;
+  for(i=31;i>=0;i--)
+  {
+    if(x->v[i] < y->v[i]) return 1;
+    if(x->v[i] > y->v[i]) return 0;
+  }
+  return 0;
+}
+
+void sc25519_add(sc25519 *r, const sc25519 *x, const sc25519 *y)
+{
+  int i, carry;
+  for(i=0;i<32;i++) r->v[i] = x->v[i] + y->v[i];
+  for(i=0;i<31;i++)
+  {
+    carry = r->v[i] >> 8;
+    r->v[i+1] += carry;
+    r->v[i] &= 0xff;
+  }
+  sc_reduce_add_sub(r);
+}
+
+void sc25519_sub_nored(sc25519 *r, const sc25519 *x, const sc25519 *y)
+{
+  uint32_t b = 0;
+  uint32_t t;
+  int i;
+  for(i=0;i<32;i++)
+  {
+    t = x->v[i] - y->v[i] - b;
+    r->v[i] = t & 255;
+    b = (t >> 8) & 1;
+  }
+}
+
+void sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y)
+{
+  int i,j,carry;
+  uint32_t t[64];
+  for(i=0;i<64;i++)t[i] = 0;
+
+  for(i=0;i<32;i++)
+    for(j=0;j<32;j++)
+      t[i+j] += x->v[i] * y->v[j];
+
+  /* Reduce coefficients */
+  for(i=0;i<63;i++)
+  {
+    carry = t[i] >> 8;
+    t[i+1] += carry;
+    t[i] &= 0xff;
+  }
+
+  barrett_reduce(r, t);
+}
+
+void sc25519_mul_shortsc(sc25519 *r, const sc25519 *x, const shortsc25519 *y)
+{
+  sc25519 t;
+  sc25519_from_shortsc(&t, y);
+  sc25519_mul(r, x, &t);
+}
+
+void sc25519_window3(signed char r[85], const sc25519 *s)
+{
+  char carry;
+  int i;
+  for(i=0;i<10;i++)
+  {
+    r[8*i+0]  =  s->v[3*i+0]       & 7;
+    r[8*i+1]  = (s->v[3*i+0] >> 3) & 7;
+    r[8*i+2]  = (s->v[3*i+0] >> 6) & 7;
+    r[8*i+2] ^= (s->v[3*i+1] << 2) & 7;
+    r[8*i+3]  = (s->v[3*i+1] >> 1) & 7;
+    r[8*i+4]  = (s->v[3*i+1] >> 4) & 7;
+    r[8*i+5]  = (s->v[3*i+1] >> 7) & 7;
+    r[8*i+5] ^= (s->v[3*i+2] << 1) & 7;
+    r[8*i+6]  = (s->v[3*i+2] >> 2) & 7;
+    r[8*i+7]  = (s->v[3*i+2] >> 5) & 7;
+  }
+  r[8*i+0]  =  s->v[3*i+0]       & 7;
+  r[8*i+1]  = (s->v[3*i+0] >> 3) & 7;
+  r[8*i+2]  = (s->v[3*i+0] >> 6) & 7;
+  r[8*i+2] ^= (s->v[3*i+1] << 2) & 7;
+  r[8*i+3]  = (s->v[3*i+1] >> 1) & 7;
+  r[8*i+4]  = (s->v[3*i+1] >> 4) & 7;
+
+  /* Making it signed */
+  carry = 0;
+  for(i=0;i<84;i++)
+  {
+    r[i] += carry;
+    r[i+1] += r[i] >> 3;
+    r[i] &= 7;
+    carry = r[i] >> 2;
+    r[i] -= carry<<3;
+  }
+  r[84] += carry;
+}
+
+void sc25519_window5(signed char r[51], const sc25519 *s)
+{
+  char carry;
+  int i;
+  for(i=0;i<6;i++)
+  {
+    r[8*i+0]  =  s->v[5*i+0]       & 31;
+    r[8*i+1]  = (s->v[5*i+0] >> 5) & 31;
+    r[8*i+1] ^= (s->v[5*i+1] << 3) & 31;
+    r[8*i+2]  = (s->v[5*i+1] >> 2) & 31;
+    r[8*i+3]  = (s->v[5*i+1] >> 7) & 31;
+    r[8*i+3] ^= (s->v[5*i+2] << 1) & 31;
+    r[8*i+4]  = (s->v[5*i+2] >> 4) & 31;
+    r[8*i+4] ^= (s->v[5*i+3] << 4) & 31;
+    r[8*i+5]  = (s->v[5*i+3] >> 1) & 31;
+    r[8*i+6]  = (s->v[5*i+3] >> 6) & 31;
+    r[8*i+6] ^= (s->v[5*i+4] << 2) & 31;
+    r[8*i+7]  = (s->v[5*i+4] >> 3) & 31;
+  }
+  r[8*i+0]  =  s->v[5*i+0]       & 31;
+  r[8*i+1]  = (s->v[5*i+0] >> 5) & 31;
+  r[8*i+1] ^= (s->v[5*i+1] << 3) & 31;
+  r[8*i+2]  = (s->v[5*i+1] >> 2) & 31;
+
+  /* Making it signed */
+  carry = 0;
+  for(i=0;i<50;i++)
+  {
+    r[i] += carry;
+    r[i+1] += r[i] >> 5;
+    r[i] &= 31;
+    carry = r[i] >> 4;
+    r[i] -= carry<<5;
+  }
+  r[50] += carry;
+}
+
+void sc25519_2interleave2(unsigned char r[127], const sc25519 *s1, const sc25519 *s2)
+{
+  int i;
+  for(i=0;i<31;i++)
+  {
+    r[4*i]   = ( s1->v[i]       & 3) ^ (( s2->v[i]       & 3) << 2);
+    r[4*i+1] = ((s1->v[i] >> 2) & 3) ^ (((s2->v[i] >> 2) & 3) << 2);
+    r[4*i+2] = ((s1->v[i] >> 4) & 3) ^ (((s2->v[i] >> 4) & 3) << 2);
+    r[4*i+3] = ((s1->v[i] >> 6) & 3) ^ (((s2->v[i] >> 6) & 3) << 2);
+  }
+  r[124] = ( s1->v[31]       & 3) ^ (( s2->v[31]       & 3) << 2);
+  r[125] = ((s1->v[31] >> 2) & 3) ^ (((s2->v[31] >> 2) & 3) << 2);
+  r[126] = ((s1->v[31] >> 4) & 3) ^ (((s2->v[31] >> 4) & 3) << 2);
+}
diff --git a/plugins/ssh-base/crypto/sc25519.h b/plugins/ssh-base/crypto/sc25519.h
new file mode 100644
index 0000000000000000000000000000000000000000..dace1a17e7819c29c20c69fbc9c73b3aa2137610
--- /dev/null
+++ b/plugins/ssh-base/crypto/sc25519.h
@@ -0,0 +1,78 @@
+/* $OpenBSD: sc25519.h,v 1.3 2013/12/09 11:03:45 markus Exp $ */
+
+/*
+ * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
+ * Peter Schwabe, Bo-Yin Yang.
+ * Copied from supercop-20130419/crypto_sign/ed25519/ref/sc25519.h
+ */
+
+#ifndef SC25519_H
+#define SC25519_H
+
+#define sc25519                  crypto_sign_ed25519_ref_sc25519
+#define shortsc25519             crypto_sign_ed25519_ref_shortsc25519
+#define sc25519_from32bytes      crypto_sign_ed25519_ref_sc25519_from32bytes
+#define shortsc25519_from16bytes crypto_sign_ed25519_ref_shortsc25519_from16bytes
+#define sc25519_from64bytes      crypto_sign_ed25519_ref_sc25519_from64bytes
+#define sc25519_from_shortsc     crypto_sign_ed25519_ref_sc25519_from_shortsc
+#define sc25519_to32bytes        crypto_sign_ed25519_ref_sc25519_to32bytes
+#define sc25519_iszero_vartime   crypto_sign_ed25519_ref_sc25519_iszero_vartime
+#define sc25519_isshort_vartime  crypto_sign_ed25519_ref_sc25519_isshort_vartime
+#define sc25519_lt_vartime       crypto_sign_ed25519_ref_sc25519_lt_vartime
+#define sc25519_add              crypto_sign_ed25519_ref_sc25519_add
+#define sc25519_sub_nored        crypto_sign_ed25519_ref_sc25519_sub_nored
+#define sc25519_mul              crypto_sign_ed25519_ref_sc25519_mul
+#define sc25519_mul_shortsc      crypto_sign_ed25519_ref_sc25519_mul_shortsc
+#define sc25519_window3          crypto_sign_ed25519_ref_sc25519_window3
+#define sc25519_window5          crypto_sign_ed25519_ref_sc25519_window5
+#define sc25519_2interleave2     crypto_sign_ed25519_ref_sc25519_2interleave2
+
+typedef struct 
+{
+  uint32_t v[32];
+}
+sc25519;
+
+typedef struct 
+{
+  uint32_t v[16];
+}
+shortsc25519;
+
+void sc25519_from32bytes(sc25519 *r, const unsigned char x[32]);
+
+void shortsc25519_from16bytes(shortsc25519 *r, const unsigned char x[16]);
+
+void sc25519_from64bytes(sc25519 *r, const unsigned char x[64]);
+
+void sc25519_from_shortsc(sc25519 *r, const shortsc25519 *x);
+
+void sc25519_to32bytes(unsigned char r[32], const sc25519 *x);
+
+int sc25519_iszero_vartime(const sc25519 *x);
+
+int sc25519_isshort_vartime(const sc25519 *x);
+
+int sc25519_lt_vartime(const sc25519 *x, const sc25519 *y);
+
+void sc25519_add(sc25519 *r, const sc25519 *x, const sc25519 *y);
+
+void sc25519_sub_nored(sc25519 *r, const sc25519 *x, const sc25519 *y);
+
+void sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y);
+
+void sc25519_mul_shortsc(sc25519 *r, const sc25519 *x, const shortsc25519 *y);
+
+/* Convert s into a representation of the form \sum_{i=0}^{84}r[i]2^3
+ * with r[i] in {-4,...,3}
+ */
+void sc25519_window3(signed char r[85], const sc25519 *s);
+
+/* Convert s into a representation of the form \sum_{i=0}^{50}r[i]2^5
+ * with r[i] in {-16,...,15}
+ */
+void sc25519_window5(signed char r[51], const sc25519 *s);
+
+void sc25519_2interleave2(unsigned char r[127], const sc25519 *s1, const sc25519 *s2);
+
+#endif
diff --git a/plugins/ssh-base/crypto/smult_curve25519_ref.c b/plugins/ssh-base/crypto/smult_curve25519_ref.c
new file mode 100644
index 0000000000000000000000000000000000000000..c514c8b85baf5db0d7fc1c26057c975500813c88
--- /dev/null
+++ b/plugins/ssh-base/crypto/smult_curve25519_ref.c
@@ -0,0 +1,265 @@
+/* $OpenBSD: smult_curve25519_ref.c,v 1.2 2013/11/02 22:02:14 markus Exp $ */
+/*
+version 20081011
+Matthew Dempsky
+Public domain.
+Derived from public domain code by D. J. Bernstein.
+*/
+
+static void add(unsigned int out[32],const unsigned int a[32],const unsigned int b[32])
+{
+  unsigned int j;
+  unsigned int u;
+  u = 0;
+  for (j = 0;j < 31;++j) { u += a[j] + b[j]; out[j] = u & 255; u >>= 8; }
+  u += a[31] + b[31]; out[31] = u;
+}
+
+static void sub(unsigned int out[32],const unsigned int a[32],const unsigned int b[32])
+{
+  unsigned int j;
+  unsigned int u;
+  u = 218;
+  for (j = 0;j < 31;++j) {
+    u += a[j] + 65280 - b[j];
+    out[j] = u & 255;
+    u >>= 8;
+  }
+  u += a[31] - b[31];
+  out[31] = u;
+}
+
+static void squeeze(unsigned int a[32])
+{
+  unsigned int j;
+  unsigned int u;
+  u = 0;
+  for (j = 0;j < 31;++j) { u += a[j]; a[j] = u & 255; u >>= 8; }
+  u += a[31]; a[31] = u & 127;
+  u = 19 * (u >> 7);
+  for (j = 0;j < 31;++j) { u += a[j]; a[j] = u & 255; u >>= 8; }
+  u += a[31]; a[31] = u;
+}
+
+static const unsigned int minusp[32] = {
+ 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128
+} ;
+
+static void freeze(unsigned int a[32])
+{
+  unsigned int aorig[32];
+  unsigned int j;
+  unsigned int negative;
+
+  for (j = 0;j < 32;++j) aorig[j] = a[j];
+  add(a,a,minusp);
+  negative = -(int)((a[31] >> 7) & 1);
+  for (j = 0;j < 32;++j) a[j] ^= negative & (aorig[j] ^ a[j]);
+}
+
+static void mult(unsigned int out[32],const unsigned int a[32],const unsigned int b[32])
+{
+  unsigned int i;
+  unsigned int j;
+  unsigned int u;
+
+  for (i = 0;i < 32;++i) {
+    u = 0;
+    for (j = 0;j <= i;++j) u += a[j] * b[i - j];
+    for (j = i + 1;j < 32;++j) u += 38 * a[j] * b[i + 32 - j];
+    out[i] = u;
+  }
+  squeeze(out);
+}
+
+static void mult121665(unsigned int out[32],const unsigned int a[32])
+{
+  unsigned int j;
+  unsigned int u;
+
+  u = 0;
+  for (j = 0;j < 31;++j) { u += 121665 * a[j]; out[j] = u & 255; u >>= 8; }
+  u += 121665 * a[31]; out[31] = u & 127;
+  u = 19 * (u >> 7);
+  for (j = 0;j < 31;++j) { u += out[j]; out[j] = u & 255; u >>= 8; }
+  u += out[j]; out[j] = u;
+}
+
+static void square(unsigned int out[32],const unsigned int a[32])
+{
+  unsigned int i;
+  unsigned int j;
+  unsigned int u;
+
+  for (i = 0;i < 32;++i) {
+    u = 0;
+    for (j = 0;j < i - j;++j) u += a[j] * a[i - j];
+    for (j = i + 1;j < i + 32 - j;++j)
+	    if (i + 32 - j < 32 && j < 32)
+		    u += 38 * a[j] * a[i + 32 - j];
+    u *= 2;
+    if ((i & 1) == 0) {
+      u += a[i / 2] * a[i / 2];
+      u += 38 * a[i / 2 + 16] * a[i / 2 + 16];
+    }
+    out[i] = u;
+  }
+  squeeze(out);
+}
+
+static void smc_select(unsigned int p[64],unsigned int q[64],const unsigned int r[64],const unsigned int s[64],unsigned int b)
+{
+  unsigned int j;
+  unsigned int t;
+  unsigned int bminus1;
+
+  bminus1 = b - 1;
+  for (j = 0;j < 64;++j) {
+    t = bminus1 & (r[j] ^ s[j]);
+    p[j] = s[j] ^ t;
+    q[j] = r[j] ^ t;
+  }
+}
+
+static void mainloop(unsigned int work[64],const unsigned char e[32])
+{
+  unsigned int xzm1[64];
+  unsigned int xzm[64];
+  unsigned int xzmb[64];
+  unsigned int xzm1b[64];
+  unsigned int xznb[64];
+  unsigned int xzn1b[64];
+  unsigned int a0[64];
+  unsigned int a1[64];
+  unsigned int b0[64];
+  unsigned int b1[64];
+  unsigned int c1[64];
+  unsigned int r[32];
+  unsigned int s[32];
+  unsigned int t[32];
+  unsigned int u[32];
+  unsigned int j;
+  unsigned int b;
+  int pos;
+
+  for (j = 0;j < 32;++j) xzm1[j] = work[j];
+  xzm1[32] = 1;
+  for (j = 33;j < 64;++j) xzm1[j] = 0;
+
+  xzm[0] = 1;
+  for (j = 1;j < 64;++j) xzm[j] = 0;
+
+  for (pos = 254;pos >= 0;--pos) {
+    b = e[pos / 8] >> (pos & 7);
+    b &= 1;
+    smc_select(xzmb,xzm1b,xzm,xzm1,b);
+    add(a0,xzmb,xzmb + 32);
+    sub(a0 + 32,xzmb,xzmb + 32);
+    add(a1,xzm1b,xzm1b + 32);
+    sub(a1 + 32,xzm1b,xzm1b + 32);
+    square(b0,a0);
+    square(b0 + 32,a0 + 32);
+    mult(b1,a1,a0 + 32);
+    mult(b1 + 32,a1 + 32,a0);
+    add(c1,b1,b1 + 32);
+    sub(c1 + 32,b1,b1 + 32);
+    square(r,c1 + 32);
+    sub(s,b0,b0 + 32);
+    mult121665(t,s);
+    add(u,t,b0);
+    mult(xznb,b0,b0 + 32);
+    mult(xznb + 32,s,u);
+    square(xzn1b,c1);
+    mult(xzn1b + 32,r,work);
+    smc_select(xzm,xzm1,xznb,xzn1b,b);
+  }
+
+  for (j = 0;j < 64;++j) work[j] = xzm[j];
+}
+
+static void recip(unsigned int out[32],const unsigned int z[32])
+{
+  unsigned int z2[32];
+  unsigned int z9[32];
+  unsigned int z11[32];
+  unsigned int z2_5_0[32];
+  unsigned int z2_10_0[32];
+  unsigned int z2_20_0[32];
+  unsigned int z2_50_0[32];
+  unsigned int z2_100_0[32];
+  unsigned int t0[32];
+  unsigned int t1[32];
+  int i;
+
+  /* 2 */ square(z2,z);
+  /* 4 */ square(t1,z2);
+  /* 8 */ square(t0,t1);
+  /* 9 */ mult(z9,t0,z);
+  /* 11 */ mult(z11,z9,z2);
+  /* 22 */ square(t0,z11);
+  /* 2^5 - 2^0 = 31 */ mult(z2_5_0,t0,z9);
+
+  /* 2^6 - 2^1 */ square(t0,z2_5_0);
+  /* 2^7 - 2^2 */ square(t1,t0);
+  /* 2^8 - 2^3 */ square(t0,t1);
+  /* 2^9 - 2^4 */ square(t1,t0);
+  /* 2^10 - 2^5 */ square(t0,t1);
+  /* 2^10 - 2^0 */ mult(z2_10_0,t0,z2_5_0);
+
+  /* 2^11 - 2^1 */ square(t0,z2_10_0);
+  /* 2^12 - 2^2 */ square(t1,t0);
+  /* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { square(t0,t1); square(t1,t0); }
+  /* 2^20 - 2^0 */ mult(z2_20_0,t1,z2_10_0);
+
+  /* 2^21 - 2^1 */ square(t0,z2_20_0);
+  /* 2^22 - 2^2 */ square(t1,t0);
+  /* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { square(t0,t1); square(t1,t0); }
+  /* 2^40 - 2^0 */ mult(t0,t1,z2_20_0);
+
+  /* 2^41 - 2^1 */ square(t1,t0);
+  /* 2^42 - 2^2 */ square(t0,t1);
+  /* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) { square(t1,t0); square(t0,t1); }
+  /* 2^50 - 2^0 */ mult(z2_50_0,t0,z2_10_0);
+
+  /* 2^51 - 2^1 */ square(t0,z2_50_0);
+  /* 2^52 - 2^2 */ square(t1,t0);
+  /* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) { square(t0,t1); square(t1,t0); }
+  /* 2^100 - 2^0 */ mult(z2_100_0,t1,z2_50_0);
+
+  /* 2^101 - 2^1 */ square(t1,z2_100_0);
+  /* 2^102 - 2^2 */ square(t0,t1);
+  /* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) { square(t1,t0); square(t0,t1); }
+  /* 2^200 - 2^0 */ mult(t1,t0,z2_100_0);
+
+  /* 2^201 - 2^1 */ square(t0,t1);
+  /* 2^202 - 2^2 */ square(t1,t0);
+  /* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { square(t0,t1); square(t1,t0); }
+  /* 2^250 - 2^0 */ mult(t0,t1,z2_50_0);
+
+  /* 2^251 - 2^1 */ square(t1,t0);
+  /* 2^252 - 2^2 */ square(t0,t1);
+  /* 2^253 - 2^3 */ square(t1,t0);
+  /* 2^254 - 2^4 */ square(t0,t1);
+  /* 2^255 - 2^5 */ square(t1,t0);
+  /* 2^255 - 21 */ mult(out,t1,z11);
+}
+
+int crypto_scalarmult_curve25519(unsigned char *q,
+  const unsigned char *n,
+  const unsigned char *p)
+{
+  unsigned int work[96];
+  unsigned char e[32];
+  unsigned int i;
+  for (i = 0;i < 32;++i) e[i] = n[i];
+  e[0] &= 248;
+  e[31] &= 127;
+  e[31] |= 64;
+  for (i = 0;i < 32;++i) work[i] = p[i];
+  mainloop(work,e);
+  recip(work + 32,work + 32);
+  mult(work + 64,work,work + 32);
+  freeze(work + 64);
+  for (i = 0;i < 32;++i) q[i] = work[64 + i];
+  return 0;
+}
diff --git a/plugins/ssh-base/include/lws-plugin-ssh.h b/plugins/ssh-base/include/lws-plugin-ssh.h
new file mode 100644
index 0000000000000000000000000000000000000000..4ba1165833ccf663a0063059bf538d512790f080
--- /dev/null
+++ b/plugins/ssh-base/include/lws-plugin-ssh.h
@@ -0,0 +1,364 @@
+/*
+ * libwebsockets - lws-plugin-ssh-base
+ *
+ * Copyright (C) 2017 Andy Green <andy@warmcat.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation:
+ *  version 2.1 of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#if !defined(__LWS_PLUGIN_SSH_H__)
+#define __LWS_PLUGIN_SSH_H__
+
+#define LWS_CALLBACK_SSH_UART_SET_RXFLOW (LWS_CALLBACK_USER + 800)
+
+#define LWS_SSH_OPS_VERSION 1
+
+struct lws_ssh_pty {
+	char term[16];
+	char *modes;
+	uint32_t width_ch;
+	uint32_t height_ch;
+	uint32_t width_px;
+	uint32_t height_px;
+	uint32_t modes_len;
+};
+
+#define SSHMO_TTY_OP_END 0 /* Indicates end of options. */
+#define SSHMO_VINTR	 1 /* Interrupt character; 255 if none.  Similarly
+			    * for the other characters.  Not all of these
+			    * characters are supported on all systems. */
+#define SSHMO_VQUIT	 2 /* The quit character (sends SIGQUIT signal on
+			    * POSIX systems). */
+#define SSHMO_VERASE	 3 /* Erase the character to left of the cursor. */
+#define SSHMO_VKILL	 4 /* Kill the current input line. */
+#define SSHMO_VEOF	 5 /* End-of-file character (sends EOF from the
+			    * terminal). */
+#define SSHMO_VEOL	 6 /* End-of-line character in addition to
+			    * carriage return and/or linefeed. */
+#define SSHMO_VEOL2	 7 /* Additional end-of-line character. */
+#define SSHMO_VSTART	 8 /* Continues paused output (normally
+			    * control-Q). */
+#define SSHMO_VSTOP	 9 /* Pauses output (normally control-S). */
+#define SSHMO_VSUSP	10 /* Suspends the current program. */
+#define SSHMO_VDSUSP	11 /* Another suspend character. */
+#define SSHMO_VREPRINT	12 /* Reprints the current input line. */
+#define SSHMO_VWERASE	13 /* Erases a word left of cursor. */
+#define SSHMO_VLNEXT	14 /* Enter the next character typed literally,
+			    * even if it is a special character */
+#define SSHMO_VFLUSH	15 /* Character to flush output. */
+#define SSHMO_VSWTCH	16 /* Switch to a different shell layer. */
+#define SSHMO_VSTATUS	17 /* Prints system status line (load, command,
+			    * pid, etc). */
+#define SSHMO_VDISCARD	18 /* Toggles the flushing of terminal output. */
+#define SSHMO_IGNPAR	30 /* The ignore parity flag.  The parameter
+			    * SHOULD be 0 if this flag is FALSE,
+			    * and 1 if it is TRUE. */
+#define SSHMO_PARMRK	31 /* Mark parity and framing errors. */
+#define SSHMO_INPCK	32 /* Enable checking of parity errors. */
+#define SSHMO_ISTRIP	33 /* Strip 8th bit off characters. */
+#define SSHMO_INLCR	34 /* Map NL into CR on input. */
+#define SSHMO_IGNCR	35 /* Ignore CR on input. */
+#define SSHMO_ICRNL	36 /* Map CR to NL on input. */
+#define SSHMO_IUCLC	37 /* Translate uppercase characters to lowercase. */
+#define SSHMO_IXON	38 /* Enable output flow control. */
+#define SSHMO_IXANY	39 /* Any char will restart after stop. */
+#define SSHMO_IXOFF	40 /* Enable input flow control. */
+#define SSHMO_IMAXBEL	41 /* Ring bell on input queue full. */
+#define SSHMO_ISIG	50 /* Enable signals INTR, QUIT, [D]SUSP. */
+#define SSHMO_ICANON	51 /* Canonicalize input lines. */
+#define SSHMO_XCASE	52 /* Enable input and output of uppercase
+			    * characters by preceding their lowercase
+			    * equivalents with "\". */
+#define SSHMO_ECHO	53 /* Enable echoing. */
+#define SSHMO_ECHOE	54 /* Visually erase chars. */
+#define SSHMO_ECHOK	55 /* Kill character discards current line. */
+#define SSHMO_ECHONL	56 /* Echo NL even if ECHO is off. */
+#define SSHMO_NOFLSH	57 /* Don't flush after interrupt. */
+#define SSHMO_TOSTOP	58 /* Stop background jobs from output. */
+#define SSHMO_IEXTEN	59 /* Enable extensions. */
+#define SSHMO_ECHOCTL	60 /* Echo control characters as ^(Char). */
+#define SSHMO_ECHOKE	61 /* Visual erase for line kill. */
+#define SSHMO_PENDIN	62 /* Retype pending input. */
+#define SSHMO_OPOST	70 /* Enable output processing. */
+#define SSHMO_OLCUC	71 /* Convert lowercase to uppercase. */
+#define SSHMO_ONLCR	72 /* Map NL to CR-NL. */
+#define SSHMO_OCRNL	73 /* Translate carriage return to newline (out). */
+#define SSHMO_ONOCR	74 /* Translate newline to CR-newline (out). */
+#define SSHMO_ONLRET	75 /* Newline performs a carriage return (out). */
+#define SSHMO_CS7	90 /* 7 bit mode. */
+#define SSHMO_CS8	91 /* 8 bit mode. */
+#define SSHMO_PARENB	92 /* Parity enable. */
+#define SSHMO_PARODD	93 /* Odd parity, else even. */
+#define SSHMO_TTY_OP_ISPEED	128 /* Specifies the input baud rate in
+				     * bits per second. */
+#define SSHMO_TTY_OP_OSPEED	129 /* Specifies the output baud rate in
+				     * bits per second. */
+
+/*! \defgroup ssh-base plugin: lws-ssh-base
+ * \ingroup Protocols-and-Plugins
+ *
+ * ##Plugin lws-ssh-base
+ *
+ * This is the interface to customize the ssh server per-vhost.  A pointer
+ * to your struct lws_ssh_ops with the members initialized is passed in using
+ * pvo when you create the vhost.  The pvo is attached to the protocol name
+ *
+ *  - "lws-ssh-base" - the ssh serving part
+ *
+ *  - "lws-telnetd-base" - the telnet serving part
+ *
+ *  This way you can have different instances of ssh servers wired up to
+ *  different IO and server keys per-vhost.
+ *
+ *  See also ./READMEs/README-plugin-sshd-base.md
+ */
+///@{
+
+struct lws_ssh_ops {
+	/**
+	 * channel_create() - Channel created
+	 *
+	 * \param wsi: raw wsi representing this connection
+	 * \param priv: pointer to void * you can allocate and attach to the
+	 *		channel
+	 *
+	 * Called when new channel created, *priv should be set to any
+	 * allocation your implementation needs
+	 *
+	 * You probably want to save the wsi inside your priv struct.  Calling
+	 * lws_callback_on_writable() on this wsi causes your ssh server
+	 * instance to call .tx_waiting() next time you can write something
+	 * to the client.
+	 */
+	int (*channel_create)(struct lws *wsi, void **priv);
+
+	/**
+	 * channel_destroy() - Channel is being destroyed
+	 *
+	 * \param priv: void * you set when channel was created (or NULL)
+	 *
+	 * Called when channel destroyed, priv should be freed if you allocated
+	 * into it.
+	 */
+	int (*channel_destroy)(void *priv);
+
+	/**
+	 * rx() - receive payload from peer
+	 *
+	 * \param priv:	void * you set when this channel was created
+	 * \param wsi:  struct lws * for the ssh connection
+	 * \param buf:	pointer to start of received data
+	 * \param len:	bytes of received data available at buf
+	 *
+	 * len bytes of payload from the peer arrived and is available at buf
+	 */
+	int (*rx)(void *priv, struct lws *wsi, const uint8_t *buf, uint32_t len);
+
+	/**
+	 * tx_waiting() - report if data waiting to transmit on the channel
+	 *
+	 * \param priv:	void * you set when this channel was created
+	 *
+	 * returns a bitmask of LWS_STDOUT and LWS_STDERR, with the bits set
+	 * if they have tx waiting to send, else 0 if nothing to send
+	 *
+	 * You should use one of the lws_callback_on_writable() family to
+	 * trigger the ssh protocol to ask if you have any tx waiting.
+	 *
+	 * Returning -1 from here will close the tcp connection to the client.
+	 */
+	int (*tx_waiting)(void *priv);
+
+	/**
+	 * tx() - provide data to send on the channel
+	 *
+	 * \param priv:	void * you set when this channel was created
+	 * \param stdch: LWS_STDOUT or LWS_STDERR
+	 * \param buf:	start of the buffer to copy the transmit data into
+	 * \param len: 	max length of the buffer in bytes
+	 *
+	 * copy and consume up to len bytes into *buf,
+	 * return the actual copied count.
+	 *
+	 * You should use one of the lws_callback_on_writable() family to
+	 * trigger the ssh protocol to ask if you have any tx waiting.  If you
+	 * do you will get calls here to fetch it, for each of LWS_STDOUT or
+	 * LWS_STDERR that were reported to be waiting by tx_waiting().
+	 */
+	size_t (*tx)(void *priv, int stdch, uint8_t *buf, size_t len);
+
+	/**
+	 * get_server_key() - retreive the secret keypair for this server
+	 *
+	 * \param wsi:  the wsi representing the connection to the client
+	 * \param buf:	start of the buffer to copy the keypair into
+	 * \param len: 	length of the buffer in bytes
+	 *
+	 * load the server key into buf, max len len.  Returns length of buf
+	 * set to key, or 0 if no key or other error.  If there is no key,
+	 * the error isn't fatal... the plugin will generate a random key and
+	 * store it using *get_server_key() for subsequent times.
+	 */
+	size_t (*get_server_key)(struct lws *wsi, uint8_t *buf, size_t len);
+
+	/**
+	 * set_server_key() - store the secret keypair of this server
+	 *
+	 * \param wsi:  the wsi representing the connection to the client
+	 * \param buf:	start of the buffer containing the keypair
+	 * \param len: 	length of the keypair in bytes
+	 *
+	 * store the server key in buf, length len, to nonvolatile stg.
+	 * Return length stored, 0 for fail.
+	 */
+	size_t (*set_server_key)(struct lws *wsi, uint8_t *buf, size_t len);
+
+	/**
+	 * set_env() - Set environment variable
+	 *
+	 * \param priv:	void * you set when this channel was created
+	 * \param name: env var name
+	 * \param value: value to set env var to
+	 *
+	 * Client requested to set environment var.  Return nonzero to fail.
+	 */
+	int (*set_env)(void *priv, const char *name, const char *value);
+
+	/**
+	 * exec() - spawn command and wire up stdin/out/err to ssh channel
+	 *
+	 * \param priv:	void * you set when this channel was created
+	 * \param wsi: the struct lws the connection belongs to
+	 * \param command:	string containing path to app and arguments
+	 *
+	 * Client requested to exec something.  Return nonzero to fail.
+	 */
+	int (*exec)(void *priv, struct lws *wsi, const char *command);
+
+	/**
+	 * shell() - Spawn shell that is appropriate for user
+	 *
+	 * \param priv:	void * you set when this channel was created
+	 * \param wsi: the struct lws the connection belongs to
+	 *
+	 * Spawn the appropriate shell for this user.  Return 0 for OK
+	 * or nonzero to fail.
+	 */
+	int (*shell)(void *priv, struct lws *wsi);
+
+	/**
+	 * pty_req() - Create a Pseudo-TTY as described in pty
+	 *
+	 * \param priv:	void * you set when this channel was created
+	 * \param pty:	pointer to struct describing the desired pty
+	 *
+	 * Client requested a pty.  Return nonzero to fail.
+	 */
+	int (*pty_req)(void *priv, struct lws_ssh_pty *pty);
+
+	/**
+	 * child_process_io() - Child process has IO
+	 *
+	 * \param priv:	void * you set when this channel was created
+	 * \param wsi: the struct lws the connection belongs to
+	 * \param args: information related to the cgi IO events
+	 *
+	 * Child process has IO
+	 */
+	int (*child_process_io)(void *priv, struct lws *wsi,
+				struct lws_cgi_args *args);
+
+	/**
+	 * child_process_io() - Child process has terminated
+	 *
+	 * \param priv:	void * you set when this channel was created
+	 * \param wsi: the struct lws the connection belongs to
+	 *
+	 * Child process has terminated
+	 */
+	int (*child_process_terminated)(void *priv, struct lws *wsi);
+
+	/**
+	 * disconnect_reason() - Optional notification why connection is lost
+	 *
+	 * \param reason: one of the SSH_DISCONNECT_ constants
+	 * \param desc: UTF-8 description of reason
+	 * \param desc_lang: RFC3066 language for description
+	 *
+	 * The remote peer may tell us why it's going to disconnect.  Handling
+	 * this is optional.
+	 */
+	void (*disconnect_reason)(uint32_t reason, const char *desc,
+				  const char *desc_lang);
+
+	/**
+	 * is_pubkey_authorized() - check if auth pubkey is valid for user
+	 *
+	 * \param username:	username the key attempted to authenticate
+	 * \param type:		"ssh-rsa"
+	 * \param peer:		start of Public key peer used to authenticate
+	 * \param peer_len:	length of Public key at peer
+	 *
+	 * We confirmed the client has the private key for this public key...
+	 * but is that keypair something authorized for this username on this
+	 * server? 0 = OK, 1 = fail
+	 *
+	 * Normally this checks for a copy of the same public key stored
+	 * somewhere out of band, it's the same procedure as openssh does
+	 * when looking in ~/.ssh/authorized_keys
+	 */
+	int (*is_pubkey_authorized)(const char *username,
+			const char *type, const uint8_t *peer, int peer_len);
+
+	/**
+	 * banner() - copy the connection banner to buffer
+	 *
+	 * \param buf:	start of the buffer to copy to
+	 * \param max_len: maximum number of bytes the buffer can hold
+	 * \param lang:	start of the buffer to copy language descriptor to
+	 * \param max_lang_len: maximum number of bytes lang can hold
+	 *
+	 * Copy the text banner to be returned to client on connect,
+	 * before auth, into buf.  The text should be in UTF-8.
+	 * if none wanted then leave .banner as NULL.
+	 *
+	 * lang should have a RFC3066 language descriptor like "en/US"
+	 * copied to it.
+	 *
+	 * Returns the number of bytes copies to buf.
+	 */
+	size_t (*banner)(char *buf, size_t max_len, char *lang,
+			 size_t max_lang_len);
+
+	/**
+	 * SSH version string sent to client (required)
+	 * By convention a string like "SSH-2.0-Libwebsockets"
+	 */
+	const char *server_string;
+
+	/**
+	 * set to the API version you support (current is in
+	 * LWS_SSH_OPS_VERSION) You should set it to an integer like 1,
+	 * that reflects the latest api at the time your code was written.  If
+	 * the ops api_version is not equal to the LWS_SSH_OPS_VERSION of the
+	 * plugin, it will error out at runtime.
+	 */
+	char api_version;
+};
+///@}
+
+#endif
+
diff --git a/plugins/ssh-base/include/lws-plugin-sshd-static-build-includes.h b/plugins/ssh-base/include/lws-plugin-sshd-static-build-includes.h
new file mode 100644
index 0000000000000000000000000000000000000000..e134b4f057335b3256250901f51997eefa87699b
--- /dev/null
+++ b/plugins/ssh-base/include/lws-plugin-sshd-static-build-includes.h
@@ -0,0 +1,18 @@
+/*
+ * If you are including the plugin into your code using static build, you
+ * can simplify it by just including this file, which will include all the
+ * related code in one step without you having to get involved in the detail.
+ */
+
+#define LWS_PLUGIN_STATIC
+
+#include "../crypto/chacha.c"
+#include "../crypto/ed25519.c"
+#include "../crypto/fe25519.c"
+#include "../crypto/ge25519.c"
+#include "../crypto/poly1305.c"
+#include "../crypto/sc25519.c"
+#include "../crypto/smult_curve25519_ref.c"
+#include "../kex-25519.c"
+#include "../sshd.c"
+#include "../telnet.c"
diff --git a/plugins/ssh-base/include/lws-ssh.h b/plugins/ssh-base/include/lws-ssh.h
new file mode 100644
index 0000000000000000000000000000000000000000..c74c517d71a4724db88a6117071083a17923b6b2
--- /dev/null
+++ b/plugins/ssh-base/include/lws-ssh.h
@@ -0,0 +1,600 @@
+/*
+ * libwebsockets - lws-plugin-ssh-base
+ *
+ * Copyright (C) 2017 Andy Green <andy@warmcat.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation:
+ *  version 2.1 of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#if !defined(__LWS_SSH_H__)
+#define __LWS_SSH_H__
+
+#if defined(LWS_WITH_MBEDTLS)
+#include "mbedtls/sha1.h"
+#include "mbedtls/sha256.h"
+#include "mbedtls/sha512.h"
+#include "mbedtls/rsa.h"
+#endif
+
+#include "lws-plugin-ssh.h"
+
+#define LWS_SIZE_EC25519	32
+#define LWS_SIZE_EC25519_PUBKEY 32
+#define LWS_SIZE_EC25519_PRIKEY 64
+
+#define LWS_SIZE_SHA256		32
+#define LWS_SIZE_SHA512		64
+
+#define LWS_SIZE_AES256_KEY	32
+#define LWS_SIZE_AES256_IV	12
+#define LWS_SIZE_AES256_MAC	16
+#define LWS_SIZE_AES256_BLOCK	16
+
+#define LWS_SIZE_CHACHA256_KEY	(2 * 32)
+#define POLY1305_TAGLEN		16
+#define POLY1305_KEYLEN		32
+
+#define crypto_hash_sha512_BYTES 64U
+
+#define PEEK_U64(p) \
+        (((uint64_t)(((const uint8_t *)(p))[0]) << 56) | \
+         ((uint64_t)(((const uint8_t *)(p))[1]) << 48) | \
+         ((uint64_t)(((const uint8_t *)(p))[2]) << 40) | \
+         ((uint64_t)(((const uint8_t *)(p))[3]) << 32) | \
+         ((uint64_t)(((const uint8_t *)(p))[4]) << 24) | \
+         ((uint64_t)(((const uint8_t *)(p))[5]) << 16) | \
+         ((uint64_t)(((const uint8_t *)(p))[6]) << 8) | \
+          (uint64_t)(((const uint8_t *)(p))[7]))
+#define PEEK_U32(p) \
+        (((uint32_t)(((const uint8_t *)(p))[0]) << 24) | \
+         ((uint32_t)(((const uint8_t *)(p))[1]) << 16) | \
+         ((uint32_t)(((const uint8_t *)(p))[2]) << 8) | \
+          (uint32_t)(((const uint8_t *)(p))[3]))
+#define PEEK_U16(p) \
+        (((uint16_t)(((const uint8_t *)(p))[0]) << 8) | \
+          (uint16_t)(((const uint8_t *)(p))[1]))
+
+#define POKE_U64(p, v) \
+        do { \
+                const uint64_t __v = (v); \
+                ((uint8_t *)(p))[0] = (__v >> 56) & 0xff; \
+                ((uint8_t *)(p))[1] = (__v >> 48) & 0xff; \
+                ((uint8_t *)(p))[2] = (__v >> 40) & 0xff; \
+                ((uint8_t *)(p))[3] = (__v >> 32) & 0xff; \
+                ((uint8_t *)(p))[4] = (__v >> 24) & 0xff; \
+                ((uint8_t *)(p))[5] = (__v >> 16) & 0xff; \
+                ((uint8_t *)(p))[6] = (__v >> 8) & 0xff; \
+                ((uint8_t *)(p))[7] = __v & 0xff; \
+        } while (0)
+#define POKE_U32(p, v) \
+        do { \
+                const uint32_t __v = (v); \
+                ((uint8_t *)(p))[0] = (__v >> 24) & 0xff; \
+                ((uint8_t *)(p))[1] = (__v >> 16) & 0xff; \
+                ((uint8_t *)(p))[2] = (__v >> 8) & 0xff; \
+                ((uint8_t *)(p))[3] = __v & 0xff; \
+        } while (0)
+#define POKE_U16(p, v) \
+        do { \
+                const uint16_t __v = (v); \
+                ((uint8_t *)(p))[0] = (__v >> 8) & 0xff; \
+                ((uint8_t *)(p))[1] = __v & 0xff; \
+        } while (0)
+
+
+enum {
+	SSH_MSG_DISCONNECT					= 1,
+	SSH_MSG_IGNORE						= 2,
+	SSH_MSG_UNIMPLEMENTED					= 3,
+	SSH_MSG_DEBUG						= 4,
+	SSH_MSG_SERVICE_REQUEST					= 5,
+	SSH_MSG_SERVICE_ACCEPT					= 6,
+	SSH_MSG_KEXINIT						= 20,
+	SSH_MSG_NEWKEYS						= 21,
+
+	/* 30 .. 49: KEX messages specific to KEX protocol */
+	SSH_MSG_KEX_ECDH_INIT					= 30,
+	SSH_MSG_KEX_ECDH_REPLY					= 31,
+
+	/* 50... userauth */
+
+	SSH_MSG_USERAUTH_REQUEST				= 50,
+	SSH_MSG_USERAUTH_FAILURE				= 51,
+	SSH_MSG_USERAUTH_SUCCESS				= 52,
+	SSH_MSG_USERAUTH_BANNER					= 53,
+
+	/* 60... publickey */
+
+	SSH_MSG_USERAUTH_PK_OK					= 60,
+
+	/* 80... connection */
+
+	SSH_MSG_GLOBAL_REQUEST					= 80,
+	SSH_MSG_REQUEST_SUCCESS					= 81,
+	SSH_MSG_REQUEST_FAILURE					= 82,
+
+	SSH_MSG_CHANNEL_OPEN					= 90,
+	SSH_MSG_CHANNEL_OPEN_CONFIRMATION			= 91,
+	SSH_MSG_CHANNEL_OPEN_FAILURE				= 92,
+	SSH_MSG_CHANNEL_WINDOW_ADJUST				= 93,
+	SSH_MSG_CHANNEL_DATA					= 94,
+	SSH_MSG_CHANNEL_EXTENDED_DATA				= 95,
+	SSH_MSG_CHANNEL_EOF					= 96,
+	SSH_MSG_CHANNEL_CLOSE					= 97,
+	SSH_MSG_CHANNEL_REQUEST					= 98,
+	SSH_MSG_CHANNEL_SUCCESS					= 99,
+	SSH_MSG_CHANNEL_FAILURE					= 100,
+
+	SSH_EXTENDED_DATA_STDERR				= 1,
+
+	SSH_CH_TYPE_SESSION					= 1,
+	SSH_CH_TYPE_SCP						= 2,
+	SSH_CH_TYPE_SFTP					= 3,
+
+	SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT		= 1,
+	SSH_DISCONNECT_PROTOCOL_ERROR				= 2,
+	SSH_DISCONNECT_KEY_EXCHANGE_FAILED			= 3,
+	SSH_DISCONNECT_RESERVED					= 4,
+	SSH_DISCONNECT_MAC_ERROR				= 5,
+	SSH_DISCONNECT_COMPRESSION_ERROR			= 6,
+	SSH_DISCONNECT_SERVICE_NOT_AVAILABLE			= 7,
+	SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED		= 8,
+	SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE			= 9,
+	SSH_DISCONNECT_CONNECTION_LOST				= 10,
+	SSH_DISCONNECT_BY_APPLICATION				= 11,
+	SSH_DISCONNECT_TOO_MANY_CONNECTIONS			= 12,
+	SSH_DISCONNECT_AUTH_CANCELLED_BY_USER			= 13,
+	SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE		= 14,
+	SSH_DISCONNECT_ILLEGAL_USER_NAME			= 15,
+	
+	SSH_OPEN_ADMINISTRATIVELY_PROHIBITED			= 1,
+	SSH_OPEN_CONNECT_FAILED					= 2,
+	SSH_OPEN_UNKNOWN_CHANNEL_TYPE				= 3,
+	SSH_OPEN_RESOURCE_SHORTAGE				= 4,
+
+	KEX_STATE_EXPECTING_CLIENT_OFFER			= 0,
+	KEX_STATE_REPLIED_TO_OFFER,
+	KEX_STATE_CRYPTO_INITIALIZED,
+
+	SSH_KEYIDX_IV						= 0,
+	SSH_KEYIDX_ENC,
+	SSH_KEYIDX_INTEG,
+
+	/* things we may write on the connection */
+
+	SSH_WT_NONE						= 0,
+	SSH_WT_VERSION,
+	SSH_WT_OFFER,
+	SSH_WT_OFFER_REPLY,
+	SSH_WT_SEND_NEWKEYS,
+	SSH_WT_UA_ACCEPT,
+	SSH_WT_UA_FAILURE,
+	SSH_WT_UA_BANNER,
+	SSH_WT_UA_PK_OK,
+	SSH_WT_UA_SUCCESS,
+	SSH_WT_CH_OPEN_CONF,
+	SSH_WT_CH_FAILURE,
+	SSH_WT_CHRQ_SUCC,
+	SSH_WT_CHRQ_FAILURE,
+	SSH_WT_SCP_ACK_OKAY,
+	SSH_WT_SCP_ACK_ERROR,
+	SSH_WT_CH_CLOSE,
+	SSH_WT_CH_EOF,
+	SSH_WT_WINDOW_ADJUST,
+
+	/* RX parser states */
+
+	SSH_INITIALIZE_TRANSIENT				= 0,
+	SSHS_IDSTRING,
+	SSHS_IDSTRING_CR,
+	SSHS_MSG_LEN,
+	SSHS_MSG_PADDING,
+	SSHS_MSG_ID,
+	SSH_KEX_STATE_COOKIE,
+	SSH_KEX_NL_KEX_ALGS_LEN,
+	SSH_KEX_NL_KEX_ALGS,
+	SSH_KEX_NL_SHK_ALGS_LEN,
+	SSH_KEX_NL_SHK_ALGS,
+	SSH_KEX_NL_EACTS_ALGS_LEN,
+	SSH_KEX_NL_EACTS_ALGS,
+	SSH_KEX_NL_EASTC_ALGS_LEN,
+	SSH_KEX_NL_EASTC_ALGS,
+	SSH_KEX_NL_MACTS_ALGS_LEN,
+	SSH_KEX_NL_MACTS_ALGS,
+	SSH_KEX_NL_MASTC_ALGS_LEN,
+	SSH_KEX_NL_MASTC_ALGS,
+	SSH_KEX_NL_CACTS_ALGS_LEN,
+	SSH_KEX_NL_CACTS_ALGS,
+	SSH_KEX_NL_CASTC_ALGS_LEN,
+	SSH_KEX_NL_CASTC_ALGS,
+	SSH_KEX_NL_LCTS_ALGS_LEN,
+	SSH_KEX_NL_LCTS_ALGS,
+	SSH_KEX_NL_LSTC_ALGS_LEN,
+	SSH_KEX_NL_LSTC_ALGS,
+	SSH_KEX_FIRST_PKT,
+	SSH_KEX_RESERVED,
+
+	SSH_KEX_STATE_ECDH_KEYLEN,
+	SSH_KEX_STATE_ECDH_Q_C,
+
+	SSHS_MSG_EAT_PADDING,
+	SSH_KEX_STATE_SKIP,
+
+	SSHS_GET_STRING_LEN,
+	SSHS_GET_STRING,
+	SSHS_GET_STRING_LEN_ALLOC,
+	SSHS_GET_STRING_ALLOC,
+	SSHS_DO_SERVICE_REQUEST,
+
+	SSHS_DO_UAR_SVC,
+	SSHS_DO_UAR_PUBLICKEY,
+	SSHS_NVC_DO_UAR_CHECK_PUBLICKEY,
+	SSHS_DO_UAR_SIG_PRESENT,
+	SSHS_NVC_DO_UAR_ALG,
+	SSHS_NVC_DO_UAR_PUBKEY_BLOB,
+	SSHS_NVC_DO_UAR_SIG,
+
+	SSHS_GET_U32,
+
+	SSHS_NVC_CHOPEN_TYPE,
+	SSHS_NVC_CHOPEN_SENDER_CH,
+	SSHS_NVC_CHOPEN_WINSIZE,
+	SSHS_NVC_CHOPEN_PKTSIZE,
+
+	SSHS_NVC_CHRQ_RECIP,
+	SSHS_NVC_CHRQ_TYPE,
+	SSHS_CHRQ_WANT_REPLY,
+        SSHS_NVC_CHRQ_TERM,
+        SSHS_NVC_CHRQ_TW,
+        SSHS_NVC_CHRQ_TH,
+	SSHS_NVC_CHRQ_TWP,
+        SSHS_NVC_CHRQ_THP,
+        SSHS_NVC_CHRQ_MODES,
+
+	SSHS_NVC_CHRQ_ENV_NAME,
+	SSHS_NVC_CHRQ_ENV_VALUE,
+
+	SSHS_NVC_CHRQ_EXEC_CMD,
+
+	SSHS_NVC_CHRQ_SUBSYSTEM,
+
+	SSHS_NVC_CH_EOF,
+	SSHS_NVC_CH_CLOSE,
+
+	SSHS_NVC_CD_RECIP,
+	SSHS_NVC_CD_DATA,
+	SSHS_NVC_CD_DATA_ALLOC,
+
+	SSHS_NVC_WA_RECIP,
+	SSHS_NVC_WA_ADD,
+
+	SSHS_NVC_DISCONNECT_REASON,
+	SSHS_NVC_DISCONNECT_DESC,
+	SSHS_NVC_DISCONNECT_LANG,
+
+	SSHS_SCP_COLLECTSTR			= 0,
+	SSHS_SCP_PAYLOADIN			= 1,
+
+
+	/* from https://tools.ietf.org/html/draft-ietf-secsh-filexfer-13 */
+
+	SECSH_FILEXFER_VERSION			= 6,
+
+	/* sftp packet types */
+
+	SSH_FXP_INIT				= 1,
+	SSH_FXP_VERSION				= 2,
+	SSH_FXP_OPEN				= 3,
+	SSH_FXP_CLOSE				= 4,
+	SSH_FXP_READ				= 5,
+	SSH_FXP_WRITE				= 6,
+	SSH_FXP_LSTAT				= 7,
+	SSH_FXP_FSTAT				= 8,
+	SSH_FXP_SETSTAT				= 9,
+	SSH_FXP_FSETSTAT			= 10,
+	SSH_FXP_OPENDIR				= 11,
+	SSH_FXP_READDIR				= 12,
+	SSH_FXP_REMOVE				= 13,
+	SSH_FXP_MKDIR				= 14,
+	SSH_FXP_RMDIR				= 15,
+	SSH_FXP_REALPATH			= 16,
+	SSH_FXP_STAT				= 17,
+	SSH_FXP_RENAME				= 18,
+	SSH_FXP_READLINK			= 19,
+	SSH_FXP_LINK				= 21,
+	SSH_FXP_BLOCK				= 22,
+	SSH_FXP_UNBLOCK				= 23,
+	SSH_FXP_STATUS				= 101,
+	SSH_FXP_HANDLE				= 102,
+	SSH_FXP_DATA				= 103,
+	SSH_FXP_NAME				= 104,
+	SSH_FXP_ATTRS				= 105,
+	SSH_FXP_EXTENDED			= 200,
+	SSH_FXP_EXTENDED_REPLY			= 201,
+
+	/* sftp return codes */
+
+	SSH_FX_OK				= 0,
+	SSH_FX_EOF				= 1,
+	SSH_FX_NO_SUCH_FILE			= 2,
+	SSH_FX_PERMISSION_DENIED		= 3,
+	SSH_FX_FAILURE				= 4,
+	SSH_FX_BAD_MESSAGE			= 5,
+	SSH_FX_NO_CONNECTION			= 6,
+	SSH_FX_CONNECTION_LOST			= 7,
+	SSH_FX_OP_UNSUPPORTED			= 8,
+	SSH_FX_INVALID_HANDLE			= 9,
+	SSH_FX_NO_SUCH_PATH			= 10,
+	SSH_FX_FILE_ALREADY_EXISTS		= 11,
+	SSH_FX_WRITE_PROTECT			= 12,
+	SSH_FX_NO_MEDIA				= 13,
+	SSH_FX_NO_SPACE_ON_FILESYSTEM		= 14,
+	SSH_FX_QUOTA_EXCEEDED			= 15,
+	SSH_FX_UNKNOWN_PRINCIPAL		= 16,
+	SSH_FX_LOCK_CONFLICT			= 17,
+	SSH_FX_DIR_NOT_EMPTY			= 18,
+	SSH_FX_NOT_A_DIRECTORY			= 19,
+	SSH_FX_INVALID_FILENAME			= 20,
+	SSH_FX_LINK_LOOP			= 21,
+	SSH_FX_CANNOT_DELETE			= 22,
+	SSH_FX_INVALID_PARAMETER		= 23,
+	SSH_FX_FILE_IS_A_DIRECTORY		= 24,
+	SSH_FX_BYTE_RANGE_LOCK_CONFLICT		= 25,
+	SSH_FX_BYTE_RANGE_LOCK_REFUSED		= 26,
+	SSH_FX_DELETE_PENDING			= 27,
+	SSH_FX_FILE_CORRUPT			= 28,
+	SSH_FX_OWNER_INVALID			= 29,
+	SSH_FX_GROUP_INVALID			= 30,
+	SSH_FX_NO_MATCHING_BYTE_RANGE_LOCK	= 31,
+
+
+	SSH_PENDING_TIMEOUT_CONNECT_TO_SUCCESSFUL_AUTH =
+			PENDING_TIMEOUT_USER_REASON_BASE + 0,
+
+	SSH_AUTH_STATE_NO_AUTH			= 0,
+	SSH_AUTH_STATE_GAVE_AUTH_IGNORE_REQS	= 1,
+};
+
+#define LWS_SSH_INITIAL_WINDOW 16384
+
+struct lws_ssh_userauth {
+	struct lws_genhash_ctx hash_ctx;
+	char *username;
+	char *service;
+	char *alg;
+	uint8_t *pubkey;
+	uint32_t pubkey_len;
+	uint8_t *sig;
+	uint32_t sig_len;
+	char sig_present;
+};
+
+struct lws_ssh_keys {
+	/* 3 == SSH_KEYIDX_IV (len=4), SSH_KEYIDX_ENC, SSH_KEYIDX_INTEG */
+	uint8_t key[3][LWS_SIZE_CHACHA256_KEY];
+
+	/* opaque allocation made when cipher activated */
+	void *cipher;
+
+	uint8_t MAC_length;
+	uint8_t padding_alignment; /* block size */
+	uint8_t valid:1;
+	uint8_t full_length:1;
+};
+
+struct lws_kex {
+	uint8_t kex_r[256];
+	uint8_t Q_C[LWS_SIZE_EC25519]; /* client eph public key aka 'e' */
+	uint8_t eph_pri_key[LWS_SIZE_EC25519]; /* server eph private key */
+	uint8_t Q_S[LWS_SIZE_EC25519]; /* server ephemeral public key */
+	uint8_t kex_cookie[16];
+	uint8_t *I_C; /* malloc'd copy of client KEXINIT payload */
+	uint8_t *I_S; /* malloc'd copy of server KEXINIT payload */
+	uint32_t I_C_payload_len;
+	uint32_t I_C_alloc_len;
+	uint32_t I_S_payload_len;
+	uint32_t kex_r_len;
+	uint8_t match_bitfield;
+	uint8_t newkeys; /* which sides newkeys have been applied */
+
+	struct lws_ssh_keys keys_next_cts;
+	struct lws_ssh_keys keys_next_stc;
+};
+
+struct lws_subprotocol_scp {
+	char fp[128];
+	uint64_t len;
+	uint32_t attr;
+	char cmd;
+	char ips;
+};
+
+typedef union {
+	struct lws_subprotocol_scp scp;
+} lws_subprotocol;
+
+struct lws_ssh_channel {
+	struct lws_ssh_channel *next;
+	lws_subprotocol *sub; /* NULL, or allocated subprotocol state */
+	void *priv; /* owned by user code */
+	int type;
+	uint32_t server_ch;
+	uint32_t sender_ch;
+	int32_t window;
+	int32_t peer_window_est;
+	uint32_t max_pkt;
+
+	uint32_t spawn_pid;
+
+	uint8_t had_eof:1;
+	uint8_t sent_close:1;
+	uint8_t received_close:1;
+};
+
+struct per_vhost_data__sshd;
+
+struct per_session_data__sshd {
+	struct per_session_data__sshd *next;
+	struct per_vhost_data__sshd *vhd;
+	struct lws *wsi;
+
+	struct lws_kex *kex;
+	char *disconnect_desc;
+
+	uint8_t K[LWS_SIZE_EC25519]; /* shared secret */
+	uint8_t session_id[LWS_SIZE_SHA256]; /* H from first working KEX */
+	char name[64];
+	char last_auth_req_username[32];
+	char last_auth_req_service[32];
+
+	struct lws_ssh_keys active_keys_cts;
+	struct lws_ssh_keys active_keys_stc;
+	struct lws_ssh_userauth *ua;
+	struct lws_ssh_channel *ch_list;
+	struct lws_ssh_channel *ch_temp;
+
+	uint8_t *last_alloc;
+
+	union {
+		struct lws_ssh_pty pty;
+		char aux[64];
+	} args;
+
+	uint32_t ssh_sequence_ctr_cts;
+	uint32_t ssh_sequence_ctr_stc;
+
+	uint64_t payload_bytes_cts;
+	uint64_t payload_bytes_stc;
+
+	uint32_t disconnect_reason;
+
+	char V_C[64]; /* Client version String */
+	uint8_t packet_assembly[2048];
+	uint32_t pa_pos;
+
+	uint32_t msg_len;
+	uint32_t pos;
+	uint32_t len;
+	uint32_t ctr;
+	uint32_t npos;
+	uint32_t reason;
+	uint32_t channel_doing_spawn;
+	int next_ch_num;
+
+	uint8_t K_S[LWS_SIZE_EC25519]; /* server public key */
+
+	uint32_t copy_to_I_C:1;
+	uint32_t okayed_userauth:1;
+	uint32_t sent_banner:1;
+	uint32_t seen_auth_req_before:1;
+	uint32_t serviced_stderr_last:1;
+	uint32_t kex_state;
+	uint32_t chrq_server_port;
+	uint32_t ch_recip;
+	uint32_t count_auth_attempts;
+
+	char parser_state;
+	char state_after_string;
+	char first_coming;
+	uint8_t rq_want_reply;
+	uint8_t ssh_auth_state;
+
+	uint8_t msg_id;
+	uint8_t msg_padding;
+	uint8_t write_task[4];
+	struct lws_ssh_channel *write_channel[4];
+	uint8_t wt_head, wt_tail;
+};
+
+struct per_vhost_data__sshd {
+	struct lws_context *context;
+	struct lws_vhost *vhost;
+	const struct lws_protocols *protocol;
+	struct per_session_data__sshd *live_pss_list;
+	const struct lws_ssh_ops *ops;
+};
+
+
+struct host_keys {
+	uint8_t *data;
+	uint32_t len;
+};
+
+extern struct host_keys host_keys[];
+
+extern int
+crypto_scalarmult_curve25519(unsigned char *q, const unsigned char *n,
+			     const unsigned char *p);
+
+extern int
+ed25519_key_parse(uint8_t *p, size_t len, char *type, size_t type_len,
+                  uint8_t *pub, uint8_t *pri);
+
+extern int
+kex_ecdh(struct per_session_data__sshd *pss, uint8_t *result, uint32_t *plen);
+
+extern uint32_t
+lws_g32(uint8_t **p);
+
+extern uint32_t
+lws_p32(uint8_t *p, uint32_t v);
+
+extern void
+explicit_bzero(void *p, size_t len);
+
+extern int
+timingsafe_bcmp(const void *a, const void *b, uint32_t len);
+
+extern const char *lws_V_S;
+
+extern int
+lws_chacha_activate(struct lws_ssh_keys *keys);
+
+extern void
+lws_chacha_destroy(struct lws_ssh_keys *keys);
+
+extern uint32_t
+lws_chachapoly_get_length(struct lws_ssh_keys *keys, uint32_t seq,
+			  const uint8_t *in4);
+
+extern void
+poly1305_auth(u_char out[POLY1305_TAGLEN], const u_char *m, size_t inlen,
+    const u_char key[POLY1305_KEYLEN]);
+
+extern int
+lws_chacha_decrypt(struct lws_ssh_keys *keys, uint32_t seq,
+		   const uint8_t *ct, uint32_t len, uint8_t *pt);
+extern int
+lws_chacha_encrypt(struct lws_ssh_keys *keys, uint32_t seq,
+		   const uint8_t *ct, uint32_t len, uint8_t *pt);
+
+extern void
+lws_pad_set_length(struct per_session_data__sshd *pss, void *start, uint8_t **p,
+		   struct lws_ssh_keys *keys);
+
+extern size_t
+get_gen_server_key_25519(struct per_session_data__sshd *pss, uint8_t *b, size_t len);
+
+extern int
+crypto_sign_ed25519(unsigned char *sm, unsigned long long *smlen,
+		    const unsigned char *m, size_t mlen,
+		    const unsigned char *sk);
+
+extern int
+crypto_sign_ed25519_keypair(struct lws_context *context, uint8_t *pk,
+			    uint8_t *sk);
+
+#endif
diff --git a/plugins/ssh-base/kex-25519.c b/plugins/ssh-base/kex-25519.c
new file mode 100644
index 0000000000000000000000000000000000000000..7223ac194892465bbda0b78f1ebd06551ad04f1a
--- /dev/null
+++ b/plugins/ssh-base/kex-25519.c
@@ -0,0 +1,546 @@
+/*
+ * libwebsockets - lws-plugin-ssh-base - kex-25519.c
+ *
+ * Copyright (C) 2017 Andy Green <andy@warmcat.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation:
+ *  version 2.1 of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+#include "libwebsockets.h"
+#include "lws-ssh.h"
+
+#include <string.h>
+
+/*
+ * ssh-keygen -t ed25519
+ * head -n-1 srv-key-25519 | tail -n +2 | base64 -d | hexdump -C
+ */
+
+static void
+lws_sized_blob(uint8_t **p, void *blob, uint32_t len)
+{
+	lws_p32((*p), len);
+	*p += 4;
+	memcpy(*p, blob, len);
+	*p += len;
+}
+
+static const char key_leadin[] = "openssh-key-v1\x00\x00\x00\x00\x04none"
+				 "\x00\x00\x00\x04none\x00"
+				 "\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x33"
+				 "\x00\x00\x00\x0bssh-ed25519\x00\x00\x00\x20",
+		  key_sep[] = 	 "\x00\x00\x00\x90\xb1\x4f\xa7\x28"
+				 "\xb1\x4f\xa7\x28\x00\x00\x00\x0bssh-ed25519"
+				 "\x00\x00\x00\x20",
+		  key_privl[] =	 "\x00\x00\x00\x40",
+		  key_trail[] =  "\x00\x00\x00\x0cself-gen@cbl\x01";
+
+static size_t
+lws_gen_server_key_ed25519(struct lws_context *context, uint8_t *buf256,
+			   size_t max_len)
+{
+	uint8_t *p = buf256 + sizeof(key_leadin) - 1;
+
+	if (max_len < sizeof(key_leadin) - 1 + 32 + sizeof(key_sep) - 1 + 32 +
+		      sizeof(key_privl) - 1 + 64 + sizeof(key_trail) - 1)
+		return 0;
+
+	memcpy(buf256, key_leadin, sizeof(key_leadin) - 1);
+	crypto_sign_ed25519_keypair(context, p, p + 32 + sizeof(key_sep) - 1 +
+				    32 + sizeof(key_privl) - 1);
+	memcpy(p + 32 + sizeof(key_sep) - 1, p, 32);
+	p += 32;
+	memcpy(p, key_sep, sizeof(key_sep) - 1);
+	p += sizeof(key_sep) - 1 + 32;
+	memcpy(p, key_privl, sizeof(key_privl) - 1);
+	p += sizeof(key_privl) - 1 + 64;
+	memcpy(p, key_trail, sizeof(key_trail) - 1);
+	p += sizeof(key_trail) - 1;
+
+	lwsl_notice("%s: Generated key len %ld\n", __func__, (long)(p - buf256));
+
+	return p - buf256;
+}
+
+static int
+lws_mpint_rfc4251(uint8_t *dest, const uint8_t *src, int bytes, int uns)
+{
+	uint8_t *odest = dest;
+
+	while (!*src && bytes > 1) {
+		src++;
+		bytes--;
+	}
+
+	if (!*src) {
+		*dest++ = 0;
+		*dest++ = 0;
+		*dest++ = 0;
+		*dest++ = 0;
+
+		return 4;
+	}
+
+	if (uns && (*src) & 0x80)
+		bytes++;
+
+	*dest++ = bytes >> 24;
+	*dest++ = bytes >> 16;
+	*dest++ = bytes >> 8;
+	*dest++ = bytes;
+
+	if (uns && (*src) & 0x80) {
+		*dest++ = 0;
+		bytes--;
+	}
+
+	while (bytes--)
+		*dest++ = *src++;
+
+	return dest - odest;
+}
+
+int
+ed25519_key_parse(uint8_t *p, size_t len, char *type, size_t type_len,
+		  uint8_t *pub, uint8_t *pri)
+{
+	uint32_t l, publ, m;
+	uint8_t *op = p;
+
+	if (len < 180)
+		return 1;
+
+	if (memcmp(p, "openssh-key-v1", 14))
+		return 2;
+
+	p += 15;
+
+	l = lws_g32(&p); /* ciphername */
+	if (l != 4 || memcmp(p, "none", 4))
+		return 3;
+	p += l;
+
+	l = lws_g32(&p); /* kdfname */
+	if (l != 4 || memcmp(p, "none", 4))
+		return 4;
+	p += l;
+
+	l = lws_g32(&p); /* kdfoptions */
+	if (l)
+		return 5;
+
+	l = lws_g32(&p); /* number of keys */
+	if (l != 1)
+		return 6;
+
+	publ = lws_g32(&p); /* length of pubkey block */
+	if ((p - op) + publ >= len)
+		return 7;
+
+	l = lws_g32(&p); /* key type length */
+	if (l > 31)
+		return 8;
+	m = l;
+	if (m > type_len)
+		m = type_len -1 ;
+	strncpy(type, (const char *)p, m);
+	type[m] = '\0';
+
+	p += l;
+	l = lws_g32(&p); /* pub key length */
+	if (l != 32)
+		return 10;
+
+	p += l;
+
+	publ = lws_g32(&p); /* length of private key block */
+	if ((p - op) + publ != len)
+		return 11;
+
+	l = lws_g32(&p); /* checkint 1 */
+	if (lws_g32(&p) != l) /* must match checkint 2 */
+		return 12;
+
+	l = lws_g32(&p); /* key type length */
+
+	p += l;
+	l = lws_g32(&p); /* public key part length */
+	if (l != LWS_SIZE_EC25519_PUBKEY)
+		return 15;
+
+	if (pub)
+		memcpy(pub, p, LWS_SIZE_EC25519_PUBKEY);
+	p += l;
+	l = lws_g32(&p); /* private key part length */
+	if (l != LWS_SIZE_EC25519_PRIKEY)
+		return 16;
+
+	if (pri)
+		memcpy(pri, p, LWS_SIZE_EC25519_PRIKEY);
+
+	return 0;
+}
+
+static int
+_genhash_update_len(struct lws_genhash_ctx *ctx, const void *input, size_t ilen)
+{
+	uint32_t be;
+
+	lws_p32((uint8_t *)&be, ilen);
+
+	if (lws_genhash_update(ctx, (uint8_t *)&be, 4))
+		return 1;
+	if (lws_genhash_update(ctx, input, ilen))
+		return 1;
+
+	return 0;
+}
+
+static int
+kex_ecdh_dv(uint8_t *dest, int dest_len, const uint8_t *kbi, int kbi_len,
+	    const uint8_t *H, char c, const uint8_t *session_id)
+{
+	uint8_t pool[LWS_SIZE_SHA256];
+	struct lws_genhash_ctx ctx;
+	int n = 0, m;
+
+	/*
+	 * Key data MUST be taken from the beginning of the hash output.
+	 * As many bytes as needed are taken from the beginning of the hash
+	 * value.
+	 *
+	 * If the key length needed is longer than the output of the HASH,
+	 * the key is extended by computing HASH of the concatenation of K
+	 * and H and the entire key so far, and appending the resulting
+	 * bytes (as many as HASH generates) to the key.  This process is
+	 * repeated until enough key material is available; the key is taken
+	 * from the beginning of this value.  In other words:
+	 *
+	 * K1 = HASH(K || H || X || session_id)   (X is e.g., "A")
+	 * K2 = HASH(K || H || K1)
+	 * K3 = HASH(K || H || K1 || K2)
+	 *      ...
+	 * key = K1 || K2 || K3 || ...
+	 */
+
+	while (n < dest_len) {
+
+		if (lws_genhash_init(&ctx, LWS_GENHASH_TYPE_SHA256))
+			return 1;
+
+		if (lws_genhash_update(&ctx, kbi, kbi_len))
+			goto hash_failed;
+		if (lws_genhash_update(&ctx, H, LWS_SIZE_SHA256))
+			goto hash_failed;
+
+		if (!n) {
+			if (lws_genhash_update(&ctx, (void *)&c, 1))
+				goto hash_failed;
+			if (lws_genhash_update(&ctx, session_id,
+					      LWS_SIZE_EC25519))
+				goto hash_failed;
+		} else
+			if (lws_genhash_update(&ctx, pool, LWS_SIZE_EC25519))
+				goto hash_failed;
+
+		lws_genhash_destroy(&ctx, pool);
+
+		m = LWS_SIZE_EC25519;
+		if (m > (dest_len - n))
+			m = dest_len - n;
+
+		memcpy(dest, pool, m);
+		n += m;
+		dest += m;
+	}
+
+	return 0;
+
+hash_failed:
+	lws_genhash_destroy(&ctx, NULL);
+
+	return 1;
+}
+
+
+static const unsigned char basepoint[32] = { 9 };
+
+size_t
+get_gen_server_key_25519(struct per_session_data__sshd *pss, uint8_t *b,
+			 size_t len)
+{
+	size_t s, mylen;
+
+	mylen = pss->vhd->ops->get_server_key(pss->wsi, b, len);
+	if (mylen)
+		return mylen;
+
+	/* create one then */
+	lwsl_notice("Generating server hostkey\n");
+	s = lws_gen_server_key_ed25519(pss->vhd->context, b, len);
+	lwsl_notice("  gen key len %ld\n", (long)s);
+	if (!s)
+		return 0;
+	/* set the key */
+	if (!pss->vhd->ops->set_server_key(pss->wsi, b, s))
+		return 0;
+
+	/* new key stored OK */
+
+	return s;
+}
+
+int
+kex_ecdh(struct per_session_data__sshd *pss, uint8_t *reply, uint32_t *plen)
+{
+	uint8_t pri_key[64], temp[64], payload_sig[64 + 32], a, *lp, kbi[64];
+	struct lws_kex *kex = pss->kex;
+	struct lws_genhash_ctx ctx;
+        unsigned long long smlen;
+	uint8_t *p = reply + 5;
+	uint32_t be, kbi_len;
+	uint8_t servkey[256];
+	char keyt[33];
+	int r, c;
+
+	r = get_gen_server_key_25519(pss, servkey, sizeof(servkey));
+	if (!r) {
+		lwsl_err("%s: Failed to get or gen server key\n", __func__);
+
+		return 1;
+	}
+
+	r = ed25519_key_parse(servkey, r, keyt, sizeof(keyt),
+			      pss->K_S /* public key */, pri_key);
+	if (r) {
+		lwsl_notice("%s: server key parse failed: %d\n", __func__, r);
+
+		return 1;
+	}
+	keyt[32] = '\0';
+
+	lwsl_info("Server key type: %s\n", keyt);
+
+	/*
+	 * 1) Generate ephemeral key pair [ eph_pri_key | kex->Q_S ]
+	 * 2) Compute shared secret.
+	 * 3) Generate and sign exchange hash.
+	 *
+	 * 1) A 32 bytes private key should be generated for each new
+	 *    connection, using a secure PRNG. The following actions
+	 *    must be done on the private key:
+	 *
+	 *     mysecret[0] &= 248;
+	 *     mysecret[31] &= 127;
+	 *     mysecret[31] |= 64;
+	 */
+	lws_get_random(pss->vhd->context, kex->eph_pri_key, LWS_SIZE_EC25519);
+	kex->eph_pri_key[0] &= 248;
+	kex->eph_pri_key[31] &= 127;
+	kex->eph_pri_key[31] |= 64;
+
+	/*
+	 * 2) The public key is calculated using the cryptographic scalar
+	 *    multiplication:
+	 *
+	 *     const unsigned char privkey[32];
+	 *     unsigned char pubkey[32];
+	 *
+	 *     crypto_scalarmult (pubkey, privkey, basepoint);
+	 */
+	crypto_scalarmult_curve25519(kex->Q_S, kex->eph_pri_key, basepoint);
+
+	a = 0;
+	for (r = 0; r < sizeof(kex->Q_S); r++)
+		a |= kex->Q_S[r];
+	if (!a) {
+		lwsl_notice("all zero pubkey\n");
+		return SSH_DISCONNECT_KEY_EXCHANGE_FAILED;
+	}
+
+	/*
+	 * The shared secret, k, is defined in SSH specifications to be a big
+	 * integer.  This number is calculated using the following procedure:
+	 *
+	 * X is the 32 bytes point obtained by the scalar multiplication of
+	 * the other side's public key and the local private key scalar.
+	 */
+	crypto_scalarmult_curve25519(pss->K, kex->eph_pri_key, kex->Q_C);
+
+	/*
+	 * The whole 32 bytes of the number X are then converted into a big
+	 * integer k.  This conversion follows the network byte order. This
+	 * step differs from RFC5656.
+	 */
+	kbi_len = lws_mpint_rfc4251(kbi, pss->K, LWS_SIZE_EC25519, 1);
+
+	/*
+	 * The exchange hash H is computed as the hash of the concatenation of
+	 * the following:
+	 *
+	 *      string    V_C, the client's identification string (CR and LF
+         *		       excluded)
+	 *      string    V_S, the server's identification string (CR and LF
+         *		       excluded)
+	 *      string    I_C, the payload of the client's SSH_MSG_KEXINIT
+	 *      string    I_S, the payload of the server's SSH_MSG_KEXINIT
+	 *      string    K_S, the host key
+	 *      mpint     Q_C, exchange value sent by the client
+	 *      mpint     Q_S, exchange value sent by the server
+	 *      mpint     K, the shared secret
+	 *
+	 * However there are a lot of unwritten details in the hash
+	 * definition...
+	 */
+
+	if (lws_genhash_init(&ctx, LWS_GENHASH_TYPE_SHA256)) {
+		lwsl_notice("genhash init failed\n");
+		return 1;
+	}
+
+	if (_genhash_update_len(&ctx, pss->V_C, strlen(pss->V_C)))
+		goto hash_probs;
+	if (_genhash_update_len(&ctx, pss->vhd->ops->server_string, /* aka V_S */
+			       strlen(pss->vhd->ops->server_string)))
+		goto hash_probs;
+	if (_genhash_update_len(&ctx, kex->I_C, kex->I_C_payload_len))
+		goto hash_probs;
+	if (_genhash_update_len(&ctx, kex->I_S, kex->I_S_payload_len))
+		goto hash_probs;
+	/*
+	 * K_S (host public key)
+	 *
+	 * sum of name + key lengths and headers
+	 * name length: name
+	 * key length: key
+	 * ---> */
+	lws_p32((uint8_t *)&be, 8 + strlen(keyt) + LWS_SIZE_EC25519);
+	if (lws_genhash_update(&ctx, (void *)&be, 4))
+		goto hash_probs;
+
+	if (_genhash_update_len(&ctx, keyt, strlen(keyt)))
+		goto hash_probs;
+	if (_genhash_update_len(&ctx, pss->K_S, LWS_SIZE_EC25519))
+		goto hash_probs;
+	/* <---- */
+
+	if (_genhash_update_len(&ctx, kex->Q_C, LWS_SIZE_EC25519))
+		goto hash_probs;
+	if (_genhash_update_len(&ctx, kex->Q_S, LWS_SIZE_EC25519))
+		goto hash_probs;
+
+	if (lws_genhash_update(&ctx, kbi, kbi_len))
+		goto hash_probs;
+
+	if (lws_genhash_destroy(&ctx, temp))
+		goto hash_probs;
+
+	/*
+	 * Sign the 32-byte SHA256 "exchange hash" in temp
+	 * The signature is itself 64 bytes
+	 */
+        smlen = LWS_SIZE_EC25519 + 64;
+        if (crypto_sign_ed25519(payload_sig, &smlen, temp, LWS_SIZE_EC25519,
+        			pri_key))
+		return 1;
+
+#if 0
+        l = LWS_SIZE_EC25519;
+        n = crypto_sign_ed25519_open(temp, &l, payload_sig, smlen, pss->K_S);
+
+        lwsl_notice("own sig sanity check says %d\n", n);
+#endif
+
+	/* sig [64] and payload [32] concatenated in payload_sig
+	 *
+	 * The server then responds with the following
+	 *
+	 *	uint32    packet length (exl self + mac)
+	 *	byte      padding len
+	 *      byte      SSH_MSG_KEX_ECDH_REPLY
+	 *      string    server public host key and certificates (K_S)
+	 *      string    Q_S (exchange value sent by the server)
+	 *      string    signature of H
+	 *      padding
+	 */
+	*p++ = SSH_MSG_KEX_ECDH_REPLY;
+
+	/* server public host key and certificates (K_S) */
+
+	lp = p;
+	p +=4;
+	lws_sized_blob(&p, keyt, strlen(keyt));
+	lws_sized_blob(&p, pss->K_S, LWS_SIZE_EC25519);
+	lws_p32(lp, p - lp - 4);
+
+	/* Q_S (exchange value sent by the server) */
+	
+	lws_sized_blob(&p, kex->Q_S, LWS_SIZE_EC25519);
+
+	/* signature of H */
+
+	lp = p;
+	p +=4;
+	lws_sized_blob(&p, keyt, strlen(keyt));
+	lws_sized_blob(&p, payload_sig, 64);
+	lws_p32(lp, p - lp - 4);
+
+	/* end of message */
+
+	lws_pad_set_length(pss, reply, &p, &pss->active_keys_stc);
+	*plen = p - reply;
+
+	if (!pss->active_keys_stc.valid)
+		memcpy(pss->session_id, temp, LWS_SIZE_EC25519);
+
+	/* RFC4253 7.2:
+	 *
+	 * The key exchange produces two values: a shared secret K,
+	 * and an exchange hash H.  Encryption and authentication
+	 * keys are derived from these.  The exchange hash H from the
+	 * first key exchange is additionally used as the session
+	 * identifier, which is a unique identifier for this connection.
+	 * It is used by authentication methods as a part of the data
+	 * that is signed as a proof of possession of a private key.
+	 * Once computed, the session identifier is not changed,
+	 * even if keys are later re-exchanged.
+	 *
+	 * The hash alg used in the KEX must be used for key derivation.
+	 *
+	 * 1) Initial IV client to server:
+	 *
+	 *     HASH(K || H || "A" || session_id)
+	 *
+	 * (Here K is encoded as mpint and "A" as byte and session_id
+	 * as raw data.  "A" means the single character A, ASCII 65).
+	 *
+	 *
+	 */
+	for (c = 0; c < 3; c++) {
+		kex_ecdh_dv(kex->keys_next_cts.key[c], LWS_SIZE_CHACHA256_KEY,
+			    kbi, kbi_len, temp, 'A' + (c * 2), pss->session_id);
+		kex_ecdh_dv(kex->keys_next_stc.key[c], LWS_SIZE_CHACHA256_KEY,
+			    kbi, kbi_len, temp, 'B' + (c * 2), pss->session_id);
+	}
+
+	explicit_bzero(temp, sizeof(temp));
+
+	return 0;
+
+hash_probs:
+	lws_genhash_destroy(&ctx, NULL);
+
+	return 1;
+}
diff --git a/plugins/ssh-base/sshd.c b/plugins/ssh-base/sshd.c
new file mode 100644
index 0000000000000000000000000000000000000000..b3823db1dbdb9ea04fc510e784fdd3d01e5949ef
--- /dev/null
+++ b/plugins/ssh-base/sshd.c
@@ -0,0 +1,2619 @@
+/*
+ * libwebsockets - lws-plugin-ssh-base - sshd.c
+ *
+ * Copyright (C) 2017 Andy Green <andy@warmcat.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation:
+ *  version 2.1 of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "libwebsockets.h"
+#include "lws-ssh.h"
+
+#include <string.h>
+
+void *sshd_zalloc(size_t s)
+{
+	void *p = malloc(s);
+
+	if (p)
+		memset(p, 0, s);
+
+	return p;
+}
+
+uint32_t
+lws_g32(uint8_t **p)
+{
+	uint32_t v = 0;
+
+	v = (v << 8) | *((*p)++);
+	v = (v << 8) | *((*p)++);
+	v = (v << 8) | *((*p)++);
+	v = (v << 8) | *((*p)++);
+
+	return v;
+}
+
+uint32_t
+lws_p32(uint8_t *p, uint32_t v)
+{
+	*p++ = v >> 24;
+	*p++ = v >> 16;
+	*p++ = v >> 8;
+	*p++ = v;
+
+	return v;
+}
+
+int
+lws_cstr(uint8_t **p, const char *s, uint32_t max)
+{
+	uint32_t n = strlen(s);
+
+	if (n > max)
+		return 1;
+
+	lws_p32(*p, n);
+	*p += 4;
+	strcpy((char *)(*p), s);
+	*p += n;
+
+	return 0;
+}
+
+int
+lws_buf(uint8_t **p, void *s, uint32_t len)
+{
+	lws_p32(*p, len);
+	*p += 4;
+	memcpy((char *)(*p), s, len);
+	*p += len;
+
+	return 0;
+}
+
+
+void
+explicit_bzero(void *p, size_t len)
+{
+	volatile uint8_t *vp = p;
+
+	while (len--)
+		*vp++ = 0;
+}
+
+int
+timingsafe_bcmp(const void *a, const void *b, uint32_t len)
+{
+	const uint8_t *pa = a, *pb = b;
+	uint8_t sum = 0;
+
+	while (len--)
+		sum |= (*pa ^ *pb);
+
+	return sum;
+}
+
+void
+write_task(struct per_session_data__sshd *pss, struct lws_ssh_channel *ch,
+	   int task)
+{
+	pss->write_task[pss->wt_head] = task;
+	pss->write_channel[pss->wt_head] = ch;
+	pss->wt_head = (pss->wt_head + 1) & 3;
+	lws_callback_on_writable(pss->wsi);
+}
+
+void
+lws_pad_set_length(struct per_session_data__sshd *pss, void *start, uint8_t **p,
+		   struct lws_ssh_keys *keys)
+{
+	uint32_t len = *p - (uint8_t *)start;
+	uint8_t padc = 4, *bs = start;
+
+	if (keys->full_length)
+		len -= 4;
+
+	if ((len + padc) & (keys->padding_alignment - 1))
+		padc += keys->padding_alignment -
+			((len + padc) & (keys->padding_alignment - 1));
+
+	bs[4] = padc;
+	len += padc;
+
+	if (!keys->valid) /* no crypto = pad with 00 */
+		while (padc--)
+			*((*p)++) = 0;
+	else { /* crypto active = pad with random */
+		lws_get_random(pss->vhd->context, *p, padc);
+		(*p) += padc;
+	}
+	if (keys->full_length)
+		len += 4;
+
+	lws_p32(start, len - 4);
+}
+
+static uint32_t
+offer(struct per_session_data__sshd *pss, uint8_t *p, uint32_t len, int first,
+      int *payload_len)
+{
+	uint8_t *op = p, *lp, *end = p + len - 1;
+	int n, padc = 4, keylen;
+	char keyt[32];
+	uint8_t keybuf[256];
+
+	keylen = get_gen_server_key_25519(pss, keybuf, sizeof(keybuf));
+	if (!keylen) {
+		lwsl_notice("get_gen_server_key failed\n");
+		return 1;
+	}
+	lwsl_info("keylen %d\n", keylen);
+	n = ed25519_key_parse(keybuf, keylen,
+			      keyt, sizeof(keyt), NULL, NULL);
+	if (n) {
+		lwsl_notice("unable to parse server key: %d\n", n);
+		return 1;
+	}
+
+	/*
+	 *     byte         SSH_MSG_KEXINIT
+	 *     byte[16]     cookie (random bytes)
+	 *     name-list    kex_algorithms
+	 *     name-list    server_host_key_algorithms
+	 *     name-list    encryption_algorithms_client_to_server
+	 *     name-list    encryption_algorithms_server_to_client
+	 *     name-list    mac_algorithms_client_to_server
+	 *     name-list    mac_algorithms_server_to_client
+	 *     name-list    compression_algorithms_client_to_server
+	 *     name-list    compression_algorithms_server_to_client
+	 *     name-list    langua->es_client_to_server
+	 *     name-list    langua->es_server_to_client
+	 *     boolean      first_kex_packet_follows
+	 *     uint32       0 (reserved for future extension)
+      	 */
+
+	p += 5; /* msg len + padding */
+
+	*p++ = SSH_MSG_KEXINIT;
+	lws_get_random(pss->vhd->context, p, 16);
+	p += 16;
+
+	/* KEX algorithms */
+
+	lp = p;
+	p += 4;
+	n = lws_snprintf((char *)p, end - p, "curve25519-sha256@libssh.org");
+	p += lws_p32(lp, n);
+
+	/* Server Host Key Algorithms */
+
+	lp = p;
+	p += 4;
+	n = lws_snprintf((char *)p, end - p, "%s", keyt);
+	p += lws_p32(lp, n);
+
+	/* Encryption Algorithms: C -> S */
+
+	lp = p;
+	p += 4;
+//	n = lws_snprintf((char *)p, end - p, "aes256-gcm@openssh.com");
+	n = lws_snprintf((char *)p, end - p, "chacha20-poly1305@openssh.com");
+	p += lws_p32(lp, n);
+
+	/* Encryption Algorithms: S -> C */
+
+	lp = p;
+	p += 4;
+//	n = lws_snprintf((char *)p, end - p, "aes256-gcm@openssh.com");
+	n = lws_snprintf((char *)p, end - p, "chacha20-poly1305@openssh.com");
+	p += lws_p32(lp, n);
+
+	/* MAC Algorithms: C -> S */
+
+	lp = p;
+	p += 4;
+	/* bogus: chacha20 does not use MACs, but 'none' is not offered */
+	n = lws_snprintf((char *)p, end - p, "hmac-sha2-256");
+	p += lws_p32(lp, n);
+
+	/* MAC Algorithms: S -> C */
+
+	lp = p;
+	p += 4;
+	/* bogus: chacha20 does not use MACs, but 'none' is not offered */
+	n = lws_snprintf((char *)p, end - p, "hmac-sha2-256");
+	p += lws_p32(lp, n);
+
+	/* Compression Algorithms: C -> S */
+
+	lp = p;
+	p += 4;
+	n = lws_snprintf((char *)p, end - p, "none");
+	p += lws_p32(lp, n);
+
+	/* Compression Algorithms: S -> C */
+
+	lp = p;
+	p += 4;
+	n = lws_snprintf((char *)p, end - p, "none");
+	p += lws_p32(lp, n);
+
+	if (p - op < 13 + padc + 8)
+		return 0;
+
+	/* Languages: C -> S */
+
+	*p++ = 0;
+	*p++ = 0;
+	*p++ = 0;
+	*p++ = 0;
+
+	/* Languages: S -> C */
+
+	*p++ = 0;
+	*p++ = 0;
+	*p++ = 0;
+	*p++ = 0;
+
+	/* First KEX packet coming */
+
+	*p++ = !!first;
+
+	/* Reserved */
+
+	*p++ = 0;
+	*p++ = 0;
+	*p++ = 0;
+	*p++ = 0;
+
+	len = p - op;
+	if (payload_len)
+		/* starts at buf + 5 and excludes padding */
+		*payload_len = len - 5;
+
+	/* we must give at least 4 bytes of 00 padding */
+
+	if ((len + padc) & 7)
+		padc += 8 - ((len + padc) & 7);
+
+	op[4] = padc;
+	len += padc;
+
+	while (padc--)
+		*p++ = 0;
+
+	/* recorded length does not include the uint32_t len itself */
+	lws_p32(op, len - 4);
+
+	return len;
+}
+
+static int
+handle_name(struct per_session_data__sshd *pss)
+{
+	struct lws_kex *kex = pss->kex;
+	char keyt[32];
+	uint8_t keybuf[256];
+	int n = 0, len;
+
+	switch (pss->parser_state) {
+	case SSH_KEX_NL_KEX_ALGS:
+		if (!strcmp(pss->name, "curve25519-sha256@libssh.org"))
+			kex->match_bitfield |= 1;
+		break;
+	case SSH_KEX_NL_SHK_ALGS:
+		len = get_gen_server_key_25519(pss, keybuf, sizeof(keybuf));
+		if (!len)
+			break;
+		if (ed25519_key_parse(keybuf, len,
+				      keyt, sizeof(keyt),
+				      NULL, NULL)) {
+			lwsl_err("Unable to parse host key %d\n", n);
+		} else {
+			if (!strcmp(pss->name, keyt)) {
+				kex->match_bitfield |= 2;
+				break;
+			}
+		}
+		break;
+	case SSH_KEX_NL_EACTS_ALGS:
+		if (!strcmp(pss->name, "chacha20-poly1305@openssh.com"))
+			kex->match_bitfield |= 4;
+		break;
+	case SSH_KEX_NL_EASTC_ALGS:
+		if (!strcmp(pss->name, "chacha20-poly1305@openssh.com"))
+			kex->match_bitfield |= 8;
+		break;
+	case SSH_KEX_NL_MACTS_ALGS:
+		if (!strcmp(pss->name, "hmac-sha2-256"))
+			kex->match_bitfield |= 16;
+		break;
+	case SSH_KEX_NL_MASTC_ALGS:
+		if (!strcmp(pss->name, "hmac-sha2-256"))
+			kex->match_bitfield |= 32;
+		break;
+	case SSH_KEX_NL_CACTS_ALGS:
+		if (!strcmp(pss->name, "none"))
+			kex->match_bitfield |= 64;
+		break;
+	case SSH_KEX_NL_CASTC_ALGS:
+		if (!strcmp(pss->name, "none"))
+			kex->match_bitfield |= 128;
+		break;
+	case SSH_KEX_NL_LCTS_ALGS:
+	case SSH_KEX_NL_LSTC_ALGS:
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+
+static int
+lws_kex_create(struct per_session_data__sshd *pss)
+{
+	pss->kex = sshd_zalloc(sizeof(struct lws_kex));
+	lwsl_info("%s\n", __func__);
+	return !pss->kex;
+}
+
+static void
+lws_kex_destroy(struct per_session_data__sshd *pss)
+{
+	if (!pss->kex)
+		return;
+
+	lwsl_info("Destroying KEX\n");
+
+	if (pss->kex->I_C) {
+		free(pss->kex->I_C);
+		pss->kex->I_C = NULL;
+	}
+	if (pss->kex->I_S) {
+		free(pss->kex->I_S);
+		pss->kex->I_S = NULL;
+	}
+
+	explicit_bzero(pss->kex, sizeof(*pss->kex));
+	free(pss->kex);
+	pss->kex = NULL;
+}
+
+static void
+ssh_free(void *p)
+{
+	if (!p)
+		return;
+
+	lwsl_debug("%s: FREE %p\n", __func__, p);
+	free(p);
+}
+
+static void
+lws_ua_destroy(struct per_session_data__sshd *pss)
+{
+	if (!pss->ua)
+		return;
+
+	lwsl_info("%s\n", __func__);
+
+	if (pss->ua->username)
+		ssh_free(pss->ua->username);
+	if (pss->ua->service)
+		ssh_free(pss->ua->service);
+	if (pss->ua->alg)
+		ssh_free(pss->ua->alg);
+	if (pss->ua->pubkey)
+		ssh_free(pss->ua->pubkey);
+	if (pss->ua->sig) {
+		explicit_bzero(pss->ua->sig, pss->ua->sig_len);
+		ssh_free(pss->ua->sig);
+	}
+
+	explicit_bzero(pss->ua, sizeof(*pss->ua));
+	free(pss->ua);
+	pss->ua = NULL;
+}
+
+
+static int
+rsa_hash_alg_from_ident(const char *ident)
+{
+	if (strcmp(ident, "ssh-rsa") == 0 ||
+	    strcmp(ident, "ssh-rsa-cert-v01@openssh.com") == 0)
+		return LWS_GENHASH_TYPE_SHA1;
+	if (strcmp(ident, "rsa-sha2-256") == 0)
+		return LWS_GENHASH_TYPE_SHA256;
+	if (strcmp(ident, "rsa-sha2-512") == 0)
+		return LWS_GENHASH_TYPE_SHA512;
+
+        return -1;
+}
+
+static void
+state_get_string_alloc(struct per_session_data__sshd *pss, int next)
+{
+	pss->parser_state = SSHS_GET_STRING_LEN_ALLOC;
+        pss->state_after_string = next;
+}
+
+static void
+state_get_string(struct per_session_data__sshd *pss, int next)
+{
+	pss->parser_state = SSHS_GET_STRING_LEN;
+        pss->state_after_string = next;
+}
+
+static void
+state_get_u32(struct per_session_data__sshd *pss, int next)
+{
+	pss->parser_state = SSHS_GET_U32;
+        pss->state_after_string = next;
+}
+
+static struct lws_ssh_channel *
+ssh_get_server_ch(struct per_session_data__sshd *pss, uint32_t chi)
+{
+	struct lws_ssh_channel *ch = pss->ch_list;
+
+	while (ch) {
+		if (ch->server_ch == chi)
+			return ch;
+		ch = ch->next;
+	}
+
+	return NULL;
+}
+
+#if 0
+static struct lws_ssh_channel *
+ssh_get_peer_ch(struct per_session_data__sshd *pss, uint32_t chi)
+{
+	struct lws_ssh_channel *ch = pss->ch_list;
+
+	while (ch) {
+		if (ch->sender_ch == chi)
+			return ch;
+		ch = ch->next;
+	}
+
+	return NULL;
+}
+#endif
+
+static void
+ssh_destroy_channel(struct per_session_data__sshd *pss,
+		    struct lws_ssh_channel *ch)
+{
+	lws_start_foreach_llp(struct lws_ssh_channel **, ppch, pss->ch_list) {
+		if (*ppch == ch) {
+			lwsl_info("Deleting ch %p\n", ch);
+			if (pss->vhd && pss->vhd->ops &&
+			    pss->vhd->ops->channel_destroy)
+				pss->vhd->ops->channel_destroy(ch->priv);
+			*ppch = ch->next;
+			if (ch->sub)
+				free(ch->sub);
+			free(ch);
+
+			return;
+		}
+	} lws_end_foreach_llp(ppch, next);
+
+	lwsl_notice("Failed to delete ch\n");
+}
+
+
+static int
+lws_ssh_parse_plaintext(struct per_session_data__sshd *pss, uint8_t *p, size_t len)
+{
+#if defined(LWS_USE_MBEDTLS)
+	mbedtls_rsa_context *ctx;
+#else
+	BIGNUM *bn_e = NULL, *bn_n = NULL;
+	RSA *rsa = NULL;
+#endif
+	struct lws_ssh_channel *ch;
+	struct lws_subprotocol_scp *scp;
+	uint8_t *pp, *ps, hash[64], *otmp;
+	size_t olen;
+	uint32_t m;
+	int n;
+
+	while (len --) {
+again:
+		switch(pss->parser_state) {
+		case SSH_INITIALIZE_TRANSIENT:
+			pss->parser_state = SSHS_IDSTRING;
+			pss->ctr = 0;
+			pss->copy_to_I_C = 0;
+
+			/* fallthru */
+		case SSHS_IDSTRING:
+			if (*p == 0x0d) {
+				pss->V_C[pss->npos] = '\0';
+				pss->npos = 0;
+				lwsl_info("peer id: %s\n", pss->V_C);
+				p++;
+				pss->parser_state = SSHS_IDSTRING_CR;
+				break;
+			}
+			if (pss->npos < sizeof(pss->V_C) - 1)
+				pss->V_C[pss->npos++] = *p;
+			p++;
+			break;
+
+		case SSHS_IDSTRING_CR:
+			if (*p++ != 0x0a) {
+				lwsl_notice("mangled id string\n");
+				return 1;
+			}
+			pss->ssh_sequence_ctr_cts = 0;
+			pss->parser_state = SSHS_MSG_LEN;
+			break;
+
+		case SSHS_MSG_LEN:
+			pss->msg_len = (pss->msg_len << 8) | *p++;
+			if (++pss->ctr != 4)
+				break;
+
+			if (pss->active_keys_cts.valid) {
+				uint8_t b[4];
+
+				POKE_U32(b, pss->msg_len);
+				pss->msg_len = lws_chachapoly_get_length(
+					&pss->active_keys_cts,
+					pss->ssh_sequence_ctr_cts, b);
+			} else
+				pss->ssh_sequence_ctr_cts++;
+
+			lwsl_info("msg len %d\n", pss->msg_len);
+
+			pss->parser_state = SSHS_MSG_PADDING;
+			pss->ctr = 0;
+			pss->pos = 4;
+			if (pss->msg_len < 2 + 4) {
+				lwsl_notice("illegal msg size\n");
+				goto bail;
+			}
+			break;
+
+		case SSHS_MSG_PADDING:
+			pss->msg_padding = *p++;
+			pss->parser_state = SSHS_MSG_ID;
+			break;
+
+		case SSHS_MSG_ID:
+			pss->msg_id = *p++;
+			pss->ctr = 0;
+			switch (pss->msg_id) {
+			case SSH_MSG_DISCONNECT:
+				/*
+				 *       byte      SSH_MSG_DISCONNECT
+      	      	      	         *	 uint32    reason code
+				 *	 string    description in ISO-10646
+				 *	 	   UTF-8 encoding [RFC3629]
+      	      	      	      	 *	 string    language tag [RFC3066]
+				 */
+				lwsl_notice("SSH_MSG_DISCONNECT\n");
+				state_get_u32(pss, SSHS_NVC_DISCONNECT_REASON);
+				break;
+			case SSH_MSG_IGNORE:
+				lwsl_notice("SSH_MSG_IGNORE\n");
+				break;
+			case SSH_MSG_UNIMPLEMENTED:
+				lwsl_notice("SSH_MSG_UNIMPLEMENTED\n");
+				break;
+			case SSH_MSG_DEBUG:
+				lwsl_notice("SSH_MSG_DEBUG\n");
+				break;
+			case SSH_MSG_SERVICE_REQUEST:
+				lwsl_info("SSH_MSG_SERVICE_REQUEST\n");
+				/* payload is a string */
+				state_get_string(pss, SSHS_DO_SERVICE_REQUEST);
+				break;
+			case SSH_MSG_SERVICE_ACCEPT:
+				lwsl_notice("SSH_MSG_ACCEPT\n");
+				break;
+
+			case SSH_MSG_KEXINIT:
+				if (pss->kex_state !=
+					    KEX_STATE_EXPECTING_CLIENT_OFFER) {
+					pss->parser_state = SSH_KEX_STATE_SKIP;
+					break;
+				}
+				pss->parser_state = SSH_KEX_STATE_COOKIE;
+				pss->kex->I_C_payload_len = 0;
+				pss->kex->I_C_alloc_len = pss->msg_len;
+				pss->kex->I_C = sshd_zalloc(pss->kex->I_C_alloc_len);
+				if (!pss->kex->I_C) {
+					lwsl_notice("OOM 3\n");
+					goto bail;
+				}
+				pss->kex->I_C[pss->kex->I_C_payload_len++] =
+					pss->msg_id;
+				pss->copy_to_I_C = 1;
+				break;
+			case SSH_MSG_KEX_ECDH_INIT:
+				pss->parser_state = SSH_KEX_STATE_ECDH_KEYLEN;
+				break;
+
+			case SSH_MSG_NEWKEYS:
+				if (pss->kex_state !=
+						KEX_STATE_REPLIED_TO_OFFER &&
+				    pss->kex_state !=
+				    		KEX_STATE_CRYPTO_INITIALIZED) {
+					lwsl_notice("unexpected newkeys\n");
+
+					goto bail;
+				}
+				/*
+				 * it means we should now use the keys we
+				 * agreed on
+				 */
+				lwsl_info("Activating CTS keys\n");
+				pss->active_keys_cts = pss->kex->keys_next_cts;
+				if (lws_chacha_activate(&pss->active_keys_cts))
+					goto bail;
+
+				pss->kex->newkeys |= 2;
+				if (pss->kex->newkeys == 3)
+					lws_kex_destroy(pss);
+
+				if (pss->msg_padding) {
+					pss->copy_to_I_C = 0;
+					pss->parser_state =
+						SSHS_MSG_EAT_PADDING;
+					break;
+				} else {
+					pss->parser_state = SSHS_MSG_LEN;
+				}
+				break;
+
+			case SSH_MSG_USERAUTH_REQUEST:
+				/*
+				 *    byte      SSH_MSG_USERAUTH_REQUEST
+				 *    string    user name in UTF-8
+				 *    		encoding [RFC3629]
+				 *    string    service name in US-ASCII
+				 *    string    "publickey"
+				 *    boolean   FALSE
+				 *    string    public key alg
+				 *    string    public key blob
+				 */
+				lwsl_info("SSH_MSG_USERAUTH_REQUEST\n");
+				if (pss->ua) {
+					lwsl_notice("pss->ua overwrite\n");
+
+					goto bail;
+				}
+
+				pss->ua = sshd_zalloc(sizeof(*pss->ua));
+				if (!pss->ua)
+					goto bail;
+
+				state_get_string_alloc(pss, SSHS_DO_UAR_SVC);
+				/* username is destroyed with userauth struct */
+				if (!pss->sent_banner) {
+					if (pss->vhd->ops->banner)
+						write_task(pss, NULL,
+							   SSH_WT_UA_BANNER);
+					pss->sent_banner = 1;
+				}
+                                break;
+			case SSH_MSG_USERAUTH_FAILURE:
+				goto bail;
+			case SSH_MSG_USERAUTH_SUCCESS:
+				goto bail;
+			case SSH_MSG_USERAUTH_BANNER:
+				goto bail;
+
+			case SSH_MSG_CHANNEL_OPEN:
+				state_get_string(pss, SSHS_NVC_CHOPEN_TYPE);
+				break;
+
+			case SSH_MSG_CHANNEL_REQUEST:
+				/* RFC4254
+				 *
+				 *  byte      SSH_MSG_CHANNEL_REQUEST
+				 *  uint32    recipient channel
+				 *  string    "pty-req"
+				 *  boolean   want_reply
+				 *  string    TERM environment variable value
+				 *      		(e.g., vt100)
+				 *  uint32    terminal width, characters
+				 *      		(e.g., 80)
+				 *  uint32    terminal height, rows (e.g., 24)
+				 *  uint32    terminal width, px (e.g., 640)
+				 *  uint32    terminal height, px (e.g., 480)
+				 *  string    encoded terminal modes
+				 */
+				state_get_u32(pss, SSHS_NVC_CHRQ_RECIP);
+				break;
+
+			case SSH_MSG_CHANNEL_EOF:
+				/* RFC4254
+				 * When a party will no longer send more data
+				 * to a channel, it SHOULD send
+				 * SSH_MSG_CHANNEL_EOF.
+				 *
+				 *  byte      SSH_MSG_CHANNEL_EOF
+ 	 	 	 	 *  uint32    recipient channel
+				 */
+				state_get_u32(pss, SSHS_NVC_CH_EOF);
+				break;
+
+			case SSH_MSG_CHANNEL_CLOSE:
+				/* RFC4254
+				 *
+				 *  byte      SSH_MSG_CHANNEL_CLOSE
+				 *  uint32    recipient channel
+				 *
+				 * This message does not consume window space
+				 * and can be sent even if no window space is
+				 * available.
+				 *
+				 * It is RECOMMENDED that all data sent before
+				 * this message be delivered to the actual
+				 * destination, if possible.
+				 */
+				state_get_u32(pss, SSHS_NVC_CH_CLOSE);
+				break;
+
+			case SSH_MSG_CHANNEL_DATA:
+				/* RFC4254
+				 *
+				 *      byte      SSH_MSG_CHANNEL_DATA
+				 *      uint32    recipient channel
+				 *      string    data
+				 */
+				state_get_u32(pss, SSHS_NVC_CD_RECIP);
+				break;
+
+			case SSH_MSG_CHANNEL_WINDOW_ADJUST:
+				/* RFC452
+				 *
+				 * byte      SSH_MSG_CHANNEL_WINDOW_ADJUST
+				 * uint32    recipient channel
+				 * uint32    bytes to add
+				 */
+				if (!pss->ch_list)
+					goto bail;
+
+				state_get_u32(pss, SSHS_NVC_WA_RECIP);
+				break;
+			default:
+				lwsl_notice("unk msg_id %d\n", pss->msg_id);
+
+				goto bail;
+			}
+			break;
+
+		case SSH_KEX_STATE_COOKIE:
+			if (pss->msg_len < 16 + 1 + 1 + (10 * 4) + 5) {
+				lwsl_notice("sanity: kex length failed\n");
+				goto bail;
+			}
+			pss->kex->kex_cookie[pss->ctr++] = *p++;
+			if (pss->ctr != sizeof(pss->kex->kex_cookie))
+				break;
+			pss->parser_state = SSH_KEX_NL_KEX_ALGS_LEN;
+			pss->ctr = 0;
+			break;
+		case SSH_KEX_NL_KEX_ALGS_LEN:
+		case SSH_KEX_NL_SHK_ALGS_LEN:
+		case SSH_KEX_NL_EACTS_ALGS_LEN:
+		case SSH_KEX_NL_EASTC_ALGS_LEN:
+		case SSH_KEX_NL_MACTS_ALGS_LEN:
+		case SSH_KEX_NL_MASTC_ALGS_LEN:
+		case SSH_KEX_NL_CACTS_ALGS_LEN:
+		case SSH_KEX_NL_CASTC_ALGS_LEN:
+		case SSH_KEX_NL_LCTS_ALGS_LEN:
+		case SSH_KEX_NL_LSTC_ALGS_LEN:
+		case SSH_KEX_STATE_ECDH_KEYLEN:
+
+			pss->len = (pss->len << 8) | *p++;
+			if (++pss->ctr != 4)
+				break;
+
+			switch (pss->parser_state) {
+			case SSH_KEX_STATE_ECDH_KEYLEN:
+				pss->parser_state = SSH_KEX_STATE_ECDH_Q_C;
+				break;
+			default:
+				pss->parser_state++;
+				if (pss->len == 0)
+					pss->parser_state++;
+				break;
+			}
+			pss->ctr = 0;
+			pss->npos = 0;
+			if (pss->msg_len - pss->pos < pss->len) {
+				lwsl_notice("sanity: length  %d - %d < %d\n",
+					    pss->msg_len, pss->pos, pss->len);
+				goto bail;
+			}
+			break;
+
+		case SSH_KEX_NL_KEX_ALGS:
+		case SSH_KEX_NL_SHK_ALGS:
+		case SSH_KEX_NL_EACTS_ALGS:
+		case SSH_KEX_NL_EASTC_ALGS:
+		case SSH_KEX_NL_MACTS_ALGS:
+		case SSH_KEX_NL_MASTC_ALGS:
+		case SSH_KEX_NL_CACTS_ALGS:
+		case SSH_KEX_NL_CASTC_ALGS:
+		case SSH_KEX_NL_LCTS_ALGS:
+		case SSH_KEX_NL_LSTC_ALGS:
+			if (*p != ',') {
+				if (pss->npos < sizeof(pss->name) - 1)
+					pss->name[pss->npos++] = *p;
+			} else {
+				pss->name[pss->npos] = '\0';
+				pss->npos = 0;
+				handle_name(pss);
+			}
+			p++;
+			if (!--pss->len) {
+				pss->name[pss->npos] = '\0';
+				if (pss->npos)
+					handle_name(pss);
+				pss->parser_state++;
+				break;
+			}
+			break;
+
+		case SSH_KEX_FIRST_PKT:
+			pss->first_coming = !!*p++;
+			pss->parser_state = SSH_KEX_RESERVED;
+			break;
+
+		case SSH_KEX_RESERVED:
+			pss->len = (pss->len << 8) | *p++;
+			if (++pss->ctr != 4)
+				break;
+			pss->ctr = 0;
+			if (pss->msg_padding) {
+				pss->copy_to_I_C = 0;
+				pss->parser_state = SSHS_MSG_EAT_PADDING;
+				break;
+			}
+			pss->parser_state = SSHS_MSG_LEN;
+			break;
+
+		case SSH_KEX_STATE_ECDH_Q_C:
+			if (pss->len != 32) {
+				lwsl_notice("wrong key len\n");
+				goto bail;
+			}
+			pss->kex->Q_C[pss->ctr++] = *p++;
+			if (pss->ctr != 32)
+				break;
+			lwsl_info("Q_C parsed\n");
+			pss->parser_state = SSHS_MSG_EAT_PADDING;
+			break;
+
+		case SSH_KEX_STATE_SKIP:
+			if (pss->pos - 4 < pss->msg_len) {
+				p++;
+				break;
+			}
+			lwsl_debug("skip done pos %d, msg_len %d len=%ld, \n",
+				       pss->pos, pss->msg_len, (long)len);
+			pss->parser_state = SSHS_MSG_LEN;
+			pss->ctr = 0;
+			break;
+
+		case SSHS_MSG_EAT_PADDING:
+			p++;
+			if (--pss->msg_padding)
+				break;
+			if (pss->msg_len + 4 != pss->pos) {
+				lwsl_notice("sanity: kex end mismatch %d %d\n",
+						pss->pos, pss->msg_len);
+				goto bail;
+			}
+
+			switch (pss->msg_id) {
+			case SSH_MSG_KEX_ECDH_INIT:
+				if (pss->kex->match_bitfield != 0xff) {
+					lwsl_notice("unable to negotiate\n");
+					goto bail;
+				}
+				if (kex_ecdh(pss, pss->kex->kex_r,
+					     &pss->kex->kex_r_len)) {
+					lwsl_notice("hex_ecdh failed\n");
+					goto bail;
+				}
+				write_task(pss, NULL, SSH_WT_OFFER_REPLY);
+				break;
+			}
+
+			pss->parser_state = SSHS_MSG_LEN;
+			pss->ctr = 0;
+			break;
+
+		case SSHS_GET_STRING_LEN:
+			pss->npos = 0;
+			pss->len = (pss->len << 8) | *p++;
+                        if (++pss->ctr != 4)
+                                break;
+                        pss->ctr = 0;
+			pss->parser_state = SSHS_GET_STRING;
+			break;
+
+		case SSHS_GET_STRING:
+			if (pss->npos >= sizeof(pss->name) - 1) {
+				lwsl_notice("non-alloc string too big\n");
+				goto bail;
+			}
+			pss->name[pss->npos++] = *p++;
+			if (pss->npos != pss->len)
+				break;
+
+			pss->name[pss->npos] = '\0';
+			pss->parser_state = pss->state_after_string;
+			goto again;
+
+		case SSHS_GET_STRING_LEN_ALLOC:
+			pss->npos = 0;
+			pss->len = (pss->len << 8) | *p++;
+                        if (++pss->ctr != 4)
+                                break;
+                        pss->ctr = 0;
+			pss->last_alloc = sshd_zalloc(pss->len + 1);
+			lwsl_debug("SSHS_GET_STRING_LEN_ALLOC: %p, state %d\n",
+				   pss->last_alloc, pss->state_after_string);
+			if (!pss->last_alloc) {
+				lwsl_notice("alloc string too big\n");
+				goto bail;
+			}
+			pss->parser_state = SSHS_GET_STRING_ALLOC;
+			break;
+
+		case SSHS_GET_STRING_ALLOC:
+			if (pss->npos >= pss->len)
+				goto bail;
+			pss->last_alloc[pss->npos++] = *p++;
+			if (pss->npos != pss->len)
+				break;
+			pss->last_alloc[pss->npos] = '\0';
+			pss->parser_state = pss->state_after_string;
+			goto again;
+
+		/*
+		 * User Authentication
+		 */
+
+		case SSHS_DO_SERVICE_REQUEST:
+			pss->okayed_userauth = 1;
+			pss->parser_state = SSHS_MSG_EAT_PADDING;
+			/*
+			 * this only 'accepts' that we can negotiate auth for
+			 * this service, not accepts the auth
+			 */
+			write_task(pss, NULL, SSH_WT_UA_ACCEPT);
+			break;
+
+		case SSHS_DO_UAR_SVC:
+			pss->ua->username = (char *)pss->last_alloc;
+			state_get_string_alloc(pss, SSHS_DO_UAR_PUBLICKEY);
+			/* destroyed with UA struct */
+			break;
+
+		case SSHS_DO_UAR_PUBLICKEY:
+			pss->ua->service = (char *)pss->last_alloc;
+
+			/* Sect 5, RFC4252
+			 *
+			 * The 'user name' and 'service name' are repeated in
+			 * every new authentication attempt, and MAY change.
+			 *
+			 * The server implementation MUST carefully check them
+			 * in every message, and MUST flush any accumulated
+			 * authentication states if they change.  If it is
+			 * unable to flush an authentication state, it MUST
+			 * disconnect if the 'user name' or 'service name'
+			 * changes.
+			 */
+
+			if (pss->seen_auth_req_before && (
+			     strcmp(pss->ua->username,
+				    pss->last_auth_req_username) ||
+			     strcmp(pss->ua->service,
+				    pss->last_auth_req_service))) {
+				lwsl_notice("username / svc changed\n");
+
+				goto bail;
+			}
+
+			pss->seen_auth_req_before = 1;
+			strncpy(pss->last_auth_req_username, pss->ua->username,
+				sizeof(pss->last_auth_req_username) - 1);
+			pss->last_auth_req_username[
+			        sizeof(pss->last_auth_req_username) - 1] = '\0';
+			strncpy(pss->last_auth_req_service, pss->ua->service,
+				sizeof(pss->last_auth_req_service) - 1);
+			pss->last_auth_req_service[
+			        sizeof(pss->last_auth_req_service) - 1] = '\0';
+
+			if (strcmp(pss->ua->service, "ssh-connection"))
+				goto ua_fail;
+			state_get_string(pss, SSHS_NVC_DO_UAR_CHECK_PUBLICKEY);
+			break;
+
+		case SSHS_NVC_DO_UAR_CHECK_PUBLICKEY:
+			if (!strcmp(pss->name, "none")) {
+				/* we must fail it */
+				lwsl_info("got 'none' req, refusing\n");
+				goto ua_fail;
+			}
+
+			if (strcmp(pss->name, "publickey")) {
+				lwsl_notice("expected 'publickey' got '%s'\n",
+					    pss->name);
+				goto ua_fail;
+			}
+			pss->parser_state = SSHS_DO_UAR_SIG_PRESENT;
+			break;
+
+		case SSHS_DO_UAR_SIG_PRESENT:
+			lwsl_info("SSHS_DO_UAR_SIG_PRESENT\n");
+			pss->ua->sig_present = *p++;
+			state_get_string_alloc(pss, SSHS_NVC_DO_UAR_ALG);
+			/* destroyed with UA struct */
+			break;
+
+		case SSHS_NVC_DO_UAR_ALG:
+			pss->ua->alg = (char *)pss->last_alloc;
+			if (rsa_hash_alg_from_ident(pss->ua->alg) < 0) {
+				lwsl_notice("unknown alg\n");
+				goto ua_fail;
+			}
+			state_get_string_alloc(pss, SSHS_NVC_DO_UAR_PUBKEY_BLOB);
+			/* destroyed with UA struct */
+			break;
+
+		case SSHS_NVC_DO_UAR_PUBKEY_BLOB:
+			pss->ua->pubkey = pss->last_alloc;
+			pss->ua->pubkey_len = pss->npos;
+			/*
+			 * RFC4253
+			 *
+			 * ssh-rsa
+			 *
+			 * The structure inside the blob is
+			 *
+			 *   mpint e
+			 *   mpint n
+			 *
+			 * Let's see if this key is authorized 
+			 */
+			
+			n = 1;
+			if (pss->vhd->ops && pss->vhd->ops->is_pubkey_authorized)
+				n = pss->vhd->ops->is_pubkey_authorized(
+					pss->ua->username, pss->ua->alg,
+					pss->ua->pubkey, pss->ua->pubkey_len);
+			if (n) {
+				lwsl_info("rejecting peer pubkey\n");
+				goto ua_fail;
+			}
+
+			if (pss->ua->sig_present) {
+				state_get_string_alloc(pss, SSHS_NVC_DO_UAR_SIG);
+				/* destroyed with UA struct */
+				break;
+			}
+
+			/*
+			 * This key is at least one we would be prepared
+			 * to accept if he really has it... since no sig
+			 * client should resend everything with a sig
+			 * appended.  OK it and delete this initial UA
+			 */
+			write_task(pss, NULL, SSH_WT_UA_PK_OK);
+			pss->parser_state = SSHS_MSG_EAT_PADDING;
+			break;
+
+		case SSHS_NVC_DO_UAR_SIG:
+			/*
+			 * Now the pubkey is coming with a sig
+			 */
+			/* Sect 5.1 RFC4252
+			 *
+			 * SSH_MSG_USERAUTH_SUCCESS MUST be sent only once.
+			 * When SSH_MSG_USERAUTH_SUCCESS has been sent, any
+			 * further authentication requests received after that
+			 * SHOULD be silently ignored.
+			 */
+			if (pss->ssh_auth_state == SSH_AUTH_STATE_GAVE_AUTH_IGNORE_REQS) {
+				lwsl_info("Silently ignoring auth req after accepted\n");
+				goto ua_fail_silently;
+			}
+			lwsl_info("SSHS_DO_UAR_SIG\n");
+			pss->ua->sig = pss->last_alloc;
+			pss->ua->sig_len = pss->npos;
+			pss->parser_state = SSHS_MSG_EAT_PADDING;
+
+			/*
+			 *   RFC 4252 p9
+			 *
+			 *   The value of 'signature' is a signature with
+			 *   the private host key of the following data, in
+			 *   this order:
+			 *
+			 *      string    session identifier
+			 *      byte      SSH_MSG_USERAUTH_REQUEST
+			 *      string    user name
+			 *      string    service name
+			 *      string    "publickey"
+			 *      boolean   TRUE
+			 *      string    public key algorithm name
+			 *      string    public key to be used for auth
+			 *
+			 * We reproduce the signature plaintext and the
+			 * hash, and then decrypt the incoming signed block.
+			 * What comes out is some ASN1, in there is the
+			 * hash decrypted.  We find it and confirm it
+			 * matches the hash we computed ourselves.
+			 *
+			 * First step is generate the sig plaintext
+			 */
+			n = 4 + 32 +
+			    1 +
+			    4 + strlen(pss->ua->username) +
+			    4 + strlen(pss->ua->service) +
+			    4 + 9 +
+			    1 +
+			    4 + strlen(pss->ua->alg) +
+			    4 + pss->ua->pubkey_len;
+
+			ps = sshd_zalloc(n);
+			if (!ps) {
+				lwsl_notice("OOM 4\n");
+				goto ua_fail;
+			}
+
+			pp = ps;
+			lws_buf(&pp, pss->session_id, 32);
+			*pp++ = SSH_MSG_USERAUTH_REQUEST;
+			lws_cstr(&pp, pss->ua->username, 64);
+			lws_cstr(&pp, pss->ua->service, 64);
+			lws_cstr(&pp, "publickey", 64);
+			*pp++ = 1;
+			lws_cstr(&pp, pss->ua->alg, 64);
+			lws_buf(&pp, pss->ua->pubkey, pss->ua->pubkey_len);
+
+			/* Next hash the plaintext */
+
+			if (lws_genhash_init(&pss->ua->hash_ctx,
+				rsa_hash_alg_from_ident(pss->ua->alg))) {
+				lwsl_notice("genhash init failed\n");
+				free(ps);
+				goto ua_fail;
+			}
+
+			if (lws_genhash_update(&pss->ua->hash_ctx, ps, pp - ps)) {
+				lwsl_notice("genhash update failed\n");
+				free(ps);
+				goto ua_fail;
+			}
+			lws_genhash_destroy(&pss->ua->hash_ctx, hash);
+			free(ps);
+
+			/*
+			 * Prepare the RSA decryption context: load in
+			 * the E and N factors
+			 */
+#if defined(LWS_USE_MBEDTLS)
+			ctx = sshd_zalloc(sizeof(*ctx));
+			if (!ctx)
+				goto ua_fail;
+			mbedtls_rsa_init(ctx, MBEDTLS_RSA_PKCS_V15, 0);
+
+			pp = pss->ua->pubkey;
+			m = lws_g32(&pp);
+			pp += m;
+			m = lws_g32(&pp);
+			if (mbedtls_mpi_read_binary(&ctx->E, pp, m))
+				lwsl_notice("mpi load E failed\n");
+			pp += m;
+			m = lws_g32(&pp);
+
+			m = mbedtls_mpi_read_binary(&ctx->N, pp, m);
+			if (m)
+				lwsl_notice("mpi load N failed %d\n", m);
+#else
+			/* Step 1:
+			 *
+			 * convert the MPI for e and n to OpenSSL BIGNUMs
+			 */
+
+			pp = pss->ua->pubkey;
+			m = lws_g32(&pp);
+			pp += m;
+			m = lws_g32(&pp);
+			pp -= 4;
+			bn_e = BN_mpi2bn(pp, m + 4, NULL);
+			if (!bn_e) {
+				lwsl_notice("mpi load E failed\n");
+				goto ua_fail;
+			}
+			pp += m + 4;
+			m = lws_g32(&pp);
+			pp -= 4;
+			bn_n = BN_mpi2bn(pp, m + 4, NULL);
+			if (!bn_n) {
+				lwsl_notice("mpi load N failed %d\n", m);
+				BN_free(bn_e);
+				bn_e = NULL;
+				goto ua_fail;
+			}
+
+			/* Step 2:
+			 *
+			 * assemble the OpenSSL RSA from the BIGNUMs
+			 */
+
+			rsa = RSA_new();
+			if (!rsa) {
+				lwsl_notice("Failed to create RSA\n");
+				BN_free(bn_e);
+				BN_free(bn_n);
+				goto ua_fail;
+			}
+#if defined(LWS_HAVE_RSA_SET0_KEY)
+			if (RSA_set0_key(rsa, bn_n, bn_e, NULL) != 1) {
+				lwsl_notice("RSA_set0_key failed\n");
+				BN_free(bn_e);
+				BN_free(bn_n);
+				goto ua_fail;
+			}
+
+#else
+			rsa->e = bn_e;
+			rsa->n = bn_n;
+#endif
+#endif
+			/*
+			 * point to the encrypted signature payload we
+			 * were sent
+			 */
+			pp = pss->ua->sig;
+			m = lws_g32(&pp);
+			pp += m;
+			m = lws_g32(&pp);
+#if defined(LWS_USE_MBEDTLS)
+			ctx->len = m;
+#endif
+
+			/*
+			 * decrypt it, resulting in an error or some
+			 * ASN1 including the decrypted signature
+			 */
+
+			otmp = sshd_zalloc(m);
+			if (!otmp)
+				/* ua_fail1 frees bn_e, bn_n and rsa */
+				goto ua_fail1;
+#if defined(LWS_USE_MBEDTLS)
+			m = mbedtls_rsa_rsaes_pkcs1_v15_decrypt(ctx,
+				NULL, NULL, MBEDTLS_RSA_PUBLIC,
+				&olen, pp, otmp, m);
+#else
+			olen = 0;
+			m = RSA_public_decrypt((int)m, pp, otmp, rsa,
+					       RSA_PKCS1_PADDING);
+			if (m != (uint32_t)-1) {
+				olen = m;
+				m = 0;
+			}
+			/* the bignums are also freed by freeing the RSA */
+			RSA_free(rsa);
+#endif
+			if (!m) {
+				/* the decrypted sig is in ASN1 format */
+				m = 0;
+				while (m < olen) {
+					/* sig payload */
+					if (otmp[m] == 0x04 &&
+					    otmp[m + 1] == lws_genhash_size(
+						  pss->ua->hash_ctx.type)) {
+						m = memcmp(&otmp[m + 2], hash,
+						lws_genhash_size(pss->ua->hash_ctx.type));
+						break;
+					}
+					/* go into these */
+					if (otmp[m] == 0x30) {
+						m += 2;
+						continue;
+					}
+					/* otherwise skip payloads */
+					m += otmp[m + 1] + 2;
+				}
+			} else
+				lwsl_notice("decrypt failed\n");
+#if defined(LWS_USE_MBEDTLS)
+			mbedtls_rsa_free(ctx);
+			free(ctx);
+#endif
+			free(otmp);
+			/*
+			 * if no good, m is nonzero and inform peer
+			 */
+			if (m) {
+				lwsl_notice("hash sig verify fail: %d\n", m);
+				goto ua_fail;
+			}
+
+			/* if it checks out, inform peer */
+
+			lwsl_info("sig check OK\n");
+
+			/* Sect 5.1 RFC4252
+			 *
+			 * SSH_MSG_USERAUTH_SUCCESS MUST be sent only once.
+			 * When SSH_MSG_USERAUTH_SUCCESS has been sent, any
+			 * further authentication requests received after that
+			 * SHOULD be silently ignored.
+			 */
+			pss->ssh_auth_state = SSH_AUTH_STATE_GAVE_AUTH_IGNORE_REQS;
+
+			write_task(pss, NULL, SSH_WT_UA_SUCCESS);
+			lws_ua_destroy(pss);
+			break;
+
+			/*
+			 * Channels
+			 */
+
+		case SSHS_GET_U32:
+			pss->len = (pss->len << 8) | *p++;
+                        if (++pss->ctr != 4)
+                                break;
+                        pss->ctr = 0;
+			pss->parser_state = pss->state_after_string;
+			goto again;
+
+			/*
+			 * Channel: Disconnect
+			 */
+
+		case SSHS_NVC_DISCONNECT_REASON:
+			pss->disconnect_reason = pss->len;
+			state_get_string_alloc(pss, SSHS_NVC_DISCONNECT_DESC);
+			break;
+
+		case SSHS_NVC_DISCONNECT_DESC:
+			pss->disconnect_desc = (char *)pss->last_alloc;
+			state_get_string(pss, SSHS_NVC_DISCONNECT_LANG);
+			break;
+
+		case SSHS_NVC_DISCONNECT_LANG:
+			lwsl_notice("SSHS_NVC_DISCONNECT_LANG\n");
+			if (pss->vhd->ops && pss->vhd->ops->disconnect_reason)
+				pss->vhd->ops->disconnect_reason(
+					pss->disconnect_reason,
+					pss->disconnect_desc, pss->name);
+			ssh_free(pss->last_alloc);
+			break;
+
+			/*
+			 * Channel: Open
+			 */
+
+		case SSHS_NVC_CHOPEN_TYPE:
+			/* channel open */
+			if (strcmp(pss->name, "session")) {
+				lwsl_notice("Failing on not session\n");
+				pss->reason = 3;
+				goto ch_fail;
+			}
+			lwsl_info("SSHS_NVC_CHOPEN_TYPE: creating session\n");
+			pss->ch_temp = sshd_zalloc(sizeof(*pss->ch_temp));
+			if (!pss->ch_temp)
+				return -1;
+
+			pss->ch_temp->type = SSH_CH_TYPE_SESSION;
+			state_get_u32(pss, SSHS_NVC_CHOPEN_SENDER_CH);
+			break;
+
+		case SSHS_NVC_CHOPEN_SENDER_CH:
+			pss->ch_temp->sender_ch = pss->len;
+			state_get_u32(pss, SSHS_NVC_CHOPEN_WINSIZE);
+			break;
+		case SSHS_NVC_CHOPEN_WINSIZE:
+			lwsl_info("Initial window set to %d\n", pss->len);
+			pss->ch_temp->window = pss->len;
+			state_get_u32(pss, SSHS_NVC_CHOPEN_PKTSIZE);
+			break;
+		case SSHS_NVC_CHOPEN_PKTSIZE:
+			pss->ch_temp->max_pkt = pss->len;
+			pss->ch_temp->peer_window_est = LWS_SSH_INITIAL_WINDOW;
+			pss->ch_temp->server_ch = pss->next_ch_num++;
+			/*
+			 * add us to channel list... leave as ch_temp
+			 * as write task needs it and will NULL down
+			 */
+			lwsl_info("creating new session ch\n");
+			pss->ch_temp->next = pss->ch_list;
+			pss->ch_list = pss->ch_temp;
+			if (pss->vhd->ops && pss->vhd->ops->channel_create)
+				pss->vhd->ops->channel_create(pss->wsi,
+						&pss->ch_temp->priv);
+			write_task(pss, pss->ch_temp, SSH_WT_CH_OPEN_CONF);
+			pss->parser_state = SSHS_MSG_EAT_PADDING;
+			break;
+
+		/*
+		 * SSH_MSG_CHANNEL_REQUEST
+		 */
+
+		case SSHS_NVC_CHRQ_RECIP:
+			pss->ch_recip = pss->len;
+			state_get_string(pss, SSHS_NVC_CHRQ_TYPE);
+			break;
+
+		case SSHS_NVC_CHRQ_TYPE:
+			pss->parser_state = SSHS_CHRQ_WANT_REPLY;
+			break;
+
+		case SSHS_CHRQ_WANT_REPLY:
+			pss->rq_want_reply = *p++;
+			lwsl_info("SSHS_CHRQ_WANT_REPLY: %s, wantrep: %d\n",
+					pss->name, pss->rq_want_reply);
+
+			pss->ch_temp = ssh_get_server_ch(pss, pss->ch_recip);
+
+			/* after this they differ by the request */
+
+			/*
+			 * a PTY for a shell
+			 */
+			if (!strcmp(pss->name, "pty-req")) {
+				state_get_string(pss, SSHS_NVC_CHRQ_TERM);
+				break;
+			}
+			/*
+			 * a shell
+			 */
+			if (!strcmp(pss->name, "shell")) {
+				pss->channel_doing_spawn = pss->ch_temp->server_ch;
+				if (pss->vhd->ops && pss->vhd->ops->shell &&
+				    !pss->vhd->ops->shell(pss->ch_temp->priv,
+						          pss->wsi)) {
+					if (pss->rq_want_reply)
+						write_task(pss, pss->ch_temp,
+							   SSH_WT_CHRQ_SUCC);
+					pss->parser_state = SSHS_MSG_EAT_PADDING;
+					break;
+				}
+
+				goto chrq_fail;
+			}
+			/*
+			 * env vars to be set in the shell
+			 */
+			if (!strcmp(pss->name, "env")) {
+				state_get_string(pss, SSHS_NVC_CHRQ_ENV_NAME);
+				break;
+			}
+
+			/*
+			 * exec something
+			 */
+			if (!strcmp(pss->name, "exec")) {
+				state_get_string_alloc(pss, SSHS_NVC_CHRQ_EXEC_CMD);
+				break;
+			}
+
+			/*
+			 * spawn a subsystem
+			 */
+			if (!strcmp(pss->name, "subsystem")) {
+				lwsl_notice("subsystem\n");
+				state_get_string_alloc(pss,
+						       SSHS_NVC_CHRQ_SUBSYSTEM);
+				break;
+			}
+
+			if (pss->rq_want_reply)
+				goto chrq_fail;
+
+			pss->parser_state = SSH_KEX_STATE_SKIP;
+			break;
+
+		/* CHRQ pty-req */
+
+		case SSHS_NVC_CHRQ_TERM:
+			strncpy(pss->args.pty.term, pss->name,
+				sizeof(pss->args.pty.term) - 1);
+			state_get_u32(pss, SSHS_NVC_CHRQ_TW);
+			break;
+		case SSHS_NVC_CHRQ_TW:
+			pss->args.pty.width_ch = pss->len;
+			state_get_u32(pss, SSHS_NVC_CHRQ_TH);
+			break;
+		case SSHS_NVC_CHRQ_TH:
+			pss->args.pty.height_ch = pss->len;
+			state_get_u32(pss, SSHS_NVC_CHRQ_TWP);
+			break;
+		case SSHS_NVC_CHRQ_TWP:
+			pss->args.pty.width_px = pss->len;
+			state_get_u32(pss, SSHS_NVC_CHRQ_THP);
+			break;
+		case SSHS_NVC_CHRQ_THP:
+			pss->args.pty.height_px = pss->len;
+			state_get_string_alloc(pss, SSHS_NVC_CHRQ_MODES);
+			break;
+		case SSHS_NVC_CHRQ_MODES:
+			/* modes is a stream of byte-pairs, not a string */
+			pss->args.pty.modes = (char *)pss->last_alloc;
+			pss->args.pty.modes_len = pss->npos;
+			n = 0;
+			if (pss->vhd->ops && pss->vhd->ops->pty_req)
+				n = pss->vhd->ops->pty_req(pss->ch_temp->priv,
+							&pss->args.pty);
+			ssh_free(pss->last_alloc);
+			if (n)
+				goto chrq_fail;
+			if (pss->rq_want_reply)
+				write_task(pss, pss->ch_temp, SSH_WT_CHRQ_SUCC);
+			pss->parser_state = SSHS_MSG_EAT_PADDING;
+			break;
+
+		/* CHRQ env */
+
+		case SSHS_NVC_CHRQ_ENV_NAME:
+			strcpy(pss->args.aux, pss->name);
+			state_get_string(pss, SSHS_NVC_CHRQ_ENV_VALUE);
+			break;
+
+		case SSHS_NVC_CHRQ_ENV_VALUE:
+			if (pss->vhd->ops && pss->vhd->ops->set_env)
+				if (pss->vhd->ops->set_env(pss->ch_temp->priv,
+						pss->args.aux, pss->name))
+					goto chrq_fail;
+			pss->parser_state = SSHS_MSG_EAT_PADDING;
+			break;
+
+		/* CHRQ exec */
+
+		case SSHS_NVC_CHRQ_EXEC_CMD:
+			/*
+			 * byte      SSH_MSG_CHANNEL_REQUEST
+			 * uint32    recipient channel
+			 * string    "exec"
+			 * boolean   want reply
+			 * string    command
+			 *
+			 * This message will request that the server start the
+			 * execution of the given command.  The 'command' string
+			 * may contain a path.  Normal precautions MUST be taken
+			 * to prevent the execution of unauthorized commands.
+			 *
+			 * scp sends "scp -t /path/..."
+			 */
+			lwsl_info("exec cmd: %s %02X\n", pss->last_alloc, *p);
+
+			pss->channel_doing_spawn = pss->ch_temp->server_ch;
+
+			if (pss->vhd->ops && pss->vhd->ops->exec &&
+			    !pss->vhd->ops->exec(pss->ch_temp->priv, pss->wsi,
+					    	 (const char *)pss->last_alloc)) {
+				ssh_free(pss->last_alloc);
+				if (pss->rq_want_reply)
+					write_task(pss, pss->ch_temp,
+						   SSH_WT_CHRQ_SUCC);
+
+				pss->parser_state = SSHS_MSG_EAT_PADDING;
+				break;
+			}
+
+			/*
+			 * even if he doesn't want to exec it, we know how to
+			 * fake scp
+			 */
+
+			/* we only alloc "exec" of scp for scp destination */
+			n = 1;
+			if (pss->last_alloc[0] != 's' ||
+			    pss->last_alloc[1] != 'c' ||
+			    pss->last_alloc[2] != 'p' ||
+			    pss->last_alloc[3] != ' ')
+				/* disallow it */
+				n = 0;
+
+			ssh_free(pss->last_alloc);
+			if (!n)
+				goto chrq_fail;
+
+			/* our channel speaks SCP protocol now */
+
+			scp = sshd_zalloc(sizeof(*scp));
+			if (!scp)
+				return -1;
+
+			pss->ch_temp->type = SSH_CH_TYPE_SCP;
+			pss->ch_temp->sub = (lws_subprotocol *)scp;
+
+			scp->ips = SSHS_SCP_COLLECTSTR;
+
+			if (pss->rq_want_reply)
+				write_task(pss, pss->ch_temp, SSH_WT_CHRQ_SUCC);
+
+			/* we start the scp protocol first by sending an ACK */
+			write_task(pss, pss->ch_temp, SSH_WT_SCP_ACK_OKAY);
+
+			pss->parser_state = SSHS_MSG_EAT_PADDING;
+			break;
+
+		case SSHS_NVC_CHRQ_SUBSYSTEM:
+			lwsl_notice("subsystem: %s", pss->last_alloc);
+			n = 0;
+#if 0
+			if (!strcmp(pss->name, "sftp")) {
+				lwsl_notice("SFTP session\n");
+				pss->ch_temp->type = SSH_CH_TYPE_SFTP;
+				n = 1;
+			}
+#endif
+			ssh_free(pss->last_alloc);
+//			if (!n)
+				goto ch_fail;
+#if 0
+			if (pss->rq_want_reply)
+				write_task(pss, ssh_get_server_ch(pss,
+					pss->ch_recip), SSH_WT_CHRQ_SUCC);
+			pss->parser_state = SSHS_MSG_EAT_PADDING;
+			break;
+#endif
+
+		/* SSH_MSG_CHANNEL_DATA */
+
+		case SSHS_NVC_CD_RECIP:
+			pss->ch_recip = pss->len;
+
+			ch = ssh_get_server_ch(pss, pss->ch_recip);
+			ch->peer_window_est -= pss->msg_len;
+
+			if (pss->msg_len < sizeof(pss->name))
+				state_get_string(pss, SSHS_NVC_CD_DATA);
+			else
+				state_get_string_alloc(pss,
+					SSHS_NVC_CD_DATA_ALLOC);
+			break;
+
+		case SSHS_NVC_CD_DATA_ALLOC:
+		case SSHS_NVC_CD_DATA:
+			/*
+			 * Actual protocol incoming payload
+			 */
+			if (pss->parser_state == SSHS_NVC_CD_DATA_ALLOC)
+				pp = pss->last_alloc;
+			else
+				pp = (uint8_t *)pss->name;
+			lwsl_info("SSHS_NVC_CD_DATA\n");
+
+			ch = ssh_get_server_ch(pss, pss->ch_recip);
+			switch (ch->type) {
+			case SSH_CH_TYPE_SCP:
+				scp = &ch->sub->scp;
+				switch (scp->ips) {
+				case SSHS_SCP_COLLECTSTR:
+					/* gather the ascii-coded headers */
+					for (n = 0; n < (int)pss->npos; n++)
+						lwsl_notice("0x%02X %c\n",
+							    pp[n], pp[n]);
+
+					/* Header triggers the transfer? */
+					if (pp[0] == 'C' && pp[pss->npos - 1] == '\x0a') {
+						while (*pp != ' ' && *pp != '\x0a')
+							pp++;
+						if (*pp++ != ' ') {
+							write_task(pss, ch,
+							   SSH_WT_SCP_ACK_ERROR);
+							pss->parser_state = SSHS_MSG_EAT_PADDING;
+							break;
+						}
+						scp->len = atoll((const char *)pp);
+						lwsl_notice("scp payload %llu expected\n",
+							    (unsigned long long)scp->len);
+						scp->ips = SSHS_SCP_PAYLOADIN;
+					}
+					/* ack it */
+					write_task(pss, pss->ch_temp,
+						   SSH_WT_SCP_ACK_OKAY);
+					break;
+				case SSHS_SCP_PAYLOADIN:
+					/* the scp file payload */
+					if (pss->vhd->ops)
+						pss->vhd->ops->rx(ch->priv,
+							pss->wsi, pp, pss->npos);
+					if (scp->len >= pss->npos)
+						scp->len -= pss->npos;
+					else
+						scp->len = 0;
+					if (!scp->len) {
+						lwsl_notice("scp txfer completed\n");
+						scp->ips = SSHS_SCP_COLLECTSTR;
+						break;
+					}
+					break;
+				}
+				break;
+			default: /* scp payload */
+				if (pss->vhd->ops)
+					pss->vhd->ops->rx(ch->priv, pss->wsi,
+							  pp, pss->npos);
+				break;
+			}
+			if (pss->parser_state == SSHS_NVC_CD_DATA_ALLOC)
+				ssh_free(pss->last_alloc);
+
+			if (ch->peer_window_est < 32768) {
+				write_task(pss, ch, SSH_WT_WINDOW_ADJUST);
+				ch->peer_window_est += 32768;
+				lwsl_notice("extra peer WINDOW_ADJUST (~ %d)\n",
+					    ch->peer_window_est);
+			}
+
+			pss->parser_state = SSHS_MSG_EAT_PADDING;
+			break;
+
+		case SSHS_NVC_WA_RECIP:
+			pss->ch_recip = pss->len;
+			state_get_u32(pss, SSHS_NVC_WA_ADD);
+			break;
+
+		case SSHS_NVC_WA_ADD:
+			ch = ssh_get_server_ch(pss, pss->ch_recip);
+			if (ch) {
+				ch->window += pss->len;
+				lwsl_notice("got additional window %d (now %d)\n",
+						pss->len, ch->window);
+			}
+			pss->parser_state = SSHS_MSG_EAT_PADDING;
+			break;
+
+			/*
+			 *  channel close
+			 */
+
+		case SSHS_NVC_CH_EOF:
+			/*
+			 * No explicit response is sent to this
+			 * message.  However, the application may send
+			 * EOF to whatever is at the other end of the
+			 * channel.  Note that the channel remains open
+			 * after this message, and more data may still
+			 * be sent in the other direction.  This message
+			 * does not consume window space and can be sent
+			 * even if no window space is available.
+			 */
+			lwsl_notice("SSH_MSG_CHANNEL_EOF: %d\n", pss->ch_recip);
+			ch = ssh_get_server_ch(pss, pss->ch_recip);
+			if (!ch)
+				return -1;
+
+			if (!ch->had_eof) {
+				ch->had_eof = 1;
+				write_task(pss, ch, SSH_WT_CH_CLOSE);
+			}
+			pss->parser_state = SSHS_MSG_EAT_PADDING;
+			break;
+
+		case SSHS_NVC_CH_CLOSE:
+			/*
+			 * When either party wishes to terminate the
+			 * channel, it sends SSH_MSG_CHANNEL_CLOSE.
+			 * Upon receiving this message, a party MUST
+			 * send back an SSH_MSG_CHANNEL_CLOSE unless it
+			 * has already sent this message for the
+			 * channel.  The channel is considered closed
+			 * for a party when it has both sent and
+			 * received SSH_MSG_CHANNEL_CLOSE, and the
+			 * party may then reuse the channel number.
+			 * A party MAY send SSH_MSG_CHANNEL_CLOSE
+			 * without having sent or received
+			 * SSH_MSG_CHANNEL_EOF.
+			 */
+			lwsl_notice("SSH_MSG_CHANNEL_CLOSE ch %d\n",
+				    pss->ch_recip);
+			ch = ssh_get_server_ch(pss, pss->ch_recip);
+			if (!ch)
+				goto bail;
+
+			pss->parser_state = SSHS_MSG_EAT_PADDING;
+
+			if (ch->sent_close) {
+				/*
+				 * This is acking our sent close...
+				 * we can destroy the channel with no
+				 * further communication.
+				 */
+				ssh_destroy_channel(pss, ch);
+				break;
+			}
+
+			ch->received_close = 1;
+			write_task(pss, ch, SSH_WT_CH_CLOSE);
+			break;
+
+		default:
+			break;
+
+chrq_fail:
+			lwsl_notice("chrq_fail\n");
+			write_task(pss, pss->ch_temp, SSH_WT_CHRQ_FAILURE);
+			pss->parser_state = SSH_KEX_STATE_SKIP;
+			break;
+
+ch_fail:
+			if (pss->ch_temp) {
+				free(pss->ch_temp);
+				pss->ch_temp = NULL;
+			}
+			write_task(pss, pss->ch_temp, SSH_WT_CH_FAILURE);
+			pss->parser_state = SSH_KEX_STATE_SKIP;
+			break;
+
+ua_fail1:
+#if defined(LWS_USE_MBEDTLS)
+			mbedtls_rsa_free(ctx);
+			free(ctx);
+#else
+			/* also frees the bignums */
+			RSA_free(rsa);
+#endif
+ua_fail:
+			write_task(pss, NULL, SSH_WT_UA_FAILURE);
+ua_fail_silently:
+			lws_ua_destroy(pss);
+			/* Sect 4, RFC4252
+			 *
+			 * Additionally, the implementation SHOULD limit the
+			 * number of failed authentication attempts a client
+			 * may perform in a single session (the RECOMMENDED
+			 * limit is 20 attempts).  If the threshold is
+			 * exceeded, the server SHOULD disconnect.
+			 */
+			if (pss->count_auth_attempts++ > 20)
+				goto bail;
+
+			pss->parser_state = SSH_KEX_STATE_SKIP;
+			break;
+		}
+
+		pss->pos++;
+	}
+
+	return 0;	
+bail:
+	lws_kex_destroy(pss);
+	lws_ua_destroy(pss);
+
+	return SSH_DISCONNECT_KEY_EXCHANGE_FAILED;
+}
+
+static int
+parse(struct per_session_data__sshd *pss, uint8_t *p, size_t len)
+{
+	while (len--) {
+
+		if (pss->copy_to_I_C && pss->kex->I_C_payload_len <
+				pss->kex->I_C_alloc_len &&
+				pss->parser_state != SSHS_MSG_EAT_PADDING)
+			pss->kex->I_C[pss->kex->I_C_payload_len++] = *p;
+
+		if (pss->active_keys_cts.valid &&
+		    pss->parser_state == SSHS_MSG_LEN)
+			/* take a copy for full decrypt */
+			pss->packet_assembly[pss->pa_pos++] = *p;
+
+		if (pss->active_keys_cts.valid &&
+		    pss->parser_state == SSHS_MSG_PADDING &&
+		    pss->msg_len) {
+			/* we are going to have to decrypt it */
+			uint32_t cp, l = pss->msg_len + 4 +
+				pss->active_keys_cts.MAC_length;
+			uint8_t pt[2048];
+
+			len++;
+			cp = len;
+
+			if (cp > l - pss->pa_pos)
+				cp = l - pss->pa_pos;
+
+			if (cp > sizeof(pss->packet_assembly) -
+					pss->pa_pos) {
+				lwsl_err("Packet is too big to decrypt\n");
+
+				goto bail;
+			}
+			if (pss->msg_len < 2 + 4) {
+				lwsl_err("packet too small\n");
+
+				goto bail;
+			}
+
+			memcpy(&pss->packet_assembly[pss->pa_pos], p, cp);
+			pss->pa_pos += cp;
+			len -= cp;
+			p += cp;
+
+			if (pss->pa_pos != l)
+				return 0;
+
+			/* decrypt it */
+			cp = lws_chacha_decrypt(&pss->active_keys_cts,
+					        pss->ssh_sequence_ctr_cts++,
+					        pss->packet_assembly,
+					        pss->pa_pos, pt);
+			if (cp) {
+				lwsl_notice("Decryption failed: %d\n", cp);
+				goto bail;
+			}
+
+			if (lws_ssh_parse_plaintext(pss, pt + 4, pss->msg_len))
+				goto bail;
+
+			pss->pa_pos = 0;
+			pss->ctr = 0;
+			continue;
+		}
+
+		if (lws_ssh_parse_plaintext(pss, p, 1))
+			goto bail;
+
+		p++;
+	}
+
+	return 0;
+
+bail:
+	lws_kex_destroy(pss);
+	lws_ua_destroy(pss);
+
+	return SSH_DISCONNECT_KEY_EXCHANGE_FAILED;
+}
+
+static uint32_t
+pad_and_encrypt(uint8_t *dest, void *ps, uint8_t *pp,
+		struct per_session_data__sshd *pss, int skip_pad)
+{
+	uint32_t n;
+
+	if (!skip_pad)
+		lws_pad_set_length(pss, ps, &pp, &pss->active_keys_stc);
+	n = pp - (uint8_t *)ps;
+
+	if (!pss->active_keys_stc.valid) {
+		memcpy(dest, ps, n);
+		return n;
+	}
+
+	lws_chacha_encrypt(&pss->active_keys_stc, pss->ssh_sequence_ctr_stc,
+			   ps, n, dest);
+	n += pss->active_keys_stc.MAC_length;
+
+	return n;
+}
+
+static int
+lws_callback_raw_sshd(struct lws *wsi, enum lws_callback_reasons reason,
+		      void *user, void *in, size_t len)
+{
+	struct per_session_data__sshd *pss =
+			(struct per_session_data__sshd *)user, **p;
+	struct per_vhost_data__sshd *vhd = NULL;
+	uint8_t buf[LWS_PRE + 1024], *pp, *ps = &buf[LWS_PRE + 512];
+	const struct lws_protocol_vhost_options *pvo;
+	const struct lws_protocols *prot;
+	struct lws_ssh_channel *ch;
+	char lang[10];
+	int n, m, o;
+
+	/*
+	 * Because we are an abstract protocol plugin, we will get called by
+	 * wsi that actually bind to a plugin "on top of us" that calls thru
+	 * to our callback.
+	 *
+	 * Under those circumstances, we can't simply get a pointer to our own
+	 * protocol from the wsi.  If there's a pss already, we can get it from
+	 * there, but the first time for each connection we have to look it up.
+	 */
+	if (pss && pss->vhd)
+		vhd = (struct per_vhost_data__sshd *)
+			lws_protocol_vh_priv_get(lws_get_vhost(wsi),
+				pss->vhd->protocol);
+	else
+		vhd = (struct per_vhost_data__sshd *)
+				lws_protocol_vh_priv_get(lws_get_vhost(wsi),
+				lws_vhost_name_to_protocol(
+					lws_get_vhost(wsi), "lws-ssh-base"));
+
+	if (!vhd && reason != LWS_CALLBACK_PROTOCOL_INIT)
+		return -1;
+
+	switch ((int)reason) {
+	case LWS_CALLBACK_PROTOCOL_INIT:
+		vhd = lws_protocol_vh_priv_zalloc(lws_get_vhost(wsi),
+						  lws_get_protocol(wsi),
+						  sizeof(struct per_vhost_data__sshd));
+		vhd->context = lws_get_context(wsi);
+		vhd->protocol = lws_get_protocol(wsi);
+		vhd->vhost = lws_get_vhost(wsi);
+
+		pvo = (const struct lws_protocol_vhost_options *)in;
+		while (pvo) {
+			/*
+			 * the user code passes the ops struct address to us
+			 * using a pvo (per-vhost option)
+			 */
+			if (!strcmp(pvo->name, "ops"))
+				vhd->ops = (const struct lws_ssh_ops *)pvo->value;
+
+			/*
+			 * the user code is telling us to get the ops struct
+			 * from another protocol's protocol.user pointer
+			 */
+			if (!strcmp(pvo->name, "ops-from")) {
+				prot = lws_vhost_name_to_protocol(vhd->vhost,
+								  pvo->value);
+				if (prot)
+					vhd->ops = (const struct lws_ssh_ops *)prot->user;
+				else
+					lwsl_err("%s: can't find protocol %s\n",
+						    __func__, pvo->value);
+			}
+
+			pvo = pvo->next;
+		}
+
+		if (!vhd->ops) {
+			lwsl_err("ssh pvo \"ops\" is mandatory\n");
+			return 1;
+		}
+		/*
+		 * The user code ops api_version has to be current
+		 */
+		if (vhd->ops->api_version != LWS_SSH_OPS_VERSION) {
+			lwsl_err("FATAL ops is api_version v%d but code is v%d",
+				vhd->ops->api_version, LWS_SSH_OPS_VERSION);
+			return 1;
+		}
+		break;
+
+        case LWS_CALLBACK_RAW_ADOPT:
+		lwsl_info("LWS_CALLBACK_RAW_ADOPT\n");
+		pss->next = vhd->live_pss_list;
+		vhd->live_pss_list = pss;
+		pss->parser_state = SSH_INITIALIZE_TRANSIENT;
+		pss->wsi = wsi;
+		pss->vhd = vhd;
+		pss->kex_state = KEX_STATE_EXPECTING_CLIENT_OFFER;
+		pss->active_keys_cts.padding_alignment = 8;
+		pss->active_keys_stc.padding_alignment = 8;
+		if (lws_kex_create(pss))
+			return -1;
+		write_task(pss, NULL, SSH_WT_VERSION);
+
+		/* sect 4  RFC4252
+		 *
+		 * The server SHOULD have a timeout for authentication and
+		 * disconnect if the authentication has not been accepted
+		 * within the timeout period.
+		 *
+		 * The RECOMMENDED timeout period is 10 minutes.
+		 */
+		lws_set_timeout(wsi,
+		       SSH_PENDING_TIMEOUT_CONNECT_TO_SUCCESSFUL_AUTH, 10 * 60);
+                break;
+
+	case LWS_CALLBACK_RAW_CLOSE:
+		lwsl_info("LWS_CALLBACK_RAW_CLOSE\n");
+		lws_kex_destroy(pss);
+		lws_ua_destroy(pss);
+
+		while (pss->ch_list)
+			ssh_destroy_channel(pss, pss->ch_list);
+
+		lws_chacha_destroy(&pss->active_keys_cts);
+		lws_chacha_destroy(&pss->active_keys_stc);
+
+		p = &vhd->live_pss_list;
+
+		while (*p) {
+			if ((*p) == pss) {
+				*p = pss->next;
+				continue;
+			}
+			p = &((*p)->next);
+		}
+		break;
+
+	case LWS_CALLBACK_RAW_RX:
+		if (parse(pss, in, len))
+			return -1;
+		break;
+
+	case LWS_CALLBACK_RAW_WRITEABLE:
+		n = 0;
+		o = pss->write_task[pss->wt_tail];
+		ch = pss->write_channel[pss->wt_tail];
+
+		if (pss->wt_head == pss->wt_tail)
+			o = SSH_WT_NONE;
+
+		switch (o) {
+		case SSH_WT_VERSION:
+			if (!pss->vhd)
+				break;
+			n = lws_snprintf((char *)buf + LWS_PRE,
+					 sizeof(buf) - LWS_PRE - 1, "%s\r\n",
+					 pss->vhd->ops->server_string);
+			write_task(pss, NULL, SSH_WT_OFFER);
+			break;
+
+		case SSH_WT_OFFER:
+			if (!pss->vhd)
+				break;
+			m = 0;
+			n = offer(pss, buf + LWS_PRE,
+				  sizeof(buf) - LWS_PRE, 0, &m);
+			if (n == 0) {
+				lwsl_notice("Too small\n");
+
+				return -1;
+			}
+
+			if (!pss->kex) {
+				lwsl_notice("%s: SSH_WT_OFFER: pss->kex is NULL\n",
+					    __func__);
+				return -1;
+			}
+
+			/* we need a copy of it to generate the hash later */
+			if (pss->kex->I_S)
+				free(pss->kex->I_S);
+			pss->kex->I_S = sshd_zalloc(m);
+			if (!pss->kex->I_S) {
+				lwsl_notice("OOM 5: %d\n", m);
+
+				return -1;
+			}
+			/* without length + padcount part */
+			memcpy(pss->kex->I_S, buf + LWS_PRE + 5, m);
+			pss->kex->I_S_payload_len = m; /* without padding */
+			break;
+
+		case SSH_WT_OFFER_REPLY:
+			memcpy(ps, pss->kex->kex_r, pss->kex->kex_r_len);
+			n = pad_and_encrypt(&buf[LWS_PRE], ps,
+					    ps + pss->kex->kex_r_len, pss, 1);
+			pss->kex_state = KEX_STATE_REPLIED_TO_OFFER;
+			/* afterwards, must do newkeys */
+			write_task(pss, NULL, SSH_WT_SEND_NEWKEYS);
+			break;
+
+		case SSH_WT_SEND_NEWKEYS:
+			pp = ps + 5;
+			*pp++ = SSH_MSG_NEWKEYS;
+			goto pac;
+
+		case SSH_WT_UA_ACCEPT:
+			/*
+			 *  If the server supports the service (and permits
+			 *  the client to use it), it MUST respond with the
+			 *  following:
+			 *
+			 *      byte      SSH_MSG_SERVICE_ACCEPT
+			 *      string    service name
+			 */
+			pp = ps + 5;
+			*pp++ = SSH_MSG_SERVICE_ACCEPT;
+			lws_p32(pp, pss->npos);
+			pp += 4;
+			strcpy((char *)pp, pss->name);
+			pp += pss->npos;
+			goto pac;
+
+		case SSH_WT_UA_FAILURE:
+			pp = ps + 5;
+			*pp++ = SSH_MSG_USERAUTH_FAILURE;
+			lws_p32(pp, 9);
+			pp += 4;
+			strcpy((char *)pp, "publickey");
+			pp += 9;
+			*pp++ = 0;
+			goto pac;
+
+		case SSH_WT_UA_BANNER:
+			pp = ps + 5;
+			*pp++ = SSH_MSG_USERAUTH_BANNER;
+			if (pss->vhd && pss->vhd->ops->banner)
+				n = pss->vhd->ops->banner((char *)&buf[650],
+							  150 - 1,
+							  lang, sizeof(lang));
+			lws_p32(pp, n);
+			pp += 4;
+			strcpy((char *)pp, (char *)&buf[650]);
+			pp += n;
+			if (lws_cstr(&pp, lang, sizeof(lang)))
+				goto bail;
+			goto pac;
+
+		case SSH_WT_UA_PK_OK:
+			/*
+			 *  The server MUST respond to this message with
+			 *  either SSH_MSG_USERAUTH_FAILURE or with the
+			 *  following:
+			 *
+			 *    byte      SSH_MSG_USERAUTH_PK_OK
+			 *    string    public key alg name from the request
+			 *    string    public key blob from the request
+      			 */
+			n = 74 + pss->ua->pubkey_len;
+			if (n > sizeof(buf) - LWS_PRE) {
+				lwsl_notice("pubkey too large\n");
+				goto bail;
+			}
+			ps = sshd_zalloc(n);
+			if (!ps)
+				goto bail;
+			pp = ps + 5;
+			*pp++ = SSH_MSG_USERAUTH_PK_OK;
+			if (lws_cstr(&pp, pss->ua->alg, 64)) {
+				free(ps);
+				goto bail;
+			}
+			lws_p32(pp, pss->ua->pubkey_len);
+			pp += 4;
+			memcpy(pp, pss->ua->pubkey, pss->ua->pubkey_len);
+			pp += pss->ua->pubkey_len;
+
+			/* we no longer need the UA now we judged it */
+			lws_ua_destroy(pss);
+
+			goto pac;
+
+		case SSH_WT_UA_SUCCESS:
+			pp = ps + 5;
+			*pp++ = SSH_MSG_USERAUTH_SUCCESS;
+			/* end SSH_PENDING_TIMEOUT_CONNECT_TO_SUCCESSFUL_AUTH */
+			lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
+			goto pac;
+
+		case SSH_WT_CH_OPEN_CONF:
+			pp = ps + 5;
+			*pp++ = SSH_MSG_CHANNEL_OPEN_CONFIRMATION;
+			lws_p32(pp, pss->ch_temp->server_ch);
+			pp += 4;
+			lws_p32(pp, pss->ch_temp->sender_ch);
+			pp += 4;
+			/* tx initial window size towards us */
+			lws_p32(pp, LWS_SSH_INITIAL_WINDOW);
+			pp += 4;
+			/* maximum packet size towards us */
+			lws_p32(pp, 800);
+			pp += 4;
+			lwsl_info("SSH_WT_CH_OPEN_CONF\n");
+			/* it's on the linked-list */
+			pss->ch_temp = NULL;
+			goto pac;
+
+		case SSH_WT_CH_FAILURE:
+			pp = ps + 5;
+			*pp++ = SSH_MSG_CHANNEL_OPEN_FAILURE;
+			lws_p32(pp, ch->server_ch);
+			pp += 4;
+			lws_p32(pp, ch->sender_ch);
+			pp += 4;
+			lws_cstr(&pp, "reason", 64);
+			lws_cstr(&pp, "en/US", 64);
+			lwsl_info("SSH_WT_CH_FAILURE\n");
+			goto pac;
+
+		case SSH_WT_CHRQ_SUCC:
+			pp = ps + 5;
+			*pp++ = SSH_MSG_CHANNEL_SUCCESS;
+			lws_p32(pp, ch->server_ch);
+			lwsl_info("SSH_WT_CHRQ_SUCC\n");
+			pp += 4;
+			goto pac;
+
+		case SSH_WT_CHRQ_FAILURE:
+			pp = ps + 5;
+			*pp++ = SSH_MSG_CHANNEL_FAILURE;
+			lws_p32(pp, ch->server_ch);
+			pp += 4;
+			lwsl_info("SSH_WT_CHRQ_FAILURE\n");
+			goto pac;
+
+		case SSH_WT_CH_CLOSE:
+			pp = ps + 5;
+			*pp++ = SSH_MSG_CHANNEL_CLOSE;
+			lws_p32(pp, ch->server_ch);
+			lwsl_info("SSH_WT_CH_CLOSE\n");
+			pp += 4;
+			goto pac;
+
+		case SSH_WT_CH_EOF:
+			pp = ps + 5;
+			*pp++ = SSH_MSG_CHANNEL_EOF;
+			lws_p32(pp, ch->server_ch);
+			lwsl_info("SSH_WT_CH_EOF\n");
+			pp += 4;
+			goto pac;
+
+		case SSH_WT_SCP_ACK_ERROR:
+		case SSH_WT_SCP_ACK_OKAY:
+			pp = ps + 5;
+			*pp++ = SSH_MSG_CHANNEL_DATA;
+			/* ps + 6 */
+			lws_p32(pp, ch->sender_ch);
+			pp += 4;
+			lws_p32(pp, 1);
+			pp += 4;
+			if (o == SSH_WT_SCP_ACK_ERROR)
+				*pp++ = 2;
+			else
+				*pp++ = 0;
+			lwsl_info("SSH_WT_SCP_ACK_OKAY\n");
+			goto pac;
+
+		case SSH_WT_WINDOW_ADJUST:
+			pp = ps + 5;
+			*pp++ = SSH_MSG_CHANNEL_WINDOW_ADJUST;
+			/* ps + 6 */
+			lws_p32(pp, ch->sender_ch);
+			pp += 4;
+			lws_p32(pp, 32768);
+			pp += 4;
+			lwsl_info("send SSH_MSG_CHANNEL_WINDOW_ADJUST\n");
+			goto pac;
+
+		case SSH_WT_NONE:
+		default:
+			/* sending payload */
+
+			ch = ssh_get_server_ch(pss, 0);
+			/* have a channel up to send on? */
+			if (!ch)
+				break;
+
+			if (!pss->vhd || !pss->vhd->ops)
+				break;
+			n = pss->vhd->ops->tx_waiting(ch->priv);
+			if (n < 0)
+				return -1;
+			if (!n)
+				/* nothing to send */
+				break;
+
+			if (n == (LWS_STDOUT | LWS_STDERR)) {
+				/* pick one using round-robin */
+				if (pss->serviced_stderr_last)
+					n = LWS_STDOUT;
+				else
+					n = LWS_STDERR;
+			}
+
+			pss->serviced_stderr_last = !!(n & LWS_STDERR);
+
+			/* stdout or stderr */
+			pp = ps + 5;
+			if (n == LWS_STDOUT)
+				*pp++ = SSH_MSG_CHANNEL_DATA;
+			else
+				*pp++ = SSH_MSG_CHANNEL_EXTENDED_DATA;
+			/* ps + 6 */
+			lws_p32(pp, pss->ch_list->server_ch);
+			m = 14;
+			if (n == LWS_STDERR) {
+				pp += 4;
+				/* data type code... 1 for stderr payload */
+				lws_p32(pp, SSH_EXTENDED_DATA_STDERR);
+				m = 18;
+			}
+			/* also skip another strlen u32 at + 10 / +14 */
+			pp += 8;
+			/* ps + 14 / + 18 */
+
+			pp += pss->vhd->ops->tx(ch->priv, n, pp,
+						&buf[sizeof(buf) - 1] - pp);
+
+			lws_p32(ps + m - 4, pp - (ps + m));
+
+			if (pss->vhd->ops->tx_waiting(ch->priv) > 0)
+				lws_callback_on_writable(wsi);
+
+			ch->window -= (pp - ps) - m;
+			//lwsl_debug("our send window: %d\n", ch->window);
+
+			/* fallthru */
+pac:
+			if (!pss->vhd)
+				break;
+			n = pad_and_encrypt(&buf[LWS_PRE], ps, pp, pss, 0);
+			break;
+
+bail:
+			lws_ua_destroy(pss);
+			lws_kex_destroy(pss);
+
+			return 1;
+
+		}
+
+		if (n > 0) {
+			m = lws_write(wsi, (unsigned char *)buf + LWS_PRE, n,
+				      LWS_WRITE_HTTP);
+
+			switch(o) {
+			case SSH_WT_SEND_NEWKEYS:
+				lwsl_info("Activating STC keys\n");
+				pss->active_keys_stc = pss->kex->keys_next_stc;
+				lws_chacha_activate(&pss->active_keys_stc);
+				pss->kex_state = KEX_STATE_CRYPTO_INITIALIZED;
+				pss->kex->newkeys |= 1;
+				if (pss->kex->newkeys == 3)
+					lws_kex_destroy(pss);
+				break;
+			case SSH_WT_UA_PK_OK:
+				free(ps);
+				break;
+			case SSH_WT_CH_CLOSE:
+				if (ch->received_close) {
+					/*
+					 * We are sending this at the behest of
+					 * the remote peer...
+					 * we can destroy the channel with no
+					 * further communication.
+					 */
+					ssh_destroy_channel(pss, ch);
+					break;
+				}
+				ch->sent_close = 1;
+				break;
+			}
+	                if (m < 0) {
+	                        lwsl_err("ERR %d from write\n", m);
+	                        goto bail;
+	                }
+
+			if (o != SSH_WT_VERSION)
+				pss->ssh_sequence_ctr_stc++;
+
+			if (o != SSH_WT_NONE)
+				pss->wt_tail =
+					(pss->wt_tail + 1) & 3;
+		} else
+			if (o == SSH_WT_UA_PK_OK) /* free it either way */
+				free(ps);
+
+		ch = ssh_get_server_ch(pss, 0);
+
+		if (pss->wt_head != pss->wt_tail ||
+		    (ch && ch->priv && pss->vhd &&
+		     pss->vhd->ops->tx_waiting(ch->priv)))
+		       lws_callback_on_writable(wsi);
+
+		break;
+
+	case LWS_CALLBACK_SSH_UART_SET_RXFLOW:
+		/*
+		 * this is sent to set rxflow state on any connections that
+		 * sink on a particular sink.  The sink index affected is in len
+		 *
+		 * More than one protocol may sink to the same uart, and the
+		 * protocol may select the sink itself, eg, in the URL used
+		 * to set up the connection.
+		 */
+		lwsl_notice("sshd LWS_CALLBACK_SSH_UART_SET_RXFLOW: wsi %p, %d\n",
+				wsi, (int)len & 1);
+		lws_rx_flow_control(wsi, len & 1);
+		break;
+
+	case LWS_CALLBACK_CGI:
+		if (pss->vhd && pss->vhd->ops &&
+		    pss->vhd->ops->child_process_io &&
+		    pss->vhd->ops->child_process_io(pss->ch_temp->priv,
+					pss->wsi, (struct lws_cgi_args *)in))
+			return -1;
+		break;
+
+	case LWS_CALLBACK_CGI_PROCESS_ATTACH:
+		ch = ssh_get_server_ch(pss, pss->channel_doing_spawn);
+		if (ch) {
+			ch->spawn_pid = len; /* child process PID */
+			lwsl_notice("associated PID %d to ch %d\n", (int)len,
+				    pss->channel_doing_spawn);
+		}
+		break;
+
+	case LWS_CALLBACK_CGI_TERMINATED:
+		if (pss->vhd && pss->vhd->ops &&
+		    pss->vhd->ops->child_process_terminated)
+		    pss->vhd->ops->child_process_terminated(pss->ch_temp->priv,
+							    pss->wsi);
+		/*
+		 * we have the child PID in len... we need to match it to a
+		 * channel that is on the wsi
+		 */
+		ch = pss->ch_list;
+
+		while (ch) {
+			if (ch->spawn_pid == len) {
+				lwsl_notice("starting close of ch with PID %d\n",
+					    (int)len);
+				write_task(pss, ch, SSH_WT_CH_CLOSE);
+				break;
+			}
+			ch = ch->next;
+		}
+		break;
+
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+#define LWS_PLUGIN_PROTOCOL_LWS_RAW_SSHD { \
+		"lws-ssh-base",	\
+		lws_callback_raw_sshd,	\
+		sizeof(struct per_session_data__sshd),	\
+		1024, 0, NULL, 900	\
+	}
+
+LWS_VISIBLE const struct lws_protocols protocols_sshd[] = {
+	LWS_PLUGIN_PROTOCOL_LWS_RAW_SSHD,
+	{ NULL, NULL, 0, 0, 0, NULL, 0 } /* terminator */
+};
+
+#if !defined (LWS_PLUGIN_STATIC)
+
+LWS_VISIBLE int
+init_protocol_lws_ssh_base(struct lws_context *context,
+			     struct lws_plugin_capability *c)
+{
+	if (c->api_magic != LWS_PLUGIN_API_MAGIC) {
+		lwsl_err("Plugin API %d, library API %d", LWS_PLUGIN_API_MAGIC,
+			 c->api_magic);
+		return 1;
+	}
+
+	c->protocols = protocols_sshd;
+	c->count_protocols = ARRAY_SIZE(protocols_sshd);
+	c->extensions = NULL;
+	c->count_extensions = 0;
+
+	return 0;
+}
+
+LWS_VISIBLE int
+destroy_protocol_lws_ssh_base(struct lws_context *context)
+{
+	return 0;
+}
+#endif
diff --git a/plugins/ssh-base/telnet.c b/plugins/ssh-base/telnet.c
new file mode 100644
index 0000000000000000000000000000000000000000..62d7a808e9ed333b6da124cdd9dc4b3915c6fa29
--- /dev/null
+++ b/plugins/ssh-base/telnet.c
@@ -0,0 +1,260 @@
+/*
+ * libwebsockets - lws-plugin-ssh-base
+ *
+ * Copyright (C) 2017 Andy Green <andy@warmcat.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation:
+ *  version 2.1 of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "libwebsockets.h"
+#include "lws-ssh.h"
+
+#include <string.h>
+
+struct per_vhost_data__telnet {
+	struct lws_context *context;
+	struct lws_vhost *vhost;
+	const struct lws_protocols *protocol;
+	struct per_session_data__telnet *live_pss_list;
+	const struct lws_ssh_ops *ops;
+};
+
+struct per_session_data__telnet {
+	struct per_session_data__telnet *next;
+	struct per_vhost_data__telnet *vhd;
+	uint32_t rx_tail;
+	void *priv;
+
+	uint32_t initial:1;
+
+	char state;
+	uint8_t cmd;
+};
+
+enum {
+	LTS_BINARY_XMIT,
+	LTS_ECHO,
+	LTS_SUPPRESS_GA,
+
+
+	LTSC_SUBOPT_END		= 240,
+	LTSC_BREAK		= 243,
+	LTSC_SUBOPT_START	= 250,
+	LTSC_WILL		= 251,
+	LTSC_WONT,
+	LTSC_DO,
+	LTSC_DONT,
+	LTSC_IAC,
+
+	LTST_WAIT_IAC		= 0,
+	LTST_GOT_IAC,
+	LTST_WAIT_OPT,
+};
+
+static int
+telnet_ld(struct per_session_data__telnet *pss, uint8_t c)
+{
+	switch (pss->state) {
+	case LTST_WAIT_IAC:
+		if (c == LTSC_IAC) {
+			pss->state = LTST_GOT_IAC;
+			return 0;
+		}
+		return 1;
+
+	case LTST_GOT_IAC:
+		pss->state = LTST_WAIT_IAC;
+
+		switch (c) {
+		case LTSC_BREAK:
+			return 0;
+		case LTSC_WILL:
+		case LTSC_WONT:
+		case LTSC_DO:
+		case LTSC_DONT:
+			pss->cmd = c;
+			pss->state = LTST_WAIT_OPT;
+			return 0;
+		case LTSC_IAC:
+			return 1; /* double IAC */
+		}
+		return 0; /* ignore unknown */
+
+	case LTST_WAIT_OPT:
+		lwsl_notice(" tld: cmd %d: opt %d\n", pss->cmd, c);
+		pss->state = LTST_WAIT_IAC;
+		return 0;	
+	}
+
+	return 0;
+}
+
+static uint8_t init[] = {
+	LTSC_IAC, LTSC_WILL, 3,
+	LTSC_IAC, LTSC_WILL, 1,
+	LTSC_IAC, LTSC_DONT, 1,
+	LTSC_IAC, LTSC_DO,   0
+};
+
+static int
+lws_callback_raw_telnet(struct lws *wsi, enum lws_callback_reasons reason,
+			void *user, void *in, size_t len)
+{
+	struct per_session_data__telnet *pss =
+			(struct per_session_data__telnet *)user, **p;
+	struct per_vhost_data__telnet *vhd =
+			(struct per_vhost_data__telnet *)
+			lws_protocol_vh_priv_get(lws_get_vhost(wsi),
+					lws_get_protocol(wsi));
+	const struct lws_protocol_vhost_options *pvo =
+			(const struct lws_protocol_vhost_options *)in;
+	int n, m;
+	uint8_t buf[LWS_PRE + 800], *pu = in;
+
+	switch ((int)reason) {
+	case LWS_CALLBACK_PROTOCOL_INIT:
+		vhd = lws_protocol_vh_priv_zalloc(lws_get_vhost(wsi),
+				lws_get_protocol(wsi),
+				sizeof(struct per_vhost_data__telnet));
+		vhd->context = lws_get_context(wsi);
+		vhd->protocol = lws_get_protocol(wsi);
+		vhd->vhost = lws_get_vhost(wsi);
+
+		while (pvo) {
+			if (!strcmp(pvo->name, "ops"))
+				vhd->ops = (const struct lws_ssh_ops *)pvo->value;
+
+			pvo = pvo->next;
+		}
+
+		if (!vhd->ops) {
+			lwsl_err("telnet pvo \"ops\" is mandatory\n");
+			return -1;
+		}
+		break;
+
+        case LWS_CALLBACK_RAW_ADOPT:
+		pss->next = vhd->live_pss_list;
+		vhd->live_pss_list = pss;
+		pss->vhd = vhd;
+		pss->state = LTST_WAIT_IAC;
+		pss->initial = 0;
+		if (vhd->ops->channel_create)
+			vhd->ops->channel_create(wsi, &pss->priv);
+		lws_callback_on_writable(wsi);
+                break;
+
+	case LWS_CALLBACK_RAW_CLOSE:
+		p = &vhd->live_pss_list;
+
+		while (*p) {
+			if ((*p) == pss) {
+				if (vhd->ops->channel_destroy)
+					vhd->ops->channel_destroy(pss->priv);
+				*p = pss->next;
+				continue;
+			}
+			p = &((*p)->next);
+		}
+		break;
+
+	case LWS_CALLBACK_RAW_RX:
+		n = 0;
+
+		/* this stuff is coming in telnet line discipline, we
+		 * have to strip IACs and process IAC repeats */
+
+		while (len--) {
+			if (telnet_ld(pss, *pu))
+				buf[n++] = *pu++;
+			else
+				pu++;
+
+			if (n > 100 || !len)
+				pss->vhd->ops->rx(pss->priv, wsi, buf, n);
+		}
+		break;
+
+        case LWS_CALLBACK_RAW_WRITEABLE:
+		n = 0;
+		if (!pss->initial) {
+			memcpy(buf + LWS_PRE, init, sizeof(init));
+
+			n = sizeof(init);
+			pss->initial = 1;
+		} else {
+			/* bring any waiting tx into second half of buffer
+			 * restrict how much we can send to 1/4 of the buffer,
+			 * because we have to apply telnet line discipline...
+			 * in the worst case of all 0xff, doubling the size
+			 */
+			pu = buf + LWS_PRE + 400;
+			m = pss->vhd->ops->tx(pss->priv, LWS_STDOUT, pu,
+					(sizeof(buf) - LWS_PRE - n - 401) / 2);
+
+			/*
+			 * apply telnet line discipline and copy into place
+			 * in output buffer
+			 */
+			while (m--) {
+				if (*pu == 0xff)
+					buf[LWS_PRE + n++] = 0xff;
+				buf[LWS_PRE + n++] = *pu++;
+			}
+		}
+		if (n > 0) {
+			m = lws_write(wsi, (unsigned char *)buf + LWS_PRE, n,
+				      LWS_WRITE_HTTP);
+	                if (m < 0) {
+	                        lwsl_err("ERROR %d writing to di socket\n", m);
+	                        return -1;
+	                }
+		}
+
+		if (vhd->ops->tx_waiting(&pss->priv))
+		       lws_callback_on_writable(wsi);
+		break;
+
+        case LWS_CALLBACK_SSH_UART_SET_RXFLOW:
+        	/*
+        	 * this is sent to set rxflow state on any connections that
+        	 * sink on a particular uart.  The uart index affected is in len
+        	 *
+        	 * More than one protocol may sink to the same uart, and the
+        	 * protocol may select the uart itself, eg, in the URL used
+        	 * to set up the connection.
+        	 */
+        	lws_rx_flow_control(wsi, len & 1);
+        	break;
+
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+const struct lws_protocols protocols_telnet[] = {
+	{
+		"lws-telnetd-base",
+		lws_callback_raw_telnet,
+		sizeof(struct per_session_data__telnet),
+		1024, 0, NULL, 900
+	},
+	{ NULL, NULL, 0, 0, 0, NULL, 0 } /* terminator */
+};
+
+
diff --git a/test-apps/lws-ssh-test-keys b/test-apps/lws-ssh-test-keys
new file mode 100644
index 0000000000000000000000000000000000000000..2c409b2e94eb754ad44099209890f21946414786
--- /dev/null
+++ b/test-apps/lws-ssh-test-keys
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIJKQIBAAKCAgEAp1oj/nPpEg+i5PgujQPSq7gKWuObG7feP3cU9GwiE5QAP/jw
+ZOpkdZcFoF2KMzjHax66sd+KYqg8l53OB2m6gmjpvxa2IZAjy/M2tujzGKrXkqLL
+sCr//+Yk+mVoTZ7DMBMQcLVejCKtDMQHlqsUZ2DVqTTPIjerBc5HRv2BXch6yAU4
+MMzO+zSwjJehhJCRK0QhaaQtksGMRmtwUa4FMF9y5FfB6TCGmBxaNUII+0nKph8E
+tke+Ujqotmjlg6So85wEYPSYMw1kkIuLHgTFdqC9AU8CQDUg3/qdLEC7GihiYaVa
+QUMktsFHsrhssrbqVsxJbkK2ozGaudoqLXKIL+QX3rpX00xWyT+JLhzrEj9JbENp
+aTA0ADUhxL18cxySwy1zPYFyc8CfmYkbekfm35j9Z3zdzIlrcXCGwWp1sECusUwi
+gXuMD2irWuRFOsLCz3mpDiFc6Hmjrvx7G7T2ZcF9DLv6FBXHysigIZZFNeTDgCBH
+1D6PGIedm1jJSJaWWuMVmyzBsNxq7Kzz3XLAGrsqr2OPzY41kG1oT9UrlH77+e9P
+TyIjlI1Sith1MJkdaLnIelzEBl3zEdYdVo73Pm5DbNe4AiK0JxYpQGSwt0ptzqYs
+/+CzvfR8OOPBtETNr0J9JiROOsBLvwddFOiX+BH6I4YdXZPOQQ9S0yG/jd0CAwEA
+AQKCAgAC3XY0SwO4fXAKf308iM44hmQW/kKPjOxPJdjD/n3u29/NOJPVBnZF1RoR
+jsho7BXt7Y7AsNULr1mqNtdqJRM+XFF0Jg1kMbWLLlTHeOGAkJw0NHlMQNA1L1l+
+t/G7MnahAhKL+27s80MHLuv6Vl95DZ1a0j6hlVZmOQvbWUe3tVD0z7IQk9EPV+2V
+2pq3TEpP9VClIFxvYMToB7raiyInm9q5sg7t0Rjczc91jfXdZ3wCsBFClaPagIqW
+5ODZCh6iXQ9uIYHhjd8k4l61WtuOll3mAdZGByLS8tVyBoGthvd4OH59E4szXce+
+dY3W2W7VoZW4P4gk7xp5CBUkxgsyz5yJR4rNKVV9JSDAGpfBGsoCFMwXjeq/u1JQ
+RRAViVmB8QYSoVmHf/f+IXYXuVbwzAZMoUf1DHjAG94bxyPi6tAshw79jDxJudnv
+L3mFVYrtRD+dXlihdrUX8UOBfnNd3oxA5FXHV8zOwhpZwr8rsfXLXKAtL/XPfiLj
+VbK9gAikS3dnVibioTMa8O8qUSRRb4zaqrV5bBgVvmNMNyP+bOXDBAf86sNt/blb
+Sf8P/yruWVOQTafhHtDbaEFgaDDZ7JabCiVu6Q2faBAVfnxho9ynL0AalM6fkrAP
+D2nWii4DeNKg4+yc9gDk9LlDX9SqLwND6wQYhpXhsH41ZDxvQQKCAQEAz2SoF0rO
+FvWAJElMLGtTIzxT8otABP5vWfhBzY+MtFo7iRlmMDEL+2fYYYK3PGzhSyNMwhAW
+QBrhqCZJc1DPtqubxeqkpnloHQvQy4YB8GeM6dAerj+/1k3Ox3tg2EaFaPuOOxhy
+krgr53K8+O6DFa3OMHVijPRKr0RgzNHJxkLcfaSrjCd27kPp68ndW79rt2hWgyCP
+P+97XEjBo7CegHcfOuZKcFtHVD9PyScP7Piv0wtuoCpi3/GyiBaQCpcyK02duQDs
+eFK9bLMtZvnKl0L+tLYjvyBjBjd6m3MuQR+4CH2mKB1zpdPftp2/yPjUTue3eGjB
+/hfy9ZEB3Qo+NQKCAQEAzpMRMztnvpYcPt3yhGGyqivtPL/2g6rsGwmpaTpWywF5
+1LfscLSpmJ0JYQsHn6Gpqcezsf/VOAUilE5L333ZFAfMOwi49YJ2b8Aok8tbt1+j
+fdl6o3weSyMTO/hBfR48Fk9tB1hZgh0u3xlYf+vRH/ilEFOgqhNmRVL19rr8lW1t
+8ZpHV/7lfX/2bLgW1g8ng+vS0OMe6ugdoRXVvJzUBccKqpksOTuUmmv7xyAKQoUe
+JbtOFRYKAeOo+eIeOxNbyl5kn7+Dh5P1049F+ERbiDSc20Q+8kyJoiVQbYVLJN2A
+2Mb7EUt/xolzQLnVjvTtE4LsN688g122+HfrLXmmCQKCAQBhqqZaKbk6KK0K6ZW8
+yWIiktN5wkgI0gWAWiAq/PInMOMeol50TXS2FWZaLWO7Sg8jAmGwdkD0OXSRak5m
+xuS6wsAeCW02lLAKFbljTx10qF888Oyx5IWkF4pMePbXgwZqtSR7Af1ayO6sFWWW
+2UPUHsCeI3mgpZ7SQSJQ8m7SNkR9yuGapC8m78amaq8a+N9yROmQ4PF1C4ONpxnB
+y3gpSW/knfTqSqIhs5sQQJwIXej3O0gCl1Nu4PTRj8aPpjpTGD8xk5TI6TYZjZvR
+Bct5RmyKj8fvxwG7OL89m5Vpx9Uz8nAgLhZ7Pnb5GfrqWvwomIjXZIYO8hpRuNMm
+1B8NAoIBAQCKqGDFOLy8StoOwL/GaCWa3/1P57I6UwJEa8nRHh2gCg+S3xnP1RR5
+of7nqpWlasgNdESD2CtwfNHnJl77Vufc8BcAESzFbpq9DAiwm7GmdoWxNceB8RAM
+czC38j1TFHZUq1+NrJn4IkqR6dtjkhA/G5EAUoHnZzogkj0TLhPY4SkJIPt+b1Pv
+V3M7Kp35dRabEDHjkG/yUXeB5rwe7E3Myvu34zSx/fITbSQFVtZMLDo+LWmN8csp
+1XxYrpSIJshYH9/+8ngBCynYpbTbnlaqKFaZP0fZL9K6ib1gpjX4Os3/tCBWTY0o
+4J4B9jsIyBJSJHEWN4Ow0bi9MxEi5yKxAoIBAQCJOAIDUxI/6FgXzpl3HBfbsRZS
+g0vI9pXRT5mAKx+ovVubXO7sJL1GlG9H4nKcVWTThzqyeskosBMF0RkKB7VAj2Ur
+pYFcVsrtM6U4wiSpiHXyPGSK6jevCJQZEQ8MKSg69HRTPFFXc39afXq1xqJVamtp
+5QjLttBeoidnzuKpNUdIqJzmehevipofB/lvXZ/e8CzNNh2ryW0gwFo8b+StuMou
+cIaynvwaVdMm5/4LsAwE08liLshMIxng6FNnxEMzZ6fiSFT1jq1qv54agqWfFEOJ
+57g8A/HpVKmSQXFyq1QEdKlA2vttuavq3iIW2OpUnxAnk8ZPo9oRoR8YQ7PH
+-----END RSA PRIVATE KEY-----
diff --git a/test-apps/lws-ssh-test-keys.pub b/test-apps/lws-ssh-test-keys.pub
new file mode 100644
index 0000000000000000000000000000000000000000..ea854fe8c5385db278a64f1106954f3b6747dc1d
--- /dev/null
+++ b/test-apps/lws-ssh-test-keys.pub
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCnWiP+c+kSD6Lk+C6NA9KruApa45sbt94/dxT0bCITlAA/+PBk6mR1lwWgXYozOMdrHrqx34piqDyXnc4HabqCaOm/FrYhkCPL8za26PMYqteSosuwKv//5iT6ZWhNnsMwExBwtV6MIq0MxAeWqxRnYNWpNM8iN6sFzkdG/YFdyHrIBTgwzM77NLCMl6GEkJErRCFppC2SwYxGa3BRrgUwX3LkV8HpMIaYHFo1Qgj7ScqmHwS2R75SOqi2aOWDpKjznARg9JgzDWSQi4seBMV2oL0BTwJANSDf+p0sQLsaKGJhpVpBQyS2wUeyuGyytupWzEluQrajMZq52iotcogv5BfeulfTTFbJP4kuHOsSP0lsQ2lpMDQANSHEvXxzHJLDLXM9gXJzwJ+ZiRt6R+bfmP1nfN3MiWtxcIbBanWwQK6xTCKBe4wPaKta5EU6wsLPeakOIVzoeaOu/HsbtPZlwX0Mu/oUFcfKyKAhlkU15MOAIEfUPo8Yh52bWMlIlpZa4xWbLMGw3GrsrPPdcsAauyqvY4/NjjWQbWhP1SuUfvv5709PIiOUjVKK2HUwmR1ouch6XMQGXfMR1h1Wjvc+bkNs17gCIrQnFilAZLC3Sm3Opiz/4LO99Hw448G0RM2vQn0mJE46wEu/B10U6Jf4Efojhh1dk85BD1LTIb+N3Q== agreen@build
diff --git a/test-apps/test-sshd.c b/test-apps/test-sshd.c
new file mode 100644
index 0000000000000000000000000000000000000000..a881f2844f83fd900ae9862fe61f632b396fe735
--- /dev/null
+++ b/test-apps/test-sshd.c
@@ -0,0 +1,701 @@
+/*
+ * Example embedded sshd server using libwebsockets sshd plugin
+ *
+ * Copyright (C) 2017 Andy Green <andy@warmcat.com>
+ *
+ * This file is made available under the Creative Commons CC0 1.0
+ * Universal Public Domain Dedication.
+ *
+ * The person who associated a work with this deed has dedicated
+ * the work to the public domain by waiving all of his or her rights
+ * to the work worldwide under copyright law, including all related
+ * and neighboring rights, to the extent allowed by law. You can copy,
+ * modify, distribute and perform the work, even for commercial purposes,
+ * all without asking permission.
+ *
+ * The test apps are intended to be adapted for use in your code, which
+ * may be proprietary.	So unlike the library itself, they are licensed
+ * Public Domain.
+ *
+ *
+ * This test app listens on port 2200 for authorized ssh connections.  Run it
+ * using
+ *
+ * $ sudo libwebsockets-test-sshd
+ *
+ * Connect to it using the test private key with:
+ *
+ * $ ssh -p 2200 -i /usr/local/share/libwebsockets-test-server/lws-ssh-test-keys anyuser@127.0.0.1
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <signal.h>
+
+/* import the whole of lws-plugin-sshd-base statically */
+#include <lws-plugin-sshd-static-build-includes.h>
+
+/*
+ * We store the test server's own key here (will be created with a new
+ * random key if it doesn't exist
+ *
+ * The /etc path is the only reason we have to run as root.
+ */
+#define TEST_SERVER_KEY_PATH "/etc/lws-test-sshd-server-key"
+
+/*
+ *  This is a copy of the lws ssh test public key, you can find it in
+ *  /usr[/local]/share/libwebsockets-test-server/lws-ssh-test-keys.pub
+ *  and the matching private key there too in .../lws-ssh-test-keys
+ *
+ *  These keys are distributed for testing!  Don't use them on a real system
+ *  unless you want anyone with a copy of lws to access it.
+ */
+static const char *authorized_key =
+	"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCnWiP+c+kSD6Lk+C6NA9KruApa45sbt"
+	"94/dxT0bCITlAA/+PBk6mR1lwWgXYozOMdrHrqx34piqDyXnc4HabqCaOm/FrYhkCPL8z"
+	"a26PMYqteSosuwKv//5iT6ZWhNnsMwExBwtV6MIq0MxAeWqxRnYNWpNM8iN6sFzkdG/YF"
+	"dyHrIBTgwzM77NLCMl6GEkJErRCFppC2SwYxGa3BRrgUwX3LkV8HpMIaYHFo1Qgj7Scqm"
+	"HwS2R75SOqi2aOWDpKjznARg9JgzDWSQi4seBMV2oL0BTwJANSDf+p0sQLsaKGJhpVpBQ"
+	"yS2wUeyuGyytupWzEluQrajMZq52iotcogv5BfeulfTTFbJP4kuHOsSP0lsQ2lpMDQANS"
+	"HEvXxzHJLDLXM9gXJzwJ+ZiRt6R+bfmP1nfN3MiWtxcIbBanWwQK6xTCKBe4wPaKta5EU"
+	"6wsLPeakOIVzoeaOu/HsbtPZlwX0Mu/oUFcfKyKAhlkU15MOAIEfUPo8Yh52bWMlIlpZa"
+	"4xWbLMGw3GrsrPPdcsAauyqvY4/NjjWQbWhP1SuUfvv5709PIiOUjVKK2HUwmR1ouch6X"
+	"MQGXfMR1h1Wjvc+bkNs17gCIrQnFilAZLC3Sm3Opiz/4LO99Hw448G0RM2vQn0mJE46w"
+	"Eu/B10U6Jf4Efojhh1dk85BD1LTIb+N3Q== ssh-test-key@lws";
+
+static struct lws_context *context = NULL;
+static volatile char force_exit = 0;
+
+/*
+ * These are our "ops" that form our customization of, and interface to, the
+ * generic sshd plugin.
+ *
+ * The priv struct contains our data we want to associate to each channel
+ * individually.
+ */
+
+struct sshd_instance_priv {
+	struct lws_protocol_vhost_options *env;
+	struct lws_ring	*ring_stdout;
+	struct lws_ring	*ring_stderr;
+
+	struct lws 	*wsi_stdout;
+	struct lws 	*wsi_stderr;
+
+	uint32_t	pty_in_bloat_nl_to_crnl:1;
+	uint32_t	pty_in_echo:1;
+	uint32_t	pty_in_cr_to_nl:1;
+
+	uint32_t	insert_lf:1;
+};
+
+
+/* ops: channel lifecycle */
+
+static int
+ssh_ops_channel_create(struct lws *wsi, void **_priv)
+{
+	struct sshd_instance_priv *priv;
+
+	priv = malloc(sizeof(struct sshd_instance_priv));
+	*_priv = priv;
+	if (!priv)
+		return 1;
+
+	memset(priv, 0, sizeof(*priv));
+
+	priv->ring_stdout = lws_ring_create(1, 1024, NULL);
+	if (!priv->ring_stdout) {
+		free(priv);
+
+		return 1;
+	}
+
+	priv->ring_stderr = lws_ring_create(1, 1024, NULL);
+	if (!priv->ring_stderr) {
+		lws_ring_destroy(priv->ring_stdout);
+		free(priv);
+
+		return 1;
+	}
+
+	return 0;
+}
+
+static int
+ssh_ops_channel_destroy(void *_priv)
+{
+	struct sshd_instance_priv *priv = _priv;
+	const struct lws_protocol_vhost_options *pvo = priv->env, *pvo1;
+
+	while (pvo) {
+		pvo1 = pvo;
+		free((char *)pvo->name);
+		free((char *)pvo->value);
+		pvo = pvo->next;
+		free((void *)pvo1);
+	}
+	priv->env = NULL;
+
+	lws_ring_destroy(priv->ring_stdout);
+	lws_ring_destroy(priv->ring_stderr);
+	free(priv);
+
+	return 0;
+}
+
+/* ops: IO */
+
+static int
+ssh_ops_tx_waiting(void *_priv)
+{
+	struct sshd_instance_priv *priv = _priv;
+	int s = 0;
+
+	if (lws_ring_get_count_waiting_elements(priv->ring_stdout, NULL))
+		s |= LWS_STDOUT;
+	if (lws_ring_get_count_waiting_elements(priv->ring_stderr, NULL))
+		s |= LWS_STDERR;
+
+	return s;
+}
+
+static size_t
+ssh_ops_tx(void *_priv, int stdch, uint8_t *buf, size_t len)
+{
+	struct sshd_instance_priv *priv = _priv;
+	struct lws_ring *r;
+	struct lws *wsi;
+	size_t n;
+
+	if (stdch == LWS_STDOUT) {
+		r = priv->ring_stdout;
+		wsi = priv->wsi_stdout;
+	} else {
+		r = priv->ring_stderr;
+		wsi = priv->wsi_stderr;
+	}
+
+	n = lws_ring_consume(r, NULL, buf, len);
+
+	if (n)
+		lws_rx_flow_control(wsi, 1);
+
+	return n;
+}
+
+
+static int
+ssh_ops_rx(void *_priv, struct lws *wsi, const uint8_t *buf, uint32_t len)
+{
+	struct sshd_instance_priv *priv = _priv;
+	struct lws *wsi_stdin = lws_cgi_get_stdwsi(wsi, LWS_STDIN);
+	int fd;
+	uint8_t bbuf[256];
+
+	if (!wsi_stdin)
+		return -1;
+
+	fd = lws_get_socket_fd(wsi_stdin);
+
+	if (*buf != 0x0d) {
+		if (write(fd, buf, len) != len)
+			return -1;
+		if (priv->pty_in_echo) {
+			lws_ring_insert(priv->ring_stdout, buf, 1);
+			lws_callback_on_writable(wsi);
+		}
+	} else {
+		bbuf[0] = 0x0a;
+		bbuf[1] = 0x0a;
+		if (write(fd, bbuf, 1) != 1)
+			return -1;
+
+		if (priv->pty_in_echo) {
+			bbuf[0] = 0x0d;
+			bbuf[1] = 0x0a;
+			lws_ring_insert(priv->ring_stdout, bbuf, 2);
+			lws_callback_on_writable(wsi);
+		}
+	}
+
+	return 0;
+}
+
+/* ops: storage for the (autogenerated) persistent server key */
+
+static size_t
+ssh_ops_get_server_key(struct lws *wsi, uint8_t *buf, size_t len)
+{
+	int fd = open(TEST_SERVER_KEY_PATH, O_RDONLY), n;
+
+	if (fd == -1) {
+		lwsl_err("%s: unable to open %s for read: %s\n", __func__,
+				TEST_SERVER_KEY_PATH, strerror(errno));
+
+		return 0;
+	}
+
+	n = read(fd, buf, len);
+	if (n < 0) {
+		lwsl_err("%s: read failed: %d\n", __func__, n);
+		n = 0;
+	}
+
+	close(fd);
+
+	return n;
+}
+
+static size_t
+ssh_ops_set_server_key(struct lws *wsi, uint8_t *buf, size_t len)
+{
+	int fd = open(TEST_SERVER_KEY_PATH, O_CREAT | O_TRUNC | O_RDWR, 0600);
+	int n;
+
+	lwsl_notice("%s: %d\n", __func__, fd);
+	if (fd == -1) {
+		lwsl_err("%s: unable to open %s for write: %s\n", __func__,
+				TEST_SERVER_KEY_PATH, strerror(errno));
+
+		return 0;
+	}
+
+	n = write(fd, buf, len);
+	if (n < 0) {
+		lwsl_err("%s: read failed: %d\n", __func__, errno);
+		n = 0;
+	}
+
+	close(fd);
+
+	return n;
+}
+
+/* ops: auth */
+
+static int
+ssh_ops_is_pubkey_authorized(const char *username, const char *type,
+				 const uint8_t *peer, int peer_len)
+{
+	char *aps = NULL, *p, *ps;
+	int n = strlen(type), alen = 2048, ret = 2, len;
+	size_t s = 0;
+
+	lwsl_info("%s: checking pubkey for %s\n", __func__, username);
+
+	s = strlen(authorized_key) + 1;
+
+	aps = malloc(s);
+	if (!aps) {
+		lwsl_notice("OOM 1\n");
+		goto bail_p1;
+	}
+	memcpy(aps, authorized_key, s);
+
+	/* this is all we understand at the moment */
+	if (strcmp(type, "ssh-rsa")) {
+		lwsl_notice("type is not ssh-rsa\n");
+		goto bail_p1;
+	}
+	p = aps;
+
+	if (strncmp(p, type, n)) {
+		lwsl_notice("lead-in string  does not match %s\n", type);
+		goto bail_p1;
+	}
+
+	p += n;
+	if (*p != ' ') {
+		lwsl_notice("missing space at end of lead-in\n");
+		goto bail_p1;
+	}
+
+
+	p++;
+	ps = malloc(alen);
+	if (!ps) {
+		lwsl_notice("OOM 2\n");
+		free(aps);
+		goto bail;
+	}
+	len = lws_b64_decode_string(p, ps, alen);
+	free(aps);
+	if (len < 0) {
+		lwsl_notice("key too big\n");
+		goto bail;
+	}
+
+	if (peer_len > len) {
+		lwsl_notice("peer_len %d bigger than decoded len %d\n",
+				peer_len, len);
+		goto bail;
+	}
+
+	/*
+	 * once we are past that, it's the same <len32>name
+	 * <len32>E<len32>N that the peer sends us
+	 */
+
+	if (memcmp(peer, ps, peer_len)) {
+		lwsl_notice("factors mismatch\n");
+		goto bail;
+	}
+
+	lwsl_info("pubkey authorized\n");
+
+	ret = 0;
+bail:
+	free(ps);
+
+	return ret;
+
+bail_p1:
+	if (aps)
+		free(aps);
+
+	return 1;
+}
+
+/* ops: spawn subprocess */
+
+static int
+ssh_cgi_env_add(struct sshd_instance_priv *priv, const char *name,
+		const char *value)
+{
+	struct lws_protocol_vhost_options *pvo = malloc(sizeof(*pvo));
+
+	if (!pvo)
+		return 1;
+
+	pvo->name = malloc(strlen(name) + 1);
+	if (!pvo->name) {
+		free(pvo);
+		return 1;
+	}
+
+	pvo->value = malloc(strlen(name) + 1);
+	if (!pvo->value) {
+		free((char *)pvo->name);
+		free(pvo);
+		return 1;
+	}
+
+	strcpy((char *)pvo->name, name);
+	strcpy((char *)pvo->value, value);
+
+	pvo->next = priv->env;
+	priv->env = pvo;
+
+	lwsl_notice("%s: ENV %s <- %s\n", __func__, name, value);
+
+	return 0;
+}
+
+static int
+ssh_ops_set_env(void *_priv, const char *name, const char *value)
+{
+	struct sshd_instance_priv *priv = _priv;
+
+	return ssh_cgi_env_add(priv, name, value);
+}
+
+
+static int
+ssh_ops_pty_req(void *_priv, struct lws_ssh_pty *pty)
+{
+	struct sshd_instance_priv *priv = _priv;
+	uint8_t *p = (uint8_t *)pty->modes, opc;
+	uint32_t arg;
+
+	lwsl_notice("%s: pty term %s, modes_len %d\n", __func__, pty->term,
+		    pty->modes_len);
+
+	ssh_cgi_env_add(priv, "TERM", pty->term);
+
+	while (p < (uint8_t *)pty->modes + pty->modes_len) {
+		if (*p >= 160)
+			break;
+		if (!*p)
+			break;
+		opc = *p++;
+
+		arg = *p++ << 24;
+		arg |= *p++ << 16;
+		arg |= *p++ << 8;
+		arg |= *p++;
+
+		lwsl_debug("pty opc %d: 0x%x\n", opc, arg);
+
+		switch (opc) {
+		case SSHMO_ICRNL:
+			priv->pty_in_cr_to_nl = !!arg;
+			lwsl_notice(" SSHMO_ICRNL: %d\n", !!arg);
+			break;
+		case SSHMO_ONLCR:
+			priv->pty_in_bloat_nl_to_crnl = !!arg;
+			lwsl_notice(" SSHMO_ONLCR: %d\n", !!arg);
+			break;
+		case SSHMO_ECHO:
+//			priv->pty_in_echo = !!arg;
+			lwsl_notice(" SSHMO_ECHO: %d\n", !!arg);
+			break;
+		}
+	}
+
+	return 0;
+}
+
+static int
+ssh_ops_child_process_io(void *_priv, struct lws *wsi,
+			 struct lws_cgi_args *args)
+{
+	struct sshd_instance_priv *priv = _priv;
+	struct lws_ring *r = priv->ring_stdout;
+	void *rp;
+	uint8_t buf[256], *p, *d;
+	size_t bytes;
+	int n, m;
+
+	priv->wsi_stdout = args->stdwsi[LWS_STDOUT];
+	priv->wsi_stderr = args->stdwsi[LWS_STDERR];
+
+	switch (args->ch) {
+	case LWS_STDIN:
+		lwsl_notice("STDIN\n");
+		break;
+
+	case LWS_STDERR:
+		r = priv->ring_stderr;
+		/* fallthru */
+	case LWS_STDOUT:
+		if (lws_ring_next_linear_insert_range(r, &rp, &bytes) ||
+		    bytes < 1) {
+			lwsl_notice("bytes %d\n", (int)bytes);
+			/* no room in the fifo */
+			break;
+		}
+		if (priv->pty_in_bloat_nl_to_crnl) {
+			if (bytes != 1)
+				n = bytes / 2;
+			else
+				n = 1;
+			if (n > sizeof(buf))
+				n = sizeof(buf);
+
+			if (!n)
+				break;
+
+			m = lws_get_socket_fd(args->stdwsi[args->ch]);
+			if (m < 0)
+				return -1;
+			n = read(m, buf, n);
+			if (n < 0)
+				return -1;
+			if (n == 0) {
+				lwsl_notice("zero length stdin %d\n", n);
+				break;
+			}
+			m = 0;
+			p = rp;
+			d = buf;
+			while (m++ < n) {
+				if (priv->insert_lf) {
+					priv->insert_lf = 0;
+					*p++ = 0x0d;
+				}
+				if (*d == 0x0a)
+					priv->insert_lf = 1;
+
+				*p++ = *d++;
+			}
+			n = (void *)p - rp;
+			if (n < bytes && priv->insert_lf) {
+				priv->insert_lf = 0;
+				*p++ = 0x0d;
+				n++;
+			}
+		} else {
+			n = lws_get_socket_fd(args->stdwsi[args->ch]);
+			if (n < 0)
+				return -1;
+			n = read(n, rp, bytes);
+			if (n < 0)
+				return -1;
+		}
+
+		lws_rx_flow_control(args->stdwsi[args->ch], 0);
+
+		lws_ring_bump_head(r, n);
+		lws_callback_on_writable(wsi);
+		break;
+	}
+
+	return 0;
+}
+
+static int
+ssh_ops_child_process_terminated(void *priv, struct lws *wsi)
+{
+	lwsl_notice("%s\n", __func__);
+	return -1;
+}
+
+static int
+ssh_ops_exec(void *_priv, struct lws *wsi, const char *command)
+{
+	lwsl_notice("%s: EXEC %s\n", __func__, command);
+
+	/* we don't want to exec anything */
+	return 1;
+}
+
+static int
+ssh_ops_shell(void *_priv, struct lws *wsi)
+{
+	struct sshd_instance_priv *priv = _priv;
+	const char *cmd[] = {
+		"/bin/bash",
+		"-i",
+		"-l",
+		NULL
+	};
+	lwsl_notice("%s: SHELL\n", __func__);
+
+	if (lws_cgi(wsi, cmd, -1, 0, priv->env)) {
+		lwsl_notice("shell spawn failed\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+/* ops: banner */
+
+static size_t
+ssh_ops_banner(char *buf, size_t max_len, char *lang, size_t max_lang_len)
+{
+	int n = snprintf(buf, max_len, "\n"
+		      " |\\---/|  lws-ssh Test Server\n"
+		      " | o_o |  SSH Terminal Server\n"
+		      "  \\_^_/   Copyright (C) 2017 Crash Barrier Ltd\n\n");
+
+	snprintf(lang, max_lang_len, "en/US");
+
+	return n;
+}
+
+static void
+ssh_ops_disconnect_reason(uint32_t reason, const char *desc,
+			  const char *desc_lang)
+{
+	lwsl_notice("DISCONNECT reason 0x%X, %s (lang %s)\n", reason, desc,
+			desc_lang);
+}
+
+static const struct lws_ssh_ops ssh_ops = {
+	.channel_create			= ssh_ops_channel_create,
+	.channel_destroy		= ssh_ops_channel_destroy,
+	.tx_waiting			= ssh_ops_tx_waiting,
+	.tx				= ssh_ops_tx,
+	.rx				= ssh_ops_rx,
+	.get_server_key			= ssh_ops_get_server_key,
+	.set_server_key			= ssh_ops_set_server_key,
+	.set_env			= ssh_ops_set_env,
+	.pty_req			= ssh_ops_pty_req,
+	.child_process_io		= ssh_ops_child_process_io,
+	.child_process_terminated	= ssh_ops_child_process_terminated,
+	.exec				= ssh_ops_exec,
+	.shell				= ssh_ops_shell,
+	.is_pubkey_authorized		= ssh_ops_is_pubkey_authorized,
+	.banner				= ssh_ops_banner,
+	.disconnect_reason		= ssh_ops_disconnect_reason,
+	.server_string			= "SSH-2.0-Libwebsockets",
+	.api_version			= 1,
+};
+
+/*
+ * use per-vhost options to bind the ops struct to the instance of the
+ * "lws_raw_sshd" protocol instantiated on our vhost
+ */
+
+static const struct lws_protocol_vhost_options pvo_ssh_ops = {
+	NULL,
+	NULL,
+	"ops",
+	(void *)&ssh_ops
+};
+
+static const struct lws_protocol_vhost_options pvo_ssh = {
+	NULL,
+	&pvo_ssh_ops,
+	"lws-ssh-base",
+	"" /* ignored, just matches the protocol name above */
+};
+
+void sighandler(int sig)
+{
+	force_exit = 1;
+	lws_cancel_service(context);
+}
+
+int main()
+{
+	static struct lws_context_creation_info info;
+	struct lws_vhost *vh_sshd;
+	int ret = 1, n;
+
+	/* info is on the stack, it must be cleared down before use */
+	memset(&info, 0, sizeof(info));
+
+	signal(SIGINT, sighandler);
+	lws_set_log_level(LLL_ERR | LLL_WARN | LLL_NOTICE
+			/*| LLL_INFO */
+			/* | LLL_DEBUG */, NULL);
+
+	lwsl_notice("lws test-sshd -- Copyright (C) 2017 <andy@warmcat.com>\n");
+
+	/* create the lws context */
+
+	info.options = LWS_SERVER_OPTION_EXPLICIT_VHOSTS |
+		       LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
+
+	context = lws_create_context(&info);
+	if (!context) {
+		lwsl_err("Failed to create context\n");
+		return 1;
+	}
+
+	/* create our listening vhost */
+
+	info.port = 2200;
+	info.options = LWS_SERVER_OPTION_ONLY_RAW;
+	info.vhost_name = "sshd";
+	info.protocols = protocols_sshd;
+	info.pvo = &pvo_ssh;
+
+	vh_sshd = lws_create_vhost(context, &info);
+	if (!vh_sshd) {
+		lwsl_err("Failed to create sshd vhost\n");
+		goto bail;
+	}
+
+	/* spin doing service */
+
+	n = 0;
+	while (!n  && !force_exit)
+		n = lws_service(context, 500);
+
+	ret = 0;
+
+	/* cleanup */
+
+bail:
+	lws_context_destroy(context);
+	lwsl_notice("exiting...\n");
+
+	return ret;
+}