Пример #1
0
        /// <summary>
        /// Initializes a new instance of <see cref="BIP0032"/> with an entropy derived from the given
        /// <see cref="IRandomNumberGenerator"/> and the entropy size.
        /// </summary>
        /// <exception cref="ArgumentException"/>
        /// <exception cref="ArgumentNullException"/>
        /// <exception cref="ArgumentOutOfRangeException"/>
        /// <param name="rng">RNG to use</param>
        /// <param name="entropySize">
        /// [Default value = 32]
        /// Size of the entropy (must be between 128 and 512 bits; ie. 16 and 64 bytes).
        /// </param>
        public BIP0032(IRandomNumberGenerator rng, int entropySize = 32)
        {
            if (rng is null)
            {
                throw new ArgumentNullException(nameof(rng), "Random number generator can not be null.");
            }
            if (entropySize < MinEntropyLength || entropySize > MaxEntropyLength)
            {
                throw new ArgumentOutOfRangeException(nameof(entropySize), "Entropy size must be between 16 and 64 bytes.");
            }


            byte[] entropy = new byte[entropySize];
            int    count   = 0;

            while (count <= Constants.RngRetryCount)
            {
                try
                {
                    rng.GetBytes(entropy);
                    SetEntropy(entropy);
                    break;
                }
                catch (Exception)
                {
                    // We should never land here for curves like secp256k1 because of how close N and P are.
                    count++;
                    // This will only throw if the RNG is broken.
                    if (count == Constants.RngRetryCount)
                    {
                        throw new ArgumentException(Err.BadRNG);
                    }
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Initializes a new instance of <see cref="PrivateKey"/> using the given <see cref="IRandomNumberGenerator"/>.
        /// </summary>
        /// <exception cref="ArgumentException"/>
        /// <exception cref="ArgumentNullException"/>
        /// <param name="rng">The <see cref="IRandomNumberGenerator"/> instance to use</param>
        public PrivateKey(IRandomNumberGenerator rng)
        {
            if (rng is null)
            {
                throw new ArgumentNullException(nameof(rng), "Random number generator can not be null.");
            }

            byte[] temp  = new byte[KeyByteSize];
            int    count = 0;

            while (count <= Constants.RngRetryCount)
            {
                try
                {
                    rng.GetBytes(temp);
                    SetBytes(temp);
                    break;
                }
                catch (Exception)
                {
                    count++;
                    // This should never happen:
                    if (count == Constants.RngRetryCount)
                    {
                        throw new ArgumentException(Err.BadRNG);
                    }
                    // TODO: maybe use a mod Curve.N in case bytes were bigger than N (out of range)
                }
            }
        }
        /// <summary>
        /// Initializes a new instance of <see cref="BIP0039"/> with a randomly generated entropy of given
        /// <paramref name="entropySize"/> using the given <see cref="IRandomNumberGenerator"/> instance,
        /// world list and an the passphrase.
        /// </summary>
        /// <exception cref="ArgumentException"/>
        /// <exception cref="ArgumentNullException"/>
        /// <exception cref="ArgumentOutOfRangeException"/>
        /// <param name="rng">Random number generator to use</param>
        /// <param name="entropySize">
        /// Size of the entropy which determines number of words in final mnemonic.
        /// Size must be 16, 20, 24, 28 or 32 which results in 12, 15, 18, 21, and 24 words respectively.
        /// </param>
        /// <param name="wl">[Defaultvalue = <see cref="WordLists.English"/> Word list to use</param>
        /// <param name="passPhrase">
        /// [Default value = null] Optional passphrase to use for computing <see cref="BIP0032"/> entropy
        /// </param>
        public BIP0039(IRandomNumberGenerator rng, int entropySize, WordLists wl = WordLists.English, string passPhrase = null)
        {
            if (rng is null)
            {
                throw new ArgumentNullException(nameof(rng), "Random number generator can not be null.");
            }
            if (!allowedEntropyLengths.Contains(entropySize))
            {
                throw new ArgumentOutOfRangeException(nameof(entropySize), "Entropy must be 16 or 20 or 24 or 28 or 32 bytes.");
            }

            allWords = GetAllWords(wl);

            byte[] entropy = new byte[entropySize];
            rng.GetBytes(entropy);
            SetWordsFromEntropy(entropy);

            SetBip32(passPhrase);
        }
Пример #4
0
        /// <summary>
        /// Initializes a new instance of <see cref="BetterMnemonic"/> using the given arguments.
        /// </summary>
        /// <exception cref="ArgumentNullException"/>
        /// <exception cref="ArgumentOutOfRangeException"/>
        /// <param name="rng">Random number generator to use</param>
        /// <param name="entropySize">Entropy size</param>
        /// <param name="path">Child key derivation path</param>
        /// <param name="creationTime">Creation time as a <see cref="LockTime"/></param>
        /// <param name="wl">Word list to use</param>
        /// <param name="passPhrase">Optional passphrase to extend the key</param>
        public BetterMnemonic(IRandomNumberGenerator rng, int entropySize, BIP0032Path path, LockTime creationTime,
                              BIP0039.WordLists wl = BIP0039.WordLists.English, string passPhrase = null)
        {
            if (rng is null)
            {
                throw new ArgumentNullException(nameof(rng), "Random number generator can not be null.");
            }
            if (!BIP0039.allowedEntropyLengths.Contains(entropySize))
            {
                throw new ArgumentOutOfRangeException(nameof(entropySize), "Entropy must be 16 or 20 or 24 or 28 or 32 bytes.");
            }

            DerivationPath = path;
            Locktime       = creationTime;
            allWords       = BIP0039.GetAllWords(wl);
            entropy        = new byte[entropySize];
            rng.GetBytes(entropy);
            SetBip32(passPhrase);
        }
Пример #5
0
        /// <summary>
        /// Initializes a new instance of <see cref="ElectrumMnemonic"/> with a randomly generated entropy
        /// using the given <see cref="IRandomNumberGenerator"/> instance, world list and an the passphrase.
        /// </summary>
        /// <exception cref="ArgumentException"/>
        /// <exception cref="ArgumentNullException"/>
        /// <exception cref="ArgumentOutOfRangeException"/>
        /// <param name="rng">Random number generator to use</param>
        /// <param name="mnType">Type of the mnemonic to create (anything but <see cref="MnemonicType.Undefined"/>)</param>
        /// <param name="wl">[Defaultvalue = <see cref="BIP0039.WordLists.English"/> Word list to use</param>
        /// <param name="passPhrase">
        /// [Default value = null] Optional passphrase to use for computing <see cref="BIP0032"/> entropy
        /// </param>
        public ElectrumMnemonic(IRandomNumberGenerator rng, MnemonicType mnType,
                                BIP0039.WordLists wl = BIP0039.WordLists.English, string passPhrase = null)
        {
            if (rng is null)
            {
                throw new ArgumentNullException(nameof(rng), "Random number generator can not be null.");
            }
            if (!Enum.IsDefined(typeof(MnemonicType), mnType) || mnType == MnemonicType.Undefined)
            {
                throw new ArgumentException("Undefined mnemonic type.", nameof(mnType));
            }

            MnType   = mnType;
            allWords = BIP0039.GetAllWords(wl);

            byte[] entropy = new byte[EntropyByteLen];
            rng.GetBytes(entropy);
            SetWordsFromEntropy(entropy);
            SetBip32(passPhrase);
        }
        /// <inheritdoc/>
        protected override int GetNextRandom(int sides)
        {
            if (sides < 2)
            {
                throw new ArgumentOutOfRangeException("sides");
            }

            // Create a byte array to hold the random value.
            byte[] randomNumber = new byte[1];
            do
            {
                // Fill the array with a random value.
                rngProvider.GetBytes(randomNumber);
            }while (!this.IsFairRoll(randomNumber[0], sides));

            // Return the random number mod the number
            // of sides.  The possible values are zero-
            // based, so we add one.
            return((byte)((randomNumber[0] % sides) + 1));
        }
Пример #7
0
        public override void PopulateChildren(XElement xml, IRandomNumberGenerator rng, KdbxSerializationParameters parameters)
        {
            xml.Add(new XElement("Key", Key));

            XElement valueElement = new XElement("Value");

            if (!string.IsNullOrEmpty(RawValue))
            {
                string value = (Protected ?
                                getEncrypted(ClearValue, rng.GetBytes((uint)this._xorKey.Length)) :
                                ClearValue
                                );
                valueElement.SetValue(value);
            }
            xml.Add(valueElement);

            if (Protected)
            {
                valueElement.SetAttributeValue("Protected", "True");
            }
        }
Пример #8
0
        public KdbxString(XElement xml, IRandomNumberGenerator rng)
            : base(xml)
        {
            this._rng = rng;

            XElement   valueNode     = GetNode("Value");
            XAttribute protectedAttr = valueNode.Attribute("Protected");

            if (protectedAttr != null && protectedAttr.Value == "True")
            {
                Protected = true;
            }
            else
            {
                Protected = false;
            }

            Key      = GetString("Key");
            RawValue = valueNode.Value;
            if (Protected)
            {
                this._xorKey = rng.GetBytes((uint)getBytes(RawValue).Length);
            }
        }
Пример #9
0
 private byte[] GetCspData()
 {
     byte[] pbCspRandom = new byte[32];
     m_rng.GetBytes(pbCspRandom);
     return(pbCspRandom);
 }
        /// <summary>
        /// Initializes a new instance of <see cref="MiniPrivateKey"/> with a randomly generated key
        /// using the given <see cref="IRandomNumberGenerator"/> instance.
        /// </summary>
        /// <exception cref="ArgumentNullException"/>
        /// <param name="rng">Random number generator to use</param>
        public MiniPrivateKey(IRandomNumberGenerator rng)
        {
            if (rng is null)
            {
                throw new ArgumentNullException("Random number generator can not be null.");
            }

            // This is the way Casascius does it.
            // https://github.com/casascius/Bitcoin-Address-Utility/blob/e493d51e4a1da7536fc8e8aea38eeaee38abf4cb/Model/MiniKeyPair.cs#L54-L80
            // Create a random 256 bit key. It will only be used for its characters
            byte[] tempBa = new byte[32 + 1];
            rng.GetBytes(tempBa);
            tempBa[0] = GetWifFirstByte(NetworkType.MainNet);
            string b58 = 'S' + b58Encoder.EncodeWithCheckSum(tempBa).Replace("1", "").Substring(4, 29);

            char[] chars     = b58.ToCharArray();
            char[] charstest = (b58 + "?").ToCharArray();
            while (hash.ComputeHash(Encoding.UTF8.GetBytes(charstest))[0] != 0)
            {
                // As long as key doesn't pass typo check, increment it.
                for (int i = chars.Length - 1; i >= 0; i--)
                {
                    char c = chars[i];
                    if (c == '9')
                    {
                        charstest[i] = chars[i] = 'A';
                        break;
                    }
                    else if (c == 'H')
                    {
                        charstest[i] = chars[i] = 'J';
                        break;
                    }
                    else if (c == 'N')
                    {
                        charstest[i] = chars[i] = 'P';
                        break;
                    }
                    else if (c == 'Z')
                    {
                        charstest[i] = chars[i] = 'a';
                        break;
                    }
                    else if (c == 'k')
                    {
                        charstest[i] = chars[i] = 'm';
                        break;
                    }
                    else if (c == 'z')
                    {
                        charstest[i] = chars[i] = '2';
                        // No break - let loop increment prior character.
                    }
                    else
                    {
                        charstest[i] = chars[i] = ++c;
                        break;
                    }
                }
            }

            smallBytes = Encoding.UTF8.GetBytes(chars);
            SetBytes(hash.ComputeHash(smallBytes));
        }