kapger давай по шагам, что делаем. 1. синхропосылку (берем её из поста 155) шифрум по ECB -тут у нас совпал результат 2. что получилось после первого шага- в качестве аргумента передаем в ф-ю гаммирование. Так оно же? а вот как должно быть 1. Берем (формируем) 64-разрядное случайное число S. 2. Шифруем S методом простой замены. S=Ц32-з(S) 3. Разбиваем S на две 32-х разрядные части: S0 (младшая часть) и S1 (старшая). 4. Каждую часть вычисляем отдельно, используя вышеуказанные константы: S0=S0+C1 (mod 2^32) S1=S1+C2-1 (mod (2^32)-1) + 1 5. Склеиваем S0 и S1 обратно в S. 6. Шифруем S методом простой замены S=Ц32-з(S). 7. Читаем 64 бит входных данных и делаем поразрядный xor с нашим S. Повторяем шаги 3 - 7, пока не закончатся входные данные. Последний блок входных данных может быть меньше чем 64 бит. В этом случае поразрядный xor производится только с необходимыми разрядами S. тут шаг 1 и2 у нас в первом пункте. Пока есть замечания?
metcenger Замечаний особых пока нет Разве что синхропосылка может и не быть случайным числом, а может вырабатываться источником (шифровальщиком) и приемником (дешифровальщиком) синхронно по определенному закону. Но это к математике, которую мы здесь проверяем, не относится... Да и написание S1=S1+C2-1 (mod (2^32)-1) + 1 - по сути правильное, а по реализации будет затык. Но не сейчас, а вскоре (не в этом примере), на этом мы остановимся отдельно и чуть позже Так что резюме: все написанное в посте выше - верно. А где числа-то? Где результаты?
kapger в моем списке 3-й пункт- разбил. S1= FEFEFEFB S0= 4DA15E7C 4. после выполнения (так в программе и написано- никаких затыков тут) S0= S0 + C1; //(mod 2^32) S1= S1 + C2-1; //(mod (2^32)-1) + 1 результат равен S1= FFFFFFFE S0= 4EA25F7D пока совпало?
metcenger Нет! S1 должен быть не FFFFFFFE, а FFFFFFFF Проверяй! Открой сам ГОСТ (приложение к нему) и внимательно почитай про правила суммирования по модулю 2^32-1
kapger очень спорно. Цитируя Винокура, Второе выражение нуждается в комментариях, так как в тексте ГОСТа приведено нечто другое что, оказывается, под операцией взятия остатка по модулю 2^32–1 там понимается не то же самое, что и в математике Отличие заключается в том, что согласно ГОСТу = (2^32–1), а не 0. ну и вот на схеме процесса гаммирования так выкачай отсюда фотку http://files.mail.ru/A8UMHA да и на 1-й странице Olegras все четко описал, и эти две формулы так и реализуются а с S0= S0 + C1; //(mod 2^32) ты согласен?
metcenger Если будем цитировать Винокурова, то я докажу таки, что у тебя немного неправильно! И у Винокурова и у olegras написано правильно, а вот у тебя немного не то... Смотри (кусок из сообщения olegras): С первым выражением я полностью согласен. С одним уточнением: S0 и C1 должны быть 32-битными беззнаковыми! А во втором выражении ты потерял сложение последней единички То есть сначала вычел единичку, а вот прибавить обратно - забыл. Кроме того, чуть раньше я писал, что указанная формула вычисления S1 требует добавления дополнительных скобок, иначе может быть ситуация, когда S1 и C2 (должны быть тоже 32-битными беззнаковыми!) при сложении и переполнении дадут в результате 0, а потом ты будешь вычитать из 0 единицу... Что будет? Будет глюк! И именно этот глюк мы с тобой и будем рассматривать в варианте синхропосылки №2 Готовься... Так что формула должна быть такая (см. сообщение №48 http://www.wasm.ru/forum/viewtopic.php?pid=311653#p311653):
metcenger Кстати, последнюю конструкцию можно и упростить, если переменные S1 и C2 - 32-битные беззнаковые. В этом случае действие просто лишнее, насколько я понимаю... Переполнение и так отбросится, так что можно написать Поправьте меня, если я не прав...
А вообще, если абстрагироваться от языков программирования, то сложение по модулю (2^32-1) означает следующее: Складываем два 32-битных беззнаковых числа. Если переполнения нет - то ответом является сумма этих чисел. Если переполнение было (ну и отбросилось, соответственно), то добавляем к сумме этих чисел (уже с отброшенным переполнением) единицу! Вот кусок из файлов Винокурова, который описывает в первой строке сложение по модулю 2^32, а во второй-третьей строке - сложение по модулю (2^32-1), причем во второй строке происходит сложение по модулю 2^32, а в третьей - добавление единицы, если было переполнение!
kapger точнее сказать, в третьей строке регистр EDX равен EDX +0 + переполнение, если конечно было... http://www.wasm.ru/forum/viewtopic.php?id=28853&p=1 топик 13. я олеграса спрашивал, как програмно это реализовать. Как написано до скобок? Сказал- да. если мы берем ассемблер add EDX,C2 adc EDX,0 это ни что иное, как просто сложение двух чисел, учитывая знак переноса, т.е. если мы сложим 49103 в десятичной форме и 62445 получим 111548 это, конечно больше, чем 16 бит- это 17 бит, вот он и вылез перенос. а почему тогда на картинке моей указана реализация без этого +1 ??? т.е. хочешь сказать, что надо вместо S1= S1 + C2-1; использовать S1 = S1 + (C2 - 1) + 1 так?
kapger дваай по- другому c этим S1, что мы должны получить? По простому, на числах. как было бы правильно. 2-3 примера. C2 у нас известна C2= 0x01010104; или C2= 42 в десятичном. Дальше будет видно как реализовать уже
metcenger Как это C2=42 в десятичном? C2 в десятичном равняется 16843012 ! Примеры для S1 = S1 + (C2 - 1) + 1 (в десятичном виде) S1=4278124283; C2=16843012; Их сумма по модулю (2^32-1) должна быть равна 4294967295 (0xFFFFFFFF) S1=4278124284; C2=16843012; Их сумма по модулю (2^32-1) должна быть равна 1 (0x00000001) S1=4278124285; C2=16843012; Их сумма по модулю (2^32-1) должна быть равна 2 (0x00000002)
kapger да, да, конечно же равняется 16843012. Моя ошибка. По запаре вставил как двоичное число. сейчас поскладываю, отпишусь. Пара вопросов не по теме- ты вроде как просил за деньги написать алгоритм. Были предложения? Или сам все- таки решился? Перечитал и Шнайера и Винокура, нигде не нашел, что в конце 32-3 и 32-Р меняем нибблы местами. Это работает, согласен. Но, почему там ни слова?
kapger прогнал на калькуляторе и в проге. Калькулятор упорно не хочет понимать что всего 32 бита данных и загоняет при переполнении в 33 бит 1. Зато прога (а в ней С1 и С2 объявлено как 32- битное целое), хорошо считает. Но, позволь теья подправить, вторая строчка S1=4278124284; C2=16843012; Их сумма по модулю (2^32-1) должна быть равна 1 (0x00000001) даст вконце не 0x00000001 а 0. т.к. S1 мы увеличиваем на 1, а след. значение после FFFFFFFF будет 0. Зато последняя 3-я строка уже даст 1 вконце. Т.е. строка S1 = S1 + (C2 - 1) + 1 в коде Си работает.
metcenger Отвечаю по порядку... Желающих не нашлось. Так как очень специфичная реализация требовалась - для 16-разрядного микропроцессора и на специфичном же Си-подобном языке. А чего решаться-то? Если время жмет, доклады и статьи надо писать, некогда думать... Сам разобрался. Открываем статью Винокурова на странице 7, рисунки 2а и 2б, смотрим блок №3 - там написано N1<->N2. А вот и неверно! Открываем ГОСТ в исходниках. Здесь в этой теме ссылка была на скан. Смотрим в самом конце Приложение 4. Там сказано так: Вот эта фраза - единственно (изначально) правильная. А все остальное - перекомпиляция. И, надо сказать, у Винокурова правильная и очень элегантная компиляция. Все остальное - от лукавого... Так что берем калькулятор и считаем вручную, а потом удивляемся...
И вторая строчка будет в конце именно 0x00000001, а последняя 3-я строка уже даст в конце 0x00000002. Проверяй именно вручную!
kapger ещё больше запутал ))) другими словами, так S1 = S1 + (C2 - 1) + 1 работать не будет. ? т.е. мы должны получить иенно то, что ты привел 3 примера десятичных ?
metcenger так работать будет, если S1 и C2 - оба 32-битные беззнаковые. Ну возьми уже эти три примера сложения десятичных чисел по модулю (2^32-1) и посчитай их карандашом на бумаге (в теории), как это указано в самом ГОСТ. И эти же три примера посчитай на компьютере по этой формуле. И сравни... Должно получиться одно и то же...
kapger я понял идею. Однако, изловчились они с ГОСТом этим... S1 = S1 + (C2 - 1) + 1 не работает, как мы хотим, т.к. при проверке второй строки S1=4278124284; C2=16843012; Их сумма по модулю (2^32-1) должна быть равна 1 (0x00000001) результат S1 =0. Мы хотим, чтобы был =1. Думаю, как это на Си провернуть. Вопрос- точно уверен, что так надо? Или ошибаешься может? может ответ 0 должен быть все- таки?