📜 [專欄新文章] [ZKP 讀書會] Tornado Cash
✍️ Jerry Ho
📥 歡迎投稿: https://medium.com/taipei-ethereum-meetup #徵技術分享文 #使用心得 #教學文 #medium
Disclaimer: 本人與Tornade Cash專案及其員工無任何利益往來。
Tornado Cash是一個Ethereum上的原生隱私轉帳解決方案,使用zk-SNARK+Merkle Tree的路徑證明作為其核心隱私保護機制。
你知我知,Ethereum上的交易記錄是公開的,這使得任何一個人只要知道你的address,便可以在https://etherscan.io/ 之類的網站上查出有多少人和這個位置進行過交易,你做過什麼消費行為或是交易行為等。
或許這聽來不像是個問題,而想要隱藏自己的交易記錄甚至聽起來反而像是不法分子的銷贓行為。
但試想下開情境:因為我曾經使用ethereum捐款給一個政治不正確的專案/組織,而我在接受dd/kyc/reference check的時候因為我的ethereum address就寫在自己的blog上而被查了個底朝天,因而被拒絕入職/拒絕開戶/拒絕服務。
這並不是一個很遙遠的情境…
Tl;dr
解決交易隱私問題分為兩個層次,Assuming你的目的是讓自己的金錢流向無法被追蹤。
層次一:我的錢「丟進了」Tornado Cash的contract,我要如何在不使用與轉入時同一個address的情況下— 若是同一個address就沒有隱私可言了 — 取出我的錢?contract如何知道我存過錢,餘額還夠,所以現在我來領錢了他讓我領?
層次二:就算層次一成立,我的隱私如何達成?到底有多隱私?到底有多不隱私?
技術上來說(細節下文詳談),層次一使用zero-knowledge的set-membership proof來證明,透過預先在Merkle Tree中「登記」一個自己的entry/leaf,tornado cash稱為note,爾後在提款時提出該leaf之zk proof,來解決這個提款時的認證問題。
層次二則是所謂的藏樹於林。既然轉出和轉入無法被連結在一起,那麼只要使用Tornado Cash的人數夠多,總轉出和總轉入的交易總筆數就會太多,以致無法輕易重新關聯轉入與轉出地址背後的真人。
使用界面
https://tornado.cash/
當然你也可以直接和合約地址互動啦
上圖左方紅框為存入幣種與金額大小,右方紅框為該額度對應之帳戶內有多少顆「樹」。
記得藏樹於林嗎?右方的 Anonymity set 就是告訴你現在森林的規模有多大。數量一大,跑資料分析試圖重新關聯某筆特定存款到某筆特定提款就變得更為困難。
提款界面如上。
值得注意的是,提款時的以上兩個選項(Wallet/Relayer),是在目前Account Abstraction尚未實現時的一個折衷方案。
這裡有個死循環:既然我提款的時候需要支付gas,那麼我的gas從哪裡來?是不是勢必得從交易所或是其他帳號來?簡言之,若是無法直接新建立一個地址然後直接將其作為Tornado Cash提款用,達到的隱私強度就大打折扣。
Relayer就是針對這個問題所設計的。透過付出一些手續費來提供社群架設relayer node的誘因,提款時該筆轉帳的gas費用,便可以讓relayer node來負責先出。relayer node收到使用者的zk proof後將其轉交給tornado cash的合約,合約就會會將應有的relayer手續費與扣除手續費+gas後的款項分別轉給relayer與使用者。
社群治理
Tornado Cash天生是一個比較沒有銅臭味的專案 — 社群治理和funded的味道相當強烈。
透過預先設計好的proxy contract與staking/locking機制,任何一個Tornado Cash的使用者都能夠提出對合約實行的改動建議,並交由社群來投票決定是否要執行該改動。
技術細節可以參照此篇,同時Tornado Cash的第一輪社群治理提案也剛投票過關,回顧可參考此處之討論。
誘因設計
本文作者比較任性不在意錢,請移駕此處閱讀官方如何設計Anonymity Mining來確保以下兩點:
機制能讓使用者願意加入存錢,提供流動性同時也讓樹林變大,增加隱私程度。
產生TORN(ERC20 token)與領取TORN的機制,透過在原本的tornado cash上面再加一層,來避免TORN激勵層錯誤的設計導致下一層之隱私洩漏(激勵層出事不影響核心隱私之意)。
技術細節
首先本文不打算解釋何為zero-knowledge proof,請接受以下描述:
若有一NP statement分類上是satisfiability problem(例:merkle tree中的hash chaining H(H(H(a,b),c),d) ),則我們可以設計出一個arithmetic circuit來確保能夠有效率的產生proof, 有效率的驗證, 無法產生假的且能說服人的proof…且其電路驗證的statement是我們想要的,像是此例中的merkle tree opening.
存款
存款者透過送出C = H(k, r) 以及存入之數額給tornado cash的合約來進行存款的動作。其中k在之後會成為存款者領錢的憑證,稱為nullifier,r則是增加randomness而已,此二值需要記下。此時合約端會將這個C(commitment)丟入Merkle Tree上其中一個空的leaf,並更新root hash。存款者還需要記下自己的C對應之leaf index。
產生proof,用此proof作為提款憑證
用一段話來概括,若是我
知道Merkle Tree上某個leaf的commitment的preimage, 代表我能在電路中證明我知道H(k, r) 中的 k, r, 同時不洩漏k, r到底是多少(zk特性, magic)。
我知道該leaf至root的路徑上會經過哪些點,我也提供了一個可以讓電路驗證root hash的hash chaining過程,代表我知道他是從哪個leaf開始走的。因而,這證明了我提出的1.中的commitment確實屬於某顆公開的、大家都知道的merkle tree中的特定leaf(就是我之前存款對應到的leaf)。
就可以在不需要提供像是原本存款地址的簽章之類的驗證機制情況下,透過zk proof,亦能正確做permission control讓unlinkable的提款能夠成真。
另,讀者可以看到在proof中已然預設了relayer的存在。這使得上開所提到之「使用者提款, 拜託relayer執行=>relayer預付gas發起transaction,將內容送給tornado cash合約=>合約處理proof並將款項拆成兩份給relayer與使用者」這個行為得以成立,且relayer無法得知或假造proof內容。
提款流程
基本上在上方的產生證明都講過一次了,這邊就是pseudo code順過一次提款流程而已,大家自己看啊。
值得一提的是,使用者除了需要提出上一部分提到的證明之外,還需要將k的部分額外拿出來再做一次H(k),將值一併傳給contract。
這裡的設計哲學,簡單來講是這樣的:zero-knowledge太強了,強到就算證明了我知道H(k, r)的k跟r, 收到的驗證者並沒有辦法知道H(k)是什麼東西。為了讓同一筆款項不會被提領兩次,在提款流程中合約會將「每一筆成功提款中的H(k)」記錄下來,另外開個表存著。爾後若是其他提款交易中的H(k)與表中的重複了,這就代表有人試圖想要騙合約重複提款,自然該提款嘗試就不會成立。
洗錢失敗例
工程師都知道使用者從來不看說明書,看了可能也不會懂。
Koh Wei Jie分析了Kucoin的駭客事件。Kucoin的駭客使用Tornado Cash來洗錢,但忽略了Tornado Cash官方一直三令五申的使用需知,因而讓款項在進入Tornado Cash跑了一輪之後還是能夠被追蹤,哈哈UCCU。
簡單來說,hacker為了節省多次使用relayer的手續費,而將大多數的提領過程都變成直接提領到wallet。雖然該wallet的位置是全新產生的沒有gas,但是透過只讓第一次的提款使用relayer,hacker便能從第一次提款中取得手續費並分發給其他全新產生的wallet address。
那問題在哪?還要問?
要達到隱私需要保持藏樹於林原則,同時使用者不應自己破壞tornado cash幫你達成的address unlinkability。這位hacker因為愛省手續費,所以違背了後者;同時他因為太心急又愛省手續費,太快、分太少次提領、每次提領的數額又太大了,所以side-channel去給他做簡單的traffic analysis就能夠用虛無假設推出:「綜觀歷史上所有的存款位置與數額,扣掉駭客存錢的那些位址之後,我們還需要14個unique address/user共謀,才能有能力一次提這麼多錢。」
這看起來可能嗎?自然是不可能的。
所以這位駭客就是錯誤的沒有遵守藏樹於林的原則,才導致自己的金流重新被和帳號聯繫在一起。
提供一些延伸閱讀,圈子內的”名人”對這種不看說明書的使用者的看法:
tornado * Gavin Andresen
如何避免洗錢失敗
我自己的投影片,我自己翻譯:
打開你的VPN 打開你的TOR 打開你的無痕瀏覽器分頁 用上你全新的VM PC VPS instance 最好連data-link layer安全都顧到 產生全新的地址不要懶惰 自己跑一個fullnode 乖乖用relayer付手續費提款 領錢之後記得把C(k,r)的記錄刪掉 不要急一次存或提領大額 時間拉長數目減少…..
簡而言之:要設計相對安全但又讓使用者可以直覺上手的安全系統真的很他媽難 - 使用者永遠會想辦法抄近路,然後系統的security assumption就爆炸了。
結論上來講,你想要多安全取決於你在臺大水源校區的腳踏車平常都上幾個大鎖=想付出多少成本。只要不要學Kucoin Hacker那樣連鎖都不鎖車還是新的,大部分時間都沒啥問題 lol。
參考資料與文中出現過的連結,不按先後順序:
https://tornado.cash/Tornado.cash_whitepaper_v1.4.pdf
https://tornado.cash/audits/TornadoCash_cryptographic_review_ABDK.pdf
https://tornado.cash/audits/TornadoCash_circuit_audit_ABDK.pdf
https://torn.community/t/whats-next-for-tornado-cash-governance/250
https://weijiek.medium.com/deanonymising-the-kucoin-hacker-418fa5e9911d
https://tornado-cash.medium.com/tornado-cash-governance-proposal-a55c5c7d0703#2084
https://eips.ethereum.org/EIPS/eip-2938
http://gavinandresen.ninja/private-thoughts
[ZKP 讀書會] Tornado Cash was originally published in Taipei Ethereum Meetup on Medium, where people are continuing the conversation by highlighting and responding to this story.
👏 歡迎轉載分享鼓掌
同時也有2部Youtube影片,追蹤數超過2萬的網紅奮game王紫楓,也在其Youtube影片中提到,#軟體工程師 👍歡迎訂閱!! 🔔🔔按下小鈴鐺,就可以一有新影片就搶先看! [軟體工程師雜談]來寫寫你的第一支程式Hello World吧,安裝JDK環境IDE? NONONO | IT鐵人賽: 從零開始搞懂寫程式,資工系4年最重要的學科,資料結構,演算法,物件導向 寫個Hello world還...
「pseudo code c」的推薦目錄:
- 關於pseudo code c 在 Taipei Ethereum Meetup Facebook 的最佳解答
- 關於pseudo code c 在 軟體開發學習資訊分享 Facebook 的最佳解答
- 關於pseudo code c 在 Johntool-工具王阿璋 Facebook 的最佳貼文
- 關於pseudo code c 在 奮game王紫楓 Youtube 的精選貼文
- 關於pseudo code c 在 奮game王紫楓 Youtube 的精選貼文
- 關於pseudo code c 在 Translating C programming into pseudocode - Stack Overflow 的評價
- 關於pseudo code c 在 C: Pseudo-code example - gists · GitHub 的評價
- 關於pseudo code c 在 Gsoc 2018 Radeco Pseudo C Code Generation 的評價
- 關於pseudo code c 在 How to translate IDA pseudocode to C/C++ code? - Reverse ... 的評價
pseudo code c 在 軟體開發學習資訊分享 Facebook 的最佳解答
記憶體洩漏( Memory leaks ) 和迷途指標( dangling pointers )是手動記憶體管理的主要問題。 你在連結串列中刪除了父節點,卻忘了先刪除它的所有子節點ーー你的記憶體正在洩漏。 你以正確的順序刪除一個物件鏈ー但是突然你的程式崩潰了,因此你忘記了這個資源的第二個所有者,這個資源現在試圖取消參考( dereference ) 一個空指標( null-pointer )。
為了避免這些問題,大多數現代高階程式語言實現了自動記憶體管理。 你可以手動分配物件的記憶體,但是不必擔心它們的釋放: 一個特殊的程式,垃圾收集器,知道如何正確地自動釋放物件,並回收它們以供將來重複使用。
在“垃圾收集器必備基礎”課程中,我們學習了與自動記憶體管理相關的所有不同的技術和演算法,這些技術和演算法現在已經在實踐中得到了應用。
✅這門課是給誰上的?
首先,針對編譯器工程師。
在實現程式語言時,很有可能需要實現一個垃圾收集器。 即使最初定位為“記憶體安全”的語言,如 Rust,最終也實現了自動參考計數(ARC)和其它收集器。
重申一下: 在大多數現代高階程式語言中,垃圾收集器模組(或多個 GC 模組,比如 Java)現在基本上是必需的。
如果實現程式語言不是我每天的工作?
如果你不是一個編譯器工程師,那麼這個課程對你來說仍然是有趣的。 總的來說,實現垃圾收集器或記憶體管理器是一項相當高階的工程任務。 這是一個簡單的技巧: 你參與一些複雜的專案(如垃圾收集器、編譯器、直譯器等) ,在構建它時,你將學習所有不同的資料結構和演算法。 然後回到“每日程式設計” ,得到能力上的提升以成為一個更好的工程師,掌握了複雜系統的可轉移通用知識。
✅這個專案我需要熟悉 C 還是 C++ ?
也不盡然! 當然,C 和 C++ 可能是最適合原始記憶體操作的語言,並且在這裡非常適合,但是在課程中我們學習通用設計演算法,主要關注垃圾收集器和記憶體分配器的理論方面。 這意味著你可以用任何你想要的語言來實現它們。 例如,你可以在 JavaScript 中為一個虛擬 Heap 分配一個 ArrayBuffer,或者類似的在 Python、 Rust 等中分配一個 bytearray。
本課程中的大多數演算法都是用泛型虛擬碼( generic pseudo-code )描述的,因此你可以將它們移植到任何語言中。
https://softnshare.com/essentials-of-garbage-collectors/
pseudo code c 在 Johntool-工具王阿璋 Facebook 的最佳貼文
【#程式教學】新手快收藏!5個C語言小技巧
知道你們最想學C語言,但是卻苦無好技巧,來來來,看這就對了🙋♂️!
我幫大家整理好5個C語言小技巧㊙,新手一定要趕快收藏!
技巧1️⃣ 盡量不使用「goto」語句
二十幾年前,當計算機編程尚處於起步階段時,程序流程是由「goto」語句來控制。
這類語句允許程式設計師對當前代碼行斷行,而直接進入另一個不同的代碼段。但以現今的結構而言,用 for(; ;)或while來代替goto會更好,最主要的好處就是「方便維護」。
goto 使用太多會讓程式的可讀性降低,維護起來也比較困難。當然不是說 goto 不好,而是要「用的巧」,如果能夠適當的使用 goto 也非常棒,但難度較高😎。
技巧2️⃣ 使用合適的條件語句⭕️
除了代碼的可讀性之外,程序的執行時間,主要依賴於做決定選擇的條件結構類型。
許多硬體工程師都熟悉簡單的 if 語句的使用。然而,有時工程師可能沒有意識到,如果第一個條件不正確,還可以使用 else 或 else if 語句。這可以節省處理器時間,而不必評估另一個條件語句。
技巧3️⃣ 充分利用模組化⭕️
不要將所有的程式碼都寫在一個 main 裡面,這是新手常犯的錯誤。C 語言的設計就是可以將各個不一樣的功能模組化,寫成 function,呼叫的時候可以重複利用,如果全部程式都寫在一個 main,一定會發現許多地方都是重複的功能,這時候適當的將這些地方搬出來自成一個 function 吧!
技巧4️⃣ 錯誤沒有那麼簡單❌❌❌
在編譯 C 語言的時候,有一個讓人當心的陷阱就是「編譯器」錯誤。
由於編譯器的複雜性,當檢測到一個錯誤時,很可能錯誤位於程式中的其它地方,而非編譯器所指示的位置。這主要與編譯器生成程序的步驟有關。
下面列出幾點新手常犯的錯誤🙅♂️🚫:
•當心漏掉 #include 文件:有時候看見一些 function 錯誤,其實並不是 function 用錯,而是沒有在開頭 include 相關的來源。
•當心漏掉分號:寫程式時,最常見的錯誤是忘記在句末加分號。
•當心漏掉括號:漏寫括號是程式編寫過程中又一常犯的錯誤,或是粗心漏掉,或是由於鍵入錯誤而產生一個錯誤字符,善用一個好的 IDE 可以更方便的查看括號是否成雙成對。
•當心漏掉逗號:在複雜的定義中很容易忘記逗號!
•選擇良好的編譯環境:C 語言版本有沒有正確、IDE 會不會太雷等等,有時候環境配置的影響更重大。
一般情況下,彈出一個奇怪的編譯錯誤對話框的時候,要查看該行前已被編譯的內容。很有可能就是錯誤所在! 但也可能是出現在與該行完全不同的地方。
千萬不要放棄!只要具備一定的經驗,解決這些疑難問題就會成為一塊小蛋糕🍰。
技巧5️⃣ 寫程式先定義好規格⭕️
寫程式前先定義好規格,這才是良好的習慣,先定義好所有要用的 function 以及清晰明瞭的註解,從 Pseudo Code 開始寫到詳細的內容,會大幅減少開發時間,一開始磨練的時候肯定比較痛苦,但到了後期就會發現超越了許多人✌✌✌。
想知道更多?
【歡迎追蹤Johntool-工具王阿璋 @johntooltw ↓↓↓】
facebook► https://www.facebook.com/JohntoolTW/
instagram► https://www.instagram.com/johntooltw/
收到更多 #程式教學 #不務正業工程師 系列!
#程式 #程式語言 #程式入門 #engineer #engineering
#學習 #study #coding #code #程式設計 #program #programming #programminglanguage
#技巧 #skill #tip #程式語言技巧 #懶人包 #程式教學
#分享
pseudo code c 在 奮game王紫楓 Youtube 的精選貼文
#軟體工程師
👍歡迎訂閱!! 🔔🔔按下小鈴鐺,就可以一有新影片就搶先看!
[軟體工程師雜談]來寫寫你的第一支程式Hello World吧,安裝JDK環境IDE? NONONO | IT鐵人賽: 從零開始搞懂寫程式,資工系4年最重要的學科,資料結構,演算法,物件導向
寫個Hello world還要安裝一堆東西
太累啦!!!
來~~最懶人包的方法,8分鐘寫5種程式語言(C, C++, Java, python, kotlin)的Hello world
IT鐵人賽網址:https://ithelp.ithome.com.tw/users/20128489/ironman/3093
紫楓FB專頁: https://www.facebook.com/tbpfs2/
紫楓blog: https://tbpfs1.blogspot.com/
斗內專線: https://pse.is/KUYMP

