6
ADVANCED ENCRYPTION STANDARD

ASIF UR RAHMAN, SAEF ULLAH MIAH, AND SAIFUL AZAD

Contents

Keywords

6.1 Overview

6.2 History

6.3 Design Consideration

6.4 Primitive Operations of AES

6.5 Structure of AES

6.6 Overview of Key Expansion

6.7 Key Expansion Example

6.8 Encryption

6.9 An Encryption Example

6.10 Decryption

6.11 Limitations

6.12 Pros and Cons of AES

6.13 Implementation

6.14 Conclusion

Keywords

Advanced Encryption Standard

Block cipher

6.1 Overview

The Advanced Encryption Standard (AES) is a renowned symmetric key algorithm that utilizes a same secret key to encrypt and decrypt a message. It overcomes the limitation of the smaller key size of the Data Encryption Standard (DES) by utilizing a bigger and variable-length key that may take 149 trillion years to crack (assuming a machine could try 255 keys per second—National Institute of Standards and Technology [NIST]). Moreover, it also resolves the slow processing speed of Triple DES (3DES) and utilizes lower resources than that. Therefore, it is preferred as the encryption and decryption standard by the U.S. government. This standard is described in Federal Information Processing Standard (FIPS). AES is now being used worldwide for encrypting digital information, including financial, telecommunications, and government data.

AES supports secret keys of length 128, 192, or 256 bits to encrypt and decrypt a data block of 128 bits. Like other block cipher techniques, it is based on permutations and substitutions. Its design supports implementation in both hardware and software. Moreover, it is royalty-free to use, unlike some commercial encryption algorithms.

6.2 History

Because of the limitations of the previous encryption standard (i.e., DES), the NIST was searching for a new symmetric block cipher technique that could be considered a more robust replacement. In the new proposed technique, it was looking for a cipher that could support multiple key sizes (i.e., key lengths), capable of running efficiently in both hardware and software, and also have a good defense mechanism against various attacking techniques. Thus, a process was initiated on January 2, 1997, where it published a Request for Comments (RFC) for the “Development of a Federal Information Processing Standard for Advanced Encryption Standard.” The entire selection process was fully made open to public scrutiny and comments, because full visibility of any process would ensure the best possible analysis of the designs.

In this flow of the process, NIST publicly called for nominees for the new algorithm on September 12, 1997. The first AES conference was held from August 20–23, 1998. At that conference NIST selected 15 candidates for the AES, which were then subjected to preliminary analysis by the world cryptographic community, including the National Security Agency (NSA). All the selected algorithms were presented, analyzed, and tested at the second AES conference, which was held on March 22–23, 1999. On August 9, 1999, NIST selected five algorithms for extensive analysis:

  1. MARS, submitted by a team from IBM

  2. RC6, submitted by RSA Security

  3. Rijndael, submitted by two Belgian cryptographers, Joan Daemen and Vincent Rijmen

  4. Serpent, submitted by Ross Anderson, Eli Biham, and Lars Knudsen

  5. Twofish, submitted by a team of researchers, including Bruce Schneier

Finally, on October 2, 2000, Rijndael, by Joan Daemen and Vincent Rijmen, was chosen as the Advanced Encryption Standard. On February 28, 2001, the algorithm was included in the publication of a draft by FIPS. Then it was open for public review for 90 days. After that, it was finally included in the Federal Register on December 6, 2001.

6.3 Design Consideration

One of the principal design goals of AES was to keep it simpler to implement in both hardware and software. Therefore, unlike DES, instead of operating on bits, it operates on bytes, which makes it easier to implement and explain. It works by repeating the same defined steps multiple times, which are called rounds. Each round consists of several processing steps, including one that utilizes an encryption/decryption subkey that is generated from the shared key. Since AES is an iterative symmetric block cipher, it shares a single secret key among the two communicating parties involved in encryption and decryption operations. The allowable key lengths in AES are 128, 192, and 256 bits. Every key is expanded so that a separate subkey(w[i, j], where i and j provide the byte range) could be utilized for every round. Number of rounds of AES generally depends on the key length. A relationship between key length, number of columns in a state, and number of rounds is mentioned in Table 6.1. For instance, if the key length (Nk) is 128 bits or 16 bytes or 4 words, the number of columns (Nb) would be 4 and only 10 rounds (Nr) are performed, where Nb = key length/32.

Table 6.1 Relationship between Key Lengths, Number of Columns in a State, and Total Number of Rounds in AES

KEY LENGTH (Nk) (1 WORD = 32 BITS/4 BYTES)

NUMBER OF COLUMNS IN STATE (Nb)

ROUNDS (Nr)

4

4

10

6

6

12

8

8

14

image

Figure 6.1 A state of 128-bit key AES, where Sr,c denotes a byte of the rth row and the cth column.

AES, as well as most of the encryption algorithms, is reversible, which means that for the steps performed to complete an encryption, similar steps could be followed to complete a decryption, but in reverse order. In the following section, a detailed description of the operations of AES is explained with examples.

6.4 Primitive Operations of AES

Internally, all the AES operations are performed on a two-dimensional array of bytes called the state. A state constitutes four rows and Nb (Table 6.1) number of columns. Hence, for a 128-bit key, a state consists of four rows and four columns, as depicted in Figure 6.1.

