DES与AES实现

代码先扔这,区域赛打完来补

/*
DES实现
Author: Hardict
E-mail: [email protected]/[email protected]
 */
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
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 MP_Hex;
map MP_Hex_inv;
string btos(int x, int d);              // d位转二进制转string
int stob(string s, int d);              // d位string转int
vector> getK(bitset<64> K);  //生成子密钥
// 0加密,1解密(提前生成子密钥)
bitset<64> crypt(bitset<64> M, vector> 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> 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, 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> 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, 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> 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: [email protected]/[email protected]
 */
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
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 MP_Hex;
map MP_Hex_inv;
vector Shift_rows(vector org);
vector Shift_rows_inv(vector org);
vector Gene_Keys(vector org);
vector AES_encrypt_128(vector P, vector keys);
vector AES_decrypt_128(vector C, vector 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 Plain;
  vector 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 AES_encrypt_128(vector P, vector keys) {
  vector 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 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 AES_decrypt_128(vector C, vector keys) {
  vector 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 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 Gene_Keys(vector org) {
  static int RC[AES_ROUND] = {0x01, 0x02, 0x04, 0x08, 0x10,
                              0x20, 0x40, 0x80, 0x1b, 0x36};
  vector res;
  res.resize((AES_ROUND + 1) * AES_BLOCK_SIZE);
  for (int i = 0; i < AES_BLOCK_SIZE; i++) res[i] = org[i];
  // bitset;
  for (int k = 0; k < AES_ROUND; k++) {
    vector 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 Shift_rows(vector org) {
  vector 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 Shift_rows_inv(vector org) {
  vector 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;
}

 

你可能感兴趣的:(密码学)