HarakaBase
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Digests
{
public abstract class HarakaBase : IDigest
{
internal static readonly int DIGEST_SIZE = 32;
internal static readonly byte[][] RC = new byte[40][] {
new byte[16] {
157,
123,
129,
117,
240,
254,
197,
178,
10,
192,
32,
230,
76,
112,
132,
6
},
new byte[16] {
23,
247,
8,
47,
164,
107,
15,
100,
107,
160,
243,
136,
225,
180,
102,
139
},
new byte[16] {
20,
145,
2,
159,
96,
157,
2,
207,
152,
132,
242,
83,
45,
222,
2,
52
},
new byte[16] {
121,
79,
91,
253,
175,
188,
243,
187,
8,
79,
123,
46,
230,
234,
214,
14
},
new byte[16] {
68,
112,
57,
190,
28,
205,
238,
121,
139,
68,
114,
72,
203,
176,
207,
203
},
new byte[16] {
123,
5,
138,
43,
237,
53,
83,
141,
183,
50,
144,
110,
238,
205,
234,
126
},
new byte[16] {
27,
239,
79,
218,
97,
39,
65,
226,
208,
124,
46,
94,
67,
143,
194,
103
},
new byte[16] {
59,
11,
199,
31,
226,
253,
95,
103,
7,
204,
202,
175,
176,
217,
36,
41
},
new byte[16] {
238,
101,
212,
185,
202,
143,
219,
236,
233,
127,
134,
230,
241,
99,
77,
171
},
new byte[16] {
51,
126,
3,
173,
79,
64,
42,
91,
100,
205,
183,
212,
132,
191,
48,
28
},
new byte[16] {
0,
152,
246,
141,
46,
139,
2,
105,
191,
35,
23,
148,
185,
11,
204,
178
},
new byte[16] {
138,
45,
157,
92,
200,
158,
170,
74,
114,
85,
111,
222,
166,
120,
4,
250
},
new byte[16] {
212,
159,
18,
41,
46,
79,
250,
14,
18,
42,
119,
107,
43,
159,
180,
223
},
new byte[16] {
238,
18,
106,
187,
174,
17,
214,
50,
54,
162,
73,
244,
68,
3,
161,
30
},
new byte[16] {
166,
236,
168,
156,
201,
0,
150,
95,
132,
0,
5,
75,
136,
73,
4,
175
},
new byte[16] {
236,
147,
229,
39,
227,
199,
162,
120,
79,
156,
25,
157,
216,
94,
2,
33
},
new byte[16] {
115,
1,
212,
130,
205,
46,
40,
185,
183,
201,
89,
167,
248,
170,
58,
191
},
new byte[16] {
107,
125,
48,
16,
217,
239,
242,
55,
23,
176,
134,
97,
13,
112,
96,
98
},
new byte[16] {
198,
154,
252,
246,
83,
145,
194,
129,
67,
4,
48,
33,
194,
69,
202,
90
},
new byte[16] {
58,
148,
209,
54,
232,
146,
175,
44,
187,
104,
107,
34,
60,
151,
35,
146
},
new byte[16] {
180,
113,
16,
229,
88,
185,
186,
108,
235,
134,
88,
34,
56,
146,
191,
211
},
new byte[16] {
141,
18,
225,
36,
221,
253,
61,
147,
119,
198,
240,
174,
229,
60,
134,
219
},
new byte[16] {
177,
18,
34,
203,
227,
141,
228,
131,
156,
160,
235,
byte.MaxValue,
104,
98,
96,
187
},
new byte[16] {
125,
247,
43,
199,
78,
26,
185,
45,
156,
209,
228,
226,
220,
211,
75,
115
},
new byte[16] {
78,
146,
179,
44,
196,
21,
20,
75,
67,
27,
48,
97,
195,
71,
187,
67
},
new byte[16] {
153,
104,
235,
22,
221,
49,
178,
3,
246,
239,
7,
231,
168,
117,
167,
219
},
new byte[16] {
44,
71,
202,
126,
2,
35,
94,
142,
119,
89,
117,
60,
75,
97,
243,
109
},
new byte[16] {
249,
23,
134,
184,
185,
229,
27,
109,
119,
125,
222,
214,
23,
90,
167,
205
},
new byte[16] {
93,
238,
70,
169,
157,
6,
108,
157,
170,
233,
168,
107,
240,
67,
107,
236
},
new byte[16] {
193,
39,
243,
59,
89,
17,
83,
162,
43,
51,
87,
249,
80,
105,
30,
203
},
new byte[16] {
217,
208,
14,
96,
83,
3,
237,
228,
156,
97,
218,
0,
117,
12,
238,
44
},
new byte[16] {
80,
163,
164,
99,
188,
186,
187,
128,
171,
12,
233,
150,
161,
165,
177,
240
},
new byte[16] {
57,
202,
141,
147,
48,
222,
13,
171,
136,
41,
150,
94,
2,
177,
61,
174
},
new byte[16] {
66,
180,
117,
46,
168,
243,
20,
136,
11,
164,
84,
213,
56,
143,
187,
23
},
new byte[16] {
246,
22,
10,
54,
121,
183,
182,
174,
215,
127,
66,
95,
91,
138,
187,
52
},
new byte[16] {
222,
175,
186,
byte.MaxValue,
24,
89,
206,
67,
56,
84,
229,
203,
65,
82,
246,
38
},
new byte[16] {
120,
201,
158,
131,
247,
156,
202,
162,
106,
2,
243,
185,
84,
154,
233,
76
},
new byte[16] {
53,
18,
144,
34,
40,
110,
192,
64,
190,
247,
223,
27,
26,
165,
81,
174
},
new byte[16] {
207,
89,
166,
72,
15,
188,
115,
193,
43,
210,
126,
186,
60,
97,
193,
160
},
new byte[16] {
161,
157,
197,
233,
253,
189,
214,
74,
136,
130,
40,
2,
3,
204,
106,
117
}
};
private static readonly byte[,] S = new byte[16, 16] {
{
99,
124,
119,
123,
242,
107,
111,
197,
48,
1,
103,
43,
254,
215,
171,
118
},
{
202,
130,
201,
125,
250,
89,
71,
240,
173,
212,
162,
175,
156,
164,
114,
192
},
{
183,
253,
147,
38,
54,
63,
247,
204,
52,
165,
229,
241,
113,
216,
49,
21
},
{
4,
199,
35,
195,
24,
150,
5,
154,
7,
18,
128,
226,
235,
39,
178,
117
},
{
9,
131,
44,
26,
27,
110,
90,
160,
82,
59,
214,
179,
41,
227,
47,
132
},
{
83,
209,
0,
237,
32,
252,
177,
91,
106,
203,
190,
57,
74,
76,
88,
207
},
{
208,
239,
170,
251,
67,
77,
51,
133,
69,
249,
2,
127,
80,
60,
159,
168
},
{
81,
163,
64,
143,
146,
157,
56,
245,
188,
182,
218,
33,
16,
byte.MaxValue,
243,
210
},
{
205,
12,
19,
236,
95,
151,
68,
23,
196,
167,
126,
61,
100,
93,
25,
115
},
{
96,
129,
79,
220,
34,
42,
144,
136,
70,
238,
184,
20,
222,
94,
11,
219
},
{
224,
50,
58,
10,
73,
6,
36,
92,
194,
211,
172,
98,
145,
149,
228,
121
},
{
231,
200,
55,
109,
141,
213,
78,
169,
108,
86,
244,
234,
101,
122,
174,
8
},
{
186,
120,
37,
46,
28,
166,
180,
198,
232,
221,
116,
31,
75,
189,
139,
138
},
{
112,
62,
181,
102,
72,
3,
246,
14,
97,
53,
87,
185,
134,
193,
29,
158
},
{
225,
248,
152,
17,
105,
217,
142,
148,
155,
30,
135,
233,
206,
85,
40,
223
},
{
140,
161,
137,
13,
191,
230,
66,
104,
65,
153,
45,
15,
176,
84,
187,
22
}
};
public abstract string AlgorithmName { get; }
private static byte SBox(byte x)
{
return S[(uint)x >> 4, x & 15];
}
private static byte[] SubBytes(byte[] s)
{
byte[] array = new byte[s.Length];
for (int i = 0; i < 16; i++) {
array[i] = SBox(s[i]);
}
return array;
}
private static byte[] ShiftRows(byte[] s)
{
return new byte[16] {
s[0],
s[5],
s[10],
s[15],
s[4],
s[9],
s[14],
s[3],
s[8],
s[13],
s[2],
s[7],
s[12],
s[1],
s[6],
s[11]
};
}
internal static byte[] AesEnc(byte[] s, byte[] rk)
{
s = SubBytes(s);
s = ShiftRows(s);
s = MixColumns(s);
Bytes.XorTo(16, rk, s);
return s;
}
private static byte MulX(byte p)
{
return (byte)(((p & 127) << 1) ^ (((uint)p >> 7) * 27));
}
private static byte[] MixColumns(byte[] s)
{
byte[] array = new byte[s.Length];
int num = 0;
for (int i = 0; i < 4; i++) {
int num2 = i << 2;
array[num++] = (byte)(MulX(s[num2]) ^ MulX(s[num2 + 1]) ^ s[num2 + 1] ^ s[num2 + 2] ^ s[num2 + 3]);
array[num++] = (byte)(s[num2] ^ MulX(s[num2 + 1]) ^ MulX(s[num2 + 2]) ^ s[num2 + 2] ^ s[num2 + 3]);
array[num++] = (byte)(s[num2] ^ s[num2 + 1] ^ MulX(s[num2 + 2]) ^ MulX(s[num2 + 3]) ^ s[num2 + 3]);
array[num++] = (byte)(MulX(s[num2]) ^ s[num2] ^ s[num2 + 1] ^ s[num2 + 2] ^ MulX(s[num2 + 3]));
}
return array;
}
public int GetDigestSize()
{
return DIGEST_SIZE;
}
public abstract int GetByteLength();
public abstract void Update(byte input);
public abstract void BlockUpdate(byte[] input, int inOff, int length);
public abstract int DoFinal(byte[] output, int outOff);
public abstract void Reset();
}
}