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()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.