Dsa
ECDSA 簽名驗證實施中缺少的步驟
在ECDSA 的 Wikipedia 頁面上,在驗證算法的第 6 步中聲明:
If (x1,y1)=O then the signature is invalid.
在 X9.62 中,還聲明了
If u1G + u2Q is the point at infinity, then reject the signature.
但是,我在多個開源庫中找不到對這種情況的明確檢查。
xy = u1 * G + u2 * self.point v = xy.x() % n return v == r
有沒有我錯過的隱式檢查?
如果錯過了這樣的驗證,是否有可能對此進行攻擊?
許多圖書館將無限遠點定義為 $ \mathcal{O} = (0, 1, 0) $ (或作為 $ (0, 1) $ 如果使用仿射座標)。請注意,您連結的維基百科文章指出:
- 驗證 $ r $ 和 $ s $ 是整數 $ [1,n-1] $ . 如果不是,則簽名無效。
再往下一點:
- 簽名有效,如果 $ r\equiv x_1 \pmod{n} $ ,否則無效。
因此,如果我們將無限遠點表示為 x 座標為零,那麼我們會看到 $ r $ 永遠不能等於 $ x_1 $ 作為 $ r $ 必須明確檢查是否在範圍內 $ [1, n-1] $ 這意味著 $ r > 0 $ .
python-ecdsa
在第 132-135 行執行步驟 1 的檢查。然而,它並不代表 $ \mathcal{O} $ 如上所述,而是設置INFINITY = Point(None, None, None)
. 因此,如果我們進入xy = INFINITY
驗證呼叫,該方法將拋出異常,因為v = xy.x() % n
將呼叫模運算符 inNone
。目前尚不清楚呼叫程式碼是否擷取或預期此異常,但無論如何驗證呼叫不會在發生這種情況時返回簽名有效。