lua-cryptorandom is a lightweight, native library for Lua aimed to generate cryptographically secure pseudo random numbers, using trusted sources of randomness provided by the operating system.
- On Unix-like distributions, it uses the
OpenSSL
library to generate random numbers; - On Windows, it uses the WINAPI
bcrypt
library; - On macOS / iOS, it uses the
Security
framework.
Note
lua-cryptorandom
is implemented in C, and also compiles as C++.
Important
On Unix-like operating systems (e.g.: Linux, BSD), lua-cryptorandom
depends on the OpenSSL
library:
-
On Debian-based (e.g.: Ubuntu) distributions:
sudo apt install -y libssl-dev
-
On RedHat-based (e.g.: Fedora) distributions:
sudo dnf install openssl-devel
-
On BSD-based (e.g.: FreeBSD) distributions:
pkg install openssl-devel
Assuming that LuaRocks is properly installed and configured on your system, execute the following command:
luarocks install lua-cryptorandom
local random = require("lua-cryptorandom")
-- number of bytes to generate
local n = 10
local bytes, err = random.bytes(n)
if (bytes == nil) then
print("error code: ", err)
else
assert(n == #bytes, "Unexpected number of bytes")
-- print each byte
for i, b in ipairs(bytes) do
print(i, ("0x%02X"):format(b))
end
end
local random = require("lua-cryptorandom")
local number, err = random.number()
if (number == nil) then
print("error code: ", err)
else
print("number: ", number)
end
There are two functions to generate integers: take and integer.
-
Generate integer (usually in 32-bits range):
local random = require("lua-cryptorandom") local take, err = random.take() if (take == nil) then print("error code: ", err) else print("take: ", take) end
-
Generate a potentially large integer (in 64-bits range):
local random = require("lua-cryptorandom") local integer, err = random.integer() if (integer == nil) then print("error code: ", err) else print("integer: ", integer) end
Many security operations rely on high-quality randomization services to avoid reproducibility and remain resistant to reverse engineering:
- randomized password generation;
- nonces (numbers used once) generation;
- initialization vectors;
- salts in passwords before hashing;
- tokenization (token generation) to represent sensitive data;
- secure random sampling in statistical analysis.
Important
For each method below, always check whether the first returned value is nil
or not. When the first value is nil
, there was an underlying error generating random values. It can fail because no trusted random source is available or the trusted entropy source temporarily fail to provide sufficient randomness material.
-
Description: Generates a sequence of random bytes
-
Signature:
bytes(n)
- Parameters:
- n: the number of bytes to generate
- Return:
table | nil
as first value, andnil | number
as the second.table | nil
: a table containingn
bytes on success, ornil
when an error occurred;nil | integer
: an error code that is set tonil
on success, or aninteger
representing the code used by the underlying library (OpenSSL
on Unix,bcrypt
on Windows andSecurity
framework on macOS / iOS).
- Parameters:
-
Remark: Here, a byte is meant as an integer in the range 0 - 255.
-
Usage:
local random = require("lua-cryptorandom") -- number of bytes to generate local n = 10 local bytes, err = random.bytes(n) if (bytes == nil) then print("error code: ", err) else assert(n == #bytes, "Unexpected number of bytes") -- print each byte for i, b in ipairs(bytes) do print(i, ("0x%02X"):format(b)) end end
-
Description: Generates a random integer
-
Signature:
integer()
- Return:
integer | nil
as first value, andnil | integer
as the second.integer | nil
: the generated integer on success, ornil
when an error occurred;nil | integer
: an error code that is set tonil
on success, or aninteger
representing the code used by the underlying library (OpenSSL
on Unix,bcrypt
on Windows andSecurity
framework on macOS / iOS).
- Return:
-
Remark: The generated integer can be any valid Lua integer, and such integer can span up to 64 bits. Use this function when you need a potentially large integer. For smaller integers, see take.
-
Usage:
local random = require("lua-cryptorandom") local integer, err = random.integer() if (integer == nil) then print("error code: ", err) else print("integer: ", integer) end
-
Description: Generates a random float number
-
Signature:
number()
- Return:
number | nil
as first value, andnil | integer
as the second.number | nil
: the generated float number on success, ornil
when an error occurred;nil | integer
: an error code that is set tonil
on success, or aninteger
representing the code used by the underlying library (OpenSSL
on Unix,bcrypt
on Windows andSecurity
framework on macOS / iOS).
- Return:
-
Remark: since v0.0.2, in case of success, the returned number is not
NaN
or positive/negative infinity values. -
Usage:
local random = require("lua-cryptorandom") local number, err = random.number() if (number == nil) then print("error code: ", err) else print("number: ", number) end
-
Description: Generates a random integer that spans at least 16 bits in size, but usually 32 bits in these-days-computers.
-
Signature:
take()
- Return:
integer | nil
as first value, andnil | integer
as the second.integer | nil
: the generated integer on success, ornil
when an error occurred;nil | integer
: an error code that is set tonil
on success, or aninteger
representing the code used by the underlying library (OpenSSL
on Unix,bcrypt
on Windows andSecurity
framework on macOS / iOS).
- Return:
-
Remark: The generated integer has, at least, 16 bits in size, but it is usually a 32 bits integer in these-day-computers. The returned integer has the
int
data type in C. To generate potentially large integers, see integer. -
Usage:
local random = require("lua-cryptorandom") local take, err = random.take() if (take == nil) then print("error code: ", err) else print("take: ", take) end
Warning
This section mostly applies to users running a customized build of Lua.
- The error code (second return value) on each method might deliver a value different than the one returned by the underlying library. This condition might happen when the Lua type
lua_Integer
is shorter than anunsigned long
in size. Even though it can be achieved on personalized builds of Lua (e.g.: Lua compiled as C89 on some platforms), the usual build of Lua should be safe for most users and platforms.
- v0.0.3:
- v0.0.2: Prevent the generation of
NaN
and positive/negative infinity values in the function number. - v0.0.1: Initial release.
- Add CMake as a build system.