Advertisement
Guest User

Untitled

a guest
Dec 12th, 2016
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
D 8.70 KB | None | 0 0
  1. import std.stdio;
  2. import std.conv;
  3. import std.bitmanip;
  4. import std.format : format;
  5. import std.algorithm.iteration;
  6. import std.array;
  7. import std.math;
  8. import std.format, std.random;
  9. import std.range;
  10. import std.algorithm.comparison : equal;
  11. import std.traits;
  12. import std.typecons;
  13.  
  14. //конвертировать число в строку в 16ной системе счисления
  15. alias toHex = toChars!(16,char,LetterCase.upper, ulong);
  16.  
  17. //блок из 8 байт для DES
  18. alias block = char[16];
  19.  
  20. auto bin2char = function char(bool x) { return x ? '1' : '0'; };
  21.  
  22. pure T[] shr(T)(T[] arr, ulong shift) {
  23.     shift %= arr.length;
  24.     return arr[shift..$] ~ arr[0..shift];
  25. }
  26.  
  27. pure block[] getBlocks(string msg) {
  28.     //количество блоков по 8 байт (16 символов)
  29.     auto count = to!size_t(ceil(2 * msg.length / to!double(block.length)));
  30.    
  31.     msg ~= array(to!char(0x0).repeat.take(8 * count - msg.length));
  32.    
  33.     block[] result = new block[count];
  34.    
  35.     foreach (int i, ref t; result) {
  36.         // текущая часть сообщения длиной 8 байт
  37.         auto str = msg[8*i .. 8*i+8];
  38.        
  39.         // получаем массив цифр в 16-ном формате
  40.         t = reduce!((a,b) => a ~ toHex(b >> 4)[0] ~ toHex(b & 0xF)[0])(new char[0], str);
  41.     }
  42.    
  43.     return result;
  44. }
  45.  
  46. unittest {
  47.     string msg = "Your lips are smoother than vaseline\r\n";
  48.     block[] blocks = ["596F7572206C6970", "732061726520736D", "6F6F746865722074", "68616E2076617365", "6C696E650D0A0000"];
  49.     assert(getBlocks(msg) == blocks);
  50. }
  51.  
  52. pure bool[48] subkey(in bool[64] key, int n) {
  53.    
  54.     // таблица изначальной перестановки ключа
  55.     immutable(immutable byte)[56] PC1 = [
  56.         56, 48, 40, 32, 24, 16,  8,
  57.          0, 57, 49, 41, 33, 25, 17,
  58.          9,  1, 58, 50, 42, 34, 26,
  59.         18, 10,  2, 59, 51, 43, 35,
  60.         62, 54, 46, 38, 30, 22, 14,
  61.          6, 61, 53, 45, 37, 29, 21,
  62.         13,  5, 60, 52, 44, 36, 28,
  63.         20, 12,  4, 27, 19, 11,  3
  64.     ];
  65.    
  66.     // получить 56-битный К+ по таблице перестановок
  67.     immutable(immutable bool)[56] K = indexed(cast(bool[]) key, cast(byte[]) PC1).array;
  68.    
  69.     // необходимый битовый сдвиг по таблице
  70.     immutable int shift = [1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28][n];
  71.    
  72.     // левая смещенная часть К+
  73.     immutable(immutable bool)[28] C = K[0..$/2].shr(shift);
  74.    
  75.     // правая смещенная часть К+
  76.     immutable(immutable bool)[28] D = K[$/2..$].shr(shift);
  77.    
  78.     // таблица конечной перестановки подключа
  79.     immutable(immutable byte)[48] PC2 = [
  80.         13, 16, 10, 23,  0,  4,
  81.          2, 27, 14,  5, 20,  9,
  82.         22, 18, 11,  3, 25,  7,
  83.         15,  6, 26, 19, 12,  1,
  84.         40, 51, 30, 36, 46, 54,
  85.         29, 39, 50, 44, 32, 47,
  86.         43, 48, 38, 55, 33, 52,
  87.         45, 41, 49, 35, 28, 31
  88.     ];
  89.    
  90.     immutable(immutable bool)[48] Kn = indexed(C ~ D, cast(byte[]) PC2).array;
  91.    
  92.     return Kn;
  93. }
  94.  
  95. pure bool[32] f(in bool[32] Rprev, in bool[48] Kn) {   
  96.     immutable(immutable byte)[16][4] S1 = [
  97.         [14,  4, 13, 1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9, 0,  7],
  98.         [ 0, 15,  7, 4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5, 3,  8],
  99.         [ 4,  1, 14, 8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10, 5,  0],
  100.         [15, 12,  8, 2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0, 6, 13]
  101.     ];
  102.    
  103.     immutable(immutable byte)[16][4] S2 = [
  104.         [15,  1,  8, 14,  6, 11,  3,  4,  9, 7,  2, 13, 12, 0,  5, 10],
  105.         [ 3, 13,  4,  7, 15,  2,  8, 14, 12, 0,  1, 10,  6, 9, 11,  5],
  106.         [ 0, 14,  7, 11, 10,  4, 13,  1,  5, 8, 12,  6,  9, 3,  2, 15],
  107.         [13,  8, 10,  1,  3, 15,  4,  2, 11, 6,  7, 12,  0, 5, 14,  9]
  108.     ];
  109.    
  110.     immutable(immutable byte)[16][4] S3 = [
  111.         [10,  0,  9, 14, 6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8],
  112.         [13,  7,  0,  9, 3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1],
  113.         [13,  6,  4,  9, 8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7],
  114.         [ 1, 10, 13,  0, 6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12]
  115.     ];
  116.    
  117.     immutable(immutable byte)[16][4] S4 = [
  118.         [ 7, 13, 14, 3,  0,  6,  9, 10,  1, 2, 8,  5, 11, 12,  4, 15],
  119.         [13,  8, 11, 5,  6, 15,  0,  3,  4, 7, 2, 12,  1, 10, 14,  9],
  120.         [10,  6,  9, 0, 12, 11,  7, 13, 15, 1, 3, 14,  5,  2,  8,  4],
  121.         [ 3, 15,  0, 6, 10,  1, 13,  8,  9, 4, 5, 11, 12,  7,  2, 14]
  122.     ];
  123.    
  124.     immutable(immutable byte)[16][4] S5 = [
  125.         [ 2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13, 0, 14,  9],
  126.         [14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3, 9,  8,  6],
  127.         [ 4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6, 3,  0, 14],
  128.         [11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10, 4,  5,  3]
  129.     ];
  130.    
  131.     immutable(immutable byte)[16][4] S6 = [
  132.         [12,  1, 10, 15, 9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11],
  133.         [10, 15,  4,  2, 7, 12,  6,  5,  6,  1, 13, 14,  0, 11,  3,  8],
  134.         [ 9, 14, 15,  5, 2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6],
  135.         [ 4,  3,  2, 12, 9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13]
  136.     ];
  137.    
  138.     immutable(immutable byte)[16][4] S7 = [
  139.         [ 4, 11,  2, 14, 15, 0,  8, 13,  3, 12, 9,  7,  5, 10, 6,  1],
  140.         [13,  0, 11,  7,  4, 9,  1, 10, 14,  3, 5, 12,  2, 15, 8,  6],
  141.         [ 1,  4, 11, 13, 12, 3,  7, 14, 10, 15, 6,  8,  0,  5, 9,  2],
  142.         [ 6, 11, 13,  8,  1, 4, 10,  7,  9,  5, 0, 15, 14,  2, 3, 12]
  143.     ];
  144.    
  145.     immutable(immutable byte)[16][4] S8 = [
  146.         [13,  2,  8, 4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7],
  147.         [ 1, 15, 13, 8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2],
  148.         [ 7, 11,  4, 1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8],
  149.         [ 2,  1, 14, 7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11]
  150.     ];
  151.    
  152.     immutable(immutable byte)[48] E = [
  153.         31,  0,  1,  2,  3,  4,
  154.          3,  4,  5,  6,  7,  8,
  155.          7,  8,  9, 10, 11, 12,
  156.         11, 12, 13, 14, 15, 16,
  157.         15, 16, 17, 18, 19, 20,
  158.         19, 20, 21, 22, 23, 24,
  159.         23, 24, 25, 26, 27, 28,
  160.         27, 28, 29, 30, 31,  0
  161.     ];
  162.    
  163.     //таблица для перевода числа 0..15 в двоичный вид (массив из 4х битов)
  164.     immutable(immutable bool)[4][16] dec2bin = [
  165.         [0,0,0,0], [0,0,0,1], [0,0,1,0], [0,0,1,1],
  166.         [0,1,0,0], [0,1,0,1], [0,1,1,0], [0,1,1,1],
  167.         [1,0,0,0], [1,0,0,1], [1,0,1,0], [1,0,1,1],
  168.         [1,1,0,0], [1,1,0,1], [1,1,1,0], [1,1,1,1]
  169.     ];
  170.    
  171.     pure bool[] S(in bool[] B, in byte[16][4] table) {
  172.         ubyte i = 2*cast(byte)B[0] + 1*cast(byte)B[5];
  173.         ubyte j = 8*cast(byte)B[1] + 4*cast(byte)B[2] + 2*cast(byte)B[3] + 1*cast(byte)B[4];
  174.        
  175.         return cast(bool[]) dec2bin[table[i][j]];
  176.     }
  177.    
  178.     immutable(immutable bool)[48] ER = indexed(cast(bool[]) Rprev, cast(byte[]) E).array;
  179.    
  180.     bool[48] Bn = new bool[48];
  181.     Bn[] = ER[] ^ Kn[];
  182.    
  183.     immutable(immutable bool)[32] result = (cast(bool[])Bn).chunks(6).zip([S1, S2, S3, S4, S5, S6, S7, S8]).map!(x => S(x[0], x[1])).join;
  184.    
  185.     immutable(immutable byte)[32] P = [
  186.         15,  6, 19, 20,
  187.         28, 11, 27, 16,
  188.          0, 14, 22, 25,
  189.          4, 17, 30,  9,
  190.          1,  7, 23, 13,
  191.         31, 26,  2,  8,
  192.         18, 12, 29,  5,
  193.         21, 10,  3, 24
  194.     ];
  195.    
  196.     return indexed(cast(bool[]) result, cast(byte[]) P).array.to!(bool[32]);
  197. }
  198.  
  199. void main(string[] arg) {
  200.    
  201.     immutable(immutable bool)[64] key = [
  202.         0, 0, 0, 1, 0, 0, 1, 1,
  203.         0, 0, 1, 1, 0, 1, 0, 0,
  204.         0, 1, 0, 1, 0, 1, 1, 1,
  205.         0, 1, 1, 1, 1, 0, 0, 1,
  206.         1, 0, 0, 1, 1, 0, 1, 1,
  207.         1, 0, 1, 1, 1, 1, 0, 0,
  208.         1, 1, 0, 1, 1, 1, 1, 1,
  209.         1, 1, 1, 1, 0, 0, 0, 1
  210.     ];
  211.    
  212.     immutable(immutable bool)[64] M = [
  213.         0, 0, 0, 0, 0, 0, 0, 1,
  214.         0, 0, 1, 0, 0, 0, 1, 1,
  215.         0, 1, 0, 0, 0, 1, 0, 1,
  216.         0, 1, 1, 0, 0, 1, 1, 1,
  217.         1, 0, 0, 0, 1, 0, 0, 1,
  218.         1, 0, 1, 0, 1, 0, 1, 1,
  219.         1, 1, 0, 0, 1, 1, 0, 1,
  220.         1, 1, 1, 0, 1, 1, 1, 1
  221.     ];
  222.    
  223.     immutable(immutable byte)[64] IP = [
  224.         57, 49, 41, 33, 25, 17,  9, 1,
  225.         59, 51, 43, 35, 27, 19, 11, 3,
  226.         61, 53, 45, 37, 29, 21, 13, 5,
  227.         63, 55, 47, 39, 31, 23, 15, 7,
  228.         56, 48, 40, 32, 24, 16,  8, 0,
  229.         58, 50, 42, 34, 26, 18, 10, 2,
  230.         60, 52, 44, 36, 28, 20, 12, 4,
  231.         62, 54, 46, 38, 30, 22, 14, 6
  232.     ];
  233.    
  234.     immutable(immutable bool)[64] msg = indexed(cast(bool[]) M, cast(byte[]) IP).array;
  235.    
  236.     bool[32] Lprev = msg[0..$/2];
  237.     bool[32] Rprev = msg[$/2..$];
  238.    
  239.     pure bool[64] step(in bool[32] Lprev, in bool[32] Rprev, uint n) {
  240.         bool[48] Kn = subkey(key, n);
  241.         bool[32] Lcur = Rprev;
  242.         bool[32] Rcur = new bool[32];
  243.         Rcur[] = Lprev[] ^ f(Rprev, Kn)[];
  244.        
  245.         bool[64] result = Lcur ~ Rcur;
  246.        
  247.         return result;
  248.     }
  249.    
  250.     for (int n=0; n<16; ++n) {
  251.         auto cur = step(Lprev, Rprev, n);
  252.         Lprev = cur[0..$/2];
  253.         Rprev = cur[$/2..$];
  254.     }
  255.    
  256.     immutable(immutable byte)[64] LP = [
  257.         39, 7, 47, 15, 55, 23, 63, 31,
  258.         38, 6, 46, 14, 54, 22, 62, 30,
  259.         37, 5, 45, 13, 53, 21, 61, 29,
  260.         36, 4, 44, 12, 52, 20, 60, 28,
  261.         35, 3, 43, 11, 51, 19, 59, 27,
  262.         34, 2, 42, 10, 50, 18, 58, 26,
  263.         33, 1, 41,  9, 49, 17, 57, 25,
  264.         32, 0, 40,  8, 48, 16, 56, 24
  265.     ];
  266.    
  267.     bool[64] result = indexed(Rprev ~ Lprev, cast(byte[]) LP).array;
  268.    
  269.     (cast(bool[]) result).map!bin2char.chunks(8).join(' ').writeln;
  270. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement