Title: Extract ECDSA parameters from Block Post by: tiago777 on November 08, 2019, 10:21:47 AM I am trying to extract the parameters of ECDSA signature used in bitcoin to run some tests. For that i need to obtain :
--- r and s , i.e., the ECDSA signature --- H(m) , the hash of the message used to generate the ECDSA signature --- the random integer k used in ECDSA signature generation, this is, the k such that s = k*(H(m) + x*r) mod q where x is the private key I already was able to obtain the r and the s of a very specific type of block, the ones where len(inp.script_sig) == 214 ) and the public key as well. So i need to obtain these parameters for all blocks. Also if someone knows how to do this for Ethereum and LiteCoin i'd appreciate you tell me. ```python from blockchain import blockexplorer from binascii import unhexlify from pyasn1.codec.der import decoder as asn1der import time, os, codecs import numpy as np from bitcoin_tools.bitcoin_tools.core.transaction import TX # returns the blocks of given day # if day = 0 , returns blocks of today # if day = 1 , returns blocks of yesterday , and so on .... def getBlocksofDay( day ): # get blocks from blockchain from given day # if we want the day before just subtract 86400000 return blockexplorer.get_blocks(int(round(time.time() * 1000)) - 86400000*day) # print SimpleBlock def printSimpleBlock( block ): print("\nHeight : ", block.height ) print("Hash : ", block.hash ) print("Time : ", block.time) print("Main Chain :", block.main_chain, "\n" ) # print Block def printBlock( block ): print("\nHash : ", block.hash ) print("Version : ", block.version ) print("Previous Block : ", block.previous_block ) print("Merkle Root : ", block.merkle_root ) print("Time : ", block.time) print("Bits : ", block.bits) print("Fee : ", block.fee) print("Nonce : ", block.nonce) print("Number of transaction : ", block.n_tx) print("Size : ", block.size ) print("Block Index : " , block.block_index ) print("Main Chain :", block.main_chain ) print("Height : ", block.height ) print("Received Time : ", block.received_time ) print("Relayed By : ", block.relayed_by ) if( block.n_tx > 50): print("Transactions : NOT PRINTING TX TOO MANY \n" ) else: print("Transactions : ", block.transactions ) # print Transaction def printTransaction( tx ): print("\nDouble Spend : ", tx.double_spend ) print("Block height : ", tx.block_height ) print("Time : ", tx.time ) print("Relayed By : ", tx.relayed_by ) print("Hash : ", tx.hash ) print("Tx Index : " , tx.tx_index ) print("Version : ", tx.version ) print("Size : ", tx.size ) print("Inputs : ", tx.inputs ) print("Outputs : ", tx.outputs, "\n" ) # print Input def printInput( inp ): try: if( len(inp.script_sig) == 214 ): ''' print("\nN : ", inp.n ) print("Value : ", inp.value ) print("Address : ", inp.address ) print("Tx_Index : ", inp.tx_index ) print("Type : ", inp.type ) print("Script : ", inp.script ) print("Script_Sig : ", inp.script_sig ) print("Sequence : ", inp.sequence ) ''' return 0 except: return -1 # print XPub def printXPub( xpub ): print("\nAddress : ", xpub.address) print("Number of Transaction : ", xpub.n_tx ) print("Total Received : ", xpub.total_received / 100000000, "BTC" ) print("Total Sent : ", xpub.total_sent / 100000000, "BTC" ) print("Final Balance : ", xpub.final_balance ) print("Change Index : ", xpub.change_index ) print("Account Index : ", xpub.account_index, "\n\n" ) for tx in xpub.transactions: printTransaction(tx) def printR_S_PK(script_sig_hex): #script_sig_hex is the scriptsig hex values = asn1der.decode(unhexlify(script_sig_hex)[1:]) ''' #R Value in int form print( "\nR value:", values[0][0] ) #S Value in int form print( "S value:", values[0][1] ) # X coordinate of Public Key print( "X coordinate of PK:", int(values[1].hex()[4:],16) ) ''' return [ int(values[1].hex()[6:],16), int(values[1].hex()[4:6],16), int(values[0][0]), int(values[0][1]) ] #if __name__ == "__main__": def getThemBlocks(day): simpleBlocksofDay = getBlocksofDay(day) pubKeys = np.array([[-1], [-1], [-1], [-1], [-1], [-1]]) print("LEN : ", len(simpleBlocksofDay), "\n") # run through all blocks of this day for block in [simpleBlocksofDay[0]]: blocksofDay = blockexplorer.get_block( block.hash ) txs = blocksofDay.transactions # run through all tx of this day for txofDay in txs: inpofTx = txofDay.inputs # run through all inputs of this day for inp in inpofTx: # if input has format we want if( printInput(inp) == 0 ): numLines, numColumns = len(pubKeys), pubKeys[0].size script_sig_hex = inp.script_sig xC, sig, r, s = printR_S_PK(script_sig_hex) aux = np.where(pubKeys[2]==xC) columnToAdd = [ -1 for i in range(0,numLines) ] columnToAdd[0], columnToAdd[1], columnToAdd[2], columnToAdd[3] = 6, 1, xC, sig columnToAdd[4], columnToAdd[5] = r, s lineToAdd = [ -1 for i in range(0,numColumns) ] # xC it's not repeated if( aux[0].size == 0 ): pubKeys = np.c_[pubKeys, np.array(columnToAdd)] # again xC it's not repeated elif( (aux[0].size == 1) and (pubKeys[3][aux[0][0]] != sig) ): pubKeys = np.c_[pubKeys, np.array(columnToAdd)] # xC it's repeated else: if( pubKeys[3][aux[0][0]] == sig ): column = aux[0][0] else: column = aux[0][1] # need to add 2 new lines if( pubKeys[0][column]+1 > numLines ): aux = np.array(lineToAdd) pubKeys = np.r_[pubKeys, [aux]] pubKeys = np.r_[pubKeys, [aux]] pubKeys = np.r_[pubKeys, [aux]] line = pubKeys[0][column] pubKeys[line][column] = r pubKeys[line+1][column] = s pubKeys[line+2][column] = txofDay.hash # increase the number of elements in that columns by 2 pubKeys[0][column] += 3 # increase the number of signatures by 1 pubKeys[1][column] += 1 for j in range(1, pubKeys[0].size): if(pubKeys[1][j] > 40): for i in range(0, len(pubKeys)): print(pubKeys[j]) print("\n\n") if __name__ == "__main__": ''' for i in range(0,3): getThemBlocks(i) ''' # First a transaction object is created (through the deserialize constructor) by deserializing the hex transaction we have selected. hex_tx = "01000000013ca58d2f6fac36602d831ee0cf2bc80031c7472e80a322b57f614c5ce9142b7100000 0006b483045022100f0331d85cb7f7ec1bedc41f50c695d654489458e88aec0076fbad5d8aeda16 73022009e8ca2dda1d6a16bfd7133b0008720145dacccb35c0d5c9fc567e52f26ca5f7012103a16 4209a7c23227fcd6a71c51efc5b6eb25407f4faf06890f57908425255e42bffffffff0241a20000 000000001976a914e44839239ab36f5bc67b2079de00ecf587233ebe88ac7463000000000000197 6a914dc7016484646168d99e49f907c86c271299441c088ac00000000" tx = TX.deserialize(hex_tx) # Then, the transaction can be displayed using the display method to analyze how it's been constructed. tx.display() ``` |