User:Casascius/Base58Check-encoded objects proposal

From Bitcoin Wiki
Jump to navigation Jump to search

Proposal for redefinition of the "version byte"

Currently, all objects in Bitcoin when encoded in Base58Check have a "version byte". For example, a Bitcoin address has a byte of 0. A private key has a byte of 0x80. Derivative "altcoins" follow the scheme as well, and therefore their addresses and other objects are easily identified programmatically.

As a result of this practice, all Base58encoded objects tend to have similar prefixes that have come to be used to identify the object by users. A Bitcoin address always starts with a '1', a private key always starts with a '5'.

I propose that the "numberspace" in this version byte as used by implementers yield its importance to the "prefixspace" as seen by users. It is much more important that users be able to grasp Bitcoin concepts than it is for us to assign "version" bytes using some sort of sequential orthodoxy.

I propose that this byte be used as an "object co-identifier byte". Object types should be recognized by two attributes: this byte, as well as the payload length. Because the payload cannot be arbitrarily shortened or lengthened accidentally by users (the checksum will catch omissions or insertions), the payload length is a safe attribute for reliable recognition of objects.

Regular private key

Indicates an uncompressed private key. Widely accepted as "wallet import format", "sipa format".

  • Version byte: 0x80
  • Payload bytes: 32
  • How the user sees it: Always 51 characters beginning with '5' (specifically: 5H, 5J, or 5K)
  • Range in base58 encoding:
    • Lowest possible value: 5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAbuatmU
    • Highest possible value: 5Km2kuu7vtFDPpxywn4u3NLu8iSdrqhxWT8tUKjeEXs2f9yxoWz


Existing encoding for compressed private key

  • Version byte: 0x00
  • Payload bytes: 33 (32 for the key, plus the constant 0x01)
  • How the user sees it: Always 52 characters, beginning with K or L
  • Lowest possible value: KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73Nd2Mcv1
  • Highest possible value: L5oLkpV3aqBjhki6LmvChTCq73v9gyymzzMpBbhDLjDpKCuAXpsi

Proposed encoding for compressed private key

Rationale: Whether we like it or not, many users (particularly power users) will see base58 encoded objects, such as on paper wallets.

Since the distinction of compressed/uncompressed is of little practical difference to the user, and the question "why is this one 5 and that one K/L" an unnecessary burden that disregards simplicity, I propose a different encoding that both preserves the '5' and keeps a visual distinction there (in the second character) for those who can make use of it.

Proposal:

  • Version byte: 0x82
  • Payload bytes: 32
  • How the user sees it: Always 51 characters beginning with '5' (specifically: 5M, 5N, or 5P)
  • Range in base58 encoding:
    • Lowest possible value: 5Mhmw9M9nJvSXeYgrMgtzgwg3q4MWYYqJ6CziURYEBsR9t6VP82
    • Highest possible value: 5PeX7NoBdjbffU8PkwJtx1YSxwg5AFPi5jH6xd7SDqsoeMcxpoG
  • Note: By using 0x82 instead of 0x81 we ensures the second character always divulges the compressed status. If we used 0x81, then the prefix '5K' could belong to either, and would be ambiguous.

Implementation suggestion

Implementations already built around the existing compressed private key format (0x80 + 32bytes + 0x01) should continue to accept that format when parsing input, but should only output strings in the proposed format if the proposal is accepted.

Observation

A Base58Check string starts with '5' when it has a version byte of 0x80 and a payload of 43 bytes. (range: 5h thru 5j - lowercase mimic!)