srsLTE/lib/src/common/s3g.cc

568 lines
21 KiB
C++

/**
* Copyright 2013-2022 Software Radio Systems Limited
*
* This file is part of srsRAN.
*
* srsRAN is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsRAN is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#include "srsran/common/s3g.h"
/* S-box SQ */
static const uint8_t SQ[256] = {
0x25, 0x24, 0x73, 0x67, 0xD7, 0xAE, 0x5C, 0x30, 0xA4, 0xEE, 0x6E, 0xCB, 0x7D, 0xB5, 0x82, 0xDB, 0xE4, 0x8E, 0x48,
0x49, 0x4F, 0x5D, 0x6A, 0x78, 0x70, 0x88, 0xE8, 0x5F, 0x5E, 0x84, 0x65, 0xE2, 0xD8, 0xE9, 0xCC, 0xED, 0x40, 0x2F,
0x11, 0x28, 0x57, 0xD2, 0xAC, 0xE3, 0x4A, 0x15, 0x1B, 0xB9, 0xB2, 0x80, 0x85, 0xA6, 0x2E, 0x02, 0x47, 0x29, 0x07,
0x4B, 0x0E, 0xC1, 0x51, 0xAA, 0x89, 0xD4, 0xCA, 0x01, 0x46, 0xB3, 0xEF, 0xDD, 0x44, 0x7B, 0xC2, 0x7F, 0xBE, 0xC3,
0x9F, 0x20, 0x4C, 0x64, 0x83, 0xA2, 0x68, 0x42, 0x13, 0xB4, 0x41, 0xCD, 0xBA, 0xC6, 0xBB, 0x6D, 0x4D, 0x71, 0x21,
0xF4, 0x8D, 0xB0, 0xE5, 0x93, 0xFE, 0x8F, 0xE6, 0xCF, 0x43, 0x45, 0x31, 0x22, 0x37, 0x36, 0x96, 0xFA, 0xBC, 0x0F,
0x08, 0x52, 0x1D, 0x55, 0x1A, 0xC5, 0x4E, 0x23, 0x69, 0x7A, 0x92, 0xFF, 0x5B, 0x5A, 0xEB, 0x9A, 0x1C, 0xA9, 0xD1,
0x7E, 0x0D, 0xFC, 0x50, 0x8A, 0xB6, 0x62, 0xF5, 0x0A, 0xF8, 0xDC, 0x03, 0x3C, 0x0C, 0x39, 0xF1, 0xB8, 0xF3, 0x3D,
0xF2, 0xD5, 0x97, 0x66, 0x81, 0x32, 0xA0, 0x00, 0x06, 0xCE, 0xF6, 0xEA, 0xB7, 0x17, 0xF7, 0x8C, 0x79, 0xD6, 0xA7,
0xBF, 0x8B, 0x3F, 0x1F, 0x53, 0x63, 0x75, 0x35, 0x2C, 0x60, 0xFD, 0x27, 0xD3, 0x94, 0xA5, 0x7C, 0xA1, 0x05, 0x58,
0x2D, 0xBD, 0xD9, 0xC7, 0xAF, 0x6B, 0x54, 0x0B, 0xE0, 0x38, 0x04, 0xC8, 0x9D, 0xE7, 0x14, 0xB1, 0x87, 0x9C, 0xDF,
0x6F, 0xF9, 0xDA, 0x2A, 0xC4, 0x59, 0x16, 0x74, 0x91, 0xAB, 0x26, 0x61, 0x76, 0x34, 0x2B, 0xAD, 0x99, 0xFB, 0x72,
0xEC, 0x33, 0x12, 0xDE, 0x98, 0x3B, 0xC0, 0x9B, 0x3E, 0x18, 0x10, 0x3A, 0x56, 0xE1, 0x77, 0xC9, 0x1E, 0x9E, 0x95,
0xA3, 0x90, 0x19, 0xA8, 0x6C, 0x09, 0xD0, 0xF0, 0x86};
static const uint8_t S[256] = {
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, 255, 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};
/*********************************************************************
Name: s3g_mul_x
Description: Multiplication with reduction.
Document Reference: Specification of the 3GPP Confidentiality and
Integrity Algorithms UEA2 & UIA2 D2 v1.1
Section 3.1.1
*********************************************************************/
uint8_t s3g_mul_x(uint8_t v, uint8_t c);
/*********************************************************************
Name: s3g_mul_x_pow
Description: Recursive multiplication with reduction.
Document Reference: Specification of the 3GPP Confidentiality and
Integrity Algorithms UEA2 & UIA2 D2 v1.1
Section 3.1.2
*********************************************************************/
uint8_t s3g_mul_x_pow(uint8_t v, uint8_t i, uint8_t c);
/*********************************************************************
Name: s3g_mul_alpha
Description: Multiplication with alpha.
Document Reference: Specification of the 3GPP Confidentiality and
Integrity Algorithms UEA2 & UIA2 D2 v1.1
Section 3.4.2
*********************************************************************/
uint32_t s3g_mul_alpha(uint8_t c);
/*********************************************************************
Name: s3g_div_alpha
Description: Division by alpha.
Document Reference: Specification of the 3GPP Confidentiality and
Integrity Algorithms UEA2 & UIA2 D2 v1.1
Section 3.4.3
*********************************************************************/
uint32_t s3g_div_alpha(uint8_t c);
/*********************************************************************
Name: s3g_s1
Description: S-Box S1.
Document Reference: Specification of the 3GPP Confidentiality and
Integrity Algorithms UEA2 & UIA2 D2 v1.1
Section 3.3.1
*********************************************************************/
uint32_t s3g_s1(uint32_t w);
/*********************************************************************
Name: s3g_s2
Description: S-Box S2.
Document Reference: Specification of the 3GPP Confidentiality and
Integrity Algorithms UEA2 & UIA2 D2 v1.1
Section 3.3.2
*********************************************************************/
uint32_t s3g_s2(uint32_t w);
/*********************************************************************
Name: s3g_clock_lfsr
Description: Clocking LFSR.
Document Reference: Specification of the 3GPP Confidentiality and
Integrity Algorithms UEA2 & UIA2 D2 v1.1
Section 3.4.4 and Section 3.4.5
*********************************************************************/
void s3g_clock_lfsr(S3G_STATE* state, uint32_t f);
/*********************************************************************
Name: s3g_clock_fsm
Description: Clocking FSM.
Document Reference: Specification of the 3GPP Confidentiality and
Integrity Algorithms UEA2 & UIA2 D2 v1.1
Section 3.4.6
*********************************************************************/
uint32_t s3g_clock_fsm(S3G_STATE* state);
/*********************************************************************
Name: s3g_deinitialize
Description: Deinitialization.
Document Reference: Specification of the 3GPP Confidentiality and
Integrity Algorithms UEA2 & UIA2 D2 v1.1
*********************************************************************/
void s3g_deinitialize(S3G_STATE* state);
/*********************************************************************
Name: s3g_generate_keystream
Description: Generation of Keystream.
Document Reference: Specification of the 3GPP Confidentiality and
Integrity Algorithms UEA2 & UIA2 D2 v1.1
Section 4.2
*********************************************************************/
void s3g_generate_keystream(S3G_STATE* state, uint32_t n, uint32_t* ks);
/*********************************************************************
Name: s3g_mul_x
Description: Multiplication with reduction.
Document Reference: Specification of the 3GPP Confidentiality and
Integrity Algorithms UEA2 & UIA2 D2 v1.1
Section 3.1.1
*********************************************************************/
uint8_t s3g_mul_x(uint8_t v, uint8_t c)
{
if (v & 0x80)
return ((v << 1) ^ c);
else
return (v << 1);
}
/*********************************************************************
Name: s3g_mul_x_pow
Description: Recursive multiplication with reduction.
Document Reference: Specification of the 3GPP Confidentiality and
Integrity Algorithms UEA2 & UIA2 D2 v1.1
Section 3.1.2
*********************************************************************/
uint8_t s3g_mul_x_pow(uint8_t v, uint8_t i, uint8_t c)
{
if (i == 0)
return v;
else
return s3g_mul_x(s3g_mul_x_pow(v, i - 1, c), c);
}
/*********************************************************************
Name: s3g_mul_alpha
Description: Multiplication with alpha.
Document Reference: Specification of the 3GPP Confidentiality and
Integrity Algorithms UEA2 & UIA2 D2 v1.1
Section 3.4.2
*********************************************************************/
uint32_t s3g_mul_alpha(uint8_t c)
{
return ((((uint32_t)s3g_mul_x_pow(c, 23, 0xa9)) << 24) | (((uint32_t)s3g_mul_x_pow(c, 245, 0xa9)) << 16) |
(((uint32_t)s3g_mul_x_pow(c, 48, 0xa9)) << 8) | (((uint32_t)s3g_mul_x_pow(c, 239, 0xa9))));
}
/*********************************************************************
Name: s3g_div_alpha
Description: Division by alpha.
Document Reference: Specification of the 3GPP Confidentiality and
Integrity Algorithms UEA2 & UIA2 D2 v1.1
Section 3.4.3
*********************************************************************/
uint32_t s3g_div_alpha(uint8_t c)
{
return ((((uint32_t)s3g_mul_x_pow(c, 16, 0xa9)) << 24) | (((uint32_t)s3g_mul_x_pow(c, 39, 0xa9)) << 16) |
(((uint32_t)s3g_mul_x_pow(c, 6, 0xa9)) << 8) | (((uint32_t)s3g_mul_x_pow(c, 64, 0xa9))));
}
/*********************************************************************
Name: s3g_s1
Description: S-Box S1.
Document Reference: Specification of the 3GPP Confidentiality and
Integrity Algorithms UEA2 & UIA2 D2 v1.1
Section 3.3.1
*********************************************************************/
uint32_t s3g_s1(uint32_t w)
{
uint8_t r0 = 0, r1 = 0, r2 = 0, r3 = 0;
uint8_t srw0 = S[(uint8_t)((w >> 24) & 0xff)];
uint8_t srw1 = S[(uint8_t)((w >> 16) & 0xff)];
uint8_t srw2 = S[(uint8_t)((w >> 8) & 0xff)];
uint8_t srw3 = S[(uint8_t)((w)&0xff)];
r0 = ((s3g_mul_x(srw0, 0x1b)) ^ (srw1) ^ (srw2) ^ ((s3g_mul_x(srw3, 0x1b)) ^ srw3));
r1 = (((s3g_mul_x(srw0, 0x1b)) ^ srw0) ^ (s3g_mul_x(srw1, 0x1b)) ^ (srw2) ^ (srw3));
r2 = ((srw0) ^ ((s3g_mul_x(srw1, 0x1b)) ^ srw1) ^ (s3g_mul_x(srw2, 0x1b)) ^ (srw3));
r3 = ((srw0) ^ (srw1) ^ ((s3g_mul_x(srw2, 0x1b)) ^ srw2) ^ (s3g_mul_x(srw3, 0x1b)));
return ((((uint32_t)r0) << 24) | (((uint32_t)r1) << 16) | (((uint32_t)r2) << 8) | (((uint32_t)r3)));
}
/*********************************************************************
Name: s3g_s2
Description: S-Box S2.
Document Reference: Specification of the 3GPP Confidentiality and
Integrity Algorithms UEA2 & UIA2 D2 v1.1
Section 3.3.2
*********************************************************************/
uint32_t s3g_s2(uint32_t w)
{
uint8_t r0 = 0, r1 = 0, r2 = 0, r3 = 0;
uint8_t sqw0 = SQ[(uint8_t)((w >> 24) & 0xff)];
uint8_t sqw1 = SQ[(uint8_t)((w >> 16) & 0xff)];
uint8_t sqw2 = SQ[(uint8_t)((w >> 8) & 0xff)];
uint8_t sqw3 = SQ[(uint8_t)((w)&0xff)];
r0 = ((s3g_mul_x(sqw0, 0x69)) ^ (sqw1) ^ (sqw2) ^ ((s3g_mul_x(sqw3, 0x69)) ^ sqw3));
r1 = (((s3g_mul_x(sqw0, 0x69)) ^ sqw0) ^ (s3g_mul_x(sqw1, 0x69)) ^ (sqw2) ^ (sqw3));
r2 = ((sqw0) ^ ((s3g_mul_x(sqw1, 0x69)) ^ sqw1) ^ (s3g_mul_x(sqw2, 0x69)) ^ (sqw3));
r3 = ((sqw0) ^ (sqw1) ^ ((s3g_mul_x(sqw2, 0x69)) ^ sqw2) ^ (s3g_mul_x(sqw3, 0x69)));
return ((((uint32_t)r0) << 24) | (((uint32_t)r1) << 16) | (((uint32_t)r2) << 8) | (((uint32_t)r3)));
}
/*********************************************************************
Name: s3g_clock_lfsr
Description: Clocking LFSR.
Document Reference: Specification of the 3GPP Confidentiality and
Integrity Algorithms UEA2 & UIA2 D2 v1.1
Section 3.4.4 and Section 3.4.5
*********************************************************************/
void s3g_clock_lfsr(S3G_STATE* state, uint32_t f)
{
uint32_t v = (((state->lfsr[0] << 8) & 0xffffff00) ^ (s3g_mul_alpha((uint8_t)((state->lfsr[0] >> 24) & 0xff))) ^
(state->lfsr[2]) ^ ((state->lfsr[11] >> 8) & 0x00ffffff) ^
(s3g_div_alpha((uint8_t)((state->lfsr[11]) & 0xff))) ^ (f));
uint8_t i;
for (i = 0; i < 15; i++) {
state->lfsr[i] = state->lfsr[i + 1];
}
state->lfsr[15] = v;
}
/*********************************************************************
Name: s3g_clock_fsm
Description: Clocking FSM.
Document Reference: Specification of the 3GPP Confidentiality and
Integrity Algorithms UEA2 & UIA2 D2 v1.1
Section 3.4.6
*********************************************************************/
uint32_t s3g_clock_fsm(S3G_STATE* state)
{
uint32_t f = ((state->lfsr[15] + state->fsm[0]) & 0xffffffff) ^ state->fsm[1];
uint32_t r = (state->fsm[1] + (state->fsm[2] ^ state->lfsr[5])) & 0xffffffff;
state->fsm[2] = s3g_s2(state->fsm[1]);
state->fsm[1] = s3g_s1(state->fsm[0]);
state->fsm[0] = r;
return f;
}
/*********************************************************************
Name: s3g_initialize
Description: Initialization.
Document Reference: Specification of the 3GPP Confidentiality and
Integrity Algorithms UEA2 & UIA2 D2 v1.1
Section 4.1
*********************************************************************/
void s3g_initialize(S3G_STATE* state, uint32_t k[4], uint32_t iv[4])
{
uint8_t i = 0;
uint32_t f = 0x0;
state->lfsr = (uint32_t*)calloc(16, sizeof(uint32_t));
state->fsm = (uint32_t*)calloc(3, sizeof(uint32_t));
state->lfsr[15] = k[3] ^ iv[0];
state->lfsr[14] = k[2];
state->lfsr[13] = k[1];
state->lfsr[12] = k[0] ^ iv[1];
state->lfsr[11] = k[3] ^ 0xffffffff;
state->lfsr[10] = k[2] ^ 0xffffffff ^ iv[2];
state->lfsr[9] = k[1] ^ 0xffffffff ^ iv[3];
state->lfsr[8] = k[0] ^ 0xffffffff;
state->lfsr[7] = k[3];
state->lfsr[6] = k[2];
state->lfsr[5] = k[1];
state->lfsr[4] = k[0];
state->lfsr[3] = k[3] ^ 0xffffffff;
state->lfsr[2] = k[2] ^ 0xffffffff;
state->lfsr[1] = k[1] ^ 0xffffffff;
state->lfsr[0] = k[0] ^ 0xffffffff;
state->fsm[0] = 0x0;
state->fsm[1] = 0x0;
state->fsm[2] = 0x0;
for (i = 0; i < 32; i++) {
f = s3g_clock_fsm(state);
s3g_clock_lfsr(state, f);
}
}
/*********************************************************************
Name: s3g_deinitialize
Description: Deinitialization.
Document Reference: Specification of the 3GPP Confidentiality and
Integrity Algorithms UEA2 & UIA2 D2 v1.1
*********************************************************************/
void s3g_deinitialize(S3G_STATE* state)
{
free(state->lfsr);
free(state->fsm);
}
/*********************************************************************
Name: s3g_generate_keystream
Description: Generation of Keystream.
Document Reference: Specification of the 3GPP Confidentiality and
Integrity Algorithms UEA2 & UIA2 D2 v1.1
Section 4.2
*********************************************************************/
void s3g_generate_keystream(S3G_STATE* state, uint32_t n, uint32_t* ks)
{
uint32_t t = 0;
uint32_t f = 0x0;
// Clock FSM once. Discard the output.
s3g_clock_fsm(state);
// Clock LFSR in keystream mode once.
s3g_clock_lfsr(state, 0x0);
for (t = 0; t < n; t++) {
f = s3g_clock_fsm(state);
// Note that ks[t] corresponds to z_{t+1} in section 4.2
ks[t] = f ^ state->lfsr[0];
s3g_clock_lfsr(state, 0x0);
}
}
/* MUL64x.
* Input V: a 64-bit input.
* Input c: a 64-bit input.
* Output : a 64-bit output.
* A 64-bit memory is allocated which is to be freed by the calling
* function.
* See section 4.3.2 for details.
*/
uint64_t s3g_MUL64x(uint64_t V, uint64_t c)
{
if (V & 0x8000000000000000)
return (V << 1) ^ c;
else
return V << 1;
}
/* MUL64xPOW.
* Input V: a 64-bit input.
* Input i: a positive integer.
* Input c: a 64-bit input.
* Output : a 64-bit output.
* A 64-bit memory is allocated which is to be freed by the calling function.
* See section 4.3.3 for details.
*/
uint64_t s3g_MUL64xPOW(uint64_t V, uint8_t i, uint64_t c)
{
if (i == 0)
return V;
else
return s3g_MUL64x(s3g_MUL64xPOW(V, i - 1, c), c);
}
/* MUL64.
* Input V: a 64-bit input.
* Input P: a 64-bit input.
* Input c: a 64-bit input.
* Output : a 64-bit output.
* A 64-bit memory is allocated which is to be freed by the calling
* function.
* See section 4.3.4 for details.
*/
uint64_t s3g_MUL64(uint64_t V, uint64_t P, uint64_t c)
{
uint64_t result = 0;
int i = 0;
for (i = 0; i < 64; i++) {
if ((P >> i) & 0x1)
result ^= s3g_MUL64xPOW(V, i, c);
}
return result;
}
/* mask8bit.
* Input n: an integer in 1-7.
* Output : an 8 bit mask.
* Prepares an 8 bit mask with required number of 1 bits on the MSB side.
*/
uint8_t mask8bit(int n)
{
return 0xFF ^ ((1 << (8 - n)) - 1);
}
/* f9.
* Input key: 128 bit Integrity Key.
* Input count:32-bit Count, Frame dependent input.
* Input fresh: 32-bit Random number.
* Input dir:1 bit, direction of transmission (in the LSB).
* Input data: length number of bits, input bit stream.
* Input length: 64 bit Length, i.e., the number of bits to be MAC'd.
* Output : 32 bit block used as MAC
* Generates 32-bit MAC using UIA2 algorithm as defined in Section 4.
*/
uint8_t* s3g_f9(const uint8_t* key, uint32_t count, uint32_t fresh, uint32_t dir, uint8_t* data, uint64_t length)
{
uint32_t K[4], IV[4], z[5];
uint32_t i = 0, D;
static uint8_t MAC_I[4] = {0, 0, 0, 0}; /* static memory for the result */
uint64_t EVAL;
uint64_t V;
uint64_t P;
uint64_t Q;
uint64_t c;
S3G_STATE state, *state_ptr;
uint64_t M_D_2;
int rem_bits = 0;
state_ptr = &state;
/* Load the Integrity Key for SNOW3G initialization as in section 4.4. */
for (i = 0; i < 4; i++)
K[3 - i] = (key[4 * i] << 24) ^ (key[4 * i + 1] << 16) ^ (key[4 * i + 2] << 8) ^ (key[4 * i + 3]);
/* Prepare the Initialization Vector (IV) for SNOW3G initialization as
in section 4.4. */
IV[3] = count;
IV[2] = fresh;
IV[1] = count ^ (dir << 31);
IV[0] = fresh ^ (dir << 15);
z[0] = z[1] = z[2] = z[3] = z[4] = 0;
/* Run SNOW 3G to produce 5 keystream words z_1, z_2, z_3, z_4 and z_5. */
s3g_initialize(state_ptr, K, IV);
s3g_generate_keystream(state_ptr, 5, z);
s3g_deinitialize(state_ptr);
P = (uint64_t)z[0] << 32 | (uint64_t)z[1];
Q = (uint64_t)z[2] << 32 | (uint64_t)z[3];
/* Calculation */
if ((length % 64) == 0)
D = (length >> 6) + 1;
else
D = (length >> 6) + 2;
EVAL = 0;
c = 0x1b;
/* for 0 <= i <= D-3 */
for (i = 0; i < D - 2; i++) {
V = EVAL ^ ((uint64_t)data[8 * i] << 56 | (uint64_t)data[8 * i + 1] << 48 | (uint64_t)data[8 * i + 2] << 40 |
(uint64_t)data[8 * i + 3] << 32 | (uint64_t)data[8 * i + 4] << 24 | (uint64_t)data[8 * i + 5] << 16 |
(uint64_t)data[8 * i + 6] << 8 | (uint64_t)data[8 * i + 7]);
EVAL = s3g_MUL64(V, P, c);
}
/* for D-2 */
rem_bits = length % 64;
if (rem_bits == 0)
rem_bits = 64;
M_D_2 = 0;
i = 0;
while (rem_bits > 7) {
M_D_2 |= (uint64_t)data[8 * (D - 2) + i] << (8 * (7 - i));
rem_bits -= 8;
i++;
}
if (rem_bits > 0)
M_D_2 |= (uint64_t)(data[8 * (D - 2) + i] & mask8bit(rem_bits)) << (8 * (7 - i));
V = EVAL ^ M_D_2;
EVAL = s3g_MUL64(V, P, c);
/* for D-1 */
EVAL ^= length;
/* Multiply by Q */
EVAL = s3g_MUL64(EVAL, Q, c);
/* XOR with z_5: this is a modification to the reference C code,
which forgot to XOR z[5] */
for (i = 0; i < 4; i++)
/*
MAC_I[i] = (mac32 >> (8*(3-i))) & 0xff;
*/
MAC_I[i] = ((EVAL >> (56 - (i * 8))) ^ (z[4] >> (24 - (i * 8)))) & 0xff;
return MAC_I;
}