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-битных переменных) и считаем тоже самое, только по приведенной формуле: И удивляемся, что вычисления по этой формуле на компе приводят к такому же результату, как и вручную по ГОСТ. Так? И если и то, и другое совпадает между собой, то значит я ничего от себя не приврал...
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; } так работает. проверил. позже твой вариант опробую. Ещё раз, с этим битом переноса так и должно быть по стандарту? не намудрили мы тут?
kapger да, твоя ф-я в одну строку дает такой же результат только перед FFFFFFFF надо 0x не забыть S1 = ((S1 + (C2 - 1)) % 0xFFFFFFFF) + 1; //(mod (2^32)-1) + 1 и результат первой гаммы равен BB1B2F0FAEFEA452 для S1= 0xFEFEFEFC; так же?
metcenger А зачем такие сложности? Как-то не так... Давай вернемся сейчас к сообщению №155 http://wasm.ru/forum/viewtopic.php?pid=323535#p323535 и по шагам приводи свои значения...
metcenger Так. Прошу прощения... Ступил немного... Не въехал сразу, что мы (не посчитав и не сверив гаммы для первого варианта синхропосылки) перешли сразу ко второй синхропосылке... Да, второго варианта синхропосылки первая гамма будет BB1B2F0FAEFEA452 Только теперь давай для чистоты эксперимента, начнем все же с первого варианта синхропосылки и посчитаем две подряд идущие гаммы для нее, а потом перейдем ко второй и к третьей синхропосылке.
metcenger И ради интереса при втором варианте синхропосылки убери скобки от (C2 - 1), которые я так настойчиво предлагаю и посмотри что будет. То есть эта строка: абсолютно не моя! Это наиболее правильная версия из всех исходных текстов, которые я смог накопать... Моё настойчивое предложение здесь только эти скобки у (C2 - 1)! А видел бы ты, какие шедевры попадались в разных исходных кодах вместо этой строки...
kapger давай уже завтра проверимся. Сегодня я уже сплю... Но, похоже, все сошлось у нас ))) Сложности с 64- х битной переменной затем, что мне совсем не понятна запись S1 = ((S1 + (C2 - 1)) % 0xFFFFFFFF) + 1 Не мог бы ты разжевать её чуток? Т.е. то, как она проговаривается. Я плохо с сокращенными записями в Си. Однако мой вариант тоже работал ))) Но так- красивее, конечно.
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 ! Ну и единицу в конце прибавить не забыть...
kapger Привет! сообщ 173. Если берем как S1 вторую и третью строчку из трех, то ответ всегда 1. А во второй строке он должен быть 2. Проверь, плз. Похоже, эта запись в одну строку не корректна. Здесь нужен мой вариант, но покультурней немного. Проверяй, отпишесься тогда.
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-битном виде не требуется.
kapger конечно же я имел ввиду 3-ю строчку. В голове держал две последние, вот и сказал про вторую... Ну так что с формулой- то? Как она теперь должна выглядеть? Какие переменные объявлять 64- битными? В моем варианте нужно было только S1 объявить как 64- битное.
kapger конечно же я имел ввиду 3-ю строчку. В голове держал две последние, вот и сказал про вторую... Ну так что с формулой- то? Как она теперь должна выглядеть? Какие переменные объявлять 64- битными? В моем варианте нужно было только S1 объявить как 64- битное.
metcenger Получается, что S1 объявить как 64-битное и выглядеть будет так: Если вдруг я где ошибаюсь, то, надеюсь, что меня присутствующие поправят...
kapger проверил. формула та же твоя. S1 объявил как 64-битное, вместо 32. Работает правильно теперь! Проверяем гамму? Синхропосылка какая?
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-разрядная...
kapger ты как настоящий программер не должен париться какая у тебя система счисления. У меня она 8- ми разрядная, например. Если под МК AVR брать. Это задача компилятора что и как. Просто пиши код. И давай размер переменным
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 Так?