A HARDWARE IMPLEMENTATION OF THE ADVANCED ENCRYPTION STANDARD (AES) ALGORITHM USING SYSTEMVERILOG Bahram Hakhamaneshi B.S., Islamic Azad University, Iran, 2004 PROJECT Submitted in partial satisfaction of the requirements for the degree of MASTER OF SCIENCE in COMPUTER ENGINEERING at CALIFORNIA STATE UNIVERSITY, SACRAMENTO FALL 2009
A HARDWARE IMPLEMENTATION OF THE ADVANCED ENCRYPTION STANDARD (AES) ALGORITHM USING SYSTEMVERILOG A Project by Bahram Hakhamaneshi Approved by:, Committee Chair Dr. Behnam Arad Date, Second Reader Dr. Isaac Ghansah Date ii
Student: Bahram Hakhamaneshi I certify that this student has met the requirements for format contained in the University format manual, and that this project is suitable for shelving in the Library and credit is to be awarded for the Project., Graduate Coordinator Dr. Suresh Vadhva Date Department of Computer Engineering iii
Abstract of A HARDWARE IMPLEMENTATION OF THE ADVANCED ENCRYPTION STANDARD (AES) ALGORITHM USING SYSTEMVERILOG by Bahram Hakhamaneshi The increasing need for protecting data communication in computer networks has led to development of several cryptography algorithms. The Advanced Encryption Standard (AES) is a computer security standard issued by the National Institute of Standards and Technology (NIST) intended for protecting electronic data. Its specification is defined in Federal Information Processing Standards (FIPS) Publication 197. The AES cryptography algorithm can be used to encrypt/decrypt blocks of 128 bits and is capable of using cipher keys of 128, 196 or 256 bits wide (AES128, AES196, and AES256). The Advanced Encryption Standard can be implemented in either software or hardware. Hardware acceleration is the use of hardware to perform a task more efficiently than is possible in software. In order to achieve higher performance in today s heavily loaded communication networks, utilization of hardware accelerators for cryptography algorithms is more efficient. iv
In this project, a hardware implementation of the AES128 encryption algorithm was proposed. A unique feature of the proposed pipelined design is that the round keys, which are consumed during different iterations of encryption, are generated in parallel with the encryption process. This lowers the delay associated with each round of encryption and reduces the overall encryption delay of a plaintext block. This leads to an increase in the message encryption throughput. The proposed pipelined design was modeled and validated in SystemVerilog hardware description language. The testbench developed for validating the design kept track of Functional Coverage to make sure the design is thoroughly verified. The design was validated using the Synopsys VCS tool and synthesized using the Synopsys Design- Compiler tool. The gate level netlist generated during the synthesis phase using the LSI_10K technology library was capable of operating at 40MHz frequency. We expect the timing and area of the gate level netlist to improve if a more efficient technology library file is used for synthesis. Finally, to get an estimate of the speed gain by the hardware implementation, a virtual system was created using the Virtutech Simics software to emulate the execution of a C program that implements the AES128 encryption in software. The Simics virtual system utilized in this project is based on Intel s x86 architecture with the 440BX chipset and has a 2GHz Pentium4 processor. v
The statistics gathered from the virtual system showed that it would take more than 30,000 CPU cycles to encrypt a block of plaintext, assuming one clock per instruction. The results indicate that the hardware implementation proposed in this project is at least 60 times faster than the software implementation., Committee Chair Dr. Behnam Arad Date vi
To Mom and Dad whom I love the most in the world vii
ACKNOWLEDGMENTS I would like to say thanks to Dr. Behnam Arad and Dr. Isaac Ghansah for their help with defining and concluding this project. This project could not have reached this far without their guidance and assistance. I also want to give special thanks to them for reviewing this report and proofreading it in the very short time that was left before submission deadline. I also would like to thank my family, either those who were close or far away, for encouraging and supporting me during the course of this project and all my life. viii
TABLE OF CONTENTS Page Dedication..vii Acknowledgments viii List of Tables.. xi List of Figures.... xii Chapter 1. INTRODUCTION. 1 2. ADVANCED ENCRYPTION STANDARD (AES). 5 2.1 Overview.... 5 2.2 Inputs, Outputs and the State. 6 2.3 Cipher Transformations 9 2.3.1 SubBytes ( ) Transformation 11 2.3.2 ShiftRows ( ) Transformation... 13 2.3.3 MixColumns ( ) Transformation... 13 2.3.4 AddRoundKey ( ) Transformation... 15 2.4 AES Key Expansion.... 16 3. AES128 DESIGN AND IMPLEMENTATION.. 19 3.1 Overview.......19 3.2 Design Hierarchy........20 3.2.1 AES128 Encryption Process.21 3.2.2 AES128 Round Key Generation... 22 3.3 AES128 Pipelined Design 25 ix
4. AES128 VERIFICATION... 27 4.1 Overview.. 27 4.2 Testbench Infrastructure... 27 4.3 AES128_Interface 29 4.4 AES128_Program 31 5. AES128 SYNTHESIS. 36 5.1 Overview..36 5.2 Synthesis Methodology 37 5.3 Synthesis Timing Result... 40 5.4 Synthesis Area Result... 42 5.5 Synthesis Constraint Violators Result.. 43 6. AES128 SOFTWARE IMPLEMENTATION.....44 6.1 Overview... 44 6.2 AES128 Software Implementation on a Simics Virtual System... 44 7. CONCLUSION........48 Appendix A: AES128 Hardware Model Source Files... 52 Appendix B: AES128 Testbench Source Files.. 68 Appendix C: AES128 Simulation Results. 75 Appendix D: AES128 Implementation in C Language 102 References....107 x
LIST OF TABLES Page 1. Table 1 AES Variations 7 2. Table 2 AES S-box. 12 3. Table 3 Simics Virtual System Statistics 47 xi
LIST OF FIGURES Page 1. Figure 1 State Population and Results.8 2. Figure 2 AES Cipher.. 10 3. Figure 3 SubBytes Transformation 11 4. Figure 4 ShiftRows Transformation.. 13 5. Figure 5 MixColumns Transformation... 15 6. Figure 6 AddRoundKey Transformation...16 7. Figure 7 KeyExpansion Algorithm......17 8. Figure 8 Design Hierarchy..... 20 9. Figure 9 AES128_Cipher_Top Module State Diagram.... 22 10. Figure 10 AES128_Key_Expand Module State Diagram. 23 11. Figure 11 AES128_Key_Expand Module.... 24 12. Figure 12 AES128_Rcon Module. 25 13. Figure 13 AES128 Pipelined Round Key Generation and Cipher Rounds... 26 14. Figure 14 AES128 Test Infrastructure... 28 15. Figure 15 AES128_Top Definition....29 16. Figure 16 AES128_Interface Definition... 30 17. Figure 17 Class Definition in the AES128_Program.32 18. Figure 18 AES128_Program Pseudo Code.... 33 19. Figure 19 AES128_Testbench_Package Pseudo Code.. 34 20. Figure 20 Sample Simulation Results 35 21. Figure 21 AES128 Block Encryption Pseudo Code in C... 46 xii
1 Chapter 1 INTRODUCTION In today s digital world, encryption is emerging as a disintegrable part of all communication networks and information processing systems, for protecting both stored and in transit data. Encryption is the transformation of plain data (known as plaintext) into unintelligible data (known as ciphertext) through an algorithm referred to as cipher. There are numerous encryption algorithms that are now commonly used in computation, but the U.S. government has adopted the Advanced Encryption Standard (AES) to be used by Federal departments and agencies for protecting sensitive information. The National Institute of Standards and Technology (NIST) has published the specifications of this encryption standard in the Federal Information Processing Standards (FIPS) Publication 197. [1] Any conventional symmetric cipher, such as AES, requires a single key for both encryption and decryption, which is independent of the plaintext and the cipher itself. It should be impractical to retrieve the plaintext solely based on the ciphertext and the encryption algorithm, without knowing the encryption key. Thus, the secrecy of the encryption key is of high importance in symmetric ciphers such as AES. Software implementation of encryption algorithms does not provide ultimate secrecy of the key since the operating system, on which the encryption software runs, is always vulnerable to attacks.
2 There are other important drawbacks in software implementation of any encryption algorithm, including lack of CPU instructions operating on very large operands, word size mismatch on different operating systems and less parallelism in software. In addition, software implementation does not fulfill the required speed for time critical encryption applications. Thus, hardware implementation of encryption algorithms is an important alternative, since it provides ultimate secrecy of the encryption key, faster speed and more efficiency through higher levels of parallelism. Different versions of AES algorithm exist today (AES128, AES196, and AES256) depending on the size of the encryption key. In this project, a hardware model for implementing the AES128 algorithm was developed using the SystemVerilog hardware description language. A unique feature of the design proposed in this project is that the round keys, which are consumed during different iterations of encryption, are generated in parallel with the encryption process. The hardware model was then completely verified using a testbench, which took advantage of the SystemVerilog s object oriented programming (OOP) feature, by constructing random test objects and providing them to the model. The validation process continued until the model was verified for a certain Functional Coverage. Then, the verified model was synthesized using the Synopsis Design-Compiler tool to get an estimate of the number of gates, area and timing of the hardware model.
3 In addition, the AES128 algorithm was modeled in C language and was ported on a Simics virtual system. The statistics of the Simics virtual system was gathered to get an estimate of the time it would take to encrypt a plaintext block on the virtual system. Finally, the performances of software and hardware implementations were compared. The rest of the report is organized into six chapters. Chapter 2 covers an overview of the AES encryption algorithm and different version of it. In this chapter, different types of transformations and steps that are involved in the AES encryption process are introduced. Chapter 3 discusses the design and modeling of the hardware implementation of the AES128 encryption algorithm by explaining the modules used in the design hierarchy, their interconnections and state diagrams. Chapter 4 covers the verification of the hardware model. In this chapter, a test infrastructure is developed which fully validates the design. The testbench generates random input test vectors for the hardware model and validates its functionality until a certain Functional Coverage is met. Chapter 5 covers the synthesis of the hardware model using the Synopsys Design Compiler synthesis tool. In this chapter, a script is developed to synthesize the design
4 into a gate-level netlist using the LSI_10K library file. The synthesis result, including the timing and area of the netlist comes at the end of this chapter. Chapter 6 covers the software implementation of the AES128 algorithm (in C language) and porting it on a Simics virtual system. In addition, the software and hardware implementation are compared based on the time it takes to encrypt a block of plaintext. Finally, in Chapter 7, the research work is summarized and potential improvements and suggestions of future works for this project are included.
5 Chapter 2 ADVANCED ENCRYPTION STANDARD (AES) 2.1 Overview This chapter is a summary of the Federal Information Processing Standards (FIPS) Publication 197 [1], issued by the National Institute of Standards and Technology (NIST) which specifies the Advanced Encryption Standard. Throughout the remainder of this chapter, the mathematical properties of the Advanced Encryption Standard (AES) are introduced using the information obtained from the AES specification. The AES is a subset of a much larger encryption algorithm known as Rijndael, which was one of many proposals to the NIST competing for becoming a standard encryption algorithm. On October of 2000, the NIST announced the Rijndael algorithm as the winner due to the best overall score in security, performance, efficiency, implementation capability and simplicity. [2] The AES algorithm is a symmetric cipher. In symmetric ciphers, a single secret key is used for both the encryption and decryption, whereas in asymmetric ciphers, there are two sets of keys known as private and public keys. The plaintext is encrypted using the public key and can only be decrypted using the private key.
6 In addition, the AES algorithm is a block cipher as it operates on fixed-length groups of bits (blocks), whereas in stream ciphers, the plaintext bits are encrypted one at a time, and the set of transformations applied to successive bits may vary during the encryption process. The AES algorithm operates on blocks of 128 bits, by using cipher keys with lengths of 128, 192 or 256 bits for the encryption process. Although the original Rijndael encryption algorithm was capable of processing different blocks sizes as well as using several other cipher key lengths, but the NIST did not adopt these additional features in the AES. [1] 2.2 Inputs, Outputs and the State The plaintext input and ciphertext output for the AES algorithms are blocks of 128 bits. The cipher key input is a sequence of 128, 192 or 256 bits. In other words the length of the cipher key, N k, is either 4, 6 or 8 words which represent the number of columns in the cipher key. The AES algorithm is categorized into three versions based on the cipher key length. The number of rounds of encryption for each AES version depends on the cipher key size. In the AES algorithm, the number of rounds is represented by N r, where N r = 10 when N k = 4, N r = 12 when N k = 6, and N r = 14 when N k = 8. The following table
7 illustrated the variations of the AES algorithm. For the AES algorithm the block size (N b ), which represents the number of columns comprising the State is N b = 4. AES Version Key Length (N k words) Block Size (N b words) Number of Rounds (N r rounds) AES128 4 4 10 AES192 6 4 12 AES256 8 4 14 Table 1 AES Variations The basic processing unit for the AES algorithm is a byte. As a result, the plaintext, ciphertext and the cipher key are arranged and processed as arrays of bytes. For an input, an output or a cipher key denoted by a, the bytes in the resulting array are referenced as a n, where n is in one of the following ranges: Block length = 128 bits, 0 <= n < 16 Key length = 128 bits, 0 <= n < 16 Key length = 192 bits, 0 <= n < 24 Key length = 256 bits, 0 <= n < 24
8 All byte values in the AES algorithm are presented as the concatenation of their individual bit values between braces in the order {b7, b6, b5, b4, b3, b2, b1, b0}. These bytes are interpreted as finite field elements using a polynomial representation: b 7 x 7 + b 6 x 6 + b 5 x 5 + b 4 x 4 + b 3 x 3 + b 2 x + b x 1 + b 0 x = 7 i= 0 b i x i As an example, {10001001} (or {85} in hexadecimal) identifies the polynomial 7 3 x + x + 1. The arrays of bytes in the AES algorithm are represented as a a1a2... an 0. All the AES algorithm operations are performed on a two dimensional 4x4 array of bytes which is called the State, and any individual byte within the State is referred to as s r,c, where letter r represent the row and letter c denotes the column. At the beginning of the encryption process, the State is populated with the plaintext. Then the cipher performs a set of substitutions and permutations on the State. After the cipher operations are conducted on the State, the final value of the state is copied to the ciphertext output as is shown in the following figure. in 0 in 4 in 8 in 12 in 1 in 5 in 9 in 13 in 2 in 6 in 10 in 14 in 3 in 7 in 11 in 15 s 0,0 s 0,1 s 0,2 s 0,3 s 1,0 s 1,1 s 1,2 s 1,3 s 2,0 s 2,1 s 2,2 s 2,3 s 3,0 s 3,1 s 3,2 s 3,3 out 0 out 4 out 8 out 12 out 1 out 5 out 9 out 13 out 2 out 6 out 10 out 14 out 3 out 7 out 11 out 15 Figure 1 State Population and Results
9 At the beginning of the cipher, the input array is copied into the State according the following scheme: s[r,c] = in [r + 4c] for 0 r < 4 and 0 c < 4, and at the end of the cipher the State is copied into the output array as shown below: out[r+4c] = s[r,c] for 0 r < 4 and 0 c < 4 2.3 Cipher Transformations The AES cipher either operates on individual bytes of the State or an entire row/column. At the start of the cipher, the input is copied into the State as described in Section 2.2. Then, an initial Round Key addition is performed on the State. Round keys are derived from the cipher key using the Key Expansion routine. The key expansion routine generates a series of round keys for each round of transformations that are performed on the State. The transformations performed on the state are similar among all AES versions but the number of transformation rounds depends on the cipher key length. The final round in all AES versions differs slightly from the first N r 1 rounds as it has one less transformation performed on the State. Each round of AES cipher (except the last one) consists of all the following transformation: - SubBytes( ) - ShiftRows( )
10 - MixColumns( ) - AddRoundKey ( ) The AES cipher is described as a pseudo code in Figure 2. [1] As shown in the pseudo code, all the N r rounds are identical with the exception of the final round which does not include the MixColumns transformation. The array w[] represents the round keys that are generated by the key expansion routine. In the following sections, individual transformations that are used in each encryption round are described. Cipher(byte PlainText[4*N b ], byte CipherText[4*N b ], word w[n b *(N r +1)]) begin byte state[4,n b ] state = in AddRoundKey(state, w[0, N b -1]) for round = 1 step 1 to N r 1 SubBytes(state) ShiftRows(state) MixColumns(state) AddRoundKey(state, w[round*n b, (round+1)*n b -1]) end for SubBytes(state) ShiftRows(state) AddRoundKey(state, w[n r *N b, (N r +1)*N b -1]) out = state end Figure 2 AES Cipher
11 2.3.1 - SubBytes ( ) Transformation The SubBytes is a byte substitution operation performed on individual bytes of the State, as shown in Figure 3, using a substitution table called S-box. s 0,0 s 0,1 s 0,2 s 0,3 s 1,0 s 1,1 s 1,2 s 1,3 s 2,0 s 2,1 s 2,2 s 2,3 s 3,0 s 3,1 s 3,2 s 3,3 s 0,0 s 0,1 s 0,2 s 0,3 s 1,0 s 1,1 s 1,2 s 1,3 s 2,0 s 2,1 s 2,2 s 2,3 s 3,0 s 3,1 s 3,2 s 3,3 Figure 3 SubBytes Transformation The invertible S-box table is constructed by performing the following transformation on each byte of the State. [1] - Take the multiplicative inverse in the finite field GF(2 8 ) of the byte. - Apply the following transformation to the byte: b ' i = bi b( i+ 4) mod 8 b( i+ 5) mod 8 b( i+ 6) mod 8 b( i+ 7) mod 8 c i The b i is the i th bit of the byte and c i is the i th bit of a constant byte with the value of {63}. The combination of the two transformations can be expressed in matrix form as shown below:
12 + = 0 1 1 0 0 0 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 0 0 0 0 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 0 0 0 1 7 6 5 4 3 2 1 0 ' 7 ' 6 ' 5 ' 4 ' 3 ' 2 ' 1 ' 0 b b b b b b b b b b b b b b b b The S-box table shown in Table 2 is constructed by performing the two transformations described earlier for all possible values of a byte, ranging from {00} to {ff}. For example the substitution value for {53} would be determined by the intersection of the row with index 5 and the column with index 3. Y 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 X F 8c a1 89 0d bf e6 42 68 41 99 2d 0f b0 54 bb 16 Table 2 AES S-box
13 2.3.2 - ShiftRows ( ) Transformation The ShiftRows transformation cyclically shifts the last three rows of the state by different offsets. The first row is left unchanged in this transformation. Each byte of the second row is shifted one position to the left. The third and fourth rows are shifted left by two and three positions, respectively. The ShiftRows transformation is illustrated in Figure 4. s 0,0 s 0,1 s 0,2 s 0,3 s 1,0 s 1,1 s 1,2 s 1,3 s 2,0 s 2,1 s 2,2 s 2,3 s 3,0 s 3,1 s 3,2 s 3,3 s 0,0 s 0,1 s 0,2 s 0,3 s 1,1 s 1,2 s 1,3 s 1,0 s 2,2 s 2,3 s 2,0 s 2,1 s 3,3 s 3,0 s 3,1 s 3,2 Figure 4 ShiftRows Transformation 2.3.3 MixColumns ( ) Transformation This transformation operates on the columns of the State, treating each columns as a four term polynomial the finite field GF(2 8 ). Each columns is multiplied modulo x 4 +1 with a fixed four-term polynomial a(x) = {03}x 3 + {01}x 2 + {01}x + {02} over the
GF(2 8 ). The MixColumns transformation can be expressed as a matrix multiplication as shown below: 14 ' s ' s ' s ' s 0, c 1, c 2, c 3, c 02 = 01 01 03 03 02 01 01 01 03 02 01 01 s 01 s 03 s 02 s 0, c 0, c 0, c 0, c The MixColumns transformation replaces the four bytes of the processed column with the following values: ' s 0, c = ({ 02} s0, c ) ({03} s1, c ) s2, c s3, c ' s 1, c = s0, c ({ 02} s1, c ) ({03} s2, c ) s3, c s s = s s ({ 02} s2, c ) ({03} s3, ) ' 0, c 0, c 1, c c = ({ 03} s0, c s1, c ) s2, c ({02} s3, ) ' 1, c c The corresponds to the multiplication of polynomials in GF(2 8 ) modulo an irreducible polynomial of degree 8. A polynomial is irreducible if its only divisors are one and itself. For the AES algorithm the irreducible polynomial is: m(x) = x 8 + x 4 + x 3 + x +1.[1]
15 The MixColumns transformation is illustrated in Figure 5. This transformation together with ShiftRows, provide substantial diffusion in the cipher meaning that the result of the cipher depends on the cipher inputs in a very complex way. In other words, in a cipher with a good diffusion, a single bit change in the plaintext will completely change the ciphertext in an unpredictable manner. s 0,0 s 0,1 s 0,2 s 0,3 s 1,0 s 1,1 s 1,2 s 1,3 s 2,0 s 2,1 s 2,2 s 2,3 s 3,0 s 3,1 s 3,2 s 3,3 s 0,0 s 0,1 s 0,2 s 0,3 s 1,1 s 1,2 s 1,3 s 1,0 s 2,2 s 2,3 s 2,0 s 2,1 s 3,3 s 3,0 s 3,1 s 3,2 Figure 5 MixColumns Transformation 2.3.4 AddRoundKey ( ) Transformation During the AddRoundKey transformation, the round key values are added to the State by means of a simple Exclusive Or (XOR) operation. Each round key consists of N b words that are generated from the KeyExpansion routine. The round key values are added to the columns of the state in the following way:
' ' ' ' [ s, s, s ] [ s, s, s s ] [ w ], for 0 c < N b s 0, c 1, c 2, c 3, c = 0, c 1, c 2, c, 3, c round* Nb+ c 16 In the equation above, the round value is between 0 round N. When round=0, the cipher key itself is used as the round key and it corresponds to the initial AddRoundKey transformation displayed in the pseudo code in Figure 2. The AddRoundKey transformation is illustrated in Figure 6. r s 0,0 s 0,1 s 0,2 s 0,3 s 1,0 s 1,1 s 1,2 s 1,3 s 2,0 s 2,1 s 2,2 s 2,3 s 3,0 s 3,1 s 3,2 s 3,3 s 0,0 s 0,1 s 0,2 s 0,3 s 1,1 s 1,2 s 1,3 s 1,0 s 2,2 s 2,3 s 2,0 s 2,1 s 3,3 s 3,0 s 3,1 s 3,2 Figure 6 AddRoundKey Transformation 2.4 AES Key Expansion The AES algorithm requires four words of round keys for each encryption round. That is total of 4*(N r + 1) round keys considering the initial set of keys required for the first AddRoundKey transformation. All the round keys are derived from the cipher key itself.
17 According to the Federal Information Processing Standards (FIPS) Publication 197 [1], there is no restriction on the cipher key selection, as no week cipher key has been identified for the AES algorithm. The expansion of the cipher key into the round keys is performed by the KeyExpansion algorithm as shown in the pseudo code in Figure 7. [1] KeyExpansion(byte CipherKey[4*N k ], word w[n b *(N r +1)], N k ) begin word temp i = 0 while (i < N k ) w[i] = word(key[4*i], key[4*i+1], key[4*i+2], key[4*i+3]) i = i+1 end while i = N k while (i < N b * (N r +1)] temp = w[i-1] if (i mod N k = 0) temp = SubWord(RotWord(temp)) xor Rcon[i/N k ] else if (N k > 6 and i mod N k = 4) temp = SubWord(temp) end if w[i] = w[i-n k ] xor temp i = i + 1 end while end Figure 7 KeyExpansion Algorithm In the above pseudo code, the array w[] represents the round keys that are generated by the KeyExpansion routine and N k represents the size of the cipher key. Depending on the version of the AES algorithm, N k =4, 6 or 8. The first N k words of the expanded key are filled with the cipher key.
18 The SubWord( ) function applies the same S-box substitution to each of the four bytes in the word. The RotWord( ) function takes a word [a0,a1,a2,a3] as input and perform a cyclic shift and returns the word [a1,a2,a3,a0]. The round constant word array, Rcon[i], contains a 32 bit value given by [{02} i-1,{00},{00},{00}]. Every following round key, w[i], is equal to the XOR of the previous round key, w[i-1], and the word N k positions earlier, w[i-n k ]. For words in positions that are a multiple of N k, two transformations are initially applied to the previous round key, w[i-1]. These transformations are a cyclic shift of the bytes in the previous round key, followed by the application of the S-box table lookup to all four bytes of the word. Afterwards, an XOR with a round constant value, Rcon[i], is applied to the previous round key. The KeyExpansion routine for the AES256 (N k =8) is slightly different than the AES128 and AES192 ones, as an additional SubWord function is applied to the previous round key, w[i-1], prior to the XOR with w[i- N k ].
19 Chapter 3 AES128 DESIGN AND IMPLEMENTATION 3.1 Overview In this chapter, a hardware model for implementing the AES128 algorithm is introduced. The model is implemented using the SystemVerilog hardware description language [5]. This chapter covers the design and implementation issues of the AES128 algorithm. In the next chapter, a test infrastructure is presented that thoroughly tests the functionality of the implemented model. The hardware model developed in this chapter is synthesizable. This means that the model provides a cycle-by-cycle RTL description of the circuit that a logic synthesis tool can convert to an optimized gate-level netlist. [3] The modeling process utilized in this project is the bottom-up approach. This means that the leaf components in the design hierarchy were developed first and the higher-level modules were constructed by instantiating their subcomponents and connecting them with the internal signals. All the modules in the design hierarchy were modeled in behavioral style, but the root module consisted of data flow modeling as well to implement the four major cipher transformations.
20 3.2 Design Hierarchy The proposed AES128 hardware model is a 3-level hierarchical design as shown in Figure 8. The root module in the hierarchy is the AES128_cipher_top. This module implements the AES128 pseudo code displayed in Figure 2. It has two 128-bit inputs for receiving the cipher key and the plaintext. There is also a single bit input signal, Ld, which is used to indicate the availability of a new set of plaintext or cipher key on the input ports. The completion of the encryption process is indicated by asserting the done single bit output. plaintext 128 b cipherkey 128 b ld rst clk AES128_Cipher_Top AES128_Rcon AES128_Key_Expand ciphertext 128 b done Figure 8 Design Hierarchy
21 A unique feature of the proposed design is that the AES128_Key_Expand module is pipelined with the AES128_cipher_top module. While the AES128_cipher_top module is performing an iteration of the encryption transformations on the State using the previously generated round keys, the AES128_Key_Expand produces the next round s set of keys to be used by the root module in the next encryption iteration. 3.2.1 AES128 Encryption Process The AES128_cipher_top module state diagram is shown in Figure 9. There are ten rounds of transformations represented by r1 to r10 states. The four cipher transformations introduced in section 2.3 are applied to each state. The r0 state corresponds to the initial AddRoundKey transformation in Figure 2. After leaving the Reset state, the AES128_Cipher_Top module waits for assertion of the Ld signal, which indicates that a valid set of plaintext and cipher key is available on the input ports. After reaching the r0 state, there is a transition on every clock cycle for the next ten cycles, as ten rounds of encryption is applied to the State. After going through ten rounds of transformations, the done signal is asserted to indicate the completion of cipher and availability of the ciphertext on the corresponding output port.
22 Figure 9 AES128_Cipher_Top Module State Diagram 3.2.2 AES128 Round Key Generation The round keys used by the AES128_Cipher_Top module are generated based on the state diagram shown in Figure 10. The AES128_Key_Expand and the AES128_RCon modules are responsible for generating the round keys. These two modules operate based on the state diagram shown in Figure 10, which is slightly different than the one used for the encryption process.
23 clk r2 clk Ld r1 r3 clk rst r0!ld r4 clk!rst Reset clk r5 r10 r6 clk clk States Outputs --------------- --------------------------------- R0 R10 w0 = roundkey(round*i) w1 = roundkey(round*i+1) w2 = roundkey(round*i+2) w3 = roundkey(round*i+3) r9 clk r8 clk r7 clk Figure 10 AES128_Key_Expand Module State Diagram In the state diagram shown above, the Ld signal is checked in the r0 state and if asserted, then the cipher key is provided to the AES128_Cipher_Top module to be used for the initial AddRoundKey transformation. The AES128_Key_Expand module generates four 32-bit keys for each round of the encryption process, by using the cipher key. Figure 12 shows the block diagram of the AES128_Key_Expand module. The cipher key is passed to this module through a 128- bit input port, and the round keys are generated on the four output ports.
24 cipherkey 128 b ld rst clk AES128_Key_Expand 32 b w0 32 b w1 32 b w2 32 b w3 Figure 11 AES128_Key_Expand Module There is a 32-bit round constant value, which is used by the key expansion algorithm to generate the round keys. This value varies for each encryption round and for N r =1 to N r =10 is given by [{02} i-1,{00},{00},{00}]. The AES128_RCcon module is used to generate this value as shown in Figure 13. The AES128_RCon module also operates based on the state diagram shown in Figure 10.
25 ld AES128_RCon 32 b rcon rst clk Figure 12 AES128_Rcon Module 3.3 AES128 Pipelined Design As stated earlier in this chapter, the round key generation in the proposed design is pipelined with the encryption rounds. The pipelined operation of the round key expansion and the cipher is shown in Figure 11. Each AES encryption round n (white cells) is pipelined with the key generation for round n+1 (gray cells).
26 reset wait for ld r0 r9 r8 r10 r7 r9 r6 r8 r5 r7 r4 r6 r3 r5 r2 r4 r1 r3 r0 r2 r1 r0 r10 r1 r0 reset Figure 13 AES128 Pipelined Round Key Generation and Cipher Rounds The most important advantage of the pipelined design is the lower delay for each encryption iteration, since the round keys for each encryption iteration is present at the beginning of the iteration cycle. The lower delay in each encryption iteration means faster completion of each round of encryption. This reduces the overall encryption delay and allows the design to operate at higher clock frequencies. The higher clock frequency will increase the message encryption rate (throughput) making this design suitable for time critical encryption applications.
27 Chapter 4 AES128 VERIFICATION 4.1 Overview In this chapter, we describe the test infrastructure that is developed in SystemVerilog to verify the functionality of the model described in the previous chapter. The simulation was done using the Synopsis VCS tool. The testbench fully validated the design by constructing random cyclic test vectors for the plaintext and the cipher key, passing them to the model, and comparing the ciphertext to the expected result. 4.2 Testbench Infrastructure There are four major steps involved in verifying a design using an HDL, including test vector generation, passing the test vectors to the design and capturing the design response, determining correctness by comparing the design response with the expected results, and measuring the verification coverage. The test infrastructure described in this chapter performs all the above steps in a systematic way. The AES128 test infrastructure contains several components, some of which are unique SystemVerilog features. These SystemVerilog features make the verification of a design more reliable and more structured. The test infrastructure components are displayed in Figure 14 as part of the AES128_Top module.
28 Clock Generator AES128_Top AES128_Program Clk AES128_Cipher_Top AES128_Interface AES128_rcon AES128_Key_Expand Figure 14 AES128 Test Infrastructure The test infrastructure utilizes the SystemVerilog program block, which has multiple implicit timing regions to evaluate the design events separately from the testbench events. The program block is connected to the model through another unique feature of the SystemVerilog, called Interface. The Interface bundles the connections between the testbench and the design while enforcing the synchronization and communication protocol between the two entities. [4] The definition of the AES128_Top module in SystemVerilog is shown in Figure 15, which has the high-level instantiation of the modules constructing the test infrastructure.
29 module top; bit clk; always #5 clk=~clk; AES128_interface intf(clk); AES128_program prog(intf); AES128_cipher_top aes(intf); endmodule Figure15 AES128_Top Definition The AES128_Top module instantiates the design, Interface and the Program. The Interface and the Program constructs are discussed in the next two sections. The clock generator is defined inside the AES128_top module as well, to avoid any potential race conditions. [4] 4.3 AES128_Interface As designs are becoming more complex, the number of module ports and the complexity of the interconnections between the modules are also increasing. The SystemVerilog Interface construct is the solution for properly connecting the modules as it provides an intelligent means of communication between several modules. The Interface bundles the ports together and enforces synchronization between the modules connected through it. The Interface can provide connectivity between design modules and/or testbench. The modport construct is used in an Interface to specify the direction of signals that are bundled together and to group the signals that are
30 synchronous to a specifc clock. In this project, the SystemVerilog Interface was only used to connect the high-level design with the testbench as shown in Figure 14. As a result, there were two modports declared for the Interface in this project. In an Interface, the signals that are synchronous to a clock are defined inside a Clocking Block to ensure correct timing between the testbench and the high-level design. This ensures that any synchronous signal is driven or sampled with respect to clock and eliminates the potential race condition that exists between the testbench and high-level design written in Verilog. The AES128_Interface definition is shown in Figure 16. Interface AES128_interface(input bit clk); logic rst, ld, done; logic [127:0] key, text_in, text_out; clocking cb @(posedge clk); output ld ; output key; output text_in; input done; input text_out; endclocking modport dut( input clk, input rst, input ld, input key, input text_in, output done, output text_out); modport tb( input clk, output rst, clocking cb); endinterface Figure 16 AES128_Interface Definition
31 4.3 AES128_Program In Verilog, a testbench is basically another module which is connected to the highlevel design. This can cause a race condition between the testbench and the design. [4] SystemVerilog hardware description language introduces a new construct called Program to be used as the testbench. The SystemVerilog Program, having one (or more entry) points, is closer to a program in C, than Verilog s many small blocks of concurrently executing hardware [4]. It also has multiple implicit timing regions to evaluate the design events separately from the testbench event, eliminating any race condition between the design under test and the testbench. The testbench described in this chapter consists of a single Program, which uses the Object Oriented Programming feature of SystemVerilog to dynamically build random test vectors. This is done by defining a Class inside the AES128_Program that encapsulates two random cyclic variables (Properties) for generating stimulus to the high-level design. The class defined in the AES128_Program is shown in Figure 17. As stated earlier in this chapter, another important feature of a testbench is keeping track of the verification coverage. In other words, to make sure that a design is thoroughly verified, the testbench needs to test all the design features. Functional Coverage is a measure of which design features have been exercised by the test. [4]
32 Functional Coverage is done by means of Cover Groups defined inside the SystemVerilog Program. Each Cover Group consists of multiple Cover Points that are the variables used for generating stimulus for the design under test. As it is shown in Figure 17, the class defined in the AES128_Program uses a single Cover Group to keep track of the 128-bit plain_text and cipher_key stimuli. Due to limitations of the Synopsys VCS compiler that limits the cyclic random objects to no more than 16 bits, the 128-bit stimuli are broken into arrays of 16-bit elements. Each array element is declared as a Cover Point inside the Cover Group to be sampled together for measuring the Functional Coverage. class Transaction; randc bit [15:0] plain_text[8]; randc bit [15:0] cipher_key[8]; covergroup Coverage; coverpoint this.plain_text[0]; coverpoint this.plain_text[1]; coverpoint this.plain_text[2]; coverpoint this.plain_text[3]; coverpoint this.plain_text[4]; coverpoint this.plain_text[5]; coverpoint this.plain_text[6]; coverpoint this.plain_text[7]; coverpoint this.cipher_key[0]; coverpoint this.cipher_key[1]; coverpoint this.cipher_key[2]; coverpoint this.cipher_key[3]; coverpoint this.cipher_key[4]; coverpoint this.cipher_key[5]; coverpoint this.cipher_key[6]; coverpoint this.cipher_key[7]; endgroup function new; Coverage = new(); endfunction endclass Figure 17 Class Definition in the AES128_Program
33 The AES128_Program pseudo code is shown in Figure 18. This testbench verifies the design until the Functional Coverage is 100%. The verification procedure involves generating the stimuli and passing them through the AES128_Interface to the design under test and verifying correctness of the results obtained from the design. Class Transaction // see Figure 17 end class initial begin //reset the design while (Functional_Coverage < 100) begin // randomize the cover points // populate palin_text & cipher_key using the cover points // calculate the expected ciphertext using the following function aes128_cipher(plain_text, cipher_key, expected_cipher_text); // pass the stimuli to the design and wait for the result // compare the expected result with the ciphertext generated by // the design to determine correctness // sample the Functional Coverage percentage end $finish; end Figure 18 AES128_Program Pseudo Code To verify the correct functionality of the design under test, a C-style function is developed in SystemVerilog, which takes the stimuli as input and calculates the expected ciphertext. This function is defined as part of package that contains all the variables and routines involved in the encryption process as shown in Figure 19.
34 package AES128_testbench_package logic [7:0] state [4][4]; function aes128_keyexpansion(input bit [127:0] cipher_key); //generate the round keys endfunction function aes128_subbytes(); //performs SubBytes transformation on the state endfunction function aes128_shiftrows(); //performs ShiftRows transformation on the state endfunction function aes128_addroundkey(input int round); //performs AddRoundKey transformation on the state endfunction function aes128_mixcolumns(); //performs MicColumns transformation on the state endfunction /*********************************************************************/ function aes128_cipher( input bit [127:0] plain_text, input bit [127:0] cipher_key, output [127:0] expected_cipher_text); state = plain_text; aes128_keyexpansion(cipher_key); aes128_addroundkey(0); for(round=1;round<10;round++) begin aes128_subbytes(); aes128_shiftrows(); aes128_mixcolumns(); aes128_addroundkey(round); end aes128_subbytes(); aes128_shiftrows(); aes128_addroundkey(10); expected_cipher_text = state endfunction endpackage Figure 19 AES128_Testbench_Package pseudo code
35 The complete simulation result of the testbench is included in Appendix C. Figure 20 illustrates the simulation result for the first three test cases. Each test case starts with randomizing the cover points to populate the plaintext and cipher key inputs to the design under test. Then, the expected ciphertext is calculated using the AES128_cipher function shown in Figure 19. After the design under test has encrypted the plaintext and the done signal is asserted, the ciphertext generated by the hardware model is compared with the expected result to catch any mismatch. The last step in each test case is gathering the Functional Coverage and continuing with the next test case until all design features are tested. Test# 0 plain_text=55f529e00b1a3f14d8a746860e9b533e cipher_key=bbda8d5457141b255a022fee50b6461c expected_cipher_text:116340860130033742714813403090106826404 intf.cb.text_out: 116340860130033742714813403090106826404 Functional Coverage = %1.562500 Test# 1 plain_text=37500380d9d6dccbf474334e02c23ec9 cipher_key=fd1f4dd414ec0fec5078a0a5ef328294 expected_cipher_text:279883244544087465675915927115776104969 intf.cb.text_out: 279883244544087465675915927115776104969 Functional Coverage = %3.125000 Test# 2 plain_text=dd27152407a1dfc8f2c67423377b3d28 cipher_key=e9a308df435809a059ce2b9e26b08c8b expected_cipher_text: 55911193611511870268248153978729662868 intf.cb.text_out: 55911193611511870268248153978729662868 Functional Coverage = %4.394531 Figure 20 Sample Simulation Results
36 Chapter 5 AES128 SYNTHESIS 5.1 Overview A primary objective of this project was to develop a synthesizable model for the AES128 encryption algorithm. Synthesis is the process of converting the register transfer level (RTL) representation of a design into an optimized gate-level netlist. This is a major step in ASIC design flow that takes an RTL model closer to a low-level hardware implementation. Synthesis consists of three main steps. The first step is the Translation, which involves converting the RTL description of a design into a non-optimized intermediate representation that is used by the synthesis tool. The second step is the logic optimization, which optimizes the internal representation by removing redundant logic and performing Boolean logic optimizations. The third step is called technology mapping & optimization which maps the internal representation to an optimized gate level representation using the technology library cells based on design constraints.[3] In this chapter, we describe how the Synopsys Design_Compiler tool was utilized to synthesize the verified AES128 model, by using a script that was developed to perform the synthesis based on certain constraints. The script generates several reports about the synthesis outcome including timing and area estimates.
37 5.2 Synthesis Methodology The first step in the synthesis process is to read all the components in the design hierarchy. There are three components in the 3-level design hierarchy that needs to be synthesized. Since the RTL model utilizes a SystemVerilog Package, then the synthesis tool needs to enable the semantics of a package. In addition, the synthesis tool needs to know if there are multiple instances of calling an automatic function in the design, to preserve separate values for each instance. The following Synopsys Design Compiler (DC) shell commands enable package and automatic function utilizations: set hdlin_sv_packages "enable" set hdlin_infer_function_local_latches "true" Then, the package and the modules in the design hierarchy are read using the following commands: read_file -format sverilog {./AES128_DUT_package.sv} read_file -format sverilog {./AES128_rcon.sv} read_file -format sverilog {./AES128_key_expand.sv} read_file -format sverilog {./AES128_cipher_top.sv} After reading the design files, they are Analyzed and Elaborated through which the RTL code is converted into the Synopsys Design Compiler internal format. [6]
The intermediate results are stored in the defined working library. The following DC commands are used for these steps: 38 analyze -library WORK -format sverilog {./AES128_rcon.sv} analyze -library WORK -format sverilog {./AES128_key_expand.sv} analyze -library WORK -format sverilog {./AES128_cipher_top.sv} elaborate AES128_rcon -architecture verilog -library WORK elaborate AES128_key_expand -architecture verilog -library WORK elaborate AES128_cipher_top -architecture verilog -library WORK Then, the dont_touch attribute is removed from all the modules in the design hierarchy so that during the optimization phase the tool can modify the modules. The following DC command is used for this step: remove_attribute [find design -hierarchy] dont_touch After this step, a 40MHz clock signal is applied to the clock port of the root module, and the synthesis tool is programmed not to modify the clock tree during the optimization phase. In addition, an arbitrary input delay of 5ns with respect to the clock port is applied to all input and output ports (except the clock port itself) to set a safe margin by considering any unintended source of delay such as the delay associated with driving module/modules.
39 Then, the design is constrained with hypothetical maximum area equal to zero to force the tool to make the gate level netlist as compact as possible. The following DC commands are used for these steps: create_clock -name clk -period 25 [find port intf_clk] set_dont_touch_network [find clock "clk"] set non_clock_ports [remove_from_collection [all_inputs] [get_ports intf_clk]] set_input_delay 5 $non_clock_ports -clock clk set_output_delay 5 [all_outputs] set_max_area 0 In the next steps, the tool is programmed to consider a unique design for each cell instance by removing the multiply-instantiated hierarchy in the current design. Then, the synthesis script removes the boundaries from all the components in the design hierarchy and removes all levels of hierarchy. uniquify set_boundary_optimization [find design -hierarchy] true ungroup -all -flatten -all_instances Finally, the tool compiles the design with high effort and reports any warning related the mapping and final optimization step. At the end, the tool generates reports for the optimized gate level netlist area, the worst combinational path timing, and any violated design constraint.
40 report_attribute >./Synthesis_Reports_Attribute.txt report_area >./Synthesis_Reports_Area.txt report_constraints -all_violators >./Synthesis_Reports_Constraint_Violaters.txt report_timing -path full -delay max -max_paths 1 -nworst 1 >./Synthesis_Reports_Timing.txt 5.3 Synthesis Timing Result The synthesis tool optimizes the combinational paths in a design. In General, four types of combinational paths can exist in any design: [3] 1- Input port of the design under test to input of one internal flip-flip 2- Output of an internal flip-flip to input of another flip-flip 3- Output of an internal flip-flip to output port of the design under test 4- A combinational path connecting the input and output ports of the design under test The last DC command in the script developed in previous section, instructs the tool to report the path with the worst timing. In this case, the path with the worst timing is a combinational path of type two. The delay associated with this path is the summation of delays of all combinational gates in the path plus the Clock-To-Q delay of the originating flip-flop, which was calculated as 24.09ns. By considering the setup time of the destination flip-flop in this path, which is 0.85ns, the 40MHz clock signal satisfies the worst combinational path delay. The delays of combinational gates, setup time of flip-
flops and Clock-To-Q values are derived from the LSI_10k library file that was used for the mapping step during synthesis. The synthesis timing report is shown below: 41 **************************************** Report : timing -path full -delay max -max_paths 1 Design : AES128_cipher_top Version: Z-2007.03 Date : Mon Nov 16 21:25:14 2009 **************************************** Operating Conditions: Wire Load Model Mode: top Startpoint: u0/w3_reg[22] (rising edge-triggered flip-flop clocked by clk) Endpoint: u0/w2_reg[27] (rising edge-triggered flip-flop clocked by clk) Path Group: clk Path Type: max Point Incr Path ----------------------------------------------------------- clock clk (rise edge) 0.00 0.00 clock network delay (ideal) 0.00 0.00 u0/w3_reg[22]/cp (FD2) 0.00 0.00 r u0/w3_reg[22]/q (FD2) 1.84 1.84 f U12175/Z (ND2) 2.01 3.86 r U11490/Z (IVP) 0.49 4.35 f U952/Z (ND2) 1.46 5.81 r U11501/Z (IVP) 0.42 6.24 f U11511/Z (ND2P) 1.25 7.48 r U907/Z (IV) 0.39 7.87 f U11489/Z (ND2) 1.05 8.92 r U828/Z (NR2) 0.37 9.29 f U11485/Z (NR4) 1.58 10.87 r U818/Z (ND4) 0.59 11.46 f U11728/Z (NR4) 2.10 13.56 r U553/Z (AN3) 0.84 14.40 r U542/Z (ND4) 0.73 15.13 f U541/Z (AO1) 1.50 16.63 r U540/Z (IV) 0.21 16.84 f U534/Z (NR16) 2.42 19.26 r U533/Z (EN) 1.26 20.51 f U11486/Z (EN) 1.37 21.89 r U118/Z (EO) 1.13 23.01 f U117/Z (EON1) 1.08 24.09 r
42 u0/w2_reg[27]/d (FD2) 0.00 24.09 r data arrival time 24.09 clock clk (rise edge) 25.00 25.00 clock network delay (ideal) 0.00 25.00 u0/w2_reg[27]/cp (FD2) 0.00 25.00 r library setup time -0.85 24.15 data required time 24.15 ----------------------------------------------------------- data required time 24.15 data arrival time -24.09 ----------------------------------------------------------- slack (MET) 0.06 5.4 Synthesis Area Result The synthesis area report shows the total number of cells and nets in the netlist. It also uses the area parameter associated with each cell in the LSI_10K library file, to calculate the total combinational and sequential area of the netlist. The total area of the gate level netlist is unknown since it depends on total area of the interconnects, which itself is a function of the wiring load model used in physical design. The total cell area in the netlist is reported as 22978 units, which is the sum of combinational and sequential areas. The synthesis area report is shown below: Information: Updating design information... (UID-85) **************************************** Report : area Design : AES128_cipher_top Version: Z-2007.03 Date : Mon Nov 16 21:25:14 2009 **************************************** Library(s) Used: lsi_10k (File: /usr/pkg/syn/libraries/syn/lsi_10k.db)
43 Number of ports: 388 Number of nets: 12020 Number of cells: 11574 Number of references: 42 Combinational area: 19045.000000 Noncombinational area: 3940.000000 Net Interconnect area: undefined (No wire load specified) Total cell area: 22985.000000 Total area: undefined 5.5 Synthesis Constraint Violators Result To enforce the synthesis tool to create the most compact netlist, the area of the gate level netlist was constrained to zero during the synthesis process. As a result, the only constraint violation, which is expected, is related to the area as shown bellow: **************************************** Report : constraint -all_violators Design : AES128_cipher_top Version: Z-2007.03 Date : Tue Nov 10 12:50:19 2009 **************************************** max_area Required Actual Design Area Area Slack ----------------------------------------------------------------- AES128_cipher_top 0.00 22978.00-22978.00 (VIOLATED)
44 Chapter 6 AES128 SOFTWARE IMPLEMENTATION 6.1 Overview The optimized gate level netlist generated after synthesizing the hardware model by using the LSI_10K technology library can operate at a 40MHz clock signal. Since the hardware model takes ten clock cycles (for ten rounds of encryption) to encrypt a 128-bit block, the overall delay for encrypting a block of plaintext is 250ns. In order to compare the speed of the hardware implementation with that of a software implementation, the AES128 algorithm was modeled in C language. The C program was then run on a virtual system, and the statistics of the virtual system were gathered before and after encrypting a block of plaintext. The number of CPU cycles that were required on the virtual system to encrypt a block of plaintext was used to compare the efficiency of software and hardware implementations. 6.2 AES128 Software Implementation on a Simics Virtual System Simics is a complete functional simulation tool for creating virtual platforms that supports single-core, multicore, multiple processor, and multiple machine configurations (racks, clusters, and distributed systems). [7]
45 Simics supports several processor families (e.g. ARM, MIPS, PowerPC, x86) and runs the same binary software as the physical target system. To the target software, the virtualized target hardware behaves exactly the same as the physical target hardware. [8] In this project, the Simics software was used to create a virtual system based on Intel s x86 architecture and the 440BX chipset. The target virtual system consisted of a 2GHz Pentium4 processor and ran the Red Hat 7.3 Enterprise Linux operating system. The C program implementing the AES128 encryption algorithm (See Appendix D) was ported to the Simics s virtual system and then compiled to create the executable file (object file). The virtual system s statistics were gathered during the execution of the C program, before and after encrypting a block of plaintext. This was done by using the Simics s Magic instruction that called a registered python function for gathering the virtual system statistics. The portion of the C code for encrypting a block of plaintext is shown in Figure 20. Encrypting a block of plaintext involves copying the block to the state, generating the round keys from the cipher key and performing ten rounds of encryption on the state.
46 int main() {... MAGIC(1); for(i=0;i<4;i++) for(j=0;j<4;j++) state[i][j]=plain_text[i][j]; aes128_keyexpansion(cipher_key); aes128_addroundkey(0);... for(round=1;round<10;round++){ aes128_subbytes(); aes128_shiftrows(); aes128_mixcolumns(); aes128_addroundkey(round); } aes128_subbytes(); aes128_shiftrows(); aes128_addroundkey(10); MAGIC(2); } Figure 21 AES128 Block Encryption Pseudo Code in C The target virtual system statistics before and after encryption of a plaintext block is summarized in Table 3. The Callback1 and Callback2 statistics refer to the virtual system s state before and after the encryption of the plaintext block, respectively.
# of CPU Instructions User Supervisor Toall CPU Cycles Callback 1 1893584723 11589546395282 11591439980005 11591439980005 Callback 2 1893616460 11589546395282 11591440011742 11591440011742 Difference 31737 0 31737 31737 Table 3 Simics Virtual System Statistics 47 The User and Supervisor columns refer to the number of instruction that were executed in the user space and the system space, respectively. Since the clock per instruction for the virtual target was assumed to be one (CPI=1), the total CPU cycles was equal to the total number of instructions. The results show that encrypting a block of plaintext in software takes more than 30,000 CPU cycles of the virtual target system. Since the virtual system has a 2GHz Pentium4 processor, the encryption of a plaintext block takes more than 15us, which is 60 times slower than the proposed hardware implementation.
48 Chapter 7 CONCLUSION In this project, a hardware accelerator for the AES128 encryption algorithm was designed, modeled and verified using the SystemVerilog hardware descrition language. The Synopsys VCS tool was used for simulation and verification of the model. The hardware model was then synthesized using the Synopsys Design Compiler tool. In addition, to get an estimate of the speed gain by hardware implementation, a virtual system was created using the Virtutech Simics software to run a C program implementing the AES128 encryption in software. The proposed pipelined design of the AES encryption algorithm reduces the delay associated with each round of encryption, which allows the hardware to operate at a much higher clock frequencies, compared to a non-pipelined design. This increases the message encryption throughput and makes the hardware model suitable for time critical encryption applications. In addition, the hardware implementation of AES encryption algorithm provides ultimate secrecy of the encryption key, much faster speed compared to software implementation, and higher throughput by means of inherent hardware concurrency. The pipelined design was thoroughly validated by means of a test infrastructure, which utilized several unique SystemVerilog features including Interface and Program.
49 The test infrastructure utilized Interface to enforce synchronization and communication protocol between the design and the testbench. The SystemVerilog Program was used as part of the testbench to construct and provide test objects to the design, while eliminating any potential race condition between them. The testbench included Functional Coverage to measure the verification progress of the design features to make sure the design is fully validated. The gate level netlist generated during the synthesis phase using the LSI_10K technology library is capable of operating at 40MHz frequency, which means the proposed model can encrypt a block of plaintext in 250ns after ten clock cycles. We expect the design to run at higher frequency if synthesized using a more efficient technology library. The software implementation of AES128 algorithm (in C language) on a Simics virtual system (Intel s x86 architecture and a 2GHz Pentium4 processor) showed that it would take more than 30,000 CPU cycles (15,000 ns) to encrypt a block of plaintext. This shows that the hardware implementation of the AES algorithm proposed in this project is more than 60 times faster than the software implementation. There are certain aspects of this project that may be explored in future. One example is to add decryption capability to the design so that it can perform both
50 encryption and decryption. The model can also be extended to perform encryption/ decryption based on other versions of the AES algorithm.
APPENDICES 51
52 APPENDIX A AES128 Hardware Model Source Files AES128_DUT_package.sv `ifndef AES128_DUT_package_defined `define AES128_DUT_package_defined package AES128_DUT_package; typedef enum [3:0] {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,reset,wait_for_load} aes_rounds_t; function automatic [7:0] xtime (input [7:0] b); return {b[6:0],1'b0}^(8'h1b&{8{b[7]}}); endfunction function automatic [31:0] mix_col (input [7:0] s0,s1,s2,s3); mix_col={xtime(s0)^xtime(s1)^s1^s2^s3,s0^xtime(s1)^xtime(s2)^s2^s3, s0^s1^xtime(s2)^xtime(s3)^s3,xtime(s0)^s0^s1^s2^xtime(s3)}; endfunction function automatic [7:0] sbox(input [7:0] a); case (a) 8'h00: return 8'h63; 8'h01: return 8'h7c; 8'h02: return 8'h77; 8'h03: return 8'h7b; 8'h04: return 8'hf2; 8'h05: return 8'h6b; 8'h06: return 8'h6f; 8'h07: return 8'hc5; 8'h08: return 8'h30; 8'h09: return 8'h01; 8'h0a: return 8'h67; 8'h0b: return 8'h2b; 8'h0c: return 8'hfe; 8'h0d: return 8'hd7; 8'h0e: return 8'hab; 8'h0f: return 8'h76; 8'h10: return 8'hca; 8'h11: return 8'h82; 8'h12: return 8'hc9; 8'h13: return 8'h7d; 8'h14: return 8'hfa; 8'h15: return 8'h59; 8'h16: return 8'h47; 8'h17: return 8'hf0; 8'h18: return 8'had;
8'h19: return 8'hd4; 8'h1a: return 8'ha2; 8'h1b: return 8'haf; 8'h1c: return 8'h9c; 8'h1d: return 8'ha4; 8'h1e: return 8'h72; 8'h1f: return 8'hc0; 8'h20: return 8'hb7; 8'h21: return 8'hfd; 8'h22: return 8'h93; 8'h23: return 8'h26; 8'h24: return 8'h36; 8'h25: return 8'h3f; 8'h26: return 8'hf7; 8'h27: return 8'hcc; 8'h28: return 8'h34; 8'h29: return 8'ha5; 8'h2a: return 8'he5; 8'h2b: return 8'hf1; 8'h2c: return 8'h71; 8'h2d: return 8'hd8; 8'h2e: return 8'h31; 8'h2f: return 8'h15; 8'h30: return 8'h04; 8'h31: return 8'hc7; 8'h32: return 8'h23; 8'h33: return 8'hc3; 8'h34: return 8'h18; 8'h35: return 8'h96; 8'h36: return 8'h05; 8'h37: return 8'h9a; 8'h38: return 8'h07; 8'h39: return 8'h12; 8'h3a: return 8'h80; 8'h3b: return 8'he2; 8'h3c: return 8'heb; 8'h3d: return 8'h27; 8'h3e: return 8'hb2; 8'h3f: return 8'h75; 8'h40: return 8'h09; 8'h41: return 8'h83; 8'h42: return 8'h2c; 8'h43: return 8'h1a; 8'h44: return 8'h1b; 8'h45: return 8'h6e; 8'h46: return 8'h5a; 8'h47: return 8'ha0; 8'h48: return 8'h52; 8'h49: return 8'h3b; 8'h4a: return 8'hd6; 8'h4b: return 8'hb3; 8'h4c: return 8'h29; 53
8'h4d: return 8'he3; 8'h4e: return 8'h2f; 8'h4f: return 8'h84; 8'h50: return 8'h53; 8'h51: return 8'hd1; 8'h52: return 8'h00; 8'h53: return 8'hed; 8'h54: return 8'h20; 8'h55: return 8'hfc; 8'h56: return 8'hb1; 8'h57: return 8'h5b; 8'h58: return 8'h6a; 8'h59: return 8'hcb; 8'h5a: return 8'hbe; 8'h5b: return 8'h39; 8'h5c: return 8'h4a; 8'h5d: return 8'h4c; 8'h5e: return 8'h58; 8'h5f: return 8'hcf; 8'h60: return 8'hd0; 8'h61: return 8'hef; 8'h62: return 8'haa; 8'h63: return 8'hfb; 8'h64: return 8'h43; 8'h65: return 8'h4d; 8'h66: return 8'h33; 8'h67: return 8'h85; 8'h68: return 8'h45; 8'h69: return 8'hf9; 8'h6a: return 8'h02; 8'h6b: return 8'h7f; 8'h6c: return 8'h50; 8'h6d: return 8'h3c; 8'h6e: return 8'h9f; 8'h6f: return 8'ha8; 8'h70: return 8'h51; 8'h71: return 8'ha3; 8'h72: return 8'h40; 8'h73: return 8'h8f; 8'h74: return 8'h92; 8'h75: return 8'h9d; 8'h76: return 8'h38; 8'h77: return 8'hf5; 8'h78: return 8'hbc; 8'h79: return 8'hb6; 8'h7a: return 8'hda; 8'h7b: return 8'h21; 8'h7c: return 8'h10; 8'h7d: return 8'hff; 8'h7e: return 8'hf3; 8'h7f: return 8'hd2; 8'h80: return 8'hcd; 54
8'h81: return 8'h0c; 8'h82: return 8'h13; 8'h83: return 8'hec; 8'h84: return 8'h5f; 8'h85: return 8'h97; 8'h86: return 8'h44; 8'h87: return 8'h17; 8'h88: return 8'hc4; 8'h89: return 8'ha7; 8'h8a: return 8'h7e; 8'h8b: return 8'h3d; 8'h8c: return 8'h64; 8'h8d: return 8'h5d; 8'h8e: return 8'h19; 8'h8f: return 8'h73; 8'h90: return 8'h60; 8'h91: return 8'h81; 8'h92: return 8'h4f; 8'h93: return 8'hdc; 8'h94: return 8'h22; 8'h95: return 8'h2a; 8'h96: return 8'h90; 8'h97: return 8'h88; 8'h98: return 8'h46; 8'h99: return 8'hee; 8'h9a: return 8'hb8; 8'h9b: return 8'h14; 8'h9c: return 8'hde; 8'h9d: return 8'h5e; 8'h9e: return 8'h0b; 8'h9f: return 8'hdb; 8'ha0: return 8'he0; 8'ha1: return 8'h32; 8'ha2: return 8'h3a; 8'ha3: return 8'h0a; 8'ha4: return 8'h49; 8'ha5: return 8'h06; 8'ha6: return 8'h24; 8'ha7: return 8'h5c; 8'ha8: return 8'hc2; 8'ha9: return 8'hd3; 8'haa: return 8'hac; 8'hab: return 8'h62; 8'hac: return 8'h91; 8'had: return 8'h95; 8'hae: return 8'he4; 8'haf: return 8'h79; 8'hb0: return 8'he7; 8'hb1: return 8'hc8; 8'hb2: return 8'h37; 8'hb3: return 8'h6d; 8'hb4: return 8'h8d; 55
8'hb5: return 8'hd5; 8'hb6: return 8'h4e; 8'hb7: return 8'ha9; 8'hb8: return 8'h6c; 8'hb9: return 8'h56; 8'hba: return 8'hf4; 8'hbb: return 8'hea; 8'hbc: return 8'h65; 8'hbd: return 8'h7a; 8'hbe: return 8'hae; 8'hbf: return 8'h08; 8'hc0: return 8'hba; 8'hc1: return 8'h78; 8'hc2: return 8'h25; 8'hc3: return 8'h2e; 8'hc4: return 8'h1c; 8'hc5: return 8'ha6; 8'hc6: return 8'hb4; 8'hc7: return 8'hc6; 8'hc8: return 8'he8; 8'hc9: return 8'hdd; 8'hca: return 8'h74; 8'hcb: return 8'h1f; 8'hcc: return 8'h4b; 8'hcd: return 8'hbd; 8'hce: return 8'h8b; 8'hcf: return 8'h8a; 8'hd0: return 8'h70; 8'hd1: return 8'h3e; 8'hd2: return 8'hb5; 8'hd3: return 8'h66; 8'hd4: return 8'h48; 8'hd5: return 8'h03; 8'hd6: return 8'hf6; 8'hd7: return 8'h0e; 8'hd8: return 8'h61; 8'hd9: return 8'h35; 8'hda: return 8'h57; 8'hdb: return 8'hb9; 8'hdc: return 8'h86; 8'hdd: return 8'hc1; 8'hde: return 8'h1d; 8'hdf: return 8'h9e; 8'he0: return 8'he1; 8'he1: return 8'hf8; 8'he2: return 8'h98; 8'he3: return 8'h11; 8'he4: return 8'h69; 8'he5: return 8'hd9; 8'he6: return 8'h8e; 8'he7: return 8'h94; 8'he8: return 8'h9b; 56
57 8'he9: return 8'h1e; 8'hea: return 8'h87; 8'heb: return 8'he9; 8'hec: return 8'hce; 8'hed: return 8'h55; 8'hee: return 8'h28; 8'hef: return 8'hdf; 8'hf0: return 8'h8c; 8'hf1: return 8'ha1; 8'hf2: return 8'h89; 8'hf3: return 8'h0d; 8'hf4: return 8'hbf; 8'hf5: return 8'he6; 8'hf6: return 8'h42; 8'hf7: return 8'h68; 8'hf8: return 8'h41; 8'hf9: return 8'h99; 8'hfa: return 8'h2d; 8'hfb: return 8'h0f; 8'hfc: return 8'hb0; 8'hfd: return 8'h54; 8'hfe: return 8'hbb; 8'hff: return 8'h16; endcase endfunction endpackage `endif
58 AES128_cipher_top.sv interface AES128_interface(input bit clk); logic ld, rst ; logic [127:0] key, text_in ; logic done; logic [127:0] text_out; clocking cb @(posedge clk); output ld ; output key; output text_in; input done; input text_out; endclocking modport dut( input clk, input rst, input ld, input key, input text_in, output done, output text_out); modport tb( input clk, output rst, clocking cb); endinterface **************************************************** module AES128_cipher_top(AES128_interface.dut intf); import AES128_DUT_package::*; aes_rounds_t cs, ns; logic [127:0] plain_text; wire [31:0] w[4]; logic [7:0] sa [4][4]; logic [7:0] sa_next[4][4]; wire [7:0] sa_sub[4][4]; wire [7:0] sa_sr[4][4]; wire [7:0] sa_mc[4][4]; int i,j,a,b;
59 AES128_key_expand u0(.clk( intf.clk ),.rst( intf.rst ),.kld( intf.ld ),.key( intf.key ),.w0( w[0] ),.w1( w[1] ),.w2( w[2] ),.w3( w[3] )); assign sa_sub[0][0] = sbox( sa[0][0] ) ; assign sa_sub[0][1] = sbox( sa[0][1] ) ; assign sa_sub[0][2] = sbox( sa[0][2] ) ; assign sa_sub[0][3] = sbox( sa[0][3] ) ; assign sa_sub[1][0] = sbox( sa[1][0] ) ; assign sa_sub[1][1] = sbox( sa[1][1] ) ; assign sa_sub[1][2] = sbox( sa[1][2] ) ; assign sa_sub[1][3] = sbox( sa[1][3] ) ; assign sa_sub[2][0] = sbox( sa[2][0] ) ; assign sa_sub[2][1] = sbox( sa[2][1] ) ; assign sa_sub[2][2] = sbox( sa[2][2] ) ; assign sa_sub[2][3] = sbox( sa[2][3] ) ; assign sa_sub[3][0] = sbox( sa[3][0] ) ; assign sa_sub[3][1] = sbox( sa[3][1] ) ; assign sa_sub[3][2] = sbox( sa[3][2] ) ; assign sa_sub[3][3] = sbox( sa[3][3] ) ; assign sa_sr[0][0] = sa_sub[0][0]; assign sa_sr[0][1] = sa_sub[0][1]; assign sa_sr[0][2] = sa_sub[0][2]; assign sa_sr[0][3] = sa_sub[0][3]; assign sa_sr[1][0] = sa_sub[1][1]; assign sa_sr[1][1] = sa_sub[1][2]; assign sa_sr[1][2] = sa_sub[1][3]; assign sa_sr[1][3] = sa_sub[1][0]; assign sa_sr[2][0] = sa_sub[2][2]; assign sa_sr[2][1] = sa_sub[2][3]; assign sa_sr[2][2] = sa_sub[2][0]; assign sa_sr[2][3] = sa_sub[2][1]; assign sa_sr[3][0] = sa_sub[3][3]; assign sa_sr[3][1] = sa_sub[3][0]; assign sa_sr[3][2] = sa_sub[3][1]; assign sa_sr[3][3] = sa_sub[3][2]; assign {sa_mc[0][0], sa_mc[1][0], sa_mc[2][0], sa_mc[3][0]} = mix_col(sa_sr[0][0],sa_sr[1][0],sa_sr[2][0],sa_sr[3][0]); assign {sa_mc[0][1], sa_mc[1][1], sa_mc[2][1], sa_mc[3][1]} = mix_col(sa_sr[0][1],sa_sr[1][1],sa_sr[2][1],sa_sr[3][1]); assign {sa_mc[0][2], sa_mc[1][2], sa_mc[2][2], sa_mc[3][2]} = mix_col(sa_sr[0][2],sa_sr[1][2],sa_sr[2][2],sa_sr[3][2]); assign {sa_mc[0][3], sa_mc[1][3], sa_mc[2][3], sa_mc[3][3]} = mix_col(sa_sr[0][3],sa_sr[1][3],sa_sr[2][3],sa_sr[3][3]);
60 always_ff @(posedge intf.clk or negedge intf.rst) if(!intf.rst) begin cs<=reset; plain_text <= 0; for(i=0;i<4;i++) for(j=0;j<4;j++) sa[i][j]<=0; end else begin cs<=ns; sa<=sa_next; if(intf.ld) plain_text <= intf.text_in; end always_comb begin case(cs) reset:begin intf.text_out=128'bz; intf.done=1'b0; for(a=0;a<4;a++) for(b=0;b<4;b++) sa_next[a][b]=0; end wait_for_load: begin for(a=0;a<4;a++) for(b=0;b<4;b++) sa_next[a][b]=0; intf.text_out = 128'bz; intf.done = 1'b0; end r0:begin intf.text_out=128'bz; intf.done=1'b0; sa_next[3][3] = plain_text[007:000] ^ w[3][07:00] ; sa_next[2][3] = plain_text[015:008] ^ w[3][15:08] ; sa_next[1][3] = plain_text[023:016] ^ w[3][23:16] ; sa_next[0][3] = plain_text[031:024] ^ w[3][31:24] ; sa_next[3][2] = plain_text[039:032] ^ w[2][07:00] ; sa_next[2][2] = plain_text[047:040] ^ w[2][15:08] ; sa_next[1][2] = plain_text[055:048] ^ w[2][23:16] ; sa_next[0][2] = plain_text[063:056] ^ w[2][31:24] ; sa_next[3][1] = plain_text[071:064] ^ w[1][07:00] ; sa_next[2][1] = plain_text[079:072] ^ w[1][15:08] ; sa_next[1][1] = plain_text[087:080] ^ w[1][23:16] ; sa_next[0][1] = plain_text[095:088] ^ w[1][31:24] ; sa_next[3][0] = plain_text[103:096] ^ w[0][07:00] ; sa_next[2][0] = plain_text[111:104] ^ w[0][15:08] ; sa_next[1][0] = plain_text[119:112] ^ w[0][23:16] ; sa_next[0][0] = plain_text[127:120] ^ w[0][31:24] ;
61 end r1,r2,r3,r4,r5,r6,r7,r8,r9:begin intf.text_out=128'bz; intf.done=1'b0; sa_next[0][0] = sa_mc[0][0] ^ w[0][31:24]; sa_next[0][1] = sa_mc[0][1] ^ w[1][31:24]; sa_next[0][2] = sa_mc[0][2] ^ w[2][31:24]; sa_next[0][3] = sa_mc[0][3] ^ w[3][31:24]; sa_next[1][0] = sa_mc[1][0] ^ w[0][23:16]; sa_next[1][1] = sa_mc[1][1] ^ w[1][23:16]; sa_next[1][2] = sa_mc[1][2] ^ w[2][23:16]; sa_next[1][3] = sa_mc[1][3] ^ w[3][23:16]; sa_next[2][0] = sa_mc[2][0] ^ w[0][15:08]; sa_next[2][1] = sa_mc[2][1] ^ w[1][15:08]; sa_next[2][2] = sa_mc[2][2] ^ w[2][15:08]; sa_next[2][3] = sa_mc[2][3] ^ w[3][15:08]; sa_next[3][0] = sa_mc[3][0] ^ w[0][07:00]; sa_next[3][1] = sa_mc[3][1] ^ w[1][07:00]; sa_next[3][2] = sa_mc[3][2] ^ w[2][07:00]; sa_next[3][3] = sa_mc[3][3] ^ w[3][07:00]; end r10:begin sa_next[0][0] = sa_sr[0][0] ^ w[0][31:24]; sa_next[0][1] = sa_sr[0][1] ^ w[1][31:24]; sa_next[0][2] = sa_sr[0][2] ^ w[2][31:24]; sa_next[0][3] = sa_sr[0][3] ^ w[3][31:24]; sa_next[1][0] = sa_sr[1][0] ^ w[0][23:16]; sa_next[1][1] = sa_sr[1][1] ^ w[1][23:16]; sa_next[1][2] = sa_sr[1][2] ^ w[2][23:16]; sa_next[1][3] = sa_sr[1][3] ^ w[3][23:16]; sa_next[2][0] = sa_sr[2][0] ^ w[0][15:08]; sa_next[2][1] = sa_sr[2][1] ^ w[1][15:08]; sa_next[2][2] = sa_sr[2][2] ^ w[2][15:08]; sa_next[2][3] = sa_sr[2][3] ^ w[3][15:08]; sa_next[3][0] = sa_sr[3][0] ^ w[0][07:00]; sa_next[3][1] = sa_sr[3][1] ^ w[1][07:00]; sa_next[3][2] = sa_sr[3][2] ^ w[2][07:00]; sa_next[3][3] = sa_sr[3][3] ^ w[3][07:00]; intf.text_out = {sa_next[0][0], sa_next[1][0], Sa_next[2][0], sa_next[3][0], sa_next[0][1], sa_next[1][1], sa_next[2][1], sa_next[3][1], sa_next[0][2], sa_next[1][2], sa_next[2][2], sa_next[3][2], sa_next[0][3], sa_next[1][3], sa_next[2][3], sa_next[3][3]}; intf.done=1'b1; end default:begin intf.text_out=128'bz; intf.done=1'b0; for(a=0;a<4;a++) for(b=0;b<4;b++)
62 end endcase end sa_next[a][b]=0; always_comb begin case (cs) reset: ns = wait_for_load; wait_for_load: begin if( intf.ld ) ns=r0; else ns=wait_for_load; end r0: ns=r1; r1: ns=r2; r2: ns=r3; r3: ns=r4; r4: ns=r5; r5: ns=r6; r6: ns=r7; r7: ns=r8; r8: ns=r9; r9: ns=r10; r10: ns=wait_for_load; default:ns=wait_for_load; endcase end endmodule
63 AES128_key_expand.sv module AES128_key_expand(clk, rst, kld, key, w0, w1, w2, w3); input clk, rst; input kld; input [127:0] key; output [31:0] w0, w1, w2, w3; logic [31:0] w0, w1, w2, w3; logic [31:0] w0_next,w1_next,w2_next,w3_next; logic [31:0] subword; wire [31:0] rcon; import AES128_DUT_package::*; aes_rounds_t cs, ns; AES128_rcon rcon0(.clk(clk),.rst(rst),.kld(kld),.out(rcon)); always_ff @(posedge clk or negedge rst) if(!rst) begin cs <= reset; w0<=0; w1<=0; w2<=0; w3<=0; end else begin cs <= ns; w0 <= w0_next; w1 <= w1_next; w2 <= w2_next; w3 <= w3_next; end always_comb begin case(cs) reset:begin w0_next=0; w1_next=0; w2_next=0; w3_next=0; subword = 0; end r0:begin subword=0; w0_next = kld? key[127:096] : 32'h0; w1_next = kld? key[095:064] : 32'h0; w2_next = kld? key[063:032] : 32'h0; w3_next = kld? key[031:000] : 32'h0; end r1,r2,r3,r4,r5,r6,r7,r8,r9,r10:begin
64 subword[31:24] = sbox(w3[23:16]); subword[23:16] = sbox(w3[15:08]); subword[15:08] = sbox(w3[07:00]); subword[07:00] = sbox(w3[31:24]); w0_next = w0^subword^rcon; w1_next = w1^w0^subword^rcon; w2_next = w2^w1^w0^subword^rcon; w3_next = w3^w2^w1^w0^subword^rcon; end default:begin subword = 32'h0; w0_next = 32'h0; w1_next = 32'h0; w2_next = 32'h0; w3_next = 32'h0; end endcase end always_comb begin case(cs) reset:begin ns = r0; end r0:begin ns = kld? r1 : r0 ; end r1:begin ns = r2; end r2:begin ns = r3; end r3:begin ns = r4; end r4:begin ns = r5; end r5:begin ns = r6; end r6:begin ns = r7; end r7:begin ns = r8; end r8:begin ns = r9; end r9:begin
65 ns = r10; end r10:begin ns = r0; end default:begin ns = r0; end endcase end endmodule
66 AES128_rcon.sv module AES128_rcon(clk, rst, kld, out); input clk, rst; input kld; output [31:0] out; logic [31:0] out; import AES128_DUT_package::*; aes_rounds_t cs, ns; always_ff @(posedge clk or negedge rst) if(!rst) begin cs <= reset; end else begin cs <= ns ; end always_comb begin case(cs) reset:begin out = 32'h00_00_00_00; ns = r0; end r0:begin out = 32'h00_00_00_00; ns = kld? r1 : r0 ; end r1:begin out = 32'h01_00_00_00; ns = r2; end r2:begin out = 32'h02_00_00_00; ns = r3; end r3:begin out = 32'h04_00_00_00; ns = r4; end r4:begin out = 32'h08_00_00_00; ns = r5; end r5:begin out = 32'h10_00_00_00; ns = r6; end r6:begin out = 32'h20_00_00_00;
67 ns = r7; end r7:begin out = 32'h40_00_00_00; ns = r8; end r8:begin out = 32'h80_00_00_00; ns = r9; end r9:begin out = 32'h1b_00_00_00; ns = r10; end r10:begin out = 32'h36_00_00_00; ns = r0; end default:begin out = 32'h00_00_00_00; ns = r0; end endcase end endmodule
68 APPENDIX B AES128 Testbench Source Files AES128_Testbench_Package.sv `ifndef AES128_testbench_package_defined `define AES128_testbench_package_defined package AES128_testbench_package; logic [7:0] state [4][4]; logic [7:0] key [16]; logic [7:0] RoundKey[176]; logic [7:0] Rcon[11] = '{8'h0, 8'h01, 8'h02, 8'h04, 8'h08, 8'h10, 8'h20, 8'h40, 8'h80, 8'h1b, 8'h36}; /*******************************************************/ function automatic [7:0] times2 (input [7:0] b); return {b[6:0],1'b0}^(8'h1b&{8{b[7]}}); endfunction /*******************************************************/ function logic [7:0] getsboxvalue(input logic [7:0] num); logic [7:0] sbox[256] = '{ //0 1 2 3 4 5 6 7 8 9 A B C D E F 8'h63, 8'h7c, 8'h77, 8'h7b, 8'hf2, 8'h6b, 8'h6f, 8'hc5, 8'h30, 8'h01, 8'h67, 8'h2b, 8'hfe, 8'hd7, 8'hab, 8'h76, //0 8'hca, 8'h82, 8'hc9, 8'h7d, 8'hfa, 8'h59, 8'h47, 8'hf0, 8'had, 8'hd4, 8'ha2, 8'haf, 8'h9c, 8'ha4, 8'h72, 8'hc0, //1 8'hb7, 8'hfd, 8'h93, 8'h26, 8'h36, 8'h3f, 8'hf7, 8'hcc, 8'h34, 8'ha5, 8'he5, 8'hf1, 8'h71, 8'hd8, 8'h31, 8'h15, //2 8'h04, 8'hc7, 8'h23, 8'hc3, 8'h18, 8'h96, 8'h05, 8'h9a, 8'h07, 8'h12, 8'h80, 8'he2, 8'heb, 8'h27, 8'hb2, 8'h75, //3 8'h09, 8'h83, 8'h2c, 8'h1a, 8'h1b, 8'h6e, 8'h5a, 8'ha0, 8'h52, 8'h3b, 8'hd6, 8'hb3, 8'h29, 8'he3, 8'h2f, 8'h84, //4 8'h53, 8'hd1, 8'h00, 8'hed, 8'h20, 8'hfc, 8'hb1, 8'h5b, 8'h6a, 8'hcb, 8'hbe, 8'h39, 8'h4a, 8'h4c, 8'h58, 8'hcf, //5 8'hd0, 8'hef, 8'haa, 8'hfb, 8'h43, 8'h4d, 8'h33, 8'h85, 8'h45, 8'hf9, 8'h02, 8'h7f, 8'h50, 8'h3c, 8'h9f, 8'ha8, //6 8'h51, 8'ha3, 8'h40, 8'h8f, 8'h92, 8'h9d, 8'h38, 8'hf5, 8'hbc, 8'hb6, 8'hda, 8'h21, 8'h10, 8'hff, 8'hf3, 8'hd2, //7 8'hcd, 8'h0c, 8'h13, 8'hec, 8'h5f, 8'h97, 8'h44, 8'h17, 8'hc4, 8'ha7, 8'h7e, 8'h3d, 8'h64, 8'h5d, 8'h19, 8'h73, //8 8'h60, 8'h81, 8'h4f, 8'hdc, 8'h22, 8'h2a, 8'h90, 8'h88, 8'h46, 8'hee, 8'hb8, 8'h14, 8'hde, 8'h5e, 8'h0b, 8'hdb, //9 8'he0, 8'h32, 8'h3a, 8'h0a, 8'h49, 8'h06, 8'h24, 8'h5c, 8'hc2, 8'hd3, 8'hac, 8'h62, 8'h91, 8'h95, 8'he4, 8'h79, //A
69 8'he7, 8'hc8, 8'h37, 8'h6d, 8'h8d, 8'hd5, 8'h4e, 8'ha9, 8'h6c, 8'h56, 8'hf4, 8'hea, 8'h65, 8'h7a, 8'hae, 8'h08, //B 8'hba, 8'h78, 8'h25, 8'h2e, 8'h1c, 8'ha6, 8'hb4, 8'hc6, 8'he8, 8'hdd, 8'h74, 8'h1f, 8'h4b, 8'hbd, 8'h8b, 8'h8a, //C 8'h70, 8'h3e, 8'hb5, 8'h66, 8'h48, 8'h03, 8'hf6, 8'h0e, 8'h61, 8'h35, 8'h57, 8'hb9, 8'h86, 8'hc1, 8'h1d, 8'h9e, //D 8'he1, 8'hf8, 8'h98, 8'h11, 8'h69, 8'hd9, 8'h8e, 8'h94, 8'h9b, 8'h1e, 8'h87, 8'he9, 8'hce, 8'h55, 8'h28, 8'hdf, //E 8'h8c, 8'ha1, 8'h89, 8'h0d, 8'hbf, 8'he6, 8'h42, 8'h68, 8'h41, 8'h99, 8'h2d, 8'h0f, 8'hb0, 8'h54, 8'hbb, 8'h16 //F }; return sbox[num]; endfunction /*****************************************************/ function aes128_shiftrows(); logic [7:0] temp; // Rotate left the second row by 1 columns temp=state[1][0]; state[1][0]=state[1][1]; state[1][1]=state[1][2]; state[1][2]=state[1][3]; state[1][3]=temp; // Rotate left the third row by 2 columns temp=state[2][0]; state[2][0]=state[2][2]; state[2][2]=temp; temp=state[2][1]; state[2][1]=state[2][3]; state[2][3]=temp; // Rotate left the fourth row by 3 columns temp=state[3][0]; state[3][0]=state[3][3]; state[3][3]=state[3][2]; state[3][2]=state[3][1]; state[3][1]=temp; endfunction /*****************************************************/ function aes128_addroundkey(input int round); int i,j; for(i=0;i<4;i++) for(j=0;j<4;j++) state[j][i] ^= RoundKey[round*16 + i*4 + j]; endfunction /*****************************************************/ function aes128_subbytes(); int i,j; for(i=0;i<4;i++) for(j=0;j<4;j++)
state[i][j] = getsboxvalue(state[i][j]); endfunction /*****************************************************/ function aes128_mixcolumns(); int i; logic [7:0] tmp [4]; for(i=0;i<4;i++) begin tmp[0] = times2(state[0][i])^times2(state[1][i])^state[1][i]^state[2][i]^state[3 ][i]; tmp[1] = state[0][i]^times2(state[1][i])^times2(state[2][i])^state[2][i]^state[3 ][i]; tmp[2] = state[0][i]^state[1][i]^times2(state[2][i])^times2(state[3][i])^state[3 ][i]; tmp[3] = times2(state[0][i])^state[0][i]^state[1][i]^state[2][i]^times2(state[3] [i]); state[0][i] = tmp[0]; state[1][i] = tmp[1]; state[2][i] = tmp[2]; state[3][i] = tmp[3]; end endfunction /*****************************************************/ function aes128_keyexpansion(input bit [127:0] cipher_key); int i,j; logic [7:0] temp[4],k; {RoundKey[0],RoundKey[1],RoundKey[2],RoundKey[3], RoundKey[4],RoundKey[5],RoundKey[6],RoundKey[7], RoundKey[8],RoundKey[9],RoundKey[10],RoundKey[11], RoundKey[12],RoundKey[13],RoundKey[14],RoundKey[15]} = cipher_key; for (i=4;i<44;i++) begin for(j=0;j<4;j++) temp[j]=roundkey[(i-1) * 4 + j]; if (i % 4 == 0) begin k = temp[0]; temp[0] = temp[1]; temp[1] = temp[2]; temp[2] = temp[3]; temp[3] = k; 70 // Function Subword() temp[0]=getsboxvalue(temp[0]); temp[1]=getsboxvalue(temp[1]); temp[2]=getsboxvalue(temp[2]);
71 temp[3]=getsboxvalue(temp[3]); end temp[0] = temp[0] ^ Rcon[i/4]; end RoundKey[i*4+0] = RoundKey[(i-4)*4+0] ^ temp[0]; RoundKey[i*4+1] = RoundKey[(i-4)*4+1] ^ temp[1]; RoundKey[i*4+2] = RoundKey[(i-4)*4+2] ^ temp[2]; RoundKey[i*4+3] = RoundKey[(i-4)*4+3] ^ temp[3]; endfunction /*****************************************************/ function aes128_cipher( input bit [127:0] plain_text, input bit [127:0] cipher_key, output [127:0] cipher_text); int i, j, round; int upper,lower; {state[0][0],state[1][0],state[2][0],state[3][0], state[0][1],state[1][1],state[2][1],state[3][1], state[0][2],state[1][2],state[2][2],state[3][2], state[0][3],state[1][3],state[2][3],state[3][3]} = plain_text; aes128_keyexpansion(cipher_key); aes128_addroundkey(0); for(round=1;round<10;round++) begin aes128_subbytes(); aes128_shiftrows(); aes128_mixcolumns(); aes128_addroundkey(round); end aes128_subbytes(); aes128_shiftrows(); aes128_addroundkey(10); cipher_text = {state[0][0],state[1][0],state[2][0],state[3][0], state[0][1],state[1][1],state[2][1],state[3][1], state[0][2],state[1][2],state[2][2],state[3][2], state[0][3],state[1][3],state[2][3],state[3][3]}; endfunction endpackage `endif
72 AES128_Program.sv program automatic AES128_program(AES128_interface.tb intf); initial $vcdpluson; import AES128_testbench_package::*; class Transaction; randc bit [15:0] plain_text[8]; randc bit [15:0] cipher_key[8]; covergroup Coverage; coverpoint this.plain_text[0]; coverpoint this.plain_text[1]; coverpoint this.plain_text[2]; coverpoint this.plain_text[3]; coverpoint this.plain_text[4]; coverpoint this.plain_text[5]; coverpoint this.plain_text[6]; coverpoint this.plain_text[7]; coverpoint this.cipher_key[0]; coverpoint this.cipher_key[1]; coverpoint this.cipher_key[2]; coverpoint this.cipher_key[3]; coverpoint this.cipher_key[4]; coverpoint this.cipher_key[5]; coverpoint this.cipher_key[6]; coverpoint this.cipher_key[7]; endgroup function new; Coverage = new(); endfunction endclass initial begin Transaction tr; real coverage_percentage=0; bit [127:0] expected_cipher_text; bit [127:0] plain_text; bit [127:0] cipher_key; int i, num=0; tr = new(); intf.rst <= 0; intf.cb.ld <= 0; intf.cb.key <= 128'h0;
73 intf.cb.text_in <= 128'h0; #1 intf.rst <= 1; while (coverage_percentage < 100) begin assert(tr.randomize); plain_text = {tr.plain_text[0],tr.plain_text[1],tr.plain_text[2],tr.plain_text[3], tr.plain_text[4],tr.plain_text[5],tr.plain_text[6],tr.plain_text[7]}; cipher_key = {tr.cipher_key[0],tr.cipher_key[1],tr.cipher_key[2],tr.cipher_key[3], tr.cipher_key[4],tr.cipher_key[5],tr.cipher_key[6],tr.cipher_key[7]}; $display("\n Test# %5d",num); $display("plain_text=%h",plain_text); $display("cipher_key=%h",cipher_key); aes128_cipher(plain_text, cipher_key, expected_cipher_text); @(intf.cb); intf.cb.ld<=1'b1; intf.cb.key <= cipher_key; intf.cb.text_in <= plain_text; repeat(1) @(intf.cb); intf.cb.ld<=0; repeat(11) @(intf.cb); $display("expected_cipher_text:",expected_cipher_text); $display("intf.cb.text_out: ",intf.cb.text_out); if(expected_cipher_text!= intf.cb.text_out) $display("*****----- Error-----*****"); else $display(""); tr.coverage.sample(); coverage_percentage = $get_coverage; $display("functional Coverage = %%%f",coverage_percentage); num++; end $finish; end endprogram
74 AES128_Top.sv module top; bit clk; always #5 clk=~clk; AES128_interface intf(clk); AES128_program prog(intf); AES128_cipher_top aes(intf); endmodule
75 APPENDIX C AES128 Simulation Results The testbench described in Chapter 4, thoroughly validates the design, and the Synopsys VCS tool is used for the simulation purpose. In this appendix, only a subset of the simulation results is shown due to huge number of test cases that the design was validated for. Chronologic VCS simulator copyright 1991-2005 Contains Synopsys proprietary information. Compiler version Y-2006.06-SP1; Runtime version Y-2006.06-SP1; Nov 17 13:16 2009 VCD+ Writer Y-2006.06-SP1 Copyright 2005 Synopsys Inc. Test# 0 plain_text=55f529e00b1a3f14d8a746860e9b533e cipher_key=bbda8d5457141b255a022fee50b6461c expected_cipher_text:116340860130033742714813403090106826404 intf.cb.text_out: 116340860130033742714813403090106826404 Functional Coverage = %1.562500 Test# 1 plain_text=37500380d9d6dccbf474334e02c23ec9 cipher_key=fd1f4dd414ec0fec5078a0a5ef328294 expected_cipher_text:279883244544087465675915927115776104969 intf.cb.text_out: 279883244544087465675915927115776104969 Functional Coverage = %3.125000 Test# 2 plain_text=dd27152407a1dfc8f2c67423377b3d28 cipher_key=e9a308df435809a059ce2b9e26b08c8b expected_cipher_text: 55911193611511870268248153978729662868 intf.cb.text_out: 55911193611511870268248153978729662868 Functional Coverage = %4.394531 Test# 3 plain_text=53f3bcf10153df65d61e04860a9c0cce cipher_key=cc4b029fb9438eca59f42a6a414a80f5
76 expected_cipher_text:317041142724998787170070703714748992470 intf.cb.text_out: 317041142724998787170070703714748992470 Functional Coverage = %5.566406 Test# 4 plain_text=54dd1864003ffd2cdc31444c249a03b5 cipher_key=c9bc0be6544514bdd09b2a924aa04516 expected_cipher_text:133128010134344142095605381799055481842 intf.cb.text_out: 133128010134344142095605381799055481842 Functional Coverage = %6.445312 Test# 5 plain_text=3fa7024900c4ed0bdbd526b628694383 cipher_key=f4df354714700abe18c91cd44da3457b expected_cipher_text:236205387813121504574579897909266715212 intf.cb.text_out: 236205387813121504574579897909266715212 Functional Coverage = %7.421875 Test# 6 plain_text=89eb1829081afc4a81fc449e28400174 cipher_key=ebe00a60e82d76c959dd2467d3f4166a expected_cipher_text:165382230212087431893558788117816931773 intf.cb.text_out: 165382230212087431893558788117816931773 Functional Coverage = %8.105469 Test# 7 plain_text=64761f179c8c31dac96e02770bf20009 cipher_key=5d8713a8f54109b807322a49e2a5457f expected_cipher_text: 33797046360149420235539561090515935558 intf.cb.text_out: 33797046360149420235539561090515935558 Functional Coverage = %9.179688 Test# 8 plain_text=d4387efcf632df6fb1f14104279d51ac cipher_key=fe13b95b14ce0a3008762a4d50a7457e expected_cipher_text:297790548154920611482802827044675334909 intf.cb.text_out: 297790548154920611482802827044675334909 Functional Coverage = %9.863281 Test# 9 plain_text=d68d960a00a7dda9f2e8506e27e544e6 cipher_key=eb6202d9fc05dc2f13322a8b50aae0af expected_cipher_text:134719208224288860893674850368782003671 intf.cb.text_out: 134719208224288860893674850368782003671 Functional Coverage = %10.546875
77 Test# 10 plain_text=ec7bdd04080dbdfe21ee98c812254dd9 cipher_key=fe5bcc4414a8085f0708cb5548e1817a expected_cipher_text:183835503504538499013601446648491038853 intf.cb.text_out: 183835503504538499013601446648491038853 Functional Coverage = %11.425781 Test# 11 plain_text=54ff064500d23007def7001821044431 cipher_key=fd2f012757100a43078902d04eebbaed expected_cipher_text:178804163573402208372642319608749893291 intf.cb.text_out: 178804163573402208372642319608749893291 Functional Coverage = %11.816406 Test# 12 plain_text=540e90c500e8e305f30c14b72ecc0000 cipher_key=ca060e07148b179715c38b07501d99d1 expected_cipher_text:192075097531310469988229301724792477835 intf.cb.text_out: 192075097531310469988229301724792477835 Functional Coverage = %12.597656 Test# 13 plain_text=da814f6102ddcf7bc01349e4272637dc cipher_key=f12f02155713fb5507fd2a4a49d1f82f expected_cipher_text:224400144526916765051524229192793812095 intf.cb.text_out: 224400144526916765051524229192793812095 Functional Coverage = %13.476562 Test# 14 plain_text=80e9bfa602071d03c49c8a172d091dad cipher_key=ebba0b7a14da156e18152a4b07a02f7c expected_cipher_text:222759115340301353601308021887855379922 intf.cb.text_out: 222759115340301353601308021887855379922 Functional Coverage = %14.160156 Test# 15 plain_text=a0d45628c9fd31cddc293af325d32d53 cipher_key=eb30fe994cba547559d01dfc50a9811d expected_cipher_text:117905178368192907001418599706983608782 intf.cb.text_out: 117905178368192907001418599706983608782 Functional Coverage = %14.941406 Test# 16 plain_text=550b8dda0ae8fd80754746cb21e4236f cipher_key=f13901f45298087b59e909cc4a79ff7a
78 expected_cipher_text: 42949385691530687995896640549874853275 intf.cb.text_out: 42949385691530687995896640549874853275 Functional Coverage = %15.527344 Test# 17 plain_text=d65dbe7b00161614f4360253277f442d cipher_key=e9e9caad4d2f087012db2806d61f45d1 expected_cipher_text:163336314913802443400899181917873705389 intf.cb.text_out: 163336314913802443400899181917873705389 Functional Coverage = %15.820312 Test# 18 plain_text=d666443bfd33df7ddc2c454c36f45207 cipher_key=f3253cd033e81219076bf021f9d95006 expected_cipher_text: 56440562981015562949789587783761420573 intf.cb.text_out: 56440562981015562949789587783761420573 Functional Coverage = %16.601562 Test# 19 plain_text=549f185000ce3c35d1534b3f00dc014e cipher_key=f74903e314b70862070b1d5cf8af4546 expected_cipher_text: 49475289490596986886005751655690681929 intf.cb.text_out: 49475289490596986886005751655690681929 Functional Coverage = %16.699219 Test# 20 plain_text=54ea017f00cafd1ea5883fb0f36e2164 cipher_key=f1300265147b861917c2b0b1d4cfe55d expected_cipher_text:209909398637724806308818391962773148041 intf.cb.text_out: 209909398637724806308818391962773148041 Functional Coverage = %17.285156 Test# 21 plain_text=d68b206d011c211bf2f9086900385067 cipher_key=ff2c01fe899c09a959ea00fa50ad8ce0 expected_cipher_text: 22672540126892344146050027610166952989 intf.cb.text_out: 22672540126892344146050027610166952989 Functional Coverage = %17.675781 Test# 22 plain_text=5503027a01102b0de8260bc8295550e8 cipher_key=c9feff3a53cdfcf8163e2a4c4a95452b expected_cipher_text:102936181704996322519820548684073612664 intf.cb.text_out: 102936181704996322519820548684073612664 Functional Coverage = %17.968750
79 Test# 23 plain_text=d68c0195011631d0f3d20c792112a310 cipher_key=c5eb023cf6571256d6b52a7afd5df937 expected_cipher_text:308128750558880204705551837058229608270 intf.cb.text_out: 308128750558880204705551837058229608270 Functional Coverage = %18.457031 Test# 24 plain_text=d65f1f5b0004fcbce6d20010252b421c cipher_key=c494093befbe0a0818682aa2720b819f expected_cipher_text:302256041747000708368980164152182860616 intf.cb.text_out: 302256041747000708368980164152182860616 Functional Coverage = %18.750000 Test# 25 plain_text=d66203870000df73dc199016259d95be cipher_key=c8c7017c1481076e071f2601f9c5f2df expected_cipher_text:279594098914737410316846851048528948359 intf.cb.text_out: 279594098914737410316846851048528948359 Functional Coverage = %19.140625 Test# 26 plain_text=543a024100cdffeff30602ac0b0ba019 cipher_key=fe3e0145541b112b59d326029d44ffc5 expected_cipher_text: 83189870830372928131664867329609325384 intf.cb.text_out: 83189870830372928131664867329609325384 Functional Coverage = %19.238281 Test# 27 plain_text=1f6dbe16080f0cb3d9930f4024a53dde cipher_key=c9a80268ff530a28072d1e994a9736c0 expected_cipher_text:291078326198652742356066643622575001310 intf.cb.text_out: 291078326198652742356066643622575001310 Functional Coverage = %19.531250 Test# 28 plain_text=d664bf230811cc24c20500010b944fee cipher_key=ff9eff20f752a93b072ebb06f2c5457c expected_cipher_text: 96079233282179773314685695350387612516 intf.cb.text_out: 96079233282179773314685695350387612516 Functional Coverage = %19.824219 Test# 29 plain_text=5425d6150113dbf8f2d908f73760519d cipher_key=ffe6ff30375f3b0c07ce13cc50ab819d
80 expected_cipher_text:106245573294815981219408990652565492038 intf.cb.text_out: 106245573294815981219408990652565492038 Functional Coverage = %20.312500 Test# 30 plain_text=d665bf3300a8139cf2e0503d283e9c30 cipher_key=c9cfff22296611c9161ac09850a84524 expected_cipher_text:175814349903934944808111983570349070949 intf.cb.text_out: 175814349903934944808111983570349070949 Functional Coverage = %20.703125 Test# 31 plain_text=7d2d508400d1de44dc150a2237752251 cipher_key=c80acbea533810aa17e02a50f9d1854a expected_cipher_text: 85926897541776856979518867720662729464 intf.cb.text_out: 85926897541776856979518867720662729464 Functional Coverage = %20.996094 Test# 32 plain_text=542f18610812ffb8d55a0899284551d5 cipher_key=c8143ada3e04124f0aa12a8ea295819e expected_cipher_text:328878606142221432576008418446292089875 intf.cb.text_out: 328878606142221432576008418446292089875 Functional Coverage = %21.289062 Test# 33 plain_text=374d175702d52ba3dcc60000214596a4 cipher_key=feab024c5132151c07300092fe9c455b expected_cipher_text: 70209082959105632398554262191503936109 intf.cb.text_out: 70209082959105632398554262191503936109 Functional Coverage = %21.289062 Test# 34 plain_text=30d8185c0115f39ebb3f46ca27c90b44 cipher_key=d76f02cd8e2f0a2159f92a8df944453e expected_cipher_text:255695591600976145670691716006666697842 intf.cb.text_out: 255695591600976145670691716006666697842 Functional Coverage = %21.875000 Test# 35 plain_text=5431025e00cc3c6dd36a46b60ae04820 cipher_key=c8abff21fd80994b590a2a914a98eed4 expected_cipher_text:288387074680323093804483812110081084471 intf.cb.text_out: 288387074680323093804483812110081084471 Functional Coverage = %22.167969
81 Test# 36 plain_text=54e31f7f00bcdf71d60689312aa64fef cipher_key=a81a436afd56604a072f1daab47b4519 expected_cipher_text: 86982923039116153778713099652427348906 intf.cb.text_out: 86982923039116153778713099652427348906 Functional Coverage = %22.558594 Test# 37 plain_text=8aef026e01f831d6f2ff041927e038a8 cipher_key=bae90041148f07935934bb73f9c2e425 expected_cipher_text:104346973576239500404175124922680650729 intf.cb.text_out: 104346973576239500404175124922680650729 Functional Coverage = %22.656250 Test# 38 plain_text=76991f67fe0dfd20be40c6b4233f442e cipher_key=ca0003dc529f1253077a2a8f4a9645f0 expected_cipher_text:262192791137140945853749877722420653731 intf.cb.text_out: 262192791137140945853749877722420653731 Functional Coverage = %22.949219 Test# 39 plain_text=cf11627d0007fd55def500062131511d cipher_key=c810feeb14788ac976c1b89fa875fff4 expected_cipher_text:171086773109986637596917690111693653607 intf.cb.text_out: 171086773109986637596917690111693653607 Functional Coverage = %23.437500 Test# 40 plain_text=38d991b707ccdf6ef7782edd27ba0154 cipher_key=fff6cbc3e87f104c59fdc614bf20454d expected_cipher_text: 82946656957029543296925195997947193139 intf.cb.text_out: 82946656957029543296925195997947193139 Functional Coverage = %23.828125 Test# 41 plain_text=db0e1837f85ddd40f2db0cd3cea9511a cipher_key=c702cb53fe2f09b507112a8c44fb4540 expected_cipher_text:224628345418433827162941896337039485429 intf.cb.text_out: 224628345418433827162941896337039485429 Functional Coverage = %24.121094 Test# 42 plain_text=54300385080e07d2c032021a377a511b cipher_key=eb740baeffdf14deb075b54ab2c34609
82 expected_cipher_text:108087358122402600403922582513409310401 intf.cb.text_out: 108087358122402600403922582513409310401 Functional Coverage = %24.511719 Test# 43 plain_text=d663bf59f3e52ba5d5672fb426110548 cipher_key=c80f01dbffe612390785b653477cf0fb expected_cipher_text:300018059597418215603555958214398948664 intf.cb.text_out: 300018059597418215603555958214398948664 Functional Coverage = %24.707031 Test# 44 plain_text=6a156e9400d0206e6a124b0327fc3f3a cipher_key=ff46013a14738ba717efb202f36ffd84 expected_cipher_text: 65956291527776034487810013573490977047 intf.cb.text_out: 65956291527776034487810013573490977047 Functional Coverage = %25.000000 Test# 45 plain_text=aaf7153a0114fecbd6854b170198389e cipher_key=c9b602d014b09e4816222a764fbc4542 expected_cipher_text:162434111314348495707756583276564630781 intf.cb.text_out: 162434111314348495707756583276564630781 Functional Coverage = %25.195312 Test# 46 plain_text=abbd018501242ba4cca54545f8be5018 cipher_key=eb6501fb4d2609de072ab2b5462a140a expected_cipher_text:267666740818715586604653707170936636441 intf.cb.text_out: 267666740818715586604653707170936636441 Functional Coverage = %25.390625 Test# 47 plain_text=d661018700b0deeaf3d8143cdd4e51a2 cipher_key=ca8fcac63e6b09b659d2181d48b7959a expected_cipher_text: 37631377443043338298078460469368199544 intf.cb.text_out: 37631377443043338298078460469368199544 Functional Coverage = %25.683594 Test# 48 plain_text=54e7be1c00cbfdd57de449712ae298ea cipher_key=c26d01e24fef2b1007262a63fe8d4530 expected_cipher_text: 40319680744353830149768632317995425081 intf.cb.text_out: 40319680744353830149768632317995425081 Functional Coverage = %26.074219
83 Test# 49 plain_text=5644956dfe27fffc85c040e00c473e5d cipher_key=ecd30e2f14d62d08072b0195d41d45da expected_cipher_text: 89565357766871011245323579574747499221 intf.cb.text_out: 89565357766871011245323579574747499221 Functional Coverage = %26.367188 Test# 50 plain_text=54e6be7d00c831cef30340fa27e25105 cipher_key=fe8f3937147209b75d8c9ccdf9c345aa expected_cipher_text: 19602768903876727492025712238382309507 intf.cb.text_out: 19602768903876727492025712238382309507 Functional Coverage = %26.562500 Test# 51 plain_text=3ea695e907cefd1fbaf0044c276a4430 cipher_key=ebc9206a036ce6e459190d8142e59005 expected_cipher_text:297382369036057084374870216444582761917 intf.cb.text_out: 297382369036057084374870216444582761917 Functional Coverage = %27.050781 Test# 52 plain_text=592c95fd07cdfce6e69249912e160035 cipher_key=eba4cf69ff9b07ff1623b24e06408110 expected_cipher_text:240462008358592278722723116395968982096 intf.cb.text_out: 240462008358592278722723116395968982096 Functional Coverage = %27.148438 Test# 53 plain_text=aba41a680036df70d3df041737780bc5 cipher_key=f13501f0ff980778595328574a8044e8 expected_cipher_text:250463057566715831898083608731026459343 intf.cb.text_out: 250463057566715831898083608731026459343 Functional Coverage = %27.148438 Test# 54 plain_text=5434185e0003ddcfc83f0c9724a251d0 cipher_key=ffef0085035c1fef59e3efbe4697edd8 expected_cipher_text:207178367080561818747502170763133797917 intf.cb.text_out: 207178367080561818747502170763133797917 Functional Coverage = %27.343750 Test# 55 plain_text=56ae0190d882ffbdc02b0a150b1d9a77 cipher_key=c9bfc476f6361b2707d42a89d3f5445f
84 expected_cipher_text:211540653082514058988619121175618745070 intf.cb.text_out: 211540653082514058988619121175618745070 Functional Coverage = %27.441406 Test# 56 plain_text=550853a6f920dce6bafd4a00f6693e58 cipher_key=c7e90245092a24fc1627b1cdf9ccf29d expected_cipher_text: 52596604184890656251005142021946542828 intf.cb.text_out: 52596604184890656251005142021946542828 Functional Coverage = %27.734375 Test# 57 plain_text=542dbee9011bfe97c02e922227ec014f cipher_key=fd2ab9563e07106c59d12a8450ac4552 expected_cipher_text:209990674050181286099491228730715500753 intf.cb.text_out: 209990674050181286099491228730715500753 Functional Coverage = %27.734375 Test# 58 plain_text=53f695710006df1fe814143ed79c3e23 cipher_key=ec9501514a6f300559381e44f9c98113 expected_cipher_text: 81184329897071922724954042099187915195 intf.cb.text_out: 81184329897071922724954042099187915195 Functional Coverage = %28.027344 Test# 59 plain_text=374e4266ecbc122ef2fe087d246e0382 cipher_key=cddfcb93036610970685af3242074517 expected_cipher_text:330938340826514890015739978337333640290 intf.cb.text_out: 330938340826514890015739978337333640290 Functional Coverage = %28.320312 Test# 60 plain_text=54c7535d017230c3e7bf086f27c60002 cipher_key=ebcccac254050a340843a26205288ca7 expected_cipher_text:121991005234184472490115315311914482917 intf.cb.text_out: 121991005234184472490115315311914482917 Functional Coverage = %28.320312 Test# 61 plain_text=d65e52330105dd11e6c30870210551d1 cipher_key=fd26cb9eed830874c428b576e2f82b44 expected_cipher_text:161538619325826521782896869815082042855 intf.cb.text_out: 161538619325826521782896869815082042855 Functional Coverage = %28.515625
85 Test# 62 plain_text=0adfbf4d0112dd19c34b4ca1283f4de0 cipher_key=c8bf124935f79c3b12dc2a734a93e82b expected_cipher_text: 23707707936159328849021969344526973109 intf.cb.text_out: 23707707936159328849021969344526973109 Functional Coverage = %28.808594 Test# 63 plain_text=8a0495ecf81c2e2fd36e7e3f002b00cc cipher_key=ffedcbcaab6fffeb07e2b56d053d4522 expected_cipher_text: 43132416904880514566135316329231905325 intf.cb.text_out: 43132416904880514566135316329231905325 Functional Coverage = %29.101562 Test# 64 plain_text=abae0381f730fa1ee4364b3727e3442f cipher_key=fe440e268c5b084b071d08de4a7a4601 expected_cipher_text:298325512413003521281976464316145595368 intf.cb.text_out: 298325512413003521281976464316145595368 Functional Coverage = %29.199219 Test# 65 plain_text=8a00058700b7fd0ed0ef4b13d9650006 cipher_key=fe9301cd65cf1790590d249af7b54543 expected_cipher_text:138474037289734874043099377315808310514 intf.cb.text_out: 138474037289734874043099377315808310514 Functional Coverage = %29.492188 Test# 66 plain_text=8793d7ad0813df72d6194d7727c7d073 cipher_key=f9a9cbc1370c1c3855af2a694f6fffda expected_cipher_text: 66571641135338714454464677789283690019 intf.cb.text_out: 66571641135338714454464677789283690019 Functional Coverage = %29.882812 Test# 67 plain_text=32d2f44700faca58dbe40a1825592749 cipher_key=ffb40042644f1c861895f62941cd9451 expected_cipher_text:318690248920134729194319675138748503134 intf.cb.text_out: 318690248920134729194319675138748503134 Functional Coverage = %30.273438 Test# 68 plain_text=1c130ac40111deb0f74a31c40ace21f9 cipher_key=f487fee7ffc530ec071eb56e4a8dfb66
86 expected_cipher_text:108185051945334103372680794384301980552 intf.cb.text_out: 108185051945334103372680794384301980552 Functional Coverage = %30.371094 Test# 69 plain_text=7833bf5a07e6ce29d2184b29242351c3 cipher_key=ddb50a00f639268d3d722a85d9c0ffc0 expected_cipher_text:269265017899999899745553448054852721605 intf.cb.text_out: 269265017899999899745553448054852721605 Functional Coverage = %30.761719 Test# 70 plain_text=56340184010efffdc543896b213250fe cipher_key=c3b89537fd900860070f096a4f50f92d expected_cipher_text: 91399184479117820029293239878637822267 intf.cb.text_out: 91399184479117820029293239878637822267 Functional Coverage = %30.859375 Test# 71 plain_text=5460503a01b2fc60f343086b2846386a cipher_key=c500ff648cf814d51635b1f4f975851e expected_cipher_text:321959126696914639075985202449703570216 intf.cb.text_out: 321959126696914639075985202449703570216 Functional Coverage = %30.859375 Test# 72 plain_text=54e40636d9a4ffff7b590cad210b9a40 cipher_key=f14cfef8149608783d94bb6e9a238111 expected_cipher_text:149933491571216464530725689020878715025 intf.cb.text_out: 149933491571216464530725689020878715025 Functional Coverage = %31.054688 Test# 73 plain_text=54a4bf3b00c2dbfc02a70455219c447a cipher_key=c5340267fd8d0abc17d2b68afe24451b expected_cipher_text:253449910885310524221828752935831417114 intf.cb.text_out: 253449910885310524221828752935831417114 Functional Coverage = %31.152344 Test# 74 plain_text=7d5b536f95273c61def61f6124a301c0 cipher_key=c551cb9d147409c207252a7848bb8cf1 expected_cipher_text:249669494066402992734710607691301894248 intf.cb.text_out: 249669494066402992734710607691301894248 Functional Coverage = %31.347656
87 Test# 75 plain_text=371e0386f35c3c3ce78c2d9a0c014ddd cipher_key=c7ed2fc214e212522bbfa21cf730e4f4 expected_cipher_text: 71392783348285490124105936961742310 intf.cb.text_out: 71392783348285490124105936961742310 Functional Coverage = %31.542969 Test# 76 plain_text=54c54b40d9baf136d60b26712d2b510a cipher_key=c8290e2564ce0a141624b685f9d045f2 expected_cipher_text:273207072652194034934404696698075758511 intf.cb.text_out: 273207072652194034934404696698075758511 Functional Coverage = %31.640625 Test# 77 plain_text=1bda3c31f6eb20c4f3d69fda27eb4f8e cipher_key=c842cac55397125530e7a242dfe9eed2 expected_cipher_text:207121986814219135514617201837444383149 intf.cb.text_out: 207121986814219135514617201837444383149 Functional Coverage = %32.128906 Test# 78 plain_text=374f5079d9b12c73bf46440efee221ac cipher_key=4cf1cb61036008ca17c509804709459f expected_cipher_text:132030726739576636034788722060159399855 intf.cb.text_out: 132030726739576636034788722060159399855 Functional Coverage = %32.324219 Test# 79 plain_text=35a618451366dd12c78249e625dd9eae cipher_key=f6a80143207e1020d38c1e68d53230e5 expected_cipher_text: 75046355866300200315479205467476625648 intf.cb.text_out: 75046355866300200315479205467476625648 Functional Coverage = %32.617188 Test# 80 plain_text=54df1858010fde86d5af086a00c63f16 cipher_key=c91d0abd55d4143118a1baffd809e228 expected_cipher_text:185570209737900397921146935503442538305 intf.cb.text_out: 185570209737900397921146935503442538305 Functional Coverage = %32.617188 Test# 81 plain_text=542e2aae00d7cce0cdbf269624be3d52 cipher_key=c9b801fd14798b3a17c4db688d13831d
88 expected_cipher_text: 1105315519550579143289768419960138489 intf.cb.text_out: 1105315519550579143289768419960138489 Functional Coverage = %32.812500 Test# 82 plain_text=54debe4e00fb1532de53454425d8235b cipher_key=c9172b28ffc809ae0727b42c98bf4591 expected_cipher_text:155565977056720506677083113903233633679 intf.cb.text_out: 155565977056720506677083113903233633679 Functional Coverage = %32.910156 Test# 83 plain_text=abb031ea00b6dd36e520eb3800363838 cipher_key=c8e3ce3c14e420fe2c92c3c5f9b7f2c6 expected_cipher_text:107944325845194119628380236660522739949 intf.cb.text_out: 107944325845194119628380236660522739949 Functional Coverage = %33.300781 Test# 84 plain_text=d660018200b43c62dbdf2f88010450f9 cipher_key=fd2e02464cc129c52773d188f74e4523 expected_cipher_text:161335800699365850276334749476005302146 intf.cb.text_out: 161335800699365850276334749476005302146 Functional Coverage = %33.496094 Test# 85 plain_text=5914046801f3ed56f4580ee624a45194 cipher_key=fd21020c6682148014ecb32bd6ae453f expected_cipher_text:172722530438674145844700178272441544513 intf.cb.text_out: 172722530438674145844700178272441544513 Functional Coverage = %33.496094 Test# 86 plain_text=548603a507bfdcdcc81b4b3a25d4001e cipher_key=fff10b2d08f91250594eb5cf4a94ffc2 expected_cipher_text:316376741518841587249080544809699479134 intf.cb.text_out: 316376741518841587249080544809699479134 Functional Coverage = %33.496094 Test# 87 plain_text=abbc018100cffcf790f3034411da5089 cipher_key=c78901ec5299dc665a001df8079115ef expected_cipher_text:153576527519207843715557579660064274433 intf.cb.text_out: 153576527519207843715557579660064274433 Functional Coverage = %33.593750
89 Test# 88 plain_text=37a259dfd9d512e7dbd8027c0eb89b08 cipher_key=eb610aa551a0fc3d078825c1e2e48115 expected_cipher_text: 21304543897274511782158580130976100075 intf.cb.text_out: 21304543897274511782158580130976100075 Functional Coverage = %33.691406 Test# 89 plain_text=563f018601ffdcddb7502fa437765116 cipher_key=eb642e57f626086107222a64f75a15f1 expected_cipher_text:105453385340884647043492976583667840622 intf.cb.text_out: 105453385340884647043492976583667840622 Functional Coverage = %33.789062 Test# 90 plain_text=047ebe0000c03037e79c9d6a12185206 cipher_key=593d9c40540e0abd59f62a7948ba810c expected_cipher_text: 90999535967915285838173167561349050330 intf.cb.text_out: 90999535967915285838173167561349050330 Functional Coverage = %34.082031 Test# 91 plain_text=ebdd1148f86dfee0f2de49fa121f015b cipher_key=c41200e4147526c1070a2a61f5ee2cf8 expected_cipher_text:208967645364748785434780441684346373318 intf.cb.text_out: 208967645364748785434780441684346373318 Functional Coverage = %34.277344 Test# 92 plain_text=545e508301f6fffbd12944be27a00158 cipher_key=c8c201e1508f09bb17d9f014fe99446d expected_cipher_text:212985826671980441970728874130303479128 intf.cb.text_out: 212985826671980441970728874130303479128 Functional Coverage = %34.277344 Test# 93 plain_text=76b30051000531d8c2ce04712d9b380a cipher_key=c07b0b9114eb8bd9083ad65ead1a45e2 expected_cipher_text: 39777704288759687186352671331207003031 intf.cb.text_out: 39777704288759687186352671331207003031 Functional Coverage = %34.472656 Test# 94 plain_text=8ab3063b00c320c7dcc44102002e9aa1 cipher_key=fec600793e1d1cbc16082a6648d7f934
90 expected_cipher_text:298972177069360515943108082200013385682 intf.cb.text_out: 298972177069360515943108082200013385682 Functional Coverage = %34.472656 Test# 95 plain_text=54a095ca00b1ffbac25e445e000c38a3 cipher_key=c9b9cdd6541414c708872a62f3e345a4 expected_cipher_text: 17677409688637761808372703578272182386 intf.cb.text_out: 17677409688637761808372703578272182386 Functional Coverage = %34.472656 Test# 96 plain_text=54a111fb0350fffeb2c6043926aaae80 cipher_key=c8c301edfd8309da072cb5601fa2fd91 expected_cipher_text: 88598085060512199100696942188171556343 intf.cb.text_out: 88598085060512199100696942188171556343 Functional Coverage = %34.667969 Test# 97 plain_text=d90a73b500b5fff5c20049fd267d0159 cipher_key=ee0a01f5fd8f07e21394b4a3d306451a expected_cipher_text:185898777039418857702270070218716328472 intf.cb.text_out: 185898777039418857702270070218716328472 Functional Coverage = %34.765625 Test# 98 plain_text=2cd4018b07f32282f41d30bf11eb21aa cipher_key=fd2c5c39541913d317edb4b6d46a4572 expected_cipher_text:152281465508117463586981091987266224942 intf.cb.text_out: 152281465508117463586981091987266224942 Functional Coverage = %34.960938 Test# 99 plain_text=38c102618cda3aaff2df4b3800373899 cipher_key=ff6901501487dcf91840b2c24e144dd9 expected_cipher_text: 37791562435889426540851174287453554588 intf.cb.text_out: 37791562435889426540851174287453554588 Functional Coverage = %35.253906 Test# 100 plain_text=4e0c0267d1e92eacd14e3158fa1651d2 cipher_key=ca030e2103ad12511370a2401fb68d05 expected_cipher_text:316498168513003812427016431729475425046 intf.cb.text_out: 316498168513003812427016431729475425046 Functional Coverage = %35.449219
91 Test# 101 plain_text=5555591e00c9fcd1d565086e27e1001c cipher_key=c9b7cbf653b61d1d4310a029b2f4ffa5 expected_cipher_text: 89420625627045204199662525342104484645 intf.cb.text_out: 89420625627045204199662525342104484645 Functional Coverage = %35.546875 Test# 102 plain_text=770f021f0335ce51f3d790492ab03ef5 cipher_key=ff930e17ee000b0e59f3b370ae3245f1 expected_cipher_text:320711078506292958830694637388178427877 intf.cb.text_out: 320711078506292958830694637388178427877 Functional Coverage = %35.546875 Test# 103 plain_text=550211c301cb2b92dc2a497c377951d3 cipher_key=eb450a3e14ab8dad67ad9eb00799e61b expected_cipher_text:246348566703544381859713374911704375082 intf.cb.text_out: 246348566703544381859713374911704375082 Functional Coverage = %35.644531 Test# 104 plain_text=54390260010acc9be6e549e5376551a7 cipher_key=ed6fcd58148a1238186a2a7547674465 expected_cipher_text:153818184649346531361688351276913266726 intf.cb.text_out: 153818184649346531361688351276913266726 Functional Coverage = %35.644531 Test# 105 plain_text=7d4795e107cbdd3bd5db08730ad952a5 cipher_key=fe99cdf2fd609d8959d8bb0041ef8c95 expected_cipher_text: 74012329913626100250189454197088850405 intf.cb.text_out: 74012329913626100250189454197088850405 Functional Coverage = %35.644531 Test# 106 plain_text=550e967307cadca0e60849be110c9681 cipher_key=eb5f007e4cc00a3b493e098c9b79818e expected_cipher_text: 40320794982229318643075492534704839820 intf.cb.text_out: 40320794982229318643075492534704839820 Functional Coverage = %35.742188 Test# 107 plain_text=7b86039400c5fed2c2013075279e0008 cipher_key=fe9439a6112014ae1869b1f8473a4545
92 expected_cipher_text:189359622328901630199109940181684604684 intf.cb.text_out: 189359622328901630199109940181684604684 Functional Coverage = %35.839844 Test# 108 plain_text=5432bf6e011edd3edcc544ba0b43981a cipher_key=ff6c00843e140a1628aab305f34d8119 expected_cipher_text: 73013110255585711796722016813825696644 intf.cb.text_out: 73013110255585711796722016813825696644 Functional Coverage = %35.839844 Test# 109 plain_text=abb990ca03442dc69f101e7fd45251a9 cipher_key=f56001e5ff3b1484d0b18c86475fffc1 expected_cipher_text: 17595748892454701632383632727639941009 intf.cb.text_out: 17595748892454701632383632727639941009 Functional Coverage = %36.035156 Test# 110 plain_text=564192670810cf3df43044f8fd383e5b cipher_key=c5580e228ddc0a3859e21ad3a8844549 expected_cipher_text:302481902060233107562000245391072403826 intf.cb.text_out: 302481902060233107562000245391072403826 Functional Coverage = %36.035156 Test# 111 plain_text=542795cd00d62e67ce0549fb21160007 cipher_key=c9503b042bb713e70773afcd47413bc7 expected_cipher_text:216952307753015996610404044499454487353 intf.cb.text_out: 216952307753015996610404044499454487353 Functional Coverage = %36.132812 Test# 112 plain_text=d159be6901ba2e86c0dc44f2f9cd3e5c cipher_key=c49d0204fcb7a6515937d8ccae788118 expected_cipher_text:331561480930153459110440154747432507765 intf.cb.text_out: 331561480930153459110440154747432507765 Functional Coverage = %36.328125 Test# 113 plain_text=a6f495cc0336223beea049ec27e84f4a cipher_key=c9d2400a14c50a3108410124df71ff8d expected_cipher_text:159437845298806521399915682727175716061 intf.cb.text_out: 159437845298806521399915682727175716061 Functional Coverage = %36.523438
93 Test# 114 plain_text=8abf3b890123dd3fd91501d82cc30156 cipher_key=c7e00213063d8de71888092d41db453b expected_cipher_text: 63357933614246902079548961509764239485 intf.cb.text_out: 63357933614246902079548961509764239485 Functional Coverage = %36.718750 Test# 115 plain_text=5642019402d91adae7a80c8d11e75103 cipher_key=c54510f114d1fbaed0a0a21f1efcfd8d expected_cipher_text: 32673852811948870908315128553342436814 intf.cb.text_out: 32673852811948870908315128553342436814 Functional Coverage = %36.816406 Test# 116 plain_text=5436d3fb00c6ccfdd580498c27c49a8e cipher_key=c98b9555fd81077516150bcb422aef21 expected_cipher_text:109311673874348513357801868049756808747 intf.cb.text_out: 109311673874348513357801868049756808747 Functional Coverage = %36.914062 Test# 117 plain_text=56615e3200ef1564d61408ba0b0841a9 cipher_key=ecaccbec54d6122edb8d24864166f084 expected_cipher_text:256133638496274307285499419805602264156 intf.cb.text_out: 256133638496274307285499419805602264156 Functional Coverage = %37.109375 Test# 118 plain_text=2f7195fa0158fd21e6d94b24239f0c71 cipher_key=fd2001e64fbe0a0d17d31e36d35de4de expected_cipher_text:291002412752038358599390789043617137555 intf.cb.text_out: 291002412752038358599390789043617137555 Functional Coverage = %37.109375 Test# 119 plain_text=319995ebe586fc38c2352dae27c53800 cipher_key=f1320178e84b087659351e799ab5811a expected_cipher_text:124245487401669864102843322192344349410 intf.cb.text_out: 124245487401669864102843322192344349410 Functional Coverage = %37.207031 Test# 120 plain_text=54e596182f2058cbdc2b4100f9d79af1 cipher_key=fd220115542b174d076f2a4eb2c54594
94 expected_cipher_text: 61659979920827050161116021753938984242 intf.cb.text_out: 61659979920827050161116021753938984242 Functional Coverage = %37.402344 Test# 121 plain_text=e98b95e4011dfc40e23946e601f806e6 cipher_key=c217b957f5f607890728c17eac0c4548 expected_cipher_text:237704731356395537206261884043983166711 intf.cb.text_out: 237704731356395537206261884043983166711 Functional Coverage = %37.500000 Test# 122 plain_text=7d14038d034f316671dc451a0ea721ab cipher_key=b6703ae314d314dd1341262bf7198cfd expected_cipher_text:254990002287906960154682590935870569412 intf.cb.text_out: 254990002287906960154682590935870569412 Functional Coverage = %37.695312 Test# 123 plain_text=4a4ebe8c01b62e77c32f46a70ea44ff7 cipher_key=c8bdff2352911c8b15da09f4f9bf3eee expected_cipher_text:284476257535088200393481303722058827793 intf.cb.text_out: 284476257535088200393481303722058827793 Functional Coverage = %37.890625 Test# 124 plain_text=b0f690c7010947d5c90b1ee2d3eb37df cipher_key=ffee0249374314e859fcb5f34f58e594 expected_cipher_text:181094886658041155045964407464172489473 intf.cb.text_out: 181094886658041155045964407464172489473 Functional Coverage = %38.183594 Test# 125 plain_text=7d1f95e22d50fcf3ba8746aad40b50ef cipher_key=ffb34e0b1471dccbdbfa2a87352b45cd expected_cipher_text:144511515138894836729262641803746007533 intf.cb.text_out: 144511515138894836729262641803746007533 Functional Coverage = %38.281250 Test# 126 plain_text=2f4f32d5ff58478bc01a4973121b51c0 cipher_key=fda80110ffc78b710883b6891fac6eee expected_cipher_text:124142886693616427436594777418586602765 intf.cb.text_out: 124142886693616427436594777418586602765 Functional Coverage = %38.378906
95 Test# 127 plain_text=30c3be6b00bb31515e2e43f6f9cf50ea cipher_key=ff98cec5ec751c891363b9959356c122 expected_cipher_text:151195210421504525021825658903910826662 intf.cb.text_out: 151195210421504525021825658903910826662 Functional Coverage = %38.671875 Test# 128 plain_text=ec74b57f07c4ccfce484086cf8c33eee cipher_key=f544cbc414d909c407102ee14004e567 expected_cipher_text:273148885754329916020934394531925519690 intf.cb.text_out: 273148885754329916020934394531925519690 Functional Coverage = %38.769531 Test# 129 plain_text=77522575fdb1fff4fe5440fb25be530c cipher_key=fe980144546913d71823a0a9d7fde4f1 expected_cipher_text:201463152228829181227896560097260981610 intf.cb.text_out: 201463152228829181227896560097260981610 Functional Coverage = %38.964844 Test# 130 plain_text=7472002aff7ffff8bf7646b9015005bc cipher_key=bb6f0112352e08cb57692a86ae57bc35 expected_cipher_text: 42724922915323745594402774340541496382 intf.cb.text_out: 42724922915323745594402774340541496382 Functional Coverage = %39.062500 Test# 131 plain_text=d44911b9fdc3ccde751c498f255e9fc7 cipher_key=c997feeafd8e0a3917c32300feff8ce1 expected_cipher_text:111066237196290495921245637211422335539 intf.cb.text_out: 111066237196290495921245637211422335539 Functional Coverage = %39.160156 Test# 132 plain_text=3edb1f3e01b5feab6bac40fd25ab44b4 cipher_key=fd2b3a1a54111237182209e54476454a expected_cipher_text:180120858150212415319203995135027249205 intf.cb.text_out: 180120858150212415319203995135027249205 Functional Coverage = %39.160156 Test# 133 plain_text=ab1590c801f720c64652276e0adb389c cipher_key=dbf70167373607fe0a022fadf5d345a2
96 expected_cipher_text:153435665762075860057841480519241226908 intf.cb.text_out: 153435665762075860057841480519241226908 Functional Coverage = %39.355469 Test# 134 plain_text=db6b61a6d8e9df77dbd609d90adc7a57 cipher_key=c9ff020314d714d21617b581f9ce4555 expected_cipher_text:257048683504206509901260725708540848516 intf.cb.text_out: 257048683504206509901260725708540848516 Functional Coverage = %39.453125 Test# 135 plain_text=7d225081ff9131d1e797089a0ad850cb cipher_key=f1331191545b17931619b5d3f3c04f7f expected_cipher_text: 61194789647899311913103269807207279204 intf.cb.text_out: 61194789647899311913103269807207279204 Functional Coverage = %39.453125 Test# 136 plain_text=a90ebe6a00f83c39f3e8447b121e50fa cipher_key=c80b018f4cfdfc89153a1df95010d3c1 expected_cipher_text:151521809196192556371225093992079650633 intf.cb.text_out: 151521809196192556371225093992079650633 Functional Coverage = %39.550781 Test# 137 plain_text=30cc90c1021b31cfe792031900353e26 cipher_key=fe410b71e85220703959b687ff638fdb expected_cipher_text: 91836409901946432134887704912851660246 intf.cb.text_out: 91836409901946432134887704912851660246 Functional Coverage = %39.648438 Test# 138 plain_text=543301ae0349edc981a30889260a9b05 cipher_key=c496fee88c660a3a689b046f41d645a6 expected_cipher_text: 65154675507879386155536108636524949385 intf.cb.text_out: 65154675507879386155536108636524949385 Functional Coverage = %39.843750 Test# 139 plain_text=4d6a70be01f520f2f75d02780f9a3e4c cipher_key=ed98ce743e11167759501e43473b4562 expected_cipher_text:256990810036835831033768826973384621483 intf.cb.text_out: 256990810036835831033768826973384621483 Functional Coverage = %39.843750
97 Test# 140 plain_text=4aac323d0002fd7cf2dd0c9c002c9932 cipher_key=c7e501df8cca0ae206ca1e6548b8fca3 expected_cipher_text:132270103641098554176001999270782176067 intf.cb.text_out: 132270103641098554176001999270782176067 Functional Coverage = %39.843750 Test# 141 plain_text=36cc3f6207d8dce5dc2d4466f8bc0019 cipher_key=c9e40179373914831660a0a848cde4f3 expected_cipher_text:101341814556848481205806294818382658461 intf.cb.text_out: 101341814556848481205806294818382658461 Functional Coverage = %39.843750 Test# 142 plain_text=74a9be8703cfccdfc33909fd25e7510f cipher_key=ff94cbc24cbd5de70709bb71b2e48ee1 expected_cipher_text: 59312026510356852834228294887567170921 intf.cb.text_out: 59312026510356852834228294887567170921 Functional Coverage = %39.941406 Test# 143 plain_text=db2b185a0001fcc1e79f3185f9ce389b cipher_key=ebca40528df39cde14c91e37f9c0157f expected_cipher_text: 43027465970860390454708368081178225240 intf.cb.text_out: 43027465970860390454708368081178225240 Functional Coverage = %39.941406 Test# 144 plain_text=8a49bd37d9cd2509dc1646b8121a4ff6 cipher_key=f55201e0fee307771628aa6c1fae4544 expected_cipher_text:106481885721421788549684294466169140840 intf.cb.text_out: 106481885721421788549684294466169140840 Functional Coverage = %40.136719 Test# 145 plain_text=ec7a923200c7fff6d88526c80b59015a cipher_key=c7ec12844dc9171dda8c9e2b4a8eeee7 expected_cipher_text: 87221603746798755565664018638032305532 intf.cb.text_out: 87221603746798755565664018638032305532 Functional Coverage = %40.136719 Test# 146 plain_text=563d4fb00107f608542b26ad0ada50ed cipher_key=ff970a0435a1108e16182a77f9c1e597
98 expected_cipher_text:204989214848655319606740136312774623131 intf.cb.text_out: 204989214848655319606740136312774623131 Functional Coverage = %40.332031 Test# 147 plain_text=31d34ff700e9ccf3f33e30ad28422219 cipher_key=d93acbf1571114a913402a68d40feee1 expected_cipher_text:307137798225678264046906037220025263688 intf.cb.text_out: 307137798225678264046906037220025263688 Functional Coverage = %40.332031 Test# 148 plain_text=316603820345cf37ff0b0a02f8820025 cipher_key=fd29cacf14b2122f660af0eea353452f expected_cipher_text:202257509318140549633711749136917577548 intf.cb.text_out: 202257509318140549633711749136917577548 Functional Coverage = %40.332031 Test# 149 plain_text=11abbf3001f4fa50d1d52fa911e841f2 cipher_key=ff50050b3e0f263f07702a7b4e8845dd expected_cipher_text:202122747268824293586668904049301096555 intf.cb.text_out: 202122747268824293586668904049301096555 Functional Coverage = %40.527344... Test# 30433 plain_text=67d68c8eb55b1f35058b912171ccb7d7 cipher_key=d44f2be19df75270fff35eae95499e86 expected_cipher_text: 54993961189497411582475211985531592621 intf.cb.text_out: 54993961189497411582475211985531592621 Functional Coverage = %99.902344 Test# 30434 plain_text=d7b4d79b222179d23d3bcfb32b2035de cipher_key=a067ea940f10f6c593a28e79bb65d38a expected_cipher_text:219444398843322724845164944671551837366 intf.cb.text_out: 219444398843322724845164944671551837366 Functional Coverage = %99.902344 Test# 30435
99 plain_text=921389ec9adb449f60b4fbfadf724d32 cipher_key=109b627c92e3f0f0cc29fafbc5c13cf3 expected_cipher_text:197775199999021594959013195800724093515 intf.cb.text_out: 197775199999021594959013195800724093515 Functional Coverage = %99.902344 Test# 30436 plain_text=95ecf5da381137beebdc1c4ee6600300 cipher_key=6d2695bbcfd6c427a1cd2efce7828f7e expected_cipher_text:268001363104317902816368128586534149502 intf.cb.text_out: 268001363104317902816368128586534149502 Functional Coverage = %99.902344 Test# 30437 plain_text=4da2774b05ad6b0064318ea7089a83c2 cipher_key=e57a24e690b8edb27a1a817daa634f3c expected_cipher_text:161651277971006626223455072427319093388 intf.cb.text_out: 161651277971006626223455072427319093388 Functional Coverage = %99.902344 Test# 30438 plain_text=342d903641b45c899e505fc839bb68dd cipher_key=a59c07c18d800cc5a00ef06ea8cc7014 expected_cipher_text:201167093145906464752338403382686813581 intf.cb.text_out: 201167093145906464752338403382686813581 Functional Coverage = %99.902344 Test# 30439 plain_text=2bf764760dfc8a0e70d173b1452ea238 cipher_key=2476a3225c8f69d636e5c9886d462f22 expected_cipher_text:126684722883796609946505201812530887183 intf.cb.text_out: 126684722883796609946505201812530887183 Functional Coverage = %99.902344 Test# 30440 plain_text=d4f70a6ac96edaf11a76c21ab7923c1e cipher_key=345ed023eedfa246d8482771fabf3bd0 expected_cipher_text:117770351100312500010291508853848750435 intf.cb.text_out: 117770351100312500010291508853848750435 Functional Coverage = %99.902344 Test# 30441 plain_text=b8b6cb8d517722cad2b46eeb6ab80ecc cipher_key=46c44b8101ab17afc4ff7f5e7bc30670 expected_cipher_text: 58028918665503450398731845309957416691 intf.cb.text_out: 58028918665503450398731845309957416691
100 Functional Coverage = %99.902344 Test# 30442 plain_text=6f3002fb18c84e321eb81982f3f45fb0 cipher_key=88e60cddf4c39622fb2fb8052880893b expected_cipher_text:154680458935969887821826519042618876157 intf.cb.text_out: 154680458935969887821826519042618876157 Functional Coverage = %99.902344 Test# 30443 plain_text=089e20659a2a467d662d3b22491fd6b8 cipher_key=d5c8c7cf3b2cef65cd59d66e804cdc5a expected_cipher_text:241733669850370819784792434143079870965 intf.cb.text_out: 241733669850370819784792434143079870965 Functional Coverage = %99.902344 Test# 30444 plain_text=aa0adc7339635d785e7710785537f412 cipher_key=b2926df9607e992da292b2e57f5ee9bd expected_cipher_text: 34026205514318703717398088549874136543 intf.cb.text_out: 34026205514318703717398088549874136543 Functional Coverage = %99.902344 Test# 30445 plain_text=e1c8ffd74a402317c0b177cdad3f86f2 cipher_key=504fa9750e4ee3f51c4fd74d0ee6a7fa expected_cipher_text:163789554394008223375802199745537339506 intf.cb.text_out: 163789554394008223375802199745537339506 Functional Coverage = %99.902344 Test# 30446 plain_text=fdc5d86bd580011283565b1eb7c9119b cipher_key=2bf2a49690ab7a396c4f0155bf5d9a45 expected_cipher_text:283013848500370801975735409037544043194 intf.cb.text_out: 283013848500370801975735409037544043194 Functional Coverage = %99.902344 Test# 30447 plain_text=dc48f27b58f3f2cd7f3e43e6dc22daa6 cipher_key=858b3495db6f44a069b3beac10654841 expected_cipher_text: 99189029658263411386506910983377053441 intf.cb.text_out: 99189029658263411386506910983377053441 Functional Coverage = %99.902344 Test# 30448
101 plain_text=43d25612728147ae86374f0eff8aa5c3 cipher_key=2c4a9f0165898dda3a597593d3bd70d0 expected_cipher_text: 96012358800635010943519307425632709285 intf.cb.text_out: 96012358800635010943519307425632709285 Functional Coverage = %99.902344 Test# 30449 plain_text=affb8d7496b6d4f8dcb6e7ad38c410e7 cipher_key=a661bb0144ce4d7e7d7ed10d0ed93a5f expected_cipher_text:153129670018291104490411741174870621078 intf.cb.text_out: 153129670018291104490411741174870621078 Functional Coverage = %99.902344 Test# 30450 plain_text=2ebeb9d372b3717505c81055663569ae cipher_key=8ba49f3f7ab726b056f87096df5b099c expected_cipher_text:282237689968339489117699446886508141296 intf.cb.text_out: 282237689968339489117699446886508141296 Functional Coverage = %99.902344 Test# 30451 plain_text=4fd05f0310f0759c60b822c83888f7d0 cipher_key=6353bd4961b9072db1653a187cc72113 expected_cipher_text:152900574266681613718535032188128758895 intf.cb.text_out: 152900574266681613718535032188128758895 Functional Coverage = %99.902344 Test# 30452 plain_text=940a651cc669b54cc0cae56d9be72510 cipher_key=55351bd98294f122d6111a47a48de63c expected_cipher_text:250717795008170880362515515672911212947 intf.cb.text_out: 250717795008170880362515515672911212947 Functional Coverage = %99.902344 Test# 30453 plain_text=6765ecd6c28bdff75db398c5e1fbf28b cipher_key=039c42aab23715934b56a3c719c0ac85 expected_cipher_text:307758848720487418976689865632800315289 intf.cb.text_out: 307758848720487418976689865632800315289 Functional Coverage = %100.000000 $finish at simulation time 3959015 V C S S i m u l a t i o n R e p o r t Time: 3959015 CPU Time: 53.720 seconds; Data structure size: 0.0Mb Tue Nov 17 13:17:31 2009
102 APPENDIX D AES128 Implementation in C Language AES128.c #include<stdio.h> #include "magic_instruction.h" /*find it in local directory*/ #define MY_MAGIC(n) \ { \ asm volatile ("movl %0, %%eax" \ : /*no outputs*/ \ : "g" (n) \ : "eax"); \ MAGIC(0); \ } unsigned short int state [4][4]; unsigned short int RoundKey[176]; unsigned short int Rcon[11] = {0x0, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36}; unsigned short int sbox[256] = { //0 1 2 3 4 5 6 7 8 9 A B C D E F 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, //0 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, //1 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, //2 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, //3 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, //4 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, //5 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, //6 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, //7 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, //8 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, //9 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, //A 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, //B
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, //C 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, //D 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, //E 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 //F }; /*******************************************************/ unsigned char times2 (unsigned short int b){ if((b>>7)) return ((b<<1) ^ 0x1b); else return (b<<1); } /*******************************************************/ unsigned short int getsboxvalue(unsigned short int num){ return sbox[num]; } /*****************************************************/ void aes128_shiftrows(){ unsigned short int temp; temp=state[1][0]; state[1][0]=state[1][1]; state[1][1]=state[1][2]; state[1][2]=state[1][3]; state[1][3]=temp; temp=state[2][0]; state[2][0]=state[2][2]; state[2][2]=temp; temp=state[2][1]; state[2][1]=state[2][3]; state[2][3]=temp; temp=state[3][0]; state[3][0]=state[3][3]; state[3][3]=state[3][2]; state[3][2]=state[3][1]; state[3][1]=temp; } /*****************************************************/ void aes128_addroundkey(unsigned short int round){ int i,j; for(i=0;i<4;i++) for(j=0;j<4;j++) state[j][i] ^= RoundKey[round*16 + i*4 + j]; } /*****************************************************/ void aes128_subbytes(){ int i,j; 103
for(i=0;i<4;i++) for(j=0;j<4;j++) state[i][j] = getsboxvalue(state[i][j]); } /*****************************************************/ void aes128_mixcolumns(){ int i; unsigned short int tmp [4]; for(i=0;i<4;i++) { tmp[0] = times2(state[0][i])^times2(state[1][i])^state[1][i]^state[2][i]^state[3 ][i]; tmp[1] = state[0][i]^times2(state[1][i])^times2(state[2][i])^state[2][i]^state[3 ][i]; tmp[2] = state[0][i]^state[1][i]^times2(state[2][i])^times2(state[3][i])^state[3 ][i]; tmp[3] = times2(state[0][i])^state[0][i]^state[1][i]^state[2][i]^times2(state[3] [i]); state[0][i] = tmp[0]; state[1][i] = tmp[1]; state[2][i] = tmp[2]; state[3][i] = tmp[3]; } } /*****************************************************/ void aes128_keyexpansion(unsigned short int cipher_key[16]){ int i,j; unsigned short int temp[4],k; for(i=0;i<4;i++) { RoundKey[i*4]=cipher_key[i*4]; RoundKey[i*4+1]=cipher_key[i*4+1]; RoundKey[i*4+2]=cipher_key[i*4+2]; RoundKey[i*4+3]=cipher_key[i*4+3]; } for (i=4;i<44;i++) { for(j=0;j<4;j++) temp[j]=roundkey[(i-1) * 4 + j]; if (i % 4 == 0){ k = temp[0]; temp[0] = temp[1]; temp[1] = temp[2]; temp[2] = temp[3]; temp[3] = k; temp[0]=getsboxvalue(temp[0]); 104
105 temp[1]=getsboxvalue(temp[1]); temp[2]=getsboxvalue(temp[2]); temp[3]=getsboxvalue(temp[3]); } temp[0] = temp[0] ^ Rcon[i/4]; } RoundKey[i*4+0] = RoundKey[(i-4)*4+0] ^ temp[0]; RoundKey[i*4+1] = RoundKey[(i-4)*4+1] ^ temp[1]; RoundKey[i*4+2] = RoundKey[(i-4)*4+2] ^ temp[2]; RoundKey[i*4+3] = RoundKey[(i-4)*4+3] ^ temp[3]; } /*****************************************************/ int main() { int i, j, round; unsigned short int cipher_key[16]={0x2b,0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c}; unsigned short int plain_text[4][4]={0x32, 0x88, 0x31, 0xe0, 0x43, 0x5a, 0x31, 0x37, 0xf6, 0x30, 0x98, 0x07, 0xa8, 0x8d, 0xa2, 0x34}; printf("\nplaintext:\n"); for(i=0;i<4;i++){ for(j=0;j<4;j++) printf(" %x",plain_text[i][j]); printf("\n"); } /**************************************************************/ MY_MAGIC(1); //initialize simulation on processing element (PE) for(i=0;i<4;i++) for(j=0;j<4;j++) state[i][j]=plain_text[i][j]; aes128_keyexpansion(cipher_key); aes128_addroundkey(0); for(round=1;round<10;round++){ aes128_subbytes(); aes128_shiftrows(); aes128_mixcolumns(); aes128_addroundkey(round); } aes128_subbytes(); aes128_shiftrows();
106 aes128_addroundkey(10); MY_MAGIC(2); //Collect simulation data on PE /*************************************************************/ } printf("\nciphertext:\n"); for(i=0;i<4;i++){ for(j=0;j<4;j++) printf(" %x",state[i][j]); printf("\n"); } return 0;
107 REFERENCES [1] National Institute of Standards and Technology, Federal Information Processing Standards Publication 197, 2001 [2] Joan Daemen and Vincent Rijmen, "The Design of Rijndael: AES - The Advanced Encryption Standard." Springer, 2002. ISBN 3-540-42580-2 [3] Samir Palnitkar, Verilog HDL, A Guide to Digital Design and Synthesis, Prentice Hall, 2003 [4] Chris Spear, SystemVerilog for Verification, Springer, 2008 [5] Stuart Sutherland, SystenVerilog for Design, Springer, 2006 [6] Synopsys Inc, Synthesis Quick Reference, 2002 [7] http://www.virtutech.com/whatissimics.html [8] Virtuetech Inc, Getting Started with Simics, 2009