Example #1
0
        public static string[] DecodeMnemonicFromEntropy(byte[] entropy, Wordlist wordList)
        {
            if (entropy == null || entropy.Length == 0)
            {
                throw new FormatException("Seed was null or empty.");
            }

            List <string> mnemonic = new List <string>();

            if (entropy.Length % 4 > 0)
            {
                throw new FormatException("Seed must be multiples of 32 bits of entropy");
            }
            else if (entropy.Length < 8)
            {
                throw new FormatException("Seed must be at least 64 bits of entropy");
            }
            else if (entropy.Length > 124)
            {
                throw new FormatException("Seed must not exceed 992 bits of entropy");
            }

            // There's a reason to this double array madness...
            BitArray entropyBitArray    = new BitArray(BytesToBoolArray(entropy));
            int      checksumLengthBits = entropyBitArray.Length / 32;
            Array    entropyBits        = Array.CreateInstance(typeof(bool), entropyBitArray.Length);

            entropyBitArray.CopyTo(entropyBits, 0);

            byte[]   hash         = SHA256.Create().ComputeHash(entropy);
            BitArray hashBitArray = new BitArray(BytesToBoolArray(hash));
            Array    hashBits     = Array.CreateInstance(typeof(bool), checksumLengthBits);

            for (int i = 0; i < checksumLengthBits; i++)
            {
                bool bit = hashBitArray.Get(i);
                hashBits.SetValue(bit, i);
            }

            Array concatBits = Array.CreateInstance(typeof(bool), entropyBits.Length + checksumLengthBits);

            entropyBits.CopyTo(concatBits, 0);
            hashBits.CopyTo(concatBits, entropyBits.Length);

            int nwords = concatBits.Length / 11;

            for (int i = 0; i < nwords; ++i)
            {
                // 11 bits per word (2048)
                int index = 0;
                for (int j = 0; j < 11; ++j)
                {
                    index <<= 1;
                    bool bit = (bool)concatBits.GetValue((i * 11) + j);
                    if (bit)
                    {
                        index |= 0b1;
                    }
                }

                mnemonic.Add(wordList.GetWordAtIndex(index));
            }

            return(mnemonic.ToArray());
        }