Signature

如何確定簽名(消息簽名)的第一個字節(恢復 ID)?

  • January 9, 2022

我確實意識到,在比特幣中,當我們返回對消息進行簽名的簽名結果時,第一個字節包含用於恢復使用如下公式進行驗證所需的公鑰的資訊:

27 + (4 if comp. 0 if not) + (0<=num<=3)

我正在努力解決的是我們如何確定這個num數字?根據SEC:1的第 4.1.6 節恢復公鑰:

  1. x = r + jn
  2. Q根據R是否無效移動到下一個計算
  3. 計算Q依據-R

由於 j(secp256k1 的輔因子)是 0 和 1,並且 R 有兩個值。所以應該有 4 個可能的公鑰。num在達到正確的公鑰之前我們拒絕的公鑰數量是多少?因為這是我根據我在使用 Electrum 生成的簽名和我自己使用 SEC1 完成的公鑰恢復之間所做的比較得出的唯一解釋。

額外問題:為什麼選擇 27?

FWIW這就是我發現的關於這個問題的內容。基本上有兩種方法可以找到庫稱為“recid”或恢復 ID。他們中的大多數人使用第一種方法,但還有另一種方法:

方法一:

  • 僅需要rs因此只要您有簽名和已簽名的“消息”,任何人都可以執行。
  • 它慢得多,因為它有 3 個標量乘法,並且基於所使用的橢圓曲線的輔因子,整個操作可能會重複 2*(h+1) 次,對於具有 secp256k1 曲線的比特幣來說,最多 4 次(99%時間是 1 或 2 次)。

這些步驟在SEC:1的 4.1.6 節中進行了說明,這裡不再贅述。

要找到recid您使用給定的公鑰或其雜湊檢查計算的公鑰,並將被拒絕的公鑰的數量報告為recid. 例如 if x=r+(0*order)and Qwas used thenrecid=0和 if -Qwas used thenrecid=1等等。

方法二:

  • 它需要完整的r,因此只能在簽名時完成(需要擁有私鑰)。R=(xR, yR)
  • 它要快得多,因為沒有額外的計算。它只需要快速的值檢查。
  • 這通常v在庫中被稱為

byte v = if(R.X > curve.N) then 2 else 0) | (if R.Y.IsEven then 0 else 1);

基本上檢查是否大於曲線階數(N)以及是偶數還是奇數。不應該忘記的事情是“翻轉”,它是基於簽名中使用的以及是否用於xR``yR``s``s``-s

if s > curve.N/2 then v^=1 else do nothing

** 請注意,最後您需要計算以下內容:

recid = 27 + v + (if compressed 4 else 0)

引用自:https://bitcoin.stackexchange.com/questions/83035