0
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 ).
So i need to obtain these parameters for all blocks and also need to know how to do this for Ethereum and LiteCoin.
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[i][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 = "01000000013ca58d2f6fac36602d831ee0cf2bc80031c7472e80a322b57f614c5ce9142b71000000006b483045022100f0331d85cb7f7ec1bedc41f50c695d654489458e88aec0076fbad5d8aeda1673022009e8ca2dda1d6a16bfd7133b0008720145dacccb35c0d5c9fc567e52f26ca5f7012103a164209a7c23227fcd6a71c51efc5b6eb25407f4faf06890f57908425255e42bffffffff0241a20000000000001976a914e44839239ab36f5bc67b2079de00ecf587233ebe88ac74630000000000001976a914dc7016484646168d99e49f907c86c271299441c088ac00000000"
tx = TX.deserialize(hex_tx)
# Then, the transaction can be displayed using the display method to analyze how it's been constructed.
tx.display()