Back to Blog

Анализ уязвимости Zcash Orchard | Еженедельник BlockSec

Code Auditing
10 июня 2026 г.
10 min read
Key Insights
  • В схеме экранированного пула Orchard протокола Zcash была обнаружена критическая уязвимость корректности, потенциально позволяющая незаметно подделывать ZEC (нативный токен Zcash) внутри пула Orchard. Ошибка существовала более чет

За прошедшую неделю (2026/06/01 - 2026/06/07) в блокчейн-экосистемах было зафиксировано несколько инцидентов, связанных с атаками. Основная тема отчёта этой недели — публичное раскрытие критической уязвимости корректности (soundness) в защищённом пуле Orchard сети Zcash, которая могла позволить незаметную подделку монет ZEC. Подтверждений эксплуатации уязвимости в сети не обнаружено, однако раскрытие спровоцировало экстренное обновление сети, а курс ZEC упал более чем на 40%.

Дата Инцидент Тип Оценочный ущерб
2026/06/04 Zcash Orchard Ошибка корректности ZK Эксплуатация не подтверждена

Best Security Auditor for Web3

Validate design, code, and business logic before launch

Главное событие недели: ошибка корректности в Zcash Orchard

Этот инцидент выбран главным событием недели, поскольку является одной из наиболее серьёзных ZK-уязвимостей, обнаруженных в рабочей среде. Отсутствующее ограничение схемы оставалось незамеченным более четырёх лет, несмотря на многочисленные аудиты, и в конечном счёте было обнаружено в ходе проверки безопасности с использованием ИИ. Класс уязвимостей (недостаточно ограниченные отношения в ZK-схемах) может присутствовать в любом протоколе, построенном на ZK-схемах.

4 июня 2026 года Zcash публично раскрыла критическую ошибку корректности в схеме защищённого пула Orchard [1]. Отсутствующее ограничение в схеме доказательства с нулевым разглашением нарушило криптографическую привязку, предотвращающую двойное расходование, что потенциально позволяло тратить одну и ту же защищённую ноту несколько раз без возможности обнаружения. Уязвимость существовала с момента активации Orchard в мае 2022 года и была обнаружена 29 мая 2026 года исследователем безопасности Тейлором Хорнби в ходе аудита с применением ИИ. Экстренное обновление сети (NU6.2) исправило схему 3 июня 2026 года. Свидетельств эксплуатации уязвимости не обнаружено.

Предыстория

Zcash — это блокчейн первого уровня с акцентом на конфиденциальность, нативным токеном которого является ZEC. В отличие от Bitcoin, где все детали транзакций общедоступны, Zcash поддерживает защищённые транзакции посредством доказательств с нулевым разглашением, скрывая адреса отправителей, адреса получателей и суммы транзакций. Zcash имеет несколько защищённых пулов, каждый из которых соответствует определённому поколению протокола конфиденциальности. Orchard — последнее поколение, активированное в мае 2022 года с обновлением сети NU5; для верификации транзакций оно использует систему доказательств с нулевым разглашением halo2 [2]. При совершении защищённой транзакции пользователь выступает в роли доказывающего: он формирует доказательство с нулевым разглашением, используя схему Orchard, которая подтверждает действительность транзакции — владение нотой, корректное получение нуллификатора и баланс сумм — без раскрытия каких-либо приватных данных. Узлы сети выступают верификаторами, проверяя доказательство без доступа к исходным данным. Схема Orchard определяет ограничения, которым должно удовлетворять каждое корректное доказательство. Уязвимость находится в реализации этой схемы и затрагивает четыре ключевых концепции Zcash: ключи, адреса, ноты и нуллификаторы.

Ключи. Иерархия ключей Zcash сложнее, чем у большинства блокчейнов. Из единственного ключа расходования (секрета кошелька) выводится несколько подключей: ask (секретный ключ авторизации расходования), nk (ключ получения нуллификатора) и rivk (рандомизатор). На их основе система вычисляет ak (публичный ключ авторизации) и ivk (ключ просмотра входящих, через ivk = Commit(ak, nk, rivk)). Ключ ivk используется для идентификации и получения входящих средств.

Адреса. Для создания адреса Orchard пользователь выбирает диверсификатор d (11-байтовое значение), который определяет диверсифицированную базовую точку g_d = DiversifyHash(d). Адрес представляет собой пару (d, pk_d), где диверсифицированный ключ передачи pk_d вычисляется как скалярное умножение на эллиптической кривой: pk_d = [ivk] g_d. Это означает, что адрес криптографически привязан к ключу просмотра пользователя.

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

