aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--aes.cpp31
-rw-r--r--aes.h3
2 files changed, 21 insertions, 13 deletions
diff --git a/aes.cpp b/aes.cpp
index 7430717..f36a69f 100644
--- a/aes.cpp
+++ b/aes.cpp
@@ -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){
diff --git a/aes.h b/aes.h
index 9274d21..77dc9d2 100644
--- a/aes.h
+++ b/aes.h
@@ -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);
}