代码先扔这,区域赛打完来补
/*
DES实现
Author: Hardict
E-mail: 1035979074@qq.com/a1035979074@gmail.com
*/
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <vector>
using namespace std;
using LL = long long;
using ULL = unsigned long long;
using LDB = long double;
const int MAXN = 1e5 + 5;
const int INF = 2e9 + 5;
map<int, char> MP_Hex;
map<char, int> MP_Hex_inv;
string btos(int x, int d); // d位转二进制转string
int stob(string s, int d); // d位string转int
vector<bitset<48>> getK(bitset<64> K); //生成子密钥
// 0加密,1解密(提前生成子密钥)
bitset<64> crypt(bitset<64> M, vector<bitset<48>> K, int op);
int main() {
freopen("DES.in", "r", stdin);
freopen("DES.out", "w", stdout);
for (int i = 0; i < 10; i++) MP_Hex[i] = '0' + i, MP_Hex_inv['0' + i] = i;
for (int i = 10; i < 16; i++)
MP_Hex[i] = 'A' + (i - 10), MP_Hex_inv['A' + (i - 10)] = i;
string plain, secret;
//明文
plain = "";
for (int i = 0; i < 16; i++) {
char ch;
cin >> ch;
int x = MP_Hex_inv[ch];
plain += btos(x, 4);
}
// for (int i = 0; i < 16; i++) plain += btos(i, 4);
bitset<64> M(plain);
cout << "Plaintext:" << endl << "M: " << M << endl;
//密钥
secret = "";
for (int i = 0; i < 16; i++) {
char ch;
cin >> ch;
int x = MP_Hex_inv[ch];
secret += btos(x, 4);
}
cout << secret << endl;
/* secret += btos(1, 4) + btos(3, 4);
secret += btos(3, 4) + btos(4, 4);
secret += btos(5, 4) + btos(7, 4);
secret += btos(7, 4) + btos(9, 4);
secret += btos(9, 4) + btos(11, 4);
secret += btos(11, 4) + btos(12, 4);
secret += btos(13, 4) + btos(15, 4);
secret += btos(15, 4) + btos(1, 4); */
bitset<64> K(secret);
cout << "Secret key:" << endl << "K: " << K << endl << endl;
auto K_array = getK(K);
string s, t;
//加密
cout << "----" << endl << "encrypt:" << endl;
auto C = crypt(M, K_array, 0);
cout << "C(bin): " << C << endl;
s = "", t = C.to_string();
for (int i = 0; i < 16; i++) {
int x = stob(t.substr(i * 4, 4), 4);
s += MP_Hex[x];
}
cout << "C(hex): " << s << endl;
//解密
cout << "----" << endl << "decrypt:" << endl;
auto C_inv = crypt(C, K_array, 1);
cout << "C_inv(bin): " << C_inv << endl;
return 0;
}
bitset<32> fuc1(bitset<32> R, bitset<48> K);
bitset<64> crypt(bitset<64> M, vector<bitset<48>> K, int op) {
//初始置换
static int IP1[8][8] = {
{58, 50, 42, 34, 26, 18, 10, 2}, {60, 52, 44, 36, 28, 20, 12, 4},
{62, 54, 46, 38, 30, 22, 14, 6}, {64, 56, 48, 40, 32, 24, 16, 8},
{57, 49, 41, 33, 25, 17, 9, 1}, {59, 51, 43, 35, 27, 19, 11, 3},
{61, 53, 45, 37, 29, 21, 13, 5}, {63, 55, 47, 39, 31, 23, 15, 7}};
string s;
s = "";
for (int i = 0; i < 8; i++)
for (int j = 0; j < 8; j++) {
// bitset是从高位开始存
s += '0' + M[64 - IP1[i][j]];
}
cout << "初始置换(64-64):" << endl;
cout << "M_IP1: " << s << endl;
bitset<32> L(s.substr(0, s.size() / 2)),
R(s.substr(s.size() / 2, s.size() / 2));
cout << "L0: " << L << endl;
cout << "R0: " << R << endl;
cout << endl;
vector<pair<bitset<32>, bitset<32>>> LR;
LR.push_back(make_pair(L, R));
// L = L ^ fuc1(R, K[1]);
// cout << L << endl;
if (op == 0) {
for (int i = 0; i < 16; i++) {
cout << "加密第" << i + 1 << "次迭代" << endl;
L = LR[i].first;
R = LR[i].second;
L = L ^ fuc1(R, K[i + 1]);
LR.push_back(make_pair(R, L));
cout << "L" << i + 1 << ": " << R << endl;
cout << "R" << i + 1 << ": " << L << endl;
cout << endl;
}
} else if (op == 1) {
for (int i = 16; i >= 1; i--) {
cout << "解密第" << 17 - i << "次迭代" << endl;
L = LR[LR.size() - 1].first;
R = LR[LR.size() - 1].second;
L = L ^ fuc1(R, K[i]);
// cout << K[i] << endl;
LR.push_back(make_pair(R, L));
cout << "L" << 17 - i << ": " << R << endl;
cout << "R" << 17 - i << ": " << L << endl;
cout << endl;
}
}
//最终置换
static int IP_1[8][8] = {
{40, 8, 48, 16, 56, 24, 64, 32}, {39, 7, 47, 15, 55, 23, 63, 31},
{38, 6, 46, 14, 54, 22, 62, 30}, {37, 5, 45, 13, 53, 21, 61, 29},
{36, 4, 44, 12, 52, 20, 60, 28}, {35, 3, 43, 11, 51, 19, 59, 27},
{34, 2, 42, 10, 50, 18, 58, 26}, {33, 1, 41, 9, 49, 17, 57, 25}};
string t;
s = LR[16].second.to_string() + LR[16].first.to_string();
cout << "R16L16:" << endl;
cout << s << endl;
t = "";
for (int i = 0; i < 8; i++)
for (int j = 0; j < 8; j++) t += s[IP_1[i][j] - 1];
// cout << t << endl;
bitset<64> res(t);
return res;
}
bitset<32> fuc1(bitset<32> R, bitset<48> K) {
// E盒扩展
static int E[8][6] = {{32, 1, 2, 3, 4, 5}, {4, 5, 6, 7, 8, 9},
{8, 9, 10, 11, 12, 13}, {12, 13, 14, 15, 16, 17},
{16, 17, 18, 19, 20, 21}, {20, 21, 22, 23, 24, 25},
{24, 25, 26, 27, 28, 29}, {28, 29, 30, 31, 32, 1}};
string s;
s = "";
for (int i = 0; i < 8; i++)
for (int j = 0; j < 6; j++) s += '0' + R[32 - E[i][j]];
bitset<48> ER(s);
cout << "E盒扩展(32->48):" << endl;
cout << ER << endl;
ER = ER ^ K;
cout << "异或运算:" << endl;
cout << ER << endl;
// S盒转换
static int S[8][4][16] = {
{{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},
{0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},
{4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
{15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}},
{{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},
{3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},
{0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},
{13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}},
{{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},
{13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},
{13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},
{1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}},
{{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},
{13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},
{10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},
{3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}},
{{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},
{14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},
{4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},
{11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}},
{{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},
{10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},
{9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},
{4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}},
{{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1},
{13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},
{1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},
{6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}},
{{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},
{1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2},
{7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8},
{2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}};
//
s = ER.to_string();
string t;
t = "";
// cout << s << endl;
for (int i = 0; i < 8; i++) {
// cout << i << endl;
//分组拆分
string s1, s2;
s1 = s[i * 6];
s1 = s1 + s[i * 6 + 5];
s2 = s.substr(i * 6 + 1, 4);
int row, col;
// cout << s1 << " " << s2 << endl;
row = stob(s1, 2), col = stob(s2, 4);
// cout << row << " " << col << endl;
t += btos(S[i][row][col], 4);
}
cout << "S盒运算:" << endl;
cout << t << endl;
// P盒置换
static int P[8][4] = {{16, 7, 20, 21}, {29, 12, 28, 17}, {1, 15, 23, 26},
{5, 18, 31, 10}, {2, 8, 24, 14}, {32, 27, 3, 9},
{19, 13, 30, 6}, {22, 11, 4, 25}};
s = "";
for (int i = 0; i < 8; i++)
for (int j = 0; j < 4; j++) s += t[P[i][j] - 1];
cout << "P盒置换" << endl;
cout << s << endl;
bitset<32> res(s);
return res;
}
vector<bitset<48>> getK(bitset<64> K) {
//初步交换
static int PC1[8][7] = {
{57, 49, 41, 33, 25, 17, 9}, {1, 58, 50, 42, 34, 26, 18},
{10, 2, 59, 51, 43, 35, 27}, {19, 11, 3, 60, 52, 44, 36},
{63, 55, 47, 39, 31, 23, 15}, {7, 62, 54, 46, 38, 30, 22},
{14, 6, 61, 53, 45, 37, 29}, {21, 13, 5, 28, 20, 12, 4}};
string s = "";
for (int i = 0; i < 8; i++)
for (int j = 0; j < 7; j++) s += '0' + K[64 - PC1[i][j]];
bitset<56> _K(s);
cout << "初步置换:" << endl;
cout << "K': " << _K << endl;
bitset<28> C(s.substr(0, s.size() / 2)),
D(s.substr(s.size() / 2, s.size() / 2));
cout << "C0: " << C << endl;
cout << "D0: " << D << endl;
vector<pair<bitset<28>, bitset<28>>> CD;
CD.push_back(make_pair(C, D));
cout << endl;
//左移变换
static int L_Mv[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
cout << "左移过程" << endl;
for (int i = 0; i < 16; i++) {
C = CD[i].first, D = CD[i].second;
bitset<28> tmp;
//利用溢出得到循环左移解
tmp = C >> (28 - L_Mv[i]);
C = (C << L_Mv[i]) | (tmp);
tmp = D >> (28 - L_Mv[i]);
D = (D << L_Mv[i]) | (tmp);
CD.push_back(make_pair(C, D));
cout << "C" << i + 1 << ": " << C << endl;
cout << "D" << i + 1 << ": " << D << endl;
}
cout << endl;
//子密钥生成
static int PC2[8][6] = {{14, 17, 11, 24, 1, 5}, {3, 28, 15, 6, 21, 10},
{23, 19, 12, 4, 26, 8}, {16, 7, 27, 20, 13, 2},
{41, 52, 31, 37, 47, 55}, {30, 40, 51, 45, 33, 48},
{44, 49, 39, 56, 34, 53}, {46, 42, 50, 36, 29, 32}};
vector<bitset<48>> res;
bitset<48> p;
res.push_back(p);
cout << "16个子密钥" << endl;
for (int i = 1; i <= 16; i++) {
s = "";
string org = CD[i].first.to_string() + CD[i].second.to_string();
for (int j = 0; j < 8; j++)
for (int k = 0; k < 6; k++) s += org[PC2[j][k] - 1];
bitset<48> p(s);
cout << "K" << i << ": " << p << endl;
res.push_back(p);
}
cout << endl;
return res;
}
// d位转二进制转string
string btos(int x, int d) {
string s = "";
for (int i = 0; i < d; i++) s += '0' + ((x >> i) & 1);
reverse(s.begin(), s.end());
return s;
}
// d位string转int
int stob(string s, int d) {
int res = 0;
for (int i = 0; i < d; i++) res = (res << 1) + (s[i] == '1');
return res;
}
/*
AES实现
Author: Hardict
E-mail: 1035979074@qq.com/a1035979074@gmail.com
*/
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <vector>
using namespace std;
using LL = long long;
using ULL = unsigned long long;
using LDB = long double;
using UI8 = unsigned char;
const int MAXN = 1e5 + 5;
const int INF = 2e9 + 5;
const int AES_ROUND = 10;
const int AES_BLOCK_SIZE = 16;
map<int, char> MP_Hex;
map<char, int> MP_Hex_inv;
vector<int> Shift_rows(vector<int> org);
vector<int> Shift_rows_inv(vector<int> org);
vector<int> Gene_Keys(vector<int> org);
vector<int> AES_encrypt_128(vector<int> P, vector<int> keys);
vector<int> AES_decrypt_128(vector<int> C, vector<int> keys);
int multi_2(int x);
int main() {
freopen("AES.in", "r", stdin);
freopen("AES.out", "w", stdout);
for (int i = 0; i < 10; i++) MP_Hex[i] = '0' + i, MP_Hex_inv['0' + i] = i;
for (int i = 10; i < 16; i++)
MP_Hex[i] = 'A' + (i - 10), MP_Hex_inv['A' + (i - 10)] = i;
vector<int> Plain;
vector<int> K;
Plain.resize(AES_BLOCK_SIZE);
K.resize(AES_BLOCK_SIZE);
for (int i = 0; i < AES_BLOCK_SIZE; i++) {
char ch = getchar();
while (isspace(ch)) ch = getchar();
Plain[i] = MP_Hex_inv[ch];
}
for (int i = 0; i < AES_BLOCK_SIZE; i++) {
char ch = getchar();
while (isspace(ch)) ch = getchar();
K[i] = MP_Hex_inv[ch];
}
printf("Plaintext:\n");
for (int i = 0; i < AES_BLOCK_SIZE; i++)
printf("%d%c", Plain[i], (i == AES_BLOCK_SIZE - 1) ? '\n' : ' ');
auto Keys = Gene_Keys(K);
printf("Keys:\n");
for (int i = 0; i < AES_ROUND + 1; i++) {
for (int j = 0; j < AES_BLOCK_SIZE; j++)
printf("%d ", Keys[i * AES_BLOCK_SIZE + j]);
printf("\n");
}
printf("\n");
auto C = AES_encrypt_128(Plain, Keys);
printf("\nCiphertext:\n");
for (int i = 0; i < AES_BLOCK_SIZE; i++)
printf("%d%c", C[i], (i == AES_BLOCK_SIZE - 1) ? '\n' : ' ');
auto P1 = AES_decrypt_128(C, Keys);
printf("\ndecrypt:\n");
for (int i = 0; i < AES_BLOCK_SIZE; i++)
printf("%d%c", P1[i], (i == AES_BLOCK_SIZE - 1) ? '\n' : ' ');
return 0;
}
static int S[256] = {
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};
static int S_inv[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};
vector<int> AES_encrypt_128(vector<int> P, vector<int> keys) {
vector<int> res;
res.resize(AES_BLOCK_SIZE);
for (int i = 0; i < AES_BLOCK_SIZE; i++) {
res[i] = P[i] ^ keys[i];
// printf("%d\n", res[i]);
}
for (int k = 1; k < AES_ROUND; k++) {
vector<int> tmp;
tmp.resize(AES_BLOCK_SIZE);
for (int i = 0; i < AES_BLOCK_SIZE; i++) {
tmp[i] = S[res[i]];
// cout << "tmp:" << k << " " << i << " " << tmp[i] << endl;
}
tmp = Shift_rows(tmp);
/*
* MixColumns
* [02 03 01 01] [s0 s4 s8 s12]
* [01 02 03 01] . [s1 s5 s9 s13]
* [01 01 02 03] [s2 s6 s10 s14]
* [03 01 01 02] [s3 s7 s11 s15]
*/
for (int i = 0; i < AES_BLOCK_SIZE; i += 4) {
int x = tmp[i] ^ tmp[i + 1] ^ tmp[i + 2] ^ tmp[i + 3];
res[i] = multi_2(tmp[i] ^ tmp[i + 1]) ^ tmp[i] ^ x;
res[i + 1] = multi_2(tmp[i + 1] ^ tmp[i + 2]) ^ tmp[i + 1] ^ x;
res[i + 2] = multi_2(tmp[i + 2] ^ tmp[i + 3]) ^ tmp[i + 2] ^ x;
res[i + 3] = multi_2(tmp[i + 3] ^ tmp[i]) ^ tmp[i + 3] ^ x;
}
for (int i = 0; i < AES_BLOCK_SIZE; i++) {
// cout << "res:" << k << " " << i << " " << tmp[i] << endl;
res[i] ^= keys[k * AES_BLOCK_SIZE + i];
}
}
for (int i = 0; i < AES_BLOCK_SIZE; i++) res[i] = S[res[i]];
res = Shift_rows(res);
for (int i = 0; i < AES_BLOCK_SIZE; i++)
res[i] ^= keys[AES_ROUND * AES_BLOCK_SIZE + i];
return res;
}
vector<int> AES_decrypt_128(vector<int> C, vector<int> keys) {
vector<int> res;
res.resize(AES_BLOCK_SIZE);
for (int i = 0; i < AES_BLOCK_SIZE; i++)
res[i] = C[i] ^ keys[AES_ROUND * AES_BLOCK_SIZE + i];
res = Shift_rows_inv(res);
for (int i = 0; i < AES_BLOCK_SIZE; i++) {
res[i] = S_inv[res[i]];
// cout << res[i] << endl;
}
for (int k = 1; k < AES_ROUND; k++) {
vector<int> tmp;
tmp.resize(AES_BLOCK_SIZE);
for (int i = 0; i < AES_BLOCK_SIZE; i++) {
tmp[i] = res[i] ^ keys[(AES_ROUND - k) * AES_BLOCK_SIZE + i];
// cout << tmp[i] << endl;
}
/*
* Inverse MixColumns
* [0e 0b 0d 09] [s0 s4 s8 s12]
* [09 0e 0b 0d] . [s1 s5 s9 s13]
* [0d 09 0e 0b] [s2 s6 s10 s14]
* [0b 0d 09 0e] [s3 s7 s11 s15]
*/
for (int i = 0; i < AES_BLOCK_SIZE; i += 4) {
int x = tmp[i] ^ tmp[i + 1] ^ tmp[i + 2] ^ tmp[i + 3];
res[i] = multi_2(tmp[i] ^ tmp[i + 1]) ^ tmp[i] ^ x;
res[i + 1] = multi_2(tmp[i + 1] ^ tmp[i + 2]) ^ tmp[i + 1] ^ x;
res[i + 2] = multi_2(tmp[i + 2] ^ tmp[i + 3]) ^ tmp[i + 2] ^ x;
res[i + 3] = multi_2(tmp[i + 3] ^ tmp[i]) ^ tmp[i + 3] ^ x;
int u, v;
u = multi_2(multi_2(tmp[i] ^ tmp[i + 2]));
v = multi_2(multi_2(tmp[i + 1] ^ tmp[i + 3]));
x = multi_2(u ^ v);
res[i] ^= x ^ u;
res[i + 1] ^= x ^ v;
res[i + 2] ^= x ^ u;
res[i + 3] ^= x ^ v;
// cout << res[i] << endl;
}
res = Shift_rows_inv(res);
for (int i = 0; i < AES_BLOCK_SIZE; i++) {
res[i] = S_inv[res[i]];
}
}
for (int i = 0; i < AES_BLOCK_SIZE; i++) res[i] ^= keys[i];
return res;
}
vector<int> Gene_Keys(vector<int> org) {
static int RC[AES_ROUND] = {0x01, 0x02, 0x04, 0x08, 0x10,
0x20, 0x40, 0x80, 0x1b, 0x36};
vector<int> res;
res.resize((AES_ROUND + 1) * AES_BLOCK_SIZE);
for (int i = 0; i < AES_BLOCK_SIZE; i++) res[i] = org[i];
// bitset<int>;
for (int k = 0; k < AES_ROUND; k++) {
vector<int> S_;
S_.resize(4);
for (int i = AES_BLOCK_SIZE * (k + 1) - 4, j = 3;
i < AES_BLOCK_SIZE * (k + 1); i++, j = (j + 1) % 4)
S_[j] = S[res[i]];
S_[0] ^= RC[k];
// cout << (S_[0] ^ res[k * AES_BLOCK_SIZE]) << endl;
for (int i = 0; i < 4; i++)
res[(k + 1) * AES_BLOCK_SIZE + i] = S_[i] ^ res[k * AES_BLOCK_SIZE + i];
for (int i = 4; i < AES_BLOCK_SIZE; i++)
res[(k + 1) * AES_BLOCK_SIZE + i] =
res[(k + 1) * AES_BLOCK_SIZE + i - 4] ^ res[k * AES_BLOCK_SIZE + i];
}
return res;
}
vector<int> Shift_rows(vector<int> org) {
vector<int> res;
res.resize(AES_BLOCK_SIZE);
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++) res[i * 4 + j] = org[i * 4 + (j + i) % 4];
// res[1] = org[5], res[5] = org[9], res[9] = org[13], res[13] = org[1];
// res[2] = org[10], res[10] = org[2], res[6] = org[14], res[14] = org[6];
// res[15] = org[11], res[11] = org[7], res[7] = org[3], res[3] = org[15];
// res[0] = org[0], res[4] = org[4], res[8] = org[8], res[12] = org[12];
return res;
}
vector<int> Shift_rows_inv(vector<int> org) {
vector<int> res;
res.resize(AES_BLOCK_SIZE);
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++) res[i * 4 + j] = org[i * 4 + (j - i + 4) % 4];
// res[1] = org[13], res[5] = org[1], res[9] = org[5], res[13] = org[9];
// res[2] = org[10], res[6] = org[14], res[10] = org[2], res[14] = org[6];
// res[3] = org[7], res[7] = org[11], res[11] = org[15], res[15] = org[3];
// res[0] = org[0], res[4] = org[4], res[8] = org[8], res[12] = org[12];
return res;
}
int multi_2(int x) {
int res = x << 1;
res = (uint8_t)res;
if (x & (1 << 7)) res ^= 0x1b;
res = (uint8_t)res;
// cout << x << " " << res << endl;
return res;
}