Menu Close

Kryptologie (Praktikum 3)

Skript-AnfangKryptouebung2 – Seite 1
Skript-EndeKryptouebung2 – Seite 1

main.cpp


// Präprozessor-Direktiven
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include "myGUI.h"

// Using-Deklarationen
using namespace std;

int main(int argc, char** argv) {
    myGUI gui;
}// main

myGUI.h


#ifndef MYGUI_H
#define	MYGUI_H

#include <iostream>
#include "myCBC.h"
#include "myECB.h"

class myGUI {
public:
    myGUI();
    void callAES();
    void callCBC();
    void callECB();
    bool checkAES();
    bool checkCBC();
    bool checkECB();
    int validatedInput(unsigned int, unsigned int);
    virtual ~myGUI();
private:
};

#endif	/* MYGUI_H */

myGUI.cpp


#include "myGUI.h"
#include <vector>

using namespace std;

bool areEqual(vector<uchar> v1, vector<uchar> v2) {
    bool tmp = false;
    if (v1.size() == v2.size()) {
        for (int i = 0; i < v1.size(); i++) {
            if (v1[i] == v2[i]) {
                tmp = true;
            } else {
                cout << hex << v1[i] << "!=" << v2[i] << endl;
                tmp = false;
                break;
            }
        }
    }
    return tmp;
}

bool areEqual(uchar* arr1, uchar* arr2) {
    bool tmp = false;
    for (int i = 0; i < 16; i++) {
        if (arr1[i] == arr2[i]) {
            tmp = true;
        } else {
            cout << hex << arr1[i] << "!=" << arr2[i] << endl;
            tmp = false;
            break;
        }
    }
    return tmp;
}

bool myGUI::checkCBC() {
    bool returnValue = false;

    //16 Byte Testvektoren
    uchar keyB[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar ivB[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    uchar klartextB1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar ciphertextB1[16] = {0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d};
    vector<uchar> cipherB1;
    vector<uchar> ktB;

    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartextB1[i]);
        cipherB1.push_back(ciphertextB1[i]);
    }

    myCBC cbcB;
    cbcB.setKey(keyB);
    cbcB.setIV(ivB);
    cbcB.setKlartext(ktB);
    cbcB.crypt(false);

    // 32 Byte Testvektoren

    uchar klartextA1[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
    uchar klartextA2[16] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};
    uchar ivA[16] = {0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28, 0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58};
    uchar keyA[16] = {0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0, 0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a};
    uchar ciphertextA1[16] = {0xd2, 0x96, 0xcd, 0x94, 0xc2, 0xcc, 0xcf, 0x8a, 0x3a, 0x86, 0x30, 0x28, 0xb5, 0xe1, 0xdc, 0x0a};
    uchar ciphertextA2[16] = {0x75, 0x86, 0x60, 0x2d, 0x25, 0x3c, 0xff, 0xf9, 0x1b, 0x82, 0x66, 0xbe, 0xa6, 0xd6, 0x1a, 0xb1};
    vector<uchar> cipherA1;

    vector<uchar> test;

    for (int i = 0; i < 16; i++) {
        test.push_back(klartextA1[i]);
        cipherA1.push_back(ciphertextA1[i]);
    }

    for (int i = 0; i < 16; i++) {
        test.push_back(klartextA2[i]);
        cipherA1.push_back(ciphertextA2[i]);
    }

    myCBC cbcA;
    cbcA.setKey(keyA);
    cbcA.setIV(ivA);
    cbcA.setKlartext(test);
    cbcA.crypt(false);

    //Prüfung
    bool isWorking = areEqual(cbcA.getCiphertext(), cipherA1) && areEqual(cbcB.getCiphertext(), cipherB1);

    if (isWorking) {
        returnValue = true;
    } else {
        returnValue = false;
    }
    return returnValue;
}

bool myGUI::checkECB() {
    bool returnValue = false;

    //16 Byte Testvektoren
    uchar schluessel[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};

    uchar klartext_1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar klartext_2[16] = {0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
    uchar klartext_3[16] = {0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef};

    uchar cipher_1[16] = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97};
    uchar cipher_2[16] = {0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d, 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf};
    uchar cipher_3[16] = {0x43, 0xb1, 0xcd, 0x7f, 0x59, 0x8e, 0xce, 0x23, 0x88, 0x1b, 0x00, 0xe3, 0xed, 0x03, 0x06, 0x88};
    vector<uchar> cipherB1;
    vector<uchar> ktB;

    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_1[i]);
        cipherB1.push_back(cipher_1[i]);
    }

    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_2[i]);
        cipherB1.push_back(cipher_2[i]);
    }

    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_3[i]);
        cipherB1.push_back(cipher_3[i]);
    }

    myECB ecb;
    ecb.setKey(schluessel);
    ecb.setKlartext(ktB);
    ecb.crypt(false);

    //Prüfung
    bool isWorking = areEqual(ecb.getCiphertext(), cipherB1);

    if (isWorking) {
        returnValue = true;
    } else {
        returnValue = false;
    }
    return returnValue;
}

bool myGUI::checkAES() {

    bool returnValue = false;
    uchar schluessel[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};

    uchar klartext_1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar klartext_2[16] = {0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
    uchar klartext_3[16] = {0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef};

    uchar cipher_1[16] = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97};
    uchar cipher_2[16] = {0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d, 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf};
    uchar cipher_3[16] = {0x43, 0xb1, 0xcd, 0x7f, 0x59, 0x8e, 0xce, 0x23, 0x88, 0x1b, 0x00, 0xe3, 0xed, 0x03, 0x06, 0x88};

    myAES aes1;
    aes1.setKlartext(klartext_1);
    aes1.setSchluessel(schluessel);
    aes1.crypt(false);

    myAES aes2;
    aes2.setKlartext(klartext_2);
    aes2.setSchluessel(schluessel);
    aes2.crypt(false);

    myAES aes3;
    aes3.setKlartext(klartext_3);
    aes3.setSchluessel(schluessel);
    aes3.crypt(false);

    bool isWorking = areEqual(aes3.getCiphertext(), cipher_3) && areEqual(aes2.getCiphertext(), cipher_2) && areEqual(aes1.getCiphertext(), cipher_1);
    if (isWorking) {
        returnValue = true;
    } else {

        returnValue = false;
    }
    return returnValue;
}

void myGUI::callAES() {
    string RED_start = "3[22;31m";
    string RED_end = "3[0m";
    myAES aes;
    aes.crypt(false);
    //myAES aesDecrypt;
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 5;
    int input = end;

    //Menu Eingabe
    while (run) {
        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Text und Schluessel aus Datei laden\n";
        cout << "(4) Entschluesseln \n";
        cout << "(5) Zurueck\n";
        cout << "> ";
        input = validatedInput(lowest, end);
        if (input == 1) {
            aes.crypt(true);
        }
        if (input == 2) {
            aes.enterKlartext();
            aes.enterSchluessel();
            aes.crypt(true);
        }
        if (input == 3) {
            cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
        }
        if (input == 4) {
            aes.decrypt(true);
        }
        if (input == 5) {
            run = false;
        }
        if (input == -1) {

            cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
            cout << endl;
        }
    }
}

void myGUI::callCBC() {
    string RED_start = "3[22;31m";
    string RED_end = "3[0m";
    myCBC cbc;
    cbc.crypt(true);
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 5;
    int input = end;

    //Menu Eingabe
    while (run) {

        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Text und Schluessel aus Datei laden\n";
        cout << "(4) Text entschluesseln\n";
        cout << "(5) Zurueck\n";
        cout << "> ";
        input = validatedInput(lowest, end);
        if (input == 1) {
            cbc.crypt(true);
        }
        if (input == 2) {
            cbc.enterIV();
            cbc.enterKey();
            cbc.enterKlartext();
            cbc.crypt(true);
        }
        if (input == 3) {
            cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
        }
        if (input == 4) {
            cbc.decrypt(true);
        }
        if (input == 5) {
            run = false;
        }
        if (input == -1) {
            cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
            cout << endl;
        }
    }

}

void myGUI::callECB() {
    string RED_start = "3[22;31m";
    string RED_end = "3[0m";
    myECB ecb;
    ecb.crypt(false);
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 5;
    int input = end;

    //Menu Eingabe
    while (run) {

        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Text und Schluessel aus Datei laden\n";
        cout << "(4) Text entschluesseln\n";
        cout << "(5) Zurueck\n";
        cout << "> ";
        input = validatedInput(lowest, end);
        if (input == 1) {
            ecb.crypt(true);
        }
        if (input == 2) {
            ecb.enterKey();
            ecb.enterKlartext();
            ecb.crypt(true);
        }
        if (input == 3) {
            cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
        }
        if (input == 4) {
                ecb.decrypt(true);
        }
        if (input == 5) {
            run = false;
        }
        if (input == -1) {
            cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
            cout << endl;
        }
    }

}

int myGUI::validatedInput(unsigned int lowest, unsigned int highest) {
    int tmp = 0;
    cin.clear();
    if (cin >> tmp) {//Eingabe ist in Ordnung
        cout << endl;
        if (tmp >= lowest && tmp <= highest) {//Eingabe liegt in den Parametern

            return tmp;
        }
    } else {
        string trash = "";
        cin.clear();
        std::getline(std::cin, trash);
    }
    return -1;
}

myGUI::myGUI() {
    string RED_start = "3[22;31m";
    string RED_end = "3[0m";
    string GREEN_start = "3[22;32m";
    string GREEN_end = "3[0m";
    //Menu-Variablen

    unsigned int lowest = 1;
    unsigned int end = 4;
    int input = end;
    bool run = true;

    //Start
    cout << "#### Kryptographie Sommersemester 2013 ####\n";
    cout << "Nils Rogmann (725915) und Maximilian Krieg (725922)\n";

    // Begrüßung und Information
    cout << "\nHerzlich willkommen.\n";
    cout << "Das Programm wird nun mit Hilfe von Testvektoren geprüft.\n";

    // AES Check
    cout << "\nAES:\t\t";
    if (checkAES()) {
        cout << GREEN_start << "OK" << GREEN_end;
    } else {
        cerr << RED_start << "Fehler" << RED_end;
    }

    // CBC Check
    cout << "\nAES mit CBC:\t";
    if (checkCBC()) {
        cout << GREEN_start << "OK" << GREEN_end;
    } else {
        cerr << RED_start << "Fehler" << RED_end;
    }


    // ECB Check
    cout << "\nAES mit ECB:\t";
    if (checkECB()) 
    {
        cout << GREEN_start << "OK" << GREEN_end;
    }
    else
    {
        cerr << RED_start << "Fehler" << RED_end;
    }
    cout << endl;

    //Menu Eingabe
    while (run) {
        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) AES\n";
        cout << "(2) AES mit CBC\n";
        cout << "(3) AES mit ECB\n";
        cout << "(4) Programm beenden\n";
        cout << "> ";

        input = validatedInput(lowest, end);

        // Aufrufe
        if (input == 1) {
            cout << GREEN_start << "#### AES ####\n" << GREEN_end;
            callAES();
            cout << endl;
        }

        if (input == 2) {
            cout << GREEN_start << "#### AES mit CBC ####\n" << GREEN_end;
            callCBC();
            cout << endl;
        }


        if (input == 3) {
            cout << GREEN_start << "#### AES mit ECB ####\n" << GREEN_end;
            callECB();
            cout << endl;
        }

        // Fehler
        if (input == -1) {
            cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
            cout << endl;
        }

        // Beenden
        if (input == end) {

            cout << "Programm wird beendet.\n";
            run = false;
            cout << endl;
        }
    }
}

myGUI::~myGUI() {
}

myAES.h


#ifndef MYAES_H
#define	MYAES_H

#include <iostream>

using namespace std;
// Typedefs
typedef unsigned char uchar;

class myAES {
public:
    // Konstruktoren/Destruktoren
    myAES();
    virtual ~myAES();

    // Manuelle Eingabe
    void enterKlartext();
    void enterSchluessel();

    // Set/Get-Methoden
    void setKlartext(uchar[16]);
    void setSchluessel(uchar[16]);
    void setCiphertext(uchar[16]);
    uchar* getKlartext();
    uchar* getSchluessel();
    uchar* getCiphertext();

    // AES-Methoden
    void crypt(bool);
    void mixcolumns();
    void shiftrows();
    void schluesselexpansion(uchar[][44], int, int, int);
    void rotword(uchar[], int);
    uchar mix(uchar, unsigned int);
    void subbytes(uchar [], uchar [], int);

    // Print-Methoden
    void printSchluessel();
    void printCiphertext();
    void printKlartext();
    
   void decrypt(bool) ;
   uchar gmul(uchar, uchar);
   void invert_mixcolumns();
   void invert_shiftrows();

private:
    uchar klartext[16];
    uchar schluessel[16];
    uchar ciphertext[16];
};



#endif	/* MYAES_H */

myAES.cpp


#include "myAES.h"
using namespace std;
unsigned char Sbox[256] = {//  s-box
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, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
};
unsigned char sbox_inverse[256] = {
0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
};
unsigned char Rcon[256] = {
0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,
0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,
0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,
0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,
0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b,
0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,
0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,
0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d
};
void myAES::subbytes(uchar sbox[], uchar tmp[], int arrSize) {
for (int i = 0; i < arrSize; i++) {
tmp[i] = sbox[tmp[i]];
}
}// subbytes
uchar myAES::mix(uchar byte, unsigned int mixvalue) {
unsigned char retValue;
switch (mixvalue) {
case 1:
retValue = byte;
break;
case 2:
retValue = byte << 1;
if (byte & 0x80) {
retValue = retValue ^ 0x1b;
}
break;
case 3:
retValue = byte << 1;
if (byte & 0x80) {
retValue = retValue ^ 0x1b;
}
retValue = retValue^byte;
break;
}
return retValue;
}
void addRoundKey(uchar klartext[], int iLaenge, uchar matrix[][44], int iReihe, int iSpalte, int iRunde) {
int pos = 0;
for (int i = iRunde * 4; i < ((iRunde * 4) + 4) && i < iSpalte; i++) {
for (int k = 0; k < iReihe; k++) {
klartext[pos] = klartext[pos] ^ matrix[k][i];
pos++;
}
}
}// addroundkey
void myAES::rotword(uchar column[], int iReihe) {
uchar tmp = column[0];
for (int i = 1; i < iReihe; i++) {
column[i - 1] = column[i];
}
column[iReihe - 1] = tmp;
} // rotword
void myAES::schluesselexpansion(uchar matrix[][44], int iReihe, int iSpalte, int iLaenge) {
// Alle Spalten durchlaufen
int pos = 0;
for (int i = 0; i < iSpalte; i++) {
if (i < 4) { // Schluessel in erste vier Spalten kopieren
for (int k = 0; k < iReihe && pos < iLaenge; k++) {
matrix[k][i] = schluessel[pos];
pos++;
//cout << hex << "matrix[" << k << "][" << i << "] = " << (int) matrix[k][i] << endl;
}
} else { // i > 4
if (i % 4 == 0) {// erste Spalte eines Schluessels
// Spalte in Hilfsarray kopieren
uchar tmp[iReihe]; // i-1
uchar tmp2[iReihe]; // i-4
for (int k = 0; k < iReihe; k++) {
tmp[k] = matrix[k][i - 1];
tmp2[k] = matrix[k][i - 4];
}
rotword(tmp, iReihe);
subbytes(Sbox, tmp, iReihe);
// Spalte[i-4] XOR subbytes[rotword[i-i]
for (int k = 0; k < iReihe; k++) {
tmp[k] = tmp[k] ^ tmp2[k];
}
// tmp[0] XOR (i/4)
tmp[0] = tmp[0] ^ Rcon[i / iReihe];
// tmp[k] an Spalte[k][i] kopieren
for (int k = 0; k < iReihe; k++) {
matrix[k][i] = tmp[k];
}
} else {
//cout << "i " << i << endl;
for (int k = 0; k < iReihe; k++) {
matrix[k][i] = matrix[k][i - 4] ^ matrix[k][i - 1];
}
}
}
}
}// schluesselexpansion
void myAES::shiftrows() {
uchar copys[16] = {};
//reihe 1   
copys[0] = ciphertext[0];
copys[4] = ciphertext[4];
copys[8] = ciphertext[8];
copys[12] = ciphertext[12];
//reihe 2
copys[1] = ciphertext[5];
copys[5] = ciphertext[9];
copys[9] = ciphertext[13];
copys[13] = ciphertext[1];
// reihe 3
copys[2] = ciphertext[10];
copys[6] = ciphertext[14];
copys[10] = ciphertext[2];
copys[14] = ciphertext[6];
//reihe 4
copys[3] = ciphertext[15];
copys[7] = ciphertext[3];
copys[11] = ciphertext[7];
copys[15] = ciphertext[11];
//umschreiben   
for (int i = 0; i < 16; i++) {
ciphertext[i] = copys[i];
}
}// shiftrows
void myAES::mixcolumns() {
for (int i = 0; i < 4; i++) {
uchar sj0 = mix(ciphertext[i * 4], 2)^mix(ciphertext[i * 4 + 1], 3)^mix(ciphertext[i * 4 + 2], 1)^mix(ciphertext[i * 4 + 3], 1);
uchar sj1 = mix(ciphertext[i * 4], 1)^mix(ciphertext[i * 4 + 1], 2)^mix(ciphertext[i * 4 + 2], 3)^mix(ciphertext[i * 4 + 3], 1);
uchar sj2 = mix(ciphertext[i * 4], 1)^mix(ciphertext[i * 4 + 1], 1)^mix(ciphertext[i * 4 + 2], 2)^mix(ciphertext[i * 4 + 3], 3);
uchar sj3 = mix(ciphertext[i * 4], 3)^mix(ciphertext[i * 4 + 1], 1)^mix(ciphertext[i * 4 + 2], 1)^mix(ciphertext[i * 4 + 3], 2);
ciphertext[i * 4] = sj0;
ciphertext[i * 4 + 1] = sj1;
ciphertext[i * 4 + 2] = sj2;
ciphertext[i * 4 + 3] = sj3;
}
}// mixcolumns
void myAES::crypt(bool output) {
// Parameter
int iRunde = 10;
int iLaenge = 16;
// Überschreibe ciphertext um diesen fortan zu verwenden
for (int i = 0; i < 16; i++) {
ciphertext[i] = klartext[i];
}
// Arraygroesse dynamisch bestimmen
int arrSize = sizeof (ciphertext) / sizeof (ciphertext[0]);
// Zwischenspeicherung der Rundenschluessel
int iReihe = 4;
int iSpalte = 4 * (iRunde + 1);
uchar carrRundenschluessel[4][44];
// Schluessel expandieren
schluesselexpansion(carrRundenschluessel, iReihe, iSpalte, iLaenge);
// Vorrunde
for (int k = 0; k < iLaenge; k++) {
ciphertext[k] = ciphertext[k] ^ schluessel[k];
}
// Durchlaufen der Runden
for (int i = 1; i < iRunde + 1; i++) {
// S-Box
subbytes(Sbox, ciphertext, arrSize);
// Shift Rows
shiftrows();
// Mix Columns
if (i != (iRunde)) { // kein MixColumns in der letzten Runde
mixcolumns();
}
// Rundenschlüssel addieren
addRoundKey(ciphertext, arrSize, carrRundenschluessel, iReihe, iSpalte, i);
}
// Ausgabe des Ciphertexts
if (output) {
printSchluessel();
printKlartext();
printCiphertext();
}
}
void myAES::invert_shiftrows() {
uchar copys[16] = {};
//reihe 1   
copys[0] = klartext[0];
copys[4] = klartext[4];
copys[8] = klartext[8];
copys[12] = klartext[12];
//reihe 2
copys[1] = klartext[13];
copys[13] = klartext[9];
copys[9] = klartext[5];
copys[5] = klartext[1];
// reihe 3   
copys[6] = klartext[14];
copys[2] = klartext[10];
copys[14] = klartext[6];
copys[10] = klartext[2];
//reihe 4
copys[11] = klartext[15];
copys[7] = klartext[11];
copys[3] = klartext[7];
copys[15] = klartext[3];
//umschreiben   
for (int i = 0; i < 16; i++) {
klartext[i] = copys[i];
}
}// invert_shiftrows
void myAES::invert_mixcolumns() {
for (int i = 0; i < 4; i++) {
uchar sj0 = gmul(klartext[i * 4], 14)^gmul(klartext[i * 4 + 1], 11)^gmul(klartext[i * 4 + 2], 13)^gmul(klartext[i * 4 + 3], 9);
uchar sj1 = gmul(klartext[i * 4], 9)^gmul(klartext[i * 4 + 1], 14)^gmul(klartext[i * 4 + 2], 11)^gmul(klartext[i * 4 + 3], 13);
uchar sj2 = gmul(klartext[i * 4], 13)^gmul(klartext[i * 4 + 1], 9)^gmul(klartext[i * 4 + 2], 14)^gmul(klartext[i * 4 + 3], 11);
uchar sj3 = gmul(klartext[i * 4], 11)^gmul(klartext[i * 4 + 1], 13)^gmul(klartext[i * 4 + 2], 9)^gmul(klartext[i * 4 + 3], 14);
klartext[i * 4] = sj0;
klartext[i * 4 + 1] = sj1;
klartext[i * 4 + 2] = sj2;
klartext[i * 4 + 3] = sj3;
}
}
uchar myAES::gmul(uchar a, uchar b) {
unsigned char p = 0;
unsigned char hi;
for (int i = 0; i < 8; ++i) {
if ((b & 1) == 1)
p ^= a;
hi = (a & 0x80);
a <<= 1;
if (hi == 0x80)
a ^= 0x1b;
b >>= 1;
}
return p;
}
void myAES::decrypt(bool output) {
// Parameter
int iRunde = 10;
int iLaenge = 16;
// Überschreibe klartext um diesen fortan zu verwenden
for (int i = 0; i < 16; i++) {
klartext[i] = ciphertext[i];
}
// Arraygroesse dynamisch bestimmen
int arrSize = sizeof (klartext) / sizeof (klartext[0]);
// Zwischenspeicherung der Rundenschluessel
int iReihe = 4;
int iSpalte = 4 * (iRunde + 1);
uchar carrRundenschluessel[4][44];
// Schluessel expandieren
schluesselexpansion(carrRundenschluessel, iReihe, iSpalte, iLaenge);
//printRundenSchluessel(carrRundenschluessel, iReihe, iSpalte);
// "neue" Vorrunde
addRoundKey(klartext, arrSize, carrRundenschluessel, iReihe, iSpalte, 10);
// Durchlaufen der Runden
for (int i = 9; i > 0; i--) {
// Shift Rows
invert_shiftrows();
// S-Box
subbytes(sbox_inverse, klartext, arrSize);
// Rundenschlüssel addieren
addRoundKey(klartext, arrSize, carrRundenschluessel, iReihe, iSpalte, i);
// Mix Columns
if (i != 10) { // kein MixColumns in der letzten Runde
invert_mixcolumns();
}
}
// Letzte Runde
invert_shiftrows();
subbytes(sbox_inverse, klartext, arrSize);
for (int k = 0; k < iLaenge; k++) {
klartext[k] = klartext[k] ^ schluessel[k];
}
// Ausgabe des Ciphertexts
if (output) {
printSchluessel();
printCiphertext();
printKlartext();
}
}// decrypt
void myAES::printSchluessel() {
cout << endl << "Schluessel:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) schluessel[0 + i] << "\t0x" << (int) schluessel [4 + i] << "\t0x" << (int) schluessel [8 + i] << "\t0x" << (int) schluessel[12 + i] << endl;
cout << endl;
}
void myAES::printCiphertext() {
cout << endl << "Ciphertext:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) ciphertext[0 + i] << "\t0x" << (int) ciphertext [4 + i] << "\t0x" << (int) ciphertext [8 + i] << "\t0x" << (int) ciphertext[12 + i] << endl;
cout << endl;
}
void myAES::printKlartext() {
cout << endl << "Klartext:\n";
for (int i = 0; i < 4; i++)
cout << hex << "\t0x" << (int) klartext[0 + i] << "\t0x" << (int) klartext [4 + i] << "\t0x" << (int) klartext [8 + i] << "\t0x" << (int) klartext[12 + i] << endl;
cout << endl;
}
myAES::myAES() {
uchar kt[16] = {0x61, 0x62, 0x62, 0x69, 0x6c, 0x64, 0x75, 0x6e, 0x67, 0x73, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78};
uchar s[16] = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31};
//uchar c[16] = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31};
for (int i = 0; i < 16; i++) {
schluessel[i] = s[i];
klartext[i] = kt[i];
}
}
myAES::~myAES() {
}
void myAES::enterKlartext() {
string RED_start = "3[22;31m";
string RED_end = "3[0m";
string GREEN_start = "3[22;32m";
string GREEN_end = "3[0m";
string tmp = "";
int diff = 0;
cout << "Klartext (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den Klartext zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\nWert fuer den Klartext zu klein. Fuelle mit Nullen auf.\n";
diff = 16 - tmp.length();
for (int i = 0; i < diff; i++) {
tmp.push_back('
Menu Close

Kryptologie (Praktikum 3)

Skript-AnfangKryptouebung2 – Seite 1
Skript-EndeKryptouebung2 – Seite 1

main.cpp


// Präprozessor-Direktiven
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include "myGUI.h"

// Using-Deklarationen
using namespace std;

int main(int argc, char** argv) {
    myGUI gui;
}// main

myGUI.h


#ifndef MYGUI_H
#define	MYGUI_H

#include <iostream>
#include "myCBC.h"
#include "myECB.h"

class myGUI {
public:
    myGUI();
    void callAES();
    void callCBC();
    void callECB();
    bool checkAES();
    bool checkCBC();
    bool checkECB();
    int validatedInput(unsigned int, unsigned int);
    virtual ~myGUI();
private:
};

#endif	/* MYGUI_H */

myGUI.cpp


#include "myGUI.h"
#include <vector>

using namespace std;

bool areEqual(vector<uchar> v1, vector<uchar> v2) {
    bool tmp = false;
    if (v1.size() == v2.size()) {
        for (int i = 0; i < v1.size(); i++) {
            if (v1[i] == v2[i]) {
                tmp = true;
            } else {
                cout << hex << v1[i] << "!=" << v2[i] << endl;
                tmp = false;
                break;
            }
        }
    }
    return tmp;
}

bool areEqual(uchar* arr1, uchar* arr2) {
    bool tmp = false;
    for (int i = 0; i < 16; i++) {
        if (arr1[i] == arr2[i]) {
            tmp = true;
        } else {
            cout << hex << arr1[i] << "!=" << arr2[i] << endl;
            tmp = false;
            break;
        }
    }
    return tmp;
}

bool myGUI::checkCBC() {
    bool returnValue = false;

    //16 Byte Testvektoren
    uchar keyB[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar ivB[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    uchar klartextB1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar ciphertextB1[16] = {0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d};
    vector<uchar> cipherB1;
    vector<uchar> ktB;

    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartextB1[i]);
        cipherB1.push_back(ciphertextB1[i]);
    }

    myCBC cbcB;
    cbcB.setKey(keyB);
    cbcB.setIV(ivB);
    cbcB.setKlartext(ktB);
    cbcB.crypt(false);

    // 32 Byte Testvektoren

    uchar klartextA1[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
    uchar klartextA2[16] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};
    uchar ivA[16] = {0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28, 0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58};
    uchar keyA[16] = {0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0, 0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a};
    uchar ciphertextA1[16] = {0xd2, 0x96, 0xcd, 0x94, 0xc2, 0xcc, 0xcf, 0x8a, 0x3a, 0x86, 0x30, 0x28, 0xb5, 0xe1, 0xdc, 0x0a};
    uchar ciphertextA2[16] = {0x75, 0x86, 0x60, 0x2d, 0x25, 0x3c, 0xff, 0xf9, 0x1b, 0x82, 0x66, 0xbe, 0xa6, 0xd6, 0x1a, 0xb1};
    vector<uchar> cipherA1;

    vector<uchar> test;

    for (int i = 0; i < 16; i++) {
        test.push_back(klartextA1[i]);
        cipherA1.push_back(ciphertextA1[i]);
    }

    for (int i = 0; i < 16; i++) {
        test.push_back(klartextA2[i]);
        cipherA1.push_back(ciphertextA2[i]);
    }

    myCBC cbcA;
    cbcA.setKey(keyA);
    cbcA.setIV(ivA);
    cbcA.setKlartext(test);
    cbcA.crypt(false);

    //Prüfung
    bool isWorking = areEqual(cbcA.getCiphertext(), cipherA1) && areEqual(cbcB.getCiphertext(), cipherB1);

    if (isWorking) {
        returnValue = true;
    } else {
        returnValue = false;
    }
    return returnValue;
}

bool myGUI::checkECB() {
    bool returnValue = false;

    //16 Byte Testvektoren
    uchar schluessel[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};

    uchar klartext_1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar klartext_2[16] = {0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
    uchar klartext_3[16] = {0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef};

    uchar cipher_1[16] = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97};
    uchar cipher_2[16] = {0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d, 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf};
    uchar cipher_3[16] = {0x43, 0xb1, 0xcd, 0x7f, 0x59, 0x8e, 0xce, 0x23, 0x88, 0x1b, 0x00, 0xe3, 0xed, 0x03, 0x06, 0x88};
    vector<uchar> cipherB1;
    vector<uchar> ktB;

    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_1[i]);
        cipherB1.push_back(cipher_1[i]);
    }

    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_2[i]);
        cipherB1.push_back(cipher_2[i]);
    }

    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_3[i]);
        cipherB1.push_back(cipher_3[i]);
    }

    myECB ecb;
    ecb.setKey(schluessel);
    ecb.setKlartext(ktB);
    ecb.crypt(false);

    //Prüfung
    bool isWorking = areEqual(ecb.getCiphertext(), cipherB1);

    if (isWorking) {
        returnValue = true;
    } else {
        returnValue = false;
    }
    return returnValue;
}

bool myGUI::checkAES() {

    bool returnValue = false;
    uchar schluessel[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};

    uchar klartext_1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar klartext_2[16] = {0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
    uchar klartext_3[16] = {0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef};

    uchar cipher_1[16] = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97};
    uchar cipher_2[16] = {0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d, 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf};
    uchar cipher_3[16] = {0x43, 0xb1, 0xcd, 0x7f, 0x59, 0x8e, 0xce, 0x23, 0x88, 0x1b, 0x00, 0xe3, 0xed, 0x03, 0x06, 0x88};

    myAES aes1;
    aes1.setKlartext(klartext_1);
    aes1.setSchluessel(schluessel);
    aes1.crypt(false);

    myAES aes2;
    aes2.setKlartext(klartext_2);
    aes2.setSchluessel(schluessel);
    aes2.crypt(false);

    myAES aes3;
    aes3.setKlartext(klartext_3);
    aes3.setSchluessel(schluessel);
    aes3.crypt(false);

    bool isWorking = areEqual(aes3.getCiphertext(), cipher_3) && areEqual(aes2.getCiphertext(), cipher_2) && areEqual(aes1.getCiphertext(), cipher_1);
    if (isWorking) {
        returnValue = true;
    } else {

        returnValue = false;
    }
    return returnValue;
}

void myGUI::callAES() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    myAES aes;
    aes.crypt(false);
    //myAES aesDecrypt;
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 5;
    int input = end;

    //Menu Eingabe
    while (run) {
        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Text und Schluessel aus Datei laden\n";
        cout << "(4) Entschluesseln \n";
        cout << "(5) Zurueck\n";
        cout << "> ";
        input = validatedInput(lowest, end);
        if (input == 1) {
            aes.crypt(true);
        }
        if (input == 2) {
            aes.enterKlartext();
            aes.enterSchluessel();
            aes.crypt(true);
        }
        if (input == 3) {
            cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
        }
        if (input == 4) {
            aes.decrypt(true);
        }
        if (input == 5) {
            run = false;
        }
        if (input == -1) {

            cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
            cout << endl;
        }
    }
}

void myGUI::callCBC() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    myCBC cbc;
    cbc.crypt(true);
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 5;
    int input = end;

    //Menu Eingabe
    while (run) {

        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Text und Schluessel aus Datei laden\n";
        cout << "(4) Text entschluesseln\n";
        cout << "(5) Zurueck\n";
        cout << "> ";
        input = validatedInput(lowest, end);
        if (input == 1) {
            cbc.crypt(true);
        }
        if (input == 2) {
            cbc.enterIV();
            cbc.enterKey();
            cbc.enterKlartext();
            cbc.crypt(true);
        }
        if (input == 3) {
            cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
        }
        if (input == 4) {
            cbc.decrypt(true);
        }
        if (input == 5) {
            run = false;
        }
        if (input == -1) {
            cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
            cout << endl;
        }
    }

}

void myGUI::callECB() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    myECB ecb;
    ecb.crypt(false);
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 5;
    int input = end;

    //Menu Eingabe
    while (run) {

        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Text und Schluessel aus Datei laden\n";
        cout << "(4) Text entschluesseln\n";
        cout << "(5) Zurueck\n";
        cout << "> ";
        input = validatedInput(lowest, end);
        if (input == 1) {
            ecb.crypt(true);
        }
        if (input == 2) {
            ecb.enterKey();
            ecb.enterKlartext();
            ecb.crypt(true);
        }
        if (input == 3) {
            cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
        }
        if (input == 4) {
                ecb.decrypt(true);
        }
        if (input == 5) {
            run = false;
        }
        if (input == -1) {
            cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
            cout << endl;
        }
    }

}

int myGUI::validatedInput(unsigned int lowest, unsigned int highest) {
    int tmp = 0;
    cin.clear();
    if (cin >> tmp) {//Eingabe ist in Ordnung
        cout << endl;
        if (tmp >= lowest && tmp <= highest) {//Eingabe liegt in den Parametern

            return tmp;
        }
    } else {
        string trash = "";
        cin.clear();
        std::getline(std::cin, trash);
    }
    return -1;
}

myGUI::myGUI() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    //Menu-Variablen

    unsigned int lowest = 1;
    unsigned int end = 4;
    int input = end;
    bool run = true;

    //Start
    cout << "#### Kryptographie Sommersemester 2013 ####\n";
    cout << "Nils Rogmann (725915) und Maximilian Krieg (725922)\n";

    // Begrüßung und Information
    cout << "\nHerzlich willkommen.\n";
    cout << "Das Programm wird nun mit Hilfe von Testvektoren geprüft.\n";

    // AES Check
    cout << "\nAES:\t\t";
    if (checkAES()) {
        cout << GREEN_start << "OK" << GREEN_end;
    } else {
        cerr << RED_start << "Fehler" << RED_end;
    }

    // CBC Check
    cout << "\nAES mit CBC:\t";
    if (checkCBC()) {
        cout << GREEN_start << "OK" << GREEN_end;
    } else {
        cerr << RED_start << "Fehler" << RED_end;
    }


    // ECB Check
    cout << "\nAES mit ECB:\t";
    if (checkECB()) 
    {
        cout << GREEN_start << "OK" << GREEN_end;
    }
    else
    {
        cerr << RED_start << "Fehler" << RED_end;
    }
    cout << endl;

    //Menu Eingabe
    while (run) {
        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) AES\n";
        cout << "(2) AES mit CBC\n";
        cout << "(3) AES mit ECB\n";
        cout << "(4) Programm beenden\n";
        cout << "> ";

        input = validatedInput(lowest, end);

        // Aufrufe
        if (input == 1) {
            cout << GREEN_start << "#### AES ####\n" << GREEN_end;
            callAES();
            cout << endl;
        }

        if (input == 2) {
            cout << GREEN_start << "#### AES mit CBC ####\n" << GREEN_end;
            callCBC();
            cout << endl;
        }


        if (input == 3) {
            cout << GREEN_start << "#### AES mit ECB ####\n" << GREEN_end;
            callECB();
            cout << endl;
        }

        // Fehler
        if (input == -1) {
            cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
            cout << endl;
        }

        // Beenden
        if (input == end) {

            cout << "Programm wird beendet.\n";
            run = false;
            cout << endl;
        }
    }
}

myGUI::~myGUI() {
}

myAES.h


#ifndef MYAES_H
#define	MYAES_H

#include <iostream>

using namespace std;
// Typedefs
typedef unsigned char uchar;

class myAES {
public:
    // Konstruktoren/Destruktoren
    myAES();
    virtual ~myAES();

    // Manuelle Eingabe
    void enterKlartext();
    void enterSchluessel();

    // Set/Get-Methoden
    void setKlartext(uchar[16]);
    void setSchluessel(uchar[16]);
    void setCiphertext(uchar[16]);
    uchar* getKlartext();
    uchar* getSchluessel();
    uchar* getCiphertext();

    // AES-Methoden
    void crypt(bool);
    void mixcolumns();
    void shiftrows();
    void schluesselexpansion(uchar[][44], int, int, int);
    void rotword(uchar[], int);
    uchar mix(uchar, unsigned int);
    void subbytes(uchar [], uchar [], int);

    // Print-Methoden
    void printSchluessel();
    void printCiphertext();
    void printKlartext();
    
   void decrypt(bool) ;
   uchar gmul(uchar, uchar);
   void invert_mixcolumns();
   void invert_shiftrows();

private:
    uchar klartext[16];
    uchar schluessel[16];
    uchar ciphertext[16];
};



#endif	/* MYAES_H */

myAES.cpp


#include "myAES.h"

using namespace std;

unsigned char Sbox[256] = {//  s-box
    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, 0x9c, 0xa4, 0x72, 0xc0,
    0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
    0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
    0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
    0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
    0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
    0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
    0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
    0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
    0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
    0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
    0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
    0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
    0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
    0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
};

unsigned char sbox_inverse[256] = {
    0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
    0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
    0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
    0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
    0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
    0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
    0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
    0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
    0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
    0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
    0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
    0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
    0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
    0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
    0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
    0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
};

unsigned char Rcon[256] = {
    0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
    0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,
    0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,
    0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
    0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,
    0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,
    0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b,
    0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
    0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
    0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
    0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
    0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
    0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
    0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,
    0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,
    0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d
};

void myAES::subbytes(uchar sbox[], uchar tmp[], int arrSize) {
    for (int i = 0; i < arrSize; i++) {
        tmp[i] = sbox[tmp[i]];
    }
}// subbytes

uchar myAES::mix(uchar byte, unsigned int mixvalue) {
    unsigned char retValue;
    switch (mixvalue) {
        case 1:
            retValue = byte;
            break;
        case 2:
            retValue = byte << 1;
            if (byte & 0x80) {
                retValue = retValue ^ 0x1b;
            }
            break;
        case 3:
            retValue = byte << 1;
            if (byte & 0x80) {
                retValue = retValue ^ 0x1b;
            }
            retValue = retValue^byte;
            break;
    }
    return retValue;
}

void addRoundKey(uchar klartext[], int iLaenge, uchar matrix[][44], int iReihe, int iSpalte, int iRunde) {
    int pos = 0;
    for (int i = iRunde * 4; i < ((iRunde * 4) + 4) && i < iSpalte; i++) {
        for (int k = 0; k < iReihe; k++) {
            klartext[pos] = klartext[pos] ^ matrix[k][i];
            pos++;
        }
    }
}// addroundkey

void myAES::rotword(uchar column[], int iReihe) {
    uchar tmp = column[0];
    for (int i = 1; i < iReihe; i++) {
        column[i - 1] = column[i];
    }
    column[iReihe - 1] = tmp;
} // rotword

void myAES::schluesselexpansion(uchar matrix[][44], int iReihe, int iSpalte, int iLaenge) {
    // Alle Spalten durchlaufen
    int pos = 0;

    for (int i = 0; i < iSpalte; i++) {
        if (i < 4) { // Schluessel in erste vier Spalten kopieren
            for (int k = 0; k < iReihe && pos < iLaenge; k++) {
                matrix[k][i] = schluessel[pos];
                pos++;
                //cout << hex << "matrix[" << k << "][" << i << "] = " << (int) matrix[k][i] << endl;
            }
        } else { // i > 4
            if (i % 4 == 0) {// erste Spalte eines Schluessels
                // Spalte in Hilfsarray kopieren
                uchar tmp[iReihe]; // i-1
                uchar tmp2[iReihe]; // i-4
                for (int k = 0; k < iReihe; k++) {
                    tmp[k] = matrix[k][i - 1];
                    tmp2[k] = matrix[k][i - 4];
                }

                rotword(tmp, iReihe);

                subbytes(Sbox, tmp, iReihe);

                // Spalte[i-4] XOR subbytes[rotword[i-i]
                for (int k = 0; k < iReihe; k++) {
                    tmp[k] = tmp[k] ^ tmp2[k];
                }

                // tmp[0] XOR (i/4)
                tmp[0] = tmp[0] ^ Rcon[i / iReihe];

                // tmp[k] an Spalte[k][i] kopieren
                for (int k = 0; k < iReihe; k++) {
                    matrix[k][i] = tmp[k];
                }

            } else {
                //cout << "i " << i << endl;
                for (int k = 0; k < iReihe; k++) {
                    matrix[k][i] = matrix[k][i - 4] ^ matrix[k][i - 1];
                }
            }
        }
    }
}// schluesselexpansion

void myAES::shiftrows() {
    uchar copys[16] = {};

    //reihe 1   
    copys[0] = ciphertext[0];
    copys[4] = ciphertext[4];
    copys[8] = ciphertext[8];
    copys[12] = ciphertext[12];

    //reihe 2
    copys[1] = ciphertext[5];
    copys[5] = ciphertext[9];
    copys[9] = ciphertext[13];
    copys[13] = ciphertext[1];

    // reihe 3
    copys[2] = ciphertext[10];
    copys[6] = ciphertext[14];
    copys[10] = ciphertext[2];
    copys[14] = ciphertext[6];

    //reihe 4
    copys[3] = ciphertext[15];
    copys[7] = ciphertext[3];
    copys[11] = ciphertext[7];
    copys[15] = ciphertext[11];

    //umschreiben   
    for (int i = 0; i < 16; i++) {
        ciphertext[i] = copys[i];
    }
}// shiftrows

void myAES::mixcolumns() {
    for (int i = 0; i < 4; i++) {
        uchar sj0 = mix(ciphertext[i * 4], 2)^mix(ciphertext[i * 4 + 1], 3)^mix(ciphertext[i * 4 + 2], 1)^mix(ciphertext[i * 4 + 3], 1);
        uchar sj1 = mix(ciphertext[i * 4], 1)^mix(ciphertext[i * 4 + 1], 2)^mix(ciphertext[i * 4 + 2], 3)^mix(ciphertext[i * 4 + 3], 1);
        uchar sj2 = mix(ciphertext[i * 4], 1)^mix(ciphertext[i * 4 + 1], 1)^mix(ciphertext[i * 4 + 2], 2)^mix(ciphertext[i * 4 + 3], 3);
        uchar sj3 = mix(ciphertext[i * 4], 3)^mix(ciphertext[i * 4 + 1], 1)^mix(ciphertext[i * 4 + 2], 1)^mix(ciphertext[i * 4 + 3], 2);
        ciphertext[i * 4] = sj0;
        ciphertext[i * 4 + 1] = sj1;
        ciphertext[i * 4 + 2] = sj2;
        ciphertext[i * 4 + 3] = sj3;
    }
}// mixcolumns

void myAES::crypt(bool output) {

    // Parameter
    int iRunde = 10;
    int iLaenge = 16;

    // Überschreibe ciphertext um diesen fortan zu verwenden
    for (int i = 0; i < 16; i++) {
        ciphertext[i] = klartext[i];
    }

    // Arraygroesse dynamisch bestimmen
    int arrSize = sizeof (ciphertext) / sizeof (ciphertext[0]);

    // Zwischenspeicherung der Rundenschluessel
    int iReihe = 4;
    int iSpalte = 4 * (iRunde + 1);
    uchar carrRundenschluessel[4][44];

    // Schluessel expandieren
    schluesselexpansion(carrRundenschluessel, iReihe, iSpalte, iLaenge);

    // Vorrunde
    for (int k = 0; k < iLaenge; k++) {
        ciphertext[k] = ciphertext[k] ^ schluessel[k];
    }

    // Durchlaufen der Runden
    for (int i = 1; i < iRunde + 1; i++) {

        // S-Box
        subbytes(Sbox, ciphertext, arrSize);

        // Shift Rows
        shiftrows();

        // Mix Columns
        if (i != (iRunde)) { // kein MixColumns in der letzten Runde
            mixcolumns();
        }

        // Rundenschlüssel addieren
        addRoundKey(ciphertext, arrSize, carrRundenschluessel, iReihe, iSpalte, i);

    }

    // Ausgabe des Ciphertexts
    if (output) {
        printSchluessel();
        printKlartext();
        printCiphertext();
    }
}

void myAES::invert_shiftrows() {
    uchar copys[16] = {};

    //reihe 1   
    copys[0] = klartext[0];
    copys[4] = klartext[4];
    copys[8] = klartext[8];
    copys[12] = klartext[12];

    //reihe 2
    copys[1] = klartext[13];
    copys[13] = klartext[9];
    copys[9] = klartext[5];
    copys[5] = klartext[1];

    // reihe 3   
    copys[6] = klartext[14];
    copys[2] = klartext[10];
    copys[14] = klartext[6];
    copys[10] = klartext[2];

    //reihe 4
    copys[11] = klartext[15];
    copys[7] = klartext[11];
    copys[3] = klartext[7];
    copys[15] = klartext[3];

    //umschreiben   
    for (int i = 0; i < 16; i++) {
        klartext[i] = copys[i];
    }
}// invert_shiftrows

void myAES::invert_mixcolumns() {
    for (int i = 0; i < 4; i++) {
        uchar sj0 = gmul(klartext[i * 4], 14)^gmul(klartext[i * 4 + 1], 11)^gmul(klartext[i * 4 + 2], 13)^gmul(klartext[i * 4 + 3], 9);
        uchar sj1 = gmul(klartext[i * 4], 9)^gmul(klartext[i * 4 + 1], 14)^gmul(klartext[i * 4 + 2], 11)^gmul(klartext[i * 4 + 3], 13);
        uchar sj2 = gmul(klartext[i * 4], 13)^gmul(klartext[i * 4 + 1], 9)^gmul(klartext[i * 4 + 2], 14)^gmul(klartext[i * 4 + 3], 11);
        uchar sj3 = gmul(klartext[i * 4], 11)^gmul(klartext[i * 4 + 1], 13)^gmul(klartext[i * 4 + 2], 9)^gmul(klartext[i * 4 + 3], 14);
        klartext[i * 4] = sj0;
        klartext[i * 4 + 1] = sj1;
        klartext[i * 4 + 2] = sj2;
        klartext[i * 4 + 3] = sj3;
    }
}

uchar myAES::gmul(uchar a, uchar b) {
    unsigned char p = 0;
    unsigned char hi;

    for (int i = 0; i < 8; ++i) {
        if ((b & 1) == 1)
            p ^= a;
        hi = (a & 0x80);
        a <<= 1;
        if (hi == 0x80)
            a ^= 0x1b;
        b >>= 1;
    }
    return p;
}

void myAES::decrypt(bool output) {

    // Parameter
    int iRunde = 10;
    int iLaenge = 16;


    // Überschreibe klartext um diesen fortan zu verwenden
    for (int i = 0; i < 16; i++) {
        klartext[i] = ciphertext[i];
    }


    // Arraygroesse dynamisch bestimmen
    int arrSize = sizeof (klartext) / sizeof (klartext[0]);

    // Zwischenspeicherung der Rundenschluessel
    int iReihe = 4;
    int iSpalte = 4 * (iRunde + 1);
    uchar carrRundenschluessel[4][44];

    // Schluessel expandieren
    schluesselexpansion(carrRundenschluessel, iReihe, iSpalte, iLaenge);

    //printRundenSchluessel(carrRundenschluessel, iReihe, iSpalte);

    // "neue" Vorrunde
    addRoundKey(klartext, arrSize, carrRundenschluessel, iReihe, iSpalte, 10);

    // Durchlaufen der Runden
    for (int i = 9; i > 0; i--) {

        // Shift Rows
        invert_shiftrows();

        // S-Box
        subbytes(sbox_inverse, klartext, arrSize);

        // Rundenschlüssel addieren
        addRoundKey(klartext, arrSize, carrRundenschluessel, iReihe, iSpalte, i);

        // Mix Columns
        if (i != 10) { // kein MixColumns in der letzten Runde
            invert_mixcolumns();
        }
    }


    // Letzte Runde
    invert_shiftrows();
    subbytes(sbox_inverse, klartext, arrSize);

    for (int k = 0; k < iLaenge; k++) {
        klartext[k] = klartext[k] ^ schluessel[k];
    }

    // Ausgabe des Ciphertexts
    if (output) {
        printSchluessel();
        printCiphertext();
        printKlartext();
    }
}// decrypt

void myAES::printSchluessel() {
    cout << endl << "Schluessel:\n";
    for (int i = 0; i < 4; i++)
        cout << hex << "\t0x" << (int) schluessel[0 + i] << "\t0x" << (int) schluessel [4 + i] << "\t0x" << (int) schluessel [8 + i] << "\t0x" << (int) schluessel[12 + i] << endl;
    cout << endl;
}

void myAES::printCiphertext() {
    cout << endl << "Ciphertext:\n";
    for (int i = 0; i < 4; i++)
        cout << hex << "\t0x" << (int) ciphertext[0 + i] << "\t0x" << (int) ciphertext [4 + i] << "\t0x" << (int) ciphertext [8 + i] << "\t0x" << (int) ciphertext[12 + i] << endl;
    cout << endl;
}

void myAES::printKlartext() {
    cout << endl << "Klartext:\n";
    for (int i = 0; i < 4; i++)
        cout << hex << "\t0x" << (int) klartext[0 + i] << "\t0x" << (int) klartext [4 + i] << "\t0x" << (int) klartext [8 + i] << "\t0x" << (int) klartext[12 + i] << endl;
    cout << endl;
}

myAES::myAES() {
    uchar kt[16] = {0x61, 0x62, 0x62, 0x69, 0x6c, 0x64, 0x75, 0x6e, 0x67, 0x73, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78};
    uchar s[16] = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31};
    //uchar c[16] = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31};
    for (int i = 0; i < 16; i++) {
        schluessel[i] = s[i];
        klartext[i] = kt[i];
    }
}

myAES::~myAES() {
}

void myAES::enterKlartext() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    string tmp = "";
    int diff = 0;
    cout << "Klartext (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << RED_start << "\nWerte fuer den Klartext zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << RED_start << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << RED_end << endl;
        }

        if (tmp.length() < 16) {
            cerr << RED_start << "\nWert fuer den Klartext zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << RED_end << endl;
        }

        for (int i = 0; i < 16; i++) {
            klartext[i] = tmp[i];
        }
        cout << endl;

    }
}

void myAES::enterSchluessel() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    string tmp = "";
    int diff = 0;
    cout << "Schluessel (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << RED_start << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << RED_end << endl;
        }

        if (tmp.length() < 16) {
            cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << RED_end << endl;
        }

        for (int i = 0; i < 16; i++) {
            schluessel[i] = tmp[i];
            //cout << hex << tmp[i];
        }
        cout << endl;

    }
}

void myAES::setCiphertext(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        ciphertext[i] = tmp[i];
    }

}

void myAES::setKlartext(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        klartext[i] = tmp[i];
    }
}

void myAES::setSchluessel(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        schluessel[i] = tmp[i];

    }
}

uchar* myAES::getSchluessel() {
    return schluessel;
}

uchar* myAES::getCiphertext() {
    return ciphertext;
}

uchar* myAES::getKlartext() {
    return klartext;
}

myCBC.h


#ifndef MYCBC_H
#define	MYCBC_H
#include "myAES.h"
#include <vector>
class myCBC {
public:
    // Konstruktoren / Destruktoren
    myCBC();
    virtual ~myCBC();
    
    //CBC
    void crypt(bool);
    void decrypt(bool);
    
    // Set/Get-Methoden
    void setKey(uchar[16]);
    void setIV(uchar[16]);
    void setKlartext(vector<uchar>);
    void setCiphertext(vector<uchar>);

    vector<uchar> getKlartext();
    vector<uchar> getCiphertext();
    uchar* getSchluessel();
    uchar* getIV();
    
    // Manuelle Eingabe
    void enterKey();
    void enterIV();
    void enterKlartext();
    
    // Print-Methoden
    void printSchluessel();
    void printCiphertext();
    void printKlartext();
    
private:
    //unsigned int stellen;
    uchar iv[16];
    uchar key[16];
    vector<uchar> klartext;
    vector<uchar> ciphertext;

};

#endif	/* MYCBC_H */

myCBC.cpp


#include "myCBC.h"

void myCBC::enterKey() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    string tmp = "";
    int diff = 0;
    cout << "Schluessel (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << RED_start << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << RED_end << endl;
        }

        if (tmp.length() < 16) {
            cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << RED_end << endl;
        }

        for (int i = 0; i < 16; i++) {
            key[i] = tmp[i];
        }
        cout << endl;

    }
}

void myCBC::enterIV() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    string tmp = "";
    int diff = 0;
    cout << "IV (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << RED_start << "\nWerte fuer den IV zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << RED_start << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << RED_end << endl;
        }

        if (tmp.length() < 16) {
            cerr << RED_start << "\nWert fuer den IV zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << RED_end << endl;
        }

        for (int i = 0; i < 16; i++) {
            iv[i] = tmp[i];
        }
        cout << endl;

    }
}

void myCBC::enterKlartext() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    klartext.clear();
    string tmp = "";
    cout << "Klartext (Beliebig viele Zeichen):";
    if (cin >> tmp) {
        for (int i = 0; i < tmp.size(); i++) {
            klartext.push_back(tmp[i]);
        }
        cout << endl;
    }

    if (tmp.size() % 16 != 0) {
        cerr << RED_start << "\nLetzter Klartext-Block nicht vollstaendig. Fuelle mit Nullen auf.\n";
        for (int i = 0; i < 16 - tmp.size() % 16; i++) {
            klartext.push_back('\0');
        }
        cout << RED_end << endl;
    }
}

myCBC::myCBC() {

    // Default Parameter
    uchar newKey[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar newIV[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    uchar newKlartext[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};

    // Schluessel setzen
    for (int i = 0; i < 16; i++) {
        key[i] = newKey[i];
    }

    //IV setzen
    for (int i = 0; i < 16; i++) {
        iv[i] = newIV[i];
    }

    // Klartext setzen
    for (int i = 0; i < 16; i++) {
        klartext.push_back(newKlartext[i]);
    }
}

void myCBC::printSchluessel() {
    cout << endl << "Schluessel:\n";
    for (int i = 0; i < 4; i++)
        cout << hex << "\t0x" << (int) key[0 + i] << "\t0x" << (int) key [4 + i] << "\t0x" << (int) key [8 + i] << "\t0x" << (int) key[12 + i] << endl;
    cout << endl;
}

void myCBC::printCiphertext() {
    cout << endl << "Ciphertext:\n";
    for (int i = 0; i < ciphertext.size(); i++) {
        cout << std::hex << " 0x" << (int) ciphertext[i];
    }
}

void myCBC::printKlartext() {
    cout << endl << "Klartext:\n";
    for (int i = 0; i < klartext.size(); i++) {
        cout << std::hex << " 0x" << (int) klartext[i];
    }
}

vector<uchar> myCBC::getCiphertext() {
    return ciphertext;
}

void myCBC::decrypt(bool print) {
    klartext.clear();
    uchar tmp_iv[16];
    for (int j = 0; j < 16; j++) {
        tmp_iv[j] = iv[j];
    }
    //printSchluessel();
    //printKlartext();
    //printCiphertext();
    for (int i = 0; i < ciphertext.size() / 16; i++) {

        myAES a1;

        //Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = ciphertext[j + 16 * i];
        }

        // Ciphertext
        a1.setCiphertext(tmp);

        // Schluessel
        a1.setSchluessel(key);

        // crypt
        a1.decrypt(false);

        // Resultat mit IV addieren
        for (int j = 0; j < 16; j++) {

            a1.getKlartext()[j] = a1.getKlartext()[j]^tmp_iv[j];
        }

        for (int j = 0; j < 16; j++) {
            tmp_iv[j] = a1.getCiphertext()[j + 16 * i];
            klartext.push_back(a1.getKlartext()[j]);
        }
    }

    if (print) {
        printSchluessel();
        printCiphertext();
        printKlartext();
    }

}

void myCBC::crypt(bool print) {
    ciphertext.clear();
    uchar tmp_iv[16];
    for (int i = 0; i < 16; i++) {
        tmp_iv[i] = iv[i];
    }

    for (int i = 0; i < klartext.size() / 16; i++) {

        myAES a1;
        a1.setSchluessel(key);

        //XOR in Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = klartext[j + 16 * i]^tmp_iv[j];
        }

        // Klartext
        a1.setKlartext(tmp);

        // crypt
        a1.crypt(false);


        for (int j = 0; j < 16; j++) {
            tmp_iv[j] = a1.getCiphertext()[j];
            ciphertext.push_back(a1.getCiphertext()[j]);
        }
    }

    if (print) {
        printSchluessel();
        printKlartext();
        printCiphertext();
    }
}

void myCBC::setKlartext(vector<uchar> kt) {
    if (kt.size() > klartext.size()) {
        int diff = kt.size() - klartext.size();
        for (int i = 0; i < diff; i++) {
            klartext.push_back(0x00);
        }
    }
    for (int i = 0; i < kt.size(); i++) {
        klartext.at(i) = kt.at(i);
    }
}

void myCBC::setIV(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        iv[i] = tmp[i];
    }
}

void myCBC::setKey(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        key[i] = tmp[i];
    }
}

myCBC::~myCBC() {
}

myECB.h



#ifndef MYECB_H
#define	MYECB_H

#include "myAES.h"
#include <vector>
class myECB {
public:
    // Konstruktoren / Destruktoren
    myECB();
    virtual ~myECB();
    
    //CBC
    void crypt(bool);
    void decrypt(bool);
    
    // Set/Get-Methoden
    void setKey(uchar[16]);
    
    void setKlartext(vector<uchar>);
    void setCiphertext(vector<uchar>);

    vector<uchar> getKlartext();
    vector<uchar> getCiphertext();
    uchar* getSchluessel();
    
    
    // Manuelle Eingabe
    void enterKey();
    
    void enterKlartext();
    
    // Print-Methoden
    void printSchluessel();
    void printCiphertext();
    void printKlartext();
    
private:
    //unsigned int stellen;
    
    uchar key[16];
    vector<uchar> klartext;
    vector<uchar> ciphertext;

};

#endif	/* MYECB_H */

myECB.cpp



#include "myECB.h"

void myECB::enterKey() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    string tmp = "";
    int diff = 0;
    cout << "Schluessel (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << RED_start << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << RED_end << endl;
        }

        if (tmp.length() < 16) {
            cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << RED_end << endl;
        }

        for (int i = 0; i < 16; i++) {
            key[i] = tmp[i];
        }
        cout << endl;

    }
}

void myECB::enterKlartext() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    klartext.clear();
    string tmp = "";
    cout << "Klartext (Beliebig viele Zeichen):";
    if (cin >> tmp) {
        for (int i = 0; i < tmp.size(); i++) {
            klartext.push_back(tmp[i]);
        }
        cout << endl;
    }

    if (tmp.size() % 16 != 0) {
        cerr << RED_start << "\nLetzter Klartext-Block nicht vollstaendig. Fuelle mit Nullen auf.\n";
        for (int i = 0; i < 16 - tmp.size() % 16; i++) {
            klartext.push_back('\0');
        }
        cout << RED_end << endl;
    }
}

myECB::myECB() {

    // Default Parameter
    uchar newKey[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar newIV[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    uchar newKlartext[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};

    // Schluessel setzen
    for (int i = 0; i < 16; i++) {
        key[i] = newKey[i];
    }

    // Klartext setzen
    for (int i = 0; i < 16; i++) {
        klartext.push_back(newKlartext[i]);
    }
}

void myECB::printSchluessel() {
    cout << endl << "Schluessel:\n";
    for (int i = 0; i < 4; i++)
        cout << hex << "\t0x" << (int) key[0 + i] << "\t0x" << (int) key [4 + i] << "\t0x" << (int) key [8 + i] << "\t0x" << (int) key[12 + i] << endl;
    cout << endl;
}

void myECB::printCiphertext() {
    cout << endl << "Ciphertext:\n";
    for (int i = 0; i < ciphertext.size(); i++) {
        cout << std::hex << " 0x" << (int) ciphertext[i];
    }
}

void myECB::printKlartext() {
    cout << endl << "Klartext:\n";
    for (int i = 0; i < klartext.size(); i++) {
        cout << std::hex << " 0x" << (int) klartext[i];
    }
}

vector<uchar> myECB::getCiphertext() {
    return ciphertext;
}

void myECB::decrypt(bool print) {
    klartext.clear();

    for (int i = 0; i < ciphertext.size() / 16; i++) {

        myAES a1;

        //Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = ciphertext[j + 16 * i];
        }

        // Ciphertext
        a1.setCiphertext(tmp);

        // Schluessel
        a1.setSchluessel(key);

        // crypt
        a1.decrypt(false);

        // Resultat mit IV addieren
        for (int j = 0; j < 16; j++) {
            klartext.push_back(a1.getKlartext()[j]);
        }
    }

    if (print) {
        printSchluessel();
        printCiphertext();
        printKlartext();
    }

}

void myECB::crypt(bool print) {
    ciphertext.clear();
    /* uchar tmp_iv[16];
     for (int i = 0; i < 16; i++) {
         tmp_iv[i] = iv[i];
     }*/

    for (int i = 0; i < klartext.size() / 16; i++) {

        myAES a1;
        a1.setSchluessel(key);

        //XOR in Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = klartext[j + 16 * i]; //^tmp_iv[j];
        }

        // Klartext
        a1.setKlartext(tmp);

        // crypt
        a1.crypt(false);


        for (int j = 0; j < 16; j++) {
            //tmp_iv[j] = a1.getCiphertext()[j];
            ciphertext.push_back(a1.getCiphertext()[j]);
        }
    }

    if (print) {
        printSchluessel();
        printKlartext();
        printCiphertext();
    }
}

void myECB::setKlartext(vector<uchar> kt) {
    if (kt.size() > klartext.size()) {
        int diff = kt.size() - klartext.size();
        for (int i = 0; i < diff; i++) {
            klartext.push_back(0x00);
        }
    }
    for (int i = 0; i < kt.size(); i++) {
        klartext.at(i) = kt.at(i);
    }
}

void myECB::setKey(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        key[i] = tmp[i];
    }
}

myECB::~myECB() {
}

Schreiben Sie einen Kommentar

Ihre E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahren Sie, wie Ihre Kommentardaten verarbeitet werden.

'); } cout << RED_end << endl; } for (int i = 0; i < 16; i++) { klartext[i] = tmp[i]; } cout << endl; } } void myAES::enterSchluessel() { string RED_start = "3[22;31m"; string RED_end = "3[0m"; string GREEN_start = "3[22;32m"; string GREEN_end = "3[0m"; string tmp = ""; int diff = 0; cout << "Schluessel (16 Zeichen):"; if (cin >> tmp) { if (tmp.length() > 16) { cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start; for (int i = 0; i < tmp.length(); i++) { if (i == 16) { cerr << RED_start << " | "; } cerr << tmp.at(i); } cout << ")" << RED_end << endl; } if (tmp.length() < 16) { cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n"; diff = 16 - tmp.length(); for (int i = 0; i < diff; i++) { tmp.push_back('
Menu Close

Kryptologie (Praktikum 3)

Skript-AnfangKryptouebung2 – Seite 1
Skript-EndeKryptouebung2 – Seite 1

main.cpp


// Präprozessor-Direktiven
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include "myGUI.h"

// Using-Deklarationen
using namespace std;

int main(int argc, char** argv) {
    myGUI gui;
}// main

myGUI.h


#ifndef MYGUI_H
#define	MYGUI_H

#include <iostream>
#include "myCBC.h"
#include "myECB.h"

class myGUI {
public:
    myGUI();
    void callAES();
    void callCBC();
    void callECB();
    bool checkAES();
    bool checkCBC();
    bool checkECB();
    int validatedInput(unsigned int, unsigned int);
    virtual ~myGUI();
private:
};

#endif	/* MYGUI_H */

myGUI.cpp


#include "myGUI.h"
#include <vector>

using namespace std;

bool areEqual(vector<uchar> v1, vector<uchar> v2) {
    bool tmp = false;
    if (v1.size() == v2.size()) {
        for (int i = 0; i < v1.size(); i++) {
            if (v1[i] == v2[i]) {
                tmp = true;
            } else {
                cout << hex << v1[i] << "!=" << v2[i] << endl;
                tmp = false;
                break;
            }
        }
    }
    return tmp;
}

bool areEqual(uchar* arr1, uchar* arr2) {
    bool tmp = false;
    for (int i = 0; i < 16; i++) {
        if (arr1[i] == arr2[i]) {
            tmp = true;
        } else {
            cout << hex << arr1[i] << "!=" << arr2[i] << endl;
            tmp = false;
            break;
        }
    }
    return tmp;
}

bool myGUI::checkCBC() {
    bool returnValue = false;

    //16 Byte Testvektoren
    uchar keyB[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar ivB[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    uchar klartextB1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar ciphertextB1[16] = {0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d};
    vector<uchar> cipherB1;
    vector<uchar> ktB;

    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartextB1[i]);
        cipherB1.push_back(ciphertextB1[i]);
    }

    myCBC cbcB;
    cbcB.setKey(keyB);
    cbcB.setIV(ivB);
    cbcB.setKlartext(ktB);
    cbcB.crypt(false);

    // 32 Byte Testvektoren

    uchar klartextA1[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
    uchar klartextA2[16] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};
    uchar ivA[16] = {0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28, 0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58};
    uchar keyA[16] = {0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0, 0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a};
    uchar ciphertextA1[16] = {0xd2, 0x96, 0xcd, 0x94, 0xc2, 0xcc, 0xcf, 0x8a, 0x3a, 0x86, 0x30, 0x28, 0xb5, 0xe1, 0xdc, 0x0a};
    uchar ciphertextA2[16] = {0x75, 0x86, 0x60, 0x2d, 0x25, 0x3c, 0xff, 0xf9, 0x1b, 0x82, 0x66, 0xbe, 0xa6, 0xd6, 0x1a, 0xb1};
    vector<uchar> cipherA1;

    vector<uchar> test;

    for (int i = 0; i < 16; i++) {
        test.push_back(klartextA1[i]);
        cipherA1.push_back(ciphertextA1[i]);
    }

    for (int i = 0; i < 16; i++) {
        test.push_back(klartextA2[i]);
        cipherA1.push_back(ciphertextA2[i]);
    }

    myCBC cbcA;
    cbcA.setKey(keyA);
    cbcA.setIV(ivA);
    cbcA.setKlartext(test);
    cbcA.crypt(false);

    //Prüfung
    bool isWorking = areEqual(cbcA.getCiphertext(), cipherA1) && areEqual(cbcB.getCiphertext(), cipherB1);

    if (isWorking) {
        returnValue = true;
    } else {
        returnValue = false;
    }
    return returnValue;
}

bool myGUI::checkECB() {
    bool returnValue = false;

    //16 Byte Testvektoren
    uchar schluessel[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};

    uchar klartext_1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar klartext_2[16] = {0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
    uchar klartext_3[16] = {0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef};

    uchar cipher_1[16] = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97};
    uchar cipher_2[16] = {0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d, 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf};
    uchar cipher_3[16] = {0x43, 0xb1, 0xcd, 0x7f, 0x59, 0x8e, 0xce, 0x23, 0x88, 0x1b, 0x00, 0xe3, 0xed, 0x03, 0x06, 0x88};
    vector<uchar> cipherB1;
    vector<uchar> ktB;

    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_1[i]);
        cipherB1.push_back(cipher_1[i]);
    }

    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_2[i]);
        cipherB1.push_back(cipher_2[i]);
    }

    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_3[i]);
        cipherB1.push_back(cipher_3[i]);
    }

    myECB ecb;
    ecb.setKey(schluessel);
    ecb.setKlartext(ktB);
    ecb.crypt(false);

    //Prüfung
    bool isWorking = areEqual(ecb.getCiphertext(), cipherB1);

    if (isWorking) {
        returnValue = true;
    } else {
        returnValue = false;
    }
    return returnValue;
}

bool myGUI::checkAES() {

    bool returnValue = false;
    uchar schluessel[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};

    uchar klartext_1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar klartext_2[16] = {0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
    uchar klartext_3[16] = {0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef};

    uchar cipher_1[16] = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97};
    uchar cipher_2[16] = {0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d, 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf};
    uchar cipher_3[16] = {0x43, 0xb1, 0xcd, 0x7f, 0x59, 0x8e, 0xce, 0x23, 0x88, 0x1b, 0x00, 0xe3, 0xed, 0x03, 0x06, 0x88};

    myAES aes1;
    aes1.setKlartext(klartext_1);
    aes1.setSchluessel(schluessel);
    aes1.crypt(false);

    myAES aes2;
    aes2.setKlartext(klartext_2);
    aes2.setSchluessel(schluessel);
    aes2.crypt(false);

    myAES aes3;
    aes3.setKlartext(klartext_3);
    aes3.setSchluessel(schluessel);
    aes3.crypt(false);

    bool isWorking = areEqual(aes3.getCiphertext(), cipher_3) && areEqual(aes2.getCiphertext(), cipher_2) && areEqual(aes1.getCiphertext(), cipher_1);
    if (isWorking) {
        returnValue = true;
    } else {

        returnValue = false;
    }
    return returnValue;
}

void myGUI::callAES() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    myAES aes;
    aes.crypt(false);
    //myAES aesDecrypt;
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 5;
    int input = end;

    //Menu Eingabe
    while (run) {
        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Text und Schluessel aus Datei laden\n";
        cout << "(4) Entschluesseln \n";
        cout << "(5) Zurueck\n";
        cout << "> ";
        input = validatedInput(lowest, end);
        if (input == 1) {
            aes.crypt(true);
        }
        if (input == 2) {
            aes.enterKlartext();
            aes.enterSchluessel();
            aes.crypt(true);
        }
        if (input == 3) {
            cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
        }
        if (input == 4) {
            aes.decrypt(true);
        }
        if (input == 5) {
            run = false;
        }
        if (input == -1) {

            cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
            cout << endl;
        }
    }
}

void myGUI::callCBC() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    myCBC cbc;
    cbc.crypt(true);
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 5;
    int input = end;

    //Menu Eingabe
    while (run) {

        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Text und Schluessel aus Datei laden\n";
        cout << "(4) Text entschluesseln\n";
        cout << "(5) Zurueck\n";
        cout << "> ";
        input = validatedInput(lowest, end);
        if (input == 1) {
            cbc.crypt(true);
        }
        if (input == 2) {
            cbc.enterIV();
            cbc.enterKey();
            cbc.enterKlartext();
            cbc.crypt(true);
        }
        if (input == 3) {
            cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
        }
        if (input == 4) {
            cbc.decrypt(true);
        }
        if (input == 5) {
            run = false;
        }
        if (input == -1) {
            cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
            cout << endl;
        }
    }

}

void myGUI::callECB() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    myECB ecb;
    ecb.crypt(false);
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 5;
    int input = end;

    //Menu Eingabe
    while (run) {

        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Text und Schluessel aus Datei laden\n";
        cout << "(4) Text entschluesseln\n";
        cout << "(5) Zurueck\n";
        cout << "> ";
        input = validatedInput(lowest, end);
        if (input == 1) {
            ecb.crypt(true);
        }
        if (input == 2) {
            ecb.enterKey();
            ecb.enterKlartext();
            ecb.crypt(true);
        }
        if (input == 3) {
            cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
        }
        if (input == 4) {
                ecb.decrypt(true);
        }
        if (input == 5) {
            run = false;
        }
        if (input == -1) {
            cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
            cout << endl;
        }
    }

}

int myGUI::validatedInput(unsigned int lowest, unsigned int highest) {
    int tmp = 0;
    cin.clear();
    if (cin >> tmp) {//Eingabe ist in Ordnung
        cout << endl;
        if (tmp >= lowest && tmp <= highest) {//Eingabe liegt in den Parametern

            return tmp;
        }
    } else {
        string trash = "";
        cin.clear();
        std::getline(std::cin, trash);
    }
    return -1;
}

myGUI::myGUI() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    //Menu-Variablen

    unsigned int lowest = 1;
    unsigned int end = 4;
    int input = end;
    bool run = true;

    //Start
    cout << "#### Kryptographie Sommersemester 2013 ####\n";
    cout << "Nils Rogmann (725915) und Maximilian Krieg (725922)\n";

    // Begrüßung und Information
    cout << "\nHerzlich willkommen.\n";
    cout << "Das Programm wird nun mit Hilfe von Testvektoren geprüft.\n";

    // AES Check
    cout << "\nAES:\t\t";
    if (checkAES()) {
        cout << GREEN_start << "OK" << GREEN_end;
    } else {
        cerr << RED_start << "Fehler" << RED_end;
    }

    // CBC Check
    cout << "\nAES mit CBC:\t";
    if (checkCBC()) {
        cout << GREEN_start << "OK" << GREEN_end;
    } else {
        cerr << RED_start << "Fehler" << RED_end;
    }


    // ECB Check
    cout << "\nAES mit ECB:\t";
    if (checkECB()) 
    {
        cout << GREEN_start << "OK" << GREEN_end;
    }
    else
    {
        cerr << RED_start << "Fehler" << RED_end;
    }
    cout << endl;

    //Menu Eingabe
    while (run) {
        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) AES\n";
        cout << "(2) AES mit CBC\n";
        cout << "(3) AES mit ECB\n";
        cout << "(4) Programm beenden\n";
        cout << "> ";

        input = validatedInput(lowest, end);

        // Aufrufe
        if (input == 1) {
            cout << GREEN_start << "#### AES ####\n" << GREEN_end;
            callAES();
            cout << endl;
        }

        if (input == 2) {
            cout << GREEN_start << "#### AES mit CBC ####\n" << GREEN_end;
            callCBC();
            cout << endl;
        }


        if (input == 3) {
            cout << GREEN_start << "#### AES mit ECB ####\n" << GREEN_end;
            callECB();
            cout << endl;
        }

        // Fehler
        if (input == -1) {
            cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
            cout << endl;
        }

        // Beenden
        if (input == end) {

            cout << "Programm wird beendet.\n";
            run = false;
            cout << endl;
        }
    }
}

myGUI::~myGUI() {
}

myAES.h


#ifndef MYAES_H
#define	MYAES_H

#include <iostream>

using namespace std;
// Typedefs
typedef unsigned char uchar;

class myAES {
public:
    // Konstruktoren/Destruktoren
    myAES();
    virtual ~myAES();

    // Manuelle Eingabe
    void enterKlartext();
    void enterSchluessel();

    // Set/Get-Methoden
    void setKlartext(uchar[16]);
    void setSchluessel(uchar[16]);
    void setCiphertext(uchar[16]);
    uchar* getKlartext();
    uchar* getSchluessel();
    uchar* getCiphertext();

    // AES-Methoden
    void crypt(bool);
    void mixcolumns();
    void shiftrows();
    void schluesselexpansion(uchar[][44], int, int, int);
    void rotword(uchar[], int);
    uchar mix(uchar, unsigned int);
    void subbytes(uchar [], uchar [], int);

    // Print-Methoden
    void printSchluessel();
    void printCiphertext();
    void printKlartext();
    
   void decrypt(bool) ;
   uchar gmul(uchar, uchar);
   void invert_mixcolumns();
   void invert_shiftrows();

private:
    uchar klartext[16];
    uchar schluessel[16];
    uchar ciphertext[16];
};



#endif	/* MYAES_H */

myAES.cpp


#include "myAES.h"

using namespace std;

unsigned char Sbox[256] = {//  s-box
    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, 0x9c, 0xa4, 0x72, 0xc0,
    0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
    0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
    0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
    0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
    0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
    0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
    0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
    0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
    0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
    0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
    0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
    0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
    0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
    0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
};

