Hashes and Salts; what they are and the simple concept of it in Luau

Just cause I’m not experienced in one section doesn’t mean I don’t know the bare basics

Oh okay! Makes more sense now haha

Hashing is definitely a one way function and cannot be reversed. However, if you’re referring to old algorithms like MD5, those are cryptographically insecure. In contrast, modern algorithms are cryptographically secure.

If you’re one of those people who are worried about post-quantum cryptography, NSA put out some great information regarding that:

Edit: To provide some more insight into the latest public cryptanalysis: currently, MD5’s collision resistance can be broken in 2^18 time. MD5 can still be used to make sure a file hasn’t been unintentionally corrupted. SHA256 has some interesting cryptanalysis to look into, but it is still certified by NIST’s Federal Information Processing Standards.

2 Likes

Take a good read at my post. I take a deep dive in explaining hashing and other various cryptography concepts. In doing so, I give examples of how you could can create salted hashes for passwords in Roblox.

I am well aware of what sanity checks are- they’re a very simple concept that anyone with proficient knowledge on Filtering-Enabled technology would know. We’re not talking about remote event security, we’re talking about cryptography.

1 Like

I would strongly advise against promoting your own hashing algorithms- especially given the fact that you’ve branded your post as a community tutorial. It’s best to share the current industry-leading practices as opposed to your own algorithm.

Also, I would strongly advise creating your own algorithm here. For one, your previous “algorithm” was already deeply flawed. Current cryptographic hash functions have been developed by some of the best mathematicians out there, all backed by highly equipped cryptanalysis experts.

If you’re adamant on creating your own algorithm- by all means do so! It’s an incredible learning experience. But don’t advertise whatever you create as something that has been accepted by the industry.

Yo this cool thanks very much i like Cryptography! also basically a hash generator would always give the same hash if the input given was the same right? that makes me wonder how they make hash generator. I could imagine like they take account of how many characters there are, how many numbers there are, how many characters there are, how many characters is capitalised, how long is the input, is the letter after the before a vocal, is the letter before a vocal, or just combine both before and after to make a unique vocal, and that also depends on the character, and while that also take account if it was capitalize or not, or just depending on the character length, how many uppercase or so, make it combine depending on them, and just combine them so much.

uhh so basically i wanna ask if a hash generator is just them taking EVERY single thing in the input into account and combining every function in world possible every single thing like crazy, and maybe depending on the function theres a function on top of that too?

The closest I would probably be able to do is create a function to cut, shift, rotate, inverse, reverse and insert bytecode via the Bit32 module based on the characters in the input.

Right now I have very simple ‘hashing’ system that has same output is just by averageing the bytecode in a string, but that would be quite weak.

Would a combination of the utf8 & bit32 libaries be able to create a strong-enough lua based hashing algorithm or do I need more built-in libaries to accomplish this?

advise against*?

Yes, the function of a hash is to guarantee a few things:

  • One input always corresponds to the same output
  • It’s extremely difficult to find an input that corresponds to a desired output
  • Changing any tiny little bit of the input results in a completely different output

I think @ForcyDorcy meant that I should improve on my ‘hashing’ algorithm, on which I will.

You are mixing up Filtering Enabled and hashing.
Hashing does fall under a sort sanity check (if you definition of sanity check is a broad as security by design).

You clearly didn’t read what he said and/or don’t understand what he is talking about.

You should use a real hash algorithm for this
Here is a fast & simple implementation of the SHA256 hash

local band = bit32.band
local bnot = bit32.bnot
local bxor = bit32.bxor

local rrotate = bit32.rrotate
local rshift = bit32.rshift

