Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Ethereum Moscow | Обзор приватных протоколов (R...

Avatar for DeFrens community DeFrens community
December 26, 2025
4

Ethereum Moscow | Обзор приватных протоколов (Railgun, Privacy Pools и др.)

Спикер: Расул Ибрагимов, R&D @ Ethereum Foundation

Avatar for DeFrens community

DeFrens community

December 26, 2025
Tweet

More Decks by DeFrens community

Transcript

  1. Railgun • Railgun – открытая инфраструктура для приватности для EVM

    чейнов (live on Ethereum, Arbitrum, BSC). • DAO-owned/created протокол. Управляется держателями токена $RAIL. • Не предоставляет кошельки / dapp для взаимодействия с инфраструктурой “из коробки”. Кошельки создаются комьюнити; наиболее популярный – Railway Wallet. Др. пример – Kohaku SDK
  2. Railgun // Протокол • Для обеспечения приватности используются zkSnarks, а

    именно Groth16. • Основной протокол состоит из 2 частей: zk circuits и смарт-контракт. Отдельная важная часть протокола – Private Proof Of Innocence (PPOI). • Позволяет переводы любых сумм, благодаря использованию “приватной” UTXO модели, чем отличается, например, от Tornado Cash и Privacy Pools, которые позволяют только депозит / вывод фиксированных сумм. • Позволяет использовать “Private” Dapp (в тч. Defi), благодаря системе адаптеров.
  3. Railgun // Ключи Для использования системы необходима генерация ключей: •

    SpendingKey – пара ключей (PrivateSpendingKey и PublicSpendingKey) на BabyJubJub. SpendingKey нужен для трат/использования UTXO, а также для вычисления MasterPublicKey. • ViewingKey – пара ключей (PrivateViewingKey позволяет видеть все UTXO принадлежащие данному владельцу; PublicViewingKey нужен для ECDH / получения токенов). Используется Ed25519. • “0zk” адрес – комбинация pvk + mpk
  4. Railgun // UTXO Структура UTXO: { npk // Note Public

    Key value // Сумма доступная для траты token // Адрес Токена (или айди токена в системе) } • Commitment = Poseidon(npk, value, token) • Nullifier = Poseidon(nullifyingKey, leafIndex), nullifyingKey = poseidon(VK)
  5. Railgun // Криптография • Ядро Railgun – zk circuit joinsplit.circom,

    основной серкут, проверяющий “UTXO-транзакцию”, генерирует nullifier и тд. > template JoinSplit(nInputs, nOutputs, MerkleTreeDepth) { … } • Публичные входы: merkleRoot, boundParamHash, nullifiers[nInputs], commitmentsOut[nOutputs] • Приватные входы: token, publicKey, signature, randomIn, valueIn, pathElements, leavesIndices, nullifyingKey, npkOut[nOutputs], valueOut[nOutputs]
  6. Railgun // JoinSplit.circom 1. Вычисляет hash публичных входов (messageHash). Это

    значение подписано PrivateSpendingKey. 2. Верификация EdDSA 3. Верификация nullifier’ов 4. Вычисление master public key (Poseidon(PublicSpendingKey, nullifyingKey)) 5. Вычисление npk (Poseidon(mpk, random)) 6. UTXO Merkle Proof 7. Верификация OutputCommitments (UTXO получателя) 8. Верификация корректности балансов
  7. Railgun // Флоу 1. Отправитель в кошельке выбирает входные UTXO,

    строит Merkle‑пути к текущему/историческому merkleRoot, считает nullifiers для входов. 2. Из “0zk‑адреса” получателя берёт его pvk + mpk 3. Создаёт выходные ноты (UTXO) — random/value/token для получателя и сдачи, считает commitmentsOut 4. Шифрует payload выходных нот под получателя (ECDH → shared key → AES‑GCM), формирует ciphertext (публикуемый в событии) 5. Генерация пруфа JoinSplit.circom 6. Отправка транзакции + эмит события Transact() с ciphertext 7. Получатель может “расшифровать” ноту своим PrivateViewingKey и в дальнейшем использовать ее
  8. Railgun // Дополнение Структура “шифрованной” ноты при эмите ивента Transact():

    • CommitmentCiphertext { bytes32[4] ciphertext, bytes32 blindedSenderViewingKey, bytes32 blindedReceiverViewingKey } — • Серкуты оптимизированы – всего сгенерировано 54 серкута JoinSplit, с различными константами nInputs и nOutputs; при этом глубина дерева всегда 16 • Каждая транзакция обновляет root, поэтому для избежания Race Condition в пруфе разрешается использовать любой root из RootHistory для данного treeNumber • TVL ~ 99м$ (52% ETH, 22% USDT, 11% USDC, 8% DAI …)
  9. Railgun // PPOI PPOI – дополнительный оффчейн слой “assurance/комплаенса” поверх

    Railgun, который доказывает, что средства не связаны с известными плохими источниками (по наборам List Providers), не раскрывая 0zk‑адрес, баланс и приватную историю. • List Providers: Elliptic, ScanSniffer, PureFi, SlowMist, Chainalysis • кошелёк/PPoI‑инфраструктура строит и публикует POI‑статус (blinded данные) → broadcaster/биржа проверяют PPOI и только потом обслуживают (ретранслируют / принимают депозит) • Railgun даёт приватность, PPOI добавляет проверяемую “чистоту происхождения” как опциональный оффчейн допуск к сервисам (broadcaster/CEX), не ломая приватность
  10. Privacy Pools Privacy Pools — это развитие идей Tornado Cash

    (пул с депозитами/выводами фиксированных сумм) с отдельным способом доказательства “добропорядочности” (комплаенса). • Помимо общего Merkle дерева всех коммитментов, существует AST (Association Set Tree) данного ASP (провайдера). Для вывода средств из пула нужно доказать включение в AST. Провайдер включает депозит в AST на свое усмотрение • Используется структура LeanIMT – отсутствие “нулевых” хэшей, динамическая глубина; более эффективно он-чейн.
  11. Stealth Addresses Stealth-адреса — это механизм конфиденциальности, который позволяет отправителю

    создавать неограниченное количество уникальных одноразовых адресов для получателя на основе его публичного ключа, так, что: • Связь между этим адресом и реальным владельцем видна только участникам транзакции • Только “законный” получатель может вычислить приватный ключ для управления средствами на этом адресе
  12. Stealth Addresses // Пример Получатель (Боб): sk, Pk – регистрирует

    Pk как мета-адрес в ens Для получения ETH Боб сканирует все R, и генерирует A’ . Если получилось сгенерировать корректный A, – Боб на основе sk генерирует sk для данного A. gen_addr(r, Pk) = gen_addr(R, sk) Отправитель (Алиса) хочет приватно отправить ETH Бобу: • Находит Pk Боба • Генерирует эфемерный ключ r • Генерирует адрес получения и публичный эфемерный ключ: ◦ A = gen_addr(r, Pk) ◦ R = gen_ephem_pk(r) • Публикует R • Отправляет ETH на A
  13. Stealth Addresses • Алиса вычисляет Shared Secret S = Pk

    * r = sk * G * r • Боб вычисляет Shared Secret S = sk * R = sk * r * G • Сгенерированный пуб. ключ/адрес: A = Pk + G * hash(S) • Приватный ключ для данного адреса: a = sk + hash(S). Только Боб может его вычислить На практике ключ Боба – пара (K, V), где k – это spending key, а v – это viewing key • Для более эффективного сканирования также публикуется view_tag = первому байту S. Это делает сканирование в 256 раз эффективнее. Существует стандарт Stealth адресов ERC-5564
  14. Stealth Addresses // Fluidkey Fluidkey – проект, реализующий механизм Stealth-адресов.

    • Криптографически следует ERC-5564 • Нет ERC-5564 он-чейн скана событий • Viewing Key делегируется приложению/разработчикам • Для резолва мета-адресов используется off-chain resolver Fluidkey • Каждый стелс-адрес фактически является Safe смарт-контрактом, управляемым одним и тем ключом (Spending Key), который есть только у пользователя: Self-Custodial, но Data-Trusted! Fluidkey – это bank-like проект/продукт с удобным UX, но не обеспечивает полную приватность
  15. Stealth Addresses // Curvy.box Curvy.box – альтернативный Stealth-адрес протокол. •

    Не совместим с ERC-5564 • Использует пэйринги (Bn254) для вычисления Shared Secret: ◦ благодаря разделению значений (отдельно для вывода Shared Secret, отдельно для деривации адреса) можно сделать скан еще более эффективным, безопасно открыв еще несколько байт для view_tag • Нет удобного UX, как у fluidkey, но при этом Trustless Curvy.box, в отличие от fluidkey – это полностью Trustless протокол + SDK