Bitcoin Forum
October 15, 2019, 12:44:52 PM *
News: Latest Bitcoin Core release: 0.18.1 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: Is possible get public key from signature?  (Read 125 times)
Frodek
Member
**
Offline Offline

Activity: 118
Merit: 12


View Profile
October 11, 2019, 02:29:24 PM
Merited by LoyceV (1)
 #1

Transaction inputs script are usually (but coinbase) 73 bytes signature + 65 bytes key.
But in rare cases I see is only 73 bytes signature.
Is possible get 65 or 33 key from it?
I see
https://learnmeabitcoin.com/guide/digital_signatures_signing_verifying

https://learnmeabitcoin.com/guide/digital_signatures

But I don't know which bytes is messages which is "r" and "s" to divide. I wanna example how to get key from 73 bytes signature (or maybe from signature and message=other fields of input, like amount etc?)
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction. Advertise here.
1571143492
Hero Member
*
Offline Offline

Posts: 1571143492

View Profile Personal Message (Offline)

Ignore
1571143492
Reply with quote  #2

1571143492
Report to moderator
Coding Enthusiast
Hero Member
*****
Offline Offline

Activity: 691
Merit: 1099


Novice C♯ Coder


View Profile WWW
October 11, 2019, 04:14:07 PM
Merited by ETFbitcoin (1), LoyceV (1), AdolfinWolf (1), mr_random (1), Heisenberg_Hunter (1), TalkStar (1)
 #2

First let's get something out of the way, "scripts" are just scripts. Think of them as a series of data and commands that programmatically define the locking and unlocking conditions for each transaction. They don't have to contain signature + public key. They can have multiple signatures or no signatures at all. For example this script I posted recently is a simple mathematical formula (2+3=5) as the signature!

In bitcoin when an ECDSA signature is provided it will always be accompanied by the corresponding public key. In other words the blockchain already contains the pubkey you just have to first have to figure out the type of script they are using and locate it based on that. There can be lots of scripts but a handful are the most common (and considered standard):
- P2PK (uncommon these days) -> the public key will be in previous transaction's (tx being spent) PubkeyScript (aka scriptpub)
- P2PKH (aka legacy) -> pubkey is in SignatureScript (aka scriptsig)
- P2SH -> in common cases the pub key(s) are in redeem script which is the last item being pushed in SignatureScript
- P2WPKH (aka native SegWit) -> pubkey is in witness item corresponding to the input index.
- P2WSH (aka native SegWit script hash) -> similar to P2SH but it will be in witness items
- nested SegWit (P2WPKH-P2SH and P2WSH-P2SH) are similar to their native counterparts and have the "sig+pub" in their witness

The only thing remaining is to deserialize the transaction bytes into an object (or basically read it byte by byte) to get to the public key. A short example:
Script Sig:
Code:
483045022100f3581e1972ae8ac7c7367a7a253bc1135223adb9a468bb3a59233f45bc578380022059af01ca17d00e41837a1d58e97aa31bae584edec28d35bd96923690913bae9a0141049c02bfc97ef236ce6d8fe5d94013c721e915982acd2b12b65d9b7d59e20a842005f8fc4e02532e873d37b96f09d6d4511ada8f14042f46614a4c70c0f14beff5
Breaking it apart:
Code:
48 <-push
30-45 <-seq. tag + len
02-21 <-int tag + len
00f3581e1972ae8ac7c7367a7a253bc1135223adb9a468bb3a59233f45bc578380 <-r
02-20 <-int tag + len
59af01ca17d00e41837a1d58e97aa31bae584edec28d35bd96923690913bae9a <-s
01 <- sighash type
41 <- push
049c02bfc97ef236ce6d8fe5d94013c721e915982acd2b12b65d9b7d59e20a842005f8fc4e02532e873d37b96f09d6d4511ada8f14042f46614a4c70c0f14beff5 <- uncompressed pubkey
I think this answers your question about getting public key from a "transaction" or "scripts". I didn't want to make this reply that long but if you want to extract signatures (r,s) and derive the public key from that I could explain that part for you too.

