我正在進一步研究開放的 Taproot PR。你能解釋一下 bip340_test_vectors 嗎?
我正在進一步研究開放的 Taproot PR。我找到了這些bip340_test_vectors。
它們具有密鑰、公鑰、aux_rand(輔助隨機性)、消息、簽名以及簽名是否驗證。你能解釋為什麼失敗的簽名失敗了嗎?
這些
bip340_test_vectors
用於兩個地方:單元測試(src/test/key_tests.cpp)和功能測試(test/functional/test_framework/key.py)。
bip340_test_vectors
用於測試的Python 程式碼在這裡。總共有 15 個測試案例,但只有 4 個不同的密鑰、7 個不同的公鑰(其中 3 個沒有密鑰)和 15 個不同的簽名。
例如,公鑰
DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659
被重複使用 9 次,但不同的簽名是使用不同的消息、輔助隨機性等生成的。前五個測試案例具有有效簽名(驗證結果為 TRUE),儘管第四個測試案例(索引 = 3)的註釋為
test fails if msg is reduced modulo p or n
(我不確定這意味著什麼)剩下的測試案例無法通過簽名驗證:定義 BIP 340 簽名的橢圓曲線是 secp256k1(與我們用於 ECDSA 的曲線相同),即:
y 2 = x 3 + 7 (mod p)
其中欄位大小p = 2 256 - 2 32 - 977或
p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
十六進制,是素數。我們使用的生成點 G(在曲線上)是 (G x , G y ),其中
G x =
0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798
G y =
0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8
secp256k1的曲線順序為:
n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
(曲線階數 n 使得 nG = 無窮遠點。每 n 次我們循環回到無窮遠點。這裡定義無窮遠點。它不在曲線上,由 (x,y) + 定義(x,-y) = 無窮大。)
與秘密(私有)密鑰關聯的公鑰 P(點)使用以下公式計算:
P = d (mod n).G
其中 d 是私鑰(標量),G 是生成點(point)。
BIP 340 Schnorr 簽名是一個 64 字節數組 (R x , s)。
前 32 個字節是 R 的 X 座標。
R = k’⋅G
R 是一個點 (R x , R y )
G 是前面定義的生成點
第二個 32 字節是滿足的 s:
s⋅G = R + H(r | pk | m)⋅P (mod n)
這可以寫成 sG = R + eP 其中 e = H(r | pk | m)
或者 s = k’ + ed 其中 d 是私鑰(標量)。
G 是前面定義的生成點(point)
R 較早計算(點)
H是雜湊函式(function)
r 是 R 的 X 座標,R x (標量)
pk 是公鑰 P 的 X 座標,P x (標量)
m 是消息(標量)。比特幣案例中的消息是比特幣交易的一部分,需要根據 SIGHASH 標誌進行簽名。
P是公鑰(點)
索引 5的公鑰不在比特幣使用的 secp256k1 曲線上。公鑰是通過將私鑰(標量)乘以生成點來計算的,因此它必須在橢圓曲線上。如果不是,則無法生成有效簽名。實際上,沒有為此公鑰提供密鑰,因為沒有可以與生成器點相乘以獲得公鑰的密鑰。
索引 6指的是BIP 340設計選擇以隱式選擇偶數的 Y 座標(每個有效的 X 座標有兩個可能的 Y 座標,一個是奇數,一個是偶數)。如果 Y 座標是奇數,則它不遵循 BIP 340 規範,並且簽名驗證應該失敗。
索引 7使用否定消息來驗證原始消息的簽名。否定意味著取群階 n 的補碼。如果您使用否定消息而不是簽名中使用的實際消息來驗證簽名,則簽名將無效。
-m = n-m (mod n)
顯然,整數環(mod n)中沒有實際的“負”數。
索引 8具有否定的 s 值。否定的定義見索引 7。如果您使用否定的 s 而不是初始 s 進行驗證,則簽名驗證將失敗。
索引 9狀態
R = sG - eP
是無限的,如果has_even_y(inf)
為 TRUE 和,則測試失敗x(inf)=0
。無窮遠點不在曲線上,根本沒有座標,但實現需要它的表示。如果一個實現使用 (0,0) 作為無窮遠點,那麼如果has_even_y
返回 TRUE(它不應該)並且x(inf)
返回 0,這個測試將失敗。索引 10狀態
R = sG - eP
是無限的。索引 11狀態
sig[0:32]
不是曲線上的 X 座標。如果 BIP 340 Schnorr 簽名的前 32 個字節不是橢圓曲線上的 X 座標,則這不是有效的簽名。索引 12也指簽名的前 32 個字節。但這次 32 個字節等於曲線 p 的欄位大小。這在 mod p 下是不可能的(所有值必須在 0 和 p-1 之間),所以這裡不可能有有效的簽名。
索引 13指的是 64 字節簽名的第二個 32 字節。s 不能等於曲線階 n,因為它被定義為 mod n,這意味著它只能取 0 到 n-1 之間的值。
索引 14的公鑰的 X 座標超過了欄位大小 (p = 2^256 - 2^32 - 977)。這在 mod p 下是不可能的(所有值必須在 0 和 p-1 之間),所以這裡不可能有有效的簽名。
(Jimmy Song 在他的《比特幣程式》一書中關於橢圓曲線密碼學的第 3 章有助於解釋 secp256k1 曲線。它在 BIP 340 最終確定之前發布,因此僅涵蓋 ECDSA 簽名,而不是 Schnorr 簽名。有關 Schnorr 簽名的介紹,請參閱 Elichai Turkel 的在Chaincode Labs 或倫敦 BitDevs Socratic Seminar on BIP 340 上的演講)
感謝 Pieter Wuille 和 Jonas Nick 對初始文章的建議編輯。