unsigned char sbox_inverse[256] = {
    0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
    0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
    0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
    0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
    0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
    0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
    0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
    0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
    0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
    0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
    0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
    0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
    0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
    0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
    0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
    0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
};

unsigned char Rcon[256] = {
    0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
    0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,
    0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,
    0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
    0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,
    0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,
    0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b,
    0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
    0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
    0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
    0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
    0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
    0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
    0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,
    0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,
    0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d
};

void myAES::subbytes(uchar sbox[], uchar tmp[], int arrSize) {
    for (int i = 0; i < arrSize; i++) {
        tmp[i] = sbox[tmp[i]];
    }
}// subbytes

uchar myAES::mix(uchar byte, unsigned int mixvalue) {
    unsigned char retValue;
    switch (mixvalue) {
        case 1:
            retValue = byte;
            break;
        case 2:
            retValue = byte << 1;
            if (byte & 0x80) {
                retValue = retValue ^ 0x1b;
            }
            break;
        case 3:
            retValue = byte << 1;
            if (byte & 0x80) {
                retValue = retValue ^ 0x1b;
            }
            retValue = retValue^byte;
            break;
    }
    return retValue;
}

void addRoundKey(uchar klartext[], int iLaenge, uchar matrix[][44], int iReihe, int iSpalte, int iRunde) {
    int pos = 0;
    for (int i = iRunde * 4; i < ((iRunde * 4) + 4) && i < iSpalte; i++) {
        for (int k = 0; k < iReihe; k++) {
            klartext[pos] = klartext[pos] ^ matrix[k][i];
            pos++;
        }
    }
}// addroundkey

void myAES::rotword(uchar column[], int iReihe) {
    uchar tmp = column[0];
    for (int i = 1; i < iReihe; i++) {
        column[i - 1] = column[i];
    }
    column[iReihe - 1] = tmp;
} // rotword

void myAES::schluesselexpansion(uchar matrix[][44], int iReihe, int iSpalte, int iLaenge) {
    // Alle Spalten durchlaufen
    int pos = 0;

    for (int i = 0; i < iSpalte; i++) {
        if (i < 4) { // Schluessel in erste vier Spalten kopieren
            for (int k = 0; k < iReihe && pos < iLaenge; k++) {
                matrix[k][i] = schluessel[pos];
                pos++;
                //cout << hex << "matrix[" << k << "][" << i << "] = " << (int) matrix[k][i] << endl;
            }
        } else { // i > 4
            if (i % 4 == 0) {// erste Spalte eines Schluessels
                // Spalte in Hilfsarray kopieren
                uchar tmp[iReihe]; // i-1
                uchar tmp2[iReihe]; // i-4
                for (int k = 0; k < iReihe; k++) {
                    tmp[k] = matrix[k][i - 1];
                    tmp2[k] = matrix[k][i - 4];
                }

                rotword(tmp, iReihe);

                subbytes(Sbox, tmp, iReihe);

                // Spalte[i-4] XOR subbytes[rotword[i-i]
                for (int k = 0; k < iReihe; k++) {
                    tmp[k] = tmp[k] ^ tmp2[k];
                }

                // tmp[0] XOR (i/4)
                tmp[0] = tmp[0] ^ Rcon[i / iReihe];

                // tmp[k] an Spalte[k][i] kopieren
                for (int k = 0; k < iReihe; k++) {
                    matrix[k][i] = tmp[k];
                }

            } else {
                //cout << "i " << i << endl;
                for (int k = 0; k < iReihe; k++) {
                    matrix[k][i] = matrix[k][i - 4] ^ matrix[k][i - 1];
                }
            }
        }
    }
}// schluesselexpansion

void myAES::shiftrows() {
    uchar copys[16] = {};

    //reihe 1   
    copys[0] = ciphertext[0];
    copys[4] = ciphertext[4];
    copys[8] = ciphertext[8];
    copys[12] = ciphertext[12];

    //reihe 2
    copys[1] = ciphertext[5];
    copys[5] = ciphertext[9];
    copys[9] = ciphertext[13];
    copys[13] = ciphertext[1];

    // reihe 3
    copys[2] = ciphertext[10];
    copys[6] = ciphertext[14];
    copys[10] = ciphertext[2];
    copys[14] = ciphertext[6];

    //reihe 4
    copys[3] = ciphertext[15];
    copys[7] = ciphertext[3];
    copys[11] = ciphertext[7];
    copys[15] = ciphertext[11];

    //umschreiben   
    for (int i = 0; i < 16; i++) {
        ciphertext[i] = copys[i];
    }
}// shiftrows

void myAES::mixcolumns() {
    for (int i = 0; i < 4; i++) {
        uchar sj0 = mix(ciphertext[i * 4], 2)^mix(ciphertext[i * 4 + 1], 3)^mix(ciphertext[i * 4 + 2], 1)^mix(ciphertext[i * 4 + 3], 1);
        uchar sj1 = mix(ciphertext[i * 4], 1)^mix(ciphertext[i * 4 + 1], 2)^mix(ciphertext[i * 4 + 2], 3)^mix(ciphertext[i * 4 + 3], 1);
        uchar sj2 = mix(ciphertext[i * 4], 1)^mix(ciphertext[i * 4 + 1], 1)^mix(ciphertext[i * 4 + 2], 2)^mix(ciphertext[i * 4 + 3], 3);
        uchar sj3 = mix(ciphertext[i * 4], 3)^mix(ciphertext[i * 4 + 1], 1)^mix(ciphertext[i * 4 + 2], 1)^mix(ciphertext[i * 4 + 3], 2);
        ciphertext[i * 4] = sj0;
        ciphertext[i * 4 + 1] = sj1;
        ciphertext[i * 4 + 2] = sj2;
        ciphertext[i * 4 + 3] = sj3;
    }
}// mixcolumns

void myAES::crypt(bool output) {

    // Parameter
    int iRunde = 10;
    int iLaenge = 16;

    // Überschreibe ciphertext um diesen fortan zu verwenden
    for (int i = 0; i < 16; i++) {
        ciphertext[i] = klartext[i];
    }

    // Arraygroesse dynamisch bestimmen
    int arrSize = sizeof (ciphertext) / sizeof (ciphertext[0]);

    // Zwischenspeicherung der Rundenschluessel
    int iReihe = 4;
    int iSpalte = 4 * (iRunde + 1);
    uchar carrRundenschluessel[4][44];

    // Schluessel expandieren
    schluesselexpansion(carrRundenschluessel, iReihe, iSpalte, iLaenge);

    // Vorrunde
    for (int k = 0; k < iLaenge; k++) {
        ciphertext[k] = ciphertext[k] ^ schluessel[k];
    }

    // Durchlaufen der Runden
    for (int i = 1; i < iRunde + 1; i++) {

        // S-Box
        subbytes(Sbox, ciphertext, arrSize);

        // Shift Rows
        shiftrows();

        // Mix Columns
        if (i != (iRunde)) { // kein MixColumns in der letzten Runde
            mixcolumns();
        }

        // Rundenschlüssel addieren
        addRoundKey(ciphertext, arrSize, carrRundenschluessel, iReihe, iSpalte, i);

    }

    // Ausgabe des Ciphertexts
    if (output) {
        printSchluessel();
        printKlartext();
        printCiphertext();
    }
}

void myAES::invert_shiftrows() {
    uchar copys[16] = {};

    //reihe 1   
    copys[0] = klartext[0];
    copys[4] = klartext[4];
    copys[8] = klartext[8];
    copys[12] = klartext[12];

    //reihe 2
    copys[1] = klartext[13];
    copys[13] = klartext[9];
    copys[9] = klartext[5];
    copys[5] = klartext[1];

    // reihe 3   
    copys[6] = klartext[14];
    copys[2] = klartext[10];
    copys[14] = klartext[6];
    copys[10] = klartext[2];

    //reihe 4
    copys[11] = klartext[15];
    copys[7] = klartext[11];
    copys[3] = klartext[7];
    copys[15] = klartext[3];

    //umschreiben   
    for (int i = 0; i < 16; i++) {
        klartext[i] = copys[i];
    }
}// invert_shiftrows

void myAES::invert_mixcolumns() {
    for (int i = 0; i < 4; i++) {
        uchar sj0 = gmul(klartext[i * 4], 14)^gmul(klartext[i * 4 + 1], 11)^gmul(klartext[i * 4 + 2], 13)^gmul(klartext[i * 4 + 3], 9);
        uchar sj1 = gmul(klartext[i * 4], 9)^gmul(klartext[i * 4 + 1], 14)^gmul(klartext[i * 4 + 2], 11)^gmul(klartext[i * 4 + 3], 13);
        uchar sj2 = gmul(klartext[i * 4], 13)^gmul(klartext[i * 4 + 1], 9)^gmul(klartext[i * 4 + 2], 14)^gmul(klartext[i * 4 + 3], 11);
        uchar sj3 = gmul(klartext[i * 4], 11)^gmul(klartext[i * 4 + 1], 13)^gmul(klartext[i * 4 + 2], 9)^gmul(klartext[i * 4 + 3], 14);
        klartext[i * 4] = sj0;
        klartext[i * 4 + 1] = sj1;
        klartext[i * 4 + 2] = sj2;
        klartext[i * 4 + 3] = sj3;
    }
}

uchar myAES::gmul(uchar a, uchar b) {
    unsigned char p = 0;
    unsigned char hi;

    for (int i = 0; i < 8; ++i) {
        if ((b & 1) == 1)
            p ^= a;
        hi = (a & 0x80);
        a <<= 1;
        if (hi == 0x80)
            a ^= 0x1b;
        b >>= 1;
    }
    return p;
}

void myAES::decrypt(bool output) {

    // Parameter
    int iRunde = 10;
    int iLaenge = 16;


    // Überschreibe klartext um diesen fortan zu verwenden
    for (int i = 0; i < 16; i++) {
        klartext[i] = ciphertext[i];
    }


    // Arraygroesse dynamisch bestimmen
    int arrSize = sizeof (klartext) / sizeof (klartext[0]);

    // Zwischenspeicherung der Rundenschluessel
    int iReihe = 4;
    int iSpalte = 4 * (iRunde + 1);
    uchar carrRundenschluessel[4][44];

    // Schluessel expandieren
    schluesselexpansion(carrRundenschluessel, iReihe, iSpalte, iLaenge);

    //printRundenSchluessel(carrRundenschluessel, iReihe, iSpalte);

    // "neue" Vorrunde
    addRoundKey(klartext, arrSize, carrRundenschluessel, iReihe, iSpalte, 10);

    // Durchlaufen der Runden
    for (int i = 9; i > 0; i--) {

        // Shift Rows
        invert_shiftrows();

        // S-Box
        subbytes(sbox_inverse, klartext, arrSize);

        // Rundenschlüssel addieren
        addRoundKey(klartext, arrSize, carrRundenschluessel, iReihe, iSpalte, i);

        // Mix Columns
        if (i != 10) { // kein MixColumns in der letzten Runde
            invert_mixcolumns();
        }
    }


    // Letzte Runde
    invert_shiftrows();
    subbytes(sbox_inverse, klartext, arrSize);

    for (int k = 0; k < iLaenge; k++) {
        klartext[k] = klartext[k] ^ schluessel[k];
    }

    // Ausgabe des Ciphertexts
    if (output) {
        printSchluessel();
        printCiphertext();
        printKlartext();
    }
}// decrypt

void myAES::printSchluessel() {
    cout << endl << "Schluessel:\n";
    for (int i = 0; i < 4; i++)
        cout << hex << "\t0x" << (int) schluessel[0 + i] << "\t0x" << (int) schluessel [4 + i] << "\t0x" << (int) schluessel [8 + i] << "\t0x" << (int) schluessel[12 + i] << endl;
    cout << endl;
}

void myAES::printCiphertext() {
    cout << endl << "Ciphertext:\n";
    for (int i = 0; i < 4; i++)
        cout << hex << "\t0x" << (int) ciphertext[0 + i] << "\t0x" << (int) ciphertext [4 + i] << "\t0x" << (int) ciphertext [8 + i] << "\t0x" << (int) ciphertext[12 + i] << endl;
    cout << endl;
}

void myAES::printKlartext() {
    cout << endl << "Klartext:\n";
    for (int i = 0; i < 4; i++)
        cout << hex << "\t0x" << (int) klartext[0 + i] << "\t0x" << (int) klartext [4 + i] << "\t0x" << (int) klartext [8 + i] << "\t0x" << (int) klartext[12 + i] << endl;
    cout << endl;
}

myAES::myAES() {
    uchar kt[16] = {0x61, 0x62, 0x62, 0x69, 0x6c, 0x64, 0x75, 0x6e, 0x67, 0x73, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78};
    uchar s[16] = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31};
    //uchar c[16] = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31};
    for (int i = 0; i < 16; i++) {
        schluessel[i] = s[i];
        klartext[i] = kt[i];
    }
}

myAES::~myAES() {
}

void myAES::enterKlartext() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    string tmp = "";
    int diff = 0;
    cout << "Klartext (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << RED_start << "\nWerte fuer den Klartext zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << RED_start << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << RED_end << endl;
        }

        if (tmp.length() < 16) {
            cerr << RED_start << "\nWert fuer den Klartext zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << RED_end << endl;
        }

        for (int i = 0; i < 16; i++) {
            klartext[i] = tmp[i];
        }
        cout << endl;

    }
}

void myAES::enterSchluessel() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    string tmp = "";
    int diff = 0;
    cout << "Schluessel (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << RED_start << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << RED_end << endl;
        }

        if (tmp.length() < 16) {
            cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << RED_end << endl;
        }

        for (int i = 0; i < 16; i++) {
            schluessel[i] = tmp[i];
            //cout << hex << tmp[i];
        }
        cout << endl;

    }
}

void myAES::setCiphertext(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        ciphertext[i] = tmp[i];
    }

}

void myAES::setKlartext(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        klartext[i] = tmp[i];
    }
}

void myAES::setSchluessel(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        schluessel[i] = tmp[i];

    }
}

uchar* myAES::getSchluessel() {
    return schluessel;
}

uchar* myAES::getCiphertext() {
    return ciphertext;
}

uchar* myAES::getKlartext() {
    return klartext;
}

myCBC.h


#ifndef MYCBC_H
#define	MYCBC_H
#include "myAES.h"
#include <vector>
class myCBC {
public:
    // Konstruktoren / Destruktoren
    myCBC();
    virtual ~myCBC();
    
    //CBC
    void crypt(bool);
    void decrypt(bool);
    
    // Set/Get-Methoden
    void setKey(uchar[16]);
    void setIV(uchar[16]);
    void setKlartext(vector<uchar>);
    void setCiphertext(vector<uchar>);

    vector<uchar> getKlartext();
    vector<uchar> getCiphertext();
    uchar* getSchluessel();
    uchar* getIV();
    
    // Manuelle Eingabe
    void enterKey();
    void enterIV();
    void enterKlartext();
    
    // Print-Methoden
    void printSchluessel();
    void printCiphertext();
    void printKlartext();
    
private:
    //unsigned int stellen;
    uchar iv[16];
    uchar key[16];
    vector<uchar> klartext;
    vector<uchar> ciphertext;

};

#endif	/* MYCBC_H */

myCBC.cpp


#include "myCBC.h"

void myCBC::enterKey() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    string tmp = "";
    int diff = 0;
    cout << "Schluessel (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << RED_start << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << RED_end << endl;
        }

        if (tmp.length() < 16) {
            cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << RED_end << endl;
        }

        for (int i = 0; i < 16; i++) {
            key[i] = tmp[i];
        }
        cout << endl;

    }
}

void myCBC::enterIV() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    string tmp = "";
    int diff = 0;
    cout << "IV (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << RED_start << "\nWerte fuer den IV zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << RED_start << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << RED_end << endl;
        }

        if (tmp.length() < 16) {
            cerr << RED_start << "\nWert fuer den IV zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << RED_end << endl;
        }

        for (int i = 0; i < 16; i++) {
            iv[i] = tmp[i];
        }
        cout << endl;

    }
}

void myCBC::enterKlartext() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    klartext.clear();
    string tmp = "";
    cout << "Klartext (Beliebig viele Zeichen):";
    if (cin >> tmp) {
        for (int i = 0; i < tmp.size(); i++) {
            klartext.push_back(tmp[i]);
        }
        cout << endl;
    }

    if (tmp.size() % 16 != 0) {
        cerr << RED_start << "\nLetzter Klartext-Block nicht vollstaendig. Fuelle mit Nullen auf.\n";
        for (int i = 0; i < 16 - tmp.size() % 16; i++) {
            klartext.push_back('\0');
        }
        cout << RED_end << endl;
    }
}

myCBC::myCBC() {

    // Default Parameter
    uchar newKey[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar newIV[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    uchar newKlartext[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};

    // Schluessel setzen
    for (int i = 0; i < 16; i++) {
        key[i] = newKey[i];
    }

    //IV setzen
    for (int i = 0; i < 16; i++) {
        iv[i] = newIV[i];
    }

    // Klartext setzen
    for (int i = 0; i < 16; i++) {
        klartext.push_back(newKlartext[i]);
    }
}

void myCBC::printSchluessel() {
    cout << endl << "Schluessel:\n";
    for (int i = 0; i < 4; i++)
        cout << hex << "\t0x" << (int) key[0 + i] << "\t0x" << (int) key [4 + i] << "\t0x" << (int) key [8 + i] << "\t0x" << (int) key[12 + i] << endl;
    cout << endl;
}

void myCBC::printCiphertext() {
    cout << endl << "Ciphertext:\n";
    for (int i = 0; i < ciphertext.size(); i++) {
        cout << std::hex << " 0x" << (int) ciphertext[i];
    }
}

void myCBC::printKlartext() {
    cout << endl << "Klartext:\n";
    for (int i = 0; i < klartext.size(); i++) {
        cout << std::hex << " 0x" << (int) klartext[i];
    }
}

vector<uchar> myCBC::getCiphertext() {
    return ciphertext;
}

void myCBC::decrypt(bool print) {
    klartext.clear();
    uchar tmp_iv[16];
    for (int j = 0; j < 16; j++) {
        tmp_iv[j] = iv[j];
    }
    //printSchluessel();
    //printKlartext();
    //printCiphertext();
    for (int i = 0; i < ciphertext.size() / 16; i++) {

        myAES a1;

        //Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = ciphertext[j + 16 * i];
        }

        // Ciphertext
        a1.setCiphertext(tmp);

        // Schluessel
        a1.setSchluessel(key);

        // crypt
        a1.decrypt(false);

        // Resultat mit IV addieren
        for (int j = 0; j < 16; j++) {

            a1.getKlartext()[j] = a1.getKlartext()[j]^tmp_iv[j];
        }

        for (int j = 0; j < 16; j++) {
            tmp_iv[j] = a1.getCiphertext()[j + 16 * i];
            klartext.push_back(a1.getKlartext()[j]);
        }
    }

    if (print) {
        printSchluessel();
        printCiphertext();
        printKlartext();
    }

}

void myCBC::crypt(bool print) {
    ciphertext.clear();
    uchar tmp_iv[16];
    for (int i = 0; i < 16; i++) {
        tmp_iv[i] = iv[i];
    }

    for (int i = 0; i < klartext.size() / 16; i++) {

        myAES a1;
        a1.setSchluessel(key);

        //XOR in Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = klartext[j + 16 * i]^tmp_iv[j];
        }

        // Klartext
        a1.setKlartext(tmp);

        // crypt
        a1.crypt(false);


        for (int j = 0; j < 16; j++) {
            tmp_iv[j] = a1.getCiphertext()[j];
            ciphertext.push_back(a1.getCiphertext()[j]);
        }
    }

    if (print) {
        printSchluessel();
        printKlartext();
        printCiphertext();
    }
}

void myCBC::setKlartext(vector<uchar> kt) {
    if (kt.size() > klartext.size()) {
        int diff = kt.size() - klartext.size();
        for (int i = 0; i < diff; i++) {
            klartext.push_back(0x00);
        }
    }
    for (int i = 0; i < kt.size(); i++) {
        klartext.at(i) = kt.at(i);
    }
}

void myCBC::setIV(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        iv[i] = tmp[i];
    }
}

void myCBC::setKey(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        key[i] = tmp[i];
    }
}

myCBC::~myCBC() {
}

myECB.h



#ifndef MYECB_H
#define	MYECB_H

#include "myAES.h"
#include <vector>
class myECB {
public:
    // Konstruktoren / Destruktoren
    myECB();
    virtual ~myECB();
    
    //CBC
    void crypt(bool);
    void decrypt(bool);
    
    // Set/Get-Methoden
    void setKey(uchar[16]);
    
    void setKlartext(vector<uchar>);
    void setCiphertext(vector<uchar>);

    vector<uchar> getKlartext();
    vector<uchar> getCiphertext();
    uchar* getSchluessel();
    
    
    // Manuelle Eingabe
    void enterKey();
    
    void enterKlartext();
    
    // Print-Methoden
    void printSchluessel();
    void printCiphertext();
    void printKlartext();
    
private:
    //unsigned int stellen;
    
    uchar key[16];
    vector<uchar> klartext;
    vector<uchar> ciphertext;

};

#endif	/* MYECB_H */

myECB.cpp



#include "myECB.h"

void myECB::enterKey() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    string tmp = "";
    int diff = 0;
    cout << "Schluessel (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << RED_start << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << RED_end << endl;
        }

        if (tmp.length() < 16) {
            cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << RED_end << endl;
        }

        for (int i = 0; i < 16; i++) {
            key[i] = tmp[i];
        }
        cout << endl;

    }
}

void myECB::enterKlartext() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    klartext.clear();
    string tmp = "";
    cout << "Klartext (Beliebig viele Zeichen):";
    if (cin >> tmp) {
        for (int i = 0; i < tmp.size(); i++) {
            klartext.push_back(tmp[i]);
        }
        cout << endl;
    }

    if (tmp.size() % 16 != 0) {
        cerr << RED_start << "\nLetzter Klartext-Block nicht vollstaendig. Fuelle mit Nullen auf.\n";
        for (int i = 0; i < 16 - tmp.size() % 16; i++) {
            klartext.push_back('\0');
        }
        cout << RED_end << endl;
    }
}

myECB::myECB() {

    // Default Parameter
    uchar newKey[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar newIV[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    uchar newKlartext[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};

    // Schluessel setzen
    for (int i = 0; i < 16; i++) {
        key[i] = newKey[i];
    }

    // Klartext setzen
    for (int i = 0; i < 16; i++) {
        klartext.push_back(newKlartext[i]);
    }
}

void myECB::printSchluessel() {
    cout << endl << "Schluessel:\n";
    for (int i = 0; i < 4; i++)
        cout << hex << "\t0x" << (int) key[0 + i] << "\t0x" << (int) key [4 + i] << "\t0x" << (int) key [8 + i] << "\t0x" << (int) key[12 + i] << endl;
    cout << endl;
}

void myECB::printCiphertext() {
    cout << endl << "Ciphertext:\n";
    for (int i = 0; i < ciphertext.size(); i++) {
        cout << std::hex << " 0x" << (int) ciphertext[i];
    }
}

void myECB::printKlartext() {
    cout << endl << "Klartext:\n";
    for (int i = 0; i < klartext.size(); i++) {
        cout << std::hex << " 0x" << (int) klartext[i];
    }
}

vector<uchar> myECB::getCiphertext() {
    return ciphertext;
}

void myECB::decrypt(bool print) {
    klartext.clear();

    for (int i = 0; i < ciphertext.size() / 16; i++) {

        myAES a1;

        //Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = ciphertext[j + 16 * i];
        }

        // Ciphertext
        a1.setCiphertext(tmp);

        // Schluessel
        a1.setSchluessel(key);

        // crypt
        a1.decrypt(false);

        // Resultat mit IV addieren
        for (int j = 0; j < 16; j++) {
            klartext.push_back(a1.getKlartext()[j]);
        }
    }

    if (print) {
        printSchluessel();
        printCiphertext();
        printKlartext();
    }

}

void myECB::crypt(bool print) {
    ciphertext.clear();
    /* uchar tmp_iv[16];
     for (int i = 0; i < 16; i++) {
         tmp_iv[i] = iv[i];
     }*/

    for (int i = 0; i < klartext.size() / 16; i++) {

        myAES a1;
        a1.setSchluessel(key);

        //XOR in Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = klartext[j + 16 * i]; //^tmp_iv[j];
        }

        // Klartext
        a1.setKlartext(tmp);

        // crypt
        a1.crypt(false);


        for (int j = 0; j < 16; j++) {
            //tmp_iv[j] = a1.getCiphertext()[j];
            ciphertext.push_back(a1.getCiphertext()[j]);
        }
    }

    if (print) {
        printSchluessel();
        printKlartext();
        printCiphertext();
    }
}

void myECB::setKlartext(vector<uchar> kt) {
    if (kt.size() > klartext.size()) {
        int diff = kt.size() - klartext.size();
        for (int i = 0; i < diff; i++) {
            klartext.push_back(0x00);
        }
    }
    for (int i = 0; i < kt.size(); i++) {
        klartext.at(i) = kt.at(i);
    }
}

void myECB::setKey(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        key[i] = tmp[i];
    }
}

myECB::~myECB() {
}

Schreiben Sie einen Kommentar

Ihre E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahren Sie, wie Ihre Kommentardaten verarbeitet werden.

'); } cout << RED_end << endl; } for (int i = 0; i < 16; i++) { schluessel[i] = tmp[i]; //cout << hex << tmp[i]; } cout << endl; } } void myAES::setCiphertext(uchar tmp[16]) { for (int i = 0; i < 16; i++) { ciphertext[i] = tmp[i]; } } void myAES::setKlartext(uchar tmp[16]) { for (int i = 0; i < 16; i++) { klartext[i] = tmp[i]; } } void myAES::setSchluessel(uchar tmp[16]) { for (int i = 0; i < 16; i++) { schluessel[i] = tmp[i]; } } uchar* myAES::getSchluessel() { return schluessel; } uchar* myAES::getCiphertext() { return ciphertext; } uchar* myAES::getKlartext() { return klartext; }

myCBC.h


#ifndef MYCBC_H
#define	MYCBC_H
#include "myAES.h"
#include <vector>
class myCBC {
public:
    // Konstruktoren / Destruktoren
    myCBC();
    virtual ~myCBC();
    
    //CBC
    void crypt(bool);
    void decrypt(bool);
    
    // Set/Get-Methoden
    void setKey(uchar[16]);
    void setIV(uchar[16]);
    void setKlartext(vector<uchar>);
    void setCiphertext(vector<uchar>);

    vector<uchar> getKlartext();
    vector<uchar> getCiphertext();
    uchar* getSchluessel();
    uchar* getIV();
    
    // Manuelle Eingabe
    void enterKey();
    void enterIV();
    void enterKlartext();
    
    // Print-Methoden
    void printSchluessel();
    void printCiphertext();
    void printKlartext();
    
private:
    //unsigned int stellen;
    uchar iv[16];
    uchar key[16];
    vector<uchar> klartext;
    vector<uchar> ciphertext;

};

#endif	/* MYCBC_H */

myCBC.cpp


#include "myCBC.h"
void myCBC::enterKey() {
string RED_start = "3[22;31m";
string RED_end = "3[0m";
string GREEN_start = "3[22;32m";
string GREEN_end = "3[0m";
string tmp = "";
int diff = 0;
cout << "Schluessel (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
diff = 16 - tmp.length();
for (int i = 0; i < diff; i++) {
tmp.push_back('
Menu Close

Kryptologie (Praktikum 3)

Skript-AnfangKryptouebung2 – Seite 1
Skript-EndeKryptouebung2 – Seite 1

main.cpp


// Präprozessor-Direktiven
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include "myGUI.h"

// Using-Deklarationen
using namespace std;

int main(int argc, char** argv) {
    myGUI gui;
}// main

myGUI.h


#ifndef MYGUI_H
#define	MYGUI_H

#include <iostream>
#include "myCBC.h"
#include "myECB.h"

class myGUI {
public:
    myGUI();
    void callAES();
    void callCBC();
    void callECB();
    bool checkAES();
    bool checkCBC();
    bool checkECB();
    int validatedInput(unsigned int, unsigned int);
    virtual ~myGUI();
private:
};

#endif	/* MYGUI_H */

myGUI.cpp


#include "myGUI.h"
#include <vector>

using namespace std;

bool areEqual(vector<uchar> v1, vector<uchar> v2) {
    bool tmp = false;
    if (v1.size() == v2.size()) {
        for (int i = 0; i < v1.size(); i++) {
            if (v1[i] == v2[i]) {
                tmp = true;
            } else {
                cout << hex << v1[i] << "!=" << v2[i] << endl;
                tmp = false;
                break;
            }
        }
    }
    return tmp;
}

bool areEqual(uchar* arr1, uchar* arr2) {
    bool tmp = false;
    for (int i = 0; i < 16; i++) {
        if (arr1[i] == arr2[i]) {
            tmp = true;
        } else {
            cout << hex << arr1[i] << "!=" << arr2[i] << endl;
            tmp = false;
            break;
        }
    }
    return tmp;
}

bool myGUI::checkCBC() {
    bool returnValue = false;

    //16 Byte Testvektoren
    uchar keyB[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar ivB[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    uchar klartextB1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar ciphertextB1[16] = {0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d};
    vector<uchar> cipherB1;
    vector<uchar> ktB;

    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartextB1[i]);
        cipherB1.push_back(ciphertextB1[i]);
    }

    myCBC cbcB;
    cbcB.setKey(keyB);
    cbcB.setIV(ivB);
    cbcB.setKlartext(ktB);
    cbcB.crypt(false);

    // 32 Byte Testvektoren

    uchar klartextA1[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
    uchar klartextA2[16] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};
    uchar ivA[16] = {0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28, 0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58};
    uchar keyA[16] = {0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0, 0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a};
    uchar ciphertextA1[16] = {0xd2, 0x96, 0xcd, 0x94, 0xc2, 0xcc, 0xcf, 0x8a, 0x3a, 0x86, 0x30, 0x28, 0xb5, 0xe1, 0xdc, 0x0a};
    uchar ciphertextA2[16] = {0x75, 0x86, 0x60, 0x2d, 0x25, 0x3c, 0xff, 0xf9, 0x1b, 0x82, 0x66, 0xbe, 0xa6, 0xd6, 0x1a, 0xb1};
    vector<uchar> cipherA1;

    vector<uchar> test;

    for (int i = 0; i < 16; i++) {
        test.push_back(klartextA1[i]);
        cipherA1.push_back(ciphertextA1[i]);
    }

    for (int i = 0; i < 16; i++) {
        test.push_back(klartextA2[i]);
        cipherA1.push_back(ciphertextA2[i]);
    }

    myCBC cbcA;
    cbcA.setKey(keyA);
    cbcA.setIV(ivA);
    cbcA.setKlartext(test);
    cbcA.crypt(false);

    //Prüfung
    bool isWorking = areEqual(cbcA.getCiphertext(), cipherA1) && areEqual(cbcB.getCiphertext(), cipherB1);

    if (isWorking) {
        returnValue = true;
    } else {
        returnValue = false;
    }
    return returnValue;
}

bool myGUI::checkECB() {
    bool returnValue = false;

    //16 Byte Testvektoren
    uchar schluessel[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};

    uchar klartext_1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar klartext_2[16] = {0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
    uchar klartext_3[16] = {0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef};

    uchar cipher_1[16] = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97};
    uchar cipher_2[16] = {0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d, 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf};
    uchar cipher_3[16] = {0x43, 0xb1, 0xcd, 0x7f, 0x59, 0x8e, 0xce, 0x23, 0x88, 0x1b, 0x00, 0xe3, 0xed, 0x03, 0x06, 0x88};
    vector<uchar> cipherB1;
    vector<uchar> ktB;

    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_1[i]);
        cipherB1.push_back(cipher_1[i]);
    }

    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_2[i]);
        cipherB1.push_back(cipher_2[i]);
    }

    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_3[i]);
        cipherB1.push_back(cipher_3[i]);
    }

    myECB ecb;
    ecb.setKey(schluessel);
    ecb.setKlartext(ktB);
    ecb.crypt(false);

    //Prüfung
    bool isWorking = areEqual(ecb.getCiphertext(), cipherB1);

    if (isWorking) {
        returnValue = true;
    } else {
        returnValue = false;
    }
    return returnValue;
}

bool myGUI::checkAES() {

    bool returnValue = false;
    uchar schluessel[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};

    uchar klartext_1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar klartext_2[16] = {0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
    uchar klartext_3[16] = {0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef};

    uchar cipher_1[16] = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97};
    uchar cipher_2[16] = {0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d, 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf};
    uchar cipher_3[16] = {0x43, 0xb1, 0xcd, 0x7f, 0x59, 0x8e, 0xce, 0x23, 0x88, 0x1b, 0x00, 0xe3, 0xed, 0x03, 0x06, 0x88};

    myAES aes1;
    aes1.setKlartext(klartext_1);
    aes1.setSchluessel(schluessel);
    aes1.crypt(false);

    myAES aes2;
    aes2.setKlartext(klartext_2);
    aes2.setSchluessel(schluessel);
    aes2.crypt(false);

    myAES aes3;
    aes3.setKlartext(klartext_3);
    aes3.setSchluessel(schluessel);
    aes3.crypt(false);

    bool isWorking = areEqual(aes3.getCiphertext(), cipher_3) && areEqual(aes2.getCiphertext(), cipher_2) && areEqual(aes1.getCiphertext(), cipher_1);
    if (isWorking) {
        returnValue = true;
    } else {

        returnValue = false;
    }
    return returnValue;
}

void myGUI::callAES() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    myAES aes;
    aes.crypt(false);
    //myAES aesDecrypt;
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 5;
    int input = end;

    //Menu Eingabe
    while (run) {
        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Text und Schluessel aus Datei laden\n";
        cout << "(4) Entschluesseln \n";
        cout << "(5) Zurueck\n";
        cout << "> ";
        input = validatedInput(lowest, end);
        if (input == 1) {
            aes.crypt(true);
        }
        if (input == 2) {
            aes.enterKlartext();
            aes.enterSchluessel();
            aes.crypt(true);
        }
        if (input == 3) {
            cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
        }
        if (input == 4) {
            aes.decrypt(true);
        }
        if (input == 5) {
            run = false;
        }
        if (input == -1) {

            cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
            cout << endl;
        }
    }
}

void myGUI::callCBC() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    myCBC cbc;
    cbc.crypt(true);
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 5;
    int input = end;

    //Menu Eingabe
    while (run) {

        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Text und Schluessel aus Datei laden\n";
        cout << "(4) Text entschluesseln\n";
        cout << "(5) Zurueck\n";
        cout << "> ";
        input = validatedInput(lowest, end);
        if (input == 1) {
            cbc.crypt(true);
        }
        if (input == 2) {
            cbc.enterIV();
            cbc.enterKey();
            cbc.enterKlartext();
            cbc.crypt(true);
        }
        if (input == 3) {
            cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
        }
        if (input == 4) {
            cbc.decrypt(true);
        }
        if (input == 5) {
            run = false;
        }
        if (input == -1) {
            cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
            cout << endl;
        }
    }

}

void myGUI::callECB() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    myECB ecb;
    ecb.crypt(false);
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 5;
    int input = end;

    //Menu Eingabe
    while (run) {

        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Text und Schluessel aus Datei laden\n";
        cout << "(4) Text entschluesseln\n";
        cout << "(5) Zurueck\n";
        cout << "> ";
        input = validatedInput(lowest, end);
        if (input == 1) {
            ecb.crypt(true);
        }
        if (input == 2) {
            ecb.enterKey();
            ecb.enterKlartext();
            ecb.crypt(true);
        }
        if (input == 3) {
            cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
        }
        if (input == 4) {
                ecb.decrypt(true);
        }
        if (input == 5) {
            run = false;
        }
        if (input == -1) {
            cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
            cout << endl;
        }
    }

}

int myGUI::validatedInput(unsigned int lowest, unsigned int highest) {
    int tmp = 0;
    cin.clear();
    if (cin >> tmp) {//Eingabe ist in Ordnung
        cout << endl;
        if (tmp >= lowest && tmp <= highest) {//Eingabe liegt in den Parametern

            return tmp;
        }
    } else {
        string trash = "";
        cin.clear();
        std::getline(std::cin, trash);
    }
    return -1;
}

myGUI::myGUI() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    //Menu-Variablen

    unsigned int lowest = 1;
    unsigned int end = 4;
    int input = end;
    bool run = true;

    //Start
    cout << "#### Kryptographie Sommersemester 2013 ####\n";
    cout << "Nils Rogmann (725915) und Maximilian Krieg (725922)\n";

    // Begrüßung und Information
    cout << "\nHerzlich willkommen.\n";
    cout << "Das Programm wird nun mit Hilfe von Testvektoren geprüft.\n";

    // AES Check
    cout << "\nAES:\t\t";
    if (checkAES()) {
        cout << GREEN_start << "OK" << GREEN_end;
    } else {
        cerr << RED_start << "Fehler" << RED_end;
    }

    // CBC Check
    cout << "\nAES mit CBC:\t";
    if (checkCBC()) {
        cout << GREEN_start << "OK" << GREEN_end;
    } else {
        cerr << RED_start << "Fehler" << RED_end;
    }


    // ECB Check
    cout << "\nAES mit ECB:\t";
    if (checkECB()) 
    {
        cout << GREEN_start << "OK" << GREEN_end;
    }
    else
    {
        cerr << RED_start << "Fehler" << RED_end;
    }
    cout << endl;

    //Menu Eingabe
    while (run) {
        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) AES\n";
        cout << "(2) AES mit CBC\n";
        cout << "(3) AES mit ECB\n";
        cout << "(4) Programm beenden\n";
        cout << "> ";

        input = validatedInput(lowest, end);

        // Aufrufe
        if (input == 1) {
            cout << GREEN_start << "#### AES ####\n" << GREEN_end;
            callAES();
            cout << endl;
        }

        if (input == 2) {
            cout << GREEN_start << "#### AES mit CBC ####\n" << GREEN_end;
            callCBC();
            cout << endl;
        }


        if (input == 3) {
            cout << GREEN_start << "#### AES mit ECB ####\n" << GREEN_end;
            callECB();
            cout << endl;
        }

        // Fehler
        if (input == -1) {
            cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
            cout << endl;
        }

        // Beenden
        if (input == end) {

            cout << "Programm wird beendet.\n";
            run = false;
            cout << endl;
        }
    }
}

myGUI::~myGUI() {
}

myAES.h


#ifndef MYAES_H
#define	MYAES_H

#include <iostream>

using namespace std;
// Typedefs
typedef unsigned char uchar;

class myAES {
public:
    // Konstruktoren/Destruktoren
    myAES();
    virtual ~myAES();

    // Manuelle Eingabe
    void enterKlartext();
    void enterSchluessel();

    // Set/Get-Methoden
    void setKlartext(uchar[16]);
    void setSchluessel(uchar[16]);
    void setCiphertext(uchar[16]);
    uchar* getKlartext();
    uchar* getSchluessel();
    uchar* getCiphertext();

    // AES-Methoden
    void crypt(bool);
    void mixcolumns();
    void shiftrows();
    void schluesselexpansion(uchar[][44], int, int, int);
    void rotword(uchar[], int);
    uchar mix(uchar, unsigned int);
    void subbytes(uchar [], uchar [], int);

    // Print-Methoden
    void printSchluessel();
    void printCiphertext();
    void printKlartext();
    
   void decrypt(bool) ;
   uchar gmul(uchar, uchar);
   void invert_mixcolumns();
   void invert_shiftrows();

private:
    uchar klartext[16];
    uchar schluessel[16];
    uchar ciphertext[16];
};



#endif	/* MYAES_H */

myAES.cpp


#include "myAES.h"

using namespace std;

unsigned char Sbox[256] = {//  s-box
    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, 0x9c, 0xa4, 0x72, 0xc0,
    0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
    0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
    0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
    0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
    0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
    0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
    0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
    0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
    0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
    0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
    0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
    0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
    0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
    0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
};

unsigned char sbox_inverse[256] = {
    0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
    0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
    0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
    0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
    0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
    0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
    0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
    0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
    0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
    0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
    0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
    0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
    0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
    0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
    0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
    0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
};

unsigned char Rcon[256] = {
    0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
    0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,
    0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,
    0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
    0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,
    0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,
    0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b,
    0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
    0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
    0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
    0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
    0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
    0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
    0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,
    0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,
    0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d
};

void myAES::subbytes(uchar sbox[], uchar tmp[], int arrSize) {
    for (int i = 0; i < arrSize; i++) {
        tmp[i] = sbox[tmp[i]];
    }
}// subbytes

uchar myAES::mix(uchar byte, unsigned int mixvalue) {
    unsigned char retValue;
    switch (mixvalue) {
        case 1:
            retValue = byte;
            break;
        case 2:
            retValue = byte << 1;
            if (byte & 0x80) {
                retValue = retValue ^ 0x1b;
            }
            break;
        case 3:
            retValue = byte << 1;
            if (byte & 0x80) {
                retValue = retValue ^ 0x1b;
            }
            retValue = retValue^byte;
            break;
    }
    return retValue;
}

void addRoundKey(uchar klartext[], int iLaenge, uchar matrix[][44], int iReihe, int iSpalte, int iRunde) {
    int pos = 0;
    for (int i = iRunde * 4; i < ((iRunde * 4) + 4) && i < iSpalte; i++) {
        for (int k = 0; k < iReihe; k++) {
            klartext[pos] = klartext[pos] ^ matrix[k][i];
            pos++;
        }
    }
}// addroundkey

void myAES::rotword(uchar column[], int iReihe) {
    uchar tmp = column[0];
    for (int i = 1; i < iReihe; i++) {
        column[i - 1] = column[i];
    }
    column[iReihe - 1] = tmp;
} // rotword

void myAES::schluesselexpansion(uchar matrix[][44], int iReihe, int iSpalte, int iLaenge) {
    // Alle Spalten durchlaufen
    int pos = 0;

    for (int i = 0; i < iSpalte; i++) {
        if (i < 4) { // Schluessel in erste vier Spalten kopieren
            for (int k = 0; k < iReihe && pos < iLaenge; k++) {
                matrix[k][i] = schluessel[pos];
                pos++;
                //cout << hex << "matrix[" << k << "][" << i << "] = " << (int) matrix[k][i] << endl;
            }
        } else { // i > 4
            if (i % 4 == 0) {// erste Spalte eines Schluessels
                // Spalte in Hilfsarray kopieren
                uchar tmp[iReihe]; // i-1
                uchar tmp2[iReihe]; // i-4
                for (int k = 0; k < iReihe; k++) {
                    tmp[k] = matrix[k][i - 1];
                    tmp2[k] = matrix[k][i - 4];
                }

                rotword(tmp, iReihe);

                subbytes(Sbox, tmp, iReihe);

                // Spalte[i-4] XOR subbytes[rotword[i-i]
                for (int k = 0; k < iReihe; k++) {
                    tmp[k] = tmp[k] ^ tmp2[k];
                }

                // tmp[0] XOR (i/4)
                tmp[0] = tmp[0] ^ Rcon[i / iReihe];

                // tmp[k] an Spalte[k][i] kopieren
                for (int k = 0; k < iReihe; k++) {
                    matrix[k][i] = tmp[k];
                }

            } else {
                //cout << "i " << i << endl;
                for (int k = 0; k < iReihe; k++) {
                    matrix[k][i] = matrix[k][i - 4] ^ matrix[k][i - 1];
                }
            }
        }
    }
}// schluesselexpansion

void myAES::shiftrows() {
    uchar copys[16] = {};

    //reihe 1   
    copys[0] = ciphertext[0];
    copys[4] = ciphertext[4];
    copys[8] = ciphertext[8];
    copys[12] = ciphertext[12];

    //reihe 2
    copys[1] = ciphertext[5];
    copys[5] = ciphertext[9];
    copys[9] = ciphertext[13];
    copys[13] = ciphertext[1];

    // reihe 3
    copys[2] = ciphertext[10];
    copys[6] = ciphertext[14];
    copys[10] = ciphertext[2];
    copys[14] = ciphertext[6];

    //reihe 4
    copys[3] = ciphertext[15];
    copys[7] = ciphertext[3];
    copys[11] = ciphertext[7];
    copys[15] = ciphertext[11];

    //umschreiben   
    for (int i = 0; i < 16; i++) {
        ciphertext[i] = copys[i];
    }
}// shiftrows

void myAES::mixcolumns() {
    for (int i = 0; i < 4; i++) {
        uchar sj0 = mix(ciphertext[i * 4], 2)^mix(ciphertext[i * 4 + 1], 3)^mix(ciphertext[i * 4 + 2], 1)^mix(ciphertext[i * 4 + 3], 1);
        uchar sj1 = mix(ciphertext[i * 4], 1)^mix(ciphertext[i * 4 + 1], 2)^mix(ciphertext[i * 4 + 2], 3)^mix(ciphertext[i * 4 + 3], 1);
        uchar sj2 = mix(ciphertext[i * 4], 1)^mix(ciphertext[i * 4 + 1], 1)^mix(ciphertext[i * 4 + 2], 2)^mix(ciphertext[i * 4 + 3], 3);
        uchar sj3 = mix(ciphertext[i * 4], 3)^mix(ciphertext[i * 4 + 1], 1)^mix(ciphertext[i * 4 + 2], 1)^mix(ciphertext[i * 4 + 3], 2);
        ciphertext[i * 4] = sj0;
        ciphertext[i * 4 + 1] = sj1;
        ciphertext[i * 4 + 2] = sj2;
        ciphertext[i * 4 + 3] = sj3;
    }
}// mixcolumns

void myAES::crypt(bool output) {

    // Parameter
    int iRunde = 10;
    int iLaenge = 16;

    // Überschreibe ciphertext um diesen fortan zu verwenden
    for (int i = 0; i < 16; i++) {
        ciphertext[i] = klartext[i];
    }

    // Arraygroesse dynamisch bestimmen
    int arrSize = sizeof (ciphertext) / sizeof (ciphertext[0]);

    // Zwischenspeicherung der Rundenschluessel
    int iReihe = 4;
    int iSpalte = 4 * (iRunde + 1);
    uchar carrRundenschluessel[4][44];

    // Schluessel expandieren
    schluesselexpansion(carrRundenschluessel, iReihe, iSpalte, iLaenge);

    // Vorrunde
    for (int k = 0; k < iLaenge; k++) {
        ciphertext[k] = ciphertext[k] ^ schluessel[k];
    }

    // Durchlaufen der Runden
    for (int i = 1; i < iRunde + 1; i++) {

        // S-Box
        subbytes(Sbox, ciphertext, arrSize);

        // Shift Rows
        shiftrows();

        // Mix Columns
        if (i != (iRunde)) { // kein MixColumns in der letzten Runde
            mixcolumns();
        }

        // Rundenschlüssel addieren
        addRoundKey(ciphertext, arrSize, carrRundenschluessel, iReihe, iSpalte, i);

    }

    // Ausgabe des Ciphertexts
    if (output) {
        printSchluessel();
        printKlartext();
        printCiphertext();
    }
}

void myAES::invert_shiftrows() {
    uchar copys[16] = {};

    //reihe 1   
    copys[0] = klartext[0];
    copys[4] = klartext[4];
    copys[8] = klartext[8];
    copys[12] = klartext[12];

    //reihe 2
    copys[1] = klartext[13];
    copys[13] = klartext[9];
    copys[9] = klartext[5];
    copys[5] = klartext[1];

    // reihe 3   
    copys[6] = klartext[14];
    copys[2] = klartext[10];
    copys[14] = klartext[6];
    copys[10] = klartext[2];

    //reihe 4
    copys[11] = klartext[15];
    copys[7] = klartext[11];
    copys[3] = klartext[7];
    copys[15] = klartext[3];

    //umschreiben   
    for (int i = 0; i < 16; i++) {
        klartext[i] = copys[i];
    }
}// invert_shiftrows

void myAES::invert_mixcolumns() {
    for (int i = 0; i < 4; i++) {
        uchar sj0 = gmul(klartext[i * 4], 14)^gmul(klartext[i * 4 + 1], 11)^gmul(klartext[i * 4 + 2], 13)^gmul(klartext[i * 4 + 3], 9);
        uchar sj1 = gmul(klartext[i * 4], 9)^gmul(klartext[i * 4 + 1], 14)^gmul(klartext[i * 4 + 2], 11)^gmul(klartext[i * 4 + 3], 13);
        uchar sj2 = gmul(klartext[i * 4], 13)^gmul(klartext[i * 4 + 1], 9)^gmul(klartext[i * 4 + 2], 14)^gmul(klartext[i * 4 + 3], 11);
        uchar sj3 = gmul(klartext[i * 4], 11)^gmul(klartext[i * 4 + 1], 13)^gmul(klartext[i * 4 + 2], 9)^gmul(klartext[i * 4 + 3], 14);
        klartext[i * 4] = sj0;
        klartext[i * 4 + 1] = sj1;
        klartext[i * 4 + 2] = sj2;
        klartext[i * 4 + 3] = sj3;
    }
}

uchar myAES::gmul(uchar a, uchar b) {
    unsigned char p = 0;
    unsigned char hi;

    for (int i = 0; i < 8; ++i) {
        if ((b & 1) == 1)
            p ^= a;
        hi = (a & 0x80);
        a <<= 1;
        if (hi == 0x80)
            a ^= 0x1b;
        b >>= 1;
    }
    return p;
}

void myAES::decrypt(bool output) {

    // Parameter
    int iRunde = 10;
    int iLaenge = 16;


    // Überschreibe klartext um diesen fortan zu verwenden
    for (int i = 0; i < 16; i++) {
        klartext[i] = ciphertext[i];
    }


    // Arraygroesse dynamisch bestimmen
    int arrSize = sizeof (klartext) / sizeof (klartext[0]);

    // Zwischenspeicherung der Rundenschluessel
    int iReihe = 4;
    int iSpalte = 4 * (iRunde + 1);
    uchar carrRundenschluessel[4][44];

    // Schluessel expandieren
    schluesselexpansion(carrRundenschluessel, iReihe, iSpalte, iLaenge);

    //printRundenSchluessel(carrRundenschluessel, iReihe, iSpalte);

    // "neue" Vorrunde
    addRoundKey(klartext, arrSize, carrRundenschluessel, iReihe, iSpalte, 10);

    // Durchlaufen der Runden
    for (int i = 9; i > 0; i--) {

        // Shift Rows
        invert_shiftrows();

        // S-Box
        subbytes(sbox_inverse, klartext, arrSize);

        // Rundenschlüssel addieren
        addRoundKey(klartext, arrSize, carrRundenschluessel, iReihe, iSpalte, i);

        // Mix Columns
        if (i != 10) { // kein MixColumns in der letzten Runde
            invert_mixcolumns();
        }
    }


    // Letzte Runde
    invert_shiftrows();
    subbytes(sbox_inverse, klartext, arrSize);

    for (int k = 0; k < iLaenge; k++) {
        klartext[k] = klartext[k] ^ schluessel[k];
    }

    // Ausgabe des Ciphertexts
    if (output) {
        printSchluessel();
        printCiphertext();
        printKlartext();
    }
}// decrypt

void myAES::printSchluessel() {
    cout << endl << "Schluessel:\n";
    for (int i = 0; i < 4; i++)
        cout << hex << "\t0x" << (int) schluessel[0 + i] << "\t0x" << (int) schluessel [4 + i] << "\t0x" << (int) schluessel [8 + i] << "\t0x" << (int) schluessel[12 + i] << endl;
    cout << endl;
}

void myAES::printCiphertext() {
    cout << endl << "Ciphertext:\n";
    for (int i = 0; i < 4; i++)
        cout << hex << "\t0x" << (int) ciphertext[0 + i] << "\t0x" << (int) ciphertext [4 + i] << "\t0x" << (int) ciphertext [8 + i] << "\t0x" << (int) ciphertext[12 + i] << endl;
    cout << endl;
}

void myAES::printKlartext() {
    cout << endl << "Klartext:\n";
    for (int i = 0; i < 4; i++)
        cout << hex << "\t0x" << (int) klartext[0 + i] << "\t0x" << (int) klartext [4 + i] << "\t0x" << (int) klartext [8 + i] << "\t0x" << (int) klartext[12 + i] << endl;
    cout << endl;
}

myAES::myAES() {
    uchar kt[16] = {0x61, 0x62, 0x62, 0x69, 0x6c, 0x64, 0x75, 0x6e, 0x67, 0x73, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78};
    uchar s[16] = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31};
    //uchar c[16] = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31};
    for (int i = 0; i < 16; i++) {
        schluessel[i] = s[i];
        klartext[i] = kt[i];
    }
}

myAES::~myAES() {
}

void myAES::enterKlartext() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    string tmp = "";
    int diff = 0;
    cout << "Klartext (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << RED_start << "\nWerte fuer den Klartext zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << RED_start << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << RED_end << endl;
        }

        if (tmp.length() < 16) {
            cerr << RED_start << "\nWert fuer den Klartext zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << RED_end << endl;
        }

        for (int i = 0; i < 16; i++) {
            klartext[i] = tmp[i];
        }
        cout << endl;

    }
}

void myAES::enterSchluessel() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    string tmp = "";
    int diff = 0;
    cout << "Schluessel (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << RED_start << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << RED_end << endl;
        }

        if (tmp.length() < 16) {
            cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << RED_end << endl;
        }

        for (int i = 0; i < 16; i++) {
            schluessel[i] = tmp[i];
            //cout << hex << tmp[i];
        }
        cout << endl;

    }
}

void myAES::setCiphertext(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        ciphertext[i] = tmp[i];
    }

}

void myAES::setKlartext(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        klartext[i] = tmp[i];
    }
}

void myAES::setSchluessel(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        schluessel[i] = tmp[i];

    }
}

uchar* myAES::getSchluessel() {
    return schluessel;
}

uchar* myAES::getCiphertext() {
    return ciphertext;
}

uchar* myAES::getKlartext() {
    return klartext;
}

myCBC.h


#ifndef MYCBC_H
#define	MYCBC_H
#include "myAES.h"
#include <vector>
class myCBC {
public:
    // Konstruktoren / Destruktoren
    myCBC();
    virtual ~myCBC();
    
    //CBC
    void crypt(bool);
    void decrypt(bool);
    
    // Set/Get-Methoden
    void setKey(uchar[16]);
    void setIV(uchar[16]);
    void setKlartext(vector<uchar>);
    void setCiphertext(vector<uchar>);

    vector<uchar> getKlartext();
    vector<uchar> getCiphertext();
    uchar* getSchluessel();
    uchar* getIV();
    
    // Manuelle Eingabe
    void enterKey();
    void enterIV();
    void enterKlartext();
    
    // Print-Methoden
    void printSchluessel();
    void printCiphertext();
    void printKlartext();
    
private:
    //unsigned int stellen;
    uchar iv[16];
    uchar key[16];
    vector<uchar> klartext;
    vector<uchar> ciphertext;

};

#endif	/* MYCBC_H */

myCBC.cpp


#include "myCBC.h"

void myCBC::enterKey() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    string tmp = "";
    int diff = 0;
    cout << "Schluessel (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << RED_start << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << RED_end << endl;
        }

        if (tmp.length() < 16) {
            cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << RED_end << endl;
        }

        for (int i = 0; i < 16; i++) {
            key[i] = tmp[i];
        }
        cout << endl;

    }
}

void myCBC::enterIV() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    string tmp = "";
    int diff = 0;
    cout << "IV (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << RED_start << "\nWerte fuer den IV zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << RED_start << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << RED_end << endl;
        }

        if (tmp.length() < 16) {
            cerr << RED_start << "\nWert fuer den IV zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << RED_end << endl;
        }

        for (int i = 0; i < 16; i++) {
            iv[i] = tmp[i];
        }
        cout << endl;

    }
}

void myCBC::enterKlartext() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    klartext.clear();
    string tmp = "";
    cout << "Klartext (Beliebig viele Zeichen):";
    if (cin >> tmp) {
        for (int i = 0; i < tmp.size(); i++) {
            klartext.push_back(tmp[i]);
        }
        cout << endl;
    }

    if (tmp.size() % 16 != 0) {
        cerr << RED_start << "\nLetzter Klartext-Block nicht vollstaendig. Fuelle mit Nullen auf.\n";
        for (int i = 0; i < 16 - tmp.size() % 16; i++) {
            klartext.push_back('\0');
        }
        cout << RED_end << endl;
    }
}

myCBC::myCBC() {

    // Default Parameter
    uchar newKey[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar newIV[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    uchar newKlartext[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};

    // Schluessel setzen
    for (int i = 0; i < 16; i++) {
        key[i] = newKey[i];
    }

    //IV setzen
    for (int i = 0; i < 16; i++) {
        iv[i] = newIV[i];
    }

    // Klartext setzen
    for (int i = 0; i < 16; i++) {
        klartext.push_back(newKlartext[i]);
    }
}

void myCBC::printSchluessel() {
    cout << endl << "Schluessel:\n";
    for (int i = 0; i < 4; i++)
        cout << hex << "\t0x" << (int) key[0 + i] << "\t0x" << (int) key [4 + i] << "\t0x" << (int) key [8 + i] << "\t0x" << (int) key[12 + i] << endl;
    cout << endl;
}

void myCBC::printCiphertext() {
    cout << endl << "Ciphertext:\n";
    for (int i = 0; i < ciphertext.size(); i++) {
        cout << std::hex << " 0x" << (int) ciphertext[i];
    }
}

void myCBC::printKlartext() {
    cout << endl << "Klartext:\n";
    for (int i = 0; i < klartext.size(); i++) {
        cout << std::hex << " 0x" << (int) klartext[i];
    }
}

vector<uchar> myCBC::getCiphertext() {
    return ciphertext;
}

void myCBC::decrypt(bool print) {
    klartext.clear();
    uchar tmp_iv[16];
    for (int j = 0; j < 16; j++) {
        tmp_iv[j] = iv[j];
    }
    //printSchluessel();
    //printKlartext();
    //printCiphertext();
    for (int i = 0; i < ciphertext.size() / 16; i++) {

        myAES a1;

        //Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = ciphertext[j + 16 * i];
        }

        // Ciphertext
        a1.setCiphertext(tmp);

        // Schluessel
        a1.setSchluessel(key);

        // crypt
        a1.decrypt(false);

        // Resultat mit IV addieren
        for (int j = 0; j < 16; j++) {

            a1.getKlartext()[j] = a1.getKlartext()[j]^tmp_iv[j];
        }

        for (int j = 0; j < 16; j++) {
            tmp_iv[j] = a1.getCiphertext()[j + 16 * i];
            klartext.push_back(a1.getKlartext()[j]);
        }
    }

    if (print) {
        printSchluessel();
        printCiphertext();
        printKlartext();
    }

}

void myCBC::crypt(bool print) {
    ciphertext.clear();
    uchar tmp_iv[16];
    for (int i = 0; i < 16; i++) {
        tmp_iv[i] = iv[i];
    }

    for (int i = 0; i < klartext.size() / 16; i++) {

        myAES a1;
        a1.setSchluessel(key);

        //XOR in Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = klartext[j + 16 * i]^tmp_iv[j];
        }

        // Klartext
        a1.setKlartext(tmp);

        // crypt
        a1.crypt(false);


        for (int j = 0; j < 16; j++) {
            tmp_iv[j] = a1.getCiphertext()[j];
            ciphertext.push_back(a1.getCiphertext()[j]);
        }
    }

    if (print) {
        printSchluessel();
        printKlartext();
        printCiphertext();
    }
}

void myCBC::setKlartext(vector<uchar> kt) {
    if (kt.size() > klartext.size()) {
        int diff = kt.size() - klartext.size();
        for (int i = 0; i < diff; i++) {
            klartext.push_back(0x00);
        }
    }
    for (int i = 0; i < kt.size(); i++) {
        klartext.at(i) = kt.at(i);
    }
}

void myCBC::setIV(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        iv[i] = tmp[i];
    }
}

void myCBC::setKey(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        key[i] = tmp[i];
    }
}

myCBC::~myCBC() {
}

myECB.h



#ifndef MYECB_H
#define	MYECB_H

#include "myAES.h"
#include <vector>
class myECB {
public:
    // Konstruktoren / Destruktoren
    myECB();
    virtual ~myECB();
    
    //CBC
    void crypt(bool);
    void decrypt(bool);
    
    // Set/Get-Methoden
    void setKey(uchar[16]);
    
    void setKlartext(vector<uchar>);
    void setCiphertext(vector<uchar>);

    vector<uchar> getKlartext();
    vector<uchar> getCiphertext();
    uchar* getSchluessel();
    
    
    // Manuelle Eingabe
    void enterKey();
    
    void enterKlartext();
    
    // Print-Methoden
    void printSchluessel();
    void printCiphertext();
    void printKlartext();
    
private:
    //unsigned int stellen;
    
    uchar key[16];
    vector<uchar> klartext;
    vector<uchar> ciphertext;

};

#endif	/* MYECB_H */

myECB.cpp



#include "myECB.h"

void myECB::enterKey() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    string tmp = "";
    int diff = 0;
    cout << "Schluessel (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << RED_start << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << RED_end << endl;
        }

        if (tmp.length() < 16) {
            cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << RED_end << endl;
        }

        for (int i = 0; i < 16; i++) {
            key[i] = tmp[i];
        }
        cout << endl;

    }
}

void myECB::enterKlartext() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    klartext.clear();
    string tmp = "";
    cout << "Klartext (Beliebig viele Zeichen):";
    if (cin >> tmp) {
        for (int i = 0; i < tmp.size(); i++) {
            klartext.push_back(tmp[i]);
        }
        cout << endl;
    }

    if (tmp.size() % 16 != 0) {
        cerr << RED_start << "\nLetzter Klartext-Block nicht vollstaendig. Fuelle mit Nullen auf.\n";
        for (int i = 0; i < 16 - tmp.size() % 16; i++) {
            klartext.push_back('\0');
        }
        cout << RED_end << endl;
    }
}

myECB::myECB() {

    // Default Parameter
    uchar newKey[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar newIV[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    uchar newKlartext[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};

    // Schluessel setzen
    for (int i = 0; i < 16; i++) {
        key[i] = newKey[i];
    }

    // Klartext setzen
    for (int i = 0; i < 16; i++) {
        klartext.push_back(newKlartext[i]);
    }
}

void myECB::printSchluessel() {
    cout << endl << "Schluessel:\n";
    for (int i = 0; i < 4; i++)
        cout << hex << "\t0x" << (int) key[0 + i] << "\t0x" << (int) key [4 + i] << "\t0x" << (int) key [8 + i] << "\t0x" << (int) key[12 + i] << endl;
    cout << endl;
}

void myECB::printCiphertext() {
    cout << endl << "Ciphertext:\n";
    for (int i = 0; i < ciphertext.size(); i++) {
        cout << std::hex << " 0x" << (int) ciphertext[i];
    }
}

void myECB::printKlartext() {
    cout << endl << "Klartext:\n";
    for (int i = 0; i < klartext.size(); i++) {
        cout << std::hex << " 0x" << (int) klartext[i];
    }
}

vector<uchar> myECB::getCiphertext() {
    return ciphertext;
}

void myECB::decrypt(bool print) {
    klartext.clear();

    for (int i = 0; i < ciphertext.size() / 16; i++) {

        myAES a1;

        //Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = ciphertext[j + 16 * i];
        }

        // Ciphertext
        a1.setCiphertext(tmp);

        // Schluessel
        a1.setSchluessel(key);

        // crypt
        a1.decrypt(false);

        // Resultat mit IV addieren
        for (int j = 0; j < 16; j++) {
            klartext.push_back(a1.getKlartext()[j]);
        }
    }

    if (print) {
        printSchluessel();
        printCiphertext();
        printKlartext();
    }

}

void myECB::crypt(bool print) {
    ciphertext.clear();
    /* uchar tmp_iv[16];
     for (int i = 0; i < 16; i++) {
         tmp_iv[i] = iv[i];
     }*/

    for (int i = 0; i < klartext.size() / 16; i++) {

        myAES a1;
        a1.setSchluessel(key);

        //XOR in Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = klartext[j + 16 * i]; //^tmp_iv[j];
        }

        // Klartext
        a1.setKlartext(tmp);

        // crypt
        a1.crypt(false);


        for (int j = 0; j < 16; j++) {
            //tmp_iv[j] = a1.getCiphertext()[j];
            ciphertext.push_back(a1.getCiphertext()[j]);
        }
    }

    if (print) {
        printSchluessel();
        printKlartext();
        printCiphertext();
    }
}

void myECB::setKlartext(vector<uchar> kt) {
    if (kt.size() > klartext.size()) {
        int diff = kt.size() - klartext.size();
        for (int i = 0; i < diff; i++) {
            klartext.push_back(0x00);
        }
    }
    for (int i = 0; i < kt.size(); i++) {
        klartext.at(i) = kt.at(i);
    }
}

void myECB::setKey(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        key[i] = tmp[i];
    }
}

myECB::~myECB() {
}

Schreiben Sie einen Kommentar

Ihre E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahren Sie, wie Ihre Kommentardaten verarbeitet werden.

'); } cout << RED_end << endl; } for (int i = 0; i < 16; i++) { key[i] = tmp[i]; } cout << endl; } } void myCBC::enterIV() { string RED_start = "3[22;31m"; string RED_end = "3[0m"; string GREEN_start = "3[22;32m"; string GREEN_end = "3[0m"; string tmp = ""; int diff = 0; cout << "IV (16 Zeichen):"; if (cin >> tmp) { if (tmp.length() > 16) { cerr << RED_start << "\nWerte fuer den IV zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start; for (int i = 0; i < tmp.length(); i++) { if (i == 16) { cerr << RED_start << " | "; } cerr << tmp.at(i); } cout << ")" << RED_end << endl; } if (tmp.length() < 16) { cerr << RED_start << "\nWert fuer den IV zu klein. Fuelle mit Nullen auf.\n"; diff = 16 - tmp.length(); for (int i = 0; i < diff; i++) { tmp.push_back('
Menu Close

Kryptologie (Praktikum 3)

Skript-AnfangKryptouebung2 – Seite 1
Skript-EndeKryptouebung2 – Seite 1

main.cpp


// Präprozessor-Direktiven
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include "myGUI.h"

// Using-Deklarationen
using namespace std;

int main(int argc, char** argv) {
    myGUI gui;
}// main

myGUI.h


#ifndef MYGUI_H
#define	MYGUI_H

#include <iostream>
#include "myCBC.h"
#include "myECB.h"

class myGUI {
public:
    myGUI();
    void callAES();
    void callCBC();
    void callECB();
    bool checkAES();
    bool checkCBC();
    bool checkECB();
    int validatedInput(unsigned int, unsigned int);
    virtual ~myGUI();
private:
};

#endif	/* MYGUI_H */

myGUI.cpp


#include "myGUI.h"
#include <vector>

using namespace std;

bool areEqual(vector<uchar> v1, vector<uchar> v2) {
    bool tmp = false;
    if (v1.size() == v2.size()) {
        for (int i = 0; i < v1.size(); i++) {
            if (v1[i] == v2[i]) {
                tmp = true;
            } else {
                cout << hex << v1[i] << "!=" << v2[i] << endl;
                tmp = false;
                break;
            }
        }
    }
    return tmp;
}

bool areEqual(uchar* arr1, uchar* arr2) {
    bool tmp = false;
    for (int i = 0; i < 16; i++) {
        if (arr1[i] == arr2[i]) {
            tmp = true;
        } else {
            cout << hex << arr1[i] << "!=" << arr2[i] << endl;
            tmp = false;
            break;
        }
    }
    return tmp;
}

bool myGUI::checkCBC() {
    bool returnValue = false;

    //16 Byte Testvektoren
    uchar keyB[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar ivB[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    uchar klartextB1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar ciphertextB1[16] = {0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d};
    vector<uchar> cipherB1;
    vector<uchar> ktB;

    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartextB1[i]);
        cipherB1.push_back(ciphertextB1[i]);
    }

    myCBC cbcB;
    cbcB.setKey(keyB);
    cbcB.setIV(ivB);
    cbcB.setKlartext(ktB);
    cbcB.crypt(false);

    // 32 Byte Testvektoren

    uchar klartextA1[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
    uchar klartextA2[16] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};
    uchar ivA[16] = {0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28, 0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58};
    uchar keyA[16] = {0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0, 0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a};
    uchar ciphertextA1[16] = {0xd2, 0x96, 0xcd, 0x94, 0xc2, 0xcc, 0xcf, 0x8a, 0x3a, 0x86, 0x30, 0x28, 0xb5, 0xe1, 0xdc, 0x0a};
    uchar ciphertextA2[16] = {0x75, 0x86, 0x60, 0x2d, 0x25, 0x3c, 0xff, 0xf9, 0x1b, 0x82, 0x66, 0xbe, 0xa6, 0xd6, 0x1a, 0xb1};
    vector<uchar> cipherA1;

    vector<uchar> test;

    for (int i = 0; i < 16; i++) {
        test.push_back(klartextA1[i]);
        cipherA1.push_back(ciphertextA1[i]);
    }

    for (int i = 0; i < 16; i++) {
        test.push_back(klartextA2[i]);
        cipherA1.push_back(ciphertextA2[i]);
    }

    myCBC cbcA;
    cbcA.setKey(keyA);
    cbcA.setIV(ivA);
    cbcA.setKlartext(test);
    cbcA.crypt(false);

    //Prüfung
    bool isWorking = areEqual(cbcA.getCiphertext(), cipherA1) && areEqual(cbcB.getCiphertext(), cipherB1);

    if (isWorking) {
        returnValue = true;
    } else {
        returnValue = false;
    }
    return returnValue;
}

bool myGUI::checkECB() {
    bool returnValue = false;

    //16 Byte Testvektoren
    uchar schluessel[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};

    uchar klartext_1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar klartext_2[16] = {0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
    uchar klartext_3[16] = {0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef};

    uchar cipher_1[16] = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97};
    uchar cipher_2[16] = {0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d, 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf};
    uchar cipher_3[16] = {0x43, 0xb1, 0xcd, 0x7f, 0x59, 0x8e, 0xce, 0x23, 0x88, 0x1b, 0x00, 0xe3, 0xed, 0x03, 0x06, 0x88};
    vector<uchar> cipherB1;
    vector<uchar> ktB;

    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_1[i]);
        cipherB1.push_back(cipher_1[i]);
    }

    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_2[i]);
        cipherB1.push_back(cipher_2[i]);
    }

    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_3[i]);
        cipherB1.push_back(cipher_3[i]);
    }

    myECB ecb;
    ecb.setKey(schluessel);
    ecb.setKlartext(ktB);
    ecb.crypt(false);

    //Prüfung
    bool isWorking = areEqual(ecb.getCiphertext(), cipherB1);

    if (isWorking) {
        returnValue = true;
    } else {
        returnValue = false;
    }
    return returnValue;
}

bool myGUI::checkAES() {

    bool returnValue = false;
    uchar schluessel[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};

    uchar klartext_1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar klartext_2[16] = {0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
    uchar klartext_3[16] = {0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef};

    uchar cipher_1[16] = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97};
    uchar cipher_2[16] = {0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d, 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf};
    uchar cipher_3[16] = {0x43, 0xb1, 0xcd, 0x7f, 0x59, 0x8e, 0xce, 0x23, 0x88, 0x1b, 0x00, 0xe3, 0xed, 0x03, 0x06, 0x88};

    myAES aes1;
    aes1.setKlartext(klartext_1);
    aes1.setSchluessel(schluessel);
    aes1.crypt(false);

    myAES aes2;
    aes2.setKlartext(klartext_2);
    aes2.setSchluessel(schluessel);
    aes2.crypt(false);

    myAES aes3;
    aes3.setKlartext(klartext_3);
    aes3.setSchluessel(schluessel);
    aes3.crypt(false);

    bool isWorking = areEqual(aes3.getCiphertext(), cipher_3) && areEqual(aes2.getCiphertext(), cipher_2) && areEqual(aes1.getCiphertext(), cipher_1);
    if (isWorking) {
        returnValue = true;
    } else {

        returnValue = false;
    }
    return returnValue;
}

void myGUI::callAES() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    myAES aes;
    aes.crypt(false);
    //myAES aesDecrypt;
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 5;
    int input = end;

    //Menu Eingabe
    while (run) {
        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Text und Schluessel aus Datei laden\n";
        cout << "(4) Entschluesseln \n";
        cout << "(5) Zurueck\n";
        cout << "> ";
        input = validatedInput(lowest, end);
        if (input == 1) {
            aes.crypt(true);
        }
        if (input == 2) {
            aes.enterKlartext();
            aes.enterSchluessel();
            aes.crypt(true);
        }
        if (input == 3) {
            cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
        }
        if (input == 4) {
            aes.decrypt(true);
        }
        if (input == 5) {
            run = false;
        }
        if (input == -1) {

            cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
            cout << endl;
        }
    }
}

void myGUI::callCBC() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    myCBC cbc;
    cbc.crypt(true);
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 5;
    int input = end;

    //Menu Eingabe
    while (run) {

        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Text und Schluessel aus Datei laden\n";
        cout << "(4) Text entschluesseln\n";
        cout << "(5) Zurueck\n";
        cout << "> ";
        input = validatedInput(lowest, end);
        if (input == 1) {
            cbc.crypt(true);
        }
        if (input == 2) {
            cbc.enterIV();
            cbc.enterKey();
            cbc.enterKlartext();
            cbc.crypt(true);
        }
        if (input == 3) {
            cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
        }
        if (input == 4) {
            cbc.decrypt(true);
        }
        if (input == 5) {
            run = false;
        }
        if (input == -1) {
            cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
            cout << endl;
        }
    }

}

void myGUI::callECB() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    myECB ecb;
    ecb.crypt(false);
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 5;
    int input = end;

    //Menu Eingabe
    while (run) {

        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Text und Schluessel aus Datei laden\n";
        cout << "(4) Text entschluesseln\n";
        cout << "(5) Zurueck\n";
        cout << "> ";
        input = validatedInput(lowest, end);
        if (input == 1) {
            ecb.crypt(true);
        }
        if (input == 2) {
            ecb.enterKey();
            ecb.enterKlartext();
            ecb.crypt(true);
        }
        if (input == 3) {
            cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
        }
        if (input == 4) {
                ecb.decrypt(true);
        }
        if (input == 5) {
            run = false;
        }
        if (input == -1) {
            cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
            cout << endl;
        }
    }

}

int myGUI::validatedInput(unsigned int lowest, unsigned int highest) {
    int tmp = 0;
    cin.clear();
    if (cin >> tmp) {//Eingabe ist in Ordnung
        cout << endl;
        if (tmp >= lowest && tmp <= highest) {//Eingabe liegt in den Parametern

            return tmp;
        }
    } else {
        string trash = "";
        cin.clear();
        std::getline(std::cin, trash);
    }
    return -1;
}

myGUI::myGUI() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    //Menu-Variablen

    unsigned int lowest = 1;
    unsigned int end = 4;
    int input = end;
    bool run = true;

    //Start
    cout << "#### Kryptographie Sommersemester 2013 ####\n";
    cout << "Nils Rogmann (725915) und Maximilian Krieg (725922)\n";

    // Begrüßung und Information
    cout << "\nHerzlich willkommen.\n";
    cout << "Das Programm wird nun mit Hilfe von Testvektoren geprüft.\n";

    // AES Check
    cout << "\nAES:\t\t";
    if (checkAES()) {
        cout << GREEN_start << "OK" << GREEN_end;
    } else {
        cerr << RED_start << "Fehler" << RED_end;
    }

    // CBC Check
    cout << "\nAES mit CBC:\t";
    if (checkCBC()) {
        cout << GREEN_start << "OK" << GREEN_end;
    } else {
        cerr << RED_start << "Fehler" << RED_end;
    }


    // ECB Check
    cout << "\nAES mit ECB:\t";
    if (checkECB()) 
    {
        cout << GREEN_start << "OK" << GREEN_end;
    }
    else
    {
        cerr << RED_start << "Fehler" << RED_end;
    }
    cout << endl;

    //Menu Eingabe
    while (run) {
        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) AES\n";
        cout << "(2) AES mit CBC\n";
        cout << "(3) AES mit ECB\n";
        cout << "(4) Programm beenden\n";
        cout << "> ";

        input = validatedInput(lowest, end);

        // Aufrufe
        if (input == 1) {
            cout << GREEN_start << "#### AES ####\n" << GREEN_end;
            callAES();
            cout << endl;
        }

        if (input == 2) {
            cout << GREEN_start << "#### AES mit CBC ####\n" << GREEN_end;
            callCBC();
            cout << endl;
        }


        if (input == 3) {
            cout << GREEN_start << "#### AES mit ECB ####\n" << GREEN_end;
            callECB();
            cout << endl;
        }

        // Fehler
        if (input == -1) {
            cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
            cout << endl;
        }

        // Beenden
        if (input == end) {

            cout << "Programm wird beendet.\n";
            run = false;
            cout << endl;
        }
    }
}

myGUI::~myGUI() {
}

myAES.h


#ifndef MYAES_H
#define	MYAES_H

#include <iostream>

using namespace std;
// Typedefs
typedef unsigned char uchar;

class myAES {
public:
    // Konstruktoren/Destruktoren
    myAES();
    virtual ~myAES();

    // Manuelle Eingabe
    void enterKlartext();
    void enterSchluessel();

    // Set/Get-Methoden
    void setKlartext(uchar[16]);
    void setSchluessel(uchar[16]);
    void setCiphertext(uchar[16]);
    uchar* getKlartext();
    uchar* getSchluessel();
    uchar* getCiphertext();

    // AES-Methoden
    void crypt(bool);
    void mixcolumns();
    void shiftrows();
    void schluesselexpansion(uchar[][44], int, int, int);
    void rotword(uchar[], int);
    uchar mix(uchar, unsigned int);
    void subbytes(uchar [], uchar [], int);

    // Print-Methoden
    void printSchluessel();
    void printCiphertext();
    void printKlartext();
    
   void decrypt(bool) ;
   uchar gmul(uchar, uchar);
   void invert_mixcolumns();
   void invert_shiftrows();

private:
    uchar klartext[16];
    uchar schluessel[16];
    uchar ciphertext[16];
};



#endif	/* MYAES_H */

myAES.cpp


#include "myAES.h"

using namespace std;

unsigned char Sbox[256] = {//  s-box
    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, 0x9c, 0xa4, 0x72, 0xc0,
    0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
    0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
    0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
    0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
    0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
    0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
    0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
    0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
    0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
    0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
    0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
    0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
    0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
    0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
};

unsigned char sbox_inverse[256] = {
    0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
    0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
    0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
    0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
    0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
    0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
    0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
    0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
    0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
    0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
    0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
    0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
    0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
    0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
    0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
    0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
};

unsigned char Rcon[256] = {
    0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
    0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,
    0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,
    0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
    0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,
    0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,
    0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b,
    0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
    0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
    0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
    0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
    0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
    0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
    0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,
    0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,
    0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d
};

void myAES::subbytes(uchar sbox[], uchar tmp[], int arrSize) {
    for (int i = 0; i < arrSize; i++) {
        tmp[i] = sbox[tmp[i]];
    }
}// subbytes

uchar myAES::mix(uchar byte, unsigned int mixvalue) {
    unsigned char retValue;
    switch (mixvalue) {
        case 1:
            retValue = byte;
            break;
        case 2:
            retValue = byte << 1;
            if (byte & 0x80) {
                retValue = retValue ^ 0x1b;
            }
            break;
        case 3:
            retValue = byte << 1;
            if (byte & 0x80) {
                retValue = retValue ^ 0x1b;
            }
            retValue = retValue^byte;
            break;
    }
    return retValue;
}

void addRoundKey(uchar klartext[], int iLaenge, uchar matrix[][44], int iReihe, int iSpalte, int iRunde) {
    int pos = 0;
    for (int i = iRunde * 4; i < ((iRunde * 4) + 4) && i < iSpalte; i++) {
        for (int k = 0; k < iReihe; k++) {
            klartext[pos] = klartext[pos] ^ matrix[k][i];
            pos++;
        }
    }
}// addroundkey

void myAES::rotword(uchar column[], int iReihe) {
    uchar tmp = column[0];
    for (int i = 1; i < iReihe; i++) {
        column[i - 1] = column[i];
    }
    column[iReihe - 1] = tmp;
} // rotword

void myAES::schluesselexpansion(uchar matrix[][44], int iReihe, int iSpalte, int iLaenge) {
    // Alle Spalten durchlaufen
    int pos = 0;

    for (int i = 0; i < iSpalte; i++) {
        if (i < 4) { // Schluessel in erste vier Spalten kopieren
            for (int k = 0; k < iReihe && pos < iLaenge; k++) {
                matrix[k][i] = schluessel[pos];
                pos++;
                //cout << hex << "matrix[" << k << "][" << i << "] = " << (int) matrix[k][i] << endl;
            }
        } else { // i > 4
            if (i % 4 == 0) {// erste Spalte eines Schluessels
                // Spalte in Hilfsarray kopieren
                uchar tmp[iReihe]; // i-1
                uchar tmp2[iReihe]; // i-4
                for (int k = 0; k < iReihe; k++) {
                    tmp[k] = matrix[k][i - 1];
                    tmp2[k] = matrix[k][i - 4];
                }

                rotword(tmp, iReihe);

                subbytes(Sbox, tmp, iReihe);

                // Spalte[i-4] XOR subbytes[rotword[i-i]
                for (int k = 0; k < iReihe; k++) {
                    tmp[k] = tmp[k] ^ tmp2[k];
                }

                // tmp[0] XOR (i/4)
                tmp[0] = tmp[0] ^ Rcon[i / iReihe];

                // tmp[k] an Spalte[k][i] kopieren
                for (int k = 0; k < iReihe; k++) {
                    matrix[k][i] = tmp[k];
                }

            } else {
                //cout << "i " << i << endl;
                for (int k = 0; k < iReihe; k++) {
                    matrix[k][i] = matrix[k][i - 4] ^ matrix[k][i - 1];
                }
            }
        }
    }
}// schluesselexpansion

void myAES::shiftrows() {
    uchar copys[16] = {};

    //reihe 1   
    copys[0] = ciphertext[0];
    copys[4] = ciphertext[4];
    copys[8] = ciphertext[8];
    copys[12] = ciphertext[12];

    //reihe 2
    copys[1] = ciphertext[5];
    copys[5] = ciphertext[9];
    copys[9] = ciphertext[13];
    copys[13] = ciphertext[1];

    // reihe 3
    copys[2] = ciphertext[10];
    copys[6] = ciphertext[14];
    copys[10] = ciphertext[2];
    copys[14] = ciphertext[6];

    //reihe 4
    copys[3] = ciphertext[15];
    copys[7] = ciphertext[3];
    copys[11] = ciphertext[7];
    copys[15] = ciphertext[11];

    //umschreiben   
    for (int i = 0; i < 16; i++) {
        ciphertext[i] = copys[i];
    }
}// shiftrows

void myAES::mixcolumns() {
    for (int i = 0; i < 4; i++) {
        uchar sj0 = mix(ciphertext[i * 4], 2)^mix(ciphertext[i * 4 + 1], 3)^mix(ciphertext[i * 4 + 2], 1)^mix(ciphertext[i * 4 + 3], 1);
        uchar sj1 = mix(ciphertext[i * 4], 1)^mix(ciphertext[i * 4 + 1], 2)^mix(ciphertext[i * 4 + 2], 3)^mix(ciphertext[i * 4 + 3], 1);
        uchar sj2 = mix(ciphertext[i * 4], 1)^mix(ciphertext[i * 4 + 1], 1)^mix(ciphertext[i * 4 + 2], 2)^mix(ciphertext[i * 4 + 3], 3);
        uchar sj3 = mix(ciphertext[i * 4], 3)^mix(ciphertext[i * 4 + 1], 1)^mix(ciphertext[i * 4 + 2], 1)^mix(ciphertext[i * 4 + 3], 2);
        ciphertext[i * 4] = sj0;
        ciphertext[i * 4 + 1] = sj1;
        ciphertext[i * 4 + 2] = sj2;
        ciphertext[i * 4 + 3] = sj3;
    }
}// mixcolumns

void myAES::crypt(bool output) {

    // Parameter
    int iRunde = 10;
    int iLaenge = 16;

    // Überschreibe ciphertext um diesen fortan zu verwenden
    for (int i = 0; i < 16; i++) {
        ciphertext[i] = klartext[i];
    }

    // Arraygroesse dynamisch bestimmen
    int arrSize = sizeof (ciphertext) / sizeof (ciphertext[0]);

    // Zwischenspeicherung der Rundenschluessel
    int iReihe = 4;
    int iSpalte = 4 * (iRunde + 1);
    uchar carrRundenschluessel[4][44];

    // Schluessel expandieren
    schluesselexpansion(carrRundenschluessel, iReihe, iSpalte, iLaenge);

    // Vorrunde
    for (int k = 0; k < iLaenge; k++) {
        ciphertext[k] = ciphertext[k] ^ schluessel[k];
    }

    // Durchlaufen der Runden
    for (int i = 1; i < iRunde + 1; i++) {

        // S-Box
        subbytes(Sbox, ciphertext, arrSize);

        // Shift Rows
        shiftrows();

        // Mix Columns
        if (i != (iRunde)) { // kein MixColumns in der letzten Runde
            mixcolumns();
        }

        // Rundenschlüssel addieren
        addRoundKey(ciphertext, arrSize, carrRundenschluessel, iReihe, iSpalte, i);

    }

    // Ausgabe des Ciphertexts
    if (output) {
        printSchluessel();
        printKlartext();
        printCiphertext();
    }
}

void myAES::invert_shiftrows() {
    uchar copys[16] = {};

    //reihe 1   
    copys[0] = klartext[0];
    copys[4] = klartext[4];
    copys[8] = klartext[8];
    copys[12] = klartext[12];

    //reihe 2
    copys[1] = klartext[13];
    copys[13] = klartext[9];
    copys[9] = klartext[5];
    copys[5] = klartext[1];

    // reihe 3   
    copys[6] = klartext[14];
    copys[2] = klartext[10];
    copys[14] = klartext[6];
    copys[10] = klartext[2];

    //reihe 4
    copys[11] = klartext[15];
    copys[7] = klartext[11];
    copys[3] = klartext[7];
    copys[15] = klartext[3];

    //umschreiben   
    for (int i = 0; i < 16; i++) {
        klartext[i] = copys[i];
    }
}// invert_shiftrows

void myAES::invert_mixcolumns() {
    for (int i = 0; i < 4; i++) {
        uchar sj0 = gmul(klartext[i * 4], 14)^gmul(klartext[i * 4 + 1], 11)^gmul(klartext[i * 4 + 2], 13)^gmul(klartext[i * 4 + 3], 9);
        uchar sj1 = gmul(klartext[i * 4], 9)^gmul(klartext[i * 4 + 1], 14)^gmul(klartext[i * 4 + 2], 11)^gmul(klartext[i * 4 + 3], 13);
        uchar sj2 = gmul(klartext[i * 4], 13)^gmul(klartext[i * 4 + 1], 9)^gmul(klartext[i * 4 + 2], 14)^gmul(klartext[i * 4 + 3], 11);
        uchar sj3 = gmul(klartext[i * 4], 11)^gmul(klartext[i * 4 + 1], 13)^gmul(klartext[i * 4 + 2], 9)^gmul(klartext[i * 4 + 3], 14);
        klartext[i * 4] = sj0;
        klartext[i * 4 + 1] = sj1;
        klartext[i * 4 + 2] = sj2;
        klartext[i * 4 + 3] = sj3;
    }
}

uchar myAES::gmul(uchar a, uchar b) {
    unsigned char p = 0;
    unsigned char hi;

    for (int i = 0; i < 8; ++i) {
        if ((b & 1) == 1)
            p ^= a;
        hi = (a & 0x80);
        a <<= 1;
        if (hi == 0x80)
            a ^= 0x1b;
        b >>= 1;
    }
    return p;
}

void myAES::decrypt(bool output) {

    // Parameter
    int iRunde = 10;
    int iLaenge = 16;


    // Überschreibe klartext um diesen fortan zu verwenden
    for (int i = 0; i < 16; i++) {
        klartext[i] = ciphertext[i];
    }


    // Arraygroesse dynamisch bestimmen
    int arrSize = sizeof (klartext) / sizeof (klartext[0]);

    // Zwischenspeicherung der Rundenschluessel
    int iReihe = 4;
    int iSpalte = 4 * (iRunde + 1);
    uchar carrRundenschluessel[4][44];

    // Schluessel expandieren
    schluesselexpansion(carrRundenschluessel, iReihe, iSpalte, iLaenge);

    //printRundenSchluessel(carrRundenschluessel, iReihe, iSpalte);

    // "neue" Vorrunde
    addRoundKey(klartext, arrSize, carrRundenschluessel, iReihe, iSpalte, 10);

    // Durchlaufen der Runden
    for (int i = 9; i > 0; i--) {

        // Shift Rows
        invert_shiftrows();

        // S-Box
        subbytes(sbox_inverse, klartext, arrSize);

        // Rundenschlüssel addieren
        addRoundKey(klartext, arrSize, carrRundenschluessel, iReihe, iSpalte, i);

        // Mix Columns
        if (i != 10) { // kein MixColumns in der letzten Runde
            invert_mixcolumns();
        }
    }


    // Letzte Runde
    invert_shiftrows();
    subbytes(sbox_inverse, klartext, arrSize);

    for (int k = 0; k < iLaenge; k++) {
        klartext[k] = klartext[k] ^ schluessel[k];
    }

    // Ausgabe des Ciphertexts
    if (output) {
        printSchluessel();
        printCiphertext();
        printKlartext();
    }
}// decrypt

void myAES::printSchluessel() {
    cout << endl << "Schluessel:\n";
    for (int i = 0; i < 4; i++)
        cout << hex << "\t0x" << (int) schluessel[0 + i] << "\t0x" << (int) schluessel [4 + i] << "\t0x" << (int) schluessel [8 + i] << "\t0x" << (int) schluessel[12 + i] << endl;
    cout << endl;
}

void myAES::printCiphertext() {
    cout << endl << "Ciphertext:\n";
    for (int i = 0; i < 4; i++)
        cout << hex << "\t0x" << (int) ciphertext[0 + i] << "\t0x" << (int) ciphertext [4 + i] << "\t0x" << (int) ciphertext [8 + i] << "\t0x" << (int) ciphertext[12 + i] << endl;
    cout << endl;
}

void myAES::printKlartext() {
    cout << endl << "Klartext:\n";
    for (int i = 0; i < 4; i++)
        cout << hex << "\t0x" << (int) klartext[0 + i] << "\t0x" << (int) klartext [4 + i] << "\t0x" << (int) klartext [8 + i] << "\t0x" << (int) klartext[12 + i] << endl;
    cout << endl;
}

myAES::myAES() {
    uchar kt[16] = {0x61, 0x62, 0x62, 0x69, 0x6c, 0x64, 0x75, 0x6e, 0x67, 0x73, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78};
    uchar s[16] = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31};
    //uchar c[16] = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31};
    for (int i = 0; i < 16; i++) {
        schluessel[i] = s[i];
        klartext[i] = kt[i];
    }
}

myAES::~myAES() {
}

void myAES::enterKlartext() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    string tmp = "";
    int diff = 0;
    cout << "Klartext (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << RED_start << "\nWerte fuer den Klartext zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << RED_start << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << RED_end << endl;
        }

        if (tmp.length() < 16) {
            cerr << RED_start << "\nWert fuer den Klartext zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << RED_end << endl;
        }

        for (int i = 0; i < 16; i++) {
            klartext[i] = tmp[i];
        }
        cout << endl;

    }
}

void myAES::enterSchluessel() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    string tmp = "";
    int diff = 0;
    cout << "Schluessel (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << RED_start << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << RED_end << endl;
        }

        if (tmp.length() < 16) {
            cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << RED_end << endl;
        }

        for (int i = 0; i < 16; i++) {
            schluessel[i] = tmp[i];
            //cout << hex << tmp[i];
        }
        cout << endl;

    }
}

void myAES::setCiphertext(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        ciphertext[i] = tmp[i];
    }

}

void myAES::setKlartext(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        klartext[i] = tmp[i];
    }
}

void myAES::setSchluessel(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        schluessel[i] = tmp[i];

    }
}

uchar* myAES::getSchluessel() {
    return schluessel;
}

uchar* myAES::getCiphertext() {
    return ciphertext;
}

uchar* myAES::getKlartext() {
    return klartext;
}

myCBC.h


#ifndef MYCBC_H
#define	MYCBC_H
#include "myAES.h"
#include <vector>
class myCBC {
public:
    // Konstruktoren / Destruktoren
    myCBC();
    virtual ~myCBC();
    
    //CBC
    void crypt(bool);
    void decrypt(bool);
    
    // Set/Get-Methoden
    void setKey(uchar[16]);
    void setIV(uchar[16]);
    void setKlartext(vector<uchar>);
    void setCiphertext(vector<uchar>);

    vector<uchar> getKlartext();
    vector<uchar> getCiphertext();
    uchar* getSchluessel();
    uchar* getIV();
    
    // Manuelle Eingabe
    void enterKey();
    void enterIV();
    void enterKlartext();
    
    // Print-Methoden
    void printSchluessel();
    void printCiphertext();
    void printKlartext();
    
private:
    //unsigned int stellen;
    uchar iv[16];
    uchar key[16];
    vector<uchar> klartext;
    vector<uchar> ciphertext;

};

#endif	/* MYCBC_H */

myCBC.cpp


#include "myCBC.h"

void myCBC::enterKey() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    string tmp = "";
    int diff = 0;
    cout << "Schluessel (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << RED_start << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << RED_end << endl;
        }

        if (tmp.length() < 16) {
            cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << RED_end << endl;
        }

        for (int i = 0; i < 16; i++) {
            key[i] = tmp[i];
        }
        cout << endl;

    }
}

void myCBC::enterIV() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    string tmp = "";
    int diff = 0;
    cout << "IV (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << RED_start << "\nWerte fuer den IV zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << RED_start << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << RED_end << endl;
        }

        if (tmp.length() < 16) {
            cerr << RED_start << "\nWert fuer den IV zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << RED_end << endl;
        }

        for (int i = 0; i < 16; i++) {
            iv[i] = tmp[i];
        }
        cout << endl;

    }
}

void myCBC::enterKlartext() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    klartext.clear();
    string tmp = "";
    cout << "Klartext (Beliebig viele Zeichen):";
    if (cin >> tmp) {
        for (int i = 0; i < tmp.size(); i++) {
            klartext.push_back(tmp[i]);
        }
        cout << endl;
    }

    if (tmp.size() % 16 != 0) {
        cerr << RED_start << "\nLetzter Klartext-Block nicht vollstaendig. Fuelle mit Nullen auf.\n";
        for (int i = 0; i < 16 - tmp.size() % 16; i++) {
            klartext.push_back('\0');
        }
        cout << RED_end << endl;
    }
}

myCBC::myCBC() {

    // Default Parameter
    uchar newKey[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar newIV[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    uchar newKlartext[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};

    // Schluessel setzen
    for (int i = 0; i < 16; i++) {
        key[i] = newKey[i];
    }

    //IV setzen
    for (int i = 0; i < 16; i++) {
        iv[i] = newIV[i];
    }

    // Klartext setzen
    for (int i = 0; i < 16; i++) {
        klartext.push_back(newKlartext[i]);
    }
}

void myCBC::printSchluessel() {
    cout << endl << "Schluessel:\n";
    for (int i = 0; i < 4; i++)
        cout << hex << "\t0x" << (int) key[0 + i] << "\t0x" << (int) key [4 + i] << "\t0x" << (int) key [8 + i] << "\t0x" << (int) key[12 + i] << endl;
    cout << endl;
}

void myCBC::printCiphertext() {
    cout << endl << "Ciphertext:\n";
    for (int i = 0; i < ciphertext.size(); i++) {
        cout << std::hex << " 0x" << (int) ciphertext[i];
    }
}

void myCBC::printKlartext() {
    cout << endl << "Klartext:\n";
    for (int i = 0; i < klartext.size(); i++) {
        cout << std::hex << " 0x" << (int) klartext[i];
    }
}

vector<uchar> myCBC::getCiphertext() {
    return ciphertext;
}

void myCBC::decrypt(bool print) {
    klartext.clear();
    uchar tmp_iv[16];
    for (int j = 0; j < 16; j++) {
        tmp_iv[j] = iv[j];
    }
    //printSchluessel();
    //printKlartext();
    //printCiphertext();
    for (int i = 0; i < ciphertext.size() / 16; i++) {

        myAES a1;

        //Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = ciphertext[j + 16 * i];
        }

        // Ciphertext
        a1.setCiphertext(tmp);

        // Schluessel
        a1.setSchluessel(key);

        // crypt
        a1.decrypt(false);

        // Resultat mit IV addieren
        for (int j = 0; j < 16; j++) {

            a1.getKlartext()[j] = a1.getKlartext()[j]^tmp_iv[j];
        }

        for (int j = 0; j < 16; j++) {
            tmp_iv[j] = a1.getCiphertext()[j + 16 * i];
            klartext.push_back(a1.getKlartext()[j]);
        }
    }

    if (print) {
        printSchluessel();
        printCiphertext();
        printKlartext();
    }

}

void myCBC::crypt(bool print) {
    ciphertext.clear();
    uchar tmp_iv[16];
    for (int i = 0; i < 16; i++) {
        tmp_iv[i] = iv[i];
    }

    for (int i = 0; i < klartext.size() / 16; i++) {

        myAES a1;
        a1.setSchluessel(key);

        //XOR in Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = klartext[j + 16 * i]^tmp_iv[j];
        }

        // Klartext
        a1.setKlartext(tmp);

        // crypt
        a1.crypt(false);


        for (int j = 0; j < 16; j++) {
            tmp_iv[j] = a1.getCiphertext()[j];
            ciphertext.push_back(a1.getCiphertext()[j]);
        }
    }

    if (print) {
        printSchluessel();
        printKlartext();
        printCiphertext();
    }
}

void myCBC::setKlartext(vector<uchar> kt) {
    if (kt.size() > klartext.size()) {
        int diff = kt.size() - klartext.size();
        for (int i = 0; i < diff; i++) {
            klartext.push_back(0x00);
        }
    }
    for (int i = 0; i < kt.size(); i++) {
        klartext.at(i) = kt.at(i);
    }
}

void myCBC::setIV(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        iv[i] = tmp[i];
    }
}

void myCBC::setKey(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        key[i] = tmp[i];
    }
}

myCBC::~myCBC() {
}

myECB.h



#ifndef MYECB_H
#define	MYECB_H

#include "myAES.h"
#include <vector>
class myECB {
public:
    // Konstruktoren / Destruktoren
    myECB();
    virtual ~myECB();
    
    //CBC
    void crypt(bool);
    void decrypt(bool);
    
    // Set/Get-Methoden
    void setKey(uchar[16]);
    
    void setKlartext(vector<uchar>);
    void setCiphertext(vector<uchar>);

    vector<uchar> getKlartext();
    vector<uchar> getCiphertext();
    uchar* getSchluessel();
    
    
    // Manuelle Eingabe
    void enterKey();
    
    void enterKlartext();
    
    // Print-Methoden
    void printSchluessel();
    void printCiphertext();
    void printKlartext();
    
private:
    //unsigned int stellen;
    
    uchar key[16];
    vector<uchar> klartext;
    vector<uchar> ciphertext;

};

#endif	/* MYECB_H */

myECB.cpp



#include "myECB.h"

void myECB::enterKey() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    string tmp = "";
    int diff = 0;
    cout << "Schluessel (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << RED_start << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << RED_end << endl;
        }

        if (tmp.length() < 16) {
            cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << RED_end << endl;
        }

        for (int i = 0; i < 16; i++) {
            key[i] = tmp[i];
        }
        cout << endl;

    }
}

void myECB::enterKlartext() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    klartext.clear();
    string tmp = "";
    cout << "Klartext (Beliebig viele Zeichen):";
    if (cin >> tmp) {
        for (int i = 0; i < tmp.size(); i++) {
            klartext.push_back(tmp[i]);
        }
        cout << endl;
    }

    if (tmp.size() % 16 != 0) {
        cerr << RED_start << "\nLetzter Klartext-Block nicht vollstaendig. Fuelle mit Nullen auf.\n";
        for (int i = 0; i < 16 - tmp.size() % 16; i++) {
            klartext.push_back('\0');
        }
        cout << RED_end << endl;
    }
}

myECB::myECB() {

    // Default Parameter
    uchar newKey[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar newIV[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    uchar newKlartext[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};

    // Schluessel setzen
    for (int i = 0; i < 16; i++) {
        key[i] = newKey[i];
    }

    // Klartext setzen
    for (int i = 0; i < 16; i++) {
        klartext.push_back(newKlartext[i]);
    }
}

void myECB::printSchluessel() {
    cout << endl << "Schluessel:\n";
    for (int i = 0; i < 4; i++)
        cout << hex << "\t0x" << (int) key[0 + i] << "\t0x" << (int) key [4 + i] << "\t0x" << (int) key [8 + i] << "\t0x" << (int) key[12 + i] << endl;
    cout << endl;
}

void myECB::printCiphertext() {
    cout << endl << "Ciphertext:\n";
    for (int i = 0; i < ciphertext.size(); i++) {
        cout << std::hex << " 0x" << (int) ciphertext[i];
    }
}

void myECB::printKlartext() {
    cout << endl << "Klartext:\n";
    for (int i = 0; i < klartext.size(); i++) {
        cout << std::hex << " 0x" << (int) klartext[i];
    }
}

vector<uchar> myECB::getCiphertext() {
    return ciphertext;
}

void myECB::decrypt(bool print) {
    klartext.clear();

    for (int i = 0; i < ciphertext.size() / 16; i++) {

        myAES a1;

        //Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = ciphertext[j + 16 * i];
        }

        // Ciphertext
        a1.setCiphertext(tmp);

        // Schluessel
        a1.setSchluessel(key);

        // crypt
        a1.decrypt(false);

        // Resultat mit IV addieren
        for (int j = 0; j < 16; j++) {
            klartext.push_back(a1.getKlartext()[j]);
        }
    }

    if (print) {
        printSchluessel();
        printCiphertext();
        printKlartext();
    }

}

void myECB::crypt(bool print) {
    ciphertext.clear();
    /* uchar tmp_iv[16];
     for (int i = 0; i < 16; i++) {
         tmp_iv[i] = iv[i];
     }*/

    for (int i = 0; i < klartext.size() / 16; i++) {

        myAES a1;
        a1.setSchluessel(key);

        //XOR in Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = klartext[j + 16 * i]; //^tmp_iv[j];
        }

        // Klartext
        a1.setKlartext(tmp);

        // crypt
        a1.crypt(false);


        for (int j = 0; j < 16; j++) {
            //tmp_iv[j] = a1.getCiphertext()[j];
            ciphertext.push_back(a1.getCiphertext()[j]);
        }
    }

    if (print) {
        printSchluessel();
        printKlartext();
        printCiphertext();
    }
}

void myECB::setKlartext(vector<uchar> kt) {
    if (kt.size() > klartext.size()) {
        int diff = kt.size() - klartext.size();
        for (int i = 0; i < diff; i++) {
            klartext.push_back(0x00);
        }
    }
    for (int i = 0; i < kt.size(); i++) {
        klartext.at(i) = kt.at(i);
    }
}

void myECB::setKey(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        key[i] = tmp[i];
    }
}

myECB::~myECB() {
}

Schreiben Sie einen Kommentar

Ihre E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahren Sie, wie Ihre Kommentardaten verarbeitet werden.

'); } cout << RED_end << endl; } for (int i = 0; i < 16; i++) { iv[i] = tmp[i]; } cout << endl; } } void myCBC::enterKlartext() { string RED_start = "3[22;31m"; string RED_end = "3[0m"; klartext.clear(); string tmp = ""; cout << "Klartext (Beliebig viele Zeichen):"; if (cin >> tmp) { for (int i = 0; i < tmp.size(); i++) { klartext.push_back(tmp[i]); } cout << endl; } if (tmp.size() % 16 != 0) { cerr << RED_start << "\nLetzter Klartext-Block nicht vollstaendig. Fuelle mit Nullen auf.\n"; for (int i = 0; i < 16 - tmp.size() % 16; i++) { klartext.push_back('
Menu Close

Kryptologie (Praktikum 3)

Skript-AnfangKryptouebung2 – Seite 1
Skript-EndeKryptouebung2 – Seite 1

main.cpp


// Präprozessor-Direktiven
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include "myGUI.h"

// Using-Deklarationen
using namespace std;

int main(int argc, char** argv) {
    myGUI gui;
}// main

myGUI.h


#ifndef MYGUI_H
#define	MYGUI_H

#include <iostream>
#include "myCBC.h"
#include "myECB.h"

class myGUI {
public:
    myGUI();
    void callAES();
    void callCBC();
    void callECB();
    bool checkAES();
    bool checkCBC();
    bool checkECB();
    int validatedInput(unsigned int, unsigned int);
    virtual ~myGUI();
private:
};

#endif	/* MYGUI_H */

myGUI.cpp


#include "myGUI.h"
#include <vector>

using namespace std;

bool areEqual(vector<uchar> v1, vector<uchar> v2) {
    bool tmp = false;
    if (v1.size() == v2.size()) {
        for (int i = 0; i < v1.size(); i++) {
            if (v1[i] == v2[i]) {
                tmp = true;
            } else {
                cout << hex << v1[i] << "!=" << v2[i] << endl;
                tmp = false;
                break;
            }
        }
    }
    return tmp;
}

bool areEqual(uchar* arr1, uchar* arr2) {
    bool tmp = false;
    for (int i = 0; i < 16; i++) {
        if (arr1[i] == arr2[i]) {
            tmp = true;
        } else {
            cout << hex << arr1[i] << "!=" << arr2[i] << endl;
            tmp = false;
            break;
        }
    }
    return tmp;
}

bool myGUI::checkCBC() {
    bool returnValue = false;

    //16 Byte Testvektoren
    uchar keyB[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar ivB[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    uchar klartextB1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar ciphertextB1[16] = {0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d};
    vector<uchar> cipherB1;
    vector<uchar> ktB;

    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartextB1[i]);
        cipherB1.push_back(ciphertextB1[i]);
    }

    myCBC cbcB;
    cbcB.setKey(keyB);
    cbcB.setIV(ivB);
    cbcB.setKlartext(ktB);
    cbcB.crypt(false);

    // 32 Byte Testvektoren

    uchar klartextA1[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
    uchar klartextA2[16] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};
    uchar ivA[16] = {0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28, 0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58};
    uchar keyA[16] = {0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0, 0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a};
    uchar ciphertextA1[16] = {0xd2, 0x96, 0xcd, 0x94, 0xc2, 0xcc, 0xcf, 0x8a, 0x3a, 0x86, 0x30, 0x28, 0xb5, 0xe1, 0xdc, 0x0a};
    uchar ciphertextA2[16] = {0x75, 0x86, 0x60, 0x2d, 0x25, 0x3c, 0xff, 0xf9, 0x1b, 0x82, 0x66, 0xbe, 0xa6, 0xd6, 0x1a, 0xb1};
    vector<uchar> cipherA1;

    vector<uchar> test;

    for (int i = 0; i < 16; i++) {
        test.push_back(klartextA1[i]);
        cipherA1.push_back(ciphertextA1[i]);
    }

    for (int i = 0; i < 16; i++) {
        test.push_back(klartextA2[i]);
        cipherA1.push_back(ciphertextA2[i]);
    }

    myCBC cbcA;
    cbcA.setKey(keyA);
    cbcA.setIV(ivA);
    cbcA.setKlartext(test);
    cbcA.crypt(false);

    //Prüfung
    bool isWorking = areEqual(cbcA.getCiphertext(), cipherA1) && areEqual(cbcB.getCiphertext(), cipherB1);

    if (isWorking) {
        returnValue = true;
    } else {
        returnValue = false;
    }
    return returnValue;
}

bool myGUI::checkECB() {
    bool returnValue = false;

    //16 Byte Testvektoren
    uchar schluessel[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};

    uchar klartext_1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar klartext_2[16] = {0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
    uchar klartext_3[16] = {0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef};

    uchar cipher_1[16] = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97};
    uchar cipher_2[16] = {0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d, 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf};
    uchar cipher_3[16] = {0x43, 0xb1, 0xcd, 0x7f, 0x59, 0x8e, 0xce, 0x23, 0x88, 0x1b, 0x00, 0xe3, 0xed, 0x03, 0x06, 0x88};
    vector<uchar> cipherB1;
    vector<uchar> ktB;

    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_1[i]);
        cipherB1.push_back(cipher_1[i]);
    }

    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_2[i]);
        cipherB1.push_back(cipher_2[i]);
    }

    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_3[i]);
        cipherB1.push_back(cipher_3[i]);
    }

    myECB ecb;
    ecb.setKey(schluessel);
    ecb.setKlartext(ktB);
    ecb.crypt(false);

    //Prüfung
    bool isWorking = areEqual(ecb.getCiphertext(), cipherB1);

    if (isWorking) {
        returnValue = true;
    } else {
        returnValue = false;
    }
    return returnValue;
}

bool myGUI::checkAES() {

    bool returnValue = false;
    uchar schluessel[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};

    uchar klartext_1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar klartext_2[16] = {0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
    uchar klartext_3[16] = {0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef};

    uchar cipher_1[16] = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97};
    uchar cipher_2[16] = {0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d, 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf};
    uchar cipher_3[16] = {0x43, 0xb1, 0xcd, 0x7f, 0x59, 0x8e, 0xce, 0x23, 0x88, 0x1b, 0x00, 0xe3, 0xed, 0x03, 0x06, 0x88};

    myAES aes1;
    aes1.setKlartext(klartext_1);
    aes1.setSchluessel(schluessel);
    aes1.crypt(false);

    myAES aes2;
    aes2.setKlartext(klartext_2);
    aes2.setSchluessel(schluessel);
    aes2.crypt(false);

    myAES aes3;
    aes3.setKlartext(klartext_3);
    aes3.setSchluessel(schluessel);
    aes3.crypt(false);

    bool isWorking = areEqual(aes3.getCiphertext(), cipher_3) && areEqual(aes2.getCiphertext(), cipher_2) && areEqual(aes1.getCiphertext(), cipher_1);
    if (isWorking) {
        returnValue = true;
    } else {

        returnValue = false;
    }
    return returnValue;
}

void myGUI::callAES() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    myAES aes;
    aes.crypt(false);
    //myAES aesDecrypt;
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 5;
    int input = end;

    //Menu Eingabe
    while (run) {
        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Text und Schluessel aus Datei laden\n";
        cout << "(4) Entschluesseln \n";
        cout << "(5) Zurueck\n";
        cout << "> ";
        input = validatedInput(lowest, end);
        if (input == 1) {
            aes.crypt(true);
        }
        if (input == 2) {
            aes.enterKlartext();
            aes.enterSchluessel();
            aes.crypt(true);
        }
        if (input == 3) {
            cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
        }
        if (input == 4) {
            aes.decrypt(true);
        }
        if (input == 5) {
            run = false;
        }
        if (input == -1) {

            cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
            cout << endl;
        }
    }
}

void myGUI::callCBC() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    myCBC cbc;
    cbc.crypt(true);
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 5;
    int input = end;

    //Menu Eingabe
    while (run) {

        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Text und Schluessel aus Datei laden\n";
        cout << "(4) Text entschluesseln\n";
        cout << "(5) Zurueck\n";
        cout << "> ";
        input = validatedInput(lowest, end);
        if (input == 1) {
            cbc.crypt(true);
        }
        if (input == 2) {
            cbc.enterIV();
            cbc.enterKey();
            cbc.enterKlartext();
            cbc.crypt(true);
        }
        if (input == 3) {
            cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
        }
        if (input == 4) {
            cbc.decrypt(true);
        }
        if (input == 5) {
            run = false;
        }
        if (input == -1) {
            cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
            cout << endl;
        }
    }

}

void myGUI::callECB() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    myECB ecb;
    ecb.crypt(false);
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 5;
    int input = end;

    //Menu Eingabe
    while (run) {

        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Text und Schluessel aus Datei laden\n";
        cout << "(4) Text entschluesseln\n";
        cout << "(5) Zurueck\n";
        cout << "> ";
        input = validatedInput(lowest, end);
        if (input == 1) {
            ecb.crypt(true);
        }
        if (input == 2) {
            ecb.enterKey();
            ecb.enterKlartext();
            ecb.crypt(true);
        }
        if (input == 3) {
            cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
        }
        if (input == 4) {
                ecb.decrypt(true);
        }
        if (input == 5) {
            run = false;
        }
        if (input == -1) {
            cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
            cout << endl;
        }
    }

}

int myGUI::validatedInput(unsigned int lowest, unsigned int highest) {
    int tmp = 0;
    cin.clear();
    if (cin >> tmp) {//Eingabe ist in Ordnung
        cout << endl;
        if (tmp >= lowest && tmp <= highest) {//Eingabe liegt in den Parametern

            return tmp;
        }
    } else {
        string trash = "";
        cin.clear();
        std::getline(std::cin, trash);
    }
    return -1;
}

