我正在尝试在MATLAB中实现PRESENT密码,但它没有正确加密和解密(我在解密后没有获得明文)。在测试了密码的每个部分,即子层,播放器,添加轮密钥和密钥更新后,我发现我的密钥更新不按预期的方式工作。使用的密钥是:'00000 00000 00000 00000',每轮的关键更新应该是:
Round key 1: 0000000000000000
Round key 2: c000000000000000
Round key 3: 5000180000000001
Round key 4: 60000a0003000001
Round key 5: b0000c0001400062
Round key 6: 900016000180002a
Round key 7: 0001920002c00033
Round key 8: a000a0003240005b
Round key 9: d000d4001400064c
Round key 10: 30017a001a800284
Round key 11: e01926002f400355
Round key 12: f00a1c0324c005ed
Round key 13: 800d5e014380649e
Round key 14: 4017b001abc02876
Round key 15: 71926802f600357f
Round key 16: 10a1ce324d005ec7
Round key 17: 20d5e21439c649a8
Round key 18: c17b041abc428730
Round key 19: c926b82f60835781
Round key 20: 6a1cd924d705ec19
Round key 21: bd5e0d439b249aea
Round key 22: 07b077abc1a8736e
Round key 23: 426ba0f60ef5783e
Round key 24: 41cda84d741ec1d5
Round key 25: f5e0e839b509ae8f
Round key 26: 2b075ebc1d0736ad
Round key 27: 86ba2560ebd783ad
Round key 28: 8cdab0d744ac1d77
Round key 29: 1e0eb19b561ae89b
Round key 30: d075c3c1d6336acd
Round key 31: 8ba27a0eb8783ac9
Round key 32: 6dab31744f41d700
但是我的代码每轮的关键更新是这样的:
'C0000000000000008000'
'50001800000000010000'
'60000A00030000018000'
'B0000C00014000620000'
'900016000180002A800C'
'0001920002C000330005'
'A000A0003240005B8006'
'D000D4001400064C000B'
'30017A001A80028480C9'
'E01926002F4003550050'
'F00A1C0324C005ED806A'
'800D5E014380649E00BD'
'4017B001ABC028768C93'
'71926802F600357F050E'
'10A1CE324D005EC786AF'
'20D5E21439C649A80BD8'
'C17B041ABC4287304935'
'C926B82F6083578150E6'
'6A1CD924D705EC19EAF0'
'BD5E0D439B249AEABD83'
'07B077ABC1A8736E135D'
'426BA0F60EF5783E0E6D'
'41CDA84D741EC1D52F07'
'F5E0E839B509AE8FD83A'
'2B075EBC1D0736ADB5D1'
'86BA2560EBD783ADE6D5'
'8CDAB0D744AC1D777075'
'1E0EB19B561AE89B83AE'
'D075C3C1D6336ACDDD13'
'8BA27A0EB8783AC96D59'
'6DAB31744F41D7008759'
'50EB2DB5662E89E83AE0'
我的密钥更新matlab代码是:
function thekeys = generatekeys(key)
torot = hexToBinaryVector(key,80);
for counter = 1:32
if counter == 1
rotate61 = [torot(1,62:80),torot(1,1:61)];
else
old = counter - 1;
rotate61 = [torot(old,62:80),torot(old,1:61)];
end
sbox_in = binaryVectorToHex([rotate61(1,1:4)]);
if sbox_in == '0'
sbox_out = 'C';
elseif sbox_in == '1'
sbox_out = '5';
elseif sbox_in == '2'
sbox_out = '6';
elseif sbox_in == '3'
sbox_out = 'B';
elseif sbox_in == '4'
sbox_out = '9';
elseif sbox_in == '5'
sbox_out = '0';
elseif sbox_in == '6'
sbox_out = 'A';
elseif sbox_in == '7'
sbox_out = 'D';
elseif sbox_in == '8'
sbox_out = '3';
elseif sbox_in == '9'
sbox_out = 'E';
elseif sbox_in == 'A'
sbox_out = 'F';
elseif sbox_in == 'B'
sbox_out = '8';
elseif sbox_in == 'C'
sbox_out = '4';
elseif sbox_in == 'D'
sbox_out = '7';
elseif sbox_in == 'E'
sbox_out = '1';
elseif sbox_in == 'F'
sbox_out = '2';
else
sbox_out = 'Z';
end
torot(counter,1:4) = hexToBinaryVector(sbox_out,4);
torot(counter,5:60) = rotate61(1,5:60);
count = dec2bin(counter,6);
b = logical(count(:)'-'0');
a = rotate61(1,61:65);
torot(counter,61:65) = bitxor(a,b(1,2:6));
torot(counter,66:80) = rotate61(1,66:80);
end
thekeys = torot;
disp (binaryVectorToHex(torot));
end
答案 0 :(得分:1)
我看了一下PRESENT分组密码的许多不同实现。以下Matlab代码应该产生您正在寻找的正确结果,通过我更喜欢使用按位方法而不是矢量化方法:
generatekeys('00000000000000000000');
function [kl,kr] = generatekeys(key)
sbox = [12, 5, 6, 11, 9, 0, 10, 13, 3, 14, 15, 8, 4, 7, 1, 2];
ul_15 = uint64(15);
ul_16mv = uint64(65535);
ul_2p60 = uint64(1152921504606846975);
kl = uint64(binaryVectorToDecimal(hexToBinaryVector(key(1:16))));
kr = uint64(binaryVectorToDecimal(hexToBinaryVector(key(17:end))));
for i = 0:31
kr_tmp = kr;
kr = bitand(bitshift(kl,-3),ul_16mv);
kl = bitor(bitor(bitshift(kl,61),bitshift(kr_tmp,45)),bitshift(kl,-19));
kl_tmp = kl;
kl = bitshift(sbox(bitand(bitshift(kl_tmp,-60),ul_15) + 1),60);
kl = bitor(kl,bitand(kl_tmp,ul_2p60));
t = bitand(uint64(i+1),uint64(31));
kl = bitxor(kl,bitshift(t,-1));
kr = bitxor(kr,bitshift(bitand(t,1),ul_15));
hex = binaryVectorToHex(decimalToBinaryVector(kl));
hex = [repmat('0',1,16-numel(hex)) hex];
disp(hex);
end
end
从迭代中排除第一轮密钥,输出为:
C000000000000000
5000180000000001
60000A0003000001
B0000C0001400062
900016000180002A
0001920002C00033
A000A0003240005B
D000D4001400064C
30017A001A800284
E01926002F400355
F00A1C0324C005ED
800D5E014380649E
4017B001ABC02876
71926802F600357F
10A1CE324D005EC7
20D5E21439C649A8
C17B041ABC428730
C926B82F60835781
6A1CD924D705EC19
BD5E0D439B249AEA
07B077ABC1A8736E
426BA0F60EF5783E
41CDA84D741EC1D5
F5E0E839B509AE8F
2B075EBC1D0736AD
86BA2560EBD783AD
8CDAB0D744AC1D77
1E0EB19B561AE89B
D075C3C1D6336ACD
8BA27A0EB8783AC9
6DAB31744F41D700
50EB2DB5662E89E8
长话短说(我不想过多介绍细节,因为从头开始编写代码花了我很长时间而且我没有详细注释所有内容)你的代码提出了有关索引和与两个关键部分的管理有关(第一部分是16
比特,第二部分是4
比特)。