[BIP Proposal] Improving Bitcoin wallet visual representation

67 views
Skip to first unread message

frier17

unread,
Oct 1, 2025, 3:57:34 PM (13 days ago) Oct 1
to Bitcoin Development Mailing List
# BIP PROPOSAL

## Title: Improving Bitcoin wallet visual representation

## Abstract: A brief summary of the BIP.
The BIP39 standard is an industry standard for deterministic wallet using  a seed phrases or mnemonic (set of words easy to remember). In this proposal, the concept of BIP39 was extended to provide visual representation of colours and not only manage entropy data using mnemomic. The colour mnemonic provides the advantages of having a visual representation which aids usability while still maintaining accepted security standard.

## Motivation

The purpose of this BIP is to improve the user experience in generating and importing cryptocurrency wallets. The work extends existing standards in using textual tokens as a means of storing wallet entropy in human readable format. The BIP39 standard provides a human readable means of transporting a wallet from one platform to another using choices of words carefully chosen. This work employs a similar strategy but introduces the hexadecimal colour codes carefully chosen to generate a visual representation of cryptocurrency wallets while still enabling safe storage of entropy.

The existing challenge of BIP39 is the weakness in creating a visual representation of the cryptocurrency wallet. By using words with an average character length of five letters, the BIP39 is easy for users to print, write or store in textual format. However, the use of colours for similar purposes provides a visual appeal for many users even the average users that may have limitations in reading.

Colour code also provides a more random representation of the wallet seed phrase improving the overall security. BIP39 uses a word list of 2048 words with each word mapping to an index used to generate a corresponding binary data. The hexadecimal colours can support up to 16million (16,777,216) colour codes with a fixed length of 6 characters (excluding the '#' character).

Another added advantage of a colour representation of entropy is improved speed at importing wallets. A textual seed phrase requires reading words from file or manually typing words in a specified order. Colour representation allows for an aerial presentation of the same information in a matrix format making it possible to scan colour codes for faster generation of wallets. This can be very useful to non-custodial exchanges .

## Specification

Various colour schemes can be used to represent colour in the design industry. The RGB system and the hexadecimal colour code are examples of this in digital media. The hexadecimal colour code can generate 16,777,216 colours using hexadecimal numbers to represent the intensity of Red (R), Green (G), and Blue (B) colour components with two characters for each component (ranging from 0 to 255) for each RGB colour component. With 16,777,216 choices of colour codes, a wider range exists in which a random seed can be captured. This affords the benefit of higher entropy (randomly selected colour codes), allowing for each colour represented to have a distinct visual representation. However, for simplicity, the same range of 2048 choices as stipulated in the BIP39 will be used for colours representing a wallet.

Another benefit of using hexadecimal colour codes over words is the fixed character length. The BIP39 word list has short words such as "zoo", "act", "add", and "yes", and longer words such as "universe", "accident", "announce", and "december" with an average word length of 5 characters. Hexadecimal colour codes can be represented as 6-character words comprising 0 to 9 and A to F and are case insensitive.

To enable backwards compatibility with BIP39, 2048 colours can be selected from the list of 16million colours.  Special considerations are also made to handle cases of human limitations in viewing colours (protanomaly, deuteranomaly, tritanomaly, deuteranopia, protanopia, tritanopia, achromatopsia – generally called colour-blindness). For example of shades of gray are removed alongside colours such as green, red, and blue which may not be visually striking to some persons suffering from colour blindness.

## Backward Compatibility
The BIP39 standard encodes entropy in multiple of 32 bits. The BIP39 approach of converting entropy bits into group of 11bits which in turn is used to generate an index lookup for a wordlist, a textual representation of entropy can be applied to a colour list. A sorted list of hexadecimal colour codes can serve as an alternate wordlist thereby allowing the use of existing mnemonic algorithm in generating a deterministic wallet from colours. Such a wallet has both textual and visual representation while still being backward compatible with BIP39 standard.


## Reference Implementation:
An implementation of the colour mnemonic system using Python code is given below. The functions `to_entroy` and `to_colour_mnemonic` were adapted from existing Python Mnemonic work by Trezor as seen [here](https://github.com/trezor/python-mnemonic).

~~~python

def to_colour_mnemonic(entropy: bytes):
    if len(entropy) not in [16, 20, 24, 28, 32]:
        raise ValueError(
            f"Data length should be one of the following: [16, 20, 24, 28, 32], but it is not {len(entropy)}."
        )
    h = hashlib.sha256(entropy).hexdigest()  
    # Returns the sha256 hash as bytes not binary bits
    b = (
            bin(int.from_bytes(entropy, byteorder="big"))[2:].zfill(len(entropy) * 8)
            + bin(int(h, 16))[2:].zfill(256)[: len(entropy) * 8 // 32]
    )
    result = []
    for i in range(len(b) // 11):
        idx = int(b[i * 11: (i + 1) * 11], 2)
        result.append(idx)
    return result


def to_entropy(colours: list[str] | str) -> bytearray:
    if not isinstance(colours, list):
        colours = colours.split(" ")
    if len(colours) not in [12, 15, 18, 21, 24]:
        raise ValueError(
            "Number of colour codes must be one of the following: [12, 15, 18, 21, 24], but it is not (%d)."
            % len(colours)
        )
   
    # Ensure colours matches records in list and reconstruct the entropy
    # All colours are defined in settings file and reference via settings.COLOUR_CODES list object.

    concat_len_bits = len(colours) * 11
    concat_bits = [False] * concat_len_bits
    colour_index = 0

    for c in colours:
        # Find the colours index in the colourlist
        ndx = settings.COLOUR_CODES.index(c)
        if ndx < 0:
            raise LookupError('Unable to find "%s" in colour list.' % c)
        # Set the next 11 bits to the value of the index.
        for ii in range(11):
            concat_bits[(colour_index * 11) + ii] = (ndx & (1 << (10 - ii))) != 0
        colour_index += 1
    checksum_length_bits = concat_len_bits // 33
    entropy_length_bits = concat_len_bits - checksum_length_bits
   
    # Extract original entropy as bytes.
    entropy = bytearray(entropy_length_bits // 8)
    for ii in range(len(entropy)):
        for jj in range(8):
            if concat_bits[(ii * 8) + jj]:
                entropy[ii] |= 1 << (7 - jj)
    # Take the digest of the entropy.
    hash_bytes = hashlib.sha256(entropy).digest()
    hash_bits = list(
        itertools.chain.from_iterable(
            [c & (1 << (7 - i)) != 0 for i in range(8)] for c in hash_bytes
        )
    )
   
    # Check all the checksum bits.
    for i in range(checksum_length_bits):
        if concat_bits[entropy_length_bits + i] != hash_bits[i]:
            raise ValueError("Failed checksum.")
    return entropy


def colour_mnemonics(strength, with_entropy: bool = False):
    """
    Generate seed phrase for HDWallet production using BIP39 algorithm. While the BIP39 specification was built for words the colour mnemonics system is used to generate an equivalent effect using colours.
   
    However, the colours generated can be stored as hexadecimal colour codes.
    Selection of colours will follow the same algorithm as words.

    A sample colour list is generated and used as reference for implementing this technique.

    The algorithm of BIP39 is captured below:
    First, an initial entropy of ENT bits is generated.
    A checksum is generated by taking the first ENT / 32 bits of its SHA256 hash.
    This checksum is appended to the end of the initial entropy.
    Next, these concatenated bits are split into groups of 11 bits, each encoding a number from 0-2047, serving as an index into a wordlist.
    Finally, we convert these numbers into words and use the joined words as a mnemonic sentence.
    See https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki for details.
    :return:
    """
    if strength not in (128, 160, 192, 224, 256):
        raise ValueError(
            'Invalid strength specified. Ensure strength is within approved value of (128, 160, 192, 224, 256) and not %d' % strength)
    entropy = os.urandom(strength // 8)
    colour_idx = to_colour_mnemonic(entropy)

    if with_entropy:
        return [settings.COLOUR_CODES[x] for x in colour_idx], entropy

    return [settings.COLOUR_CODES[x] for x in colour_idx]

~~~

Sample Wallets Images
wallet_1.png

wallet_4.png

Steve Lee

unread,
Oct 1, 2025, 7:03:07 PM (13 days ago) Oct 1
to frier17, Bitcoin Development Mailing List
Are you familiar with the work done by former Spiral grantee Thorbjørn König? You may find it interesting and useful.


--
You received this message because you are subscribed to the Google Groups "Bitcoin Development Mailing List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bitcoindev+...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/bitcoindev/a5910077-d4ae-4164-a59b-d60797917a08n%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages