forked from Autonomous-Finance/ao-link
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwasm-test-lua-wasm-files.txt
223 lines (222 loc) · 392 KB
/
wasm-test-lua-wasm-files.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
(elem (;0;) (i32.const 1) func $msghandler $laction $lstop $growstack $f_call $resume $unroll $f_parser $dothecall $lua_newstate $f_luaopen $boxgc $getF $getS $l_alloc $panic $dofilecont $ipairsaux $generic_reader $luaB_next $finishpcall $luaB_assert $luaB_collectgarbage $luaB_dofile $luaB_error $luaB_getmetatable $luaB_ipairs $luaB_loadfile $luaB_load $luaB_pairs $luaB_pcall $luaB_print $luaB_rawequal $luaB_rawlen $luaB_rawget $luaB_rawset $luaB_select $luaB_setmetatable $luaB_tonumber $luaB_tostring $luaB_type $luaB_xpcall $gctm $searcher_preload $searcher_Lua $searcher_C $searcher_Croot $ll_loadlib $ll_searchpath $ll_require $luaB_auxwrap $luaB_cocreate $luaB_coresume $luaB_corunning $luaB_costatus $luaB_cowrap $luaB_yield $luaB_yieldable $tconcat $tinsert $pack $unpack $tremove $tmove $sort $io_noclose $io_fclose $io_readline $io_pclose $io_close $io_flush $io_input $io_lines $io_open $io_output $io_popen $io_read $io_tmpfile $io_type $io_write $f_flush $f_lines $f_read $f_seek $f_setvbuf $f_write $f_gc $f_tostring $os_clock $os_date $os_difftime $os_execute $os_exit $os_getenv $os_remove $os_rename $os_setlocale $os_time $os_tmpname $writer $gmatch_aux $str_byte $str_char $str_dump $str_find $str_format $gmatch $str_gsub $str_len $str_lower $str_match $str_rep $str_reverse $str_sub $str_upper $str_pack $str_packsize $str_unpack $math_abs $math_acos $math_asin $math_atan $math_ceil $math_cos $math_deg $math_exp $math_toint $math_floor $math_fmod $math_ult $math_log $math_max $math_min $math_modf $math_rad $math_random $math_randomseed $math_sin $math_sqrt $math_tan $math_type $math_cosh $math_sinh $math_tanh $math_pow $math_frexp $math_ldexp $math_log10 $iter_aux $byteoffset $codepoint $utfchar $utflen $iter_codes $hookf $db_debug $db_getuservalue $db_gethook $db_getinfo $db_getlocal $db_getregistry $db_getmetatable $db_getupvalue $db_upvaluejoin $db_upvalueid $db_setuservalue $db_sethook $db_setlocal $db_setmetatable $db_setupvalue $db_traceback $b_arshift $b_and $b_not $b_or $b_xor $b_test $b_extract $b_lrot $b_lshift $b_replace $b_rrot $b_rshift $luaopen_base $luaopen_package $luaopen_coroutine $luaopen_table $luaopen_io $luaopen_os $luaopen_string $luaopen_math $luaopen_utf8 $luaopen_debug $luaopen_bit32 $__stdio_seek $__stdio_write $__stdio_read $__stdio_close $__pthread_mutex_lock $__emscripten_stdout_seek $fmt_fp $pop_arg_long_double $sn_write)
(data $.rodata (;0;) (i64.const 1024) ".pretty\00interval is empty\00infinity\00getregistry\00not enough memory\00monetary\00binary\00attempt to yield across a C-call boundary\00.stringify\00.crypto.util.array\00yday\00wday\00aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%||EcECExEXEyEYOdOeOHOIOmOMOSOuOUOVOwOWOy\00.crypto.cipher.norx\000x%llx\00pattern too complex\00.crypto.util.hex\00__newindex\00__index\00invalid upvalue index\00max\00-+ 0X0x\00-0X+0X 0X-0x+0x 0x\00__pow\00integer overflow\00C stack overflow\00string length overflow\00table overflow\00unsigned overflow\00getenv\00__idiv\00__div\00flnStu\00text\00next\00_IO_output\00_IO_input\00stdout\00btest\00isdst\00sqrt\00sort\00data string too short\00assert\00insert\00restart\00__bnot\00count\00Slnt\00print\00codepoint\00.bint\00absent\00comment\00constant\00.default\00__lt\00exit\00.crypto.digest.init\00.crypto.cipher.init\00.crypto.init\00.crypto.util.init\00.crypto.kdf.init\00.crypto.mac.init\00.crypto.util.bit\00arshift\00lshift\00rawset\00offset\00rawget\00collect\00select\00extract\00bt\00float\00variable-length format\00invalid format\00namewhat\00repeat\00__concat\00size_t\00*t\00status\00.crypto.cipher.morus\00too many arguments\00wrong number of arguments\00constants\00too many results\00trying to access non-existent bits\00.process\00__ipairs\00__pairs\00function or expression needs too many registers\00.handlers\00searchers\00nups\00labels/gotos\00string contains zeros\00acos\00too many nested functions\00nparams\00.utils\00.handlers-utils\00C levels\00too many upvalues\00attempt to compare two %s values\00too many captures\00core and library have incompatible numeric types\00activelines\00chunk has too many lines\00local variables\00opcodes\00.crypto.cipher.aes\00position out of bounds\00abs\00%s%s\00attempt to %s a %s value%s\00luaopen_%s\00@%s\00>%s\00module '%s' not found:%s\00%s expected, got %s\00%s near %s\00too many %s (limit is %d) in %s\00attempt to compare %s with %s\00cannot %s %s: %s\00%s:%d: %s\00error loading module '%s' from file '%s':\0a\09%s\00hour\00cur\00.crypto.cipher.mode.ctr\00stderr\00__bxor\00for iterator\00syntax error\00floor\00for\00__bor\00__shr\00lower\00invalid long string delimiter\00upper\00maxinteger\00tointeger\00mininteger\00object length is not an integer\00field '%s' is not an integer\00lua_Integer\00%d-byte integer does not fit into Lua Integer\00tonumber\00malformed number\00'for' limit must be a number\00'for' step must be a number\00'for' initial value must be a number\00lua_Number\00char\00year\00__eq\00frexp\00ldexp\00stop\00'__newindex' chain too long; possible loop\00'__index' chain too long; possible loop\00<%s> at line %d not inside a loop\00.dump\00step\00rep\00wrap\00Pp\00%s: %p\00proto\00goto\00/usr/local/lib/lua/5.3/?.so;/usr/local/lib/lua/5.3/loadall.so;./?.so\00.crypto.padding.zero\00attempt to divide by zero\00no\00io\00getinfo\00do\00ao\00return\00charpattern\00missing '[' after '%%f' in pattern\00json\00invalid option\00Instruction\00main function\00unable to dump given function\00cannot use '...' outside a vararg function\00failed to call handle function\00number%s has no integer representation\00number has no integer representation\00time result cannot be represented in this installation\00dynamic libraries not enabled; check your Lua installation\00not enough memory for buffer allocation\00perform bitwise operation on\00perform arithmetic on\00asin\00upvaluejoin\00min\00=stdin\00main\00float format mismatch in\00endianness mismatch in\00version mismatch in\00%s size mismatch in\00popen\00reopen\00rawlen\00__len\00then\00atan\00nan\00boolean\00failed to boot lua runtime\5cn\00value has no literal form\00random\00__unm\00.crypto.util.stream\00setstepmul\00__mul\00unexpected symbol\00full\00xpcall\00istailcall\00__call\00tail call\00until\00table index is nil\00ceil\00__shl\00.eval\00rawequal\00normal\00setlocal\00getlocal\00global\00Sl\00sethook\00gethook\00external hook\00main chunk\00%s: %s precompiled chunk\00seek\00clock\00too many results to unpack\00traceback\00break\00pi\00month\00searchpath\00cpath\00math\00flush\00cosh\00sinh\00tanh\00gmatch\00debug\00isvararg\00log\00lexical element too long\00control structure too long\00string slice too long\00invalid order function for sorting\00__tostring\00binary string\00invalid use of '%c' in replacement string\00final position out of string\00initial position out of string\00unfinished string\00reader function must return a string\00'__tostring' must return a string\00'package.%s' must be a string\00isrunning\00error in error handling\00config\00array too big\00memory allocation error: block too big\00deg\00%.14g\00setvbuf\00get length of\00inf\00self\00elseif\00modf\00version mismatch: app. needs %f, Lua core provides %f\00packsize\00string length does not fit in given size\00string longer than given size\00remove\00too many elements to move\00width must be positive\00field cannot be negative\00true\00setuservalue\00getuservalue\00setupvalue\00getupvalue\00no value\00.crypto.util.queue\00initial position is a continuation byte\00execute\00write\00rrotate\00lrotate\00concatenate\00collate\00create\00date\00setpause\00reverse\00close\00else\00false\00invalid pattern capture\00unfinished capture\00require\00ctype\00cannot resume non-suspended coroutine\00cannot resume dead coroutine\00attempt to yield from outside a coroutine\00currentline\00too many arguments to resume\00too many results to resume\00function handle is not defined globaly in lua runtime\00difftime\00tmpname\00rename\00unable to generate a unique filename\00__name\00while\00tmpfile\00dofile\00loadfile\00cannot close standard file\00attempt to use a closed file\00handle\00setmetatable\00getmetatable\00__metatable\00cannot change a protected metatable\00field '%s' missing in date table\00'package.searchers' must be a table\00isyieldable\00setlocale\00__le\00huge\00format result too large\00buffer too large\00interval too large\00resulting string too large\00UTF-8 value too large\00decimal escape too large\00index out of range\00position out of range\00level out of range\00value out of range\00base out of range\00no message\00package\00collectgarbage\00__mode\00invalid mode\00invalid UTF-8 code\00source\00invalid escape sequence\00.chance\00replace\00Ee\00fmod\00__mod\00metamethod\00destination wrap around\00field '%s' is out-of-bound\00find\00end\00__band\00%lld\00yield\00field\00upvalueid\00'popen' not supported\00corrupted\00multiple Lua VMs detected\00hexadecimal digit expected\00function arguments expected\00%s expected\00Lua function expected\00table or string expected\00value expected\00string/function/table expected\00nil or table expected\00thread expected\00'=' or 'in' expected\00<name> or '...' expected\00truncated\00file is already closed\00standard %s file is closed\00lastlinedefined\00randomseed\00suspended\00loaded\00__add\00rad\00preload\00thread\00dead\00\5c%03d\00\5c%d\00invalid capture index %%%d\00function at line %d\00no visible label '%s' for <goto> at line %d\00label '%s' already defined on line %d\00short_src\00func\00numeric\00__gc\00sec\00.crypto.cipher.mode.cbc\00.crypto.cipher.issac\00.crypto.mac.hmac\00%c\00gsub\00__sub\00rb\00loadlib\00.crypto.cipher.mode.ofb\00.crypto.cipher.mode.cfb\00.crypto.cipher.mode.ecb\00.crypto.digest.blake2b\00rwa\00/usr/local/share/lua/5.3/?.lua;/usr/local/share/lua/5.3/?/init.lua;/usr/local/lib/lua/5.3/?.lua;/usr/local/lib/lua/5.3/?/init.lua;./?.lua;./?/init.lua\00\1bLua\00light userdata\00%a\00not a\00__lua_webassembly__\00integral size (%d) out of limits [1,%d]\00=[C]\00\0a\09no field package.preload['%s']\00\22]\00xX\00LUABOX\00POSIX\00_ENV\00LUA_NOENV\00%U\00GMT\00pP\00.xXnN\00table index is NaN\00_VERSION\00NAN\00LC_ALL\00%I\00LUA_PATH\00LUA_CPATH\00_G\00LANG\00INF\00eE\00_LOADED\00_PRELOAD\00C\00=?\00<integer>\00<number>\00<string>\00<eof>\00<name>\00<\5c%d>\00function <%s:%d>\00>>\00~=\00>=\00==\00<=\00<<\00;;\00;\01;\00\0a\09%s:\00stack traceback:\00%d:\00::\00-0123456789\00utf8\00.crypto.cipher.aes128\00C.UTF-8\00.crypto.cipher.aes256\00.crypto.digest.sha2_256\00.crypto.digest.md5\00.crypto.digest.md4\00.base64\00.crypto.digest.sha3\00_5_3\00Lua 5.3\00atan2\00.crypto.kdf.pbkdf2\00.crypto.digest.md2\00.crypto.cipher.aes192\00bit32\00.crypto.digest.sha2_512\00format asks for alignment not power of 2\00.crypto.digest.sha1\00log10\00//\00_G.\00\0a\09...\00^$*+?.([%-\00w+\00-+\00FILE*\00(*temporary)\00(for index)\00(for limit)\00invalid format (repeated flags)\00stack overflow (%s)\00calling '%s' on bad self (%s)\00error in __gc metamethod (%s)\00bad argument #%d (%s)\00bad argument #%d to '%s' (%s)\00cannot open file '%s' (%s)\00invalid replacement value (a %s)\00(for generator)\00(for step)\00file (%p)\00(for control)\00(null)\00(*vararg)\00invalid format (width or precision too long)\00(error object is a %s value)\00(for state)\00(*no name)\00=(debug command)\00file (closed)\00=(load)\00too many %s (limit is %d)\00%s expected (to close %s at line %d)\00unfinished long %s (starting at line %d)\00\0a\09(...tail calls...)\00attempt to load a %s chunk (mode is '%s')\00 (%s '%s')\00malformed pattern (missing arguments to '%%b')\00malformed pattern (missing ']')\00malformed pattern (ends with '%%')\00missing '}'\00missing '{'\00invalid key to 'next'\00wrong number of arguments to 'insert'\00'tostring' must return a string to 'print'\00invalid option '%%%c' to 'format'\00invalid value (%s) at index %d in table for 'concat'\00%s '%s'\00invalid option '%s'\00function '%s'\00<goto %s> at line %d jumps into the scope of local '%s'\00\0a\09no file '%s'\00\0a\09no module '%s' in file '%s'\00invalid conversion specifier '%%%s'\00invalid option '%%%c' to 'lua_pushfstring'\00missing size for format option 'c'\00invalid format option '%c'\00invalid next option for option 'X'\00attempt to perform 'n%%0'\00%\00[string \22\00interrupted!\00assertion failed!\00 in \00lua_debug> \00%s:%d: \00 \0c\0a\0d\09\0b\00cont\0a\00error: %s\0a\00/\0a;\0a?\0a!\0a-\0a\00PANIC: unprotected error in call to Lua API (%s)\0a\00error on luaL_loadbuffer()\0a\00\19\93\0d\0a\1a\0a\00\01\00-- This script is bridge program for WASM\0alocal args = {...}\0alocal lua_bundle = args[1]\0a\0amath.random = function()\0a return 0.5 -- Replace with any value you want\0aend\0a-- Inline loader\0a-- In WASM Lua, all Lua scripted will be compiled as byte string and set to lua_bundle table.\0a-- Then, this loader will resolve by module name and evaluate it.\0alocal function _inline_loader(name)\0a local mod = lua_bundle[name] or lua_bundle[name .. '.init']\0a if not mod then return (\22module %s not found\22):format(name) end\0a if type(mod) == 'string' then\0a local chunk, err = load(mod, name)\0a if chunk then\0a return chunk\0a else\0a error((\22error loading module %s: %s\22):format(name, err), 0)\0a end\0a elseif type(mod) == 'function' then\0a return mod\0a end\0aend\0a\0atable.insert(package.loaders or package.searchers, 2, _inline_loader)\0a\0a-- The __lua_webassembly__ module will be inject via C program.\0alocal main = _inline_loader('__lua_webassembly__')\0amain()\0a\0a-- Export function call wrapper\0a-- function lua_call(function_name, ...)\0a-- for k, v in pairs(exports) do\0a-- print(k)\0a-- end\0a-- print(exports['hello_world'])\0a-- print(#function_name)\0a-- print(function_name == 'hello_world')\0a-- print(function_name == 'hello_world')\0a-- print(type(function_name))\0a-- \0a-- local mod = exports[function_name]\0a-- if not mod then\0a-- print((\22Module %s isn't exported\22):format(function_name))\0a-- return\0a-- elseif type(mod) ~= 'table' then\0a-- print((\22Module %s exported but not an table\22):format(function_name))\0a-- return\0a-- end\0a-- \0a-- local fn = mod.fn\0a-- if not fn then\0a-- print((\22Module %s.fn is not defined\22):format(function_name))\0a-- return\0a-- elseif type(fn) ~= 'function' then\0a-- print((\22Module %s.fn is not a function\22):format(function_name))\0a-- return\0a-- end\0a-- -- Call exported function\0a-- local arguments = {select(1, ...)}\0a-- return fn(table.unpack(arguments))\0a-- end\0a")
(data $.rodata.1 (;1;) (i64.const 11856) "local json = require \22json\22\0alocal process = require \22.process\22\0aao = require \22ao\22\0a\0afunction handle(msgJSON, aoJSON)\0a -- decode inputs\0a local msg = json.decode(msgJSON)\0a local env = json.decode(aoJSON)\0a ao.init(env)\0a -- relocate custom tags to root message\0a msg = ao.normalize(msg)\0a -- handle process\0a --\0a -- The process may throw an error, either intentionally or unintentionally\0a -- So we need to be able to catch these unhandled errors and bubble them\0a -- across the interop with some indication that it was unhandled\0a --\0a -- To do this, we wrap the process.handle with pcall(), and return both the status\0a -- and response as JSON. The caller can examine the status boolean and decide how to\0a -- handle the error\0a --\0a -- See pcall https://www.lua.org/pil/8.4.html\0a local status, response = pcall(function()\0a return (process.handle(msg, ao))\0a end)\0a\0a -- encode output\0a local responseJSON = json.encode({ok = status, response = response})\0a return responseJSON\0aend\0a\00\00\00\00\00--[[\0a\0a\0a\0a base64 -- v1.5.3 public domain Lua base64 encoder/decoder\0a\0a no warranty implied; use at your own risk\0a\0a\0a\0a Needs bit32.extract function. If not present it's implemented using BitOp\0a\0a or Lua 5.3 native bit operators. For Lua 5.1 fallbacks to pure Lua\0a\0a implementation inspired by Rici Lake's post:\0a\0a http://ricilake.blogspot.co.uk/2007/10/iterating-bits-in-lua.html\0a\0a\0a\0a author: Ilya Kolbin (iskolbin@gmail.com)\0a\0a url: github.com/iskolbin/lbase64\0a\0a\0a\0a COMPATIBILITY\0a\0a\0a\0a Lua 5.1+, LuaJIT\0a\0a\0a\0a LICENSE\0a\0a\0a\0a See end of file for license information.\0a\0a\0a\0a--]]\0a\0a\0a\0a\0a\0alocal base64 = {}\0a\0a\0a\0alocal extract = _G.bit32 and _G.bit32.extract -- Lua 5.2/Lua 5.3 in compatibility mode\0a\0aif not extract then\0a\0a\09if _G.bit then -- LuaJIT\0a\0a\09\09local shl, shr, band = _G.bit.lshift, _G.bit.rshift, _G.bit.band\0a\0a\09\09extract = function( v, from, width )\0a\0a\09\09\09return band( shr( v, from ), shl( 1, width ) - 1 )\0a\0a\09\09end\0a\0a\09elseif _G._VERSION == \22Lua 5.1\22 then\0a\0a\09\09extract = function( v, from, width )\0a\0a\09\09\09local w = 0\0a\0a\09\09\09local flag = 2^from\0a\0a\09\09\09for i = 0, width-1 do\0a\0a\09\09\09\09local flag2 = flag + flag\0a\0a\09\09\09\09if v % flag2 >= flag then\0a\0a\09\09\09\09\09w = w + 2^i\0a\0a\09\09\09\09end\0a\0a\09\09\09\09flag = flag2\0a\0a\09\09\09end\0a\0a\09\09\09return w\0a\0a\09\09end\0a\0a\09else -- Lua 5.3+\0a\0a\09\09extract = load[[return function( v, from, width )\0a\0a\09\09\09return ( v >> from ) & ((1 << width) - 1)\0a\0a\09\09end]]()\0a\0a\09end\0a\0aend\0a\0a\0a\0a\0a\0afunction base64.makeencoder( s62, s63, spad )\0a\0a\09local encoder = {}\0a\0a\09for b64code, char in pairs{[0]='A','B','C','D','E','F','G','H','I','J',\0a\0a\09\09'K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y',\0a\0a\09\09'Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n',\0a\0a\09\09'o','p','q','r','s','t','u','v','w','x','y','z','0','1','2',\0a\0a\09\09'3','4','5','6','7','8','9',s62 or '+',s63 or'/',spad or'='} do\0a\0a\09\09encoder[b64code] = char:byte()\0a\0a\09end\0a\0a\09return encoder\0a\0aend\0a\0a\0a\0afunction base64.makedecoder( s62, s63, spad )\0a\0a\09local decoder = {}\0a\0a\09for b64code, charcode in pairs( base64.makeencoder( s62, s63, spad )) do\0a\0a\09\09decoder[charcode] = b64code\0a\0a\09end\0a\0a\09return decoder\0a\0aend\0a\0a\0a\0alocal DEFAULT_ENCODER = base64.makeencoder()\0a\0alocal DEFAULT_DECODER = base64.makedecoder()\0a\0a\0a\0alocal char, concat = string.char, table.concat\0a\0a\0a\0afunction base64.encode( str, encoder, usecaching )\0a\0a\09encoder = encoder or DEFAULT_ENCODER\0a\0a\09local t, k, n = {}, 1, #str\0a\0a\09local lastn = n % 3\0a\0a\09local cache = {}\0a\0a\09for i = 1, n-lastn, 3 do\0a\0a\09\09local a, b, c = str:byte( i, i+2 )\0a\0a\09\09local v = a*0x10000 + b*0x100 + c\0a\0a\09\09local s\0a\0a\09\09if usecaching then\0a\0a\09\09\09s = cache[v]\0a\0a\09\09\09if not s then\0a\0a\09\09\09\09s = char(encoder[extract(v,18,6)], encoder[extract(v,12,6)], encoder[extract(v,6,6)], encoder[extract(v,0,6)])\0a\0a\09\09\09\09cache[v] = s\0a\0a\09\09\09end\0a\0a\09\09else\0a\0a\09\09\09s = char(encoder[extract(v,18,6)], encoder[extract(v,12,6)], encoder[extract(v,6,6)], encoder[extract(v,0,6)])\0a\0a\09\09end\0a\0a\09\09t[k] = s\0a\0a\09\09k = k + 1\0a\0a\09end\0a\0a\09if lastn == 2 then\0a\0a\09\09local a, b = str:byte( n-1, n )\0a\0a\09\09local v = a*0x10000 + b*0x100\0a\0a\09\09t[k] = char(encoder[extract(v,18,6)], encoder[extract(v,12,6)], encoder[extract(v,6,6)], encoder[64])\0a\0a\09elseif lastn == 1 then\0a\0a\09\09local v = str:byte( n )*0x10000\0a\0a\09\09t[k] = char(encoder[extract(v,18,6)], encoder[extract(v,12,6)], encoder[64], encoder[64])\0a\0a\09end\0a\0a\09return concat( t )\0a\0aend\0a\0a\0a\0afunction base64.decode( b64, decoder, usecaching )\0a\0a\09decoder = decoder or DEFAULT_DECODER\0a\0a\09local pattern = '[^%w%+%/%=]'\0a\0a\09if decoder then\0a\0a\09\09local s62, s63\0a\0a\09\09for charcode, b64code in pairs( decoder ) do\0a\0a\09\09\09if b64code == 62 then s62 = charcode\0a\0a\09\09\09elseif b64code == 63 then s63 = charcode\0a\0a\09\09\09end\0a\0a\09\09end\0a\0a\09\09pattern = ('[^%%w%%%s%%%s%%=]'):format( char(s62), char(s63) )\0a\0a\09end\0a\0a\09b64 = b64:gsub( pattern, '' )\0a\0a\09local cache = usecaching and {}\0a\0a\09local t, k = {}, 1\0a\0a\09local n = #b64\0a\0a\09local padding = b64:sub(-2) == '==' and 2 or b64:sub(-1) == '=' and 1 or 0\0a\0a\09for i = 1, padding > 0 and n-4 or n, 4 do\0a\0a\09\09local a, b, c, d = b64:byte( i, i+3 )\0a\0a\09\09local s\0a\0a\09\09if usecaching then\0a\0a\09\09\09local v0 = a*0x1000000 + b*0x10000 + c*0x100 + d\0a\0a\09\09\09s = cache[v0]\0a\0a\09\09\09if not s then\0a\0a\09\09\09\09local v = decoder[a]*0x40000 + decoder[b]*0x1000 + decoder[c]*0x40 + decoder[d]\0a\0a\09\09\09\09s = char( extract(v,16,8), extract(v,8,8), extract(v,0,8))\0a\0a\09\09\09\09cache[v0] = s\0a\0a\09\09\09end\0a\0a\09\09else\0a\0a\09\09\09local v = decoder[a]*0x40000 + decoder[b]*0x1000 + decoder[c]*0x40 + decoder[d]\0a\0a\09\09\09s = char( extract(v,16,8), extract(v,8,8), extract(v,0,8))\0a\0a\09\09end\0a\0a\09\09t[k] = s\0a\0a\09\09k = k + 1\0a\0a\09end\0a\0a\09if padding == 1 then\0a\0a\09\09local a, b, c = b64:byte( n-3, n-1 )\0a\0a\09\09local v = decoder[a]*0x40000 + decoder[b]*0x1000 + decoder[c]*0x40\0a\0a\09\09t[k] = char( extract(v,16,8), extract(v,8,8))\0a\0a\09elseif padding == 2 then\0a\0a\09\09local a, b = b64:byte( n-3, n-2 )\0a\0a\09\09local v = decoder[a]*0x40000 + decoder[b]*0x1000\0a\0a\09\09t[k] = char( extract(v,16,8))\0a\0a\09end\0a\0a\09return concat( t )\0a\0aend\0a\0a\0a\0areturn base64\0a\0a\0a\0a--[[\0a\0a------------------------------------------------------------------------------\0a\0aThis software is available under 2 licenses -- choose whichever you prefer.\0a\0a------------------------------------------------------------------------------\0a\0aALTERNATIVE A - MIT License\0a\0aCopyright (c) 2018 Ilya Kolbin\0a\0aPermission is hereby granted, free of charge, to any person obtaining a copy of\0a\0athis software and associated documentation files (the \22Software\22), to deal in\0a\0athe Software without restriction, including without limitation the rights to\0a\0ause, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\0a\0aof the Software, and to permit persons to whom the Software is furnished to do\0a\0aso, subject to the following conditions:\0a\0aThe above copyright notice and this permission notice shall be included in all\0a\0acopies or substantial portions of the Software.\0a\0aTHE SOFTWARE IS PROVIDED \22AS IS\22, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\0a\0aIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\0a\0aFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\0a\0aAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\0a\0aLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\0a\0aOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\0a\0aSOFTWARE.\0a\0a------------------------------------------------------------------------------\0a\0aALTERNATIVE B - Public Domain (www.unlicense.org)\0a\0aThis is free and unencumbered software released into the public domain.\0a\0aAnyone is free to copy, modify, publish, use, compile, sell, or distribute this\0a\0asoftware, either in source code form or as a compiled binary, for any purpose,\0a\0acommercial or non-commercial, and by any means.\0a\0aIn jurisdictions that recognize copyright laws, the author or authors of this\0a\0asoftware dedicate any and all copyright interest in the software to the public\0a\0adomain. We make this dedication for the benefit of the public at large and to\0a\0athe detriment of our heirs and successors. We intend this dedication to be an\0a\0aovert act of relinquishment in perpetuity of all present and future rights to\0a\0athis software under copyright law.\0a\0aTHE SOFTWARE IS PROVIDED \22AS IS\22, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\0a\0aIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\0a\0aFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\0a\0aAUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\0a\0aACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\0a\0aWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\0a\0a------------------------------------------------------------------------------\0a\0a--]]")
(data $.rodata.2 (;2;) (i64.const 20288) "--[[--\0a\0alua-bint - v0.5.1 - 26/Jun/2023\0a\0aEduardo Bart - edub4rt@gmail.com\0a\0ahttps://github.com/edubart/lua-bint\0a\0a\0a\0aSmall portable arbitrary-precision integer arithmetic library in pure Lua for\0a\0acomputing with large integers.\0a\0a\0a\0aDifferent from most arbitrary-precision integer libraries in pure Lua out there this one\0a\0auses an array of lua integers as underlying data-type in its implementation instead of\0a\0ausing strings or large tables, this make it efficient for working with fixed width integers\0a\0aand to make bitwise operations.\0a\0a\0a\0a## Design goals\0a\0a\0a\0aThe main design goal of this library is to be small, correct, self contained and use few\0a\0aresources while retaining acceptable performance and feature completeness.\0a\0a\0a\0aThe library is designed to follow recent Lua integer semantics, this means that\0a\0ainteger overflow warps around,\0a\0asigned integers are implemented using two-complement arithmetic rules,\0a\0ainteger division operations rounds towards minus infinity,\0a\0aany mixed operations with float numbers promotes the value to a float,\0a\0aand the usual division/power operation always promotes to floats.\0a\0a\0a\0aThe library is designed to be possible to work with only unsigned integer arithmetic\0a\0awhen using the proper methods.\0a\0a\0a\0aAll the lua arithmetic operators (+, -, *, //, /, %) and bitwise operators (&, |, ~, <<, >>)\0a\0aare implemented as metamethods.\0a\0a\0a\0aThe integer size must be fixed in advance and the library is designed to be more efficient when\0a\0aworking with integers of sizes between 64-4096 bits. If you need to work with really huge numbers\0a\0awithout size restrictions then use another library. This choice has been made to have more efficiency\0a\0ain that specific size range.\0a\0a\0a\0a## Usage\0a\0a\0a\0aFirst on you should require the bint file including how many bits the bint module will work with,\0a\0aby calling the returned function from the require, for example:\0a\0a\0a\0a```lua\0a\0alocal bint = require 'bint'(1024)\0a\0a```\0a\0a\0a\0aFor more information about its arguments see @{newmodule}.\0a\0aThen when you need create a bint, you can use one of the following functions:\0a\0a\0a\0a* @{bint.fromuinteger} (convert from lua integers, but read as unsigned integer)\0a\0a* @{bint.frominteger} (convert from lua integers, preserving the sign)\0a\0a* @{bint.frombase} (convert from arbitrary bases, like hexadecimal)\0a\0a* @{bint.fromstring} (convert from arbitrary string, support binary/hexadecimal/decimal)\0a\0a* @{bint.trunc} (convert from lua numbers, truncating the fractional part)\0a\0a* @{bint.new} (convert from anything, asserts on invalid integers)\0a\0a* @{bint.tobint} (convert from anything, returns nil on invalid integers)\0a\0a* @{bint.parse} (convert from anything, returns a lua number as fallback)\0a\0a* @{bint.zero}\0a\0a* @{bint.one}\0a\0a* `bint`\0a\0a\0a\0aYou can also call `bint` as it is an alias to `bint.new`.\0a\0aIn doubt use @{bint.new} to create a new bint.\0a\0a\0a\0aThen you can use all the usual lua numeric operations on it,\0a\0aall the arithmetic metamethods are implemented.\0a\0aWhen you are done computing and need to get the result,\0a\0aget the output from one of the following functions:\0a\0a\0a\0a* @{bint.touinteger} (convert to a lua integer, wraps around as an unsigned integer)\0a\0a* @{bint.tointeger} (convert to a lua integer, wraps around, preserves the sign)\0a\0a* @{bint.tonumber} (convert to lua float, losing precision)\0a\0a* @{bint.tobase} (convert to a string in any base)\0a\0a* @{bint.__tostring} (convert to a string in base 10)\0a\0a\0a\0aTo output a very large integer with no loss you probably want to use @{bint.tobase}\0a\0aor call `tostring` to get a string representation.\0a\0a\0a\0a## Precautions\0a\0a\0a\0aAll library functions can be mixed with lua numbers,\0a\0athis makes easy to mix operations between bints and lua numbers,\0a\0ahowever the user should take care in some situations:\0a\0a\0a\0a* Don't mix integers and float operations if you want to work with integers only.\0a\0a* Don't use the regular equal operator ('==') to compare values from this library,\0a\0aunless you know in advance that both values are of the same primitive type,\0a\0aotherwise it will always return false, use @{bint.eq} to be safe.\0a\0a* Don't pass fractional numbers to functions that an integer is expected\0a\0a* Don't mix operations between bint classes with different sizes as this is not supported, this\0a\0awill throw assertions.\0a\0a* Remember that casting back to lua integers or numbers precision can be lost.\0a\0a* For dividing while preserving integers use the @{bint.__idiv} (the '//' operator).\0a\0a* For doing power operation preserving integers use the @{bint.ipow} function.\0a\0a* Configure the proper integer size you intend to work with, otherwise large integers may wrap around.\0a\0a\0a\0a]]\0a\0a\0a\0a-- Returns number of bits of the internal lua integer type.\0a\0alocal function luainteger_bitsize()\0a\0a local n, i = -1, 0\0a\0a repeat\0a\0a n, i = n >> 16, i + 16\0a\0a until n==0\0a\0a return i\0a\0aend\0a\0a\0a\0alocal math_type = math.type\0a\0alocal math_floor = math.floor\0a\0alocal math_abs = math.abs\0a\0alocal math_ceil = math.ceil\0a\0alocal math_modf = math.modf\0a\0alocal math_mininteger = math.mininteger\0a\0alocal math_maxinteger = math.maxinteger\0a\0alocal math_max = math.max\0a\0alocal math_min = math.min\0a\0alocal string_format = string.format\0a\0alocal table_insert = table.insert\0a\0alocal table_concat = table.concat\0a\0alocal table_unpack = table.unpack\0a\0a\0a\0alocal memo = {}\0a\0a\0a\0a--- Create a new bint module representing integers of the desired bit size.\0a\0a-- This is the returned function when `require 'bint'` is called.\0a\0a-- @function newmodule\0a\0a-- @param bits Number of bits for the integer representation, must be multiple of wordbits and\0a\0a-- at least 64.\0a\0a-- @param[opt] wordbits Number of the bits for the internal word,\0a\0a-- defaults to half of Lua's integer size.\0a\0alocal function newmodule(bits, wordbits)\0a\0a\0a\0alocal intbits = luainteger_bitsize()\0a\0abits = bits or 256\0a\0awordbits = wordbits or (intbits // 2)\0a\0a\0a\0a-- Memoize bint modules\0a\0alocal memoindex = bits * 64 + wordbits\0a\0aif memo[memoindex] then\0a\0a return memo[memoindex]\0a\0aend\0a\0a\0a\0a-- Validate\0a\0aassert(bits % wordbits == 0, 'bitsize is not multiple of word bitsize')\0a\0aassert(2*wordbits <= intbits, 'word bitsize must be half of the lua integer bitsize')\0a\0aassert(bits >= 64, 'bitsize must be >= 64')\0a\0aassert(wordbits >= 8, 'wordbits must be at least 8')\0a\0aassert(bits % 8 == 0, 'bitsize must be multiple of 8')\0a\0a\0a\0a-- Create bint module\0a\0alocal bint = {}\0a\0abint.__index = bint\0a\0a\0a\0a--- Number of bits representing a bint instance.\0a\0abint.bits = bits\0a\0a\0a\0a-- Constants used internally\0a\0alocal BINT_BITS = bits\0a\0alocal BINT_BYTES = bits // 8\0a\0alocal BINT_WORDBITS = wordbits\0a\0alocal BINT_SIZE = BINT_BITS // BINT_WORDBITS\0a\0alocal BINT_WORDMAX = (1 << BINT_WORDBITS) - 1\0a\0alocal BINT_WORDMSB = (1 << (BINT_WORDBITS - 1))\0a\0alocal BINT_LEPACKFMT = '<'..('I'..(wordbits // 8)):rep(BINT_SIZE)\0a\0alocal BINT_MATHMININTEGER, BINT_MATHMAXINTEGER\0a\0alocal BINT_MININTEGER\0a\0a\0a\0a--- Create a new bint with 0 value.\0a\0afunction bint.zero()\0a\0a local x = setmetatable({}, bint)\0a\0a for i=1,BINT_SIZE do\0a\0a x[i] = 0\0a\0a end\0a\0a return x\0a\0aend\0a\0alocal bint_zero = bint.zero\0a\0a\0a\0a--- Create a new bint with 1 value.\0a\0afunction bint.one()\0a\0a local x = setmetatable({}, bint)\0a\0a x[1] = 1\0a\0a for i=2,BINT_SIZE do\0a\0a x[i] = 0\0a\0a end\0a\0a return x\0a\0aend\0a\0alocal bint_one = bint.one\0a\0a\0a\0a-- Convert a value to a lua integer without losing precision.\0a\0alocal function tointeger(x)\0a\0a x = tonumber(x)\0a\0a local ty = math_type(x)\0a\0a if ty == 'float' then\0a\0a local floorx = math_floor(x)\0a\0a if floorx == x then\0a\0a x = floorx\0a\0a ty = math_type(x)\0a\0a end\0a\0a end\0a\0a if ty == 'integer' then\0a\0a return x\0a\0a end\0a\0aend\0a\0a\0a\0a--- Create a bint from an unsigned integer.\0a\0a-- Treats signed integers as an unsigned integer.\0a\0a-- @param x A value to initialize from convertible to a lua integer.\0a\0a-- @return A new bint or nil in case the input cannot be represented by an integer.\0a\0a-- @see bint.frominteger\0a\0afunction bint.fromuinteger(x)\0a\0a x = tointeger(x)\0a\0a if x then\0a\0a if x == 1 then\0a\0a return bint_one()\0a\0a elseif x == 0 then\0a\0a return bint_zero()\0a\0a end\0a\0a local n = setmetatable({}, bint)\0a\0a for i=1,BINT_SIZE do\0a\0a n[i] = x & BINT_WORDMAX\0a\0a x = x >> BINT_WORDBITS\0a\0a end\0a\0a return n\0a\0a end\0a\0aend\0a\0alocal bint_fromuinteger = bint.fromuinteger\0a\0a\0a\0a--- Create a bint from a signed integer.\0a\0a-- @param x A value to initialize from convertible to a lua integer.\0a\0a-- @return A new bint or nil in case the input cannot be represented by an integer.\0a\0a-- @see bint.fromuinteger\0a\0afunction bint.frominteger(x)\0a\0a x = tointeger(x)\0a\0a if x then\0a\0a if x == 1 then\0a\0a return bint_one()\0a\0a elseif x == 0 then\0a\0a return bint_zero()\0a\0a end\0a\0a local neg = false\0a\0a if x < 0 then\0a\0a x = math_abs(x)\0a\0a neg = true\0a\0a end\0a\0a local n = setmetatable({}, bint)\0a\0a for i=1,BINT_SIZE do\0a\0a n[i] = x & BINT_WORDMAX\0a\0a x = x >> BINT_WORDBITS\0a\0a end\0a\0a if neg then\0a\0a n:_unm()\0a\0a end\0a\0a return n\0a\0a end\0a\0aend\0a\0alocal bint_frominteger = bint.frominteger\0a\0a\0a\0alocal basesteps = {}\0a\0a\0a\0a-- Compute the read step for frombase function\0a\0alocal function getbasestep(base)\0a\0a local step = basesteps[base]\0a\0a if step then\0a\0a return step\0a\0a end\0a\0a step = 0\0a\0a local dmax = 1\0a\0a local limit = math_maxinteger // base\0a\0a repeat\0a\0a step = step + 1\0a\0a dmax = dmax * base\0a\0a until dmax >= limit\0a\0a basesteps[base] = step\0a\0a return step\0a\0aend\0a\0a\0a\0a-- Compute power with lua integers.\0a\0alocal function ipow(y, x, n)\0a\0a if n == 1 then\0a\0a return y * x\0a\0a elseif n & 1 == 0 then --even\0a\0a return ipow(y, x * x, n // 2)\0a\0a end\0a\0a return ipow(x * y, x * x, (n-1) // 2)\0a\0aend\0a\0a\0a\0a--- Create a bint from a string of the desired base.\0a\0a-- @param s The string to be converted from,\0a\0a-- must have only alphanumeric and '+-' characters.\0a\0a-- @param[opt] base Base that the number is represented, defaults to 10.\0a\0a-- Must be at least 2 and at most 36.\0a\0a-- @return A new bint or nil in case the conversion failed.\0a\0afunction bint.frombase(s, base)\0a\0a if type(s) ~= 'string' then\0a\0a return\0a\0a end\0a\0a base = base or 10\0a\0a if not (base >= 2 and base <= 36) then\0a\0a -- number base is too large\0a\0a return\0a\0a end\0a\0a local step = getbasestep(base)\0a\0a if #s < step then\0a\0a -- string is small, use tonumber (faster)\0a\0a return bint_frominteger(tonumber(s, base))\0a\0a end\0a\0a local sign, int = s:lower():match('^([+-]?)(%w+)$')\0a\0a if not (sign and int) then\0a\0a -- invalid integer string representation\0a\0a return\0a\0a end\0a\0a local n = bint_zero()\0a\0a for i=1,#int,step do\0a\0a local part = int:sub(i,i+step-1)\0a\0a local d = tonumber(part, base)\0a\0a if not d then\0a\0a -- invalid integer string representation\0a\0a return\0a\0a end\0a\0a if i > 1 then\0a\0a n = n * ipow(1, base, #part)\0a\0a end\0a\0a if d ~= 0 then\0a\0a n:_add(d)\0a\0a end\0a\0a end\0a\0a if sign == '-' then\0a\0a n:_unm()\0a\0a end\0a\0a return n\0a\0aend\0a\0alocal bint_frombase = bint.frombase\0a\0a\0a\0a--- Create a new bint from a string.\0a\0a-- The string can by a decimal number, binary number prefixed with '0b' or hexadecimal number prefixed with '0x'.\0a\0a-- @param s A string convertible to a bint.\0a\0a-- @return A new bint or nil in case the conversion failed.\0a\0a-- @see bint.frombase\0a\0afunction bint.fromstring(s)\0a\0a if type(s) ~= 'string' then\0a\0a return\0a\0a end\0a\0a if s:find('^[+-]?[0-9]+$') then\0a\0a return bint_frombase(s, 10)\0a\0a elseif s:find('^[+-]?0[xX][0-9a-fA-F]+$') then\0a\0a return bint_frombase(s:gsub('0[xX]', '', 1), 16)\0a\0a elseif s:find('^[+-]?0[bB][01]+$') then\0a\0a return bint_frombase(s:gsub('0[bB]', '', 1), 2)\0a\0a end\0a\0aend\0a\0alocal bint_fromstring = bint.fromstring\0a\0a\0a\0a--- Create a new bint from a buffer of little-endian bytes.\0a\0a-- @param buffer Buffer of bytes, extra bytes are trimmed from the right, missing bytes are padded to the right.\0a\0a-- @raise An assert is thrown in case buffer is not an string.\0a\0a-- @return A bint.\0a\0afunction bint.fromle(buffer)\0a\0a assert(type(buffer) == 'string', 'buffer is not a string')\0a\0a if #buffer > BINT_BYTES then -- trim extra bytes from the right\0a\0a buffer = buffer:sub(1, BINT_BYTES)\0a\0a elseif #buffer < BINT_BYTES then -- add missing bytes to the right\0a\0a buffer = buffer..('\5cx00'):rep(BINT_BYTES - #buffer)\0a\0a end\0a\0a return setmetatable({BINT_LEPACKFMT:unpack(buffer)}, bint)\0a\0aend\0a\0a\0a\0a--- Create a new bint from a buffer of big-endian bytes.\0a\0a-- @param buffer Buffer of bytes, extra bytes are trimmed from the left, missing bytes are padded to the left.\0a\0a-- @raise An assert is thrown in case buffer is not an string.\0a\0a-- @return A bint.\0a\0afunction bint.frombe(buffer)\0a\0a assert(type(buffer) == 'string', 'buffer is not a string')\0a\0a if #buffer > BINT_BYTES then -- trim extra bytes from the left\0a\0a buffer = buffer:sub(-BINT_BYTES, #buffer)\0a\0a elseif #buffer < BINT_BYTES then -- add missing bytes to the left\0a\0a buffer = ('\5cx00'):rep(BINT_BYTES - #buffer)..buffer\0a\0a end\0a\0a return setmetatable({BINT_LEPACKFMT:unpack(buffer:reverse())}, bint)\0a\0aend\0a\0a\0a\0a--- Create a new bint from a value.\0a\0a-- @param x A value convertible to a bint (string, number or another bint).\0a\0a-- @return A new bint, guaranteed to be a new reference in case needed.\0a\0a-- @raise An assert is thrown in case x is not convertible to a bint.\0a\0a-- @see bint.tobint\0a\0a-- @see bint.parse\0a\0afunction bint.new(x)\0a\0a if getmetatable(x) ~= bint then\0a\0a local ty = type(x)\0a\0a if ty == 'number' then\0a\0a x = bint_frominteger(x)\0a\0a elseif ty == 'string' then\0a\0a x = bint_fromstring(x)\0a\0a end\0a\0a assert(x, 'value cannot be represented by a bint')\0a\0a return x\0a\0a end\0a\0a -- return a clone\0a\0a local n = setmetatable({}, bint)\0a\0a for i=1,BINT_SIZE do\0a\0a n[i] = x[i]\0a\0a end\0a\0a return n\0a\0aend\0a\0alocal bint_new = bint.new\0a\0a\0a\0a--- Convert a value to a bint if possible.\0a\0a-- @param x A value to be converted (string, number or another bint).\0a\0a-- @param[opt] clone A boolean that tells if a new bint reference should be returned.\0a\0a-- Defaults to false.\0a\0a-- @return A bint or nil in case the conversion failed.\0a\0a-- @see bint.new\0a\0a-- @see bint.parse\0a\0afunction bint.tobint(x, clone)\0a\0a if getmetatable(x) == bint then\0a\0a if not clone then\0a\0a return x\0a\0a end\0a\0a -- return a clone\0a\0a local n = setmetatable({}, bint)\0a\0a for i=1,BINT_SIZE do\0a\0a n[i] = x[i]\0a\0a end\0a\0a return n\0a\0a end\0a\0a local ty = type(x)\0a\0a if ty == 'number' then\0a\0a return bint_frominteger(x)\0a\0a elseif ty == 'string' then\0a\0a return bint_fromstring(x)\0a\0a end\0a\0aend\0a\0alocal tobint = bint.tobint\0a\0a\0a\0a--- Convert a value to a bint if possible otherwise to a lua number.\0a\0a-- Useful to prepare values that you are unsure if it's going to be an integer or float.\0a\0a-- @param x A value to be converted (string, number or another bint).\0a\0a-- @param[opt] clone A boolean that tells if a new bint reference should be returned.\0a\0a-- Defaults to false.\0a\0a-- @return A bint or a lua number or nil in case the conversion failed.\0a\0a-- @see bint.new\0a\0a-- @see bint.tobint\0a\0afunction bint.parse(x, clone)\0a\0a local i = tobint(x, clone)\0a\0a if i then\0a\0a return i\0a\0a end\0a\0a return tonumber(x)\0a\0aend\0a\0alocal bint_parse = bint.parse\0a\0a\0a\0a--- Convert a bint to an unsigned integer.\0a\0a-- Note that large unsigned integers may be represented as negatives in lua integers.\0a\0a-- Note that lua cannot represent values larger than 64 bits,\0a\0a-- in that case integer values wrap around.\0a\0a-- @param x A bint or a number to be converted into an unsigned integer.\0a\0a-- @return An integer or nil in case the input cannot be represented by an integer.\0a\0a-- @see bint.tointeger\0a\0afunction bint.touinteger(x)\0a\0a if getmetatable(x) == bint then\0a\0a local n = 0\0a\0a for i=1,BINT_SIZE do\0a\0a n = n | (x[i] << (BINT_WORDBITS * (i - 1)))\0a\0a end\0a\0a return n\0a\0a end\0a\0a return tointeger(x)\0a\0aend\0a\0a\0a\0a--- Convert a bint to a signed integer.\0a\0a-- It works by taking absolute values then applying the sign bit in case needed.\0a\0a-- Note that lua cannot represent values larger than 64 bits,\0a\0a-- in that case integer values wrap around.\0a\0a-- @param x A bint or value to be converted into an unsigned integer.\0a\0a-- @return An integer or nil in case the input cannot be represented by an integer.\0a\0a-- @see bint.touinteger\0a\0afunction bint.tointeger(x)\0a\0a if getmetatable(x) == bint then\0a\0a local n = 0\0a\0a local neg = x:isneg()\0a\0a if neg then\0a\0a x = -x\0a\0a end\0a\0a for i=1,BINT_SIZE do\0a\0a n = n | (x[i] << (BINT_WORDBITS * (i - 1)))\0a\0a end\0a\0a if neg then\0a\0a n = -n\0a\0a end\0a\0a return n\0a\0a end\0a\0a return tointeger(x)\0a\0aend\0a\0alocal bint_tointeger = bint.tointeger\0a\0a\0a\0alocal function bint_assert_tointeger(x)\0a\0a x = bint_tointeger(x)\0a\0a if not x then\0a\0a error('value has no integer representation')\0a\0a end\0a\0a return x\0a\0aend\0a\0a\0a\0a--- Convert a bint to a lua float in case integer would wrap around or lua integer otherwise.\0a\0a-- Different from @{bint.tointeger} the operation does not wrap around integers,\0a\0a-- but digits precision are lost in the process of converting to a float.\0a\0a-- @param x A bint or value to be converted into a lua number.\0a\0a-- @return A lua number or nil in case the input cannot be represented by a number.\0a\0a-- @see bint.tointeger\0a\0afunction bint.tonumber(x)\0a\0a if getmetatable(x) == bint then\0a\0a if x <= BINT_MATHMAXINTEGER and x >= BINT_MATHMININTEGER then\0a\0a return x:tointeger()\0a\0a end\0a\0a return tonumber(tostring(x))\0a\0a end\0a\0a return tonumber(x)\0a\0aend\0a\0alocal bint_tonumber = bint.tonumber\0a\0a\0a\0a-- Compute base letters to use in bint.tobase\0a\0alocal BASE_LETTERS = {}\0a\0ado\0a\0a for i=1,36 do\0a\0a BASE_LETTERS[i-1] = ('0123456789abcdefghijklmnopqrstuvwxyz'):sub(i,i)\0a\0a end\0a\0aend\0a\0a\0a\0a--- Convert a bint to a string in the desired base.\0a\0a-- @param x The bint to be converted from.\0a\0a-- @param[opt] base Base to be represented, defaults to 10.\0a\0a-- Must be at least 2 and at most 36.\0a\0a-- @param[opt] unsigned Whether to output as an unsigned integer.\0a\0a-- Defaults to false for base 10 and true for others.\0a\0a-- When unsigned is false the symbol '-' is prepended in negative values.\0a\0a-- @return A string representing the input.\0a\0a-- @raise An assert is thrown in case the base is invalid.\0a\0afunction bint.tobase(x, base, unsigned)\0a\0a x = tobint(x)\0a\0a if not x then\0a\0a -- x is a fractional float or something else\0a\0a return\0a\0a end\0a\0a base = base or 10\0a\0a if not (base >= 2 and base <= 36) then\0a\0a -- number base is too large\0a\0a return\0a\0a end\0a\0a if unsigned == nil then\0a\0a unsigned = base ~= 10\0a\0a end\0a\0a local isxneg = x:isneg()\0a\0a if (base == 10 and not unsigned) or (base == 16 and unsigned and not isxneg) then\0a\0a if x <= BINT_MATHMAXINTEGER and x >= BINT_MATHMININTEGER then\0a\0a -- integer is small, use tostring or string.format (faster)\0a\0a local n = x:tointeger()\0a\0a if base == 10 then\0a\0a return tostring(n)\0a\0a elseif unsigned then\0a\0a return string_format('%x', n)\0a\0a end\0a\0a end\0a\0a end\0a\0a local ss = {}\0a\0a local neg = not unsigned and isxneg\0a\0a x = neg and x:abs() or bint_new(x)\0a\0a local xiszero = x:iszero()\0a\0a if xiszero then\0a\0a return '0'\0a\0a end\0a\0a -- calculate basepow\0a\0a local step = 0\0a\0a local basepow = 1\0a\0a local limit = (BINT_WORDMSB - 1) // base\0a\0a repeat\0a\0a step = step + 1\0a\0a basepow = basepow * base\0a\0a until basepow >= limit\0a\0a -- serialize base digits\0a\0a local size = BINT_SIZE\0a\0a local xd, carry, d\0a\0a repeat\0a\0a -- single word division\0a\0a carry = 0\0a\0a xiszero = true\0a\0a for i=size,1,-1 do\0a\0a carry = carry | x[i]\0a\0a d, xd = carry // basepow, carry % basepow\0a\0a if xiszero and d ~= 0 then\0a\0a size = i\0a\0a xiszero = false\0a\0a end\0a\0a x[i] = d\0a\0a carry = xd << BINT_WORDBITS\0a\0a end\0a\0a -- digit division\0a\0a for _=1,step do\0a\0a xd, d = xd // base, xd % base\0a\0a if xiszero and xd == 0 and d == 0 then\0a\0a -- stop on leading zeros\0a\0a break\0a\0a end\0a\0a table_insert(ss, 1, BASE_LETTERS[d])\0a\0a end\0a\0a until xiszero\0a\0a if neg then\0a\0a table_insert(ss, 1, '-')\0a\0a end\0a\0a return table_concat(ss)\0a\0aend\0a\0a\0a\0alocal function bint_assert_convert(x)\0a\0a return assert(tobint(x), 'value has not integer representation')\0a\0aend\0a\0a\0a\0a--- Convert a bint to a buffer of little-endian bytes.\0a\0a-- @param x A bint or lua integer.\0a\0a-- @param[opt] trim If true, zero bytes on the right are trimmed.\0a\0a-- @return A buffer of bytes representing the input.\0a\0a-- @raise Asserts in case input is not convertible to an integer.\0a\0afunction bint.tole(x, trim)\0a\0a x = bint_assert_convert(x)\0a\0a local s = BINT_LEPACKFMT:pack(table_unpack(x))\0a\0a if trim then\0a\0a s = s:gsub('\5cx00+$', '')\0a\0a if s == '' then\0a\0a s = '\5cx00'\0a\0a end\0a\0a end\0a\0a return s\0a\0aend\0a\0a\0a\0a--- Convert a bint to a buffer of big-endian bytes.\0a\0a-- @param x A bint or lua integer.\0a\0a-- @param[opt] trim If true, zero bytes on the left are trimmed.\0a\0a-- @return A buffer of bytes representing the input.\0a\0a-- @raise Asserts in case input is not convertible to an integer.\0a\0afunction bint.tobe(x, trim)\0a\0a x = bint_assert_convert(x)\0a\0a local s = BINT_LEPACKFMT:pack(table_unpack(x)):reverse()\0a\0a if trim then\0a\0a s = s:gsub('^\5cx00+', '')\0a\0a if s == '' then\0a\0a s = '\5cx00'\0a\0a end\0a\0a end\0a\0a return s\0a\0aend\0a\0a\0a\0a--- Check if a number is 0 considering bints.\0a\0a-- @param x A bint or a lua number.\0a\0afunction bint.iszero(x)\0a\0a if getmetatable(x) == bint then\0a\0a for i=1,BINT_SIZE do\0a\0a if x[i] ~= 0 then\0a\0a return false\0a\0a end\0a\0a end\0a\0a return true\0a\0a end\0a\0a return x == 0\0a\0aend\0a\0a\0a\0a--- Check if a number is 1 considering bints.\0a\0a-- @param x A bint or a lua number.\0a\0afunction bint.isone(x)\0a\0a if getmetatable(x) == bint then\0a\0a if x[1] ~= 1 then\0a\0a return false\0a\0a end\0a\0a for i=2,BINT_SIZE do\0a\0a if x[i] ~= 0 then\0a\0a return false\0a\0a end\0a\0a end\0a\0a return true\0a\0a end\0a\0a return x == 1\0a\0aend\0a\0a\0a\0a--- Check if a number is -1 considering bints.\0a\0a-- @param x A bint or a lua number.\0a\0afunction bint.isminusone(x)\0a\0a if getmetatable(x) == bint then\0a\0a for i=1,BINT_SIZE do\0a\0a if x[i] ~= BINT_WORDMAX then\0a\0a return false\0a\0a end\0a\0a end\0a\0a return true\0a\0a end\0a\0a return x == -1\0a\0aend\0a\0alocal bint_isminusone = bint.isminusone\0a\0a\0a\0a--- Check if the input is a bint.\0a\0a-- @param x Any lua value.\0a\0afunction bint.isbint(x)\0a\0a return getmetatable(x) == bint\0a\0aend\0a\0a\0a\0a--- Check if the input is a lua integer or a bint.\0a\0a-- @param x Any lua value.\0a\0afunction bint.isintegral(x)\0a\0a return getmetatable(x) == bint or math_type(x) == 'integer'\0a\0aend\0a\0a\0a\0a--- Check if the input is a bint or a lua number.\0a\0a-- @param x Any lua value.\0a\0afunction bint.isnumeric(x)\0a\0a return getmetatable(x) == bint or type(x) == 'number'\0a\0aend\0a\0a\0a\0a--- Get the number type of the input (bint, integer or float).\0a\0a-- @param x Any lua value.\0a\0a-- @return Returns \22bint\22 for bints, \22integer\22 for lua integers,\0a\0a-- \22float\22 from lua floats or nil otherwise.\0a\0afunction bint.type(x)\0a\0a if getmetatable(x) == bint then\0a\0a return 'bint'\0a\0a end\0a\0a return math_type(x)\0a\0aend\0a\0a\0a\0a--- Check if a number is negative considering bints.\0a\0a-- Zero is guaranteed to never be negative for bints.\0a\0a-- @param x A bint or a lua number.\0a\0afunction bint.isneg(x)\0a\0a if getmetatable(x) == bint then\0a\0a return x[BINT_SIZE] & BINT_WORDMSB ~= 0\0a\0a end\0a\0a return x < 0\0a\0aend\0a\0alocal bint_isneg = bint.isneg\0a\0a\0a\0a--- Check if a number is positive considering bints.\0a\0a-- @param x A bint or a lua number.\0a\0afunction bint.ispos(x)\0a\0a if getmetatable(x) == bint then\0a\0a return not x:isneg() and not x:iszero()\0a\0a end\0a\0a return x > 0\0a\0aend\0a\0a\0a\0a--- Check if a number is even considering bints.\0a\0a-- @param x A bint or a lua number.\0a\0afunction bint.iseven(x)\0a\0a if getmetatable(x) == bint then\0a\0a return x[1] & 1 == 0\0a\0a end\0a\0a return math_abs(x) % 2 == 0\0a\0aend\0a\0a\0a\0a--- Check if a number is odd considering bints.\0a\0a-- @param x A bint or a lua number.\0a\0afunction bint.isodd(x)\0a\0a if getmetatable(x) == bint then\0a\0a return x[1] & 1 == 1\0a\0a end\0a\0a return math_abs(x) % 2 == 1\0a\0aend\0a\0a\0a\0a--- Create a new bint with the maximum possible integer value.\0a\0afunction bint.maxinteger()\0a\0a local x = setmetatable({}, bint)\0a\0a for i=1,BINT_SIZE-1 do\0a\0a x[i] = BINT_WORDMAX\0a\0a end\0a\0a x[BINT_SIZE] = BINT_WORDMAX ~ BINT_WORDMSB\0a\0a return x\0a\0aend\0a\0a\0a\0a--- Create a new bint with the minimum possible integer value.\0a\0afunction bint.mininteger()\0a\0a local x = setmetatable({}, bint)\0a\0a for i=1,BINT_SIZE-1 do\0a\0a x[i] = 0\0a\0a end\0a\0a x[BINT_SIZE] = BINT_WORDMSB\0a\0a return x\0a\0aend\0a\0a\0a\0a--- Bitwise left shift a bint in one bit (in-place).\0a\0afunction bint:_shlone()\0a\0a local wordbitsm1 = BINT_WORDBITS - 1\0a\0a for i=BINT_SIZE,2,-1 do\0a\0a self[i] = ((self[i] << 1) | (self[i-1] >> wordbitsm1)) & BINT_WORDMAX\0a\0a end\0a\0a self[1] = (self[1] << 1) & BINT_WORDMAX\0a\0a return self\0a\0aend\0a\0a\0a\0a--- Bitwise right shift a bint in one bit (in-place).\0a\0afunction bint:_shrone()\0a\0a local wordbitsm1 = BINT_WORDBITS - 1\0a\0a for i=1,BINT_SIZE-1 do\0a\0a self[i] = ((self[i] >> 1) | (self[i+1] << wordbitsm1)) & BINT_WORDMAX\0a\0a end\0a\0a self[BINT_SIZE] = self[BINT_SIZE] >> 1\0a\0a return self\0a\0aend\0a\0a\0a\0a-- Bitwise left shift words of a bint (in-place). Used only internally.\0a\0afunction bint:_shlwords(n)\0a\0a for i=BINT_SIZE,n+1,-1 do\0a\0a self[i] = self[i - n]\0a\0a end\0a\0a for i=1,n do\0a\0a self[i] = 0\0a\0a end\0a\0a return self\0a\0aend\0a\0a\0a\0a-- Bitwise right shift words of a bint (in-place). Used only internally.\0a\0afunction bint:_shrwords(n)\0a\0a if n < BINT_SIZE then\0a\0a for i=1,BINT_SIZE-n do\0a\0a self[i] = self[i + n]\0a\0a end\0a\0a for i=BINT_SIZE-n+1,BINT_SIZE do\0a\0a self[i] = 0\0a\0a end\0a\0a else\0a\0a for i=1,BINT_SIZE do\0a\0a self[i] = 0\0a\0a end\0a\0a end\0a\0a return self\0a\0aend\0a\0a\0a\0a--- Increment a bint by one (in-place).\0a\0afunction bint:_inc()\0a\0a for i=1,BINT_SIZE do\0a\0a local tmp = self[i]\0a\0a local v = (tmp + 1) & BINT_WORDMAX\0a\0a self[i] = v\0a\0a if v > tmp then\0a\0a break\0a\0a end\0a\0a end\0a\0a return self\0a\0aend\0a\0a\0a\0a--- Increment a number by one considering bints.\0a\0a-- @param x A bint or a lua number to increment.\0a\0afunction bint.inc(x)\0a\0a local ix = tobint(x, true)\0a\0a if ix then\0a\0a return ix:_inc()\0a\0a end\0a\0a return x + 1\0a\0aend\0a\0a\0a\0a--- Decrement a bint by one (in-place).\0a\0afunction bint:_dec()\0a\0a for i=1,BINT_SIZE do\0a\0a local tmp = self[i]\0a\0a local v = (tmp - 1) & BINT_WORDMAX\0a\0a self[i] = v\0a\0a if v <= tmp then\0a\0a break\0a\0a end\0a\0a end\0a\0a return self\0a\0aend\0a\0a\0a\0a--- Decrement a number by one considering bints.\0a\0a-- @param x A bint or a lua number to decrement.\0a\0afunction bint.dec(x)\0a\0a local ix = tobint(x, true)\0a\0a if ix then\0a\0a return ix:_dec()\0a\0a end\0a\0a return x - 1\0a\0aend\0a\0a\0a\0a--- Assign a bint to a new value (in-place).\0a\0a-- @param y A value to be copied from.\0a\0a-- @raise Asserts in case inputs are not convertible to integers.\0a\0afunction bint:_assign(y)\0a\0a y = bint_assert_convert(y)\0a\0a for i=1,BINT_SIZE do\0a\0a self[i] = y[i]\0a\0a end\0a\0a return self\0a\0aend\0a\0a\0a\0a--- Take absolute of a bint (in-place).\0a\0afunction bint:_abs()\0a\0a if self:isneg() then\0a\0a self:_unm()\0a\0a end\0a\0a return self\0a\0aend\0a\0a\0a\0a--- Take absolute of a number considering bints.\0a\0a-- @param x A bint or a lua number to take the absolute.\0a\0afunction bint.abs(x)\0a\0a local ix = tobint(x, true)\0a\0a if ix then\0a\0a return ix:_abs()\0a\0a end\0a\0a return math_abs(x)\0a\0aend\0a\0alocal bint_abs = bint.abs\0a\0a\0a\0a--- Take the floor of a number considering bints.\0a\0a-- @param x A bint or a lua number to perform the floor operation.\0a\0afunction bint.floor(x)\0a\0a if getmetatable(x) == bint then\0a\0a return bint_new(x)\0a\0a end\0a\0a return bint_new(math_floor(tonumber(x)))\0a\0aend\0a\0a\0a\0a--- Take ceil of a number considering bints.\0a\0a-- @param x A bint or a lua number to perform the ceil operation.\0a\0afunction bint.ceil(x)\0a\0a if getmetatable(x) == bint then\0a\0a return bint_new(x)\0a\0a end\0a\0a return bint_new(math_ceil(tonumber(x)))\0a\0aend\0a\0a\0a\0a--- Wrap around bits of an integer (discarding left bits) considering bints.\0a\0a-- @param x A bint or a lua integer.\0a\0a-- @param y Number of right bits to preserve.\0a\0afunction bint.bwrap(x, y)\0a\0a x = bint_assert_convert(x)\0a\0a if y <= 0 then\0a\0a return bint_zero()\0a\0a elseif y < BINT_BITS then\0a\0a return x & (bint_one() << y):_dec()\0a\0a end\0a\0a return bint_new(x)\0a\0aend\0a\0a\0a\0a--- Rotate left integer x by y bits considering bints.\0a\0a-- @param x A bint or a lua integer.\0a\0a-- @param y Number of bits to rotate.\0a\0afunction bint.brol(x, y)\0a\0a x, y = bint_assert_convert(x), bint_assert_tointeger(y)\0a\0a if y > 0 then\0a\0a return (x << y) | (x >> (BINT_BITS - y))\0a\0a elseif y < 0 then\0a\0a if y ~= math_mininteger then\0a\0a return x:bror(-y)\0a\0a else\0a\0a x:bror(-(y+1))\0a\0a x:bror(1)\0a\0a end\0a\0a end\0a\0a return x\0a\0aend\0a\0a\0a\0a--- Rotate right integer x by y bits considering bints.\0a\0a-- @param x A bint or a lua integer.\0a\0a-- @param y Number of bits to rotate.\0a\0afunction bint.bror(x, y)\0a\0a x, y = bint_assert_convert(x), bint_assert_tointeger(y)\0a\0a if y > 0 then\0a\0a return (x >> y) | (x << (BINT_BITS - y))\0a\0a elseif y < 0 then\0a\0a if y ~= math_mininteger then\0a\0a return x:brol(-y)\0a\0a else\0a\0a x:brol(-(y+1))\0a\0a x:brol(1)\0a\0a end\0a\0a end\0a\0a return x\0a\0aend\0a\0a\0a\0a--- Truncate a number to a bint.\0a\0a-- Floats numbers are truncated, that is, the fractional port is discarded.\0a\0a-- @param x A number to truncate.\0a\0a-- @return A new bint or nil in case the input does not fit in a bint or is not a number.\0a\0afunction bint.trunc(x)\0a\0a if getmetatable(x) ~= bint then\0a\0a x = tonumber(x)\0a\0a if x then\0a\0a local ty = math_type(x)\0a\0a if ty == 'float' then\0a\0a -- truncate to integer\0a\0a x = math_modf(x)\0a\0a end\0a\0a return bint_frominteger(x)\0a\0a end\0a\0a return\0a\0a end\0a\0a return bint_new(x)\0a\0aend\0a\0a\0a\0a--- Take maximum between two numbers considering bints.\0a\0a-- @param x A bint or lua number to compare.\0a\0a-- @param y A bint or lua number to compare.\0a\0a-- @return A bint or a lua number. Guarantees to return a new bint for integer values.\0a\0afunction bint.max(x, y)\0a\0a local ix, iy = tobint(x), tobint(y)\0a\0a if ix and iy then\0a\0a return bint_new(ix > iy and ix or iy)\0a\0a end\0a\0a return bint_parse(math_max(x, y))\0a\0aend\0a\0a\0a\0a--- Take minimum between two numbers considering bints.\0a\0a-- @param x A bint or lua number to compare.\0a\0a-- @param y A bint or lua number to compare.\0a\0a-- @return A bint or a lua number. Guarantees to return a new bint for integer values.\0a\0afunction bint.min(x, y)\0a\0a local ix, iy = tobint(x), tobint(y)\0a\0a if ix and iy then\0a\0a return bint_new(ix < iy and ix or iy)\0a\0a end\0a\0a return bint_parse(math_min(x, y))\0a\0aend\0a\0a\0a\0a--- Add an integer to a bint (in-place).\0a\0a-- @param y An integer to be added.\0a\0a-- @raise Asserts in case inputs are not convertible to integers.\0a\0afunction bint:_add(y)\0a\0a y = bint_assert_convert(y)\0a\0a local carry = 0\0a\0a for i=1,BINT_SIZE do\0a\0a local tmp = self[i] + y[i] + carry\0a\0a carry = tmp >> BINT_WORDBITS\0a\0a self[i] = tmp & BINT_WORDMAX\0a\0a end\0a\0a return self\0a\0aend\0a\0a\0a\0a--- Add two numbers considering bints.\0a\0a-- @param x A bint or a lua number to be added.\0a\0a-- @param y A bint or a lua number to be added.\0a\0afunction bint.__add(x, y)\0a\0a local ix, iy = tobint(x), tobint(y)\0a\0a if ix and iy then\0a\0a local z = setmetatable({}, bint)\0a\0a local carry = 0\0a\0a for i=1,BINT_SIZE do\0a\0a local tmp = ix[i] + iy[i] + carry\0a\0a carry = tmp >> BINT_WORDBITS\0a\0a z[i] = tmp & BINT_WORDMAX\0a\0a end\0a\0a return z\0a\0a end\0a\0a return bint_tonumber(x) + bint_tonumber(y)\0a\0aend\0a\0a\0a\0a--- Subtract an integer from a bint (in-place).\0a\0a-- @param y An integer to subtract.\0a\0a-- @raise Asserts in case inputs are not convertible to integers.\0a\0afunction bint:_sub(y)\0a\0a y = bint_assert_convert(y)\0a\0a local borrow = 0\0a\0a local wordmaxp1 = BINT_WORDMAX + 1\0a\0a for i=1,BINT_SIZE do\0a\0a local res = self[i] + wordmaxp1 - y[i] - borrow\0a\0a self[i] = res & BINT_WORDMAX\0a\0a borrow = (res >> BINT_WORDBITS) ~ 1\0a\0a end\0a\0a return self\0a\0aend\0a\0a\0a\0a--- Subtract two numbers considering bints.\0a\0a-- @param x A bint or a lua number to be subtracted from.\0a\0a-- @param y A bint or a lua number to subtract.\0a\0afunction bint.__sub(x, y)\0a\0a local ix, iy = tobint(x), tobint(y)\0a\0a if ix and iy then\0a\0a local z = setmetatable({}, bint)\0a\0a local borrow = 0\0a\0a local wordmaxp1 = BINT_WORDMAX + 1\0a\0a for i=1,BINT_SIZE do\0a\0a local res = ix[i] + wordmaxp1 - iy[i] - borrow\0a\0a z[i] = res & BINT_WORDMAX\0a\0a borrow = (res >> BINT_WORDBITS) ~ 1\0a\0a end\0a\0a return z\0a\0a end\0a\0a return bint_tonumber(x) - bint_tonumber(y)\0a\0aend\0a\0a\0a\0a--- Multiply two numbers considering bints.\0a\0a-- @param x A bint or a lua number to multiply.\0a\0a-- @param y A bint or a lua number to multiply.\0a\0afunction bint.__mul(x, y)\0a\0a local ix, iy = tobint(x), tobint(y)\0a\0a if ix and iy then\0a\0a local z = bint_zero()\0a\0a local sizep1 = BINT_SIZE+1\0a\0a local s = sizep1\0a\0a local e = 0\0a\0a for i=1,BINT_SIZE do\0a\0a if ix[i] ~= 0 or iy[i] ~= 0 then\0a\0a e = math_max(e, i)\0a\0a s = math_min(s, i)\0a\0a end\0a\0a end\0a\0a for i=s,e do\0a\0a for j=s,math_min(sizep1-i,e) do\0a\0a local a = ix[i] * iy[j]\0a\0a if a ~= 0 then\0a\0a local carry = 0\0a\0a for k=i+j-1,BINT_SIZE do\0a\0a local tmp = z[k] + (a & BINT_WORDMAX) + carry\0a\0a carry = tmp >> BINT_WORDBITS\0a\0a z[k] = tmp & BINT_WORDMAX\0a\0a a = a >> BINT_WORDBITS\0a\0a end\0a\0a end\0a\0a end\0a\0a end\0a\0a return z\0a\0a end\0a\0a return bint_tonumber(x) * bint_tonumber(y)\0a\0aend\0a\0a\0a\0a--- Check if bints are equal.\0a\0a-- @param x A bint to compare.\0a\0a-- @param y A bint to compare.\0a\0afunction bint.__eq(x, y)\0a\0a for i=1,BINT_SIZE do\0a\0a if x[i] ~= y[i] then\0a\0a return false\0a\0a end\0a\0a end\0a\0a return true\0a\0aend\0a\0a\0a\0a--- Check if numbers are equal considering bints.\0a\0a-- @param x A bint or lua number to compare.\0a\0a-- @param y A bint or lua number to compare.\0a\0afunction bint.eq(x, y)\0a\0a local ix, iy = tobint(x), tobint(y)\0a\0a if ix and iy then\0a\0a return ix == iy\0a\0a end\0a\0a return x == y\0a\0aend\0a\0alocal bint_eq = bint.eq\0a\0a\0a\0alocal function findleftbit(x)\0a\0a for i=BINT_SIZE,1,-1 do\0a\0a local v = x[i]\0a\0a if v ~= 0 then\0a\0a local j = 0\0a\0a repeat\0a\0a v = v >> 1\0a\0a j = j + 1\0a\0a until v == 0\0a\0a return (i-1)*BINT_WORDBITS + j - 1, i\0a\0a end\0a\0a end\0a\0aend\0a\0a\0a\0a-- Single word division modulus\0a\0alocal function sudivmod(nume, deno)\0a\0a local rema\0a\0a local carry = 0\0a\0a for i=BINT_SIZE,1,-1 do\0a\0a carry = carry | nume[i]\0a\0a nume[i] = carry // deno\0a\0a rema = carry % deno\0a\0a carry = rema << BINT_WORDBITS\0a\0a end\0a\0a return rema\0a\0aend\0a\0a\0a\0a--- Perform unsigned division and modulo operation between two integers considering bints.\0a\0a-- This is effectively the same of @{bint.udiv} and @{bint.umod}.\0a\0a-- @param x The numerator, must be a bint or a lua integer.\0a\0a-- @param y The denominator, must be a bint or a lua integer.\0a\0a-- @return The quotient following the remainder, both bints.\0a\0a-- @raise Asserts on attempt to divide by zero\0a\0a-- or if inputs are not convertible to integers.\0a\0a-- @see bint.udiv\0a\0a-- @see bint.umod\0a\0afunction bint.udivmod(x, y)\0a\0a local nume = bint_new(x)\0a\0a local deno = bint_assert_convert(y)\0a\0a -- compute if high bits of denominator are all zeros\0a\0a local ishighzero = true\0a\0a for i=2,BINT_SIZE do\0a\0a if deno[i] ~= 0 then\0a\0a ishighzero = false\0a\0a break\0a\0a end\0a\0a end\0a\0a if ishighzero then\0a\0a -- try to divide by a single word (optimization)\0a\0a local low = deno[1]\0a\0a assert(low ~= 0, 'attempt to divide by zero')\0a\0a if low == 1 then\0a\0a -- denominator is one\0a\0a return nume, bint_zero()\0a\0a elseif low <= (BINT_WORDMSB - 1) then\0a\0a -- can do single word division\0a\0a local rema = sudivmod(nume, low)\0a\0a return nume, bint_fromuinteger(rema)\0a\0a end\0a\0a end\0a\0a if nume:ult(deno) then\0a\0a -- denominator is greater than numerator\0a\0a return bint_zero(), nume\0a\0a end\0a\0a -- align leftmost digits in numerator and denominator\0a\0a local denolbit = findleftbit(deno)\0a\0a local numelbit, numesize = findleftbit(nume)\0a\0a local bit = numelbit - denolbit\0a\0a deno = deno << bit\0a\0a local wordmaxp1 = BINT_WORDMAX + 1\0a\0a local wordbitsm1 = BINT_WORDBITS - 1\0a\0a local denosize = numesize\0a\0a local quot = bint_zero()\0a\0a while bit >= 0 do\0a\0a -- compute denominator <= numerator\0a\0a local le = true\0a\0a local size = math_max(numesize, denosize)\0a\0a for i=size,1,-1 do\0a\0a local a, b = deno[i], nume[i]\0a\0a if a ~= b then\0a\0a le = a < b\0a\0a break\0a\0a end\0a\0a end\0a\0a -- if the portion of the numerator above the denominator is greater or equal than to the denominator\0a\0a if le then\0a\0a -- subtract denominator from the portion of the numerator\0a\0a local borrow = 0\0a\0a for i=1,size do\0a\0a local res = nume[i] + wordmaxp1 - deno[i] - borrow\0a\0a nume[i] = res & BINT_WORDMAX\0a\0a borrow = (res >> BINT_WORDBITS) ~ 1\0a\0a end\0a\0a -- concatenate 1 to the right bit of the quotient\0a\0a local i = (bit // BINT_WORDBITS) + 1\0a\0a quot[i] = quot[i] | (1 << (bit % BINT_WORDBITS))\0a\0a end\0a\0a -- shift right the denominator in one bit\0a\0a for i=1,denosize-1 do\0a\0a deno[i] = ((deno[i] >> 1) | (deno[i+1] << wordbitsm1)) & BINT_WORDMAX\0a\0a end\0a\0a local lastdenoword = deno[denosize] >> 1\0a\0a deno[denosize] = lastdenoword\0a\0a -- recalculate denominator size (optimization)\0a\0a if lastdenoword == 0 then\0a\0a while deno[denosize] == 0 do\0a\0a denosize = denosize - 1\0a\0a end\0a\0a if denosize == 0 then\0a\0a break\0a\0a end\0a\0a end\0a\0a -- decrement current set bit for the quotient\0a\0a bit = bit - 1\0a\0a end\0a\0a -- the remaining numerator is the remainder\0a\0a return quot, nume\0a\0aend\0a\0alocal bint_udivmod = bint.udivmod\0a\0a\0a\0a--- Perform unsigned division between two integers considering bints.\0a\0a-- @param x The numerator, must be a bint or a lua integer.\0a\0a-- @param y The denominator, must be a bint or a lua integer.\0a\0a-- @return The quotient, a bint.\0a\0a-- @raise Asserts on attempt to divide by zero\0a\0a-- or if inputs are not convertible to integers.\0a\0afunction bint.udiv(x, y)\0a\0a return (bint_udivmod(x, y))\0a\0aend\0a\0a\0a\0a--- Perform unsigned integer modulo operation between two integers considering bints.\0a\0a-- @param x The numerator, must be a bint or a lua integer.\0a\0a-- @param y The denominator, must be a bint or a lua integer.\0a\0a-- @return The remainder, a bint.\0a\0a-- @raise Asserts on attempt to divide by zero\0a\0a-- or if the inputs are not convertible to integers.\0a\0afunction bint.umod(x, y)\0a\0a local _, rema = bint_udivmod(x, y)\0a\0a return rema\0a\0aend\0a\0alocal bint_umod = bint.umod\0a\0a\0a\0a--- Perform integer truncate division and modulo operation between two numbers considering bints.\0a\0a-- This is effectively the same of @{bint.tdiv} and @{bint.tmod}.\0a\0a-- @param x The numerator, a bint or lua number.\0a\0a-- @param y The denominator, a bint or lua number.\0a\0a-- @return The quotient following the remainder, both bint or lua number.\0a\0a-- @raise Asserts on attempt to divide by zero or on division overflow.\0a\0a-- @see bint.tdiv\0a\0a-- @see bint.tmod\0a\0afunction bint.tdivmod(x, y)\0a\0a local ax, ay = bint_abs(x), bint_abs(y)\0a\0a local ix, iy = tobint(ax), tobint(ay)\0a\0a local quot, rema\0a\0a if ix and iy then\0a\0a assert(not (bint_eq(x, BINT_MININTEGER) and bint_isminusone(y)), 'division overflow')\0a\0a quot, rema = bint_udivmod(ix, iy)\0a\0a else\0a\0a quot, rema = ax // ay, ax % ay\0a\0a end\0a\0a local isxneg, isyneg = bint_isneg(x), bint_isneg(y)\0a\0a if isxneg ~= isyneg then\0a\0a quot = -quot\0a\0a end\0a\0a if isxneg then\0a\0a rema = -rema\0a\0a end\0a\0a return quot, rema\0a\0aend\0a\0alocal bint_tdivmod = bint.tdivmod\0a\0a\0a\0a--- Perform truncate division between two numbers considering bints.\0a\0a-- Truncate division is a division that rounds the quotient towards zero.\0a\0a-- @param x The numerator, a bint or lua number.\0a\0a-- @param y The denominator, a bint or lua number.\0a\0a-- @return The quotient, a bint or lua number.\0a\0a-- @raise Asserts on attempt to divide by zero or on division overflow.\0a\0afunction bint.tdiv(x, y)\0a\0a return (bint_tdivmod(x, y))\0a\0aend\0a\0a\0a\0a--- Perform integer truncate modulo operation between two numbers considering bints.\0a\0a-- The operation is defined as the remainder of the truncate division\0a\0a-- (division that rounds the quotient towards zero).\0a\0a-- @param x The numerator, a bint or lua number.\0a\0a-- @param y The denominator, a bint or lua number.\0a\0a-- @return The remainder, a bint or lua number.\0a\0a-- @raise Asserts on attempt to divide by zero or on division overflow.\0a\0afunction bint.tmod(x, y)\0a\0a local _, rema = bint_tdivmod(x, y)\0a\0a return rema\0a\0aend\0a\0a\0a\0a--- Perform integer floor division and modulo operation between two numbers considering bints.\0a\0a-- This is effectively the same of @{bint.__idiv} and @{bint.__mod}.\0a\0a-- @param x The numerator, a bint or lua number.\0a\0a-- @param y The denominator, a bint or lua number.\0a\0a-- @return The quotient following the remainder, both bint or lua number.\0a\0a-- @raise Asserts on attempt to divide by zero.\0a\0a-- @see bint.__idiv\0a\0a-- @see bint.__mod\0a\0afunction bint.idivmod(x, y)\0a\0a local ix, iy = tobint(x), tobint(y)\0a\0a if ix and iy then\0a\0a local isnumeneg = ix[BINT_SIZE] & BINT_WORDMSB ~= 0\0a\0a local isdenoneg = iy[BINT_SIZE] & BINT_WORDMSB ~= 0\0a\0a if isnumeneg then\0a\0a ix = -ix\0a\0a end\0a\0a if isdenoneg then\0a\0a iy = -iy\0a\0a end\0a\0a local quot, rema = bint_udivmod(ix, iy)\0a\0a if isnumeneg ~= isdenoneg then\0a\0a quot:_unm()\0a\0a -- round quotient towards minus infinity\0a\0a if not rema:iszero() then\0a\0a quot:_dec()\0a\0a -- adjust the remainder\0a\0a if isnumeneg and not isdenoneg then\0a\0a rema:_unm():_add(y)\0a\0a elseif isdenoneg and not isnumeneg then\0a\0a rema:_add(y)\0a\0a end\0a\0a end\0a\0a elseif isnumeneg then\0a\0a -- adjust the remainder\0a\0a rema:_unm()\0a\0a end\0a\0a return quot, rema\0a\0a end\0a\0a local nx, ny = bint_tonumber(x), bint_tonumber(y)\0a\0a return nx // ny, nx % ny\0a\0aend\0a\0alocal bint_idivmod = bint.idivmod\0a\0a\0a\0a--- Perform floor division between two numbers considering bints.\0a\0a-- Floor division is a division that rounds the quotient towards minus infinity,\0a\0a-- resulting in the floor of the division of its operands.\0a\0a-- @param x The numerator, a bint or lua number.\0a\0a-- @param y The denominator, a bint or lua number.\0a\0a-- @return The quotient, a bint or lua number.\0a\0a-- @raise Asserts on attempt to divide by zero.\0a\0afunction bint.__idiv(x, y)\0a\0a local ix, iy = tobint(x), tobint(y)\0a\0a if ix and iy then\0a\0a local isnumeneg = ix[BINT_SIZE] & BINT_WORDMSB ~= 0\0a\0a local isdenoneg = iy[BINT_SIZE] & BINT_WORDMSB ~= 0\0a\0a if isnumeneg then\0a\0a ix = -ix\0a\0a end\0a\0a if isdenoneg then\0a\0a iy = -iy\0a\0a end\0a\0a local quot, rema = bint_udivmod(ix, iy)\0a\0a if isnumeneg ~= isdenoneg then\0a\0a quot:_unm()\0a\0a -- round quotient towards minus infinity\0a\0a if not rema:iszero() then\0a\0a quot:_dec()\0a\0a end\0a\0a end\0a\0a return quot, rema\0a\0a end\0a\0a return bint_tonumber(x) // bint_tonumber(y)\0a\0aend\0a\0a\0a\0a--- Perform division between two numbers considering bints.\0a\0a-- This always casts inputs to floats, for integer division only use @{bint.__idiv}.\0a\0a-- @param x The numerator, a bint or lua number.\0a\0a-- @param y The denominator, a bint or lua number.\0a\0a-- @return The quotient, a lua number.\0a\0afunction bint.__div(x, y)\0a\0a return bint_tonumber(x) / bint_tonumber(y)\0a\0aend\0a\0a\0a\0a--- Perform integer floor modulo operation between two numbers considering bints.\0a\0a-- The operation is defined as the remainder of the floor division\0a\0a-- (division that rounds the quotient towards minus infinity).\0a\0a-- @param x The numerator, a bint or lua number.\0a\0a-- @param y The denominator, a bint or lua number.\0a\0a-- @return The remainder, a bint or lua number.\0a\0a-- @raise Asserts on attempt to divide by zero.\0a\0afunction bint.__mod(x, y)\0a\0a local _, rema = bint_idivmod(x, y)\0a\0a return rema\0a\0aend\0a\0a\0a\0a--- Perform integer power between two integers considering bints.\0a\0a-- If y is negative then pow is performed as an unsigned integer.\0a\0a-- @param x The base, an integer.\0a\0a-- @param y The exponent, an integer.\0a\0a-- @return The result of the pow operation, a bint.\0a\0a-- @raise Asserts in case inputs are not convertible to integers.\0a\0a-- @see bint.__pow\0a\0a-- @see bint.upowmod\0a\0afunction bint.ipow(x, y)\0a\0a y = bint_assert_convert(y)\0a\0a if y:iszero() then\0a\0a return bint_one()\0a\0a elseif y:isone() then\0a\0a return bint_new(x)\0a\0a end\0a\0a -- compute exponentiation by squaring\0a\0a x, y = bint_new(x), bint_new(y)\0a\0a local z = bint_one()\0a\0a repeat\0a\0a if y:iseven() then\0a\0a x = x * x\0a\0a y:_shrone()\0a\0a else\0a\0a z = x * z\0a\0a x = x * x\0a\0a y:_dec():_shrone()\0a\0a end\0a\0a until y:isone()\0a\0a return x * z\0a\0aend\0a\0a\0a\0a--- Perform integer power between two unsigned integers over a modulus considering bints.\0a\0a-- @param x The base, an integer.\0a\0a-- @param y The exponent, an integer.\0a\0a-- @param m The modulus, an integer.\0a\0a-- @return The result of the pow operation, a bint.\0a\0a-- @raise Asserts in case inputs are not convertible to integers.\0a\0a-- @see bint.__pow\0a\0a-- @see bint.ipow\0a\0afunction bint.upowmod(x, y, m)\0a\0a m = bint_assert_convert(m)\0a\0a if m:isone() then\0a\0a return bint_zero()\0a\0a end\0a\0a x, y = bint_new(x), bint_new(y)\0a\0a local z = bint_one()\0a\0a x = bint_umod(x, m)\0a\0a while not y:iszero() do\0a\0a if y:isodd() then\0a\0a z = bint_umod(z*x, m)\0a\0a end\0a\0a y:_shrone()\0a\0a x = bint_umod(x*x, m)\0a\0a end\0a\0a return z\0a\0aend\0a\0a\0a\0a--- Perform numeric power between two numbers considering bints.\0a\0a-- This always casts inputs to floats, for integer power only use @{bint.ipow}.\0a\0a-- @param x The base, a bint or lua number.\0a\0a-- @param y The exponent, a bint or lua number.\0a\0a-- @return The result of the pow operation, a lua number.\0a\0a-- @see bint.ipow\0a\0afunction bint.__pow(x, y)\0a\0a return bint_tonumber(x) ^ bint_tonumber(y)\0a\0aend\0a\0a\0a\0a--- Bitwise left shift integers considering bints.\0a\0a-- @param x An integer to perform the bitwise shift.\0a\0a-- @param y An integer with the number of bits to shift.\0a\0a-- @return The result of shift operation, a bint.\0a\0a-- @raise Asserts in case inputs are not convertible to integers.\0a\0afunction bint.__shl(x, y)\0a\0a x, y = bint_new(x), bint_assert_tointeger(y)\0a\0a if y == math_mininteger or math_abs(y) >= BINT_BITS then\0a\0a return bint_zero()\0a\0a end\0a\0a if y < 0 then\0a\0a return x >> -y\0a\0a end\0a\0a local nvals = y // BINT_WORDBITS\0a\0a if nvals ~= 0 then\0a\0a x:_shlwords(nvals)\0a\0a y = y - nvals * BINT_WORDBITS\0a\0a end\0a\0a if y ~= 0 then\0a\0a local wordbitsmy = BINT_WORDBITS - y\0a\0a for i=BINT_SIZE,2,-1 do\0a\0a x[i] = ((x[i] << y) | (x[i-1] >> wordbitsmy)) & BINT_WORDMAX\0a\0a end\0a\0a x[1] = (x[1] << y) & BINT_WORDMAX\0a\0a end\0a\0a return x\0a\0aend\0a\0a\0a\0a--- Bitwise right shift integers considering bints.\0a\0a-- @param x An integer to perform the bitwise shift.\0a\0a-- @param y An integer with the number of bits to shift.\0a\0a-- @return The result of shift operation, a bint.\0a\0a-- @raise Asserts in case inputs are not convertible to integers.\0a\0afunction bint.__shr(x, y)\0a\0a x, y = bint_new(x), bint_assert_tointeger(y)\0a\0a if y == math_mininteger or math_abs(y) >= BINT_BITS then\0a\0a return bint_zero()\0a\0a end\0a\0a if y < 0 then\0a\0a return x << -y\0a\0a end\0a\0a local nvals = y // BINT_WORDBITS\0a\0a if nvals ~= 0 then\0a\0a x:_shrwords(nvals)\0a\0a y = y - nvals * BINT_WORDBITS\0a\0a end\0a\0a if y ~= 0 then\0a\0a local wordbitsmy = BINT_WORDBITS - y\0a\0a for i=1,BINT_SIZE-1 do\0a\0a x[i] = ((x[i] >> y) | (x[i+1] << wordbitsmy)) & BINT_WORDMAX\0a\0a end\0a\0a x[BINT_SIZE] = x[BINT_SIZE] >> y\0a\0a end\0a\0a return x\0a\0aend\0a\0a\0a\0a--- Bitwise AND bints (in-place).\0a\0a-- @param y An integer to perform bitwise AND.\0a\0a-- @raise Asserts in case inputs are not convertible to integers.\0a\0afunction bint:_band(y)\0a\0a y = bint_assert_convert(y)\0a\0a for i=1,BINT_SIZE do\0a\0a self[i] = self[i] & y[i]\0a\0a end\0a\0a return self\0a\0aend\0a\0a\0a\0a--- Bitwise AND two integers considering bints.\0a\0a-- @param x An integer to perform bitwise AND.\0a\0a-- @param y An integer to perform bitwise AND.\0a\0a-- @raise Asserts in case inputs are not convertible to integers.\0a\0afunction bint.__band(x, y)\0a\0a return bint_new(x):_band(y)\0a\0aend\0a\0a\0a\0a--- Bitwise OR bints (in-place).\0a\0a-- @param y An integer to perform bitwise OR.\0a\0a-- @raise Asserts in case inputs are not convertible to integers.\0a\0afunction bint:_bor(y)\0a\0a y = bint_assert_convert(y)\0a\0a for i=1,BINT_SIZE do\0a\0a self[i] = self[i] | y[i]\0a\0a end\0a\0a return self\0a\0aend\0a\0a\0a\0a--- Bitwise OR two integers considering bints.\0a\0a-- @param x An integer to perform bitwise OR.\0a\0a-- @param y An integer to perform bitwise OR.\0a\0a-- @raise Asserts in case inputs are not convertible to integers.\0a\0afunction bint.__bor(x, y)\0a\0a return bint_new(x):_bor(y)\0a\0aend\0a\0a\0a\0a--- Bitwise XOR bints (in-place).\0a\0a-- @param y An integer to perform bitwise XOR.\0a\0a-- @raise Asserts in case inputs are not convertible to integers.\0a\0afunction bint:_bxor(y)\0a\0a y = bint_assert_convert(y)\0a\0a for i=1,BINT_SIZE do\0a\0a self[i] = self[i] ~ y[i]\0a\0a end\0a\0a return self\0a\0aend\0a\0a\0a\0a--- Bitwise XOR two integers considering bints.\0a\0a-- @param x An integer to perform bitwise XOR.\0a\0a-- @param y An integer to perform bitwise XOR.\0a\0a-- @raise Asserts in case inputs are not convertible to integers.\0a\0afunction bint.__bxor(x, y)\0a\0a return bint_new(x):_bxor(y)\0a\0aend\0a\0a\0a\0a--- Bitwise NOT a bint (in-place).\0a\0afunction bint:_bnot()\0a\0a for i=1,BINT_SIZE do\0a\0a self[i] = (~self[i]) & BINT_WORDMAX\0a\0a end\0a\0a return self\0a\0aend\0a\0a\0a\0a--- Bitwise NOT a bint.\0a\0a-- @param x An integer to perform bitwise NOT.\0a\0a-- @raise Asserts in case inputs are not convertible to integers.\0a\0afunction bint.__bnot(x)\0a\0a local y = setmetatable({}, bint)\0a\0a for i=1,BINT_SIZE do\0a\0a y[i] = (~x[i]) & BINT_WORDMAX\0a\0a end\0a\0a return y\0a\0aend\0a\0a\0a\0a--- Negate a bint (in-place). This effectively applies two's complements.\0a\0afunction bint:_unm()\0a\0a return self:_bnot():_inc()\0a\0aend\0a\0a\0a\0a--- Negate a bint. This effectively applies two's complements.\0a\0a-- @param x A bint to perform negation.\0a\0afunction bint.__unm(x)\0a\0a return (~x):_inc()\0a\0aend\0a\0a\0a\0a--- Compare if integer x is less than y considering bints (unsigned version).\0a\0a-- @param x Left integer to compare.\0a\0a-- @param y Right integer to compare.\0a\0a-- @raise Asserts in case inputs are not convertible to integers.\0a\0a-- @see bint.__lt\0a\0afunction bint.ult(x, y)\0a\0a x, y = bint_assert_convert(x), bint_assert_convert(y)\0a\0a for i=BINT_SIZE,1,-1 do\0a\0a local a, b = x[i], y[i]\0a\0a if a ~= b then\0a\0a return a < b\0a\0a end\0a\0a end\0a\0a return false\0a\0aend\0a\0a\0a\0a--- Compare if bint x is less or equal than y considering bints (unsigned version).\0a\0a-- @param x Left integer to compare.\0a\0a-- @param y Right integer to compare.\0a\0a-- @raise Asserts in case inputs are not convertible to integers.\0a\0a-- @see bint.__le\0a\0afunction bint.ule(x, y)\0a\0a x, y = bint_assert_convert(x), bint_assert_convert(y)\0a\0a for i=BINT_SIZE,1,-1 do\0a\0a local a, b = x[i], y[i]\0a\0a if a ~= b then\0a\0a return a < b\0a\0a end\0a\0a end\0a\0a return true\0a\0aend\0a\0a\0a\0a--- Compare if number x is less than y considering bints and signs.\0a\0a-- @param x Left value to compare, a bint or lua number.\0a\0a-- @param y Right value to compare, a bint or lua number.\0a\0a-- @see bint.ult\0a\0afunction bint.__lt(x, y)\0a\0a local ix, iy = tobint(x), tobint(y)\0a\0a if ix and iy then\0a\0a local xneg = ix[BINT_SIZE] & BINT_WORDMSB ~= 0\0a\0a local yneg = iy[BINT_SIZE] & BINT_WORDMSB ~= 0\0a\0a if xneg == yneg then\0a\0a for i=BINT_SIZE,1,-1 do\0a\0a local a, b = ix[i], iy[i]\0a\0a if a ~= b then\0a\0a return a < b\0a\0a end\0a\0a end\0a\0a return false\0a\0a end\0a\0a return xneg and not yneg\0a\0a end\0a\0a return bint_tonumber(x) < bint_tonumber(y)\0a\0aend\0a\0a\0a\0a--- Compare if number x is less or equal than y considering bints and signs.\0a\0a-- @param x Left value to compare, a bint or lua number.\0a\0a-- @param y Right value to compare, a bint or lua number.\0a\0a-- @see bint.ule\0a\0afunction bint.__le(x, y)\0a\0a local ix, iy = tobint(x), tobint(y)\0a\0a if ix and iy then\0a\0a local xneg = ix[BINT_SIZE] & BINT_WORDMSB ~= 0\0a\0a local yneg = iy[BINT_SIZE] & BINT_WORDMSB ~= 0\0a\0a if xneg == yneg then\0a\0a for i=BINT_SIZE,1,-1 do\0a\0a local a, b = ix[i], iy[i]\0a\0a if a ~= b then\0a\0a return a < b\0a\0a end\0a\0a end\0a\0a return true\0a\0a end\0a\0a return xneg and not yneg\0a\0a end\0a\0a return bint_tonumber(x) <= bint_tonumber(y)\0a\0aend\0a\0a\0a\0a--- Convert a bint to a string on base 10.\0a\0a-- @see bint.tobase\0a\0afunction bint:__tostring()\0a\0a return self:tobase(10)\0a\0aend\0a\0a\0a\0a-- Allow creating bints by calling bint itself\0a\0asetmetatable(bint, {\0a\0a __call = function(_, x)\0a\0a return bint_new(x)\0a\0a end\0a\0a})\0a\0a\0a\0aBINT_MATHMININTEGER, BINT_MATHMAXINTEGER = bint_new(math.mininteger), bint_new(math.maxinteger)\0a\0aBINT_MININTEGER = bint.mininteger()\0a\0amemo[memoindex] = bint\0a\0a\0a\0areturn bint\0a\0a\0a\0aend\0a\0a\0a\0areturn newmodule")
(data $.rodata.3 (;3;) (i64.const 72048) "local N = 624\0a\0alocal M = 397\0a\0alocal MATRIX_A = 0x9908b0df\0a\0alocal UPPER_MASK = 0x80000000\0a\0alocal LOWER_MASK = 0x7fffffff\0a\0a\0a\0a-- initializes mt[N] with a seed\0a\0alocal function init_genrand(o, s)\0a\0a o.mt[0] = s & 0xffffffff\0a\0a for i = 1, N - 1 do\0a\0a o.mt[i] = (1812433253 * (o.mt[i - 1] ~ (o.mt[i - 1] >> 30))) + i\0a\0a -- See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier.\0a\0a -- In the previous versions, MSBs of the seed affect\0a\0a -- only MSBs of the array mt[].\0a\0a -- 2002/01/09 modified by Makoto Matsumoto\0a\0a o.mt[i] = o.mt[i] & 0xffffffff\0a\0a -- for >32 bit machines\0a\0a end\0a\0a o.mti = N\0a\0aend\0a\0a\0a\0a-- generates a random number on [0,0xffffffff]-interval\0a\0alocal function genrand_int32(o)\0a\0a local y\0a\0a local mag01 = {} -- mag01[x] = x * MATRIX_A for x=0,1\0a\0a mag01[0] = 0x0\0a\0a mag01[1] = MATRIX_A\0a\0a if o.mti >= N then -- generate N words at one time\0a\0a if o.mti == N + 1 then -- if init_genrand() has not been called,\0a\0a init_genrand(o, 5489) -- a default initial seed is used\0a\0a end\0a\0a for kk = 0, N - M - 1 do\0a\0a y = (o.mt[kk] & UPPER_MASK) | (o.mt[kk + 1] & LOWER_MASK)\0a\0a o.mt[kk] = o.mt[kk + M] ~ (y >> 1) ~ mag01[y & 0x1]\0a\0a end\0a\0a for kk = N - M, N - 2 do\0a\0a y = (o.mt[kk] & UPPER_MASK) | (o.mt[kk + 1] & LOWER_MASK)\0a\0a o.mt[kk] = o.mt[kk + (M - N)] ~ (y >> 1) ~ mag01[y & 0x1]\0a\0a end\0a\0a y = (o.mt[N - 1] & UPPER_MASK) | (o.mt[0] & LOWER_MASK)\0a\0a o.mt[N - 1] = o.mt[M - 1] ~ (y >> 1) ~ mag01[y & 0x1]\0a\0a\0a\0a o.mti = 0\0a\0a end\0a\0a\0a\0a y = o.mt[o.mti]\0a\0a o.mti = o.mti + 1\0a\0a\0a\0a -- Tempering\0a\0a y = y ~ (y >> 11)\0a\0a y = y ~ ((y << 7) & 0x9d2c5680)\0a\0a y = y ~ ((y << 15) & 0xefc60000)\0a\0a y = y ~ (y >> 18)\0a\0a\0a\0a return y\0a\0aend\0a\0a\0a\0alocal MersenneTwister = {}\0a\0aMersenneTwister.mt = {}\0a\0aMersenneTwister.mti = N + 1\0a\0a\0a\0a\0a\0alocal Random = {}\0a\0a\0a\0a-- set new random seed\0a\0afunction Random.seed(seed)\0a\0a init_genrand(MersenneTwister, seed)\0a\0aend\0a\0a\0a\0a-- generates a random number on [0,1)-real-interval\0a\0afunction Random.random()\0a\0a return genrand_int32(MersenneTwister) * (1.0 / 4294967296.0)\0a\0aend\0a\0a\0a\0a--[[\0a\0areturn a random integer\0a\0aNOTE the min and max are INCLUDED in the range.\0a\0athe max integer in lua is math.maxinteger\0a\0athe min is math.mininteger\0a\0a]]\0a\0afunction Random.integer(min, max)\0a\0a assert(max >= min, \22max must bigger than min\22)\0a\0a return math.floor(Random.random() * (max - min + 1) + min)\0a\0aend\0a\0a\0a\0areturn Random\00\00\00\00-- default handler for aos\0a\0areturn function (insertInbox)\0a\0a return function (msg)\0a\0a -- Add Message to Inbox\0a\0a insertInbox(msg)\0a\0a\0a\0a local txt = Colors.gray .. \22New Message From \22 .. Colors.green .. \0a\0a (msg.From and (msg.From:sub(1,3) .. \22...\22 .. msg.From:sub(-3)) or \22unknown\22) .. Colors.gray .. \22: \22\0a\0a if msg.Action then\0a\0a txt = txt .. Colors.gray .. (msg.Action and (\22Action = \22 .. Colors.blue .. msg.Action:sub(1,20)) or \22\22) .. Colors.reset\0a\0a else\0a\0a local data = msg.Data\0a\0a if type(data) == 'table' then\0a\0a data = require('json').encode(data)\0a\0a end\0a\0a txt = txt .. Colors.gray .. \22Data = \22 .. Colors.blue .. (data and data:sub(1,20) or \22\22) .. Colors.reset\0a\0a end\0a\0a -- Print to Output\0a\0a print(txt)\0a\0a end\0a\0a\0a\0aend")
(data $.rodata.4 (;4;) (i64.const 75328) "--\0a\0a-- Copyright (C) 2018 Masatoshi Teruya\0a\0a--\0a\0a-- Permission is hereby granted, free of charge, to any person obtaining a copy\0a\0a-- of this software and associated documentation files (the \22Software\22), to deal\0a\0a-- in the Software without restriction, including without limitation the rights\0a\0a-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\0a\0a-- copies of the Software, and to permit persons to whom the Software is\0a\0a-- furnished to do so, subject to the following conditions:\0a\0a--\0a\0a-- The above copyright notice and this permission notice shall be included in\0a\0a-- all copies or substantial portions of the Software.\0a\0a--\0a\0a-- THE SOFTWARE IS PROVIDED \22AS IS\22, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\0a\0a-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\0a\0a-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\0a\0a-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\0a\0a-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\0a\0a-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\0a\0a-- THE SOFTWARE.\0a\0a--\0a\0a-- dump.lua\0a\0a-- lua-dump\0a\0a-- Created by Masatoshi Teruya on 18/04/22.\0a\0a--\0a\0a--- file-scope variables\0a\0alocal type = type\0a\0alocal floor = math.floor\0a\0alocal tostring = tostring\0a\0alocal tblsort = table.sort\0a\0alocal tblconcat = table.concat\0a\0alocal strmatch = string.match\0a\0alocal strformat = string.format\0a\0a--- constants\0a\0alocal INFINITE_POS = math.huge\0a\0alocal LUA_FIELDNAME_PAT = '^[a-zA-Z_][a-zA-Z0-9_]*$'\0a\0alocal FOR_KEY = 'key'\0a\0alocal FOR_VAL = 'val'\0a\0alocal FOR_CIRCULAR = 'circular'\0a\0alocal RESERVED_WORD = {\0a\0a -- primitive data\0a\0a ['nil'] = true,\0a\0a ['true'] = true,\0a\0a ['false'] = true,\0a\0a -- declaraton\0a\0a ['local'] = true,\0a\0a ['function'] = true,\0a\0a -- boolean logic\0a\0a ['and'] = true,\0a\0a ['or'] = true,\0a\0a ['not'] = true,\0a\0a -- conditional statement\0a\0a ['if'] = true,\0a\0a ['elseif'] = true,\0a\0a ['else'] = true,\0a\0a -- iteration statement\0a\0a ['for'] = true,\0a\0a ['in'] = true,\0a\0a ['while'] = true,\0a\0a ['until'] = true,\0a\0a ['repeat'] = true,\0a\0a -- jump statement\0a\0a ['break'] = true,\0a\0a ['goto'] = true,\0a\0a ['return'] = true,\0a\0a -- block scope statement\0a\0a ['then'] = true,\0a\0a ['do'] = true,\0a\0a ['end'] = true,\0a\0a}\0a\0alocal DEFAULT_INDENT = 4\0a\0a\0a\0a--- filter function for dump\0a\0a--- @param val any\0a\0a--- @param depth integer\0a\0a--- @param vtype string\0a\0a--- @param use string\0a\0a--- @param key any\0a\0a--- @param udata any\0a\0a--- @return any val\0a\0a--- @return boolean nodump\0a\0alocal function DEFAULT_FILTER(val)\0a\0a return val\0a\0aend\0a\0a\0a\0a--- sort_index\0a\0a--- @param a table\0a\0a--- @param b table\0a\0alocal function sort_index(a, b)\0a\0a if a.typ == b.typ then\0a\0a if a.typ == 'boolean' then\0a\0a return b.key\0a\0a end\0a\0a\0a\0a return a.key < b.key\0a\0a end\0a\0a\0a\0a return a.typ == 'number'\0a\0aend\0a\0a\0a\0a--- dumptbl\0a\0a--- @param tbl table\0a\0a--- @param depth integer\0a\0a--- @param indent string\0a\0a--- @param nestIndent string\0a\0a--- @param ctx table\0a\0a--- @return string\0a\0alocal function dumptbl(tbl, depth, indent, nestIndent, ctx)\0a\0a local ref = tostring(tbl)\0a\0a\0a\0a -- circular reference\0a\0a if ctx.circular[ref] then\0a\0a local val, nodump = ctx.filter(tbl, depth, type(tbl), FOR_CIRCULAR, tbl,\0a\0a ctx.udata)\0a\0a\0a\0a if val ~= nil and val ~= tbl then\0a\0a local t = type(val)\0a\0a\0a\0a if t == 'table' then\0a\0a -- dump table value\0a\0a if not nodump then\0a\0a return dumptbl(val, depth + 1, indent, nestIndent, ctx)\0a\0a end\0a\0a return tostring(val)\0a\0a elseif t == 'string' then\0a\0a return strformat('%q', val)\0a\0a elseif t == 'number' or t == 'boolean' then\0a\0a return tostring(val)\0a\0a end\0a\0a\0a\0a return strformat('%q', tostring(val))\0a\0a end\0a\0a\0a\0a return '\22<Circular ' .. ref .. '>\22'\0a\0a end\0a\0a\0a\0a local res = {}\0a\0a local arr = {}\0a\0a local narr = 0\0a\0a local fieldIndent = indent .. nestIndent\0a\0a\0a\0a -- save reference\0a\0a ctx.circular[ref] = true\0a\0a\0a\0a for k, v in pairs(tbl) do\0a\0a -- check key\0a\0a local key, nokdump = ctx.filter(k, depth, type(k), FOR_KEY, nil,\0a\0a ctx.udata)\0a\0a\0a\0a if key ~= nil then\0a\0a -- check val\0a\0a local val, novdump = ctx.filter(v, depth, type(v), FOR_VAL, key,\0a\0a ctx.udata)\0a\0a local kv\0a\0a\0a\0a if val ~= nil then\0a\0a local kt = type(key)\0a\0a local vt = type(val)\0a\0a\0a\0a -- convert key to suitable to be safely read back\0a\0a -- by the Lua interpreter\0a\0a if kt == 'number' or kt == 'boolean' then\0a\0a k = key\0a\0a key = '[' .. tostring(key) .. ']'\0a\0a -- dump table value\0a\0a elseif kt == 'table' and not nokdump then\0a\0a key = '[' ..\0a\0a dumptbl(key, depth + 1, fieldIndent, nestIndent,\0a\0a ctx) .. ']'\0a\0a k = key\0a\0a kt = 'string'\0a\0a elseif kt ~= 'string' or RESERVED_WORD[key] or\0a\0a not strmatch(key, LUA_FIELDNAME_PAT) then\0a\0a key = strformat(\22[%q]\22, tostring(key), v)\0a\0a k = key\0a\0a kt = 'string'\0a\0a end\0a\0a\0a\0a -- convert key-val pair to suitable to be safely read back\0a\0a -- by the Lua interpreter\0a\0a if vt == 'number' or vt == 'boolean' then\0a\0a kv = strformat('%s%s = %s', fieldIndent, key, tostring(val))\0a\0a elseif vt == 'string' then\0a\0a -- dump a string-value\0a\0a if not novdump then\0a\0a kv = strformat('%s%s = %q', fieldIndent, key, val)\0a\0a else\0a\0a kv = strformat('%s%s = %s', fieldIndent, key, val)\0a\0a end\0a\0a elseif vt == 'table' and not novdump then\0a\0a kv = strformat('%s%s = %s', fieldIndent, key, dumptbl(val,\0a\0a depth +\0a\0a 1,\0a\0a fieldIndent,\0a\0a nestIndent,\0a\0a ctx))\0a\0a else\0a\0a kv = strformat('%s%s = %q', fieldIndent, key, tostring(val))\0a\0a end\0a\0a\0a\0a -- add to array\0a\0a narr = narr + 1\0a\0a arr[narr] = {\0a\0a typ = kt,\0a\0a key = k,\0a\0a val = kv,\0a\0a }\0a\0a end\0a\0a end\0a\0a end\0a\0a\0a\0a -- remove reference\0a\0a ctx.circular[ref] = nil\0a\0a -- concat result\0a\0a if narr > 0 then\0a\0a tblsort(arr, sort_index)\0a\0a\0a\0a for i = 1, narr do\0a\0a res[i] = arr[i].val\0a\0a end\0a\0a res[1] = '{' .. ctx.LF .. res[1]\0a\0a res = tblconcat(res, ',' .. ctx.LF) .. ctx.LF .. indent .. '}'\0a\0a else\0a\0a res = '{}'\0a\0a end\0a\0a\0a\0a return res\0a\0aend\0a\0a\0a\0a--- is_uint\0a\0a--- @param v any\0a\0a--- @return boolean ok\0a\0alocal function is_uint(v)\0a\0a return type(v) == 'number' and v < INFINITE_POS and v >= 0 and floor(v) == v\0a\0aend\0a\0a\0a\0a--- dump\0a\0a--- @param val any\0a\0a--- @param indent integer\0a\0a--- @param padding integer\0a\0a--- @param filter function\0a\0a--- @param udata\0a\0a--- @return string\0a\0alocal function dump(val, indent, padding, filter, udata)\0a\0a local t = type(val)\0a\0a\0a\0a -- check indent\0a\0a if indent == nil then\0a\0a indent = DEFAULT_INDENT\0a\0a elseif not is_uint(indent) then\0a\0a error('indent must be unsigned integer', 2)\0a\0a end\0a\0a\0a\0a -- check padding\0a\0a if padding == nil then\0a\0a padding = 0\0a\0a elseif not is_uint(padding) then\0a\0a error('padding must be unsigned integer', 2)\0a\0a end\0a\0a\0a\0a -- check filter\0a\0a if filter == nil then\0a\0a filter = DEFAULT_FILTER\0a\0a elseif type(filter) ~= 'function' then\0a\0a error('filter must be function', 2)\0a\0a end\0a\0a\0a\0a -- dump table\0a\0a if t == 'table' then\0a\0a local ispace = ''\0a\0a local pspace = ''\0a\0a\0a\0a if indent > 0 then\0a\0a ispace = strformat('%' .. tostring(indent) .. 's', '')\0a\0a end\0a\0a\0a\0a if padding > 0 then\0a\0a pspace = strformat('%' .. tostring(padding) .. 's', '')\0a\0a end\0a\0a\0a\0a return dumptbl(val, 1, pspace, ispace, {\0a\0a LF = ispace == '' and ' ' or '\5cn',\0a\0a circular = {},\0a\0a filter = filter,\0a\0a udata = udata,\0a\0a })\0a\0a end\0a\0a\0a\0a -- dump value\0a\0a local v, nodump = filter(val, 0, t, FOR_VAL, nil, udata)\0a\0a if nodump == true then\0a\0a return tostring(v)\0a\0a end\0a\0a return strformat('%q', tostring(v))\0a\0aend\0a\0a\0a\0areturn dump")
(data $.rodata.5 (;5;) (i64.const 84432) "local stringify = require(\22.stringify\22)\0a\0a-- handler for eval\0a\0areturn function (ao)\0a\0a return function (msg)\0a\0a -- exec expression\0a\0a local expr = msg.Data\0a\0a local func, err = load(\22return \22 .. expr, 'aos', 't', _G)\0a\0a local output = \22\22\0a\0a local e = nil\0a\0a if err then\0a\0a func, err = load(expr, 'aos', 't', _G)\0a\0a end\0a\0a if func then\0a\0a output, e = func()\0a\0a else\0a\0a ao.outbox.Error = err\0a\0a return\0a\0a end\0a\0a if e then \0a\0a ao.outbox.Error = e\0a\0a return \0a\0a end\0a\0a -- set result in outbox.Output \0a\0a ao.outbox.Output = { data = { \0a\0a json = type(output) == \22table\22 and pcall(function () return json.encode(output) end) and output or \22undefined\22,\0a\0a output = type(output) == \22table\22 and stringify.format(output) or output, \0a\0a prompt = Prompt() \0a\0a }}\0a\0a end \0a\0aend\0a\00\00\00local _utils = { _version = \220.0.1\22 }\0a\0a\0a\0alocal _ = require('.utils')\0a\0alocal ao = require(\22ao\22)\0a\0a\0a\0afunction _utils.hasMatchingTag(name, value)\0a\0a assert(type(name) == 'string' and type(value) == 'string', 'invalid arguments: (name : string, value : string)')\0a\0a\0a\0a return function (msg) \0a\0a return msg.Tags[name] == value \0a\0a end\0a\0aend\0a\0a\0a\0afunction _utils.hasMatchingTagOf(name, values)\0a\0a assert(type(name) == 'string' and type(values) == 'table', 'invalid arguments: (name : string, values : string[])')\0a\0a return function (msg)\0a\0a for _, value in ipairs(values) do\0a\0a local patternResult = Handlers.utils.hasMatchingTag(name, value)(msg)\0a\0a\0a\0a if patternResult ~= 0 and patternResult ~= false and patternResult ~= \22skip\22 then\0a\0a return patternResult\0a\0a end\0a\0a end\0a\0a\0a\0a return 0\0a\0a end\0a\0aend\0a\0a\0a\0afunction _utils.hasMatchingData(value)\0a\0a assert(type(value) == 'string', 'invalid arguments: (value : string)')\0a\0a return function (msg)\0a\0a return msg.Data == value\0a\0a end\0a\0aend\0a\0a\0a\0afunction _utils.reply(input) \0a\0a assert(type(input) == 'table' or type(input) == 'string', 'invalid arguments: (input : table or string)')\0a\0a return function (msg)\0a\0a if type(input) == 'string' then\0a\0a ao.send({Target = msg.From, Data = input})\0a\0a return\0a\0a end\0a\0a ao.send({Target = msg.From, Tags = input })\0a\0a end\0a\0aend\0a\0a\0a\0afunction _utils.continue(fn)\0a\0a assert(type(fn) == 'function', 'invalid arguments: (fn : function)')\0a\0a return function (msg)\0a\0a local patternResult = fn(msg)\0a\0a\0a\0a if not patternResult or patternResult == 0 or patternResult == \22skip\22 then\0a\0a return patternResult\0a\0a end\0a\0a return 1\0a\0a end\0a\0aend\0a\0a\0a\0areturn _utils\00\00\00\00local handlers = { _version = \220.0.3\22 }\0a\0a\0a\0ahandlers.utils = require('.handlers-utils')\0a\0ahandlers.list = {}\0a\0a\0a\0alocal function findIndexByProp(array, prop, value)\0a\0a for index, object in ipairs(array) do\0a\0a if object[prop] == value then\0a\0a return index\0a\0a end\0a\0a end\0a\0a return nil\0a\0aend\0a\0a\0a\0afunction handlers.add(name, pattern, handle)\0a\0a assert(type(name) == 'string' and type(pattern) == 'function' and type(handle) == 'function', 'invalid arguments: handler.add(name : string, pattern : function(msg: Message) : {-1 = break, 0 = skip, 1 = continue}, handle(msg : Message) : void)') \0a\0a assert(type(name) == 'string', 'name MUST be string')\0a\0a assert(type(pattern) == 'function', 'pattern MUST be function')\0a\0a assert(type(handle) == 'function', 'handle MUST be function')\0a\0a \0a\0a \0a\0a -- update existing handler by name\0a\0a local idx = findIndexByProp(handlers.list, \22name\22, name)\0a\0a if idx ~= nil and idx > 0 then\0a\0a -- found update\0a\0a handlers.list[idx].pattern = pattern\0a\0a handlers.list[idx].handle = handle\0a\0a else\0a\0a -- not found then add \0a\0a table.insert(handlers.list, { pattern = pattern, handle = handle, name = name })\0a\0a\0a\0a end\0a\0aend\0a\0a\0a\0a\0a\0afunction handlers.append(name, pattern, handle)\0a\0a assert(type(name) == 'string' and type(pattern) == 'function' and type(handle) == 'function', 'invalid arguments: handler.append(name : string, pattern : function(msg: Message) : {-1 = break, 0 = skip, 1 = continue}, handle(msg : Message) : void)') \0a\0a assert(type(name) == 'string', 'name MUST be string')\0a\0a assert(type(pattern) == 'function', 'pattern MUST be function')\0a\0a assert(type(handle) == 'function', 'handle MUST be function')\0a\0a \0a\0a -- update existing handler by name\0a\0a local idx = findIndexByProp(handlers.list, \22name\22, name)\0a\0a if idx ~= nil and idx > 0 then\0a\0a -- found update\0a\0a handlers.list[idx].pattern = pattern\0a\0a handlers.list[idx].handle = handle\0a\0a else\0a\0a \0a\0a table.insert(handlers.list, { pattern = pattern, handle = handle, name = name })\0a\0a end\0a\0a\0a\0a \0a\0aend\0a\0a\0a\0afunction handlers.prepend(name, pattern, handle) \0a\0a assert(type(name) == 'string' and type(pattern) == 'function' and type(handle) == 'function', 'invalid arguments: handler.prepend(name : string, pattern : function(msg: Message) : {-1 = break, 0 = skip, 1 = continue}, handle(msg : Message) : void)') \0a\0a assert(type(name) == 'string', 'name MUST be string')\0a\0a assert(type(pattern) == 'function', 'pattern MUST be function')\0a\0a assert(type(handle) == 'function', 'handle MUST be function')\0a\0a \0a\0a\0a\0a -- update existing handler by name\0a\0a local idx = findIndexByProp(handlers.list, \22name\22, name)\0a\0a if idx ~= nil and idx > 0 then\0a\0a -- found update\0a\0a handlers.list[idx].pattern = pattern\0a\0a handlers.list[idx].handle = handle\0a\0a else \0a\0a table.insert(handlers.list, 1, { pattern = pattern, handle = handle, name = name })\0a\0a end\0a\0a\0a\0a \0a\0aend\0a\0a\0a\0afunction handlers.before(handleName)\0a\0a assert(handleName ~= nil, 'invalid arguments: handlers.before(name : string) : { add = function(name, pattern, handler)}')\0a\0a assert(type(handleName) == 'string', 'name MUST be string')\0a\0a\0a\0a local idx = findIndexByProp(handlers.list, \22name\22, handleName)\0a\0a return {\0a\0a add = function (name, pattern, handle) \0a\0a assert(type(name) == 'string' and type(pattern) == 'function' and type(handle) == 'function', 'invalid arguments: handler.before(\22foo\22).add(name : string, pattern : function(msg: Message) : {-1 = break, 0 = skip, 1 = continue}, handle(msg : Message) : void)') \0a\0a assert(type(name) == 'string', 'name MUST be string')\0a\0a \0a\0a assert(type(pattern) == 'function', 'pattern MUST be function')\0a\0a assert(type(handle) == 'function', 'handle MUST be function')\0a\0a \0a\0a if idx then\0a\0a table.insert(handlers.list, idx, { pattern = pattern, handle = handle, name = name })\0a\0a end\0a\0a \0a\0a end\0a\0a }\0a\0aend\0a\0a\0a\0afunction handlers.after(handleName)\0a\0a assert(handleName ~= nil, 'invalid arguments: handlers.after(name : string) : { add = function(name, pattern, handler)}')\0a\0a assert(type(handleName) == 'string', 'name MUST be string')\0a\0a local idx = findIndexByProp(handlers.list, \22name\22, handleName)\0a\0a return { \0a\0a add = function (name, pattern, handle)\0a\0a assert(type(name) == 'string' and type(pattern) == 'function' and type(handle) == 'function', 'invalid arguments: handler.after(\22foo\22).add(name : string, pattern : function(msg: Message) : {-1 = break, 0 = skip, 1 = continue}, handle(msg : Message) : void)') \0a\0a\0a\0a assert(type(name) == 'string', 'name MUST be string')\0a\0a assert(type(pattern) == 'function', 'pattern MUST be function')\0a\0a assert(type(handle) == 'function', 'handle MUST be function')\0a\0a \0a\0a if idx then\0a\0a table.insert(handlers.list, idx + 1, { pattern = pattern, handle = handle, name = name })\0a\0a end\0a\0a \0a\0a end\0a\0a }\0a\0a\0a\0aend\0a\0a\0a\0afunction handlers.remove(name)\0a\0a assert(type(name) == 'string', 'name MUST be string')\0a\0a if #handlers.list == 1 and handlers.list[1].name == name then\0a\0a handlers.list = {}\0a\0a \0a\0a end\0a\0a\0a\0a local idx = findIndexByProp(handlers.list, \22name\22, name)\0a\0a table.remove(handlers.list, idx)\0a\0a \0a\0aend\0a\0a\0a\0a--- return 0 to not call handler, -1 to break after handler is called, 1 to continue\0a\0afunction handlers.evaluate(msg, env)\0a\0a local handled = false\0a\0a assert(type(msg) == 'table', 'msg is not valid')\0a\0a assert(type(env) == 'table', 'env is not valid')\0a\0a \0a\0a for _, o in ipairs(handlers.list) do\0a\0a if o.name ~= \22_default\22 then\0a\0a local match = o.pattern(msg)\0a\0a if not (type(match) == 'number' or type(match) == 'string' or type(match) == 'boolean') then\0a\0a error({message = \22pattern result is not valid, it MUST be string, number, or boolean\22})\0a\0a end\0a\0a \0a\0a -- handle boolean returns\0a\0a if type(match) == \22boolean\22 and match == true then\0a\0a match = -1\0a\0a elseif type(match) == \22boolean\22 and match == false then\0a\0a match = 0\0a\0a end\0a\0a\0a\0a -- handle string returns\0a\0a if type(match) == \22string\22 then\0a\0a if match == \22continue\22 then\0a\0a match = 1\0a\0a elseif match == \22break\22 then\0a\0a match = -1\0a\0a else\0a\0a match = 0\0a\0a end\0a\0a end\0a\0a\0a\0a if match ~= 0 then\0a\0a if match < 0 then\0a\0a handled = true\0a\0a end\0a\0a -- each handle function can accept, the msg, env\0a\0a local status, err = pcall(o.handle, msg, env) \0a\0a if not status then\0a\0a error(err)\0a\0a ao.outbox.Error = { err = err }\0a\0a\0a\0a end\0a\0a \0a\0a end\0a\0a if match < 0 then\0a\0a return handled\0a\0a end\0a\0a end\0a\0a end\0a\0a -- do default\0a\0a if not handled then\0a\0a local idx = findIndexByProp(handlers.list, \22name\22, \22_default\22)\0a\0a handlers.list[idx].handle(msg,env)\0a\0a end\0a\0aend\0a\0a\0a\0areturn handlers\00\00\00local pretty = { _version = \220.0.1\22}\0a\0a\0a\0afunction pretty.tprint (tbl, indent) \0a\0a if not indent then indent = 0 end\0a\0a local output = \22\22\0a\0a for k, v in pairs(tbl) do\0a\0a local formatting = string.rep(\22 \22, indent) .. k .. \22: \22\0a\0a if type(v) == \22table\22 then\0a\0a output = output .. formatting .. \22\5cn\22\0a\0a output = output .. pretty.tprint(v, indent+1)\0a\0a elseif type(v) == 'boolean' then\0a\0a output = output .. formatting .. tostring(v) .. \22\5cn\22\0a\0a else\0a\0a output = output .. formatting .. v .. \22\5cn\22\0a\0a end\0a\0a end\0a\0a return output\0a\0aend\0a\0a\0a\0areturn pretty\00\00\00\00\00\00\00\00local pretty = require('.pretty')\0a\0alocal base64 = require('.base64')\0a\0alocal json = require('json')\0a\0alocal chance = require('.chance')\0a\0alocal crypto = require('.crypto.init')\0a\0a\0a\0aColors = {\0a\0a red = \22\5c27[31m\22,\0a\0a green = \22\5c27[32m\22,\0a\0a blue = \22\5c27[34m\22,\0a\0a reset = \22\5c27[0m\22,\0a\0a gray = \22\5c27[90m\22\0a\0a}\0a\0a\0a\0aBell = \22\5cx07\22\0a\0a\0a\0aDump = require('.dump')\0a\0aUtils = require('.utils')\0a\0aHandlers = require('.handlers')\0a\0alocal stringify = require(\22.stringify\22)\0a\0alocal _ao = require('ao')\0a\0alocal process = { _version = \220.2.0\22 }\0a\0alocal maxInboxCount = 10000\0a\0a\0a\0a-- wrap ao.send and ao.spawn for magic table\0a\0alocal aosend = _ao.send \0a\0alocal aospawn = _ao.spawn\0a\0a_ao.send = function (msg)\0a\0a if msg.Data and type(msg.Data) == 'table' then\0a\0a msg['Content-Type'] = 'application/json'\0a\0a msg.Data = require('json').encode(msg.Data)\0a\0a end\0a\0a return aosend(msg)\0a\0aend\0a\0a_ao.spawn = function (module, msg) \0a\0a if msg.Data and type(msg.Data) == 'table' then\0a\0a msg['Content-Type'] = 'application/json'\0a\0a msg.Data = require('json').encode(msg.Data)\0a\0a end\0a\0a return aospawn(module, msg)\0a\0aend\0a\0a\0a\0alocal function insertInbox(msg)\0a\0a table.insert(Inbox, msg)\0a\0a if #Inbox > maxInboxCount then\0a\0a local overflow = #Inbox - maxInboxCount \0a\0a for i = 1,overflow do\0a\0a table.remove(Inbox, 1)\0a\0a end\0a\0a end \0a\0aend\0a\0a\0a\0alocal function findObject(array, key, value)\0a\0a for i, object in ipairs(array) do\0a\0a if object[key] == value then\0a\0a return object\0a\0a end\0a\0a end\0a\0a return nil\0a\0aend\0a\0a\0a\0afunction Tab(msg)\0a\0a local inputs = {}\0a\0a for _, o in ipairs(msg.Tags) do\0a\0a if not inputs[o.name] then\0a\0a inputs[o.name] = o.value\0a\0a end\0a\0a end\0a\0a return inputs\0a\0aend\0a\0a\0a\0afunction Prompt()\0a\0a return \22aos> \22\0a\0aend\0a\0a\0a\0afunction print(a)\0a\0a if type(a) == \22table\22 then\0a\0a a = stringify.format(a)\0a\0a end\0a\0a \0a\0a pcall(function () \0a\0a local data = a\0a\0a if _ao.outbox.Output.data then\0a\0a data = _ao.outbox.Output.data .. \22\5cn\22 .. a\0a\0a end\0a\0a _ao.outbox.Output = { data = data, prompt = Prompt(), print = true }\0a\0a end)\0a\0a\0a\0a return tostring(a)\0a\0aend\0a\0a\0a\0afunction Send(msg)\0a\0a _ao.send(msg)\0a\0a return 'message added to outbox'\0a\0aend\0a\0a\0a\0afunction Spawn(module, msg)\0a\0a if not msg then\0a\0a msg = {}\0a\0a end\0a\0a\0a\0a _ao.spawn(module, msg)\0a\0a return 'spawn process request'\0a\0aend\0a\0a\0a\0afunction Assign(assignment)\0a\0a _ao.assign(assignment)\0a\0a return 'assignment added to outbox'\0a\0aend\0a\0a\0a\0aSeeded = Seeded or false\0a\0a\0a\0a-- this is a temporary approach...\0a\0alocal function stringToSeed(s)\0a\0a local seed = 0\0a\0a for i = 1, #s do\0a\0a local char = string.byte(s, i)\0a\0a seed = seed + char\0a\0a end\0a\0a return seed\0a\0aend\0a\0a\0a\0alocal function initializeState(msg, env)\0a\0a if not Seeded then\0a\0a --math.randomseed(1234)\0a\0a chance.seed(tonumber(msg['Block-Height'] .. stringToSeed(msg.Owner .. msg.Module .. msg.Id)))\0a\0a math.random = function (...)\0a\0a local args = {...}\0a\0a local n = #args\0a\0a if n == 0 then\0a\0a return chance.random()\0a\0a end\0a\0a if n == 1 then\0a\0a return chance.integer(1, args[1])\0a\0a end\0a\0a if n == 2 then\0a\0a return chance.integer(args[1], args[2])\0a\0a end\0a\0a return chance.random()\0a\0a end\0a\0a Seeded = true\0a\0a end\0a\0a Errors = Errors or {}\0a\0a Inbox = Inbox or {}\0a\0a\0a\0a -- temporary fix for Spawn\0a\0a if not Owner then\0a\0a local _from = findObject(env.Process.Tags, \22name\22, \22From-Process\22)\0a\0a if _from then\0a\0a Owner = _from.value\0a\0a else\0a\0a Owner = msg.From\0a\0a end\0a\0a end\0a\0a\0a\0a if not Name then\0a\0a local aosName = findObject(env.Process.Tags, \22name\22, \22Name\22)\0a\0a if aosName then\0a\0a Name = aosName.value\0a\0a else\0a\0a Name = 'aos'\0a\0a end\0a\0a end\0a\0a\0a\0aend\0a\0a\0a\0afunction Version()\0a\0a print(\22version: \22 .. process._version)\0a\0aend\0a\0a\0a\0afunction process.handle(msg, ao)\0a\0a ao.id = ao.env.Process.Id\0a\0a initializeState(msg, ao.env)\0a\0a \0a\0a -- tagify msg\0a\0a msg.TagArray = msg.Tags\0a\0a msg.Tags = Tab(msg)\0a\0a -- tagify Process\0a\0a ao.env.Process.TagArray = ao.env.Process.Tags\0a\0a ao.env.Process.Tags = Tab(ao.env.Process)\0a\0a -- magic table - if Content-Type == application/json - decode msg.Data to a Table\0a\0a if msg.Tags['Content-Type'] and msg.Tags['Content-Type'] == 'application/json' then\0a\0a msg.Data = require('json').decode(msg.Data or \22{}\22)\0a\0a end\0a\0a -- init Errors\0a\0a Errors = Errors or {}\0a\0a -- clear Outbox\0a\0a ao.clearOutbox()\0a\0a\0a\0a -- Only trust messages from a signed owner or an Authority\0a\0a if msg.From ~= msg.Owner and not ao.isTrusted(msg) then\0a\0a Send({Target = msg.From, Data = \22Message is not trusted by this process!\22})\0a\0a print('Message is not trusted! From: ' .. msg.From .. ' - Owner: ' .. msg.Owner)\0a\0a return ao.result({ }) \0a\0a end\0a\0a\0a\0a\0a\0a Handlers.add(\22_eval\22, \0a\0a function (msg)\0a\0a return msg.Action == \22Eval\22 and Owner == msg.From\0a\0a end,\0a\0a require('.eval')(ao)\0a\0a )\0a\0a Handlers.append(\22_default\22, function () return true end, require('.default')(insertInbox))\0a\0a -- call evaluate from handlers passing env\0a\0a \0a\0a local status, result = pcall(Handlers.evaluate, msg, ao.env)\0a\0a \0a\0a\0a\0a if not status then\0a\0a table.insert(Errors, result)\0a\0a return { Error = result }\0a\0a -- return {\0a\0a -- Output = { \0a\0a -- data = { \0a\0a -- prompt = Prompt(), \0a\0a -- json = 'undefined', \0a\0a -- output = result \0a\0a -- }\0a\0a -- }, \0a\0a -- Messages = {}, \0a\0a -- Spawns = {}\0a\0a -- }\0a\0a end\0a\0a \0a\0a return ao.result({ })\0a\0aend\0a\0a\0a\0areturn process\0a")
(data $.rodata.6 (;6;) (i64.const 99648) "local stringify = { _version = \220.0.1\22 }\0a\0a\0a\0a-- ANSI color codes\0a\0alocal colors = {\0a\0a red = \22\5c27[31m\22,\0a\0a green = \22\5c27[32m\22,\0a\0a blue = \22\5c27[34m\22,\0a\0a reset = \22\5c27[0m\22\0a\0a}\0a\0a\0a\0afunction stringify.isSimpleArray(tbl)\0a\0a local arrayIndex = 1\0a\0a for k, v in pairs(tbl) do\0a\0a if k ~= arrayIndex or (type(v) ~= \22number\22 and type(v) ~= \22string\22) then\0a\0a return false\0a\0a end\0a\0a arrayIndex = arrayIndex + 1\0a\0a end\0a\0a return true\0a\0aend\0a\0a\0a\0afunction stringify.format(tbl, indent)\0a\0a indent = indent or 0\0a\0a local toIndent = string.rep(\22 \22, indent)\0a\0a local toIndentChild = string.rep(\22 \22, indent + 2)\0a\0a\0a\0a local result = {}\0a\0a local isArray = true\0a\0a local arrayIndex = 1\0a\0a\0a\0a if stringify.isSimpleArray(tbl) then\0a\0a for _, v in ipairs(tbl) do\0a\0a if type(v) == \22string\22 then\0a\0a v = colors.green .. '\22' .. v .. '\22' .. colors.reset\0a\0a else\0a\0a v = colors.blue .. tostring(v) .. colors.reset\0a\0a end\0a\0a table.insert(result, v)\0a\0a end\0a\0a return \22{ \22 .. table.concat(result, \22, \22) .. \22 }\22\0a\0a end\0a\0a\0a\0a for k, v in pairs(tbl) do\0a\0a if isArray then\0a\0a if k == arrayIndex then\0a\0a arrayIndex = arrayIndex + 1\0a\0a if type(v) == \22table\22 then\0a\0a v = stringify.format(v, indent + 2)\0a\0a elseif type(v) == \22string\22 then\0a\0a v = colors.green .. '\22' .. v .. '\22' .. colors.reset\0a\0a else\0a\0a v = colors.blue .. tostring(v) .. colors.reset\0a\0a end\0a\0a table.insert(result, toIndentChild .. v)\0a\0a else\0a\0a isArray = false\0a\0a result = {}\0a\0a end\0a\0a end\0a\0a if not isArray then\0a\0a if type(v) == \22table\22 then\0a\0a v = stringify.format(v, indent + 2)\0a\0a elseif type(v) == \22string\22 then\0a\0a v = colors.green .. '\22' .. v .. '\22' .. colors.reset\0a\0a else\0a\0a v = colors.blue .. tostring(v) .. colors.reset\0a\0a end\0a\0a k = colors.red .. k .. colors.reset\0a\0a table.insert(result, toIndentChild .. k .. \22 = \22 .. v)\0a\0a end\0a\0a end\0a\0a\0a\0a local prefix = isArray and \22{\5cn\22 or \22{\5cn \22\0a\0a local suffix = isArray and \22\5cn\22 .. toIndent .. \22 }\22 or \22\5cn\22 .. toIndent .. \22}\22\0a\0a local separator = isArray and \22,\5cn\22 or \22,\5cn \22\0a\0a return prefix .. table.concat(result, separator) .. suffix\0a\0aend\0a\0a\0a\0areturn stringify\0a\00\00\00\00local utils = { _version = \220.0.2\22 }\0a\0a\0a\0alocal function isArray(table)\0a\0a if type(table) == \22table\22 then\0a\0a local maxIndex = 0\0a\0a for k, v in pairs(table) do\0a\0a if type(k) ~= \22number\22 or k < 1 or math.floor(k) ~= k then\0a\0a return false -- If there's a non-integer key, it's not an array\0a\0a end\0a\0a maxIndex = math.max(maxIndex, k)\0a\0a end\0a\0a -- If the highest numeric index is equal to the number of elements, it's an array\0a\0a return maxIndex == #table\0a\0a end\0a\0a return false\0a\0aend\0a\0a\0a\0a-- @param {function} fn\0a\0a-- @param {number} arity\0a\0autils.curry = function (fn, arity)\0a\0a assert(type(fn) == \22function\22, \22function is required as first argument\22)\0a\0a arity = arity or debug.getinfo(fn, \22u\22).nparams\0a\0a if arity < 2 then return fn end\0a\0a\0a\0a return function (...)\0a\0a local args = {...}\0a\0a\0a\0a if #args >= arity then\0a\0a return fn(table.unpack(args))\0a\0a else\0a\0a return utils.curry(function (...)\0a\0a return fn(table.unpack(args), ...)\0a\0a end, arity - #args)\0a\0a end\0a\0a end\0a\0aend\0a\0a\0a\0a--- Concat two Array Tables.\0a\0a-- @param {table<Array>} a\0a\0a-- @param {table<Array>} b\0a\0autils.concat = utils.curry(function (a, b)\0a\0a assert(type(a) == \22table\22, \22first argument should be a table that is an array\22)\0a\0a assert(type(b) == \22table\22, \22second argument should be a table that is an array\22)\0a\0a assert(isArray(a), \22first argument should be a table\22)\0a\0a assert(isArray(b), \22second argument should be a table\22)\0a\0a\0a\0a local result = {}\0a\0a for i = 1, #a do\0a\0a result[#result + 1] = a[i]\0a\0a end\0a\0a for i = 1, #b do\0a\0a result[#result + 1] = b[i]\0a\0a end\0a\0a return result\0a\0aend, 2)\0a\0a\0a\0a--- reduce applies a function to a table\0a\0a-- @param {function} fn\0a\0a-- @param {any} initial\0a\0a-- @param {table<Array>} t\0a\0autils.reduce = utils.curry(function (fn, initial, t)\0a\0a assert(type(fn) == \22function\22, \22first argument should be a function that accepts (result, value, key)\22)\0a\0a assert(type(t) == \22table\22 and isArray(t), \22third argument should be a table that is an array\22)\0a\0a local result = initial\0a\0a for k, v in pairs(t) do\0a\0a if result == nil then\0a\0a result = v\0a\0a else\0a\0a result = fn(result, v, k)\0a\0a end\0a\0a end\0a\0a return result\0a\0aend, 3)\0a\0a\0a\0a-- @param {function} fn\0a\0a-- @param {table<Array>} data\0a\0autils.map = utils.curry(function (fn, data)\0a\0a assert(type(fn) == \22function\22, \22first argument should be a unary function\22)\0a\0a assert(type(data) == \22table\22 and isArray(data), \22second argument should be an Array\22)\0a\0a\0a\0a local function map (result, v, k)\0a\0a result[k] = fn(v, k)\0a\0a return result\0a\0a end\0a\0a\0a\0a return utils.reduce(map, {}, data)\0a\0aend, 2)\0a\0a\0a\0a-- @param {function} fn\0a\0a-- @param {table<Array>} data\0a\0autils.filter = utils.curry(function (fn, data)\0a\0a assert(type(fn) == \22function\22, \22first argument should be a unary function\22)\0a\0a assert(type(data) == \22table\22 and isArray(data), \22second argument should be an Array\22)\0a\0a\0a\0a local function filter (result, v, _k)\0a\0a if fn(v) then\0a\0a table.insert(result, v)\0a\0a end\0a\0a return result\0a\0a end\0a\0a\0a\0a return utils.reduce(filter,{}, data)\0a\0aend, 2)\0a\0a\0a\0a-- @param {function} fn\0a\0a-- @param {table<Array>} t\0a\0autils.find = utils.curry(function (fn, t)\0a\0a assert(type(fn) == \22function\22, \22first argument should be a unary function\22)\0a\0a assert(type(t) == \22table\22, \22second argument should be a table that is an array\22)\0a\0a for _, v in pairs(t) do\0a\0a if fn(v) then\0a\0a return v\0a\0a end\0a\0a end\0a\0aend, 2)\0a\0a\0a\0a-- @param {string} propName\0a\0a-- @param {string} value \0a\0a-- @param {table} object\0a\0autils.propEq = utils.curry(function (propName, value, object)\0a\0a assert(type(propName) == \22string\22, \22first argument should be a string\22)\0a\0a -- assert(type(value) == \22string\22, \22second argument should be a string\22)\0a\0a assert(type(object) == \22table\22, \22third argument should be a table<object>\22)\0a\0a \0a\0a return object[propName] == value\0a\0aend, 3)\0a\0a\0a\0a-- @param {table<Array>} data\0a\0autils.reverse = function (data)\0a\0a assert(type(data) == \22table\22, \22argument needs to be a table that is an array\22)\0a\0a return utils.reduce(\0a\0a function (result, v, i)\0a\0a result[#data - i + 1] = v\0a\0a return result\0a\0a end,\0a\0a {},\0a\0a data\0a\0a )\0a\0aend\0a\0a\0a\0a-- @param {function} ... \0a\0autils.compose = utils.curry(function (...)\0a\0a local mutations = utils.reverse({...})\0a\0a\0a\0a return function (v)\0a\0a local result = v\0a\0a for _, fn in pairs(mutations) do\0a\0a assert(type(fn) == \22function\22, \22each argument needs to be a function\22)\0a\0a result = fn(result)\0a\0a end\0a\0a return result\0a\0a end\0a\0aend, 2)\0a\0a\0a\0a-- @param {string} propName\0a\0a-- @param {table} object\0a\0autils.prop = utils.curry(function (propName, object) \0a\0a return object[propName]\0a\0aend, 2)\0a\0a\0a\0a-- @param {any} val\0a\0a-- @param {table<Array>} t\0a\0autils.includes = utils.curry(function (val, t)\0a\0a assert(type(t) == \22table\22, \22argument needs to be a table\22)\0a\0a return utils.find(function (v) return v == val end, t) ~= nil\0a\0aend, 2)\0a\0a\0a\0a-- @param {table} t\0a\0autils.keys = function (t)\0a\0a assert(type(t) == \22table\22, \22argument needs to be a table\22)\0a\0a local keys = {}\0a\0a for key in pairs(t) do\0a\0a table.insert(keys, key)\0a\0a end\0a\0a return keys\0a\0aend\0a\0a\0a\0a-- @param {table} t\0a\0autils.values = function (t)\0a\0a assert(type(t) == \22table\22, \22argument needs to be a table\22)\0a\0a local values = {}\0a\0a for _, value in pairs(t) do\0a\0a table.insert(values, value)\0a\0a end\0a\0a return values\0a\0aend\0a\0a\0a\0areturn utils\0a")
(data $.rodata.7 (;7;) (i64.const 107184) "local util = require(\22.crypto.util.init\22)\0a\0alocal digest = require(\22.crypto.digest.init\22)\0a\0alocal cipher = require(\22.crypto.cipher.init\22)\0a\0alocal mac = require(\22.crypto.mac.init\22)\0a\0alocal kdf = require(\22.crypto.kdf.init\22)\0a\0a\0a\0alocal crypto = {\0a\0a _version = \220.0.1\22,\0a\0a digest = digest,\0a\0a utils = util,\0a\0a cipher = cipher,\0a\0a random = cipher.issac.random,\0a\0a mac = mac,\0a\0a kdf = kdf,\0a\0a};\0a\0a\0a\0areturn crypto\00\00\00local Stream = require(\22.crypto.util.stream\22)\0a\0alocal Hex = require(\22.crypto.util.hex\22)\0a\0alocal Array = require(\22.crypto.util.array\22)\0a\0a\0a\0a-- Ciphers\0a\0alocal AES128Cipher = require(\22.crypto.cipher.aes128\22)\0a\0alocal AES192Cipher = require(\22.crypto.cipher.aes192\22)\0a\0alocal AES256Cipher = require(\22.crypto.cipher.aes256\22)\0a\0a\0a\0a-- Modes\0a\0alocal CBCMode = require(\22.crypto.cipher.mode.cbc\22)\0a\0alocal ECBMode = require(\22.crypto.cipher.mode.ecb\22)\0a\0alocal CFBMode = require(\22.crypto.cipher.mode.cfb\22)\0a\0alocal OFBMode = require(\22.crypto.cipher.mode.ofb\22)\0a\0alocal CTRMode = require(\22.crypto.cipher.mode.ctr\22)\0a\0a\0a\0a-- Padding\0a\0alocal ZeroPadding = require(\22.crypto.padding.zero\22)\0a\0a\0a\0alocal public = {}\0a\0a\0a\0alocal getBlockCipher = function(keyLength)\0a\0a if keyLength == 128 then\0a\0a return AES128Cipher\0a\0a elseif keyLength == 192 then\0a\0a return AES192Cipher\0a\0a elseif keyLength == 256 then\0a\0a return AES256Cipher\0a\0a elseif keyLength == nil then\0a\0a return AES128Cipher\0a\0a else\0a\0a return nil\0a\0a end\0a\0aend\0a\0a\0a\0alocal getMode = function(mode)\0a\0a if mode == \22CBC\22 then\0a\0a return CBCMode\0a\0a elseif mode == \22ECB\22 then\0a\0a return ECBMode\0a\0a elseif mode == \22CFB\22 then\0a\0a return CFBMode\0a\0a elseif mode == \22OFB\22 then\0a\0a return OFBMode\0a\0a elseif mode == \22CTR\22 then\0a\0a return CTRMode\0a\0a else\0a\0a return nil\0a\0a end\0a\0aend\0a\0a\0a\0a\0a\0a--- Encrypts the given data using AES encryption.\0a\0a--- @param data string - The data to be encrypted.\0a\0a--- @param key string - The key to use for encryption.\0a\0a--- @param iv? string (optional) - The initialization vector to use for encryption. Defaults to 16 null bytes.\0a\0a--- @param mode? string (optional) - The mode to use for encryption. Defaults to \22CBC\22.\0a\0a--- @param keyLength? number (optional) - The length of the key to use for encryption. Defaults to 128.\0a\0a--- @returns table - A table containing the encrypted data in bytes, hex, and string formats.\0a\0apublic.encrypt = function(data, key, iv, mode, keyLength)\0a\0a local d = Array.fromString(data)\0a\0a local k = Array.fromString(key)\0a\0a local _iv = iv ~= nil and Array.fromString(iv) or Array.fromHex(\2200000000000000000000000000000000\22)\0a\0a\0a\0a local cipherMode = getMode(mode) or CBCMode\0a\0a local blockCipher = getBlockCipher(keyLength) or AES128Cipher\0a\0a\0a\0a local cipher = cipherMode.Cipher()\0a\0a .setKey(k)\0a\0a .setBlockCipher(blockCipher)\0a\0a .setPadding(ZeroPadding);\0a\0a\0a\0a\0a\0a local cipherOutput = cipher\0a\0a .init()\0a\0a .update(Stream.fromArray(_iv))\0a\0a .update(Stream.fromArray(d))\0a\0a .finish()\0a\0a\0a\0a local results = {}\0a\0a\0a\0a results.asBytes = function()\0a\0a return cipherOutput.asBytes()\0a\0a end\0a\0a\0a\0a results.asHex = function()\0a\0a return cipherOutput.asHex()\0a\0a end\0a\0a\0a\0a results.asString = function()\0a\0a return cipherOutput.asString()\0a\0a end\0a\0a\0a\0a return results\0a\0aend\0a\0a\0a\0a--- Decrypts the given data using AES decryption.\0a\0a--- @param cipher string - The hex encoded cipher to be decrypted.\0a\0a--- @param key string - The key to use for decryption.\0a\0a--- @param iv? string (optional) - The initialization vector to use for decryption. Defaults to 16 null bytes.\0a\0a--- @param mode? string (optional) - The mode to use for decryption. Defaults to \22CBC\22.\0a\0a--- @param keyLength? number (optional) - The length of the key to use for decryption. Defaults to 128.\0a\0apublic.decrypt = function(cipher, key, iv, mode, keyLength)\0a\0a local cipherText = Array.fromHex(cipher)\0a\0a local k = Array.fromString(key)\0a\0a local _iv = iv ~= nil and Array.fromString(iv) or Array.fromHex(\2200000000000000000000000000000000\22)\0a\0a\0a\0a local cipherMode = getMode(mode) or CBCMode\0a\0a local blockCipher = getBlockCipher(keyLength) or AES128Cipher\0a\0a\0a\0a\0a\0a local decipher = cipherMode.Decipher()\0a\0a .setKey(k)\0a\0a .setBlockCipher(blockCipher)\0a\0a .setPadding(ZeroPadding);\0a\0a\0a\0a\0a\0a local plainOutput = decipher\0a\0a .init()\0a\0a .update(Stream.fromArray(_iv))\0a\0a .update(Stream.fromArray(cipherText))\0a\0a .finish()\0a\0a\0a\0a local results = {}\0a\0a\0a\0a results.asBytes = function()\0a\0a return plainOutput.asBytes()\0a\0a end\0a\0a\0a\0a results.asHex = function()\0a\0a return plainOutput.asHex()\0a\0a end\0a\0a\0a\0a results.asString = function()\0a\0a return plainOutput.asString()\0a\0a end\0a\0a\0a\0a return results\0a\0aend\0a\0a\0a\0a\0a\0areturn public\0a\00local Array = require(\22.crypto.util.array\22);\0a\0alocal Bit = require(\22.crypto.util.bit\22);\0a\0a\0a\0alocal XOR = Bit.bxor;\0a\0a\0a\0alocal SBOX = {\0a\0a [0] = 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,\0a\0a 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,\0a\0a 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,\0a\0a 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,\0a\0a 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,\0a\0a 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,\0a\0a 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,\0a\0a 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,\0a\0a 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,\0a\0a 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,\0a\0a 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,\0a\0a 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,\0a\0a 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,\0a\0a 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,\0a\0a 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,\0a\0a 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16};\0a\0a\0a\0alocal ISBOX = {\0a\0a [0] = 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,\0a\0a 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,\0a\0a 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,\0a\0a 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,\0a\0a 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,\0a\0a 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,\0a\0a 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,\0a\0a 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,\0a\0a 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,\0a\0a 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,\0a\0a 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,\0a\0a 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,\0a\0a 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,\0a\0a 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,\0a\0a 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,\0a\0a 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D};\0a\0a\0a\0alocal ROW_SHIFT = { 1, 6, 11, 16, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, };\0a\0alocal IROW_SHIFT = { 1, 14, 11, 8, 5, 2, 15, 12, 9, 6, 3, 16, 13, 10, 7, 4, };\0a\0a\0a\0alocal ETABLE = {\0a\0a [0] = 0x01, 0x03, 0x05, 0x0F, 0x11, 0x33, 0x55, 0xFF, 0x1A, 0x2E, 0x72, 0x96, 0xA1, 0xF8, 0x13, 0x35,\0a\0a 0x5F, 0xE1, 0x38, 0x48, 0xD8, 0x73, 0x95, 0xA4, 0xF7, 0x02, 0x06, 0x0A, 0x1E, 0x22, 0x66, 0xAA,\0a\0a 0xE5, 0x34, 0x5C, 0xE4, 0x37, 0x59, 0xEB, 0x26, 0x6A, 0xBE, 0xD9, 0x70, 0x90, 0xAB, 0xE6, 0x31,\0a\0a 0x53, 0xF5, 0x04, 0x0C, 0x14, 0x3C, 0x44, 0xCC, 0x4F, 0xD1, 0x68, 0xB8, 0xD3, 0x6E, 0xB2, 0xCD,\0a\0a 0x4C, 0xD4, 0x67, 0xA9, 0xE0, 0x3B, 0x4D, 0xD7, 0x62, 0xA6, 0xF1, 0x08, 0x18, 0x28, 0x78, 0x88,\0a\0a 0x83, 0x9E, 0xB9, 0xD0, 0x6B, 0xBD, 0xDC, 0x7F, 0x81, 0x98, 0xB3, 0xCE, 0x49, 0xDB, 0x76, 0x9A,\0a\0a 0xB5, 0xC4, 0x57, 0xF9, 0x10, 0x30, 0x50, 0xF0, 0x0B, 0x1D, 0x27, 0x69, 0xBB, 0xD6, 0x61, 0xA3,\0a\0a 0xFE, 0x19, 0x2B, 0x7D, 0x87, 0x92, 0xAD, 0xEC, 0x2F, 0x71, 0x93, 0xAE, 0xE9, 0x20, 0x60, 0xA0,\0a\0a 0xFB, 0x16, 0x3A, 0x4E, 0xD2, 0x6D, 0xB7, 0xC2, 0x5D, 0xE7, 0x32, 0x56, 0xFA, 0x15, 0x3F, 0x41,\0a\0a 0xC3, 0x5E, 0xE2, 0x3D, 0x47, 0xC9, 0x40, 0xC0, 0x5B, 0xED, 0x2C, 0x74, 0x9C, 0xBF, 0xDA, 0x75,\0a\0a 0x9F, 0xBA, 0xD5, 0x64, 0xAC, 0xEF, 0x2A, 0x7E, 0x82, 0x9D, 0xBC, 0xDF, 0x7A, 0x8E, 0x89, 0x80,\0a\0a 0x9B, 0xB6, 0xC1, 0x58, 0xE8, 0x23, 0x65, 0xAF, 0xEA, 0x25, 0x6F, 0xB1, 0xC8, 0x43, 0xC5, 0x54,\0a\0a 0xFC, 0x1F, 0x21, 0x63, 0xA5, 0xF4, 0x07, 0x09, 0x1B, 0x2D, 0x77, 0x99, 0xB0, 0xCB, 0x46, 0xCA,\0a\0a 0x45, 0xCF, 0x4A, 0xDE, 0x79, 0x8B, 0x86, 0x91, 0xA8, 0xE3, 0x3E, 0x42, 0xC6, 0x51, 0xF3, 0x0E,\0a\0a 0x12, 0x36, 0x5A, 0xEE, 0x29, 0x7B, 0x8D, 0x8C, 0x8F, 0x8A, 0x85, 0x94, 0xA7, 0xF2, 0x0D, 0x17,\0a\0a 0x39, 0x4B, 0xDD, 0x7C, 0x84, 0x97, 0xA2, 0xFD, 0x1C, 0x24, 0x6C, 0xB4, 0xC7, 0x52, 0xF6, 0x01};\0a\0a\0a\0alocal LTABLE = {\0a\0a [0] = 0x00, 0x00, 0x19, 0x01, 0x32, 0x02, 0x1A, 0xC6, 0x4B, 0xC7, 0x1B, 0x68, 0x33, 0xEE, 0xDF, 0x03,\0a\0a 0x64, 0x04, 0xE0, 0x0E, 0x34, 0x8D, 0x81, 0xEF, 0x4C, 0x71, 0x08, 0xC8, 0xF8, 0x69, 0x1C, 0xC1,\0a\0a 0x7D, 0xC2, 0x1D, 0xB5, 0xF9, 0xB9, 0x27, 0x6A, 0x4D, 0xE4, 0xA6, 0x72, 0x9A, 0xC9, 0x09, 0x78,\0a\0a 0x65, 0x2F, 0x8A, 0x05, 0x21, 0x0F, 0xE1, 0x24, 0x12, 0xF0, 0x82, 0x45, 0x35, 0x93, 0xDA, 0x8E,\0a\0a 0x96, 0x8F, 0xDB, 0xBD, 0x36, 0xD0, 0xCE, 0x94, 0x13, 0x5C, 0xD2, 0xF1, 0x40, 0x46, 0x83, 0x38,\0a\0a 0x66, 0xDD, 0xFD, 0x30, 0xBF, 0x06, 0x8B, 0x62, 0xB3, 0x25, 0xE2, 0x98, 0x22, 0x88, 0x91, 0x10,\0a\0a 0x7E, 0x6E, 0x48, 0xC3, 0xA3, 0xB6, 0x1E, 0x42, 0x3A, 0x6B, 0x28, 0x54, 0xFA, 0x85, 0x3D, 0xBA,\0a\0a 0x2B, 0x79, 0x0A, 0x15, 0x9B, 0x9F, 0x5E, 0xCA, 0x4E, 0xD4, 0xAC, 0xE5, 0xF3, 0x73, 0xA7, 0x57,\0a\0a 0xAF, 0x58, 0xA8, 0x50, 0xF4, 0xEA, 0xD6, 0x74, 0x4F, 0xAE, 0xE9, 0xD5, 0xE7, 0xE6, 0xAD, 0xE8,\0a\0a 0x2C, 0xD7, 0x75, 0x7A, 0xEB, 0x16, 0x0B, 0xF5, 0x59, 0xCB, 0x5F, 0xB0, 0x9C, 0xA9, 0x51, 0xA0,\0a\0a 0x7F, 0x0C, 0xF6, 0x6F, 0x17, 0xC4, 0x49, 0xEC, 0xD8, 0x43, 0x1F, 0x2D, 0xA4, 0x76, 0x7B, 0xB7,\0a\0a 0xCC, 0xBB, 0x3E, 0x5A, 0xFB, 0x60, 0xB1, 0x86, 0x3B, 0x52, 0xA1, 0x6C, 0xAA, 0x55, 0x29, 0x9D,\0a\0a 0x97, 0xB2, 0x87, 0x90, 0x61, 0xBE, 0xDC, 0xFC, 0xBC, 0x95, 0xCF, 0xCD, 0x37, 0x3F, 0x5B, 0xD1,\0a\0a 0x53, 0x39, 0x84, 0x3C, 0x41, 0xA2, 0x6D, 0x47, 0x14, 0x2A, 0x9E, 0x5D, 0x56, 0xF2, 0xD3, 0xAB,\0a\0a 0x44, 0x11, 0x92, 0xD9, 0x23, 0x20, 0x2E, 0x89, 0xB4, 0x7C, 0xB8, 0x26, 0x77, 0x99, 0xE3, 0xA5,\0a\0a 0x67, 0x4A, 0xED, 0xDE, 0xC5, 0x31, 0xFE, 0x18, 0x0D, 0x63, 0x8C, 0x80, 0xC0, 0xF7, 0x70, 0x07};\0a\0a\0a\0alocal MIXTABLE = {\0a\0a 0x02, 0x03, 0x01, 0x01,\0a\0a 0x01, 0x02, 0x03, 0x01,\0a\0a 0x01, 0x01, 0x02, 0x03,\0a\0a 0x03, 0x01, 0x01, 0x02};\0a\0a\0a\0alocal IMIXTABLE = {\0a\0a 0x0E, 0x0B, 0x0D, 0x09,\0a\0a 0x09, 0x0E, 0x0B, 0x0D,\0a\0a 0x0D, 0x09, 0x0E, 0x0B,\0a\0a 0x0B, 0x0D, 0x09, 0x0E};\0a\0a\0a\0alocal RCON = {\0a\0a[0] = 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,\0a\0a0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,\0a\0a0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,\0a\0a0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,\0a\0a0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,\0a\0a0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,\0a\0a0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b,\0a\0a0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,\0a\0a0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,\0a\0a0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,\0a\0a0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,\0a\0a0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,\0a\0a0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,\0a\0a0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,\0a\0a0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,\0a\0a0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d};\0a\0a\0a\0a\0a\0alocal GMUL = function(A, B)\0a\0a if(A == 0x01) then return B; end\0a\0a if(B == 0x01) then return A; end\0a\0a if(A == 0x00) then return 0; end\0a\0a if(B == 0x00) then return 0; end\0a\0a\0a\0a local LA = LTABLE[A];\0a\0a local LB = LTABLE[B];\0a\0a\0a\0a local sum = LA + LB;\0a\0a if (sum > 0xFF) then sum = sum - 0xFF; end\0a\0a\0a\0a return ETABLE[sum];\0a\0aend\0a\0a\0a\0alocal byteSub = Array.substitute;\0a\0a\0a\0alocal shiftRow = Array.permute;\0a\0a\0a\0alocal mixCol = function(i, mix)\0a\0a local out = {};\0a\0a\0a\0a local a, b, c, d;\0a\0a\0a\0a a = GMUL(i[ 1], mix[ 1]);\0a\0a b = GMUL(i[ 2], mix[ 2]);\0a\0a c = GMUL(i[ 3], mix[ 3]);\0a\0a d = GMUL(i[ 4], mix[ 4]);\0a\0a out[ 1] = XOR(XOR(a, b), XOR(c, d));\0a\0a a = GMUL(i[ 1], mix[ 5]);\0a\0a b = GMUL(i[ 2], mix[ 6]);\0a\0a c = GMUL(i[ 3], mix[ 7]);\0a\0a d = GMUL(i[ 4], mix[ 8]);\0a\0a out[ 2] = XOR(XOR(a, b), XOR(c, d));\0a\0a a = GMUL(i[ 1], mix[ 9]);\0a\0a b = GMUL(i[ 2], mix[10]);\0a\0a c = GMUL(i[ 3], mix[11]);\0a\0a d = GMUL(i[ 4], mix[12]);\0a\0a out[ 3] = XOR(XOR(a, b), XOR(c, d));\0a\0a a = GMUL(i[ 1], mix[13]);\0a\0a b = GMUL(i[ 2], mix[14]);\0a\0a c = GMUL(i[ 3], mix[15]);\0a\0a d = GMUL(i[ 4], mix[16]);\0a\0a out[ 4] = XOR(XOR(a, b), XOR(c, d));\0a\0a\0a\0a\0a\0a a = GMUL(i[ 5], mix[ 1]);\0a\0a b = GMUL(i[ 6], mix[ 2]);\0a\0a c = GMUL(i[ 7], mix[ 3]);\0a\0a d = GMUL(i[ 8], mix[ 4]);\0a\0a out[ 5] = XOR(XOR(a, b), XOR(c, d));\0a\0a a = GMUL(i[ 5], mix[ 5]);\0a\0a b = GMUL(i[ 6], mix[ 6]);\0a\0a c = GMUL(i[ 7], mix[ 7]);\0a\0a d = GMUL(i[ 8], mix[ 8]);\0a\0a out[ 6] = XOR(XOR(a, b), XOR(c, d));\0a\0a a = GMUL(i[ 5], mix[ 9]);\0a\0a b = GMUL(i[ 6], mix[10]);\0a\0a c = GMUL(i[ 7], mix[11]);\0a\0a d = GMUL(i[ 8], mix[12]);\0a\0a out[ 7] = XOR(XOR(a, b), XOR(c, d));\0a\0a a = GMUL(i[ 5], mix[13]);\0a\0a b = GMUL(i[ 6], mix[14]);\0a\0a c = GMUL(i[ 7], mix[15]);\0a\0a d = GMUL(i[ 8], mix[16]);\0a\0a out[ 8] = XOR(XOR(a, b), XOR(c, d));\0a\0a\0a\0a\0a\0a a = GMUL(i[ 9], mix[ 1]);\0a\0a b = GMUL(i[10], mix[ 2]);\0a\0a c = GMUL(i[11], mix[ 3]);\0a\0a d = GMUL(i[12], mix[ 4]);\0a\0a out[ 9] = XOR(XOR(a, b), XOR(c, d));\0a\0a a = GMUL(i[ 9], mix[ 5]);\0a\0a b = GMUL(i[10], mix[ 6]);\0a\0a c = GMUL(i[11], mix[ 7]);\0a\0a d = GMUL(i[12], mix[ 8]);\0a\0a out[10] = XOR(XOR(a, b), XOR(c, d));\0a\0a a = GMUL(i[ 9], mix[ 9]);\0a\0a b = GMUL(i[10], mix[10]);\0a\0a c = GMUL(i[11], mix[11]);\0a\0a d = GMUL(i[12], mix[12]);\0a\0a out[11] = XOR(XOR(a, b), XOR(c, d));\0a\0a a = GMUL(i[ 9], mix[13]);\0a\0a b = GMUL(i[10], mix[14]);\0a\0a c = GMUL(i[11], mix[15]);\0a\0a d = GMUL(i[12], mix[16]);\0a\0a out[12] = XOR(XOR(a, b), XOR(c, d));\0a\0a\0a\0a\0a\0a a = GMUL(i[13], mix[ 1]);\0a\0a b = GMUL(i[14], mix[ 2]);\0a\0a c = GMUL(i[15], mix[ 3]);\0a\0a d = GMUL(i[16], mix[ 4]);\0a\0a out[13] = XOR(XOR(a, b), XOR(c, d));\0a\0a a = GMUL(i[13], mix[ 5]);\0a\0a b = GMUL(i[14], mix[ 6]);\0a\0a c = GMUL(i[15], mix[ 7]);\0a\0a d = GMUL(i[16], mix[ 8]);\0a\0a out[14] = XOR(XOR(a, b), XOR(c, d));\0a\0a a = GMUL(i[13], mix[ 9]);\0a\0a b = GMUL(i[14], mix[10]);\0a\0a c = GMUL(i[15], mix[11]);\0a\0a d = GMUL(i[16], mix[12]);\0a\0a out[15] = XOR(XOR(a, b), XOR(c, d));\0a\0a a = GMUL(i[13], mix[13]);\0a\0a b = GMUL(i[14], mix[14]);\0a\0a c = GMUL(i[15], mix[15]);\0a\0a d = GMUL(i[16], mix[16]);\0a\0a out[16] = XOR(XOR(a, b), XOR(c, d));\0a\0a\0a\0a return out;\0a\0aend\0a\0a\0a\0alocal keyRound = function(key, round)\0a\0a local out = {};\0a\0a\0a\0a out[ 1] = XOR(key[ 1], XOR(SBOX[key[14]], RCON[round]));\0a\0a out[ 2] = XOR(key[ 2], SBOX[key[15]]);\0a\0a out[ 3] = XOR(key[ 3], SBOX[key[16]]);\0a\0a out[ 4] = XOR(key[ 4], SBOX[key[13]]);\0a\0a\0a\0a out[ 5] = XOR(out[ 1], key[ 5]);\0a\0a out[ 6] = XOR(out[ 2], key[ 6]);\0a\0a out[ 7] = XOR(out[ 3], key[ 7]);\0a\0a out[ 8] = XOR(out[ 4], key[ 8]);\0a\0a\0a\0a out[ 9] = XOR(out[ 5], key[ 9]);\0a\0a out[10] = XOR(out[ 6], key[10]);\0a\0a out[11] = XOR(out[ 7], key[11]);\0a\0a out[12] = XOR(out[ 8], key[12]);\0a\0a\0a\0a out[13] = XOR(out[ 9], key[13]);\0a\0a out[14] = XOR(out[10], key[14]);\0a\0a out[15] = XOR(out[11], key[15]);\0a\0a out[16] = XOR(out[12], key[16]);\0a\0a\0a\0a return out;\0a\0aend\0a\0a\0a\0alocal keyExpand = function(key)\0a\0a local keys = {};\0a\0a\0a\0a local temp = key;\0a\0a\0a\0a keys[1] = temp;\0a\0a\0a\0a for i = 1, 10 do\0a\0a temp = keyRound(temp, i);\0a\0a keys[i + 1] = temp;\0a\0a end\0a\0a\0a\0a return keys;\0a\0a\0a\0aend\0a\0a\0a\0alocal addKey = Array.XOR;\0a\0a\0a\0a\0a\0a\0a\0alocal AES = {};\0a\0a\0a\0aAES.blockSize = 16;\0a\0a\0a\0aAES.encrypt = function(key, block)\0a\0a\0a\0a local keySchedule = keyExpand(key);\0a\0a\0a\0a --round 0\0a\0a block = addKey(block, keySchedule[1]);\0a\0a\0a\0a --round 1\0a\0a block = byteSub(block, SBOX);\0a\0a block = shiftRow(block, ROW_SHIFT);\0a\0a block = mixCol(block, MIXTABLE);\0a\0a block = addKey(block, keySchedule[2]);\0a\0a\0a\0a --round 2\0a\0a block = byteSub(block, SBOX);\0a\0a block = shiftRow(block, ROW_SHIFT);\0a\0a block = mixCol(block, MIXTABLE);\0a\0a block = addKey(block, keySchedule[3]);\0a\0a\0a\0a --round 3\0a\0a block = byteSub(block, SBOX);\0a\0a block = shiftRow(block, ROW_SHIFT);\0a\0a block = mixCol(block, MIXTABLE);\0a\0a block = addKey(block, keySchedule[4]);\0a\0a\0a\0a --round 4\0a\0a block = byteSub(block, SBOX);\0a\0a block = shiftRow(block, ROW_SHIFT);\0a\0a block = mixCol(block, MIXTABLE);\0a\0a block = addKey(block, keySchedule[5]);\0a\0a\0a\0a --round 5\0a\0a block = byteSub(block, SBOX);\0a\0a block = shiftRow(block, ROW_SHIFT);\0a\0a block = mixCol(block, MIXTABLE);\0a\0a block = addKey(block, keySchedule[6]);\0a\0a\0a\0a --round 6\0a\0a block = byteSub(block, SBOX);\0a\0a block = shiftRow(block, ROW_SHIFT);\0a\0a block = mixCol(block, MIXTABLE);\0a\0a block = addKey(block, keySchedule[7]);\0a\0a\0a\0a --round 7\0a\0a block = byteSub(block, SBOX);\0a\0a block = shiftRow(block, ROW_SHIFT);\0a\0a block = mixCol(block, MIXTABLE);\0a\0a block = addKey(block, keySchedule[8]);\0a\0a\0a\0a --round 8\0a\0a block = byteSub(block, SBOX);\0a\0a block = shiftRow(block, ROW_SHIFT);\0a\0a block = mixCol(block, MIXTABLE);\0a\0a block = addKey(block, keySchedule[9]);\0a\0a\0a\0a --round 9\0a\0a block = byteSub(block, SBOX);\0a\0a block = shiftRow(block, ROW_SHIFT);\0a\0a block = mixCol(block, MIXTABLE);\0a\0a block = addKey(block, keySchedule[10]);\0a\0a\0a\0a --round 10\0a\0a block = byteSub(block, SBOX);\0a\0a block = shiftRow(block, ROW_SHIFT);\0a\0a block = addKey(block, keySchedule[11]);\0a\0a\0a\0a return block;\0a\0a\0a\0aend\0a\0a\0a\0aAES.decrypt = function(key, block)\0a\0a\0a\0a local keySchedule = keyExpand(key);\0a\0a\0a\0a --round 0\0a\0a block = addKey(block, keySchedule[11]);\0a\0a\0a\0a --round 1\0a\0a block = shiftRow(block, IROW_SHIFT);\0a\0a block = byteSub(block, ISBOX);\0a\0a block = addKey(block, keySchedule[10]);\0a\0a block = mixCol(block, IMIXTABLE);\0a\0a\0a\0a --round 2\0a\0a block = shiftRow(block, IROW_SHIFT);\0a\0a block = byteSub(block, ISBOX);\0a\0a block = addKey(block, keySchedule[9]);\0a\0a block = mixCol(block, IMIXTABLE);\0a\0a\0a\0a --round 3\0a\0a block = shiftRow(block, IROW_SHIFT);\0a\0a block = byteSub(block, ISBOX);\0a\0a block = addKey(block, keySchedule[8]);\0a\0a block = mixCol(block, IMIXTABLE);\0a\0a\0a\0a --round 4\0a\0a block = shiftRow(block, IROW_SHIFT);\0a\0a block = byteSub(block, ISBOX);\0a\0a block = addKey(block, keySchedule[7]);\0a\0a block = mixCol(block, IMIXTABLE);\0a\0a\0a\0a --round 5\0a\0a block = shiftRow(block, IROW_SHIFT);\0a\0a block = byteSub(block, ISBOX);\0a\0a block = addKey(block, keySchedule[6]);\0a\0a block = mixCol(block, IMIXTABLE);\0a\0a\0a\0a --round 6\0a\0a block = shiftRow(block, IROW_SHIFT);\0a\0a block = byteSub(block, ISBOX);\0a\0a block = addKey(block, keySchedule[5]);\0a\0a block = mixCol(block, IMIXTABLE);\0a\0a\0a\0a --round 7\0a\0a block = shiftRow(block, IROW_SHIFT);\0a\0a block = byteSub(block, ISBOX);\0a\0a block = addKey(block, keySchedule[4]);\0a\0a block = mixCol(block, IMIXTABLE);\0a\0a\0a\0a --round 8\0a\0a block = shiftRow(block, IROW_SHIFT);\0a\0a block = byteSub(block, ISBOX);\0a\0a block = addKey(block, keySchedule[3]);\0a\0a block = mixCol(block, IMIXTABLE);\0a\0a\0a\0a --round 9\0a\0a block = shiftRow(block, IROW_SHIFT);\0a\0a block = byteSub(block, ISBOX);\0a\0a block = addKey(block, keySchedule[2]);\0a\0a block = mixCol(block, IMIXTABLE);\0a\0a\0a\0a --round 10\0a\0a block = shiftRow(block, IROW_SHIFT);\0a\0a block = byteSub(block, ISBOX);\0a\0a block = addKey(block, keySchedule[1]);\0a\0a\0a\0a return block;\0a\0aend\0a\0a\0a\0areturn AES;\00\00\00\00\0a\0alocal Array = require(\22.crypto.util.array\22);\0a\0alocal Bit = require(\22.crypto.util.bit\22);\0a\0a\0a\0alocal XOR = Bit.bxor;\0a\0a\0a\0alocal SBOX = {\0a\0a [0] = 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,\0a\0a 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,\0a\0a 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,\0a\0a 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,\0a\0a 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,\0a\0a 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,\0a\0a 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,\0a\0a 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,\0a\0a 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,\0a\0a 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,\0a\0a 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,\0a\0a 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,\0a\0a 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,\0a\0a 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,\0a\0a 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,\0a\0a 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16};\0a\0a\0a\0alocal ISBOX = {\0a\0a [0] = 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,\0a\0a 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,\0a\0a 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,\0a\0a 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,\0a\0a 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,\0a\0a 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,\0a\0a 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,\0a\0a 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,\0a\0a 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,\0a\0a 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,\0a\0a 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,\0a\0a 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,\0a\0a 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,\0a\0a 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,\0a\0a 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,\0a\0a 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D};\0a\0a\0a\0alocal ROW_SHIFT = { 1, 6, 11, 16, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, };\0a\0alocal IROW_SHIFT = { 1, 14, 11, 8, 5, 2, 15, 12, 9, 6, 3, 16, 13, 10, 7, 4, };\0a\0a\0a\0alocal ETABLE = {\0a\0a [0] = 0x01, 0x03, 0x05, 0x0F, 0x11, 0x33, 0x55, 0xFF, 0x1A, 0x2E, 0x72, 0x96, 0xA1, 0xF8, 0x13, 0x35,\0a\0a 0x5F, 0xE1, 0x38, 0x48, 0xD8, 0x73, 0x95, 0xA4, 0xF7, 0x02, 0x06, 0x0A, 0x1E, 0x22, 0x66, 0xAA,\0a\0a 0xE5, 0x34, 0x5C, 0xE4, 0x37, 0x59, 0xEB, 0x26, 0x6A, 0xBE, 0xD9, 0x70, 0x90, 0xAB, 0xE6, 0x31,\0a\0a 0x53, 0xF5, 0x04, 0x0C, 0x14, 0x3C, 0x44, 0xCC, 0x4F, 0xD1, 0x68, 0xB8, 0xD3, 0x6E, 0xB2, 0xCD,\0a\0a 0x4C, 0xD4, 0x67, 0xA9, 0xE0, 0x3B, 0x4D, 0xD7, 0x62, 0xA6, 0xF1, 0x08, 0x18, 0x28, 0x78, 0x88,\0a\0a 0x83, 0x9E, 0xB9, 0xD0, 0x6B, 0xBD, 0xDC, 0x7F, 0x81, 0x98, 0xB3, 0xCE, 0x49, 0xDB, 0x76, 0x9A,\0a\0a 0xB5, 0xC4, 0x57, 0xF9, 0x10, 0x30, 0x50, 0xF0, 0x0B, 0x1D, 0x27, 0x69, 0xBB, 0xD6, 0x61, 0xA3,\0a\0a 0xFE, 0x19, 0x2B, 0x7D, 0x87, 0x92, 0xAD, 0xEC, 0x2F, 0x71, 0x93, 0xAE, 0xE9, 0x20, 0x60, 0xA0,\0a\0a 0xFB, 0x16, 0x3A, 0x4E, 0xD2, 0x6D, 0xB7, 0xC2, 0x5D, 0xE7, 0x32, 0x56, 0xFA, 0x15, 0x3F, 0x41,\0a\0a 0xC3, 0x5E, 0xE2, 0x3D, 0x47, 0xC9, 0x40, 0xC0, 0x5B, 0xED, 0x2C, 0x74, 0x9C, 0xBF, 0xDA, 0x75,\0a\0a 0x9F, 0xBA, 0xD5, 0x64, 0xAC, 0xEF, 0x2A, 0x7E, 0x82, 0x9D, 0xBC, 0xDF, 0x7A, 0x8E, 0x89, 0x80,\0a\0a 0x9B, 0xB6, 0xC1, 0x58, 0xE8, 0x23, 0x65, 0xAF, 0xEA, 0x25, 0x6F, 0xB1, 0xC8, 0x43, 0xC5, 0x54,\0a\0a 0xFC, 0x1F, 0x21, 0x63, 0xA5, 0xF4, 0x07, 0x09, 0x1B, 0x2D, 0x77, 0x99, 0xB0, 0xCB, 0x46, 0xCA,\0a\0a 0x45, 0xCF, 0x4A, 0xDE, 0x79, 0x8B, 0x86, 0x91, 0xA8, 0xE3, 0x3E, 0x42, 0xC6, 0x51, 0xF3, 0x0E,\0a\0a 0x12, 0x36, 0x5A, 0xEE, 0x29, 0x7B, 0x8D, 0x8C, 0x8F, 0x8A, 0x85, 0x94, 0xA7, 0xF2, 0x0D, 0x17,\0a\0a 0x39, 0x4B, 0xDD, 0x7C, 0x84, 0x97, 0xA2, 0xFD, 0x1C, 0x24, 0x6C, 0xB4, 0xC7, 0x52, 0xF6, 0x01};\0a\0a\0a\0alocal LTABLE = {\0a\0a [0] = 0x00, 0x00, 0x19, 0x01, 0x32, 0x02, 0x1A, 0xC6, 0x4B, 0xC7, 0x1B, 0x68, 0x33, 0xEE, 0xDF, 0x03,\0a\0a 0x64, 0x04, 0xE0, 0x0E, 0x34, 0x8D, 0x81, 0xEF, 0x4C, 0x71, 0x08, 0xC8, 0xF8, 0x69, 0x1C, 0xC1,\0a\0a 0x7D, 0xC2, 0x1D, 0xB5, 0xF9, 0xB9, 0x27, 0x6A, 0x4D, 0xE4, 0xA6, 0x72, 0x9A, 0xC9, 0x09, 0x78,\0a\0a 0x65, 0x2F, 0x8A, 0x05, 0x21, 0x0F, 0xE1, 0x24, 0x12, 0xF0, 0x82, 0x45, 0x35, 0x93, 0xDA, 0x8E,\0a\0a 0x96, 0x8F, 0xDB, 0xBD, 0x36, 0xD0, 0xCE, 0x94, 0x13, 0x5C, 0xD2, 0xF1, 0x40, 0x46, 0x83, 0x38,\0a\0a 0x66, 0xDD, 0xFD, 0x30, 0xBF, 0x06, 0x8B, 0x62, 0xB3, 0x25, 0xE2, 0x98, 0x22, 0x88, 0x91, 0x10,\0a\0a 0x7E, 0x6E, 0x48, 0xC3, 0xA3, 0xB6, 0x1E, 0x42, 0x3A, 0x6B, 0x28, 0x54, 0xFA, 0x85, 0x3D, 0xBA,\0a\0a 0x2B, 0x79, 0x0A, 0x15, 0x9B, 0x9F, 0x5E, 0xCA, 0x4E, 0xD4, 0xAC, 0xE5, 0xF3, 0x73, 0xA7, 0x57,\0a\0a 0xAF, 0x58, 0xA8, 0x50, 0xF4, 0xEA, 0xD6, 0x74, 0x4F, 0xAE, 0xE9, 0xD5, 0xE7, 0xE6, 0xAD, 0xE8,\0a\0a 0x2C, 0xD7, 0x75, 0x7A, 0xEB, 0x16, 0x0B, 0xF5, 0x59, 0xCB, 0x5F, 0xB0, 0x9C, 0xA9, 0x51, 0xA0,\0a\0a 0x7F, 0x0C, 0xF6, 0x6F, 0x17, 0xC4, 0x49, 0xEC, 0xD8, 0x43, 0x1F, 0x2D, 0xA4, 0x76, 0x7B, 0xB7,\0a\0a 0xCC, 0xBB, 0x3E, 0x5A, 0xFB, 0x60, 0xB1, 0x86, 0x3B, 0x52, 0xA1, 0x6C, 0xAA, 0x55, 0x29, 0x9D,\0a\0a 0x97, 0xB2, 0x87, 0x90, 0x61, 0xBE, 0xDC, 0xFC, 0xBC, 0x95, 0xCF, 0xCD, 0x37, 0x3F, 0x5B, 0xD1,\0a\0a 0x53, 0x39, 0x84, 0x3C, 0x41, 0xA2, 0x6D, 0x47, 0x14, 0x2A, 0x9E, 0x5D, 0x56, 0xF2, 0xD3, 0xAB,\0a\0a 0x44, 0x11, 0x92, 0xD9, 0x23, 0x20, 0x2E, 0x89, 0xB4, 0x7C, 0xB8, 0x26, 0x77, 0x99, 0xE3, 0xA5,\0a\0a 0x67, 0x4A, 0xED, 0xDE, 0xC5, 0x31, 0xFE, 0x18, 0x0D, 0x63, 0x8C, 0x80, 0xC0, 0xF7, 0x70, 0x07};\0a\0a\0a\0alocal MIXTABLE = {\0a\0a 0x02, 0x03, 0x01, 0x01,\0a\0a 0x01, 0x02, 0x03, 0x01,\0a\0a 0x01, 0x01, 0x02, 0x03,\0a\0a 0x03, 0x01, 0x01, 0x02};\0a\0a\0a\0alocal IMIXTABLE = {\0a\0a 0x0E, 0x0B, 0x0D, 0x09,\0a\0a 0x09, 0x0E, 0x0B, 0x0D,\0a\0a 0x0D, 0x09, 0x0E, 0x0B,\0a\0a 0x0B, 0x0D, 0x09, 0x0E};\0a\0a\0a\0alocal RCON = {\0a\0a[0] = 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,\0a\0a0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,\0a\0a0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,\0a\0a0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,\0a\0a0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,\0a\0a0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,\0a\0a0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b,\0a\0a0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,\0a\0a0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,\0a\0a0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,\0a\0a0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,\0a\0a0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,\0a\0a0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,\0a\0a0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,\0a\0a0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,\0a\0a0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d};\0a\0a\0a\0a\0a\0alocal GMUL = function(A, B)\0a\0a if(A == 0x01) then return B; end\0a\0a if(B == 0x01) then return A; end\0a\0a if(A == 0x00) then return 0; end\0a\0a if(B == 0x00) then return 0; end\0a\0a\0a\0a local LA = LTABLE[A];\0a\0a local LB = LTABLE[B];\0a\0a\0a\0a local sum = LA + LB;\0a\0a if (sum > 0xFF) then sum = sum - 0xFF; end\0a\0a\0a\0a return ETABLE[sum];\0a\0aend\0a\0a\0a\0alocal byteSub = Array.substitute;\0a\0a\0a\0alocal shiftRow = Array.permute;\0a\0a\0a\0alocal mixCol = function(i, mix)\0a\0a local out = {};\0a\0a\0a\0a local a, b, c, d;\0a\0a\0a\0a a = GMUL(i[ 1], mix[ 1]);\0a\0a b = GMUL(i[ 2], mix[ 2]);\0a\0a c = GMUL(i[ 3], mix[ 3]);\0a\0a d = GMUL(i[ 4], mix[ 4]);\0a\0a out[ 1] = XOR(XOR(a, b), XOR(c, d));\0a\0a a = GMUL(i[ 1], mix[ 5]);\0a\0a b = GMUL(i[ 2], mix[ 6]);\0a\0a c = GMUL(i[ 3], mix[ 7]);\0a\0a d = GMUL(i[ 4], mix[ 8]);\0a\0a out[ 2] = XOR(XOR(a, b), XOR(c, d));\0a\0a a = GMUL(i[ 1], mix[ 9]);\0a\0a b = GMUL(i[ 2], mix[10]);\0a\0a c = GMUL(i[ 3], mix[11]);\0a\0a d = GMUL(i[ 4], mix[12]);\0a\0a out[ 3] = XOR(XOR(a, b), XOR(c, d));\0a\0a a = GMUL(i[ 1], mix[13]);\0a\0a b = GMUL(i[ 2], mix[14]);\0a\0a c = GMUL(i[ 3], mix[15]);\0a\0a d = GMUL(i[ 4], mix[16]);\0a\0a out[ 4] = XOR(XOR(a, b), XOR(c, d));\0a\0a\0a\0a\0a\0a a = GMUL(i[ 5], mix[ 1]);\0a\0a b = GMUL(i[ 6], mix[ 2]);\0a\0a c = GMUL(i[ 7], mix[ 3]);\0a\0a d = GMUL(i[ 8], mix[ 4]);\0a\0a out[ 5] = XOR(XOR(a, b), XOR(c, d));\0a\0a a = GMUL(i[ 5], mix[ 5]);\0a\0a b = GMUL(i[ 6], mix[ 6]);\0a\0a c = GMUL(i[ 7], mix[ 7]);\0a\0a d = GMUL(i[ 8], mix[ 8]);\0a\0a out[ 6] = XOR(XOR(a, b), XOR(c, d));\0a\0a a = GMUL(i[ 5], mix[ 9]);\0a\0a b = GMUL(i[ 6], mix[10]);\0a\0a c = GMUL(i[ 7], mix[11]);\0a\0a d = GMUL(i[ 8], mix[12]);\0a\0a out[ 7] = XOR(XOR(a, b), XOR(c, d));\0a\0a a = GMUL(i[ 5], mix[13]);\0a\0a b = GMUL(i[ 6], mix[14]);\0a\0a c = GMUL(i[ 7], mix[15]);\0a\0a d = GMUL(i[ 8], mix[16]);\0a\0a out[ 8] = XOR(XOR(a, b), XOR(c, d));\0a\0a\0a\0a\0a\0a a = GMUL(i[ 9], mix[ 1]);\0a\0a b = GMUL(i[10], mix[ 2]);\0a\0a c = GMUL(i[11], mix[ 3]);\0a\0a d = GMUL(i[12], mix[ 4]);\0a\0a out[ 9] = XOR(XOR(a, b), XOR(c, d));\0a\0a a = GMUL(i[ 9], mix[ 5]);\0a\0a b = GMUL(i[10], mix[ 6]);\0a\0a c = GMUL(i[11], mix[ 7]);\0a\0a d = GMUL(i[12], mix[ 8]);\0a\0a out[10] = XOR(XOR(a, b), XOR(c, d));\0a\0a a = GMUL(i[ 9], mix[ 9]);\0a\0a b = GMUL(i[10], mix[10]);\0a\0a c = GMUL(i[11], mix[11]);\0a\0a d = GMUL(i[12], mix[12]);\0a\0a out[11] = XOR(XOR(a, b), XOR(c, d));\0a\0a a = GMUL(i[ 9], mix[13]);\0a\0a b = GMUL(i[10], mix[14]);\0a\0a c = GMUL(i[11], mix[15]);\0a\0a d = GMUL(i[12], mix[16]);\0a\0a out[12] = XOR(XOR(a, b), XOR(c, d));\0a\0a\0a\0a\0a\0a a = GMUL(i[13], mix[ 1]);\0a\0a b = GMUL(i[14], mix[ 2]);\0a\0a c = GMUL(i[15], mix[ 3]);\0a\0a d = GMUL(i[16], mix[ 4]);\0a\0a out[13] = XOR(XOR(a, b), XOR(c, d));\0a\0a a = GMUL(i[13], mix[ 5]);\0a\0a b = GMUL(i[14], mix[ 6]);\0a\0a c = GMUL(i[15], mix[ 7]);\0a\0a d = GMUL(i[16], mix[ 8]);\0a\0a out[14] = XOR(XOR(a, b), XOR(c, d));\0a\0a a = GMUL(i[13], mix[ 9]);\0a\0a b = GMUL(i[14], mix[10]);\0a\0a c = GMUL(i[15], mix[11]);\0a\0a d = GMUL(i[16], mix[12]);\0a\0a out[15] = XOR(XOR(a, b), XOR(c, d));\0a\0a a = GMUL(i[13], mix[13]);\0a\0a b = GMUL(i[14], mix[14]);\0a\0a c = GMUL(i[15], mix[15]);\0a\0a d = GMUL(i[16], mix[16]);\0a\0a out[16] = XOR(XOR(a, b), XOR(c, d));\0a\0a\0a\0a return out;\0a\0aend\0a\0a\0a\0alocal keyRound = function(key, round)\0a\0a local i = (round - 1) * 24;\0a\0a local out = key;\0a\0a\0a\0a out[25 + i] = XOR(key[ 1 + i], XOR(SBOX[key[22 + i]], RCON[round]));\0a\0a out[26 + i] = XOR(key[ 2 + i], SBOX[key[23 + i]]);\0a\0a out[27 + i] = XOR(key[ 3 + i], SBOX[key[24 + i]]);\0a\0a out[28 + i] = XOR(key[ 4 + i], SBOX[key[21 + i]]);\0a\0a\0a\0a out[29 + i] = XOR(out[25 + i], key[ 5 + i]);\0a\0a out[30 + i] = XOR(out[26 + i], key[ 6 + i]);\0a\0a out[31 + i] = XOR(out[27 + i], key[ 7 + i]);\0a\0a out[32 + i] = XOR(out[28 + i], key[ 8 + i]);\0a\0a\0a\0a out[33 + i] = XOR(out[29 + i], key[ 9 + i]);\0a\0a out[34 + i] = XOR(out[30 + i], key[10 + i]);\0a\0a out[35 + i] = XOR(out[31 + i], key[11 + i]);\0a\0a out[36 + i] = XOR(out[32 + i], key[12 + i]);\0a\0a\0a\0a out[37 + i] = XOR(out[33 + i], key[13 + i]);\0a\0a out[38 + i] = XOR(out[34 + i], key[14 + i]);\0a\0a out[39 + i] = XOR(out[35 + i], key[15 + i]);\0a\0a out[40 + i] = XOR(out[36 + i], key[16 + i]);\0a\0a\0a\0a out[41 + i] = XOR(out[37 + i], key[17 + i]);\0a\0a out[42 + i] = XOR(out[38 + i], key[18 + i]);\0a\0a out[43 + i] = XOR(out[39 + i], key[19 + i]);\0a\0a out[44 + i] = XOR(out[40 + i], key[20 + i]);\0a\0a\0a\0a out[45 + i] = XOR(out[41 + i], key[21 + i]);\0a\0a out[46 + i] = XOR(out[42 + i], key[22 + i]);\0a\0a out[47 + i] = XOR(out[43 + i], key[23 + i]);\0a\0a out[48 + i] = XOR(out[44 + i], key[24 + i]);\0a\0a\0a\0a return out;\0a\0aend\0a\0a\0a\0alocal keyExpand = function(key)\0a\0a local bytes = Array.copy(key);\0a\0a\0a\0a for i = 1, 8 do\0a\0a keyRound(bytes, i);\0a\0a end\0a\0a\0a\0a local keys = {};\0a\0a\0a\0a keys[ 1] = Array.slice(bytes, 1, 16);\0a\0a keys[ 2] = Array.slice(bytes, 17, 32);\0a\0a keys[ 3] = Array.slice(bytes, 33, 48);\0a\0a keys[ 4] = Array.slice(bytes, 49, 64);\0a\0a keys[ 5] = Array.slice(bytes, 65, 80);\0a\0a keys[ 6] = Array.slice(bytes, 81, 96);\0a\0a keys[ 7] = Array.slice(bytes, 97, 112);\0a\0a keys[ 8] = Array.slice(bytes, 113, 128);\0a\0a keys[ 9] = Array.slice(bytes, 129, 144);\0a\0a keys[10] = Array.slice(bytes, 145, 160);\0a\0a keys[11] = Array.slice(bytes, 161, 176);\0a\0a keys[12] = Array.slice(bytes, 177, 192);\0a\0a keys[13] = Array.slice(bytes, 193, 208);\0a\0a\0a\0a return keys;\0a\0a\0a\0aend\0a\0a\0a\0alocal addKey = Array.XOR;\0a\0a\0a\0a\0a\0a\0a\0alocal AES = {};\0a\0a\0a\0aAES.blockSize = 16;\0a\0a\0a\0aAES.encrypt = function(key, block)\0a\0a\0a\0a local keySchedule = keyExpand(key);\0a\0a\0a\0a --round 0\0a\0a block = addKey(block, keySchedule[1]);\0a\0a\0a\0a --round 1\0a\0a block = byteSub(block, SBOX);\0a\0a block = shiftRow(block, ROW_SHIFT);\0a\0a block = mixCol(block, MIXTABLE);\0a\0a block = addKey(block, keySchedule[2]);\0a\0a\0a\0a --round 2\0a\0a block = byteSub(block, SBOX);\0a\0a block = shiftRow(block, ROW_SHIFT);\0a\0a block = mixCol(block, MIXTABLE);\0a\0a block = addKey(block, keySchedule[3]);\0a\0a\0a\0a --round 3\0a\0a block = byteSub(block, SBOX);\0a\0a block = shiftRow(block, ROW_SHIFT);\0a\0a block = mixCol(block, MIXTABLE);\0a\0a block = addKey(block, keySchedule[4]);\0a\0a\0a\0a --round 4\0a\0a block = byteSub(block, SBOX);\0a\0a block = shiftRow(block, ROW_SHIFT);\0a\0a block = mixCol(block, MIXTABLE);\0a\0a block = addKey(block, keySchedule[5]);\0a\0a\0a\0a --round 5\0a\0a block = byteSub(block, SBOX);\0a\0a block = shiftRow(block, ROW_SHIFT);\0a\0a block = mixCol(block, MIXTABLE);\0a\0a block = addKey(block, keySchedule[6]);\0a\0a\0a\0a --round 6\0a\0a block = byteSub(block, SBOX);\0a\0a block = shiftRow(block, ROW_SHIFT);\0a\0a block = mixCol(block, MIXTABLE);\0a\0a block = addKey(block, keySchedule[7]);\0a\0a\0a\0a --round 7\0a\0a block = byteSub(block, SBOX);\0a\0a block = shiftRow(block, ROW_SHIFT);\0a\0a block = mixCol(block, MIXTABLE);\0a\0a block = addKey(block, keySchedule[8]);\0a\0a\0a\0a --round 8\0a\0a block = byteSub(block, SBOX);\0a\0a block = shiftRow(block, ROW_SHIFT);\0a\0a block = mixCol(block, MIXTABLE);\0a\0a block = addKey(block, keySchedule[9]);\0a\0a\0a\0a --round 9\0a\0a block = byteSub(block, SBOX);\0a\0a block = shiftRow(block, ROW_SHIFT);\0a\0a block = mixCol(block, MIXTABLE);\0a\0a block = addKey(block, keySchedule[10]);\0a\0a\0a\0a --round 10\0a\0a block = byteSub(block, SBOX);\0a\0a block = shiftRow(block, ROW_SHIFT);\0a\0a block = mixCol(block, MIXTABLE);\0a\0a block = addKey(block, keySchedule[11]);\0a\0a\0a\0a --round 11\0a\0a block = byteSub(block, SBOX);\0a\0a block = shiftRow(block, ROW_SHIFT);\0a\0a block = mixCol(block, MIXTABLE);\0a\0a block = addKey(block, keySchedule[12]);\0a\0a\0a\0a --round 12\0a\0a block = byteSub(block, SBOX);\0a\0a block = shiftRow(block, ROW_SHIFT);\0a\0a block = addKey(block, keySchedule[13]);\0a\0a\0a\0a return block;\0a\0a\0a\0aend\0a\0a\0a\0aAES.decrypt = function(key, block)\0a\0a\0a\0a local keySchedule = keyExpand(key);\0a\0a\0a\0a --round 0\0a\0a block = addKey(block, keySchedule[13]);\0a\0a\0a\0a --round 1\0a\0a block = shiftRow(block, IROW_SHIFT);\0a\0a block = byteSub(block, ISBOX);\0a\0a block = addKey(block, keySchedule[12]);\0a\0a block = mixCol(block, IMIXTABLE);\0a\0a\0a\0a --round 2\0a\0a block = shiftRow(block, IROW_SHIFT);\0a\0a block = byteSub(block, ISBOX);\0a\0a block = addKey(block, keySchedule[11]);\0a\0a block = mixCol(block, IMIXTABLE);\0a\0a\0a\0a --round 3\0a\0a block = shiftRow(block, IROW_SHIFT);\0a\0a block = byteSub(block, ISBOX);\0a\0a block = addKey(block, keySchedule[10]);\0a\0a block = mixCol(block, IMIXTABLE);\0a\0a\0a\0a --round 4\0a\0a block = shiftRow(block, IROW_SHIFT);\0a\0a block = byteSub(block, ISBOX);\0a\0a block = addKey(block, keySchedule[9]);\0a\0a block = mixCol(block, IMIXTABLE);\0a\0a\0a\0a --round 5\0a\0a block = shiftRow(block, IROW_SHIFT);\0a\0a block = byteSub(block, ISBOX);\0a\0a block = addKey(block, keySchedule[8]);\0a\0a block = mixCol(block, IMIXTABLE);\0a\0a\0a\0a --round 6\0a\0a block = shiftRow(block, IROW_SHIFT);\0a\0a block = byteSub(block, ISBOX);\0a\0a block = addKey(block, keySchedule[7]);\0a\0a block = mixCol(block, IMIXTABLE);\0a\0a\0a\0a --round 7\0a\0a block = shiftRow(block, IROW_SHIFT);\0a\0a block = byteSub(block, ISBOX);\0a\0a block = addKey(block, keySchedule[6]);\0a\0a block = mixCol(block, IMIXTABLE);\0a\0a\0a\0a --round 8\0a\0a block = shiftRow(block, IROW_SHIFT);\0a\0a block = byteSub(block, ISBOX);\0a\0a block = addKey(block, keySchedule[5]);\0a\0a block = mixCol(block, IMIXTABLE);\0a\0a\0a\0a --round 9\0a\0a block = shiftRow(block, IROW_SHIFT);\0a\0a block = byteSub(block, ISBOX);\0a\0a block = addKey(block, keySchedule[4]);\0a\0a block = mixCol(block, IMIXTABLE);\0a\0a\0a\0a --round 10\0a\0a block = shiftRow(block, IROW_SHIFT);\0a\0a block = byteSub(block, ISBOX);\0a\0a block = addKey(block, keySchedule[3]);\0a\0a block = mixCol(block, IMIXTABLE);\0a\0a\0a\0a --round 11\0a\0a block = shiftRow(block, IROW_SHIFT);\0a\0a block = byteSub(block, ISBOX);\0a\0a block = addKey(block, keySchedule[2]);\0a\0a block = mixCol(block, IMIXTABLE);\0a\0a\0a\0a --round 12\0a\0a block = shiftRow(block, IROW_SHIFT);\0a\0a block = byteSub(block, ISBOX);\0a\0a block = addKey(block, keySchedule[1]);\0a\0a\0a\0a return block;\0a\0aend\0a\0a\0a\0areturn AES;\00\00\00\00\00\00local Array = require(\22.crypto.util.array\22);\0a\0alocal Bit = require(\22.crypto.util.bit\22);\0a\0a\0a\0alocal XOR = Bit.bxor;\0a\0a\0a\0alocal SBOX = {\0a\0a [0] = 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,\0a\0a 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,\0a\0a 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,\0a\0a 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,\0a\0a 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,\0a\0a 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,\0a\0a 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,\0a\0a 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,\0a\0a 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,\0a\0a 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,\0a\0a 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,\0a\0a 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,\0a\0a 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,\0a\0a 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,\0a\0a 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,\0a\0a 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16};\0a\0a\0a\0alocal ISBOX = {\0a\0a [0] = 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,\0a\0a 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,\0a\0a 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,\0a\0a 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,\0a\0a 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,\0a\0a 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,\0a\0a 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,\0a\0a 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,\0a\0a 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,\0a\0a 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,\0a\0a 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,\0a\0a 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,\0a\0a 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,\0a\0a 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,\0a\0a 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,\0a\0a 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D};\0a\0a\0a\0alocal ROW_SHIFT = { 1, 6, 11, 16, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, };\0a\0alocal IROW_SHIFT = { 1, 14, 11, 8, 5, 2, 15, 12, 9, 6, 3, 16, 13, 10, 7, 4, };\0a\0a\0a\0alocal ETABLE = {\0a\0a [0] = 0x01, 0x03, 0x05, 0x0F, 0x11, 0x33, 0x55, 0xFF, 0x1A, 0x2E, 0x72, 0x96, 0xA1, 0xF8, 0x13, 0x35,\0a\0a 0x5F, 0xE1, 0x38, 0x48, 0xD8, 0x73, 0x95, 0xA4, 0xF7, 0x02, 0x06, 0x0A, 0x1E, 0x22, 0x66, 0xAA,\0a\0a 0xE5, 0x34, 0x5C, 0xE4, 0x37, 0x59, 0xEB, 0x26, 0x6A, 0xBE, 0xD9, 0x70, 0x90, 0xAB, 0xE6, 0x31,\0a\0a 0x53, 0xF5, 0x04, 0x0C, 0x14, 0x3C, 0x44, 0xCC, 0x4F, 0xD1, 0x68, 0xB8, 0xD3, 0x6E, 0xB2, 0xCD,\0a\0a 0x4C, 0xD4, 0x67, 0xA9, 0xE0, 0x3B, 0x4D, 0xD7, 0x62, 0xA6, 0xF1, 0x08, 0x18, 0x28, 0x78, 0x88,\0a\0a 0x83, 0x9E, 0xB9, 0xD0, 0x6B, 0xBD, 0xDC, 0x7F, 0x81, 0x98, 0xB3, 0xCE, 0x49, 0xDB, 0x76, 0x9A,\0a\0a 0xB5, 0xC4, 0x57, 0xF9, 0x10, 0x30, 0x50, 0xF0, 0x0B, 0x1D, 0x27, 0x69, 0xBB, 0xD6, 0x61, 0xA3,\0a\0a 0xFE, 0x19, 0x2B, 0x7D, 0x87, 0x92, 0xAD, 0xEC, 0x2F, 0x71, 0x93, 0xAE, 0xE9, 0x20, 0x60, 0xA0,\0a\0a 0xFB, 0x16, 0x3A, 0x4E, 0xD2, 0x6D, 0xB7, 0xC2, 0x5D, 0xE7, 0x32, 0x56, 0xFA, 0x15, 0x3F, 0x41,\0a\0a 0xC3, 0x5E, 0xE2, 0x3D, 0x47, 0xC9, 0x40, 0xC0, 0x5B, 0xED, 0x2C, 0x74, 0x9C, 0xBF, 0xDA, 0x75,\0a\0a 0x9F, 0xBA, 0xD5, 0x64, 0xAC, 0xEF, 0x2A, 0x7E, 0x82, 0x9D, 0xBC, 0xDF, 0x7A, 0x8E, 0x89, 0x80,\0a\0a 0x9B, 0xB6, 0xC1, 0x58, 0xE8, 0x23, 0x65, 0xAF, 0xEA, 0x25, 0x6F, 0xB1, 0xC8, 0x43, 0xC5, 0x54,\0a\0a 0xFC, 0x1F, 0x21, 0x63, 0xA5, 0xF4, 0x07, 0x09, 0x1B, 0x2D, 0x77, 0x99, 0xB0, 0xCB, 0x46, 0xCA,\0a\0a 0x45, 0xCF, 0x4A, 0xDE, 0x79, 0x8B, 0x86, 0x91, 0xA8, 0xE3, 0x3E, 0x42, 0xC6, 0x51, 0xF3, 0x0E,\0a\0a 0x12, 0x36, 0x5A, 0xEE, 0x29, 0x7B, 0x8D, 0x8C, 0x8F, 0x8A, 0x85, 0x94, 0xA7, 0xF2, 0x0D, 0x17,\0a\0a 0x39, 0x4B, 0xDD, 0x7C, 0x84, 0x97, 0xA2, 0xFD, 0x1C, 0x24, 0x6C, 0xB4, 0xC7, 0x52, 0xF6, 0x01};\0a\0a\0a\0alocal LTABLE = {\0a\0a [0] = 0x00, 0x00, 0x19, 0x01, 0x32, 0x02, 0x1A, 0xC6, 0x4B, 0xC7, 0x1B, 0x68, 0x33, 0xEE, 0xDF, 0x03,\0a\0a 0x64, 0x04, 0xE0, 0x0E, 0x34, 0x8D, 0x81, 0xEF, 0x4C, 0x71, 0x08, 0xC8, 0xF8, 0x69, 0x1C, 0xC1,\0a\0a 0x7D, 0xC2, 0x1D, 0xB5, 0xF9, 0xB9, 0x27, 0x6A, 0x4D, 0xE4, 0xA6, 0x72, 0x9A, 0xC9, 0x09, 0x78,\0a\0a 0x65, 0x2F, 0x8A, 0x05, 0x21, 0x0F, 0xE1, 0x24, 0x12, 0xF0, 0x82, 0x45, 0x35, 0x93, 0xDA, 0x8E,\0a\0a 0x96, 0x8F, 0xDB, 0xBD, 0x36, 0xD0, 0xCE, 0x94, 0x13, 0x5C, 0xD2, 0xF1, 0x40, 0x46, 0x83, 0x38,\0a\0a 0x66, 0xDD, 0xFD, 0x30, 0xBF, 0x06, 0x8B, 0x62, 0xB3, 0x25, 0xE2, 0x98, 0x22, 0x88, 0x91, 0x10,\0a\0a 0x7E, 0x6E, 0x48, 0xC3, 0xA3, 0xB6, 0x1E, 0x42, 0x3A, 0x6B, 0x28, 0x54, 0xFA, 0x85, 0x3D, 0xBA,\0a\0a 0x2B, 0x79, 0x0A, 0x15, 0x9B, 0x9F, 0x5E, 0xCA, 0x4E, 0xD4, 0xAC, 0xE5, 0xF3, 0x73, 0xA7, 0x57,\0a\0a 0xAF, 0x58, 0xA8, 0x50, 0xF4, 0xEA, 0xD6, 0x74, 0x4F, 0xAE, 0xE9, 0xD5, 0xE7, 0xE6, 0xAD, 0xE8,\0a\0a 0x2C, 0xD7, 0x75, 0x7A, 0xEB, 0x16, 0x0B, 0xF5, 0x59, 0xCB, 0x5F, 0xB0, 0x9C, 0xA9, 0x51, 0xA0,\0a\0a 0x7F, 0x0C, 0xF6, 0x6F, 0x17, 0xC4, 0x49, 0xEC, 0xD8, 0x43, 0x1F, 0x2D, 0xA4, 0x76, 0x7B, 0xB7,\0a\0a 0xCC, 0xBB, 0x3E, 0x5A, 0xFB, 0x60, 0xB1, 0x86, 0x3B, 0x52, 0xA1, 0x6C, 0xAA, 0x55, 0x29, 0x9D,\0a\0a 0x97, 0xB2, 0x87, 0x90, 0x61, 0xBE, 0xDC, 0xFC, 0xBC, 0x95, 0xCF, 0xCD, 0x37, 0x3F, 0x5B, 0xD1,\0a\0a 0x53, 0x39, 0x84, 0x3C, 0x41, 0xA2, 0x6D, 0x47, 0x14, 0x2A, 0x9E, 0x5D, 0x56, 0xF2, 0xD3, 0xAB,\0a\0a 0x44, 0x11, 0x92, 0xD9, 0x23, 0x20, 0x2E, 0x89, 0xB4, 0x7C, 0xB8, 0x26, 0x77, 0x99, 0xE3, 0xA5,\0a\0a 0x67, 0x4A, 0xED, 0xDE, 0xC5, 0x31, 0xFE, 0x18, 0x0D, 0x63, 0x8C, 0x80, 0xC0, 0xF7, 0x70, 0x07};\0a\0a\0a\0alocal MIXTABLE = {\0a\0a 0x02, 0x03, 0x01, 0x01,\0a\0a 0x01, 0x02, 0x03, 0x01,\0a\0a 0x01, 0x01, 0x02, 0x03,\0a\0a 0x03, 0x01, 0x01, 0x02};\0a\0a\0a\0alocal IMIXTABLE = {\0a\0a 0x0E, 0x0B, 0x0D, 0x09,\0a\0a 0x09, 0x0E, 0x0B, 0x0D,\0a\0a 0x0D, 0x09, 0x0E, 0x0B,\0a\0a 0x0B, 0x0D, 0x09, 0x0E};\0a\0a\0a\0alocal RCON = {\0a\0a[0] = 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,\0a\0a0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,\0a\0a0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,\0a\0a0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,\0a\0a0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,\0a\0a0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,\0a\0a0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b,\0a\0a0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,\0a\0a0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,\0a\0a0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,\0a\0a0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,\0a\0a0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,\0a\0a0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,\0a\0a0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,\0a\0a0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,\0a\0a0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d};\0a\0a\0a\0a\0a\0alocal GMUL = function(A, B)\0a\0a if(A == 0x01) then return B; end\0a\0a if(B == 0x01) then return A; end\0a\0a if(A == 0x00) then return 0; end\0a\0a if(B == 0x00) then return 0; end\0a\0a\0a\0a local LA = LTABLE[A];\0a\0a local LB = LTABLE[B];\0a\0a\0a\0a local sum = LA + LB;\0a\0a if (sum > 0xFF) then sum = sum - 0xFF; end\0a\0a\0a\0a return ETABLE[sum];\0a\0aend\0a\0a\0a\0alocal byteSub = Array.substitute;\0a\0a\0a\0alocal shiftRow = Array.permute;\0a\0a\0a\0alocal mixCol = function(i, mix)\0a\0a local out = {};\0a\0a\0a\0a local a, b, c, d;\0a\0a\0a\0a a = GMUL(i[ 1], mix[ 1]);\0a\0a b = GMUL(i[ 2], mix[ 2]);\0a\0a c = GMUL(i[ 3], mix[ 3]);\0a\0a d = GMUL(i[ 4], mix[ 4]);\0a\0a out[ 1] = XOR(XOR(a, b), XOR(c, d));\0a\0a a = GMUL(i[ 1], mix[ 5]);\0a\0a b = GMUL(i[ 2], mix[ 6]);\0a\0a c = GMUL(i[ 3], mix[ 7]);\0a\0a d = GMUL(i[ 4], mix[ 8]);\0a\0a out[ 2] = XOR(XOR(a, b), XOR(c, d));\0a\0a a = GMUL(i[ 1], mix[ 9]);\0a\0a b = GMUL(i[ 2], mix[10]);\0a\0a c = GMUL(i[ 3], mix[11]);\0a\0a d = GMUL(i[ 4], mix[12]);\0a\0a out[ 3] = XOR(XOR(a, b), XOR(c, d));\0a\0a a = GMUL(i[ 1], mix[13]);\0a\0a b = GMUL(i[ 2], mix[14]);\0a\0a c = GMUL(i[ 3], mix[15]);\0a\0a d = GMUL(i[ 4], mix[16]);\0a\0a out[ 4] = XOR(XOR(a, b), XOR(c, d));\0a\0a\0a\0a\0a\0a a = GMUL(i[ 5], mix[ 1]);\0a\0a b = GMUL(i[ 6], mix[ 2]);\0a\0a c = GMUL(i[ 7], mix[ 3]);\0a\0a d = GMUL(i[ 8], mix[ 4]);\0a\0a out[ 5] = XOR(XOR(a, b), XOR(c, d));\0a\0a a = GMUL(i[ 5], mix[ 5]);\0a\0a b = GMUL(i[ 6], mix[ 6]);\0a\0a c = GMUL(i[ 7], mix[ 7]);\0a\0a d = GMUL(i[ 8], mix[ 8]);\0a\0a out[ 6] = XOR(XOR(a, b), XOR(c, d));\0a\0a a = GMUL(i[ 5], mix[ 9]);\0a\0a b = GMUL(i[ 6], mix[10]);\0a\0a c = GMUL(i[ 7], mix[11]);\0a\0a d = GMUL(i[ 8], mix[12]);\0a\0a out[ 7] = XOR(XOR(a, b), XOR(c, d));\0a\0a a = GMUL(i[ 5], mix[13]);\0a\0a b = GMUL(i[ 6], mix[14]);\0a\0a c = GMUL(i[ 7], mix[15]);\0a\0a d = GMUL(i[ 8], mix[16]);\0a\0a out[ 8] = XOR(XOR(a, b), XOR(c, d));\0a\0a\0a\0a\0a\0a a = GMUL(i[ 9], mix[ 1]);\0a\0a b = GMUL(i[10], mix[ 2]);\0a\0a c = GMUL(i[11], mix[ 3]);\0a\0a d = GMUL(i[12], mix[ 4]);\0a\0a out[ 9] = XOR(XOR(a, b), XOR(c, d));\0a\0a a = GMUL(i[ 9], mix[ 5]);\0a\0a b = GMUL(i[10], mix[ 6]);\0a\0a c = GMUL(i[11], mix[ 7]);\0a\0a d = GMUL(i[12], mix[ 8]);\0a\0a out[10] = XOR(XOR(a, b), XOR(c, d));\0a\0a a = GMUL(i[ 9], mix[ 9]);\0a\0a b = GMUL(i[10], mix[10]);\0a\0a c = GMUL(i[11], mix[11]);\0a\0a d = GMUL(i[12], mix[12]);\0a\0a out[11] = XOR(XOR(a, b), XOR(c, d));\0a\0a a = GMUL(i[ 9], mix[13]);\0a\0a b = GMUL(i[10], mix[14]);\0a\0a c = GMUL(i[11], mix[15]);\0a\0a d = GMUL(i[12], mix[16]);\0a\0a out[12] = XOR(XOR(a, b), XOR(c, d));\0a\0a\0a\0a\0a\0a a = GMUL(i[13], mix[ 1]);\0a\0a b = GMUL(i[14], mix[ 2]);\0a\0a c = GMUL(i[15], mix[ 3]);\0a\0a d = GMUL(i[16], mix[ 4]);\0a\0a out[13] = XOR(XOR(a, b), XOR(c, d));\0a\0a a = GMUL(i[13], mix[ 5]);\0a\0a b = GMUL(i[14], mix[ 6]);\0a\0a c = GMUL(i[15], mix[ 7]);\0a\0a d = GMUL(i[16], mix[ 8]);\0a\0a out[14] = XOR(XOR(a, b), XOR(c, d));\0a\0a a = GMUL(i[13], mix[ 9]);\0a\0a b = GMUL(i[14], mix[10]);\0a\0a c = GMUL(i[15], mix[11]);\0a\0a d = GMUL(i[16], mix[12]);\0a\0a out[15] = XOR(XOR(a, b), XOR(c, d));\0a\0a a = GMUL(i[13], mix[13]);\0a\0a b = GMUL(i[14], mix[14]);\0a\0a c = GMUL(i[15], mix[15]);\0a\0a d = GMUL(i[16], mix[16]);\0a\0a out[16] = XOR(XOR(a, b), XOR(c, d));\0a\0a\0a\0a return out;\0a\0aend\0a\0a\0a\0alocal keyRound = function(key, round)\0a\0a local i = (round - 1) * 32;\0a\0a local out = key;\0a\0a\0a\0a out[33 + i] = XOR(key[ 1 + i], XOR(SBOX[key[30 + i]], RCON[round]));\0a\0a out[34 + i] = XOR(key[ 2 + i], SBOX[key[31 + i]]);\0a\0a out[35 + i] = XOR(key[ 3 + i], SBOX[key[32 + i]]);\0a\0a out[36 + i] = XOR(key[ 4 + i], SBOX[key[29 + i]]);\0a\0a\0a\0a out[37 + i] = XOR(out[33 + i], key[ 5 + i]);\0a\0a out[38 + i] = XOR(out[34 + i], key[ 6 + i]);\0a\0a out[39 + i] = XOR(out[35 + i], key[ 7 + i]);\0a\0a out[40 + i] = XOR(out[36 + i], key[ 8 + i]);\0a\0a\0a\0a out[41 + i] = XOR(out[37 + i], key[ 9 + i]);\0a\0a out[42 + i] = XOR(out[38 + i], key[10 + i]);\0a\0a out[43 + i] = XOR(out[39 + i], key[11 + i]);\0a\0a out[44 + i] = XOR(out[40 + i], key[12 + i]);\0a\0a\0a\0a out[45 + i] = XOR(out[41 + i], key[13 + i]);\0a\0a out[46 + i] = XOR(out[42 + i], key[14 + i]);\0a\0a out[47 + i] = XOR(out[43 + i], key[15 + i]);\0a\0a out[48 + i] = XOR(out[44 + i], key[16 + i]);\0a\0a\0a\0a\0a\0a out[49 + i] = XOR(SBOX[out[45 + i]], key[17 + i]);\0a\0a out[50 + i] = XOR(SBOX[out[46 + i]], key[18 + i]);\0a\0a out[51 + i] = XOR(SBOX[out[47 + i]], key[19 + i]);\0a\0a out[52 + i] = XOR(SBOX[out[48 + i]], key[20 + i]);\0a\0a\0a\0a out[53 + i] = XOR(out[49 + i], key[21 + i]);\0a\0a out[54 + i] = XOR(out[50 + i], key[22 + i]);\0a\0a out[55 + i] = XOR(out[51 + i], key[23 + i]);\0a\0a out[56 + i] = XOR(out[52 + i], key[24 + i]);\0a\0a\0a\0a out[57 + i] = XOR(out[53 + i], key[25 + i]);\0a\0a out[58 + i] = XOR(out[54 + i], key[26 + i]);\0a\0a out[59 + i] = XOR(out[55 + i], key[27 + i]);\0a\0a out[60 + i] = XOR(out[56 + i], key[28 + i]);\0a\0a\0a\0a out[61 + i] = XOR(out[57 + i], key[29 + i]);\0a\0a out[62 + i] = XOR(out[58 + i], key[30 + i]);\0a\0a out[63 + i] = XOR(out[59 + i], key[31 + i]);\0a\0a out[64 + i] = XOR(out[60 + i], key[32 + i]);\0a\0a\0a\0a return out;\0a\0aend\0a\0a\0a\0alocal keyExpand = function(key)\0a\0a local bytes = Array.copy(key);\0a\0a\0a\0a for i = 1, 7 do\0a\0a keyRound(bytes, i);\0a\0a end\0a\0a\0a\0a local keys = {};\0a\0a\0a\0a keys[ 1] = Array.slice(bytes, 1, 16);\0a\0a keys[ 2] = Array.slice(bytes, 17, 32);\0a\0a keys[ 3] = Array.slice(bytes, 33, 48);\0a\0a keys[ 4] = Array.slice(bytes, 49, 64);\0a\0a keys[ 5] = Array.slice(bytes, 65, 80);\0a\0a keys[ 6] = Array.slice(bytes, 81, 96);\0a\0a keys[ 7] = Array.slice(bytes, 97, 112);\0a\0a keys[ 8] = Array.slice(bytes, 113, 128);\0a\0a keys[ 9] = Array.slice(bytes, 129, 144);\0a\0a keys[10] = Array.slice(bytes, 145, 160);\0a\0a keys[11] = Array.slice(bytes, 161, 176);\0a\0a keys[12] = Array.slice(bytes, 177, 192);\0a\0a keys[13] = Array.slice(bytes, 193, 208);\0a\0a keys[14] = Array.slice(bytes, 209, 224);\0a\0a keys[15] = Array.slice(bytes, 225, 240);\0a\0a\0a\0a return keys;\0a\0a\0a\0aend\0a\0a\0a\0alocal addKey = Array.XOR;\0a\0a\0a\0a\0a\0a\0a\0alocal AES = {};\0a\0a\0a\0aAES.blockSize = 16;\0a\0a\0a\0aAES.encrypt = function(key, block)\0a\0a\0a\0a local keySchedule = keyExpand(key);\0a\0a\0a\0a --round 0\0a\0a block = addKey(block, keySchedule[1]);\0a\0a\0a\0a --round 1\0a\0a block = byteSub(block, SBOX);\0a\0a block = shiftRow(block, ROW_SHIFT);\0a\0a block = mixCol(block, MIXTABLE);\0a\0a block = addKey(block, keySchedule[2]);\0a\0a\0a\0a --round 2\0a\0a block = byteSub(block, SBOX);\0a\0a block = shiftRow(block, ROW_SHIFT);\0a\0a block = mixCol(block, MIXTABLE);\0a\0a block = addKey(block, keySchedule[3]);\0a\0a\0a\0a --round 3\0a\0a block = byteSub(block, SBOX);\0a\0a block = shiftRow(block, ROW_SHIFT);\0a\0a block = mixCol(block, MIXTABLE);\0a\0a block = addKey(block, keySchedule[4]);\0a\0a\0a\0a --round 4\0a\0a block = byteSub(block, SBOX);\0a\0a block = shiftRow(block, ROW_SHIFT);\0a\0a block = mixCol(block, MIXTABLE);\0a\0a block = addKey(block, keySchedule[5]);\0a\0a\0a\0a --round 5\0a\0a block = byteSub(block, SBOX);\0a\0a block = shiftRow(block, ROW_SHIFT);\0a\0a block = mixCol(block, MIXTABLE);\0a\0a block = addKey(block, keySchedule[6]);\0a\0a\0a\0a --round 6\0a\0a block = byteSub(block, SBOX);\0a\0a block = shiftRow(block, ROW_SHIFT);\0a\0a block = mixCol(block, MIXTABLE);\0a\0a block = addKey(block, keySchedule[7]);\0a\0a\0a\0a --round 7\0a\0a block = byteSub(block, SBOX);\0a\0a block = shiftRow(block, ROW_SHIFT);\0a\0a block = mixCol(block, MIXTABLE);\0a\0a block = addKey(block, keySchedule[8]);\0a\0a\0a\0a --round 8\0a\0a block = byteSub(block, SBOX);\0a\0a block = shiftRow(block, ROW_SHIFT);\0a\0a block = mixCol(block, MIXTABLE);\0a\0a block = addKey(block, keySchedule[9]);\0a\0a\0a\0a --round 9\0a\0a block = byteSub(block, SBOX);\0a\0a block = shiftRow(block, ROW_SHIFT);\0a\0a block = mixCol(block, MIXTABLE);\0a\0a block = addKey(block, keySchedule[10]);\0a\0a\0a\0a --round 10\0a\0a block = byteSub(block, SBOX);\0a\0a block = shiftRow(block, ROW_SHIFT);\0a\0a block = mixCol(block, MIXTABLE);\0a\0a block = addKey(block, keySchedule[11]);\0a\0a\0a\0a --round 11\0a\0a block = byteSub(block, SBOX);\0a\0a block = shiftRow(block, ROW_SHIFT);\0a\0a block = mixCol(block, MIXTABLE);\0a\0a block = addKey(block, keySchedule[12]);\0a\0a\0a\0a --round 12\0a\0a block = byteSub(block, SBOX);\0a\0a block = shiftRow(block, ROW_SHIFT);\0a\0a block = mixCol(block, MIXTABLE);\0a\0a block = addKey(block, keySchedule[13]);\0a\0a\0a\0a --round 13\0a\0a block = byteSub(block, SBOX);\0a\0a block = shiftRow(block, ROW_SHIFT);\0a\0a block = mixCol(block, MIXTABLE);\0a\0a block = addKey(block, keySchedule[14]);\0a\0a\0a\0a --round 14\0a\0a block = byteSub(block, SBOX);\0a\0a block = shiftRow(block, ROW_SHIFT);\0a\0a block = addKey(block, keySchedule[15]);\0a\0a\0a\0a return block;\0a\0a\0a\0aend\0a\0a\0a\0aAES.decrypt = function(key, block)\0a\0a\0a\0a local keySchedule = keyExpand(key);\0a\0a\0a\0a --round 0\0a\0a block = addKey(block, keySchedule[15]);\0a\0a\0a\0a --round 1\0a\0a block = shiftRow(block, IROW_SHIFT);\0a\0a block = byteSub(block, ISBOX);\0a\0a block = addKey(block, keySchedule[14]);\0a\0a block = mixCol(block, IMIXTABLE);\0a\0a\0a\0a --round 2\0a\0a block = shiftRow(block, IROW_SHIFT);\0a\0a block = byteSub(block, ISBOX);\0a\0a block = addKey(block, keySchedule[13]);\0a\0a block = mixCol(block, IMIXTABLE);\0a\0a\0a\0a --round 3\0a\0a block = shiftRow(block, IROW_SHIFT);\0a\0a block = byteSub(block, ISBOX);\0a\0a block = addKey(block, keySchedule[12]);\0a\0a block = mixCol(block, IMIXTABLE);\0a\0a\0a\0a --round 4\0a\0a block = shiftRow(block, IROW_SHIFT);\0a\0a block = byteSub(block, ISBOX);\0a\0a block = addKey(block, keySchedule[11]);\0a\0a block = mixCol(block, IMIXTABLE);\0a\0a\0a\0a --round 5\0a\0a block = shiftRow(block, IROW_SHIFT);\0a\0a block = byteSub(block, ISBOX);\0a\0a block = addKey(block, keySchedule[10]);\0a\0a block = mixCol(block, IMIXTABLE);\0a\0a\0a\0a --round 6\0a\0a block = shiftRow(block, IROW_SHIFT);\0a\0a block = byteSub(block, ISBOX);\0a\0a block = addKey(block, keySchedule[9]);\0a\0a block = mixCol(block, IMIXTABLE);\0a\0a\0a\0a --round 7\0a\0a block = shiftRow(block, IROW_SHIFT);\0a\0a block = byteSub(block, ISBOX);\0a\0a block = addKey(block, keySchedule[8]);\0a\0a block = mixCol(block, IMIXTABLE);\0a\0a\0a\0a --round 8\0a\0a block = shiftRow(block, IROW_SHIFT);\0a\0a block = byteSub(block, ISBOX);\0a\0a block = addKey(block, keySchedule[7]);\0a\0a block = mixCol(block, IMIXTABLE);\0a\0a\0a\0a --round 9\0a\0a block = shiftRow(block, IROW_SHIFT);\0a\0a block = byteSub(block, ISBOX);\0a\0a block = addKey(block, keySchedule[6]);\0a\0a block = mixCol(block, IMIXTABLE);\0a\0a\0a\0a --round 10\0a\0a block = shiftRow(block, IROW_SHIFT);\0a\0a block = byteSub(block, ISBOX);\0a\0a block = addKey(block, keySchedule[5]);\0a\0a block = mixCol(block, IMIXTABLE);\0a\0a\0a\0a --round 11\0a\0a block = shiftRow(block, IROW_SHIFT);\0a\0a block = byteSub(block, ISBOX);\0a\0a block = addKey(block, keySchedule[4]);\0a\0a block = mixCol(block, IMIXTABLE);\0a\0a\0a\0a --round 12\0a\0a block = shiftRow(block, IROW_SHIFT);\0a\0a block = byteSub(block, ISBOX);\0a\0a block = addKey(block, keySchedule[3]);\0a\0a block = mixCol(block, IMIXTABLE);\0a\0a\0a\0a --round 13\0a\0a block = shiftRow(block, IROW_SHIFT);\0a\0a block = byteSub(block, ISBOX);\0a\0a block = addKey(block, keySchedule[2]);\0a\0a block = mixCol(block, IMIXTABLE);\0a\0a\0a\0a --round 14\0a\0a block = shiftRow(block, IROW_SHIFT);\0a\0a block = byteSub(block, ISBOX);\0a\0a block = addKey(block, keySchedule[1]);\0a\0a\0a\0a return block;\0a\0aend\0a\0a\0a\0areturn AES;\00\00\00\00local issac = require(\22.crypto.cipher.issac\22)\0a\0alocal morus = require(\22.crypto.cipher.morus\22)\0a\0alocal aes = require(\22.crypto.cipher.aes\22)\0a\0alocal norx = require(\22.crypto.cipher.norx\22)\0a\0a\0a\0alocal cipher = {\0a\0a _version = \220.0.1\22,\0a\0a issac = issac,\0a\0a morus = morus,\0a\0a aes = aes,\0a\0a norx = norx\0a\0a};\0a\0a\0a\0areturn cipher\00local Hex = require(\22.crypto.util.hex\22);\0a\0a\0a\0a-- External Results\0a\0alocal randRsl = {};\0a\0alocal randCnt = 0;\0a\0a\0a\0a-- Internal State\0a\0alocal mm = {};\0a\0alocal aa,bb,cc = 0,0,0;\0a\0a\0a\0a-- Cap to maintain 32 bit maths\0a\0alocal cap = 0x100000000;\0a\0a\0a\0a-- CipherMode\0a\0alocal ENCRYPT = 1;\0a\0alocal DECRYPT = 2;\0a\0a\0a\0alocal function isaac()\0a\0a cc = ( cc + 1 ) % cap; -- cc just gets incremented once per 256 results\0a\0a bb = ( bb + cc ) % cap; -- then combined with bb\0a\0a\0a\0a for i = 0,255 do\0a\0a local x = mm[i];\0a\0a local y;\0a\0a local imod = i % 4;\0a\0a if imod == 0 then aa = aa ~ (aa << 13);\0a\0a elseif imod == 1 then aa = aa ~ (aa >> 6);\0a\0a elseif imod == 2 then aa = aa ~ (aa << 2);\0a\0a elseif imod == 3 then aa = aa ~ (aa >> 16);\0a\0a end\0a\0a aa = ( mm[(i+128)%256] + aa ) % cap;\0a\0a y = ( mm[(x>>2) % 256] + aa + bb ) % cap;\0a\0a mm[i] = y;\0a\0a bb = ( mm[(y>>10)%256] + x ) % cap;\0a\0a randRsl[i] = bb;\0a\0a end\0a\0a\0a\0a randCnt = 0; -- Prepare to use the first set of results.\0a\0a\0a\0aend\0a\0a\0a\0alocal function mix(a)\0a\0a a[0] = ( a[0] ~ ( a[1] << 11 ) ) % cap; a[3] = ( a[3] + a[0] ) % cap; a[1] = ( a[1] + a[2] ) % cap;\0a\0a a[1] = ( a[1] ~ ( a[2] >> 2 ) ) % cap; a[4] = ( a[4] + a[1] ) % cap; a[2] = ( a[2] + a[3] ) % cap;\0a\0a a[2] = ( a[2] ~ ( a[3] << 8 ) ) % cap; a[5] = ( a[5] + a[2] ) % cap; a[3] = ( a[3] + a[4] ) % cap;\0a\0a a[3] = ( a[3] ~ ( a[4] >> 16 ) ) % cap; a[6] = ( a[6] + a[3] ) % cap; a[4] = ( a[4] + a[5] ) % cap;\0a\0a a[4] = ( a[4] ~ ( a[5] << 10 ) ) % cap; a[7] = ( a[7] + a[4] ) % cap; a[5] = ( a[5] + a[6] ) % cap;\0a\0a a[5] = ( a[5] ~ ( a[6] >> 4 ) ) % cap; a[0] = ( a[0] + a[5] ) % cap; a[6] = ( a[6] + a[7] ) % cap;\0a\0a a[6] = ( a[6] ~ ( a[7] << 8 ) ) % cap; a[1] = ( a[1] + a[6] ) % cap; a[7] = ( a[7] + a[0] ) % cap;\0a\0a a[7] = ( a[7] ~ ( a[0] >> 9 ) ) % cap; a[2] = ( a[2] + a[7] ) % cap; a[0] = ( a[0] + a[1] ) % cap;\0a\0aend\0a\0a\0a\0alocal function randInit(flag)\0a\0a\0a\0a -- The golden ratio in 32 bit\0a\0a -- math.floor((((math.sqrt(5)+1)/2)%1)*2^32) == 2654435769 == 0x9e3779b9\0a\0a local a = { [0] = 0x9e3779b9, 0x9e3779b9, 0x9e3779b9, 0x9e3779b9, 0x9e3779b9, 0x9e3779b9, 0x9e3779b9, 0x9e3779b9, };\0a\0a\0a\0a aa,bb,cc = 0,0,0;\0a\0a\0a\0a for i = 1,4 do mix(a) end -- Scramble it.\0a\0a\0a\0a for i = 0,255,8 do -- Fill in mm[] with messy stuff.\0a\0a if flag then -- Use all the information in the seed.\0a\0a for j = 0,7 do\0a\0a a[j] = ( a[j] + randRsl[i+j] ) % cap;\0a\0a end\0a\0a end\0a\0a mix(a);\0a\0a for j = 0,7 do\0a\0a mm[i+j] = a[j];\0a\0a end\0a\0a end\0a\0a\0a\0a if flag then\0a\0a -- Do a second pass to make all of the seed affect all of mm.\0a\0a for i = 0,255,8 do\0a\0a for j = 0,7 do\0a\0a a[j] = ( a[j] + mm[i+j] ) % cap;\0a\0a end\0a\0a mix(a);\0a\0a for j = 0,7 do\0a\0a mm[i+j] = a[j];\0a\0a end\0a\0a end\0a\0a end\0a\0a\0a\0a isaac(); -- Fill in the first set of results.\0a\0a randCnt = 0; -- Prepare to use the first set of results.\0a\0a\0a\0aend\0a\0a\0a\0a--- Seeds the ISAAC random number generator with the given seed.\0a\0a--- @param seed string - The seed to use for the random number generator.\0a\0a--- @param flag? boolean - Whether to use all the information in the seed. Defaults to true.\0a\0alocal function seedIsaac(seed, flag)\0a\0a local seedLength = #seed;\0a\0a for i = 0,255 do mm[i] = 0; end\0a\0a for i = 0,255 do randRsl[i] = seed:byte(i+1,i+1) or 0; end\0a\0a randInit(flag);\0a\0aend\0a\0a\0a\0a--- Retrieves a random number from the ISAAC random number generator\0a\0a--- @return number: The random number\0a\0alocal function getRandom()\0a\0a local result = randRsl[randCnt];\0a\0a randCnt = randCnt + 1;\0a\0a if randCnt > 255 then\0a\0a isaac();\0a\0a randCnt = 0;\0a\0a end\0a\0a return result;\0a\0aend\0a\0a\0a\0a--- Get a random 32-bit value within the specified range.\0a\0a--- @param min? number (optional) - The minimum value of the range. Defaults to 0.\0a\0a--- @param max? number (optional) - The maximum value of the range. Defaults to 2^31-1.\0a\0a--- @param seed? string (optional) - The seed to use for the random number generator.\0a\0a--- @return number: The random 32-bit value within the specified range.\0a\0alocal function random(min, max, seed)\0a\0a local min = min or 0;\0a\0a local max = max or 2^31-1;\0a\0a if seed then\0a\0a seedIsaac(seed, true);\0a\0a else\0a\0a seedIsaac(tostring(math.random(2^31-1)), false);\0a\0a end\0a\0a return (getRandom() % (max - min + 1)) + min;\0a\0aend\0a\0a\0a\0a\0a\0a--- Get a random character in printable ASCII range.\0a\0a--- @return number: The random character [32, 126].\0a\0alocal function getRandomChar()\0a\0a return getRandom() % 95 + 32;\0a\0aend\0a\0a\0a\0a-- Caesar-shift a character <shift> places: Generalized Vigenere\0a\0alocal function caesar(m, ch, shift, modulo, start)\0a\0a local n\0a\0a local si = 1\0a\0a if m == DECRYPT then shift = shift*-1 ; end\0a\0a n = (ch - start) + shift;\0a\0a if n < 0 then si,n = -1,n*-1 ; end\0a\0a n = ( n % modulo ) * si;\0a\0a if n < 0 then n = n + modulo ; end\0a\0a return start + n;\0a\0aend\0a\0a\0a\0a--- Encrypts a message using the ISSAC cipher algorithm.\0a\0a--- @param msg string - The message to be encrypted.\0a\0a--- @param key string - The key used for encryption.\0a\0a--- @returns table - A table containing the encrypted message in bytes, string, and hex formats.\0a\0alocal function encrypt(msg, key)\0a\0a seedIsaac(key, true);\0a\0a local msgLength = #msg;\0a\0a local destination = {};\0a\0a \0a\0a for i = 1, msgLength do \0a\0a destination[i] = string.char(caesar(1, msg:byte(i, i), getRandomChar(), 95, 32));\0a\0a end\0a\0a \0a\0a local encrypted = destination\0a\0a\0a\0a local public = {}\0a\0a public.asBytes = function()\0a\0a return encrypted\0a\0a end\0a\0a\0a\0a public.asString = function()\0a\0a return table.concat(encrypted)\0a\0a end\0a\0a\0a\0a public.asHex = function()\0a\0a return Hex.stringToHex(table.concat(encrypted))\0a\0a end\0a\0a\0a\0a return public\0a\0aend\0a\0a\0a\0a--- Decrypts an encrypted message using the ISSAC cipher algorithm.\0a\0a--- @param encrypted string - The encrypted message to be decrypted.\0a\0a--- @param key string - The key used for encryption.\0a\0a--- @returns string - The decrypted message.\0a\0alocal function decrypt(encrypted, key)\0a\0a seedIsaac(key, true);\0a\0a local msgLength = #encrypted;\0a\0a local destination = {};\0a\0a \0a\0a for i = 1, msgLength do \0a\0a destination[i] = string.char(caesar(2, encrypted:byte(i, i), getRandomChar(), 95, 32));\0a\0a end\0a\0a \0a\0a return table.concat(destination);\0a\0aend\0a\0a\0a\0areturn {\0a\0a seedIsaac = seedIsaac,\0a\0a getRandomChar = getRandomChar,\0a\0a random = random,\0a\0a getRandom = getRandom,\0a\0a encrypt = encrypt,\0a\0a decrypt = decrypt\0a\0a}\00\00\00\00local Hex = require(\22.crypto.util.hex\22);\0a\0a\0a\0alocal function state_update(s, m0, m1, m2, m3)\0a\0a\09local s00, s01, s02, s03 = s[1], s[2], s[3], s[4]\0a\0a\09local s10, s11, s12, s13 = s[5], s[6], s[7], s[8]\0a\0a\09local s20, s21, s22, s23 = s[9], s[10], s[11], s[12]\0a\0a\09local s30, s31, s32, s33 = s[13], s[14], s[15], s[16]\0a\0a\09local s40, s41, s42, s43 = s[17], s[18], s[19], s[20]\0a\0a\09local temp\0a\0a\0a\0a\09s00 = s00 ~ s30\0a\0a\09s01 = s01 ~ s31\0a\0a\09s02 = s02 ~ s32\0a\0a\09s03 = s03 ~ s33\0a\0a\0a\0a\09temp = s33\0a\0a\09s33 = s32\0a\0a\09s32 = s31\0a\0a\09s31 = s30\0a\0a\09s30 = temp\0a\0a\0a\0a\09s00 = s00 ~ s10 & s20\0a\0a\09s01 = s01 ~ s11 & s21\0a\0a\09s02 = s02 ~ s12 & s22\0a\0a\09s03 = s03 ~ s13 & s23\0a\0a\0a\0a\09s00 = (s00 << 13) | (s00 >> (64-13)) --n1\0a\0a\09s01 = (s01 << 13) | (s01 >> (64-13)) --n1\0a\0a\09s02 = (s02 << 13) | (s02 >> (64-13)) --n1\0a\0a\09s03 = (s03 << 13) | (s03 >> (64-13)) --n1\0a\0a\0a\0a\0a\0a\09s10 = s10 ~ m0\0a\0a\09s11 = s11 ~ m1\0a\0a\09s12 = s12 ~ m2\0a\0a\09s13 = s13 ~ m3\0a\0a\0a\0a\09s10 = s10 ~ s40\0a\0a\09s11 = s11 ~ s41\0a\0a\09s12 = s12 ~ s42\0a\0a\09s13 = s13 ~ s43\0a\0a\0a\0a\09temp = s43\0a\0a\09s43 = s41\0a\0a\09s41 = temp\0a\0a\0a\0a\09temp = s42\0a\0a\09s42 = s40\0a\0a\09s40 = temp\0a\0a\0a\0a\09s10 = s10 ~ (s20 & s30)\0a\0a\09s11 = s11 ~ (s21 & s31)\0a\0a\09s12 = s12 ~ (s22 & s32)\0a\0a\09s13 = s13 ~ (s23 & s33)\0a\0a\0a\0a\09s10 = (s10 << 46) | (s10 >> (64-46)) --n2\0a\0a\09s11 = (s11 << 46) | (s11 >> (64-46)) --n2\0a\0a\09s12 = (s12 << 46) | (s12 >> (64-46)) --n2\0a\0a\09s13 = (s13 << 46) | (s13 >> (64-46)) --n2\0a\0a\0a\0a\0a\0a\09s20 = s20 ~ m0\0a\0a\09s21 = s21 ~ m1\0a\0a\09s22 = s22 ~ m2\0a\0a\09s23 = s23 ~ m3\0a\0a\0a\0a\09s20 = s20 ~ s00\0a\0a\09s21 = s21 ~ s01\0a\0a\09s22 = s22 ~ s02\0a\0a\09s23 = s23 ~ s03\0a\0a\0a\0a\09temp = s00\0a\0a\09s00 = s01\0a\0a\09s01 = s02\0a\0a\09s02 = s03\0a\0a\09s03 = temp\0a\0a\0a\0a\09s20 = s20 ~ s30 & s40\0a\0a\09s21 = s21 ~ s31 & s41\0a\0a\09s22 = s22 ~ s32 & s42\0a\0a\09s23 = s23 ~ s33 & s43\0a\0a\0a\0a\09s20 = (s20 << 38) | (s20 >> (64-38)) --n3\0a\0a\09s21 = (s21 << 38) | (s21 >> (64-38)) --n3\0a\0a\09s22 = (s22 << 38) | (s22 >> (64-38)) --n3\0a\0a\09s23 = (s23 << 38) | (s23 >> (64-38)) --n3\0a\0a\0a\0a\0a\0a\09s30 = s30 ~ m0\0a\0a\09s31 = s31 ~ m1\0a\0a\09s32 = s32 ~ m2\0a\0a\09s33 = s33 ~ m3\0a\0a\0a\0a\09s30 = s30 ~ s10\0a\0a\09s31 = s31 ~ s11\0a\0a\09s32 = s32 ~ s12\0a\0a\09s33 = s33 ~ s13\0a\0a\0a\0a\09temp = s13\0a\0a\09s13 = s11\0a\0a\09s11 = temp\0a\0a\0a\0a\09temp = s12\0a\0a\09s12 = s10\0a\0a\09s10 = temp\0a\0a\0a\0a\09s30 = s30 ~ s40 & s00\0a\0a\09s31 = s31 ~ s41 & s01\0a\0a\09s32 = s32 ~ s42 & s02\0a\0a\09s33 = s33 ~ s43 & s03\0a\0a\0a\0a\09s30 = (s30 << 7) | (s30 >> (64-7)) --n4\0a\0a\09s31 = (s31 << 7) | (s31 >> (64-7)) --n4\0a\0a\09s32 = (s32 << 7) | (s32 >> (64-7)) --n4\0a\0a\09s33 = (s33 << 7) | (s33 >> (64-7)) --n4\0a\0a\0a\0a\0a\0a\09s40 = s40 ~ m0\0a\0a\09s41 = s41 ~ m1\0a\0a\09s42 = s42 ~ m2\0a\0a\09s43 = s43 ~ m3\0a\0a\0a\0a\09s40 = s40 ~ s20\0a\0a\09s41 = s41 ~ s21\0a\0a\09s42 = s42 ~ s22\0a\0a\09s43 = s43 ~ s23\0a\0a\0a\0a\09temp = s23\0a\0a\09s23 = s22\0a\0a\09s22 = s21\0a\0a\09s21 = s20\0a\0a\09s20 = temp\0a\0a\0a\0a\09s40 = s40 ~ s00 & s10\0a\0a\09s41 = s41 ~ s01 & s11\0a\0a\09s42 = s42 ~ s02 & s12\0a\0a\09s43 = s43 ~ s03 & s13\0a\0a\0a\0a\09s40 = (s40 << 4) | (s40 >> (64-4)) --n5\0a\0a\09s41 = (s41 << 4) | (s41 >> (64-4)) --n5\0a\0a\09s42 = (s42 << 4) | (s42 >> (64-4)) --n5\0a\0a\09s43 = (s43 << 4) | (s43 >> (64-4)) --n5\0a\0a\0a\0a\09-- update the state array\0a\0a\09s[1], s[2], s[3], s[4] = s00, s01, s02, s03\0a\0a\09s[5], s[6], s[7], s[8] = s10, s11, s12, s13\0a\0a\09s[9], s[10], s[11], s[12] = s20, s21, s22, s23\0a\0a\09s[13], s[14], s[15], s[16] = s30, s31, s32, s33\0a\0a\09s[17], s[18], s[19], s[20] = s40, s41, s42, s43\0a\0a\0a\0aend--state_update()\0a\0a\0a\0alocal function enc_aut_step(s, m0, m1, m2, m3)\0a\0a\09-- m0 s00 s11 s20 s30\0a\0a\09local c0 = m0 ~ s[1] ~ s[6] ~ (s[9] & s[13])\0a\0a\09-- m1 s01 s12 s21 s31\0a\0a\09local c1 = m1 ~ s[2] ~ s[7] ~ (s[10] & s[14])\0a\0a\09-- m2 s02 s13 s22 s32\0a\0a\09local c2 = m2 ~ s[3] ~ s[8] ~ (s[11] & s[15])\0a\0a\09-- m3 s03 s10 s23 s33\0a\0a\09local c3 = m3 ~ s[4] ~ s[5] ~ (s[12] & s[16])\0a\0a\09state_update(s, m0, m1, m2, m3)\0a\0a\09return c0, c1, c2, c3\0a\0aend\0a\0a\0a\0alocal function dec_aut_step(s, c0, c1, c2, c3, blen)\0a\0a\09-- mlen is the length of a last partial block\0a\0a\09-- mlen is absent/nil for full blocks\0a\0a\09-- return the decrypted block\0a\0a\09--\0a\0a\09-- m0 s00 s11 s20 s30\0a\0a\09local m0 = c0 ~ s[1] ~ s[6] ~ (s[9] & s[13])\0a\0a\09-- m1 s01 s12 s21 s31\0a\0a\09local m1 = c1 ~ s[2] ~ s[7] ~ (s[10] & s[14]) \0a\0a\09-- m2 s02 s13 s22 s32\0a\0a\09local m2 = c2 ~ s[3] ~ s[8] ~ (s[11] & s[15])\0a\0a\09-- m3 s03 s10 s23 s33\0a\0a\09local m3 = c3 ~ s[4] ~ s[5] ~ (s[12] & s[16])\0a\0a\09if blen then \0a\0a\09\09-- partial block => must adjust (m0, ...) before\0a\0a\09\09-- updating the state\0a\0a\09\09local mblk = string.pack(\22<I8I8I8I8\22, m0, m1, m2, m3):sub(1, blen) \0a\0a\09\09local blk = mblk .. string.rep('\5c0', 32 - blen)\0a\0a\09\09assert(#blk == 32, #blk)\0a\0a\09\09m0, m1, m2, m3 = string.unpack(\22<I8I8I8I8\22, blk)\0a\0a\09\09state_update(s, m0, m1, m2, m3)\0a\0a\09\09return mblk\0a\0a\09end\0a\0a\09-- full block\0a\0a\09state_update(s, m0, m1, m2, m3)\0a\0a\09return string.pack(\22<I8I8I8I8\22, m0, m1, m2, m3)\0a\0aend\0a\0a\0a\0a-- state init constants (fibonacci)\0a\0a-- u8 con[32] = {\0a\0a--\090x00,0x01,0x01,0x02,0x03,0x05,0x08,0x0d\0a\0a--\09,0x15,0x22,0x37,0x59,0x90,0xe9,0x79,0x62\0a\0a--\09,0xdb,0x3d,0x18,0x55,0x6d,0xc2,0x2f,0xf1\0a\0a--\09,0x20,0x11,0x31,0x42,0x73,0xb5,0x28,0xdd\0a\0alocal con = { -- con as 4 uint64 - !! assume little endian !!\0a\0a\09\090xd08050302010100, 0x6279e99059372215, \0a\0a\09 0xf12fc26d55183ddb, 0xdd28b57342311120 }\0a\0a\09\0a\0alocal function state_init(key, iv)\0a\0a\09-- return an initialized state array\0a\0a\09assert((#key == 16) or (#key == 32), \22key must be 16 or 32 bytes\22)\0a\0a\09assert(#iv == 16, \22iv must be 16 bytes\22)\0a\0a\09local ek0, ek1, ek2, ek3 \0a\0a\09if #key == 16 then \0a\0a\09\09ek0, ek1 = string.unpack(\22<I8I8\22, key)\0a\0a\09\09ek3, ek2 = ek1, ek0\0a\0a\09else\0a\0a\09\09ek0, ek1, ek2, ek3 = string.unpack(\22<I8I8I8I8\22, key)\0a\0a\09end\0a\0a\09local iv0, iv1 = string.unpack(\22<I8I8\22, iv)\0a\0a\09--initaialize state s:\0a\0a\09local s = {\0a\0a\09\09iv0, iv1, 0, 0, -- state[0][]\0a\0a\09\09ek0, ek1, ek2, ek3, -- state[1][]\0a\0a\09\09-1, -1, -1, -1, -- state[2][] (0xff * 32)\0a\0a\09\090, 0, 0, 0, -- state[3][]\0a\0a\09\09con[1], con[2], con[3], con[4], -- state[4][]\0a\0a\09}\0a\0a\09for i = 1, 16 do state_update(s, 0, 0, 0, 0) end\0a\0a\09s[5] = s[5] ~ ek0 -- state[1][i] ^= ((uint64_t*)ekey)[i];\0a\0a\09s[6] = s[6] ~ ek1\0a\0a\09s[7] = s[7] ~ ek2\0a\0a\09s[8] = s[8] ~ ek3\0a\0a\09return s\0a\0aend--state_init()\0a\0a\0a\0a--finalization\0a\0a\0a\0alocal function tag_compute(s, mlen, adlen)\0a\0a\09-- return tag0, tag1 (the tag as two uint64)\0a\0a\09local m0, m1, m2, m3 = (adlen << 3), (mlen << 3), 0, 0\0a\0a\0a\0a\09-- s[1], s[2], s[3], s[4] = s00, s01, s02, s03\0a\0a\09-- s[5], s[6], s[7], s[8] = s10, s11, s12, s13\0a\0a\09-- s[9], s[10], s[11], s[12] = s20, s21, s22, s23\0a\0a\09-- s[13], s[14], s[15], s[16] = s30, s31, s32, s33\0a\0a\09-- s[17], s[18], s[19], s[20] = s40, s41, s42, s43\0a\0a\0a\0a\09-- state[4][0] ^= state[0][0]; state[4][1] ^= state[0][1]; \0a\0a\09-- state[4][2] ^= state[0][2]; state[4][3] ^= state[0][3];\0a\0a\09s[17] = s[17] ~ s[1]; s[18] = s[18] ~ s[2]\0a\0a\09s[19] = s[19] ~ s[3]; s[20] = s[20] ~ s[4]\0a\0a\09for i = 1, 10 do state_update(s, m0, m1, m2, m3) end\0a\0a\09-- for (j = 0; j < 4; j++) {\0a\0a\09--\09state[0][j] ^= state[1][(j + 1) & 3] ^ (state[2][j] & state[3][j]);}\0a\0a\09s[1] = s[1] ~ s[6] ~ (s[9] & s[13]) -- j=0\0a\0a\09s[2] = s[2] ~ s[7] ~ (s[10] & s[14]) -- j=1\0a\0a\09s[3] = s[3] ~ s[8] ~ (s[11] & s[15]) -- j=2\0a\0a\09s[4] = s[4] ~ s[5] ~ (s[12] & s[16]) -- j=3\0a\0a\09\0a\0a\09return s[1], s[2]\0a\0aend\0a\0a\0a\0a--- Encrypts a message using the Morus encryption algorithm.\0a\0a--- @param k string - The encryption key (16 or 32-byte string).\0a\0a--- @param iv string - The nonce or initial value (16-byte string).\0a\0a--- @param m string - The message to encrypt (variable length string).\0a\0a--- @param ad? string (optional) - The additional data (variable length string). Optional, defaults to \22\22.\0a\0a--- @returns table - A table containing the encrypted message in bytes, hex, and string formats.\0a\0a--- @usage local encryptedMessage = encrypt(key, nonce, message, additionalData)\0a\0alocal function encrypt(k, iv, m, ad)\0a\0a\09ad = ad or \22\22\0a\0a\09local mlen, adlen = #m, #ad\0a\0a\09local m0, m1, m2, m3, c0, c1, c2, c3\0a\0a\09local blk, blen\0a\0a\09local ct = {}\0a\0a\09-- init\0a\0a\09local s = state_init(k, iv)\0a\0a\09-- absorb ad\0a\0a\09local i = 1\0a\0a\09while i <= adlen - 31 do --process full blocks\0a\0a\09\09m0, m1, m2, m3 = string.unpack(\22<I8I8I8I8\22, ad, i)\0a\0a\09\09i = i + 32\0a\0a\09\09enc_aut_step(s, m0, m1, m2, m3)\0a\0a\09end\0a\0a\09if i <= adlen then -- process last, partial block of ad\0a\0a\09\09blk = ad:sub(i) .. string.rep('\5c0', 31 + i - adlen)\0a\0a\09\09assert(#blk == 32, #blk)\0a\0a\09\09m0, m1, m2, m3 = string.unpack(\22<I8I8I8I8\22, blk)\0a\0a\09\09enc_aut_step(s, m0, m1, m2, m3)\0a\0a\09end\0a\0a\09table.insert(ct, ad) -- collect the ad in ct\0a\0a\09-- encrypt m\0a\0a\09i = 1\0a\0a\09while i <= mlen - 31 do --process full blocks\0a\0a\09\09m0, m1, m2, m3 = string.unpack(\22<I8I8I8I8\22, m, i)\0a\0a\09\09i = i + 32\0a\0a\09\09--c0, c1, c2, c3 = m0, m1, m2, m3 --use this to test overhead perf\0a\0a\09\09c0, c1, c2, c3 = enc_aut_step(s, m0, m1, m2, m3)\0a\0a\09\09-- collect the 32 encrypted bytes in ct\0a\0a\09\09table.insert(ct, string.pack(\22<I8I8I8I8\22, c0, c1, c2, c3))\0a\0a\09end\0a\0a\09if i <= mlen then -- process last, partial block of m\0a\0a\09\09blk = m:sub(i) -- last partial block\0a\0a\09\09blen = #blk\0a\0a\09\09blk = blk .. string.rep('\5c0', 31 + i - mlen)\0a\0a\09\09assert(#blk == 32, #blk)\0a\0a\09\09m0, m1, m2, m3 = string.unpack(\22<I8I8I8I8\22, blk)\0a\0a\09\09c0, c1, c2, c3 = enc_aut_step(s, m0, m1, m2, m3)\0a\0a\09\09-- collect the last blen encrypted bytes in ct\0a\0a\09\09table.insert(ct, string.pack(\22<I8I8I8I8\22, c0, c1, c2, c3):sub(1, blen))\0a\0a\09end\0a\0a\09-- compute the mac\0a\0a\09local tag0, tag1 = tag_compute(s, mlen, adlen)\0a\0a\09table.insert(ct, string.pack(\22<I8I8\22, tag0, tag1))\0a\0a\09-- return the complete encrypted message (with ad prefix and tag suffix)\0a\0a\0a\0a\09local public = {};\0a\0a\0a\0a\09public.asBytes = function()\0a\0a\09\09return ct\0a\0a\09end\0a\0a\0a\0a\09public.asHex = function()\0a\0a\09\09return Hex.stringToHex(table.concat(ct))\0a\0a\09end\0a\0a\0a\0a\09public.asString = function()\0a\0a\09\09return table.concat(ct)\0a\0a\09end\0a\0a\0a\0a\09return public\0a\0aend\0a\0a\0a\0a--- Decrypts an encrypted message using the Morus encryption algorithm.\0a\0a--- @param k string - The encryption key (16 or 32-byte string).\0a\0a--- @param iv string - The nonce or initial value (16-byte string).\0a\0a--- @param e string - The encrypted message (variable length string).\0a\0a--- @param adlen? number (optional) - The length of the additional data at the start of e. Optional, defaults to 0.\0a\0a--- @returns table - A table containing the decrypted message in bytes, hex, and string formats.\0a\0alocal function decrypt(k, iv, e, adlen)\0a\0a\09adlen = adlen or 0\0a\0a local ad = \22\22\0a\0a\09local elen = #e - 16 -- length of msg before tag\0a\0a\09local mlen = elen - adlen\0a\0a\09local m0, m1, m2, m3, c0, c1, c2, c3\0a\0a\09local blk, blen\0a\0a\09local ct = {} -- used to collect decrypted blocks\0a\0a\09-- init\0a\0a\09local s = state_init(k, iv)\0a\0a\09-- absorb ad\0a\0a\09if adlen > 0 then ad = e:sub(1, adlen) end\0a\0a\09local i = 1\0a\0a\09while i <= adlen - 31 do --process full blocks\0a\0a\09\09m0, m1, m2, m3 = string.unpack(\22<I8I8I8I8\22, ad, i)\0a\0a\09\09i = i + 32\0a\0a\09\09enc_aut_step(s, m0, m1, m2, m3)\0a\0a\09end\0a\0a\09if i <= adlen then -- process last, partial block of ad\0a\0a\09\09blk = ad:sub(i) .. string.rep('\5c0', 31 + i - adlen)\0a\0a\09\09assert(#blk == 32, #blk)\0a\0a\09\09m0, m1, m2, m3 = string.unpack(\22<I8I8I8I8\22, blk)\0a\0a\09\09enc_aut_step(s, m0, m1, m2, m3)\0a\0a\09end\0a\0a\09-- decrypt message\0a\0a\09i = adlen + 1\0a\0a\09while i <= elen - 31 do --process full blocks\0a\0a\09\09c0, c1, c2, c3 = string.unpack(\22<I8I8I8I8\22, e, i)\0a\0a\09\09i = i + 32\0a\0a\09\09blk = dec_aut_step(s, c0, c1, c2, c3)\0a\0a\09\09-- collect the 32 decrypted bytes in ct\0a\0a\09\09table.insert(ct, blk)\0a\0a\09end\0a\0a\09if i <= elen then -- process last, partial block of m\0a\0a\09\09blk = e:sub(i, elen) -- last partial block\0a\0a\09\09blen = #blk\0a\0a\09\09blk = blk .. string.rep('\5c0', 31 + i - elen)\0a\0a\09\09assert(#blk == 32, #blk)\0a\0a\09\09c0, c1, c2, c3 = string.unpack(\22<I8I8I8I8\22, blk)\0a\0a\09\09blk = dec_aut_step(s, c0, c1, c2, c3, blen)\0a\0a\09\09table.insert(ct, blk)\0a\0a\09end\0a\0a\09-- check the mac\0a\0a\09local ctag0, ctag1 = tag_compute(s, mlen, adlen)\0a\0a\09local tag0, tag1 = string.unpack(\22<I8I8\22, e, elen + 1)\0a\0a\09if ((ctag0 ~ tag0) | (ctag1 ~ tag1)) ~= 0 then\0a\0a\09\09return nil, \22decrypt error\22\0a\0a\09end\0a\0a\09return table.concat(ct)\0a\0aend\0a\0a\0a\0a\0a\0areturn {\0a\0a\09-- the core permutation is exposed to facilitate tests \0a\0a\09state_update = state_update,\0a\0a\09--\0a\0a\09encrypt = encrypt,\0a\0a\09decrypt = decrypt,\0a\0a\09--\0a\0a\09key_size = 32,\0a\0a\09nonce_size = 16,\0a\0a\09variant = \22Morus-1280\22,\0a\0a}\0a\00\00\00\00local Hex = require(\22.crypto.util.hex\22)\0a\0a\0a\0a-- tags\0a\0alocal HEADER_TAG = 0x01\0a\0alocal PAYLOAD_TAG = 0x02\0a\0alocal TRAILER_TAG = 0x04\0a\0alocal FINAL_TAG = 0x08\0a\0a\0a\0alocal function G(s, a, b, c, d)\0a\0a\09-- The quarter-round.\0a\0a\09-- s is the state: u64[16].\0a\0a\09local A, B, C, D = s[a], s[b], s[c], s[d]\0a\0a\09--\0a\0a\09-- H(): return (a ~ b) ~ ((a & b) << 1) -- INLINED\0a\0a\09-- ROTR64(): return (x >> n) | (x << (64-n)) --INLINED\0a\0a\09--\0a\0a\09A = (A ~ B) ~ ((A & B) << 1) -- H(A, B);\0a\0a\09D = D ~ A; D = (D >> 8) | (D << (56)) --ROTR64(D, 8) --R0\0a\0a\09C = (C ~ D) ~ ((C & D) << 1) -- H(C, D);\0a\0a\09B = B ~ C; B = (B >> 19) | (B << (45)) --ROTR64(B, 19) --R1\0a\0a\09A = (A ~ B) ~ ((A & B) << 1) -- H(A, B);\0a\0a\09D = D ~ A; D = (D >> 40) | (D << (24)) --ROTR64(D, 40) --R2\0a\0a\09C = (C ~ D) ~ ((C & D) << 1) -- H(C, D);\0a\0a\09B = B ~ C; B = (B >> 63) | (B << (1)) --ROTR64(B, 63) --R3\0a\0a\09s[a], s[b], s[c], s[d] = A, B, C, D\0a\0aend\0a\0a\0a\0alocal function F(s)\0a\0a\09-- The full round. s is the state: u64[16]\0a\0a\09--\0a\0a\09-- beware! in Lua, arrays are 1-based indexed, not 0-indexed as in C\0a\0a -- Column step\0a\0a\09G(s, 1, 5, 9, 13);\0a\0a G(s, 2, 6, 10, 14);\0a\0a G(s, 3, 7, 11, 15);\0a\0a G(s, 4, 8, 12, 16);\0a\0a -- Diagonal step\0a\0a G(s, 1, 6, 11, 16);\0a\0a G(s, 2, 7, 12, 13);\0a\0a G(s, 3, 8, 9, 14);\0a\0a G(s, 4, 5, 10, 15);\0a\0aend\0a\0a\0a\0alocal function permute(s)\0a\0a\09-- the core permutation (four rounds)\0a\0a\09for _ = 1, 4 do F(s) end\0a\0aend\0a\0a\0a\0alocal function pad(ins)\0a\0a\09-- pad string ins to length 96 (\22BYTES(NORX_R)\22)\0a\0a\09local out\0a\0a\09local inslen = #ins\0a\0a\09if inslen == 95 then return ins .. '\5cx81' end -- last byte is 0x01 | 0x80\0a\0a\09-- here inslen is < 95, so must pad with 96-(inslen+2) zeros\0a\0a\09out = ins .. '\5cx01' .. string.rep('\5c0', 94-inslen) .. '\5cx80'\0a\0a\09assert(#out == 96)\0a\0a\09return out\0a\0aend\0a\0a\0a\0alocal function absorb_block(s, ins, ini, tag)\0a\0a\09-- the input string is the substring of 'ins' starting at position 'ini'\0a\0a\09-- (we cannot use a char* as in C!)\0a\0a\09s[16] = s[16] ~ tag\0a\0a\09permute(s)\0a\0a\09for i = 1, 12 do\0a\0a\09\09s[i] = s[i] ~ string.unpack(\22<I8\22, ins, ini + (i-1)*8)\0a\0a\09end\0a\0aend\0a\0a\0a\0alocal function absorb_lastblock(s, last, tag)\0a\0a\09absorb_block(s, pad(last), 1, tag)\0a\0aend\0a\0a\0a\0alocal function encrypt_block(s, out_table, ins, ini)\0a\0a\09-- encrypt block in 'ins' at offset 'ini'\0a\0a\09-- append encrypted chunks at the end of out_table\0a\0a\09s[16] = s[16] ~ PAYLOAD_TAG\0a\0a\09permute(s)\0a\0a\09for i = 1, 12 do\0a\0a\09\09s[i] = s[i] ~ string.unpack(\22<I8\22, ins, ini + (i-1)*8)\0a\0a\09\09table.insert(out_table, string.pack(\22<I8\22, s[i]))\0a\0a\09end\0a\0aend\0a\0a\0a\0alocal function encrypt_lastblock(s, out_table, last)\0a\0a\09-- encrypt last block\0a\0a\09-- append encrypted last block at the end of out_table\0a\0a\09local t = {} -- encrypted chunks of 'last' will be appended to t\0a\0a\09local lastlen = #last\0a\0a\09last = pad(last)\0a\0a\09encrypt_block(s, t, last, 1)\0a\0a\09last = table.concat(t)\0a\0a\09last = last:sub(1, lastlen) -- keep only the first lastlen bytes\0a\0a\09table.insert(out_table, last)\0a\0aend\0a\0a\0a\0alocal function decrypt_block(s, out_table, ins, ini)\0a\0a\09-- decrypt block in 'ins' at offset 'ini'\0a\0a\09-- append decrypted chunks at the end of out_table\0a\0a\09s[16] = s[16] ~ PAYLOAD_TAG\0a\0a\09permute(s)\0a\0a\09for i = 1, 12 do\0a\0a\09\09local c = string.unpack(\22<I8\22, ins, ini + (i-1)*8)\0a\0a\09\09table.insert(out_table, string.pack(\22<I8\22, s[i] ~ c))\0a\0a\09\09s[i] = c\0a\0a\09end\0a\0aend\0a\0a\0a\0alocal function decrypt_lastblock(s, out_table, last)\0a\0a\09-- decrypt last block\0a\0a\09-- append decrypted block at the end of out_table\0a\0a\09--\0a\0a\09local lastlen = #last\0a\0a\09s[16] = s[16] ~ PAYLOAD_TAG\0a\0a\09permute(s)\0a\0a\09local byte, char = string.byte, string.char\0a\0a\09local lastblock_s8_table = {} -- last block as an array of 8-byte strings\0a\0a\09for i = 1, 12 do\0a\0a\09\09local s8 = string.pack(\22<I8\22, s[i])\0a\0a\09\09table.insert(lastblock_s8_table, s8)\0a\0a\09end\0a\0a\09local lastblock = table.concat(lastblock_s8_table) -- lastblock as a 96-byte string\0a\0a\09-- explode lastblock as an array of bytes\0a\0a\09local lastblock_byte_table = {}\0a\0a\09for i = 1, 96 do\0a\0a\09\09lastblock_byte_table[i] = byte(lastblock, i)\0a\0a\09end\0a\0a\09-- copy last\0a\0a\09for i = 1, lastlen do\0a\0a\09\09lastblock_byte_table[i] = byte(last, i)\0a\0a\09end\0a\0a\09-- perform the 'xor's\0a\0a\09lastblock_byte_table[lastlen+1] = lastblock_byte_table[lastlen+1] ~ 0x01\0a\0a\09lastblock_byte_table[96] = lastblock_byte_table[96] ~ 0x80\0a\0a\09-- build back lastblock as a string\0a\0a\09local lastblock_char_table = {}\0a\0a\09for i = 1, 96 do\0a\0a\09\09lastblock_char_table[i] = char(lastblock_byte_table[i])\0a\0a\09end\0a\0a\09lastblock = table.concat(lastblock_char_table) -- lastblock as a 96-byte string\0a\0a\09--\0a\0a\09local t = {}\0a\0a\09for i = 1, 12 do\0a\0a\09\09local c = string.unpack(\22<I8\22, lastblock, 1 + (i-1)*8)\0a\0a\09\09local x = string.pack(\22<I8\22, s[i] ~ c)\0a\0a\09\09table.insert(t, x)\0a\0a\09\09s[i] = c\0a\0a\09end\0a\0a\09last = table.concat(t)\0a\0a\09last = last:sub(1, lastlen) -- keep only the first lastlen bytes\0a\0a\09table.insert(out_table, last)\0a\0aend\0a\0a\0a\0alocal function init(k, n)\0a\0a\09-- initialize and return the norx state\0a\0a\09-- k: the key as a 32-byte string\0a\0a\09-- n: the nonce as a 32-byte string\0a\0a\09local s = {} -- the norx state: u64[16]\0a\0a\09-- (the two following F(s) could be replaced with a constant table)\0a\0a\09-- (only s[9]..s[16] are needed)\0a\0a\09for i = 1, 16 do s[i] = i-1 end\0a\0a\09F(s)\0a\0a\09F(s)\0a\0a\09-- load the nonce\0a\0a\09s[1], s[2], s[3], s[4] = string.unpack(\22<I8I8I8I8\22, n)\0a\0a\09-- load the key\0a\0a\09local k1, k2, k3, k4 = string.unpack(\22<I8I8I8I8\22, k)\0a\0a\09s[5], s[6], s[7], s[8] = k1, k2, k3, k4\0a\0a\09--\0a\0a\09s[13] = s[13] ~ 64 --W\0a\0a\09s[14] = s[14] ~ 4 --L\0a\0a\09s[15] = s[15] ~ 1 --P\0a\0a\09s[16] = s[16] ~ 256 --T\0a\0a\09--\0a\0a\09permute(s)\0a\0a\09--\0a\0a\09s[13] = s[13] ~ k1\0a\0a\09s[14] = s[14] ~ k2\0a\0a\09s[15] = s[15] ~ k3\0a\0a\09s[16] = s[16] ~ k4\0a\0a\09--\0a\0a\09return s\0a\0aend\0a\0a\0a\0alocal function absorb_data(s, ins, tag)\0a\0a\09local inlen = #ins\0a\0a\09local i = 1\0a\0a\09if inlen > 0 then\0a\0a\09\09while inlen >= 96 do\0a\0a\09\09\09absorb_block(s, ins, i, tag)\0a\0a\09\09\09inlen = inlen - 96\0a\0a\09\09\09i = i + 96\0a\0a\09\09end\0a\0a\09\09absorb_lastblock(s, ins:sub(i), tag)\0a\0a\09end--if\0a\0aend\0a\0a\0a\0alocal function encrypt_data(s, out_table, ins)\0a\0a\09local inlen = #ins\0a\0a\09local i = 1\0a\0a\09if inlen > 0 then\0a\0a\09\09while inlen >= 96 do\0a\0a\09\09\09encrypt_block(s, out_table, ins, i)\0a\0a\09\09\09inlen = inlen - 96\0a\0a\09\09\09i = i + 96\0a\0a\09\09end\0a\0a\09\09encrypt_lastblock(s, out_table, ins:sub(i))\0a\0a\09end\0a\0aend\0a\0a\0a\0alocal function decrypt_data(s, out_table, ins)\0a\0a\09local inlen = #ins\0a\0a\09local i = 1\0a\0a\09if inlen > 0 then\0a\0a\09\09while inlen >= 96 do\0a\0a\09\09\09decrypt_block(s, out_table, ins, i)\0a\0a\09\09\09inlen = inlen - 96\0a\0a\09\09\09i = i + 96\0a\0a\09\09end\0a\0a\09\09decrypt_lastblock(s, out_table, ins:sub(i))\0a\0a\09end\0a\0aend\0a\0a\0a\0alocal function finalize(s, k)\0a\0a\09-- return the authentication tag (32-byte string)\0a\0a\09--\0a\0a\09s[16] = s[16] ~ FINAL_TAG\0a\0a\09permute(s)\0a\0a\09--\0a\0a\09local k1, k2, k3, k4 = string.unpack(\22<I8I8I8I8\22, k)\0a\0a\09--\0a\0a\09s[13] = s[13] ~ k1\0a\0a\09s[14] = s[14] ~ k2\0a\0a\09s[15] = s[15] ~ k3\0a\0a\09s[16] = s[16] ~ k4\0a\0a\09--\0a\0a\09permute(s)\0a\0a\09--\0a\0a\09s[13] = s[13] ~ k1\0a\0a\09s[14] = s[14] ~ k2\0a\0a\09s[15] = s[15] ~ k3\0a\0a\09s[16] = s[16] ~ k4\0a\0a\09--\0a\0a\09local authtag = string.pack(\22<I8I8I8I8\22, s[13], s[14], s[15], s[16])\0a\0a\09return authtag\0a\0aend\0a\0a\0a\0alocal function verify_tag(tag1, tag2)\0a\0a\09return tag1 == tag2\0a\0aend\0a\0a\0a\0a\0a\0a--- Encrypts the given plain text using the NORX cipher with an AEAD construction.\0a\0a--- @param key string - The key used for encryption.\0a\0a--- @param nonce string - The nonce used for encryption 32-byte string.\0a\0a--- @param plain string - The plain text to be encrypted 32-byte string.\0a\0a--- @param header? string (optional) - The header to be encrypted 32-byte string. Defaults to an empty string.\0a\0a--- @param trailer? string (optional) - The trailer to be encrypted 32-byte string. Defaults to an empty string.\0a\0a--- @returns table - A table containing the encrypted message in bytes, string, and hex formats.\0a\0alocal function aead_encrypt(key, nonce, plain, header, trailer)\0a\0a\09header = header or \22\22\0a\0a\09trailer = trailer or \22\22\0a\0a\09local out_table = {}\0a\0a\09local state = init(key, nonce)\0a\0a\09absorb_data(state, header, HEADER_TAG)\0a\0a\09encrypt_data(state, out_table, plain)\0a\0a\09absorb_data(state, trailer, TRAILER_TAG)\0a\0a\09local tag = finalize(state, key)\0a\0a\09table.insert(out_table, tag)\0a\0a\09local crypted = table.concat(out_table)\0a\0a\09assert(#crypted == #plain + 32)\0a\0a\0a\0a local public = {}\0a\0a\0a\0a public.asBytes = function()\0a\0a return out_table\0a\0a end\0a\0a\0a\0a public.asString = function()\0a\0a return crypted\0a\0a end\0a\0a\0a\0a public.asHex = function()\0a\0a return Hex.stringToHex(crypted)\0a\0a end\0a\0a\0a\0a return public\0a\0aend\0a\0a\0a\0a--- Decrypts the given crypted text using the NORX cipher with an AEAD construction.\0a\0a--- @param key string - The key used for decryption 32-byte string.\0a\0a--- @param nonce string - The nonce used for decryption 32-byte string.\0a\0a--- @param crypted string - The crypted text to be decrypted 32-byte string.\0a\0a--- @param header? string (optional) - The header to be decrypted 32-byte string. Defaults to an empty string.\0a\0a--- @param trailer? string (optional) - The trailer to be decrypted 32-byte string. Defaults to an empty string.\0a\0a--- @returns string|nil - The decrypted plain text, or (nil, error message) if the authenticated decryption fails.\0a\0alocal function aead_decrypt(key, nonce, crypted, header, trailer)\0a\0a\09header = header or \22\22\0a\0a\09trailer = trailer or \22\22\0a\0a\09assert(#crypted >= 32)\0a\0a\09local out_table = {}\0a\0a\09local state = init(key, nonce)\0a\0a\09absorb_data(state, header, HEADER_TAG)\0a\0a\09local ctag = crypted:sub(#crypted - 32 + 1)\0a\0a\09local c = crypted:sub(1, #crypted - 32)\0a\0a\09decrypt_data(state, out_table, c)\0a\0a\09absorb_data(state, trailer, TRAILER_TAG)\0a\0a\09local tag = finalize(state, key)\0a\0a\09if not verify_tag(tag, ctag) then return nil, \22auth failure\22 end\0a\0a\09local plain = table.concat(out_table)\0a\0a\09return plain\0a\0aend\0a\0a\0a\0areturn {\0a\0a\09encrypt = aead_encrypt,\0a\0a\09decrypt = aead_decrypt,\0a\0a\09--\0a\0a\09key_size = 32,\0a\0a\09nonce_size = 32,\0a\0a\09variant = \22NORX 64-4-1\22,\0a\0a}\0a")
(data $.rodata.8 (;8;) (i64.const 194544) "local Array = require(\22.crypto.util.array\22);\0a\0alocal Stream = require(\22.crypto.util.stream\22);\0a\0alocal Queue = require(\22.crypto.util.queue\22);\0a\0a\0a\0alocal CBC = {};\0a\0a\0a\0aCBC.Cipher = function()\0a\0a\0a\0a local public = {};\0a\0a\0a\0a local key;\0a\0a local blockCipher;\0a\0a local padding;\0a\0a local inputQueue;\0a\0a local outputQueue;\0a\0a local iv;\0a\0a\0a\0a public.setKey = function(keyBytes)\0a\0a key = keyBytes;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.setBlockCipher = function(cipher)\0a\0a blockCipher = cipher;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.setPadding = function(paddingMode)\0a\0a padding = paddingMode;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.init = function()\0a\0a inputQueue = Queue();\0a\0a outputQueue = Queue();\0a\0a iv = nil;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.update = function(messageStream)\0a\0a local byte = messageStream();\0a\0a while (byte ~= nil) do\0a\0a inputQueue.push(byte);\0a\0a if(inputQueue.size() >= blockCipher.blockSize) then\0a\0a local block = Array.readFromQueue(inputQueue, blockCipher.blockSize);\0a\0a\0a\0a if(iv == nil) then\0a\0a iv = block;\0a\0a else\0a\0a local out = Array.XOR(iv, block);\0a\0a out = blockCipher.encrypt(key, out);\0a\0a Array.writeToQueue(outputQueue, out);\0a\0a iv = out;\0a\0a end\0a\0a end\0a\0a byte = messageStream();\0a\0a end\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.finish = function()\0a\0a local paddingStream = padding(blockCipher.blockSize, inputQueue.getHead());\0a\0a public.update(paddingStream);\0a\0a\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.getOutputQueue = function()\0a\0a return outputQueue;\0a\0a end\0a\0a\0a\0a public.asHex = function()\0a\0a return Stream.toHex(outputQueue.pop);\0a\0a end\0a\0a\0a\0a public.asBytes = function()\0a\0a return Stream.toArray(outputQueue.pop);\0a\0a end\0a\0a\0a\0a public.asString = function()\0a\0a return Stream.toString(outputQueue.pop);\0a\0a end\0a\0a\0a\0a return public;\0a\0a\0a\0aend\0a\0a\0a\0a\0a\0aCBC.Decipher = function()\0a\0a\0a\0a local public = {};\0a\0a\0a\0a local key;\0a\0a local blockCipher;\0a\0a local padding;\0a\0a local inputQueue;\0a\0a local outputQueue;\0a\0a local iv;\0a\0a\0a\0a public.setKey = function(keyBytes)\0a\0a key = keyBytes;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.setBlockCipher = function(cipher)\0a\0a blockCipher = cipher;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.setPadding = function(paddingMode)\0a\0a padding = paddingMode;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.init = function()\0a\0a inputQueue = Queue();\0a\0a outputQueue = Queue();\0a\0a iv = nil;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.update = function(messageStream)\0a\0a local byte = messageStream();\0a\0a while (byte ~= nil) do\0a\0a inputQueue.push(byte);\0a\0a if(inputQueue.size() >= blockCipher.blockSize) then\0a\0a local block = Array.readFromQueue(inputQueue, blockCipher.blockSize);\0a\0a\0a\0a if(iv == nil) then\0a\0a iv = block;\0a\0a else\0a\0a local out = block;\0a\0a out = blockCipher.decrypt(key, out);\0a\0a out = Array.XOR(iv, out);\0a\0a Array.writeToQueue(outputQueue, out);\0a\0a iv = block;\0a\0a end\0a\0a end\0a\0a byte = messageStream();\0a\0a end\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.finish = function()\0a\0a local paddingStream = padding(blockCipher.blockSize, inputQueue.getHead());\0a\0a public.update(paddingStream);\0a\0a\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.getOutputQueue = function()\0a\0a return outputQueue;\0a\0a end\0a\0a\0a\0a public.asHex = function()\0a\0a return Stream.toHex(outputQueue.pop);\0a\0a end\0a\0a\0a\0a public.asBytes = function()\0a\0a return Stream.toArray(outputQueue.pop);\0a\0a end\0a\0a\0a\0a public.asString = function()\0a\0a return Stream.toString(outputQueue.pop);\0a\0a end\0a\0a\0a\0a return public;\0a\0a\0a\0aend\0a\0a\0a\0areturn CBC;\0a")
(data $.rodata.9 (;9;) (i64.const 198672) "local Array = require(\22.crypto.util.array\22);\0a\0alocal Stream = require(\22.crypto.util.stream\22);\0a\0alocal Queue = require(\22.crypto.util.queue\22);\0a\0a\0a\0alocal CFB = {};\0a\0a\0a\0aCFB.Cipher = function()\0a\0a\0a\0a local public = {};\0a\0a\0a\0a local key;\0a\0a local blockCipher;\0a\0a local padding;\0a\0a local inputQueue;\0a\0a local outputQueue;\0a\0a local iv;\0a\0a\0a\0a public.setKey = function(keyBytes)\0a\0a key = keyBytes;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.setBlockCipher = function(cipher)\0a\0a blockCipher = cipher;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.setPadding = function(paddingMode)\0a\0a padding = paddingMode;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.init = function()\0a\0a inputQueue = Queue();\0a\0a outputQueue = Queue();\0a\0a iv = nil;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.update = function(messageStream)\0a\0a local byte = messageStream();\0a\0a while (byte ~= nil) do\0a\0a inputQueue.push(byte);\0a\0a if(inputQueue.size() >= blockCipher.blockSize) then\0a\0a local block = Array.readFromQueue(inputQueue, blockCipher.blockSize);\0a\0a\0a\0a if(iv == nil) then\0a\0a iv = block;\0a\0a else\0a\0a local out = iv;\0a\0a out = blockCipher.encrypt(key, out);\0a\0a out = Array.XOR(out, block);\0a\0a Array.writeToQueue(outputQueue, out);\0a\0a iv = out;\0a\0a end\0a\0a end\0a\0a byte = messageStream();\0a\0a end\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.finish = function()\0a\0a local paddingStream = padding(blockCipher.blockSize, inputQueue.getHead());\0a\0a public.update(paddingStream);\0a\0a\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.getOutputQueue = function()\0a\0a return outputQueue;\0a\0a end\0a\0a\0a\0a public.asHex = function()\0a\0a return Stream.toHex(outputQueue.pop);\0a\0a end\0a\0a\0a\0a public.asBytes = function()\0a\0a return Stream.toArray(outputQueue.pop);\0a\0a end\0a\0a\0a\0a public.asString = function()\0a\0a return Stream.toString(outputQueue.pop);\0a\0a end\0a\0a\0a\0a return public;\0a\0a\0a\0aend\0a\0a\0a\0aCFB.Decipher = function()\0a\0a\0a\0a local public = {};\0a\0a\0a\0a local key;\0a\0a local blockCipher;\0a\0a local padding;\0a\0a local inputQueue;\0a\0a local outputQueue;\0a\0a local iv;\0a\0a\0a\0a public.setKey = function(keyBytes)\0a\0a key = keyBytes;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.setBlockCipher = function(cipher)\0a\0a blockCipher = cipher;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.setPadding = function(paddingMode)\0a\0a padding = paddingMode;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.init = function()\0a\0a inputQueue = Queue();\0a\0a outputQueue = Queue();\0a\0a iv = nil;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.update = function(messageStream)\0a\0a local byte = messageStream();\0a\0a while (byte ~= nil) do\0a\0a inputQueue.push(byte);\0a\0a if(inputQueue.size() >= blockCipher.blockSize) then\0a\0a local block = Array.readFromQueue(inputQueue, blockCipher.blockSize);\0a\0a\0a\0a if(iv == nil) then\0a\0a iv = block;\0a\0a else\0a\0a local out = iv;\0a\0a out = blockCipher.encrypt(key, out);\0a\0a out = Array.XOR(out, block);\0a\0a Array.writeToQueue(outputQueue, out);\0a\0a iv = block;\0a\0a end\0a\0a end\0a\0a byte = messageStream();\0a\0a end\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.finish = function()\0a\0a local paddingStream = padding(blockCipher.blockSize, inputQueue.getHead());\0a\0a public.update(paddingStream);\0a\0a\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.getOutputQueue = function()\0a\0a return outputQueue;\0a\0a end\0a\0a\0a\0a public.asHex = function()\0a\0a return Stream.toHex(outputQueue.pop);\0a\0a end\0a\0a\0a\0a public.asBytes = function()\0a\0a return Stream.toArray(outputQueue.pop);\0a\0a end\0a\0a\0a\0a public.asString = function()\0a\0a return Stream.toString(outputQueue.pop);\0a\0a end\0a\0a\0a\0a return public;\0a\0a\0a\0aend\0a\0a\0a\0areturn CFB;local Array = require(\22.crypto.util.array\22);\0a\0alocal Stream = require(\22.crypto.util.stream\22);\0a\0alocal Queue = require(\22.crypto.util.queue\22);\0a\0a\0a\0alocal Bit = require(\22.crypto.util.bit\22);\0a\0a\0a\0alocal AND = Bit.band;\0a\0a\0a\0alocal CTR = {};\0a\0a\0a\0aCTR.Cipher = function()\0a\0a\0a\0a local public = {};\0a\0a\0a\0a local key;\0a\0a local blockCipher;\0a\0a local padding;\0a\0a local inputQueue;\0a\0a local outputQueue;\0a\0a local iv;\0a\0a\0a\0a public.setKey = function(keyBytes)\0a\0a key = keyBytes;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.setBlockCipher = function(cipher)\0a\0a blockCipher = cipher;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.setPadding = function(paddingMode)\0a\0a padding = paddingMode;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.init = function()\0a\0a inputQueue = Queue();\0a\0a outputQueue = Queue();\0a\0a iv = nil;\0a\0a return public;\0a\0a end\0a\0a\0a\0a local updateIV = function()\0a\0a iv[16] = iv[16] + 1;\0a\0a if iv[16] <= 0xFF then return; end\0a\0a iv[16] = AND(iv[16], 0xFF);\0a\0a\0a\0a iv[15] = iv[15] + 1;\0a\0a if iv[15] <= 0xFF then return; end\0a\0a iv[15] = AND(iv[15], 0xFF);\0a\0a\0a\0a iv[14] = iv[14] + 1;\0a\0a if iv[14] <= 0xFF then return; end\0a\0a iv[14] = AND(iv[14], 0xFF);\0a\0a\0a\0a iv[13] = iv[13] + 1;\0a\0a if iv[13] <= 0xFF then return; end\0a\0a iv[13] = AND(iv[13], 0xFF);\0a\0a\0a\0a iv[12] = iv[12] + 1;\0a\0a if iv[12] <= 0xFF then return; end\0a\0a iv[12] = AND(iv[12], 0xFF);\0a\0a\0a\0a iv[11] = iv[11] + 1;\0a\0a if iv[11] <= 0xFF then return; end\0a\0a iv[11] = AND(iv[11], 0xFF);\0a\0a\0a\0a iv[10] = iv[10] + 1;\0a\0a if iv[10] <= 0xFF then return; end\0a\0a iv[10] = AND(iv[10], 0xFF);\0a\0a\0a\0a iv[9] = iv[9] + 1;\0a\0a if iv[9] <= 0xFF then return; end\0a\0a iv[9] = AND(iv[9], 0xFF);\0a\0a\0a\0a return;\0a\0a end\0a\0a\0a\0a public.update = function(messageStream)\0a\0a local byte = messageStream();\0a\0a while (byte ~= nil) do\0a\0a inputQueue.push(byte);\0a\0a\0a\0a if(inputQueue.size() >= blockCipher.blockSize) then\0a\0a local block = Array.readFromQueue(inputQueue, blockCipher.blockSize);\0a\0a\0a\0a if(iv == nil) then\0a\0a iv = block;\0a\0a else\0a\0a local out = iv;\0a\0a out = blockCipher.encrypt(key, out);\0a\0a\0a\0a out = Array.XOR(out, block);\0a\0a Array.writeToQueue(outputQueue, out);\0a\0a updateIV();\0a\0a end\0a\0a end\0a\0a byte = messageStream();\0a\0a end\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.finish = function()\0a\0a local paddingStream = padding(blockCipher.blockSize, inputQueue.getHead());\0a\0a public.update(paddingStream);\0a\0a\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.getOutputQueue = function()\0a\0a return outputQueue;\0a\0a end\0a\0a\0a\0a public.asHex = function()\0a\0a return Stream.toHex(outputQueue.pop);\0a\0a end\0a\0a\0a\0a public.asBytes = function()\0a\0a return Stream.toArray(outputQueue.pop);\0a\0a end\0a\0a\0a\0a public.asString = function()\0a\0a return Stream.toString(outputQueue.pop);\0a\0a end\0a\0a\0a\0a return public;\0a\0a\0a\0aend\0a\0a\0a\0a\0a\0aCTR.Decipher = function()\0a\0a\0a\0a local public = {};\0a\0a\0a\0a local key;\0a\0a local blockCipher;\0a\0a local padding;\0a\0a local inputQueue;\0a\0a local outputQueue;\0a\0a local iv;\0a\0a\0a\0a public.setKey = function(keyBytes)\0a\0a key = keyBytes;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.setBlockCipher = function(cipher)\0a\0a blockCipher = cipher;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.setPadding = function(paddingMode)\0a\0a padding = paddingMode;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.init = function()\0a\0a inputQueue = Queue();\0a\0a outputQueue = Queue();\0a\0a iv = nil;\0a\0a return public;\0a\0a end\0a\0a\0a\0a local updateIV = function()\0a\0a iv[16] = iv[16] + 1;\0a\0a if iv[16] <= 0xFF then return; end\0a\0a iv[16] = AND(iv[16], 0xFF);\0a\0a\0a\0a iv[15] = iv[15] + 1;\0a\0a if iv[15] <= 0xFF then return; end\0a\0a iv[15] = AND(iv[15], 0xFF);\0a\0a\0a\0a iv[14] = iv[14] + 1;\0a\0a if iv[14] <= 0xFF then return; end\0a\0a iv[14] = AND(iv[14], 0xFF);\0a\0a\0a\0a iv[13] = iv[13] + 1;\0a\0a if iv[13] <= 0xFF then return; end\0a\0a iv[13] = AND(iv[13], 0xFF);\0a\0a\0a\0a iv[12] = iv[12] + 1;\0a\0a if iv[12] <= 0xFF then return; end\0a\0a iv[12] = AND(iv[12], 0xFF);\0a\0a\0a\0a iv[11] = iv[11] + 1;\0a\0a if iv[11] <= 0xFF then return; end\0a\0a iv[11] = AND(iv[11], 0xFF);\0a\0a\0a\0a iv[10] = iv[10] + 1;\0a\0a if iv[10] <= 0xFF then return; end\0a\0a iv[10] = AND(iv[10], 0xFF);\0a\0a\0a\0a iv[9] = iv[9] + 1;\0a\0a if iv[9] <= 0xFF then return; end\0a\0a iv[9] = AND(iv[9], 0xFF);\0a\0a\0a\0a return;\0a\0a end\0a\0a\0a\0a public.update = function(messageStream)\0a\0a local byte = messageStream();\0a\0a while (byte ~= nil) do\0a\0a inputQueue.push(byte);\0a\0a\0a\0a if(inputQueue.size() >= blockCipher.blockSize) then\0a\0a local block = Array.readFromQueue(inputQueue, blockCipher.blockSize);\0a\0a\0a\0a if(iv == nil) then\0a\0a iv = block;\0a\0a else\0a\0a local out = iv;\0a\0a out = blockCipher.encrypt(key, out);\0a\0a\0a\0a out = Array.XOR(out, block);\0a\0a Array.writeToQueue(outputQueue, out);\0a\0a updateIV();\0a\0a end\0a\0a end\0a\0a byte = messageStream();\0a\0a end\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.finish = function()\0a\0a local paddingStream = padding(blockCipher.blockSize, inputQueue.getHead());\0a\0a public.update(paddingStream);\0a\0a\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.getOutputQueue = function()\0a\0a return outputQueue;\0a\0a end\0a\0a\0a\0a public.asHex = function()\0a\0a return Stream.toHex(outputQueue.pop);\0a\0a end\0a\0a\0a\0a public.asBytes = function()\0a\0a return Stream.toArray(outputQueue.pop);\0a\0a end\0a\0a\0a\0a public.asString = function()\0a\0a return Stream.toString(outputQueue.pop);\0a\0a end\0a\0a\0a\0a return public;\0a\0a\0a\0aend\0a\0a\0a\0areturn CTR;\0a")
(data $.rodata.10 (;10;) (i64.const 208976) "local Array = require(\22.crypto.util.array\22);\0a\0alocal Stream = require(\22.crypto.util.stream\22);\0a\0alocal Queue = require(\22.crypto.util.queue\22);\0a\0a\0a\0alocal ECB = {};\0a\0a\0a\0aECB.Cipher = function()\0a\0a\0a\0a local public = {};\0a\0a\0a\0a local key;\0a\0a local blockCipher;\0a\0a local padding;\0a\0a local inputQueue;\0a\0a local outputQueue;\0a\0a\0a\0a public.setKey = function(keyBytes)\0a\0a key = keyBytes;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.setBlockCipher = function(cipher)\0a\0a blockCipher = cipher;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.setPadding = function(paddingMode)\0a\0a padding = paddingMode;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.init = function()\0a\0a inputQueue = Queue();\0a\0a outputQueue = Queue();\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.update = function(messageStream)\0a\0a local byte = messageStream();\0a\0a while (byte ~= nil) do\0a\0a inputQueue.push(byte);\0a\0a if(inputQueue.size() >= blockCipher.blockSize) then\0a\0a local block = Array.readFromQueue(inputQueue, blockCipher.blockSize);\0a\0a\0a\0a block = blockCipher.encrypt(key, block);\0a\0a\0a\0a Array.writeToQueue(outputQueue, block);\0a\0a end\0a\0a byte = messageStream();\0a\0a end\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.finish = function()\0a\0a local paddingStream = padding(blockCipher.blockSize, inputQueue.getHead());\0a\0a public.update(paddingStream);\0a\0a\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.getOutputQueue = function()\0a\0a return outputQueue;\0a\0a end\0a\0a\0a\0a public.asHex = function()\0a\0a return Stream.toHex(outputQueue.pop);\0a\0a end\0a\0a\0a\0a public.asBytes = function()\0a\0a return Stream.toArray(outputQueue.pop);\0a\0a end\0a\0a\0a\0a public.asString = function()\0a\0a return Stream.toString(outputQueue.pop);\0a\0a end\0a\0a\0a\0a return public;\0a\0a\0a\0aend\0a\0a\0a\0aECB.Decipher = function()\0a\0a\0a\0a local public = {};\0a\0a\0a\0a local key;\0a\0a local blockCipher;\0a\0a local padding;\0a\0a local inputQueue;\0a\0a local outputQueue;\0a\0a\0a\0a public.setKey = function(keyBytes)\0a\0a key = keyBytes;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.setBlockCipher = function(cipher)\0a\0a blockCipher = cipher;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.setPadding = function(paddingMode)\0a\0a padding = paddingMode;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.init = function()\0a\0a inputQueue = Queue();\0a\0a outputQueue = Queue();\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.update = function(messageStream)\0a\0a local byte = messageStream();\0a\0a while (byte ~= nil) do\0a\0a inputQueue.push(byte);\0a\0a if(inputQueue.size() >= blockCipher.blockSize) then\0a\0a local block = Array.readFromQueue(inputQueue, blockCipher.blockSize);\0a\0a\0a\0a block = blockCipher.decrypt(key, block);\0a\0a\0a\0a Array.writeToQueue(outputQueue, block);\0a\0a end\0a\0a byte = messageStream();\0a\0a end\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.finish = function()\0a\0a local paddingStream = padding(blockCipher.blockSize, inputQueue.getHead());\0a\0a public.update(paddingStream);\0a\0a\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.getOutputQueue = function()\0a\0a return outputQueue;\0a\0a end\0a\0a\0a\0a public.asHex = function()\0a\0a return Stream.toHex(outputQueue.pop);\0a\0a end\0a\0a\0a\0a public.asBytes = function()\0a\0a return Stream.toArray(outputQueue.pop);\0a\0a end\0a\0a\0a\0a public.asString = function()\0a\0a return Stream.toString(outputQueue.pop);\0a\0a end\0a\0a\0a\0a return public;\0a\0a\0a\0aend\0a\0a\0a\0a\0a\0areturn ECB;local Array = require(\22.crypto.util.array\22);\0a\0alocal Stream = require(\22.crypto.util.stream\22);\0a\0alocal Queue = require(\22.crypto.util.queue\22);\0a\0a\0a\0alocal OFB = {};\0a\0a\0a\0aOFB.Cipher = function()\0a\0a\0a\0a local public = {};\0a\0a\0a\0a local key;\0a\0a local blockCipher;\0a\0a local padding;\0a\0a local inputQueue;\0a\0a local outputQueue;\0a\0a local iv;\0a\0a\0a\0a public.setKey = function(keyBytes)\0a\0a key = keyBytes;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.setBlockCipher = function(cipher)\0a\0a blockCipher = cipher;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.setPadding = function(paddingMode)\0a\0a padding = paddingMode;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.init = function()\0a\0a inputQueue = Queue();\0a\0a outputQueue = Queue();\0a\0a iv = nil;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.update = function(messageStream)\0a\0a local byte = messageStream();\0a\0a while (byte ~= nil) do\0a\0a inputQueue.push(byte);\0a\0a if(inputQueue.size() >= blockCipher.blockSize) then\0a\0a local block = Array.readFromQueue(inputQueue, blockCipher.blockSize);\0a\0a\0a\0a if(iv == nil) then\0a\0a iv = block;\0a\0a else\0a\0a local out = iv;\0a\0a out = blockCipher.encrypt(key, out);\0a\0a iv = out;\0a\0a out = Array.XOR(out, block);\0a\0a Array.writeToQueue(outputQueue, out);\0a\0a end\0a\0a end\0a\0a byte = messageStream();\0a\0a end\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.finish = function()\0a\0a local paddingStream = padding(blockCipher.blockSize, inputQueue.getHead());\0a\0a public.update(paddingStream);\0a\0a\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.getOutputQueue = function()\0a\0a return outputQueue;\0a\0a end\0a\0a\0a\0a public.asHex = function()\0a\0a return Stream.toHex(outputQueue.pop);\0a\0a end\0a\0a\0a\0a public.asBytes = function()\0a\0a return Stream.toArray(outputQueue.pop);\0a\0a end\0a\0a\0a\0a public.asString = function()\0a\0a return Stream.toString(outputQueue.pop);\0a\0a end\0a\0a\0a\0a return public;\0a\0a\0a\0aend\0a\0a\0a\0aOFB.Decipher = function()\0a\0a\0a\0a local public = {};\0a\0a\0a\0a local key;\0a\0a local blockCipher;\0a\0a local padding;\0a\0a local inputQueue;\0a\0a local outputQueue;\0a\0a local iv;\0a\0a\0a\0a public.setKey = function(keyBytes)\0a\0a key = keyBytes;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.setBlockCipher = function(cipher)\0a\0a blockCipher = cipher;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.setPadding = function(paddingMode)\0a\0a padding = paddingMode;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.init = function()\0a\0a inputQueue = Queue();\0a\0a outputQueue = Queue();\0a\0a iv = nil;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.update = function(messageStream)\0a\0a local byte = messageStream();\0a\0a while (byte ~= nil) do\0a\0a inputQueue.push(byte);\0a\0a if(inputQueue.size() >= blockCipher.blockSize) then\0a\0a local block = Array.readFromQueue(inputQueue, blockCipher.blockSize);\0a\0a\0a\0a if(iv == nil) then\0a\0a iv = block;\0a\0a else\0a\0a local out = iv;\0a\0a out = blockCipher.encrypt(key, out);\0a\0a iv = out;\0a\0a out = Array.XOR(out, block);\0a\0a Array.writeToQueue(outputQueue, out);\0a\0a end\0a\0a end\0a\0a byte = messageStream();\0a\0a end\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.finish = function()\0a\0a local paddingStream = padding(blockCipher.blockSize, inputQueue.getHead());\0a\0a public.update(paddingStream);\0a\0a\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.getOutputQueue = function()\0a\0a return outputQueue;\0a\0a end\0a\0a\0a\0a public.asHex = function()\0a\0a return Stream.toHex(outputQueue.pop);\0a\0a end\0a\0a\0a\0a public.asBytes = function()\0a\0a return Stream.toArray(outputQueue.pop);\0a\0a end\0a\0a\0a\0a public.asString = function()\0a\0a return Stream.toString(outputQueue.pop);\0a\0a end\0a\0a\0a\0a return public;\0a\0a\0a\0aend\0a\0a\0a\0a\0a\0areturn OFB;local Hex = require(\22.crypto.util.hex\22);\0a\0a\0a\0a\0a\0alocal function ROTR64(x, n)\0a\0a return (x >> n) | (x << (64-n))\0a\0aend\0a\0a\0a\0a-- G Mixing function.\0a\0a\0a\0alocal function G(v, a, b, c, d, x, y)\0a\0a\09v[a] = v[a] + v[b] + x\0a\0a\09v[d] = ROTR64(v[d] ~ v[a], 32)\0a\0a\09v[c] = v[c] + v[d]\0a\0a\09v[b] = ROTR64(v[b] ~ v[c], 24)\0a\0a\09v[a] = v[a] + v[b] + y\0a\0a\09v[d] = ROTR64(v[d] ~ v[a], 16)\0a\0a\09v[c] = v[c] + v[d]\0a\0a\09v[b] = ROTR64(v[b] ~ v[c], 63)\0a\0aend\0a\0a\0a\0a-- Initialization Vector.\0a\0alocal iv = {\0a\0a 0x6a09e667f3bcc908, 0xbb67ae8584caa73b,\0a\0a 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,\0a\0a 0x510e527fade682d1, 0x9b05688c2b3e6c1f,\0a\0a 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179\0a\0a}\0a\0a\0a\0alocal sigma = {\0a\0a\09-- array index start at 1 in Lua,\0a\0a\09-- => all the permutation values are incremented by one\0a\0a\09{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 },\0a\0a\09{ 15, 11, 5, 9, 10, 16, 14, 7, 2, 13, 1, 3, 12, 8, 6, 4 },\0a\0a\09{ 12, 9, 13, 1, 6, 3, 16, 14, 11, 15, 4, 7, 8, 2, 10, 5 },\0a\0a\09{ 8, 10, 4, 2, 14, 13, 12, 15, 3, 7, 6, 11, 5, 1, 16, 9 },\0a\0a\09{ 10, 1, 6, 8, 3, 5, 11, 16, 15, 2, 12, 13, 7, 9, 4, 14 },\0a\0a\09{ 3, 13, 7, 11, 1, 12, 9, 4, 5, 14, 8, 6, 16, 15, 2, 10 },\0a\0a\09{ 13, 6, 2, 16, 15, 14, 5, 11, 1, 8, 7, 4, 10, 3, 9, 12 },\0a\0a\09{ 14, 12, 8, 15, 13, 2, 4, 10, 6, 1, 16, 5, 9, 7, 3, 11 },\0a\0a\09{ 7, 16, 15, 10, 12, 4, 1, 9, 13, 3, 14, 8, 2, 5, 11, 6 },\0a\0a\09{ 11, 3, 9, 5, 8, 7, 2, 6, 16, 12, 10, 15, 4, 13, 14, 1 },\0a\0a\09{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 },\0a\0a\09{ 15, 11, 5, 9, 10, 16, 14, 7, 2, 13, 1, 3, 12, 8, 6, 4 }\0a\0a}\0a\0a\0a\0a\0a\0alocal function compress(ctx, last)\0a\0a\09-- Compression function. \22last\22 flag indicates last block.\0a\0a\09local v, m = {}, {} -- both v and m are u64[16]\0a\0a\09for i = 1, 8 do\0a\0a\09\09v[i] = ctx.h[i]\0a\0a\09\09v[i+8] = iv[i]\0a\0a\09end\0a\0a\09v[13] = v[13] ~ ctx.t[1] -- low 64 bits of offset\0a\0a\09v[14] = v[14] ~ ctx.t[2] -- high 64 bits\0a\0a\09if last then v[15] = ~v[15] end\0a\0a\09for i = 0, 15 do -- get little-endian words\0a\0a\09\09m[i+1] = string.unpack(\22<I8\22, ctx.b, i*8+1) --copy b as a seq of u64\0a\0a\09end\0a\0a\0a\0a\09for i = 1, 12 do -- twelve rounds\0a\0a\09\09G(v, 1, 5, 9, 13, m[sigma[i][ 1]], m[sigma[i][ 2]])\0a\0a\09\09G(v, 2, 6,10, 14, m[sigma[i][ 3]], m[sigma[i][ 4]])\0a\0a\09\09G(v, 3, 7,11, 15, m[sigma[i][ 5]], m[sigma[i][ 6]])\0a\0a\09\09G(v, 4, 8,12, 16, m[sigma[i][ 7]], m[sigma[i][ 8]])\0a\0a\09\09G(v, 1, 6,11, 16, m[sigma[i][ 9]], m[sigma[i][10]])\0a\0a\09\09G(v, 2, 7,12, 13, m[sigma[i][11]], m[sigma[i][12]])\0a\0a\09\09G(v, 3, 8, 9, 14, m[sigma[i][13]], m[sigma[i][14]])\0a\0a\09\09G(v, 4, 5,10, 15, m[sigma[i][15]], m[sigma[i][16]])\0a\0a\0a\0a\09end\0a\0a\0a\0a\09for i = 1, 8 do\0a\0a\09\09ctx.h[i] = ctx.h[i] ~ v[i] ~ v[i + 8]\0a\0a\09end\0a\0aend\0a\0a\0a\0alocal update -- (update is used in init() below, but defined after)\0a\0a\0a\0alocal function init(outlen, key)\0a\0a\09-- initialize the blake function\0a\0a\09-- 1 <= outlen <= 64 gives the digest size in bytes. defaults to 64\0a\0a\09-- key: optional secret key (also <= 64 bytes). defaults to no key\0a\0a\09-- return the initialized context\0a\0a\09outlen = outlen or 64\0a\0a\09key = key or \22\22\0a\0a\09local keylen = #key\0a\0a\09if outlen < 1 or outlen > 64 or (key and #key > 64) then\0a\0a\09\09return nil, \22illegal parameters\22\0a\0a\09end\0a\0a\09local ctx = {h={}, t={}, c=1, outlen=outlen} -- the blake2 context\0a\0a\09-- note: ctx.c is the index of 1st byte free in input buffer (ctx.b)\0a\0a\09-- it is not used in this implementation\0a\0a\09for i = 1, 8 do ctx.h[i] = iv[i] end -- state, \22param block\22\0a\0a\09ctx.h[1] = ctx.h[1] ~ 0x01010000 ~ (keylen << 8) ~ outlen\0a\0a\09ctx.t[1] = 0 --input count low word\0a\0a\09ctx.t[2] = 0 --input count high word\0a\0a\09-- zero input block\0a\0a\09ctx.b = \22\22\0a\0a\09if keylen > 0 then\0a\0a\09\09update(ctx, key)\0a\0a\09\09-- ctx.c = 128 -- pad b with zero bytes\0a\0a\09\09ctx.b = ctx.b .. string.rep('\5c0', 128 - #ctx.b)\0a\0a\09\09assert(#ctx.b == 128)\0a\0a\09end\0a\0a\09return ctx\0a\0aend\0a\0a\0a\0aupdate = function(ctx, data)\0a\0a\09-- buffer mgt cannot be done the C way..\0a\0a\09local bln, rln, iln\0a\0a\09local i = 1 -- index of 1st byte to process in data\0a\0a\09while true do\0a\0a\09\09bln = #ctx.b -- current number of bytes in the input buffer\0a\0a\09\09assert(bln <= 128)\0a\0a\09\09if bln == 128 then --ctx.b is full; process it.\0a\0a\09\09\09-- add counters\0a\0a\09\09\09ctx.t[1] = ctx.t[1] + 128\0a\0a\09\09\09-- warning: this is a signed 64bit addition\0a\0a\09\09\09-- here it is assumed that the total input is less\0a\0a\09\09\09-- than 2^63 bytes (this should be enough for a\0a\0a\09\09\09-- pure Lua implementation!) => ctx.t[1] overflow is ignored.\0a\0a\09\09\09compress(ctx, false) -- false means not last\0a\0a\09\09\09ctx.b = \22\22 -- empty buffer\0a\0a\09\09else -- ctx.b is not full; append more bytes from data\0a\0a\09\09\09rln = 128 - bln -- remaining space (in bytes) in ctx.b\0a\0a\09\09\09iln = #data - i + 1 -- number of bytes yet to process in data\0a\0a\09\09\09if iln < rln then\0a\0a\09\09\09\09ctx.b = ctx.b .. data:sub(i, i + iln -1)\0a\0a\09\09\09\09-- here, all data bytes have been processed or put in\0a\0a\09\09\09\09-- buffer and buffer is not full. we are done.\0a\0a\09\09\09\09break\0a\0a\09\09\09else\0a\0a\09\09\09\09ctx.b = ctx.b .. data:sub(i, i + rln -1)\0a\0a\09\09\09\09i = i + rln\0a\0a\09\09\09end\0a\0a\09\09end\0a\0a\09end\0a\0aend\0a\0a\0a\0alocal function final(ctx)\0a\0a\09-- finalize the hash and return the digest as a string\0a\0a\09--\0a\0a\09local bln = #ctx.b\0a\0a\09-- add number of remaining bytes in buffer (ignore carry overflow)\0a\0a\09ctx.t[1] = ctx.t[1] + bln\0a\0a\09-- pad the buffer with zero bytes\0a\0a\09local rln = 128 - bln -- remaining space (in bytes) in ctx.b\0a\0a\09ctx.b = ctx.b .. string.rep('\5c0', rln)\0a\0a\09compress(ctx, true) -- true means final block\0a\0a\09-- extract the digest (outlen bytes long)\0a\0a\09local outtbl = {}\0a\0a\09for i = 0, ctx.outlen - 1 do\0a\0a\09\09outtbl[i+1] = string.char(\0a\0a\09\09\09(ctx.h[(i >> 3) + 1] >> (8 * (i & 7))) & 0xff)\0a\0a\09end\0a\0a\09local dig = table.concat(outtbl)\0a\0a\09return outtbl\0a\0aend\0a\0a\0a\0a--- Calculates the BLAKE2b hash of the given data.\0a\0a--- @param data string - The input data to be hashed.\0a\0a--- @param outlen? number (optional) - The desired length of the hash output. Defaults to 64.\0a\0a--- @param key? string (optional) - The key to be used for the hash calculation. Defaults to an empty string.\0a\0a--- @returns table - A table containing the hash in bytes, string, and hex formats.\0a\0alocal function black2b(data, outlen, key)\0a\0a local ctx, msg = init(outlen, key)\0a\0a if not ctx then return ctx, msg end\0a\0a update(ctx, data)\0a\0a local bytes = final(ctx)\0a\0a\09local hash = table.concat(bytes)\0a\0a\0a\0a local public = {}\0a\0a\09\0a\0a\09public.asBytes = function()\0a\0a\09\09return bytes\0a\0a\09end\0a\0a\0a\0a\09public.asString = function()\0a\0a\09\09return hash\0a\0a\09end\0a\0a\0a\0a\09public.asHex = function()\0a\0a\09\09return Hex.stringToHex(hash)\0a\0a\09end\0a\0a\0a\0a\09return public\0a\0aend\0a\0a\0a\0areturn black2b\0a\00local MD2 = require(\22.crypto.digest.md2\22)\0a\0alocal MD4 = require(\22.crypto.digest.md4\22)\0a\0alocal MD5 = require(\22.crypto.digest.md5\22)\0a\0alocal SHA1 = require(\22.crypto.digest.sha1\22)\0a\0alocal SHA2_256 = require(\22.crypto.digest.sha2_256\22)\0a\0alocal SHA2_512 = require(\22.crypto.digest.sha2_512\22)\0a\0alocal SHA3 = require(\22.crypto.digest.sha3\22)\0a\0alocal Blake2b = require(\22.crypto.digest.blake2b\22)\0a\0a\0a\0a\0a\0alocal digest = {\0a\0a _version = \220.0.1\22,\0a\0a md2 = MD2,\0a\0a md4 = MD4,\0a\0a md5 = MD5,\0a\0a sha1 = SHA1.sha1,\0a\0a sha2_256 = SHA2_256.sha2_256,\0a\0a sha2_512 = SHA2_512,\0a\0a sha3_256 = SHA3.sha3_256,\0a\0a sha3_512 = SHA3.sha3_512,\0a\0a keccak256 = SHA3.keccak256,\0a\0a keccak512 = SHA3.keccak512,\0a\0a blake2b = Blake2b\0a\0a}\0a\0a\0a\0a\0a\0a\0a\0a\0a\0areturn digest\0a\00\00\00\00\00local Bit = require(\22.crypto.util.bit\22);\0a\0alocal Queue = require(\22.crypto.util.queue\22);\0a\0a\0a\0alocal SUBST = {\0a\0a 0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36, 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13,\0a\0a 0x62, 0xA7, 0x05, 0xF3, 0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, 0x82, 0xCA,\0a\0a 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16, 0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12,\0a\0a 0xBE, 0x4E, 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E, 0xBB, 0x2F, 0xEE, 0x7A,\0a\0a 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, 0x07, 0x3F, 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,\0a\0a 0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E, 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03,\0a\0a 0xFF, 0x19, 0x30, 0xB3, 0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, 0xAA, 0xC6,\0a\0a 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6, 0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1,\0a\0a 0x45, 0x9D, 0x70, 0x59, 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65, 0xE6, 0x2D, 0xA8, 0x02,\0a\0a 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, 0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F,\0a\0a 0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, 0xC3, 0x5C, 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26,\0a\0a 0x2C, 0x53, 0x0D, 0x6E, 0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, 0x4D, 0x52,\0a\0a 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA, 0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A,\0a\0a 0x78, 0x88, 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, 0xE9, 0xCB, 0xD5, 0xFE, 0x3B, 0x00, 0x1D, 0x39,\0a\0a 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, 0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,\0a\0a 0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99, 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14 };\0a\0a\0a\0alocal XOR = Bit.bxor;\0a\0a\0a\0alocal MD2 = function(stream)\0a\0a local queue = Queue();\0a\0a local public = {}\0a\0a\0a\0a local X = {};\0a\0a for i = 0, 47 do\0a\0a X[i] = 0x00;\0a\0a end\0a\0a\0a\0a local C = {};\0a\0a for i = 0, 15 do\0a\0a C[i] = 0x00;\0a\0a end\0a\0a\0a\0a local processBlock = function()\0a\0a local block = {};\0a\0a\0a\0a for i = 0, 15 do\0a\0a block[i] = queue.pop();\0a\0a end\0a\0a\0a\0a for i = 0, 15 do\0a\0a X[i + 16] = block[i];\0a\0a X[i + 32] = XOR(X[i], block[i]); --mix\0a\0a end\0a\0a\0a\0a local t;\0a\0a\0a\0a --update block\0a\0a t = 0;\0a\0a for i = 0, 17 do\0a\0a for j = 0, 47 do\0a\0a X[j] = XOR(X[j], SUBST[t + 1]);\0a\0a t = X[j];\0a\0a end\0a\0a t = (t + i) % 256;\0a\0a end\0a\0a\0a\0a --update checksum\0a\0a t = C[15];\0a\0a for i = 0, 15 do\0a\0a C[i] = XOR(C[i], SUBST[XOR(block[i], t) + 1]);\0a\0a t = C[i];\0a\0a end\0a\0a\0a\0a end\0a\0a\0a\0a for b in stream do\0a\0a queue.push(b);\0a\0a if(queue.size() >= 16) then processBlock(); end\0a\0a end\0a\0a\0a\0a local i = 16 - queue.size();\0a\0a\0a\0a while queue.size() < 16 do\0a\0a queue.push(i);\0a\0a end\0a\0a\0a\0a processBlock();\0a\0a\0a\0a queue.push(C[ 0]); queue.push(C[ 1]); queue.push(C[ 2]); queue.push(C[ 3]);\0a\0a queue.push(C[ 4]); queue.push(C[ 5]); queue.push(C[ 6]); queue.push(C[ 7]);\0a\0a queue.push(C[ 8]); queue.push(C[ 9]); queue.push(C[10]); queue.push(C[11]);\0a\0a queue.push(C[12]); queue.push(C[13]); queue.push(C[14]); queue.push(C[15]);\0a\0a\0a\0a processBlock();\0a\0a\0a\0a public.asBytes = function()\0a\0a return {X[ 0], X[ 1], X[ 2], X[ 3], X[ 4], X[ 5], X[ 6], X[ 7],\0a\0a X[ 8], X[ 9], X[10], X[11], X[12], X[13], X[14], X[15]};\0a\0a end\0a\0a\0a\0a public.asHex = function()\0a\0a return string.format(\22%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\22,\0a\0a X[ 0], X[ 1], X[ 2], X[ 3], X[ 4], X[ 5], X[ 6], X[ 7],\0a\0a X[ 8], X[ 9], X[10], X[11], X[12], X[13], X[14], X[15]);\0a\0a end\0a\0a\0a\0a public.asString = function()\0a\0a return string.pack(string.rep('B', 16),\0a\0a X[ 0], X[ 1], X[ 2], X[ 3], X[ 4], X[ 5], X[ 6], X[ 7],\0a\0a X[ 8], X[ 9], X[10], X[11], X[12], X[13], X[14], X[15]);\0a\0a end\0a\0a\0a\0a return public;\0a\0a\0a\0aend\0a\0a\0a\0areturn MD2;\00\00\00\00\00local Bit = require(\22.crypto.util.bit\22);\0a\0alocal Queue = require(\22.crypto.util.queue\22);\0a\0a\0a\0alocal AND = Bit.band;\0a\0alocal OR = Bit.bor;\0a\0alocal NOT = Bit.bnot;\0a\0alocal XOR = Bit.bxor;\0a\0alocal LROT = Bit.lrotate;\0a\0alocal LSHIFT = Bit.lshift;\0a\0alocal RSHIFT = Bit.rshift;\0a\0a\0a\0a--MD4 is little-endian\0a\0alocal bytes2word = function(b0, b1, b2, b3)\0a\0a local i = b3; i = LSHIFT(i, 8);\0a\0a i = OR(i, b2); i = LSHIFT(i, 8);\0a\0a i = OR(i, b1); i = LSHIFT(i, 8);\0a\0a i = OR(i, b0);\0a\0a return i;\0a\0aend\0a\0a\0a\0alocal word2bytes = function(word)\0a\0a local b0, b1, b2, b3;\0a\0a b0 = AND(word, 0xFF); word = RSHIFT(word, 8);\0a\0a b1 = AND(word, 0xFF); word = RSHIFT(word, 8);\0a\0a b2 = AND(word, 0xFF); word = RSHIFT(word, 8);\0a\0a b3 = AND(word, 0xFF);\0a\0a return b0, b1, b2, b3;\0a\0aend\0a\0a\0a\0alocal dword2bytes = function(i)\0a\0a local b4, b5, b6, b7 = word2bytes(math.floor(i / 0x100000000));\0a\0a local b0, b1, b2, b3 = word2bytes(i);\0a\0a return b0, b1, b2, b3, b4, b5, b6, b7;\0a\0aend\0a\0a\0a\0alocal F = function(x, y, z) return OR(AND(x, y), AND(NOT(x), z)); end\0a\0alocal G = function(x, y, z) return OR(AND(x, y), OR(AND(x, z), AND(y, z))); end\0a\0alocal H = function(x, y, z) return XOR(x, XOR(y, z)); end\0a\0a\0a\0a\0a\0alocal MD4 = function(stream)\0a\0a\0a\0a local queue = Queue();\0a\0a\0a\0a local A = 0x67452301;\0a\0a local B = 0xefcdab89;\0a\0a local C = 0x98badcfe;\0a\0a local D = 0x10325476;\0a\0a local public = {};\0a\0a\0a\0a local processBlock = function()\0a\0a local a = A;\0a\0a local b = B;\0a\0a local c = C;\0a\0a local d = D;\0a\0a\0a\0a local X = {};\0a\0a\0a\0a for i = 0, 15 do\0a\0a X[i] = bytes2word(queue.pop(), queue.pop(), queue.pop(), queue.pop());\0a\0a end\0a\0a\0a\0a a = LROT(a + F(b, c, d) + X[0], 3);\0a\0a d = LROT(d + F(a, b, c) + X[1], 7);\0a\0a c = LROT(c + F(d, a, b) + X[2], 11);\0a\0a b = LROT(b + F(c, d, a) + X[3], 19);\0a\0a\0a\0a a = LROT(a + F(b, c, d) + X[4], 3);\0a\0a d = LROT(d + F(a, b, c) + X[5], 7);\0a\0a c = LROT(c + F(d, a, b) + X[6], 11);\0a\0a b = LROT(b + F(c, d, a) + X[7], 19);\0a\0a\0a\0a a = LROT(a + F(b, c, d) + X[8], 3);\0a\0a d = LROT(d + F(a, b, c) + X[9], 7);\0a\0a c = LROT(c + F(d, a, b) + X[10], 11);\0a\0a b = LROT(b + F(c, d, a) + X[11], 19);\0a\0a\0a\0a a = LROT(a + F(b, c, d) + X[12], 3);\0a\0a d = LROT(d + F(a, b, c) + X[13], 7);\0a\0a c = LROT(c + F(d, a, b) + X[14], 11);\0a\0a b = LROT(b + F(c, d, a) + X[15], 19);\0a\0a\0a\0a\0a\0a a = LROT(a + G(b, c, d) + X[0] + 0x5A827999, 3);\0a\0a d = LROT(d + G(a, b, c) + X[4] + 0x5A827999, 5);\0a\0a c = LROT(c + G(d, a, b) + X[8] + 0x5A827999, 9);\0a\0a b = LROT(b + G(c, d, a) + X[12] + 0x5A827999, 13);\0a\0a\0a\0a a = LROT(a + G(b, c, d) + X[1] + 0x5A827999, 3);\0a\0a d = LROT(d + G(a, b, c) + X[5] + 0x5A827999, 5);\0a\0a c = LROT(c + G(d, a, b) + X[9] + 0x5A827999, 9);\0a\0a b = LROT(b + G(c, d, a) + X[13] + 0x5A827999, 13);\0a\0a\0a\0a a = LROT(a + G(b, c, d) + X[2] + 0x5A827999, 3);\0a\0a d = LROT(d + G(a, b, c) + X[6] + 0x5A827999, 5);\0a\0a c = LROT(c + G(d, a, b) + X[10] + 0x5A827999, 9);\0a\0a b = LROT(b + G(c, d, a) + X[14] + 0x5A827999, 13);\0a\0a\0a\0a a = LROT(a + G(b, c, d) + X[3] + 0x5A827999, 3);\0a\0a d = LROT(d + G(a, b, c) + X[7] + 0x5A827999, 5);\0a\0a c = LROT(c + G(d, a, b) + X[11] + 0x5A827999, 9);\0a\0a b = LROT(b + G(c, d, a) + X[15] + 0x5A827999, 13);\0a\0a\0a\0a\0a\0a a = LROT(a + H(b, c, d) + X[0] + 0x6ED9EBA1, 3);\0a\0a d = LROT(d + H(a, b, c) + X[8] + 0x6ED9EBA1, 9);\0a\0a c = LROT(c + H(d, a, b) + X[4] + 0x6ED9EBA1, 11);\0a\0a b = LROT(b + H(c, d, a) + X[12] + 0x6ED9EBA1, 15);\0a\0a\0a\0a a = LROT(a + H(b, c, d) + X[2] + 0x6ED9EBA1, 3);\0a\0a d = LROT(d + H(a, b, c) + X[10] + 0x6ED9EBA1, 9);\0a\0a c = LROT(c + H(d, a, b) + X[6] + 0x6ED9EBA1, 11);\0a\0a b = LROT(b + H(c, d, a) + X[14] + 0x6ED9EBA1, 15);\0a\0a\0a\0a a = LROT(a + H(b, c, d) + X[1] + 0x6ED9EBA1, 3);\0a\0a d = LROT(d + H(a, b, c) + X[9] + 0x6ED9EBA1, 9);\0a\0a c = LROT(c + H(d, a, b) + X[5] + 0x6ED9EBA1, 11);\0a\0a b = LROT(b + H(c, d, a) + X[13] + 0x6ED9EBA1, 15);\0a\0a\0a\0a a = LROT(a + H(b, c, d) + X[3] + 0x6ED9EBA1, 3);\0a\0a d = LROT(d + H(a, b, c) + X[11] + 0x6ED9EBA1, 9);\0a\0a c = LROT(c + H(d, a, b) + X[7] + 0x6ED9EBA1, 11);\0a\0a b = LROT(b + H(c, d, a) + X[15] + 0x6ED9EBA1, 15);\0a\0a\0a\0a\0a\0a A = AND(A + a, 0xFFFFFFFF);\0a\0a B = AND(B + b, 0xFFFFFFFF);\0a\0a C = AND(C + c, 0xFFFFFFFF);\0a\0a D = AND(D + d, 0xFFFFFFFF);\0a\0a end\0a\0a \0a\0a\0a\0a for s in stream do\0a\0a queue.push(s);\0a\0a if (queue.size() >= 64) then processBlock(); end\0a\0a end\0a\0a \0a\0a local bits = queue.getHead() * 8;\0a\0a\0a\0a queue.push(0x80);\0a\0a while ((queue.size() + 7) % 64) < 63 do\0a\0a queue.push(0x00);\0a\0a end\0a\0a\0a\0a local b0, b1, b2, b3, b4, b5, b6, b7 = dword2bytes(bits);\0a\0a\0a\0a queue.push(b0);\0a\0a queue.push(b1);\0a\0a queue.push(b2);\0a\0a queue.push(b3);\0a\0a queue.push(b4);\0a\0a queue.push(b5);\0a\0a queue.push(b6);\0a\0a queue.push(b7);\0a\0a\0a\0a while queue.size() > 0 do\0a\0a processBlock();\0a\0a end\0a\0a\0a\0a public.asBytes = function()\0a\0a local b0, b1, b2, b3 = word2bytes(A);\0a\0a local b4, b5, b6, b7 = word2bytes(B);\0a\0a local b8, b9, b10, b11 = word2bytes(C);\0a\0a local b12, b13, b14, b15 = word2bytes(D);\0a\0a\0a\0a return {b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15};\0a\0a end\0a\0a\0a\0a public.asHex = function()\0a\0a local b0, b1, b2, b3 = word2bytes(A);\0a\0a local b4, b5, b6, b7 = word2bytes(B);\0a\0a local b8, b9, b10, b11 = word2bytes(C);\0a\0a local b12, b13, b14, b15 = word2bytes(D);\0a\0a\0a\0a return string.format(\22%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\22,\0a\0a b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15);\0a\0a end\0a\0a\0a\0a public.asString = function()\0a\0a local b0, b1, b2, b3 = word2bytes(A);\0a\0a local b4, b5, b6, b7 = word2bytes(B);\0a\0a local b8, b9, b10, b11 = word2bytes(C);\0a\0a local b12, b13, b14, b15 = word2bytes(D);\0a\0a\0a\0a return string.pack(string.rep('B', 16),\0a\0a b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15);\0a\0a end\0a\0a\0a\0a return public;\0a\0a\0a\0aend\0a\0a\0a\0areturn MD4;")
(data $.rodata.11 (;11;) (i64.const 233936) "local Bit = require(\22.crypto.util.bit\22);\0a\0alocal Queue = require(\22.crypto.util.queue\22);\0a\0a\0a\0alocal SHIFT = {\0a\0a 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,\0a\0a 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,\0a\0a 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,\0a\0a 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21};\0a\0a\0a\0alocal CONSTANTS = {\0a\0a 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,\0a\0a 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,\0a\0a 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,\0a\0a 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,\0a\0a 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,\0a\0a 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,\0a\0a 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,\0a\0a 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,\0a\0a 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,\0a\0a 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,\0a\0a 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,\0a\0a 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,\0a\0a 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,\0a\0a 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,\0a\0a 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,\0a\0a 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391};\0a\0a\0a\0alocal AND = Bit.band;\0a\0alocal OR = Bit.bor;\0a\0alocal NOT = Bit.bnot;\0a\0alocal XOR = Bit.bxor;\0a\0alocal LROT = Bit.lrotate;\0a\0alocal LSHIFT = Bit.lshift;\0a\0alocal RSHIFT = Bit.rshift;\0a\0a\0a\0a--MD5 is little-endian\0a\0alocal bytes2word = function(b0, b1, b2, b3)\0a\0a local i = b3; i = LSHIFT(i, 8);\0a\0a i = OR(i, b2); i = LSHIFT(i, 8);\0a\0a i = OR(i, b1); i = LSHIFT(i, 8);\0a\0a i = OR(i, b0);\0a\0a return i;\0a\0aend\0a\0a\0a\0alocal word2bytes = function(word)\0a\0a local b0, b1, b2, b3;\0a\0a b0 = AND(word, 0xFF); word = RSHIFT(word, 8);\0a\0a b1 = AND(word, 0xFF); word = RSHIFT(word, 8);\0a\0a b2 = AND(word, 0xFF); word = RSHIFT(word, 8);\0a\0a b3 = AND(word, 0xFF);\0a\0a return b0, b1, b2, b3;\0a\0aend\0a\0a\0a\0alocal dword2bytes = function(i)\0a\0a local b4, b5, b6, b7 = word2bytes(math.floor(i / 0x100000000));\0a\0a local b0, b1, b2, b3 = word2bytes(i);\0a\0a return b0, b1, b2, b3, b4, b5, b6, b7;\0a\0aend\0a\0a\0a\0alocal F = function(x, y, z) return OR(AND(x, y), AND(NOT(x), z)); end\0a\0alocal G = function(x, y, z) return OR(AND(x, z), AND(y, NOT(z))); end\0a\0alocal H = function(x, y, z) return XOR(x, XOR(y, z)); end\0a\0alocal I = function(x, y, z) return XOR(y, OR(x, NOT(z))); end\0a\0a\0a\0alocal MD5 = function(stream)\0a\0a\0a\0a local queue = Queue();\0a\0a\0a\0a local A = 0x67452301;\0a\0a local B = 0xefcdab89;\0a\0a local C = 0x98badcfe;\0a\0a local D = 0x10325476;\0a\0a local public = {};\0a\0a\0a\0a local processBlock = function()\0a\0a local a = A;\0a\0a local b = B;\0a\0a local c = C;\0a\0a local d = D;\0a\0a\0a\0a local X = {};\0a\0a\0a\0a for i = 1, 16 do\0a\0a X[i] = bytes2word(queue.pop(), queue.pop(), queue.pop(), queue.pop());\0a\0a end\0a\0a\0a\0a for i = 0, 63 do\0a\0a local f, g, temp;\0a\0a\0a\0a if (0 <= i) and (i <= 15) then\0a\0a f = F(b, c, d);\0a\0a g = i;\0a\0a elseif (16 <= i) and (i <= 31) then\0a\0a f = G(b, c, d);\0a\0a g = (5 * i + 1) % 16;\0a\0a elseif (32 <= i) and (i <= 47) then\0a\0a f = H(b, c, d);\0a\0a g = (3 * i + 5) % 16;\0a\0a elseif (48 <= i) and (i <= 63) then\0a\0a f = I(b, c, d);\0a\0a g = (7 * i) % 16;\0a\0a end\0a\0a temp = d;\0a\0a d = c;\0a\0a c = b;\0a\0a b = b + LROT((a + f + CONSTANTS[i + 1] + X[g + 1]), SHIFT[i + 1]);\0a\0a a = temp;\0a\0a end\0a\0a\0a\0a A = AND(A + a, 0xFFFFFFFF);\0a\0a B = AND(B + b, 0xFFFFFFFF);\0a\0a C = AND(C + c, 0xFFFFFFFF);\0a\0a D = AND(D + d, 0xFFFFFFFF);\0a\0a end\0a\0a\0a\0a for s in stream do\0a\0a queue.push(s);\0a\0a if (queue.size() >= 64) then processBlock(); end\0a\0a end\0a\0a\0a\0a local bits = queue.getHead() * 8;\0a\0a\0a\0a queue.push(0x80);\0a\0a while ((queue.size() + 7) % 64) < 63 do\0a\0a queue.push(0x00);\0a\0a end\0a\0a\0a\0a local b0, b1, b2, b3, b4, b5, b6, b7 = dword2bytes(bits);\0a\0a\0a\0a queue.push(b0);\0a\0a queue.push(b1);\0a\0a queue.push(b2);\0a\0a queue.push(b3);\0a\0a queue.push(b4);\0a\0a queue.push(b5);\0a\0a queue.push(b6);\0a\0a queue.push(b7);\0a\0a\0a\0a while queue.size() > 0 do\0a\0a processBlock();\0a\0a end\0a\0a\0a\0a public.asBytes = function()\0a\0a local b0, b1, b2, b3 = word2bytes(A);\0a\0a local b4, b5, b6, b7 = word2bytes(B);\0a\0a local b8, b9, b10, b11 = word2bytes(C);\0a\0a local b12, b13, b14, b15 = word2bytes(D);\0a\0a\0a\0a return {b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15};\0a\0a end\0a\0a\0a\0a public.asHex = function()\0a\0a local b0, b1, b2, b3 = word2bytes(A);\0a\0a local b4, b5, b6, b7 = word2bytes(B);\0a\0a local b8, b9, b10, b11 = word2bytes(C);\0a\0a local b12, b13, b14, b15 = word2bytes(D);\0a\0a\0a\0a return string.format(\22%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\22,\0a\0a b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15);\0a\0a end\0a\0a\0a\0a public.asString = function()\0a\0a local b0, b1, b2, b3 = word2bytes(A);\0a\0a local b4, b5, b6, b7 = word2bytes(B);\0a\0a local b8, b9, b10, b11 = word2bytes(C);\0a\0a local b12, b13, b14, b15 = word2bytes(D);\0a\0a\0a\0a return string.pack(string.rep('B', 16),\0a\0a b0, b1, b2, b3, b4, b5, b6, b7, b8,\0a\0a b9, b10, b11, b12, b13, b14, b15\0a\0a )\0a\0a end\0a\0a\0a\0a return public;\0a\0a\0a\0aend\0a\0a\0a\0areturn MD5;\00\00local Bit = require(\22.crypto.util.bit\22);\0a\0alocal Queue = require(\22.crypto.util.queue\22);\0a\0a\0a\0alocal AND = Bit.band;\0a\0alocal OR = Bit.bor;\0a\0alocal XOR = Bit.bxor;\0a\0alocal LROT = Bit.lrotate;\0a\0alocal LSHIFT = Bit.lshift;\0a\0alocal RSHIFT = Bit.rshift;\0a\0a\0a\0a--SHA1 is big-endian\0a\0alocal bytes2word = function(b0, b1, b2, b3)\0a\0a local i = b0; i = LSHIFT(i, 8);\0a\0a i = OR(i, b1); i = LSHIFT(i, 8);\0a\0a i = OR(i, b2); i = LSHIFT(i, 8);\0a\0a i = OR(i, b3);\0a\0a return i;\0a\0aend\0a\0a\0a\0alocal word2bytes = function(word)\0a\0a local b0, b1, b2, b3;\0a\0a b3 = AND(word, 0xFF); word = RSHIFT(word, 8);\0a\0a b2 = AND(word, 0xFF); word = RSHIFT(word, 8);\0a\0a b1 = AND(word, 0xFF); word = RSHIFT(word, 8);\0a\0a b0 = AND(word, 0xFF);\0a\0a return b0, b1, b2, b3;\0a\0aend\0a\0a\0a\0alocal dword2bytes = function(i)\0a\0a local b4, b5, b6, b7 = word2bytes(i);\0a\0a local b0, b1, b2, b3 = word2bytes(math.floor(i / 0x100000000));\0a\0a return b0, b1, b2, b3, b4, b5, b6, b7;\0a\0aend\0a\0a\0a\0alocal F = function(x, y, z) return XOR(z, AND(x, XOR(y, z))); end\0a\0alocal G = function(x, y, z) return XOR(x, XOR(y, z)); end\0a\0alocal H = function(x, y, z) return OR(AND(x, OR(y, z)), AND(y, z)); end\0a\0alocal I = function(x, y, z) return XOR(x, XOR(y, z)); end\0a\0a\0a\0alocal SHA1 = function()\0a\0a\0a\0a local queue = Queue();\0a\0a\0a\0a local h0 = 0x67452301;\0a\0a local h1 = 0xEFCDAB89;\0a\0a local h2 = 0x98BADCFE;\0a\0a local h3 = 0x10325476;\0a\0a local h4 = 0xC3D2E1F0;\0a\0a\0a\0a local public = {};\0a\0a\0a\0a local processBlock = function()\0a\0a local a = h0;\0a\0a local b = h1;\0a\0a local c = h2;\0a\0a local d = h3;\0a\0a local e = h4;\0a\0a local temp;\0a\0a local k;\0a\0a\0a\0a local w = {};\0a\0a for i = 0, 15 do\0a\0a w[i] = bytes2word(queue.pop(), queue.pop(), queue.pop(), queue.pop());\0a\0a end\0a\0a\0a\0a for i = 16, 79 do\0a\0a w[i] = LROT((XOR(XOR(w[i - 3], w[i - 8]), XOR(w[i - 14], w[i - 16]))), 1);\0a\0a end\0a\0a\0a\0a for i = 0, 79 do\0a\0a if (i <= 19) then\0a\0a temp = F(b, c, d);\0a\0a k = 0x5A827999;\0a\0a elseif (i <= 39) then\0a\0a temp = G(b, c, d);\0a\0a k = 0x6ED9EBA1;\0a\0a elseif (i <= 59) then\0a\0a temp = H(b, c, d);\0a\0a k = 0x8F1BBCDC;\0a\0a else\0a\0a temp = I(b, c, d);\0a\0a k = 0xCA62C1D6;\0a\0a end\0a\0a temp = LROT(a, 5) + temp + e + k + w[i];\0a\0a e = d;\0a\0a d = c;\0a\0a c = LROT(b, 30);\0a\0a b = a;\0a\0a a = temp;\0a\0a end\0a\0a\0a\0a h0 = AND(h0 + a, 0xFFFFFFFF);\0a\0a h1 = AND(h1 + b, 0xFFFFFFFF);\0a\0a h2 = AND(h2 + c, 0xFFFFFFFF);\0a\0a h3 = AND(h3 + d, 0xFFFFFFFF);\0a\0a h4 = AND(h4 + e, 0xFFFFFFFF);\0a\0a end\0a\0a\0a\0a public.init = function()\0a\0a queue.reset();\0a\0a h0 = 0x67452301;\0a\0a h1 = 0xEFCDAB89;\0a\0a h2 = 0x98BADCFE;\0a\0a h3 = 0x10325476;\0a\0a h4 = 0xC3D2E1F0;\0a\0a return public;\0a\0a end\0a\0a\0a\0a\0a\0a public.update = function(bytes)\0a\0a for b in bytes do\0a\0a queue.push(b);\0a\0a if queue.size() >= 64 then processBlock(); end\0a\0a end\0a\0a\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.finish = function()\0a\0a local bits = queue.getHead() * 8;\0a\0a\0a\0a queue.push(0x80);\0a\0a while ((queue.size() + 7) % 64) < 63 do\0a\0a queue.push(0x00);\0a\0a end\0a\0a\0a\0a local b0, b1, b2, b3, b4, b5, b6, b7 = dword2bytes(bits);\0a\0a\0a\0a queue.push(b0);\0a\0a queue.push(b1);\0a\0a queue.push(b2);\0a\0a queue.push(b3);\0a\0a queue.push(b4);\0a\0a queue.push(b5);\0a\0a queue.push(b6);\0a\0a queue.push(b7);\0a\0a\0a\0a while queue.size() > 0 do\0a\0a processBlock();\0a\0a end\0a\0a\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.asBytes = function()\0a\0a local b0, b1, b2, b3 = word2bytes(h0);\0a\0a local b4, b5, b6, b7 = word2bytes(h1);\0a\0a local b8, b9, b10, b11 = word2bytes(h2);\0a\0a local b12, b13, b14, b15 = word2bytes(h3);\0a\0a local b16, b17, b18, b19 = word2bytes(h4);\0a\0a\0a\0a return {b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15, b16, b17, b18, b19};\0a\0a end\0a\0a\0a\0a public.asHex = function()\0a\0a local b0, b1, b2, b3 = word2bytes(h0);\0a\0a local b4, b5, b6, b7 = word2bytes(h1);\0a\0a local b8, b9, b10, b11 = word2bytes(h2);\0a\0a local b12, b13, b14, b15 = word2bytes(h3);\0a\0a local b16, b17, b18, b19 = word2bytes(h4);\0a\0a\0a\0a return string.format(\22%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\22,\0a\0a b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15, b16, b17, b18, b19);\0a\0a end\0a\0a\0a\0a public.asString = function()\0a\0a local b0, b1, b2, b3 = word2bytes(h0);\0a\0a local b4, b5, b6, b7 = word2bytes(h1);\0a\0a local b8, b9, b10, b11 = word2bytes(h2);\0a\0a local b12, b13, b14, b15 = word2bytes(h3);\0a\0a local b16, b17, b18, b19 = word2bytes(h4);\0a\0a\0a\0a return string.pack(string.rep('B', 20),\0a\0a b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15, b16, b17, b18, b19);\0a\0a end\0a\0a\0a\0a return public;\0a\0aend\0a\0a\0a\0a\0a\0alocal sha1 = function(stream)\0a\0a local result = SHA1()\0a\0a .update(stream)\0a\0a .finish()\0a\0a return result\0a\0aend\0a\0a\0a\0areturn {\0a\0a sha1 = sha1,\0a\0a SHA1 = SHA1\0a\0a}\00\00\00\00\00\00\00local Bit = require(\22.crypto.util.bit\22);\0a\0alocal Queue = require(\22.crypto.util.queue\22);\0a\0alocal Stream = require(\22.crypto.util.stream\22);\0a\0a\0a\0alocal CONSTANTS = {\0a\0a 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\0a\0a 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\0a\0a 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\0a\0a 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\0a\0a 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\0a\0a 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\0a\0a 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\0a\0a 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 };\0a\0a\0a\0alocal fmt = \22%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\22 ..\0a\0a \22%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\22\0a\0a\0a\0alocal AND = Bit.band;\0a\0alocal OR = Bit.bor;\0a\0alocal NOT = Bit.bnot;\0a\0alocal XOR = Bit.bxor;\0a\0alocal RROT = Bit.rrotate;\0a\0alocal LSHIFT = Bit.lshift;\0a\0alocal RSHIFT = Bit.rshift;\0a\0a\0a\0a--SHA2 is big-endian\0a\0alocal bytes2word = function(b0, b1, b2, b3)\0a\0a local i = b0; i = LSHIFT(i, 8);\0a\0a i = OR(i, b1); i = LSHIFT(i, 8);\0a\0a i = OR(i, b2); i = LSHIFT(i, 8);\0a\0a i = OR(i, b3);\0a\0a return i;\0a\0aend\0a\0a\0a\0alocal word2bytes = function(word)\0a\0a local b0, b1, b2, b3;\0a\0a b3 = AND(word, 0xFF); word = RSHIFT(word, 8);\0a\0a b2 = AND(word, 0xFF); word = RSHIFT(word, 8);\0a\0a b1 = AND(word, 0xFF); word = RSHIFT(word, 8);\0a\0a b0 = AND(word, 0xFF);\0a\0a return b0, b1, b2, b3;\0a\0aend\0a\0a\0a\0alocal dword2bytes = function(i)\0a\0a local b4, b5, b6, b7 = word2bytes(i);\0a\0a local b0, b1, b2, b3 = word2bytes(math.floor(i / 0x100000000));\0a\0a return b0, b1, b2, b3, b4, b5, b6, b7;\0a\0aend\0a\0a\0a\0a\0a\0alocal SHA2_256 = function()\0a\0a\0a\0a local queue = Queue();\0a\0a\0a\0a local h0 = 0x6a09e667;\0a\0a local h1 = 0xbb67ae85;\0a\0a local h2 = 0x3c6ef372;\0a\0a local h3 = 0xa54ff53a;\0a\0a local h4 = 0x510e527f;\0a\0a local h5 = 0x9b05688c;\0a\0a local h6 = 0x1f83d9ab;\0a\0a local h7 = 0x5be0cd19;\0a\0a\0a\0a local public = {};\0a\0a\0a\0a local processBlock = function()\0a\0a local a = h0;\0a\0a local b = h1;\0a\0a local c = h2;\0a\0a local d = h3;\0a\0a local e = h4;\0a\0a local f = h5;\0a\0a local g = h6;\0a\0a local h = h7;\0a\0a\0a\0a local w = {};\0a\0a\0a\0a for i = 0, 15 do\0a\0a w[i] = bytes2word(queue.pop(), queue.pop(), queue.pop(), queue.pop());\0a\0a end\0a\0a\0a\0a for i = 16, 63 do\0a\0a local s0 = XOR(RROT(w[i - 15], 7), XOR(RROT(w[i - 15], 18), RSHIFT(w[i - 15], 3)));\0a\0a local s1 = XOR(RROT(w[i - 2], 17), XOR(RROT(w[i - 2], 19), RSHIFT(w[i - 2], 10)));\0a\0a w[i] = AND(w[i - 16] + s0 + w[i - 7] + s1, 0xFFFFFFFF);\0a\0a end\0a\0a\0a\0a for i = 0, 63 do\0a\0a local s1 = XOR(RROT(e, 6), XOR(RROT(e, 11), RROT(e, 25)));\0a\0a local ch = XOR(AND(e, f), AND(NOT(e), g));\0a\0a local temp1 = h + s1 + ch + CONSTANTS[i + 1] + w[i];\0a\0a local s0 = XOR(RROT(a, 2), XOR(RROT(a, 13), RROT(a, 22)));\0a\0a local maj = XOR(AND(a, b), XOR(AND(a, c), AND(b, c)));\0a\0a local temp2 = s0 + maj;\0a\0a\0a\0a h = g;\0a\0a g = f;\0a\0a f = e;\0a\0a e = d + temp1;\0a\0a d = c;\0a\0a c = b;\0a\0a b = a;\0a\0a a = temp1 + temp2;\0a\0a end\0a\0a\0a\0a h0 = AND(h0 + a, 0xFFFFFFFF);\0a\0a h1 = AND(h1 + b, 0xFFFFFFFF);\0a\0a h2 = AND(h2 + c, 0xFFFFFFFF);\0a\0a h3 = AND(h3 + d, 0xFFFFFFFF);\0a\0a h4 = AND(h4 + e, 0xFFFFFFFF);\0a\0a h5 = AND(h5 + f, 0xFFFFFFFF);\0a\0a h6 = AND(h6 + g, 0xFFFFFFFF);\0a\0a h7 = AND(h7 + h, 0xFFFFFFFF);\0a\0a end\0a\0a\0a\0a public.init = function()\0a\0a queue.reset();\0a\0a\0a\0a h0 = 0x6a09e667;\0a\0a h1 = 0xbb67ae85;\0a\0a h2 = 0x3c6ef372;\0a\0a h3 = 0xa54ff53a;\0a\0a h4 = 0x510e527f;\0a\0a h5 = 0x9b05688c;\0a\0a h6 = 0x1f83d9ab;\0a\0a h7 = 0x5be0cd19;\0a\0a\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.update = function(bytes)\0a\0a for b in bytes do\0a\0a queue.push(b);\0a\0a if queue.size() >= 64 then processBlock(); end\0a\0a end\0a\0a\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.finish = function()\0a\0a local bits = queue.getHead() * 8;\0a\0a\0a\0a queue.push(0x80);\0a\0a while ((queue.size() + 7) % 64) < 63 do\0a\0a queue.push(0x00);\0a\0a end\0a\0a\0a\0a local b0, b1, b2, b3, b4, b5, b6, b7 = dword2bytes(bits);\0a\0a\0a\0a queue.push(b0);\0a\0a queue.push(b1);\0a\0a queue.push(b2);\0a\0a queue.push(b3);\0a\0a queue.push(b4);\0a\0a queue.push(b5);\0a\0a queue.push(b6);\0a\0a queue.push(b7);\0a\0a\0a\0a while queue.size() > 0 do\0a\0a processBlock();\0a\0a end\0a\0a\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.asBytes = function()\0a\0a local b0, b1, b2, b3 = word2bytes(h0);\0a\0a local b4, b5, b6, b7 = word2bytes(h1);\0a\0a local b8, b9, b10, b11 = word2bytes(h2);\0a\0a local b12, b13, b14, b15 = word2bytes(h3);\0a\0a local b16, b17, b18, b19 = word2bytes(h4);\0a\0a local b20, b21, b22, b23 = word2bytes(h5);\0a\0a local b24, b25, b26, b27 = word2bytes(h6);\0a\0a local b28, b29, b30, b31 = word2bytes(h7);\0a\0a\0a\0a\0a\0a return { b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15\0a\0a , b16, b17, b18, b19, b20, b21, b22, b23, b24, b25, b26, b27, b28, b29, b30, b31};\0a\0a end\0a\0a\0a\0a public.asHex = function()\0a\0a local b0, b1, b2, b3 = word2bytes(h0);\0a\0a local b4, b5, b6, b7 = word2bytes(h1);\0a\0a local b8, b9, b10, b11 = word2bytes(h2);\0a\0a local b12, b13, b14, b15 = word2bytes(h3);\0a\0a local b16, b17, b18, b19 = word2bytes(h4);\0a\0a local b20, b21, b22, b23 = word2bytes(h5);\0a\0a local b24, b25, b26, b27 = word2bytes(h6);\0a\0a local b28, b29, b30, b31 = word2bytes(h7);\0a\0a\0a\0a return string.format(fmt, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15\0a\0a , b16, b17, b18, b19, b20, b21, b22, b23, b24, b25, b26, b27, b28, b29, b30, b31);\0a\0a end\0a\0a\0a\0a public.asString = function()\0a\0a local b0, b1, b2, b3 = word2bytes(h0);\0a\0a local b4, b5, b6, b7 = word2bytes(h1);\0a\0a local b8, b9, b10, b11 = word2bytes(h2);\0a\0a local b12, b13, b14, b15 = word2bytes(h3);\0a\0a local b16, b17, b18, b19 = word2bytes(h4);\0a\0a local b20, b21, b22, b23 = word2bytes(h5);\0a\0a local b24, b25, b26, b27 = word2bytes(h6);\0a\0a local b28, b29, b30, b31 = word2bytes(h7);\0a\0a\0a\0a return string.pack(string.rep('B', 32),\0a\0a b0, b1, b2, b3, b4, b5, b6, b7, b8,\0a\0a b9, b10, b11, b12, b13, b14, b15,\0a\0a b16, b17, b18, b19, b20, b21, b22, b23, b24,\0a\0a b25, b26, b27, b28, b29, b30, b31);\0a\0a end\0a\0a\0a\0a return public;\0a\0a\0a\0aend\0a\0a\0a\0a--- @class Stream : table\0a\0a\0a\0a--- @param stream (Stream) - A function that returns the next byte of the stream, or nil if the stream has ended.\0a\0a--- @returns table - A table containing the hash in bytes, string, and hex formats.\0a\0alocal sha2_256 = function(stream)\0a\0a local result = SHA2_256()\0a\0a .update(stream)\0a\0a .finish()\0a\0a return result\0a\0aend\0a\0a\0a\0areturn {\0a\0a sha2_256 = sha2_256,\0a\0a SHA2_256 = SHA2_256\0a\0a};\0a\00\00local Hex = require(\22.crypto.util.hex\22)\0a\0a\0a\0alocal k512 = {\0a\0a0x428a2f98d728ae22,0x7137449123ef65cd,0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc,\0a\0a0x3956c25bf348b538,0x59f111f1b605d019,0x923f82a4af194f9b,0xab1c5ed5da6d8118,\0a\0a0xd807aa98a3030242,0x12835b0145706fbe,0x243185be4ee4b28c,0x550c7dc3d5ffb4e2,\0a\0a0x72be5d74f27b896f,0x80deb1fe3b1696b1,0x9bdc06a725c71235,0xc19bf174cf692694,\0a\0a0xe49b69c19ef14ad2,0xefbe4786384f25e3,0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65,\0a\0a0x2de92c6f592b0275,0x4a7484aa6ea6e483,0x5cb0a9dcbd41fbd4,0x76f988da831153b5,\0a\0a0x983e5152ee66dfab,0xa831c66d2db43210,0xb00327c898fb213f,0xbf597fc7beef0ee4,\0a\0a0xc6e00bf33da88fc2,0xd5a79147930aa725,0x06ca6351e003826f,0x142929670a0e6e70,\0a\0a0x27b70a8546d22ffc,0x2e1b21385c26c926,0x4d2c6dfc5ac42aed,0x53380d139d95b3df,\0a\0a0x650a73548baf63de,0x766a0abb3c77b2a8,0x81c2c92e47edaee6,0x92722c851482353b,\0a\0a0xa2bfe8a14cf10364,0xa81a664bbc423001,0xc24b8b70d0f89791,0xc76c51a30654be30,\0a\0a0xd192e819d6ef5218,0xd69906245565a910,0xf40e35855771202a,0x106aa07032bbd1b8,\0a\0a0x19a4c116b8d2d0c8,0x1e376c085141ab53,0x2748774cdf8eeb99,0x34b0bcb5e19b48a8,\0a\0a0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb,0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3,\0a\0a0x748f82ee5defb2fc,0x78a5636f43172f60,0x84c87814a1f0ab72,0x8cc702081a6439ec,\0a\0a0x90befffa23631e28,0xa4506cebde82bde9,0xbef9a3f7b2c67915,0xc67178f2e372532b,\0a\0a0xca273eceea26619c,0xd186b8c721c0c207,0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178,\0a\0a0x06f067aa72176fba,0x0a637dc5a2c898a6,0x113f9804bef90dae,0x1b710b35131c471b,\0a\0a0x28db77f523047d84,0x32caab7b40c72493,0x3c9ebe0a15c9bebc,0x431d67c49c100d4c,\0a\0a0x4cc5d4becb3e42b6,0x597f299cfc657e2a,0x5fcb6fab3ad6faec,0x6c44198c4a475817\0a\0a}\0a\0a\0a\0alocal function pad128(msg, len)\0a\0a\09local extra = 128 - ((len + 1 + 8) % 128)\0a\0a\09len = string.pack(\22>I8\22, len * 8)\0a\0a\09msg = msg .. \22\5c128\22 .. string.rep(\22\5c0\22, extra) .. len\0a\0a\09assert(#msg % 128 == 0)\0a\0a\09return msg\0a\0aend\0a\0a\0a\0alocal ww512 = {}\0a\0a\0a\0a--- SHA-512 hash function.\0a\0a--- @param msg string - The message to hash.\0a\0a--- @returns table - A table containing the hash in bytes, string, and hex formats.\0a\0alocal function sha512 (msg)\0a\0a\09msg = pad128(msg, #msg)\0a\0a\09local h1, h2, h3, h4, h5, h6, h7, h8 = \0a\0a\09\090x6a09e667f3bcc908, 0xbb67ae8584caa73b,\0a\0a\09\090x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,\0a\0a\09\090x510e527fade682d1, 0x9b05688c2b3e6c1f,\0a\0a\09\090x1f83d9abfb41bd6b, 0x5be0cd19137e2179\0a\0a\09local k = k512\0a\0a\09local w = ww512\0a\0a\09local mlen = #msg\0a\0a\0a\0a\09for i = 1, mlen, 128 do\0a\0a\09\09w[1], w[2], w[3], w[4], w[5], w[6], w[7], w[8], \0a\0a\09\09w[9], w[10], w[11], w[12], w[13], w[14], w[15], w[16]\0a\0a\09\09= string.unpack(\22>i8i8i8i8i8i8i8i8i8i8i8i8i8i8i8i8\22, msg, i)\0a\0a\09\09-- mix msg block in state\0a\0a\0a\0a\09\09for j = 17, 80 do\0a\0a\09\09\09local a = w[j-15]\0a\0a\09\09\09local b = w[j-2]\0a\0a\09\09\09w[j] = (a >> 1 ~ a >> 7 ~ a >> 8 ~ a << 56 ~ a << 63)\0a\0a\09\09\09 + (b >> 6 ~ b >> 19 ~ b >> 61 ~ b << 3 ~ b << 45) \0a\0a\09\09\09 + w[j-7] + w[j-16]\0a\0a\09\09end\0a\0a\09\09local a, b, c, d, e, f, g, h = h1, h2, h3, h4, h5, h6, h7, h8\0a\0a\09\09-- main state permutation\0a\0a\09\09for j = 1, 80 do\0a\0a\09\09\09local z = (e >> 14 ~ e >> 18 ~ e >> 41 ~ e << 23 \0a\0a\09\09\09\09 ~ e << 46 ~ e << 50) \0a\0a\09\09\09\09+ (g ~ e & (f ~ g)) + h + k[j] + w[j]\0a\0a\09\09\09h = g\0a\0a\09\09\09g = f\0a\0a\09\09\09f = e\0a\0a\09\09\09e = z + d\0a\0a\09\09\09d = c\0a\0a\09\09\09c = b\0a\0a\09\09\09b = a\0a\0a\09\09\09a = z + ((a ~ c) & d ~ a & c) \0a\0a\09\09\09 + (a >> 28 ~ a >> 34 ~ a >> 39 ~ a << 25 \0a\0a\09\09\09\09~ a << 30 ~ a << 36)\0a\0a\09\09end\0a\0a\09\09h1 = h1 + a\0a\0a\09\09h2 = h2 + b \0a\0a\09\09h3 = h3 + c \0a\0a\09\09h4 = h4 + d \0a\0a\09\09h5 = h5 + e \0a\0a\09\09h6 = h6 + f \0a\0a\09\09h7 = h7 + g \0a\0a\09\09h8 = h8 + h \0a\0a\09end\0a\0a\0a\0a\09local public = {}\0a\0a\0a\0a\09public.asBytes = function()\0a\0a\09\09return { h1, h2, h3, h4, h5, h6, h7, h8}\0a\0a\09end\0a\0a\0a\0a\09public.asString = function()\0a\0a\09\09return string.pack(\22>i8i8i8i8i8i8i8i8\22, h1, h2, h3, h4, h5, h6, h7, h8)\0a\0a\09end\0a\0a\0a\0a\09public.asHex = function()\0a\0a\09\09return Hex.stringToHex(string.pack(\22>i8i8i8i8i8i8i8i8\22, h1, h2, h3, h4, h5, h6, h7, h8))\0a\0a\09end\0a\0a\0a\0a\09return public\0a\0aend\0a\0a\0a\0areturn sha512\0a\00\00\00\00\00\00\00\00local Hex = require(\22.crypto.util.hex\22);\0a\0a\0a\0alocal ROUNDS = 24\0a\0a\0a\0alocal roundConstants = {\0a\0a0x0000000000000001,\0a\0a0x0000000000008082,\0a\0a0x800000000000808A,\0a\0a0x8000000080008000,\0a\0a0x000000000000808B,\0a\0a0x0000000080000001,\0a\0a0x8000000080008081,\0a\0a0x8000000000008009,\0a\0a0x000000000000008A,\0a\0a0x0000000000000088,\0a\0a0x0000000080008009,\0a\0a0x000000008000000A,\0a\0a0x000000008000808B,\0a\0a0x800000000000008B,\0a\0a0x8000000000008089,\0a\0a0x8000000000008003,\0a\0a0x8000000000008002,\0a\0a0x8000000000000080,\0a\0a0x000000000000800A,\0a\0a0x800000008000000A,\0a\0a0x8000000080008081,\0a\0a0x8000000000008080,\0a\0a0x0000000080000001,\0a\0a0x8000000080008008\0a\0a}\0a\0a\0a\0alocal rotationOffsets = {\0a\0a-- ordered for [x][y] dereferencing, so appear flipped here:\0a\0a{0, 36, 3, 41, 18},\0a\0a{1, 44, 10, 45, 2},\0a\0a{62, 6, 43, 15, 61},\0a\0a{28, 55, 25, 21, 56},\0a\0a{27, 20, 39, 8, 14}\0a\0a}\0a\0a\0a\0a\0a\0a\0a\0a-- the full permutation function\0a\0alocal function keccakF(st)\0a\0a\09local permuted = st.permuted\0a\0a\09local parities = st.parities\0a\0a\09for round = 1, ROUNDS do\0a\0a\09\09-- theta()\0a\0a\09\09for x = 1,5 do\0a\0a\09\09\09parities[x] = 0\0a\0a\09\09\09local sx = st[x]\0a\0a\09\09\09for y = 1,5 do parities[x] = parities[x] ~ sx[y] end\0a\0a\09\09end\0a\0a\09\09--\0a\0a\09\09-- unroll the following loop\0a\0a\09\09--for x = 1,5 do\0a\0a\09\09--\09local p5 = parities[(x)%5 + 1]\0a\0a\09\09--\09local flip = parities[(x-2)%5 + 1] ~ ( p5 << 1 | p5 >> 63)\0a\0a\09\09--\09for y = 1,5 do st[x][y] = st[x][y] ~ flip end\0a\0a\09\09--end\0a\0a\09\09local p5, flip, s\0a\0a\09\09--x=1\0a\0a\09\09p5 = parities[2]\0a\0a\09\09flip = parities[5] ~ (p5 << 1 | p5 >> 63)\0a\0a\09\09s = st[1]\0a\0a\09\09for y = 1,5 do s[y] = s[y] ~ flip end\0a\0a\09\09--x=2\0a\0a\09\09p5 = parities[3]\0a\0a\09\09flip = parities[1] ~ (p5 << 1 | p5 >> 63)\0a\0a\09\09s = st[2]\0a\0a\09\09for y = 1,5 do s[y] = s[y] ~ flip end\0a\0a\09\09--x=3\0a\0a\09\09p5 = parities[4]\0a\0a\09\09flip = parities[2] ~ (p5 << 1 | p5 >> 63)\0a\0a\09\09s = st[3]\0a\0a\09\09for y = 1,5 do s[y] = s[y] ~ flip end\0a\0a\09\09--x=4\0a\0a\09\09p5 = parities[5]\0a\0a\09\09flip = parities[3] ~ (p5 << 1 | p5 >> 63)\0a\0a\09\09s = st[4]\0a\0a\09\09for y = 1,5 do s[y] = s[y] ~ flip end\0a\0a\09\09--x=5\0a\0a\09\09p5 = parities[1]\0a\0a\09\09flip = parities[4] ~ (p5 << 1 | p5 >> 63)\0a\0a\09\09s = st[5]\0a\0a\09\09for y = 1,5 do s[y] = s[y] ~ flip end\0a\0a\0a\0a\09\09-- rhopi()\0a\0a\09\09for y = 1,5 do\0a\0a\09\09\09local py = permuted[y]\0a\0a\09\09\09local r\0a\0a\09\09\09for x = 1,5 do\0a\0a\09\09\09\09s, r = st[x][y], rotationOffsets[x][y]\0a\0a\09\09\09\09py[(2*x + 3*y)%5 + 1] = (s << r | s >> (64-r))\0a\0a\09\09\09end\0a\0a\09\09end\0a\0a\0a\0a\09\09-- chi() - unroll the loop\0a\0a\09\09--for x = 1,5 do\0a\0a\09\09--\09for y = 1,5 do\0a\0a\09\09--\09\09local combined = (~ permuted[(x)%5 +1][y]) & permuted[(x+1)%5 +1][y]\0a\0a\09\09--\09\09st[x][y] = permuted[x][y] ~ combined\0a\0a\09\09--\09end\0a\0a\09\09--end\0a\0a\0a\0a\09\09local p, p1, p2\0a\0a\09\09--x=1\0a\0a\09\09s, p, p1, p2 = st[1], permuted[1], permuted[2], permuted[3]\0a\0a\09\09for y = 1,5 do s[y] = p[y] ~ (~ p1[y]) & p2[y] end\0a\0a\09\09--x=2\0a\0a\09\09s, p, p1, p2 = st[2], permuted[2], permuted[3], permuted[4]\0a\0a\09\09for y = 1,5 do s[y] = p[y] ~ (~ p1[y]) & p2[y] end\0a\0a\09\09--x=3\0a\0a\09\09s, p, p1, p2 = st[3], permuted[3], permuted[4], permuted[5]\0a\0a\09\09for y = 1,5 do s[y] = p[y] ~ (~ p1[y]) & p2[y] end\0a\0a\09\09--x=4\0a\0a\09\09s, p, p1, p2 = st[4], permuted[4], permuted[5], permuted[1]\0a\0a\09\09for y = 1,5 do s[y] = p[y] ~ (~ p1[y]) & p2[y] end\0a\0a\09\09--x=5\0a\0a\09\09s, p, p1, p2 = st[5], permuted[5], permuted[1], permuted[2]\0a\0a\09\09for y = 1,5 do s[y] = p[y] ~ (~ p1[y]) & p2[y] end\0a\0a\0a\0a\09\09-- iota()\0a\0a\09\09st[1][1] = st[1][1] ~ roundConstants[round]\0a\0a\09end\0a\0aend\0a\0a\0a\0a\0a\0alocal function absorb(st, buffer, algorithm)\0a\0a\0a\0a\09local blockBytes = st.rate / 8\0a\0a\09local blockWords = blockBytes / 8\0a\0a\0a\0a\09-- append 0x01 byte and pad with zeros to block size (rate/8 bytes)\0a\0a\09local totalBytes = #buffer + 1\0a\0a\09-- for keccak (2012 submission), the padding is byte 0x01 followed by zeros\0a\0a\09-- for SHA3 (NIST, 2015), the padding is byte 0x06 followed by zeros\0a\0a\0a\0a\09if algorithm == \22keccak\22 then\0a\0a\09\09buffer = buffer .. ( '\5cx01' .. string.char(0):rep(blockBytes - (totalBytes % blockBytes)))\0a\0a\09end\0a\0a\09\0a\0a\09if algorithm == \22sha3\22 then\0a\0a\09\09buffer = buffer .. ( '\5cx06' .. string.char(0):rep(blockBytes - (totalBytes % blockBytes)))\0a\0a\09end\0a\0a\0a\0a\09totalBytes = #buffer\0a\0a\0a\0a\09--convert data to an array of u64\0a\0a\09local words = {}\0a\0a\09for i = 1, totalBytes - (totalBytes % 8), 8 do\0a\0a\09\09words[#words + 1] = string.unpack('<I8', buffer, i)\0a\0a\09end\0a\0a\0a\0a\09local totalWords = #words\0a\0a\09-- OR final word with 0x80000000 to set last bit of state to 1\0a\0a\09words[totalWords] = words[totalWords] | 0x8000000000000000\0a\0a\0a\0a\09-- XOR blocks into state\0a\0a\09for startBlock = 1, totalWords, blockWords do\0a\0a\09\09local offset = 0\0a\0a\09\09for y = 1, 5 do\0a\0a\09\09\09for x = 1, 5 do\0a\0a\09\09\09\09if offset < blockWords then\0a\0a\09\09\09\09\09local index = startBlock+offset\0a\0a\09\09\09\09\09st[x][y] = st[x][y] ~ words[index]\0a\0a\09\09\09\09\09offset = offset + 1\0a\0a\09\09\09\09end\0a\0a\09\09\09end\0a\0a\09\09end\0a\0a\09\09keccakF(st)\0a\0a\09end\0a\0aend\0a\0a\0a\0a\0a\0a-- returns [rate] bits from the state, without permuting afterward.\0a\0a-- Only for use when the state will immediately be thrown away,\0a\0a-- and not used for more output later\0a\0alocal function squeeze(st)\0a\0a\09local blockBytes = st.rate / 8\0a\0a\09local blockWords = blockBytes / 4\0a\0a\09-- fetch blocks out of state\0a\0a\09local hasht = {}\0a\0a\09local offset = 1\0a\0a\09for y = 1, 5 do\0a\0a\09\09for x = 1, 5 do\0a\0a\09\09\09if offset < blockWords then\0a\0a\09\09\09\09hasht[offset] = string.pack(\22<I8\22, st[x][y])\0a\0a\09\09\09\09offset = offset + 1\0a\0a\09\09\09end\0a\0a\09\09end\0a\0a\09end\0a\0a\09return table.concat(hasht)\0a\0aend\0a\0a\0a\0a-- primitive functions (assume rate is a whole multiple of 64 and length is a whole multiple of 8)\0a\0alocal function keccakHash(rate, length, data, algorithm)\0a\0a\09local state = {\09{0,0,0,0,0},\0a\0a\09\09\09\09\09{0,0,0,0,0},\0a\0a\09\09\09\09\09{0,0,0,0,0},\0a\0a\09\09\09\09\09{0,0,0,0,0},\0a\0a\09\09\09\09\09{0,0,0,0,0},\0a\0a\09}\0a\0a\09state.rate = rate\0a\0a\09-- these are allocated once, and reused\0a\0a\09state.permuted = { {}, {}, {}, {}, {}, }\0a\0a\09state.parities = {0,0,0,0,0}\0a\0a\09absorb(state, data, algorithm)\0a\0a\09local encoded = squeeze(state):sub(1,length/8);\0a\0a\0a\0a\09local public = {}\0a\0a\0a\0a\09public.asString = function()\0a\0a\09\09return encoded\0a\0a\09end\0a\0a\0a\0a\09public.asHex = function()\0a\0a\09\09return Hex.stringToHex(encoded)\0a\0a\09end\0a\0a\0a\0a\09return public\0a\0aend\0a\0a\0a\0a-- output tables for getting the hash as bytes, string, or hex\0a\0alocal function sha3_256(data) return keccakHash(1088, 256, data, 'sha3') end\0a\0alocal function sha3_512(data) return keccakHash(576, 512, data, 'sha3') end\0a\0alocal function keccak256(data) return keccakHash(1088, 256, data, 'keccak') end\0a\0alocal function keccak512(data) return keccakHash(576, 512, data, 'keccak') end\0a\0a\0a\0areturn {\0a\0a\09sha3_256 = sha3_256,\0a\0a\09sha3_512 = sha3_512,\0a\0a\09keccak256 = keccak256,\0a\0a\09keccak512 = keccak512\0a\0a}\00\00\00\00\00local PBKDF2 = require(\22.crypto.kdf.pbkdf2\22)\0a\0a\0a\0alocal kdf = {\0a\0a _version = \220.0.1\22,\0a\0a pbkdf2 = PBKDF2.pbkdf2,\0a\0a};\0a\0a\0a\0areturn kdf")
(data $.rodata.12 (;12;) (i64.const 262256) "local Bit = require(\22.crypto.util.bit\22);\0a\0alocal Array = require(\22.crypto.util.array\22);\0a\0alocal Stream = require(\22.crypto.util.stream\22);\0a\0alocal HMAC = require(\22.crypto.mac.hmac\22)\0a\0a\0a\0alocal SHA1 = require(\22.crypto.digest.sha1\22);\0a\0alocal SHA2_256 = require(\22.crypto.digest.sha2_256\22);\0a\0a\0a\0alocal AND = Bit.band;\0a\0alocal RSHIFT = Bit.rshift;\0a\0a\0a\0alocal word2bytes = function(word)\0a\0a local b0, b1, b2, b3;\0a\0a b3 = AND(word, 0xFF); word = RSHIFT(word, 8);\0a\0a b2 = AND(word, 0xFF); word = RSHIFT(word, 8);\0a\0a b1 = AND(word, 0xFF); word = RSHIFT(word, 8);\0a\0a b0 = AND(word, 0xFF);\0a\0a return b0, b1, b2, b3;\0a\0aend\0a\0a\0a\0alocal PBKDF2 = function()\0a\0a\0a\0a local public = {};\0a\0a\0a\0a local blockLen = 16;\0a\0a local dKeyLen = 256;\0a\0a local iterations = 4096;\0a\0a\0a\0a local salt;\0a\0a local password;\0a\0a\0a\0a\0a\0a local PRF;\0a\0a\0a\0a local dKey;\0a\0a\0a\0a\0a\0a public.setBlockLen = function(len)\0a\0a blockLen = len;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.setDKeyLen = function(len)\0a\0a dKeyLen = len\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.setIterations = function(iter)\0a\0a iterations = iter;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.setSalt = function(saltBytes)\0a\0a salt = saltBytes;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.setPassword = function(passwordBytes)\0a\0a password = passwordBytes;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.setPRF = function(prf)\0a\0a PRF = prf;\0a\0a return public;\0a\0a end\0a\0a\0a\0a local buildBlock = function(i)\0a\0a local b0, b1, b2, b3 = word2bytes(i);\0a\0a local ii = {b0, b1, b2, b3};\0a\0a local s = Array.concat(salt, ii);\0a\0a\0a\0a local out = {};\0a\0a\0a\0a PRF.setKey(password);\0a\0a for c = 1, iterations do\0a\0a PRF.init()\0a\0a .update(Stream.fromArray(s));\0a\0a\0a\0a s = PRF.finish().asBytes();\0a\0a if(c > 1) then\0a\0a out = Array.XOR(out, s);\0a\0a else\0a\0a out = s;\0a\0a end\0a\0a end\0a\0a\0a\0a return out;\0a\0a end\0a\0a\0a\0a public.finish = function()\0a\0a local blocks = math.ceil(dKeyLen / blockLen);\0a\0a\0a\0a dKey = {};\0a\0a\0a\0a for b = 1, blocks do\0a\0a local block = buildBlock(b);\0a\0a dKey = Array.concat(dKey, block);\0a\0a end\0a\0a\0a\0a if(Array.size(dKey) > dKeyLen) then dKey = Array.truncate(dKey, dKeyLen); end\0a\0a\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.asBytes = function()\0a\0a return dKey;\0a\0a end\0a\0a\0a\0a public.asHex = function()\0a\0a return Array.toHex(dKey);\0a\0a end\0a\0a\0a\0a public.asString = function()\0a\0a return Array.toString(dKey);\0a\0a end\0a\0a\0a\0a return public;\0a\0aend\0a\0a\0a\0a--- @class Array : table\0a\0a\0a\0a--- PBKDF2 key derivation function\0a\0a--- @param password (Array) - The password to derive the key from\0a\0a--- @param salt (Array) - The salt to use\0a\0a--- @param iterations number - The number of iterations to perform\0a\0a--- @param keyLen number - The length of the key to derive\0a\0a--- @param digest? string - The digest algorithm to use (sha1, sha256). Defaults to sha1.\0a\0a--- @returns string - The derived key\0a\0alocal pbkdf2 = function(password, salt, iterations, keyLen, digest)\0a\0a local Digest = nil\0a\0a if digest == \22sha1\22 then\0a\0a Digest = SHA1.SHA1\0a\0a elseif digest == \22sha256\22 then\0a\0a Digest = SHA2_256.SHA2_256\0a\0a elseif digest == nil then\0a\0a Digest = SHA1.SHA1\0a\0a else\0a\0a error(\22Unsupported algorithm: \22 .. digest)\0a\0a end\0a\0a\0a\0a local prf = HMAC.HMAC().setBlockSize(64).setDigest(Digest);\0a\0a\0a\0a local res = PBKDF2()\0a\0a .setPRF(prf)\0a\0a .setBlockLen(16)\0a\0a .setDKeyLen(keyLen)\0a\0a .setIterations(iterations)\0a\0a .setSalt(salt)\0a\0a .setPassword(password)\0a\0a .finish()\0a\0a\0a\0a return res\0a\0aend\0a\0a\0a\0areturn {\0a\0a PBKDF2 = PBKDF2,\0a\0a pbkdf2 = pbkdf2\0a\0a};")
(data $.rodata.13 (;13;) (i64.const 266064) "local Bit = require(\22.crypto.util.bit\22);\0a\0alocal Stream = require(\22.crypto.util.stream\22);\0a\0alocal Array = require(\22.crypto.util.array\22);\0a\0a\0a\0alocal SHA1 = require(\22.crypto.digest.sha1\22);\0a\0alocal SHA2_256 = require(\22.crypto.digest.sha2_256\22);\0a\0a\0a\0alocal XOR = Bit.bxor;\0a\0a\0a\0alocal HMAC = function()\0a\0a local public = {};\0a\0a local blockSize = 64;\0a\0a local Digest = nil;\0a\0a local outerPadding = {};\0a\0a local innerPadding = {}\0a\0a local digest;\0a\0a\0a\0a public.setBlockSize = function(bytes)\0a\0a blockSize = bytes;\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.setDigest = function(digestModule)\0a\0a Digest = digestModule;\0a\0a digest = Digest();\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.setKey = function(key)\0a\0a local keyStream;\0a\0a if Digest == nil then\0a\0a error(\22Digest not set\22);\0a\0a end\0a\0a if (Array.size(key) > blockSize) then\0a\0a keyStream = Stream.fromArray(Digest()\0a\0a .update(Stream.fromArray(key))\0a\0a .finish()\0a\0a .asBytes());\0a\0a else\0a\0a keyStream = Stream.fromArray(key);\0a\0a end\0a\0a\0a\0a outerPadding = {};\0a\0a innerPadding = {};\0a\0a\0a\0a for i = 1, blockSize do\0a\0a local byte = keyStream();\0a\0a if byte == nil then byte = 0x00; end\0a\0a outerPadding[i] = XOR(0x5C, byte);\0a\0a innerPadding[i] = XOR(0x36, byte);\0a\0a end\0a\0a\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.init = function()\0a\0a digest.init()\0a\0a .update(Stream.fromArray(innerPadding));\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.update = function(messageStream)\0a\0a digest.update(messageStream);\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.finish = function()\0a\0a local inner = digest.finish().asBytes();\0a\0a digest.init()\0a\0a .update(Stream.fromArray(outerPadding))\0a\0a .update(Stream.fromArray(inner))\0a\0a .finish();\0a\0a\0a\0a return public;\0a\0a end\0a\0a\0a\0a public.asBytes = function()\0a\0a return digest.asBytes();\0a\0a end\0a\0a\0a\0a public.asHex = function()\0a\0a return digest.asHex();\0a\0a end\0a\0a\0a\0a public.asString = function()\0a\0a return digest.asString();\0a\0a end\0a\0a\0a\0a return public;\0a\0aend\0a\0a\0a\0a--- @class Array : table\0a\0a--- @class Stream : table\0a\0a\0a\0a--- HMAC function for generating a hash-based message authentication code\0a\0a--- @param data (Stream) - The data to hash and authenticate\0a\0a--- @param key (Array) - The key to use for the HMAC\0a\0a--- @param algorithm? (string) - The algorithm to use for the HMAC (sha1, sha256). Defaults to \22sha1\22\0a\0a--- @returns table - A table containing the HMAC in bytes, string, and hex formats.\0a\0alocal hmac = function(data, key, algorithm)\0a\0a local digest = nil\0a\0a if algorithm == \22sha1\22 then\0a\0a digest = SHA1.SHA1\0a\0a elseif algorithm == \22sha256\22 then\0a\0a digest = SHA2_256.SHA2_256\0a\0a elseif algorithm == nil then\0a\0a digest = SHA1.SHA1\0a\0a else\0a\0a error(\22Unsupported algorithm: \22 .. algorithm)\0a\0a end\0a\0a\0a\0a local res = HMAC()\0a\0a .setBlockSize(32)\0a\0a .setDigest(digest)\0a\0a .setKey(key)\0a\0a .init()\0a\0a .update(data)\0a\0a .finish()\0a\0a\0a\0a\09return res\0a\0aend\0a\0a\0a\0areturn {\0a\0a hmac = hmac,\0a\0a HMAC = HMAC\0a\0a};")
(data $.rodata.14 (;14;) (i64.const 269360) "local Hmac = require(\22.crypto.mac.hmac\22)\0a\0a\0a\0alocal mac = {\0a\0a _version = \220.0.1\22,\0a\0a createHmac = Hmac.hmac,\0a\0a};\0a\0a\0a\0areturn mac")
(data $.rodata.15 (;15;) (i64.const 269504) "local ZeroPadding = function(blockSize, byteCount)\0a\0a\0a\0a local paddingCount = blockSize - ((byteCount -1) % blockSize) + 1;\0a\0a local bytesLeft = paddingCount;\0a\0a\0a\0a local stream = function()\0a\0a if bytesLeft > 0 then\0a\0a bytesLeft = bytesLeft - 1;\0a\0a return 0x00;\0a\0a else\0a\0a return nil;\0a\0a end\0a\0a end\0a\0a return stream;\0a\0aend\0a\0a\0a\0areturn ZeroPadding;\0a\0alocal Bit = require(\22.crypto.util.bit\22);\0a\0alocal Queue = require(\22.crypto.util.queue\22);\0a\0a\0a\0alocal XOR = Bit.bxor;\0a\0a\0a\0alocal Array = {};\0a\0a\0a\0aArray.size = function(array)\0a\0a return #array;\0a\0aend\0a\0a\0a\0aArray.fromString = function(string)\0a\0a local bytes = {};\0a\0a\0a\0a local i = 1;\0a\0a local byte = string.byte(string, i);\0a\0a while byte ~= nil do\0a\0a bytes[i] = byte;\0a\0a i = i + 1;\0a\0a byte = string.byte(string, i);\0a\0a end\0a\0a\0a\0a return bytes;\0a\0a\0a\0aend\0a\0a\0a\0aArray.toString = function(bytes)\0a\0a local chars = {};\0a\0a local i = 1;\0a\0a\0a\0a local byte = bytes[i];\0a\0a while byte ~= nil do\0a\0a chars[i] = string.char(byte);\0a\0a i = i + 1;\0a\0a byte = bytes[i];\0a\0a end\0a\0a\0a\0a return table.concat(chars, \22\22);\0a\0aend\0a\0a\0a\0aArray.fromStream = function(stream)\0a\0a local array = {};\0a\0a local i = 1;\0a\0a\0a\0a local byte = stream();\0a\0a while byte ~= nil do\0a\0a array[i] = byte;\0a\0a i = i + 1;\0a\0a byte = stream();\0a\0a end\0a\0a\0a\0a return array;\0a\0aend\0a\0a\0a\0aArray.readFromQueue = function(queue, size)\0a\0a local array = {};\0a\0a\0a\0a for i = 1, size do\0a\0a array[i] = queue.pop();\0a\0a end\0a\0a\0a\0a return array;\0a\0aend\0a\0a\0a\0aArray.writeToQueue = function(queue, array)\0a\0a local size = Array.size(array);\0a\0a\0a\0a for i = 1, size do\0a\0a queue.push(array[i]);\0a\0a end\0a\0aend\0a\0a\0a\0aArray.toStream = function(array)\0a\0a local queue = Queue();\0a\0a local i = 1;\0a\0a\0a\0a local byte = array[i];\0a\0a while byte ~= nil do\0a\0a queue.push(byte);\0a\0a i = i + 1;\0a\0a byte = array[i];\0a\0a end\0a\0a\0a\0a return queue.pop;\0a\0aend\0a\0a\0a\0a\0a\0alocal fromHexTable = {};\0a\0afor i = 0, 255 do\0a\0a fromHexTable[string.format(\22%02X\22, i)] = i;\0a\0a fromHexTable[string.format(\22%02x\22, i)] = i;\0a\0aend\0a\0a\0a\0aArray.fromHex = function(hex)\0a\0a local array = {};\0a\0a\0a\0a for i = 1, string.len(hex) / 2 do\0a\0a local h = string.sub(hex, i * 2 - 1, i * 2);\0a\0a array[i] = fromHexTable[h];\0a\0a end\0a\0a\0a\0a return array;\0a\0aend\0a\0a\0a\0a\0a\0alocal toHexTable = {};\0a\0afor i = 0, 255 do\0a\0a toHexTable[i] = string.format(\22%02X\22, i);\0a\0aend\0a\0a\0a\0aArray.toHex = function(array)\0a\0a local hex = {};\0a\0a local i = 1;\0a\0a\0a\0a local byte = array[i];\0a\0a while byte ~= nil do\0a\0a hex[i] = toHexTable[byte];\0a\0a i = i + 1;\0a\0a byte = array[i];\0a\0a end\0a\0a\0a\0a return table.concat(hex, \22\22);\0a\0a\0a\0aend\0a\0a\0a\0aArray.concat = function(a, b)\0a\0a local concat = {};\0a\0a local out = 1;\0a\0a\0a\0a local i = 1;\0a\0a local byte = a[i];\0a\0a while byte ~= nil do\0a\0a concat[out] = byte;\0a\0a i = i + 1;\0a\0a out = out + 1;\0a\0a byte = a[i];\0a\0a end\0a\0a\0a\0a i = 1;\0a\0a byte = b[i];\0a\0a while byte ~= nil do\0a\0a concat[out] = byte;\0a\0a i = i + 1;\0a\0a out = out + 1;\0a\0a byte = b[i];\0a\0a end\0a\0a\0a\0a return concat;\0a\0aend\0a\0a\0a\0aArray.truncate = function(a, newSize)\0a\0a local x = {};\0a\0a\0a\0a for i = 1, newSize do\0a\0a x[i] = a[i];\0a\0a end\0a\0a\0a\0a return x;\0a\0aend\0a\0a\0a\0aArray.XOR = function(a, b)\0a\0a local x = {};\0a\0a\0a\0a for k, v in pairs(a) do\0a\0a x[k] = XOR(v, b[k]);\0a\0a end\0a\0a\0a\0a return x;\0a\0aend\0a\0a\0a\0aArray.substitute = function(input, sbox)\0a\0a local out = {};\0a\0a\0a\0a for k, v in pairs(input) do\0a\0a out[k] = sbox[v];\0a\0a end\0a\0a\0a\0a return out;\0a\0aend\0a\0a\0a\0aArray.permute = function(input, pbox)\0a\0a local out = {};\0a\0a\0a\0a for k, v in pairs(pbox) do\0a\0a out[k] = input[v];\0a\0a end\0a\0a\0a\0a return out;\0a\0aend\0a\0a\0a\0aArray.copy = function(input)\0a\0a local out = {};\0a\0a\0a\0a for k, v in pairs(input) do\0a\0a out[k] = v;\0a\0a end\0a\0a return out;\0a\0aend\0a\0a\0a\0aArray.slice = function(input, start, stop)\0a\0a local out = {};\0a\0a\0a\0a if start == nil then\0a\0a start = 1\0a\0a elseif start < 0 then\0a\0a start = #input + start + 1\0a\0a end\0a\0a if stop == nil then\0a\0a stop = #input\0a\0a elseif stop < 0 then\0a\0a stop = #input + stop + 1\0a\0a end\0a\0a\0a\0a for i = start, stop do\0a\0a table.insert(out, input[i])\0a\0a end\0a\0a\0a\0a return out;\0a\0aend\0a\0a\0a\0areturn Array;\00\00\00\00local ok, e\0a\0aok = nil\0a\0aif not ok then\0a\0a ok, e = pcall(require, \22bit\22) -- the LuaJIT one ?\0a\0aend\0a\0aif not ok then\0a\0a ok, e = pcall(require, \22bit32\22) -- Lua 5.2\0a\0aend\0a\0aif not ok then\0a\0a ok, e = pcall(require, \22bit.numberlua\22) -- for Lua 5.1, https://github.com/tst2005/lua-bit-numberlua/\0a\0aend\0a\0aif not ok then\0a\0a error(\22no bitwise support found\22, 2)\0a\0aend\0a\0aassert(type(e) == \22table\22, \22invalid bit module\22)\0a\0a\0a\0a-- Workaround to support Lua 5.2 bit32 API with the LuaJIT bit one\0a\0aif e.rol and not e.lrotate then\0a\0a e.lrotate = e.rol\0a\0aend\0a\0aif e.ror and not e.rrotate then\0a\0a e.rrotate = e.ror\0a\0aend\0a\0a\0a\0a-- Workaround to support incomplete bit operations set\0a\0aif not e.ror and not e.rrotate then\0a\0a local ror = function(b, n)\0a\0a return e.bor(e.rshift(b, n), e.lshift(b, 32 - n))\0a\0a end\0a\0a\0a\0a e.ror = ror\0a\0a e.rrotate = ror\0a\0aend\0a\0a\0a\0aif not e.rol and not e.lrotate then\0a\0a local rol = function(b, n)\0a\0a return e.bor(e.lshift(b, n), e.rshift(b, 32 - n))\0a\0a end\0a\0a\0a\0a e.rol = rol\0a\0a e.lrotate = rol\0a\0aend\0a\0a\0a\0areturn e\00\00\00\00\00\0a\0a--- Converts a string to its hexadecimal representation.\0a\0a--- @param s string The input string.\0a\0a--- @param ln? number - The number of characters per line. If not provided, the output will be a single line.\0a\0a--- @param sep? string - The separator between each pair of hexadecimal characters. Defaults to an empty string.\0a\0a--- @return string The - hexadecimal representation of the input string.\0a\0alocal function stringToHex(s, ln, sep)\0a\0a\09if #s == 0 then return \22\22 end\0a\0a\09if not ln then\0a\0a\09\09return (s:gsub('.',\0a\0a\09\09\09function(c) return string.format('%02x', string.byte(c)) end\0a\0a\09\09))\0a\0a\09end\0a\0a\09sep = sep or \22\22\0a\0a\09local t = {}\0a\0a\09for i = 1, #s - 1 do\0a\0a\09\09t[#t + 1] = string.format(\22%02x%s\22, s:byte(i),\0a\0a\09\09\09(i % ln == 0) and '\5cn' or sep)\0a\0a\09end\0a\0a\09t[#t + 1] = string.format(\22%02x\22, s:byte(#s))\0a\0a\09return table.concat(t)\0a\0aend\0a\0a\0a\0a--- Converts a hex encoded string to its corresponding decoded string.\0a\0a--- If the optional parameter `unsafe` is defined, it assumes that the hex string is well-formed\0a\0a--- (no checks, no whitespace removal). By default, it removes whitespace (including newlines)\0a\0a--- and checks that the hex string is well-formed.\0a\0a--- @param hs (string) The hex encoded string to be decoded.\0a\0a--- @param unsafe (boolean) [optional] If true, assumes the hex string is well-formed.\0a\0a--- @return (string) The decoded string.\0a\0alocal function hexToString(hs, unsafe)\0a\0a\09local tonumber = tonumber\0a\0a\09if not unsafe then\0a\0a\09\09hs = string.gsub(hs, \22%s+\22, \22\22) -- remove whitespaces\0a\0a\09\09if string.find(hs, '[^0-9A-Za-z]') or #hs % 2 ~= 0 then\0a\0a\09\09\09error(\22invalid hex string\22)\0a\0a\09\09end\0a\0a\09end\0a\0a\09local count = string.gsub(hs, '(%x%x)',function(c) return string.char(tonumber(c, 16)) end)\0a\0a\09return count\0a\0aend\0a\0a\0a\0areturn {\0a\0a\09stringToHex = stringToHex,\0a\0a\09hexToString = hexToString,\0a\0a}local Bit = require(\22.crypto.util.bit\22)\0a\0alocal Queue = require(\22.crypto.util.queue\22)\0a\0alocal Stream = require(\22.crypto.util.stream\22)\0a\0alocal Hex = require(\22.crypto.util.hex\22)\0a\0alocal Array = require(\22.crypto.util.array\22)\0a\0a\0a\0alocal util = {\0a\0a _version = \220.0.1\22,\0a\0a bit = Bit,\0a\0a queue = Queue,\0a\0a stream = Stream,\0a\0a hex = Hex,\0a\0a array = Array,\0a\0a}\0a\0a\0a\0areturn util\0a")
(data $.rodata.16 (;16;) (i64.const 276976) "local Queue = function()\0a\0a local queue = {};\0a\0a local tail = 0;\0a\0a local head = 0;\0a\0a\0a\0a local public = {};\0a\0a\0a\0a public.push = function(obj)\0a\0a queue[head] = obj;\0a\0a head = head + 1;\0a\0a return;\0a\0a end\0a\0a\0a\0a public.pop = function()\0a\0a if tail < head\0a\0a then\0a\0a local obj = queue[tail];\0a\0a queue[tail] = nil;\0a\0a tail = tail + 1;\0a\0a return obj;\0a\0a else\0a\0a return nil;\0a\0a end\0a\0a end\0a\0a\0a\0a public.size = function()\0a\0a return head - tail;\0a\0a end\0a\0a\0a\0a public.getHead = function()\0a\0a return head;\0a\0a end\0a\0a\0a\0a public.getTail = function()\0a\0a return tail;\0a\0a end\0a\0a\0a\0a public.reset = function()\0a\0a queue = {};\0a\0a head = 0;\0a\0a tail = 0;\0a\0a end\0a\0a\0a\0a return public;\0a\0aend\0a\0a\0a\0areturn Queue;local Queue = require(\22.crypto.util.queue\22);\0a\0a\0a\0alocal Stream = {};\0a\0a\0a\0a\0a\0aStream.fromString = function(string)\0a\0a local i = 0;\0a\0a return function()\0a\0a i = i + 1;\0a\0a return string.byte(string, i);\0a\0a end\0a\0aend\0a\0a\0a\0a\0a\0aStream.toString = function(stream)\0a\0a local array = {};\0a\0a local i = 1;\0a\0a\0a\0a local byte = stream();\0a\0a while byte ~= nil do\0a\0a array[i] = string.char(byte);\0a\0a i = i + 1;\0a\0a byte = stream();\0a\0a end\0a\0a\0a\0a return table.concat(array);\0a\0aend\0a\0a\0a\0a\0a\0aStream.fromArray = function(array)\0a\0a local queue = Queue();\0a\0a local i = 1;\0a\0a\0a\0a local byte = array[i];\0a\0a while byte ~= nil do\0a\0a queue.push(byte);\0a\0a i = i + 1;\0a\0a byte = array[i];\0a\0a end\0a\0a\0a\0a return queue.pop;\0a\0aend\0a\0a\0a\0a\0a\0aStream.toArray = function(stream)\0a\0a local array = {};\0a\0a local i = 1;\0a\0a\0a\0a local byte = stream();\0a\0a while byte ~= nil do\0a\0a array[i] = byte;\0a\0a i = i + 1;\0a\0a byte = stream();\0a\0a end\0a\0a\0a\0a return array;\0a\0aend\0a\0a\0a\0a\0a\0alocal fromHexTable = {};\0a\0afor i = 0, 255 do\0a\0a fromHexTable[string.format(\22%02X\22, i)] = i;\0a\0a fromHexTable[string.format(\22%02x\22, i)] = i;\0a\0aend\0a\0a\0a\0aStream.fromHex = function(hex)\0a\0a local queue = Queue();\0a\0a\0a\0a for i = 1, string.len(hex) / 2 do\0a\0a local h = string.sub(hex, i * 2 - 1, i * 2);\0a\0a queue.push(fromHexTable[h]);\0a\0a end\0a\0a\0a\0a return queue.pop;\0a\0aend\0a\0a\0a\0a\0a\0a\0a\0alocal toHexTable = {};\0a\0afor i = 0, 255 do\0a\0a toHexTable[i] = string.format(\22%02X\22, i);\0a\0aend\0a\0a\0a\0aStream.toHex = function(stream)\0a\0a local hex = {};\0a\0a local i = 1;\0a\0a\0a\0a local byte = stream();\0a\0a while byte ~= nil do\0a\0a hex[i] = toHexTable[byte];\0a\0a i = i + 1;\0a\0a byte = stream();\0a\0a end\0a\0a\0a\0a return table.concat(hex);\0a\0aend\0a\0a\0a\0areturn Stream;\00\00\00\00\00local ao = {\0a\0a _version = \220.0.4\22,\0a\0a id = \22\22,\0a\0a _module = \22\22,\0a\0a authorities = {},\0a\0a _ref = 0,\0a\0a outbox = {Output = {}, Messages = {}, Spawns = {}, Assignments = {}}\0a\0a}\0a\0a\0a\0alocal function _includes(list)\0a\0a return function(key)\0a\0a local exists = false\0a\0a for _, listKey in ipairs(list) do\0a\0a if key == listKey then\0a\0a exists = true\0a\0a break\0a\0a end\0a\0a end\0a\0a if not exists then return false end\0a\0a return true\0a\0a end\0a\0aend\0a\0a\0a\0alocal function isArray(table)\0a\0a if type(table) == \22table\22 then\0a\0a local maxIndex = 0\0a\0a for k, v in pairs(table) do\0a\0a if type(k) ~= \22number\22 or k < 1 or math.floor(k) ~= k then\0a\0a return false -- If there's a non-integer key, it's not an array\0a\0a end\0a\0a maxIndex = math.max(maxIndex, k)\0a\0a end\0a\0a -- If the highest numeric index is equal to the number of elements, it's an array\0a\0a return maxIndex == #table\0a\0a end\0a\0a return false\0a\0aend\0a\0a\0a\0alocal function padZero32(num) return string.format(\22%032d\22, num) end\0a\0a\0a\0afunction ao.normalize(msg)\0a\0a for _, o in ipairs(msg.Tags) do\0a\0a if not _includes({\0a\0a 'Data-Protocol', 'Variant', 'From-Process', 'From-Module', 'Type',\0a\0a 'Ref_', 'From', 'Owner', 'Anchor', 'Target', 'Data', 'Tags'\0a\0a })(o.name) then msg[o.name] = o.value end\0a\0a end\0a\0a return msg\0a\0aend\0a\0a\0a\0afunction ao.init(env)\0a\0a if ao.id == \22\22 then ao.id = env.Process.Id end\0a\0a\0a\0a if ao._module == \22\22 then\0a\0a for _, o in ipairs(env.Process.Tags) do\0a\0a if o.name == \22Module\22 then ao._module = o.value end\0a\0a end\0a\0a end\0a\0a\0a\0a if #ao.authorities < 1 then\0a\0a for _, o in ipairs(env.Process.Tags) do\0a\0a if o.name == \22Authority\22 then\0a\0a table.insert(ao.authorities, o.value)\0a\0a end\0a\0a end\0a\0a end\0a\0a\0a\0a ao.outbox = {Output = {}, Messages = {}, Spawns = {}, Assignments = {}}\0a\0a ao.env = env\0a\0a\0a\0aend\0a\0a\0a\0afunction ao.log(txt)\0a\0a if type(ao.outbox.Output) == 'string' then\0a\0a ao.outbox.Output = {ao.outbox.Output}\0a\0a end\0a\0a table.insert(ao.outbox.Output, txt)\0a\0aend\0a\0a\0a\0a-- clears outbox\0a\0afunction ao.clearOutbox() ao.outbox = {Output = {}, Messages = {}, Spawns = {}, Assignments = {}} end\0a\0a\0a\0afunction ao.send(msg)\0a\0a assert(type(msg) == 'table', 'msg should be a table')\0a\0a ao._ref = ao._ref + 1\0a\0a\0a\0a local message = {\0a\0a Target = msg.Target,\0a\0a Data = msg.Data,\0a\0a Anchor = padZero32(ao._ref),\0a\0a Tags = {\0a\0a {name = \22Data-Protocol\22, value = \22ao\22},\0a\0a {name = \22Variant\22, value = \22ao.TN.1\22},\0a\0a {name = \22Type\22, value = \22Message\22},\0a\0a {name = \22From-Process\22, value = ao.id},\0a\0a {name = \22From-Module\22, value = ao._module},\0a\0a {name = \22Ref_\22, value = tostring(ao._ref)}\0a\0a }\0a\0a }\0a\0a\0a\0a -- if custom tags in root move them to tags\0a\0a for k, v in pairs(msg) do\0a\0a if not _includes({\22Target\22, \22Data\22, \22Anchor\22, \22Tags\22, \22From\22})(k) then\0a\0a table.insert(message.Tags, {name = k, value = v})\0a\0a end\0a\0a end\0a\0a\0a\0a if msg.Tags then\0a\0a if isArray(msg.Tags) then\0a\0a for _, o in ipairs(msg.Tags) do\0a\0a table.insert(message.Tags, o)\0a\0a end\0a\0a else\0a\0a for k, v in pairs(msg.Tags) do\0a\0a table.insert(message.Tags, {name = k, value = v})\0a\0a end\0a\0a end\0a\0a end\0a\0a\0a\0a -- add message to outbox\0a\0a table.insert(ao.outbox.Messages, message)\0a\0a\0a\0a return message\0a\0aend\0a\0a\0a\0afunction ao.spawn(module, msg)\0a\0a assert(type(module) == \22string\22, \22module source id is required!\22)\0a\0a assert(type(msg) == 'table', 'msg should be a table')\0a\0a -- inc spawn reference\0a\0a ao._ref = ao._ref + 1\0a\0a\0a\0a local spawn = {\0a\0a Data = msg.Data or \22NODATA\22,\0a\0a Anchor = padZero32(ao._ref),\0a\0a Tags = {\0a\0a {name = \22Data-Protocol\22, value = \22ao\22},\0a\0a {name = \22Variant\22, value = \22ao.TN.1\22},\0a\0a {name = \22Type\22, value = \22Process\22},\0a\0a {name = \22From-Process\22, value = ao.id},\0a\0a {name = \22From-Module\22, value = ao._module},\0a\0a {name = \22Module\22, value = module},\0a\0a {name = \22Ref_\22, value = tostring(ao._ref)}\0a\0a }\0a\0a }\0a\0a\0a\0a -- if custom tags in root move them to tags\0a\0a for k, v in pairs(msg) do\0a\0a if not _includes({\22Target\22, \22Data\22, \22Anchor\22, \22Tags\22, \22From\22})(k) then\0a\0a table.insert(spawn.Tags, {name = k, value = v})\0a\0a end\0a\0a end\0a\0a\0a\0a if msg.Tags then\0a\0a if isArray(msg.Tags) then\0a\0a for _, o in ipairs(msg.Tags) do\0a\0a table.insert(spawn.Tags, o)\0a\0a end\0a\0a else\0a\0a for k, v in pairs(msg.Tags) do\0a\0a table.insert(spawn.Tags, {name = k, value = v})\0a\0a end\0a\0a end\0a\0a end\0a\0a\0a\0a -- add spawn to outbox\0a\0a table.insert(ao.outbox.Spawns, spawn)\0a\0a\0a\0a return spawn\0a\0aend\0a\0a\0a\0afunction ao.assign(assignment)\0a\0a assert(type(assignment) == 'table', 'assignment should be a table')\0a\0a assert(type(assignment.Processes) == 'table', 'Processes should be a table')\0a\0a assert(type(assignment.Message) == \22string\22, \22Message should be a string\22)\0a\0a table.insert(ao.outbox.Assignments, assignment)\0a\0aend\0a\0a\0a\0afunction ao.isTrusted(msg)\0a\0a if #ao.authorities == 0 then return true end\0a\0a\0a\0a for _, authority in ipairs(ao.authorities) do\0a\0a if msg.From == authority then return true end\0a\0a if msg.Owner == authority then return true end\0a\0a end\0a\0a return false\0a\0aend\0a\0a\0a\0afunction ao.result(result)\0a\0a -- if error then only send the Error to CU\0a\0a if ao.outbox.Error or result.Error then\0a\0a return {Error = result.Error or ao.outbox.Error}\0a\0a end\0a\0a return {\0a\0a Output = result.Output or ao.outbox.Output,\0a\0a Messages = ao.outbox.Messages,\0a\0a Spawns = ao.outbox.Spawns,\0a\0a Assignments = ao.outbox.Assignments\0a\0a }\0a\0aend\0a\0a\0a\0areturn ao\0a\00\00\00\00\00\00--\0a\0a-- json.lua\0a\0a--\0a\0a-- Copyright (c) 2020 rxi\0a\0a--\0a\0a-- Permission is hereby granted, free of charge, to any person obtaining a copy of\0a\0a-- this software and associated documentation files (the \22Software\22), to deal in\0a\0a-- the Software without restriction, including without limitation the rights to\0a\0a-- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\0a\0a-- of the Software, and to permit persons to whom the Software is furnished to do\0a\0a-- so, subject to the following conditions:\0a\0a--\0a\0a-- The above copyright notice and this permission notice shall be included in all\0a\0a-- copies or substantial portions of the Software.\0a\0a--\0a\0a-- THE SOFTWARE IS PROVIDED \22AS IS\22, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\0a\0a-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\0a\0a-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\0a\0a-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\0a\0a-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\0a\0a-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\0a\0a-- SOFTWARE.\0a\0a--\0a\0a\0a\0alocal json = { _version = \220.1.2\22 }\0a\0a\0a\0a-------------------------------------------------------------------------------\0a\0a-- Encode\0a\0a-------------------------------------------------------------------------------\0a\0a\0a\0alocal encode\0a\0a\0a\0alocal escape_char_map = {\0a\0a [ \22\5c\5c\22 ] = \22\5c\5c\22,\0a\0a [ \22\5c\22\22 ] = \22\5c\22\22,\0a\0a [ \22\5cb\22 ] = \22b\22,\0a\0a [ \22\5cf\22 ] = \22f\22,\0a\0a [ \22\5cn\22 ] = \22n\22,\0a\0a [ \22\5cr\22 ] = \22r\22,\0a\0a [ \22\5ct\22 ] = \22t\22,\0a\0a}\0a\0a\0a\0alocal escape_char_map_inv = { [ \22/\22 ] = \22/\22 }\0a\0afor k, v in pairs(escape_char_map) do\0a\0a escape_char_map_inv[v] = k\0a\0aend\0a\0a\0a\0a\0a\0alocal function escape_char(c)\0a\0a return \22\5c\5c\22 .. (escape_char_map[c] or string.format(\22u%04x\22, c:byte()))\0a\0aend\0a\0a\0a\0a\0a\0alocal function encode_nil(val)\0a\0a return \22null\22\0a\0aend\0a\0a\0a\0a\0a\0alocal function encode_table(val, stack)\0a\0a local res = {}\0a\0a stack = stack or {}\0a\0a\0a\0a -- Circular reference?\0a\0a if stack[val] then error(\22circular reference\22) end\0a\0a\0a\0a stack[val] = true\0a\0a\0a\0a if rawget(val, 1) ~= nil or next(val) == nil then\0a\0a -- Treat as array -- check keys are valid and it is not sparse\0a\0a local n = 0\0a\0a for k in pairs(val) do\0a\0a if type(k) ~= \22number\22 then\0a\0a error(\22invalid table: mixed or invalid key types\22)\0a\0a end\0a\0a n = n + 1\0a\0a end\0a\0a if n ~= #val then\0a\0a error(\22invalid table: sparse array\22)\0a\0a end\0a\0a -- Encode\0a\0a for i, v in ipairs(val) do\0a\0a table.insert(res, encode(v, stack))\0a\0a end\0a\0a stack[val] = nil\0a\0a return \22[\22 .. table.concat(res, \22,\22) .. \22]\22\0a\0a\0a\0a else\0a\0a -- Treat as an object\0a\0a for k, v in pairs(val) do\0a\0a if type(k) ~= \22string\22 then\0a\0a error(\22invalid table: mixed or invalid key types\22)\0a\0a end\0a\0a table.insert(res, encode(k, stack) .. \22:\22 .. encode(v, stack))\0a\0a end\0a\0a stack[val] = nil\0a\0a return \22{\22 .. table.concat(res, \22,\22) .. \22}\22\0a\0a end\0a\0aend\0a\0a\0a\0a\0a\0alocal function encode_string(val)\0a\0a return '\22' .. val:gsub('[%z\5c1-\5c31\5c\5c\22]', escape_char) .. '\22'\0a\0aend\0a\0a\0a\0a\0a\0alocal function encode_number(val)\0a\0a -- Check for NaN, -inf and inf\0a\0a if val ~= val or val <= -math.huge or val >= math.huge then\0a\0a error(\22unexpected number value '\22 .. tostring(val) .. \22'\22)\0a\0a end\0a\0a return string.format(\22%.14g\22, val)\0a\0aend\0a\0a\0a\0a\0a\0alocal type_func_map = {\0a\0a [ \22nil\22 ] = encode_nil,\0a\0a [ \22table\22 ] = encode_table,\0a\0a [ \22string\22 ] = encode_string,\0a\0a [ \22number\22 ] = encode_number,\0a\0a [ \22boolean\22 ] = tostring,\0a\0a}\0a\0a\0a\0a\0a\0aencode = function(val, stack)\0a\0a local t = type(val)\0a\0a local f = type_func_map[t]\0a\0a if f then\0a\0a return f(val, stack)\0a\0a end\0a\0a error(\22unexpected type '\22 .. t .. \22'\22)\0a\0aend\0a\0a\0a\0a\0a\0afunction json.encode(val)\0a\0a return ( encode(val) )\0a\0aend\0a\0a\0a\0a\0a\0a-------------------------------------------------------------------------------\0a\0a-- Decode\0a\0a-------------------------------------------------------------------------------\0a\0a\0a\0alocal parse\0a\0a\0a\0alocal function create_set(...)\0a\0a local res = {}\0a\0a for i = 1, select(\22#\22, ...) do\0a\0a res[ select(i, ...) ] = true\0a\0a end\0a\0a return res\0a\0aend\0a\0a\0a\0alocal space_chars = create_set(\22 \22, \22\5ct\22, \22\5cr\22, \22\5cn\22)\0a\0alocal delim_chars = create_set(\22 \22, \22\5ct\22, \22\5cr\22, \22\5cn\22, \22]\22, \22}\22, \22,\22)\0a\0alocal escape_chars = create_set(\22\5c\5c\22, \22/\22, '\22', \22b\22, \22f\22, \22n\22, \22r\22, \22t\22, \22u\22)\0a\0alocal literals = create_set(\22true\22, \22false\22, \22null\22)\0a\0a\0a\0alocal literal_map = {\0a\0a [ \22true\22 ] = true,\0a\0a [ \22false\22 ] = false,\0a\0a [ \22null\22 ] = nil,\0a\0a}\0a\0a\0a\0a\0a\0alocal function next_char(str, idx, set, negate)\0a\0a for i = idx, #str do\0a\0a if set[str:sub(i, i)] ~= negate then\0a\0a return i\0a\0a end\0a\0a end\0a\0a return #str + 1\0a\0aend\0a\0a\0a\0a\0a\0alocal function decode_error(str, idx, msg)\0a\0a local line_count = 1\0a\0a local col_count = 1\0a\0a for i = 1, idx - 1 do\0a\0a col_count = col_count + 1\0a\0a if str:sub(i, i) == \22\5cn\22 then\0a\0a line_count = line_count + 1\0a\0a col_count = 1\0a\0a end\0a\0a end\0a\0a error( string.format(\22%s at line %d col %d\22, msg, line_count, col_count) )\0a\0aend\0a\0a\0a\0a\0a\0alocal function codepoint_to_utf8(n)\0a\0a -- http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=iws-appendixa\0a\0a local f = math.floor\0a\0a if n <= 0x7f then\0a\0a return string.char(n)\0a\0a elseif n <= 0x7ff then\0a\0a return string.char(f(n / 64) + 192, n % 64 + 128)\0a\0a elseif n <= 0xffff then\0a\0a return string.char(f(n / 4096) + 224, f(n % 4096 / 64) + 128, n % 64 + 128)\0a\0a elseif n <= 0x10ffff then\0a\0a return string.char(f(n / 262144) + 240, f(n % 262144 / 4096) + 128,\0a\0a f(n % 4096 / 64) + 128, n % 64 + 128)\0a\0a end\0a\0a error( string.format(\22invalid unicode codepoint '%x'\22, n) )\0a\0aend\0a\0a\0a\0a\0a\0alocal function parse_unicode_escape(s)\0a\0a local n1 = tonumber( s:sub(1, 4), 16 )\0a\0a local n2 = tonumber( s:sub(7, 10), 16 )\0a\0a -- Surrogate pair?\0a\0a if n2 then\0a\0a return codepoint_to_utf8((n1 - 0xd800) * 0x400 + (n2 - 0xdc00) + 0x10000)\0a\0a else\0a\0a return codepoint_to_utf8(n1)\0a\0a end\0a\0aend\0a\0a\0a\0a\0a\0alocal function parse_string(str, i)\0a\0a local res = \22\22\0a\0a local j = i + 1\0a\0a local k = j\0a\0a\0a\0a while j <= #str do\0a\0a local x = str:byte(j)\0a\0a\0a\0a if x < 32 then\0a\0a decode_error(str, j, \22control character in string\22)\0a\0a\0a\0a elseif x == 92 then -- `\5c`: Escape\0a\0a res = res .. str:sub(k, j - 1)\0a\0a j = j + 1\0a\0a local c = str:sub(j, j)\0a\0a if c == \22u\22 then\0a\0a local hex = str:match(\22^[dD][89aAbB]%x%x\5c\5cu%x%x%x%x\22, j + 1)\0a\0a or str:match(\22^%x%x%x%x\22, j + 1)\0a\0a or decode_error(str, j - 1, \22invalid unicode escape in string\22)\0a\0a res = res .. parse_unicode_escape(hex)\0a\0a j = j + #hex\0a\0a else\0a\0a if not escape_chars[c] then\0a\0a decode_error(str, j - 1, \22invalid escape char '\22 .. c .. \22' in string\22)\0a\0a end\0a\0a res = res .. escape_char_map_inv[c]\0a\0a end\0a\0a k = j + 1\0a\0a\0a\0a elseif x == 34 then -- `\22`: End of string\0a\0a res = res .. str:sub(k, j - 1)\0a\0a return res, j + 1\0a\0a end\0a\0a\0a\0a j = j + 1\0a\0a end\0a\0a\0a\0a decode_error(str, i, \22expected closing quote for string\22)\0a\0aend\0a\0a\0a\0a\0a\0alocal function parse_number(str, i)\0a\0a local x = next_char(str, i, delim_chars)\0a\0a local s = str:sub(i, x - 1)\0a\0a local n = tonumber(s)\0a\0a if not n then\0a\0a decode_error(str, i, \22invalid number '\22 .. s .. \22'\22)\0a\0a end\0a\0a return n, x\0a\0aend\0a\0a\0a\0a\0a\0alocal function parse_literal(str, i)\0a\0a local x = next_char(str, i, delim_chars)\0a\0a local word = str:sub(i, x - 1)\0a\0a if not literals[word] then\0a\0a decode_error(str, i, \22invalid literal '\22 .. word .. \22'\22)\0a\0a end\0a\0a return literal_map[word], x\0a\0aend\0a\0a\0a\0a\0a\0alocal function parse_array(str, i)\0a\0a local res = {}\0a\0a local n = 1\0a\0a i = i + 1\0a\0a while 1 do\0a\0a local x\0a\0a i = next_char(str, i, space_chars, true)\0a\0a -- Empty / end of array?\0a\0a if str:sub(i, i) == \22]\22 then\0a\0a i = i + 1\0a\0a break\0a\0a end\0a\0a -- Read token\0a\0a x, i = parse(str, i)\0a\0a res[n] = x\0a\0a n = n + 1\0a\0a -- Next token\0a\0a i = next_char(str, i, space_chars, true)\0a\0a local chr = str:sub(i, i)\0a\0a i = i + 1\0a\0a if chr == \22]\22 then break end\0a\0a if chr ~= \22,\22 then decode_error(str, i, \22expected ']' or ','\22) end\0a\0a end\0a\0a return res, i\0a\0aend\0a\0a\0a\0a\0a\0alocal function parse_object(str, i)\0a\0a local res = {}\0a\0a i = i + 1\0a\0a while 1 do\0a\0a local key, val\0a\0a i = next_char(str, i, space_chars, true)\0a\0a -- Empty / end of object?\0a\0a if str:sub(i, i) == \22}\22 then\0a\0a i = i + 1\0a\0a break\0a\0a end\0a\0a -- Read key\0a\0a if str:sub(i, i) ~= '\22' then\0a\0a decode_error(str, i, \22expected string for key\22)\0a\0a end\0a\0a key, i = parse(str, i)\0a\0a -- Read ':' delimiter\0a\0a i = next_char(str, i, space_chars, true)\0a\0a if str:sub(i, i) ~= \22:\22 then\0a\0a decode_error(str, i, \22expected ':' after key\22)\0a\0a end\0a\0a i = next_char(str, i + 1, space_chars, true)\0a\0a -- Read value\0a\0a val, i = parse(str, i)\0a\0a -- Set\0a\0a res[key] = val\0a\0a -- Next token\0a\0a i = next_char(str, i, space_chars, true)\0a\0a local chr = str:sub(i, i)\0a\0a i = i + 1\0a\0a if chr == \22}\22 then break end\0a\0a if chr ~= \22,\22 then decode_error(str, i, \22expected '}' or ','\22) end\0a\0a end\0a\0a return res, i\0a\0aend\0a\0a\0a\0a\0a\0alocal char_func_map = {\0a\0a [ '\22' ] = parse_string,\0a\0a [ \220\22 ] = parse_number,\0a\0a [ \221\22 ] = parse_number,\0a\0a [ \222\22 ] = parse_number,\0a\0a [ \223\22 ] = parse_number,\0a\0a [ \224\22 ] = parse_number,\0a\0a [ \225\22 ] = parse_number,\0a\0a [ \226\22 ] = parse_number,\0a\0a [ \227\22 ] = parse_number,\0a\0a [ \228\22 ] = parse_number,\0a\0a [ \229\22 ] = parse_number,\0a\0a [ \22-\22 ] = parse_number,\0a\0a [ \22t\22 ] = parse_literal,\0a\0a [ \22f\22 ] = parse_literal,\0a\0a [ \22n\22 ] = parse_literal,\0a\0a [ \22[\22 ] = parse_array,\0a\0a [ \22{\22 ] = parse_object,\0a\0a}\0a\0a\0a\0a\0a\0aparse = function(str, idx)\0a\0a local chr = str:sub(idx, idx)\0a\0a local f = char_func_map[chr]\0a\0a if f then\0a\0a return f(str, idx)\0a\0a end\0a\0a decode_error(str, idx, \22unexpected character '\22 .. chr .. \22'\22)\0a\0aend\0a\0a\0a\0a\0a\0afunction json.decode(str)\0a\0a if type(str) ~= \22string\22 then\0a\0a error(\22expected argument of type string, got \22 .. type(str))\0a\0a end\0a\0a local res, idx = parse(str, next_char(str, 1, space_chars, true))\0a\0a idx = next_char(str, idx, space_chars, true)\0a\0a if idx <= #str then\0a\0a decode_error(str, idx, \22trailing garbage\22)\0a\0a end\0a\0a return res\0a\0aend\0a\0a\0a\0a\0a\0areturn json\00\00\00\00\00p\7f@")
(data $.rodata.17 (;17;) (i64.const 295594) "\08\08\08\08\08")
(data $.rodata.18 (;18;) (i64.const 295617) "\0c\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\16\16\16\16\16\16\16\16\16\16\04\04\04\04\04\04\04\15\15\15\15\15\15\05\05\05\05\05\05\05\05\05\05\05\05\05\05\05\05\05\05\05\05\04\04\04\04\05\04\15\15\15\15\15\15\05\05\05\05\05\05\05\05\05\05\05\05\05\05\05\05\05\05\05\05\04\04\04\04")
(data $.rodata.19 (;19;) (i64.const 295873) "\01\02\02\03\03\03\03\04\04\04\04\04\04\04\04\05\05\05\05\05\05\05\05\05\05\05\05\05\05\05\05\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\06\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\07\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08\08`qATPP\5cl<\10<Tl||||||||||||````h\22\bc\bc\bc\84\e4TT\10bb\04b\14QP\17\00\e2\19\00\00\00\00\00\00\c1\11\00\00\00\00\00\00\c2\0d\00\00\00\00\00\00\b0\15\00\00\00\00\00\00\ff\13\00\00\00\00\00\00\db\19\00\00\00\00\00\00\b5\15\00\00\00\00\00\00.\0b\00\00\00\00\00\00\8b\0e\00\00\00\00\00\00;\0d\00\00\00\00\00\00\03\14\00\00\00\00\00\00#\10\00\00\00\00\00\00?\11\00\00\00\00\00\00\0e\11\00\00\00\00\00\00a\06\00\00\00\00\00\005\0b\00\00\00\00\00\00\9e\07\00\00\00\00\00\00\c8\0d\00\00\00\00\00\00@\10\00\00\00\00\00\00\e2\14\00\00\00\00\00\00\f9\10\00\00\00\00\00\00\1f\17\00\00\00\00\00\00\8a \00\00\00\00\00\00\94 \00\00\00\00\00\00\93 \00\00\00\00\00\00\0d\1f\00\00\00\00\00\00\0a\1f\00\00\00\00\00\00\10\1f\00\00\00\00\00\00\07\1f\00\00\00\00\00\00\13\1f\00\00\00\00\00\00\04\1f\00\00\00\00\00\008\1f\00\00\00\00\00\00\e0\1e\00\00\00\00\00\00\ce\1e\00\00\00\00\00\00\c4\1e\00\00\00\00\00\00\e6\1e\00\00\00\00\00\00\d7\1e\00\00\00\00\00\00\06")
(data $.rodata.20 (;20;) (i64.const 296488) "\ff\ff\ff\ff\ff\ff\ff\ff\0a\0a\0a\0a\0b\0b\0b\0b\0e\0d\0b\0b\0b\0b\06\06\04\04\05\05\07\07\07\07\09\08\03\03\03\03\03\03\03\03\03\03\03\03\02\02\01\01")
(data $.rodata.21 (;21;) (i64.const 296576) "userdata\00\00\00\00\00\00\00\00\17\15\00\00\00\00\00\00\0e\11\00\00\00\00\00\00N\10\00\00\00\00\00\00\80\86\04\00\00\00\00\00p\0c\00\00\00\00\00\00q\13\00\00\00\00\00\00\05\18\00\00\00\00\00\00\8b\0e\00\00\00\00\00\00\80\86\04\00\00\00\00\00\a9\1b\00\00\00\00\00\005\0d")
(data $.rodata.22 (;22;) (i64.const 296688) "<\05\00\00\00\00\00\001\05\00\00\00\00\00\00W\1c\00\00\00\00\00\004\19\00\00\00\00\00\00:\10\00\00\00\00\00\00\8c\0c\00\00\00\00\00\00\97\1b\00\00\00\00\00\00\a6\1c\00\00\00\00\00\00\b9\10\00\00\00\00\00\00\92\19\00\00\00\00\00\00{\05\00\00\00\00\00\00\e9\05\00\00\00\00\00\00\e2\05\00\00\00\00\00\00\df\19\00\00\00\00\00\002\0b\00\00\00\00\00\00\07\0b\00\00\00\00\00\00\17\11\00\00\00\00\00\008\0b\00\00\00\00\00\00\94\10\00\00\00\00\00\00^\06\00\00\00\00\00\00\a7\06\00\00\00\00\00\00!\18\00\00\00\00\00\00\a5\07\00\00\00\00\00\00\e8\10\00\00\00\00\00\00H\06\00\00\00\00\00\00\16\00\00\00\00\00\00\00%\19\00\00\00\00\00\00\17\00\00\00\00\00\00\00-\17\00\00\00\00\00\00\18\00\00\00\00\00\00\00\22\0b\00\00\00\00\00\00\19\00\00\00\00\00\00\00\89\17\00\00\00\00\00\00\1a\00\00\00\00\00\00\00J\08\00\00\00\00\00\00\1b\00\00\00\00\00\00\004\17\00\00\00\00\00\00\1c\00\00\00\00\00\00\00\a4\1b\00\00\00\00\00\00\1d\00\00\00\00\00\00\00\fb\05\00\00\00\00\00\00\14\00\00\00\00\00\00\00S\08\00\00\00\00\00\00\1e\00\00\00\00\00\00\00\d7\10\00\00\00\00\00\00\1f\00\00\00\00\00\00\00p\06\00\00\00\00\00\00 \00\00\00\00\00\00\00#\11\00\00\00\00\00\00!\00\00\00\00\00\00\003\10\00\00\00\00\00\00\22\00\00\00\00\00\00\00H\07\00\00\00\00\00\00#\00\00\00\00\00\00\00:\07\00\00\00\00\00\00$\00\00\00\00\00\00\00W\07\00\00\00\00\00\00%\00\00\00\00\00\00\00|\17\00\00\00\00\00\00&\00\00\00\00\00\00\00\ff\0b\00\00\00\00\00\00'\00\00\00\00\00\00\00\84\12\00\00\00\00\00\00(\00\00\00\00\00\00\00\ef\15\00\00\00\00\00\00)\00\00\00\00\00\00\00\d6\10\00\00\00\00\00\00*\00\00\00\00\00\00\00\9f\1e")
(data $.rodata.23 (;23;) (i64.const 297248) "u\1e")
(data $.rodata.24 (;24;) (i64.const 297280) "\9d\0c\00\00\00\00\00\00V\06\00\00\00\00\00\00O\07\00\00\00\00\00\00e\06\00\00\00\00\00\00\1d\0d\00\00\00\00\00\00\99\15\00\00\00\00\00\00\ae\10\00\00\00\00\00\00x\13")
(data $.rodata.25 (;25;) (i64.const 297364) "\01\00\00\00\02\00\00\00\03\00\00\00\05\00\00\00\06\00\00\00\07\00\00\00\09\00\00\00\af\1c\00\00\00\00\00\000\00\00\00\00\00\00\00\d0\11\00\00\00\00\00\001\00\00\00\00\00\00\00\a1\1b")
(data $.rodata.26 (;26;) (i64.const 297440) "\db\11")
(data $.rodata.27 (;27;) (i64.const 297456) "\dc\11")
(data $.rodata.28 (;28;) (i64.const 297472) "\93\08")
(data $.rodata.29 (;29;) (i64.const 297488) "\90\1b")
(data $.rodata.30 (;30;) (i64.const 297520) "\e6\15\00\00\00\00\00\002")
(data $.rodata.31 (;31;) (i64.const 297568) "\8d\15\00\00\00\00\00\004\00\00\00\00\00\00\00\9e\16\00\00\00\00\00\005\00\00\00\00\00\00\00z\13\00\00\00\00\00\006\00\00\00\00\00\00\00\b8\07\00\00\00\00\00\007\00\00\00\00\00\00\00&\0d\00\00\00\00\00\008\00\00\00\00\00\00\00\eb\19\00\00\00\00\00\009\00\00\00\00\00\00\00\0b\18\00\00\00\00\00\00:")
(data $.rodata.32 (;32;) (i64.const 297696) "\a7\07\00\00\00\00\00\00;\00\00\00\00\00\00\00O\06\00\00\00\00\00\00<\00\00\00\00\00\00\00\b2\11\00\00\00\00\00\00=\00\00\00\00\00\00\00\b0\11\00\00\00\00\00\00>\00\00\00\00\00\00\00\91\14\00\00\00\00\00\00?\00\00\00\00\00\00\00\ad\14\00\00\00\00\00\00@\00\00\00\00\00\00\00-\06\00\00\00\00\00\00A")
(data $.rodata.33 (;33;) (i64.const 297824) "\aa\15\00\00\00\00\00\00F\00\00\00\00\00\00\00\e6\11\00\00\00\00\00\00G\00\00\00\00\00\00\00\0f\06\00\00\00\00\00\00H\00\00\00\00\00\00\00\a1\09\00\00\00\00\00\00I\00\00\00\00\00\00\00.\10\00\00\00\00\00\00J\00\00\00\00\00\00\00\04\06\00\00\00\00\00\00K\00\00\00\00\00\00\00&\10\00\00\00\00\00\00L\00\00\00\00\00\00\00\ab\1b\00\00\00\00\00\00M\00\00\00\00\00\00\00%\17\00\00\00\00\00\00N\00\00\00\00\00\00\00\ef\15\00\00\00\00\00\00O\00\00\00\00\00\00\00c\15\00\00\00\00\00\00P")
(data $.rodata.34 (;34;) (i64.const 298016) "\aa\15\00\00\00\00\00\00F\00\00\00\00\00\00\00\e6\11\00\00\00\00\00\00Q\00\00\00\00\00\00\00\a1\09\00\00\00\00\00\00R\00\00\00\00\00\00\00\ab\1b\00\00\00\00\00\00S\00\00\00\00\00\00\00\91\11\00\00\00\00\00\00T\00\00\00\00\00\00\00\e0\13\00\00\00\00\00\00U\00\00\00\00\00\00\00c\15\00\00\00\00\00\00V\00\00\00\00\00\00\00W\1c\00\00\00\00\00\00W\00\00\00\00\00\00\00\82\12\00\00\00\00\00\00X")
(data $.rodata.35 (;35;) (i64.const 298180) "\01\00\00\00\02\00\00\00\00\00\00\00D\07\00\00\00\00\00\00\e4\0a\00\00\00\00\00\00\db\19")
(data $.rodata.36 (;36;) (i64.const 298224) "\02\00\00\00\00\00\00\00\01\00\00\00\00\00\00\00\b4\0d\00\00\00\00\00\00\d1\10\00\00\00\00\00\00h\16")
(data $.rodata.37 (;37;) (i64.const 298272) "\96\11\00\00\00\00\00\00Y\00\00\00\00\00\00\00\94\15\00\00\00\00\00\00Z\00\00\00\00\00\00\00\db\16\00\00\00\00\00\00[\00\00\00\00\00\00\00[\15\00\00\00\00\00\00\5c\00\00\00\00\00\00\00\ac\06\00\00\00\00\00\00]\00\00\00\00\00\00\00\db\05\00\00\00\00\00\00^\00\00\00\00\00\00\00\91\14\00\00\00\00\00\00_\00\00\00\00\00\00\00\ec\16\00\00\00\00\00\00`\00\00\00\00\00\00\00\17\18\00\00\00\00\00\00a\00\00\00\00\00\00\00\df\16\00\00\00\00\00\00b\00\00\00\00\00\00\00\e4\16\00\00\00\00\00\00c")
(data $.rodata.38 (;38;) (i64.const 298464) "\06\00\00\00\03\00\00\00\00\00\00\00\04\00\00\00\01\00\00\00\02")
(data $.rodata.39 (;39;) (i64.const 298496) "\f5\10\00\00\00\00\00\00\85\15\00\00\00\00\00\00\ee\15\00\00\00\00\00\00A\04\00\00\00\00\00\00O\1c\00\00\00\00\00\00\df\16")
(data $.rodata.40 (;40;) (i64.const 298560) "V\15\00\00\00\00\00\00f\00\00\00\00\00\00\00\82\0c\00\00\00\00\00\00g\00\00\00\00\00\00\00\18\0d\00\00\00\00\00\00h\00\00\00\00\00\00\00\d6\19\00\00\00\00\00\00i\00\00\00\00\00\00\00\8e\07\00\00\00\00\00\00j\00\00\00\00\00\00\00\fb\11\00\00\00\00\00\00k\00\00\00\00\00\00\00\a1\1c\00\00\00\00\00\00l\00\00\00\00\00\00\00<\10\00\00\00\00\00\00m\00\00\00\00\00\00\00>\0b\00\00\00\00\00\00n\00\00\00\00\00\00\00\fc\11\00\00\00\00\00\00o\00\00\00\00\00\00\00\22\0d\00\00\00\00\00\00p\00\00\00\00\00\00\00\a2\15\00\00\00\00\00\00q\00\00\00\00\00\00\00\a8\1c\00\00\00\00\00\00r\00\00\00\00\00\00\00b\0b\00\00\00\00\00\00s\00\00\00\00\00\00\00\b2\11\00\00\00\00\00\00t\00\00\00\00\00\00\00A\14\00\00\00\00\00\00u\00\00\00\00\00\00\00\b0\11\00\00\00\00\00\00v")
(data $.rodata.41 (;41;) (i64.const 298848) "\e9\09\00\00\00\00\00\00w\00\00\00\00\00\00\00\c5\08\00\00\00\00\00\00x\00\00\00\00\00\00\00\ad\0f\00\00\00\00\00\00y\00\00\00\00\00\00\00E\10\00\00\00\00\00\00z\00\00\00\00\00\00\00\12\11\00\00\00\00\00\00{\00\00\00\00\00\00\00\c6\08\00\00\00\00\00\00|\00\00\00\00\00\00\00\d6\13\00\00\00\00\00\00}\00\00\00\00\00\00\00\99\0c\00\00\00\00\00\00~\00\00\00\00\00\00\00s\0b\00\00\00\00\00\00\7f\00\00\00\00\00\00\00(\0b\00\00\00\00\00\00\80\00\00\00\00\00\00\00\8d\19\00\00\00\00\00\00\81\00\00\00\00\00\00\00\a3\06\00\00\00\00\00\00\82\00\00\00\00\00\00\00\11\12\00\00\00\00\00\00\83\00\00\00\00\00\00\00Z\05\00\00\00\00\00\00\84\00\00\00\00\00\00\00\be\0f\00\00\00\00\00\00\85\00\00\00\00\00\00\00\06\14\00\00\00\00\00\00\86\00\00\00\00\00\00\00\9d\1b\00\00\00\00\00\00\87\00\00\00\00\00\00\00\8d\10\00\00\00\00\00\00\88\00\00\00\00\00\00\00{\1b\00\00\00\00\00\00\89\00\00\00\00\00\00\00\ae\0f\00\00\00\00\00\00\8a\00\00\00\00\00\00\00(\06\00\00\00\00\00\00\8b\00\00\00\00\00\00\00F\10\00\00\00\00\00\00\8c\00\00\00\00\00\00\00\ef\15\00\00\00\00\00\00\8d\00\00\00\00\00\00\00\e7\1f\00\00\00\00\00\00z\00\00\00\00\00\00\00\ec\11\00\00\00\00\00\00\8e\00\00\00\00\00\00\00\f1\11\00\00\00\00\00\00\8f\00\00\00\00\00\00\00\f6\11\00\00\00\00\00\00\90\00\00\00\00\00\00\00}\05\00\00\00\00\00\00\91\00\00\00\00\00\00\00\91\0c\00\00\00\00\00\00\92\00\00\00\00\00\00\00\97\0c\00\00\00\00\00\00\93\00\00\00\00\00\00\00\84 \00\00\00\00\00\00\94\00\00\00\00\00\00\00\c7\11")
(data $.rodata.42 (;42;) (i64.const 299360) "&\18")
(data $.rodata.43 (;43;) (i64.const 299376) "h\0b")
(data $.rodata.44 (;44;) (i64.const 299392) "}\0b")
(data $.rodata.45 (;45;) (i64.const 299424) "A\07\00\00\00\00\00\00\96\00\00\00\00\00\00\00v\06\00\00\00\00\00\00\97\00\00\00\00\00\00\00\82\0c\00\00\00\00\00\00\98\00\00\00\00\00\00\00<\10\00\00\00\00\00\00\99\00\00\00\00\00\00\00\b9\09\00\00\00\00\00\00\9a\00\00\00\00\00\00\00\cf\0d")
(data $.rodata.46 (;46;) (i64.const 299536) "[\00-\7f\c2-\f4][\80-\bf]*\00\00\ff\00\00\00\7f\00\00\00\ff\07\00\00\ff\ff\00\00\02\12\00\00\00\00\00\00\9c\00\00\00\00\00\00\00\f4\14\00\00\00\00\00\00\9d\00\00\00\00\00\00\00W\11\00\00\00\00\00\00\9e\00\00\00\00\00\00\00\ba\0d\00\00\00\00\00\00\9f\00\00\00\00\00\00\00<\11\00\00\00\00\00\00\a0\00\00\00\00\00\00\00#\04\00\00\00\00\00\00\a1\00\00\00\00\00\00\00\89\17\00\00\00\00\00\00\a2\00\00\00\00\00\00\00\0c\15\00\00\00\00\00\00\a3\00\00\00\00\00\00\00\b2\0f\00\00\00\00\00\00\a4\00\00\00\00\00\00\00\f7\19\00\00\00\00\00\00\a5\00\00\00\00\00\00\00\e7\14\00\00\00\00\00\00\a6\00\00\00\00\00\00\00O\11\00\00\00\00\00\00\a7\00\00\00\00\00\00\003\11\00\00\00\00\00\00\a8\00\00\00\00\00\00\00|\17\00\00\00\00\00\00\a9\00\00\00\00\00\00\00\01\15\00\00\00\00\00\00\aa\00\00\00\00\00\00\00\b7\11\00\00\00\00\00\00\ab")
(data $.rodata.47 (;47;) (i64.const 299856) "\f4\10\00\00\00\00\00\00\c8\0d\00\00\00\00\00\00h\16\00\00\00\00\00\00e\06\00\00\00\00\00\00\ef\10")
(data $.rodata.48 (;48;) (i64.const 299904) "+\07\00\00\00\00\00\00\ac\00\00\00\00\00\00\00\e1\19\00\00\00\00\00\00\ad\00\00\00\00\00\00\00`\06\00\00\00\00\00\00\ae\00\00\00\00\00\00\004\0b\00\00\00\00\00\00\af\00\00\00\00\00\00\00\09\0b\00\00\00\00\00\00\b0\00\00\00\00\00\00\00\1c\06\00\00\00\00\00\00\b1\00\00\00\00\00\00\00^\07\00\00\00\00\00\00\b2\00\00\00\00\00\00\00q\15\00\00\00\00\00\00\b3\00\00\00\00\00\00\003\07\00\00\00\00\00\00\b4\00\00\00\00\00\00\00\82\19\00\00\00\00\00\00\b5\00\00\00\00\00\00\00i\15\00\00\00\00\00\00\b6\00\00\00\00\00\00\00,\07\00\00\00\00\00\00\b7")
(data $.rodata.49 (;49;) (i64.const 300112) "O\bba\05g\ac\dd?\18-DT\fb!\e9?\9b\f6\81\d2\0bs\ef?\18-DT\fb!\f9?\e2e/\22\7f+z<\07\5c\143&\a6\81<\bd\cb\f0z\88\07p<\07\5c\143&\a6\91<\18-DT\fb!\e9?\18-DT\fb!\e9\bf\d2!3\7f|\d9\02@\d2!3\7f|\d9\02\c0")
(data $.rodata.50 (;50;) (i64.const 300223) "\80\18-DT\fb!\09@\18-DT\fb!\09\c0\03\00\00\00\04\00\00\00\04\00\00\00\06\00\00\00\83\f9\a2\00DNn\00\fc)\15\00\d1W'\00\dd4\f5\00b\db\c0\00<\99\95\00A\90C\00cQ\fe\00\bb\de\ab\00\b7a\c5\00:n$\00\d2MB\00I\06\e0\00\09\ea.\00\1c\92\d1\00\eb\1d\fe\00)\b1\1c\00\e8>\a7\00\f55\82\00D\bb.\00\9c\e9\84\00\b4&p\00A~_\00\d6\919\00S\839\00\9c\f49\00\8b_\84\00(\f9\bd\00\f8\1f;\00\de\ff\97\00\0f\98\05\00\11/\ef\00\0aZ\8b\00m\1fm\00\cf~6\00\09\cb'\00FO\b7\00\9ef?\00-\ea_\00\ba'u\00\e5\eb\c7\00={\f1\00\f79\07\00\92R\8a\00\fbk\ea\00\1f\b1_\00\08]\8d\000\03V\00{\fcF\00\f0\abk\00 \bc\cf\006\f4\9a\00\e3\a9\1d\00^a\91\00\08\1b\e6\00\85\99e\00\a0\14_\00\8d@h\00\80\d8\ff\00'sM\00\06\061\00\caV\15\00\c9\a8s\00{\e2`\00k\8c\c0\00\19\c4G\00\cdg\c3\00\09\e8\dc\00Y\83*\00\8bv\c4\00\a6\1c\96\00D\af\dd\00\19W\d1\00\a5>\05\00\05\07\ff\003~?\00\c22\e8\00\98O\de\00\bb}2\00&=\c3\00\1ek\ef\00\9f\f8^\005\1f:\00\7f\f2\ca\00\f1\87\1d\00|\90!\00j$|\00\d5n\fa\000-w\00\15;C\00\b5\14\c6\00\c3\19\9d\00\ad\c4\c2\00,MA\00\0c\00]\00\86}F\00\e3q-\00\9b\c6\9a\003b\00\00\b4\d2|\00\b4\a7\97\007U\d5\00\d7>\f6\00\a3\10\18\00Mv\fc\00d\9d*\00p\d7\ab\00c|\f8\00z\b0W\00\17\15\e7\00\c0IV\00;\d6\d9\00\a7\848\00$#\cb\00\d6\8aw\00ZT#\00\00\1f\b9\00\f1\0a\1b\00\19\ce\df\00\9f1\ff\00f\1ej\00\99Wa\00\ac\fbG\00~\7f\d8\00\22e\b7\002\e8\89\00\e6\bf`\00\ef\c4\cd\00l6\09\00]?\d4\00\16\de\d7\00X;\de\00\de\9b\92\00\d2\22(\00(\86\e8\00\e2XM\00\c6\ca2\00\08\e3\16\00\e0}\cb\00\17\c0P\00\f3\1d\a7\00\18\e0[\00.\134\00\83\12b\00\83H\01\00\f5\8e[\00\ad\b0\7f\00\1e\e9\f2\00HJC\00\10g\d3\00\aa\dd\d8\00\ae_B\00ja\ce\00\0a(\a4\00\d3\99\b4\00\06\a6\f2\00\5cw\7f\00\a3\c2\83\00a<\88\00\8asx\00\af\8cZ\00o\d7\bd\00-\a6c\00\f4\bf\cb\00\8d\81\ef\00&\c1g\00U\caE\00\ca\d96\00(\a8\d2\00\c2a\8d\00\12\c9w\00\04&\14\00\12F\9b\00\c4Y\c4\00\c8\c5D\00M\b2\91\00\00\17\f3\00\d4C\ad\00)I\e5\00\fd\d5\10\00\00\be\fc\00\1e\94\cc\00p\ce\ee\00\13>\f5\00\ec\f1\80\00\b3\e7\c3\00\c7\f8(\00\93\05\94\00\c1q>\00.\09\b3\00\0bE\f3\00\88\12\9c\00\ab {\00.\b5\9f\00G\92\c2\00{2/\00\0cUm\00r\a7\90\00k\e7\1f\001\cb\96\00y\16J\00Ay\e2\00\f4\df\89\00\e8\94\97\00\e2\e6\84\00\991\97\00\88\edk\00__6\00\bb\fd\0e\00H\9a\b4\00g\a4l\00qrB\00\8d]2\00\9f\15\b8\00\bc\e5\09\00\8d1%\00\f7t9\000\05\1c\00\0d\0c\01\00K\08h\00,\eeX\00G\aa\90\00t\e7\02\00\bd\d6$\00\f7}\a6\00nHr\00\9f\16\ef\00\8e\94\a6\00\b4\91\f6\00\d1SQ\00\cf\0a\f2\00 \983\00\f5K~\00\b2ch\00\dd>_\00@]\03\00\85\89\7f\00UR)\007d\c0\00m\d8\10\002H2\00[Lu\00Nq\d4\00ETn\00\0b\09\c1\00*\f5i\00\14f\d5\00'\07\9d\00]\04P\00\b4;\db\00\eav\c5\00\87\f9\17\00Ik}\00\1d'\ba\00\96i)\00\c6\cc\ac\00\ad\14T\00\90\e2j\00\88\d9\89\00,rP\00\04\a4\be\00w\07\94\00\f30p\00\00\fc'\00\eaq\a8\00f\c2I\00d\e0=\00\97\dd\83\00\a3?\97\00C\94\fd\00\0d\86\8c\001A\de\00\929\9d\00\ddp\8c\00\17\b7\e7\00\08\df;\00\157+\00\5c\80\a0\00Z\80\93\00\10\11\92\00\0f\e8\d8\00l\80\af\00\db\ffK\008\90\0f\00Y\18v\00b\a5\15\00a\cb\bb\00\c7\89\b9\00\10@\bd\00\d2\f2\04\00Iu'\00\eb\b6\f6\00\db\22\bb\00\0a\14\aa\00\89&/\00d\83v\00\09;3\00\0e\94\1a\00Q:\aa\00\1d\a3\c2\00\af\ed\ae\00\5c&\12\00m\c2M\00-z\9c\00\c0V\97\00\03?\83\00\09\f0\f6\00+@\8c\00m1\99\009\b4\07\00\0c \15\00\d8\c3[\00\f5\92\c4\00\c6\adK\00N\ca\a5\00\a77\cd\00\e6\a96\00\ab\92\94\00\ddBh\00\19c\de\00v\8c\ef\00h\8bR\00\fc\db7\00\ae\a1\ab\00\df\151\00\00\ae\a1\00\0c\fb\da\00dMf\00\ed\05\b7\00)e0\00WV\bf\00G\ff:\00j\f9\b9\00u\be\f3\00(\93\df\00\ab\800\00f\8c\f6\00\04\cb\15\00\fa\22\06\00\d9\e4\1d\00=\b3\a4\00W\1b\8f\006\cd\09\00NB\e9\00\13\be\a4\003#\b5\00\f0\aa\1a\00Oe\a8\00\d2\c1\a5\00\0b?\0f\00[x\cd\00#\f9v\00{\8b\04\00\89\17r\00\c6\a6S\00on\e2\00\ef\eb\00\00\9bJX\00\c4\da\b7\00\aaf\ba\00v\cf\cf\00\d1\02\1d\00\b1\f1-\00\8c\99\c1\00\c3\adw\00\86H\da\00\f7]\a0\00\c6\80\f4\00\ac\f0/\00\dd\ec\9a\00?\5c\bc\00\d0\dem\00\90\c7\1f\00*\db\b6\00\a3%:\00\00\af\9a\00\adS\93\00\b6W\04\00)-\b4\00K\80~\00\da\07\a7\00v\aa\0e\00{Y\a1\00\16\12*\00\dc\b7-\00\fa\e5\fd\00\89\db\fe\00\89\be\fd\00\e4vl\00\06\a9\fc\00>\80p\00\85n\15\00\fd\87\ff\00(>\07\00ag3\00*\18\86\00M\bd\ea\00\b3\e7\af\00\8fmn\00\95g9\001\bf[\00\84\d7H\000\df\16\00\c7-C\00%a5\00\c9p\ce\000\cb\b8\00\bfl\fd\00\a4\00\a2\00\05l\e4\00Z\dd\a0\00!oG\00b\12\d2\00\b9\5c\84\00paI\00kV\e0\00\99R\01\00PU7\00\1e\d5\b7\003\f1\c4\00\13n_\00]0\e4\00\85.\a9\00\1d\b2\c3\00\a126\00\08\b7\a4\00\ea\b1\d4\00\16\f7!\00\8fi\e4\00'\ffw\00\0c\03\80\00\8d@-\00O\cd\a0\00 \a5\99\00\b3\a2\d3\00/]\0a\00\b4\f9B\00\11\da\cb\00}\be\d0\00\9b\db\c1\00\ab\17\bd\00\ca\a2\81\00\08j\5c\00.U\17\00'\00U\00\7f\14\f0\00\e1\07\86\00\14\0bd\00\96A\8d\00\87\be\de\00\da\fd*\00k%\b6\00{\894\00\05\f3\fe\00\b9\bf\9e\00hjO\00J*\a8\00O\c4Z\00-\f8\bc\00\d7Z\98\00\f4\c7\95\00\0dM\8d\00 :\a6\00\a4W_\00\14?\b1\00\808\95\00\cc \01\00q\dd\86\00\c9\de\b6\00\bf`\f5\00Me\11\00\01\07k\00\8c\b0\ac\00\b2\c0\d0\00QUH\00\1e\fb\0e\00\95r\c3\00\a3\06;\00\c0@5\00\06\dc{\00\e0E\cc\00N)\fa\00\d6\ca\c8\00\e8\f3A\00|d\de\00\9bd\d8\00\d9\be1\00\a4\97\c3\00wX\d4\00i\e3\c5\00\f0\da\13\00\ba:<\00F\18F\00Uu_\00\d2\bd\f5\00n\92\c6\00\ac.]\00\0eD\ed\00\1c>B\00a\c4\87\00)\fd\e9\00\e7\d6\f3\00\22|\ca\00o\915\00\08\e0\c5\00\ff\d7\8d\00nj\e2\00\b0\fd\c6\00\93\08\c1\00|]t\00k\ad\b2\00\cdn\9d\00>r{\00\c6\11j\00\f7\cf\a9\00)s\df\00\b5\c9\ba\00\b7\00Q\00\e2\b2\0d\00t\ba$\00\e5}`\00t\d8\8a\00\0d\15,\00\81\18\0c\00~f\94\00\01)\16\00\9fzv\00\fd\fd\be\00VE\ef\00\d9~6\00\ec\d9\13\00\8b\ba\b9\00\c4\97\fc\001\a8'\00\f1n\c3\00\94\c56\00\d8\a8V\00\b4\a8\b5\00\cf\cc\0e\00\12\89-\00oW4\00,V\89\00\99\ce\e3\00\d6 \b9\00k^\aa\00>*\9c\00\11_\cc\00\fd\0bJ\00\e1\f4\fb\00\8e;m\00\e2\86,\00\e9\d4\84\00\fc\b4\a9\00\ef\ee\d1\00.5\c9\00/9a\008!D\00\1b\d9\c8\00\81\fc\0a\00\fbJj\00/\1c\d8\00S\b4\84\00N\99\8c\00T\22\cc\00*U\dc\00\c0\c6\d6\00\0b\19\96\00\1ap\b8\00i\95d\00&Z`\00?R\ee\00\7f\11\0f\00\f4\b5\11\00\fc\cb\f5\004\bc-\004\bc\ee\00\e8]\cc\00\dd^`\00g\8e\9b\00\923\ef\00\c9\17\b8\00aX\9b\00\e1W\bc\00Q\83\c6\00\d8>\10\00\ddqH\00-\1c\dd\00\af\18\a1\00!,F\00Y\f3\d7\00\d9z\98\00\9eT\c0\00O\86\fa\00V\06\fc\00\e5y\ae\00\89\226\008\ad\22\00g\93\dc\00U\e8\aa\00\82&8\00\ca\e7\9b\00Q\0d\a4\00\993\b1\00\a9\d7\0e\00i\05H\00e\b2\f0\00\7f\88\a7\00\88L\97\00\f9\d16\00!\92\b3\00{\82J\00\98\cf!\00@\9f\dc\00\dcGU\00\e1t:\00g\ebB\00\fe\9d\df\00^\d4_\00{g\a4\00\ba\acz\00U\f6\a2\00+\88#\00A\baU\00Yn\08\00!*\86\009G\83\00\89\e3\e6\00\e5\9e\d4\00I\fb@\00\ffV\e9\00\1c\0f\ca\00\c5Y\8a\00\94\fa+\00\d3\c1\c5\00\0f\c5\cf\00\dbZ\ae\00G\c5\86\00\85Cb\00!\86;\00,y\94\00\10a\87\00*L{\00\80,\1a\00C\bf\12\00\88&\90\00x<\89\00\a8\c4\e4\00\e5\db{\00\c4:\c2\00&\f4\ea\00\f7g\8a\00\0d\92\bf\00e\a3+\00=\93\b1\00\bd|\0b\00\a4Q\dc\00'\ddc\00i\e1\dd\00\9a\94\19\00\a8)\95\00h\ce(\00\09\ed\b4\00D\9f \00N\98\ca\00p\82c\00~|#\00\0f\b92\00\a7\f5\8e\00\14V\e7\00!\f1\08\00\b5\9d*\00o~M\00\a5\19Q\00\b5\f9\ab\00\82\df\d6\00\96\dda\00\166\02\00\c4:\9f\00\83\a2\a1\00r\edm\009\8dz\00\82\b8\a9\00k2\5c\00F'[\00\004\ed\00\d2\00w\00\fc\f4U\00\01YM\00\e0q\80")
(data $.rodata.51 (;51;) (i64.const 303027) "@\fb!\f9?\00\00\00\00-Dt>\00\00\00\80\98F\f8<\00\00\00`Q\ccx;\00\00\00\80\83\1b\f09\00\00\00@ %z8\00\00\00\80\22\82\e36\00\00\00\00\1d\f3i5\fe\82+eG\15g@\00\00\00\00\00\008C\00\00\fa\feB.v\bf:;\9e\bc\9a\f7\0c\bd\bd\fd\ff\ff\ff\ff\df?<TUUUU\c5?\91+\17\cfUU\a5?\17\d0\a4g\11\11\81?\00\00\00\00\00\00\c8B\ef9\fa\feB.\e6?$\c4\82\ff\bd\bf\ce?\b5\f4\0c\d7\08k\ac?\ccPF\d2\ab\b2\83?\84:N\9b\e0\d7U?")
(data $.rodata.52 (;52;) (i64.const 303214) "\f0?n\bf\88\1aO;\9b<53\fb\a9=\f6\ef?]\dc\d8\9c\13`q\bca\80w>\9a\ec\ef?\d1f\87\10z^\90\bc\85\7fn\e8\15\e3\ef?\13\f6g5R\d2\8c<t\85\15\d3\b0\d9\ef?\fa\8e\f9#\80\ce\8b\bc\de\f6\dd)k\d0\ef?a\c8\e6aN\f7`<\c8\9bu\18E\c7\ef?\99\d33[\e4\a3\90<\83\f3\c6\ca>\be\ef?m{\83]\a6\9a\97<\0f\89\f9lX\b5\ef?\fc\ef\fd\92\1a\b5\8e<\f7Gr+\92\ac\ef?\d1\9c/p=\be><\a2\d1\d32\ec\a3\ef?\0bn\90\894\03j\bc\1b\d3\fe\aff\9b\ef?\0e\bd/*RV\95\bcQ[\12\d0\01\93\ef?U\eaN\8c\ef\80P\bc\cc1l\c0\bd\8a\ef?\16\f4\d5\b9#\c9\91\bc\e0-\a9\ae\9a\82\ef?\afU\5c\e9\e3\d3\80<Q\8e\a5\c8\98z\ef?H\93\a5\ea\15\1b\80\bc{Q}<\b8r\ef?=2\deU\f0\1f\8f\bc\ea\8d\8c8\f9j\ef?\bfS\13?\8c\89\8b<u\cbo\eb[c\ef?&\eb\11v\9c\d9\96\bc\d4\5c\04\84\e0[\ef?`/:>\f7\ec\9a<\aa\b9h1\87T\ef?\9d8\86\cb\82\e7\8f\bc\1d\d9\fc\22PM\ef?\8d\c3\a6DAo\8a<\d6\8cb\88;F\ef?}\04\e4\b0\05z\80<\96\dc}\91I?\ef?\94\a8\a8\e3\fd\8e\96<8bunz8\ef?}Ht\f2\18^\87<?\a6\b2O\ce1\ef?\f2\e7\1f\98+G\80<\dd|\e2eE+\ef?^\08q?{\b8\96\bc\81c\f5\e1\df$\ef?1\ab\09m\e1\f7\82<\e1\de\1f\f5\9d\1e\ef?\fa\bfo\1a\9b!=\bc\90\d9\da\d0\7f\18\ef?\b4\0a\0cr\827\8b<\0b\03\e4\a6\85\12\ef?\8f\cb\ce\89\92\14n<V/>\a9\af\0c\ef?\b6\ab\b0MuM\83<\15\b71\0a\fe\06\ef?Lt\ac\e2\01B\86<1\d8L\fcp\01\ef?J\f8\d3]9\dd\8f<\ff\16d\b2\08\fc\ee?\04[\8e;\80\a3\86\bc\f1\9f\92_\c5\f6\ee?hPK\cc\edJ\92\bc\cb\a9:7\a7\f1\ee?\8e-Q\1b\f8\07\99\bcf\d8\05m\ae\ec\ee?\d26\94>\e8\d1q\bc\f7\9f\e54\db\e7\ee?\15\1b\ce\b3\19\19\99\bc\e5\a8\13\c3-\e3\ee?mL*\a7H\9f\85<\224\12L\a6\de\ee?\8ai(z`\12\93\bc\1c\80\ac\04E\da\ee?[\89\17H\8f\a7X\bc*.\f7!\0a\d6\ee?\1b\9aIg\9b,|\bc\97\a8P\d9\f5\d1\ee?\11\ac\c2`\edcC<-\89a`\08\ce\ee?\efd\06;\09f\96<W\00\1d\edA\ca\ee?y\03\a1\da\e1\ccn<\d0<\c1\b5\a2\c6\ee?0\12\0f?\8e\ff\93<\de\d3\d7\f0*\c3\ee?\b0\afz\bb\ce\90v<'*6\d5\da\bf\ee?w\e0T\eb\bd\1d\93<\0d\dd\fd\99\b2\bc\ee?\8e\a3q\004\94\8f\bc\a7,\9dv\b2\b9\ee?I\a3\93\dc\cc\de\87\bcBf\cf\a2\da\b6\ee?_8\0f\bd\c6\dex\bc\82O\9dV+\b4\ee?\f6\5c{\ecF\12\86\bc\0f\92]\ca\a4\b1\ee?\8e\d7\fd\18\055\93<\da'\b56G\af\ee?\05\9b\8a/\b7\98{<\fd\c7\97\d4\12\ad\ee?\09T\1c\e2\e1c\90<)TH\dd\07\ab\ee?\ea\c6\19P\85\c74<\b7FY\8a&\a9\ee?5\c0d+\e62\94<H!\ad\15o\a7\ee?\9fv\99aJ\e4\8c\bc\09\dcv\b9\e1\a5\ee?\a8M\ef;\c53\8c\bc\85U:\b0~\a4\ee?\ae\e9+\89xS\84\bc \c3\cc4F\a3\ee?XXVx\dd\ce\93\bc%\22U\828\a2\ee?d\19~\80\aa\10W<s\a9L\d4U\a1\ee?(\22^\bf\ef\b3\93\bc\cd;\7ff\9e\a0\ee?\82\b94\87\ad\12j\bc\bf\da\0bu\12\a0\ee?\ee\a9m\b8\efgc\bc/\1ae<\b2\9f\ee?Q\88\e0T=\dc\80\bc\84\94Q\f9}\9f\ee?\cf>Z~d\1fx\bct_\ec\e8u\9f\ee?\b0}\8b\c0J\ee\86\bct\81\a5H\9a\9f\ee?\8a\e6U\1e2\19\86\bc\c9gBV\eb\9f\ee?\d3\d4\09^\cb\9c\90<?]\deOi\a0\ee?\1d\a5M\b9\dc2{\bc\87\01\ebs\14\a1\ee?k\c0gT\fd\ec\94<2\c10\01\ed\a1\ee?Ul\d6\ab\e1\ebe<bN\cf6\f3\a2\ee?B\cf\b3/\c5\a1\88\bc\12\1a>T'\a4\ee?47;\f1\b6i\93\bc\13\ceL\99\89\a5\ee?\1e\ff\19:\84^\80\bc\ad\c7#F\1a\a7\ee?nWr\d8P\d4\94\bc\ed\92D\9b\d9\a8\ee?\00\8a\0e[g\ad\90<\99f\8a\d9\c7\aa\ee?\b4\ea\f0\c1/\b7\8d<\db\a0*B\e5\ac\ee?\ff\e7\c5\9c`\b6e\bc\8cD\b5\162\af\ee?D_\f3Y\83\f6{<6w\15\99\ae\b1\ee?\83=\1e\a7\1f\09\93\bc\c6\ff\91\0b[\b4\ee?)\1el\8b\b8\a9]\bc\e5\c5\cd\b07\b7\ee?Y\b9\90|\f9#l\bc\0fR\c8\cbD\ba\ee?\aa\f9\f4\22CC\92\bcPN\de\9f\82\bd\ee?K\8ef\d7l\ca\85\bc\ba\07\cap\f1\c0\ee?'\ce\91+\fc\afq<\90\f0\a3\82\91\c4\ee?\bbs\0a\e15\d2m<##\e3\19c\c8\ee?c\22b\22\04\c5\87\bce\e5]{f\cc\ee?\d51\e2\e3\86\1c\8b<3-J\ec\9b\d0\ee?\15\bb\bc\d3\d1\bb\91\bc]%>\b2\03\d5\ee?\d21\ee\9c1\cc\90<X\b30\13\9e\d9\ee?\b3Zsn\84i\84<\bf\fdyUk\de\ee?\b4\9d\8e\97\cd\df\82\bcz\f3\d3\bfk\e3\ee?\873\cb\92w\1a\8c<\ad\d3Z\99\9f\e8\ee?\fa\d9\d1J\8f{\90\bcf\b6\8d)\07\ee\ee?\ba\ae\dcV\d9\c3U\bc\fb\15O\b8\a2\f3\ee?@\f6\a6=\0e\a4\90\bc:Y\e5\8dr\f9\ee?4\93\ad8\f4\d6h\bcG^\fb\f2v\ff\ee?5\8aXk\e2\ee\91\bcJ\06\a10\b0\05\ef?\cd\dd_\0a\d7\fft<\d2\c1K\90\1e\0c\ef?\ac\98\92\fa\fb\bd\91\bc\09\1e\d7[\c2\12\ef?\b3\0c\af0\aens<\9cR\85\dd\9b\19\ef?\94\fd\9f\5c2\e3\8e<z\d0\ff_\ab \ef?\acY\09\d1\8f\e0\84<K\d1W.\f1'\ef?g\1aN8\af\cdc<\b5\e7\06\94m/\ef?h\19\92l,kg<i\90\ef\dc 7\ef?\d2\b5\cc\83\18\8a\80\bc\fa\c3]U\0b?\ef?o\fa\ff?]\ad\8f\bc|\89\07J-G\ef?I\a9u8\ae\0d\90\bc\f2\89\0d\08\87O\ef?\a7\07=\a6\85\a3t<\87\a4\fb\dc\18X\ef?\0f\22@ \9e\91\82\bc\98\83\c9\16\e3`\ef?\ac\92\c1\d5PZ\8e<\852\db\03\e6i\ef?Kk\01\acY:\84<`\b4\01\f3!s\ef?\1f>\b4\07!\d5\82\bc_\9b{3\97|\ef?\c9\0dG;\b9*\89\bc)\a1\f5\14F\86\ef?\d3\88:`\04\b6t<\f6?\8b\e7.\90\ef?qr\9dQ\ec\c5\83<\83L\c7\fbQ\9a\ef?\f0\91\d3\8f\12\f7\8f\bc\da\90\a4\a2\af\a4\ef?}t#\e2\98\ae\8d\bc\f1g\8e-H\af\ef?\08 \aaA\bc\c3\8e<'Za\ee\1b\ba\ef?2\eb\a9\c3\94+\84<\97\bak7+\c5\ef?\ee\85\d11\a9d\8a<@En[v\d0\ef?\ed\e3;\e4\ba7\8e\bc\14\be\9c\ad\fd\db\ef?\9d\cd\91M;\89w<\d8\90\9e\81\c1\e7\ef?\89\cc`A\c1\05S<\f1q\8f+\c2\f3\ef?\95 \00\00\00\00\00\00\8f&\00\00\00\00\00\00\8f&\00\00\00\00\00\00\8f&\00\00\00\00\00\00\8f&\00\00\00\00\00\00\8f&\00\00\00\00\00\00\8f&\00\00\00\00\00\00\8f&\00\00\00\00\00\00\8f&\00\00\00\00\00\00\8f&\00\00\00\00\00\00\7f\7f\7f\7f\7f\7f\7f\7f\7f\7f\7f\7f\7f\7f\00\00\00\00 eG\15\f7?\00\a2\ef.\fc\05\e7=9\83+eG\15\e7\bf\be\04:\dc\09\c7\de?\fb/pdG\15\d7\bfHL\03Plw\d2?\bc\92\ea(\b3\c7\ce\bf.\f9\17\e1%b\ca?\fe\82+eG\15\e7\bf\f7\03:\dc\09\c7\de??|+eG\15\d7\bf\e4[\f0Plw\d2?\e5\8fv\dd\09\c7\ce\bf6\e7\c4\1eva\ca?\9b\a7d\bc?\15\c7\bfJ\1b\f0T\d1\84\c4?<8,\a7\e4\89\c2\bff\eeZ(/\b3\c0?\f8\ac\b1k($\f7?\00\b0\cd\ee_\09\e1\bf\a1\cc\d2f\f7\e1\f6?\00\d0v\bd\94\84\e0\bf\8a\d40\0e=\a1\f6?\00\f8\e8\aeC\01\e0\bf\85l\d02\eca\f6?\00@\0b6\c5\fe\de\bf\f8\98\11\95\fa#\f6?\00\e0\b7\1a\d9\fd\dd\bfl\02\cf\a4[\e7\f5?\00\90\c7\0c\ae\ff\dc\bf\b8O!Z\05\ac\f5?\00\a0\fd\118\04\dc\bf\1en\16\0f\edq\f5?\00\e0:2g\0b\db\bf5\f8\0bY\099\f5?\00\b0-Z/\15\da\bf\dd\ada\edO\01\f5?\00`\f8Z\7f!\d9\bf\d0{H\8e\b8\ca\f4?\00\90q\b0M0\d8\bf\eeO3\b49\95\f4?\00\e0\a9\f9\89A\d7\bfi\d5\af\df\cb`\f4?\00\90\19\b5+U\d6\bfS\b9\e4Nf-\f4?\00\10\9b\a2#k\d5\bf\a6\d8\1d\11\01\fb\f3?\00\a0_\0fe\83\d4\bf6X\0c\b7\95\c9\f3?\00\a0\f67\e9\9d\d3\bfJ\fd\b6J\1c\99\f3?\00`\8dS\a1\ba\d2\bf\b5\99\e0\0c\8ei\f3?\00@\ca@\83\d9\d1\bf\b2\e7\13\82\e4:\f3?\00\e0@:\85\fa\d0\bf\b1\bd\85\19\19\0d\f3?\000\e72\9c\1d\d0\bf\d7q\b2\ca%\e0\f2?\00`\fa\a2}\85\ce\bf\82\cd\13\cf\04\b4\f2?\00\80=c\c8\d3\cc\bfP\cb|,\b0\88\f2?\00\a0\14L\03&\cb\bf\e5M\94c\22^\f2?\00\e0O/\1c|\c9\bf\b1\15\86=V4\f2?\00\00\80?\02\d6\c7\bf8\af>\e3F\0b\f2?\00\e0\05\1a\a73\c6\bf\dd\a3\cd\fd\ee\e2\f1?\00\00W\e9\f5\94\c4\bf09\0bXJ\bb\f1?\00\a0\e0$\e4\f9\c2\bf\00\22\7f\84S\94\f1?\00\c0\fdZYb\c1\bf<\d7\d5\c0\06n\f1?\00\80\bdu\9a\9c\bf\bf\c2\e4\b7G_H\f1?\00\c0\f9[W{\bc\bf\d1\85\00\adX#\f1?\00\80\f4\0f\c6`\b9\bf'\22S\0f\f0\fe\f0?\00\00\b6G\e2L\b6\bf\8f:\d0w \db\f0?\00@\01\b2x?\b3\bf\d9\80Y\d6\e6\b7\f0?\00\c0B\1a}8\b0\bf\8d@{\fe>\95\f0?\00\00\b5\08\92o\aa\bf\83;\c5\ca%s\f0?\00\00wO\95z\a4\bf\5c\1b\0d\e4\97Q\f0?\00\00\0c\c5\a8#\9d\bf\a2\8e \c1\910\f0?\00\00x)&j\91\bf!~\b3%\10\10\f0?\00\00\e8\d8\f8 w\bfk\a7\ca\f9~\c0\ef?\00\00P\b1S\fe\86?\84\f1\f6\d3eD\ef?\00\80\0f\e1\cc\1c\a1?\7f\10\84\9f\07\cc\ee?\00\80\8b\8c\fcM\ac?\e8Z\97\99:W\ee?\00@W\1e2\aa\b3?\e6=\bd\f0\d6\e5\ed?\00\80\8b\d0\a0\18\b9?\b38\ff\81\b6w\ed?\00@\04\da\e9r\be?C\e9Mr\b5\0c\ed?\00`\7fP\d2\dc\c1?cu\0e\dc\b2\a4\ec?\00\a0\de\03\abv\c4?Q\cb\d6\e8\8e?\ec?\00 \e2wC\07\c7?L\0c\02O+\dd\eb?\00@\a9\8b\de\8e\c9?\ca\15`\00l}\eb?\00\e0\d2j\b8\0d\cc?\8f3.n6 \eb?\00\e0\ce\af\0a\84\ce?9P)&p\c5\ea?\00\80g\b4\0ay\d0?\dd1'\bc\01m\ea?\00\c0\01h\05\ac\d1?\8b\f1?\bc\d3\16\ea?\00\e0\fe\d4\11\db\d2?\ad\fegI\d1\c2\e9?\00\80\c5NF\06\d4?\02\99|\f4\e4p\e9?\00\f0:\09\be-\d5?\f2\bc\829\fb \e9?\00\d0P \90Q\d6?\f1Y\f7\87\01\d3\e8?\00\f0\ea\cd\d2q\d7?m\f6\b9\eb\e5\86\e8?\00\90}\85\9c\8e\d8?\94\b9X\b6\97<\e8?\00`\e1U\01\a8\d9?\22\10\c6\ff\05\f4\e7?\00\d0\d3n\18\be\da?\ca\15\14\18\22\ad\e7?\00\e0\a0\ae\f2\d0\db?\8c\ff\9e\f9\dcg\e7?\00@\bf=\a4\e0\dc?\8e\0a\b9\12\00 \e6?\05\b6D\06\ab\04\89<\a64W\04\00`\e6?\a9\f7b\ea\9b\ffa<\c5\f2%\c3\ff\9f\e6?\ba\90<\cb\cf~\82<\04Z\b98\00\e0\e6?&\93sV\88\ff\88<\e3\94\99\e0\ff\1f\e7?\b1\82_'@\fd\8a<\10\0eY\15\00`\e7?A\83#\b4u\fdr\bc\d5[e\12\00\a0\e7?v+$|\e6\08x<\a6\e9Y2\00\e0\e7?\b7\22\f6&\e4\08b\bc\d2\b2\b4\ed\ff\1f\e8?/\c9\a5\1eF\02\84\bc\c3\fc\fa-\00`\e8?\1f\9a\f2\a2\f4\f7m<Pk\8c\f7\ff\9f\e8?\fd\95I\09S\04\8e\bcf\15g9\00\e0\e8?E{\c7\be\f3\04\8a\bcE\17\bf\e2\ff\1f\e9?< \0e@4\faw\bc\d1\9f\5c\cc\ff_\e9?]i\a0\05\80\ffv\bcgG\ba;\00\a0\e9?\03~\ec\c4\c4\f8p<\a5-\b9\e7\ff\df\e9?\02F\8cG\d9\7f\8e<\af\fd.\d7\ff\1f\ea?~\ae\cdMU\0cj\bc\95\ff\04\de\ff_\ea?k\b2\e9\8c\a9}\86<+\8d^\ca\ff\9f\ea?\de\13L\b5\c9\84\82\bc\ea\03\ad\dd\ff\df\ea?<.`\ea\c8\12X<M=\0d\f1\ff\1f\eb?\9cx'\ad\dd\fa\8e\bcZ\16!\ce\ff_\eb?7\12\c6\19\17\cbS<t\e6P\d9\ff\9f\eb?\00\ce\94A\d9\f7s<\af\a8\9c\13\00\e0\eb?\c0\9b]!\c4\0au<\99\dfF[\00 \ec?\c9\c1\e9S\a6\eek<\ae\f7\b9@\00`\ec?\d6pJ'\9f\07|\bc\8a\fdUb\00\a0\ec?\1fL\e8v@\0bz\bc]\09L\d9\ff\df\ec?\d7\b5\9a\f93\f9\88<\cf\d6u\f9\ff\1f\ed?\be\e1_f\08,X\bc\93\1cV\a2\ff_\ed?\f3\95\d2\9b(\04{\bc\0c\8b\22\9d\ff\9f\ed?6\a2\0f4Q\02\87<\16~\bce\00\e0\ed?\0c\d8\a4\16\1e\01u\bc\91G\f6\02\00 \ee?\e0b\ef\09/\80\89<\d8\a6\d7W\00`\ee?\fa\f7\0cXu\0b~\bc\0c\c0\ed'\00\a0\ee?\11\98E\09\83\84\8c\bc|\cb\f5l\00\e0\ee?\f4v\15\95'\80\8f\bc\cc}+x\00 \ef?\8fStr\d9\81\8f\bc\0aE\0c&\00`\ef?\dc\ff''\00q@\bc3\d5\8c\e8\ff\9f\ef?\b0\a8\fd\e1\dc\1bX\bc\89\86\0f\d5\ff\df\ef?n\8e\91\cb\1a\f9\87<g#)\04\00 \f0?\81F2e\f3\7f\9b<h\d6\e3\e3\ff_\f0?{\95\ae\dd\08\fa\86<W\a7\85\0a\00\a0\f0?\91\fb\d3\80\de\e2W\bc\cc?_\1a\00\e0\f0?\14\f0\c5\053\82\91\bc\f5\ba\af\f8\ff\1f\f1?\c2\ba\80f\bb\fa\8b\bc\ad\91M\e5\ff_\f1?\ef\e77\17\12\7f\9d\bc\e16\ac\11\00\a0\f1?\ff\f5\16\05\0a\00\9c<HB\c8\19\00\e0\f1?\a0]\da\e4\fb\82\90\bcn^\fe\0f\00 \f2?C\fb\9cL\d0\fd\88\bc\91\d8\9f&\00`\f2?\82\d1\94y*\fe\8c<\da\e6\a6)\00\a0\f2?\c5\8b^qs\02p\bc9>)\e0\ff\df\f2?\f9\a6\b2\da9|\9b<\82\f0\dc\f7\ff\1f\f3?TR\dcn3\f1}<`\8bZ\f0\ff_\f3?\eb1\cdLV\03\9e\bc\cc\ae\0e.\00\a0\f3?w\a4\d3K\e7\f0u<6\b2;\04\00\e0\f3?3\88\9d\14\cb}\9c<\ff\87\d1\02\00 \f4?(=-\cf\af\08~<\b1|8\0d\00`\f4?\a6\99e\857\08\82<\89\9fV\04\00\a0\f4?\d2\bcO\90\5c\fa\89\bc\f3C5\04\00\e0\f4?)S\17\ed%\11x\bc\0f\7f\02\cc\ff\1f\f5?\dcTw\84\d8\83\98<o\b3\87\fd\ff_\f5?\07(\d01\e7\09\87\bc\ba\f7\1d\f2\ff\9f\f5?\02{rh\9f\f7\87<\814\fc\eb\ff\df\f5?>\e90.\90\80\91\bc\008\fa\feB.\e6?0g\c7\93W\f3.=\01\00\00\00\00\00\e0\bf[0QUUU\d5?\90E\eb\ff\ff\ff\cf\bf\11\01\f1$\b3\99\c9?\9f\c8\06\e5uU\c5\bf\00\00\00\00\00\00\e0\bfwUUUUU\d5?\cb\fd\ff\ff\ff\ff\cf\bf\0c\dd\95\99\99\99\c9?\a7EgUUU\c5\bf0\deD\a3$I\c2?e=B\a4\ff\ff\bf\bf\ca\d6*(\84q\bc?\ffh\b0C\eb\99\b9\bf\85\d0\af\f7\82\81\b7?\cdE\d1u\13R\b5\bf\9f\de\e0\c3\f04\f7?\00\90\e6y\7f\cc\d7\bf\1f\e9,jx\13\f7?\00\00\0d\c2\eeo\d7\bf\a0\b5\fa\08`\f2\f6?\00\e0Q\13\e3\13\d7\bf}\8c\13\1f\a6\d1\f6?\00x(8[\b8\d6\bf\d1\b4\c5\0bI\b1\f6?\00x\80\90U]\d6\bf\ba\0c/3G\91\f6?\00\00\18v\d0\02\d6\bf#B\22\18\9fq\f6?\00\90\90\86\ca\a8\d5\bf\d9\1e\a5\99OR\f6?\00P\03VCO\d5\bf\c4$\8f\aaV3\f6?\00@k\c37\f6\d4\bf\14\dc\9dk\b3\14\f6?\00P\a8\fd\a7\9d\d4\bfL\5c\c6Rd\f6\f5?\00\a8\899\92E\d4\bfO,\91\b5g\d8\f5?\00\b8\b09\f4\ed\d3\bf\de\90[\cb\bc\ba\f5?\00p\8fD\ce\96\d3\bfx\1a\d9\f2a\9d\f5?\00\a0\bd\17\1e@\d3\bf\87VF\12V\80\f5?\00\80F\ef\e2\e9\d2\bf\d3k\e7\ce\97c\f5?\00\e008\1b\94\d2\bf\93\7f\a7\e2%G\f5?\00\88\da\8c\c5>\d2\bf\83E\06B\ff*\f5?\00\90')\e1\e9\d1\bf\df\bd\b2\db\22\0f\f5?\00\f8H+m\95\d1\bf\d7\de4G\8f\f3\f4?\00\f8\b9\9agA\d1\bf@(\de\cfC\d8\f4?\00\98\ef\94\d0\ed\d0\bf\c8\a3x\c0>\bd\f4?\00\10\db\18\a5\9a\d0\bf\8a%\e0\c3\7f\a2\f4?\00\b8cR\e6G\d0\bf4\84\d4$\05\88\f4?\00\f0\86E\22\eb\cf\bf\0b-\19\1b\cem\f4?\00\b0\17uJG\cf\bfT\189\d3\d9S\f4?\000\10=D\a4\ce\bfZ\84\b4D':\f4?\00\b0\e9D\0d\02\ce\bf\fb\f8\15A\b5 \f4?\00\f0w)\a2`\cd\bf\b1\f4>\da\82\07\f4?\00\90\95\04\01\c0\cc\bf\8f\feW]\8f\ee\f3?\00\10\89V) \cc\bf\e9L\0b\a0\d9\d5\f3?\00\10\81\8d\17\81\cb\bf+\c1\10\c0`\bd\f3?\00\d0\d3\cc\c9\e2\ca\bf\b8\dau+$\a5\f3?\00\90\12.@E\ca\bf\02\d0\9f\cd\22\8d\f3?\00\f0\1dhw\a8\c9\bf\1cz\84\c5[u\f3?\000Him\0c\c9\bf\e26\adI\ce]\f3?\00\c0E\a6 q\c8\bf@\d4M\98yF\f3?\000\14\b4\8f\d6\c7\bf$\cb\ff\ce\5c/\f3?\00pb<\b8<\c7\bfI\0d\a1uw\18\f3?\00`7\9b\9a\a3\c6\bf\909>7\c8\01\f3?\00\a0\b7T1\0b\c6\bfA\f8\95\bbN\eb\f2?\000$v}s\c5\bf\d1\a9\19\02\0a\d5\f2?\000\c2\8f{\dc\c4\bf*\fd\b7\a8\f9\be\f2?\00\00\d2Q,F\c4\bf\ab\1b\0cz\1c\a9\f2?\00\00\83\bc\8a\b0\c3\bf0\b5\14`r\93\f2?\00\00Ik\99\1b\c3\bf\f5\a1WW\fa}\f2?\00@\a4\90T\87\c2\bf\bf;\1d\9b\b3h\f2?\00\a0y\f8\b9\f3\c1\bf\bd\f5\8f\83\9dS\f2?\00\a0,%\c8`\c1\bf;\08\c9\aa\b7>\f2?\00 \f7W\7f\ce\c0\bf\b6@\a9+\01*\f2?\00\a0\feI\dc<\c0\bf2A\cc\96y\15\f2?\00\80K\bc\bdW\bf\bf\9b\fc\d2\1d \01\f2?\00@@\96\087\be\bf\0bHMI\f4\ec\f1?\00@\f9>\98\17\bd\bfie\8fR\f5\d8\f1?\00\a0\d8Ng\f9\bb\bf|~W\11#\c5\f1?\00`/ y\dc\ba\bf\e9&\cbt|\b1\f1?\00\80(\e7\c3\c0\b9\bf\b6\1a,\0c\01\9e\f1?\00\c0r\b3F\a6\b8\bf\bdp\b6{\b0\8a\f1?\00\00\ac\b3\01\8d\b7\bf\b6\bc\ef%\8aw\f1?\00\008E\f1t\b6\bf\da1L5\8dd\f1?\00\80\87m\0e^\b5\bf\dd_'\90\b9Q\f1?\00\e0\a1\de\5cH\b4\bfL\d22\a4\0e?\f1?\00\a0jM\d93\b3\bf\da\f9\10r\8b,\f1?\00`\c5\f8y \b2\bf1\b5\ec(0\1a\f1?\00 b\98F\0e\b1\bf\af4\84\da\fb\07\f1?\00\00\d2jl\fa\af\bf\b3kN\0f\ee\f5\f0?\00@wJ\8d\da\ad\bf\ce\9f*]\06\e4\f0?\00\00\85\e4\ec\bc\ab\bf!\a5,cD\d2\f0?\00\c0\12@\89\a1\a9\bf\1a\98\e2|\a7\c0\f0?\00\c0\023X\88\a7\bf\d16\c6\83/\af\f0?\00\80\d6g^q\a5\bf9\13\a0\98\db\9d\f0?\00\80eI\8a\5c\a3\bf\df\e7R\af\ab\8c\f0?\00@\15d\e3I\a1\bf\fb(N/\9f{\f0?\00\80\eb\82\c0r\9e\bf\19\8f5\8c\b5j\f0?\00\80RR\f1U\9a\bf,\f9\ec\a5\eeY\f0?\00\80\81\cfb=\96\bf\90,\d1\cdII\f0?\00\00\aa\8c\fb(\92\bf\a9\ad\f0\c6\c68\f0?\00\00\f9 {1\8c\bf\a92y\13e(\f0?\00\00\aa]5\19\84\bfHs\ea'$\18\f0?\00\00\ec\c2\03\12x\bf\95\b1\14\06\04\08\f0?\00\00$y\09\04`\bf\1a\fa&\f7\1f\e0\ef?\00\00\90\84\f3\efo?t\eaa\c2\1c\a1\ef?\00\00=5A\dc\87?.\99\81\b0\10c\ef?\00\80\c2\c4\a3\ce\93?\cd\ad\ee<\f6%\ef?\00\00\89\14\c1\9f\9b?\e7\13\91\03\c8\e9\ee?\00\00\11\ce\d8\b0\a1?\ab\b1\cbx\80\ae\ee?\00\c0\01\d0[\8a\a5?\9b\0c\9d\a2\1at\ee?\00\80\d8@\83\5c\a9?\b5\99\0a\83\91:\ee?\00\80W\efj'\ad?V\9a`\09\e0\01\ee?\00\c0\98\e5\98u\b0?\98\bbw\e5\01\ca\ed?\00 \0d\e3\f5S\b2?\03\91|\0b\f2\92\ed?\00\008\8b\dd.\b4?\ce\5c\fbf\ac\5c\ed?\00\c0W\87Y\06\b6?\9d\de^\aa,'\ed?\00\00j5v\da\b7?\cd,k>n\f2\ec?\00`\1cNC\ab\b9?\02y\a7\a2m\be\ec?\00`\0d\bb\c7x\bb?m\087m&\8b\ec?\00 \e72\13C\bd?\04X]\bd\94X\ec?\00`\deq1\0a\bf?\8c\9f\bb3\b5&\ec?\00@\91+\15g\c0??\e7\ec\ee\83\f5\eb?\00\b0\92\82\85G\c1?\c1\96\dbu\fd\c4\eb?\000\ca\cdn&\c2?(J\86\0c\1e\95\eb?\00P\c5\a6\d7\03\c3?,>\ef\c5\e2e\eb?\00\103<\c3\df\c3?\8b\88\c9gH7\eb?\00\80zk6\ba\c4?J0\1d!K\09\eb?\00\f0\d1(9\93\c5?~\ef\f2\85\e8\db\ea?\00\f0\18$\cdj\c6?\a2=`1\1d\af\ea?\00\90f\ec\f8@\c7?\a7X\d3?\e6\82\ea?\00\f0\1a\f5\c0\15\c8?\8bs\09\ef@W\ea?\00\80\f6T)\e9\c8?'K\ab\90*,\ea?\00@\f8\026\bb\c9?\d1\f2\93\13\a0\01\ea?\00\00,\1c\ed\8b\ca?\1b<\db$\9f\d7\e9?\00\d0\01\5cQ[\cb?\90\b1\c7\05%\ae\e9?\00\c0\bc\ccg)\cc?/\ce\97\f2.\85\e9?\00`H\d55\f6\cc?uK\a4\ee\ba\5c\e9?\00\c0F4\bd\c1\cd?8H\e7\9d\c64\e9?\00\e0\cf\b8\01\8c\ce?\e6Rg/O\0d\e9?\00\90\17\c0\09U\cf?\9d\d7\ff\8eR\e6\e8?\00\b8\1f\12l\0e\d0?|\00\cc\9f\ce\bf\e8?\00\d0\93\0e\b8q\d0?\0e\c3\be\da\c0\99\e8?\00p\86\9ek\d4\d0?\fb\17#\aa't\e8?\00\d0K3\876\d1?\08\9a\b3\ac\00O\e8?\00H#g\0d\98\d1?U>e\e8I*\e8?\00\80\cc\e0\ff\f8\d1?`\02\f4\95\01\06\e8?\00hc\d7_Y\d2?)\a3\e0c%\e2\e7?\00\a8\14\090\b9\d2?\ad\b5\dcw\b3\be\e7?\00`C\10r\18\d3?\c2%\97g\aa\9b\e7?\00\18\ecm&w\d3?W\06\17\f2\07y\e7?\000\af\fbO\d5\d3?\0c\13\d6\db\caV\e7?\00\e0/\e3\ee2\d4?k\b6O\01\00\10\e6?<[B\91l\02~<\95\b4M\03\000\e6?A]\00H\ea\bf\8d<x\d4\94\0d\00P\e6?\b7\a5\d6\86\a7\7f\8e<\adoN\07\00p\e6?L%Tk\ea\fca<\ae\0f\df\fe\ff\8f\e6?\fd\0eYL'~|\bc\bc\c5c\07\00\b0\e6?\01\da\dcHh\c1\8a\bc\f6\c1\5c\1e\00\d0\e6?\11\93I\9d\1c?\83<>\f6\05\eb\ff\ef\e6?S-\e2\1a\04\80~\bc\80\97\86\0e\00\10\e7?Ry\09qf\ff{<\12\e9g\fc\ff/\e7?$\87\bd&\e2\00\8c<j\11\81\df\ffO\e7?\d2\01\f1n\91\02n\bc\90\9cg\0f\00p\e7?t\9cT\cdq\fcg\bc5\c8~\fa\ff\8f\e7?\83\04\f5\9e\c1\be\81<\e6\c2 \fe\ff\af\e7?ed\cc)\17~p\bc\00\c9?\ed\ff\cf\e7?\1c\8b{\08r\80\80\bcv\1a&\e9\ff\ef\e7?\ae\f9\9dm(\c0\8d<\e8\a3\9c\04\00\10\e8?3L\e5Q\d2\7f\89<\8f,\93\17\000\e8?\81\f30\b6\e9\fe\8a\bc\9cs3\06\00P\e8?\bc5ek\bf\bf\89<\c6\89B \00p\e8?u{\11\f3e\bf\8b\bc\04y\f5\eb\ff\8f\e8?W\cb=\a2n\00\89\bc\df\04\bc\22\00\b0\e8?\0aK\e08\df\00}\bc\8a\1b\0c\e5\ff\cf\e8?\05\9f\ffFq\00\88\bcC\8e\91\fc\ff\ef\e8?8pz\d0{\81\83<\c7_\fa\1e\00\10\e9?\03\b4\dfv\91>\89<\b9{F\13\000\e9?v\02\98KN\80\7f<o\07\ee\e6\ffO\e9?.b\ff\d9\f0~\8f\bc\d1\12<\de\ffo\e9?\ba8&\96\aa\82p\bc\0d\8aE\f4\ff\8f\e9?\ef\a8d\91\1b\80\87\bc>.\98\dd\ff\af\e9?7\93Z\8a\e0@\87\bcf\fbI\ed\ff\cf\e9?\00\e0\9b\c1\08\ce?<Q\9c\f1 \00\f0\e9?\0a[\88'\aa?\8a\bc\06\b0E\11\00\10\ea?V\daX\99H\fft<\fa\f6\bb\07\000\ea?\18m+\8a\ab\be\8c<y\1d\97\10\00P\ea?0yx\dd\ca\fe\88<H.\f5\1d\00p\ea?\db\ab\d8=vA\8f\bcR3Y\1c\00\90\ea?\12v\c2\84\02\bf\8e\bcK>O*\00\b0\ea?_?\ff<\04\fdi\bc\d1\1e\ae\d7\ff\cf\ea?\b4p\90\12\e7>\82\bcx\04Q\ee\ff\ef\ea?\a3\de\0e\e0>\06j<[\0de\db\ff\0f\eb?\b9\0a\1f8\c8\06Z<W\ca\aa\fe\ff/\eb?\1d<#t\1e\01y\bc\dc\ba\95\d9\ffO\eb?\9f*\86h\10\ffy\bc\9ce\9e$\00p\eb?>O\86\d0E\ff\8a<@\16\87\f9\ff\8f\eb?\f9\c3\c2\96w\fe|<O\cb\04\d2\ff\af\eb?\c4+\f2\ee'\ffc\bcE\5cA\d2\ff\cf\eb?!\ea;\ee\b7\ffl\bc\df\09c\f8\ff\ef\eb?\5c\0b.\97\03A\81\bcSv\b5\e1\ff\0f\ec?\19j\b7\94d\c1\8b<\e3W\fa\f1\ff/\ec?\ed\c60\8d\ef\fed\bc$\e4\bf\dc\ffO\ec?uG\ec\bch?\84\bc\f7\b9T\ed\ffo\ec?\ec\e0S\f0\a3~\84<\d5\8f\99\eb\ff\8f\ec?\f1\92\f9\8d\06\83s<\9a!%!\00\b0\ec?\04\0e\18d\8e\fdh\bc\9cF\94\dd\ff\cf\ec?r\ea\c7\1c\be~\8e<v\c4\fd\ea\ff\ef\ec?\fe\88\9f\ad9\be\8e<+\f8\9a\16\00\10\ed?qZ\b9\a8\91}u<\1d\f7\0f\0d\000\ed?\da\c7pi\90\c1\89<\c4\0fy\ea\ffO\ed?\0c\feX\c57\0eX\bc\e5\87\dc.\00p\ed?D\0f\c1M\d6\80\7f\bc\aa\82\dc!\00\90\ed?\5c\5c\fd\94\8f|t\bc\83\02k\d8\ff\af\ed?~a!\c5\1d\7f\8c<9Gl)\00\d0\ed?S\b1\ff\b2\9e\01\88<\f5\90D\e5\ff\ef\ed?\89\ccR\c6\d2\00n<\94\f6\ab\cd\ff\0f\ee?\d2i- @\83\7f\bc\dd\c8R\db\ff/\ee?d\08\1b\ca\c1\00{<\ef\16B\f2\ffO\ee?Q\ab\94\b0\a8\ffr<\11^\8a\e8\ffo\ee?Y\be\ef\b1s\f6W\bc\0d\ff\9e\11\00\90\ee?\01\c8\0b^\8d\80\84\bcD\17\a5\df\ff\af\ee?\b5 C\d5\06\00x<\a1\7f\12\1a\00\d0\ee?\92\5cV`\f8\02P\bc\c4\bc\ba\07\00\f0\ee?\11\e65]D@\85\bc\02\8dz\f5\ff\0f\ef?\05\91\ef91\fbO\bc\c7\8a\e5\1e\000\ef?U\11s\f2\ac\81\8a<\944\82\f5\ffO\ef?C\c7\d7\d4A?\8a<kL\a9\fc\ffo\ef?ux\98\1c\f4\02b\bcA\c4\f9\e1\ff\8f\ef?K\e7w\f4\d1}w<~\e3\e0\d2\ff\af\ef?1\a3|\9a\19\01o\bc\9e\e4w\1c\00\d0\ef?\b1\ac\ceK\ee\81q<1\c3\e0\f7\ff\ef\ef?Z\87p\017\05n\bcn`e\f4\ff\0f\f0?\da\0a\1cI\ad~\8a\bcXz\86\f3\ff/\f0?\e0\b2\fc\c3i\7f\97\bc\17\0d\fc\fd\ffO\f0?[\94\cb4\fe\bf\97<\82M\cd\03\00p\f0?\cbV\e4\c0\83\00\82<\e8\cb\f2\f9\ff\8f\f0?\1au7\be\df\ffm\bce\da\0c\01\00\b0\f0?\eb&\e6\ae\7f?\91\bc8\d3\a4\01\00\d0\f0?\f7\9fHy\fa}\80<\fd\fd\da\fa\ff\ef\f0?\c0k\d6p\05\04w\bc\96\fd\ba\0b\00\10\f1?b\0bm\84\d4\80\8e<]\f4\e5\fa\ff/\f1?\ef6\fdd\fa\bf\9d<\d9\9a\d5\0d\00P\f1?\aeP\12pw\00\9a<\9aU!\0f\00p\f1?\ee\de\e3\e2\f9\fd\8d<&T'\fc\ff\8f\f1?sr;\dc0\00\91<Y<=\12\00\b0\f1?\88\01\03\80y\7f\99<\b7\9e)\f8\ff\cf\f1?g\8c\9f\ab2\f9e\bc\00\d4\8a\f4\ff\ef\f1?\eb[\a7\9d\bf\7f\93<\a4\86\8b\0c\00\10\f2?\22[\fd\91k\80\9f<\03C\85\03\000\f2?3\bf\9f\eb\c2\ff\93<\84\f6\bc\ff\ffO\f2?r..~\e7\01v<\d9!)\f5\ffo\f2?a\0c\7fv\bb\fc\7f<<:\93\14\00\90\f2?+A\02<\ca\02r\bc\13cU\14\00\b0\f2?\02\1f\f23\82\80\92\bc;R\fe\eb\ff\cf\f2?\f2\dcO8~\ff\88\bc\96\ad\b8\0b\00\f0\f2?\c5A0PQ\ff\85\bc\af\e2z\fb\ff\0f\f3?\9d(^\88q\00\81\bc\7f_\ac\fe\ff/\f3?\15\b7\b7?]\ff\91\bcVg\a6\0c\00P\f3?\bd\82\8b\22\82\7f\95<!\f7\fb\11\00p\f3?\cc\d5\0d\c4\ba\00\80<\b9/Y\f9\ff\8f\f3?Q\a7\b2-\9d?\94\bcB\d2\dd\04\00\b0\f3?\e18vpk\7f\85<W\c9\b2\f5\ff\cf\f3?1\12\bf\10:\02z<\18\b4\b0\ea\ff\ef\f3?\b0R\b1fm\7f\98<\f4\af2\15\00\10\f4?$\85\19_7\f8g<)\8bG\17\000\f4?CQ\dcr\e6\01\83<c\b4\95\e7\ffO\f4?Z\89\b2\b8i\ff\89<\e0u\04\e8\ffo\f4?T\f2\c2\9b\b1\c0\95\bc\e7\c1o\ef\ff\8f\f4?r*:\f2\09@\9b<\04\a7\be\e5\ff\af\f4?E}\0d\bf\b7\ff\94\bc\de'\10\17\00\d0\f4?=j\dcqd\c0\99\bc\e2>\f0\0f\00\f0\f4?\1cS\85\0b\89\7f\97<\d1K\dc\12\00\10\f5?6\a4fqe\04`<z'\05\16\000\f5?\092#\ce\ce\bf\96\bcLp\db\ec\ffO\f5?\d7\a1\05\05r\02\89\bc\a9T_\ef\ffo\f5?\12d\c9\0e\e6\bf\9b<\12\10\e6\17\00\90\f5?\90\ef\af\81\c5~\88<\92>\c9\03\00\b0\f5?\c0\0c\bf\0a\08A\9f\bc\bc\19I\1d\00\d0\f5?)G%\fb*\81\98\bc\89z\b8\e7\ff\ef\f5?\04i\ed\80\b7~\94\bc\008\fa\feB.\e6?0g\c7\93W\f3.=\00\00\00\00\00\00\e0\bf`UUUUU\e5\bf\06\00\00\00\00\00\e0?NUY\99\99\99\e9?z\a4)UUU\e5\bf\e9EH\9b[I\f2\bf\c3?&\8b+\00\f0?\00\00\00\00\00\a0\f6?")
(data $.rodata.53 (;53;) (i64.const 311865) "\c8\b9\f2\82,\d6\bf\80V7($\b4\fa<\00\00\00\00\00\80\f6?")
(data $.rodata.54 (;54;) (i64.const 311897) "\08X\bf\bd\d1\d5\bf \f7\e0\d8\08\a5\1c\bd\00\00\00\00\00`\f6?")
(data $.rodata.55 (;55;) (i64.const 311929) "XE\17wv\d5\bfmP\b6\d5\a4b#\bd\00\00\00\00\00@\f6?")
(data $.rodata.56 (;56;) (i64.const 311961) "\f8-\87\ad\1a\d5\bf\d5g\b0\9e\e4\84\e6\bc\00\00\00\00\00 \f6?")
(data $.rodata.57 (;57;) (i64.const 311993) "xw\95_\be\d4\bf\e0>)\93i\1b\04\bd\00\00\00\00\00\00\f6?")
(data $.rodata.58 (;58;) (i64.const 312025) "`\1c\c2\8ba\d4\bf\cc\84LH/\d8\13=\00\00\00\00\00\e0\f5?")
(data $.rodata.59 (;59;) (i64.const 312057) "\a8\86\860\04\d4\bf:\0b\82\ed\f3B\dc<\00\00\00\00\00\c0\f5?")
(data $.rodata.60 (;60;) (i64.const 312089) "HiUL\a6\d3\bf`\94Q\86\c6\b1 =\00\00\00\00\00\a0\f5?")
(data $.rodata.61 (;61;) (i64.const 312121) "\80\98\9a\ddG\d3\bf\92\80\c5\d4MY%=\00\00\00\00\00\80\f5?")
(data $.rodata.62 (;62;) (i64.const 312153) " \e1\ba\e2\e8\d2\bf\d8+\b7\99\1e{&=\00\00\00\00\00`\f5?")
(data $.rodata.63 (;63;) (i64.const 312185) "\88\de\13Z\89\d2\bf?\b0\cf\b6\14\ca\15=\00\00\00\00\00`\f5?")
(data $.rodata.64 (;64;) (i64.const 312217) "\88\de\13Z\89\d2\bf?\b0\cf\b6\14\ca\15=\00\00\00\00\00@\f5?")
(data $.rodata.65 (;65;) (i64.const 312249) "x\cf\fbA)\d2\bfv\daS($Z\16\bd\00\00\00\00\00 \f5?")
(data $.rodata.66 (;66;) (i64.const 312281) "\98i\c1\98\c8\d1\bf\04T\e7h\bc\af\1f\bd\00\00\00\00\00\00\f5?")
(data $.rodata.67 (;67;) (i64.const 312313) "\a8\ab\ab\5cg\d1\bf\f0\a8\823\c6\1f\1f=\00\00\00\00\00\e0\f4?")
(data $.rodata.68 (;68;) (i64.const 312345) "H\ae\f9\8b\05\d1\bffZ\05\fd\c4\a8&\bd\00\00\00\00\00\c0\f4?")
(data $.rodata.69 (;69;) (i64.const 312377) "\90s\e2$\a3\d0\bf\0e\03\f4~\eek\0c\bd\00\00\00\00\00\a0\f4?")
(data $.rodata.70 (;70;) (i64.const 312409) "\d0\b4\94%@\d0\bf\7f-\f4\9e\b86\f0\bc\00\00\00\00\00\a0\f4?")
(data $.rodata.71 (;71;) (i64.const 312441) "\d0\b4\94%@\d0\bf\7f-\f4\9e\b86\f0\bc\00\00\00\00\00\80\f4?")
(data $.rodata.72 (;72;) (i64.const 312473) "@^m\18\b9\cf\bf\87<\99\ab*W\0d=\00\00\00\00\00`\f4?")
(data $.rodata.73 (;73;) (i64.const 312505) "`\dc\cb\ad\f0\ce\bf$\af\86\9c\b7&+=\00\00\00\00\00@\f4?")
(data $.rodata.74 (;74;) (i64.const 312537) "\f0*n\07'\ce\bf\10\ff?TO/\17\bd\00\00\00\00\00 \f4?")
(data $.rodata.75 (;75;) (i64.const 312569) "\c0Ok!\5c\cd\bf\1bh\ca\bb\91\ba!=\00\00\00\00\00\00\f4?")
(data $.rodata.76 (;76;) (i64.const 312601) "\a0\9a\c7\f7\8f\cc\bf4\84\9fhOy'=\00\00\00\00\00\00\f4?")
(data $.rodata.77 (;77;) (i64.const 312633) "\a0\9a\c7\f7\8f\cc\bf4\84\9fhOy'=\00\00\00\00\00\e0\f3?")
(data $.rodata.78 (;78;) (i64.const 312665) "\90-t\86\c2\cb\bf\8f\b7\8b1\b0N\19=\00\00\00\00\00\c0\f3?")
(data $.rodata.79 (;79;) (i64.const 312697) "\c0\80N\c9\f3\ca\bff\90\cd?cN\ba<\00\00\00\00\00\a0\f3?")
(data $.rodata.80 (;80;) (i64.const 312729) "\b0\e2\1f\bc#\ca\bf\ea\c1F\dcd\8c%\bd\00\00\00\00\00\a0\f3?")
(data $.rodata.81 (;81;) (i64.const 312761) "\b0\e2\1f\bc#\ca\bf\ea\c1F\dcd\8c%\bd\00\00\00\00\00\80\f3?")
(data $.rodata.82 (;82;) (i64.const 312793) "P\f4\9cZR\c9\bf\e3\d4\c1\04\d9\d1*\bd\00\00\00\00\00`\f3?")
(data $.rodata.83 (;83;) (i64.const 312825) "\d0 e\a0\7f\c8\bf\09\fa\db\7f\bf\bd+=\00\00\00\00\00@\f3?")
(data $.rodata.84 (;84;) (i64.const 312857) "\e0\10\02\89\ab\c7\bfXJSr\90\db+=\00\00\00\00\00@\f3?")
(data $.rodata.85 (;85;) (i64.const 312889) "\e0\10\02\89\ab\c7\bfXJSr\90\db+=\00\00\00\00\00 \f3?")
(data $.rodata.86 (;86;) (i64.const 312921) "\d0\19\e7\0f\d6\c6\bff\e2\b2\a3j\e4\10\bd\00\00\00\00\00\00\f3?")
(data $.rodata.87 (;87;) (i64.const 312953) "\90\a7p0\ff\c5\bf9P\10\9fC\9e\1e\bd\00\00\00\00\00\00\f3?")
(data $.rodata.88 (;88;) (i64.const 312985) "\90\a7p0\ff\c5\bf9P\10\9fC\9e\1e\bd\00\00\00\00\00\e0\f2?")
(data $.rodata.89 (;89;) (i64.const 313017) "\b0\a1\e3\e5&\c5\bf\8f[\07\90\8b\de \bd\00\00\00\00\00\c0\f2?")
(data $.rodata.90 (;90;) (i64.const 313049) "\80\cbl+M\c4\bf<x5a\c1\0c\17=\00\00\00\00\00\c0\f2?")
(data $.rodata.91 (;91;) (i64.const 313081) "\80\cbl+M\c4\bf<x5a\c1\0c\17=\00\00\00\00\00\a0\f2?")
(data $.rodata.92 (;92;) (i64.const 313113) "\90\1e \fcq\c3\bf:T'M\86x\f1<\00\00\00\00\00\80\f2?")
(data $.rodata.93 (;93;) (i64.const 313145) "\f0\1f\f8R\95\c2\bf\08\c4q\170\8d$\bd\00\00\00\00\00`\f2?")
(data $.rodata.94 (;94;) (i64.const 313177) "`/\d5*\b7\c1\bf\96\a3\11\18\a4\80.\bd\00\00\00\00\00`\f2?")
(data $.rodata.95 (;95;) (i64.const 313209) "`/\d5*\b7\c1\bf\96\a3\11\18\a4\80.\bd\00\00\00\00\00@\f2?")
(data $.rodata.96 (;96;) (i64.const 313241) "\90\d0|~\d7\c0\bf\f4[\e8\88\96i\0a=\00\00\00\00\00@\f2?")
(data $.rodata.97 (;97;) (i64.const 313273) "\90\d0|~\d7\c0\bf\f4[\e8\88\96i\0a=\00\00\00\00\00 \f2?")
(data $.rodata.98 (;98;) (i64.const 313305) "\e0\db1\91\ec\bf\bf\f23\a3\5cTu%\bd\00\00\00\00\00\00\f2?")
(data $.rodata.99 (;99;) (i64.const 313338) "+n\07'\be\bf<\00\f0*,4*=\00\00\00\00\00\00\f2?")
(data $.rodata.100 (;100;) (i64.const 313370) "+n\07'\be\bf<\00\f0*,4*=\00\00\00\00\00\e0\f1?")
(data $.rodata.101 (;101;) (i64.const 313401) "\c0[\8fT^\bc\bf\06\be_XW\0c\1d\bd\00\00\00\00\00\c0\f1?")
(data $.rodata.102 (;102;) (i64.const 313433) "\e0J:m\92\ba\bf\c8\aa[\e859%=\00\00\00\00\00\c0\f1?")
(data $.rodata.103 (;103;) (i64.const 313465) "\e0J:m\92\ba\bf\c8\aa[\e859%=\00\00\00\00\00\a0\f1?")
(data $.rodata.104 (;104;) (i64.const 313497) "\a01\d6E\c3\b8\bfhV/M)|\13=\00\00\00\00\00\a0\f1?")
(data $.rodata.105 (;105;) (i64.const 313529) "\a01\d6E\c3\b8\bfhV/M)|\13=\00\00\00\00\00\80\f1?")
(data $.rodata.106 (;106;) (i64.const 313561) "`\e5\8a\d2\f0\b6\bf\das3\c97\97&\bd\00\00\00\00\00`\f1?")
(data $.rodata.107 (;107;) (i64.const 313593) " \06?\07\1b\b5\bfW^\c6a[\02\1f=\00\00\00\00\00`\f1?")
(data $.rodata.108 (;108;) (i64.const 313625) " \06?\07\1b\b5\bfW^\c6a[\02\1f=\00\00\00\00\00@\f1?")
(data $.rodata.109 (;109;) (i64.const 313657) "\e0\1b\96\d7A\b3\bf\df\13\f9\cc\da^,=\00\00\00\00\00@\f1?")
(data $.rodata.110 (;110;) (i64.const 313689) "\e0\1b\96\d7A\b3\bf\df\13\f9\cc\da^,=\00\00\00\00\00 \f1?")
(data $.rodata.111 (;111;) (i64.const 313721) "\80\a3\ee6e\b1\bf\09\a3\8fv^|\14=\00\00\00\00\00\00\f1?")
(data $.rodata.112 (;112;) (i64.const 313753) "\80\11\c00\0a\af\bf\91\8e6\83\9eY-=\00\00\00\00\00\00\f1?")
(data $.rodata.113 (;113;) (i64.const 313785) "\80\11\c00\0a\af\bf\91\8e6\83\9eY-=\00\00\00\00\00\e0\f0?")
(data $.rodata.114 (;114;) (i64.const 313817) "\80\19q\ddB\ab\bfLp\d6\e5z\82\1c=\00\00\00\00\00\e0\f0?")
(data $.rodata.115 (;115;) (i64.const 313849) "\80\19q\ddB\ab\bfLp\d6\e5z\82\1c=\00\00\00\00\00\c0\f0?")
(data $.rodata.116 (;116;) (i64.const 313881) "\c02\f6Xt\a7\bf\ee\a1\f24F\fc,\bd\00\00\00\00\00\c0\f0?")
(data $.rodata.117 (;117;) (i64.const 313913) "\c02\f6Xt\a7\bf\ee\a1\f24F\fc,\bd\00\00\00\00\00\a0\f0?")
(data $.rodata.118 (;118;) (i64.const 313945) "\c0\fe\b9\87\9e\a3\bf\aa\fe&\f5\b7\02\f5<\00\00\00\00\00\a0\f0?")
(data $.rodata.119 (;119;) (i64.const 313977) "\c0\fe\b9\87\9e\a3\bf\aa\fe&\f5\b7\02\f5<\00\00\00\00\00\80\f0?")
(data $.rodata.120 (;120;) (i64.const 314010) "x\0e\9b\82\9f\bf\e4\09~|&\80)\bd\00\00\00\00\00\80\f0?")
(data $.rodata.121 (;121;) (i64.const 314042) "x\0e\9b\82\9f\bf\e4\09~|&\80)\bd\00\00\00\00\00`\f0?")
(data $.rodata.122 (;122;) (i64.const 314073) "\80\d5\07\1b\b9\97\bf9\a6\fa\93T\8d(\bd\00\00\00\00\00@\f0?")
(data $.rodata.123 (;123;) (i64.const 314106) "\fc\b0\a8\c0\8f\bf\9c\a6\d3\f6|\1e\df\bc\00\00\00\00\00@\f0?")
(data $.rodata.124 (;124;) (i64.const 314138) "\fc\b0\a8\c0\8f\bf\9c\a6\d3\f6|\1e\df\bc\00\00\00\00\00 \f0?")
(data $.rodata.125 (;125;) (i64.const 314170) "\10k*\e0\7f\bf\e4@\da\0d?\e2\19\bd\00\00\00\00\00 \f0?")
(data $.rodata.126 (;126;) (i64.const 314202) "\10k*\e0\7f\bf\e4@\da\0d?\e2\19\bd\00\00\00\00\00\00\f0?")
(data $.rodata.127 (;127;) (i64.const 314254) "\f0?")
(data $.rodata.128 (;128;) (i64.const 314285) "\c0\ef?")
(data $.rodata.129 (;129;) (i64.const 314298) "\89u\15\10\80?\e8+\9d\99k\c7\10\bd\00\00\00\00\00\80\ef?")
(data $.rodata.130 (;130;) (i64.const 314329) "\80\93XV \90?\d2\f7\e2\06[\dc#\bd\00\00\00\00\00@\ef?")
(data $.rodata.131 (;131;) (i64.const 314362) "\c9(%I\98?4\0cZ2\ba\a0*\bd\00\00\00\00\00\00\ef?")
(data $.rodata.132 (;132;) (i64.const 314393) "@\e7\89]A\a0?S\d7\f1\5c\c0\11\01=\00\00\00\00\00\c0\ee?")
(data $.rodata.133 (;133;) (i64.const 314426) ".\d4\aef\a4?(\fd\bdus\16,\bd\00\00\00\00\00\80\ee?")
(data $.rodata.134 (;134;) (i64.const 314457) "\c0\9f\14\aa\94\a8?}&Z\d0\95y\19\bd\00\00\00\00\00@\ee?")
(data $.rodata.135 (;135;) (i64.const 314489) "\c0\dd\cds\cb\ac?\07(\d8G\f2h\1a\bd\00\00\00\00\00 \ee?")
(data $.rodata.136 (;136;) (i64.const 314521) "\c0\06\c01\ea\ae?{;\c9O>\11\0e\bd\00\00\00\00\00\e0\ed?")
(data $.rodata.137 (;137;) (i64.const 314553) "`F\d1;\97\b1?\9b\9e\0dV]2%\bd\00\00\00\00\00\a0\ed?")
(data $.rodata.138 (;138;) (i64.const 314585) "\e0\d1\a7\f5\bd\b3?\d7N\db\a5^\c8,=\00\00\00\00\00`\ed?")
(data $.rodata.139 (;139;) (i64.const 314617) "\a0\97MZ\e9\b5?\1e\1d]<\06i,\bd\00\00\00\00\00@\ed?")
(data $.rodata.140 (;140;) (i64.const 314649) "\c0\ea\0a\d3\00\b7?2\ed\9d\a9\8d\1e\ec<\00\00\00\00\00\00\ed?")
(data $.rodata.141 (;141;) (i64.const 314681) "@Y]^3\b9?\daG\bd:\5c\11#=\00\00\00\00\00\c0\ec?")
(data $.rodata.142 (;142;) (i64.const 314713) "`\ad\8d\c8j\bb?\e5h\f7+\80\90\13\bd\00\00\00\00\00\a0\ec?")
(data $.rodata.143 (;143;) (i64.const 314745) "@\bc\01X\88\bc?\d3\acZ\c6\d1F&=\00\00\00\00\00`\ec?")
(data $.rodata.144 (;144;) (i64.const 314777) " \0a\839\c7\be?\e0E\e6\afh\c0-\bd\00\00\00\00\00@\ec?")
(data $.rodata.145 (;145;) (i64.const 314809) "\e0\db9\91\e8\bf?\fd\0a\a1O\d64%\bd\00\00\00\00\00\00\ec?")
(data $.rodata.146 (;146;) (i64.const 314841) "\e0'\82\8e\17\c1?\f2\07-\cex\ef!=\00\00\00\00\00\e0\eb?")
(data $.rodata.147 (;147;) (i64.const 314873) "\f0#~+\aa\c1?4\998D\8e\a7,=\00\00\00\00\00\a0\eb?")
(data $.rodata.148 (;148;) (i64.const 314905) "\80\86\0ca\d1\c2?\a1\b4\81\cbl\9d\03=\00\00\00\00\00\80\eb?")
(data $.rodata.149 (;149;) (i64.const 314937) "\90\15\b0\fce\c3?\89rK#\a8/\c6<\00\00\00\00\00@\eb?")
(data $.rodata.150 (;150;) (i64.const 314969) "\b03\83=\91\c4?x\b6\fdTy\83%=\00\00\00\00\00 \eb?")
(data $.rodata.151 (;151;) (i64.const 315001) "\b0\a1\e4\e5'\c5?\c7}i\e5\e83&=\00\00\00\00\00\e0\ea?")
(data $.rodata.152 (;152;) (i64.const 315033) "\10\8c\beNW\c6?x.<,\8b\cf\19=\00\00\00\00\00\c0\ea?")
(data $.rodata.153 (;153;) (i64.const 315065) "pu\8b\12\f0\c6?\e1!\9c\e5\8d\11%\bd\00\00\00\00\00\a0\ea?")
(data $.rodata.154 (;154;) (i64.const 315097) "PD\85\8d\89\c7?\05C\91p\10f\1c\bd\00\00\00\00\00`\ea?")
(data $.rodata.155 (;155;) (i64.const 315130) "9\eb\af\be\c8?\d1,\e9\aaT=\07\bd\00\00\00\00\00@\ea?")
(data $.rodata.156 (;156;) (i64.const 315162) "\f7\dcZZ\c9?o\ff\a0X(\f2\07=\00\00\00\00\00\00\ea?")
(data $.rodata.157 (;157;) (i64.const 315193) "\e0\8a<\ed\93\ca?i!VPCr(\bd\00\00\00\00\00\e0\e9?")
(data $.rodata.158 (;158;) (i64.const 315225) "\d0[W\d81\cb?\aa\e1\acN\8d5\0c\bd\00\00\00\00\00\c0\e9?")
(data $.rodata.159 (;159;) (i64.const 315257) "\e0;8\87\d0\cb?\b6\12TY\c4K-\bd\00\00\00\00\00\a0\e9?")
(data $.rodata.160 (;160;) (i64.const 315289) "\10\f0\c6\fbo\cc?\d2+\96\c5r\ec\f1\bc\00\00\00\00\00`\e9?")
(data $.rodata.161 (;161;) (i64.const 315321) "\90\d4\b0=\b1\cd?5\b0\15\f7*\ff*\bd\00\00\00\00\00@\e9?")
(data $.rodata.162 (;162;) (i64.const 315353) "\10\e7\ff\0eS\ce?0\f4A`'\12\c2<\00\00\00\00\00 \e9?")
(data $.rodata.163 (;163;) (i64.const 315386) "\dd\e4\ad\f5\ce?\11\8e\bbe\15!\ca\bc\00\00\00\00\00\00\e9?")
(data $.rodata.164 (;164;) (i64.const 315417) "\b0\b3l\1c\99\cf?0\df\0c\ca\ec\cb\1b=\00\00\00\00\00\c0\e8?")
(data $.rodata.165 (;165;) (i64.const 315449) "XM`8q\d0?\91N\ed\16\db\9c\f8<\00\00\00\00\00\a0\e8?")
(data $.rodata.166 (;166;) (i64.const 315481) "`ag-\c4\d0?\e9\ea<\16\8b\18'=\00\00\00\00\00\80\e8?")
(data $.rodata.167 (;167;) (i64.const 315513) "\e8'\82\8e\17\d1?\1c\f0\a5c\0e!,\bd\00\00\00\00\00`\e8?")
(data $.rodata.168 (;168;) (i64.const 315545) "\f8\ac\cb\5ck\d1?\81\16\a5\f7\cd\9a+=\00\00\00\00\00@\e8?")
(data $.rodata.169 (;169;) (i64.const 315577) "hZc\99\bf\d1?\b7\bdGQ\ed\a6,=\00\00\00\00\00 \e8?")
(data $.rodata.170 (;170;) (i64.const 315609) "\b8\0emE\14\d2?\ea\baF\ba\de\87\0a=\00\00\00\00\00\e0\e7?")
(data $.rodata.171 (;171;) (i64.const 315641) "\90\dc|\f0\be\d2?\f4\04PJ\fa\9c*=\00\00\00\00\00\c0\e7?")
(data $.rodata.172 (;172;) (i64.const 315673) "`\d3\e1\f1\14\d3?\b8<!\d3z\e2(\bd\00\00\00\00\00\a0\e7?")
(data $.rodata.173 (;173;) (i64.const 315705) "\10\bevgk\d3?\c8w\f1\b0\cdn\11=\00\00\00\00\00\80\e7?")
(data $.rodata.174 (;174;) (i64.const 315737) "03wR\c2\d3?\5c\bd\06\b6T;\18=\00\00\00\00\00`\e7?")
(data $.rodata.175 (;175;) (i64.const 315769) "\e8\d5#\b4\19\d4?\9d\e0\90\ec6\e4\08=\00\00\00\00\00@\e7?")
(data $.rodata.176 (;176;) (i64.const 315801) "\c8q\c2\8dq\d4?u\d6g\09\ce'/\bd\00\00\00\00\00 \e7?")
(data $.rodata.177 (;177;) (i64.const 315833) "0\17\9e\e0\c9\d4?\a4\d8\0a\1b\89 .\bd\00\00\00\00\00\00\e7?")
(data $.rodata.178 (;178;) (i64.const 315865) "\a08\07\ae\22\d5?Y\c7d\81p\be.=\00\00\00\00\00\e0\e6?")
(data $.rodata.179 (;179;) (i64.const 315897) "\d0\c8S\f7{\d5?\ef@]\ee\ed\ad\1f=\00\00\00\00\00\c0\e6?")
(data $.rodata.180 (;180;) (i64.const 315929) "`Y\df\bd\d5\d5?\dce\a4\08*\0b\0a\bd\00\00\00\00\00\00\00\00\de\12\04\95\00\00\00\00\ff\ff\ff\ff\ff\ff\ff\ff\ff\ff\ff\ff\00\00\00\000\d2\04\00\00\00\00\00\14\00\00\00\00\00\00\00C.UTF-8")
(data $.rodata.181 (;181;) (i64.const 316032) "LC_CTYPE\00\00\00\00LC_NUMERIC\00\00LC_TIME\00\00\00\00\00LC_COLLATE\00\00LC_MONETARY\00LC_MESSAGES")
(data $.rodata.182 (;182;) (i64.const 316112) "C.UTF-8")
(data $.rodata.183 (;183;) (i64.const 316136) "0\de\04\00\00\00\00\00 \df\04\00\00\00\00\00\08\e0\04\00\00\00\00\00No error information\00Illegal byte sequence\00Domain error\00Result not representable\00Not a tty\00Permission denied\00Operation not permitted\00No such file or directory\00No such process\00File exists\00Value too large for data type\00No space left on device\00Out of memory\00Resource busy\00Interrupted system call\00Resource temporarily unavailable\00Invalid seek\00Cross-device link\00Read-only file system\00Directory not empty\00Connection reset by peer\00Operation timed out\00Connection refused\00Host is down\00Host is unreachable\00Address in use\00Broken pipe\00I/O error\00No such device or address\00Block device required\00No such device\00Not a directory\00Is a directory\00Text file busy\00Exec format error\00Invalid argument\00Argument list too long\00Symbolic link loop\00Filename too long\00Too many open files in system\00No file descriptors available\00Bad file descriptor\00No child process\00Bad address\00File too large\00Too many links\00No locks available\00Resource deadlock would occur\00State not recoverable\00Previous owner died\00Operation canceled\00Function not implemented\00No message of desired type\00Identifier removed\00Device not a stream\00No data available\00Device timeout\00Out of streams resources\00Link has been severed\00Protocol error\00Bad message\00File descriptor in bad state\00Not a socket\00Destination address required\00Message too large\00Protocol wrong type for socket\00Protocol not available\00Protocol not supported\00Socket type not supported\00Not supported\00Protocol family not supported\00Address family not supported by protocol\00Address not available\00Network is down\00Network unreachable\00Connection reset by network\00Connection aborted\00No buffer space available\00Socket is connected\00Socket not connected\00Cannot send after socket shutdown\00Operation already in progress\00Operation in progress\00Stale file handle\00Remote I/O error\00Quota exceeded\00No medium found\00Wrong medium type\00Multihop attempted\00Required key not available\00Key has expired\00Key has been revoked\00Key was rejected by service")
(data $.rodata.184 (;184;) (i64.const 318082) "\a5\02[\00\f0\01\b5\05\8c\05%\01\83\06\1d\03\94\04\ff\00\c7\031\03\0b\06\bc\01\8f\01\7f\03\ca\04+\00\da\06\af\00B\03N\03\dc\01\0e\04\15\00\a1\06\0d\01\94\02\0b\028\06d\02\bc\02\ff\02]\03\e7\04\0b\07\cf\02\cb\05\ef\05\db\05\e1\02\1e\06E\02\85\00\82\02l\03o\04\f1\00\f3\03\18\05\d9\00\da\03L\06T\02{\01\9d\03\bd\04\00\00Q\00\15\02\bb\00\b3\03m\00\ff\01\85\04/\05\f9\048\00e\01F\01\9f\00\b7\06\a8\01s\02S\01")
(data $.rodata.185 (;185;) (i64.const 318280) "!\04\00\00\00\00\00\00\00\00/\02")
(data $.rodata.186 (;186;) (i64.const 318312) "5\04G\04V\04")
(data $.rodata.187 (;187;) (i64.const 318334) "\a0\04")
(data $.rodata.188 (;188;) (i64.const 318354) "F\05`\05n\05a\06\00\00\cf\01\00\00\00\00\00\00\00\00\c9\06\e9\06\f9\06\1e\079\07I\07^\07")
(data $.rodata.189 (;189;) (i64.const 318400) "\d1t\9e\00W\9d\bd*\80pR\0f\ff\ff>'\0a\00\00\00d\00\00\00\e8\03\00\00\10'\00\00\a0\86\01\00@B\0f\00\80\96\98\00\00\e1\f5\05\18\00\00\005\00\00\00q\00\00\00k\ff\ff\ff\ce\fb\ff\ff\92\bf\ff\ff\00\00\00\00\00\00\00\00/tmp/tmpfile_XXXXXX")
(data $.rodata.190 (;190;) (i64.const 318512) "/tmp/tmpnam_XXXXXX")
(data $.rodata.191 (;191;) (i64.const 318544) "\19\00\0b\00\19\19\19\00\00\00\00\05\00\00\00\00\00\00\09\00\00\00\00\0b\00\00\00\00\00\00\00\00\19\00\0a\0a\19\19\19\03\0a\07\00\01\00\09\0b\18\00\00\09\06\0b\00\00\0b\00\06\19\00\00\00\19\19\19")
(data $.rodata.192 (;192;) (i64.const 318625) "\0e\00\00\00\00\00\00\00\00\19\00\0b\0d\19\19\19\00\0d\00\00\02\00\09\0e\00\00\00\09\00\0e\00\00\0e")
(data $.rodata.193 (;193;) (i64.const 318683) "\0c")
(data $.rodata.194 (;194;) (i64.const 318695) "\13\00\00\00\00\13\00\00\00\00\09\0c\00\00\00\00\00\0c\00\00\0c")
(data $.rodata.195 (;195;) (i64.const 318741) "\10")
(data $.rodata.196 (;196;) (i64.const 318753) "\0f\00\00\00\04\0f\00\00\00\00\09\10\00\00\00\00\00\10\00\00\10")
(data $.rodata.197 (;197;) (i64.const 318799) "\12")
(data $.rodata.198 (;198;) (i64.const 318811) "\11\00\00\00\00\11\00\00\00\00\09\12\00\00\00\00\00\12\00\00\12\00\00\1a\00\00\00\1a\1a\1a")
(data $.rodata.199 (;199;) (i64.const 318866) "\1a\00\00\00\1a\1a\1a\00\00\00\00\00\00\09")
(data $.rodata.200 (;200;) (i64.const 318915) "\14")
(data $.rodata.201 (;201;) (i64.const 318927) "\17\00\00\00\00\17\00\00\00\00\09\14\00\00\00\00\00\14\00\00\14")
(data $.rodata.202 (;202;) (i64.const 318973) "\16")
(data $.rodata.203 (;203;) (i64.const 318985) "\15\00\00\00\00\15\00\00\00\00\09\16\00\00\00\00\00\16\00\00\16\00\000123456789ABCDEF")
(data $.data (;204;) (i64.const 319024) "\05")
(data $.data.1 (;205;) (i64.const 319048) "\c6")
(data $.data.2 (;206;) (i64.const 319096) "\c4\00\00\00\00\00\00\00\c3\00\00\00\00\00\00\00\e0\0c\05")
(data $.data.3 (;207;) (i64.const 319144) "\02")
(data $.data.4 (;208;) (i64.const 319164) "\ff\ff\ff\ff\ff\ff\ff\ff")
(data $.data.5 (;209;) (i64.const 319256) "0\de\04\00\00\00\00\00\09")
(data $.data.6 (;210;) (i64.const 319288) "\c6")
(data $.data.7 (;211;) (i64.const 319328) "\c5")
(data $.data.8 (;212;) (i64.const 319344) "\c3\00\00\00\00\00\00\00\e8\0c\05\00\00\00\00\00\00\04")
(data $.data.9 (;213;) (i64.const 319404) "\ff\ff\ff\ff")
(data $.data.10 (;214;) (i64.const 319496) "\05")
(data $.data.11 (;215;) (i64.const 319520) "\c7")
(data $.data.12 (;216;) (i64.const 319568) "\c4\00\00\00\00\00\00\00\c8\00\00\00\00\00\00\00\f8\10\05\00\00\00\00\00\00\04")
(data $.data.13 (;217;) (i64.const 319616) "\01")
(data $.data.14 (;218;) (i64.const 319636) "\ff\ff\ff\ff\0a")
(data $.data.15 (;219;) (i64.const 319728) "\08\e0\04\00\00\00\00\00p\19\85\02")
)