[Ethereum] easily generate a public address which has no private key

addresseskeccakprivate-keypublic-keysolidity

I might be wrong in some of the facts that I state here, so please correct me if necessary.

My understanding:

  • Private key – 256 bits
  • Public key – 256 bits
  • Public address – the last 160 bits of a public key
  • Every private key is mapped to a public key, and hence to a public address

The facts above imply that some private keys are mapped to the same public address, but they do not imply that some private keys are mapped to the same public key.

I would like to ask the following questions:

  1. Do we have any other knowledge as to whether or not some private keys are mapped to the same public key, and hence, some public keys have no private key which is mapped to them?

  2. If the answer to the above question is yes, then there's a possibility that some public addresses have no private key which is mapped to them. Do we know of any such addresses, or if they even exist?

My motivation for asking this, is that I have an ERC20 contract which sometimes (depending on the current state) mints an additional amount of tokens which will later be distributed among (i.e., transferred to) some users.

Now, I need some address to hold these tokens, but I wish to avoid the case where someone has the private key of this address (as slim a chance as it may be).

At present, I am generating this address as follows:

address public constant MINTING_ACCOUNT = address(keccak256("MINTING_ACCOUNT"));

Ideally, I would like to replace this with a constant address which has no private key.

Thank you!

Best Answer

TLDR: Use address 0.

  1. Depending on your definition of a private key, then yes or no. The public key is generated from the private key by scalar elliptic curve multiplication.

    P = k * G
    

    We know that the order of the generator G is

    n = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141 
    

    and so every k in the range [0, n) gives a unique public key. Sometimes people say that a private key is just a random 256-bit number, but private keys are equivalent mod n, which is slightly less than 2^256. For instance the private key k and n+k will give the same public key.

If you define a "public key" as any 512-bit integer then clearly almost all of them do not have associated private keys. (There are only n < 2^256 distinct private keys).

  1. The question of whether or not an address exists with no private key is a completely separate issue. Essentially you want to know if there is a 20-byte string such that no keccak256 hash ever ends in that postfix. The answer is that nobody knows, but probably not. Cryptographic hashes are designed exactly to avoid these sorts of nontrivial patterns in their output, and it would be a major flaw if such a string were to be discovered.

In summary, no. There is no "safe address". On the other hand, as many others have pointed out, the probability of guessing a private key corresponding to the 0 address is almost exactly 2^-160. This will never happen. Note that I don't say "this will probably never happen", because humans tend to be bad at reasoning about big numbers. I say "there's a 1 in 2^160" chance, and you say "so there's a chance?"

The chance is lower than any the probability of every computer on the network spontaneously combusting. There's no chance.

So we see the only option is to just pick an address "at random". You seem to want to pick a address generated by the hash of some string. I argue that you should use the 0 address instead. In cryptography this is sometimes called a "nothing up my sleve number". The more freedom you have in picking the address, the less confident users will be that you didn't intentionally search for a collision between the fake address and a real address. If you pick 0, users can be sure you have nothing up your sleeve.