Lỗ hổng range proof trong token hóa tài sản thực: Khi ZK không phải là phép màu
Dương Vĩnh
Tháng 3/2025, tôi nhận một hợp đồng audit cho giao thức token hóa trái phiếu chính phủ trị giá 50 triệu USD. Khách hàng là một quỹ đầu tư tổ chức lớn, họ tự hào về việc sử dụng zk-SNARKs để bảo vệ quyền riêng tư cho các giao dịch. Tôi mở hợp đồng thông minh, nhìn vào tham số đường cong – và một nỗi lo quen thuộc dâng lên. Có thứ gì đó không ổn với range proof.
Bối cảnh: Token hóa tài sản thực (RWA) đang là xu hướng nóng trong thị trường giảm. Các tổ chức tài chính truyền thống muốn đưa trái phiếu, cổ phiếu lên blockchain, nhưng yêu cầu về quyền riêng tư là bắt buộc. Zero-knowledge proofs (ZK) trở thành giải pháp được ưa chuộng. Giao thức này sử dụng Groth16 – một trong những hệ thống ZK phổ biến nhất – để chứng minh rằng mỗi giao dịch tuân thủ các ràng buộc về số dư và loại tài sản mà không tiết lộ chi tiết.
Core phân tích: Range proof là một phần quan trọng trong bất kỳ giao thức ZK nào xử lý số lượng. Nó đảm bảo rằng giá trị đầu vào nằm trong một khoảng xác định (ví dụ: 0 đến 2^256). Trong hợp đồng của dự án này, họ dùng range proof để kiểm tra rằng số dư sau giao dịch không âm và không vượt quá tổng cung. Tôi đào sâu vào mã nguồn của thư viện ZK mà họ sử dụng – một bản fork từ circomlib. Ở dòng 247, tôi thấy một hằng số curve parameter được hardcode: bn128 scalar field size là 21888242871839275222246405745257275088548364400416034343698204186575808495617. Họ sử dụng range proof với các bit chunk 64-bit, nhưng trong quá trình tạo proof, họ quên normalize giá trị đầu vào khi nó lớn hơn field size. Điều này có nghĩa là nếu một người dùng gửi một giá trị âm được wrap-around (ví dụ: field size - 1), range proof vẫn pass vì nó nằm trong khoảng bit, nhưng khi ánh xạ vào số nguyên, nó trở thành số âm. Tôi mất ba ngày để xây dựng một proof khai thác: với một số dư 100 token, tôi có thể tạo một giao dịch chuyển 200 token ra ngoài bằng cách sử dụng số âm, và range proof không phát hiện. Khoảng 2% giao dịch có thể bị rò rỉ thông tin hoặc thao túng số dư.
Contrarian angle: Điểm mù ở đây không phải là logic kinh doanh hay kiểm soát truy cập – những thứ mà hầu hết auditor DeFi tập trung vào. Vấn đề nằm ở mật mã học thuần túy: việc chọn tham số đường cong và xử lý wrap-around trong số học modulo. Cộng đồng bảo mật thường ca ngợi ZK như một 'phép màu' bảo vệ quyền riêng tư, nhưng thực tế, các implementation ZK đầy rẫy lỗi cấp thấp mà chỉ những người hiểu sâu lý thuyết số mới phát hiện. Trong audit, tôi nhận thấy các đội ngũ phát triển RWA thường đến từ tài chính truyền thống, họ thuê các chuyên gia ZK từ các trường đại học để viết circuit, nhưng không ai kiểm tra kỹ các tham số thư viện cơ bản. Họ nghĩ rằng 'zk-SNARKs là chuẩn mực', nhưng chuẩn mực cũng có lỗi.
Takeaway: Lỗ hổng trong range proof không chỉ là một bug kỹ thuật – nó đặt ra câu hỏi về sự sẵn sàng của toàn bộ hệ sinh thái RWA. Nếu một giao thức trị giá 50 triệu USD mắc lỗi cơ bản như vậy, thì các giao thức nhỏ hơn sẽ thế nào? Khi thị trường giảm, các tổ chức lớn đổ xô vào token hóa tài sản thực, nhưng liệu họ có thực sự hiểu rủi ro toán học ẩn sau những 'bằng chứng không kiến thức'? Tôi không có câu trả lời. Chỉ biết rằng, trong audit tiếp theo, tôi sẽ dành nhiều thời gian hơn cho thư viện ZK thay vì logic kinh doanh. Và bạn – nếu đang hold token của một giao thức RWA – hãy hỏi đội ngũ của họ: 'Ai đã audit circuit ZK của bạn?'
Bài học từ kinh nghiệm: Cách đây ba năm, khi audit một bản fork Uniswap, tôi học được rằng whitepaper không bao giờ trùng khớp với code. Bây giờ, tôi biết thêm: ZK không phải là phép màu – nó là một lớp phức tạp mới mà nếu không cẩn thận, có thể biến tài sản của bạn thành con số trên một modulo field.