Exemple #1
0
		public Key Derivate(byte[] cc, uint nChild, out byte[] ccChild)
		{
			byte[] l = null;
			if((nChild >> 31) == 0)
			{
				var pubKey = PubKey.ToBytes();
				l = Hashes.BIP32Hash(cc, nChild, pubKey[0], pubKey.SafeSubarray(1));
			}
			else
			{
				l = Hashes.BIP32Hash(cc, nChild, 0, this.ToBytes());
			}
			var ll = l.SafeSubarray(0, 32);
			var lr = l.SafeSubarray(32, 32);

			ccChild = lr;

			var parse256LL = new BigInteger(1, ll);
			var kPar = new BigInteger(1, vch);
			var N = ECKey.CURVE.N;

			if(parse256LL.CompareTo(N) >= 0)
				throw new InvalidOperationException("You won a prize ! this should happen very rarely. Take a screenshot, and roll the dice again.");
			var key = parse256LL.Add(kPar).Mod(N);
			if(key == BigInteger.Zero)
				throw new InvalidOperationException("You won the big prize ! this would happen only 1 in 2^127. Take a screenshot, and roll the dice again.");

			var keyBytes = key.ToByteArrayUnsigned();
			if(keyBytes.Length < 32)
				keyBytes = new byte[32 - keyBytes.Length].Concat(keyBytes).ToArray();
			return new Key(keyBytes);
		}
Exemple #2
0
		public ExtKey GetParentExtKey(ExtPubKey parent)
		{
			if(parent == null)
				throw new ArgumentNullException("parent");
			if(Depth == 0)
				throw new InvalidOperationException("This ExtKey is the root key of the HD tree");
			if(IsHardened)
				throw new InvalidOperationException("This private key is hardened, so you can't get its parent");
			var expectedFingerPrint = parent.CalculateChildFingerprint();
			if(parent.Depth != this.Depth - 1 || !expectedFingerPrint.SequenceEqual(vchFingerprint))
				throw new ArgumentException("The parent ExtPubKey is not the immediate parent of this ExtKey", "parent");

			byte[] l = null;
			byte[] ll = new byte[32];
			byte[] lr = new byte[32];

			var pubKey = parent.PubKey.ToBytes();
			l = Hashes.BIP32Hash(parent.vchChainCode, nChild, pubKey[0], pubKey.SafeSubarray(1));
			Array.Copy(l, ll, 32);
			Array.Copy(l, 32, lr, 0, 32);
			var ccChild = lr;

			BigInteger parse256LL = new BigInteger(1, ll);
			BigInteger N = ECKey.CURVE.N;

			if(!ccChild.SequenceEqual(vchChainCode))
				throw new InvalidOperationException("The derived chain code of the parent is not equal to this child chain code");

			var keyBytes = PrivateKey.ToBytes();
			var key = new BigInteger(1, keyBytes);

			BigInteger kPar = key.Add(parse256LL.Negate()).Mod(N);
			var keyParentBytes = kPar.ToByteArrayUnsigned();
			if(keyParentBytes.Length < 32)
				keyParentBytes = new byte[32 - keyParentBytes.Length].Concat(keyParentBytes).ToArray();

			var parentExtKey = new ExtKey
			{
				vchChainCode = parent.vchChainCode,
				nDepth = parent.Depth,
				vchFingerprint = parent.Fingerprint,
				nChild = parent.nChild,
				key = new Key(keyParentBytes)
			};
			return parentExtKey;
		}