AES is based on five primitive operations:

  1. Exclusive disjunction/exclusive OR (XOR): Exclusive disjunction or exclusive or is a logical operation that outputs true whenever both inputs differ from each other (e.g., one is true and the other is false) (Table 6.2). It is symbolized by the prefix operator J and by the infix operators XOR, EOR, EXOR, , ⊕, , and .

  2. Substitution (SubByte): A byte is substituted by another byte. AES utilizes a lookup table, also known as S-box, to perform substitutions of encryption, and another S-box, also known as inverse S-box, for decryption. Both S-boxes are given in Tables 6.3 and 6.4, respectively. Each individual byte can be represented by two hex digits where the first (from right) digit represents row and the second digit represents column of the S-box lookup table in the case of encryption, and of the inverse S-box in the case of decryption. For instance, let us assume that {42} is a hexadecimal value that represents a byte. Here, 4 refers to row number and 2 refers to column number; the value over that location would substitute this value, i.e., {2C}.

    Table 6.2 XOR Truth Table

    INPUT

    OUTPUT

    0

    0

    0

    0

    1

    1

    1

    0

    1

    1

    1

    1

    Table 6.3 S-Box Lookup Table

    S-BOX VALUES

    SN

    0

    1

    2

    3

    4

    5

    6

    7

    8

    9

    A

    B

    C

    D

    E

    F

    0

    63

    7C

    77

    7B

    F2

    6B

    6F

    C5

    30

    01

    67

    2B

    FE

    D7

    AB

    76

    1

    CA

    82

    C9

    7D

    FA

    59

    47

    F0

    AD

    D4

    A2

    AF

    9C

    A4

    72

    C0

    2

    B7

    FD

    93

    26

    36

    3F

    F7

    CC

    34

    A5

    E5

    F1

    71

    D8

    31

    15

    3

    04

    C7

    23

    C3

    18

    96

    05

    9A

    07

    12

    80

    E2

    EB

    27

    B2

    75

    4

    09

    83

    2C

    1A

    1B

    6E

    5A

    A0

    52

    3B

    D6

    B3

    29

    E3

    2F

    84

    5

    53

    D1

    00

    ED

    20

    FC

    B1

    5B

    6A

    CB

    BE

    39

    4A

    4C

    58

    CF

    6

    D0

    EF

    AA

    FB

    43

    4D

    33

    85

    45

    F9

    02

    7F

    50

    3C

    9F

    A8

    7

    51

    A3

    40

    8F

    92

    9D

    38

    F5

    BC

    B6

    DA

    21

    10

    FF

    F3

    D2

    8

    CD

    0C

    13

    EC

    5F

    97

    44

    17

    C4

    A7

    7E

    3D

    64

    5D

    19

    73

    9

    60

    81

    4F

    DC

    22

    2A

    90

    88

    46

    EE

    B8

    14

    DE

    5E

    0B

    DB

    A

    E0

    32

    3A

    0A

    49

    06

    24

    5C

    C2

    D3

    AC

    62

    91

    95

    E4

    79

    B

    E7

    C8

    37

    6D

    8D

    D5

    4E

    A9

    6C

    56

    F4

    EA

    65

    7A

    AE

    08

    C

    BA

    78

    25

    2E

    1C

    A6

    B4

    C6

    E8

    DD

    74

    1F

    4B

    BD

    8B

    8A

    D

    70

    3E

    B5

    66

    48

    03

    F6

    0E

    61

    35

    57

    B9

    86

    C1

    1D

    9E

    E

    E1

    F8

    98

    11

    69

    D9

    8E

    94

    9B

    1E

    87

    E9

    CE

    55

    28

    DF

    F

    8C

    A1

    89

    0D

    BF

    E6

    42

    68

    41

    99

    2D

    0F

    B0

    54

    BB

    16

  3. Rotation (ShiftRows): A simple permutation is performed by rearranging of bytes through rotating a row by a fixed number of cells. It provides a diffusion by the cyclic left shift of the last three rows of the state by different offsets. Row 0 of the state is not shifted, row 1 is shifted 1 byte, row 2 is shifted 2 bytes, and row 3 is shifted 3 bytes. This operation is illustrated in Figure 6.2.

    Table 6.4 Inverse S-Box Lookup Table

    INVERSE S-BOX VALUES

    SN

    0

    1

    2

    3

    4

    5

    6

    7

    8

    9

    A

    B

    C

    D

    E

    F

    0

    52

    09

    6A

    D5

    30

    36

    A5

    38

    BF

    40

    A3

    9E

    81

    F3

    D7

    FB

    1

    7C

    E3

    39

    82

    9B

    2F

    FF

    87

    34

    8E

    43

    44

    C4

    DE

    E9

    CB

    2

    54

    7B

    94

    32

    A6

    C2

    23

    3D

    EE

    4C

    95

    0B

    42

    FA

    C3

    4E

    3

    08

    2E

    A1

    66

    28

    D9

    24

    B2

    76

    5B

    A2

    49

    6D

    8B

    D1

    25

    4

    72

    F8

    F6

    64

    86

    68

    98

    16

    D4

    A4

    5C

    CC

    5D

    65

    B6

    92

    5

    6C

    70

    48

    50

    FD

    ED

    B9

    DA

    5E

    15

    46

    57

    A7

    8D

    9D

    84

    6

    90

    D8

    AB

    00

    8C

    BC

    D3

    0A

    F7

    E4

    58

    05

    B8

    B3

    45

    06

    7

    D0

    2C

    1E

    8F

    CA

    3F

    0F

    02

    C1

    AF

    BD

    03

    01

    13

    8A

    6B

    8

    3A

    91

    11

    41

    4F

    67

    DC

    EA

    97

    F2

    CF

    CE

    F0

    B4

    E6

    73

    9

    96

    AC

    74

    22

    E7

    AD

    35

    85

    E2

    F9

    37

    E8

    1C

    75

    DF

    6E

    A

    47

    F1

    1A

    71

    1D

    29

    C5

    89

    6F

    B7

    62

    0E

    AA

    18

    BE

    1B

    B

    FC

    56

    3E

    4B

    C6

    D2

    79

    20

    9A

    DB

    C0

    FE

    78

    CD

    5A

    F4

    C

    1F

    DD

    A8

    33

    88

    07

    C7

    31

    B1

    12

    10

    59

    27

    80

    EC

    5F

    D

    60

    51

    7F

    A9

    19

    B5

    4A

    0D

    2D

    E5

    7A

    9F

    93

    C9

    9C

    EF

    E

    A0

    E0

    3B

    4D

    AE

    2A

    F5

    B0

    C8

    EB

    BB

    3C

    83

    53

    99

    61

    F

    17

    2B

    04

    7E

    BA

    77

    D6

    26

    E1

    69

    14

    63

    55

    21

    0C

    7D

    image

    Figure 6.2 Shift row operation of AES.

    In case of decryption, inverse shift rows (InvShiftRows) are performed, which follows a process similar to that of ShiftRows, only the shifting is done to the right.

  4. MixColumn: It operates on each column individually where a single byte of a column is mapped into a new value that is a function of all four bytes in that column. Each column of the state is replaced by multiplying with a 4 × Nb matrix in the Galois field 28, also denoted as GF(28). The mathematics behind this is beyond the scope of this book. An example matrix is given for 128-bit key in Figure 6.3.

    The first result byte is calculated by multiplying four values of the state column against four values of the first row of the matrix. The result of each multiplication is then XORed to produce 1 byte like below:

    S0,0 = (S0,0*2) XOR (S1,0*3) XOR (S2,0*1) XOR (S3,0*1)

    This procedure is repeated again with each byte of all columns of the state, until there is no more state column. As a result of this multiplication, the four bytes in the first column are replaced by the following:

    S0,0 = (S0,0*2) XOR (S1,0*3) XOR (S2,0*1) XOR (S3,0*1)

    S1,0 = (S0,0*1) XOR (S1,0*2) XOR (S2,0*3) XOR (S3,0*1)

    S2,0 = (S0,0*1) XOR (S1,0*1) XOR (S2,0*2) XOR (S3,0*3)

    S3,0 = (S0,0*3) XOR (S1,0*1) XOR (S2,0*1) XOR (S3,0*2)

    This multiplication value also could be achieved using a two-table lookup represented in hexadecimal numbers and indexed with a hexadecimal digit. They are called the L-Table and E-Table and are given in Tables 6.5 and 6.6, respectively.

    The result of the multiplication could be found from the L lookup table, followed by the addition of the results (+, not a bitwise AND), followed by a lookup to the E-table. The numbers being multiplied are 1 byte each and are represented in two hexadecimal digits. The first digit is used as row index and the last digit as column index of the L-table. Then, two values acquired from the L-table are added, which results in another byte. The resultant byte is used to look up from E-table, following a procedure similar to that of the L-table. For instance, let us assume that the two hex values being multiplied are 87*02. First, we have to look up the L-table to find out the substitution values, i.e., 74 and 19. Then, add the two acquired values together, which is 8D in this example. If the added value is greater than FF, then FF needs to be subtracted from the added value. The final step is to look up the addition result on the E-table. Note that any number multiplied by 1 is equal to itself and does not need to go through the above-mentioned procedure, e.g., 87*1 = 87.

    image

    Figure 6.3 128-bit key state and its multiplication matrix.

    Table 6.5 L-Table

    L-TABLE

    SN

    0

    1

    2

    3

    4

    5

    6

    7

    8

    9

    A

    B

    C

    D

    E

    F

    0

     

    00

    19

    01

    32

    02

    1A

    C6

    4B

    C7

    1B

    68

    33

    E

    DF

    03

    1

    64

    04

    E0

    0E

    34

    8D

    81

    EF

    4C

    71

    08

    C8

    F8

    69

    1C

    C1

    2

    7D

    C2

    1D

    B5

    F9

    B9

    27

    6A

    4D

    E4

    A6

    72

    9A

    C9

    09

    78

    3

    65

    2F

    8A

    05

    21

    0F

    E1

    24

    12

    F0

    82

    45

    35

    93

    DA

    8E

    4

    96

    8F

    DB

    BD

    36

    D0

    CE

    94

    13

    5C

    D2

    F1

    40

    46

    83

    38

    5

    66

    DD

    FD

    30

    BF

    06

    8B

    62

    B3

    25

    E2

    98

    22

    88

    91

    10

    6

    7E

    6E

    48

    C3

    A3

    B6

    1E

    42

    3A

    6B

    28

    54

    FA

    85

    3D

    BA

    7

    2B

    79

    0A

    15

    9B

    9F

    5E

    CA

    4E

    D4

    AC

    E5

    F3

    73

    A7

    57

    8

    AF

    58

    A8

    50

    F4

    EA

    D6

    74

    4F

    AE

    E9

    D5

    E7

    E6

    AD

    E8

    9

    2C

    D7

    75

    7A

    EB

    16

    0B

    F5

    59

    CB

    5F

    B0

    9C

    A9

    51

    A0

    A

    7F

    0C

    F6

    6F

    17

    C4

    49

    EC

    D8

    43

    1F

    2D

    A4

    76

    7B

    B7

    B

    CC

    BB

    3E

    5A

    FB

    60

    B1

    86

    3B

    52

    A1

    6C

    AA

    55

    29

    9D

    C

    97

    B2

    87

    90

    61

    BE

    DC

    FC

    BC

    95

    CF

    CD

    37

    3F

    5B

    D1

    D

    53

    39

    84

    3C

    41

    A2

    6D

    47

    14

    2A

    9E

    5D

    56

    F2

    D3

    AB

    E

    44

    11

    92

    D9

    23

    20

    2E

    89

    B4

    7C

    B8

    26

    77

    99

    E3

    A5

    F

    67

    4A

    ED

    DE

    C5

    31

    FE

    18

    0D

    63

    8C

    80

    C0

    F7

    70

    07

    Table 6.6 E-Table

    E-TABLE

    SN

    0

    1

    2

    3

    4

    5

    6

    7

    8

    9

    A

    B

    C

    D

    E

    F

    0

    01

    03

    05

    0F

    11

    33

    55

    FF

    1A

    2E

    72

    96

    A1

    F8

    13

    35

    1

    5F

    E1

    38

    48

    D8

    73

    95

    A4

    F7

    02

    06

    0A

    1E

    22

    66

    AA

    2

    E5

    34

    5C

    E4

    37

    59

    EB

    26

    6A

    BE

    D9

    70

    90

    AB

    E6

    31

    3

    53

    F5

    04

    0C

    14

    3C

    44

    CC

    4F

    D1

    68

    B8

    D3

    6E

    B2

    CD

    4

    4C

    D4

    67

    A9

    E0

    3B

    4D

    D7

    62

    A6

    F1

    08

    18

    28

    78

    88

    5

    83

    9E

    B9

    D0

    6B

    BD

    DC

    7F

    81

    98

    B3

    CE

    49

    DB

    76

    9A

    6

    B5

    C4

    57

    F9

    10

    30

    50

    F0

    0B

    1D

    27

    69

    BB

    D6

    61

    A3

    7

    FE

    19

    2B

    7D

    87

    92

    AD

    EC

    2F

    71

    93

    AE

    E9

    20

    60

    A0

    8

    FB

    16

    3A

    4E

    D2

    6D

    B7

    C2

    5D

    E7

    32

    56

    FA

    15

    3F

    41

    9

    C3

    5E

    E2

    3D

    47

    C9

    40

    C0

    5B

    ED

    2C

    74

    9C

    BF

    DA

    75

    A

    9F

    BA

    D5

    64

    AC

    EF

    2A

    7E

    82

    9D

    BC

    DF

    7A

    8E

    89

    80

    B

    9B

    B6

    C1

    58

    E8

    23

    65

    AF

    EA

    25

    6F

    B1

    C8

    43

    C5

    54

    C

    FC

    1F

    21

    63

    A5

    F4

    07

    09

    1B

    2D

    77

    99

    B0

    CB

    46

    CA

    D

    45

    CF

    4A

    DE

    79

    8B

    86

    91

    A8

    E3

    3E

    42

    C6

    51

    F3

    0E

    E

    12

    36

    5A

    EE

    29

    7B

    8D

    8C

    8F

    8A

    85

    94

    A7

    F2

    0D

    17

    F

    39

    4B

    DD

    7C

    84

    97

    A2

    FD

    1C

    24

    6C

    B4

    C7

    52

    F6

    01

    An example of MixColumn during encryption is given below:

    Input = 87 6E 46 A6

    S0,0 = (87*2) XOR (6E*3) XOR (46*1) XOR (A6*1)

    = E(L(87) + L(02)) XOR E(L(6E) + L(03)) XOR 46 XOR A6

    = E(8D) XOR E(3E) XOR 46 XOR A6

    = 15 XOR B2 XOR 46 XOR A6

    = 47

    Similarly, one can calculate the other values of the state. In the case of decryption, the inverse mix column (InvMixColumn) technique is utilized, which follows the same process as MixColumn, but multiplications are performed on a different multiplication matrix. InvMixColumn utilizes the multiplication matrix shown in Table 6.7.

    Table 6.7 Inverse Multiplication Matrix

    0E

    0B

    0D

    09

    09

    0E

    0B

    0D

    0D

    09

    0E

    0B

    0B

    0D

    09

    0E

    image

    Figure 6.4 Add round key function.

  5. AddRoundKey: This is a simple operation where each byte of the state is XORed with each byte of the round key, which is a portion of the expanded key. In the next section, a detailed description of the key expansion technique of AES is elaborated. Figure 6.4 illustrates the technique of AddRoundKey transformation.

