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

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

  1. mart

    mart New Member

    Публикаций:
    0
    Регистрация:
    1 окт 2007
    Сообщения:
    67
    Попробую объяснить смысл синхропосылки как можно более бытовым языком. Из самого слова "синхропосылка" можно выяснить, что оно посылается с чем-то синхронно. Вопрос: с чем? Ответ: с шифртекстом. Т.е для простоты рассмотрим вариант, когда посылаются несколько зашифрованных сообщений на ключе К. Каждое сообщение выглядит так: синхропосылка || шифртекст. Шифртекст зависит от ключа шифрования К, содержимого открытого текста и синхропосылки. Каким образом эта зависимость выглядит определяется режимом шифрования, в данном ответе это не так существенно. Синхропосылка может передаваться в открытом виде, шифровать её не всегда обязательно. Что от неё требуется? От неё требуется 2 свойства: уникальность и случайность. Уникальность состоит в том, чтобы при различных сообщениях находились различные синхропосылки. Для некоторых режимов шифрования как, например, счётчик(CTR) это свойство критически важно. А случайность можно понимать как независимость от ключа К и открытого текста. Это конечно же неверное определение, но от синхропосылки требуется чтобы злоумышленник перехватив её не узнал ничего для себя полезного. В предыдущем куске кода, который вы привели, синхропосылка зависит от ключа, причём очень простым и незатейливым способом. Это означает, что фактически вы отправляете ключ по сети в незащищённом виде и он попадает в руки злоумышленника в слегка измененном виде. Это сводит в ноль все усилия по шифрованию, т.е. вы с тем же уровнем защиты могли бы просто отправлять открытый текст.

    Что ещё хочется добавить: если вам нужна защита для чего-либо и качественная реализация ГОСТ на 16-разрядном проце не поленитесь и наймите человека, который за деньги сделает все как положено. Боюсь у вас лично могут возникнуть большие проблемы в реализации, о которых вы и не подозреваете сейчас. Успехов!
     
  2. kapger

    kapger New Member

    Публикаций:
    0
    Регистрация:
    18 фев 2009
    Сообщения:
    135
    Понял, спасибо! Это я более-менее понимаю... Я только не понял и не смог увязать приведенный кусок кода со стандартом...
    Еще хочу добавить цитату из статьи Винокурова:
    Для моей задачи наиболее удобно использовать предопределенное значение синхропосылки или вырабатывать ее
    синхронно источником и приемником по определенному закону. Вопрос встает в реализации...

    По поводу:
    Я готов к такому предложению, в том числе в Ваш адрес... Встречные предложения жду в личке.
     
  3. mart

    mart New Member

    Публикаций:
    0
    Регистрация:
    1 окт 2007
    Сообщения:
    67
    Я вам дам дружеский совет: напишите краткое резюме того, что нужно сделать и опубликуйте это в ветке WASM.COMMERCE и ждите предложений в личку=)
     
  4. kapger

    kapger New Member

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

    Ну а пока жду, хочу продолжить:
    Код (Text):
    1. S0=(S0+C1)mod2^32
    2. S1=(S1+C2–1)mod(2^32–1)+1
    правильно ли будет следующее в реализации ANSI C:
    Код (Text):
    1.     // S - беззнаковое 64 бит, передается в эту функцию и возвращается обратно
    2.     // S0 и S1 - беззнаковые 32 бит, используются только внутри этой функции
    3.     S0 = S & 0xFFFFFFFF;
    4.     S1 = (S >> 32) & 0xFFFFFFFF;
    5.     const C1 = 0x01010101, C2 = 0x01010104;
    6.     S0 += C1;
    7.     S1 = ((S1 + C2 - 1) % 0xFFFFFFFF) + 1;
    8.     S = S1;
    9.     S = (S << 32) | S0;
    10.     return S;
     
  5. kapger

    kapger New Member

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

    Подскажите, плиз, по вышеприведенному примеру. Особенно интересует строчка:
    Код (Text):
    1. S1 = ((S1 + C2 - 1) % 0xFFFFFFFF) + 1;
    Может ли кто на пальцах как для школьника объяснить смысл этой строчки?
    Иначе я ничего не понимаю...
     
  6. kapger

    kapger New Member

    Публикаций:
    0
    Регистрация:
    18 фев 2009
    Сообщения:
    135
    Особенно не понимаю следующее:
    Если мы два 32-битных числа S1 и C2 сложили (и отбросили бит переполнения, если он возник) и затем вычли из этой суммы единицу, то получившееся число будет всегда меньше, чем 0xFFFFFFFF. Или я не прав? И дальше: остатком отделения этого (меньшего) числа на (большее) 0xFFFFFFFF будет это само меньшее число. Тогда зачем вообще делить?
     
  7. kapger

    kapger New Member

    Публикаций:
    0
    Регистрация:
    18 фев 2009
    Сообщения:
    135
    Нашел вот такое: (http://protect.htmlweb.ru/gost.htm)
    [+] - сложение 32-разрядных чисел по модулю 2^32;
    {+} - сложение 32-разрядных чисел по модулю 2^32-1.

    Числа суммируются по следующему правилу:
    A [+] B = A + B, если A + B < 2^32,
    A [+] B = A + B - 2^32, если A + B >= 2^32.
    A {+} B = A + B , если A + B < 2^32 - 1,
    A {+} B = A + B - (2^32 - 1), если A + B >= 2^32 - 1.

    И как эту теорию сложения 32-разрядных чисел по модулю 2^32-1 применить на языке Си для A и B, если они изначально 32-битные, как в вышеприведенном примере S1 = ((S1 + C2 - 1) % 0xFFFFFFFF) + 1?
    То есть, если в Си складывать два 32-битных числа A + B, то лишний бит (в случае переполнения, когда A + B >= 2^32 - 1) у нас все-равно отбросится или как? И если он отбросится, то нам нужно проверять на переполнение, а потом вычитать из суммы: A + B - (2^32 - 1), причем держа в уме бит переполнения?
     
  8. kapger

    kapger New Member

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

    Раз никто не хочет поддерживать разговор, продолжу дискуссию сам с собой...
    Вышеприведенная конструкция
    Код (Text):
    1. A {+} B = A + B , если A + B < 2^32 - 1,
    2. A {+} B = A + B - (2^32 - 1), если A + B >= 2^32 - 1.
    - неверна! На указанном выше сайте имеется ошибка, заключающаяся в том, что в оригинальном тексте ГОСТа указано иное:
    Код (Text):
    1. A {+} B = A + B , если A + B < 2^32,
    2. A {+} B = A + B - (2^32 - 1), если A + B >= 2^32.
    Поэтому, конструкция для 32-битной реализации на Си:
    Код (Text):
    1. S1 = ((S1 + C2 - 1) % 0xFFFFFFFF) + 1
    в принципе верна, но точнее будет вот так:
    Код (Text):
    1. S1 = ((S1 + (C2 - 1)) % 0xFFFFFFFF) + 1
    , иначе при определенных условиях мы можем получить отрицательное число при вычислении S1 + C2 - 1.

    Если рассматривать файл-исходник Винокурова "GAMMA_.ASM", то там указано так:
    Код (Text):
    1. add     EAX,C1          ; N1=(N1+C1)mod 2^32
    2. add     EDX,C2          ; N2=(N2+C2)mod 2^32
    3. adc     EDX,0           ; N2=(N2+C2)mod(2^32-1)
    , и, ориентируясь на эту конструкцию, текст самого ГОСТа и статью Винокурова для 32-битной реализации на Си все становится правильно и прозрачно:
    Код (Text):
    1. S1 = ((S1 + (C2 - 1)) % 0xFFFFFFFF) + 1
    .
     
  9. kapger

    kapger New Member

    Публикаций:
    0
    Регистрация:
    18 фев 2009
    Сообщения:
    135
    А для 16-битной реализации будет так:
    Код (Text):
    1. // S - беззнаковое 64 бит, виртуально состоит из 4-х 16-битных чисел {S1Hi,S1Lo,S0Hi,S0Lo}
    2. // S0 = S & 0xFFFFFFFF;
    3. // S1 = (S >> 32) & & 0xFFFFFFFF;
    4. // S1Hi, S1Lo, S0Hi, S0Lo - беззнаковые 16-битные числа
    5. unsigned long S1Hi, S1Lo, S0Hi, S0Lo; // беззнаковые 16-бит
    6. const unsigned long C1Hi=0x0101, C1Lo=0x0101; // C1=0x01010101
    7. const unsigned long C2Hi=0x0101, C2Lo=0x0104; // C2=0x01010104
    8.  
    9. // S0 += C1, тоже, что и S0 = (S0 + C1)mod2^32
    10. S0Hi += C1Hi;
    11. S0Lo += C1Lo;
    12. if (S0Lo < C1Lo) ++S0Hi;
    13.  
    14. // S1 = (S1 + C2)mod2^(32-1), тоже, что и S1 = ((S1 + (C2 - 1)) % 0xFFFFFFFF) + 1,
    15. // тоже, что и:
    16. // add     EAX,C1          ; N1=(N1+C1)mod 2^32
    17. // add     EDX,C2          ; N2=(N2+C2)mod 2^32
    18. // adc     EDX,0           ; N2=(N2+C2)mod(2^32-1)
    19. S1Hi += C2Hi;
    20. S1Lo += C2Lo;
    21. if (S1Lo < C2Lo) ++S1Hi;
    22. if (S1Hi < C2Hi) ++S1Lo;
    Здесь есть сомнения по поводу двух последних подряд идущих условий "If..." Может быть правильнее будет так?
    Код (Text):
    1. if (S1Lo < C2Lo)
    2. {
    3.   ++S1Hi;
    4.   if (S1Hi < C2Hi) ++S1Lo;
    5. }
    Поправьте меня, если в чем либо ошибаюсь...
     
  10. irrona

    irrona Member

    Публикаций:
    0
    Регистрация:
    26 май 2004
    Сообщения:
    178
    Адрес:
    Тирасполь
  11. kapger

    kapger New Member

    Публикаций:
    0
    Регистрация:
    18 фев 2009
    Сообщения:
    135
    Прошу с этого места:
    поподробнее... Иначе получается голословно...
    Первоисточник читал... и не раз :)
    Но, так как качество Вашего скана выше, чем то, которое у меня имеется, то Ваш скан однозначно пригодится!
     
  12. irrona

    irrona Member

    Публикаций:
    0
    Регистрация:
    26 май 2004
    Сообщения:
    178
    Адрес:
    Тирасполь
    kapger

    В описании основного шага криптопреобразования по ГОСТ 28147 Винокуров на схеме представил вроде бы всё верно. Но в описании алгоритма забыл указать, что перед выполнением "Шаг 1" необходимо сохранить значение заполнения N1, чтобы затем на "Шаг 5" использовать его для заполнения N2. А такая мелочь в описании может сильно испортить жизнь начинающему крипто-кодеру. По-крайней мере я при реализации алгоритма, лишился немалого количества серого вещества из-за такого, на мой взгляд, "вольного" подхода к описанию ГОСТа.
     
  13. irrona

    irrona Member

    Публикаций:
    0
    Регистрация:
    26 май 2004
    Сообщения:
    178
    Адрес:
    Тирасполь
    В описании режима гаммирования также нет однозначности. Нет указания на то, что между вторым и третьим шагами алгоритма необходимо сохранить значение синхропосылки. По описанию и схеме выходит, что для каждого последующего цикла выработки гаммы шифра, необходимо использовать выработанную ранее гамму. А это не так.
     
  14. kapger

    kapger New Member

    Публикаций:
    0
    Регистрация:
    18 фев 2009
    Сообщения:
    135
    Вроде бы Винокуров именно так и описал, как должно быть... Или я не прав?
    Смотрим pdf-файл http://www.enlight.ru/crypto/download/articles/vinokurov/28147_89.zip на странице 6 в самом верху есть рисунок (Рис.1. Схема основного шага криптопреобразования алгоритма ГОСТ 28147-89) и рядом с ним описание шагов. Что в блок-схеме рисунка, что в описании Шага 5 указано, что N2=N1. По моему мнению, соответствует ГОСТу.
     
  15. irrona

    irrona Member

    Публикаций:
    0
    Регистрация:
    26 май 2004
    Сообщения:
    178
    Адрес:
    Тирасполь
    kapger

    Если прослеживать схему - всё верно. Если же читать описание: "Шаг 1. Сложение с ключом. Младшая половина преобразуемого блока складывается по модулю 2^32 с используемым на шаге элементом ключа, результат передается на следующий шаг", то логика подсказывает, что N1 нужно сложить с элементом ключа. На самом деле с ключом складывается копия N1, расположенная в S.
     
  16. irrona

    irrona Member

    Публикаций:
    0
    Регистрация:
    26 май 2004
    Сообщения:
    178
    Адрес:
    Тирасполь
    Может быть немного непонятно я объясняю. Попробую иначе. У Винокурова на схеме в Шаг 1 показано:
    Код (Text):
    1. S = (N1 + X) Mod 2^32
    На самом же деле, согласно официальному ГОСТу должно быть так:
    Код (Text):
    1. S = N1
    2. S = (S + X) Mod 2^32
    В таком случае N1 сохраняется и может быть правильно использован на Шаг 5.
     
  17. kapger

    kapger New Member

    Публикаций:
    0
    Регистрация:
    18 фев 2009
    Сообщения:
    135
    С этим тоже позвольте не согласиться...
    Синхропосылку (начальное заполнение) мы не сохраняем! А точнее мы ее сохраняем (даже не ее саму, а сначала зашифрованную синхпропосылку, после чего единожды суммированную по частям с соответствующими константами C) только между первым и вторым блоком гаммы, а далее (при выработке второго и далее блоков гаммы) сохраняется уже не сама синхропосылка (пусть даже она уже зашифрованная и единожды суммированная с соответствующими константами C), а ее неоднократное нарастающее суммирование с константами C. Вот, смотрите... Если следовать ГОСТу, то, в соответствии с пунктом 3.1.4 в предложении чуть ниже чертежа 3 указано, что "при этом заполнение N3, N4 сохраняется" для выработки первого блока гаммы, где и используется именно синхропосылка (уже зашифрованная и единожды суммированная с соответствующими константами C). Но только на первом блоке гаммы используется синхропосылка! Далее в ГОСТе указано в пункте 3.1.5, что "Для получения следующего 64-разрядного блока гаммы заполнение N4... и N3...", сохраненные ранее, суммируются, соответственно, с константами C1 и C2, после чего уже эти суммы становятся заполнением N4 и N3, соответственно. И уже после этого "... заполнение N3 и N4 сохраняется". И так далее...

    То есть, указанное у Винокурова на рисунке 4 в шаге 2 полностью соответствует ГОСТу:
    S0=S0+C1 (в редакции ГОСТа N4=N4+C1)
    S1=S1+C2 (в редакции ГОСТа N3=N3+C2)
     
  18. kapger

    kapger New Member

    Публикаций:
    0
    Регистрация:
    18 фев 2009
    Сообщения:
    135
    С этими Вашими утверждениями я согласен. Но, все дело в том, что с точки зрения программирования - эти два варианты одинаковы! Ну разве что одно лишнее (и вроде бы абсолютно ненужное) действие присваивания:
    Код (Text):
    1. S = N1
     
  19. kapger

    kapger New Member

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

    Проверял ли кто реализацию собственного алгоритма шифрования в режиме простой замены с реализацией Винокурова на примере его файла GOST32.EXE и его же ключа KEY.KEY и таблицы замен CHANGTBL.CHT? Все эти файлы есть в исходниках Винокурова. То есть, если взять какое-либо 64-битное число и зашифровать его в режиме простой замены с помощью Вашего алгоритма с использованием указанных ключа и таблицы замен, то результат шифрования должен совпадать с результатом шифрования, полученным с помощью программы Винокурова GOST32.EXE! И то же самое для расшифрования...

    Также, в рамках этого вопроса, интересует порядок расположения элементов ключа в файле KEY.KEY и элементов таблицы в таблице замен CHANGTBL.CHT. То есть, если смотреть от начала файла, то элементы ключа идут по порядку в виде key0, key1, ... key7 или в обратном порядке? А в таблице замен элементы идут по порядку в виде k8, k7, ... k0 или в обратном порядке?
     
  20. kapger

    kapger New Member

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

    Тогда подскажите ссылку на программу (можно Вашу личную), которая однозначно соответствует ГОСТу, имеет возможность каким-либо способом явно указать ключ и таблицу замен, чтобы в итоге можно было получить результат шифрования тестовой строки, и результат которого будет равен результату шифрования с помощью программы Винокурова. Будем считать, что реализация Винокурова наиболее правильная, так?

    Зачем это надо? Мне нужно проверить свою реализацию (для микропроцессора, скажем так), которой нет никакого доверия с моей же стороны. Зато есть доверие к программе Винокурова, но нет полного понимания о расположении ключевых элементов в соответствующих файлах (см. предыдущий пост). То, что в моей реализации результат шифрования при его последующей расшифровке совпадает с исходным текстом - это еще ни о чем не говорит, насколько я понимаю...

    Пытался найти в сети подобные программы, чтобы проверить себя же... Есть либо простые программы, которые используют неизвестно какую таблицу замен, либо вообще ничего хорошего нет... Одну программу, правда, нашел, которая позволяет явно указывать и ключ и таблицу замен, так ее результат отличается как от программы Винокурова, так и от моего результата. Получается полная ерунда... Кому верить?