Перейти к содержимому
Anon Wallet

Синхронизация кошелька

У экранированного кошелька есть задача, которой нет у обычного. Баланс хранится не под вашим адресом, а в виде зашифрованных нот в общем пуле рядом с чужими. Ноты не помечены именами владельцев. Чтобы определить ваши средства, кошелёк должен найти ваши ноты среди всех остальных.

Для этого есть два способа, и выбор между ними — важнейшее решение экранированного кошелька в области приватности.

Два способа найти свои ноты

Попросить сервер найти их за вас. Кошелёк отправляет индексатору фильтр, выведенный из ключа просмотра, а индексатор возвращает совпадающие записи. Это быстро и дёшево, но полностью раскрывает цель поиска: фильтр и есть вопрос, который сервер обязан прочитать, чтобы ответить.

Загрузить данные и искать самостоятельно. Кошелёк получает историю пула фиксированными публичными частями, затем локально пытается расшифровать каждую ноту. Успешно расшифровываются только ваши ноты. Сервер не узнаёт, какие именно, поскольку его об этом не спрашивали.

Anon выбирает второй вариант — дайджест-синхронизацию.

Почему запрос сам по себе раскрывает информацию

Возникает соблазн считать это проблемой журналирования: если индексатор обещает не сохранять запросы, риск исчезнет. Это не так.

Запрос к индексатору — условие: дай коммитменты, соответствующие X. Это условие вычисляется из ключа просмотра. Сервер должен разобрать его, чтобы ответить, поэтому при каждом запросе материалы, связанные с ключом, попадают в память чужого компьютера независимо от политики хранения. Отключение логов меняет то, что записывается на диск, но не то, что сервер должен был узнать.

Не вести логи — обещание. Не иметь данных — архитектурное решение.

Поэтому сетевая анонимность не исправляет модель запросов. Можно отправить запрос через Tor, но индексатор всё равно точно знает, какими коммитментами вы интересовались; просто при этом он не знает ваш IP.

Как выглядит запрос дайджеста

История Anon хранится на CDN в неизменяемых файлах, разделённых на единообразные чанки. Запрос выглядит так:

GET https://digest.anon.inc/v4/1/chunks/42/commitments.json.gz

В нём нет ваших персональных данных. Путь определяется общим состоянием сети: чанк 42 охватывает фиксированный диапазон блоков Ethereum и содержит одинаковые байты для любого человека. Пустой кошелёк и кошелёк с тысячей нот отправляют одинаковый запрос к одному и тому же файлу.

Отсюда следуют два свойства:

  • В запросе истории нет фильтра, выведенного из данных кошелька. Даже полностью скомпрометированный CDN с полным журналированием узнаёт лишь, что IP скачал публичный файл. Он не может узнать, что в этом файле относилось к вам, поскольку такой информации у CDN нет.
  • Совпадения и их отсутствие невидимы. Расшифровка происходит на вашем устройстве после получения байтов. Узел CDN не может определить, содержал ли чанк 42 что-либо ваше. Индексатор знает это по своей конструкции: фильтр был самим вопросом.

Запечатанные чанки неизменяемы и кешируются на периферийных узлах в течение года, поэтому при стабильной работе запрос обслуживает ближайший дата-центр Cloudflare и он вообще не доходит до инфраструктуры Anon.

Что видит каждый сервер

Синхронизация — не единственная сетевая активность кошелька, и свойства разных каналов различаются. Конкретно:

Канал Оператор Данные выведены из ваших ключей? Что может узнать
CDN дайджеста (digest.anon.inc) Cloudflare Нет Ваш IP и факт загрузки публичных файлов определённого диапазона блоков
API актуального состояния индексатора (api.anon.inc) Anon Нет Ваш IP и примерное отставание от последнего блока сети
Прокси PPOI Anon перед сторонним агрегатором Да Ваш IP и запрошенные ослеплённые коммитменты
RPC-узлы Настроенный вами провайдер Нет Ваш IP и запрошенные публичные адреса и контракты
Сеть бродкастеров (Waku) Одноранговая сеть Нет Зашифрованные сообщения транзакций; узлы могут наблюдать метаданные соединения
Пеймастер через OHTTP Шлюз Anon и независимый ретранслятор Нет Ретранслятор видит IP клиента и зашифрованный запрос; шлюз — расшифрованный запрос и время отправки

API актуального состояния поддерживает синхронизацию между запечатываниями чанков. Он принимает курсор блока или последовательности — вашу позицию в сети, а не содержимое кошелька. Поэтому раскрывается «этот IP синхронизировался примерно до этого места», а не «эти ноты принадлежат ему».

Прокси PPOI — отдельная поверхность приватности. Доказательство невиновности запрашивает у агрегатора ослеплённые коммитменты, выведенные из ключа просмотра. Запросы специфичны для кошелька. Текущий прокси может кешировать ответы и сохранять параметры в метаданных кеша; хеширование ключа кеша не анонимизирует данные. Операторам нужно проверить сроки хранения и связывание с сетевыми метаданными. См. Прокси PPOI. Массовая история загружается без запросов по кошельку, а путь POI содержит их.

От чего это не защищает

  • Время и объём. Первая синхронизация всей истории выглядит в сети иначе, чем загрузка только последних данных вернувшимся кошельком. Это примерно раскрывает «данный IP последний раз синхронизировался около блока X», но не показывает, какие ноты ваши.
  • Метаданные соединения. Сервер, принимающий прямое соединение, видит его IP-адрес, время и метаданные TLS. Ретранслятор OHTTP отделяет соединение клиента от шлюза, расшифровывающего запрос; сам ретранслятор всё ещё видит IP клиента.
  • Ослеплённые коммитменты на пути PPOI, описанные выше.

Правильно настроенные VPN или Tor могут уменьшить раскрытие данных на сетевом уровне, но меняют круг доверенных сторон и не устраняют анализ трафика или данные приложения, специфичные для кошелька.

Сетевая приватность не стирает содержимое запроса, связанное с конкретным кошельком.

У индексатора на основе запросов утечка находится на уровне приложения, и пользователь не может её устранить, кроме как отказавшись от кошелька. Единообразные запросы истории, не зависящие от содержимого, исключают именно такое раскрытие фильтра. Другие запросы кошелька и сетевые метаданные требуют отдельного рассмотрения.

Компромисс

Это не приватное извлечение информации. Криптография не скрывает запрос, поскольку специфичного запроса нечего скрывать: вы просто скачиваете набор анонимности и ищете самостоятельно. Цена — трафик: при первой синхронизации передаётся сжатая история пула вместо нескольких подходящих строк.

Для этой нагрузки компромисс оправдан. Данные публичны, неизменяемы и одинаковы для всех пользователей, поэтому хорошо кешируются. Затраты возникают один раз на файл в каждой точке CDN, а не для каждого пользователя, и устраняется целый класс раскрытия информации. Но компромисс работает лишь пока выбор чанков не зависит от пользователя. Если клиент выбирает только «нужные» диапазоны по содержимому кошелька, он заново создаёт запрос в более медленной форме. Поэтому границы чанков определяются только высотой блока.