diff --git a/SYCL/SYCL/AES.cpp b/SYCL/SYCL/AES.cpp index 13678de..80ade09 100644 --- a/SYCL/SYCL/AES.cpp +++ b/SYCL/SYCL/AES.cpp @@ -5,6 +5,9 @@ #include #include "AES.h" #include "API.h" +#include +using namespace sycl; + namespace MyAES { AES::AES(const AESKeyLength keyLength) @@ -30,15 +33,15 @@ namespace MyAES { } unsigned char* AES::EncryptCBC(const unsigned char in[], unsigned int& inLen, const unsigned char key[], const unsigned char* iv) { API::writeLog("AES::EncryptCBC"); - // Adjust the input length and get the padded input + //Adjust the input length and get the padded input unsigned char* paddedIn = CheckLength(in, inLen); unsigned char* out = new unsigned char[inLen]; unsigned char block[blockBytesLen]; unsigned char* roundKeys = new unsigned char[NUM_WORDS * WORD * (NR + 1)]; KeyExpansion(key, roundKeys); - // Initialize block with IV + //Initialize block with IV memcpy(block, iv, blockBytesLen); - // Encrypt each block + //Encrypt each block for (unsigned int i = 0; i < inLen; i += blockBytesLen) { XorBlocks(block, paddedIn + i, block, blockBytesLen); EncryptBlock(block, out + i, roundKeys); @@ -66,7 +69,6 @@ namespace MyAES { // Remove padding from the decrypted output unsigned char* unpaddedOut = RemovePadding(out, inLen); delete[] out; - return unpaddedOut; } unsigned char* AES::EncryptECB(const unsigned char in[], unsigned int& inLen, const unsigned char key[]) @@ -78,23 +80,48 @@ namespace MyAES { unsigned char* out = new unsigned char[inLen]; unsigned char* roundKeys = new unsigned char[NUM_WORDS * WORD * (NR + 1)]; KeyExpansion(key, roundKeys); - // Encrypt each block - for (unsigned int i = 0; i < inLen; i += blockBytesLen) { - EncryptBlock(paddedIn + i, out + i, roundKeys); - } - delete[] roundKeys; - delete[] paddedIn; // Clean up padded input - return out; + //// SYCL setup + queue q; + buffer bufIn(paddedIn, range<1>(inLen)); + buffer bufOut(out, range<1>(inLen)); + buffer bufRoundKeys(roundKeys, range<1>(NUM_WORDS * WORD * (14 + 1))); + // Encrypt each block in parallel using SYCL + q.submit([&](handler& h) { + + auto inAcc = bufIn.get_access(h); + auto outAcc = bufOut.get_access(h); + auto roundKeysAcc = bufRoundKeys.get_access(h); + h.parallel_for(range<1>(inLen / blockBytesLen), [=](id<1> idx) { + unsigned int i = idx[0] * blockBytesLen; + AES::EncryptBlock(inAcc.get_pointer() + i, outAcc.get_pointer() + i, roundKeysAcc.get_pointer()); + }); + }).wait(); + + delete[] roundKeys; + delete[] paddedIn; // Clean up padded input + return out; } unsigned char* AES::DecryptECB(const unsigned char in[], unsigned int inLen, const unsigned char key[]) { API::writeLog("AES::DecryptECB"); unsigned char* out = new unsigned char[inLen]; unsigned char* roundKeys = new unsigned char[NUM_WORDS * WORD * (NR + 1)]; KeyExpansion(key, roundKeys); - // Decrypt each block - for (unsigned int i = 0; i < inLen; i += blockBytesLen) { - DecryptBlock(in + i, out + i, roundKeys); - } + //// SYCL setup + queue q; + buffer bufIn(in, range<1>(inLen)); + buffer bufOut(out, range<1>(inLen)); + buffer bufRoundKeys(roundKeys, range<1>(NUM_WORDS * WORD * (14 + 1))); + // Encrypt each block in parallel using SYCL + q.submit([&](handler& h) { + + auto inAcc = bufIn.get_access(h); + auto outAcc = bufOut.get_access(h); + auto roundKeysAcc = bufRoundKeys.get_access(h); + h.parallel_for(range<1>(inLen / blockBytesLen), [=](id<1> idx) { + unsigned int i = idx[0] * blockBytesLen; + AES::DecryptBlock(inAcc.get_pointer() + i, outAcc.get_pointer() + i, roundKeysAcc.get_pointer()); + }); + }).wait(); delete[] roundKeys; // Remove padding from the decrypted output unsigned char* unpaddedOut = RemovePadding(out, inLen); @@ -232,6 +259,7 @@ namespace MyAES { } void AES::EncryptBlock(const unsigned char in[], unsigned char out[], unsigned char* roundKeys) { + int nr = 14, nk = 8; unsigned char state[NUM_WORDS][WORD]; unsigned int i, j, round; for (i = 0; i < NUM_WORDS; i++) @@ -239,7 +267,7 @@ namespace MyAES { state[i][j] = in[i + WORD * j]; AddRoundKey(state, roundKeys); //In every round except the last, the following steps are performed: - for (round = 1; round <= NR - 1; round++) + for (round = 1; round <= nr - 1; round++) { SubBytes(state); ShiftRows(state); @@ -249,12 +277,15 @@ namespace MyAES { //the last round: SubBytes(state); ShiftRows(state); - AddRoundKey(state, roundKeys + NR * NUM_WORDS * WORD); + AddRoundKey(state, roundKeys + nr * NUM_WORDS * WORD); for (i = 0; i < NUM_WORDS; i++) for (j = 0; j < WORD; j++) out[i + NUM_WORDS * j] = state[i][j]; } + + void AES::DecryptBlock(const unsigned char in[], unsigned char out[], unsigned char* roundKeys) { + int nr = 14; unsigned char state[NUM_WORDS][WORD]; unsigned int i, j, round; @@ -264,9 +295,9 @@ namespace MyAES { } } - AddRoundKey(state, roundKeys + NR * NUM_WORDS * WORD); + AddRoundKey(state, roundKeys + nr * NUM_WORDS * WORD); - for (round = NR - 1; round >= 1; round--) { + for (round = nr - 1; round >= 1; round--) { InvSubBytes(state); InvShiftRows(state); AddRoundKey(state, roundKeys + round * NUM_WORDS * WORD); @@ -330,7 +361,8 @@ namespace MyAES { for (j = 0; j < WORD; j++) { t = state[i][j]; - state[i][j] = sbox[t / 16][t % 16]; + //state[i][j] = sbox[t]; + state[i][j] = sbox[t/16][t%16]; } } //The function receives the state matrix and moves the rows. Second row-1, third row-2, fourth row-3 @@ -366,8 +398,9 @@ namespace MyAES { memset(temp_state[i], 0, NUM_WORDS); for (size_t i = 0; i < NUM_WORDS; ++i) { for (size_t k = 0; k < NUM_WORDS; ++k) { - for (size_t j = 0; j < NUM_WORDS; ++j) { - if (CMDS[i][k] == 1) + for (size_t j = 0; j < WORD; ++j) { + unsigned char cmd = CMDS[i][k]; + if (cmd == 1) temp_state[i][j] ^= state[k][j]; else temp_state[i][j] ^= GF_MUL_TABLE[CMDS[i][k]][state[k][j]]; diff --git a/SYCL/SYCL/AES.h b/SYCL/SYCL/AES.h index 72c6e13..226581a 100644 --- a/SYCL/SYCL/AES.h +++ b/SYCL/SYCL/AES.h @@ -5,10 +5,13 @@ #include #include #include +#include +using namespace sycl; using namespace std; //word=NUM_WORDS bytes #define WORD 4 #define NUM_WORDS 4 + namespace MyAES { enum class AESKeyLength { AES_128, AES_192, AES_256 }; @@ -20,21 +23,20 @@ namespace MyAES unsigned char* CheckLength(const unsigned char in[], unsigned int& inLen); unsigned char xtime(unsigned char b); void XorBlocks(const unsigned char* a, const unsigned char* b, unsigned char* c, unsigned int len); - void EncryptBlock(const unsigned char in[], unsigned char out[], unsigned char* roundKeys); - void InvSubBytes(unsigned char state[NUM_WORDS][WORD]); - void InvMixColumns(unsigned char state[NUM_WORDS][WORD]); - void InvShiftRows(unsigned char state[NUM_WORDS][WORD]); - void DecryptBlock(const unsigned char in[], unsigned char out[], unsigned char* roundKeys); + static void InvSubBytes(unsigned char state[NUM_WORDS][WORD]); + static void InvMixColumns(unsigned char state[NUM_WORDS][WORD]); + static void InvShiftRows(unsigned char state[NUM_WORDS][WORD]); + static void DecryptBlock(const unsigned char in[], unsigned char out[], unsigned char* roundKeys); + static void EncryptBlock(const unsigned char in[], unsigned char out[], unsigned char* roundKeys); + static void AddRoundKey(unsigned char state[NUM_WORDS][WORD], unsigned char* key); + static void MixColumns(unsigned char state[NUM_WORDS][WORD]); + static void ShiftRows(unsigned char state[NUM_WORDS][WORD]); + static void ShiftRow(unsigned char state[NUM_WORDS][WORD], unsigned int i, unsigned int j); + static void SubBytes(unsigned char state[NUM_WORDS][WORD]); unsigned char* RemovePadding(const unsigned char* in, unsigned int& outLen); void KeyExpansion(const unsigned char key[], unsigned char w[]); - void SubBytes(unsigned char state[NUM_WORDS][WORD]); - void FindInSBox(int r, int c); void RotWord(unsigned char* a); void SubWord(unsigned char* a); - void AddRoundKey(unsigned char state[NUM_WORDS][WORD], unsigned char* key); - void MixColumns(unsigned char state[NUM_WORDS][WORD]); - void ShiftRows(unsigned char state[NUM_WORDS][WORD]); - void ShiftRow(unsigned char state[NUM_WORDS][WORD], unsigned int i, unsigned int j); void XorWords(unsigned char* a, unsigned char* b, unsigned char* c); void Rcon(unsigned char* a, unsigned int n); public: @@ -45,7 +47,7 @@ namespace MyAES unsigned char* DecryptECB(const unsigned char in[], unsigned int inLen, const unsigned char key[]); }; } - unsigned const char sbox[16][16] = { + unsigned static const char sbox[16][16] = { {0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76}, {0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf,