Рабочая эталонная реализация TwoFish?
Страница википедии на TwoFish указывает на эту эталонную реализацию в C (и коде), что хорошо, но в ней нет main
и мои первые несколько проходов при реализации одного не правильно обрабатывали ни один из "известных векторных" тестовых случаев, которые я пытался. Я подозреваю, что смотрю на проблему неправильного использования API, но я не знаю, с чего начать поиск ошибки. Вместо того, чтобы бить меня по голове, лучше начать с кодовой базы:
- Бежит из коробки
- Есть тесты
- Самостоятельно
- Написано для наглядности
У меня также есть сильное предпочтение C или C, как C++ код.
Примечание. На данный момент меня больше интересует читаемость кода, чем что-либо еще. Небольшой, простой код, который может шифровать и дешифровать отдельный блок, и основная функция, которая жестко кодирует вызов или три, будет идеальным вариантом. Почти все, что за этим (как и любой пользовательский интерфейс) будет просто шумом для моего варианта использования.
Кроме того, все, что имеет лицензию, более ограничивающую, чем Boost, будет полезно для меня только как источник знаний о хороших значениях и состояниях для сравнения.
4 ответа
В конце концов я нашел эту реализацию Python, основанную на имплементации C, которую я перечислил выше. Основной причиной моих проблем оказалось то, что слова ключа были в неправильном порядке.
Я взял реализацию Нилса Фергюсона, одного из дизайнеров Twofish, и обернул ее (очень легко, делая очень мало изменений) в C++, и она хорошо работает. Я должен подчеркнуть, что я почти не работал здесь, и не претендую на то, чтобы понять, как работает Twofish (и это после того, как я прочел об этом - но мне слишком трудно следовать).
Конструктор выполняет всестороннее тестирование и прерывает работу, если тесты не пройдены, поэтому, когда у вас есть полностью сконструированный объект, вы знаете, что он будет работать.
Я поместил источники здесь: http://www.cartotype.com/assets/downloads/twofish/.
В файлах есть различные настраиваемые элементы; одну, которую вы можете изменить, - это функция прерывания Twofish_fatal, которая в моей версии пытается записать адрес 0 для принудительного выхода, но это не работает на некоторых платформах.
Как и код, упомянутый выше, все это кодирует отдельные 16-байтовые блоки (ECB = режим электронной кодовой книги). Но очень легко реализовать лучший режим поверх него, например, цепочку шифровавшего слова, в которой каждый блок простого текста перед шифрованием XORed с предыдущим блоком зашифрованного текста (используйте случайный "вектор инициализации" из 16 байтов для первый блок и передать его вместе с зашифрованными данными).
Другая реализация может быть найдена в исходном коде программы базы данных паролей Брюса Шнайера с открытым исходным кодом, PasswordSafe: соответствующие источники здесь: http://passwordsafe.git.sourceforge.net/git/gitweb.cgi?p=passwordsafe/pwsafe.git;a=tree;f=pwsafe/pwsafe/src/core;hb=HEAD. Я не пробовал, поэтому я не могу комментировать, как легко интегрировать.
Если бы вы потратили всего минуту, чтобы прочитать эталонную реализацию, предоставляемую libObfuscate, вы нашли бы наглядный пример использования TwoFish.
// Encrypt : outBuf [16] = Twofish ECB ( inBuf [16] )
TWOFISH_STATIC_DATA twofish;
BYTE passw [32];
BYTE inBuf [16] , outBuf [16];
memset( &twofish , 0 , sizeof( TWOFISH_STATIC_DATA ) );
Twofish_set_key( &twofish.key , ( DWORD * ) passw , 256 );
Twofish_encrypt( &twofish.key , ( DWORD * ) inBuf , ( DWORD * ) outBuf );
Никакой серьезной СПРАВОЧНОЙ ОСУЩЕСТВЛЕНИЯ не было бы иначе, как реализация ЕЦБ с одним блоком.
Если вы хотите зашифровать больше данных, вам нужно выбрать режим цепочки блоков шифрования (CBC, ecc...) и применить его поверх ECB.
cryptcat
пакет на Ubuntu и Debian предоставляет nc(1)
-подобная функциональность со встроенным twofish.
Двенадцатая поддержка предоставляется в twofish2.cc
а также twofish2.h
в исходном пакете. farm9crypt.cc
обеспечивает слой между C-стилем read()
а также write()
функциональность и двоякий алгоритм - это стиль, который я бы назвал C-подобным C++.