├── .gitignore ├── LICENSE ├── README.md ├── hashings ├── adler32.lua ├── blake2b.lua ├── blake2s.lua ├── crc32.lua ├── hmac.lua ├── init.lua ├── keccak.lua ├── md5.lua ├── pbkdf2.lua ├── ripemd160.lua ├── sha1.lua ├── sha256.lua ├── sha3_256.lua ├── sha3_512.lua ├── sha512.lua └── whirlpool.lua ├── lua-hashings-scm-1.rockspec └── test ├── runner.lua ├── test.lua ├── test_adler32.lua ├── test_blake2b.lua ├── test_blake2s.lua ├── test_crc32.lua ├── test_md5.lua ├── test_ripemd160.lua ├── test_sha1.lua ├── test_sha256.lua ├── test_sha3_256.lua ├── test_sha3_512.lua ├── test_sha512.lua ├── test_whirlpool.lua └── vectors.lua /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Lua sources 2 | luac.out 3 | 4 | # luarocks build files 5 | *.src.rock 6 | *.zip 7 | *.tar.gz 8 | 9 | # Object files 10 | *.o 11 | *.os 12 | *.ko 13 | *.obj 14 | *.elf 15 | 16 | # Precompiled Headers 17 | *.gch 18 | *.pch 19 | 20 | # Libraries 21 | *.lib 22 | *.a 23 | *.la 24 | *.lo 25 | *.def 26 | *.exp 27 | 28 | # Shared objects (inc. Windows DLLs) 29 | *.dll 30 | *.so 31 | *.so.* 32 | *.dylib 33 | 34 | # Executables 35 | *.exe 36 | *.out 37 | *.app 38 | *.i*86 39 | *.x86_64 40 | *.hex 41 | 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 John Schember 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Lua-hashings 2 | ============ 3 | 4 | Pure Lua cryptographic hash library. 5 | 6 | Supported hashes 7 | ---------------- 8 | 9 | * adler32 10 | * blake2b 11 | * blake2s 12 | * crc32 13 | * md5 14 | * ripemd160 15 | * sha1 16 | * sha256 17 | * sha3_256 18 | * sha3_512 19 | * sha512 20 | * whirlpool 21 | 22 | Additional hash functions 23 | ------------------------- 24 | 25 | * hmac 26 | * pbkdf2 27 | 28 | API 29 | --- 30 | 31 | All hash modules support the same API and any module implementing 32 | this API can be used by the additional hash functions. 33 | 34 | * `new(data)` or `(data)` 35 | * `copy()` 36 | * `update(data)` 37 | * `digest()` 38 | * `hexdigest()` 39 | 40 | The digest and hexdigest functions will not change the internal state 41 | of the object. Multiple calls to these will return the same result. 42 | 43 | All hash modules provide the following information about the hash. 44 | 45 | * digest_size 46 | * block_size 47 | 48 | There are some functions, such as `hexdigest`, which are the same implementation 49 | in multiple modules. This is by design because modules are intended to be independent 50 | of the library itself. Each module can be copied into another project without needing 51 | the rest of the library. The hash functions are the same in that they can 52 | be dropped into another project and used independent of the library provided that 53 | anything using the hash functions implements the above API. 54 | 55 | Dependencies 56 | ------------ 57 | 58 | This library depends on [lua-nums](https://github.com/user-none/lua-nums) 59 | because many hashes rely on fixed width integers. It's also needed 60 | to support 64 bit hashes. 61 | 62 | Example Use 63 | ----------- 64 | 65 | LUA_PATH="../lua-nums/?/init.lua;../lua-nums/?.lua;../lua-hashings/?/init.lua;../lua-hashings/?.lua;./?.lua" lua hs.lua 66 | 67 | ```lua 68 | local digest = require("hashings.sha256") 69 | print(digest:new("Hello"):hexdigest()) 70 | ``` 71 | 72 | ```lua 73 | local hashings = require("hashings") 74 | local hs = hashings("sha256") 75 | hs:update("Hello") 76 | print(hs:hexdigest()) 77 | ``` 78 | 79 | ```lua 80 | local mod = require("hashings").sha256 81 | local hs = mod() 82 | hs:update("Hello") 83 | print(hs:hexdigest()) 84 | ``` 85 | 86 | ### HMAC 87 | 88 | ```lua 89 | local hashings = require("hashings") 90 | local hs = hashings.hmac(hashings.sha256, 'secret123', "Hello") 91 | print(hs:hexdigest()) 92 | ``` 93 | 94 | ```lua 95 | local hashings = require("hashings") 96 | local hs = hashings.hmac(hashings.sha256, 'secret123') 97 | hs:update("Hello") 98 | print(hs:hexdigest()) 99 | ``` 100 | 101 | ### PBKDF2 102 | 103 | ```lua 104 | local hashings = require("hashings") 105 | print(hashings.pbkdf2(hashings.sha256, "password", 123, 256)) 106 | ``` 107 | 108 | ### Data from file 109 | 110 | ```lua 111 | local hs = require("hashings").sha256() 112 | local f = io.open("hs.lua", "rb") 113 | while true do 114 | local r = f:read(2) # You should use are more appropriately sized buffer 115 | if r == nuil then 116 | break 117 | end 118 | hs:update(r) 119 | end 120 | print(hs:hexdigest()) 121 | ``` 122 | 123 | Performance 124 | ----------- 125 | 126 | 32 bit hashes have quite good performance. However, due to using lua-nums which 127 | provides fixed width unsigned 64 bit integers 64 bit hashes are very slow. It is 128 | not recommended to use 64 bit hashes in performance critical code. 129 | -------------------------------------------------------------------------------- /hashings/adler32.lua: -------------------------------------------------------------------------------- 1 | -- Copyright (c) 2016 John Schember 2 | -- 3 | -- Permission is hereby granted, free of charge, to any person obtaining 4 | -- a copy of this software and associated documentation files (the "Software"), 5 | -- to deal in the Software without restriction, including without limitation 6 | -- the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | -- and/or sell copies of the Software, and to permit persons to whom the 8 | -- Software is furnished to do so, subject to the following conditions: 9 | -- 10 | -- The above copyright notice and this permission notice shall be included in 11 | -- all copies or substantial portions of the Software. 12 | -- 13 | -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | -- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | -- DEALINGS IN THE SOFTWARE. 20 | 21 | local string = require("string") 22 | local u32 = require("nums.uintn").u32 23 | 24 | local M = {} 25 | local M_mt = { __metatable = {}, __index = M } 26 | 27 | local MOD = 65521 28 | 29 | M.digest_size = 8 30 | M.block_size = 8 31 | 32 | function M:new(data) 33 | if self ~= M then 34 | return nil, "First argument must be self" 35 | end 36 | local o = setmetatable({}, M_mt) 37 | 38 | o._b1 = u32(1) 39 | o._b2 = u32(0) 40 | 41 | if data ~= nil then 42 | o:update(data) 43 | end 44 | 45 | return o 46 | end 47 | setmetatable(M, { __call = M.new }) 48 | 49 | function M:copy() 50 | local o = M:new() 51 | o._b1 = self._b1:copy() 52 | o._b2 = self._b2:copy() 53 | return o 54 | end 55 | 56 | function M:update(data) 57 | local b 58 | 59 | if data == nil then 60 | data = "" 61 | end 62 | 63 | data = tostring(data) 64 | 65 | for i=1,#data do 66 | b = string.byte(data, i) 67 | self._b1 = (self._b1+b) % MOD 68 | self._b2 = (self._b2+self._b1) % MOD 69 | end 70 | end 71 | 72 | function M:digest() 73 | return ((self._b2 << 16) | self._b1):asbytestring() 74 | end 75 | 76 | function M:hexdigest() 77 | local h 78 | local out = {} 79 | 80 | h = self:digest() 81 | for i=1,#h do 82 | out[i] = string.format("%02X", string.byte(h, i)) 83 | end 84 | return table.concat(out) 85 | end 86 | 87 | return M 88 | -------------------------------------------------------------------------------- /hashings/blake2b.lua: -------------------------------------------------------------------------------- 1 | -- Copyright (c) 2016 John Schember 2 | -- 3 | -- Permission is hereby granted, free of charge, to any person obtaining 4 | -- a copy of this software and associated documentation files (the "Software"), 5 | -- to deal in the Software without restriction, including without limitation 6 | -- the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | -- and/or sell copies of the Software, and to permit persons to whom the 8 | -- Software is furnished to do so, subject to the following conditions: 9 | -- 10 | -- The above copyright notice and this permission notice shall be included in 11 | -- all copies or substantial portions of the Software. 12 | -- 13 | -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | -- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | -- DEALINGS IN THE SOFTWARE. 20 | 21 | local string = require("string") 22 | local u64 = require("nums.uintb").u64 23 | local u8 = require("nums.uintn").u8 24 | 25 | local M = {} 26 | local M_mt = { __metatable = {}, __index = M } 27 | 28 | M.digest_size = 64 29 | M.block_size = 128 30 | 31 | local IV = { 32 | u64("0x6A09E667F3BCC908"), u64("0xBB67AE8584CAA73B"), u64("0x3C6EF372FE94F82B"), u64("0xA54FF53A5F1D36F1"), 33 | u64("0x510E527FADE682D1"), u64("0x9B05688C2B3E6C1F"), u64("0x1F83D9ABFB41BD6B"), u64("0x5BE0CD19137E2179") 34 | } 35 | 36 | local sigma = { 37 | { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }, 38 | { 15, 11, 5, 9, 10, 16, 14, 7, 2, 13, 1, 3, 12, 8, 6, 4 }, 39 | { 12, 9, 13, 1, 6, 3, 16, 14, 11, 15, 4, 7, 8, 2, 10, 5 }, 40 | { 8, 10, 4, 2, 14, 13, 12, 15, 3, 7, 6, 11, 5, 1, 16, 9 }, 41 | { 10, 1, 6, 8, 3, 5, 11, 16, 15, 2, 12, 13, 7, 9, 4, 14 }, 42 | { 3, 13, 7, 11, 1, 12, 9, 4, 5, 14, 8, 6, 16, 15, 2, 10 }, 43 | { 13, 6, 2, 16, 15, 14, 5, 11, 1, 8, 7, 4, 10, 3, 9, 12 }, 44 | { 14, 12, 8, 15, 13, 2, 4, 10, 6, 1, 16, 5, 9, 7, 3, 11 }, 45 | { 7, 16, 15, 10, 12, 4, 1, 9, 13, 3, 14, 8, 2, 5, 11, 6 }, 46 | { 11, 3, 9, 5, 8, 7, 2, 6, 16, 12, 10, 15, 4, 13, 14, 1 }, 47 | { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }, 48 | { 15, 11, 5, 9, 10, 16, 14, 7, 2, 13, 1, 3, 12, 8, 6, 4 } 49 | } 50 | 51 | local function rotate_right(x, n) 52 | return (x >> n) | (x << (64-n)) 53 | end 54 | 55 | local function increment_counter(cs, len) 56 | cs._t0 = cs._t0 + len 57 | if cs._t0 < len then 58 | cs._t1 = cs._t1 + 1 59 | end 60 | end 61 | 62 | local function G(r, i, m, a, b, c, d) 63 | a = a + b + m[sigma[r+1][2*i+1]] 64 | d = rotate_right(d ~ a, 32) 65 | c = c + d 66 | b = rotate_right(b ~ c, 24) 67 | a = a + b + m[sigma[r+1][2*i+2]] 68 | d = rotate_right(d ~ a, 16) 69 | c = c + d 70 | b = rotate_right(b ~ c, 63) 71 | return a, b, c, d 72 | end 73 | 74 | local function ROUND(r, m, v) 75 | v[1], v[5], v[9], v[13] = G(r ,0, m, v[1], v[5], v[9], v[13]) 76 | v[2], v[6], v[10], v[14] = G(r, 1, m, v[2], v[6], v[10], v[14]) 77 | v[3], v[7], v[11], v[15] = G(r, 2, m, v[3], v[7], v[11], v[15]) 78 | v[4], v[8], v[12], v[16] = G(r, 3, m, v[4], v[8], v[12], v[16]) 79 | v[1], v[6], v[11], v[16] = G(r, 4, m, v[1], v[6], v[11], v[16]) 80 | v[2], v[7], v[12], v[13] = G(r, 5, m, v[2], v[7], v[12], v[13]) 81 | v[3], v[8], v[9], v[14] = G(r, 6, m, v[3], v[8], v[9], v[14]) 82 | v[4], v[5], v[10], v[15] = G(r, 7, m, v[4], v[5], v[10], v[15]) 83 | end 84 | 85 | local function compress(cs) 86 | local v = {} 87 | local m = {} 88 | 89 | if #cs._data < 128 then 90 | return 91 | end 92 | 93 | for j=1,128,8 do 94 | m[#m+1] = 95 | u64(string.byte(cs._data, j+7)) << 56 | 96 | u64(string.byte(cs._data, j+6)) << 48 | 97 | u64(string.byte(cs._data, j+5)) << 40 | 98 | u64(string.byte(cs._data, j+4)) << 32 | 99 | u64(string.byte(cs._data, j+3)) << 24 | 100 | u64(string.byte(cs._data, j+2)) << 16 | 101 | u64(string.byte(cs._data, j+1)) << 8 | 102 | u64(string.byte(cs._data, j)) 103 | end 104 | cs._data = cs._data:sub(129, #cs._data) 105 | 106 | for i=1,8 do 107 | v[i] = cs._h[i]:copy() 108 | end 109 | v[9] = IV[1]:copy() 110 | v[10] = IV[2]:copy() 111 | v[11] = IV[3]:copy() 112 | v[12] = IV[4]:copy() 113 | v[13] = cs._t0 ~ IV[5] 114 | v[14] = cs._t1 ~ IV[6] 115 | if cs._last then 116 | v[15] = u64("0xFFFFFFFFFFFFFFFF") ~ IV[7] 117 | else 118 | v[15] = IV[7]:copy() 119 | end 120 | v[16] = IV[8]:copy() 121 | 122 | ROUND(0, m, v) 123 | ROUND(1, m, v) 124 | ROUND(2, m, v) 125 | ROUND(3, m, v) 126 | ROUND(4, m, v) 127 | ROUND(5, m, v) 128 | ROUND(6, m, v) 129 | ROUND(7, m, v) 130 | ROUND(8, m, v) 131 | ROUND(9, m, v) 132 | ROUND(10, m, v) 133 | ROUND(11, m, v) 134 | 135 | for i=1,8 do 136 | cs._h[i] = cs._h[i] ~ v[i] ~ v[i+8] 137 | end 138 | end 139 | 140 | function M:new(data) 141 | if self ~= M then 142 | return nil, "First argument must be self" 143 | end 144 | local o = setmetatable({}, M_mt) 145 | 146 | o._h = {} 147 | for i=1,8 do 148 | o._h[i] = IV[i]:copy() 149 | end 150 | -- XOR in param block. We don't support salt for 151 | -- personal parameters so this ends up being a constant. 152 | o._h[1] = o._h[1] ~ 16842816 153 | 154 | o._last = false 155 | o._t0 = u64(0) 156 | o._t1 = u64(0) 157 | o._data = "" 158 | 159 | if data ~= nil then 160 | o:update(data) 161 | end 162 | 163 | return o 164 | end 165 | setmetatable(M, { __call = M.new }) 166 | 167 | function M:copy() 168 | local o = M() 169 | for i=1,8 do 170 | o._h[i] = self._h[i]:copy() 171 | end 172 | o._last = self._last 173 | o._t0 = self._t0:copy() 174 | o._t1 = self._t1:copy() 175 | o._data = self._data 176 | return o 177 | end 178 | 179 | function M:update(data) 180 | if data == nil then 181 | data = "" 182 | end 183 | 184 | data = tostring(data) 185 | self._data = self._data .. data 186 | 187 | -- Update always leaves at least 1 byte for final. 188 | while #self._data > 128 do 189 | increment_counter(self, 128) 190 | compress(self) 191 | end 192 | end 193 | 194 | function M:digest() 195 | local final 196 | local out = {} 197 | local j 198 | 199 | final = self:copy() 200 | 201 | increment_counter(final, #final._data) 202 | final._last = true 203 | final._data = final._data .. string.rep(string.char(0), 128 - #final._data) 204 | compress(final) 205 | 206 | for i=1,#final._h do 207 | out[i] = final._h[i]:swape():asbytestring() 208 | end 209 | 210 | return table.concat(out) 211 | end 212 | 213 | function M:hexdigest() 214 | local h 215 | local out = {} 216 | 217 | h = self:digest() 218 | for i=1,#h do 219 | out[i] = string.format("%02X", string.byte(h, i)) 220 | end 221 | return table.concat(out) 222 | end 223 | 224 | return M 225 | -------------------------------------------------------------------------------- /hashings/blake2s.lua: -------------------------------------------------------------------------------- 1 | -- Copyright (c) 2016 John Schember 2 | -- 3 | -- Permission is hereby granted, free of charge, to any person obtaining 4 | -- a copy of this software and associated documentation files (the "Software"), 5 | -- to deal in the Software without restriction, including without limitation 6 | -- the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | -- and/or sell copies of the Software, and to permit persons to whom the 8 | -- Software is furnished to do so, subject to the following conditions: 9 | -- 10 | -- The above copyright notice and this permission notice shall be included in 11 | -- all copies or substantial portions of the Software. 12 | -- 13 | -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | -- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | -- DEALINGS IN THE SOFTWARE. 20 | 21 | local string = require("string") 22 | local u32 = require("nums.uintn").u32 23 | local u8 = require("nums.uintn").u8 24 | 25 | local M = {} 26 | local M_mt = { __metatable = {}, __index = M } 27 | 28 | M.digest_size = 32 29 | M.block_size = 64 30 | 31 | local IV = { 32 | u32(0x6A09E667), u32(0xBB67AE85), u32(0x3C6EF372), u32(0xA54FF53A), 33 | u32(0x510E527F), u32(0x9B05688C), u32(0x1F83D9AB), u32(0x5BE0CD19) 34 | } 35 | 36 | local sigma = { 37 | { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }, 38 | { 15, 11, 5, 9, 10, 16, 14, 7, 2, 13, 1, 3, 12, 8, 6, 4 }, 39 | { 12, 9, 13, 1, 6, 3, 16, 14, 11, 15, 4, 7, 8, 2, 10, 5 }, 40 | { 8, 10, 4, 2, 14, 13, 12, 15, 3, 7, 6, 11, 5, 1, 16, 9 }, 41 | { 10, 1, 6, 8, 3, 5, 11, 16, 15, 2, 12, 13, 7, 9, 4, 14 }, 42 | { 3, 13, 7, 11, 1, 12, 9, 4, 5, 14, 8, 6, 16, 15, 2, 10 }, 43 | { 13, 6, 2, 16, 15, 14, 5, 11, 1, 8, 7, 4, 10, 3, 9, 12 }, 44 | { 14, 12, 8, 15, 13, 2, 4, 10, 6, 1, 16, 5, 9, 7, 3, 11 }, 45 | { 7, 16, 15, 10, 12, 4, 1, 9, 13, 3, 14, 8, 2, 5, 11, 6 }, 46 | { 11, 3, 9, 5, 8, 7, 2, 6, 16, 12, 10, 15, 4, 13, 14, 1 } 47 | } 48 | 49 | local function rotate_right(x, n) 50 | return (x >> n) | (x << (32-n)) 51 | end 52 | 53 | local function increment_counter(cs, len) 54 | cs._t0 = cs._t0 + len 55 | if cs._t0 < len then 56 | cs._t1 = cs._t1 + 1 57 | end 58 | end 59 | 60 | local function G(r, i, m, a, b, c, d) 61 | a = a + b + m[sigma[r+1][2*i+1]] 62 | d = rotate_right(d ~ a, 16) 63 | c = c + d 64 | b = rotate_right(b ~ c, 12) 65 | a = a + b + m[sigma[r+1][2*i+2]] 66 | d = rotate_right(d ~ a, 8) 67 | c = c + d 68 | b = rotate_right(b ~ c, 7) 69 | return a, b, c, d 70 | end 71 | 72 | local function ROUND(r, m, v) 73 | v[1], v[5], v[9], v[13] = G(r ,0, m, v[1], v[5], v[9], v[13]) 74 | v[2], v[6], v[10], v[14] = G(r, 1, m, v[2], v[6], v[10], v[14]) 75 | v[3], v[7], v[11], v[15] = G(r, 2, m, v[3], v[7], v[11], v[15]) 76 | v[4], v[8], v[12], v[16] = G(r, 3, m, v[4], v[8], v[12], v[16]) 77 | v[1], v[6], v[11], v[16] = G(r, 4, m, v[1], v[6], v[11], v[16]) 78 | v[2], v[7], v[12], v[13] = G(r, 5, m, v[2], v[7], v[12], v[13]) 79 | v[3], v[8], v[9], v[14] = G(r, 6, m, v[3], v[8], v[9], v[14]) 80 | v[4], v[5], v[10], v[15] = G(r, 7, m, v[4], v[5], v[10], v[15]) 81 | end 82 | 83 | local function compress(cs) 84 | local v = {} 85 | local m = {} 86 | 87 | if #cs._data < 64 then 88 | return 89 | end 90 | 91 | for j=1,64,4 do 92 | m[#m+1] = u32(string.byte(cs._data, j+3) << 24 | 93 | string.byte(cs._data, j+2) << 16 | 94 | string.byte(cs._data, j+1) << 8 | 95 | string.byte(cs._data, j)) 96 | end 97 | cs._data = cs._data:sub(65, #cs._data) 98 | 99 | for i=1,8 do 100 | v[i] = cs._h[i]:copy() 101 | end 102 | v[9] = IV[1]:copy() 103 | v[10] = IV[2]:copy() 104 | v[11] = IV[3]:copy() 105 | v[12] = IV[4]:copy() 106 | v[13] = cs._t0 ~ IV[5] 107 | v[14] = cs._t1 ~ IV[6] 108 | if cs._last then 109 | v[15] = u32(0xFFFFFFFF) ~ IV[7] 110 | else 111 | v[15] = IV[7]:copy() 112 | end 113 | v[16] = IV[8]:copy() 114 | 115 | ROUND(0, m, v) 116 | ROUND(1, m, v) 117 | ROUND(2, m, v) 118 | ROUND(3, m, v) 119 | ROUND(4, m, v) 120 | ROUND(5, m, v) 121 | ROUND(6, m, v) 122 | ROUND(7, m, v) 123 | ROUND(8, m, v) 124 | ROUND(9, m, v) 125 | 126 | for i=1,8 do 127 | cs._h[i] = cs._h[i] ~ v[i] ~ v[i+8] 128 | end 129 | end 130 | 131 | function M:new(data) 132 | if self ~= M then 133 | return nil, "First argument must be self" 134 | end 135 | local o = setmetatable({}, M_mt) 136 | 137 | o._h = {} 138 | for i=1,8 do 139 | o._h[i] = IV[i]:copy() 140 | end 141 | -- XOR in param block. We don't support salt for 142 | -- personal parameters so this ends up being a constant. 143 | o._h[1] = o._h[1] ~ 16842784 144 | 145 | o._last = false 146 | o._t0 = u32(0) 147 | o._t1 = u32(0) 148 | o._data = "" 149 | 150 | if data ~= nil then 151 | o:update(data) 152 | end 153 | 154 | return o 155 | end 156 | setmetatable(M, { __call = M.new }) 157 | 158 | function M:copy() 159 | local o = M() 160 | for i=1,8 do 161 | o._h[i] = self._h[i]:copy() 162 | end 163 | o._last = self._last 164 | o._t0 = self._t0:copy() 165 | o._t1 = self._t1:copy() 166 | o._data = self._data 167 | return o 168 | end 169 | 170 | function M:update(data) 171 | if data == nil then 172 | data = "" 173 | end 174 | 175 | data = tostring(data) 176 | self._data = self._data .. data 177 | 178 | -- Update always leaves at least 1 byte for final. 179 | while #self._data > 64 do 180 | increment_counter(self, 64) 181 | compress(self) 182 | end 183 | end 184 | 185 | function M:digest() 186 | local final 187 | local out = {} 188 | 189 | final = self:copy() 190 | 191 | increment_counter(final, #final._data) 192 | final._last = true 193 | final._data = final._data .. string.rep(string.char(0), 64 - #final._data) 194 | compress(final) 195 | 196 | for i=1,#final._h do 197 | out[i] = final._h[i]:swape():asbytestring() 198 | end 199 | 200 | return table.concat(out) 201 | end 202 | 203 | function M:hexdigest() 204 | local h 205 | local out = {} 206 | 207 | h = self:digest() 208 | for i=1,#h do 209 | out[i] = string.format("%02X", string.byte(h, i)) 210 | end 211 | return table.concat(out) 212 | end 213 | 214 | return M 215 | -------------------------------------------------------------------------------- /hashings/crc32.lua: -------------------------------------------------------------------------------- 1 | -- Copyright (c) 2016 John Schember 2 | -- 3 | -- Permission is hereby granted, free of charge, to any person obtaining 4 | -- a copy of this software and associated documentation files (the "Software"), 5 | -- to deal in the Software without restriction, including without limitation 6 | -- the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | -- and/or sell copies of the Software, and to permit persons to whom the 8 | -- Software is furnished to do so, subject to the following conditions: 9 | -- 10 | -- The above copyright notice and this permission notice shall be included in 11 | -- all copies or substantial portions of the Software. 12 | -- 13 | -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | -- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | -- DEALINGS IN THE SOFTWARE. 20 | 21 | local string = require("string") 22 | local u32 = require("nums.uintn").u32 23 | 24 | local M = {} 25 | local M_mt = { __metatable = {}, __index = M } 26 | 27 | M.digest_size = 8 28 | M.block_size = 8 29 | 30 | local function digest_int(cs) 31 | end 32 | 33 | function M:new(data) 34 | if self ~= M then 35 | return nil, "First argument must be self" 36 | end 37 | local o = setmetatable({}, M_mt) 38 | o._crc = u32(0xFFFFFFFF) 39 | 40 | if data ~= nil then 41 | o:update(data) 42 | end 43 | 44 | return o 45 | end 46 | setmetatable(M, { __call = M.new }) 47 | 48 | function M:copy() 49 | local o = M:new() 50 | o._crc = self._crc:copy() 51 | return o 52 | end 53 | 54 | function M:update(data) 55 | local byte 56 | local mask 57 | 58 | if data == nil then 59 | data = "" 60 | end 61 | 62 | data = tostring(data) 63 | 64 | for i=1,#data do 65 | byte = string.byte(data, i) 66 | self._crc = self._crc ~ byte 67 | for j=1,8 do 68 | mask = (self._crc & 1)*-1 69 | self._crc = (self._crc >> 1) ~ (0xEDB88320 & mask) 70 | end 71 | end 72 | end 73 | 74 | function M:digest() 75 | return (~self._crc):asbytestring() 76 | end 77 | 78 | function M:hexdigest() 79 | local h 80 | local out = {} 81 | 82 | h = self:digest() 83 | for i=1,#h do 84 | out[i] = string.format("%02X", string.byte(h, i)) 85 | end 86 | return table.concat(out) 87 | end 88 | 89 | return M 90 | -------------------------------------------------------------------------------- /hashings/hmac.lua: -------------------------------------------------------------------------------- 1 | -- Copyright (c) 2016 John Schember 2 | -- 3 | -- Permission is hereby granted, free of charge, to any person obtaining 4 | -- a copy of this software and associated documentation files (the "Software"), 5 | -- to deal in the Software without restriction, including without limitation 6 | -- the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | -- and/or sell copies of the Software, and to permit persons to whom the 8 | -- Software is furnished to do so, subject to the following conditions: 9 | -- 10 | -- The above copyright notice and this permission notice shall be included in 11 | -- all copies or substantial portions of the Software. 12 | -- 13 | -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | -- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | -- DEALINGS IN THE SOFTWARE. 20 | 21 | local string = require("string") 22 | 23 | local M = {} 24 | local M_mt = { __metatable = {}, __index = M } 25 | 26 | function M:new(hm, key, data) 27 | local th 28 | local tk = {} 29 | local ipad = {} 30 | 31 | if self ~= M then 32 | return nil, "First argument must be self" 33 | end 34 | local o = setmetatable({}, M_mt) 35 | o._hm = hm 36 | 37 | -- Compute the key. 38 | if #key > hm.block_size then 39 | th = hm(key) 40 | key = th:digest() 41 | end 42 | for i=1,#key do 43 | tk[#tk+1] = string.byte(key, i) 44 | end 45 | for i=#key+1,hm.block_size do 46 | tk[#tk+1] = 0 47 | end 48 | 49 | -- Generate the inner and outer padding. 50 | o._opad = {} 51 | for i=1,#tk do 52 | ipad[i] = string.char(tk[i] ~ 0x36) 53 | o._opad[i] = string.char(tk[i] ~ 0x5C) 54 | end 55 | ipad = table.concat(ipad) 56 | o._opad = table.concat(o._opad) 57 | 58 | -- Start the hash witht the inner padding 59 | o._hash = o._hm(ipad) 60 | 61 | if data ~= nil then 62 | o._hash:update(data) 63 | end 64 | 65 | return o 66 | end 67 | setmetatable(M, { __call = M.new }) 68 | 69 | function M:copy() 70 | local o = setmetatable({}, M_mt) 71 | o._hm = self._hm 72 | o._hash = self._hash:copy() 73 | o._opad = self._opad 74 | return o 75 | end 76 | 77 | function M:update(data) 78 | self._hash:update(data) 79 | end 80 | 81 | function M:digest() 82 | local final 83 | local digest 84 | local th 85 | 86 | final = self:copy() 87 | digest = final._hash:digest() 88 | th = final._hm(final._opad) 89 | th:update(digest) 90 | 91 | return th:digest() 92 | end 93 | 94 | function M:hexdigest() 95 | local h 96 | local out = {} 97 | 98 | h = self:digest() 99 | for i=1,#h do 100 | out[i] = string.format("%02X", string.byte(h, i)) 101 | end 102 | return table.concat(out) 103 | end 104 | 105 | return M 106 | -------------------------------------------------------------------------------- /hashings/init.lua: -------------------------------------------------------------------------------- 1 | -- Copyright (c) 2016 John Schember 2 | -- 3 | -- Permission is hereby granted, free of charge, to any person obtaining 4 | -- a copy of this software and associated documentation files (the "Software"), 5 | -- to deal in the Software without restriction, including without limitation 6 | -- the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | -- and/or sell copies of the Software, and to permit persons to whom the 8 | -- Software is furnished to do so, subject to the following conditions: 9 | -- 10 | -- The above copyright notice and this permission notice shall be included in 11 | -- all copies or substantial portions of the Software. 12 | -- 13 | -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | -- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | -- DEALINGS IN THE SOFTWARE. 20 | 21 | local M = {} 22 | 23 | M.adler32 = require("hashings.adler32") 24 | M.blake2b = require("hashings.blake2b") 25 | M.blake2s = require("hashings.blake2s") 26 | M.crc32 = require("hashings.crc32") 27 | M.md5 = require("hashings.md5") 28 | M.ripemd160 = require("hashings.ripemd160") 29 | M.sha1 = require("hashings.sha1") 30 | M.sha256 = require("hashings.sha256") 31 | M.sha3_256 = require("hashings.sha3_256") 32 | M.sha3_512 = require("hashings.sha3_512") 33 | M.sha512 = require("hashings.sha512") 34 | M.whirlpool = require("hashings.whirlpool") 35 | 36 | M.hmac = require("hashings.hmac") 37 | M.pbkdf2 = require("hashings.pbkdf2") 38 | 39 | M.algorithms = { 40 | "adler32", 41 | "blake2b", 42 | "blake2s", 43 | "crc32", 44 | "md5", 45 | "ripemd160", 46 | "sha1", 47 | "sha256", 48 | "sha3_256", 49 | "sha3_512", 50 | "sha512", 51 | "whirlpool" 52 | } 53 | 54 | local alg_map = { 55 | adler32 = M.adler32, 56 | blake2b = M.blake2b, 57 | blake2s = M.blake2s, 58 | crc32 = M.crc32, 59 | md5 = M.md5, 60 | ripemd160 = M.ripemd160, 61 | sha1 = M.sha1, 62 | sha256 = M.sha256, 63 | sha3_256 = M.sha3_256, 64 | sha3_512 = M.sha3_512, 65 | sha512 = M.sha512, 66 | whirlpool = M.whirlpool 67 | } 68 | 69 | function M:new(alg, data) 70 | local a 71 | 72 | a = alg_map[alg] 73 | if a == nil then 74 | return nil 75 | end 76 | return a:new(data) 77 | end 78 | setmetatable(M, { __call = M.new }) 79 | 80 | return M 81 | -------------------------------------------------------------------------------- /hashings/keccak.lua: -------------------------------------------------------------------------------- 1 | -- Copyright (c) 2016 John Schember 2 | -- 3 | -- Permission is hereby granted, free of charge, to any person obtaining 4 | -- a copy of this software and associated documentation files (the "Software"), 5 | -- to deal in the Software without restriction, including without limitation 6 | -- the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | -- and/or sell copies of the Software, and to permit persons to whom the 8 | -- Software is furnished to do so, subject to the following conditions: 9 | -- 10 | -- The above copyright notice and this permission notice shall be included in 11 | -- all copies or substantial portions of the Software. 12 | -- 13 | -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | -- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | -- DEALINGS IN THE SOFTWARE. 20 | 21 | local string = require("string") 22 | local u64 = require("nums.uintb").u64 23 | 24 | local M = {} 25 | local M_mt = { __metatable = {}, __index = M } 26 | 27 | --[[ 28 | for i=0,4 do 29 | print(((i+4)%5), ((i+1)%5)) 30 | end 31 | ]]-- 32 | -- idx + 1 for lua offsets starting with 1 33 | local theta_idxs = { 34 | { 5, 2 }, { 1, 3 }, { 2, 4 }, { 3, 5 }, { 4, 1 } 35 | } 36 | 37 | --[[ 38 | local x = 1 39 | local y = 0 40 | local Y 41 | local r 42 | for i=1,24 do 43 | Y = (2*x)+(3*y) 44 | x = y 45 | y = Y % 5 46 | r = x+(5*y) 47 | print(r) 48 | end 49 | ]]-- 50 | -- idx + 1 for lua offsets starting with 1 51 | local rhopi_idxs = { 52 | 11, 8, 12, 18, 19, 4, 6, 17, 9, 22, 25, 5, 53 | 16, 24, 20, 14, 13, 3, 21, 15, 23, 10, 7, 2 54 | } 55 | -- 56 | --[[ 57 | local r = 0 58 | for i=0,23 do 59 | r = r+i+1 60 | print(r%64) 61 | end 62 | ]]-- 63 | local rotation_constants = { 64 | 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, 65 | 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44 66 | } 67 | 68 | --[[ 69 | for i=0,24,5 do 70 | for j=0,4 do 71 | print(((j+1)%5)+i, ((j+2)%5)+i) 72 | end 73 | end 74 | ]]-- 75 | -- idx + 1 for lua offsets starting with 1 76 | local chi_idxs = { 77 | { 2, 3 }, { 3, 4 }, { 4, 5 }, { 5, 1 }, { 1, 2 }, 78 | { 7, 8 }, { 8, 9 }, { 9, 10 }, { 10, 6 }, { 6, 7 }, 79 | { 12, 13 }, { 13, 14 }, { 14, 15 }, { 15, 11 }, { 11, 12 }, 80 | { 17, 18 }, { 18, 19 }, { 19, 20 }, { 20, 16 }, { 16, 17 }, 81 | { 22, 23 }, { 23, 24 }, { 24, 25 }, { 25, 21 }, { 21, 22 } 82 | } 83 | 84 | --[[ 85 | local R = u8(1) 86 | local b 87 | for i=1,24 do 88 | b = u64(0) 89 | for j=0,6 do 90 | R = ((R<<1) ~ (113 * (R>>7))) 91 | if R & 2 ~= u8(0) then 92 | b = b ~ u64(1)<<((1<> (64-n)) 109 | end 110 | 111 | local function load_block(cs) 112 | local j 113 | local k 114 | 115 | for i=1,cs._block_size,8 do 116 | j = i//8+1 117 | k = ((i//8)*8)+1 118 | cs._s[j] = cs._s[j] ~ 119 | (u64(string.byte(cs._data, k)) | 120 | u64(string.byte(cs._data, k+1)) << 8 | 121 | u64(string.byte(cs._data, k+2)) << 16 | 122 | u64(string.byte(cs._data, k+3)) << 24 | 123 | u64(string.byte(cs._data, k+4)) << 32 | 124 | u64(string.byte(cs._data, k+5)) << 40 | 125 | u64(string.byte(cs._data, k+6)) << 48 | 126 | u64(string.byte(cs._data, k+7)) << 56) 127 | end 128 | cs._data = cs._data:sub(cs._block_size+1) 129 | end 130 | 131 | local function permute_theta(s) 132 | local B = {} 133 | local t 134 | 135 | for i=1,5 do 136 | B[i] = s[i] ~ s[i+5] ~ s[i+10] ~ s[i+15] ~ s[i+20] 137 | end 138 | 139 | for i=1,5 do 140 | t = B[theta_idxs[i][1]] ~ rotate_left(B[theta_idxs[i][2]], 1) 141 | for j=i,25,5 do 142 | s[j] = s[j] ~ t 143 | end 144 | end 145 | end 146 | 147 | local function permute_rho_pi(s) 148 | local b 149 | local t 150 | 151 | t = s[2]:copy() 152 | for i=1,24 do 153 | b = s[rhopi_idxs[i]] 154 | s[rhopi_idxs[i]] = rotate_left(t, rotation_constants[i]) 155 | t = b 156 | end 157 | end 158 | 159 | local function permute_chi(s) 160 | local B = {} 161 | 162 | for i=1,25 do 163 | B[i] = s[i]:copy() 164 | end 165 | 166 | for i=1,25 do 167 | s[i] = s[i] ~ (~B[chi_idxs[i][1]] & B[chi_idxs[i][2]]) 168 | end 169 | end 170 | 171 | local function permute_iota(s, n) 172 | s[1] = s[1] ~ round_constants[n] 173 | end 174 | 175 | function M:new(block_size, digest_size, data) 176 | if self ~= M then 177 | return nil, "First argument must be self" 178 | end 179 | 180 | if block_size > 200 then 181 | return nil, "Invalid block size" 182 | end 183 | 184 | local o = setmetatable({}, M_mt) 185 | 186 | o._block_size = block_size 187 | o._digest_size = digest_size 188 | o._data = "" 189 | 190 | o._s = {} 191 | for i=1,25 do 192 | o._s[i] = u64(0) 193 | end 194 | 195 | if data ~= nil then 196 | o:update(data) 197 | end 198 | 199 | return o 200 | end 201 | setmetatable(M, { __call = M.new }) 202 | 203 | function M:copy() 204 | local o = setmetatable({}, M_mt) 205 | 206 | o._block_size = self._block_size 207 | o._digest_size = self._digest_size 208 | o._data = self._data 209 | 210 | o._s = {} 211 | for i=1,25 do 212 | o._s[i] = self._s[i]:copy() 213 | end 214 | 215 | return o 216 | end 217 | 218 | function M:update(data) 219 | if data == nil then 220 | data = "" 221 | end 222 | 223 | data = tostring(data) 224 | self._data = self._data .. data 225 | 226 | while #self._data >= self._block_size do 227 | load_block(self) 228 | for i=1,24 do 229 | permute_theta(self._s) 230 | permute_rho_pi(self._s) 231 | permute_chi(self._s) 232 | permute_iota(self._s, i) 233 | end 234 | end 235 | end 236 | 237 | function M:digest() 238 | local final 239 | local data 240 | local out = {} 241 | 242 | final = self:copy() 243 | 244 | -- Pad 245 | if #final._data == final._block_size - 1 then 246 | data = string.char(0x06|0x80) 247 | else 248 | data = string.char(0x06) .. string.rep(string.char(0), final._block_size - #final._data - 2) .. string.char(0x80) 249 | end 250 | 251 | final:update(data) 252 | 253 | -- Squeeze 254 | for i=1,final._digest_size//8 do 255 | out[i] = final._s[i]:swape():asbytestring() 256 | end 257 | 258 | return table.concat(out) 259 | end 260 | 261 | function M:hexdigest() 262 | local h 263 | local out = {} 264 | 265 | h = self:digest() 266 | for i=1,#h do 267 | out[i] = string.format("%02X", string.byte(h, i)) 268 | end 269 | return table.concat(out) 270 | end 271 | 272 | return M 273 | -------------------------------------------------------------------------------- /hashings/md5.lua: -------------------------------------------------------------------------------- 1 | -- Copyright (c) 2016 John Schember 2 | -- 3 | -- Permission is hereby granted, free of charge, to any person obtaining 4 | -- a copy of this software and associated documentation files (the "Software"), 5 | -- to deal in the Software without restriction, including without limitation 6 | -- the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | -- and/or sell copies of the Software, and to permit persons to whom the 8 | -- Software is furnished to do so, subject to the following conditions: 9 | -- 10 | -- The above copyright notice and this permission notice shall be included in 11 | -- all copies or substantial portions of the Software. 12 | -- 13 | -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | -- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | -- DEALINGS IN THE SOFTWARE. 20 | 21 | local string = require("string") 22 | local u32 = require("nums.uintn").u32 23 | 24 | local M = {} 25 | local M_mt = { __metatable = {}, __index = M } 26 | 27 | M.digest_size = 16 28 | M.block_size = 64 29 | 30 | local function F(X, Y, Z) 31 | return (X & Y) | (~X & Z) 32 | end 33 | 34 | local function G(X, Y, Z) 35 | return (X & Z) | (Y & ~Z) 36 | end 37 | 38 | local function H(X, Y, Z) 39 | return X ~ Y ~ Z 40 | end 41 | 42 | local function I(X, Y, Z) 43 | return Y ~ (X | ~Z) 44 | end 45 | 46 | local function rotate_left(x, n) 47 | return (x << n) | (x >> (32-n)) 48 | end 49 | 50 | local function run_step(f, a, b, c, d, x, s, ac) 51 | return rotate_left(a + f(b, c, d) + x + ac, s) + b 52 | end 53 | 54 | local function transform(A, B, C, D, X) 55 | local a = A 56 | local b = B 57 | local c = C 58 | local d = D 59 | 60 | -- Round 1 61 | a = run_step(F, a, b, c, d, X[1], 7, 0xD76AA478) 62 | d = run_step(F, d, a, b, c, X[2], 12, 0xE8C7B756) 63 | c = run_step(F, c, d, a, b, X[3], 17, 0x242070DB) 64 | b = run_step(F, b, c, d, a, X[4], 22, 0xC1BDCEEE) 65 | a = run_step(F, a, b, c, d, X[5], 7, 0xF57C0FAF) 66 | d = run_step(F, d, a, b, c, X[6], 12, 0x4787C62A) 67 | c = run_step(F, c, d, a, b, X[7], 17, 0xA8304613) 68 | b = run_step(F, b, c, d, a, X[8], 22, 0xFD469501) 69 | a = run_step(F, a, b, c, d, X[9], 7, 0x698098D8) 70 | d = run_step(F, d, a, b, c, X[10], 12, 0x8B44F7AF) 71 | c = run_step(F, c, d, a, b, X[11], 17, 0xFFFF5BB1) 72 | b = run_step(F, b, c, d, a, X[12], 22, 0x895CD7BE) 73 | a = run_step(F, a, b, c, d, X[13], 7, 0x6B901122) 74 | d = run_step(F, d, a, b, c, X[14], 12, 0xFD987193) 75 | c = run_step(F, c, d, a, b, X[15], 17, 0xA679438E) 76 | b = run_step(F, b, c, d, a, X[16], 22, 0x49B40821) 77 | 78 | -- Round 2 79 | a = run_step(G, a, b, c, d, X[2], 5, 0xF61E2562) 80 | d = run_step(G, d, a, b, c, X[7], 9, 0xC040B340) 81 | c = run_step(G, c, d, a, b, X[12], 14, 0x265E5A51) 82 | b = run_step(G, b, c, d, a, X[1], 20, 0xE9B6C7AA) 83 | a = run_step(G, a, b, c, d, X[6], 5, 0xD62F105D) 84 | d = run_step(G, d, a, b, c, X[11], 9, 0x2441453) 85 | c = run_step(G, c, d, a, b, X[16], 14, 0xD8A1E681) 86 | b = run_step(G, b, c, d, a, X[5], 20, 0xE7D3FBC8) 87 | a = run_step(G, a, b, c, d, X[10], 5, 0x21E1CDE6) 88 | d = run_step(G, d, a, b, c, X[15], 9, 0xC33707D6) 89 | c = run_step(G, c, d, a, b, X[4], 14, 0xF4D50D87) 90 | b = run_step(G, b, c, d, a, X[9], 20, 0x455A14ED) 91 | a = run_step(G, a, b, c, d, X[14], 5, 0xA9E3E905) 92 | d = run_step(G, d, a, b, c, X[3], 9, 0xFCEFA3F8) 93 | c = run_step(G, c, d, a, b, X[8], 14, 0x676F02D9) 94 | b = run_step(G, b, c, d, a, X[13], 20, 0x8D2A4C8A) 95 | 96 | -- Round 3 97 | a = run_step(H, a, b, c, d, X[6], 4, 0xFFFA3942) 98 | d = run_step(H, d, a, b, c, X[9], 11, 0x8771F681) 99 | c = run_step(H, c, d, a, b, X[12], 16, 0x6D9D6122) 100 | b = run_step(H, b, c, d, a, X[15], 23, 0xFDE5380C) 101 | a = run_step(H, a, b, c, d, X[2], 4, 0xA4BEEA44) 102 | d = run_step(H, d, a, b, c, X[5], 11, 0x4BDECFA9) 103 | c = run_step(H, c, d, a, b, X[8], 16, 0xF6BB4B60) 104 | b = run_step(H, b, c, d, a, X[11], 23, 0xBEBFBC70) 105 | a = run_step(H, a, b, c, d, X[14], 4, 0x289B7EC6) 106 | d = run_step(H, d, a, b, c, X[1], 11, 0xEAA127FA) 107 | c = run_step(H, c, d, a, b, X[4], 16, 0xD4EF3085) 108 | b = run_step(H, b, c, d, a, X[7], 23, 0x4881D05) 109 | a = run_step(H, a, b, c, d, X[10], 4, 0xD9D4D039) 110 | d = run_step(H, d, a, b, c, X[13], 11, 0xE6DB99E5) 111 | c = run_step(H, c, d, a, b, X[16], 16, 0x1FA27CF8) 112 | b = run_step(H, b, c, d, a, X[3], 23, 0xC4AC5665) 113 | 114 | -- Round 4 115 | a = run_step(I, a, b, c, d, X[1], 6, 0xF4292244) 116 | d = run_step(I, d, a, b, c, X[8], 10, 0x432AFF97) 117 | c = run_step(I, c, d, a, b, X[15], 15, 0xAB9423A7) 118 | b = run_step(I, b, c, d, a, X[6], 21, 0xFC93A039) 119 | a = run_step(I, a, b, c, d, X[13], 6, 0x655B59C3) 120 | d = run_step(I, d, a, b, c, X[4], 10, 0x8F0CCC92) 121 | c = run_step(I, c, d, a, b, X[11], 15, 0xFFEFF47D) 122 | b = run_step(I, b, c, d, a, X[2], 21, 0x85845DD1) 123 | a = run_step(I, a, b, c, d, X[9], 6, 0x6FA87E4F) 124 | d = run_step(I, d, a, b, c, X[16], 10, 0xFE2CE6E0) 125 | c = run_step(I, c, d, a, b, X[7], 15, 0xA3014314) 126 | b = run_step(I, b, c, d, a, X[14], 21, 0x4E0811A1) 127 | a = run_step(I, a, b, c, d, X[5], 6, 0xF7537E82) 128 | d = run_step(I, d, a, b, c, X[12], 10, 0xBD3AF235) 129 | c = run_step(I, c, d, a, b, X[3], 15, 0x2AD7D2BB) 130 | b = run_step(I, b, c, d, a, X[10], 21, 0xEB86D391) 131 | 132 | return a+A, b+B, c+C, d+D 133 | end 134 | 135 | function M:new(data) 136 | if self ~= M then 137 | return nil, "First argument must be self" 138 | end 139 | local o = setmetatable({}, M_mt) 140 | 141 | o._A = u32(0x67452301) 142 | o._B = u32(0xEFCDAB89) 143 | o._C = u32(0x98BADCFE) 144 | o._D = u32(0x10325476) 145 | o._len = 0 146 | o._data = "" 147 | 148 | if data ~= nil then 149 | o:update(data) 150 | end 151 | 152 | return o 153 | end 154 | setmetatable(M, { __call = M.new }) 155 | 156 | function M:copy() 157 | local o = M() 158 | o._A = self._A:copy() 159 | o._B = self._B:copy() 160 | o._C = self._C:copy() 161 | o._D = self._D:copy() 162 | o._data = self._data 163 | o._len = self._len 164 | return o 165 | end 166 | 167 | function M:update(data) 168 | local X 169 | 170 | if data == nil then 171 | data = "" 172 | end 173 | 174 | data = tostring(data) 175 | self._len = self._len + #data 176 | self._data = self._data .. data 177 | 178 | while #self._data >= 64 do 179 | X = {} 180 | for j=1,64,4 do 181 | X[#X+1] = string.byte(self._data, j+3) << 24 | 182 | string.byte(self._data, j+2) << 16 | 183 | string.byte(self._data, j+1) << 8 | 184 | string.byte(self._data, j) 185 | end 186 | self._data = self._data:sub(65, #self._data) 187 | 188 | self._A, self._B, self._C, self._D = transform(self._A, self._B, self._C, self._D, X) 189 | end 190 | end 191 | 192 | function M:digest() 193 | local final 194 | local data 195 | local len = 0 196 | local padlen = 0 197 | 198 | final = self:copy() 199 | 200 | padlen = final._len % 64 201 | if padlen < 56 then 202 | padlen = 56 - padlen 203 | else 204 | padlen = 120 - padlen 205 | end 206 | 207 | len = final._len * 8 208 | data = string.char(1<<7) .. 209 | string.rep(string.char(0), padlen-1) .. 210 | string.char(len & 0xFF) .. 211 | string.char(len >> 8 & 0xFF) .. 212 | string.char(len >> 16 & 0xFF) .. 213 | string.char(len >> 24 & 0xFF) .. 214 | string.char(len >> 32 & 0xFF) .. 215 | string.char(len >> 40 & 0xFF) .. 216 | string.char(len >> 48 & 0xFF) .. 217 | string.char(len >> 56 & 0xFF) 218 | 219 | final:update(data) 220 | 221 | return final._A:swape():asbytestring() .. 222 | final._B:swape():asbytestring() .. 223 | final._C:swape():asbytestring() .. 224 | final._D:swape():asbytestring() 225 | end 226 | 227 | function M:hexdigest() 228 | local h 229 | local out = {} 230 | 231 | h = self:digest() 232 | for i=1,#h do 233 | out[i] = string.format("%02X", string.byte(h, i)) 234 | end 235 | return table.concat(out) 236 | end 237 | 238 | return M 239 | -------------------------------------------------------------------------------- /hashings/pbkdf2.lua: -------------------------------------------------------------------------------- 1 | -- Copyright (c) 2016 John Schember 2 | -- 3 | -- Permission is hereby granted, free of charge, to any person obtaining 4 | -- a copy of this software and associated documentation files (the "Software"), 5 | -- to deal in the Software without restriction, including without limitation 6 | -- the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | -- and/or sell copies of the Software, and to permit persons to whom the 8 | -- Software is furnished to do so, subject to the following conditions: 9 | -- 10 | -- The above copyright notice and this permission notice shall be included in 11 | -- all copies or substantial portions of the Software. 12 | -- 13 | -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | -- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | -- DEALINGS IN THE SOFTWARE. 20 | 21 | local string = require("string") 22 | local u32 = require("nums.uintn").u32 23 | local hmac = require("hashings.hmac") 24 | 25 | local M = {} 26 | 27 | local function sxor(s1, s2) 28 | local b1 = {} 29 | local b2 = {} 30 | local b3 = {} 31 | 32 | for i=1,#s1 do 33 | b1[#b1+1] = string.byte(s1, i) 34 | end 35 | for i=1,#s2 do 36 | b2[#b2+1] = string.byte(s2, i) 37 | end 38 | for i=1,#b1 do 39 | b3[#b3+1] = string.char(b1[i] ~ b2[i]) 40 | end 41 | 42 | return table.concat(b3) 43 | end 44 | 45 | local function hexify(h) 46 | local out = {} 47 | 48 | for i=1,#h do 49 | out[i] = string.format("%02X", string.byte(h, i)) 50 | end 51 | return table.concat(out) 52 | end 53 | 54 | function M:pbkdf2(hm, pass, salt, it) 55 | local u 56 | local t 57 | 58 | u = hmac(hm, pass, salt..u32(1):asbytestring()):digest() 59 | t = u 60 | for i=2,it do 61 | u = hmac(hm, pass, u):digest() 62 | t = sxor(t, u) 63 | end 64 | 65 | return hexify(t) 66 | end 67 | setmetatable(M, { __call = M.pbkdf2 }) 68 | 69 | return M 70 | -------------------------------------------------------------------------------- /hashings/ripemd160.lua: -------------------------------------------------------------------------------- 1 | -- Copyright (c) 2016 John Schember 2 | -- 3 | -- Permission is hereby granted, free of charge, to any person obtaining 4 | -- a copy of this software and associated documentation files (the "Software"), 5 | -- to deal in the Software without restriction, including without limitation 6 | -- the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | -- and/or sell copies of the Software, and to permit persons to whom the 8 | -- Software is furnished to do so, subject to the following conditions: 9 | -- 10 | -- The above copyright notice and this permission notice shall be included in 11 | -- all copies or substantial portions of the Software. 12 | -- 13 | -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | -- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | -- DEALINGS IN THE SOFTWARE. 20 | 21 | local string = require("string") 22 | local u32 = require("nums.uintn").u32 23 | 24 | local M = {} 25 | local M_mt = { __metatable = {}, __index = M } 26 | 27 | M.digest_size = 20 28 | M.block_size = 64 29 | 30 | local function F(X, Y, Z) 31 | return X ~ Y ~ Z 32 | end 33 | 34 | local function G(X, Y, Z) 35 | return (X & Y) | (~X & Z) 36 | end 37 | 38 | local function H(X, Y, Z) 39 | return (X | ~Y) ~ Z 40 | end 41 | 42 | local function I(X, Y, Z) 43 | return (X & Z) | (Y & ~Z) 44 | end 45 | 46 | local function J(X, Y, Z) 47 | return X ~ (Y | ~Z) 48 | end 49 | 50 | local function rotate_left(x, n) 51 | return (x << n) | (x >> (32-n)) 52 | end 53 | 54 | local function run_step(f, a, b, c, d, e, x, s, ac) 55 | a = a + f(b, c, d) + x + ac 56 | a = rotate_left(a, s) + e 57 | return a, rotate_left(c, 10) 58 | end 59 | 60 | local function transform(A, B, C, D, E, X) 61 | local a = A 62 | local b = B 63 | local c = C 64 | local d = D 65 | local e = E 66 | local aa = A 67 | local bb = B 68 | local cc = C 69 | local dd = D 70 | local ee = E 71 | 72 | -- Round 1 73 | a, c = run_step(F, a, b, c, d, e, X[1], 11, 0) 74 | e, b = run_step(F, e, a, b, c, d, X[2], 14, 0) 75 | d, a = run_step(F, d, e, a, b, c, X[3], 15, 0) 76 | c, e = run_step(F, c, d, e, a, b, X[4], 12, 0) 77 | b, d = run_step(F, b, c, d, e, a, X[5], 5, 0) 78 | a, c = run_step(F, a, b, c, d, e, X[6], 8, 0) 79 | e, b = run_step(F, e, a, b, c, d, X[7], 7, 0) 80 | d, a = run_step(F, d, e, a, b, c, X[8], 9, 0) 81 | c, e = run_step(F, c, d, e, a, b, X[9], 11, 0) 82 | b, d = run_step(F, b, c, d, e, a, X[10], 13, 0) 83 | a, c = run_step(F, a, b, c, d, e, X[11], 14, 0) 84 | e, b = run_step(F, e, a, b, c, d, X[12], 15, 0) 85 | d, a = run_step(F, d, e, a, b, c, X[13], 6, 0) 86 | c, e = run_step(F, c, d, e, a, b, X[14], 7, 0) 87 | b, d = run_step(F, b, c, d, e, a, X[15], 9, 0) 88 | a, c = run_step(F, a, b, c, d, e, X[16], 8, 0) 89 | 90 | -- Round 2 91 | e, b = run_step(G, e, a, b, c, d, X[8], 7, 0x5A827999) 92 | d, a = run_step(G, d, e, a, b, c, X[5], 6, 0x5A827999) 93 | c, e = run_step(G, c, d, e, a, b, X[14], 8, 0x5A827999) 94 | b, d = run_step(G, b, c, d, e, a, X[2], 13, 0x5A827999) 95 | a, c = run_step(G, a, b, c, d, e, X[11], 11, 0x5A827999) 96 | e, b = run_step(G, e, a, b, c, d, X[7], 9, 0x5A827999) 97 | d, a = run_step(G, d, e, a, b, c, X[16], 7, 0x5A827999) 98 | c, e = run_step(G, c, d, e, a, b, X[4], 15, 0x5A827999) 99 | b, d = run_step(G, b, c, d, e, a, X[13], 7, 0x5A827999) 100 | a, c = run_step(G, a, b, c, d, e, X[1], 12, 0x5A827999) 101 | e, b = run_step(G, e, a, b, c, d, X[10], 15, 0x5A827999) 102 | d, a = run_step(G, d, e, a, b, c, X[6], 9, 0x5A827999) 103 | c, e = run_step(G, c, d, e, a, b, X[3], 11, 0x5A827999) 104 | b, d = run_step(G, b, c, d, e, a, X[15], 7, 0x5A827999) 105 | a, c = run_step(G, a, b, c, d, e, X[12], 13, 0x5A827999) 106 | e, b = run_step(G, e, a, b, c, d, X[9], 12, 0x5A827999) 107 | 108 | -- Round 3 109 | d, a = run_step(H, d, e, a, b, c, X[4], 11, 0x6ED9EBA1) 110 | c, e = run_step(H, c, d, e, a, b, X[11], 13, 0x6ED9EBA1) 111 | b, d = run_step(H, b, c, d, e, a, X[15], 6, 0x6ED9EBA1) 112 | a, c = run_step(H, a, b, c, d, e, X[5], 7, 0x6ED9EBA1) 113 | e, b = run_step(H, e, a, b, c, d, X[10], 14, 0x6ED9EBA1) 114 | d, a = run_step(H, d, e, a, b, c, X[16], 9, 0x6ED9EBA1) 115 | c, e = run_step(H, c, d, e, a, b, X[9], 13, 0x6ED9EBA1) 116 | b, d = run_step(H, b, c, d, e, a, X[2], 15, 0x6ED9EBA1) 117 | a, c = run_step(H, a, b, c, d, e, X[3], 14, 0x6ED9EBA1) 118 | e, b = run_step(H, e, a, b, c, d, X[8], 8, 0x6ED9EBA1) 119 | d, a = run_step(H, d, e, a, b, c, X[1], 13, 0x6ED9EBA1) 120 | c, e = run_step(H, c, d, e, a, b, X[7], 6, 0x6ED9EBA1) 121 | b, d = run_step(H, b, c, d, e, a, X[14], 5, 0x6ED9EBA1) 122 | a, c = run_step(H, a, b, c, d, e, X[12], 12, 0x6ED9EBA1) 123 | e, b = run_step(H, e, a, b, c, d, X[6], 7, 0x6ED9EBA1) 124 | d, a = run_step(H, d, e, a, b, c, X[13], 5, 0x6ED9EBA1) 125 | 126 | -- Round 4 127 | c, e = run_step(I, c, d, e, a, b, X[2], 11, 0x8F1BBCDC) 128 | b, d = run_step(I, b, c, d, e, a, X[10], 12, 0x8F1BBCDC) 129 | a, c = run_step(I, a, b, c, d, e, X[12], 14, 0x8F1BBCDC) 130 | e, b = run_step(I, e, a, b, c, d, X[11], 15, 0x8F1BBCDC) 131 | d, a = run_step(I, d, e, a, b, c, X[1], 14, 0x8F1BBCDC) 132 | c, e = run_step(I, c, d, e, a, b, X[9], 15, 0x8F1BBCDC) 133 | b, d = run_step(I, b, c, d, e, a, X[13], 9, 0x8F1BBCDC) 134 | a, c = run_step(I, a, b, c, d, e, X[5], 8, 0x8F1BBCDC) 135 | e, b = run_step(I, e, a, b, c, d, X[14], 9, 0x8F1BBCDC) 136 | d, a = run_step(I, d, e, a, b, c, X[4], 14, 0x8F1BBCDC) 137 | c, e = run_step(I, c, d, e, a, b, X[8], 5, 0x8F1BBCDC) 138 | b, d = run_step(I, b, c, d, e, a, X[16], 6, 0x8F1BBCDC) 139 | a, c = run_step(I, a, b, c, d, e, X[15], 8, 0x8F1BBCDC) 140 | e, b = run_step(I, e, a, b, c, d, X[6], 6, 0x8F1BBCDC) 141 | d, a = run_step(I, d, e, a, b, c, X[7], 5, 0x8F1BBCDC) 142 | c, e = run_step(I, c, d, e, a, b, X[3], 12, 0x8F1BBCDC) 143 | 144 | -- Round 5 145 | b, d = run_step(J, b, c, d, e, a, X[5], 9, 0xA953FD4E) 146 | a, c = run_step(J, a, b, c, d, e, X[1], 15, 0xA953FD4E) 147 | e, b = run_step(J, e, a, b, c, d, X[6], 5, 0xA953FD4E) 148 | d, a = run_step(J, d, e, a, b, c, X[10], 11, 0xA953FD4E) 149 | c, e = run_step(J, c, d, e, a, b, X[8], 6, 0xA953FD4E) 150 | b, d = run_step(J, b, c, d, e, a, X[13], 8, 0xA953FD4E) 151 | a, c = run_step(J, a, b, c, d, e, X[3], 13, 0xA953FD4E) 152 | e, b = run_step(J, e, a, b, c, d, X[11], 12, 0xA953FD4E) 153 | d, a = run_step(J, d, e, a, b, c, X[15], 5, 0xA953FD4E) 154 | c, e = run_step(J, c, d, e, a, b, X[2], 12, 0xA953FD4E) 155 | b, d = run_step(J, b, c, d, e, a, X[4], 13, 0xA953FD4E) 156 | a, c = run_step(J, a, b, c, d, e, X[9], 14, 0xA953FD4E) 157 | e, b = run_step(J, e, a, b, c, d, X[12], 11, 0xA953FD4E) 158 | d, a = run_step(J, d, e, a, b, c, X[7], 8, 0xA953FD4E) 159 | c, e = run_step(J, c, d, e, a, b, X[16], 5, 0xA953FD4E) 160 | b, d = run_step(J, b, c, d, e, a, X[14], 6, 0xA953FD4E) 161 | 162 | -- Parallel Round 1 163 | aa, cc = run_step(J, aa, bb, cc, dd, ee, X[6], 8, 0x50A28BE6) 164 | ee, bb = run_step(J, ee, aa, bb, cc, dd, X[15], 9, 0x50A28BE6) 165 | dd, aa = run_step(J, dd, ee, aa, bb, cc, X[8], 9, 0x50A28BE6) 166 | cc, ee = run_step(J, cc, dd, ee, aa, bb, X[1], 11, 0x50A28BE6) 167 | bb, dd = run_step(J, bb, cc, dd, ee, aa, X[10], 13, 0x50A28BE6) 168 | aa, cc = run_step(J, aa, bb, cc, dd, ee, X[3], 15, 0x50A28BE6) 169 | ee, bb = run_step(J, ee, aa, bb, cc, dd, X[12], 15, 0x50A28BE6) 170 | dd, aa = run_step(J, dd, ee, aa, bb, cc, X[5], 5, 0x50A28BE6) 171 | cc, ee = run_step(J, cc, dd, ee, aa, bb, X[14], 7, 0x50A28BE6) 172 | bb, dd = run_step(J, bb, cc, dd, ee, aa, X[7], 7, 0x50A28BE6) 173 | aa, cc = run_step(J, aa, bb, cc, dd, ee, X[16], 8, 0x50A28BE6) 174 | ee, bb = run_step(J, ee, aa, bb, cc, dd, X[9], 11, 0x50A28BE6) 175 | dd, aa = run_step(J, dd, ee, aa, bb, cc, X[2], 14, 0x50A28BE6) 176 | cc, ee = run_step(J, cc, dd, ee, aa, bb, X[11], 14, 0x50A28BE6) 177 | bb, dd = run_step(J, bb, cc, dd, ee, aa, X[4], 12, 0x50A28BE6) 178 | aa, cc = run_step(J, aa, bb, cc, dd, ee, X[13], 6, 0x50A28BE6) 179 | 180 | -- Parallel Round 2 181 | ee, bb = run_step(I, ee, aa, bb, cc, dd, X[7], 9, 0x5C4DD124) 182 | dd, aa = run_step(I, dd, ee, aa, bb, cc, X[12], 13, 0x5C4DD124) 183 | cc, ee = run_step(I, cc, dd, ee, aa, bb, X[4], 15, 0x5C4DD124) 184 | bb, dd = run_step(I, bb, cc, dd, ee, aa, X[8], 7, 0x5C4DD124) 185 | aa, cc = run_step(I, aa, bb, cc, dd, ee, X[1], 12, 0x5C4DD124) 186 | ee, bb = run_step(I, ee, aa, bb, cc, dd, X[14], 8, 0x5C4DD124) 187 | dd, aa = run_step(I, dd, ee, aa, bb, cc, X[6], 9, 0x5C4DD124) 188 | cc, ee = run_step(I, cc, dd, ee, aa, bb, X[11], 11, 0x5C4DD124) 189 | bb, dd = run_step(I, bb, cc, dd, ee, aa, X[15], 7, 0x5C4DD124) 190 | aa, cc = run_step(I, aa, bb, cc, dd, ee, X[16], 7, 0x5C4DD124) 191 | ee, bb = run_step(I, ee, aa, bb, cc, dd, X[9], 12, 0x5C4DD124) 192 | dd, aa = run_step(I, dd, ee, aa, bb, cc, X[13], 7, 0x5C4DD124) 193 | cc, ee = run_step(I, cc, dd, ee, aa, bb, X[5], 6, 0x5C4DD124) 194 | bb, dd = run_step(I, bb, cc, dd, ee, aa, X[10], 15, 0x5C4DD124) 195 | aa, cc = run_step(I, aa, bb, cc, dd, ee, X[2], 13, 0x5C4DD124) 196 | ee, bb = run_step(I, ee, aa, bb, cc, dd, X[3], 11, 0x5C4DD124) 197 | 198 | -- Parallel Round 3 199 | dd, aa = run_step(H, dd, ee, aa, bb, cc, X[16], 9, 0x6D703EF3) 200 | cc, ee = run_step(H, cc, dd, ee, aa, bb, X[6], 7, 0x6D703EF3) 201 | bb, dd = run_step(H, bb, cc, dd, ee, aa, X[2], 15, 0x6D703EF3) 202 | aa, cc = run_step(H, aa, bb, cc, dd, ee, X[4], 11, 0x6D703EF3) 203 | ee, bb = run_step(H, ee, aa, bb, cc, dd, X[8], 8, 0x6D703EF3) 204 | dd, aa = run_step(H, dd, ee, aa, bb, cc, X[15], 6, 0x6D703EF3) 205 | cc, ee = run_step(H, cc, dd, ee, aa, bb, X[7], 6, 0x6D703EF3) 206 | bb, dd = run_step(H, bb, cc, dd, ee, aa, X[10], 14, 0x6D703EF3) 207 | aa, cc = run_step(H, aa, bb, cc, dd, ee, X[12], 12, 0x6D703EF3) 208 | ee, bb = run_step(H, ee, aa, bb, cc, dd, X[9], 13, 0x6D703EF3) 209 | dd, aa = run_step(H, dd, ee, aa, bb, cc, X[13], 5, 0x6D703EF3) 210 | cc, ee = run_step(H, cc, dd, ee, aa, bb, X[3], 14, 0x6D703EF3) 211 | bb, dd = run_step(H, bb, cc, dd, ee, aa, X[11], 13, 0x6D703EF3) 212 | aa, cc = run_step(H, aa, bb, cc, dd, ee, X[1], 13, 0x6D703EF3) 213 | ee, bb = run_step(H, ee, aa, bb, cc, dd, X[5], 7, 0x6D703EF3) 214 | dd, aa = run_step(H, dd, ee, aa, bb, cc, X[14], 5, 0x6D703EF3) 215 | 216 | -- Parallel Round 4 217 | cc, ee = run_step(G, cc, dd, ee, aa, bb, X[9], 15, 0x7A6D76E9) 218 | bb, dd = run_step(G, bb, cc, dd, ee, aa, X[7], 5, 0x7A6D76E9) 219 | aa, cc = run_step(G, aa, bb, cc, dd, ee, X[5], 8, 0x7A6D76E9) 220 | ee, bb = run_step(G, ee, aa, bb, cc, dd, X[2], 11, 0x7A6D76E9) 221 | dd, aa = run_step(G, dd, ee, aa, bb, cc, X[4], 14, 0x7A6D76E9) 222 | cc, ee = run_step(G, cc, dd, ee, aa, bb, X[12], 14, 0x7A6D76E9) 223 | bb, dd = run_step(G, bb, cc, dd, ee, aa, X[16], 6, 0x7A6D76E9) 224 | aa, cc = run_step(G, aa, bb, cc, dd, ee, X[1], 14, 0x7A6D76E9) 225 | ee, bb = run_step(G, ee, aa, bb, cc, dd, X[6], 6, 0x7A6D76E9) 226 | dd, aa = run_step(G, dd, ee, aa, bb, cc, X[13], 9, 0x7A6D76E9) 227 | cc, ee = run_step(G, cc, dd, ee, aa, bb, X[3], 12, 0x7A6D76E9) 228 | bb, dd = run_step(G, bb, cc, dd, ee, aa, X[14], 9, 0x7A6D76E9) 229 | aa, cc = run_step(G, aa, bb, cc, dd, ee, X[10], 12, 0x7A6D76E9) 230 | ee, bb = run_step(G, ee, aa, bb, cc, dd, X[8], 5, 0x7A6D76E9) 231 | dd, aa = run_step(G, dd, ee, aa, bb, cc, X[11], 15, 0x7A6D76E9) 232 | cc, ee = run_step(G, cc, dd, ee, aa, bb, X[15], 8, 0x7A6D76E9) 233 | 234 | -- Parallel Round 5 235 | bb, dd = run_step(F, bb, cc, dd, ee, aa, X[13], 8, 0) 236 | aa, cc = run_step(F, aa, bb, cc, dd, ee, X[16], 5, 0) 237 | ee, bb = run_step(F, ee, aa, bb, cc, dd, X[11], 12, 0) 238 | dd, aa = run_step(F, dd, ee, aa, bb, cc, X[5], 9, 0) 239 | cc, ee = run_step(F, cc, dd, ee, aa, bb, X[2], 12, 0) 240 | bb, dd = run_step(F, bb, cc, dd, ee, aa, X[6], 5, 0) 241 | aa, cc = run_step(F, aa, bb, cc, dd, ee, X[9], 14, 0) 242 | ee, bb = run_step(F, ee, aa, bb, cc, dd, X[8], 6, 0) 243 | dd, aa = run_step(F, dd, ee, aa, bb, cc, X[7], 8, 0) 244 | cc, ee = run_step(F, cc, dd, ee, aa, bb, X[3], 13, 0) 245 | bb, dd = run_step(F, bb, cc, dd, ee, aa, X[14], 6, 0) 246 | aa, cc = run_step(F, aa, bb, cc, dd, ee, X[15], 5, 0) 247 | ee, bb = run_step(F, ee, aa, bb, cc, dd, X[1], 15, 0) 248 | dd, aa = run_step(F, dd, ee, aa, bb, cc, X[4], 13, 0) 249 | cc, ee = run_step(F, cc, dd, ee, aa, bb, X[10], 11, 0) 250 | bb, dd = run_step(F, bb, cc, dd, ee, aa, X[12], 11, 0) 251 | 252 | dd = dd + c + B 253 | return dd, C+d+ee, D+e+aa, E+a+bb, A+b+cc 254 | end 255 | 256 | function M:new(data) 257 | if self ~= M then 258 | return nil, "First argument must be self" 259 | end 260 | local o = setmetatable({}, M_mt) 261 | 262 | o._A = u32(0x67452301) 263 | o._B = u32(0xEFCDAB89) 264 | o._C = u32(0x98BADCFE) 265 | o._D = u32(0x10325476) 266 | o._E = u32(0xC3D2E1F0) 267 | o._len = 0 268 | o._data = "" 269 | 270 | if data ~= nil then 271 | o:update(data) 272 | end 273 | 274 | return o 275 | end 276 | setmetatable(M, { __call = M.new }) 277 | 278 | function M:copy() 279 | local o = M() 280 | o._A = self._A:copy() 281 | o._B = self._B:copy() 282 | o._C = self._C:copy() 283 | o._D = self._D:copy() 284 | o._E = self._E:copy() 285 | o._data = self._data 286 | o._len = self._len 287 | return o 288 | end 289 | 290 | function M:update(data) 291 | local X 292 | 293 | if data == nil then 294 | data = "" 295 | end 296 | 297 | data = tostring(data) 298 | self._len = self._len + #data 299 | self._data = self._data .. data 300 | 301 | while #self._data >= 64 do 302 | X = {} 303 | for j=1,64,4 do 304 | X[#X+1] = string.byte(self._data, j+3) << 24 | 305 | string.byte(self._data, j+2) << 16 | 306 | string.byte(self._data, j+1) << 8 | 307 | string.byte(self._data, j) 308 | end 309 | 310 | self._A, self._B, self._C, self._D, self._E = transform(self._A, self._B, self._C, self._D, self._E, X) 311 | 312 | self._data = self._data:sub(65, #self._data) 313 | end 314 | end 315 | 316 | local function digest_int(cs) 317 | end 318 | 319 | function M:digest() 320 | local final 321 | local data 322 | local len = 0 323 | local padlen = 0 324 | 325 | final = self:copy() 326 | 327 | padlen = final._len % 64 328 | if padlen < 56 then 329 | padlen = 56 - padlen 330 | else 331 | padlen = 120 - padlen 332 | end 333 | 334 | len = final._len * 8 335 | data = string.char(1<<7) .. 336 | string.rep(string.char(0), padlen-1) .. 337 | string.char(len & 0xFF) .. 338 | string.char(len >> 8 & 0xFF) .. 339 | string.char(len >> 16 & 0xFF) .. 340 | string.char(len >> 24 & 0xFF) .. 341 | string.char(len >> 32 & 0xFF) .. 342 | string.char(len >> 40 & 0xFF) .. 343 | string.char(len >> 48 & 0xFF) .. 344 | string.char(len >> 56 & 0xFF) 345 | 346 | final:update(data) 347 | 348 | return final._A:swape():asbytestring() .. 349 | final._B:swape():asbytestring() .. 350 | final._C:swape():asbytestring() .. 351 | final._D:swape():asbytestring() .. 352 | final._E:swape():asbytestring() 353 | end 354 | 355 | function M:hexdigest() 356 | local h 357 | local out = {} 358 | 359 | h = self:digest() 360 | for i=1,#h do 361 | out[i] = string.format("%02X", string.byte(h, i)) 362 | end 363 | return table.concat(out) 364 | end 365 | 366 | return M 367 | -------------------------------------------------------------------------------- /hashings/sha1.lua: -------------------------------------------------------------------------------- 1 | -- Copyright (c) 2016 John Schember 2 | -- 3 | -- Permission is hereby granted, free of charge, to any person obtaining 4 | -- a copy of this software and associated documentation files (the "Software"), 5 | -- to deal in the Software without restriction, including without limitation 6 | -- the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | -- and/or sell copies of the Software, and to permit persons to whom the 8 | -- Software is furnished to do so, subject to the following conditions: 9 | -- 10 | -- The above copyright notice and this permission notice shall be included in 11 | -- all copies or substantial portions of the Software. 12 | -- 13 | -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | -- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | -- DEALINGS IN THE SOFTWARE. 20 | 21 | local string = require("string") 22 | local u32 = require("nums.uintn").u32 23 | 24 | local M = {} 25 | local M_mt = { __metatable = {}, __index = M } 26 | 27 | M.digest_size = 20 28 | M.block_size = 64 29 | 30 | local function rotate_left(x, n) 31 | return (x << n) | (x >> (32-n)) 32 | end 33 | 34 | function M:new(data) 35 | if self ~= M then 36 | return nil, "First argument must be self" 37 | end 38 | local o = setmetatable({}, M_mt) 39 | 40 | o._H0 = u32(0x67452301) 41 | o._H1 = u32(0xEFCDAB89) 42 | o._H2 = u32(0x98BADCFE) 43 | o._H3 = u32(0x10325476) 44 | o._H4 = u32(0xC3D2E1F0) 45 | o._len = 0 46 | o._data = "" 47 | 48 | if data ~= nil then 49 | o:update(data) 50 | end 51 | 52 | return o 53 | end 54 | setmetatable(M, { __call = M.new }) 55 | 56 | function M:copy() 57 | local o = M:new() 58 | o._H0 = self._H0:copy() 59 | o._H1 = self._H1:copy() 60 | o._H2 = self._H2:copy() 61 | o._H3 = self._H3:copy() 62 | o._H4 = self._H4:copy() 63 | o._data = self._data 64 | o._len = self._len 65 | return o 66 | end 67 | 68 | function M:update(data) 69 | local K0 = u32(0x5A827999) 70 | local K1 = u32(0x6ED9EBA1) 71 | local K2 = u32(0x8F1BBCDC) 72 | local K3 = u32(0xCA62C1D6) 73 | local W 74 | local temp 75 | local A 76 | local B 77 | local C 78 | local D 79 | local E 80 | 81 | if data == nil then 82 | data = "" 83 | end 84 | 85 | data = tostring(data) 86 | self._len = self._len + #data 87 | self._data = self._data .. data 88 | 89 | while #self._data >= 64 do 90 | W = {} 91 | for i=1,64,4 do 92 | local j = #W+1 93 | W[j] = u32(string.byte(self._data, i)) << 24 94 | W[j] = W[j] | u32(string.byte(self._data, i+1)) << 16 95 | W[j] = W[j] | u32(string.byte(self._data, i+2)) << 8 96 | W[j] = W[j] | u32(string.byte(self._data, i+3)) 97 | end 98 | 99 | for i=17,80 do 100 | W[i] = rotate_left(W[i-3] ~ W[i-8] ~ W[i-14] ~ W[i-16], 1) 101 | end 102 | 103 | A = self._H0 104 | B = self._H1 105 | C = self._H2 106 | D = self._H3 107 | E = self._H4 108 | 109 | for i=1,20 do 110 | temp = rotate_left(A, 5) + ((B & C) | ((~B) & D)) + E + W[i] + K0 111 | E = D 112 | D = C 113 | C = rotate_left(B, 30) 114 | B = A 115 | A = temp 116 | end 117 | 118 | for i=21,40 do 119 | temp = rotate_left(A, 5) + (B ~ C ~ D) + E + W[i] + K1 120 | E = D 121 | D = C 122 | C = rotate_left(B, 30) 123 | B = A 124 | A = temp 125 | end 126 | 127 | for i=41,60 do 128 | temp = rotate_left(A, 5) + ((B & C) | (B & D) | (C & D)) + E + W[i] + K2 129 | E = D 130 | D = C 131 | C = rotate_left(B, 30) 132 | B = A 133 | A = temp 134 | end 135 | 136 | for i=61,80 do 137 | temp = rotate_left(A, 5) + (B ~ C ~ D) + E + W[i] + K3 138 | E = D 139 | D = C 140 | C = rotate_left(B, 30) 141 | B = A 142 | A = temp 143 | end 144 | 145 | self._H0 = self._H0 + A 146 | self._H1 = self._H1 + B 147 | self._H2 = self._H2 + C 148 | self._H3 = self._H3 + D 149 | self._H4 = self._H4 + E 150 | 151 | self._data = self._data:sub(65, #self._data) 152 | end 153 | end 154 | 155 | function M:digest() 156 | local final 157 | local data 158 | local len = 0 159 | local padlen = 0 160 | 161 | final = self:copy() 162 | 163 | padlen = final._len % 64 164 | if padlen < 56 then 165 | padlen = 56 - padlen 166 | else 167 | padlen = 120 - padlen 168 | end 169 | 170 | len = final._len * 8 171 | data = string.char(1<<7) .. 172 | string.rep(string.char(0), padlen-1) .. 173 | string.char(len >> 56 & 0xFF) .. 174 | string.char(len >> 48 & 0xFF) .. 175 | string.char(len >> 40 & 0xFF) .. 176 | string.char(len >> 32 & 0xFF) .. 177 | string.char(len >> 24 & 0xFF) .. 178 | string.char(len >> 16 & 0xFF) .. 179 | string.char(len >> 8 & 0xFF) .. 180 | string.char(len & 0xFF) 181 | 182 | final:update(data) 183 | 184 | return final._H0:asbytestring() .. 185 | final._H1:asbytestring() .. 186 | final._H2:asbytestring() .. 187 | final._H3:asbytestring() .. 188 | final._H4:asbytestring() 189 | end 190 | 191 | function M:hexdigest() 192 | local h 193 | local out = {} 194 | 195 | h = self:digest() 196 | for i=1,#h do 197 | out[i] = string.format("%02X", string.byte(h, i)) 198 | end 199 | return table.concat(out) 200 | end 201 | 202 | return M 203 | -------------------------------------------------------------------------------- /hashings/sha256.lua: -------------------------------------------------------------------------------- 1 | -- Copyright (c) 2016 John Schember 2 | -- 3 | -- Permission is hereby granted, free of charge, to any person obtaining 4 | -- a copy of this software and associated documentation files (the "Software"), 5 | -- to deal in the Software without restriction, including without limitation 6 | -- the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | -- and/or sell copies of the Software, and to permit persons to whom the 8 | -- Software is furnished to do so, subject to the following conditions: 9 | -- 10 | -- The above copyright notice and this permission notice shall be included in 11 | -- all copies or substantial portions of the Software. 12 | -- 13 | -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | -- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | -- DEALINGS IN THE SOFTWARE. 20 | 21 | local string = require("string") 22 | local u32 = require("nums.uintn").u32 23 | 24 | local M = {} 25 | local M_mt = { __metatable = {}, __index = M } 26 | 27 | M.digest_size = 32 28 | M.block_size = 64 29 | 30 | local K = { 31 | u32(0x428A2F98), u32(0x71374491), u32(0xB5C0FBCF), u32(0xE9B5DBA5), 32 | u32(0x3956C25B), u32(0x59F111F1), u32(0x923F82A4), u32(0xAB1C5ED5), 33 | u32(0xD807AA98), u32(0x12835B01), u32(0x243185BE), u32(0x550C7DC3), 34 | u32(0x72BE5D74), u32(0x80DEB1FE), u32(0x9BDC06A7), u32(0xC19BF174), 35 | u32(0xE49B69C1), u32(0xEFBE4786), u32(0x0FC19DC6), u32(0x240CA1CC), 36 | u32(0x2DE92C6F), u32(0x4A7484AA), u32(0x5CB0A9DC), u32(0x76F988DA), 37 | u32(0x983E5152), u32(0xA831C66D), u32(0xB00327C8), u32(0xBF597FC7), 38 | u32(0xC6E00BF3), u32(0xD5A79147), u32(0x06CA6351), u32(0x14292967), 39 | u32(0x27B70A85), u32(0x2E1B2138), u32(0x4D2C6DFC), u32(0x53380D13), 40 | u32(0x650A7354), u32(0x766A0ABB), u32(0x81C2C92E), u32(0x92722C85), 41 | u32(0xA2BFE8A1), u32(0xA81A664B), u32(0xC24B8B70), u32(0xC76C51A3), 42 | u32(0xD192E819), u32(0xD6990624), u32(0xF40E3585), u32(0x106AA070), 43 | u32(0x19A4C116), u32(0x1E376C08), u32(0x2748774C), u32(0x34B0BCB5), 44 | u32(0x391C0CB3), u32(0x4ED8AA4A), u32(0x5B9CCA4F), u32(0x682E6FF3), 45 | u32(0x748F82EE), u32(0x78A5636F), u32(0x84C87814), u32(0x8CC70208), 46 | u32(0x90BEFFFA), u32(0xA4506CEB), u32(0xBEF9A3F7), u32(0xC67178F2) 47 | } 48 | 49 | local function rotate_right(x, n) 50 | return (x >> n) | (x << (32-n)) 51 | end 52 | 53 | local function CH(x, y, z) 54 | return (x & y) ~ ((~x) & z) 55 | end 56 | 57 | local function MAJ(x, y, z) 58 | return (x & y) ~ ( x & z) ~ (y & z) 59 | end 60 | 61 | local function BSIG0(x) 62 | return rotate_right(x, 2) ~ rotate_right(x, 13) ~ rotate_right(x, 22) 63 | end 64 | 65 | local function BSIG1(x) 66 | return rotate_right(x, 6) ~ rotate_right(x, 11) ~ rotate_right(x, 25) 67 | end 68 | 69 | local function SSIG0(x) 70 | return rotate_right(x, 7) ~ rotate_right(x, 18) ~ (x >> 3) 71 | end 72 | 73 | local function SSIG1(x) 74 | return rotate_right(x, 17) ~ rotate_right(x, 19) ~ (x >> 10) 75 | end 76 | 77 | function M:new(data) 78 | if self ~= M then 79 | return nil, "First argument must be self" 80 | end 81 | local o = setmetatable({}, M_mt) 82 | 83 | o._H0 = u32(0x6A09E667) 84 | o._H1 = u32(0xBB67AE85) 85 | o._H2 = u32(0x3C6EF372) 86 | o._H3 = u32(0xA54FF53A) 87 | o._H4 = u32(0x510E527F) 88 | o._H5 = u32(0x9B05688C) 89 | o._H6 = u32(0x1F83D9AB) 90 | o._H7 = u32(0x5BE0CD19) 91 | o._len = 0 92 | o._data = "" 93 | 94 | if data ~= nil then 95 | o:update(data) 96 | end 97 | 98 | return o 99 | end 100 | setmetatable(M, { __call = M.new }) 101 | 102 | function M:copy() 103 | local o = M:new() 104 | o._H0 = self._H0:copy() 105 | o._H1 = self._H1:copy() 106 | o._H2 = self._H2:copy() 107 | o._H3 = self._H3:copy() 108 | o._H4 = self._H4:copy() 109 | o._H5 = self._H5:copy() 110 | o._H6 = self._H6:copy() 111 | o._H7 = self._H7:copy() 112 | o._data = self._data 113 | o._len = self._len 114 | return o 115 | end 116 | 117 | function M:update(data) 118 | local W 119 | local temp1 120 | local temp2 121 | local a 122 | local b 123 | local c 124 | local d 125 | local e 126 | local f 127 | local g 128 | local h 129 | 130 | if data == nil then 131 | data = "" 132 | end 133 | 134 | data = tostring(data) 135 | self._len = self._len + #data 136 | self._data = self._data .. data 137 | 138 | while #self._data >= 64 do 139 | W = {} 140 | for i=1,64,4 do 141 | local j = #W+1 142 | W[j] = u32(string.byte(self._data, i)) << 24 143 | W[j] = W[j] | u32(string.byte(self._data, i+1)) << 16 144 | W[j] = W[j] | u32(string.byte(self._data, i+2)) << 8 145 | W[j] = W[j] | u32(string.byte(self._data, i+3)) 146 | end 147 | self._data = self._data:sub(65, #self._data) 148 | 149 | for i=17,64 do 150 | W[i] = SSIG1(W[i-2]) + W[i-7] + SSIG0(W[i-15]) + W[i-16] 151 | end 152 | 153 | a = self._H0 154 | b = self._H1 155 | c = self._H2 156 | d = self._H3 157 | e = self._H4 158 | f = self._H5 159 | g = self._H6 160 | h = self._H7 161 | 162 | for i=1,64 do 163 | temp1 = h + BSIG1(e) + CH(e, f, g) + K[i] + W[i] 164 | temp2 = BSIG0(a) + MAJ(a, b, c) 165 | h = g 166 | g = f 167 | f = e 168 | e = d + temp1 169 | d = c 170 | c = b 171 | b = a 172 | a = temp1 + temp2 173 | end 174 | 175 | self._H0 = self._H0 + a 176 | self._H1 = self._H1 + b 177 | self._H2 = self._H2 + c 178 | self._H3 = self._H3 + d 179 | self._H4 = self._H4 + e 180 | self._H5 = self._H5 + f 181 | self._H6 = self._H6 + g 182 | self._H7 = self._H7 + h 183 | end 184 | end 185 | 186 | function M:digest() 187 | local final 188 | local data 189 | local len = 0 190 | local padlen = 0 191 | 192 | final = self:copy() 193 | 194 | padlen = final._len % 64 195 | if padlen < 56 then 196 | padlen = 56 - padlen 197 | else 198 | padlen = 120 - padlen 199 | end 200 | 201 | len = final._len * 8 202 | data = string.char(1<<7) .. 203 | string.rep(string.char(0), padlen-1) .. 204 | string.char(len >> 56 & 0xFF) .. 205 | string.char(len >> 48 & 0xFF) .. 206 | string.char(len >> 40 & 0xFF) .. 207 | string.char(len >> 32 & 0xFF) .. 208 | string.char(len >> 24 & 0xFF) .. 209 | string.char(len >> 16 & 0xFF) .. 210 | string.char(len >> 8 & 0xFF) .. 211 | string.char(len & 0xFF) 212 | 213 | final:update(data) 214 | 215 | return final._H0:asbytestring() .. 216 | final._H1:asbytestring() .. 217 | final._H2:asbytestring() .. 218 | final._H3:asbytestring() .. 219 | final._H4:asbytestring() .. 220 | final._H5:asbytestring() .. 221 | final._H6:asbytestring() .. 222 | final._H7:asbytestring() 223 | end 224 | 225 | function M:hexdigest() 226 | local h 227 | local out = {} 228 | 229 | h = self:digest() 230 | for i=1,#h do 231 | out[i] = string.format("%02X", string.byte(h, i)) 232 | end 233 | return table.concat(out) 234 | end 235 | 236 | return M 237 | -------------------------------------------------------------------------------- /hashings/sha3_256.lua: -------------------------------------------------------------------------------- 1 | -- Copyright (c) 2016 John Schember 2 | -- 3 | -- Permission is hereby granted, free of charge, to any person obtaining 4 | -- a copy of this software and associated documentation files (the "Software"), 5 | -- to deal in the Software without restriction, including without limitation 6 | -- the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | -- and/or sell copies of the Software, and to permit persons to whom the 8 | -- Software is furnished to do so, subject to the following conditions: 9 | -- 10 | -- The above copyright notice and this permission notice shall be included in 11 | -- all copies or substantial portions of the Software. 12 | -- 13 | -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | -- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | -- DEALINGS IN THE SOFTWARE. 20 | 21 | local keccakf1600 = require("hashings.keccak") 22 | 23 | local M = {} 24 | local M_mt = { __metatable = {}, __index = M } 25 | 26 | M.digest_size = 32 27 | M.block_size = 136 28 | 29 | function M:new(data) 30 | return keccakf1600:new(M.block_size, M.digest_size, data) 31 | end 32 | setmetatable(M, { __call = M.new }) 33 | 34 | return M 35 | -------------------------------------------------------------------------------- /hashings/sha3_512.lua: -------------------------------------------------------------------------------- 1 | -- Copyright (c) 2016 John Schember 2 | -- 3 | -- Permission is hereby granted, free of charge, to any person obtaining 4 | -- a copy of this software and associated documentation files (the "Software"), 5 | -- to deal in the Software without restriction, including without limitation 6 | -- the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | -- and/or sell copies of the Software, and to permit persons to whom the 8 | -- Software is furnished to do so, subject to the following conditions: 9 | -- 10 | -- The above copyright notice and this permission notice shall be included in 11 | -- all copies or substantial portions of the Software. 12 | -- 13 | -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | -- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | -- DEALINGS IN THE SOFTWARE. 20 | 21 | local keccakf1600 = require("hashings.keccak") 22 | 23 | local M = {} 24 | local M_mt = { __metatable = {}, __index = M } 25 | 26 | M.digest_size = 64 27 | M.block_size = 72 28 | 29 | function M:new(data) 30 | return keccakf1600:new(M.block_size, M.digest_size, data) 31 | end 32 | setmetatable(M, { __call = M.new }) 33 | 34 | return M 35 | -------------------------------------------------------------------------------- /hashings/sha512.lua: -------------------------------------------------------------------------------- 1 | -- Copyright (c) 2016 John Schember 2 | -- 3 | -- Permission is hereby granted, free of charge, to any person obtaining 4 | -- a copy of this software and associated documentation files (the "Software"), 5 | -- to deal in the Software without restriction, including without limitation 6 | -- the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | -- and/or sell copies of the Software, and to permit persons to whom the 8 | -- Software is furnished to do so, subject to the following conditions: 9 | -- 10 | -- The above copyright notice and this permission notice shall be included in 11 | -- all copies or substantial portions of the Software. 12 | -- 13 | -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | -- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | -- DEALINGS IN THE SOFTWARE. 20 | 21 | local string = require("string") 22 | local u64 = require("nums.uintb").u64 23 | 24 | local M = {} 25 | local M_mt = { __metatable = {}, __index = M } 26 | 27 | M.digest_size = 64 28 | M.block_size = 128 29 | 30 | local K = { 31 | u64("0x428A2F98D728AE22"), u64("0x7137449123EF65CD"), u64("0xB5C0FBCFEC4D3B2F"), u64("0xE9B5DBA58189DBBC"), 32 | u64("0x3956C25BF348B538"), u64("0x59F111F1B605D019"), u64("0x923F82A4AF194F9B"), u64("0xAB1C5ED5DA6D8118"), 33 | u64("0xD807AA98A3030242"), u64("0x12835B0145706FBE"), u64("0x243185BE4EE4B28C"), u64("0x550C7DC3D5FFB4E2"), 34 | u64("0x72BE5D74F27B896F"), u64("0x80DEB1FE3B1696B1"), u64("0x9BDC06A725C71235"), u64("0xC19BF174CF692694"), 35 | u64("0xE49B69C19EF14AD2"), u64("0xEFBE4786384F25E3"), u64("0x0FC19DC68B8CD5B5"), u64("0x240CA1CC77AC9C65"), 36 | u64("0x2DE92C6F592B0275"), u64("0x4A7484AA6EA6E483"), u64("0x5CB0A9DCBD41FBD4"), u64("0x76F988DA831153B5"), 37 | u64("0x983E5152EE66DFAB"), u64("0xA831C66D2DB43210"), u64("0xB00327C898FB213F"), u64("0xBF597FC7BEEF0EE4"), 38 | u64("0xC6E00BF33DA88FC2"), u64("0xD5A79147930AA725"), u64("0x06CA6351E003826F"), u64("0x142929670A0E6E70"), 39 | u64("0x27B70A8546D22FFC"), u64("0x2E1B21385C26C926"), u64("0x4D2C6DFC5AC42AED"), u64("0x53380D139D95B3DF"), 40 | u64("0x650A73548BAF63DE"), u64("0x766A0ABB3C77B2A8"), u64("0x81C2C92E47EDAEE6"), u64("0x92722C851482353B"), 41 | u64("0xA2BFE8A14CF10364"), u64("0xA81A664BBC423001"), u64("0xC24B8B70D0F89791"), u64("0xC76C51A30654BE30"), 42 | u64("0xD192E819D6EF5218"), u64("0xD69906245565A910"), u64("0xF40E35855771202A"), u64("0x106AA07032BBD1B8"), 43 | u64("0x19A4C116B8D2D0C8"), u64("0x1E376C085141AB53"), u64("0x2748774CDF8EEB99"), u64("0x34B0BCB5E19B48A8"), 44 | u64("0x391C0CB3C5C95A63"), u64("0x4ED8AA4AE3418ACB"), u64("0x5B9CCA4F7763E373"), u64("0x682E6FF3D6B2B8A3"), 45 | u64("0x748F82EE5DEFB2FC"), u64("0x78A5636F43172F60"), u64("0x84C87814A1F0AB72"), u64("0x8CC702081A6439EC"), 46 | u64("0x90BEFFFA23631E28"), u64("0xA4506CEBDE82BDE9"), u64("0xBEF9A3F7B2C67915"), u64("0xC67178F2E372532B"), 47 | u64("0xCA273ECEEA26619C"), u64("0xD186B8C721C0C207"), u64("0xEADA7DD6CDE0EB1E"), u64("0xF57D4F7FEE6ED178"), 48 | u64("0x06F067AA72176FBA"), u64("0x0A637DC5A2C898A6"), u64("0x113F9804BEF90DAE"), u64("0x1B710B35131C471B"), 49 | u64("0x28DB77F523047D84"), u64("0x32CAAB7B40C72493"), u64("0x3C9EBE0A15C9BEBC"), u64("0x431D67C49C100D4C"), 50 | u64("0x4CC5D4BECB3E42B6"), u64("0x597F299CFC657E2A"), u64("0x5FCB6FAB3AD6FAEC"), u64("0x6C44198C4A475817") 51 | } 52 | 53 | local function rotate_right(x, n) 54 | return (x >> n) | (x << (64-n)) 55 | end 56 | 57 | local function CH(x, y, z) 58 | return (x & y) ~ ((~x) & z) 59 | end 60 | 61 | local function MAJ(x, y, z) 62 | return (x & y) ~ ( x & z) ~ (y & z) 63 | end 64 | 65 | local function BSIG0(x) 66 | return rotate_right(x, 28) ~ rotate_right(x, 34) ~ rotate_right(x, 39) 67 | end 68 | 69 | local function BSIG1(x) 70 | return rotate_right(x, 14) ~ rotate_right(x, 18) ~ rotate_right(x, 41) 71 | end 72 | 73 | local function SSIG0(x) 74 | return rotate_right(x, 1) ~ rotate_right(x, 8) ~ (x >> 7) 75 | end 76 | 77 | local function SSIG1(x) 78 | return rotate_right(x, 19) ~ rotate_right(x, 61) ~ (x >> 6) 79 | end 80 | 81 | function M:new(data) 82 | if self ~= M then 83 | return nil, "First argument must be self" 84 | end 85 | local o = setmetatable({}, M_mt) 86 | 87 | o._H0 = u64(0x6A09E667F3BCC908) 88 | o._H1 = u64(0xBB67AE8584CAA73B) 89 | o._H2 = u64(0x3C6EF372FE94F82B) 90 | o._H3 = u64(0xA54FF53A5F1D36F1) 91 | o._H4 = u64(0x510E527FADE682D1) 92 | o._H5 = u64(0x9B05688C2B3E6C1F) 93 | o._H6 = u64(0x1F83D9ABFB41BD6B) 94 | o._H7 = u64(0x5BE0CD19137E2179) 95 | o._len = 0 96 | o._data = "" 97 | 98 | if data ~= nil then 99 | o:update(data) 100 | end 101 | 102 | return o 103 | end 104 | setmetatable(M, { __call = M.new }) 105 | 106 | function M:copy() 107 | local o = M:new() 108 | o._H0 = self._H0:copy() 109 | o._H1 = self._H1:copy() 110 | o._H2 = self._H2:copy() 111 | o._H3 = self._H3:copy() 112 | o._H4 = self._H4:copy() 113 | o._H5 = self._H5:copy() 114 | o._H6 = self._H6:copy() 115 | o._H7 = self._H7:copy() 116 | o._data = self._data 117 | o._len = self._len 118 | return o 119 | end 120 | 121 | function M:update(data) 122 | local W 123 | local temp1 124 | local temp2 125 | local a 126 | local b 127 | local c 128 | local d 129 | local e 130 | local f 131 | local g 132 | local h 133 | 134 | if data == nil then 135 | data = "" 136 | end 137 | 138 | data = tostring(data) 139 | self._len = self._len + #data 140 | self._data = self._data .. data 141 | 142 | while #self._data >= 128 do 143 | W = {} 144 | for i=1,128,8 do 145 | local j = #W+1 146 | W[j] = u64(string.byte(self._data, i)) << 56 147 | W[j] = W[j] | u64(string.byte(self._data, i+1)) << 48 148 | W[j] = W[j] | u64(string.byte(self._data, i+2)) << 40 149 | W[j] = W[j] | u64(string.byte(self._data, i+3)) << 32 150 | W[j] = W[j] | u64(string.byte(self._data, i+4)) << 24 151 | W[j] = W[j] | u64(string.byte(self._data, i+5)) << 16 152 | W[j] = W[j] | u64(string.byte(self._data, i+6)) << 8 153 | W[j] = W[j] | u64(string.byte(self._data, i+7)) 154 | end 155 | self._data = self._data:sub(129, #self._data) 156 | 157 | for i=17,80 do 158 | W[i] = SSIG1(W[i-2]) + W[i-7] + SSIG0(W[i-15]) + W[i-16] 159 | end 160 | 161 | a = self._H0 162 | b = self._H1 163 | c = self._H2 164 | d = self._H3 165 | e = self._H4 166 | f = self._H5 167 | g = self._H6 168 | h = self._H7 169 | 170 | for i=1,80 do 171 | temp1 = h + BSIG1(e) + CH(e, f, g) + K[i] + W[i] 172 | temp2 = BSIG0(a) + MAJ(a, b, c) 173 | h = g 174 | g = f 175 | f = e 176 | e = d + temp1 177 | d = c 178 | c = b 179 | b = a 180 | a = temp1 + temp2 181 | end 182 | 183 | self._H0 = self._H0 + a 184 | self._H1 = self._H1 + b 185 | self._H2 = self._H2 + c 186 | self._H3 = self._H3 + d 187 | self._H4 = self._H4 + e 188 | self._H5 = self._H5 + f 189 | self._H6 = self._H6 + g 190 | self._H7 = self._H7 + h 191 | end 192 | end 193 | 194 | function M:digest() 195 | local final 196 | local data 197 | local len = 0 198 | local padlen = 0 199 | 200 | final = self:copy() 201 | 202 | padlen = final._len % 128 203 | if padlen < 112 then 204 | padlen = 112 - padlen 205 | else 206 | padlen = 240 - padlen 207 | end 208 | 209 | len = final._len * 8 210 | data = string.char(1<<7) .. 211 | string.rep(string.char(0), padlen-1) .. 212 | string.char(len >> 120 & 0xFF) .. 213 | string.char(len >> 112 & 0xFF) .. 214 | string.char(len >> 104 & 0xFF) .. 215 | string.char(len >> 96 & 0xFF) .. 216 | string.char(len >> 88 & 0xFF) .. 217 | string.char(len >> 80 & 0xFF) .. 218 | string.char(len >> 72 & 0xFF) .. 219 | string.char(len >> 64 & 0xFF) .. 220 | string.char(len >> 56 & 0xFF) .. 221 | string.char(len >> 48 & 0xFF) .. 222 | string.char(len >> 40 & 0xFF) .. 223 | string.char(len >> 32 & 0xFF) .. 224 | string.char(len >> 24 & 0xFF) .. 225 | string.char(len >> 16 & 0xFF) .. 226 | string.char(len >> 8 & 0xFF) .. 227 | string.char(len & 0xFF) 228 | 229 | final:update(data) 230 | 231 | return final._H0:asbytestring() .. 232 | final._H1:asbytestring() .. 233 | final._H2:asbytestring() .. 234 | final._H3:asbytestring() .. 235 | final._H4:asbytestring() .. 236 | final._H5:asbytestring() .. 237 | final._H6:asbytestring() .. 238 | final._H7:asbytestring() 239 | end 240 | 241 | function M:hexdigest() 242 | local h 243 | local out = {} 244 | 245 | h = self:digest() 246 | for i=1,#h do 247 | out[i] = string.format("%02X", string.byte(h, i)) 248 | end 249 | return table.concat(out) 250 | end 251 | 252 | return M 253 | -------------------------------------------------------------------------------- /hashings/whirlpool.lua: -------------------------------------------------------------------------------- 1 | -- Copyright (c) 2016 John Schember 2 | -- 3 | -- Permission is hereby granted, free of charge, to any person obtaining 4 | -- a copy of this software and associated documentation files (the "Software"), 5 | -- to deal in the Software without restriction, including without limitation 6 | -- the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | -- and/or sell copies of the Software, and to permit persons to whom the 8 | -- Software is furnished to do so, subject to the following conditions: 9 | -- 10 | -- The above copyright notice and this permission notice shall be included in 11 | -- all copies or substantial portions of the Software. 12 | -- 13 | -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | -- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | -- DEALINGS IN THE SOFTWARE. 20 | 21 | local string = require("string") 22 | local u64 = require("nums.uintb").u64 23 | local u256 = require("nums.uintb").u256 24 | local u8 = require("nums.uintn").u8 25 | 26 | local M = {} 27 | local M_mt = { __metatable = {}, __index = M } 28 | 29 | M.digest_size = 64 30 | M.block_size = 64 31 | 32 | local C0 = { 33 | u64("0x18186018C07830D8"), u64("0x23238C2305AF4626"), u64("0xC6C63FC67EF991B8"), u64("0xE8E887E8136FCDFB"), 34 | u64("0x878726874CA113CB"), u64("0xB8B8DAB8A9626D11"), u64("0x0101040108050209"), u64("0x4F4F214F426E9E0D"), 35 | u64("0x3636D836ADEE6C9B"), u64("0xA6A6A2A6590451FF"), u64("0xD2D26FD2DEBDB90C"), u64("0xF5F5F3F5FB06F70E"), 36 | u64("0x7979F979EF80F296"), u64("0x6F6FA16F5FCEDE30"), u64("0x91917E91FCEF3F6D"), u64("0x52525552AA07A4F8"), 37 | u64("0x60609D6027FDC047"), u64("0xBCBCCABC89766535"), u64("0x9B9B569BACCD2B37"), u64("0x8E8E028E048C018A"), 38 | u64("0xA3A3B6A371155BD2"), u64("0x0C0C300C603C186C"), u64("0x7B7BF17BFF8AF684"), u64("0x3535D435B5E16A80"), 39 | u64("0x1D1D741DE8693AF5"), u64("0xE0E0A7E05347DDB3"), u64("0xD7D77BD7F6ACB321"), u64("0xC2C22FC25EED999C"), 40 | u64("0x2E2EB82E6D965C43"), u64("0x4B4B314B627A9629"), u64("0xFEFEDFFEA321E15D"), u64("0x575741578216AED5"), 41 | u64("0x15155415A8412ABD"), u64("0x7777C1779FB6EEE8"), u64("0x3737DC37A5EB6E92"), u64("0xE5E5B3E57B56D79E"), 42 | u64("0x9F9F469F8CD92313"), u64("0xF0F0E7F0D317FD23"), u64("0x4A4A354A6A7F9420"), u64("0xDADA4FDA9E95A944"), 43 | u64("0x58587D58FA25B0A2"), u64("0xC9C903C906CA8FCF"), u64("0x2929A429558D527C"), u64("0x0A0A280A5022145A"), 44 | u64("0xB1B1FEB1E14F7F50"), u64("0xA0A0BAA0691A5DC9"), u64("0x6B6BB16B7FDAD614"), u64("0x85852E855CAB17D9"), 45 | u64("0xBDBDCEBD8173673C"), u64("0x5D5D695DD234BA8F"), u64("0x1010401080502090"), u64("0xF4F4F7F4F303F507"), 46 | u64("0xCBCB0BCB16C08BDD"), u64("0x3E3EF83EEDC67CD3"), u64("0x0505140528110A2D"), u64("0x676781671FE6CE78"), 47 | u64("0xE4E4B7E47353D597"), u64("0x27279C2725BB4E02"), u64("0x4141194132588273"), u64("0x8B8B168B2C9D0BA7"), 48 | u64("0xA7A7A6A7510153F6"), u64("0x7D7DE97DCF94FAB2"), u64("0x95956E95DCFB3749"), u64("0xD8D847D88E9FAD56"), 49 | u64("0xFBFBCBFB8B30EB70"), u64("0xEEEE9FEE2371C1CD"), u64("0x7C7CED7CC791F8BB"), u64("0x6666856617E3CC71"), 50 | u64("0xDDDD53DDA68EA77B"), u64("0x17175C17B84B2EAF"), u64("0x4747014702468E45"), u64("0x9E9E429E84DC211A"), 51 | u64("0xCACA0FCA1EC589D4"), u64("0x2D2DB42D75995A58"), u64("0xBFBFC6BF9179632E"), u64("0x07071C07381B0E3F"), 52 | u64("0xADAD8EAD012347AC"), u64("0x5A5A755AEA2FB4B0"), u64("0x838336836CB51BEF"), u64("0x3333CC3385FF66B6"), 53 | u64("0x636391633FF2C65C"), u64("0x02020802100A0412"), u64("0xAAAA92AA39384993"), u64("0x7171D971AFA8E2DE"), 54 | u64("0xC8C807C80ECF8DC6"), u64("0x19196419C87D32D1"), u64("0x494939497270923B"), u64("0xD9D943D9869AAF5F"), 55 | u64("0xF2F2EFF2C31DF931"), u64("0xE3E3ABE34B48DBA8"), u64("0x5B5B715BE22AB6B9"), u64("0x88881A8834920DBC"), 56 | u64("0x9A9A529AA4C8293E"), u64("0x262698262DBE4C0B"), u64("0x3232C8328DFA64BF"), u64("0xB0B0FAB0E94A7D59"), 57 | u64("0xE9E983E91B6ACFF2"), u64("0x0F0F3C0F78331E77"), u64("0xD5D573D5E6A6B733"), u64("0x80803A8074BA1DF4"), 58 | u64("0xBEBEC2BE997C6127"), u64("0xCDCD13CD26DE87EB"), u64("0x3434D034BDE46889"), u64("0x48483D487A759032"), 59 | u64("0xFFFFDBFFAB24E354"), u64("0x7A7AF57AF78FF48D"), u64("0x90907A90F4EA3D64"), u64("0x5F5F615FC23EBE9D"), 60 | u64("0x202080201DA0403D"), u64("0x6868BD6867D5D00F"), u64("0x1A1A681AD07234CA"), u64("0xAEAE82AE192C41B7"), 61 | u64("0xB4B4EAB4C95E757D"), u64("0x54544D549A19A8CE"), u64("0x93937693ECE53B7F"), u64("0x222288220DAA442F"), 62 | u64("0x64648D6407E9C863"), u64("0xF1F1E3F1DB12FF2A"), u64("0x7373D173BFA2E6CC"), u64("0x12124812905A2482"), 63 | u64("0x40401D403A5D807A"), u64("0x0808200840281048"), u64("0xC3C32BC356E89B95"), u64("0xECEC97EC337BC5DF"), 64 | u64("0xDBDB4BDB9690AB4D"), u64("0xA1A1BEA1611F5FC0"), u64("0x8D8D0E8D1C830791"), u64("0x3D3DF43DF5C97AC8"), 65 | u64("0x97976697CCF1335B"), u64("0x0000000000000000"), u64("0xCFCF1BCF36D483F9"), u64("0x2B2BAC2B4587566E"), 66 | u64("0x7676C57697B3ECE1"), u64("0x8282328264B019E6"), u64("0xD6D67FD6FEA9B128"), u64("0x1B1B6C1BD87736C3"), 67 | u64("0xB5B5EEB5C15B7774"), u64("0xAFAF86AF112943BE"), u64("0x6A6AB56A77DFD41D"), u64("0x50505D50BA0DA0EA"), 68 | u64("0x45450945124C8A57"), u64("0xF3F3EBF3CB18FB38"), u64("0x3030C0309DF060AD"), u64("0xEFEF9BEF2B74C3C4"), 69 | u64("0x3F3FFC3FE5C37EDA"), u64("0x55554955921CAAC7"), u64("0xA2A2B2A2791059DB"), u64("0xEAEA8FEA0365C9E9"), 70 | u64("0x656589650FECCA6A"), u64("0xBABAD2BAB9686903"), u64("0x2F2FBC2F65935E4A"), u64("0xC0C027C04EE79D8E"), 71 | u64("0xDEDE5FDEBE81A160"), u64("0x1C1C701CE06C38FC"), u64("0xFDFDD3FDBB2EE746"), u64("0x4D4D294D52649A1F"), 72 | u64("0x92927292E4E03976"), u64("0x7575C9758FBCEAFA"), u64("0x06061806301E0C36"), u64("0x8A8A128A249809AE"), 73 | u64("0xB2B2F2B2F940794B"), u64("0xE6E6BFE66359D185"), u64("0x0E0E380E70361C7E"), u64("0x1F1F7C1FF8633EE7"), 74 | u64("0x6262956237F7C455"), u64("0xD4D477D4EEA3B53A"), u64("0xA8A89AA829324D81"), u64("0x96966296C4F43152"), 75 | u64("0xF9F9C3F99B3AEF62"), u64("0xC5C533C566F697A3"), u64("0x2525942535B14A10"), u64("0x59597959F220B2AB"), 76 | u64("0x84842A8454AE15D0"), u64("0x7272D572B7A7E4C5"), u64("0x3939E439D5DD72EC"), u64("0x4C4C2D4C5A619816"), 77 | u64("0x5E5E655ECA3BBC94"), u64("0x7878FD78E785F09F"), u64("0x3838E038DDD870E5"), u64("0x8C8C0A8C14860598"), 78 | u64("0xD1D163D1C6B2BF17"), u64("0xA5A5AEA5410B57E4"), u64("0xE2E2AFE2434DD9A1"), u64("0x616199612FF8C24E"), 79 | u64("0xB3B3F6B3F1457B42"), u64("0x2121842115A54234"), u64("0x9C9C4A9C94D62508"), u64("0x1E1E781EF0663CEE"), 80 | u64("0x4343114322528661"), u64("0xC7C73BC776FC93B1"), u64("0xFCFCD7FCB32BE54F"), u64("0x0404100420140824"), 81 | u64("0x51515951B208A2E3"), u64("0x99995E99BCC72F25"), u64("0x6D6DA96D4FC4DA22"), u64("0x0D0D340D68391A65"), 82 | u64("0xFAFACFFA8335E979"), u64("0xDFDF5BDFB684A369"), u64("0x7E7EE57ED79BFCA9"), u64("0x242490243DB44819"), 83 | u64("0x3B3BEC3BC5D776FE"), u64("0xABAB96AB313D4B9A"), u64("0xCECE1FCE3ED181F0"), u64("0x1111441188552299"), 84 | u64("0x8F8F068F0C890383"), u64("0x4E4E254E4A6B9C04"), u64("0xB7B7E6B7D1517366"), u64("0xEBEB8BEB0B60CBE0"), 85 | u64("0x3C3CF03CFDCC78C1"), u64("0x81813E817CBF1FFD"), u64("0x94946A94D4FE3540"), u64("0xF7F7FBF7EB0CF31C"), 86 | u64("0xB9B9DEB9A1676F18"), u64("0x13134C13985F268B"), u64("0x2C2CB02C7D9C5851"), u64("0xD3D36BD3D6B8BB05"), 87 | u64("0xE7E7BBE76B5CD38C"), u64("0x6E6EA56E57CBDC39"), u64("0xC4C437C46EF395AA"), u64("0x03030C03180F061B"), 88 | u64("0x565645568A13ACDC"), u64("0x44440D441A49885E"), u64("0x7F7FE17FDF9EFEA0"), u64("0xA9A99EA921374F88"), 89 | u64("0x2A2AA82A4D825467"), u64("0xBBBBD6BBB16D6B0A"), u64("0xC1C123C146E29F87"), u64("0x53535153A202A6F1"), 90 | u64("0xDCDC57DCAE8BA572"), u64("0x0B0B2C0B58271653"), u64("0x9D9D4E9D9CD32701"), u64("0x6C6CAD6C47C1D82B"), 91 | u64("0x3131C43195F562A4"), u64("0x7474CD7487B9E8F3"), u64("0xF6F6FFF6E309F115"), u64("0x464605460A438C4C"), 92 | u64("0xACAC8AAC092645A5"), u64("0x89891E893C970FB5"), u64("0x14145014A04428B4"), u64("0xE1E1A3E15B42DFBA"), 93 | u64("0x16165816B04E2CA6"), u64("0x3A3AE83ACDD274F7"), u64("0x6969B9696FD0D206"), u64("0x09092409482D1241"), 94 | u64("0x7070DD70A7ADE0D7"), u64("0xB6B6E2B6D954716F"), u64("0xD0D067D0CEB7BD1E"), u64("0xEDED93ED3B7EC7D6"), 95 | u64("0xCCCC17CC2EDB85E2"), u64("0x424215422A578468"), u64("0x98985A98B4C22D2C"), u64("0xA4A4AAA4490E55ED"), 96 | u64("0x2828A0285D885075"), u64("0x5C5C6D5CDA31B886"), u64("0xF8F8C7F8933FED6B"), u64("0x8686228644A411C2") 97 | } 98 | 99 | local C1 = { 100 | u64("0xD818186018C07830"), u64("0x2623238C2305AF46"), u64("0xB8C6C63FC67EF991"), u64("0xFBE8E887E8136FCD"), 101 | u64("0xCB878726874CA113"), u64("0x11B8B8DAB8A9626D"), u64("0x0901010401080502"), u64("0x0D4F4F214F426E9E"), 102 | u64("0x9B3636D836ADEE6C"), u64("0xFFA6A6A2A6590451"), u64("0x0CD2D26FD2DEBDB9"), u64("0x0EF5F5F3F5FB06F7"), 103 | u64("0x967979F979EF80F2"), u64("0x306F6FA16F5FCEDE"), u64("0x6D91917E91FCEF3F"), u64("0xF852525552AA07A4"), 104 | u64("0x4760609D6027FDC0"), u64("0x35BCBCCABC897665"), u64("0x379B9B569BACCD2B"), u64("0x8A8E8E028E048C01"), 105 | u64("0xD2A3A3B6A371155B"), u64("0x6C0C0C300C603C18"), u64("0x847B7BF17BFF8AF6"), u64("0x803535D435B5E16A"), 106 | u64("0xF51D1D741DE8693A"), u64("0xB3E0E0A7E05347DD"), u64("0x21D7D77BD7F6ACB3"), u64("0x9CC2C22FC25EED99"), 107 | u64("0x432E2EB82E6D965C"), u64("0x294B4B314B627A96"), u64("0x5DFEFEDFFEA321E1"), u64("0xD5575741578216AE"), 108 | u64("0xBD15155415A8412A"), u64("0xE87777C1779FB6EE"), u64("0x923737DC37A5EB6E"), u64("0x9EE5E5B3E57B56D7"), 109 | u64("0x139F9F469F8CD923"), u64("0x23F0F0E7F0D317FD"), u64("0x204A4A354A6A7F94"), u64("0x44DADA4FDA9E95A9"), 110 | u64("0xA258587D58FA25B0"), u64("0xCFC9C903C906CA8F"), u64("0x7C2929A429558D52"), u64("0x5A0A0A280A502214"), 111 | u64("0x50B1B1FEB1E14F7F"), u64("0xC9A0A0BAA0691A5D"), u64("0x146B6BB16B7FDAD6"), u64("0xD985852E855CAB17"), 112 | u64("0x3CBDBDCEBD817367"), u64("0x8F5D5D695DD234BA"), u64("0x9010104010805020"), u64("0x07F4F4F7F4F303F5"), 113 | u64("0xDDCBCB0BCB16C08B"), u64("0xD33E3EF83EEDC67C"), u64("0x2D0505140528110A"), u64("0x78676781671FE6CE"), 114 | u64("0x97E4E4B7E47353D5"), u64("0x0227279C2725BB4E"), u64("0x7341411941325882"), u64("0xA78B8B168B2C9D0B"), 115 | u64("0xF6A7A7A6A7510153"), u64("0xB27D7DE97DCF94FA"), u64("0x4995956E95DCFB37"), u64("0x56D8D847D88E9FAD"), 116 | u64("0x70FBFBCBFB8B30EB"), u64("0xCDEEEE9FEE2371C1"), u64("0xBB7C7CED7CC791F8"), u64("0x716666856617E3CC"), 117 | u64("0x7BDDDD53DDA68EA7"), u64("0xAF17175C17B84B2E"), u64("0x454747014702468E"), u64("0x1A9E9E429E84DC21"), 118 | u64("0xD4CACA0FCA1EC589"), u64("0x582D2DB42D75995A"), u64("0x2EBFBFC6BF917963"), u64("0x3F07071C07381B0E"), 119 | u64("0xACADAD8EAD012347"), u64("0xB05A5A755AEA2FB4"), u64("0xEF838336836CB51B"), u64("0xB63333CC3385FF66"), 120 | u64("0x5C636391633FF2C6"), u64("0x1202020802100A04"), u64("0x93AAAA92AA393849"), u64("0xDE7171D971AFA8E2"), 121 | u64("0xC6C8C807C80ECF8D"), u64("0xD119196419C87D32"), u64("0x3B49493949727092"), u64("0x5FD9D943D9869AAF"), 122 | u64("0x31F2F2EFF2C31DF9"), u64("0xA8E3E3ABE34B48DB"), u64("0xB95B5B715BE22AB6"), u64("0xBC88881A8834920D"), 123 | u64("0x3E9A9A529AA4C829"), u64("0x0B262698262DBE4C"), u64("0xBF3232C8328DFA64"), u64("0x59B0B0FAB0E94A7D"), 124 | u64("0xF2E9E983E91B6ACF"), u64("0x770F0F3C0F78331E"), u64("0x33D5D573D5E6A6B7"), u64("0xF480803A8074BA1D"), 125 | u64("0x27BEBEC2BE997C61"), u64("0xEBCDCD13CD26DE87"), u64("0x893434D034BDE468"), u64("0x3248483D487A7590"), 126 | u64("0x54FFFFDBFFAB24E3"), u64("0x8D7A7AF57AF78FF4"), u64("0x6490907A90F4EA3D"), u64("0x9D5F5F615FC23EBE"), 127 | u64("0x3D202080201DA040"), u64("0x0F6868BD6867D5D0"), u64("0xCA1A1A681AD07234"), u64("0xB7AEAE82AE192C41"), 128 | u64("0x7DB4B4EAB4C95E75"), u64("0xCE54544D549A19A8"), u64("0x7F93937693ECE53B"), u64("0x2F222288220DAA44"), 129 | u64("0x6364648D6407E9C8"), u64("0x2AF1F1E3F1DB12FF"), u64("0xCC7373D173BFA2E6"), u64("0x8212124812905A24"), 130 | u64("0x7A40401D403A5D80"), u64("0x4808082008402810"), u64("0x95C3C32BC356E89B"), u64("0xDFECEC97EC337BC5"), 131 | u64("0x4DDBDB4BDB9690AB"), u64("0xC0A1A1BEA1611F5F"), u64("0x918D8D0E8D1C8307"), u64("0xC83D3DF43DF5C97A"), 132 | u64("0x5B97976697CCF133"), u64("0x0000000000000000"), u64("0xF9CFCF1BCF36D483"), u64("0x6E2B2BAC2B458756"), 133 | u64("0xE17676C57697B3EC"), u64("0xE68282328264B019"), u64("0x28D6D67FD6FEA9B1"), u64("0xC31B1B6C1BD87736"), 134 | u64("0x74B5B5EEB5C15B77"), u64("0xBEAFAF86AF112943"), u64("0x1D6A6AB56A77DFD4"), u64("0xEA50505D50BA0DA0"), 135 | u64("0x5745450945124C8A"), u64("0x38F3F3EBF3CB18FB"), u64("0xAD3030C0309DF060"), u64("0xC4EFEF9BEF2B74C3"), 136 | u64("0xDA3F3FFC3FE5C37E"), u64("0xC755554955921CAA"), u64("0xDBA2A2B2A2791059"), u64("0xE9EAEA8FEA0365C9"), 137 | u64("0x6A656589650FECCA"), u64("0x03BABAD2BAB96869"), u64("0x4A2F2FBC2F65935E"), u64("0x8EC0C027C04EE79D"), 138 | u64("0x60DEDE5FDEBE81A1"), u64("0xFC1C1C701CE06C38"), u64("0x46FDFDD3FDBB2EE7"), u64("0x1F4D4D294D52649A"), 139 | u64("0x7692927292E4E039"), u64("0xFA7575C9758FBCEA"), u64("0x3606061806301E0C"), u64("0xAE8A8A128A249809"), 140 | u64("0x4BB2B2F2B2F94079"), u64("0x85E6E6BFE66359D1"), u64("0x7E0E0E380E70361C"), u64("0xE71F1F7C1FF8633E"), 141 | u64("0x556262956237F7C4"), u64("0x3AD4D477D4EEA3B5"), u64("0x81A8A89AA829324D"), u64("0x5296966296C4F431"), 142 | u64("0x62F9F9C3F99B3AEF"), u64("0xA3C5C533C566F697"), u64("0x102525942535B14A"), u64("0xAB59597959F220B2"), 143 | u64("0xD084842A8454AE15"), u64("0xC57272D572B7A7E4"), u64("0xEC3939E439D5DD72"), u64("0x164C4C2D4C5A6198"), 144 | u64("0x945E5E655ECA3BBC"), u64("0x9F7878FD78E785F0"), u64("0xE53838E038DDD870"), u64("0x988C8C0A8C148605"), 145 | u64("0x17D1D163D1C6B2BF"), u64("0xE4A5A5AEA5410B57"), u64("0xA1E2E2AFE2434DD9"), u64("0x4E616199612FF8C2"), 146 | u64("0x42B3B3F6B3F1457B"), u64("0x342121842115A542"), u64("0x089C9C4A9C94D625"), u64("0xEE1E1E781EF0663C"), 147 | u64("0x6143431143225286"), u64("0xB1C7C73BC776FC93"), u64("0x4FFCFCD7FCB32BE5"), u64("0x2404041004201408"), 148 | u64("0xE351515951B208A2"), u64("0x2599995E99BCC72F"), u64("0x226D6DA96D4FC4DA"), u64("0x650D0D340D68391A"), 149 | u64("0x79FAFACFFA8335E9"), u64("0x69DFDF5BDFB684A3"), u64("0xA97E7EE57ED79BFC"), u64("0x19242490243DB448"), 150 | u64("0xFE3B3BEC3BC5D776"), u64("0x9AABAB96AB313D4B"), u64("0xF0CECE1FCE3ED181"), u64("0x9911114411885522"), 151 | u64("0x838F8F068F0C8903"), u64("0x044E4E254E4A6B9C"), u64("0x66B7B7E6B7D15173"), u64("0xE0EBEB8BEB0B60CB"), 152 | u64("0xC13C3CF03CFDCC78"), u64("0xFD81813E817CBF1F"), u64("0x4094946A94D4FE35"), u64("0x1CF7F7FBF7EB0CF3"), 153 | u64("0x18B9B9DEB9A1676F"), u64("0x8B13134C13985F26"), u64("0x512C2CB02C7D9C58"), u64("0x05D3D36BD3D6B8BB"), 154 | u64("0x8CE7E7BBE76B5CD3"), u64("0x396E6EA56E57CBDC"), u64("0xAAC4C437C46EF395"), u64("0x1B03030C03180F06"), 155 | u64("0xDC565645568A13AC"), u64("0x5E44440D441A4988"), u64("0xA07F7FE17FDF9EFE"), u64("0x88A9A99EA921374F"), 156 | u64("0x672A2AA82A4D8254"), u64("0x0ABBBBD6BBB16D6B"), u64("0x87C1C123C146E29F"), u64("0xF153535153A202A6"), 157 | u64("0x72DCDC57DCAE8BA5"), u64("0x530B0B2C0B582716"), u64("0x019D9D4E9D9CD327"), u64("0x2B6C6CAD6C47C1D8"), 158 | u64("0xA43131C43195F562"), u64("0xF37474CD7487B9E8"), u64("0x15F6F6FFF6E309F1"), u64("0x4C464605460A438C"), 159 | u64("0xA5ACAC8AAC092645"), u64("0xB589891E893C970F"), u64("0xB414145014A04428"), u64("0xBAE1E1A3E15B42DF"), 160 | u64("0xA616165816B04E2C"), u64("0xF73A3AE83ACDD274"), u64("0x066969B9696FD0D2"), u64("0x4109092409482D12"), 161 | u64("0xD77070DD70A7ADE0"), u64("0x6FB6B6E2B6D95471"), u64("0x1ED0D067D0CEB7BD"), u64("0xD6EDED93ED3B7EC7"), 162 | u64("0xE2CCCC17CC2EDB85"), u64("0x68424215422A5784"), u64("0x2C98985A98B4C22D"), u64("0xEDA4A4AAA4490E55"), 163 | u64("0x752828A0285D8850"), u64("0x865C5C6D5CDA31B8"), u64("0x6BF8F8C7F8933FED"), u64("0xC28686228644A411") 164 | } 165 | 166 | local C2 = { 167 | u64("0x30D818186018C078"), u64("0x462623238C2305AF"), u64("0x91B8C6C63FC67EF9"), u64("0xCDFBE8E887E8136F"), 168 | u64("0x13CB878726874CA1"), u64("0x6D11B8B8DAB8A962"), u64("0x0209010104010805"), u64("0x9E0D4F4F214F426E"), 169 | u64("0x6C9B3636D836ADEE"), u64("0x51FFA6A6A2A65904"), u64("0xB90CD2D26FD2DEBD"), u64("0xF70EF5F5F3F5FB06"), 170 | u64("0xF2967979F979EF80"), u64("0xDE306F6FA16F5FCE"), u64("0x3F6D91917E91FCEF"), u64("0xA4F852525552AA07"), 171 | u64("0xC04760609D6027FD"), u64("0x6535BCBCCABC8976"), u64("0x2B379B9B569BACCD"), u64("0x018A8E8E028E048C"), 172 | u64("0x5BD2A3A3B6A37115"), u64("0x186C0C0C300C603C"), u64("0xF6847B7BF17BFF8A"), u64("0x6A803535D435B5E1"), 173 | u64("0x3AF51D1D741DE869"), u64("0xDDB3E0E0A7E05347"), u64("0xB321D7D77BD7F6AC"), u64("0x999CC2C22FC25EED"), 174 | u64("0x5C432E2EB82E6D96"), u64("0x96294B4B314B627A"), u64("0xE15DFEFEDFFEA321"), u64("0xAED5575741578216"), 175 | u64("0x2ABD15155415A841"), u64("0xEEE87777C1779FB6"), u64("0x6E923737DC37A5EB"), u64("0xD79EE5E5B3E57B56"), 176 | u64("0x23139F9F469F8CD9"), u64("0xFD23F0F0E7F0D317"), u64("0x94204A4A354A6A7F"), u64("0xA944DADA4FDA9E95"), 177 | u64("0xB0A258587D58FA25"), u64("0x8FCFC9C903C906CA"), u64("0x527C2929A429558D"), u64("0x145A0A0A280A5022"), 178 | u64("0x7F50B1B1FEB1E14F"), u64("0x5DC9A0A0BAA0691A"), u64("0xD6146B6BB16B7FDA"), u64("0x17D985852E855CAB"), 179 | u64("0x673CBDBDCEBD8173"), u64("0xBA8F5D5D695DD234"), u64("0x2090101040108050"), u64("0xF507F4F4F7F4F303"), 180 | u64("0x8BDDCBCB0BCB16C0"), u64("0x7CD33E3EF83EEDC6"), u64("0x0A2D050514052811"), u64("0xCE78676781671FE6"), 181 | u64("0xD597E4E4B7E47353"), u64("0x4E0227279C2725BB"), u64("0x8273414119413258"), u64("0x0BA78B8B168B2C9D"), 182 | u64("0x53F6A7A7A6A75101"), u64("0xFAB27D7DE97DCF94"), u64("0x374995956E95DCFB"), u64("0xAD56D8D847D88E9F"), 183 | u64("0xEB70FBFBCBFB8B30"), u64("0xC1CDEEEE9FEE2371"), u64("0xF8BB7C7CED7CC791"), u64("0xCC716666856617E3"), 184 | u64("0xA77BDDDD53DDA68E"), u64("0x2EAF17175C17B84B"), u64("0x8E45474701470246"), u64("0x211A9E9E429E84DC"), 185 | u64("0x89D4CACA0FCA1EC5"), u64("0x5A582D2DB42D7599"), u64("0x632EBFBFC6BF9179"), u64("0x0E3F07071C07381B"), 186 | u64("0x47ACADAD8EAD0123"), u64("0xB4B05A5A755AEA2F"), u64("0x1BEF838336836CB5"), u64("0x66B63333CC3385FF"), 187 | u64("0xC65C636391633FF2"), u64("0x041202020802100A"), u64("0x4993AAAA92AA3938"), u64("0xE2DE7171D971AFA8"), 188 | u64("0x8DC6C8C807C80ECF"), u64("0x32D119196419C87D"), u64("0x923B494939497270"), u64("0xAF5FD9D943D9869A"), 189 | u64("0xF931F2F2EFF2C31D"), u64("0xDBA8E3E3ABE34B48"), u64("0xB6B95B5B715BE22A"), u64("0x0DBC88881A883492"), 190 | u64("0x293E9A9A529AA4C8"), u64("0x4C0B262698262DBE"), u64("0x64BF3232C8328DFA"), u64("0x7D59B0B0FAB0E94A"), 191 | u64("0xCFF2E9E983E91B6A"), u64("0x1E770F0F3C0F7833"), u64("0xB733D5D573D5E6A6"), u64("0x1DF480803A8074BA"), 192 | u64("0x6127BEBEC2BE997C"), u64("0x87EBCDCD13CD26DE"), u64("0x68893434D034BDE4"), u64("0x903248483D487A75"), 193 | u64("0xE354FFFFDBFFAB24"), u64("0xF48D7A7AF57AF78F"), u64("0x3D6490907A90F4EA"), u64("0xBE9D5F5F615FC23E"), 194 | u64("0x403D202080201DA0"), u64("0xD00F6868BD6867D5"), u64("0x34CA1A1A681AD072"), u64("0x41B7AEAE82AE192C"), 195 | u64("0x757DB4B4EAB4C95E"), u64("0xA8CE54544D549A19"), u64("0x3B7F93937693ECE5"), u64("0x442F222288220DAA"), 196 | u64("0xC86364648D6407E9"), u64("0xFF2AF1F1E3F1DB12"), u64("0xE6CC7373D173BFA2"), u64("0x248212124812905A"), 197 | u64("0x807A40401D403A5D"), u64("0x1048080820084028"), u64("0x9B95C3C32BC356E8"), u64("0xC5DFECEC97EC337B"), 198 | u64("0xAB4DDBDB4BDB9690"), u64("0x5FC0A1A1BEA1611F"), u64("0x07918D8D0E8D1C83"), u64("0x7AC83D3DF43DF5C9"), 199 | u64("0x335B97976697CCF1"), u64("0x0000000000000000"), u64("0x83F9CFCF1BCF36D4"), u64("0x566E2B2BAC2B4587"), 200 | u64("0xECE17676C57697B3"), u64("0x19E68282328264B0"), u64("0xB128D6D67FD6FEA9"), u64("0x36C31B1B6C1BD877"), 201 | u64("0x7774B5B5EEB5C15B"), u64("0x43BEAFAF86AF1129"), u64("0xD41D6A6AB56A77DF"), u64("0xA0EA50505D50BA0D"), 202 | u64("0x8A5745450945124C"), u64("0xFB38F3F3EBF3CB18"), u64("0x60AD3030C0309DF0"), u64("0xC3C4EFEF9BEF2B74"), 203 | u64("0x7EDA3F3FFC3FE5C3"), u64("0xAAC755554955921C"), u64("0x59DBA2A2B2A27910"), u64("0xC9E9EAEA8FEA0365"), 204 | u64("0xCA6A656589650FEC"), u64("0x6903BABAD2BAB968"), u64("0x5E4A2F2FBC2F6593"), u64("0x9D8EC0C027C04EE7"), 205 | u64("0xA160DEDE5FDEBE81"), u64("0x38FC1C1C701CE06C"), u64("0xE746FDFDD3FDBB2E"), u64("0x9A1F4D4D294D5264"), 206 | u64("0x397692927292E4E0"), u64("0xEAFA7575C9758FBC"), u64("0x0C3606061806301E"), u64("0x09AE8A8A128A2498"), 207 | u64("0x794BB2B2F2B2F940"), u64("0xD185E6E6BFE66359"), u64("0x1C7E0E0E380E7036"), u64("0x3EE71F1F7C1FF863"), 208 | u64("0xC4556262956237F7"), u64("0xB53AD4D477D4EEA3"), u64("0x4D81A8A89AA82932"), u64("0x315296966296C4F4"), 209 | u64("0xEF62F9F9C3F99B3A"), u64("0x97A3C5C533C566F6"), u64("0x4A102525942535B1"), u64("0xB2AB59597959F220"), 210 | u64("0x15D084842A8454AE"), u64("0xE4C57272D572B7A7"), u64("0x72EC3939E439D5DD"), u64("0x98164C4C2D4C5A61"), 211 | u64("0xBC945E5E655ECA3B"), u64("0xF09F7878FD78E785"), u64("0x70E53838E038DDD8"), u64("0x05988C8C0A8C1486"), 212 | u64("0xBF17D1D163D1C6B2"), u64("0x57E4A5A5AEA5410B"), u64("0xD9A1E2E2AFE2434D"), u64("0xC24E616199612FF8"), 213 | u64("0x7B42B3B3F6B3F145"), u64("0x42342121842115A5"), u64("0x25089C9C4A9C94D6"), u64("0x3CEE1E1E781EF066"), 214 | u64("0x8661434311432252"), u64("0x93B1C7C73BC776FC"), u64("0xE54FFCFCD7FCB32B"), u64("0x0824040410042014"), 215 | u64("0xA2E351515951B208"), u64("0x2F2599995E99BCC7"), u64("0xDA226D6DA96D4FC4"), u64("0x1A650D0D340D6839"), 216 | u64("0xE979FAFACFFA8335"), u64("0xA369DFDF5BDFB684"), u64("0xFCA97E7EE57ED79B"), u64("0x4819242490243DB4"), 217 | u64("0x76FE3B3BEC3BC5D7"), u64("0x4B9AABAB96AB313D"), u64("0x81F0CECE1FCE3ED1"), u64("0x2299111144118855"), 218 | u64("0x03838F8F068F0C89"), u64("0x9C044E4E254E4A6B"), u64("0x7366B7B7E6B7D151"), u64("0xCBE0EBEB8BEB0B60"), 219 | u64("0x78C13C3CF03CFDCC"), u64("0x1FFD81813E817CBF"), u64("0x354094946A94D4FE"), u64("0xF31CF7F7FBF7EB0C"), 220 | u64("0x6F18B9B9DEB9A167"), u64("0x268B13134C13985F"), u64("0x58512C2CB02C7D9C"), u64("0xBB05D3D36BD3D6B8"), 221 | u64("0xD38CE7E7BBE76B5C"), u64("0xDC396E6EA56E57CB"), u64("0x95AAC4C437C46EF3"), u64("0x061B03030C03180F"), 222 | u64("0xACDC565645568A13"), u64("0x885E44440D441A49"), u64("0xFEA07F7FE17FDF9E"), u64("0x4F88A9A99EA92137"), 223 | u64("0x54672A2AA82A4D82"), u64("0x6B0ABBBBD6BBB16D"), u64("0x9F87C1C123C146E2"), u64("0xA6F153535153A202"), 224 | u64("0xA572DCDC57DCAE8B"), u64("0x16530B0B2C0B5827"), u64("0x27019D9D4E9D9CD3"), u64("0xD82B6C6CAD6C47C1"), 225 | u64("0x62A43131C43195F5"), u64("0xE8F37474CD7487B9"), u64("0xF115F6F6FFF6E309"), u64("0x8C4C464605460A43"), 226 | u64("0x45A5ACAC8AAC0926"), u64("0x0FB589891E893C97"), u64("0x28B414145014A044"), u64("0xDFBAE1E1A3E15B42"), 227 | u64("0x2CA616165816B04E"), u64("0x74F73A3AE83ACDD2"), u64("0xD2066969B9696FD0"), u64("0x124109092409482D"), 228 | u64("0xE0D77070DD70A7AD"), u64("0x716FB6B6E2B6D954"), u64("0xBD1ED0D067D0CEB7"), u64("0xC7D6EDED93ED3B7E"), 229 | u64("0x85E2CCCC17CC2EDB"), u64("0x8468424215422A57"), u64("0x2D2C98985A98B4C2"), u64("0x55EDA4A4AAA4490E"), 230 | u64("0x50752828A0285D88"), u64("0xB8865C5C6D5CDA31"), u64("0xED6BF8F8C7F8933F"), u64("0x11C28686228644A4") 231 | } 232 | 233 | local C3 = { 234 | u64("0x7830D818186018C0"), u64("0xAF462623238C2305"), u64("0xF991B8C6C63FC67E"), u64("0x6FCDFBE8E887E813"), 235 | u64("0xA113CB878726874C"), u64("0x626D11B8B8DAB8A9"), u64("0x0502090101040108"), u64("0x6E9E0D4F4F214F42"), 236 | u64("0xEE6C9B3636D836AD"), u64("0x0451FFA6A6A2A659"), u64("0xBDB90CD2D26FD2DE"), u64("0x06F70EF5F5F3F5FB"), 237 | u64("0x80F2967979F979EF"), u64("0xCEDE306F6FA16F5F"), u64("0xEF3F6D91917E91FC"), u64("0x07A4F852525552AA"), 238 | u64("0xFDC04760609D6027"), u64("0x766535BCBCCABC89"), u64("0xCD2B379B9B569BAC"), u64("0x8C018A8E8E028E04"), 239 | u64("0x155BD2A3A3B6A371"), u64("0x3C186C0C0C300C60"), u64("0x8AF6847B7BF17BFF"), u64("0xE16A803535D435B5"), 240 | u64("0x693AF51D1D741DE8"), u64("0x47DDB3E0E0A7E053"), u64("0xACB321D7D77BD7F6"), u64("0xED999CC2C22FC25E"), 241 | u64("0x965C432E2EB82E6D"), u64("0x7A96294B4B314B62"), u64("0x21E15DFEFEDFFEA3"), u64("0x16AED55757415782"), 242 | u64("0x412ABD15155415A8"), u64("0xB6EEE87777C1779F"), u64("0xEB6E923737DC37A5"), u64("0x56D79EE5E5B3E57B"), 243 | u64("0xD923139F9F469F8C"), u64("0x17FD23F0F0E7F0D3"), u64("0x7F94204A4A354A6A"), u64("0x95A944DADA4FDA9E"), 244 | u64("0x25B0A258587D58FA"), u64("0xCA8FCFC9C903C906"), u64("0x8D527C2929A42955"), u64("0x22145A0A0A280A50"), 245 | u64("0x4F7F50B1B1FEB1E1"), u64("0x1A5DC9A0A0BAA069"), u64("0xDAD6146B6BB16B7F"), u64("0xAB17D985852E855C"), 246 | u64("0x73673CBDBDCEBD81"), u64("0x34BA8F5D5D695DD2"), u64("0x5020901010401080"), u64("0x03F507F4F4F7F4F3"), 247 | u64("0xC08BDDCBCB0BCB16"), u64("0xC67CD33E3EF83EED"), u64("0x110A2D0505140528"), u64("0xE6CE78676781671F"), 248 | u64("0x53D597E4E4B7E473"), u64("0xBB4E0227279C2725"), u64("0x5882734141194132"), u64("0x9D0BA78B8B168B2C"), 249 | u64("0x0153F6A7A7A6A751"), u64("0x94FAB27D7DE97DCF"), u64("0xFB374995956E95DC"), u64("0x9FAD56D8D847D88E"), 250 | u64("0x30EB70FBFBCBFB8B"), u64("0x71C1CDEEEE9FEE23"), u64("0x91F8BB7C7CED7CC7"), u64("0xE3CC716666856617"), 251 | u64("0x8EA77BDDDD53DDA6"), u64("0x4B2EAF17175C17B8"), u64("0x468E454747014702"), u64("0xDC211A9E9E429E84"), 252 | u64("0xC589D4CACA0FCA1E"), u64("0x995A582D2DB42D75"), u64("0x79632EBFBFC6BF91"), u64("0x1B0E3F07071C0738"), 253 | u64("0x2347ACADAD8EAD01"), u64("0x2FB4B05A5A755AEA"), u64("0xB51BEF838336836C"), u64("0xFF66B63333CC3385"), 254 | u64("0xF2C65C636391633F"), u64("0x0A04120202080210"), u64("0x384993AAAA92AA39"), u64("0xA8E2DE7171D971AF"), 255 | u64("0xCF8DC6C8C807C80E"), u64("0x7D32D119196419C8"), u64("0x70923B4949394972"), u64("0x9AAF5FD9D943D986"), 256 | u64("0x1DF931F2F2EFF2C3"), u64("0x48DBA8E3E3ABE34B"), u64("0x2AB6B95B5B715BE2"), u64("0x920DBC88881A8834"), 257 | u64("0xC8293E9A9A529AA4"), u64("0xBE4C0B262698262D"), u64("0xFA64BF3232C8328D"), u64("0x4A7D59B0B0FAB0E9"), 258 | u64("0x6ACFF2E9E983E91B"), u64("0x331E770F0F3C0F78"), u64("0xA6B733D5D573D5E6"), u64("0xBA1DF480803A8074"), 259 | u64("0x7C6127BEBEC2BE99"), u64("0xDE87EBCDCD13CD26"), u64("0xE468893434D034BD"), u64("0x75903248483D487A"), 260 | u64("0x24E354FFFFDBFFAB"), u64("0x8FF48D7A7AF57AF7"), u64("0xEA3D6490907A90F4"), u64("0x3EBE9D5F5F615FC2"), 261 | u64("0xA0403D202080201D"), u64("0xD5D00F6868BD6867"), u64("0x7234CA1A1A681AD0"), u64("0x2C41B7AEAE82AE19"), 262 | u64("0x5E757DB4B4EAB4C9"), u64("0x19A8CE54544D549A"), u64("0xE53B7F93937693EC"), u64("0xAA442F222288220D"), 263 | u64("0xE9C86364648D6407"), u64("0x12FF2AF1F1E3F1DB"), u64("0xA2E6CC7373D173BF"), u64("0x5A24821212481290"), 264 | u64("0x5D807A40401D403A"), u64("0x2810480808200840"), u64("0xE89B95C3C32BC356"), u64("0x7BC5DFECEC97EC33"), 265 | u64("0x90AB4DDBDB4BDB96"), u64("0x1F5FC0A1A1BEA161"), u64("0x8307918D8D0E8D1C"), u64("0xC97AC83D3DF43DF5"), 266 | u64("0xF1335B97976697CC"), u64("0x0000000000000000"), u64("0xD483F9CFCF1BCF36"), u64("0x87566E2B2BAC2B45"), 267 | u64("0xB3ECE17676C57697"), u64("0xB019E68282328264"), u64("0xA9B128D6D67FD6FE"), u64("0x7736C31B1B6C1BD8"), 268 | u64("0x5B7774B5B5EEB5C1"), u64("0x2943BEAFAF86AF11"), u64("0xDFD41D6A6AB56A77"), u64("0x0DA0EA50505D50BA"), 269 | u64("0x4C8A574545094512"), u64("0x18FB38F3F3EBF3CB"), u64("0xF060AD3030C0309D"), u64("0x74C3C4EFEF9BEF2B"), 270 | u64("0xC37EDA3F3FFC3FE5"), u64("0x1CAAC75555495592"), u64("0x1059DBA2A2B2A279"), u64("0x65C9E9EAEA8FEA03"), 271 | u64("0xECCA6A656589650F"), u64("0x686903BABAD2BAB9"), u64("0x935E4A2F2FBC2F65"), u64("0xE79D8EC0C027C04E"), 272 | u64("0x81A160DEDE5FDEBE"), u64("0x6C38FC1C1C701CE0"), u64("0x2EE746FDFDD3FDBB"), u64("0x649A1F4D4D294D52"), 273 | u64("0xE0397692927292E4"), u64("0xBCEAFA7575C9758F"), u64("0x1E0C360606180630"), u64("0x9809AE8A8A128A24"), 274 | u64("0x40794BB2B2F2B2F9"), u64("0x59D185E6E6BFE663"), u64("0x361C7E0E0E380E70"), u64("0x633EE71F1F7C1FF8"), 275 | u64("0xF7C4556262956237"), u64("0xA3B53AD4D477D4EE"), u64("0x324D81A8A89AA829"), u64("0xF4315296966296C4"), 276 | u64("0x3AEF62F9F9C3F99B"), u64("0xF697A3C5C533C566"), u64("0xB14A102525942535"), u64("0x20B2AB59597959F2"), 277 | u64("0xAE15D084842A8454"), u64("0xA7E4C57272D572B7"), u64("0xDD72EC3939E439D5"), u64("0x6198164C4C2D4C5A"), 278 | u64("0x3BBC945E5E655ECA"), u64("0x85F09F7878FD78E7"), u64("0xD870E53838E038DD"), u64("0x8605988C8C0A8C14"), 279 | u64("0xB2BF17D1D163D1C6"), u64("0x0B57E4A5A5AEA541"), u64("0x4DD9A1E2E2AFE243"), u64("0xF8C24E616199612F"), 280 | u64("0x457B42B3B3F6B3F1"), u64("0xA542342121842115"), u64("0xD625089C9C4A9C94"), u64("0x663CEE1E1E781EF0"), 281 | u64("0x5286614343114322"), u64("0xFC93B1C7C73BC776"), u64("0x2BE54FFCFCD7FCB3"), u64("0x1408240404100420"), 282 | u64("0x08A2E351515951B2"), u64("0xC72F2599995E99BC"), u64("0xC4DA226D6DA96D4F"), u64("0x391A650D0D340D68"), 283 | u64("0x35E979FAFACFFA83"), u64("0x84A369DFDF5BDFB6"), u64("0x9BFCA97E7EE57ED7"), u64("0xB44819242490243D"), 284 | u64("0xD776FE3B3BEC3BC5"), u64("0x3D4B9AABAB96AB31"), u64("0xD181F0CECE1FCE3E"), u64("0x5522991111441188"), 285 | u64("0x8903838F8F068F0C"), u64("0x6B9C044E4E254E4A"), u64("0x517366B7B7E6B7D1"), u64("0x60CBE0EBEB8BEB0B"), 286 | u64("0xCC78C13C3CF03CFD"), u64("0xBF1FFD81813E817C"), u64("0xFE354094946A94D4"), u64("0x0CF31CF7F7FBF7EB"), 287 | u64("0x676F18B9B9DEB9A1"), u64("0x5F268B13134C1398"), u64("0x9C58512C2CB02C7D"), u64("0xB8BB05D3D36BD3D6"), 288 | u64("0x5CD38CE7E7BBE76B"), u64("0xCBDC396E6EA56E57"), u64("0xF395AAC4C437C46E"), u64("0x0F061B03030C0318"), 289 | u64("0x13ACDC565645568A"), u64("0x49885E44440D441A"), u64("0x9EFEA07F7FE17FDF"), u64("0x374F88A9A99EA921"), 290 | u64("0x8254672A2AA82A4D"), u64("0x6D6B0ABBBBD6BBB1"), u64("0xE29F87C1C123C146"), u64("0x02A6F153535153A2"), 291 | u64("0x8BA572DCDC57DCAE"), u64("0x2716530B0B2C0B58"), u64("0xD327019D9D4E9D9C"), u64("0xC1D82B6C6CAD6C47"), 292 | u64("0xF562A43131C43195"), u64("0xB9E8F37474CD7487"), u64("0x09F115F6F6FFF6E3"), u64("0x438C4C464605460A"), 293 | u64("0x2645A5ACAC8AAC09"), u64("0x970FB589891E893C"), u64("0x4428B414145014A0"), u64("0x42DFBAE1E1A3E15B"), 294 | u64("0x4E2CA616165816B0"), u64("0xD274F73A3AE83ACD"), u64("0xD0D2066969B9696F"), u64("0x2D12410909240948"), 295 | u64("0xADE0D77070DD70A7"), u64("0x54716FB6B6E2B6D9"), u64("0xB7BD1ED0D067D0CE"), u64("0x7EC7D6EDED93ED3B"), 296 | u64("0xDB85E2CCCC17CC2E"), u64("0x578468424215422A"), u64("0xC22D2C98985A98B4"), u64("0x0E55EDA4A4AAA449"), 297 | u64("0x8850752828A0285D"), u64("0x31B8865C5C6D5CDA"), u64("0x3FED6BF8F8C7F893"), u64("0xA411C28686228644") 298 | } 299 | 300 | local C4 = { 301 | u64("0xC07830D818186018"), u64("0x05AF462623238C23"), u64("0x7EF991B8C6C63FC6"), u64("0x136FCDFBE8E887E8"), 302 | u64("0x4CA113CB87872687"), u64("0xA9626D11B8B8DAB8"), u64("0x0805020901010401"), u64("0x426E9E0D4F4F214F"), 303 | u64("0xADEE6C9B3636D836"), u64("0x590451FFA6A6A2A6"), u64("0xDEBDB90CD2D26FD2"), u64("0xFB06F70EF5F5F3F5"), 304 | u64("0xEF80F2967979F979"), u64("0x5FCEDE306F6FA16F"), u64("0xFCEF3F6D91917E91"), u64("0xAA07A4F852525552"), 305 | u64("0x27FDC04760609D60"), u64("0x89766535BCBCCABC"), u64("0xACCD2B379B9B569B"), u64("0x048C018A8E8E028E"), 306 | u64("0x71155BD2A3A3B6A3"), u64("0x603C186C0C0C300C"), u64("0xFF8AF6847B7BF17B"), u64("0xB5E16A803535D435"), 307 | u64("0xE8693AF51D1D741D"), u64("0x5347DDB3E0E0A7E0"), u64("0xF6ACB321D7D77BD7"), u64("0x5EED999CC2C22FC2"), 308 | u64("0x6D965C432E2EB82E"), u64("0x627A96294B4B314B"), u64("0xA321E15DFEFEDFFE"), u64("0x8216AED557574157"), 309 | u64("0xA8412ABD15155415"), u64("0x9FB6EEE87777C177"), u64("0xA5EB6E923737DC37"), u64("0x7B56D79EE5E5B3E5"), 310 | u64("0x8CD923139F9F469F"), u64("0xD317FD23F0F0E7F0"), u64("0x6A7F94204A4A354A"), u64("0x9E95A944DADA4FDA"), 311 | u64("0xFA25B0A258587D58"), u64("0x06CA8FCFC9C903C9"), u64("0x558D527C2929A429"), u64("0x5022145A0A0A280A"), 312 | u64("0xE14F7F50B1B1FEB1"), u64("0x691A5DC9A0A0BAA0"), u64("0x7FDAD6146B6BB16B"), u64("0x5CAB17D985852E85"), 313 | u64("0x8173673CBDBDCEBD"), u64("0xD234BA8F5D5D695D"), u64("0x8050209010104010"), u64("0xF303F507F4F4F7F4"), 314 | u64("0x16C08BDDCBCB0BCB"), u64("0xEDC67CD33E3EF83E"), u64("0x28110A2D05051405"), u64("0x1FE6CE7867678167"), 315 | u64("0x7353D597E4E4B7E4"), u64("0x25BB4E0227279C27"), u64("0x3258827341411941"), u64("0x2C9D0BA78B8B168B"), 316 | u64("0x510153F6A7A7A6A7"), u64("0xCF94FAB27D7DE97D"), u64("0xDCFB374995956E95"), u64("0x8E9FAD56D8D847D8"), 317 | u64("0x8B30EB70FBFBCBFB"), u64("0x2371C1CDEEEE9FEE"), u64("0xC791F8BB7C7CED7C"), u64("0x17E3CC7166668566"), 318 | u64("0xA68EA77BDDDD53DD"), u64("0xB84B2EAF17175C17"), u64("0x02468E4547470147"), u64("0x84DC211A9E9E429E"), 319 | u64("0x1EC589D4CACA0FCA"), u64("0x75995A582D2DB42D"), u64("0x9179632EBFBFC6BF"), u64("0x381B0E3F07071C07"), 320 | u64("0x012347ACADAD8EAD"), u64("0xEA2FB4B05A5A755A"), u64("0x6CB51BEF83833683"), u64("0x85FF66B63333CC33"), 321 | u64("0x3FF2C65C63639163"), u64("0x100A041202020802"), u64("0x39384993AAAA92AA"), u64("0xAFA8E2DE7171D971"), 322 | u64("0x0ECF8DC6C8C807C8"), u64("0xC87D32D119196419"), u64("0x7270923B49493949"), u64("0x869AAF5FD9D943D9"), 323 | u64("0xC31DF931F2F2EFF2"), u64("0x4B48DBA8E3E3ABE3"), u64("0xE22AB6B95B5B715B"), u64("0x34920DBC88881A88"), 324 | u64("0xA4C8293E9A9A529A"), u64("0x2DBE4C0B26269826"), u64("0x8DFA64BF3232C832"), u64("0xE94A7D59B0B0FAB0"), 325 | u64("0x1B6ACFF2E9E983E9"), u64("0x78331E770F0F3C0F"), u64("0xE6A6B733D5D573D5"), u64("0x74BA1DF480803A80"), 326 | u64("0x997C6127BEBEC2BE"), u64("0x26DE87EBCDCD13CD"), u64("0xBDE468893434D034"), u64("0x7A75903248483D48"), 327 | u64("0xAB24E354FFFFDBFF"), u64("0xF78FF48D7A7AF57A"), u64("0xF4EA3D6490907A90"), u64("0xC23EBE9D5F5F615F"), 328 | u64("0x1DA0403D20208020"), u64("0x67D5D00F6868BD68"), u64("0xD07234CA1A1A681A"), u64("0x192C41B7AEAE82AE"), 329 | u64("0xC95E757DB4B4EAB4"), u64("0x9A19A8CE54544D54"), u64("0xECE53B7F93937693"), u64("0x0DAA442F22228822"), 330 | u64("0x07E9C86364648D64"), u64("0xDB12FF2AF1F1E3F1"), u64("0xBFA2E6CC7373D173"), u64("0x905A248212124812"), 331 | u64("0x3A5D807A40401D40"), u64("0x4028104808082008"), u64("0x56E89B95C3C32BC3"), u64("0x337BC5DFECEC97EC"), 332 | u64("0x9690AB4DDBDB4BDB"), u64("0x611F5FC0A1A1BEA1"), u64("0x1C8307918D8D0E8D"), u64("0xF5C97AC83D3DF43D"), 333 | u64("0xCCF1335B97976697"), u64("0x0000000000000000"), u64("0x36D483F9CFCF1BCF"), u64("0x4587566E2B2BAC2B"), 334 | u64("0x97B3ECE17676C576"), u64("0x64B019E682823282"), u64("0xFEA9B128D6D67FD6"), u64("0xD87736C31B1B6C1B"), 335 | u64("0xC15B7774B5B5EEB5"), u64("0x112943BEAFAF86AF"), u64("0x77DFD41D6A6AB56A"), u64("0xBA0DA0EA50505D50"), 336 | u64("0x124C8A5745450945"), u64("0xCB18FB38F3F3EBF3"), u64("0x9DF060AD3030C030"), u64("0x2B74C3C4EFEF9BEF"), 337 | u64("0xE5C37EDA3F3FFC3F"), u64("0x921CAAC755554955"), u64("0x791059DBA2A2B2A2"), u64("0x0365C9E9EAEA8FEA"), 338 | u64("0x0FECCA6A65658965"), u64("0xB9686903BABAD2BA"), u64("0x65935E4A2F2FBC2F"), u64("0x4EE79D8EC0C027C0"), 339 | u64("0xBE81A160DEDE5FDE"), u64("0xE06C38FC1C1C701C"), u64("0xBB2EE746FDFDD3FD"), u64("0x52649A1F4D4D294D"), 340 | u64("0xE4E0397692927292"), u64("0x8FBCEAFA7575C975"), u64("0x301E0C3606061806"), u64("0x249809AE8A8A128A"), 341 | u64("0xF940794BB2B2F2B2"), u64("0x6359D185E6E6BFE6"), u64("0x70361C7E0E0E380E"), u64("0xF8633EE71F1F7C1F"), 342 | u64("0x37F7C45562629562"), u64("0xEEA3B53AD4D477D4"), u64("0x29324D81A8A89AA8"), u64("0xC4F4315296966296"), 343 | u64("0x9B3AEF62F9F9C3F9"), u64("0x66F697A3C5C533C5"), u64("0x35B14A1025259425"), u64("0xF220B2AB59597959"), 344 | u64("0x54AE15D084842A84"), u64("0xB7A7E4C57272D572"), u64("0xD5DD72EC3939E439"), u64("0x5A6198164C4C2D4C"), 345 | u64("0xCA3BBC945E5E655E"), u64("0xE785F09F7878FD78"), u64("0xDDD870E53838E038"), u64("0x148605988C8C0A8C"), 346 | u64("0xC6B2BF17D1D163D1"), u64("0x410B57E4A5A5AEA5"), u64("0x434DD9A1E2E2AFE2"), u64("0x2FF8C24E61619961"), 347 | u64("0xF1457B42B3B3F6B3"), u64("0x15A5423421218421"), u64("0x94D625089C9C4A9C"), u64("0xF0663CEE1E1E781E"), 348 | u64("0x2252866143431143"), u64("0x76FC93B1C7C73BC7"), u64("0xB32BE54FFCFCD7FC"), u64("0x2014082404041004"), 349 | u64("0xB208A2E351515951"), u64("0xBCC72F2599995E99"), u64("0x4FC4DA226D6DA96D"), u64("0x68391A650D0D340D"), 350 | u64("0x8335E979FAFACFFA"), u64("0xB684A369DFDF5BDF"), u64("0xD79BFCA97E7EE57E"), u64("0x3DB4481924249024"), 351 | u64("0xC5D776FE3B3BEC3B"), u64("0x313D4B9AABAB96AB"), u64("0x3ED181F0CECE1FCE"), u64("0x8855229911114411"), 352 | u64("0x0C8903838F8F068F"), u64("0x4A6B9C044E4E254E"), u64("0xD1517366B7B7E6B7"), u64("0x0B60CBE0EBEB8BEB"), 353 | u64("0xFDCC78C13C3CF03C"), u64("0x7CBF1FFD81813E81"), u64("0xD4FE354094946A94"), u64("0xEB0CF31CF7F7FBF7"), 354 | u64("0xA1676F18B9B9DEB9"), u64("0x985F268B13134C13"), u64("0x7D9C58512C2CB02C"), u64("0xD6B8BB05D3D36BD3"), 355 | u64("0x6B5CD38CE7E7BBE7"), u64("0x57CBDC396E6EA56E"), u64("0x6EF395AAC4C437C4"), u64("0x180F061B03030C03"), 356 | u64("0x8A13ACDC56564556"), u64("0x1A49885E44440D44"), u64("0xDF9EFEA07F7FE17F"), u64("0x21374F88A9A99EA9"), 357 | u64("0x4D8254672A2AA82A"), u64("0xB16D6B0ABBBBD6BB"), u64("0x46E29F87C1C123C1"), u64("0xA202A6F153535153"), 358 | u64("0xAE8BA572DCDC57DC"), u64("0x582716530B0B2C0B"), u64("0x9CD327019D9D4E9D"), u64("0x47C1D82B6C6CAD6C"), 359 | u64("0x95F562A43131C431"), u64("0x87B9E8F37474CD74"), u64("0xE309F115F6F6FFF6"), u64("0x0A438C4C46460546"), 360 | u64("0x092645A5ACAC8AAC"), u64("0x3C970FB589891E89"), u64("0xA04428B414145014"), u64("0x5B42DFBAE1E1A3E1"), 361 | u64("0xB04E2CA616165816"), u64("0xCDD274F73A3AE83A"), u64("0x6FD0D2066969B969"), u64("0x482D124109092409"), 362 | u64("0xA7ADE0D77070DD70"), u64("0xD954716FB6B6E2B6"), u64("0xCEB7BD1ED0D067D0"), u64("0x3B7EC7D6EDED93ED"), 363 | u64("0x2EDB85E2CCCC17CC"), u64("0x2A57846842421542"), u64("0xB4C22D2C98985A98"), u64("0x490E55EDA4A4AAA4"), 364 | u64("0x5D8850752828A028"), u64("0xDA31B8865C5C6D5C"), u64("0x933FED6BF8F8C7F8"), u64("0x44A411C286862286") 365 | } 366 | 367 | local C5 = { 368 | u64("0x18C07830D8181860"), u64("0x2305AF462623238C"), u64("0xC67EF991B8C6C63F"), u64("0xE8136FCDFBE8E887"), 369 | u64("0x874CA113CB878726"), u64("0xB8A9626D11B8B8DA"), u64("0x0108050209010104"), u64("0x4F426E9E0D4F4F21"), 370 | u64("0x36ADEE6C9B3636D8"), u64("0xA6590451FFA6A6A2"), u64("0xD2DEBDB90CD2D26F"), u64("0xF5FB06F70EF5F5F3"), 371 | u64("0x79EF80F2967979F9"), u64("0x6F5FCEDE306F6FA1"), u64("0x91FCEF3F6D91917E"), u64("0x52AA07A4F8525255"), 372 | u64("0x6027FDC04760609D"), u64("0xBC89766535BCBCCA"), u64("0x9BACCD2B379B9B56"), u64("0x8E048C018A8E8E02"), 373 | u64("0xA371155BD2A3A3B6"), u64("0x0C603C186C0C0C30"), u64("0x7BFF8AF6847B7BF1"), u64("0x35B5E16A803535D4"), 374 | u64("0x1DE8693AF51D1D74"), u64("0xE05347DDB3E0E0A7"), u64("0xD7F6ACB321D7D77B"), u64("0xC25EED999CC2C22F"), 375 | u64("0x2E6D965C432E2EB8"), u64("0x4B627A96294B4B31"), u64("0xFEA321E15DFEFEDF"), u64("0x578216AED5575741"), 376 | u64("0x15A8412ABD151554"), u64("0x779FB6EEE87777C1"), u64("0x37A5EB6E923737DC"), u64("0xE57B56D79EE5E5B3"), 377 | u64("0x9F8CD923139F9F46"), u64("0xF0D317FD23F0F0E7"), u64("0x4A6A7F94204A4A35"), u64("0xDA9E95A944DADA4F"), 378 | u64("0x58FA25B0A258587D"), u64("0xC906CA8FCFC9C903"), u64("0x29558D527C2929A4"), u64("0x0A5022145A0A0A28"), 379 | u64("0xB1E14F7F50B1B1FE"), u64("0xA0691A5DC9A0A0BA"), u64("0x6B7FDAD6146B6BB1"), u64("0x855CAB17D985852E"), 380 | u64("0xBD8173673CBDBDCE"), u64("0x5DD234BA8F5D5D69"), u64("0x1080502090101040"), u64("0xF4F303F507F4F4F7"), 381 | u64("0xCB16C08BDDCBCB0B"), u64("0x3EEDC67CD33E3EF8"), u64("0x0528110A2D050514"), u64("0x671FE6CE78676781"), 382 | u64("0xE47353D597E4E4B7"), u64("0x2725BB4E0227279C"), u64("0x4132588273414119"), u64("0x8B2C9D0BA78B8B16"), 383 | u64("0xA7510153F6A7A7A6"), u64("0x7DCF94FAB27D7DE9"), u64("0x95DCFB374995956E"), u64("0xD88E9FAD56D8D847"), 384 | u64("0xFB8B30EB70FBFBCB"), u64("0xEE2371C1CDEEEE9F"), u64("0x7CC791F8BB7C7CED"), u64("0x6617E3CC71666685"), 385 | u64("0xDDA68EA77BDDDD53"), u64("0x17B84B2EAF17175C"), u64("0x4702468E45474701"), u64("0x9E84DC211A9E9E42"), 386 | u64("0xCA1EC589D4CACA0F"), u64("0x2D75995A582D2DB4"), u64("0xBF9179632EBFBFC6"), u64("0x07381B0E3F07071C"), 387 | u64("0xAD012347ACADAD8E"), u64("0x5AEA2FB4B05A5A75"), u64("0x836CB51BEF838336"), u64("0x3385FF66B63333CC"), 388 | u64("0x633FF2C65C636391"), u64("0x02100A0412020208"), u64("0xAA39384993AAAA92"), u64("0x71AFA8E2DE7171D9"), 389 | u64("0xC80ECF8DC6C8C807"), u64("0x19C87D32D1191964"), u64("0x497270923B494939"), u64("0xD9869AAF5FD9D943"), 390 | u64("0xF2C31DF931F2F2EF"), u64("0xE34B48DBA8E3E3AB"), u64("0x5BE22AB6B95B5B71"), u64("0x8834920DBC88881A"), 391 | u64("0x9AA4C8293E9A9A52"), u64("0x262DBE4C0B262698"), u64("0x328DFA64BF3232C8"), u64("0xB0E94A7D59B0B0FA"), 392 | u64("0xE91B6ACFF2E9E983"), u64("0x0F78331E770F0F3C"), u64("0xD5E6A6B733D5D573"), u64("0x8074BA1DF480803A"), 393 | u64("0xBE997C6127BEBEC2"), u64("0xCD26DE87EBCDCD13"), u64("0x34BDE468893434D0"), u64("0x487A75903248483D"), 394 | u64("0xFFAB24E354FFFFDB"), u64("0x7AF78FF48D7A7AF5"), u64("0x90F4EA3D6490907A"), u64("0x5FC23EBE9D5F5F61"), 395 | u64("0x201DA0403D202080"), u64("0x6867D5D00F6868BD"), u64("0x1AD07234CA1A1A68"), u64("0xAE192C41B7AEAE82"), 396 | u64("0xB4C95E757DB4B4EA"), u64("0x549A19A8CE54544D"), u64("0x93ECE53B7F939376"), u64("0x220DAA442F222288"), 397 | u64("0x6407E9C86364648D"), u64("0xF1DB12FF2AF1F1E3"), u64("0x73BFA2E6CC7373D1"), u64("0x12905A2482121248"), 398 | u64("0x403A5D807A40401D"), u64("0x0840281048080820"), u64("0xC356E89B95C3C32B"), u64("0xEC337BC5DFECEC97"), 399 | u64("0xDB9690AB4DDBDB4B"), u64("0xA1611F5FC0A1A1BE"), u64("0x8D1C8307918D8D0E"), u64("0x3DF5C97AC83D3DF4"), 400 | u64("0x97CCF1335B979766"), u64("0x0000000000000000"), u64("0xCF36D483F9CFCF1B"), u64("0x2B4587566E2B2BAC"), 401 | u64("0x7697B3ECE17676C5"), u64("0x8264B019E6828232"), u64("0xD6FEA9B128D6D67F"), u64("0x1BD87736C31B1B6C"), 402 | u64("0xB5C15B7774B5B5EE"), u64("0xAF112943BEAFAF86"), u64("0x6A77DFD41D6A6AB5"), u64("0x50BA0DA0EA50505D"), 403 | u64("0x45124C8A57454509"), u64("0xF3CB18FB38F3F3EB"), u64("0x309DF060AD3030C0"), u64("0xEF2B74C3C4EFEF9B"), 404 | u64("0x3FE5C37EDA3F3FFC"), u64("0x55921CAAC7555549"), u64("0xA2791059DBA2A2B2"), u64("0xEA0365C9E9EAEA8F"), 405 | u64("0x650FECCA6A656589"), u64("0xBAB9686903BABAD2"), u64("0x2F65935E4A2F2FBC"), u64("0xC04EE79D8EC0C027"), 406 | u64("0xDEBE81A160DEDE5F"), u64("0x1CE06C38FC1C1C70"), u64("0xFDBB2EE746FDFDD3"), u64("0x4D52649A1F4D4D29"), 407 | u64("0x92E4E03976929272"), u64("0x758FBCEAFA7575C9"), u64("0x06301E0C36060618"), u64("0x8A249809AE8A8A12"), 408 | u64("0xB2F940794BB2B2F2"), u64("0xE66359D185E6E6BF"), u64("0x0E70361C7E0E0E38"), u64("0x1FF8633EE71F1F7C"), 409 | u64("0x6237F7C455626295"), u64("0xD4EEA3B53AD4D477"), u64("0xA829324D81A8A89A"), u64("0x96C4F43152969662"), 410 | u64("0xF99B3AEF62F9F9C3"), u64("0xC566F697A3C5C533"), u64("0x2535B14A10252594"), u64("0x59F220B2AB595979"), 411 | u64("0x8454AE15D084842A"), u64("0x72B7A7E4C57272D5"), u64("0x39D5DD72EC3939E4"), u64("0x4C5A6198164C4C2D"), 412 | u64("0x5ECA3BBC945E5E65"), u64("0x78E785F09F7878FD"), u64("0x38DDD870E53838E0"), u64("0x8C148605988C8C0A"), 413 | u64("0xD1C6B2BF17D1D163"), u64("0xA5410B57E4A5A5AE"), u64("0xE2434DD9A1E2E2AF"), u64("0x612FF8C24E616199"), 414 | u64("0xB3F1457B42B3B3F6"), u64("0x2115A54234212184"), u64("0x9C94D625089C9C4A"), u64("0x1EF0663CEE1E1E78"), 415 | u64("0x4322528661434311"), u64("0xC776FC93B1C7C73B"), u64("0xFCB32BE54FFCFCD7"), u64("0x0420140824040410"), 416 | u64("0x51B208A2E3515159"), u64("0x99BCC72F2599995E"), u64("0x6D4FC4DA226D6DA9"), u64("0x0D68391A650D0D34"), 417 | u64("0xFA8335E979FAFACF"), u64("0xDFB684A369DFDF5B"), u64("0x7ED79BFCA97E7EE5"), u64("0x243DB44819242490"), 418 | u64("0x3BC5D776FE3B3BEC"), u64("0xAB313D4B9AABAB96"), u64("0xCE3ED181F0CECE1F"), u64("0x1188552299111144"), 419 | u64("0x8F0C8903838F8F06"), u64("0x4E4A6B9C044E4E25"), u64("0xB7D1517366B7B7E6"), u64("0xEB0B60CBE0EBEB8B"), 420 | u64("0x3CFDCC78C13C3CF0"), u64("0x817CBF1FFD81813E"), u64("0x94D4FE354094946A"), u64("0xF7EB0CF31CF7F7FB"), 421 | u64("0xB9A1676F18B9B9DE"), u64("0x13985F268B13134C"), u64("0x2C7D9C58512C2CB0"), u64("0xD3D6B8BB05D3D36B"), 422 | u64("0xE76B5CD38CE7E7BB"), u64("0x6E57CBDC396E6EA5"), u64("0xC46EF395AAC4C437"), u64("0x03180F061B03030C"), 423 | u64("0x568A13ACDC565645"), u64("0x441A49885E44440D"), u64("0x7FDF9EFEA07F7FE1"), u64("0xA921374F88A9A99E"), 424 | u64("0x2A4D8254672A2AA8"), u64("0xBBB16D6B0ABBBBD6"), u64("0xC146E29F87C1C123"), u64("0x53A202A6F1535351"), 425 | u64("0xDCAE8BA572DCDC57"), u64("0x0B582716530B0B2C"), u64("0x9D9CD327019D9D4E"), u64("0x6C47C1D82B6C6CAD"), 426 | u64("0x3195F562A43131C4"), u64("0x7487B9E8F37474CD"), u64("0xF6E309F115F6F6FF"), u64("0x460A438C4C464605"), 427 | u64("0xAC092645A5ACAC8A"), u64("0x893C970FB589891E"), u64("0x14A04428B4141450"), u64("0xE15B42DFBAE1E1A3"), 428 | u64("0x16B04E2CA6161658"), u64("0x3ACDD274F73A3AE8"), u64("0x696FD0D2066969B9"), u64("0x09482D1241090924"), 429 | u64("0x70A7ADE0D77070DD"), u64("0xB6D954716FB6B6E2"), u64("0xD0CEB7BD1ED0D067"), u64("0xED3B7EC7D6EDED93"), 430 | u64("0xCC2EDB85E2CCCC17"), u64("0x422A578468424215"), u64("0x98B4C22D2C98985A"), u64("0xA4490E55EDA4A4AA"), 431 | u64("0x285D8850752828A0"), u64("0x5CDA31B8865C5C6D"), u64("0xF8933FED6BF8F8C7"), u64("0x8644A411C2868622") 432 | } 433 | 434 | local C6 = { 435 | u64("0x6018C07830D81818"), u64("0x8C2305AF46262323"), u64("0x3FC67EF991B8C6C6"), u64("0x87E8136FCDFBE8E8"), 436 | u64("0x26874CA113CB8787"), u64("0xDAB8A9626D11B8B8"), u64("0x0401080502090101"), u64("0x214F426E9E0D4F4F"), 437 | u64("0xD836ADEE6C9B3636"), u64("0xA2A6590451FFA6A6"), u64("0x6FD2DEBDB90CD2D2"), u64("0xF3F5FB06F70EF5F5"), 438 | u64("0xF979EF80F2967979"), u64("0xA16F5FCEDE306F6F"), u64("0x7E91FCEF3F6D9191"), u64("0x5552AA07A4F85252"), 439 | u64("0x9D6027FDC0476060"), u64("0xCABC89766535BCBC"), u64("0x569BACCD2B379B9B"), u64("0x028E048C018A8E8E"), 440 | u64("0xB6A371155BD2A3A3"), u64("0x300C603C186C0C0C"), u64("0xF17BFF8AF6847B7B"), u64("0xD435B5E16A803535"), 441 | u64("0x741DE8693AF51D1D"), u64("0xA7E05347DDB3E0E0"), u64("0x7BD7F6ACB321D7D7"), u64("0x2FC25EED999CC2C2"), 442 | u64("0xB82E6D965C432E2E"), u64("0x314B627A96294B4B"), u64("0xDFFEA321E15DFEFE"), u64("0x41578216AED55757"), 443 | u64("0x5415A8412ABD1515"), u64("0xC1779FB6EEE87777"), u64("0xDC37A5EB6E923737"), u64("0xB3E57B56D79EE5E5"), 444 | u64("0x469F8CD923139F9F"), u64("0xE7F0D317FD23F0F0"), u64("0x354A6A7F94204A4A"), u64("0x4FDA9E95A944DADA"), 445 | u64("0x7D58FA25B0A25858"), u64("0x03C906CA8FCFC9C9"), u64("0xA429558D527C2929"), u64("0x280A5022145A0A0A"), 446 | u64("0xFEB1E14F7F50B1B1"), u64("0xBAA0691A5DC9A0A0"), u64("0xB16B7FDAD6146B6B"), u64("0x2E855CAB17D98585"), 447 | u64("0xCEBD8173673CBDBD"), u64("0x695DD234BA8F5D5D"), u64("0x4010805020901010"), u64("0xF7F4F303F507F4F4"), 448 | u64("0x0BCB16C08BDDCBCB"), u64("0xF83EEDC67CD33E3E"), u64("0x140528110A2D0505"), u64("0x81671FE6CE786767"), 449 | u64("0xB7E47353D597E4E4"), u64("0x9C2725BB4E022727"), u64("0x1941325882734141"), u64("0x168B2C9D0BA78B8B"), 450 | u64("0xA6A7510153F6A7A7"), u64("0xE97DCF94FAB27D7D"), u64("0x6E95DCFB37499595"), u64("0x47D88E9FAD56D8D8"), 451 | u64("0xCBFB8B30EB70FBFB"), u64("0x9FEE2371C1CDEEEE"), u64("0xED7CC791F8BB7C7C"), u64("0x856617E3CC716666"), 452 | u64("0x53DDA68EA77BDDDD"), u64("0x5C17B84B2EAF1717"), u64("0x014702468E454747"), u64("0x429E84DC211A9E9E"), 453 | u64("0x0FCA1EC589D4CACA"), u64("0xB42D75995A582D2D"), u64("0xC6BF9179632EBFBF"), u64("0x1C07381B0E3F0707"), 454 | u64("0x8EAD012347ACADAD"), u64("0x755AEA2FB4B05A5A"), u64("0x36836CB51BEF8383"), u64("0xCC3385FF66B63333"), 455 | u64("0x91633FF2C65C6363"), u64("0x0802100A04120202"), u64("0x92AA39384993AAAA"), u64("0xD971AFA8E2DE7171"), 456 | u64("0x07C80ECF8DC6C8C8"), u64("0x6419C87D32D11919"), u64("0x39497270923B4949"), u64("0x43D9869AAF5FD9D9"), 457 | u64("0xEFF2C31DF931F2F2"), u64("0xABE34B48DBA8E3E3"), u64("0x715BE22AB6B95B5B"), u64("0x1A8834920DBC8888"), 458 | u64("0x529AA4C8293E9A9A"), u64("0x98262DBE4C0B2626"), u64("0xC8328DFA64BF3232"), u64("0xFAB0E94A7D59B0B0"), 459 | u64("0x83E91B6ACFF2E9E9"), u64("0x3C0F78331E770F0F"), u64("0x73D5E6A6B733D5D5"), u64("0x3A8074BA1DF48080"), 460 | u64("0xC2BE997C6127BEBE"), u64("0x13CD26DE87EBCDCD"), u64("0xD034BDE468893434"), u64("0x3D487A7590324848"), 461 | u64("0xDBFFAB24E354FFFF"), u64("0xF57AF78FF48D7A7A"), u64("0x7A90F4EA3D649090"), u64("0x615FC23EBE9D5F5F"), 462 | u64("0x80201DA0403D2020"), u64("0xBD6867D5D00F6868"), u64("0x681AD07234CA1A1A"), u64("0x82AE192C41B7AEAE"), 463 | u64("0xEAB4C95E757DB4B4"), u64("0x4D549A19A8CE5454"), u64("0x7693ECE53B7F9393"), u64("0x88220DAA442F2222"), 464 | u64("0x8D6407E9C8636464"), u64("0xE3F1DB12FF2AF1F1"), u64("0xD173BFA2E6CC7373"), u64("0x4812905A24821212"), 465 | u64("0x1D403A5D807A4040"), u64("0x2008402810480808"), u64("0x2BC356E89B95C3C3"), u64("0x97EC337BC5DFECEC"), 466 | u64("0x4BDB9690AB4DDBDB"), u64("0xBEA1611F5FC0A1A1"), u64("0x0E8D1C8307918D8D"), u64("0xF43DF5C97AC83D3D"), 467 | u64("0x6697CCF1335B9797"), u64("0x0000000000000000"), u64("0x1BCF36D483F9CFCF"), u64("0xAC2B4587566E2B2B"), 468 | u64("0xC57697B3ECE17676"), u64("0x328264B019E68282"), u64("0x7FD6FEA9B128D6D6"), u64("0x6C1BD87736C31B1B"), 469 | u64("0xEEB5C15B7774B5B5"), u64("0x86AF112943BEAFAF"), u64("0xB56A77DFD41D6A6A"), u64("0x5D50BA0DA0EA5050"), 470 | u64("0x0945124C8A574545"), u64("0xEBF3CB18FB38F3F3"), u64("0xC0309DF060AD3030"), u64("0x9BEF2B74C3C4EFEF"), 471 | u64("0xFC3FE5C37EDA3F3F"), u64("0x4955921CAAC75555"), u64("0xB2A2791059DBA2A2"), u64("0x8FEA0365C9E9EAEA"), 472 | u64("0x89650FECCA6A6565"), u64("0xD2BAB9686903BABA"), u64("0xBC2F65935E4A2F2F"), u64("0x27C04EE79D8EC0C0"), 473 | u64("0x5FDEBE81A160DEDE"), u64("0x701CE06C38FC1C1C"), u64("0xD3FDBB2EE746FDFD"), u64("0x294D52649A1F4D4D"), 474 | u64("0x7292E4E039769292"), u64("0xC9758FBCEAFA7575"), u64("0x1806301E0C360606"), u64("0x128A249809AE8A8A"), 475 | u64("0xF2B2F940794BB2B2"), u64("0xBFE66359D185E6E6"), u64("0x380E70361C7E0E0E"), u64("0x7C1FF8633EE71F1F"), 476 | u64("0x956237F7C4556262"), u64("0x77D4EEA3B53AD4D4"), u64("0x9AA829324D81A8A8"), u64("0x6296C4F431529696"), 477 | u64("0xC3F99B3AEF62F9F9"), u64("0x33C566F697A3C5C5"), u64("0x942535B14A102525"), u64("0x7959F220B2AB5959"), 478 | u64("0x2A8454AE15D08484"), u64("0xD572B7A7E4C57272"), u64("0xE439D5DD72EC3939"), u64("0x2D4C5A6198164C4C"), 479 | u64("0x655ECA3BBC945E5E"), u64("0xFD78E785F09F7878"), u64("0xE038DDD870E53838"), u64("0x0A8C148605988C8C"), 480 | u64("0x63D1C6B2BF17D1D1"), u64("0xAEA5410B57E4A5A5"), u64("0xAFE2434DD9A1E2E2"), u64("0x99612FF8C24E6161"), 481 | u64("0xF6B3F1457B42B3B3"), u64("0x842115A542342121"), u64("0x4A9C94D625089C9C"), u64("0x781EF0663CEE1E1E"), 482 | u64("0x1143225286614343"), u64("0x3BC776FC93B1C7C7"), u64("0xD7FCB32BE54FFCFC"), u64("0x1004201408240404"), 483 | u64("0x5951B208A2E35151"), u64("0x5E99BCC72F259999"), u64("0xA96D4FC4DA226D6D"), u64("0x340D68391A650D0D"), 484 | u64("0xCFFA8335E979FAFA"), u64("0x5BDFB684A369DFDF"), u64("0xE57ED79BFCA97E7E"), u64("0x90243DB448192424"), 485 | u64("0xEC3BC5D776FE3B3B"), u64("0x96AB313D4B9AABAB"), u64("0x1FCE3ED181F0CECE"), u64("0x4411885522991111"), 486 | u64("0x068F0C8903838F8F"), u64("0x254E4A6B9C044E4E"), u64("0xE6B7D1517366B7B7"), u64("0x8BEB0B60CBE0EBEB"), 487 | u64("0xF03CFDCC78C13C3C"), u64("0x3E817CBF1FFD8181"), u64("0x6A94D4FE35409494"), u64("0xFBF7EB0CF31CF7F7"), 488 | u64("0xDEB9A1676F18B9B9"), u64("0x4C13985F268B1313"), u64("0xB02C7D9C58512C2C"), u64("0x6BD3D6B8BB05D3D3"), 489 | u64("0xBBE76B5CD38CE7E7"), u64("0xA56E57CBDC396E6E"), u64("0x37C46EF395AAC4C4"), u64("0x0C03180F061B0303"), 490 | u64("0x45568A13ACDC5656"), u64("0x0D441A49885E4444"), u64("0xE17FDF9EFEA07F7F"), u64("0x9EA921374F88A9A9"), 491 | u64("0xA82A4D8254672A2A"), u64("0xD6BBB16D6B0ABBBB"), u64("0x23C146E29F87C1C1"), u64("0x5153A202A6F15353"), 492 | u64("0x57DCAE8BA572DCDC"), u64("0x2C0B582716530B0B"), u64("0x4E9D9CD327019D9D"), u64("0xAD6C47C1D82B6C6C"), 493 | u64("0xC43195F562A43131"), u64("0xCD7487B9E8F37474"), u64("0xFFF6E309F115F6F6"), u64("0x05460A438C4C4646"), 494 | u64("0x8AAC092645A5ACAC"), u64("0x1E893C970FB58989"), u64("0x5014A04428B41414"), u64("0xA3E15B42DFBAE1E1"), 495 | u64("0x5816B04E2CA61616"), u64("0xE83ACDD274F73A3A"), u64("0xB9696FD0D2066969"), u64("0x2409482D12410909"), 496 | u64("0xDD70A7ADE0D77070"), u64("0xE2B6D954716FB6B6"), u64("0x67D0CEB7BD1ED0D0"), u64("0x93ED3B7EC7D6EDED"), 497 | u64("0x17CC2EDB85E2CCCC"), u64("0x15422A5784684242"), u64("0x5A98B4C22D2C9898"), u64("0xAAA4490E55EDA4A4"), 498 | u64("0xA0285D8850752828"), u64("0x6D5CDA31B8865C5C"), u64("0xC7F8933FED6BF8F8"), u64("0x228644A411C28686") 499 | } 500 | 501 | local C7 = { 502 | u64("0x186018C07830D818"), u64("0x238C2305AF462623"), u64("0xC63FC67EF991B8C6"), u64("0xE887E8136FCDFBE8"), 503 | u64("0x8726874CA113CB87"), u64("0xB8DAB8A9626D11B8"), u64("0x0104010805020901"), u64("0x4F214F426E9E0D4F"), 504 | u64("0x36D836ADEE6C9B36"), u64("0xA6A2A6590451FFA6"), u64("0xD26FD2DEBDB90CD2"), u64("0xF5F3F5FB06F70EF5"), 505 | u64("0x79F979EF80F29679"), u64("0x6FA16F5FCEDE306F"), u64("0x917E91FCEF3F6D91"), u64("0x525552AA07A4F852"), 506 | u64("0x609D6027FDC04760"), u64("0xBCCABC89766535BC"), u64("0x9B569BACCD2B379B"), u64("0x8E028E048C018A8E"), 507 | u64("0xA3B6A371155BD2A3"), u64("0x0C300C603C186C0C"), u64("0x7BF17BFF8AF6847B"), u64("0x35D435B5E16A8035"), 508 | u64("0x1D741DE8693AF51D"), u64("0xE0A7E05347DDB3E0"), u64("0xD77BD7F6ACB321D7"), u64("0xC22FC25EED999CC2"), 509 | u64("0x2EB82E6D965C432E"), u64("0x4B314B627A96294B"), u64("0xFEDFFEA321E15DFE"), u64("0x5741578216AED557"), 510 | u64("0x155415A8412ABD15"), u64("0x77C1779FB6EEE877"), u64("0x37DC37A5EB6E9237"), u64("0xE5B3E57B56D79EE5"), 511 | u64("0x9F469F8CD923139F"), u64("0xF0E7F0D317FD23F0"), u64("0x4A354A6A7F94204A"), u64("0xDA4FDA9E95A944DA"), 512 | u64("0x587D58FA25B0A258"), u64("0xC903C906CA8FCFC9"), u64("0x29A429558D527C29"), u64("0x0A280A5022145A0A"), 513 | u64("0xB1FEB1E14F7F50B1"), u64("0xA0BAA0691A5DC9A0"), u64("0x6BB16B7FDAD6146B"), u64("0x852E855CAB17D985"), 514 | u64("0xBDCEBD8173673CBD"), u64("0x5D695DD234BA8F5D"), u64("0x1040108050209010"), u64("0xF4F7F4F303F507F4"), 515 | u64("0xCB0BCB16C08BDDCB"), u64("0x3EF83EEDC67CD33E"), u64("0x05140528110A2D05"), u64("0x6781671FE6CE7867"), 516 | u64("0xE4B7E47353D597E4"), u64("0x279C2725BB4E0227"), u64("0x4119413258827341"), u64("0x8B168B2C9D0BA78B"), 517 | u64("0xA7A6A7510153F6A7"), u64("0x7DE97DCF94FAB27D"), u64("0x956E95DCFB374995"), u64("0xD847D88E9FAD56D8"), 518 | u64("0xFBCBFB8B30EB70FB"), u64("0xEE9FEE2371C1CDEE"), u64("0x7CED7CC791F8BB7C"), u64("0x66856617E3CC7166"), 519 | u64("0xDD53DDA68EA77BDD"), u64("0x175C17B84B2EAF17"), u64("0x47014702468E4547"), u64("0x9E429E84DC211A9E"), 520 | u64("0xCA0FCA1EC589D4CA"), u64("0x2DB42D75995A582D"), u64("0xBFC6BF9179632EBF"), u64("0x071C07381B0E3F07"), 521 | u64("0xAD8EAD012347ACAD"), u64("0x5A755AEA2FB4B05A"), u64("0x8336836CB51BEF83"), u64("0x33CC3385FF66B633"), 522 | u64("0x6391633FF2C65C63"), u64("0x020802100A041202"), u64("0xAA92AA39384993AA"), u64("0x71D971AFA8E2DE71"), 523 | u64("0xC807C80ECF8DC6C8"), u64("0x196419C87D32D119"), u64("0x4939497270923B49"), u64("0xD943D9869AAF5FD9"), 524 | u64("0xF2EFF2C31DF931F2"), u64("0xE3ABE34B48DBA8E3"), u64("0x5B715BE22AB6B95B"), u64("0x881A8834920DBC88"), 525 | u64("0x9A529AA4C8293E9A"), u64("0x2698262DBE4C0B26"), u64("0x32C8328DFA64BF32"), u64("0xB0FAB0E94A7D59B0"), 526 | u64("0xE983E91B6ACFF2E9"), u64("0x0F3C0F78331E770F"), u64("0xD573D5E6A6B733D5"), u64("0x803A8074BA1DF480"), 527 | u64("0xBEC2BE997C6127BE"), u64("0xCD13CD26DE87EBCD"), u64("0x34D034BDE4688934"), u64("0x483D487A75903248"), 528 | u64("0xFFDBFFAB24E354FF"), u64("0x7AF57AF78FF48D7A"), u64("0x907A90F4EA3D6490"), u64("0x5F615FC23EBE9D5F"), 529 | u64("0x2080201DA0403D20"), u64("0x68BD6867D5D00F68"), u64("0x1A681AD07234CA1A"), u64("0xAE82AE192C41B7AE"), 530 | u64("0xB4EAB4C95E757DB4"), u64("0x544D549A19A8CE54"), u64("0x937693ECE53B7F93"), u64("0x2288220DAA442F22"), 531 | u64("0x648D6407E9C86364"), u64("0xF1E3F1DB12FF2AF1"), u64("0x73D173BFA2E6CC73"), u64("0x124812905A248212"), 532 | u64("0x401D403A5D807A40"), u64("0x0820084028104808"), u64("0xC32BC356E89B95C3"), u64("0xEC97EC337BC5DFEC"), 533 | u64("0xDB4BDB9690AB4DDB"), u64("0xA1BEA1611F5FC0A1"), u64("0x8D0E8D1C8307918D"), u64("0x3DF43DF5C97AC83D"), 534 | u64("0x976697CCF1335B97"), u64("0x0000000000000000"), u64("0xCF1BCF36D483F9CF"), u64("0x2BAC2B4587566E2B"), 535 | u64("0x76C57697B3ECE176"), u64("0x82328264B019E682"), u64("0xD67FD6FEA9B128D6"), u64("0x1B6C1BD87736C31B"), 536 | u64("0xB5EEB5C15B7774B5"), u64("0xAF86AF112943BEAF"), u64("0x6AB56A77DFD41D6A"), u64("0x505D50BA0DA0EA50"), 537 | u64("0x450945124C8A5745"), u64("0xF3EBF3CB18FB38F3"), u64("0x30C0309DF060AD30"), u64("0xEF9BEF2B74C3C4EF"), 538 | u64("0x3FFC3FE5C37EDA3F"), u64("0x554955921CAAC755"), u64("0xA2B2A2791059DBA2"), u64("0xEA8FEA0365C9E9EA"), 539 | u64("0x6589650FECCA6A65"), u64("0xBAD2BAB9686903BA"), u64("0x2FBC2F65935E4A2F"), u64("0xC027C04EE79D8EC0"), 540 | u64("0xDE5FDEBE81A160DE"), u64("0x1C701CE06C38FC1C"), u64("0xFDD3FDBB2EE746FD"), u64("0x4D294D52649A1F4D"), 541 | u64("0x927292E4E0397692"), u64("0x75C9758FBCEAFA75"), u64("0x061806301E0C3606"), u64("0x8A128A249809AE8A"), 542 | u64("0xB2F2B2F940794BB2"), u64("0xE6BFE66359D185E6"), u64("0x0E380E70361C7E0E"), u64("0x1F7C1FF8633EE71F"), 543 | u64("0x62956237F7C45562"), u64("0xD477D4EEA3B53AD4"), u64("0xA89AA829324D81A8"), u64("0x966296C4F4315296"), 544 | u64("0xF9C3F99B3AEF62F9"), u64("0xC533C566F697A3C5"), u64("0x25942535B14A1025"), u64("0x597959F220B2AB59"), 545 | u64("0x842A8454AE15D084"), u64("0x72D572B7A7E4C572"), u64("0x39E439D5DD72EC39"), u64("0x4C2D4C5A6198164C"), 546 | u64("0x5E655ECA3BBC945E"), u64("0x78FD78E785F09F78"), u64("0x38E038DDD870E538"), u64("0x8C0A8C148605988C"), 547 | u64("0xD163D1C6B2BF17D1"), u64("0xA5AEA5410B57E4A5"), u64("0xE2AFE2434DD9A1E2"), u64("0x6199612FF8C24E61"), 548 | u64("0xB3F6B3F1457B42B3"), u64("0x21842115A5423421"), u64("0x9C4A9C94D625089C"), u64("0x1E781EF0663CEE1E"), 549 | u64("0x4311432252866143"), u64("0xC73BC776FC93B1C7"), u64("0xFCD7FCB32BE54FFC"), u64("0x0410042014082404"), 550 | u64("0x515951B208A2E351"), u64("0x995E99BCC72F2599"), u64("0x6DA96D4FC4DA226D"), u64("0x0D340D68391A650D"), 551 | u64("0xFACFFA8335E979FA"), u64("0xDF5BDFB684A369DF"), u64("0x7EE57ED79BFCA97E"), u64("0x2490243DB4481924"), 552 | u64("0x3BEC3BC5D776FE3B"), u64("0xAB96AB313D4B9AAB"), u64("0xCE1FCE3ED181F0CE"), u64("0x1144118855229911"), 553 | u64("0x8F068F0C8903838F"), u64("0x4E254E4A6B9C044E"), u64("0xB7E6B7D1517366B7"), u64("0xEB8BEB0B60CBE0EB"), 554 | u64("0x3CF03CFDCC78C13C"), u64("0x813E817CBF1FFD81"), u64("0x946A94D4FE354094"), u64("0xF7FBF7EB0CF31CF7"), 555 | u64("0xB9DEB9A1676F18B9"), u64("0x134C13985F268B13"), u64("0x2CB02C7D9C58512C"), u64("0xD36BD3D6B8BB05D3"), 556 | u64("0xE7BBE76B5CD38CE7"), u64("0x6EA56E57CBDC396E"), u64("0xC437C46EF395AAC4"), u64("0x030C03180F061B03"), 557 | u64("0x5645568A13ACDC56"), u64("0x440D441A49885E44"), u64("0x7FE17FDF9EFEA07F"), u64("0xA99EA921374F88A9"), 558 | u64("0x2AA82A4D8254672A"), u64("0xBBD6BBB16D6B0ABB"), u64("0xC123C146E29F87C1"), u64("0x535153A202A6F153"), 559 | u64("0xDC57DCAE8BA572DC"), u64("0x0B2C0B582716530B"), u64("0x9D4E9D9CD327019D"), u64("0x6CAD6C47C1D82B6C"), 560 | u64("0x31C43195F562A431"), u64("0x74CD7487B9E8F374"), u64("0xF6FFF6E309F115F6"), u64("0x4605460A438C4C46"), 561 | u64("0xAC8AAC092645A5AC"), u64("0x891E893C970FB589"), u64("0x145014A04428B414"), u64("0xE1A3E15B42DFBAE1"), 562 | u64("0x165816B04E2CA616"), u64("0x3AE83ACDD274F73A"), u64("0x69B9696FD0D20669"), u64("0x092409482D124109"), 563 | u64("0x70DD70A7ADE0D770"), u64("0xB6E2B6D954716FB6"), u64("0xD067D0CEB7BD1ED0"), u64("0xED93ED3B7EC7D6ED"), 564 | u64("0xCC17CC2EDB85E2CC"), u64("0x4215422A57846842"), u64("0x985A98B4C22D2C98"), u64("0xA4AAA4490E55EDA4"), 565 | u64("0x28A0285D88507528"), u64("0x5C6D5CDA31B8865C"), u64("0xF8C7F8933FED6BF8"), u64("0x86228644A411C286") 566 | } 567 | 568 | local rc = { 569 | u64("0x0000000000000000"), 570 | u64("0x1823C6E887B8014F"), 571 | u64("0x36A6D2F5796F9152"), 572 | u64("0x60BC9B8EA30C7B35"), 573 | u64("0x1DE0D7C22E4BFE57"), 574 | u64("0x157737E59FF04ADA"), 575 | u64("0x58C9290AB1A06B85"), 576 | u64("0xBD5D10F4CB3E0567"), 577 | u64("0xE427418BA77D95D8"), 578 | u64("0xFBEE7C66DD17479E"), 579 | u64("0xCA2DBF07AD5A8333") 580 | } 581 | 582 | local function load_block(cs) 583 | local block = {} 584 | local j 585 | local k 586 | 587 | for i=1,M.block_size,8 do 588 | j = i//8+1 589 | k = ((i//8)*8)+1 590 | block[j] = 591 | (u64(string.byte(cs._data, k)) << 56 ~ 592 | u64(string.byte(cs._data, k+1)) << 48 ~ 593 | u64(string.byte(cs._data, k+2)) << 40 ~ 594 | u64(string.byte(cs._data, k+3)) << 32 ~ 595 | u64(string.byte(cs._data, k+4)) << 24 ~ 596 | u64(string.byte(cs._data, k+5)) << 16 ~ 597 | u64(string.byte(cs._data, k+6)) << 8 ~ 598 | u64(string.byte(cs._data, k+7))) 599 | end 600 | cs._data = cs._data:sub(M.block_size+1) 601 | 602 | return block 603 | end 604 | 605 | function M:new(data) 606 | if self ~= M then 607 | return nil, "First argument must be self" 608 | end 609 | local o = setmetatable({}, M_mt) 610 | 611 | o._hash = {} 612 | for i=1,8 do 613 | o._hash[i] = u64(0) 614 | end 615 | o._len = u256(0) 616 | o._data = "" 617 | 618 | if data ~= nil then 619 | o:update(data) 620 | end 621 | 622 | return o 623 | end 624 | setmetatable(M, { __call = M.new }) 625 | 626 | function M:copy() 627 | local o = M:new() 628 | for i=1,8 do 629 | o._hash[i] = self._hash[i]:copy() 630 | end 631 | o._data = self._data 632 | o._len = self._len:copy() 633 | return o 634 | end 635 | 636 | function M:update(data) 637 | local K = {} 638 | local state = {} 639 | local block = {} 640 | local L = {} 641 | 642 | if data == nil then 643 | data = "" 644 | end 645 | 646 | data = tostring(data) 647 | self._len = self._len + #data * 8 648 | self._data = self._data .. data 649 | 650 | while #self._data >= M.block_size do 651 | block = load_block(self) 652 | 653 | K[1] = self._hash[1]:copy() 654 | K[2] = self._hash[2]:copy() 655 | K[3] = self._hash[3]:copy() 656 | K[4] = self._hash[4]:copy() 657 | K[5] = self._hash[5]:copy() 658 | K[6] = self._hash[6]:copy() 659 | K[7] = self._hash[7]:copy() 660 | K[8] = self._hash[8]:copy() 661 | 662 | state[1] = block[1] ~ K[1] 663 | state[2] = block[2] ~ K[2] 664 | state[3] = block[3] ~ K[3] 665 | state[4] = block[4] ~ K[4] 666 | state[5] = block[5] ~ K[5] 667 | state[6] = block[6] ~ K[6] 668 | state[7] = block[7] ~ K[7] 669 | state[8] = block[8] ~ K[8] 670 | 671 | for r=2,11 do 672 | L[1] = 673 | C0[((K[1] >> 56)+1):asnumber()] ~ 674 | C1[(((K[8] >> 48) & 0xFF)+1):asnumber()] ~ 675 | C2[(((K[7] >> 40) & 0xFF)+1):asnumber()] ~ 676 | C3[(((K[6] >> 32) & 0xFF)+1):asnumber()] ~ 677 | C4[(((K[5] >> 24) & 0xFF)+1):asnumber()] ~ 678 | C5[(((K[4] >> 16) & 0xFF)+1):asnumber()] ~ 679 | C6[(((K[3] >> 8) & 0xFF)+1):asnumber()] ~ 680 | C7[((K[2] & 0xFF)+1):asnumber()] ~ 681 | rc[r] 682 | L[2] = 683 | C0[((K[2] >> 56)+1):asnumber()] ~ 684 | C1[(((K[1] >> 48) & 0xFF)+1):asnumber()] ~ 685 | C2[(((K[8] >> 40) & 0xFF)+1):asnumber()] ~ 686 | C3[(((K[7] >> 32) & 0xFF)+1):asnumber()] ~ 687 | C4[(((K[6] >> 24) & 0xFF)+1):asnumber()] ~ 688 | C5[(((K[5] >> 16) & 0xFF)+1):asnumber()] ~ 689 | C6[(((K[4] >> 8) & 0xFF)+1):asnumber()] ~ 690 | C7[((K[3] & 0xFF)+1):asnumber()] 691 | L[3] = 692 | C0[((K[3] >> 56)+1):asnumber()] ~ 693 | C1[(((K[2] >> 48) & 0xFF)+1):asnumber()] ~ 694 | C2[(((K[1] >> 40) & 0xFF)+1):asnumber()] ~ 695 | C3[(((K[8] >> 32) & 0xFF)+1):asnumber()] ~ 696 | C4[(((K[7] >> 24) & 0xFF)+1):asnumber()] ~ 697 | C5[(((K[6] >> 16) & 0xFF)+1):asnumber()] ~ 698 | C6[(((K[5] >> 8) & 0xFF)+1):asnumber()] ~ 699 | C7[((K[4] & 0xFF)+1):asnumber()] 700 | L[4] = 701 | C0[((K[4] >> 56)+1):asnumber()] ~ 702 | C1[(((K[3] >> 48) & 0xFF)+1):asnumber()] ~ 703 | C2[(((K[2] >> 40) & 0xFF)+1):asnumber()] ~ 704 | C3[(((K[1] >> 32) & 0xFF)+1):asnumber()] ~ 705 | C4[(((K[8] >> 24) & 0xFF)+1):asnumber()] ~ 706 | C5[(((K[7] >> 16) & 0xFF)+1):asnumber()] ~ 707 | C6[(((K[6] >> 8) & 0xFF)+1):asnumber()] ~ 708 | C7[((K[5] & 0xFF)+1):asnumber()] 709 | L[5] = 710 | C0[((K[5] >> 56)+1):asnumber()] ~ 711 | C1[(((K[4] >> 48) & 0xFF)+1):asnumber()] ~ 712 | C2[(((K[3] >> 40) & 0xFF)+1):asnumber()] ~ 713 | C3[(((K[2] >> 32) & 0xFF)+1):asnumber()] ~ 714 | C4[(((K[1] >> 24) & 0xFF)+1):asnumber()] ~ 715 | C5[(((K[8] >> 16) & 0xFF)+1):asnumber()] ~ 716 | C6[(((K[7] >> 8) & 0xFF)+1):asnumber()] ~ 717 | C7[((K[6] & 0xFF)+1):asnumber()] 718 | L[6] = 719 | C0[((K[6] >> 56)+1):asnumber()] ~ 720 | C1[(((K[5] >> 48) & 0xFF)+1):asnumber()] ~ 721 | C2[(((K[4] >> 40) & 0xFF)+1):asnumber()] ~ 722 | C3[(((K[3] >> 32) & 0xFF)+1):asnumber()] ~ 723 | C4[(((K[2] >> 24) & 0xFF)+1):asnumber()] ~ 724 | C5[(((K[1] >> 16) & 0xFF)+1):asnumber()] ~ 725 | C6[(((K[8] >> 8) & 0xFF)+1):asnumber()] ~ 726 | C7[((K[7] & 0xFF)+1):asnumber()] 727 | L[7] = 728 | C0[((K[7] >> 56)+1):asnumber()] ~ 729 | C1[(((K[6] >> 48) & 0xFF)+1):asnumber()] ~ 730 | C2[(((K[5] >> 40) & 0xFF)+1):asnumber()] ~ 731 | C3[(((K[4] >> 32) & 0xFF)+1):asnumber()] ~ 732 | C4[(((K[3] >> 24) & 0xFF)+1):asnumber()] ~ 733 | C5[(((K[2] >> 16) & 0xFF)+1):asnumber()] ~ 734 | C6[(((K[1] >> 8) & 0xFF)+1):asnumber()] ~ 735 | C7[((K[8] & 0xFF)+1):asnumber()] 736 | L[8] = 737 | C0[((K[8] >> 56)+1):asnumber()] ~ 738 | C1[(((K[7] >> 48) & 0xFF)+1):asnumber()] ~ 739 | C2[(((K[6] >> 40) & 0xFF)+1):asnumber()] ~ 740 | C3[(((K[5] >> 32) & 0xFF)+1):asnumber()] ~ 741 | C4[(((K[4] >> 24) & 0xFF)+1):asnumber()] ~ 742 | C5[(((K[3] >> 16) & 0xFF)+1):asnumber()] ~ 743 | C6[(((K[2] >> 8) & 0xFF)+1):asnumber()] ~ 744 | C7[((K[1] & 0xFF)+1):asnumber()] 745 | 746 | K[1] = L[1]:copy() 747 | K[2] = L[2]:copy() 748 | K[3] = L[3]:copy() 749 | K[4] = L[4]:copy() 750 | K[5] = L[5]:copy() 751 | K[6] = L[6]:copy() 752 | K[7] = L[7]:copy() 753 | K[8] = L[8]:copy() 754 | 755 | L[1] = 756 | C0[((state[1] >> 56)+1):asnumber()] ~ 757 | C1[(((state[8] >> 48) & 0xFF)+1):asnumber()] ~ 758 | C2[(((state[7] >> 40) & 0xFF)+1):asnumber()] ~ 759 | C3[(((state[6] >> 32) & 0xFF)+1):asnumber()] ~ 760 | C4[(((state[5] >> 24) & 0xFF)+1):asnumber()] ~ 761 | C5[(((state[4] >> 16) & 0xFF)+1):asnumber()] ~ 762 | C6[(((state[3] >> 8) & 0xFF)+1):asnumber()] ~ 763 | C7[((state[2] & 0xFF)+1):asnumber()] ~ 764 | K[1] 765 | L[2] = 766 | C0[((state[2] >> 56)+1):asnumber()] ~ 767 | C1[(((state[1] >> 48) & 0xFF)+1):asnumber()] ~ 768 | C2[(((state[8] >> 40) & 0xFF)+1):asnumber()] ~ 769 | C3[(((state[7] >> 32) & 0xFF)+1):asnumber()] ~ 770 | C4[(((state[6] >> 24) & 0xFF)+1):asnumber()] ~ 771 | C5[(((state[5] >> 16) & 0xFF)+1):asnumber()] ~ 772 | C6[(((state[4] >> 8) & 0xFF)+1):asnumber()] ~ 773 | C7[((state[3] & 0xFF)+1):asnumber()] ~ 774 | K[2] 775 | L[3] = 776 | C0[((state[3] >> 56)+1):asnumber()] ~ 777 | C1[(((state[2] >> 48) & 0xFF)+1):asnumber()] ~ 778 | C2[(((state[1] >> 40) & 0xFF)+1):asnumber()] ~ 779 | C3[(((state[8] >> 32) & 0xFF)+1):asnumber()] ~ 780 | C4[(((state[7] >> 24) & 0xFF)+1):asnumber()] ~ 781 | C5[(((state[6] >> 16) & 0xFF)+1):asnumber()] ~ 782 | C6[(((state[5] >> 8) & 0xFF)+1):asnumber()] ~ 783 | C7[((state[4] & 0xFF)+1):asnumber()] ~ 784 | K[3] 785 | L[4] = 786 | C0[((state[4] >> 56)+1):asnumber()] ~ 787 | C1[(((state[3] >> 48) & 0xFF)+1):asnumber()] ~ 788 | C2[(((state[2] >> 40) & 0xFF)+1):asnumber()] ~ 789 | C3[(((state[1] >> 32) & 0xFF)+1):asnumber()] ~ 790 | C4[(((state[8] >> 24) & 0xFF)+1):asnumber()] ~ 791 | C5[(((state[7] >> 16) & 0xFF)+1):asnumber()] ~ 792 | C6[(((state[6] >> 8) & 0xFF)+1):asnumber()] ~ 793 | C7[((state[5] & 0xFF)+1):asnumber()] ~ 794 | K[4] 795 | L[5] = 796 | C0[((state[5] >> 56)+1):asnumber()] ~ 797 | C1[(((state[4] >> 48) & 0xFF)+1):asnumber()] ~ 798 | C2[(((state[3] >> 40) & 0xFF)+1):asnumber()] ~ 799 | C3[(((state[2] >> 32) & 0xFF)+1):asnumber()] ~ 800 | C4[(((state[1] >> 24) & 0xFF)+1):asnumber()] ~ 801 | C5[(((state[8] >> 16) & 0xFF)+1):asnumber()] ~ 802 | C6[(((state[7] >> 8) & 0xFF)+1):asnumber()] ~ 803 | C7[((state[6] & 0xFF)+1):asnumber()] ~ 804 | K[5] 805 | L[6] = 806 | C0[((state[6] >> 56)+1):asnumber()] ~ 807 | C1[(((state[5] >> 48) & 0xFF)+1):asnumber()] ~ 808 | C2[(((state[4] >> 40) & 0xFF)+1):asnumber()] ~ 809 | C3[(((state[3] >> 32) & 0xFF)+1):asnumber()] ~ 810 | C4[(((state[2] >> 24) & 0xFF)+1):asnumber()] ~ 811 | C5[(((state[1] >> 16) & 0xFF)+1):asnumber()] ~ 812 | C6[(((state[8] >> 8) & 0xFF)+1):asnumber()] ~ 813 | C7[((state[7] & 0xFF)+1):asnumber()] ~ 814 | K[6] 815 | L[7] = 816 | C0[((state[7] >> 56)+1):asnumber()] ~ 817 | C1[(((state[6] >> 48) & 0xFF)+1):asnumber()] ~ 818 | C2[(((state[5] >> 40) & 0xFF)+1):asnumber()] ~ 819 | C3[(((state[4] >> 32) & 0xFF)+1):asnumber()] ~ 820 | C4[(((state[3] >> 24) & 0xFF)+1):asnumber()] ~ 821 | C5[(((state[2] >> 16) & 0xFF)+1):asnumber()] ~ 822 | C6[(((state[1] >> 8) & 0xFF)+1):asnumber()] ~ 823 | C7[((state[8] & 0xff)+1):asnumber()] ~ 824 | K[7] 825 | L[8] = 826 | C0[((state[8] >> 56)+1):asnumber()] ~ 827 | C1[(((state[7] >> 48) & 0xFF)+1):asnumber()] ~ 828 | C2[(((state[6] >> 40) & 0xFF)+1):asnumber()] ~ 829 | C3[(((state[5] >> 32) & 0xFF)+1):asnumber()] ~ 830 | C4[(((state[4] >> 24) & 0xFF)+1):asnumber()] ~ 831 | C5[(((state[3] >> 16) & 0xFF)+1):asnumber()] ~ 832 | C6[(((state[2] >> 8) & 0xFF)+1):asnumber()] ~ 833 | C7[((state[1] & 0xFF)+1):asnumber()] ~ 834 | K[8] 835 | 836 | state[1] = L[1]:copy() 837 | state[2] = L[2]:copy() 838 | state[3] = L[3]:copy() 839 | state[4] = L[4]:copy() 840 | state[5] = L[5]:copy() 841 | state[6] = L[6]:copy() 842 | state[7] = L[7]:copy() 843 | state[8] = L[8]:copy() 844 | end 845 | 846 | self._hash[1] = self._hash[1] ~ state[1] ~ block[1] 847 | self._hash[2] = self._hash[2] ~ state[2] ~ block[2] 848 | self._hash[3] = self._hash[3] ~ state[3] ~ block[3] 849 | self._hash[4] = self._hash[4] ~ state[4] ~ block[4] 850 | self._hash[5] = self._hash[5] ~ state[5] ~ block[5] 851 | self._hash[6] = self._hash[6] ~ state[6] ~ block[6] 852 | self._hash[7] = self._hash[7] ~ state[7] ~ block[7] 853 | self._hash[8] = self._hash[8] ~ state[8] ~ block[8] 854 | end 855 | end 856 | 857 | function M:digest() 858 | local final 859 | local out = {} 860 | local padlen = 0 861 | local j 862 | 863 | final = self:copy() 864 | 865 | final._data = final._data .. string.char(1<<7) 866 | if #final._data > 32 then 867 | final._data = final._data .. string.rep(string.char(0), 64-#final._data) 868 | padlen = 64-#final._data + 32; 869 | else 870 | padlen = 32 - #final._data 871 | end 872 | 873 | final._data = final._data .. 874 | string.rep(string.char(0), padlen) .. 875 | final._len:asbytestring() 876 | 877 | final:update() 878 | 879 | for i=1,#final._hash do 880 | out[i] = final._hash[i]:asbytestring() 881 | end 882 | 883 | return table.concat(out) 884 | end 885 | 886 | function M:hexdigest() 887 | local h 888 | local out = {} 889 | 890 | h = self:digest() 891 | for i=1,#h do 892 | out[i] = string.format("%02X", string.byte(h, i)) 893 | end 894 | return table.concat(out) 895 | end 896 | 897 | return M 898 | -------------------------------------------------------------------------------- /lua-hashings-scm-1.rockspec: -------------------------------------------------------------------------------- 1 | package = "lua-hashings" 2 | version = "scm-1" 3 | 4 | source = { 5 | url = "git://github.com/user-none/lua-hashings.git" 6 | } 7 | 8 | description = { 9 | summary = "Lua hashing library providing a variety of cryptographic hashs and related hash function", 10 | homepage = "https://github.com/user-none/lua-hashings.git", 11 | license = "MIT/X11", 12 | maintainer = "John Schember ", 13 | detailed = [[ 14 | Lua-hashings provides a variety of cryptographically secure hashes and 15 | hash related functions. 16 | 17 | Hashes: 18 | 19 | * adler32 20 | * blake2b 21 | * blake2s 22 | * crc32 23 | * md5 24 | * ripemd160 25 | * sha1 26 | * sha256 27 | * sha3_256 28 | * sha3_512 29 | * sha512 30 | * whirlpool 31 | 32 | Hash functions: 33 | 34 | * hmac 35 | * pbkdf2 36 | ]] 37 | } 38 | 39 | dependencies = { 40 | "lua >= 5.3", 41 | "lua-nums" 42 | } 43 | 44 | build = { 45 | type = "builtin", 46 | modules = { 47 | ["hashings"] = "hashings/init.lua", 48 | ["hashings.adler32"] = "hashings/adler32.lua", 49 | ["hashings.blake2b"] = "hashings/blake2b.lua", 50 | ["hashings.blake2s"] = "hashings/blake2s.lua", 51 | ["hashings.crc32"] = "hashings/crc32.lua", 52 | ["hashings.keccak"] = "hashings/keccak.lua", 53 | ["hashings.md5"] = "hashings/md5.lua", 54 | ["hashings.ripemd160"] = "hashings/ripemd160.lua", 55 | ["hashings.sha1"] = "hashings/sha1.lua", 56 | ["hashings.sha256"] = "hashings/sha256.lua", 57 | ["hashings.sha3_256"] = "hashings/sha3_256.lua", 58 | ["hashings.sha3_512"] = "hashings/sha3_512.lua", 59 | ["hashings.sha512"] = "hashings/sha512.lua", 60 | ["hashings.whirlpool"] = "hashings/whirlpool.lua", 61 | 62 | ["hashings.hmac"] = "hashings/hmac.lua", 63 | ["hashings.pbkdf2"] = "hashings/pbkdf2.lua" 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /test/runner.lua: -------------------------------------------------------------------------------- 1 | local hashings = require("hashings") 2 | require("vectors") 3 | 4 | local M = {} 5 | 6 | local function run_hash_test(hmod, name, input, output) 7 | hmod = hmod() 8 | 9 | for i=1,#input do 10 | hmod:update(input[i]) 11 | hd = hmod:hexdigest() 12 | 13 | if hd == output[i] then 14 | -- Run the digest again if the output matches to verify calling digest 15 | -- doesn't update the internal data. 16 | hd = hmod:hexdigest() 17 | if hd ~= output[i] then 18 | print("\tFail: " .. name .. " - digest again") 19 | return false 20 | end 21 | else 22 | print("\tFail: " .. name.." '"..hd.."'") 23 | return false 24 | end 25 | end 26 | 27 | return true 28 | end 29 | 30 | function M.hash_runner(name, hmod, output) 31 | local fail = false 32 | 33 | print("Hash Test: ".. name .. "...") 34 | 35 | for i=1,#hash_test_names do 36 | if output[hash_test_names[i]] == nil then 37 | print("\tOutput for test "..hash_test_names[i].." missing") 38 | else 39 | if not run_hash_test(hmod, hash_test_names[i], hash_test_input[hash_test_names[i]], output[hash_test_names[i]]) then 40 | fail = true 41 | end 42 | end 43 | end 44 | 45 | if not fail then 46 | print("\tPass") 47 | end 48 | end 49 | 50 | function M.hmac_runner(name, hmod, output) 51 | local fail = false 52 | local hmac 53 | local hd 54 | local tname 55 | local input 56 | local j 57 | 58 | print("HMAC Test: ".. name .. "...") 59 | 60 | for i=1,#hmac_test_names do 61 | tname = hmac_test_names[i] 62 | if output[tname] == nil then 63 | print("\tOutput for test "..hmac_test_names[i].." missing") 64 | else 65 | j = 1 66 | input = hmac_test_input[tname] 67 | hmac = hashings.hmac(hmod, input[1]) 68 | for i=2,#input do 69 | hmac:update(input[i]) 70 | hd = hmac:hexdigest() 71 | if hd ~= output[tname][j] then 72 | print("\tFail: " .. tname .. "(" .. tostring(j) .. ") '" .. hd .. "'") 73 | fail = true 74 | break 75 | end 76 | j = j+1 77 | end 78 | end 79 | end 80 | 81 | if not fail then 82 | print("\tPass") 83 | end 84 | end 85 | 86 | function M.pbkdf2_runner(name, hmod, output) 87 | local fail = false 88 | local hd 89 | 90 | print("PBKDF2 Test: ".. name .. "...") 91 | 92 | for i=1,#pbkdf2_test_names do 93 | local tname = pbkdf2_test_names[i] 94 | if output[tname] == nil then 95 | print("\tOutput for test "..tname.." missing") 96 | else 97 | hd = hashings.pbkdf2(hmod, pbkdf2_test_input[tname][1], pbkdf2_test_input[tname][2], pbkdf2_test_input[tname][3]) 98 | if hd ~= output[tname] then 99 | print("\tFail: " .. tname .." '"..hd.."'") 100 | fail = true 101 | end 102 | end 103 | end 104 | 105 | if not fail then 106 | print("\tPass") 107 | end 108 | end 109 | 110 | return M 111 | -------------------------------------------------------------------------------- /test/test.lua: -------------------------------------------------------------------------------- 1 | require("test_adler32") 2 | require("test_blake2b") 3 | require("test_blake2s") 4 | require("test_crc32") 5 | require("test_md5") 6 | require("test_ripemd160") 7 | require("test_sha1") 8 | require("test_sha256") 9 | require("test_sha3_256") 10 | require("test_sha3_512") 11 | require("test_sha512") 12 | require("test_whirlpool") 13 | -------------------------------------------------------------------------------- /test/test_adler32.lua: -------------------------------------------------------------------------------- 1 | local hmod = require("hashings").adler32 2 | local runner = require("runner") 3 | 4 | local hash_test_output = { 5 | v1 = { "00000001" }, 6 | v2 = { "024D0127" }, 7 | v3 = { "0D0B0277" }, 8 | v4 = { "5BDC0FDA" }, 9 | v5 = { "E45D177F" }, 10 | v6 = { "042C181F" }, 11 | v7 = { "24CD18C1" }, 12 | v8 = { "46521965" }, 13 | v9 = { "68BE1A0B" }, 14 | v10 = { "75183235" }, 15 | v11 = { "C773331A" }, 16 | v12 = { "1B433401" }, 17 | v13 = { "706D34EA" }, 18 | v14 = { "C70335D5" }, 19 | v15 = { "CDD5D52B" }, 20 | v16 = { "A298D795" }, 21 | v17 = { "7BC6DA01" }, 22 | v18 = { "5962DC6F" }, 23 | v19 = { "3B6FDEDF" }, 24 | v20 = { "98EE5DDF" }, 25 | v21 = { "116D0FD7" }, 26 | v22 = { "50C46121", "19CE6AD7" }, 27 | v23 = { "F9F30EB3", "09280F26", "18C20F9A" } 28 | } 29 | 30 | runner.hash_runner("adler32", hmod, hash_test_output) 31 | -------------------------------------------------------------------------------- /test/test_blake2b.lua: -------------------------------------------------------------------------------- 1 | local hmod = require("hashings").blake2b 2 | local runner = require("runner") 3 | 4 | local hash_test_output = { 5 | v1 = { "786A02F742015903C6C6FD852552D272912F4740E15847618A86E217F71F5419D25E1031AFEE585313896444934EB04B903A685B1448B755D56F701AFE9BE2CE" }, 6 | v2 = { "BA80A53F981C4D0D6A2797B69F12F6E94C212F14685AC4B74B12BB6FDBFFA2D17D87C5392AAB792DC252D5DE4533CC9518D38AA8DBF1925AB92386EDD4009923" }, 7 | v3 = { "36DFDC408593CE71BA54E708018719B0F451B1912A762A9F3B992BB96E878D9C592D90AD141D4D39A61A751E61590657F3D1C471F93D5A094B5A113969061E89" }, 8 | v4 = { "A8ADD4BDDDFD93E4877D2746E62817B116364A1FA7BC148D95090BC7333B3673F82401CF7AA2E4CB1ECD90296E3F14CB5413F8ED77BE73045B13914CDCD6A918" }, 9 | v5 = { "ABA9F147DBCB8A3C3D8AF8245AB2E1A304A847CE7E6CFFE8AD9F24E9621ADF5B73B5891520F8725DFD3E611BF668C4E1CF55C0B09B5794B1F7F9630C77B60BF9" }, 10 | v6 = { "C13BDD6CC33F7D685E1F5E926A9A74E0CFA3614968E3880615ABE84C289E2359F3E3028EDF86AD35E283480768D434C9BEF6D06D2B29B8A7410BF97C47138288" }, 11 | v7 = { "75B1107E926A96825EC266B316C459A94871E7E5408E55C7A3611736A75DAF9BDB51082D0A188B67240D690B2821FF2F8B2F881B3CD18ED3ED128CDEFD8CD10B" }, 12 | v8 = { "A39BA29CF84B2AAEAB68A6069CB4E3EC67DF2AB68374C441F1CDE18265FDF5D644E06CB7C9D8E58DDAA72DEE74449A7F7D626389CE60AA588F1BD7C37C6B18B8" }, 13 | v9 = { "B699297E52F21C014CBBC61E401E58AC84553199402EE653EC8DEBAABD3324F4C45F955D6D98120CBD18F318E7216587A33F18CD8E72F7E17962EC7CFE208DA2" }, 14 | v10 = { "41033BF23B0E3CD6E6D3C930C1155CC471D36E47A47A1A2CD1EE4ED53CC230DF4B7F25026EDF41101181FC38A89BF808E290EDBD3857FDBB71D0BA3C9684DA8F" }, 15 | v11 = { "BADF7262B5BE700B9814A321DAE4A5772791AEC8B99E26978AFCE9CD99976A35D084FF2E975083D351EB2EC9D197D345D7FFAAA1DAFB5B14E5EDB2981E93CD30" }, 16 | v12 = { "376B2A0270310EC5F92587DC9154DF08A94E3D8F4B50F39530418AEA2B8F4A94039F75EBFACA1E12F3ADD089DF9F20C5125607ED890FD988C3D1B9B9475DEBF4" }, 17 | v13 = { "66A19ACE42E9B83F77A925D0C1FA51E61957B218FFE4461AD253BEB887D89CC5D4A2EC8DDCBE4DE708A5B75BE924FB82BA370427F4E86145CCEA5F4481A85D6A" }, 18 | v14 = { "7CCD26BF2D1C255D3BEEC7B6D6BE59D122BCC7E82C8EBAD4A0038ADE7B93E26496640CA74408E398A83457CDD679C560B6CF586B66E4B3D7A2A4DB0F3E4DDC08" }, 19 | v15 = { "89AC793C7E69A40513E85326EDE597F5F38106D99FCDEE7F985F4D2922A9487003BA2ED4DD79A2FD622B34395944F92650F5AE865D4C2B16A82AAF3A2885A832" }, 20 | v16 = { "B59944117E09D8829306E0DFBDB347255A71343B801D0E5A488F4CBCA24211F258FAB5280824F32FD5777F16B5BD6D3C786E50AAA132092B704AF78491BDA6F2" }, 21 | v17 = { "598D88741C77D79DEB3A5EFC23417E627E141BE5E1579FDA60E2428D2F20A1A054B64E182CD27743C41C442634E1A1950CD70EC5280F29D577E27B0024A2AD07" }, 22 | v18 = { "17FE864B52F3B62C3C35F37788CF68B5D1D59F8019357BA53D6099A93E4D65121FFD352A459152B07E44AF6BBB1E1098081E3A612AE68609ECE59EC05B6241D5" }, 23 | v19 = { "23D6FEC4B4442FBBD6589D9731F8166CE9460B4DDA174C58D4B464E04A3FF1E439F274F88E35311F93F2BCF0ECF6113EB71F667A6FC02F8B0F8C56C91BB42256" }, 24 | v20 = { "A911E95D599AB49DED17FA996CCC7F57B20463D77C38ECF6FB5FD9D236DA0AE8A42D90839581E69C0834D2FCEBF839B0C9F30E1930F91340CA528F7DCEB226C3" }, 25 | v21 = { "6077C66A1CA4D93673043A118C94948D8E216E605E573A1FEF0A0B3104800C9B6F12C5FB823B3DBBE91FA62ACD52FAFE5877ECA5C3F1F5D031F9B4ED58C1A6BA" }, 26 | v22 = { "0C806DF52E2D65100C5348FF41104D57E724DD5EA52B4CA110A2C606B88AF9937C474B1969D2C9033A7BADDC344A8BAE3248EC28A1BC5C004733F5C89A6A86AA", "A5647BD8394E1EDFB120E5EA23B00EE806A64BB4A8BC3E1324ED2E665BF90460E67C6C782D4B17D379E645A261C905319A90BC23168FEFFF86415F65E1D1CC33" }, 27 | v23 = { "F5742F7AEBB77435B036E68FEF8399E3CB629F83BA721CECD222F50BC3ACBB4E77E932D8F984D8E5340C29DD4633CFBB6186C66726173B3269A405259C11501F", "67AD64807E3CD1B60579A50EF264A12EC2646745DCBC6E0576995F7CBB7F97F900313B812876D489CD0053002F9631B9BDC85F00F72DC7926BEDAAEF502D6980", "3059872EE80DC9143668E3B683977403CCA3A1A52464C17AABB0BAE68B719D81A6134F45428A1CC92974904658C40201A5B8F98FC14ED046EF1E83938D336218" } 28 | } 29 | 30 | runner.hash_runner("blake2b", hmod, hash_test_output) 31 | -------------------------------------------------------------------------------- /test/test_blake2s.lua: -------------------------------------------------------------------------------- 1 | local hmod = require("hashings").blake2s 2 | local runner = require("runner") 3 | 4 | local hash_test_output = { 5 | v1 = { "69217A3079908094E11121D042354A7C1F55B6482CA1A51E1B250DFD1ED0EEF9" }, 6 | v2 = { "508C5E8C327C14E2E1A72BA34EEB452F37458B209ED63A294D999B4C86675982" }, 7 | v3 = { "6FE6A61D36DD4F9BDD3999BD9E35C53ABC650AA1B926FCB5807DE7B5F1704FD1" }, 8 | v4 = { "606BEEEC743CCBEFF6CBCDF5D5302AA855C256C29B88C8ED331EA1A6BF3C8812" }, 9 | v5 = { "1109521FEED362D8AC50E28784406E8B8577E9103F74C7DDE7E7C5339A700E9F" }, 10 | v6 = { "46BA9185AA823559D31B9682338353CB535CBA84648A575E29BE2DD2712F6CBC" }, 11 | v7 = { "0D61429825CE22866DA7490E1369670E6F61BBCEA831266C96C9C5886A1481AF" }, 12 | v8 = { "B39A9D609FED058837E9D4F85BFC5723A67C01B98919086B3D4835D7C3F2E05D" }, 13 | v9 = { "BEDB9C535E5D6AD5B77D26D51A456C0A36E1C2AA9B6135A91A97E6559BB91E36" }, 14 | v10 = { "F45DD7BFF0254F6DBE717F8D34B294BEEF0B63301C7465539E720E6C2CADAC43" }, 15 | v11 = { "7C1556AB3B3E4A511605AEE6431D5B1241351A40C82689731884FC1016581B49" }, 16 | v12 = { "3944F8F3203D6F46EFA0C094CC1E1DCAB26B8315584BE1190A8F44A3589AB87F" }, 17 | v13 = { "EFA4CF2F94691527C94550516BF0516B97A47A3993338E48C520939B86E433F2" }, 18 | v14 = { "C515B0AAB9415FB7692704634B78CD56F3ED6FF857F69106DE1419E0045BD7FF" }, 19 | v15 = { "433871A2BB30C07B10CCADCAA32E85D2328251DCCABE328AE092115AE3713F35" }, 20 | v16 = { "6E48805FB8665447038002935E50F152AF02F88EE186998C855818EF8DBEB450" }, 21 | v17 = { "9FF95613AE8DDB3FC30464CA9B4B97B8B0E1124C5AD05255DD4A463BFB2D7FB5" }, 22 | v18 = { "EC16F4B3C1B01666F4E1B3A7EC3459B2F88BF886567011AB058C46E03E3E26B1" }, 23 | v19 = { "E155E0D866904C8AC28F963F1A65C875FD179F24AA8E0627C97D6F13B5A8DE63" }, 24 | v20 = { "F4F5B62BC6C8A1EE951DF1ECFED6BB2F75E04647D51D341AF833722C574D4293" }, 25 | v21 = { "593EE168A41620BB3AF56FBD197E566059FCCCCF0906BE1639E06918352F45C3" }, 26 | v22 = { "1273FC4D7B9DE19D83E5BE5F6B925D952DFAE5FB162EA4AD0AE62A869D701A2F", "D837CE86F21CF40CC7AE56A90909F6147418B3920B8744255CACF79E70A1FE39" }, 27 | v23 = { "0533BC945F491C1271FEC6B2CF5E25DFCE82FEC607221D2BC66787C722F650B6", "C460FE73F564FF635AED33404565A57537DEE384079DB14E9E956C6B3588D2EC", "F8FCF37100BE2B1219201B9527636774E9318C9FF66F6CA6A86B4AD4063C97E5" } 28 | } 29 | 30 | runner.hash_runner("blake2s", hmod, hash_test_output) 31 | 32 | -------------------------------------------------------------------------------- /test/test_crc32.lua: -------------------------------------------------------------------------------- 1 | local hmod = require("hashings").crc32 2 | local runner = require("runner") 3 | 4 | local hash_test_output = { 5 | v1 = { "00000000" }, 6 | v2 = { "352441C2" }, 7 | v3 = { "C2690FDF" }, 8 | v4 = { "414FA339" }, 9 | v5 = { "F61C5695" }, 10 | v6 = { "A0CAAF8B" }, 11 | v7 = { "75347667" }, 12 | v8 = { "41DE955C" }, 13 | v9 = { "4D027FE6" }, 14 | v10 = { "1550633F" }, 15 | v11 = { "04F9AD2B" }, 16 | v12 = { "D679541E" }, 17 | v13 = { "23F7D295" }, 18 | v14 = { "F420E643" }, 19 | v15 = { "2D865A4C" }, 20 | v16 = { "9097C7F1" }, 21 | v17 = { "6D632434" }, 22 | v18 = { "CDE6DF13" }, 23 | v19 = { "B4CDD8F1" }, 24 | v20 = { "76629A1C" }, 25 | v21 = { "C3747D4F" }, 26 | v22 = { "3DDE37A0", "EDF632E1" }, 27 | v23 = { "F7F4B8DB", "0AF830EF", "B5D55D71" } 28 | } 29 | 30 | runner.hash_runner("crc32", hmod, hash_test_output) 31 | -------------------------------------------------------------------------------- /test/test_md5.lua: -------------------------------------------------------------------------------- 1 | local hmod = require("hashings").md5 2 | local runner = require("runner") 3 | 4 | local hash_test_output = { 5 | v1 = { "D41D8CD98F00B204E9800998ECF8427E" }, 6 | v2 = { "900150983CD24FB0D6963F7D28E17F72" }, 7 | v3 = { "39D0D586A701E199389D954F2D592720" }, 8 | v4 = { "9E107D9D372BB6826BD81D3542A419D6" }, 9 | v5 = { "24612F0CE2C9D2CF2B022EF1E027A54F" }, 10 | v6 = { "2270DD76C5CCD0F130993BF395915D06" }, 11 | v7 = { "BCD5708ED79B18F0F0AAA27FD0056D86" }, 12 | v8 = { "8962DB95A4C1F6EB93ACF5F1455B66E0" }, 13 | v9 = { "AE3FC22818DDD86D6882EDE68B49131A" }, 14 | v10 = { "0502661254F13C89973CB3A83E0CBEC0" }, 15 | v11 = { "AB4C157745EEDF1AEC9E2F58B0E17027" }, 16 | v12 = { "8AA3C99436BB00B28EAD91FA77C20B36" }, 17 | v13 = { "113A0663226B46ED51EF0BE4A8A18D77" }, 18 | v14 = { "02E125B9E80FE5AF053D716DC2AF379F" }, 19 | v15 = { "599BE40C139904DB995E4164FB36E594" }, 20 | v16 = { "43A3E0BE7C032DA1AB072DED02122206" }, 21 | v17 = { "0272018238BDBE60094283596BB92DB3" }, 22 | v18 = { "6757FB2376040EED986EDC39B9368C5F" }, 23 | v19 = { "AFC725E494D19E44197B72B2BBFE6B6B" }, 24 | v20 = { "220F35327CDD178AE2999CC887D6722F" }, 25 | v21 = { "82DD67AE61E6D8C41001BFA214A2CEC1" }, 26 | v22 = { "C8F60FF54D7888613A4552D738221E67", "A230F74A6D07AA638809A27F64F76D99" }, 27 | v23 = { "69972A932E4F3C199F49EBD1FA0EF398", "F0D97ACADEF223BA0F22D7F1FDFC6980", "15CA0901C9A4C34C8FBB78E96A9008E6" } 28 | } 29 | 30 | local hmac_test_output = { 31 | v1 = { "E630E7BA6E333361D5C626A542D0A1C6" }, 32 | v2 = { "3055AF9F075E3E6B4B431EAC67103E3D" }, 33 | v3 = { "FC4F2DB12931D7F6D4475E5A9D1B406A", "9371DDD05368E6B329F27146798E8A54" }, 34 | v4 = { "0344C9A6973CD820B57A3759C3890C31", "7B132B424E63178E7D396A3BE28F515A", "D361784B00DABA2D9561C32E9E287006" } 35 | } 36 | 37 | runner.hash_runner("md5", hmod, hash_test_output) 38 | runner.hmac_runner("md5", hmod, hmac_test_output) 39 | -------------------------------------------------------------------------------- /test/test_ripemd160.lua: -------------------------------------------------------------------------------- 1 | local hmod = require("hashings").ripemd160 2 | local runner = require("runner") 3 | 4 | local hash_test_output = { 5 | v1 = { "9C1185A5C5E9FC54612808977EE8F548B2258D31" }, 6 | v2 = { "8EB208F7E05D987A9B044A8E98C6B087F15A0BFC" }, 7 | v3 = { "007280D8D04D9ED15B80BA0AC778E8DAB2BADE89" }, 8 | v4 = { "37F332F68DB77BD9D7EDD4969571AD671CF9DD3B" }, 9 | v5 = { "AB79697005EBAA6193C5B62FC04CE3E14FDE781C" }, 10 | v6 = { "155BC4A51549E7106B370B45492FCA83728A0239" }, 11 | v7 = { "238F0264369668E547848E2760064B8A6C0D624B" }, 12 | v8 = { "4F7F297FABA2DB1C857777A803A972D9BAB4F07D" }, 13 | v9 = { "B4BF31B9ADA44DD67A875CEF0F0963C0FE1C0F70" }, 14 | v10 = { "499644C167C6D4E329947A03564B07092D55B9E2" }, 15 | v11 = { "3CCBC3A58B9CE27BF2E9713C57741AD4434FE46A" }, 16 | v12 = { "A30C2AA3F88B0E7C716F38EEDA35CEA57E053AA1" }, 17 | v13 = { "A006FFDE18D2EB3A162BAA768C08BBA080EDE4D8" }, 18 | v14 = { "4ED00D372F4A9DE08714B5B3E6CED7D77C480BB4" }, 19 | v15 = { "27C4B258229D19A603AC3B96872D2A24CAFAFBED" }, 20 | v16 = { "49A749653476F3163348036FDAAA48227AA55252" }, 21 | v17 = { "0DD97C4E2314D0CFF92C3C53787AE29B30D8834D" }, 22 | v18 = { "6729DC2D66635746C59A1A6C6596D30189184147" }, 23 | v19 = { "8F890A5CDCA493E48A24399171CAD1F04867E998" }, 24 | v20 = { "1F25ED73069130148927018196324D4542A782DD" }, 25 | v21 = { "FDB8D4778DE02D3F78A8542FDF45510470465BCA" }, 26 | v22 = { "FC1928D686FF96E08DF823D0BF933F75FDB667D9", "ABD2F552CA15489881F9C14F38EBC9B2F8F6AA32" }, 27 | v23 = { "566CBE1167D3A7E40068F41835F5BAB536509DE9", "C1B36CAE8E1E5CE6A6BD9C9949EB6B854987EE21", "AE5673A78017A9A8E4119854CFAB5CB82E902B96" } 28 | } 29 | 30 | local hmac_test_output = { 31 | v1 = { "4D2720387D8ABAAE416D5DC2CBB5F9024169BCCE" }, 32 | v2 = { "D45921EBDB7CB344891B081ADFDFD19490092A9A" }, 33 | v3 = { "B0478940010BEC26C070B52309E7647CBD9E267C", "3195B840F9BDBCEE805B64E19CDA4ED8CEB3ACDD" }, 34 | v4 = { "42628BDBC00F12E5D3ACDFF8BF15DE7147D027B8", "AC7A2844AE2FE787F211DEAFFB92F321146A53CD", "223F43BEEE68367F72FA93797BE0D32D710F2DCE" } 35 | } 36 | 37 | runner.hash_runner("ripemd160", hmod, hash_test_output) 38 | runner.hmac_runner("ripemd160", hmod, hmac_test_output) 39 | -------------------------------------------------------------------------------- /test/test_sha1.lua: -------------------------------------------------------------------------------- 1 | local hmod = require("hashings").sha1 2 | local runner = require("runner") 3 | 4 | local hash_test_output = { 5 | v1 = { "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709" }, 6 | v2 = { "A9993E364706816ABA3E25717850C26C9CD0D89D" }, 7 | v3 = { "20BADB8B25DB064A59D1940472EBA77016A0E978" }, 8 | v4 = { "2FD4E1C67A2D28FCED849EE1BB76E7391B93EB12" }, 9 | v5 = { "67B4B3923FA178D788A9611B76446C96431071F2" }, 10 | v6 = { "956B36ADE6E3E4B7818CED2D611FB95E8ABC2BD0" }, 11 | v7 = { "B29FCB5F41614B4EC81C87E4614FFE8B9ACE1D4E" }, 12 | v8 = { "9B815BFBEB05280B696F4AEE68066C6F98F59646" }, 13 | v9 = { "181FB6F89A543639BCD607BD5CF6261A25C7549D" }, 14 | v10 = { "7CC74DAF65BC1006F596C1B7B0041133B0FD0501" }, 15 | v11 = { "6A5A18FA923BC9D855487703CC292D10ED4A001A" }, 16 | v12 = { "B8E32ABC10F70D42BD3CFD641A5360744EC13104" }, 17 | v13 = { "31812D5182D1E0FC88920EC4231F40E3271BB265" }, 18 | v14 = { "35F014C8301160F5263E5EDAA5BAAEE8A389CB54" }, 19 | v15 = { "1E24A0DBA98EE2F5A2D7D7F8F788DB5FF9BEFC8A" }, 20 | v16 = { "DD25414710EEE424CC24BAE388591552E06D256D" }, 21 | v17 = { "B629F760B90AE99FFD2DCC3040486AA942DB6A5D" }, 22 | v18 = { "95DC377B7CA32B94E9382C98D6DAE5C0816433FA" }, 23 | v19 = { "F0D9BD2551C2D6C7F37B04E494089E0B8343FF89" }, 24 | v20 = { "9FFCDB616084647B96A1D4E7B15FB0394D738F75" }, 25 | v21 = { "A4BB132CFCF2312D17FFC237A38E92A5CF7B93F4" }, 26 | v22 = { "3BBC5DCA3C0A6ADAEE9A57D9D874479862738FC3", "0E074A353385D9403D291E8455FB5CCD2AE8D549" }, 27 | v23 = { "ABDA17BA2B1B30405790FE848B2A3549DADD8E88", "7CB355B5B61FF86B6CD853965EE936AEE8FC0A50", "7F770D18C0BB6B4F48207D9A08D58C32ADC83D18" } 28 | } 29 | 30 | local hmac_test_output = { 31 | v1 = { "6657855686823986C874362731139752014CB60B" }, 32 | v2 = { "A5E91A369D9C5586D7CBFB84E1E292CA6723F29E" }, 33 | v3 = { "8CC660DE79D8FB91587FC4E036A116F400E01EF0", "93B31D4C34336408C5B5D2BCE773851657E16593" }, 34 | v4 = { "EB1872E7A448F719550E7D64C81E63F789E81A22", "1444B71B5429771B2CE0A2008E26C60FD92EC5C2", "DFE1DDDBCF79E45B8F7A840639AEDA88ACCE5D68" } 35 | } 36 | 37 | local pbkdf2_test_output = { 38 | v1 = "D1D1D5D8575042070CC8D865AA24621B41F77452", 39 | v2 = "C02F28722B700190FBB675766EDBBF460AC15DA4", 40 | } 41 | 42 | runner.hash_runner("sha1", hmod, hash_test_output) 43 | runner.hmac_runner("sha1", hmod, hmac_test_output) 44 | runner.pbkdf2_runner("sha1", hmod, pbkdf2_test_output) 45 | -------------------------------------------------------------------------------- /test/test_sha256.lua: -------------------------------------------------------------------------------- 1 | local hmod = require("hashings").sha256 2 | local runner = require("runner") 3 | 4 | local hash_test_output = { 5 | v1 = { "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855" }, 6 | v2 = { "BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD" }, 7 | v3 = { "F7EF53D21502321EAECB78BB405B7FF266253B4A27D89B9B8C4DA5847CDD1B9D" }, 8 | v4 = { "D7A8FBB307D7809469CA9ABCB0082E4F8D5651E46D3CDB762D02D0BF37C9E592" }, 9 | v5 = { "F506898CC7C2E092F9EB9FADAE7BA50383F5B46A2A4FE5597DBB553A78981268" }, 10 | v6 = { "94E419FABAC7F930810F9636354042F8C1426D2F834D4AB65C93DC1E69326B13" }, 11 | v7 = { "52B6419D27BD7F547CEE3B92F8C17A908B8A49601ECBEC161E5030DE1DFE9E0A" }, 12 | v8 = { "899987F295364060C6ABD752A7E895124B467FD7CF56B52CE22F4A684A5723F4" }, 13 | v9 = { "AC7E96C630650857439C5AC18603A5AA8F9154C080A05A7858FE9F5694428D7A" }, 14 | v10 = { "AF9342E7FDF6A632CAC37A375EB9057325C9D44B608D6BE0792D6F92E0646718" }, 15 | v11 = { "F071645658F95C502FF32EF04C678B250FB4EE41D0147E898ACEE132CDAFDC5B" }, 16 | v12 = { "8720E03272DE2D4B660C41F52BB61597B569F576989EB895F2075BEED4DEBDAB" }, 17 | v13 = { "77A8301D1755947925B1E03A74470BC1EE47E1669BDCCCB5700752FECDFD94BA" }, 18 | v14 = { "466383BCB41954E34017DFF9AD661299F7992DC0AE9085C4867DDB235F236995" }, 19 | v15 = { "778A8CA56E915E224A53BC981D235696C586F471654E5BA93E6D37DA58BF8CB6" }, 20 | v16 = { "4A83CD2045150FEDB04E66AF0B726B84BD9685B4305CFD78C975276311549839" }, 21 | v17 = { "20E45866084B5BB116FB0F7217FB91D67029FE7AEBA911A2160440AED1139988" }, 22 | v18 = { "924E4CA78CA9862A93DA95E8BA3C3E7CFB7489C922916591A4170D0439D0AB7F" }, 23 | v19 = { "6285825761D8FEC75564385B299D10A097890B987BE7C759D4F4E0BD7FCC4962" }, 24 | v20 = { "536C4AAFD7347354BC5EE38EABA10B965097D861BCA3D416844790F5A063803C" }, 25 | v21 = { "9C355C3A10CFCE93813A024160E32A8458BB0A979B70CA6012A48B9930B4AF12" }, 26 | v22 = { "E830DD650DDA5C905B13F23363660EF7D65B156A7481FFE16DB4482C37012671", "09A3DC9726D905DB10FA4300BE3BC9B7698223FD14BC4C3C07D50E1880CD2A0D" }, 27 | v23 = { "83145E41E6F4FF6CDF478BB37AE12BF39A1B096D5A576871E630880AB07A77F2", "1F39A5F8CF37EADDA2AABEFDC15DEFAC29900A1F00E2B11FA4C65A156F982BC5", "A8CCF26483555FAD76D401C0F0DB122FBDC168EC2C7C0C30469087A6CBDFE843" } 28 | } 29 | 30 | local hmac_test_output = { 31 | v1 = { "08DE329931E295683776AA9A43529BD0B275286DF3160300C49BA4E841833013" }, 32 | v2 = { "DEEECC926FF7B20C12802D5BD3E8CE4FA9D3938A684A13BD374CE45C2EC6082C" }, 33 | v3 = { "5BB19FC9B15D248FD102864D0AD93A9DDCAD0F44DBE52DD8E4E6BC5241ECDB2D", "2CEC83CAE3F5ABB1643EC7D75C2D805F0F5B36D07A321A122983B212394B3B7E" }, 34 | v4 = { "391C00359D7D53FE73677831A9705F977FD3B78EED95BF054A1C3504931478E8", "418C9C485647A970E5D3EFE411CC4971AE3CD72C0A815BCAEDDB42DF75D6FF5D", "9A2A2DCCCFE14DEB195EFA1A1D18407A07C73F5DAA561892F179AE038B1A5022" } 35 | } 36 | 37 | runner.hash_runner("sha256", hmod, hash_test_output) 38 | runner.hmac_runner("sha256", hmod, hmac_test_output) 39 | -------------------------------------------------------------------------------- /test/test_sha3_256.lua: -------------------------------------------------------------------------------- 1 | local hmod = require("hashings").sha3_256 2 | local runner = require("runner") 3 | 4 | local hash_test_output = { 5 | v1 = { "A7FFC6F8BF1ED76651C14756A061D662F580FF4DE43B49FA82D80A4B80F8434A" }, 6 | v2 = { "3A985DA74FE225B2045C172D6BD390BD855F086E3E9D525B46BFE24511431532" }, 7 | v3 = { "C2B2CD4FA9B92ED8FB062E931FA10F94C6236E377D5328AAF156B50BFAA3A239" }, 8 | v4 = { "69070DDA01975C8C120C3AADA1B282394E7F032FA9CF32F4CB2259A0897DFC04" }, 9 | v5 = { "FC51EC1E0B7359383048CD3E985197A28119AC8F110CD33254F4B9E8AEF23220" }, 10 | v6 = { "6869865C752C5AFD87BFBECE22FDEFB031B5D6C01AB86D104302BAF903A27CE7" }, 11 | v7 = { "1808E70C666D55DD1826F6E20F1E628F878946CDACC2B28A4F621224EE6EE2F3" }, 12 | v8 = { "42AEF9221D5A149A54E8337F25FB22041155E391457508B395DC2427AB46AD40" }, 13 | v9 = { "F50632E6F308A1F18AFD3A84FEF46DF56931FD969E0233661CB7E5BD30DC15E1" }, 14 | v10 = { "D64919D34B731F3F080AD2FC94F876B79E730DE0ACF36D1EDDD1F0A91673B08A" }, 15 | v11 = { "F29F2B6584B56E42DD022A791902D4F23CF783985CAA05B97906FADD1205AE77" }, 16 | v12 = { "1744F7BD7D288B4E585587C4B228D17AD3D896A8B1880AD51D14FCF34969734A" }, 17 | v13 = { "622327AC9BFB7336C6FA39AA7618648F85A2EA9D814411BF6A49B994B84D0186" }, 18 | v14 = { "BF964F8AC6243E0A53E63CEF4E78B954655116A5BAE51EBCD9F283C7453E7972" }, 19 | v15 = { "13B4CBAFBEF29C2696D3D6D6DD68387B5E843C0BCB6C24C09A3F3E9D9FCA618E" }, 20 | v16 = { "D000F845B1E270EA74BACC7D4D7984BD5B84E60B6FB3FADB25BF4013C70DDE0B" }, 21 | v17 = { "D8A2ED80CEBD14C758EA065441F66DF081B0A1530B2804B31600C5A1BD0529B1" }, 22 | v18 = { "6278C9F82F06AD1518CC8E54843A02D5CD695A0FA1151E0989CDC75FD93B81A7" }, 23 | v19 = { "5AE34323B29465573F47AA65EB69978FF631AD627862052EFA70A8FAB9C05FB2" }, 24 | v20 = { "9E88635310939D7AFDA175A8934BFE2E97EB8143E7AEA335676CFE68450AE633" }, 25 | v21 = { "DA1F7DB12B02E8600D615D033796502E3167318AF875B7AA2205F53D10E9BCA8" }, 26 | v22 = { "C93DDF19AF13B3269F3EFB705014F028B3A352D75CF7822AA6AB87430B68F822", "48B9DFC30C9D9B674E5C0B226E52CC93D0F499D17590C5491735894AA4207872" }, 27 | v23 = { "E7CFA22AC39414FACA784C07F27AB4181B63E2398382D04A582FAB28296B147C", "F950058103479C498C40FF14FDA65D788930EF6CC31E91650E2287605035F451", "DF14F1A80B1AAE0DBC2D37C8DC2741D646D0E2E7133BC5AE296E9C545AE37ADC" } 28 | } 29 | 30 | runner.hash_runner("sha3_256", hmod, hash_test_output) 31 | -------------------------------------------------------------------------------- /test/test_sha3_512.lua: -------------------------------------------------------------------------------- 1 | local hmod = require("hashings").sha3_512 2 | local runner = require("runner") 3 | 4 | local hash_test_output = { 5 | v1 = { "A69F73CCA23A9AC5C8B567DC185A756E97C982164FE25859E0D1DCC1475C80A615B2123AF1F5F94C11E3E9402C3AC558F500199D95B6D3E301758586281DCD26" }, 6 | v2 = { "B751850B1A57168A5693CD924B6B096E08F621827444F70D884F5D0240D2712E10E116E9192AF3C91A7EC57647E3934057340B4CF408D5A56592F8274EEC53F0" }, 7 | v3 = { "8273EB838C349EC3809734540417781EBAB8D8669D84EAAC5F8DE1FF67450FC81CB880F29D32F0FF0E9AC5804A80BF5675E122683510735CEB92E7874FCCA1FA" }, 8 | v4 = { "01DEDD5DE4EF14642445BA5F5B97C15E47B9AD931326E4B0727CD94CEFC44FFF23F07BF543139939B49128CAF436DC1BDEE54FCB24023A08D9403F9B4BF0D450" }, 9 | v5 = { "023CA677D6B4F21272B53F3B114775624A4ECE2D20ADC61D77176A4EA6428ED3BB9BB9E125351D477C15672922D9F04B5A35EF02B8AD09251972A49DBD38BB5B" }, 10 | v6 = { "1697BD919489E437916786BCB3D196CABF8581E83581A098DFD478223BE47453B97D5D71F249998DBE57F1C7BE61F0B20158DE56D7C701AABEF923F2177140B1" }, 11 | v7 = { "CF3BC00B759333E749D015650C811BB60F1EE084D30B56AA26B5D5D9CAF3AE2E9C1974F44B215D95637A4DFE03FFC089E54238E904351F27AC5D5D09056E22A1" }, 12 | v8 = { "4BD3438D05E31AD3276C81FFF65E1562A7DCB057D92FEE3F16126C8FE6BB0CB02FCAF6791D2204C5002D33FD060EA0AFBAD0F496F076954B10FA57F449AE10F4" }, 13 | v9 = { "E2FAA5314DD1FBFE5082F0F4664E1E09532DA356C6AA66DED6FF095C1705AB8B6BD0BBE78B410F3CD784D0984D584A4FBBFA9F0D8259A198452B99823ACC9249" }, 14 | v10 = { "FFF813AF86D03D786890BBCA4C88C3FE91271E634A071921E5733E722B20F836D417945EC68184EE4353F1D945E13685205E1C337E1C36D548BE21CE7F83F80D" }, 15 | v11 = { "CFAF4ECB2768F4944EA026BABC362F60D252432C2AD247F6630AFBB1C15FF800947576EE1F4787456D5865A2190B399B8282DD783A7899DCAC736F85BBEBBD63" }, 16 | v12 = { "288C30238791BB568259D51DA7A63BB8FC82A1DD08B611B81FFA327A7E7D2B1A5CE11D1DD2AB0F9C824E81B863FF53B9217085F0855546A78A902AA983EBE3D3" }, 17 | v13 = { "B98857A022D2397B98A89589F17C8BCBFADAE46BDC50425ECAA49D4220DF05EE7A966571EFD3FE9DB0BD713FC2BF90B134A0309C8733AA78E12657F66FA58160" }, 18 | v14 = { "B12CD16E4635CA8391ACF24D3D174EDB3E6C1D9EF028A993625BBA315DB65BB958DA6B70D2A3363FA595E50FD65855CA84AC99872457A6EF43F77B90DE2CCA5F" }, 19 | v15 = { "AC85E56370C7BDE2E35588D3B1F72C9BBC504747D13F594D7C4D83284CC7F9FD121A1D6B25803D2606D8FA782081897D3714D1D520849B6725CAEED217A0105F" }, 20 | v16 = { "9B7E2218FD895CA7259850489F35D53BF1EE8A42AAEE1DBF2225B6215C548EE803F3A96BE8B9363B37655F22C6401DAE539351761C814AC3ED13657FF010462F" }, 21 | v17 = { "57FA9450E81A3D378D414132D40509EF15AB2E8C07303E51E81A19EDBAB0550064C69EBF9944D5A3007D76651A86CCC7C33189E0DA1B8B1532D5C9E8BA6E9852" }, 22 | v18 = { "0EE5067BAE3BC9368F916021882BE7E9915F8EE08E289D7BAA8D64D60793CCBA3CDF93258AA2E18920FF979BD1E1D6DC0BD404759BE1E3750B4FBF9ACC53BF94" }, 23 | v19 = { "41F7E1A0466B40C825CBC9FB50A968178646B3AF7C82ED833915D9DF940B4F6471FEF21F12BC5F6300DD3682CAE681D5BDEA7BBC1D8DC4A959E43170952D5D37" }, 24 | v20 = { "4B690CC3584EB00CF2839BC86FB5B211D98B6A16C58CE7B148413C39599F66C5C796CC12FCA432EF4CD5E9E43724AD1A9254659D163D06A06404E7B893F2B98D" }, 25 | v21 = { "362844D62048C89A513174F7CF6046228D0937974D11097969A763357B6C54920341F76F5963AB300C840796EDAB711E0DE12169B7E846AC02F22C77D07F7EC3" }, 26 | v22 = { "A985DB723CE9C7671925D2961482DD2A25DF667305F9990C6D70B516594812A60497FB59AFC35B2A6C2793E17E95ECCA9D054E12EC99F1DC3B51949F74E502B7", "764588F3E31C897B29AE50ED89A6C4A2E2370DF6B9131A7EB0A6026304260D390D2CB25FBE6245E971A85D20447A507AB6C17D8527247D933B4B19F04B295DA0" }, 27 | v23 = { "723AF8C60A0A13430CF1A80AE34F8A2D92C567AA38362ADC7AC57014827155304F6A26FCC5C479C41512B808298B39186D2E885FD16FA44E9F9EDD89E83B103E", "10ADC0B9E2EEC4D83C4237FE77672DDABAA70B1942A529F9CFF69636D0BF7DC20162BBDA76A37E9AC132B9F7A80FEF4A12AC08CCA41B8C33BD6B85D74C275B37", "DBC611DF76418C7218CE64B7F3E7557F6DBA118BC38ABEB36E4B2C7A4ABBCF9E89A47A2297BA4EECA52C3E3786910CEA3BAB89DF7A54AEE91A8050991D29D89B" } 28 | } 29 | 30 | runner.hash_runner("sha3_512", hmod, hash_test_output) 31 | -------------------------------------------------------------------------------- /test/test_sha512.lua: -------------------------------------------------------------------------------- 1 | local hmod = require("hashings").sha512 2 | local runner = require("runner") 3 | 4 | local hash_test_output = { 5 | v1 = { "CF83E1357EEFB8BDF1542850D66D8007D620E4050B5715DC83F4A921D36CE9CE47D0D13C5D85F2B0FF8318D2877EEC2F63B931BD47417A81A538327AF927DA3E" }, 6 | v2 = { "DDAF35A193617ABACC417349AE20413112E6FA4E89A97EA20A9EEEE64B55D39A2192992A274FC1A836BA3C23A3FEEBBD454D4423643CE80E2A9AC94FA54CA49F" }, 7 | v3 = { "44D8B0F5909F5AF22DD52CA317C7B177B8670D01F0F0A2B589571BA95F9FC8FB7ACA28F7467664252D52B2E126B711F88E396524EE1FDC72B7463A7484A21C6F" }, 8 | v4 = { "07E547D9586F6A73F73FBAC0435ED76951218FB7D0C8D788A309D785436BBB642E93A252A954F23912547D1E8A3B5ED6E1BFD7097821233FA0538F3DB854FEE6" }, 9 | v5 = { "9814D48AE1BFD731B32F0A829F20507EC9BD6B77609053718F7E2053B53C7A264BBAB6A96D3D54A7F9A736570D11B1F99AFB1735149F43CFEE9B6F87886D3FF6" }, 10 | v6 = { "EEF039626EA05D418B6025E75501FEF85025D2AAB8DF0FF44E47E72041835B6844407E60CD20E67958EC5495127E94317A8D47965EE3F3E2414A23B801690C25" }, 11 | v7 = { "CE733117F9963859337176B7DDF93F889190B36AE0D76B61B8760EB350C48FD48A79437C812701A53DBCE608B613E52835618AA5895BDE9B75C0D72F7B368BFA" }, 12 | v8 = { "9D247923385736CB7A6B9C4DD872A301963795B5EB8244F28EA10B4A84E607429FBB00BA3BA2EADBDBF854048C7EB9A014A18952B72347B1D3A363CFD2C349B5" }, 13 | v9 = { "3210512D6E6BD85CC22A6E15EF4687FDA60F96EB4851129E64664EF7EE61E44CBDF4847D8D5B4B262F86087A0386D68C5B720F793883736AE81368EC277FD2D6" }, 14 | v10 = { "8C18585BBB7BA8E13B35010243D2E9F143AE19B630F2646CECB65C4FF2FE7F95F09D96497532BE99ABB425573DA946B326F6AF9D51448F3EEFDA1B23285B98F5" }, 15 | v11 = { "8760A6780B9011ABC3D040224DB3B93F6251045813D97A1B639E91CC34022C5A4DDA4F357B34A98FCBBCAAF15C369DAD159DEC8492FF81B3F49B668A838B6D72" }, 16 | v12 = { "3E42219A5116CA224EF73944526538367A037F3A6E8271E8BDD5546AC2612BCB6DD4CED52F33A197B6F8B08444D109A6D41DFDBAFC7CF380A4C0B12CB03E8228" }, 17 | v13 = { "34A15944D86A67FD7B4083502FB5F08B6AE35EDD4B4A56D6AE46B45C950A515F79824A933958988DACB42ED71DC30E0D1398D0D9FCF1799D35A3C39AECCBD19F" }, 18 | v14 = { "736E3496A3989859EDDC30CBF5CBBD047328F844C7E6CE804DE724C66D0348B78D163F2E420E4282279151DF5551B19C264940B48F51E5E4F2CD4323318F02C7" }, 19 | v15 = { "2EBA73AFA4F649C4875859DEC5F6D7DFD17F4C50B01307AEE2C38438BB77A3C1664826613E4E94B55F1AB1AAF676ECE310717E767129CE7DD4940C2D974349BA" }, 20 | v16 = { "40DA5FAF1EE61A477688BC0BA6B9F5D58B73D4A891D33B5F4B6FE58A8AC4EB8FCB25915286729E55EE85EB17CD6B74659432A0F8E304FCFCC1B01C646AE23480" }, 21 | v17 = { "8902DAA5ABEB0084BE3DCAFA651371888C86521A9006B004502A2DA7507E7CEEF78A0E3C643E19833117473E5F8B6EDC22E3CDB7F52833C6263CA4210D47E540" }, 22 | v18 = { "5B79CAD852C8608B2544A047BB2DEFDD6180FCBA2B82EA59E3BE889A70733DD6F28C09223A08138155C03BAB2A24224E726948F31321372C65B525EBDCCDE4C0" }, 23 | v19 = { "8354B850ACF996044987399396BF209AFD308EF8ED4DB3881E11EA93F94DEBBDA9F703A07165C05E634C47BA36900C3125B7A0942AF72B5886102F8D3562F09C" }, 24 | v20 = { "80EB23CE9BEB7FBD9479603818B48F8A7430FB2BF6975A34E1DC26B06A5A512393F8A7CE2C0977B9DB67DF29EDC34360C1118CE4D80FFCBA06CD4A7CEEDE7E34" }, 25 | v21 = { "23782B4254A3CD1B54E871F9D5B950D9A21E9AE4CE6974D968CC9FC1D2B46D270542982659B59BC1A7C8A1B8A75331F9C02F715AFA181D998AB8454A52A9CE28" }, 26 | v22 = { "0DAA8FB6012BC44718FA305DEBD2A751C305B3DBB7EB6D1F1E01228F0988987053E70FD77C5012D04B0B4DBDA41F138A02FBB4C36D838C3D9DC67A42E849B169", "D5BB064665BAAF0C9486D0474DFC8F61CD73561440ABCC7E215DC002817EA184CEED713974179B09E0600030D53940E3D45148D3D4B9CBAFDECED9EFA518C444" }, 27 | v23 = { "14F49D6EA74F4C59254D8FA5CBB22F88C7D3E2B93CFAA60F94AE281D5F2E5ADF941BD43D4779C0161C9765DCE9A4FC97D3692DD9418AA2BEC90182951D32C3A0", "E599F8CF14C869C2414D0FFDC341FD1AA5E65CA9B1E981B600057741A094B350AD96C198FEEE2FCCDFEC8256854401A30931FEAFB3178732117F02EB579E97A2", "43B07DEFCD0B661A45073C53C07E891303AB3ADD105A4A07E5D591730897279A853F4441684E6BB4118E34ADB303055D207F1B6E5FEB884DA6A98788F4BEFDE4" } 28 | } 29 | 30 | local hmac_test_output = { 31 | v1 = { "D98942D69A75C61A08D2BC62B63AEDA9C8FE6E34493BA10515102340A32474B0618013C12E79B69A65908E27B45592C39BB4A03B5A84E35B010EFC9030ED8DF8" }, 32 | v2 = { "60DB8FE1EB688257941ED4332E571D7CAD3DEA156E70ABBFA37897DDD7E782B25236E863E1B1B9AD06BC681FD6F3238F2A13F0972E9EC91E736F0DE2B9F8D508" }, 33 | v3 = { "16FCEB85A8F4CC6A988254A267FAE93939F82863290AD4BC291DF322E50654D7894853E601766265D4C27ABAA8F754664DC14F411DE4400A3F7BD5A682E672DC", "3F22B0F30C69234B27AB8D5BB0D8F40C1F38D874901B3901973C1018416104337586AA149552630A782D310D71103E44AFCBA06E1CAF135D355479EB9CFA3DB2" }, 34 | v4 = { "7368E2485D0D8A6D836ABEDFC29F1C5B5E690C412BC9D00BBFEFBB34818A26C6D9D10965D2F9031F5C35910DB9F73A03E911967B2BD5D9319E103DFB00E62CB7", "995C53FB039E7113D8C33A8258575D3D87D95040F2446538BC4B3C069D892D382AACF1291A5893961EF566A8A9B584B578DC70CED03330CFE43C97348273E8F5", "FFBED8C850B359951527AFCAD3916EC745D25C52885CE822FC7B92AD387737B537960AB824DEF5A7254CBCF7A504424586B9379EE8E0FF906877223682C52579" } 35 | } 36 | 37 | runner.hash_runner("sha512", hmod, hash_test_output) 38 | runner.hmac_runner("sha512", hmod, hmac_test_output) 39 | -------------------------------------------------------------------------------- /test/test_whirlpool.lua: -------------------------------------------------------------------------------- 1 | local hmod = require("hashings").whirlpool 2 | local runner = require("runner") 3 | 4 | local hash_test_output = { 5 | v1 = { "19FA61D75522A4669B44E39C1D2E1726C530232130D407F89AFEE0964997F7A73E83BE698B288FEBCF88E3E03C4F0757EA8964E59B63D93708B138CC42A66EB3" }, 6 | v2 = { "4E2448A4C6F486BB16B6562C73B4020BF3043E3A731BCE721AE1B303D97E6D4C7181EEBDB6C57E277D0E34957114CBD6C797FC9D95D8B582D225292076D4EEF5" }, 7 | v3 = { "CC8569F5283CC57AD3C8225A31B39D439CB8CCEC3C2E8AE7E8FE7E8E699BC8BA3ADB41EA561936C38109EF1126706B59AB198297FF8D695627FFFFFC97E33B10" }, 8 | v4 = { "B97DE512E91E3828B40D2B0FDCE9CEB3C4A71F9BEA8D88E75C4FA854DF36725FD2B52EB6544EDCACD6F8BEDDFEA403CB55AE31F03AD62A5EF54E42EE82C3FB35" }, 9 | v5 = { "4E50A42D469B6E5334F80A6BB85437823347AFFDD40A3DE2E701E9DFD4AFB3A01A46CD233EC8497FDC8BAA95FE46C2F0F2079D6E976E9B4C56957732BF35F467" }, 10 | v6 = { "29573367963A1110E79F06863BA82587FBC12E073297C7FEFADA6DE558DA08DD1F95B7BEC9A388550DF9D0A0C94296EE935110F47CEEFE16A081EED29091169D" }, 11 | v7 = { "2B9B47385F9A9DD90738957225A87D064177590D134941E8F009C388B712DA455D9D4F3D6440B36333D879C3C6D29E6C7EF4098FBFFE841F7DB8E8EE436AB295" }, 12 | v8 = { "B51B9E0D4F2C13F0DE7AF69A902E57AB04EF859CA6BDDA3F6CF66B69596476130C613F3A1E1E22918424B33BE28190D02330B8A494AC397DED7675799B9B0C7E" }, 13 | v9 = { "7B8B62E3EFE411F357C5CC2FEF8C36F8C2418F9E97AA2D9C2C7FB15A9CCA61F5E83FC411494F5DF76C2F3D7090021F0BF518D01E1BF651187AAF9FC6CB7DAEB8" }, 14 | v10 = { "C608B0C4BA2F5DFC86AAAC14E3D63D5846EFA3DC5BAA2B0ED8D6137E3EC0C21EBE6E3620E7BA443C1A031B52887B99D1737412ECE63691A35AC87E524C8F50A3" }, 15 | v11 = { "25DFE5DD47ADEE5047297267A08C32540C69D26BF1839C4A8B1ACDBB019A59C1A16ECA6435F31B40475C5D3A02CA320938173ACE51B19D1FADE8A80E7C2C7031" }, 16 | v12 = { "CB8FD5CBFD6841C611590523E21EA4BD67A61B16FE42D8645263B1F324E0AECB58D161613FB12706401B7AB5A5C9FEB38F3EEF8DEAF0E62C653F52620494F6D6" }, 17 | v13 = { "92742BA02F4900F42D5D7F6D63C782BC4C21DF65079840A7DF05774952327D4C01E2E02D23901D3F6A58099245EBEFA571F44C405A949A5E299AA3567F775056" }, 18 | v14 = { "970B4961242A5FE7A2E6502B58A8DEB7D59247CE8CEC3AB02B2D7A1B6397B1EEAD73969F5471FDB0E2A604D955E03C1693077E2D83D2890F74632E2A4B361081" }, 19 | v15 = { "27BE77BE71BE6D6A1C5E9880474C248F9C89B9278E92DF340A65D9146571E1484F15AF6E0ED993F8283192C0F37597297CA7D90A882FC0EBE1931868032670D7" }, 20 | v16 = { "FE3F9F8B18D18EFD5A7176B55DE62375FA7C214F19C01A63826A01216CEC5B947A581C1C9D8D7EDEA12778286DDDA280276299202B2641437965C5ACC008D367" }, 21 | v17 = { "4E65B7A614B56EDCC4253AEC1D865C8F1391F03FB989875172E898E907C9AD3F5AA79DCCC322E6B9DEB358C572C47F0F25579385BA355426541E69310AED6025" }, 22 | v18 = { "2981BE6EA0F44CF0B488EAE44A0A0A9470AE5296D817F04875559EA5B91D8B36E0610A696C8C3E88D37726D7B47C9B20A4A9D8BF35A2D85C2DCFAF82C9050E4B" }, 23 | v19 = { "9CF4E5E5A0A76B1E093E378B0E7E7FF5EEFC7834D89D9DCFD9E3B7ECC99D34E379E5C010953232B85809855D4895A09F12CFBDB4CAB743C41208E6F0EDFB8F11" }, 24 | v20 = { "1712AB54AC763C3522E888C2CD30D0D3BB8260238F495B989C7165EDC2818986F9C77A675C427713D7AC89E7CDD4D1718A6669DD8DF75C08DA16F91707A3B4D8" }, 25 | v21 = { "7B045AA579D384CDCDA5ABBF5ED8C35CB0470CEF6434902D53F869267B3B267955C42D071EED0F75EAC9EE2D59BCCBC07F19D91324A4EE4EBA0AC6BA5B550B0A" }, 26 | v22 = { "FC08D2AB9582D6F4615980949FA2618AAC53CBB95A1190324E72F6C1834999D29B626A687F5D4772B907E961FB7F2878E933C528CCC29D6AE8B89D40CAC0C0A3", "E88CF6B01FCC2D6ABF369094DBBE87B5F1A934FEDCDD13EC397D769AEE9C841DB51C62EF0F000953E1B4A74EACD5E1A15CA6CBBFA2836A14D7EA730526F176BA" }, 27 | v23 = { "D4F271DA93507E1F6024801A307B773858EEF473FC29609BE5C3EDDF12DD15078356E427A407F81CDC64CE19773A6F7D282E0EA95C0D73C16DA1187B5F21C809", "E58A95E70F1B64A5F3190BB63C28D0496D3A1F5AD470E1227EDDFD3322CBF1728CD05F7CE359DF444870A6AFE63F046CB8D8F2A4FE738CC3FA2AFC0CA0492C96", "A64E40BB4E734000F16278BB87DED156AD3C3DFEFDDEE45B301A74C585B049CB93A539289FE9532C559A8BD429788DE25C488F3A1737605CD4E36D224DC3544E" } 28 | } 29 | 30 | local hmac_test_output = { 31 | v1 = { "2704E7F5254DD6595518D0D06A99C474CF8A85EAD6EBAC8A8DE6C3A2DA2EAA59F960EE29779255B18D526DFEA6D6AFAC3A33CBA0274A309D0F6A2AB320230838" }, 32 | v2 = { "B3DE8895326D0A69AADF681310BAA6633184B7039ED897EEDE1D9E49E13A801785A20C4CF72CE562D68545D88D5379CA7AF89BC179B861D2CF3CCFA174045FEA" }, 33 | v3 = { "98AC55B54D475F51227F172F2D51F8D0D71F69C3E91AA6F57B049EE4F520D985C096FAD38BCEA28EC4635554CC9AD6A12F360567C343752058E84C7987EEAFFE", "020BD26B4FFB0C8B88BFF71D38F77BE649A19FCD80CADB9F0013F1002ADC2ED4A211550EF210CB29DEFEDD081FE42D365F2EFE7452CB70D5307F20EB0E2BE54D" }, 34 | v4 = { "A8EB32136CD6AB9A4C2FF6F3429AAF7E6508682653DB56E3E3F5E7CAFAA355C80A77CBCEA6603653DF5BCDCD78871AEE76BA4949B326D5638CDEC6DD80387141", "B6CB9F90A75D88D96A4BB96517CB8639467D4958FC8B7FD31275B048F832C395398E687A20B4769F960ED0781C8072BA9F50465B7BB652F30F0A3AE236FDA507", "2E4F1F92D4E16252328C44C0D8C83882AC44E3B62184C1BE22333086BABC5F97126CC7D7C9E7DB93CE15310B2DF9FCFCC1DE817DB814A2F982F5AE1405D4ABCB" } 35 | } 36 | 37 | runner.hash_runner("whirlpool", hmod, hash_test_output) 38 | runner.hmac_runner("whirlpool", hmod, hmac_test_output) 39 | -------------------------------------------------------------------------------- /test/vectors.lua: -------------------------------------------------------------------------------- 1 | hash_test_names = { 2 | "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", 3 | "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", 4 | "v21", "v22", "v23" 5 | } 6 | 7 | hash_test_input = { 8 | v1 = { "" }, 9 | v2 = { "abc" }, 10 | v3 = { "test 123" }, 11 | v4 = { "The quick brown fox jumps over the lazy dog" }, 12 | v5 = { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" }, -- string.rep("a", 62) 13 | v6 = { "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" }, -- string.rep("b", 63) 14 | v7 = { "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" }, -- string.rep("c", 64) 15 | v8 = { "ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd" }, -- string.rep("d", 65) 16 | v9 = { "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" }, -- string.rep("e", 66) 17 | v10 = { "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" }, -- string.rep("f", 126) 18 | v11 = { "ggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg" }, -- string.rep("g", 127) 19 | v12 = { "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh" }, -- string.rep("h", 128) 20 | v13 = { "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii" }, -- string.rep("i", 129) 21 | v14 = { "jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj" }, -- string.rep("j", 130) 22 | v15 = { "kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk" }, -- string.rep("k", 510) 23 | v16 = { "lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll" }, -- string.rep("l", 511) 24 | v17 = { "mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm" }, -- string.rep("m", 512) 25 | v18 = { "nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn" }, -- string.rep("n", 513) 26 | v19 = { "oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo" }, -- string.rep("o", 514) 27 | v20 = { "A4UlbcD3fTxfV0vuwMfgrqjwU2RbazoTBFFwuTUGTJXIy2fy8Fvrgw6XWlTMSSpaKHKLklPBFJKbSpvnelCvTmvN3nl5T76zKmlxhn6r7w6fUnzIueJbMt2zbzLKSwR0wYmEfrfZMg7jfgY9BlqMV3tPTkBEb9uTct8M8zAiB7Qh30mHW8QW0PspJQ1DFHJjtnnTkomHrvNHZVkoQHXA6B3VDp3SiZzLOWAOzMxE9BjVW6fOr5O5nQ2bs99AaUjT9qU45Ugm6V6VQrDENDDO3mrxklVK1vwst9X2EQwqhL6aghcOzOkGTQPQfKCJYpZIeieu6WR21mg7ctq7IijejoEhPIFkORb2QShZp4AssyHQP4Z5gY8pB3X1TNzhRss7gpbloLzG2UWOLNpHSzROAUjiaixnEQnbNSjmF2XUvyYkWxNevvZOZeq0utYHyOkDF5yrHFrUSK4qZtjqZJyEEp6KFLRIAoo8oSBmni4bzX0nf0M4nTfK2wSKyRnIGTGv3pjwALJ9DxMCQDKbgKLD86ENkQGwMgujagyzpehoQ3m6iiCkhlIOPWAOCW5gEMRfE6ZLIRSqfYnF0pLHSrDnJ9uzm6SctNsNSccqFmX3umX2chx7HOAPOxMUeiB8z7iWosaHUNroJQ0CEK0fgcJcGYmwSmj3Gt7ZwuEgQVvVoR30Ds6WpaQ8jrwv3hyYXbFl3fYy320v67loBQj2mG0u7QeM1k26QsjqSi9xaeCaHr5YD1tG6DsyQDyjjZ9x9P7pT7iAfXoX83qmlHGtTGXEntB32sl6KzjlbTLwkj8G9MDGA0IwEM18Jqo7q6tZV5cQFYB8E73SRZRNDASvXlvKX2tLGHQSp8AagD9xPcBP67fqWm79Eny5NnASZK0OSZTQHDQ5qtsQEPggrqkxW86PR18JvIcxLWLpoVFGoit3ODzZYBcefBCAGuy6EPSYt9k0phlVIPRC4LCO5FxV1335gQFQ7Ek6vQ7fzhbfBGPuP2JNTUhyDp1keuMHTy4KH63shU6OyAmxC" }, -- 1033 chars 28 | v21 = { "S9rlJoj3sxaqFMCnWmEbanqxv6q5xhU2BRDYZO9lpfnw0a8Jk7rAhMGDn94Rux80go4OGFgCemV21FAtYbFLNTwHrGHJ6EHwVBqKC9SFxHRapbh1vLRo5nvg1UHs6GpXylkmvKhoSKZxJeOPkzB4RL3ta7gUZ1JXIIGhwLNk2xl9Jx5C3SoywGDa4qTuFZ4EcTTj7SzQfkD4aGSlHQFheKCeYSVvDaSqwoa3GK8cIUnFEVXEDL1jqEUmXKwpJzXfPrT1zYbURuUwnL1INU0EEKUS7ZUqg7Wui5EpWxhaYu6ooNwwsaYa33RtrP5DcJmA95f7V7PoWflgGFAqrbmxloWGD8oHa8bOLyCg0MlpcUJkEgkH9jPVYSLygWPFIiHmzjHcSWBc9UADi9gKmZQDxGTfCOZGWKUlf3VxDmywxZ3S3DNetrPs60LtOwE01uEircN8lJyDXKyM83Va6kHVisURe79Q2D28qYxIRncPXxXjoq2B1N5IbnJkGQAWaH9lMEUFzh9uEgtqAzkYAtFeIu996hKjISDX48gAw43IaG2EqyPEzoxG3HYuPMR47yG2lz33p5g9hjy4tZ8SI6QHVcEYEIOVE6zINeKAFNVJournJEf5g3GjwXyK7gSqMy6KvjvZvweuXzOkOosvPsZBvRSJf0U2OrjxizNCpS2uE7L2sp5utPe6I4m0JoR1Ce2sZTVHkpnvyx12JrF7vUKwGJLbRbK4Fl5fS5vq169OLAMNBfv2V1TPJOqPlYOEHn4AeyC5NqTZpsEB6YcpmUaOqYoKsYzmqA7pG2ygb61QrrXFvFWDZ0Vui1oxmfnLYknthppvs4urN9ZuBlKnnoAYV9EopsEZIanIiDJllH0K5XfLHbuUGokSABqJeE1Dx0nai4E5JANefszO4miUjuCvDrCBut1wGI0ee6wFhnZaqGjGY8Ik10baju1p1taP1WoEIf3TPVFhfT8SI0oaorMnPcxpDExvVWGJ3Ns8Q2XjhtAR9yM8swmlPjy8kcibY8JSe4LrHcOQnFRItPwulTisDFkE3vY8PBMZrXvoIO1Oo2zmcPItsVjazfmUNaZWreR2IpqhTuhhoP2ok0uQnbA3DyTVHUN7bSBHCcicjqNH21zWe8LiXJpVb1fC37r3UTjV53wPUmIUSSWuoeURN8zi5Extb6BmM7ajoxIZkw39VNjlSQAyLiuh1JX1YNlafJm4aCmtUj22ysjWGT4puAi2OgYIoVefXMaM9V2Yh7UVan8bZFAGOQnaP65IouC8jcnAi0yoj7yLDt9SR8y6x0WXE1l6cZEvr4QXIx5qgiMkN9xxboDJzm3XFaZhyM2bNrcjFVvmSxrTgcSpYlD88ny5ksoLsogSzFEvtSULeO5rgsrvc5ljpjQ92uxS8wBAP2h3mSMYmXMFTaD2XP8lqpYmeuHpWPxlaCZigXDC4iwPqB8WIvhjgf1leeMttjRcg8sfKFw069WknYfLW9FcCRZw84Z7HIDiGu8aaxBNBwu7KmB6Pjl2xNYFQpTwAyuOpUvrWzfX5LgEALr6m7PvLeCR73UhwDuvW6hu2r4AqoohHO88pSnl1olDXPF4Jo4Rk9bFcODwVQoOwSSMqDMlhlN7R2jBryb0W4OiGvjPgyhUa7yzKugMiZXcphC9O04UpTOQHGXpezWcggVLffKJEkKDsUXWIaLgh5ZBE3fgZ0V5K2R5zu52EVY15tHnHVIbDGjhAKaJF0UcUnraIZ4iMiv0TXQR48BSF7wpEDujkbPzRucnTJR02hZhJALhwuN7Q2mSoo9Jf08WK2o1LoLx2A36hqRVGOpRvzCOUF8H5R5s3J5GanSUAo0ObQmssI75a1Gzw9MozRWAunVnE8WCbjxELsVEQb1Ea2yzRQmSNSTlTQ3pNQq8A4QjgFkeZw7mb8yU4JEj1OnupoUlohkbNqo3ewQBaTUojjEAfpyeP9pQTxjRxCBzUy4xVF1YBfoLb5OyVHTjgbq31ujV0kSCopfMbvf2NgTsACQYUNx22XioZocgOzGPaxMbHnXH1Gl6hVbIS5FvPMqmCuZMV2001f2AS6Q0mXNMjrfYMlqh6fHiRC8uielL3DlgZkjGk6AacqvGIqQyERsA5J4Hm57owUAaNxbUUfMERnx67DBzvTFHJwk8sqzoCNfS1Vktg438Dg2rXOJa0Zvm7BWggaxwvI2HVpCiANCpWf6r1ZjLkzhFaUeEqoppeqKUUZmGKqAt9DSYihm6izHNtLWxmSwmFBmQWi8OohAJcTfKSPC6Zn4vcEeejUFHqoHEmBSP2H2Wt" }, -- 2301 chars 29 | v22 = { "pppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp", "qqqqqqqqqqqqqqqqqqqqqq" }, -- string.rep("p", 222), string.rep("q", 22) 30 | v23 = { "rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr", "s", "t" } -- string.rep("r", 33), "s", "t" 31 | } 32 | 33 | hmac_test_names = { 34 | "v1", "v2", "v3", "v4" 35 | } 36 | 37 | hmac_test_input = { 38 | v1 = { "a", "b" }, 39 | v2 = { "s", "A4UlbcD3fTxfV0vuwMfgrqjwU2RbazoTBFFwuTUGTJXIy2fy8Fvrgw6XWlTMSSpaKHKLklPBFJKbSpvnelCvTmvN3nl5T76zKmlxhn6r7w6fUnzIueJbMt2zbzLKSwR0wYmEfrfZMg7jfgY9BlqMV3tPTkBEb9uTct8M8zAiB7Qh30mHW8QW0PspJQ1DFHJjtnnTkomHrvNHZVkoQHXA6B3VDp3SiZzLOWAOzMxE9BjVW6fOr5O5nQ2bs99AaUjT9qU45Ugm6V6VQrDENDDO3mrxklVK1vwst9X2EQwqhL6aghcOzOkGTQPQfKCJYpZIeieu6WR21mg7ctq7IijejoEhPIFkORb2QShZp4AssyHQP4Z5gY8pB3X1TNzhRss7gpbloLzG2UWOLNpHSzROAUjiaixnEQnbNSjmF2XUvyYkWxNevvZOZeq0utYHyOkDF5yrHFrUSK4qZtjqZJyEEp6KFLRIAoo8oSBmni4bzX0nf0M4nTfK2wSKyRnIGTGv3pjwALJ9DxMCQDKbgKLD86ENkQGwMgujagyzpehoQ3m6iiCkhlIOPWAOCW5gEMRfE6ZLIRSqfYnF0pLHSrDnJ9uzm6SctNsNSccqFmX3umX2chx7HOAPOxMUeiB8z7iWosaHUNroJQ0CEK0fgcJcGYmwSmj3Gt7ZwuEgQVvVoR30Ds6WpaQ8jrwv3hyYXbFl3fYy320v67loBQj2mG0u7QeM1k26QsjqSi9xaeCaHr5YD1tG6DsyQDyjjZ9x9P7pT7iAfXoX83qmlHGtTGXEntB32sl6KzjlbTLwkj8G9MDGA0IwEM18Jqo7q6tZV5cQFYB8E73SRZRNDASvXlvKX2tLGHQSp8AagD9xPcBP67fqWm79Eny5NnASZK0OSZTQHDQ5qtsQEPggrqkxW86PR18JvIcxLWLpoVFGoit3ODzZYBcefBCAGuy6EPSYt9k0phlVIPRC4LCO5FxV1335gQFQ7Ek6vQ7fzhbfBGPuP2JNTUhyDp1keuMHTy4KH63shU6OyAmxC" }, 40 | v3 = { "abc", "test 123", " and 456" }, 41 | v4 = { "The quick brown fox jumps over the lazy dog", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "bbbbbbbbbb", "cccccccccccccccccccccccccccccccccccccc" } 42 | } 43 | 44 | pbkdf2_test_names = { 45 | "v1", "v2" 46 | } 47 | 48 | pbkdf2_test_input = { 49 | v1 = { "a8i09ujko", "this is salt", 18 }, 50 | v2 = { "S9rlJoj3sxaqFMCnWmEbanqxv6q5xhU2BRDYZO9lpfnw0a8Jk7rAhMGDn94Rux80go4OGFgCemV21FAtYbFLNTwHrGHJ6EHwVBqKC9SFxHRapbh1vLRo5nvg1UHs6GpXylkmvKhoSKZxJeOPkzB4RL3ta7gUZ1JXIIGhwLNk2xl9Jx5C3SoywGDa4qTuFZ4EcTTj7SzQfkD4aGSlHQFheKCeYSVvDaSqwoa3GK8cIUnFEVXEDL1jqEUmXKwpJzXfPrT1zYbURuUwnL1INU0EEKUS7ZUqg7Wui5EpWxhaYu6ooNwwsaYa33RtrP5DcJmA95f7V7PoWflgGFAqrbmxloWGD8oHa8bOLyCg0MlpcUJkEgkH9jPVYSLygWPFIiHmzjHcSWBc9UADi9gKmZQDxGTfCOZGWKUlf3VxDmywxZ3S3DNetrPs60LtOwE01uEircN8lJyDXKyM83Va6kHVisURe79Q2D28qYxIRncPXxXjoq2B1N5IbnJkGQAWaH9lMEUFzh9uEgtqAzkYAtFeIu996hKjISDX48gAw43IaG2EqyPEzoxG3HYuPMR47yG2lz33p5g9hjy4tZ8SI6QHVcEYEIOVE6zINeKAFNVJournJEf5g3GjwXyK7gSqMy6KvjvZvweuXzOkOosvPsZBvRSJf0U2OrjxizNCpS2uE7L2sp5utPe6I4m0JoR1Ce2sZTVHkpnvyx12JrF7vUKwGJLbRbK4Fl5fS5vq169OLAMNBfv2V1TPJOqPlYOEHn4AeyC5NqTZpsEB6YcpmUaOqYoKsYzmqA7pG2ygb61QrrXFvFWDZ0Vui1oxmfnLYknthppvs4urN9ZuBlKnnoAYV9EopsEZIanIiDJllH0K5XfLHbuUGokSABqJeE1Dx0nai4E5JANefszO4miUjuCvDrCBut1wGI0ee6wFhnZaqGjGY8Ik10baju1p1taP1WoEIf3TPVFhfT8SI0oaorMnPcxpDExvVWGJ3Ns8Q2XjhtAR9yM8swmlPjy8kcibY8JSe4LrHcOQnFRItPwulTisDFkE3vY8PBMZrXvoIO1Oo2zmcPItsVjazfmUNaZWreR2IpqhTuhhoP2ok0uQnbA3DyTVHUN7bSBHCcicjqNH21zWe8LiXJpVb1fC37r3UTjV53wPUmIUSSWuoeURN8zi5Extb6BmM7ajoxIZkw39VNjlSQAyLiuh1JX1YNlafJm4aCmtUj22ysjWGT4puAi2OgYIoVefXMaM9V2Yh7UVan8bZFAGOQnaP65IouC8jcnAi0yoj7yLDt9SR8y6x0WXE1l6cZEvr4QXIx5qgiMkN9xxboDJzm3XFaZhyM2bNrcjFVvmSxrTgcSpYlD88ny5ksoLsogSzFEvtSULeO5rgsrvc5ljpjQ92uxS8wBAP2h3mSMYmXMFTaD2XP8lqpYmeuHpWPxlaCZigXDC4iwPqB8WIvhjgf1leeMttjRcg8sfKFw069WknYfLW9FcCRZw84Z7HIDiGu8aaxBNBwu7KmB6Pjl2xNYFQpTwAyuOpUvrWzfX5LgEALr6m7PvLeCR73UhwDuvW6hu2r4AqoohHO88pSnl1olDXPF4Jo4Rk9bFcODwVQoOwSSMqDMlhlN7R2jBryb0W4OiGvjPgyhUa7yzKugMiZXcphC9O04UpTOQHGXpezWcggVLffKJEkKDsUXWIaLgh5ZBE3fgZ0V5K2R5zu52EVY15tHnHVIbDGjhAKaJF0UcUnraIZ4iMiv0TXQR48BSF7wpEDujkbPzRucnTJR02hZhJALhwuN7Q2mSoo9Jf08WK2o1LoLx2A36hqRVGOpRvzCOUF8H5R5s3J5GanSUAo0ObQmssI75a1Gzw9MozRWAunVnE8WCbjxELsVEQb1Ea2yzRQmSNSTlTQ3pNQq8A4QjgFkeZw7mb8yU4JEj1OnupoUlohkbNqo3ewQBaTUojjEAfpyeP9pQTxjRxCBzUy4xVF1YBfoLb5OyVHTjgbq31ujV0kSCopfMbvf2NgTsACQYUNx22XioZocgOzGPaxMbHnXH1Gl6hVbIS5FvPMqmCuZMV2001f2AS6Q0mXNMjrfYMlqh6fHiRC8uielL3DlgZkjGk6AacqvGIqQyERsA5J4Hm57owUAaNxbUUfMERnx67DBzvTFHJwk8sqzoCNfS1Vktg438Dg2rXOJa0Zvm7BWggaxwvI2HVpCiANCpWf6r1ZjLkzhFaUeEqoppeqKUUZmGKqAt9DSYihm6izHNtLWxmSwmFBmQWi8OohAJcTfKSPC6Zn4vcEeejUFHqoHEmBSP2H2Wt", "A4UlbcD3fTxfV0vuwMfgrqjwU2RbazoTBFFwuTUGTJXIy2fy8Fvrgw6XWlTMSSpaKHKLklPBFJKbSpvnelCvTmvN3nl5T76zKmlxhn6r7w6fUnzIueJbMt2zbzLKSwR0wYmEfrfZMg7jfgY9BlqMV3tPTkBEb9uTct8M8zAiB7Qh30mHW8QW0PspJQ1DFHJjtnnTkomHrvNHZVkoQHXA6B3VDp3SiZzLOWAOzMxE9BjVW6fOr5O5nQ2bs99AaUjT9qU45Ugm6V6VQrDENDDO3mrxklVK1vwst9X2EQwqhL6aghcOzOkGTQPQfKCJYpZIeieu6WR21mg7ctq7IijejoEhPIFkORb2QShZp4AssyHQP4Z5gY8pB3X1TNzhRss7gpbloLzG2UWOLNpHSzROAUjiaixnEQnbNSjmF2XUvyYkWxNevvZOZeq0utYHyOkDF5yrHFrUSK4qZtjqZJyEEp6KFLRIAoo8oSBmni4bzX0nf0M4nTfK2wSKyRnIGTGv3pjwALJ9DxMCQDKbgKLD86ENkQGwMgujagyzpehoQ3m6iiCkhlIOPWAOCW5gEMRfE6ZLIRSqfYnF0pLHSrDnJ9uzm6SctNsNSccqFmX3umX2chx7HOAPOxMUeiB8z7iWosaHUNroJQ0CEK0fgcJcGYmwSmj3Gt7ZwuEgQVvVoR30Ds6WpaQ8jrwv3hyYXbFl3fYy320v67loBQj2mG0u7QeM1k26QsjqSi9xaeCaHr5YD1tG6DsyQDyjjZ9x9P7pT7iAfXoX83qmlHGtTGXEntB32sl6KzjlbTLwkj8G9MDGA0IwEM18Jqo7q6tZV5cQFYB8E73SRZRNDASvXlvKX2tLGHQSp8AagD9xPcBP67fqWm79Eny5NnASZK0OSZTQHDQ5qtsQEPggrqkxW86PR18JvIcxLWLpoVFGoit3ODzZYBcefBCAGuy6EPSYt9k0phlVIPRC4LCO5FxV1335gQFQ7Ek6vQ7fzhbfBGPuP2JNTUhyDp1keuMHTy4KH63shU6OyAmxC", 25 }, 51 | } 52 | --------------------------------------------------------------------------------