text: (function (root, factory) {
  	if (typeof process === "object" && typeof process.stdout === "undefined") {
  		process.stderr = process.stdout = { write: function() { } };
  	}
  	if (typeof define === "function" && define.amd) {
  		define(["exports", "libsodium"], factory);
  	} else if (typeof exports !== "undefined") {
  		factory(exports, require("./libsodium")); // DAVE changed name...
  	} else {
  		var cb = root.sodium && root.sodium.onload;
  		factory((root.sodium = {}), root.libsodium);
  		if (typeof cb === "function") {
  			cb(root.sodium);
  		}
  	}
  }(this, function (exports, libsodium) {
  	"use strict";
  	Object.defineProperty(exports, '__esModule', { value: true });
  
  	var output_format = "uint8array";
  
  	libsodium._sodium_init();
  
  	// List of functions and constants defined in the wrapped libsodium
  	function symbols() {
  		return Object.keys(exports).sort();
  	}
  
  	function memzero(bytes) {
  		if (! bytes instanceof Uint8Array) {
  			throw new TypeError("Only Uint8Array instances can be wiped");
  		}
  		for (var i = 0 | 0, j = bytes.length; i < j; i++) {
  			bytes[i] = 0;
  		}
  	}
  
  	function memcmp(b1, b2) {
  		if (!(b1 instanceof Uint8Array && b2 instanceof Uint8Array)) {
  			throw new TypeError("Only Uint8Array instances can be compared");
  		}
  		if (b1.length !== b2.length) {
  			throw new TypeError("Only instances of identical length can be compared");
  		}
  		for (var d = 0 | 0, i = 0 | 0, j = b1.length; i < j; i++) {
  			d |= b1[i] ^ b2[i];
  		}
  		return d === 0;
  	}
  
  	//---------------------------------------------------------------------------
  	// Codecs
  
  	function from_string(str) {
  		if (typeof TextEncoder === "function") {
  			return new TextEncoder("utf-8").encode(str);
  		}
  		str = unescape(encodeURIComponent(str));
  		var bytes = new Uint8Array(str.length);
  		for (var i = 0; i < str.length; i++) {
  			bytes[i] = str.charCodeAt(i);
  		}
  		return bytes;
  	}
  
  	function from_hex(str) {
  		if (!is_hex(str)) throw new TypeError("The provided string doesn't look like hex data");
  		var result = new Uint8Array(str.length / 2);
  		for (var i = 0; i < str.length; i += 2) {
  			result[i >>> 1] = parseInt(str.substr(i, 2), 16);
  		}
  		return result;
  	}
  
  	function to_hex(bytes) {
  		var str = "", b, c, x;
  		for (var i = 0; i < bytes.length; i++) {
  			c = bytes[i] & 0xf;
  			b = bytes[i] >>> 4;
  			x = (87 + c + (((c - 10) >> 8) & ~38)) << 8 |
  			    (87 + b + (((b - 10) >> 8) & ~38));
  			str += String.fromCharCode(x & 0xff) + String.fromCharCode(x >>> 8);
  		}
  		return str;
  	}
  
  	function is_hex(str) {
  		return (typeof str === "string" && /^[0-9a-f]+$/i.test(str) && str.length % 2 === 0);
  	}
  
  	function from_base64(sBase64, nBlocksSize) {
  		function _b64ToUint6(nChr) {
  			return nChr > 64 && nChr < 91 ?
  				nChr - 65 : nChr > 96 && nChr < 123 ?
  				nChr - 71 : nChr > 47 && nChr < 58 ?
  				nChr + 4 : nChr === 43 ?
  				62 : nChr === 47 ?
  				63 :
  				0;
  		}
  		var
  			sB64Enc = sBase64.replace(/[^A-Za-z0-9\+\/]/g, ""),
  			nInLen = sB64Enc.length,
  			nOutLen = nBlocksSize ? Math.ceil((nInLen * 3 + 1 >> 2) / nBlocksSize) * nBlocksSize : nInLen * 3 + 1 >> 2,
  			taBytes = new Uint8Array(nOutLen);
  		for (var nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; nInIdx < nInLen; nInIdx++) {
  			nMod4 = nInIdx & 3;
  			nUint24 |= _b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << 18 - 6 * nMod4;
  			if (nMod4 === 3 || nInLen - nInIdx === 1) {
  				for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) {
  					taBytes[nOutIdx] = nUint24 >>> (16 >>> nMod3 & 24) & 255;
  				}
  				nUint24 = 0;
  			}
  		}
  		return taBytes;
  	}
  
  	function to_base64(aBytes, noNewLine) {
  		function _uint6ToB64(nUint6) {
  			return nUint6 < 26 ?
  				nUint6 + 65 : nUint6 < 52 ?
  				nUint6 + 71 : nUint6 < 62 ?
  				nUint6 - 4 : nUint6 === 62 ?
  				43 : nUint6 === 63 ?
  				47 :
  				65;
  		}
  		if (typeof aBytes === "string") {
  			throw new Exception("input has to be an array");
  		}
  		var nMod3 = 2,
  			sB64Enc = "";
  		for (var nLen = aBytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; nIdx++) {
  			nMod3 = nIdx % 3;
  			if (nIdx > 0 && (nIdx * 4 / 3) % 76 === 0 && !noNewLine) {
  				sB64Enc += "\r\n";
  			}
  			nUint24 |= aBytes[nIdx] << (16 >>> nMod3 & 24);
  			if (nMod3 === 2 || aBytes.length - nIdx === 1) {
  				sB64Enc += String.fromCharCode(_uint6ToB64(nUint24 >>> 18 & 63), _uint6ToB64(nUint24 >>> 12 & 63), _uint6ToB64(nUint24 >>> 6 & 63), _uint6ToB64(nUint24 & 63));
  				nUint24 = 0;
  			}
  		}
  		return sB64Enc.substr(0, sB64Enc.length - 2 + nMod3) + (nMod3 === 2 ? "" : nMod3 === 1 ? "=" : "==");
  	}
  
  	function output_formats() {
  		return ["uint8array", "text", "hex", "base64"];
  	}
  
  	function _format_output(output, optionalOutputFormat) {
  		var selectedOutputFormat = optionalOutputFormat || output_format;
  		if (!_is_output_format(selectedOutputFormat)) throw new Error(selectedOutputFormat + " output format is not available");
  		if (output instanceof AllocatedBuf) {
  			if (selectedOutputFormat === "uint8array") return output.to_Uint8Array();
  			else if (selectedOutputFormat === "text") return libsodium.Pointer_stringify(output.address, output.length);
  			else if (selectedOutputFormat === "hex") return to_hex(output.to_Uint8Array());
  			else if (selectedOutputFormat === "base64") return to_base64(output.to_Uint8Array());
  			else throw new Error("What is output format \"" + selectedOutputFormat + "\"?");
  		} else if (typeof output === "object") { //Composed output. Example : key pairs
  			var props = Object.keys(output);
  			var formattedOutput = {};
  			for (var i = 0; i < props.length; i++) {
  				formattedOutput[props[i]] = _format_output(output[props[i]], selectedOutputFormat);
  			}
  			return formattedOutput;
  		} else if (typeof output === "string") {
  			return output;
  		} else {
  			throw new TypeError("Cannot format output");
  		}
  	}
  
  	function _is_output_format(format) {
  		var formats = output_formats();
  		for (var i = 0; i < formats.length; i++) {
  			if (formats[i] === format) return true;
  		}
  		return false;
  	}
  
  	function _check_output_format(format) {
  		if (!format) {
  			return;
  		} else if (typeof format !== "string") {
  			throw new TypeError("When defined, the output format must be a string");
  		} else if (!_is_output_format(format)) {
  			throw new Error(format + " is not a supported output format");
  		}
  	}
  
  	//---------------------------------------------------------------------------
  	// Memory management
  
  	// AllocatedBuf: address allocated using _malloc() + length
  	function AllocatedBuf(length) {
  		this.length = length;
  		this.address = _malloc(length);
  	}
  
  	// Copy the content of a AllocatedBuf (_malloc()'d memory) into a Uint8Array
  	AllocatedBuf.prototype.to_Uint8Array = function () {
  		var result = new Uint8Array(this.length);
  		result.set(libsodium.HEAPU8.subarray(this.address, this.address + this.length));
  		return result;
  	};
  
  	// _malloc() a region and initialize it with the content of a Uint8Array
  	function _to_allocated_buf_address(bytes) {
  		var address = _malloc(bytes.length);
  		libsodium.HEAPU8.set(bytes, address);
  		return address;
  	}
  
  	function _malloc(length) {
  		var result = libsodium._malloc(length);
  		if (result === 0) {
  			throw {
  				message: "_malloc() failed",
  				length: length
  			};
  		}
  		return result;
  	}
  
  	function _free(address) {
  		libsodium._free(address);
  	}
  
  	function _free_all(addresses) {
  		for (var i = 0; i < addresses.length; i++) {
  			_free(addresses[i]);
  		}
  	}
  
  	function _free_and_throw_error(address_pool, err) {
  		_free_all(address_pool);
  		throw new Error(err);
  	}
  
  	function _free_and_throw_type_error(address_pool, err) {
  		_free_all(address_pool);
  		throw new TypeError(err);
  	}
  
  	function _require_defined(address_pool, varValue, varName) {
  		if (varValue == undefined) {
  			_free_and_throw_type_error(address_pool, varName + " cannot be null or undefined");
  		}
  	}
  
  	function _any_to_Uint8Array(address_pool, varValue, varName) {
  		_require_defined(address_pool, varValue, varName);
  		if (varValue instanceof Uint8Array) {
  			return varValue;
  		} else if (typeof varValue === "string") {
  			return from_string(varValue);
  		}
  		_free_and_throw_type_error(address_pool, "unsupported input type for " + varName);
  	}
  
  	
  	function crypto_aead_chacha20poly1305_decrypt(secret_nonce, ciphertext, additional_data, public_nonce, key, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: secret_nonce (unsized_buf_optional)
  		
  		var secret_nonce_address = null, secret_nonce_length = 0;
  		if (secret_nonce != undefined) {
  			secret_nonce = _any_to_Uint8Array(address_pool, secret_nonce, "secret_nonce");
  			secret_nonce_address = _to_allocated_buf_address(secret_nonce);
  			secret_nonce_length = secret_nonce.length;
  			address_pool.push(secret_nonce_address);
  		}
  		
  		// ---------- input: ciphertext (unsized_buf)
  		
  		ciphertext = _any_to_Uint8Array(address_pool, ciphertext, "ciphertext");
  		var ciphertext_address = _to_allocated_buf_address(ciphertext),
  		    ciphertext_length = ciphertext.length;
  		address_pool.push(ciphertext_address);
  		
  		// ---------- input: additional_data (unsized_buf_optional)
  		
  		var additional_data_address = null, additional_data_length = 0;
  		if (additional_data != undefined) {
  			additional_data = _any_to_Uint8Array(address_pool, additional_data, "additional_data");
  			additional_data_address = _to_allocated_buf_address(additional_data);
  			additional_data_length = additional_data.length;
  			address_pool.push(additional_data_address);
  		}
  		
  		// ---------- input: public_nonce (buf)
  		
  		public_nonce = _any_to_Uint8Array(address_pool, public_nonce, "public_nonce");
  		var public_nonce_address, public_nonce_length = (libsodium._crypto_aead_chacha20poly1305_npubbytes()) | 0;
  		if (public_nonce.length !== public_nonce_length) {
  			_free_and_throw_type_error(address_pool, "invalid public_nonce length");
  		}
  		public_nonce_address = _to_allocated_buf_address(public_nonce);
  		address_pool.push(public_nonce_address);
  		
  		// ---------- input: key (buf)
  		
  		key = _any_to_Uint8Array(address_pool, key, "key");
  		var key_address, key_length = (libsodium._crypto_aead_chacha20poly1305_keybytes()) | 0;
  		if (key.length !== key_length) {
  			_free_and_throw_type_error(address_pool, "invalid key length");
  		}
  		key_address = _to_allocated_buf_address(key);
  		address_pool.push(key_address);
  		
  		// ---------- output message (buf)
  		
  		var message_length = (ciphertext_length - libsodium._crypto_aead_chacha20poly1305_abytes()) | 0,
  		    message = new AllocatedBuf(message_length),
  		    message_address = message.address;
  		
  		address_pool.push(message_address);
  		
  		if ((libsodium._crypto_aead_chacha20poly1305_decrypt(message_address, null, secret_nonce_address, ciphertext_address, ciphertext_length, 0, additional_data_address, additional_data_length, 0, public_nonce_address, key_address)) === 0) {
  			var ret = _format_output(message, outputFormat);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_aead_chacha20poly1305_encrypt(message, additional_data, secret_nonce, public_nonce, key, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: message (unsized_buf)
  		
  		message = _any_to_Uint8Array(address_pool, message, "message");
  		var message_address = _to_allocated_buf_address(message),
  		    message_length = message.length;
  		address_pool.push(message_address);
  		
  		// ---------- input: additional_data (unsized_buf_optional)
  		
  		var additional_data_address = null, additional_data_length = 0;
  		if (additional_data != undefined) {
  			additional_data = _any_to_Uint8Array(address_pool, additional_data, "additional_data");
  			additional_data_address = _to_allocated_buf_address(additional_data);
  			additional_data_length = additional_data.length;
  			address_pool.push(additional_data_address);
  		}
  		
  		// ---------- input: secret_nonce (unsized_buf_optional)
  		
  		var secret_nonce_address = null, secret_nonce_length = 0;
  		if (secret_nonce != undefined) {
  			secret_nonce = _any_to_Uint8Array(address_pool, secret_nonce, "secret_nonce");
  			secret_nonce_address = _to_allocated_buf_address(secret_nonce);
  			secret_nonce_length = secret_nonce.length;
  			address_pool.push(secret_nonce_address);
  		}
  		
  		// ---------- input: public_nonce (buf)
  		
  		public_nonce = _any_to_Uint8Array(address_pool, public_nonce, "public_nonce");
  		var public_nonce_address, public_nonce_length = (libsodium._crypto_aead_chacha20poly1305_npubbytes()) | 0;
  		if (public_nonce.length !== public_nonce_length) {
  			_free_and_throw_type_error(address_pool, "invalid public_nonce length");
  		}
  		public_nonce_address = _to_allocated_buf_address(public_nonce);
  		address_pool.push(public_nonce_address);
  		
  		// ---------- input: key (buf)
  		
  		key = _any_to_Uint8Array(address_pool, key, "key");
  		var key_address, key_length = (libsodium._crypto_aead_chacha20poly1305_keybytes()) | 0;
  		if (key.length !== key_length) {
  			_free_and_throw_type_error(address_pool, "invalid key length");
  		}
  		key_address = _to_allocated_buf_address(key);
  		address_pool.push(key_address);
  		
  		// ---------- output ciphertext (buf)
  		
  		var ciphertext_length = (message_length + libsodium._crypto_aead_chacha20poly1305_abytes()) | 0,
  		    ciphertext = new AllocatedBuf(ciphertext_length),
  		    ciphertext_address = ciphertext.address;
  		
  		address_pool.push(ciphertext_address);
  		
  		if ((libsodium._crypto_aead_chacha20poly1305_encrypt(ciphertext_address, null, message_address, message_length, 0, additional_data_address, additional_data_length, 0, secret_nonce_address, public_nonce_address, key_address)) === 0) {
  			var ret = _format_output(ciphertext, outputFormat);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_auth(message, key, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: message (unsized_buf)
  		
  		message = _any_to_Uint8Array(address_pool, message, "message");
  		var message_address = _to_allocated_buf_address(message),
  		    message_length = message.length;
  		address_pool.push(message_address);
  		
  		// ---------- input: key (buf)
  		
  		key = _any_to_Uint8Array(address_pool, key, "key");
  		var key_address, key_length = (libsodium._crypto_auth_keybytes()) | 0;
  		if (key.length !== key_length) {
  			_free_and_throw_type_error(address_pool, "invalid key length");
  		}
  		key_address = _to_allocated_buf_address(key);
  		address_pool.push(key_address);
  		
  		// ---------- output tag (buf)
  		
  		var tag_length = (libsodium._crypto_auth_bytes()) | 0,
  		    tag = new AllocatedBuf(tag_length),
  		    tag_address = tag.address;
  		
  		address_pool.push(tag_address);
  		
  		if ((libsodium._crypto_auth(tag_address, message_address, message_length, 0, key_address) | 0) === 0) {
  			var ret = _format_output(tag, outputFormat);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_auth_hmacsha256(message, key, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: message (unsized_buf)
  		
  		message = _any_to_Uint8Array(address_pool, message, "message");
  		var message_address = _to_allocated_buf_address(message),
  		    message_length = message.length;
  		address_pool.push(message_address);
  		
  		// ---------- input: key (buf)
  		
  		key = _any_to_Uint8Array(address_pool, key, "key");
  		var key_address, key_length = (libsodium._crypto_auth_hmacsha256_keybytes()) | 0;
  		if (key.length !== key_length) {
  			_free_and_throw_type_error(address_pool, "invalid key length");
  		}
  		key_address = _to_allocated_buf_address(key);
  		address_pool.push(key_address);
  		
  		// ---------- output hash (buf)
  		
  		var hash_length = (libsodium._crypto_auth_hmacsha256_bytes()) | 0,
  		    hash = new AllocatedBuf(hash_length),
  		    hash_address = hash.address;
  		
  		address_pool.push(hash_address);
  		
  		if ((libsodium._crypto_auth_hmacsha256(hash_address, message_address, message_length, 0, key_address) | 0) === 0) {
  			var ret = _format_output(hash, outputFormat);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_auth_verify(tag, message, key) {
  		var address_pool = [];
  
  		// ---------- input: tag (buf)
  		
  		tag = _any_to_Uint8Array(address_pool, tag, "tag");
  		var tag_address, tag_length = (libsodium._crypto_auth_hmacsha256_bytes()) | 0;
  		if (tag.length !== tag_length) {
  			_free_and_throw_type_error(address_pool, "invalid tag length");
  		}
  		tag_address = _to_allocated_buf_address(tag);
  		address_pool.push(tag_address);
  		
  		// ---------- input: message (unsized_buf)
  		
  		message = _any_to_Uint8Array(address_pool, message, "message");
  		var message_address = _to_allocated_buf_address(message),
  		    message_length = message.length;
  		address_pool.push(message_address);
  		
  		// ---------- input: key (buf)
  		
  		key = _any_to_Uint8Array(address_pool, key, "key");
  		var key_address, key_length = (libsodium._crypto_auth_hmacsha256_keybytes()) | 0;
  		if (key.length !== key_length) {
  			_free_and_throw_type_error(address_pool, "invalid key length");
  		}
  		key_address = _to_allocated_buf_address(key);
  		address_pool.push(key_address);
  		
  		var result = libsodium._crypto_auth_hmacsha256_verify(tag_address, message_address, message_length, 0, key_address) | 0;
  		var ret = (result === 0);
  		_free_all(address_pool);
  		return ret;
  		
  	}
  
  	function crypto_auth_hmacsha512(message, key, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: message (unsized_buf)
  		
  		message = _any_to_Uint8Array(address_pool, message, "message");
  		var message_address = _to_allocated_buf_address(message),
  		    message_length = message.length;
  		address_pool.push(message_address);
  		
  		// ---------- input: key (buf)
  		
  		key = _any_to_Uint8Array(address_pool, key, "key");
  		var key_address, key_length = (libsodium._crypto_auth_hmacsha512_keybytes()) | 0;
  		if (key.length !== key_length) {
  			_free_and_throw_type_error(address_pool, "invalid key length");
  		}
  		key_address = _to_allocated_buf_address(key);
  		address_pool.push(key_address);
  		
  		// ---------- output hash (buf)
  		
  		var hash_length = (libsodium._crypto_auth_hmacsha512_bytes()) | 0,
  		    hash = new AllocatedBuf(hash_length),
  		    hash_address = hash.address;
  		
  		address_pool.push(hash_address);
  		
  		if ((libsodium._crypto_auth_hmacsha512(hash_address, message_address, message_length, 0, key_address) | 0) === 0) {
  			var ret = _format_output(hash, outputFormat);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_auth_verify(tag, message, key) {
  		var address_pool = [];
  
  		// ---------- input: tag (buf)
  		
  		tag = _any_to_Uint8Array(address_pool, tag, "tag");
  		var tag_address, tag_length = (libsodium._crypto_auth_hmacsha512_bytes()) | 0;
  		if (tag.length !== tag_length) {
  			_free_and_throw_type_error(address_pool, "invalid tag length");
  		}
  		tag_address = _to_allocated_buf_address(tag);
  		address_pool.push(tag_address);
  		
  		// ---------- input: message (unsized_buf)
  		
  		message = _any_to_Uint8Array(address_pool, message, "message");
  		var message_address = _to_allocated_buf_address(message),
  		    message_length = message.length;
  		address_pool.push(message_address);
  		
  		// ---------- input: key (buf)
  		
  		key = _any_to_Uint8Array(address_pool, key, "key");
  		var key_address, key_length = (libsodium._crypto_auth_hmacsha512_keybytes()) | 0;
  		if (key.length !== key_length) {
  			_free_and_throw_type_error(address_pool, "invalid key length");
  		}
  		key_address = _to_allocated_buf_address(key);
  		address_pool.push(key_address);
  		
  		var result = libsodium._crypto_auth_hmacsha512_verify(tag_address, message_address, message_length, 0, key_address) | 0;
  		var ret = (result === 0);
  		_free_all(address_pool);
  		return ret;
  		
  	}
  
  	function crypto_auth_verify(tag, message, key) {
  		var address_pool = [];
  
  		// ---------- input: tag (buf)
  		
  		tag = _any_to_Uint8Array(address_pool, tag, "tag");
  		var tag_address, tag_length = (libsodium._crypto_auth_bytes()) | 0;
  		if (tag.length !== tag_length) {
  			_free_and_throw_type_error(address_pool, "invalid tag length");
  		}
  		tag_address = _to_allocated_buf_address(tag);
  		address_pool.push(tag_address);
  		
  		// ---------- input: message (unsized_buf)
  		
  		message = _any_to_Uint8Array(address_pool, message, "message");
  		var message_address = _to_allocated_buf_address(message),
  		    message_length = message.length;
  		address_pool.push(message_address);
  		
  		// ---------- input: key (buf)
  		
  		key = _any_to_Uint8Array(address_pool, key, "key");
  		var key_address, key_length = (libsodium._crypto_auth_keybytes()) | 0;
  		if (key.length !== key_length) {
  			_free_and_throw_type_error(address_pool, "invalid key length");
  		}
  		key_address = _to_allocated_buf_address(key);
  		address_pool.push(key_address);
  		
  		var result = libsodium._crypto_auth_verify(tag_address, message_address, message_length, 0, key_address) | 0;
  		var ret = (result === 0);
  		_free_all(address_pool);
  		return ret;
  		
  	}
  
  	function crypto_box_detached(message, nonce, publicKey, secretKey, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: message (unsized_buf)
  		
  		message = _any_to_Uint8Array(address_pool, message, "message");
  		var message_address = _to_allocated_buf_address(message),
  		    message_length = message.length;
  		address_pool.push(message_address);
  		
  		// ---------- input: nonce (buf)
  		
  		nonce = _any_to_Uint8Array(address_pool, nonce, "nonce");
  		var nonce_address, nonce_length = (libsodium._crypto_box_noncebytes()) | 0;
  		if (nonce.length !== nonce_length) {
  			_free_and_throw_type_error(address_pool, "invalid nonce length");
  		}
  		nonce_address = _to_allocated_buf_address(nonce);
  		address_pool.push(nonce_address);
  		
  		// ---------- input: publicKey (buf)
  		
  		publicKey = _any_to_Uint8Array(address_pool, publicKey, "publicKey");
  		var publicKey_address, publicKey_length = (libsodium._crypto_box_publickeybytes()) | 0;
  		if (publicKey.length !== publicKey_length) {
  			_free_and_throw_type_error(address_pool, "invalid publicKey length");
  		}
  		publicKey_address = _to_allocated_buf_address(publicKey);
  		address_pool.push(publicKey_address);
  		
  		// ---------- input: secretKey (buf)
  		
  		secretKey = _any_to_Uint8Array(address_pool, secretKey, "secretKey");
  		var secretKey_address, secretKey_length = (libsodium._crypto_box_secretkeybytes()) | 0;
  		if (secretKey.length !== secretKey_length) {
  			_free_and_throw_type_error(address_pool, "invalid secretKey length");
  		}
  		secretKey_address = _to_allocated_buf_address(secretKey);
  		address_pool.push(secretKey_address);
  		
  		// ---------- output ciphertext (buf)
  		
  		var ciphertext_length = (message_length) | 0,
  		    ciphertext = new AllocatedBuf(ciphertext_length),
  		    ciphertext_address = ciphertext.address;
  		
  		address_pool.push(ciphertext_address);
  		
  		// ---------- output mac (buf)
  		
  		var mac_length = (libsodium._crypto_box_macbytes()) | 0,
  		    mac = new AllocatedBuf(mac_length),
  		    mac_address = mac.address;
  		
  		address_pool.push(mac_address);
  		
  		if ((libsodium._crypto_box_detached(ciphertext_address, mac_address, message_address, message_length, 0, nonce_address, publicKey_address, secretKey_address) | 0) === 0) {
  			var ret = _format_output({ciphertext: ciphertext, mac: mac}, outputFormat);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_box_easy(message, nonce, publicKey, secretKey, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: message (unsized_buf)
  		
  		message = _any_to_Uint8Array(address_pool, message, "message");
  		var message_address = _to_allocated_buf_address(message),
  		    message_length = message.length;
  		address_pool.push(message_address);
  		
  		// ---------- input: nonce (buf)
  		
  		nonce = _any_to_Uint8Array(address_pool, nonce, "nonce");
  		var nonce_address, nonce_length = (libsodium._crypto_box_noncebytes()) | 0;
  		if (nonce.length !== nonce_length) {
  			_free_and_throw_type_error(address_pool, "invalid nonce length");
  		}
  		nonce_address = _to_allocated_buf_address(nonce);
  		address_pool.push(nonce_address);
  		
  		// ---------- input: publicKey (buf)
  		
  		publicKey = _any_to_Uint8Array(address_pool, publicKey, "publicKey");
  		var publicKey_address, publicKey_length = (libsodium._crypto_box_publickeybytes()) | 0;
  		if (publicKey.length !== publicKey_length) {
  			_free_and_throw_type_error(address_pool, "invalid publicKey length");
  		}
  		publicKey_address = _to_allocated_buf_address(publicKey);
  		address_pool.push(publicKey_address);
  		
  		// ---------- input: secretKey (buf)
  		
  		secretKey = _any_to_Uint8Array(address_pool, secretKey, "secretKey");
  		var secretKey_address, secretKey_length = (libsodium._crypto_box_secretkeybytes()) | 0;
  		if (secretKey.length !== secretKey_length) {
  			_free_and_throw_type_error(address_pool, "invalid secretKey length");
  		}
  		secretKey_address = _to_allocated_buf_address(secretKey);
  		address_pool.push(secretKey_address);
  		
  		// ---------- output ciphertext (buf)
  		
  		var ciphertext_length = (message_length + libsodium._crypto_box_macbytes()) | 0,
  		    ciphertext = new AllocatedBuf(ciphertext_length),
  		    ciphertext_address = ciphertext.address;
  		
  		address_pool.push(ciphertext_address);
  		
  		if ((libsodium._crypto_box_easy(ciphertext_address, message_address, message_length, 0, nonce_address, publicKey_address, secretKey_address) | 0) === 0) {
  			var ret = _format_output(ciphertext, outputFormat);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_box_keypair(outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- output publicKey (buf)
  		
  		var publicKey_length = (libsodium._crypto_box_publickeybytes()) | 0,
  		    publicKey = new AllocatedBuf(publicKey_length),
  		    publicKey_address = publicKey.address;
  		
  		address_pool.push(publicKey_address);
  		
  		// ---------- output secretKey (buf)
  		
  		var secretKey_length = (libsodium._crypto_box_secretkeybytes()) | 0,
  		    secretKey = new AllocatedBuf(secretKey_length),
  		    secretKey_address = secretKey.address;
  		
  		address_pool.push(secretKey_address);
  		
  		if ((libsodium._crypto_box_keypair(publicKey_address, secretKey_address) | 0) === 0) {
  			var ret = _format_output({publicKey: publicKey, privateKey: secretKey, keyType: "curve25519"}, outputFormat);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_box_open_detached(ciphertext, mac, nonce, publicKey, secretKey, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: ciphertext (unsized_buf)
  		
  		ciphertext = _any_to_Uint8Array(address_pool, ciphertext, "ciphertext");
  		var ciphertext_address = _to_allocated_buf_address(ciphertext),
  		    ciphertext_length = ciphertext.length;
  		address_pool.push(ciphertext_address);
  		
  		// ---------- input: mac (buf)
  		
  		mac = _any_to_Uint8Array(address_pool, mac, "mac");
  		var mac_address, mac_length = (libsodium._crypto_box_macbytes()) | 0;
  		if (mac.length !== mac_length) {
  			_free_and_throw_type_error(address_pool, "invalid mac length");
  		}
  		mac_address = _to_allocated_buf_address(mac);
  		address_pool.push(mac_address);
  		
  		// ---------- input: nonce (buf)
  		
  		nonce = _any_to_Uint8Array(address_pool, nonce, "nonce");
  		var nonce_address, nonce_length = (libsodium._crypto_box_noncebytes()) | 0;
  		if (nonce.length !== nonce_length) {
  			_free_and_throw_type_error(address_pool, "invalid nonce length");
  		}
  		nonce_address = _to_allocated_buf_address(nonce);
  		address_pool.push(nonce_address);
  		
  		// ---------- input: publicKey (buf)
  		
  		publicKey = _any_to_Uint8Array(address_pool, publicKey, "publicKey");
  		var publicKey_address, publicKey_length = (libsodium._crypto_box_publickeybytes()) | 0;
  		if (publicKey.length !== publicKey_length) {
  			_free_and_throw_type_error(address_pool, "invalid publicKey length");
  		}
  		publicKey_address = _to_allocated_buf_address(publicKey);
  		address_pool.push(publicKey_address);
  		
  		// ---------- input: secretKey (buf)
  		
  		secretKey = _any_to_Uint8Array(address_pool, secretKey, "secretKey");
  		var secretKey_address, secretKey_length = (libsodium._crypto_box_secretkeybytes()) | 0;
  		if (secretKey.length !== secretKey_length) {
  			_free_and_throw_type_error(address_pool, "invalid secretKey length");
  		}
  		secretKey_address = _to_allocated_buf_address(secretKey);
  		address_pool.push(secretKey_address);
  		
  		// ---------- output plaintext (buf)
  		
  		var plaintext_length = (ciphertext_length) | 0,
  		    plaintext = new AllocatedBuf(plaintext_length),
  		    plaintext_address = plaintext.address;
  		
  		address_pool.push(plaintext_address);
  		
  		if ((libsodium._crypto_box_open_detached(plaintext_address, ciphertext_address, mac_address, ciphertext_length, 0, nonce_address, publicKey_address, secretKey_address) | 0) === 0) {
  			var ret = _format_output(plaintext, outputFormat);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_box_open_easy(ciphertext, nonce, publicKey, secretKey, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: ciphertext (unsized_buf)
  		
  		ciphertext = _any_to_Uint8Array(address_pool, ciphertext, "ciphertext");
  		var ciphertext_address = _to_allocated_buf_address(ciphertext),
  		    ciphertext_length = ciphertext.length;
  		address_pool.push(ciphertext_address);
  		
  		// ---------- input: nonce (buf)
  		
  		nonce = _any_to_Uint8Array(address_pool, nonce, "nonce");
  		var nonce_address, nonce_length = (libsodium._crypto_box_noncebytes()) | 0;
  		if (nonce.length !== nonce_length) {
  			_free_and_throw_type_error(address_pool, "invalid nonce length");
  		}
  		nonce_address = _to_allocated_buf_address(nonce);
  		address_pool.push(nonce_address);
  		
  		// ---------- input: publicKey (buf)
  		
  		publicKey = _any_to_Uint8Array(address_pool, publicKey, "publicKey");
  		var publicKey_address, publicKey_length = (libsodium._crypto_box_publickeybytes()) | 0;
  		if (publicKey.length !== publicKey_length) {
  			_free_and_throw_type_error(address_pool, "invalid publicKey length");
  		}
  		publicKey_address = _to_allocated_buf_address(publicKey);
  		address_pool.push(publicKey_address);
  		
  		// ---------- input: secretKey (buf)
  		
  		secretKey = _any_to_Uint8Array(address_pool, secretKey, "secretKey");
  		var secretKey_address, secretKey_length = (libsodium._crypto_box_secretkeybytes()) | 0;
  		if (secretKey.length !== secretKey_length) {
  			_free_and_throw_type_error(address_pool, "invalid secretKey length");
  		}
  		secretKey_address = _to_allocated_buf_address(secretKey);
  		address_pool.push(secretKey_address);
  		
  		// ---------- output plaintext (buf)
  		
  		var plaintext_length = (ciphertext_length - libsodium._crypto_box_macbytes()) | 0,
  		    plaintext = new AllocatedBuf(plaintext_length),
  		    plaintext_address = plaintext.address;
  		
  		address_pool.push(plaintext_address);
  		
  		if ((libsodium._crypto_box_open_easy(plaintext_address, ciphertext_address, ciphertext_length, 0, nonce_address, publicKey_address, secretKey_address) | 0) === 0) {
  			var ret = _format_output(plaintext, outputFormat);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_box_seal(message, publicKey, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: message (unsized_buf)
  		
  		message = _any_to_Uint8Array(address_pool, message, "message");
  		var message_address = _to_allocated_buf_address(message),
  		    message_length = message.length;
  		address_pool.push(message_address);
  		
  		// ---------- input: publicKey (buf)
  		
  		publicKey = _any_to_Uint8Array(address_pool, publicKey, "publicKey");
  		var publicKey_address, publicKey_length = (libsodium._crypto_box_publickeybytes()) | 0;
  		if (publicKey.length !== publicKey_length) {
  			_free_and_throw_type_error(address_pool, "invalid publicKey length");
  		}
  		publicKey_address = _to_allocated_buf_address(publicKey);
  		address_pool.push(publicKey_address);
  		
  		// ---------- output ciphertext (buf)
  		
  		var ciphertext_length = (message_length + libsodium._crypto_box_sealbytes()) | 0,
  		    ciphertext = new AllocatedBuf(ciphertext_length),
  		    ciphertext_address = ciphertext.address;
  		
  		address_pool.push(ciphertext_address);
  		
  		if ((libsodium._crypto_box_seal(ciphertext_address, message_address, message_length, 0, publicKey_address) | 0) === 0) {
  			var ret = _format_output(ciphertext, outputFormat);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_box_seal_open(ciphertext, publicKey, secretKey, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: ciphertext (unsized_buf)
  		
  		ciphertext = _any_to_Uint8Array(address_pool, ciphertext, "ciphertext");
  		var ciphertext_address = _to_allocated_buf_address(ciphertext),
  		    ciphertext_length = ciphertext.length;
  		address_pool.push(ciphertext_address);
  		
  		// ---------- input: publicKey (buf)
  		
  		publicKey = _any_to_Uint8Array(address_pool, publicKey, "publicKey");
  		var publicKey_address, publicKey_length = (libsodium._crypto_box_publickeybytes()) | 0;
  		if (publicKey.length !== publicKey_length) {
  			_free_and_throw_type_error(address_pool, "invalid publicKey length");
  		}
  		publicKey_address = _to_allocated_buf_address(publicKey);
  		address_pool.push(publicKey_address);
  		
  		// ---------- input: secretKey (buf)
  		
  		secretKey = _any_to_Uint8Array(address_pool, secretKey, "secretKey");
  		var secretKey_address, secretKey_length = (libsodium._crypto_box_secretkeybytes()) | 0;
  		if (secretKey.length !== secretKey_length) {
  			_free_and_throw_type_error(address_pool, "invalid secretKey length");
  		}
  		secretKey_address = _to_allocated_buf_address(secretKey);
  		address_pool.push(secretKey_address);
  		
  		// ---------- output plaintext (buf)
  		
  		var plaintext_length = (ciphertext_length - libsodium._crypto_box_sealbytes()) | 0,
  		    plaintext = new AllocatedBuf(plaintext_length),
  		    plaintext_address = plaintext.address;
  		
  		address_pool.push(plaintext_address);
  		
  		if ((libsodium._crypto_box_seal_open(plaintext_address, ciphertext_address, ciphertext_length, 0, publicKey_address, secretKey_address) | 0) === 0) {
  			var ret = _format_output(plaintext, outputFormat);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_box_seed_keypair(seed, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: seed (buf)
  		
  		seed = _any_to_Uint8Array(address_pool, seed, "seed");
  		var seed_address, seed_length = (libsodium._crypto_box_seedbytes()) | 0;
  		if (seed.length !== seed_length) {
  			_free_and_throw_type_error(address_pool, "invalid seed length");
  		}
  		seed_address = _to_allocated_buf_address(seed);
  		address_pool.push(seed_address);
  		
  		// ---------- output publicKey (buf)
  		
  		var publicKey_length = (libsodium._crypto_box_publickeybytes()) | 0,
  		    publicKey = new AllocatedBuf(publicKey_length),
  		    publicKey_address = publicKey.address;
  		
  		address_pool.push(publicKey_address);
  		
  		// ---------- output privateKey (buf)
  		
  		var privateKey_length = (libsodium._crypto_box_secretkeybytes()) | 0,
  		    privateKey = new AllocatedBuf(privateKey_length),
  		    privateKey_address = privateKey.address;
  		
  		address_pool.push(privateKey_address);
  		
  		if ((libsodium._crypto_box_seed_keypair(publicKey_address, privateKey_address, seed_address) | 0) === 0) {
  			var ret = _format_output({publicKey: publicKey, privateKey: privateKey}, outputFormat);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_generichash(hash_length, message, key, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: hash_length (uint)
  		
  		_require_defined(address_pool, hash_length, "hash_length");
  		
  		if (!(typeof hash_length === "number" && (hash_length | 0) === hash_length) && (hash_length | 0) > 0) {
  			_free_and_throw_type_error(address_pool, "hash_length must be an unsigned integer");
  		}
  		
  		// ---------- input: message (unsized_buf)
  		
  		message = _any_to_Uint8Array(address_pool, message, "message");
  		var message_address = _to_allocated_buf_address(message),
  		    message_length = message.length;
  		address_pool.push(message_address);
  		
  		// ---------- input: key (unsized_buf_optional)
  		
  		var key_address = null, key_length = 0;
  		if (key != undefined) {
  			key = _any_to_Uint8Array(address_pool, key, "key");
  			key_address = _to_allocated_buf_address(key);
  			key_length = key.length;
  			address_pool.push(key_address);
  		}
  		
  		// ---------- output hash (buf)
  		
  		var hash_length = (hash_length) | 0,
  		    hash = new AllocatedBuf(hash_length),
  		    hash_address = hash.address;
  		
  		address_pool.push(hash_address);
  		
  		if ((libsodium._crypto_generichash(hash_address, hash_length, message_address, message_length, 0, key_address, key_length) | 0) === 0) {
  			var ret = _format_output(hash, outputFormat);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_generichash_final(state_address, hash_length, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: state_address (generichash_state_address)
  		
  		_require_defined(address_pool, state_address, "state_address");
  		
  		// ---------- input: hash_length (uint)
  		
  		_require_defined(address_pool, hash_length, "hash_length");
  		
  		if (!(typeof hash_length === "number" && (hash_length | 0) === hash_length) && (hash_length | 0) > 0) {
  			_free_and_throw_type_error(address_pool, "hash_length must be an unsigned integer");
  		}
  		
  		// ---------- output hash (buf)
  		
  		var hash_length = (hash_length) | 0,
  		    hash = new AllocatedBuf(hash_length),
  		    hash_address = hash.address;
  		
  		address_pool.push(hash_address);
  		
  		if ((libsodium._crypto_generichash_final(state_address, hash_address, hash_length) | 0) === 0) {
  			var ret = (libsodium._free(state_address), _format_output(hash, outputFormat));
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_generichash_init(key, hash_length, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: key (unsized_buf_optional)
  		
  		var key_address = null, key_length = 0;
  		if (key != undefined) {
  			key = _any_to_Uint8Array(address_pool, key, "key");
  			key_address = _to_allocated_buf_address(key);
  			key_length = key.length;
  			address_pool.push(key_address);
  		}
  		
  		// ---------- input: hash_length (uint)
  		
  		_require_defined(address_pool, hash_length, "hash_length");
  		
  		if (!(typeof hash_length === "number" && (hash_length | 0) === hash_length) && (hash_length | 0) > 0) {
  			_free_and_throw_type_error(address_pool, "hash_length must be an unsigned integer");
  		}
  		
  		// ---------- output state (generichash_state)
  		
  		var state_address = new AllocatedBuf(357).address;
  		
  		if ((libsodium._crypto_generichash_init(state_address, key_address, key_length, hash_length) | 0) === 0) {
  			var ret = state_address;
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_generichash_update(state_address, message_chunk, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: state_address (generichash_state_address)
  		
  		_require_defined(address_pool, state_address, "state_address");
  		
  		// ---------- input: message_chunk (unsized_buf)
  		
  		message_chunk = _any_to_Uint8Array(address_pool, message_chunk, "message_chunk");
  		var message_chunk_address = _to_allocated_buf_address(message_chunk),
  		    message_chunk_length = message_chunk.length;
  		address_pool.push(message_chunk_address);
  		
  		if ((libsodium._crypto_generichash_update(state_address, message_chunk_address, message_chunk_length, 0) | 0) === 0) {
  			_free_all(address_pool);
  			return;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_hash(message, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: message (unsized_buf)
  		
  		message = _any_to_Uint8Array(address_pool, message, "message");
  		var message_address = _to_allocated_buf_address(message),
  		    message_length = message.length;
  		address_pool.push(message_address);
  		
  		// ---------- output hash (buf)
  		
  		var hash_length = (libsodium._crypto_hash_bytes()) | 0,
  		    hash = new AllocatedBuf(hash_length),
  		    hash_address = hash.address;
  		
  		address_pool.push(hash_address);
  		
  		if ((libsodium._crypto_hash(hash_address, message_address, message_length, 0) | 0) === 0) {
  			var ret = _format_output(hash, outputFormat);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_hash_sha256(message, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: message (unsized_buf)
  		
  		message = _any_to_Uint8Array(address_pool, message, "message");
  		var message_address = _to_allocated_buf_address(message),
  		    message_length = message.length;
  		address_pool.push(message_address);
  		
  		// ---------- output hash (buf)
  		
  		var hash_length = (libsodium._crypto_hash_sha256_bytes()) | 0,
  		    hash = new AllocatedBuf(hash_length),
  		    hash_address = hash.address;
  		
  		address_pool.push(hash_address);
  		
  		if ((libsodium._crypto_hash_sha256(hash_address, message_address, message_length, 0) | 0) === 0) {
  			var ret = _format_output(hash, outputFormat);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_hash_sha512(message, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: message (unsized_buf)
  		
  		message = _any_to_Uint8Array(address_pool, message, "message");
  		var message_address = _to_allocated_buf_address(message),
  		    message_length = message.length;
  		address_pool.push(message_address);
  		
  		// ---------- output hash (buf)
  		
  		var hash_length = (libsodium._crypto_hash_sha512_bytes()) | 0,
  		    hash = new AllocatedBuf(hash_length),
  		    hash_address = hash.address;
  		
  		address_pool.push(hash_address);
  		
  		if ((libsodium._crypto_hash_sha512(hash_address, message_address, message_length, 0) | 0) === 0) {
  			var ret = _format_output(hash, outputFormat);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_onetimeauth(message, key, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: message (unsized_buf)
  		
  		message = _any_to_Uint8Array(address_pool, message, "message");
  		var message_address = _to_allocated_buf_address(message),
  		    message_length = message.length;
  		address_pool.push(message_address);
  		
  		// ---------- input: key (buf)
  		
  		key = _any_to_Uint8Array(address_pool, key, "key");
  		var key_address, key_length = (libsodium._crypto_onetimeauth_keybytes()) | 0;
  		if (key.length !== key_length) {
  			_free_and_throw_type_error(address_pool, "invalid key length");
  		}
  		key_address = _to_allocated_buf_address(key);
  		address_pool.push(key_address);
  		
  		// ---------- output hash (buf)
  		
  		var hash_length = (libsodium._crypto_onetimeauth_bytes()) | 0,
  		    hash = new AllocatedBuf(hash_length),
  		    hash_address = hash.address;
  		
  		address_pool.push(hash_address);
  		
  		if ((libsodium._crypto_onetimeauth(hash_address, message_address, message_length, 0, key_address) | 0) === 0) {
  			var ret = _format_output(hash, outputFormat);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_onetimeauth_verify(hash, message, key) {
  		var address_pool = [];
  
  		// ---------- input: hash (buf)
  		
  		hash = _any_to_Uint8Array(address_pool, hash, "hash");
  		var hash_address, hash_length = (libsodium._crypto_onetimeauth_bytes()) | 0;
  		if (hash.length !== hash_length) {
  			_free_and_throw_type_error(address_pool, "invalid hash length");
  		}
  		hash_address = _to_allocated_buf_address(hash);
  		address_pool.push(hash_address);
  		
  		// ---------- input: message (unsized_buf)
  		
  		message = _any_to_Uint8Array(address_pool, message, "message");
  		var message_address = _to_allocated_buf_address(message),
  		    message_length = message.length;
  		address_pool.push(message_address);
  		
  		// ---------- input: key (buf)
  		
  		key = _any_to_Uint8Array(address_pool, key, "key");
  		var key_address, key_length = (libsodium._crypto_onetimeauth_keybytes()) | 0;
  		if (key.length !== key_length) {
  			_free_and_throw_type_error(address_pool, "invalid key length");
  		}
  		key_address = _to_allocated_buf_address(key);
  		address_pool.push(key_address);
  		
  		var result = libsodium._crypto_onetimeauth_verify(hash_address, message_address, message_length, 0, key_address) | 0;
  		var ret = (result === 0);
  		_free_all(address_pool);
  		return ret;
  		
  	}
  
  	function crypto_pwhash_scryptsalsa208sha256(password, salt, opsLimit, memLimit, keyLength, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: password (unsized_buf)
  		
  		password = _any_to_Uint8Array(address_pool, password, "password");
  		var password_address = _to_allocated_buf_address(password),
  		    password_length = password.length;
  		address_pool.push(password_address);
  		
  		// ---------- input: salt (buf)
  		
  		salt = _any_to_Uint8Array(address_pool, salt, "salt");
  		var salt_address, salt_length = (libsodium._crypto_pwhash_scryptsalsa208sha256_saltbytes()) | 0;
  		if (salt.length !== salt_length) {
  			_free_and_throw_type_error(address_pool, "invalid salt length");
  		}
  		salt_address = _to_allocated_buf_address(salt);
  		address_pool.push(salt_address);
  		
  		// ---------- input: opsLimit (uint)
  		
  		_require_defined(address_pool, opsLimit, "opsLimit");
  		
  		if (!(typeof opsLimit === "number" && (opsLimit | 0) === opsLimit) && (opsLimit | 0) > 0) {
  			_free_and_throw_type_error(address_pool, "opsLimit must be an unsigned integer");
  		}
  		
  		// ---------- input: memLimit (uint)
  		
  		_require_defined(address_pool, memLimit, "memLimit");
  		
  		if (!(typeof memLimit === "number" && (memLimit | 0) === memLimit) && (memLimit | 0) > 0) {
  			_free_and_throw_type_error(address_pool, "memLimit must be an unsigned integer");
  		}
  		
  		// ---------- input: keyLength (uint)
  		
  		_require_defined(address_pool, keyLength, "keyLength");
  		
  		if (!(typeof keyLength === "number" && (keyLength | 0) === keyLength) && (keyLength | 0) > 0) {
  			_free_and_throw_type_error(address_pool, "keyLength must be an unsigned integer");
  		}
  		
  		// ---------- output derivedKey (buf)
  		
  		var derivedKey_length = (keyLength) | 0,
  		    derivedKey = new AllocatedBuf(derivedKey_length),
  		    derivedKey_address = derivedKey.address;
  		
  		address_pool.push(derivedKey_address);
  		
  		if ((libsodium._crypto_pwhash_scryptsalsa208sha256(derivedKey_address, keyLength, 0, password_address, password_length, 0, salt_address, opsLimit, 0, memLimit) | 0) === 0) {
  			var ret = _format_output(derivedKey, outputFormat);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_pwhash_scryptsalsa208sha256_ll(password, salt, opsLimit, r, p, keyLength, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: password (unsized_buf)
  		
  		password = _any_to_Uint8Array(address_pool, password, "password");
  		var password_address = _to_allocated_buf_address(password),
  		    password_length = password.length;
  		address_pool.push(password_address);
  		
  		// ---------- input: salt (unsized_buf)
  		
  		salt = _any_to_Uint8Array(address_pool, salt, "salt");
  		var salt_address = _to_allocated_buf_address(salt),
  		    salt_length = salt.length;
  		address_pool.push(salt_address);
  		
  		// ---------- input: opsLimit (uint)
  		
  		_require_defined(address_pool, opsLimit, "opsLimit");
  		
  		if (!(typeof opsLimit === "number" && (opsLimit | 0) === opsLimit) && (opsLimit | 0) > 0) {
  			_free_and_throw_type_error(address_pool, "opsLimit must be an unsigned integer");
  		}
  		
  		// ---------- input: r (uint)
  		
  		_require_defined(address_pool, r, "r");
  		
  		if (!(typeof r === "number" && (r | 0) === r) && (r | 0) > 0) {
  			_free_and_throw_type_error(address_pool, "r must be an unsigned integer");
  		}
  		
  		// ---------- input: p (uint)
  		
  		_require_defined(address_pool, p, "p");
  		
  		if (!(typeof p === "number" && (p | 0) === p) && (p | 0) > 0) {
  			_free_and_throw_type_error(address_pool, "p must be an unsigned integer");
  		}
  		
  		// ---------- input: keyLength (uint)
  		
  		_require_defined(address_pool, keyLength, "keyLength");
  		
  		if (!(typeof keyLength === "number" && (keyLength | 0) === keyLength) && (keyLength | 0) > 0) {
  			_free_and_throw_type_error(address_pool, "keyLength must be an unsigned integer");
  		}
  		
  		// ---------- output derivedKey (buf)
  		
  		var derivedKey_length = (keyLength) | 0,
  		    derivedKey = new AllocatedBuf(derivedKey_length),
  		    derivedKey_address = derivedKey.address;
  		
  		address_pool.push(derivedKey_address);
  		
  		if ((libsodium._crypto_pwhash_scryptsalsa208sha256_ll(password_address, password_length, salt_address, salt_length, opsLimit, 0, r, p, derivedKey_address, keyLength) | 0) === 0) {
  			var ret = _format_output(derivedKey, outputFormat);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_pwhash_scryptsalsa208sha256_str(password, opsLimit, memLimit, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: password (unsized_buf)
  		
  		password = _any_to_Uint8Array(address_pool, password, "password");
  		var password_address = _to_allocated_buf_address(password),
  		    password_length = password.length;
  		address_pool.push(password_address);
  		
  		// ---------- input: opsLimit (uint)
  		
  		_require_defined(address_pool, opsLimit, "opsLimit");
  		
  		if (!(typeof opsLimit === "number" && (opsLimit | 0) === opsLimit) && (opsLimit | 0) > 0) {
  			_free_and_throw_type_error(address_pool, "opsLimit must be an unsigned integer");
  		}
  		
  		// ---------- input: memLimit (uint)
  		
  		_require_defined(address_pool, memLimit, "memLimit");
  		
  		if (!(typeof memLimit === "number" && (memLimit | 0) === memLimit) && (memLimit | 0) > 0) {
  			_free_and_throw_type_error(address_pool, "memLimit must be an unsigned integer");
  		}
  		
  		// ---------- output hashed_password (buf)
  		
  		var hashed_password_length = (libsodium._crypto_pwhash_scryptsalsa208sha256_strbytes()) | 0,
  		    hashed_password = new AllocatedBuf(hashed_password_length),
  		    hashed_password_address = hashed_password.address;
  		
  		address_pool.push(hashed_password_address);
  		
  		if ((libsodium._crypto_pwhash_scryptsalsa208sha256_str(hashed_password_address, password_address, password_length, 0, opsLimit, 0, memLimit) | 0) === 0) {
  			var ret = libsodium.Pointer_stringify(hashed_password_address);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_pwhash_scryptsalsa208sha256_str_verify(hashed_password, password, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: hashed_password (string)
  		
  		hashed_password = from_string(hashed_password + "\0");
  		var hashed_password_address = _to_allocated_buf_address(hashed_password),
  		    hashed_password_length = hashed_password.length - 1;
  		address_pool.push(hashed_password_address);
  		
  		// ---------- input: password (unsized_buf)
  		
  		password = _any_to_Uint8Array(address_pool, password, "password");
  		var password_address = _to_allocated_buf_address(password),
  		    password_length = password.length;
  		address_pool.push(password_address);
  		
  		var result = libsodium._crypto_pwhash_scryptsalsa208sha256_str_verify(hashed_password_address, password_address, password_length, 0) | 0;
  		var ret = (result === 0);
  		_free_all(address_pool);
  		return ret;
  		
  	}
  
  	function crypto_scalarmult(privateKey, publicKey, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: privateKey (buf)
  		
  		privateKey = _any_to_Uint8Array(address_pool, privateKey, "privateKey");
  		var privateKey_address, privateKey_length = (libsodium._crypto_scalarmult_scalarbytes()) | 0;
  		if (privateKey.length !== privateKey_length) {
  			_free_and_throw_type_error(address_pool, "invalid privateKey length");
  		}
  		privateKey_address = _to_allocated_buf_address(privateKey);
  		address_pool.push(privateKey_address);
  		
  		// ---------- input: publicKey (buf)
  		
  		publicKey = _any_to_Uint8Array(address_pool, publicKey, "publicKey");
  		var publicKey_address, publicKey_length = (libsodium._crypto_scalarmult_scalarbytes()) | 0;
  		if (publicKey.length !== publicKey_length) {
  			_free_and_throw_type_error(address_pool, "invalid publicKey length");
  		}
  		publicKey_address = _to_allocated_buf_address(publicKey);
  		address_pool.push(publicKey_address);
  		
  		// ---------- output sharedSecret (buf)
  		
  		var sharedSecret_length = (libsodium._crypto_scalarmult_bytes()) | 0,
  		    sharedSecret = new AllocatedBuf(sharedSecret_length),
  		    sharedSecret_address = sharedSecret.address;
  		
  		address_pool.push(sharedSecret_address);
  		
  		if ((libsodium._crypto_scalarmult(sharedSecret_address, privateKey_address, publicKey_address) | 0) === 0) {
  			var ret = _format_output(sharedSecret, outputFormat);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_scalarmult_base(privateKey, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: privateKey (buf)
  		
  		privateKey = _any_to_Uint8Array(address_pool, privateKey, "privateKey");
  		var privateKey_address, privateKey_length = (libsodium._crypto_scalarmult_scalarbytes()) | 0;
  		if (privateKey.length !== privateKey_length) {
  			_free_and_throw_type_error(address_pool, "invalid privateKey length");
  		}
  		privateKey_address = _to_allocated_buf_address(privateKey);
  		address_pool.push(privateKey_address);
  		
  		// ---------- output publicKey (buf)
  		
  		var publicKey_length = (libsodium._crypto_scalarmult_scalarbytes()) | 0,
  		    publicKey = new AllocatedBuf(publicKey_length),
  		    publicKey_address = publicKey.address;
  		
  		address_pool.push(publicKey_address);
  		
  		if ((libsodium._crypto_scalarmult_base(publicKey_address, privateKey_address) | 0) === 0) {
  			var ret = _format_output(publicKey, outputFormat);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_secretbox_detached(message, nonce, key, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: message (unsized_buf)
  		
  		message = _any_to_Uint8Array(address_pool, message, "message");
  		var message_address = _to_allocated_buf_address(message),
  		    message_length = message.length;
  		address_pool.push(message_address);
  		
  		// ---------- input: nonce (buf)
  		
  		nonce = _any_to_Uint8Array(address_pool, nonce, "nonce");
  		var nonce_address, nonce_length = (libsodium._crypto_secretbox_noncebytes()) | 0;
  		if (nonce.length !== nonce_length) {
  			_free_and_throw_type_error(address_pool, "invalid nonce length");
  		}
  		nonce_address = _to_allocated_buf_address(nonce);
  		address_pool.push(nonce_address);
  		
  		// ---------- input: key (buf)
  		
  		key = _any_to_Uint8Array(address_pool, key, "key");
  		var key_address, key_length = (libsodium._crypto_secretbox_keybytes()) | 0;
  		if (key.length !== key_length) {
  			_free_and_throw_type_error(address_pool, "invalid key length");
  		}
  		key_address = _to_allocated_buf_address(key);
  		address_pool.push(key_address);
  		
  		// ---------- output cipher (buf)
  		
  		var cipher_length = (message_length) | 0,
  		    cipher = new AllocatedBuf(cipher_length),
  		    cipher_address = cipher.address;
  		
  		address_pool.push(cipher_address);
  		
  		// ---------- output mac (buf)
  		
  		var mac_length = (libsodium._crypto_secretbox_macbytes()) | 0,
  		    mac = new AllocatedBuf(mac_length),
  		    mac_address = mac.address;
  		
  		address_pool.push(mac_address);
  		
  		if ((libsodium._crypto_secretbox_detached(cipher_address, mac_address, message_address, message_length, 0, nonce_address, key_address) | 0) === 0) {
  			var ret = _format_output({mac: mac, cipher: cipher}, outputFormat);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_secretbox_easy(message, nonce, key, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: message (unsized_buf)
  		
  		message = _any_to_Uint8Array(address_pool, message, "message");
  		var message_address = _to_allocated_buf_address(message),
  		    message_length = message.length;
  		address_pool.push(message_address);
  		
  		// ---------- input: nonce (buf)
  		
  		nonce = _any_to_Uint8Array(address_pool, nonce, "nonce");
  		var nonce_address, nonce_length = (libsodium._crypto_secretbox_noncebytes()) | 0;
  		if (nonce.length !== nonce_length) {
  			_free_and_throw_type_error(address_pool, "invalid nonce length");
  		}
  		nonce_address = _to_allocated_buf_address(nonce);
  		address_pool.push(nonce_address);
  		
  		// ---------- input: key (buf)
  		
  		key = _any_to_Uint8Array(address_pool, key, "key");
  		var key_address, key_length = (libsodium._crypto_secretbox_keybytes()) | 0;
  		if (key.length !== key_length) {
  			_free_and_throw_type_error(address_pool, "invalid key length");
  		}
  		key_address = _to_allocated_buf_address(key);
  		address_pool.push(key_address);
  		
  		// ---------- output cipher (buf)
  		
  		var cipher_length = (message_length + libsodium._crypto_secretbox_macbytes()) | 0,
  		    cipher = new AllocatedBuf(cipher_length),
  		    cipher_address = cipher.address;
  		
  		address_pool.push(cipher_address);
  		
  		if ((libsodium._crypto_secretbox_easy(cipher_address, message_address, message_length, 0, nonce_address, key_address) | 0) === 0) {
  			var ret = _format_output(cipher, outputFormat);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_secretbox_open_detached(ciphertext, mac, nonce, key, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: ciphertext (unsized_buf)
  		
  		ciphertext = _any_to_Uint8Array(address_pool, ciphertext, "ciphertext");
  		var ciphertext_address = _to_allocated_buf_address(ciphertext),
  		    ciphertext_length = ciphertext.length;
  		address_pool.push(ciphertext_address);
  		
  		// ---------- input: mac (buf)
  		
  		mac = _any_to_Uint8Array(address_pool, mac, "mac");
  		var mac_address, mac_length = (libsodium._crypto_secretbox_macbytes()) | 0;
  		if (mac.length !== mac_length) {
  			_free_and_throw_type_error(address_pool, "invalid mac length");
  		}
  		mac_address = _to_allocated_buf_address(mac);
  		address_pool.push(mac_address);
  		
  		// ---------- input: nonce (buf)
  		
  		nonce = _any_to_Uint8Array(address_pool, nonce, "nonce");
  		var nonce_address, nonce_length = (libsodium._crypto_secretbox_noncebytes()) | 0;
  		if (nonce.length !== nonce_length) {
  			_free_and_throw_type_error(address_pool, "invalid nonce length");
  		}
  		nonce_address = _to_allocated_buf_address(nonce);
  		address_pool.push(nonce_address);
  		
  		// ---------- input: key (buf)
  		
  		key = _any_to_Uint8Array(address_pool, key, "key");
  		var key_address, key_length = (libsodium._crypto_secretbox_keybytes()) | 0;
  		if (key.length !== key_length) {
  			_free_and_throw_type_error(address_pool, "invalid key length");
  		}
  		key_address = _to_allocated_buf_address(key);
  		address_pool.push(key_address);
  		
  		// ---------- output message (buf)
  		
  		var message_length = (ciphertext_length) | 0,
  		    message = new AllocatedBuf(message_length),
  		    message_address = message.address;
  		
  		address_pool.push(message_address);
  		
  		if ((libsodium._crypto_secretbox_open_detached(message_address, ciphertext_address, mac_address, ciphertext_length, 0, nonce_address, key_address) | 0) === 0) {
  			var ret = _format_output(message, outputFormat);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_secretbox_open_easy(ciphertext, nonce, key, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: ciphertext (unsized_buf)
  		
  		ciphertext = _any_to_Uint8Array(address_pool, ciphertext, "ciphertext");
  		var ciphertext_address = _to_allocated_buf_address(ciphertext),
  		    ciphertext_length = ciphertext.length;
  		address_pool.push(ciphertext_address);
  		
  		// ---------- input: nonce (buf)
  		
  		nonce = _any_to_Uint8Array(address_pool, nonce, "nonce");
  		var nonce_address, nonce_length = (libsodium._crypto_secretbox_noncebytes()) | 0;
  		if (nonce.length !== nonce_length) {
  			_free_and_throw_type_error(address_pool, "invalid nonce length");
  		}
  		nonce_address = _to_allocated_buf_address(nonce);
  		address_pool.push(nonce_address);
  		
  		// ---------- input: key (buf)
  		
  		key = _any_to_Uint8Array(address_pool, key, "key");
  		var key_address, key_length = (libsodium._crypto_secretbox_keybytes()) | 0;
  		if (key.length !== key_length) {
  			_free_and_throw_type_error(address_pool, "invalid key length");
  		}
  		key_address = _to_allocated_buf_address(key);
  		address_pool.push(key_address);
  		
  		// ---------- output message (buf)
  		
  		var message_length = (ciphertext_length - libsodium._crypto_secretbox_macbytes()) | 0,
  		    message = new AllocatedBuf(message_length),
  		    message_address = message.address;
  		
  		address_pool.push(message_address);
  		
  		if ((libsodium._crypto_secretbox_open_easy(message_address, ciphertext_address, ciphertext_length, 0, nonce_address, key_address) | 0) === 0) {
  			var ret = _format_output(message, outputFormat);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_shorthash(message, key, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: message (unsized_buf)
  		
  		message = _any_to_Uint8Array(address_pool, message, "message");
  		var message_address = _to_allocated_buf_address(message),
  		    message_length = message.length;
  		address_pool.push(message_address);
  		
  		// ---------- input: key (buf)
  		
  		key = _any_to_Uint8Array(address_pool, key, "key");
  		var key_address, key_length = (libsodium._crypto_shorthash_keybytes()) | 0;
  		if (key.length !== key_length) {
  			_free_and_throw_type_error(address_pool, "invalid key length");
  		}
  		key_address = _to_allocated_buf_address(key);
  		address_pool.push(key_address);
  		
  		// ---------- output hash (buf)
  		
  		var hash_length = (libsodium._crypto_shorthash_bytes()) | 0,
  		    hash = new AllocatedBuf(hash_length),
  		    hash_address = hash.address;
  		
  		address_pool.push(hash_address);
  		
  		if ((libsodium._crypto_shorthash(hash_address, message_address, message_length, 0, key_address) | 0) === 0) {
  			var ret = _format_output(hash, outputFormat);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_sign(message, privateKey, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: message (unsized_buf)
  		
  		message = _any_to_Uint8Array(address_pool, message, "message");
  		var message_address = _to_allocated_buf_address(message),
  		    message_length = message.length;
  		address_pool.push(message_address);
  		
  		// ---------- input: privateKey (buf)
  		
  		privateKey = _any_to_Uint8Array(address_pool, privateKey, "privateKey");
  		var privateKey_address, privateKey_length = (libsodium._crypto_sign_secretkeybytes()) | 0;
  		if (privateKey.length !== privateKey_length) {
  			_free_and_throw_type_error(address_pool, "invalid privateKey length");
  		}
  		privateKey_address = _to_allocated_buf_address(privateKey);
  		address_pool.push(privateKey_address);
  		
  		// ---------- output signature (buf)
  		
  		var signature_length = (message.length + libsodium._crypto_sign_bytes()) | 0,
  		    signature = new AllocatedBuf(signature_length),
  		    signature_address = signature.address;
  		
  		address_pool.push(signature_address);
  		
  		if ((libsodium._crypto_sign(signature_address, null, message_address, message_length, 0, privateKey_address) | 0) === 0) {
  			var ret = _format_output(signature, outputFormat);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_sign_detached(message, privateKey, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: message (unsized_buf)
  		
  		message = _any_to_Uint8Array(address_pool, message, "message");
  		var message_address = _to_allocated_buf_address(message),
  		    message_length = message.length;
  		address_pool.push(message_address);
  		
  		// ---------- input: privateKey (buf)
  		
  		privateKey = _any_to_Uint8Array(address_pool, privateKey, "privateKey");
  		var privateKey_address, privateKey_length = (libsodium._crypto_sign_secretkeybytes()) | 0;
  		if (privateKey.length !== privateKey_length) {
  			_free_and_throw_type_error(address_pool, "invalid privateKey length");
  		}
  		privateKey_address = _to_allocated_buf_address(privateKey);
  		address_pool.push(privateKey_address);
  		
  		// ---------- output signature (buf)
  		
  		var signature_length = (libsodium._crypto_sign_bytes()) | 0,
  		    signature = new AllocatedBuf(signature_length),
  		    signature_address = signature.address;
  		
  		address_pool.push(signature_address);
  		
  		if ((libsodium._crypto_sign_detached(signature_address, null, message_address, message_length, 0, privateKey_address) | 0) === 0) {
  			var ret = _format_output(signature, outputFormat);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_sign_ed25519_pk_to_curve25519(edPk, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: edPk (buf)
  		
  		edPk = _any_to_Uint8Array(address_pool, edPk, "edPk");
  		var edPk_address, edPk_length = (libsodium._crypto_sign_publickeybytes()) | 0;
  		if (edPk.length !== edPk_length) {
  			_free_and_throw_type_error(address_pool, "invalid edPk length");
  		}
  		edPk_address = _to_allocated_buf_address(edPk);
  		address_pool.push(edPk_address);
  		
  		// ---------- output cPk (buf)
  		
  		var cPk_length = (libsodium._crypto_scalarmult_scalarbytes()) | 0,
  		    cPk = new AllocatedBuf(cPk_length),
  		    cPk_address = cPk.address;
  		
  		address_pool.push(cPk_address);
  		
  		if ((libsodium._crypto_sign_ed25519_pk_to_curve25519(cPk_address, edPk_address) | 0) === 0) {
  			var ret = _format_output(cPk, outputFormat);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_sign_ed25519_sk_to_curve25519(edSk, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: edSk (buf)
  		
  		edSk = _any_to_Uint8Array(address_pool, edSk, "edSk");
  		var edSk_address, edSk_length = (libsodium._crypto_sign_secretkeybytes()) | 0;
  		if (edSk.length !== edSk_length) {
  			_free_and_throw_type_error(address_pool, "invalid edSk length");
  		}
  		edSk_address = _to_allocated_buf_address(edSk);
  		address_pool.push(edSk_address);
  		
  		// ---------- output cSk (buf)
  		
  		var cSk_length = (libsodium._crypto_scalarmult_scalarbytes()) | 0,
  		    cSk = new AllocatedBuf(cSk_length),
  		    cSk_address = cSk.address;
  		
  		address_pool.push(cSk_address);
  		
  		if ((libsodium._crypto_sign_ed25519_sk_to_curve25519(cSk_address, edSk_address) | 0) === 0) {
  			var ret = _format_output(cSk, outputFormat);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_sign_ed25519_sk_to_pk(privateKey, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: privateKey (buf)
  		
  		privateKey = _any_to_Uint8Array(address_pool, privateKey, "privateKey");
  		var privateKey_address, privateKey_length = (libsodium._crypto_sign_secretkeybytes()) | 0;
  		if (privateKey.length !== privateKey_length) {
  			_free_and_throw_type_error(address_pool, "invalid privateKey length");
  		}
  		privateKey_address = _to_allocated_buf_address(privateKey);
  		address_pool.push(privateKey_address);
  		
  		// ---------- output publicKey (buf)
  		
  		var publicKey_length = (libsodium._crypto_sign_publickeybytes()) | 0,
  		    publicKey = new AllocatedBuf(publicKey_length),
  		    publicKey_address = publicKey.address;
  		
  		address_pool.push(publicKey_address);
  		
  		if ((libsodium._crypto_sign_ed25519_sk_to_pk(publicKey_address, privateKey_address) | 0) === 0) {
  			var ret = _format_output(publicKey, outputFormat);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_sign_ed25519_sk_to_seed(privateKey, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: privateKey (buf)
  		
  		privateKey = _any_to_Uint8Array(address_pool, privateKey, "privateKey");
  		var privateKey_address, privateKey_length = (libsodium._crypto_sign_secretkeybytes()) | 0;
  		if (privateKey.length !== privateKey_length) {
  			_free_and_throw_type_error(address_pool, "invalid privateKey length");
  		}
  		privateKey_address = _to_allocated_buf_address(privateKey);
  		address_pool.push(privateKey_address);
  		
  		// ---------- output seed (buf)
  		
  		var seed_length = (libsodium._crypto_sign_seedbytes()) | 0,
  		    seed = new AllocatedBuf(seed_length),
  		    seed_address = seed.address;
  		
  		address_pool.push(seed_address);
  		
  		if ((libsodium._crypto_sign_ed25519_sk_to_seed(seed_address, privateKey_address) | 0) === 0) {
  			var ret = _format_output(seed, outputFormat);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_sign_keypair(outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- output publicKey (buf)
  		
  		var publicKey_length = (libsodium._crypto_sign_publickeybytes()) | 0,
  		    publicKey = new AllocatedBuf(publicKey_length),
  		    publicKey_address = publicKey.address;
  		
  		address_pool.push(publicKey_address);
  		
  		// ---------- output privateKey (buf)
  		
  		var privateKey_length = (libsodium._crypto_sign_secretkeybytes()) | 0,
  		    privateKey = new AllocatedBuf(privateKey_length),
  		    privateKey_address = privateKey.address;
  		
  		address_pool.push(privateKey_address);
  		
  		if ((libsodium._crypto_sign_keypair(publicKey_address, privateKey_address) | 0) === 0) {
  			var ret = _format_output({publicKey: publicKey, privateKey: privateKey, keyType: 'ed25519'}, outputFormat);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_sign_open(signedMessage, publicKey, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: signedMessage (unsized_buf)
  		
  		signedMessage = _any_to_Uint8Array(address_pool, signedMessage, "signedMessage");
  		var signedMessage_address = _to_allocated_buf_address(signedMessage),
  		    signedMessage_length = signedMessage.length;
  		address_pool.push(signedMessage_address);
  		
  		// ---------- input: publicKey (buf)
  		
  		publicKey = _any_to_Uint8Array(address_pool, publicKey, "publicKey");
  		var publicKey_address, publicKey_length = (libsodium._crypto_sign_publickeybytes()) | 0;
  		if (publicKey.length !== publicKey_length) {
  			_free_and_throw_type_error(address_pool, "invalid publicKey length");
  		}
  		publicKey_address = _to_allocated_buf_address(publicKey);
  		address_pool.push(publicKey_address);
  		
  		// ---------- output message (buf)
  		
  		var message_length = (signedMessage_length - libsodium._crypto_sign_bytes()) | 0,
  		    message = new AllocatedBuf(message_length),
  		    message_address = message.address;
  		
  		address_pool.push(message_address);
  		
  		if ((libsodium._crypto_sign_open(message_address, null, signedMessage_address, signedMessage_length, 0, publicKey_address) | 0) === 0) {
  			var ret = _format_output(message, outputFormat);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_sign_seed_keypair(seed, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: seed (buf)
  		
  		seed = _any_to_Uint8Array(address_pool, seed, "seed");
  		var seed_address, seed_length = (libsodium._crypto_sign_seedbytes()) | 0;
  		if (seed.length !== seed_length) {
  			_free_and_throw_type_error(address_pool, "invalid seed length");
  		}
  		seed_address = _to_allocated_buf_address(seed);
  		address_pool.push(seed_address);
  		
  		// ---------- output publicKey (buf)
  		
  		var publicKey_length = (libsodium._crypto_sign_publickeybytes()) | 0,
  		    publicKey = new AllocatedBuf(publicKey_length),
  		    publicKey_address = publicKey.address;
  		
  		address_pool.push(publicKey_address);
  		
  		// ---------- output privateKey (buf)
  		
  		var privateKey_length = (libsodium._crypto_sign_secretkeybytes()) | 0,
  		    privateKey = new AllocatedBuf(privateKey_length),
  		    privateKey_address = privateKey.address;
  		
  		address_pool.push(privateKey_address);
  		
  		if ((libsodium._crypto_sign_seed_keypair(publicKey_address, privateKey_address, seed_address) | 0) === 0) {
  			var ret = _format_output({publicKey: publicKey, privateKey: privateKey, keyType: "ed25519"}, outputFormat);
  			_free_all(address_pool);
  			return ret;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function crypto_sign_verify_detached(signature, message, publicKey) {
  		var address_pool = [];
  
  		// ---------- input: signature (buf)
  		
  		signature = _any_to_Uint8Array(address_pool, signature, "signature");
  		var signature_address, signature_length = (libsodium._crypto_sign_bytes()) | 0;
  		if (signature.length !== signature_length) {
  			_free_and_throw_type_error(address_pool, "invalid signature length");
  		}
  		signature_address = _to_allocated_buf_address(signature);
  		address_pool.push(signature_address);
  		
  		// ---------- input: message (unsized_buf)
  		
  		message = _any_to_Uint8Array(address_pool, message, "message");
  		var message_address = _to_allocated_buf_address(message),
  		    message_length = message.length;
  		address_pool.push(message_address);
  		
  		// ---------- input: publicKey (buf)
  		
  		publicKey = _any_to_Uint8Array(address_pool, publicKey, "publicKey");
  		var publicKey_address, publicKey_length = (libsodium._crypto_sign_publickeybytes()) | 0;
  		if (publicKey.length !== publicKey_length) {
  			_free_and_throw_type_error(address_pool, "invalid publicKey length");
  		}
  		publicKey_address = _to_allocated_buf_address(publicKey);
  		address_pool.push(publicKey_address);
  		
  		var verificationResult = libsodium._crypto_sign_verify_detached(signature_address, message_address, message_length, 0, publicKey_address) | 0;
  		var ret = (verificationResult === 0);
  		_free_all(address_pool);
  		return ret;
  		
  	}
  
  	function randombytes_buf(length, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: length (uint)
  		
  		_require_defined(address_pool, length, "length");
  		
  		if (!(typeof length === "number" && (length | 0) === length) && (length | 0) > 0) {
  			_free_and_throw_type_error(address_pool, "length must be an unsigned integer");
  		}
  		
  		// ---------- output output (buf)
  		
  		var output_length = (length) | 0,
  		    output = new AllocatedBuf(output_length),
  		    output_address = output.address;
  		
  		address_pool.push(output_address);
  		
  		libsodium._randombytes_buf(output_address, length);
  		var ret = (_format_output(output, outputFormat));
  		_free_all(address_pool);
  		return ret;
  		
  	}
  
  	function randombytes_close(outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		libsodium._randombytes_close();
  		
  	}
  
  	function randombytes_random(outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		var random_value = libsodium._randombytes_random() >>> 0;
  		var ret = (random_value);
  		_free_all(address_pool);
  		return ret;
  		
  	}
  
  	function randombytes_set_implementation(implementation, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: implementation (randombytes_implementation)
  		
  		var implementation_address = libsodium._malloc(6 * 4);
  		for (var i = 0; i < 6; i++) {
  			libsodium.setValue(implementation_address + i * 4,
  			    libsodium.Runtime.addFunction(implementation
  			    [["implementation_name", "random", "stir", "uniform", "buf", "close"][i]]),
  			    "i32");
  		}
  		
  		if ((libsodium._randombytes_set_implementation(implementation_address) | 0) === 0) {
  			_free_all(address_pool);
  			return;
  		}
  		_free_and_throw_error(address_pool);
  		
  	}
  
  	function randombytes_stir(outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		libsodium._randombytes_stir();
  		
  	}
  
  	function randombytes_uniform(upper_bound, outputFormat) {
  		var address_pool = [];
  		_check_output_format(outputFormat);
  
  		// ---------- input: upper_bound (uint)
  		
  		_require_defined(address_pool, upper_bound, "upper_bound");
  		
  		if (!(typeof upper_bound === "number" && (upper_bound | 0) === upper_bound) && (upper_bound | 0) > 0) {
  			_free_and_throw_type_error(address_pool, "upper_bound must be an unsigned integer");
  		}
  		
  		var random_value = libsodium._randombytes_uniform(upper_bound) >>> 0;
  		var ret = (random_value);
  		_free_all(address_pool);
  		return ret;
  		
  	}
  
  	function sodium_version_string() {
  		var address_pool = [];
  
  		var version = libsodium._sodium_version_string();
  		var ret = (libsodium.Pointer_stringify(version));
  		_free_all(address_pool);
  		return ret;
  		
  	}
  
  
  	exports.from_base64 = from_base64;
  	exports.from_hex = from_hex;
  	exports.from_string = from_string;
  	exports.libsodium = libsodium;
  	exports.memcmp = memcmp;
  	exports.memzero = memzero;
  	exports.output_formats = output_formats;
  	exports.symbols = symbols;
  	exports.to_base64 = to_base64;
  	exports.to_hex = to_hex;
  
  	
  	var exported_functions = ["crypto_aead_chacha20poly1305_decrypt", "crypto_aead_chacha20poly1305_encrypt", "crypto_auth", "crypto_auth_hmacsha256", "crypto_auth_hmacsha512", "crypto_auth_verify", "crypto_auth_verify", "crypto_auth_verify", "crypto_box_detached", "crypto_box_easy", "crypto_box_keypair", "crypto_box_open_detached", "crypto_box_open_easy", "crypto_box_seal", "crypto_box_seal_open", "crypto_box_seed_keypair", "crypto_generichash", "crypto_generichash_final", "crypto_generichash_init", "crypto_generichash_update", "crypto_hash", "crypto_hash_sha256", "crypto_hash_sha512", "crypto_onetimeauth", "crypto_onetimeauth_verify", "crypto_pwhash_scryptsalsa208sha256", "crypto_pwhash_scryptsalsa208sha256_ll", "crypto_pwhash_scryptsalsa208sha256_str", "crypto_pwhash_scryptsalsa208sha256_str_verify", "crypto_scalarmult", "crypto_scalarmult_base", "crypto_secretbox_detached", "crypto_secretbox_easy", "crypto_secretbox_open_detached", "crypto_secretbox_open_easy", "crypto_shorthash", "crypto_sign", "crypto_sign_detached", "crypto_sign_ed25519_pk_to_curve25519", "crypto_sign_ed25519_sk_to_curve25519", "crypto_sign_ed25519_sk_to_pk", "crypto_sign_ed25519_sk_to_seed", "crypto_sign_keypair", "crypto_sign_open", "crypto_sign_seed_keypair", "crypto_sign_verify_detached", "randombytes_buf", "randombytes_close", "randombytes_random", "randombytes_set_implementation", "randombytes_stir", "randombytes_uniform", "sodium_version_string"],
  		functions = [crypto_aead_chacha20poly1305_decrypt, crypto_aead_chacha20poly1305_encrypt, crypto_auth, crypto_auth_hmacsha256, crypto_auth_hmacsha512, crypto_auth_verify, crypto_auth_verify, crypto_auth_verify, crypto_box_detached, crypto_box_easy, crypto_box_keypair, crypto_box_open_detached, crypto_box_open_easy, crypto_box_seal, crypto_box_seal_open, crypto_box_seed_keypair, crypto_generichash, crypto_generichash_final, crypto_generichash_init, crypto_generichash_update, crypto_hash, crypto_hash_sha256, crypto_hash_sha512, crypto_onetimeauth, crypto_onetimeauth_verify, crypto_pwhash_scryptsalsa208sha256, crypto_pwhash_scryptsalsa208sha256_ll, crypto_pwhash_scryptsalsa208sha256_str, crypto_pwhash_scryptsalsa208sha256_str_verify, crypto_scalarmult, crypto_scalarmult_base, crypto_secretbox_detached, crypto_secretbox_easy, crypto_secretbox_open_detached, crypto_secretbox_open_easy, crypto_shorthash, crypto_sign, crypto_sign_detached, crypto_sign_ed25519_pk_to_curve25519, crypto_sign_ed25519_sk_to_curve25519, crypto_sign_ed25519_sk_to_pk, crypto_sign_ed25519_sk_to_seed, crypto_sign_keypair, crypto_sign_open, crypto_sign_seed_keypair, crypto_sign_verify_detached, randombytes_buf, randombytes_close, randombytes_random, randombytes_set_implementation, randombytes_stir, randombytes_uniform, sodium_version_string];
  	for (var i = 0; i < functions.length; i++) {
  		if (typeof libsodium["_" + exported_functions[i]] === "function") {
  			exports[exported_functions[i]] = functions[i];
  		}
  	}
  	var constants = ["SODIUM_LIBRARY_VERSION_MAJOR", "SODIUM_LIBRARY_VERSION_MINOR", "crypto_aead_chacha20poly1305_ABYTES", "crypto_aead_chacha20poly1305_KEYBYTES", "crypto_aead_chacha20poly1305_NPUBBYTES", "crypto_aead_chacha20poly1305_NSECBYTES", "crypto_auth_BYTES", "crypto_auth_KEYBYTES", "crypto_box_BEFORENMBYTES", "crypto_box_MACBYTES", "crypto_box_NONCEBYTES", "crypto_box_PUBLICKEYBYTES", "crypto_box_SEALBYTES", "crypto_box_SECRETKEYBYTES", "crypto_box_SEEDBYTES", "crypto_generichash_BYTES", "crypto_generichash_BYTES_MAX", "crypto_generichash_BYTES_MIN", "crypto_generichash_KEYBYTES", "crypto_generichash_KEYBYTES_MAX", "crypto_generichash_KEYBYTES_MIN", "crypto_hash_BYTES", "crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE", "crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE", "crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE", "crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE", "crypto_pwhash_scryptsalsa208sha256_SALTBYTES", "crypto_pwhash_scryptsalsa208sha256_STRBYTES", "crypto_pwhash_scryptsalsa208sha256_STR_VERIFY", "crypto_scalarmult_BYTES", "crypto_scalarmult_SCALARBYTES", "crypto_secretbox_KEYBYTES", "crypto_secretbox_MACBYTES", "crypto_secretbox_NONCEBYTES", "crypto_shorthash_BYTES", "crypto_shorthash_KEYBYTES", "crypto_sign_BYTES", "crypto_sign_PUBLICKEYBYTES", "crypto_sign_SECRETKEYBYTES", "crypto_sign_SEEDBYTES"];
  	for (var i = 0; i < constants.length; i++) {
  		var raw = libsodium["_" + constants[i].toLowerCase()];
  		if (typeof raw === "function") exports[constants[i]] = raw()|0;
  	}
  	var constants_str = ["SODIUM_VERSION_STRING", "crypto_pwhash_scryptsalsa208sha256_STRPREFIX"];
  	for (var i = 0; i < constants_str.length; i++) {
  		var raw = libsodium["_" + constants_str[i].toLowerCase()];
  		if (typeof raw === "function") exports[constants_str[i]] = libsodium.Pointer_stringify(raw());
  	}
  
  	return exports;
  }));
  