Vitalik suggests pushing for a base58check similar to Bitcoin, outside of the consensus layer. This standard would be socially enforced from day 1, instead of being retro-fitted like EIP55.
I actually quite aesthetically dislike base58check :smile:
My favorite choices would be:
Stick with mixed-case hex like in ETH1 [...] With the length increase from 20 to 32 byte
so you don't need bigints
Does EIP55 also use bigints with utils.big_endian_to_int(utils.sha3(addr.hex()))? It also uses big-endian encoding which I guess is another argument to consider in https://github.com/ethereum/eth2.0-specs/issues/1046.
That's just using the hash as a bitfield (the only use of v is o += c.upper() if (v & (2**(255 - i))) else c.lower()); it's completely doable without converting to ints at any step of the process, I just wrote it that way because it was the simplest to write in python.
I actually quite aesthetically dislike base58check
What do you dislike about it in particular? Surely having to use a bigint is rather marginal
(Shorter addresses seem like a plus to me)
Copying from bitcoin documentation (bitcoin is trying to switch from base58 to a base32 variant):
We could potentially even use bech32 as is.
As mentioned at https://ethresear.ch/t/ethereum-2-address-format/6138 bech32 seems like a decent option.
What would the process for public key to address be, though? Seem to be that there are three main options:
sha256() of the public keysha256() of the public keywhich would give, as an example, the following:
with bech32 encoding of these being (assuming an "eth" prefix):
eth14xd8dmthjmmmugk4kl59mm4hc4nhaz89z8stxdmp37xyadsnfx6t7tg48ajf776nxk073w228rjycmj83h0eth1m0ad9f4lkrnlru8523sfgnaa3ha87d76q6jdzwees0xfpw6xjcas7ucq5eeth1j38mmr060uma5p4y6yannq7vjza5d93md9du2kPersonally I think the first one is too long, but either of the latter two could work.
@mcdee I think addressing via a hash generally makes sense here. As for the hash vs the 20 bytes, I think we have generally been thinking that there is no need to reduce the security by using 20 bytes like eth1 and should instead use the full 32
@CarlBeek What is the status of checksums? (I understood using bech32 out of the box doesn't work.) Are you pursuing EIP 2336 (a closed PR)?
Careful there with new Bech32 use-cases. Recently there was a (small, but oversight) issue found in Bech32: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-December/017521.html
+1 to having checksums from day 1.
While trying to process some Eth1 payments recently, I ran into some annoying lack of checksums, and thought of the Eth2 implementation. Before raising a new issue, I thought I would check if it had already been discussed and found it it still an open issue.
There are two places I see checksums being useful:
(1) withdrawal credentials - 32 bytes, kind of like an address (is a hash with bytes truncated)
(2) validator public key - 48 bytes, and you need the private key to sign the deposit message so is probably going to be derived (not typed in)
The eth2 values are likely going to be more specialised users than general eth1 address, but even if they are derived values, I still think there are benefits of having a checksum:
I would like to see this issue implemented.
cc @CarlBeek
For validator public key:
A kind of weird thought, if you don't want to change the data size, and have a checksum that is completely invisible to the current implementation, would be to specify valid keys as only those whose public key where the last 1 or 2 bytes are a valid checksum for the other bytes.
i.e. add a simple CRC-8 or CRC-16 check by simply restricting the domain of valid values.
This may mean you need to calculate ~256 private keys before you randomly get one who public key happens that happens to meet the criteria, so would add time to key generation. (If it was CRC-16 then that would be ~16,000 generations.)
It would also be reducing the effective key size by at least 8 bits (or maybe 16 bits as the private key is 2x public). I don't know what other cryptographic effects it might have, and it would need to be analyzed theoretically to see if such a constraint causes issues, e.g. something about the curve makes CRC values more rare than expected.
(It should be easy enough to check if there is any correlation, by seeing if the actual rate of randomly meeting the criteria matches the expected rate or not).
For withdrawal credentials it is even easier, as it is already just a hash value that we trim down to 31 bytes... easy enough to trim the hash down to 29 bytes, so:
withdrawal credentials = version byte + hash bytes 2-30 + 2 byte CRC-16
This doesn't have any impact on the keys, just the withdrawal "address" becomes only 29 bytes.
There would be no impact on any of the code either; at least not in phase 0... it would only be relevant to validate withdrawals. And could even be made optional by having withdrawal type 1 (checks 31 bytes match) and a new type 2 (checks 29 bytes match and the last 2 are the CRC).
Note that adding a CRC to the bytes representation is different from having an encoding for addresses (e.g. Base 32) and/or have an error detection scheme specifically designed to detect transpositions, repetitions, etc. You could even have both if you wanted.
The rough consensus from the EF research team seems to be that checksums for validator pubkeys don't have a well-defined use case. The key actions involving validator pubkeys (namely deposits and transfers) have some in-built protections. For example, the deposit interface will check the proof of possession, the deposit contract has a deposit data root check, and transfers can only be made to an existing validator.
Closing for now but feel free to open another issue if you feel otherwise :)
Most helpful comment
@mcdee I think addressing via a hash generally makes sense here. As for the hash vs the 20 bytes, I think we have generally been thinking that there is no need to reduce the security by using 20 bytes like eth1 and should instead use the full 32