ZK-доказательство позволяет Вам доказать, что утверждение истинно, не раскрывая, почему оно истинно.
Канонический пример: представьте дальтоника, держащего два одинаковых на вид шара — один красный, один зелёный. Вы можете доказать ему, что шары действительно разного цвета, не сообщая, какой из них какой. Для этого он за спиной либо меняет шары местами, либо нет, а Вы говорите, был ли обмен. После достаточного числа раундов он убеждён, что Вы отличаете красный от зелёного, но всё ещё не знает, какой шар какого цвета.
В этом вся идея. SolMask использует ZK-доказательства для одного конкретного утверждения:
«Я знаю секрет, соответствующий одному из депозитов в этом защищённом пуле, и я авторизовал вывод N токенов на кошелёк X».
Доказательство ничего не говорит о том, какой именно депозит. Блокчейн видит корректный вывод, но не может сопоставить его с конкретным депозитом.
Что входит в доказательство
Когда Вы делали депозит, SolMask вычислил обязательство:
commitment = Poseidon(secret, nullifier_secret, amount, unlock_slot)
В блокчейн попадает только обязательство. Четыре входа — Ваш секрет, нуллификатор, сумма и время ожидания — никогда не покидают Ваш браузер. Они не сохраняются в файл, который Вам нужно беречь: Ваш кошелёк заново выводит их по запросу, подписывая фиксированное сообщение, а депозит публикует ончейн зашифрованный кошельком блоб для восстановления, чтобы тот же кошелёк мог заново обнаружить ноту где угодно.
При выводе Ваш браузер генерирует доказательство Groth16, которое на языке математики означает:
- Обязательство является одним из листьев в дереве Меркла пула (без указания, каким именно листом).
- Раскрываемый сейчас нуллификатор — это хеш секрета нуллификатора, к которому Вы привязались.
- Прошло достаточно времени (
current_slot >= unlock_slot). - Выводимая сумма согласуется со значением обязательства.
- Любая сдача хешируется в новое обязательство, которое Вы добавляете в дерево.
Доказательство занимает около 200 байт. Программа Solana проверяет его за несколько миллисекунд.
Зачем нужны нуллификаторы?
Каждый депозит сопровождается уникальным секретом. При выводе Вы раскрываете хеш этого секрета — нуллификатор. Блокчейн фиксирует каждый увиденный нуллификатор; если Вы попытаетесь вывести тот же депозит дважды, вторая попытка раскроет тот же нуллификатор и будет отклонена.
Важно, что нуллификатор генерируется из Вашего приватного секрета — поэтому только Вы можете создать его для Вашего депозита, но блокчейн способен проверить его, не узнавая сам секрет.
Почему Poseidon?
Стандартные хеши вроде SHA-256 чрезвычайно дороги при представлении в виде ZK-доказательств (сотни тысяч ограничений). Poseidon — это хеш, разработанный быть дешёвым внутри ZK-схем — примерно в 5 раз меньше ограничений, чем у Keccak при том же уровне безопасности. Цена этого: он медленнее SHA-256 при прямом вычислении на CPU, но для нашего сценария это не имеет значения.
Почему Groth16?
Groth16 — это самая проверенная в продакшене система доказательств в ZK. Её доказательства крошечные (3 точки на эллиптической кривой, около 200 байт) и проверяются за постоянное время. Подвох: она требует одноразовой церемонии доверенной настройки для генерации публичных параметров. Церемония SolMask описана в наших заметках о доверенной настройке.
Чему Вам не нужно доверять
Вам не нужно доверять операторам SolMask. Код верификатора находится в блокчейне и публичен. Схема публична и воспроизводима. Релейер может отказаться транслировать Ваш вывод, но он не может украсть Ваши средства — доказательство привязано к адресу получателя, и любая попытка перенаправить средства сделает его недействительным.
Чему Вам действительно нужно доверять
Доверенной настройке. Если кто-либо из участников церемонии сохранил секрет — «токсичные отходы» — он мог бы подделывать доказательства и опустошить пул. Церемония SolMask использует публичный маяк блока Bitcoin как якорь случайности; публичная многосторонняя церемония запланирована по мере развития протокола.