Обзор
При помощи JNI (Java Native Interface), небольшого кода на C (спасибо, ugha!), небольшого количества ручной работы и кусочка жвачки мы заставили некоторые криптографические операции работать немного быстрее.
Ускорения удалось достичь за счёт использования библиотеки GNU MP Bignum (libgmp). Мы используем одну функцию из libgmp - mpz_powm() как замену для функции modPow() из библиотеки Java Math BigInteger. А так как значительная часть вычислений использует modPow() - это позволило неплохо ускориться.
Стандартная поставка I2P содержит около 20 версий библиотеки для разных платформ, каждая около 50КБ, в файле jbigi.jar. Инициализация библиотеки JBigI, включая идентификацию CPU, выбор и извлечение подходящего загрузочного модуля, управляется классом NativeBigInteger. Если модуль недоступен для текущей платформы, то используется стандартная функция BigInteger modPow() из библиотеки Java Math.
Пересборка и Тестирование JBigI
Ниже приведены инструкции для сборки новой библиотеки jbigi для вашей платформы и тестирования её производительностиТребования
Это работает на Linux, а с небольшими изменениями в build.sh, вероятно, и на других платформах. Сообщается, что работает в том числе и на FreeBSD. На Kaffee ускорение незначительно, так как там уже используется нативный BigInteger. Blackdown похоже вызывает странные ошибки. Так как вам потребуется компилировать, необходимо иметь JDK; с JRE не выйдет.
Необходимый код доступен в бд monotone и последнем архиве с исходным кодом.
Требуется установка библиотеки GNU MP Bignum (libgmp), если она не включена в вашу ОС/дистрибутив или не установлена ранее, то её можно загрузить с http://gmplib.org/#DOWNLOAD. Даже если вы установили её ранее, может быть стоит скомпилировать GMP самостоятельно, чтобы можно было использовать специфичные инструкции вашего процессора. Также можно использовать последнюю версию GMP вместо версии GMP 5.0.2, но мы ещё не проводили тестирование.
Пошаговые инструкции
- Посмотрите на вашу среду выполнения на странице logs.jsp. Там должно быть одно из двух сообщений о статусе JBigI, любое. Локально оптимизированная нативная библиотека BigInteger загружена по указанному пути или Нативная библиотека jbigi не загружена — используется обычная java. Если нативная библиотека BigInteger НЕ была загружена, то вам определенно нужно скомпилировать свою. Некоторые платформы, такие как OS X, OpenSolaris и 64-битные системы, могут потребовать компиляцию своей собственной библиотеки. Если библиотека BigInteger была загружена, проделайте хотя бы следующий шаг, чтобы определить производительность.
- Зайдите на http://localhost:7657/stats.jsp, чтобы увидеть среднее время существования значений для
crypto.elGamal.decrypt
иcrypto.elGamal.encrypt
. Значения указаны в миллисекундах. Скопируйте значения куда-нибудь так, чтобы вы могли сравнить с ними позже. Среднее время для шифрования в сети — около 20мс. Если время шифрования менее 50мс для достаточно нового процессора или менее 100мс для старого, нативная библиотека BigInteger загружена, то у вас, вероятно, всё в порядке. - Скачайте последний выпущенный исходный код I2P на странице загрузок или из бд monotone mtn.i2p2.de
- В директории с исходниками перейдите в :
core/c/jbigi
- Прочитайте файл README.
Если у вас есть файл /usr/lib/libgmp.so, то скачивать GMP не требуется.
Используйте параметр 'dynamic' для build.sh.
В противном случае вам необходимо скачать GMP версии 5.0.2 с http://gmplib.org/#DOWNLOAD, сохранив как gmp-5.0.2.tar.bz2.
Если вы решите использовать более новую версию, то измените параметр VER= в файле
core/c/jbigi/build.sh
. - Просмотрите
build.sh
, если переменная окруженияJAVA_HOME
установлена и вы используете Linux, то всё это может успешно работать. Иначе измените настройки. Не забудьте, что требуется наличие установленного Java SDK. - Выполните
build.sh
(если вы скачивали GMP) илиbuild.sh dynamic
(если у вас есть /usr/lib/libgmp.so).
Возможно, скрипт выдаст ошибки об отсутствии файлов jni.h и jni_md.h. Или скопируйте эти файлы из установки java в директорию core/c/jbigi/jbigi/include/, или исправьте $JAVA_HOME.
Вы можете запуститьbuild.sh
из директорииcore/c/
, в результате будет выполнена сборка всех доступных библиотек jbigi в jbigi.jar. В текущей директории должен быть создан файлlibjbigi.so
. Если этого не произойдет и/или будут сообщения об ошибках, пожалуйста, расскажите нам об этом. - Для установки библиотеки и запуска теста скорости следуйте инструкциям в core/c/README.
Прочитайте последние строки результата теста для дополнительной информации, они будут похожи на:
native run time: 5842ms ( 57ms each) java run time: 41072ms (406ms each) native = 14.223802103622907% of pure java time
Если нативная библиотека действительно в 5-7 раз быстрее (или более), то всё хорошо. Иначе сообщите нам. - Скопируйте
libjbigi.so
в директорию с i2p. - Перезапустите приложения I2P.
- На странице http://localhost:7657/stats.jsp
crypto.elGamal.decrypt
иcrypto.elGamal.encrypt
должны быть гораздо быстрее.