Jump to content




SHA-256 in Pure Lua

utility lua api

66 replies to this topic

#1 GravityScore

  • Members
  • 796 posts
  • LocationLand of Meh

Posted 05 January 2013 - 09:38 AM

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.

#2 theoriginalbit

    Semi-Professional ComputerCrafter

  • Moderators
  • 7,332 posts
  • LocationAustralia

Posted 05 January 2013 - 12:10 PM

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?

#3 GravityScore

  • Members
  • 796 posts
  • LocationLand of Meh

Posted 05 January 2013 - 12:34 PM

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. :P

#4 CoolisTheName007

  • Members
  • 304 posts

Posted 05 January 2013 - 01:04 PM

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.

#5 GravityScore

  • Members
  • 796 posts
  • LocationLand of Meh

Posted 05 January 2013 - 09:17 PM

 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.

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, ...)?)

#6 theoriginalbit

    Semi-Professional ComputerCrafter

  • Moderators
  • 7,332 posts
  • LocationAustralia

Posted 05 January 2013 - 10:37 PM

 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.
I would have suggested a way to test for curiosity but because of the way that os.time() works in CC there went the easiest way :P not having any system time in milliseconds sucks sometimes :P



OFF TOPIC:

 GravityScore, on 05 January 2013 - 09:17 PM, said:

"number is too large (maximum allowed: 2^32-1)"
Yeh I had/may still have some issues (haven't overly tested it) with that atm with the Extended String Library and implementing Java's hashCode function...

#7 CoolisTheName007

  • Members
  • 304 posts

Posted 06 January 2013 - 04:22 AM

 GravityScore, on 05 January 2013 - 09:17 PM, said:

Would it be better if I stored each function in a local variable? (like local band = function(int1, int2, int3, ...)?)

Yes, but outside the sha244 function, like

local function band(...

end

function sha244(...)

#8 GravityScore

  • Members
  • 796 posts
  • LocationLand of Meh

Posted 06 January 2013 - 05:13 AM

 CoolisTheName007, on 06 January 2013 - 04:22 AM, said:

 GravityScore, on 05 January 2013 - 09:17 PM, said:

Would it be better if I stored each function in a local variable? (like local band = function(int1, int2, int3, ...)?)

Yes, but outside the sha244 function, like

local function band(...

end

function sha244(...)

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.

#9 CoolisTheName007

  • Members
  • 304 posts

Posted 06 January 2013 - 07:21 AM

 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.

#10 DiamondOwner

  • Members
  • 29 posts
  • LocationWhere am I? My Minecraft GPS tells me I'm in Minecraft.

Posted 04 February 2013 - 11:15 AM

How do you run the hash code for sha256?

#11 GravityScore

  • Members
  • 796 posts
  • LocationLand of Meh

Posted 05 February 2013 - 03:17 AM

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)


#12 DiamondOwner

  • Members
  • 29 posts
  • LocationWhere am I? My Minecraft GPS tells me I'm in Minecraft.

Posted 05 February 2013 - 09:46 AM

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 :D .

#13 theoriginalbit

    Semi-Professional ComputerCrafter

  • Moderators
  • 7,332 posts
  • LocationAustralia

Posted 05 February 2013 - 02:53 PM

 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?
http://en.wikipedia....f_SHA_functions

 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?
You just open the programs file and read the contents, thats a string. It the program is big enough it may crash the computer with a failure to yield (although I haven't tested if it will with this one, it does it with others). But be aware, you cannot do a hash of a program and then store it in itself, because then the hash will change, so the best method is to have an external program that stores all the and compares all the hashes, then store ITS own hash in a file somewhere for comparison.

 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 :D .
Not quite. With parallel functions you need to give it a function pointer, and since a function pointer means you can provide parameters you would need to setup a function that gets called from the parallel, which then calls the hashing.

#14 KillaVanilla

  • Members
  • 303 posts

Posted 10 February 2013 - 04:41 PM

 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, ...)?)

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.

#15 theoriginalbit

    Semi-Professional ComputerCrafter

  • Moderators
  • 7,332 posts
  • LocationAustralia

Posted 10 February 2013 - 05:19 PM

 KillaVanilla, on 10 February 2013 - 04:41 PM, said:

I just moduloed (spelling?) pretty much every variable in the code by (2^32-1)
I think it would be this?

I just used modulo
Or
I just used modulus

#16 KillaVanilla

  • Members
  • 303 posts

Posted 10 February 2013 - 07:38 PM

 TheOriginalBIT, on 10 February 2013 - 05:19 PM, said:

 KillaVanilla, on 10 February 2013 - 04:41 PM, said:

I just moduloed (spelling?) pretty much every variable in the code by (2^32-1)
I think it would be this?

I just used modulo
Or
I just used modulus
Okay, thanks for the insight.

#17 bjornir90

  • Members
  • 378 posts
  • LocationFrance

Posted 11 February 2013 - 05:50 AM

To make it de-hash the msg I just have to run the function again ?

#18 remiX

  • Members
  • 2,076 posts
  • LocationSouth Africa

Posted 11 February 2013 - 07:26 AM

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

#19 Left

  • Members
  • 88 posts

Posted 22 March 2013 - 08:45 PM

Hello, Gravity.

Can I use SHA256 for CUNIX root and other user password encryption? Thanks, Lin

#20 GravityScore

  • Members
  • 796 posts
  • LocationLand of Meh

Posted 22 March 2013 - 09:19 PM

Sure, go ahead!





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users