Seed-to-Mnemonic

BIP39

https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki

Motivation

The bitcoin reference client offered a JBOK (just a punch of keys) wallet which required backing up of all the independent private keys and no support for regenerating/restoring the wallet state without them.

Individuals are no more required to backup their private keys in hexadicimal/binary formats rather they can store them as human readable memorable words in multiple languages (EN,CN,KR,...)

The introduction of BIP39 aids in implementing hierarchical deterministic wallets to overcome the above limitation.

Technical Implementation

  1. Generate random entropy in multiples of 32 bits (128,160,..,256)

    entropy := make([]byte, 32)
    _, err := rand.Read(entropy)

    as example I am generating for a 256 (32 * 8 ) bit entropy

  2. Calculate checksum

    entropyBitLength := len(entropy)*8
    checksumBitLength := entropyBitLength/32
    checksum := clacSha256(entropy)[0]
  3. Append the checksum to the end of the entropy

    entropy = append(entropy, checksum)
  4. Divide the entropy into 11 bits segments

    entropyAsInt := new(big.Int).SetBytes(entropy)
    word := big.NewInt(0)
    last11BitsMask := big.NewInt(2047)
    word.Add(entropyAsInt,last11BitsMask)
    entropyAsInt.Rsh(entropyAsInt, 11)
  5. Create a 2-byte slice from the above word

    sliceWord := PaddedSlice(word.Bytes(),2)
    func PaddedSlice (slice []byte, length int) []byte {
    offset:= length - len(slice)
    if offset <= 0 {
    return slice
    }
    newSlice := make([]byte,length)
    copy(newSlice[offset:],slice)
    return newSlice
    }
  6. Map each word number to the word index in the Mnemonic dictionary

    idx := binary.BigEndian.Uint16(sliceWord)
0