6.5 Structure of AES

The basic encryption and decryption structure of AES is illustrated in Figure 6.5. Here, a 128-bit key length is considered. Therefore, both encryption and decryption must go through 10 rounds before producing the desired output. There are 12 rounds for a 192-bit key and 14 rounds for a 256-bit key. It can be observed from the figure that every round generally performs four operations: (1) SubBytes/InvSubBytes, (2) ShiftRows/InvShiftRows, (3) MixColumns/InvMixColumns, and (4) AddRoundKey. One of them is permutation and the other three are substitutions. However, the final round comprises only three operations, excluding MixColumns/InvMixColumns. The expanded key is only utilized by the AddRoundKey operations. Each operation is easily reversible, thus making it easy to implement in both hardware and software. Similar to most of the block ciphers, the decryption algorithm utilizes the key in reverse order.

6.6 Overview of Key Expansion

As mentioned earlier, since AES supports symmetric key, a secret key must be shared between the two parties. AES provides flexibility regarding selecting a key length. A key could be 128, 192, or 256 bits long. Since every round utilizes a new subkey, prior to encryption or decryption, the key must be expanded according to the number of rounds. This process is called key expansion.

image

Figure 6.5 AES encryption and decryption techniques.

The key expansion routine takes an input key of size Nk and produces a linear array of size, Nb × (Nr + 1), where a number of columns in states is (Nb) and the number of rounds (Nr) depends on key length (Nk).

For instance, Nr is 10 when Nk is 4, which is illustrated in Table 6.1. Let us denote a word in the expanded key as w[i], where i is the ith word of that key. Algorithm 6.1 shows a key expansion algorithm.

Algorithm 6.1: KeyExpansion(key)

Begin
        word temp;
        for i ← 0 to (Nk - 1)
              w[i] ← (unsigned char) key[4*i] << 24) |
                     ((unsigned char) key[4*i+1] << 16) |
                     ((unsigned char) key[4*i+2]<<8) |
                     ((unsigned char) key[4*i+3]);
        end for

        for i ← (Nk - 1) to Nb × Nr
              temp = w[i-1];
              if (imodNk = = 0)
                    temp = SubWord(RotWord(temp))
                    (Rcon[i/Nk] << 24);
              else if(Nk> 6 and(i mod Nk) = = 4)
                     temp = SubWord(temp);
              end if
              w[i] = w[i-Nk] ⊕ temp;
        end for
End

From Algorithm 6.1, we can easily identify the functions necessary for the expanding key:

  1. RotWord: This function does a circular shift on 4 bytes, similar to the shift row function, e.g., 0, 1, 2, 3 to 1, 2, 3, 0.

  2. SubWord: It does a similar transformation, which is described in the SubByte operation. It utilizes the S-box table to substitute a byte.

  3. XOR with round constant (Rcon): For every round in key expansion, the result acquired from function 1 and function 2 is XORed with a round constant value Rcon[i]. These values are shown in Table 6.8.

Table 6.8 Rounds and Their Respective Constants

Round[j]

1

2

3

4

5

6

7

8

9

10

Rcon[j]

01

02

04

08

10

20

40

80

1B

36

6.7 Key Expansion Example

Let us assume that the secret key shared between two parties is aes 128 pass key, which is 128 bits long. Therefore, Nk is 4, Nb is 4, and Nr is 10 for this key length. A hexadecimal representation of the key is shown in Figure 6.6.

This key is utilized to expand the key to Nb × (Nr + 1) bytes, which is 44 bytes in this example. A detailed description of the steps is presented in previous sections. In this section, we demonstrate how the round key for the first round, i.e., w[4, 7], can be calculated while w[0, 3] is given. From Figure 6.6, we get

w[0] = 1A91F720

w[1] = 5E456706

w[2] = A25B66DE

w[3] = 5F145988

W[I]

W[I – 1] OR TEMP

AFTER ROTWORD

AFTER SUBWORD

RCON[I]

AFTER XOR WITH RCON[I]

W[I – 4]

W[I] = TEMP XOR W[I – 4]

4

5F145988

1459885F

FACBC4CF

1000000

EACBC4CF

1A91F720

E15A33EF

5

E15A33EF

5A33EFE1

BEC3DFF8

1000000

AEC3DFF8

5E456706

BF1F54E9

6

BF1F54E9

1F54E9BF

C0201E08

1000000

D0201E08

A25B66DE

1D443237

7

1D443237

4432371D

1B2394A4

1000000

0B2394A4

5F145988

42506BBF

By repeating the similar procedures, the remaining words of the expanded key are generated.

6.8 Encryption

In AES, a plaintext has to travel through Nr number of rounds before producing the cipher. Again, each round comprises four different operations. One operation is permutation and the other three are substitutions. They are (1) SubBytes, (2) ShiftRows, (3) MixColumns, and (4) AddRoundKey. All these operations are detailed previously. Algorithm 6.2 gives a high-level description of the encryption algorithm.

image

Figure 6.6 Hex value representations of the secret key.

Algorithm 6.2: Encryption (PlainText)

Begin
          State = plainText
          1. KeyExpansion
          2. AddRoundKey (State, ExpandedKey[0])
          3. for r ← 1 to (Nr - 1)
                a. SubBytes (State, S-box)
                b. ShiftRows (State)
                c. MixColumns (State)
                d. AddRoundKey (State, ExpandedKey[r])
          end for
          4. SubBytes (State, S-box)
          5. ShiftRows (State)
          6. AddRoundKey (State, ExpandedKey[Nr])
          Out = CipherText
End

6.9 An Encryption Example

Let us assume that the plaintext we are going to encrypt is string 2 encrypt using the key stated in Section 6.7. To encrypt, this string is copied to the state, and hexadecimal representations are given in Figure 6.7.

The steps of various rounds with their corresponding values are portrayed in tabular format in Table 6.9.

6.10 Decryption

The decryption routine takes the encrypted string/state as input or output of the encryption routine and performs a reverse operation.

image

Figure 6.7 Hex value representations of plaintext.

Table 6.9 Steps of the AES Encryption

ROUND NUMBER

START OF A ROUND

AFTER SUBBYTES

AFTER SHIFTROWS

AFTER MIXCOLUMNS

ROUND KEY VALUE

ROUND OUTPUT

INP

736E2072

 

 

 

1A5EA25F

6930822D

 

74676579

 

 

 

91455B14

E5223E6D

 

72206E70

 

 

 

F7676659

85470829

 

69326374

 

 

 

2006DE88

4934BDFC

1

6930822D

F90413D8

F90413D8

C75BED01

E1BF1D42

26E4F043

 

E5223E6D

D993B23C

93B23CD9

24B4D1F0

5A1F4450

7EAB95A0

 

85470829

97A03095

30A597A0

C1AA32D4

3354326B

F2FE00BF

 

4934BDFC

3B187AB0

B03B187A

C86DAEFE

EFE937BF

27849941

2

26E4F043

F7698C1A

F7698C1A

B368EE6F

B00F1250

0367FC3F

 

7EAB95A0

F3622AE0

622AE0F3

15E988DF

253A7E2E

30D3F6F1

 

F2FE00BF

89BB6308

630889BB

CD1C84AD

3B6F5D36

F673D99B

 

27849941

CC5FEE83

83CC5FEE

1E1A58A1

C32A1DA2

DD304503

3

0367FC3F

7B85B075

7B85B075

1202C507

858A98C8

97885DCF

 

30D3F6F1

046642A1

6642A104

93FC2B99

201A644A

B3E64FD3

 

F673D99B

428F3514

3514428F

FAB799C6

016E3305

FBD9AAC3

 

DD304503

C1046E7B

7BC1046E

285B20C8

90BAA705

B8E187CD

4

97885DCF

88C44C8A

88C44C8A

9346C59A

5BD14981

C8978C1B

 

B3E64FD3

6D8E8466

8E84666D

DDC96918

4B51357F

96985C67

 

FBD9AAC3

0F35AC2E

AC2E0F35

99A827B4

6A043732

F3AC1086

 

B8E187CD

6CF817BD

BD6CF817

C02556F3

78C26560

B8E73393

5

C8978C1B

E88864AF

E88864AF

17FDC5BC

99480180

8EB5C43C

 

96985C67

90464A85

464A8590

FDBCF6FF

68390C73

9585FA8C

 

F3AC1086

0D91CA44

CA440D91

5EFE5C58

BABE89BB

E440D5E3

 

B8E73393

6C94C3DC

DC6C94C3

0C551776

74B6D3B3

78E3C4C5

6

8EB5C43C

19D51CEB

19D51CEB

356BECA6

367E7FFF

03159359

 

9585FA8C

2A972D64

972D642A

8F007EB8

82BBB7C4

0DBBC97C

 

E440D5E3

69090311

03116909

790599F7

D769E05B

AE6C79AC

 

78E3C4C5

BC111CA6

A6BC111C

E83B0B3D

B90FDC6F

5134D752

7

03159359

7B59DCCB

7B59DCCB

658E6FB1

