diff --git a/CMakeLists.txt b/CMakeLists.txt index 03b8369..9534ce5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,8 +6,13 @@ set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 -Wall -Wdeprecated") set(CMAKE_D_FLAGS_DEBUG "${CMAKE_D_FLAGS_DEBUG} -funittest -g -O0 -Wall -Wdeprecated") set(CMAKE_D_FLAGS_RELEASE "${CMAKE_D_FLAGS_RELEASE} -O3 -Wall -Wdeprecated") +include_directories( + . +) + add_executable(${PROJECT_NAME} sboxes.c tiger.c main.d + tiger.d ) diff --git a/main.d b/main.d index e0a81c1..c7fd54a 100644 --- a/main.d +++ b/main.d @@ -1,92 +1,6 @@ import std.stdio; -import std.string; -import std.array, std.range; import std.file; -import std.algorithm; - -extern(C) void tiger (char* parMessage, ulong parLength, out ulong[3] parOut, char parPadding); -extern(C) void tiger_init (out ulong[3] parOut); -extern(C) void tiger_chunk (char* parMessage, ulong parLength, out ulong[3] parOut); -extern(C) void tiger_last_chunk (char* parMessage, ulong parBuffLength, ulong parTotalLength, out ulong[3] parOut, char parPadding); - -ulong swapLong (ulong parNum) { - parNum = (parNum & 0x00000000FFFFFFFF) << 32 | (parNum & 0xFFFFFFFF00000000) >> 32; - parNum = (parNum & 0x0000FFFF0000FFFF) << 16 | (parNum & 0xFFFF0000FFFF0000) >> 16; - parNum = (parNum & 0x00FF00FF00FF00FF) << 8 | (parNum & 0xFF00FF00FF00FF00) >> 8; - return parNum; -} - -ulong[3] getTiger (in string parData, bool parV2) { - char[] unaligned = new char[parData.length + ulong.alignof - 1]; - size_t offset = ((cast(size_t)unaligned.ptr + (ulong.alignof - 1)) & ~cast(size_t)(ulong.alignof - 1)) - cast(size_t)unaligned.ptr; - assert(offset >= 0 && offset < ulong.alignof); - assert(offset + parData.length <= unaligned.length); - - char padding = (parV2 ? 0x80 : 0x01); - char[] aligned = unaligned[offset .. offset + parData.length]; - aligned[] = parData[]; - assert((cast(size_t)aligned.ptr & cast(size_t)(ulong.alignof - 1)) == 0); - ulong[3] retval; - tiger(aligned.ptr, aligned.length, retval, padding); - return retval; -} - -ulong[3] getTiger (ref File parData, bool parV2) { - const auto buff_length = 64 * 128; - char[] unaligned = new char[buff_length + ulong.alignof - 1]; - size_t offset = ((cast(size_t)unaligned.ptr + (ulong.alignof - 1)) & ~cast(size_t)(ulong.alignof - 1)) - cast(size_t)unaligned.ptr; - assert(offset >= 0 && offset < ulong.alignof); - - assert(offset + buff_length <= unaligned.length); - char[] aligned = unaligned[offset .. buff_length]; - assert(aligned.length == buff_length); - - ulong[3] retval; - auto data_left = parData.size; - tiger_init(retval); - while (data_left >= buff_length) { - parData.rawRead(aligned); - tiger_chunk(aligned.ptr, buff_length, retval); - data_left -= buff_length; - } - - const char padding = (parV2 ? 0x80 : 0x01); - if (data_left) { - parData.rawRead(aligned[0 .. data_left]); - const ulong proc_length = data_left & ~0x3fUL; - tiger_chunk(aligned.ptr, proc_length, retval); - tiger_last_chunk(aligned.ptr + proc_length, data_left - proc_length, parData.size, retval, padding); - } - else { - tiger_last_chunk(null, 0, parData.size, retval, padding); - } - - return retval; -} - -string tigerToString (in ulong[3] parTiger) { - return format("%016x%016x%016x", swapLong(parTiger[0]), swapLong(parTiger[1]), swapLong(parTiger[2])); -} - -unittest { - assert("67e6ae8e9e968999f70a23e72aeaa9251cbc7c78a7916636" == tigerToString(getTiger("a", true))); - assert("f68d7bc5af4b43a06e048d7829560d4a9415658bb0b1f3bf" == tigerToString(getTiger("abc", true))); - assert("e29419a1b5fa259de8005e7de75078ea81a542ef2552462d" == tigerToString(getTiger("message digest", true))); - assert("f5b6b6a78c405c8547e91cd8624cb8be83fc804a474488fd" == tigerToString(getTiger("abcdefghijklmnopqrstuvwxyz", true))); - assert("a6737f3997e8fbb63d20d2df88f86376b5fe2d5ce36646a9" == tigerToString(getTiger("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", true))); - assert("ea9ab6228cee7b51b77544fca6066c8cbb5bbae6319505cd" == tigerToString(getTiger("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", true))); - assert("d85278115329ebaa0eec85ecdc5396fda8aa3a5820942fff" == tigerToString(getTiger(replicate("1234567890", 8), true))); - assert("e068281f060f551628cc5715b9d0226796914d45f7717cf4" == tigerToString(getTiger(replicate("a", 1000000), true))); - - assert("2aab1484e8c158f2bfb8c5ff41b57a525129131c957b5f93" == tigerToString(getTiger("abc", false))); - assert("dd00230799f5009fec6debc838bb6a27df2b9d6f110c7937" == tigerToString(getTiger("Tiger", false))); - assert("f71c8583902afb879edfe610f82c0d4786a3a534504486b5" == tigerToString(getTiger("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-", false))); - assert("48ceeb6308b87d46e95d656112cdf18d97915f9765658957" == tigerToString(getTiger("ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789", false))); - assert("8a866829040a410c729ad23f5ada711603b3cdd357e4c15e" == tigerToString(getTiger("Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham", false))); - assert("ce55a6afd591f5ebac547ff84f89227f9331dab0b611c889" == tigerToString(getTiger("Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge.", false))); - assert("631abdd103eb9a3d245b6dfd4d77b257fc7439501d1568dd" == tigerToString(getTiger("Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge, 1996.", false))); - assert("c54034e5b43eb8005848a7e0ae6aac76e4ff590ae715fd25" == tigerToString(getTiger("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-", false))); -} +import tiger; void main (string[] parArgs) { const auto cwd = getcwd(); diff --git a/tiger.d b/tiger.d new file mode 100644 index 0000000..5ffc1c3 --- /dev/null +++ b/tiger.d @@ -0,0 +1,88 @@ +import std.stdio; +import std.string; +import std.array, std.range; +import std.algorithm; + +private extern(C) void tiger (char* parMessage, ulong parLength, out ulong[3] parOut, char parPadding); +private extern(C) void tiger_init (out ulong[3] parOut); +private extern(C) void tiger_chunk (char* parMessage, ulong parLength, out ulong[3] parOut); +private extern(C) void tiger_last_chunk (char* parMessage, ulong parBuffLength, ulong parTotalLength, out ulong[3] parOut, char parPadding); + +private ulong swapLong (ulong parNum) { + parNum = (parNum & 0x00000000FFFFFFFF) << 32 | (parNum & 0xFFFFFFFF00000000) >> 32; + parNum = (parNum & 0x0000FFFF0000FFFF) << 16 | (parNum & 0xFFFF0000FFFF0000) >> 16; + parNum = (parNum & 0x00FF00FF00FF00FF) << 8 | (parNum & 0xFF00FF00FF00FF00) >> 8; + return parNum; +} + +public ulong[3] getTiger (in string parData, bool parV2) { + char[] unaligned = new char[parData.length + ulong.alignof - 1]; + size_t offset = ((cast(size_t)unaligned.ptr + (ulong.alignof - 1)) & ~cast(size_t)(ulong.alignof - 1)) - cast(size_t)unaligned.ptr; + assert(offset >= 0 && offset < ulong.alignof); + assert(offset + parData.length <= unaligned.length); + + char padding = (parV2 ? 0x80 : 0x01); + char[] aligned = unaligned[offset .. offset + parData.length]; + aligned[] = parData[]; + assert((cast(size_t)aligned.ptr & cast(size_t)(ulong.alignof - 1)) == 0); + ulong[3] retval; + tiger(aligned.ptr, aligned.length, retval, padding); + return retval; +} + +public ulong[3] getTiger (ref File parData, bool parV2) { + const auto buff_length = 64 * 128; + char[] unaligned = new char[buff_length + ulong.alignof - 1]; + size_t offset = ((cast(size_t)unaligned.ptr + (ulong.alignof - 1)) & ~cast(size_t)(ulong.alignof - 1)) - cast(size_t)unaligned.ptr; + assert(offset >= 0 && offset < ulong.alignof); + + assert(offset + buff_length <= unaligned.length); + char[] aligned = unaligned[offset .. buff_length]; + assert(aligned.length == buff_length); + + ulong[3] retval; + auto data_left = parData.size; + tiger_init(retval); + while (data_left >= buff_length) { + parData.rawRead(aligned); + tiger_chunk(aligned.ptr, buff_length, retval); + data_left -= buff_length; + } + + const char padding = (parV2 ? 0x80 : 0x01); + if (data_left) { + parData.rawRead(aligned[0 .. data_left]); + const ulong proc_length = data_left & ~0x3fUL; + tiger_chunk(aligned.ptr, proc_length, retval); + tiger_last_chunk(aligned.ptr + proc_length, data_left - proc_length, parData.size, retval, padding); + } + else { + tiger_last_chunk(null, 0, parData.size, retval, padding); + } + + return retval; +} + +public string tigerToString (in ulong[3] parTiger) { + return format("%016x%016x%016x", swapLong(parTiger[0]), swapLong(parTiger[1]), swapLong(parTiger[2])); +} + +unittest { + assert("67e6ae8e9e968999f70a23e72aeaa9251cbc7c78a7916636" == tigerToString(getTiger("a", true))); + assert("f68d7bc5af4b43a06e048d7829560d4a9415658bb0b1f3bf" == tigerToString(getTiger("abc", true))); + assert("e29419a1b5fa259de8005e7de75078ea81a542ef2552462d" == tigerToString(getTiger("message digest", true))); + assert("f5b6b6a78c405c8547e91cd8624cb8be83fc804a474488fd" == tigerToString(getTiger("abcdefghijklmnopqrstuvwxyz", true))); + assert("a6737f3997e8fbb63d20d2df88f86376b5fe2d5ce36646a9" == tigerToString(getTiger("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", true))); + assert("ea9ab6228cee7b51b77544fca6066c8cbb5bbae6319505cd" == tigerToString(getTiger("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", true))); + assert("d85278115329ebaa0eec85ecdc5396fda8aa3a5820942fff" == tigerToString(getTiger(replicate("1234567890", 8), true))); + assert("e068281f060f551628cc5715b9d0226796914d45f7717cf4" == tigerToString(getTiger(replicate("a", 1000000), true))); + + assert("2aab1484e8c158f2bfb8c5ff41b57a525129131c957b5f93" == tigerToString(getTiger("abc", false))); + assert("dd00230799f5009fec6debc838bb6a27df2b9d6f110c7937" == tigerToString(getTiger("Tiger", false))); + assert("f71c8583902afb879edfe610f82c0d4786a3a534504486b5" == tigerToString(getTiger("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-", false))); + assert("48ceeb6308b87d46e95d656112cdf18d97915f9765658957" == tigerToString(getTiger("ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789", false))); + assert("8a866829040a410c729ad23f5ada711603b3cdd357e4c15e" == tigerToString(getTiger("Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham", false))); + assert("ce55a6afd591f5ebac547ff84f89227f9331dab0b611c889" == tigerToString(getTiger("Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge.", false))); + assert("631abdd103eb9a3d245b6dfd4d77b257fc7439501d1568dd" == tigerToString(getTiger("Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge, 1996.", false))); + assert("c54034e5b43eb8005848a7e0ae6aac76e4ff590ae715fd25" == tigerToString(getTiger("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-", false))); +}