diff options
-rw-r--r-- | aes.cpp | 31 | ||||
-rw-r--r-- | aes.h | 3 |
2 files changed, 21 insertions, 13 deletions
@@ -1,5 +1,3 @@ -#include <iostream> -#include <iomanip> #include <stdexcept> #include <cstring> #include <cassert> @@ -17,16 +15,12 @@ namespace AES{ //State is represented in bytes, as is the key schedule (which is represented in words in the AES spec). //State is in column-major order. + //Most functions (and the three tables below) refer to similarly named functions and tables in the AES + //spec. The core AES algorithm is not documented here. + uint32_t roundconstant[10]={}; uint8_t sbox[256]={}; - uint8_t invsbox[256]={}; - - void printstate(const uint8_t *state){ - for(int i=0;i<16;i++){ - cout<<setw(2)<<setfill('0')<<hex<<(int)state[i]<<dec; - } - cout<<endl; - } + uint8_t invsbox[256]={}; //look-up table of sbox void initTables(){ //generated tables have been checked with AES spec @@ -140,6 +134,7 @@ namespace AES{ } + //The AES block encryption algorithm specified in the AES spec void encryptBlock(uint8_t *state,const uint8_t *keysched,const uint8_t *data,int numrounds){ memcpy(state,data,16); @@ -155,6 +150,7 @@ namespace AES{ addRoundKey(state,keysched+16*numrounds); } + //The AES block decryption algorithm specified in the AES spec void decryptBlock(uint8_t *state,const uint8_t *keysched,const uint8_t *data,int numrounds){ memcpy(state,data,16); @@ -170,6 +166,14 @@ namespace AES{ addRoundKey(state,keysched); } + //Encrypt variably sized data with a key (assumed to be of valid length). + //This applies the CBC algorithm: first generate an IV and add it to the + //ciphertext as the first block. Then when encrypting the next block, first + //xor it with the previous encrypted block. With this encryption method, all + //of the encrypted text is influenced by the random IV, and therefore + //different each time. + //Padding is standard: if n>0 bytes are needed to reach a multiple of 16 bytes, + //n bytes of padding are added with the value n. This is easily reversible. string encryptCBC(const string &data,const string &key,int numrounds){ if(roundconstant[0]==0)initTables(); @@ -200,13 +204,14 @@ namespace AES{ } if(padding<16)memcpy(inbuf,data.data()+16*blocks,16-padding); - memset(inbuf+16-padding,padding,padding); + memset(inbuf+16-padding,padding,padding); //apply the padding for(int j=0;j<16;j++)inbuf[j]^=res[res.size()-16+j]; //the CBC xor step - encryptBlock(buf,keysched,inbuf,numrounds); + encryptBlock(buf,keysched,inbuf,numrounds); //encrypt the final padded block res.insert(res.size(),(char*)buf,16); return res; } + //The inverse of encryptCBC string decryptCBC(const string &data,const string &key,int numrounds){ if(roundconstant[0]==0)initTables(); @@ -228,6 +233,7 @@ namespace AES{ return res; } + //Public interface to encryptCBC string encrypt(const string &data,const string &key,Algorithm algo){ int increment; switch(algo){ @@ -240,6 +246,7 @@ namespace AES{ return encryptCBC(data,key,10+2*increment); } + //Public interface to decryptCBC string decrypt(const string &data,const string &key,Algorithm algo){ int increment; switch(algo){ @@ -12,7 +12,8 @@ namespace AES{ std::string encrypt(const std::string &data,const std::string &key,Algorithm algo); - //throws invalid_argument for an invalid ciphertext (length not a multiple of block size, or padding malformed) or an invalid key (invalid length) + //throws invalid_argument for an invalid ciphertext (length not a multiple of block + //size, or padding malformed) or an invalid key (invalid length) std::string decrypt(const std::string &data,const std::string &key,Algorithm algo); } |