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()); }