login

local lud = require "ludweb"

local hex = lud.crypt.hex

local Suite = {}

local b64_cases = {
    -- generated by coreutils' `base64` command
    {"Lorem Ipsum", "TG9yZW0gSXBzdW0="},
    {"dolor sit", "ZG9sb3Igc2l0"},
    {"amet", "YW1ldA=="},
}

function Suite.b64_enc()
    for i, case in ipairs(b64_cases) do
        local msg = "failed for '"..case[1].."'"
        assert(lud.crypt.b64_enc(case[1]) == case[2], msg)
    end
end

function Suite.b64_dec()
    for i, case in ipairs(b64_cases) do
        local msg = "failed for '"..case[1].."'"
        assert(lud.crypt.b64_dec(case[2]) == case[1], msg)
    end
end

function Suite.urandom()
    for i = 1, 32 do
        assert(#lud.crypt.urandom(i) == i)
    end
end

function Suite.uuid4()
    local ids = {}
    local n = 32
    for i = 1, n do
        local id = lud.crypt.uuid4()
        assert(#id == 16, "UUID has bad length: "..#id)
        ids[id] = true
    end
    local j = 0
    for id in pairs(ids) do
        j = j + 1
    end
    assert(j == n, "UUIDs not unique")
end

-- $ printf "Lorem Ipsum" | awk '{for(i=1; i<=256; i++) print $0}'
local big_str = ("Lorem Ipsum\n"):rep(256)

function Suite.sha256()
    local cases = {
        -- generated by coreutils' `sha256sum` command
        {"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", ""},
        {"16aba5393ad72c0041f5600ad3c2c52ec437a2f0c7fc08fadfc3c0fe9641d7a3", "Lorem ipsum dolor sit amet"},
        {"181eb9ac4d4d08b00a64d636ab7a6174c3781c32b3b3a32b8783e9dda7be3455", big_str},
    }
    for i, case in ipairs(cases) do
        assert(hex(lud.crypt.sha256(case[2])) == case[1], "failed for case "..i)
    end
end

function Suite.hmac()
    local cases = {
        -- generated by coreutils' `hmac256` command
        {"bce68cb87da59c708eaff17571c501dee1c4aeed50d9552f0b8644286317bcc9", "test123", ""},
        {"dce75555c455f477dd2f54d08c78277b3f3c12ba7f69d78b0222eb7b85438e89", "foo", "Lorem Ipsum"},
        {"5dcbecdb10bb78da2ca11fe6849578e1d4a23bdcf23a71b8fd7a18f5d968a922", "kind-of-a-long-key-for-hmac", big_str},
    }
    for i, case in ipairs(cases) do
        assert(hex(lud.crypt.hmac(case[2], case[3])) == case[1], "failed for case "..i)
    end
end

function Suite.pbkdf2()
    -- test vector from RFC 7914, section 11
    local cases = {
        {"passwd", "salt", 1, 64, [[
            55 ac 04 6e 56 e3 08 9f ec 16 91 c2 25 44 b6 05
            f9 41 85 21 6d de 04 65 e6 8b 9d 57 c2 0d ac bc
            49 ca 9c cc f1 79 b6 45 99 16 64 b3 9d 77 ef 31
            7c 71 b8 45 b1 e3 0b d5 09 11 20 41 d3 a1 97 83
        ]]},
        -- the following takes a few seconds; comment it out for quick test
        {"Password", "NaCl", 80000, 64, [[
            4d dc d8 f6 0b 98 be 21 83 0c ee 5e f2 27 01 f9
            64 1a 44 18 d0 4c 04 14 ae ff 08 87 6b 34 ab 56
            a1 d4 25 a1 22 58 33 54 9a db 84 1b 51 c9 b3 17
            6a 27 2b de bb a1 d0 78 47 8f 62 b3 97 f3 3c 8d
        ]]},
    }
    for i, case in ipairs(cases) do
        local pw, salt, c, dklen, hash = unpack(case)
        hash = hash:gsub("%s", "")
        local my_hash = hex(lud.crypt.pbkdf2(pw, salt, c, dklen))
        assert(my_hash == hash)
    end
end

return Suite