do local function V(V,B,G,F)local K,E,L,q=table.create(F),0,0,1 for F=1,F,1 do for K=math.max(1,(F+1)-#B),math.min(F,#V),1 do E=E+(G*V[K])*B[(F+1)-K]end local c=E%TWO_POW_24 K[F]=math.floor(c)E=(E-c)/TWO_POW_24 L=L+c*q q=q*TWO_POW_24 end return K,L end local B,G,F,K,E,L=0,{4;1;2,-2,2},4,{1},sha2_H_hi,sha2_H_lo repeat F=F+G[F%6]local q=1 repeat q=q+G[q%6]if q*q>F then local G=F^.33333333333333 local q=G*TWO_POW_40 q=V(table.create(1,math.floor(q)),K,1,2)local c,X=V(q,V(q,q,1,4),-1,4)local m=(q[2]%65536)*65536+math.floor(q[1]/256)local h=(q[1]%256)*16777216+math.floor(((X*(TWO_POW_NEG_56/3))*G)/F)if B<16 then G=math.sqrt(F)q=G*TWO_POW_40 q=V(table.create(1,math.floor(q)),K,1,2)c,X=V(q,q,-1,2)local m=(q[2]%65536)*65536+math.floor(q[1]/256)local h=(q[1]%256)*16777216+math.floor((X*TWO_POW_NEG_17)/G)local I=B%8+1 sha2_H_ext256[224][I]=h E[I],L[I]=m,h+m*hi_factor if I>7 then E,L=sha2_H_ext512_hi[384],sha2_H_ext512_lo[384]end end B=B+1 sha2_K_hi[B],sha2_K_lo[B]=m,h%K_lo_modulo+m*hi_factor break end until F%q==0 until B>79 end

do
	local function mul(src1, src2, factor, result_length)
		-- src1, src2 - long integers (arrays of digits in base TWO_POW_24)
		-- factor - small integer
		-- returns long integer result (src1 * src2 * factor) and its floating point approximation
		local result, carry, value, weight = table.create(result_length), 0, 0, 1
		for j = 1, result_length do
			for k = math.max(1, j + 1 - #src2), math.min(j, #src1) do
				carry = carry + factor * src1[k] * src2[j + 1 - k] -- "int32" is not enough for multiplication result, that's why "factor" must be of type "double"
			end

			local digit = carry % TWO_POW_24
			result[j] = math.floor(digit)
			carry = (carry - digit) / TWO_POW_24
			value = value + digit * weight
			weight = weight * TWO_POW_24
		end

		return result, value
	end

	local idx, step, p, one, sqrt_hi, sqrt_lo = 0, {4, 1, 2, -2, 2}, 4, {1}, sha2_H_hi, sha2_H_lo
	repeat
		p = p + step[p % 6]
		local d = 1
		repeat
			d = d + step[d % 6]
			if d * d > p then
				-- next prime number is found
				local root = p ^ (1 / 3)
				local R = root * TWO_POW_40
				R = mul(table.create(1, math.floor(R)), one, 1, 2)
				local _, delta = mul(R, mul(R, R, 1, 4), -1, 4)
				local hi = R[2] % 65536 * 65536 + math.floor(R[1] / 256)
				local lo = R[1] % 256 * 16777216 + math.floor(delta * (TWO_POW_NEG_56 / 3) * root / p)

				if idx < 16 then
					root = math.sqrt(p)
					R = root * TWO_POW_40
					R = mul(table.create(1, math.floor(R)), one, 1, 2)
					_, delta = mul(R, R, -1, 2)
					local hi = R[2] % 65536 * 65536 + math.floor(R[1] / 256)
					local lo = R[1] % 256 * 16777216 + math.floor(delta * TWO_POW_NEG_17 / root)
					local idx = idx % 8 + 1
					sha2_H_ext256[224][idx] = lo
					sqrt_hi[idx], sqrt_lo[idx] = hi, lo + hi * hi_factor
					if idx > 7 then
						sqrt_hi, sqrt_lo = sha2_H_ext512_hi[384], sha2_H_ext512_lo[384]
					end
				end

				idx = idx + 1
				sha2_K_hi[idx], sha2_K_lo[idx] = hi, lo % K_lo_modulo + hi * hi_factor
				break
			end
		until p % d == 0
	until idx > 79
end