6A146B94

0F9A0425

 

0DBBC97C

D7EADD10

EADD10D7

7581D380

BB00B773

CE8164F3

 

AE6C79AC

E450B691

B691E450

E6D537AE

7F16F6AD

99C3C103

 

5134D752

D1180E00

00D1180E

D11EBBDD

AFA07C13

7EBEC7CE

8

0F9A0425

76B8F23F

76B8F23F

0B26A810

65711A8E

6E57B29E

 

CE8164F3

8B0C430D

0C430D8B

6D406F86

2E2E99EA

436EF66C

 

99C3C103

EE2E787B

787BEE2E

0C03D1B9

0214E24F

0E1733F6

 

7EBEC7CE

F3AEC68B

8BF3AEC6

E316A973

8D2D5142

6E3BF831

9

6E57B29E

9F5B370B

9F5B370B

9BADD789

F988921C

62254595

 

436EF66C

1A9F4250

9F42501A

23869375

AA841DF7

89028E82

 

0E1733F6

ABF0C342

C342ABF0

CF271729

2E3AD897

E11DCFBE

 

6E3BF831

9FE241C7

C79FE241

73C87D75

94B9E8AA

E77195DF

10

62254595

AA3F6E2A

AA3F6E2A

 

A72FBDA1

0D10D38B

 

89028E82

A7771913

771913A7

 

22A6BB4C

55BFA8EB

 

E11DCFBE

F8A48AAE

8AAEF8A4

 

82B860F7

08169853

 

E77195DF

94A32A9E

9E94A32A

 

08B159F3

9625FAD9

Ciphertext: 0D 10 D3 8B 55 BF A8 EB 08 16 98 53 96 25 FA D9.

The state value of each step will be the opposite of the encryption state value. Again, a higher-level description of the decryption algorithm is given in Algorithm 6.3.

Algorithm 6.3: Decryption (CipherText)

Begin
        State = CipherText
        1. KeyExpansion
        2. AddRoundKey (State, ExpandedKey[0])
        3. for r ← (Nr - 1) to 1
              a. InverseShiftRows (State)
              b. InverseSubBytes (State, S-box)
              c. AddRoundKey (State, ExpandedKey[r])
              d. InverseMixColumns (State)
        end for
        4. InverseSubBytes (State, S-box)
        5. InverseShiftRows (State)
        6. AddRoundKey (State, ExpandedKey[Nr])
        out = PlainText
End

6.11 Limitations

In our implementation, there is no restriction on key selection; no weak or semiweak key has been identified for this AES implementation. The implementation here covers only electronic code block (ECB) encryption mode.

6.12 Pros and Cons of AES

Actually, AES has many pros rather than noticeable cons. As AES was developed after DES, all known attacks on DES have been tested on AES, and all the test results were satisfactory. AES is more secure to brute-force attack than DES because of its larger key size. AES is not prone to statistical attacks, and it has been demonstrated that it is not possible with common techniques to do statistical analysis of ciphertext in AES. As yet, there are no differential and linear attacks on AES. The best part of AES is that the algorithms used in it are so simple that they can be easily implemented using cheap processors and a minimum amount of memory.

On the other hand, AES needs more processing and more rounds of communication than DES, and we can hardly tell this is AES’s disadvantage.

6.13 Implementation

#include<iostream>
#include<vector>
#include<fstream>
#include<string>
#include<sstream>
using namespace std;

#define word unsigned int
#define byte unsigned char

class AES
{
    vector<word> ExpandedKey;
    int Nk,//width of key block
        Nr,//number of round
        Nb;//block size
    static const byte S_Box 256];
    static const byte Si_Box 256];
    static const byte Rcon[30];
    static const byte ColMixMatrix[4][4];
    static const byte InvColMixMatrix[4][4];
    static const byte AlogTable[256];
    static const byte LogTable[256];
    string cipherText;
    byte state[4][4];

    #ifdef _KEY_TEST_
        fstream in;

    #endif

    #ifdef _TEST_STATE_
        fstream stest_fin;
    #endif

    byte Mul(byte a, byte b);
    void   MixColumns();
    void   ShiftRows();
    void   SubBytes();
    byte   SubByte(byte oneByte);
    word   SubWord(word val);
    word   RotWord(word val);

    void   InvMixColumns();
    void   InvShiftRows();
    byte   InvSubByte(byte oneByte);
    void   InvSubBytes();

    void AddRoundKey(int roundNo);
    void KeyExpansion(string key);
    string ToString();

public:
    static enum KeySize {AES128 = 128, AES192 = 192,
    AES256 = 256};

    AES(string key, int bitSize);
    ~AES();
    void Encrypt(string plainText);
    string GetCipherText();
    void Decrypt(string cipherText);
};

#include"AES.h"

    byte AES::Mul(byte a, byte b)
    {
       if(a && b)
                   return AlogTable[((unsigned char)
                   LogTable[a] + (unsigned char)
                   LogTable[b])%255];
       return 0;
    }

       void AES::InvMixColumns()
       {
         byte temp[4];
         for(int c = 0; c < Nb; c ++)
         {
             //4 rows and Nb columns to store temp mix
               col value
             for(int r = 0; r < 4; r ++)
             {
                temp[r] = Mul(InvColMixMatrix[r][0],
                         (state[0][c]) )
                         ^ Mul(InvColMixMatrix[r]
                           [1],(state[1][c]))
                         ^ Mul(InvColMixMatrix[r]
                           [2],(state[2][c]))
                         ^ Mul(InvColMixMatrix[r]
                           [3],(state[3][c]));
             }

             state[0][c]     =   temp[0];
             state[1][c]     =   temp[1];
             state[2][c]     =   temp[2];
             state[3][c]     =   temp[3];
     }
}

    void AES::MixColumns()
    {
      byte temp[4];
      for(int c = 0; c < Nb; c ++)
      {
         //4 rows and Nb columns to store temp mix
         //col value
         for(int r = 0; r < 4; r ++)
         {
             temp[r] = Mul(ColMixMatrix[r][0],
                       (state[0][c]) )
                       ^ Mul(ColMixMatrix[r]
                         [1],(state[1][c]))
                       ^ Mul(ColMixMatrix[r]
                         [2],(state[2][c]))
                       ^ Mul(ColMixMatrix[r]
                         [3],(state[3][c]));
         }

         state[0][c]     =   temp[0];
         state[1][c]     =   temp[1];
         state[2][c]     =   temp[2];
         state[3][c]     =   temp[3];
    }
}
void AES::InvShiftRows()
{
     //row is always 4
     for(int r = 0; r < 4; r ++)
     {
        byte temp[4];

        temp[0]   =   state[r][0];
        temp[1]   =   state[r][1];
        temp[2]   =   state[r][2];
        temp[3]   =   state[r][3];

        for(int c = 0; c < Nb; c ++)
        {
           state[r][(r+c)% Nb] = temp[c];
        }

    }

}

void AES::ShiftRows()
{
     //row is always 4
     for(int r = 0; r < 4; r ++)
     {
         byte temp[4];
         for(int c = 0; c < Nb; c ++)
         {
             temp[c] = state[r][(r+c)% Nb];
         }
         //temp[0] = state[r][(r+0)% Nb];
         //temp[1] = state[r][(r+1) % Nb];
         //temp[2] = state[r][(r+2) % Nb];
         //temp[3] = state[r][(r+3) % Nb];

         state[r][0]     =   temp[0];
         state[r][1]     =   temp[1];
         state[r][2]     =   temp[2];
         state[r][3]     =   temp[3];
     }

}

byte AES::InvSubByte(byte oneByte)
{
     //one byte represent in hex (xy) x is row
     //index and y is column index
     return Si_Box[oneByte];
}

void AES::InvSubBytes()
{
   for(int i = 0; i < 4; i ++)
   {
      for(int j = 0; j < Nb; j ++)
      {
          state[i][j] = InvSubByte(state[i][j]);
      }
   }
}

void AES::SubBytes()
{
    for(int i = 0; i < 4; i ++)
    {
        for(int j = 0; j < Nb; j ++)
        {
            state[i][j] = SubByte(state[i][j]);
        }
    }
}

byte AES::SubByte(byte oneByte)
{
    //one byte represent in hex (xy) x is row
    //index and y is column index
      return S_Box[oneByte];
}

word AES::SubWord(word val)
{
    byte oneByte;
    word res = 0;
    for(int i = 0; i< 4; i ++)
    {
        res = res << 8;
        oneByte = (val >> 24) & 0xFF;
        res = res | SubByte(oneByte);
        val = val << 8;
    }
      return res;
}

word AES::RotWord(word val)
{
     word res = val << 8;
     res = res | (val >> 24);
     return res;
}

void AES::AddRoundKey(int roundNo)
{

   for(int col = 0; col < Nb; col++)
   {

       word roundKeyVal = ExpandedKey
       [(roundNo*Nb)+col];
       for(int row = 3; row > = 0; row— )
       {

           state[row][col] ^ = (roundKeyVal &0xFF);
           roundKeyVal = roundKeyVal >> 8;
       }
   }
}
AES::~AES()
{
    #ifdef _KEY_TEST_
       if(in)
       {
          in.close();
       }
    #endif
    #ifdef _TEST_STATE_
       if(stest_fin)
           stest_fin.close();
    #endif
}

