Объявление3 минуты

Все мои сайты теперь доступны на hloth.loki

Виктор Щелочков
Виктор ЩелочковФуллстек разработчик
hloth.loki, blog.hloth.loki, cv.hloth.loki now available in lokinet

Сегодня я опубликовал в Lokinet все свои личные веб-сайты под доменом hloth.dev. Подключитесь, замените .dev на .loki и вы зайдете на зеркало веб-сайта из клирнета! Прочитайте эту статью в Lokinet: http://blog.hloth.loki/blog/now-in-lokinet

Пока я читал о Lokinet и его настройке, мне стало любопытно, возможно ли создать бесплатный домен, как в сети Tor onion. Как оказалось, никто раньше не публиковал подобные инструменты! Я нашел только один репозиторий с программой на Golang, которая не работала. Я также нашел неработающую ссылку на имплементацию на питоне среди комментариев к issues в репозиториях oxen, и ничего более. Так что я решил просто создать свой собственный генератор!

В прошлом я уже публиковал генератор vanity Session ID для мессенджера Session, поэтому мне просто нужно было выяснить, как генерируется адрес loki. Оказалось, это не так просто. Я начал с просмотра документации, но, как и следовало ожидать от продуктов oxen, там не было никакой информации.

Пришлось отправиться в исходный код Lokinet на C++... Последний раз, когда я читал код на C от разработчиков oxen мне хотелось вырвать глаза: у меня не укладывается в голове, что в фукнцию нужно что-то передать и она запишет результат в эту переменную, вместо того, чтобы вернуть результат. Вдобавок C++ импортирует ВСЁ из файла, который вы референсите, а не конкретные перечисленные явно переменные, как в JavaScript. Приходится искать среди тонны файлов-заголовков, несколько из которых просто по приколу будут в соседнем репозитории.

https://github.com/oxen-io/lokinet/blob/178ac1757b1a6e835b9e39561376318c77e5ff08/test/service/test_llarp_service_name.cpp#L31
https://github.com/oxen-io/lokinet/blob/178ac1757b1a6e835b9e39561376318c77e5ff08/test/service/test_llarp_service_name.cpp#L31

В конце концов я все таки нашел файлы service/info.cpp, service/identity.cpp и constants/proto.hpp, которые и содержат логику по преобразованию файлов .private в адрес loki. На самом деле, адрес — это закодированный алгоритмом z-base32 ключ размером 32 байта. В файле .private хранится этот ключ и секретный seed, из которого его можно получить путем преобразований, а также получить и другие ключи, нужные для Lokinet, но не нужные нам для этой статьи.

Я написал алгоритм на псевдо-языке, чтобы объяснить, как это все работает:

1// 32 байта
2seed = crypto_random_bytes(32)
3
4// на момент 8 марта 2025
5protoVersion = 0
6
7// 64 байта
8hash = sha512(seed)
9
10// Clamping curve25519: https://neilmadden.blog/2020/05/28/whats-the-curve25519-clamping-all-about/
11hash[0] &= 248
12hash[31] &= 63
13hash[31] |= 64
14
15// 32 байта
16privateKey = hash[0:32]
17
18// 32 байта
19signingKey = crypto_scalarmult_ed25519_base_noclamp(privateKey)
20
21// https://en.wikipedia.org/wiki/Base32#z-base-32
22// всегда 52 символа
23addressName = zbase32(signingKey)
24
25// всегда 57 символов
26address = addressName + ".loki"
27
28// == This part is for writing to .private file: ==
29
30// 64 байта
31sValue = concat(seed, signingKey)
32
33// https://en.wikipedia.org/wiki/Bencode
34serviceInfo = bencode({
35 "s": sValue, // Не конвертируйте! просто отдайте сырые байты в bencode
36 "v": protoVersion
37})
38
39// Запишите serviceInfo как строку utf-8 в файл .private

Я написал это на JavaScript, провел несколько тестов и оно заработало! Даже не заняло весь день, хотя я ненадолго застрял на том, как генерируется encryptionKey (та программа на go, о которой я говорил, меня запутала: я думал надо использовать хеш blake для адреса, но на самом деле нужен только signing key, encryption key, nonce и прочее не надо)

Если хотите посмотреть на мою реализацию на JS, вот итоговый результат: https://github.com/VityaSchel/lokinet-vanity-address-generator

Я сделал бинарники, так что вам остается только скачать CLI и использовать его. Создание vanity доменов для Lokinet теперь очень просто. И быстро: на моем MacBook M1 Pro с 8 потоками скорость может доходить до 230 тыс генераций в секунду. А на подаренном моему парню MacBook M4 Pro она доходит аж до 450-500 тыс генераций в секунду, это настоящий монстр. Я нашел домен с 5-символьным префиксом "h1oth" всего за пару минут.

Кстати, если hloth.loki истечет, вы можете использовать вот этот домен для просмотра моих сайтов:

http://h1oth5jgjqqc1xji8hq1pjgupjzockn56uja7mfsrjcay63oi5ty.loki/

Было весело! Но если честно, мне нужна работа. Надеюсь Session однажды наймут меня. К слову, вот моё резюме: http://cv.hloth.loki/ 😁

Опубликовано: 8 марта