myGUI::myGUI() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    //Menu-Variablen

    unsigned int lowest = 1;
    unsigned int end = 4;
    int input = end;
    bool run = true;

    //Start
    cout << "#### Kryptographie Sommersemester 2013 ####\n";
    cout << "Nils Rogmann (725915) und Maximilian Krieg (725922)\n";

    // Begrüßung und Information
    cout << "\nHerzlich willkommen.\n";
    cout << "Das Programm wird nun mit Hilfe von Testvektoren geprüft.\n";

    // AES Check
    cout << "\nAES:\t\t";
    if (checkAES()) {
        cout << GREEN_start << "OK" << GREEN_end;
    } else {
        cerr << RED_start << "Fehler" << RED_end;
    }

    // CBC Check
    cout << "\nAES mit CBC:\t";
    if (checkCBC()) {
        cout << GREEN_start << "OK" << GREEN_end;
    } else {
        cerr << RED_start << "Fehler" << RED_end;
    }


    // ECB Check
    cout << "\nAES mit ECB:\t";
    if (checkECB()) 
    {
        cout << GREEN_start << "OK" << GREEN_end;
    }
    else
    {
        cerr << RED_start << "Fehler" << RED_end;
    }
    cout << endl;

    //Menu Eingabe
    while (run) {
        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) AES\n";
        cout << "(2) AES mit CBC\n";
        cout << "(3) AES mit ECB\n";
        cout << "(4) Programm beenden\n";
        cout << "> ";

        input = validatedInput(lowest, end);

        // Aufrufe
        if (input == 1) {
            cout << GREEN_start << "#### AES ####\n" << GREEN_end;
            callAES();
            cout << endl;
        }

        if (input == 2) {
            cout << GREEN_start << "#### AES mit CBC ####\n" << GREEN_end;
            callCBC();
            cout << endl;
        }


        if (input == 3) {
            cout << GREEN_start << "#### AES mit ECB ####\n" << GREEN_end;
            callECB();
            cout << endl;
        }

        // Fehler
        if (input == -1) {
            cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
            cout << endl;
        }

        // Beenden
        if (input == end) {

            cout << "Programm wird beendet.\n";
            run = false;
            cout << endl;
        }
    }
}

myGUI::~myGUI() {
}

myAES.h


#ifndef MYAES_H
#define	MYAES_H

#include <iostream>

using namespace std;
// Typedefs
typedef unsigned char uchar;

class myAES {
public:
    // Konstruktoren/Destruktoren
    myAES();
    virtual ~myAES();

    // Manuelle Eingabe
    void enterKlartext();
    void enterSchluessel();

    // Set/Get-Methoden
    void setKlartext(uchar[16]);
    void setSchluessel(uchar[16]);
    void setCiphertext(uchar[16]);
    uchar* getKlartext();
    uchar* getSchluessel();
    uchar* getCiphertext();

    // AES-Methoden
    void crypt(bool);
    void mixcolumns();
    void shiftrows();
    void schluesselexpansion(uchar[][44], int, int, int);
    void rotword(uchar[], int);
    uchar mix(uchar, unsigned int);
    void subbytes(uchar [], uchar [], int);

    // Print-Methoden
    void printSchluessel();
    void printCiphertext();
    void printKlartext();
    
   void decrypt(bool) ;
   uchar gmul(uchar, uchar);
   void invert_mixcolumns();
   void invert_shiftrows();

private:
    uchar klartext[16];
    uchar schluessel[16];
    uchar ciphertext[16];
};



#endif	/* MYAES_H */

myAES.cpp


#include "myAES.h"

using namespace std;

unsigned char Sbox[256] = {//  s-box
    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, 0x9c, 0xa4, 0x72, 0xc0,
    0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
    0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
    0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
    0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
    0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
    0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
    0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
    0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
    0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
    0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
    0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
    0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
    0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
    0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
};

unsigned char sbox_inverse[256] = {
    0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
    0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
    0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
    0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
    0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
    0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
    0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
    0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
    0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
    0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
    0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
    0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
    0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
    0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
    0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
    0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
};

unsigned char Rcon[256] = {
    0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
    0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,
    0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,
    0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
    0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,
    0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,
    0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b,
    0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
    0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
    0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
    0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
    0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
    0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
    0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,
    0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,
    0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d
};

void myAES::subbytes(uchar sbox[], uchar tmp[], int arrSize) {
    for (int i = 0; i < arrSize; i++) {
        tmp[i] = sbox[tmp[i]];
    }
}// subbytes

uchar myAES::mix(uchar byte, unsigned int mixvalue) {
    unsigned char retValue;
    switch (mixvalue) {
        case 1:
            retValue = byte;
            break;
        case 2:
            retValue = byte << 1;
            if (byte & 0x80) {
                retValue = retValue ^ 0x1b;
            }
            break;
        case 3:
            retValue = byte << 1;
            if (byte & 0x80) {
                retValue = retValue ^ 0x1b;
            }
            retValue = retValue^byte;
            break;
    }
    return retValue;
}

void addRoundKey(uchar klartext[], int iLaenge, uchar matrix[][44], int iReihe, int iSpalte, int iRunde) {
    int pos = 0;
    for (int i = iRunde * 4; i < ((iRunde * 4) + 4) && i < iSpalte; i++) {
        for (int k = 0; k < iReihe; k++) {
            klartext[pos] = klartext[pos] ^ matrix[k][i];
            pos++;
        }
    }
}// addroundkey

void myAES::rotword(uchar column[], int iReihe) {
    uchar tmp = column[0];
    for (int i = 1; i < iReihe; i++) {
        column[i - 1] = column[i];
    }
    column[iReihe - 1] = tmp;
} // rotword

void myAES::schluesselexpansion(uchar matrix[][44], int iReihe, int iSpalte, int iLaenge) {
    // Alle Spalten durchlaufen
    int pos = 0;

    for (int i = 0; i < iSpalte; i++) {
        if (i < 4) { // Schluessel in erste vier Spalten kopieren
            for (int k = 0; k < iReihe && pos < iLaenge; k++) {
                matrix[k][i] = schluessel[pos];
                pos++;
                //cout << hex << "matrix[" << k << "][" << i << "] = " << (int) matrix[k][i] << endl;
            }
        } else { // i > 4
            if (i % 4 == 0) {// erste Spalte eines Schluessels
                // Spalte in Hilfsarray kopieren
                uchar tmp[iReihe]; // i-1
                uchar tmp2[iReihe]; // i-4
                for (int k = 0; k < iReihe; k++) {
                    tmp[k] = matrix[k][i - 1];
                    tmp2[k] = matrix[k][i - 4];
                }

                rotword(tmp, iReihe);

                subbytes(Sbox, tmp, iReihe);

                // Spalte[i-4] XOR subbytes[rotword[i-i]
                for (int k = 0; k < iReihe; k++) {
                    tmp[k] = tmp[k] ^ tmp2[k];
                }

                // tmp[0] XOR (i/4)
                tmp[0] = tmp[0] ^ Rcon[i / iReihe];

                // tmp[k] an Spalte[k][i] kopieren
                for (int k = 0; k < iReihe; k++) {
                    matrix[k][i] = tmp[k];
                }

            } else {
                //cout << "i " << i << endl;
                for (int k = 0; k < iReihe; k++) {
                    matrix[k][i] = matrix[k][i - 4] ^ matrix[k][i - 1];
                }
            }
        }
    }
}// schluesselexpansion

void myAES::shiftrows() {
    uchar copys[16] = {};

    //reihe 1   
    copys[0] = ciphertext[0];
    copys[4] = ciphertext[4];
    copys[8] = ciphertext[8];
    copys[12] = ciphertext[12];

    //reihe 2
    copys[1] = ciphertext[5];
    copys[5] = ciphertext[9];
    copys[9] = ciphertext[13];
    copys[13] = ciphertext[1];

    // reihe 3
    copys[2] = ciphertext[10];
    copys[6] = ciphertext[14];
    copys[10] = ciphertext[2];
    copys[14] = ciphertext[6];

    //reihe 4
    copys[3] = ciphertext[15];
    copys[7] = ciphertext[3];
    copys[11] = ciphertext[7];
    copys[15] = ciphertext[11];

    //umschreiben   
    for (int i = 0; i < 16; i++) {
        ciphertext[i] = copys[i];
    }
}// shiftrows

void myAES::mixcolumns() {
    for (int i = 0; i < 4; i++) {
        uchar sj0 = mix(ciphertext[i * 4], 2)^mix(ciphertext[i * 4 + 1], 3)^mix(ciphertext[i * 4 + 2], 1)^mix(ciphertext[i * 4 + 3], 1);
        uchar sj1 = mix(ciphertext[i * 4], 1)^mix(ciphertext[i * 4 + 1], 2)^mix(ciphertext[i * 4 + 2], 3)^mix(ciphertext[i * 4 + 3], 1);
        uchar sj2 = mix(ciphertext[i * 4], 1)^mix(ciphertext[i * 4 + 1], 1)^mix(ciphertext[i * 4 + 2], 2)^mix(ciphertext[i * 4 + 3], 3);
        uchar sj3 = mix(ciphertext[i * 4], 3)^mix(ciphertext[i * 4 + 1], 1)^mix(ciphertext[i * 4 + 2], 1)^mix(ciphertext[i * 4 + 3], 2);
        ciphertext[i * 4] = sj0;
        ciphertext[i * 4 + 1] = sj1;
        ciphertext[i * 4 + 2] = sj2;
        ciphertext[i * 4 + 3] = sj3;
    }
}// mixcolumns

void myAES::crypt(bool output) {

    // Parameter
    int iRunde = 10;
    int iLaenge = 16;

    // Überschreibe ciphertext um diesen fortan zu verwenden
    for (int i = 0; i < 16; i++) {
        ciphertext[i] = klartext[i];
    }

    // Arraygroesse dynamisch bestimmen
    int arrSize = sizeof (ciphertext) / sizeof (ciphertext[0]);

    // Zwischenspeicherung der Rundenschluessel
    int iReihe = 4;
    int iSpalte = 4 * (iRunde + 1);
    uchar carrRundenschluessel[4][44];

    // Schluessel expandieren
    schluesselexpansion(carrRundenschluessel, iReihe, iSpalte, iLaenge);

    // Vorrunde
    for (int k = 0; k < iLaenge; k++) {
        ciphertext[k] = ciphertext[k] ^ schluessel[k];
    }

    // Durchlaufen der Runden
    for (int i = 1; i < iRunde + 1; i++) {

        // S-Box
        subbytes(Sbox, ciphertext, arrSize);

        // Shift Rows
        shiftrows();

        // Mix Columns
        if (i != (iRunde)) { // kein MixColumns in der letzten Runde
            mixcolumns();
        }

        // Rundenschlüssel addieren
        addRoundKey(ciphertext, arrSize, carrRundenschluessel, iReihe, iSpalte, i);

    }

    // Ausgabe des Ciphertexts
    if (output) {
        printSchluessel();
        printKlartext();
        printCiphertext();
    }
}

void myAES::invert_shiftrows() {
    uchar copys[16] = {};

    //reihe 1   
    copys[0] = klartext[0];
    copys[4] = klartext[4];
    copys[8] = klartext[8];
    copys[12] = klartext[12];

    //reihe 2
    copys[1] = klartext[13];
    copys[13] = klartext[9];
    copys[9] = klartext[5];
    copys[5] = klartext[1];

    // reihe 3   
    copys[6] = klartext[14];
    copys[2] = klartext[10];
    copys[14] = klartext[6];
    copys[10] = klartext[2];

    //reihe 4
    copys[11] = klartext[15];
    copys[7] = klartext[11];
    copys[3] = klartext[7];
    copys[15] = klartext[3];

    //umschreiben   
    for (int i = 0; i < 16; i++) {
        klartext[i] = copys[i];
    }
}// invert_shiftrows

void myAES::invert_mixcolumns() {
    for (int i = 0; i < 4; i++) {
        uchar sj0 = gmul(klartext[i * 4], 14)^gmul(klartext[i * 4 + 1], 11)^gmul(klartext[i * 4 + 2], 13)^gmul(klartext[i * 4 + 3], 9);
        uchar sj1 = gmul(klartext[i * 4], 9)^gmul(klartext[i * 4 + 1], 14)^gmul(klartext[i * 4 + 2], 11)^gmul(klartext[i * 4 + 3], 13);
        uchar sj2 = gmul(klartext[i * 4], 13)^gmul(klartext[i * 4 + 1], 9)^gmul(klartext[i * 4 + 2], 14)^gmul(klartext[i * 4 + 3], 11);
        uchar sj3 = gmul(klartext[i * 4], 11)^gmul(klartext[i * 4 + 1], 13)^gmul(klartext[i * 4 + 2], 9)^gmul(klartext[i * 4 + 3], 14);
        klartext[i * 4] = sj0;
        klartext[i * 4 + 1] = sj1;
        klartext[i * 4 + 2] = sj2;
        klartext[i * 4 + 3] = sj3;
    }
}

uchar myAES::gmul(uchar a, uchar b) {
    unsigned char p = 0;
    unsigned char hi;

    for (int i = 0; i < 8; ++i) {
        if ((b & 1) == 1)
            p ^= a;
        hi = (a & 0x80);
        a <<= 1;
        if (hi == 0x80)
            a ^= 0x1b;
        b >>= 1;
    }
    return p;
}

void myAES::decrypt(bool output) {

    // Parameter
    int iRunde = 10;
    int iLaenge = 16;


    // Überschreibe klartext um diesen fortan zu verwenden
    for (int i = 0; i < 16; i++) {
        klartext[i] = ciphertext[i];
    }


    // Arraygroesse dynamisch bestimmen
    int arrSize = sizeof (klartext) / sizeof (klartext[0]);

    // Zwischenspeicherung der Rundenschluessel
    int iReihe = 4;
    int iSpalte = 4 * (iRunde + 1);
    uchar carrRundenschluessel[4][44];

    // Schluessel expandieren
    schluesselexpansion(carrRundenschluessel, iReihe, iSpalte, iLaenge);

    //printRundenSchluessel(carrRundenschluessel, iReihe, iSpalte);

    // "neue" Vorrunde
    addRoundKey(klartext, arrSize, carrRundenschluessel, iReihe, iSpalte, 10);

    // Durchlaufen der Runden
    for (int i = 9; i > 0; i--) {

        // Shift Rows
        invert_shiftrows();

        // S-Box
        subbytes(sbox_inverse, klartext, arrSize);

        // Rundenschlüssel addieren
        addRoundKey(klartext, arrSize, carrRundenschluessel, iReihe, iSpalte, i);

        // Mix Columns
        if (i != 10) { // kein MixColumns in der letzten Runde
            invert_mixcolumns();
        }
    }


    // Letzte Runde
    invert_shiftrows();
    subbytes(sbox_inverse, klartext, arrSize);

    for (int k = 0; k < iLaenge; k++) {
        klartext[k] = klartext[k] ^ schluessel[k];
    }

    // Ausgabe des Ciphertexts
    if (output) {
        printSchluessel();
        printCiphertext();
        printKlartext();
    }
}// decrypt

void myAES::printSchluessel() {
    cout << endl << "Schluessel:\n";
    for (int i = 0; i < 4; i++)
        cout << hex << "\t0x" << (int) schluessel[0 + i] << "\t0x" << (int) schluessel [4 + i] << "\t0x" << (int) schluessel [8 + i] << "\t0x" << (int) schluessel[12 + i] << endl;
    cout << endl;
}

void myAES::printCiphertext() {
    cout << endl << "Ciphertext:\n";
    for (int i = 0; i < 4; i++)
        cout << hex << "\t0x" << (int) ciphertext[0 + i] << "\t0x" << (int) ciphertext [4 + i] << "\t0x" << (int) ciphertext [8 + i] << "\t0x" << (int) ciphertext[12 + i] << endl;
    cout << endl;
}

void myAES::printKlartext() {
    cout << endl << "Klartext:\n";
    for (int i = 0; i < 4; i++)
        cout << hex << "\t0x" << (int) klartext[0 + i] << "\t0x" << (int) klartext [4 + i] << "\t0x" << (int) klartext [8 + i] << "\t0x" << (int) klartext[12 + i] << endl;
    cout << endl;
}

myAES::myAES() {
    uchar kt[16] = {0x61, 0x62, 0x62, 0x69, 0x6c, 0x64, 0x75, 0x6e, 0x67, 0x73, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78};
    uchar s[16] = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31};
    //uchar c[16] = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31};
    for (int i = 0; i < 16; i++) {
        schluessel[i] = s[i];
        klartext[i] = kt[i];
    }
}

myAES::~myAES() {
}

void myAES::enterKlartext() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    string tmp = "";
    int diff = 0;
    cout << "Klartext (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << RED_start << "\nWerte fuer den Klartext zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << RED_start << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << RED_end << endl;
        }

        if (tmp.length() < 16) {
            cerr << RED_start << "\nWert fuer den Klartext zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << RED_end << endl;
        }

        for (int i = 0; i < 16; i++) {
            klartext[i] = tmp[i];
        }
        cout << endl;

    }
}

void myAES::enterSchluessel() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    string tmp = "";
    int diff = 0;
    cout << "Schluessel (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << RED_start << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << RED_end << endl;
        }

        if (tmp.length() < 16) {
            cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << RED_end << endl;
        }

        for (int i = 0; i < 16; i++) {
            schluessel[i] = tmp[i];
            //cout << hex << tmp[i];
        }
        cout << endl;

    }
}

void myAES::setCiphertext(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        ciphertext[i] = tmp[i];
    }

}

void myAES::setKlartext(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        klartext[i] = tmp[i];
    }
}

void myAES::setSchluessel(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        schluessel[i] = tmp[i];

    }
}

uchar* myAES::getSchluessel() {
    return schluessel;
}

uchar* myAES::getCiphertext() {
    return ciphertext;
}

uchar* myAES::getKlartext() {
    return klartext;
}

myCBC.h


#ifndef MYCBC_H
#define	MYCBC_H
#include "myAES.h"
#include <vector>
class myCBC {
public:
    // Konstruktoren / Destruktoren
    myCBC();
    virtual ~myCBC();
    
    //CBC
    void crypt(bool);
    void decrypt(bool);
    
    // Set/Get-Methoden
    void setKey(uchar[16]);
    void setIV(uchar[16]);
    void setKlartext(vector<uchar>);
    void setCiphertext(vector<uchar>);

    vector<uchar> getKlartext();
    vector<uchar> getCiphertext();
    uchar* getSchluessel();
    uchar* getIV();
    
    // Manuelle Eingabe
    void enterKey();
    void enterIV();
    void enterKlartext();
    
    // Print-Methoden
    void printSchluessel();
    void printCiphertext();
    void printKlartext();
    
private:
    //unsigned int stellen;
    uchar iv[16];
    uchar key[16];
    vector<uchar> klartext;
    vector<uchar> ciphertext;

};

#endif	/* MYCBC_H */

myCBC.cpp


#include "myCBC.h"

void myCBC::enterKey() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    string tmp = "";
    int diff = 0;
    cout << "Schluessel (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << RED_start << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << RED_end << endl;
        }

        if (tmp.length() < 16) {
            cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << RED_end << endl;
        }

        for (int i = 0; i < 16; i++) {
            key[i] = tmp[i];
        }
        cout << endl;

    }
}

void myCBC::enterIV() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    string tmp = "";
    int diff = 0;
    cout << "IV (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << RED_start << "\nWerte fuer den IV zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << RED_start << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << RED_end << endl;
        }

        if (tmp.length() < 16) {
            cerr << RED_start << "\nWert fuer den IV zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << RED_end << endl;
        }

        for (int i = 0; i < 16; i++) {
            iv[i] = tmp[i];
        }
        cout << endl;

    }
}

void myCBC::enterKlartext() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    klartext.clear();
    string tmp = "";
    cout << "Klartext (Beliebig viele Zeichen):";
    if (cin >> tmp) {
        for (int i = 0; i < tmp.size(); i++) {
            klartext.push_back(tmp[i]);
        }
        cout << endl;
    }

    if (tmp.size() % 16 != 0) {
        cerr << RED_start << "\nLetzter Klartext-Block nicht vollstaendig. Fuelle mit Nullen auf.\n";
        for (int i = 0; i < 16 - tmp.size() % 16; i++) {
            klartext.push_back('\0');
        }
        cout << RED_end << endl;
    }
}

myCBC::myCBC() {

    // Default Parameter
    uchar newKey[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar newIV[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    uchar newKlartext[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};

    // Schluessel setzen
    for (int i = 0; i < 16; i++) {
        key[i] = newKey[i];
    }

    //IV setzen
    for (int i = 0; i < 16; i++) {
        iv[i] = newIV[i];
    }

    // Klartext setzen
    for (int i = 0; i < 16; i++) {
        klartext.push_back(newKlartext[i]);
    }
}

void myCBC::printSchluessel() {
    cout << endl << "Schluessel:\n";
    for (int i = 0; i < 4; i++)
        cout << hex << "\t0x" << (int) key[0 + i] << "\t0x" << (int) key [4 + i] << "\t0x" << (int) key [8 + i] << "\t0x" << (int) key[12 + i] << endl;
    cout << endl;
}

void myCBC::printCiphertext() {
    cout << endl << "Ciphertext:\n";
    for (int i = 0; i < ciphertext.size(); i++) {
        cout << std::hex << " 0x" << (int) ciphertext[i];
    }
}

void myCBC::printKlartext() {
    cout << endl << "Klartext:\n";
    for (int i = 0; i < klartext.size(); i++) {
        cout << std::hex << " 0x" << (int) klartext[i];
    }
}

vector<uchar> myCBC::getCiphertext() {
    return ciphertext;
}

void myCBC::decrypt(bool print) {
    klartext.clear();
    uchar tmp_iv[16];
    for (int j = 0; j < 16; j++) {
        tmp_iv[j] = iv[j];
    }
    //printSchluessel();
    //printKlartext();
    //printCiphertext();
    for (int i = 0; i < ciphertext.size() / 16; i++) {

        myAES a1;

        //Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = ciphertext[j + 16 * i];
        }

        // Ciphertext
        a1.setCiphertext(tmp);

        // Schluessel
        a1.setSchluessel(key);

        // crypt
        a1.decrypt(false);

        // Resultat mit IV addieren
        for (int j = 0; j < 16; j++) {

            a1.getKlartext()[j] = a1.getKlartext()[j]^tmp_iv[j];
        }

        for (int j = 0; j < 16; j++) {
            tmp_iv[j] = a1.getCiphertext()[j + 16 * i];
            klartext.push_back(a1.getKlartext()[j]);
        }
    }

    if (print) {
        printSchluessel();
        printCiphertext();
        printKlartext();
    }

}

void myCBC::crypt(bool print) {
    ciphertext.clear();
    uchar tmp_iv[16];
    for (int i = 0; i < 16; i++) {
        tmp_iv[i] = iv[i];
    }

    for (int i = 0; i < klartext.size() / 16; i++) {

        myAES a1;
        a1.setSchluessel(key);

        //XOR in Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = klartext[j + 16 * i]^tmp_iv[j];
        }

        // Klartext
        a1.setKlartext(tmp);

        // crypt
        a1.crypt(false);


        for (int j = 0; j < 16; j++) {
            tmp_iv[j] = a1.getCiphertext()[j];
            ciphertext.push_back(a1.getCiphertext()[j]);
        }
    }

    if (print) {
        printSchluessel();
        printKlartext();
        printCiphertext();
    }
}

void myCBC::setKlartext(vector<uchar> kt) {
    if (kt.size() > klartext.size()) {
        int diff = kt.size() - klartext.size();
        for (int i = 0; i < diff; i++) {
            klartext.push_back(0x00);
        }
    }
    for (int i = 0; i < kt.size(); i++) {
        klartext.at(i) = kt.at(i);
    }
}

void myCBC::setIV(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        iv[i] = tmp[i];
    }
}

void myCBC::setKey(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        key[i] = tmp[i];
    }
}

myCBC::~myCBC() {
}

myECB.h



#ifndef MYECB_H
#define	MYECB_H

#include "myAES.h"
#include <vector>
class myECB {
public:
    // Konstruktoren / Destruktoren
    myECB();
    virtual ~myECB();
    
    //CBC
    void crypt(bool);
    void decrypt(bool);
    
    // Set/Get-Methoden
    void setKey(uchar[16]);
    
    void setKlartext(vector<uchar>);
    void setCiphertext(vector<uchar>);

    vector<uchar> getKlartext();
    vector<uchar> getCiphertext();
    uchar* getSchluessel();
    
    
    // Manuelle Eingabe
    void enterKey();
    
    void enterKlartext();
    
    // Print-Methoden
    void printSchluessel();
    void printCiphertext();
    void printKlartext();
    
private:
    //unsigned int stellen;
    
    uchar key[16];
    vector<uchar> klartext;
    vector<uchar> ciphertext;

};

#endif	/* MYECB_H */

myECB.cpp



#include "myECB.h"

void myECB::enterKey() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    string tmp = "";
    int diff = 0;
    cout << "Schluessel (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << RED_start << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << RED_end << endl;
        }

        if (tmp.length() < 16) {
            cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << RED_end << endl;
        }

        for (int i = 0; i < 16; i++) {
            key[i] = tmp[i];
        }
        cout << endl;

    }
}

void myECB::enterKlartext() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    klartext.clear();
    string tmp = "";
    cout << "Klartext (Beliebig viele Zeichen):";
    if (cin >> tmp) {
        for (int i = 0; i < tmp.size(); i++) {
            klartext.push_back(tmp[i]);
        }
        cout << endl;
    }

    if (tmp.size() % 16 != 0) {
        cerr << RED_start << "\nLetzter Klartext-Block nicht vollstaendig. Fuelle mit Nullen auf.\n";
        for (int i = 0; i < 16 - tmp.size() % 16; i++) {
            klartext.push_back('\0');
        }
        cout << RED_end << endl;
    }
}

myECB::myECB() {

    // Default Parameter
    uchar newKey[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar newIV[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    uchar newKlartext[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};

    // Schluessel setzen
    for (int i = 0; i < 16; i++) {
        key[i] = newKey[i];
    }

    // Klartext setzen
    for (int i = 0; i < 16; i++) {
        klartext.push_back(newKlartext[i]);
    }
}

void myECB::printSchluessel() {
    cout << endl << "Schluessel:\n";
    for (int i = 0; i < 4; i++)
        cout << hex << "\t0x" << (int) key[0 + i] << "\t0x" << (int) key [4 + i] << "\t0x" << (int) key [8 + i] << "\t0x" << (int) key[12 + i] << endl;
    cout << endl;
}

void myECB::printCiphertext() {
    cout << endl << "Ciphertext:\n";
    for (int i = 0; i < ciphertext.size(); i++) {
        cout << std::hex << " 0x" << (int) ciphertext[i];
    }
}

void myECB::printKlartext() {
    cout << endl << "Klartext:\n";
    for (int i = 0; i < klartext.size(); i++) {
        cout << std::hex << " 0x" << (int) klartext[i];
    }
}

vector<uchar> myECB::getCiphertext() {
    return ciphertext;
}

void myECB::decrypt(bool print) {
    klartext.clear();

    for (int i = 0; i < ciphertext.size() / 16; i++) {

        myAES a1;

        //Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = ciphertext[j + 16 * i];
        }

        // Ciphertext
        a1.setCiphertext(tmp);

        // Schluessel
        a1.setSchluessel(key);

        // crypt
        a1.decrypt(false);

        // Resultat mit IV addieren
        for (int j = 0; j < 16; j++) {
            klartext.push_back(a1.getKlartext()[j]);
        }
    }

    if (print) {
        printSchluessel();
        printCiphertext();
        printKlartext();
    }

}

void myECB::crypt(bool print) {
    ciphertext.clear();
    /* uchar tmp_iv[16];
     for (int i = 0; i < 16; i++) {
         tmp_iv[i] = iv[i];
     }*/

    for (int i = 0; i < klartext.size() / 16; i++) {

        myAES a1;
        a1.setSchluessel(key);

        //XOR in Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = klartext[j + 16 * i]; //^tmp_iv[j];
        }

        // Klartext
        a1.setKlartext(tmp);

        // crypt
        a1.crypt(false);


        for (int j = 0; j < 16; j++) {
            //tmp_iv[j] = a1.getCiphertext()[j];
            ciphertext.push_back(a1.getCiphertext()[j]);
        }
    }

    if (print) {
        printSchluessel();
        printKlartext();
        printCiphertext();
    }
}

void myECB::setKlartext(vector<uchar> kt) {
    if (kt.size() > klartext.size()) {
        int diff = kt.size() - klartext.size();
        for (int i = 0; i < diff; i++) {
            klartext.push_back(0x00);
        }
    }
    for (int i = 0; i < kt.size(); i++) {
        klartext.at(i) = kt.at(i);
    }
}

void myECB::setKey(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        key[i] = tmp[i];
    }
}

myECB::~myECB() {
}

Schreiben Sie einen Kommentar

Ihre E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahren Sie, wie Ihre Kommentardaten verarbeitet werden.

'); } cout << RED_end << endl; } } myCBC::myCBC() { // Default Parameter uchar newKey[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c}; uchar newIV[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}; uchar newKlartext[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a}; // Schluessel setzen for (int i = 0; i < 16; i++) { key[i] = newKey[i]; } //IV setzen for (int i = 0; i < 16; i++) { iv[i] = newIV[i]; } // Klartext setzen for (int i = 0; i < 16; i++) { klartext.push_back(newKlartext[i]); } } void myCBC::printSchluessel() { cout << endl << "Schluessel:\n"; for (int i = 0; i < 4; i++) cout << hex << "\t0x" << (int) key[0 + i] << "\t0x" << (int) key [4 + i] << "\t0x" << (int) key [8 + i] << "\t0x" << (int) key[12 + i] << endl; cout << endl; } void myCBC::printCiphertext() { cout << endl << "Ciphertext:\n"; for (int i = 0; i < ciphertext.size(); i++) { cout << std::hex << " 0x" << (int) ciphertext[i]; } } void myCBC::printKlartext() { cout << endl << "Klartext:\n"; for (int i = 0; i < klartext.size(); i++) { cout << std::hex << " 0x" << (int) klartext[i]; } } vector<uchar> myCBC::getCiphertext() { return ciphertext; } void myCBC::decrypt(bool print) { klartext.clear(); uchar tmp_iv[16]; for (int j = 0; j < 16; j++) { tmp_iv[j] = iv[j]; } //printSchluessel(); //printKlartext(); //printCiphertext(); for (int i = 0; i < ciphertext.size() / 16; i++) { myAES a1; //Übergabe - Array uchar tmp[16]; for (int j = 0; j < 16; j++) { tmp[j] = ciphertext[j + 16 * i]; } // Ciphertext a1.setCiphertext(tmp); // Schluessel a1.setSchluessel(key); // crypt a1.decrypt(false); // Resultat mit IV addieren for (int j = 0; j < 16; j++) { a1.getKlartext()[j] = a1.getKlartext()[j]^tmp_iv[j]; } for (int j = 0; j < 16; j++) { tmp_iv[j] = a1.getCiphertext()[j + 16 * i]; klartext.push_back(a1.getKlartext()[j]); } } if (print) { printSchluessel(); printCiphertext(); printKlartext(); } } void myCBC::crypt(bool print) { ciphertext.clear(); uchar tmp_iv[16]; for (int i = 0; i < 16; i++) { tmp_iv[i] = iv[i]; } for (int i = 0; i < klartext.size() / 16; i++) { myAES a1; a1.setSchluessel(key); //XOR in Übergabe - Array uchar tmp[16]; for (int j = 0; j < 16; j++) { tmp[j] = klartext[j + 16 * i]^tmp_iv[j]; } // Klartext a1.setKlartext(tmp); // crypt a1.crypt(false); for (int j = 0; j < 16; j++) { tmp_iv[j] = a1.getCiphertext()[j]; ciphertext.push_back(a1.getCiphertext()[j]); } } if (print) { printSchluessel(); printKlartext(); printCiphertext(); } } void myCBC::setKlartext(vector<uchar> kt) { if (kt.size() > klartext.size()) { int diff = kt.size() - klartext.size(); for (int i = 0; i < diff; i++) { klartext.push_back(0x00); } } for (int i = 0; i < kt.size(); i++) { klartext.at(i) = kt.at(i); } } void myCBC::setIV(uchar tmp[16]) { for (int i = 0; i < 16; i++) { iv[i] = tmp[i]; } } void myCBC::setKey(uchar tmp[16]) { for (int i = 0; i < 16; i++) { key[i] = tmp[i]; } } myCBC::~myCBC() { }

myECB.h



#ifndef MYECB_H
#define	MYECB_H

#include "myAES.h"
#include <vector>
class myECB {
public:
    // Konstruktoren / Destruktoren
    myECB();
    virtual ~myECB();
    
    //CBC
    void crypt(bool);
    void decrypt(bool);
    
    // Set/Get-Methoden
    void setKey(uchar[16]);
    
    void setKlartext(vector<uchar>);
    void setCiphertext(vector<uchar>);

    vector<uchar> getKlartext();
    vector<uchar> getCiphertext();
    uchar* getSchluessel();
    
    
    // Manuelle Eingabe
    void enterKey();
    
    void enterKlartext();
    
    // Print-Methoden
    void printSchluessel();
    void printCiphertext();
    void printKlartext();
    
private:
    //unsigned int stellen;
    
    uchar key[16];
    vector<uchar> klartext;
    vector<uchar> ciphertext;

};

#endif	/* MYECB_H */

myECB.cpp


#include "myECB.h"
void myECB::enterKey() {
string RED_start = "3[22;31m";
string RED_end = "3[0m";
string GREEN_start = "3[22;32m";
string GREEN_end = "3[0m";
string tmp = "";
int diff = 0;
cout << "Schluessel (16 Zeichen):";
if (cin >> tmp) {
if (tmp.length() > 16) {
cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
for (int i = 0; i < tmp.length(); i++) {
if (i == 16) {
cerr << RED_start << " | ";
}
cerr << tmp.at(i);
}
cout << ")" << RED_end << endl;
}
if (tmp.length() < 16) {
cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
diff = 16 - tmp.length();
for (int i = 0; i < diff; i++) {
tmp.push_back('
Menu Close

Kryptologie (Praktikum 3)

Skript-AnfangKryptouebung2 – Seite 1
Skript-EndeKryptouebung2 – Seite 1

main.cpp


// Präprozessor-Direktiven
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include "myGUI.h"

// Using-Deklarationen
using namespace std;

int main(int argc, char** argv) {
    myGUI gui;
}// main

myGUI.h


#ifndef MYGUI_H
#define	MYGUI_H

#include <iostream>
#include "myCBC.h"
#include "myECB.h"

class myGUI {
public:
    myGUI();
    void callAES();
    void callCBC();
    void callECB();
    bool checkAES();
    bool checkCBC();
    bool checkECB();
    int validatedInput(unsigned int, unsigned int);
    virtual ~myGUI();
private:
};

#endif	/* MYGUI_H */

myGUI.cpp


#include "myGUI.h"
#include <vector>

using namespace std;

bool areEqual(vector<uchar> v1, vector<uchar> v2) {
    bool tmp = false;
    if (v1.size() == v2.size()) {
        for (int i = 0; i < v1.size(); i++) {
            if (v1[i] == v2[i]) {
                tmp = true;
            } else {
                cout << hex << v1[i] << "!=" << v2[i] << endl;
                tmp = false;
                break;
            }
        }
    }
    return tmp;
}

bool areEqual(uchar* arr1, uchar* arr2) {
    bool tmp = false;
    for (int i = 0; i < 16; i++) {
        if (arr1[i] == arr2[i]) {
            tmp = true;
        } else {
            cout << hex << arr1[i] << "!=" << arr2[i] << endl;
            tmp = false;
            break;
        }
    }
    return tmp;
}

bool myGUI::checkCBC() {
    bool returnValue = false;

    //16 Byte Testvektoren
    uchar keyB[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar ivB[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    uchar klartextB1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar ciphertextB1[16] = {0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d};
    vector<uchar> cipherB1;
    vector<uchar> ktB;

    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartextB1[i]);
        cipherB1.push_back(ciphertextB1[i]);
    }

    myCBC cbcB;
    cbcB.setKey(keyB);
    cbcB.setIV(ivB);
    cbcB.setKlartext(ktB);
    cbcB.crypt(false);

    // 32 Byte Testvektoren

    uchar klartextA1[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
    uchar klartextA2[16] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};
    uchar ivA[16] = {0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28, 0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58};
    uchar keyA[16] = {0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0, 0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a};
    uchar ciphertextA1[16] = {0xd2, 0x96, 0xcd, 0x94, 0xc2, 0xcc, 0xcf, 0x8a, 0x3a, 0x86, 0x30, 0x28, 0xb5, 0xe1, 0xdc, 0x0a};
    uchar ciphertextA2[16] = {0x75, 0x86, 0x60, 0x2d, 0x25, 0x3c, 0xff, 0xf9, 0x1b, 0x82, 0x66, 0xbe, 0xa6, 0xd6, 0x1a, 0xb1};
    vector<uchar> cipherA1;

    vector<uchar> test;

    for (int i = 0; i < 16; i++) {
        test.push_back(klartextA1[i]);
        cipherA1.push_back(ciphertextA1[i]);
    }

    for (int i = 0; i < 16; i++) {
        test.push_back(klartextA2[i]);
        cipherA1.push_back(ciphertextA2[i]);
    }

    myCBC cbcA;
    cbcA.setKey(keyA);
    cbcA.setIV(ivA);
    cbcA.setKlartext(test);
    cbcA.crypt(false);

    //Prüfung
    bool isWorking = areEqual(cbcA.getCiphertext(), cipherA1) && areEqual(cbcB.getCiphertext(), cipherB1);

    if (isWorking) {
        returnValue = true;
    } else {
        returnValue = false;
    }
    return returnValue;
}

bool myGUI::checkECB() {
    bool returnValue = false;

    //16 Byte Testvektoren
    uchar schluessel[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};

    uchar klartext_1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar klartext_2[16] = {0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
    uchar klartext_3[16] = {0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef};

    uchar cipher_1[16] = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97};
    uchar cipher_2[16] = {0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d, 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf};
    uchar cipher_3[16] = {0x43, 0xb1, 0xcd, 0x7f, 0x59, 0x8e, 0xce, 0x23, 0x88, 0x1b, 0x00, 0xe3, 0xed, 0x03, 0x06, 0x88};
    vector<uchar> cipherB1;
    vector<uchar> ktB;

    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_1[i]);
        cipherB1.push_back(cipher_1[i]);
    }

    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_2[i]);
        cipherB1.push_back(cipher_2[i]);
    }

    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_3[i]);
        cipherB1.push_back(cipher_3[i]);
    }

    myECB ecb;
    ecb.setKey(schluessel);
    ecb.setKlartext(ktB);
    ecb.crypt(false);

    //Prüfung
    bool isWorking = areEqual(ecb.getCiphertext(), cipherB1);

    if (isWorking) {
        returnValue = true;
    } else {
        returnValue = false;
    }
    return returnValue;
}

