/src/botan/src/lib/hash/whirlpool/whirlpool.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Whirlpool |
3 | | * (C) 1999-2007 Jack Lloyd |
4 | | * |
5 | | * Botan is released under the Simplified BSD License (see license.txt) |
6 | | */ |
7 | | |
8 | | #include <botan/whrlpool.h> |
9 | | #include <botan/loadstor.h> |
10 | | |
11 | | namespace Botan { |
12 | | |
13 | | std::unique_ptr<HashFunction> Whirlpool::copy_state() const |
14 | 0 | { |
15 | 0 | return std::unique_ptr<HashFunction>(new Whirlpool(*this)); |
16 | 0 | } |
17 | | |
18 | | /* |
19 | | * Whirlpool Compression Function |
20 | | */ |
21 | | void Whirlpool::compress_n(const uint8_t in[], size_t blocks) |
22 | 0 | { |
23 | 0 | static const uint64_t RC[10] = { |
24 | 0 | 0x1823C6E887B8014F, 0x36A6D2F5796F9152, |
25 | 0 | 0x60BC9B8EA30C7B35, 0x1DE0D7C22E4BFE57, |
26 | 0 | 0x157737E59FF04ADA, 0x58C9290AB1A06B85, |
27 | 0 | 0xBD5D10F4CB3E0567, 0xE427418BA77D95D8, |
28 | 0 | 0xFBEE7C66DD17479E, 0xCA2DBF07AD5A8333 |
29 | 0 | }; |
30 | 0 |
|
31 | 0 | for(size_t i = 0; i != blocks; ++i) |
32 | 0 | { |
33 | 0 | load_be(m_M.data(), in, m_M.size()); |
34 | 0 |
|
35 | 0 | uint64_t K0, K1, K2, K3, K4, K5, K6, K7; |
36 | 0 | K0 = m_digest[0]; K1 = m_digest[1]; K2 = m_digest[2]; K3 = m_digest[3]; |
37 | 0 | K4 = m_digest[4]; K5 = m_digest[5]; K6 = m_digest[6]; K7 = m_digest[7]; |
38 | 0 |
|
39 | 0 | uint64_t B0, B1, B2, B3, B4, B5, B6, B7; |
40 | 0 | B0 = K0 ^ m_M[0]; B1 = K1 ^ m_M[1]; B2 = K2 ^ m_M[2]; B3 = K3 ^ m_M[3]; |
41 | 0 | B4 = K4 ^ m_M[4]; B5 = K5 ^ m_M[5]; B6 = K6 ^ m_M[6]; B7 = K7 ^ m_M[7]; |
42 | 0 |
|
43 | 0 | for(size_t j = 0; j != 10; ++j) |
44 | 0 | { |
45 | 0 | uint64_t T0, T1, T2, T3, T4, T5, T6, T7; |
46 | 0 | T0 = C0[get_byte(0, K0)] ^ C1[get_byte(1, K7)] ^ |
47 | 0 | C2[get_byte(2, K6)] ^ C3[get_byte(3, K5)] ^ |
48 | 0 | C4[get_byte(4, K4)] ^ C5[get_byte(5, K3)] ^ |
49 | 0 | C6[get_byte(6, K2)] ^ C7[get_byte(7, K1)] ^ RC[j]; |
50 | 0 | T1 = C0[get_byte(0, K1)] ^ C1[get_byte(1, K0)] ^ |
51 | 0 | C2[get_byte(2, K7)] ^ C3[get_byte(3, K6)] ^ |
52 | 0 | C4[get_byte(4, K5)] ^ C5[get_byte(5, K4)] ^ |
53 | 0 | C6[get_byte(6, K3)] ^ C7[get_byte(7, K2)]; |
54 | 0 | T2 = C0[get_byte(0, K2)] ^ C1[get_byte(1, K1)] ^ |
55 | 0 | C2[get_byte(2, K0)] ^ C3[get_byte(3, K7)] ^ |
56 | 0 | C4[get_byte(4, K6)] ^ C5[get_byte(5, K5)] ^ |
57 | 0 | C6[get_byte(6, K4)] ^ C7[get_byte(7, K3)]; |
58 | 0 | T3 = C0[get_byte(0, K3)] ^ C1[get_byte(1, K2)] ^ |
59 | 0 | C2[get_byte(2, K1)] ^ C3[get_byte(3, K0)] ^ |
60 | 0 | C4[get_byte(4, K7)] ^ C5[get_byte(5, K6)] ^ |
61 | 0 | C6[get_byte(6, K5)] ^ C7[get_byte(7, K4)]; |
62 | 0 | T4 = C0[get_byte(0, K4)] ^ C1[get_byte(1, K3)] ^ |
63 | 0 | C2[get_byte(2, K2)] ^ C3[get_byte(3, K1)] ^ |
64 | 0 | C4[get_byte(4, K0)] ^ C5[get_byte(5, K7)] ^ |
65 | 0 | C6[get_byte(6, K6)] ^ C7[get_byte(7, K5)]; |
66 | 0 | T5 = C0[get_byte(0, K5)] ^ C1[get_byte(1, K4)] ^ |
67 | 0 | C2[get_byte(2, K3)] ^ C3[get_byte(3, K2)] ^ |
68 | 0 | C4[get_byte(4, K1)] ^ C5[get_byte(5, K0)] ^ |
69 | 0 | C6[get_byte(6, K7)] ^ C7[get_byte(7, K6)]; |
70 | 0 | T6 = C0[get_byte(0, K6)] ^ C1[get_byte(1, K5)] ^ |
71 | 0 | C2[get_byte(2, K4)] ^ C3[get_byte(3, K3)] ^ |
72 | 0 | C4[get_byte(4, K2)] ^ C5[get_byte(5, K1)] ^ |
73 | 0 | C6[get_byte(6, K0)] ^ C7[get_byte(7, K7)]; |
74 | 0 | T7 = C0[get_byte(0, K7)] ^ C1[get_byte(1, K6)] ^ |
75 | 0 | C2[get_byte(2, K5)] ^ C3[get_byte(3, K4)] ^ |
76 | 0 | C4[get_byte(4, K3)] ^ C5[get_byte(5, K2)] ^ |
77 | 0 | C6[get_byte(6, K1)] ^ C7[get_byte(7, K0)]; |
78 | 0 |
|
79 | 0 | K0 = T0; K1 = T1; K2 = T2; K3 = T3; |
80 | 0 | K4 = T4; K5 = T5; K6 = T6; K7 = T7; |
81 | 0 |
|
82 | 0 | T0 = C0[get_byte(0, B0)] ^ C1[get_byte(1, B7)] ^ |
83 | 0 | C2[get_byte(2, B6)] ^ C3[get_byte(3, B5)] ^ |
84 | 0 | C4[get_byte(4, B4)] ^ C5[get_byte(5, B3)] ^ |
85 | 0 | C6[get_byte(6, B2)] ^ C7[get_byte(7, B1)] ^ K0; |
86 | 0 | T1 = C0[get_byte(0, B1)] ^ C1[get_byte(1, B0)] ^ |
87 | 0 | C2[get_byte(2, B7)] ^ C3[get_byte(3, B6)] ^ |
88 | 0 | C4[get_byte(4, B5)] ^ C5[get_byte(5, B4)] ^ |
89 | 0 | C6[get_byte(6, B3)] ^ C7[get_byte(7, B2)] ^ K1; |
90 | 0 | T2 = C0[get_byte(0, B2)] ^ C1[get_byte(1, B1)] ^ |
91 | 0 | C2[get_byte(2, B0)] ^ C3[get_byte(3, B7)] ^ |
92 | 0 | C4[get_byte(4, B6)] ^ C5[get_byte(5, B5)] ^ |
93 | 0 | C6[get_byte(6, B4)] ^ C7[get_byte(7, B3)] ^ K2; |
94 | 0 | T3 = C0[get_byte(0, B3)] ^ C1[get_byte(1, B2)] ^ |
95 | 0 | C2[get_byte(2, B1)] ^ C3[get_byte(3, B0)] ^ |
96 | 0 | C4[get_byte(4, B7)] ^ C5[get_byte(5, B6)] ^ |
97 | 0 | C6[get_byte(6, B5)] ^ C7[get_byte(7, B4)] ^ K3; |
98 | 0 | T4 = C0[get_byte(0, B4)] ^ C1[get_byte(1, B3)] ^ |
99 | 0 | C2[get_byte(2, B2)] ^ C3[get_byte(3, B1)] ^ |
100 | 0 | C4[get_byte(4, B0)] ^ C5[get_byte(5, B7)] ^ |
101 | 0 | C6[get_byte(6, B6)] ^ C7[get_byte(7, B5)] ^ K4; |
102 | 0 | T5 = C0[get_byte(0, B5)] ^ C1[get_byte(1, B4)] ^ |
103 | 0 | C2[get_byte(2, B3)] ^ C3[get_byte(3, B2)] ^ |
104 | 0 | C4[get_byte(4, B1)] ^ C5[get_byte(5, B0)] ^ |
105 | 0 | C6[get_byte(6, B7)] ^ C7[get_byte(7, B6)] ^ K5; |
106 | 0 | T6 = C0[get_byte(0, B6)] ^ C1[get_byte(1, B5)] ^ |
107 | 0 | C2[get_byte(2, B4)] ^ C3[get_byte(3, B3)] ^ |
108 | 0 | C4[get_byte(4, B2)] ^ C5[get_byte(5, B1)] ^ |
109 | 0 | C6[get_byte(6, B0)] ^ C7[get_byte(7, B7)] ^ K6; |
110 | 0 | T7 = C0[get_byte(0, B7)] ^ C1[get_byte(1, B6)] ^ |
111 | 0 | C2[get_byte(2, B5)] ^ C3[get_byte(3, B4)] ^ |
112 | 0 | C4[get_byte(4, B3)] ^ C5[get_byte(5, B2)] ^ |
113 | 0 | C6[get_byte(6, B1)] ^ C7[get_byte(7, B0)] ^ K7; |
114 | 0 |
|
115 | 0 | B0 = T0; B1 = T1; B2 = T2; B3 = T3; |
116 | 0 | B4 = T4; B5 = T5; B6 = T6; B7 = T7; |
117 | 0 | } |
118 | 0 |
|
119 | 0 | m_digest[0] ^= B0 ^ m_M[0]; |
120 | 0 | m_digest[1] ^= B1 ^ m_M[1]; |
121 | 0 | m_digest[2] ^= B2 ^ m_M[2]; |
122 | 0 | m_digest[3] ^= B3 ^ m_M[3]; |
123 | 0 | m_digest[4] ^= B4 ^ m_M[4]; |
124 | 0 | m_digest[5] ^= B5 ^ m_M[5]; |
125 | 0 | m_digest[6] ^= B6 ^ m_M[6]; |
126 | 0 | m_digest[7] ^= B7 ^ m_M[7]; |
127 | 0 |
|
128 | 0 | in += hash_block_size(); |
129 | 0 | } |
130 | 0 | } |
131 | | |
132 | | /* |
133 | | * Copy out the digest |
134 | | */ |
135 | | void Whirlpool::copy_out(uint8_t output[]) |
136 | 0 | { |
137 | 0 | copy_out_vec_be(output, output_length(), m_digest); |
138 | 0 | } |
139 | | |
140 | | /* |
141 | | * Clear memory of sensitive data |
142 | | */ |
143 | | void Whirlpool::clear() |
144 | 0 | { |
145 | 0 | MDx_HashFunction::clear(); |
146 | 0 | zeroise(m_M); |
147 | 0 | zeroise(m_digest); |
148 | 0 | } |
149 | | |
150 | | } |