Your calculations are right, except there aren't exactly 2^256 private keys -- there are "FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141" (this number is named N
in the ETH source code, and is the order of the generator of the elliptic curve secp256k1, from which Ethereum key pairs are generated).
In answer to your question, yes, private keys mapping to the same address will both be able to spend the money in that address on a first come first served basis. They will create the same public key, which the ECDSA verification algorithm is performed against, and so signatures generated by either private key will verify against the same address!
In go-ethereum/accounts/key.go, we have a private key generated from S256 which is secp256k1's curve, meaning they will be less than N
be default.
func newKeyFromECDSA(privateKeyECDSA *ecdsa.PrivateKey) *Key {
id := uuid.NewRandom()
key := &Key{
Id: id,
Address: crypto.PubkeyToAddress(privateKeyECDSA.PublicKey),
PrivateKey: privateKeyECDSA,
}
return key
}
func newKey(rand io.Reader) (*Key, error) {
privateKeyECDSA, err := ecdsa.GenerateKey(secp256k1.S256(), rand)
if err != nil {
return nil, err
}
return newKeyFromECDSA(privateKeyECDSA), nil
}
go-ethereum/crypto/secp256k1/secp256 also generates the key pairs in accordance with secp2656k1 albeit in a slightly different way :)
Cool illustrative explanation for what N
really is and why 2 keys will be able to spend money from the same account
Imagine private keys are miles driven in your car, and public keys are number of miles on your car's odometer. If the odometer rolls over from 999,999 to 000,000, a person with miles driven = 1,000,001 will have the same 'public key', and hence the same address, as a person with miles driven = 1.
EC group arithmetic is surprisingly similar to this, but rather than 999,999, we have the seemingly arbitrary number given above! Due to this property, even with your different 'private keys', you will be able to create signatures that verify against the same public key, and hence spend ETH from the same address!!
Boring math explanation
Private keys are 256 bit numbers, and to calculate the public key from a private key you multiply by the generator, g
, of the elliptic curve group. The generator in use is defined in the parameters of the secp256k1 libraries being used in ETH. It itself is also an elliptic curve point, and as elliptic curves are cyclic, there exists an n
such that n.g = 1
(this is called the generator order).
With this equation we can see that if we had a private key k
with k>n
, we would have k.g = (k-n).g = k'.g
, for a k'
that is possibly someone else's private key! So we have keys generated at random modulo n
, rather than 2^256.
A Bitcoin address is made by:
private key -> public key -> hash
An Ethereum address is made by:
private key -> public key -> hash -> throw some of it away and keep the rest
This means that the address alone is not enough to give you the address from the other system, but if you have the public key, you can create both the Bitcoin address and the Ethereum address.
The problem is getting the public key.
The public key cannot be deduced from the address in either Bitcoin or Ethereum. However, in both Bitcoin and Ethereum, making a transaction has the effect of publishing the public key on the network you are transacting with: In Ethereum, it is recoverable from the signature. In bitcoin, although it is recoverable from the signature, it is also explicitly sent as part of the transaction spending. (Bitcoin transactions are bigger than they need to be; Satoshi was probably not that big on cryptography.) So once a user has sent a transaction from an address on either the Bitcoin network or the Ethereum network, you can retrieve the public key from their spending transaction and use that to derive the address for the other network.
If the goal is to send the owner of a Bitcoin address assets on the Ethereum network, you also have another option: You can make a contract that is able to verify ownership of the Bitcoin address, once the owner gives it their public key. That way rather than needing the public key to send the user assets on the Ethereum network, you can defer the need to get hold of the public key until the user tries to spend the assets. Effectively, you are making a contract so that you can use a Bitcoin address on the Ethereum network. However, retrieving the funds will require the recipient to do non-standard things like sending this special contract their public key, at which point the contract will verify first that the public key supplied matches the specified bitcoin address, and then that the spender is able to provide a correct signature for that public key.
Best Answer
Yes, both cryptocoins use the same elliptic curve SECP256K1.
Perhaps a better alternative is to use a BIP32 wallet. You have a master key that is not directly used for transactions, but it is used to derive child keys than can be used.
You can derive separate keys for bitcoin and ethereum. You will always be able to use the master key to sign transactions for both keys.