AES::AES(string key, int bitSize)
{
     Nr = bitSize/32 + 6;
     Nk = bitSize/32;
     Nb = 4;//always 4
     ExpandedKey.resize(Nk*(Nr+1));

     #ifdef _TEST_STATE_
         stest_fin.open("128_enc_test.txt",ios::in);
         if(!stest_fin )
         {
            cout << "Cannot not open" << endl;
            exit(1);
         }
    #endif//_Debug_
    #ifdef _KEY_TEST_
        in.open("128_key_test.txt",ios::in);
        if(!in )
        {
           cout << "Cannot not open" << endl;
           exit(1);
        }
   #endif//_Debug_
   KeyExpansion(key);

}
void AES::KeyExpansion(string key)
{
    word temp;
    for(int i = 0; i < Nk; i ++)
    {
        ExpandedKey [i] = ((unsigned char) key[4*i]
        << 24) |
                            ((unsigned char)
                            key[4*i+1] << 16) |
                            ((unsigned char)
                            key[4*i+2]<<8) |
                            ((unsigned char)
                            key[4*i+3]);
            cout << hex << ExpandedKey[i] << endl;
    }
    for(int i = Nk; i < Nb*(Nr+1); i++)
    {
        temp = ExpandedKey[i-1];
        if(i% Nk = = 0)
        {
            temp = SubWord(RotWord(temp)) ^
            (Rcon[i/Nk] << 24);
        }
        else if(Nk >6 && i%Nk = = 4)
      {
         temp = SubWord(temp);
      }
      ExpandedKey[i] = ExpandedKey[i-Nk] ^ temp;

      #ifdef _KEY_TEST_
                int x;
                string inpHexVal;
                std::stringstream exKeyHexVal;
                in >> x >> inpHexVal;
                exKeyHexVal << hex <<
                ExpandedKey[i];
                if(x == i && inpHexVal ==
                exKeyHexVal.str() && 0)
                     cout << i << " : ok " << endl;
                else
                {
                     temp = ExpandedKey[i-1];
                     if(i% Nk = = 0)
                     {
                           ofstream out ("keyval.
                           txt", ios::app);
                           out << dec <<i << ":not
                           ok:" << endl;
                           out << "temp:" <<hex <<
                           temp << endl;
                           out << "rot:" <<hex <<
                           RotWord(temp) << endl;
                           out << "sub:" <<hex <<
                           SubWord(RotWord(temp))
                           << endl;
                           out << "After xor
                           Rcon:" <<hex <<
                           (SubWord(RotWord
                           (temp))^ (Rcon[i/Nk] <<
                           24)) << endl;
                           out << "Rcon :" <<hex
                           << (Rcon[i/Nk] <<24) <<
                           endl;
                           out << "W[i-nk] :"
                           <<hex <<
                           ExpandedKey[i-Nk] <<
                           endl;
                           out << "final :" <<hex
                           << ExpandedKey[i]
                           << " and " << inpHexVal
                           <<", "<<exKeyHexVal.
                           str() << endl <<endl <<
                           endl;
                           out.close();
                     }
                     else if(Nk >6 && i%Nk = = 4)
                     {
                           ofstream out ("keyval.
                           txt", ios::app);
                           out << i << ": not ok:"
                           << endl;
                           out << "temp : " <<hex
                           << temp << endl;
                           out << "sub : " <<hex
                           << SubWord(temp) <<
                           endl;
                           out << "final :" <<hex
                           << ExpandedKey[i] <<
                           endl <<endl << endl;
                           out.close();
                     }
                     else
                     {
                           ofstream out ("keyval.
                           txt", ios::app);
                           out << dec <<i <<
                           " : not ok : " << endl;
                           out << "temp : " <<hex
                           << temp << endl;
                           out << "W[i-nk] : "
                           <<hex <<
                           ExpandedKey[i-Nk] <<
                           endl;
                           out << "final :" <<hex
                           << ExpandedKey[i] <<
                           " and " << inpHexVal
                           <<", "<<exKeyHexVal.
                           str() << endl <<endl <<
                           endl;
                     }
                  }
        #endif//_DEBUG_
    }
}
#ifdef _DEBUG_
   void printState()
   {
      ofstream out("enc_step.txt",ios::app);
      for(int i = 0; i< 4; i ++)
      {
          for(int j = 0; j < Nb; j++)
          {
                out << hex << (int)
                state[i][j] <<" ";
          }
          out << endl;
       }
       out << endl << endl;
          }
      #endif// _DEBUG_
      #ifdef _TEST_STATE_
          void testState(int round)
          {
             cout << round << endl;
             for(int i = 0; i< 4; i ++)
             {
                 int x;
                 stest_fin >> x;
                 for(int j = 0; j < Nb; j++)
                 {
                        string inpHexVal;
                        std::stringstream exKeyHexVal;
                        stest_fin >> inpHexVal;
                        exKeyHexVal << hex << (int)
                        state[i][j];

                        if(x = = round && inpHexVal = =
                        exKeyHexVal.str())
                             cout << " ok ";
                        else
                        {
                             cout << " not ok " <<
                             inpHexVal << " " <<
                             exKeyHexVal.str() << endl;
                        }
                 }
                 cout << endl;
             }
             cout << endl << endl;
    }
#endif//_TEST_STATE_

void AES::Encrypt(string plainText)
{
    if((plainText.length()% (4*Nb)) ! = 0)
        plainText.append((4*Nb) - (plainText.
        length()%(4*Nb)),''),
    int count = 0;
    while (count < (plainText.length()))
    {
        //copy one block into state
        for(int c = 0; c <Nb; c++)
        {
            for(int r = 0; r< 4; r ++)
                  state[r][c] =
                  plainText[count+(c*Nb)+r];
        }
        AddRoundKey(0);

       #ifdef _DEBUG_
           cout << "After Add round Key 0" << endl;
           printState();
       #endif//_DEBUG_
           int i;
       for(i = 1; i < Nr; i ++)
       {

           #ifdef _TEST_STATE_
                 cout << i << endl;
                 testState(i);
           #endif//_TEST_STATE_
           SubBytes();
           #ifdef _DEBUG_
                 cout << "After Subbytes "<< dec<<
                 i << endl;
                 printState();
           #endif//_DEBUG_

           ShiftRows();
           #ifdef _DEBUG_
                 cout << "After ShifRows "<< dec<<
                 i << endl;
                 printState();
           #endif//_DEBUG_
                 MixColumns();
                 #ifdef _DEBUG_
                       cout << "After MixColumns "<<
                       dec<< i << endl;
                       printState();
                 #endif//_DEBUG_

                 AddRoundKey(i);
                 #ifdef _DEBUG_
                       cout << "Add round Key " << i <<
                       endl;
                       printState();
                 #endif//_DEBUG_
                       //exit (1);
             }

                 SubBytes();
                 #ifdef _DEBUG_
                       cout << "Round Subbytes"<< dec<<
                       i << endl;
                       printState();
                 #endif//_DEBUG_

                 ShiftRows();
                 #ifdef _DEBUG_
                       cout << "Round ShiftRows"<< dec<<
                       i << endl;
                       printState();
                 #endif//_DEBUG_
                 AddRoundKey(Nr);
                 #ifdef _DEBUG_
                       cout << "Add round Key " << i <<
                       endl;
                       printState();
                 #endif//_DEBUG_
                 #ifdef _TEST_STATE_
                       //testState(i);
                       printState();
                 #endif//_TEST_STATE_
                 cipherText = cipherText + ToString();
                 count+ = 4*Nb;
             }
      }
      string AES::GetCipherText()
      {
         return cipherText;
}
string AES::ToString()
{
    string str;
    for(int c = 0;c<Nb; c ++)
    {
        for(int r = 0; r< Nb; r++)
        {
            str.push_back(state[r][c]);
        }
    }
    return str;
}

void AES::Decrypt(string cipherText)
{
    if((cipherText.length()% (4*Nb)) ! = 0)
        cipherText.append((4*Nb) - (cipherText.
        length()%(4*Nb)),''),
    int count = 0;
    while (count < (cipherText.length()))
    {
        //copy one block into state
        for(int c = 0; c <Nb; c++)
        {
            for(int r = 0; r< 4; r ++)
                  state[r][c] =
                  cipherText[count+(c*Nb)+r];
        }
        AddRoundKey(Nr);
        #ifdef _DEBUG_D_
            cout << "After Add round Key 0" << endl;
            printState();
        #endif//_DEBUG_
            int i;
        for(i = Nr-1; i>0; i— )
        {
            #ifdef _TEST_STATE_
                   cout << i << endl;
                   testState(i);
            #endif//_TEST_STATE_
            InvShiftRows();
            #ifdef _DEBUG_D_
                 cout << "After ShiftRows "<< dec<<
                 i << endl;
                 printState();
           #endif//_DEBUG_
           InvSubBytes();
           #ifdef _DEBUG_D_
                 cout << "After Subbytes "<< dec<<
                 i << endl;
                 printState();
           #endif//_DEBUG_
           AddRoundKey(i);
           #ifdef _DEBUG_D_
                 cout << "Add round Key " << i <<
                 endl;
                 printState();
           #endif//_DEBUG_
           InvMixColumns();
           #ifdef _DEBUG_D_
                 cout << "After MixColumns "<<
                 dec<< i << endl;
                 printState();
           #endif//_DEBUG_
       }
           InvSubBytes();
           #ifdef _DEBUG_D_
                 cout << "Round Subbytes"<< dec<<
                 i << endl;
                 printState();
           #endif//_DEBUG_
           InvShiftRows();
           #ifdef _DEBUG_D_
                 cout << "Round ShiftRows"<< dec<<
                 i << endl;
                 printState();
           #endif//_DEBUG_
           AddRoundKey(0);
           #ifdef _DEBUG_D_
                 cout << "Add round Key " << i <<
                 endl;
                 printState();
           #endif//_DEBUG_
           #ifdef _TEST_STATE_
                 //testState(i);
                 printState();
           #endif//_TEST_STATE_
            count+ = 4*Nb;
        }
    }

const byte AES::LogTable[256] = {
    0, 0, 25, 1, 50, 2, 26, 198, 75, 199, 27, 104, 51,
    238, 223, 3,
    100, 4, 224, 14, 52, 141, 129, 239, 76, 113, 8,
    200, 248, 105, 28, 193,
    125, 194, 29, 181, 249, 185, 39, 106, 77, 228, 166,
    114, 154, 201, 9, 120,
    101, 47, 138, 5, 33, 15, 225, 36, 18, 240, 130, 69,
    53, 147, 218, 142,
    150, 143, 219, 189, 54, 208, 206, 148, 19, 92, 210,
    241, 64, 70, 131, 56,
    102, 221, 253, 48, 191, 6, 139, 98, 179, 37, 226,
    152, 34, 136, 145, 16,
    126, 110, 72, 195, 163, 182, 30, 66, 58, 107, 40,
    84, 250, 133, 61, 186,
    43, 121, 10, 21, 155, 159, 94, 202, 78, 212, 172,
    229, 243, 115, 167, 87,
    175, 88, 168, 80, 244, 234, 214, 116, 79, 174, 233,
    213, 231, 230, 173, 232,
    44, 215, 117, 122, 235, 22, 11, 245, 89, 203, 95,
    176, 156, 169, 81, 160,
    127, 12, 246, 111, 23, 196, 73, 236, 216, 67, 31,
    45, 164, 118, 123, 183,
    204, 187, 62, 90, 251, 96, 177, 134, 59, 82, 161,
    108, 170, 85, 41, 157,
    151, 178, 135, 144, 97, 190, 220, 252, 188, 149,
    207, 205, 55, 63, 91, 209,
    83, 57, 132, 60, 65, 162, 109, 71, 20, 42, 158, 93,
    86, 242, 211, 171,
    68, 17, 146, 217, 35, 32, 46, 137, 180, 124, 184,
    38, 119, 153, 227, 165,
    103, 74, 237, 222, 197, 49, 254, 24, 13, 99, 140,
    128, 192, 247, 112, 7
};

const byte AES::AlogTable[256] =
{
    1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150,
    161, 248, 19, 53,
    95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10,
    30, 34, 102, 170,
    229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217,
    112, 144, 171, 230, 49,
    83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184,
    211, 110, 178, 205,
    76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241,
    8, 24, 40, 120, 136,
    131, 158, 185, 208, 107, 189, 220, 127, 129, 152,
    179, 206, 73, 219, 118, 154,
    181, 196, 87, 249, 16, 48, 80, 240, 11, 29, 39,
    105, 187, 214, 97, 163,
    254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147,
    174, 233, 32, 96, 160,
    251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50,
    86, 250, 21, 63, 65,
    195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 44,
    116, 156, 191, 218, 117,
    159, 186, 213, 100, 172, 239, 42, 126, 130, 157,
    188, 223, 122, 142, 137, 128,
    155, 182, 193, 88, 232, 35, 101, 175, 234, 37, 111,
    177, 200, 67, 197, 84,
    252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153,
    176, 203, 70, 202,
    69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62,
    66, 198, 81, 243, 14,
    18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133,
    148, 167, 242, 13, 23,
    57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108,
    180, 199, 82, 246, 1
};

const byte AES::Si_Box 256] =
{
    82, 9, 106, -43, 48, 54, -91, 56, -65, 64, -93,
    -98, -127, -13, -41, -5,
    124, -29, 57, -126, -101, 47, -1, -121, 52, -114,
    67, 68, -60, -34, -23, -53,
    84, 123, -108, 50, -90, -62, 35, 61, -18, 76, -107,
    11, 66, -6, -61, 78,
    8, 46, -95, 102, 40, -39, 36, -78, 118, 91, -94,
    73, 109, -117, -47, 37,
    114, -8, -10, 100, -122, 104, -104, 22, -44, -92,
    92, -52, 93, 101, -74, -110,
    108, 112, 72, 80, -3, -19, -71, -38, 94, 21, 70,
    87, -89, -115, -99, -124,
    -112, -40, -85, 0, -116, -68, -45, 10, -9, -28, 88,
    5, -72, -77, 69, 6,
    -48, 44, 30, -113, -54, 63, 15, 2, -63, -81, -67,
    3, 1, 19, -118, 107,
    58, -111, 17, 65, 79, 103, -36, -22, -105, -14,
    -49, -50, -16, -76, -26, 115,
    -106, -84, 116, 34, -25, -83, 53, -123, -30, -7,
    55, -24, 28, 117, -33, 110,
    71, -15, 26, 113, 29, 41, -59, -119, 111, -73, 98,
    14, -86, 24, -66, 27,
    -4, 86, 62, 75, -58, -46, 121, 32, -102, -37, -64,
    -2, 120, -51, 90, -12,
    31, -35, -88, 51, -120, 7, -57, 49, -79, 18, 16,
    89, 39, -128, -20, 95,
    96, 81, 127, -87, 25, -75, 74, 13, 45, -27, 122,
    -97, -109, -55, -100, -17,
    -96, -32, 59, 77, -82, 42, -11, -80, -56, -21, -69,
    60, -125, 83, -103, 97,
    23, 43, 4, 126, -70, 119, -42, 38, -31, 105, 20,
    99, 85, 33, 12, 125
};

const byte AES::S_Box 256] =
{
    99, 124, 119, 123, -14, 107, 111, -59, 48, 1, 103,
    43, -2, -41, -85, 118,
    -54, -126, -55, 125, -6, 89, 71, -16, -83, -44,
    -94, -81, -100, -92, 114, -64,
    -73, -3, -109, 38, 54, 63, -9, -52, 52, -91, -27,
    -15, 113, -40, 49, 21,
    4, -57, 35, -61, 24, -106, 5, -102, 7, 18, -128,
    -30, -21, 39, -78, 117,
    9, -125, 44, 26, 27, 110, 90, -96, 82, 59, -42,
    -77, 41, -29, 47, -124,
    83, -47, 0, -19, 32, -4, -79, 91, 106, -53, -66,
    57, 74, 76, 88, -49,
    -48, -17, -86, -5, 67, 77, 51, -123, 69, -7, 2,
    127, 80, 60, -97, -88,
    81, -93, 64, -113, -110, -99, 56, -11, -68, -74,
    -38, 33, 16, -1, -13, -46,
    -51, 12, 19, -20, 95, -105, 68, 23, -60, -89, 126,
    61, 100, 93, 25, 115,
    96, -127, 79, -36, 34, 42, -112, -120, 70, -18,
    -72, 20, -34, 94, 11, -37,
    -32, 50, 58, 10, 73, 6, 36, 92, -62, -45, -84, 98,
    -111, -107, -28, 121,
    -25, -56, 55, 109, -115, -43, 78, -87, 108, 86,
    -12, -22, 101, 122, -82, 8,
    -70, 120, 37, 46, 28, -90, -76, -58, -24, -35, 116,
    31, 75, -67, -117, -118,
    112, 62, -75, 102, 72, 3, -10, 14, 97, 53, 87, -71,
    -122, -63, 29, -98,
    -31, -8, -104, 17, 105, -39, -114, -108, -101, 30,
    -121, -23, -50, 85, 40, -33,
    -116, -95, -119, 13, -65, -26, 66, 104, 65, -103,
    45, 15, -80, 84, -69, 22
};

const byte AES::Rcon[30] =
{
    0,1, 2, 4, 8, 16, 32,
    64, -128, 27, 54, 108, -40,
    -85, 77, -102, 47, 94, -68,
    99, -58, -105, 53, 106, -44,
    -77, 125, -6, -17, -59
};

const byte AES::ColMixMatrix[4][4] =
              {
                     2, 3,1, 1,
                     1, 2, 3, 1,
                     1, 1, 2, 3,
                     3, 1, 1, 2
              };

const byte AES::InvColMixMatrix[4][4] =
              {
                     0x0E, 0x0B,0x0D, 0x09,
                     0x09, 0x0E, 0x0B, 0x0D,
                     0x0D, 0x09, 0x0E, 0x0B,
                     0x0b, 0x0D, 0x09, 0x0E
              };

#include "AES.h"

int main(void)
{
    //////////////////////
    ///Keys test vector
    //////////////////////
    //128
    //char a[] = {0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0
      xa6,0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0
      x3c,''};
      char a[] = {0x1a,0x91,0xf7,0x20,0x5e,0x45,0x67,0
      x06,0xa2,0x5b,0x66,0xde,0x5f,0x14,0x59
      ,0x88,''};
    //192
    //char a[] = {0x8e,0x73,0xb0,0xf7,0xda,0x0e,0x64,0
      x52,0xc8,0x10,0xf3,0x2b,0x80,0x90,0x79,0xe5,0x62
      ,0xf8,0xea,0xd2,0x52,0x2c,0x6b,0x7b,''};
    //256
    //char a[] = {0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0
      xbe,0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81,0x1f
      ,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7,0x2d,0x98,0x
      10,0xa3,0x09,0x14,0xdf,0xf4,''};
    /////////////////////
    //Plain Text test vector
    ////////////////////
    //char b[] = {0x32,0x43,0xf6,0xa8,0x88,0x5a,0x30,0
      x8d,0x31,0x31,0x98,0xa2,0xe0,0x37,0x07
      ,0x34,''};
    //73, 74, 72. 69, 6e, 67, 20. 32, 20, 65,
      6e,6372797074
      char b[] = {0x73, 0x74, 0x72,0x69, 0x6e, 0x67,
      0x20, 0x32, 0x20, 0x65, 0x6e, 0x63, 0x72, 0x79,
      0x70, 0x74};

      string key;
      string text;

      for(int i = 0; i < 16;i++)
      {
          key.push_back(a[i]);
          text.push_back(b[i]);
      }
      AES obj (key, AES::KeySize::AES128);

       //obj.KeyExpansion(key);
       obj.Encrypt(text);
       obj.Decrypt(obj.GetCipherText());
    return 0;
}

6.14 Conclusion

AES was chosen as the new standard for several reasons. The purpose was to create a new algorithm that is resistant to known attacks and more reliable, as well as faster and simpler, than the existing ones, while also being implemented easily with hardware and software, including restricted environments. It is very clear that AES has satisfied all the conditions with its simple and easy implementation without compromising the security aspect. AES is more versatile, with its variable key size and block size. It was originally designed for nonclassified U.S. government information, but due to its success, AES-256 is usable for top secret government information. As of today, no successful attack on AES has been detected. This reflects how successful AES is in its categories.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.206.25