Skip to content

Commit 36ae3b8

Browse files
committed
test: SHA-256/KECCAK-256 hash functions
1 parent 44a88e7 commit 36ae3b8

File tree

4 files changed

+208
-5
lines changed

4 files changed

+208
-5
lines changed

tests/lua/cartesi/tests/util.lua

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,27 @@ local function adjust_path(path)
2525
return string.gsub(path or ".", "/*$", "") .. "/"
2626
end
2727

28+
-- Returns the directory absolute path at level `dirlevel` for the calling script at level `calllevel`.
29+
local function get_script_path(dirlevel, calllevel)
30+
local info = debug.getinfo(calllevel or 1, "S")
31+
local path = info and info.source and info.source:match("^@([^\n\r]+)")
32+
assert(path, "could not retrieve calling script path")
33+
path = require("posix.stdlib").realpath(path)
34+
if dirlevel and dirlevel > 0 then
35+
local segments = {}
36+
for segment in path:gmatch("[^/]+") do
37+
table.insert(segments, segment)
38+
end
39+
return "/" .. table.concat(segments, "/", 1, #segments - dirlevel)
40+
end
41+
return path
42+
end
43+
2844
local test_util = {
29-
images_path = adjust_path(assert(os.getenv("CARTESI_IMAGES_PATH"), "must set CARTESI_IMAGES_PATH")),
30-
tests_path = adjust_path(assert(os.getenv("CARTESI_TESTS_PATH"), "must set CARTESI_TESTS_PATH")),
31-
cmio_path = adjust_path(assert(os.getenv("CARTESI_CMIO_PATH"), "must set CARTESI_CMIO_PATH")),
32-
tests_uarch_path = adjust_path(assert(os.getenv("CARTESI_TESTS_UARCH_PATH"), "must set CARTESI_TESTS_UARCH_PATH")),
45+
images_path = adjust_path(os.getenv("CARTESI_IMAGES_PATH") or get_script_path(5) .. "/src"),
46+
tests_path = adjust_path(os.getenv("CARTESI_TESTS_PATH") or get_script_path(4) .. "/build/machine"),
47+
cmio_path = adjust_path(os.getenv("CARTESI_CMIO_PATH") or get_script_path(4) .. "/build/cmio"),
48+
tests_uarch_path = adjust_path(os.getenv("CARTESI_TESTS_UARCH_PATH") or get_script_path(4) .. "/build/uarch"),
3349
}
3450

3551
local function compute_zero_hash_table(hash_fn)

tests/lua/spec-hash-functions.lua

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
--[[
2+
Test suite for hash functions (SHA-256 and Keccak-256).
3+
Specifically, it provides test coverage for:
4+
sha-256-hasher.cpp
5+
keccak-256-hasher.cpp
6+
Can be run independently during development the mentioned files.
7+
]]
8+
9+
local lester = require("cartesi.third-party.lester")
10+
local util = require("cartesi.tests.util")
11+
local describe, it, expect = lester.describe, lester.it, lester.expect
12+
13+
describe("hash function", function()
14+
describe("keccak256", function()
15+
local keccak256 = require("cartesi").keccak256
16+
local function hexkeccak256(...)
17+
return util.tohex(keccak256(...)):lower()
18+
end
19+
20+
it("should fail when passing invalid arguments", function()
21+
expect.fail(function()
22+
keccak256("a", "b", "c")
23+
end, "too many arguments")
24+
expect.fail(function()
25+
keccak256(1, 2)
26+
end, "only supported for inputs with size of hash")
27+
expect.fail(function()
28+
keccak256()
29+
end, "too few arguments")
30+
end)
31+
32+
it("should match hashes", function()
33+
expect.equal(hexkeccak256(""), "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470")
34+
expect.equal(hexkeccak256("0"), "044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d")
35+
expect.equal(hexkeccak256("test"), "9c22ff5f21f0b81b113e63f7db6da94fedef11b2119b4088b89664fb9a3cb658")
36+
expect.equal(
37+
hexkeccak256(hexkeccak256("")),
38+
"79482f93ea0d714e293366322922962af38ecdd95cff648355c1af4b40a78b32"
39+
)
40+
end)
41+
42+
it("should match concat hashes", function()
43+
expect.equal(
44+
hexkeccak256(string.rep("\x00", 32), string.rep("\x00", 32)),
45+
hexkeccak256(string.rep("\x00", 64))
46+
)
47+
expect.equal(
48+
hexkeccak256(string.rep("a", 32), string.rep("b", 32)),
49+
hexkeccak256(string.rep("a", 32) .. string.rep("b", 32))
50+
)
51+
end)
52+
53+
it("should match with special lengths", function()
54+
local KECCAK_RSIZE = 136
55+
-- The data lengths are chosen to cover special cases of the KECCAK-256 algorithm
56+
for data, expected_hash in pairs({
57+
-- luacheck: push no max line length
58+
[string.rep("a", 0)] = "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470",
59+
[string.rep("a", 1)] = "3ac225168df54212a25c1c01fd35bebfea408fdac2e31ddd6f80a4bbf9a5f1cb",
60+
[string.rep("a", 2)] = "dfa57c542fea29ed292cef0ce135d0e22189365fa59abedc7a310b751ace684f",
61+
[string.rep("a", 4)] = "a80470dba00d5faf620fd6c51a1ca94668e13cd66fffaee3702f5497a8549053",
62+
[string.rep("a", 8)] = "a6eb2a81043a7349b2d066b3433ceadd8dd290343e6c41a4e36e82261e0b25cb",
63+
[string.rep("a", 16)] = "05bf23668a24407fc90dc33375cdeb2c8aef9db64ba12353dbc7e8d103dfba00",
64+
[string.rep("a", 32)] = "47a01324181e85459310f8fb9b24dc09744323ebdcef26cbf98959effdc76e02",
65+
[string.rep("a", 64)] = "1036d73cc8350b0635393d79759b10488165e792073f84d4462e22edec243b92",
66+
[string.rep("a", 128)] = "81555b8e18b3c117311c16373b1aa78c0a84aad7b8f7f4c753d0021fd9a6700e",
67+
[string.rep("a", KECCAK_RSIZE - 1)] = "34367dc248bbd832f4e3e69dfaac2f92638bd0bbd18f2912ba4ef454919cf446",
68+
[string.rep("a", KECCAK_RSIZE / 2)] = "e4b16954d021544d168b5ea23de13c97c762d1f331fe4c7470df3c1000a62fdb",
69+
[string.rep("a", KECCAK_RSIZE)] = "a6c4d403279fe3e0af03729caada8374b5ca54d8065329a3ebcaeb4b60aa386e",
70+
[string.rep("a", KECCAK_RSIZE + 1)] = "d869f639c7046b4929fc92a4d988a8b22c55fbadb802c0c66ebcd484f1915f39",
71+
[string.rep("a", KECCAK_RSIZE + (KECCAK_RSIZE / 2))] = "5f6404fdb4057bbd7bce17d97cc655fca0c1c4129a083d323d79136f768ae757",
72+
[string.rep("a", (KECCAK_RSIZE * 2) - 1)] = "132f47effd6c8b1b299efa53fe68aece77ec8ae4eb2e294f668eec94f76001e1",
73+
[string.rep("a", KECCAK_RSIZE * 2)] = "cf7fcd4f705ee749930d19ca84561a9bf62516bd90a471545fa2f49fdc7e63c8",
74+
[string.rep("a", (KECCAK_RSIZE * 2) + 1)] = "5a7b8187d2778e614097fac3097573de1fee4d972304d3360796a857029bb176",
75+
-- luacheck: pop
76+
}) do
77+
expect.equal(hexkeccak256(data), expected_hash)
78+
end
79+
end)
80+
end)
81+
82+
describe("sha256", function()
83+
local sha256 = require("cartesi").sha256
84+
local function hexsha256(...)
85+
return util.tohex(sha256(...)):lower()
86+
end
87+
88+
it("should fail when passing invalid arguments", function()
89+
expect.fail(function()
90+
sha256("a", "b", "c")
91+
end, "too many arguments")
92+
expect.fail(function()
93+
sha256(1, 2)
94+
end, "only supported for inputs with size of hash")
95+
expect.fail(function()
96+
sha256()
97+
end, "too few arguments")
98+
end)
99+
100+
it("should match hashes", function()
101+
expect.equal(hexsha256(""), "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
102+
expect.equal(hexsha256("0"), "5feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9")
103+
expect.equal(hexsha256("test"), "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08")
104+
expect.equal(hexsha256(hexsha256("")), "cd372fb85148700fa88095e3492d3f9f5beb43e555e5ff26d95f5a6adc36f8e6")
105+
end)
106+
107+
it("should match concat hashes", function()
108+
expect.equal(hexsha256(string.rep("\x00", 32), string.rep("\x00", 32)), hexsha256(string.rep("\x00", 64)))
109+
expect.equal(
110+
hexsha256(string.rep("a", 32), string.rep("b", 32)),
111+
hexsha256(string.rep("a", 32) .. string.rep("b", 32))
112+
)
113+
end)
114+
115+
it("should match hashes with special lengths", function()
116+
local SHA256_LEN_POS = 56
117+
local SHA256_BUF_SIZE = 64
118+
-- The data lengths are chosen to cover special cases of the SHA-256 algorithm
119+
for data, expected_hash in pairs({
120+
-- luacheck: push no max line length
121+
[string.rep("a", 0)] = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
122+
[string.rep("a", 1)] = "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb",
123+
[string.rep("a", 2)] = "961b6dd3ede3cb8ecbaacbd68de040cd78eb2ed5889130cceb4c49268ea4d506",
124+
[string.rep("a", 4)] = "61be55a8e2f6b4e172338bddf184d6dbee29c98853e0a0485ecee7f27b9af0b4",
125+
[string.rep("a", 8)] = "1f3ce40415a2081fa3eee75fc39fff8e56c22270d1a978a7249b592dcebd20b4",
126+
[string.rep("a", 16)] = "0c0beacef8877bbf2416eb00f2b5dc96354e26dd1df5517320459b1236860f8c",
127+
[string.rep("a", 32)] = "3ba3f5f43b92602683c19aee62a20342b084dd5971ddd33808d81a328879a547",
128+
[string.rep("a", 64)] = "ffe054fe7ae0cb6dc65c3af9b61d5209f439851db43d0ba5997337df154668eb",
129+
[string.rep("a", 128)] = "6836cf13bac400e9105071cd6af47084dfacad4e5e302c94bfed24e013afb73e",
130+
[string.rep("a", SHA256_LEN_POS - 1)] = "9f4390f8d30c2dd92ec9f095b65e2b9ae9b0a925a5258e241c9f1e910f734318",
131+
[string.rep("a", SHA256_LEN_POS / 2)] = "9c547cb8115a44883b9f70ba68f75117cd55359c92611875e386f8af98c172ab",
132+
[string.rep("a", SHA256_LEN_POS)] = "b35439a4ac6f0948b6d6f9e3c6af0f5f590ce20f1bde7090ef7970686ec6738a",
133+
[string.rep("a", SHA256_LEN_POS + 1)] = "f13b2d724659eb3bf47f2dd6af1accc87b81f09f59f2b75e5c0bed6589dfe8c6",
134+
[string.rep("a", SHA256_LEN_POS + (SHA256_LEN_POS // 2))] = "f5475022feb69870295b9c1e78c5a4919374061d5345167815801879f931ebb0",
135+
[string.rep("a", (SHA256_LEN_POS * 2) - 1)] = "6374f73208854473827f6f6a3f43b1f53eaa3b82c21c1a6d69a2110b2a79baad",
136+
[string.rep("a", SHA256_LEN_POS * 2)] = "f54353008a2553262ecdc4a34749563ba0950e8b0fc8652780b0a614b99683c1",
137+
[string.rep("a", (SHA256_LEN_POS * 2) + 1)] = "ba02731ae695aae5cd49b49d84330b63995733eb22102aca755f0179b1e0e20f",
138+
[string.rep("a", SHA256_BUF_SIZE - 1)] = "7d3e74a05d7db15bce4ad9ec0658ea98e3f06eeecf16b4c6fff2da457ddc2f34",
139+
[string.rep("a", SHA256_BUF_SIZE + 1)] = "635361c48bb9eab14198e76ea8ab7f1a41685d6ad62aa9146d301d4f17eb0ae0",
140+
[string.rep("a", SHA256_BUF_SIZE + (SHA256_BUF_SIZE // 2))] = "ee4caa5518a866f33e174d6e71ba3961a86ca00a7486b132e5a9f01bfaa1d794",
141+
[string.rep("a", (SHA256_BUF_SIZE * 2) - 1)] = "c57e9278af78fa3cab38667bef4ce29d783787a2f731d4e12200270f0c32320a",
142+
[string.rep("a", (SHA256_BUF_SIZE * 2) + 1)] = "c12cb024a2e5551cca0e08fce8f1c5e314555cc3fef6329ee994a3db752166ae",
143+
-- luacheck: pop
144+
}) do
145+
expect.equal(hexsha256(data), expected_hash)
146+
end
147+
end)
148+
end)
149+
end)

tests/lua/test-spec.lua

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/usr/bin/env lua5.4
2+
3+
-- Copyright 2023 Cartesi Pte. Ltd.
4+
--
5+
-- This file is part of the machine-emulator. The machine-emulator is free
6+
-- software: you can redistribute it and/or modify it under the terms of the GNU
7+
-- Lesser General Public License as published by the Free Software Foundation,
8+
-- either version 3 of the License, or (at your option) any later version.
9+
--
10+
-- The machine-emulator is distributed in the hope that it will be useful, but
11+
-- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12+
-- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
13+
-- for more details.
14+
--
15+
-- You should have received a copy of the GNU Lesser General Public License
16+
-- along with the machine-emulator. If not, see http://www.gnu.org/licenses/.
17+
--
18+
19+
local lester = require("cartesi.third-party.lester")
20+
21+
-- Parse arguments from command line.
22+
lester.parse_args()
23+
24+
require("spec-hash-functions")
25+
26+
lester.report() -- Print overall statistic of the tests run.
27+
lester.exit() -- Exit with success if all tests passed.

tests/scripts/run-lua-tests.sh

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,19 @@ SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
2222

2323
LUA=${1:-lua5.4}
2424

25-
TEST_LIST=(htif-console.lua htif-cmio.lua htif-yield.lua log-with-mtime-transition.lua machine-bind.lua machine-test.lua mcycle-overflow.lua mtime-interrupt.lua)
25+
TEST_LIST=(
26+
htif-console.lua
27+
htif-cmio.lua
28+
htif-yield.lua
29+
log-with-mtime-transition.lua
30+
machine-bind.lua
31+
machine-test.lua
32+
mcycle-overflow.lua
33+
mtime-interrupt.lua
34+
test-spec.lua
35+
)
2636

37+
cd $SCRIPT_DIR/../lua
2738
for x in ${TEST_LIST[@]}; do
2839
echo "Running $x"
2940
echo -n 'CTSICTSI' | (bash -c "${LUA} $SCRIPT_DIR/../lua/$x local") || exit 1;

0 commit comments

Comments
 (0)