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

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

  1. kapger

    kapger New Member

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

    Так. Я нашел свою же ошибку!
    В сообщении http://wasm.ru/forum/viewtopic.php?pid=323578#p323578 я написал, что действие
    можно выкинуть. Ан нет! Ошибся. В этом вся и суть. Дело в том, что я у себя считаю в 16-разрядных переменных, а там вовсе все не так. И поэтому, чтобы объяснить тебе, то пытаюсь в голове на лету перекомпилировать в 32-битные. Вот и пролетел.

    Давай по новой объясню...

    Должно быть так:
    Вот, повторяю пример:
    S1=4278124284; C2=16843012
    сложение S1 + C2 должно быть по модулю (2^32-1)
    1. Считаем вручную по ГОСТ:
    S1 + C2 = 4278124284 + 16843012 = 4294967296
    Так как полученное число 4294967296 = 2^32, то вычислять следует по формуле
    a@b=a+b-2^32+1, т.к. если a+b>=2^32
    4294967296 - 4294967296 + 1 = 1 (!) Так?
    2. Считаем в компе в 32-битных числах по формуле S1 = ((S1 + (C2 - 1)) % FFFFFFFF) + 1:
    S1 + C2 = ((4278124284 + (16843012 - 1)) % FFFFFFFF) + 1= (4294967295 % FFFFFFFF) + 1 = 0+1 = 1

    А вообще однозначно должно быть так, как написано в тексте ГОСТа, так?
    Берем калькулятор и считаем ВРУЧНУЮ те три примера в соответствии с текстом ГОСТа и понимаем суть. Так?
    Теперь берем комп (а можно снова калькулятор, но тут уже надо мыслить в 32-битных переменных) и считаем тоже самое, только по приведенной формуле:
    И удивляемся, что вычисления по этой формуле на компе приводят к такому же результату, как и вручную по ГОСТ. Так?
    И если и то, и другое совпадает между собой, то значит я ничего от себя не приврал...
     
  2. metcenger

    metcenger New Member

    Публикаций:
    0
    Регистрация:
    18 сен 2008
    Сообщения:
    87
    kapger
    я тоже подумал тут...
    ...
    S1= 0xFEFEFEFC; //temp

    S0= S0 + C1; //(mod 2^32)
    // S1 = S1 + (C2 - 1) + 1; //(mod (2^32)-1) + 1 (похоже, не правильно так)

    //новое
    S1= S1+C2; // получил S1 33 бита, т.е. с залезшей 1 в левый 33-й бит
    //бью 64 бита S1 на S10 S11 -S10 (младшая часть) и S11 (старшая)
    S10= S1;
    S11= S1 >> 32;
    //складываю S10 и S11
    S1 = S10 + S11; // тут S1 64 бита

    S= S1;
    S= (S << 32);
    S= S | S0; //Склеиваем S0 и S1 обратно в S

    S = ECB_Code (S);

    return S;
    }

    так работает. проверил. позже твой вариант опробую.
    Ещё раз, с этим битом переноса так и должно быть по стандарту? не намудрили мы тут?
     
  3. metcenger

    metcenger New Member

    Публикаций:
    0
    Регистрация:
    18 сен 2008
    Сообщения:
    87
    да, S1 у меня объявлена как 64 бита
     
  4. metcenger

    metcenger New Member

    Публикаций:
    0
    Регистрация:
    18 сен 2008
    Сообщения:
    87
    kapger
    да, твоя ф-я в одну строку дает такой же результат
    только перед FFFFFFFF надо 0x не забыть

    S1 = ((S1 + (C2 - 1)) % 0xFFFFFFFF) + 1; //(mod (2^32)-1) + 1

    и результат первой гаммы равен
    BB1B2F0FAEFEA452

    для
    S1= 0xFEFEFEFC;

    так же?
     
  5. kapger

    kapger New Member

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

    Как-то не так...

    Давай вернемся сейчас к сообщению №155 http://wasm.ru/forum/viewtopic.php?pid=323535#p323535
    и по шагам приводи свои значения...
     
  6. kapger

    kapger New Member

    Публикаций:
    0
    Регистрация:
    18 фев 2009
    Сообщения:
    135
    metcenger
    Так. Прошу прощения... Ступил немного...
    Не въехал сразу, что мы (не посчитав и не сверив гаммы для первого варианта синхропосылки) перешли сразу ко второй синхропосылке...
    Да, второго варианта синхропосылки первая гамма будет BB1B2F0FAEFEA452

    Только теперь давай для чистоты эксперимента, начнем все же с первого варианта синхропосылки и посчитаем две подряд идущие гаммы для нее, а потом перейдем ко второй и к третьей синхропосылке.
     
  7. kapger

    kapger New Member

    Публикаций:
    0
    Регистрация:
    18 фев 2009
    Сообщения:
    135
    metcenger
    И ради интереса при втором варианте синхропосылки убери скобки от (C2 - 1), которые я так настойчиво предлагаю и посмотри что будет. То есть эта строка:
    абсолютно не моя! Это наиболее правильная версия из всех исходных текстов, которые я смог накопать... Моё настойчивое предложение здесь только эти скобки у (C2 - 1)! А видел бы ты, какие шедевры попадались в разных исходных кодах вместо этой строки...
     
  8. metcenger

    metcenger New Member

    Публикаций:
    0
    Регистрация:
    18 сен 2008
    Сообщения:
    87
    kapger
    давай уже завтра проверимся. Сегодня я уже сплю... Но, похоже, все сошлось у нас )))

    Сложности с 64- х битной переменной затем, что мне совсем не понятна запись
    S1 = ((S1 + (C2 - 1)) % 0xFFFFFFFF) + 1

    Не мог бы ты разжевать её чуток? Т.е. то, как она проговаривается. Я плохо с сокращенными записями в Си. Однако мой вариант тоже работал ))) Но так- красивее, конечно.
     
  9. kapger

    kapger New Member

    Публикаций:
    0
    Регистрация:
    18 фев 2009
    Сообщения:
    135
    metcenger
    В этой записи "%" означает "mod", а 0xFFFFFFFF - это и есть 2^32-1
    И, насколько я понимаю, если вычисленное значение (S1+(C2-1))<0xFFFFFFFF, то результатом действия (S1+(C2-1))%0xFFFFFFFF так и останется (S1+(C2-1)). Если же (S1+(C2-1))=0xFFFFFFFF, то результатом действия (S1+(C2-1))%0xFFFFFFFF будет 0. А варианта когда (S1+(C2-1))>0xFFFFFFFF - не бывает, т.к. числа S1 и C2 - 32-битные и при вычислении (S1+(C2-1)) при наличии переполнения это выражение снова становится меньше, чем 0xFFFFFFFF ! Ну и единицу в конце прибавить не забыть...
     
  10. metcenger

    metcenger New Member

    Публикаций:
    0
    Регистрация:
    18 сен 2008
    Сообщения:
    87
    kapger
    Привет!
    сообщ 173. Если берем как S1 вторую и третью строчку из трех, то ответ всегда 1. А во второй строке он должен быть 2.
    Проверь, плз. Похоже, эта запись в одну строку не корректна. Здесь нужен мой вариант, но покультурней немного.
    Проверяй, отпишесься тогда.
     
  11. kapger

    kapger New Member

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

    Проверяем пример из сообщения №173 http://www.wasm.ru/forum/viewtopic.php?pid=323602#p323602
    Пример 1:
    S1=4278124283; C2=16843012
    сложение S1 + C2 должно быть по модулю (2^32-1)
    1. Считаем вручную по ГОСТ:
    S1 + C2 = 4278124283 + 16843012 = 4294967295
    Так как полученное число 4294967295 < 2^32, то вычислять следует по формуле
    a@b=a+b, т.к. если a+b<2^32
    S1 @ C2 = 4294967295 = 0xFFFFFFFF
    2. Считаем в компе в 32-битных числах по формуле S1 = ((S1 + (C2 - 1)) % 0xFFFFFFFF) + 1:
    S1 + C2 = ((4278124283 + (16843012 - 1)) % 0xFFFFFFFF) + 1= (4294967294 % 0xFFFFFFFF) + 1 = 4294967294+1 = 4294967295 = 0xFFFFFFFF

    Пример 2:
    S1=4278124284; C2=16843012
    сложение S1 + C2 должно быть по модулю (2^32-1)
    1. Считаем вручную по ГОСТ:
    S1 + C2 = 4278124284 + 16843012 = 4294967296
    Так как полученное число 4294967296 = 2^32, то вычислять следует по формуле
    a@b=a+b-2^32+1, т.к. если a+b>=2^32
    S1 @ C2 = 4294967296 - 4294967296 + 1 = 1
    2. Считаем в компе в 32-битных числах по формуле S1 = ((S1 + (C2 - 1)) % 0xFFFFFFFF) + 1:
    S1 + C2 = ((4278124284 + (16843012 - 1)) % 0xFFFFFFFF) + 1= (4294967295 % 0xFFFFFFFF) + 1 = 0+1 = 1

    Пример 3:
    S1=4278124285; C2=16843012
    сложение S1 + C2 должно быть по модулю (2^32-1)
    1. Считаем вручную по ГОСТ:
    S1 + C2 = 4278124285 + 16843012 = 4294967297
    Так как полученное число 4294967297 > 2^32, то вычислять следует по формуле
    a@b=a+b-2^32+1, т.к. если a+b>=2^32
    S1 @ C2 = 4294967297 - 4294967296 + 1 = 2
    2a. Считаем в компе в 32-битных числах по формуле S1 = ((S1 + (C2 - 1)) % 0xFFFFFFFF) + 1:
    S1 + C2 = ((4278124285 + (16843012 - 1)) % 0xFFFFFFFF) + 1= (0 % 0xFFFFFFFF) + 1 = 0+1 = 1 (НЕВЕРНО!)
    Вот именно здесь и обнаружилась ЗАСАДА! Кстати, эта засада будет и дальше во всех вариантах, где есть переполнение...
    Проверим подробнее:
    Вычисления со скобками у (C2 - 1):
    4278124285 + (16843012 - 1) = 4278124285 + 16843011 = 0x100000000. Отбрасываем переполнение и остается 0. Делим по модулю %0xFFFFFFFF, получаем 0. Прибавляем 1, получаем 1. А должно быть 2!
    Вычисления без скобок у C2 - 1:
    4278124285 + 16843012 = 0x100000001. Отбрасываем переполнение и остается 1. Вычитаем 1, остается 0. Делим по модулю %0xFFFFFFFF, получаем 0. Прибавляем 1, получаем 1. А должно быть 2!
    То есть наличие или отсутствие скобок не влияет на результат - он в обоих вариантах (ПРИ НАЛИЧИИ ПЕРЕПОЛНЕНИЯ при операциях с 32-битными числами) неверный... Наличие или отсутствие скобок ОДНОЗНАЧНО влияет на пример №2, так как там в случае с 32-битным исчислением получим вычитание 1 из 0.
    Идем дальше...
    Если мы считаем в 32-битных числах, то в приведенном варианте данная конструкция не работает. А если действительно считать данную конструкцию в 64-битных числах?
    Проверяем:
    2b. Считаем в компе в 64-битных числах по формуле S1 = ((S1 + (C2 - 1)) % 0xFFFFFFFF) + 1:
    S1 + C2 = ((4278124285 + (16843012 - 1)) % 0xFFFFFFFF) + 1= (0x100000000 % 0xFFFFFFFF) + 1 = 1+1 = 2
    Вот теперь ВЕРНО!

    И какое же резюме?
    Считать эту конструкцию в 64-битном виде? Я прикинул и посчитал, что все эти три примера и последующие несколько аналогичных дают правильное решение при расчете в 64-битном виде...
    Примечание: наличие скобок у (C2 - 1) при расчете в 64-битном виде не требуется.
     
  12. metcenger

    metcenger New Member

    Публикаций:
    0
    Регистрация:
    18 сен 2008
    Сообщения:
    87
    kapger
    конечно же я имел ввиду 3-ю строчку. В голове держал две последние, вот и сказал про вторую...
    Ну так что с формулой- то? Как она теперь должна выглядеть? Какие переменные объявлять 64- битными? В моем варианте нужно было только S1 объявить как 64- битное.
     
  13. metcenger

    metcenger New Member

    Публикаций:
    0
    Регистрация:
    18 сен 2008
    Сообщения:
    87
    kapger
    конечно же я имел ввиду 3-ю строчку. В голове держал две последние, вот и сказал про вторую...
    Ну так что с формулой- то? Как она теперь должна выглядеть? Какие переменные объявлять 64- битными? В моем варианте нужно было только S1 объявить как 64- битное.
     
  14. kapger

    kapger New Member

    Публикаций:
    0
    Регистрация:
    18 фев 2009
    Сообщения:
    135
    metcenger
    Получается, что S1 объявить как 64-битное и выглядеть будет так:
    Если вдруг я где ошибаюсь, то, надеюсь, что меня присутствующие поправят...
     
  15. metcenger

    metcenger New Member

    Публикаций:
    0
    Регистрация:
    18 сен 2008
    Сообщения:
    87
    kapger
    проверил. формула та же твоя.
    S1 объявил как 64-битное, вместо 32. Работает правильно теперь!

    Проверяем гамму?
    Синхропосылка какая?
     
  16. kapger

    kapger New Member

    Публикаций:
    0
    Регистрация:
    18 фев 2009
    Сообщения:
    135
    metcenger
    Либо можно использовать по аналогии с ассемблерным кодом Винокурова (см. сообщение №169 http://www.wasm.ru/forum/viewtopic.php?pid=323579#p323579):
    в случае с реализацией 32-битных чисел следующее выражение:
    Этот вариант предложил мне уважаемый OLS в сообщении №35 http://www.wasm.ru/forum/viewtopic.php?pid=302050#p302050
    И именно подобным образом у меня и считается, только на самом деле еще корявее, т.к. у меня система счисления 16-разрядная...
     
  17. metcenger

    metcenger New Member

    Публикаций:
    0
    Регистрация:
    18 сен 2008
    Сообщения:
    87
    kapger
    да, так со скобками что? оставить их можно? или как хочу?
     
  18. kapger

    kapger New Member

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

    metcenger New Member

    Публикаций:
    0
    Регистрация:
    18 сен 2008
    Сообщения:
    87
    kapger
    ты как настоящий программер не должен париться какая у тебя система счисления. У меня она 8- ми разрядная, например. Если под МК AVR брать. Это задача компилятора что и как. Просто пиши код. И давай размер переменным
     
  20. kapger

    kapger New Member

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

    Таблица замен берется из сообщения №79 данной темы. Ключ шифрования используем один из тех, что описаны в этом же сообщении №79, а именно:
    K1=0x733D2C20 65686573 74746769 79676120 626E7373 20657369 326C6568 33206D54
    (порядок расположения элементов в ключе: k7, k6, ... ,k0)
    Синхропосылка в открытом виде 104BD8E832B1A503.

    Шаги по выработке гаммы №1:
    1. Шифруем синхропосылку по циклу 32-З с указанными ключевыми данными, результат равен FEFEFEFB4DA15E7C.
    2. Входное значение для генерации гаммы FEFEFEFB4DA15E7C
    3. Выходное значение полученной гаммы FFFFFFFF4EA25F7D
    4. Зашифрованное значение полученной гаммы, которое и используется для наложения гаммы на открытые данные - гамма равна 9D9BA7C74D32B3A9

    Шаги по выработке гаммы №2:
    1. Входное значение для генерации гаммы FFFFFFFF4EA25F7D
    2. Выходное значение полученной гаммы 010101044FA3607E
    3. Зашифрованное значение полученной гаммы, которое и используется для наложения гаммы на открытые данные - гамма равна D4449DF19F77FF81

    Так?