вопрос по ГОСТ 28147-89

Тема в разделе "WASM.CRYPTO", создана пользователем metcenger, 18 сен 2008.

  1. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    kapger
    Млять, а поиск юзать ? Почти на каждой странице яндекса мелькает Брюс Шнайер со своей книгой, а вней приложение, а там на си стоко сорцов, хоть задницей жуй
     
  2. kapger

    kapger New Member

    Публикаций:
    0
    Регистрация:
    18 фев 2009
    Сообщения:
    135
    Спасибо за добрые слова!

    Поиск юзается, но
    НЕ НАШЕЛ!

    Шнайера только начал...

    P.S. ссылка http://darksoftware.narod.ru/narod_is_best/libgost.ppmp - не понял что с ней делать... И IE, и FireFox предлагают сохранить файл. Сохранил. И что с ним дальше делать?
     
  3. alexanderwm

    alexanderwm New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2008
    Сообщения:
    43
    Это - архив PPMPackTC.
     
  4. OLS

    OLS New Member

    Публикаций:
    0
    Регистрация:
    8 янв 2005
    Сообщения:
    322
    Адрес:
    Russia
    В чем затруднение преобразования ASM в С ?
     
  5. OLS

    OLS New Member

    Публикаций:
    0
    Регистрация:
    8 янв 2005
    Сообщения:
    322
    Адрес:
    Russia
    не тестировал :
    Код (Text):
    1. /*
    2.  * The GOST 28147-89 cipher
    3.  *
    4.  * This is based on the 25 Movember 1993 draft translation
    5.  * by Aleksandr Malchik, with Whitfield Diffie, of the Government
    6.  * Standard of the U.S.S.R. GOST 28149-89, "Cryptographic Transformation
    7.  * Algorithm", effective 1 July 1990.  (Whitfield.Diffie@eng.sun.com)
    8.  *
    9.  * That is a draft, and may contain errors, which will be faithfully
    10.  * reflected here, along with possible exciting new bugs.
    11.  *
    12.  * Some details have been cleared up by the paper "Soviet Encryption
    13.  * Algorithm" by Josef Pieprzyk and Leonid Tombak of the University
    14.  * of Wollongong, New South Wales.  (josef/leo@cs.adfa.oz.au)
    15.  *
    16.  * The standard is written by A. Zabotin (project leader), G.P. Glazkov,
    17.  * and V.B. Isaeva.  It was accepted and introduced into use by the
    18.  * action of the State Standards Committee of the USSR on 2 June 89 as
    19.  * No. 1409.  It was to be reviewed in 1993, but whether anyone wishes
    20.  * to take on this obligation from the USSR is questionable.
    21.  *
    22.  * This code is placed in the public domain.
    23.  */
    24.  
    25. /*
    26.  * If you read the standard, it belabors the point of copying corresponding
    27.  * bits from point A to point B quite a bit.  It helps to understand that
    28.  * the standard is uniformly little-endian, although it numbers bits from
    29.  * 1 rather than 0, so bit n has value 2^(n-1).  The least significant bit
    30.  * of the 32-bit words that are manipulated in the algorithm is the first,
    31.  * lowest-numbered, in the bit string.
    32.  */
    33.  
    34.  
    35. /* A 32-bit data type */
    36. #ifdef __alpha  /* Any other 64-bit machines? */
    37. typedef unsigned int word32;
    38. #else
    39. typedef unsigned long word32;
    40. #endif
    41.  
    42. /*
    43.  * The standard does not specify the contents of the 8 4 bit->4 bit
    44.  * substitution boxes, saying they're a parameter of the network
    45.  * being set up.  For illustration purposes here, I have used
    46.  * the first rows of the 8 S-boxes from the DES.  (Note that the
    47.  * DES S-boxes are numbered starting from 1 at the msb.  In keeping
    48.  * with the rest of the GOST, I have used little-endian numbering.
    49.  * Thus, k8 is S-box 1.
    50.  *
    51.  * Obviously, a careful look at the cryptographic properties of the cipher
    52.  * must be undertaken before "production" substitution boxes are defined.
    53.  *
    54.  * The standard also does not specify a standard bit-string representation
    55.  * for the contents of these blocks.
    56.  */
    57. static unsigned char const k8[16] = {
    58.     14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7 };
    59. static unsigned char const k7[16] = {
    60.     15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10 };
    61. static unsigned char const k6[16] = {
    62.     10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8 };
    63. static unsigned char const k5[16] = {
    64.      7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15 };
    65. static unsigned char const k4[16] = {
    66.      2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9 };
    67. static unsigned char const k3[16] = {
    68.     12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11 };
    69. static unsigned char const k2[16] = {
    70.      4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1 };
    71. static unsigned char const k1[16] = {
    72.     13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7 };
    73.  
    74. /* Byte-at-a-time substitution boxes */
    75. static unsigned char k87[256];
    76. static unsigned char k65[256];
    77. static unsigned char k43[256];
    78. static unsigned char k21[256];
    79.  
    80. /*
    81.  * Build byte-at-a-time subtitution tables.
    82.  * This must be called once for global setup.
    83.  */
    84. void
    85. kboxinit(void)
    86. {
    87.     int i;
    88.     for (i = 0; i < 256; i++) {
    89.         k87[i] = k8[i >> 4] << 4 | k7[i & 15];
    90.         k65[i] = k6[i >> 4] << 4 | k5[i & 15];
    91.         k43[i] = k4[i >> 4] << 4 | k3[i & 15];
    92.         k21[i] = k2[i >> 4] << 4 | k1[i & 15];
    93.     }
    94. }
    95.  
    96. /*
    97.  * Do the substitution and rotation that are the core of the operation,
    98.  * like the expansion, substitution and permutation of the DES.
    99.  * It would be possible to perform DES-like optimisations and store
    100.  * the table entries as 32-bit words, already rotated, but the
    101.  * efficiency gain is questionable.
    102.  *
    103.  * This should be inlined for maximum speed
    104.  */
    105. #if __GNUC__
    106. __inline__
    107. #endif
    108. static word32
    109. f(word32 x)
    110. {
    111.     /* Do substitutions */
    112. #if 0
    113.     /* This is annoyingly slow */
    114.     x = k8[x>>28 & 15] << 28 | k7[x>>24 & 15] << 24 |
    115.         k6[x>>20 & 15] << 20 | k5[x>>16 & 15] << 16 |
    116.         k4[x>>12 & 15] << 12 | k3[x>> 8 & 15] <<  8 |
    117.         k2[x>> 4 & 15] <<  4 | k1[x     & 15];
    118. #else
    119.     /* This is faster */
    120.     x = k87[x>>24 & 255] << 24 | k65[x>>16 & 255] << 16 |
    121.         k43[x>> 8 & 255] <<  8 | k21[x & 255];
    122. #endif
    123.  
    124.     /* Rotate left 11 bits */
    125.     return x<<11 | x>>(32-11);
    126. }
    127.  
    128. /*
    129.  * The GOST standard defines the input in terms of bits 1..64, with
    130.  * bit 1 being the lsb of in[0] and bit 64 being the msb of in[1].
    131.  *
    132.  * The keys are defined similarly, with bit 256 being the msb of key[7].
    133.  */
    134. void
    135. gostcrypt(word32 const in[2], word32 out[2], word32 const key[8])
    136. {
    137.     register word32 n1, n2; /* As named in the GOST */
    138.  
    139.     n1 = in[0];
    140.     n2 = in[1];
    141.  
    142.     /* Instead of swapping halves, swap names each round */
    143.     n2 ^= f(n1+key[0]);
    144.     n1 ^= f(n2+key[1]);
    145.     n2 ^= f(n1+key[2]);
    146.     n1 ^= f(n2+key[3]);
    147.     n2 ^= f(n1+key[4]);
    148.     n1 ^= f(n2+key[5]);
    149.     n2 ^= f(n1+key[6]);
    150.     n1 ^= f(n2+key[7]);
    151.  
    152.     n2 ^= f(n1+key[0]);
    153.     n1 ^= f(n2+key[1]);
    154.     n2 ^= f(n1+key[2]);
    155.     n1 ^= f(n2+key[3]);
    156.     n2 ^= f(n1+key[4]);
    157.     n1 ^= f(n2+key[5]);
    158.     n2 ^= f(n1+key[6]);
    159.     n1 ^= f(n2+key[7]);
    160.  
    161.     n2 ^= f(n1+key[0]);
    162.     n1 ^= f(n2+key[1]);
    163.     n2 ^= f(n1+key[2]);
    164.     n1 ^= f(n2+key[3]);
    165.     n2 ^= f(n1+key[4]);
    166.     n1 ^= f(n2+key[5]);
    167.     n2 ^= f(n1+key[6]);
    168.     n1 ^= f(n2+key[7]);
    169.  
    170.     n2 ^= f(n1+key[7]);
    171.     n1 ^= f(n2+key[6]);
    172.     n2 ^= f(n1+key[5]);
    173.     n1 ^= f(n2+key[4]);
    174.     n2 ^= f(n1+key[3]);
    175.     n1 ^= f(n2+key[2]);
    176.     n2 ^= f(n1+key[1]);
    177.     n1 ^= f(n2+key[0]);
    178.  
    179.     /* There is no swap after the last round */
    180.     out[0] = n2;
    181.     out[1] = n1;
    182. }
    183.    
    184.  
    185. /*
    186.  * The key schedule is somewhat different for decryption.
    187.  * (The key table is used once forward and three times backward.)
    188.  * You could define an expanded key, or just write the code twice,
    189.  * as done here.
    190.  */
    191. void
    192. gostdecrypt(word32 const in[2], word32 out[2], word32 const key[8])
    193. {
    194.     register word32 n1, n2; /* As named in the GOST */
    195.  
    196.     n1 = in[0];
    197.     n2 = in[1];
    198.  
    199.     n2 ^= f(n1+key[0]);
    200.     n1 ^= f(n2+key[1]);
    201.     n2 ^= f(n1+key[2]);
    202.     n1 ^= f(n2+key[3]);
    203.     n2 ^= f(n1+key[4]);
    204.     n1 ^= f(n2+key[5]);
    205.     n2 ^= f(n1+key[6]);
    206.     n1 ^= f(n2+key[7]);
    207.  
    208.     n2 ^= f(n1+key[7]);
    209.     n1 ^= f(n2+key[6]);
    210.     n2 ^= f(n1+key[5]);
    211.     n1 ^= f(n2+key[4]);
    212.     n2 ^= f(n1+key[3]);
    213.     n1 ^= f(n2+key[2]);
    214.     n2 ^= f(n1+key[1]);
    215.     n1 ^= f(n2+key[0]);
    216.  
    217.     n2 ^= f(n1+key[7]);
    218.     n1 ^= f(n2+key[6]);
    219.     n2 ^= f(n1+key[5]);
    220.     n1 ^= f(n2+key[4]);
    221.     n2 ^= f(n1+key[3]);
    222.     n1 ^= f(n2+key[2]);
    223.     n2 ^= f(n1+key[1]);
    224.     n1 ^= f(n2+key[0]);
    225.  
    226.     n2 ^= f(n1+key[7]);
    227.     n1 ^= f(n2+key[6]);
    228.     n2 ^= f(n1+key[5]);
    229.     n1 ^= f(n2+key[4]);
    230.     n2 ^= f(n1+key[3]);
    231.     n1 ^= f(n2+key[2]);
    232.     n2 ^= f(n1+key[1]);
    233.     n1 ^= f(n2+key[0]);
    234.  
    235.     out[0] = n2;
    236.     out[1] = n1;
    237. }
    238.  
    239. /*
    240.  * The GOST "Output feedback" standard.  It seems closer morally
    241.  * to the counter feedback mode some people have proposed for DES.
    242.  * The avoidance of the short cycles that are possible in OFB seems
    243.  * like a Good Thing.
    244.  *
    245.  * Calling it the stream mode makes more sense.
    246.  *
    247.  * The IV is encrypted with the key to produce the initial counter value.
    248.  * Then, for each output block, a constant is added, modulo 2^32-1
    249.  * (0 is represented as all-ones, not all-zeros), to each half of
    250.  * the counter, and the counter is encrypted to produce the value
    251.  * to XOR with the output.
    252.  *
    253.  * Len is the number of blocks.  Sub-block encryption is
    254.  * left as an exercise for the user.  Remember that the
    255.  * standard defines everything in a little-endian manner,
    256.  * so you want to use the low bit of gamma[0] first.
    257.  *
    258.  * OFB is, of course, self-inverse, so there is only one function.
    259.  */
    260.  
    261. /* The constants for addition */
    262. #define C1 0x01010104
    263. #define C2 0x01010101
    264.  
    265. void
    266. gostofb(word32 const *in, word32 *out, int len,
    267.     word32 const iv[2], word32 const key[8])
    268. {
    269.     word32 temp[2];         /* Counter */
    270.     word32 gamma[2];        /* Output XOR value */
    271.  
    272.     /* Compute starting value for counter */
    273.     gostcrypt(iv, temp, key);
    274.  
    275.     while (len--) {
    276.         temp[0] += C2;
    277.         if (temp[0] < C2)       /* Wrap modulo 2^32? */
    278.             temp[0]++;      /* Make it modulo 2^32-1 */
    279.         temp[1] += C1;
    280.         if (temp[1] < C1)       /* Wrap modulo 2^32? */
    281.             temp[1]++;      /* Make it modulo 2^32-1 */
    282.  
    283.         gostcrypt(temp, gamma, key);
    284.  
    285.         *out++ = *in++ ^ gamma[0];
    286.         *out++ = *in++ ^ gamma[1];
    287.     }
    288. }
    289.  
    290. /*
    291.  * The CFB mode is just what you'd expect.  Each block of ciphertext y[] is
    292.  * derived from the input x[] by the following pseudocode:
    293.  * y[i] = x[i] ^ gostcrypt(y[i-1])
    294.  * x[i] = y[i] ^ gostcrypt(y[i-1])
    295.  * Where y[-1] is the IV.
    296.  *
    297.  * The IV is modified in place.  Again, len is in *blocks*.
    298.  */
    299.  
    300. void
    301. gostcfbencrypt(word32 const *in, word32 *out, int len,
    302.            word32 iv[2], word32 const key[8])
    303. {
    304.     while (len--) {
    305.         gostcrypt(iv, iv, key);
    306.         iv[0] = *out++ ^= iv[0];
    307.         iv[1] = *out++ ^= iv[1];
    308.     }
    309. }
    310.  
    311. void
    312. gostcfbdecrypt(word32 const *in, word32 *out, int len,
    313.            word32 iv[2], word32 const key[8])
    314. {
    315.     word32 t;
    316.     while (len--) {
    317.         gostcrypt(iv, iv, key);
    318.         t = *out;
    319.         *out++ ^= iv[0];
    320.         iv[0] = t;
    321.         t = *out;
    322.         *out++ ^= iv[1];
    323.         iv[1] = t;
    324.     }
    325. }
    326.  
    327.  
    328. /*
    329.  * The message suthetication code uses only 16 of the 32 rounds.
    330.  * There *is* a swap after the 16th round.
    331.  * The last block should be padded to 64 bits with zeros.
    332.  * len is the number of *blocks* in the input.
    333.  */
    334. void
    335. gostmac(word32 const *in, int len, word32 out[2], word32 const key[8])
    336. {
    337.     register word32 n1, n2; /* As named in the GOST */
    338.  
    339.     n1 = 0;
    340.     n2 = 0;
    341.  
    342.     while (len--) {
    343.         n1 ^= *in++;
    344.         n2 = *in++;
    345.  
    346.         /* Instead of swapping halves, swap names each round */
    347.         n2 ^= f(n1+key[0]);
    348.         n1 ^= f(n2+key[1]);
    349.         n2 ^= f(n1+key[2]);
    350.         n1 ^= f(n2+key[3]);
    351.         n2 ^= f(n1+key[4]);
    352.         n1 ^= f(n2+key[5]);
    353.         n2 ^= f(n1+key[6]);
    354.         n1 ^= f(n2+key[7]);
    355.  
    356.         n2 ^= f(n1+key[0]);
    357.         n1 ^= f(n2+key[1]);
    358.         n2 ^= f(n1+key[2]);
    359.         n1 ^= f(n2+key[3]);
    360.         n2 ^= f(n1+key[4]);
    361.         n1 ^= f(n2+key[5]);
    362.         n2 ^= f(n1+key[6]);
    363.         n1 ^= f(n2+key[7]);
    364.     }
    365.  
    366.     out[0] = n1;
    367.     out[1] = n2;
    368. }
    369.  
    370. #ifdef TEST
    371.  
    372. #include <stdio.h>
    373. #include <stdlib.h>
    374.  
    375. /* Designed to cope with 15-bit rand() implementations */
    376. #define RAND32 ((word32)rand() << 17 ^ (word32)rand() << 9 ^ rand())
    377.  
    378. int
    379. main(void)
    380. {
    381.     word32 key[8];
    382.     word32 plain[2];
    383.     word32 cipher[2];
    384.     int i, j;
    385.  
    386.     kboxinit();
    387.  
    388.     printf("GOST 21847-89 test driver.\n");
    389.  
    390.     for (i = 0; i < 1000; i++) {
    391.         for (j = 0; j < 8; j++)
    392.             key[j] = RAND32;
    393.         plain[0] = RAND32;
    394.         plain[1] = RAND32;
    395.  
    396.         printf("%3d\r", i);
    397.         fflush(stdout);
    398.  
    399.         gostcrypt(plain, cipher, key);
    400.         for (j = 0; j < 99; j++)
    401.             gostcrypt(cipher, cipher, key);
    402.         for (j = 0; j < 100; j++)
    403.             gostdecrypt(cipher, cipher, key);
    404.  
    405.         if (plain[0] != cipher[0] || plain[1] != cipher[1]) {
    406.             fprintf(stderr, "\nError! i = %d\n", i);
    407.             return 1;
    408.         }
    409.     }
    410.     printf("All tests passed.\n");
    411.     return 0;
    412. }
    413.  
    414. #endif /* TEST */
     
  6. alexanderwm

    alexanderwm New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2008
    Сообщения:
    43
    2OLS: В этой реализации, к-рая гуляет по сети еще со времен книги Шнайера, SBOX взяты с потолка, при преобразовании в byte-to-byte u8 SBOX[4][256] мы видим множество левых перестановок x (sbox[x]) = 0. На радостях криптоаналитики и объявили, что ГОСТ - слабый, поскольку реальных перестановок не было.

    Если заметить SBOX, к примеру, на тот, к-рый используется в примерах к стандарту и в ЦБ

    u8 sbox[8][16] = {
    {4, 10, 9, 2, 13, 8, 0, 14, 6, 11, 1, 12, 7, 15, 5, 3},
    {14, 11, 4, 12, 6, 13, 15, 10, 2, 3, 8, 1, 0, 7, 5, 9},
    {5, 8, 1, 13, 10, 3, 4, 2, 14, 15, 12, 7, 6, 0, 9, 11},
    {7, 13, 10, 1, 0, 8, 9, 15, 14, 4, 6, 12, 11, 2, 5, 3},
    {6, 12, 7, 1, 5, 15, 13, 8, 4, 10, 9, 14, 0, 3, 11, 2},
    {4, 11, 10, 0, 7, 2, 1, 13, 3, 6, 8, 5, 9, 12, 15, 14},
    {13, 11, 4, 1, 3, 15, 5, 9, 0, 10, 14, 7, 6, 8, 2, 12},
    {1, 15, 13, 0, 5, 7, 10, 4, 9, 2, 3, 14, 6, 11, 8, 12}
    };

    четыре 256 байтных SBOX дадут уже нормальные перестановки.

    в принципе, можно исключить runtime генерацию этих массивов и заменить константами...

    Код (Text):
    1. /* Byte-at-a-time substitution boxes */
    2. const static u8 k87[256] =
    3.   { 0x4E, 0x4B, 0x44, 0x4C, 0x46, 0x4D, 0x4F, 0x4A, 0x42, 0x43, 0x48, 0x41,
    4.   0x40, 0x47, 0x45, 0x49, 0xAE, 0xAB, 0xA4, 0xAC, 0xA6, 0xAD, 0xAF, 0xAA,
    5.     0xA2, 0xA3, 0xA8,
    6.   0xA1, 0xA0, 0xA7, 0xA5, 0xA9, 0x9E, 0x9B, 0x94, 0x9C, 0x96, 0x9D, 0x9F,
    7.     0x9A, 0x92, 0x93,
    8.   0x98, 0x91, 0x90, 0x97, 0x95, 0x99, 0x2E, 0x2B, 0x24, 0x2C, 0x26, 0x2D,
    9.     0x2F, 0x2A, 0x22,
    10.   0x23, 0x28, 0x21, 0x20, 0x27, 0x25, 0x29, 0xDE, 0xDB, 0xD4, 0xDC, 0xD6,
    11.     0xDD, 0xDF, 0xDA,
    12.   0xD2, 0xD3, 0xD8, 0xD1, 0xD0, 0xD7, 0xD5, 0xD9, 0x8E, 0x8B, 0x84, 0x8C,
    13.     0x86, 0x8D, 0x8F,
    14.   0x8A, 0x82, 0x83, 0x88, 0x81, 0x80, 0x87, 0x85, 0x89, 0x0E, 0x0B, 0x04,
    15.     0x0C, 0x06, 0x0D,
    16.   0x0F, 0x0A, 0x02, 0x03, 0x08, 0x01, 0x00, 0x07, 0x05, 0x09, 0xEE, 0xEB,
    17.     0xE4, 0xEC, 0xE6,
    18.   0xED, 0xEF, 0xEA, 0xE2, 0xE3, 0xE8, 0xE1, 0xE0, 0xE7, 0xE5, 0xE9, 0x6E,
    19.     0x6B, 0x64, 0x6C,
    20.   0x66, 0x6D, 0x6F, 0x6A, 0x62, 0x63, 0x68, 0x61, 0x60, 0x67, 0x65, 0x69,
    21.     0xBE, 0xBB, 0xB4,
    22.   0xBC, 0xB6, 0xBD, 0xBF, 0xBA, 0xB2, 0xB3, 0xB8, 0xB1, 0xB0, 0xB7, 0xB5,
    23.     0xB9, 0x1E, 0x1B,
    24.   0x14, 0x1C, 0x16, 0x1D, 0x1F, 0x1A, 0x12, 0x13, 0x18, 0x11, 0x10, 0x17,
    25.     0x15, 0x19, 0xCE,
    26.   0xCB, 0xC4, 0xCC, 0xC6, 0xCD, 0xCF, 0xCA, 0xC2, 0xC3, 0xC8, 0xC1, 0xC0,
    27.     0xC7, 0xC5, 0xC9,
    28.   0x7E, 0x7B, 0x74, 0x7C, 0x76, 0x7D, 0x7F, 0x7A, 0x72, 0x73, 0x78, 0x71,
    29.     0x70, 0x77, 0x75,
    30.   0x79, 0xFE, 0xFB, 0xF4, 0xFC, 0xF6, 0xFD, 0xFF, 0xFA, 0xF2, 0xF3, 0xF8,
    31.     0xF1, 0xF0, 0xF7,
    32.   0xF5, 0xF9, 0x5E, 0x5B, 0x54, 0x5C, 0x56, 0x5D, 0x5F, 0x5A, 0x52, 0x53,
    33.     0x58, 0x51, 0x50,
    34.   0x57, 0x55, 0x59, 0x3E, 0x3B, 0x34, 0x3C, 0x36, 0x3D, 0x3F, 0x3A, 0x32,
    35.     0x33, 0x38, 0x31,
    36.   0x30, 0x37, 0x35, 0x39
    37. };
    38.  
    39. const static u8 k65[256] =
    40.   { 0x57, 0x5D, 0x5A, 0x51, 0x50, 0x58, 0x59, 0x5F, 0x5E, 0x54, 0x56, 0x5C,
    41.   0x5B, 0x52, 0x55, 0x53, 0x87, 0x8D, 0x8A, 0x81, 0x80, 0x88, 0x89, 0x8F,
    42.     0x8E, 0x84, 0x86,
    43.   0x8C, 0x8B, 0x82, 0x85, 0x83, 0x17, 0x1D, 0x1A, 0x11, 0x10, 0x18, 0x19,
    44.     0x1F, 0x1E, 0x14,
    45.   0x16, 0x1C, 0x1B, 0x12, 0x15, 0x13, 0xD7, 0xDD, 0xDA, 0xD1, 0xD0, 0xD8,
    46.     0xD9, 0xDF, 0xDE,
    47.   0xD4, 0xD6, 0xDC, 0xDB, 0xD2, 0xD5, 0xD3, 0xA7, 0xAD, 0xAA, 0xA1, 0xA0,
    48.     0xA8, 0xA9, 0xAF,
    49.   0xAE, 0xA4, 0xA6, 0xAC, 0xAB, 0xA2, 0xA5, 0xA3, 0x37, 0x3D, 0x3A, 0x31,
    50.     0x30, 0x38, 0x39,
    51.   0x3F, 0x3E, 0x34, 0x36, 0x3C, 0x3B, 0x32, 0x35, 0x33, 0x47, 0x4D, 0x4A,
    52.     0x41, 0x40, 0x48,
    53.   0x49, 0x4F, 0x4E, 0x44, 0x46, 0x4C, 0x4B, 0x42, 0x45, 0x43, 0x27, 0x2D,
    54.     0x2A, 0x21, 0x20,
    55.   0x28, 0x29, 0x2F, 0x2E, 0x24, 0x26, 0x2C, 0x2B, 0x22, 0x25, 0x23, 0xE7,
    56.     0xED, 0xEA, 0xE1,
    57.   0xE0, 0xE8, 0xE9, 0xEF, 0xEE, 0xE4, 0xE6, 0xEC, 0xEB, 0xE2, 0xE5, 0xE3,
    58.     0xF7, 0xFD, 0xFA,
    59.   0xF1, 0xF0, 0xF8, 0xF9, 0xFF, 0xFE, 0xF4, 0xF6, 0xFC, 0xFB, 0xF2, 0xF5,
    60.     0xF3, 0xC7, 0xCD,
    61.   0xCA, 0xC1, 0xC0, 0xC8, 0xC9, 0xCF, 0xCE, 0xC4, 0xC6, 0xCC, 0xCB, 0xC2,
    62.     0xC5, 0xC3, 0x77,
    63.   0x7D, 0x7A, 0x71, 0x70, 0x78, 0x79, 0x7F, 0x7E, 0x74, 0x76, 0x7C, 0x7B,
    64.     0x72, 0x75, 0x73,
    65.   0x67, 0x6D, 0x6A, 0x61, 0x60, 0x68, 0x69, 0x6F, 0x6E, 0x64, 0x66, 0x6C,
    66.     0x6B, 0x62, 0x65,
    67.   0x63, 0x07, 0x0D, 0x0A, 0x01, 0x00, 0x08, 0x09, 0x0F, 0x0E, 0x04, 0x06,
    68.     0x0C, 0x0B, 0x02,
    69.   0x05, 0x03, 0x97, 0x9D, 0x9A, 0x91, 0x90, 0x98, 0x99, 0x9F, 0x9E, 0x94,
    70.     0x96, 0x9C, 0x9B,
    71.   0x92, 0x95, 0x93, 0xB7, 0xBD, 0xBA, 0xB1, 0xB0, 0xB8, 0xB9, 0xBF, 0xBE,
    72.     0xB4, 0xB6, 0xBC,
    73.   0xBB, 0xB2, 0xB5, 0xB3
    74. };
    75.  
    76. const static u8 k43[256] =
    77.   { 0x64, 0x6B, 0x6A, 0x60, 0x67, 0x62, 0x61, 0x6D, 0x63, 0x66, 0x68, 0x65,
    78.   0x69, 0x6C, 0x6F, 0x6E, 0xC4, 0xCB, 0xCA, 0xC0, 0xC7, 0xC2, 0xC1, 0xCD,
    79.     0xC3, 0xC6, 0xC8,
    80.   0xC5, 0xC9, 0xCC, 0xCF, 0xCE, 0x74, 0x7B, 0x7A, 0x70, 0x77, 0x72, 0x71,
    81.     0x7D, 0x73, 0x76,
    82.   0x78, 0x75, 0x79, 0x7C, 0x7F, 0x7E, 0x14, 0x1B, 0x1A, 0x10, 0x17, 0x12,
    83.     0x11, 0x1D, 0x13,
    84.   0x16, 0x18, 0x15, 0x19, 0x1C, 0x1F, 0x1E, 0x54, 0x5B, 0x5A, 0x50, 0x57,
    85.     0x52, 0x51, 0x5D,
    86.   0x53, 0x56, 0x58, 0x55, 0x59, 0x5C, 0x5F, 0x5E, 0xF4, 0xFB, 0xFA, 0xF0,
    87.     0xF7, 0xF2, 0xF1,
    88.   0xFD, 0xF3, 0xF6, 0xF8, 0xF5, 0xF9, 0xFC, 0xFF, 0xFE, 0xD4, 0xDB, 0xDA,
    89.     0xD0, 0xD7, 0xD2,
    90.   0xD1, 0xDD, 0xD3, 0xD6, 0xD8, 0xD5, 0xD9, 0xDC, 0xDF, 0xDE, 0x84, 0x8B,
    91.     0x8A, 0x80, 0x87,
    92.   0x82, 0x81, 0x8D, 0x83, 0x86, 0x88, 0x85, 0x89, 0x8C, 0x8F, 0x8E, 0x44,
    93.     0x4B, 0x4A, 0x40,
    94.   0x47, 0x42, 0x41, 0x4D, 0x43, 0x46, 0x48, 0x45, 0x49, 0x4C, 0x4F, 0x4E,
    95.     0xA4, 0xAB, 0xAA,
    96.   0xA0, 0xA7, 0xA2, 0xA1, 0xAD, 0xA3, 0xA6, 0xA8, 0xA5, 0xA9, 0xAC, 0xAF,
    97.     0xAE, 0x94, 0x9B,
    98.   0x9A, 0x90, 0x97, 0x92, 0x91, 0x9D, 0x93, 0x96, 0x98, 0x95, 0x99, 0x9C,
    99.     0x9F, 0x9E, 0xE4,
    100.   0xEB, 0xEA, 0xE0, 0xE7, 0xE2, 0xE1, 0xED, 0xE3, 0xE6, 0xE8, 0xE5, 0xE9,
    101.     0xEC, 0xEF, 0xEE,
    102.   0x04, 0x0B, 0x0A, 0x00, 0x07, 0x02, 0x01, 0x0D, 0x03, 0x06, 0x08, 0x05,
    103.     0x09, 0x0C, 0x0F,
    104.   0x0E, 0x34, 0x3B, 0x3A, 0x30, 0x37, 0x32, 0x31, 0x3D, 0x33, 0x36, 0x38,
    105.     0x35, 0x39, 0x3C,
    106.   0x3F, 0x3E, 0xB4, 0xBB, 0xBA, 0xB0, 0xB7, 0xB2, 0xB1, 0xBD, 0xB3, 0xB6,
    107.     0xB8, 0xB5, 0xB9,
    108.   0xBC, 0xBF, 0xBE, 0x24, 0x2B, 0x2A, 0x20, 0x27, 0x22, 0x21, 0x2D, 0x23,
    109.     0x26, 0x28, 0x25,
    110.   0x29, 0x2C, 0x2F, 0x2E
    111. };
    112.  
    113. const static u8 k21[256] =
    114.   { 0xD1, 0xDF, 0xDD, 0xD0, 0xD5, 0xD7, 0xDA, 0xD4, 0xD9, 0xD2, 0xD3, 0xDE,
    115.   0xD6, 0xDB, 0xD8, 0xD2, 0xB1, 0xBF, 0xBD, 0xB0, 0xB5, 0xB7, 0xBA, 0xB4,
    116.     0xB9, 0xB2, 0xB3,
    117.   0xBE, 0xB6, 0xBB, 0xB8, 0xB2, 0x41, 0x4F, 0x4D, 0x40, 0x45, 0x47, 0x4A,
    118.     0x44, 0x49, 0x42,
    119.   0x43, 0x4E, 0x46, 0x4B, 0x48, 0x42, 0x11, 0x1F, 0x1D, 0x10, 0x15, 0x17,
    120.     0x1A, 0x14, 0x19,
    121.   0x12, 0x13, 0x1E, 0x16, 0x1B, 0x18, 0x12, 0x31, 0x3F, 0x3D, 0x30, 0x35,
    122.     0x37, 0x3A, 0x34,
    123.   0x39, 0x32, 0x33, 0x3E, 0x36, 0x3B, 0x38, 0x32, 0xF1, 0xFF, 0xFD, 0xF0,
    124.     0xF5, 0xF7, 0xFA,
    125.   0xF4, 0xF9, 0xF2, 0xF3, 0xFE, 0xF6, 0xFB, 0xF8, 0xF2, 0x51, 0x5F, 0x5D,
    126.     0x50, 0x55, 0x57,
    127.   0x5A, 0x54, 0x59, 0x52, 0x53, 0x5E, 0x56, 0x5B, 0x58, 0x52, 0x91, 0x9F,
    128.     0x9D, 0x90, 0x95,
    129.   0x97, 0x9A, 0x94, 0x99, 0x92, 0x93, 0x9E, 0x96, 0x9B, 0x98, 0x92, 0x01,
    130.     0x0F, 0x0D, 0x00,
    131.   0x05, 0x07, 0x0A, 0x04, 0x09, 0x02, 0x03, 0x0E, 0x06, 0x0B, 0x08, 0x02,
    132.     0xA1, 0xAF, 0xAD,
    133.   0xA0, 0xA5, 0xA7, 0xAA, 0xA4, 0xA9, 0xA2, 0xA3, 0xAE, 0xA6, 0xAB, 0xA8,
    134.     0xA2, 0xE1, 0xEF,
    135.   0xED, 0xE0, 0xE5, 0xE7, 0xEA, 0xE4, 0xE9, 0xE2, 0xE3, 0xEE, 0xE6, 0xEB,
    136.     0xE8, 0xE2, 0x71,
    137.   0x7F, 0x7D, 0x70, 0x75, 0x77, 0x7A, 0x74, 0x79, 0x72, 0x73, 0x7E, 0x76,
    138.     0x7B, 0x78, 0x72,
    139.   0x61, 0x6F, 0x6D, 0x60, 0x65, 0x67, 0x6A, 0x64, 0x69, 0x62, 0x63, 0x6E,
    140.     0x66, 0x6B, 0x68,
    141.   0x62, 0x81, 0x8F, 0x8D, 0x80, 0x85, 0x87, 0x8A, 0x84, 0x89, 0x82, 0x83,
    142.     0x8E, 0x86, 0x8B,
    143.   0x88, 0x82, 0x21, 0x2F, 0x2D, 0x20, 0x25, 0x27, 0x2A, 0x24, 0x29, 0x22,
    144.     0x23, 0x2E, 0x26,
    145.   0x2B, 0x28, 0x22, 0xC1, 0xCF, 0xCD, 0xC0, 0xC5, 0xC7, 0xCA, 0xC4, 0xC9,
    146.     0xC2, 0xC3, 0xCE,
    147.   0xC6, 0xCB, 0xC8, 0xC2
    148. };
     
  7. OLS

    OLS New Member

    Публикаций:
    0
    Регистрация:
    8 янв 2005
    Сообщения:
    322
    Адрес:
    Russia
    Ну во-первых, честно скажу, что С для меня малознаком - я об это предупредил перед постом с кодом.

    А во-вторых, человек просил исходники - я полагаю, общеизвестно, что ГОСТ 28147 не специфицирует сами узлы замен. Следовательно, для учебных целей он может брать узлы какие угодно, хоть из ЦБ хоть из ГОСТ Р 34.11, а если пишет для серьезного проекта, то ему их "сверху спустят".
     
  8. alexanderwm

    alexanderwm New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2008
    Сообщения:
    43
    Правильно! Это я на заметку тем, кто будет использовать исходники.
     
  9. kapger

    kapger New Member

    Публикаций:
    0
    Регистрация:
    18 фев 2009
    Сообщения:
    135
    Спасибо большое за помощь!

    Начало положено, буду разбираться...

    Я очень (!) малознаком с С и совсем не знаком с ассемблером, так что и искал без ассемблерных вставок. Писал в свое время на VB, немножко Паскаль и Perl. А теперь приспичило на С, причем на очень своеобразной реализации - Neuron C для LON-контроллеров.
     
  10. kapger

    kapger New Member

    Публикаций:
    0
    Регистрация:
    18 фев 2009
    Сообщения:
    135
    Доброго времени суток!

    Пытаюсь вникать... Получается не очень...
    Из исходных кодов алгоритма выбрал два файла:
    1. Тот, который по ссылке из этой темы в архиве PPMP (libgost.ppmp).
    2. Тот, который показан в этой же теме в конце первой страницы в открытом виде.
    ... Есть и еще куча различных файлов, нарытых в инете, однако все они с ассемблерными вставками, что мне противопоказано, поэтому вопросы, с Вашего позволения, буду задавать касательно этих двух файлов.

    Почему эти два файла так сильно отличаются, если в файле №1 указано, что это доработанный вариант в части S-BOX. Насколько я понимаю, другие S-BOX и отсутствие в файле "инициализации" этих S-BOX должны иметь отличия в файлах, а остальное должно быть одинаковое? Где, например, в файле №1 имеющиеся в файле №2 строки, которые идут начиная со строки #define C1 0x01010104 и далее (до конца)?

    И самый главный вопрос, который касается несоответствия типов языка Neuron C и языка ANSI C:
    В Neuron C тип char = 8 бит, тип short int = 8 бит, тип long int = 16 бит. К сожалению, 32-битных типов там нет, а это, насколько я понимаю, краеугольный камень ГОСТа? А реализовать этот ГОСТ очень нужно на этом языке и для этого железа. Как выходить из этого положения?
     
  11. kapger

    kapger New Member

    Публикаций:
    0
    Регистрация:
    18 фев 2009
    Сообщения:
    135
    Небольшое дополнение...

    Если быть совсем точным, то Neron C немножко умеет работать с 32-битными числами, но очень ущербно...
    Вот выдержка из мануала:
    Код (Text):
    1. Signed 32-Bit Integer Support Functions
    2.  
    3. The Neuron C compiler does not directly support the use of the C arithmetic
    4. and comparison operators with signed 32-bit integers. However, there is a
    5. complete library of functions for 32-bit integer match. These functions are
    6. listed under Integer Math in the previous section. For example, in standard
    7. ANSI C, to evaluate X = A + B * C in long (32-bit) arithmetic, the '+' and '*'
    8. infix operators may be used as follows:
    9. long X, A, B, C;
    10. X = A + B * C;
    11. With Neuron C, this can be expressed as follows:
    12. s32_type X, A, B, C;
    13. s32_mul(&B, &C, &X);
    14. s32_add(&X, &A, &X);
    15. The signed 32-bit integer format can represent numbers in the range of
    16. ±2,147,483,647 with an absolute resolution of ±1.
    17. An s32_type structure data type for signed 32-bit integers is defined by
    18. means of a typedef in the file <S32.H>. It defines a structure containing an
    19. array of four bytes that represents a signed 32-bit integer in Neuron C
    20. format. This is represented as a two's complement number stored with the
    21. most significant byte first. The type declaration is shown here for reference:
    22. typedef struct {
    23. int bytes[ 4 ];
    24. } s32_type;
    25. All the constants and functions in <S32.H> are defined using the Neuron C
    26. signed 32-bit data type, which is a structure. Neuron C does not permit
    27. structures to be passed as parameters or returned as values from functions.
    28. When these objects are passed as parameters to C functions, they are passed
    29. as addresses (using the '&' operator) rather than as values. However,
    30. Neuron C does support structure assignment, so signed 32-bit integers may
    31. be assigned to each other with the '=' operator.
    32. No errors are detected by the 32-bit functions. Overflows follow the rules of
    33. the C programming language for integers, namely, they are ignored. Only
    34. the least significant 32 bits of the results are returned.
    35. Initializers can be defined using structure initialization syntax. For example:
    36. s32_type some_number = { 0, 0, 0, 4 }; // initialized to 4 on reset
    37. s32_type another_number = { -1, -1, -1, -16 }; // initialized to -16
    38. A number of constants are defined for use by the application if desired.
    39. s32_zero, s32_one, s32_minus_one represent the numbers 0, 1, and -1.
    40. If other constants are desired, they may be converted at runtime from ASCII
    41. strings using the function s32_from_ascii.
    42. EXAMPLE:
    43. s32_type one_million;
    44. when(reset) {
    45. s32_from_ascii("1000000", one_million);
    46. }
    47. Since this function is fairly time consuming, it may be advantageous to precompute
    48. constants with the NXT.EXE utility. This program accepts an input
    49. file with declarations using standard integer initializers, and creates an
    50. output file with Neuron C initializers. See the Neuron C Extended Arithmetic
    51. Translator section below.
    52. For example, if the input file contains:
    53. const s32_type one_million = 1000000;
    54. then the output file will contain:
    55. const s32_type one_million = {0x00,0x0f,0x42,0x40} /*
    56. 1000000 */;
    57. Users of the NodeBuilder tool can use Code Wizard to create initializer data
    58. for s32_type network variables and configuration parameters. The
    59. NodeBuilder Neuron C debugger can display signed 32-bit integers through
    60. the s32_type shown above.
    61. The LonBuilder’s Neuron C debugger can display signed 32-bit integers as
    62. raw data at a specific address. To examine the value of one or more
    63. contiguous signed 32-bit integer variables, enter the address of the first
    64. variable into the raw data evaluation window, select Raw Data at Address
    65. type, Data Size as quad, Count as the number of variables you wish to
    66. display, and Format as Dec. The data will be displayed as unsigned, even if
    67. it is negative. To view the data as signed, click on the value field, and the
    68. Modify Variable window will show the data in both formats. You can also
    69. modify signed 32-bit integer variables by clicking on the value field, and
    70. entering new data in the usual format for integers.
    71. The signed 32-bit integer arguments are all passed as addresses of
    72. structures. The calling function or task is responsible for declaring storage
    73. for the arguments themselves. Argument lists are ordered so that input
    74. arguments precede output arguments. In all cases, signed 32-bit integer
    75. output arguments may match any of the input arguments to facilitate
    76. operations in place.
    77.  
    78. Binary Arithmetic Operators
    79. void s32_add( const s32_type * arg1, const s32_type * arg2,
    80. s32_type * arg3 );
    81. Adds two signed 32-bit integers. ( arg3 = arg1 + arg2 )
    82. void s32_sub( const s32_type * arg1, const s32_type * arg2,
    83. s32_type * arg3 );
    84. Subtracts two signed 32-bit integers. ( arg3 = arg1 - arg2 )
    85. void s32_mul( const s32_type * arg1, const s32_type * arg2,
    86. s32_type * arg3 );
    87. Multiplies two signed 32-bit integers. ( arg3 = arg1 * arg2 )
    88. void s32_div( const s32_type * arg1, const s32_type * arg2,
    89. s32_type * arg3 );
    90. Divides two signed 32-bit integers. ( arg3 = arg1 / arg2 )
    91. void s32_rem( const s32_type * arg1, const s32_type * arg2,
    92. s32_type * arg3 );
    93. Returns the remainder of the division of two signed 32-bit integers
    94. ( arg3 = arg1 % arg2 ). The sign of arg3 is always the same as the sign of arg1.
    95. void s32_max( const s32_type * arg1, const s32_type * arg2,
    96. s32_type * arg3 );
    97. Returns the maximum of two signed 32-bit integers. ( arg3 = max(arg1, arg2 )).
    98. void s32_min( const s32_type * arg1, const s32_type * arg2,
    99. s32_type * arg3 );
    100. Returns the minimum of two signed 32-bit integers. ( arg3 = min( arg1, arg2 )).
    101.  
    102. Unary Arithmetic Operators
    103. void s32_abs( const s32_type * arg1, s32_type * arg2 );
    104. Returns the absolute value of a signed 32-bit integer. ( arg2 = abs(arg1 ) )
    105. void s32_neg( const s32_type * arg1, s32_type * arg2 );
    106. Returns the negative of a signed 32-bit integer. ( arg2 = - arg1 )
    107.  
    108. Comparison Operators
    109. boolean s32_eq( const s32_type * arg1, const s32_type * arg2 );
    110. Returns TRUE if the first argument is equal to the second argument,
    111. otherwise FALSE. ( arg1 == arg2 )
    112. boolean s32_ne( const s32_type * arg1, const s32_type * arg2 );
    113. Returns TRUE if the first argument is not equal to the second argument,
    114. otherwise FALSE. ( arg1 != arg2 )
    115. boolean s32_gt( const s32_type * arg1, const s32_type * arg2 );
    116. Returns TRUE if the first argument is greater than the second argument,
    117. otherwise FALSE. ( arg1 > arg2 )
    118. boolean s32_lt( const s32_type * arg1, const s32_type * arg2 );
    119. Returns TRUE if the first argument is less than the second argument,
    120. otherwise FALSE. ( arg1 < arg2 )
    121. boolean s32_ge( const s32_type * arg1, const s32_type * arg2 );
    122. Returns TRUE if the first argument is greater than or equal to the second
    123. argument, otherwise FALSE. ( arg1 >= arg2 )
    124. boolean s32_le( const s32_type * arg1, const s32_type * arg2 );
    125. Returns TRUE if the first argument is less than or equal to the second
    126. argument, otherwise FALSE. ( arg1 <= arg2 )
    127. int s32_cmp( const s32_type * arg1, const s32_type * arg2 );
    128. Returns +1 if the first argument is greater than the second argument, -1 if it
    129. is less, and 0 if it is equal.
    130.  
    131. Miscellaneous Signed 32-bit Functions
    132. int s32_sign( const s32_type * arg );
    133. Sign function, returns +1 if the argument is positive, 0 if the argument is
    134. zero, and -1 if the argument is negative.
    135. void s32_inc( s32_type * arg );
    136. Increments a signed 32-bit integer.
    137. void s32_dec( s32_type * arg );
    138. Decrements a signed 32-bit integer.
    139. void s32_mul2( s32_type * arg );
    140. Multiplies a signed 32-bit integer by two.
    141. void s32_div2( s32_type * arg );
    142. Divides a signed 32-bit integer by two.
    143. void s32_rand( s32_type * arg );
    144. Returns a random integer uniformly distributed in the range
    145. [-2,147,483,648 to +2,147,483,647].
    146.  
    147. Integer Conversions
    148. signed long s32_to_slong( const s32_type * arg );
    149. Converts a signed 32-bit integer to a Neuron C signed long integer
    150. (range 32,768 to +32,767). Overflow is ignored.
    151. unsigned long s32_to_ulong( const s32_type * arg );
    152. Converts a signed 32-bit integer to a Neuron C unsigned long integer
    153. (range 0 to 65,535). Overflow is ignored.
    154. void s32_from_slong( signed long arg1, s32_type * arg2 );
    155. Converts a Neuron C signed long integer (range -32,768 to +32,767) to a
    156. signed 32-bit integer.
    157. void s32_from_ulong( unsigned long arg1, s32_type * arg2 );
    158. Converts a Neuron C unsigned long integer (range 0 to +65,535) to a signed
    159. 32-bit integer.
    160.  
    161. Conversion of Signed 32-bit to ASCII String
    162. void s32_to_ascii( const s32_type * arg1, char * arg2 );
    163. Converts a signed 32-bit integer *arg1 to an ASCII string followed by a
    164. terminating null character. The *arg2 output buffer should be at least 12
    165. bytes long. The general output format is [-]xxxxxxxxxx, with one to nine
    166. digits.
    167.  
    168. Conversion of ASCII String to Signed 32-bit
    169. void s32_from_ascii( const char * arg1, s32_type * arg2 );
    170. Converts an ASCII string arg1 to a signed 32-bit integer *arg2. The
    171. conversion stops at the first invalid character in the input buffer - there is no
    172. error notification. The acceptable format is [-]xxxxxxxxxx. The number of
    173. digits should not exceed ten. Embedded spaces within the string are not
    174. allowed.
    Достаточно ли этого расширенного набора для проведения вычислений и преобразований по ГОСТ?
     
  12. OLS

    OLS New Member

    Публикаций:
    0
    Регистрация:
    8 янв 2005
    Сообщения:
    322
    Адрес:
    Russia
    В ГОСТе всего 3 вида 32-разрядных операций (подстановку sbox не считаю) :
    - XOR
    - сложение ADD
    - циклический сдвиг ROL

    Если процессор 16-разрядный, то

    XOR делается по частям вообще без каких-либо дополнений

    ADD делается с учетом флага переноса (ADD младших половинок, затем ADC старших половинок)

    ROL делается за 4 операции 16-битных ROL/ROR с учетом того в какие позиции должны попасть соответствующие биты
     
  13. kapger

    kapger New Member

    Публикаций:
    0
    Регистрация:
    18 фев 2009
    Сообщения:
    135
    А можно чуть подробнее? Как для... чайника, да.
     
  14. kapger

    kapger New Member

    Публикаций:
    0
    Регистрация:
    18 фев 2009
    Сообщения:
    135
    Поправьте, если ошибаюсь...

    Например, имеем 32-битные беззнаковые числа, состоящие в моей реализации из двух 16-битных беззнаковых чисел:
    unsigned long xHi, xLo, tmpHi, tmpLo;

    тогда функция замены и сдвига на 11 бит, описанная в этой теме, аналогично показанной ниже:
    Код (Text):
    1. tmp = k87[x >> 24 & 255] << 24 | k65[x >> 16 & 255] << 16 | k43[x >> 8 & 255] << 8 | k21[x & 255];
    2. x = (tmp << 11) | (tmp >> (32 - 11));
    получаем:
    Код (Text):
    1. tmpHi = k87[xHi >> 8 & 255] << 8 | k65[xHi  & 255];
    2. tmpLo = k43[xLo >> 8 & 255] << 8 | k21[xLo & 255];
    3. xHi = (tmpHi << 11) |  (tmpLo >> (16-11));
    4. xLo = (tmpLo << 11) |  (tmpHi >> (16-11));
    Не уверен, что правильно...

    P.S. Вообще не понимаю, как сделать
     
  15. OLS

    OLS New Member

    Публикаций:
    0
    Регистрация:
    8 янв 2005
    Сообщения:
    322
    Адрес:
    Russia
    Да именно так. По моему все коэффициенты верны.

    В Ассемблере в случае переполнения при сложении/вычитании устанавливается флаг переноса в значение 1. А команда ADC складывает кроме двух чисел еще и третий компонент - значение флага переноса (от предыдущего сложения).

    Как это реализовать на языке высокого уровня ?

    Могу лишь предположить вот такой код, наверное,
    программисты меня подправят более простым решением :
    Код (Text):
    1. пытаемся вычислить z=x+y
    2.  
    3. zLo:=xLo+yLo;
    4. zHi:=xHi+yHi;
    5. if (zLo<xLo) then zHi:=zHi+1
    все 6 переменных обязательно должны быть беззнаковыми (16-битными), только тогда условие (zLo<xLo) уникально указывает на произошедшее переполнение из 15-го в 16-ый разряд при сложении
    (проверять можно и второе условие zLo<yLo - без разницы)
     
  16. kapger

    kapger New Member

    Публикаций:
    0
    Регистрация:
    18 фев 2009
    Сообщения:
    135
    Продолжим, с Вашего позволения...

    По поводу инициализации синхропосылки.
    Нашел вот такой кусок:
    Код (Text):
    1. ULONG64 WINAPI gInitSynchro(PULONG Key){
    2.  
    3.     ULONG64 Result = 0;
    4.     PULONG64 p_int64 = (PULONG64)Key;
    5.  
    6.     // Инициируем синхропосылку из ключей (XOR 64-х битные слова)
    7.     for(int i = 0; i < 4; i++){
    8.         Result ^= *(p_int64 + i);
    9.     }
    10.  
    11.     return Result;
    12. }
    Зачем нужен этот кусок? И как он увязывается, например, с описанной ниже опцией, взятой из программы GOST32.EXE А.Винокурова:
    /s<значение> - задает синхропосылку, <значение> - от 1 до 16 16-ричных цифр;
     
  17. mart

    mart New Member

    Публикаций:
    0
    Регистрация:
    1 окт 2007
    Сообщения:
    67
    За такие куски надо отрывать руки программистам:) А этот кусок нужен для того, чтобы помочь злоумышленнику дешифровать шифртекст, очевидно.
     
  18. kapger

    kapger New Member

    Публикаций:
    0
    Регистрация:
    18 фев 2009
    Сообщения:
    135
    Тогда как правильно должна выглядеть инициализация синхропосылки и дальнейшее вычисление гаммы? Особенно интересует как правильно реализовать на Си формулы вычисления шага работы РГПЧ, описанный у А.Винокурова:
    S0=(S0+C1)mod2^32
    S1=(S1+C2–1)mod(2^32–1)+1
    А то есть много (нарытого на просторах инета) кусков, написанных настолько по-разному, что общая картина никак не складывается! И ведь для того, чтобы весь алгоритм переложить на 16-тиразрядную платформу, нужно полностью разобраться с тем, что есть...
     
  19. mart

    mart New Member

    Публикаций:
    0
    Регистрация:
    1 окт 2007
    Сообщения:
    67
    Синхропосылка выбирается случайным образом,т.е. для её успешной реализации необходим псевдослучайный генератор. У Винокурова написано что используется не сама сгенерированная синхропосылка S, а результат шифрования S на ключе K. Мне кажется вы совершенно не понимаете, что есть синхропосылка и почему нельзя её генерировать так, как написано в предыдущем куске кода. А это плохо. Если нужно могу объяснить.




    Лучше замутить на асме, тогда первая команда add S0,C1 а вторая adc S1,C2. Надеюсь не наврал. Если же нужен Си, то, как известно, mod - это оператор "%".
     
  20. kapger

    kapger New Member

    Публикаций:
    0
    Регистрация:
    18 фев 2009
    Сообщения:
    135
    Однозначно не понимаю... И буду премного благодарен, если Вы объясните.

    Асм не пойдет, т.к. я уже писал выше, что нужна реализация на Си-подобном языке для 16-разрядной платформы: