Advertisement
Guest User

Ukrainian/xUSSR Gost Hash implementation

a guest
Jul 13th, 2016
145
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 23.48 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdint.h>
  3. #include <stdlib.h>
  4. #include <sys/time.h>
  5. #include <string.h>
  6.  
  7. typedef struct {
  8.     unsigned int sum[8];
  9.     unsigned int hash[8];
  10.     unsigned int len[8];
  11.     unsigned char partial[32];
  12.     unsigned int partial_bytes;
  13. } GostHashCtx;
  14.  
  15. static const unsigned int gost_sbox_1[256] = {
  16.  
  17.     0x72000UL, 0x75000UL, 0x74800UL, 0x71000UL, 0x76800UL,
  18.     0x74000UL, 0x70000UL, 0x77000UL, 0x73000UL, 0x75800UL,
  19.     0x70800UL, 0x76000UL, 0x73800UL, 0x77800UL, 0x72800UL,
  20.     0x71800UL, 0x5A000UL, 0x5D000UL, 0x5C800UL, 0x59000UL,
  21.     0x5E800UL, 0x5C000UL, 0x58000UL, 0x5F000UL, 0x5B000UL,
  22.     0x5D800UL, 0x58800UL, 0x5E000UL, 0x5B800UL, 0x5F800UL,
  23.     0x5A800UL, 0x59800UL, 0x22000UL, 0x25000UL, 0x24800UL,
  24.     0x21000UL, 0x26800UL, 0x24000UL, 0x20000UL, 0x27000UL,
  25.     0x23000UL, 0x25800UL, 0x20800UL, 0x26000UL, 0x23800UL,
  26.     0x27800UL, 0x22800UL, 0x21800UL, 0x62000UL, 0x65000UL,
  27.     0x64800UL, 0x61000UL, 0x66800UL, 0x64000UL, 0x60000UL,
  28.     0x67000UL, 0x63000UL, 0x65800UL, 0x60800UL, 0x66000UL,
  29.     0x63800UL, 0x67800UL, 0x62800UL, 0x61800UL, 0x32000UL,
  30.     0x35000UL, 0x34800UL, 0x31000UL, 0x36800UL, 0x34000UL,
  31.     0x30000UL, 0x37000UL, 0x33000UL, 0x35800UL, 0x30800UL,
  32.     0x36000UL, 0x33800UL, 0x37800UL, 0x32800UL, 0x31800UL,
  33.     0x6A000UL, 0x6D000UL, 0x6C800UL, 0x69000UL, 0x6E800UL,
  34.     0x6C000UL, 0x68000UL, 0x6F000UL, 0x6B000UL, 0x6D800UL,
  35.     0x68800UL, 0x6E000UL, 0x6B800UL, 0x6F800UL, 0x6A800UL,
  36.     0x69800UL, 0x7A000UL, 0x7D000UL, 0x7C800UL, 0x79000UL,
  37.     0x7E800UL, 0x7C000UL, 0x78000UL, 0x7F000UL, 0x7B000UL,
  38.     0x7D800UL, 0x78800UL, 0x7E000UL, 0x7B800UL, 0x7F800UL,
  39.     0x7A800UL, 0x79800UL, 0x52000UL, 0x55000UL, 0x54800UL,
  40.     0x51000UL, 0x56800UL, 0x54000UL, 0x50000UL, 0x57000UL,
  41.     0x53000UL, 0x55800UL, 0x50800UL, 0x56000UL, 0x53800UL,
  42.     0x57800UL, 0x52800UL, 0x51800UL, 0x12000UL, 0x15000UL,
  43.     0x14800UL, 0x11000UL, 0x16800UL, 0x14000UL, 0x10000UL,
  44.     0x17000UL, 0x13000UL, 0x15800UL, 0x10800UL, 0x16000UL,
  45.     0x13800UL, 0x17800UL, 0x12800UL, 0x11800UL, 0x1A000UL,
  46.     0x1D000UL, 0x1C800UL, 0x19000UL, 0x1E800UL, 0x1C000UL,
  47.     0x18000UL, 0x1F000UL, 0x1B000UL, 0x1D800UL, 0x18800UL,
  48.     0x1E000UL, 0x1B800UL, 0x1F800UL, 0x1A800UL, 0x19800UL,
  49.     0x42000UL, 0x45000UL, 0x44800UL, 0x41000UL, 0x46800UL,
  50.     0x44000UL, 0x40000UL, 0x47000UL, 0x43000UL, 0x45800UL,
  51.     0x40800UL, 0x46000UL, 0x43800UL, 0x47800UL, 0x42800UL,
  52.     0x41800UL, 0xA000UL,  0xD000UL,  0xC800UL,  0x9000UL,
  53.     0xE800UL,  0xC000UL,  0x8000UL,  0xF000UL,  0xB000UL,
  54.     0xD800UL,  0x8800UL,  0xE000UL,  0xB800UL,  0xF800UL,
  55.     0xA800UL,  0x9800UL,  0x2000UL,  0x5000UL,  0x4800UL,
  56.     0x1000UL,  0x6800UL,  0x4000UL,  0x0UL,     0x7000UL,
  57.     0x3000UL,  0x5800UL,  0x800UL,   0x6000UL,  0x3800UL,
  58.     0x7800UL,  0x2800UL,  0x1800UL,  0x3A000UL, 0x3D000UL,
  59.     0x3C800UL, 0x39000UL, 0x3E800UL, 0x3C000UL, 0x38000UL,
  60.     0x3F000UL, 0x3B000UL, 0x3D800UL, 0x38800UL, 0x3E000UL,
  61.     0x3B800UL, 0x3F800UL, 0x3A800UL, 0x39800UL, 0x2A000UL,
  62.     0x2D000UL, 0x2C800UL, 0x29000UL, 0x2E800UL, 0x2C000UL,
  63.     0x28000UL, 0x2F000UL, 0x2B000UL, 0x2D800UL, 0x28800UL,
  64.     0x2E000UL, 0x2B800UL, 0x2F800UL, 0x2A800UL, 0x29800UL,
  65.     0x4A000UL, 0x4D000UL, 0x4C800UL, 0x49000UL, 0x4E800UL,
  66.     0x4C000UL, 0x48000UL, 0x4F000UL, 0x4B000UL, 0x4D800UL,
  67.     0x48800UL, 0x4E000UL, 0x4B800UL, 0x4F800UL, 0x4A800UL,
  68.     0x49800UL,
  69. };
  70. static const unsigned int gost_sbox_2[256] = {
  71.  
  72.     0x3A80000UL, 0x3C00000UL, 0x3880000UL, 0x3E80000UL, 0x3D00000UL,
  73.     0x3980000UL, 0x3A00000UL, 0x3900000UL, 0x3F00000UL, 0x3F80000UL,
  74.     0x3E00000UL, 0x3B80000UL, 0x3B00000UL, 0x3800000UL, 0x3C80000UL,
  75.     0x3D80000UL, 0x6A80000UL, 0x6C00000UL, 0x6880000UL, 0x6E80000UL,
  76.     0x6D00000UL, 0x6980000UL, 0x6A00000UL, 0x6900000UL, 0x6F00000UL,
  77.     0x6F80000UL, 0x6E00000UL, 0x6B80000UL, 0x6B00000UL, 0x6800000UL,
  78.     0x6C80000UL, 0x6D80000UL, 0x5280000UL, 0x5400000UL, 0x5080000UL,
  79.     0x5680000UL, 0x5500000UL, 0x5180000UL, 0x5200000UL, 0x5100000UL,
  80.     0x5700000UL, 0x5780000UL, 0x5600000UL, 0x5380000UL, 0x5300000UL,
  81.     0x5000000UL, 0x5480000UL, 0x5580000UL, 0xA80000UL,  0xC00000UL,
  82.     0x880000UL,  0xE80000UL,  0xD00000UL,  0x980000UL,  0xA00000UL,
  83.     0x900000UL,  0xF00000UL,  0xF80000UL,  0xE00000UL,  0xB80000UL,
  84.     0xB00000UL,  0x800000UL,  0xC80000UL,  0xD80000UL,  0x280000UL,
  85.     0x400000UL,  0x80000UL,   0x680000UL,  0x500000UL,  0x180000UL,
  86.     0x200000UL,  0x100000UL,  0x700000UL,  0x780000UL,  0x600000UL,
  87.     0x380000UL,  0x300000UL,  0x0UL,       0x480000UL,  0x580000UL,
  88.     0x4280000UL, 0x4400000UL, 0x4080000UL, 0x4680000UL, 0x4500000UL,
  89.     0x4180000UL, 0x4200000UL, 0x4100000UL, 0x4700000UL, 0x4780000UL,
  90.     0x4600000UL, 0x4380000UL, 0x4300000UL, 0x4000000UL, 0x4480000UL,
  91.     0x4580000UL, 0x4A80000UL, 0x4C00000UL, 0x4880000UL, 0x4E80000UL,
  92.     0x4D00000UL, 0x4980000UL, 0x4A00000UL, 0x4900000UL, 0x4F00000UL,
  93.     0x4F80000UL, 0x4E00000UL, 0x4B80000UL, 0x4B00000UL, 0x4800000UL,
  94.     0x4C80000UL, 0x4D80000UL, 0x7A80000UL, 0x7C00000UL, 0x7880000UL,
  95.     0x7E80000UL, 0x7D00000UL, 0x7980000UL, 0x7A00000UL, 0x7900000UL,
  96.     0x7F00000UL, 0x7F80000UL, 0x7E00000UL, 0x7B80000UL, 0x7B00000UL,
  97.     0x7800000UL, 0x7C80000UL, 0x7D80000UL, 0x7280000UL, 0x7400000UL,
  98.     0x7080000UL, 0x7680000UL, 0x7500000UL, 0x7180000UL, 0x7200000UL,
  99.     0x7100000UL, 0x7700000UL, 0x7780000UL, 0x7600000UL, 0x7380000UL,
  100.     0x7300000UL, 0x7000000UL, 0x7480000UL, 0x7580000UL, 0x2280000UL,
  101.     0x2400000UL, 0x2080000UL, 0x2680000UL, 0x2500000UL, 0x2180000UL,
  102.     0x2200000UL, 0x2100000UL, 0x2700000UL, 0x2780000UL, 0x2600000UL,
  103.     0x2380000UL, 0x2300000UL, 0x2000000UL, 0x2480000UL, 0x2580000UL,
  104.     0x3280000UL, 0x3400000UL, 0x3080000UL, 0x3680000UL, 0x3500000UL,
  105.     0x3180000UL, 0x3200000UL, 0x3100000UL, 0x3700000UL, 0x3780000UL,
  106.     0x3600000UL, 0x3380000UL, 0x3300000UL, 0x3000000UL, 0x3480000UL,
  107.     0x3580000UL, 0x6280000UL, 0x6400000UL, 0x6080000UL, 0x6680000UL,
  108.     0x6500000UL, 0x6180000UL, 0x6200000UL, 0x6100000UL, 0x6700000UL,
  109.     0x6780000UL, 0x6600000UL, 0x6380000UL, 0x6300000UL, 0x6000000UL,
  110.     0x6480000UL, 0x6580000UL, 0x5A80000UL, 0x5C00000UL, 0x5880000UL,
  111.     0x5E80000UL, 0x5D00000UL, 0x5980000UL, 0x5A00000UL, 0x5900000UL,
  112.     0x5F00000UL, 0x5F80000UL, 0x5E00000UL, 0x5B80000UL, 0x5B00000UL,
  113.     0x5800000UL, 0x5C80000UL, 0x5D80000UL, 0x1280000UL, 0x1400000UL,
  114.     0x1080000UL, 0x1680000UL, 0x1500000UL, 0x1180000UL, 0x1200000UL,
  115.     0x1100000UL, 0x1700000UL, 0x1780000UL, 0x1600000UL, 0x1380000UL,
  116.     0x1300000UL, 0x1000000UL, 0x1480000UL, 0x1580000UL, 0x2A80000UL,
  117.     0x2C00000UL, 0x2880000UL, 0x2E80000UL, 0x2D00000UL, 0x2980000UL,
  118.     0x2A00000UL, 0x2900000UL, 0x2F00000UL, 0x2F80000UL, 0x2E00000UL,
  119.     0x2B80000UL, 0x2B00000UL, 0x2800000UL, 0x2C80000UL, 0x2D80000UL,
  120.     0x1A80000UL, 0x1C00000UL, 0x1880000UL, 0x1E80000UL, 0x1D00000UL,
  121.     0x1980000UL, 0x1A00000UL, 0x1900000UL, 0x1F00000UL, 0x1F80000UL,
  122.     0x1E00000UL, 0x1B80000UL, 0x1B00000UL, 0x1800000UL, 0x1C80000UL,
  123.     0x1D80000UL,
  124. };
  125. static const unsigned int gost_sbox_3[256] = {
  126.  
  127.     0x30000002UL, 0x60000002UL, 0x38000002UL, 0x8000002UL,
  128.     0x28000002UL, 0x78000002UL, 0x68000002UL, 0x40000002UL,
  129.     0x20000002UL, 0x50000002UL, 0x48000002UL, 0x70000002UL,
  130.     0x2UL,        0x18000002UL, 0x58000002UL, 0x10000002UL,
  131.     0xB0000005UL, 0xE0000005UL, 0xB8000005UL, 0x88000005UL,
  132.     0xA8000005UL, 0xF8000005UL, 0xE8000005UL, 0xC0000005UL,
  133.     0xA0000005UL, 0xD0000005UL, 0xC8000005UL, 0xF0000005UL,
  134.     0x80000005UL, 0x98000005UL, 0xD8000005UL, 0x90000005UL,
  135.     0x30000005UL, 0x60000005UL, 0x38000005UL, 0x8000005UL,
  136.     0x28000005UL, 0x78000005UL, 0x68000005UL, 0x40000005UL,
  137.     0x20000005UL, 0x50000005UL, 0x48000005UL, 0x70000005UL,
  138.     0x5UL,        0x18000005UL, 0x58000005UL, 0x10000005UL,
  139.     0x30000000UL, 0x60000000UL, 0x38000000UL, 0x8000000UL,
  140.     0x28000000UL, 0x78000000UL, 0x68000000UL, 0x40000000UL,
  141.     0x20000000UL, 0x50000000UL, 0x48000000UL, 0x70000000UL,
  142.     0x0UL,        0x18000000UL, 0x58000000UL, 0x10000000UL,
  143.     0xB0000003UL, 0xE0000003UL, 0xB8000003UL, 0x88000003UL,
  144.     0xA8000003UL, 0xF8000003UL, 0xE8000003UL, 0xC0000003UL,
  145.     0xA0000003UL, 0xD0000003UL, 0xC8000003UL, 0xF0000003UL,
  146.     0x80000003UL, 0x98000003UL, 0xD8000003UL, 0x90000003UL,
  147.     0x30000001UL, 0x60000001UL, 0x38000001UL, 0x8000001UL,
  148.     0x28000001UL, 0x78000001UL, 0x68000001UL, 0x40000001UL,
  149.     0x20000001UL, 0x50000001UL, 0x48000001UL, 0x70000001UL,
  150.     0x1UL,        0x18000001UL, 0x58000001UL, 0x10000001UL,
  151.     0xB0000000UL, 0xE0000000UL, 0xB8000000UL, 0x88000000UL,
  152.     0xA8000000UL, 0xF8000000UL, 0xE8000000UL, 0xC0000000UL,
  153.     0xA0000000UL, 0xD0000000UL, 0xC8000000UL, 0xF0000000UL,
  154.     0x80000000UL, 0x98000000UL, 0xD8000000UL, 0x90000000UL,
  155.     0xB0000006UL, 0xE0000006UL, 0xB8000006UL, 0x88000006UL,
  156.     0xA8000006UL, 0xF8000006UL, 0xE8000006UL, 0xC0000006UL,
  157.     0xA0000006UL, 0xD0000006UL, 0xC8000006UL, 0xF0000006UL,
  158.     0x80000006UL, 0x98000006UL, 0xD8000006UL, 0x90000006UL,
  159.     0xB0000001UL, 0xE0000001UL, 0xB8000001UL, 0x88000001UL,
  160.     0xA8000001UL, 0xF8000001UL, 0xE8000001UL, 0xC0000001UL,
  161.     0xA0000001UL, 0xD0000001UL, 0xC8000001UL, 0xF0000001UL,
  162.     0x80000001UL, 0x98000001UL, 0xD8000001UL, 0x90000001UL,
  163.     0x30000003UL, 0x60000003UL, 0x38000003UL, 0x8000003UL,
  164.     0x28000003UL, 0x78000003UL, 0x68000003UL, 0x40000003UL,
  165.     0x20000003UL, 0x50000003UL, 0x48000003UL, 0x70000003UL,
  166.     0x3UL,        0x18000003UL, 0x58000003UL, 0x10000003UL,
  167.     0x30000004UL, 0x60000004UL, 0x38000004UL, 0x8000004UL,
  168.     0x28000004UL, 0x78000004UL, 0x68000004UL, 0x40000004UL,
  169.     0x20000004UL, 0x50000004UL, 0x48000004UL, 0x70000004UL,
  170.     0x4UL,        0x18000004UL, 0x58000004UL, 0x10000004UL,
  171.     0xB0000002UL, 0xE0000002UL, 0xB8000002UL, 0x88000002UL,
  172.     0xA8000002UL, 0xF8000002UL, 0xE8000002UL, 0xC0000002UL,
  173.     0xA0000002UL, 0xD0000002UL, 0xC8000002UL, 0xF0000002UL,
  174.     0x80000002UL, 0x98000002UL, 0xD8000002UL, 0x90000002UL,
  175.     0xB0000004UL, 0xE0000004UL, 0xB8000004UL, 0x88000004UL,
  176.     0xA8000004UL, 0xF8000004UL, 0xE8000004UL, 0xC0000004UL,
  177.     0xA0000004UL, 0xD0000004UL, 0xC8000004UL, 0xF0000004UL,
  178.     0x80000004UL, 0x98000004UL, 0xD8000004UL, 0x90000004UL,
  179.     0x30000006UL, 0x60000006UL, 0x38000006UL, 0x8000006UL,
  180.     0x28000006UL, 0x78000006UL, 0x68000006UL, 0x40000006UL,
  181.     0x20000006UL, 0x50000006UL, 0x48000006UL, 0x70000006UL,
  182.     0x6UL,        0x18000006UL, 0x58000006UL, 0x10000006UL,
  183.     0xB0000007UL, 0xE0000007UL, 0xB8000007UL, 0x88000007UL,
  184.     0xA8000007UL, 0xF8000007UL, 0xE8000007UL, 0xC0000007UL,
  185.     0xA0000007UL, 0xD0000007UL, 0xC8000007UL, 0xF0000007UL,
  186.     0x80000007UL, 0x98000007UL, 0xD8000007UL, 0x90000007UL,
  187.     0x30000007UL, 0x60000007UL, 0x38000007UL, 0x8000007UL,
  188.     0x28000007UL, 0x78000007UL, 0x68000007UL, 0x40000007UL,
  189.     0x20000007UL, 0x50000007UL, 0x48000007UL, 0x70000007UL,
  190.     0x7UL,        0x18000007UL, 0x58000007UL, 0x10000007UL,
  191. };
  192. static const unsigned int gost_sbox_4[256] = {
  193.  
  194.     0xE8UL,  0xD8UL,  0xA0UL,  0x88UL,  0x98UL,
  195.     0xF8UL,  0xA8UL,  0xC8UL,  0x80UL,  0xD0UL,
  196.     0xF0UL,  0xB8UL,  0xB0UL,  0xC0UL,  0x90UL,
  197.     0xE0UL,  0x7E8UL, 0x7D8UL, 0x7A0UL, 0x788UL,
  198.     0x798UL, 0x7F8UL, 0x7A8UL, 0x7C8UL, 0x780UL,
  199.     0x7D0UL, 0x7F0UL, 0x7B8UL, 0x7B0UL, 0x7C0UL,
  200.     0x790UL, 0x7E0UL, 0x6E8UL, 0x6D8UL, 0x6A0UL,
  201.     0x688UL, 0x698UL, 0x6F8UL, 0x6A8UL, 0x6C8UL,
  202.     0x680UL, 0x6D0UL, 0x6F0UL, 0x6B8UL, 0x6B0UL,
  203.     0x6C0UL, 0x690UL, 0x6E0UL, 0x68UL,  0x58UL,
  204.     0x20UL,  0x8UL,   0x18UL,  0x78UL,  0x28UL,
  205.     0x48UL,  0x0UL,   0x50UL,  0x70UL,  0x38UL,
  206.     0x30UL,  0x40UL,  0x10UL,  0x60UL,  0x2E8UL,
  207.     0x2D8UL, 0x2A0UL, 0x288UL, 0x298UL, 0x2F8UL,
  208.     0x2A8UL, 0x2C8UL, 0x280UL, 0x2D0UL, 0x2F0UL,
  209.     0x2B8UL, 0x2B0UL, 0x2C0UL, 0x290UL, 0x2E0UL,
  210.     0x3E8UL, 0x3D8UL, 0x3A0UL, 0x388UL, 0x398UL,
  211.     0x3F8UL, 0x3A8UL, 0x3C8UL, 0x380UL, 0x3D0UL,
  212.     0x3F0UL, 0x3B8UL, 0x3B0UL, 0x3C0UL, 0x390UL,
  213.     0x3E0UL, 0x568UL, 0x558UL, 0x520UL, 0x508UL,
  214.     0x518UL, 0x578UL, 0x528UL, 0x548UL, 0x500UL,
  215.     0x550UL, 0x570UL, 0x538UL, 0x530UL, 0x540UL,
  216.     0x510UL, 0x560UL, 0x268UL, 0x258UL, 0x220UL,
  217.     0x208UL, 0x218UL, 0x278UL, 0x228UL, 0x248UL,
  218.     0x200UL, 0x250UL, 0x270UL, 0x238UL, 0x230UL,
  219.     0x240UL, 0x210UL, 0x260UL, 0x4E8UL, 0x4D8UL,
  220.     0x4A0UL, 0x488UL, 0x498UL, 0x4F8UL, 0x4A8UL,
  221.     0x4C8UL, 0x480UL, 0x4D0UL, 0x4F0UL, 0x4B8UL,
  222.     0x4B0UL, 0x4C0UL, 0x490UL, 0x4E0UL, 0x168UL,
  223.     0x158UL, 0x120UL, 0x108UL, 0x118UL, 0x178UL,
  224.     0x128UL, 0x148UL, 0x100UL, 0x150UL, 0x170UL,
  225.     0x138UL, 0x130UL, 0x140UL, 0x110UL, 0x160UL,
  226.     0x1E8UL, 0x1D8UL, 0x1A0UL, 0x188UL, 0x198UL,
  227.     0x1F8UL, 0x1A8UL, 0x1C8UL, 0x180UL, 0x1D0UL,
  228.     0x1F0UL, 0x1B8UL, 0x1B0UL, 0x1C0UL, 0x190UL,
  229.     0x1E0UL, 0x768UL, 0x758UL, 0x720UL, 0x708UL,
  230.     0x718UL, 0x778UL, 0x728UL, 0x748UL, 0x700UL,
  231.     0x750UL, 0x770UL, 0x738UL, 0x730UL, 0x740UL,
  232.     0x710UL, 0x760UL, 0x368UL, 0x358UL, 0x320UL,
  233.     0x308UL, 0x318UL, 0x378UL, 0x328UL, 0x348UL,
  234.     0x300UL, 0x350UL, 0x370UL, 0x338UL, 0x330UL,
  235.     0x340UL, 0x310UL, 0x360UL, 0x5E8UL, 0x5D8UL,
  236.     0x5A0UL, 0x588UL, 0x598UL, 0x5F8UL, 0x5A8UL,
  237.     0x5C8UL, 0x580UL, 0x5D0UL, 0x5F0UL, 0x5B8UL,
  238.     0x5B0UL, 0x5C0UL, 0x590UL, 0x5E0UL, 0x468UL,
  239.     0x458UL, 0x420UL, 0x408UL, 0x418UL, 0x478UL,
  240.     0x428UL, 0x448UL, 0x400UL, 0x450UL, 0x470UL,
  241.     0x438UL, 0x430UL, 0x440UL, 0x410UL, 0x460UL,
  242.     0x668UL, 0x658UL, 0x620UL, 0x608UL, 0x618UL,
  243.     0x678UL, 0x628UL, 0x648UL, 0x600UL, 0x650UL,
  244.     0x670UL, 0x638UL, 0x630UL, 0x640UL, 0x610UL,
  245.     0x660UL,
  246. };
  247.  
  248. /*
  249.  *  A macro that performs a full encryption round of GOST 28147-89.
  250.  *  Temporary variable t assumed and variables r and l for left and right
  251.  *  blocks
  252.  */
  253.  
  254. #define GOST_ENCRYPT_ROUND(k1, k2) \
  255. t = (k1) + r; \
  256. l ^= gost_sbox_1[t & 0xff] ^ gost_sbox_2[(t >> 8) & 0xff] ^ \
  257. gost_sbox_3[(t >> 16) & 0xff] ^ gost_sbox_4[t >> 24]; \
  258. t = (k2) + l; \
  259. r ^= gost_sbox_1[t & 0xff] ^ gost_sbox_2[(t >> 8) & 0xff] ^ \
  260. gost_sbox_3[(t >> 16) & 0xff] ^ gost_sbox_4[t >> 24]; \
  261.  
  262. /*
  263.    encrypt a block with the given key
  264.  */
  265.  
  266. #define GOST_ENCRYPT(key) \
  267. GOST_ENCRYPT_ROUND(key[0], key[1]) \
  268. GOST_ENCRYPT_ROUND(key[2], key[3]) \
  269. GOST_ENCRYPT_ROUND(key[4], key[5]) \
  270. GOST_ENCRYPT_ROUND(key[6], key[7]) \
  271. GOST_ENCRYPT_ROUND(key[0], key[1]) \
  272. GOST_ENCRYPT_ROUND(key[2], key[3]) \
  273. GOST_ENCRYPT_ROUND(key[4], key[5]) \
  274. GOST_ENCRYPT_ROUND(key[6], key[7]) \
  275. GOST_ENCRYPT_ROUND(key[0], key[1]) \
  276. GOST_ENCRYPT_ROUND(key[2], key[3]) \
  277. GOST_ENCRYPT_ROUND(key[4], key[5]) \
  278. GOST_ENCRYPT_ROUND(key[6], key[7]) \
  279. GOST_ENCRYPT_ROUND(key[7], key[6]) \
  280. GOST_ENCRYPT_ROUND(key[5], key[4]) \
  281. GOST_ENCRYPT_ROUND(key[3], key[2]) \
  282. GOST_ENCRYPT_ROUND(key[1], key[0]) \
  283. t = r; \
  284. r = l; \
  285. l = t;
  286.  
  287. /*
  288.  *  "chi" compression function. the result is stored over h
  289.  */
  290.  
  291. static void gosthash_compress(unsigned int * h, unsigned int * m)
  292. {
  293.     unsigned int i;
  294.     unsigned int l, r, t, key[8], u[8], v[8], w[8], s[8];
  295.  
  296.     memcpy(u, h, sizeof(u));
  297.     memcpy(v, m, sizeof(u));
  298.  
  299.     for (i = 0; i < 8; i += 2) {
  300.         w[0] = u[0] ^ v[0]; /*
  301.                        w = u xor v
  302.                      */
  303.         w[1] = u[1] ^ v[1];
  304.         w[2] = u[2] ^ v[2];
  305.         w[3] = u[3] ^ v[3];
  306.         w[4] = u[4] ^ v[4];
  307.         w[5] = u[5] ^ v[5];
  308.         w[6] = u[6] ^ v[6];
  309.         w[7] = u[7] ^ v[7];
  310.  
  311.         /*
  312.            P-Transformation
  313.          */
  314.  
  315.         key[0] = (w[0] & 0x000000ff) | ((w[2] & 0x000000ff) << 8) | ((w[4] & 0x000000ff) << 16) | ((w[6] & 0x000000ff) << 24);
  316.         key[1] = ((w[0] & 0x0000ff00) >> 8) | (w[2] & 0x0000ff00) | ((w[4] & 0x0000ff00) << 8) | ((w[6] & 0x0000ff00) << 16);
  317.         key[2] = ((w[0] & 0x00ff0000) >> 16) | ((w[2] & 0x00ff0000) >> 8) | (w[4] & 0x00ff0000)
  318.             | ((w[6] & 0x00ff0000) << 8);
  319.         key[3] = ((w[0] & 0xff000000) >> 24) | ((w[2] & 0xff000000) >> 16) | ((w[4] & 0xff000000) >> 8) | (w[6] & 0xff000000);
  320.         key[4] = (w[1] & 0x000000ff) | ((w[3] & 0x000000ff) << 8) | ((w[5] & 0x000000ff) << 16) | ((w[7] & 0x000000ff) << 24);
  321.         key[5] = ((w[1] & 0x0000ff00) >> 8) | (w[3] & 0x0000ff00) | ((w[5] & 0x0000ff00) << 8) | ((w[7] & 0x0000ff00) << 16);
  322.         key[6] = ((w[1] & 0x00ff0000) >> 16) | ((w[3] & 0x00ff0000) >> 8) | (w[5] & 0x00ff0000)
  323.             | ((w[7] & 0x00ff0000) << 8);
  324.         key[7] = ((w[1] & 0xff000000) >> 24) | ((w[3] & 0xff000000) >> 16) | ((w[5] & 0xff000000) >> 8) | (w[7] & 0xff000000);
  325.  
  326.         r = h[i];   /*
  327.                    encriphering transformation
  328.                  */
  329.         l = h[i + 1];
  330.         GOST_ENCRYPT(key);
  331.  
  332.         s[i] = r;
  333.         s[i + 1] = l;
  334.  
  335.         if (i == 6)
  336.             break;
  337.  
  338.         l = u[0] ^ u[2];    /*
  339.                        U = A(U)
  340.                      */
  341.         r = u[1] ^ u[3];
  342.         u[0] = u[2];
  343.         u[1] = u[3];
  344.         u[2] = u[4];
  345.         u[3] = u[5];
  346.         u[4] = u[6];
  347.         u[5] = u[7];
  348.         u[6] = l;
  349.         u[7] = r;
  350.  
  351.         if (i == 2) {   /*
  352.                    Constant C_3
  353.                  */
  354.             u[0] ^= 0xff00ff00;
  355.             u[1] ^= 0xff00ff00;
  356.             u[2] ^= 0x00ff00ff;
  357.             u[3] ^= 0x00ff00ff;
  358.             u[4] ^= 0x00ffff00;
  359.             u[5] ^= 0xff0000ff;
  360.             u[6] ^= 0x000000ff;
  361.             u[7] ^= 0xff00ffff;
  362.         }
  363.  
  364.         l = v[0];   /*
  365.                    V = A(A(V))
  366.                  */
  367.         r = v[2];
  368.         v[0] = v[4];
  369.         v[2] = v[6];
  370.         v[4] = l ^ r;
  371.         v[6] = v[0] ^ r;
  372.         l = v[1];
  373.         r = v[3];
  374.         v[1] = v[5];
  375.         v[3] = v[7];
  376.         v[5] = l ^ r;
  377.         v[7] = v[1] ^ r;
  378.     }
  379.  
  380.     /*
  381.        12 rounds of the LFSR (computed from a product matrix) and xor in M
  382.      */
  383.  
  384.     u[0] = m[0] ^ s[6];
  385.     u[1] = m[1] ^ s[7];
  386.     u[2] = m[2] ^ (s[0] << 16) ^ (s[0] >> 16) ^ (s[0] & 0xffff) ^ (s[1] & 0xffff) ^ (s[1] >> 16) ^ (s[2] << 16) ^ s[6] ^ (s[6] << 16) ^ (s[7] & 0xffff0000) ^ (s[7] >> 16);
  387.     u[3] = m[3] ^ (s[0] & 0xffff) ^ (s[0] << 16) ^ (s[1] & 0xffff) ^ (s[1]
  388.                                       << 16)
  389.         ^ (s[1] >> 16) ^ (s[2] << 16) ^ (s[2] >> 16) ^ (s[3] << 16) ^ s[6] ^ (s[6] << 16) ^ (s[6] >> 16) ^ (s[7] & 0xffff) ^ (s[7] << 16) ^ (s[7] >> 16);
  390.     u[4] =
  391.         m[4] ^ (s[0] & 0xffff0000) ^ (s[0] << 16) ^ (s[0] >> 16) ^
  392.         (s[1] & 0xffff0000) ^ (s[1] >> 16) ^ (s[2] << 16) ^ (s[2] >> 16) ^ (s[3] << 16) ^ (s[3] >> 16) ^ (s[4] << 16) ^ (s[6] << 16) ^ (s[6] >> 16) ^ (s[7] & 0xffff) ^ (s[7] << 16) ^ (s[7] >> 16);
  393.     u[5] =
  394.         m[5] ^ (s[0] << 16) ^ (s[0] >> 16) ^ (s[0] & 0xffff0000) ^
  395.         (s[1] & 0xffff) ^ s[2] ^ (s[2] >> 16) ^ (s[3] << 16) ^ (s[3] >>
  396.                                     16) ^ (s[4] << 16) ^ (s[4] >> 16) ^ (s[5] << 16) ^ (s[6] << 16) ^ (s[6] >> 16) ^ (s[7] & 0xffff0000) ^ (s[7] << 16) ^ (s[7] >> 16);
  397.     u[6] = m[6] ^ s[0] ^ (s[1] >> 16) ^ (s[2] << 16) ^ s[3] ^ (s[3] >> 16)
  398.         ^ (s[4] << 16) ^ (s[4] >> 16) ^ (s[5] << 16) ^ (s[5] >> 16) ^ s[6] ^ (s[6] << 16) ^ (s[6] >> 16) ^ (s[7] << 16);
  399.     u[7] =
  400.         m[7] ^ (s[0] & 0xffff0000) ^ (s[0] << 16) ^ (s[1] & 0xffff) ^
  401.         (s[1] << 16) ^ (s[2] >> 16) ^ (s[3] << 16) ^ s[4] ^ (s[4] >> 16) ^ (s[5] << 16) ^ (s[5] >> 16) ^ (s[6] >> 16) ^ (s[7] & 0xffff) ^ (s[7] << 16) ^ (s[7] >> 16);
  402.  
  403.     /*
  404.        16 * 1 round of the LFSR and xor in H
  405.      */
  406.  
  407.     v[0] = h[0] ^ (u[1] << 16) ^ (u[0] >> 16);
  408.     v[1] = h[1] ^ (u[2] << 16) ^ (u[1] >> 16);
  409.     v[2] = h[2] ^ (u[3] << 16) ^ (u[2] >> 16);
  410.     v[3] = h[3] ^ (u[4] << 16) ^ (u[3] >> 16);
  411.     v[4] = h[4] ^ (u[5] << 16) ^ (u[4] >> 16);
  412.     v[5] = h[5] ^ (u[6] << 16) ^ (u[5] >> 16);
  413.     v[6] = h[6] ^ (u[7] << 16) ^ (u[6] >> 16);
  414.     v[7] = h[7] ^ (u[0] & 0xffff0000) ^ (u[0] << 16) ^ (u[7] >> 16) ^ (u[1] & 0xffff0000) ^ (u[1] << 16) ^ (u[6] << 16) ^ (u[7] & 0xffff0000);
  415.  
  416.     /*
  417.        61 rounds of LFSR, mixing up h (computed from a product matrix)
  418.      */
  419.  
  420.     h[0] =
  421.         (v[0] & 0xffff0000) ^ (v[0] << 16) ^ (v[0] >> 16) ^ (v[1] >>
  422.                                  16) ^
  423.         (v[1] & 0xffff0000) ^ (v[2] << 16) ^ (v[3] >> 16) ^ (v[4] << 16) ^ (v[5] >> 16) ^ v[5] ^ (v[6] >> 16) ^ (v[7] << 16) ^ (v[7] >> 16) ^ (v[7] & 0xffff);
  424.     h[1] =
  425.         (v[0] << 16) ^ (v[0] >> 16) ^ (v[0] & 0xffff0000) ^ (v[1] &
  426.                                  0xffff) ^ v[2] ^ (v[2] >> 16) ^ (v[3] << 16) ^ (v[4] >> 16) ^ (v[5] << 16) ^ (v[6] << 16) ^ v[6] ^ (v[7] & 0xffff0000) ^ (v[7] >> 16);
  427.     h[2] =
  428.         (v[0] & 0xffff) ^ (v[0] << 16) ^ (v[1] << 16) ^ (v[1] >> 16) ^
  429.         (v[1] & 0xffff0000) ^ (v[2] << 16) ^ (v[3] >> 16) ^ v[3] ^ (v[4] << 16) ^ (v[5] >> 16) ^ v[6] ^ (v[6] >> 16) ^ (v[7] & 0xffff) ^ (v[7] << 16) ^ (v[7] >> 16);
  430.     h[3] = (v[0] << 16) ^ (v[0] >> 16) ^ (v[0] & 0xffff0000) ^ (v[1] & 0xffff0000)
  431.         ^ (v[1] >> 16) ^ (v[2] << 16) ^ (v[2] >> 16) ^ v[2] ^ (v[3] << 16) ^ (v[4] >> 16) ^ v[4] ^ (v[5] << 16) ^ (v[6] << 16) ^ (v[7] & 0xffff) ^ (v[7] >> 16);
  432.     h[4] = (v[0] >> 16) ^ (v[1] << 16) ^ v[1] ^ (v[2] >> 16) ^ v[2] ^ (v[3] << 16) ^ (v[3] >> 16) ^ v[3] ^ (v[4] << 16) ^ (v[5] >> 16) ^ v[5]
  433.         ^ (v[6] << 16) ^ (v[6] >> 16) ^ (v[7] << 16);
  434.     h[5] = (v[0] << 16) ^ (v[0] & 0xffff0000) ^ (v[1] << 16) ^ (v[1] >> 16) ^ (v[1] & 0xffff0000) ^ (v[2] << 16) ^ v[2] ^ (v[3] >> 16) ^ v[3]
  435.         ^ (v[4] << 16) ^ (v[4] >> 16) ^ v[4] ^ (v[5] << 16) ^ (v[6] << 16) ^ (v[6] >> 16) ^ v[6] ^ (v[7] << 16) ^ (v[7] >> 16) ^ (v[7] & 0xffff0000);
  436.     h[6] = v[0] ^ v[2] ^ (v[2] >> 16) ^ v[3] ^ (v[3] << 16) ^ v[4] ^ (v[4]
  437.                                       >> 16)
  438.         ^ (v[5] << 16) ^ (v[5] >> 16) ^ v[5] ^ (v[6] << 16) ^ (v[6] >> 16) ^ v[6] ^ (v[7] << 16) ^ v[7];
  439.     h[7] = v[0] ^ (v[0] >> 16) ^ (v[1] << 16) ^ (v[1] >> 16) ^ (v[2] << 16) ^ (v[3] >> 16) ^ v[3] ^ (v[4] << 16) ^ v[4] ^ (v[5] >> 16) ^ v[5]
  440.         ^ (v[6] << 16) ^ (v[6] >> 16) ^ (v[7] << 16) ^ v[7];
  441. }
  442.  
  443. /*
  444.    Clear the state of the given context structure.
  445.  */
  446.  
  447. void gosthash_reset(GostHashCtx * ctx)
  448. {
  449.     memset(ctx->sum, 0x00, 32);
  450.     memset(ctx->hash, 0x00, 32);
  451.     memset(ctx->len, 0x00, 32);
  452.     memset(ctx->partial, 0x00, 32);
  453.     ctx->partial_bytes = 0;
  454. }
  455.  
  456. /*
  457.    Mix in a 32-byte chunk ("stage 3")
  458.  */
  459.  
  460. static void gosthash_bytes(GostHashCtx * ctx, const unsigned char * buf, unsigned int bits)
  461. {
  462.     unsigned int i;
  463.     unsigned int j;
  464.     unsigned int a, c, m[8];
  465.  
  466.     /*
  467.        convert bytes to a long words and compute the sum
  468.      */
  469.  
  470.     j = 0;
  471.     c = 0;
  472.     for (i = 0; i < 8; i++) {
  473.         a = ((unsigned int) buf[j]) | (((unsigned int) buf[j + 1]) << 8) | (((unsigned int) buf[j + 2]) << 16) | (((unsigned int) buf[j + 3]) << 24);
  474.         j += 4;
  475.         m[i] = a;
  476.         c = a + c + ctx->sum[i];
  477.        
  478.         if ((a==0xFFFFFFFFUL) && (ctx->sum[i]==0xFFFFFFFFUL)) {
  479.             ctx->sum[i] = c;
  480.             c = 1;
  481.         } else {
  482.             ctx->sum[i] = c;
  483.             c = c < a ? 1 : 0;
  484.         }
  485.     }
  486.  
  487.     /*
  488.        compress
  489.      */
  490.  
  491.     gosthash_compress(ctx->hash, m);
  492.  
  493.     /*
  494.        a 64-bit counter should be sufficient
  495.      */
  496.  
  497.     ctx->len[0] += bits;
  498.     if (ctx->len[0] < bits)
  499.         ctx->len[1]++;
  500. }
  501.  
  502. /*
  503.    Mix in len bytes of data for the given buffer.
  504.  */
  505.  
  506. void gosthash_update(GostHashCtx * ctx, const unsigned char * buf, unsigned int len)
  507. {
  508.     unsigned int i, j;
  509.  
  510.     i = ctx->partial_bytes;
  511.     j = 0;
  512.     while (i < 32 && j < len)
  513.         ctx->partial[i++] = buf[j++];
  514.  
  515.     if (i < 32) {
  516.         ctx->partial_bytes = i;
  517.         return;
  518.     }
  519.     gosthash_bytes(ctx, ctx->partial, 256);
  520.  
  521.     while ((j + 32) < len) {
  522.         gosthash_bytes(ctx, &buf[j], 256);
  523.         j += 32;
  524.     }
  525.  
  526.     i = 0;
  527.     while (j < len)
  528.         ctx->partial[i++] = buf[j++];
  529.     ctx->partial_bytes = i;
  530. }
  531.  
  532.  
  533. /*
  534.    Compute and save the 32-byte digest.
  535.  */
  536.  
  537. void gosthash_final(GostHashCtx * ctx, unsigned char * digest)
  538. {
  539.     unsigned int i;
  540.     unsigned int j;
  541.     unsigned int a;
  542.  
  543.     /*
  544.        adjust and mix in the last chunk
  545.      */
  546.  
  547.     if (ctx->partial_bytes > 0) {
  548.         memset(&ctx->partial[ctx->partial_bytes], 0x00, 32 - ctx->partial_bytes);
  549.         gosthash_bytes(ctx, ctx->partial, ctx->partial_bytes << 3);
  550.     }
  551.  
  552.     /*
  553.        mix in the length and the sum
  554.      */
  555.  
  556.     gosthash_compress(ctx->hash, ctx->len);
  557.     gosthash_compress(ctx->hash, ctx->sum);
  558.  
  559.     /*
  560.        convert the output to bytes
  561.      */
  562.  
  563.     j = 0;
  564.  
  565.     if (digest != NULL)
  566.     for (i = 0; i < 8; i++) {
  567.         a = ctx->hash[i];
  568.         digest[j] = (unsigned char) a;
  569.         digest[j + 1] = (unsigned char) (a >> 8);
  570.         digest[j + 2] = (unsigned char) (a >> 16);
  571.         digest[j + 3] = (unsigned char) (a >> 24);
  572.         j += 4;
  573.     }
  574. }
  575.  
  576. int main()
  577. {
  578.     GostHashCtx ctx;
  579.     unsigned char data[4096];
  580.     unsigned char digest[32];
  581.     int it;
  582.     int jt;
  583.     time_t start_time=time(NULL);
  584.     int counter=0;
  585.  
  586.     memset(&ctx, 0x00, sizeof(ctx));
  587.  
  588.     do { } while(start_time==time(NULL));
  589.     printf("Go\n");
  590.  
  591.     /* Let's rock and roll, babe */
  592.     do {
  593.         for (it=0; it<4096; it++) {
  594.             data[it]=it;
  595.         }
  596.         gosthash_reset(&ctx);
  597.  
  598.         for (jt=0; jt<256; jt++) {
  599.             gosthash_update(&ctx, (void*)&data, 4096);
  600.             for (it=0; it<4096; it++) {
  601.                 data[it]++;
  602.             }
  603.         }
  604.         gosthash_final(&ctx, digest);
  605.         if (time(NULL)-start_time>=5) {
  606.             printf("%d hashes/sec, %f Mb/sec\n", counter, 256.0f*4096.0f*(float)counter/5.0f/1024.0f/1024.0f);
  607.             counter=0;
  608.             start_time=time(NULL);
  609.         } else {
  610.             counter++;
  611.         }
  612.     } while(1);
  613. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement