Botan  1.10.9
whrlpool.cpp
Go to the documentation of this file.
1 /*
2 * Whirlpool
3 * (C) 1999-2007 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
6 */
7 
8 #include <botan/whrlpool.h>
9 #include <botan/loadstor.h>
10 
11 namespace Botan {
12 
13 /*
14 * Whirlpool Compression Function
15 */
16 void Whirlpool::compress_n(const byte in[], size_t blocks)
17  {
18  static const u64bit RC[10] = {
19  0x1823C6E887B8014F, 0x36A6D2F5796F9152,
20  0x60BC9B8EA30C7B35, 0x1DE0D7C22E4BFE57,
21  0x157737E59FF04ADA, 0x58C9290AB1A06B85,
22  0xBD5D10F4CB3E0567, 0xE427418BA77D95D8,
23  0xFBEE7C66DD17479E, 0xCA2DBF07AD5A8333
24  };
25 
26  for(size_t i = 0; i != blocks; ++i)
27  {
28  load_be(&M[0], in, M.size());
29 
30  u64bit K0, K1, K2, K3, K4, K5, K6, K7;
31  K0 = digest[0]; K1 = digest[1]; K2 = digest[2]; K3 = digest[3];
32  K4 = digest[4]; K5 = digest[5]; K6 = digest[6]; K7 = digest[7];
33 
34  u64bit B0, B1, B2, B3, B4, B5, B6, B7;
35  B0 = K0 ^ M[0]; B1 = K1 ^ M[1]; B2 = K2 ^ M[2]; B3 = K3 ^ M[3];
36  B4 = K4 ^ M[4]; B5 = K5 ^ M[5]; B6 = K6 ^ M[6]; B7 = K7 ^ M[7];
37 
38  for(size_t j = 0; j != 10; ++j)
39  {
40  u64bit T0, T1, T2, T3, T4, T5, T6, T7;
41  T0 = C0[get_byte(0, K0)] ^ C1[get_byte(1, K7)] ^
42  C2[get_byte(2, K6)] ^ C3[get_byte(3, K5)] ^
43  C4[get_byte(4, K4)] ^ C5[get_byte(5, K3)] ^
44  C6[get_byte(6, K2)] ^ C7[get_byte(7, K1)] ^ RC[j];
45  T1 = C0[get_byte(0, K1)] ^ C1[get_byte(1, K0)] ^
46  C2[get_byte(2, K7)] ^ C3[get_byte(3, K6)] ^
47  C4[get_byte(4, K5)] ^ C5[get_byte(5, K4)] ^
48  C6[get_byte(6, K3)] ^ C7[get_byte(7, K2)];
49  T2 = C0[get_byte(0, K2)] ^ C1[get_byte(1, K1)] ^
50  C2[get_byte(2, K0)] ^ C3[get_byte(3, K7)] ^
51  C4[get_byte(4, K6)] ^ C5[get_byte(5, K5)] ^
52  C6[get_byte(6, K4)] ^ C7[get_byte(7, K3)];
53  T3 = C0[get_byte(0, K3)] ^ C1[get_byte(1, K2)] ^
54  C2[get_byte(2, K1)] ^ C3[get_byte(3, K0)] ^
55  C4[get_byte(4, K7)] ^ C5[get_byte(5, K6)] ^
56  C6[get_byte(6, K5)] ^ C7[get_byte(7, K4)];
57  T4 = C0[get_byte(0, K4)] ^ C1[get_byte(1, K3)] ^
58  C2[get_byte(2, K2)] ^ C3[get_byte(3, K1)] ^
59  C4[get_byte(4, K0)] ^ C5[get_byte(5, K7)] ^
60  C6[get_byte(6, K6)] ^ C7[get_byte(7, K5)];
61  T5 = C0[get_byte(0, K5)] ^ C1[get_byte(1, K4)] ^
62  C2[get_byte(2, K3)] ^ C3[get_byte(3, K2)] ^
63  C4[get_byte(4, K1)] ^ C5[get_byte(5, K0)] ^
64  C6[get_byte(6, K7)] ^ C7[get_byte(7, K6)];
65  T6 = C0[get_byte(0, K6)] ^ C1[get_byte(1, K5)] ^
66  C2[get_byte(2, K4)] ^ C3[get_byte(3, K3)] ^
67  C4[get_byte(4, K2)] ^ C5[get_byte(5, K1)] ^
68  C6[get_byte(6, K0)] ^ C7[get_byte(7, K7)];
69  T7 = C0[get_byte(0, K7)] ^ C1[get_byte(1, K6)] ^
70  C2[get_byte(2, K5)] ^ C3[get_byte(3, K4)] ^
71  C4[get_byte(4, K3)] ^ C5[get_byte(5, K2)] ^
72  C6[get_byte(6, K1)] ^ C7[get_byte(7, K0)];
73 
74  K0 = T0; K1 = T1; K2 = T2; K3 = T3;
75  K4 = T4; K5 = T5; K6 = T6; K7 = T7;
76 
77  T0 = C0[get_byte(0, B0)] ^ C1[get_byte(1, B7)] ^
78  C2[get_byte(2, B6)] ^ C3[get_byte(3, B5)] ^
79  C4[get_byte(4, B4)] ^ C5[get_byte(5, B3)] ^
80  C6[get_byte(6, B2)] ^ C7[get_byte(7, B1)] ^ K0;
81  T1 = C0[get_byte(0, B1)] ^ C1[get_byte(1, B0)] ^
82  C2[get_byte(2, B7)] ^ C3[get_byte(3, B6)] ^
83  C4[get_byte(4, B5)] ^ C5[get_byte(5, B4)] ^
84  C6[get_byte(6, B3)] ^ C7[get_byte(7, B2)] ^ K1;
85  T2 = C0[get_byte(0, B2)] ^ C1[get_byte(1, B1)] ^
86  C2[get_byte(2, B0)] ^ C3[get_byte(3, B7)] ^
87  C4[get_byte(4, B6)] ^ C5[get_byte(5, B5)] ^
88  C6[get_byte(6, B4)] ^ C7[get_byte(7, B3)] ^ K2;
89  T3 = C0[get_byte(0, B3)] ^ C1[get_byte(1, B2)] ^
90  C2[get_byte(2, B1)] ^ C3[get_byte(3, B0)] ^
91  C4[get_byte(4, B7)] ^ C5[get_byte(5, B6)] ^
92  C6[get_byte(6, B5)] ^ C7[get_byte(7, B4)] ^ K3;
93  T4 = C0[get_byte(0, B4)] ^ C1[get_byte(1, B3)] ^
94  C2[get_byte(2, B2)] ^ C3[get_byte(3, B1)] ^
95  C4[get_byte(4, B0)] ^ C5[get_byte(5, B7)] ^
96  C6[get_byte(6, B6)] ^ C7[get_byte(7, B5)] ^ K4;
97  T5 = C0[get_byte(0, B5)] ^ C1[get_byte(1, B4)] ^
98  C2[get_byte(2, B3)] ^ C3[get_byte(3, B2)] ^
99  C4[get_byte(4, B1)] ^ C5[get_byte(5, B0)] ^
100  C6[get_byte(6, B7)] ^ C7[get_byte(7, B6)] ^ K5;
101  T6 = C0[get_byte(0, B6)] ^ C1[get_byte(1, B5)] ^
102  C2[get_byte(2, B4)] ^ C3[get_byte(3, B3)] ^
103  C4[get_byte(4, B2)] ^ C5[get_byte(5, B1)] ^
104  C6[get_byte(6, B0)] ^ C7[get_byte(7, B7)] ^ K6;
105  T7 = C0[get_byte(0, B7)] ^ C1[get_byte(1, B6)] ^
106  C2[get_byte(2, B5)] ^ C3[get_byte(3, B4)] ^
107  C4[get_byte(4, B3)] ^ C5[get_byte(5, B2)] ^
108  C6[get_byte(6, B1)] ^ C7[get_byte(7, B0)] ^ K7;
109 
110  B0 = T0; B1 = T1; B2 = T2; B3 = T3;
111  B4 = T4; B5 = T5; B6 = T6; B7 = T7;
112  }
113 
114  digest[0] ^= B0 ^ M[0];
115  digest[1] ^= B1 ^ M[1];
116  digest[2] ^= B2 ^ M[2];
117  digest[3] ^= B3 ^ M[3];
118  digest[4] ^= B4 ^ M[4];
119  digest[5] ^= B5 ^ M[5];
120  digest[6] ^= B6 ^ M[6];
121  digest[7] ^= B7 ^ M[7];
122 
123  in += hash_block_size();
124  }
125  }
126 
127 /*
128 * Copy out the digest
129 */
130 void Whirlpool::copy_out(byte output[])
131  {
132  for(size_t i = 0; i != output_length(); i += 8)
133  store_be(digest[i/8], output + i);
134  }
135 
136 /*
137 * Clear memory of sensitive data
138 */
140  {
142  zeroise(M);
143  zeroise(digest);
144  }
145 
146 }
T load_be(const byte in[], size_t off)
Definition: loadstor.h:100
size_t hash_block_size() const
Definition: mdx_hash.h:32
size_t output_length() const
Definition: whrlpool.h:22
byte get_byte(size_t byte_num, T input)
Definition: get_byte.h:21
unsigned char byte
Definition: types.h:22
unsigned long long u64bit
Definition: types.h:49
size_t size() const
Definition: secmem.h:29
void store_be(u16bit in, byte out[2])
Definition: loadstor.h:412
void zeroise(MemoryRegion< T > &vec)
Definition: secmem.h:415