Projects List+Suggestion box
Donation link using BIP21
Bech32 Donation link!
BitcoinTransactionTool (0.9.2):  Ann - Source Code
Watch Only Bitcoin Wallet (supporting SegWit) (3.1.0):  Ann - Source Code
SharpPusher (broadcast transactions) (0.10.0): Ann - Source Code

Frodek
Member
**
Offline Offline

Activity: 118
Merit: 12


View Profile
October 11, 2019, 08:43:24 PM
 #3

Thanks!
I previously thougt that "r" and "s" is one array
r and s are relative smaller numbers than key
How compute key? I have "r" and "s" but what is number "message".
Whose numbers I must divide by them?


Code:
049c02bfc97ef236ce6d8fe5d94013c721e915982acd2b12b65d9b7d59e20a842005f8fc4e02532e873d37b96f09d6d4511ada8f14042f46614a4c70c0f14beff5
The number aboce is key?
But is possible compute key from r and s knowing "message"?
bitaps
Member
**
Offline Offline

Activity: 128
Merit: 39

https://bitaps.com/


View Profile WWW
October 11, 2019, 09:15:06 PM
Merited by suchmoon (4), ETFbitcoin (1), LoyceV (1), Coding Enthusiast (1)
 #4

Yes it is possible but each signature corresponds to 4 possible public key (only 2 in most cases) and you should check all of them

please read this https://crypto.stackexchange.com/questions/60218/recovery-public-key-from-secp256k1-signature-and-message

implementation on python

https://github.com/bitaps-com/pybtc/blob/master/pybtc/functions/script.py#L432

This is example of usage

https://github.com/bitaps-com/pybtc/blob/master/pybtc/transaction.py#L895

https://github.com/bitaps-com/pybtc/blob/master/pybtc/test/transaction_constructor.py#L561





Coding Enthusiast
Hero Member
*****
Offline Offline

Activity: 691
Merit: 1099


Novice C♯ Coder


View Profile WWW
October 12, 2019, 03:38:01 AM
Last edit: October 12, 2019, 06:30:09 AM by Coding Enthusiast
 #5

r and s are relative smaller numbers than key
r and s are two numbers that represent x and y coordinates on the elliptic curve used in bitcoin (secp256k1). (correction thanks to achow101) r is the x coordinate of a point on curve, and s is s = k−1(e + rdU) mod n. Because of (mod n) they are both smaller than n which is 32 bytes in length.
If by "key" you mean the public key, you can't define "smaller or bigger" for points (pubkey is also a point). As for the length of them in bytes or the values compared to each other (r with pubkey.x) there still is no reason for it being smaller or bigger. These are numbers that could take up from 1 byte to 32 bytes (ignoring the sign byte).

How compute key? I have "r" and "s" but what is number "message".
The SE link posted by above user explains it.
The "message" for a transaction is double SHA256 hash of the serialized transaction in a different way depending on the SigHashType and the output type (PublicScript) that is being spent. Example of SigHashType.ALL and P2PKH output: https://bitcoin.stackexchange.com/questions/32628/redeeming-a-raw-transaction-step-by-step-example-required

Projects List+Suggestion box
Donation link using BIP21
Bech32 Donation link!
BitcoinTransactionTool (0.9.2):  Ann - Source Code
Watch Only Bitcoin Wallet (supporting SegWit) (3.1.0):  Ann - Source Code
SharpPusher (broadcast transactions) (0.10.0): Ann - Source Code

achow101
Moderator
Legendary
*
expert
Offline Offline

Activity: 1918
Merit: 2837


bc1qshxkrpe4arppq89fpzm6c0tpdvx5cfkve2c8kl


View Profile WWW
October 12, 2019, 05:14:27 AM
Merited by Coding Enthusiast (2), ETFbitcoin (1), nc50lc (1)
 #6

Transaction inputs script are usually (but coinbase) 73 bytes signature + 65 bytes key.
But in rare cases I see is only 73 bytes signature.
Is possible get 65 or 33 key from it?
I see
https://learnmeabitcoin.com/guide/digital_signatures_signing_verifying

https://learnmeabitcoin.com/guide/digital_signatures

