SHA-256 in Pure Lua
GravityScore 05 Jan 2013
Hey all,
Quite recently, I've been finding myself needing some very secure hashing functions to encrypt passwords and other data. In light of recent conversations on these forums, it seemed like SHA-1 just wasn't going to cut it.
I started searching and came across SHA-2 - a set of functions that are far more secure than SHA-1. They include SHA-244, SHA-256, SHA-384, and SHA-512. I found a pure Lua implementation of both SHA-244 and SHA-256 here, in the Lua documentation (adapted from the Pseudo code found on Wikipedia here). This seemed like it would work perfectly.
I fired it up with a test example, and found that the standard ComputerCraft bit API couldn't deal with the large numbers that were being produced by this, and also didn't have a right rotate function - so I found a custom implementation of the Lua bit32, and included it.
I vastly adapted both sources, and compiled them into easily copy and paste-able pieces of code (no need to install an API). Albeit, there may be far more speed and size efficient ways (it's around 200 lines) of implementing this, but they work.
In regards to copyright: both of these sources allow the free use of the code in them - they do not require you to include credits or licenses (to be honest, they aren't very clear about who exactly wrote them...).
SHA-256 can be downloaded from Pastebin using the ID: gsFrNjbt.
Quite recently, I've been finding myself needing some very secure hashing functions to encrypt passwords and other data. In light of recent conversations on these forums, it seemed like SHA-1 just wasn't going to cut it.
I started searching and came across SHA-2 - a set of functions that are far more secure than SHA-1. They include SHA-244, SHA-256, SHA-384, and SHA-512. I found a pure Lua implementation of both SHA-244 and SHA-256 here, in the Lua documentation (adapted from the Pseudo code found on Wikipedia here). This seemed like it would work perfectly.
I fired it up with a test example, and found that the standard ComputerCraft bit API couldn't deal with the large numbers that were being produced by this, and also didn't have a right rotate function - so I found a custom implementation of the Lua bit32, and included it.
I vastly adapted both sources, and compiled them into easily copy and paste-able pieces of code (no need to install an API). Albeit, there may be far more speed and size efficient ways (it's around 200 lines) of implementing this, but they work.
In regards to copyright: both of these sources allow the free use of the code in them - they do not require you to include credits or licenses (to be honest, they aren't very clear about who exactly wrote them...).
SHA-256 can be downloaded from Pastebin using the ID: gsFrNjbt.
theoriginalbit 05 Jan 2013
Nice job. I think I will be replacing my SHA-1 with one of these, never found any done quite like this.
On a separate note how are you testing the speed?
On a separate note how are you testing the speed?
GravityScore 05 Jan 2013
I just was printing them one after another, and the SHA-1 to a noticeably longer amount of time than the SHA-244 or 256.
CoolisTheName007 05 Jan 2013
Maybe you were using a sha1 that didn't used the bit API? I adapted one to use it, I doubt that it will be slower.
Also, doing all in one function might seem cleaner, but since each internal function is re-made (not sure exactly of the terminology) each time you call sha244, it is actually worst efficiency-wise.
I have a bench marking module (github) that generates nice-looking results and comparisons between given functions; can't really spend time doing it now with sha.
Also, doing all in one function might seem cleaner, but since each internal function is re-made (not sure exactly of the terminology) each time you call sha244, it is actually worst efficiency-wise.
I have a bench marking module (github) that generates nice-looking results and comparisons between given functions; can't really spend time doing it now with sha.
GravityScore 05 Jan 2013
CoolisTheName007, on 05 January 2013 - 01:04 PM, said:
Maybe you were using a sha1 that didn't used the bit API? I adapted one to use it, I doubt that it will be slower.
Also, doing all in one function might seem cleaner, but since each internal function is re-made (not sure exactly of the terminology) each time you call sha244, it is actually worst efficiency-wise.
I have a bench marking module (github) that generates nice-looking results and comparisons between given functions; can't really spend time doing it now with sha.
Also, doing all in one function might seem cleaner, but since each internal function is re-made (not sure exactly of the terminology) each time you call sha244, it is actually worst efficiency-wise.
I have a bench marking module (github) that generates nice-looking results and comparisons between given functions; can't really spend time doing it now with sha.
Yes the SHA1 I was using wasn't yours that used the CC bit API. Maybe that will be faster - I'm not too concerned about speed with this.
Like I said in the OP, I would have used the local CC bit API, but I couldn't because it gave me the error "number is too large (maximum allowed: 2^32-1)", and it also did not have an implementation of right rotate (rrotate). Would it be better if I stored each function in a local variable? (like local band = function(int1, int2, int3, ...)?)
theoriginalbit 05 Jan 2013
GravityScore, on 05 January 2013 - 09:17 PM, said:
Yes the SHA1 I was using wasn't yours that used the CC bit API. Maybe that will be faster - I'm not too concerned about speed with this.
OFF TOPIC:
GravityScore, on 05 January 2013 - 09:17 PM, said:
"number is too large (maximum allowed: 2^32-1)"
CoolisTheName007 06 Jan 2013
GravityScore 06 Jan 2013
CoolisTheName007, on 06 January 2013 - 04:22 AM, said:
Just note this isn't supposed to be an API. I hate programs that make me install APIs. This is intended to be copied and pasted straight into code. I guess I can move the bit functions outside of the function though. I'll do it now! Thanks for the suggestion.
CoolisTheName007 06 Jan 2013
GravityScore, on 06 January 2013 - 05:13 AM, said:
Just note this isn't supposed to be an API. I hate programs that make me install APIs. This is intended to be copied and pasted straight into code. I guess I can move the bit functions outside of the function though. I'll do it now! Thanks for the suggestion.
To make sure the only function exposed is sha22 to an user that copied and pasted your code into a program, surround the whole code with a do ... end block. That will keep the local functions to that block, and only sha244 will be put into the program's environment:
do
local function band(..)
..
end
function sha244(..)
..
end
end
I use this more and more to keep blocks of code contained to themselves in the same file.
GravityScore 05 Feb 2013
You can run the hash function by copy and pasting the code for the SHA-256 function into you program, then do something like:
local stringToHash = "thisisapassword" hash = sha256(stringToHash)
DiamondOwner 05 Feb 2013
Thx GravityScore. Will global variables also work with the hash function? I'm planning to make my own small OS, may I use your hash code in my OS (I will give you credit.)? Are collisions with the hash "sha256" highly unlikely, unlikely, likely, or highly likely? This is to determine if encryption is required to keep people from reliably using rainbow tables to find out the password. What's the speed of the hash? This will help me determine the timer needed to hash a change to the username/password. I'm new to Lua, so can you convert a program into a string, then hash the program? This is to verify the integrity of core programs. Will this function (the hash) work in parallel.waitForAll? If you read to this part and have answered the above .
theoriginalbit 05 Feb 2013
DiamondOwner, on 05 February 2013 - 09:46 AM, said:
Thx GravityScore. Will global variables also work with the hash function? I'm planning to make my own small OS, may I use your hash code in my OS (I will give you credit.)? Are collisions with the hash "sha256" highly unlikely, unlikely, likely, or highly likely? This is to determine if encryption is required to keep people from reliably using rainbow tables to find out the password. What's the speed of the hash?
DiamondOwner, on 05 February 2013 - 09:46 AM, said:
I'm new to Lua, so can you convert a program into a string, then hash the program?
DiamondOwner, on 05 February 2013 - 09:46 AM, said:
Will this function (the hash) work in parallel.waitForAll? If you read to this part and have answered the above .
KillaVanilla 10 Feb 2013
GravityScore, on 05 January 2013 - 09:17 PM, said:
-snip-
Like I said in the OP, I would have used the local CC bit API, but I couldn't because it gave me the error "number is too large (maximum allowed: 2^32-1)", and it also did not have an implementation of right rotate (rrotate). Would it be better if I stored each function in a local variable? (like local band = function(int1, int2, int3, ...)?)
Like I said in the OP, I would have used the local CC bit API, but I couldn't because it gave me the error "number is too large (maximum allowed: 2^32-1)", and it also did not have an implementation of right rotate (rrotate). Would it be better if I stored each function in a local variable? (like local band = function(int1, int2, int3, ...)?)
I just wrote my own implementation of SHA-2, and ran into the same problem you did. Instead of doing everything with the standard operators as you did, I just used modulus on pretty much every variable in the code by (2^32-1) that was used in addition operations.
Also, as for the second question, you can simply put all of the functions used within the function inside the function body itself. Lua has no problems with functions inside of functions.
theoriginalbit 10 Feb 2013
KillaVanilla 10 Feb 2013
Okay, thanks for the insight.
remiX 11 Feb 2013
No, you can't de-hash a hashed string. To check if a typed string is equal to an already-hased string, hash the typed one and then check if they're equal
Left 22 Mar 2013
Hello, Gravity.
Can I use SHA256 for CUNIX root and other user password encryption? Thanks, Lin
Can I use SHA256 for CUNIX root and other user password encryption? Thanks, Lin