Pull to refresh

Comments 27

Elligator взяли референсную реализацию или свою? Если свою, то можно глянуть?
у вас на Go? Потому что по второй ссылке референс кода на С не очень много…
Да, на Go. По ссылке ведёт на статью блога автора кода. Говорит что основано на SUPERCOP C реализации, собственно упоминаемого на сайте Ed25519 сразу же: ed25519.cr.yp.to/software.html. Я сравнивал только то что тестовые векторы совпадают и тесты проходят.
Ясно, просто я кагбэ больше на c# и немного офигеваю от объема кода, который надо переносить. А тестовые вектора не подскажете где лежат? Интересно допилить
Не знаю, что вы так привязались к «закрытым проприетарным» системам. Задача создания безопасных соединений всегда очерчивается моделью угроз. Если вы используете «открытый» ГПСЧ (хотя бы тот же fortuna от FreeBSD), то это все равно не дает гарантий, что вы защищены, скажем, от закладок в оборудовании или чего-то подобного Dual EC DRBG (как видите, открытость все равно не исключает закладок в коде). В таком случае, если мы исключаем collocated adversary из модели угроз, то можно взять хотя бы тот же RDRAND + какие-то шумы от пользователя, скормить их фортуне или же взять тот же PRF на базе чачи. И это будет все равно лучше, чем упорствовать, что работать в закрытых проприетарных системах не может быть безопасным (потому что в вашей модели угроз безопасности все равно не существует).
UFO just landed and posted this here
1. Референс чего на C? Реализации GoVPN на C? Не будет. Код должен быть reviewable, одна из целей этого проекта.
2. Само собой 1 экран я написал только для прикидки. В моём случае это ровно 45 строк.
3. Это результат оптимизации кода в последних коммитах, где уменьшено кол-во вновь создаваемых переменных, за счёт чего для garbage collector осталось значительно меньше работы.
Портировал код Elligator на c#, даже тесты проходят. Правда беспокоит пара моментов:

1) Открытый ключ, полученный при помощи Elligator, не такой же как при обычном преобразовании ed25519
2) ed25519 вроде как для подписи, а нам нужно согласование ключей
1) Обычное преобразование сделает точку на кривой. Elligator сделает нечто похожее на шум.
2) Elligator в GoVPN и применяется для Curve25519 Диффи-Хельман ключей. Ed25519 Elligator-ом не затрагивается. Ed25519 публичные ключи это verifier для проверки пароля, лежат на жёстком диске сервера, по сети не передаются.
1) Я имел в виду, что если обернуть Elligator, то получившийся ключ будет не таким же, как если бы мы получали его из закрытого обычным способом и это довольно странно.
2) Curve25519 от Ed25519 отличается форматом кривой, при этом тот код, который вы привели, работает для Ed25519, а не для Curve25519. Вы это учитываете у себя в коде?
1) Таков алгоритм уж.
2) Документация библиотеки говорит об обратном. Надо будет проверить. Хотя странно как бы оно работало если бы пыталось применить алгоритм к разноформатным кривым и не падать.
Я был не прав, эллигатор все правильно генерит именно для Curve25519 (а я смотрел на ключи для ed25519) Меня просто смутило, что код лежит в файле d25519/extra25519/extra25519.go и все методы используются от Ed25519 (edwards25519.FeMul(&t0, &t0, &u) ...)
Так что, всё гуд, я спокоен )
Теперь, после того как я сам реализовал Elligator, у меня возник вопрос: А нафига он нам нужен? Почему, например, не шифровать открытый ключ каким то быстрым шифром с известным ключом (по сути, ксорить с заранее выбранной псевдослучайной последовательностью)? Проще же, и быстрее, судя по объему вычислений
Ну во-первых в GoVPN публичный ключ шифруется при передаче. В качестве случайной последовательности можно выбрать некий высокоэнтропийный PSK ключ — изначально в GoVPN так и было. Однако хочется чтобы можно было вместо выскокоэнтропийных PSK использовать пароль. Пароль эта штука которая уязвима к атакам по словарю, его можно пробовать перебирать. Мы перехватываем зашифрованный публичный DH ключ и перебираем пароли, пытаясь его дешифровать. Без Elligator мы внезапно сможем увидеть что при дешифровании получили не случайный непонятный шум, а как бы 25519 точку на кривой — после этого мы понимаем что пароль подобрали успешно. С Elligator-ом мы не знаем правильно ли мы дешифровали или нет (zero-knowledge).
Почему не знаете? Просто каждый раз пытаетесь обернуть его, вот и всё. Просто еще один шаг который надо выполнить
Если смогли преобразовать из Elligator, то и в него назад сможем же. Или я не понял вас.
Без Elligator мы внезапно сможем увидеть что при дешифровании получили не случайный непонятный шум, а как бы 25519 точку на кривой


Зная, что может использоваться Elligator, мы этот шум превратим в точку автоматически. Это просто еще одно преобразование, которое нужно принимать во внимание. Чем оно лучше шифрования по известному ключу?
Elligator *любой* шум превратит в точку. В итоге мы при каждом дешифровании получим точки (валидные публичные DH ключи). Мы не знаем какой конкретно DH ключ (точка) используется на деле. Без Elligator мы получим при дешифровании: либо то что не является точкой, либо точку. Здесь мы везде получаем то что Elligator сможет преобразовать в точки, то есть получаем точки всегда.
О, вот щас понятно стало, спасибо
Конструкции
if err != nil {
    panic(err)
} 

Можно заменить на
func must(err) {
   if err != nil {
        log.Fatal(err)
   }
}
// ...
must(err)

Ну или хотя бы не вызывать panic() там, где нужен log.Fatal(), потому что стек-трейсы не нужны в таком случае (ошибка конфигурации, например).

Было бы приятно видеть проект на github (хотя бы зеркало) :)
Огромное спасибо за проделанную работу!
Да, согласен насчёт того что panic() вреден. Собственно сейчас это у меня первое в списке что надо исправить, так как оно не красиво и пугает пользователей. Но я за использование без func() — чтобы меньше overhead был.

На github он имеется с самого начала: github.com/stargrave/govpn
Overhead не имеет значения для проверки конфигурации, например, тут. В основном цикле простой if оправдан, да и обычно там таких проверок не так много/они не подряд идут.

Спасибо за ссылку, упустил, что он уже есть на гитхабе.
А можно сделать как-нибудь проект «go-gettable»? Я вижу, что используются конкретные коммиты для внешних зависимостей, это можно решить с помощью утилиты из PackageManagementTools.
Хотя это не очень важно, учитывая простоту развертывания проектов на go.
Да, насчёт конфигурации полностью согласен. Беру на заметку, скоро закоммичу.

В самом начале govpn ещё можно было установить через go get, сейчас нет. Мне не нравится идея впиливать какие-то зависимости и инструменты для задач которые уже могут быть решены имеющимся инструментариев в виде Makefile-ов.

go get не делает криптографические проверки кода который скачался. HTTPS сертификат для Github это зависимость от PKI. Я не доверяю PKI для таких вещей. Отдельные tarball-ы с PGP-подписями: это старый добрый проверенный вариант.

Кроме того через go get не будет документации видно Texinfo-вской. Делать доку исключительно внутри Go кода: как вариант, но она не такая красивая, структурированная и пригодная для выкладки как статичный HTML-сайт. Можно ещё коммитить готовые .info/.html файлы, но это уж совсем не правильно: репозиторий это для разработки и не стоит в нём хранить генерируемые вещи (не исходники).

Release tarball содержат все требуемые библиотеки, собранную документацию, подпись не зависящую от PKI.
Минус вашего подхода в том, что вы используете import «govpn» в своем коде.
Например, если у кого-нибудь возникнет идея использовать код govpn для своего проекта (вот мне как раз не хватало vpn для проекта обхода блокировок РКМ), то это добавит сложностей. Я считаю, что выбор способа проверки кода/бинарников/etc лучше оставить конечному пользователю, как вы это частично и сделали уже (сайт доступен по HTTP).
По поводу красивости доков — readthedocs в этом смысле предпочтительней. Доки внутри go кода обычно используют для godoc, у них немного предназначение другое.

А можно поподробней каких сложностей? Если речь про namespace и то что govpn может коррелировать с другими названиями — да, тут не спорю что может возникнуть фигня. Но а какие пути решения с namespace-ом? Классический подход привязываться к github.com и прочему мне не нравится тем, что сегодня это github, завтра какой-то другой. Если кто-то делает fork (в терминах github) библиотеки где прописаны «github.com/stargrave», то тут тоже возникнут проблемы.

Способ аутентификации кода: иметь выбор это безусловно полезно. Но я, как разработчик, тоже должен оградить себя от возможных нападок со стороны пользователей связанных с тем что они или не проверяют что скачали или полагаются на информацию официально разработчиком не подтверждаемую. И тут похоже мне надо поднять HTTPS сервер и предоставить его данные о сертификате, но технически мне кажется что это куда более геморройнее (указывать всяким git clone, wget, go get, whatever сертификат).

Да, я про godoc как-раз говорил. Они для разработчика всё же заточены сильно. Вы имеете в виду чтобы readthedocs.org использовать пользователям для чтения документации? Иметь зависимость от подключения к Интернету? Опять же отсутствие проверки что информация которую они выведут будет достоверна (аутентифицирована). Online ресурсы — никогда не вариант. Только разве что для ознакомления и первого взгляда, а для этого есть собственно просто сайт проекта.
Sign up to leave a comment.