Нуллификаторы. При расходовании ноты расходующий раскрывает нуллификатор nf, вычисленный из данных ноты и ключа нуллификатора nk: nf = Extract_P([(F_nk(ρ) + ψ) mod p]G + cm). Ключевое свойство безопасности состоит в том, что каждая нота должна порождать ровно один нуллификатор. После появления нуллификатора в сети соответствующая нота считается безвозвратно израсходованной. Если одна и та же нота могла бы порождать разные нуллификаторы, её можно было бы потратить несколько раз незаметно.

Цепочка привязки. Эти концепции связаны криптографической цепочкой привязки:

Выделенные красным узлы (pk_d, nk) — это точки, в которых уязвимость разрывает цепочку привязки: схема должна обеспечивать выполнение условия pk_d = [ivk] g_d, что привязывает расходующего к корректному ivk, а следовательно — к корректному nk для данной ноты. Если эта привязка нарушена, расходующий может подделать фиктивный ivk и тем самым использовать разные nk при каждом расходовании. Различные значения nk порождают разные нуллификаторы для одной и той же ноты, что позволяет осуществлять двойное расходование.

Как схема обеспечивает эту привязку. Отношение pk_d = [ivk] g_d представляет собой скалярное умножение на эллиптической кривой (Q = [k]P), реализованное с использованием алгоритма удвоения-и-сложения. В схеме с нулевым разглашением верификатор не выполняет алгоритм напрямую; вместо этого схема ограничивает каждый промежуточный шаг. Корректная схема скалярного умножения должна обеспечивать, в частности, что базовая точка внутреннего цикла равна предполагаемой входной базовой точке (P_loop = P_input). Без этого ограничения схема может доказывать факт выполнения корректного скалярного умножения, но с неправильной базовой точкой, что делает всю цепочку привязки бессмысленной.

Анализ уязвимости

Уязвимый гаджет ECC использовался в отношении скалярного умножения, обеспечивающем выполнение условия pk_d = [ivk] g_d, где Q = pk_d, k = ivk, а P = g_d. Уязвимый код находится в реализации скалярного умножения с переменным основанием в репозитории halo2 (incomplete.rs L309-L310):

// incomplete.rs (полный исходный код по ссылке выше)
298  for (row, k) in bits.iter().enumerate() {
299      // z_{i} = 2 * z_{i+1} + k_i
         ...
305      z = region.assign_advice(|| "z", self.z, row + offset, || z_val)?;
306      zs.push(Z(z.clone()));
307
308      // Присвоить `x_p`, `y_p`
309      region.assign_advice(|| "x_p", self.double_and_add.x_p, row + offset, || x_p)?;  // BUG
310      region.assign_advice(|| "y_p", self.y_p, row + offset, || y_p)?;                  // BUG
311
312      // Если бит установлен, использовать `y`; если не установлен — использовать `-y`
313      let y_p = y_p
314          .zip(k.as_ref())
315          .map(|(y_p, k)| if !k { -y_p } else { y_p });
316
317      // Вычислить и присвоить lambda1
318      let lambda1 = y_a.zip(y_p).zip(x_a.value()).zip(x_p)
             .map(|(((y_a, y_p), x_a), x_p)| (y_a - y_p) * (x_a - x_p).invert());
         ...
     }

В схеме с нулевым разглашением доказывающий заполняет значения всех ячеек; сама схема не может копировать или передавать значения между ячейками — она может лишь определять ограничения, которые верификатор проверяет. Две строки, помеченные BUG, используют assign_advice() для записи координат базовой точки x_p и y_p (приватных входных данных схемы, известных как значения свидетеля) в вспомогательные столбцы схемы (область приватных входных данных доказывающего). Эта функция записывает значение без создания ограничения, связывающего его с внешней базовой точкой. Отдельное ограничение обеспечивает равенство базовых значений во всех итерациях цикла — доказывающий не может использовать разные базовые точки в каждой итерации. Однако доказывающий может подставить произвольную единственную базовую точку для всех итераций, и схема её не отвергнет, поскольку ни одно ограничение не привязывает базовые значения цикла к реальной g_d, переданной извне.

Корректная функция — это copy_advice(), которая записывает значение и добавляет ограничение равенства (ограничение копирования), обеспечивающее его соответствие реальной базовой точке g_d. Поскольку g_d меняется для каждого адреса (выводится из диверсификатора каждого адреса), схема не может жёстко закодировать её — она должна ограничивать базовую точку цикла, чтобы та соответствовала g_d, вычисленной выше по цепочке.

