Bitcoin Forum

Bitcoin => Development & Technical Discussion => Topic started by: Was on December 02, 2015, 06:17:01 AM



Title: Difference between a Public Key and Bitcoin address
Post by: Was on December 02, 2015, 06:17:01 AM
I understand that A public key is 140 char or something like that?

I was told that a Shorthand Bitcoin "address" corresponds to (A very large number) of Public keys on the secp256k1 curve.

How does one go about determining all of these public keys, and

Are you able to send outputs to all these public keys and still end up with coins at the same bitcoin address?


Thanks

Was


Title: Re: Difference between a Public Key and Bitcoin address
Post by: DannyHamilton on December 02, 2015, 09:07:08 AM
I understand that A public key is 140 char or something like that?

I suppose that depends on how you define a "char".  When talking about a bitcoin public key, people are typically referring to the ECDSA public key from the secp256k1 curve.  That public key is a pair of 256 bit numbers (x and y coordinates).  That's 512 binary digits.  In computer programming, a "char" is often just an alias for an 8 bit "byte". Using that  definition of a "char", a public key would be 512 / 8 = 64 char.  Alternately a byte is often represented as 2 hexadecimal digits.  Using a hexadecimal representation, the public key would be 64 X 2 = 128 hexadecimal digits.  It would also be possible to encode the public key in base 58 or base 64 (or just about any other base you like).

Then, you could further reduce the size of the representation by using a compressed key. Since the curve that bitcoin uses for computing the public key is known, you only need the x value (plus one additional bit) to be able to calculate the y value.  This cuts the size of the representation in half (plus one bit).

I was told that a Shorthand Bitcoin "address" corresponds to (A very large number) of Public keys on the secp256k1 curve.

Correct.  While there are 2256 possible public keys, version 1 (pay-to-pub-key-hash) bitcoin "addresses" use the RIPEMD160 hash function. This reduces the total number of possible addresses to 2160. This means that (on average) each address corresponds to 2256 / 2160 = 296 different public keys.

How does one go about determining all of these public keys,

One does not.  There is currently no known way to reverse the RIPEMD160 hash function and generate a list of public keys for a given hash value.

and Are you able to send outputs to all these public keys and still end up with coins at the same bitcoin address?

Bitcoin doesn't generally send to public keys any more.  Pay-to-pub-key was supported in the past (as well as pay-to-ip-address), but at this point in time the two output scripts that are generally used are pay-to-pub-key-hash (addresses that start with a "1") and pay-to-scrupt-hash (addresses that start with a "3").  The output script for pay-to-pub-key-hash doesn't make any reference to a public key at all.  It doesn't "send outputs to public keys", it "encumbers an output with a requirement to supply a signature with a key that hashes to a given hash value"


Title: Re: Difference between a Public Key and Bitcoin address
Post by: watashi-kokoto on December 02, 2015, 03:24:31 PM
bitcoin address = ripemd(sha256(public key))

public key = ecdsaexponentiation(private key)


Title: Re: Difference between a Public Key and Bitcoin address
Post by: Was on December 03, 2015, 10:28:08 AM
I understand that A public key is 140 char or something like that?

I suppose that depends on how you define a "char".  When talking about a bitcoin public key, people are typically referring to the ECDSA public key from the secp256k1 curve.  That public key is a pair of 256 bit numbers (x and y coordinates).  That's 512 binary digits.  In computer programming, a "char" is often just an alias for an 8 bit "byte". Using that  definition of a "char", a public key would be 512 / 8 = 64 char.  Alternately a byte is often represented as 2 hexadecimal digits.  Using a hexadecimal representation, the public key would be 64 X 2 = 128 hexadecimal digits.  It would also be possible to encode the public key in base 58 or base 64 (or just about any other base you like).

Then, you could further reduce the size of the representation by using a compressed key. Since the curve that bitcoin uses for computing the public key is known, you only need the x value (plus one additional bit) to be able to calculate the y value.  This cuts the size of the representation in half (plus one bit).

I was told that a Shorthand Bitcoin "address" corresponds to (A very large number) of Public keys on the secp256k1 curve.

Correct.  While there are 2256 possible public keys, version 1 (pay-to-pub-key-hash) bitcoin "addresses" use the RIPEMD160 hash function. This reduces the total number of possible addresses to 2160. This means that (on average) each address corresponds to 2256 / 2160 = 296 different public keys.

How does one go about determining all of these public keys,

One does not.  There is currently no known way to reverse the RIPEMD160 hash function and generate a list of public keys for a given hash value.

and Are you able to send outputs to all these public keys and still end up with coins at the same bitcoin address?

Bitcoin doesn't generally send to public keys any more.  Pay-to-pub-key was supported in the past (as well as pay-to-ip-address), but at this point in time the two output scripts that are generally used are pay-to-pub-key-hash (addresses that start with a "1") and pay-to-scrupt-hash (addresses that start with a "3").  The output script for pay-to-pub-key-hash doesn't make any reference to a public key at all.  It doesn't "send outputs to public keys", it "encumbers an output with a requirement to supply a signature with a key that hashes to a given hash value"


Danny, thank you, you've been more than helpful with my questions over the past few weeks. I've been trying to get a more in-depth understanding of how everything is working under the hood of this beast. May I ask who you are quoting "encumbers an output with a requirement to supply a signature with a key that hashes to a given hash value"

In this circumstance, what is the given hash value's relation to the destination address? The signature you speak of is derived from the private key of the origin of the output, correct?

 The pay-to-pub-key-hash makes reference to the pub key hash, but not the public key itself? I guess that is the point of the pkh?

Is there any resource you can suggest to me that covers this kind of thing all the way through?

Thanks


Title: Re: Difference between a Public Key and Bitcoin address
Post by: gerald-80 on December 03, 2015, 10:30:39 AM
A wallet is an abstract construct, which contains the set of public and private key pairs randomly generated for the user. In a deterministic wallet, the keys are derived from a passphrase (a specific seed, masterkey or password) instead of a random seed.


Title: Re: Difference between a Public Key and Bitcoin address
Post by: Was on December 03, 2015, 10:31:31 AM
A bitcoin "Address" is nothing more than a pairing of a public key (which you share with people to receive money, think of your public key as INBOUND ONLY traffic) and a private key (which cryptographically links to your public key, allowing you to spend said funds, OUTBOUND traffic). As im sure most of us would have no issue with money accidentally coming INTO our account, your public address can be shown to anyone. However, to spend/move those funds, you must possess the PRIVATE key. this is why they are named as such.

I didn't ask what the difference between Public and private keys, which, like you said, would be redundant since they're sort of self explanatory


Title: Re: Difference between a Public Key and Bitcoin address
Post by: Was on December 03, 2015, 10:33:24 AM
A wallet is an abstract construct, which contains the set of public and private key pairs randomly generated for the user. In a deterministic wallet, the keys are derived from a passphrase (a specific seed, masterkey or password) instead of a random seed.

seems like Danny is the only one that understands what I'm asking here, but thanks for the info on the deterministic wallets, I've been reading about how these are used in hardware wallets.


Title: Re: Difference between a Public Key and Bitcoin address
Post by: shorena on December 03, 2015, 11:52:27 AM
-snip-
May I ask who you are quoting "encumbers an output with a requirement to supply a signature with a key that hashes to a given hash value"

In this circumstance, what is the given hash value's relation to the destination address? The signature you speak of is derived from the private key of the origin of the output, correct?

I have to entangle this a bit before I can try an answer. Bitcoins you receive can be used in transactions. This is what Danny refered to with the quote. Its not actually a quote though. A transaction spends previously received coins (inputs). In a sense the inputs are destoryed in the process and the transaction creates new coins (outputs). You can also view it as if the coins are modified if that helps. The outputs can in turn be used as inputs for other transactions, either by you or someone else.

A destination address is the hash of the receivers public key (pay to pubkey hash) or the hash of a script the receiver created (pay to script hash). A signature is required to authenticate a payment with inputs previously received via the corresponding address (pubkey hash). A given transaction might require several signatures because it uses inputs received on several addresses. The signature is done with the private key and commonly by the person that created the address.

The scripts can require one or more signatures and even be spendable by anyone. Lets focus on pay to pubkey hash for now.

The pay-to-pub-key-hash makes reference to the pub key hash, but not the public key itself? I guess that is the point of the pkh?

Yes, the person paying to such an address does not know the public key. The person that received coins on such an address however has the public key and must provide it when the coins are used as an input. The public key is needed to verify the signature. What exactly the point behind this is might be something for someone more knowledge than me to explain, but it increases the security of bitcoin in the rare event that elliptic curves should be broken, but sha256 and/or ripemd 160 are not. This would mean that coins received on addresss where the public key is not known are still save even though elliptic curves in general are no longer.

Is there any resource you can suggest to me that covers this kind of thing all the way through?

Thanks

I found this -> https://bitcoin.org/en/developer-guide
very helpful.


Title: Re: Difference between a Public Key and Bitcoin address
Post by: DannyHamilton on December 03, 2015, 01:16:07 PM
- snip -
Danny, thank you, you've been more than helpful with my questions over the past few weeks. I've been trying to get a more in-depth understanding of how everything is working under the hood of this beast. May I ask who you are quoting "encumbers an output with a requirement to supply a signature with a key that hashes to a given hash value"

In this circumstance, what is the given hash value's relation to the destination address? The signature you speak of is derived from the private key of the origin of the output, correct?

 The pay-to-pub-key-hash makes reference to the pub key hash, but not the public key itself? I guess that is the point of the pkh?

Is there any resource you can suggest to me that covers this kind of thing all the way through?

Thanks

Shorena has done a pretty good job of answering you at a high level with generally used terms.

However, your questions are starting to get into some rather complicated details of the bitcoin protocol such that understanding how it actually works is going to require you to unlearn some things that most people believe about bitcoin.

The first thing to understand is that a "bitcoin address" is an abstraction that only exists at the human interface level. We use "addresses" to make it easier to discuss the transfer of control of value with those that aren't really interested in what is actually happening.   There are no addresses in transactions or in the blockchain.  The data that is stored there is just typically converted to an address representation when it is shown to humans.

