Zero knowledge cũng có điểm mù.
Tôi vẫn nhớ cái ngày năm 2017, khi tôi – một phụ nữ 35 tuổi, duy nhất trong phòng họp đầy những kỹ sư trẻ – phát hiện ra lỗi trong mã nguồn của 0x Protocol v2. Đó là một lỗi tràn calldata tưởng chừng như vô hại, nhưng nó đã cho tôi một bài học nhớ đời: không có hệ thống nào là hoàn hảo, kể cả những hệ thống được cho là an toàn nhất.
Bảy năm sau, tôi đã audit Uniswap v2, phân tích OpenZeppelin cho NFT, và đào sâu vào zk-SNARKs trong thị trường gấu năm 2022. Tôi đã thấy những điểm mù lặp đi lặp lại. Và gần đây nhất, trong một audit cho Aztec Protocol, tôi lại một lần nữa chạm vào ranh giới mong manh giữa lý thuyết và thực tế.
Bài viết này không phải để nói rằng zero-knowledge proofs (ZK) là xấu. Nó là một trong những công nghệ đẹp nhất mà tôi từng nghiên cứu. Nhưng như một INTP, tôi thích tháo gỡ hệ thống. Và tôi muốn chỉ ra một điểm mù mà hầu hết mọi người đều bỏ qua: cơ chế chứng minh và xác minh trong ZK không phải lúc nào cũng hoạt động như lý thuyết.
Hãy bắt đầu với một ví dụ đơn giản. Trong một hệ thống ZK, một prover muốn thuyết phục một verifier rằng một tuyên bố là đúng, mà không tiết lộ bất kỳ thông tin nào ngoài tuyên bố đó. Nghe có vẻ an toàn tuyệt đối. Nhưng hãy nhìn vào thực tế: khi tôi audit Uniswap v2, tôi đã phát hiện ra rằng oracle giá có thể bị thao túng thông qua thanh khoản thấp. Điều này cho thấy một sự thật phản trực giác: an ninh ở cấp độ giao thức không đảm bảo an ninh ở cấp độ ứng dụng. Bạn có thể có một ZK-proof hoàn hảo, nhưng nếu dữ liệu đầu vào bị nhiễm độc, thì proof đó cũng vô dụng.
Điều này dẫn tôi đến một khám phá counter-intuitive khác: sự phức tạp của ZK proofs có thể tạo ra một ảo tưởng về an toàn. Trong một dự án tôi audit gần đây, nhóm phát triển rất tự tin về thiết kế ZK của họ. Họ đã dành hàng tháng trời để tối ưu hóa vòng Galois và giảm thời gian tạo proof. Nhưng khi tôi đào sâu vào mã nguồn, tôi thấy rằng họ đã quên mất một điều cơ bản: cơ chế khởi tạo (setup) cho ZK proofs là cực kỳ nhạy cảm. Nếu trusted setup bị xâm phạm, toàn bộ hệ thống sẽ sụp đổ. Đây không phải là một lỗi trong giao thức; đó là một điểm mù trong văn hóa phát triển.
Tôi nhớ lại bài học từ 0x v2. Đó là một lỗi đơn giản, nhưng nó đã dạy tôi rằng bảo mật không phải là một tính năng, mà là một quy trình. Khi tôi phân tích Aztec vào năm 2025, tôi thấy cùng một vấn đề: nhóm phát triển quá tập trung vào hiệu suất, họ quên mất những nguyên tắc cơ bản. Họ đã tối ưu hóa quá mức cho vòng Galois, nhưng lại bỏ qua việc kiểm tra các kịch bản tấn công cơ bản như tấn công reentrancy trong metadata extension của ERC-721 mà tôi đã phát hiện năm 2021. Một lỗ hổng không bao giờ biến mất; nó chỉ thay đổi hình dạng.
Vậy làm thế nào để tránh những điểm mù này? Đầu tiên, chúng ta cần kiểm tra mã nguồn như thể chúng ta là kẻ tấn công. Đừng tin vào bất kỳ tuyên bố an toàn nào. Hãy đọc từng dòng code, từng dòng logic, và đặt câu hỏi về từng giả định. Thứ hai, chúng ta cần kết hợp lý thuyết với thực tế. Lý thuyết ZK rất đẹp, nhưng nó chỉ là một phần của câu chuyện. Bạn cần test mã nguồn của mình trong các điều kiện thực tế, với dữ liệu nhiễu, với tấn công, với các kịch bản biên. Cuối cùng, chúng ta cần xây dựng một văn hóa khiêm tốn trong phát triển.
Tôi đã nhìn thấy điều này trong các dự án thành công nhất mà tôi từng làm việc. Họ không bao giờ nói "chúng tôi đã sử dụng ZK, vì vậy chúng tôi an toàn." Thay vào đó, họ nói "chúng tôi đã sử dụng ZK, nhưng chúng tôi cần kiểm tra lại từng bước." Đó là sự khác biệt giữa một dự án tồn tại và một dự án thất bại thảm hại.
0x v2 lỗi – bài học nhớ mãi.
Tôi không có câu trả lời hoàn hảo. Tôi chỉ có một câu hỏi: bạn có sẵn sàng đào sâu vào mã nguồn và đối mặt với những điểm mù của chính mình không?