
雙模式重鑄:一種在保留代幣可組合性的同時緩解 EIP-7503 生日攻擊的方案
本文為 ZWToken 提出了一種雙模式重鑄機制,透過引入匿名上限以及針對大額轉帳的揭露模式,來緩解 EIP-7503 中 160 位元生日攻擊的風險,並同時確保代幣在 DeFi 中的可組合性。
1. 問題陳述
1.1 背景
EIP-7503 (零知識蟲洞) 提出了一種圍繞燃燒地址(burn addresses)構建的鏈上隱私設計。ERC-8065 (零知識代幣包裝器) 定義了一個包裝器,為現有代幣添加 EIP-7503 風格的隱私功能。ZWToken 是 ERC-8065 的完整實現,支持 ERC-20、原生 ETH、ERC-721 和 ERC-1155。
作為 ERC-8065 的實現,ZWToken 繼承了 EIP-7503 中提出但未解決的核心安全問題——160 位元生日攻擊。本文檔說明了該問題以及 ZWToken 的緩解方案。
1.2 燃燒地址隱私流程
EIP-7503 的核心流程為:
-
用戶從一個秘密(secret)推導出一個燃燒地址(隱私地址)
-
代幣被發送到該地址(存入承諾)
-
通過證明其知曉秘密的 ZK 證明,用戶在另一個地址**重新鑄造(remint)**等量的代幣
此流程中的隱私依賴於:沒有人能將燃燒地址與接收地址關聯起來。
1.3 攻擊向量
以太坊地址為 160 位元。燃燒地址的推導方式如下:
addrScalar = Poseidon(8065, tokenId, secret) // ~254 位元
addr20 = addrScalar mod 2^160 // 截斷至 160 位元
生日攻擊可以在 2^80 次操作中找到碰撞。攻擊者並行搜索兩個空間;根據生日悖論,約 2^80 次嘗試足以找到一對匹配項:
向量 1:重複鑄造(兩個秘密碰撞到同一個地址)
Poseidon(8065, 0, secret_A) mod 2^160 == Poseidon(8065, 0, secret_B) mod 2^160
攻擊者使用 secret_A 和 secret_B 產生不同的無效符(nullifiers),並針對同一個承諾進行兩次重新鑄造。
向量 2:CREATE2 碰撞
Poseidon(8065, 0, secret) mod 2^160 == CREATE2(deployer, salt, codehash)
攻擊者利用 CREATE2 控制燃燒地址:他們可以直接提取代幣,同時也能通過 ZK 證明重新鑄造。
向量 3:EOA 私鑰碰撞
Poseidon(8065, 0, secret) mod 2^160 == keccak256(publicKey)[12:32]
攻擊者同時搜索秘密和 ECDSA 金鑰;一旦發生碰撞,他們便持有該燃燒地址的私鑰,並可以簽名轉出資金。
1.4 嚴重性
指標
數值
攻擊複雜度
2^80 次雜湊操作
128 位元安全性
2^128 次操作
差距
未達到 128 位元安全性
粗略成本估算
數百億美元的硬體成本(目前)
影響
協議通膨;資金池可能被掏空
雖然目前在經濟上不可行,但風險隨著硬體和 ASIC 優化而增加。
2. 先前技術
2.1 EIP-7503 工作量證明 (PoW)
在 ZK 電路中加入 PoW 限制:
Poseidon(MAGIC_POW, secret) mod 2^POW_BITS == 0
秘密必須滿足 PoW 條件,從而提高尋找有效秘密的成本。
優點:
-
對面向用戶的流程無改動
-
自然地融入 ZK 電路
缺點:
-
僅改善了常數因子,而非漸近複雜度——攻擊者只需支付 2^POW_BITS 的倍數成本
-
證明生成時間顯著增加(用戶在客戶端運行 PoW)
-
行動端體驗較差
-
POW_BITS 難以調整:太低無效,太高則用戶無法接受
2.2 存款上限
限制每次存款/轉帳/重新鑄造的最大金額。
優點:
-
易於實現
-
將每次攻擊的利潤限制在 2^80 生日攻擊的成本之下
缺點:
-
破壞了代幣的兼容性和可組合性——存款、轉帳等不能超過上限,因此 ZWToken(例如具備隱私功能的包裝 ERC-20)無法像標準 ERC-20 一樣與 DeFi(Uniswap、Aave 等)交互
-
限制了合法的巨額轉帳
3. ZWToken 解決方案:雙模式重新鑄造
3.1 核心思路
設置一個低於 2^80 生日攻擊經濟成本的匿名上限(anonymousCap):
-
金額 ≤ anonymousCap:完全匿名模式;行為與之前一致
-
金額 > anonymousCap:揭露模式;用戶必須公佈燃燒地址;合約從該地址燃燒代幣後再進行鑄造
在最壞的情況下,經過約 2^80 的工作量後,攻擊者最多只能竊取 anonymousCap 的金額。如果 anonymousCap 設置低於 2^80 攻擊的估計成本(目前為數百億美元),則不存在理性的經濟動機。大額轉帳被迫通過「從地址燃燒」的路徑,因此通過此向量產生的通膨是不可能的。
與全局存款上限不同,此限制僅適用於重新鑄造;標準的 ERC-20 存款、轉帳和提款不受限制,保留了完整的兼容性和 DeFi 可組合性。UI 會將發往燃燒地址的轉帳限制在 anonymousCap 以內;普通地址之間的轉帳則無限制。
3.2 電路設計
增加一個公開輸入 revealedAddr 和一個二次約束:
signal input revealedAddr; // 0 = 匿名, addr20 = 揭露
// 如果 revealedAddr != 0,則它必須等於 addr20
revealedAddr * (revealedAddr - addr20) === 0;
-
revealedAddr = 0:匿名模式;約束自然成立
-
revealedAddr = addr20:揭露模式;證明 revealedAddr 與電路內的 addr20 匹配
-
revealedAddr = 其他任何值:約束失敗;無法生成證明
成本:增加一個額外約束(13084 → 13085);對證明時間的影響微乎其微。
3.3 合約設計
// BaseZWToken.sol
uint256 public immutable anonymousCap; // 0 = 無上限
function _requireRevealIfNeeded(uint256 amount, address revealedAddr) internal view {
// 金額超過上限需要揭露
if (anonymousCap > 0 && amount > anonymousCap && revealedAddr == address(0)) {
revert RevealRequired();
}
// 揭露的地址帶有代碼 = CREATE2 碰撞攻擊
if (revealedAddr != address(0) && revealedAddr.code.length != 0) {
revert BurnAddressHasCode();
}
}
揭露模式重新鑄造流程(以 ZWERC20 為例):
// 1. 先從燃燒地址燃燒
if (revealedAddr != address(0)) {
_burn(revealedAddr, amount);
}
// 2. 然後進行正常重新鑄造(鑄造給接收者)
_executeRemint(to, id, amount, redeem, relayerFee);
效果:燃燒金額 → 鑄造金額(分配給接收者 + 中繼者 + 協議);總供應量(totalSupply)淨變化為 0。
3.4 EXTCODESIZE 防護
有效的燃燒地址是來自 Poseidon 的隨機地址;它始終是一個 EOA(無字節碼)。如果 revealedAddr 擁有代碼,說明有人通過 CREATE2 碰撞在該處部署了合約——這是攻擊的直接證據。
if (revealedAddr.code.length != 0) revert BurnAddressHasCode();
成本:EXTCODESIZE 操作碼,約 100 gas。
4. 參考資料
-
EIP-3607: Reject transactions from senders with deployed code
-
1 則貼文 - 1 位參與者 [閱讀完整主題](https://ethresear.ch/t/dual-mode-remint-an-eip-7503-birthday-attack-mitigation-that-preserves-token-composability/24566)