Пример #1
0
        public static bool Verification(string mnemonic)
        {
            var words = mnemonic.Trim().Split(' ');
            //判断助记词的单数数是否合法
            var allowLength = new int[] { 12, 15, 18, 21, 24 };

            if (!allowLength.Contains(words.Length))
            {
                throw new ArgumentException("Mnemonic words count error!");
            }

            //检测助记语言
            Wordlist wordList = new English();

            if (words.ToList().All(p => new ChineseSimplified().WordList.Contains(p)))
            {
                wordList = new ChineseSimplified();
            }

            //将助记词转为二进制字符串(每个单词转为 11 位的二进制数)
            var sb = new StringBuilder();

            foreach (var item in words)
            {
                var index = wordList.WordList.IndexOf(item);
                if (index < 0)
                {
                    throw new ArgumentException($"The \"{item}\" isn't the correct mnemonic word!");
                }
                var str = Convert.ToString(index, 2);
                while (str.Length < 11)
                {
                    str = "0" + str;
                }
                sb.Append(str);
            }
            var entcsString   = sb.ToString();
            var entropyString = entcsString.Substring(0, sb.Length * 32 / 33);
            //将二进制字符串转了字节数组
            var entropyBytes = new List <byte>();

            for (int i = 0; i < entropyString.Length / 8; i++)
            {
                var binaryString = new string(entropyString.Substring(i * 8, 8).Reverse().ToArray());
                var temp         = 0;
                for (int j = 0; j < binaryString.Length; j++)
                {
                    temp += (int)Math.Pow(2, j) * (binaryString[j] == '1' ? 1 : 0);
                }
                entropyBytes.Add((byte)temp);
            }
            var checksum       = entropyBytes.ToArray().Sha256();
            var checksumString = ToBinaryString(checksum).Substring(0, entropyBytes.Count / 4);

            if (!entcsString.EndsWith(checksumString))
            {
                throw new ArgumentException($"The mnemonic verification doesn't pass!");
            }
            return(true);
        }
Пример #2
0
        /// <summary>
        /// 生成助记词
        /// </summary>
        /// <param name="entLength">随机序列(熵)的长度,为了防止错误,可选范围为 {128, 160, 192, 224, 256}</param>
        /// <param name="language">助词词语言</param>
        /// <returns>助记词列表</returns>
        public static string GenerateMnemonic(EntropyLength entLength = EntropyLength._128, Language language = Language.English)
        {
            //创建一个 128 到 256 位的随机序列(熵)
            var entropyBytes  = GetRandom((int)entLength / 8);
            var entropyString = ToBinaryString(entropyBytes);
            //提出 SHA256 哈希前几位(ENT/ 32),就可以创造一个随机序列的校验和
            var checksum       = entropyBytes.Sha256();
            var checksumString = ToBinaryString(checksum).Substring(0, (int)entLength / 32);
            //将校验和添加到随机序列的末尾。
            var entcsString = entropyString + checksumString;

            //将序列划分为包含 11 位的不同部分。
            if (entcsString.Length % 11 != 0)
            {
                throw new Exception();
            }
            //将每个包含 11 位部分的值与一个已经预先定义 2048 个单词的字典做对应
            var index = new List <int>();

            for (int i = 0; i < entcsString.Length / 11; i++)
            {
                var binaryString = new string(entcsString.Skip(11 * i).Take(11).Reverse().ToArray());
                var temp         = 0;
                for (int j = 0; j < binaryString.Length; j++)
                {
                    temp += (int)Math.Pow(2, j) * (binaryString[j] == '1' ? 1 : 0);
                }
                index.Add(temp);
            }
            //生成的有顺序的单词组就是助记码
            var      words = new List <string>();
            Wordlist wordList;

            if (language == Language.ChineseSimplified)
            {
                wordList = new ChineseSimplified();
            }
            else
            {
                wordList = new English();
            }
            index.ForEach(p => words.Add(wordList.WordList[p]));
            return(string.Join(' ', words));
        }