It is slower but more secure than RC4, however it is faster than AES.
This is based off the implementation in this ietf draft (https://tools.ietf.o...a20-poly1305-01)
Usage
As with any stream ciphers, encryption and decryption are done in exactly the same way, encrypting a plaintext will give you a ciphertext, re-encrypting that ciphertext with the same settings will give you the plaintext back.
The only function, "crypt", takes 3 main arguments, and two optional.
crypt(data, key, nonce, counter, round)
The type of data that must be passed is an array of 8-bits values per indexes, example the string "hello world" would be {0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64}
Strings can be easily converted into this format by doing {str:byte(1,-1)}, and can be as easily converted back into string with string.char(unpack(data))
The output of the function is in the same array format coupled with a __tostring metamethod for easy conversion back into string.
The only function, "crypt", takes 3 main arguments, and two optional.
crypt(data, key, nonce, counter, round)
The type of data that must be passed is an array of 8-bits values per indexes, example the string "hello world" would be {0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64}
Strings can be easily converted into this format by doing {str:byte(1,-1)}, and can be as easily converted back into string with string.char(unpack(data))
- The "data" argument is your data that you want to encrypt, and can take both an 8-bits array and a string as an input.
- The "key" argument is your secret key, its size can be either 128-bits (16 bytes) or 256-bits (32 bytes), a 256-bits key is recommended and does not make the algorithm run slower than with an 128-bits one.
- The "nonce" argument is a public, random nonce, it must be 96-bits (12 bytes), this value should be different for every messages transmitted, see example below.
- The "counter" argument is optional, defaulted to 1, is the starting point of the counter used by the cipher.
- The "round" argument is optional, default is 20, is the amount of rounds that the algorithm does, other standardized amounts are 8 and 12, less rounds runs faster at the slight cost of security.
The output of the function is in the same array format coupled with a __tostring metamethod for easy conversion back into string.
Example
The preferable way of implementing most ciphers for modem transmission is the following
os.loadAPI("chacha")
local random = math.random
local key = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31} #-- Generate your own random key
#-- Little utility function for easy nonce generation
local function gen_nonce(size)
local n = {}
for i = 1, size do n[#n+1] = random(0, 255) end
return n
end
local function encrypt(msg)
local nonce = gen_nonce(12)
local ctx = chacha.crypt(msg, key, nonce)
return { nonce, ctx }
end
local function decrypt(msg)
local nonce = msg[1]
local ctx = msg[2]
return chacha.crypt(ctx, key, nonce)
end
#-- Sending
local message = "hello world"
transmit( encrypt(message) )
#-- Receiving
local e = {os.pullEvent("modem_message")}
local msg = e[5]
local receivedMsg = decrypt(msg)
Download: pastebin get GPzf9JSa chacha
Edited by Anavrins, 12 August 2018 - 07:44 PM.