pseudo code c 在 奮game王紫楓 Youtube 的精選貼文
#軟體工程師
👍歡迎訂閱!! 🔔🔔按下小鈴鐺,就可以一有新影片就搶先看!
[軟體工程師雜談] 這麼多種程式語言,新手要學什麼語言比較好? Java? Python? C++? JS?都不是!!| IT鐵人賽: 從零開始搞懂寫程式,資工系4年最重要的學科,資料結構,演算法,物件導向
💻 入門最推薦的程式語言,新手必看!
💻 最夯的程式語言
💻 C++ 對決 Python,還是 Java, javascript?
💻 物件導向?
程式語言入門須知 新手該學哪個程式語言
| What you should know about programming languages
大家好:
我是紫楓,之前曾經在巴哈姆特發表一個關於軟體工程師,問都給問的文
其中有很多個問題是關於
我是學生,我該學什麼?
我想轉職,我該學什麼?
我想精益求精,我該學什麼?
這類的問題,那歸根究柢,就是目前的軟體工程師中,很多人的基本功不足,所以對學習,對找工作會非常迷惘
所以我打算開設這一個最基本功的鐵人賽主題,幫助基本功沒練好,或是想轉職當軟體工程師的人。
而所謂的基本功,便是資料結構,演算法,物件導向
當然,這一系列可能對已經身經百戰的強者們來說,實在太淺了。
那也歡迎強者們對我的影片做個批評指教。
如果你覺得我的影片做得不錯,也會非常感謝你給個讚或訂閱。
這是對我而言最大的鼓勵
IT鐵人賽網址:https://ithelp.ithome.com.tw/users/20128489/ironman/3093
紫楓FB專頁: https://www.facebook.com/tbpfs2/
紫楓blog: https://tbpfs1.blogspot.com/
斗內專線: https://pse.is/KUYMP

pseudo code c 在 C: Pseudo-code example - gists · GitHub 的推薦與評價
C : Pseudo-code example. GitHub Gist: instantly share code, notes, and snippets. ... <看更多>
pseudo code c 在 Gsoc 2018 Radeco Pseudo C Code Generation 的推薦與評價
This summer, I was working on C-like pseudocode generation with radeco. Althrough radeco was able to analyze executables, it could not decompile ... ... <看更多>
pseudo code c 在 Translating C programming into pseudocode - Stack Overflow 的推薦與評價
... <看更多>