В результате схема фактически не обеспечивала выполнения условия pk_d = [ivk] g_d. Злоумышленник, выступающий в роли доказывающего, мог подставить произвольную базовую точку внутри цикла (вместо корректной g_d), и схема всё равно принимала бы доказательство: внутренние вычисления оставались алгебраически самосогласованными, но более не были привязаны к диверсифицированной базовой точке, заданной протоколом. Эта дополнительная степень свободы позволяет доказывающему каждый раз выбирать другой nk, вычислять соответствующий ivk = Commit(ak, nk, rivk) и использовать неограниченное скалярное умножение для того, чтобы поддельный ivk прошёл проверку. Поскольку нуллификатор зависит от nk, каждое расходование даёт отличный нуллификатор:

та же нота N + nk_1 → nf_1
та же нота N + nk_2 → nf_2
где: nf_1 ≠ nf_2

Консенсус проверяет лишь то, появлялся ли нуллификатор ранее в сети. Поскольку каждое расходование порождает уникальный нуллификатор, неотличимый от легитимного, двойное расходование остаётся невидимым для сети.

Исправление [3] добавляет вызов copy_advice() в первой итерации цикла (row == 0), создавая ограничение копирования, которое привязывает базовую точку цикла к реальному base, переданному извне. В остальных итерациях по-прежнему используется assign_advice(), однако существующее ограничение согласованности между итерациями распространяет привязку на все из них.

Последствия и реакция

Сценарий эксплуатации. Злоумышленник, выступающий в роли доказывающего, мог использовать уязвимость для многократного расходования одной и той же ноты Orchard, каждый раз генерируя разный нуллификатор. Поскольку доказательство с нулевым разглашением скрывает приватные входные данные схемы, мошеннические нуллификаторы неотличимы от легитимных. Атака не оставляет однозначных криптографических доказательств в сети, что делает невозможным однозначное определение факта её осуществления.

Уязвимость существовала с момента активации Orchard в мае 2022 года (обновление NU5), что даёт общее окно воздействия более четырёх лет. Механизм учёта оборотов (turnstile) Zcash ограничивает объём поддельных средств, которые могут выйти из пула Orchard в прозрачные пулы или пул Sapling, ограничивая тем самым реальное воздействие на общее предложение. Тем не менее поддельные ноты могли существовать незамеченными внутри защищённого пула, а его свойства конфиденциальности делают криптографическое доказательство факта эксплуатации уязвимости невозможным.

Примечание: механизм turnstile срабатывает только тогда, когда общий объём оттоков превышает общий объём притоков для пула. Злоумышленник мог выводить поддельные средства небольшими суммами с течением времени, не достигая этого лимита. Расхождение стало бы очевидным лишь в том случае, если бы легитимные пользователи в совокупности попытались вывести больше средств, чем фактически содержит пул.

Обнаружение и реакция. Уязвимость была обнаружена 29 мая 2026 года исследователем безопасности Тейлором Хорнби (работающим по контракту с Shielded Labs) с использованием фреймворка аудита на основе ИИ с моделью Anthropic Opus 4.8, выпущенной днём ранее. Предыдущие аудиты той же схемы с более старыми моделями не выявили ошибку. Хорнби в тот же день сообщил о проблеме в ZODL. Экстренный мягкий форк 2 июня (UTC) временно отключил транзакции Orchard, а обновление сети NU6.2 от 3 июня (UTC, блок 3 364 600) ввело исправленную схему, восстановив функциональность Orchard [1]. После публичного раскрытия информации 4 июня курс ZEC упал более чем на 40%, а объём ликвидаций превысил 100 миллионов долларов [4].

Заключение

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

Библиотека halo2 используется в экосистеме ZKP повсеместно, и аналогичные недостаточно ограниченные отношения могут присутствовать в других проектах, построенных на этих криптографических строительных блоках. Протоколам, использующим доказательства с нулевым разглашением, следует реализовывать проверки целостности баланса (например, механизм turnstile) для ограничения потенциального воздействия необнаруженных ошибок корректности: без механизма turnstile Zcash поддельные средства, созданные внутри защищённого пула, могли бы свободно перетекать в общее предложение. Shielded Labs объявила о планах по формальной математической верификации схемы Orchard.