bool myGUI::checkAES() {

    bool returnValue = false;
    uchar schluessel[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};

    uchar klartext_1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar klartext_2[16] = {0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
    uchar klartext_3[16] = {0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef};

    uchar cipher_1[16] = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97};
    uchar cipher_2[16] = {0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d, 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf};
    uchar cipher_3[16] = {0x43, 0xb1, 0xcd, 0x7f, 0x59, 0x8e, 0xce, 0x23, 0x88, 0x1b, 0x00, 0xe3, 0xed, 0x03, 0x06, 0x88};

    myAES aes1;
    aes1.setKlartext(klartext_1);
    aes1.setSchluessel(schluessel);
    aes1.crypt(false);

    myAES aes2;
    aes2.setKlartext(klartext_2);
    aes2.setSchluessel(schluessel);
    aes2.crypt(false);

    myAES aes3;
    aes3.setKlartext(klartext_3);
    aes3.setSchluessel(schluessel);
    aes3.crypt(false);

    bool isWorking = areEqual(aes3.getCiphertext(), cipher_3) && areEqual(aes2.getCiphertext(), cipher_2) && areEqual(aes1.getCiphertext(), cipher_1);
    if (isWorking) {
        returnValue = true;
    } else {

        returnValue = false;
    }
    return returnValue;
}

void myGUI::callAES() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    myAES aes;
    aes.crypt(false);
    //myAES aesDecrypt;
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 5;
    int input = end;

    //Menu Eingabe
    while (run) {
        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Text und Schluessel aus Datei laden\n";
        cout << "(4) Entschluesseln \n";
        cout << "(5) Zurueck\n";
        cout << "> ";
        input = validatedInput(lowest, end);
        if (input == 1) {
            aes.crypt(true);
        }
        if (input == 2) {
            aes.enterKlartext();
            aes.enterSchluessel();
            aes.crypt(true);
        }
        if (input == 3) {
            cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
        }
        if (input == 4) {
            aes.decrypt(true);
        }
        if (input == 5) {
            run = false;
        }
        if (input == -1) {

            cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
            cout << endl;
        }
    }
}

void myGUI::callCBC() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    myCBC cbc;
    cbc.crypt(true);
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 5;
    int input = end;

    //Menu Eingabe
    while (run) {

        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Text und Schluessel aus Datei laden\n";
        cout << "(4) Text entschluesseln\n";
        cout << "(5) Zurueck\n";
        cout << "> ";
        input = validatedInput(lowest, end);
        if (input == 1) {
            cbc.crypt(true);
        }
        if (input == 2) {
            cbc.enterIV();
            cbc.enterKey();
            cbc.enterKlartext();
            cbc.crypt(true);
        }
        if (input == 3) {
            cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
        }
        if (input == 4) {
            cbc.decrypt(true);
        }
        if (input == 5) {
            run = false;
        }
        if (input == -1) {
            cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
            cout << endl;
        }
    }

}

void myGUI::callECB() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    myECB ecb;
    ecb.crypt(false);
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 5;
    int input = end;

    //Menu Eingabe
    while (run) {

        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Text und Schluessel aus Datei laden\n";
        cout << "(4) Text entschluesseln\n";
        cout << "(5) Zurueck\n";
        cout << "> ";
        input = validatedInput(lowest, end);
        if (input == 1) {
            ecb.crypt(true);
        }
        if (input == 2) {
            ecb.enterKey();
            ecb.enterKlartext();
            ecb.crypt(true);
        }
        if (input == 3) {
            cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
        }
        if (input == 4) {
                ecb.decrypt(true);
        }
        if (input == 5) {
            run = false;
        }
        if (input == -1) {
            cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
            cout << endl;
        }
    }

}

int myGUI::validatedInput(unsigned int lowest, unsigned int highest) {
    int tmp = 0;
    cin.clear();
    if (cin >> tmp) {//Eingabe ist in Ordnung
        cout << endl;
        if (tmp >= lowest && tmp <= highest) {//Eingabe liegt in den Parametern

            return tmp;
        }
    } else {
        string trash = "";
        cin.clear();
        std::getline(std::cin, trash);
    }
    return -1;
}

myGUI::myGUI() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    //Menu-Variablen

    unsigned int lowest = 1;
    unsigned int end = 4;
    int input = end;
    bool run = true;

    //Start
    cout << "#### Kryptographie Sommersemester 2013 ####\n";
    cout << "Nils Rogmann (725915) und Maximilian Krieg (725922)\n";

    // Begrüßung und Information
    cout << "\nHerzlich willkommen.\n";
    cout << "Das Programm wird nun mit Hilfe von Testvektoren geprüft.\n";

    // AES Check
    cout << "\nAES:\t\t";
    if (checkAES()) {
        cout << GREEN_start << "OK" << GREEN_end;
    } else {
        cerr << RED_start << "Fehler" << RED_end;
    }

    // CBC Check
    cout << "\nAES mit CBC:\t";
    if (checkCBC()) {
        cout << GREEN_start << "OK" << GREEN_end;
    } else {
        cerr << RED_start << "Fehler" << RED_end;
    }


    // ECB Check
    cout << "\nAES mit ECB:\t";
    if (checkECB()) 
    {
        cout << GREEN_start << "OK" << GREEN_end;
    }
    else
    {
        cerr << RED_start << "Fehler" << RED_end;
    }
    cout << endl;

    //Menu Eingabe
    while (run) {
        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) AES\n";
        cout << "(2) AES mit CBC\n";
        cout << "(3) AES mit ECB\n";
        cout << "(4) Programm beenden\n";
        cout << "> ";

        input = validatedInput(lowest, end);

        // Aufrufe
        if (input == 1) {
            cout << GREEN_start << "#### AES ####\n" << GREEN_end;
            callAES();
            cout << endl;
        }

        if (input == 2) {
            cout << GREEN_start << "#### AES mit CBC ####\n" << GREEN_end;
            callCBC();
            cout << endl;
        }


        if (input == 3) {
            cout << GREEN_start << "#### AES mit ECB ####\n" << GREEN_end;
            callECB();
            cout << endl;
        }

        // Fehler
        if (input == -1) {
            cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
            cout << endl;
        }

        // Beenden
        if (input == end) {

            cout << "Programm wird beendet.\n";
            run = false;
            cout << endl;
        }
    }
}

myGUI::~myGUI() {
}

myAES.h


#ifndef MYAES_H
#define	MYAES_H

#include <iostream>

using namespace std;
// Typedefs
typedef unsigned char uchar;

class myAES {
public:
    // Konstruktoren/Destruktoren
    myAES();
    virtual ~myAES();

    // Manuelle Eingabe
    void enterKlartext();
    void enterSchluessel();

    // Set/Get-Methoden
    void setKlartext(uchar[16]);
    void setSchluessel(uchar[16]);
    void setCiphertext(uchar[16]);
    uchar* getKlartext();
    uchar* getSchluessel();
    uchar* getCiphertext();

    // AES-Methoden
    void crypt(bool);
    void mixcolumns();
    void shiftrows();
    void schluesselexpansion(uchar[][44], int, int, int);
    void rotword(uchar[], int);
    uchar mix(uchar, unsigned int);
    void subbytes(uchar [], uchar [], int);

    // Print-Methoden
    void printSchluessel();
    void printCiphertext();
    void printKlartext();
    
   void decrypt(bool) ;
   uchar gmul(uchar, uchar);
   void invert_mixcolumns();
   void invert_shiftrows();

private:
    uchar klartext[16];
    uchar schluessel[16];
    uchar ciphertext[16];
};



#endif	/* MYAES_H */

myAES.cpp


#include "myAES.h"

using namespace std;

unsigned char Sbox[256] = {//  s-box
    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, 0x9c, 0xa4, 0x72, 0xc0,
    0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
    0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
    0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
    0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
    0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
    0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
    0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
    0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
    0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
    0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
    0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
    0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
    0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
    0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
};

unsigned char sbox_inverse[256] = {
    0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
    0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
    0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
    0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
    0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
    0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
    0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
    0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
    0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
    0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
    0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
    0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
    0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
    0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
    0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
    0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
};

unsigned char Rcon[256] = {
    0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
    0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,
    0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,
    0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
    0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,
    0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,
    0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b,
    0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
    0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
    0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
    0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
    0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
    0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
    0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,
    0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,
    0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d
};

void myAES::subbytes(uchar sbox[], uchar tmp[], int arrSize) {
    for (int i = 0; i < arrSize; i++) {
        tmp[i] = sbox[tmp[i]];
    }
}// subbytes

uchar myAES::mix(uchar byte, unsigned int mixvalue) {
    unsigned char retValue;
    switch (mixvalue) {
        case 1:
            retValue = byte;
            break;
        case 2:
            retValue = byte << 1;
            if (byte & 0x80) {
                retValue = retValue ^ 0x1b;
            }
            break;
        case 3:
            retValue = byte << 1;
            if (byte & 0x80) {
                retValue = retValue ^ 0x1b;
            }
            retValue = retValue^byte;
            break;
    }
    return retValue;
}

void addRoundKey(uchar klartext[], int iLaenge, uchar matrix[][44], int iReihe, int iSpalte, int iRunde) {
    int pos = 0;
    for (int i = iRunde * 4; i < ((iRunde * 4) + 4) && i < iSpalte; i++) {
        for (int k = 0; k < iReihe; k++) {
            klartext[pos] = klartext[pos] ^ matrix[k][i];
            pos++;
        }
    }
}// addroundkey

void myAES::rotword(uchar column[], int iReihe) {
    uchar tmp = column[0];
    for (int i = 1; i < iReihe; i++) {
        column[i - 1] = column[i];
    }
    column[iReihe - 1] = tmp;
} // rotword

void myAES::schluesselexpansion(uchar matrix[][44], int iReihe, int iSpalte, int iLaenge) {
    // Alle Spalten durchlaufen
    int pos = 0;

    for (int i = 0; i < iSpalte; i++) {
        if (i < 4) { // Schluessel in erste vier Spalten kopieren
            for (int k = 0; k < iReihe && pos < iLaenge; k++) {
                matrix[k][i] = schluessel[pos];
                pos++;
                //cout << hex << "matrix[" << k << "][" << i << "] = " << (int) matrix[k][i] << endl;
            }
        } else { // i > 4
            if (i % 4 == 0) {// erste Spalte eines Schluessels
                // Spalte in Hilfsarray kopieren
                uchar tmp[iReihe]; // i-1
                uchar tmp2[iReihe]; // i-4
                for (int k = 0; k < iReihe; k++) {
                    tmp[k] = matrix[k][i - 1];
                    tmp2[k] = matrix[k][i - 4];
                }

                rotword(tmp, iReihe);

                subbytes(Sbox, tmp, iReihe);

                // Spalte[i-4] XOR subbytes[rotword[i-i]
                for (int k = 0; k < iReihe; k++) {
                    tmp[k] = tmp[k] ^ tmp2[k];
                }

                // tmp[0] XOR (i/4)
                tmp[0] = tmp[0] ^ Rcon[i / iReihe];

                // tmp[k] an Spalte[k][i] kopieren
                for (int k = 0; k < iReihe; k++) {
                    matrix[k][i] = tmp[k];
                }

            } else {
                //cout << "i " << i << endl;
                for (int k = 0; k < iReihe; k++) {
                    matrix[k][i] = matrix[k][i - 4] ^ matrix[k][i - 1];
                }
            }
        }
    }
}// schluesselexpansion

void myAES::shiftrows() {
    uchar copys[16] = {};

    //reihe 1   
    copys[0] = ciphertext[0];
    copys[4] = ciphertext[4];
    copys[8] = ciphertext[8];
    copys[12] = ciphertext[12];

    //reihe 2
    copys[1] = ciphertext[5];
    copys[5] = ciphertext[9];
    copys[9] = ciphertext[13];
    copys[13] = ciphertext[1];

    // reihe 3
    copys[2] = ciphertext[10];
    copys[6] = ciphertext[14];
    copys[10] = ciphertext[2];
    copys[14] = ciphertext[6];

    //reihe 4
    copys[3] = ciphertext[15];
    copys[7] = ciphertext[3];
    copys[11] = ciphertext[7];
    copys[15] = ciphertext[11];

    //umschreiben   
    for (int i = 0; i < 16; i++) {
        ciphertext[i] = copys[i];
    }
}// shiftrows

void myAES::mixcolumns() {
    for (int i = 0; i < 4; i++) {
        uchar sj0 = mix(ciphertext[i * 4], 2)^mix(ciphertext[i * 4 + 1], 3)^mix(ciphertext[i * 4 + 2], 1)^mix(ciphertext[i * 4 + 3], 1);
        uchar sj1 = mix(ciphertext[i * 4], 1)^mix(ciphertext[i * 4 + 1], 2)^mix(ciphertext[i * 4 + 2], 3)^mix(ciphertext[i * 4 + 3], 1);
        uchar sj2 = mix(ciphertext[i * 4], 1)^mix(ciphertext[i * 4 + 1], 1)^mix(ciphertext[i * 4 + 2], 2)^mix(ciphertext[i * 4 + 3], 3);
        uchar sj3 = mix(ciphertext[i * 4], 3)^mix(ciphertext[i * 4 + 1], 1)^mix(ciphertext[i * 4 + 2], 1)^mix(ciphertext[i * 4 + 3], 2);
        ciphertext[i * 4] = sj0;
        ciphertext[i * 4 + 1] = sj1;
        ciphertext[i * 4 + 2] = sj2;
        ciphertext[i * 4 + 3] = sj3;
    }
}// mixcolumns

void myAES::crypt(bool output) {

    // Parameter
    int iRunde = 10;
    int iLaenge = 16;

    // Überschreibe ciphertext um diesen fortan zu verwenden
    for (int i = 0; i < 16; i++) {
        ciphertext[i] = klartext[i];
    }

    // Arraygroesse dynamisch bestimmen
    int arrSize = sizeof (ciphertext) / sizeof (ciphertext[0]);

    // Zwischenspeicherung der Rundenschluessel
    int iReihe = 4;
    int iSpalte = 4 * (iRunde + 1);
    uchar carrRundenschluessel[4][44];

    // Schluessel expandieren
    schluesselexpansion(carrRundenschluessel, iReihe, iSpalte, iLaenge);

    // Vorrunde
    for (int k = 0; k < iLaenge; k++) {
        ciphertext[k] = ciphertext[k] ^ schluessel[k];
    }

    // Durchlaufen der Runden
    for (int i = 1; i < iRunde + 1; i++) {

        // S-Box
        subbytes(Sbox, ciphertext, arrSize);

        // Shift Rows
        shiftrows();

        // Mix Columns
        if (i != (iRunde)) { // kein MixColumns in der letzten Runde
            mixcolumns();
        }

        // Rundenschlüssel addieren
        addRoundKey(ciphertext, arrSize, carrRundenschluessel, iReihe, iSpalte, i);

    }

    // Ausgabe des Ciphertexts
    if (output) {
        printSchluessel();
        printKlartext();
        printCiphertext();
    }
}

void myAES::invert_shiftrows() {
    uchar copys[16] = {};

    //reihe 1   
    copys[0] = klartext[0];
    copys[4] = klartext[4];
    copys[8] = klartext[8];
    copys[12] = klartext[12];

    //reihe 2
    copys[1] = klartext[13];
    copys[13] = klartext[9];
    copys[9] = klartext[5];
    copys[5] = klartext[1];

    // reihe 3   
    copys[6] = klartext[14];
    copys[2] = klartext[10];
    copys[14] = klartext[6];
    copys[10] = klartext[2];

    //reihe 4
    copys[11] = klartext[15];
    copys[7] = klartext[11];
    copys[3] = klartext[7];
    copys[15] = klartext[3];

    //umschreiben   
    for (int i = 0; i < 16; i++) {
        klartext[i] = copys[i];
    }
}// invert_shiftrows

void myAES::invert_mixcolumns() {
    for (int i = 0; i < 4; i++) {
        uchar sj0 = gmul(klartext[i * 4], 14)^gmul(klartext[i * 4 + 1], 11)^gmul(klartext[i * 4 + 2], 13)^gmul(klartext[i * 4 + 3], 9);
        uchar sj1 = gmul(klartext[i * 4], 9)^gmul(klartext[i * 4 + 1], 14)^gmul(klartext[i * 4 + 2], 11)^gmul(klartext[i * 4 + 3], 13);
        uchar sj2 = gmul(klartext[i * 4], 13)^gmul(klartext[i * 4 + 1], 9)^gmul(klartext[i * 4 + 2], 14)^gmul(klartext[i * 4 + 3], 11);
        uchar sj3 = gmul(klartext[i * 4], 11)^gmul(klartext[i * 4 + 1], 13)^gmul(klartext[i * 4 + 2], 9)^gmul(klartext[i * 4 + 3], 14);
        klartext[i * 4] = sj0;
        klartext[i * 4 + 1] = sj1;
        klartext[i * 4 + 2] = sj2;
        klartext[i * 4 + 3] = sj3;
    }
}

uchar myAES::gmul(uchar a, uchar b) {
    unsigned char p = 0;
    unsigned char hi;

    for (int i = 0; i < 8; ++i) {
        if ((b & 1) == 1)
            p ^= a;
        hi = (a & 0x80);
        a <<= 1;
        if (hi == 0x80)
            a ^= 0x1b;
        b >>= 1;
    }
    return p;
}

void myAES::decrypt(bool output) {

    // Parameter
    int iRunde = 10;
    int iLaenge = 16;


    // Überschreibe klartext um diesen fortan zu verwenden
    for (int i = 0; i < 16; i++) {
        klartext[i] = ciphertext[i];
    }


    // Arraygroesse dynamisch bestimmen
    int arrSize = sizeof (klartext) / sizeof (klartext[0]);

    // Zwischenspeicherung der Rundenschluessel
    int iReihe = 4;
    int iSpalte = 4 * (iRunde + 1);
    uchar carrRundenschluessel[4][44];

    // Schluessel expandieren
    schluesselexpansion(carrRundenschluessel, iReihe, iSpalte, iLaenge);

    //printRundenSchluessel(carrRundenschluessel, iReihe, iSpalte);

    // "neue" Vorrunde
    addRoundKey(klartext, arrSize, carrRundenschluessel, iReihe, iSpalte, 10);

    // Durchlaufen der Runden
    for (int i = 9; i > 0; i--) {

        // Shift Rows
        invert_shiftrows();

        // S-Box
        subbytes(sbox_inverse, klartext, arrSize);

        // Rundenschlüssel addieren
        addRoundKey(klartext, arrSize, carrRundenschluessel, iReihe, iSpalte, i);

        // Mix Columns
        if (i != 10) { // kein MixColumns in der letzten Runde
            invert_mixcolumns();
        }
    }


    // Letzte Runde
    invert_shiftrows();
    subbytes(sbox_inverse, klartext, arrSize);

    for (int k = 0; k < iLaenge; k++) {
        klartext[k] = klartext[k] ^ schluessel[k];
    }

    // Ausgabe des Ciphertexts
    if (output) {
        printSchluessel();
        printCiphertext();
        printKlartext();
    }
}// decrypt

void myAES::printSchluessel() {
    cout << endl << "Schluessel:\n";
    for (int i = 0; i < 4; i++)
        cout << hex << "\t0x" << (int) schluessel[0 + i] << "\t0x" << (int) schluessel [4 + i] << "\t0x" << (int) schluessel [8 + i] << "\t0x" << (int) schluessel[12 + i] << endl;
    cout << endl;
}

void myAES::printCiphertext() {
    cout << endl << "Ciphertext:\n";
    for (int i = 0; i < 4; i++)
        cout << hex << "\t0x" << (int) ciphertext[0 + i] << "\t0x" << (int) ciphertext [4 + i] << "\t0x" << (int) ciphertext [8 + i] << "\t0x" << (int) ciphertext[12 + i] << endl;
    cout << endl;
}

void myAES::printKlartext() {
    cout << endl << "Klartext:\n";
    for (int i = 0; i < 4; i++)
        cout << hex << "\t0x" << (int) klartext[0 + i] << "\t0x" << (int) klartext [4 + i] << "\t0x" << (int) klartext [8 + i] << "\t0x" << (int) klartext[12 + i] << endl;
    cout << endl;
}

myAES::myAES() {
    uchar kt[16] = {0x61, 0x62, 0x62, 0x69, 0x6c, 0x64, 0x75, 0x6e, 0x67, 0x73, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78};
    uchar s[16] = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31};
    //uchar c[16] = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31};
    for (int i = 0; i < 16; i++) {
        schluessel[i] = s[i];
        klartext[i] = kt[i];
    }
}

myAES::~myAES() {
}

void myAES::enterKlartext() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    string tmp = "";
    int diff = 0;
    cout << "Klartext (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << RED_start << "\nWerte fuer den Klartext zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << RED_start << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << RED_end << endl;
        }

        if (tmp.length() < 16) {
            cerr << RED_start << "\nWert fuer den Klartext zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << RED_end << endl;
        }

        for (int i = 0; i < 16; i++) {
            klartext[i] = tmp[i];
        }
        cout << endl;

    }
}

void myAES::enterSchluessel() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    string tmp = "";
    int diff = 0;
    cout << "Schluessel (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << RED_start << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << RED_end << endl;
        }

        if (tmp.length() < 16) {
            cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << RED_end << endl;
        }

        for (int i = 0; i < 16; i++) {
            schluessel[i] = tmp[i];
            //cout << hex << tmp[i];
        }
        cout << endl;

    }
}

void myAES::setCiphertext(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        ciphertext[i] = tmp[i];
    }

}

void myAES::setKlartext(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        klartext[i] = tmp[i];
    }
}

void myAES::setSchluessel(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        schluessel[i] = tmp[i];

    }
}

uchar* myAES::getSchluessel() {
    return schluessel;
}

uchar* myAES::getCiphertext() {
    return ciphertext;
}

uchar* myAES::getKlartext() {
    return klartext;
}

myCBC.h


#ifndef MYCBC_H
#define	MYCBC_H
#include "myAES.h"
#include <vector>
class myCBC {
public:
    // Konstruktoren / Destruktoren
    myCBC();
    virtual ~myCBC();
    
    //CBC
    void crypt(bool);
    void decrypt(bool);
    
    // Set/Get-Methoden
    void setKey(uchar[16]);
    void setIV(uchar[16]);
    void setKlartext(vector<uchar>);
    void setCiphertext(vector<uchar>);

    vector<uchar> getKlartext();
    vector<uchar> getCiphertext();
    uchar* getSchluessel();
    uchar* getIV();
    
    // Manuelle Eingabe
    void enterKey();
    void enterIV();
    void enterKlartext();
    
    // Print-Methoden
    void printSchluessel();
    void printCiphertext();
    void printKlartext();
    
private:
    //unsigned int stellen;
    uchar iv[16];
    uchar key[16];
    vector<uchar> klartext;
    vector<uchar> ciphertext;

};

#endif	/* MYCBC_H */

myCBC.cpp


#include "myCBC.h"

void myCBC::enterKey() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    string tmp = "";
    int diff = 0;
    cout << "Schluessel (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << RED_start << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << RED_end << endl;
        }

        if (tmp.length() < 16) {
            cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << RED_end << endl;
        }

        for (int i = 0; i < 16; i++) {
            key[i] = tmp[i];
        }
        cout << endl;

    }
}

void myCBC::enterIV() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    string tmp = "";
    int diff = 0;
    cout << "IV (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << RED_start << "\nWerte fuer den IV zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << RED_start << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << RED_end << endl;
        }

        if (tmp.length() < 16) {
            cerr << RED_start << "\nWert fuer den IV zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << RED_end << endl;
        }

        for (int i = 0; i < 16; i++) {
            iv[i] = tmp[i];
        }
        cout << endl;

    }
}

void myCBC::enterKlartext() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    klartext.clear();
    string tmp = "";
    cout << "Klartext (Beliebig viele Zeichen):";
    if (cin >> tmp) {
        for (int i = 0; i < tmp.size(); i++) {
            klartext.push_back(tmp[i]);
        }
        cout << endl;
    }

    if (tmp.size() % 16 != 0) {
        cerr << RED_start << "\nLetzter Klartext-Block nicht vollstaendig. Fuelle mit Nullen auf.\n";
        for (int i = 0; i < 16 - tmp.size() % 16; i++) {
            klartext.push_back('\0');
        }
        cout << RED_end << endl;
    }
}

myCBC::myCBC() {

    // Default Parameter
    uchar newKey[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar newIV[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    uchar newKlartext[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};

    // Schluessel setzen
    for (int i = 0; i < 16; i++) {
        key[i] = newKey[i];
    }

    //IV setzen
    for (int i = 0; i < 16; i++) {
        iv[i] = newIV[i];
    }

    // Klartext setzen
    for (int i = 0; i < 16; i++) {
        klartext.push_back(newKlartext[i]);
    }
}

void myCBC::printSchluessel() {
    cout << endl << "Schluessel:\n";
    for (int i = 0; i < 4; i++)
        cout << hex << "\t0x" << (int) key[0 + i] << "\t0x" << (int) key [4 + i] << "\t0x" << (int) key [8 + i] << "\t0x" << (int) key[12 + i] << endl;
    cout << endl;
}

void myCBC::printCiphertext() {
    cout << endl << "Ciphertext:\n";
    for (int i = 0; i < ciphertext.size(); i++) {
        cout << std::hex << " 0x" << (int) ciphertext[i];
    }
}

void myCBC::printKlartext() {
    cout << endl << "Klartext:\n";
    for (int i = 0; i < klartext.size(); i++) {
        cout << std::hex << " 0x" << (int) klartext[i];
    }
}

vector<uchar> myCBC::getCiphertext() {
    return ciphertext;
}

void myCBC::decrypt(bool print) {
    klartext.clear();
    uchar tmp_iv[16];
    for (int j = 0; j < 16; j++) {
        tmp_iv[j] = iv[j];
    }
    //printSchluessel();
    //printKlartext();
    //printCiphertext();
    for (int i = 0; i < ciphertext.size() / 16; i++) {

        myAES a1;

        //Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = ciphertext[j + 16 * i];
        }

        // Ciphertext
        a1.setCiphertext(tmp);

        // Schluessel
        a1.setSchluessel(key);

        // crypt
        a1.decrypt(false);

        // Resultat mit IV addieren
        for (int j = 0; j < 16; j++) {

            a1.getKlartext()[j] = a1.getKlartext()[j]^tmp_iv[j];
        }

        for (int j = 0; j < 16; j++) {
            tmp_iv[j] = a1.getCiphertext()[j + 16 * i];
            klartext.push_back(a1.getKlartext()[j]);
        }
    }

    if (print) {
        printSchluessel();
        printCiphertext();
        printKlartext();
    }

}

void myCBC::crypt(bool print) {
    ciphertext.clear();
    uchar tmp_iv[16];
    for (int i = 0; i < 16; i++) {
        tmp_iv[i] = iv[i];
    }

    for (int i = 0; i < klartext.size() / 16; i++) {

        myAES a1;
        a1.setSchluessel(key);

        //XOR in Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = klartext[j + 16 * i]^tmp_iv[j];
        }

        // Klartext
        a1.setKlartext(tmp);

        // crypt
        a1.crypt(false);


        for (int j = 0; j < 16; j++) {
            tmp_iv[j] = a1.getCiphertext()[j];
            ciphertext.push_back(a1.getCiphertext()[j]);
        }
    }

    if (print) {
        printSchluessel();
        printKlartext();
        printCiphertext();
    }
}

void myCBC::setKlartext(vector<uchar> kt) {
    if (kt.size() > klartext.size()) {
        int diff = kt.size() - klartext.size();
        for (int i = 0; i < diff; i++) {
            klartext.push_back(0x00);
        }
    }
    for (int i = 0; i < kt.size(); i++) {
        klartext.at(i) = kt.at(i);
    }
}

void myCBC::setIV(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        iv[i] = tmp[i];
    }
}

void myCBC::setKey(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        key[i] = tmp[i];
    }
}

myCBC::~myCBC() {
}

myECB.h



#ifndef MYECB_H
#define	MYECB_H

#include "myAES.h"
#include <vector>
class myECB {
public:
    // Konstruktoren / Destruktoren
    myECB();
    virtual ~myECB();
    
    //CBC
    void crypt(bool);
    void decrypt(bool);
    
    // Set/Get-Methoden
    void setKey(uchar[16]);
    
    void setKlartext(vector<uchar>);
    void setCiphertext(vector<uchar>);

    vector<uchar> getKlartext();
    vector<uchar> getCiphertext();
    uchar* getSchluessel();
    
    
    // Manuelle Eingabe
    void enterKey();
    
    void enterKlartext();
    
    // Print-Methoden
    void printSchluessel();
    void printCiphertext();
    void printKlartext();
    
private:
    //unsigned int stellen;
    
    uchar key[16];
    vector<uchar> klartext;
    vector<uchar> ciphertext;

};

#endif	/* MYECB_H */

myECB.cpp



#include "myECB.h"

void myECB::enterKey() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    string tmp = "";
    int diff = 0;
    cout << "Schluessel (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << RED_start << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << RED_end << endl;
        }

        if (tmp.length() < 16) {
            cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << RED_end << endl;
        }

        for (int i = 0; i < 16; i++) {
            key[i] = tmp[i];
        }
        cout << endl;

    }
}

void myECB::enterKlartext() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    klartext.clear();
    string tmp = "";
    cout << "Klartext (Beliebig viele Zeichen):";
    if (cin >> tmp) {
        for (int i = 0; i < tmp.size(); i++) {
            klartext.push_back(tmp[i]);
        }
        cout << endl;
    }

    if (tmp.size() % 16 != 0) {
        cerr << RED_start << "\nLetzter Klartext-Block nicht vollstaendig. Fuelle mit Nullen auf.\n";
        for (int i = 0; i < 16 - tmp.size() % 16; i++) {
            klartext.push_back('\0');
        }
        cout << RED_end << endl;
    }
}

myECB::myECB() {

    // Default Parameter
    uchar newKey[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar newIV[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    uchar newKlartext[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};

    // Schluessel setzen
    for (int i = 0; i < 16; i++) {
        key[i] = newKey[i];
    }

    // Klartext setzen
    for (int i = 0; i < 16; i++) {
        klartext.push_back(newKlartext[i]);
    }
}

void myECB::printSchluessel() {
    cout << endl << "Schluessel:\n";
    for (int i = 0; i < 4; i++)
        cout << hex << "\t0x" << (int) key[0 + i] << "\t0x" << (int) key [4 + i] << "\t0x" << (int) key [8 + i] << "\t0x" << (int) key[12 + i] << endl;
    cout << endl;
}

void myECB::printCiphertext() {
    cout << endl << "Ciphertext:\n";
    for (int i = 0; i < ciphertext.size(); i++) {
        cout << std::hex << " 0x" << (int) ciphertext[i];
    }
}

void myECB::printKlartext() {
    cout << endl << "Klartext:\n";
    for (int i = 0; i < klartext.size(); i++) {
        cout << std::hex << " 0x" << (int) klartext[i];
    }
}

vector<uchar> myECB::getCiphertext() {
    return ciphertext;
}

void myECB::decrypt(bool print) {
    klartext.clear();

    for (int i = 0; i < ciphertext.size() / 16; i++) {

        myAES a1;

        //Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = ciphertext[j + 16 * i];
        }

        // Ciphertext
        a1.setCiphertext(tmp);

        // Schluessel
        a1.setSchluessel(key);

        // crypt
        a1.decrypt(false);

        // Resultat mit IV addieren
        for (int j = 0; j < 16; j++) {
            klartext.push_back(a1.getKlartext()[j]);
        }
    }

    if (print) {
        printSchluessel();
        printCiphertext();
        printKlartext();
    }

}

void myECB::crypt(bool print) {
    ciphertext.clear();
    /* uchar tmp_iv[16];
     for (int i = 0; i < 16; i++) {
         tmp_iv[i] = iv[i];
     }*/

    for (int i = 0; i < klartext.size() / 16; i++) {

        myAES a1;
        a1.setSchluessel(key);

        //XOR in Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = klartext[j + 16 * i]; //^tmp_iv[j];
        }

        // Klartext
        a1.setKlartext(tmp);

        // crypt
        a1.crypt(false);


        for (int j = 0; j < 16; j++) {
            //tmp_iv[j] = a1.getCiphertext()[j];
            ciphertext.push_back(a1.getCiphertext()[j]);
        }
    }

    if (print) {
        printSchluessel();
        printKlartext();
        printCiphertext();
    }
}

void myECB::setKlartext(vector<uchar> kt) {
    if (kt.size() > klartext.size()) {
        int diff = kt.size() - klartext.size();
        for (int i = 0; i < diff; i++) {
            klartext.push_back(0x00);
        }
    }
    for (int i = 0; i < kt.size(); i++) {
        klartext.at(i) = kt.at(i);
    }
}

void myECB::setKey(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        key[i] = tmp[i];
    }
}

myECB::~myECB() {
}

Schreiben Sie einen Kommentar

Ihre E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahren Sie, wie Ihre Kommentardaten verarbeitet werden.

'); } cout << RED_end << endl; } for (int i = 0; i < 16; i++) { key[i] = tmp[i]; } cout << endl; } } void myECB::enterKlartext() { string RED_start = "3[22;31m"; string RED_end = "3[0m"; klartext.clear(); string tmp = ""; cout << "Klartext (Beliebig viele Zeichen):"; if (cin >> tmp) { for (int i = 0; i < tmp.size(); i++) { klartext.push_back(tmp[i]); } cout << endl; } if (tmp.size() % 16 != 0) { cerr << RED_start << "\nLetzter Klartext-Block nicht vollstaendig. Fuelle mit Nullen auf.\n"; for (int i = 0; i < 16 - tmp.size() % 16; i++) { klartext.push_back('
Menu Close

Kryptologie (Praktikum 3)

Skript-AnfangKryptouebung2 – Seite 1
Skript-EndeKryptouebung2 – Seite 1

main.cpp


// Präprozessor-Direktiven
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include "myGUI.h"

// Using-Deklarationen
using namespace std;

int main(int argc, char** argv) {
    myGUI gui;
}// main

myGUI.h


#ifndef MYGUI_H
#define	MYGUI_H

#include <iostream>
#include "myCBC.h"
#include "myECB.h"

class myGUI {
public:
    myGUI();
    void callAES();
    void callCBC();
    void callECB();
    bool checkAES();
    bool checkCBC();
    bool checkECB();
    int validatedInput(unsigned int, unsigned int);
    virtual ~myGUI();
private:
};

#endif	/* MYGUI_H */

myGUI.cpp


#include "myGUI.h"
#include <vector>

using namespace std;

bool areEqual(vector<uchar> v1, vector<uchar> v2) {
    bool tmp = false;
    if (v1.size() == v2.size()) {
        for (int i = 0; i < v1.size(); i++) {
            if (v1[i] == v2[i]) {
                tmp = true;
            } else {
                cout << hex << v1[i] << "!=" << v2[i] << endl;
                tmp = false;
                break;
            }
        }
    }
    return tmp;
}

bool areEqual(uchar* arr1, uchar* arr2) {
    bool tmp = false;
    for (int i = 0; i < 16; i++) {
        if (arr1[i] == arr2[i]) {
            tmp = true;
        } else {
            cout << hex << arr1[i] << "!=" << arr2[i] << endl;
            tmp = false;
            break;
        }
    }
    return tmp;
}

bool myGUI::checkCBC() {
    bool returnValue = false;

    //16 Byte Testvektoren
    uchar keyB[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar ivB[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    uchar klartextB1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar ciphertextB1[16] = {0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d};
    vector<uchar> cipherB1;
    vector<uchar> ktB;

    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartextB1[i]);
        cipherB1.push_back(ciphertextB1[i]);
    }

    myCBC cbcB;
    cbcB.setKey(keyB);
    cbcB.setIV(ivB);
    cbcB.setKlartext(ktB);
    cbcB.crypt(false);

    // 32 Byte Testvektoren

    uchar klartextA1[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
    uchar klartextA2[16] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};
    uchar ivA[16] = {0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28, 0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58};
    uchar keyA[16] = {0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0, 0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a};
    uchar ciphertextA1[16] = {0xd2, 0x96, 0xcd, 0x94, 0xc2, 0xcc, 0xcf, 0x8a, 0x3a, 0x86, 0x30, 0x28, 0xb5, 0xe1, 0xdc, 0x0a};
    uchar ciphertextA2[16] = {0x75, 0x86, 0x60, 0x2d, 0x25, 0x3c, 0xff, 0xf9, 0x1b, 0x82, 0x66, 0xbe, 0xa6, 0xd6, 0x1a, 0xb1};
    vector<uchar> cipherA1;

    vector<uchar> test;

    for (int i = 0; i < 16; i++) {
        test.push_back(klartextA1[i]);
        cipherA1.push_back(ciphertextA1[i]);
    }

    for (int i = 0; i < 16; i++) {
        test.push_back(klartextA2[i]);
        cipherA1.push_back(ciphertextA2[i]);
    }

    myCBC cbcA;
    cbcA.setKey(keyA);
    cbcA.setIV(ivA);
    cbcA.setKlartext(test);
    cbcA.crypt(false);

    //Prüfung
    bool isWorking = areEqual(cbcA.getCiphertext(), cipherA1) && areEqual(cbcB.getCiphertext(), cipherB1);

    if (isWorking) {
        returnValue = true;
    } else {
        returnValue = false;
    }
    return returnValue;
}

