public string EntropyToMnemonic(string entropy, BIP39Wordlist wordlistType) { var wordlist = GetWordlist(wordlistType); //How can I do this more efficiently, the multiple substrings I don't like... var entropyBytes = Enumerable.Range(0, entropy.Length / 2) .Select(x => Convert.ToByte(entropy.Substring(x * 2, 2), 16)) .ToArray(); CheckValidEntropy(entropyBytes); var entropyBits = BytesToBinary(entropyBytes); var checksumBits = DeriveChecksumBits(entropyBytes); var bits = entropyBits + checksumBits; var chunks = Regex.Matches(bits, "(.{1,11})") .OfType <Match>() .Select(m => m.Groups[0].Value) .ToArray(); var words = chunks.Select(binary => { var index = Convert.ToInt32(binary, 2); return(wordlist[index]); }); var joinedText = String.Join((wordlistType == BIP39Wordlist.Japanese ? "\u3000" : " "), words); return(joinedText); }
public string MnemonicToEntropy(string mnemonic, BIP39Wordlist wordlistType) { var wordlist = GetWordlist(wordlistType); var words = mnemonic.Normalize(NormalizationForm.FormKD).Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (words.Length % 3 != 0) { throw new FormatException(InvalidMnemonic); } var bits = string.Join("", words.Select(word => { var index = Array.IndexOf(wordlist, word); if (index == -1) { throw new FormatException(InvalidMnemonic); } return(lPad(Convert.ToString(index, 2), "0", 11)); })); // split the binary string into ENT/CS var dividerIndex = (int)Math.Floor((double)bits.Length / 33) * 32; var entropyBits = bits.Substring(0, dividerIndex); var checksumBits = bits.Substring(dividerIndex); // calculate the checksum and compare var entropyBytesMatch = Regex.Matches(entropyBits, "(.{1,8})") .OfType <Match>() .Select(m => m.Groups[0].Value) .ToArray(); var entropyBytes = entropyBytesMatch .Select(bytes => Convert.ToByte(bytes, 2)).ToArray(); CheckValidEntropy(entropyBytes); var newChecksum = DeriveChecksumBits(entropyBytes); if (newChecksum != checksumBits) { throw new Exception(InvalidChecksum); } var result = BitConverter .ToString(entropyBytes) .Replace("-", "") .ToLower(); return(result); }
public bool ValidateMnemonic(string mnemonic, BIP39Wordlist wordlist) { try { MnemonicToEntropy(mnemonic, wordlist); } catch { return(false); } return(true); }
public string GenerateMnemonic(int strength, BIP39Wordlist wordlistType) { if (strength % 32 != 0) { throw new NotSupportedException(InvalidEntropy); } RNGCryptoServiceProvider rngCryptoServiceProvider = new RNGCryptoServiceProvider(); byte[] buffer = new byte[strength / 8]; rngCryptoServiceProvider.GetBytes(buffer); var entropyHex = BitConverter.ToString(buffer).Replace("-", ""); return(EntropyToMnemonic(entropyHex, wordlistType)); }
private static string[] GetWordlist(BIP39Wordlist wordlist) { var wordlists = new Dictionary <string, string> { { BIP39Wordlist.ChineseSimplified.ToString(), "chinese_simplified" }, { BIP39Wordlist.ChineseTraditional.ToString(), "chinese_traditional" }, { BIP39Wordlist.English.ToString(), "english" }, { BIP39Wordlist.French.ToString(), "french" }, { BIP39Wordlist.Italian.ToString(), "italian" }, { BIP39Wordlist.Japanese.ToString(), "japanese" }, { BIP39Wordlist.Korean.ToString(), "korean" }, { BIP39Wordlist.Spanish.ToString(), "spanish" } }; var wordListFile = wordlists[wordlist.ToString()]; var wordListResults = Resources.ResourceManager.GetString(wordListFile) .Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries); return(wordListResults); }
private (string entropy, string seedHex, string mnemonic) TestVector(string description, BIP39Wordlist wordlist, string password, string entropy, string mnemonic, string seedHex) { var bip39 = new BIP39(); var entropyResult = bip39.MnemonicToEntropy(mnemonic, wordlist); var seedResult = bip39.MnemonicToSeedHex(mnemonic, password); var mnemonicResult = bip39.EntropyToMnemonic(entropy, wordlist); return(entropyResult, seedResult, mnemonicResult); }
public static string GenerateMnemonic(BIP39Wordlist wordlistType, int entropyStrength = 256) { return(Bip39.GenerateMnemonic(entropyStrength, wordlistType)); }
public static bool ValidateMnemonic(string mnemonic, BIP39Wordlist wordlist) { return(Bip39.ValidateMnemonic(mnemonic, wordlist)); }
/// <summary> /// Get a key pair from mnemonic /// </summary> /// <param name="mnemonic"></param> /// <param name="password"></param> /// <param name="bIP39Wordlist"></param> /// <param name="expandMode"></param> /// <returns></returns> public static KeyPair GetKeyPairFromMnemonic(string mnemonic, string password, BIP39Wordlist bIP39Wordlist, ExpandMode expandMode) { var secretBytes = GetSecretKeyFromMnemonic(mnemonic, password, bIP39Wordlist); var miniSecret = new MiniSecret(secretBytes, expandMode); return(new KeyPair(miniSecret.ExpandToPublic(), miniSecret.ExpandToSecret())); }
/// <summary> /// Get secret key from mnemonic /// </summary> /// <param name="mnemonic"></param> /// <param name="password"></param> /// <param name="bIP39Wordlist"></param> /// <returns></returns> public static byte[] GetSecretKeyFromMnemonic(string mnemonic, string password, BIP39Wordlist bIP39Wordlist) { var entropyBytes = Utils.HexToByteArray(GetEntropy(mnemonic, bIP39Wordlist)); var seedBytes = SeedFromEntropy(entropyBytes, password); return(seedBytes.AsMemory().Slice(0, 32).ToArray()); }
/// <summary> /// /// </summary> /// <param name="mnemonic"></param> /// <param name="bIP39Wordlist"></param> /// <returns></returns> public static string GetEntropy(string mnemonic, BIP39Wordlist bIP39Wordlist) => new BIP39().MnemonicToEntropy(mnemonic, bIP39Wordlist);