A = ( 1 0 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 0 0 0 0 1 1 1 1 1 0 0 0 0 1 1 1 1 1 ) A= \begin{pmatrix} 1 &0 &0 &0 &1 &1 &1 &1\\ 1 &1 &0 &0 &0 &1 &1 &1\\ 1 &1 &1 &0 &0 &0 &1 &1\\ 1 &1 &1 &1 &0 &0 &0 &1\\ 1 &1 &1 &1 &1 &0 &0 &0\\ 0 &1 &1 &1 &1 &1 &0 &0 \\ 0 &0 &1 &1 &1 &1 &1 &0\\ 0 &0 &0 &1 &1 &1 &1 &1 \end{pmatrix} A=⎝⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎛1111100001111100001111100001111110001111110001111110001111110001⎠⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎞
有一步反序
A = ( F 1 , E 3 , C 7 , 8 F , 1 F , 3 E , 7 C , F 8 ) A= \begin{pmatrix} F1,E3,C7,8F,1F,3E,7C,F8 \end{pmatrix} A=(F1,E3,C7,8F,1F,3E,7C,F8)
A − 1 = ( 0 0 1 0 0 1 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 1 0 0 1 0 0 0 1 0 1 0 0 1 0 0 0 1 0 1 0 0 1 1 0 0 1 0 1 0 0 0 1 0 0 1 0 1 0 ) A^{-1} = \begin{pmatrix} 0 &0 &1 &0 &0 &1 &0 &1\\ 1 &0 &0 &1 &0 &0 &1 &0\\ 0 &1 &0 &0 &1 &0 &0 &1\\ 1 &0 &1 &0 &0 &1 &0 &0\\ 0 &1 &0 &1 &0 &0 &1 &0\\ 0 &0 &1 &0 &1 &0 &0 &1 \\ 1 &0 &0 &1 &0 &1 &0 &0\\ 0 &1 &0 &0 &1 &0 &1 &0 \end{pmatrix} A−1=⎝⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎛0101001000101001100101000100101000100101100100100100100110100100⎠⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎞
A − 1 = ( A 4 , 49 , 92 , 25 , 4 A , 94 , 29 , 52 ) A^{-1} = \begin{pmatrix} A4,49,92,25,4A,94,29,52 \end{pmatrix} A−1=(A4,49,92,25,4A,94,29,52)
b = ( 1 1 0 0 0 1 1 0 ) b = \begin{pmatrix} &1\\ &1 \\&0 \\&0 \\&0 \\&1 \\&1 \\&0 \end{pmatrix} b=⎝⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎛11000110⎠⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎞
b = 63 b=63 b=63
aes博客,写得很棒
aes博客
求A的逆矩阵用到的算法
高斯消元法求解异或线性方程组
遇到的大坑,字节序,intel的cpu是小字节序,这一点一定要注意,假设有 a a , b b , c c , d d aa,bb,cc,dd aa,bb,cc,dd四个字节那么如果当成一个32位的数,它会反过来变成 d d , c c , b b , a a dd,cc,bb,aa dd,cc,bb,aa。上边的左移变成了下边的右移,密钥扩展的Rcon异或的是低位。字节操作是不受影响的。
密钥扩展:
1.字循环,即左移一个字节,在小端序下为右移一个字节
2.取逆元
3.异或一个与轮数有关的值 "abcd"的情况下,是异或在a上,小端序下0x04,
大端序下就会变成0x04000000
正常流程:
g f ( 2 8 ) gf(2^8) gf(28)上取逆元,矩阵乘,加上一个偏移
行移位,简单平移,注意大端小端
列混淆,模 f ( x ) = x 4 + 1 f(x)=x^4+1 f(x)=x4+1上序数为 g f ( 2 8 ) gf(2^8) gf(28)上的乘积运算,乘以 3 x 3 + 1 x 2 + 1 x + 2 3x^3+1x^2+1^x+2 3x3+1x2+1x+2的运算
数据与扩展密钥异或
#include<vector>
#include<iostream>
using namespace std;
union M {
unsigned char chars[4][4];
uint32_t i32[4];
};
int tb[256];
int rtb[256];
int S[16][16];
int rS[16][16];
int A[] = {
0xF1,0xE3,0xC7,0x8F,0x1F,0x3E,0x7C,0xF8 };
int A_[] = {
0xA4,0x49,0x92,0x25,0x4A,0x94,0x29,0x52 };
int b = 0x63;
int Mixtb[4][4] = {
{
0x02,0x03,0x01,0x01},
{
0x01,0x02,0x03,0x01},
{
0x01,0x01,0x02,0x03},
{
0x03,0x01,0x01,0x02}
};
int rMixtb[4][4] = {
{
0x0e,0x0b,0x0d,0x09},
{
0x09,0x0e,0x0b,0x0d},
{
0x0d,0x09,0x0e,0x0b},
{
0x0b,0x0d,0x09,0x0e}
};
constexpr uint32_t Rcon[11] = {
0x00000000, 0x01, 0x02,
0x04, 0x08,
0x10, 0x20,
0x40, 0x80,
0x1b, 0x36 };
uint32_t rev(uint32_t val) {
uint8_t* p = (uint8_t*)&val;
swap(p[0], p[3]);
swap(p[1], p[2]);
return val;
}
//xtimes实现乘法
int GFmul(int a, int b) {
int ans = 0;
while (b) {
if (b & 1) {
ans ^= a;
}
if (a > 127)
a = (a << 1) ^ 0x1b;
else
a <<= 1;
a &= 0xff;
b >>= 1;
}
return ans;
}
//用生成元三生成表
void g3() {
tb[0] = rtb[0] = 0;
tb[1] = rtb[1] = 1;
int g = 3;
int ans = 1;
for (int i = 2; i < 256; i++) {
ans = GFmul(ans, g);
tb[i] = ans;
rtb[ans] = i;
}
}
//查表乘法
int GFtbMul(int a, int b) {
if (!a || !b)return 0;
else return tb[(rtb[a] + rtb[b] - 2) % 255 + 1];
}
//查表求逆元
int GFinver(int a) {
if (a < 2)return a;
else {
return tb[257 - rtb[a]];
}
}
//实现GF矩阵乘法
int GFMatrixMul(int* matrix, int val) {
int ans = 0;
for (int i = 0; i < 8; i++) {
int t = matrix[i] & val;
int k = 0;
while (t) {
k++;
t -= (t & -t);
}
ans |= (k % 2) << (i);
}
return ans;
}
//求S盒
void gS() {
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
int element = i << 4 | j;
int relement = GFinver(element);
S[i][j] = GFMatrixMul(A, relement) ^ b;
//printf("%2x ", S[i][j]);
}//cout << endl;
}
}
void grS() {
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
int element = i << 4 | j;
element ^= b;
rS[i][j] = GFinver(GFMatrixMul(A_, element));
//printf("%2x ", rS[i][j]);
}//cout << endl;
}
}
uint32_t subByte(uint32_t val) {
unsigned char* t = (unsigned char*)&val;
for (int i = 0; i < 4; i++) {
uint32_t tmp = *(t + i);
*(t + i) = S[tmp >> 4][tmp & 0xf];
}
return val;
}
uint32_t rsubByte(uint32_t val) {
unsigned char* t = (unsigned char*)&val;
for (int i = 0; i < 4; i++) {
uint32_t tmp = *(t + i);
*(t + i) = rS[tmp >> 4][tmp & 0xf];
}
return val;
}
uint32_t shiftL(uint32_t val,int t) {
//printf("%x %x %x\n",val, val << t, val >> (32 - t));
val = (val >> t) | (val << (32-t));
return val;
}
uint32_t RotByte(uint32_t val) {
val = val >> 8 | val << 24;
return val;
}
//将四个字节同时替换
uint32_t SubByte(uint32_t val) {
unsigned char* t = (unsigned char*)&val;
for (int i = 0; i < 4; i++){
uint32_t tmp = *(t + i);
*(t + i) = S[tmp >> 4][tmp & 0xf];
}
return val;
}
uint32_t rSubByte(uint32_t val) {
unsigned char* t = (unsigned char*)&val;
for (int i = 0; i < 4; i++) {
uint32_t tmp = *(t + i);
*(t + i) = rS[tmp >> 4][tmp & 0xf];
}
return val;
}
vector<uint32_t> expandKey(vector<uint32_t> key) {
int Nb = 4;//分组长度32bit aes标准限定128
int Nk = key.size();
int Nr;
if (Nk == 4)Nr = 10;
else if (Nk == 6)Nr = 12;
else Nr = 14;
int len = Nb * (Nr + 1);
vector<uint32_t> ans(len);
for (int i = 0; i < Nk; i++) {
ans[i] = (key[i]);
}
for (int i = Nk; i < len; i++) {
int temp = ans[i - 1];
if (i % Nk == 0) {
temp = SubByte(RotByte(temp)) ^ Rcon[i / Nk];
}
else if (i % Nk == 4 && Nk > 6)temp = SubByte(temp);
ans[i] = ans[i - Nk] ^ temp;
}
//for (int i = 0; i < len; i++)ans[i] = rev(ans[i]);
return ans;
}
#if 0
#define PRINT
#else
#define PRINT do{
\
for(int gi=0;gi<4;gi++){
\
for(int gj=0;gj<4;gj++){
\
printf("%02x ",d->chars[gi][gj]);\
}\
}puts("");\
}while(0);
#endif
void AddRoundKey(M* p,M* k) {
for (int i = 0; i < 4; i++) {
p->i32[i]^=k->i32[i];
}
}
void subBytes(M* p) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
uint32_t t = p->chars[i][j];
p->chars[i][j] = S[t >> 4][t & 0xf];
}
}
}
void trans(M* t) {
for (int i = 0; i < 4; i++) {
for (int j = i+1; j < 4; j++) {
swap(t->chars[i][j], t->chars[j][i]);
}
}
}
void shiftRows(M* p) {
for (int i = 1; i < 4; i++) {
p->i32[i] = shiftL(p->i32[i], i << 3);
}
}
void mixColumns(M* p) {
M tmp;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
uint32_t ans = 0;
for (int k = 0; k < 4; k++) {
ans ^= GFtbMul(Mixtb[i][k], p->chars[k][j]);
//printf("%02x %02x %02x\n",Mixtb[i][k] ,p->chars[k][j], ans);
}
tmp.chars[i][j] = ans;
}
}
for (int i = 0; i < 4; i++) {
p->i32[i] = tmp.i32[i];
}
}
vector<uint32_t> AES_128_en(vector<uint32_t>& data, vector<uint32_t>& expkey) {
int n = data.size();
vector<uint32_t> ans(data.begin(), data.end());
if (n % 4) {
cout << "error" << endl;
return ans;
}
for (int i = 0; i < n; i += 4) {
//AddRoundKey
M* d = (M*)&ans[i];
M* key = (M*)&expkey[0];
trans(d); trans(key);
//PRINT
AddRoundKey(d, key);
//PRINT
for (int j = 1; j <= 9; j++) {
//字节替换
subBytes(d);
//PRINT
//行移位
shiftRows(d);
//PRINT
//列混淆
mixColumns(d);
//PRINT
//轮密钥加
key =(M*) &expkey[j << 2];
trans(key);
AddRoundKey(d, key);
//PRINT
}
//字节替换
subBytes(d);
//行移位
shiftRows(d);
//轮密钥加
key = (M*)&expkey[10 << 2];
trans(key);
AddRoundKey(d, key);
trans(d);
PRINT
}
return ans;
}
int main() {
g3();
gS(); cout << endl;
grS();
unsigned char a[2048] = "123asdfsafa4345kjasdf";
unsigned char keya[2048] = "aaaaaaaaaaaaaaaa";
uint32_t *pa = (uint32_t*)a;
uint32_t* pkeya = (uint32_t*)keya;
vector<uint32_t> data = {
pa[0],pa[1],pa[2],pa[3] };///ABCDEFGHIJKLMNOP
vector<uint32_t> key = {
pkeya[0],pkeya[1],pkeya[2],pkeya[3] };
auto expkey = expandKey(key);
auto ans = AES_128_en(data, expkey);
}