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
86 lines
2.0 KiB
Lua
3 years ago
|
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
|