Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 02.07.2015, 07:22   #1
Sushev
Пользователь
 
Регистрация: 14.12.2014
Сообщений: 13
Печаль Проблема с кодом, когда -On, n >= 1 (GCC)

Доброго времени суток.
Пишу я тут класс Blowfish. Если я его компилирую с ключом -O0, то результат шифрования блока получается один, если с ключом -O1 или -O2, то результат шифрования получается другой. При этом расшифровываются блоки корректно, а каждый запуск программы выдает один и тот же результат. Но вот если теперь попробовать ключ -O3, то при каждом запуске программы результат шифрования одного и того же блока разный, но при этом расшифровка (в этом же процессе) происходит корректно! (Это как так, вообще? ) Я уже шатал-шатал реализацию всех методов по разному, пробовал запрещать оптимизацию каждого из методов, надеясь найти тот, реализация которого косячная, но результат все тот же. Разбивал сложные выражения на мелкие, выносил куски кода в отдельные методы, - не меняется совершенно ничего. Пробовал другую версию (5.1.0 вместо 4.7.1) GCC, при этом результат шифрования немного изменялся, но общая картина та же. Воз и ныне там. Кто-нибудь может подсказать что-нибудь по этому поводу?

На всякий случай нарисую здесь мой код проверки класса:

Код:
#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
#include "blowfish/blowfish.h"

using namespace std;

int main()
{
    vector <byte>* key = new vector <byte> (32, 0x00);
    word64 block = 0x8000000000000001;
    
    Blowfish* secure = new Blowfish(key);
    cout << hex << block << endl;
    secure->EncryptBlock(&block);
    cout << hex << block << endl;
    secure->DecryptBlock(&block);
    cout << hex << block << endl;
    cout << secure->GetCipherName() << endl;
    delete secure;
    
    delete key;
    
    return 0;
}
А сам класс здесь: blowfish.zip
Sushev вне форума Ответить с цитированием
Старый 02.07.2015, 09:07   #2
Shad0wF1rst
Форумчанин
 
Регистрация: 11.01.2013
Сообщений: 149
По умолчанию

Цитата:
Сообщение от Sushev Посмотреть сообщение
Доброго времени суток.
Пишу я тут класс Blowfish. Если я его компилирую с ключом -O0, то результат шифрования блока получается один, если с ключом -O1 или -O2, то результат шифрования получается другой. При этом расшифровываются блоки корректно, а каждый запуск программы выдает один и тот же результат. Но вот если теперь попробовать ключ -O3, то при каждом запуске программы результат шифрования одного и того же блока разный, но при этом расшифровка (в этом же процессе) происходит корректно! (Это как так, вообще? ) Я уже шатал-шатал реализацию всех методов по разному, пробовал запрещать оптимизацию каждого из методов, надеясь найти тот, реализация которого косячная, но результат все тот же. Разбивал сложные выражения на мелкие, выносил куски кода в отдельные методы, - не меняется совершенно ничего. Пробовал другую версию (5.1.0 вместо 4.7.1) GCC, при этом результат шифрования немного изменялся, но общая картина та же. Воз и ныне там. Кто-нибудь может подсказать что-нибудь по этому поводу?

На всякий случай нарисую здесь мой код проверки класса:

Код:
#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
#include "blowfish/blowfish.h"

using namespace std;

int main()
{
    vector <byte>* key = new vector <byte> (32, 0x00);
    word64 block = 0x8000000000000001;
    
    Blowfish* secure = new Blowfish(key);
    cout << hex << block << endl;
    secure->EncryptBlock(&block);
    cout << hex << block << endl;
    secure->DecryptBlock(&block);
    cout << hex << block << endl;
    cout << secure->GetCipherName() << endl;
    delete secure;
    
    delete key;
    
    return 0;
}

-On это не шифрование а оптимизация кода компилятором. При -О3 компилировать не рекомендуется, правда если скомпилировалось и корректно работает то там оптимизация очень хорошая, но это редкость когда так получается.
Может это и чушь, но это моя чушь и я ее никому не отдам.
Shad0wF1rst вне форума Ответить с цитированием
Старый 02.07.2015, 09:37   #3
Sushev
Пользователь
 
Регистрация: 14.12.2014
Сообщений: 13
По умолчанию

Цитата:
Сообщение от Shad0wF1rst Посмотреть сообщение
-On это не шифрование а оптимизация кода компилятором.
Простите, наверное я не ясно выразился. На самом деле я не называл оптимизацию шифрованием. Все, что я говорю о шифровании блоков, относится к алгоритму Blowfish. Алгоритм реализован в представленном классе, а блоки размером 64 бита с помощью этого класса зашифровывает и расшифровывает функция main() программы. Так вот саму программу (все ее *.cpp файлы) я компилирую с параметром (я случайно назвал его ключом) -On.
Sushev вне форума Ответить с цитированием
Старый 02.07.2015, 09:43   #4
Sushev
Пользователь
 
Регистрация: 14.12.2014
Сообщений: 13
По умолчанию

Вообще, подозрения, конечно изначально падали на SetCipherKey(), уж очень она криворукая. Взял сейчас реализацию этой функции (и немного переделал) у Paul Kocher:

Код:
void Blowfish::SetCipherKey(const std::vector <byte>* key)
{
    unsigned int i;
    unsigned int j;
    unsigned int k;
    word32 data;
    word32 datal;
    word32 datar;

    for(i = 0; i < 4; i++)
    {
        for(j = 0; j < 256; j++)
            Sbox[j][i] = fixedS[j][i];
    }

    j = 0;
    for(i = 0; i < 16 + 2; ++i)
    {
        data = 0x00000000;
        for(k = 0; k < 4; ++k)
        {
            data = (data << 8)|cipherKey->at(j);
            j = j + 1;
            if(j >= 56)
                j = 0;
        }
        P[i] = fixedP[i] ^ data;
    }

    datal = 0x00000000;
    datar = 0x00000000;

    for(i = 0; i < 16 + 2; i += 2)
    {
        EncryptBlock(&datal, &datar);
        P[i] = datal;
        P[i + 1] = datar;
    }

    for(i = 0; i < 4; ++i)
    {
        for(j = 0; j < 256; j += 2)
        {
            EncryptBlock(&datal, &datar);
            Sbox[j][i] = datal;
            Sbox[j + 1][i] = datar;
        }
    }
}
Проблема, кажется, исчезла. При любом параметре -On результат теперь всегда одинаковый. При этом больше никаких изменений в классе не делал. Но мне все-таки интересно, чем моя реализация все портила, ведь она от представленной выше не сильно-то отличается...

Последний раз редактировалось Sushev; 02.07.2015 в 10:21.
Sushev вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
GCC, проблема с прогой shamaz Общие вопросы C/C++ 7 12.09.2013 21:19
проблема с кодом net_probelam Общие вопросы C/C++ 1 19.10.2011 02:06
Проблема с компиляцией матфункций в gcc Svent Qt и кроссплатформенное программирование С/С++ 4 09.07.2010 12:44
Проблема с функцией pow в С, использую GCC maryan.vetrov Помощь студентам 0 07.06.2010 04:12
проблема с gcc d9m0n Qt и кроссплатформенное программирование С/С++ 6 04.09.2009 02:30