The next thing to understand is that bitcoins aren't "sent" anywhere.  They certainly aren't sent to an address (since as I just stated, addresses don't even exist at the protocol level).  As a matter of fact, the concept of "bitcoins" as a thing that can be sent is just an abstraction that only exists at the human interface level.  We use the concept of "a bitcoin", and "fractions of bitcoins" to make it easier to discuss transfer of control of value with those that aren't really interested in what is actually happening. There is nothing that can be called "a bitcoin" or "a satoshi" in transactions or in the blockchain.  The value that is associated with an output is just typically referred to as a quantity of bitcoins when it is shown to humans. Perhaps we'll save this idea that bitcoins are just an abstraction and don't actually exist for another conversation, for now it's sufficient to understand that transactions are broadcast to peers on the bitcoin network, those peers verify that the transaction is valid and then relay it to their peers, eventually it gets to miners (or mining pools) which verify it is valid and include the transaction in a block, they perform a proof-of-work on the block and the block is then broadcast to all peers to be relayed and added to everyone's blockchain.  So in the end, what you have are transactions registered in a shared blockchain, not bitcoins being removed from a wallet and sent anywhere.

What actually exists in transactions are output scripts.  In every case other than the generation transaction, transactions are supplied value with inputs that are nothing more than unspent outputs from previous transactions (generation transactions get there value from another mechanism that isn't important for this discussion).  All transactions then assign some, or all, of their value to new unspent outputs.  Each output has a script that must be satisfied with some data in any input that tries to spend it. If the input does not supply data that allows the output script to be successfully executed, then the transaction is not valid.

There are opcode (operation code) bytes that are used to build the script.  You can see the opcode list here:
https://en.bitcoin.it/wiki/Script

One possible output script is:
<OP_DUP> <OP_HASH160>  0x14 <the 20 byte RIPEMD160 hash of a public key>  <OP_EQUALVERIFY> <OP_CHECKSIG>

When this output is referenced as an input to a transaction, the data supplied by transaction input is pushed onto the stack.  The script is then processed. The data that this script is expecting to be supplied by the transaction input is an ECDSA signature of the transaction that is spending this output and then a public key.

So the stack consists of a signature on the bottom, and then a public key on top of that.

The OP_DUP says to duplicate whatever element is on the top of the processing stack (the most thing most recently added, which in this case is the public key), and push the result on top of the stack.

So the stack now consists of a signature on the bottom, then a public key on top of that, then a duplicate of that public key on top of that.

OP_HASH160 says to remove the top element off the stack, use the RIPEMD160 algorithm to hash the data that was just removed, and push the result back on top of the stack.

So now the stack now consists of a signature on the bottom, then a public key on top of that, then a RIPEMD160 hash of that public key on top of that.

0x14 is a hex representation of the number 20. It says to push the next 20 bytes of the script onto the stack. This is the 20 byte RIPEMD160 hash from the output that is being spent.

So now the stack now consists of a signature on the bottom, then a public key on top of that, then a RIPEMD160 hash of that public key on top of that, then the RIPEMD160 hash from the output that is being spent on top of that.

OP_EQUALVERIFY says to remove the top two elements from the stack and verify that they are equal to each other.  If they are not equal, then the transaction is invalid and we can stop processing.  This verifies that the public key that was supplied by the person spending the output hashes to the same value as the RIPEMD160 hash that the output was encumbered with in its script. It is the public key that the output script was expecting.

So, as long as the two hashes were equal, the stack now consists of a signature on the bottom, then a public key on top of that.

OP_CHECKSIG says to remove the element on top of the stack and consider it to be an ECDSA public key, then remove the next element from the top of the stack and consider it to be a signature of the transaction that is attempting to spend the output. Then use ECDSA with the public key to verify that the signature is a valid signature of the transaction.  We already determined with OP_EQUALVERIFY that this is the expected public key, so now we are making sure that the spender has control of the private key (since without the private key, they wouldn't have been able to generate a valid signature).  If the signature is not valid, then the transaction is not valid and we can stop processing. If the signature is valid, then there is nothing left on the stack, there is nothing left of the script to process, and we have not encountered anything that reported as invalid, so the input is valid and will be accepted by all nodes running the bitcoin protocol.

This is a pay-to-pub-key-hash script. As you can probably see, this would be complicated and messy to have to write out every time you want someone to use this script in an output of a transaction that they are creating.  Also, everything except the hash value in that script is constant. So, when creating wallets, we can all agree to call this script a "version 1" script.  Then I could just give you the hash value and tell you to use the version 1 script.

Of course, I'd still have to give you the 160 bit hash value somehow, and there is a chance that you could make a typing error and put the wrong hash in there!  Then nobody will be able to spend the output you create (unless someone else is lucky enough to have the key that hashes to whatever value you entered.  So, I can create a 4 byte checksum on that 160 bit value, and give you that as well.  Now there is only a 1 in 4294967295 chance that any typing error that you make in either the hash or the checksum will still result in a hash that matches the checksum.

Now I just need an easy way to give you the script version, the hash, and the checksum.  If I send it to you in binary (and a use a full byte to represent the version), then I've got to send you a stream of 200 ones and zeros!  Base58 representation of a number uses almost all of the english alphabetical characters as well as nearly all of the base 10 digits. It leaves out a few that are difficult to distinguish from other similarly shaped symbols (0,O,I,l) (zero, capital Oh, capital eye, lowercase el). So if we start with the 8 bit version, append the 160 bit hash value, append the 32 bit checksum, and then convert the resulting 200 bit number into base58, we'll get a much shorter alpha-numeric string (typically about 34 characters).  We call this 34 character string a "bitcoin address".

So now, all we have to do is have all wallet creators agree that when they receive one of these "addresses" they will verify the checksum to prevent typing errors, and then recognize which script to create based on the version number.

Once we have such a system of creating "addresses" from standard scripts with some variable data, it becomes possible to come up with a new standard script and assign it a version number. Wallet creators can then add the new scripts to their wallets and all the users need to know to make use of the new script is what the new "address" looks like.

So, you can hopefully see here that output scripts encumber the output with a condition that must be met with input data in order for the output to be used to supply value to a transaction.  Notice that the transactions don't actually send bitcoins anywhere.  They just encumber outputs with conditions.  Users that want to spend those outputs then satisfy those conditions with input data, and create new outputs that are encumbered with new conditions.

If you haven't already done so, I suggest that you read the bitcoin whitepaper that Satoshi Nakamoto wrote:
https://bitcoin.org/bitcoin.pdf

There are some generalizations in there, and there are some implementation details that were later improved upon, so it doesn't describe exactly how bitcoin works, but it gives a good high level overview of the general concepts.

As for some of these other details, You can learn a lot from exploring the bitcoin wiki.  I'd suggest you start with the following if you are looking for details on the stuff I just described:

https://en.bitcoin.it/wiki/Base58Check_encoding
https://en.bitcoin.it/wiki/Address
https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses
https://en.bitcoin.it/wiki/List_of_address_prefixes
https://en.bitcoin.it/wiki/Script
https://en.bitcoin.it/wiki/Transaction