在 Matlab 中存储大小为 8 位 (uint8) 的变量值时出错
Error in storing variable values with size 8bits (uint8) in Matlab
我正在 Matlab 中实现一个 128 位 AES 加密算法,我正在基于 C 中的功能代码实现此代码,最大的问题是在 C 代码中所有变量都被定义为 unsigned char它更容易操作,在 MatLab 中我将所有变量声明为 uint8(unsingned integer 8 位),加密的一部分几乎准备就绪,但是我遇到了一个问题,我是 运行 代码并意识到一些值were sent wrong from the vector S-Box, debugging the Codes I found the problem, there is a moment without code that a letter below returns 我的值是255:
for i = 1 : 16
stateU(i)= sboxU(bitxor(stateU(i),keyU(i))+1);
end
这个函数负责通过S-box对应的值来改变裸数据的值,在C中用同样的函数来做这个改变,但是C中的向量从索引0开始转到 255,在 matlab 中,向量从索引 1 开始,一直到 256,这就是问题所在,当我的函数 returns 255 作为索引值时,由于索引值的这种差异,总是添加 +1 relation from C to MatLab, but how all variables are defined With 8-bit size, it is not possible to store the value of 256 in the variable, so the code stores 255, resulting the a wrong value in the variable.[=15 ] =]
预期的输出应该是(这是C中代码的正确输出,在for循环的第二次迭代后范围为1-16):
State[0] before shift: 207
State[1] before shift: 0
State[2] before shift: 152
State[3] before shift: 115
State[4] before shift: 237
State[5] before shift: 77
State[6] before shift: 148
State[7] before shift: 123
State[8] before shift: 22
State[9] before shift: 182
State[10] before shift: 122
State[11] before shift: 190
State[12] before shift: 130
State[13] before shift: 198
State[14] before shift: 29
State[15] before shift: 155
注意位置[8]是22,这个值是通过状态变量与变量key逐位异或得到的,如本文开头所说post,在C中变量被定义为 unsigned char,因此,值的大小没有问题。在 Matlab 中,我有以下输出:
State[0] before shift: 207
State[1] before shift: 0
State[2] before shift: 152
State[3] before shift: 115
State[4] before shift: 237
State[5] before shift: 77
State[6] before shift: 148
State[7] before shift: 123
State[8] before shift: 187
State[9] before shift: 182
State[10] before shift: 122
State[11] before shift: 190
State[12] before shift: 130
State[13] before shift: 198
State[14] before shift: 29
State[15] before shift: 155
注意向量在MatLab中的位置[8]有不同的值,由于变量的类型在MatLab中被定义为uint8,它最多只能存储255的值,理论上应该取S-box的第256位的值,但由于类型是uint8,所以它至少取一个位置的值(255 - 1111 1111),最多可以存储8位。
下面两段代码进行分析
Galois_mul2函数:
function galois_value = galois_mul2( value )
value = uint8(value);
temp = typecast(value, 'int8');
temp = bitshift(temp,-7);
hex = int8(hex2dec('1B'));
temp = bitand(temp,hex);
temp2 = typecast(bitshift(value,1),'int8');
galois_value = typecast(bitxor(temp2,temp),'uint8');
end
主要代码:
%Key
key = {'00','01','02','03','04','05','06','07','08','09','0a','0b','0c','0d','0e','0f'};
for n = 1 : 16
keyU(n)=uint8(hex2dec(key(n)));
end
%State
state = {'00','11','22','33','44','55','66','77','88','99','aa','bb','cc','dd','ee','ff'};
for n = 1 : 16
stateU(n)=uint8(hex2dec(state(n)));
end
%Sbox
sbox = {'63','7c','77','7b','f2','6b','6f','c5','30','01','67','2b','fe','d7','ab','76','ca','82','c9','7d','fa','59','47','f0','ad','d4','a2','af','9c','a4','72','c0','b7','fd','93','26','36','3f','f7','cc','34','a5','e5','f1','71','d8','31','15','04','c7','23','c3','18','96','05','9a','07','12','80','e2','eb','27','b2','75','09','83','2c','1a','1b','6e','5a','a0','52','3b','d6','b3','29','e3','2f','84','53','d1','00','ed','20','fc','b1','5b','6a','cb','be','39','4a','4c','58','cf','d0','ef','aa','fb','43','4d','33','85','45','f9','02','7f','50','3c','9f','a8','51','a3','40','8f','92','9d','38','f5','bc','b6','da','21','10','ff','f3','d2','cd','0c','13','ec','5f','97','44','17','c4','a7','7e','3d','64','5d','19','73','60','81','4f','dc','22','2a','90','88','46','ee','b8','14','de','5e','0b','db','e0','32','3a','0a','49','06','24','5c','c2','d3','ac','62','91','95','e4','79','e7','c8','37','6d','8d','d5','4e','a9','6c','56','f4','ea','65','7a','ae','08','ba','78','25','2e','1c','a6','b4','c6','e8','dd','74','1f','4b','bd','8b','8a','70','3e','b5','66','48','03','f6','0e','61','35','57','b9','86','c1','1d','9e','e1','f8','98','11','69','d9','8e','94','9b','1e','87','e9','ce','55','28','df','8c','a1','89','0d','bf','e6','42','68','41','99','2d','0f','b0','54','bb','16'};
for n = 1 : 256
sboxU(n)=uint8(hex2dec(sbox(n)));
end
%Rcon
rcon = {'01','02','04','08','10','20','40','80','1b','36'};
for n = 1 : 10
rconU(n)=uint8(hex2dec(rcon(n)));
end
%Main AES Data Loop
for round = 1 : 10
%Add key + sbox
for i = 1 : 16
stateU(i)= sboxU(bitxor(stateU(i),keyU(i))+1);
end
%Shift Rows
buf1 = stateU(2);
stateU(2) = stateU(6);
stateU(6) = stateU(10);
stateU(10) = stateU(14);
stateU(14) = buf1;
buf1 = stateU(3);
buf2 = stateU(7);
stateU(3) = stateU(11);
stateU(7) = stateU(15);
stateU(11) = buf1;
stateU(15) = buf2;
buf1 = stateU(16);
stateU(16) = stateU(12);
stateU(12) = stateU(8);
stateU(8) = stateU(4);
stateU(4) = buf1;
%Process mixcolumn for all rounds but the last one
if round < 10
for j = 0 : 3
%Compute the current index
buf4 = (bitshift(j,2));
%buf1
aux1 = bitxor(stateU(buf4+1),stateU(buf4+2));
aux2 = bitxor(stateU(buf4+3),stateU(buf4+4));
buf1 = bitxor(aux1,aux2);
%buf2
buf2 = stateU(buf4+1);
%buf3
buf3 = bitxor(stateU(buf4+1),stateU(buf4+2));
buf3 = galois_mul2(buf3);
%%%%%%%%%%%%%%%%%%%
aux = bitxor(stateU(buf4+1),buf3);
stateU(buf4+1) = bitxor (aux,buf1);
end
end
end
值得注意的是,当我发现错误时,我在for循环的第二次迭代中停止了调试,也就是说,显示的正确输出是for循环第二次迭代后的输出从 0-16 也被 posted 在 Top 中。在第一次迭代中,它起作用了,因为逐位 XOR 函数 returns 没有值大于 255 (1111 1111).
我已经尝试将所有变量更改为 uint16 但是代码不起作用,它说类型必须是标量或 2 的倍数。
问题是当您将 1
添加到 uint8
类型的 255
时,会发生溢出。
for i = 1 : 16
stateU(i)= sboxU(bitxor(stateU(i),keyU(i))+1);
end
由于你只是加1生成索引,与你的数据类型无关,你可以先将vector索引转换成更合适的数据类型再加1,这样可以避免溢出,而且你的数据未被触及,仍然是 uint8
。
for i = 1 : 16
stateU(i)= sboxU(double(bitxor(stateU(i),keyU(i)))+1);
end
关于数据类型的一些注意事项:虽然使用了到 double
(或任何可以容纳 256 的类型)的类型转换,但这并不意味着您正在以 [=14= 以外的其他类型存储任何数据].这只是Matlab的索引约定;事实上,在 C 中,你完全可以依赖 uint8
,因为 C 中的向量索引从 0 开始,所以最后一个索引将是 255
。
我正在 Matlab 中实现一个 128 位 AES 加密算法,我正在基于 C 中的功能代码实现此代码,最大的问题是在 C 代码中所有变量都被定义为 unsigned char它更容易操作,在 MatLab 中我将所有变量声明为 uint8(unsingned integer 8 位),加密的一部分几乎准备就绪,但是我遇到了一个问题,我是 运行 代码并意识到一些值were sent wrong from the vector S-Box, debugging the Codes I found the problem, there is a moment without code that a letter below returns 我的值是255:
for i = 1 : 16
stateU(i)= sboxU(bitxor(stateU(i),keyU(i))+1);
end
这个函数负责通过S-box对应的值来改变裸数据的值,在C中用同样的函数来做这个改变,但是C中的向量从索引0开始转到 255,在 matlab 中,向量从索引 1 开始,一直到 256,这就是问题所在,当我的函数 returns 255 作为索引值时,由于索引值的这种差异,总是添加 +1 relation from C to MatLab, but how all variables are defined With 8-bit size, it is not possible to store the value of 256 in the variable, so the code stores 255, resulting the a wrong value in the variable.[=15 ] =]
预期的输出应该是(这是C中代码的正确输出,在for循环的第二次迭代后范围为1-16):
State[0] before shift: 207
State[1] before shift: 0
State[2] before shift: 152
State[3] before shift: 115
State[4] before shift: 237
State[5] before shift: 77
State[6] before shift: 148
State[7] before shift: 123
State[8] before shift: 22
State[9] before shift: 182
State[10] before shift: 122
State[11] before shift: 190
State[12] before shift: 130
State[13] before shift: 198
State[14] before shift: 29
State[15] before shift: 155
注意位置[8]是22,这个值是通过状态变量与变量key逐位异或得到的,如本文开头所说post,在C中变量被定义为 unsigned char,因此,值的大小没有问题。在 Matlab 中,我有以下输出:
State[0] before shift: 207
State[1] before shift: 0
State[2] before shift: 152
State[3] before shift: 115
State[4] before shift: 237
State[5] before shift: 77
State[6] before shift: 148
State[7] before shift: 123
State[8] before shift: 187
State[9] before shift: 182
State[10] before shift: 122
State[11] before shift: 190
State[12] before shift: 130
State[13] before shift: 198
State[14] before shift: 29
State[15] before shift: 155
注意向量在MatLab中的位置[8]有不同的值,由于变量的类型在MatLab中被定义为uint8,它最多只能存储255的值,理论上应该取S-box的第256位的值,但由于类型是uint8,所以它至少取一个位置的值(255 - 1111 1111),最多可以存储8位。
下面两段代码进行分析
Galois_mul2函数:
function galois_value = galois_mul2( value )
value = uint8(value);
temp = typecast(value, 'int8');
temp = bitshift(temp,-7);
hex = int8(hex2dec('1B'));
temp = bitand(temp,hex);
temp2 = typecast(bitshift(value,1),'int8');
galois_value = typecast(bitxor(temp2,temp),'uint8');
end
主要代码:
%Key
key = {'00','01','02','03','04','05','06','07','08','09','0a','0b','0c','0d','0e','0f'};
for n = 1 : 16
keyU(n)=uint8(hex2dec(key(n)));
end
%State
state = {'00','11','22','33','44','55','66','77','88','99','aa','bb','cc','dd','ee','ff'};
for n = 1 : 16
stateU(n)=uint8(hex2dec(state(n)));
end
%Sbox
sbox = {'63','7c','77','7b','f2','6b','6f','c5','30','01','67','2b','fe','d7','ab','76','ca','82','c9','7d','fa','59','47','f0','ad','d4','a2','af','9c','a4','72','c0','b7','fd','93','26','36','3f','f7','cc','34','a5','e5','f1','71','d8','31','15','04','c7','23','c3','18','96','05','9a','07','12','80','e2','eb','27','b2','75','09','83','2c','1a','1b','6e','5a','a0','52','3b','d6','b3','29','e3','2f','84','53','d1','00','ed','20','fc','b1','5b','6a','cb','be','39','4a','4c','58','cf','d0','ef','aa','fb','43','4d','33','85','45','f9','02','7f','50','3c','9f','a8','51','a3','40','8f','92','9d','38','f5','bc','b6','da','21','10','ff','f3','d2','cd','0c','13','ec','5f','97','44','17','c4','a7','7e','3d','64','5d','19','73','60','81','4f','dc','22','2a','90','88','46','ee','b8','14','de','5e','0b','db','e0','32','3a','0a','49','06','24','5c','c2','d3','ac','62','91','95','e4','79','e7','c8','37','6d','8d','d5','4e','a9','6c','56','f4','ea','65','7a','ae','08','ba','78','25','2e','1c','a6','b4','c6','e8','dd','74','1f','4b','bd','8b','8a','70','3e','b5','66','48','03','f6','0e','61','35','57','b9','86','c1','1d','9e','e1','f8','98','11','69','d9','8e','94','9b','1e','87','e9','ce','55','28','df','8c','a1','89','0d','bf','e6','42','68','41','99','2d','0f','b0','54','bb','16'};
for n = 1 : 256
sboxU(n)=uint8(hex2dec(sbox(n)));
end
%Rcon
rcon = {'01','02','04','08','10','20','40','80','1b','36'};
for n = 1 : 10
rconU(n)=uint8(hex2dec(rcon(n)));
end
%Main AES Data Loop
for round = 1 : 10
%Add key + sbox
for i = 1 : 16
stateU(i)= sboxU(bitxor(stateU(i),keyU(i))+1);
end
%Shift Rows
buf1 = stateU(2);
stateU(2) = stateU(6);
stateU(6) = stateU(10);
stateU(10) = stateU(14);
stateU(14) = buf1;
buf1 = stateU(3);
buf2 = stateU(7);
stateU(3) = stateU(11);
stateU(7) = stateU(15);
stateU(11) = buf1;
stateU(15) = buf2;
buf1 = stateU(16);
stateU(16) = stateU(12);
stateU(12) = stateU(8);
stateU(8) = stateU(4);
stateU(4) = buf1;
%Process mixcolumn for all rounds but the last one
if round < 10
for j = 0 : 3
%Compute the current index
buf4 = (bitshift(j,2));
%buf1
aux1 = bitxor(stateU(buf4+1),stateU(buf4+2));
aux2 = bitxor(stateU(buf4+3),stateU(buf4+4));
buf1 = bitxor(aux1,aux2);
%buf2
buf2 = stateU(buf4+1);
%buf3
buf3 = bitxor(stateU(buf4+1),stateU(buf4+2));
buf3 = galois_mul2(buf3);
%%%%%%%%%%%%%%%%%%%
aux = bitxor(stateU(buf4+1),buf3);
stateU(buf4+1) = bitxor (aux,buf1);
end
end
end
值得注意的是,当我发现错误时,我在for循环的第二次迭代中停止了调试,也就是说,显示的正确输出是for循环第二次迭代后的输出从 0-16 也被 posted 在 Top 中。在第一次迭代中,它起作用了,因为逐位 XOR 函数 returns 没有值大于 255 (1111 1111).
我已经尝试将所有变量更改为 uint16 但是代码不起作用,它说类型必须是标量或 2 的倍数。
问题是当您将 1
添加到 uint8
类型的 255
时,会发生溢出。
for i = 1 : 16
stateU(i)= sboxU(bitxor(stateU(i),keyU(i))+1);
end
由于你只是加1生成索引,与你的数据类型无关,你可以先将vector索引转换成更合适的数据类型再加1,这样可以避免溢出,而且你的数据未被触及,仍然是 uint8
。
for i = 1 : 16
stateU(i)= sboxU(double(bitxor(stateU(i),keyU(i)))+1);
end
关于数据类型的一些注意事项:虽然使用了到 double
(或任何可以容纳 256 的类型)的类型转换,但这并不意味着您正在以 [=14= 以外的其他类型存储任何数据].这只是Matlab的索引约定;事实上,在 C 中,你完全可以依赖 uint8
,因为 C 中的向量索引从 0 开始,所以最后一个索引将是 255
。