You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

86 lines
2.0 KiB
Lua

local ffi = require('ffi')
local loaded, lib = pcall(ffi.load, 'sodium')
if not loaded then
return nil, lib
end
local typeof = ffi.typeof
local format = string.format
ffi.cdef[[
const char *sodium_version_string(void);
const char *crypto_secretbox_primitive(void);
size_t crypto_secretbox_keybytes(void);
size_t crypto_secretbox_noncebytes(void);
size_t crypto_secretbox_macbytes(void);
size_t crypto_secretbox_zerobytes(void);
int crypto_secretbox_easy(
unsigned char *c,
const unsigned char *m,
unsigned long long mlen,
const unsigned char *n,
const unsigned char *k
);
int crypto_secretbox_open_easy(
unsigned char *m,
const unsigned char *c,
unsigned long long clen,
const unsigned char *n,
const unsigned char *k
);
void randombytes(unsigned char* const buf, const unsigned long long buf_len);
]]
local sodium = {}
local MACBYTES = lib.crypto_secretbox_macbytes()
local NONCEBYTES = lib.crypto_secretbox_noncebytes()
local KEYBYTES = lib.crypto_secretbox_keybytes()
local key_t = typeof(format('const unsigned char[%i]', tonumber(KEYBYTES)))
local nonce_t = typeof(format('unsigned char[%i] const', tonumber(NONCEBYTES)))
local unsigned_char_array_t = typeof('unsigned char[?]')
function sodium.key(key)
return key_t(key)
end
function sodium.nonce()
local nonce = nonce_t()
lib.randombytes(nonce, NONCEBYTES)
return nonce, NONCEBYTES
end
function sodium.encrypt(decrypted, decrypted_len, nonce, key)
local encrypted_len = decrypted_len + MACBYTES
local encrypted = unsigned_char_array_t(encrypted_len)
if lib.crypto_secretbox_easy(encrypted, decrypted, decrypted_len, nonce, key) < 0 then
return error('libsodium encryption failed')
end
return encrypted, encrypted_len
end
function sodium.decrypt(encrypted, encrypted_len, nonce, key)
local decrypted_len = encrypted_len - MACBYTES
local decrypted = unsigned_char_array_t(decrypted_len)
if lib.crypto_secretbox_open_easy(decrypted, encrypted, encrypted_len, nonce, key) < 0 then
return error('libsodium decryption failed')
end
return decrypted, decrypted_len
end
return sodium