手動 ECDSA 簽名
我正在嘗試了解 ECDSA 簽名的逐步過程。該功能應如下所示:
S = k^-1 (hash + dA * R) mod p
,但我試圖了解我是否正確實施它。為了執行一個範例,我將從比特幣中藉用一個實際案例。變數如下:
hash: 13981225937542801152472832285710043259607809420725863171548640618989758767092 k: 11253563012059685825953619222107823549092147699031672238385790369351542642469 dA: 32678163117146052705943574521051490808324525286453391448021727749576063492292 p: 115792089237316195423570985008687907853269984665640564039457584007908834671663 R: 36422191471907241029883925342251831624200921388586025344128047678873736520530
我試圖理解的第一部分是 k^-1 是什麼意思。它是 k 的反轉版本(與生成公鑰時使用的方式相同)嗎?假設它是,我們最終得到以下等式:
S = 46845980742442032273496636384730466168994452136155887088844811385771348454723 * (13981225937542801152472832285710043259607809420725863171548640618989758767092 + 32678163117146052705943574521051490808324525286453391448021727749576063492292 * 36422191471907241029883925342251831624200921388586025344128047678873736520530) MOD 115792089237316195423570985008687907853269984665640564039457584007908834671663
這給了我們
47948206650808861643197644356522075407904568696590364200235146232910054391376
和十六進制:6A01B9263C7233181FEE2661C53E75C14312A7F4A2426EAEEA3502DCC40F7E50
。但是,它的長度似乎只有有效簽名的一半。我做的數學正確嗎?這只是簽名的一部分,其餘部分是單獨生成的嗎?
做什麼 $ k^{-1} $ 意思是?
在問題的公式中 $ S=k^{-1}(\mathrm{hash}+d_A\cdot R)\bmod p $ , 期限 $ k^{-1} $ 是*(*或)乘法逆 $ k $ 模組 $ p $ . 根據定義,這是一個整數 $ i $ 這樣 $ (i\cdot k)\equiv1\pmod p $ , 那是一個整數 $ i $ 這樣 $ p $ 劃分 $ (i\cdot k)-1 $ (或者如果我們想要乘法逆,另外 $ i $ 必須是這樣的 $ 0<i<p $ )。我們採用哪個乘法逆元不會改變結果 $ S $ .
$ k^{-1} $ 可以使用(半)擴展歐幾里得算法計算(見this);或其他方法。無論使用什麼,問題都有 $ S $ 匹配 $ k $ , $ \mathrm{hash} $ , $ d_A $ , $ R $ 和 $ p $ , 和給出的方程。但請看下面為什麼 $ S $ 錯了。
它的長度似乎只有有效簽名的一半
的確。那是因為簽名是 $ (R,S) $ 根據某些約定;比如連接固定長度的八位字節字元串,表示 $ R $ 和 $ S $ 根據 big-endian 約定,可能帶有一些前綴。
評論方程
哦,我最初錯過了:問題的方程式 $ S=k^{-1}(\mathrm{hash}+d_A\cdot R)\bmod p $ 是錯的!訂單之間存在混淆 $ p $ 場的(用於橢圓曲線 secp256k1 上的座標),以及順序 $ n $ 點的 $ G $ 在橢圓曲線上(對於 secp256k1 也是橢圓曲線上的點數,包括無窮遠點)。正確的方程是 $ S=k^{-1}(\mathrm{hash}+d_A\cdot R)\bmod n $ . 對於 secp256k1, $ n $ 是
115792089237316195423570985008687907852837564279074904382605163141518161494337
。那改變 $ S $ , 當然。如果方程只給我們 $ R $ ,我們怎樣才能得到 $ S $ ?
我們獲得 $ S $ 使用等式 $ S=k^{-1}(\mathrm{hash}+d_A\cdot R)\bmod n $ 從…開始 $ k $ , $ \mathrm{hash} $ , $ d_A $ , $ R $ 和 $ n $ .
我們之前一定已經獲得 $ R $ 通過計算 $ k\times G $ . 這是橢圓曲線 secp256k1 上的點乘法,使用算術模 $ p $ (這不是錯字),保持 $ X $ 協調和演繹 $ R $ . 規範的方法是計算 $ R=X\bmod n $ (減少後 $ X $ 模組 $ p $ 以便 $ 0\le X<p $ ),並從另一個開始重做 $ k $ 什麼時候 $ R=0 $ . 然而在實踐中,如果我們沒有得到 $ 0<X<n $ , 那麼這個過程 $ k $ 被選中並 $ X $ 計算幾乎肯定會被破壞,並且在所有其他情況下 $ R=X $ .
更新:我確認問題是 $ R $ 匹配問題的 $ k $ . 因此,剩下要做的就是計算 $ S $ 使用適當的模數和格式 $ (R,S) $ 進入簽名。