Описание «стандарта docx» — это совершенно монструозный талмуд с массой неточностей, противоречий и неиспользуемых/неподдерживаемых возможностей. M$ буквально применили тактику взятия измором, когда пропихивали свое творение в ранг стандарта.
Итоговая ситуация де-факто жуткая — у M$ огромное кол-во ошибок и «косяков», которые для совместимости поддерживаются и обрабатываются огромной кучей костылей. Т.е. если бы устроить тест на корректную поддержку стандартов группы OpenDocument, то LibreOffice не оставит продуктам M$ никакого шанса.
На всякий — на Эльбрусе большинство уязвимостей не работают, в частности потому что там тегированные указатели и разные стеки для данных и адресов возврата. Поэтому, "при прочих равных", Эльбрус на 2-3 порядка более защищенная/безопасная архитектура в сравнении с "обычными" (и тут тоже есть определенная схожесть с AS/400).
Смысл есть, но это очень сложно. Кроме этого, крайне маловероятно что МЦСТ когда-нибудь откроет исходники компилятора (точнее говоря оптимизатора), так как это know how (и одна из причин смерти IA64, aka Itanium). Поэтому задача пожалуй решается только через С или использование JIT из Java.
На VLIW от компилятора зависит гораздо больше чем для "обычных" процессоров. Грубо говоря, перекомпиляция софта более новым компилятором может давать заметный (даже кратный) рост производительность. В этом плане есть некоторое сходство с AS/400.
Нижний уровень (backend) компилятора для VLIW кардинально отличается от "обычных" RISC/CISC процессоров. Это отдельная большая сложная задача, для которой примерно никакие наработки от GCC/CLANG не подойдут (можно взять что-то для построения SSA, но смысла нет).
Умножение 64x64 => 128 используется в массе хешей, включая MUM, t1ha и xxh3.
Реализовать такое умножение можно через переносимые операции с uint64_t.
Но конечно это будет немного медленнее, чем использование соответствующих intrinsic-ков или __uint128_t от нормального компилятора. Кстати, 128-битные целые поддерживаются clang-ом (и всеми приличными компиляторами) для 64-битных платформ.
А вот у java тут действительно болит, точнее со всеми языками на основе java-VM. Ибо от «большого ума» убрали uint64_t, оставив только int64_t. Поэтому умножение 64x64=>128 или 128-битные умножения стоят еще дороже, ибо дополнительно приходиться проверять и переворачивать знаки. Тем не менее для java-кофеварок это приемлемо.
Персонализированный фастфуд, да они просто больны.
Но это безумство оправдывает цель — максимально выпотрошить ваш бумажник (как верно подметил Aquahawk в первом комментарии).
На так давно помогал с прототипом защиты от подобного анализа для "мягких" процессоров.
Идейно защита достаточно проста — вставляется несколько скремблеров, в частности в шину данных и в декодер инструкций, конечно с зависимостью от адреса и ключа прошивки. Технически же сложности из-за необходимости экономить cells и latency, ну и возня с toolchain. Но получается очень неплохо, можно даже специально оставлять статистические bias/skew, которые при попытке их использовать уводят в совершенно неверном направлении ;)
Попросили сравнить скорость переносимых и SIMD-версий (ну и самому было интересно).
С использованием всех возможностей i7-6700K (GCC 7.3.0 с опцией -march=native) в перерасчете тактов в GiB/s для частоты процессора 3 ГГц.
На всякий случай поясню — из t1ha-семейства тут только t1ha0(), так именно она изменяет переносимости ради скорости.
Теперь переносимые реализации хеш-функций, последние три строки — это 32-битные хеши для сопоставления.
На всякий случай поясню — здесь вместо t1ha0() результаты t1ha2_atonce(), так она переносима (и будет вызвана изнутри t1ha0 на CPU без AVX и т.п.):
Чтобы устранить подобные недостатки (в том числе, еще пример) следует использовать Merkle–Damgård хотя-бы в варианте "fast wide pipe". С точки зрения практической реализации это означает удвоение ширины внутреннего состояния c перекрестным "опылением" его половин на каждом цикле. Также желательно обеспечивать две точки инъекции данных, чтобы не терять энтропию.
Внутри t1ha именно так и сделано (wide pipe с перекрестным перемешиванием и двумя точками инъекции). Тем не менее, свойства t1ha2 не идеальны, так как операции перемешивания сильно упрощены ради скорости. Можно сказать, что именно эти упрощения не позволяют конкурировать с SipHash.
Поэтому, в t1ha3 основное изменением будет именно в этом месте. Кроме этого, будут заменены внутренности t1ha0 (это позволяет задекларированный контракт интерфейса), в том числе вариантов с AES-NI.
Не-переносимые реализации (SSE, AVX, AVX2) не совсем корректно сравнивать с переносимыми — получается волшебно большая разница. Соответственно, логично бы добавить в графики результаты t1ha0_aes.
Тем не менее, приятно видеть что t1ha2 уверенно идет на втором месте (за вычетом имеющих проблемы FNV и функций без seed).
В целом здорово что Yann Collet продолжил соревнование, так что постараюсь не отставать с t1ha3 :)
На всякий случай, всё-таки поясню почему вы не правы.
Если компилятору разрешить объединять константы (см ниже), то он вправе совместить все байты всех констант, с учетом требований к выравниванию их типов. Более того, аналогичный функционал может быть параллельно или независимо реализован в линкере.
В рассматриваемом случае такое объединение точно произойдет, если где-то в пределах видимости компилятора (или "умного" линкера) есть константа с совпадающим названием локали.
В свою очередь, если m_resolvedName имеет тип const wchat_t* и соответствующее значение указателя было сохранено (не было создано исходной константы), то и результат сравнения будет true.
Всё вышеописанное повсеместно в коде проектов собираемых для "мелких" процессоров (PIC, ATmega и т.п.).
-fmerge-constants
Attempt to merge identical constants (string constants and floating-point constants) across compilation units.
This option is the default for optimized compilation if the assembler and linker support it. Use -fno-merge-constants to inhibit this behavior.
Enabled at levels -O, -O2, -O3, -Os.
-fmerge-all-constants
Attempt to merge identical constants and identical variables.
This option implies -fmerge-constants. In addition to -fmerge-constants this considers e.g. even constant initialized arrays or initialized constant variables with integral or floating-point types. Languages like C or C++ require each variable, including multiple instances of the same variable in recursive calls, to have distinct locations, so using this option results in non-conforming behavior.
For now "t1ha" is positioned as "not suitable for cryptography" at least until the independent cryptanalysis will completed and published. However, by some unpublished estimations of 128-bit version t1ha2 no less secure than SipHash.
In any case, I am very interested in independent third-party evaluation of t1ha2 properties.
To do this, the compression cycle and the final mixing (part-1, part-2) must be thoroughly analyzed.
Однако, в «военное время» компилятор (или даже линкер) может объединять константы (в том числе константные строки), и вот тогда сравнение будет работать правильно. Причем подобное не редкость в embedded-проектах.
Вот поинтересовался бы — последние версии Hyperflex уже пропатчили против «curl-уязвимости» или еще не успели?
Кстати, RLP — это MessagePack сломанный в духе «назло бабушке уши отморожу».
А первый blockchain — это git, буквально.
Итоговая ситуация де-факто жуткая — у M$ огромное кол-во ошибок и «косяков», которые для совместимости поддерживаются и обрабатываются огромной кучей костылей. Т.е. если бы устроить тест на корректную поддержку стандартов группы OpenDocument, то LibreOffice не оставит продуктам M$ никакого шанса.
На всякий — на Эльбрусе большинство уязвимостей не работают, в частности потому что там тегированные указатели и разные стеки для данных и адресов возврата. Поэтому, "при прочих равных", Эльбрус на 2-3 порядка более защищенная/безопасная архитектура в сравнении с "обычными" (и тут тоже есть определенная схожесть с AS/400).
Смысл есть, но это очень сложно. Кроме этого, крайне маловероятно что МЦСТ когда-нибудь откроет исходники компилятора (точнее говоря оптимизатора), так как это know how (и одна из причин смерти IA64, aka Itanium). Поэтому задача пожалуй решается только через С или использование JIT из Java.
Так и осталось.
На всякий, для остальных чуток поясню:
Реализовать такое умножение можно через переносимые операции с uint64_t.
Но конечно это будет немного медленнее, чем использование соответствующих intrinsic-ков или __uint128_t от нормального компилятора. Кстати, 128-битные целые поддерживаются clang-ом (и всеми приличными компиляторами) для 64-битных платформ.
А вот у java тут действительно болит, точнее со всеми языками на основе java-VM. Ибо от «большого ума» убрали uint64_t, оставив только int64_t. Поэтому умножение 64x64=>128 или 128-битные умножения стоят еще дороже, ибо дополнительно приходиться проверять и переворачивать знаки. Тем не менее для java-кофеварок это приемлемо.
Теперь точно придется постараться c t1ha3 )
Но это безумство оправдывает цель — максимально выпотрошить ваш бумажник (как верно подметил Aquahawk в первом комментарии).
На так давно помогал с прототипом защиты от подобного анализа для "мягких" процессоров.
Идейно защита достаточно проста — вставляется несколько скремблеров, в частности в шину данных и в декодер инструкций, конечно с зависимостью от адреса и ключа прошивки. Технически же сложности из-за необходимости экономить cells и latency, ну и возня с toolchain. Но получается очень неплохо, можно даже специально оставлять статистические bias/skew, которые при попытке их использовать уводят в совершенно неверном направлении ;)
Попросили сравнить скорость переносимых и SIMD-версий (ну и самому было интересно).
С использованием всех возможностей i7-6700K (GCC 7.3.0 с опцией
-march=native
) в перерасчете тактов в GiB/s для частоты процессора 3 ГГц.На всякий случай поясню — из t1ha-семейства тут только t1ha0(), так именно она изменяет переносимости ради скорости.
Теперь переносимые реализации хеш-функций, последние три строки — это 32-битные хеши для сопоставления.
На всякий случай поясню — здесь вместо t1ha0() результаты t1ha2_atonce(), так она переносима (и будет вызвана изнутри t1ha0 на CPU без AVX и т.п.):
На всякий, у xxHash есть некоторые проблемы, причем у всех версий.
Чтобы устранить подобные недостатки (в том числе, еще пример) следует использовать Merkle–Damgård хотя-бы в варианте "fast wide pipe". С точки зрения практической реализации это означает удвоение ширины внутреннего состояния c перекрестным "опылением" его половин на каждом цикле. Также желательно обеспечивать две точки инъекции данных, чтобы не терять энтропию.
Внутри t1ha именно так и сделано (wide pipe с перекрестным перемешиванием и двумя точками инъекции). Тем не менее, свойства t1ha2 не идеальны, так как операции перемешивания сильно упрощены ради скорости. Можно сказать, что именно эти упрощения не позволяют конкурировать с SipHash.
Поэтому, в t1ha3 основное изменением будет именно в этом месте. Кроме этого, будут заменены внутренности t1ha0 (это позволяет задекларированный контракт интерфейса), в том числе вариантов с AES-NI.
Не-переносимые реализации (SSE, AVX, AVX2) не совсем корректно сравнивать с переносимыми — получается волшебно большая разница. Соответственно, логично бы добавить в графики результаты t1ha0_aes.
Тем не менее, приятно видеть что t1ha2 уверенно идет на втором месте (за вычетом имеющих проблемы FNV и функций без seed).
В целом здорово что Yann Collet продолжил соревнование, так что постараюсь не отставать с t1ha3 :)
На всякий случай, всё-таки поясню почему вы не правы.
Если компилятору разрешить объединять константы (см ниже), то он вправе совместить все байты всех констант, с учетом требований к выравниванию их типов. Более того, аналогичный функционал может быть параллельно или независимо реализован в линкере.
В рассматриваемом случае такое объединение точно произойдет, если где-то в пределах видимости компилятора (или "умного" линкера) есть константа с совпадающим названием локали.
В свою очередь, если
m_resolvedName
имеет типconst wchat_t*
и соответствующее значение указателя было сохранено (не было создано исходной константы), то и результат сравнения будет true.Всё вышеописанное повсеместно в коде проектов собираемых для "мелких" процессоров (PIC, ATmega и т.п.).
For now "t1ha" is positioned as "not suitable for cryptography" at least until the independent cryptanalysis will completed and published. However, by some unpublished estimations of 128-bit version t1ha2 no less secure than SipHash.
In any case, I am very interested in independent third-party evaluation of t1ha2 properties.
To do this, the compression cycle and the final mixing (part-1, part-2) must be thoroughly analyzed.
Однако, в «военное время» компилятор (или даже линкер) может объединять константы (в том числе константные строки), и вот тогда сравнение будет работать правильно. Причем подобное не редкость в embedded-проектах.
nvnikolai, еще один повод для тоста в пятницу!
Комментариев очень много, очень.
Поэтому прошу прощенья если у меня выйдет что-то вроде "не читал, но осуждаю".
Тем не менее, мне не хватает:
Конкретный пример двуязычной пары статья-перевод:
P.S. Такие пары от меня буду еще (но триплеты с китайским пока слабо).