local primes = 
{
	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 toHex(str)
	local result = str:gsub('.', function (char)
		return string.format("%02x", char:byte())
	end)
	
	return result
end

local function toBytes(value, length)
    local str = ""
	
    for i = 1, length do
        local rem = value % 256
        str = string.char(rem) .. str
        value = (value - rem) / 256
    end
	
    return str
end

local function readInt32(buffer, index)
    local value = 0
	
    for i = index, index + 3 do 
		value = (value * 256) + string.byte(buffer, i)
	end
	
    return value
end

local function digestBlock(msg, i, hash)
	local digest = {}
	
	for j = 1, 16 do 
		digest[j] = readInt32(msg, i + (j - 1) * 4) 
	end
	
	for j = 17, 64 do
		local v = digest[j - 15]
		local s0 = bxor(rrotate(v, 7), rrotate(v, 18), rshift(v, 3))
		
		v = digest[j - 2]
		digest[j] = digest[j - 16] + s0 + digest[j - 7] + bxor(rrotate(v, 17), rrotate(v, 19), rshift(v, 10))
	end
	
	local a, b, c, d, e, f, g, h = unpack(hash)
	
	for i = 1, 64 do
		local s0 = bxor(rrotate(a, 2), rrotate(a, 13), rrotate(a, 22))
		local maj = bxor(band(a, b), band(a, c), band(b, c))
		
		local t2 = s0 + maj
		local s1 = bxor(rrotate(e, 6), rrotate(e, 11), rrotate(e, 25))
		
		local ch = bxor(band(e, f), band(bnot(e), g))
		local t1 = h + s1 + ch + primes[i] + digest[i]
		
		h, g, f, e, d, c, b, a = g, f, e, d + t1, c, b, a, t1 + t2
	end
	
	hash[1] = band(hash[1] + a)
	hash[2] = band(hash[2] + b)
	hash[3] = band(hash[3] + c)
	hash[4] = band(hash[4] + d)
	hash[5] = band(hash[5] + e)
	hash[6] = band(hash[6] + f)
	hash[7] = band(hash[7] + g)
	hash[8] = band(hash[8] + h)
end

local function sha256(msg)
	do
		local extra = 64 - ((#msg + 9) % 64)
		local len = toBytes(8 * #msg, 8)
		
		msg = msg .. '\128' .. string.rep('\0', extra) .. len
		assert(#msg % 64 == 0)
	end
	
	local hash = 
	{
		0x6a09e667,
		0xbb67ae85,
		0x3c6ef372,
		0xa54ff53a,
		0x510e527f,
		0x9b05688c,
		0x1f83d9ab,
		0x5be0cd19,	
	}
	
	for i = 1, #msg, 64 do 
		digestBlock(msg, i, hash)
	end
	
	local result = ""
	
	for i = 1, 8 do
		local value = hash[i]
		result = result .. toBytes(value, 4)
	end
	
	return toHex(result)
end

Here is the original posts where I got this. : Faster Lua VM: Studio beta - #286 by maximum_adhd

I highly suggest you use this SHA256 implementation (or another secure hash)
instead of a random string generator, as its kind of misleading.

Here are also some other great things related to these
Hashlib - has a lot of different hash functions: HashLib - Cryptographic hashes in pure Lua
AES implementration - great symmetric encryption (edit: this AES implementation is a bit slow and produces some non standard) : Lua AES Implementation

1 Like

Yes, like I said before it is mostly just for concept.

Also Secure Hashing Algorithmn is a very outdated algorithmn and can easily be cracked with the processing power of modern computers, but I really like how you implemented it in.

Since you seem to be good at hashing, do you think that a combination of Bit32 and utf8 be able to create a hashing algorithm or something very similar? I have some details about my plans in the replies in this post.

That applies to older versions eg SHA-1. However the version I supplied is part of SHA-2 which is secure as it’s a more up to date version.
In particular it’s SHA256 which is considered secure still today and will be for a lot longer (of course you still have to do salting like always).

Bit32 absolutely, it will do a lot of optimisations. UTF8 not so much.
UTF8 is only a character encoding.

If you want to make a hash algorithm (which is secure), you should really read up some good info on the internet as there is simply too much to explain here. But yeah go for it if you want, however i’d probably not use it for production as the popular hash algorithms are verified to be secure & fast.

1 Like

Yes, I will pretty much just use utf8 to get the byte data and then manipulate the bytedata with the bit32 module.

I am quite experienced with the Bit32 module so this should be no issue.

While you could do that I’d advice you use the raw byte data instead.
It’s better for performance, security and for a lot of other reasons.

One thing to keep in mind is to make sure that

  • changing 1 character should completely change the hash

  • Hash should be same lenght always

  • Not too fast or slow.

  1. I could add some average bytedata, cut of and insert bytedata based on the input.
  2. Answered in 1.
  3. Parameters may be hard to control unlike proper SHAs like bcript, but I am sure that adding more bit proccessing would be more secure and not too fast.

Hash functions are based on a number of math problems mathematicians have come up with. It is fairly decoupled from the actual logic you’re describing with strings. It’s all math.

cant these be including in math too? all that i mentioned is how many and how long so they are all in particular, numbers that basically means, math

Here’s a video by Dr. Mike Pound giving a more specific explanation about SHA and the underlying technical details about how it goes about hashing things.

Sorry for bumping, but

The code is inefficient as your putting more memory by

Hash..=thing

“thing” will still be on the memory

A more efficient way to do this is by putting a table, and insert the characters in it, and table.concat it when youre done.