Skip to content

Commit

Permalink
Merge pull request #11 from thibaultcha/feat/jit-compiled
Browse files Browse the repository at this point in the history
feat(argon2) ensure we are JIT compiled
  • Loading branch information
thibaultcha authored Jan 19, 2017
2 parents 432dd16 + e253292 commit ef1ef50
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 45 deletions.
4 changes: 3 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ install:
- luarocks make

script:
- make lint && busted -v --coverage -o gtest --repeat 3 spec
- make lint
- busted --exclude-tags=JIT -v --coverage -o gtest --repeat 3 spec
- if [ "$LUA" = "luajit 2.1" ]; then busted -v -o gtest --tags JIT; fi

after_success:
- luacov-coveralls -i ./src/argon2.lua
Expand Down
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
## [Unreleased][unrelease]

## [3.0.1] - 2017/01/18

### Added

- Ensure `hash_encoded()` and `verify()` are JIT compiled in LuaJIT 2.1.
[#11](https://github.com/thibaultcha/lua-argon2-ffi/pull/11)

## [3.0.0] - 2016/12/08

**Note**: This module's version was bumped to `3.0.0` to reflect the
interoperability of its API with the lua-argon2 implementation. In the future,
lua-argon2 and lua-argon2-ffi will continue sharing the same version number
lua-argon2 and lua-argon2-ffi will continue sharing the same major version number
for similar versions.

### Changed
Expand Down
44 changes: 44 additions & 0 deletions spec/argon2_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ describe("hash_encoded()", function()
argon2.hash_encoded("", "", {parallelism = ""})
end, "bad argument #3 to 'hash_encoded' (expected parallelism to be a number, got string)")

assert.has_error(function()
argon2.hash_encoded("", "", {hash_len = ""})
end, "bad argument #3 to 'hash_encoded' (expected hash_len to be a number, got string)")

--[[
assert.has_error(function()
argon2.hash_encoded("", "", {}, "")
Expand Down Expand Up @@ -233,6 +237,46 @@ describe("verify()", function()
end)
end)

describe("#JIT", function()

local function read_trace(outfile)
local f = assert(io.open(outfile, "r"))
local t = f:read("*a")
f:close()
return t
end

it("hash_encoded() JITs", function()
local v = require "jit.v"
local outfile = os.tmpname()
v.on(outfile)

for _ = 1, 100 do
argon2.hash_encoded("password", "somesalt")
end

local trace = read_trace(outfile)
assert.matches("argon2_spec%.lua:%d+ loop", trace)
assert.not_matches("NYI", trace)
end)

it("verify() JITs", function()
local v = require "jit.v"
local outfile = os.tmpname()
v.on(outfile)

local hash = assert(argon2.hash_encoded("password", "somesalt"))

for _ = 1, 100 do
argon2.verify(hash, "password")
end

local trace = read_trace(outfile)
assert.matches("argon2_spec%.lua:%d+ loop", trace)
assert.not_matches("NYI", trace)
end)
end)

--[[
pending("module settings", function()
Expand Down
95 changes: 52 additions & 43 deletions src/argon2.lua
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
-- vim:set st=4 sw=4 et:
-- vim:set st=4 sw=4 sts=4 et:
local ffi = require "ffi"


local ffi_new = ffi.new
local ffi_str = ffi.string
local find = string.find
local error = error
local pairs = pairs
local type = type


local empty_t = {}


ffi.cdef [[
typedef enum Argon2_type {
Argon2_d = 0,
Expand Down Expand Up @@ -73,15 +75,6 @@ do
end


local OPTIONS = {
t_cost = 3,
m_cost = 4096,
parallelism = 1,
hash_len = 32,
variant = argon2_i,
}


local _M = {
_VERSION = "3.0.0",
_AUTHOR = "Thibault Charbonnier",
Expand All @@ -106,57 +99,73 @@ function _M.hash_encoded(pwd, salt, opts)
.. type(salt) .. ")", 2)
end

if opts and type(opts) ~= "table" then
if not opts then
opts = empty_t
end

if type(opts) ~= "table" then
return error("bad argument #3 to 'hash_encoded' (expected to be a "
.. "table)", 2)
end

if opts == nil then
opts = OPTIONS

else
for k, v in pairs(OPTIONS) do
local o = opts[k]
local t_cost = opts.t_cost or 3
local m_cost = opts.m_cost or 4096
local parallelism = opts.parallelism or 1
local hash_len = opts.hash_len or 32
local variant = opts.variant or argon2_i

if type(variant) ~= "cdata" then
return error("bad argument #3 to 'hash_encoded' (expected " ..
"variant to be an argon2_type, got " ..
type(opts.variant) .. ")", 2)
end

if o == nil then
opts[k] = v
if type(t_cost) ~= "number" then
return error("bad argument #3 to 'hash_encoded' (expected " ..
"t_cost to be a number, got " ..
type(t_cost) .. ")", 2)
end

elseif k == "variant" then
if type(o) ~= "cdata" then
return error("bad argument #3 to 'hash_encoded' (expected "
.. k .. " to be an argon2_type, got "
.. type(o) .. ")", 2)
end
if type(m_cost) ~= "number" then
return error("bad argument #3 to 'hash_encoded' (expected " ..
"m_cost to be a number, got " ..
type(m_cost) .. ")", 2)
end

if type(parallelism) ~= "number" then
return error("bad argument #3 to 'hash_encoded' (expected " ..
"parallelism to be a number, got " ..
type(parallelism) .. ")", 2)
end

elseif type(o) ~= "number" then
return error("bad argument #3 to 'hash_encoded' (expected "
.. k .. " to be a number, got "
.. type(o) .. ")", 2)
end
end
if type(hash_len) ~= "number" then
return error("bad argument #3 to 'hash_encoded' (expected " ..
"hash_len to be a number, got " ..
type(hash_len) .. ")", 2)
end

local buf_len = lib.argon2_encodedlen(opts.t_cost, opts.m_cost,
opts.parallelism, #salt,
opts.hash_len, opts.variant)
local buf_len = lib.argon2_encodedlen(t_cost, m_cost,
parallelism, #salt,
hash_len, variant)

local buf = ffi_new("char[?]", buf_len)
local ret_code

if opts.variant == argon2_d then
ret_code = lib.argon2d_hash_encoded(opts.t_cost, opts.m_cost,
opts.parallelism, pwd, #pwd, salt,
#salt, opts.hash_len, buf, buf_len)
ret_code = lib.argon2d_hash_encoded(t_cost, m_cost,
parallelism, pwd, #pwd, salt,
#salt, hash_len, buf, buf_len)

elseif opts.variant == argon2_id then
ret_code = lib.argon2id_hash_encoded(opts.t_cost, opts.m_cost,
opts.parallelism, pwd, #pwd, salt,
#salt, opts.hash_len, buf, buf_len)
ret_code = lib.argon2id_hash_encoded(t_cost, m_cost,
parallelism, pwd, #pwd, salt,
#salt, hash_len, buf, buf_len)

else
ret_code = lib.argon2i_hash_encoded(opts.t_cost, opts.m_cost,
opts.parallelism, pwd, #pwd, salt,
#salt, opts.hash_len, buf, buf_len)
ret_code = lib.argon2i_hash_encoded(t_cost, m_cost,
parallelism, pwd, #pwd, salt,
#salt, hash_len, buf, buf_len)
end

if ret_code ~= ARGON2_OK then
Expand Down

0 comments on commit ef1ef50

Please sign in to comment.