Segregated-Witness
BIP143 中的範例簽名無效?
在BIP143中,第一個範例有見證簽名,但它似乎無法驗證/正確?!我寫了一個超級簡單的python程序來展示
import ecdsa import asn1 #Importing the 3 pieces of data from the example to byte arrays pub = bytearray.fromhex("025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee6357") sighash = bytearray.fromhex("c37af31116d1b27caf68aae9e3ac82f1477929014d5b917657d0eb49478cb670") dersigscript = bytearray.fromhex("304402203609e17b84f6a7d30c80bfa610b5b4542f32a8a0d5447a12fb1366d7f01cc44a0220573a954c4518331561406f90300e8f3358f51928d43c212a8caed02de67eebee") #deocding the DEC encoding decoder = asn1.Decoder() decoder.start(bytes(dersigscript)) tag, sigscript = decoder.read() #stripping off the script potion so we just have a signature sig = bytearray(sigscript)[2:66] vk = ecdsa.VerifyingKey.from_string(pub, curve=ecdsa.SECP256k1) vk.verify(sig, sighash)
如果有人可以闡明我在做什麼愚蠢的事情,或者可以將其分解的範例參考,那麼它會起作用,那將非常有幫助。我還嘗試在 3 個輸入的所有 8 個組合上反轉字節順序。話雖如此,我已經使用發布的私鑰和公鑰來進行我自己的簽名/驗證,所以我相當有信心它們的順序是正確的,只是對簽名不太確定。
謝謝!!
—-編輯—–
只是想列出為了完整性而嘗試過的其他事情
- 正如 pieter 指出的那樣,我錯誤地解碼了私鑰。S 和 R 分為 2 個不同的變數
304402203609e17b84f6a7d30c80bfa610b5b4542f32a8a0d5447a12fb1366d7f01cc44a0220573a954c4518331561406f90300e8f3358f51928d467eed 變成 3044 02 20 **3609e17b84f6a7d30c80bfa610b5b4542f32a8a0d5447a12fb1366d7f01cc44a** 02 20 **573a954c4518331561406f90300e8f3358f51928d4632cbeee1** 所以原始的 64 字節 sig 是 609e17b84f6a7d30c80bfa610b5b4542f32a8a0d5447a12fb1366d7f01cc44a573a954c4518331561406f90300e8f3358f51928d467c212a8caedebee02 不幸的是,這仍然沒有用 另外我嘗試使用pythons native der style ecdsa,但仍然沒有成功 從 ecdsa.util 導入 sigencode_der, sigdecode_der vk.verify(字節(sig),字節(sighash),sigdecode = sigdecode_der) 和 vk.verify(字節(sig),字節(sighash),hashlib.sha256,sigdecode=sigdecode_der) 其中 sig 以 0x30 開頭: 3044022047ac8e878352d3ebbde1c94ce3a10d057c24175747116f8288e5d794d12d482f0220217f36a485cae903c713331d877c1f6467e3622ad4010fe9dc6870540b6
有趣的是,python 庫除了簽名錯誤之外沒有給我任何錯誤。所以我似乎找不到任何關於如何使用標準庫來做到這一點的線索。如果我弄清楚了,我會發布答案
使用這個庫:
from cryptotools import Signature, PublicKey, hex_to_bytes pub = PublicKey.from_hex('025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee6357') sig = Signature.from_hex('304402203609e17b84f6a7d30c80bfa610b5b4542f32a8a0d5447a12fb1366d7f01cc44a0220573a954c4518331561406f90300e8f3358f51928d43c212a8caed02de67eebee') sighash = hex_to_bytes('c37af31116d1b27caf68aae9e3ac82f1477929014d5b917657d0eb49478cb670') >>> sig.verify_hash(sighash, pub) True
好的,多虧了 PieterWuille,我(我們)能夠弄清楚為什麼我的程式碼無法正常工作以及如何使用標準的 python 或 openssl 庫。
這些是以下問題
- python 庫的 DER 解碼使用不正確。我們需要遍歷所有變數並分別提取簽名的兩個部分(r 和 s)並重新組合它們。
- 因為標準簽名庫在簽名/驗證中內置了雜湊,而比特幣使用雙重雜湊,要使其與標準庫一起使用,您需要手動雜湊 1 次,然後將其提供給庫以執行第二次雜湊。這意味著我們不能使用 sigHash 作為輸入,而必須使用雜湊 preImage。下面發布的是關於最短的 Python 腳本,展示如何使用原始格式和 DER 編碼格式給出的範例驗證簽名:
進口ecdsa 導入 asn1 導入雜湊庫 #用於der版本 從 ecdsa.util 導入 sigencode_der, sigdecode_der #將範例中的3條數據導入字節數組 pub = bytearray.fromhex("025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee6357") DerEncodedSig = bytearray.fromhex " prehashimage = bytearray.fromhex(“0100000096b827c8483d4e9b96712b6713a7b68d6e8003a781feba36c31143470b4efd3752b0a642eea2fb7ae638c36f6252b6750293dbe574a806984b8e4d8548339a3bef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a010000001976a9141d0f172a0ecb48aee1be1f2687d2963ae33f71a188ac0046c32300000000ffffffff863ef3e1a92afbfdb97f31ad0fc7683ee943e9abcf2501590ff8f6551f47e5e51100000001000000”) #deocding DEC 編碼 解碼器 = asn1.Decoder() 解碼器.start(字節(DerEncodedSig)) 標籤,sigder = 解碼器.read() sig1 = sigder [2:34] sig2 = sigder [36:68] 信號 = 信號 1 + 信號 2 #現在我們需要獲取原像的單個sha256雜湊 m = hashlib.sha256() m.update (prehashimage) singlesighash = m.digest() #我們不會使用雙雜湊進行驗證,但這表明它與 bip143 中的 sigHash 相同 n = hashlib.sha256() n.update(singlesighash) sigHash = n.digest vk = ecdsa.VerifyingKey.from_string(字節(pub),曲線=ecdsa.SECP256k1) #我們必須提供雜湊庫,因為預設不是sha256 結果 = vk.verify(字節(sig),字節(singlesighash),hashlib.sha256) 列印(結果) #這是der原生方式,不需要我們對簽名進行der解碼,但兼容openssl 結果 = vk.verify(bytes(DerEncodedSig), bytes(singlesighash), hashlib.sha256, sigdecode=sigdecode_der) 列印(結果)