Перейти к содержанию

ZK-доказательства: witness и приватность данных

Свидетель существует вне доказательства

В предыдущем уроке мы описали отношение между публичным утверждением и скрытыми данными. Пользователь должен знать секрет и путь членства, чтобы построить доказательство права на действие курса 17. Эти данные называют witness. Даже если проверяющий не получает witness из proof, его всё равно обрабатывает программа, которая proof создаёт.

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

Что находится в локальном состоянии

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

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

Локальная запись библиотеки имеет версию формата и ссылки на группу. Секрет не включается в публичный манифест выпуска, в contentHash-досье, пример статьи или журнал ошибок. Указание «для отладки» не меняет последствий публикации. Досье выпуска должно позволять восстановить материалы, а не раскрывать право участника.

Путь членства не равен секрету идентичности

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

Представим три обязательства A, B и C и корень R1. После добавления D появляется R2. Сохранённый путь для A к R1 не обязательно подходит к R2. Если библиотека принимает только текущий корень, прежнее доказательство не проходит. Если допускается ограниченное окно старых корней, оно может быть принято до окончания этого окна. Политика приложения и механика дерева обсуждаются отдельно.

Руководство по группам Semaphore объясняет управление деревом и старые корни. Для учебного маршрута фиксируем, какой корень был использован, когда его заменили и по какому правилу он допускается. Не выдаём обновление пути за восстановление потерянной идентичности: эти проблемы имеют разные причины.

Какие сведения остаются публичными

Проверяющий видит публичную часть proof. В нашем адаптере это включает связь с действием библиотеки. Если сообщение содержит адрес получателя, этот адрес не становится скрытым от того, что членство анонимно. Если действие выполняется с обычного известного кошелька, наблюдатель может сопоставить транзакцию с пользователем вне доказательства.

Скрыто в модели доказательства:
  секрет участника, конкретный путь членства

Публично в маршруте приложения:
  группа/допустимый корень, scope, message, nullifier,
  получатель права, транзакция принятия, время действия

Это описание нашего маршрута, а не обещание абсолютной анонимности. Сайт также может видеть IP-адрес, cookie и учётную запись. RPC-провайдер наблюдает запросы, а оператор страницы управляет кодом браузера. Нужно отдельно рассматривать корреляцию и не называть всё действие «невидимым» только из-за скрытого witness.

Размер группы влияет на смысл приватности

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

Для курса 17 не публикуем таблицу «обязательство — настоящее имя», если целью режима является приватность членства. Административная регистрация всё же может иметь такую связь в своей системе, поэтому честно описываем, от кого она скрывается. Независимая проверка proof не запрещает администратору помнить процесс выдачи.

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

Где проходит доверие к генератору

Код построения witness должен соответствовать версии схемы. Но правильный генератор не освобождает схему от ограничений. Пользователь может заменить клиент и передать иные значения. Поэтому проверка браузера на длину courseId не доказывает, что допустимый диапазон проверяет circuit.

В Circom различие назначения и ограничения показано в документации сигналов. Хороший witness-генератор помогает честному пользователю получить данные, но verifier проверяет именно доказанное отношение. Если ограничение забыто, запрет в интерфейсе не исправляет математическую часть системы.

Для учебного продукта заранее отделяем публичный экспорт от резервной копии секрета. Экспорт proof может быть нужен для отправки, но резервная копия идентичности даёт возможность действовать от имени участника. Названия файлов и кнопок должны объяснять эту разницу. Ошибка интерфейса здесь способна раскрыть данные, не нарушая ни одного ограничения схемы.

Изменяем один элемент

Рассмотрим ожидаемые сценарии. Потеряли путь, но сохранили секрет: восстанавливаем публичные сведения группы и строим новый путь по допустимому корню. Потеряли секрет: старая идентичность сама не восстанавливается из обязательства. Раскрыли секрет: злоумышленник может получить её полномочия, поэтому требуется политика отзыва и повторной регистрации, а не просто очистка browser cache.

Если пользователь сменил получателя, строится новое сообщение действия. Копирование прежнего proof не меняет связанную публичную часть. Если интерфейс загрузил сторонний код, модель угроз включает чтение локального witness; ZK не защищает от программы, которой сам пользователь передал скрытые данные.

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

Оглавление серии