But I don't know which bytes is messages which is "r" and "s" to divide. I wanna example how to get key from 73 bytes signature (or maybe from signature and message=other fields of input, like amount etc?)
In those cases, the public key is in the blockchain as part of the output. The output is a P2PK output. Bitcoin does not use public key recovery anywhere in transaction validation.

R and s are part of the signature. The signature is a DER encoded signature, and the breakdown of the encoding is given by Coding Enthusiast above.

Thanks!
I previously thougt that "r" and "s" is one array
It is. In Bitcoin, it is one item: a DER encoded signature. Because it is encoded, it can be further broken down into the R and s components. This is done by signature verifiers; Bitcoin itself (i.e. consensus and the script evaluator), do not care that it is encoded and just treat the signature as a single array.

r and s are relative smaller numbers than key
The key itself can be broken down into X and Y components, each of which are of the same magnitude of R and s. The key is also encoded.

How compute key? I have "r" and "s" but what is number "message".
The message is the double SHA256 of the transaction with some modification. For your specific example/question, this SE question and answer should be sufficient: https://bitcoin.stackexchange.com/questions/3374/how-to-redeem-a-basic-tx.

r and s are two numbers that represent x and y coordinates on the elliptic curve used in bitcoin (secp256k1).
They are not. The signature is not a curve point.

R is the X component of the "public key" of the nonce. S is just a scalar computed by the ECDSA formula.

bitaps
Member
**
Offline Offline

Activity: 128
Merit: 39

https://bitaps.com/


View Profile WWW
October 12, 2019, 05:33:05 AM
 #7


How compute key? I have "r" and "s" but what is number "message".
The message is the double SHA256 of the transaction with some modification. For your specific example/question, this SE question and answer should be sufficient: https://bitcoin.stackexchange.com/questions/3374/how-to-redeem-a-basic-tx.


The  "message" in bitcoin transaction signing process this is sighash. We have 2 classes of sighash today, first one is sighash for non segwit inputs and second for segwit inputs.

Sighash calculation algorithm:

for non witness inputs  explained here: https://en.bitcoin.it/wiki/OP_CHECKSIG
                                  python implementation: https://github.com/bitaps-com/pybtc/blob/master/pybtc/transaction.py#L947
                                  tests and examples: https://github.com/bitaps-com/pybtc/blob/master/pybtc/test/sighash.py#L14

for witness inputs defined in BIP 143 https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki#specification
                                  python implementation: https://github.com/bitaps-com/pybtc/blob/master/pybtc/transaction.py#L1020
                                  tests and examples: https://github.com/bitaps-com/pybtc/blob/master/pybtc/test/sighash.py#L521

Frodek
Member
**
Offline Offline

Activity: 118
Merit: 12


View Profile
October 14, 2019, 04:05:17 PM
 #8

I can' t understand because is
48 <-push
30-45 <-seq. tag + len

Hexadecinal 0x48 because in script.h is
Code:
enum opcodetype
{
    // push value
    OP_0 = 0x00,
    OP_FALSE = OP_0,
    OP_PUSHDATA1 = 0x4c,
    OP_PUSHDATA2 = 0x4d,
    OP_PUSHDATA4 = 0x4e,
..........
0x48 is len, not push?
Coding Enthusiast
Hero Member
*****
Offline Offline

Activity: 691
Merit: 1099


Novice C♯ Coder


View Profile WWW
October 14, 2019, 04:14:47 PM
 #9

I can' t understand because is
0x48 is len, not push?

True, it is length of the data to be "pushed" onto the stack.
These bytes (from 0x01 to 0x4b) have no name because there is no point in naming them since they each indicate the length equal to their value, so they could be referred to as "push" OPs.

Projects List+Suggestion box
Donation link using BIP21
Bech32 Donation link!
BitcoinTransactionTool (0.9.2):  Ann - Source Code
Watch Only Bitcoin Wallet (supporting SegWit) (3.1.0):  Ann - Source Code
SharpPusher (broadcast transactions) (0.10.0): Ann - Source Code

Pages: [1]
  Print  
 
Jump to:  

Sponsored by , a Bitcoin-accepting VPN.
Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!