1

i am trying to implement PRESENT cipher in MATLAB but its not encrypting and decrypting correctly (i am not getting the plaintext after decryption). After testing each part of the cipher i.e sub layer, player, add round key and key update, i found out that my key update is not working the way it is supposed too. The key used is: `'00000 00000 00000 00000' and the key updates for each round should be:

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

But the key updates for each round with my code is like this:

'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'

My matlab code for key update is:

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

1 Answers1

1

I gave a look at many different implementations of the PRESENT block cipher. The following Matlab code should produce the correct result you are looking for, althrough I preferred to use a bitwise approach instead of a vectorized one:

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

The first round key being excluded from the iteration, the output is:

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

Long story short (I don't want to enter too much into the details because writing the code from scratch took me long time and I didn't annotate everything in detail) your code presented problems concerning indexing and related to the management of the two key portions (the first one being of 16 bits and the second one consisting of 4 bits).

Tommaso Belluzzo
  • 23,232
  • 8
  • 74
  • 98