1 | #include <cstdint> |
---|
2 | #include <cstdio> |
---|
3 | #include <cstring> |
---|
4 | #include <ctime> |
---|
5 | #include <fstream> |
---|
6 | #include <utility> |
---|
7 | #include "resource.h" |
---|
8 | #include "types.h" |
---|
9 | #include "hash.h" |
---|
10 | |
---|
11 | using namespace std; |
---|
12 | |
---|
13 | uint64_t lpsbox[8][0x100]; |
---|
14 | |
---|
15 | void hash_nm::precalc_mul_table() { |
---|
16 | for (int i = 0; i < 8; ++i) { |
---|
17 | for (int j = 0; j < 0x100; ++j){ |
---|
18 | uint64_t t = 0; |
---|
19 | uint8_t p = sbox[j]; |
---|
20 | for (int k = 0; k < 8; ++k) |
---|
21 | if (p &(1 << k)) |
---|
22 | t ^= lbox[0x3f - ((i << 3) | k)]; |
---|
23 | lpsbox[i][j] = t; |
---|
24 | } |
---|
25 | } |
---|
26 | } |
---|
27 | void lps(block512_t &in) { |
---|
28 | block512_t res; |
---|
29 | for (int i = 0; i < 8; ++i){ |
---|
30 | uint64_t t = lpsbox[0][in.x8[i]]; |
---|
31 | for (int k = 1; k < 8; ++k) |
---|
32 | t ^= lpsbox[k][in.x8[i + k * 8]]; |
---|
33 | res.x64[i] = t; |
---|
34 | } |
---|
35 | in = res; |
---|
36 | } |
---|
37 | |
---|
38 | void add512(block512_t &a, const block512_t &b) { |
---|
39 | uint32_t tmp = 0; |
---|
40 | for (int i = 0; i < 64; ++i) { |
---|
41 | tmp = a.x8[i] + b.x8[i] + (tmp >> 8); |
---|
42 | a.x8[i] = tmp & 0xFF; |
---|
43 | } |
---|
44 | } |
---|
45 | inline void x(block512_t &a, const block512_t &b) { |
---|
46 | a.x64[0] ^= b.x64[0]; a.x64[1] ^= b.x64[1]; a.x64[2] ^= b.x64[2]; a.x64[3] ^= b.x64[3]; |
---|
47 | a.x64[4] ^= b.x64[4]; a.x64[5] ^= b.x64[5]; a.x64[6] ^= b.x64[6]; a.x64[7] ^= b.x64[7]; |
---|
48 | } |
---|
49 | void g(const block512_t &n, block512_t &h, const block512_t &m) { |
---|
50 | block512_t res = h; |
---|
51 | x(res, n); |
---|
52 | lps(res); |
---|
53 | block512_t k = res; |
---|
54 | x(res, m); |
---|
55 | for (int i = 0; i < 12; ++i) { |
---|
56 | lps(res); |
---|
57 | x(k, c[i]); |
---|
58 | lps(k); |
---|
59 | x(res, k); |
---|
60 | } |
---|
61 | x(h, res); |
---|
62 | x(h, m); |
---|
63 | } |
---|
64 | block512_t hash_nm::hash(char *buf, size_t size, hash_mode_t mode) { |
---|
65 | block512_t m, h(mode == hm256), n(0), s(0); |
---|
66 | for (int64_t i = size - 64; i > -1; i -= 64) { |
---|
67 | memcpy(&m, buf + i, sizeof(m)); |
---|
68 | g(n, h, m); |
---|
69 | add512(n, value512); |
---|
70 | add512(s, m); |
---|
71 | } |
---|
72 | memset(m.x8, 0, sizeof(m)); |
---|
73 | memcpy(m.x8, buf + size, size % 64); |
---|
74 | m.x8[size % 64] = 1; |
---|
75 | g(n, h, m); |
---|
76 | add512(s, m); |
---|
77 | memset(m.x8, 0, sizeof(m)); |
---|
78 | m.x64[0] = 8 * (size % 64); |
---|
79 | add512(n, m); |
---|
80 | m.x64[0] = 0; |
---|
81 | g(m, h, n); |
---|
82 | g(m, h, s); |
---|
83 | return h; |
---|
84 | } |
---|