Это открытие является типичным примером рабочего процесса с участием человека: опытный исследователь безопасности создал фреймворк аудита и направлял исследование, тогда как ИИ взял на себя широкий охват проверки отдельных ограничений схемы. Ни один компонент в отдельности не был достаточен: предыдущие запуски с использованием только ИИ на более старых моделях упустили ошибку, и годы экспертной проверки людьми также её не выявили. Хорнби сам является экспертом по безопасности Zcash — предметная экспертиза была необходима для определения правильного охвата аудита, в рамках которого ИИ мог работать. Как показывают недавние исследования BlockSec [5], модели ИИ стремительно прогрессируют в области анализа безопасности, однако для указания ИИ на правильные цели и валидации его находок по-прежнему необходимо экспертное руководство. Интерактивное сотрудничество между экспертами и ИИ — а не опора исключительно на ИИ — является наиболее эффективной моделью работы.

Ссылки

  1. The Orchard counterfeiting vulnerability and next steps, Zcash Community Forum, June 4, 2026. Ссылка
  2. halo2: A zero-knowledge proof system, GitHub. Ссылка
  3. Fix: anchor scalar multiplication base point via copy constraint, halo2 GitHub. Ссылка
  4. Why ZEC fell 40% even after Zcash patched a shielded pool bug, CoinTelegraph, June 5, 2026. Ссылка
  5. Re-Evaluating EVMBench: Are AI Agents Ready for Smart Contract Security?, arXiv, 2026. Ссылка

Get Started with Phalcon Security

Detect every threat, alert what matters, and block attacks.

Try now for free

О компании BlockSec

BlockSec — поставщик комплексных решений в области безопасности блокчейна и криптовалютного соответствия нормативным требованиям. Мы создаём продукты и услуги, помогающие клиентам проводить аудит кода (включая смарт-контракты, блокчейн и кошельки), перехватывать атаки в режиме реального времени, анализировать инциденты, отслеживать незаконные средства и выполнять обязательства по ПОД/ФТ на протяжении всего жизненного цикла протоколов и платформ.

BlockSec опубликовала множество научных работ по безопасности блокчейна на престижных конференциях, сообщила о нескольких атаках типа «zero-day» на приложения DeFi, предотвратила несколько взломов и спасла более 20 миллионов долларов, а также обеспечила безопасность криптовалют на миллиарды долларов.

Sign up for the latest updates
Потери на сумму около 3,87 млн USD: взломы Autheo Network и UNCX | Еженедельный обзор BlockSec
Security Insights

Потери на сумму около 3,87 млн USD: взломы Autheo Network и UNCX | Еженедельный обзор BlockSec

В этом еженедельном отчёте рассматриваются 3 инцидента безопасности за период 12.10.2026–18.10.2026. Общий оценочный ущерб составил около 3,87 млн USD. Ущерб Autheo Network от компрометации закрытого ключа составил примерно 1,76 млн USD, Qubic Wallet потерял примерно 1,30 млн USD из-за ненадёжной генерации seed, а ошибка учёта в контрактах Smart Token Vesting V2 сети UNCX Network на Ethereum, BNB Chain, Base и Robinhood Chain привела к ущербу примерно в 807 тыс. USD. В подробном анализе инцидента UNCX объясняется, как некорректный расчёт совокупного количества долей смешивал транши вестинга, созданные при разных соотношениях токенов и долей, и позволял выводить из общих пулов больше положенного.

Потеряно около $542 тыс.: эксплуатация уязвимости MakerDaoBot | Еженедельный обзор BlockSec
Security Insights

Потеряно около $542 тыс.: эксплуатация уязвимости MakerDaoBot | Еженедельный обзор BlockSec

В Ethereum за 05–11.10.2026 произошёл 1 инцидент; ущерб — около $542 тыс. Атакующий передал вредоносный адаптер функции MakerDaoBot без контроля доступа. Получив права на балансы MakerDAO, адаптер закрыл 4 аукциона ETH-A, конвертировал 200 ETH-A в WETH; атакующий вывел 200 ETH.

~418 млн $ потеряно: эксплойты Bitget и NEAR Intents | BlockSec Weekly
Security Insights

~418 млн $ потеряно: эксплойты Bitget и NEAR Intents | BlockSec Weekly

Этот отчёт за две недели фиксирует 8 инцидентов с 21 сентября по 4 октября 2026 г., убытки ≈$418,4М в Ethereum, BNB Chain, Solana, Bitcoin, TRON, XRP Ledger, Zcash, Avalanche, NEAR. Разбор: уязвимость продукта безопасности Bitget ($387,5М) и ошибка NEAR Intents ($3,87М).

Best Security Auditor for Web3

Validate design, code, and business logic before launch. Aligned with the highest industry security standards.

BlockSec Audit
Анализ уязвимости Zcash Orchard | Еженедельник BlockSec