This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
KleinRefrigerator's profile picture

[CC 1.46] ComputerCraft Crypto rev1

Started by KleinRefrigerator, 15 November 2012 - 04:25 PM
KleinRefrigerator #1
Posted 15 November 2012 - 05:25 PM
About
ComputerCraft Crypto (alternate name: oh god why did I decide to implement AES in Lua) is intended to be a general purpose cryptography API and absolute overkill for Minecraft. At the moment, I have only implemented the core components of AES, it requires a bit more work to be in a generally useable state. Provided I don't get busy or lose interest, I plan to implement ECB, CBC, CFB, and OFB, and look into an authenticated encryption mode like GCM. I also hope to implement some cryptographic hash functions and RSA.

And just to head off any potential objections, I'm not writing this because I expect it to be widely useful, I'm writing it because it's fun and interesting. It's complicated enough that I figure it would be a waste not to share it.

A Word About Security
I will, of course, do my best to ensure that my implementation is correct and secure. However, if you have a security-critical application: first of all, don't do it in minecraft, second: I cannot guarantee the security of this package. Even if it is secure, it is secure only within the context of ComputerCraft. The data you send to the server and vice versa is still sent unencrypted and can be intercepted by someone on your local network or anywhere between you and the server. (Though this should not be the case; encryption should be standard on all electronic communications.) Even properly implemented AES is not appropriate for all uses, and not all cipher modes are equal.

That said, this is almost certainly overkill for any use anyone here will have for it, and AES is currently practically unbreakable (a brute force attack can be expected to take longer than the age of the universe on the fastest supercomputer that exists today.)

cccAES
Neal R. Wagner said:
Law AES-1: Conventional block ciphers are always ugly, complicated, inelegant brutes, and the AES is no exception.

AES is an ugly, complicated, inelegant, and goddamn effective symmetric block cipher. The same key is used to encrypt and decrypt, and AES encrypts 16 bytes of data in chunks, rather than a byte at a time. AES supports 128, 192, and 256 bit keys.

Please note that while I have tested every function currently included, I cannot properly run the standard test vectors until I have implemented the various cipher modes.

Download:
http://pastebin.com/e65Bm5G5
pastebin get e65Bm5G5 cccAES

cccAES Functions:

-- expands a 16, 24, or 32 byte key to the full size required (176, 208, and 240 bytes)
function expandKey(key)
-- runs one full round of AES on the state given the roundKey and returns it
function AESRound(state, roundKey)
-- same as AESRpund but decryption
function AESRoundInv(state, roundKey)
-- retrives a round key from an expanded key given the round number
function getRoundKey(eKey, round)
-- the full 10, 12, or 14 rounds of encryption
function AESMain(state, eKey)
-- same as AESMain but decryption
function AESMainInv(state, eKey)

Sample Usage:
As cccAES currently stands, it's not terribly useful unless you're familiar with block cipher modes. Stand by for revision 2 if you're not.

Change Log:
rev1: all round operations (subBytes, shiftRows, mixColumns, strXor) and requisite functions, block cipher encryption, and the key schedule

(hopefully) upcoming features: ECB, CBC, CFB, OFB
dissy #2
Posted 15 November 2012 - 05:53 PM
That is some mighty impressive work sir! My hat is off to you.
KleinRefrigerator #3
Posted 15 November 2012 - 06:10 PM
That is some mighty impressive work sir! My hat is off to you.

Thanks! It's not terribly hard to implement, there's just a lot of it.
Sammich Lord #4
Posted 15 November 2012 - 09:36 PM
That is some mighty impressive work sir! My hat is off to you.
I didn't know people still wore hats then took them off.
robhol #5
Posted 15 November 2012 - 09:50 PM
*puts on hat and takes it off*

Anyway, I was expecting just another homegrown deal that's about as secure as Rot13, lol. Nice work.
CoolisTheName007 #6
Posted 26 November 2012 - 12:14 AM
EDIT: I'm posting this here because it's a cryptography post, and people gravitating around it might have thought about it before.
What would you do to ensure that B, via broadcasting, informs A of it's existence and certifies itself as belonging to the same permission group as A, without enabling malevolent computer C to do the same? (C knows both the ID's and general programs that A and B are running, but A and B can share a private key previously set). IMPORTANT: the key is not a white-list; though probably one could update one over the network as needed; not sure about which one is easier.
KleinRefrigerator #7
Posted 03 December 2012 - 07:07 AM
EDIT: I'm posting this here because it's a cryptography post, and people gravitating around it might have thought about it before.
What would you do to ensure that B, via broadcasting, informs A of it's existence and certifies itself as belonging to the same permission group as A, without enabling malevolent computer C to do the same? (C knows both the ID's and general programs that A and B are running, but A and B can share a private key previously set). IMPORTANT: the key is not a white-list; though probably one could update one over the network as needed; not sure about which one is easier.

A and B actually don't even need to share a private key. As long as A and B know each other's public keys, they can digitally sign something with their private keys to verify their identities without C being able to. Public keys are easy to share over the network because they can be shared freely. Even if C knows both public keys, he can't spoof anything in this situation. One difficulty with RSA, though, is that you can't encrypt anything longer than the key (should you need privacy too, not just authentication).
Key exchange algorithms are a way to work around this, and there are two I know of off the top of my head. A can generate a public-private keypair (or already has one) and transmit the public key to B. B encrypts a symmetric key with it, like for AES, and sends it back to A, who can decrypt it. A and B then share a symmetric key that nobody else can get without access to either A or B or knowledge of A's private key. The other is for both A and B to either generate or have keypairs, exchange public keys, and then A combines A's private and B's public keys and vice versa. It turns out both these processes give the same answer, and you can use that as a symmetric key.

Edit: 'combines' in the context of the second key exchange algorithm is not simple addition or concatenation as far as I know, but there's some mathematical operation you can do that will give the same answer on A's public and B's private as on A's private and B's public.
CoolisTheName007 #8
Posted 03 December 2012 - 09:22 AM
snip

Thanks for the answer. There's quite a lot of discussion going on here about rednet changes in the future, that may depend on how efficient encryption is.
bwhodle #9
Posted 18 July 2013 - 06:08 PM
Well, wouldn't implementing hash functions be insanely hard due to the cc's +/- 2^32-1 limit for all numbers? I tried it once but it's just too hard to do with the number limits. (I tried MD5 and SHA-something, they both are tough).
bentallea #10
Posted 23 August 2013 - 01:21 AM
Well, wouldn't implementing hash functions be insanely hard due to the cc's +/- 2^32-1 limit for all numbers? I tried it once but it's just too hard to do with the number limits. (I tried MD5 and SHA-something, they both are tough).

If you use a 32 bit hash algorithm then there is no issue with number limits in lua or computercraft. however, fir larger sequences, here are a few suggestions:
  1. output a table of bits using true/false or 1/0
  2. output a series of smaller numbers that fit within the computational limits of lua and ComputerCraft
  3. translate the bits to hexadecimal in a string
  4. compress the binary data to an alphanumerical string that is easier to read.
number 4 is the method that i am using for a project of mine that requires a 64 bit hash. i lengthened the table of bits to 66 then red each group of 6 as a letter or number