Hôm rồi mình đọc được trên facebook của người bạn về thuật toán này. Đây là một thuật mang tên người Việt Nam (theo như chia sẻ của Facebook ấy). Thật đáng tự hào! Trong note này mình cố gắng giải thích một số điểm mấu chốt của thuật toán, hy vọng có thể giúp các bạn dễ dàng hơn khi tìm hiểu nó.
Note này đa số dựa trên bài viết gốc này.
Scenario
Giả sử chúng ta có một thông điệp được xác thực bởi chữ ký điện tử của nhiều người trên blockchain, như vậy để xác thực, chúng ta phải xác thực chữ ký của từng người. Tuy nhiên việc này tốn kém vì mọi tính toán trên sẽ tốn chi phí gas, do đó, thay vì check từng chữ ký, ta sẽ “gộp” tất cả các chữ ký và validate 1 lần cho đỡ tốn (Batch verification).
Review về bilinear mapping / pairing
Lược đồ chữ ký kết hợp trên được thiết lập dựa trên nền tảng chữ ký BLS (Boneh–Lynn–Shacham) mà trung tâm của nó là ánh xạ song tuyến tính / cặp ghép.
Một cặp ghép e:G1×G2→GT là một ánh xạ song tuyến tính giữa các nhóm G1,G2,GT với g1,g2,gT lần lượt là các phần tử sinh. Một cặp ghép song tuyến tính thỏa mãn các điều kiện sau:
Song tuyến tính: Với mọi u∈G1 và v∈G2, luôn có: e(ua,vb)=e(u,v)ab
Không suy biến: e(g1,g2)=1GT
G1,G2,GT có cùng bậc nguyên tố.
Chữ ký BLS
Message m
Cho H:{0,1}∗→G1 là hàm hash biến một giá trị bất kỳ thành một phần tử của nhóm G1.
Secret key sk∈Zp, public key pk=g2sk∈G2
Để tạo chữ ký cho m, ta tính σ=H(m)sk∈G1
Để verify chữ ký, kiểm tra: e(σ,g2)=?e(H(m),pk).
Lý do là vì:
e(σ,g2)e(H(m)sk,g2)e(H(m),g2)ske(H(m),g2)=?e(H(m),pk)⇔=?e(H(m),g2sk)⇔=?e(H(m),g2)sk⇔=e(H(m),g2) Chữ ký kết hợp
Giả sử có n chữ ký σ1,σ2,…,σn∈G2 trên message H(m)∈G1 với các secret key sk1,sk2,…,skn∈Zp và public key tương ứng pk1,pk2,…,pkn∈G2. Ta có thể kết hợp toàn bộ các chữ ký này lại thành một chữ ký tổng hợp σagg và nhờ đó chỉ cần verify chữ ký này một lần duy nhất.
Bước 1: Tạo chữ ký tổng hợp
σagg=i=1∑nσi=i=1∑n(ski⋅H(m))=(i=1∑nski)⋅H(m) Bước 2: Tạo public key tổng hợp
pkagg=i=1∑npki=i=1∑n(ski⋅g)=(i=1∑nski)⋅g Bước 3: Xác thực chữ ký
e(g,σagg)=e(g,(i=1∑nski)⋅H(m))=e((i=1∑nski)⋅g,H(m))=e(pkagg,H(m)) Tấn công Rogue Public Key
Việc kết hợp các chữ ký như trên tuy có lợi ích về mặt tính toán nhưng lại không an toàn vì có thể bị tấn công như sau:
Giả sử một user là Bob, có public key là pk1
Kẻ tấn công sẽ tính pk1−1∈G2, sau đó chọn một public key pk2=g1β⋅(pk1)−1∈G1, với β được chọn ngẫu nhiên trong Zp.
Lúc này attacker có thể tuyên bố chữ ký của hắn cũng là một thành phần trong chữ ký kết hợp trên m bằng cách đưa ra chữ ký kết hợp của hắn và Bob σ=H(m)β. Chữ ký này hợp lệ vì vẫn đảm bảo bước kiểm tra:
e(g1,σ)=e(g1, H(m)β)=e(g1β, H(m))=e(pk1⋅pk2, H(m)). Điều này dẫn đến việc attacker có thể ngụy tạo việc Bob và hắn đã ký lên , mặc dù Bob chưa hề ký.
Khắc phục bằng Tuyen Optimization
Để khắc phục tấn công như trên, Tuyen Optimization đề nghị phương pháp che giấu cặp chữ ký và public key bằng cách nhân scalar thêm một giá trị ngẫu nhiên ri∈Z cho mỗi public key pki. Lúc này, chữ ký đã được che giấu sẽ được verfier kiểm tra phương trình:
e(g,i=1∑n(ri⋅σi))=?e(i=1∑n(ri⋅pki),H(m)) Nếu chữ ký hợp lệ, phương trình trên sẽ thỏa vì:
e(g,i=1∑n(ri⋅σi))=e(g,i=1∑n(riski⋅H(m)))=e(g,(i=1∑nriski)⋅H(m))=e((i=1∑nriski)⋅g,H(m))=e(i=1∑n(riski⋅g),H(m))=e(i=1∑n(ri⋅pki),H(m))