crhash: whirlpool: bulk copy constant data from S-matrix
[crhash.git] / hash-whirlpool.c
blob72b72825fbcc768271015fa781adca4638cc81b6
1 #include <stdint.h>
2 #include <stdlib.h>
3 #include <string.h>
5 #include "hash-whirlpool.h"
7 static const uint8_t S[256] = {
8 0x18, 0x23, 0xC6, 0xE8, 0x87, 0xB8, 0x01, 0x4F, 0x36, 0xA6, 0xD2, 0xF5, 0x79, 0x6F, 0x91, 0x52,
9 0x60, 0xBC, 0x9B, 0x8E, 0xA3, 0x0C, 0x7B, 0x35, 0x1D, 0xE0, 0xD7, 0xC2, 0x2E, 0x4B, 0xFE, 0x57,
10 0x15, 0x77, 0x37, 0xE5, 0x9F, 0xF0, 0x4A, 0xDA, 0x58, 0xC9, 0x29, 0x0A, 0xB1, 0xA0, 0x6B, 0x85,
11 0xBD, 0x5D, 0x10, 0xF4, 0xCB, 0x3E, 0x05, 0x67, 0xE4, 0x27, 0x41, 0x8B, 0xA7, 0x7D, 0x95, 0xD8,
12 0xFB, 0xEE, 0x7C, 0x66, 0xDD, 0x17, 0x47, 0x9E, 0xCA, 0x2D, 0xBF, 0x07, 0xAD, 0x5A, 0x83, 0x33,
13 0x63, 0x02, 0xAA, 0x71, 0xC8, 0x19, 0x49, 0xD9, 0xF2, 0xE3, 0x5B, 0x88, 0x9A, 0x26, 0x32, 0xB0,
14 0xE9, 0x0F, 0xD5, 0x80, 0xBE, 0xCD, 0x34, 0x48, 0xFF, 0x7A, 0x90, 0x5F, 0x20, 0x68, 0x1A, 0xAE,
15 0xB4, 0x54, 0x93, 0x22, 0x64, 0xF1, 0x73, 0x12, 0x40, 0x08, 0xC3, 0xEC, 0xDB, 0xA1, 0x8D, 0x3D,
16 0x97, 0x00, 0xCF, 0x2B, 0x76, 0x82, 0xD6, 0x1B, 0xB5, 0xAF, 0x6A, 0x50, 0x45, 0xF3, 0x30, 0xEF,
17 0x3F, 0x55, 0xA2, 0xEA, 0x65, 0xBA, 0x2F, 0xC0, 0xDE, 0x1C, 0xFD, 0x4D, 0x92, 0x75, 0x06, 0x8A,
18 0xB2, 0xE6, 0x0E, 0x1F, 0x62, 0xD4, 0xA8, 0x96, 0xF9, 0xC5, 0x25, 0x59, 0x84, 0x72, 0x39, 0x4C,
19 0x5E, 0x78, 0x38, 0x8C, 0xD1, 0xA5, 0xE2, 0x61, 0xB3, 0x21, 0x9C, 0x1E, 0x43, 0xC7, 0xFC, 0x04,
20 0x51, 0x99, 0x6D, 0x0D, 0xFA, 0xDF, 0x7E, 0x24, 0x3B, 0xAB, 0xCE, 0x11, 0x8F, 0x4E, 0xB7, 0xEB,
21 0x3C, 0x81, 0x94, 0xF7, 0xB9, 0x13, 0x2C, 0xD3, 0xE7, 0x6E, 0xC4, 0x03, 0x56, 0x44, 0x7F, 0xA9,
22 0x2A, 0xBB, 0xC1, 0x53, 0xDC, 0x0B, 0x9D, 0x6C, 0x31, 0x74, 0xF6, 0x46, 0xAC, 0x89, 0x14, 0xE1,
23 0x16, 0x3A, 0x69, 0x09, 0x70, 0xB6, 0xD0, 0xED, 0xCC, 0x42, 0x98, 0xA4, 0x28, 0x5C, 0xF8, 0x86,
26 static void gamma(uint8_t a[8][8], uint8_t b[8][8])
28 unsigned int i, j;
30 for (i = 0; i < 8; i++)
31 for (j = 0; j < 8; j++)
32 b[i][j] = S[a[i][j]];
35 static void pi(uint8_t a[8][8], uint8_t b[8][8])
37 unsigned int i, j;
39 for (i = 0; i < 8; i++)
40 for (j = 0; j < 8; j++)
41 b[i][j] = a[(i - j) % 8][j];
44 /* GF(2^8) = GF(2)[x] / x^8 + x^4 + x^3 + x^2 + 1 */
45 static const uint8_t _02[256] = {
46 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E,
47 0x20, 0x22, 0x24, 0x26, 0x28, 0x2A, 0x2C, 0x2E, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3A, 0x3C, 0x3E,
48 0x40, 0x42, 0x44, 0x46, 0x48, 0x4A, 0x4C, 0x4E, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5A, 0x5C, 0x5E,
49 0x60, 0x62, 0x64, 0x66, 0x68, 0x6A, 0x6C, 0x6E, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7A, 0x7C, 0x7E,
50 0x80, 0x82, 0x84, 0x86, 0x88, 0x8A, 0x8C, 0x8E, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9A, 0x9C, 0x9E,
51 0xA0, 0xA2, 0xA4, 0xA6, 0xA8, 0xAA, 0xAC, 0xAE, 0xB0, 0xB2, 0xB4, 0xB6, 0xB8, 0xBA, 0xBC, 0xBE,
52 0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC, 0xCE, 0xD0, 0xD2, 0xD4, 0xD6, 0xD8, 0xDA, 0xDC, 0xDE,
53 0xE0, 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEC, 0xEE, 0xF0, 0xF2, 0xF4, 0xF6, 0xF8, 0xFA, 0xFC, 0xFE,
54 0x1D, 0x1F, 0x19, 0x1B, 0x15, 0x17, 0x11, 0x13, 0x0D, 0x0F, 0x09, 0x0B, 0x05, 0x07, 0x01, 0x03,
55 0x3D, 0x3F, 0x39, 0x3B, 0x35, 0x37, 0x31, 0x33, 0x2D, 0x2F, 0x29, 0x2B, 0x25, 0x27, 0x21, 0x23,
56 0x5D, 0x5F, 0x59, 0x5B, 0x55, 0x57, 0x51, 0x53, 0x4D, 0x4F, 0x49, 0x4B, 0x45, 0x47, 0x41, 0x43,
57 0x7D, 0x7F, 0x79, 0x7B, 0x75, 0x77, 0x71, 0x73, 0x6D, 0x6F, 0x69, 0x6B, 0x65, 0x67, 0x61, 0x63,
58 0x9D, 0x9F, 0x99, 0x9B, 0x95, 0x97, 0x91, 0x93, 0x8D, 0x8F, 0x89, 0x8B, 0x85, 0x87, 0x81, 0x83,
59 0xBD, 0xBF, 0xB9, 0xBB, 0xB5, 0xB7, 0xB1, 0xB3, 0xAD, 0xAF, 0xA9, 0xAB, 0xA5, 0xA7, 0xA1, 0xA3,
60 0xDD, 0xDF, 0xD9, 0xDB, 0xD5, 0xD7, 0xD1, 0xD3, 0xCD, 0xCF, 0xC9, 0xCB, 0xC5, 0xC7, 0xC1, 0xC3,
61 0xFD, 0xFF, 0xF9, 0xFB, 0xF5, 0xF7, 0xF1, 0xF3, 0xED, 0xEF, 0xE9, 0xEB, 0xE5, 0xE7, 0xE1, 0xE3,
64 static const uint8_t _04[256] = {
65 0x00, 0x04, 0x08, 0x0C, 0x10, 0x14, 0x18, 0x1C, 0x20, 0x24, 0x28, 0x2C, 0x30, 0x34, 0x38, 0x3C,
66 0x40, 0x44, 0x48, 0x4C, 0x50, 0x54, 0x58, 0x5C, 0x60, 0x64, 0x68, 0x6C, 0x70, 0x74, 0x78, 0x7C,
67 0x80, 0x84, 0x88, 0x8C, 0x90, 0x94, 0x98, 0x9C, 0xA0, 0xA4, 0xA8, 0xAC, 0xB0, 0xB4, 0xB8, 0xBC,
68 0xC0, 0xC4, 0xC8, 0xCC, 0xD0, 0xD4, 0xD8, 0xDC, 0xE0, 0xE4, 0xE8, 0xEC, 0xF0, 0xF4, 0xF8, 0xFC,
69 0x1D, 0x19, 0x15, 0x11, 0x0D, 0x09, 0x05, 0x01, 0x3D, 0x39, 0x35, 0x31, 0x2D, 0x29, 0x25, 0x21,
70 0x5D, 0x59, 0x55, 0x51, 0x4D, 0x49, 0x45, 0x41, 0x7D, 0x79, 0x75, 0x71, 0x6D, 0x69, 0x65, 0x61,
71 0x9D, 0x99, 0x95, 0x91, 0x8D, 0x89, 0x85, 0x81, 0xBD, 0xB9, 0xB5, 0xB1, 0xAD, 0xA9, 0xA5, 0xA1,
72 0xDD, 0xD9, 0xD5, 0xD1, 0xCD, 0xC9, 0xC5, 0xC1, 0xFD, 0xF9, 0xF5, 0xF1, 0xED, 0xE9, 0xE5, 0xE1,
73 0x3A, 0x3E, 0x32, 0x36, 0x2A, 0x2E, 0x22, 0x26, 0x1A, 0x1E, 0x12, 0x16, 0x0A, 0x0E, 0x02, 0x06,
74 0x7A, 0x7E, 0x72, 0x76, 0x6A, 0x6E, 0x62, 0x66, 0x5A, 0x5E, 0x52, 0x56, 0x4A, 0x4E, 0x42, 0x46,
75 0xBA, 0xBE, 0xB2, 0xB6, 0xAA, 0xAE, 0xA2, 0xA6, 0x9A, 0x9E, 0x92, 0x96, 0x8A, 0x8E, 0x82, 0x86,
76 0xFA, 0xFE, 0xF2, 0xF6, 0xEA, 0xEE, 0xE2, 0xE6, 0xDA, 0xDE, 0xD2, 0xD6, 0xCA, 0xCE, 0xC2, 0xC6,
77 0x27, 0x23, 0x2F, 0x2B, 0x37, 0x33, 0x3F, 0x3B, 0x07, 0x03, 0x0F, 0x0B, 0x17, 0x13, 0x1F, 0x1B,
78 0x67, 0x63, 0x6F, 0x6B, 0x77, 0x73, 0x7F, 0x7B, 0x47, 0x43, 0x4F, 0x4B, 0x57, 0x53, 0x5F, 0x5B,
79 0xA7, 0xA3, 0xAF, 0xAB, 0xB7, 0xB3, 0xBF, 0xBB, 0x87, 0x83, 0x8F, 0x8B, 0x97, 0x93, 0x9F, 0x9B,
80 0xE7, 0xE3, 0xEF, 0xEB, 0xF7, 0xF3, 0xFF, 0xFB, 0xC7, 0xC3, 0xCF, 0xCB, 0xD7, 0xD3, 0xDF, 0xDB,
83 static const uint8_t _05[256] = {
84 0x00, 0x05, 0x0A, 0x0F, 0x14, 0x11, 0x1E, 0x1B, 0x28, 0x2D, 0x22, 0x27, 0x3C, 0x39, 0x36, 0x33,
85 0x50, 0x55, 0x5A, 0x5F, 0x44, 0x41, 0x4E, 0x4B, 0x78, 0x7D, 0x72, 0x77, 0x6C, 0x69, 0x66, 0x63,
86 0xA0, 0xA5, 0xAA, 0xAF, 0xB4, 0xB1, 0xBE, 0xBB, 0x88, 0x8D, 0x82, 0x87, 0x9C, 0x99, 0x96, 0x93,
87 0xF0, 0xF5, 0xFA, 0xFF, 0xE4, 0xE1, 0xEE, 0xEB, 0xD8, 0xDD, 0xD2, 0xD7, 0xCC, 0xC9, 0xC6, 0xC3,
88 0x5D, 0x58, 0x57, 0x52, 0x49, 0x4C, 0x43, 0x46, 0x75, 0x70, 0x7F, 0x7A, 0x61, 0x64, 0x6B, 0x6E,
89 0x0D, 0x08, 0x07, 0x02, 0x19, 0x1C, 0x13, 0x16, 0x25, 0x20, 0x2F, 0x2A, 0x31, 0x34, 0x3B, 0x3E,
90 0xFD, 0xF8, 0xF7, 0xF2, 0xE9, 0xEC, 0xE3, 0xE6, 0xD5, 0xD0, 0xDF, 0xDA, 0xC1, 0xC4, 0xCB, 0xCE,
91 0xAD, 0xA8, 0xA7, 0xA2, 0xB9, 0xBC, 0xB3, 0xB6, 0x85, 0x80, 0x8F, 0x8A, 0x91, 0x94, 0x9B, 0x9E,
92 0xBA, 0xBF, 0xB0, 0xB5, 0xAE, 0xAB, 0xA4, 0xA1, 0x92, 0x97, 0x98, 0x9D, 0x86, 0x83, 0x8C, 0x89,
93 0xEA, 0xEF, 0xE0, 0xE5, 0xFE, 0xFB, 0xF4, 0xF1, 0xC2, 0xC7, 0xC8, 0xCD, 0xD6, 0xD3, 0xDC, 0xD9,
94 0x1A, 0x1F, 0x10, 0x15, 0x0E, 0x0B, 0x04, 0x01, 0x32, 0x37, 0x38, 0x3D, 0x26, 0x23, 0x2C, 0x29,
95 0x4A, 0x4F, 0x40, 0x45, 0x5E, 0x5B, 0x54, 0x51, 0x62, 0x67, 0x68, 0x6D, 0x76, 0x73, 0x7C, 0x79,
96 0xE7, 0xE2, 0xED, 0xE8, 0xF3, 0xF6, 0xF9, 0xFC, 0xCF, 0xCA, 0xC5, 0xC0, 0xDB, 0xDE, 0xD1, 0xD4,
97 0xB7, 0xB2, 0xBD, 0xB8, 0xA3, 0xA6, 0xA9, 0xAC, 0x9F, 0x9A, 0x95, 0x90, 0x8B, 0x8E, 0x81, 0x84,
98 0x47, 0x42, 0x4D, 0x48, 0x53, 0x56, 0x59, 0x5C, 0x6F, 0x6A, 0x65, 0x60, 0x7B, 0x7E, 0x71, 0x74,
99 0x17, 0x12, 0x1D, 0x18, 0x03, 0x06, 0x09, 0x0C, 0x3F, 0x3A, 0x35, 0x30, 0x2B, 0x2E, 0x21, 0x24,
102 static const uint8_t _08[256] = {
103 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38, 0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78,
104 0x80, 0x88, 0x90, 0x98, 0xA0, 0xA8, 0xB0, 0xB8, 0xC0, 0xC8, 0xD0, 0xD8, 0xE0, 0xE8, 0xF0, 0xF8,
105 0x1D, 0x15, 0x0D, 0x05, 0x3D, 0x35, 0x2D, 0x25, 0x5D, 0x55, 0x4D, 0x45, 0x7D, 0x75, 0x6D, 0x65,
106 0x9D, 0x95, 0x8D, 0x85, 0xBD, 0xB5, 0xAD, 0xA5, 0xDD, 0xD5, 0xCD, 0xC5, 0xFD, 0xF5, 0xED, 0xE5,
107 0x3A, 0x32, 0x2A, 0x22, 0x1A, 0x12, 0x0A, 0x02, 0x7A, 0x72, 0x6A, 0x62, 0x5A, 0x52, 0x4A, 0x42,
108 0xBA, 0xB2, 0xAA, 0xA2, 0x9A, 0x92, 0x8A, 0x82, 0xFA, 0xF2, 0xEA, 0xE2, 0xDA, 0xD2, 0xCA, 0xC2,
109 0x27, 0x2F, 0x37, 0x3F, 0x07, 0x0F, 0x17, 0x1F, 0x67, 0x6F, 0x77, 0x7F, 0x47, 0x4F, 0x57, 0x5F,
110 0xA7, 0xAF, 0xB7, 0xBF, 0x87, 0x8F, 0x97, 0x9F, 0xE7, 0xEF, 0xF7, 0xFF, 0xC7, 0xCF, 0xD7, 0xDF,
111 0x74, 0x7C, 0x64, 0x6C, 0x54, 0x5C, 0x44, 0x4C, 0x34, 0x3C, 0x24, 0x2C, 0x14, 0x1C, 0x04, 0x0C,
112 0xF4, 0xFC, 0xE4, 0xEC, 0xD4, 0xDC, 0xC4, 0xCC, 0xB4, 0xBC, 0xA4, 0xAC, 0x94, 0x9C, 0x84, 0x8C,
113 0x69, 0x61, 0x79, 0x71, 0x49, 0x41, 0x59, 0x51, 0x29, 0x21, 0x39, 0x31, 0x09, 0x01, 0x19, 0x11,
114 0xE9, 0xE1, 0xF9, 0xF1, 0xC9, 0xC1, 0xD9, 0xD1, 0xA9, 0xA1, 0xB9, 0xB1, 0x89, 0x81, 0x99, 0x91,
115 0x4E, 0x46, 0x5E, 0x56, 0x6E, 0x66, 0x7E, 0x76, 0x0E, 0x06, 0x1E, 0x16, 0x2E, 0x26, 0x3E, 0x36,
116 0xCE, 0xC6, 0xDE, 0xD6, 0xEE, 0xE6, 0xFE, 0xF6, 0x8E, 0x86, 0x9E, 0x96, 0xAE, 0xA6, 0xBE, 0xB6,
117 0x53, 0x5B, 0x43, 0x4B, 0x73, 0x7B, 0x63, 0x6B, 0x13, 0x1B, 0x03, 0x0B, 0x33, 0x3B, 0x23, 0x2B,
118 0xD3, 0xDB, 0xC3, 0xCB, 0xF3, 0xFB, 0xE3, 0xEB, 0x93, 0x9B, 0x83, 0x8B, 0xB3, 0xBB, 0xA3, 0xAB,
121 static const uint8_t _09[256] = {
122 0x00, 0x09, 0x12, 0x1B, 0x24, 0x2D, 0x36, 0x3F, 0x48, 0x41, 0x5A, 0x53, 0x6C, 0x65, 0x7E, 0x77,
123 0x90, 0x99, 0x82, 0x8B, 0xB4, 0xBD, 0xA6, 0xAF, 0xD8, 0xD1, 0xCA, 0xC3, 0xFC, 0xF5, 0xEE, 0xE7,
124 0x3D, 0x34, 0x2F, 0x26, 0x19, 0x10, 0x0B, 0x02, 0x75, 0x7C, 0x67, 0x6E, 0x51, 0x58, 0x43, 0x4A,
125 0xAD, 0xA4, 0xBF, 0xB6, 0x89, 0x80, 0x9B, 0x92, 0xE5, 0xEC, 0xF7, 0xFE, 0xC1, 0xC8, 0xD3, 0xDA,
126 0x7A, 0x73, 0x68, 0x61, 0x5E, 0x57, 0x4C, 0x45, 0x32, 0x3B, 0x20, 0x29, 0x16, 0x1F, 0x04, 0x0D,
127 0xEA, 0xE3, 0xF8, 0xF1, 0xCE, 0xC7, 0xDC, 0xD5, 0xA2, 0xAB, 0xB0, 0xB9, 0x86, 0x8F, 0x94, 0x9D,
128 0x47, 0x4E, 0x55, 0x5C, 0x63, 0x6A, 0x71, 0x78, 0x0F, 0x06, 0x1D, 0x14, 0x2B, 0x22, 0x39, 0x30,
129 0xD7, 0xDE, 0xC5, 0xCC, 0xF3, 0xFA, 0xE1, 0xE8, 0x9F, 0x96, 0x8D, 0x84, 0xBB, 0xB2, 0xA9, 0xA0,
130 0xF4, 0xFD, 0xE6, 0xEF, 0xD0, 0xD9, 0xC2, 0xCB, 0xBC, 0xB5, 0xAE, 0xA7, 0x98, 0x91, 0x8A, 0x83,
131 0x64, 0x6D, 0x76, 0x7F, 0x40, 0x49, 0x52, 0x5B, 0x2C, 0x25, 0x3E, 0x37, 0x08, 0x01, 0x1A, 0x13,
132 0xC9, 0xC0, 0xDB, 0xD2, 0xED, 0xE4, 0xFF, 0xF6, 0x81, 0x88, 0x93, 0x9A, 0xA5, 0xAC, 0xB7, 0xBE,
133 0x59, 0x50, 0x4B, 0x42, 0x7D, 0x74, 0x6F, 0x66, 0x11, 0x18, 0x03, 0x0A, 0x35, 0x3C, 0x27, 0x2E,
134 0x8E, 0x87, 0x9C, 0x95, 0xAA, 0xA3, 0xB8, 0xB1, 0xC6, 0xCF, 0xD4, 0xDD, 0xE2, 0xEB, 0xF0, 0xF9,
135 0x1E, 0x17, 0x0C, 0x05, 0x3A, 0x33, 0x28, 0x21, 0x56, 0x5F, 0x44, 0x4D, 0x72, 0x7B, 0x60, 0x69,
136 0xB3, 0xBA, 0xA1, 0xA8, 0x97, 0x9E, 0x85, 0x8C, 0xFB, 0xF2, 0xE9, 0xE0, 0xDF, 0xD6, 0xCD, 0xC4,
137 0x23, 0x2A, 0x31, 0x38, 0x07, 0x0E, 0x15, 0x1C, 0x6B, 0x62, 0x79, 0x70, 0x4F, 0x46, 0x5D, 0x54,
140 #define _1(a) a
141 #define _2(a) _02[a]
142 #define _4(a) _04[a]
143 #define _5(a) _05[a]
144 #define _8(a) _08[a]
145 #define _9(a) _09[a]
147 static void theta(uint8_t a[8][8], uint8_t b[8][8])
149 unsigned int i;
151 for (i = 0; i < 8; i++) {
152 b[i][0] = _1(a[i][0]) ^ _9(a[i][1]) ^ _2(a[i][2]) ^ _5(a[i][3]) ^ _8(a[i][4]) ^ _1(a[i][5]) ^ _4(a[i][6]) ^ _1(a[i][7]);
153 b[i][1] = _1(a[i][0]) ^ _1(a[i][1]) ^ _9(a[i][2]) ^ _2(a[i][3]) ^ _5(a[i][4]) ^ _8(a[i][5]) ^ _1(a[i][6]) ^ _4(a[i][7]);
154 b[i][2] = _4(a[i][0]) ^ _1(a[i][1]) ^ _1(a[i][2]) ^ _9(a[i][3]) ^ _2(a[i][4]) ^ _5(a[i][5]) ^ _8(a[i][6]) ^ _1(a[i][7]);
155 b[i][3] = _1(a[i][0]) ^ _4(a[i][1]) ^ _1(a[i][2]) ^ _1(a[i][3]) ^ _9(a[i][4]) ^ _2(a[i][5]) ^ _5(a[i][6]) ^ _8(a[i][7]);
156 b[i][4] = _8(a[i][0]) ^ _1(a[i][1]) ^ _4(a[i][2]) ^ _1(a[i][3]) ^ _1(a[i][4]) ^ _9(a[i][5]) ^ _2(a[i][6]) ^ _5(a[i][7]);
157 b[i][5] = _5(a[i][0]) ^ _8(a[i][1]) ^ _1(a[i][2]) ^ _4(a[i][3]) ^ _1(a[i][4]) ^ _1(a[i][5]) ^ _9(a[i][6]) ^ _2(a[i][7]);
158 b[i][6] = _2(a[i][0]) ^ _5(a[i][1]) ^ _8(a[i][2]) ^ _1(a[i][3]) ^ _4(a[i][4]) ^ _1(a[i][5]) ^ _1(a[i][6]) ^ _9(a[i][7]);
159 b[i][7] = _9(a[i][0]) ^ _2(a[i][1]) ^ _5(a[i][2]) ^ _8(a[i][3]) ^ _1(a[i][4]) ^ _4(a[i][5]) ^ _1(a[i][6]) ^ _1(a[i][7]);
163 static void sigma(uint8_t a[8][8], uint8_t k[8][8], uint8_t b[8][8])
165 unsigned int i, j;
167 for (i = 0; i < 8; i++)
168 for (j = 0; j < 8; j++)
169 b[i][j] = a[i][j] ^ k[i][j];
172 static void rho(uint8_t a[8][8], uint8_t k[8][8], uint8_t b[8][8])
174 uint8_t a1[8][8], a2[8][8], a3[8][8];
176 gamma(a, a1);
177 pi(a1, a2);
178 theta(a2, a3);
179 sigma(a3, k, b);
182 struct whirlpool_context {
183 uint8_t H[8][8];
184 uint64_t len;
185 uint8_t m[512 / 8];
186 unsigned int m_len;
189 static void __whirlpool_update(void *_ctx, const uint8_t *m)
191 struct whirlpool_context *ctx = _ctx;
192 uint8_t W[8][8], K[8][8];
193 unsigned int i, j;
194 int r;
196 memcpy(K, ctx->H, 8 * 8);
197 memcpy(W, m, 8 * 8);
198 for (i = 0; i < 8; i++)
199 for (j = 0; j < 8; j++)
200 W[i][j] ^= K[i][j];
202 #define R 10
203 for (r = 1; r <= R; r++) {
204 uint8_t K1[8][8], W1[8][8];
205 uint8_t c[8][8];
207 memcpy(&c[0][0], &S[8 * (r - 1)], 8);
208 memset(&c[1][0], 0, (8 - 1) * 8);
209 rho(K, c, K1);
210 rho(W, K1, W1);
211 memcpy(K, K1, 8 * 8);
212 memcpy(W, W1, 8 * 8);
215 for (i = 0; i < 8; i++)
216 for (j = 0; j < 8; j++)
217 ctx->H[i][j] ^= W[i][j] ^ m[8 * i + j];
220 void *whirlpool_init_context(void)
222 struct whirlpool_context *ctx;
224 ctx = malloc(sizeof(struct whirlpool_context));
225 if (!ctx)
226 return NULL;
227 memset(ctx, 0, sizeof(struct whirlpool_context));
228 return ctx;
231 void whirlpool_fini_context(void *_ctx)
233 struct whirlpool_context *ctx = _ctx;
235 memset(ctx, 0, sizeof(struct whirlpool_context));
236 free(ctx);
239 void whirlpool_update(void *_ctx, const uint8_t *m)
241 struct whirlpool_context *ctx = _ctx;
243 __whirlpool_update(ctx, m);
244 ctx->len += 512;
247 void _whirlpool_update(void *_ctx, const uint8_t *m, unsigned int len)
249 struct whirlpool_context *ctx = _ctx;
251 while (len > 0) {
252 unsigned int inc;
254 if (64 - ctx->m_len < len)
255 inc = 64 - ctx->m_len;
256 else
257 inc = len;
258 memcpy(&ctx->m[ctx->m_len], m, inc);
259 ctx->m_len += inc;
260 ctx->len += inc * 8;
261 len -= inc;
262 m += inc;
264 if (ctx->m_len == 512 / 8) {
265 __whirlpool_update(ctx, ctx->m);
266 ctx->m_len = 0;
271 void whirlpool_fini(void *_ctx)
273 struct whirlpool_context *ctx = _ctx;
275 ctx->m[ctx->m_len] = 0x80;
276 ctx->m_len++;
277 if (ctx->m_len <= 64 - 32) {
278 memset(&ctx->m[ctx->m_len], 0, 64 - 8 - ctx->m_len);
279 } else {
280 memset(&ctx->m[ctx->m_len], 0, 64 - ctx->m_len);
281 __whirlpool_update(ctx, ctx->m);
282 memset(ctx->m, 0, 64 - 8);
284 *(uint64_t *)&ctx->m[64 - 8] = htobe64(ctx->len);
285 __whirlpool_update(ctx, ctx->m);
288 void whirlpool_digest(void *_ctx, uint8_t *digest)
290 struct whirlpool_context *ctx = _ctx;
292 memcpy(digest, ctx->H, 8 * 8);