Exemple #3
0
		// 5.4 pg 29
		/**
         * return true if the value r and s represent a DSA signature for
         * the passed in message (for standard DSA the message should be
         * a SHA-1 hash of the real message to be verified).
         */
		public virtual bool VerifySignature(byte[] message, BigInteger r, BigInteger s)
		{
			BigInteger n = key.Parameters.N;

			// r and s should both in the range [1,n-1]
			if(r.SignValue < 1 || s.SignValue < 1
				|| r.CompareTo(n) >= 0 || s.CompareTo(n) >= 0)
			{
				return false;
			}

			BigInteger e = CalculateE(n, message);
			BigInteger c = s.ModInverse(n);

			BigInteger u1 = e.Multiply(c).Mod(n);
			BigInteger u2 = r.Multiply(c).Mod(n);

			ECPoint G = key.Parameters.G;
			ECPoint Q = ((ECPublicKeyParameters)key).Q;

			ECPoint point = ECAlgorithms.SumOfTwoMultiplies(G, u1, Q, u2);

			if(point.IsInfinity)
				return false;

			/*
             * If possible, avoid normalizing the point (to save a modular inversion in the curve field).
             * 
             * There are ~cofactor elements of the curve field that reduce (modulo the group order) to 'r'.
             * If the cofactor is known and small, we generate those possible field values and project each
             * of them to the same "denominator" (depending on the particular projective coordinates in use)
             * as the calculated point.X. If any of the projected values matches point.X, then we have:
             *     (point.X / Denominator mod p) mod n == r
             * as required, and verification succeeds.
             * 
             * Based on an original idea by Gregory Maxwell (https://github.com/gmaxwell), as implemented in
             * the libsecp256k1 project (https://github.com/bitcoin/secp256k1).
             */
			ECCurve curve = point.Curve;
			if(curve != null)
			{
				BigInteger cofactor = curve.Cofactor;
				if(cofactor != null && cofactor.CompareTo(Eight) <= 0)
				{
					ECFieldElement D = GetDenominator(curve.CoordinateSystem, point);
					if(D != null && !D.IsZero)
					{
						ECFieldElement X = point.XCoord;
						while(curve.IsValidFieldElement(r))
						{
							ECFieldElement R = curve.FromBigInteger(r).Multiply(D);
							if(R.Equals(X))
							{
								return true;
							}
							r = r.Add(n);
						}
						return false;
					}
				}
			}

			BigInteger v = point.Normalize().AffineXCoord.ToBigInteger().Mod(n);
			return v.Equals(r);
		}
        /*
         * Finds a pair of prime BigInteger's {p, q: p = 2q + 1}
         * 
         * (see: Handbook of Applied Cryptography 4.86)
         */
        internal static BigInteger[] GenerateSafePrimes(int size, int certainty, SecureRandom random)
        {
            BigInteger p, q;
            int qLength = size - 1;
            int minWeight = size >> 2;

            if (size <= 32)
            {
                for (;;)
                {
                    q = new BigInteger(qLength, 2, random);

                    p = q.ShiftLeft(1).Add(BigInteger.One);

                    if (!p.IsProbablePrime(certainty))
                        continue;

                    if (certainty > 2 && !q.IsProbablePrime(certainty - 2))
                        continue;

                    break;
                }
            }
            else
            {
                // Note: Modified from Java version for speed
                for (;;)
                {
                    q = new BigInteger(qLength, 0, random);

                retry:
                    for (int i = 0; i < primeLists.Length; ++i)
                    {
                        int test = q.Remainder(BigPrimeProducts[i]).IntValue;

                        if (i == 0)
                        {
                            int rem3 = test % 3;
                            if (rem3 != 2)
                            {
                                int diff = 2 * rem3 + 2;
                                q = q.Add(BigInteger.ValueOf(diff));
                                test = (test + diff) % primeProducts[i];
                            }
                        }

                        int[] primeList = primeLists[i];
                        for (int j = 0; j < primeList.Length; ++j)
                        {
                            int prime = primeList[j];
                            int qRem = test % prime;
                            if (qRem == 0 || qRem == (prime >> 1))
                            {
                                q = q.Add(Six);
                                goto retry;
                            }
                        }
                    }

                    if (q.BitLength != qLength)
                        continue;

                    if (!q.RabinMillerTest(2, random))
                        continue;

                    p = q.ShiftLeft(1).Add(BigInteger.One);

                    if (!p.RabinMillerTest(certainty, random))
                        continue;

                    if (certainty > 2 && !q.RabinMillerTest(certainty - 2, random))
                        continue;

                    /*
                     * Require a minimum weight of the NAF representation, since low-weight primes may be
                     * weak against a version of the number-field-sieve for the discrete-logarithm-problem.
                     * 
                     * See "The number field sieve for integers of low weight", Oliver Schirokauer.
                     */
                    if (WNafUtilities.GetNafWeight(p) < minWeight)
                        continue;

                    break;
                }
            }

            return new BigInteger[] { p, q };
        }
Exemple #5
0
        public BigInteger And(
            BigInteger value)
        {
            if (this.sign == 0 || value.sign == 0)
            {
                return Zero;
            }

            int[] aMag = this.sign > 0
                ? this.magnitude
                : Add(One).magnitude;

            int[] bMag = value.sign > 0
                ? value.magnitude
                : value.Add(One).magnitude;

            bool resultNeg = sign < 0 && value.sign < 0;
            int resultLength = System.Math.Max(aMag.Length, bMag.Length);
            int[] resultMag = new int[resultLength];

            int aStart = resultMag.Length - aMag.Length;
            int bStart = resultMag.Length - bMag.Length;

            for (int i = 0; i < resultMag.Length; ++i)
            {
                int aWord = i >= aStart ? aMag[i - aStart] : 0;
                int bWord = i >= bStart ? bMag[i - bStart] : 0;

                if (this.sign < 0)
                {
                    aWord = ~aWord;
                }

                if (value.sign < 0)
                {
                    bWord = ~bWord;
                }

                resultMag[i] = aWord & bWord;

                if (resultNeg)
                {
                    resultMag[i] = ~resultMag[i];
                }
            }

            BigInteger result = new BigInteger(1, resultMag, true);

            // TODO Optimise this case
            if (resultNeg)
            {
                result = result.Not();
            }

            return result;
        }
Exemple #6
0
        private static BigInteger ReduceBarrett(BigInteger x, BigInteger m, BigInteger mr, BigInteger yu)
        {
            int xLen = x.BitLength, mLen = m.BitLength;
            if (xLen < mLen)
                return x;

            if (xLen - mLen > 1)
            {
                int k = m.magnitude.Length;

                BigInteger q1 = x.DivideWords(k - 1);
                BigInteger q2 = q1.Multiply(yu); // TODO Only need partial multiplication here
                BigInteger q3 = q2.DivideWords(k + 1);

                BigInteger r1 = x.RemainderWords(k + 1);
                BigInteger r2 = q3.Multiply(m); // TODO Only need partial multiplication here
                BigInteger r3 = r2.RemainderWords(k + 1);

                x = r1.Subtract(r3);
                if (x.sign < 0)
                {
                    x = x.Add(mr);
                }
            }

            while (x.CompareTo(m) >= 0)
            {
                x = x.Subtract(m);
            }

            return x;
        }