in_lua_native_sha256-verschluesselung
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
| in_lua_native_sha256-verschluesselung [2016-10-25 10:56:41] – angelegt manfred | in_lua_native_sha256-verschluesselung [2016-10-25 11:18:39] (aktuell) – manfred | ||
|---|---|---|---|
| Zeile 1: | Zeile 1: | ||
| + | ====== in LUA native SHA256-Verschlüsselung ====== | ||
| + | |||
| + | * [[http:// | ||
| + | * [[http:// | ||
| + | * [[https:// | ||
| + | * [[https:// | ||
| + | |||
| + | <file lua sha256.lua> | ||
| + | local bit = require ' | ||
| + | local ffi = require ' | ||
| + | |||
| + | local type = type | ||
| + | |||
| + | local band, bnot, bswap, bxor, rol, ror, rshift, tobit = | ||
| + | bit.band, bit.bnot, bit.bswap, bit.bxor, bit.rol, bit.ror, bit.rshift, bit.tobit | ||
| + | |||
| + | local min, max = math.min, math.max | ||
| + | |||
| + | local C = ffi.C | ||
| + | local istype, new, fill, copy, cast, sizeof, ffi_string = | ||
| + | ffi.istype, ffi.new, ffi.fill, ffi.copy, ffi.cast, ffi.sizeof, ffi.string | ||
| + | |||
| + | local sha256 = {} | ||
| + | |||
| + | ffi.cdef [[ | ||
| + | void *malloc(size_t size); | ||
| + | void free(void *ptr); | ||
| + | ]] | ||
| + | |||
| + | local ctHashState = ffi.typeof ' | ||
| + | local cbHashState = ffi.sizeof(ctHashState) | ||
| + | local ctBlock = ffi.typeof ' | ||
| + | local cbBlock = ffi.sizeof(ctBlock) | ||
| + | local ctpu8 = ffi.typeof ' | ||
| + | local ctpcu8 = ffi.typeof 'const uint8_t *' | ||
| + | local ctpu32 = ffi.typeof ' | ||
| + | local ctpu64 = ffi.typeof ' | ||
| + | |||
| + | -- This struct is used by the ' | ||
| + | -- of the end of the input string + the total input length in bits + a pointer | ||
| + | -- to the block buffer (where expansion takes place.) | ||
| + | local ctBlockIter | ||
| + | local cmtBlockIter = {} | ||
| + | function cmtBlockIter.__sub(a, | ||
| + | if istype(ctBlockIter, | ||
| + | if istype(ctBlockIter, | ||
| + | return a - b | ||
| + | end | ||
| + | function cmtBlockIter: | ||
| + | return string.format("< | ||
| + | | ||
| + | end | ||
| + | ctBlockIter = ffi.metatype([[ | ||
| + | struct { | ||
| + | const uint8_t *limit; | ||
| + | uint32_t *blockBuffer; | ||
| + | uint64_t keyLength; | ||
| + | } | ||
| + | ]], cmtBlockIter) | ||
| + | |||
| + | -- Initial state of the hash | ||
| + | local init_h = new(' | ||
| + | | ||
| + | | ||
| + | }) | ||
| + | |||
| + | -- Constants used in the add step of the compression function | ||
| + | local k = new(' | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | }) | ||
| + | |||
| + | -- Expand block from 512 to 2048 bits | ||
| + | local function expand(w) | ||
| + | for i = 16, 63 do | ||
| + | local s0 = bxor(ror(w[i-15], | ||
| + | local s1 = bxor(ror(w[i-2], | ||
| + | w[i] = w[i-16] + s0 + w[i-7] + s1 | ||
| + | end | ||
| + | end | ||
| + | |||
| + | -- Process one expanded block and update the hash state | ||
| + | local function compress(hh, | ||
| + | local a, b, c, d, e, f, g, h = | ||
| + | hh[0], | ||
| + | for i = 0, 63 do | ||
| + | local S1 = bxor(ror(e, 6), ror(e, 11), ror(e, 25)) | ||
| + | local ch = bxor(band(e, | ||
| + | local t = tobit(h + S1 + ch + k[i] + w[i]) | ||
| + | local S0 = bxor(ror(a, 2), ror(a, 13), ror(a, 22)) | ||
| + | local maj = bxor(band(a, | ||
| + | a, b, c, d, e, f, g, h = | ||
| + | tobit(t + S0 + maj), | ||
| + | a, b, c, | ||
| + | tobit(d + t), | ||
| + | e, f, g | ||
| + | end | ||
| + | hh[0], | ||
| + | hh[0]+a, hh[1]+b, hh[2]+c, hh[3]+d, | ||
| + | hh[4]+e, hh[5]+f, hh[6]+g, hh[7]+h | ||
| + | end | ||
| + | |||
| + | -- Take a 512-bit chunk from the input. | ||
| + | -- If it is the final chunk, also add padding | ||
| + | local keyLengthOfs = ffi.offsetof(ctBlockIter, | ||
| + | local function nextBlock(state, | ||
| + | local w = state.blockBuffer | ||
| + | local cLen = min(state - input, 64) | ||
| + | if cLen < -8 then return nil end | ||
| + | fill(w, 256, 0) | ||
| + | copy(w, input, max(0, cLen)) | ||
| + | if 0 <= cLen and cLen < 64 then | ||
| + | copy(cast(ctpu8, | ||
| + | end | ||
| + | for i = 0, 15 do w[i] = bswap(w[i]) end | ||
| + | if cLen <= (64-8-1) then | ||
| + | copy(cast(ctpu64, | ||
| + | w[14], w[15] = w[15], w[14] | ||
| + | end | ||
| + | input = input + 64 | ||
| + | return input | ||
| + | end | ||
| + | |||
| + | -- Iterator that yields one block (possibly padded) at a time from the input | ||
| + | local function preprocess(input, | ||
| + | len = len or (type(input) == ' | ||
| + | input = cast(ctpu8, input) | ||
| + | local it = new(ctBlockIter) | ||
| + | it.blockBuffer = w | ||
| + | it.limit = input+len | ||
| + | it.keyLength = len*8 | ||
| + | return nextBlock, it, input | ||
| + | end | ||
| + | |||
| + | -- Compute a binary hash (32-byte binary string) from the input | ||
| + | function sha256.binFromBin(input, | ||
| + | local h = new(ctHashState) | ||
| + | local w = cast(ctpu32, | ||
| + | copy(h, init_h, cbHashState) | ||
| + | for _ in preprocess(input, | ||
| + | expand(w) | ||
| + | compress(h, w) | ||
| + | end | ||
| + | for i = 0, 7 do h[i] = bswap(h[i]) end | ||
| + | C.free(w) | ||
| + | return ffi_string(h, | ||
| + | end | ||
| + | |||
| + | local hexDigits = new(' | ||
| + | local hexOut = new(' | ||
| + | |||
| + | -- Compute the hash and convert to hexadecimal | ||
| + | function sha256.hexFromBin(input, | ||
| + | local h = new(ctHashState) | ||
| + | local w = cast(ctpu32, | ||
| + | copy(h, init_h, cbHashState) | ||
| + | for _ in preprocess(input, | ||
| + | expand(w) | ||
| + | compress(h, w) | ||
| + | end | ||
| + | for i = 0, 7 do | ||
| + | local w = h[i] | ||
| + | for j = 0, 3 do | ||
| + | w = rol(w, 8) | ||
| + | hexOut[i*8 + j*2] = hexDigits[band(rshift(w, | ||
| + | hexOut[i*8 + j*2 + 1] = hexDigits[band(w, | ||
| + | end | ||
| + | end | ||
| + | C.free(w) | ||
| + | return ffi_string(hexOut, | ||
| + | end | ||
| + | |||
| + | return sha256 | ||
| + | </ | ||
