Open-source реализации отечественных криптоГОСТов

    На выходных решил поискать open-source реализации отечественных криптографических стандартов. Прежде всего интересовали новые: хэш-функция Стрибог (ГОСТ Р 34.11-2012), Кузнечик (ГОСТ Р 34.12-2015) и ЭЦП (ГОСТ Р 34.10-2012 или 2001 (без 512-бит) ). Старый ГОСТ 28147-89 специально не искал, поскольку найти его реализацию никаких проблем нет уже давно.
    Итак, давайте посмотрим, что же получилось. Сразу предупреждаю, что корректность реализаций не проверял.

    Кузнечик




    Стрибог




    Подпись





    Если указал не все — пишите добавлю.
    Поделиться публикацией
    Комментарии 64
      +1
      в копилку по Кузнечику http://omegicus.org/get/gost14.zip
      (инструмент чисто для себя делал, так что AS IS)
        0
        Забыли вот этот мега-проект на JS — gostcrypto.com
          0
          А, не, не забыли :)
          0
          ГОСТ 28147-89, если вдруг кому надо: gostash.it/ru/stashes/1425
            0
            Какой-то антипример реализации, если честно.
              0
              А что именно там не так?
                0
                Да хз, говногодес какой-то :-)
                  0
                  Это как? :)
                    0
                    Долго объяснять :-)
          • НЛО прилетело и опубликовало эту надпись здесь
              0
              В реализации отсюда https://github.com/sftp/gost28147/ есть ошибка. Некорретно реализована функция (режим CTR):

              void gen_gamma(struct gost_ctx_t *ctx)
              {
              	ctx->n4 = ctx->n4 + C1;
              	ctx->n3 = ((u64) ctx->n3 + C2) % 0xffffffff;
              
              	ctx->n1 = ctx->n3;
              	ctx->n2 = ctx->n4;
              
              	encrypt_block(&ctx->n2, &ctx->n1, ctx);
              }
              


              В стандарте своеобразная трактовка операции сложения по модулю 2^32-1. Должно быть:

              a + b (mod 2^32) ::= { a + b, if (a + b) < 2^32; a + b - 2^32, elsewhere }
              a + b (mod 2^32 - 1) ::= { a + b, if (a + b) < 2^32; a + b - 2^32 + 1, elsewhere }
              


              К сожалению, это частая ошибка при реализации ГОСТ 28147-89.

              Вот обсуждение этой проблемы, найденной мной в gostcrypto:
              github.com/rudonick/crypto/issues/1
              • НЛО прилетело и опубликовало эту надпись здесь
                  0
                  Согласен, отечественные стандарты это функции с секретом :-) От ТК-26 вообще не знаю чего ожидать, вроде бы должны способствовать стандартизации, но по факту — документы корявые, тестовые примеры не всегда сходяться… Был на нескольких заседаниях комиссии — такое впечатление, что попал на диссертационный совет годов 80-х, ей богу :-D

                  С Магмой тоже находимся в непонимании — то ли 89-й гост, то ли что-то новое. Ещё до стандартизации ставили вопрос о порядке байтов, но что-то вменяемого нам никто не ответил.
                    0
                    Добрый день!

                    1) Про тестовые примеры. Есть ошибочные контрольные примеры в ТК26TLS, изменения в документе с исправленными примерами должны быть утверждены на весеннем заседании ТК 26. Вы где-то еще ошибки находили?
                    2) Не могли бы Вы уточнить по поводу «корявости» документов? Практика создания документов «патчей» к стандартам (как ТК26TLS) себя изживает, новые документы ТК 26 создаются самодостаточными (ТК26АЛГ, ТК26ECC, ТК26SESPAKE). Какие есть предложения?
                    3) Магма, как неоднократно озвучивалось, это ГОСТ 28147-89 с фиксированными узлами замены из ТК26УЗ.
                      0
                      1) Из того, что точно помню — не сходились тесты для HMAC на базе ГОСТ 34.11-94.
                      2) Одно из предложений — дать возможность публичного обсуждения проектов, разместив текстовые документы на github (или поднять на ТК26 gitlab). Учитывать комментарии, принимать пулл-реквесты (закрытй форум это конечно хорошо, но не всегда). Публиковать окончательные документы в txt-виде как основном. Во многих проектах, связанных с ASN.1 структурами и расширением стандартных структур/контейнеров есть неоднозначные моменты. Принимать исправления и выпускать errata как для RFC. То есть в целом наладить похожий, открырый для сообщества процесс.
                      3) Ниже про Магму откомментировали уже. Рекомендации типа, — «внимательно читайте стандарт», — это конечно хорошо, но стандарт он на то и стандарт, что должен быть в достаточной степени однозначным и недвусмысленным. Мы же не юриспруденцией занимаемся :-)
                        0
                        1) HMAC на базе ГОСТ Р 34.11-94 описан в RFC 4357, в документе ТК 26 описывается исключительно HMAC на основе ГОСТ Р 34.11-2012. Уточните, пожалуйста, где была ошибка и в чем заключалась.
                        2) Вы правы в том, что в настоящий момент процесс избыточно закрыт. Но полную открытость обеспечивать тоже вредно – сотни школьников в комментариях утопили не одно благое дело с обсуждениями документов. А если Вы работаете в сфере ИБ и есть желание подключиться к процессу – это нетрудно сделать через секретариат ТК 26.
                        3) Вы в чем-то, конечно, правы, учитывая количество ошибочных из-за переворота байтов реализаций — даже крупные компании (не будем называть конкретно) предварительные релизы своих продуктов выпускали с подобными ошибками. Но, как я прокомментировал ниже, оба варианта указания данных имеют проблемы.
                          0
                          Я ошибся. Вот в этом документе ошибка (?) www.tc26.ru/methods/containers_v2/Addition_to_PKCS5_v2.pdf

                          Данные  тестовые  вектора  сформированы  по  аналогии  с  тестовыми  векторами  из RFC6070 [6] для алгоритма хэширования ГОСТ Р34.11-2012 512 бит [4].
                          
                          Input:
                             P = "password" (8 octets)
                             S = "salt" (4 octets)
                             c = 1
                             dkLen = 64
                             DK = bc d1 9a 1c 42 3a 63 e7 2e 47 ef 0f 56 56 6c 72 67 45 d9 6a c1 a1 c1 27 b2 ed ad b4 5f b4 5b 30 7a ca 15 99 9e 91 f6 40 f4 81 8f 68 af 71 6e 30 fd 54 3c 52 02 6b bb 29 5d 10 0e b4 71 33 9f 46
                          


                          Мой результат:

                          64 77 0a f7 f7 48 c3 b1 c9 ac 83 1d bc fd 85 c2 61 11 b3 0a 8a 65 7d dc 30 56 b8 0c a7 3e 04 0d 28 54 fd 36 81 1f 6d 82 5c c4 ab 66 ec 0a 68 a4 90 a9 e5 cf 51 56 b3 a2 b7 ee cd db f9 a1 6b 47
                          

                            +1
                            На сайте ТК 26 коллеги обновили версию, примеры скорректированы, результаты с Вашими сошлись.
                              0
                              Отлично. А вот как историю исправлений документа посмотреть?
                                0
                                Полагаю, никак — сайт у ТК 26 не как у IETF, увы.
                                  0
                                  Про сайт у ТК-26 вообще лучше не говорить — говно поделие какое-то на битриксе (о он ешё и платный, если я правильно понимаю). В общем, печально всё…
                    0
                    По поводу контрольных примеров погуглите про little и big endian.Магма отличается только фиксированным набором подстановок. В новом стандарте просто развернули порядок байтов в описании для 'унификации' с международными стандартами.
                    • НЛО прилетело и опубликовало эту надпись здесь
                        0
                        Да ну вы что. От формы записи результат не меняется. Там в начале стандарта написано как и что читать. Алгоритм тот же самый, только подстановки другие.
                        • НЛО прилетело и опубликовало эту надпись здесь
                            0
                            Добрый день!

                            Все тестовые данные в новых стандартах, действительно, приведены «с переворотом байтов». Ошибкой (с формальной точки зрения) это не является, так как в начале стандарта в обозначениях это явно указано. Удобно это или нет? Для реализации, разумеется, нет (приходится переворачивать все входы и выходы), для формальной корректности стандарта и упрощения описания – в чем-то удобно. Разумеется, Магма в точности совпадает с ГОСТ 28147-89 с узлами замены ТК26-Z из соответствующих Рекомендаций ТК-26.

                            Весьма много разработчиков первые реализации новых ГОСТов выкатывают ошибочные, с переворотом байтов. Так что определенная проблема, действительно, есть, но рекомендация тут только одна — внимательно читать стандарт.

                            В документах ТК 26, замечу, все данные в основном приведены в little-endian, без переворотов. Но из-за этого в тексте иногда встречаются неочевидные обозначения.
                            • НЛО прилетело и опубликовало эту надпись здесь
                                0
                                Во-первых, просьба сменить тон общения на более спокойный, не нужно нервничать.
                                Во-вторых, никто ни разу не говорил, что от старого ГОСТа были унаследованы режимы работы. Хоть ГОСТ Р 34.12-2015 и совпадает с ГОСТ 28147-89 в версии «Магма», но режим имитовставки в ГОСТ Р 34.13-2015 введен другой. Кроме того, другой в ГОСТ Р 34.13-2015 используется и режим гаммирования.
                                В-третьих, насчет реализации на сайте ТК 26, все же давайте не путать стандарты и тестовые реализации. Если видите ошибку, так потратьте чуток времени, напишите авторам. Поверьте, никто ошибочную реализацию отстаивать не будет, если ошибки и впрямь есть.

                                По поводу RFC, авторы всех российских проектов всегда будут рады критике. Навскидку, сейчас по линии IETF у российских коллег идет работа по двум проектам RFC: по сопутствующим алгоритмам и по протоколу SESPAKE. Присоединяйтесь, пишите авторам на почту, критикуйте, предлагайте коррективы – участвуйте.
                                • НЛО прилетело и опубликовало эту надпись здесь
                                    0
                                    Именно что Магма как базовое преобразование — это в точности ГОСТ 28147-89. Суть проблемы с пониманием тут ровно в том, что базовое преобразование шифра и его режимы работы (а для прикладника эти вещи в принципе не особо разделимы) — все же разные вещи. Простой тезис: в режиме ECB Магма в точности эквивалентна ГОСТ 28147-89 с узлами замены ТК 26 Z.

                                    Писать по стандартам ГОСТ Р 34.1х-2015 можно на находящийся в ведении ИнфоТеКСа секретариат ТК 26 (лучше сразу попросить перенаправить на конкретных авторов), по документам по сопутствующим алгоритмам и SESPAKE – например, напрямую Станиславу Смышляеву из КРИПТО-ПРО (кстати, утвержденные российские версии документов по алгоритмам и по SESPAKE ТК 26 выложило на своем сайте).
                                    • НЛО прилетело и опубликовало эту надпись здесь
                                0
                                Весьма много разработчиков первые реализации новых ГОСТов выкатывают ошибочные, с переворотом байтов.
                                О, я тоже наступил на эти грабли! Вопрос как от неспециалиста в теории криптографии: уступает ли реализация с кривым порядком байт правильной, с точки зрения надёжности-безопасности?
                                  0
                                  Нет, конечно. Только проблемы с совместимостью.
                                    0
                                    Да там граблей — целый вагон. Но отечественная криптография — удел «элиты». Понимаете, нельзя вот так вот просто взять и опубликовать стандарт, который всем был бы одинаково понятен. Нельзя вот так просто опубликовать исчерпывающие тестовые последовательности, для всех режимов и с учётом много численных нюансов.
                        0
                      0
                      LibreSSL.
                      В куске про ЭЦП надо уточнять, поддерживается ли версия -2012 года, с размером ключа 512 бит.
                      Про 28147-89/Р 34.11-94. Их много кто поддерживает, но не много где есть возможность использовать разные S-BOX.
                        0
                        Потихоньку пилится код для nettle/GnuTLS, но пока далеко до завершения.
                          +1
                          Насколько они соответствуют исходным алгоритмам по криптостойкости?
                          Было бы интересно посмотреть криптоанализ, а также анализ на типичные ошибки при реализации криптографии (например, уязвимость к тайминг атакам).
                            +1
                            Все подписались?
                            https://habrastorage.org/files/084/c25/36f/084c2536fe7044cf83f19fbcaaf45cd0.png
                              0
                              Точно ли в openssl есть реализация ГОСТ Р 34.10-2012? Я видел там GOST 28147-89 и GOST R 34.10-2001
                                0
                                Написал так потому, что и 2001й и 2012й ГОСТы это по сути одна и та же схема. Например в ISO/IEC 14888-3 наша ЭЦП описана безотносительно к размерам (хотя есть численные примеры есть для 256 и для 512). Но формально вы правы.
                                0
                                В pygost тоже появилась реализация Кузнечика на чистом Python: http://git.cypherpunks.ru/cgit.cgi/pygost.git/commit/?id=451f5a3a43425377e4e5566d9bf945d662e84f9d
                                • НЛО прилетело и опубликовало эту надпись здесь
                                    0
                                    Обоснуйте пожалуйста свою клевету на то что «реализация на Python» является «не правильной». Я смотрю на ваш список (тестовые вектора, нарезание блоков, padding) и нет ни одного пункта которому не удовлетворял бы pygost.
                                    • НЛО прилетело и опубликовало эту надпись здесь
                                        0
                                        Вектора в коде специально написаны в «некорректном» виде чтобы оно совпадало с тем что написано в стандарте, в бумажке: чтобы можно было посмотреть на бумажку и монитор и увидеть те же самые данные.

                                        То что он просто склеивает и помещает все данные в память: это да, не оптимально. Но тоже сделано осознанно: чтобы код оставался максимально простым. Ориентируется его применение исключительно для тестовых целей, например чтобы сравнить какую-нибудь другую реализацию, быстренько на коленке что-то посчитать, но конечно не для «боя».
                                    0
                                    В GoGOST (http://git.cypherpunks.ru/cgit.cgi/gogost.git/) появилась реализация 34.10-2001/2012 на чистом Go. Кроме того, в нём и 28147-89, 34.11-94, 34.11-2012.
                                      0
                                      Ещё появилась реализация 34.12-2015 Кузнечик.
                                        0
                                        Спасибо! Сейчас добавим
                                    • НЛО прилетело и опубликовало эту надпись здесь
                                        0
                                        Круто! Спасибо за подробный анализ характеристик. Добавил ссылку
                                        0
                                        * В ссылке к Кузнечику http://omegicus.org/get/gost14.zip/ — лишний слэш в URL, приводящий к 404.
                                        * В ссылке к Стрибогу https://code.google.com/archive/p/jstribog/ — в URL я вижу JS, возможно написано оно не на Java, а на JavaScript. Прощу прощения если не так, JS-enabled броузера нет чтобы проверить.
                                        * Кривая ссылка к Стрибогу и 34.10 на libressl.org (лишний http://)
                                        * ccgost engine в OpenSSL уже нет. Зато 34.10 есть в LibreSSL, а Стрибог в https://github.com/gost-engine/engine

                                        Я создал вот такой сайт: http://www.cypherpunks.ru/gost/ в котором на русскоязычных страницах перенёс исправленные ссылки:

                                        * http://www.cypherpunks.ru/gost/ru34122015.html#g_t34122015Impl
                                        * http://www.cypherpunks.ru/gost/ru34112015.html#g_t34112015Impl
                                        * http://www.cypherpunks.ru/gost/ru3410.html#g_t3410Impl
                                          0
                                          Поправил, спасибо.
                                          0

                                          @ru_crypt.
                                          Подбираюсь к реализации Кузнечика, перед этим сверяю старые реализации ГОСТ 28147-89 с тем, что написано в ГОСТ Р 34.12-2015/ГОСТ Р 34.13-2015. Правильно ли я понимаю, что пример из стандарта ГОСТ Р 34.12-2015 надо читать так:


                                          Если ключ K задан как массив байт
                                          {0xcc, 0xdd, 0xee, 0xff, 0x88, 0x99, 0xaa, 0xbb, 0x44, 0x55, 0x66, 0x77, 0x00, 0x11, 0x22, 0x33, 0xf3, 0xf2, 0xf1, 0xf0, 0xf7, 0xf6, 0xf5, 0xf4, 0xfb, 0xfa, 0xf9, 0xf8, 0xff, 0xfe, 0xfd, 0xfc},


                                          то при шифровании массива байт
                                          {0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe}


                                          получится массив байт
                                          {0x3d, 0xca, 0xd8, 0xc2, 0xe5, 0x01, 0xe9, 0x4e}

                                            0
                                            Открытый текст и шифртекст такие, а вот ключ в примере (приложение А.2, с.16 на https://tc26.ru/standard/gost/GOST_R_3412-2015.pdf) указан другой.

                                            K = ffeeddccbbaa99887766554433221100f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff.

                                            То есть, массив байт для ключа следующий:
                                            {0xff, 0xfe, 0xfd, ..., 0xee, 0xff}
                                              0

                                              Т.е. на уровне последовательностей байт 34.12-2015 отличается от того, как до сих пор применяли 28147-89?

                                                0

                                                Переформулирую вопрос: получается, что ключ считывается как единый вектор в формате Little endian от начала и до конца. В этом есть некая логика. По сути новый стандарт меняет порядок подключей в ключевом расписании по сравнению с традиционными способами применения ГОСТ 28147-89. Правильно ли я понимаю, что все предыдущие документы/стандарты, которые использовали ГОСТ 28147-89, например тот же ТК26CMS, оказываются несоответствующими ГОСТ Р 34.12-2015?

                                                  0
                                                  Нет, вопрос только в обозначениях и записи.
                                                    0

                                                    Текущие реализации ГОСТ 28147-89 по массиву {0xff, 0xfe, 0xfd, ..., 0xee, 0xff} строят ключевое расписание {0xfcfdfeff, 0xf8f9fafb, 0xf4f5f6f7, 0xf0f1f2f3, 0x33221100, 0x77665544, 0xbbaa9988, 0xffeeddcc}, а не {0xffeeddcc, 0xbbaa9988, 0x77665544, 0x33221100, 0xf0f1f2f3, 0xf4f5f6f7, 0xf8f9fafb, 0xfcfdfeff}, как записано в ГОСТ 34.12-2015.


                                                    Более того, такой («старый») способ построения ключевого расписания соответствует примеру из окончательной редакции проекта «Криптографические алгоритмы, сопутствующие
                                                    применению алгоритмов электронной цифровой подписи и функции хэширования»

                                              0
                                              У нас в i2pd теперь тоже есть своя реализация ГОСТ Р 34.10-2012 и ГОСТ Р 34.11-2012 (стрибог) для подписи адресов.
                                              • НЛО прилетело и опубликовало эту надпись здесь
                                                  0
                                                  Для хэша openssl не используется.
                                                  Из openssl 1.1 гост выкинули.
                                                    0

                                                    Можно engine использовать внешнюю.

                                                0
                                                GPU майнер, вычисляющий двойной ГОСТ 34.11-2012. Сначала вычисляется 64-х байтный хэш от 80-байтного заголовка, затем от этих 64 байт вычисляется 32 байтный хэш, который потом используется в блокчейне вместо SHA256 и PoW.
                                                Хэшируются ровно 4 блока, используются таблицы и превычисленные значения преобразований для нулевого и единичного IV.

                                                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                Самое читаемое