bool myGUI::checkECB() {
    bool returnValue = false;

    //16 Byte Testvektoren
    uchar schluessel[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};

    uchar klartext_1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar klartext_2[16] = {0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
    uchar klartext_3[16] = {0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef};

    uchar cipher_1[16] = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97};
    uchar cipher_2[16] = {0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d, 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf};
    uchar cipher_3[16] = {0x43, 0xb1, 0xcd, 0x7f, 0x59, 0x8e, 0xce, 0x23, 0x88, 0x1b, 0x00, 0xe3, 0xed, 0x03, 0x06, 0x88};
    vector<uchar> cipherB1;
    vector<uchar> ktB;

    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_1[i]);
        cipherB1.push_back(cipher_1[i]);
    }

    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_2[i]);
        cipherB1.push_back(cipher_2[i]);
    }

    for (int i = 0; i < 16; i++) {
        ktB.push_back(klartext_3[i]);
        cipherB1.push_back(cipher_3[i]);
    }

    myECB ecb;
    ecb.setKey(schluessel);
    ecb.setKlartext(ktB);
    ecb.crypt(false);

    //Prüfung
    bool isWorking = areEqual(ecb.getCiphertext(), cipherB1);

    if (isWorking) {
        returnValue = true;
    } else {
        returnValue = false;
    }
    return returnValue;
}

bool myGUI::checkAES() {

    bool returnValue = false;
    uchar schluessel[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};

    uchar klartext_1[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    uchar klartext_2[16] = {0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
    uchar klartext_3[16] = {0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef};

    uchar cipher_1[16] = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97};
    uchar cipher_2[16] = {0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d, 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf};
    uchar cipher_3[16] = {0x43, 0xb1, 0xcd, 0x7f, 0x59, 0x8e, 0xce, 0x23, 0x88, 0x1b, 0x00, 0xe3, 0xed, 0x03, 0x06, 0x88};

    myAES aes1;
    aes1.setKlartext(klartext_1);
    aes1.setSchluessel(schluessel);
    aes1.crypt(false);

    myAES aes2;
    aes2.setKlartext(klartext_2);
    aes2.setSchluessel(schluessel);
    aes2.crypt(false);

    myAES aes3;
    aes3.setKlartext(klartext_3);
    aes3.setSchluessel(schluessel);
    aes3.crypt(false);

    bool isWorking = areEqual(aes3.getCiphertext(), cipher_3) && areEqual(aes2.getCiphertext(), cipher_2) && areEqual(aes1.getCiphertext(), cipher_1);
    if (isWorking) {
        returnValue = true;
    } else {

        returnValue = false;
    }
    return returnValue;
}

void myGUI::callAES() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    myAES aes;
    aes.crypt(false);
    //myAES aesDecrypt;
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 5;
    int input = end;

    //Menu Eingabe
    while (run) {
        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Text und Schluessel aus Datei laden\n";
        cout << "(4) Entschluesseln \n";
        cout << "(5) Zurueck\n";
        cout << "> ";
        input = validatedInput(lowest, end);
        if (input == 1) {
            aes.crypt(true);
        }
        if (input == 2) {
            aes.enterKlartext();
            aes.enterSchluessel();
            aes.crypt(true);
        }
        if (input == 3) {
            cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
        }
        if (input == 4) {
            aes.decrypt(true);
        }
        if (input == 5) {
            run = false;
        }
        if (input == -1) {

            cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
            cout << endl;
        }
    }
}

void myGUI::callCBC() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    myCBC cbc;
    cbc.crypt(true);
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 5;
    int input = end;

    //Menu Eingabe
    while (run) {

        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Text und Schluessel aus Datei laden\n";
        cout << "(4) Text entschluesseln\n";
        cout << "(5) Zurueck\n";
        cout << "> ";
        input = validatedInput(lowest, end);
        if (input == 1) {
            cbc.crypt(true);
        }
        if (input == 2) {
            cbc.enterIV();
            cbc.enterKey();
            cbc.enterKlartext();
            cbc.crypt(true);
        }
        if (input == 3) {
            cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
        }
        if (input == 4) {
            cbc.decrypt(true);
        }
        if (input == 5) {
            run = false;
        }
        if (input == -1) {
            cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
            cout << endl;
        }
    }

}

void myGUI::callECB() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    myECB ecb;
    ecb.crypt(false);
    bool run = true;
    unsigned int lowest = 1;
    unsigned int end = 5;
    int input = end;

    //Menu Eingabe
    while (run) {

        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) Text verschluesseln \n";
        cout << "(2) Text und Schluessel eingeben \n";
        cout << "(3) Text und Schluessel aus Datei laden\n";
        cout << "(4) Text entschluesseln\n";
        cout << "(5) Zurueck\n";
        cout << "> ";
        input = validatedInput(lowest, end);
        if (input == 1) {
            ecb.crypt(true);
        }
        if (input == 2) {
            ecb.enterKey();
            ecb.enterKlartext();
            ecb.crypt(true);
        }
        if (input == 3) {
            cerr << RED_start << "Noch nicht implementiert\n" << RED_end;
        }
        if (input == 4) {
                ecb.decrypt(true);
        }
        if (input == 5) {
            run = false;
        }
        if (input == -1) {
            cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
            cout << endl;
        }
    }

}

int myGUI::validatedInput(unsigned int lowest, unsigned int highest) {
    int tmp = 0;
    cin.clear();
    if (cin >> tmp) {//Eingabe ist in Ordnung
        cout << endl;
        if (tmp >= lowest && tmp <= highest) {//Eingabe liegt in den Parametern

            return tmp;
        }
    } else {
        string trash = "";
        cin.clear();
        std::getline(std::cin, trash);
    }
    return -1;
}

myGUI::myGUI() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    //Menu-Variablen

    unsigned int lowest = 1;
    unsigned int end = 4;
    int input = end;
    bool run = true;

    //Start
    cout << "#### Kryptographie Sommersemester 2013 ####\n";
    cout << "Nils Rogmann (725915) und Maximilian Krieg (725922)\n";

    // Begrüßung und Information
    cout << "\nHerzlich willkommen.\n";
    cout << "Das Programm wird nun mit Hilfe von Testvektoren geprüft.\n";

    // AES Check
    cout << "\nAES:\t\t";
    if (checkAES()) {
        cout << GREEN_start << "OK" << GREEN_end;
    } else {
        cerr << RED_start << "Fehler" << RED_end;
    }

    // CBC Check
    cout << "\nAES mit CBC:\t";
    if (checkCBC()) {
        cout << GREEN_start << "OK" << GREEN_end;
    } else {
        cerr << RED_start << "Fehler" << RED_end;
    }


    // ECB Check
    cout << "\nAES mit ECB:\t";
    if (checkECB()) 
    {
        cout << GREEN_start << "OK" << GREEN_end;
    }
    else
    {
        cerr << RED_start << "Fehler" << RED_end;
    }
    cout << endl;

    //Menu Eingabe
    while (run) {
        cout << "\nBitte waehlen sie aus:\n";
        cout << "(1) AES\n";
        cout << "(2) AES mit CBC\n";
        cout << "(3) AES mit ECB\n";
        cout << "(4) Programm beenden\n";
        cout << "> ";

        input = validatedInput(lowest, end);

        // Aufrufe
        if (input == 1) {
            cout << GREEN_start << "#### AES ####\n" << GREEN_end;
            callAES();
            cout << endl;
        }

        if (input == 2) {
            cout << GREEN_start << "#### AES mit CBC ####\n" << GREEN_end;
            callCBC();
            cout << endl;
        }


        if (input == 3) {
            cout << GREEN_start << "#### AES mit ECB ####\n" << GREEN_end;
            callECB();
            cout << endl;
        }

        // Fehler
        if (input == -1) {
            cerr << RED_start << "Ungueltige Eingabe getätigt.\nBitte nochmal eingeben.\n" << RED_end;
            cout << endl;
        }

        // Beenden
        if (input == end) {

            cout << "Programm wird beendet.\n";
            run = false;
            cout << endl;
        }
    }
}

myGUI::~myGUI() {
}

myAES.h


#ifndef MYAES_H
#define	MYAES_H

#include <iostream>

using namespace std;
// Typedefs
typedef unsigned char uchar;

class myAES {
public:
    // Konstruktoren/Destruktoren
    myAES();
    virtual ~myAES();

    // Manuelle Eingabe
    void enterKlartext();
    void enterSchluessel();

    // Set/Get-Methoden
    void setKlartext(uchar[16]);
    void setSchluessel(uchar[16]);
    void setCiphertext(uchar[16]);
    uchar* getKlartext();
    uchar* getSchluessel();
    uchar* getCiphertext();

    // AES-Methoden
    void crypt(bool);
    void mixcolumns();
    void shiftrows();
    void schluesselexpansion(uchar[][44], int, int, int);
    void rotword(uchar[], int);
    uchar mix(uchar, unsigned int);
    void subbytes(uchar [], uchar [], int);

    // Print-Methoden
    void printSchluessel();
    void printCiphertext();
    void printKlartext();
    
   void decrypt(bool) ;
   uchar gmul(uchar, uchar);
   void invert_mixcolumns();
   void invert_shiftrows();

private:
    uchar klartext[16];
    uchar schluessel[16];
    uchar ciphertext[16];
};



#endif	/* MYAES_H */

myAES.cpp


#include "myAES.h"

using namespace std;

unsigned char Sbox[256] = {//  s-box
    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, 0x9c, 0xa4, 0x72, 0xc0,
    0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
    0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
    0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
    0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
    0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
    0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
    0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
    0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
    0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
    0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
    0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
    0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
    0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
    0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
};

unsigned char sbox_inverse[256] = {
    0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
    0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
    0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
    0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
    0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
    0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
    0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
    0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
    0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
    0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
    0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
    0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
    0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
    0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
    0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
    0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
};

unsigned char Rcon[256] = {
    0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
    0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,
    0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,
    0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
    0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,
    0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,
    0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b,
    0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
    0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
    0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
    0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
    0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
    0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
    0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,
    0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,
    0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d
};

void myAES::subbytes(uchar sbox[], uchar tmp[], int arrSize) {
    for (int i = 0; i < arrSize; i++) {
        tmp[i] = sbox[tmp[i]];
    }
}// subbytes

uchar myAES::mix(uchar byte, unsigned int mixvalue) {
    unsigned char retValue;
    switch (mixvalue) {
        case 1:
            retValue = byte;
            break;
        case 2:
            retValue = byte << 1;
            if (byte & 0x80) {
                retValue = retValue ^ 0x1b;
            }
            break;
        case 3:
            retValue = byte << 1;
            if (byte & 0x80) {
                retValue = retValue ^ 0x1b;
            }
            retValue = retValue^byte;
            break;
    }
    return retValue;
}

void addRoundKey(uchar klartext[], int iLaenge, uchar matrix[][44], int iReihe, int iSpalte, int iRunde) {
    int pos = 0;
    for (int i = iRunde * 4; i < ((iRunde * 4) + 4) && i < iSpalte; i++) {
        for (int k = 0; k < iReihe; k++) {
            klartext[pos] = klartext[pos] ^ matrix[k][i];
            pos++;
        }
    }
}// addroundkey

void myAES::rotword(uchar column[], int iReihe) {
    uchar tmp = column[0];
    for (int i = 1; i < iReihe; i++) {
        column[i - 1] = column[i];
    }
    column[iReihe - 1] = tmp;
} // rotword

void myAES::schluesselexpansion(uchar matrix[][44], int iReihe, int iSpalte, int iLaenge) {
    // Alle Spalten durchlaufen
    int pos = 0;

    for (int i = 0; i < iSpalte; i++) {
        if (i < 4) { // Schluessel in erste vier Spalten kopieren
            for (int k = 0; k < iReihe && pos < iLaenge; k++) {
                matrix[k][i] = schluessel[pos];
                pos++;
                //cout << hex << "matrix[" << k << "][" << i << "] = " << (int) matrix[k][i] << endl;
            }
        } else { // i > 4
            if (i % 4 == 0) {// erste Spalte eines Schluessels
                // Spalte in Hilfsarray kopieren
                uchar tmp[iReihe]; // i-1
                uchar tmp2[iReihe]; // i-4
                for (int k = 0; k < iReihe; k++) {
                    tmp[k] = matrix[k][i - 1];
                    tmp2[k] = matrix[k][i - 4];
                }

                rotword(tmp, iReihe);

                subbytes(Sbox, tmp, iReihe);

                // Spalte[i-4] XOR subbytes[rotword[i-i]
                for (int k = 0; k < iReihe; k++) {
                    tmp[k] = tmp[k] ^ tmp2[k];
                }

                // tmp[0] XOR (i/4)
                tmp[0] = tmp[0] ^ Rcon[i / iReihe];

                // tmp[k] an Spalte[k][i] kopieren
                for (int k = 0; k < iReihe; k++) {
                    matrix[k][i] = tmp[k];
                }

            } else {
                //cout << "i " << i << endl;
                for (int k = 0; k < iReihe; k++) {
                    matrix[k][i] = matrix[k][i - 4] ^ matrix[k][i - 1];
                }
            }
        }
    }
}// schluesselexpansion

void myAES::shiftrows() {
    uchar copys[16] = {};

    //reihe 1   
    copys[0] = ciphertext[0];
    copys[4] = ciphertext[4];
    copys[8] = ciphertext[8];
    copys[12] = ciphertext[12];

    //reihe 2
    copys[1] = ciphertext[5];
    copys[5] = ciphertext[9];
    copys[9] = ciphertext[13];
    copys[13] = ciphertext[1];

    // reihe 3
    copys[2] = ciphertext[10];
    copys[6] = ciphertext[14];
    copys[10] = ciphertext[2];
    copys[14] = ciphertext[6];

    //reihe 4
    copys[3] = ciphertext[15];
    copys[7] = ciphertext[3];
    copys[11] = ciphertext[7];
    copys[15] = ciphertext[11];

    //umschreiben   
    for (int i = 0; i < 16; i++) {
        ciphertext[i] = copys[i];
    }
}// shiftrows

void myAES::mixcolumns() {
    for (int i = 0; i < 4; i++) {
        uchar sj0 = mix(ciphertext[i * 4], 2)^mix(ciphertext[i * 4 + 1], 3)^mix(ciphertext[i * 4 + 2], 1)^mix(ciphertext[i * 4 + 3], 1);
        uchar sj1 = mix(ciphertext[i * 4], 1)^mix(ciphertext[i * 4 + 1], 2)^mix(ciphertext[i * 4 + 2], 3)^mix(ciphertext[i * 4 + 3], 1);
        uchar sj2 = mix(ciphertext[i * 4], 1)^mix(ciphertext[i * 4 + 1], 1)^mix(ciphertext[i * 4 + 2], 2)^mix(ciphertext[i * 4 + 3], 3);
        uchar sj3 = mix(ciphertext[i * 4], 3)^mix(ciphertext[i * 4 + 1], 1)^mix(ciphertext[i * 4 + 2], 1)^mix(ciphertext[i * 4 + 3], 2);
        ciphertext[i * 4] = sj0;
        ciphertext[i * 4 + 1] = sj1;
        ciphertext[i * 4 + 2] = sj2;
        ciphertext[i * 4 + 3] = sj3;
    }
}// mixcolumns

void myAES::crypt(bool output) {

    // Parameter
    int iRunde = 10;
    int iLaenge = 16;

    // Überschreibe ciphertext um diesen fortan zu verwenden
    for (int i = 0; i < 16; i++) {
        ciphertext[i] = klartext[i];
    }

    // Arraygroesse dynamisch bestimmen
    int arrSize = sizeof (ciphertext) / sizeof (ciphertext[0]);

    // Zwischenspeicherung der Rundenschluessel
    int iReihe = 4;
    int iSpalte = 4 * (iRunde + 1);
    uchar carrRundenschluessel[4][44];

    // Schluessel expandieren
    schluesselexpansion(carrRundenschluessel, iReihe, iSpalte, iLaenge);

    // Vorrunde
    for (int k = 0; k < iLaenge; k++) {
        ciphertext[k] = ciphertext[k] ^ schluessel[k];
    }

    // Durchlaufen der Runden
    for (int i = 1; i < iRunde + 1; i++) {

        // S-Box
        subbytes(Sbox, ciphertext, arrSize);

        // Shift Rows
        shiftrows();

        // Mix Columns
        if (i != (iRunde)) { // kein MixColumns in der letzten Runde
            mixcolumns();
        }

        // Rundenschlüssel addieren
        addRoundKey(ciphertext, arrSize, carrRundenschluessel, iReihe, iSpalte, i);

    }

    // Ausgabe des Ciphertexts
    if (output) {
        printSchluessel();
        printKlartext();
        printCiphertext();
    }
}

void myAES::invert_shiftrows() {
    uchar copys[16] = {};

    //reihe 1   
    copys[0] = klartext[0];
    copys[4] = klartext[4];
    copys[8] = klartext[8];
    copys[12] = klartext[12];

    //reihe 2
    copys[1] = klartext[13];
    copys[13] = klartext[9];
    copys[9] = klartext[5];
    copys[5] = klartext[1];

    // reihe 3   
    copys[6] = klartext[14];
    copys[2] = klartext[10];
    copys[14] = klartext[6];
    copys[10] = klartext[2];

    //reihe 4
    copys[11] = klartext[15];
    copys[7] = klartext[11];
    copys[3] = klartext[7];
    copys[15] = klartext[3];

    //umschreiben   
    for (int i = 0; i < 16; i++) {
        klartext[i] = copys[i];
    }
}// invert_shiftrows

void myAES::invert_mixcolumns() {
    for (int i = 0; i < 4; i++) {
        uchar sj0 = gmul(klartext[i * 4], 14)^gmul(klartext[i * 4 + 1], 11)^gmul(klartext[i * 4 + 2], 13)^gmul(klartext[i * 4 + 3], 9);
        uchar sj1 = gmul(klartext[i * 4], 9)^gmul(klartext[i * 4 + 1], 14)^gmul(klartext[i * 4 + 2], 11)^gmul(klartext[i * 4 + 3], 13);
        uchar sj2 = gmul(klartext[i * 4], 13)^gmul(klartext[i * 4 + 1], 9)^gmul(klartext[i * 4 + 2], 14)^gmul(klartext[i * 4 + 3], 11);
        uchar sj3 = gmul(klartext[i * 4], 11)^gmul(klartext[i * 4 + 1], 13)^gmul(klartext[i * 4 + 2], 9)^gmul(klartext[i * 4 + 3], 14);
        klartext[i * 4] = sj0;
        klartext[i * 4 + 1] = sj1;
        klartext[i * 4 + 2] = sj2;
        klartext[i * 4 + 3] = sj3;
    }
}

uchar myAES::gmul(uchar a, uchar b) {
    unsigned char p = 0;
    unsigned char hi;

    for (int i = 0; i < 8; ++i) {
        if ((b & 1) == 1)
            p ^= a;
        hi = (a & 0x80);
        a <<= 1;
        if (hi == 0x80)
            a ^= 0x1b;
        b >>= 1;
    }
    return p;
}

void myAES::decrypt(bool output) {

    // Parameter
    int iRunde = 10;
    int iLaenge = 16;


    // Überschreibe klartext um diesen fortan zu verwenden
    for (int i = 0; i < 16; i++) {
        klartext[i] = ciphertext[i];
    }


    // Arraygroesse dynamisch bestimmen
    int arrSize = sizeof (klartext) / sizeof (klartext[0]);

    // Zwischenspeicherung der Rundenschluessel
    int iReihe = 4;
    int iSpalte = 4 * (iRunde + 1);
    uchar carrRundenschluessel[4][44];

    // Schluessel expandieren
    schluesselexpansion(carrRundenschluessel, iReihe, iSpalte, iLaenge);

    //printRundenSchluessel(carrRundenschluessel, iReihe, iSpalte);

    // "neue" Vorrunde
    addRoundKey(klartext, arrSize, carrRundenschluessel, iReihe, iSpalte, 10);

    // Durchlaufen der Runden
    for (int i = 9; i > 0; i--) {

        // Shift Rows
        invert_shiftrows();

        // S-Box
        subbytes(sbox_inverse, klartext, arrSize);

        // Rundenschlüssel addieren
        addRoundKey(klartext, arrSize, carrRundenschluessel, iReihe, iSpalte, i);

        // Mix Columns
        if (i != 10) { // kein MixColumns in der letzten Runde
            invert_mixcolumns();
        }
    }


    // Letzte Runde
    invert_shiftrows();
    subbytes(sbox_inverse, klartext, arrSize);

    for (int k = 0; k < iLaenge; k++) {
        klartext[k] = klartext[k] ^ schluessel[k];
    }

    // Ausgabe des Ciphertexts
    if (output) {
        printSchluessel();
        printCiphertext();
        printKlartext();
    }
}// decrypt

void myAES::printSchluessel() {
    cout << endl << "Schluessel:\n";
    for (int i = 0; i < 4; i++)
        cout << hex << "\t0x" << (int) schluessel[0 + i] << "\t0x" << (int) schluessel [4 + i] << "\t0x" << (int) schluessel [8 + i] << "\t0x" << (int) schluessel[12 + i] << endl;
    cout << endl;
}

void myAES::printCiphertext() {
    cout << endl << "Ciphertext:\n";
    for (int i = 0; i < 4; i++)
        cout << hex << "\t0x" << (int) ciphertext[0 + i] << "\t0x" << (int) ciphertext [4 + i] << "\t0x" << (int) ciphertext [8 + i] << "\t0x" << (int) ciphertext[12 + i] << endl;
    cout << endl;
}

void myAES::printKlartext() {
    cout << endl << "Klartext:\n";
    for (int i = 0; i < 4; i++)
        cout << hex << "\t0x" << (int) klartext[0 + i] << "\t0x" << (int) klartext [4 + i] << "\t0x" << (int) klartext [8 + i] << "\t0x" << (int) klartext[12 + i] << endl;
    cout << endl;
}

myAES::myAES() {
    uchar kt[16] = {0x61, 0x62, 0x62, 0x69, 0x6c, 0x64, 0x75, 0x6e, 0x67, 0x73, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78};
    uchar s[16] = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31};
    //uchar c[16] = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31};
    for (int i = 0; i < 16; i++) {
        schluessel[i] = s[i];
        klartext[i] = kt[i];
    }
}

myAES::~myAES() {
}

void myAES::enterKlartext() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    string tmp = "";
    int diff = 0;
    cout << "Klartext (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << RED_start << "\nWerte fuer den Klartext zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << RED_start << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << RED_end << endl;
        }

        if (tmp.length() < 16) {
            cerr << RED_start << "\nWert fuer den Klartext zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << RED_end << endl;
        }

        for (int i = 0; i < 16; i++) {
            klartext[i] = tmp[i];
        }
        cout << endl;

    }
}

void myAES::enterSchluessel() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    string tmp = "";
    int diff = 0;
    cout << "Schluessel (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << RED_start << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << RED_end << endl;
        }

        if (tmp.length() < 16) {
            cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << RED_end << endl;
        }

        for (int i = 0; i < 16; i++) {
            schluessel[i] = tmp[i];
            //cout << hex << tmp[i];
        }
        cout << endl;

    }
}

void myAES::setCiphertext(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        ciphertext[i] = tmp[i];
    }

}

void myAES::setKlartext(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        klartext[i] = tmp[i];
    }
}

void myAES::setSchluessel(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        schluessel[i] = tmp[i];

    }
}

uchar* myAES::getSchluessel() {
    return schluessel;
}

uchar* myAES::getCiphertext() {
    return ciphertext;
}

uchar* myAES::getKlartext() {
    return klartext;
}

myCBC.h


#ifndef MYCBC_H
#define	MYCBC_H
#include "myAES.h"
#include <vector>
class myCBC {
public:
    // Konstruktoren / Destruktoren
    myCBC();
    virtual ~myCBC();
    
    //CBC
    void crypt(bool);
    void decrypt(bool);
    
    // Set/Get-Methoden
    void setKey(uchar[16]);
    void setIV(uchar[16]);
    void setKlartext(vector<uchar>);
    void setCiphertext(vector<uchar>);

    vector<uchar> getKlartext();
    vector<uchar> getCiphertext();
    uchar* getSchluessel();
    uchar* getIV();
    
    // Manuelle Eingabe
    void enterKey();
    void enterIV();
    void enterKlartext();
    
    // Print-Methoden
    void printSchluessel();
    void printCiphertext();
    void printKlartext();
    
private:
    //unsigned int stellen;
    uchar iv[16];
    uchar key[16];
    vector<uchar> klartext;
    vector<uchar> ciphertext;

};

#endif	/* MYCBC_H */

myCBC.cpp


#include "myCBC.h"

void myCBC::enterKey() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    string tmp = "";
    int diff = 0;
    cout << "Schluessel (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << RED_start << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << RED_end << endl;
        }

        if (tmp.length() < 16) {
            cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << RED_end << endl;
        }

        for (int i = 0; i < 16; i++) {
            key[i] = tmp[i];
        }
        cout << endl;

    }
}

void myCBC::enterIV() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    string tmp = "";
    int diff = 0;
    cout << "IV (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << RED_start << "\nWerte fuer den IV zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << RED_start << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << RED_end << endl;
        }

        if (tmp.length() < 16) {
            cerr << RED_start << "\nWert fuer den IV zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << RED_end << endl;
        }

        for (int i = 0; i < 16; i++) {
            iv[i] = tmp[i];
        }
        cout << endl;

    }
}

void myCBC::enterKlartext() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    klartext.clear();
    string tmp = "";
    cout << "Klartext (Beliebig viele Zeichen):";
    if (cin >> tmp) {
        for (int i = 0; i < tmp.size(); i++) {
            klartext.push_back(tmp[i]);
        }
        cout << endl;
    }

    if (tmp.size() % 16 != 0) {
        cerr << RED_start << "\nLetzter Klartext-Block nicht vollstaendig. Fuelle mit Nullen auf.\n";
        for (int i = 0; i < 16 - tmp.size() % 16; i++) {
            klartext.push_back('\0');
        }
        cout << RED_end << endl;
    }
}

myCBC::myCBC() {

    // Default Parameter
    uchar newKey[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar newIV[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    uchar newKlartext[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};

    // Schluessel setzen
    for (int i = 0; i < 16; i++) {
        key[i] = newKey[i];
    }

    //IV setzen
    for (int i = 0; i < 16; i++) {
        iv[i] = newIV[i];
    }

    // Klartext setzen
    for (int i = 0; i < 16; i++) {
        klartext.push_back(newKlartext[i]);
    }
}

void myCBC::printSchluessel() {
    cout << endl << "Schluessel:\n";
    for (int i = 0; i < 4; i++)
        cout << hex << "\t0x" << (int) key[0 + i] << "\t0x" << (int) key [4 + i] << "\t0x" << (int) key [8 + i] << "\t0x" << (int) key[12 + i] << endl;
    cout << endl;
}

void myCBC::printCiphertext() {
    cout << endl << "Ciphertext:\n";
    for (int i = 0; i < ciphertext.size(); i++) {
        cout << std::hex << " 0x" << (int) ciphertext[i];
    }
}

void myCBC::printKlartext() {
    cout << endl << "Klartext:\n";
    for (int i = 0; i < klartext.size(); i++) {
        cout << std::hex << " 0x" << (int) klartext[i];
    }
}

vector<uchar> myCBC::getCiphertext() {
    return ciphertext;
}

void myCBC::decrypt(bool print) {
    klartext.clear();
    uchar tmp_iv[16];
    for (int j = 0; j < 16; j++) {
        tmp_iv[j] = iv[j];
    }
    //printSchluessel();
    //printKlartext();
    //printCiphertext();
    for (int i = 0; i < ciphertext.size() / 16; i++) {

        myAES a1;

        //Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = ciphertext[j + 16 * i];
        }

        // Ciphertext
        a1.setCiphertext(tmp);

        // Schluessel
        a1.setSchluessel(key);

        // crypt
        a1.decrypt(false);

        // Resultat mit IV addieren
        for (int j = 0; j < 16; j++) {

            a1.getKlartext()[j] = a1.getKlartext()[j]^tmp_iv[j];
        }

        for (int j = 0; j < 16; j++) {
            tmp_iv[j] = a1.getCiphertext()[j + 16 * i];
            klartext.push_back(a1.getKlartext()[j]);
        }
    }

    if (print) {
        printSchluessel();
        printCiphertext();
        printKlartext();
    }

}

void myCBC::crypt(bool print) {
    ciphertext.clear();
    uchar tmp_iv[16];
    for (int i = 0; i < 16; i++) {
        tmp_iv[i] = iv[i];
    }

    for (int i = 0; i < klartext.size() / 16; i++) {

        myAES a1;
        a1.setSchluessel(key);

        //XOR in Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = klartext[j + 16 * i]^tmp_iv[j];
        }

        // Klartext
        a1.setKlartext(tmp);

        // crypt
        a1.crypt(false);


        for (int j = 0; j < 16; j++) {
            tmp_iv[j] = a1.getCiphertext()[j];
            ciphertext.push_back(a1.getCiphertext()[j]);
        }
    }

    if (print) {
        printSchluessel();
        printKlartext();
        printCiphertext();
    }
}

void myCBC::setKlartext(vector<uchar> kt) {
    if (kt.size() > klartext.size()) {
        int diff = kt.size() - klartext.size();
        for (int i = 0; i < diff; i++) {
            klartext.push_back(0x00);
        }
    }
    for (int i = 0; i < kt.size(); i++) {
        klartext.at(i) = kt.at(i);
    }
}

void myCBC::setIV(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        iv[i] = tmp[i];
    }
}

void myCBC::setKey(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        key[i] = tmp[i];
    }
}

myCBC::~myCBC() {
}

myECB.h



#ifndef MYECB_H
#define	MYECB_H

#include "myAES.h"
#include <vector>
class myECB {
public:
    // Konstruktoren / Destruktoren
    myECB();
    virtual ~myECB();
    
    //CBC
    void crypt(bool);
    void decrypt(bool);
    
    // Set/Get-Methoden
    void setKey(uchar[16]);
    
    void setKlartext(vector<uchar>);
    void setCiphertext(vector<uchar>);

    vector<uchar> getKlartext();
    vector<uchar> getCiphertext();
    uchar* getSchluessel();
    
    
    // Manuelle Eingabe
    void enterKey();
    
    void enterKlartext();
    
    // Print-Methoden
    void printSchluessel();
    void printCiphertext();
    void printKlartext();
    
private:
    //unsigned int stellen;
    
    uchar key[16];
    vector<uchar> klartext;
    vector<uchar> ciphertext;

};

#endif	/* MYECB_H */

myECB.cpp



#include "myECB.h"

void myECB::enterKey() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    string GREEN_start = "\033[22;32m";
    string GREEN_end = "\033[0m";
    string tmp = "";
    int diff = 0;
    cout << "Schluessel (16 Zeichen):";
    if (cin >> tmp) {

        if (tmp.length() > 16) {
            cerr << RED_start << "\nWerte fuer den Schluessel zu groß. Trenne nach 16 Zeichen ab.\n(" << GREEN_start;
            for (int i = 0; i < tmp.length(); i++) {
                if (i == 16) {
                    cerr << RED_start << " | ";
                }
                cerr << tmp.at(i);
            }
            cout << ")" << RED_end << endl;
        }

        if (tmp.length() < 16) {
            cerr << RED_start << "\nWert fuer den Schluessel zu klein. Fuelle mit Nullen auf.\n";
            diff = 16 - tmp.length();
            for (int i = 0; i < diff; i++) {
                tmp.push_back('\0');
            }
            cout << RED_end << endl;
        }

        for (int i = 0; i < 16; i++) {
            key[i] = tmp[i];
        }
        cout << endl;

    }
}

void myECB::enterKlartext() {
    string RED_start = "\033[22;31m";
    string RED_end = "\033[0m";
    klartext.clear();
    string tmp = "";
    cout << "Klartext (Beliebig viele Zeichen):";
    if (cin >> tmp) {
        for (int i = 0; i < tmp.size(); i++) {
            klartext.push_back(tmp[i]);
        }
        cout << endl;
    }

    if (tmp.size() % 16 != 0) {
        cerr << RED_start << "\nLetzter Klartext-Block nicht vollstaendig. Fuelle mit Nullen auf.\n";
        for (int i = 0; i < 16 - tmp.size() % 16; i++) {
            klartext.push_back('\0');
        }
        cout << RED_end << endl;
    }
}

myECB::myECB() {

    // Default Parameter
    uchar newKey[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    uchar newIV[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    uchar newKlartext[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};

    // Schluessel setzen
    for (int i = 0; i < 16; i++) {
        key[i] = newKey[i];
    }

    // Klartext setzen
    for (int i = 0; i < 16; i++) {
        klartext.push_back(newKlartext[i]);
    }
}

void myECB::printSchluessel() {
    cout << endl << "Schluessel:\n";
    for (int i = 0; i < 4; i++)
        cout << hex << "\t0x" << (int) key[0 + i] << "\t0x" << (int) key [4 + i] << "\t0x" << (int) key [8 + i] << "\t0x" << (int) key[12 + i] << endl;
    cout << endl;
}

void myECB::printCiphertext() {
    cout << endl << "Ciphertext:\n";
    for (int i = 0; i < ciphertext.size(); i++) {
        cout << std::hex << " 0x" << (int) ciphertext[i];
    }
}

void myECB::printKlartext() {
    cout << endl << "Klartext:\n";
    for (int i = 0; i < klartext.size(); i++) {
        cout << std::hex << " 0x" << (int) klartext[i];
    }
}

vector<uchar> myECB::getCiphertext() {
    return ciphertext;
}

void myECB::decrypt(bool print) {
    klartext.clear();

    for (int i = 0; i < ciphertext.size() / 16; i++) {

        myAES a1;

        //Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = ciphertext[j + 16 * i];
        }

        // Ciphertext
        a1.setCiphertext(tmp);

        // Schluessel
        a1.setSchluessel(key);

        // crypt
        a1.decrypt(false);

        // Resultat mit IV addieren
        for (int j = 0; j < 16; j++) {
            klartext.push_back(a1.getKlartext()[j]);
        }
    }

    if (print) {
        printSchluessel();
        printCiphertext();
        printKlartext();
    }

}

void myECB::crypt(bool print) {
    ciphertext.clear();
    /* uchar tmp_iv[16];
     for (int i = 0; i < 16; i++) {
         tmp_iv[i] = iv[i];
     }*/

    for (int i = 0; i < klartext.size() / 16; i++) {

        myAES a1;
        a1.setSchluessel(key);

        //XOR in Übergabe - Array
        uchar tmp[16];
        for (int j = 0; j < 16; j++) {
            tmp[j] = klartext[j + 16 * i]; //^tmp_iv[j];
        }

        // Klartext
        a1.setKlartext(tmp);

        // crypt
        a1.crypt(false);


        for (int j = 0; j < 16; j++) {
            //tmp_iv[j] = a1.getCiphertext()[j];
            ciphertext.push_back(a1.getCiphertext()[j]);
        }
    }

    if (print) {
        printSchluessel();
        printKlartext();
        printCiphertext();
    }
}

void myECB::setKlartext(vector<uchar> kt) {
    if (kt.size() > klartext.size()) {
        int diff = kt.size() - klartext.size();
        for (int i = 0; i < diff; i++) {
            klartext.push_back(0x00);
        }
    }
    for (int i = 0; i < kt.size(); i++) {
        klartext.at(i) = kt.at(i);
    }
}

void myECB::setKey(uchar tmp[16]) {
    for (int i = 0; i < 16; i++) {
        key[i] = tmp[i];
    }
}

myECB::~myECB() {
}

Schreiben Sie einen Kommentar

Ihre E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahren Sie, wie Ihre Kommentardaten verarbeitet werden.

'); } cout << RED_end << endl; } } myECB::myECB() { // Default Parameter uchar newKey[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c}; uchar newIV[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}; uchar newKlartext[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a}; // Schluessel setzen for (int i = 0; i < 16; i++) { key[i] = newKey[i]; } // Klartext setzen for (int i = 0; i < 16; i++) { klartext.push_back(newKlartext[i]); } } void myECB::printSchluessel() { cout << endl << "Schluessel:\n"; for (int i = 0; i < 4; i++) cout << hex << "\t0x" << (int) key[0 + i] << "\t0x" << (int) key [4 + i] << "\t0x" << (int) key [8 + i] << "\t0x" << (int) key[12 + i] << endl; cout << endl; } void myECB::printCiphertext() { cout << endl << "Ciphertext:\n"; for (int i = 0; i < ciphertext.size(); i++) { cout << std::hex << " 0x" << (int) ciphertext[i]; } } void myECB::printKlartext() { cout << endl << "Klartext:\n"; for (int i = 0; i < klartext.size(); i++) { cout << std::hex << " 0x" << (int) klartext[i]; } } vector<uchar> myECB::getCiphertext() { return ciphertext; } void myECB::decrypt(bool print) { klartext.clear(); for (int i = 0; i < ciphertext.size() / 16; i++) { myAES a1; //Übergabe - Array uchar tmp[16]; for (int j = 0; j < 16; j++) { tmp[j] = ciphertext[j + 16 * i]; } // Ciphertext a1.setCiphertext(tmp); // Schluessel a1.setSchluessel(key); // crypt a1.decrypt(false); // Resultat mit IV addieren for (int j = 0; j < 16; j++) { klartext.push_back(a1.getKlartext()[j]); } } if (print) { printSchluessel(); printCiphertext(); printKlartext(); } } void myECB::crypt(bool print) { ciphertext.clear(); /* uchar tmp_iv[16]; for (int i = 0; i < 16; i++) { tmp_iv[i] = iv[i]; }*/ for (int i = 0; i < klartext.size() / 16; i++) { myAES a1; a1.setSchluessel(key); //XOR in Übergabe - Array uchar tmp[16]; for (int j = 0; j < 16; j++) { tmp[j] = klartext[j + 16 * i]; //^tmp_iv[j]; } // Klartext a1.setKlartext(tmp); // crypt a1.crypt(false); for (int j = 0; j < 16; j++) { //tmp_iv[j] = a1.getCiphertext()[j]; ciphertext.push_back(a1.getCiphertext()[j]); } } if (print) { printSchluessel(); printKlartext(); printCiphertext(); } } void myECB::setKlartext(vector<uchar> kt) { if (kt.size() > klartext.size()) { int diff = kt.size() - klartext.size(); for (int i = 0; i < diff; i++) { klartext.push_back(0x00); } } for (int i = 0; i < kt.size(); i++) { klartext.at(i) = kt.at(i); } } void myECB::setKey(uchar tmp[16]) { for (int i = 0; i < 16; i++) { key[i] = tmp[i]; } } myECB::~myECB() { }

Schreiben Sie einen Kommentar

Ihre E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahren Sie, wie Ihre Kommentardaten verarbeitet werden.

Index