Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- A PRNG-ish thing for potatOS
- -- Nice SHA256 implementation, derived from Anavrins' work: https://pastebin.com/6UV4qfNF
- do
- local a=2^32;local b=bit32 and bit32.band or bit.band;local c=bit32 and bit32.bnot or bit.bnot;local d=bit32 and bit32.bxor or bit.bxor;local e=bit32 and bit32.lshift or bit.blshift;local f=unpack;local function g(h,i)local j=h/2^i;local k=j%1;return j-k+k*a end;local function l(m,n)local j=m/2^n;return j-j%1 end;local o={0x6a09e667,0xbb67ae85,0x3c6ef372,0xa54ff53a,0x510e527f,0x9b05688c,0x1f83d9ab,0x5be0cd19}local p={0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2}local function q(r)local s,t=0,0;if 0xFFFFFFFF-s<r then t=t+1;s=r-(0xFFFFFFFF-s)-1 else s=s+r end;return t,s end;local function u(v,w)return e(v[w]or 0,24)+e(v[w+1]or 0,16)+e(v[w+2]or 0,8)+(v[w+3]or 0)end;local function x(y)local z=#y;local A={}y[#y+1]=0x80;while#y%64~=56 do y[#y+1]=0 end;local B=math.ceil(#y/64)for w=1,B do A[w]={}for C=1,16 do A[w][C]=u(y,1+(w-1)*64+(C-1)*4)end end;A[B][15],A[B][16]=q(z*8)return A end;local function D(E,F)for C=17,64 do local G=E[C-15]local H=d(d(g(E[C-15],7),g(E[C-15],18)),l(E[C-15],3))local I=d(d(g(E[C-2],17),g(E[C-2],19)),l(E[C-2],10))E[C]=(E[C-16]+H+E[C-7]+I)%a end;local J,i,K,L,M,k,N,O=f(F)for C=1,64 do local P=d(d(g(M,6),g(M,11)),g(M,25))local Q=d(b(M,k),b(c(M),N))local R=(O+P+Q+p[C]+E[C])%a;local S=d(d(g(J,2),g(J,13)),g(J,22))local T=d(d(b(J,i),b(J,K)),b(i,K))local U=(S+T)%a;O,N,k,M,L,K,i,J=N,k,M,(L+R)%a,K,i,J,(R+U)%a end;F[1]=(F[1]+J)%a;F[2]=(F[2]+i)%a;F[3]=(F[3]+K)%a;F[4]=(F[4]+L)%a;F[5]=(F[5]+M)%a;F[6]=(F[6]+k)%a;F[7]=(F[7]+N)%a;F[8]=(F[8]+O)%a;return F end;local V={__tostring=function(J)return string.char(unpack(J))end,__index={toHex=function(self,j)return("%02x"):rep(#self):format(unpack(self))end,isEqual=function(self,W)if type(W)~="table"then return false end;if#self~=#W then return false end;local X=0;for w=1,#self do X=bit32.bor(X,d(self[w],W[w]))end;return X==0 end}}local function Y(W,h)local i={}for w=1,h do i[(w-1)*4+1]=b(l(W[w],24),0xFF)i[(w-1)*4+2]=b(l(W[w],16),0xFF)i[(w-1)*4+3]=b(l(W[w],8),0xFF)i[(w-1)*4+4]=b(W[w],0xFF)end;return setmetatable(i,V)end;function sha256(y)local y=y or""y=type(y)=="table"and{f(y)}or{tostring(y):byte(1,-1)}y=x(y)local F={f(o)}for w=1,#y do F=D(y[w],F)end;return Y(F,8)end
- end
- local io_balance = 0
- local current = ""
- -- Serialize a value, not in a way which lets you get the original one back. Internal.
- local function serialize(data)
- local ty = type(data)
- if ty == "number" then return tostring(data)
- elseif ty == "string" then return data
- elseif ty == "table" then
- local out = ""
- for k, v in pairs(data) do
- out = out .. serialize(k) .. serialize(v)
- end
- return out
- elseif ty == "function" then
- local ok, res = pcall(string.dump, data)
- if ok then return res
- else return tostring(data) end
- else return tostring(data) end
- end
- --Add data to the entropy pool.
- local function add(data)
- current = sha256(tostring(current) .. serialize(data))
- io_balance = io_balance + 1
- end
- -- Initially seed it with time
- add(os.epoch "utc")
- -- Get a new chunk (16 bytes, 128 bits) from the entropy pool. Internal.
- local function get_chunk()
- local x = current
- current = sha256(x)
- io_balance = io_balance - 1
- -- Limit it to only providing *half* the current thing at once
- local slice = {}
- for i = 1, 16 do slice[i] = x[i] end
- return slice
- end
- -- Get a single unsigned 8-bit integer
- local function get_u8()
- return get_chunk()[1]
- end
- -- Get a variable-length string
- local function get_str(len)
- local str = ""
- local remaining = len
- repeat
- local c = get_chunk()
- local diff = math.min(remaining, 16)
- for i = 1, diff do
- str = str .. string.char(c[i])
- end
- remaining = remaining - diff
- until remaining == 0
- return str
- end
- -- Get a single unsigned 32-bit integer
- local function get_u32()
- local chunk = get_chunk()
- local b1, b2, b3, b4 = chunk[1], chunk[2], chunk[3], chunk[4]
- return b1 * 0x1000000 + b2 * 0x10000 + b3 * 0x100 + b4
- end
- -- Get a randomish float between 0 and 1
- local function get_0_1_float()
- return get_u32() / 0x100000000
- end
- -- Get a rough estimate of how much entropy has been added vs. removed. I totally know what entropy is.
- local function balance()
- return io_balance
- end
- -- Listen to events and use them for entropy
- local function hook()
- while true do
- add {os.epoch "utc", coroutine.yield()}
- end
- end
- return {
- add = add,
- get_u32 = get_u32,
- get_u8 = get_u8,
- get_str = get_str,
- balance = balance,
- hook = hook
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement